index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. <template>
  2. <div class="TemplateManagementNew">
  3. <!-- <Breadcrumb separator=">" class="breadcrumb">
  4. <BreadcrumbItem to="/TemplateManagementLists">模版管理</BreadcrumbItem>
  5. <BreadcrumbItem>{{$route.params.id != '-1'?'编辑模版':'新建模版'}}</BreadcrumbItem>
  6. </Breadcrumb> -->
  7. <!-- 预览状态 -->
  8. <div class="content" v-if="this.readOnly">
  9. <div class="tips" v-if="currentSteps === 2">
  10. <p>
  11. <span>单据类型:</span><span>{{data.businessTypeText}}</span>
  12. </p>
  13. <p>
  14. <span>模版名称:</span><span>{{data.name}}</span>
  15. </p>
  16. <p>
  17. <span>查询索引:</span><span>{{data.businessKey}}</span>
  18. </p>
  19. <p>
  20. <span>模版描述:</span><span>{{data.description}}</span>
  21. </p>
  22. <p>
  23. <span>自动处理:</span><span>{{data.autoClose?'开':'关'}}</span>
  24. </p>
  25. <p>
  26. <span>业务数据检查:</span><span>{{data.businessCheckUrl}}</span>
  27. </p>
  28. </div>
  29. <FlowChartComponent
  30. v-if="currentSteps === 2"
  31. :data="data"
  32. :currentSteps="2"
  33. :readOnly="readOnly"
  34. ref="component_2"
  35. >
  36. </FlowChartComponent>
  37. <p class="buttonGroups" v-if="currentSteps === 2">
  38. <Button type="primary" @click="close">关闭</Button>
  39. </p>
  40. </div>
  41. <!-- 编辑状态 -->
  42. <Steps :current="currentSteps" class="steps" v-if="!this.readOnly">
  43. <Step title="参数配置" ></Step>
  44. <Step title="流程设计器" ></Step>
  45. <Step title="保存发布模版" ></Step>
  46. </Steps>
  47. <div class="content" v-if="!this.readOnly">
  48. <keep-alive exclude="component_2" >
  49. <component
  50. :is="currentComponent"
  51. :ref="currentComponent"
  52. class="block"
  53. :editable="currentSteps === 1?true:false"
  54. :data="data"
  55. :currentSteps="currentSteps"
  56. :noFreshFlag="noFreshFlag"
  57. @dataChange=dataChange
  58. >
  59. </component>
  60. </keep-alive>
  61. <p class="buttonGroups">
  62. <Button type="primary" v-if="currentSteps > 0" @click="previousSteps">上一步</Button>
  63. <Button type="primary" v-if="currentSteps < 2" @click="nextSteps">下一步</Button>
  64. <Button type="primary" v-if="(currentSteps === 2 && this.data.status !== 1)" @click="confirm(false)">保存</Button>
  65. <Button type="primary" v-if="(currentSteps === 2 && this.data.status !== 1)" @click="confirmAndPublish()">保存并发布</Button>
  66. </p>
  67. </div>
  68. </div>
  69. </template>
  70. <script>
  71. import '@/utils/go'
  72. import Vue from 'vue'
  73. import ParameterConfiguration from '@/components/ParameterConfiguration'
  74. import FlowChartComponent from '@/components/FlowChartComponent'
  75. import FlowSuccess from '@/components/FlowSuccess'
  76. import { mapMutations } from 'vuex';
  77. import { setTimeout } from 'timers';
  78. import {
  79. getLoad,
  80. getCommit,
  81. getDuplicate,
  82. getPublish
  83. } from '@/api/modeler.js'
  84. export default {
  85. name:'TemplateManagementNew',
  86. components:{ParameterConfiguration,FlowChartComponent,FlowSuccess},
  87. data () {
  88. return {
  89. currentSteps:0,
  90. currentComponent:null,
  91. imgBase:'',
  92. defaultData:{
  93. guiStyle:JSON.stringify({
  94. "class": "NewGraphLinksModel",
  95. "linkFromPortIdProperty": "fromPort",
  96. "linkToPortIdProperty": "toPort",
  97. "nodeDataArray": [
  98. {"key":-1, "category":"Start", "loc":"175 0", "text":"开始", "type": 1},
  99. {"key":0, "loc":"175 100", "text":"审批节点","type": 0, "category": 'Approval'},
  100. {"key":-2, "category":"End", "loc":"175 200", "text":"结束", "type": 2}
  101. ],
  102. "linkDataArray": [
  103. {"from":-1, "to":0, "fromPort":"B", "toPort":"T","key":0},
  104. {"from":0, "to":-2, "fromPort":"B", "toPort":"T","key":1}
  105. ]
  106. }),
  107. nodeMsg:[
  108. {"key":-1, "category":"Start", "loc":"175 0", "text":"开始", "name":"开始", "type": 1,"ruleList":[]},
  109. {"key":0, "loc":"175 100", "text":"审批节点", "name":"审批节点", "category": 'Approval',"type": 0,"ruleList":[],"actServiceS":[],"actionConfig":[],"approvelList":[],"approverStyle":0},
  110. {"key":-2, "category":"End", "loc":"175 200", "text":"结束", "name":"结束", "type": 2,"actionConfig":[{
  111. handleValue:null,
  112. extra_msg:{},
  113. handleType:31
  114. },
  115. {
  116. handleValue:'{}',
  117. extra_msg:{},
  118. handleType:41
  119. }]}
  120. ],
  121. pathMsg:[
  122. {"from":-1, "to":0, "fromPort":"B", "toPort":"T","ruleList":[],"key":0},
  123. {"from":0, "to":-2, "fromPort":"B", "toPort":"T","ruleList":[],"key":1}
  124. ],
  125. removeNode:[],
  126. removePath:[],
  127. },
  128. data:{
  129. guiStyle:JSON.stringify({
  130. "class": "NewGraphLinksModel",
  131. "linkFromPortIdProperty": "fromPort",
  132. "linkToPortIdProperty": "toPort",
  133. "nodeDataArray": [
  134. {"key":-1, "category":"Start", "loc":"175 0", "text":"开始", "type": 1},
  135. {"key":0, "loc":"175 100", "text":"审批节点","type": 0, "category": 'Approval'},
  136. {"key":-2, "category":"End", "loc":"175 200", "text":"结束", "type": 2}
  137. ],
  138. "linkDataArray": [
  139. {"from":-1, "to":0, "fromPort":"B", "toPort":"T","key":0},
  140. {"from":0, "to":-2, "fromPort":"B", "toPort":"T","key":1}
  141. ]
  142. }),
  143. nodeMsg:[
  144. {"key":-1, "category":"Start", "loc":"175 0", "text":"开始", "name":"开始", "type": 1,"ruleList":[]},
  145. {"key":0, "loc":"175 100", "text":"审批节点", "name":"审批节点", "category": 'Approval',"type": 0,"ruleList":[],"actServiceS":[],"actionConfig":[],"approvelList":[],"approverStyle":0},
  146. {"key":-2, "category":"End", "loc":"175 200", "text":"结束", "name":"结束", "type": 2,"actionConfig":[{
  147. handleValue:null,
  148. extra_msg:{},
  149. handleType:31
  150. },
  151. {
  152. handleValue:'{}',
  153. extra_msg:{},
  154. handleType:41
  155. }]}
  156. ],
  157. pathMsg:[
  158. {"from":-1, "to":0, "fromPort":"B", "toPort":"T","ruleList":[],"key":0},
  159. {"from":0, "to":-2, "fromPort":"B", "toPort":"T","ruleList":[],"key":1}
  160. ],
  161. removeNode:[],
  162. removePath:[],
  163. autoClose: true,
  164. moduleType: 0
  165. },
  166. noFreshFlag:false,
  167. readOnly:false, //是否只读为预览模式
  168. //存放三步骤的数据
  169. defaultModuleType: null, //暂存模版类型
  170. }
  171. },
  172. watch:{
  173. currentSteps (val) {
  174. if(this.readOnly){
  175. return
  176. }
  177. let componentName = `component_${val}`
  178. if(Vue.component(componentName) === undefined){
  179. if(val === 0 ){
  180. Vue.component(componentName,ParameterConfiguration)
  181. }else if(val === 1){
  182. Vue.component(componentName,FlowChartComponent)
  183. }else if(val === 2){
  184. Vue.component(componentName,FlowSuccess)
  185. }
  186. }
  187. this.currentComponent = componentName
  188. }
  189. },
  190. methods:{
  191. ...mapMutations(['currentChange']),
  192. getModuleInfo (id) {
  193. getLoad({id:id}).then((res) => {
  194. if(res.resultCode === 0){
  195. res.data.businessType = [{
  196. ID:res.data.businessType,
  197. Label:res.data.businessTypeName,
  198. val:res.data.businessTypeText
  199. }]
  200. res.data.businessNumber = [{
  201. ID:String(res.data.businessKeyId),
  202. Label:res.data.businessKey,
  203. val:res.data.businessKeyName
  204. }]
  205. this.data = res.data
  206. this.data.guiStyle = JSON.parse(res.data.guiStyle)
  207. this.data.moduleId = res.data.id
  208. this.$nextTick(() => {
  209. if(this.readOnly){
  210. this.currentSteps = 2
  211. this.noFreshFlag = false
  212. }else{
  213. this.$refs.component_1.init()
  214. this.noFreshFlag = false
  215. }
  216. })
  217. }
  218. });
  219. },
  220. async nextSteps () { //下一步
  221. if(await this.checkModuleName()){
  222. return false
  223. }
  224. if(this.currentSteps === 0 && (this.defaultModuleType != this.data.moduleType) && this.defaultModuleType !== null){
  225. this.$Modal.fcWarning({
  226. title:'警告',
  227. content:'您已修改模板类型/单据类型,这将导致下一步的流程设计器内所有设置恢复初始化,是否确定更改?',
  228. showCancel: true,
  229. mask: true,
  230. onOk: () => {
  231. this.defaultModuleType = this.data.moduleType
  232. this.data = Object.assign(this.data,JSON.parse(JSON.stringify(this.defaultData)))
  233. if(this.data.businessType && this.data.businessType.length > 0 && this.data.name){
  234. this.defaultModuleType = this.data.moduleType
  235. ++this.currentSteps
  236. }else{
  237. this.$Modal.fcWarning({
  238. title:'警告',
  239. content:'请填写必填项!',
  240. mask:true
  241. })
  242. }
  243. },
  244. onCancel: () => {
  245. }
  246. })
  247. return
  248. }
  249. if( this.data.name && (this.data.moduleType === 0?(this.data.businessType && this.data.businessType.length > 0):true) ){
  250. this.defaultModuleType = this.data.moduleType
  251. ++this.currentSteps
  252. }else{
  253. this.$Modal.fcWarning({
  254. title:'警告',
  255. content:'请填写必填项!',
  256. mask:true
  257. })
  258. }
  259. },
  260. async checkModuleName () {
  261. await new Promise((resolve, reject) => {
  262. let jsonObject = {
  263. ID:this.data.moduleId,
  264. NAME:this.data.name
  265. }
  266. getDuplicate(jsonObject).then(res => {
  267. if(res.resultCode !== 0){
  268. this.$Modal.fcWarning({
  269. title:'警告',
  270. content:res.resultMsg,
  271. mask:true
  272. })
  273. reject()
  274. }
  275. resolve(res)
  276. })
  277. })
  278. },
  279. previousSteps () { //上一步
  280. --this.currentSteps
  281. },
  282. async confirm (flag) { //确定
  283. return await new Promise((resolve,reject) => {
  284. var svg = this.data.myDisplay.makeImage({
  285. scale: 2
  286. });
  287. this.imgBase = svg.getAttribute('src')
  288. let nodeMsg = []
  289. Object.keys(this.data.nodeMsg).map(item => {
  290. nodeMsg.push(this.data.nodeMsg[item])
  291. return item
  292. })
  293. let pathMsg = []
  294. Object.keys(this.data.pathMsg).map(item => {
  295. pathMsg.push(this.data.pathMsg[item])
  296. return item
  297. })
  298. let jsonObject = {
  299. id:this.data.moduleId,
  300. name:this.data.name,
  301. description:this.data.description,
  302. GUI_STYLE:this.data.guiStyle,
  303. url:svg.getAttribute('src'),
  304. moduleType: this.data.moduleType,
  305. BUSINESS_TYPE:this.data.businessType?this.data.businessType[0].ID:null,
  306. BUSINESS_TYPE_NAME:this.data.businessType?this.data.businessType[0].Label:null,
  307. businessTypeText:this.data.businessType?this.data.businessType[0].val:null,
  308. businessKeyId:(this.data.businessNumber && this.data.businessNumber.length > 0)?this.data.businessNumber[0].ID:null,
  309. businessKey:(this.data.businessNumber && this.data.businessNumber.length > 0)?this.data.businessNumber[0].Label:null,
  310. businessKeyName:(this.data.businessNumber && this.data.businessNumber.length > 0)?this.data.businessNumber[0].val:null,
  311. autoClose:this.data.autoClose,
  312. businessCheckUrl:this.data.businessCheckUrl,
  313. nodeMsg: nodeMsg,
  314. pathMsg: pathMsg,
  315. removeNode: this.data.removeNode,
  316. removePath: this.data.removePath
  317. }
  318. getCommit(jsonObject).then(res => {
  319. if(res.data.resultCode === 0){
  320. // this.data = {
  321. // guiStyle:{
  322. // "class": "go.GraphLinksModel",
  323. // "linkFromPortIdProperty": "fromPort",
  324. // "linkToPortIdProperty": "toPort",
  325. // "nodeDataArray": [],
  326. // "linkDataArray": []
  327. // }
  328. // }
  329. if(!flag){
  330. window.flag = true
  331. this.$router.push('/TemplateManagementLists')
  332. this.currentChange({
  333. path:'/TemplateManagementLists'
  334. });
  335. }
  336. resolve(res)
  337. }
  338. })
  339. })
  340. },
  341. async formatGuiStyle () { //format整个流程图
  342. await new Promise((resolve) => {
  343. let startNode = {} //获取开始节点
  344. this.data.guiStyle.nodeDataArray.map(item => {
  345. if(item.key === -1){
  346. startNode = item
  347. }
  348. })
  349. let startlink = {}
  350. //获取第一根线的数据
  351. this.data.guiStyle.linkDataArray.map(item => {
  352. if(item.from === -1){
  353. startlink = item
  354. }
  355. })
  356. //获取连线的正确排序
  357. let linkMap = []
  358. new Array(this.data.guiStyle.linkDataArray.length).fill(null).map(() => {
  359. this.data.guiStyle.linkDataArray.map(item => {
  360. if(linkMap.length === 0 && item.from === -1){
  361. linkMap.push(item)
  362. }
  363. if(linkMap.length > 0 && item.from === linkMap[linkMap.length-1].to){
  364. linkMap.push(item)
  365. }
  366. })
  367. })
  368. this.data.guiStyle.linkDataArray = linkMap
  369. //获取节点的正确顺序
  370. // let nodeMap = [startNode]
  371. this.data.guiStyle.nodeDataArray = this.data.guiStyle.linkDataArray.reduce((sum,item) => {
  372. sum.push(this.data.Diagram.model.findNodeDataForKey(item.to))
  373. return sum
  374. },[startNode])
  375. //将所有节点的x轴与开始节点对齐
  376. this.data.guiStyle.nodeDataArray.map((item,index) => {
  377. let loc = item.loc.split(' ')
  378. loc[0] = startNode.loc.split(' ')[0]
  379. loc[1] = Number(startNode.loc.split(' ')[1]) + index*80
  380. item.loc = loc.join(' ')
  381. })
  382. //将所有连线的x轴与开始节点对齐
  383. this.data.guiStyle.linkDataArray.map((item,index) => {
  384. item.points.j.map(temp => {
  385. temp.F = startlink.points.j[0].F
  386. })
  387. item.points.j.map((temp,j) => {
  388. if(index === 0){
  389. if(j !== item.points.j.length-1){
  390. temp.G = Number(this.data.guiStyle.nodeDataArray[index].loc.split(' ')[1])+20
  391. }else{
  392. temp.G = Number(this.data.guiStyle.nodeDataArray[index+1].loc.split(' ')[1])-20
  393. }
  394. }else if(index === this.data.guiStyle.linkDataArray.length - 1){
  395. if(j !== item.points.j.length-1){
  396. temp.G = Number(this.data.guiStyle.nodeDataArray[index].loc.split(' ')[1])+20
  397. }else{
  398. temp.G = Number(this.data.guiStyle.nodeDataArray[index+1].loc.split(' ')[1])-20
  399. }
  400. }else{
  401. if(j !== item.points.j.length-1){
  402. temp.G = Number(this.data.guiStyle.nodeDataArray[index].loc.split(' ')[1])+20
  403. }else{
  404. temp.G = Number(this.data.guiStyle.nodeDataArray[index+1].loc.split(' ')[1])-20
  405. }
  406. }
  407. })
  408. })
  409. this.data.Diagram.model = go.Model.fromJson(this.data.guiStyle)
  410. setTimeout(() => {
  411. resolve()
  412. },100)
  413. })
  414. },
  415. dataChange (data) { //每一步中的数据变化
  416. this.data = Object.assign(this.data,data)
  417. },
  418. close () {
  419. this.$router.push('/TemplateManagementLists')
  420. this.currentChange({
  421. path:'/TemplateManagementLists'
  422. });
  423. },
  424. confirmAndPublish () { //保存并发布
  425. this.confirm(true).then(res => {
  426. getPublish({id:res.data.data.id}).then((response) => {
  427. if(response.data.resultCode === 0){
  428. this.$router.push('/TemplateManagementLists')
  429. this.currentChange({
  430. path:'/TemplateManagementLists'
  431. });
  432. }
  433. })
  434. })
  435. }
  436. },
  437. created () {
  438. Vue.component(`component_${this.currentSteps}`,Vue.extend(Object.assign({isKeepAliveModel:true},ParameterConfiguration)))
  439. this.currentComponent = `component_${this.currentSteps}`
  440. if(this.$route.params.flag === '1'){
  441. this.readOnly = true
  442. this.noFreshFlag = true
  443. this.getModuleInfo(this.$route.params.id)
  444. return
  445. }
  446. if(this.$route.params.id === '-1'){ //新增
  447. }else{ //编辑
  448. this.noFreshFlag = true
  449. this.currentSteps = 1
  450. this.getModuleInfo(this.$route.params.id)
  451. }
  452. },
  453. beforeDestroy () {
  454. }
  455. }
  456. </script>
  457. <style lang=scss" >
  458. .TemplateManagementNew{
  459. padding:16px;
  460. background: white;
  461. display: flex;
  462. flex-direction: column;
  463. .breadcrumb{
  464. margin-bottom: 30px;
  465. font-size: 18px;
  466. }
  467. .steps{
  468. width: 75%;
  469. margin-left: 12.5%;
  470. margin-bottom: 30px;
  471. }
  472. .content{
  473. flex:1;
  474. border:1px solid rgba(220,222,226,1);
  475. display: flex;
  476. flex-direction: column;
  477. position: relative;
  478. // 预览tips
  479. .tips{
  480. width:260px;
  481. height:204px;
  482. background:rgba(236,236,236,1);
  483. padding: 16px;
  484. box-sizing: border-box;
  485. display: inline-block;
  486. position: absolute;
  487. top: 0;
  488. left: 0;
  489. z-index: 99;
  490. >p{
  491. font-weight:400;
  492. color:rgba(52,52,52,1);
  493. line-height:16px;
  494. margin-bottom: 12px;
  495. display: flex;
  496. >span:first-child{
  497. margin-right: 8px;
  498. white-space: nowrap;
  499. }
  500. >span:last-child{
  501. word-break: break-all;
  502. }
  503. }
  504. }
  505. .block{
  506. flex: 1;
  507. }
  508. .buttonGroups{
  509. text-align: right;
  510. padding-bottom: 16px;
  511. button{
  512. margin-right: 10px;
  513. &:last-child{
  514. margin-right:16px;
  515. }
  516. }
  517. }
  518. }
  519. .burgeon-steps-item.burgeon-steps-status-finish .burgeon-steps-head-inner > .burgeon-steps-icon, .burgeon-steps-item.burgeon-steps-status-finish .burgeon-steps-head-inner span{
  520. color: white;
  521. }
  522. .burgeon-steps-item.burgeon-steps-status-finish .burgeon-steps-head-inner{
  523. border-color: #09A155;
  524. background: #09A155;
  525. }
  526. }
  527. </style>