@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,248 @@
1
+ ```vue
2
+ <template>
3
+ <div class="page-box">
4
+ <n-space justify="space-between">
5
+ <CommonQuery :query="listQuery" :options="keyQuery" @submit="pageState.search()" @reset="pageState.reset()" />
6
+ </n-space>
7
+ <div style="margin-bottom: 15px; margin-top: 10px">
8
+ <n-space>
9
+ <n-button type="primary" @click="onAddOrEdit(null, 'add')">新增资讯</n-button>
10
+ <n-button type="primary" :disabled="checkedRowKeysRef.length === 0" @click="onSendBatch()"
11
+ >批量发布资讯</n-button
12
+ >
13
+ </n-space>
14
+ </div>
15
+ <div class="page-main">
16
+ <DataTable
17
+ ref="tableRef"
18
+ v-model:checked-row-keys="checkedRowKeysRef"
19
+ :loading="pageState.loading"
20
+ :data="pageState.list"
21
+ :pagination="pageState"
22
+ :columns="columns"
23
+ :opr-columns="oprColumns"
24
+ :select-columns="selectColumns"
25
+ :row-key="(row) => row.id"
26
+ />
27
+ </div>
28
+ </div>
29
+ </template>
30
+
31
+ <script setup lang="jsx">
32
+ import { onMounted, ref } from 'vue'
33
+ import { useRouter, useRoute } from 'vue-router'
34
+ import { useNaivePage } from '@/use/useNaivePage.jsx'
35
+ import { useDeleteConfirm, useInfoConfirm } from '@/use/dialog.js'
36
+ import { getList, save, add, remove, sendBatch } from '@/api/spreadPlatform/information.js'
37
+ import { DataTable, commonDialogMethod, createActionColumnJsx } from 'core'
38
+
39
+ const router = useRouter()
40
+ const route = useRoute()
41
+
42
+ // way:'select'的 options可以根据enum 通过 options = ObjectToArray(enum) 转换
43
+
44
+
45
+ const keyQuery = [
46
+ {
47
+ label: '名称',
48
+ key: 'name',
49
+ queryType: 'likeQuery'
50
+ },
51
+ {
52
+ label: '类型',
53
+ key: 'type',
54
+ queryType: 'andQuery',
55
+ way: 'select',
56
+ options: [
57
+ { label: '类型1', value: 1 },
58
+ { label: '类型2', value: 2 }
59
+ ]
60
+ },
61
+ {
62
+ label: '状态',
63
+ key: 'status',
64
+ queryType: 'andQuery',
65
+ way: 'select',
66
+ options: [
67
+ { label: '启用', value: 1 },
68
+ { label: '禁用', value: 0 }
69
+ ]
70
+ }
71
+ ]
72
+ onMounted(() => {
73
+ pageState.search()
74
+ })
75
+ const infoContent = ref('确认要批量发布吗?')
76
+ function ReqGetList() {
77
+ pageState.showLoading()
78
+ getList(listQuery)
79
+ .then((res) => {
80
+ pageState.list = res.data.records
81
+ pageState.itemCount = res.data.total
82
+ })
83
+ .finally(() => {
84
+ pageState.hideLoading()
85
+ })
86
+ }
87
+ const checkedRowKeysRef = ref([])
88
+
89
+ const columns = [
90
+ {
91
+ key: 'sort',
92
+ title: '排序',
93
+ render(row, index) {
94
+ return index + 1
95
+ }
96
+ },
97
+
98
+ {
99
+ key: 'name',
100
+ title: '资讯标题'
101
+ },
102
+ {
103
+ key: 'link',
104
+ title: '链接'
105
+ },
106
+ {
107
+ title: '来源平台',
108
+ key: 'source'
109
+ },
110
+ {
111
+ title: '发布',
112
+ key: 'sendStatus',
113
+ render: (row) => (row?.sendStatus ? '已发布' : '未发布')
114
+ },
115
+ {
116
+ title: '发布日期',
117
+ key: 'sendTime'
118
+ },
119
+ {
120
+ title: '显示',
121
+ key: 'status',
122
+ render: (row) => (
123
+ <NSwitch
124
+ v-model:value={row.status}
125
+ onUpdateValue={(v) => {
126
+ pageState.showLoading()
127
+ save({
128
+ id: row.id,
129
+ status: v
130
+ })
131
+ .then((res) => {
132
+ $message.success('操作成功')
133
+ })
134
+ .catch(() => {
135
+ row.status = !v
136
+ })
137
+ .finally(() => pageState.hideLoading())
138
+ }}
139
+ />
140
+ )
141
+ }
142
+ ]
143
+ const oprColumns = createActionColumnJsx(
144
+ [
145
+ {
146
+ label: '编辑',
147
+ type: 'primary',
148
+
149
+ onClick: (row) => onAddOrEdit(row, 'edit'),
150
+ permission: []
151
+ },
152
+
153
+ {
154
+ label: '删除',
155
+ type: 'error',
156
+ mode: 'pop',
157
+ onClick: (row) =>
158
+ remove({ id: row.id }).then(() => {
159
+ $message.success('操作成功')
160
+ pageState.fetchData()
161
+ }),
162
+ permission: []
163
+ }
164
+ ],
165
+ {
166
+ width: 200
167
+ }
168
+ )
169
+ const selectColumns = {
170
+ type: 'selection'
171
+ width: 50
172
+ }
173
+
174
+ const { pageState, listQuery } = useNaivePage(ReqGetList)
175
+
176
+ function onSendBatch() {
177
+ commonDialogMethod({
178
+ title: '批量发布',
179
+ mode: null,
180
+ options: [
181
+ {
182
+ render: () => '确认要批量发布吗?'
183
+ }
184
+ ],
185
+ interfaceFn: (_, { close }) =>
186
+ sendBatch(checkedRowKeysRef.value).then(() => {
187
+ $message.success('操作成功')
188
+ pageState.fetchData()
189
+ checkedRowKeysRef.value = []
190
+ close()
191
+ })
192
+ })
193
+ }
194
+
195
+ function onAddOrEdit(row = {}, mode = 'add') {
196
+ const { model, modeEnum } = commonDialogMethod(
197
+ {
198
+ title: '资讯',
199
+ mode,
200
+ options: [
201
+ {
202
+ label: '标题',
203
+ key: 'name',
204
+ required: true
205
+ },
206
+ {
207
+ label: '链接',
208
+ key: 'link',
209
+ required: true
210
+ },
211
+ {
212
+ label: '来源平台',
213
+ key: 'source',
214
+ required: true
215
+ },
216
+ {
217
+ label: '排序',
218
+ key: 'sort',
219
+ way: 'inputNumber'
220
+ },
221
+ {
222
+ label: '是否展示',
223
+ key: 'status',
224
+ way: 'switch'
225
+ }
226
+ ],
227
+ valueData: { status: true, sort: pageState.itemCount, ...row },
228
+ interfaceFn: (data, { close }) =>
229
+ (data?.id ? save : add)(data).then(() => {
230
+ pageState.fetchData()
231
+ $message.succees(`${modeEnum[mode]}成功`)
232
+ close()
233
+ })
234
+ },
235
+ {
236
+ style: {
237
+ width: '600px'
238
+ }
239
+ }
240
+ )
241
+ }
242
+ </script>
243
+
244
+ <style scoped lang="less">
245
+ .xxx-page {
246
+ }
247
+ </style>
248
+ ```
@@ -0,0 +1,22 @@
1
+ export const ellipsis = {
2
+ style: {
3
+ cursor: 'pointer',
4
+ },
5
+ tooltip: {
6
+ flip: true,
7
+ arrowPointToCenter: true,
8
+ contentStyle: {
9
+ minWidth: '100px',
10
+ maxWidth: '300px',
11
+ maxHeight: '300px',
12
+ overflowY: 'auto',
13
+ whiteSpace: 'pre-line',
14
+ boxSizing: 'border-box',
15
+ margin: '0 -14px',
16
+ padding: '0 14px',
17
+ },
18
+ arrowStyle: {
19
+ backgroundColor: '--n-color',
20
+ },
21
+ },
22
+ }
@@ -0,0 +1,26 @@
1
+ import { unref } from 'vue'
2
+ import {
3
+ labelField as globalLabelField,
4
+ valueField as globalValueField,
5
+ } from '../enum/options'
6
+
7
+ export function ArrayToObject(
8
+ arr = [],
9
+ { labelField = globalLabelField, valueField = globalValueField } = {
10
+ labelField: globalLabelField,
11
+ valueField: globalValueField,
12
+ },
13
+ ) {
14
+ return unref(arr).reduce((o, n) => {
15
+ o[n[valueField]] = {
16
+ ...n,
17
+ [labelField]: n[labelField],
18
+ [valueField]: n[valueField],
19
+ }
20
+ return o
21
+ }, {})
22
+ }
23
+
24
+ export function toArray(v) {
25
+ return Array.isArray(v) ? v : [v]
26
+ }
@@ -0,0 +1,118 @@
1
+ import { useRoute, useRouter } from 'vue-router'
2
+ import { toArray } from './array'
3
+
4
+ export function cellectChildenPermission(o) {
5
+ if (o?.children?.length) {
6
+ const pn = []
7
+ o.children.forEach((v) => {
8
+ cellectChildenPermission(v)
9
+ let arr = []
10
+ if (typeof v?.meta?.permission === 'string')
11
+ arr = [v.meta.permission]
12
+ else if (Array.isArray(v.meta?.permission))
13
+ arr.push(...v.meta.permission)
14
+ else if (typeof v.meta?.permission === 'object')
15
+ arr.push(...mergaMethod(allMethod(v.meta.permission)))
16
+ else if (!v?.meta?.permission)
17
+ arr = null
18
+ v.meta.permission = arr
19
+ pn.push(...new Set(arr))
20
+ })
21
+ if (!o?.meta?.permission)
22
+ o.meta.permission = pn
23
+ else o.meta.permission = [...new Set(o.meta.permission.concat(pn))]
24
+ }
25
+
26
+ return o
27
+ }
28
+ export function mergaMethod(...arg) {
29
+ const arr = arg?.map(v => (Array.isArray(v) ? v : v?.ALL))
30
+ return [].concat(...arr)
31
+ }
32
+
33
+ export function allMethod(data) {
34
+ if (!data)
35
+ return []
36
+ return Object.keys(data).reduce((a, b) => {
37
+ if (typeof data[b] !== 'string') {
38
+ a.concat(allMethod(data[b]))
39
+ }
40
+ else {
41
+ a.push(data[b])
42
+ }
43
+ return a
44
+ }, [])
45
+ }
46
+
47
+ export function useAuthPermission(...arg) {
48
+ return {
49
+ ...getRouteMeta('auth', arg),
50
+ }
51
+ }
52
+
53
+ export function useApiConfig(...arg) {
54
+ return {
55
+ ...getRouteMeta('api', arg),
56
+ }
57
+ }
58
+
59
+ /**
60
+ *
61
+ * @param {*} str 接口字符串
62
+ * @param {*} op 接口参数替换
63
+ * @returns
64
+ * return handleParams(data?.id ? updateTask : createTask, {
65
+ '{processId}': unref(processId),
66
+ '{id}': data?.id,
67
+ })[data?.id ? '$Put' : '$Post']({
68
+ ...data,
69
+ }).then(() => {
70
+ reLoad()
71
+ $message.success(`${modeEnum[str]?.sub}成功`)
72
+ cancel()
73
+ if (isNext.value)
74
+ onAdd()
75
+ })
76
+ */
77
+
78
+ export function handleParams(str, op = {}) {
79
+ const arr = Object.keys(op)
80
+ if (arr.length) {
81
+ arr.forEach((v) => {
82
+ const reg = new RegExp(`${v}`, 'g')
83
+ str = str?.replace(reg, op[v])
84
+ })
85
+ }
86
+ return str
87
+ }
88
+
89
+ function getRouteMeta(name, arg) {
90
+ const route = useRoute()
91
+ const router = useRouter()
92
+ const meta = handleMeta(route?.meta?.[name] ?? {})
93
+ const routeNameArr = toArray(arg[0])
94
+
95
+ if (routeNameArr?.length) {
96
+ const routeArr = router
97
+ .getRoutes()
98
+ .filter(v => routeNameArr.includes(v.name))
99
+ routeArr.forEach((v) => {
100
+ if (v.meta?.[name])
101
+ meta[v.name] = handleMeta(v.meta[name])
102
+ })
103
+ }
104
+ return {
105
+ ...meta,
106
+ }
107
+ }
108
+
109
+ function handleMeta(o = {}) {
110
+ return Object.keys(o).reduce((a, b) => {
111
+ const data = o[b]
112
+ if (typeof data === 'object')
113
+ a[b] = data?.key
114
+ else if (typeof data === 'string')
115
+ a[b] = String(data)
116
+ return a
117
+ }, {})
118
+ }
@@ -0,0 +1,32 @@
1
+ import {
2
+ labelField as globalLabelField,
3
+ valueField as globalValueField,
4
+ } from '../enum/options'
5
+
6
+ export function ObjectToArray(
7
+ obj,
8
+ { labelField = globalLabelField, valueField = globalValueField } = {},
9
+ ) {
10
+ return Object.keys(obj).reduce((o, n) => {
11
+ const data = toObject(obj[n], n)
12
+ const params = {
13
+ ...data,
14
+ }
15
+ params[labelField] = data?.[labelField]
16
+ params[valueField] = data?.[valueField]
17
+ return o.concat(params)
18
+ }, [])
19
+ }
20
+
21
+ export function toObject(label, value) {
22
+ const params = {
23
+ [globalLabelField]: unref(label),
24
+ [globalValueField]: Number.isNaN(Number(value)) ? value : Number(value),
25
+ }
26
+ return typeof unref(label) === 'object'
27
+ ? {
28
+ ...unref(label),
29
+ [globalValueField]: Number.isNaN(Number(value)) ? value : Number(value),
30
+ }
31
+ : params
32
+ }
@@ -0,0 +1,7 @@
1
+ import dayjs from 'dayjs'
2
+
3
+ export function timeFormat(v, str = 'YYYY-MM-DD', extend = { emptyText: '' }) {
4
+ if (!v)
5
+ return extend?.emptyText || ''
6
+ return dayjs(Number.isNaN(Number(v)) ? v : Number(v)).format(str)
7
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * 上传数据类型
3
+ * @import {AxiosRequestConfig} 'axios'
4
+ * @typedef {object} UploadData
5
+ * @property {string} url - 文件上传后的访问地址
6
+ * // 可根据实际需求扩展更多字段
7
+ * @typedef {Promise<import('axios').AxiosResponse<UploadData>>} UploadDataPromise
8
+ */
9
+
10
+ import { BASE_URL } from '@/utils/request'
11
+
12
+ /**
13
+ * 实际的上传实现函数
14
+ * @type {null | ((AxiosRequestConfig) => UploadDataPromise)}
15
+ */
16
+ let uploadMethod = null
17
+
18
+ /**
19
+ * 注册上传方法
20
+ * @param {function(AxiosRequestConfig): UploadDataPromise} fn - 实际的上传实现函数
21
+ */
22
+ export function registryUpload(fn) {
23
+ uploadMethod = fn
24
+ }
25
+
26
+ /**
27
+ * 自定义上传方法,调用已注册的上传实现
28
+ * @param {AxiosRequestConfig} args - 上传参数
29
+ * @returns {UploadDataPromise} 上传结果Promise
30
+ */
31
+ export function customUpload(...args) {
32
+ if (typeof uploadMethod !== 'function') {
33
+ throw new TypeError('请先通过 registryUpload(fn) 注册上传实现')
34
+ }
35
+ return uploadMethod(...args)
36
+ }
37
+
38
+ export function getFileUrl(url, ossSize = null) {
39
+ if (url && !url?.startsWith('http')) {
40
+ return !ossSize
41
+ ? `${BASE_URL}${url}`
42
+ : `${BASE_URL}${url}?x-oss-process=style/w${ossSize}`
43
+ }
44
+ return url
45
+ }
46
+
@@ -0,0 +1,67 @@
1
+ import type { Component } from 'vue'
2
+
3
+ export interface CommonDialogResult {
4
+ cancel(): void
5
+ setValue(v: any, key?: string): void
6
+ model: any
7
+ modeEnum: Record<string, { sub?: string; read?: boolean }>
8
+ }
9
+
10
+ export function commonDialogMethod(
11
+ options?: Record<string, any>,
12
+ dialogProps?: Record<string, any>,
13
+ ): CommonDialogResult
14
+
15
+ export const DataForm: Component
16
+ export const Options: Component
17
+ export const CommonQuery: Component
18
+ export const DataTable: Component
19
+ export const OprButton: Component
20
+ export const Pop: Component
21
+
22
+ export function createActionColumnJsx(...args: any[]): any
23
+ export function initRules(args: {
24
+ options?: any[]
25
+ model?: any
26
+ labelField?: string
27
+ formOpr?: Record<string, any>
28
+ }): any
29
+
30
+ export function getAllOptions(...args: any[]): any
31
+ export function getOptions(...args: any[]): any
32
+ export function setupOptions(...args: any[]): any
33
+
34
+ export function toArray<T = any>(v: T | T[]): T[]
35
+ export function ArrayToObject<T = any>(
36
+ arr?: T[],
37
+ fields?: { labelField?: string; valueField?: string },
38
+ ): Record<string, T>
39
+ export function ObjectToArray<T extends Record<string, any> = any>(
40
+ obj?: T,
41
+ fields?: { labelField?: string; valueField?: string },
42
+ ): any[]
43
+
44
+ export function customUpload(...args: any[]): Promise<any>
45
+ export function registryUpload(fn: (...args: any[]) => Promise<any>): void
46
+ export function getFileUrl(url?: string, ossSize?: number | null): string | undefined
47
+
48
+ export function cellectChildenPermission(route: any): any
49
+ export function handleParams(str?: string, op?: Record<string, any>): string
50
+ export function useApiConfig(...args: any[]): Record<string, any>
51
+ export function useAuthPermission(...args: any[]): Record<string, any>
52
+ export function initRouteMeta(routes: any[], base?: string): any[]
53
+
54
+ export const ellipsis: any
55
+ export const orderEnum: Record<string, any>
56
+ export const globalLabelField: string
57
+ export const globalValueField: string
58
+
59
+ declare module 'core' {
60
+ export * from './index.d'
61
+ }
62
+
63
+ declare module 'core/*' {
64
+ const mod: any
65
+ export = mod
66
+ }
67
+