n20-common-lib 2.9.43 → 2.9.44

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": "2.9.43",
3
+ "version": "2.9.44",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -2,6 +2,15 @@
2
2
  <template>
3
3
  <div :class="prefixCls">
4
4
  <el-form ref="approveBtnGroup" label-position="right" :label-width="_lang === 'zh' ? '6em' : '10em'">
5
+ <div v-if="taskId && showBtn" class="m-b-s">
6
+ <show-other-att-new
7
+ v-if="authList.includes('isShowOtherAtt')"
8
+ ref="showOtherAttNew"
9
+ :task-id="taskId"
10
+ :form="customizationDtos"
11
+ />
12
+ </div>
13
+
5
14
  <div v-if="taskId && showBtn" class="flex-box">
6
15
  <el-form-item v-if="authList.includes('isCarboncopy')" :label="'抄送' | $lc" class="flex-1 m-b-s">
7
16
  <el-input
@@ -80,6 +89,7 @@
80
89
  </div>
81
90
  </el-form-item>
82
91
  </div>
92
+
83
93
  <div class="flex-box">
84
94
  <template v-if="taskId && showBtn">
85
95
  <show-app-opi
@@ -123,7 +133,7 @@
123
133
  :file-url.sync="fileUrl"
124
134
  :on-success="onSuccess"
125
135
  :on-remove="onRemove"
126
- action="/api/neams/eamsbaserecord/batchSavejson"
136
+ action="/neams/eamsbaserecord/batchSavejson"
127
137
  msg-type="message"
128
138
  />
129
139
  </el-form-item>
@@ -253,6 +263,7 @@ import CarboncopyProp from './setCarboncopyProp.vue'
253
263
  import RejectToProp from './setRejectToProp.vue'
254
264
  import ShowAppOpi from './showAppOpi.vue'
255
265
  import ShowOtherAtt from './showOtherAttr.vue'
266
+ import ShowOtherAttNew from './showOtherAttrNew.vue'
256
267
  import { toExaminePath } from './specialHandle'
257
268
  const prefixCls = 'n20-approval-Button'
258
269
  // window._approvalExtend = { 'addtask.chdUserInfo.extend': {}, 'appOpi.queryAppOpiAndUser.exist': undefined, 'card.countermand.suggestion': false }
@@ -269,7 +280,8 @@ export default {
269
280
  CarboncopyProp,
270
281
  RejectToProp,
271
282
  ShowAppOpi,
272
- ShowOtherAtt
283
+ ShowOtherAtt,
284
+ ShowOtherAttNew
273
285
  },
