From f98b1c0458fb8cfd11b1c201a8d6c461d6fbb9ba Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Mon, 21 Sep 2020 16:17:55 +0800 Subject: [PATCH] =?UTF-8?q?feat(web):=20=E5=A2=9E=E5=8A=A0=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E7=AE=80=E6=98=93=E6=9C=BA=E5=99=A8=E4=BA=BA=E7=9A=84?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/shared/i18n/langs/en-US/translation.json | 3 + src/shared/i18n/langs/zh-CN/translation.json | 3 + src/shared/manager/ui.ts | 2 +- src/shared/model/bot.ts | 25 ++++++ src/shared/redux/hooks/group.ts | 18 ++++- src/web/components/BotResultTip.tsx | 37 +++++++++ src/web/components/modal/BotCreate.tsx | 76 +++++++++++++++++++ .../Group/GroupInfoDetail/GroupBotManage.tsx | 34 +++++++++ .../Content/Group/GroupInfoDetail/index.tsx | 7 ++ 9 files changed, 203 insertions(+), 2 deletions(-) create mode 100644 src/shared/model/bot.ts create mode 100644 src/web/components/BotResultTip.tsx create mode 100644 src/web/components/modal/BotCreate.tsx create mode 100644 src/web/routes/Main/Content/Group/GroupInfoDetail/GroupBotManage.tsx diff --git a/src/shared/i18n/langs/en-US/translation.json b/src/shared/i18n/langs/en-US/translation.json index 4623de601..1c158eb05 100644 --- a/src/shared/i18n/langs/en-US/translation.json +++ b/src/shared/i18n/langs/en-US/translation.json @@ -7,6 +7,7 @@ "k2847a777": "Offline Time", "k2a1f6b54": "Save Completed!", "k2bf06524": "Search Content should Not Empty", + "k2f546b1d": "Bot Manage", "k3081870c": "More", "k323b5cc7": "Revoke", "k324d7571": "Dismiss Group", @@ -62,6 +63,7 @@ "k9bb2f08b": "User Profile", "k9fe28f33": "Official", "ka0451c97": "Cancel", + "ka2188016": "Create Bot", "ka7907771": "Save Success", "kabfe9512": "Save", "kad207008": "Edit", @@ -83,6 +85,7 @@ "kcec953bb": "Group Summary", "kd105c7b2": "Developer Blog", "kd8702fdb": "No Search Result", + "kda3ac7f9": "Bot", "kdc2b5fe0": "Login Time", "kdf2b27a": "Gender", "kdff3e28e": "Ensure to Clear Cache", diff --git a/src/shared/i18n/langs/zh-CN/translation.json b/src/shared/i18n/langs/zh-CN/translation.json index 7a940c5d3..8540a1c6e 100644 --- a/src/shared/i18n/langs/zh-CN/translation.json +++ b/src/shared/i18n/langs/zh-CN/translation.json @@ -7,6 +7,7 @@ "k2847a777": "离线时间", "k2a1f6b54": "保存完毕!", "k2bf06524": "搜索内容不能为空", + "k2f546b1d": "机器人管理", "k3081870c": "更多", "k323b5cc7": "撤回", "k324d7571": "解散团", @@ -62,6 +63,7 @@ "k9bb2f08b": "用户信息", "k9fe28f33": "正式人物卡", "ka0451c97": "取消", + "ka2188016": "创建机器人", "ka7907771": "保存成功", "kabfe9512": "保存", "kad207008": "编辑", @@ -83,6 +85,7 @@ "kcec953bb": "团简介", "kd105c7b2": "开发博客", "kd8702fdb": "暂无搜索结果", + "kda3ac7f9": "机器人", "kdc2b5fe0": "登录时间", "kdf2b27a": "性别", "kdff3e28e": "确认要清除缓存么", diff --git a/src/shared/manager/ui.ts b/src/shared/manager/ui.ts index 04f49ed9d..ffd999020 100644 --- a/src/shared/manager/ui.ts +++ b/src/shared/manager/ui.ts @@ -10,7 +10,7 @@ export const [showToasts, setToasts] = buildRegFn< >('toasts'); interface AlertOptions { - message: string; + message: React.ReactNode; onConfirm?: () => void | Promise; } export const [showAlert, setAlert] = buildRegFn< diff --git a/src/shared/model/bot.ts b/src/shared/model/bot.ts new file mode 100644 index 000000000..dacbf115a --- /dev/null +++ b/src/shared/model/bot.ts @@ -0,0 +1,25 @@ +import { request } from '@shared/utils/request'; + +interface MsgTokenBot { + token: string; + name: string; + group_uuid: string; + channel_uuid: string | null; +} + +/** + * 创建简单机器人 + */ +export async function createMsgTokenBot( + name: string, + groupUUID: string, + channelUUID: string | null +): Promise { + const { data } = await request.post('/bot/msg/token/create', { + name, + groupUUID, + channelUUID, + }); + + return data.bot; +} diff --git a/src/shared/redux/hooks/group.ts b/src/shared/redux/hooks/group.ts index 9d8e4a030..ba038de33 100644 --- a/src/shared/redux/hooks/group.ts +++ b/src/shared/redux/hooks/group.ts @@ -1,5 +1,10 @@ import { useTRPGSelector } from '@shared/hooks/useTRPGSelector'; -import { GroupInfo, GroupActorType, GroupPanel } from '@redux/types/group'; +import { + GroupInfo, + GroupActorType, + GroupPanel, + GroupChannel, +} from '@redux/types/group'; import { useCurrentUserInfo } from './user'; import _get from 'lodash/get'; import _uniq from 'lodash/uniq'; @@ -122,3 +127,14 @@ export function useGroupPanelInfo( return panelInfo; } + +/** + * 获取团的频道列表 + * @param groupUUID 团UUID + */ +export function useGroupChannel(groupUUID: string): GroupChannel[] { + const groupInfo = useJoinedGroupInfo(groupUUID); + const channels = groupInfo?.channels ?? []; + + return channels; +} diff --git a/src/web/components/BotResultTip.tsx b/src/web/components/BotResultTip.tsx new file mode 100644 index 000000000..8ceafa8bf --- /dev/null +++ b/src/web/components/BotResultTip.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { TMemo } from '@shared/components/TMemo'; +import config from '@shared/project.config'; +import { Typography } from 'antd'; + +interface BotResultTipProps { + name: string; + token: string; +} + +/** + * 创建机器人结果提示 + */ + +export const BotResultTip: React.FC = TMemo((props) => { + const { name, token } = props; + + const requestUrl = `${config.url.api}/bot/msg/send`; + const getUrl = `${requestUrl}?token=${token}&msg=${encodeURI('Hello World')}`; + + return ( +
+ 创建机器人{name}完毕 + 唯一标识: {token} + +
尝试以下方式使用机器人
+
+ 简单访问: + + {getUrl} + + 或发送POST请求到{requestUrl} +
+
+ ); +}); +BotResultTip.displayName = 'BotResultTip'; diff --git a/src/web/components/modal/BotCreate.tsx b/src/web/components/modal/BotCreate.tsx new file mode 100644 index 000000000..7f15dbbca --- /dev/null +++ b/src/web/components/modal/BotCreate.tsx @@ -0,0 +1,76 @@ +import React, { useCallback, useMemo } from 'react'; +import { TMemo } from '@shared/components/TMemo'; +import { WebFastForm } from '../WebFastForm'; +import { FastFormFieldMeta } from '@shared/components/FastForm/field'; +import { useTranslation } from '@shared/i18n'; +import { ModalWrapper, useModalContext } from '../Modal'; +import { createMsgTokenBot } from '@shared/model/bot'; +import { useGroupChannel } from '@redux/hooks/group'; +import { showAlert, showToasts } from '@shared/manager/ui'; +import { BotResultTip } from '../BotResultTip'; + +const baseFields: FastFormFieldMeta[] = [ + { type: 'text', name: 'name', label: '机器人名', maxLength: 16 }, +]; + +interface BotCreateProps { + groupUUID: string; +} + +/** + * 创建机器人 + */ +export const BotCreate: React.FC = TMemo((props) => { + const { groupUUID } = props; + const { t } = useTranslation(); + const channels = useGroupChannel(groupUUID); + const { closeModal } = useModalContext(); + + const fields = useMemo(() => { + return [ + ...baseFields, + { + type: 'select', + name: 'channelUUID', + label: '频道', + options: [ + { + label: '大厅', + value: null, + }, + ...channels.map((channel) => ({ + label: channel.name, + value: channel.uuid, + })), + ], + }, + ]; + }, [channels]); + + const handleCreateBot = useCallback( + async (values) => { + try { + const bot = await createMsgTokenBot( + values.name, + groupUUID, + values.channelUUID + ); + + closeModal(); + showAlert({ + message: , + }); + } catch (err) { + showToasts(err, 'error'); + } + }, + [groupUUID, closeModal] + ); + + return ( + + + + ); +}); +BotCreate.displayName = 'BotCreate'; diff --git a/src/web/routes/Main/Content/Group/GroupInfoDetail/GroupBotManage.tsx b/src/web/routes/Main/Content/Group/GroupInfoDetail/GroupBotManage.tsx new file mode 100644 index 000000000..ed33dee2c --- /dev/null +++ b/src/web/routes/Main/Content/Group/GroupInfoDetail/GroupBotManage.tsx @@ -0,0 +1,34 @@ +import React, { useCallback } from 'react'; +import { TMemo } from '@shared/components/TMemo'; +import { Button, Typography } from 'antd'; +import { useTranslation } from '@shared/i18n'; +import { ModalWrapper, openModal } from '@web/components/Modal'; +import { BotCreate } from '@web/components/modal/BotCreate'; + +interface GroupBotManageProps { + groupUUID: string; +} +export const GroupBotManage: React.FC = TMemo( + (props: GroupBotManageProps) => { + const { groupUUID } = props; + const { t } = useTranslation(); + + const handleCreateBot = useCallback(() => { + openModal(); + }, [groupUUID]); + + return ( +
+ {t('机器人')} + + + + {/* TODO */} + {/*
机器人列表
*/} +
+ ); + } +); +GroupBotManage.displayName = 'GroupBotManage'; diff --git a/src/web/routes/Main/Content/Group/GroupInfoDetail/index.tsx b/src/web/routes/Main/Content/Group/GroupInfoDetail/index.tsx index 26cb2e5ba..f2936f74d 100644 --- a/src/web/routes/Main/Content/Group/GroupInfoDetail/index.tsx +++ b/src/web/routes/Main/Content/Group/GroupInfoDetail/index.tsx @@ -7,6 +7,7 @@ import { GroupPanelManage } from './GroupPanelManage'; import { GroupActorManage } from './GroupActorManage'; import { useTranslation } from '@shared/i18n'; import { GroupMemberManage } from './GroupMemberManage'; +import { GroupBotManage } from './GroupBotManage'; interface GroupInfoDetailProps { groupUUID: string; @@ -46,6 +47,12 @@ export const GroupInfoDetail: React.FC = TMemo( title: t('人物卡管理'), content: , }, + { + type: 'item', + title: t('机器人管理'), + hidden: !isGroupManager, + content: , + }, ], }, ],