cos和sms改为依赖上层注入,修改了模块初始化的调用位置,增加了template模板的一些文件结构
This commit is contained in:
parent
cd8e553ee1
commit
f05405ebf4
|
|
@ -12,7 +12,7 @@ declare const _default: <ED2 extends EntityDict & BaseEntityDict, T2 extends key
|
|||
type?: ButtonProps['type'] | AmButtonProps['type'];
|
||||
executeText?: string | undefined;
|
||||
buttonProps?: (ButtonProps & {
|
||||
color?: "default" | "success" | "primary" | "warning" | "danger" | undefined;
|
||||
color?: "default" | "success" | "warning" | "primary" | "danger" | undefined;
|
||||
fill?: "none" | "solid" | "outline" | undefined;
|
||||
size?: "small" | "large" | "middle" | "mini" | undefined;
|
||||
block?: boolean | undefined;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export declare abstract class FrontendRuntimeContext<ED extends EntityDict & Bas
|
|||
private token;
|
||||
constructor(store: SyncRowStore<ED, FrontendRuntimeContext<ED>>, features: FeatureDict<ED> & BasicFeatures<ED>);
|
||||
protected getSerializedData(): Promise<SerializedData>;
|
||||
getApplicationId(): string;
|
||||
getApplicationId(): string | undefined;
|
||||
getSystemId(): string | undefined;
|
||||
getApplication(): Partial<import("../oak-app-domain/Application/Schema").Schema> | undefined;
|
||||
getTokenValue(allowUnloggedIn?: boolean): string | undefined;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export declare class Application<ED extends EntityDict> extends Feature {
|
|||
private loadApplicationInfo;
|
||||
initialize(domain: string, appId?: string | null, projection?: EntityDict['application']['Selection']['data']): Promise<void>;
|
||||
getApplication(): Partial<import("../oak-app-domain/Application/Schema").Schema> | undefined;
|
||||
getApplicationId(): string;
|
||||
getApplicationId(allowUnInitialized?: boolean): string | undefined;
|
||||
uploadWechatMedia(params: {
|
||||
applicationId: string;
|
||||
file: File;
|
||||
|
|
|
|||
|
|
@ -71,9 +71,11 @@ export class Application extends Feature {
|
|||
}
|
||||
return this.application;
|
||||
}
|
||||
getApplicationId() {
|
||||
getApplicationId(allowUnInitialized) {
|
||||
if (this.applicationId === undefined) {
|
||||
throw new OakApplicationLoadingException();
|
||||
if (!allowUnInitialized) {
|
||||
throw new OakApplicationLoadingException();
|
||||
}
|
||||
}
|
||||
return this.applicationId;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,12 +2,14 @@ import { Feature } from 'oak-frontend-base/es/types/Feature';
|
|||
import { Cache } from 'oak-frontend-base/es/features/cache';
|
||||
import { EntityDict } from '../oak-app-domain';
|
||||
import { Application } from './application';
|
||||
import Cos from '../types/Cos';
|
||||
export type FileState = 'local' | 'uploading' | 'uploaded' | 'failed';
|
||||
export declare class ExtraFile<ED extends EntityDict> extends Feature {
|
||||
private cache;
|
||||
private application;
|
||||
private files;
|
||||
constructor(cache: Cache<ED>, application: Application<ED>);
|
||||
registerCos(clazzes: Array<new () => Cos<ED>>): void;
|
||||
addLocalFile(id: string, file: File | string): void;
|
||||
removeLocalFiles(ids: string[]): void;
|
||||
upload(id: string, entity: keyof ED): Promise<void>;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { Feature } from 'oak-frontend-base/es/types/Feature';
|
|||
import { Upload } from 'oak-frontend-base/es/utils/upload';
|
||||
import { bytesToSize, getFileURL } from '../utils/extraFile';
|
||||
import { assert } from 'oak-domain/lib/utils/assert';
|
||||
import { getCos } from '../utils/cos';
|
||||
import { getCos, registerCos } from '../utils/cos';
|
||||
import { unset } from 'oak-domain/lib/utils/lodash';
|
||||
import { generateNewId, generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
|
||||
import { extraFileProjection } from '../types/Projection';
|
||||
|
|
@ -16,6 +16,9 @@ export class ExtraFile extends Feature {
|
|||
this.application = application;
|
||||
this.files = {};
|
||||
}
|
||||
registerCos(clazzes) {
|
||||
clazzes.forEach((clazz) => registerCos(clazz));
|
||||
}
|
||||
addLocalFile(id, file) {
|
||||
assert(!this.files[id]);
|
||||
this.files[id] = {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { UserWechatPublicTag } from './userWechatPublicTag';
|
|||
import { BasicFeatures } from 'oak-frontend-base';
|
||||
import { EntityDict } from '../oak-app-domain';
|
||||
import Theme from './theme';
|
||||
import Cos from '../types/Cos';
|
||||
export declare function create<ED extends EntityDict>(basicFeatures: BasicFeatures<ED>): FeatureDict<ED>;
|
||||
export type FeatureDict<ED extends EntityDict> = {
|
||||
token: Token<ED>;
|
||||
|
|
@ -27,4 +28,4 @@ import { AccessConfiguration } from 'oak-domain/lib/types/Configuration';
|
|||
export declare function initialize<ED extends EntityDict>(features: FeatureDict<ED> & BasicFeatures<ED>, access: AccessConfiguration, config?: {
|
||||
applicationExtraProjection?: ED['application']['Selection']['data'];
|
||||
dontAutoLoginInWechatmp?: true;
|
||||
}): Promise<void>;
|
||||
}, clazzes?: Array<new () => Cos<ED>>): Promise<void>;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ export function create(basicFeatures) {
|
|||
userWechatPublicTag,
|
||||
};
|
||||
}
|
||||
export async function initialize(features, access, config) {
|
||||
export async function initialize(features, access, config, clazzes) {
|
||||
const location = features.navigator.getLocation();
|
||||
const searchParams = new URLSearchParams(location.search);
|
||||
const appId = searchParams.get('appId');
|
||||
|
|
@ -40,6 +40,9 @@ export async function initialize(features, access, config) {
|
|||
if (process.env.OAK_PLATFORM === 'web') {
|
||||
features.wechatSdk.setLandingUrl(window.location.href);
|
||||
}
|
||||
if (clazzes) {
|
||||
features.extraFile.registerCos(clazzes);
|
||||
}
|
||||
// 小程序自动登录
|
||||
if (process.env.OAK_PLATFORM === 'wechatMp' && !config?.dontAutoLoginInWechatmp) {
|
||||
if (!features.token.getTokenValue()) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
export { registerMessageType, } from './aspects/template';
|
||||
export { registerWeChatPublicEventCallback, } from './endpoints/wechat';
|
||||
export { registerMessageNotificationConverters, } from './triggers/message';
|
||||
export { registSms, } from './utils/sms';
|
||||
export { registerCos, } from './utils/cos';
|
||||
export { registerWechatPublicTags, } from './config/constants';
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
export { registerMessageType, } from './aspects/template';
|
||||
export { registerWeChatPublicEventCallback, } from './endpoints/wechat';
|
||||
export { registerMessageNotificationConverters, } from './triggers/message';
|
||||
export { registSms, } from './utils/sms';
|
||||
export { registerCos, } from './utils/cos';
|
||||
export { registerWechatPublicTags, } from './config/constants';
|
||||
|
|
@ -1,2 +1,2 @@
|
|||
declare const _default: (import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "account", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "address", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "application", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "article", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "articleMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "extraFile", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "user", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "message", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "notification", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatLogin", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "parasite", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "sessionMessage", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMpJump", import("..").BRC<import("../oak-app-domain").EntityDict>>)[];
|
||||
declare const _default: (import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "message", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "account", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "address", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "application", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "article", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "articleMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "extraFile", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "user", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "notification", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatLogin", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "parasite", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "sessionMessage", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMpJump", import("..").BRC<import("../oak-app-domain").EntityDict>>)[];
|
||||
export default _default;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export declare function createToDo<ED extends EntityDict & BaseEntityDict, T ext
|
|||
redirectTo: EntityDict['toDo']['OpSchema']['redirectTo'];
|
||||
entity: any;
|
||||
entityId: string;
|
||||
}, userIds?: string[]): Promise<0 | 1>;
|
||||
}, userIds?: string[]): Promise<1 | 0>;
|
||||
/**
|
||||
* 完成todo例程,当在entity对象上进行action操作时(操作条件是filter),将对应的todo完成
|
||||
* 必须在entity的action的后trigger中调用
|
||||
|
|
|
|||
|
|
@ -1,15 +1,5 @@
|
|||
import { assert } from 'oak-domain/lib/utils/assert';
|
||||
import Qiniu from './qiniu';
|
||||
import Wechat from './wechat';
|
||||
import CTYun from './ctyun';
|
||||
const ctyun = new CTYun();
|
||||
const qiniu = new Qiniu();
|
||||
const wechat = new Wechat();
|
||||
const CosDict = {
|
||||
[qiniu.name]: qiniu,
|
||||
[wechat.name]: wechat,
|
||||
[ctyun.name]: ctyun,
|
||||
};
|
||||
const CosDict = {};
|
||||
/**
|
||||
* 注入一个其它OSS上实现的uploader类
|
||||
* @param clazz
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { EntityDict } from '../../oak-app-domain';
|
||||
import { BRC } from '../../types/RuntimeCxt';
|
||||
import Sms from '../../types/Sms';
|
||||
/**
|
||||
* 注入一个其它OSS上实现的uploader类
|
||||
|
|
@ -7,3 +8,13 @@ import Sms from '../../types/Sms';
|
|||
export declare function registSms<ED extends EntityDict>(clazz: new () => Sms<ED>): void;
|
||||
export declare function getSms<ED extends EntityDict>(origin: string): Sms<ED>;
|
||||
export declare function getOrigin(): string[];
|
||||
export declare function sendSms<ED extends EntityDict>(options: {
|
||||
messageType?: string;
|
||||
origin?: 'ali' | 'tencent';
|
||||
templateName?: string;
|
||||
mobile: string;
|
||||
templateParam?: Record<string, string> | string[];
|
||||
}, context: BRC<ED>): Promise<{
|
||||
success: boolean;
|
||||
res: any;
|
||||
}>;
|
||||
|
|
|
|||
|
|
@ -1,15 +1,5 @@
|
|||
import { assert } from 'oak-domain/lib/utils/assert';
|
||||
import Ali from './ali';
|
||||
import Tencent from './tencent';
|
||||
import CTYun from './ctyun';
|
||||
const ali = new Ali();
|
||||
const tencent = new Tencent();
|
||||
const ctyun = new CTYun();
|
||||
const SmsDict = {
|
||||
[ali.name]: ali,
|
||||
[tencent.name]: tencent,
|
||||
[ctyun.name]: ctyun,
|
||||
};
|
||||
const SmsDict = {};
|
||||
/**
|
||||
* 注入一个其它OSS上实现的uploader类
|
||||
* @param clazz
|
||||
|
|
@ -25,3 +15,105 @@ export function getSms(origin) {
|
|||
export function getOrigin() {
|
||||
return Object.keys(SmsDict);
|
||||
}
|
||||
export async function sendSms(options, context) {
|
||||
const { messageType, origin, templateName, mobile, templateParam, } = options;
|
||||
assert(messageType || (origin && templateName));
|
||||
if (origin && templateName) {
|
||||
const [smsTemplate] = await context.select('smsTemplate', {
|
||||
data: {
|
||||
id: 1,
|
||||
origin: 1,
|
||||
systemId: 1,
|
||||
templateCode: 1,
|
||||
},
|
||||
filter: {
|
||||
origin,
|
||||
templateName
|
||||
}
|
||||
}, {});
|
||||
if (!smsTemplate) {
|
||||
return {
|
||||
success: false,
|
||||
res: `${origin}渠道的${templateName}短信模板未配置`
|
||||
};
|
||||
}
|
||||
try {
|
||||
const instance = getSms(origin);
|
||||
const result = await instance.sendSms({
|
||||
mobile,
|
||||
templateParam,
|
||||
smsTemplate,
|
||||
}, context);
|
||||
return result;
|
||||
}
|
||||
catch (err) {
|
||||
return {
|
||||
success: false,
|
||||
res: err,
|
||||
};
|
||||
}
|
||||
}
|
||||
else {
|
||||
const systemId = context.getSystemId();
|
||||
const messageTypeSmsTemplateList = await context.select('messageTypeSmsTemplate', {
|
||||
data: {
|
||||
id: 1,
|
||||
type: 1,
|
||||
templateId: 1,
|
||||
template: {
|
||||
id: 1,
|
||||
origin: 1,
|
||||
systemId: 1,
|
||||
templateCode: 1,
|
||||
}
|
||||
},
|
||||
filter: {
|
||||
template: {
|
||||
systemId,
|
||||
},
|
||||
type: messageType,
|
||||
}
|
||||
}, {});
|
||||
// todo 多渠道短信的负载均衡,目前按照顺序发
|
||||
let resList = {};
|
||||
if (messageTypeSmsTemplateList.length > 0) {
|
||||
for (const messageTypeSmsTemplate of messageTypeSmsTemplateList) {
|
||||
try {
|
||||
const instance = getSms(messageTypeSmsTemplate.template.origin);
|
||||
const result = await instance.sendSms({
|
||||
mobile,
|
||||
templateParam,
|
||||
smsTemplate: messageTypeSmsTemplate.template,
|
||||
}, context);
|
||||
Object.assign(resList, {
|
||||
[messageTypeSmsTemplate.template.origin]: result.res,
|
||||
});
|
||||
if (result.success) {
|
||||
return {
|
||||
success: true,
|
||||
res: resList,
|
||||
};
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
Object.assign(resList, {
|
||||
[messageTypeSmsTemplate.template.origin]: err,
|
||||
});
|
||||
}
|
||||
}
|
||||
return {
|
||||
success: false,
|
||||
res: {
|
||||
message: '所有短信渠道均发送失败',
|
||||
errorList: resList,
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
return {
|
||||
success: false,
|
||||
res: `短信未配置${messageType}模板`
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export declare abstract class FrontendRuntimeContext<ED extends EntityDict & Bas
|
|||
private token;
|
||||
constructor(store: SyncRowStore<ED, FrontendRuntimeContext<ED>>, features: FeatureDict<ED> & BasicFeatures<ED>);
|
||||
protected getSerializedData(): Promise<SerializedData>;
|
||||
getApplicationId(): string;
|
||||
getApplicationId(): string | undefined;
|
||||
getSystemId(): string | undefined;
|
||||
getApplication(): Partial<import("../oak-app-domain/Application/Schema").Schema> | undefined;
|
||||
getTokenValue(allowUnloggedIn?: boolean): string | undefined;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export declare class Application<ED extends EntityDict> extends Feature {
|
|||
private loadApplicationInfo;
|
||||
initialize(domain: string, appId?: string | null, projection?: EntityDict['application']['Selection']['data']): Promise<void>;
|
||||
getApplication(): Partial<import("../oak-app-domain/Application/Schema").Schema> | undefined;
|
||||
getApplicationId(): string;
|
||||
getApplicationId(allowUnInitialized?: boolean): string | undefined;
|
||||
uploadWechatMedia(params: {
|
||||
applicationId: string;
|
||||
file: File;
|
||||
|
|
|
|||
|
|
@ -74,9 +74,11 @@ class Application extends Feature_1.Feature {
|
|||
}
|
||||
return this.application;
|
||||
}
|
||||
getApplicationId() {
|
||||
getApplicationId(allowUnInitialized) {
|
||||
if (this.applicationId === undefined) {
|
||||
throw new Exception_1.OakApplicationLoadingException();
|
||||
if (!allowUnInitialized) {
|
||||
throw new Exception_1.OakApplicationLoadingException();
|
||||
}
|
||||
}
|
||||
return this.applicationId;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,12 +2,14 @@ import { Feature } from 'oak-frontend-base/es/types/Feature';
|
|||
import { Cache } from 'oak-frontend-base/es/features/cache';
|
||||
import { EntityDict } from '../oak-app-domain';
|
||||
import { Application } from './application';
|
||||
import Cos from '../types/Cos';
|
||||
export type FileState = 'local' | 'uploading' | 'uploaded' | 'failed';
|
||||
export declare class ExtraFile<ED extends EntityDict> extends Feature {
|
||||
private cache;
|
||||
private application;
|
||||
private files;
|
||||
constructor(cache: Cache<ED>, application: Application<ED>);
|
||||
registerCos(clazzes: Array<new () => Cos<ED>>): void;
|
||||
addLocalFile(id: string, file: File | string): void;
|
||||
removeLocalFiles(ids: string[]): void;
|
||||
upload(id: string, entity: keyof ED): Promise<void>;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@ class ExtraFile extends Feature_1.Feature {
|
|||
this.application = application;
|
||||
this.files = {};
|
||||
}
|
||||
registerCos(clazzes) {
|
||||
clazzes.forEach((clazz) => (0, cos_1.registerCos)(clazz));
|
||||
}
|
||||
addLocalFile(id, file) {
|
||||
(0, assert_1.assert)(!this.files[id]);
|
||||
this.files[id] = {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { UserWechatPublicTag } from './userWechatPublicTag';
|
|||
import { BasicFeatures } from 'oak-frontend-base';
|
||||
import { EntityDict } from '../oak-app-domain';
|
||||
import Theme from './theme';
|
||||
import Cos from '../types/Cos';
|
||||
export declare function create<ED extends EntityDict>(basicFeatures: BasicFeatures<ED>): FeatureDict<ED>;
|
||||
export type FeatureDict<ED extends EntityDict> = {
|
||||
token: Token<ED>;
|
||||
|
|
@ -27,4 +28,4 @@ import { AccessConfiguration } from 'oak-domain/lib/types/Configuration';
|
|||
export declare function initialize<ED extends EntityDict>(features: FeatureDict<ED> & BasicFeatures<ED>, access: AccessConfiguration, config?: {
|
||||
applicationExtraProjection?: ED['application']['Selection']['data'];
|
||||
dontAutoLoginInWechatmp?: true;
|
||||
}): Promise<void>;
|
||||
}, clazzes?: Array<new () => Cos<ED>>): Promise<void>;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ function create(basicFeatures) {
|
|||
};
|
||||
}
|
||||
exports.create = create;
|
||||
async function initialize(features, access, config) {
|
||||
async function initialize(features, access, config, clazzes) {
|
||||
const location = features.navigator.getLocation();
|
||||
const searchParams = new URLSearchParams(location.search);
|
||||
const appId = searchParams.get('appId');
|
||||
|
|
@ -45,6 +45,9 @@ async function initialize(features, access, config) {
|
|||
if (process.env.OAK_PLATFORM === 'web') {
|
||||
features.wechatSdk.setLandingUrl(window.location.href);
|
||||
}
|
||||
if (clazzes) {
|
||||
features.extraFile.registerCos(clazzes);
|
||||
}
|
||||
// 小程序自动登录
|
||||
if (process.env.OAK_PLATFORM === 'wechatMp' && !config?.dontAutoLoginInWechatmp) {
|
||||
if (!features.token.getTokenValue()) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
export { registerMessageType, } from './aspects/template';
|
||||
export { registerWeChatPublicEventCallback, } from './endpoints/wechat';
|
||||
export { registerMessageNotificationConverters, } from './triggers/message';
|
||||
export { registSms, } from './utils/sms';
|
||||
export { registerCos, } from './utils/cos';
|
||||
export { registerWechatPublicTags, } from './config/constants';
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.registerWechatPublicTags = exports.registerCos = exports.registSms = exports.registerMessageNotificationConverters = exports.registerWeChatPublicEventCallback = exports.registerMessageType = void 0;
|
||||
var template_1 = require("./aspects/template");
|
||||
Object.defineProperty(exports, "registerMessageType", { enumerable: true, get: function () { return template_1.registerMessageType; } });
|
||||
var wechat_1 = require("./endpoints/wechat");
|
||||
Object.defineProperty(exports, "registerWeChatPublicEventCallback", { enumerable: true, get: function () { return wechat_1.registerWeChatPublicEventCallback; } });
|
||||
var message_1 = require("./triggers/message");
|
||||
Object.defineProperty(exports, "registerMessageNotificationConverters", { enumerable: true, get: function () { return message_1.registerMessageNotificationConverters; } });
|
||||
var sms_1 = require("./utils/sms");
|
||||
Object.defineProperty(exports, "registSms", { enumerable: true, get: function () { return sms_1.registSms; } });
|
||||
var cos_1 = require("./utils/cos");
|
||||
Object.defineProperty(exports, "registerCos", { enumerable: true, get: function () { return cos_1.registerCos; } });
|
||||
var constants_1 = require("./config/constants");
|
||||
Object.defineProperty(exports, "registerWechatPublicTags", { enumerable: true, get: function () { return constants_1.registerWechatPublicTags; } });
|
||||
|
|
@ -1,2 +1,2 @@
|
|||
declare const _default: (import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "account", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "address", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "application", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "article", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "articleMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "extraFile", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "user", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "message", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "notification", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatLogin", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "parasite", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "sessionMessage", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMpJump", import("..").BRC<import("../oak-app-domain").EntityDict>>)[];
|
||||
declare const _default: (import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "message", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "account", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "address", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "application", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "article", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "articleMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "extraFile", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "user", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "notification", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatLogin", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "parasite", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "sessionMessage", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMpJump", import("..").BRC<import("../oak-app-domain").EntityDict>>)[];
|
||||
export default _default;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export declare function createToDo<ED extends EntityDict & BaseEntityDict, T ext
|
|||
redirectTo: EntityDict['toDo']['OpSchema']['redirectTo'];
|
||||
entity: any;
|
||||
entityId: string;
|
||||
}, userIds?: string[]): Promise<0 | 1>;
|
||||
}, userIds?: string[]): Promise<1 | 0>;
|
||||
/**
|
||||
* 完成todo例程,当在entity对象上进行action操作时(操作条件是filter),将对应的todo完成
|
||||
* 必须在entity的action的后trigger中调用
|
||||
|
|
|
|||
|
|
@ -1,19 +1,8 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.composeFileUrl = exports.getCos = exports.registerCos = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const assert_1 = require("oak-domain/lib/utils/assert");
|
||||
const qiniu_1 = tslib_1.__importDefault(require("./qiniu"));
|
||||
const wechat_1 = tslib_1.__importDefault(require("./wechat"));
|
||||
const ctyun_1 = tslib_1.__importDefault(require("./ctyun"));
|
||||
const ctyun = new ctyun_1.default();
|
||||
const qiniu = new qiniu_1.default();
|
||||
const wechat = new wechat_1.default();
|
||||
const CosDict = {
|
||||
[qiniu.name]: qiniu,
|
||||
[wechat.name]: wechat,
|
||||
[ctyun.name]: ctyun,
|
||||
};
|
||||
const CosDict = {};
|
||||
/**
|
||||
* 注入一个其它OSS上实现的uploader类
|
||||
* @param clazz
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { EntityDict } from '../../oak-app-domain';
|
||||
import { BRC } from '../../types/RuntimeCxt';
|
||||
import Sms from '../../types/Sms';
|
||||
/**
|
||||
* 注入一个其它OSS上实现的uploader类
|
||||
|
|
@ -7,3 +8,13 @@ import Sms from '../../types/Sms';
|
|||
export declare function registSms<ED extends EntityDict>(clazz: new () => Sms<ED>): void;
|
||||
export declare function getSms<ED extends EntityDict>(origin: string): Sms<ED>;
|
||||
export declare function getOrigin(): string[];
|
||||
export declare function sendSms<ED extends EntityDict>(options: {
|
||||
messageType?: string;
|
||||
origin?: 'ali' | 'tencent';
|
||||
templateName?: string;
|
||||
mobile: string;
|
||||
templateParam?: Record<string, string> | string[];
|
||||
}, context: BRC<ED>): Promise<{
|
||||
success: boolean;
|
||||
res: any;
|
||||
}>;
|
||||
|
|
|
|||
|
|
@ -1,19 +1,8 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getOrigin = exports.getSms = exports.registSms = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
exports.sendSms = exports.getOrigin = exports.getSms = exports.registSms = void 0;
|
||||
const assert_1 = require("oak-domain/lib/utils/assert");
|
||||
const ali_1 = tslib_1.__importDefault(require("./ali"));
|
||||
const tencent_1 = tslib_1.__importDefault(require("./tencent"));
|
||||
const ctyun_1 = tslib_1.__importDefault(require("./ctyun"));
|
||||
const ali = new ali_1.default();
|
||||
const tencent = new tencent_1.default();
|
||||
const ctyun = new ctyun_1.default();
|
||||
const SmsDict = {
|
||||
[ali.name]: ali,
|
||||
[tencent.name]: tencent,
|
||||
[ctyun.name]: ctyun,
|
||||
};
|
||||
const SmsDict = {};
|
||||
/**
|
||||
* 注入一个其它OSS上实现的uploader类
|
||||
* @param clazz
|
||||
|
|
@ -32,3 +21,106 @@ function getOrigin() {
|
|||
return Object.keys(SmsDict);
|
||||
}
|
||||
exports.getOrigin = getOrigin;
|
||||
async function sendSms(options, context) {
|
||||
const { messageType, origin, templateName, mobile, templateParam, } = options;
|
||||
(0, assert_1.assert)(messageType || (origin && templateName));
|
||||
if (origin && templateName) {
|
||||
const [smsTemplate] = await context.select('smsTemplate', {
|
||||
data: {
|
||||
id: 1,
|
||||
origin: 1,
|
||||
systemId: 1,
|
||||
templateCode: 1,
|
||||
},
|
||||
filter: {
|
||||
origin,
|
||||
templateName
|
||||
}
|
||||
}, {});
|
||||
if (!smsTemplate) {
|
||||
return {
|
||||
success: false,
|
||||
res: `${origin}渠道的${templateName}短信模板未配置`
|
||||
};
|
||||
}
|
||||
try {
|
||||
const instance = getSms(origin);
|
||||
const result = await instance.sendSms({
|
||||
mobile,
|
||||
templateParam,
|
||||
smsTemplate,
|
||||
}, context);
|
||||
return result;
|
||||
}
|
||||
catch (err) {
|
||||
return {
|
||||
success: false,
|
||||
res: err,
|
||||
};
|
||||
}
|
||||
}
|
||||
else {
|
||||
const systemId = context.getSystemId();
|
||||
const messageTypeSmsTemplateList = await context.select('messageTypeSmsTemplate', {
|
||||
data: {
|
||||
id: 1,
|
||||
type: 1,
|
||||
templateId: 1,
|
||||
template: {
|
||||
id: 1,
|
||||
origin: 1,
|
||||
systemId: 1,
|
||||
templateCode: 1,
|
||||
}
|
||||
},
|
||||
filter: {
|
||||
template: {
|
||||
systemId,
|
||||
},
|
||||
type: messageType,
|
||||
}
|
||||
}, {});
|
||||
// todo 多渠道短信的负载均衡,目前按照顺序发
|
||||
let resList = {};
|
||||
if (messageTypeSmsTemplateList.length > 0) {
|
||||
for (const messageTypeSmsTemplate of messageTypeSmsTemplateList) {
|
||||
try {
|
||||
const instance = getSms(messageTypeSmsTemplate.template.origin);
|
||||
const result = await instance.sendSms({
|
||||
mobile,
|
||||
templateParam,
|
||||
smsTemplate: messageTypeSmsTemplate.template,
|
||||
}, context);
|
||||
Object.assign(resList, {
|
||||
[messageTypeSmsTemplate.template.origin]: result.res,
|
||||
});
|
||||
if (result.success) {
|
||||
return {
|
||||
success: true,
|
||||
res: resList,
|
||||
};
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
Object.assign(resList, {
|
||||
[messageTypeSmsTemplate.template.origin]: err,
|
||||
});
|
||||
}
|
||||
}
|
||||
return {
|
||||
success: false,
|
||||
res: {
|
||||
message: '所有短信渠道均发送失败',
|
||||
errorList: resList,
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
return {
|
||||
success: false,
|
||||
res: `短信未配置${messageType}模板`
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.sendSms = sendSms;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@
|
|||
"lib/**/*",
|
||||
"es/**/*",
|
||||
"src/entities/*",
|
||||
"src/types/*"
|
||||
"src/types/*",
|
||||
"template/**"
|
||||
],
|
||||
"dependencies": {
|
||||
"@uiw/react-amap": "^5.0.12",
|
||||
|
|
|
|||
|
|
@ -99,9 +99,11 @@ export class Application<ED extends EntityDict> extends Feature {
|
|||
return this.application;
|
||||
}
|
||||
|
||||
getApplicationId() {
|
||||
getApplicationId(allowUnInitialized?: boolean) {
|
||||
if (this.applicationId === undefined) {
|
||||
throw new OakApplicationLoadingException();
|
||||
if (!allowUnInitialized) {
|
||||
throw new OakApplicationLoadingException();
|
||||
}
|
||||
}
|
||||
return this.applicationId;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,11 +5,12 @@ import { EntityDict } from '../oak-app-domain';
|
|||
import { Application } from './application'
|
||||
import { bytesToSize, getFileURL } from '../utils/extraFile';
|
||||
import { assert } from 'oak-domain/lib/utils/assert';
|
||||
import { getCos } from '../utils/cos';
|
||||
import { getCos, registerCos } from '../utils/cos';
|
||||
import { OpSchema } from '../oak-app-domain/ExtraFile/Schema';
|
||||
import { unset } from 'oak-domain/lib/utils/lodash';
|
||||
import { generateNewId, generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
|
||||
import { extraFileProjection } from '../types/Projection';
|
||||
import Cos from '../types/Cos';
|
||||
|
||||
export type FileState = 'local' | 'uploading' | 'uploaded' | 'failed';
|
||||
|
||||
|
|
@ -32,6 +33,12 @@ export class ExtraFile<ED extends EntityDict> extends Feature {
|
|||
this.files = {};
|
||||
}
|
||||
|
||||
registerCos(clazzes: Array<new () => Cos<ED>>) {
|
||||
clazzes.forEach(
|
||||
(clazz) => registerCos(clazz)
|
||||
);
|
||||
}
|
||||
|
||||
addLocalFile(id: string, file: File | string) {
|
||||
assert(!this.files[id]);
|
||||
this.files[id] = {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { UserWechatPublicTag } from './userWechatPublicTag';
|
|||
import { BasicFeatures } from 'oak-frontend-base';
|
||||
import { EntityDict } from '../oak-app-domain';
|
||||
import Theme from './theme';
|
||||
import Cos from '../types/Cos';
|
||||
|
||||
export function create<ED extends EntityDict>(
|
||||
basicFeatures: BasicFeatures<ED>
|
||||
|
|
@ -88,7 +89,8 @@ export async function initialize<ED extends EntityDict>(
|
|||
config?: {
|
||||
applicationExtraProjection?: ED['application']['Selection']['data'],
|
||||
dontAutoLoginInWechatmp?: true
|
||||
}
|
||||
},
|
||||
clazzes?: Array<new () => Cos<ED>>,
|
||||
) {
|
||||
const location = features.navigator.getLocation();
|
||||
const searchParams = new URLSearchParams(location.search);
|
||||
|
|
@ -99,6 +101,9 @@ export async function initialize<ED extends EntityDict>(
|
|||
features.wechatSdk.setLandingUrl(window.location.href);
|
||||
}
|
||||
|
||||
if (clazzes) {
|
||||
features.extraFile.registerCos(clazzes);
|
||||
}
|
||||
// 小程序自动登录
|
||||
if (process.env.OAK_PLATFORM === 'wechatMp' && !config?.dontAutoLoginInWechatmp) {
|
||||
if (!features.token.getTokenValue()) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
export {
|
||||
registerMessageType,
|
||||
} from './aspects/template';
|
||||
|
||||
export {
|
||||
registerWeChatPublicEventCallback,
|
||||
} from './endpoints/wechat';
|
||||
|
||||
export {
|
||||
registerMessageNotificationConverters,
|
||||
} from './triggers/message';
|
||||
|
||||
export {
|
||||
registSms,
|
||||
} from './utils/sms';
|
||||
|
||||
export {
|
||||
registerCos,
|
||||
} from './utils/cos';
|
||||
|
||||
export {
|
||||
registerWechatPublicTags,
|
||||
} from './config/constants';
|
||||
|
|
@ -1,20 +1,9 @@
|
|||
import { assert } from 'oak-domain/lib/utils/assert';
|
||||
import { BRC, FRC } from '../../types/RuntimeCxt';
|
||||
import { EntityDict } from '../../oak-app-domain';
|
||||
|
||||
import Cos from '../../types/Cos';
|
||||
import Qiniu from './qiniu';
|
||||
import Wechat from './wechat';
|
||||
import CTYun from './ctyun';
|
||||
|
||||
const ctyun = new CTYun();
|
||||
const qiniu = new Qiniu();
|
||||
const wechat = new Wechat();
|
||||
|
||||
const CosDict: Record<string, Cos<EntityDict>> = {
|
||||
[qiniu.name]: qiniu,
|
||||
[wechat.name]: wechat,
|
||||
[ctyun.name]: ctyun,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
179
src/utils/sms.ts
179
src/utils/sms.ts
|
|
@ -1,179 +0,0 @@
|
|||
|
||||
import { assert } from 'oak-domain/lib/utils/assert';
|
||||
import { EntityDict } from '../oak-app-domain';
|
||||
import { getSms } from './sms/index';
|
||||
import { BRC } from '../types/RuntimeCxt';
|
||||
|
||||
export async function sendSms<ED extends EntityDict>(
|
||||
options: {
|
||||
messageType?: string;
|
||||
origin?: 'ali' | 'tencent';
|
||||
templateName?: string;
|
||||
mobile: string;
|
||||
templateParam?: Record<string, string> | string[];
|
||||
},
|
||||
context: BRC<ED>
|
||||
) {
|
||||
const {
|
||||
messageType,
|
||||
origin,
|
||||
templateName,
|
||||
mobile,
|
||||
templateParam,
|
||||
} = options;
|
||||
assert(messageType || (origin && templateName));
|
||||
if (origin && templateName) {
|
||||
const [smsTemplate] = await context.select(
|
||||
'smsTemplate', {
|
||||
data: {
|
||||
id: 1,
|
||||
origin: 1,
|
||||
systemId: 1,
|
||||
templateCode: 1,
|
||||
},
|
||||
filter: {
|
||||
origin,
|
||||
templateName
|
||||
}
|
||||
},
|
||||
{}
|
||||
);
|
||||
if (!smsTemplate) {
|
||||
return {
|
||||
success: false,
|
||||
res: `${origin}渠道的${templateName}短信模板未配置`
|
||||
}
|
||||
}
|
||||
try {
|
||||
const instance = getSms<ED>(origin!);
|
||||
const result = await instance.sendSms({
|
||||
mobile,
|
||||
templateParam,
|
||||
smsTemplate,
|
||||
}, context);
|
||||
return result;
|
||||
} catch (err) {
|
||||
return {
|
||||
success: false,
|
||||
res: err,
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
const systemId = context.getSystemId();
|
||||
const messageTypeSmsTemplateList = await context.select(
|
||||
'messageTypeSmsTemplate', {
|
||||
data: {
|
||||
id: 1,
|
||||
type: 1,
|
||||
templateId: 1,
|
||||
template: {
|
||||
id: 1,
|
||||
origin: 1,
|
||||
systemId: 1,
|
||||
templateCode: 1,
|
||||
}
|
||||
},
|
||||
filter: {
|
||||
template: {
|
||||
systemId,
|
||||
},
|
||||
type: messageType,
|
||||
}
|
||||
},
|
||||
{}
|
||||
);
|
||||
// todo 多渠道短信的负载均衡,目前按照顺序发
|
||||
let resList = {} as Record<string, any>;
|
||||
if (messageTypeSmsTemplateList.length > 0) {
|
||||
for (const messageTypeSmsTemplate of messageTypeSmsTemplateList) {
|
||||
try {
|
||||
const instance = getSms<ED>(messageTypeSmsTemplate.template!.origin!);
|
||||
const result = await instance.sendSms({
|
||||
mobile,
|
||||
templateParam,
|
||||
smsTemplate: messageTypeSmsTemplate.template!,
|
||||
}, context);
|
||||
Object.assign(resList, {
|
||||
[messageTypeSmsTemplate.template!.origin!]: result.res,
|
||||
})
|
||||
if (result.success) {
|
||||
return {
|
||||
success: true,
|
||||
res: resList,
|
||||
};
|
||||
}
|
||||
} catch (err) {
|
||||
Object.assign(resList, {
|
||||
[messageTypeSmsTemplate.template!.origin!]: err,
|
||||
});
|
||||
}
|
||||
}
|
||||
return {
|
||||
success: false,
|
||||
res: {
|
||||
message: '所有短信渠道均发送失败',
|
||||
errorList: resList,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
success: false,
|
||||
res: `短信未配置${messageType}模板`
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// const application = context.getApplication();
|
||||
|
||||
// const { system } = application!;
|
||||
// const { platform, config: systemConfig } = system!;
|
||||
// const { config: platformConfig } = platform || {};
|
||||
// const accountConfigs =
|
||||
// systemConfig?.Account?.[origin] || platformConfig?.Account?.[origin];
|
||||
// const smsConfigs =
|
||||
// systemConfig?.Sms?.[origin] || platformConfig?.Sms?.[origin];
|
||||
// if (
|
||||
// !accountConfigs ||
|
||||
// accountConfigs.length === 0 ||
|
||||
// !smsConfigs ||
|
||||
// smsConfigs.length === 0
|
||||
// ) {
|
||||
// assert(false, `${origin}短信未配置`);
|
||||
// }
|
||||
// if (origin === 'tencent') {
|
||||
// for (const smsConfig of smsConfigs) {
|
||||
// const smsConfig = smsConfigs[0] as TencentSmsConfig;
|
||||
// const accountConfig = accountConfigs[0] as TencentCloudConfig;
|
||||
|
||||
// // const accountConfig = (accountConfigs as TencentCloudConfig[]).find(
|
||||
// // ele => ele.secretId === smsConfig.secretId
|
||||
// // )!;
|
||||
|
||||
// const template = smsConfig.templates?.[templateName];
|
||||
// const SmsSdkInstance = SmsSdk.getInstance(
|
||||
// origin,
|
||||
// accountConfig.secretId,
|
||||
// accountConfig.secretKey,
|
||||
// accountConfig.region,
|
||||
// accountConfig.endpoint
|
||||
// ) as TencentSmsInstance;
|
||||
// const data = await SmsSdkInstance.sendSms({
|
||||
// PhoneNumberSet: [mobile],
|
||||
// SmsSdkAppId: smsConfig.smsSdkAppId,
|
||||
// SignName: template.signName || smsConfig.defaultSignName,
|
||||
// TemplateId: template.code,
|
||||
// TemplateParamSet: templateParamSet as string[],
|
||||
// });
|
||||
// const sendStatus = data.SendStatusSet![0];
|
||||
// if (sendStatus.Code === 'Ok') {
|
||||
// return true;
|
||||
// }
|
||||
// console.warn(`通过微信云发送sms失败,电话是${mobile},模板Id是${template.code}`, sendStatus);
|
||||
// }
|
||||
// } else {
|
||||
// throw new Error('未实现');
|
||||
// }
|
||||
}
|
||||
|
|
@ -1,20 +1,9 @@
|
|||
import { assert } from 'oak-domain/lib/utils/assert';
|
||||
import { EntityDict } from '../../oak-app-domain';
|
||||
|
||||
import { BRC } from '../../types/RuntimeCxt';
|
||||
import Sms from '../../types/Sms';
|
||||
|
||||
import Ali from './ali';
|
||||
import Tencent from './tencent';
|
||||
import CTYun from './ctyun';
|
||||
|
||||
const ali = new Ali();
|
||||
const tencent = new Tencent();
|
||||
const ctyun = new CTYun();
|
||||
|
||||
const SmsDict: Record<string, any> = {
|
||||
[ali.name]: ali,
|
||||
[tencent.name]: tencent,
|
||||
[ctyun.name]: ctyun,
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -34,4 +23,126 @@ export function getSms<ED extends EntityDict>(origin: string) {
|
|||
|
||||
export function getOrigin() {
|
||||
return Object.keys(SmsDict);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export async function sendSms<ED extends EntityDict>(
|
||||
options: {
|
||||
messageType?: string;
|
||||
origin?: 'ali' | 'tencent';
|
||||
templateName?: string;
|
||||
mobile: string;
|
||||
templateParam?: Record<string, string> | string[];
|
||||
},
|
||||
context: BRC<ED>
|
||||
) {
|
||||
const {
|
||||
messageType,
|
||||
origin,
|
||||
templateName,
|
||||
mobile,
|
||||
templateParam,
|
||||
} = options;
|
||||
assert(messageType || (origin && templateName));
|
||||
if (origin && templateName) {
|
||||
const [smsTemplate] = await context.select(
|
||||
'smsTemplate', {
|
||||
data: {
|
||||
id: 1,
|
||||
origin: 1,
|
||||
systemId: 1,
|
||||
templateCode: 1,
|
||||
},
|
||||
filter: {
|
||||
origin,
|
||||
templateName
|
||||
}
|
||||
},
|
||||
{}
|
||||
);
|
||||
if (!smsTemplate) {
|
||||
return {
|
||||
success: false,
|
||||
res: `${origin}渠道的${templateName}短信模板未配置`
|
||||
}
|
||||
}
|
||||
try {
|
||||
const instance = getSms<ED>(origin!);
|
||||
const result = await instance.sendSms({
|
||||
mobile,
|
||||
templateParam,
|
||||
smsTemplate,
|
||||
}, context);
|
||||
return result;
|
||||
} catch (err) {
|
||||
return {
|
||||
success: false,
|
||||
res: err,
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
const systemId = context.getSystemId();
|
||||
const messageTypeSmsTemplateList = await context.select(
|
||||
'messageTypeSmsTemplate', {
|
||||
data: {
|
||||
id: 1,
|
||||
type: 1,
|
||||
templateId: 1,
|
||||
template: {
|
||||
id: 1,
|
||||
origin: 1,
|
||||
systemId: 1,
|
||||
templateCode: 1,
|
||||
}
|
||||
},
|
||||
filter: {
|
||||
template: {
|
||||
systemId,
|
||||
},
|
||||
type: messageType,
|
||||
}
|
||||
},
|
||||
{}
|
||||
);
|
||||
// todo 多渠道短信的负载均衡,目前按照顺序发
|
||||
let resList = {} as Record<string, any>;
|
||||
if (messageTypeSmsTemplateList.length > 0) {
|
||||
for (const messageTypeSmsTemplate of messageTypeSmsTemplateList) {
|
||||
try {
|
||||
const instance = getSms<ED>(messageTypeSmsTemplate.template!.origin!);
|
||||
const result = await instance.sendSms({
|
||||
mobile,
|
||||
templateParam,
|
||||
smsTemplate: messageTypeSmsTemplate.template!,
|
||||
}, context);
|
||||
Object.assign(resList, {
|
||||
[messageTypeSmsTemplate.template!.origin!]: result.res,
|
||||
})
|
||||
if (result.success) {
|
||||
return {
|
||||
success: true,
|
||||
res: resList,
|
||||
};
|
||||
}
|
||||
} catch (err) {
|
||||
Object.assign(resList, {
|
||||
[messageTypeSmsTemplate.template!.origin!]: err,
|
||||
});
|
||||
}
|
||||
}
|
||||
return {
|
||||
success: false,
|
||||
res: {
|
||||
message: '所有短信渠道均发送失败',
|
||||
errorList: resList,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
success: false,
|
||||
res: `短信未配置${messageType}模板`
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
|
||||
import { CreateOperationData as Application } from '@project/oak-app-domain/Application/Schema';
|
||||
import { CreateOperationData as System } from '@project/oak-app-domain/System/Schema';
|
||||
import { CreateOperationData as Domain } from '@project/oak-app-domain/Domain/Schema';
|
||||
|
||||
export const DEV_WECHATMP_APPLICATION_ID = 'MY_DEV_WECHATMP_APPLICATION_ID';
|
||||
export const DEV_WEB_APPLICATION_ID = 'MY_DEV_WEB_APPLICATION_ID';
|
||||
export const DEV_PUBLIC_APPLICATION_ID = 'MY_DEV_PUBLIC_APPLICATION_ID';
|
||||
export const DEV_WECHATPUPLIC_APPLICATION_ID = 'MY_DEV_WECHATPUPLIC_APPLICATION_ID';
|
||||
export const DEV_DOMAIN_ID = 'MY_DEV_DOMAIN_ID';
|
||||
export const DEV_SYSTEM_ID = 'MY_DEV_SYSTEM_ID';
|
||||
|
||||
const SUPER_SYSTEM_ID = 'SUPER_SYSTEM_ID';
|
||||
const SUPER_WEB_APPLICATION_ID = 'SUPER_WEB_APPLICATION_ID';
|
||||
const SUPER_DOMAIN_ID = 'SUPER_DOMAIN_ID';
|
||||
|
||||
/**
|
||||
* 配置系统相关的初始化数据
|
||||
*/
|
||||
export const application: Application[] = [
|
||||
{
|
||||
id: DEV_WECHATMP_APPLICATION_ID,
|
||||
name: 'wechatMp',
|
||||
type: 'wechatMp',
|
||||
systemId: DEV_SYSTEM_ID,
|
||||
config: {
|
||||
type: 'wechatMp',
|
||||
appId: '',
|
||||
appSecret: '',
|
||||
},
|
||||
description: '小程序应用,指向dev_system',
|
||||
},
|
||||
{
|
||||
id: DEV_WEB_APPLICATION_ID,
|
||||
name: '测试web',
|
||||
type: 'web',
|
||||
systemId: DEV_SYSTEM_ID,
|
||||
config: {
|
||||
type: 'web',
|
||||
passport: ['email', 'mobile', 'wechat'],
|
||||
},
|
||||
description: 'web应用,指向dev_system',
|
||||
},
|
||||
{
|
||||
id: DEV_PUBLIC_APPLICATION_ID,
|
||||
name: '测试public',
|
||||
type: 'wechatPublic',
|
||||
systemId: DEV_SYSTEM_ID,
|
||||
config: {
|
||||
type: 'wechatPublic',
|
||||
isService: true,
|
||||
appId: '',
|
||||
appSecret: '',
|
||||
},
|
||||
description: 'public应用,指向dev_system',
|
||||
},
|
||||
{
|
||||
/** *
|
||||
* 线上第一个web应用,请根据应用情况配置
|
||||
* */
|
||||
id: SUPER_WEB_APPLICATION_ID,
|
||||
name: '线上',
|
||||
type: 'web',
|
||||
systemId: SUPER_SYSTEM_ID,
|
||||
config: {
|
||||
type: 'web',
|
||||
passport: ['mobile', 'wechat'],
|
||||
},
|
||||
description: '线上网站',
|
||||
},
|
||||
];
|
||||
|
||||
export const system: System[] = [
|
||||
{
|
||||
// 测试用系统,可将自己申请相应的服务帐号填在这里,用于开发过程
|
||||
id: DEV_SYSTEM_ID,
|
||||
name: '测试系统',
|
||||
description: '测试系统',
|
||||
config: {
|
||||
Map: {
|
||||
amap: {
|
||||
webApiKey: '',
|
||||
},
|
||||
},
|
||||
Cos: {
|
||||
qiniu: {
|
||||
accessKey: '',
|
||||
buckets: [
|
||||
{
|
||||
zone: 'z0',
|
||||
name: '',
|
||||
domain: '',
|
||||
protocol: 'http',
|
||||
},
|
||||
],
|
||||
defaultBucket: '',
|
||||
},
|
||||
},
|
||||
Live: {
|
||||
qiniu: {
|
||||
accessKey: '',
|
||||
liveHost: '', // 七牛直播云接口
|
||||
publishDomain: '', // rtmp
|
||||
playDomain: '', // rtmp
|
||||
hub: '',
|
||||
publishKey: '',
|
||||
playKey: '',
|
||||
playBackDomain: '',
|
||||
},
|
||||
},
|
||||
Account: {
|
||||
qiniu: [
|
||||
{
|
||||
accessKey: '',
|
||||
secretKey: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
App: {},
|
||||
},
|
||||
super: true,
|
||||
folder: 'test',
|
||||
style: {
|
||||
color: {
|
||||
primary: 'red',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
/**
|
||||
* 线上真实系统,请勿将敏感帐号填在这里,上线后在系统中配置
|
||||
* */
|
||||
id: SUPER_SYSTEM_ID,
|
||||
name: '线上系统',
|
||||
description: '线上系统',
|
||||
config: {
|
||||
App: {},
|
||||
},
|
||||
super: true,
|
||||
folder: 'test',
|
||||
style: {
|
||||
color: {
|
||||
primary: 'red',
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export const domain: Domain[] = [
|
||||
{
|
||||
id: DEV_DOMAIN_ID,
|
||||
protocol: 'http',
|
||||
url: 'localhost',
|
||||
port: 3001,
|
||||
systemId: DEV_SYSTEM_ID,
|
||||
},
|
||||
{
|
||||
/**
|
||||
* 线上真实域名,此信息必须在应用启动前初始化,否则系统无法访问
|
||||
* */
|
||||
id: SUPER_DOMAIN_ID,
|
||||
protocol: 'https',
|
||||
url: 'test.com',
|
||||
port: 443,
|
||||
apiPath: '/rest/aspect',
|
||||
systemId: SUPER_SYSTEM_ID,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
|
||||
export default {
|
||||
application,
|
||||
system,
|
||||
domain,
|
||||
};
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
import {
|
||||
String,
|
||||
Text,
|
||||
Price
|
||||
} from 'oak-domain/lib/types/DataType';
|
||||
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
||||
import { Schema as System } from 'oak-general-business/lib/entities/System';
|
||||
import { Schema as ArticleMenu } from 'oak-general-business/lib/entities/ArticleMenu';
|
||||
import { EntityDesc } from 'oak-domain/lib/types';
|
||||
|
||||
export interface Schema extends EntityShape {
|
||||
name: String<32>;
|
||||
system: System;
|
||||
systems?: System[];
|
||||
articleMenus?: ArticleMenu[];
|
||||
};
|
||||
|
||||
export type Relation = 'owner' | 'manager';
|
||||
|
||||
const entityDesc: EntityDesc<Schema, '', Relation> = {
|
||||
locales: {
|
||||
zh_CN: {
|
||||
name: '系统供应商',
|
||||
attr: {
|
||||
name: '名称',
|
||||
system: '系统',
|
||||
systems: '系统',
|
||||
articleMenus: '文章分类',
|
||||
},
|
||||
r: {
|
||||
owner: '所有者',
|
||||
manager: '管理员',
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
export default OakComponent({
|
||||
entity: 'systemProvider',
|
||||
projection: {
|
||||
id: 1,
|
||||
name: 1,
|
||||
systemId: 1,
|
||||
},
|
||||
isList: true,
|
||||
formData({ data, legalActions }) {
|
||||
return {
|
||||
rows: data,
|
||||
allowCreate: legalActions?.includes('create'),
|
||||
};
|
||||
},
|
||||
actions: ['update', 'create'],
|
||||
});
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"pageTitle": "系统供应商管理",
|
||||
"setting": "系统配置"
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
.container {
|
||||
background-color: var(--oak-bg-color-container);
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
import React, { useRef, useState } from 'react';
|
||||
import { RowWithActions, WebComponentProps } from 'oak-frontend-base';
|
||||
import { EntityDict } from '@project/oak-app-domain';
|
||||
import List from 'oak-frontend-base/es/components/listPro';
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import Styles from './web.pc.module.less';
|
||||
import PageHeader from 'oak-frontend-base/es/components/pageHeader2';
|
||||
|
||||
export default function Render(props: WebComponentProps<EntityDict, 'systemProvider', true, {
|
||||
rows?: RowWithActions<EntityDict, 'systemProvider'>[];
|
||||
allowCreate?: boolean;
|
||||
}>) {
|
||||
const { rows, oakFullpath, oakLoading, allowCreate } = props.data;
|
||||
const { t, navigateTo } = props.methods;
|
||||
|
||||
if (oakFullpath) {
|
||||
return (
|
||||
<PageHeader
|
||||
title={t('pageTitle')}
|
||||
>
|
||||
<List
|
||||
buttonGroup={allowCreate ? [
|
||||
{
|
||||
label: t('common::action.create'),
|
||||
icon: <PlusOutlined />,
|
||||
onClick: () => {
|
||||
navigateTo({
|
||||
url: '/systemProvider/upsert',
|
||||
})
|
||||
}
|
||||
}
|
||||
] : []}
|
||||
loading={oakLoading}
|
||||
entity="systemProvider"
|
||||
data={rows || []}
|
||||
attributes={
|
||||
['name']
|
||||
}
|
||||
extraActions={
|
||||
[
|
||||
// { action: 'update', label: t('common::action.update'), show: true },
|
||||
{ action: 'setting', label: t('setting'), show: true }
|
||||
]
|
||||
}
|
||||
onAction={(row, action) => {
|
||||
if (action === 'update') {
|
||||
navigateTo({
|
||||
url: '/systemProvider/upsert',
|
||||
oakId: row.id,
|
||||
});
|
||||
}
|
||||
else if (action === 'setting') {
|
||||
navigateTo({
|
||||
url: '/systemProvider/system',
|
||||
oakId: row.id,
|
||||
});
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</PageHeader>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
export default OakComponent({
|
||||
entity: 'systemProvider',
|
||||
isList: false,
|
||||
projection: {
|
||||
id: 1,
|
||||
systemId: 1,
|
||||
name: 1,
|
||||
},
|
||||
formData({ data }) {
|
||||
return data || {};
|
||||
},
|
||||
});
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"pageTitle": "系统供应商配置"
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
.container {
|
||||
background-color: var(--oak-bg-color-container);
|
||||
padding: 8px;
|
||||
height: 100%;
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
import React from 'react';
|
||||
import { Tabs } from 'antd';
|
||||
import { EntityDict } from "@project/oak-app-domain";
|
||||
import { WebComponentProps } from "oak-frontend-base";
|
||||
import SystemPanel from 'oak-general-business/es/components/system/panel';
|
||||
import Styles from './web.pc.module.less';
|
||||
|
||||
export default function Render(props: WebComponentProps<
|
||||
EntityDict,
|
||||
'system',
|
||||
false, {
|
||||
systemId: string;
|
||||
name: string;
|
||||
}>) {
|
||||
const { oakId, oakFullpath, systemId, name } = props.data;
|
||||
if (oakFullpath && name) {
|
||||
return (
|
||||
<div
|
||||
className={Styles.container}
|
||||
>
|
||||
<Tabs
|
||||
type='card'
|
||||
items={[
|
||||
{
|
||||
key: name,
|
||||
label: name,
|
||||
children: (
|
||||
<SystemPanel
|
||||
oakId={systemId}
|
||||
oakPath={`${oakFullpath}.system`}
|
||||
/>
|
||||
)
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
export default OakComponent({
|
||||
entity: 'systemProvider',
|
||||
isList: false,
|
||||
projection: {
|
||||
id: 1,
|
||||
name: 1,
|
||||
},
|
||||
formData({ data }) {
|
||||
return {
|
||||
row: data,
|
||||
};
|
||||
}
|
||||
})
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"pageTitle": "系统供应商更新",
|
||||
"setting": "配置"
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
.container {
|
||||
background-color: var(--oak-bg-color-container);
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.prefix {
|
||||
color: #888;
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
import React, { useRef, useState, useEffect } from 'react';
|
||||
import { RowWithActions, WebComponentProps } from 'oak-frontend-base';
|
||||
import { EntityDict } from '@project/oak-app-domain';
|
||||
import Upsert from 'oak-frontend-base/es/components/upsert';
|
||||
import { Button, Tabs, Form, Input, InputNumber, Row, Col, } from 'antd';
|
||||
import Styles from './web.pc.module.less';
|
||||
import type { TabsProps } from 'antd';
|
||||
|
||||
export default function Render(props: WebComponentProps<EntityDict, 'systemProvider', false, {
|
||||
row: EntityDict['systemProvider']['Schema'];
|
||||
}>) {
|
||||
const { row, oakFullpath, oakLoading, oakExecutable } = props.data;
|
||||
const { t, execute, navigateBack, update } = props.methods;
|
||||
const { name } = row || {};
|
||||
|
||||
return <>尚未实现</>;
|
||||
}
|
||||
Loading…
Reference in New Issue