ElementMultiInstance.vue 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. <template>
  2. <div class="panel-tab__content">
  3. <el-form label-width="90px">
  4. <el-form-item label="快捷配置">
  5. <el-button size="small" @click="changeConfig('依次审批')">依次审批</el-button>
  6. <el-button size="small" @click="changeConfig('会签')">会签</el-button>
  7. <el-button size="small" @click="changeConfig('或签')">或签</el-button>
  8. </el-form-item>
  9. <el-form-item label="会签类型">
  10. <el-select v-model="loopCharacteristics" @change="changeLoopCharacteristicsType">
  11. <el-option label="并行多重事件" value="ParallelMultiInstance" />
  12. <el-option label="时序多重事件" value="SequentialMultiInstance" />
  13. <!-- <el-option label="循环事件" value="StandardLoop" />-->
  14. <el-option label="无" value="Null" />
  15. </el-select>
  16. </el-form-item>
  17. <template
  18. v-if="
  19. loopCharacteristics === 'ParallelMultiInstance' ||
  20. loopCharacteristics === 'SequentialMultiInstance'
  21. "
  22. >
  23. <el-form-item label="循环数量" key="loopCardinality">
  24. <el-input
  25. v-model="loopInstanceForm.loopCardinality"
  26. clearable
  27. @change="updateLoopCardinality"
  28. />
  29. </el-form-item>
  30. <el-form-item label="集合" key="collection" v-show="false">
  31. <el-input v-model="loopInstanceForm.collection" clearable @change="updateLoopBase" />
  32. </el-form-item>
  33. <!-- add by 芋艿:由于「元素变量」暂时用不到,所以这里 display 为 none -->
  34. <el-form-item label="元素变量" key="elementVariable" style="display: none">
  35. <el-input v-model="loopInstanceForm.elementVariable" clearable @change="updateLoopBase" />
  36. </el-form-item>
  37. <el-form-item label="完成条件" key="completionCondition">
  38. <el-input
  39. v-model="loopInstanceForm.completionCondition"
  40. clearable
  41. @change="updateLoopCondition"
  42. />
  43. </el-form-item>
  44. <!-- add by 芋艿:由于「异步状态」暂时用不到,所以这里 display 为 none -->
  45. <el-form-item label="异步状态" key="async" style="display: none">
  46. <el-checkbox
  47. v-model="loopInstanceForm.asyncBefore"
  48. label="异步前"
  49. @change="updateLoopAsync('asyncBefore')"
  50. />
  51. <el-checkbox
  52. v-model="loopInstanceForm.asyncAfter"
  53. label="异步后"
  54. @change="updateLoopAsync('asyncAfter')"
  55. />
  56. <el-checkbox
  57. v-model="loopInstanceForm.exclusive"
  58. v-if="loopInstanceForm.asyncAfter || loopInstanceForm.asyncBefore"
  59. label="排除"
  60. @change="updateLoopAsync('exclusive')"
  61. />
  62. </el-form-item>
  63. <el-form-item
  64. label="重试周期"
  65. prop="timeCycle"
  66. v-if="loopInstanceForm.asyncAfter || loopInstanceForm.asyncBefore"
  67. key="timeCycle"
  68. >
  69. <el-input v-model="loopInstanceForm.timeCycle" clearable @change="updateLoopTimeCycle" />
  70. </el-form-item>
  71. </template>
  72. </el-form>
  73. </div>
  74. </template>
  75. <script lang="ts" setup>
  76. defineOptions({ name: 'ElementMultiInstance' })
  77. const props = defineProps({
  78. businessObject: Object,
  79. type: String
  80. })
  81. const prefix = inject('prefix')
  82. const loopCharacteristics = ref('')
  83. //默认配置,用来覆盖原始不存在的选项,避免报错
  84. const defaultLoopInstanceForm = ref({
  85. completionCondition: '',
  86. loopCardinality: '',
  87. extensionElements: [],
  88. asyncAfter: false,
  89. asyncBefore: false,
  90. exclusive: false
  91. })
  92. const loopInstanceForm = ref<any>({})
  93. const bpmnElement = ref(null)
  94. const multiLoopInstance = ref(null)
  95. const bpmnInstances = () => (window as any)?.bpmnInstances
  96. const getElementLoop = (businessObject) => {
  97. if (!businessObject.loopCharacteristics) {
  98. loopCharacteristics.value = 'Null'
  99. loopInstanceForm.value = {}
  100. return
  101. }
  102. if (businessObject.loopCharacteristics.$type === 'bpmn:StandardLoopCharacteristics') {
  103. loopCharacteristics.value = 'StandardLoop'
  104. loopInstanceForm.value = {}
  105. return
  106. }
  107. if (businessObject.loopCharacteristics.isSequential) {
  108. loopCharacteristics.value = 'SequentialMultiInstance'
  109. } else {
  110. loopCharacteristics.value = 'ParallelMultiInstance'
  111. }
  112. // 合并配置
  113. loopInstanceForm.value = {
  114. ...defaultLoopInstanceForm.value,
  115. ...businessObject.loopCharacteristics,
  116. completionCondition: businessObject.loopCharacteristics?.completionCondition?.body ?? '',
  117. loopCardinality: businessObject.loopCharacteristics?.loopCardinality?.body ?? ''
  118. }
  119. // 保留当前元素 businessObject 上的 loopCharacteristics 实例
  120. multiLoopInstance.value = bpmnInstances().bpmnElement.businessObject.loopCharacteristics
  121. // 更新表单
  122. if (
  123. businessObject.loopCharacteristics.extensionElements &&
  124. businessObject.loopCharacteristics.extensionElements.values &&
  125. businessObject.loopCharacteristics.extensionElements.values.length
  126. ) {
  127. loopInstanceForm.value['timeCycle'] =
  128. businessObject.loopCharacteristics.extensionElements.values[0].body
  129. }
  130. }
  131. const changeLoopCharacteristicsType = (type) => {
  132. // this.loopInstanceForm = { ...this.defaultLoopInstanceForm }; // 切换类型取消原表单配置
  133. // 取消多实例配置
  134. if (type === 'Null') {
  135. bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
  136. loopCharacteristics: null
  137. })
  138. return
  139. }
  140. // 配置循环
  141. if (type === 'StandardLoop') {
  142. const loopCharacteristicsObject = bpmnInstances().moddle.create(
  143. 'bpmn:StandardLoopCharacteristics'
  144. )
  145. bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
  146. loopCharacteristics: loopCharacteristicsObject
  147. })
  148. multiLoopInstance.value = null
  149. return
  150. }
  151. // 时序
  152. if (type === 'SequentialMultiInstance') {
  153. multiLoopInstance.value = bpmnInstances().moddle.create(
  154. 'bpmn:MultiInstanceLoopCharacteristics',
  155. { isSequential: true }
  156. )
  157. } else {
  158. multiLoopInstance.value = bpmnInstances().moddle.create(
  159. 'bpmn:MultiInstanceLoopCharacteristics',
  160. { collection: '${coll_userList}' }
  161. )
  162. }
  163. bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
  164. loopCharacteristics: toRaw(multiLoopInstance.value)
  165. })
  166. }
  167. // 循环基数
  168. const updateLoopCardinality = (cardinality) => {
  169. let loopCardinality = null
  170. if (cardinality && cardinality.length) {
  171. loopCardinality = bpmnInstances().moddle.create('bpmn:FormalExpression', {
  172. body: cardinality
  173. })
  174. }
  175. bpmnInstances().modeling.updateModdleProperties(
  176. toRaw(bpmnElement.value),
  177. multiLoopInstance.value,
  178. {
  179. loopCardinality
  180. }
  181. )
  182. }
  183. // 完成条件
  184. const updateLoopCondition = (condition) => {
  185. let completionCondition = null
  186. if (condition && condition.length) {
  187. completionCondition = bpmnInstances().moddle.create('bpmn:FormalExpression', {
  188. body: condition
  189. })
  190. }
  191. bpmnInstances().modeling.updateModdleProperties(
  192. toRaw(bpmnElement.value),
  193. multiLoopInstance.value,
  194. {
  195. completionCondition
  196. }
  197. )
  198. }
  199. // 重试周期
  200. const updateLoopTimeCycle = (timeCycle) => {
  201. const extensionElements = bpmnInstances().moddle.create('bpmn:ExtensionElements', {
  202. values: [
  203. bpmnInstances().moddle.create(`${prefix}:FailedJobRetryTimeCycle`, {
  204. body: timeCycle
  205. })
  206. ]
  207. })
  208. bpmnInstances().modeling.updateModdleProperties(
  209. toRaw(bpmnElement.value),
  210. multiLoopInstance.value,
  211. {
  212. extensionElements
  213. }
  214. )
  215. }
  216. // 直接更新的基础信息
  217. const updateLoopBase = () => {
  218. bpmnInstances().modeling.updateModdleProperties(
  219. toRaw(bpmnElement.value),
  220. multiLoopInstance.value,
  221. {
  222. collection: loopInstanceForm.value.collection || null,
  223. elementVariable: loopInstanceForm.value.elementVariable || null
  224. }
  225. )
  226. }
  227. // 各异步状态
  228. const updateLoopAsync = (key) => {
  229. const { asyncBefore, asyncAfter } = loopInstanceForm.value
  230. let asyncAttr = Object.create(null)
  231. if (!asyncBefore && !asyncAfter) {
  232. // this.$set(this.loopInstanceForm, "exclusive", false);
  233. loopInstanceForm.value['exclusive'] = false
  234. asyncAttr = { asyncBefore: false, asyncAfter: false, exclusive: false, extensionElements: null }
  235. } else {
  236. asyncAttr[key] = loopInstanceForm.value[key]
  237. }
  238. bpmnInstances().modeling.updateModdleProperties(
  239. toRaw(bpmnElement.value),
  240. multiLoopInstance.value,
  241. asyncAttr
  242. )
  243. }
  244. const changeConfig = (config) => {
  245. if (config === '依次审批') {
  246. changeLoopCharacteristicsType('SequentialMultiInstance')
  247. updateLoopCardinality('1')
  248. updateLoopCondition('${ nrOfCompletedInstances >= nrOfInstances }')
  249. } else if (config === '会签') {
  250. changeLoopCharacteristicsType('ParallelMultiInstance')
  251. updateLoopCondition('${ nrOfCompletedInstances >= nrOfInstances }')
  252. } else if (config === '或签') {
  253. changeLoopCharacteristicsType('ParallelMultiInstance')
  254. updateLoopCondition('${ nrOfCompletedInstances > 0 }')
  255. }
  256. }
  257. onBeforeUnmount(() => {
  258. multiLoopInstance.value = null
  259. bpmnElement.value = null
  260. })
  261. watch(
  262. () => props.businessObject,
  263. (val) => {
  264. bpmnElement.value = bpmnInstances().bpmnElement
  265. getElementLoop(val)
  266. },
  267. { immediate: true }
  268. )
  269. </script>