iov-pro-components 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/.eslintignore +5 -0
- package/.eslintrc.js +192 -0
- package/.gitignore +3 -0
- package/README.md +4 -0
- package/babel.config.js +5 -0
- package/docs/.vuepress/config.js +169 -0
- package/docs/.vuepress/styles/index.styl +62 -0
- package/docs/.vuepress/styles/palette.styl +20 -0
- package/docs/.vuepress/theme/enhanceApp.js +100 -0
- package/docs/.vuepress/theme/index.js +3 -0
- package/docs/README.md +13 -0
- package/docs/components/description.md +519 -0
- package/docs/components/dialog-select.md +91 -0
- package/docs/components/display.md +36 -0
- package/docs/components/enums.md +33 -0
- package/docs/components/icon.md +406 -0
- package/docs/components/link-group.md +39 -0
- package/docs/components/page-detail.md +48 -0
- package/docs/components/page-module.md +51 -0
- package/docs/components/pro-form.md +958 -0
- package/docs/components/pro-table.md +683 -0
- package/docs/components/request.md +44 -0
- package/docs/components/search-table.md +963 -0
- package/docs/components/space.md +35 -0
- package/docs/components/sub-title.md +24 -0
- package/docs/components/submit-module.md +24 -0
- package/docs/template/add.md +124 -0
- package/docs/template/confirm.md +28 -0
- package/docs/template/detail.md +240 -0
- package/docs/template/dialog.md +339 -0
- package/docs/template/list.md +464 -0
- package/docs/template/tabs-mini.md +32 -0
- package/docs/template/tabs.md +32 -0
- package/jsconfig.json +19 -0
- package/lib/iov-pro-components.css +1 -0
- package/lib/iov-pro-components.min.js +7 -0
- package/lib/postcss.config.js +8 -0
- package/package.json +75 -0
- package/patches/vue-server-renderer+2.7.16.patch +13 -0
- package/rollup.config.mjs +79 -0
- package/src/App.vue +103 -0
- package/src/main.js +33 -0
- package/src/packages/column-tooltip/index.js +7 -0
- package/src/packages/column-tooltip/src/main.vue +127 -0
- package/src/packages/description/index.js +7 -0
- package/src/packages/description/src/main.vue +375 -0
- package/src/packages/description/src/text.vue +103 -0
- package/src/packages/dialog-select/index.js +7 -0
- package/src/packages/dialog-select/src/main.vue +308 -0
- package/src/packages/display/index.js +7 -0
- package/src/packages/display/src/main.vue +44 -0
- package/src/packages/enums/index.js +7 -0
- package/src/packages/enums/src/main.vue +23 -0
- package/src/packages/export/index.js +7 -0
- package/src/packages/export/src/main.vue +316 -0
- package/src/packages/fixed-button-group/index.js +7 -0
- package/src/packages/fixed-button-group/src/main.vue +104 -0
- package/src/packages/form/index.js +7 -0
- package/src/packages/form/src/collapse.vue +149 -0
- package/src/packages/form/src/main.vue +1190 -0
- package/src/packages/form-collapse/index.js +7 -0
- package/src/packages/index.js +86 -0
- package/src/packages/link-group/index.js +7 -0
- package/src/packages/link-group/src/main.vue +52 -0
- package/src/packages/page-detail/index.js +7 -0
- package/src/packages/page-detail/src/main.vue +123 -0
- package/src/packages/page-module/index.js +7 -0
- package/src/packages/page-module/src/main.vue +56 -0
- package/src/packages/preview/index.js +7 -0
- package/src/packages/preview/src/eval-image-viewer.js +50 -0
- package/src/packages/preview/src/image-viewer.vue +366 -0
- package/src/packages/preview/src/main.vue +97 -0
- package/src/packages/request/index.js +7 -0
- package/src/packages/request/src/main.vue +125 -0
- package/src/packages/search-table/index.js +7 -0
- package/src/packages/search-table/src/inner-tabs.vue +237 -0
- package/src/packages/search-table/src/main.vue +472 -0
- package/src/packages/search-table/src/outer-tabs.vue +45 -0
- package/src/packages/search-table-inner-tabs/index.js +7 -0
- package/src/packages/search-table-outer-tabs/index.js +7 -0
- package/src/packages/space/index.js +7 -0
- package/src/packages/space/src/main.vue +74 -0
- package/src/packages/sub-title/index.js +7 -0
- package/src/packages/sub-title/src/main.vue +70 -0
- package/src/packages/submit-module/index.js +7 -0
- package/src/packages/submit-module/src/main.vue +67 -0
- package/src/packages/table/index.js +7 -0
- package/src/packages/table/src/filter.vue +89 -0
- package/src/packages/table/src/main.vue +668 -0
- package/src/packages/table/src/search.vue +90 -0
- package/src/packages/table/src/sort.vue +118 -0
- package/src/packages/theme/index.scss +15 -0
- package/src/packages/theme/src/column-tooltip.scss +23 -0
- package/src/packages/theme/src/common/color.scss +134 -0
- package/src/packages/theme/src/description.scss +56 -0
- package/src/packages/theme/src/dialog-select.scss +32 -0
- package/src/packages/theme/src/fixed-button-group.scss +25 -0
- package/src/packages/theme/src/form.scss +11 -0
- package/src/packages/theme/src/link-group.scss +43 -0
- package/src/packages/theme/src/page-detail.scss +61 -0
- package/src/packages/theme/src/page-module.scss +46 -0
- package/src/packages/theme/src/preview.scss +67 -0
- package/src/packages/theme/src/search-table.scss +185 -0
- package/src/packages/theme/src/space.scss +12 -0
- package/src/packages/theme/src/sub-title.scss +47 -0
- package/src/packages/theme/src/submit-module.scss +13 -0
- package/src/packages/theme/src/table.scss +129 -0
- package/src/packages/theme/src/toolbar.scss +109 -0
- package/src/packages/toolbar/index.js +7 -0
- package/src/packages/toolbar/src/main.vue +126 -0
- package/src/packages/toolbar/src/setting.vue +217 -0
- package/src/packages/toolbar/src/style.vue +68 -0
- package/src/packages/toolbar/src/zoom.vue +65 -0
- package/src/router.js +83 -0
- package/src/utils/config-center.js +218 -0
- package/src/utils/function-eval.js +84 -0
- package/src/utils/index.js +104 -0
- package/src/views/column-tooltip.vue +37 -0
- package/src/views/components/OtherSelect.vue +18 -0
- package/src/views/description.vue +60 -0
- package/src/views/detail.vue +146 -0
- package/src/views/directive/number.js +82 -0
- package/src/views/enums.vue +22 -0
- package/src/views/export.vue +9 -0
- package/src/views/form-collapse.vue +185 -0
- package/src/views/form.vue +402 -0
- package/src/views/link-group.vue +16 -0
- package/src/views/preview.vue +33 -0
- package/src/views/request.vue +56 -0
- package/src/views/search-table.vue +297 -0
- package/src/views/table.vue +145 -0
- package/src/views/toolbar.vue +30 -0
- package/vue.config.js +22 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 执行函数
|
|
3
|
+
* @param {Object | Function} inject 需要注入的属性
|
|
4
|
+
* @time 2024-10-31 15:52:08
|
|
5
|
+
*/
|
|
6
|
+
function functionEval(inject = {}) {
|
|
7
|
+
/**
|
|
8
|
+
* 将注入的key转换成value
|
|
9
|
+
* @param {Object} map 映射的数据
|
|
10
|
+
* @param {String} key 当前key
|
|
11
|
+
* @time 2024-11-01 14:52:01
|
|
12
|
+
*/
|
|
13
|
+
const injectKeyToValue = map => key => {
|
|
14
|
+
// 如果当前是字符串,则取出原始值
|
|
15
|
+
if (typeof key === 'string') {
|
|
16
|
+
return map[key]
|
|
17
|
+
}
|
|
18
|
+
// 如果当前是对象
|
|
19
|
+
if (key instanceof Object) {
|
|
20
|
+
return '__value' in key ? key.__value : key
|
|
21
|
+
}
|
|
22
|
+
return null
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 返回需要可执行的方法
|
|
27
|
+
* @param {Function} fn 可执行的方法
|
|
28
|
+
* @param {Array} injectKeys 需要注入的属性
|
|
29
|
+
* @time 2024-10-31 15:54:11
|
|
30
|
+
*/
|
|
31
|
+
return function(fn) {
|
|
32
|
+
// 转换后的方法
|
|
33
|
+
let evalFn = null
|
|
34
|
+
// 需要注入的属性集合
|
|
35
|
+
let injectValues = []
|
|
36
|
+
// 获取需要注入的属性值
|
|
37
|
+
const injectMaps = inject instanceof Function ? inject() : inject
|
|
38
|
+
// 如果当前是函数
|
|
39
|
+
if (fn instanceof Function) {
|
|
40
|
+
// 重新指向this
|
|
41
|
+
evalFn = fn.bind(null)
|
|
42
|
+
} else if (fn instanceof Object) {
|
|
43
|
+
// 方法需要注入的keys
|
|
44
|
+
const handlerInjectKeys = [...(fn.inject || [])]
|
|
45
|
+
// 如果是可执行的方法
|
|
46
|
+
if (fn.handler instanceof Function) {
|
|
47
|
+
evalFn = fn.handler.bind(null)
|
|
48
|
+
} else if (typeof fn.handler === 'string') {
|
|
49
|
+
evalFn = new Function(
|
|
50
|
+
...handlerInjectKeys,
|
|
51
|
+
fn.handler
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
// 获取需要注入的属性值
|
|
55
|
+
injectValues = handlerInjectKeys.map(injectKeyToValue(injectMaps))
|
|
56
|
+
}
|
|
57
|
+
// 如果有回调方法,则直接执行
|
|
58
|
+
return (...args) => evalFn ? evalFn(...args, ...injectValues) : null
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* 是否是可转换的函数
|
|
64
|
+
* @param {Object|Function} 参数说明
|
|
65
|
+
* @param {参数类型} data 参数说明
|
|
66
|
+
* @return {返回类型} data 返回说明
|
|
67
|
+
* @time 2024-11-11 18:04:00
|
|
68
|
+
*/
|
|
69
|
+
export const isEvalFunction = fn => {
|
|
70
|
+
// 如果当前不是对象或者函数
|
|
71
|
+
if (!(fn instanceof Object)) {
|
|
72
|
+
return false
|
|
73
|
+
}
|
|
74
|
+
// 如果当前是方法,则认为是可eval的方法
|
|
75
|
+
if (fn instanceof Function) {
|
|
76
|
+
return true
|
|
77
|
+
}
|
|
78
|
+
if (fn.handler instanceof Function && Array.isArray(fn.inject)) {
|
|
79
|
+
return true
|
|
80
|
+
}
|
|
81
|
+
return false
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export default functionEval
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import lodashGet from 'lodash/get'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 转换成大驼峰
|
|
5
|
+
* @param {String} tagName 参数说明
|
|
6
|
+
* @time 2024-10-29 10:33:46
|
|
7
|
+
*/
|
|
8
|
+
export const toUpperCamelCase = tagName => {
|
|
9
|
+
// 如果当前是字符串
|
|
10
|
+
if (typeof tagName === 'string') {
|
|
11
|
+
// 首字母大写,并且去掉中划线的格式
|
|
12
|
+
return tagName
|
|
13
|
+
// 首字母大写
|
|
14
|
+
.replace(/\b(\w)/, match => match.toUpperCase())
|
|
15
|
+
// 去掉中划线,并将中划线后的首字母大写
|
|
16
|
+
.replace(/-\w/g, match => match.slice(1).toUpperCase())
|
|
17
|
+
}
|
|
18
|
+
return tagName
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 从子元素中获取组件
|
|
23
|
+
* @param {Array} children 当前孩子节点
|
|
24
|
+
* @param {String} tagName 组件名
|
|
25
|
+
* @time 2024-11-14 14:46:45
|
|
26
|
+
*/
|
|
27
|
+
export const getComponentFromChildren = (children, tagName) => {
|
|
28
|
+
// 当前组件
|
|
29
|
+
let component = null
|
|
30
|
+
// 遍历所有子节点
|
|
31
|
+
children.forEach(child => {
|
|
32
|
+
// 如果没找到子节点
|
|
33
|
+
if (!component) {
|
|
34
|
+
// 如果子节点能匹配上
|
|
35
|
+
if (child.$options.name === tagName) {
|
|
36
|
+
component = child
|
|
37
|
+
} else {
|
|
38
|
+
component = getComponentFromChildren(child.$children, tagName)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
})
|
|
42
|
+
return component
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 是否是url链接
|
|
47
|
+
* @param {String} target 需要判断的字符
|
|
48
|
+
* @time 2024-11-19 11:08:26
|
|
49
|
+
*/
|
|
50
|
+
export const isUrl = target => {
|
|
51
|
+
// 如果非字符串类型
|
|
52
|
+
if (typeof target !== 'string') {
|
|
53
|
+
return false
|
|
54
|
+
}
|
|
55
|
+
return /^(https?:\/\/)?(www\.)?[a-z0-9.-]+\.[a-z]{2,}(\/[^\s]*)?$/i.test(target.toLowerCase()) || /^(\/[a-zA-Z]:|[a-zA-Z]:\\|\.\/|\.\.\/|\/)[a-zA-Z0-9\-_./\\]*$/.test(target.toLowerCase())
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 是否是base64格式的图片字符串
|
|
60
|
+
* @param {String} target 需要判断的字符
|
|
61
|
+
* @time 2024-12-20 15:55:53
|
|
62
|
+
*/
|
|
63
|
+
export const isBase64Image = target => {
|
|
64
|
+
return /^data:image\/.*;base64,/.test(target)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* 生成随机字符串
|
|
69
|
+
* @param {Number} length 随机字符串的长度
|
|
70
|
+
* @time 2024-11-19 11:33:07
|
|
71
|
+
*/
|
|
72
|
+
export const randomString = (length = 10) => {
|
|
73
|
+
// 所有字符串
|
|
74
|
+
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
|
|
75
|
+
// 当前结果
|
|
76
|
+
let result = ''
|
|
77
|
+
// 开始生成
|
|
78
|
+
for (let i = 0; i < length; i++) {
|
|
79
|
+
result += characters.charAt(Math.floor(Math.random() * characters.length))
|
|
80
|
+
}
|
|
81
|
+
return result
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* 将列的数据转换到行中
|
|
86
|
+
* @param {Array} cols 当前总数
|
|
87
|
+
* @time 2024-11-21 09:06:39
|
|
88
|
+
*/
|
|
89
|
+
export const splitColsToRow = (cols, key = 'span') => {
|
|
90
|
+
// 当前所在的索引
|
|
91
|
+
let index = 0
|
|
92
|
+
// 开始处理数据
|
|
93
|
+
return cols.reduce((memo, col) => {
|
|
94
|
+
// 当前栅格
|
|
95
|
+
const totalSpan = memo[index].reduce((memo, c) => (memo + lodashGet(c, key)), 0)
|
|
96
|
+
// 如果当前栅格大于24,则另起一行
|
|
97
|
+
if (totalSpan + lodashGet(col, key) > 24) {
|
|
98
|
+
memo[++index] = [col]
|
|
99
|
+
} else {
|
|
100
|
+
memo[index].push(col)
|
|
101
|
+
}
|
|
102
|
+
return memo
|
|
103
|
+
}, [[]])
|
|
104
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div style="width: 50%">
|
|
3
|
+
<iov-pro-column-tooltip
|
|
4
|
+
:data="DATA"
|
|
5
|
+
effect="light"
|
|
6
|
+
placement="top-start"
|
|
7
|
+
overflow="auto"
|
|
8
|
+
/>
|
|
9
|
+
</div>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<script>
|
|
13
|
+
const DATA = [
|
|
14
|
+
'key1: value1',
|
|
15
|
+
'key2: value2',
|
|
16
|
+
'key3: value3',
|
|
17
|
+
'key4: value4',
|
|
18
|
+
'key5: value5',
|
|
19
|
+
'key6: value6',
|
|
20
|
+
'key7: value7',
|
|
21
|
+
'key8: value8',
|
|
22
|
+
'key9: value9',
|
|
23
|
+
'key10: value10',
|
|
24
|
+
'key11: value11',
|
|
25
|
+
'key12: value12',
|
|
26
|
+
'key13: value13'
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
export default {
|
|
30
|
+
name: 'ColumnTooltipDemo',
|
|
31
|
+
data() {
|
|
32
|
+
return {
|
|
33
|
+
DATA
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
</script>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-select :value="value" placeholder="请选择值" @input="val => $emit('input', val)">
|
|
3
|
+
<el-option label="值1" value="1" />
|
|
4
|
+
<el-option label="值2" value="2" />
|
|
5
|
+
</el-select>
|
|
6
|
+
</template>
|
|
7
|
+
|
|
8
|
+
<script>
|
|
9
|
+
export default {
|
|
10
|
+
name: 'OtherSelect',
|
|
11
|
+
props: {
|
|
12
|
+
value: {
|
|
13
|
+
type: String,
|
|
14
|
+
default: ''
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
</script>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<iov-pro-preview>
|
|
3
|
+
<iov-pro-description
|
|
4
|
+
:data-source="dataSource"
|
|
5
|
+
:items="ITEMS"
|
|
6
|
+
>
|
|
7
|
+
<template #instro>
|
|
8
|
+
<div style="color: red;">{{ dataSource.instro }}</div>
|
|
9
|
+
</template>
|
|
10
|
+
</iov-pro-description>
|
|
11
|
+
</iov-pro-preview>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script>
|
|
15
|
+
const SEX = [
|
|
16
|
+
{ label: '男', value: 1 },
|
|
17
|
+
{ label: '女', value: 2 }
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
const TAGS = [
|
|
21
|
+
{ label: '性格好', value: 1, type: 'success' },
|
|
22
|
+
{ label: '是个好人', value: 2, type: 'success' },
|
|
23
|
+
{ label: '渣男', value: 3, type: 'danger' }
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
const ITEMS = [
|
|
27
|
+
{ label: '姓名', prop: 'name' },
|
|
28
|
+
{ label: '性别', prop: 'sex', type: 'enum', enums: SEX },
|
|
29
|
+
{ label: '年龄', prop: 'age' },
|
|
30
|
+
{ label: '标签', prop: 'tag', type: 'tag', enums: TAGS },
|
|
31
|
+
{ label: '简介', value: '查看详情', type: 'link', onClick: { handler: console.log, inject: ['$router'] }},
|
|
32
|
+
{ label: '文件', type: 'file', prop: 'file' },
|
|
33
|
+
{ label: '附件', type: 'link', prop: 'attachment' },
|
|
34
|
+
{ label: '自我介绍', prop: 'instro', type: 'slot', span: 24 }
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
export default {
|
|
38
|
+
name: 'DescriptionDemo',
|
|
39
|
+
data() {
|
|
40
|
+
return {
|
|
41
|
+
dataSource: {
|
|
42
|
+
name: '张三',
|
|
43
|
+
sex: 1,
|
|
44
|
+
age: 18,
|
|
45
|
+
tag: 1,
|
|
46
|
+
instro: '1111111',
|
|
47
|
+
file: [
|
|
48
|
+
{ name: '附件1.jpg', uuid: '1', isPrivate: true, url: 'https://prod-common-public.obs-helf.cucloud.cn/mall/goods/893f1000000000114669556' },
|
|
49
|
+
{ name: '附件2.JPG', uuid: '2', isPrivate: false, url: 'https://prod-common-public.obs-helf.cucloud.cn/mall/goods/bcaa1000000000114669571' }
|
|
50
|
+
],
|
|
51
|
+
attachment: [
|
|
52
|
+
{ name: '附件1', icon: 'el-icon-video-camera-solid' },
|
|
53
|
+
{ name: '附件2', icon: 'https://pic.rmb.bdstatic.com/bjh/news/8b97506ad15a7a495cefe17a0f7f9abf.gif' }
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
ITEMS
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
</script>
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="detail-page-demo">
|
|
3
|
+
<iov-pro-request
|
|
4
|
+
:api="queryPageData"
|
|
5
|
+
:params="params"
|
|
6
|
+
>
|
|
7
|
+
<template #default="{ data, loading }">
|
|
8
|
+
<iov-pro-space
|
|
9
|
+
v-loading.fullscreen.lock="loading"
|
|
10
|
+
element-loading-spinner="page-loading"
|
|
11
|
+
space="10"
|
|
12
|
+
>
|
|
13
|
+
<iov-pro-page-detail
|
|
14
|
+
name="应用详情 - 单点登录"
|
|
15
|
+
icon="1"
|
|
16
|
+
desc="租户ID"
|
|
17
|
+
>
|
|
18
|
+
<iov-pro-description
|
|
19
|
+
:data-source="data"
|
|
20
|
+
:items="DETAIL_ITEMS"
|
|
21
|
+
label-width="180px"
|
|
22
|
+
/>
|
|
23
|
+
<el-divider />
|
|
24
|
+
<iov-pro-sub-title
|
|
25
|
+
name="应用列表"
|
|
26
|
+
icon="1"
|
|
27
|
+
/>
|
|
28
|
+
<iov-pro-table
|
|
29
|
+
:data-source="data ? data.tableData : []"
|
|
30
|
+
:columns="TABLE_COLUMNS"
|
|
31
|
+
/>
|
|
32
|
+
</iov-pro-page-detail>
|
|
33
|
+
<iov-pro-page-module name="基本信息">
|
|
34
|
+
<iov-pro-description
|
|
35
|
+
:data-source="data"
|
|
36
|
+
:items="BASIC_LOGIN_ITEMS"
|
|
37
|
+
label-width="180px"
|
|
38
|
+
/>
|
|
39
|
+
</iov-pro-page-module>
|
|
40
|
+
<iov-pro-page-module name="登录信息">
|
|
41
|
+
<iov-pro-description
|
|
42
|
+
:data-source="data"
|
|
43
|
+
:items="SSO_LOGIN_ITEMS"
|
|
44
|
+
label-width="180px"
|
|
45
|
+
/>
|
|
46
|
+
</iov-pro-page-module>
|
|
47
|
+
</iov-pro-space>
|
|
48
|
+
</template>
|
|
49
|
+
</iov-pro-request>
|
|
50
|
+
<iov-pro-fixed-button-group height="88">
|
|
51
|
+
<el-button
|
|
52
|
+
size="small"
|
|
53
|
+
round
|
|
54
|
+
>取消</el-button>
|
|
55
|
+
<el-button
|
|
56
|
+
type="primary"
|
|
57
|
+
size="small"
|
|
58
|
+
round
|
|
59
|
+
>确定</el-button>
|
|
60
|
+
</iov-pro-fixed-button-group>
|
|
61
|
+
</div>
|
|
62
|
+
</template>
|
|
63
|
+
|
|
64
|
+
<script>
|
|
65
|
+
const DETAIL_ITEMS = [
|
|
66
|
+
{ label: 'clientID', prop: 'clientId' },
|
|
67
|
+
{ label: '是否接入单点登录', prop: 'isSso' }
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
const BASIC_LOGIN_ITEMS = [
|
|
71
|
+
{ label: '应用首页地址', prop: 'indexPageUrl' },
|
|
72
|
+
{ label: '外部appid', prop: 'openAppKey' },
|
|
73
|
+
{ label: '访问令牌有效期(秒)', prop: 'accessTokenTerm' }
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
// SSO登录配置
|
|
77
|
+
const SSO_LOGIN_ITEMS = [
|
|
78
|
+
{ label: '客户端id', prop: 'clientId' },
|
|
79
|
+
{ label: '客户端密钥', prop: 'clientSecret' }
|
|
80
|
+
]
|
|
81
|
+
|
|
82
|
+
const TABLE_COLUMNS = [
|
|
83
|
+
{ label: '应用ID', prop: 'appId' },
|
|
84
|
+
{ label: '应用名称', prop: 'appName' },
|
|
85
|
+
{ label: '是否接入单点登录', prop: 'isSso' },
|
|
86
|
+
{ label: '应用首页地址', prop: 'indexPageUrl' }
|
|
87
|
+
]
|
|
88
|
+
|
|
89
|
+
export default {
|
|
90
|
+
name: 'DetailPageDemo',
|
|
91
|
+
data() {
|
|
92
|
+
return {
|
|
93
|
+
DETAIL_ITEMS,
|
|
94
|
+
BASIC_LOGIN_ITEMS,
|
|
95
|
+
SSO_LOGIN_ITEMS,
|
|
96
|
+
TABLE_COLUMNS,
|
|
97
|
+
params: {
|
|
98
|
+
id: 111111
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
methods: {
|
|
103
|
+
queryPageData(params) {
|
|
104
|
+
return new Promise((resolve) => {
|
|
105
|
+
setTimeout(() => {
|
|
106
|
+
console.log('接口请求参数:', params)
|
|
107
|
+
resolve({
|
|
108
|
+
isSso: '是',
|
|
109
|
+
indexPageUrl: 'https://www.baidu.com/',
|
|
110
|
+
openAppKey: 'alll1091899sjj18981',
|
|
111
|
+
accessTokenTerm: '1800',
|
|
112
|
+
clientId: 'i129jk91289837372',
|
|
113
|
+
clientSecret: 'o19276734jdhey78',
|
|
114
|
+
tableData: [
|
|
115
|
+
{ appId: 1, appName: '小明', isSso: '是', indexPageUrl: 'https://www.baidu.com/' },
|
|
116
|
+
{ appId: 2, appName: '小红', isSso: '否', indexPageUrl: 'https://www.google.com/' },
|
|
117
|
+
{ appId: 3, appName: '小明', isSso: '是', indexPageUrl: 'https://www.baidu.com/' },
|
|
118
|
+
{ appId: 4, appName: '小红', isSso: '否', indexPageUrl: 'https://www.google.com/' },
|
|
119
|
+
{ appId: 5, appName: '小明', isSso: '是', indexPageUrl: 'https://www.baidu.com/' },
|
|
120
|
+
{ appId: 6, appName: '小红', isSso: '否', indexPageUrl: 'https://www.google.com/' },
|
|
121
|
+
{ appId: 7, appName: '小明', isSso: '是', indexPageUrl: 'https://www.baidu.com/' },
|
|
122
|
+
{ appId: 8, appName: '小红', isSso: '否', indexPageUrl: 'https://www.google.com/' },
|
|
123
|
+
{ appId: 9, appName: '小明', isSso: '是', indexPageUrl: 'https://www.baidu.com/' },
|
|
124
|
+
{ appId: 10, appName: '小红', isSso: '否', indexPageUrl: 'https://www.google.com/' },
|
|
125
|
+
{ appId: 11, appName: '小明', isSso: '是', indexPageUrl: 'https://www.baidu.com/' },
|
|
126
|
+
{ appId: 12, appName: '小红', isSso: '否', indexPageUrl: 'https://www.google.com/' },
|
|
127
|
+
{ appId: 13, appName: '小明', isSso: '是', indexPageUrl: 'https://www.baidu.com/' },
|
|
128
|
+
{ appId: 14, appName: '小红', isSso: '否', indexPageUrl: 'https://www.google.com/' },
|
|
129
|
+
{ appId: 15, appName: '小明', isSso: '是', indexPageUrl: 'https://www.baidu.com/' },
|
|
130
|
+
{ appId: 26, appName: '小红', isSso: '否', indexPageUrl: 'https://www.google.com/' }
|
|
131
|
+
]
|
|
132
|
+
})
|
|
133
|
+
}, 1000)
|
|
134
|
+
})
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
</script>
|
|
139
|
+
|
|
140
|
+
<style lang="scss">
|
|
141
|
+
.detail-page-demo {
|
|
142
|
+
background-color: lightgrey;
|
|
143
|
+
padding: 20px;
|
|
144
|
+
min-height: 600px;
|
|
145
|
+
}
|
|
146
|
+
</style>
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import Vue from 'vue'
|
|
2
|
+
import lodashGet from 'lodash/get'
|
|
3
|
+
|
|
4
|
+
function checkNumber(el, binding, vnode) {
|
|
5
|
+
const decimals = !isNaN(binding.value) ? binding.value : 2 // 默认小数位数为 2
|
|
6
|
+
|
|
7
|
+
// 构建正则表达式,支持 0 和空值,不允许以 '.' 开头,也不允许多个零开头
|
|
8
|
+
const regex = new RegExp(`^(?!\\.)[0-9]*(\\.\\d{0,${decimals}})?$|^$`)
|
|
9
|
+
|
|
10
|
+
// 获取 el-input 内部的 input 元素
|
|
11
|
+
const input = el.tagName === 'INPUT' ? el : el.querySelector('input')
|
|
12
|
+
if (input) {
|
|
13
|
+
let previousValue = '' // 记录上次合法的值
|
|
14
|
+
|
|
15
|
+
input.addEventListener('input', (event) => {
|
|
16
|
+
let currentValue = input.value
|
|
17
|
+
|
|
18
|
+
// 使用 slice 去除多余的零
|
|
19
|
+
if (/^0[0-9]/.test(currentValue)) {
|
|
20
|
+
currentValue = currentValue.slice(0, 1) // 保留一个零,移除其他零
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// 防止以小数点开头,例如 ".123" -> "0.123"
|
|
24
|
+
if (/^\./.test(currentValue)) {
|
|
25
|
+
currentValue = '0' + currentValue // 补全为 "0.123"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (+decimals === 0 && /^\d+\.$/.test(currentValue)) {
|
|
29
|
+
currentValue = currentValue.slice(0, -1)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 如果当前值合法,保存为上次合法值
|
|
33
|
+
if (regex.test(currentValue)) {
|
|
34
|
+
previousValue = currentValue
|
|
35
|
+
input.value = previousValue
|
|
36
|
+
} else {
|
|
37
|
+
// 如果不合法,恢复到上次合法值
|
|
38
|
+
const cursorPosition = input.selectionStart - 1 // 获取光标位置
|
|
39
|
+
input.value = previousValue // 恢复到合法值
|
|
40
|
+
|
|
41
|
+
// 修复光标位置
|
|
42
|
+
input.setSelectionRange(cursorPosition, cursorPosition)
|
|
43
|
+
|
|
44
|
+
// 手动触发 input 事件以更新 v-model
|
|
45
|
+
const event = new Event('input', { bubbles: true })
|
|
46
|
+
input.dispatchEvent(event)
|
|
47
|
+
}
|
|
48
|
+
// 如果当前正在合成,则关闭合成方法
|
|
49
|
+
if (lodashGet(vnode, 'componentInstance.isComposing')) {
|
|
50
|
+
// 设置当前未在合成
|
|
51
|
+
vnode.componentInstance.isComposing = false
|
|
52
|
+
vnode.componentInstance.handleInput(event)
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
input.addEventListener('blur', () => {
|
|
56
|
+
// 当前输入的值
|
|
57
|
+
const currentValue = input.value
|
|
58
|
+
// 如果当前输入的值以.结尾
|
|
59
|
+
if (/\.$/.test(currentValue)) {
|
|
60
|
+
previousValue = currentValue.slice(0, currentValue.length - 1)
|
|
61
|
+
input.value = previousValue
|
|
62
|
+
// 手动触发 input 事件以更新 v-model
|
|
63
|
+
const event = new Event('input', { bubbles: true })
|
|
64
|
+
input.dispatchEvent(event)
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// 注册自定义指令
|
|
71
|
+
Vue.directive('number', {
|
|
72
|
+
bind(el, binding, vnode) {
|
|
73
|
+
checkNumber(el, binding, vnode)
|
|
74
|
+
},
|
|
75
|
+
unbind(el) {
|
|
76
|
+
const input = el.tagName === 'INPUT' ? el : el.querySelector('input')
|
|
77
|
+
if (input) {
|
|
78
|
+
input.removeEventListener('input', () => {})
|
|
79
|
+
input.removeEventListener('blur', () => {})
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
})
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<iov-pro-enums
|
|
3
|
+
:value="1"
|
|
4
|
+
:enums="ENUMS"
|
|
5
|
+
/>
|
|
6
|
+
</template>
|
|
7
|
+
|
|
8
|
+
<script>
|
|
9
|
+
const ENUMS = [
|
|
10
|
+
{ label: '男', value: 1 },
|
|
11
|
+
{ label: '女', value: 2 }
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
export default {
|
|
15
|
+
name: 'EnumsDemo',
|
|
16
|
+
data() {
|
|
17
|
+
return {
|
|
18
|
+
ENUMS
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
</script>
|