processDefinition.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. <template>
  2. <div class="app-container">
  3. <div class="filter-container">
  4. <el-checkbox v-model="listQuery.latestVersion">最新版本</el-checkbox>
  5. <el-checkbox v-model="listQuery.suspended">挂起的</el-checkbox>
  6. <el-checkbox v-model="listQuery.active">激活的</el-checkbox>
  7. </div>
  8. <div class="filter-container">
  9. <el-input
  10. v-model="listQuery.processDefinitionId"
  11. placeholder="流程定义ID"
  12. style="width: 200px"
  13. class="filter-item"
  14. @keyup.enter.native="btnQuery"
  15. />
  16. <el-input
  17. v-model="listQuery.processDefinitionName"
  18. placeholder="流程定义名称"
  19. style="width: 200px"
  20. class="filter-item"
  21. @keyup.enter.native="btnQuery"
  22. />
  23. <el-input
  24. v-model="listQuery.processDefinitionKey"
  25. placeholder="流程定义KEY"
  26. style="width: 200px"
  27. class="filter-item"
  28. @keyup.enter.native="btnQuery"
  29. />
  30. <el-dropdown
  31. split-button
  32. type="primary"
  33. @click="btnQuery"
  34. class="filter-item"
  35. >
  36. <i class="el-icon-search el-icon--left"></i>查询
  37. <el-dropdown-menu slot="dropdown">
  38. <el-dropdown-item icon="el-icon-zoom-out" @click.native="btnReset"
  39. >重置</el-dropdown-item
  40. >
  41. </el-dropdown-menu>
  42. </el-dropdown>
  43. <el-button-group>
  44. <el-button
  45. icon="el-icon-plus"
  46. type="primary"
  47. @click="btnImport"
  48. class="filter-item"
  49. >导入
  50. </el-button>
  51. </el-button-group>
  52. </div>
  53. <el-table
  54. :data="records"
  55. ref="multipleTable"
  56. @selection-change="selectionChange"
  57. border
  58. fit
  59. highlight-current-row
  60. style="width: 100%"
  61. :cell-style="{ padding: '3px' }"
  62. >
  63. <el-table-column type="selection" align="center"> </el-table-column>
  64. <el-table-column label="流程定义名称" prop="name" align="center">
  65. <template slot-scope="scope"
  66. ><span>{{ scope.row.name }}</span></template
  67. >
  68. </el-table-column>
  69. <el-table-column label="流程定义KEY" prop="key" align="center">
  70. <template slot-scope="scope"
  71. ><span>{{ scope.row.key }}</span></template
  72. >
  73. </el-table-column>
  74. <el-table-column label="流程定义分类" prop="category" align="center">
  75. <template slot-scope="scope"
  76. ><span>{{ scope.row.category }}</span></template
  77. >
  78. </el-table-column>
  79. <el-table-column label="版本" prop="version" align="center">
  80. <template slot-scope="scope"
  81. ><span>{{ scope.row.version }}</span></template
  82. >
  83. </el-table-column>
  84. <el-table-column label="状态" prop="suspended" align="center">
  85. <template slot-scope="scope"
  86. ><span>{{ scope.row.suspended ? '挂起' : '激活' }}</span></template
  87. >
  88. </el-table-column>
  89. <el-table-column label="表单key" prop="formKey" align="center">
  90. <template slot-scope="scope"
  91. ><span>{{ scope.row.formKey }}</span></template
  92. >
  93. </el-table-column>
  94. <el-table-column label="操作" align="center">
  95. <template slot-scope="{ row }">
  96. <el-dropdown>
  97. <span class="el-dropdown-link"
  98. >操作<i class="el-icon-arrow-down el-icon--right"></i
  99. ></span>
  100. <el-dropdown-menu slot="dropdown">
  101. <el-dropdown-item icon="el-icon-view" @click.native="btnView(row)"
  102. >查看
  103. </el-dropdown-item>
  104. <el-dropdown-item
  105. icon="el-icon-view"
  106. divided
  107. @click.native="btnImage(row.id)"
  108. >流程图
  109. </el-dropdown-item>
  110. <el-dropdown-item
  111. icon="el-icon-edit"
  112. divided
  113. @click.native="btnProcessDefinitionIdentityLink(row)"
  114. >流程授权
  115. </el-dropdown-item>
  116. <el-dropdown-item
  117. icon="el-icon-edit"
  118. divided
  119. @click.native="btnExport(row)"
  120. >导出
  121. </el-dropdown-item>
  122. <el-dropdown-item
  123. icon="el-icon-edit"
  124. divided
  125. @click.native="btnSuspendOrActivate(row.id, row.suspended)"
  126. >
  127. {{ row.suspended ? '激活' : '挂起' }}
  128. </el-dropdown-item>
  129. <el-dropdown-item
  130. icon="el-icon-delete"
  131. divided
  132. @click.native="btnDelete(row.id)"
  133. >删除
  134. </el-dropdown-item>
  135. <el-dropdown-item
  136. icon="el-icon-delete"
  137. divided
  138. @click.native="btnDelete(row.id, true)"
  139. >删除包含实例
  140. </el-dropdown-item>
  141. <el-dropdown-item
  142. icon="el-icon-view"
  143. divided
  144. @click.native="btnViewProcessInstanceList(row)"
  145. >实例列表
  146. </el-dropdown-item>
  147. <!--<el-dropdown-item icon="el-icon-edit" divided @click.native="btnStartInstance(row)">发起流程
  148. </el-dropdown-item>-->
  149. </el-dropdown-menu>
  150. </el-dropdown>
  151. </template>
  152. </el-table-column>
  153. </el-table>
  154. <pagination
  155. v-show="total > 0"
  156. :total="total"
  157. :current.sync="listQuery.current"
  158. :size.sync="listQuery.size"
  159. @pagination="list"
  160. />
  161. <el-dialog title="流程定义" :visible.sync="dialogFormVisible">
  162. <el-form
  163. ref="dataForm"
  164. :model="temp"
  165. disabled
  166. label-position="right"
  167. label-width="110px"
  168. >
  169. <el-row>
  170. <el-col :span="12">
  171. <el-form-item label="流程定义ID" prop="id">
  172. <el-input v-model="temp.id" />
  173. </el-form-item>
  174. </el-col>
  175. <el-col :span="12">
  176. <el-form-item label="流程定义名称" prop="name">
  177. <el-input v-model="temp.name" />
  178. </el-form-item>
  179. </el-col>
  180. </el-row>
  181. <el-row>
  182. <el-col :span="12">
  183. <el-form-item label="流程定义KEY" prop="key">
  184. <el-input v-model="temp.key" />
  185. </el-form-item>
  186. </el-col>
  187. <el-col :span="12">
  188. <el-form-item label="流程定义分类" prop="category">
  189. <el-input v-model="temp.category" />
  190. </el-form-item>
  191. </el-col>
  192. </el-row>
  193. <el-row>
  194. <el-col :span="12">
  195. <el-form-item label="流程定义描述" prop="description">
  196. <el-input v-model="temp.description" />
  197. </el-form-item>
  198. </el-col>
  199. <el-col :span="12">
  200. <el-form-item label="版本" prop="version">
  201. <el-input v-model="temp.version" />
  202. </el-form-item>
  203. </el-col>
  204. </el-row>
  205. <el-row>
  206. <el-col :span="12">
  207. <el-form-item label="状态" prop="suspended">
  208. <el-input v-model="temp.suspended ? '挂起' : '激活'" />
  209. </el-form-item>
  210. </el-col>
  211. <el-col :span="12">
  212. <el-form-item label="表单key" prop="formKey">
  213. <el-input v-model="temp.formKey" />
  214. </el-form-item>
  215. </el-col>
  216. </el-row>
  217. </el-form>
  218. <div slot="footer" class="dialog-footer">
  219. <el-button icon="el-icon-close" @click="dialogFormVisible = false"
  220. >取消</el-button
  221. >
  222. </div>
  223. </el-dialog>
  224. <el-dialog title="流程定义导入" :visible.sync="dialogImportVisible">
  225. <!--<div class="filter-container">
  226. <el-input v-model="importTenantId" placeholder="租户" clearable style="width: 200px;"/>
  227. </div>-->
  228. <el-upload
  229. class="upload-demo"
  230. drag
  231. action
  232. :show-file-list="false"
  233. :before-upload="beforeUpload"
  234. :http-request="doImport"
  235. >
  236. <i class="el-icon-upload"></i>
  237. <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
  238. <div class="el-upload__tip" slot="tip"
  239. >只能上传.bpmn20.xml,.bpmn,.bar,.zip文件,且不超过512K</div
  240. >
  241. </el-upload>
  242. </el-dialog>
  243. <process-image
  244. v-if="dialogProcessImageVisible"
  245. :visible.sync="dialogProcessImageVisible"
  246. :processDefinitionId="selectedProcessDefinitionId"
  247. ></process-image>
  248. <process-definition-identity-link
  249. v-if="dialogProcessDefinitionIdentityLinkVisible"
  250. :visible.sync="dialogProcessDefinitionIdentityLinkVisible"
  251. :processDefinitionId="selectedProcessDefinitionId"
  252. :processDefinitionName="selectedProcessDefinitionName"
  253. ></process-definition-identity-link>
  254. </div>
  255. </template>
  256. <script>
  257. import Pagination from '@/components/Pagination';
  258. import {
  259. deleteAction,
  260. downloadAction,
  261. getAction,
  262. postAction,
  263. putAction
  264. } from '@/api/flowable/manage';
  265. import { Message } from 'element-ui';
  266. import ProcessImage from './components/ProcessImage';
  267. import ProcessDefinitionIdentityLink from './ProcessDefinitionIdentityLink';
  268. export default {
  269. name: 'FlowableProcessDefinition',
  270. components: { ProcessImage, ProcessDefinitionIdentityLink, Pagination },
  271. data () {
  272. return {
  273. dicts: [],
  274. records: null,
  275. selectedRecords: [],
  276. total: 0,
  277. listQuery: {
  278. current: 1,
  279. size: 10,
  280. processDefinitionId: undefined,
  281. processDefinitionName: undefined,
  282. processDefinitionKey: undefined,
  283. latestVersion: true,
  284. suspended: false,
  285. active: false
  286. },
  287. dialogFormVisible: false,
  288. dialogImportVisible: false,
  289. // importTenantId: '',
  290. dialogProcessImageVisible: false,
  291. imagePath: '',
  292. // formJson: {"list":[{"type":"input","icon":"icon-input","options":{"width":"100%","defaultValue":"","required":false,"dataType":"string","pattern":"","placeholder":"","customClass":"","disabled":false,"labelWidth":100,"isLabelWidth":false,"hidden":false,"dataBind":true,"showPassword":false,"remoteFunc":"func_1575897887618","remoteOption":"option_1575897887618"},"name":"名称","key":"1575897887618","model":"name","rules":[{"type":"string","message":"名称格式不正确"}]}],"config":{"labelWidth":100,"labelPosition":"right","size":"small","customClass":""}},
  293. formJson: undefined,
  294. temp: {
  295. id: undefined,
  296. name: '',
  297. key: '',
  298. category: '',
  299. description: '',
  300. version: '',
  301. latestVersion: '',
  302. suspended: '',
  303. formKey: '',
  304. tenantId: ''
  305. },
  306. dialogProcessDefinitionIdentityLinkVisible: false,
  307. selectedProcessDefinitionId: '',
  308. selectedProcessDefinitionName: ''
  309. };
  310. },
  311. created () {
  312. this.list();
  313. },
  314. methods: {
  315. list () {
  316. getAction('/flowable/processDefinition/list', this.listQuery).then(
  317. (res) => {
  318. // const {data} = res
  319. // this.records = data.records;
  320. // this.total = data.total
  321. if (res.data.code == 0) {
  322. console.log('res.data.data', res.data.data);
  323. const { data } = res;
  324. this.records = res.data.data.list;
  325. this.total = res.data.data.count;
  326. console.log(
  327. 'this.records',
  328. this.records,
  329. 'this.total',
  330. this.total
  331. );
  332. }
  333. }
  334. );
  335. },
  336. btnQuery () {
  337. this.listQuery.current = 1;
  338. this.list();
  339. },
  340. btnReset () {
  341. this.listQuery = {
  342. current: 1,
  343. size: 10,
  344. processDefinitionId: undefined,
  345. processDefinitionName: undefined,
  346. processDefinitionKey: undefined,
  347. latestVersion: true,
  348. suspended: false,
  349. active: false
  350. };
  351. this.list();
  352. },
  353. btnView (row) {
  354. this.temp = Object.assign({}, row);
  355. this.dialogFormVisible = true;
  356. },
  357. btnViewProcessInstanceList (row) {
  358. this.$router.push({
  359. path: '/flowable/processInstance',
  360. query: { processDefinitionId: row.id }
  361. });
  362. },
  363. btnDelete (id, cascade) {
  364. let ids = id
  365. ? [id]
  366. : this.selectedRecords.map((record) => {
  367. return record.id;
  368. });
  369. if (ids.length == 0) {
  370. Message.error('请选择要删除的记录');
  371. return;
  372. }
  373. if (ids.length > 1) {
  374. Message.error('只能选择一条记录');
  375. return;
  376. }
  377. deleteAction('/flowable/processDefinition/delete', {
  378. processDefinitionId: ids.toString(),
  379. cascade: cascade
  380. }).then(({ msg }) => {
  381. Message.success(msg);
  382. this.list();
  383. });
  384. },
  385. btnSuspendOrActivate (processDefinitionId, suspend) {
  386. let suspendOrActivate = suspend ? 'activate' : 'suspend';
  387. putAction('/flowable/processDefinition/' + suspendOrActivate, {
  388. processDefinitionId
  389. }).then(({ msg }) => {
  390. Message.success(msg);
  391. this.list();
  392. });
  393. },
  394. btnImport () {
  395. this.dialogImportVisible = true;
  396. },
  397. beforeUpload (file) {
  398. // 上传前格式与大小校验
  399. const fileName = file.name;
  400. const isFileTypeOk =
  401. fileName.endsWith('.bpmn20.xml') ||
  402. fileName.endsWith('.bpmn') ||
  403. fileName.endsWith('.bar') ||
  404. fileName.endsWith('.zip');
  405. const isLt512 = file.size / 1024 / 512 < 1;
  406. if (!isFileTypeOk) {
  407. Message.error('上传文件格式不正确');
  408. }
  409. if (!isLt512) {
  410. Message.error('上传文件大小不能超过512K');
  411. }
  412. return isFileTypeOk && isLt512;
  413. },
  414. doImport (fileObj) {
  415. let formData = new FormData();
  416. formData.set('file', fileObj.file);
  417. // formData.set("tenantId", this.importTenantId);
  418. postAction('/flowable/processDefinition/import', formData).then(
  419. ({ msg }) => {
  420. this.dialogImportVisible = false;
  421. Message.success(msg);
  422. this.list();
  423. }
  424. );
  425. },
  426. btnExport (row) {
  427. downloadAction(
  428. '/flowable/processDefinition/xml',
  429. 'get',
  430. { processDefinitionId: row.id },
  431. row.name + '-v' + row.version + '.bpmn20.xml'
  432. );
  433. },
  434. btnImage (processDefinitionId) {
  435. // this.imagePath = `${process.env.VUE_APP_BASE_API}` + '/flowable/processDefinition/image?processDefinitionId=' + processDefinitionId + '&access_token=' + getToken() + '&time=' + new Date()
  436. this.selectedProcessDefinitionId = processDefinitionId;
  437. this.dialogProcessImageVisible = true;
  438. },
  439. btnProcessDefinitionIdentityLink (row) {
  440. this.selectedProcessDefinitionId = row.id;
  441. this.selectedProcessDefinitionName = row.name;
  442. this.dialogProcessDefinitionIdentityLinkVisible = true;
  443. },
  444. selectionChange (selectedRecords) {
  445. this.selectedRecords = selectedRecords;
  446. }
  447. }
  448. };
  449. </script>
  450. <style scoped>
  451. .app-container {
  452. padding: 10px;
  453. }
  454. .filter-container .filter-item {
  455. display: inline-block;
  456. vertical-align: middle;
  457. margin-bottom: 5px;
  458. margin-right: 4px;
  459. }
  460. .filter-container {
  461. padding-bottom: 5px;
  462. }
  463. </style>