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

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

@ -1,48 +1,43 @@
import React from 'react';
import { FullModalField, Switch } from '@capital/component';
import {
DefaultFullModalInputEditorRender,
FullModalField,
Switch,
} from '@capital/component';
import { useOpenAppInfo } from '../context';
import { OpenAppCapability } from '../types';
import { postRequest, useAsyncFn } from '@capital/common';
import { Translate } from '../../translate';
import { useOpenAppAction } from './useOpenAppAction';
const Bot: React.FC = React.memo(() => {
const { refresh, appId, capability } = useOpenAppInfo();
const [{ loading }, handleChangeBotCapability] = useAsyncFn(
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]
);
const { capability, bot } = useOpenAppInfo();
const { loading, handleChangeAppCapability, handleUpdateBotInfo } =
useOpenAppAction();
return (
<div className="plugin-openapi-app-info_bot">
<FullModalField
title="开启机器人能力"
title={Translate.enableBotCapability}
content={
<Switch
disabled={loading}
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>
);
});

@ -5,44 +5,12 @@ import {
Switch,
} from '@capital/component';
import { useOpenAppInfo } from '../context';
import { OpenAppCapability } from '../types';
import { postRequest, useAsyncFn, useAsyncRequest } from '@capital/common';
import { useOpenAppAction } from './useOpenAppAction';
const OAuth: React.FC = React.memo(() => {
const { refresh, appId, capability, oauth } = useOpenAppInfo();
const [{ loading }, handleChangeOAuthCapability] = useAsyncRequest(
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();
},
[]
);
const { capability, oauth } = useOpenAppInfo();
const { loading, handleChangeAppCapability, handleUpdateOAuthInfo } =
useOpenAppAction();
return (
<div className="plugin-openapi-app-info_oauth">
@ -52,7 +20,7 @@ const OAuth: React.FC = React.memo(() => {
<Switch
disabled={loading}
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];
interface OpenAppOAuth {
export interface OpenAppOAuth {
redirectUrls: string[];
}
export interface OpenAppBot {
callbackUrl: string;
}
export interface OpenApp {
_id: string;
appId: string;
@ -19,6 +23,7 @@ export interface OpenApp {
appIcon: string;
capability: OpenAppCapability[];
oauth?: OpenAppOAuth;
bot?: OpenAppBot;
owner: string;
}

@ -6,4 +6,20 @@ export const Translate = {
'zh-CN': '管理员没有开放 Openapi 服务',
'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[];
}
class OpenAppOAuth {
@prop({
type: () => String,
})
export interface OpenAppOAuth {
redirectUrls: string[];
}
export interface OpenAppBot {
callbackUrl: string;
}
/**
*
*/
@ -70,11 +71,12 @@ export class OpenApp extends TimeStamps implements Base {
})
capability: OpenAppCapability[];
@prop({
type: () => OpenAppOAuth,
})
@prop()
oauth?: OpenAppOAuth;
@prop()
bot?: OpenAppBot;
/**
* appIdopenapp
* (secret)

@ -8,8 +8,10 @@ import {
import _ from 'lodash';
import {
filterAvailableAppCapability,
OpenAppBot,
OpenAppDocument,
OpenAppModel,
OpenAppOAuth,
} from '../../models/openapi/app';
import { Types } from 'mongoose';
import { nanoid } from 'nanoid';
@ -67,6 +69,13 @@ class OpenAppService extends TcService {
fieldValue: 'any',
},
});
this.registerAction('setAppBotInfo', this.setAppBotInfo, {
params: {
appId: 'string',
fieldName: 'string',
fieldValue: 'any',
},
});
}
/**
@ -201,11 +210,11 @@ class OpenAppService extends TcService {
/**
* OAuth
*/
async setAppOAuthInfo(
async setAppOAuthInfo<T extends keyof OpenAppOAuth>(
ctx: TcContext<{
appId: string;
fieldName: string;
fieldValue: any;
fieldName: T;
fieldValue: OpenAppOAuth[T];
}>
) {
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;

Loading…
Cancel
Save