@sl-material/sl-import 1.0.0-beta0
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/LICENSE +21 -0
- package/README.md +486 -0
- package/index.d.ts +456 -0
- package/package.json +38 -0
- package/sl-import.cjs.js +2 -0
- package/sl-import.es.js +4095 -0
- package/sl-import.umd.umd.js +1573 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 @sl-material/sl-import
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
# @sl-material/sl-import
|
|
2
|
+
|
|
3
|
+
批量导入弹窗组件,支持多种导入模板配置、文件分片上传、品牌选择、图片比例选择等功能。
|
|
4
|
+
|
|
5
|
+
## 特性
|
|
6
|
+
|
|
7
|
+
- **多种模板类型** - 内置 5 种预设模板,支持自定义配置
|
|
8
|
+
- **文件分片上传** - 支持大文件分片上传,自动合并
|
|
9
|
+
- **多文件上传** - 支持批量文件上传,横向滚动列表展示
|
|
10
|
+
- **上传时机控制** - 支持立即上传和延迟上传两种模式
|
|
11
|
+
- **品牌选择** - 支持静态数据或异步加载品牌列表
|
|
12
|
+
- **图片比例选择** - 支持配置图片裁剪比例选项
|
|
13
|
+
- **日期范围选择** - 支持月份和日期范围选择
|
|
14
|
+
- **纯原生实现** - 不依赖 Vue/React 等框架,可在任何环境使用
|
|
15
|
+
- **TypeScript 支持** - 完整的类型定义
|
|
16
|
+
- **国际化支持** - 内置多语言支持
|
|
17
|
+
|
|
18
|
+
## 安装
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install @sl-material/sl-import
|
|
22
|
+
# 或
|
|
23
|
+
yarn add @sl-material/sl-import
|
|
24
|
+
# 或
|
|
25
|
+
pnpm add @sl-material/sl-import
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 使用方式
|
|
29
|
+
|
|
30
|
+
### ES 模块
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
import { ImportDialog } from "@sl-material/sl-import";
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### CommonJS
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
const { ImportDialog } = require("@sl-material/sl-import");
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
> **注意**:CSS 样式已自动内联到 JS 文件中,无需手动导入 CSS 文件。
|
|
43
|
+
|
|
44
|
+
## 快速开始
|
|
45
|
+
|
|
46
|
+
### 基础使用
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import { ImportDialog, TemplateTypeEnum } from "@sl-material/sl-import";
|
|
50
|
+
|
|
51
|
+
// 使用静态方法(推荐)
|
|
52
|
+
try {
|
|
53
|
+
const result = await ImportDialog.open({
|
|
54
|
+
title: "批量导入",
|
|
55
|
+
templateType: TemplateTypeEnum.BASE,
|
|
56
|
+
tips: ["提示信息 1", "提示信息 2"],
|
|
57
|
+
onConfirm: async (data) => {
|
|
58
|
+
console.log("导入数据:", data);
|
|
59
|
+
return { success: true };
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
console.log("导入成功:", result);
|
|
63
|
+
} catch (error) {
|
|
64
|
+
console.log("用户取消导入");
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 多文件导入
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
import { ImportDialog, TemplateTypeEnum } from "@sl-material/sl-import";
|
|
72
|
+
|
|
73
|
+
// 使用静态方法(推荐)
|
|
74
|
+
try {
|
|
75
|
+
const result = await ImportDialog.open({
|
|
76
|
+
title: "批量导入",
|
|
77
|
+
templateType: TemplateTypeEnum.BASE,
|
|
78
|
+
tips: ["提示信息 1", "提示信息 2"],
|
|
79
|
+
uploadConfig: {
|
|
80
|
+
multiple: true
|
|
81
|
+
}
|
|
82
|
+
onConfirm: async (data) => {
|
|
83
|
+
console.log("导入数据:", data);
|
|
84
|
+
return { success: true };
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
console.log("导入成功:", result);
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.log("用户取消导入");
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 国际化,传入表单数据
|
|
94
|
+
|
|
95
|
+
```vue
|
|
96
|
+
<script setup lang="ts">
|
|
97
|
+
import { ImportDialog, TemplateTypeEnum } from "@sl-material/sl-import";
|
|
98
|
+
|
|
99
|
+
const handleImport = async () => {
|
|
100
|
+
try {
|
|
101
|
+
const result = await ImportDialog.open({
|
|
102
|
+
title: "导入商品",
|
|
103
|
+
templateType: TemplateTypeEnum.TEMPLATE1,
|
|
104
|
+
locale: I18nLocaleEnum.ZH_CN,
|
|
105
|
+
brandData: [
|
|
106
|
+
{ label: "品牌 A", value: 1 },
|
|
107
|
+
{ label: "品牌 B", value: 2 },
|
|
108
|
+
],
|
|
109
|
+
onConfirm: async (data) => {
|
|
110
|
+
return { success: true };
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
} catch (error) {
|
|
114
|
+
console.log("用户取消导入");
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
</script>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## API 文档
|
|
121
|
+
|
|
122
|
+
### ImportDialog 类
|
|
123
|
+
|
|
124
|
+
#### 静态方法
|
|
125
|
+
|
|
126
|
+
| 方法 | 参数 | 返回值 | 说明 |
|
|
127
|
+
| --------------------- | ------------------ | --------------------------- | ---------------------- |
|
|
128
|
+
| `open(options)` | `OpenModalOptions` | `Promise<ImportSubmitData>` | 打开弹窗,返回 Promise |
|
|
129
|
+
| `close()` | - | `void` | 关闭弹窗 |
|
|
130
|
+
| `setLoading(loading)` | `boolean` | `void` | 设置加载状态 |
|
|
131
|
+
| `isReady()` | - | `boolean` | 检查服务是否就绪 |
|
|
132
|
+
| `setLocale(locale)` | `I18nLocale` | `void` | 设置国际化语言 |
|
|
133
|
+
| `getLocale()` | - | `I18nLocale` | 获取当前语言 |
|
|
134
|
+
|
|
135
|
+
#### 实例方法
|
|
136
|
+
|
|
137
|
+
| 方法 | 参数 | 返回值 | 说明 |
|
|
138
|
+
| ---------------------------- | ------------------ | ------ | -------------------- |
|
|
139
|
+
| `openModal(options)` | `OpenModalOptions` | `void` | 打开导入弹窗 |
|
|
140
|
+
| `closeModal()` | - | `void` | 关闭弹窗 |
|
|
141
|
+
| `setConfirmLoading(loading)` | `boolean` | `void` | 设置确认按钮加载状态 |
|
|
142
|
+
| `hide()` | - | `void` | 隐藏弹窗 |
|
|
143
|
+
| `destroy()` | - | `void` | 销毁实例 |
|
|
144
|
+
|
|
145
|
+
### OpenModalOptions 配置
|
|
146
|
+
|
|
147
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
148
|
+
| -------------------- | ------------------------------------------------- | ------------ | ---------------------- |
|
|
149
|
+
| `type` | `ExportTypeEnum` | `excel` | 导出文件类型 |
|
|
150
|
+
| `title` | `string` | `'批量导入'` | 弹窗标题 |
|
|
151
|
+
| `width` | `string` | `'480px'` | 弹窗宽度 |
|
|
152
|
+
| `templateType` | `TemplateTypeEnum` | `BASE` | 模板类型 |
|
|
153
|
+
| `tabs` | `TabConfig[]` | `[]` | 自定义标签页配置 |
|
|
154
|
+
| `defaultActiveTab` | `number` | `0` | 默认激活的标签页 |
|
|
155
|
+
| `brandData` | `BrandOption[] \| (() => Promise<BrandOption[]>)` | - | 品牌数据或异步获取函数 |
|
|
156
|
+
| `brandPlaceholder` | `string` | `'默认品牌'` | 品牌选择占位符 |
|
|
157
|
+
| `imageRatios` | `ImageRatioOption[]` | - | 图片比例选项 |
|
|
158
|
+
| `extendImageRatios` | `ImageRatioOption[]` | - | 扩展图片比例选项 |
|
|
159
|
+
| `customTips` | `string[]` | - | 自定义提示信息 |
|
|
160
|
+
| `templateUrl` | `string` | - | 模板下载链接 |
|
|
161
|
+
| `uploadTitle` | `string` | - | 上传区域标题 |
|
|
162
|
+
| `uploadLinkText` | `string` | - | 上传链接文字 |
|
|
163
|
+
| `uploadHint` | `string` | - | 上传提示信息 |
|
|
164
|
+
| `acceptTypes` | `string` | - | 接受的文件类型 |
|
|
165
|
+
| `showBrand` | `boolean` | - | 是否显示品牌选择 |
|
|
166
|
+
| `showImageRatio` | `boolean` | - | 是否显示图片比例选择 |
|
|
167
|
+
| `showMonth` | `boolean` | - | 是否显示月份选择 |
|
|
168
|
+
| `showDateRange` | `boolean` | - | 是否显示日期范围选择 |
|
|
169
|
+
| `dateRangeShortcuts` | `DateRangeShortcut[]` | - | 日期快捷选项 |
|
|
170
|
+
| `disabledDate` | `(date: Date) => boolean` | - | 禁用日期函数 |
|
|
171
|
+
| `locale` | `I18nLocale` | - | 国际化语言 |
|
|
172
|
+
|
|
173
|
+
#### 上传配置 (UploadConfig)
|
|
174
|
+
|
|
175
|
+
所有上传相关配置统一放在 `uploadConfig` 对象中:
|
|
176
|
+
|
|
177
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
178
|
+
| --------------- | ------------------------------------- | ----------- | ----------------------- |
|
|
179
|
+
| `autoUpload` | `boolean` | `false` | 是否立即上传文件 |
|
|
180
|
+
| `multiple` | `boolean` | `false` | 是否支持多文件上传 |
|
|
181
|
+
| `maxFiles` | `number` | `10` | 最大文件数量 |
|
|
182
|
+
| `maxFileSize` | `number` | `104857600` | 单文件最大大小(100MB) |
|
|
183
|
+
| `customUpload` | `(file, onProgress?) => Promise<any>` | - | 自定义上传函数 |
|
|
184
|
+
| `chunkedUpload` | `ChunkUploadStrategy` | - | 分片上传策略配置 |
|
|
185
|
+
|
|
186
|
+
##### 分片上传策略 (ChunkUploadStrategy)
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
interface ChunkUploadStrategy {
|
|
190
|
+
initUpload: (params: InitUploadParams) => Promise<InitUploadResult>;
|
|
191
|
+
getResumableOptions: (initResult: InitUploadResult) => ResumableOptions;
|
|
192
|
+
mergeChunks: (uploadSessionId: string) => Promise<any>;
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
#### 回调函数
|
|
197
|
+
|
|
198
|
+
| 参数 | 类型 | 说明 |
|
|
199
|
+
| ------------------ | --------------------------------- | ----------------------------------- |
|
|
200
|
+
| `onBeforeConfirm` | `(data) => void \| Promise<void>` | 确认前回调 |
|
|
201
|
+
| `onConfirm` | `(data) => void` | 确认回调,返回 `{success: boolean}` |
|
|
202
|
+
| `onBeforeCancel` | `() => void \| Promise<void>` | 取消前回调 |
|
|
203
|
+
| `onCancel` | `() => void` | 取消回调 |
|
|
204
|
+
| `onTabChange` | `(data) => void` | 标签切换回调 |
|
|
205
|
+
| `onFileChange` | `(files) => void` | 文件变化回调 |
|
|
206
|
+
| `onUploadProgress` | `(file, progress) => void` | 上传进度回调 |
|
|
207
|
+
| `onUploadSuccess` | `(file, response) => void` | 上传成功回调 |
|
|
208
|
+
| `onUploadError` | `(file, error) => void` | 上传失败回调 |
|
|
209
|
+
|
|
210
|
+
### 模板类型 (TemplateTypeEnum)
|
|
211
|
+
|
|
212
|
+
| 类型 | 说明 |
|
|
213
|
+
| ----------- | ------------------------ |
|
|
214
|
+
| `BASE` | 基础模板,仅文件上传 |
|
|
215
|
+
| `TEMPLATE1` | 品牌 + 图片比例选择 |
|
|
216
|
+
| `TEMPLATE2` | 覆盖/增量导入 + 图片上传 |
|
|
217
|
+
| `TEMPLATE3` | 月份选择 + 营业目标导入 |
|
|
218
|
+
| `TEMPLATE4` | 品牌选择 + 菜谱方案导入 |
|
|
219
|
+
| `TEMPLATE5` | 合批修改价格 + 日期范围 |
|
|
220
|
+
|
|
221
|
+
### 国际化 (I18nLocaleEnum)
|
|
222
|
+
|
|
223
|
+
| 语言 | 枚举值 |
|
|
224
|
+
| -------- | ------- |
|
|
225
|
+
| 简体中文 | `ZH_CN` |
|
|
226
|
+
| 繁体中文 | `ZH_TW` |
|
|
227
|
+
| 英语 | `EN_US` |
|
|
228
|
+
| 日语 | `JA` |
|
|
229
|
+
| 印尼语 | `ID` |
|
|
230
|
+
|
|
231
|
+
### 类型定义
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
interface TabConfig {
|
|
235
|
+
label: string;
|
|
236
|
+
key: string;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
interface BrandOption {
|
|
240
|
+
label: string;
|
|
241
|
+
value: string | number;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
interface ImageRatioOption {
|
|
245
|
+
label: string;
|
|
246
|
+
value: string;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
interface ImportFormData {
|
|
250
|
+
brandId: string | number | undefined;
|
|
251
|
+
imageRatio: string;
|
|
252
|
+
month: number;
|
|
253
|
+
dateRange: [Date | null, Date | null];
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
interface ImportSubmitData {
|
|
257
|
+
files: File[];
|
|
258
|
+
formData: ImportFormData;
|
|
259
|
+
activeTab: TabConfig | undefined;
|
|
260
|
+
activeTabIndex: number;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
interface FileUploadItem {
|
|
264
|
+
id: string;
|
|
265
|
+
file: File;
|
|
266
|
+
name: string;
|
|
267
|
+
size: number;
|
|
268
|
+
progress: number;
|
|
269
|
+
status: "pending" | "uploading" | "success" | "error";
|
|
270
|
+
errorMessage?: string;
|
|
271
|
+
uploadSessionId?: string;
|
|
272
|
+
response?: any;
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## 使用示例
|
|
277
|
+
|
|
278
|
+
### 基础导入(立即上传)
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
import { ImportDialog, TemplateTypeEnum } from "@sl-material/sl-import";
|
|
282
|
+
|
|
283
|
+
ImportDialog.open({
|
|
284
|
+
title: "导入数据",
|
|
285
|
+
templateType: TemplateTypeEnum.BASE,
|
|
286
|
+
templateUrl: "/template/data_template.xlsx",
|
|
287
|
+
tips: ["提示信息 1", "提示信息 2"],
|
|
288
|
+
uploadConfig: {
|
|
289
|
+
autoUpload: true, // 选择文件后立即上传
|
|
290
|
+
customUpload: async (file, onProgress) => {
|
|
291
|
+
// 自定义上传逻辑
|
|
292
|
+
const formData = new FormData();
|
|
293
|
+
formData.append("file", file);
|
|
294
|
+
|
|
295
|
+
const response = await fetch("/api/upload", {
|
|
296
|
+
method: "POST",
|
|
297
|
+
body: formData,
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
return response.json();
|
|
301
|
+
},
|
|
302
|
+
},
|
|
303
|
+
});
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### 延迟上传(点击确定时上传)
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
ImportDialog.open({
|
|
310
|
+
title: "导入数据",
|
|
311
|
+
templateType: TemplateTypeEnum.BASE,
|
|
312
|
+
uploadConfig: {
|
|
313
|
+
autoUpload: false, // 默认值,点击确定时上传
|
|
314
|
+
customUpload: async (file, onProgress) => {
|
|
315
|
+
// 上传逻辑
|
|
316
|
+
},
|
|
317
|
+
},
|
|
318
|
+
onConfirm: async (data) => {
|
|
319
|
+
// 此时文件已上传完成,data.files 包含上传结果
|
|
320
|
+
console.log("上传结果:", data.files);
|
|
321
|
+
return { success: true };
|
|
322
|
+
},
|
|
323
|
+
});
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### 分片上传(立即上传)
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
ImportDialog.open({
|
|
330
|
+
title: "大文件上传",
|
|
331
|
+
templateType: TemplateTypeEnum.BASE,
|
|
332
|
+
uploadConfig: {
|
|
333
|
+
autoUpload: true,
|
|
334
|
+
maxFileSize: 500 * 1024 * 1024, // 500MB
|
|
335
|
+
chunkedUpload: {
|
|
336
|
+
initUpload: async (params) => {
|
|
337
|
+
const response = await fetch("/api/upload/init", {
|
|
338
|
+
method: "POST",
|
|
339
|
+
headers: { "Content-Type": "application/json" },
|
|
340
|
+
body: JSON.stringify(params),
|
|
341
|
+
});
|
|
342
|
+
return response.json();
|
|
343
|
+
},
|
|
344
|
+
getResumableOptions: (initResult) => ({
|
|
345
|
+
target: "/api/upload/chunk",
|
|
346
|
+
headers: {
|
|
347
|
+
Authorization: `Bearer ${token}`,
|
|
348
|
+
},
|
|
349
|
+
query: { uploadSessionId: initResult.uploadSessionId },
|
|
350
|
+
}),
|
|
351
|
+
mergeChunks: async (uploadSessionId) => {
|
|
352
|
+
const response = await fetch(`/api/upload/merge/${uploadSessionId}`, {
|
|
353
|
+
method: "POST",
|
|
354
|
+
});
|
|
355
|
+
return response.json();
|
|
356
|
+
},
|
|
357
|
+
},
|
|
358
|
+
},
|
|
359
|
+
});
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### 分片上传(延迟上传)
|
|
363
|
+
|
|
364
|
+
```typescript
|
|
365
|
+
ImportDialog.open({
|
|
366
|
+
title: "大文件上传",
|
|
367
|
+
templateType: TemplateTypeEnum.BASE,
|
|
368
|
+
uploadConfig: {
|
|
369
|
+
autoUpload: false, // 延迟上传
|
|
370
|
+
maxFileSize: 500 * 1024 * 1024,
|
|
371
|
+
chunkedUpload: {
|
|
372
|
+
// 分片上传配置同上
|
|
373
|
+
},
|
|
374
|
+
},
|
|
375
|
+
onConfirm: async (data) => {
|
|
376
|
+
// 点击确定时执行分片上传,data.files 包含合并后的结果
|
|
377
|
+
console.log("分片上传完成:", data.files);
|
|
378
|
+
return { success: true };
|
|
379
|
+
},
|
|
380
|
+
});
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### 多文件上传
|
|
384
|
+
|
|
385
|
+
```typescript
|
|
386
|
+
ImportDialog.open({
|
|
387
|
+
title: "批量上传文件",
|
|
388
|
+
templateType: TemplateTypeEnum.BASE,
|
|
389
|
+
uploadConfig: {
|
|
390
|
+
multiple: true,
|
|
391
|
+
maxFiles: 20,
|
|
392
|
+
autoUpload: true,
|
|
393
|
+
customUpload: async (file, onProgress) => {
|
|
394
|
+
// 自定义上传逻辑
|
|
395
|
+
const formData = new FormData();
|
|
396
|
+
formData.append("file", file);
|
|
397
|
+
|
|
398
|
+
const xhr = new XMLHttpRequest();
|
|
399
|
+
xhr.upload.addEventListener("progress", (e) => {
|
|
400
|
+
if (e.lengthComputable) {
|
|
401
|
+
onProgress?.(Math.round((e.loaded / e.total) * 100));
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
xhr.open("POST", "/api/upload");
|
|
406
|
+
await xhr.send(formData);
|
|
407
|
+
},
|
|
408
|
+
},
|
|
409
|
+
onUploadProgress: (file, progress) => {
|
|
410
|
+
console.log(`${file.name}: ${progress}%`);
|
|
411
|
+
},
|
|
412
|
+
});
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
### 带品牌选择的导入
|
|
416
|
+
|
|
417
|
+
```typescript
|
|
418
|
+
ImportDialog.open({
|
|
419
|
+
title: "导入商品",
|
|
420
|
+
templateType: TemplateTypeEnum.TEMPLATE1,
|
|
421
|
+
brandData: async () => {
|
|
422
|
+
const res = await fetch("/api/brands");
|
|
423
|
+
return res.json();
|
|
424
|
+
},
|
|
425
|
+
uploadConfig: {
|
|
426
|
+
autoUpload: false, // 延迟上传
|
|
427
|
+
},
|
|
428
|
+
onConfirm: async (data) => {
|
|
429
|
+
console.log("品牌 ID:", data.formData.brandId);
|
|
430
|
+
console.log("图片比例:", data.formData.imageRatio);
|
|
431
|
+
console.log("上传文件:", data.files);
|
|
432
|
+
|
|
433
|
+
// 处理业务逻辑
|
|
434
|
+
await processImport(data.files, {
|
|
435
|
+
brandId: data.formData.brandId,
|
|
436
|
+
imageRatio: data.formData.imageRatio,
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
return { success: true };
|
|
440
|
+
},
|
|
441
|
+
});
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
### 自定义日期范围
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
ImportDialog.open({
|
|
448
|
+
title: "导入报表",
|
|
449
|
+
templateType: TemplateTypeEnum.TEMPLATE5,
|
|
450
|
+
showDateRange: true,
|
|
451
|
+
dateRangeShortcuts: [
|
|
452
|
+
{
|
|
453
|
+
label: "最近7天",
|
|
454
|
+
value: [new Date(Date.now() - 6 * 24 * 60 * 60 * 1000), new Date()],
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
label: "最近30天",
|
|
458
|
+
value: [new Date(Date.now() - 29 * 24 * 60 * 60 * 1000), new Date()],
|
|
459
|
+
},
|
|
460
|
+
],
|
|
461
|
+
disabledDate: (date) => {
|
|
462
|
+
// 禁用未来日期
|
|
463
|
+
return date > new Date();
|
|
464
|
+
},
|
|
465
|
+
});
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
## UMD 使用方式
|
|
469
|
+
|
|
470
|
+
```html
|
|
471
|
+
<script src="https://unpkg.com/@sl-material/sl-import/dist/sl-import.umd.umd.js"></script>
|
|
472
|
+
<script>
|
|
473
|
+
const { ImportDialog } = window.SlImport;
|
|
474
|
+
|
|
475
|
+
ImportDialog.open({
|
|
476
|
+
title: "批量导入",
|
|
477
|
+
templateType: "BASE",
|
|
478
|
+
});
|
|
479
|
+
</script>
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
> **注意**:UMD 版本同样已内联 CSS,无需额外引入样式文件。
|
|
483
|
+
|
|
484
|
+
## License
|
|
485
|
+
|
|
486
|
+
MIT
|