@xmszm/core 0.0.1

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 (45) hide show
  1. package/dist/index.cjs +2 -0
  2. package/dist/index.mjs +2145 -0
  3. package/dist/style.css +1 -0
  4. package/docs/components/dataform.md +61 -0
  5. package/docs/components/datatable.md +77 -0
  6. package/docs/components/dialog.md +78 -0
  7. package/docs/components/options.md +55 -0
  8. package/docs/components/query.md +49 -0
  9. package/docs/components/utils.md +56 -0
  10. package/docs/guide/demo.md +213 -0
  11. package/docs/guide/quickstart.md +77 -0
  12. package/docs/index.md +25 -0
  13. package/docs/usage.md +61 -0
  14. package/examples/demo.vue +224 -0
  15. package/package.json +64 -0
  16. package/src/dialog/commonDialog.jsx +230 -0
  17. package/src/dialog/style/commonDialog.less +40 -0
  18. package/src/dialog/utils/dialog.js +82 -0
  19. package/src/enum/options.js +3 -0
  20. package/src/enum/sort.jsx +31 -0
  21. package/src/form/DataForm.vue +125 -0
  22. package/src/image/ImagesUpload.vue +268 -0
  23. package/src/image/SvgIcon.vue +30 -0
  24. package/src/index.js +46 -0
  25. package/src/list/useList.jsx +99 -0
  26. package/src/options/Options.jsx +338 -0
  27. package/src/options/defaultOptions.jsx +580 -0
  28. package/src/options/options.md +77 -0
  29. package/src/plugin/vite/initRouteMeta.js +54 -0
  30. package/src/query/CommonQuery.vue +272 -0
  31. package/src/store/utils/index.js +6 -0
  32. package/src/table/DataTable.vue +315 -0
  33. package/src/table/FilterDialog.vue +157 -0
  34. package/src/table/opr/DataColumnCollet.jsx +127 -0
  35. package/src/table/opr/useDataColumn.jsx +196 -0
  36. package/src/table/opr/useDataColumnButton.jsx +56 -0
  37. package/src/table/opr/useDataColumnPop.jsx +57 -0
  38. package/src/table/test.md +248 -0
  39. package/src/table/utils/ellipsis.js +22 -0
  40. package/src/utils/array.js +26 -0
  41. package/src/utils/auth.js +118 -0
  42. package/src/utils/object.js +32 -0
  43. package/src/utils/time.js +7 -0
  44. package/src/utils/upload.js +46 -0
  45. package/types/index.d.ts +67 -0
