three-trees-ui 1.0.55 → 1.0.57

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": "three-trees-ui",
3
- "version": "1.0.55",
3
+ "version": "1.0.57",
4
4
  "publicPath": "/ui",
5
5
  "author": "hotent",
6
6
  "private": false,
@@ -6,82 +6,201 @@
6
6
  :ref="vueObj.alias"
7
7
  :data="data"
8
8
  :permission="permission"
9
- :vueObj="vueObj"
9
+ :vue-obj="vueObj"
10
10
  :component="component"
11
+ :index="index"
12
+ :item="item"
11
13
  ></component>
12
14
  </template>
13
15
  </div>
14
16
  </template>
15
17
 
16
18
  <script>
17
- import Vue from 'vue'
19
+ import Vue from 'vue'
20
+ const { Base64 } = require('js-base64')
18
21
 
19
- export default {
20
- name: 'HtCustomComponent',
21
- componentName: 'HtCustomComponent',
22
- props: ['data', 'permission', 'ccAlias'],
23
- data() {
24
- return {
25
- loadOver: false,
26
- vueObj: {},
27
- component: {},
28
- componentName: '',
29
- }
30
- },
31
- methods: {
32
- init() {
33
- //解析jscode;
34
- this.component = {}
35
- if (this.vueObj.jsCode) {
36
- let jsCode = Base64.decode(this.vueObj.jsCode, 'utf-8')
37
- let parseJsCode = function () {
38
- return eval('(function(){return {' + jsCode + '} })()')
39
- }
40
- this.component = parseJsCode()
22
+ export default {
23
+ name: 'HtCustomComponent',
24
+ componentName: 'HtCustomComponent',
25
+ props: {
26
+ data: Object,
27
+ permission: Object,
28
+ ccAlias: String,
29
+ item: {
30
+ type: Object,
31
+ default: () => {
32
+ return {}
33
+ },
34
+ },
35
+ index: {
36
+ type: Number,
37
+ default: null,
38
+ },
39
+ },
40
+ data() {
41
+ return {
42
+ loadOver: false,
43
+ vueObj: {},
44
+ component: {},
45
+ componentName: '',
41
46
  }
47
+ },
48
+ mounted() {
49
+ // this.init();
50
+ },
51
+ created() {
52
+ //根据自定义组件id查询组件对象
53
+ // this.$http
54
+ // .get('${form}/formCustomComponent/v1/getByAlias?alias=' + this.ccAlias)
55
+ // .then((resp) => {
56
+ // this.vueObj = resp.data
57
+ // this.init()
58
+ // })
42
59
 
43
- this.component.props = ['data', 'permission', 'vueObj', 'component']
44
- if (this.vueObj.template) {
45
- this.component.template = Base64.decode(this.vueObj.template, 'utf-8')
46
- } else {
47
- this.component.template = '<div></div>'
48
- }
49
- if (this.vueObj.dataCode) {
50
- let dataCodeStr = Base64.decode(this.vueObj.dataCode)
51
- let parseDataCode = function () {
52
- return eval('(function(){return ' + dataCodeStr + ' })()')
60
+ this.$requestConfig
61
+ .getFormCustomComponentByAlias(this.ccAlias)
62
+ .then((resp) => {
63
+ this.vueObj = resp
64
+ this.init()
65
+ })
66
+ },
67
+ methods: {
68
+ async init() {
69
+ //解析jscode;
70
+ this.component = {}
71
+
72
+ if (this.vueObj.jsCode) {
73
+ let jsCode = Base64.decode(this.vueObj.jsCode, 'utf-8')
74
+ let parseJsCode = function() {
75
+ return eval('(function(){return {' + jsCode + '} })()')
76
+ }
77
+ this.component = parseJsCode()
53
78
  }
54
- let data = parseDataCode()
55
- this.component.data = function () {
56
- return data
79
+
80
+ this.component.props = [
81
+ 'data',
82
+ 'permission',
83
+ 'vueObj',
84
+ 'component',
85
+ 'index',
86
+ 'item',
87
+ ]
88
+ if (this.vueObj.template) {
89
+ this.component.template = Base64.decode(this.vueObj.template, 'utf-8')
90
+ } else {
91
+ this.component.template = '<div></div>'
57
92
  }
58
- }
59
93
 
60
- this.componentName = this.ccAlias + '-component'
61
- //加载动态组件
62
- Vue.component(this.componentName, this.component)
63
- //加载完成后显示
64
- this.loadOver = true
65
- },
66
- },
67
- mounted() {
68
- // this.init();
69
- },
70
- created() {
71
- //根据自定义组件id查询组件对象
72
- // this.$http
73
- // .get('${form}/formCustomComponent/v1/getByAlias?alias=' + this.ccAlias)
74
- // .then((resp) => {
75
- // this.vueObj = resp.data
76
- // this.init()
77
- // })
94
+ // 支持引用 工具类 js
95
+ const utilJsObj = {}
96
+ if (this.vueObj.utilJs) {
97
+ try {
98
+ const utilJsList = JSON.parse(
99
+ Base64.decode(this.vueObj.utilJs, 'utf-8')
100
+ )
101
+ for (const item of utilJsList) {
102
+ const name = item.utilJs_name
103
+ const path = item.utilJs_path.replace('@/', '')
104
+ if (name && path) {
105
+ // require 跟 import 都不能直接使用变量
106
+ const utilJs = await require('../../' + path)
107
+ utilJsObj[name] = utilJs.default
108
+ }
109
+ if ((name && !path) || (!name && path)) {
110
+ this.$message.error(
111
+ 'utilJs_name or utilJs_path cannot be empty!'
112
+ )
113
+ throw new Error('utilJs_name or utilJs_path cannot be empty!')
114
+ }
115
+ }
116
+ } catch (error) {
117
+ console.log(error, 'error')
118
+ }
119
+ }
78
120
 
79
- this.$requestConfig
80
- .getFormCustomComponentByAlias(this.ccAlias)
81
- .then((resp) => {
82
- this.vueObj = resp
83
- this.init()
84
- })
85
- },
86
- }
121
+ if (this.vueObj.dataCode) {
122
+ let dataCodeStr = Base64.decode(this.vueObj.dataCode)
123
+ let parseDataCode = function() {
124
+ return eval('(function(){return ' + dataCodeStr + ' })()')
125
+ }
126
+ let data = parseDataCode()
127
+ this.component.data = function() {
128
+ return data
129
+ }
130
+ }
131
+
132
+ // 支持引用外部组件
133
+ if (this.vueObj.components) {
134
+ try {
135
+ const components = JSON.parse(
136
+ Base64.decode(this.vueObj.components, 'utf-8')
137
+ )
138
+ for (const item of components) {
139
+ const name = item.components_name
140
+ const path = item.components_path.replace('@/', '')
141
+ if (name && path) {
142
+ // require 跟 import 都不能直接使用变量
143
+ const component = await require('../../' + path)
144
+ this.component.components[item.components_name] =
145
+ component.default
146
+ }
147
+ if ((name && !path) || (!name && path)) {
148
+ this.$message.error(
149
+ 'component_name or component_path cannot be empty!'
150
+ )
151
+ throw new Error(
152
+ 'component_name or component_path cannot be empty!'
153
+ )
154
+ }
155
+ }
156
+ } catch (error) {
157
+ console.log(error, 'error')
158
+ }
159
+ }
160
+
161
+ // 支持引用外部js混入
162
+ if (this.vueObj.mixins) {
163
+ this.component.mixins = []
164
+ try {
165
+ const mixins = JSON.parse(
166
+ Base64.decode(this.vueObj.mixins, 'utf-8')
167
+ )
168
+ for (const item of mixins) {
169
+ const name = item.mixin_name
170
+ const path = item.mixin_path.replace('@/', '')
171
+
172
+ if (name && path) {
173
+ // require 跟 import 都不能直接使用变量
174
+ const mixin = await require('../../' + path)
175
+ this.component.mixins.push(mixin.default)
176
+ }
177
+ if ((name && !path) || (!name && path)) {
178
+ this.$message.error(
179
+ 'mixin_name or mixin_path cannot be empty!'
180
+ )
181
+ throw new Error('mixin_name or mixin_path cannot be empty!')
182
+ }
183
+ }
184
+ } catch (error) {
185
+ console.log(error, 'error')
186
+ }
187
+ }
188
+
189
+ //支持引入css样式
190
+ if (this.vueObj.cssCode) {
191
+ let cssCode = Base64.decode(this.vueObj.cssCode, 'utf-8')
192
+ let stylee = document.createElement('style')
193
+ stylee.type = 'text/css'
194
+ stylee.innerHTML = cssCode
195
+ document.head.appendChild(stylee)
196
+ }
197
+
198
+ this.componentName = this.ccAlias + '-component'
199
+ //加载动态组件
200
+ Vue.component(this.componentName, this.component)
201
+ //加载完成后显示
202
+ this.loadOver = true
203
+ },
204
+ },
205
+ }
87
206
  </script>
@@ -1094,6 +1094,9 @@
1094
1094
  this.$el,
1095
1095
  'data-index'
1096
1096
  )
1097
+ if (!thisIndex) {
1098
+ thisIndex = utils.getSubScopeElAndIndex(this.$parent.$el).index
1099
+ }
1097
1100
  parentIndex = utils.getSomeAttributeFromParentElement(
1098
1101
  this.$parent.$parent.$el,
1099
1102
  'data-index'
@@ -3,8 +3,8 @@
3
3
  <div class="frame-container__body">
4
4
  <loading v-if="loading" />
5
5
  <div
6
- class="frame-viewer__img"
7
6
  v-else-if="contentType.indexOf('image') > -1"
7
+ class="frame-viewer__img"
8
8
  >
9
9
  <img
10
10
  :src="dataSrc"
@@ -103,6 +103,9 @@
103
103
 
104
104
  console.log('createObjectURL(new Blob([data]))')
105
105
  }
106
+ if (this.mode === 'pdf') {
107
+ this.dataSrc += '#toolbar=0'
108
+ }
106
109
  })
