vue2-client 1.8.263 → 1.8.265

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": "vue2-client",
3
- "version": "1.8.263",
3
+ "version": "1.8.265",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint",
@@ -1,5 +1,6 @@
1
1
  <template>
2
2
  <div>
3
+ <p v-if="config.page.length === 0"> 未选中任何工作空间 </p>
3
4
  <a-tree
4
5
  v-if="showTree"
5
6
  defaultExpandAll
@@ -16,11 +17,14 @@
16
17
  <span>{{ title }}</span>
17
18
  <template #overlay>
18
19
  <a-menu @click="({ key: menuKey }) => onContextMenuClick(treeKey, menuKey)">
19
- <a-menu-item key="copy">复制</a-menu-item>
20
- <a-menu-item key="paste" :disabled="copyCache === undefined">粘贴</a-menu-item>
21
- <a-menu-item key="split" :disabled="determineLevel(treeKey) !== 'item'">拆分</a-menu-item>
22
- <a-menu-item key="rename" :disabled="treeKey.length > 2 && treeKey.length <= 5">重命名</a-menu-item>
23
- <a-menu-item key="delete">删除</a-menu-item>
20
+ <a-menu-item key="copy"><a-icon type="copy" />&nbsp;&nbsp;复制</a-menu-item>
21
+ <a-menu-item key="paste" :disabled="copyCache === undefined"><a-icon type="snippets" />&nbsp;&nbsp;粘贴</a-menu-item>
22
+ <a-menu-divider />
23
+ <a-menu-item key="split" :disabled="determineLevel(treeKey) !== 'item'"><a-icon type="fullscreen" />&nbsp;&nbsp;拆分</a-menu-item>
24
+ <a-menu-item key="add" :disabled="determineLevel(treeKey) === 'item'"><a-icon type="plus-square" />&nbsp;&nbsp;添加</a-menu-item>
25
+ <a-menu-item key="rename" :disabled="treeKey.length > 2 && treeKey.length <= 5"><a-icon type="italic" />&nbsp;&nbsp;重命名</a-menu-item>
26
+ <a-menu-divider />
27
+ <a-menu-item key="delete"><a-icon type="delete" />&nbsp;&nbsp;删除</a-menu-item>
24
28
  </a-menu>
25
29
  </template>
26
30
  </a-dropdown>
@@ -28,7 +32,7 @@
28
32
  <!-- 树中的图标 -->
29
33
  <a-icon slot="file" type="file" />
30
34
  <a-icon slot="appstore" type="appstore" />
31
- <a-icon slot="layout" type="layout" />
35
+ <a-icon slot="pause" type="pause" />
32
36
  <a-icon slot="ordered-list" type="ordered-list" />
33
37
  </a-tree>
34
38
  <!-- 页面容器重命名弹框 -->
@@ -93,6 +97,29 @@ export default {
93
97
  return treeKey
94
98
  }
95
99
  },
100
+ determineDragLevel (id) {
101
+ if (id.startsWith('page')) {
102
+ return {
103
+ type: 'page',
104
+ level: 0
105
+ }
106
+ } else if (id.startsWith('container_page_')) {
107
+ return {
108
+ type: 'container_page',
109
+ level: 2
110
+ }
111
+ } else if (id.startsWith('row')) {
112
+ return {
113
+ type: 'row',
114
+ level: 1
115
+ }
116
+ } else {
117
+ return {
118
+ type: 'item',
119
+ level: 2
120
+ }
121
+ }
122
+ },
96
123
  // 树拖拽事件
97
124
  treeDrop (info) {
98
125
  // 拖拽结束目标的id
@@ -103,15 +130,9 @@ export default {
103
130
  const dropPos = info.node.pos.split('-')
104
131
 
105
132
  // 拖拽结束目标的类型
106
- const dropLevel = this.determineLevel(dropKey)
133
+ const dropLevel = this.determineDragLevel(dropKey)
107
134
  // 被拖拽的类型
108
- const dragLevel = this.determineLevel(dragKey)
109
-
110
- // 移动页面容器没有意义
111
- if (dragLevel === 'page') {
112
- this.$message.error('该移动不合法!')
113
- return
114
- }
135
+ const dragLevel = this.determineDragLevel(dragKey)
115
136
 
116
137
  // 拖拽对于目标的定位,-1表示之前,0表示插入,1表示之后
117
138
  const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1])
