Technologieaustausch

Fließfähiger Prozess basierend auf jeecgboot-vue3 – integrierte Nachahmung des DingTalk-Prozesses (5), JSON-Datenspeicherung und Anzeige der Nachahmung des DingTalk-Prozesses

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Aufgrund des Lizenzproblems dieses Projekts kann es nicht als Open Source bereitgestellt werden. Für weitere technische Unterstützung und Dienste treten Sie bitte meinem Knowledge Planet bei.

1. Sie müssen eine Schnittstelle erstellen, um den Prozess der Nachahmung von DingTalk zu speichern und anzuzeigen. Erstellen Sie zunächst eine Tabelle und verwenden Sie sie online, um eine Tabelle zu erstellen.

2. Generieren Sie den obigen Code und fügen Sie ihn in die entsprechenden Front-End- und Back-End-Projekte ein.

3. Ändern Sie die Designfunktion des Front-End-Imitations-DingTalk-Prozesses und fügen Sie wie folgt ein Dialogfeld zur ursprünglichen Listenseite hinzu:

  1. <el-dialog :title="designerData.name" class="ddDialog" v-model="designerOpen" append-to-body fullscreen>
  2. <ding-designer
  3. ref="ddDesigner"
  4. v-loading="designerLoading"
  5. :process = "flowJsonData"
  6. @save="onSaveDesigner"
  7. />
  8. </el-dialog>

