sh-view 2.9.21 → 2.9.23

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.
Files changed (29) hide show
  1. package/package.json +5 -5
  2. package/packages/components/sh-calendar/index.vue +1 -1
  3. package/packages/components/sh-date/index.vue +2 -2
  4. package/packages/components/sh-form/query.vue +1 -1
  5. package/packages/components/sh-progress/index.vue +7 -3
  6. package/packages/components/sh-table/components/importModal.vue +5 -5
  7. package/packages/components/sh-table/css/index.scss +1 -1
  8. package/packages/components/sh-table/js/useTable.js +4 -4
  9. package/packages/components/sh-table/table.vue +3 -0
  10. package/packages/components/sh-tabs/index.vue +9 -3
  11. package/packages/components/sh-toolbar/index.vue +32 -71
  12. package/packages/components/sh-tree/components/table-tree.vue +30 -27
  13. package/packages/components/sh-tree/index.vue +1 -1
  14. package/packages/components/sh-upload/index.vue +3 -3
  15. package/packages/css/main.scss +32 -0
  16. package/packages/mixin/index.js +7 -51
  17. package/packages/other/sh-preview/components/sh-excel.vue +1 -0
  18. package/packages/other/sh-preview/components/sh-image.vue +19 -0
  19. package/packages/other/sh-preview/index.vue +17 -8
  20. package/packages/vxeTable/css/index.scss +13 -9
  21. package/packages/vxeTable/index.js +61 -2
  22. package/packages/vxeTable/render/cell/vxe-render-goption.vue +2 -3
  23. package/packages/vxeTable/render/cell/vxe-render-input.vue +19 -2
  24. package/packages/vxeTable/render/cell/vxe-render-money.vue +11 -3
  25. package/packages/vxeTable/render/cell/vxe-render-progress.vue +1 -1
  26. package/packages/vxeTable/render/cell/vxe-render-textarea.vue +1 -1
  27. package/packages/vxeTable/render/cell/vxe-render-time.vue +1 -1
  28. package/packages/vxeTable/render/globalRenders.jsx +7 -7
  29. package/packages/vxeTable/render/mixin/cell-hooks.js +8 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sh-view",
3
- "version": "2.9.21",
3
+ "version": "2.9.23",
4
4
  "description": "基于vxe-table二次封装,更包含Alert,Badge,Card,CodeEditor,Col,Corner,CountTo,Drawer,Empty,Form,Header,Icon,List,Loading,Modal,Noticebar,Poptip,Progress,PullRefresh,Query,Result,Row,Split,Grid,Table,Tabs,Tag,Toolbar,Tree,Upload,WaterFall,WaterMark等丰富组件库",
5
5
  "main": "packages/index.js",
6
6
  "typings": "types/index.d.ts",
@@ -28,9 +28,9 @@
28
28
  "babel-polyfill": "^6.26.0",
29
29
  "codemirror": "^6.0.2",
30
30
  "core-js": "^3.32.2",
31
- "countup.js": "^2.8.0",
31
+ "countup.js": "^2.9.0",
32
32
  "cron-parser": "^4.8.1",
33
- "docx-preview": "^0.1.18",
33
+ "docx-preview": "^0.1.20",
34
34
  "exceljs": "^4.4.0",
35
35
  "jspdf": "^3.0.4",
36
36
  "jszip": "^3.10.1",
@@ -40,8 +40,8 @@
40
40
  "vue": "^3.5.20",
41
41
  "vue-masonry": "^0.16.0",
42
42
  "vue-router": "^4.5.1",
43
- "vxe-pc-ui": "^4.9.6",
44
- "vxe-table": "^4.16.1"
43
+ "vxe-pc-ui": "^4.11.24",
44
+ "vxe-table": "^4.17.36"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@typescript-eslint/eslint-plugin": "^6.9.0",
@@ -431,7 +431,7 @@ export default defineComponent({
431
431
  break
432
432
  }
433
433
  } catch (e) {
434
- proxy.msgwarning(e.message)
434
+ proxy.$vMessage.warning(e.message)
435
435
  }
436
436
  }
