@plasosdk/yxt-miniprogram 0.0.0-stage → 1.0.0
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 +43 -3
- package/init.js +80 -0
- package/package.json +22 -6
- package/pages/yxtDownload/yxtDownload.js +292 -0
- package/pages/yxtDownload/yxtDownload.json +4 -0
- package/pages/yxtDownload/yxtDownload.wxml +4 -0
- package/pages/yxtDownload/yxtDownload.wxss +13 -0
- package/utils/openYxtModule.js +80 -0
package/README.md
CHANGED
|
@@ -1,3 +1,43 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
# @plasosdk/yxt-miniprogram
|
|
2
|
+
|
|
3
|
+
云学堂嵌入小程序侧能力:打开作业/课堂/课程 web-view,以及板书保存页。
|
|
4
|
+
|
|
5
|
+
微信不允许 `npm i` 自动注册页面,所以安装后要跑一次 init(改 `app.json`、拷贝页面)。对方不用再零散拷文件。
|
|
6
|
+
|
|
7
|
+
## 对方接入
|
|
8
|
+
|
|
9
|
+
在**小程序根目录**(有 `app.json` 的那层):
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @plasosdk/yxt-miniprogram
|
|
13
|
+
npx yxt-mp-init
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
会得到:
|
|
17
|
+
|
|
18
|
+
- `pages/yxtDownload/`(路径不要改,H5 固定跳这里)
|
|
19
|
+
- `utils/openYxtModule.js`
|
|
20
|
+
- `app.json` 登记该页面,并补上相册权限
|
|
21
|
+
|
|
22
|
+
然后:
|
|
23
|
+
|
|
24
|
+
```js
|
|
25
|
+
const { openYxtModule } = require('../../utils/openYxtModule');
|
|
26
|
+
this.setData({
|
|
27
|
+
src: openYxtModule({ env: 'www', module: 'liveclass', token: token, userid: userid }),
|
|
28
|
+
});
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```xml
|
|
32
|
+
<web-view src="{{src}}" bindmessage="onTokenError"></web-view>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
升级:再执行一次 `npm update @plasosdk/yxt-miniprogram && npx yxt-mp-init`。
|
|
36
|
+
|
|
37
|
+
## 对方还要配的(微信后台,init 改不了)
|
|
38
|
+
|
|
39
|
+
开发 → 开发设置 → 服务器域名:
|
|
40
|
+
|
|
41
|
+
- **downloadFile 合法域名**、**request 合法域名**:`file.plaso.com`,以及板书图片所在 CDN / OSS
|
|
42
|
+
|
|
43
|
+
真机预览会校验这些域名;开发者工具需勾选「不校验合法域名、web-view、TLS 版本」。
|
package/init.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* 在对方小程序根目录执行:npx yxt-mp-init
|
|
4
|
+
* 会写入 pages/yxtDownload、utils/openYxtModule.js,并改 app.json(pages + 相册权限)。
|
|
5
|
+
*/
|
|
6
|
+
var fs = require('fs');
|
|
7
|
+
var path = require('path');
|
|
8
|
+
|
|
9
|
+
var PAGE_PATH = 'pages/yxtDownload/yxtDownload';
|
|
10
|
+
var ALBUM_DESC = '用于将课堂板书保存到相册';
|
|
11
|
+
|
|
12
|
+
function argValue(flag) {
|
|
13
|
+
var index = process.argv.indexOf(flag);
|
|
14
|
+
if (index < 0 || !process.argv[index + 1]) {
|
|
15
|
+
return '';
|
|
16
|
+
}
|
|
17
|
+
return process.argv[index + 1];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function findAppRoot(start) {
|
|
21
|
+
var dir = start;
|
|
22
|
+
for (var i = 0; i < 10; i++) {
|
|
23
|
+
if (fs.existsSync(path.join(dir, 'app.json'))) {
|
|
24
|
+
return dir;
|
|
25
|
+
}
|
|
26
|
+
var parent = path.dirname(dir);
|
|
27
|
+
if (parent === dir) {
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
dir = parent;
|
|
31
|
+
}
|
|
32
|
+
return '';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function copyDir(src, dest) {
|
|
36
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
37
|
+
fs.readdirSync(src).forEach(function (name) {
|
|
38
|
+
var from = path.join(src, name);
|
|
39
|
+
var to = path.join(dest, name);
|
|
40
|
+
if (fs.statSync(from).isDirectory()) {
|
|
41
|
+
copyDir(from, to);
|
|
42
|
+
} else {
|
|
43
|
+
fs.copyFileSync(from, to);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function patchAppJson(appRoot) {
|
|
49
|
+
var file = path.join(appRoot, 'app.json');
|
|
50
|
+
var raw = fs.readFileSync(file, 'utf8');
|
|
51
|
+
var app = JSON.parse(raw);
|
|
52
|
+
app.pages = app.pages || [];
|
|
53
|
+
if (app.pages.indexOf(PAGE_PATH) < 0) {
|
|
54
|
+
app.pages.push(PAGE_PATH);
|
|
55
|
+
}
|
|
56
|
+
app.permission = app.permission || {};
|
|
57
|
+
if (!app.permission['scope.writePhotosAlbum']) {
|
|
58
|
+
app.permission['scope.writePhotosAlbum'] = { desc: ALBUM_DESC };
|
|
59
|
+
}
|
|
60
|
+
fs.writeFileSync(file, JSON.stringify(app, null, 4) + '\n');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
var startDir = argValue('--root') || process.cwd();
|
|
64
|
+
var appRoot = findAppRoot(path.resolve(startDir));
|
|
65
|
+
if (!appRoot) {
|
|
66
|
+
console.error('[yxt-mp-init] 向上找不到 app.json,请在小程序根目录执行 npx yxt-mp-init');
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
var pkgRoot = __dirname;
|
|
71
|
+
copyDir(path.join(pkgRoot, 'pages', 'yxtDownload'), path.join(appRoot, 'pages', 'yxtDownload'));
|
|
72
|
+
fs.mkdirSync(path.join(appRoot, 'utils'), { recursive: true });
|
|
73
|
+
fs.copyFileSync(path.join(pkgRoot, 'utils', 'openYxtModule.js'), path.join(appRoot, 'utils', 'openYxtModule.js'));
|
|
74
|
+
patchAppJson(appRoot);
|
|
75
|
+
|
|
76
|
+
console.log('[yxt-mp-init] 已安装到 ' + appRoot);
|
|
77
|
+
console.log(' - ' + PAGE_PATH);
|
|
78
|
+
console.log(' - utils/openYxtModule.js');
|
|
79
|
+
console.log(' - app.json 已登记页面和相册权限');
|
|
80
|
+
console.log('请在小程序后台配置 downloadFile / request 合法域名:file.plaso.com 以及板书图片 CDN');
|
package/package.json
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
|
-
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@plasosdk/yxt-miniprogram",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "云学堂小程序嵌入:openYxtModule + 板书下载页。安装后在小程序根目录执行 npx yxt-mp-init",
|
|
5
|
+
"main": "utils/openYxtModule.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"yxt-mp-init": "./init.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"init.js",
|
|
11
|
+
"pages",
|
|
12
|
+
"utils"
|
|
13
|
+
],
|
|
14
|
+
"license": "UNLICENSED",
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public",
|
|
17
|
+
"registry": "https://registry.npmjs.org/"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"init": "node init.js"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
// 第三方小程序请原样拷贝本页,app.json 登记 pages/yxtDownload/yxtDownload(路径不要改)。
|
|
2
|
+
// H5 经 wx.miniProgram.navigateTo 进来:单文件 k+u+n,多图 b+p+n,超长清单 m=manifestUrl。
|
|
3
|
+
// downloadFile 合法域名需包含板书图片 CDN 以及 OSS 加速域名。
|
|
4
|
+
|
|
5
|
+
function splitPipe(value) {
|
|
6
|
+
if (!value) {
|
|
7
|
+
return [];
|
|
8
|
+
}
|
|
9
|
+
return String(value).split('|');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** web-view navigateTo 常常不解码 query,wx.downloadFile 不认 https%3A%2F%2F */
|
|
13
|
+
function decodeHttpUrl(value) {
|
|
14
|
+
let url = String(value || '');
|
|
15
|
+
for (let i = 0; i < 3; i++) {
|
|
16
|
+
if (/^https?:\/\//i.test(url)) {
|
|
17
|
+
return url;
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
const next = decodeURIComponent(url);
|
|
21
|
+
if (next === url) {
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
url = next;
|
|
25
|
+
} catch (error) {
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return url;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function parseOptions(options) {
|
|
33
|
+
options = options || {};
|
|
34
|
+
if (options.m) {
|
|
35
|
+
return { manifest: decodeHttpUrl(options.m) };
|
|
36
|
+
}
|
|
37
|
+
if (options.b && options.p) {
|
|
38
|
+
const base = decodeHttpUrl(options.b);
|
|
39
|
+
const parts = splitPipe(options.p);
|
|
40
|
+
const names = splitPipe(options.n);
|
|
41
|
+
return {
|
|
42
|
+
files: parts.map(function (part, index) {
|
|
43
|
+
return {
|
|
44
|
+
kind: 'image',
|
|
45
|
+
url: base + part,
|
|
46
|
+
name: names[index] || 'board_' + (index + 1) + '.png',
|
|
47
|
+
};
|
|
48
|
+
}),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
if (options.u) {
|
|
52
|
+
return {
|
|
53
|
+
files: [
|
|
54
|
+
{
|
|
55
|
+
kind: options.k === 'pdf' ? 'pdf' : 'image',
|
|
56
|
+
url: decodeHttpUrl(options.u),
|
|
57
|
+
name: options.n || (options.k === 'pdf' ? 'board.pdf' : 'board.png'),
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
return { files: [] };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function ensureAlbumAuth() {
|
|
66
|
+
return new Promise(function (resolve, reject) {
|
|
67
|
+
wx.getSetting({
|
|
68
|
+
success: function (res) {
|
|
69
|
+
const setting = (res && res.authSetting) || {};
|
|
70
|
+
if (setting['scope.writePhotosAlbum']) {
|
|
71
|
+
resolve();
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (setting['scope.writePhotosAlbum'] === false) {
|
|
75
|
+
wx.openSetting({
|
|
76
|
+
success: function (openRes) {
|
|
77
|
+
if (openRes.authSetting && openRes.authSetting['scope.writePhotosAlbum']) {
|
|
78
|
+
resolve();
|
|
79
|
+
} else {
|
|
80
|
+
reject(new Error('no album auth'));
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
fail: reject,
|
|
84
|
+
});
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
wx.authorize({
|
|
88
|
+
scope: 'scope.writePhotosAlbum',
|
|
89
|
+
success: function () {
|
|
90
|
+
resolve();
|
|
91
|
+
},
|
|
92
|
+
fail: reject,
|
|
93
|
+
});
|
|
94
|
+
},
|
|
95
|
+
fail: reject,
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function downloadToTemp(url) {
|
|
101
|
+
return new Promise(function (resolve, reject) {
|
|
102
|
+
if (!url || !/^https:\/\//i.test(url) && !/^http:\/\/(127\.0\.0\.1|localhost)/i.test(url)) {
|
|
103
|
+
reject({ errMsg: 'downloadFile:fail invalid url ' + String(url || '') });
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
wx.downloadFile({
|
|
107
|
+
url: url,
|
|
108
|
+
success: function (res) {
|
|
109
|
+
if (res.statusCode === 200 && res.tempFilePath) {
|
|
110
|
+
resolve(res.tempFilePath);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
reject(new Error('download ' + (res.statusCode || 0)));
|
|
114
|
+
},
|
|
115
|
+
fail: reject,
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function saveImage(filePath) {
|
|
121
|
+
return new Promise(function (resolve, reject) {
|
|
122
|
+
wx.saveImageToPhotosAlbum({
|
|
123
|
+
filePath: filePath,
|
|
124
|
+
success: function () {
|
|
125
|
+
resolve();
|
|
126
|
+
},
|
|
127
|
+
fail: reject,
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function openPdf(filePath) {
|
|
133
|
+
return new Promise(function (resolve, reject) {
|
|
134
|
+
wx.openDocument({
|
|
135
|
+
filePath: filePath,
|
|
136
|
+
fileType: 'pdf',
|
|
137
|
+
showMenu: true,
|
|
138
|
+
success: function () {
|
|
139
|
+
resolve();
|
|
140
|
+
},
|
|
141
|
+
fail: reject,
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function readJson(filePath) {
|
|
147
|
+
return new Promise(function (resolve, reject) {
|
|
148
|
+
wx.getFileSystemManager().readFile({
|
|
149
|
+
filePath: filePath,
|
|
150
|
+
encoding: 'utf8',
|
|
151
|
+
success: function (res) {
|
|
152
|
+
try {
|
|
153
|
+
resolve(JSON.parse(res.data || '{}'));
|
|
154
|
+
} catch (error) {
|
|
155
|
+
reject({ errMsg: 'json parse fail' });
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
fail: reject,
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function requestJson(url) {
|
|
164
|
+
return new Promise(function (resolve, reject) {
|
|
165
|
+
wx.request({
|
|
166
|
+
url: url,
|
|
167
|
+
method: 'GET',
|
|
168
|
+
dataType: 'json',
|
|
169
|
+
success: function (res) {
|
|
170
|
+
if (res.statusCode === 200 && res.data) {
|
|
171
|
+
resolve(res.data);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
reject({ errMsg: 'request status ' + (res.statusCode || 0) });
|
|
175
|
+
},
|
|
176
|
+
fail: reject,
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
Page({
|
|
182
|
+
data: {
|
|
183
|
+
status: 'loading',
|
|
184
|
+
hint: '正在准备文件…',
|
|
185
|
+
files: [],
|
|
186
|
+
},
|
|
187
|
+
onLoad(options) {
|
|
188
|
+
const parsed = parseOptions(options);
|
|
189
|
+
this._leaveOnSuccess = true;
|
|
190
|
+
if (parsed.manifest) {
|
|
191
|
+
this.loadManifest(parsed.manifest);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
this.begin(parsed.files || []);
|
|
195
|
+
},
|
|
196
|
+
loadManifest(url) {
|
|
197
|
+
const self = this;
|
|
198
|
+
this._manifestUrl = url;
|
|
199
|
+
requestJson(url)
|
|
200
|
+
.catch(function () {
|
|
201
|
+
return downloadToTemp(url).then(readJson);
|
|
202
|
+
})
|
|
203
|
+
.then(function (data) {
|
|
204
|
+
self.begin((data && data.files) || []);
|
|
205
|
+
})
|
|
206
|
+
.catch(function (error) {
|
|
207
|
+
const msg = String((error && error.errMsg) || error || '');
|
|
208
|
+
console.error('[yxtDownload] manifest failed', url, error);
|
|
209
|
+
self.fail('清单下载失败\n' + msg + '\n' + String(url || ''));
|
|
210
|
+
});
|
|
211
|
+
},
|
|
212
|
+
begin(files) {
|
|
213
|
+
if (!files.length) {
|
|
214
|
+
this.fail('没有可保存的文件');
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
this.setData({ files: files, hint: '共 ' + files.length + ' 个文件,正在保存…' });
|
|
218
|
+
this.runSave(files);
|
|
219
|
+
},
|
|
220
|
+
onTapSave() {
|
|
221
|
+
const files = this.data.files || [];
|
|
222
|
+
if (this._manifestUrl && !files.length) {
|
|
223
|
+
this.setData({ status: 'loading', hint: '正在准备文件…' });
|
|
224
|
+
this.loadManifest(this._manifestUrl);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
if (!files.length) {
|
|
228
|
+
this.fail('没有可保存的文件');
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
this.setData({ status: 'loading', hint: '正在保存…' });
|
|
232
|
+
this.runSave(files);
|
|
233
|
+
},
|
|
234
|
+
runSave(files) {
|
|
235
|
+
const self = this;
|
|
236
|
+
if (!files || !files.length) {
|
|
237
|
+
this.fail('没有可保存的文件');
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
const hasImage = files.some(function (item) {
|
|
241
|
+
return item.kind !== 'pdf';
|
|
242
|
+
});
|
|
243
|
+
const start = hasImage ? ensureAlbumAuth() : Promise.resolve();
|
|
244
|
+
start
|
|
245
|
+
.then(function () {
|
|
246
|
+
return self.saveAll(files);
|
|
247
|
+
})
|
|
248
|
+
.then(function () {
|
|
249
|
+
const onlyPdf = files.length === 1 && files[0].kind === 'pdf';
|
|
250
|
+
wx.showToast({ title: onlyPdf ? '已打开文件' : '已保存到相册', icon: 'success' });
|
|
251
|
+
self.setData({ status: 'done', hint: onlyPdf ? '可在预览里另存' : '已保存到相册' });
|
|
252
|
+
if (!onlyPdf && self._leaveOnSuccess) {
|
|
253
|
+
setTimeout(function () {
|
|
254
|
+
wx.navigateBack();
|
|
255
|
+
}, 400);
|
|
256
|
+
}
|
|
257
|
+
})
|
|
258
|
+
.catch(function (error) {
|
|
259
|
+
const msg = String((error && error.errMsg) || error || '');
|
|
260
|
+
console.error('[yxtDownload] save failed', error, files && files[0] && files[0].url);
|
|
261
|
+
const needAuth = msg.indexOf('auth') >= 0;
|
|
262
|
+
const domainFail = msg.indexOf('domain') >= 0 || msg.indexOf('url not in') >= 0;
|
|
263
|
+
let hint = '保存失败,请点击重试';
|
|
264
|
+
if (needAuth) {
|
|
265
|
+
hint = '需要相册权限才能保存,请点击重试';
|
|
266
|
+
} else if (domainFail) {
|
|
267
|
+
hint = '图片域名未配到 downloadFile 合法域名';
|
|
268
|
+
}
|
|
269
|
+
if (msg) {
|
|
270
|
+
hint += '\n' + msg;
|
|
271
|
+
}
|
|
272
|
+
self.setData({ status: 'error', hint: hint });
|
|
273
|
+
});
|
|
274
|
+
},
|
|
275
|
+
saveAll(files) {
|
|
276
|
+
let chain = Promise.resolve();
|
|
277
|
+
files.forEach(function (file) {
|
|
278
|
+
chain = chain.then(function () {
|
|
279
|
+
return downloadToTemp(file.url).then(function (filePath) {
|
|
280
|
+
if (file.kind === 'pdf') {
|
|
281
|
+
return openPdf(filePath);
|
|
282
|
+
}
|
|
283
|
+
return saveImage(filePath);
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
return chain;
|
|
288
|
+
},
|
|
289
|
+
fail(hint) {
|
|
290
|
+
this.setData({ status: 'error', hint: hint });
|
|
291
|
+
},
|
|
292
|
+
});
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 第三方小程序嵌入云学堂。推荐装包,不要零散拷文件:
|
|
3
|
+
* npm install @plasosdk/yxt-miniprogram
|
|
4
|
+
* npx yxt-mp-init
|
|
5
|
+
* 包目录:./yxt-miniprogram ,发布名为 @plasosdk/yxt-miniprogram
|
|
6
|
+
*
|
|
7
|
+
* 对方:
|
|
8
|
+
* const { openYxtModule } = require('../../utils/openYxtModule');
|
|
9
|
+
* this.setData({ src: openYxtModule({ env: 'dev', module: 'homework', token: token, userid: userid }) });
|
|
10
|
+
* <web-view src="{{src}}" bindmessage="onTokenError" />
|
|
11
|
+
*
|
|
12
|
+
* module: homework | liveclass | course
|
|
13
|
+
* env: local | dev | test | itest | ftest | b | www
|
|
14
|
+
* 换域名时传 origin,不要改 module / appType。
|
|
15
|
+
*
|
|
16
|
+
* 板书下载:H5 会 navigateTo('/pages/yxtDownload/yxtDownload?...')。
|
|
17
|
+
* init 会登记该路径;downloadFile / request 合法域名仍需对方在微信后台配置。
|
|
18
|
+
*/
|
|
19
|
+
var HOSTS = {
|
|
20
|
+
local: 'http://localhost:9527',
|
|
21
|
+
dev: 'https://dev.plaso.cn',
|
|
22
|
+
test: 'https://test.plaso.cn',
|
|
23
|
+
itest: 'https://itest.plaso.cn',
|
|
24
|
+
ftest: 'https://ftest.plaso.cn',
|
|
25
|
+
b: 'https://b.plaso.cn',
|
|
26
|
+
www: 'https://www.plaso.cn',
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
var MODULES = {
|
|
30
|
+
homework: 1,
|
|
31
|
+
liveclass: 1,
|
|
32
|
+
course: 1,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
function appendQuery(parts, key, value) {
|
|
36
|
+
if (value === undefined || value === null || value === '') {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
parts.push(encodeURIComponent(key) + '=' + encodeURIComponent(String(value)));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function openYxtModule(opts) {
|
|
43
|
+
opts = opts || {};
|
|
44
|
+
var env = opts.env || 'www';
|
|
45
|
+
var moduleName = opts.module;
|
|
46
|
+
var token = opts.token;
|
|
47
|
+
var userid = opts.userid;
|
|
48
|
+
var extra = opts.extra || {};
|
|
49
|
+
var origin = opts.origin || HOSTS[env];
|
|
50
|
+
|
|
51
|
+
if (!MODULES[moduleName]) {
|
|
52
|
+
throw new Error('openYxtModule: module 必须是 homework、liveclass 或 course');
|
|
53
|
+
}
|
|
54
|
+
if (!token) {
|
|
55
|
+
throw new Error('openYxtModule: token 必填');
|
|
56
|
+
}
|
|
57
|
+
if (userid === undefined || userid === null || userid === '') {
|
|
58
|
+
throw new Error('openYxtModule: userid 必填');
|
|
59
|
+
}
|
|
60
|
+
if (!origin) {
|
|
61
|
+
throw new Error('openYxtModule: 未知 env,或自行传入 origin');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
var parts = [];
|
|
65
|
+
appendQuery(parts, 'appType', 'mpEmbed');
|
|
66
|
+
appendQuery(parts, 'module', moduleName);
|
|
67
|
+
appendQuery(parts, 'token', token);
|
|
68
|
+
appendQuery(parts, 'userid', userid);
|
|
69
|
+
Object.keys(extra).forEach(function (key) {
|
|
70
|
+
appendQuery(parts, key, extra[key]);
|
|
71
|
+
});
|
|
72
|
+
if (extra.withBack === undefined) {
|
|
73
|
+
appendQuery(parts, 'withBack', '0');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
var path = env === 'local' ? '/?' : '/static/yxt/?';
|
|
77
|
+
return origin.replace(/\/$/, '') + path + parts.join('&');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
module.exports = { openYxtModule, HOSTS, MODULES };
|