274
286
  props: {
275
287
  message: {
@@ -370,6 +382,7 @@ export default {
370
382
  opiAndUser: false,
371
383
  addTaskMode: '0',
372
384
  otherAtt: {},
385
+ customizationDtos: {},
373
386
  fileDtos: [],
374
387
  fileName: '',
375
388
  fileUrl: '',
@@ -538,6 +551,10 @@ export default {
538
551
  // 获取提交参数
539
552
  getParam() {
540
553
  let { typeCode, taskId, groupNo, isAgentcy, isCheck } = this.$route.query
554
+ let customizationDtos
555
+ if (this.authList.includes('isShowOtherAtt')) {
556
+ customizationDtos = this.$refs['showOtherAttNew']?.getOtherAttData()
557
+ }
541
558
  return [
542
559
  {
543
560
  typeCode,
@@ -556,6 +573,7 @@ export default {
556
573
  addTaskType: this.addTaskType,
557
574
  addTaskTag: this.addTaskTag,
558
575
  addTaskWay: this.addTaskWay,
576
+ customizationDtos,
559
577
  ...this.otherAtt
560
578
  }
561
579
  ]
@@ -649,6 +667,7 @@ export default {
649
667
  this.approvalFn()
650
668
  },
651
669
  async checkFlowFn() {
670
+ debugger
652
671
  if (this.requiredC && !this.messageC) {
653
672
  return this.errMsgFn(
654
673
  this.authList.includes('byAddTask') && this.addTaskList.length > 0 ? $lc('加签') : $lc('批准')
@@ -0,0 +1,99 @@
1
+ <template>
2
+ <div class="w-100p flex-box">
3
+ <div v-for="(item, i) in otherAttData" :key="i" class="flex-box">
4
+ <el-form-item class="m-r-ss m-b-s" :label="item.cfgName">
5
+ <el-input v-if="item.cfgType === '11'" v-model="item.cfgVal" class="flex-item" clearable />
6
+ <el-select
7
+ v-if="['21'].includes(item.cfgType)"
8
+ v-model="item.cfgVal"
9
+ class="flex-item"
10
+ clearable
11
+ @change="(val) => changeFn(val, item)"
12
+ >
13
+ <el-option v-for="(row, i) in JSON.parse(item.cfgJson)" :key="i" :label="row.value" :value="row.code" />
14
+ </el-select>
15
+ <el-select
16
+ v-if="['31'].includes(item.cfgType)"
17
+ v-model="selectList"
18
+ multiple
19
+ collapse-tags
20
+ class="flex-item"
21
+ clearable
22
+ @change="(val) => changeFn(val, item)"
23
+ >
24
+ <el-option v-for="(row, i) in JSON.parse(item.cfgJson)" :key="i" :label="row.value" :value="row.code" />
25
+ </el-select>
26
+ <el-radio-group v-if="item.cfgType === '22'" v-model="item.cfgVal" @change="(val) => changeFn(val, item)">
27
+ <el-radio v-for="(row, i) in JSON.parse(item.cfgJson)" :key="i" :label="row.code">{{ row.value }}</el-radio>
28
+ </el-radio-group>
29
+ <el-checkbox-group v-if="item.cfgType === '32'" v-model="checkList" @change="(val) => changeFn(val, item)">
30
+ <el-checkbox v-for="(row, i) in JSON.parse(item.cfgJson || '[]')" :key="i" :label="row.code">{{
31
+ row.value
32
+ }}</el-checkbox>
33
+ </el-checkbox-group>
34
+ </el-form-item>
35
+ </div>
36
+ </div>
37
+ </template>
38
+
39
+ <script>
40
+ import axios from '../../utils/axios'
41
+ export default {
42
+ props: {
43
+ taskId: {
44
+ type: [String, Number],
45
+ default: ''
46
+ },
47
+ form: {
48
+ type: Object,
49
+ default: () => ({})
50
+ }
51
+ },
52
+ data() {
53
+ return {
54
+ checkList: [],
55
+ selectList: [],
56
+ otherAttData: []
57
+ }
58
+ },
59
+ mounted() {
60
+ this.getData()
61
+ },
62
+ methods: {
63
+ getData() {
64
+ axios.post(`/bems/admin/customization/${this.taskId}`, null, { loading: false }).then(({ data }) => {
65
+ if (data && data.length) {
66
+ this.otherAttData = data || []
67
+ }
68
+ })
69
+ },
70
+ changeFn(val, item) {
71
+ if (['31', '32'].includes(item.cfgType)) {
72
+ const cfgJson = JSON.parse(item.cfgJson)
73
+ item.cfgText = val
74
+ ?.map((s) => cfgJson?.find((row) => row.code === s)?.value)
75
+ ?.filter((s) => s)
76
+ .join(',')
77
+ item.cfgVal = val?.join(',')
78
+ }
79
+ if (['22', '21'].includes(item.cfgType)) {
80
+ const cfgJson = JSON.parse(item.cfgJson)
81
+ item.cfgText = cfgJson.find((row) => row.code === val)?.value
82
+ item.cfgVal = val
83
+ }
84
+ },
85
+ getOtherAttData() {
86
+ return this.otherAttData?.map((item) => {
87
+ return {
88
+ cfgName: item.cfgName,
89
+ cfgKey: item.cfgKey,
90
+ cfgVal: item.cfgVal,
91
+ cfgText: item.cfgText
92
+ }
93
+ })
94
+ }
95
+ }
96
+ }
97
+ </script>
98
+
99
+ <style></style>
@@ -63,7 +63,7 @@
63
63
  </div>
64
64
  <div v-if="item.showConnect === '1'" class="m-l-s">
65
65
  <span class="pointer color-ccc f-s-s" @click="seeDetail(item)"
66
- >查看详情 <i class="el-icon-arrow-right"></i
66
+ >{{ '查看详情' | $lc }} <i class="el-icon-arrow-right"></i
67
67
  ></span>
68
68
  </div>
69
69
  </div>
@@ -85,7 +85,7 @@
85
85
 
86
86
  <div v-if="showChildTimeline" class="n20-approve-wrap-children">
87
87
  <el-timeline :reverse="true">
88
- <el-timeline-item
88
+ <div
89
89
  v-for="(row, i) in approvalChildrenData"
90
90
  :key="i"
91
91
  :type="row | typeF(status)"
@@ -95,7 +95,7 @@
95
95
  <div>{{ row.endTime | dataF }}</div>
96
96
  <div>{{ row.endTime | timeF }}</div>
97
97
  </div>
98
- <div>
98
+ <template>
99
99
  <div v-if="row.result === 0" class="flex-box flex-v">
100
100
  <div
101
101
  v-title="row.assignee"
@@ -160,14 +160,30 @@
160
160
  <div v-if="row.addTaskName" class="n20-description-c m-t">
161
161
  {{ '加签审批人:' | $lc }}{{ row.addTaskName }}
162
162
  </div>
163
- <template v-if="row.resultName !== '撤回' || showCtdMsg">
163
+ <div v-if="row.resultName !== '撤回' || showCtdMsg">
164
164
  <div v-if="row.suggestion" class="n20-description-c n20-description-bgc m-t p-a-s">
165
165
  <span v-if="row.result !== status.waiting">{{ '审批意见:' | $lc }}</span>
166
166
  <span>{{ row.suggestion }} </span>
167
167
  </div>
168
- </template>
169
- </div>
170
- </el-timeline-item>
168
+ <div
169
+ v-if="row.flowHistoryCfgs && row.flowHistoryCfgs.length"
170
+ class="n20-description-c m-t p-a-s"
171
+ >
172
+ <span
173
+ v-if="row.result !== status.waiting"
174
+ class="color-primary pointer"
175
+ @click="showFlowHistoryChild = !showFlowHistoryChild"
176
+ >{{ '审查意见:' | $lc }} <i class="n20-icon-shouqizhedie f-s-m"></i
177
+ ></span>
178
+ <div v-show="showFlowHistoryChild" class="n20-description-bgc p-a-s">
179
+ <div v-for="(s, i) in row.flowHistoryCfgs" :key="i">
180
+ {{ s.cfgName }}:{{ s.cfgText ? s.cfgText : s.cfgVal }}
181
+ </div>
182
+ </div>
183
+ </div>
184
+ </div>
185
+ </template>
186
+ </div>
171
187
  </el-timeline>
172
188
  </div>
173
189
  </div>
@@ -175,6 +191,19 @@
175
191
  <span v-if="item.result !== status.waiting">{{ '审批意见:' | $lc }}</span>
176
192
  <span>{{ item.suggestion }} </span>
177
193
  </div>
194
+ <div v-if="item.flowHistoryCfgs && item.flowHistoryCfgs.length" class="n20-description-c m-t p-a-s">
195
+ <span
196
+ v-if="item.result !== status.waiting"
197
+ class="color-primary pointer"
198
+ @click="showFlowHistory = !showFlowHistory"
199
+ >{{ '审查意见:' | $lc }}<i class="n20-icon-shouqizhedie f-s-m"></i
200
+ ></span>
201
+ <div v-show="showFlowHistory" class="n20-description-bgc p-a-s">
202
+ <div v-for="(s, i) in item.flowHistoryCfgs" :key="i">
203
+ {{ s.cfgName }}:{{ s.cfgText ? s.cfgText : s.cfgVal }}
204
+ </div>
205
+ </div>
206
+ </div>
178
207
  <div v-if="item.flowHisFileList" class="n20-description-c n20-description-bgc m-t p-a-s">
179
208
  <span>{{ '附件信息' | $lc }}:</span>
180
209
  <div class="flex-box">
@@ -349,7 +378,9 @@ export default {
349
378
  previewName: '',
350
379
  previewSameOrg: false,
351
380
  seeTypes: /\.(jpg|png|gif|svg|pdf|swf|xlsx|xls|docx|doc)$/i,
352
- seeRow: {}
381
+ seeRow: {},
382
+ showFlowHistory: false,
383
+ showFlowHistoryChild: false
353
384
  }
354
385
  },
355
386
  async created() {
@@ -362,7 +393,7 @@ export default {
362
393
  async seeDetail(item) {
363
394
  const { appUrl = {} } = await getJsonc('activiti/server-config.jsonc', null, true)
364
395
  if (appUrl[item._details.appNo]) {
365
- let path = appUrl[item._details.appNo] + $l('/') + item._details.typeCode
396
+ let path = appUrl[item._details.appNo] + '/' + item._details.typeCode
366
397
  linkPush(path, {
367
398
  taskId: item._details.taskId,
368
399
  typeCode: item._details.typeCode,
@@ -408,7 +439,8 @@ export default {
408
439
  showConnect: item.showConnect, // 是否显示查看详情
409
440
  _details: item,
410
441
  deptName: item.deptName, // 部门
411
- addTaskTag: item.addTaskTag // 加签备注
442
+ addTaskTag: item.addTaskTag, // 加签备注
443
+ flowHistoryCfgs: item.flowHistoryCfgs // 自定义字段
412
444
  }
413
445
  if (_item.addTaskTag && this.remarkOpt?.length === 0) {
414
446
  this.getMdmDataDoc()
@@ -84,7 +84,8 @@ const obj = {
84
84
  type: item2.fieldType,
85
85
  label: item2.fieldName,
86
86
  requiredFlag: item2.isMust,
87
- remark: item2.remark
87
+ remark: item2.remark,
88
+ options: item2.fieldValue
88
89
  }
89
90
  }
90
91
  })
@@ -6,7 +6,7 @@
6
6
  <el-button v-if="type === 1" size="mini" type="primary" @click="option('新增')">新增</el-button>
7
7
  <el-button v-if="type === 1" size="mini" type="danger" plain @click="option('删除')">删除</el-button>
8
8
  <!-- <el-button v-if="type === 1" size="mini" plain @click="option('导出')">导出</el-button> -->
9
- <el-button size="mini" icon="n20-icon-caidan" plain onlyicon @click="option('转换')" />
9
+ <el-button v-if="hasTransform" size="mini" icon="n20-icon-caidan" plain onlyicon @click="option('转换')" />
10
10
  </div>
11
11
  </div>
12
12
  <transition name="el-zoom-in-center">
@@ -23,6 +23,27 @@
23
23
  <vxe-column slot="order" title="排序" width="60px" align="center">
24
24
  <i class="n20-icon-tuodong draggable-button"></i>
25
25
  </vxe-column>
26
+ <!-- 取值规则 -->
27
+ <vxe-column
28
+ slot="fieldValue"
29
+ slot-scope="{ column }"
30
+ v-bind="column"
31
+ :field="column.prop"
32
+ :title="column.label"
33
+ >
34
+ <template slot-scope="{ row, $rowIndex }">
35
+ <el-input
36
+ v-if="row.fieldType !== 'select'"
37
+ v-model="row[column.prop]"
38
+ placeholder="请输入"
39
+ size="normal"
40
+ clearable
41
+ />
42
+ <el-button v-else type="text" size="small" @click="pz(row, $rowIndex)">{{
43
+ row[column.prop] || '配置'
44
+ }}</el-button>
45
+ </template>
46
+ </vxe-column>
26
47
  <vxe-column slot="input" slot-scope="{ column }" v-bind="column" :field="column.prop" :title="column.label">
27
48
  <el-input v-model="row[column.prop]" slot-scope="{ row }" placeholder="请输入" size="normal" clearable />
28
49
  </vxe-column>
@@ -81,6 +102,9 @@
81
102
  <el-button type="primary" @click="option('保存')">保存</el-button>
82
103
  <el-button plain @click="option('重置')">重置</el-button>
83
104
  </div>
105
+ <cl-dialog v-drag :visible.sync="visible" title="数据来源" :destroy-on-open="true">
106
+ <content-pop v-model="selectFieldValue" :visible.sync="visible" @save="dialogSave" />
107
+ </cl-dialog>
84
108
  </cl-page>
85
109
  </template>
86
110
 
@@ -90,11 +114,16 @@ import customFormOptionsData from './jsonData/customFormOptionsData.json'
90
114
  import DynamicField from './DynamicField.vue'
91
115
  import DynamicFieldMixin from './DynamicFieldMixin.js'
92
116
  import { deepClone } from './utils'
117
+ import contentPop from './contentPop.vue'
93
118
  export default {
94
119
  name: 'DynamicFieldOptions',
95
- components: { DynamicField },
120
+ components: { DynamicField, contentPop },
96
121
  mixins: [DynamicFieldMixin],
97
122
  props: {
123
+ hasTransform: {
124
+ type: Boolean,
125
+ default: false
126
+ },
98
127
  showItems: {
99
128
  type: Array,
100
129
  default: () => {
@@ -137,16 +166,18 @@ export default {
137
166
  },
138
167
  data() {
139
168
  return {
169
+ visible: false,
140
170
  fieldType: [
141
171
  { code: 'input', name: '输入框' },
142
172
  { code: 'input-number', name: '金额输入框' },
143
- { code: 'input-number-range', name: '金额区间' },
144
- { code: 'input-rate-range', name: '利率区间' },
145
173
  { code: 'select', name: '下拉框' },
146
174
  { code: 'selectMultiple', name: '多选下拉框' },
147
175
  { code: 'date-picker', name: '日期选择' },
148
- { code: 'textarea', name: '大文本' },
149
- { code: 'searchinput', name: '搜索框' }
176
+ { code: 'textarea', name: '大文本' }
177
+ // 这三种暂时不开放
178
+ /* { code: 'input-number-range', name: '金额区间' },
179
+ { code: 'input-rate-range', name: '利率区间' },
180
+ /* { code: 'searchinput', name: '搜索框' } */
150
181
  ],
151
182
  type: 1,
152
183
  selectData: [],
@@ -237,7 +268,7 @@ export default {
237
268
  },
238
269
 
239
270
  {
240
- slotName: 'input',
271
+ slotName: 'fieldValue',
241
272
  label: '取值规则',
242
273
  prop: 'fieldValue',
243
274
  align: 'center',
@@ -266,7 +297,9 @@ export default {
266
297
  checkColumns: [],
267
298
  formValue: {},
268
299
  form: [],
269
- rules: {}
300
+ rules: {},
301
+ selectFieldValue: [],
302
+ selectIndex: {}
270
303
  }
271
304
  },
272
305
  computed: {},
@@ -288,6 +321,20 @@ export default {
288
321
  })
289
322
  },
290
323
  methods: {
324
+ pz(row, index) {
325
+ this.selectFieldValue = row.fieldValue || []
326
+ this.selectIndex = index
327
+ this.visible = true
328
+ },
329
+ dialogSave(value) {
330
+ this.visible = false
331
+ this.tableData[this.selectIndex].fieldValue = value.map((item) => {
332
+ return {
333
+ label: item.label,
334
+ value: item.value
335
+ }
336
+ })
337
+ },
291
338
  // 处理控件类型
292
339
  setFieldType() {
293
340
  this.options.fieldType.forEach((item) => {
@@ -321,13 +368,6 @@ export default {
321
368
  console.log(this.tableData)
322
369
  this.form = this.transform(this.tableData).form
323
370
  this.formValue = this.transform(this.tableData).formValue
324
- this.setType('select', {
325
- options: [
326
- { value: '1', label: '网银' },
327
- { value: '2', label: '网关' },
328
- { value: '3', label: '其他' }
329
- ]
330
- })
331
371
  this.setRules()
332
372
  },
333
373
  option(key) {
@@ -0,0 +1,105 @@
1
+ <template>
2
+ <cl-page class="contentPop">
3
+ <div class="flex-box flex-lr flex-v m-b-s">
4
+ <div></div>
5
+ <div>
6
+ <el-button type="primary" size="mini" @click="option('新增')">新增</el-button>
7
+ </div>
8
+ </div>
9
+ <cl-table-pro ref="xTable" :loading="loading" :data="value" :columns="TableHeader" :height="'300px'">
10
+ <vxe-column slot="input" slot-scope="{ column }" v-bind="column" :field="column.prop" :title="column.label">
11
+ <el-input v-model="row[column.prop]" slot-scope="{ row }" placeholder="请输入" size="normal" clearable />
12
+ </vxe-column>
13
+ <vxe-column slot="delete" slot-scope="{ column }" v-bind="column" :field="column.prop" :title="column.label">
14
+ <el-link
15
+ slot-scope="{ row, $rowIndex }"
16
+ class="m-r-s"
17
+ :underline="false"
18
+ icon="n20-icon-a-shanchuxuanzhong"
19
+ @click="option('删除', row, $rowIndex)"
20
+ />
21
+ </vxe-column>
22
+ </cl-table-pro>
23
+
24
+ <div slot="footer" class="page-button-shadow flex-box flex-c flex-v">
25
+ <el-button type="primary" @click="option('保存')">保存</el-button>
26
+ <!-- <el-button plain @click="option('重置')">重置</el-button> -->
27
+ </div>
28
+ </cl-page>
29
+ </template>
30
+
31
+ <script>
32
+ export default {
33
+ name: 'ContentPop',
34
+ components: {},
35
+ props: {
36
+ value: {
37
+ type: Array,
38
+ default: () => {
39
+ return []
40
+ }
41
+ }
42
+ },
43
+ data() {
44
+ return {
45
+ TableHeader: [
46
+ /* {
47
+ type: 'checkbox',
48
+ static: 'pre' // 静态不被"显示列"显示的,且最终会被拼接到"显示列"排序后的表格的"前面"
49
+ }, */
50
+ {
51
+ type: 'seq',
52
+ label: '序号',
53
+ width: '56',
54
+ align: 'center'
55
+ },
56
+ {
57
+ slotName: 'input',
58
+ label: '枚举名',
59
+ prop: 'label',
60
+ align: 'left',
61
+ minWidth: '120',
62
+ 'show-overflow-tooltip': true
63
+ },
64
+ {
65
+ slotName: 'input',
66
+ label: '枚举值',
67
+ prop: 'value',
68
+ width: '260'
69
+ },
70
+ {
71
+ slotName: 'delete',
72
+ width: '50'
73
+ }
74
+ ],
75
+ loading: false
76
+ }
77
+ },
78
+ computed: {},
79
+ watch: {},
80
+ created() {},
81
+ mounted() {},
82
+ methods: {
83
+ option(key, row, index) {
84
+ switch (key) {
85
+ case '删除':
86
+ this.value.splice(index, 1)
87
+ break
88
+ case '新增':
89
+ this.value.push({})
90
+ break
91
+ case '保存':
92
+ this.$emit('save', this.value)
93
+ break
94
+ default:
95
+ break
96
+ }
97
+ }
98
+ }
99
+ }
100
+ </script>
101
+ <style lang="scss" scoped>
102
+ .contentPop {
103
+ font-size: 14px;
104
+ }
105
+ </style>
@@ -0,0 +1,566 @@
1
+ <template>
2
+ <dialog-wrap
3
+ ref="dialog"
4
+ v-drag
5
+ class="p-t-0"
6
+ v-bind="$attrs"
7
+ :visible.sync="visible"
8
+ :title="title"
9
+ :width="width"
10
+ :close-on-click-modal="false"
11
+ @open="popOpen"
12
+ >
13
+ <div class="dialog-view">
14
+ <div class="flex-box">
15
+ <div class="left-c flex-column p-t-m bd-r">
16
+ <div class="flex-box flex-v p-r m-b">
17
+ <span>{{ header }}</span>
18
+ <span class="m-l-m color-999">
19
+ {{ '已选' | $lc }}
20
+ <span class="color-main">{{ dragList.length }}</span>
21
+ </span>
22
+ <el-link :underline="false" type="primary" class="m-l-auto" @click="setAll">{{
23
+ setState ? $lc('全部清空') : $lc('全部选中')
24
+ }}</el-link>
25
+ </div>
26
+ <div class="flex-item p-r" style="height: 50%; overflow: auto">
27
+ <el-checkbox-group :value="dragListN.map((d) => d[labelKey])">
28
+ <template v-if="!columnsGroups">
29
+ <el-checkbox
30
+ v-for="(column, i) in columnsAs"
31
+ :key="i"
32
+ v-hover-tooltip="column[labelKey]"
33
+ :label="column[labelKey]"
34
+ :disabled="column.checked"
35
+ class="m-t"
36
+ @change="(val) => checkChange(val, column)"
37
+ >{{ column[labelKey] }}</el-checkbox
38
+ >
39
+ </template>
40
+ <template v-else>
41
+ <div v-for="gp in columnsGroups" :key="gp.groupId" class="m-b">
42
+ <div class="f-s-b font-w600">{{ gp.groupName }}</div>
43
+ <template v-for="(column, i) in columnsAs">
44
+ <el-checkbox
45
+ v-if="column.groupId === gp.groupId"
46
+ :key="i"
47
+ v-hover-tooltip="column[labelKey]"
48
+ :label="column[labelKey]"
49
+ :disabled="column.checked"
50
+ class="m-t"
51
+ @change="(val) => checkChange(val, column)"
52
+ >{{ column[labelKey] }}</el-checkbox
53
+ >
54
+ </template>
55
+ </div>
56
+ </template>
57
+ </el-checkbox-group>
58
+ </div>
59
+ </div>
60
+ <div v-if="!hasPX" class="right-c flex-column p-t-m">
61
+ <div class="m-b">
62
+ {{ '当前选定项' | $lc }}
63
+ <el-link type="primary" style="visibility: hidden">{{ '当前选定项' | $lc }}</el-link>
64
+ </div>
65
+ <div class="flex-1 overflow-y">
66
+ <drag-list :list="dragList" :label-key="labelKey" :in-show-column="true" />
67
+ </div>
68
+ </div>
69
+ <div v-else class="right-tree flex-column p-t-m">
70
+ <div class="m-b flex-box flex-lr flex-v">
71
+ {{ '当前选定项' | $lc }}
72
+ <el-link class="m-r-s" :underline="false" icon="n20-icon-xinzeng" @click="add">{{
73
+ '新增字段' | $lc
74
+ }}</el-link>
75
+ </div>
76
+ <el-tree
77
+ ref="menu-tree"
78
+ class="menu-tree"
79
+ :data="dragList"
80
+ :props="{
81
+ children: 'children',
82
+ label: 'label'
83
+ }"
84
+ node-key="prop"
85
+ draggable
86
+ style="width: 200px"
87
+ :allow-drop="allowDrop"
88
+ >
89
+ <span slot-scope="{ node, data }" class="menu-item flex-item flex-box flex-lr flex-v">
90
+ <span>
91
+ <i class="n20-drag-icon n20-icon-tuodong"></i>
92
+ <span
93
+ :class="data.isNew ? 'color-success' : 'color-primary'"
94
+ class="text-ellipsis pointer"
95
+ @click="clickItem(data)"
96
+ >{{ data.label }}</span
97
+ >
98
+ </span>
99
+ <el-link
100
+ class="n20-icon-shanchu"
101
+ :underline="false"
102
+ :disabled="data.checked"
103
+ @click.stop="() => removeMenu(node, data)"
104
+ />
105
+ </span>
106
+ </el-tree>
107
+ </div>
108
+ </div>
109
+ </div>
110
+ <dialogWrap
111
+ v-drag
112
+ :visible.sync="configVisible"
113
+ :title="'表头设置' | $lc"
114
+ width="350px"
115
+ :close-on-click-modal="false"
116
+ >
117
+ <el-form :model="configModel">
118
+ <el-form-item>
119
+ {{ configModel.label }}
120
+ </el-form-item>
121
+ <el-form-item
122
+ :label="'表头宽度' | $lc"
123
+ :rules="[
124
+ {
125
+ type: 'number',
126
+ trigger: ['change', 'blur'],
127
+ validator: validator
128
+ }
129
+ ]"
130
+ prop="width"
131
+ >
132
+ <el-input v-model="configModel.width" class="w-224" />
133
+ </el-form-item>
134
+ <el-form-item :label="'是否折行' | $lc">
135
+ <el-radio-group v-model="configModel.wrap">
136
+ <el-radio :label="true">{{ $lc('是') }}</el-radio>
137
+ <el-radio :label="false">{{ $lc('否') }}</el-radio>
138
+ </el-radio-group>
139
+ </el-form-item>
140
+ <el-form-item :label="'是否加粗' | $lc">
141
+ <el-radio-group v-model="configModel.bold">
142
+ <el-radio :label="true">{{ $lc('是') }}</el-radio>
143
+ <el-radio :label="false">{{ $lc('否') }}</el-radio>
144
+ </el-radio-group>
145
+ </el-form-item>
146
+ <el-form-item :label="'对齐方式' | $lc">
147
+ <el-radio-group v-model="configModel.align">
148
+ <el-radio :label="'right'">{{ $lc('右对齐') }}</el-radio>
149
+ <el-radio :label="'left'">{{ $lc('左对齐') }}</el-radio>
150
+ <el-radio :label="'center'">{{ $lc('居中对齐') }}</el-radio>
151
+ </el-radio-group>
152
+ </el-form-item>
153
+ </el-form>
154
+ <div slot="footer">
155
+ <el-button type="primary" @click="configSave">{{ '确定' | $lc }}</el-button>
156
+ </div>
157
+ </dialogWrap>
158
+ <dialogWrap v-drag :visible.sync="configVisibleN" :title="'新增' | $lc" width="350px" :close-on-click-modal="false">
159
+ <el-form :model="configModelN">
160
+ <el-form-item :label="'名称' | $lc" required>
161
+ <el-input v-model="configModelN.label" class="input-w" :placeholder="'请输入' | $lc" />
162
+ </el-form-item>
163
+ </el-form>
164
+ <div slot="footer">
165
+ <el-button type="primary" @click="configSaveN">{{ '确定' | $lc }}</el-button>
166
+ </div>
167
+ </dialogWrap>
168
+ <div slot="footer" class="text-c">
169
+ <el-button type="primary" @click="setChange">{{ '确定' | $lc }}</el-button>
170
+ <el-button plain @click="reset">{{ '恢复默认' | $lc }}</el-button>
171
+ </div>
172
+ </dialog-wrap>
173
+ </template>
174
+
175
+ <script>
176
+ import axios from '../../utils/axios'
177
+ import { $lc } from '../../utils/i18n/index'
178
+
179
+ import { Message } from 'element-ui'
180
+ import forEachs from '../../utils/forEachs'
181
+ import dialogWrap from '../Dialog/index.vue'
182
+ import dragList from '../DragList/index.vue'
183
+ export default {
184
+ name: 'ShowColumn',
185
+ components: { dialogWrap, dragList },
186
+ inheritAttrs: false,
187
+ props: {
188
+ dialogVisible: {
189
+ type: Boolean,
190
+ default: false
191
+ },
192
+ columns: {
193
+ type: Array,
194
+ default: () => []
195
+ },
196
+ columnsGroups: {
197
+ type: Array,
198
+ default: undefined
199
+ },
200
+ checkColumns: {
201
+ type: Array,
202
+ default: () => []
203
+ },
204
+ isExport: {
205
+ type: Boolean,
206
+ default: false
207
+ },
208
+ isFilter: {
209
+ type: Boolean,
210
+ default: false
211
+ },
212
+ labelKey: {
213
+ type: String,
214
+ default: 'label'
215
+ },
216
+ pageId: {
217
+ type: String,
218
+ default: undefined
219
+ },
220
+ autoSave: {
221
+ type: Boolean,
222
+ default: false
223
+ },
224
+ width: {
225
+ type: String,
226
+ default: '1000px'
227
+ },
228
+ hasPX: {
229
+ type: Boolean,
230
+ default: false
231
+ }
232
+ },
233
+ data() {
234
+ return {
235
+ dragList: [],
236
+ configVisible: false,
237
+ enabled: false,
238
+ configModel: {
239
+ wrap: false,
240
+ bold: false,
241
+ align: 'center'
242
+ },
243
+ configModelN: {
244
+ label: '',
245
+ prop: '',
246
+ width: 120,
247
+ isNew: true,
248
+ children: []
249
+ },
250
+ userNo: sessionStorage.getItem('userNo'),
251
+ configVisibleN: false,
252
+ dragListN: []
253
+ }
254
+ },
255
+ computed: {
256
+ title() {
257
+ if (this.isExport) {
258
+ return $lc('导出')
259
+ } else if (this.isFilter) {
260
+ return $lc('筛选')
261
+ } else {
262
+ return $lc('设置显示列')
263
+ }
264
+ },
265
+ header() {
266
+ if (this.isExport) {
267
+ return $lc('导出')
268
+ } else if (this.isFilter) {
269
+ return $lc('筛选')
270
+ } else {
271
+ return $lc('显示列')
272
+ }
273
+ },
274
+ visible: {
275
+ get() {
276
+ return this.dialogVisible
277
+ },
278
+ set(val) {
279
+ this.$emit('update:dialogVisible', val)
280
+ }
281
+ },
282
+ setState() {
283
+ return this.columnsAs.length && this.columnsAs.length === this.dragListN.length
284
+ },
285
+ columnsAs: {
286
+ get() {
287
+ return this.columns.filter((col) => !col.static)
288
+ },
289
+ set(val) {
290
+ return val
291
+ }
292
+ }
293
+ },
294
+ watch: {
295
+ dragList: {
296
+ handler() {
297
+ let arr = []
298
+ forEachs(this.dragList, (item) => {
299
+ arr.push(item)
300
+ })
301
+ this.dragListN = arr
302
+ /* const newArr = arr.filter((item) => {
303
+ return item.isNew
304
+ })
305
+ newArr.forEach((item) => {
306
+ const index = this.columns.findIndex((col) => col.prop === item.prop || col.label === item.label)
307
+ if (index === -1) {
308
+ this.columns.push(item)
309
+ }
310
+ }) */
311
+ },
312
+ immediate: true,
313
+ deep: true
314
+ }
315
+ },
316
+ methods: {
317
+ validator(rule, value, callback) {
318
+ if (value) {
319
+ if (value > 300) {
320
+ return callback(new Error($lc('输入最大宽度不能大于300')))
321
+ } else if (!/^[1-9]\d*$/.test(value)) {
322
+ return callback(new Error($lc('表头宽度只能输入正整数')))
323
+ }
324
+ }
325
+ callback()
326
+ },
327
+ add() {
328
+ this.configVisibleN = true
329
+ this.configModelN.prop = `prop${Date.now()}`
330
+ },
331
+ configSaveN() {
332
+ if (!this.configModelN.label) {
333
+ return this.$message.warning($lc('请填写名称'))
334
+ }
335
+ const hasLabel = this.dragListN.find((item) => {
336
+ return item.label === this.configModelN.label
337
+ })
338
+ if (hasLabel) {
339
+ return this.$message.warning($lc('已有重名字段,请修改'))
340
+ }
341
+ this.dragList.unshift(this.configModelN)
342
+ // this.columns = [this.configModelN, ...this.columns]
343
+ this.$message.success($lc('添加成功'))
344
+ this.configVisibleN = false
345
+ this.configModelN = {
346
+ label: '',
347
+ prop: '',
348
+ width: 120,
349
+ isNew: true,
350
+ children: []
351
+ }
352
+ },
353
+ removeMenu(node, data) {
354
+ const parent = node.parent
355
+ const children = parent.data.children || parent.data
356
+ const index = children.findIndex((d) => d.prop === data.prop)
357
+ children.splice(index, 1)
358
+ },
359
+ allowDrop(draggingNode, dropNode, type) {
360
+ if (type === 'inner' && draggingNode.data.isNew) {
361
+ return !(draggingNode.level <= dropNode.level)
362
+ } else if (type === 'inner' && !draggingNode.data.isNew) {
363
+ return !(draggingNode.level <= dropNode.level && !dropNode.data.isNew)
364
+ } else {
365
+ return true
366
+ }
367
+ },
368
+ clickItem(item) {
369
+ this.configModel = item
370
+ this.configVisible = true
371
+ },
372
+ configSave() {
373
+ this.configVisible = false
374
+ },
375
+ popOpen() {
376
+ // 深拷贝一下,防止修改
377
+ this.dragList = JSON.parse(JSON.stringify(this.checkColumns)).filter((col) => !col.static)
378
+ },
379
+ setAll() {
380
+ if (this.setState) {
381
+ this.dragList = this.dragList.filter((c) => c.checked)
382
+ } else {
383
+ this.dragList = [...this.columnsAs]
384
+ }
385
+ },
386
+ checkChange(val, column) {
387
+ if (val === false) {
388
+ let index = this.dragList.findIndex((d) => d[this.labelKey] === column[this.labelKey])
389
+ index !== -1 && this.dragList.splice(index, 1)
390
+ } else {
391
+ let index = this.dragListN.findIndex((d) => d[this.labelKey] === column[this.labelKey])
392
+ if (index !== -1) {
393
+ Message.warning($lc(`子级请在右侧删除!`))
394
+ return false
395
+ }
396
+ this.dragList.push(column)
397
+ }
398
+ },
399
+ reset() {
400
+ let dragList = this.columns.filter((col) => col.isDefault)
401
+ this.dragList = dragList.length ? dragList : this.checkColumns.filter((col) => !col.static)
402
+ },
403
+ setChange() {
404
+ if (this.dragList.length < 1) {
405
+ this.$message.error(
406
+ `${$lc(`至少设置`)}${
407
+ this.isExport ? $lc('一列导出数据') : this.isFilter ? $lc('一个筛选条件') : $lc('一列显示列')
408
+ }!`
409
+ )
410
+ return
411
+ }
412
+
413
+ let list = []
414
+ let preCols = this.columns.filter((col) => col.static === 'pre')
415
+ let nextCols = this.columns.filter((col) => col.static === 'next')
416
+ list.push(...preCols, ...this.dragList, ...nextCols)
417
+ // 新增校验
418
+ if (!this.isExport) {
419
+ let state = list.findIndex((c) => c.isNew && c.children && c.children.length === 0)
420
+ if (state !== -1) {
421
+ Message.warning($lc(`新增字段必须包含子级!`))
422
+ return false
423
+ }
424
+ }
425
+ // 自动保存设置的显示列
426
+ this.userNo = sessionStorage.getItem('userNo')
427
+ !this.isExport && this.autoSave && this.saveColumns(list)
428
+ if (this.isExport) {
429
+ this.visible = false
430
+ this.$emit('setColumns', list)
431
+ }
432
+ },
433
+ saveColumns(list) {
434
+ let columns = saveTransform(list, this.labelKey, this.isFilter)
435
+ axios.post(
436
+ '/bems/prod_1.0/user/pageHabit',
437
+ {
438
+ userNo: this.userNo,
439
+ pageId: this.pageId,
440
+ showStructure: JSON.stringify(columns)
441
+ },
442
+ { loading: false }
443
+ ).then(() => {
444
+ this.getColumns(this.pageId).then(list => {
445
+ this.visible = false
446
+ this.$emit('setColumns', list)
447
+ })
448
+ })
449
+ },
450
+ getColumns(pageId) {
451
+ return getColumns(pageId || this.pageId, this.userNo, this.columns, this.labelKey)
452
+ }
453
+ }
454
+ }
455
+
456
+ function saveTransform(list, labelKey, isFilter) {
457
+ let listN = []
458
+ if (!isFilter) {
459
+ list.forEach((c) => {
460
+ if (c.prop && !c.children && !c.isNew && !c.width & !c.isNew) {
461
+ listN.push({ _colKey: 'prop', _colVal: c.prop })
462
+ } else if (c.slotName) {
463
+ listN.push({ _colKey: 'slotName', _colVal: c.slotName })
464
+ } else if (c.type && ['selection', 'index', 'expand'].includes(c.type)) {
465
+ listN.push({ _colKey: 'type', _colVal: c.type })
466
+ } else {
467
+ let sFn = false
468
+ for (let k in c) {
469
+ // if (typeof c[k] === 'function') sFn = true
470
+ }
471
+ if (sFn && c[labelKey]) {
472
+ listN.push({ _colKey: labelKey, _colVal: c[labelKey] })
473
+ } else {
474
+ listN.push(c)
475
+ }
476
+ }
477
+ })
478
+ } else {
479
+ list.forEach((c) => {
480
+ if (c.value) {
481
+ listN.push({ _colKey: 'value', _colVal: c.value })
482
+ } else if (c.startValue) {
483
+ listN.push({ _colKey: 'startValue', _colVal: c.startValue })
484
+ } else if (c.startDate) {
485
+ listN.push({ _colKey: 'startDate', _colVal: c.startDate })
486
+ } else if (c.slotName) {
487
+ listN.push({ _colKey: 'slotName', _colVal: c.slotName })
488
+ } else {
489
+ listN.push(c)
490
+ }
491
+ })
492
+ }
493
+ return listN
494
+ }
495
+
496
+ function getTransform(list, columnsT, labelKey = 'label') {
497
+ let columns = []
498
+
499
+ list.forEach((d) => {
500
+ // 如果list中的每一项是字符串
501
+ if (typeof d === 'string') {
502
+ // 从columnsT中找到label等于d的项
503
+ let column = columnsT.find((c) => c[labelKey] === d)
504
+ // 如果找到,则将其添加到columns中
505
+ column && columns.push(column)
506
+ // 如果list中的每一项是对象
507
+ } else if (typeof d === 'object') {
508
+ if (d.children) {
509
+ d.children.forEach((item, index) => {
510
+ let column = columnsT.find((c) => c.prop === d.children[index].prop)
511
+ // 如果找到,则将其添加到columns中
512
+ if (column.formatter) {
513
+ d.children[index].formatter = column.formatter
514
+ }
515
+ })
516
+ columns.push(d)
517
+ } else {
518
+ // 如果d中有_colKey属性
519
+ if (d._colKey) {
520
+ // 从columnsT中找到d._colKey等于d._colVal的项
521
+ let column = columnsT.find((c) => c[d._colKey] === d._colVal)
522
+ // 如果找到,则将其添加到columns中
523
+ column && columns.push(column)
524
+ // 如果d中没有_colKey属性
525
+ } else {
526
+ let column = columnsT.find((c) => c.prop === d.prop)
527
+ d.formatter = column.formatter
528
+ // 将d添加到columns中
529
+ columns.push(d)
530
+ }
531
+ }
532
+ }
533
+ })
534
+ console.log(columns)
535
+ // 返回columns
536
+ return columns
537
+ }
538
+
539
+ // 这段代码在筛选组件中复用
540
+ export function getColumns(pageId, userNo, columnsT, labelKey = 'label') {
541
+ return new Promise((resolve, reject) => {
542
+ axios
543
+ .post(
544
+ '/bems/prod_1.0/user/pageHabit/list',
545
+ {
546
+ userNo: userNo,
547
+ pageId: pageId
548
+ },
549
+ { loading: false }
550
+ )
551
+ .then(({ data }) => {
552
+ if (data) {
553
+ let _data = JSON.parse(data)
554
+ if (_data && _data.length > 0) {
555
+ let columns = getTransform(_data, columnsT, labelKey)
556
+ return resolve(columns)
557
+ }
558
+ }
559
+ return resolve(null)
560
+ })
561
+ .catch((err) => {
562
+ reject(err)
563
+ })
564
+ })
565
+ }
566
+ </script>
package/src/i18n.json CHANGED
@@ -1669,6 +1669,11 @@
1669
1669
  "th": "ดูแผนภาพกระบวนการ",
1670
1670
  "vi": "Xem biểu đồ luồng"
1671
1671
  },
1672
+ "查看详情": {
1673
+ "en": "View details",
1674
+ "th": "ดูรายละเอียด",
1675
+ "vi": "Xem chi tiết"
1676
+ },
1672
1677
  "请输入应用[": {
1673
1678
  "en": "Please enter an application [",
1674
1679
  "th": "โปรดป้อนแอปพลิเคชัน [",