CallActivity.vue 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. <template>
  2. <div>
  3. <el-form label-width="100px">
  4. <el-form-item label="实例名称" prop="processInstanceName">
  5. <el-input
  6. v-model="formData.processInstanceName"
  7. clearable
  8. placeholder="请输入实例名称"
  9. @change="updateCallActivityAttr('processInstanceName')"
  10. />
  11. </el-form-item>
  12. <!-- TODO 需要可选择已存在的流程 -->
  13. <el-form-item label="被调用流程" prop="calledElement">
  14. <el-input
  15. v-model="formData.calledElement"
  16. clearable
  17. placeholder="请输入被调用流程"
  18. @change="updateCallActivityAttr('calledElement')"
  19. />
  20. </el-form-item>
  21. <el-form-item label="继承变量" prop="inheritVariables">
  22. <el-switch
  23. v-model="formData.inheritVariables"
  24. @change="updateCallActivityAttr('inheritVariables')"
  25. />
  26. </el-form-item>
  27. <el-form-item label="继承业务键" prop="inheritBusinessKey">
  28. <el-switch
  29. v-model="formData.inheritBusinessKey"
  30. @change="updateCallActivityAttr('inheritBusinessKey')"
  31. />
  32. </el-form-item>
  33. <el-form-item v-if="!formData.inheritBusinessKey" label="业务键表达式" prop="businessKey">
  34. <el-input
  35. v-model="formData.businessKey"
  36. clearable
  37. placeholder="请输入业务键表达式"
  38. @change="updateCallActivityAttr('businessKey')"
  39. />
  40. </el-form-item>
  41. <el-divider />
  42. <div>
  43. <div class="flex mb-10px">
  44. <el-text>输入参数</el-text>
  45. <XButton
  46. class="ml-auto"
  47. type="primary"
  48. preIcon="ep:plus"
  49. title="添加参数"
  50. size="small"
  51. @click="openVariableForm('in', null, -1)"
  52. />
  53. </div>
  54. <el-table :data="inVariableList" max-height="240" fit border>
  55. <el-table-column label="源" prop="source" min-width="100px" show-overflow-tooltip />
  56. <el-table-column label="目标" prop="target" min-width="100px" show-overflow-tooltip />
  57. <el-table-column label="操作" width="110px">
  58. <template #default="scope">
  59. <el-button link @click="openVariableForm('in', scope.row, scope.$index)" size="small">
  60. 编辑
  61. </el-button>
  62. <el-divider direction="vertical" />
  63. <el-button
  64. link
  65. size="small"
  66. style="color: #ff4d4f"
  67. @click="removeVariable('in', scope.$index)"
  68. >
  69. 移除
  70. </el-button>
  71. </template>
  72. </el-table-column>
  73. </el-table>
  74. </div>
  75. <el-divider />
  76. <div>
  77. <div class="flex mb-10px">
  78. <el-text>输出参数</el-text>
  79. <XButton
  80. class="ml-auto"
  81. type="primary"
  82. preIcon="ep:plus"
  83. title="添加参数"
  84. size="small"
  85. @click="openVariableForm('out', null, -1)"
  86. />
  87. </div>
  88. <el-table :data="outVariableList" max-height="240" fit border>
  89. <el-table-column label="源" prop="source" min-width="100px" show-overflow-tooltip />
  90. <el-table-column label="目标" prop="target" min-width="100px" show-overflow-tooltip />
  91. <el-table-column label="操作" width="110px">
  92. <template #default="scope">
  93. <el-button
  94. link
  95. @click="openVariableForm('out', scope.row, scope.$index)"
  96. size="small"
  97. >
  98. 编辑
  99. </el-button>
  100. <el-divider direction="vertical" />
  101. <el-button
  102. link
  103. size="small"
  104. style="color: #ff4d4f"
  105. @click="removeVariable('out', scope.$index)"
  106. >
  107. 移除
  108. </el-button>
  109. </template>
  110. </el-table-column>
  111. </el-table>
  112. </div>
  113. </el-form>
  114. <!-- 添加或修改参数 -->
  115. <el-dialog
  116. v-model="variableDialogVisible"
  117. title="参数配置"
  118. width="600px"
  119. append-to-body
  120. destroy-on-close
  121. >
  122. <el-form :model="varialbeFormData" label-width="80px" ref="varialbeFormRef">
  123. <el-form-item label="源:" prop="source">
  124. <el-input v-model="varialbeFormData.source" clearable />
  125. </el-form-item>
  126. <el-form-item label="目标:" prop="target">
  127. <el-input v-model="varialbeFormData.target" clearable />
  128. </el-form-item>
  129. </el-form>
  130. <template #footer>
  131. <el-button @click="variableDialogVisible = false">取 消</el-button>
  132. <el-button type="primary" @click="saveVariable">确 定</el-button>
  133. </template>
  134. </el-dialog>
  135. </div>
  136. </template>
  137. <script lang="ts" setup>
  138. defineOptions({ name: 'CallActivity' })
  139. const props = defineProps({
  140. id: String,
  141. type: String
  142. })
  143. const prefix = inject('prefix')
  144. const message = useMessage()
  145. const formData = ref({
  146. processInstanceName: '',
  147. calledElement: '',
  148. inheritVariables: false,
  149. businessKey: '',
  150. inheritBusinessKey: false,
  151. calledElementType: 'key'
  152. })
  153. const inVariableList = ref()
  154. const outVariableList = ref()
  155. const variableType = ref() // 参数类型
  156. const editingVariableIndex = ref(-1) // 编辑参数下标
  157. const variableDialogVisible = ref(false)
  158. const varialbeFormRef = ref()
  159. const varialbeFormData = ref({
  160. source: '',
  161. target: ''
  162. })
  163. const bpmnInstances = () => (window as any)?.bpmnInstances
  164. const bpmnElement = ref()
  165. const otherExtensionList = ref()
  166. const initCallActivity = () => {
  167. bpmnElement.value = bpmnInstances().bpmnElement
  168. console.log(bpmnElement.value.businessObject, 'callActivity')
  169. // 初始化所有配置项
  170. Object.keys(formData.value).forEach((key) => {
  171. formData.value[key] = bpmnElement.value.businessObject[key] ?? formData.value[key]
  172. })
  173. otherExtensionList.value = [] // 其他扩展配置
  174. inVariableList.value = []
  175. outVariableList.value = []
  176. // 初始化输入参数
  177. bpmnElement.value.businessObject?.extensionElements?.values?.forEach((ex) => {
  178. if (ex.$type === `${prefix}:In`) {
  179. inVariableList.value.push(ex)
  180. } else if (ex.$type === `${prefix}:Out`) {
  181. outVariableList.value.push(ex)
  182. } else {
  183. otherExtensionList.value.push(ex)
  184. }
  185. })
  186. // 默认添加
  187. // bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
  188. // calledElementType: 'key'
  189. // })
  190. }
  191. const updateCallActivityAttr = (attr) => {
  192. bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
  193. [attr]: formData.value[attr]
  194. })
  195. }
  196. const openVariableForm = (type, data, index) => {
  197. editingVariableIndex.value = index
  198. variableType.value = type
  199. varialbeFormData.value = index === -1 ? {} : { ...data }
  200. variableDialogVisible.value = true
  201. }
  202. const removeVariable = async (type, index) => {
  203. try {
  204. await message.delConfirm()
  205. if (type === 'in') {
  206. inVariableList.value.splice(index, 1)
  207. }
  208. if (type === 'out') {
  209. outVariableList.value.splice(index, 1)
  210. }
  211. updateElementExtensions()
  212. } catch {}
  213. }
  214. const saveVariable = () => {
  215. if (editingVariableIndex.value === -1) {
  216. if (variableType.value === 'in') {
  217. inVariableList.value.push(
  218. bpmnInstances().moddle.create(`${prefix}:In`, { ...varialbeFormData.value })
  219. )
  220. }
  221. if (variableType.value === 'out') {
  222. outVariableList.value.push(
  223. bpmnInstances().moddle.create(`${prefix}:Out`, { ...varialbeFormData.value })
  224. )
  225. }
  226. updateElementExtensions()
  227. } else {
  228. if (variableType.value === 'in') {
  229. inVariableList.value[editingVariableIndex.value].source = varialbeFormData.value.source
  230. inVariableList.value[editingVariableIndex.value].target = varialbeFormData.value.target
  231. }
  232. if (variableType.value === 'out') {
  233. outVariableList.value[editingVariableIndex.value].source = varialbeFormData.value.source
  234. outVariableList.value[editingVariableIndex.value].target = varialbeFormData.value.target
  235. }
  236. }
  237. variableDialogVisible.value = false
  238. }
  239. const updateElementExtensions = () => {
  240. const extensions = bpmnInstances().moddle.create('bpmn:ExtensionElements', {
  241. values: [...inVariableList.value, ...outVariableList.value, ...otherExtensionList.value]
  242. })
  243. bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
  244. extensionElements: extensions
  245. })
  246. }
  247. watch(
  248. () => props.id,
  249. (val) => {
  250. val &&
  251. val.length &&
  252. nextTick(() => {
  253. initCallActivity()
  254. })
  255. },
  256. { immediate: true }
  257. )
  258. </script>
  259. <style lang="scss" scoped></style>