subscription

This commit is contained in:
wenjiarui 2022-12-20 17:21:17 +08:00
parent b7ee7ee4d6
commit a3a53c7535
5 changed files with 220 additions and 60 deletions

View File

@ -17,6 +17,7 @@ export interface Schema extends EntityShape {
author: String<32>; //作者 author: String<32>; //作者
abstract?: Text; //摘要 abstract?: Text; //摘要
content?: Text; //正文 content?: Text; //正文
url?: Text; // 外部连接
files: Array<ExtraFile>; //封面图 files: Array<ExtraFile>; //封面图
sign: String<32>; //唯一标志 sign: String<32>; //唯一标志
} }
@ -51,6 +52,7 @@ const locale: LocaleDef<
content: '正文', content: '正文',
files: '封面图', files: '封面图',
iState: '状态', iState: '状态',
url: '外部链接',
entity: '关联对象', entity: '关联对象',
entityId: '关联对象id', entityId: '关联对象id',
sign: '唯一标志', sign: '唯一标志',

View File

@ -5,7 +5,7 @@ import { LocaleDef } from 'oak-domain/lib/types/Locale';
import { Index, ActionDef } from 'oak-domain/lib/types'; import { Index, ActionDef } from 'oak-domain/lib/types';
export interface Schema extends EntityShape { export interface Schema extends EntityShape {
channel: 'public' | 'jPush' | 'jim' | 'mp' | 'gsm', channel: 'wechat' | 'jPush' | 'jim' | 'mp' | 'sms',
data: Object, data: Object,
message: Message, message: Message,
data1: Object, data1: Object,
@ -49,11 +49,11 @@ const locale: LocaleDef<Schema, Action, '', {
failure: '发送失败', failure: '发送失败',
}, },
channel: { channel: {
public: '公众号', wechat: '公众号',
jPush: '极光推送', jPush: '极光推送',
jim: '极光消息', jim: '极光消息',
mp: '小程序', mp: '小程序',
gsm: '短信', sms: '短信',
} }
} }
}, },

View File

@ -0,0 +1,65 @@
import {
String,
Boolean,
Text,
} from 'oak-domain/lib/types/DataType';
import { ActionDef } from 'oak-domain/lib/types/Action';
import { EntityShape } from 'oak-domain/lib/types/Entity';
import { LocaleDef } from 'oak-domain/lib/types/Locale';
import { Index } from 'oak-domain/lib/types/Storage';
export type WechatPublicConfig = {
type: 'wechatPublic';
appId: string;
appSecret: string;
};
export interface Schema extends EntityShape {
entity: String<32>;
entityId: String<64>;
name: String<32>;
description: Text;
config: WechatPublicConfig;
};
const indexes: Index<Schema>[] = [
//索引
{
name: 'index_name',
attributes: [
{
name: 'name',
},
],
},
{
name: 'index_entity',
attributes: [
{
name: 'entity',
},
{
name: 'entityId',
}
],
},
];
const locale: LocaleDef<
Schema,
'',
'',
{
}
> = {
zh_CN: {
attr: {
name: '名称',
entity: '对象名称',
entityId: '对象Id',
description: '描述',
config: '配置',
},
},
};

View File