107
110
  .catch((err) => {
108
111
  this.$emit('preview-error', err)
@@ -12,16 +12,16 @@
12
12
  <loading v-if="loading" />
13
13
  <fill-page v-if="errorMessage" type="2" :tip="errorMessage" />
14
14
  <!-- 预览pdf.word等文件格式 -->
15
- <pdf-viewer
15
+ <!-- <pdf-viewer
16
16
  v-else-if="mode == 'pdf'"
17
17
  :src="src"
18
18
  :headers="headerVal"
19
19
  :watermark="watermark"
20
20
  :watermark-options="watermarkOptions"
21
21
  @preview-error="handlePreviewErr"
22
- />
22
+ /> -->
23
23
  <frame-viewer
24
- v-else-if="mode == 'html' || mode == 'picture'"
24
+ v-if="mode == 'pdf' || mode == 'html' || mode == 'picture'"
25
25
  :src="src"
26
26
  :mode="mode"
27
27
  :headers="headerVal"
@@ -164,14 +164,14 @@
164
164
  }
165
165
  },
166
166
  computed: {
167
- headerVal: function () {
167
+ headerVal: function() {
168
168
  return this.headers
169
169
  ? this.headers
170
170
  : this.$requestConfig.header
171
171
  ? this.$requestConfig.header()
172
172
  : null
173
173
  },
174
- titleVal: function () {
174
+ titleVal: function() {
175
175
  return this.tempTitle ? this.tempTitle : this.title
176
176
  },
177
177
  },
@@ -112,8 +112,10 @@
112
112
  :highlight-current-row="highlightCurrentRow"
113
113
  :row-class-name="rowClassName"
114
114
  :cell-class-name="cellClassName"
115
- :style="{ height: `${tableMaxHeight ? tableMaxHeight : 400}` + 'px' }"
115
+ :height="`${tableMaxHeight ? tableMaxHeight : 400}`"
116
116
  :row-key="rowKey"
117
+ :show-summary="showSummary"
118
+ :summary-method="getSummaries"
117
119
  @row-click="handleRowClick"
118
120
  @select="handleTableSelect"
119
121
  @select-all="handleTableSelect"
@@ -190,6 +192,10 @@
190
192
  </el-main>
191
193
  </template>
192
194
  <script>
195
+ const METHOD_MAP = {
196
+ count: 'getCount',
197
+ sum: 'getSum',
198
+ }
193
199
  import Locale from '@/mixins/locale'
194
200
  import Emitter from '@/mixins/emitter'
195
201
  import utils from '@/utils.js'
@@ -367,6 +373,18 @@
367
373
  type: String,
368
374
  default: 'total, sizes, prev, pager, next, jumper',
369
375
  },
376
+ tableMainName: {
377
+ type: String,
378
+ default: '',
379
+ },
380
+ tableDataFields: {
381
+ type: Array,
382
+ default: () => [],
383
+ },
384
+ tableDataTotal: {
385
+ type: Object,
386
+ default: () => {},
387
+ },
370
388
  },
