tools-min-ns 1.18.15 → 1.18.17
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 +4 -0
- package/esm/date/DateUtil.d.ts +7 -0
- package/esm/date/DateUtil.js +23 -0
- package/esm/file/FileUtil.d.ts +11 -5
- package/esm/file/FileUtil.js +47 -174
- package/esm/system/SystemUtil.js +84 -22
- package/lib/date/DateUtil.d.ts +7 -0
- package/lib/date/DateUtil.js +23 -0
- package/lib/file/FileUtil.d.ts +11 -5
- package/lib/file/FileUtil.js +48 -180
- package/lib/system/SystemUtil.js +84 -22
- package/package.json +3 -2
package/README.md
CHANGED
package/esm/date/DateUtil.d.ts
CHANGED
|
@@ -74,6 +74,13 @@ declare namespace DateUtil {
|
|
|
74
74
|
* formatDateToFriendly2() => 2017年11月11日
|
|
75
75
|
*/
|
|
76
76
|
function formatDateToFriendly3(date?: Date | number | string): string;
|
|
77
|
+
/**
|
|
78
|
+
* 格式化时间为友好格式
|
|
79
|
+
* @param seconds
|
|
80
|
+
* @example
|
|
81
|
+
* formatBySeconds(10) => 10秒
|
|
82
|
+
*/
|
|
83
|
+
function formatBySeconds(seconds: number): string;
|
|
77
84
|
/**
|
|
78
85
|
* 判断是否为本周
|
|
79
86
|
* @param date
|
package/esm/date/DateUtil.js
CHANGED
|
@@ -233,6 +233,29 @@ var DateUtil;
|
|
|
233
233
|
return "".concat(years, "\u5E74\u524D");
|
|
234
234
|
}
|
|
235
235
|
DateUtil.formatDateToFriendly3 = formatDateToFriendly3;
|
|
236
|
+
/**
|
|
237
|
+
* 格式化时间为友好格式
|
|
238
|
+
* @param seconds
|
|
239
|
+
* @example
|
|
240
|
+
* formatBySeconds(10) => 10秒
|
|
241
|
+
*/
|
|
242
|
+
function formatBySeconds(seconds) {
|
|
243
|
+
if (!isFinite(seconds) || seconds < 0) return '计算中...';
|
|
244
|
+
var day = Math.floor(seconds / 3600 * 24);
|
|
245
|
+
var hours = Math.floor(seconds / 3600);
|
|
246
|
+
var minutes = Math.floor(seconds % 3600 / 60);
|
|
247
|
+
var secs = Math.floor(seconds % 60);
|
|
248
|
+
if (day > 0) {
|
|
249
|
+
return "".concat(day, "\u5929").concat(hours, "\u5C0F\u65F6").concat(minutes, "\u5206\u949F").concat(secs, "\u79D2");
|
|
250
|
+
} else if (hours > 0) {
|
|
251
|
+
return "".concat(hours, "\u5C0F\u65F6").concat(minutes, "\u5206\u949F").concat(secs, "\u79D2");
|
|
252
|
+
} else if (minutes > 0) {
|
|
253
|
+
return "".concat(minutes, "\u5206\u949F").concat(secs, "\u79D2");
|
|
254
|
+
} else {
|
|
255
|
+
return "".concat(secs, "\u79D2");
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
DateUtil.formatBySeconds = formatBySeconds;
|
|
236
259
|
/**
|
|
237
260
|
* 判断是否为本周
|
|
238
261
|
* @param date
|
package/esm/file/FileUtil.d.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
declare namespace FileUtil {
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* @param
|
|
5
|
-
* @param
|
|
6
|
-
* @returns
|
|
3
|
+
* 提取文件名的辅助函数
|
|
4
|
+
* @param url
|
|
5
|
+
* @param response
|
|
7
6
|
*/
|
|
8
|
-
function
|
|
7
|
+
function extractFilename(url: string, response: Response): string;
|
|
8
|
+
/**
|
|
9
|
+
* 简单提取文件扩展名的辅助函数
|
|
10
|
+
* @param url
|
|
11
|
+
*/
|
|
12
|
+
function getExt(url: string): string;
|
|
13
|
+
const ellisipsFileName: (fileName: string | undefined, maxLength?: number) => string;
|
|
14
|
+
const getFileName: (url: string, maxLength?: number) => string | undefined;
|
|
9
15
|
}
|
|
10
16
|
export default FileUtil;
|
package/esm/file/FileUtil.js
CHANGED
|
@@ -1,182 +1,55 @@
|
|
|
1
|
-
var
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
function rejected(value) {
|
|
16
|
-
try {
|
|
17
|
-
step(generator["throw"](value));
|
|
18
|
-
} catch (e) {
|
|
19
|
-
reject(e);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
function step(result) {
|
|
23
|
-
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
24
|
-
}
|
|
25
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
26
|
-
});
|
|
27
|
-
};
|
|
28
|
-
var __generator = this && this.__generator || function (thisArg, body) {
|
|
29
|
-
var _ = {
|
|
30
|
-
label: 0,
|
|
31
|
-
sent: function sent() {
|
|
32
|
-
if (t[0] & 1) throw t[1];
|
|
33
|
-
return t[1];
|
|
34
|
-
},
|
|
35
|
-
trys: [],
|
|
36
|
-
ops: []
|
|
37
|
-
},
|
|
38
|
-
f,
|
|
39
|
-
y,
|
|
40
|
-
t,
|
|
41
|
-
g;
|
|
42
|
-
return g = {
|
|
43
|
-
next: verb(0),
|
|
44
|
-
"throw": verb(1),
|
|
45
|
-
"return": verb(2)
|
|
46
|
-
}, typeof Symbol === "function" && (g[Symbol.iterator] = function () {
|
|
47
|
-
return this;
|
|
48
|
-
}), g;
|
|
49
|
-
function verb(n) {
|
|
50
|
-
return function (v) {
|
|
51
|
-
return step([n, v]);
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
function step(op) {
|
|
55
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
56
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
57
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
58
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
59
|
-
switch (op[0]) {
|
|
60
|
-
case 0:
|
|
61
|
-
case 1:
|
|
62
|
-
t = op;
|
|
63
|
-
break;
|
|
64
|
-
case 4:
|
|
65
|
-
_.label++;
|
|
66
|
-
return {
|
|
67
|
-
value: op[1],
|
|
68
|
-
done: false
|
|
69
|
-
};
|
|
70
|
-
case 5:
|
|
71
|
-
_.label++;
|
|
72
|
-
y = op[1];
|
|
73
|
-
op = [0];
|
|
74
|
-
continue;
|
|
75
|
-
case 7:
|
|
76
|
-
op = _.ops.pop();
|
|
77
|
-
_.trys.pop();
|
|
78
|
-
continue;
|
|
79
|
-
default:
|
|
80
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
81
|
-
_ = 0;
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
85
|
-
_.label = op[1];
|
|
86
|
-
break;
|
|
87
|
-
}
|
|
88
|
-
if (op[0] === 6 && _.label < t[1]) {
|
|
89
|
-
_.label = t[1];
|
|
90
|
-
t = op;
|
|
91
|
-
break;
|
|
92
|
-
}
|
|
93
|
-
if (t && _.label < t[2]) {
|
|
94
|
-
_.label = t[2];
|
|
95
|
-
_.ops.push(op);
|
|
96
|
-
break;
|
|
97
|
-
}
|
|
98
|
-
if (t[2]) _.ops.pop();
|
|
99
|
-
_.trys.pop();
|
|
100
|
-
continue;
|
|
1
|
+
var FileUtil;
|
|
2
|
+
(function (FileUtil) {
|
|
3
|
+
/**
|
|
4
|
+
* 提取文件名的辅助函数
|
|
5
|
+
* @param url
|
|
6
|
+
* @param response
|
|
7
|
+
*/
|
|
8
|
+
function extractFilename(url, response) {
|
|
9
|
+
// 尝试从 Content-Disposition 头获取文件名
|
|
10
|
+
var contentDisposition = response.headers.get('content-disposition');
|
|
11
|
+
if (contentDisposition) {
|
|
12
|
+
var filenameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
|
|
13
|
+
if (filenameMatch && filenameMatch[1]) {
|
|
14
|
+
return filenameMatch[1].replace(/['"]/g, '');
|
|
101
15
|
}
|
|
102
|
-
op = body.call(thisArg, _);
|
|
103
|
-
} catch (e) {
|
|
104
|
-
op = [6, e];
|
|
105
|
-
y = 0;
|
|
106
|
-
} finally {
|
|
107
|
-
f = t = 0;
|
|
108
16
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
done: true
|
|
113
|
-
};
|
|
17
|
+
// 从 URL 提取文件名
|
|
18
|
+
var urlFilename = url.split('/').pop();
|
|
19
|
+
return urlFilename || 'download';
|
|
114
20
|
}
|
|
115
|
-
|
|
116
|
-
var __values = this && this.__values || function (o) {
|
|
117
|
-
var s = typeof Symbol === "function" && Symbol.iterator,
|
|
118
|
-
m = s && o[s],
|
|
119
|
-
i = 0;
|
|
120
|
-
if (m) return m.call(o);
|
|
121
|
-
if (o && typeof o.length === "number") return {
|
|
122
|
-
next: function next() {
|
|
123
|
-
if (o && i >= o.length) o = void 0;
|
|
124
|
-
return {
|
|
125
|
-
value: o && o[i++],
|
|
126
|
-
done: !o
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
131
|
-
};
|
|
132
|
-
import JSZip from 'jszip';
|
|
133
|
-
var FileUtil;
|
|
134
|
-
(function (FileUtil) {
|
|
21
|
+
FileUtil.extractFilename = extractFilename;
|
|
135
22
|
/**
|
|
136
|
-
*
|
|
137
|
-
* @param
|
|
138
|
-
* @param onProgress
|
|
139
|
-
* @returns
|
|
23
|
+
* 简单提取文件扩展名的辅助函数
|
|
24
|
+
* @param url
|
|
140
25
|
*/
|
|
141
|
-
function
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
return __generator(this, function (_b) {
|
|
146
|
-
switch (_b.label) {
|
|
147
|
-
case 0:
|
|
148
|
-
zip = new JSZip();
|
|
149
|
-
try {
|
|
150
|
-
for (fileList_1 = __values(fileList), fileList_1_1 = fileList_1.next(); !fileList_1_1.done; fileList_1_1 = fileList_1.next()) {
|
|
151
|
-
file_1 = fileList_1_1.value;
|
|
152
|
-
zip.file(file_1.name, file_1);
|
|
153
|
-
}
|
|
154
|
-
} catch (e_1_1) {
|
|
155
|
-
e_1 = {
|
|
156
|
-
error: e_1_1
|
|
157
|
-
};
|
|
158
|
-
} finally {
|
|
159
|
-
try {
|
|
160
|
-
if (fileList_1_1 && !fileList_1_1.done && (_a = fileList_1.return)) _a.call(fileList_1);
|
|
161
|
-
} finally {
|
|
162
|
-
if (e_1) throw e_1.error;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
return [4 /*yield*/, zip.generateAsync({
|
|
166
|
-
type: 'blob'
|
|
167
|
-
}, function (item) {
|
|
168
|
-
onProgress === null || onProgress === void 0 ? void 0 : onProgress(item.currentFile, item.percent);
|
|
169
|
-
})];
|
|
170
|
-
case 1:
|
|
171
|
-
blob = _b.sent();
|
|
172
|
-
file = new File([blob], "\u201C".concat(fileList[0].name, "\u201D\u7B49").concat(fileList.length, "\u4E2A\u6587\u4EF6.zip"), {
|
|
173
|
-
type: blob.type
|
|
174
|
-
});
|
|
175
|
-
return [2 /*return*/, file];
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
});
|
|
26
|
+
function getExt(url) {
|
|
27
|
+
var _a;
|
|
28
|
+
var ext = (_a = url.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLocaleLowerCase();
|
|
29
|
+
return ext || url;
|
|
179
30
|
}
|
|
180
|
-
FileUtil.
|
|
31
|
+
FileUtil.getExt = getExt;
|
|
32
|
+
FileUtil.ellisipsFileName = function (fileName, maxLength) {
|
|
33
|
+
if (maxLength === void 0) {
|
|
34
|
+
maxLength = 30;
|
|
35
|
+
}
|
|
36
|
+
if (!fileName) return '';
|
|
37
|
+
if (fileName.length > maxLength) {
|
|
38
|
+
var len = Math.floor((maxLength - 3) / 2);
|
|
39
|
+
return fileName.slice(0, len) + '...' + fileName.slice(-len);
|
|
40
|
+
}
|
|
41
|
+
return fileName;
|
|
42
|
+
};
|
|
43
|
+
var _getFileName = function _getFileName(url) {
|
|
44
|
+
if (!url) return;
|
|
45
|
+
if (url.includes('*')) return url.split('*')[1];
|
|
46
|
+
return url.split('/').slice(-1).toString();
|
|
47
|
+
};
|
|
48
|
+
FileUtil.getFileName = function (url, maxLength) {
|
|
49
|
+
if (maxLength) {
|
|
50
|
+
return FileUtil.ellisipsFileName(_getFileName(url), maxLength);
|
|
51
|
+
}
|
|
52
|
+
return _getFileName(url);
|
|
53
|
+
};
|
|
181
54
|
})(FileUtil || (FileUtil = {}));
|
|
182
55
|
export default FileUtil;
|
package/esm/system/SystemUtil.js
CHANGED
|
@@ -119,7 +119,11 @@ var __generator = this && this.__generator || function (thisArg, body) {
|
|
|
119
119
|
* @author nanshen
|
|
120
120
|
* @creat 2021-09-15 14:24:57
|
|
121
121
|
*/
|
|
122
|
+
import FileUtil from '../file/FileUtil';
|
|
122
123
|
import TransferUtil from '../transfer/TransferUtil';
|
|
124
|
+
import streamSaver from 'streamsaver';
|
|
125
|
+
var MITM = 'https://ns.nihaonanshen.com/assets/stream/mitm.html';
|
|
126
|
+
streamSaver.mitm = MITM;
|
|
123
127
|
var SystemUtil;
|
|
124
128
|
(function (SystemUtil) {
|
|
125
129
|
/**
|
|
@@ -147,12 +151,13 @@ var SystemUtil;
|
|
|
147
151
|
* downloadFile('http://XXX.txt','text.txt')
|
|
148
152
|
*/
|
|
149
153
|
function downloadFile(url, name) {
|
|
154
|
+
var _a;
|
|
150
155
|
return __awaiter(this, void 0, void 0, function () {
|
|
151
|
-
var response,
|
|
152
|
-
return __generator(this, function (
|
|
153
|
-
switch (
|
|
156
|
+
var response, contentLength, total, finalFilename, fileStream, error_1;
|
|
157
|
+
return __generator(this, function (_b) {
|
|
158
|
+
switch (_b.label) {
|
|
154
159
|
case 0:
|
|
155
|
-
|
|
160
|
+
_b.trys.push([0, 2,, 3]);
|
|
156
161
|
return [4 /*yield*/, fetch(url, {
|
|
157
162
|
method: 'GET',
|
|
158
163
|
headers: {
|
|
@@ -160,33 +165,90 @@ var SystemUtil;
|
|
|
160
165
|
}
|
|
161
166
|
})];
|
|
162
167
|
case 1:
|
|
163
|
-
response =
|
|
164
|
-
if (!response.ok)
|
|
165
|
-
|
|
168
|
+
response = _b.sent();
|
|
169
|
+
if (!response.ok) throw new Error("HTTP error! status: ".concat(response.status));
|
|
170
|
+
contentLength = response.headers.get('content-length');
|
|
171
|
+
total = contentLength ? parseInt(contentLength, 10) : undefined;
|
|
172
|
+
finalFilename = name || FileUtil.extractFilename(url, response);
|
|
173
|
+
fileStream = streamSaver.createWriteStream(finalFilename, {
|
|
174
|
+
size: total
|
|
175
|
+
});
|
|
176
|
+
// 检查浏览器是否支持流式传输
|
|
177
|
+
if (window.WritableStream && ((_a = response.body) === null || _a === void 0 ? void 0 : _a.pipeTo)) {
|
|
178
|
+
// 直接管道传输(最高效)
|
|
179
|
+
return [2 /*return*/, response.body.pipeTo(fileStream).then(function () {
|
|
180
|
+
return console.log('下载完成');
|
|
181
|
+
}).catch(function (error) {
|
|
182
|
+
console.error('下载失败:', error);
|
|
183
|
+
throw error;
|
|
184
|
+
})];
|
|
185
|
+
} else {
|
|
186
|
+
// 降级方案:手动读取和写入
|
|
187
|
+
return [2 /*return*/, manualStreamDownload(response, fileStream)];
|
|
166
188
|
}
|
|
167
|
-
return [
|
|
189
|
+
return [3 /*break*/, 3];
|
|
168
190
|
case 2:
|
|
169
|
-
|
|
170
|
-
SystemUtil.downloadFileByBlob(blob, name || url.split('/').pop());
|
|
171
|
-
return [3 /*break*/, 4];
|
|
172
|
-
case 3:
|
|
173
|
-
error_1 = _a.sent();
|
|
191
|
+
error_1 = _b.sent();
|
|
174
192
|
console.error('下载失败:', error_1);
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
clickEvent = document.createEvent('MouseEvents');
|
|
180
|
-
clickEvent.initEvent('click', true, true);
|
|
181
|
-
a.dispatchEvent(clickEvent);
|
|
182
|
-
return [3 /*break*/, 4];
|
|
183
|
-
case 4:
|
|
193
|
+
// 降级方案
|
|
194
|
+
fallbackDownload(url, name);
|
|
195
|
+
return [3 /*break*/, 3];
|
|
196
|
+
case 3:
|
|
184
197
|
return [2 /*return*/];
|
|
185
198
|
}
|
|
186
199
|
});
|
|
187
200
|
});
|
|
188
201
|
}
|
|
189
202
|
SystemUtil.downloadFile = downloadFile;
|
|
203
|
+
// 最终降级方案
|
|
204
|
+
function fallbackDownload(url, filename) {
|
|
205
|
+
var a = document.createElement('a');
|
|
206
|
+
a.href = url;
|
|
207
|
+
if (filename) a.download = filename;
|
|
208
|
+
a.target = '_blank';
|
|
209
|
+
a.style.display = 'none';
|
|
210
|
+
document.body.appendChild(a);
|
|
211
|
+
a.click();
|
|
212
|
+
document.body.removeChild(a);
|
|
213
|
+
}
|
|
214
|
+
// 手动流式下载(兼容性降级)
|
|
215
|
+
function manualStreamDownload(response, fileStream) {
|
|
216
|
+
var _a;
|
|
217
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
218
|
+
var reader, writer, _b, done, value;
|
|
219
|
+
return __generator(this, function (_c) {
|
|
220
|
+
switch (_c.label) {
|
|
221
|
+
case 0:
|
|
222
|
+
reader = (_a = response.body) === null || _a === void 0 ? void 0 : _a.getReader();
|
|
223
|
+
writer = fileStream.getWriter();
|
|
224
|
+
if (!reader) throw new Error('无法获取响应流');
|
|
225
|
+
_c.label = 1;
|
|
226
|
+
case 1:
|
|
227
|
+
_c.trys.push([1,, 6, 8]);
|
|
228
|
+
_c.label = 2;
|
|
229
|
+
case 2:
|
|
230
|
+
if (!true) return [3 /*break*/, 5];
|
|
231
|
+
return [4 /*yield*/, reader.read()];
|
|
232
|
+
case 3:
|
|
233
|
+
_b = _c.sent(), done = _b.done, value = _b.value;
|
|
234
|
+
if (done) return [3 /*break*/, 5];
|
|
235
|
+
return [4 /*yield*/, writer.write(value)];
|
|
236
|
+
case 4:
|
|
237
|
+
_c.sent();
|
|
238
|
+
return [3 /*break*/, 2];
|
|
239
|
+
case 5:
|
|
240
|
+
return [3 /*break*/, 8];
|
|
241
|
+
case 6:
|
|
242
|
+
return [4 /*yield*/, writer.close()];
|
|
243
|
+
case 7:
|
|
244
|
+
_c.sent();
|
|
245
|
+
return [7 /*endfinally*/];
|
|
246
|
+
case 8:
|
|
247
|
+
return [2 /*return*/];
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
}
|
|
190
252
|
/**
|
|
191
253
|
* 通过base64下载文件
|
|
192
254
|
* @param base64 base64字符串
|
package/lib/date/DateUtil.d.ts
CHANGED
|
@@ -74,6 +74,13 @@ declare namespace DateUtil {
|
|
|
74
74
|
* formatDateToFriendly2() => 2017年11月11日
|
|
75
75
|
*/
|
|
76
76
|
function formatDateToFriendly3(date?: Date | number | string): string;
|
|
77
|
+
/**
|
|
78
|
+
* 格式化时间为友好格式
|
|
79
|
+
* @param seconds
|
|
80
|
+
* @example
|
|
81
|
+
* formatBySeconds(10) => 10秒
|
|
82
|
+
*/
|
|
83
|
+
function formatBySeconds(seconds: number): string;
|
|
77
84
|
/**
|
|
78
85
|
* 判断是否为本周
|
|
79
86
|
* @param date
|
package/lib/date/DateUtil.js
CHANGED
|
@@ -243,6 +243,29 @@ var DateUtil;
|
|
|
243
243
|
return "".concat(years, "\u5E74\u524D");
|
|
244
244
|
}
|
|
245
245
|
DateUtil.formatDateToFriendly3 = formatDateToFriendly3;
|
|
246
|
+
/**
|
|
247
|
+
* 格式化时间为友好格式
|
|
248
|
+
* @param seconds
|
|
249
|
+
* @example
|
|
250
|
+
* formatBySeconds(10) => 10秒
|
|
251
|
+
*/
|
|
252
|
+
function formatBySeconds(seconds) {
|
|
253
|
+
if (!isFinite(seconds) || seconds < 0) return '计算中...';
|
|
254
|
+
var day = Math.floor(seconds / 3600 * 24);
|
|
255
|
+
var hours = Math.floor(seconds / 3600);
|
|
256
|
+
var minutes = Math.floor(seconds % 3600 / 60);
|
|
257
|
+
var secs = Math.floor(seconds % 60);
|
|
258
|
+
if (day > 0) {
|
|
259
|
+
return "".concat(day, "\u5929").concat(hours, "\u5C0F\u65F6").concat(minutes, "\u5206\u949F").concat(secs, "\u79D2");
|
|
260
|
+
} else if (hours > 0) {
|
|
261
|
+
return "".concat(hours, "\u5C0F\u65F6").concat(minutes, "\u5206\u949F").concat(secs, "\u79D2");
|
|
262
|
+
} else if (minutes > 0) {
|
|
263
|
+
return "".concat(minutes, "\u5206\u949F").concat(secs, "\u79D2");
|
|
264
|
+
} else {
|
|
265
|
+
return "".concat(secs, "\u79D2");
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
DateUtil.formatBySeconds = formatBySeconds;
|
|
246
269
|
/**
|
|
247
270
|
* 判断是否为本周
|
|
248
271
|
* @param date
|
package/lib/file/FileUtil.d.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
declare namespace FileUtil {
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* @param
|
|
5
|
-
* @param
|
|
6
|
-
* @returns
|
|
3
|
+
* 提取文件名的辅助函数
|
|
4
|
+
* @param url
|
|
5
|
+
* @param response
|
|
7
6
|
*/
|
|
8
|
-
function
|
|
7
|
+
function extractFilename(url: string, response: Response): string;
|
|
8
|
+
/**
|
|
9
|
+
* 简单提取文件扩展名的辅助函数
|
|
10
|
+
* @param url
|
|
11
|
+
*/
|
|
12
|
+
function getExt(url: string): string;
|
|
13
|
+
const ellisipsFileName: (fileName: string | undefined, maxLength?: number) => string;
|
|
14
|
+
const getFileName: (url: string, maxLength?: number) => string | undefined;
|
|
9
15
|
}
|
|
10
16
|
export default FileUtil;
|
package/lib/file/FileUtil.js
CHANGED
|
@@ -1,192 +1,60 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
var __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) {
|
|
4
|
-
function adopt(value) {
|
|
5
|
-
return value instanceof P ? value : new P(function (resolve) {
|
|
6
|
-
resolve(value);
|
|
7
|
-
});
|
|
8
|
-
}
|
|
9
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
10
|
-
function fulfilled(value) {
|
|
11
|
-
try {
|
|
12
|
-
step(generator.next(value));
|
|
13
|
-
} catch (e) {
|
|
14
|
-
reject(e);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
function rejected(value) {
|
|
18
|
-
try {
|
|
19
|
-
step(generator["throw"](value));
|
|
20
|
-
} catch (e) {
|
|
21
|
-
reject(e);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
function step(result) {
|
|
25
|
-
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
26
|
-
}
|
|
27
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
28
|
-
});
|
|
29
|
-
};
|
|
30
|
-
var __generator = this && this.__generator || function (thisArg, body) {
|
|
31
|
-
var _ = {
|
|
32
|
-
label: 0,
|
|
33
|
-
sent: function sent() {
|
|
34
|
-
if (t[0] & 1) throw t[1];
|
|
35
|
-
return t[1];
|
|
36
|
-
},
|
|
37
|
-
trys: [],
|
|
38
|
-
ops: []
|
|
39
|
-
},
|
|
40
|
-
f,
|
|
41
|
-
y,
|
|
42
|
-
t,
|
|
43
|
-
g;
|
|
44
|
-
return g = {
|
|
45
|
-
next: verb(0),
|
|
46
|
-
"throw": verb(1),
|
|
47
|
-
"return": verb(2)
|
|
48
|
-
}, typeof Symbol === "function" && (g[Symbol.iterator] = function () {
|
|
49
|
-
return this;
|
|
50
|
-
}), g;
|
|
51
|
-
function verb(n) {
|
|
52
|
-
return function (v) {
|
|
53
|
-
return step([n, v]);
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
function step(op) {
|
|
57
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
58
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
59
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
60
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
61
|
-
switch (op[0]) {
|
|
62
|
-
case 0:
|
|
63
|
-
case 1:
|
|
64
|
-
t = op;
|
|
65
|
-
break;
|
|
66
|
-
case 4:
|
|
67
|
-
_.label++;
|
|
68
|
-
return {
|
|
69
|
-
value: op[1],
|
|
70
|
-
done: false
|
|
71
|
-
};
|
|
72
|
-
case 5:
|
|
73
|
-
_.label++;
|
|
74
|
-
y = op[1];
|
|
75
|
-
op = [0];
|
|
76
|
-
continue;
|
|
77
|
-
case 7:
|
|
78
|
-
op = _.ops.pop();
|
|
79
|
-
_.trys.pop();
|
|
80
|
-
continue;
|
|
81
|
-
default:
|
|
82
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
83
|
-
_ = 0;
|
|
84
|
-
continue;
|
|
85
|
-
}
|
|
86
|
-
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
87
|
-
_.label = op[1];
|
|
88
|
-
break;
|
|
89
|
-
}
|
|
90
|
-
if (op[0] === 6 && _.label < t[1]) {
|
|
91
|
-
_.label = t[1];
|
|
92
|
-
t = op;
|
|
93
|
-
break;
|
|
94
|
-
}
|
|
95
|
-
if (t && _.label < t[2]) {
|
|
96
|
-
_.label = t[2];
|
|
97
|
-
_.ops.push(op);
|
|
98
|
-
break;
|
|
99
|
-
}
|
|
100
|
-
if (t[2]) _.ops.pop();
|
|
101
|
-
_.trys.pop();
|
|
102
|
-
continue;
|
|
103
|
-
}
|
|
104
|
-
op = body.call(thisArg, _);
|
|
105
|
-
} catch (e) {
|
|
106
|
-
op = [6, e];
|
|
107
|
-
y = 0;
|
|
108
|
-
} finally {
|
|
109
|
-
f = t = 0;
|
|
110
|
-
}
|
|
111
|
-
if (op[0] & 5) throw op[1];
|
|
112
|
-
return {
|
|
113
|
-
value: op[0] ? op[1] : void 0,
|
|
114
|
-
done: true
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
var __values = this && this.__values || function (o) {
|
|
119
|
-
var s = typeof Symbol === "function" && Symbol.iterator,
|
|
120
|
-
m = s && o[s],
|
|
121
|
-
i = 0;
|
|
122
|
-
if (m) return m.call(o);
|
|
123
|
-
if (o && typeof o.length === "number") return {
|
|
124
|
-
next: function next() {
|
|
125
|
-
if (o && i >= o.length) o = void 0;
|
|
126
|
-
return {
|
|
127
|
-
value: o && o[i++],
|
|
128
|
-
done: !o
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
133
|
-
};
|
|
134
|
-
var __importDefault = this && this.__importDefault || function (mod) {
|
|
135
|
-
return mod && mod.__esModule ? mod : {
|
|
136
|
-
"default": mod
|
|
137
|
-
};
|
|
138
|
-
};
|
|
139
3
|
Object.defineProperty(exports, "__esModule", {
|
|
140
4
|
value: true
|
|
141
5
|
});
|
|
142
|
-
var jszip_1 = __importDefault(require("jszip"));
|
|
143
6
|
var FileUtil;
|
|
144
7
|
(function (FileUtil) {
|
|
145
8
|
/**
|
|
146
|
-
*
|
|
147
|
-
* @param
|
|
148
|
-
* @param
|
|
149
|
-
|
|
9
|
+
* 提取文件名的辅助函数
|
|
10
|
+
* @param url
|
|
11
|
+
* @param response
|
|
12
|
+
*/
|
|
13
|
+
function extractFilename(url, response) {
|
|
14
|
+
// 尝试从 Content-Disposition 头获取文件名
|
|
15
|
+
var contentDisposition = response.headers.get('content-disposition');
|
|
16
|
+
if (contentDisposition) {
|
|
17
|
+
var filenameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
|
|
18
|
+
if (filenameMatch && filenameMatch[1]) {
|
|
19
|
+
return filenameMatch[1].replace(/['"]/g, '');
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// 从 URL 提取文件名
|
|
23
|
+
var urlFilename = url.split('/').pop();
|
|
24
|
+
return urlFilename || 'download';
|
|
25
|
+
}
|
|
26
|
+
FileUtil.extractFilename = extractFilename;
|
|
27
|
+
/**
|
|
28
|
+
* 简单提取文件扩展名的辅助函数
|
|
29
|
+
* @param url
|
|
150
30
|
*/
|
|
151
|
-
function
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
return __generator(this, function (_b) {
|
|
156
|
-
switch (_b.label) {
|
|
157
|
-
case 0:
|
|
158
|
-
zip = new jszip_1.default();
|
|
159
|
-
try {
|
|
160
|
-
for (fileList_1 = __values(fileList), fileList_1_1 = fileList_1.next(); !fileList_1_1.done; fileList_1_1 = fileList_1.next()) {
|
|
161
|
-
file_1 = fileList_1_1.value;
|
|
162
|
-
zip.file(file_1.name, file_1);
|
|
163
|
-
}
|
|
164
|
-
} catch (e_1_1) {
|
|
165
|
-
e_1 = {
|
|
166
|
-
error: e_1_1
|
|
167
|
-
};
|
|
168
|
-
} finally {
|
|
169
|
-
try {
|
|
170
|
-
if (fileList_1_1 && !fileList_1_1.done && (_a = fileList_1.return)) _a.call(fileList_1);
|
|
171
|
-
} finally {
|
|
172
|
-
if (e_1) throw e_1.error;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
return [4 /*yield*/, zip.generateAsync({
|
|
176
|
-
type: 'blob'
|
|
177
|
-
}, function (item) {
|
|
178
|
-
onProgress === null || onProgress === void 0 ? void 0 : onProgress(item.currentFile, item.percent);
|
|
179
|
-
})];
|
|
180
|
-
case 1:
|
|
181
|
-
blob = _b.sent();
|
|
182
|
-
file = new File([blob], "\u201C".concat(fileList[0].name, "\u201D\u7B49").concat(fileList.length, "\u4E2A\u6587\u4EF6.zip"), {
|
|
183
|
-
type: blob.type
|
|
184
|
-
});
|
|
185
|
-
return [2 /*return*/, file];
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
});
|
|
31
|
+
function getExt(url) {
|
|
32
|
+
var _a;
|
|
33
|
+
var ext = (_a = url.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLocaleLowerCase();
|
|
34
|
+
return ext || url;
|
|
189
35
|
}
|
|
190
|
-
FileUtil.
|
|
36
|
+
FileUtil.getExt = getExt;
|
|
37
|
+
FileUtil.ellisipsFileName = function (fileName, maxLength) {
|
|
38
|
+
if (maxLength === void 0) {
|
|
39
|
+
maxLength = 30;
|
|
40
|
+
}
|
|
41
|
+
if (!fileName) return '';
|
|
42
|
+
if (fileName.length > maxLength) {
|
|
43
|
+
var len = Math.floor((maxLength - 3) / 2);
|
|
44
|
+
return fileName.slice(0, len) + '...' + fileName.slice(-len);
|
|
45
|
+
}
|
|
46
|
+
return fileName;
|
|
47
|
+
};
|
|
48
|
+
var _getFileName = function _getFileName(url) {
|
|
49
|
+
if (!url) return;
|
|
50
|
+
if (url.includes('*')) return url.split('*')[1];
|
|
51
|
+
return url.split('/').slice(-1).toString();
|
|
52
|
+
};
|
|
53
|
+
FileUtil.getFileName = function (url, maxLength) {
|
|
54
|
+
if (maxLength) {
|
|
55
|
+
return FileUtil.ellisipsFileName(_getFileName(url), maxLength);
|
|
56
|
+
}
|
|
57
|
+
return _getFileName(url);
|
|
58
|
+
};
|
|
191
59
|
})(FileUtil || (FileUtil = {}));
|
|
192
60
|
exports.default = FileUtil;
|
package/lib/system/SystemUtil.js
CHANGED
|
@@ -129,7 +129,11 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
129
129
|
* @author nanshen
|
|
130
130
|
* @creat 2021-09-15 14:24:57
|
|
131
131
|
*/
|
|
132
|
+
var FileUtil_1 = __importDefault(require("../file/FileUtil"));
|
|
132
133
|
var TransferUtil_1 = __importDefault(require("../transfer/TransferUtil"));
|
|
134
|
+
var streamsaver_1 = __importDefault(require("streamsaver"));
|
|
135
|
+
var MITM = 'https://ns.nihaonanshen.com/assets/stream/mitm.html';
|
|
136
|
+
streamsaver_1.default.mitm = MITM;
|
|
133
137
|
var SystemUtil;
|
|
134
138
|
(function (SystemUtil) {
|
|
135
139
|
/**
|
|
@@ -157,12 +161,13 @@ var SystemUtil;
|
|
|
157
161
|
* downloadFile('http://XXX.txt','text.txt')
|
|
158
162
|
*/
|
|
159
163
|
function downloadFile(url, name) {
|
|
164
|
+
var _a;
|
|
160
165
|
return __awaiter(this, void 0, void 0, function () {
|
|
161
|
-
var response,
|
|
162
|
-
return __generator(this, function (
|
|
163
|
-
switch (
|
|
166
|
+
var response, contentLength, total, finalFilename, fileStream, error_1;
|
|
167
|
+
return __generator(this, function (_b) {
|
|
168
|
+
switch (_b.label) {
|
|
164
169
|
case 0:
|
|
165
|
-
|
|
170
|
+
_b.trys.push([0, 2,, 3]);
|
|
166
171
|
return [4 /*yield*/, fetch(url, {
|
|
167
172
|
method: 'GET',
|
|
168
173
|
headers: {
|
|
@@ -170,33 +175,90 @@ var SystemUtil;
|
|
|
170
175
|
}
|
|
171
176
|
})];
|
|
172
177
|
case 1:
|
|
173
|
-
response =
|
|
174
|
-
if (!response.ok)
|
|
175
|
-
|
|
178
|
+
response = _b.sent();
|
|
179
|
+
if (!response.ok) throw new Error("HTTP error! status: ".concat(response.status));
|
|
180
|
+
contentLength = response.headers.get('content-length');
|
|
181
|
+
total = contentLength ? parseInt(contentLength, 10) : undefined;
|
|
182
|
+
finalFilename = name || FileUtil_1.default.extractFilename(url, response);
|
|
183
|
+
fileStream = streamsaver_1.default.createWriteStream(finalFilename, {
|
|
184
|
+
size: total
|
|
185
|
+
});
|
|
186
|
+
// 检查浏览器是否支持流式传输
|
|
187
|
+
if (window.WritableStream && ((_a = response.body) === null || _a === void 0 ? void 0 : _a.pipeTo)) {
|
|
188
|
+
// 直接管道传输(最高效)
|
|
189
|
+
return [2 /*return*/, response.body.pipeTo(fileStream).then(function () {
|
|
190
|
+
return console.log('下载完成');
|
|
191
|
+
}).catch(function (error) {
|
|
192
|
+
console.error('下载失败:', error);
|
|
193
|
+
throw error;
|
|
194
|
+
})];
|
|
195
|
+
} else {
|
|
196
|
+
// 降级方案:手动读取和写入
|
|
197
|
+
return [2 /*return*/, manualStreamDownload(response, fileStream)];
|
|
176
198
|
}
|
|
177
|
-
return [
|
|
199
|
+
return [3 /*break*/, 3];
|
|
178
200
|
case 2:
|
|
179
|
-
|
|
180
|
-
SystemUtil.downloadFileByBlob(blob, name || url.split('/').pop());
|
|
181
|
-
return [3 /*break*/, 4];
|
|
182
|
-
case 3:
|
|
183
|
-
error_1 = _a.sent();
|
|
201
|
+
error_1 = _b.sent();
|
|
184
202
|
console.error('下载失败:', error_1);
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
clickEvent = document.createEvent('MouseEvents');
|
|
190
|
-
clickEvent.initEvent('click', true, true);
|
|
191
|
-
a.dispatchEvent(clickEvent);
|
|
192
|
-
return [3 /*break*/, 4];
|
|
193
|
-
case 4:
|
|
203
|
+
// 降级方案
|
|
204
|
+
fallbackDownload(url, name);
|
|
205
|
+
return [3 /*break*/, 3];
|
|
206
|
+
case 3:
|
|
194
207
|
return [2 /*return*/];
|
|
195
208
|
}
|
|
196
209
|
});
|
|
197
210
|
});
|
|
198
211
|
}
|
|
199
212
|
SystemUtil.downloadFile = downloadFile;
|
|
213
|
+
// 最终降级方案
|
|
214
|
+
function fallbackDownload(url, filename) {
|
|
215
|
+
var a = document.createElement('a');
|
|
216
|
+
a.href = url;
|
|
217
|
+
if (filename) a.download = filename;
|
|
218
|
+
a.target = '_blank';
|
|
219
|
+
a.style.display = 'none';
|
|
220
|
+
document.body.appendChild(a);
|
|
221
|
+
a.click();
|
|
222
|
+
document.body.removeChild(a);
|
|
223
|
+
}
|
|
224
|
+
// 手动流式下载(兼容性降级)
|
|
225
|
+
function manualStreamDownload(response, fileStream) {
|
|
226
|
+
var _a;
|
|
227
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
228
|
+
var reader, writer, _b, done, value;
|
|
229
|
+
return __generator(this, function (_c) {
|
|
230
|
+
switch (_c.label) {
|
|
231
|
+
case 0:
|
|
232
|
+
reader = (_a = response.body) === null || _a === void 0 ? void 0 : _a.getReader();
|
|
233
|
+
writer = fileStream.getWriter();
|
|
234
|
+
if (!reader) throw new Error('无法获取响应流');
|
|
235
|
+
_c.label = 1;
|
|
236
|
+
case 1:
|
|
237
|
+
_c.trys.push([1,, 6, 8]);
|
|
238
|
+
_c.label = 2;
|
|
239
|
+
case 2:
|
|
240
|
+
if (!true) return [3 /*break*/, 5];
|
|
241
|
+
return [4 /*yield*/, reader.read()];
|
|
242
|
+
case 3:
|
|
243
|
+
_b = _c.sent(), done = _b.done, value = _b.value;
|
|
244
|
+
if (done) return [3 /*break*/, 5];
|
|
245
|
+
return [4 /*yield*/, writer.write(value)];
|
|
246
|
+
case 4:
|
|
247
|
+
_c.sent();
|
|
248
|
+
return [3 /*break*/, 2];
|
|
249
|
+
case 5:
|
|
250
|
+
return [3 /*break*/, 8];
|
|
251
|
+
case 6:
|
|
252
|
+
return [4 /*yield*/, writer.close()];
|
|
253
|
+
case 7:
|
|
254
|
+
_c.sent();
|
|
255
|
+
return [7 /*endfinally*/];
|
|
256
|
+
case 8:
|
|
257
|
+
return [2 /*return*/];
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
}
|
|
200
262
|
/**
|
|
201
263
|
* 通过base64下载文件
|
|
202
264
|
* @param base64 base64字符串
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tools-min-ns",
|
|
3
3
|
"description": "工具包适用于前端以及node",
|
|
4
|
-
"version": "1.18.
|
|
4
|
+
"version": "1.18.17",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "nanshen",
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"@babel/preset-typescript": "^7.10.4",
|
|
42
42
|
"@types/node": "^20.5.0",
|
|
43
43
|
"@types/react": "^17.0.21",
|
|
44
|
+
"@types/streamsaver": "^2.0.5",
|
|
44
45
|
"core-js": "3",
|
|
45
46
|
"del": "^5.1.0",
|
|
46
47
|
"gulp": "^4.0.2",
|
|
@@ -52,6 +53,6 @@
|
|
|
52
53
|
"typescript": "^4.9.5"
|
|
53
54
|
},
|
|
54
55
|
"dependencies": {
|
|
55
|
-
"
|
|
56
|
+
"streamsaver": "^2.0.6"
|
|
56
57
|
}
|
|
57
58
|
}
|