n20-common-lib 1.3.108 → 1.3.110

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n20-common-lib",
3
- "version": "1.3.108",
3
+ "version": "1.3.110",
4
4
  "private": false,
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -47,8 +47,10 @@
47
47
  ref="msg-input"
48
48
  v-model="messageC"
49
49
  type="textarea"
50
- :placeholder="'请输入操作意见(50字以内),批准该意见为非必填,驳回/作废该意见为必填!' | $lc"
51
- :maxlength="50"
50
+ :placeholder="
51
+ ('请输入操作意见(' + messageMax + '字以内),批准该意见为非必填,驳回/作废该意见为必填!') | $lc
52
+ "
53
+ :maxlength="messageMax"
52
54
  :autosize="{ minRows: 1 }"
53
55
  />
54
56
  </el-form-item>
@@ -56,6 +58,8 @@
56
58
 
57
59
  <div class="text-c">
58
60
  <el-button v-if="authList.includes('approval')" type="primary" @click="approvalFn">{{ '批 准' | $lc }}</el-button>
61
+ <el-button v-if="showApprovalTo" type="primary" @click="approvalToV = true">{{ '批准至' | $lc }}</el-button>
62
+ <el-button v-if="authList.includes('rejectTo')" plain @click="rejectToB">{{ '驳回至' | $lc }}</el-button>
59
63
  <el-button v-if="authList.includes('reject')" plain @click="rejectFn">{{ '驳回至发起人' | $lc }}</el-button>
60
64
  <el-button v-if="authList.includes('rejectPre')" plain @click="rejectPreFn">{{
61
65
  '驳回至上一节点' | $lc
@@ -91,6 +95,12 @@
91
95
  @confirm="setAddtaskOk"
92
96
  />
93
97
  </cl-dialog>
98
+ <cl-dialog v-drag :visible.sync="rejectToV" :title="'驳回至节点' | $lc" width="960px" append-to-body top="7.5vh">
99
+ <reject-to-prop :task-id="taskId" @close="rejectToV = false" @confirm="rejectToFn" />
100
+ </cl-dialog>
101
+ <cl-dialog v-drag :visible.sync="approvalToV" :title="'批准至节点' | $lc" width="960px" append-to-body top="7.5vh">
102
+ <reject-to-prop :task-id="taskId" type="approvalTo" @close="approvalToV = false" @confirm="approvalToFn" />
103
+ </cl-dialog>
94
104
  </div>
95
105
  </template>
96
106
 
@@ -101,18 +111,24 @@ import { linkGo } from '../../utils/urlToGo'
101
111
  import { closeTagsForBackPage } from '../../plugins/CompatibleOld'
102
112
  import ClDialog from '../Dialog'
103
113
  import CarboncopyProp from './setCarboncopyProp.vue'
114
+ import RejectToProp from './setRejectToProp.vue'
104
115
 
105
116
  export default {
106
117
  name: 'ApprovalButtons',
107
118
  components: {
108
119
  ClDialog,
109
- CarboncopyProp
120
+ CarboncopyProp,
121
+ RejectToProp
110
122
  },
111
123
  props: {
112
124
  message: {
113
125
  type: String,
114
126
  default: ''
115
127
  },
128
+ messageMax: {
129
+ type: Number,
130
+ default: 50
131
+ },
116
132
  formData: {
117
133
  type: Object,
118
134
  default: () => ({})
@@ -141,7 +157,10 @@ export default {
141
157
  carbonCopyList: [],
142
158
  setAddtaskV: false,
143
159
  addTaskList: [],
144
- addTaskType: undefined
160
+ addTaskType: undefined,
161
+ rejectToV: false,
162
+ approvalToV: false,
163
+ showApprovalTo: false
145
164
  }
146
165
  },
147
166
  computed: {
@@ -162,6 +181,16 @@ export default {
162
181
  this.taskId = this.$route.query.taskId
163
182
  this.showBtn = this.$route.query.habtn !== 'true'
164
183
  this.getBtns()
184
+ if (this.showBtn && this.$route.query.state === '2') {
185
+ axios
186
+ .get(`/bems/activiti/sample/getTaskMoveVos/${this.$route.query.taskId}/1`, null, {
187
+ loading: false,
188
+ noMsg: true
189
+ })
190
+ .then(() => {
191
+ this.showApprovalTo = true
192
+ })
193
+ }
165
194
  },
166
195
  methods: {
167
196
  // 换回到发起页
@@ -264,8 +293,26 @@ export default {
264
293
  })
265
294
  })
266
295
  },
296
+ rejectToB() {
297
+ if (!this.messageC) {
298
+ return this.errMsgFn('驳回')
299
+ }
300
+ this.rejectToV = true
301
+ },
302
+ rejectToFn(taskId) {
303
+ this.rejectToV = false
304
+ let param = this.getParam()
305
+ param.forEach((item) => {
306
+ item.taskMoveVo = { taskId }
307
+ })
308
+ this.beforeFn(this.$attrs.beforeRejectPre, () => {
309
+ axios.post('/bems/activiti/admin/todo/rejectpre', param).then(({ data }) => {
310
+ this.thenMsg(data, $lc('驳回至'))
311
+ })
312
+ })
313
+ },
267
314
  // 驳回到上一步
268
- rejectPreFn() {
315
+ rejectPreFn(list) {
269
316
  if (!this.messageC) {
270
317
  return this.errMsgFn('驳回')
271
318
  }
@@ -283,6 +330,18 @@ export default {
283
330
  })
284
331
  })
285
332
  },