@@ -122,34 +143,34 @@ export default {
122
143
  // 3. 高级组件移动到低级
123
144
  // 4. 相差2级移动
124
145
  // 唯一特例,行可以插入容器页面,容器页面等于模块级别,但可以被行插入
125
- if (dragLevel === 'row') {
126
- if (dropLevel === 'page' && dropPosition !== 0) {
127
- this.$message.error('该移动不合法!')
128
- return
129
- }
130
- if (dropLevel === 'row' && dropPosition === 0) {
131
- this.$message.error('该移动不合法!')
132
- return
133
- }
134
- if (dropLevel === 'item') {
135
- this.$message.error('该移动不合法!')
136
- return
137
- }
138
- } else if (dragLevel === 'item') {
139
- if (dropLevel === 'page') {
140
- this.$message.error('该移动不合法!')
141
- return
142
- }
143
- if (dropLevel === 'row' && dropPosition !== 0) {
144
- this.$message.error('该移动不合法!')
145
- return
146
- }
147
- if (dropLevel === 'item' && dropPosition === 0) {
148
- this.$message.error('该移动不合法!')
149
- return
150
- }
146
+
147
+ // 只有三种情况可以拖拽
148
+ // 1.平级挪
149
+ // 2.高一级插
150
+ // 3.行插子页面
151
+
152
+ // 1. 平级挪
153
+ if (dropLevel.level === dragLevel.level && dropPosition !== 0) {
154
+ const dragType = 'move'
155
+ this.$emit('componentMove', this.getOriginalKey(dragKey), this.getOriginalKey(dropKey), dragLevel, dropLevel, dropPosition, dragType)
156
+ return
151
157
  }
152
- this.$emit('componentMove', dragKey, dropKey, dropLevel, dropPosition)
158
+
159
+ // 2.高一级插
160
+ if (dropLevel.level === (dragLevel.level - 1) && dropPosition === 0) {
161
+ const dragType = 'higher'
162
+ this.$emit('componentMove', this.getOriginalKey(dragKey), this.getOriginalKey(dropKey), dragLevel, dropLevel, dropPosition, dragType)
163
+ return
164
+ }
165
+
166
+ // 3.行插子页面
167
+ if (dragLevel.type === 'row' && dropLevel.type === 'container_page' && dropPosition === 0) {
168
+ const dragType = 'rowToContainer'
169
+ this.$emit('componentMove', this.getOriginalKey(dragKey), this.getOriginalKey(dropKey), dragLevel, dropLevel, dropPosition, dragType)
170
+ return
171
+ }
172
+ // 能到这不return的证明都是非法移动
173
+ this.$message.error('不合法的拖拽!')
153
174
  },
154
175
  handleDelete (targetType, originalKey) {
155
176
  const _this = this
@@ -283,6 +304,13 @@ export default {
283
304
  },
284
305
  })
285
306
  },
307
+ handleAdd (targetType, originalKey) {
308
+ if (targetType === 'page' || targetType === 'container_page') {
309
+ this.$emit('add', originalKey, 'row')
310
+ } else if (targetType === 'row') {
311
+ this.$emit('add', originalKey, 'container')
312
+ }
313
+ },
286
314
  // 树右键事件
287
315
  onContextMenuClick (treeKey, menuKey) {
288
316
  // 判断目标类型
@@ -304,12 +332,15 @@ export default {
304
332
  return
305
333
  case 'split':
306
334
  this.handleSplit(originalKey)
335
+ return
336
+ case 'add':
337
+ this.handleAdd(targetType, originalKey)
307
338
  }
308
339
  },
309
340
  // 处理架构树点击事件
