@studio-kit/utils-browser 1.0.2 → 1.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/src/FIO.js CHANGED
@@ -1,14 +1,22 @@
1
- export default class FIO {
1
+ import CommonFIO from "@studio-kit/utils-common/FIO.js";
2
+ import { saveAs } from 'file-saver'
3
+ import axios from 'axios'
4
+ import HTTP from './HTTP.js'
5
+ export default class FIO extends CommonFIO {
2
6
  static loadingMap = {};
3
7
  static loadedMap = {};
4
8
  static loadLib(src, key, type) {
9
+ src = CommonFIO.getPath({ path: src })
5
10
  const {
6
11
  loadingMap,
7
12
  loadedMap
8
13
  } = FIO
9
- if (key && window[key]) return Promise.resolve(window['key']);
10
- if (loadedMap[src]) return Promise.resolve();
14
+ if (key && window[key]) return Promise.resolve(window[key]);
11
15
  if (loadingMap[src]) return loadingMap[src];
16
+ if (Object.prototype.hasOwnProperty.call(loadedMap, src)) {
17
+ const cached = loadedMap[src];
18
+ return Promise.resolve(cached === true ? undefined : cached);
19
+ }
12
20
  if (/\.js$/.test(src) || type === 'js')
13
21
  return loadingMap[src] = new Promise((resolve, reject) => {
14
22
  const script = document.createElement('script');
@@ -44,6 +52,25 @@ export default class FIO {
44
52
  document.head.appendChild(link);
45
53
  });
46
54
  }
55
+ if (/\.json$/.test(src) || type === 'json') {
56
+ return loadingMap[src] = fetch(src)
57
+ .then((res) => {
58
+ if (!res.ok) {
59
+ throw new Error(`加载json文件错误(src: ${src})(status: ${res.status})`);
60
+ }
61
+ return res.json();
62
+ })
63
+ .then((data) => {
64
+ delete loadingMap[src];
65
+ loadedMap[src] = data;
66
+ return data;
67
+ })
68
+ .catch((err) => {
69
+ delete loadingMap[src];
70
+ console.error(err);
71
+ throw err;
72
+ });
73
+ }
47
74
  }
48
75
  static joinPath({ pathParts, os }) {
49
76
  if (!Array.isArray(pathParts) || pathParts.length === 0) {
@@ -76,4 +103,157 @@ export default class FIO {
76
103
 
77
104
  return joinedPath;
78
105
  }
106
+ static download({ content, url, fileName }) {
107
+ if (content) {
108
+ const suffix = fileName.split('.').pop();
109
+ if (suffix === 'json' && typeof content === 'object') {
110
+ content = JSON.stringify(content, null, 2);
111
+ content = new Blob([content], { type: 'application/json;charset=utf-8' });
112
+ }
113
+ saveAs(content, fileName)
114
+ } else {
115
+ saveAs(url, fileName)
116
+ }
117
+ }
118
+ /**
119
+ * 上传文件(对应后端 POST /api/upload)
120
+ * @param {Object} options
121
+ * @param {string} options.baseURL - 请求 baseURL(如 '/studio-server')
122
+ * @param {Blob|Blob[]|File|File[]} options.files - 待上传文件
123
+ * @param {string} [options.uploadPath] - 相对上传路径
124
+ * @param {string} [options.uploadAbsPath] - 绝对上传路径
125
+ * @param {string} [options.unzipPath] - 解压目标路径
126
+ * @param {string} [options.fileName] - 指定文件名
127
+ * @param {string} [options.modelKey] - 写入数据模型的 key
128
+ * @param {string} [options.script] - 上传后执行的脚本
129
+ * @param {boolean|string} [options.needUncompress] - 是否解压
130
+ * @param {boolean|string} [options.thumbnail] - 是否生成缩略图
131
+ * @param {boolean|string} [options.keepName] - 是否保留原文件名
132
+ * @param {boolean|string} [options.uploadOnly] - 是否仅上传不落库
133
+ * @param {Function} [options.onUploadProgress] - 上传进度回调
134
+ * @returns {Promise<any>}
135
+ */
136
+ static async upload({
137
+ baseURL,
138
+ files,
139
+ uploadPath,
140
+ uploadAbsPath,
141
+ unzipPath,
142
+ fileName,
143
+ modelKey,
144
+ script,
145
+ needUncompress,
146
+ thumbnail,
147
+ keepName,
148
+ uploadOnly,
149
+ onUploadProgress,
150
+ }) {
151
+ const res = await HTTP.request({
152
+ method: 'POST',
153
+ url: '/api/upload',
154
+ query: {
155
+ uploadPath,
156
+ uploadAbsPath,
157
+ unzipPath,
158
+ fileName,
159
+ modelKey,
160
+ script,
161
+ needUncompress,
162
+ thumbnail,
163
+ keepName,
164
+ uploadOnly,
165
+ },
166
+ data: {
167
+ files,
168
+ },
169
+ contentType: 'formData',
170
+ baseURL,
171
+ onUploadProgress,
172
+ })
173
+ return res.data
174
+ }
175
+ /**
176
+ * 打开文件选择对话框
177
+ * @param {Object} options - 配置选项
178
+ * @param {boolean} [options.multiple=false] - 是否允许多选
179
+ * @param {string} [options.accept] - 允许的文件类型(如 "image/*", ".pdf")
180
+ * @returns {Promise<File[]>} 包含选定文件的Promise对象
181
+ */
182
+ static openFileDialog(options = {}) {
183
+ return new Promise((resolve) => {
184
+ // 创建隐藏的文件输入元素
185
+ const input = document.createElement('input');
186
+ input.type = 'file';
187
+ input.style.display = 'none';
188
+
189
+ // 设置多选属性
190
+ if (options.multiple) {
191
+ input.multiple = true;
192
+ }
193
+
194
+ // 设置文件类型过滤
195
+ if (options.accept) {
196
+ input.accept = options.accept;
197
+ }
198
+
199
+ // 监听文件选择变化
200
+ input.addEventListener('change', () => {
201
+ resolve(Array.from(input.files));
202
+ document.body.removeChild(input); // 清理DOM
203
+ });
204
+
205
+ // 监听取消选择
206
+ input.addEventListener('cancel', () => {
207
+ resolve([]);
208
+ document.body.removeChild(input); // 清理DOM
209
+ });
210
+
211
+ // 添加到DOM并触发点击
212
+ document.body.appendChild(input);
213
+ input.click();
214
+ });
215
+ }
216
+ static convertBase64ToBlob(base64Image) {
217
+ // Split into two parts
218
+ const parts = base64Image.split(';base64,');
219
+
220
+ // Hold the content type
221
+ const imageType = parts[0].split(':')[1];
222
+
223
+ // Decode Base64 string
224
+ const decodedData = window.atob(parts[1]);
225
+
226
+ // Create UNIT8ARRAY of size same as row data length
227
+ const uInt8Array = new Uint8Array(decodedData.length);
228
+
229
+ // Insert all character code into uInt8Array
230
+ for (let i = 0; i < decodedData.length; ++i) {
231
+ uInt8Array[i] = decodedData.charCodeAt(i);
232
+ }
233
+
234
+ // Return BLOB image after conversion
235
+ return new Blob([uInt8Array], { type: imageType });
236
+ }
237
+ static async readJson({ filePath }) {
238
+ const res = await axios({
239
+ method: 'POST',
240
+ url: '/api/util/readFileContent',
241
+ data: {
242
+ filePath,
243
+ isRelativePath: true,
244
+ },
245
+ baseURL: '/studio-server',
246
+ })
247
+ let { data } = res;
248
+ if (typeof data === 'string') {
249
+ try {
250
+ data = JSON.parse(data)
251
+ } catch (error) {
252
+ console.error(error)
253
+ }
254
+ } else if (data.error) {
255
+ return console.error(data.error)
256
+ }
257
+ return data;
258
+ }
79
259
  }
package/src/Geo.js ADDED
@@ -0,0 +1,2 @@
1
+ import Geo from '@studio-kit/utils-common/Geo.js'
2
+ export default Geo
package/src/HTTP.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import CommonHTTP from '@studio-kit/utils-common/HTTP.js'
2
2
  export default class HTTP extends CommonHTTP {
3
+ static FormData = window.FormData
3
4
  static getUrlQuery() {
4
5
  const result = {}
5
6
  if (location.search) {
@@ -17,4 +18,23 @@ export default class HTTP extends CommonHTTP {
17
18
  }
18
19
  return result
19
20
  }
21
+ static checkIsInputFile(value) {
22
+ return value instanceof Blob
23
+ }
24
+ static _beforeRequest({ data, headers, baseURL }) {
25
+ let defaultStudioSrc = window.$std_default_api_src || 'local'
26
+ if (data && data.dataSourceKey) {
27
+ defaultStudioSrc = data.dataSourceKey
28
+ }
29
+ if (headers && headers.SRC || headers && headers.src) {
30
+
31
+ } else {
32
+ if (baseURL == "/studio-server") {
33
+ headers['SRC'] = defaultStudioSrc
34
+ }
35
+ if (!baseURL) {
36
+ headers['SRC'] = defaultStudioSrc
37
+ }
38
+ }
39
+ }
20
40
  }