ItemDrawer.vue 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. <template>
  2. <el-drawer class="local-launch_drawer-wrap" title="测试表单" :model-value="modelValue" size="760px" @update:model-value="updateModelValue">
  3. <!-- <div v-loading="loading" class="local_loading" element-loading-text="加载中..." element-loading-background="rgba(0, 0, 0, 0.1)" />-->
  4. <div class="info-wrap">
  5. <FormCreate class="form-wrap" :option="formOption" :rule="formRule" />
  6. <el-timeline class="timeline-wrap">
  7. <el-timeline-item v-for="(v, index) in processTimelineList" :key="index">
  8. <template v-if="v.conditionNode === 1">
  9. <el-radio-group v-model="processChecked[v.name]" size="small">
  10. <el-radio-button v-for="c of v.conditionNodeList" :key="c.name" :label="c.name" />
  11. </el-radio-group>
  12. </template>
  13. <template v-else>
  14. {{ v.name }}
  15. <!-- {{ v.local_name }} -->
  16. <div style="display: flex; align-items: center; gap: 6px">
  17. <el-button :icon="Plus" style="width: 32px" @click="selectHandler" />
  18. <FlowNodeAvatar v-for="(item, index) in userList" id="1" :key="index" style="margin-top: 5px" />
  19. </div>
  20. </template>
  21. </el-timeline-item>
  22. </el-timeline>
  23. </div>
  24. </el-drawer>
  25. <use-select ref="useSelectRef"></use-select>
  26. </template>
  27. <script setup lang="ts">
  28. import model from '@/api/flow/process'
  29. import viewForm from '@/utils/form'
  30. import { ref, inject, shallowRef, computed, reactive } from 'vue'
  31. import { ElMessage } from 'element-plus'
  32. import { Plus } from '@element-plus/icons-vue'
  33. import UseSelect from '@/components/scWorkflow/select.vue'
  34. import FlowNodeAvatar from '@/components/Flow/FlowNodeAvatar.vue'
  35. type Props = {
  36. modelValue: boolean
  37. record: { processId: string; [key: string]: any }
  38. }
  39. const props = defineProps<Props>()
  40. /*const props = withDefaults(defineProps<Props>(), {
  41. modelValue: false
  42. })*/
  43. const emit = defineEmits<{
  44. 'update:modelValue': [bool: boolean] // 具名元组语法
  45. update: [value: string]
  46. }>()
  47. const updateModelValue = (bool: boolean) => emit('update:modelValue', bool)
  48. const userList = ref([])
  49. const useSelectRef = ref()
  50. const selectHandler = () => {
  51. useSelectRef.value.open(1, userList.value)
  52. }
  53. const FormCreate = viewForm.$form()
  54. const formOption = ref({
  55. // resetBtn: { show: true },
  56. onSubmit(formData) {
  57. // console.error(formData, 'formData')
  58. const processId = props.record.processId
  59. formOption.value.submitBtn.loading = true
  60. const processForm: any[] = JSON.parse(cur_processForm_str)
  61. processForm.forEach(v => {
  62. // 填写的数据存储(local_: 本地数据处理标识)
  63. v.local_value = formData[v.field]
  64. })
  65. model
  66. .processLaunchApi({
  67. processId, // 流程ID
  68. processForm: JSON.stringify(processForm) // 流程表单JSON内容 & local_value 保存
  69. })
  70. .then(res => {
  71. ElMessage.success('提交成功')
  72. updateModelValue(false)
  73. })
  74. .finally(() => {
  75. formOption.value.submitBtn.loading = false
  76. })
  77. },
  78. submitBtn: { loading: false }
  79. /*formData: {
  80. local_workflow: {},
  81. test_3: 'eeeee'
  82. }*/
  83. })
  84. /*const formData = ref({
  85. local_workflow: {}
  86. })*/
  87. /*const workflowItem = computed(() => {
  88. return {
  89. type:'ScWorkflow',
  90. field: 'local_workflow'
  91. }
  92. })*/
  93. /*const workflowItem = {
  94. type: 'ScWorkflow',
  95. field: 'local_workflow'
  96. }
  97. const formRule = shallowRef([workflowItem])*/
  98. // 当前form 表单数据字符串
  99. let cur_processForm_str = '[]'
  100. const formRule = shallowRef([])
  101. const loading = ref(true)
  102. const processChecked = reactive({
  103. /*'local_条件分支_期限': '短期'*/
  104. })
  105. const localProcessData = ref<any[]>([])
  106. let c_idx = 0
  107. const packageProcess = (data, list = []) => {
  108. return data.reduce((_list, config) => {
  109. if (config.conditionNode === 0) {
  110. // console.log(config.name, 'name 普通节点名称', config)
  111. if (!config.local_name) {
  112. // 普通节点 展示 控制
  113. config.local_name = (config.nodeAssigneeList || []).map(x => x.name).join(',') || config.name
  114. }
  115. _list.push(config)
  116. } else if (config.conditionNode === 1) {
  117. // 自定义标识key
  118. if (!config.name) {
  119. config.name = `local_${c_idx++}`
  120. }
  121. // console.log('条件节点', config)
  122. _list.push(config)
  123. if (Array.isArray(config.conditionNodeList) && config.conditionNodeList.length) {
  124. const _val = processChecked[config.name]
  125. let condition = config.conditionNodeList[0]
  126. if (_val) {
  127. config.conditionNodeList.some(_condition => {
  128. if (_condition.name === _val) {
  129. condition = _condition
  130. return true
  131. }
  132. })
  133. } else {
  134. // console.error('else......', condition)
  135. processChecked[config.name] = condition.name
  136. }
  137. // console.warn('条件节点', condition.name)
  138. if (Array.isArray(condition.childNode) && condition.childNode.length) {
  139. packageProcess(condition.childNode, _list)
  140. }
  141. }
  142. }
  143. return _list
  144. }, list)
  145. }
  146. const processTimelineList = computed(() => {
  147. return packageProcess(localProcessData.value)
  148. })
  149. model.processListNodeMapApi(props.record.processId).then(res => {
  150. // model.processListNodeMapApi('1747258191679991809').then((res: any[]) => {
  151. localProcessData.value = res
  152. // console.error(localProcessData, 'res..... processListNodeMapApi')
  153. })
  154. model.processDetailApi(props.record.processId).then(res => {
  155. // model.processDetailApi('1747258191679991809').then(res => {
  156. // console.error(res, '详情 process....', props.record)
  157. // modelContent 审批流数据
  158. let local_workflow = {}
  159. try {
  160. console.log(JSON.parse(res.modelContent))
  161. const modelContent = JSON.parse(res.modelContent)
  162. local_workflow = modelContent.nodeConfig ?? modelContent.childNode
  163. } catch (e) {}
  164. // formOption.value.formData = { local_workflow, test_3: 'eeeee' }
  165. cur_processForm_str = res.processForm || '[]'
  166. // processForm 动态表单
  167. formRule.value = [...JSON.parse(cur_processForm_str) /*, { ...workflowItem, value: local_workflow }*/ /*, { type: 'input', field: 'test_3' }*/]
  168. // loading.value = false
  169. // console.error(formData.value, 'formData.value')
  170. })
  171. </script>
  172. <style lang="scss">
  173. .local-launch_drawer-wrap {
  174. .el-drawer__header {
  175. display: flex;
  176. padding: 16px 24px;
  177. align-items: center;
  178. justify-content: space-between;
  179. background-color: var(--el-color-info-light-9);
  180. text-align: left;
  181. /* margin-right: 0; */
  182. margin-bottom: 0;
  183. }
  184. .el-drawer__close-btn {
  185. padding: 0;
  186. margin-right: -12px;
  187. }
  188. .el-drawer__body {
  189. position: relative;
  190. //display: flex;
  191. //flex-direction: column;
  192. }
  193. .local_loading {
  194. position: absolute;
  195. left: 0;
  196. display: flex;
  197. align-items: center;
  198. justify-content: center;
  199. width: 100%;
  200. height: 100%;
  201. z-index: 999;
  202. background: rgba(0, 0, 0, 0.05);
  203. }
  204. }
  205. </style>
  206. <style scoped lang="scss">
  207. .info-wrap {
  208. display: flex;
  209. .form-wrap {
  210. flex: 1;
  211. }
  212. .timeline-wrap {
  213. margin-left: 8px;
  214. flex-shrink: 0;
  215. padding: 0;
  216. width: 360px;
  217. }
  218. }
  219. </style>