4. Fügen Sie die oben genannte Nagelsimulationskomponente hinzu

  1. <template>
  2. <div class="formDesign">
  3. <FlowDesign :process="process" :fields="fields" :readOnly="readOnly">
  4. <el-switch
  5. inline-prompt
  6. size="large"
  7. active-text="正常模式"
  8. inactive-text="暗黑模式"
  9. @change="handleToggleDark"
  10. v-model="isDark"
  11. />
  12. <el-switch
  13. v-model="readOnly"
  14. size="large"
  15. active-text="只读模式"
  16. inactive-text="编辑模式"
  17. inline-prompt
  18. :active-value="true"
  19. :inactive-value="false"
  20. />
  21. <el-button-group>
  22. <el-button @click="viewJson" size="small" type="primary" round icon="View"> 查看Json</el-button>
  23. </el-button-group>
  24. <el-button-group>
  25. <el-button @click="viewXmlBpmn" size="small" type="primary" round icon="View"> 查看XML </el-button>
  26. </el-button-group>
  27. <el-button-group>
  28. <el-button @click="converterBpmn" size="small" type="primary" round icon="View"> 预览bpmn </el-button>
  29. </el-button-group>
  30. <el-button-group>
  31. <el-button @click="save" size="small" type="primary" round icon="View"> 保存 </el-button>
  32. </el-button-group>
  33. </FlowDesign>
  34. <el-dialog title="预览" width="60%" v-model="previewModelVisible" append-to-body destroy-on-close>
  35. <highlightjs :language="previewType" :code="previewResult" style="height: 80vh" />
  36. </el-dialog>
  37. <!-- Bpmn流程图 -->
  38. <el-dialog :title="processView.title" v-model="processView.open" width="70%" append-to-body>
  39. <process-viewer :key="`designer-${processView.title}`" :xml="processView.xmlData" :style="{height: '500px'}" />
  40. </el-dialog>
  41. </div>
  42. </template>
  43. <script setup lang="ts" name="DingDesigner">
  44. import { ref, reactive, toRaw, onMounted } from 'vue';
  45. import '@/views/lowflow/styles/index.scss'
  46. // If you want to use ElMessage, import it.
  47. import 'element-plus/dist/index.css';
  48. import 'element-plus/theme-chalk/display.css';
  49. import FlowDesign from '@/views/lowflow/flowDesign/index.vue'
  50. import type { Field } from '@/views/lowflow/components/Render/type'
  51. import type { EndNode, FlowNode, StartNode } from '@/views/lowflow/flowDesign/nodes/type'
  52. import { viewXml, ddToBpmnXml } from '@/views/lowflow/api/modules/model'
  53. import ProcessViewer from '@/components/ProcessViewer/index.vue';
  54. import { useMessage } from '/@/hooks/web/useMessage';
  55. const { createMessage, createConfirm } = useMessage();
  56. const props = defineProps({
  57. process: {
  58. type: Object,
  59. required: true
  60. },
  61. });
  62. const emit = defineEmits([
  63. 'save'
  64. ])
  65. const previewModelVisible = ref(false)
  66. const previewResult = ref('')
  67. const previewType = ref('xml')
  68. const processView = reactive<any>({
  69. title: '',
  70. open: false,
  71. xmlData:'',
  72. })
  73. // 流程节点
  74. /*const process = ref<FlowNode>({
  75. id: 'root',
  76. pid: undefined,
  77. type: 'start',
  78. name: '流程开始',
  79. executionListeners: [],
  80. formProperties: [],
  81. child: {
  82. id: 'end',
  83. pid: 'root',
  84. type: 'end',
  85. name: '流程结束',
  86. executionListeners: [],
  87. child: undefined
  88. } as EndNode
  89. } as StartNode)*/
  90. // 表单字段
  91. const fields = ref<Field[]>([
  92. {
  93. id: 'field_da2w55',
  94. type: 'formItem',
  95. label: '请假人',
  96. name: 'UserSelector',
  97. value: null,
  98. readonly: false,
  99. required: true,
  100. hidden: false,
  101. props: {
  102. multiple: false,
  103. disabled: false,
  104. placeholder: '请选择用户',
  105. style: {
  106. width: '100%'
  107. }
  108. }
  109. },
  110. {
  111. id: 'field_fa2w40',
  112. type: 'formItem',
  113. label: '请假天数',
  114. name: 'ElInputNumber',
  115. value: null,
  116. readonly: false,
  117. required: true,
  118. hidden: false,
  119. props: {
  120. disabled: false,
  121. placeholder: '请假天数',
  122. style: {
  123. width: '100%'
  124. },
  125. min: 0,
  126. max: 100,
  127. step: 1,
  128. precision: 0
  129. }
  130. },
  131. {
  132. id: 'field_d42t45',
  133. type: 'formItem',
  134. label: '请假事由',
  135. name: 'ElSelect',
  136. value: null,
  137. readonly: false,
  138. required: true,
  139. hidden: false,
  140. props: {
  141. disabled: false,
  142. multiple: false,
  143. placeholder: '请选择请假事由',
  144. options: [
  145. {
  146. label: '事假',
  147. value: '事假'
  148. },
  149. {
  150. label: '病假',
  151. value: '病假'
  152. },
  153. {
  154. label: '婚假',
  155. value: '婚假'
  156. },
  157. {
  158. label: '产假',
  159. value: '产假'
  160. },
  161. {
  162. label: '丧假',
  163. value: '丧假'
  164. },
  165. {
  166. label: '其他',
  167. value: '其他'
  168. }
  169. ],
  170. style: {
  171. width: '100%'
  172. }
  173. }
  174. },
  175. {
  176. id: 'field_522g58',
  177. type: 'formItem',
  178. label: '请假原因',
  179. name: 'ElInput',
  180. value: null,
  181. readonly: false,
  182. required: true,
  183. hidden: false,
  184. props: {
  185. type: 'textarea',
  186. placeholder: '请输入请假原因',
  187. autosize: {
  188. minRows: 3,
  189. maxRows: 3
  190. },
  191. disabled: false,
  192. style: {
  193. width: '100%'
  194. }
  195. }
  196. }
  197. ])
  198. // 是否只读
  199. const readOnly = ref(false)
  200. // 是否暗黑模式
  201. const isDark = ref(false)
  202. const viewJson = () => {
  203. const processJson = JSON.stringify(props.process,undefined, 2);
  204. previewResult.value = processJson;
  205. previewType.value = 'json'
  206. previewModelVisible.value = true
  207. }
  208. const viewXmlBpmn = () => {
  209. const processModel = {
  210. code: 'test',
  211. name: '测试',
  212. icon: {
  213. name: 'el:HomeFilled',
  214. color: '#409EFF'
  215. },
  216. process: props.process,
  217. enable: true,
  218. version: 1,
  219. sort: 0,
  220. groupId: '',
  221. remark: ''
  222. }
  223. const xmlData = viewXml(processModel)
  224. xmlData.then((result) => {
  225. previewResult.value = result
  226. previewType.value = 'xml'
  227. previewModelVisible.value = true
  228. })
  229. }
  230. const converterBpmn = () => {
  231. const processModel = {
  232. code: 'test',
  233. name: '测试',
  234. icon: {
  235. name: 'el:HomeFilled',
  236. color: '#409EFF'
  237. },
  238. process: props.process,
  239. enable: true,
  240. version: 1,
  241. sort: 0,
  242. groupId: '',
  243. remark: ''
  244. }
  245. ddToBpmnXml(processModel).then(res => {
  246. console.log("ddToBpmnXml res",res)
  247. processView.xmlData = res.result
  248. processView.title = "Bpmn流程图预览"
  249. processView.open = true
  250. })
  251. }
  252. const save = () => {
  253. const flowData = props.process
  254. emit('save', flowData);
  255. }
  256. const handleToggleDark = () => {
  257. if (isDark.value) {
  258. document.documentElement.classList.add('dark')
  259. } else {
  260. document.documentElement.classList.remove('dark')
  261. }
  262. }
  263. onMounted(() => {
  264. });
  265. </script>
  266. <style scoped lang="scss">
  267. .formDesign {
  268. z-index: 999;
  269. top: 120px;
  270. height: 100%;
  271. }
  272. </style>

5. Die Darstellungen lauten wie folgt:

Das Punktdesign ist wie folgt: