three-trees-ui 1.0.60 → 1.0.62

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.60",
3
+ "version": "1.0.62",
4
4
  "publicPath": "/ui",
5
5
  "author": "hotent",
6
6
  "private": false,
@@ -1137,8 +1137,11 @@
1137
1137
  }
1138
1138
  const pInst = utils.getOnlineFormInstance(this)
1139
1139
  this.selectOrgs = this.convertComment2Field(str, field)
1140
- this.custdialog.custDialog.mappingConf.forEach((con) => {
1141
- var val = ''
1140
+ this.custdialog.custDialog.mappingConf.forEach((con) => {
1141
+ let val = ''
1142
+ let bindValue = ''
1143
+ //改造,绑定值,表单列表查询字段绑定对话框时,新增的绑定字段选项
1144
+ const bindValueField = con.bindValue && con.bindValue.toLowerCase()
1142
1145
  str.forEach((item, index) => {
1143
1146
  // 此处添加url跳转参数保存逻辑
1144
1147
  if (
@@ -1159,6 +1162,10 @@
1159
1162
  },`
1160
1163
  } else {
1161
1164
  val += item[con.from] + ','
1165
+ //绑定字段处理
1166
+ if (bindValueField) {
1167
+ bindValue += item[bindValueField] + ','
1168
+ }
1162
1169
  }
1163
1170
  })
1164
1171
  if (this.modelName == 'data.' + con['target'][0]) {
@@ -1175,6 +1182,22 @@
1175
1182
  val.substring(0, val.length - 1),
1176
1183
  thisIndex
1177
1184
  )
1185
+ //绑定字段值处理,bindValue: {target: {id: xxx}}, bindKey: {target: id }
1186
+ if (bindValue && bindValueField) {
1187
+ const bindValueObj = {}
1188
+ //显示value对象
1189
+ bindValueObj[bindValueField] = bindValue.substring(0, bindValue.length - 1)
1190
+
1191
+ const anInst = pInst['searchForm'] ? pInst['searchForm'] : pInst.data.searchForm
1192
+ //若bindKey不存在,则默认空对象,若存在,则取出bindKey
1193
+ anInst.bindKey = anInst.bindKey || {}
1194
+ //格式 {target: id }
1195
+ anInst.bindKey[con['target'][0]] = bindValueField
1196
+ //若bindValue不存在,则默认空对象,若存在,则取出bindValue
1197
+ anInst.bindValue = anInst.bindValue || {}
1198
+ //格式 {target: {id: xxx}}
1199
+ anInst.bindValue[con['target'][0]] = bindValueObj
1200
+ }
1178
1201
  } else {
1179
1202
  let configAttr = con['target'][0].split('.')
1180
1203
  let path = con['target'][0]
@@ -1203,6 +1226,22 @@
1203
1226
  _val,
1204
1227
  thisIndex
1205
1228
  )
1229
+ //绑定字段值处理,bindValue: {target: {id: xxx}}, bindKey: {target: id }
1230
+ if (bindValue && bindValueField) {
1231
+ const bindValueObj = {}
1232
+ //显示value对象
1233
+ bindValueObj[bindValueField] = bindValue.substring(0, bindValue.length - 1)
1234
+
1235
+ const anInst = pInst['searchForm'] ? pInst['searchForm'] : pInst.data.searchForm
1236
+ //若bindKey不存在,则默认空对象,若存在,则取出bindKey
1237
+ anInst.bindKey = anInst.bindKey || {}
1238
+ //格式 {target: id }
1239
+ anInst.bindKey[con['target'][0]] = bindValueField
1240
+ //若bindValue不存在,则默认空对象,若存在,则取出bindValue
1241
+ anInst.bindValue = anInst.bindValue || {}
1242
+ //格式 {target: {id: xxx}}
1243
+ anInst.bindValue[con['target'][0]] = bindValueObj
1244
+ }
1206
1245
  }
1207
1246
  }
1208
1247
  })
@@ -1856,8 +1895,11 @@
1856
1895
  }
1857
1896
  const pInst = utils.getOnlineFormInstance(this)
1858
1897
  this.custdialog.custDialog.mappingConf.forEach((con) => {
1859
- var val = ''
1860
- var from = con.from.toLowerCase()
1898
+ let val = ''
1899
+ let bindValue = ''
1900
+ const from = con.from.toLowerCase()
1901
+ //改造,绑定值,表单列表查询字段绑定对话框时,新增的绑定字段选项
1902
+ const bindValueField = con.bindValue && con.bindValue.toLowerCase()
1861
1903
  str.forEach((item) => {
1862
1904
  // 如果有绑定url跳转参数 需获取跳转参数的key
1863
1905
  if (item) {
@@ -1885,6 +1927,10 @@
1885
1927
  )}¯${jumpParamKey}:${decodeURIComponent(item[returnMapKey])},`
1886
1928
  } else {
1887
1929
  val += decodeURIComponent(item[from]) + ','
1930
+ //绑定字段处理
1931
+ if (bindValueField) {
1932
+ bindValue += decodeURIComponent(item[bindValueField]) + ','
1933
+ }
1888
1934
  }
1889
1935
  }
1890
1936
  })
@@ -1907,6 +1953,22 @@
1907
1953
  val.substring(0, val.length - 1),
1908
1954
  thisIndex
1909
1955
  )
1956
+ //绑定字段值处理,bindValue: {target: {id: xxx}}, bindKey: {target: id }
1957
+ if (bindValue && bindValueField) {
1958
+ const bindValueObj = {}
1959
+ //显示value对象
1960
+ bindValueObj[bindValueField] = bindValue.substring(0, bindValue.length - 1)
1961
+
1962
+ const anInst = pInst['searchForm'] ? pInst['searchForm'] : pInst.data.searchForm
1963
+ //若bindKey不存在,则默认空对象,若存在,则取出bindKey
1964
+ anInst.bindKey = anInst.bindKey || {}
1965
+ //格式 {target: id }
1966
+ anInst.bindKey[con['target'][0]] = bindValueField
1967
+ //若bindValue不存在,则默认空对象,若存在,则取出bindValue
1968
+ anInst.bindValue = anInst.bindValue || {}
1969
+ //格式 {target: {id: xxx}}
1970
+ anInst.bindValue[con['target'][0]] = bindValueObj
1971
+ }
1910
1972
  } else {
1911
1973
  let configAttr = con['target'][0].split('.')
1912
1974
  let path = con['target'][0]
@@ -33,7 +33,7 @@
33
33
  </template>
34
34
  <script>
35
35
  import permission from '@/mixins/permission.js'
36
- export default {
36
+ export default {
37
37
  name: 'HtDataLists',
38
38
  mixins: [permission],
39
39
  props: {
@@ -56,7 +56,6 @@ export default {
56
56
  watch: {
57
57
  options: {
58
58
  handler(val) {
59
- debugger
60
59
  if (val) {
61
60
  this.tabPaneList = JSON.parse(val)
62
61
  this.activeName = this.tabPaneList[0].dataTemplateKey
@@ -114,4 +113,4 @@ export default {
114
113
  margin-top: 24px;
115
114
  }
116
115
  }
117
- </style>
116
+ </style>
@@ -35,6 +35,16 @@
35
35
  type: String,
36
36
  default: '子表数据',
37
37
  },
38
+ exportMaxRow: {
39
+ type: [String, Number],
40
+ },
41
+ exportField: {
42
+ // 禁止导出的字段集合
43
+ type: String,
44
+ },
45
+ exportFieldTransformData: {
46
+ type: String,
47
+ },
38
48
  },
39
49
  computed: {
40
50
  columns: function() {
@@ -47,6 +57,44 @@
47
57
  }
48
58
  },
49
59
  methods: {
60
+ async sqlChange(config, value = '') {
61
+ return new Promise((resolve) => {
62
+ let params = {
63
+ dsName: config.dataSource,
64
+ sql: config.relevancyValue
65
+ ? config.relevancyValue.replace(/{val}/g, value)
66
+ : '',
67
+ }
68
+ this.$requestConfig.getValueBySql(params).then((res) => {
69
+ resolve(res)
70
+ })
71
+ })
72
+ },
73
+ transformFieldData(data) {
74
+ return new Promise(async (resolve) => {
75
+ let fieldTransformData = JSON.parse(
76
+ decode(this.exportFieldTransformData)
77
+ )
78
+ for (let i = 0; i < data.length; i++) {
79
+ for (let j = 0; j < fieldTransformData.length; j++) {
80
+ if (fieldTransformData[j].relevancyType == 'value') {
81
+ data[i][fieldTransformData[j].field] =
82
+ fieldTransformData[j].relevancyValue
83
+ } else {
84
+ // 动态时 请求接口修改数据
85
+ let result = await this.sqlChange(
86
+ fieldTransformData[j],
87
+ data[i][fieldTransformData[j].field]
88
+ )
89
+ if (result) {
90
+ data[i][fieldTransformData[j].field] = result
91
+ }
92
+ }
93
+ }
94
+ }
95
+ resolve(data)
96
+ })
97
+ },
50
98
  // 配置的数据字典 导出时翻译为汉字
51
99
  changeDictionary(data) {
52
100
  return new Promise(async (resolve, reject) => {
@@ -76,10 +124,18 @@
76
124
  },
77
125
  changeRowKey(rows) {
78
126
  var exportData = []
127
+ let exportFieldArr = null
128
+ if (this.exportField) {
129
+ exportFieldArr = this.exportField.split(',')
130
+ }
79
131
  rows.forEach((row) => {
80
132
  var exportRow = {}
81
133
  this.columns.forEach((col) => {
82
- if (col.ctrlType != 'suntable') {
134
+ if (
135
+ col.ctrlType != 'suntable' &&
136
+ (!exportFieldArr ||
137
+ (exportFieldArr && !exportFieldArr.includes(col.name)))
138
+ ) {
83
139
  exportRow[col.desc] = row[col.name]
84
140
  }
85
141
  })
@@ -87,6 +143,25 @@
87
143
  })
88
144
  return exportData
89
145
  },
146
+ getConfirmValue(rows, count) {
147
+ return new Promise((resolve) => {
148
+ this.$confirm(
149
+ `导出数据量超出导出限制【${count}】,将导出${count}条,是否继续?`,
150
+ '提示',
151
+ {
152
+ confirmButtonText: '确定',
153
+ cancelButtonText: '取消',
154
+ type: 'warning',
155
+ }
156
+ )
157
+ .then(() => {
158
+ resolve(rows.slice(0, count))
159
+ })
160
+ .catch(() => {
161
+ resolve(false)
162
+ })
163
+ })
164
+ },
90
165
  handleCommand(type) {
91
166
  const pInst = utils.getOnlineFormInstance(this)
92
167
  SubPagination.exportData(
@@ -97,6 +172,20 @@
97
172
  )
98
173
  .then(async (data) => {
99
174
  data = JSON.parse(JSON.stringify(data))
175
+ if (this.exportMaxRow && Number(this.exportMaxRow) < data.length) {
176
+ let result = await this.getConfirmValue(
177
+ data,
178
+ Number(this.exportMaxRow)
179
+ )
180
+ if (result === false) {
181
+ return
182
+ }
183
+ data = result
184
+ }
185
+
186
+ if (this.exportFieldTransformData) {
187
+ data = await this.transformFieldData(data)
188
+ }
100
189
  // 导出时 字典转换
101
190
  await this.changeDictionary(data)
102
191
  let exportData = this.changeRowKey(data)
@@ -102,6 +102,45 @@
102
102
  type: String,
103
103
  required: true,
104
104
  },
105
+ importMaxRow: {
106
+ type: [String, Number],
107
+ default: null,
108
+ },
109
+ templateType: {
110
+ // 导入模板类型 default 系统默认 custom 自定义
111
+ type: String,
112
+ default: 'default',
113
+ },
114
+ customTemplate: {
115
+ // 自定义的导入模板文件
116
+ type: String,
117
+ default: '',
118
+ },
119
+ importTransform: {
120
+ // 是否有转换字段
121
+ type: String,
122
+ default: '0',
123
+ },
124
+ importModes: {
125
+ // 导入模式选项显示
126
+ type: String,
127
+ default: 'append,override,merge',
128
+ },
129
+ fieldTransformData: {
130
+ // 转换字段配置
131
+ type: String,
132
+ default: '',
133
+ },
134
+ conditionRule: {
135
+ // 条件模式配置
136
+ type: String,
137
+ default: '',
138
+ },
139
+ conditionType: {
140
+ // 条件模式配置
141
+ type: String,
142
+ default: 'cover',
143
+ },
105
144
  },
106
145
  data() {
107
146
  return {
@@ -110,11 +149,6 @@
110
149
  showRowData: false,
111
150
  mergeFunc: null,
112
151
  mode: 'append',
113
- modeOptions: [
114
- { mode: 'append', desc: '追加导入' },
115
- { mode: 'override', desc: '覆盖导入' },
116
- { mode: 'merge', desc: '合并导入', disabled: true },
117
- ],
118
152
  cacheDicData: {}, // 缓存字典数据
119
153
  }
120
154
  },
@@ -122,6 +156,30 @@
122
156
  columns: function() {
123
157
  return eval(decode(this.dataColumns))
124
158
  },
159
+ modeOptions() {
160
+ let options = [
161
+ { mode: 'append', desc: '追加导入' },
162
+ { mode: 'override', desc: '覆盖导入' },
163
+ { mode: 'merge', desc: '合并导入' },
164
+ { mode: 'condition', desc: '条件导入' },
165
+ ]
166
+ return options.filter((k) => {
167
+ return this.importModes.includes(k.mode)
168
+ })
169
+ },
170
+ conditionConfig() {
171
+ let config = {}
172
+ if (this.conditionRule) {
173
+ config = JSON.parse(decode(this.conditionRule))
174
+ config.conditionArr.forEach((k) => {
175
+ k.exportField = this.getNameByDesc(k.exportField)
176
+ })
177
+ }
178
+ return {
179
+ conditionType: this.conditionType,
180
+ ...config,
181
+ }
182
+ },
125
183
  },
126
184
  watch: {
127
185
  dialogVisible: {
@@ -139,7 +197,7 @@
139
197
  handler: function(newVal) {
140
198
  if (newVal) {
141
199
  // 如果有导入合并的代码,则允许选择合并导入模式
142
- this.$set(this.modeOptions[2], 'disabled', false)
200
+ // this.$set(this.modeOptions[2], 'disabled', false)
143
201
  // 并设置默认为 合并导入
144
202
  this.mode = 'merge'
145
203
  // 解码合并的代码
@@ -156,6 +214,9 @@
156
214
  }
157
215
  },
158
216
  mounted() {
217
+ if (this.importModes) {
218
+ this.mode = this.importModes.split(',')[0]
219
+ }
159
220
  // 初始化导入时需要的参数
160
221
  const pInst = utils.getOnlineFormInstance(this)
161
222
  if (!SubPagination._map.has(this.dataSubname)) {
@@ -173,6 +234,46 @@
173
234
  SubPagination.clear(this.dataSubname)
174
235
  },
175
236
  methods: {
237
+ transformFieldData(data) {
238
+ return new Promise(async (resolve) => {
239
+ if (this.importTransform === '0') {
240
+ resolve(data)
241
+ return
242
+ }
243
+ let fieldTransformData = JSON.parse(decode(this.fieldTransformData))
244
+ for (let i = 0; i < data.length; i++) {
245
+ for (let j = 0; j < fieldTransformData.length; j++) {
246
+ if (fieldTransformData[j].relevancyType == 'value') {
247
+ data[i][fieldTransformData[j].field] =
248
+ fieldTransformData[j].relevancyValue
249
+ } else {
250
+ // 动态时 请求接口修改数据
251
+ let result = await this.sqlChange(
252
+ fieldTransformData[j],
253
+ data[i][fieldTransformData[j].field]
254
+ )
255
+ if (result) {
256
+ data[i][fieldTransformData[j].field] = result
257
+ }
258
+ }
259
+ }
260
+ }
261
+ resolve(data)
262
+ })
263
+ },
264
+ async sqlChange(config, value = '') {
265
+ return new Promise((resolve) => {
266
+ let params = {
267
+ dsName: config.dataSource,
268
+ sql: config.relevancyValue
269
+ ? config.relevancyValue.replace(/{val}/g, value)
270
+ : '',
271
+ }
272
+ this.$requestConfig.getValueBySql(params).then((res) => {
273
+ resolve(res)
274
+ })
275
+ })
276
+ },
176
277
  changeDictionary(data) {
177
278
  return new Promise(async (resolve) => {
178
279
  for (let i = 0; i < data.length; i++) {
@@ -213,6 +314,28 @@
213
314
  },
214
315
  //子表模板导出
215
316
  exportFormSub() {
317
+ // 如果是自定义模板
318
+ if (this.templateType == 'custom' && this.customTemplate) {
319
+ let file = JSON.parse(decode(this.customTemplate))[0]
320
+ this.$requestConfig
321
+ .download(file.response.fileId)
322
+ .then(({ data, headers }) => {
323
+ if (data && headers) {
324
+ // 附件下载
325
+ const fileName = decodeURIComponent(
326
+ headers['content-disposition']
327
+ .split(';')[1]
328
+ .split('filename=')[1]
329
+ )
330
+ const blob = new Blob([data])
331
+ saveAs(blob, fileName)
332
+ }
333
+ })
334
+ .catch((err) => {
335
+ this.$message.error(`附件下载失败:${err}`)
336
+ })
337
+ return
338
+ }
216
339
  let columns = this.columns.filter((item) => {
217
340
  return !(
218
341
  item.ctrlType &&
@@ -262,6 +385,7 @@
262
385
  let count = this.importRows.length
263
386
  if (count > maxRowInt && maxRowInt != 0) {
264
387
  this.$message.error('子表数据已超过最大行数【' + maxRowInt + '】')
388
+ this.$refs.selectFile.value = ''
265
389
  return
266
390
  }
267
391
  } else if (this.mode == 'append') {
@@ -290,17 +414,21 @@
290
414
  }
291
415
  }
292
416
  let importRows = await this.changeDictionary(this.importRows)
417
+ // 导入如果有数据转换的此处做转换
418
+ importRows = await this.transformFieldData(importRows)
293
419
  SubPagination.importData(
294
420
  this.dataSubname,
295
421
  importRows,
296
422
  this.mode,
297
- this.mergeFunc
423
+ this.mergeFunc,
424
+ this.conditionConfig
298
425
  )
299
426
  .then(() => {
300
427
  this.$message.success('导入成功!')
301
428
  this.dialogVisible = false
302
429
  })
303
430
  .catch((err) => {
431
+ this.$refs.selectFile.value = ''
304
432
  this.$message.error(`数据导入失败:${err}`)
305
433
  })
306
434
  },
@@ -309,10 +437,43 @@
309
437
  return
310
438
  }
311
439
  this.importRows = []
312
- this.readWorkbookFromLocalFile(m.target.files[0], (rows) => {
440
+ this.readWorkbookFromLocalFile(m.target.files[0], async (rows) => {
441
+ if (this.importMaxRow) {
442
+ let count = rows.length
443
+ if (count > parseInt(this.importMaxRow)) {
444
+ let result = await this.getConfirmValue(
445
+ rows,
446
+ parseInt(this.importMaxRow)
447
+ )
448
+ if (result === false) {
449
+ this.$refs.selectFile.value = ''
450
+ return
451
+ }
452
+ rows = result
453
+ }
454
+ }
313
455
  this.importRows = this.changeRowKey(rows)
314
456
  })
315
457
  },
458
+ getConfirmValue(rows, count) {
459
+ return new Promise((resolve) => {
460
+ this.$confirm(
461
+ `导入数据量已超过最大限制,将默认导入前【${count}】条,是否继续?`,
462
+ '提示',
463
+ {
464
+ confirmButtonText: '确定',
465
+ cancelButtonText: '取消',
466
+ type: 'warning',
467
+ }
468
+ )
469
+ .then(() => {
470
+ resolve(rows.slice(0, count))
471
+ })
472
+ .catch(() => {
473
+ resolve(false)
474
+ })
475
+ })
476
+ },
316
477
  // 读取本地excel文件
317
478
  readWorkbookFromLocalFile(file, callback) {
318
479
  const reader = new FileReader()
@@ -15,6 +15,7 @@
15
15
  :class="{ 'is-align-right': isAlignRight }"
16
16
  >
17
17
  <label v-if="label" v-ellipsis :title="label" class="search-field-label">
18
+ <span v-if="isRequired" class="red-color">*</span>
18
19
  {{ label }}
19
20
  </label>
20
21
  </div>
@@ -167,6 +168,7 @@
167
168
  type: Boolean,
168
169
  default: false,
169
170
  },
171
+ isRequired: Boolean,
170
172
  },
171
173
  data() {
172
174
  return {
@@ -317,6 +319,9 @@
317
319
  display: inline-block;
318
320
  max-width: calc(100% - 10px);
319
321
  line-height: 100%;
322
+ .red-color {
323
+ color: #f56c6c;
324
+ }
320
325
 
321
326
  &::after {
322
327
  content: ':';
@@ -845,5 +845,5 @@ const Formulas = {
845
845
  Formulas.install = (Vue) => {
846
846
  Vue.prototype.$Formulas = Formulas
847
847
  }
848
-
848
+ window.FormMath = Formulas
849
849
  export { formula, Formulas }