@@ -0,0 +1,157 @@
1
+ <script setup>
2
+ import { useThemeVars } from 'naive-ui'
3
+ import { ref, watchEffect } from 'vue'
4
+
5
+ const props = defineProps({
6
+ type: {
7
+ type: String,
8
+ default: () => 'primary',
9
+ },
10
+ filterItem: {
11
+ type: Array,
12
+ default: () => [],
13
+ },
14
+ selectItem: {
15
+ type: Array,
16
+ default: () => [],
17
+ },
18
+ defaultItem: {
19
+ type: Array,
20
+ default: () => [],
21
+ },
22
+ filterButtonKey: {
23
+ type: Array,
24
+ default: () => ['all', 'selectDefault'],
25
+ // default: () => ['all', 'selectDefault','currentSelect']
26
+ },
27
+ })
28
+ const emit = defineEmits(['submit'])
29
+ const theme = useThemeVars()
30
+ const keySelect = ref([])
31
+
32
+ watchEffect(() => {
33
+ keySelect.value = props.selectItem
34
+ })
35
+ const filterButton = ref([])
36
+ const filterOprButton = [
37
+ {
38
+ key: 'all',
39
+ label: '全选',
40
+ onCheck: () => (keySelect.value = props.filterItem?.map(v => v.key)),
41
+ unCheck: () => (keySelect.value = []),
42
+ },
43
+ {
44
+ key: 'selectDefault',
45
+ label: '选中默认',
46
+ onCheck: () => (keySelect.value = props.defaultItem),
47
+ unCheck: () => (keySelect.value = props.selectItem),
48
+ },
49
+ {
50
+ key: 'currentSelect',
51
+ label: '选中当前列表',
52
+ onCheck: () => (keySelect.value = props.selectItem),
53
+ unCheck: () => (keySelect.value = props.selectItem),
54
+ },
55
+ ]
56
+ watchEffect(() => {
57
+ filterButton.value = filterOprButton.filter(v =>
58
+ props.filterButtonKey.includes(v.key),
59
+ )
60
+ console.log(props.filterButtonKey)
61
+ })
62
+
63
+ function onSubmit() {
64
+ emit('submit', keySelect.value)
65
+ }
66
+
67
+ const checkKey = ref(
68
+ props.filterItem?.length === props.selectItem?.length ? ['all'] : [],
69
+ )
70
+
71
+ function onCheckModel(string, meta) {
72
+ console.log(string)
73
+ console.log(meta)
74
+ if (meta.actionType === 'uncheck') {
75
+ filterButton.value?.find(v => v?.key === meta.value)?.unCheck()
76
+ checkKey.value = []
77
+ }
78
+ else {
79
+ filterButton.value?.find(v => v?.key === meta.value)?.onCheck()
80
+ checkKey.value = [meta.value]
81
+ }
82
+ }
83
+ </script>
84
+
85
+ <template>
86
+ <div class="filter-box">
87
+ <n-checkbox-group v-model:value="keySelect" class="filter-main">
88
+ <n-checkbox
89
+ v-for="item in filterItem"
90
+ :key="item.key"
91
+ :value="item.key"
92
+ class="filter-item"
93
+ >
94
+ <n-ellipsis style="max-width: 100px">
95
+ {{ item.title }}
96
+ </n-ellipsis>
97
+ </n-checkbox>
98
+ </n-checkbox-group>
99
+ <div class="filter-footer">
100
+ <n-checkbox-group
101
+ :type="props.type"
102
+ :value="checkKey"
103
+ @update:value="onCheckModel"
104
+ >
105
+ <n-checkbox
106
+ v-for="item in filterButton"
107
+ :key="item.key"
108
+ :value="item.key"
109
+ >
110
+ {{ item.label }}
111
+ </n-checkbox>
112
+ </n-checkbox-group>
113
+ <n-button class="submit-btn" :type="props.type" @click="onSubmit">
114
+ 保存
115
+ </n-button>
116
+ </div>
117
+ </div>
118
+ </template>
119
+
120
+ <style scoped lang="less">
121
+ .filter-box {
122
+ padding: 20px;
123
+ margin: -16px -28px -20px;
124
+ box-sizing: border-box;
125
+ }
126
+
127
+ .filter-main {
128
+ display: flex;
129
+ align-content: flex-start;
130
+ flex-wrap: wrap;
131
+ min-height: 500px;
132
+ max-height: 700px;
133
+ overflow-y: auto;
134
+ row-gap: 20px;
135
+ padding: 0 0 15px;
136
+ box-sizing: border-box;
137
+
138
+ .filter-item {
139
+ --info-color: v-bind(theme.infoColor);
140
+ --n-border-checked: 1px solid var(--info-color) !important;
141
+ --n-border-focus: 1px solid var(--info-color) !important;
142
+ --n-color-checked: var(--info-color) !important;
143
+ --n-box-shadow-focus: 0 0 0 2px #6a1f7403 !important;
144
+ width: calc(100% / 3);
145
+ }
146
+ }
147
+
148
+ .filter-footer {
149
+ display: flex;
150
+ justify-content: space-between;
151
+ align-items: center;
152
+
153
+ .submit-btn {
154
+ width: 80px;
155
+ }
156
+ }
157
+ </style>
@@ -0,0 +1,127 @@
1
+ import { NButton, NPopover, NSpace } from 'naive-ui'
2
+ import { computed, defineComponent, ref } from 'vue'
3
+
4
+ import { rowIndexKey } from './useDataColumn'
5
+ import OprButton from './useDataColumnButton'
6
+ import Pop from './useDataColumnPop'
7
+
8
+ export default defineComponent(
9
+ (props) => {
10
+ const leng = props.options.length
11
+
12
+ const toggle = ref(false)
13
+ const options = computed(() =>
14
+ props.options.slice(0, toggle.value ? leng : props.max),
15
+ )
16
+
17
+ const ellipOptions = computed(() => props.options.slice(props.max))
18
+
19
+ function renderOptions(op) {
20
+ return op
21
+ ?.map(
22
+ (
23
+ {
24
+ isRender = () => true,
25
+ onClick = null,
26
+ mode = null,
27
+ disabled = false,
28
+ type = 'primary',
29
+ ...action
30
+ },
31
+ i,
32
+ ) => {
33
+ return isRender?.(props.data)
34
+ ? (
35
+ mode === 'pop'
36
+ ? (
37
+ <Pop
38
+ onClick={onClick}
39
+ row={props.data}
40
+ action={action}
41
+ key={rowIndexKey(props.data, props.index) + i}
42
+ >
43
+ <NButton
44
+ text
45
+ disabled={disabled && disabled(props.data)}
46
+ type={disabled && disabled(props.data) ? 'default' : type}
47
+ {...action}
48
+ >
49
+ {typeof action?.label === 'function'
50
+ ? action?.label(props.data)
51
+ : action?.label}
52
+ </NButton>
53
+ </Pop>
54
+ )
55
+ : (
56
+ <OprButton
57
+ row={props.data}
58
+ action={{
59
+ ...action,
60
+ disabled,
61
+ onClick,
62
+ type,
63
+ }}
64
+ key={rowIndexKey(props.data, props.index) + i}
65
+ />
66
+ )
67
+ )
68
+ : undefined
69
+ },
70
+ )
71
+ .filter(v => v)
72
+ }
73
+
74
+ return () => (
75
+ <NSpace
76
+ style={{ width: '100%' }}
77
+ wrap-item={false}
78
+ justify="center"
79
+ align="center"
80
+ >
81
+ <NSpace wrap-item={false} align="center">
82
+ {renderOptions(options.value)}
83
+ </NSpace>
84
+ <NPopover trigger="click">
85
+ {{
86
+ trigger: () => (
87
+ <NButton text type="info">
88
+ 更多
89
+ </NButton>
90
+ ),
91
+ default: () => (
92
+ <NSpace
93
+ wrap-item={false}
94
+ align="center"
95
+ style={{ width: '250px', padding: '5px' }}
96
+ >
97
+ {renderOptions(ellipOptions.value)}
98
+ </NSpace>
99
+ ),
100
+ }}
101
+ </NPopover>
102
+ </NSpace>
103
+ )
104
+ },
105
+ {
106
+ name: 'DataColumnCollet',
107
+
108
+ props: {
109
+ options: {
110
+ type: Array,
111
+ default: () => [],
112
+ },
113
+ max: {
114
+ type: Number,
115
+ default: 3,
116
+ },
117
+ data: {
118
+ type: Object,
119
+ default: () => {},
120
+ },
121
+ index: {
122
+ type: Number,
123
+ default: 0,
124
+ },
125
+ },
126
+ },
127
+ )
@@ -0,0 +1,196 @@
1
+ import { hasPermission } from '@/utils/permission'
2
+ import { NButton, NImage, NSpace, NSpin } from 'naive-ui'
3
+ import { ref } from 'vue'
4
+ import DataColumnCollet from './DataColumnCollet.jsx'
5
+ import OprButton from './useDataColumnButton.jsx'
6
+ import Pop from './useDataColumnPop.jsx'
7
+
8
+ export const rowIndexKey = (row, index) => (row ? JSON.stringify(row) : index)
9
+
10
+ export function createActionColumnJsx(
11
+ defaultOption,
12
+ oprParams = null,
13
+ collectParams,
14
+ ) {
15
+ // 粗滤计算操作栏占用宽度
16
+ // 粗滤计算操作栏占用宽度
17
+ const defaultCollectParams = {
18
+ max: 4,
19
+ width: 80,
20
+ }
21
+ let collect = false
22
+ if (typeof collectParams === 'boolean')
23
+ collect = defaultCollectParams
24
+ else if (typeof collectParams === 'object')
25
+ collect = { ...defaultCollectParams, ...collectParams }
26
+
27
+ console.log('collect', collect)
28
+ console.log(Array.isArray(defaultOption))
29
+ if (!Array.isArray(defaultOption)) {
30
+ throw new TypeError('需要配置数组')
31
+ }
32
+ console.log('ddd')
33
+ let actions = []
34
+ let width = 0
35
+ const filterAction = []
36
+ const isLoading = false
37
+
38
+ if (Array.isArray(defaultOption)) {
39
+ actions = defaultOption
40
+ actions.forEach((itm, idx) => {
41
+ if (itm.permission) {
42
+ if (hasPermission(itm.permission)) {
43
+ if (!collectParams || idx < collect.max)
44
+ width += itm?.label?.length * 12 + 36
45
+
46
+ filterAction.push(itm)
47
+ }
48
+ }
49
+ else {
50
+ if (!collectParams || idx < collect.max)
51
+ width += itm?.label?.length * 12 + 36
52
+ filterAction.push(itm)
53
+ }
54
+ })
55
+
56
+ // for (const item of actions) {
57
+ // if (!isLoading && item?.loading) isLoading = true
58
+ // if (item.permission && item?.label) {
59
+ // if (hasPermission(item.permission)) {
60
+ // width += item?.label?.length * 12 + 36
61
+ // filterAction.push(item)
62
+ // }
63
+ // } else if (item?.label) {
64
+ // width += item?.label?.length * 12 + 36
65
+ // filterAction.push(item)
66
+ // }
67
+ // }
68
+ }
69
+
70
+ width = Math.max(80, width)
71
+ // return filterAction.length
72
+ // ?
73
+ width += isLoading ? 20 : 0
74
+
75
+ if (collect)
76
+ width += 2
77
+
78
+ return filterAction.length
79
+ ? {
80
+ title: '操作',
81
+ key: 'opr',
82
+ fixed: 'right',
83
+ align: 'left',
84
+ width,
85
+ ...oprParams,
86
+ render(row, index) {
87
+ const vNodes = collect
88
+ ? (
89
+ <DataColumnCollet
90
+ data={row}
91
+ index={index}
92
+ max={collect.max}
93
+ options={filterAction}
94
+ />
95
+ )
96
+ : (
97
+ filterAction
98
+ .map(
99
+ (
100
+ {
101
+ isRender = () => true,
102
+ onClick = null,
103
+ mode = null,
104
+ disabled = false,
105
+ type = 'primary',
106
+ ...action
107
+ },
108
+ i,
109
+ ) => {
110
+ return isRender?.(row)
111
+ ? (
112
+ mode === 'pop'
113
+ ? (
114
+ <Pop
115
+ onClick={onClick}
116
+ row={row}
117
+ index={index}
118
+ action={action}
119
+ key={rowIndexKey(row, index) + i}
120
+ >
121
+ <NButton
122
+ text
123
+ disabled={disabled && disabled(row)}
124
+ type={disabled && disabled(row) ? 'default' : type}
125
+ {...action}
126
+ >
127
+ {typeof action?.label === 'function'
128
+ ? action?.label(row)
129
+ : action?.label}
130
+ </NButton>
131
+ </Pop>
132
+ )
133
+ : (
134
+ <OprButton
135
+ row={row}
136
+ action={{
137
+ ...action,
138
+ disabled,
139
+ onClick,
140
+ type,
141
+ }}
142
+ index={index}
143
+ key={rowIndexKey(row, index) + i}
144
+ />
145
+ )
146
+ )
147
+ : undefined
148
+ },
149
+ )
150
+ .filter(v => v)
151
+ )
152
+ return oprParams?.isRender
153
+ ? (
154
+ oprParams?.render(row)
155
+ )
156
+ : (
157
+ <NSpace
158
+ align="center"
159
+ wrap-item={false}
160
+ size={18}
161
+ key={rowIndexKey(row, index)}
162
+ >
163
+ {vNodes}
164
+ </NSpace>
165
+ )
166
+ },
167
+ }
168
+ : undefined
169
+ }
170
+
171
+ export async function createQRCode(row, fn = null) {
172
+ const code = ref(null)
173
+ const loading = ref(false)
174
+ $dialog.info({
175
+ showIcon: false,
176
+ style: {
177
+ width: '350px',
178
+ height: '350px',
179
+ },
180
+ content: () => (
181
+ <div className="qr-box">
182
+ {loading.value ? <NSpin class="qr-spin" show /> : ''}
183
+ <div className="qr-img">
184
+ <NImage src={code.value} style={{ width: '100%' }} />
185
+ </div>
186
+ <div className="qr-title">{loading.value ? '' : row.name}</div>
187
+ </div>
188
+ ),
189
+ })
190
+ if (fn) {
191
+ loading.value = true
192
+ code.value = await fn()
193
+ loading.value = false
194
+ }
195
+ return true
196
+ }
@@ -0,0 +1,56 @@
1
+ import { NButton } from 'naive-ui'
2
+ import { defineComponent, ref } from 'vue'
3
+
4
+ export default defineComponent(
5
+ ({ action, row,index }) => {
6
+ const {
7
+ onClick,
8
+ disabled,
9
+ type = 'primary',
10
+ loading = false,
11
+ label = null,
12
+ ...other
13
+ } = action
14
+ const oprBtnLoading = ref(false)
15
+ return () => (
16
+ <NButton
17
+ text
18
+ onClick={async () => {
19
+ if (onClick) {
20
+ try {
21
+ if (loading) {
22
+ oprBtnLoading.value = true
23
+ }
24
+ await onClick(row,index)
25
+ }
26
+ finally {
27
+ setTimeout(() => (oprBtnLoading.value = false), 500)
28
+ }
29
+ }
30
+ }}
31
+ disabled={disabled && disabled(row)}
32
+ loading={oprBtnLoading.value}
33
+ type={disabled && disabled(row) ? 'default' : type}
34
+ {...other}
35
+ >
36
+ {typeof label === 'function' ? label?.(row) : label}
37
+ </NButton>
38
+ )
39
+ },
40
+ {
41
+ props: {
42
+ action: {
43
+ type: [Object, null],
44
+ default: null,
45
+ },
46
+ row: {
47
+ type: [Object, null],
48
+ default: null,
49
+ },
50
+ index: {
51
+ type: Number,
52
+ default: 0,
53
+ },
54
+ },
55
+ },
56
+ )
@@ -0,0 +1,57 @@
1
+ import { NPopconfirm } from 'naive-ui'
2
+ import { defineComponent, ref } from 'vue'
3
+
4
+ export default defineComponent(
5
+ ({ onClick, row, index,action }, { slots }) => {
6
+ const popLoading = ref(false)
7
+ return () => (
8
+ <NPopconfirm
9
+ positive-button-props={{
10
+ type: 'warning',
11
+ loading: popLoading.value,
12
+ }}
13
+ onPositiveClick={async () => {
14
+ try {
15
+ if (onClick) {
16
+ popLoading.value = true
17
+ await onClick(row,index)
18
+ popLoading.value = false
19
+ return true
20
+ }
21
+ }
22
+ catch {
23
+ popLoading.value = false
24
+ return false
25
+ }
26
+ return false
27
+ }}
28
+ >
29
+ {{
30
+ trigger: slots.default,
31
+ default: () =>
32
+ action?.popProps?.content || action?.content || '确定删除该记录?',
33
+ }}
34
+ </NPopconfirm>
35
+ )
36
+ },
37
+ {
38
+ props: {
39
+ onClick: {
40
+ type: [Function, null],
41
+ default: null,
42
+ },
43
+ row: {
44
+ type: [Object, null],
45
+ default: null,
46
+ },
47
+ action: {
48
+ type: [Object, null],
49
+ default: null,
50
+ },
51
+ index: {
52
+ type: Number,
53
+ default: 0,
54
+ },
55
+ },
56
+ },
57
+ )