@cpzxrobot/sdk 1.2.91 → 1.2.93
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/device_gateway.ts +1 -1
- package/dist/device_gateway.js +1 -1
- package/dist/index.js +15 -411
- package/dist/mobile_platform.js +154 -0
- package/dist/platform_interface.js +12 -0
- package/dist/user_gateway.js +14 -32
- package/dist/web_platform.js +291 -0
- package/dist/windows_platform.js +128 -0
- package/index.ts +23 -455
- package/mobile_platform.ts +179 -0
- package/package.json +1 -1
- package/platform_interface.ts +35 -0
- package/types.d.ts +12 -10
- package/user_gateway.ts +14 -32
- package/web_platform.ts +322 -0
- package/windows_platform.ts +129 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { PlatformInterface } from "./platform_interface";
|
|
2
|
+
import { Factory, MyAxiosInstance, Unit } from "./types";
|
|
3
|
+
|
|
4
|
+
export class MobilePlatform implements PlatformInterface {
|
|
5
|
+
private platform: {
|
|
6
|
+
callHandler: Function;
|
|
7
|
+
};
|
|
8
|
+
private sseCallbacks: { [key: string]: (data: any) => void } = {};
|
|
9
|
+
token: string = "";
|
|
10
|
+
appCode: string = "";
|
|
11
|
+
baseURL: string = "";
|
|
12
|
+
|
|
13
|
+
constructor() {
|
|
14
|
+
// @ts-ignore
|
|
15
|
+
this.platform = window.flutter_inappwebview;
|
|
16
|
+
|
|
17
|
+
window.addEventListener('message', (event) => {
|
|
18
|
+
if (event.data == 'capturePort') {
|
|
19
|
+
const port = event.ports[0];
|
|
20
|
+
if (port != null) {
|
|
21
|
+
port.onmessage = (event: MessageEvent) => {
|
|
22
|
+
if (event.data.id != undefined) {
|
|
23
|
+
const callback = this.sseCallbacks[event.data.id];
|
|
24
|
+
callback?.(event.data.data);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}, false);
|
|
30
|
+
}
|
|
31
|
+
setSelectedFarm(farm: Factory): void {
|
|
32
|
+
throw new Error("Method not implemented.");
|
|
33
|
+
}
|
|
34
|
+
setSelectedUnit(unit: Unit): void {
|
|
35
|
+
this.platform.callHandler("selectUnit", unit).then((_res:any) => {
|
|
36
|
+
// @ts-ignore
|
|
37
|
+
window._notifyUnitChanged?.(unit);
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
ready() {
|
|
43
|
+
if (
|
|
44
|
+
// @ts-ignore
|
|
45
|
+
window.flutter_inappwebview != null &&
|
|
46
|
+
// @ts-ignore
|
|
47
|
+
window.flutter_inappwebview.callHandler != null
|
|
48
|
+
) {
|
|
49
|
+
return Promise.resolve(true);
|
|
50
|
+
} else {
|
|
51
|
+
return new Promise<boolean>((resolve, reject) => {
|
|
52
|
+
window.addEventListener(
|
|
53
|
+
"flutterInAppWebViewPlatformReady",
|
|
54
|
+
function () {
|
|
55
|
+
console.log("flutter android/ios platform is ready");
|
|
56
|
+
resolve(true);
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
setTimeout(() => {
|
|
60
|
+
console.log("flutter android/ios platform is timeout");
|
|
61
|
+
reject("timeout");
|
|
62
|
+
}, 1500);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
getAxiosFromMiniApp(): MyAxiosInstance {
|
|
69
|
+
const that = this;
|
|
70
|
+
return {
|
|
71
|
+
get: function (url, data) {
|
|
72
|
+
return that.platform.callHandler("axios_get", url, data);
|
|
73
|
+
},
|
|
74
|
+
post: function (url, data) {
|
|
75
|
+
return that.platform.callHandler("axios_post", url, data);
|
|
76
|
+
},
|
|
77
|
+
getAndSave: function (url, config) {
|
|
78
|
+
return that.platform.callHandler("axios_getAndSave", url, config);
|
|
79
|
+
},
|
|
80
|
+
getAndPreview: function (url, config) {
|
|
81
|
+
if (config == undefined) {
|
|
82
|
+
config = {};
|
|
83
|
+
}
|
|
84
|
+
if (config.preview == undefined) {
|
|
85
|
+
config.preview = true;
|
|
86
|
+
}
|
|
87
|
+
return that.platform.callHandler("axios_getAndSave", url, config);
|
|
88
|
+
},
|
|
89
|
+
upload: function (url, option) {
|
|
90
|
+
return that.platform.callHandler("axios_upload", url, option);
|
|
91
|
+
},
|
|
92
|
+
getAsSse: async function (url, fn, config?) {
|
|
93
|
+
var randomId = Math.random().toString(36).substring(2);
|
|
94
|
+
that.sseCallbacks[randomId] = fn;
|
|
95
|
+
console.log("getAsSse", url, fn, randomId);
|
|
96
|
+
await that.platform.callHandler("axios_getAsSse", url, config, randomId);
|
|
97
|
+
delete that.sseCallbacks[randomId];
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async getSelectedFarmFromMiniApp(): Promise<any> {
|
|
103
|
+
return this.platform.callHandler("getSelectedFarmFromMiniApp");
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async getSelectedUnitFromMiniApp(): Promise<any> {
|
|
107
|
+
return this.platform.callHandler("getSelectedUnitFromMiniApp");
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async jumpToMiniApp(url: string): Promise<void> {
|
|
111
|
+
return this.platform.callHandler("app.openMiniapp", url);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async scanQrcode(): Promise<string> {
|
|
115
|
+
return this.platform.callHandler("app.scanQrcode");
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
setTitle(title: string): void {
|
|
119
|
+
this.platform.callHandler("app.setTitle", title);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async saveBase64(base64: string, filename: string): Promise<void> {
|
|
123
|
+
return this.platform.callHandler("app.saveBase64", base64, filename);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async saveBlob(blob: Blob, filename: string): Promise<void> {
|
|
127
|
+
const reader = new FileReader();
|
|
128
|
+
return new Promise<void>((resolve, reject) => {
|
|
129
|
+
reader.readAsDataURL(blob);
|
|
130
|
+
reader.onloadend = async () => {
|
|
131
|
+
const base64 = reader.result as string;
|
|
132
|
+
await this.saveBase64(base64, filename);
|
|
133
|
+
resolve();
|
|
134
|
+
};
|
|
135
|
+
reader.onerror = (err) => {
|
|
136
|
+
reject(err);
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
vibrate(time?: number): void {
|
|
142
|
+
this.platform.callHandler("app.vibrate", time);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async showInDeviceManager(deviceId: any, type: string): Promise<void> {
|
|
146
|
+
return this.platform.callHandler("app.showInDeviceManager", deviceId, type);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
reloadGroup(group: string): void {
|
|
150
|
+
this.platform.callHandler("app.reloadGroup", group);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
async getGeo(): Promise<{ lat: number; lng: number }> {
|
|
154
|
+
const result = await this.platform.callHandler("app.getGeo");
|
|
155
|
+
if (result.error) {
|
|
156
|
+
throw result.error;
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
lat: result.lat,
|
|
160
|
+
lng: result.lng
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
setResult(name: string, value: any): void {
|
|
165
|
+
this.platform.callHandler("app.setResult", name, value);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
setResultAs(name: string, value: any, type: string): void {
|
|
169
|
+
this.platform.callHandler("app.setResultAs", name, value, type);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
setError(message: string): void {
|
|
173
|
+
this.platform.callHandler("app.setError", message);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
setProgress(precentage: number): void {
|
|
177
|
+
this.platform.callHandler("app.setProgress", precentage);
|
|
178
|
+
}
|
|
179
|
+
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Factory, MyAxiosInstance, Unit } from "./types";
|
|
2
|
+
|
|
3
|
+
export abstract class PlatformInterface {
|
|
4
|
+
|
|
5
|
+
token: string;
|
|
6
|
+
appCode: string;
|
|
7
|
+
baseURL: string;
|
|
8
|
+
|
|
9
|
+
//define constructor(token: string, appCode: string) {
|
|
10
|
+
constructor(token: string, appCode: string, baseURL: string) {
|
|
11
|
+
this.token = token;
|
|
12
|
+
this.appCode = appCode;
|
|
13
|
+
this.baseURL = baseURL;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
abstract getSelectedFarmFromMiniApp(): Promise<any>;
|
|
17
|
+
abstract getSelectedUnitFromMiniApp(): Promise<any>;
|
|
18
|
+
abstract jumpToMiniApp(url: string): Promise<void>;
|
|
19
|
+
abstract scanQrcode(): Promise<string>;
|
|
20
|
+
abstract setTitle(title: string): void;
|
|
21
|
+
abstract saveBase64(base64: string, filename: string): Promise<void>;
|
|
22
|
+
abstract saveBlob(blob: Blob, filename: string): Promise<void>;
|
|
23
|
+
abstract vibrate(time?: number): void;
|
|
24
|
+
abstract showInDeviceManager(deviceId: any, type: string): Promise<void>;
|
|
25
|
+
abstract reloadGroup(key: string): void;
|
|
26
|
+
abstract getGeo(): Promise<{ lat: number; lng: number }>;
|
|
27
|
+
abstract setResult(name: string, value: any): void;
|
|
28
|
+
abstract setResultAs(name: string, value: any, type: string): void;
|
|
29
|
+
abstract setError(message: string): void;
|
|
30
|
+
abstract setProgress(precentage: number): void;
|
|
31
|
+
abstract getAxiosFromMiniApp(): MyAxiosInstance;
|
|
32
|
+
abstract ready(): Promise<boolean>;
|
|
33
|
+
abstract setSelectedUnit(unit: Unit|String|Number): void;
|
|
34
|
+
abstract setSelectedFarm(farm: Factory|String|Number): void;
|
|
35
|
+
}
|
package/types.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ import { EnergyGateway } from "./energy_gateway";
|
|
|
21
21
|
import { type ElectricMeterRate } from "./energy_types/electric_meter_gateway";
|
|
22
22
|
import { ConstructionGateway } from "./construction_gateway";
|
|
23
23
|
import { SystemGateway } from "./system_gateway";
|
|
24
|
+
import { PlatformInterface } from "./platform_interface";
|
|
24
25
|
|
|
25
26
|
type Device = {
|
|
26
27
|
id: number;
|
|
@@ -360,18 +361,19 @@ class Cpzxrobot {
|
|
|
360
361
|
construction: ConstructionGateway;
|
|
361
362
|
system: SystemGateway;
|
|
362
363
|
dict: (key: string) => any;
|
|
363
|
-
|
|
364
|
-
|
|
364
|
+
platform: PlatformInterface;
|
|
365
|
+
// _getSelectedFarmFromMiniApp: () => Promise<Factory>;
|
|
366
|
+
// _getSelectedUnitFromMiniApp: () => Promise<Unit>;
|
|
365
367
|
openMiniApp: (url: string) => void;
|
|
366
368
|
on: (event: string, callback: (data: any) => void) => void;
|
|
367
|
-
setTitle: (title: string) => void;
|
|
368
|
-
saveBase64: (base64: string, filename: string) => void;
|
|
369
|
-
saveBlob: (blob: Blob, filename: string) => void;
|
|
370
|
-
scanQrcode: () => Promise<string>;
|
|
371
|
-
vibrate: (time?: number) => void;
|
|
372
|
-
reloadGroup: (key: string) => void;
|
|
373
|
-
getGeo: () => Promise<{ lat: number; lng: number }>;
|
|
374
|
-
showInDeviceManager: (deviceId: number, type: string) => Promise<void>;
|
|
369
|
+
// setTitle: (title: string) => void;
|
|
370
|
+
// saveBase64: (base64: string, filename: string) => void;
|
|
371
|
+
// saveBlob: (blob: Blob, filename: string) => void;
|
|
372
|
+
// scanQrcode: () => Promise<string>;
|
|
373
|
+
// vibrate: (time?: number) => void;
|
|
374
|
+
// reloadGroup: (key: string) => void;
|
|
375
|
+
// getGeo: () => Promise<{ lat: number; lng: number }>;
|
|
376
|
+
// showInDeviceManager: (deviceId: number, type: string) => Promise<void>;
|
|
375
377
|
}
|
|
376
378
|
|
|
377
379
|
declare global {
|
package/user_gateway.ts
CHANGED
|
@@ -27,7 +27,7 @@ export class UserGateway extends Object {
|
|
|
27
27
|
resolve(this._selectedFarm);
|
|
28
28
|
break;
|
|
29
29
|
case "miniapp_in_app":
|
|
30
|
-
this.context.
|
|
30
|
+
this.context.platform.getSelectedFarmFromMiniApp().then((farm: any) => {
|
|
31
31
|
this._selectedFarm = farm;
|
|
32
32
|
resolve(farm);
|
|
33
33
|
});
|
|
@@ -42,6 +42,15 @@ export class UserGateway extends Object {
|
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
public async selectUnit(unit: Unit|String|Number) {
|
|
46
|
+
if ((typeof unit === "string") || (typeof unit === "number")) {
|
|
47
|
+
var axios = await this.context.ready;
|
|
48
|
+
this.context.platform.setSelectedUnit(unit);
|
|
49
|
+
} else {
|
|
50
|
+
this.context.platform.setSelectedUnit(unit);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
45
54
|
//获得当前用户选择的单元
|
|
46
55
|
getSelectedUnit() {
|
|
47
56
|
return this.context.ready.then(() => {
|
|
@@ -51,7 +60,7 @@ export class UserGateway extends Object {
|
|
|
51
60
|
resolve(this._selectedUnit);
|
|
52
61
|
break;
|
|
53
62
|
case "miniapp_in_app":
|
|
54
|
-
this.context.
|
|
63
|
+
this.context.platform.getSelectedUnitFromMiniApp().then((unit: any) => {
|
|
55
64
|
this._selectedUnit = unit;
|
|
56
65
|
resolve(unit);
|
|
57
66
|
});
|
|
@@ -68,38 +77,11 @@ export class UserGateway extends Object {
|
|
|
68
77
|
}
|
|
69
78
|
|
|
70
79
|
set selectedFarm(farm: Factory) {
|
|
71
|
-
|
|
72
|
-
case "dev":
|
|
73
|
-
this._selectedFarm = farm;
|
|
74
|
-
break;
|
|
75
|
-
case "miniapp_in_app":
|
|
76
|
-
console.log("miniapp_in_app mode, ignore");
|
|
77
|
-
break;
|
|
78
|
-
case "miniapp_in_web":
|
|
79
|
-
this._selectedFarm = farm;
|
|
80
|
-
break;
|
|
81
|
-
default:
|
|
82
|
-
console.log("dev mode, ignore");
|
|
83
|
-
break;
|
|
84
|
-
}
|
|
80
|
+
this.context.platform.setSelectedFarm(farm);
|
|
85
81
|
}
|
|
86
82
|
|
|
87
|
-
set selectedUnit(
|
|
88
|
-
|
|
89
|
-
case "dev":
|
|
90
|
-
this._selectedUnit = farm;
|
|
91
|
-
break;
|
|
92
|
-
case "miniapp_in_app":
|
|
93
|
-
console.log("miniapp_in_app mode, ignore");
|
|
94
|
-
break;
|
|
95
|
-
case "miniapp_in_web":
|
|
96
|
-
this._selectedUnit = farm;
|
|
97
|
-
console.log("miniapp_in_web mode, ignore");
|
|
98
|
-
break;
|
|
99
|
-
default:
|
|
100
|
-
console.log("dev mode, ignore");
|
|
101
|
-
break;
|
|
102
|
-
}
|
|
83
|
+
set selectedUnit(unit: Unit) {
|
|
84
|
+
this.context.platform.setSelectedUnit(unit);
|
|
103
85
|
}
|
|
104
86
|
|
|
105
87
|
async add(user: any) {
|
package/web_platform.ts
ADDED
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
import { PlatformInterface } from "./platform_interface";
|
|
2
|
+
import { Factory, MyAxiosInstance, Unit } from "./types";
|
|
3
|
+
|
|
4
|
+
export class WebPlatform implements PlatformInterface {
|
|
5
|
+
token: string = "";
|
|
6
|
+
appCode: string = "";
|
|
7
|
+
baseURL: string = "";
|
|
8
|
+
_selectedFarm: Factory | undefined;
|
|
9
|
+
_selectedUnit: Unit | undefined;
|
|
10
|
+
|
|
11
|
+
constructor(token: string, appCode: string, baseURL: string, selectedFarm: Factory | undefined, selectedUnit: Unit | undefined) {
|
|
12
|
+
this.token = token;
|
|
13
|
+
this.appCode = appCode;
|
|
14
|
+
this.baseURL = baseURL;
|
|
15
|
+
this._selectedFarm = selectedFarm;
|
|
16
|
+
this._selectedUnit = selectedUnit;
|
|
17
|
+
}
|
|
18
|
+
setSelectedFarm(farm: Factory): void {
|
|
19
|
+
this._selectedFarm = farm;
|
|
20
|
+
}
|
|
21
|
+
setSelectedUnit(unit: Unit): void {
|
|
22
|
+
this._selectedUnit = unit;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async fetchWithAuth(input: RequestInfo, init?: RequestInit) {
|
|
26
|
+
const headers = new Headers(init?.headers);
|
|
27
|
+
headers.set('Authorization', this.token);
|
|
28
|
+
headers.set('Miniapp-Code', this.appCode);
|
|
29
|
+
const response = await fetch(this.baseURL + input.toString(), {
|
|
30
|
+
...init,
|
|
31
|
+
headers
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
if (!response.ok) {
|
|
35
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
36
|
+
}
|
|
37
|
+
return response;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
async streamWithAuth(input: RequestInfo, init?: RequestInit, fn?: Function) {
|
|
41
|
+
const headers = new Headers(init?.headers);
|
|
42
|
+
headers.set('Authorization', this.token);
|
|
43
|
+
headers.set('Miniapp-Code', this.appCode);
|
|
44
|
+
const response = await fetch(this.baseURL + input.toString(), {
|
|
45
|
+
...init,
|
|
46
|
+
headers
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
var reader = response.body!.getReader();
|
|
50
|
+
const decoder = new TextDecoder("utf-8");
|
|
51
|
+
let done = false;
|
|
52
|
+
var buf: string = "";
|
|
53
|
+
while (!done) {
|
|
54
|
+
const { value, done } = await reader.read();
|
|
55
|
+
if (done) {
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
const chunkValue = decoder.decode(value);
|
|
59
|
+
|
|
60
|
+
//split value to lines
|
|
61
|
+
// 将值拆分为行
|
|
62
|
+
buf = buf + chunkValue;
|
|
63
|
+
var i = buf.indexOf("\n");
|
|
64
|
+
while (i > -1) {
|
|
65
|
+
//find first \n
|
|
66
|
+
var line = buf.substring(0, i);
|
|
67
|
+
try {
|
|
68
|
+
if (line === "[DONE]") {
|
|
69
|
+
break;
|
|
70
|
+
} else {
|
|
71
|
+
// remove prefix 'data: '
|
|
72
|
+
// 移除前缀 'data: '
|
|
73
|
+
var data = JSON.parse(line.split(": ")[1]);
|
|
74
|
+
//{"choices":[{"delta":{"content":" </"},"index":0}],"created":1741749068,"id":"chatcmpl-67ccb889154043f5874cbf3a64ec163e","model":"DeepSeek-R1","object":"chat.completion.chunk"}
|
|
75
|
+
fn?.call(data);
|
|
76
|
+
}
|
|
77
|
+
} catch (e) {
|
|
78
|
+
console.error("解析失败", e);
|
|
79
|
+
}
|
|
80
|
+
buf = buf.substring(i + 1);
|
|
81
|
+
i = buf.indexOf("\n");
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
return true;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
processQueryParams(url: string, config?: any) {
|
|
88
|
+
if (config && config.params) {
|
|
89
|
+
const flattenParams = (params: any, prefix = '') => {
|
|
90
|
+
const result: Record<string, string> = {};
|
|
91
|
+
Object.keys(params).forEach(key => {
|
|
92
|
+
const value = params[key];
|
|
93
|
+
const fullKey = prefix ? `${prefix}[${key}]` : key;
|
|
94
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
95
|
+
Object.assign(result, flattenParams(value, fullKey));
|
|
96
|
+
} else if (value) {
|
|
97
|
+
result[fullKey] = value.toString();
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
return result;
|
|
101
|
+
};
|
|
102
|
+
const flattened = flattenParams(config.params);
|
|
103
|
+
url += "?" + new URLSearchParams(flattened).toString();
|
|
104
|
+
delete config.params;
|
|
105
|
+
}
|
|
106
|
+
return url;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
getAxiosFromMiniApp(): MyAxiosInstance {
|
|
110
|
+
var instance = this;
|
|
111
|
+
return {
|
|
112
|
+
get: async (url: string, config?: any) => {
|
|
113
|
+
url = instance.processQueryParams(url, config);
|
|
114
|
+
const response = await this.fetchWithAuth(url, {
|
|
115
|
+
method: 'GET',
|
|
116
|
+
headers: config?.headers
|
|
117
|
+
});
|
|
118
|
+
return { data: await response.json() };
|
|
119
|
+
},
|
|
120
|
+
post: async (url: string, data?: any, config?: any) => {
|
|
121
|
+
const response = await this.fetchWithAuth(url, {
|
|
122
|
+
method: 'POST',
|
|
123
|
+
headers: {
|
|
124
|
+
'Content-Type': 'application/json',
|
|
125
|
+
...config?.headers
|
|
126
|
+
},
|
|
127
|
+
body: JSON.stringify(data)
|
|
128
|
+
});
|
|
129
|
+
return { data: await response.json() };
|
|
130
|
+
},
|
|
131
|
+
getAndSave: async function(url: string, config?: any) {
|
|
132
|
+
url = instance.processQueryParams(url, config);
|
|
133
|
+
const response = await instance.fetchWithAuth(url, {
|
|
134
|
+
method: 'GET',
|
|
135
|
+
headers: config?.headers
|
|
136
|
+
});
|
|
137
|
+
const blob = await response.blob();
|
|
138
|
+
|
|
139
|
+
// 文件名解析逻辑
|
|
140
|
+
const contentDisposition = response.headers.get('Content-Disposition');
|
|
141
|
+
let filename = config?.fileName ?? ""; // 默认文件名
|
|
142
|
+
|
|
143
|
+
// 1. 优先使用响应头中的文件名
|
|
144
|
+
if (filename == "") {
|
|
145
|
+
if (contentDisposition) {
|
|
146
|
+
const utf8FilenameMatch = contentDisposition.match(/filename\*=UTF-8''(.+)/i);
|
|
147
|
+
if (utf8FilenameMatch) {
|
|
148
|
+
filename = decodeURIComponent(utf8FilenameMatch[1]);
|
|
149
|
+
} else {
|
|
150
|
+
const filenameMatch = contentDisposition.match(/filename="?(.+?)"?(;|$)/i);
|
|
151
|
+
if (filenameMatch) filename = filenameMatch[1];
|
|
152
|
+
}
|
|
153
|
+
} else {
|
|
154
|
+
filename = "file"
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
await instance.saveBlob(blob, filename);
|
|
158
|
+
return { data: blob };
|
|
159
|
+
},
|
|
160
|
+
getAndPreview: async function(url: string, config?: {
|
|
161
|
+
fileName?: string;
|
|
162
|
+
params?: any;
|
|
163
|
+
preview?: boolean;
|
|
164
|
+
}){
|
|
165
|
+
url = instance.processQueryParams(url, config);
|
|
166
|
+
return this.getAndSave(url, config);
|
|
167
|
+
},
|
|
168
|
+
upload: async (url: string, option?: any) => {
|
|
169
|
+
return new Promise<any>((resolve, reject) => {
|
|
170
|
+
const button = document.createElement("input");
|
|
171
|
+
button.type = "file";
|
|
172
|
+
button.style.display = "none";
|
|
173
|
+
button.multiple = option?.multiple || false;
|
|
174
|
+
document.body.appendChild(button);
|
|
175
|
+
button.click(); // 手动触发点击
|
|
176
|
+
button.onchange = async (e: Event) => {
|
|
177
|
+
const files = (e.target as HTMLInputElement).files;
|
|
178
|
+
if (files && files.length > 0) {
|
|
179
|
+
const formData = new FormData();
|
|
180
|
+
if (option?.multiple) {
|
|
181
|
+
for (let i = 0; i < files.length; i++) {
|
|
182
|
+
formData.append("files[]", files[i]);
|
|
183
|
+
}
|
|
184
|
+
} else {
|
|
185
|
+
formData.append(option?.["fileField"] || "file", files[0]);
|
|
186
|
+
}
|
|
187
|
+
for (let key in option?.["data"]) {
|
|
188
|
+
formData.append(key, option!["data"][key]);
|
|
189
|
+
}
|
|
190
|
+
const response = await instance.fetchWithAuth(url, {
|
|
191
|
+
method: 'POST',
|
|
192
|
+
body: formData
|
|
193
|
+
});
|
|
194
|
+
button.remove();
|
|
195
|
+
resolve({ data: await response.json() });
|
|
196
|
+
} else {
|
|
197
|
+
button.remove();
|
|
198
|
+
resolve({ data: { Error: "没有选择文件" } });
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
});
|
|
202
|
+
},
|
|
203
|
+
getAsSse: (url: string, fn: any, config?: {
|
|
204
|
+
fileName?: string;
|
|
205
|
+
params?: any;
|
|
206
|
+
preview?: boolean;
|
|
207
|
+
}) => {
|
|
208
|
+
return new Promise<any>((resolve, reject) => {
|
|
209
|
+
instance.streamWithAuth(url, {
|
|
210
|
+
method: 'GET',
|
|
211
|
+
}, fn);
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
ready(): Promise<boolean> {
|
|
217
|
+
throw new Error("Method not implemented.");
|
|
218
|
+
}
|
|
219
|
+
getSelectedFarmFromMiniApp(): Promise<any> {
|
|
220
|
+
throw new Error("Method not available in web platform");
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
getSelectedUnitFromMiniApp(): Promise<any> {
|
|
224
|
+
throw new Error("Method not available in web platform");
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
jumpToMiniApp(url: string): Promise<void> {
|
|
228
|
+
window.location.href = url;
|
|
229
|
+
return Promise.resolve();
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
scanQrcode(): Promise<string> {
|
|
233
|
+
throw new Error("Method not available in web platform");
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
setTitle(title: string): void {
|
|
237
|
+
document.title = title;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
async saveBase64(base64: string, filename: string): Promise<void> {
|
|
241
|
+
const byteCharacters = atob(base64);
|
|
242
|
+
const byteNumbers = new Array(byteCharacters.length);
|
|
243
|
+
for (let i = 0; i < byteCharacters.length; i++) {
|
|
244
|
+
byteNumbers[i] = byteCharacters.charCodeAt(i);
|
|
245
|
+
}
|
|
246
|
+
const byteArray = new Uint8Array(byteNumbers);
|
|
247
|
+
const blob = new Blob([byteArray], {
|
|
248
|
+
type: "application/octet-stream",
|
|
249
|
+
});
|
|
250
|
+
return this.saveBlob(blob, filename);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
saveBlob(blob: Blob, filename: string): Promise<void> {
|
|
254
|
+
return new Promise((resolve, reject) => {
|
|
255
|
+
try {
|
|
256
|
+
const url = URL.createObjectURL(blob);
|
|
257
|
+
const a = document.createElement("a");
|
|
258
|
+
a.href = url;
|
|
259
|
+
a.download = filename;
|
|
260
|
+
document.body.appendChild(a);
|
|
261
|
+
a.click();
|
|
262
|
+
setTimeout(() => {
|
|
263
|
+
URL.revokeObjectURL(url);
|
|
264
|
+
document.body.removeChild(a);
|
|
265
|
+
resolve();
|
|
266
|
+
}, 0);
|
|
267
|
+
} catch (error) {
|
|
268
|
+
reject(error);
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
vibrate(time?: number): void {
|
|
274
|
+
if (navigator.vibrate) {
|
|
275
|
+
navigator.vibrate(time || 200);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
showInDeviceManager(deviceId: any, type: string): Promise<void> {
|
|
280
|
+
return Promise.resolve();
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
reloadGroup(key: string): void {
|
|
284
|
+
// No implementation in web platform
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
getGeo(): Promise<{ lat: number; lng: number }> {
|
|
288
|
+
return new Promise((resolve, reject) => {
|
|
289
|
+
if (navigator.geolocation) {
|
|
290
|
+
navigator.geolocation.getCurrentPosition(
|
|
291
|
+
(position) => {
|
|
292
|
+
resolve({
|
|
293
|
+
lat: position.coords.latitude,
|
|
294
|
+
lng: position.coords.longitude
|
|
295
|
+
});
|
|
296
|
+
},
|
|
297
|
+
(error) => {
|
|
298
|
+
reject(error);
|
|
299
|
+
}
|
|
300
|
+
);
|
|
301
|
+
} else {
|
|
302
|
+
reject(new Error("浏览器不支持获取位置信息"));
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
setResult(name: string, value: any): void {
|
|
308
|
+
// No implementation in web platform
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
setResultAs(name: string, value: any, type: string): void {
|
|
312
|
+
// No implementation in web platform
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
setError(message: string): void {
|
|
316
|
+
console.error(message);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
setProgress(precentage: number): void {
|
|
320
|
+
// No implementation in web platform
|
|
321
|
+
}
|
|
322
|
+
}
|