重构了config的结构和相关代码
This commit is contained in:
parent
963bfd9a77
commit
2b1fb285b5
|
|
@ -3,7 +3,7 @@ import { AppType } from '../general-app-domain/Application/Schema';
|
|||
import { EntityDict } from "../general-app-domain";
|
||||
import { QiniuUploadInfo } from "oak-frontend-base/lib/types/Upload";
|
||||
import { RuntimeContext } from '../context/RuntimeContext';
|
||||
import { Schema as Livestream } from '../general-app-domain/Livestream/Schema';
|
||||
import { Origin } from "../types/Config";
|
||||
declare type GeneralAspectDict<ED extends EntityDict, Cxt extends RuntimeContext<ED>> = {
|
||||
loginByMobile: (params: {
|
||||
captcha?: string;
|
||||
|
|
@ -27,22 +27,10 @@ declare type GeneralAspectDict<ED extends EntityDict, Cxt extends RuntimeContext
|
|||
signature: string;
|
||||
}, context: Cxt) => Promise<void>;
|
||||
getUploadInfo: (params: {
|
||||
origin: string;
|
||||
origin: Origin;
|
||||
bucket?: string;
|
||||
key?: string;
|
||||
}, context: Cxt) => Promise<QiniuUploadInfo>;
|
||||
getLivestream: (params: {
|
||||
streamTitle: string;
|
||||
expireAt: number;
|
||||
}, context: Cxt) => Promise<Pick<Livestream, 'streamTitle' | 'hub' | 'rtmpPushUrl' | 'rtmpPlayUrl' | 'pcPushUrl' | 'streamKey' | 'expireAt'>>;
|
||||
getLivestream2: (params: {
|
||||
streamTitle: string;
|
||||
expireAt: number;
|
||||
}, context: Cxt) => Promise<Pick<Livestream, 'streamTitle' | 'hub' | 'rtmpPushUrl' | 'rtmpPlayUrl' | 'pcPushUrl' | 'streamKey' | 'expireAt'>>;
|
||||
getPlayBackUrl: (params: {
|
||||
streamTitle: string;
|
||||
start: number;
|
||||
end: number;
|
||||
}, context: Cxt) => Promise<string>;
|
||||
sendCaptcha: (params: {
|
||||
mobile: string;
|
||||
env: WechatMpEnv | WebEnv;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import { RuntimeContext } from '../context/RuntimeContext';
|
||||
import { EntityDict } from '../general-app-domain';
|
||||
import { Origin } from '../types/Config';
|
||||
import { QiniuUploadInfo } from 'oak-frontend-base/lib/types/Upload';
|
||||
export declare function getUploadInfo<ED extends EntityDict, Cxt extends RuntimeContext<ED>>(params: {
|
||||
origin: string;
|
||||
origin: Origin;
|
||||
bucket?: string;
|
||||
key?: string;
|
||||
}, context: Cxt): Promise<QiniuUploadInfo>;
|
||||
|
|
|
|||
|
|
@ -2,46 +2,21 @@
|
|||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getUploadInfo = void 0;
|
||||
var tslib_1 = require("tslib");
|
||||
var qiniu_1 = tslib_1.__importDefault(require("../utils/externalUpload/qiniu"));
|
||||
var ExternalUploadClazz = {
|
||||
qiniu: qiniu_1.default,
|
||||
};
|
||||
var getContextConfig_1 = require("../utils/getContextConfig");
|
||||
var console_1 = require("console");
|
||||
function getUploadInfo(params, context) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var rowStore, application, _a, type, config, systemId, origin, key, _b, system, systemConfig, originConfig, instance, uploadInfo;
|
||||
var origin, key, bucket, _a, instance, config, _b, uploadHost, domain, bucket2;
|
||||
return tslib_1.__generator(this, function (_c) {
|
||||
switch (_c.label) {
|
||||
case 0:
|
||||
rowStore = context.rowStore;
|
||||
return [4 /*yield*/, context.getApplication()];
|
||||
origin = params.origin, key = params.key, bucket = params.bucket;
|
||||
return [4 /*yield*/, (0, getContextConfig_1.getConfig)(context, 'Cos', origin)];
|
||||
case 1:
|
||||
application = _c.sent();
|
||||
_a = application, type = _a.type, config = _a.config, systemId = _a.systemId;
|
||||
origin = params.origin, key = params.key;
|
||||
return [4 /*yield*/, rowStore.select('system', {
|
||||
data: {
|
||||
id: 1,
|
||||
config: 1
|
||||
},
|
||||
filter: {
|
||||
id: systemId
|
||||
}
|
||||
}, context, {
|
||||
dontCollect: true,
|
||||
})];
|
||||
case 2:
|
||||
_b = tslib_1.__read.apply(void 0, [(_c.sent()).result, 1]), system = _b[0];
|
||||
try {
|
||||
systemConfig = system.config;
|
||||
originConfig = systemConfig.Cos[origin];
|
||||
instance = new ExternalUploadClazz[origin](originConfig);
|
||||
uploadInfo = instance.getUploadInfo(key);
|
||||
return [2 /*return*/, uploadInfo];
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return [2 /*return*/];
|
||||
_a = _c.sent(), instance = _a.instance, config = _a.config;
|
||||
(0, console_1.assert)(origin === 'qiniu');
|
||||
_b = config, uploadHost = _b.uploadHost, domain = _b.domain, bucket2 = _b.bucket;
|
||||
return [2 /*return*/, instance.getUploadInfo(uploadHost, domain, bucket || bucket2, key)];
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { loginByMobile, loginWechat, loginWechatMp, syncUserInfoWechatMp, sendCaptcha } from './token';
|
||||
import { getUploadInfo } from './extraFile';
|
||||
import { getLivestream, getLivestream2, getPlayBackUrl } from './livestream';
|
||||
export declare const aspectDict: {
|
||||
loginByMobile: typeof loginByMobile;
|
||||
loginWechat: typeof loginWechat;
|
||||
|
|
@ -9,7 +8,4 @@ export declare const aspectDict: {
|
|||
getUploadInfo: typeof getUploadInfo;
|
||||
sendCaptcha: typeof sendCaptcha;
|
||||
getApplication: typeof import("./application.dev").getApplication | typeof import("./application.prod").getApplication;
|
||||
getLivestream: typeof getLivestream;
|
||||
getLivestream2: typeof getLivestream2;
|
||||
getPlayBackUrl: typeof getPlayBackUrl;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ exports.aspectDict = void 0;
|
|||
var token_1 = require("./token");
|
||||
var extraFile_1 = require("./extraFile");
|
||||
var application_1 = require("./application");
|
||||
var livestream_1 = require("./livestream");
|
||||
// import commonAspectDict from 'oak-common-aspect';
|
||||
exports.aspectDict = {
|
||||
loginByMobile: token_1.loginByMobile,
|
||||
|
|
@ -14,8 +13,5 @@ exports.aspectDict = {
|
|||
getUploadInfo: extraFile_1.getUploadInfo,
|
||||
sendCaptcha: token_1.sendCaptcha,
|
||||
getApplication: application_1.getApplication,
|
||||
getLivestream: livestream_1.getLivestream,
|
||||
getLivestream2: livestream_1.getLivestream2,
|
||||
getPlayBackUrl: livestream_1.getPlayBackUrl,
|
||||
};
|
||||
// export type AspectDict<ED extends EntityDict & BaseEntityDict> = TokenAD<ED> & CrudAD<ED>;
|
||||
|
|
|
|||
|
|
@ -1,241 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getPlayBackUrl = exports.getLivestream2 = exports.getLivestream = void 0;
|
||||
var tslib_1 = require("tslib");
|
||||
var qiniu_live_1 = tslib_1.__importDefault(require("../utils/externalUpload/qiniu_live"));
|
||||
var sign_1 = require("../utils/sign");
|
||||
var ts_md5_1 = require("ts-md5");
|
||||
function getQiniuUploadInfo(context) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var rowStore, application, _a, type, config, systemId, origin, _b, system, systemConfig, originConfig;
|
||||
return tslib_1.__generator(this, function (_c) {
|
||||
switch (_c.label) {
|
||||
case 0:
|
||||
rowStore = context.rowStore;
|
||||
return [4 /*yield*/, context.getApplication()];
|
||||
case 1:
|
||||
application = _c.sent();
|
||||
_a = application, type = _a.type, config = _a.config, systemId = _a.systemId;
|
||||
origin = "qiniu";
|
||||
return [4 /*yield*/, rowStore.select('system', {
|
||||
data: {
|
||||
id: 1,
|
||||
config: 1
|
||||
},
|
||||
filter: {
|
||||
id: systemId
|
||||
}
|
||||
}, context, {
|
||||
dontCollect: true,
|
||||
})];
|
||||
case 2:
|
||||
_b = tslib_1.__read.apply(void 0, [(_c.sent()).result, 1]), system = _b[0];
|
||||
try {
|
||||
systemConfig = system.config;
|
||||
originConfig = systemConfig.Cos[origin];
|
||||
return [2 /*return*/, originConfig];
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
function getQiniuToken(config, params) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var method, path, rawQuery, contentType, bodyStr, liveHost, accessKey, secretKey, instance, token;
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
method = params.method, path = params.path, rawQuery = params.rawQuery, contentType = params.contentType, bodyStr = params.bodyStr;
|
||||
liveHost = config.liveHost, accessKey = config.accessKey, secretKey = config.secretKey;
|
||||
// 请求鉴权
|
||||
try {
|
||||
instance = new qiniu_live_1.default({
|
||||
accessKey: accessKey,
|
||||
secretKey: secretKey,
|
||||
host: liveHost,
|
||||
method: method,
|
||||
path: path,
|
||||
rawQuery: rawQuery,
|
||||
contentType: contentType,
|
||||
bodyStr: bodyStr,
|
||||
});
|
||||
token = instance.getToken();
|
||||
// 拿到鉴权Token
|
||||
return [2 /*return*/, {
|
||||
token: token,
|
||||
}];
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return [2 /*return*/];
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 创建直播流并生成推拉流地址
|
||||
* @param streamTitle 直播流名称
|
||||
* @param expireAt 推流过期时间
|
||||
* @param context context
|
||||
* @returns Livestream 对象
|
||||
*/
|
||||
function getLivestream(params, context) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var streamTitle, expireAt, config, hub, path, key, bodyStr, contentType, token, url, obj;
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
streamTitle = params.streamTitle, expireAt = params.expireAt;
|
||||
return [4 /*yield*/, getQiniuUploadInfo(context)];
|
||||
case 1:
|
||||
config = _a.sent();
|
||||
hub = config.hub;
|
||||
path = "/v2/hubs/".concat(hub, "/streams");
|
||||
key = streamTitle;
|
||||
if (!key) {
|
||||
key = "class".concat(new Date().getTime());
|
||||
}
|
||||
bodyStr = JSON.stringify({
|
||||
key: key,
|
||||
});
|
||||
contentType = 'application/json';
|
||||
return [4 /*yield*/, getQiniuToken(config, {
|
||||
method: 'POST',
|
||||
path: path,
|
||||
contentType: contentType,
|
||||
bodyStr: bodyStr,
|
||||
})];
|
||||
case 2:
|
||||
token = (_a.sent()).token;
|
||||
url = "https://pili.qiniuapi.com/v2/hubs/".concat(hub, "/streams");
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: token,
|
||||
'Content-Type': contentType,
|
||||
},
|
||||
body: bodyStr,
|
||||
mode: 'no-cors',
|
||||
})
|
||||
.then(function (res) {
|
||||
console.log(res.json());
|
||||
}).then(function (res) {
|
||||
console.log(res);
|
||||
}).catch(function (e) {
|
||||
console.log(e);
|
||||
});
|
||||
return [4 /*yield*/, getStreamObj(config, streamTitle, expireAt)];
|
||||
case 3:
|
||||
obj = _a.sent();
|
||||
return [2 /*return*/, obj];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.getLivestream = getLivestream;
|
||||
// 获取推拉流地址
|
||||
/**
|
||||
* 直播流已存在的情况下,获取推拉流地址
|
||||
* @param streamTitle 直播流名称
|
||||
* @param expireAt 推流过期时间
|
||||
* @param context context
|
||||
* @returns livestream对象
|
||||
*/
|
||||
function getLivestream2(params, context) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var streamTitle, expireAt, config, livestream;
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
streamTitle = params.streamTitle, expireAt = params.expireAt;
|
||||
return [4 /*yield*/, getQiniuUploadInfo(context)];
|
||||
case 1:
|
||||
config = _a.sent();
|
||||
return [4 /*yield*/, getStreamObj(config, streamTitle, expireAt)];
|
||||
case 2:
|
||||
livestream = _a.sent();
|
||||
return [2 /*return*/, livestream];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.getLivestream2 = getLivestream2;
|
||||
function getStreamObj(config, streamTitle, expireAt) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var hub, publishDomain, playDomain, publishKey, playKey, signStr, sourcePath, token, rtmpPushUrl, t, playSign, rtmpPlayUrl, pcPushUrl, streamKey;
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
hub = config.hub, publishDomain = config.publishDomain, playDomain = config.playDomain, publishKey = config.publishKey, playKey = config.playKey;
|
||||
signStr = "/".concat(hub, "/").concat(streamTitle, "?expire=").concat(expireAt);
|
||||
sourcePath = "/".concat(hub, "/").concat(streamTitle);
|
||||
token = (0, sign_1.base64ToUrlSafe)((0, sign_1.hmacSha1)(signStr, publishKey));
|
||||
rtmpPushUrl = "rtmp://".concat(publishDomain).concat(signStr, "&token=").concat(token);
|
||||
t = expireAt.toString(16).toLowerCase();
|
||||
playSign = ts_md5_1.Md5.hashStr(playKey + sourcePath + t).toString().toLowerCase();
|
||||
rtmpPlayUrl = "https://".concat(playDomain).concat(sourcePath, ".m3u8?sign=").concat(playSign, "&t=").concat(t);
|
||||
pcPushUrl = "rtmp://".concat(publishDomain, "/").concat(hub, "/");
|
||||
streamKey = "".concat(streamTitle, "?expire=").concat(expireAt, "&token=").concat(token);
|
||||
return [2 /*return*/, {
|
||||
streamTitle: streamTitle,
|
||||
hub: hub,
|
||||
rtmpPushUrl: rtmpPushUrl,
|
||||
rtmpPlayUrl: rtmpPlayUrl,
|
||||
pcPushUrl: pcPushUrl,
|
||||
streamKey: streamKey,
|
||||
expireAt: expireAt,
|
||||
}];
|
||||
});
|
||||
});
|
||||
}
|
||||
// 生成直播回放
|
||||
function getPlayBackUrl(params, context) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var streamTitle, start, end, config, hub, playBackDomain, encodeStreamTitle, path, bodyStr, contentType, token, url;
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
streamTitle = params.streamTitle, start = params.start, end = params.end;
|
||||
return [4 /*yield*/, getQiniuUploadInfo(context)];
|
||||
case 1:
|
||||
config = _a.sent();
|
||||
hub = config.hub, playBackDomain = config.playBackDomain;
|
||||
encodeStreamTitle = (0, sign_1.base64ToUrlSafe)(streamTitle);
|
||||
path = "/v2/hubs/".concat(hub, "/streams/").concat(encodeStreamTitle, "/saveas");
|
||||
bodyStr = JSON.stringify({
|
||||
fname: streamTitle,
|
||||
start: start,
|
||||
end: end,
|
||||
});
|
||||
contentType = 'application/json';
|
||||
return [4 /*yield*/, getQiniuToken(config, {
|
||||
method: 'POST',
|
||||
path: path,
|
||||
contentType: contentType,
|
||||
bodyStr: bodyStr,
|
||||
})];
|
||||
case 2:
|
||||
token = (_a.sent()).token;
|
||||
url = "https://pili.qiniuapi.com".concat(path);
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: token,
|
||||
'Content-Type': contentType,
|
||||
},
|
||||
body: bodyStr,
|
||||
mode: 'no-cors',
|
||||
})
|
||||
.then(function (res) {
|
||||
console.log(res.json());
|
||||
}).then(function (res) {
|
||||
console.log(res);
|
||||
}).catch(function (e) {
|
||||
console.log(e);
|
||||
});
|
||||
return [2 /*return*/, "https://".concat(playBackDomain, "/").concat(streamTitle, ".m3u8")];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.getPlayBackUrl = getPlayBackUrl;
|
||||
|
|
@ -447,7 +447,7 @@ exports.default = OakComponent({
|
|||
types_1.OakUnloggedInException.name) {
|
||||
this.navigateTo({
|
||||
url: '/login',
|
||||
}, undefined, true);
|
||||
}, undefined);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
throw error_2;
|
||||
|
|
|
|||
|
|
@ -13,10 +13,15 @@ export declare type WebConfig = {
|
|||
appId?: string;
|
||||
appSecret?: string;
|
||||
};
|
||||
declare type WechatPublicTemplateMsgsConfig = Record<string, {
|
||||
templateId: string;
|
||||
dataDef: [string, string][];
|
||||
}>;
|
||||
export declare type WechatPublicConfig = {
|
||||
type: 'wechatPublic';
|
||||
appId: string;
|
||||
appSecret: string;
|
||||
templateMsgs?: WechatPublicTemplateMsgsConfig;
|
||||
};
|
||||
export interface Schema extends EntityShape {
|
||||
name: String<32>;
|
||||
|
|
@ -25,3 +30,4 @@ export interface Schema extends EntityShape {
|
|||
system: System;
|
||||
config: WebConfig | WechatMpConfig | WechatPublicConfig;
|
||||
}
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
import { String, Text } from 'oak-domain/lib/types/DataType';
|
||||
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
||||
export interface Schema extends EntityShape {
|
||||
name: String<24>;
|
||||
template: Text;
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
;
|
||||
var locale = {
|
||||
zh_CN: {
|
||||
attr: {
|
||||
name: '名称',
|
||||
template: '模板',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -1,21 +1,8 @@
|
|||
import { String, Text } from 'oak-domain/lib/types/DataType';
|
||||
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
||||
import { QiniuConfig } from '../types/Config';
|
||||
export declare type PlatformConfig = {
|
||||
Cos?: {
|
||||
qiniu?: QiniuConfig;
|
||||
};
|
||||
Map?: {
|
||||
amap?: {
|
||||
webApiKey: string;
|
||||
};
|
||||
};
|
||||
UserEntityGrant?: {
|
||||
lifetimeLength: number;
|
||||
};
|
||||
};
|
||||
import { Config } from '../types/Config';
|
||||
export interface Schema extends EntityShape {
|
||||
name: String<32>;
|
||||
description: Text;
|
||||
config: PlatformConfig;
|
||||
config: Config;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,24 +1,11 @@
|
|||
import { String, Boolean, Text } from 'oak-domain/lib/types/DataType';
|
||||
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
||||
import { Schema as Platform } from './Platform';
|
||||
import { QiniuConfig } from '../types/Config';
|
||||
export declare type SystemConfig = {
|
||||
Cos?: {
|
||||
qiniu?: QiniuConfig;
|
||||
};
|
||||
Map?: {
|
||||
amap?: {
|
||||
webApiKey: string;
|
||||
};
|
||||
};
|
||||
UserEntityGrant?: {
|
||||
lifetimeLength: number;
|
||||
};
|
||||
};
|
||||
import { Config } from '../types/Config';
|
||||
export interface Schema extends EntityShape {
|
||||
name: String<32>;
|
||||
description: Text;
|
||||
config: SystemConfig;
|
||||
config: Config;
|
||||
platform: Platform;
|
||||
super?: Boolean;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { EntityDict } from '../general-app-domain';
|
|||
import { RuntimeContext } from '../context/RuntimeContext';
|
||||
export declare class ExtraFile<ED extends EntityDict, Cxt extends RuntimeContext<ED>, AD extends AspectDict<ED, Cxt>> extends Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> {
|
||||
constructor(aspectWrapper: AspectWrapper<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>);
|
||||
getUploadInfo(origin: string, key?: string): Promise<import("oak-frontend-base/lib/types/Upload").QiniuUploadInfo>;
|
||||
private getUploadInfo;
|
||||
upload(extraFile: DeduceCreateOperationData<EntityDict['extraFile']['OpSchema']>): Promise<{
|
||||
url: string;
|
||||
bucket: string;
|
||||
|
|
|
|||
|
|
@ -58,9 +58,6 @@ var ExtraFile = /** @class */ (function (_super) {
|
|||
});
|
||||
});
|
||||
};
|
||||
tslib_1.__decorate([
|
||||
Feature_1.Action
|
||||
], ExtraFile.prototype, "getUploadInfo", null);
|
||||
tslib_1.__decorate([
|
||||
Feature_1.Action
|
||||
], ExtraFile.prototype, "upload", null);
|
||||
|
|
|
|||
|
|
@ -20,10 +20,18 @@ export declare type WebConfig = {
|
|||
appId?: string;
|
||||
appSecret?: string;
|
||||
};
|
||||
declare type WechatPublicTemplateMsgsConfig = Record<string, {
|
||||
templateId: string;
|
||||
dataDef: [
|
||||
string,
|
||||
string
|
||||
][];
|
||||
}>;
|
||||
export declare type WechatPublicConfig = {
|
||||
type: 'wechatPublic';
|
||||
appId: string;
|
||||
appSecret: string;
|
||||
templateMsgs?: WechatPublicTemplateMsgsConfig;
|
||||
};
|
||||
export declare type OpSchema = {
|
||||
id: PrimaryKey;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import { EntityDef as Domain } from "./Domain/Schema";
|
|||
import { EntityDef as Email } from "./Email/Schema";
|
||||
import { EntityDef as ExtraFile } from "./ExtraFile/Schema";
|
||||
import { EntityDef as Livestream } from "./Livestream/Schema";
|
||||
import { EntityDef as MessageType } from "./MessageType/Schema";
|
||||
import { EntityDef as Mobile } from "./Mobile/Schema";
|
||||
import { EntityDef as Platform } from "./Platform/Schema";
|
||||
import { EntityDef as UserRole } from "./UserRole/Schema";
|
||||
|
|
@ -36,6 +37,7 @@ export declare type EntityDict = {
|
|||
email: Email;
|
||||
extraFile: ExtraFile;
|
||||
livestream: Livestream;
|
||||
messageType: MessageType;
|
||||
mobile: Mobile;
|
||||
platform: Platform;
|
||||
userRole: UserRole;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,102 @@
|
|||
import { String, Text, Datetime, PrimaryKey } from "oak-domain/lib/types/DataType";
|
||||
import { Q_DateValue, Q_StringValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "oak-domain/lib/types/Demand";
|
||||
import { OneOf } from "oak-domain/lib/types/Polyfill";
|
||||
import * as SubQuery from "../_SubQuery";
|
||||
import { FormCreateData, FormUpdateData, Operation as OakOperation, MakeAction as OakMakeAction } from "oak-domain/lib/types/Entity";
|
||||
import { GenericAction } from "oak-domain/lib/actions/action";
|
||||
export declare type OpSchema = {
|
||||
id: PrimaryKey;
|
||||
$$createAt$$: Datetime;
|
||||
$$updateAt$$: Datetime;
|
||||
$$deleteAt$$?: Datetime | null;
|
||||
name: String<24>;
|
||||
template: Text;
|
||||
};
|
||||
export declare type OpAttr = keyof OpSchema;
|
||||
export declare type Schema = {
|
||||
id: PrimaryKey;
|
||||
$$createAt$$: Datetime;
|
||||
$$updateAt$$: Datetime;
|
||||
$$deleteAt$$?: Datetime | null;
|
||||
name: String<24>;
|
||||
template: Text;
|
||||
} & {
|
||||
[A in ExpressionKey]?: any;
|
||||
};
|
||||
declare type AttrFilter = {
|
||||
id: Q_StringValue | SubQuery.MessageTypeIdSubQuery;
|
||||
$$createAt$$: Q_DateValue;
|
||||
$$updateAt$$: Q_DateValue;
|
||||
name: Q_StringValue;
|
||||
template: Q_StringValue;
|
||||
};
|
||||
export declare type Filter = MakeFilter<AttrFilter & ExprOp<OpAttr | string>>;
|
||||
export declare type Projection = {
|
||||
"#id"?: NodeId;
|
||||
[k: string]: any;
|
||||
id: 1;
|
||||
$$createAt$$?: 1;
|
||||
$$updateAt$$?: 1;
|
||||
name?: 1;
|
||||
template?: 1;
|
||||
} & Partial<ExprOp<OpAttr | string>>;
|
||||
export declare type ExportProjection = {
|
||||
"#id"?: NodeId;
|
||||
[k: string]: any;
|
||||
id?: string;
|
||||
$$createAt$$?: string;
|
||||
$$updateAt$$?: string;
|
||||
name?: string;
|
||||
template?: string;
|
||||
} & Partial<ExprOp<OpAttr | string>>;
|
||||
declare type MessageTypeIdProjection = OneOf<{
|
||||
id: 1;
|
||||
}>;
|
||||
export declare type SortAttr = {
|
||||
id: 1;
|
||||
} | {
|
||||
$$createAt$$: 1;
|
||||
} | {
|
||||
$$updateAt$$: 1;
|
||||
} | {
|
||||
name: 1;
|
||||
} | {
|
||||
template: 1;
|
||||
} | {
|
||||
[k: string]: any;
|
||||
} | OneOf<ExprOp<OpAttr | string>>;
|
||||
export declare type SortNode = {
|
||||
$attr: SortAttr;
|
||||
$direction?: "asc" | "desc";
|
||||
};
|
||||
export declare type Sorter = SortNode[];
|
||||
export declare type SelectOperation<P extends Object = Projection> = Omit<OakOperation<"select", P, Filter, Sorter>, "id">;
|
||||
export declare type Selection<P extends Object = Projection> = Omit<SelectOperation<P>, "action">;
|
||||
export declare type Exportation = OakOperation<"export", ExportProjection, Filter, Sorter>;
|
||||
export declare type CreateOperationData = FormCreateData<OpSchema>;
|
||||
export declare type CreateSingleOperation = OakOperation<"create", CreateOperationData>;
|
||||
export declare type CreateMultipleOperation = OakOperation<"create", Array<CreateOperationData>>;
|
||||
export declare type CreateOperation = CreateSingleOperation | CreateMultipleOperation;
|
||||
export declare type UpdateOperationData = FormUpdateData<OpSchema> & {
|
||||
[k: string]: any;
|
||||
};
|
||||
export declare type UpdateOperation = OakOperation<"update" | string, UpdateOperationData, Filter, Sorter>;
|
||||
export declare type RemoveOperationData = {};
|
||||
export declare type RemoveOperation = OakOperation<"remove", RemoveOperationData, Filter, Sorter>;
|
||||
export declare type Operation = CreateOperation | UpdateOperation | RemoveOperation | SelectOperation;
|
||||
export declare type MessageTypeIdSubQuery = Selection<MessageTypeIdProjection>;
|
||||
export declare type NativeAttr = OpAttr;
|
||||
export declare type FullAttr = NativeAttr;
|
||||
export declare type EntityDef = {
|
||||
Schema: Schema;
|
||||
OpSchema: OpSchema;
|
||||
Action: OakMakeAction<GenericAction> | string;
|
||||
Selection: Selection;
|
||||
Operation: Operation;
|
||||
Create: CreateOperation;
|
||||
Update: UpdateOperation;
|
||||
Remove: RemoveOperation;
|
||||
CreateSingle: CreateSingleOperation;
|
||||
CreateMulti: CreateMultipleOperation;
|
||||
};
|
||||
export {};
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import { StorageDesc } from "oak-domain/lib/types/Storage";
|
||||
import { OpSchema } from "./Schema";
|
||||
export declare const desc: StorageDesc<OpSchema>;
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.desc = void 0;
|
||||
var action_1 = require("oak-domain/lib/actions/action");
|
||||
exports.desc = {
|
||||
attributes: {
|
||||
name: {
|
||||
type: "varchar",
|
||||
params: {
|
||||
length: 24
|
||||
}
|
||||
},
|
||||
template: {
|
||||
type: "text"
|
||||
}
|
||||
},
|
||||
actionType: "crud",
|
||||
actions: action_1.genericActions
|
||||
};
|
||||
|
|
@ -0,0 +1 @@
|
|||
{ "attr": { "name": "名称", "template": "模板" } }
|
||||
|
|
@ -4,21 +4,8 @@ import { OneOf } from "oak-domain/lib/types/Polyfill";
|
|||
import * as SubQuery from "../_SubQuery";
|
||||
import { FormCreateData, FormUpdateData, Operation as OakOperation, MakeAction as OakMakeAction } from "oak-domain/lib/types/Entity";
|
||||
import { GenericAction } from "oak-domain/lib/actions/action";
|
||||
import { QiniuConfig } from "../../types/Config";
|
||||
import { Config } from "../../types/Config";
|
||||
import * as System from "../System/Schema";
|
||||
export declare type PlatformConfig = {
|
||||
Cos?: {
|
||||
qiniu?: QiniuConfig;
|
||||
};
|
||||
Map?: {
|
||||
amap?: {
|
||||
webApiKey: string;
|
||||
};
|
||||
};
|
||||
UserEntityGrant?: {
|
||||
lifetimeLength: number;
|
||||
};
|
||||
};
|
||||
export declare type OpSchema = {
|
||||
id: PrimaryKey;
|
||||
$$createAt$$: Datetime;
|
||||
|
|
@ -26,7 +13,7 @@ export declare type OpSchema = {
|
|||
$$deleteAt$$?: Datetime | null;
|
||||
name: String<32>;
|
||||
description: Text;
|
||||
config: PlatformConfig;
|
||||
config: Config;
|
||||
};
|
||||
export declare type OpAttr = keyof OpSchema;
|
||||
export declare type Schema = {
|
||||
|
|
@ -36,7 +23,7 @@ export declare type Schema = {
|
|||
$$deleteAt$$?: Datetime | null;
|
||||
name: String<32>;
|
||||
description: Text;
|
||||
config: PlatformConfig;
|
||||
config: Config;
|
||||
system$platform?: Array<System.Schema>;
|
||||
} & {
|
||||
[A in ExpressionKey]?: any;
|
||||
|
|
@ -47,7 +34,7 @@ declare type AttrFilter = {
|
|||
$$updateAt$$: Q_DateValue;
|
||||
name: Q_StringValue;
|
||||
description: Q_StringValue;
|
||||
config: Q_EnumValue<PlatformConfig>;
|
||||
config: Q_EnumValue<Config>;
|
||||
};
|
||||
export declare type Filter = MakeFilter<AttrFilter & ExprOp<OpAttr | string>>;
|
||||
export declare type Projection = {
|
||||
|
|
|
|||
|
|
@ -15,15 +15,16 @@ var Storage_11 = require("./Domain/Storage");
|
|||
var Storage_12 = require("./Email/Storage");
|
||||
var Storage_13 = require("./ExtraFile/Storage");
|
||||
var Storage_14 = require("./Livestream/Storage");
|
||||
var Storage_15 = require("./Mobile/Storage");
|
||||
var Storage_16 = require("./Platform/Storage");
|
||||
var Storage_17 = require("./UserRole/Storage");
|
||||
var Storage_18 = require("./Role/Storage");
|
||||
var Storage_19 = require("./System/Storage");
|
||||
var Storage_20 = require("./Token/Storage");
|
||||
var Storage_21 = require("./UserEntityGrant/Storage");
|
||||
var Storage_22 = require("./WechatQrCode/Storage");
|
||||
var Storage_23 = require("./WechatUser/Storage");
|
||||
var Storage_15 = require("./MessageType/Storage");
|
||||
var Storage_16 = require("./Mobile/Storage");
|
||||
var Storage_17 = require("./Platform/Storage");
|
||||
var Storage_18 = require("./UserRole/Storage");
|
||||
var Storage_19 = require("./Role/Storage");
|
||||
var Storage_20 = require("./System/Storage");
|
||||
var Storage_21 = require("./Token/Storage");
|
||||
var Storage_22 = require("./UserEntityGrant/Storage");
|
||||
var Storage_23 = require("./WechatQrCode/Storage");
|
||||
var Storage_24 = require("./WechatUser/Storage");
|
||||
exports.storageSchema = {
|
||||
modi: Storage_1.desc,
|
||||
modiEntity: Storage_2.desc,
|
||||
|
|
@ -39,13 +40,14 @@ exports.storageSchema = {
|
|||
email: Storage_12.desc,
|
||||
extraFile: Storage_13.desc,
|
||||
livestream: Storage_14.desc,
|
||||
mobile: Storage_15.desc,
|
||||
platform: Storage_16.desc,
|
||||
userRole: Storage_17.desc,
|
||||
role: Storage_18.desc,
|
||||
system: Storage_19.desc,
|
||||
token: Storage_20.desc,
|
||||
userEntityGrant: Storage_21.desc,
|
||||
wechatQrCode: Storage_22.desc,
|
||||
wechatUser: Storage_23.desc
|
||||
messageType: Storage_15.desc,
|
||||
mobile: Storage_16.desc,
|
||||
platform: Storage_17.desc,
|
||||
userRole: Storage_18.desc,
|
||||
role: Storage_19.desc,
|
||||
system: Storage_20.desc,
|
||||
token: Storage_21.desc,
|
||||
userEntityGrant: Storage_22.desc,
|
||||
wechatQrCode: Storage_23.desc,
|
||||
wechatUser: Storage_24.desc
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,24 +4,11 @@ import { OneOf } from "oak-domain/lib/types/Polyfill";
|
|||
import * as SubQuery from "../_SubQuery";
|
||||
import { FormCreateData, FormUpdateData, Operation as OakOperation, MakeAction as OakMakeAction } from "oak-domain/lib/types/Entity";
|
||||
import { GenericAction } from "oak-domain/lib/actions/action";
|
||||
import { QiniuConfig } from "../../types/Config";
|
||||
import { Config } from "../../types/Config";
|
||||
import * as Platform from "../Platform/Schema";
|
||||
import * as Application from "../Application/Schema";
|
||||
import * as Domain from "../Domain/Schema";
|
||||
import * as User from "../User/Schema";
|
||||
export declare type SystemConfig = {
|
||||
Cos?: {
|
||||
qiniu?: QiniuConfig;
|
||||
};
|
||||
Map?: {
|
||||
amap?: {
|
||||
webApiKey: string;
|
||||
};
|
||||
};
|
||||
UserEntityGrant?: {
|
||||
lifetimeLength: number;
|
||||
};
|
||||
};
|
||||
export declare type OpSchema = {
|
||||
id: PrimaryKey;
|
||||
$$createAt$$: Datetime;
|
||||
|
|
@ -29,7 +16,7 @@ export declare type OpSchema = {
|
|||
$$deleteAt$$?: Datetime | null;
|
||||
name: String<32>;
|
||||
description: Text;
|
||||
config: SystemConfig;
|
||||
config: Config;
|
||||
platformId: ForeignKey<"platform">;
|
||||
super?: Boolean | null;
|
||||
};
|
||||
|
|
@ -41,7 +28,7 @@ export declare type Schema = {
|
|||
$$deleteAt$$?: Datetime | null;
|
||||
name: String<32>;
|
||||
description: Text;
|
||||
config: SystemConfig;
|
||||
config: Config;
|
||||
platformId: ForeignKey<"platform">;
|
||||
super?: Boolean | null;
|
||||
platform: Platform.Schema;
|
||||
|
|
@ -57,7 +44,7 @@ declare type AttrFilter = {
|
|||
$$updateAt$$: Q_DateValue;
|
||||
name: Q_StringValue;
|
||||
description: Q_StringValue;
|
||||
config: Q_EnumValue<SystemConfig>;
|
||||
config: Q_EnumValue<Config>;
|
||||
platformId: Q_StringValue | SubQuery.PlatformIdSubQuery;
|
||||
platform: Platform.Filter;
|
||||
super: Q_BooleanValue;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import * as Domain from "./Domain/Schema";
|
|||
import * as Email from "./Email/Schema";
|
||||
import * as ExtraFile from "./ExtraFile/Schema";
|
||||
import * as Livestream from "./Livestream/Schema";
|
||||
import * as MessageType from "./MessageType/Schema";
|
||||
import * as Mobile from "./Mobile/Schema";
|
||||
import * as Platform from "./Platform/Schema";
|
||||
import * as UserRole from "./UserRole/Schema";
|
||||
|
|
@ -121,6 +122,11 @@ export declare type LivestreamIdSubQuery = {
|
|||
entity: "livestream";
|
||||
}) | any;
|
||||
};
|
||||
export declare type MessageTypeIdSubQuery = {
|
||||
[K in "$in" | "$nin"]?: (MessageType.MessageTypeIdSubQuery & {
|
||||
entity: "messageType";
|
||||
}) | any;
|
||||
};
|
||||
export declare type MobileIdSubQuery = {
|
||||
[K in "$in" | "$nin"]?: (Mobile.MobileIdSubQuery & {
|
||||
entity: "mobile";
|
||||
|
|
|
|||
|
|
@ -1,15 +1,79 @@
|
|||
export declare type QiniuConfig = {
|
||||
export declare type QiniuCloudConfig = {
|
||||
accessKey: string;
|
||||
secretKey: string;
|
||||
};
|
||||
export declare type QiniuLiveConfig = {
|
||||
accessKey: string;
|
||||
liveHost: string;
|
||||
publishDomain: string;
|
||||
playDomain: string;
|
||||
playBackDomain: string;
|
||||
hub: string;
|
||||
publishKey: string;
|
||||
playKey: string;
|
||||
};
|
||||
export declare type QiniuCosConfig = {
|
||||
accessKey: string;
|
||||
uploadHost: string;
|
||||
liveHost?: string;
|
||||
puhlishDomain?: string;
|
||||
playDomain?: string;
|
||||
playBackDomain?: string;
|
||||
hub?: string;
|
||||
publisthKey?: string;
|
||||
playKey?: string;
|
||||
bucket: string;
|
||||
domain: string;
|
||||
protocol: string | string[];
|
||||
};
|
||||
export declare type AliCloudConfig = {
|
||||
accessKeyId: string;
|
||||
accessKeySecret: string;
|
||||
regionId: string;
|
||||
};
|
||||
export declare type TencentCloudConfig = {
|
||||
secretId: string;
|
||||
secretKey: string;
|
||||
region: string;
|
||||
};
|
||||
export declare type AmapCloudConfig = {
|
||||
webApiKey: string;
|
||||
};
|
||||
export declare type AliSmsConfig = {
|
||||
accessKeyId: string;
|
||||
defaultSignName: string;
|
||||
templates: Record<string, {
|
||||
signName?: string;
|
||||
code: string;
|
||||
params: string[];
|
||||
}>;
|
||||
};
|
||||
export declare type TencentSmsConfig = {
|
||||
secretId: string;
|
||||
defaultSignName: string;
|
||||
templates: Record<string, {
|
||||
signName?: string;
|
||||
code: string;
|
||||
}>;
|
||||
};
|
||||
export declare type Config = {
|
||||
Account?: {
|
||||
ali?: AliCloudConfig[];
|
||||
tencent?: TencentCloudConfig[];
|
||||
qiniu?: QiniuCloudConfig[];
|
||||
amap?: AmapCloudConfig[];
|
||||
};
|
||||
Cos?: {
|
||||
qiniu?: QiniuCosConfig;
|
||||
};
|
||||
Live?: {
|
||||
qiniu?: QiniuLiveConfig;
|
||||
};
|
||||
Map?: {
|
||||
amap?: {
|
||||
webApiKey: string;
|
||||
};
|
||||
};
|
||||
UserEntityGrant?: {
|
||||
lifetimeLength: number;
|
||||
};
|
||||
Sms?: {
|
||||
ali?: AliSmsConfig[];
|
||||
tencent?: TencentSmsConfig[];
|
||||
};
|
||||
};
|
||||
export declare type Origin = 'ali' | 'tencent' | 'qiniu' | 'amap';
|
||||
export declare type Service = 'Map' | 'Cos' | 'Live' | 'Sms';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { OpSchema as ExtraFile } from '../general-app-domain/ExtraFile/Schema';
|
||||
import { SystemConfig } from '../general-app-domain/System/Schema';
|
||||
export declare function composeFileUrl(extraFile: Pick<ExtraFile, 'type' | 'bucket' | 'filename' | 'origin' | 'extra1' | 'objectId' | 'extension' | 'entity'>, systemConfig?: SystemConfig): any;
|
||||
import { Config } from '../types/Config';
|
||||
export declare function composeFileUrl(extraFile: Pick<ExtraFile, 'type' | 'bucket' | 'filename' | 'origin' | 'extra1' | 'objectId' | 'extension' | 'entity'>, config?: Config): any;
|
||||
export declare function decomposeFileUrl(url: string): Pick<ExtraFile, 'bucket' | 'filename' | 'origin' | 'type' | 'extra1'>;
|
||||
export declare function getFileURL(file: File): any;
|
||||
export declare function bytesToSize(sizes: any): any;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.bytesToSize = exports.getFileURL = exports.decomposeFileUrl = exports.composeFileUrl = void 0;
|
||||
function composeFileUrl(extraFile, systemConfig) {
|
||||
function composeFileUrl(extraFile, config) {
|
||||
var type = extraFile.type, bucket = extraFile.bucket, filename = extraFile.filename, origin = extraFile.origin, extra1 = extraFile.extra1, objectId = extraFile.objectId, extension = extraFile.extension, entity = extraFile.entity;
|
||||
if (extra1) {
|
||||
// 有extra1就用extra1 可能File对象
|
||||
|
|
@ -13,8 +13,8 @@ function composeFileUrl(extraFile, systemConfig) {
|
|||
}
|
||||
return extra1;
|
||||
}
|
||||
if (systemConfig && systemConfig.Cos) {
|
||||
var _a = systemConfig.Cos[origin], domain = _a.domain, protocol = _a.protocol;
|
||||
if (config && config.Cos) {
|
||||
var _a = config.Cos[origin], domain = _a.domain, protocol = _a.protocol;
|
||||
var protocol2 = protocol;
|
||||
if (protocol instanceof Array) {
|
||||
// protocol存在https 说明域名有证书
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
import { RuntimeContext } from '../context/RuntimeContext';
|
||||
import { EntityDict } from '../general-app-domain';
|
||||
import { Origin, Service } from '../types/Config';
|
||||
export declare function getConfig<ED extends EntityDict, Cxt extends RuntimeContext<ED>>(context: Cxt, service: Service, origin: Origin): Promise<{
|
||||
instance: import("oak-external-sdk").QiniuCloudInstance;
|
||||
config: any;
|
||||
} | {
|
||||
instance: import("oak-external-sdk").AmapInstance;
|
||||
config: any;
|
||||
}>;
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getConfig = void 0;
|
||||
var tslib_1 = require("tslib");
|
||||
var console_1 = require("console");
|
||||
var Exception_1 = require("oak-domain/lib/types/Exception");
|
||||
var oak_external_sdk_1 = require("oak-external-sdk");
|
||||
function getConfig(context, service, origin) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var rowStore, systemId, _a, system, _b, systemConfig, platform, originConfig, originCloudAccounts, platformConfig, aliAccount, tencentAccount, qiniuAccount, qiniuInstance, amapAccount, amapInstance;
|
||||
return tslib_1.__generator(this, function (_c) {
|
||||
switch (_c.label) {
|
||||
case 0:
|
||||
rowStore = context.rowStore;
|
||||
return [4 /*yield*/, context.getSystemId()];
|
||||
case 1:
|
||||
systemId = _c.sent();
|
||||
(0, console_1.assert)(systemId);
|
||||
return [4 /*yield*/, rowStore.select('system', {
|
||||
data: {
|
||||
id: 1,
|
||||
config: 1,
|
||||
platform: {
|
||||
id: 1,
|
||||
config: 1,
|
||||
}
|
||||
},
|
||||
filter: {
|
||||
id: systemId
|
||||
}
|
||||
}, context, {
|
||||
dontCollect: true,
|
||||
})];
|
||||
case 2:
|
||||
_a = tslib_1.__read.apply(void 0, [(_c.sent()).result, 1]), system = _a[0];
|
||||
_b = system, systemConfig = _b.config, platform = _b.platform;
|
||||
originConfig = systemConfig[service] && systemConfig[service][origin];
|
||||
originCloudAccounts = originConfig && systemConfig.Account && systemConfig.Account[origin];
|
||||
if (!originConfig) {
|
||||
platformConfig = platform.config;
|
||||
originConfig = platformConfig[service] && platformConfig[service][origin];
|
||||
originCloudAccounts = originConfig && platformConfig.Account && platformConfig.Account[origin];
|
||||
}
|
||||
if (!originConfig) {
|
||||
throw new Exception_1.OakDataException("\u8C03\u7528\u7684\u670D\u52A1".concat(service, "\u6E90").concat(origin, "\u627E\u4E0D\u5230\u76F8\u5E94\u7684\u914D\u7F6E\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458"));
|
||||
}
|
||||
switch (origin) {
|
||||
case 'ali': {
|
||||
aliAccount = originCloudAccounts.find(function (ele) { return ele.accessKeyId === originConfig.accessKeyId; });
|
||||
(0, console_1.assert)(aliAccount, "\u8C03\u7528\u7684\u670D\u52A1".concat(service, "\u6E90").concat(origin, "\u627E\u4E0D\u5230\u76F8\u5E94\u7684\u4E91\u5E73\u53F0\u5E10\u53F7\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458"));
|
||||
throw new Error('阿里云的external SDK还未实现');
|
||||
}
|
||||
case 'tencent': {
|
||||
tencentAccount = originCloudAccounts.find(function (ele) { return ele.secretId === originConfig.secretId; });
|
||||
(0, console_1.assert)(tencentAccount, "\u8C03\u7528\u7684\u670D\u52A1".concat(service, "\u6E90").concat(origin, "\u627E\u4E0D\u5230\u76F8\u5E94\u7684\u4E91\u5E73\u53F0\u5E10\u53F7\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458"));
|
||||
throw new Error('腾讯云的external SDK还未实现');
|
||||
}
|
||||
case 'qiniu': {
|
||||
qiniuAccount = originCloudAccounts.find(function (ele) { return ele.accessKey === originConfig.accessKey; });
|
||||
(0, console_1.assert)(qiniuAccount, "\u8C03\u7528\u7684\u670D\u52A1".concat(service, "\u6E90").concat(origin, "\u627E\u4E0D\u5230\u76F8\u5E94\u7684\u4E91\u5E73\u53F0\u5E10\u53F7\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458"));
|
||||
qiniuInstance = oak_external_sdk_1.QiniuSDK.getInstance(qiniuAccount.accessKey, qiniuAccount.secretKey);
|
||||
return [2 /*return*/, {
|
||||
instance: qiniuInstance,
|
||||
config: originConfig,
|
||||
}];
|
||||
}
|
||||
default: {
|
||||
(0, console_1.assert)(origin === 'amap');
|
||||
amapAccount = originCloudAccounts.find(function (ele) { return ele.webApiKey === originConfig.webApiKey; });
|
||||
(0, console_1.assert)(amapAccount, "\u8C03\u7528\u7684\u670D\u52A1".concat(service, "\u6E90").concat(origin, "\u627E\u4E0D\u5230\u76F8\u5E94\u7684\u4E91\u5E73\u53F0\u5E10\u53F7\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458"));
|
||||
amapInstance = oak_external_sdk_1.AmapSDK.getInstance(amapAccount.webApiKey);
|
||||
return [2 /*return*/, {
|
||||
instance: amapInstance,
|
||||
config: originConfig,
|
||||
}];
|
||||
}
|
||||
}
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.getConfig = getConfig;
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import { RuntimeContext } from '../context/RuntimeContext';
|
||||
import { EntityDict } from '../general-app-domain';
|
||||
import { Schema as Livestream } from '../general-app-domain/Livestream/Schema';
|
||||
import { Origin } from '../types/Config';
|
||||
/**
|
||||
* 创建直播流并生成推拉流地址
|
||||
* @param streamTitle 直播流名称
|
||||
|
|
@ -9,6 +10,7 @@ import { Schema as Livestream } from '../general-app-domain/Livestream/Schema';
|
|||
* @returns Livestream 对象
|
||||
*/
|
||||
export declare function getLivestream<ED extends EntityDict, Cxt extends RuntimeContext<ED>>(params: {
|
||||
origin: Origin;
|
||||
streamTitle: string;
|
||||
expireAt: number;
|
||||
}, context: Cxt): Promise<Pick<Livestream, 'streamTitle' | 'hub' | 'rtmpPushUrl' | 'rtmpPlayUrl' | 'pcPushUrl' | 'streamKey' | 'expireAt'>>;
|
||||
|
|
@ -19,11 +21,13 @@ export declare function getLivestream<ED extends EntityDict, Cxt extends Runtime
|
|||
* @param context context
|
||||
* @returns livestream对象
|
||||
*/
|
||||
export declare function getLivestream2<ED extends EntityDict, Cxt extends RuntimeContext<ED>>(params: {
|
||||
export declare function getStreamObj<ED extends EntityDict, Cxt extends RuntimeContext<ED>>(params: {
|
||||
origin: Origin;
|
||||
streamTitle: string;
|
||||
expireAt: number;
|
||||
}, context: Cxt): Promise<Pick<Livestream, 'streamTitle' | 'hub' | 'rtmpPushUrl' | 'rtmpPlayUrl' | 'pcPushUrl' | 'streamKey' | 'expireAt'>>;
|
||||
export declare function getPlayBackUrl<ED extends EntityDict, Cxt extends RuntimeContext<ED>>(params: {
|
||||
origin: Origin;
|
||||
streamTitle: string;
|
||||
start: number;
|
||||
end: number;
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getPlayBackUrl = exports.getStreamObj = exports.getLivestream = void 0;
|
||||
var tslib_1 = require("tslib");
|
||||
var getContextConfig_1 = require("./getContextConfig");
|
||||
var assert_1 = tslib_1.__importDefault(require("assert"));
|
||||
/**
|
||||
* 创建直播流并生成推拉流地址
|
||||
* @param streamTitle 直播流名称
|
||||
* @param expireAt 推流过期时间
|
||||
* @param context context
|
||||
* @returns Livestream 对象
|
||||
*/
|
||||
function getLivestream(params, context) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var streamTitle, expireAt, origin, _a, instance, config, _b, hub, liveHost, publishDomain, playDomain, playKey, publishKey;
|
||||
return tslib_1.__generator(this, function (_c) {
|
||||
switch (_c.label) {
|
||||
case 0:
|
||||
streamTitle = params.streamTitle, expireAt = params.expireAt, origin = params.origin;
|
||||
return [4 /*yield*/, (0, getContextConfig_1.getConfig)(context, 'Live', origin)];
|
||||
case 1:
|
||||
_a = _c.sent(), instance = _a.instance, config = _a.config;
|
||||
(0, assert_1.default)(origin === 'qiniu');
|
||||
_b = config, hub = _b.hub, liveHost = _b.liveHost, publishDomain = _b.publishDomain, playDomain = _b.playDomain, playKey = _b.playKey, publishKey = _b.publishKey;
|
||||
return [2 /*return*/, instance.getLiveStream(hub, 'POST', streamTitle, liveHost, publishDomain, playDomain, publishKey, playKey, expireAt)];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.getLivestream = getLivestream;
|
||||
// 获取推拉流地址
|
||||
/**
|
||||
* 直播流已存在的情况下,获取推拉流地址
|
||||
* @param streamTitle 直播流名称
|
||||
* @param expireAt 推流过期时间
|
||||
* @param context context
|
||||
* @returns livestream对象
|
||||
*/
|
||||
function getStreamObj(params, context) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var streamTitle, expireAt, origin, _a, instance, config, _b, publishDomain, publishKey, playDomain, playKey, hub;
|
||||
return tslib_1.__generator(this, function (_c) {
|
||||
switch (_c.label) {
|
||||
case 0:
|
||||
streamTitle = params.streamTitle, expireAt = params.expireAt, origin = params.origin;
|
||||
return [4 /*yield*/, (0, getContextConfig_1.getConfig)(context, 'Live', origin)];
|
||||
case 1:
|
||||
_a = _c.sent(), instance = _a.instance, config = _a.config;
|
||||
(0, assert_1.default)(origin === 'qiniu');
|
||||
_b = config, publishDomain = _b.publishDomain, publishKey = _b.publishKey, playDomain = _b.playDomain, playKey = _b.playKey, hub = _b.hub;
|
||||
return [2 /*return*/, instance.getStreamObj(publishDomain, playDomain, hub, publishKey, playKey, streamTitle, expireAt)];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.getStreamObj = getStreamObj;
|
||||
// 生成直播回放
|
||||
function getPlayBackUrl(params, context) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var streamTitle, start, end, origin, _a, config, instance, _b, hub, playBackDomain, liveHost;
|
||||
return tslib_1.__generator(this, function (_c) {
|
||||
switch (_c.label) {
|
||||
case 0:
|
||||
streamTitle = params.streamTitle, start = params.start, end = params.end, origin = params.origin;
|
||||
return [4 /*yield*/, (0, getContextConfig_1.getConfig)(context, 'Live', origin)];
|
||||
case 1:
|
||||
_a = _c.sent(), config = _a.config, instance = _a.instance;
|
||||
_b = config, hub = _b.hub, playBackDomain = _b.playBackDomain, liveHost = _b.liveHost;
|
||||
return [2 /*return*/, instance.getPlayBackUrl(hub, playBackDomain, streamTitle, start, end, 'POST', liveHost)];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.getPlayBackUrl = getPlayBackUrl;
|
||||
|
|
@ -21,7 +21,6 @@
|
|||
"oak-frontend-base": "file:../oak-frontend-base",
|
||||
"oak-memory-tree-store": "file:../oak-memory-tree-store",
|
||||
"sha1": "^1.1.1",
|
||||
"ts-md5": "^1.3.1",
|
||||
"tslib": "^2.4.0",
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -4,115 +4,73 @@ import { EntityDict } from "../general-app-domain";
|
|||
import { QiniuUploadInfo } from "oak-frontend-base/lib/types/Upload";
|
||||
import { RuntimeContext } from '../context/RuntimeContext';
|
||||
import { Schema as Livestream } from '../general-app-domain/Livestream/Schema';
|
||||
import { Origin } from "../types/Config";
|
||||
|
||||
|
||||
type GeneralAspectDict<
|
||||
ED extends EntityDict,
|
||||
Cxt extends RuntimeContext<ED>
|
||||
> = {
|
||||
loginByMobile: (
|
||||
params: {
|
||||
captcha?: string;
|
||||
password?: string;
|
||||
mobile: string;
|
||||
env: WebEnv | WechatMpEnv;
|
||||
},
|
||||
context: Cxt
|
||||
) => Promise<string>;
|
||||
loginWechat: (
|
||||
{
|
||||
code,
|
||||
env,
|
||||
}: {
|
||||
code: string;
|
||||
env: WebEnv;
|
||||
},
|
||||
context: Cxt
|
||||
) => Promise<string>;
|
||||
loginWechatMp: (
|
||||
{
|
||||
code,
|
||||
env,
|
||||
}: {
|
||||
code: string;
|
||||
env: WechatMpEnv;
|
||||
},
|
||||
context: Cxt
|
||||
) => Promise<string>;
|
||||
syncUserInfoWechatMp: (
|
||||
{
|
||||
nickname,
|
||||
avatarUrl,
|
||||
encryptedData,
|
||||
iv,
|
||||
signature,
|
||||
}: {
|
||||
nickname: string;
|
||||
avatarUrl: string;
|
||||
encryptedData: string;
|
||||
iv: string;
|
||||
signature: string;
|
||||
},
|
||||
context: Cxt
|
||||
) => Promise<void>;
|
||||
getUploadInfo: (
|
||||
params: { origin: string; key?: string },
|
||||
context: Cxt
|
||||
) => Promise<QiniuUploadInfo>;
|
||||
getLivestream: (
|
||||
params: {
|
||||
streamTitle: string;
|
||||
expireAt: number;
|
||||
},
|
||||
context: Cxt
|
||||
) => Promise<
|
||||
Pick<
|
||||
Livestream,
|
||||
| 'streamTitle'
|
||||
| 'hub'
|
||||
| 'rtmpPushUrl'
|
||||
| 'rtmpPlayUrl'
|
||||
| 'pcPushUrl'
|
||||
| 'streamKey'
|
||||
| 'expireAt'
|
||||
>
|
||||
>;
|
||||
getLivestream2: (
|
||||
params: {
|
||||
streamTitle: string;
|
||||
expireAt: number;
|
||||
},
|
||||
context: Cxt
|
||||
) => Promise<
|
||||
Pick<
|
||||
Livestream,
|
||||
| 'streamTitle'
|
||||
| 'hub'
|
||||
| 'rtmpPushUrl'
|
||||
| 'rtmpPlayUrl'
|
||||
| 'pcPushUrl'
|
||||
| 'streamKey'
|
||||
| 'expireAt'
|
||||
>
|
||||
>;
|
||||
getPlayBackUrl: (
|
||||
> = {
|
||||
loginByMobile: (
|
||||
params: {
|
||||
streamTitle: string,
|
||||
start: number,
|
||||
end: number,
|
||||
captcha?: string;
|
||||
password?: string;
|
||||
mobile: string;
|
||||
env: WebEnv | WechatMpEnv;
|
||||
},
|
||||
context: Cxt
|
||||
) => Promise<string>;
|
||||
sendCaptcha: (params: {
|
||||
mobile: string;
|
||||
env: WechatMpEnv | WebEnv;
|
||||
}) => Promise<string>;
|
||||
getApplication: (
|
||||
params: {
|
||||
type: AppType;
|
||||
},
|
||||
context: Cxt
|
||||
) => Promise<string>;
|
||||
};
|
||||
loginWechat: (
|
||||
{
|
||||
code,
|
||||
env,
|
||||
}: {
|
||||
code: string;
|
||||
env: WebEnv;
|
||||
},
|
||||
context: Cxt
|
||||
) => Promise<string>;
|
||||
loginWechatMp: (
|
||||
{
|
||||
code,
|
||||
env,
|
||||
}: {
|
||||
code: string;
|
||||
env: WechatMpEnv;
|
||||
},
|
||||
context: Cxt
|
||||
) => Promise<string>;
|
||||
syncUserInfoWechatMp: (
|
||||
{
|
||||
nickname,
|
||||
avatarUrl,
|
||||
encryptedData,
|
||||
iv,
|
||||
signature,
|
||||
}: {
|
||||
nickname: string;
|
||||
avatarUrl: string;
|
||||
encryptedData: string;
|
||||
iv: string;
|
||||
signature: string;
|
||||
},
|
||||
context: Cxt
|
||||
) => Promise<void>;
|
||||
getUploadInfo: (
|
||||
params: { origin: Origin; bucket?: string; key?: string },
|
||||
context: Cxt
|
||||
) => Promise<QiniuUploadInfo>;
|
||||
|
||||
sendCaptcha: (params: {
|
||||
mobile: string;
|
||||
env: WechatMpEnv | WebEnv;
|
||||
}) => Promise<string>;
|
||||
getApplication: (
|
||||
params: {
|
||||
type: AppType;
|
||||
},
|
||||
context: Cxt
|
||||
) => Promise<string>;
|
||||
};
|
||||
|
||||
export type AspectDict<ED extends EntityDict, Cxt extends RuntimeContext<ED>> = GeneralAspectDict<ED, Cxt>;
|
||||
|
|
@ -1,44 +1,22 @@
|
|||
import { RuntimeContext } from '../context/RuntimeContext';
|
||||
import { EntityDict } from '../general-app-domain';
|
||||
import { SystemConfig } from '../general-app-domain/System/Schema';
|
||||
import qiniuInstance from '../utils/externalUpload/qiniu';
|
||||
import { Origin, QiniuCosConfig } from '../types/Config';
|
||||
import { QiniuUploadInfo } from 'oak-frontend-base/lib/types/Upload';
|
||||
import { getConfig } from '../utils/getContextConfig';
|
||||
import { assert } from 'console';
|
||||
import { QiniuCloudInstance } from 'oak-external-sdk';
|
||||
|
||||
const ExternalUploadClazz = {
|
||||
qiniu: qiniuInstance,
|
||||
};
|
||||
|
||||
export async function getUploadInfo<ED extends EntityDict, Cxt extends RuntimeContext<ED>>(
|
||||
params: { origin: string, key?: string },
|
||||
params: { origin: Origin; bucket?: string; key?: string },
|
||||
context: Cxt): Promise<QiniuUploadInfo> {
|
||||
const { rowStore } = context;
|
||||
const application = await context.getApplication();
|
||||
const { type, config, systemId } = application!;
|
||||
const { origin, key } = params;
|
||||
const { origin, key, bucket } = params;
|
||||
|
||||
const { result: [system] } = await rowStore.select('system', {
|
||||
data: {
|
||||
id: 1,
|
||||
config: 1
|
||||
},
|
||||
filter: {
|
||||
id: systemId
|
||||
}
|
||||
}, context, {
|
||||
dontCollect: true,
|
||||
});
|
||||
try {
|
||||
const { config: systemConfig } = system;
|
||||
const originConfig = (systemConfig as SystemConfig).Cos![
|
||||
origin as keyof typeof systemConfig
|
||||
];
|
||||
|
||||
const instance = new ExternalUploadClazz[
|
||||
origin as keyof typeof ExternalUploadClazz
|
||||
](originConfig);
|
||||
const uploadInfo = instance.getUploadInfo(key);
|
||||
return uploadInfo;
|
||||
} catch (err) {
|
||||
throw err;
|
||||
}
|
||||
const {
|
||||
instance,
|
||||
config,
|
||||
} = await getConfig<ED, Cxt>(context, 'Cos', origin);
|
||||
assert(origin === 'qiniu');
|
||||
const { uploadHost, domain, bucket: bucket2 } = config as QiniuCosConfig;
|
||||
return (instance as QiniuCloudInstance).getUploadInfo(uploadHost, domain, bucket || bucket2, key);
|
||||
}
|
||||
|
|
@ -7,7 +7,6 @@ import {
|
|||
} from './token';
|
||||
import { getUploadInfo } from './extraFile';
|
||||
import { getApplication } from './application';
|
||||
import { getLivestream, getLivestream2, getPlayBackUrl } from './livestream';
|
||||
// import commonAspectDict from 'oak-common-aspect';
|
||||
|
||||
export const aspectDict = {
|
||||
|
|
@ -18,9 +17,6 @@ export const aspectDict = {
|
|||
getUploadInfo,
|
||||
sendCaptcha,
|
||||
getApplication,
|
||||
getLivestream,
|
||||
getLivestream2,
|
||||
getPlayBackUrl,
|
||||
};
|
||||
|
||||
// export type AspectDict<ED extends EntityDict & BaseEntityDict> = TokenAD<ED> & CrudAD<ED>;
|
||||
|
|
@ -1,259 +0,0 @@
|
|||
import { RuntimeContext } from '../context/RuntimeContext';
|
||||
import { EntityDict } from '../general-app-domain';
|
||||
import { SystemConfig } from '../general-app-domain/System/Schema';
|
||||
import { Schema as Livestream } from '../general-app-domain/Livestream/Schema';
|
||||
import QiniuLive from '../utils/externalUpload/qiniu_live';
|
||||
import { hmacSha1, base64ToUrlSafe } from '../utils/sign';
|
||||
import { Md5 } from 'ts-md5';
|
||||
|
||||
async function getQiniuUploadInfo<ED extends EntityDict, Cxt extends RuntimeContext<ED>>(
|
||||
context: Cxt
|
||||
) {
|
||||
// 请求鉴权
|
||||
const { rowStore } = context;
|
||||
const application = await context.getApplication();
|
||||
const { type, config, systemId } = application!;
|
||||
const origin = "qiniu";
|
||||
const { result: [system] } = await rowStore.select('system', {
|
||||
data: {
|
||||
id: 1,
|
||||
config: 1
|
||||
},
|
||||
filter: {
|
||||
id: systemId
|
||||
}
|
||||
}, context, {
|
||||
dontCollect: true,
|
||||
});
|
||||
try {
|
||||
const { config: systemConfig } = system as { config: SystemConfig };
|
||||
const originConfig = systemConfig.Cos![
|
||||
origin as keyof SystemConfig['Cos']
|
||||
];
|
||||
return originConfig;
|
||||
} catch (err) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
async function getQiniuToken(
|
||||
config: { liveHost:string, accessKey: string, secretKey:string, hub:string },
|
||||
params: { method: 'GET' | 'POST' | 'PUT' | 'DELETE', path: string, rawQuery?: string, contentType?: string, bodyStr?: string, },
|
||||
): Promise<{ token: string }> {
|
||||
// 获取请求信息
|
||||
const { method, path, rawQuery, contentType, bodyStr } = params;
|
||||
const { liveHost, accessKey, secretKey } = config;
|
||||
|
||||
// 请求鉴权
|
||||
try{
|
||||
const instance = new QiniuLive({
|
||||
accessKey,
|
||||
secretKey,
|
||||
host: liveHost,
|
||||
method,
|
||||
path,
|
||||
rawQuery,
|
||||
contentType,
|
||||
bodyStr,
|
||||
})
|
||||
const token = instance.getToken();
|
||||
// 拿到鉴权Token
|
||||
return {
|
||||
token,
|
||||
};
|
||||
} catch (err) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建直播流并生成推拉流地址
|
||||
* @param streamTitle 直播流名称
|
||||
* @param expireAt 推流过期时间
|
||||
* @param context context
|
||||
* @returns Livestream 对象
|
||||
*/
|
||||
export async function getLivestream<ED extends EntityDict, Cxt extends RuntimeContext<ED>>(
|
||||
params: {
|
||||
streamTitle: string,
|
||||
expireAt: number,
|
||||
},
|
||||
context: Cxt
|
||||
): Promise<Pick<Livestream,
|
||||
| 'streamTitle'
|
||||
| 'hub'
|
||||
| 'rtmpPushUrl'
|
||||
| 'rtmpPlayUrl'
|
||||
| 'pcPushUrl'
|
||||
| 'streamKey'
|
||||
| 'expireAt'>
|
||||
> {
|
||||
const { streamTitle, expireAt } = params;
|
||||
// 获取七牛直播云信息
|
||||
const config = await getQiniuUploadInfo<ED, Cxt>(context);
|
||||
const { hub } = config;
|
||||
// 七牛创建直播流接口路径
|
||||
const path = `/v2/hubs/${hub}/streams`;
|
||||
// 如果用户没给streamTitle,那么随机生成一个
|
||||
let key:string = streamTitle;
|
||||
if (!key) {
|
||||
key = `class${new Date().getTime()}`;
|
||||
}
|
||||
const bodyStr = JSON.stringify({
|
||||
key,
|
||||
})
|
||||
const contentType = 'application/json';
|
||||
const { token } = await getQiniuToken(config, {
|
||||
method: 'POST',
|
||||
path,
|
||||
contentType,
|
||||
bodyStr,
|
||||
});
|
||||
|
||||
const url = `https://pili.qiniuapi.com/v2/hubs/${hub}/streams`;
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: token,
|
||||
'Content-Type': contentType,
|
||||
},
|
||||
body: bodyStr,
|
||||
mode: 'no-cors',
|
||||
})
|
||||
.then((res) => {
|
||||
console.log(res.json());
|
||||
}).then((res) => {
|
||||
console.log(res);
|
||||
}).catch((e) => {
|
||||
console.log(e);
|
||||
})
|
||||
const obj = await getStreamObj(config, streamTitle, expireAt);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 获取推拉流地址
|
||||
/**
|
||||
* 直播流已存在的情况下,获取推拉流地址
|
||||
* @param streamTitle 直播流名称
|
||||
* @param expireAt 推流过期时间
|
||||
* @param context context
|
||||
* @returns livestream对象
|
||||
*/
|
||||
export async function getLivestream2<ED extends EntityDict, Cxt extends RuntimeContext<ED>>(
|
||||
params: {
|
||||
streamTitle: string,
|
||||
expireAt: number,
|
||||
},
|
||||
context: Cxt
|
||||
): Promise<Pick<Livestream,
|
||||
| 'streamTitle'
|
||||
| 'hub'
|
||||
| 'rtmpPushUrl'
|
||||
| 'rtmpPlayUrl'
|
||||
| 'pcPushUrl'
|
||||
| 'streamKey'
|
||||
| 'expireAt'>
|
||||
> {
|
||||
const {streamTitle, expireAt } = params;
|
||||
const config = await getQiniuUploadInfo<ED, Cxt>(context);
|
||||
const livestream = await getStreamObj(config, streamTitle, expireAt);
|
||||
return livestream;
|
||||
}
|
||||
|
||||
async function getStreamObj(
|
||||
config: {
|
||||
publishDomain: string,
|
||||
playDomain: string,
|
||||
hub: string,
|
||||
publishKey: string,
|
||||
playKey: string,
|
||||
},
|
||||
streamTitle: string,
|
||||
expireAt: number
|
||||
)
|
||||
: Promise<Pick<Livestream,
|
||||
|'streamTitle'
|
||||
|'hub'
|
||||
|'rtmpPushUrl'
|
||||
|'rtmpPlayUrl'
|
||||
|'pcPushUrl'
|
||||
|'streamKey'
|
||||
| 'expireAt'>
|
||||
>
|
||||
{
|
||||
// 生成推流地址
|
||||
const { hub, publishDomain, playDomain, publishKey, playKey } = config;
|
||||
const signStr = `/${hub}/${streamTitle}?expire=${expireAt}`;
|
||||
const sourcePath = `/${hub}/${streamTitle}`;
|
||||
const token = base64ToUrlSafe(hmacSha1(signStr, publishKey));
|
||||
const rtmpPushUrl = `rtmp://${publishDomain}${signStr}&token=${token}`
|
||||
// 生成播放地址
|
||||
const t = expireAt.toString(16).toLowerCase();
|
||||
const playSign = Md5.hashStr(playKey + sourcePath + t).toString().toLowerCase();
|
||||
const rtmpPlayUrl = `https://${playDomain}${sourcePath}.m3u8?sign=${playSign}&t=${t}`;
|
||||
// obs推流需要的地址和串流密钥
|
||||
const pcPushUrl = `rtmp://${publishDomain}/${hub}/`;
|
||||
const streamKey = `${streamTitle}?expire=${expireAt}&token=${token}`
|
||||
return {
|
||||
streamTitle,
|
||||
hub,
|
||||
rtmpPushUrl,
|
||||
rtmpPlayUrl,
|
||||
pcPushUrl,
|
||||
streamKey,
|
||||
expireAt,
|
||||
};
|
||||
}
|
||||
|
||||
// 生成直播回放
|
||||
export async function getPlayBackUrl<ED extends EntityDict, Cxt extends RuntimeContext<ED>>(
|
||||
params: {
|
||||
streamTitle: string,
|
||||
start: number,
|
||||
end: number,
|
||||
},
|
||||
context: Cxt
|
||||
) {
|
||||
const { streamTitle, start, end } = params;
|
||||
// 获取七牛直播云信息
|
||||
const config = await getQiniuUploadInfo<ED, Cxt>(context);
|
||||
const { hub, playBackDomain } = config;
|
||||
// 七牛创建直播流接口路径
|
||||
const encodeStreamTitle = base64ToUrlSafe(streamTitle);
|
||||
const path = `/v2/hubs/${hub}/streams/${encodeStreamTitle}/saveas`;
|
||||
const bodyStr = JSON.stringify({
|
||||
fname: streamTitle,
|
||||
start,
|
||||
end,
|
||||
})
|
||||
const contentType = 'application/json';
|
||||
const { token } = await getQiniuToken(config, {
|
||||
method: 'POST',
|
||||
path,
|
||||
contentType,
|
||||
bodyStr,
|
||||
});
|
||||
|
||||
const url = `https://pili.qiniuapi.com${path}`;
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: token,
|
||||
'Content-Type': contentType,
|
||||
},
|
||||
body: bodyStr,
|
||||
mode: 'no-cors',
|
||||
})
|
||||
.then((res) => {
|
||||
console.log(res.json());
|
||||
}).then((res) => {
|
||||
console.log(res);
|
||||
}).catch((e) => {
|
||||
console.log(e);
|
||||
})
|
||||
return `https://${playBackDomain}/${streamTitle}.m3u8`;
|
||||
}
|
||||
|
|
@ -355,7 +355,6 @@ export default OakComponent({
|
|||
url: '/login',
|
||||
},
|
||||
undefined,
|
||||
true
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,10 +17,16 @@ export type WebConfig = {
|
|||
appSecret?: string; //网站 微信扫码登录
|
||||
};
|
||||
|
||||
type WechatPublicTemplateMsgsConfig = Record<string, {
|
||||
templateId: string;
|
||||
dataDef: [string, string][]; // 前一个代表keyword,后一个代表color
|
||||
}>; // key值代表messageTypeId
|
||||
|
||||
export type WechatPublicConfig = {
|
||||
type: 'wechatPublic';
|
||||
appId: string;
|
||||
appSecret: string;
|
||||
templateMsgs?: WechatPublicTemplateMsgsConfig;
|
||||
};
|
||||
|
||||
export interface Schema extends EntityShape {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
import { String, Int, Text, Image } from 'oak-domain/lib/types/DataType';
|
||||
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
||||
import { LocaleDef } from 'oak-domain/lib/types/Locale';
|
||||
|
||||
export interface Schema extends EntityShape {
|
||||
name: String<24>;
|
||||
template: Text;
|
||||
};
|
||||
|
||||
const locale: LocaleDef<Schema, '', '', {}> = {
|
||||
zh_CN: {
|
||||
attr: {
|
||||
name: '名称',
|
||||
template: '模板',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -1,26 +1,12 @@
|
|||
import { String, Int, Datetime, Image, Boolean, Text } from 'oak-domain/lib/types/DataType';
|
||||
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
||||
import { LocaleDef } from 'oak-domain/lib/types/Locale';
|
||||
import { QiniuConfig } from '../types/Config';
|
||||
|
||||
export type PlatformConfig = {
|
||||
Cos?: {
|
||||
qiniu?: QiniuConfig;
|
||||
};
|
||||
Map?: {
|
||||
amap?: {
|
||||
webApiKey: string; // 高德访问rest服务接口的key
|
||||
};
|
||||
};
|
||||
UserEntityGrant?: {
|
||||
lifetimeLength: number; // 授权的过期时间(ms)
|
||||
};
|
||||
};
|
||||
import { Config } from '../types/Config';
|
||||
|
||||
export interface Schema extends EntityShape {
|
||||
name: String<32>;
|
||||
description: Text;
|
||||
config: PlatformConfig;
|
||||
config: Config;
|
||||
};
|
||||
|
||||
const locale: LocaleDef<Schema, '', '', {}> = {
|
||||
|
|
|
|||
|
|
@ -1,27 +1,13 @@
|
|||
import { String, Int, Datetime, Image, Boolean, Text } from 'oak-domain/lib/types/DataType';
|
||||
import { String, Boolean, Text } from 'oak-domain/lib/types/DataType';
|
||||
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
||||
import { LocaleDef } from 'oak-domain/lib/types/Locale';
|
||||
import { Schema as Platform } from './Platform';
|
||||
import { QiniuConfig } from '../types/Config';
|
||||
|
||||
export type SystemConfig = {
|
||||
Cos?: {
|
||||
qiniu?: QiniuConfig;
|
||||
};
|
||||
Map?: {
|
||||
amap?: {
|
||||
webApiKey: string; // 高德访问rest服务接口的key
|
||||
};
|
||||
};
|
||||
UserEntityGrant?: {
|
||||
lifetimeLength: number; // 授权的过期时间(ms)
|
||||
};
|
||||
};
|
||||
import { Config } from '../types/Config';
|
||||
|
||||
export interface Schema extends EntityShape {
|
||||
name: String<32>;
|
||||
description: Text;
|
||||
config: SystemConfig;
|
||||
config: Config;
|
||||
platform: Platform;
|
||||
super?: Boolean; // super表示是这个platform本身的系统,可以操作application/system这些数据,也可以访问超出本system的其它数据。
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { CommonAspectDict } from 'oak-common-aspect';
|
|||
import { AspectDict } from '../aspects/AspectDict';
|
||||
import { EntityDict } from '../general-app-domain';
|
||||
import { RuntimeContext } from '../context/RuntimeContext';
|
||||
import { Origin } from '../types/Config';
|
||||
|
||||
export class ExtraFile<
|
||||
ED extends EntityDict,
|
||||
|
|
@ -17,8 +18,7 @@ export class ExtraFile<
|
|||
super(aspectWrapper);
|
||||
}
|
||||
|
||||
@Action
|
||||
async getUploadInfo(origin: string, key?: string) {
|
||||
private async getUploadInfo(origin: Origin, key?: string) {
|
||||
const { result: uploadInfo } = await this.getAspectWrapper().exec(
|
||||
'getUploadInfo',
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,15 +1,90 @@
|
|||
export type QiniuConfig = {
|
||||
export type QiniuCloudConfig = {
|
||||
accessKey: string;
|
||||
secretKey: string;
|
||||
};
|
||||
|
||||
export type QiniuLiveConfig = {
|
||||
accessKey: string;
|
||||
liveHost: string; // 七牛直播云接口域名
|
||||
publishDomain: string; // 推流域名
|
||||
playDomain: string; // 拉流域名
|
||||
playBackDomain: string; // 直播回放存储域名
|
||||
hub: string; // 直播空间名,
|
||||
publishKey: string; // 直播空间限时鉴权密钥
|
||||
playKey: string; // 拉流密钥
|
||||
}
|
||||
|
||||
export type QiniuCosConfig = {
|
||||
accessKey: string;
|
||||
uploadHost: string; // 七牛上传域名
|
||||
liveHost?: string; // 七牛直播云接口域名
|
||||
puhlishDomain?: string; // 推流域名
|
||||
playDomain?: string; // 拉流域名
|
||||
playBackDomain?: string; // 直播回放存储域名
|
||||
hub?: string; // 直播空间名,
|
||||
publisthKey?: string; // 直播空间限时鉴权密钥
|
||||
playKey?: string; // 拉流密钥
|
||||
bucket: string;
|
||||
domain: string; // 域名
|
||||
protocol: string | string[];
|
||||
};
|
||||
}
|
||||
|
||||
export type AliCloudConfig = {
|
||||
accessKeyId: string;
|
||||
accessKeySecret: string;
|
||||
regionId: string;
|
||||
};
|
||||
|
||||
export type TencentCloudConfig = {
|
||||
secretId: string;
|
||||
secretKey: string;
|
||||
region: string;
|
||||
};
|
||||
|
||||
export type AmapCloudConfig = {
|
||||
webApiKey: string;
|
||||
}
|
||||
|
||||
export type AliSmsConfig = {
|
||||
accessKeyId: string;
|
||||
defaultSignName: string;
|
||||
templates: Record<string, {
|
||||
signName?: string;
|
||||
code: string; // templateCode
|
||||
params: string[]; // templateParams中的key值(和messageType中的参数位置对应)
|
||||
}>;
|
||||
};
|
||||
|
||||
export type TencentSmsConfig = {
|
||||
secretId: string;
|
||||
defaultSignName: string;
|
||||
templates: Record<string, {
|
||||
signName?: string;
|
||||
code: string;
|
||||
}>;
|
||||
};
|
||||
|
||||
|
||||
|
||||
export type Config = {
|
||||
Account?: {
|
||||
ali?: AliCloudConfig[];
|
||||
tencent?: TencentCloudConfig[];
|
||||
qiniu?: QiniuCloudConfig[];
|
||||
amap?: AmapCloudConfig[];
|
||||
},
|
||||
Cos?: {
|
||||
qiniu?: QiniuCosConfig;
|
||||
};
|
||||
Live?: {
|
||||
qiniu?: QiniuLiveConfig;
|
||||
},
|
||||
Map?: {
|
||||
amap?: {
|
||||
webApiKey: string;
|
||||
};
|
||||
};
|
||||
UserEntityGrant?: {
|
||||
lifetimeLength: number; // 授权的过期时间(ms)
|
||||
};
|
||||
Sms?: {
|
||||
ali?: AliSmsConfig[];
|
||||
tencent?: TencentSmsConfig[];
|
||||
}
|
||||
};
|
||||
|
||||
export type Origin = 'ali' | 'tencent' | 'qiniu' | 'amap';
|
||||
export type Service = 'Map' | 'Cos' | 'Live' | 'Sms';
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { OpSchema as ExtraFile } from '../general-app-domain/ExtraFile/Schema';
|
||||
import { SystemConfig } from '../general-app-domain/System/Schema';
|
||||
import { Config } from '../types/Config';
|
||||
|
||||
export function composeFileUrl(
|
||||
extraFile: Pick<
|
||||
|
|
@ -13,7 +13,7 @@ export function composeFileUrl(
|
|||
| 'extension'
|
||||
| 'entity'
|
||||
>,
|
||||
systemConfig?: SystemConfig
|
||||
config?: Config
|
||||
) {
|
||||
const { type, bucket, filename, origin, extra1, objectId, extension, entity } =
|
||||
extraFile;
|
||||
|
|
@ -27,9 +27,9 @@ export function composeFileUrl(
|
|||
}
|
||||
return extra1;
|
||||
}
|
||||
if (systemConfig && systemConfig.Cos) {
|
||||
if (config && config.Cos) {
|
||||
const { domain, protocol } =
|
||||
systemConfig.Cos[origin as keyof typeof systemConfig.Cos]!;
|
||||
config.Cos[origin as keyof typeof config.Cos]!;
|
||||
let protocol2 = protocol;
|
||||
if (protocol instanceof Array) {
|
||||
// protocol存在https 说明域名有证书
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
import { assert } from 'console';
|
||||
import { OakDataException } from 'oak-domain/lib/types/Exception';
|
||||
import { AmapSDK, QiniuSDK } from 'oak-external-sdk';
|
||||
import { RuntimeContext } from '../context/RuntimeContext';
|
||||
import { EntityDict } from '../general-app-domain';
|
||||
import { AliCloudConfig, AmapCloudConfig, Config, Origin, QiniuCloudConfig, Service, TencentCloudConfig } from '../types/Config';
|
||||
|
||||
export async function getConfig<ED extends EntityDict, Cxt extends RuntimeContext<ED>>(context: Cxt, service: Service, origin: Origin) {
|
||||
const { rowStore } = context;
|
||||
const systemId = await context.getSystemId();
|
||||
assert(systemId);
|
||||
const { result: [system] } = await rowStore.select('system', {
|
||||
data: {
|
||||
id: 1,
|
||||
config: 1,
|
||||
platform: {
|
||||
id: 1,
|
||||
config: 1,
|
||||
}
|
||||
},
|
||||
filter: {
|
||||
id: systemId!
|
||||
}
|
||||
}, context, {
|
||||
dontCollect: true,
|
||||
});
|
||||
|
||||
const { config: systemConfig, platform } = system as EntityDict['system']['Schema'];
|
||||
let originConfig = systemConfig[service] && (systemConfig[service] as any)[origin];
|
||||
let originCloudAccounts = originConfig && systemConfig.Account && systemConfig.Account[origin];
|
||||
|
||||
if (!originConfig) {
|
||||
const { config: platformConfig } = platform ;
|
||||
originConfig = platformConfig[service] && (platformConfig[service] as any)[origin];
|
||||
originCloudAccounts = originConfig && platformConfig.Account && platformConfig.Account[origin];
|
||||
}
|
||||
if (!originConfig) {
|
||||
throw new OakDataException(`调用的服务${service}源${origin}找不到相应的配置,请联系管理员`);
|
||||
}
|
||||
switch (origin) {
|
||||
case 'ali': {
|
||||
const aliAccount = (originCloudAccounts as AliCloudConfig[]).find(
|
||||
ele => ele.accessKeyId === originConfig.accessKeyId
|
||||
);
|
||||
assert(aliAccount, `调用的服务${service}源${origin}找不到相应的云平台帐号,请联系管理员`);
|
||||
throw new Error('阿里云的external SDK还未实现');
|
||||
}
|
||||
case 'tencent': {
|
||||
const tencentAccount = (originCloudAccounts as TencentCloudConfig[]).find(
|
||||
ele => ele.secretId === originConfig.secretId
|
||||
);
|
||||
assert(tencentAccount, `调用的服务${service}源${origin}找不到相应的云平台帐号,请联系管理员`);
|
||||
throw new Error('腾讯云的external SDK还未实现');
|
||||
}
|
||||
case 'qiniu': {
|
||||
const qiniuAccount = (originCloudAccounts as QiniuCloudConfig[]).find(
|
||||
ele => ele.accessKey === originConfig.accessKey
|
||||
);
|
||||
assert(qiniuAccount, `调用的服务${service}源${origin}找不到相应的云平台帐号,请联系管理员`);
|
||||
const qiniuInstance = QiniuSDK.getInstance(qiniuAccount!.accessKey, qiniuAccount!.secretKey);
|
||||
return {
|
||||
instance: qiniuInstance,
|
||||
config: originConfig,
|
||||
};
|
||||
}
|
||||
default: {
|
||||
assert (origin === 'amap');
|
||||
const amapAccount = (originCloudAccounts as AmapCloudConfig[]).find(
|
||||
ele => ele.webApiKey === originConfig.webApiKey
|
||||
);
|
||||
assert(amapAccount, `调用的服务${service}源${origin}找不到相应的云平台帐号,请联系管理员`);
|
||||
const amapInstance = AmapSDK.getInstance(amapAccount!.webApiKey);
|
||||
return {
|
||||
instance: amapInstance,
|
||||
config: originConfig,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
import { RuntimeContext } from '../context/RuntimeContext';
|
||||
import { EntityDict } from '../general-app-domain';
|
||||
import { Schema as Livestream } from '../general-app-domain/Livestream/Schema';
|
||||
import { Origin, QiniuLiveConfig } from '../types/Config';
|
||||
import { getConfig } from './getContextConfig';
|
||||
import { QiniuCloudInstance } from 'oak-external-sdk';
|
||||
import assert from 'assert';
|
||||
|
||||
/**
|
||||
* 创建直播流并生成推拉流地址
|
||||
* @param streamTitle 直播流名称
|
||||
* @param expireAt 推流过期时间
|
||||
* @param context context
|
||||
* @returns Livestream 对象
|
||||
*/
|
||||
export async function getLivestream<ED extends EntityDict, Cxt extends RuntimeContext<ED>>(
|
||||
params: {
|
||||
origin: Origin;
|
||||
streamTitle: string,
|
||||
expireAt: number,
|
||||
},
|
||||
context: Cxt
|
||||
): Promise<Pick<Livestream,
|
||||
| 'streamTitle'
|
||||
| 'hub'
|
||||
| 'rtmpPushUrl'
|
||||
| 'rtmpPlayUrl'
|
||||
| 'pcPushUrl'
|
||||
| 'streamKey'
|
||||
| 'expireAt'>
|
||||
> {
|
||||
const { streamTitle, expireAt, origin } = params;
|
||||
// 获取七牛直播云信息
|
||||
const {
|
||||
instance,
|
||||
config,
|
||||
} = await getConfig<ED, Cxt>(context, 'Live', origin);
|
||||
assert(origin === 'qiniu');
|
||||
const { hub, liveHost, publishDomain, playDomain, playKey, publishKey } = config as QiniuLiveConfig;
|
||||
return (<QiniuCloudInstance>instance).getLiveStream(hub, 'POST', streamTitle, liveHost, publishDomain, playDomain, publishKey, playKey, expireAt);
|
||||
}
|
||||
|
||||
// 获取推拉流地址
|
||||
/**
|
||||
* 直播流已存在的情况下,获取推拉流地址
|
||||
* @param streamTitle 直播流名称
|
||||
* @param expireAt 推流过期时间
|
||||
* @param context context
|
||||
* @returns livestream对象
|
||||
*/
|
||||
export async function getStreamObj<ED extends EntityDict, Cxt extends RuntimeContext<ED>>(
|
||||
params: {
|
||||
origin: Origin;
|
||||
streamTitle: string;
|
||||
expireAt: number;
|
||||
},
|
||||
context: Cxt
|
||||
): Promise<Pick<Livestream,
|
||||
| 'streamTitle'
|
||||
| 'hub'
|
||||
| 'rtmpPushUrl'
|
||||
| 'rtmpPlayUrl'
|
||||
| 'pcPushUrl'
|
||||
| 'streamKey'
|
||||
| 'expireAt'>
|
||||
> {
|
||||
const { streamTitle, expireAt, origin } = params;
|
||||
const {
|
||||
instance,
|
||||
config,
|
||||
} = await getConfig<ED, Cxt>(context, 'Live', origin);
|
||||
|
||||
assert(origin === 'qiniu');
|
||||
const { publishDomain: publishDomain, publishKey: publishKey, playDomain, playKey, hub } = config as QiniuLiveConfig;
|
||||
return (<QiniuCloudInstance>instance).getStreamObj(publishDomain, playDomain, hub, publishKey, playKey, streamTitle, expireAt);
|
||||
}
|
||||
|
||||
// 生成直播回放
|
||||
export async function getPlayBackUrl<ED extends EntityDict, Cxt extends RuntimeContext<ED>>(
|
||||
params: {
|
||||
origin: Origin;
|
||||
streamTitle: string;
|
||||
start: number;
|
||||
end: number;
|
||||
},
|
||||
context: Cxt
|
||||
) {
|
||||
const { streamTitle, start, end, origin } = params;
|
||||
// 获取七牛直播云信息
|
||||
const {
|
||||
config,
|
||||
instance
|
||||
} = await getConfig<ED, Cxt>(context, 'Live', origin);
|
||||
const { hub, playBackDomain, liveHost } = config as QiniuLiveConfig;
|
||||
return (<QiniuCloudInstance>instance).getPlayBackUrl(hub, playBackDomain, streamTitle, start, end, 'POST', liveHost);
|
||||
}
|
||||
Loading…
Reference in New Issue