@ -1,4 +1,4 @@
import { generateNewId } from 'oak-domain/lib/utils/uuid'; import { generateNewId, generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
import { Trigger, CreateTrigger, UpdateTrigger } from 'oak-domain/lib/types/Trigger'; import { Trigger, CreateTrigger, UpdateTrigger } from 'oak-domain/lib/types/Trigger';
import { EntityDict } from '../general-app-domain/EntityDict'; import { EntityDict } from '../general-app-domain/EntityDict';
import { CreateOperationData as CreateMessageData } from '../general-app-domain/Message/Schema'; import { CreateOperationData as CreateMessageData } from '../general-app-domain/Message/Schema';
@ -6,8 +6,9 @@ import { assert } from 'oak-domain/lib/utils/assert';
import { RuntimeCxt } from '../types/RuntimeCxt'; import { RuntimeCxt } from '../types/RuntimeCxt';
import { BackendRuntimeContext } from '../context/BackendRuntimeContext'; import { BackendRuntimeContext } from '../context/BackendRuntimeContext';
import { Schema as MessageSentSchema } from '../entities/MessageSent'; import { Schema as MessageSentSchema } from '../entities/MessageSent';
import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
import { MessagePropsToSms, MessagePropsToWechat } from '../types/Message'; import { MessagePropsToSms, MessagePropsToWechat } from '../types/Message';
import { WechatMpConfig, WechatPublicConfig, WebConfig } from '../general-app-domain/Application/Schema';
import { initialState } from '@uiw/react-amap';
let SmsCoverter: MessagePropsToSms | undefined; let SmsCoverter: MessagePropsToSms | undefined;
let WechatConverter: MessagePropsToWechat | undefined; let WechatConverter: MessagePropsToWechat | undefined;
@ -22,94 +23,107 @@ export function registerMessagePropsConverter(converter: {
} }
async function tryAddMessageSent(message: CreateMessageData, channel: MessageSentSchema['channel'], context: BackendRuntimeContext<EntityDict>) { async function tryAddMessageSent(message: CreateMessageData, channel: string, context: BackendRuntimeContext<EntityDict>) {
// const { systemId, type } = message; if (!WechatConverter) {
// const disperse = MessageDisperse && MessageDisperse[systemId] && MessageDisperse[systemId][type] && MessageDisperse[systemId][type][channel]; return 0;
// if (!disperse) { }
// return 0; const { systemId, props, type } = message;
// } const [application] = await context.select(
'application',
// // 有配置也未必一定能发比如说用户没有注册手机号则无法发gsm {
// const data = disperse(message); data: {
// if (!data) { id: 1,
// return 0; name: 1,
// } config: 1,
type: 1,
// const messageSent = { systemId: 1,
// messageId: message.id, style: 1,
// iState: 'sending', },
// channel, filter: {
// }; type: 'wechatPublic',
// await context.operate('messageSent', { systemId,
// id: await generateNewIdAsync(), },
// action: 'create', },
// data: { {}
// id: await generateNewId(), );
// ...messageSent, const config2 = application.config as WechatPublicConfig;
// } as EntityDict['messageSent']['OpSchema'], const appId = config2.appId;
// }, {}); let dispersedData;
switch (channel) {
case 'weChat': {
dispersedData = WechatConverter(type, props, appId);
break;
}
default: {
break;
}
}
if (!dispersedData) {
return 0;
}
await context.operate('messageSent', {
id: await generateNewIdAsync(),
action: 'create',
data: {
messageId: message.id,
data: dispersedData,
channel,
},
}, {});
return 1; return 1;
} }
async function addMessageSent(message: CreateMessageData, context: BackendRuntimeContext<EntityDict>) { export async function addMessageSent(message: CreateMessageData, context: BackendRuntimeContext<EntityDict>) {
const { weight } = message; const { weight } = message;
switch (weight) { switch (weight) {
case 'high': { case 'high': {
// 高权重的,所有渠道一起推 // 高权重的,所有渠道一起推
const result = await Promise.all([ const result = await Promise.all([
tryAddMessageSent(message, 'public', context), tryAddMessageSent(message, 'wechat', context),
tryAddMessageSent(message, 'jPush', context), tryAddMessageSent(message, 'sms', context),
tryAddMessageSent(message, 'jim', context),
tryAddMessageSent(message, 'mp', context),
tryAddMessageSent(message, 'gsm', context),
]); ]);
return result.reduce((a, b) => a || b); return result.reduce((a, b) => a || b);
} }
case 'medium': { case 'medium': {
// 中权重的,先推三次免费渠道,失败了再推收费渠道 // 中权重的,先推免费渠道,失败了再推收费渠道
const count = await context.count( const count = await context.count(
'messageSent', 'messageSent',
{ {
filter: { filter: {
messageId: message.id, messageId: message.id,
} },
}, },
{}, {},
); );
if (count < 1) { if (count < 1) {
const result = await Promise.all([ const result = await Promise.all([
tryAddMessageSent(message, 'public', context), tryAddMessageSent(message, 'wechat', context),
tryAddMessageSent(message, 'jPush', context),
tryAddMessageSent(message, 'jim', context),
tryAddMessageSent(message, 'mp', context),
]); ]);
const count2 = result.reduce((a, b) => a || b); const count2 = result.reduce((a, b) => a || b);
if (count2 === 0) { if (count2 > 0) {
return await tryAddMessageSent(message, 'gsm', context); return count2;
} }
return count2; return await tryAddMessageSent(message, 'sms', context);
} }
return await tryAddMessageSent(message, 'gsm', context); return await tryAddMessageSent(message, 'sms', context);
} }
case 'low': { case 'low': {
// 低权重的,只推免费渠道 // 低权重的,只推免费渠道
const result = await Promise.all([ const result = await Promise.all([
tryAddMessageSent(message, 'public', context), tryAddMessageSent(message, 'wechat', context),
tryAddMessageSent(message, 'jPush', context),
tryAddMessageSent(message, 'jim', context),
tryAddMessageSent(message, 'mp', context),
]);
return result.reduce((a, b) => a || b);
}
case 'data': {
// 透传数据的只推JPush
const result = await Promise.all([
tryAddMessageSent(message, 'jPush', context),
tryAddMessageSent(message, 'jim', context),
]); ]);
return result.reduce((a, b) => a || b); return result.reduce((a, b) => a || b);
} }
// case 'data': {
// // 透传数据的只推JPush
// const result = await Promise.all([
// tryAddMessageSent(message, 'jPush', context),
// tryAddMessageSent(message, 'jim', context),
// ]);
// return result.reduce((a, b) => a || b);
// }
default: { default: {
assert(false); assert(false);
} }
@ -126,7 +140,14 @@ const triggers: Trigger<EntityDict, 'message', RuntimeCxt>[] = [
fn: async ({ operation }, context, params) => { fn: async ({ operation }, context, params) => {
const { data, filter } = operation; const { data, filter } = operation;
const fn = async (messageData: CreateMessageData) => { const fn = async (messageData: CreateMessageData) => {
await addMessageSent(messageData, context as BackendRuntimeContext<EntityDict>); const result = await addMessageSent(messageData, context as BackendRuntimeContext<EntityDict>);
if (result === 0) {
Object.assign(
messageData, {
iState: 'fail',
}
)
}
} }
if (data instanceof Array) { if (data instanceof Array) {
assert('不存在一对多的情况') assert('不存在一对多的情况')

View File

@ -0,0 +1,72 @@
import { Trigger, CreateTrigger, UpdateTrigger } from 'oak-domain/lib/types/Trigger';
import { EntityDict } from '../general-app-domain/EntityDict';
import { CreateOperationData as CreateMessageSentData } from '../general-app-domain/MessageSent/Schema';
import { assert } from 'oak-domain/lib/utils/assert';
import { RuntimeCxt } from '../types/RuntimeCxt';
import { addMessageSent } from './message';
import { BackendRuntimeContext } from '../context/BackendRuntimeContext';
import { WechatMpConfig, WechatPublicConfig, WebConfig } from '../general-app-domain/Application/Schema';
import { WechatSDK } from 'oak-external-sdk';
async function sendMessage(messageSentData: CreateMessageSentData, context: BackendRuntimeContext<EntityDict>) {
const { data, channel, messageId } = messageSentData;
const [message] = await context.select(
'message',
{
data: {
id: 1,
systemId: 1,
},
filter: {
id: messageId,
},
},
{}
);
const [application] = await context.select(
'application',
{
data: {
id: 1,
name: 1,
config: 1,
type: 1,
systemId: 1,
style: 1,
},
filter: {
type: 'wechatPublic',
systemId: message.systemId,
},
},
{}
);
const config2 = application.config as WechatPublicConfig;
const appId = config2.appId;
}
const triggers: Trigger<EntityDict, 'messageSent', RuntimeCxt>[] = [
{
name: '当创建messageSent后业务提交后再进行推送',
entity: 'messageSent',
action: 'create',
when: 'commit',
strict: 'makeSure',
fn: async ({ operation }, context, params) => {
const { data, filter } = operation;
const fn = async (messageSentData: CreateMessageSentData) => {
await sendMessage(messageSentData, context as BackendRuntimeContext<EntityDict>);
}
if (data instanceof Array) {
assert('不存在一对多的情况')
}
else {
await fn(data);
}
return 0;
}
} as CreateTrigger<EntityDict, 'messageSent', RuntimeCxt>,
];
export default triggers;