From e0141f4bc435310a6099ac87374bffd4dc90c29a Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Sat, 26 Aug 2023 22:03:25 +0800 Subject: [PATCH] feat(openapi): allow edit appName, appDesc and appIcon --- .../src/MainPanel/AppInfo/Profile.tsx | 28 +++++++++-- .../src/MainPanel/AppInfo/index.tsx | 2 +- .../MainPanel/AppInfo/useOpenAppAction.tsx | 20 ++++++-- .../components/modals/GroupDetail/Config.tsx | 2 +- client/web/src/plugin/component/index.tsx | 1 + server/services/openapi/app.service.ts | 46 +++++++++++++++++++ 6 files changed, 90 insertions(+), 9 deletions(-) diff --git a/client/web/plugins/com.msgbyte.openapi/src/MainPanel/AppInfo/Profile.tsx b/client/web/plugins/com.msgbyte.openapi/src/MainPanel/AppInfo/Profile.tsx index bd195993..c556a31c 100644 --- a/client/web/plugins/com.msgbyte.openapi/src/MainPanel/AppInfo/Profile.tsx +++ b/client/web/plugins/com.msgbyte.openapi/src/MainPanel/AppInfo/Profile.tsx @@ -6,6 +6,8 @@ import { SensitiveText, Button, Avatar, + AvatarUploader, + DefaultFullModalInputEditorRender, } from '@capital/component'; import { Translate } from '../../translate'; import { useOpenAppAction } from './useOpenAppAction'; @@ -26,7 +28,7 @@ const TwoColumnContainer = styled.div` const Profile: React.FC = React.memo(() => { const { appId, appSecret, appName, appDesc, appIcon } = useOpenAppInfo(); - const { handleDeleteApp } = useOpenAppAction(); + const { handleSetAppInfo, handleDeleteApp } = useOpenAppAction(); return (
@@ -34,13 +36,31 @@ const Profile: React.FC = React.memo(() => {
- + handleSetAppInfo('appName', val)} + /> - + handleSetAppInfo('appDesc', val)} + />
- + { + handleSetAppInfo('appIcon', fileInfo.url); + }} + > + +
diff --git a/client/web/plugins/com.msgbyte.openapi/src/MainPanel/AppInfo/index.tsx b/client/web/plugins/com.msgbyte.openapi/src/MainPanel/AppInfo/index.tsx index 4e763047..c96830ed 100644 --- a/client/web/plugins/com.msgbyte.openapi/src/MainPanel/AppInfo/index.tsx +++ b/client/web/plugins/com.msgbyte.openapi/src/MainPanel/AppInfo/index.tsx @@ -18,7 +18,7 @@ const AppInfo: React.FC = React.memo(() => { () => [ { type: 'group', - title: appName, + title:
{appName}
, children: [ // { // type: 'item', diff --git a/client/web/plugins/com.msgbyte.openapi/src/MainPanel/AppInfo/useOpenAppAction.tsx b/client/web/plugins/com.msgbyte.openapi/src/MainPanel/AppInfo/useOpenAppAction.tsx index 45f03dd1..96612e58 100644 --- a/client/web/plugins/com.msgbyte.openapi/src/MainPanel/AppInfo/useOpenAppAction.tsx +++ b/client/web/plugins/com.msgbyte.openapi/src/MainPanel/AppInfo/useOpenAppAction.tsx @@ -3,6 +3,7 @@ import { postRequest, showErrorToasts, useAsyncFn, + useAsyncRequest, useEvent, } from '@capital/common'; import { useOpenAppInfo } from '../context'; @@ -14,7 +15,7 @@ import type { OpenAppBot, OpenAppCapability, OpenAppOAuth } from '../types'; export function useOpenAppAction() { const { refresh, appId, capability, onSelectApp } = useOpenAppInfo(); - const [{ loading }, handleChangeAppCapability] = useAsyncFn( + const [{ loading }, handleChangeAppCapability] = useAsyncRequest( async (targetCapability: OpenAppCapability, checked: boolean) => { const newCapability: OpenAppCapability[] = [...capability]; const findIndex = newCapability.findIndex((c) => c === targetCapability); @@ -38,7 +39,19 @@ export function useOpenAppAction() { [appId, capability, refresh] ); - const [, handleUpdateOAuthInfo] = useAsyncFn( + const [, handleSetAppInfo] = useAsyncRequest( + async (fieldName: string, fieldValue: string) => { + await postRequest('/openapi/app/setAppInfo', { + appId, + fieldName, + fieldValue, + }); + await refresh(); + }, + [appId, refresh] + ); + + const [, handleUpdateOAuthInfo] = useAsyncRequest( async (name: T, value: OpenAppOAuth[T]) => { await postRequest('/openapi/app/setAppOAuthInfo', { appId, @@ -50,7 +63,7 @@ export function useOpenAppAction() { [] ); - const [, handleUpdateBotInfo] = useAsyncFn( + const [, handleUpdateBotInfo] = useAsyncRequest( async (name: T, value: OpenAppBot[T]) => { await postRequest('/openapi/app/setAppBotInfo', { appId, @@ -80,6 +93,7 @@ export function useOpenAppAction() { return { loading, + handleSetAppInfo, handleDeleteApp, handleChangeAppCapability, handleUpdateOAuthInfo, diff --git a/client/web/src/components/modals/GroupDetail/Config.tsx b/client/web/src/components/modals/GroupDetail/Config.tsx index 510f200b..d99eda30 100644 --- a/client/web/src/components/modals/GroupDetail/Config.tsx +++ b/client/web/src/components/modals/GroupDetail/Config.tsx @@ -92,7 +92,7 @@ export const GroupConfig: React.FC<{ <> { handleModifyConfig('groupBackgroundImage', fileInfo.url); }} > diff --git a/client/web/src/plugin/component/index.tsx b/client/web/src/plugin/component/index.tsx index 31eaae35..7288c6f4 100644 --- a/client/web/src/plugin/component/index.tsx +++ b/client/web/src/plugin/component/index.tsx @@ -78,3 +78,4 @@ export { export { NoData } from '@/components/NoData'; export { NotFound } from '@/components/NotFound'; export { withKeepAliveOverlay } from '@/components/KeepAliveOverlay/withKeepAliveOverlay'; +export { AvatarUploader, ImageUploader } from '@/components/ImageUploader'; diff --git a/server/services/openapi/app.service.ts b/server/services/openapi/app.service.ts index dd03764c..3084d022 100644 --- a/server/services/openapi/app.service.ts +++ b/server/services/openapi/app.service.ts @@ -67,6 +67,13 @@ class OpenAppService extends TcService { appId: 'string', }, }); + this.registerAction('setAppInfo', this.setAppInfo, { + params: { + appId: 'string', + fieldName: 'string', + fieldValue: 'string', + }, + }); this.registerAction('setAppCapability', this.setAppCapability, { params: { appId: 'string', @@ -222,6 +229,45 @@ class OpenAppService extends TcService { return true; } + /** + * 修改应用信息 + */ + async setAppInfo( + ctx: TcContext<{ + appId: string; + fieldName: string; + fieldValue: string; + }> + ) { + const { appId, fieldName, fieldValue } = ctx.params; + const userId = ctx.meta.userId; + const t = ctx.meta.t; + + if (!['appName', 'appDesc', 'appIcon'].includes(fieldName)) { + // 只允许修改以上字段 + throw new EntityError(`${t('该数据不允许修改')}: ${fieldName}`); + } + + const doc = await this.adapter.model + .findOneAndUpdate( + { + appId, + owner: userId, + }, + { + [fieldName]: fieldValue, + }, + { + new: true, + } + ) + .exec(); + + this.cleanAppInfoCache(appId); + + return await this.transformDocuments(ctx, {}, doc); + } + /** * 设置应用开放的能力 */