processSubmitDialog.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. <template>
  2. <ele-modal
  3. custom-class="ele-dialog-form long-dialog-form"
  4. :centered="true"
  5. :visible="processSubmitDialogFlag"
  6. title="提交审核"
  7. append-to-body
  8. :close-on-click-modal="false"
  9. width="50%"
  10. :before-close="cancel"
  11. >
  12. <!-- <el-steps :active="active" align-center style="transform: scale(0.8)">-->
  13. <!-- <el-step title="流程发起"></el-step>-->
  14. <!-- <el-step title="流程通知"></el-step>-->
  15. <!-- </el-steps>-->
  16. <el-form
  17. ref="form"
  18. :rules="rules"
  19. class="el-form-box"
  20. :model="form"
  21. label-width="80px"
  22. >
  23. <el-row v-show="active == 0">
  24. <el-col :span="12">
  25. <el-form-item label="流程分类">
  26. <ele-tree-select
  27. @change="changeLCFL"
  28. clearable
  29. ref="processTypeRef"
  30. filterable
  31. :data="LCFLList"
  32. v-model="form.LCFL"
  33. childrenKey="children"
  34. valueKey="id"
  35. labelKey="name"
  36. placeholder="请选择"
  37. default-expand-all
  38. />
  39. </el-form-item>
  40. </el-col>
  41. <el-col :span="12">
  42. <el-form-item label="发起流程">
  43. <el-select
  44. filterable
  45. v-model="form.FQLC"
  46. @change="changeFQLC"
  47. style="width: 100%"
  48. >
  49. <el-option
  50. v-for="item in processList"
  51. :key="item.id"
  52. :value="item.id"
  53. :label="item.name"
  54. ></el-option>
  55. </el-select>
  56. </el-form-item>
  57. </el-col>
  58. </el-row>
  59. <el-row v-show="active == 0">
  60. <el-col :span="12">
  61. <el-form-item label="流程名称">
  62. <el-input v-model="form.name" clearable></el-input>
  63. </el-form-item>
  64. </el-col>
  65. <el-col :span="12">
  66. <el-form-item label="流程标识">
  67. <el-input v-model="form.key" disabled></el-input>
  68. </el-form-item>
  69. </el-col>
  70. </el-row>
  71. <headerTitle
  72. v-show="active == 0"
  73. title="流程执行人/流程图"
  74. style="margin-top: 30px"
  75. ></headerTitle>
  76. <el-table
  77. v-show="active == 0"
  78. :data="datasource"
  79. border
  80. style="margin-bottom: 10px"
  81. >
  82. <el-table-column
  83. label="任务节点"
  84. align="center"
  85. prop="taskDefinitionName"
  86. width="140"
  87. fixed
  88. />
  89. <el-table-column
  90. label="执行人"
  91. align="center"
  92. prop="options"
  93. min-width="140px"
  94. >
  95. <template v-slot="scope">
  96. <div v-if="scope.row.type !== 60 && scope.row.options.length > 0">
  97. <el-tag
  98. size="medium"
  99. :key="option"
  100. v-for="option in scope.row.options"
  101. >
  102. {{ getAssignRuleOptionName(scope.row, option) }}
  103. </el-tag>
  104. </div>
  105. <el-tag size="medium" v-if="scope.row.type === 60">
  106. {{ getAssignRuleOptionName(scope.row) }}
  107. </el-tag>
  108. </template>
  109. </el-table-column>
  110. </el-table>
  111. <my-process-viewer
  112. v-show="active == 0"
  113. style="min-width: 100%; height: 200px"
  114. key="designer"
  115. v-model="bpmnXML"
  116. />
  117. <el-table v-show="active == 1" :data="form.noticeScope" border>
  118. <el-table-column
  119. label="类型"
  120. align="center"
  121. prop="taskDefinitionName"
  122. width="140"
  123. fixed
  124. />
  125. <el-table-column
  126. label="结果"
  127. align="center"
  128. prop="options"
  129. min-width="140px"
  130. >
  131. </el-table-column>
  132. </el-table>
  133. </el-form>
  134. <div slot="footer">
  135. <!-- <el-button-->
  136. <!-- type="primary"-->
  137. <!-- size="small"-->
  138. <!-- v-if="active == 0"-->
  139. <!-- @click="() => (active = 1)"-->
  140. <!-- >下一步-->
  141. <!-- </el-button>-->
  142. <!-- <el-button-->
  143. <!-- type="primary"-->
  144. <!-- size="small"-->
  145. <!-- v-if="active == 1"-->
  146. <!-- @click="() => (active = 0)"-->
  147. <!-- >上一步-->
  148. <!-- </el-button>-->
  149. <el-button type="primary" size="small" @click="submit" v-click-once
  150. >提交</el-button
  151. >
  152. <el-button
  153. v-if="isNotNeedProcess && $hasPermission('eom:common:submitrelease')"
  154. type="primary"
  155. size="small"
  156. @click="submit1"
  157. v-click-once
  158. >提交并发布</el-button
  159. >
  160. <el-button size="small" @click="cancel">关闭</el-button>
  161. </div>
  162. </ele-modal>
  163. </template>
  164. <script>
  165. import {
  166. getModelPage,
  167. getProcessDefinitionBpmnXML,
  168. getProcessDefinitionInfo,
  169. getTaskAssignRuleList,
  170. listAllUserBind,
  171. listSimpleUserGroups,
  172. processInstanceCreateAPI,getProduceTreeByCode
  173. } from './api';
  174. import { treeClassifyCodeEnum } from '@/enum/dict';
  175. import { listRoles } from '@/api/system/role';
  176. import { listOrganizations } from '@/api/system/organization';
  177. import dictMixins from '@/mixins/dictMixins';
  178. import { getByCode } from '@/api/system/dictionary-data';
  179. export default {
  180. name: 'processSubmitDialog',
  181. mixins: [dictMixins],
  182. props: {
  183. processSubmitDialogFlag: {
  184. type: Boolean,
  185. default: false
  186. },
  187. isNotNeedProcess: {
  188. type: Boolean,
  189. default: false
  190. },
  191. approvalStatus: {
  192. type: Number,
  193. default: 2
  194. },
  195. apiFunName: {
  196. type: String,
  197. default: ''
  198. }
  199. },
  200. data() {
  201. return {
  202. form: {
  203. LCFL: '',
  204. FQLC: '',
  205. processDefinitionId: '',
  206. name: '',
  207. businessId: '',
  208. noticeScope: [],
  209. businessKey: '',
  210. formCreateUserId: ''
  211. },
  212. active: 0,
  213. bpmnXML: null,
  214. LCFLList: [],
  215. processList: [],
  216. datasource: [],
  217. roleOptions: [],
  218. deptOptions: [],
  219. deptTreeOptions: [],
  220. postOptions: [],
  221. userOptions: [],
  222. userGroupOptions: [],
  223. dictList: {},
  224. rules: {}
  225. };
  226. },
  227. async created() {
  228. let typeObj = await getProduceTreeByCode(
  229. 'PROCESS001'
  230. );
  231. this.LCFLList = typeObj[0].children;
  232. // 获得角色列表
  233. this.roleOptions = [];
  234. listRoles({
  235. current: 1,
  236. size: 9999
  237. }).then((data) => {
  238. this.roleOptions.push(...data.list);
  239. });
  240. // 获得部门列表
  241. this.deptOptions = [];
  242. this.deptTreeOptions = [];
  243. listOrganizations().then((data) => {
  244. this.deptOptions.push(...data);
  245. this.deptTreeOptions.push(...this.handleTree(data, 'id'));
  246. });
  247. // 获得岗位列表 暂无岗位概念
  248. this.postOptions = [];
  249. /*listSimplePosts().then(response => {
  250. this.postOptions.push(...response.data);
  251. });*/
  252. // 获得用户列表
  253. this.userOptions = [];
  254. listAllUserBind().then((data) => {
  255. this.userOptions.push(...data);
  256. });
  257. // 获得用户组列表
  258. this.userGroupOptions = [];
  259. listSimpleUserGroups().then((response) => {
  260. this.userGroupOptions.push(...response);
  261. });
  262. //this.dictEnum['工作流任务分配自定义脚本']
  263. await this.getDictList(this.dictEnum['工作流任务分配自定义脚本']);
  264. await this.getDictList(this.dictEnum['工种类型']);
  265. },
  266. methods: {
  267. init(row = {}) {
  268. this.form = { ...this.form, ...row };
  269. // this.form.businessId = row.id;
  270. // this.form.businessKey = row.businessKey;
  271. // this.form.formCreateUserId = row.createUserId;
  272. this.getDefaultInfo(row.businessKey);
  273. },
  274. async getDefaultInfo(businessKey) {
  275. let info = await getProcessDefinitionInfo({ code: businessKey });
  276. this.form.LCFL = info?.category;
  277. this.form.FQLC = info?.modelId;
  278. this.form.name = info?.name;
  279. this.form.key = info?.key;
  280. this.form.processDefinitionId = info?.id;
  281. if (this.form.LCFL) await this.getProcessList(this.form.LCFL);
  282. if (this.form.FQLC) {
  283. await this.getProcessDefinitionBpmnXMLInfo(info.id);
  284. await this.getTaskAssignRuleListInfo({
  285. modelId: info.modelId,
  286. processDefinitionId: info.id
  287. });
  288. }
  289. },
  290. async changeLCFL(val) {
  291. this.bpmnXML = null;
  292. this.form.processDefinitionId = null;
  293. this.form.FQLC = null;
  294. await this.getProcessList(val);
  295. },
  296. async getProcessList(val) {
  297. let params = {
  298. pageNo: 1,
  299. pageSize: 999,
  300. processTypeId: val
  301. };
  302. const { list } = await getModelPage(params);
  303. this.processList = list.filter((item) => item.processDefinition);
  304. },
  305. async changeFQLC(val) {
  306. if (!val) return;
  307. let find = this.processList.find((item) => item.id === val) || {};
  308. this.form.name = find.name;
  309. this.form.key = find.key;
  310. this.form.processDefinitionId = find.processDefinition.id;
  311. await this.getProcessDefinitionBpmnXMLInfo(find.processDefinition.id);
  312. await this.getTaskAssignRuleListInfo({
  313. modelId: find.id,
  314. processDefinitionId: find.processDefinition.id
  315. });
  316. },
  317. async getProcessDefinitionBpmnXMLInfo(val) {
  318. // 加载流程图
  319. this.bpmnXML = await getProcessDefinitionBpmnXML(val);
  320. },
  321. async getTaskAssignRuleListInfo(find) {
  322. this.datasource = await getTaskAssignRuleList({
  323. modelId: find.modelId,
  324. processDefinitionId: find.processDefinitionId
  325. });
  326. },
  327. getAssignRuleOptionName(row, option) {
  328. console.log(row,'row')
  329. if (row.type == 10) {
  330. for (const roleOption of this.roleOptions) {
  331. if (roleOption.id === option) {
  332. return roleOption.name;
  333. }
  334. }
  335. } else if (row.type === 20 || row.type === 21) {
  336. for (const deptOption of this.deptOptions) {
  337. if (deptOption.id === option) {
  338. return deptOption.name;
  339. }
  340. }
  341. } else if (row.type === 22) {
  342. option = option + ''; // 转换成 string
  343. return this.getDictV(this.dictEnum['工种类型'], option);
  344. } else if (row.type === 30 || row.type === 31 || row.type === 32) {
  345. for (const userOption of this.userOptions) {
  346. if (userOption.id === option) {
  347. return userOption.nickname || userOption.name;
  348. }
  349. }
  350. } else if (row.type === 40) {
  351. for (const userGroupOption of this.userGroupOptions) {
  352. if (userGroupOption.id === option) {
  353. return userGroupOption.name;
  354. }
  355. }
  356. } else if (row.type === 50) {
  357. option = option + ''; // 转换成 string
  358. return this.getDictV(
  359. this.dictEnum['工作流任务分配自定义脚本'],
  360. option
  361. );
  362. } else if (row.type === 60) {
  363. return row.variableName;
  364. }
  365. return '未知(' + option + ')';
  366. },
  367. /**
  368. * 构造树型结构数据
  369. * @param {*} data 数据源
  370. * @param {*} id id字段 默认 'id'
  371. * @param {*} parentId 父节点字段 默认 'parentId'
  372. * @param {*} children 孩子节点字段 默认 'children'
  373. * @param {*} rootId 根Id 默认 0
  374. */
  375. handleTree(data, id, parentId, children, rootId) {
  376. id = id || 'id';
  377. parentId = parentId || 'parentId';
  378. children = children || 'children';
  379. rootId =
  380. rootId ||
  381. Math.min.apply(
  382. Math,
  383. data.map((item) => {
  384. return item[parentId];
  385. })
  386. ) ||
  387. 0;
  388. //对源数据深度克隆
  389. const cloneData = JSON.parse(JSON.stringify(data));
  390. //循环所有项
  391. const treeData = cloneData.filter((father) => {
  392. let branchArr = cloneData.filter((child) => {
  393. //返回每一项的子级数组
  394. return father[id] == child[parentId];
  395. });
  396. branchArr.length > 0 ? (father.children = branchArr) : '';
  397. //返回第一层
  398. return father[parentId] == rootId;
  399. });
  400. return treeData !== '' ? treeData : data;
  401. },
  402. getDictV(code, val) {
  403. if (!this.dictList[code]) return '';
  404. return this.dictList[code].find((item) => item.value == val)?.label;
  405. },
  406. async getDictList(code) {
  407. let { data: res } = await getByCode(code);
  408. this.dictList[code] = res.map((item) => {
  409. let values = Object.keys(item);
  410. return {
  411. value: values[0],
  412. label: item[values[0]]
  413. };
  414. });
  415. },
  416. async submit() {
  417. await processInstanceCreateAPI(this.form);
  418. this.$message('提交审核成功');
  419. this.$emit('reload');
  420. this.cancel();
  421. },
  422. async submit1() {
  423. let params = {
  424. id: this.form.businessId,
  425. approvalStatus: this.approvalStatus,
  426. ...this.form
  427. };
  428. await this[this.apiFunName](params);
  429. //await processInstanceUpdateStatusAPI(params);
  430. this.$message('提交发布成功');
  431. this.$emit('reload');
  432. this.cancel();
  433. },
  434. cancel() {
  435. this.$emit('update:processSubmitDialogFlag', false);
  436. }
  437. }
  438. };
  439. </script>
  440. <style scoped lang="scss"></style>