371
389
  data() {
372
390
  return {
@@ -388,6 +406,7 @@
388
406
  selection: [],
389
407
  tablePanelHeight: 0,
390
408
  isCardView: this.cardView,
409
+ showSummary: false,
391
410
  }
392
411
  },
393
412
  computed: {
@@ -447,6 +466,13 @@
447
466
  customTableHeight() {
448
467
  this.calcTableHeight()
449
468
  },
469
+ tableDataFields: {
470
+ immediate: true,
471
+ handler: function(val) {
472
+ // 只要显示列有一个属性设置了合计,则开启表格合计功能
473
+ this.showSummary = val.some((i) => i.summaryMethod)
474
+ },
475
+ },
450
476
  },
451
477
  created() {
452
478
  this.initCustomColumns()
@@ -692,8 +718,19 @@
692
718
  me.$refs.quickSearch.$children[0].$el.children[0].focus()
693
719
  })
694
720
  }
695
-
696
- this.$emit('load', { ...param }, loadedHandler, isSearchBtn)
721
+ // 是否需要后端统计
722
+ // 只要 表格列设置中,存在 合计方式为求和 合计范围不为 单页合计,即需要请求
723
+ const needRequestTotal = this.tableDataFields.some(
724
+ (field) =>
725
+ field.summaryMethod === 'sum' && field.summaryType !== 'single'
726
+ )
727
+ this.$emit(
728
+ 'load',
729
+ { ...param },
730
+ loadedHandler,
731
+ isSearchBtn,
732
+ needRequestTotal
733
+ )
697
734
  this.$emit('loading', { ...param }, loadedHandler, isSearchBtn)