310
341
  handleTreeSelect (value) {
311
342
  this.selectedKeys = value
312
- this.$emit('treeOrganizationClick', value[0])
343
+ this.$emit('treeOrganizationClick', this.getOriginalKey(value[0]))
313
344
  // 如果选中的id只有两位证明是页面容器
314
345
  // let isPage = false
315
346
  // if (value[0].length === 2) {
@@ -354,8 +385,8 @@ export default {
354
385
  icon = 'file'
355
386
  key = 'page_' + page.id
356
387
  } else {
357
- title = '容器页面_' + page.id.split('_')[2]
358
- icon = 'layout'
388
+ title = '列容器'
389
+ icon = 'pause'
359
390
  key = 'container_page_' + page.id
360
391
  }
361
392
  result.push({
@@ -370,7 +401,7 @@ export default {
370
401
  for (let j = 0; j < page.body.length; j++) {
371
402
  const row = page.body[j]
372
403
  result[i].children.push({
373
- title: j + 1 + '行',
404
+ title: '行容器' + (j + 1),
374
405
  key: 'row_' + page.id + '_' + (j + 1),
375
406
  children: [],
376
407
  slots: {
@@ -482,7 +482,23 @@ export default {
482
482
  })
483
483
  },
484
484
  twink (id) {
485
-
485
+ const frame = 400
486
+ this.$refs[id][0].className = 'colWithBorder'
487
+ setTimeout(() => {
488
+ this.$refs[id][0].className = ''
489
+ }, frame)
490
+ setTimeout(() => {
491
+ this.$refs[id][0].className = 'colWithBorder'
492
+ }, frame * 2)
493
+ setTimeout(() => {
494
+ this.$refs[id][0].className = ''
495
+ }, frame * 3)
496
+ setTimeout(() => {
497
+ this.$refs[id][0].className = 'colWithBorder'
498
+ }, frame * 4)
499
+ setTimeout(() => {
500
+ this.$refs[id][0].className = ''
501
+ }, frame * 5)
486
502
  }
487
503
  },
488
504
  watch: {
@@ -502,9 +518,11 @@ export default {
502
518
  }
503
519
  .componentInEditor:hover{
504
520
  border: 2px rgb( 24,144,255) solid;
521
+ box-shadow: 3px 3px 5px 1px rgba(0,0,0,0.2);
505
522
  }
506
523
  .colWithBorder{
507
524
  border: 2px rgb( 24,144,255) solid;
525
+ box-shadow: 3px 3px 5px 1px rgba(0,0,0,0.2);
508
526
  }
509
527
  .container{
510
528
  display: flex;
@@ -44,7 +44,7 @@
44
44
  <script>
45
45
 
46
46
  import { mapState } from 'vuex'
47
- import { fileDelete, upload } from '@vue2-client/services/api/common'
47
+ import { fileDelete, fileDeleteV4, upload } from '@vue2-client/services/api/common'
48
48
 
49
49
  export default {
50
50
  name: 'Uploads',
@@ -93,7 +93,8 @@ export default {
93
93
  }
94
94
  },
95
95
  computed: {
96
- ...mapState('account', { currUser: 'user' })
96
+ ...mapState('account', { currUser: 'user' }),
97
+ ...mapState('setting', ['compatible'])
97
98
  },
98
99
  created () {
99
100
  const list = this.model.type === 'file' ? [...this.files] : [...this.images]
@@ -184,19 +185,41 @@ export default {
184
185
  },
185
186
  // 删除文件
186
187
  deleteFileItem (file) {
187
- if (file.id) {
188
- fileDelete({ id: file.id, f_state: '删除' })
189
- .then(res => {}).catch(e => { })
190
- }
191
- // 找到当前文件所在列表的索引
192
- const index = this.uploadedFileList.indexOf(file)
193
- // 从列表中移除该文件
194
- this.uploadedFileList.splice(index, 1)
195
- if (this.outerContainerIndex !== undefined) {
196
- this.$emit('setFiles', this.uploadedFileList.filter(item => item.status === 'done'), this.outerContainerIndex)
197
- } else {
198
- this.$emit('setFiles', this.uploadedFileList.filter(item => item.status === 'done').map(item => item.id))
199
- }
188
+ const that = this
189
+ this.$confirm({
190
+ title: '提醒',
191
+ content: '确定删除该文件吗?',
192
+ okText: '删除',
193
+ okType: 'danger',
194
+ cancelText: '取消',
195
+ onOk () {
196
+ // 阳春博能工单信息V4页面有时会删除V3照片, V3照片不能通过这个请求删除, 已经在外层进行删除处理
197
+ if (file.id && !file.version) {
198
+ switch (that.compatible) {
199
+ case 'V3':
200
+ fileDelete({ id: file.id, f_state: '删除' })
201
+ .then(res => {}).catch(e => { })
202
+ break
203
+ case 'V4':
204
+ fileDeleteV4({ id: file.id, resDeleteMode: 'server' })
205
+ .then(res => {}).catch(e => { })
206
+ break
207
+ }
208
+ }
209
+ // 找到当前文件所在列表的索引
210
+ const index = that.uploadedFileList.indexOf(file)
211
+ // 从列表中移除该文件
212
+ that.uploadedFileList.splice(index, 1)
213
+ if (that.outerContainerIndex !== undefined) {
214
+ that.$emit('setFiles', that.uploadedFileList.filter(item => item.status === 'done'), that.outerContainerIndex)
215
+ } else {
216
+ that.$emit('setFiles', that.uploadedFileList.filter(item => item.status === 'done').map(item => item.id))
217
+ }
218
+ },
219
+ onCancel () {
220
+ console.log('取消删除')
221
+ },
222
+ })
200
223
  return true
201
224
  }
202
225
  }
@@ -88,6 +88,7 @@ import { addOrModify, getConfigByName, runLogic } from '@vue2-client/services/ap
88
88
  import lowcodeComponentMixin from '@vue2-client/utils/lowcode/lowcodeComponentMixin'
89
89
  import { _IDre15, _IDRe18, REG_EMAIL, REG_LANDLINE, REG_PHONE } from '@vue2-client/utils/reg'
90
90
  import moment from 'moment/moment'
91
+ import executeStrFunction from '@vue2-client/utils/runEvalFunction'
91
92
 
92
93
  export default {
93
94
  name: 'XAddNativeForm',
@@ -306,7 +307,7 @@ export default {
306
307
  if (!formData[item.model]) {
307
308
  formData[item.model] = undefined
308
309
  }
309
- if (!formData[item.model] && !item.formDefault) {
310
+ if (!formData[item.model] && item.formDefault) {
310
311
  if (['datePicker', 'rangePicker', 'yearPicker', 'monthPicker'].includes(item.type)) {
311
312
  formData[item.model] = this.getDateRange(item.type, item.formDefault)
312
313
  } else {
@@ -467,9 +468,68 @@ export default {
467
468
  })
468
469
  break
469
470
  }
471
+ // 大于0
472
+ case 'greaterThanZero': {
473
+ this.rules[item.model].push({
474
+ validator: (rule, value, callback) => {
475
+ if (isNaN(value) || value <= 0) {
476
+ callback(new Error('请输入一个大于0的数字'))
477
+ } else {
478
+ callback()
479
+ }
480
+ },
481
+ trigger: 'blur'
482
+ })
483
+ break
484
+ }
485
+ // 大于等于0
486
+ case 'greaterThanOrEqualZero': {
487
+ this.rules[item.model].push({
488
+ validator: (rule, value, callback) => {
489
+ if (isNaN(value) || value < 0) {
490
+ callback(new Error('请输入一个大于等于0的数字'))
491
+ } else {
492
+ callback()
493
+ }
494
+ },
495
+ trigger: 'blur'
496
+ })
497
+ break
498
+ }
499
+ case 'stringLength': {
500
+ this.rules[item.model].push({
501
+ validator: (rule, value, callback) => {
502
+ if (value && value.length < item.rule.minLen) {
503
+ callback(new Error('长度不能少于' + item.rule.minLen + '个字符'))
504
+ } else if (value && value.length > item.rule.maxLen) {
505
+ callback(new Error('长度不能超过' + item.rule.maxLen + '个字符'))
506
+ } else {
507
+ callback()
508
+ }
509
+ },
510
+ trigger: 'blur'
511
+ })
512
+ break
513
+ }
514
+ case 'customJs': {
515
+ this.rules[item.model].push({
516
+ validator: (rule, value, callback) => {
517
+ this.customJsValidate(rule, value, callback, item)
518
+ },
519
+ trigger: 'blur'
520
+ })
521
+ break
522
+ }
470
523
  }
471
524
  }
472
525
  },
526
+ customJsValidate (rule, value, callback, item) {
527
+ if (item.rule.customValidatorFunc) {
528
+ executeStrFunction(item.rule.customValidatorFunc, [rule, value, callback, this.form, item, this.util])
529
+ } else {
530
+ callback()
531
+ }
532
+ },
473
533
  itemDisabled (value) {
474
534
  return (this.businessType === '新增' && value.addOrEdit === 'edit') ||
475
535
  (this.businessType === '修改' && value.addOrEdit === 'add')
@@ -1,31 +1,31 @@
1
- export const XDescriptionsConfig = {
2
- type: 'XDescriptions',
3
- properties: {
4
- title: {
5
- type: 'string',
6
- label: '标题',
7
- desc: '用于组件中标题位置显示内容'
8
- },
9
- content: {
10
- type: 'object',
11
- label: '数据',
12
- desc: '该组件展示的数据'
13
- },
14
- configName: {
15
- type: 'string',
16
- label: '配置名',
17
- desc: '该组件对应琉璃中的配置'
18
- },
19
- serviceName: {
20
- type: 'string',
21
- label: '命名空间',
22
- desc: '该组件对应琉璃中配置的命名空间'
23
- },
24
- getRealData: {
25
- type: 'boolean',
26
- label: '格式化数据key',
27
- desc: '该组件是否调用格式化数据的key,以获取真实的数据'
28
- }
29
- },
30
- selfEvent: []
31
- }
1
+ export const XDescriptionsConfig = {
2
+ type: 'XDescriptions',
3
+ properties: {
4
+ title: {
5
+ type: 'string',
6
+ label: '标题',
7
+ desc: '用于组件中标题位置显示内容'
8
+ },
9
+ content: {
10
+ type: 'object',
11
+ label: '数据',
12
+ desc: '该组件展示的数据'
13
+ },
14
+ configName: {
15
+ type: 'string',
16
+ label: '配置名',
17
+ desc: '该组件对应琉璃中的配置'
18
+ },
19
+ serviceName: {
20
+ type: 'string',
21
+ label: '命名空间',
22
+ desc: '该组件对应琉璃中配置的命名空间'
23
+ },
24
+ getRealData: {
25
+ type: 'boolean',
26
+ label: '格式化数据key',
27
+ desc: '该组件是否调用格式化数据的key,以获取真实的数据'
28
+ }
29
+ },
30
+ selfEvent: []
31
+ }
@@ -1,48 +1,48 @@
1
- # XReportSlot 暂时废弃
2
-
3
-
4
- 动态报表的插槽组件,可以递归使用
5
-
6
-
7
- ## 何时使用
8
-
9
- > 当需要一个动态生成的报表时
10
-
11
- > 一般由XReportDesign嵌套使用,在XReportDesign中判断当前行如果类型是slot,
12
- > 则递归此组件
13
-
14
- 引用方式:
15
-
16
- ```javascript
17
- import XReportSlot from '@vue2-client/base-client/components/XReportSlot/XReportSlot'
18
-
19
- export default {
20
- components: {
21
- XReportSlot
22
- }
23
- }
24
- ```
25
-
26
-
27
- ## API
28
-
29
- | 参数 | 说明 | 类型 | 默认值 |
30
- |-----------------|--------------------------|--------|------|
31
- | config | 表格完整配置 | Object | 无(必填) |
32
- | forDisplay | 是否为展示页 | Boolean | false |
33
- | slotConfigName | 插槽名 | String | undefined |
34
-
35
- ## 例子1
36
- ----
37
- ```vue
38
- <XReportSlot
39
- :config="activatedConfig"
40
- :slot-config-name="slotConfig"
41
- :for-display="forDisplay">
42
- </XReportSlot>
43
- ```
44
- ## 注意事项
45
- > slotConfigName如果不填,则展示整个表格。
46
- > 如果填写,则仅展示插槽中的内容
47
-
48
- > 该组件可以递归调用
1
+ # XReportSlot 暂时废弃
2
+
3
+
4
+ 动态报表的插槽组件,可以递归使用
5
+
6
+
7
+ ## 何时使用
8
+
9
+ > 当需要一个动态生成的报表时
10
+
11
+ > 一般由XReportDesign嵌套使用,在XReportDesign中判断当前行如果类型是slot,
12
+ > 则递归此组件
13
+
14
+ 引用方式:
15
+
16
+ ```javascript
17
+ import XReportSlot from '@vue2-client/base-client/components/XReportSlot/XReportSlot'
18
+
19
+ export default {
20
+ components: {
21
+ XReportSlot
22
+ }
23
+ }
24
+ ```
25
+
26
+
27
+ ## API
28
+
29
+ | 参数 | 说明 | 类型 | 默认值 |
30
+ |-----------------|--------------------------|--------|------|
31
+ | config | 表格完整配置 | Object | 无(必填) |
32
+ | forDisplay | 是否为展示页 | Boolean | false |
33
+ | slotConfigName | 插槽名 | String | undefined |
34
+
35
+ ## 例子1
36
+ ----
37
+ ```vue
38
+ <XReportSlot
39
+ :config="activatedConfig"
40
+ :slot-config-name="slotConfig"
41
+ :for-display="forDisplay">
42
+ </XReportSlot>
43
+ ```
44
+ ## 注意事项
45
+ > slotConfigName如果不填,则展示整个表格。
46
+ > 如果填写,则仅展示插槽中的内容
47
+
48
+ > 该组件可以递归调用