437
437
  const emitValue = (value, evnt) => {
@@ -21,7 +21,7 @@
21
21
  </vxe-pulldown>
22
22
  </template>
23
23
  <template v-else>
24
- <vxe-input
24
+ <vxe-date-picker
25
25
  v-model="inputValue"
26
26
  v-bind="inputConfig"
27
27
  @input="dispatch('input', $event)"
@@ -38,7 +38,7 @@
38
38
  @suffix-click="dispatch('suffix-click', $event)"
39
39
  @date-prev="dispatch('date-prev', $event)"
40
40
  @date-today="dispatch('date-today', $event)"
41
- @date-next="dispatch('date-next', $event)"></vxe-input>
41
+ @date-next="dispatch('date-next', $event)"></vxe-date-picker>
42
42
  </template>
43
43
  </div>
44
44
  </template>
@@ -33,7 +33,7 @@ import useForm from './js/useForm'
33
33
  export default defineComponent({
34
34
  name: 'ShQuery',
35
35
  props: props,
36
- emits: ['submit', 'reset', 'edit-closed', 'submit-invalid', 'collapse', 'prefix-click', 'suffix-click'],
36
+ emits: ['submit', 'reset', 'edit-closed', 'submit-invalid', 'collapse', 'prefix-click', 'suffix-click', 'collapsed'],
37
37
  setup(props, context) {
38
38
  const { proxy } = getCurrentInstance()
39
39
  const useFormHooks = useForm(props, context, proxy)
@@ -31,6 +31,10 @@ export default defineComponent({
31
31
  type: Number,
32
32
  default: 0
33
33
  },
34
+ successAuto: {
35
+ type: Boolean,
36
+ default: true
37
+ },
34
38
  status: {
35
39
  type: String,
36
40
  default: 'normal' // normal', 'active', 'wrong', 'success'
@@ -97,11 +101,11 @@ export default defineComponent({
97
101
  if (isDown) {
98
102
  currentStatus.value = 'normal'
99
103
  emit('status-change', 'normal')
100
- } else {
101
- if (parseInt(props.percent, 10) === 100) {
104
+ } else if (parseInt(props.percent, 10) === 100) {
105
+ if (props.successAuto) {
102
106
  currentStatus.value = 'success'
103
- emit('status-change', 'success')
104
107
  }
108
+ emit('status-change', 'success')
105
109
  }
106
110
  }
107
111
 
@@ -136,13 +136,13 @@ export default defineComponent({
136
136
  const handleImportDataBtn = async (type = 'all') => {
137
137
  let importData = type === 'all' ? importTableData.value : shtable.value.getSelectionData()
138
138
  if (!importData || !Array.isArray(importData) || importData.length < 1) {
139
- proxy.msginfo('未导入数据')
139
+ proxy.$vMessage.info('未导入数据')
140
140
  return false
141
141
  }
142
142
  if (props.needValidate) {
143
143
  let validateErrMap = await handleImportDataValidate(importData)
144
144
  if (validateErrMap) {
145
- proxy.msgerror('导入校验失败,请检查数据')
145
+ proxy.$vMessage.error('导入校验失败,请检查数据')
146
146
  return validateErrMap
147
147
  }
148
148
  }
@@ -180,7 +180,7 @@ export default defineComponent({
180
180
  if (typeof props.downloadTemplateFinished === 'function') {
181
181
  props.downloadTemplateFinished(options)
182
182
  }
183
- proxy.msgsuccess('下载模板完成!')
183
+ proxy.$vMessage.success('下载模板完成!')
184
184
  }
185
185
  // 选择导入文件按钮
186
186
  const handleImportFileBtn = async () => {
@@ -201,9 +201,9 @@ export default defineComponent({
201
201
  if (typeof props.importFileFinished === 'function') {
202
202
  props.importFileFinished(options)
203
203
  }
204
- proxy.msgsuccess('导入完成!')
204
+ proxy.$vMessage.success('导入完成!')
205
205
  } catch (e) {
206
- proxy.msgerror(e.message || e)
206
+ proxy.$vMessage.error(e.message || e)
207
207
  }
208
208
  }
209
209
  // 读取文件
@@ -36,7 +36,7 @@
36
36
  left: 0;
37
37
  width: 100%;
38
38
  height: 100%;
39
- padding: 0.5em 1em;
39
+ padding: 8px;
40
40
  background-color: var(--bg-layout-color);
41
41
  }
42
42
  .sh-table-footer{
@@ -150,7 +150,7 @@ export default function (props, context, proxy, isGrid) {
150
150
  return Object.assign({ seqMethod: obj => seqMethod(obj, pagerConfig) }, props.seqConfig)
151
151
  })
152
152
  const tableMoneyConfig = computed(() => {
153
- return Object.assign({ style: { width: '60px' } }, $vTableSetup.moneyConfig, props.moneyConfig, tableVmConfig.value)
153
+ return Object.assign({ style: { width: '70px' } }, $vTableSetup.moneyConfig, props.moneyConfig, tableVmConfig.value)
154
154
  })
155
155
  const tableExportConfig = computed(() =>
156
156
  Object.assign(
@@ -582,7 +582,7 @@ export default function (props, context, proxy, isGrid) {
582
582
  // 自定义操作列点击事件
583
583
  const handleGoptionClick = async (btnObj, dataObj) => {
584
584
  if (btnObj.code === 'delete' || btnObj.idConfirm) {
585
- await proxy.msgconfirm({ content: btnObj.ConfirmContent || `确定${btnObj.content}吗?` })
585
+ await proxy.$vMessage.confirm({ content: btnObj.ConfirmContent || `确定${btnObj.content}吗?` })
586
586
  }
587
587
  emit('globaloption', btnObj, dataObj)
588
588
  }
@@ -611,11 +611,11 @@ export default function (props, context, proxy, isGrid) {
611
611
  if (isTool) {
612
612
  let selectedRows = getSelectionData()
613
613
  if (selectedRows.length < 1) {
614
- proxy.msgwarning('请选择要删除的行!')
614
+ proxy.$vMessage.warning('请选择要删除的行!')
615
615
  return
616
616
  }
617
617
  deleteRows = selectedRows
618
- await proxy.msgconfirm({ content: `确定删除吗?` })
618
+ await proxy.$vMessage.confirm({ content: `确定删除吗?` })
619
619
  } else if (typeof props.onToolbarBtnDeleteBefore === 'function') {
620
620
  let result = await props.onToolbarBtnDeleteBefore(deleteRows)
621
621
  if (!result) return
@@ -165,6 +165,9 @@ export default defineComponent({
165
165
  slotRefs.forEach(slotRef => {
166
166
  otherHeight += slotRef.value?.offsetHeight || 0
167
167
  })
168
+ if (useTableHooks.zoomStatus.value) {
169
+ otherHeight += 16
170
+ }
168
171
  tableHeight.value = parentHeight - otherHeight
169
172
  }
170
173
 
@@ -11,9 +11,9 @@
11
11
  <template v-for="(tab, tabIndex) in tabList" :key="tabIndex">
12
12
  <div v-bind="getTabItemBind(tab, tabIndex)" @click="handleChange(tab)">
13
13
  <slot name="tabItem" v-bind="{ ...tab, isActive: tab[labelKey] === activeKey }">
14
- <div v-if="tab.icon" class="sh-tab-icon"><sh-icon :type="tab.icon"></sh-icon></div>
14
+ <div v-if="tab.icon" class="sh-tab-icon"><sh-icon :type="tab.icon" :size="iconSize"></sh-icon></div>
15
15
  <div v-if="tab[labelField]" class="sh-tab-label">{{ tab[labelField] }}</div>
16
- <div v-if="getTabIsClosable(tab)" class="sh-tab-close" @click.stop="handleClose(tab)"><sh-icon type="ios-close"></sh-icon></div>
16
+ <div v-if="getTabIsClosable(tab)" class="sh-tab-close" @click.stop="handleClose(tab)"><sh-icon type="ios-close" :size="iconSize"></sh-icon></div>
17
17
  </slot>
18
18
  </div>
19
19
  </template>
@@ -108,6 +108,10 @@ export default defineComponent({
108
108
  const isHorizontal = computed(() => ['left', 'right'].includes(props.placement))
109
109
  const hasContent = computed(() => props.isContent && activeKey.value && props.options.map(item => item[props.labelKey]).includes(activeKey.value))
110
110
  const vmSize = computed(() => props.size || $vUiSetup.size)
111
+ const iconSize = computed(() => {
112
+ if (['small', 'mini'].includes(vmSize.value)) return 12
113
+ return 14
114
+ })
111
115
  const tabClass = computed(() => {
112
116
  return {
113
117
  'sh-tabs-card': props.type === 'card',
@@ -269,6 +273,7 @@ export default defineComponent({
269
273
  activeKey,
270
274
  hasContent,
271
275
  contentStyle,
276
+ iconSize,
272
277
  scrollPrev,
273
278
  scrollNext,
274
279
  handleScroll,
@@ -287,7 +292,7 @@ export default defineComponent({
287
292
  width: 100%;
288
293
  position: relative;
289
294
  display: flex;
290
- line-height: 2.3em;
295
+ line-height: 2.4em;
291
296
  &-size {
292
297
  &-medium {
293
298
  font-size: 1.25em;
@@ -303,6 +308,7 @@ export default defineComponent({
303
308
  display: inline-flex;
304
309
  align-items: center;
305
310
  font-size: 1.4em;
311
+ padding: 0 0.1em;
306
312
  &:hover {
307
313
  background-color: rgba(0, 0, 0, 0.1);
308
314
  }
@@ -2,14 +2,9 @@
2
2
  <div class="sh-vxe-toolbar">
3
3
  <div class="toolbar-left">
4
4
  <slot name="left"></slot>
5
- <template v-if="isTool">
6
- <template v-for="(toolBtn, toolBtnIndex) in toolBtns" :key="toolBtnIndex">
7
- <vxe-button :size="vmSize" v-bind="toolBtn" @click="handleToolBtn(toolBtn)"></vxe-button>
8
- </template>
9
- </template>
10
- <vxe-radio-group v-else v-model="leftActive" @change="handleLeftBtn">
5
+ <vxe-radio-group v-model="leftActive" @change="handleLeftBtn">
11
6
  <template v-for="(leftBtn, leftBtnIndex) in leftBtns" :key="leftBtnIndex">
12
- <vxe-radio-button :size="vmSize" v-bind="leftBtn" :label="leftBtn.value"></vxe-radio-button>
7
+ <vxe-radio-button :size="vmSize" v-bind="leftBtn" :label="leftBtn[leftKey]"></vxe-radio-button>
13
8
  </template>
14
9
  </vxe-radio-group>
15
10
  <slot name="leftr"></slot>
@@ -17,7 +12,7 @@
17
12
  <div class="toolbar-right">
18
13
  <slot name="rightl"></slot>
19
14
  <template v-for="(rightBtn, rightBtnIndex) in rightBtns" :key="rightBtnIndex">
20
- <vxe-button :size="vmSize" v-bind="rightBtn" @click="handleRightBtn(rightBtn)"></vxe-button>
15
+ <vxe-button :size="vmSize" :round="round" v-bind="rightBtn" @click="handleRightBtn(rightBtn)"></vxe-button>
21
16
  </template>
22
17
  <slot name="right"></slot>
23
18
  </div>
@@ -35,58 +30,30 @@ export default defineComponent({
35
30
  relation: {
36
31
  type: Boolean
37
32
  },
38
- leftContain: {
39
- type: Array,
40
- default() {
41
- return []
42
- }
33
+ round: {
34
+ type: Boolean
43
35
  },
44
- leftConfig: {
45
- type: Array,
46
- default() {
47
- return [
48
- { value: '1', code: 'wss', content: '未送审' },
49
- { value: '2', code: 'bth', content: '被退回' },
50
- { value: '3', code: 'yss', content: '已送审' },
51
- { value: '4', code: 'ygd', content: '已归档' },
52
- { value: '5', code: 'qb', content: '全部' },
53
- { value: '6', code: 'dsh', content: '待审核' },
54
- { value: '7', code: 'ysh', content: '已审核' }
55
- ]
56
- }
36
+ leftKey: {
37
+ String,
38
+ default: 'value'
57
39
  },
58
- rightConfig: {
40
+ leftContain: {
59
41
  type: Array,
60
42
  default() {
61
43
  return []
62
44
  }
63
45
  },
64
- isTool: {
65
- type: Boolean
46
+ leftConfig: {
47
+ type: Array
66
48
  },
67
- toolsContain: {
49
+ rightContain: {
68
50
  type: Array,
69
51
  default() {
70
52
  return []
71
53
  }
72
54
  },
73
- toolsConfig: {
74
- type: Array,
75
- default() {
76
- return [
77
- { code: 'add', content: '新增', status: 'primary', icon: 'vxe-icon-add' },
78
- { code: 'edit', content: '修改', status: 'warning', icon: 'vxe-icon-edit' },
79
- { code: 'delete', content: '删除', status: 'danger', icon: 'vxe-icon-delete' },
80
- { code: 'detail', content: '查看', status: '', icon: 'vxe-icon-information' },
81
- { code: 'export', content: '导出', status: 'success', icon: 'vxe-icon-download' },
82
- { code: 'import', content: '导入', status: 'primary', icon: 'vxe-icon-upload' },
83
- { code: 'print', content: '打印', status: 'warning', icon: 'vxe-icon-print' },
84
- { code: 'batch-add', content: '批量新增', status: 'primary', icon: 'vxe-icon-add' },
85
- { code: 'batch-edit', content: '批量修改', status: 'warning', icon: 'vxe-icon-edit' },
86
- { code: 'batch-delete', content: '批量删除', status: 'danger', icon: 'vxe-icon-delete' },
87
- { code: 'batch-detail', content: '查看', status: '', icon: 'vxe-icon-information' }
88
- ]
89
- }
55
+ rightConfig: {
56
+ type: Array
90
57
  },
91
58
  size: {
92
59
  type: String,
@@ -102,42 +69,35 @@ export default defineComponent({
102
69
  const leftActive = ref(props.modelValue)
103
70
 
104
71
  const vmSize = computed(() => props.size || $vUiSetup.size)
72
+ const leftConfigBtns = computed(() => props.leftConfig || $vUiSetup.toolbarLeftConfig)
73
+ const rightConfigBtns = computed(() => props.rightConfig || $vUiSetup.toolbarRightConfig)
105
74
  const leftBtns = computed(() => {
106
75
  let lBtns = []
107
- if (props.leftContain && Array.isArray(props.leftContain)) {
108
- lBtns = props.leftContain.map(item => props.leftConfig.find(btn => btn.code === item))
76
+ if (props.leftContain && Array.isArray(props.leftContain) && props.leftContain.length > 0) {
77
+ lBtns = props.leftContain.map(item => leftConfigBtns.value.find(btn => btn.code === item))
109
78
  }
110
- return lBtns
79
+ return lBtns.filter(item => !!item)
111
80
  })
112
81
  const rightBtns = computed(() => {
113
82
  let rBtns = []
114
- if (props.rightConfig && Array.isArray(props.rightConfig)) {
115
- rBtns = props.rightConfig
116
- }
117
- let leftCode = leftBtns.value.find(btn => btn.value === leftActive.value)
118
- if (props.relation && leftCode) {
119
- rBtns = rBtns.filter(item => item.code && item.code.split(',').includes(leftCode.code))
120
- }
121
- return rBtns
122
- })
123
- const toolBtns = computed(() => {
124
- let toolBtns = []
125
- if (props.toolsContain && Array.isArray(props.toolsContain)) {
126
- toolBtns = props.toolsContain.map(item => props.toolsConfig.find(btn => btn.code === item))
83
+ if (props.relation) {
84
+ let leftBtn = leftBtns.value.find(btn => btn.value === leftActive.value)
85
+ if (leftBtn) {
86
+ rBtns = (leftBtn.buttons || []).map(item => rightConfigBtns.value.find(btn => btn.code === item))
87
+ }
88
+ } else if (props.rightContain && Array.isArray(props.rightContain) && props.rightContain.length > 0) {
89
+ rBtns = props.rightContain.map(item => rightConfigBtns.value.find(btn => btn.code === item))
127
90
  }
128
- return toolBtns
91
+ return rBtns.filter(item => !!item)
129
92
  })
130
93
 
131
94
  const handleLeftBtn = ({ label }) => {
132
- let btnObj = props.leftConfig.find(item => item.value === label)
95
+ let btnObj = props.leftConfig.find(item => item[props.leftKey] === label)
133
96
  emitValue(btnObj)
134
97
  emit('left', label, btnObj)
135
98
  }
136
99
  const handleRightBtn = btn => {
137
- emit('right', btn.value, btn)
138
- }
139
- const handleToolBtn = btn => {
140
- emit('tool', btn)
100
+ emit('right', btn)
141
101
  }
142
102
  const emitValue = btnObj => {
143
103
  emit('input', leftActive.value, btnObj)
@@ -153,10 +113,9 @@ export default defineComponent({
153
113
 
154
114
  return {
155
115
  leftActive,
156
- toolBtns,
116
+ vmSize,
157
117
  leftBtns,
158
118
  rightBtns,
159
- handleToolBtn,
160
119
  handleLeftBtn,
161
120
  handleRightBtn
162
121
  }
@@ -175,6 +134,7 @@ export default defineComponent({
175
134
  width: 100%;
176
135
  .toolbar-left {
177
136
  flex: 1;
137
+ white-space: nowrap;
178
138
  .vxe-radio-button > input:checked + .vxe-radio--label {
179
139
  border-color: var(--primary-color);
180
140
  background: linear-gradient(-10deg, var(--primary-color), var(--primary-lighten-color));
@@ -183,6 +143,7 @@ export default defineComponent({
183
143
  .toolbar-right {
184
144
  flex: 0;
185
145
  white-space: nowrap;
146
+ margin-left: 20px;
186
147
  }
187
148
  }
188
149
  </style>
@@ -90,34 +90,36 @@ export default defineComponent({
90
90
  return Object.assign(resultConfig, tableProps.value)
91
91
  })
92
92
 
93
- const initSelection = () => {
94
- let { modelValue, multiple } = props
93
+ const initSelection = async isForce => {
94
+ let { modelValue, multiple, isSelect } = props
95
95
  let nodeKey = props.nodeKey || 'id'
96
- setTimeout(() => {
97
- if (!tableRef.value || !modelValue?.length) return
98
- let tableFullData = tableRef.value.getTableData().fullData
99
- let checkRows = []
100
- $vUtils.eachTree(tableFullData, item => {
101
- if (props.modelValue.includes(item[nodeKey])) {
102
- checkRows.push(item)
103
- }
104
- })
105
- // 找到第一个选中节点的所有父级,进行展开
106
- if (checkRows.length > 0) {
107
- let expendNode = checkRows[0]
108
- let checkParent = $vUtils.findTree(tableFullData, item => item[nodeKey] === expendNode[nodeKey])
109
- let parentNodes = checkParent.nodes.filter(item => item[nodeKey] !== expendNode[nodeKey])
110
- tableRef.value.setTreeExpand(parentNodes, true)
111
- if (multiple) {
112
- tableRef.value.setCheckboxRow(checkRows, true)
113
- } else {
114
- tableRef.value.setRadioRow(checkRows[0])
115
- }
96
+ if (!tableRef.value) return
97
+ if (!isForce && $vUtils.isEqual(modelValue, treeValue.value)) {
98
+ // 非强制更新,如果两次值相等,返回
99
+ return
100
+ }
101
+ let tableFullData = tableRef.value.getTableData().fullData
102
+ let checkRows = []
103
+ $vUtils.eachTree(tableFullData, item => {
104
+ if (props.modelValue.includes(item[nodeKey])) {
105
+ checkRows.push(item)
116
106
  }
117
- setTimeout(() => {
118
- tableRef.value.scrollToRow({ [nodeKey]: modelValue[0] })
119
- })
120
107
  })
108
+ // 找到第一个选中节点的所有父级,进行展开
109
+ if (checkRows.length > 0) {
110
+ let expendNode = checkRows[0]
111
+ let checkParent = $vUtils.findTree(tableFullData, item => item[nodeKey] === expendNode[nodeKey])
112
+ let parentNodes = checkParent.nodes.filter(item => item[nodeKey] !== expendNode[nodeKey])
113
+ await tableRef.value.setTreeExpand(parentNodes, true)
114
+ await tableRef.value.scrollToRow(checkRows[0])
115
+ if (multiple) {
116
+ await tableRef.value.setCheckboxRow(checkRows, true)
117
+ } else {
118
+ await tableRef.value.setRadioRow(checkRows[0])
119
+ }
120
+ } else {
121
+ await tableRef.value.clearAll()
122
+ }
121
123
  }
122
124
  // 单选框变化
123
125
  const onRadioChange = obj => {
@@ -198,13 +200,14 @@ export default defineComponent({
198
200
  })
199
201
  }
200
202
 
201
- const filterChangeDebounce = $vUtils.debounce(handleMyTableFilter, 500)
203
+ const initChangeDebounce = $vUtils.debounce(initSelection, 100)
204
+ const filterChangeDebounce = $vUtils.debounce(handleMyTableFilter, 300)
202
205
  const offetChangeDebounce = $vUtils.debounce(handleOffsetChange, tableConfigIn.value.resizeConfig?.refreshDelay || 100)
203
206
 
204
207
  watch(
205
208
  () => props.modelValue,
206
209
  () => {
207
- initSelection(true)
210
+ initChangeDebounce()
208
211
  }
209
212
  )
210
213
  watch(
@@ -194,7 +194,7 @@ export default defineComponent({
194
194
  // 初始化获取服务配置数据
195
195
  await getServerConfigDataSourse()
196
196
  if (tableTreeRef.value) {
197
- tableTreeRef.value.initSelection()
197
+ tableTreeRef.value.initSelection(true)
198
198
  }
199
199
  }
200
200
  // 树节点选择变换事件
@@ -367,18 +367,18 @@ export default defineComponent({
367
367
  const checked = fileFormat.value.some(item => item.toLocaleLowerCase() === _file_format)
368
368
  if (!checked) {
369
369
  let errorMsg = `格式不正确,请上传 ${fileFormat.value.join(' ')} 格式文件`
370
- props.onFormatError ? props.onFormatError(file, errorMsg, fileList.value) : proxy.msginfo(errorMsg)
370
+ props.onFormatError ? props.onFormatError(file, errorMsg, fileList.value) : proxy.$vMessage.info(errorMsg)
371
371
  return
372
372
  }
373
373
  }
374
374
  // check maxSize
375
375
  if (maxSize && file.size > maxSize * 1024) {
376
376
  let errorMsg = `文件大小不能超过 ${maxSize / 1024} M`
377
- props.onExceededSize ? props.onExceededSize(file, errorMsg, fileList.value) : proxy.msginfo(errorMsg)
377
+ props.onExceededSize ? props.onExceededSize(file, errorMsg, fileList.value) : proxy.$vMessage.info(errorMsg)
378
378
  return
379
379
  }
380
380
  if (!action) {
381
- proxy.msginfo('上传地址不能为空')
381
+ proxy.$vMessage.info('上传地址不能为空')
382
382
  return
383
383
  }
384
384
  return true
@@ -205,3 +205,35 @@ input[type="number"]{ -moz-appearance: textfield; }
205
205
  }
206
206
  }
207
207
 
208
+ // 全局通用提醒个性化样式
209
+ .sh-message-box{
210
+ &.type--confirm{
211
+ .vxe-modal--box{
212
+ }
213
+ }
214
+ &.status--success{
215
+ .vxe-modal--box{
216
+ background-color: #edfff3;
217
+ border-color: var(--success-color);
218
+ }
219
+ }
220
+ &.status--warning{
221
+ .vxe-modal--box{
222
+ background-color: #fff9e6;
223
+ border-color: var(--warning-color);
224
+ }
225
+ }
226
+ &.status--error{
227
+ .vxe-modal--box{
228
+ background-color: #ffefe6;
229
+ border-color: var(--danger-color);
230
+ }
231
+ }
232
+ &.status--info{
233
+ .vxe-modal--box{
234
+ background-color: #f0faff;
235
+ border-color: var(--info-color);
236
+ }
237
+ }
238
+ }
239
+
@@ -1,41 +1,5 @@
1
- const msgDefault = {
2
- title: '',
3
- className: 'globalMessageBox',
4
- draggable: false
5
- }
6
-
7
1
  const mixin = {
8
2
  methods: {
9
- // 全局msg提示方法
10
- msg(options) {
11
- return this.$vTable.modal.message(options)
12
- },
13
- msginfo(options) {
14
- let opts = Object.assign({}, msgDefault, typeof options === 'string' ? { content: options, status: 'info' } : options)
15
- return this.msg(opts)
16
- },
17
- msgsuccess(options) {
18
- let opts = Object.assign({}, msgDefault, typeof options === 'string' ? { content: options, status: 'success' } : options)
19
- return this.msg(opts)
20
- },
21
- msgwarning(options) {
22
- let opts = Object.assign({}, msgDefault, typeof options === 'string' ? { content: options, status: 'warning' } : options)
23
- return this.msg(opts)
24
- },
25
- msgerror(options) {
26
- let opts = Object.assign({}, msgDefault, typeof options === 'string' ? { content: options, status: 'error' } : options)
27
- return this.msg(opts)
28
- },
29
- msgconfirm(options) {
30
- return new Promise(async resolve => {
31
- let opts = Object.assign({}, typeof options === 'string' ? { content: options } : options)
32
- let type = await this.$vTable.modal.confirm({
33
- showHeader: Boolean(opts.title),
34
- ...opts
35
- })
36
- if (type === 'confirm') resolve(type)
37
- })
38
- },
39
3
  // 全局路由跳
40
4
  routerTo(route) {
41
5
  let { name, params, query } = {}
@@ -45,8 +9,11 @@ const mixin = {
45
9
  params = route.params
46
10
  query = route.query
47
11
  }
48
- if (name.indexOf('isTurnByHref_') > -1) {
49
- window.open(name.split('_')[1])
12
+ if (String(name).startsWith('http')) {
13
+ window.open(name)
14
+ return
15
+ } else if (String(name).startsWith('href:')) {
16
+ window.open(String(name).replace('href:', ''))
50
17
  return
51
18
  }
52
19
  try {
@@ -56,24 +23,13 @@ const mixin = {
56
23
  }
57
24
  },
58
25
  // 全局路由返回上一页
59
- routerback() {
60
- this.$router.back()
26
+ routerBack() {
27
+ return this.$router.back()
61
28
  },
62
29
  // 全局判断是否有子节点
63
30
  hasChildren(item, name = 'children') {
64
31
  return item && item[name] && Array.isArray(item[name]) && item[name].length > 0
65
32
  },
66
- // 全局格式化名称
67
- formatTitle(item) {
68
- let { title, __titleIsFunction__ } = item.meta || {}
69
- if (!title) return false
70
- if (this.$config.useI18n) {
71
- if (title.includes('{{') && title.includes('}}')) title = title.replace(/({{[\s\S]+?}})/, (m, str) => str.replace(/{{([\s\S]*)}}/, (m, _) => this.$t(_.trim())))
72
- else if (__titleIsFunction__) title = item.meta.title
73
- else title = this.$t(item.name)
74
- } else title = (item.meta && item.meta.title) || item.name
75
- return title
76
- },
77
33
  // 配置继承方法
78
34
  getExtendConfig(config = {}, name, module) {
79
35
  let moduleConfig = config[module] || config.default || {}
@@ -154,6 +154,7 @@ export default defineComponent({
154
154
  <style lang="scss">
155
155
  .sh-office-excel {
156
156
  position: relative;
157
+ height: 100%;
157
158
  .wolf-table-scrollbar {
158
159
  &.vertical {
159
160
  opacity: 1 !important;
@@ -0,0 +1,19 @@
1
+ <script>
2
+ import { defineComponent, computed, getCurrentInstance } from 'vue'
3
+ import dataProps from '../js/data-props'
4
+ export default defineComponent({
5
+ name: 'ShImage',
6
+ props: dataProps,
7
+ emits: ['rendered', 'error'],
8
+ setup(props, context) {
9
+ const { proxy } = getCurrentInstance()
10
+ return {}
11
+ }
12
+ })
13
+ </script>
14
+
15
+ <template>
16
+ <vxe-image ref="rootRef" :src="src" v-bind="options"></vxe-image>
17
+ </template>
18
+
19
+ <style lang="scss" scoped></style>
@@ -1,6 +1,6 @@
1
1
  <template>
2
- <div class="sh-preview">
3
- <component :is="componentName" v-bind="componentProps" :style="componentStyles" @rendered="onRendered" @error="onError" />
2
+ <div class="sh-preview" :style="styles">
3
+ <component :is="componentName" v-bind="componentProps" @rendered="onRendered" @error="onError" />
4
4
  </div>
5
5
  </template>
6
6
 
@@ -41,6 +41,8 @@ export default defineComponent({
41
41
  const componentName = computed(() => {
42
42
  if (!props.url || !previewType.value) {
43
43
  return 'div'
44
+ } else if (['jpg', 'jpeg', 'jpe', 'png', 'gif'].includes(previewType.value)) {
45
+ return defineAsyncComponent(() => import('./components/sh-image.vue'))
44
46
  } else if (['word', 'doc', 'docx'].includes(previewType.value)) {
45
47
  return defineAsyncComponent(() => import('./components/sh-word.vue'))
46
48
  } else if (['excel', 'xlsx'].includes(previewType.value)) {
@@ -51,19 +53,25 @@ export default defineComponent({
51
53
  const componentProps = computed(() => {
52
54
  let srcPrefix = props.base || ''
53
55
  let srcProps = {
54
- src: srcPrefix + props.url,
55
- frameborder: 0
56
+ src: srcPrefix + props.url
56
57
  }
57
58
  if (componentName.value === 'iframe') {
59
+ srcProps.frameborder = 0
60
+ srcProps.width = props.width
61
+ srcProps.height = props.height
58
62
  srcProps.src += '#scrollbars=0&toolbar=0&statusbar=0'
59
63
  }
60
64
  return srcProps
61
65
  })
62
- const componentStyles = computed(() => {
63
- return {
66
+ const styles = computed(() => {
67
+ let resultStyle = {
64
68
  width: props.width,
65
- height: props.height
69
+ maxWidth: '100%'
66
70
  }
71
+ if (componentName.value !== 'iframe') {
72
+ resultStyle.height = props.height
73
+ }
74
+ return resultStyle
67
75
  })
68
76
 
69
77
  const onRendered = data => {
@@ -74,9 +82,9 @@ export default defineComponent({
74
82
  }
75
83
 
76
84
  return {
85
+ styles,
77
86
  componentName,
78
87
  componentProps,
79
- componentStyles,
80
88
  onRendered,
81
89
  onError
82
90
  }
@@ -88,5 +96,6 @@ export default defineComponent({
88
96
  .sh-preview {
89
97
  position: relative;
90
98
  overflow: auto;
99
+ max-width: 100%;
91
100
  }
92
101
  </style>
@@ -94,6 +94,12 @@ button:focus, .vxe-button.type--button:not(.is--disabled):focus{
94
94
  .vxe-modal--wrapper{
95
95
  width: calc(100%);
96
96
  height: calc(100%);
97
+ .vxe-modal--box{
98
+ .vxe-modal--footer{
99
+ border-top: 1px solid var(--border-color);
100
+ padding: 0.6em;
101
+ }
102
+ }
97
103
  &.vxe-modal--preview{
98
104
  .vxe-modal--box{
99
105
  .vxe-modal--content{
@@ -102,20 +108,18 @@ button:focus, .vxe-button.type--button:not(.is--disabled):focus{
102
108
  }
103
109
  }
104
110
  &.type--modal {
105
- .vxe-modal--header{
106
- background-color: var(--primary-weak-color);
107
- }
108
- .vxe-modal--footer{
109
- border-top: 1px solid var(--border-color);
110
- padding-top: 0.5rem;
111
- padding-bottom: 0.5em;
111
+ .vxe-modal--box{
112
+ .vxe-modal--header{
113
+ background-color: var(--primary-weak-color);
114
+ }
112
115
  }
113
116
  }
114
117
  &.type--confirm {
115
118
  .vxe-modal--box{
116
- width: 320px;
119
+ width: 340px;
120
+ min-height: 130px;
121
+ max-width: 96%;
117
122
  .vxe-modal--body{
118
- padding: 10px;
119
123
  }
120
124
  }
121
125
  }
@@ -74,7 +74,40 @@ let uiOptions = {
74
74
  loading: {
75
75
  icon: 'vxe-icon-spinner roll',
76
76
  text: '加载中...'
77
- }
77
+ },
78
+ message: { title: '', className: 'sh-message-box', draggable: false },
79
+ toolbarLeftConfig: [
80
+ { value: '1', code: 'wss', content: '未送审' },
81
+ { value: '2', code: 'bth', content: '被退回' },
82
+ { value: '3', code: 'yss', content: '已送审' },
83
+ { value: '4', code: 'ygd', content: '已归档' },
84
+ { value: '5', code: 'qb', content: '全部' },
85
+ { value: '6', code: 'dsh', content: '待审核' },
86
+ { value: '7', code: 'ysh', content: '已审核' }
87
+ ],
88
+ toolbarRightConfig: [
89
+ { code: 'add', content: '新增', status: 'primary', icon: 'vxe-icon-add' },
90
+ { code: 'edit', content: '修改', status: 'warning', icon: 'vxe-icon-edit' },
91
+ { code: 'delete', content: '删除', status: 'danger', icon: 'vxe-icon-delete' },
92
+ { code: 'detail', content: '查看', status: '', icon: 'vxe-icon-information' },
93
+ { code: 'export', content: '导出', status: 'success', icon: 'vxe-icon-download' },
94
+ { code: 'import', content: '导入', status: 'primary', icon: 'vxe-icon-upload' },
95
+ { code: 'print', content: '打印', status: 'warning', icon: 'vxe-icon-print' },
96
+ { code: 'batch-add', content: '批量新增', status: 'primary', icon: 'vxe-icon-add' },
97
+ { code: 'batch-edit', content: '批量修改', status: 'warning', icon: 'vxe-icon-edit' },
98
+ { code: 'batch-delete', content: '批量删除', status: 'danger', icon: 'vxe-icon-delete' },
99
+ { code: 'batch-detail', content: '查看', status: '', icon: 'vxe-icon-information' },
100
+ { code: 'audit-push', content: '送审', status: 'success', icon: '' },
101
+ { code: 'audit-withdraw', content: '撤销', status: 'danger', icon: '' },
102
+ { code: 'audit-back', content: '退回', status: 'warning', icon: '' },
103
+ { code: 'audit-back-insert', content: '退回到录入', status: 'warning', icon: '' },
104
+ { code: 'audit-pass', content: '审核', status: 'success', icon: '' },
105
+ { code: 'batch-audit-push', content: '批量送审', status: 'success', icon: '' },
106
+ { code: 'batch-audit-withdraw', content: '批量撤销', status: 'danger', icon: '' },
107
+ { code: 'batch-audit-back', content: '批量退回', status: 'warning', icon: '' },
108
+ { code: 'batch-audit-back-insert', content: '批量退回到录入', status: 'warning', icon: '' },
109
+ { code: 'batch-audit-pass', content: '批量审核', status: 'success', icon: '' }
110
+ ]
78
111
  }
79
112
 
80
113
  let tableOptions = {
@@ -250,6 +283,30 @@ VXETable.renderer.mixin(publicRenders)
250
283
  VXETable.renderer.mixin(extraRenders)
251
284
  VXETable.renderer.mixin(filterRenders)
252
285
 
286
+ // 便捷化全局提示
287
+ const statusList = ['info', 'success', 'warning', 'error']
288
+ const vModal = VXEUI.modal
289
+ let vMessage = {
290
+ confirm: options => {
291
+ return new Promise(async resolve => {
292
+ let opts = Object.assign({}, uiOptions.message, typeof options === 'string' ? { content: options } : options)
293
+ let type = await vModal.confirm({ showHeader: Boolean(opts.title), ...opts })
294
+ if (type === 'confirm') resolve(type)
295
+ })
296
+ }
297
+ }
298
+ let vNotice = {}
299
+ statusList.forEach(status => {
300
+ vMessage[status] = options => {
301
+ let opts = Object.assign({ status }, uiOptions.message, typeof options === 'string' ? { content: options } : options)
302
+ return vModal.message(opts)
303
+ }
304
+ vNotice[status] = options => {
305
+ let opts = Object.assign({ status }, uiOptions.message, typeof options === 'string' ? { content: options } : options)
306
+ return vModal.notification(opts)
307
+ }
308
+ })
309
+
253
310
  const index = {
254
311
  install(Vue, { uiOption, tableOption, pdfOption, xlsxOption, menuOption, editorOption }) {
255
312
  let vuiOption = utils.merge(uiOptions, uiOption)
@@ -268,7 +325,9 @@ const index = {
268
325
  Vue.use(VXETable)
269
326
 
270
327
  Vue.config.globalProperties.$vUtils = utils
271
- Vue.config.globalProperties.$vModal = VXEUI.modal
328
+ Vue.config.globalProperties.$vModal = vModal
329
+ Vue.config.globalProperties.$vMessage = vMessage
330
+ Vue.config.globalProperties.$vNotice = vNotice
272
331
  Vue.config.globalProperties.$vUi = VXEUI
273
332
  Vue.config.globalProperties.$vTable = VXETable
274
333
  Vue.config.globalProperties.$vUiSetup = vuiOption
@@ -3,8 +3,7 @@
3
3
  <template v-for="renderBtn in renderBtns" :key="renderBtn.code">
4
4
  <vxe-button
5
5
  v-if="isBtnRender(renderBtn)"
6
- v-ripple
7
- :type="rprops.type"
6
+ :mode="rprops.type"
8
7
  :size="rsize"
9
8
  :icon="getBtnContent(renderBtn).icon"
10
9
  :status="getBtnContent(renderBtn).status"
@@ -47,7 +46,7 @@ export default defineComponent({
47
46
  const isBtnRender = renderBtn => {
48
47
  if ($vUtils.has(renderBtn, 'condition')) {
49
48
  let condition = $vUtils.get(renderBtn, 'condition')
50
- return $vUtils.calculate(condition, props.rdata)
49
+ return $vUtils.calculate(condition, useCell.rdata.value)
51
50
  }
52
51
  return true
53
52
  }
@@ -6,7 +6,15 @@
6
6
  <span v-else @click="vxeInputPrefixClick">{{ rprops.prefixText }}</span>
7
7
  </span>
8
8
  <span v-else-if="controlButton" class="control-btn before" @click="vxeControlClick(false)">-</span>
9
- <vxe-input v-model="renderValue" v-bind="rprops" :size="rsize" :immediate="false" @change="vxeInputChange" @input="vxeBlurCallback"></vxe-input>
9
+ <component
10
+ :is="inputComponent"
11
+ v-model="renderValue"
12
+ v-bind="rprops"
13
+ :size="rsize"
14
+ :immediate="false"
15
+ @change="vxeInputChange"
16
+ @blur="vxeBlurCallback"
17
+ @clear="vxeClearCallback"></component>
10
18
  <span v-if="rprops.suffixText && rform" class="suffix">
11
19
  <vxe-button v-if="suffixButton" v-bind="psButtonConfig" @click="vxeInputSuffixClick">{{ rprops.suffixText }}</vxe-button>
12
20
  <span v-else @click="vxeInputSuffixClick">{{ rprops.suffixText }}</span>
@@ -33,7 +41,14 @@ export default defineComponent({
33
41
  const { $vUtils } = proxy
34
42
  const useCell = cellHooks(props, context, proxy)
35
43
 
36
- const controlButton = computed(() => useCell.rprops.value.control && ['number', 'float', 'integer'].includes(useCell.rprops.value.type))
44
+ const isNumberInput = computed(() => ['number', 'float', 'integer'].includes(useCell.rprops.value.type))
45
+ const inputComponent = computed(() => {
46
+ if (isNumberInput.value) {
47
+ return 'vxe-number-input'
48
+ }
49
+ return 'vxe-input'
50
+ })
51
+ const controlButton = computed(() => useCell.rprops.value.control && isNumberInput.value)
37
52
 
38
53
  // 输入框数字加减控制
39
54
  const vxeControlClick = bol => {
@@ -45,6 +60,8 @@ export default defineComponent({
45
60
 
46
61
  return {
47
62
  ...useCell,
63
+ isNumberInput,
64
+ inputComponent,
48
65
  controlButton,
49
66
  vxeControlClick
50
67
  }
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <span class="vxe-render--inner" :class="{ 'form-render': rform, 'td-render': !rform, 'td-all': rprops.bill }">
3
3
  <template v-if="redit || isEditAll">
4
- <vxe-number-input v-model="renderText" v-bind="rprops" :size="rsize" :immediate="false" @change="vxeInputChange" @input="vxeMoneyCallback" />
4
+ <vxe-number-input v-model="renderText" v-bind="rprops" :size="rsize" :immediate="false" @change="vxeInputChange" @blur="vxeMoneyBlur" @clear="vxeMoneyClear" />
5
5
  </template>
6
6
  <template v-else-if="rprops.bill">
7
7
  <template v-for="(bil, bilindex) in billGroups" :key="bilindex">
@@ -34,15 +34,23 @@ export default defineComponent({
34
34
  return cellValue
35
35
  })
36
36
 
37
- const vxeMoneyCallback = async ({ value, $event }) => {
37
+ const vxeMoneyBlur = async ({ value, $event }) => {
38
38
  let cellValue = $vUtils.multiply(value, useCell.rprops.value.moneyUnit || 1)
39
39
  useCell.setRenderValue(cellValue)
40
40
  }
41
41
 
42
+ const vxeMoneyClear = async ({ value, $event }) => {
43
+ let cellValue = $vUtils.multiply(value, useCell.rprops.value.moneyUnit || 1)
44
+ setTimeout(() => {
45
+ useCell.setRenderValue(cellValue)
46
+ }, 50)
47
+ }
48
+
42
49
  return {
43
50
  ...useCell,
44
51
  cellFormatValue,
45
- vxeMoneyCallback
52
+ vxeMoneyBlur,
53
+ vxeMoneyClear
46
54
  }
47
55
  }
48
56
  })
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <template v-if="redit || isEditAll">
3
- <vxe-input v-model="renderValue" type="number" v-bind="rprops" :size="rsize" @change="vxeInputChange" @input="vxeBlurCallback" />
3
+ <vxe-input v-model="renderValue" type="number" v-bind="rprops" :size="rsize" :immediate="false" @change="vxeInputChange" @blur="vxeBlurCallback" @clear="vxeClearCallback" />
4
4
  </template>
5
5
  <template v-else>
6
6
  <sh-progress :percent="renderText" v-bind="rprops" />
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <template v-if="redit || isEditAll">
3
- <vxe-textarea v-model="renderValue" v-bind="rprops" :size="rsize" @change="vxeInputChange" @input="vxeBlurCallback" />
3
+ <vxe-textarea v-model="renderValue" v-bind="rprops" :size="rsize" :immediate="false" @change="vxeInputChange" @blur="vxeBlurCallback" @clear="vxeClearCallback" />
4
4
  </template>
5
5
  <template v-else>
6
6
  <span>{{ renderText }}</span>
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <template v-if="redit || isEditAll">
3
- <sh-date v-model="renderValue" v-bind="rprops" :size="rsize" :disabled-method="vxeDisabledMethod" @input="vxeChangeCallBack"></sh-date>
3
+ <sh-date v-model="renderValue" v-bind="rprops" :size="rsize" :disabled-method="vxeDisabledMethod" @change="vxeChangeCallBack" @clear="vxeChangeCallBack"></sh-date>
4
4
  </template>
5
5
  <template v-else>
6
6
  <span v-html="renderText"></span>
@@ -34,7 +34,7 @@ import vxeFilterComplex from './filters/vxe-filter-complex.vue'
34
34
  // 全局渲染器
35
35
  const publicRenders = {
36
36
  $vInput: {
37
- autofocus: '.td-render .vxe-input--inner',
37
+ autofocus: '.vxe-input--inner, .vxe-number-input--input',
38
38
  autoselect: true,
39
39
  renderCell(renderOpts, params) {
40
40
  return [<vxeRenderInput rparams={params} roptions={renderOpts} />]
@@ -50,7 +50,7 @@ const publicRenders = {
50
50
  }
51
51
  },
52
52
  $vTextArea: {
53
- autofocus: '.td-render .vxe-textarea--inner',
53
+ autofocus: '.vxe-textarea--inner',
54
54
  autoselect: true,
55
55
  renderCell(renderOpts, params) {
56
56
  return [<vxeRenderTextarea rparams={params} roptions={renderOpts} />]
@@ -63,7 +63,7 @@ const publicRenders = {
63
63
  }
64
64
  },
65
65
  $vSelect: {
66
- autofocus: '.td-render .vxe-input--inner',
66
+ autofocus: '.vxe-input--inner',
67
67
  autoselect: true,
68
68
  renderCell(renderOpts, params) {
69
69
  return [<vxeRenderSelect rparams={params} roptions={renderOpts} />]
@@ -76,7 +76,7 @@ const publicRenders = {
76
76
  }
77
77
  },
78
78
  $vTree: {
79
- autofocus: '.td-render .vxe-input--inner',
79
+ autofocus: '.vxe-input--inner',
80
80
  autoselect: true,
81
81
  renderCell(renderOpts, params) {
82
82
  return [<vxeRenderTree rparams={params} roptions={renderOpts} />]
@@ -89,7 +89,7 @@ const publicRenders = {
89
89
  }
90
90
  },
91
91
  $vTime: {
92
- autofocus: '.td-render .vxe-input--inner',
92
+ autofocus: '.vxe-date-picker--inner',
93
93
  autoselect: true,
94
94
  renderCell(renderOpts, params) {
95
95
  return [<vxeRenderTime rparams={params} roptions={renderOpts} />]
@@ -102,7 +102,7 @@ const publicRenders = {
102
102
  }
103
103
  },
104
104
  $vProgress: {
105
- autofocus: '.td-render .vxe-input--inner',
105
+ autofocus: '.vxe-input--inner',
106
106
  autoselect: true,
107
107
  renderCell(renderOpts, params) {
108
108
  return [<vxeRenderProgress rparams={params} roptions={renderOpts} />]
@@ -130,7 +130,7 @@ const publicRenders = {
130
130
  }
131
131
  },
132
132
  $vMoney: {
133
- autofocus: '.td-render .vxe-input--inner',
133
+ autofocus: '.vxe-number-input--input',
134
134
  autoselect: true,
135
135
  renderCell(renderOpts, params) {
136
136
  return [<vxeRenderMoney rparams={params} roptions={renderOpts} />]
@@ -1,4 +1,4 @@
1
- import { computed, ref, watch } from 'vue'
1
+ import { computed, ref, watch, nextTick } from 'vue'
2
2
 
3
3
  export default function (props, context, proxy) {
4
4
  const { $vUtils, $vTableSetup } = proxy
@@ -73,6 +73,12 @@ export default function (props, context, proxy) {
73
73
  const vxeBlurCallback = async ({ value, $event }) => {
74
74
  setRenderValue(value)
75
75
  }
76
+ // 输入框失去焦点回调
77
+ const vxeClearCallback = async ({ value, $event }) => {
78
+ setTimeout(() => {
79
+ setRenderValue(value)
80
+ }, 50)
81
+ }
76
82
  // 回调赋值
77
83
  const setRenderValue = value => {
78
84
  let cellValue = !$vUtils.isNone(value) ? value : renderValue.value
@@ -147,6 +153,7 @@ export default function (props, context, proxy) {
147
153
  vxeRadioCallBack,
148
154
  vxeCheckCallBack,
149
155
  vxeBlurCallback,
156
+ vxeClearCallback,
150
157
  getBillClass,
151
158
  getBillValue,
152
159
  setRenderValue