index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582
  1. <template>
  2. <div class="sc-workflow-design">
  3. <div class="box-scale">
  4. <node-wrap v-if="nodeConfig" v-model="nodeConfig"></node-wrap>
  5. <div class="node-wrap">
  6. <div class="node-wrap-box start-node">
  7. <div class="title" style="background: var(--el-color-info)">
  8. <span class="title_label">结束</span>
  9. </div>
  10. <div class="content">
  11. <span>流程结束</span>
  12. </div>
  13. </div>
  14. </div>
  15. <!-- <div class="end-node">
  16. <div class="end-node-circle"></div>
  17. <div class="end-node-text">流程结束</div>
  18. </div>-->
  19. </div>
  20. <use-select v-if="selectVisible" ref="useselect" @update:selected="update_activeSelected" @closed="selectVisible = false"></use-select>
  21. </div>
  22. </template>
  23. <script>
  24. import nodeWrap from './nodeWrap'
  25. import useSelect from './select'
  26. // import promoter from '@/components/scWorkflow/nodes/promoter.vue'
  27. export default {
  28. name: 'ScWorkflow',
  29. components: {
  30. // promoter,
  31. nodeWrap,
  32. useSelect
  33. },
  34. provide() {
  35. return {
  36. select: this.selectHandle
  37. }
  38. },
  39. props: {
  40. modelValue: { type: Object, default: () => {} }
  41. },
  42. data() {
  43. return {
  44. nodeConfig: this.modelValue,
  45. selectVisible: false,
  46. activeSelected: [] /*,
  47. end_nodeConfig: {
  48. nodeName: '结束'
  49. // nodeName: '发起人',
  50. // type: 0,
  51. // nodeRoleList: []
  52. }*/
  53. }
  54. },
  55. watch: {
  56. modelValue(val) {
  57. this.nodeConfig = val
  58. },
  59. nodeConfig(val) {
  60. this.$emit('update:modelValue', val)
  61. }
  62. },
  63. mounted() {},
  64. methods: {
  65. update_activeSelected(newSelected) {
  66. this.activeSelected.splice(0, this.activeSelected.length, ...newSelected)
  67. },
  68. selectHandle(type, data) {
  69. this.selectVisible = true
  70. this.activeSelected = data
  71. this.$nextTick(() => {
  72. this.$refs.useselect.open(type, data)
  73. })
  74. }
  75. }
  76. }
  77. </script>
  78. <style lang="scss">
  79. .sc-workflow-design {
  80. width: 100%;
  81. }
  82. .sc-workflow-design .box-scale {
  83. display: inline-block;
  84. position: relative;
  85. width: 100%;
  86. padding: 54.5px 0px;
  87. align-items: flex-start;
  88. justify-content: center;
  89. flex-wrap: wrap;
  90. min-width: min-content;
  91. }
  92. .sc-workflow-design {
  93. .node-wrap {
  94. display: inline-flex;
  95. width: 100%;
  96. flex-flow: column wrap;
  97. justify-content: flex-start;
  98. align-items: center;
  99. padding: 0px 50px;
  100. position: relative;
  101. z-index: 1;
  102. }
  103. .node-wrap-box {
  104. display: inline-flex;
  105. flex-direction: column;
  106. position: relative;
  107. width: 220px;
  108. min-height: 72px;
  109. flex-shrink: 0;
  110. background: rgb(255, 255, 255);
  111. border-radius: 4px;
  112. cursor: pointer;
  113. box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.1);
  114. &.start-node {
  115. .title_label {
  116. &:hover {
  117. text-decoration-line: none;
  118. }
  119. }
  120. }
  121. }
  122. .node-wrap-box::before {
  123. content: '';
  124. position: absolute;
  125. top: -12px;
  126. left: 50%;
  127. transform: translateX(-50%);
  128. width: 0px;
  129. border-style: solid;
  130. border-width: 8px 6px 4px;
  131. border-color: rgb(202, 202, 202) transparent transparent;
  132. background: #f6f8f9;
  133. }
  134. .node-wrap-box.start-node:before {
  135. content: none;
  136. }
  137. .node-wrap-box .title {
  138. height: 24px;
  139. line-height: 24px;
  140. color: #fff;
  141. padding-left: 16px;
  142. padding-right: 30px;
  143. border-radius: 4px 4px 0 0;
  144. position: relative;
  145. display: flex;
  146. align-items: center;
  147. &_label {
  148. display: inline-flex;
  149. align-items: center;
  150. &:hover {
  151. text-decoration-line: underline;
  152. }
  153. .edit-icon {
  154. margin-left: 4px;
  155. }
  156. }
  157. }
  158. .node-wrap-box .title .icon {
  159. margin-right: 5px;
  160. }
  161. .node-wrap-box .title .close {
  162. font-size: 15px;
  163. position: absolute;
  164. top: 50%;
  165. transform: translateY(-50%);
  166. right: 10px;
  167. display: none;
  168. }
  169. .node-wrap-box .content {
  170. position: relative;
  171. padding: 15px;
  172. }
  173. .node-wrap-box .content .placeholder {
  174. color: #999;
  175. }
  176. .node-wrap-box:hover .close {
  177. display: block;
  178. }
  179. .add-node-btn-box {
  180. width: 240px;
  181. display: inline-flex;
  182. flex-shrink: 0;
  183. position: relative;
  184. z-index: 1;
  185. }
  186. .add-node-btn-box:before {
  187. content: '';
  188. position: absolute;
  189. top: 0px;
  190. left: 0px;
  191. right: 0px;
  192. bottom: 0px;
  193. z-index: -1;
  194. margin: auto;
  195. width: 2px;
  196. height: 100%;
  197. background-color: rgb(202, 202, 202);
  198. }
  199. .add-node-btn {
  200. user-select: none;
  201. width: 240px;
  202. padding: 20px 0px 32px;
  203. display: flex;
  204. justify-content: center;
  205. flex-shrink: 0;
  206. flex-grow: 1;
  207. }
  208. .add-node-btn span {
  209. }
  210. .add-branch {
  211. justify-content: center;
  212. padding: 0px 10px;
  213. position: absolute;
  214. top: -16px;
  215. left: 50%;
  216. transform: translateX(-50%);
  217. transform-origin: center center;
  218. z-index: 1;
  219. display: inline-flex;
  220. align-items: center;
  221. }
  222. .branch-wrap {
  223. display: inline-flex;
  224. width: 100%;
  225. }
  226. .branch-box-wrap {
  227. display: flex;
  228. flex-flow: column wrap;
  229. align-items: center;
  230. min-height: 270px;
  231. width: 100%;
  232. flex-shrink: 0;
  233. }
  234. .col-box {
  235. display: inline-flex;
  236. flex-direction: column;
  237. align-items: center;
  238. position: relative;
  239. background: #f6f8f9;
  240. }
  241. .branch-box {
  242. display: flex;
  243. overflow: visible;
  244. min-height: 180px;
  245. height: auto;
  246. border-bottom: 2px solid #ccc;
  247. border-top: 2px solid #ccc;
  248. position: relative;
  249. margin-top: 15px;
  250. }
  251. .branch-box .col-box::before {
  252. content: '';
  253. position: absolute;
  254. top: 0px;
  255. left: 0px;
  256. right: 0px;
  257. bottom: 0px;
  258. z-index: 0;
  259. margin: auto;
  260. width: 2px;
  261. height: 100%;
  262. background-color: rgb(202, 202, 202);
  263. }
  264. .condition-node {
  265. display: inline-flex;
  266. flex-direction: column;
  267. min-height: 220px;
  268. }
  269. .condition-node-box {
  270. padding-top: 30px;
  271. padding-right: 50px;
  272. padding-left: 50px;
  273. justify-content: center;
  274. align-items: center;
  275. flex-grow: 1;
  276. position: relative;
  277. display: inline-flex;
  278. flex-direction: column;
  279. }
  280. .condition-node-box::before {
  281. content: '';
  282. position: absolute;
  283. top: 0px;
  284. left: 0px;
  285. right: 0px;
  286. bottom: 0px;
  287. margin: auto;
  288. width: 2px;
  289. height: 100%;
  290. background-color: rgb(202, 202, 202);
  291. }
  292. .auto-judge {
  293. position: relative;
  294. width: 220px;
  295. min-height: 72px;
  296. background: rgb(255, 255, 255);
  297. border-radius: 4px;
  298. padding: 15px 15px;
  299. cursor: pointer;
  300. box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.1);
  301. }
  302. .auto-judge::before {
  303. content: '';
  304. position: absolute;
  305. top: -12px;
  306. left: 50%;
  307. transform: translateX(-50%);
  308. width: 0px;
  309. border-style: solid;
  310. border-width: 8px 6px 4px;
  311. border-color: rgb(202, 202, 202) transparent transparent;
  312. background: rgb(245, 245, 247);
  313. }
  314. .auto-judge .title {
  315. line-height: 16px;
  316. }
  317. .auto-judge .title .node-title {
  318. color: #15bc83;
  319. &.last-child-title {
  320. color: #999;
  321. }
  322. }
  323. .auto-judge .title .close {
  324. font-size: 15px;
  325. position: absolute;
  326. top: 15px;
  327. right: 15px;
  328. color: #999;
  329. display: none;
  330. }
  331. .auto-judge .title .priority-title {
  332. position: absolute;
  333. top: 15px;
  334. right: 15px;
  335. color: #999;
  336. }
  337. .auto-judge .content {
  338. position: relative;
  339. padding-top: 15px;
  340. &.last-child-title {
  341. padding-top: 5px;
  342. span {
  343. line-height: 1;
  344. }
  345. }
  346. }
  347. .auto-judge .content .placeholder {
  348. color: #999;
  349. }
  350. .auto-judge:hover {
  351. .close {
  352. display: block;
  353. }
  354. .priority-title {
  355. display: none;
  356. }
  357. }
  358. .top-left-cover-line,
  359. .top-right-cover-line {
  360. position: absolute;
  361. height: 3px;
  362. width: 50%;
  363. background-color: #f6f8f9;
  364. top: -2px;
  365. }
  366. .bottom-left-cover-line,
  367. .bottom-right-cover-line {
  368. position: absolute;
  369. height: 3px;
  370. width: 50%;
  371. background-color: #f6f8f9;
  372. bottom: -2px;
  373. }
  374. .top-left-cover-line {
  375. left: -1px;
  376. }
  377. .top-right-cover-line {
  378. right: -1px;
  379. }
  380. .bottom-left-cover-line {
  381. left: -1px;
  382. }
  383. .bottom-right-cover-line {
  384. right: -1px;
  385. }
  386. .end-node {
  387. border-radius: 50%;
  388. font-size: 14px;
  389. color: rgba(25, 31, 37, 0.4);
  390. text-align: left;
  391. }
  392. .end-node-circle {
  393. width: 10px;
  394. height: 10px;
  395. margin: auto;
  396. border-radius: 50%;
  397. background: #dbdcdc;
  398. }
  399. .end-node-text {
  400. margin-top: 5px;
  401. text-align: center;
  402. }
  403. .auto-judge:hover {
  404. .sort-left {
  405. display: flex;
  406. }
  407. .sort-right {
  408. display: flex;
  409. }
  410. }
  411. .auto-judge .sort-left {
  412. position: absolute;
  413. top: 0;
  414. bottom: 0;
  415. z-index: 1;
  416. left: 0;
  417. display: none;
  418. justify-content: center;
  419. align-items: center;
  420. flex-direction: column;
  421. }
  422. .auto-judge .sort-right {
  423. position: absolute;
  424. top: 0;
  425. bottom: 0;
  426. z-index: 1;
  427. right: 0;
  428. display: none;
  429. justify-content: center;
  430. align-items: center;
  431. flex-direction: column;
  432. }
  433. .auto-judge .sort-left:hover,
  434. .auto-judge .sort-right:hover {
  435. background: #eee;
  436. }
  437. .auto-judge:after {
  438. pointer-events: none;
  439. content: '';
  440. position: absolute;
  441. top: 0;
  442. bottom: 0;
  443. left: 0;
  444. right: 0;
  445. z-index: 2;
  446. border-radius: 4px;
  447. transition: all 0.1s;
  448. }
  449. .auto-judge:hover:after {
  450. border: 1px solid #3296fa;
  451. box-shadow: 0 0 6px 0 rgba(50, 150, 250, 0.3);
  452. }
  453. .node-wrap-box:after {
  454. pointer-events: none;
  455. content: '';
  456. position: absolute;
  457. top: 0;
  458. bottom: 0;
  459. left: 0;
  460. right: 0;
  461. z-index: 2;
  462. border-radius: 4px;
  463. transition: all 0.1s;
  464. }
  465. .node-wrap-box:hover:after {
  466. border: 1px solid #3296fa;
  467. box-shadow: 0 0 6px 0 rgba(50, 150, 250, 0.3);
  468. }
  469. }
  470. .tags-list {
  471. margin-top: 15px;
  472. width: 100%;
  473. }
  474. .add-node-popover-body {
  475. ul {
  476. padding: 0;
  477. }
  478. }
  479. .add-node-popover-body li {
  480. display: inline-block;
  481. width: 80px;
  482. text-align: center;
  483. padding: 10px 0;
  484. }
  485. .add-node-popover-body li i {
  486. border: 1px solid var(--el-border-color-light);
  487. width: 40px;
  488. height: 40px;
  489. border-radius: 50%;
  490. text-align: center;
  491. line-height: 38px;
  492. font-size: 18px;
  493. cursor: pointer;
  494. }
  495. .add-node-popover-body li i:hover {
  496. border: 1px solid var(--el-color-primary);
  497. background: var(--el-color-primary);
  498. color: #fff !important;
  499. }
  500. .add-node-popover-body li p {
  501. font-size: 12px;
  502. margin-top: 5px;
  503. }
  504. .node-wrap-drawer__title {
  505. padding-right: 40px;
  506. }
  507. .node-wrap-drawer__title label {
  508. cursor: pointer;
  509. }
  510. .node-wrap-drawer__title label:hover {
  511. border-bottom: 1px dashed var(--el-color-primary);
  512. }
  513. .node-wrap-drawer__title .node-wrap-drawer__title-edit {
  514. color: var(--el-color-primary);
  515. margin-left: 10px;
  516. vertical-align: middle;
  517. }
  518. .dark .sc-workflow-design {
  519. .node-wrap-box,
  520. .auto-judge {
  521. background: #2b2b2b;
  522. }
  523. .col-box {
  524. background: var(--el-bg-color);
  525. }
  526. .top-left-cover-line,
  527. .top-right-cover-line,
  528. .bottom-left-cover-line,
  529. .bottom-right-cover-line {
  530. background-color: var(--el-bg-color);
  531. }
  532. .node-wrap-box::before,
  533. .auto-judge::before {
  534. background-color: var(--el-bg-color);
  535. }
  536. .branch-box .add-branch {
  537. background: var(--el-bg-color);
  538. }
  539. .end-node .end-node-text {
  540. color: #d0d0d0;
  541. }
  542. .auto-judge .sort-left:hover,
  543. .auto-judge .sort-right:hover {
  544. background: var(--el-bg-color);
  545. }
  546. }
  547. $header_height: 55px;
  548. // drawer样式
  549. .aDrawer {
  550. .el-drawer__header {
  551. display: flex;
  552. flex-shrink: 0;
  553. align-items: center;
  554. box-sizing: border-box;
  555. width: 100%;
  556. height: 48px;
  557. padding: 0 16px;
  558. margin-bottom: 0px;
  559. border-bottom: 1px solid var(--el-border-color-lighter);
  560. color: var(--el-overlay-color);
  561. }
  562. .el-drawer__body {
  563. box-sizing: border-box;
  564. height: 100%;
  565. padding: 12px 16px;
  566. overflow: auto;
  567. .el-main {
  568. padding: 0;
  569. }
  570. .el-footer {
  571. padding: 10px 0 0 0;
  572. }
  573. }
  574. }
  575. </style>