feat: 增加第三方集成插件

pull/56/head
moonrailgun 2 years ago
parent abee334e58
commit 7d63f8b6c4

@ -0,0 +1,9 @@
{
"label": "第三方集成",
"name": "com.msgbyte.integration",
"url": "/plugins/com.msgbyte.integration/index.js",
"version": "0.0.0",
"author": "moonrailgun",
"description": "用于在群组中集成第三方应用",
"requireRestart": true
}

@ -0,0 +1,16 @@
{
"name": "@plugins/com.msgbyte.integration",
"main": "src/index.tsx",
"version": "0.0.0",
"description": "用于在群组中集成第三方应用",
"private": true,
"scripts": {
"sync:declaration": "tailchat declaration github"
},
"dependencies": {},
"devDependencies": {
"@types/styled-components": "^5.1.26",
"react": "18.2.0",
"styled-components": "^5.3.6"
}
}

@ -0,0 +1,108 @@
import React, { useCallback, useState } from 'react';
import { Avatar, Button, Input, UserName } from '@capital/component';
import styled from 'styled-components';
import type { OpenAppInfo } from 'types';
import { useAsyncRequest, postRequest } from '@capital/common';
const Tip = styled.div`
color: #999;
margin-bottom: 10px;
`;
const Row = styled.div`
display: flex;
`;
const AppInfoCard = styled.div({
backgroundColor: 'rgba(0, 0, 0, 0.1)',
borderRadius: 3,
padding: 10,
marginTop: 10,
'.app-info': {
flex: 1,
marginLeft: 10,
'.title': {
fontSize: 18,
fontWeight: 'bold',
},
'.action': {
marginTop: 10,
},
},
});
const IntegrationPanel: React.FC = React.memo(() => {
const [appId, setAppId] = useState('');
const [openAppInfo, setOpenAppInfo] = useState<OpenAppInfo | null>(null);
const [{ loading }, handleQueryApp] = useAsyncRequest(async () => {
const { data } = await postRequest('/openapi/app/get', {
appId,
});
setOpenAppInfo(data);
}, [appId]);
const handleAddBotIntoGroup = useCallback(() => {
console.log('TODO', appId);
}, [appId]);
return (
<div>
<Tip>ID</Tip>
<Row>
<Input
placeholder={'应用ID'}
value={appId}
onChange={(e) => setAppId(e.target.value)}
/>
<Button
type="primary"
disabled={!appId}
loading={loading}
onClick={handleQueryApp}
>
</Button>
</Row>
{openAppInfo && (
<div>
<AppInfoCard>
<Row>
<Avatar
size={56}
src={openAppInfo.appIcon}
name={openAppInfo.appName}
/>
<div className="app-info">
<div>{openAppInfo.appName}</div>
<div>{openAppInfo.appDesc}</div>
<Row>
<div>:</div>
<UserName userId={openAppInfo.owner} />
</Row>
<div className="action">
{openAppInfo.capability.includes('bot') && (
<Button type="primary" onClick={handleAddBotIntoGroup}>
</Button>
)}
</div>
</div>
</Row>
</AppInfoCard>
</div>
)}
</div>
);
});
IntegrationPanel.displayName = 'IntegrationPanel';
export default IntegrationPanel;

@ -0,0 +1,14 @@
import { Loadable, regCustomPanel } from '@capital/common';
import { Translate } from './translate';
const PLUGIN_NAME = '第三方集成';
console.log(`Plugin ${PLUGIN_NAME} is loaded`);
regCustomPanel({
position: 'groupdetail',
name: 'com.msgbyte.integration/groupdetail',
icon: '',
label: Translate.groupdetail,
render: Loadable(() => import('./IntegrationPanel')),
});

@ -0,0 +1,8 @@
import { localTrans } from '@capital/common';
export const Translate = {
groupdetail: localTrans({
'zh-CN': '集成',
'en-US': 'Integration',
}),
};

@ -0,0 +1,11 @@
export type OpenAppCapability = 'bot' | 'webpage' | 'oauth';
export interface OpenAppInfo {
_id: string;
owner: string;
appId: string;
appName: string;
appDesc: string;
appIcon: string;
capability: OpenAppCapability[];
}

@ -0,0 +1,11 @@
{
"compilerOptions": {
"baseUrl": "./src",
"esModuleInterop": true,
"jsx": "react",
"importsNotUsedAsValues": "error",
"paths": {
"@capital/*": ["../../../src/plugin/*"],
}
}
}

@ -131,7 +131,7 @@ class OpenAppService extends TcService {
async get(ctx: TcContext<{ appId: string }>) { async get(ctx: TcContext<{ appId: string }>) {
const appId = ctx.params.appId; const appId = ctx.params.appId;
const apps = await this.adapter.model.findOne( const app = await this.adapter.model.findOne(
{ {
appId, appId,
}, },
@ -140,7 +140,7 @@ class OpenAppService extends TcService {
} }
); );
return await this.transformDocuments(ctx, {}, apps); return await this.transformDocuments(ctx, {}, app);
} }
/** /**

Loading…
Cancel
Save