web-component-gallery 2.3.6 → 2.3.8
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/dist/index.umd.js +1 -1
- package/dist/js.umd.js +1 -1
- package/lib/browse/index.jsx +75 -132
- package/lib/browse/style/index.less +9 -0
- package/lib/form-comp/ASelectCustom.vue +5 -5
- package/lib/form-comp/AUpload.vue +146 -85
- package/lib/form-comp/style/ARangePicker.less +2 -2
- package/lib/form-comp/style/ASelectCustom.less +32 -8
- package/lib/form-comp/style/AUpload.less +14 -11
- package/lib/model/style/index.less +4 -7
- package/lib/model/utils/render.js +2 -2
- package/lib/search/index.vue +1 -1
- package/lib/search/style/index.less +25 -25
- package/package.json +1 -1
- package/utils/Axios.js +1 -1
- package/utils/File.js +146 -0
- package/utils/Filter.js +590 -133
- package/utils/Tree.js +13 -12
- package/utils/Utils.js +41 -11
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
.
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
.a-upload {
|
|
2
|
+
&__tips {
|
|
3
|
+
color: @error-color;
|
|
4
|
+
line-height: @line-height-base;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
&--text > &__tips {
|
|
8
|
+
margin-top: 8px;
|
|
6
9
|
}
|
|
7
10
|
|
|
8
11
|
.ant-upload {
|
|
9
12
|
background: transparent;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
}
|
|
13
|
+
|
|
14
|
+
&-picture-card-wrapper {
|
|
15
|
+
display: flex;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -9,13 +9,6 @@
|
|
|
9
9
|
width: 100%;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
// 统一设置表单控件宽度
|
|
13
|
-
.ant-select,
|
|
14
|
-
.ant-input-number,
|
|
15
|
-
.ant-calendar-picker {
|
|
16
|
-
width: 100%;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
12
|
.ant-radio-group {
|
|
20
13
|
line-height: @input-height-lg;
|
|
21
14
|
}
|
|
@@ -23,6 +16,10 @@
|
|
|
23
16
|
.ant-form-item-children {
|
|
24
17
|
display: flex;
|
|
25
18
|
align-items: center;
|
|
19
|
+
|
|
20
|
+
& > * {
|
|
21
|
+
width: 100%;
|
|
22
|
+
}
|
|
26
23
|
}
|
|
27
24
|
|
|
28
25
|
.FormLine {
|
|
@@ -13,9 +13,9 @@ const FormModelItem = FormModel.Item
|
|
|
13
13
|
export function getFormWidth(child, layoutSize, gap = 24) {
|
|
14
14
|
const width = (100 / layoutSize) * (child.size ?? 1)
|
|
15
15
|
if (this.layout === 'vertical') {
|
|
16
|
-
return `
|
|
16
|
+
return `width: calc(${width}% - ${gap}px); margin-right: ${gap}px;`
|
|
17
17
|
}
|
|
18
|
-
return `
|
|
18
|
+
return `width: ${width}%;`
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/**
|
package/lib/search/index.vue
CHANGED
|
@@ -132,7 +132,7 @@ export default {
|
|
|
132
132
|
middle: '16px',
|
|
133
133
|
default: '24px'
|
|
134
134
|
}
|
|
135
|
-
return `
|
|
135
|
+
return `width: calc((${(100 / this.matchMediaSize) * (e.size ?? 1)}% - ${
|
|
136
136
|
gap[this.searchStyle]
|
|
137
137
|
})); margin-right: ${gap[this.searchStyle]};`
|
|
138
138
|
},
|
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
@import '../../form-comp/style/index.less';
|
|
2
2
|
|
|
3
3
|
.WebComponentFormSearch {
|
|
4
|
-
|
|
5
|
-
.flex-mixins(@justify: flex-start);
|
|
6
|
-
|
|
7
|
-
.ant-form-item {
|
|
8
|
-
display: inline-flex;
|
|
9
|
-
margin-right: unset;
|
|
10
|
-
|
|
11
|
-
.ant-form-item-label {
|
|
12
|
-
min-width: 70px;
|
|
13
|
-
max-width: 100px;
|
|
14
|
-
text-align: right;
|
|
15
|
-
}
|
|
4
|
+
.flex-mixins(@justify: flex-start, @gap: 16px 0);
|
|
16
5
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
6
|
+
.ant-form-item {
|
|
7
|
+
display: inline-flex;
|
|
8
|
+
margin-right: 0;
|
|
9
|
+
|
|
10
|
+
.ant-form-item-label {
|
|
11
|
+
min-width: 70px;
|
|
12
|
+
max-width: 100px;
|
|
13
|
+
text-align: right;
|
|
26
14
|
}
|
|
27
|
-
|
|
28
|
-
|
|
15
|
+
|
|
16
|
+
.ant-form-item-control-wrapper {
|
|
29
17
|
flex: 1;
|
|
30
|
-
|
|
31
|
-
|
|
18
|
+
min-width: 0;
|
|
19
|
+
display: inline-flex;
|
|
20
|
+
align-items: center;
|
|
32
21
|
}
|
|
22
|
+
|
|
23
|
+
&-control,
|
|
24
|
+
&-children > * {
|
|
25
|
+
width: 100%;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
&__Actions {
|
|
30
|
+
flex: 1;
|
|
31
|
+
text-align: right;
|
|
32
|
+
}
|
|
33
33
|
}
|
package/package.json
CHANGED
package/utils/Axios.js
CHANGED
|
@@ -98,7 +98,7 @@ function handleResponse(response, options, manager) {
|
|
|
98
98
|
|
|
99
99
|
if (config.responseType === 'blob') return { data, headers }
|
|
100
100
|
if (data.code && data.code !== 200) return handleError(data, options)
|
|
101
|
-
return data?.data
|
|
101
|
+
return data?.data
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
function handleError(error, options, manager) {
|
package/utils/File.js
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { Base64 } from './Base64'
|
|
2
|
+
import { transferData } from './Filter'
|
|
3
|
+
|
|
4
|
+
// 文件类型常量
|
|
5
|
+
export const FILE_TYPES = {
|
|
6
|
+
PICTURE: ['gif', 'jpeg', 'png', 'jpg', 'bmp', 'tif', 'svg', 'psd', 'raw', 'wmf', 'webp', 'apng'],
|
|
7
|
+
AUDIO: ['mp3', 'wma', 'flac', 'aac', 'mmf', 'amr', 'm4a', 'm4r', 'ogg', 'mp2', 'wav'],
|
|
8
|
+
VIDEO: ['avi', 'flv', 'mpg', 'mpeg', 'mpe', 'm1v', 'm2v', 'mpv2', 'mp2v', 'dat', 'ts', 'tp',
|
|
9
|
+
'tpr', 'pva', 'pss', 'mp4', 'm4v', 'm4p', 'm4b', '3gp', '3gpp', '3g2', '3gp2',
|
|
10
|
+
'ogg', 'mov', 'qt', 'amr', 'rm', 'ram', 'rmvb', 'rpm'],
|
|
11
|
+
DOCUMENT: ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf', 'txt', 'csv', 'rtf']
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// 文件类型映射
|
|
15
|
+
const TYPE_MAP = {
|
|
16
|
+
image: 'PICTURE',
|
|
17
|
+
audio: 'AUDIO',
|
|
18
|
+
video: 'VIDEO',
|
|
19
|
+
application: 'DOCUMENT'
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* 获取文件类型(图片、视频、音频、文档)
|
|
24
|
+
* @param {string} url - 文件 URL 或文件名
|
|
25
|
+
* @param {string} contentType - MIME type (可选)
|
|
26
|
+
* @returns {string} 文件类型:'PICTURE' | 'AUDIO' | 'VIDEO' | 'DOCUMENT' | 'OTHER'
|
|
27
|
+
*/
|
|
28
|
+
export function getFileType(url, contentType = '') {
|
|
29
|
+
if (!url) return 'OTHER'
|
|
30
|
+
|
|
31
|
+
// 优先使用 contentType 判断
|
|
32
|
+
if (contentType) {
|
|
33
|
+
const mainType = contentType.split('/')[0].toLowerCase()
|
|
34
|
+
if (TYPE_MAP[mainType]) return TYPE_MAP[mainType]
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Base64 图片处理
|
|
38
|
+
if (url.startsWith('data:image')) return 'PICTURE'
|
|
39
|
+
|
|
40
|
+
// 从 URL 提取扩展名判断
|
|
41
|
+
const ext = url.slice(url.lastIndexOf('.') + 1).toLowerCase()
|
|
42
|
+
|
|
43
|
+
if (FILE_TYPES.PICTURE.includes(ext)) return 'PICTURE'
|
|
44
|
+
if (FILE_TYPES.AUDIO.includes(ext)) return 'AUDIO'
|
|
45
|
+
if (FILE_TYPES.VIDEO.includes(ext)) return 'VIDEO'
|
|
46
|
+
if (FILE_TYPES.DOCUMENT.includes(ext)) return 'DOCUMENT'
|
|
47
|
+
|
|
48
|
+
return 'OTHER'
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* 文件预览处理
|
|
53
|
+
* @param {Object} file - 当前文件对象 {url, contentType, ...}
|
|
54
|
+
* @param {Array|string} fileList - 文件列表(数组或 URL 字符串)
|
|
55
|
+
* @param {Object} ctx - 上下文对象,包含 $viewerApi, $postM, $https/httpsUrl
|
|
56
|
+
*/
|
|
57
|
+
export function previewFile(file, fileList, ctx) {
|
|
58
|
+
// 基础校验:文件必须存在且包含 url
|
|
59
|
+
if (!file?.url) return
|
|
60
|
+
|
|
61
|
+
const { $viewerApi, $postM, $https, httpsUrl } = ctx
|
|
62
|
+
|
|
63
|
+
// 智能格式化文件数据(如果已格式化则直接使用)
|
|
64
|
+
const formattedFiles = formatFileData(fileList, $https || httpsUrl)
|
|
65
|
+
|
|
66
|
+
const { id, url, contentType } = file
|
|
67
|
+
// 获取文件类型(PICTURE | AUDIO | VIDEO | DOCUMENT | OTHER)
|
|
68
|
+
const type = getFileType(url, contentType)
|
|
69
|
+
|
|
70
|
+
// 场景 1: 图片预览,使用 v-viewer 组件
|
|
71
|
+
if (type === 'PICTURE') {
|
|
72
|
+
// 筛选出所有图片类型的文件用于轮播
|
|
73
|
+
const images = formattedFiles.filter(f => getFileType(f.url, f.contentType) === 'PICTURE')
|
|
74
|
+
try {
|
|
75
|
+
$viewerApi({
|
|
76
|
+
options: {
|
|
77
|
+
url: 'url', // 指定图片 URL 字段名
|
|
78
|
+
toolbar: true, // 显示工具栏
|
|
79
|
+
initialViewIndex: images.findIndex(f => (file.id && f.id === file.id) || f.url === url) || 0 // 优先比对 id,id 不存在则比对 url
|
|
80
|
+
},
|
|
81
|
+
images
|
|
82
|
+
})
|
|
83
|
+
} catch (e) {
|
|
84
|
+
console.error('未安装 v-viewer@1.6.4 组件库,请执行 yarn add v-viewer@1.6.4')
|
|
85
|
+
}
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// 场景 2: 其他类型文件(视频/音频/文档),通过自定义弹窗预览
|
|
90
|
+
$postM({
|
|
91
|
+
type: 'customModal',
|
|
92
|
+
name: 'browse',
|
|
93
|
+
params: { data: file }
|
|
94
|
+
})
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* 格式化文件数据
|
|
99
|
+
* @param {string|Array|Object} data - 文件数据(字符串、数组或对象)
|
|
100
|
+
* @param {Object} httpsConfig - HTTPS 配置对象
|
|
101
|
+
* @returns {Array} 格式化后的文件数组 [{url, name, contentType, ...}]
|
|
102
|
+
*/
|
|
103
|
+
export function formatFileData(data, httpsConfig) {
|
|
104
|
+
// 智能解析数据(自动转换类型)
|
|
105
|
+
let files = transferData(data)
|
|
106
|
+
if (!files) return []
|
|
107
|
+
|
|
108
|
+
// 字符串处理:转为对象数组
|
|
109
|
+
if (typeof files === 'string') files = [{ url: files }]
|
|
110
|
+
|
|
111
|
+
// 对象处理:转为对象数组
|
|
112
|
+
if (typeof files === 'object' && !Array.isArray(files)) files = [files]
|
|
113
|
+
|
|
114
|
+
// 解构 URL 配置项
|
|
115
|
+
const { FILEURL, KKFILEURL, OVERVIEWFILEURL } = httpsConfig || {}
|
|
116
|
+
|
|
117
|
+
// 校验必要的 URL 配置
|
|
118
|
+
if (!FILEURL || !KKFILEURL || !OVERVIEWFILEURL) return files
|
|
119
|
+
|
|
120
|
+
// 处理数组中的每一项数据
|
|
121
|
+
return files.map(dataItem => {
|
|
122
|
+
// 确保每项都是对象格式
|
|
123
|
+
if (typeof dataItem === 'string') dataItem = { url: dataItem }
|
|
124
|
+
|
|
125
|
+
const { url } = dataItem
|
|
126
|
+
|
|
127
|
+
// URL 不存在,过滤掉
|
|
128
|
+
if (!url) return null
|
|
129
|
+
|
|
130
|
+
// 已是完整 URL (http/https/Base64),直接返回
|
|
131
|
+
if (url.startsWith('http') || url.startsWith('data:image')) {
|
|
132
|
+
return dataItem
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// 构造完整 URL
|
|
136
|
+
const isDocument = getFileType(url) === 'DOCUMENT'
|
|
137
|
+
const baseUrl = isDocument
|
|
138
|
+
? `${KKFILEURL}${encodeURIComponent(Base64.encode(`${OVERVIEWFILEURL}${url}`))}`
|
|
139
|
+
: `${FILEURL}${url}`
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
...dataItem,
|
|
143
|
+
url: baseUrl
|
|
144
|
+
}
|
|
145
|
+
}).filter(Boolean)
|
|
146
|
+
}
|