@xuekl/cli-components 1.8.0 → 1.9.145

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/XklButton.vue CHANGED
@@ -10,29 +10,30 @@ export default {
10
10
  </script>
11
11
  <script setup lang="ts">
12
12
  import { ElButton as RealElButton } from 'element-plus'
13
- import { componentGlobal } from '@xuekl/cli-base/global'
14
13
  import { isAuth } from '@/utils'
15
- import { useAttrs } from 'vue'
14
+ import { ref, useAttrs } from 'vue'
16
15
  import { ElMessageBox } from 'element-plus'
17
16
  import { useRoute } from 'vue-router'
18
-
19
- const props = defineProps(['auth', 'prevent', 'openType', 'name'])
20
- const emit = defineEmits(['async'])
21
- const route = useRoute()
17
+ const startLoading = window.startLoading
18
+ const finishLoading = window.finishLoading
19
+ const props = defineProps(['auth', 'prevent', 'openType', 'name', 'mask'])
20
+ const route: any = useRoute()
22
21
 
23
22
  const { auth, name } = props
24
23
 
24
+ const mask = typeof props.mask === 'undefined' ? true : props.mask
25
+
25
26
  const doAuth = (auth) => {
26
27
  if (name) {
27
- return isAuth(route.name + ':' + name)
28
+ return isAuth(route?.name + ':' + name)
28
29
  } else {
29
30
  return isAuth(auth)
30
31
  }
31
32
  }
32
33
 
33
34
 
34
- const attrs = useAttrs()
35
- let preventClick = false
35
+ const attrs: any = useAttrs()
36
+ const preventClick = ref(false)
36
37
 
37
38
  const btnClick = () => {
38
39
  if (attrs.click) {
@@ -41,20 +42,26 @@ const btnClick = () => {
41
42
  window[props.openType] && window[props.openType]()
42
43
  }
43
44
  }
44
- if (componentGlobal.enableSubmit) {
45
- preventClick = false
46
- componentGlobal.enableSubmit = false
47
- }
48
- if (!preventClick) {
49
- preventClick = true
50
- emit('async', () => {
51
- setTimeout(() => {
52
- preventClick = false;
53
- if (props.openType) {
54
- window[props.openType] && window[props.openType]()
55
- }
56
- }, 200)
57
- })
45
+
46
+ if (attrs.onAsync) {
47
+ if (!preventClick.value) {
48
+ preventClick.value = true
49
+ if (props.openType !== 'preventLoading' && startLoading) {
50
+ startLoading()
51
+ }
52
+ attrs.onAsync(() => {
53
+ setTimeout(() => {
54
+ preventClick.value = false;
55
+ if (finishLoading) {
56
+ finishLoading()
57
+ }
58
+ if (props.openType) {
59
+ window[props.openType] && window[props.openType]()
60
+ }
61
+ }, 200)
62
+ })
63
+ }
64
+
58
65
  }
59
66
 
60
67
  if (attrs.onConfirm) {
@@ -86,4 +93,24 @@ const btnClick = () => {
86
93
  }
87
94
  }
88
95
  }
89
- </script>
96
+ </script>
97
+
98
+ <style lang="scss" scoped>
99
+ .loading-mask {
100
+ position: absolute;
101
+ left: 0;
102
+ top: 0;
103
+ bottom: 0;
104
+ right: 0;
105
+ background-color: rgba(0, 0, 0, 0.6);
106
+ z-index: 1003;
107
+ display: flex;
108
+ align-items: center;
109
+ justify-content: center;
110
+
111
+ .is-loading {
112
+ font-size: 40px;
113
+ color: #fff;
114
+ }
115
+ }
116
+ </style>
package/XklDatePicker.vue CHANGED
@@ -1,6 +1,13 @@
1
1
  <template>
2
- <el-date-picker :type="type" :start-placeholder="startPlaceholder" :end-placeholder="endPlaceholder"
3
- :value-format="valueFormat" />
2
+ <div v-if="type === 'doubledatetime'" class="doubledatetime">
3
+ <el-date-picker type="datetime" v-model="startVal" placeholder="开始时间"
4
+ :value-format="valueFormat"></el-date-picker>
5
+ <el-date-picker type="datetime" v-model="endVal" placeholder="结束时间"
6
+ :value-format="valueFormat"></el-date-picker>
7
+ </div>
8
+ <el-date-picker v-else :type="type" v-model="modelVal" :start-placeholder="startPlaceholder"
9
+ :popper-class="func === 'bottomshortcut' ? 'bottomshortcut' : ''" :end-placeholder="endPlaceholder"
10
+ :value-format="valueFormat" :shortcuts="shortcuts" />
4
11
  </template>
5
12
  <script lang="ts">
6
13
  export default {
@@ -8,11 +15,39 @@ export default {
8
15
  }
9
16
  </script>
10
17
  <script setup lang="ts">
11
- import { ref } from 'vue';
18
+ import { ref, computed, Ref } from 'vue';
19
+ import moment from 'dayjs'
12
20
 
13
- const props = defineProps(['type'])
14
- const { type } = props
21
+ const props = defineProps(['type', 'func', 'modelValue'])
22
+ const emit = defineEmits(['update:modelValue'])
23
+ const { type, func } = props
15
24
 
25
+ const modelVal = computed({
26
+ get() {
27
+ return props.modelValue
28
+ },
29
+ set(val) {
30
+ emit('update:modelValue', val)
31
+ }
32
+ })
33
+
34
+ const startVal = computed({
35
+ get() {
36
+ return props.modelValue[0]
37
+ },
38
+ set(val) {
39
+ emit('update:modelValue', [val, props.modelValue[1]])
40
+ }
41
+ })
42
+
43
+ const endVal = computed({
44
+ get() {
45
+ return props.modelValue[1]
46
+ },
47
+ set(val) {
48
+ emit('update:modelValue', [props.modelValue[0], val])
49
+ }
50
+ })
16
51
 
17
52
  const startPlaceholder = ref('')
18
53
  const endPlaceholder = ref('')
@@ -27,7 +62,7 @@ if (type === 'daterange') {
27
62
 
28
63
  if (['date', 'dates', 'daterange'].includes(type)) {
29
64
  valueFormat.value = 'YYYY-MM-DD'
30
- } else if (['datetime', 'datetimerange'].includes(type)) {
65
+ } else if (['datetime', 'datetimerange', 'doubledatetime'].includes(type)) {
31
66
  valueFormat.value = 'YYYY-MM-DD HH:mm:ss'
32
67
  } else if (['month', 'monthrange'].includes(type)) {
33
68
  valueFormat.value = 'YYYY-MM'
@@ -35,4 +70,77 @@ if (['date', 'dates', 'daterange'].includes(type)) {
35
70
  valueFormat.value = ''
36
71
  }
37
72
 
38
- </script>
73
+ const shortcuts: Ref<any[]> = ref([])
74
+
75
+ if (func === 'bottomshortcut') {
76
+ shortcuts.value = [{
77
+ text: '此刻',
78
+ value: () => {
79
+ if (props.modelValue && props.modelValue.length) {
80
+ if (props.modelValue[0] > moment().format('YYYY-MM-DD HH:mm:ss')) {
81
+ modelVal.value = [moment().format('YYYY-MM-DD 00:00:00'), moment().format('YYYY-MM-DD HH:mm:ss')]
82
+ } else {
83
+ modelVal.value = [props.modelValue[0], moment().format('YYYY-MM-DD HH:mm:ss')]
84
+ }
85
+
86
+ } else {
87
+ modelVal.value = [moment().format('YYYY-MM-DD 00:00:00'), moment().format('YYYY-MM-DD HH:mm:ss')]
88
+ }
89
+ }
90
+ },
91
+ {
92
+ text: '今天',
93
+ value: () => {
94
+ modelVal.value = [moment().format('YYYY-MM-DD 00:00:00'), moment().format('YYYY-MM-DD 23:59:59')]
95
+ }
96
+ }]
97
+ }
98
+
99
+ </script>
100
+ <style lang="scss">
101
+ .doubledatetime {
102
+ display: flex;
103
+
104
+ box-shadow: 0 0 0 0.01rem var(--el-input-border-color, var(--el-border-color)) inset;
105
+ border-radius: var(--el-input-border-radius, var(--el-border-radius-base));
106
+ padding: 1px;
107
+
108
+ .el-input {
109
+ border: 0;
110
+
111
+ height: 0.3rem;
112
+
113
+ // .el-input__prefix {
114
+ // display: none;
115
+ // }
116
+
117
+ .el-input__wrapper {
118
+ box-shadow: none;
119
+ }
120
+ }
121
+ }
122
+
123
+ .bottomshortcut {
124
+ .el-picker-panel__sidebar {
125
+ z-index: 1;
126
+ bottom: -35px;
127
+ top: unset;
128
+ right: 150px;
129
+ display: flex;
130
+ justify-content: flex-end;
131
+ padding-top: 0;
132
+ }
133
+
134
+ .el-picker-panel__shortcut {
135
+ width: auto;
136
+ padding-right: 24px;
137
+ padding-left: 0;
138
+ font-size: 12px;
139
+ white-space: nowrap;
140
+ }
141
+
142
+ .el-picker-panel__body {
143
+ margin-left: 0;
144
+ }
145
+ }
146
+ </style>
package/XklDict.vue CHANGED
@@ -1,6 +1,13 @@
1
1
  <template>
2
- <el-select style="width: 100%;" @change="changeHandle">
3
- <el-option v-for="item in dataList" :key="item.dictValue" :label="item.dictLabel"
2
+ <div v-if="fakeRender && (!selectData || (selectData && !selectData.length))" class="fake-render el-input__wrapper"
3
+ :class="{ 'el-select__wrapper is-disabled': disabled || readonly }" @click="updateRender">
4
+ <span class="fs-14">{{ $attrs.placeholder
5
+ }}</span>
6
+ </div>
7
+ <el-select v-else style="width: 100%;" ref="XklDictRef" v-model="selectData" :automatic-dropdown="true"
8
+ :class="{ 'readony-input': readonly }" @change="changeHandle" :filterable="initFilterable"
9
+ :disabled="disabled || readonly" :filter-method="filterMethod">
10
+ <el-option v-for="item in list" :key="item.dictValue" :label="item.dictLabel"
4
11
  :value="item.dictValue"></el-option>
5
12
  </el-select>
6
13
  </template>
@@ -10,30 +17,108 @@ export default {
10
17
  }
11
18
  </script>
12
19
  <script setup lang="ts">
13
- import { ref, onBeforeMount, Ref } from 'vue'
14
- import http from "@/utils/httpRequest"
15
- import { baseConf } from './index'
16
- const props = defineProps(['config'])
17
- const emit = defineEmits(['update:label', 'loaded'])
18
-
19
- const { config } = props
20
- const dataList: Ref<{ dictCode: string, dictLabel: string, dictValue: string | number }[]> = ref([])
21
-
22
- const changeHandle = (val: string) => {
23
- const item = dataList.value.find(res => res.dictValue === val)
24
- if (item) {
25
- emit('update:label', item.dictLabel)
20
+ import { ref, onBeforeMount, Ref, computed, onBeforeUnmount } from 'vue'
21
+ import { baseConf, dictConf } from './index'
22
+ import DictStore from '@/utils/DictStore'
23
+ import { nextTick } from 'vue';
24
+ interface DictItem {
25
+ dictCode: string, dictLabel: string, dictValue: string | number
26
+ }
27
+ const props = defineProps(['config', 'filterable', 'readonly', 'disabled', 'modelValue', 'fake'])
28
+ const emit = defineEmits(['update:label', 'itemChange', 'loaded', 'update:modelValue'])
29
+
30
+ const { config, filterable, readonly, fake } = props
31
+ const list: Ref<DictItem[]> = ref([])
32
+
33
+ const isFake = typeof fake === 'undefined' ? true : fake
34
+ const fakeRender = ref(isFake)
35
+ const XklDictRef: any = ref(null)
36
+
37
+ const updateRender = () => {
38
+ fakeRender.value = false
39
+ nextTick(() => {
40
+ XklDictRef.value.focus()
41
+ })
42
+ }
43
+
44
+ const initFilterable = ref(false)
45
+
46
+ initFilterable.value = typeof filterable !== 'undefined' ? filterable : dictConf?.filterable
47
+
48
+ const disabled = computed(() => props.disabled)
49
+ let sourceData: DictItem[] = []
50
+
51
+ const selectData = computed({
52
+ get() {
53
+ return props.modelValue
54
+ },
55
+ set(val) {
56
+
57
+ emit('update:modelValue', val)
58
+ }
59
+ })
60
+
61
+ const filterMethod = (val: any) => {
62
+ if (val) {
63
+ val = val.trim()
64
+ list.value = sourceData.filter(res => res.dictValue.toString().includes(val) || res.dictLabel.includes(val))
65
+ } else {
66
+ list.value = sourceData
26
67
  }
27
68
  }
28
69
 
29
- onBeforeMount(() => {
30
- http({
31
- url: http.adornUrl(`${baseConf.dict_api_url}${config.dict}`),
32
- method: 'get',
33
- params: http.adornParams({})
34
- }).then(({ data }) => {
35
- dataList.value = data.data
36
- emit('loaded', dataList.value)
70
+ const changeHandle = (val: string | number | string[] | number[]) => {
71
+ if (Array.isArray(val)) {
72
+ const values: (string | number)[] = val
73
+ const items = sourceData.filter(res => values.includes(res.dictValue))
74
+ const labels = items.map(res => res.dictLabel)
75
+ if (items) {
76
+ emit('update:label', labels)
77
+ emit('itemChange', items)
78
+ }
79
+ } else {
80
+ const item = sourceData.find(res => res.dictValue === val)
81
+ if (item) {
82
+ emit('update:label', item.dictLabel)
83
+ emit('itemChange', item)
84
+ }
85
+ }
86
+ }
87
+
88
+ onBeforeMount(async () => {
89
+ list.value = await DictStore.getDict(config.dict)
90
+ sourceData = JSON.parse(JSON.stringify(list.value))
91
+ emit('loaded', list.value, (vals) => {
92
+ list.value = vals
93
+ sourceData = JSON.parse(JSON.stringify(list.value))
37
94
  })
38
95
  })
39
- </script>
96
+
97
+ onBeforeUnmount(() => {
98
+ list.value = []
99
+ sourceData = []
100
+ })
101
+ </script>
102
+ <style lang="scss">
103
+ .readony-input {
104
+ .is-disabled .el-input__wrapper {
105
+ background-color: #fff !important;
106
+
107
+ .el-input__inner {
108
+ color: #606266;
109
+ -webkit-text-fill-color: #606266;
110
+ }
111
+ }
112
+ }
113
+
114
+ .fake-render {
115
+ width: 100%;
116
+ justify-content: flex-start;
117
+ color: #a8abb2;
118
+ height: 32px;
119
+ }
120
+
121
+ .el-select__wrapper.is-disabled {
122
+ border: 1px solid #dcdfe6;
123
+ }
124
+ </style>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <real-el-dropdown-item v-if="doAuth(auth)">
2
+ <real-el-dropdown-item v-if="doAuth(auth)" @click.stop="btnClick">
3
3
  <slot></slot>
4
4
  </real-el-dropdown-item>
5
5
  </template>
@@ -9,14 +9,18 @@ export default {
9
9
  }
10
10
  </script>
11
11
  <script setup lang="ts">
12
- import { ElDropdownItem as RealElDropdownItem } from 'element-plus'
12
+ import { ElMessageBox, ElDropdownItem as RealElDropdownItem } from 'element-plus'
13
+ import { Loading } from "@element-plus/icons-vue";
14
+ import { useAttrs, ref } from 'vue'
13
15
  import { isAuth } from '@/utils'
14
16
  import { useRoute } from 'vue-router'
15
- const props = defineProps(['auth', 'name'])
16
- const route = useRoute()
17
+ const startLoading = window.startLoading
18
+ const finishLoading = window.finishLoading
19
+ const props = defineProps(['auth', 'prevent', 'openType', 'name', 'mask'])
20
+ const route: any = useRoute()
17
21
 
18
22
  const { auth, name } = props
19
-
23
+ const mask = typeof props.mask === 'undefined' ? true : props.mask
20
24
  const doAuth = (auth) => {
21
25
  if (name) {
22
26
  return isAuth(route.name + ':' + name)
@@ -24,4 +28,84 @@ const doAuth = (auth) => {
24
28
  return isAuth(auth)
25
29
  }
26
30
  }
27
- </script>
31
+
32
+ const attrs: any = useAttrs()
33
+ const preventClick = ref(false)
34
+
35
+ const btnClick = () => {
36
+ if (attrs.click) {
37
+ attrs.onClick()
38
+ if (props.openType) {
39
+ window[props.openType] && window[props.openType]()
40
+ }
41
+ }
42
+
43
+ if (attrs.onAsync) {
44
+ if (!preventClick.value) {
45
+ preventClick.value = true
46
+ if (props.openType !== 'preventLoading' && startLoading) {
47
+ startLoading()
48
+ }
49
+ attrs.onAsync(() => {
50
+ setTimeout(() => {
51
+ preventClick.value = false;
52
+ if (finishLoading) {
53
+ finishLoading()
54
+ }
55
+ if (props.openType) {
56
+ window[props.openType] && window[props.openType]()
57
+ }
58
+ }, 200)
59
+ })
60
+ }
61
+ }
62
+
63
+ if (attrs.onConfirm) {
64
+ if (props.prevent === false) {
65
+ attrs.onConfirm()
66
+ if (props.openType) {
67
+ window[props.openType] && window[props.openType]()
68
+ }
69
+ } else {
70
+ ElMessageBox.confirm(
71
+ '当前内容可能存在修改,确认继续?',
72
+ '提示',
73
+ {
74
+ confirmButtonText: '确认',
75
+ cancelButtonText: '取消',
76
+ type: 'warning',
77
+ }
78
+ ).then(() => {
79
+ attrs.onConfirm()
80
+ if (props.openType) {
81
+ window[props.openType] && window[props.openType]()
82
+ }
83
+ }).catch(() => {
84
+ })
85
+ }
86
+ } else {
87
+ if (props.openType) {
88
+ window[props.openType] && window[props.openType]()
89
+ }
90
+ }
91
+ }
92
+ </script>
93
+ <style lang="scss" scoped>
94
+ .loading-mask {
95
+ position: absolute;
96
+ left: 0;
97
+ top: 0;
98
+ bottom: 0;
99
+ right: 0;
100
+ background-color: rgba(0, 0, 0, 0.6);
101
+ z-index: 1003;
102
+ display: flex;
103
+ align-items: center;
104
+ justify-content: center;
105
+
106
+ .is-loading {
107
+ font-size: 40px;
108
+ color: #fff;
109
+ }
110
+ }
111
+ </style>