333
+ approvalToFn(taskId) {
334
+ this.approvalToV = false
335
+ let param = this.getParam()
336
+ param.forEach((item) => {
337
+ item.taskMoveVo = { taskId }
338
+ })
339
+ this.beforeFn(this.$attrs.beforeRatify, () => {
340
+ axios.post('/bems/activiti/admin/todo/advance', param).then(({ data }) => {
341
+ this.thenMsg(data, $lc('批准至'))
342
+ })
343
+ })
344
+ },
286
345
  // 作废
287
346
  discardFn() {
288
347
  if (!this.messageC) {
@@ -0,0 +1,100 @@
1
+ <template>
2
+ <cl-page style="height: 460px">
3
+ <div slot="header" class="flex-box flex-v m-b">
4
+ <span class="m-r-ss">{{ '节点名称' | $lc }}</span>
5
+ <span>
6
+ <el-input v-model="searchObj.taskName" size="mini" :placeholder="'请输入节点名称' | $lc" />
7
+ </span>
8
+ <el-button class="m-l" plain size="mini" @click="resetFn">{{ '重置' | $lc }}</el-button>
9
+ <el-button type="primary" size="mini" @click="searchFn">{{ '查询' | $lc }}</el-button>
10
+ </div>
11
+ <el-table :data="tableData" border height="100%">
12
+ <el-table-column :label="'选择' | $lc" align="center" width="100px">
13
+ <template slot-scope="{ row }">
14
+ <el-radio v-model="stlV" :label="row.taskId">
15
+ <span></span>
16
+ </el-radio>
17
+ </template>
18
+ </el-table-column>
19
+ <el-table-column :label="'节点名称' | $lc" align="center" show-overflow-tooltip>
20
+ <template slot-scope="{ row }">
21
+ {{ row.taskName }}
22
+ </template>
23
+ </el-table-column>
24
+ <el-table-column :label="'审批权限' | $lc" align="center" show-overflow-tooltip>
25
+ <template slot-scope="{ row }">{{ row | userF }}</template>
26
+ </el-table-column>
27
+ </el-table>
28
+ <div slot="footer" class="m-t text-c">
29
+ <el-button type="primary" @click="confirmFn">{{ type === 'approvalTo' ? $lc('批准') : $lc('驳回') }}</el-button>
30
+ <el-button @click="$emit('close')">{{ '取消' | $lc }}</el-button>
31
+ </div>
32
+ </cl-page>
33
+ </template>
34
+
35
+ <script>
36
+ import { $lc } from '../../utils/i18n/index'
37
+ import axios from '../../utils/axios'
38
+ export default {
39
+ filters: {
40
+ userF(row) {
41
+ let usrArr = []
42
+ row.memberName && usrArr.push(row.memberName)
43
+ row.roleName && usrArr.push(row.roleName)
44
+ row.userName && usrArr.push(row.userName)
45
+ return usrArr.join(' -> ')
46
+ }
47
+ },
48
+ props: {
49
+ type: {
50
+ type: String,
51
+ default: undefined
52
+ },
53
+ taskId: {
54
+ type: String,
55
+ default: ''
56
+ }
57
+ },
58
+ data() {
59
+ return {
60
+ searchObj: {
61
+ taskName: undefined
62
+ },
63
+ stlV: undefined,
64
+ list: [],
65
+ tableData: []
66
+ }
67
+ },
68
+ mounted() {
69
+ axios
70
+ .get(`/bems/activiti/sample/getTaskMoveVos/${this.taskId}/${this.type === 'approvalTo' ? 1 : 0}`)
71
+ .then((res) => {
72
+ this.list = res.data || []
73
+ this.tableData = this.list
74
+ })
75
+ },
76
+ methods: {
77
+ resetFn() {
78
+ this.searchObj.taskName = undefined
79
+
80
+ this.searchFn()
81
+ },
82
+ searchFn() {
83
+ if (this.searchObj.taskName) {
84
+ this.tableData = this.list.filter((item) => item.taskName.includes(this.searchObj.taskName))
85
+ } else {
86
+ this.tableData = this.list
87
+ }
88
+ },
89
+ confirmFn() {
90
+ if (!this.stlV) {
91
+ this.$message.warning($lc('请选择节点'))
92
+ return
93
+ }
94
+ this.$emit('confirm', this.stlV)
95
+ }
96
+ }
97
+ }
98
+ </script>
99
+
100
+ <style></style>
@@ -254,11 +254,11 @@ export default {
254
254
  let width = this.svgC.getAttribute('width')
255
255
  let height = this.svgC.getAttribute('height')
256
256
  let viewBox = this.svgC.getAttribute('viewBox').split(' ')
257
- viewBox = [Number(viewBox[0]), Number(viewBox[1]) - 10, Number(viewBox[2]) + 20, Number(viewBox[3])]
257
+ viewBox = [Number(viewBox[0]) - 16, Number(viewBox[1]) - 16, Number(viewBox[2]) + 32, Number(viewBox[3]) + 32]
258
258
  viewBox = viewBox.join(' ')
259
259
 
260
- this.svgC.setAttribute('width', Number(width) + 20)
261
- this.svgC.setAttribute('height', Number(height) + 10)
260
+ this.svgC.setAttribute('width', Number(width) + 32)
261
+ this.svgC.setAttribute('height', Number(height) + 32)
262
262
  this.svgC.setAttribute('viewBox', viewBox)
263
263
 
264
264
  let marker = this.svgC.querySelector('defs marker')
@@ -277,6 +277,10 @@ export default {
277
277
  this.setRejectLink(from, to, $lc('驳回至发起人'))
278
278
  } else if (type === '2') {
279
279
  this.setRejectLink(from, to, $lc('驳回至上一步'))
280
+ } else if (type === '3') {
281
+ this.setRejectLink(from, to, $lc('驳回至'))
282
+ } else if (type === '4') {
283
+ this.setPropelLink(from, to, $lc('推进 至'))
280
284
  }
281
285
  }
282
286
  },
@@ -284,20 +288,18 @@ export default {
284
288
  const fromO = this.getElRect(from)
285
289
  const toO = this.getElRect(to)
286
290
  let oTop = Math.min(fromO.top, toO.top) - 12
287
- let fromLC = fromO.left + fromO.with / 2
288
- let toLC = toO.left + toO.with / 2
291
+ let fromXC = fromO.left + fromO.with / 2
292
+ let toXC = toO.left + toO.with / 2
289
293
 
290
- let oRight = Math.max(fromO.left + fromO.with, toO.left + toO.with) + 12
291
- let fromTC = fromO.top + fromO.height / 2
292
- let toTC = toO.top + toO.height / 2
294
+ let oRight = Math.max(fromO.right, toO.right) + 12
295
+ let fromYC = fromO.top + fromO.height / 2
296
+ let toYC = toO.top + toO.height / 2
293
297
 
294
298
  let d
295
- if (fromLC !== toLC) {
296
- d = `M${fromLC},${fromO.top} L${fromLC},${oTop} L${toLC},${oTop} L${toLC},${toO.top}`
299
+ if (fromXC !== toXC) {
300
+ d = `M${fromXC},${fromO.top} L${fromXC},${oTop} L${toXC},${oTop} L${toXC},${toO.top}`
297
301
  } else {
298
- d = `M${fromO.left + fromO.with},${fromTC} L${oRight},${fromTC} L${oRight},${toTC} L${
299
- toO.left + toO.with
300
- },${toTC}`
302
+ d = `M${fromO.right},${fromYC} L${oRight},${fromYC} L${oRight},${toYC} L${toO.right},${toYC}`
301
303
  }
302
304
 
303
305
  let path = document.createElementNS('http://www.w3.org/2000/svg', 'path')
@@ -309,11 +311,11 @@ export default {
309
311
  if (msg) {
310
312
  let text = document.createElementNS('http://www.w3.org/2000/svg', 'text')
311
313
  text.setAttribute('class', 'activiti-text-reject')
312
- if (fromLC !== toLC) {
313
- text.setAttribute('x', (fromLC + toLC) / 2)
314
+ if (fromXC !== toXC) {
315
+ text.setAttribute('x', (fromXC + toXC) / 2)
314
316
  text.setAttribute('y', oTop + 6)
315
317
  } else {
316
- text.setAttribute('y', (fromTC + toTC) / 2)
318
+ text.setAttribute('y', (fromYC + toYC) / 2)
317
319
  text.setAttribute('x', oRight + 8)
318
320
  text.setAttribute('writing-mode', 'tb')
319
321
  }
@@ -330,6 +332,54 @@ export default {
330
332
  this.svgC.insertBefore(rect, text)
331
333
  }
332
334
  },
335
+ setPropelLink(from, to, msg) {
336
+ const fromO = this.getElRect(from)
337
+ const toO = this.getElRect(to)
338
+ let oBottom = Math.min(fromO.bottom, toO.bottom) + 12
339
+ let fromXC = fromO.left + fromO.with / 2
340
+ let toXC = toO.left + toO.with / 2
341
+
342
+ let oLeft = Math.max(fromO.left, toO.left) - 12
343
+ let fromYC = fromO.top + fromO.height / 2
344
+ let toYC = toO.top + toO.height / 2
345
+
346
+ let d
347
+ if (fromXC !== toXC) {
348
+ d = `M${fromXC},${fromO.bottom} L${fromXC},${oBottom} L${toXC},${oBottom} L${toXC},${toO.bottom}`
349
+ } else {
350
+ d = `M${fromO.left},${fromYC} L${oLeft},${fromYC} L${oLeft},${toYC} L${toO.left},${toYC}`
351
+ }
352
+
353
+ let path = document.createElementNS('http://www.w3.org/2000/svg', 'path')
354
+ path.setAttribute('class', 'activiti-line-propel')
355
+ path.setAttribute('d', d)
356
+ path.style.markerEnd = `url('#${this.markerId}')`
357
+ this.svgC.appendChild(path)
358
+
359
+ if (msg) {
360
+ let text = document.createElementNS('http://www.w3.org/2000/svg', 'text')
361
+ text.setAttribute('class', 'activiti-text-propel')
362
+ if (fromXC !== toXC) {
363
+ text.setAttribute('x', (fromXC + toXC) / 2)
364
+ text.setAttribute('y', oBottom + 6)
365
+ } else {
366
+ text.setAttribute('y', (fromYC + toYC) / 2)
367
+ text.setAttribute('x', oLeft + 8)
368
+ text.setAttribute('writing-mode', 'tb')
369
+ }
370
+ text.textContent = msg
371
+ this.svgC.appendChild(text)
372
+
373
+ let textO = text.getBBox()
374
+ let rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect')
375
+ rect.setAttribute('class', 'activiti-text-bg-reject')
376
+ rect.setAttribute('x', textO.x)
377
+ rect.setAttribute('y', textO.y)
378
+ rect.setAttribute('width', textO.width)
379
+ rect.setAttribute('height', textO.height)
380
+ this.svgC.insertBefore(rect, text)
381
+ }
382
+ },
333
383
  getElRect(id) {
334
384
  let g = this.svgW.querySelector(`[data-element-id="${id}"]`)
335
385
  let rect = {
@@ -345,6 +395,8 @@ export default {
345
395
  left: Number(g.getAttribute('data-element-left')),
346
396
  top: Number(g.getAttribute('data-element-top'))
347
397
  }
398
+ rect.right = rect.left + rect.with
399
+ rect.bottom = rect.top + rect.height
348
400
  return rect
349
401
  }
350
402
 
@@ -358,6 +410,8 @@ export default {
358
410
  matrix = matrix.split(' ')
359
411
  rect.left = Number(matrix[4])
360
412
  rect.top = Number(matrix[5])
413
+ rect.right = rect.left + rect.with
414
+ rect.bottom = rect.top + rect.height
361
415
  }
362
416
  return rect
363
417
  },
@@ -641,6 +695,21 @@ setRejectLink(from, to) {
641
695
  font-weight: normal;
642
696
  text-anchor: middle;
643
697
  }
698
+ .activiti-line-propel,
699
+ .activiti-line-propel path {
700
+ fill: none;
701
+ stroke-width: 1px;
702
+ stroke: #3cb495 !important;
703
+ stroke-linejoin: round;
704
+ /* marker-end: url('#sequenceflow-end-white-black-3aw0mc6w8vg7jarca1qf355gu'); */
705
+ }
706
+ .activiti-text-propel {
707
+ fill: #3cb495 !important;
708
+ font-family: Arial, sans-serif;
709
+ font-size: 12px;
710
+ font-weight: normal;
711
+ text-anchor: middle;
712
+ }
644
713
  .activiti-text-bg-reject {
645
714
  fill: #ffffff;
646
715
  }
@@ -7,6 +7,7 @@
7
7
  :value="valueStr"
8
8
  :disabled="disabled"
9
9
  :placeholder="phd"
10
+ :clearable="false"
10
11
  @focus="focusFn"
11
12
  @blur.native.capture.stop
12
13
  />
@@ -1,19 +1,26 @@
1
1
  <template>
2
- <keep-alive v-if="dnsKey">
3
- <router-view ref="content-cache" :key="$route.path" class="content-box" :no-cache="$route.meta.noCache" />
4
- </keep-alive>
5
- <router-view v-else ref="content-cache" class="content-box" :no-cache="$route.meta.noCache" />
2
+ <div>
3
+ <keep-alive v-if="dnsKey" :max="32">
4
+ <router-view v-if="!$route.meta.noCache" ref="content-cache" :key="$route | keyF" class="content-box" />
5
+ </keep-alive>
6
+ <router-view v-if="!dnsKey || $route.meta.noCache" ref="content-cache" class="content-box" />
7
+ </div>
6
8
  </template>
7
9
 
8
10
  <script>
9
- const TestProduction = process.env.VUE_APP_TestProduction === 'true'
10
-
11
11
  import { setRela } from '../../../utils/relaNo'
12
- const routerBase = process.env.BASE_URL
13
- const routerBaseRe = new RegExp('^' + routerBase)
12
+ const routerBase = (process.env.BASE_URL + '/').replace(/\/\/$/, '/')
14
13
 
15
14
  export default {
16
15
  name: 'SubContent',
16
+ filters: {
17
+ keyF({ path, query = {} }) {
18
+ path = path.replace(/^\//, routerBase)
19
+ let key = path + '^' + JSON.stringify({ ...query, _fromNo: undefined }) + '^' + window._tab_route_key[path]
20
+
21
+ return key
22
+ }
23
+ },
17
24
  props: {
18
25
  isTest: {
19
26
  type: Boolean,
@@ -22,94 +29,74 @@ export default {
22
29
  },
23
30
  data() {
24
31
  return {
25
- dnsKey: this.isTest || TestProduction
26
- }
27
- },
28
- watch: {
29
- $route: {
30
- handler(vn, vo) {
31
- if (vo.meta.noCache) {
32
- this.removeOcache({ path: vo.path })
33
- }
34
- }
32
+ dnsKey: this.isTest || (process.env.NODE_ENV === 'production' && process.env.VUE_APP_KEEP_ALIVE === 'true')
35
33
  }
36
34
  },
37
35
  created() {
38
36
  setRela()
39
37
 
40
38
  window.addEventListener('message', this.watchMessage)
39
+ },
40
+ mounted() {
41
+ console.log(this.$refs, 'bbb')
41
42
 
42
- setTimeout(() => {
43
- this.pendingRemoveCaches()
44
- }, 60)
43
+ this.removeCacheTimerFn()
45
44
  },
46
45
  activated() {
47
46
  window.addEventListener('message', this.watchMessage)
48
47
 
49
- setTimeout(() => {
50
- this.pendingRemoveCaches()
51
- }, 60)
48
+ this.removeCacheTimerFn()
52
49
  },
53
50
  deactivated() {
54
51
  window.removeEventListener('message', this.watchMessage)
52
+
53
+ clearInterval(this.removeCacheTimer)
55
54
  },
56
55
  beforeDestroy() {
57
56
  window.removeEventListener('message', this.watchMessage)
57
+
58
+ clearInterval(this.removeCacheTimer)
58
59
  },
59
60
  methods: {
60
61
  watchMessage(ev) {
61
- const { updateCache, originName, targetName } = ev.data
62
- if (updateCache && originName === 'main' && targetName === '*') {
63
- this.pendingRemoveCaches()
62
+ const { updateActiveCache, originName, targetName } = ev.data
63
+ if (updateActiveCache && originName === 'main' && targetName === '*') {
64
+ this.updateActiveCache()
64
65
  }
65
66
  },
66
- pendingRemoveCaches() {
67
- for (let key in window._pending_update_cache) {
68
- if (routerBaseRe.test(key) && window._pending_update_cache[key]) {
69
- let cacheKey = key.replace(routerBaseRe, '/')
70
- if (cacheKey === this.$route.path) {
71
- let path = this.$route.path
72
- let oTab = JSON.parse(
73
- JSON.stringify({
74
- path: this.$route.path,
75
- query: this.$route.query
76
- })
77
- )
78
-
79
- this.$router.replace('/loading')
80
- this.removeOcache({ path: path })
81
- setTimeout(() => {
82
- this.$router.replace(oTab)
83
- }, 300)
84
- } else {
85
- this.removeOcache({ path: cacheKey })
86
- }
87
- }
88
- }
67
+ updateActiveCache() {
68
+ let oTab = JSON.parse(
69
+ JSON.stringify({
70
+ path: this.$route.path,
71
+ query: this.$route.query,
72
+ params: this.$route.params
73
+ })
74
+ )
75
+ this.$router.replace('/loading')
76
+ this.$nextTick(() => {
77
+ this.$router.replace({
78
+ path: oTab.path,
79
+ query: oTab.query
80
+ })
81
+ })
89
82
  },
90
- removeOcache({ path }) {
91
- if (!this.dnsKey) return
92
-
93
- let componentInstance = this.$refs['content-cache']?.$vnode.parent.componentInstance
94
-
95
- if (componentInstance) {
96
- let kI = componentInstance.keys.findIndex((k) => k === path)
97
- if (kI !== -1) {
98
- let destroy = componentInstance.cache[path].componentInstance.destroy
99
- destroy && destroy()
100
-
101
- delete componentInstance.cache[path]
102
- componentInstance.keys.splice(kI, 1)
103
-
104
- let spath = path.replace(/^\//, routerBase)
105
- delete window._pending_update_cache[spath]
83
+ removeCacheTimerFn() {
84
+ this.removeCacheTimer = setInterval(() => {
85
+ if (this.$refs['content-cache']) {
86
+ let cache = this.$refs['content-cache'].$vnode.parent.componentInstance.cache
87
+ for (let k in cache) {
88
+ if (cache[k]) {
89
+ let kM = k.split('^')
90
+ let _K = kM[0]
91
+ let _V = kM[2]
92
+ if (window._tab_route_key[_K] && window._tab_route_key[_K] !== Number(_V)) {
93
+ cache[k].componentInstance.destroy?.()
94
+ cache[k] = null
95
+ }
96
+ }
97
+ }
106
98
  }
107
-
108
- // console.log({
109
- // cache: componentInstance.cache,
110
- // keys: componentInstance.keys
111
- // })
112
- }
99
+ }, 120000)
113
100
  }
114
101
  }
115
102
  }