综合办公系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.vue 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. <!--
  2. * @Author: ysh
  3. * @Date: 2024-01-03 09:23:11
  4. * @LastEditors: Please set LastEditors
  5. * @LastEditTime: 2024-09-23 15:50:44
  6. -->
  7. <template>
  8. <div class="app-container">
  9. <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
  10. <el-form-item label="名称" prop="name">
  11. <el-input v-model="queryParams.name" placeholder="请输入名称" clearable size="small"
  12. @keyup.enter.native="handleQuery" />
  13. </el-form-item>
  14. <el-form-item>
  15. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  16. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  17. </el-form-item>
  18. </el-form>
  19. <el-row :gutter="10" class="mb8">
  20. <el-col :span="1.5">
  21. <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
  22. v-hasPermi="['system:deployment:add']">发起流程</el-button>
  23. </el-col>
  24. <!-- <el-col :span="1.5">
  25. <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete"
  26. v-hasPermi="['system:deployment:remove']">删除</el-button>
  27. </el-col> -->
  28. <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
  29. </el-row>
  30. <el-table v-loading="loading" :data="myProcessList" border @selection-change="handleSelectionChange">
  31. <!-- <el-table-column type="selection" width="55" align="center" /> -->
  32. <el-table-column type="index" label="序号" width="55" align="center" />
  33. <el-table-column label="流程状态" align="center" prop="finishTime" width="100">
  34. <template slot-scope="scope">
  35. <el-tag type="warning" v-if="scope.row.finishTime == null" size="mini">进行中</el-tag>
  36. <el-tag type="success" v-if="scope.row.finishTime != null" size="mini">已完成</el-tag>
  37. </template>
  38. </el-table-column>
  39. <!-- <el-table-column label="流程编号" align="center" prop="procInsId" :show-overflow-tooltip="true" /> -->
  40. <el-table-column label="流程名称" align="center" prop="procDefName" :show-overflow-tooltip="true" />
  41. <el-table-column label="标题" align="center" prop="title" />
  42. <!-- <el-table-column label="流程类别" align="center" prop="category" width="100px" /> -->
  43. <!-- <el-table-column label="流程版本" align="center" width="80px">
  44. <template slot-scope="scope">
  45. <el-tag size="medium">v{{ scope.row.procDefVersion }}</el-tag>
  46. </template>
  47. </el-table-column> -->
  48. <el-table-column label="提交时间" align="center" prop="createTime" width="180" />
  49. <el-table-column label="耗时" align="center" prop="duration" width="180" />
  50. <el-table-column label="当前节点" align="center" prop="taskName" />
  51. <el-table-column label="待办人" align="center">
  52. <template slot-scope="scope">
  53. <label v-if="scope.row.assigneeName">
  54. {{ scope.row.assigneeName }}
  55. <el-tag type="info" size="mini">{{ scope.row.assigneeDeptName }}</el-tag></label>
  56. <!-- <label v-if="scope.row.candidate">{{scope.row.candidate}}</label>-->
  57. </template>
  58. </el-table-column>
  59. <el-table-column label="操作" width="200" fixed="right" class-name="small-padding fixed-width">
  60. <template slot-scope="scope">
  61. <el-button @click="handleFlowRecord(scope.row)" type="text" size="small">办理进度</el-button>
  62. <el-button @click="handleFlowNote(scope.row)" type="text" size="small">表单信息</el-button>
  63. <!-- <el-button @click="handleStop(scope.row)" type="text" size="small">取消申请</el-button> -->
  64. <el-button @click="handleDelete(scope.row)" style="color:#F56C6C" type="text" size="small"
  65. :disabled="beDeleted(scope.row)" v-hasPermi="['system:deployment:remove']">取消流程</el-button>
  66. </template>
  67. </el-table-column>
  68. </el-table>
  69. <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
  70. @pagination="getList" />
  71. <!-- 发起流程 -->
  72. <el-dialog :title="title" :visible.sync="open" width="400px" append-to-body>
  73. <progress-tree :definitionList="definitionList" @confirm="handleStartProcess"
  74. @close="open = false"></progress-tree>
  75. </el-dialog>
  76. <el-dialog title="流程进度" :visible.sync="detailsOpen" append-to-body width="600px">
  77. <el-scrollbar style="height: 600px;">
  78. <RowDetail :rows="clickRow"></RowDetail>
  79. </el-scrollbar>
  80. </el-dialog>
  81. <el-dialog title="表单信息" :visible.sync="formOpen" append-to-body width="80%">
  82. <conditionDisplay :passingParam="passingParam"></conditionDisplay>
  83. </el-dialog>
  84. </div>
  85. </template>
  86. <script>
  87. import {
  88. getDeployment,
  89. delDeployment,
  90. addDeployment,
  91. updateDeployment,
  92. exportDeployment,
  93. flowRecord
  94. } from "@/api/flowable/finished";
  95. import { todoList } from "@/api/flowable/todo";
  96. import { myProcessList, stopProcess } from "@/api/flowable/process";
  97. import { listDefinition } from "@/api/flowable/definition";
  98. import { getNextFlowNodeByStart } from "@/api/flowable/todo";
  99. import { definitionStart, flowXmlAndNode } from "@/api/flowable/definition";
  100. import { Snowflake } from '@/utils/snowFlake.js'
  101. import RowDetail from './send/rowDetail.vue'
  102. import ProgressTree from './progressTree.vue';
  103. import { getProcessVariables } from "@/api/flowable/definition";
  104. import conditionDisplay from '@/views/flowable/form/components/conditionDisplay.vue'
  105. import { deleteResources } from "@/utils/deleteResource"
  106. export default {
  107. name: "Deploy",
  108. components: {
  109. RowDetail,
  110. ProgressTree,
  111. conditionDisplay
  112. },
  113. data() {
  114. return {
  115. // 遮罩层
  116. loading: true,
  117. processLoading: true,
  118. // 选中数组
  119. ids: [],
  120. // 非单个禁用
  121. single: true,
  122. // 非多个禁用
  123. multiple: true,
  124. // 显示搜索条件
  125. showSearch: true,
  126. // 总条数
  127. total: 0,
  128. processTotal: 0,
  129. // 我发起的流程列表数据
  130. myProcessList: [],
  131. // 弹出层标题
  132. title: "",
  133. // 是否显示弹出层
  134. open: false,
  135. // 详情弹出框
  136. detailsOpen: false,
  137. formOpen: false,
  138. src: "",
  139. definitionList: [],
  140. // 查询参数
  141. queryParams: {
  142. pageNum: 1,
  143. pageSize: 20,
  144. name: null,
  145. category: null,
  146. key: null,
  147. tenantId: null,
  148. deployTime: null,
  149. derivedFrom: null,
  150. derivedFromRoot: null,
  151. parentDeploymentId: null,
  152. engineVersion: null
  153. },
  154. // 查询参数
  155. queryProcessParams: {
  156. pageNum: 1,
  157. pageSize: 9999,
  158. name: null,
  159. category: null,
  160. key: null,
  161. tenantId: null,
  162. deployTime: null,
  163. derivedFrom: null,
  164. derivedFromRoot: null,
  165. parentDeploymentId: null,
  166. engineVersion: null
  167. },
  168. // 表单参数
  169. form: {},
  170. // 表单校验
  171. rules: {
  172. },
  173. // 当前点击的行数据
  174. clickRow: {},
  175. passingParam: {},
  176. pathRoute: [
  177. {
  178. name: '借款审批',
  179. path: '/applyForm/borrow'
  180. },
  181. {
  182. name: '用车审批',
  183. path: '/applyForm/carApply'
  184. },
  185. {
  186. name: '设备审批',
  187. path: '/applyForm/deviceApply'
  188. },
  189. {
  190. name: '项目结算',
  191. path: '/applyForm/settleApply'
  192. }
  193. ]
  194. };
  195. },
  196. created() {
  197. this.getList();
  198. },
  199. methods: {
  200. /** 查询流程定义列表 */
  201. getList() {
  202. this.loading = true;
  203. myProcessList(this.queryParams).then(response => {
  204. this.myProcessList = response.data.records;
  205. this.myProcessList.sort((a, b) => {
  206. // 如果有结束时间,则返回1,表示a应该排在b之后
  207. if (a.finishTime) return 1;
  208. // 如果b有结束时间,则返回-1,表示a应该排在b之前
  209. if (b.finishTime) return -1;
  210. // 如果都没有结束时间,则返回0,表示它们的顺序不变
  211. return 0;
  212. })
  213. this.total = response.data.total;
  214. this.loading = false;
  215. });
  216. },
  217. // 取消按钮
  218. cancel() {
  219. this.open = false;
  220. this.reset();
  221. },
  222. // 表单重置
  223. reset() {
  224. this.form = {
  225. id: null,
  226. name: null,
  227. category: null,
  228. key: null,
  229. tenantId: null,
  230. deployTime: null,
  231. derivedFrom: null,
  232. derivedFromRoot: null,
  233. parentDeploymentId: null,
  234. engineVersion: null
  235. };
  236. this.resetForm("form");
  237. },
  238. /** 搜索按钮操作 */
  239. handleQuery() {
  240. this.queryParams.pageNum = 1;
  241. this.getList();
  242. },
  243. /** 重置按钮操作 */
  244. resetQuery() {
  245. this.resetForm("queryForm");
  246. this.handleQuery();
  247. },
  248. /** 搜索按钮操作 */
  249. handleProcessQuery() {
  250. this.queryProcessParams.pageNum = 1;
  251. this.listDefinition();
  252. },
  253. /** 重置按钮操作 */
  254. resetProcessQuery() {
  255. this.resetForm("queryProcessForm");
  256. this.handleProcessQuery();
  257. },
  258. // 多选框选中数据
  259. handleSelectionChange(selection) {
  260. this.ids = selection.map(item => item.procInsId)
  261. this.single = selection.length !== 1
  262. this.multiple = !selection.length
  263. },
  264. // 排序
  265. handleSortChange({ column, prop, order }) {
  266. if (prop === 'finishTime') {
  267. this.myProcessList.sort((a, b) => {
  268. // 如果有结束时间,则排在后面
  269. if (a.finishTime && !b.finishTime) return 1;
  270. // 如果没有结束时间,则排在前面
  271. if (!a.finishTime && b.finishTime) return -1;
  272. // 如果都有或都没有结束时间,则保持原有顺序(或根据其他规则排序)
  273. return 0;
  274. })
  275. }
  276. },
  277. /** 新增按钮操作 */
  278. handleAdd() {
  279. this.open = true;
  280. this.title = "发起流程";
  281. this.listDefinition();
  282. },
  283. listDefinition() {
  284. listDefinition(this.queryProcessParams).then(response => {
  285. this.definitionList = response.data.records;
  286. this.processTotal = response.data.total;
  287. this.processLoading = false;
  288. });
  289. },
  290. /** 发起流程申请 */
  291. handleStartProcess(row) {
  292. console.log(row);
  293. // if (row.category == "assess" || row.category == "car" || ) {
  294. let formId = new Snowflake(1n, 1n, 0n).nextId().toString();
  295. getNextFlowNodeByStart({ deploymentId: row.deploymentId, variables: { formId: formId } }).then(res => {
  296. let data = res.data;
  297. if (data.dataType === 'dynamic') {
  298. if (data.type === 'assignee') { // 指定人员
  299. this.checkSendUser = true;
  300. this.checkType = "single";
  301. } else if (data.type === 'candidateUsers') { // 候选人员(多个)
  302. this.checkSendUser = true;
  303. this.checkType = "multiple";
  304. } else if (data.type === 'candidateGroups') { // 指定组(所属角色接收任务)
  305. this.checkSendRole = true;
  306. } else { // 会签
  307. // 流程设计指定的 elementVariable 作为会签人员列表
  308. this.multiInstanceVars = data.vars;
  309. this.checkSendUser = true;
  310. this.checkType = "multiple";
  311. }
  312. this.taskOpen = true;
  313. this.taskTitle = "选择任务接收";
  314. } else {
  315. const variables = {};
  316. const formData = {};
  317. formData.disabled = true;
  318. formData.formBtns = false;
  319. formData.formId = formId
  320. if (row.id) {
  321. variables.variables = formData;
  322. let routePath = this.getRoutePath(row);
  323. // 启动流程并将表单数据加入流程变量
  324. definitionStart(row.id, JSON.stringify(variables)).then(res => {
  325. this.$modal.msgSuccess(res.msg);
  326. let procInstanceId = res.data;
  327. todoList({
  328. pageNum: 1,
  329. pageSize: 99999999, processInsId: procInstanceId
  330. }).then(toDoRes => {
  331. let records = toDoRes.data.records;
  332. if (records.length == 1) {
  333. records = records[0]
  334. }
  335. this.$router.push({
  336. path: routePath,
  337. query: {
  338. procInsId: records.procInsId,
  339. executionId: records.executionId,
  340. deployId: records.deployId,
  341. taskId: records.taskId,
  342. taskName: records.taskName,
  343. startUser: records.startUserName + '-' + records.startDeptName,
  344. formId: formData.formId,
  345. procDefName: records.procDefName
  346. }
  347. })
  348. })
  349. // this.goBack();
  350. // this.$router.push({
  351. // path: '/flowable/task/myProcess/send/index',
  352. // query: {
  353. // deployId: row.deploymentId,
  354. // procDefId: row.id,
  355. // name: row.name
  356. // }
  357. // })
  358. })
  359. }
  360. }
  361. })
  362. // } else {
  363. // }
  364. },
  365. getRoutePath(row) {
  366. let path;
  367. for (let p of this.publicData.pathRoute) {
  368. if (p.name == row.name) {
  369. path = p.path
  370. break
  371. } else {
  372. path = '/flowable/task/todo/detail/index'
  373. }
  374. }
  375. return path
  376. },
  377. /** 取消流程申请 */
  378. handleStop(row) {
  379. const params = {
  380. instanceId: row.procInsId
  381. }
  382. stopProcess(params).then(res => {
  383. this.$modal.msgSuccess(res.msg);
  384. this.getList();
  385. });
  386. },
  387. /** 流程流转记录 */
  388. handleFlowRecord(row) {
  389. // this.$router.push({
  390. // path: '/flowable/task/myProcess/detail/index',
  391. // query: {
  392. // procInsId: row.procInsId,
  393. // deployId: row.deployId,
  394. // taskId: row.taskId
  395. // }
  396. // })
  397. this.clickRow = row;
  398. this.detailsOpen = true;
  399. },
  400. // 表单信息
  401. handleFlowNote(row) {
  402. getProcessVariables(row.taskId).then(res => {
  403. if (res.data) {
  404. this.passingParam = row
  405. this.passingParam.formId = res.data.formId
  406. this.formOpen = true
  407. }
  408. })
  409. },
  410. /** 修改按钮操作 */
  411. handleUpdate(row) {
  412. this.reset();
  413. const id = row.id || this.ids
  414. getDeployment(id).then(response => {
  415. this.form = response.data;
  416. this.open = true;
  417. this.title = "修改流程定义";
  418. });
  419. },
  420. /** 提交按钮 */
  421. submitForm() {
  422. this.$refs["form"].validate(valid => {
  423. if (valid) {
  424. if (this.form.id != null) {
  425. updateDeployment(this.form).then(response => {
  426. this.$modal.msgSuccess("修改成功");
  427. this.open = false;
  428. this.getList();
  429. });
  430. } else {
  431. addDeployment(this.form).then(response => {
  432. this.$modal.msgSuccess("新增成功");
  433. this.open = false;
  434. this.getList();
  435. });
  436. }
  437. }
  438. });
  439. },
  440. /** 删除按钮操作 */
  441. handleDelete(row) {
  442. const ids = row.procInsId || this.ids;// 暂不支持删除多个流程
  443. this.$confirm('取消流程将删除对应数据,是否确定取消流程?', "警告", {
  444. confirmButtonText: "确定",
  445. cancelButtonText: "取消",
  446. type: "warning"
  447. }).then(() => {
  448. getProcessVariables(row.taskId).then(res => {
  449. if (res.data) {
  450. let delId = res.data.formId;
  451. this.deleteDataByUrl(row.procDefName, delId)
  452. }
  453. return delDeployment(ids);
  454. }).then(() => {
  455. this.getList();
  456. this.$modal.msgSuccess("流程取消成功");
  457. })
  458. })
  459. },
  460. deleteDataByUrl(procDefName, id) {
  461. return deleteResources(procDefName, id)
  462. },
  463. // 子流程不可以删除
  464. beDeleted(row) {
  465. if (row.procDefName == '项目预算' || row.procDefName == '技术方案' || row.procDefName == '安全交底' || row.procDefName == '技术交底' || row.finishTime != null) {
  466. return true
  467. } else if (row.procDefName == '项目流转' && row.taskName != '项目登记') {
  468. return true
  469. } else {
  470. return false
  471. }
  472. },
  473. /** 导出按钮操作 */
  474. handleExport() {
  475. const queryParams = this.queryParams;
  476. this.$confirm('是否确认导出所有流程定义数据项?', "警告", {
  477. confirmButtonText: "确定",
  478. cancelButtonText: "取消",
  479. type: "warning"
  480. }).then(() => {
  481. return exportDeployment(queryParams);
  482. }).then(response => {
  483. this.download(response.msg);
  484. })
  485. }
  486. }
  487. };
  488. </script>