698
735
  },
699
736
  // 通过列属性获取列标签
@@ -862,13 +899,10 @@
862
899
  this.$refs.toolbarContainer.clientHeight) ||
863
900
  0
864
901
 
865
- // templatePreview 中 nopagination 为 true,且有自定义的分页控件 占用 65
866
902
  const paginationPanelHeight =
867
- this.$route.name === 'TemplatePreview' && this.nopagination
868
- ? 65
869
- : (this.$refs.paginationPanel &&
870
- this.$refs.paginationPanel.clientHeight) ||
871
- 0
903
+ (this.$refs.paginationPanel &&
904
+ this.$refs.paginationPanel.clientHeight) ||
905
+ 0
872
906
  // 下外边距
873
907
  const searchPanelBottom = searchPanelHeight > 0 ? 18 : 0
874
908
  const toolbarPanelBottom = toolbarPanelHeight > 0 ? 18 : 0
@@ -909,6 +943,91 @@
909
943
  )
910
944
  })
911
945
  },
946
+ getSummaries(param) {
947
+ const { columns, data } = param
948
+ const sums = []
949
+ columns.forEach((column, index) => {
950
+ if (index === 0) {
951
+ sums[index] = '合计'
952
+ return
953
+ }
954
+ if (column.property) {
955
+ const tableFieldItem = this.getTableFieldItem(column.property)
956
+ if (tableFieldItem) {
957
+ const {
958
+ summaryMethod,
959
+ summaryType,
960
+ name,
961
+ tableName,
962
+ oldTableField,
963
+ fieldDesc,
964
+ } = tableFieldItem
965
+ let field = ''
966
+ if (oldTableField) {
967
+ // 数据列表
968
+ field = this.getPropTable(
969
+ name,
970
+ tableName,
971
+ oldTableField
972
+ ).toLowerCase()
973
+ } else {
974
+ // 数据视图
975
+ field = fieldDesc.toLowerCase()
976
+ }
977
+ switch (summaryType) {
978
+ // 单页统计
979
+ case 'single':
980
+ // 前端合计当前页
981
+ sums[index] = this[METHOD_MAP[summaryMethod]](data, name)
982
+ break
983
+ default:
984
+ if (summaryMethod === 'sum') {
985
+ // 后端合计全部页
986
+ sums[index] = this.tableDataTotal[field]
987
+ } else if (summaryMethod === 'count') {
988
+ // 计数 计算当前列不为空的个数
989
+ sums[index] = this[METHOD_MAP[summaryMethod]](data, name)
990
+ }
991
+ break
992
+ }
993
+ } else {
994
+ sums[index] = ''
995
+ }
996
+ } else {
997
+ sums[index] = ''
998
+ }
999
+ })
1000
+
1001
+ return sums
1002
+ },
1003
+ getTableFieldItem(property) {
1004
+ return this.tableDataFields.find((i) => {
1005
+ let field = ''
1006
+ if (i.oldTableField) {
1007
+ // 表单列表
1008
+ field = this.getPropTable(i.name, i.tableName, i.oldTableField)
1009
+ return field === property
1010
+ } else {
1011
+ // 数据视图
1012
+ return i.fieldDesc.toLowerCase() === property.toLowerCase()
1013
+ }
1014
+ })
1015
+ },
1016
+ getCount(data, field) {
1017
+ const hasValueList = data.filter((i) => i[field])
1018
+ return hasValueList.length
1019
+ },
1020
+ getSum(data, field) {
1021
+ const sumResult = data.reduce((pre, cur) => pre + Number(cur[field]), 0)
1022
+ return sumResult ? utils.thousandBit(sumResult) : sumResult
1023
+ },
1024
+ getPropTable(field, tableName, oldTableField) {
1025
+ if (this.tableMainName.toLowerCase() == tableName.toLowerCase()) {
1026
+ return `t.${oldTableField}`
1027
+ } else {
1028
+ return `${tableName}.${oldTableField}`
1029
+ }
1030
+ },
912
1031
  },
