feat(openapi): 增加开放平台机器人回调编辑

pull/70/head
moonrailgun 2 years ago
parent 56c9f99c67
commit 3382189dee

@ -1,48 +1,43 @@
import React from 'react'; import React from 'react';
import { FullModalField, Switch } from '@capital/component'; import {
DefaultFullModalInputEditorRender,
FullModalField,
Switch,
} from '@capital/component';
import { useOpenAppInfo } from '../context'; import { useOpenAppInfo } from '../context';
import { OpenAppCapability } from '../types'; import { Translate } from '../../translate';
import { postRequest, useAsyncFn } from '@capital/common'; import { useOpenAppAction } from './useOpenAppAction';
const Bot: React.FC = React.memo(() => { const Bot: React.FC = React.memo(() => {
const { refresh, appId, capability } = useOpenAppInfo(); const { capability, bot } = useOpenAppInfo();
const { loading, handleChangeAppCapability, handleUpdateBotInfo } =
const [{ loading }, handleChangeBotCapability] = useAsyncFn( useOpenAppAction();
async (checked: boolean) => {
const newCapability: OpenAppCapability[] = [...capability];
const findIndex = newCapability.findIndex((c) => c === 'bot');
if (checked) {
if (findIndex === -1) {
newCapability.push('bot');
}
} else {
if (findIndex !== -1) {
newCapability.splice(findIndex, 1);
}
}
await postRequest('/openapi/app/setAppCapability', {
appId,
capability: newCapability,
});
await refresh();
},
[appId, capability, refresh]
);
return ( return (
<div className="plugin-openapi-app-info_bot"> <div className="plugin-openapi-app-info_bot">
<FullModalField <FullModalField
title="开启机器人能力" title={Translate.enableBotCapability}
content={ content={
<Switch <Switch
disabled={loading} disabled={loading}
checked={capability.includes('bot')} checked={capability.includes('bot')}
onChange={handleChangeBotCapability} onChange={(checked) => handleChangeAppCapability('bot', checked)}
/> />
} }
/> />
{capability.includes('bot') && (
<FullModalField
title={Translate.bot.callback}
tip={Translate.bot.callbackTip}
value={bot?.callbackUrl}
editable={true}
renderEditor={DefaultFullModalInputEditorRender}
onSave={(str: string) =>
handleUpdateBotInfo('callbackUrl', String(str))
}
/>
)}
</div> </div>
); );
}); });

