ElementMultiInstance.vue 9.1 KB

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