913
1032
  }
914
1033
  </script>
@@ -33,10 +33,43 @@
33
33
  v-if="isShow && action != 'editDraft'"
34
34
  type="primary"
35
35
  :disabled="disabled"
36
- @click="boSave()"
36
+ @click="SetOpinionText()"
37
37
  >
38
38
  提交
39
39
  </el-button>
40
+ <!-- 是否需要保存意见对话框 --start -->
41
+ <el-dialog
42
+ id="needOpinionDialog"
43
+ title="请填写修改理由:"
44
+ :visible.sync="needOpinionDialog"
45
+ width="30%"
46
+ :before-close="closeOpinionDialog"
47
+ >
48
+ <el-container>
49
+ <el-main style="padding:0px;height:80px">
50
+ <ht-input
51
+ v-model="needOpinionDetail"
52
+ type="textarea"
53
+ name="修改理由"
54
+ :validate="{ required: true }"
55
+ style="width:100%"
56
+ ></ht-input>
57
+ </el-main>
58
+ </el-container>
59
+ <div slot="footer" class="dialog-footer">
60
+ <el-button
61
+ :disabled="needOpinionDetail === '' ? true : false"
62
+ type="primary"
63
+ @click="boSave()"
64
+ >
65
+ 提交
66
+ </el-button>
67
+ <el-button type="default" @click="closeOpinionDialog()">
68
+ 取消
69
+ </el-button>
70
+ </div>
71
+ </el-dialog>
72
+ <!-- 是否需要保留意见对话框 --end -->
40
73
  <!-- <el-button
41
74
  v-if="action === 'editDraft'"
42
75
  type="primary"
@@ -107,6 +140,10 @@
107
140
  type: Boolean,
108
141
  default: false,
109
142
  },
143
+ //是否需要保存意见
144
+ needOpinion: {
145
+ type: String,
146
+ },
110
147
  },
111
148
  data() {
112
149
  return {
@@ -131,6 +168,8 @@
131
168
  tempAlias: '',
132
169
  startLable: '发起流程',
133
170
  printLable: '打印',
171
+ needOpinionDialog: false,
172
+ needOpinionDetail: '',
134
173
  }
135
174
  },
136
175
  computed: {
@@ -244,6 +283,15 @@
244
283
  boAlias: this.boAlias,
245
284
  boData: formData,
246
285
  }
286
+ //把修改原因也设置到boData里面
287
+ if (
288
+ this.action === 'edit' &&
289
+ ((this.needOpinion && this.needOpinion === '1') ||
290
+ (this.$route.query.needOpinion &&
291
+ this.$route.query.needOpinion === '1'))
292
+ ) {
293
+ data.boData.needOpinionDetail = this.needOpinionDetail
294
+ }
247
295
  this.disabled = true
248
296
 
249
297
  if (delDraftId) {
@@ -255,6 +303,8 @@
255
303
  .boSave(data)
256
304
  .then((result) => {
257
305
  if (result.state) {
306
+ //保存成功时清空意见框
307
+ this.needOpinionDetail = ''
258
308
  if (this.closeSave) {
259
309
  this.close()
260
310
  return
@@ -292,6 +342,27 @@
292
342
  })
293
343
  .catch(() => {})
294
344
  },
345
+ SetOpinionText() {
346
+ console.log(
347
+ this.action,
348
+ this.needOpinion,
349
+ this.$route.query.needOpinion
350
+ )
351
+ if (
352
+ this.action === 'edit' &&
353
+ ((this.needOpinion && this.needOpinion === '1') ||
354
+ (this.$route.query.needOpinion &&
355
+ this.$route.query.needOpinion === '1'))
356
+ ) {
357
+ //只有编辑的时候需要填写意见框
358
+ this.needOpinionDialog = true
359
+ } else {
360
+ this.boSave()
361
+ }
362
+ },
363
+ closeOpinionDialog() {
364
+ this.needOpinionDialog = false
365
+ },
295
366
  boSaveAndDelDraft() {
296
367
  this.boSave(this.draftId)
297
368
  },