@ -5,44 +5,12 @@ import {
Switch, Switch,
} from '@capital/component'; } from '@capital/component';
import { useOpenAppInfo } from '../context'; import { useOpenAppInfo } from '../context';
import { OpenAppCapability } from '../types'; import { useOpenAppAction } from './useOpenAppAction';
import { postRequest, useAsyncFn, useAsyncRequest } from '@capital/common';
const OAuth: React.FC = React.memo(() => { const OAuth: React.FC = React.memo(() => {
const { refresh, appId, capability, oauth } = useOpenAppInfo(); const { capability, oauth } = useOpenAppInfo();
const { loading, handleChangeAppCapability, handleUpdateOAuthInfo } =
const [{ loading }, handleChangeOAuthCapability] = useAsyncRequest( useOpenAppAction();
async (checked: boolean) => {
const newCapability: OpenAppCapability[] = [...capability];
const findIndex = newCapability.findIndex((c) => c === 'oauth');
const isExist = findIndex !== -1;
if (checked && !isExist) {
newCapability.push('oauth');
} else if (!checked && isExist) {
newCapability.splice(findIndex, 1);
}
await postRequest('/openapi/app/setAppCapability', {
appId,
capability: newCapability,
});
await refresh();
},
[appId, capability, refresh]
);
const [, handleUpdateOAuthInfo] = useAsyncFn(
async (name: string, value: any) => {
await postRequest('/openapi/app/setAppOAuthInfo', {
appId,
fieldName: name,
fieldValue: value,
});
await refresh();
},
[]
);
return ( return (
<div className="plugin-openapi-app-info_oauth"> <div className="plugin-openapi-app-info_oauth">
@ -52,7 +20,7 @@ const OAuth: React.FC = React.memo(() => {
<Switch <Switch
disabled={loading} disabled={loading}
checked={capability.includes('oauth')} checked={capability.includes('oauth')}
onChange={handleChangeOAuthCapability} onChange={(checked) => handleChangeAppCapability('oauth', checked)}
/> />
} }
/> />

@ -0,0 +1,65 @@
import { postRequest, useAsyncFn } from '@capital/common';
import { useOpenAppInfo } from '../context';
import type { OpenAppBot, OpenAppCapability, OpenAppOAuth } from '../types';
/**
*
*/
export function useOpenAppAction() {
const { refresh, appId, capability } = useOpenAppInfo();
const [{ loading }, handleChangeAppCapability] = useAsyncFn(
async (targetCapability: OpenAppCapability, checked: boolean) => {
const newCapability: OpenAppCapability[] = [...capability];
const findIndex = newCapability.findIndex((c) => c === targetCapability);
if (checked) {
if (findIndex === -1) {
newCapability.push(targetCapability);
}
} else {
if (findIndex !== -1) {
newCapability.splice(findIndex, 1);
}
}
await postRequest('/openapi/app/setAppCapability', {
appId,
capability: newCapability,
});
await refresh();
},
[appId, capability, refresh]
);
const [, handleUpdateOAuthInfo] = useAsyncFn(
async <T extends keyof OpenAppOAuth>(name: T, value: OpenAppOAuth[T]) => {
await postRequest('/openapi/app/setAppOAuthInfo', {
appId,
fieldName: name,
fieldValue: value,
});
await refresh();
},
[]
);
const [, handleUpdateBotInfo] = useAsyncFn(
async <T extends keyof OpenAppBot>(name: T, value: OpenAppBot[T]) => {
await postRequest('/openapi/app/setAppBotInfo', {
appId,
fieldName: name,
fieldValue: value,
});
await refresh();
},
[appId, refresh]
);
return {
loading,
handleChangeAppCapability,
handleUpdateOAuthInfo,
handleUpdateBotInfo,
};
}

@ -6,10 +6,14 @@ const openAppCapability = [
export type OpenAppCapability = typeof openAppCapability[number]; export type OpenAppCapability = typeof openAppCapability[number];
interface OpenAppOAuth { export interface OpenAppOAuth {
redirectUrls: string[]; redirectUrls: string[];
} }
export interface OpenAppBot {
callbackUrl: string;
}
export interface OpenApp { export interface OpenApp {
_id: string; _id: string;
appId: string; appId: string;
@ -19,6 +23,7 @@ export interface OpenApp {
appIcon: string; appIcon: string;
capability: OpenAppCapability[]; capability: OpenAppCapability[];
oauth?: OpenAppOAuth; oauth?: OpenAppOAuth;
bot?: OpenAppBot;
owner: string; owner: string;
} }

@ -6,4 +6,20 @@ export const Translate = {
'zh-CN': '管理员没有开放 Openapi 服务', 'zh-CN': '管理员没有开放 Openapi 服务',
'en-US': 'The administrator did not open the Openapi service', 'en-US': 'The administrator did not open the Openapi service',
}), }),
enableBotCapability: localTrans({
'zh-CN': '开启机器人能力',
'en-US': 'Enable Bot Capability',
}),
bot: {
callback: localTrans({
'zh-CN': '消息回调地址',
'en-US': 'Callback Url',
}),
callbackTip: localTrans({
'zh-CN':
'机器人被 @ 的时候会向该地址发送请求(收件箱接受到新内容时会发送回调)',
'en-US':
'The bot will send a request to this address when it is mentioned (callback will be sent when the inbox receives new content)',
}),
},
}; };

@ -29,13 +29,14 @@ export function filterAvailableAppCapability(
) as OpenAppCapability[]; ) as OpenAppCapability[];
} }
class OpenAppOAuth { export interface OpenAppOAuth {
@prop({
type: () => String,
})
redirectUrls: string[]; redirectUrls: string[];
} }
export interface OpenAppBot {
callbackUrl: string;
}
/** /**
* *
*/ */
@ -70,11 +71,12 @@ export class OpenApp extends TimeStamps implements Base {
}) })
capability: OpenAppCapability[]; capability: OpenAppCapability[];
@prop({ @prop()
type: () => OpenAppOAuth,
})
oauth?: OpenAppOAuth; oauth?: OpenAppOAuth;
@prop()
bot?: OpenAppBot;
/** /**
* appIdopenapp * appIdopenapp
* (secret) * (secret)

@ -8,8 +8,10 @@ import {
import _ from 'lodash'; import _ from 'lodash';
import { import {
filterAvailableAppCapability, filterAvailableAppCapability,
OpenAppBot,
OpenAppDocument, OpenAppDocument,
OpenAppModel, OpenAppModel,
OpenAppOAuth,
} from '../../models/openapi/app'; } from '../../models/openapi/app';
import { Types } from 'mongoose'; import { Types } from 'mongoose';
import { nanoid } from 'nanoid'; import { nanoid } from 'nanoid';
@ -67,6 +69,13 @@ class OpenAppService extends TcService {
fieldValue: 'any', fieldValue: 'any',
}, },
}); });
this.registerAction('setAppBotInfo', this.setAppBotInfo, {
params: {
appId: 'string',
fieldName: 'string',
fieldValue: 'any',
},
});
} }
/** /**
@ -201,11 +210,11 @@ class OpenAppService extends TcService {
/** /**
* OAuth * OAuth
*/ */
async setAppOAuthInfo( async setAppOAuthInfo<T extends keyof OpenAppOAuth>(
ctx: TcContext<{ ctx: TcContext<{
appId: string; appId: string;
fieldName: string; fieldName: T;
fieldValue: any; fieldValue: OpenAppOAuth[T];
}> }>
) { ) {
const { appId, fieldName, fieldValue } = ctx.params; const { appId, fieldName, fieldValue } = ctx.params;
@ -233,6 +242,42 @@ class OpenAppService extends TcService {
} }
); );
} }
/**
* Bot
*/
async setAppBotInfo<T extends keyof OpenAppBot>(
ctx: TcContext<{
appId: string;
fieldName: T;
fieldValue: OpenAppBot[T];
}>
) {
const { appId, fieldName, fieldValue } = ctx.params;
const { userId } = ctx.meta;
if (!['callbackUrl'].includes(fieldName)) {
throw new Error('Not allowed fields');
}
if (fieldName === 'callbackUrl') {
if (typeof fieldValue !== 'string') {
throw new Error('`callbackUrl` should be a string');
}
}
await this.adapter.model.findOneAndUpdate(
{
appId,
owner: userId,
},
{
$set: {
[`bot.${fieldName}`]: fieldValue,
},
}
);
}
} }
export default OpenAppService; export default OpenAppService;

Loading…
Cancel
Save