@xmszm/core 0.0.1 → 0.0.3
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/README.md +187 -0
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +1431 -1170
- package/dist/plugin/vite/initRouteMeta.cjs +1 -0
- package/dist/plugin/vite/initRouteMeta.mjs +13 -0
- package/dist/style.css +1 -1
- package/docs/.vitepress/config.mjs +91 -0
- package/docs/components/config-options.md +125 -0
- package/docs/components/dataform.md +176 -23
- package/docs/components/datatable.md +58 -39
- package/docs/components/dialog.md +158 -19
- package/docs/components/options.md +44 -15
- package/docs/components/query.md +68 -14
- package/docs/components/utils.md +124 -16
- package/docs/guide/changelog.md +81 -0
- package/docs/guide/config.md +415 -0
- package/docs/guide/demo.md +2 -2
- package/docs/guide/local-development.md +109 -0
- package/docs/guide/quickstart.md +40 -11
- package/docs/index.md +3 -3
- package/docs/usage.md +30 -6
- package/examples/README.md +46 -0
- package/examples/index.html +14 -0
- package/examples/package.json +25 -0
- package/examples/pnpm-lock.yaml +1569 -0
- package/examples/pnpm-workspace.yaml +3 -0
- package/examples/src/AdminSystem.vue +870 -0
- package/examples/src/App.vue +330 -0
- package/examples/src/Introduction.vue +307 -0
- package/examples/src/main.js +22 -0
- package/examples/src/utils/permission.js +16 -0
- package/examples/src/utils/request.js +10 -0
- package/examples/vite.config.js +41 -0
- package/package.json +13 -4
- package/src/dialog/commonDialog.tsx +285 -0
- package/src/dialog/useCommonDialog.ts +41 -0
- package/src/dialog/utils/{dialog.js → dialog.ts} +2 -0
- package/src/directives/auto-register.ts +57 -0
- package/src/directives/permission.ts +67 -0
- package/src/enum/sort.tsx +45 -0
- package/src/form/DataForm.vue +34 -52
- package/src/index.ts +58 -0
- package/src/list/{useList.jsx → useList.tsx} +49 -14
- package/src/options/{Options.jsx → Options.tsx} +86 -72
- package/src/options/defaultOptions.tsx +656 -0
- package/src/plugin/index.ts +20 -0
- package/src/query/CommonQuery.vue +65 -90
- package/src/table/DataTable.vue +82 -95
- package/src/table/opr/{DataColumnCollet.jsx → DataColumnCollet.tsx} +18 -8
- package/src/table/opr/useDataColumn.tsx +226 -0
- package/src/table/opr/{useDataColumnButton.jsx → useDataColumnButton.tsx} +13 -6
- package/src/table/opr/{useDataColumnPop.jsx → useDataColumnPop.tsx} +13 -5
- package/src/table/opr/useQRCode.ts +40 -0
- package/src/utils/{array.js → array.ts} +4 -6
- package/src/utils/config.ts +192 -0
- package/src/utils/dialog.ts +110 -0
- package/src/utils/{object.js → object.ts} +1 -0
- package/src/utils/upload.ts +53 -0
- package/types/auto-imports.d.ts +78 -0
- package/types/components.d.ts +402 -0
- package/types/index.d.ts +145 -7
- package/types/plugin/vite/initRouteMeta.d.ts +23 -0
- package/types/src.d.ts +55 -0
- package/types/vue-shim.d.ts +9 -0
- package/examples/demo.vue +0 -224
- package/src/dialog/commonDialog.jsx +0 -230
- package/src/enum/sort.jsx +0 -31
- package/src/index.js +0 -46
- package/src/options/defaultOptions.jsx +0 -580
- package/src/table/opr/useDataColumn.jsx +0 -196
- package/src/utils/upload.js +0 -46
- /package/src/enum/{options.js → options.ts} +0 -0
- /package/src/plugin/vite/{initRouteMeta.js → initRouteMeta.ts} +0 -0
- /package/src/store/utils/{index.js → index.ts} +0 -0
- /package/src/table/utils/{ellipsis.js → ellipsis.ts} +0 -0
- /package/src/utils/{auth.js → auth.ts} +0 -0
- /package/src/utils/{time.js → time.ts} +0 -0
package/types/index.d.ts
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
import type { Component } from 'vue'
|
|
2
|
+
import type {
|
|
3
|
+
CommonDialogOptions,
|
|
4
|
+
DialogAction,
|
|
5
|
+
DataFormProps,
|
|
6
|
+
DataFormExpose,
|
|
7
|
+
CommonQueryProps,
|
|
8
|
+
CommonQueryEmits,
|
|
9
|
+
DataTableProps,
|
|
10
|
+
DataTableExpose,
|
|
11
|
+
TableColumn,
|
|
12
|
+
DataTablePagination,
|
|
13
|
+
FormOption,
|
|
14
|
+
ActionOption,
|
|
15
|
+
OptionsProps,
|
|
16
|
+
} from './components'
|
|
2
17
|
|
|
18
|
+
/**
|
|
19
|
+
* commonDialogMethod 返回值
|
|
20
|
+
*
|
|
21
|
+
* | 字段名 | 必填 | 类型 | 说明 |
|
|
22
|
+
* |--------|------|------|------|
|
|
23
|
+
* | cancel | 是 | () => void | 关闭弹窗方法 |
|
|
24
|
+
* | setValue | 是 | (v: any, key?: string) => void | 设置表单值方法 |
|
|
25
|
+
* | model | 是 | any | 表单数据对象(响应式) |
|
|
26
|
+
* | modeEnum | 是 | Record<string, { sub?: string; read?: boolean }> | 模式枚举对象 |
|
|
27
|
+
*/
|
|
3
28
|
export interface CommonDialogResult {
|
|
4
29
|
cancel(): void
|
|
5
30
|
setValue(v: any, key?: string): void
|
|
@@ -7,21 +32,130 @@ export interface CommonDialogResult {
|
|
|
7
32
|
modeEnum: Record<string, { sub?: string; read?: boolean }>
|
|
8
33
|
}
|
|
9
34
|
|
|
35
|
+
/**
|
|
36
|
+
* 通用弹窗方法
|
|
37
|
+
*
|
|
38
|
+
* @param options - 弹窗配置选项,详见 CommonDialogOptions
|
|
39
|
+
* @param dialogProps - 传递给 NDialog 的属性
|
|
40
|
+
* @returns CommonDialogResult 弹窗控制对象
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* const { cancel, setValue, model } = commonDialogMethod({
|
|
45
|
+
* title: '编辑',
|
|
46
|
+
* mode: 'edit',
|
|
47
|
+
* options: [
|
|
48
|
+
* { key: 'name', label: '名称', way: 'input', required: true },
|
|
49
|
+
* { key: 'type', label: '类型', way: 'select', options: [...] }
|
|
50
|
+
* ],
|
|
51
|
+
* valueData: { name: 'test', type: 'A' },
|
|
52
|
+
* interfaceFn: async (data, { close }) => {
|
|
53
|
+
* await saveData(data)
|
|
54
|
+
* close()
|
|
55
|
+
* }
|
|
56
|
+
* })
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
10
59
|
export function commonDialogMethod(
|
|
11
|
-
options?:
|
|
60
|
+
options?: CommonDialogOptions,
|
|
12
61
|
dialogProps?: Record<string, any>,
|
|
13
62
|
): CommonDialogResult
|
|
14
63
|
|
|
15
|
-
|
|
16
|
-
export
|
|
17
|
-
|
|
18
|
-
|
|
64
|
+
// 导出类型定义
|
|
65
|
+
export type {
|
|
66
|
+
CommonDialogOptions,
|
|
67
|
+
DialogAction,
|
|
68
|
+
FormOption,
|
|
69
|
+
DataFormProps,
|
|
70
|
+
DataFormExpose,
|
|
71
|
+
CommonQueryProps,
|
|
72
|
+
CommonQueryEmits,
|
|
73
|
+
DataTableProps,
|
|
74
|
+
DataTableExpose,
|
|
75
|
+
TableColumn,
|
|
76
|
+
DataTablePagination,
|
|
77
|
+
ActionOption,
|
|
78
|
+
OptionsProps,
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* DataForm 组件
|
|
83
|
+
*
|
|
84
|
+
* Props 详见 DataFormProps
|
|
85
|
+
* Expose 详见 DataFormExpose
|
|
86
|
+
*/
|
|
87
|
+
export const DataForm: Component<DataFormProps>
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Options 组件(内部组件)
|
|
91
|
+
*
|
|
92
|
+
* Props 详见 OptionsProps
|
|
93
|
+
*/
|
|
94
|
+
export const Options: Component<OptionsProps>
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* CommonQuery 组件
|
|
98
|
+
*
|
|
99
|
+
* Props 详见 CommonQueryProps
|
|
100
|
+
* Events 详见 CommonQueryEmits
|
|
101
|
+
*/
|
|
102
|
+
export const CommonQuery: Component<CommonQueryProps>
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* DataTable 组件
|
|
106
|
+
*
|
|
107
|
+
* Props 详见 DataTableProps
|
|
108
|
+
* Expose 详见 DataTableExpose
|
|
109
|
+
*/
|
|
110
|
+
export const DataTable: Component<DataTableProps>
|
|
111
|
+
|
|
19
112
|
export const OprButton: Component
|
|
20
113
|
export const Pop: Component
|
|
21
114
|
|
|
22
|
-
|
|
115
|
+
/**
|
|
116
|
+
* 创建操作列
|
|
117
|
+
*
|
|
118
|
+
* @param defaultOption - 操作按钮配置数组,详见 ActionOption
|
|
119
|
+
* @param oprParams - 操作列额外参数
|
|
120
|
+
* @param collectParams - 是否收集操作按钮(超过 max 个时收起)
|
|
121
|
+
* @returns TableColumn 表格列配置对象
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```typescript
|
|
125
|
+
* const opr = createActionColumnJsx([
|
|
126
|
+
* {
|
|
127
|
+
* label: '编辑',
|
|
128
|
+
* type: 'primary',
|
|
129
|
+
* onClick: (row) => onEdit(row)
|
|
130
|
+
* },
|
|
131
|
+
* {
|
|
132
|
+
* label: '删除',
|
|
133
|
+
* type: 'error',
|
|
134
|
+
* mode: 'pop',
|
|
135
|
+
* onClick: (row) => onDelete(row)
|
|
136
|
+
* }
|
|
137
|
+
* ])
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
export function createActionColumnJsx(
|
|
141
|
+
defaultOption: ActionOption[],
|
|
142
|
+
oprParams?: Record<string, any>,
|
|
143
|
+
collectParams?: boolean | { max: number; width: number }
|
|
144
|
+
): TableColumn | undefined
|
|
145
|
+
/**
|
|
146
|
+
* 初始化表单验证规则
|
|
147
|
+
*
|
|
148
|
+
* | 参数名 | 必填 | 类型 | 说明 |
|
|
149
|
+
* |--------|------|------|------|
|
|
150
|
+
* | options | 否 | FormOption[] | 表单配置项数组 |
|
|
151
|
+
* | model | 否 | any | 表单数据对象 |
|
|
152
|
+
* | labelField | 否 | string | 标签字段名,默认 'label' |
|
|
153
|
+
* | formOpr | 否 | Record<string, any> | 表单操作对象 |
|
|
154
|
+
*
|
|
155
|
+
* @returns ComputedRef<Record<string, any>> 验证规则对象
|
|
156
|
+
*/
|
|
23
157
|
export function initRules(args: {
|
|
24
|
-
options?:
|
|
158
|
+
options?: FormOption[]
|
|
25
159
|
model?: any
|
|
26
160
|
labelField?: string
|
|
27
161
|
formOpr?: Record<string, any>
|
|
@@ -65,3 +199,7 @@ declare module 'core/*' {
|
|
|
65
199
|
export = mod
|
|
66
200
|
}
|
|
67
201
|
|
|
202
|
+
// 引用类型声明文件
|
|
203
|
+
/// <reference path="./components.d.ts" />
|
|
204
|
+
/// <reference path="./src.d.ts" />
|
|
205
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 初始化路由元数据
|
|
3
|
+
*
|
|
4
|
+
* @param routes - 路由配置数组
|
|
5
|
+
* @param str - 基础路径字符串,默认为空字符串
|
|
6
|
+
* @returns 处理后的路由配置数组
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const routes = [
|
|
11
|
+
* {
|
|
12
|
+
* path: '/user',
|
|
13
|
+
* title: '用户管理',
|
|
14
|
+
* children: [
|
|
15
|
+
* { path: 'list', title: '用户列表' }
|
|
16
|
+
* ]
|
|
17
|
+
* }
|
|
18
|
+
* ]
|
|
19
|
+
* const processedRoutes = initRouteMeta(routes)
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export function initRouteMeta(routes: any[], str?: string): any[]
|
|
23
|
+
|
package/types/src.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @/ 路径别名类型声明
|
|
3
|
+
*
|
|
4
|
+
* 此文件为 @xmszm/core 包中使用的 @/ 路径别名提供 TypeScript 类型支持
|
|
5
|
+
* 使用方项目需要提供对应的实现文件
|
|
6
|
+
*
|
|
7
|
+
* @see LOCAL_DEPENDENCIES.md 了解详细的使用说明
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @/utils/permission 模块类型声明
|
|
12
|
+
*
|
|
13
|
+
* 权限检查函数模块
|
|
14
|
+
* 使用方需要在项目的 src/utils/permission.js 或 src/utils/permission.ts 中实现
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* // src/utils/permission.ts
|
|
18
|
+
* export function hasPermission(permission: string): boolean {
|
|
19
|
+
* const permissions = getPermissions() // 你的权限获取逻辑
|
|
20
|
+
* return permissions.includes(permission)
|
|
21
|
+
* }
|
|
22
|
+
*/
|
|
23
|
+
declare module '@/utils/permission' {
|
|
24
|
+
/**
|
|
25
|
+
* 权限检查函数
|
|
26
|
+
* @param permission - 权限标识字符串
|
|
27
|
+
* @returns 是否拥有该权限
|
|
28
|
+
*/
|
|
29
|
+
export function hasPermission(permission: string): boolean
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @/utils/request 模块类型声明
|
|
34
|
+
*
|
|
35
|
+
* 请求配置模块
|
|
36
|
+
* 使用方需要在项目的 src/utils/request.js 或 src/utils/request.ts 中实现
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* // src/utils/request.ts
|
|
40
|
+
* export const BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:3000'
|
|
41
|
+
*/
|
|
42
|
+
declare module '@/utils/request' {
|
|
43
|
+
/**
|
|
44
|
+
* API 基础地址
|
|
45
|
+
* 用于构建完整的请求 URL
|
|
46
|
+
*/
|
|
47
|
+
export const BASE_URL: string
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// 声明全局 $dialog(如果存在)
|
|
51
|
+
// 外部可以通过 window.$dialog 或直接 $dialog 注入 dialog 实例
|
|
52
|
+
declare global {
|
|
53
|
+
// eslint-disable-next-line no-var
|
|
54
|
+
var $dialog: import('naive-ui').DialogApi | undefined
|
|
55
|
+
}
|
package/examples/demo.vue
DELETED
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
<script setup lang="jsx">
|
|
2
|
-
import { computed, onMounted, reactive } from 'vue'
|
|
3
|
-
import { NButton, NCard, NSpace } from 'naive-ui'
|
|
4
|
-
import {
|
|
5
|
-
commonDialogMethod,
|
|
6
|
-
CommonQuery,
|
|
7
|
-
createActionColumnJsx,
|
|
8
|
-
DataTable,
|
|
9
|
-
} from 'core'
|
|
10
|
-
import 'core/dist/style.css'
|
|
11
|
-
|
|
12
|
-
// 查询与分页状态(可替换为业务方的 useNaivePage)
|
|
13
|
-
const listQuery = reactive({
|
|
14
|
-
page: 1,
|
|
15
|
-
pageSize: 10,
|
|
16
|
-
desc: true,
|
|
17
|
-
likeQuery: {
|
|
18
|
-
name1: '',
|
|
19
|
-
name2: '',
|
|
20
|
-
name3: '',
|
|
21
|
-
},
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
const pageState = reactive({
|
|
25
|
-
data: [],
|
|
26
|
-
itemCount: 0,
|
|
27
|
-
loading: false,
|
|
28
|
-
page: computed(() => listQuery.page),
|
|
29
|
-
pageSize: computed(() => listQuery.pageSize),
|
|
30
|
-
showSizePicker: true,
|
|
31
|
-
pageSizes: [10, 20, 50],
|
|
32
|
-
onUpdatePage: (p) => {
|
|
33
|
-
listQuery.page = p
|
|
34
|
-
pageState.fetchData()
|
|
35
|
-
},
|
|
36
|
-
onUpdatePageSize: (ps) => {
|
|
37
|
-
listQuery.pageSize = ps
|
|
38
|
-
listQuery.page = 1
|
|
39
|
-
pageState.fetchData()
|
|
40
|
-
},
|
|
41
|
-
fetchData: async () => {
|
|
42
|
-
pageState.loading = true
|
|
43
|
-
try {
|
|
44
|
-
// 模拟请求
|
|
45
|
-
const mock = Array.from({ length: 25 }).map((_, i) => ({
|
|
46
|
-
id: i + 1,
|
|
47
|
-
name: `名称-${i + 1}`,
|
|
48
|
-
type: i % 2 ? 'B' : 'A',
|
|
49
|
-
}))
|
|
50
|
-
pageState.itemCount = mock.length
|
|
51
|
-
const start = (listQuery.page - 1) * listQuery.pageSize
|
|
52
|
-
const end = start + listQuery.pageSize
|
|
53
|
-
pageState.data = mock.slice(start, end)
|
|
54
|
-
}
|
|
55
|
-
finally {
|
|
56
|
-
pageState.loading = false
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
search: () => {
|
|
60
|
-
listQuery.page = 1
|
|
61
|
-
pageState.fetchData()
|
|
62
|
-
},
|
|
63
|
-
reset: () => {
|
|
64
|
-
listQuery.likeQuery = { name1: '', name2: '', name3: '' }
|
|
65
|
-
listQuery.page = 1
|
|
66
|
-
pageState.fetchData()
|
|
67
|
-
},
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
// 查询项
|
|
71
|
-
const keyQuery = [
|
|
72
|
-
{ label: '名称1', key: 'name1', queryType: 'likeQuery' },
|
|
73
|
-
{ label: '名称2', key: 'name2', queryType: 'likeQuery' },
|
|
74
|
-
{ label: '名称3', key: 'name3', queryType: 'likeQuery' },
|
|
75
|
-
]
|
|
76
|
-
|
|
77
|
-
// 表格列与操作列
|
|
78
|
-
const columns = [
|
|
79
|
-
{ title: '名称', key: 'name', width: 160 },
|
|
80
|
-
{ title: '类型', key: 'type', width: 120 },
|
|
81
|
-
]
|
|
82
|
-
const defaultColumns = []
|
|
83
|
-
const selectColumns = { type: 'selection', width: '40px' }
|
|
84
|
-
const opr = createActionColumnJsx([
|
|
85
|
-
{
|
|
86
|
-
label: '编辑',
|
|
87
|
-
type: 'primary',
|
|
88
|
-
onClick: row => onAdd(row, 'edit'),
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
label: '删除',
|
|
92
|
-
type: 'error',
|
|
93
|
-
mode: 'pop',
|
|
94
|
-
onClick: (row) => {
|
|
95
|
-
// del(row.id).then(() => pageState.fetchData())
|
|
96
|
-
console.log('删除', row)
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
])
|
|
100
|
-
|
|
101
|
-
// 弹窗新增/编辑
|
|
102
|
-
function onAdd(row = null, mode = 'add') {
|
|
103
|
-
commonDialogMethod({
|
|
104
|
-
title: '示例弹窗',
|
|
105
|
-
mode,
|
|
106
|
-
options: [
|
|
107
|
-
{ key: 'name', label: '名称', way: 'input', required: true },
|
|
108
|
-
{
|
|
109
|
-
key: 'type',
|
|
110
|
-
label: '类型',
|
|
111
|
-
way: 'select',
|
|
112
|
-
options: [
|
|
113
|
-
{ label: '类型A', value: 'A' },
|
|
114
|
-
{ label: '类型B', value: 'B' },
|
|
115
|
-
],
|
|
116
|
-
},
|
|
117
|
-
],
|
|
118
|
-
valueData: { ...row },
|
|
119
|
-
interfaceFn: async (data, { close }) => {
|
|
120
|
-
console.log('提交数据', data)
|
|
121
|
-
// await save(data)
|
|
122
|
-
pageState.fetchData()
|
|
123
|
-
close()
|
|
124
|
-
},
|
|
125
|
-
})
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// 导出示例
|
|
129
|
-
const exportLoading = reactive({ value: false })
|
|
130
|
-
function onExport() {
|
|
131
|
-
exportLoading.value = true
|
|
132
|
-
// exportApi(listQuery).finally(() => (exportLoading.value = false))
|
|
133
|
-
setTimeout(() => (exportLoading.value = false), 800)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
onMounted(() => pageState.fetchData())
|
|
137
|
-
</script>
|
|
138
|
-
|
|
139
|
-
<template>
|
|
140
|
-
<div class="page-box">
|
|
141
|
-
<!-- 头部筛选 -->
|
|
142
|
-
<NCard class="page-head">
|
|
143
|
-
<CommonQuery
|
|
144
|
-
:query="listQuery"
|
|
145
|
-
:options="keyQuery"
|
|
146
|
-
@submit="pageState.search()"
|
|
147
|
-
@reset="pageState.reset()"
|
|
148
|
-
/>
|
|
149
|
-
</NCard>
|
|
150
|
-
|
|
151
|
-
<!-- 操作区 -->
|
|
152
|
-
<NSpace justify="space-between">
|
|
153
|
-
<NSpace>
|
|
154
|
-
<NButton type="primary" @click="onAdd()">新增</NButton>
|
|
155
|
-
<NButton type="primary" :loading="exportLoading.value" @click="onExport">
|
|
156
|
-
导出
|
|
157
|
-
</NButton>
|
|
158
|
-
</NSpace>
|
|
159
|
-
</NSpace>
|
|
160
|
-
|
|
161
|
-
<!-- 内容表格区 -->
|
|
162
|
-
<div class="page-main">
|
|
163
|
-
<DataTable
|
|
164
|
-
:data="pageState.data"
|
|
165
|
-
:pagination="pageState"
|
|
166
|
-
:columns="columns"
|
|
167
|
-
:opr-columns="opr"
|
|
168
|
-
:default-columns="defaultColumns"
|
|
169
|
-
:row-key="row => row?.id"
|
|
170
|
-
:select-columns="selectColumns"
|
|
171
|
-
:loading="pageState.loading"
|
|
172
|
-
/>
|
|
173
|
-
</div>
|
|
174
|
-
</div>
|
|
175
|
-
</template>
|
|
176
|
-
|
|
177
|
-
<style scoped lang="less">
|
|
178
|
-
.page-head {
|
|
179
|
-
border-radius: 8px;
|
|
180
|
-
background-color: #fff;
|
|
181
|
-
box-sizing: border-box;
|
|
182
|
-
display: flex;
|
|
183
|
-
flex-direction: column;
|
|
184
|
-
row-gap: 20px;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
.page-main {
|
|
188
|
-
flex: 0 1 auto;
|
|
189
|
-
background-color: #fff;
|
|
190
|
-
border-radius: 8px;
|
|
191
|
-
padding: 20px;
|
|
192
|
-
box-sizing: border-box;
|
|
193
|
-
display: flex;
|
|
194
|
-
height: 100%;
|
|
195
|
-
flex-direction: column;
|
|
196
|
-
row-gap: 10px;
|
|
197
|
-
|
|
198
|
-
.n-data-table {
|
|
199
|
-
.n-data-table-th {
|
|
200
|
-
background-color: #f7f8fa;
|
|
201
|
-
border-right: 1px solid var(--n-merged-border-color);
|
|
202
|
-
white-space: break-spaces;
|
|
203
|
-
}
|
|
204
|
-
.n-data-table-th--last {
|
|
205
|
-
border-right: 1px solid transparent;
|
|
206
|
-
}
|
|
207
|
-
.n-data-table-td--last-row {
|
|
208
|
-
border-bottom: 1px solid var(--n-merged-border-color);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
.page-box {
|
|
214
|
-
display: flex;
|
|
215
|
-
flex-direction: column;
|
|
216
|
-
height: calc(100vh - 120px); // 可按实际头/标签高度调整
|
|
217
|
-
margin: -16px;
|
|
218
|
-
padding: 24px;
|
|
219
|
-
box-sizing: border-box;
|
|
220
|
-
overflow: hidden;
|
|
221
|
-
row-gap: 20px;
|
|
222
|
-
}
|
|
223
|
-
</style>
|
|
224
|
-
|
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
import { NButton, NSpace } from 'naive-ui'
|
|
2
|
-
import { computed, reactive, ref, unref, watch } from 'vue'
|
|
3
|
-
import DataForm from '../form/DataForm.vue'
|
|
4
|
-
import { dialogDefaultOption } from './utils/dialog'
|
|
5
|
-
import './style/commonDialog.less'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
*
|
|
9
|
-
* @param {*} param
|
|
10
|
-
* @param {object} dialogProps
|
|
11
|
-
* @returns {object {cancel,model}}
|
|
12
|
-
* 集成填写表单功能的弹窗
|
|
13
|
-
*/
|
|
14
|
-
export function commonDialogMethod(
|
|
15
|
-
{
|
|
16
|
-
title = '',
|
|
17
|
-
noTitle = false,
|
|
18
|
-
titleFull = null,
|
|
19
|
-
options = [],
|
|
20
|
-
mode = 'add',
|
|
21
|
-
modeEnum = {},
|
|
22
|
-
labelField = 'label',
|
|
23
|
-
isNo = true,
|
|
24
|
-
formProps = {},
|
|
25
|
-
interfaceFn = null,
|
|
26
|
-
interfaceFnCancel = null,
|
|
27
|
-
valueData,
|
|
28
|
-
read,
|
|
29
|
-
isRead,
|
|
30
|
-
action = null,
|
|
31
|
-
contentStyle = {},
|
|
32
|
-
actionProps = {},
|
|
33
|
-
} = {
|
|
34
|
-
title: '自定义弹窗',
|
|
35
|
-
noTitle: false,
|
|
36
|
-
action: [],
|
|
37
|
-
options: [],
|
|
38
|
-
read: false,
|
|
39
|
-
isRead: false,
|
|
40
|
-
valueData: {},
|
|
41
|
-
},
|
|
42
|
-
dialogProps = null,
|
|
43
|
-
) {
|
|
44
|
-
const defaultModeEnum = {
|
|
45
|
-
none: { sub: '', read: false },
|
|
46
|
-
create: { sub: '创建', read: false },
|
|
47
|
-
add: { sub: '添加', read: false },
|
|
48
|
-
edit: { sub: '编辑', read: false },
|
|
49
|
-
view: { sub: '查看', read: true },
|
|
50
|
-
export: { sub: '导出', read: false },
|
|
51
|
-
import: { sub: '导入', read: false },
|
|
52
|
-
delete: { sub: '删除', read: false },
|
|
53
|
-
copy: { sub: '复制', read: false },
|
|
54
|
-
...modeEnum,
|
|
55
|
-
}
|
|
56
|
-
const formRef = ref()
|
|
57
|
-
const actionLoading = reactive([])
|
|
58
|
-
const model = ref({ ...valueData })
|
|
59
|
-
const defaultActionProps = {
|
|
60
|
-
justify: 'end',
|
|
61
|
-
wrapItem: false,
|
|
62
|
-
style: {
|
|
63
|
-
width: '100%',
|
|
64
|
-
},
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const defaultButtonStyle = {
|
|
68
|
-
width: '120px',
|
|
69
|
-
}
|
|
70
|
-
const defaultAction = [
|
|
71
|
-
{
|
|
72
|
-
label: '取消',
|
|
73
|
-
props: {
|
|
74
|
-
type: 'primary',
|
|
75
|
-
ghost: true,
|
|
76
|
-
},
|
|
77
|
-
onClick: ({ cancel }) => {
|
|
78
|
-
if (interfaceFnCancel) {
|
|
79
|
-
interfaceFnCancel(unref(model), {
|
|
80
|
-
close: cancel,
|
|
81
|
-
})
|
|
82
|
-
}else {
|
|
83
|
-
cancel()
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
label: '确定',
|
|
89
|
-
valid: true,
|
|
90
|
-
onClick: async ({ cancel, hideLoading }) =>
|
|
91
|
-
interfaceFn
|
|
92
|
-
? await interfaceFn(unref(model), {
|
|
93
|
-
close: cancel,
|
|
94
|
-
hideLoading,
|
|
95
|
-
})
|
|
96
|
-
: cancel(),
|
|
97
|
-
},
|
|
98
|
-
]
|
|
99
|
-
|
|
100
|
-
action
|
|
101
|
-
|| defaultAction.forEach((v, i) => {
|
|
102
|
-
actionLoading[i] = false
|
|
103
|
-
})
|
|
104
|
-
const titleRender
|
|
105
|
-
= typeof titleFull === 'function'
|
|
106
|
-
? () => titleFull(defaultModeEnum[mode]?.sub)
|
|
107
|
-
: titleFull
|
|
108
|
-
|
|
109
|
-
const d = $dialog.create({
|
|
110
|
-
type: 'info',
|
|
111
|
-
...dialogDefaultOption,
|
|
112
|
-
...(!noTitle
|
|
113
|
-
? { title: titleRender || (defaultModeEnum[mode]?.sub ?? '') + title }
|
|
114
|
-
: {}),
|
|
115
|
-
style: {
|
|
116
|
-
width: '500px',
|
|
117
|
-
},
|
|
118
|
-
content: () => (
|
|
119
|
-
<DataForm
|
|
120
|
-
ref={v => {
|
|
121
|
-
formRef.value = v
|
|
122
|
-
}}
|
|
123
|
-
options={options}
|
|
124
|
-
v-model:value={model.value}
|
|
125
|
-
isNo={isNo}
|
|
126
|
-
read={read ?? isRead}
|
|
127
|
-
labelField={labelField}
|
|
128
|
-
formProps={formProps}
|
|
129
|
-
contentStyle={contentStyle}
|
|
130
|
-
dialog
|
|
131
|
-
/>
|
|
132
|
-
),
|
|
133
|
-
action: !(read ?? isRead)
|
|
134
|
-
? typeof action === 'function'
|
|
135
|
-
? () => action({ formRef, data: unref(model), d, close: cancel })
|
|
136
|
-
: () => (
|
|
137
|
-
<NSpace
|
|
138
|
-
{...defaultActionProps}
|
|
139
|
-
{...actionProps}
|
|
140
|
-
style={{
|
|
141
|
-
...defaultActionProps?.style,
|
|
142
|
-
...(actionProps?.style || {}),
|
|
143
|
-
}}
|
|
144
|
-
>
|
|
145
|
-
{(action || defaultAction).map((v, i) =>
|
|
146
|
-
v?.render
|
|
147
|
-
? (
|
|
148
|
-
v?.render?.()
|
|
149
|
-
)
|
|
150
|
-
: (
|
|
151
|
-
<NButton
|
|
152
|
-
type="primary" ghost={v.mode === 'cancel'} {...({ ...v?.props, ...actionProps?.buttonProps } || {})}
|
|
153
|
-
style={{ ...defaultButtonStyle, ...(v?.style || {}) }}
|
|
154
|
-
loading={actionLoading[i]}
|
|
155
|
-
onClick={async () => {
|
|
156
|
-
if (v.mode === 'cancel') {
|
|
157
|
-
d.destroy()
|
|
158
|
-
}
|
|
159
|
-
else {
|
|
160
|
-
const showLoading = () => (actionLoading[i] = true)
|
|
161
|
-
const hideLoading = () => (actionLoading[i] = false)
|
|
162
|
-
if (v?.loading)
|
|
163
|
-
showLoading()
|
|
164
|
-
try {
|
|
165
|
-
console.log('model', unref(model));
|
|
166
|
-
|
|
167
|
-
if (v?.valid)
|
|
168
|
-
await validate()
|
|
169
|
-
console.log(v?.valid)
|
|
170
|
-
if (v?.valid || v?.loading)
|
|
171
|
-
showLoading()
|
|
172
|
-
await v?.onClick({
|
|
173
|
-
model: unref(model),
|
|
174
|
-
comfirm,
|
|
175
|
-
cancel,
|
|
176
|
-
validate,
|
|
177
|
-
showLoading,
|
|
178
|
-
hideLoading,
|
|
179
|
-
})
|
|
180
|
-
}
|
|
181
|
-
catch (e) {
|
|
182
|
-
console.log(e)
|
|
183
|
-
}
|
|
184
|
-
finally {
|
|
185
|
-
if (v?.valid || v?.loading)
|
|
186
|
-
hideLoading()
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}}
|
|
190
|
-
>
|
|
191
|
-
{v.label || ''}
|
|
192
|
-
</NButton>
|
|
193
|
-
),
|
|
194
|
-
)}
|
|
195
|
-
</NSpace>
|
|
196
|
-
)
|
|
197
|
-
: null,
|
|
198
|
-
// ...readButton.value,
|
|
199
|
-
...dialogProps,
|
|
200
|
-
class: `core-dialog ${ unref(read) ? 'core-dialog-read' : ''} ${dialogProps?.class || ''}`,
|
|
201
|
-
})
|
|
202
|
-
|
|
203
|
-
function cancel() {
|
|
204
|
-
console.log('取消', model.value)
|
|
205
|
-
|
|
206
|
-
d?.destroy()
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
async function validate(arr = []) {
|
|
210
|
-
console.log('开启验证')
|
|
211
|
-
await formRef.value?.valid()
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
async function comfirm(fn) {
|
|
215
|
-
return fn && fn()
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// onBeforeUnmount(() => {
|
|
219
|
-
// console.log('commomDialog end')
|
|
220
|
-
// cancel()
|
|
221
|
-
// })
|
|
222
|
-
|
|
223
|
-
return {
|
|
224
|
-
cancel,
|
|
225
|
-
setValue: (v, str) =>
|
|
226
|
-
str ? (model.value[str] = v) : (model.value = { ...model.value, ...v }),
|
|
227
|
-
model: unref(model),
|
|
228
|
-
modeEnum: defaultModeEnum,
|
|
229
|
-
}
|
|
230
|
-
}
|