perf: ad api with zod

This commit is contained in:
archer 2025-12-23 21:40:25 +08:00
parent 35153e10fa
commit b0b9b21966
No known key found for this signature in database
GPG Key ID: 4446499B846D4A9E
20 changed files with 374 additions and 33 deletions

View File

@ -1,6 +1,7 @@
import { createDocument } from 'zod-openapi';
import { DashboardPath } from './admin/core/dashboard';
import { TagsMap } from './tag';
import { AdminSupportPath } from './admin/support';
export const adminOpenAPIDocument = createDocument({
openapi: '3.1.0',
@ -10,13 +11,18 @@ export const adminOpenAPIDocument = createDocument({
description: 'FastGPT Admin API 文档'
},
paths: {
...DashboardPath
...DashboardPath,
...AdminSupportPath
},
servers: [{ url: '/api' }],
'x-tagGroups': [
{
name: '仪表盘',
tags: [TagsMap.adminDashboard]
},
{
name: '系统配置',
tags: [TagsMap.adminInform]
}
]
});

View File

@ -13,8 +13,6 @@ import {
} from './api';
import { TagsMap } from '../../../tag';
export * from './api';
export const DashboardPath: OpenAPIPath = {
'/admin/core/dashboard/getUserStats': {
get: {

View File

@ -0,0 +1,6 @@
import { AdminUserPath } from './user';
import type { OpenAPIPath } from '../../type';
export const AdminSupportPath: OpenAPIPath = {
...AdminUserPath
};

View File

@ -0,0 +1,6 @@
import { AdminInformPath } from './inform';
import type { OpenAPIPath } from '../../../type';
export const AdminUserPath: OpenAPIPath = {
...AdminInformPath
};

View File

@ -0,0 +1,57 @@
import { z } from 'zod';
import { InformLevelEnum } from '../../../../../support/user/inform/constants';
// Send system inform
export const SendSystemInformBodySchema = z.object({
title: z.string().meta({ description: '通知标题' }),
content: z.string().meta({ description: '通知内容' }),
level: z.enum(InformLevelEnum).meta({ description: '通知等级' })
});
export type SendSystemInformBodyType = z.infer<typeof SendSystemInformBodySchema>;
// Update system modal
export const UpdateSystemModalBodySchema = z.object({
content: z.string().meta({ description: '系统弹窗内容' })
});
export type UpdateSystemModalBodyType = z.infer<typeof UpdateSystemModalBodySchema>;
// Update operational ad
export const UpdateOperationalAdBodySchema = z.object({
operationalAdImage: z.string().meta({ description: '活动图片URL' }),
operationalAdLink: z.string().meta({ description: '活动链接' })
});
export type UpdateOperationalAdBodyType = z.infer<typeof UpdateOperationalAdBodySchema>;
// Update activity ad
export const UpdateActivityAdBodySchema = z.object({
activityAdImage: z.string().meta({ description: '底部广告图片URL' }),
activityAdLink: z.string().meta({ description: '底部广告链接' })
});
export type UpdateActivityAdBodyType = z.infer<typeof UpdateActivityAdBodySchema>;
// Response schemas
export const SystemMsgModalResponseSchema = z
.object({
id: z.string().meta({ description: '弹窗ID' }),
content: z.string().meta({ description: '弹窗内容' })
})
.optional();
export type SystemMsgModalValueType = z.infer<typeof SystemMsgModalResponseSchema>;
export const OperationalAdResponseSchema = z
.object({
id: z.string().meta({ description: '广告ID' }),
operationalAdImage: z.string().meta({ description: '广告图片URL' }),
operationalAdLink: z.string().meta({ description: '广告链接' })
})
.optional();
export type OperationalAdResponseType = z.infer<typeof OperationalAdResponseSchema>;
export const ActivityAdResponseSchema = z
.object({
id: z.string().meta({ description: '广告ID' }),
activityAdImage: z.string().meta({ description: '广告图片URL' }),
activityAdLink: z.string().meta({ description: '广告链接' })
})
.optional();
export type ActivityAdResponseType = z.infer<typeof ActivityAdResponseSchema>;

View File

@ -0,0 +1,161 @@
import type { OpenAPIPath } from '../../../../type';
import {
SendSystemInformBodySchema,
UpdateSystemModalBodySchema,
UpdateOperationalAdBodySchema,
UpdateActivityAdBodySchema,
SystemMsgModalResponseSchema,
OperationalAdResponseSchema,
ActivityAdResponseSchema
} from './api';
import { TagsMap } from '../../../../tag';
export const AdminInformPath: OpenAPIPath = {
'/admin/support/user/inform/sendSystemInform': {
post: {
summary: '发送系统通知给所有用户',
description: '向所有用户发送系统通知消息',
tags: [TagsMap.adminInform],
requestBody: {
content: {
'application/json': {
schema: SendSystemInformBodySchema
}
}
},
responses: {
200: {
description: '成功发送系统通知',
content: {
'application/json': {
schema: {}
}
}
}
}
}
},
'/support/user/inform/getSystemMsgModal': {
get: {
summary: '获取系统弹窗内容',
description: '获取系统消息弹窗的内容',
tags: [TagsMap.adminInform],
responses: {
200: {
description: '成功获取系统弹窗内容',
content: {
'application/json': {
schema: SystemMsgModalResponseSchema
}
}
}
}
}
},
'/admin/support/user/inform/updateSystemModal': {
post: {
summary: '更新系统弹窗内容',
description: '更新系统消息弹窗的内容',
tags: [TagsMap.adminInform],
requestBody: {
content: {
'application/json': {
schema: UpdateSystemModalBodySchema
}
}
},
responses: {
200: {
description: '成功更新系统弹窗',
content: {
'application/json': {
schema: {}
}
}
}
}
}
},
'/support/user/inform/getOperationalAd': {
get: {
summary: '获取运营广告',
description: '获取运营广告的图片和链接',
tags: [TagsMap.adminInform],
responses: {
200: {
description: '成功获取运营广告',
content: {
'application/json': {
schema: OperationalAdResponseSchema
}
}
}
}
}
},
'/admin/support/user/inform/updateOperationalAd': {
post: {
summary: '更新运营广告',
description: '更新运营广告的图片和链接',
tags: [TagsMap.adminInform],
requestBody: {
content: {
'application/json': {
schema: UpdateOperationalAdBodySchema
}
}
},
responses: {
200: {
description: '成功更新运营广告',
content: {
'application/json': {
schema: {}
}
}
}
}
}
},
'/support/user/inform/getActivityAd': {
get: {
summary: '获取活动广告',
description: '获取活动广告的图片和链接',
tags: [TagsMap.adminInform],
responses: {
200: {
description: '成功获取活动广告',
content: {
'application/json': {
schema: ActivityAdResponseSchema
}
}
}
}
}
},
'/admin/support/user/inform/updateActivityAd': {
post: {
summary: '更新活动广告',
description: '更新活动广告的图片和链接',
tags: [TagsMap.adminInform],
requestBody: {
content: {
'application/json': {
schema: UpdateActivityAdBodySchema
}
}
},
responses: {
200: {
description: '成功更新活动广告',
content: {
'application/json': {
schema: {}
}
}
}
}
}
}
};

View File

@ -1,11 +1,9 @@
import { createDocument } from 'zod-openapi';
import { ChatPath } from './core/chat';
import { ApiKeyPath } from './support/openapi';
import { TagsMap } from './tag';
import { PluginPath } from './core/plugin';
import { WalletPath } from './support/wallet';
import { CustomDomainPath } from './support/customDomain';
import { AppPath } from './core/app';
import { SupportPath } from './support';
export const openAPIDocument = createDocument({
openapi: '3.1.0',
@ -17,10 +15,8 @@ export const openAPIDocument = createDocument({
paths: {
...AppPath,
...ChatPath,
...ApiKeyPath,
...PluginPath,
...WalletPath,
...CustomDomainPath
...SupportPath
},
servers: [{ url: '/api' }],
'x-tagGroups': [
@ -37,8 +33,8 @@ export const openAPIDocument = createDocument({
tags: [TagsMap.pluginToolTag, TagsMap.pluginTeam]
},
{
name: '支付系统',
tags: [TagsMap.walletBill, TagsMap.walletDiscountCoupon]
name: '用户体系',
tags: [TagsMap.userInform, TagsMap.walletBill, TagsMap.walletDiscountCoupon]
},
{
name: '通用-辅助功能',

View File

@ -0,0 +1,12 @@
import { UserPath } from './user';
import type { OpenAPIPath } from '../type';
import { WalletPath } from './wallet';
import { ApiKeyPath } from './openapi';
import { CustomDomainPath } from './customDomain';
export const SupportPath: OpenAPIPath = {
...UserPath,
...WalletPath,
...ApiKeyPath,
...CustomDomainPath
};

View File

@ -0,0 +1,6 @@
import { UserInformPath } from './inform';
import type { OpenAPIPath } from '../../type';
export const UserPath: OpenAPIPath = {
...UserInformPath
};

View File

@ -0,0 +1,61 @@
import type { OpenAPIPath } from '../../../type';
import {
SystemMsgModalResponseSchema,
OperationalAdResponseSchema,
ActivityAdResponseSchema
} from '../../../admin/support/user/inform/api';
import { TagsMap } from '../../../tag';
export const UserInformPath: OpenAPIPath = {
'/proApi/support/user/inform/getSystemMsgModal': {
get: {
summary: '获取系统弹窗内容',
description: '获取系统消息弹窗的内容',
tags: [TagsMap.userInform],
responses: {
200: {
description: '成功获取系统弹窗内容',
content: {
'application/json': {
schema: SystemMsgModalResponseSchema
}
}
}
}
}
},
'/proApi/support/user/inform/getOperationalAd': {
get: {
summary: '获取运营广告',
description: '获取运营广告的图片和链接',
tags: [TagsMap.userInform],
responses: {
200: {
description: '成功获取运营广告',
content: {
'application/json': {
schema: OperationalAdResponseSchema
}
}
}
}
}
},
'/proApi/support/user/inform/getActivityAd': {
get: {
summary: '获取活动广告',
description: '获取活动广告的图片和链接',
tags: [TagsMap.userInform],
responses: {
200: {
description: '成功获取活动广告',
content: {
'application/json': {
schema: ActivityAdResponseSchema
}
}
}
}
}
}
};

View File

@ -22,6 +22,8 @@ export const TagsMap = {
walletBill: '订单',
walletDiscountCoupon: '优惠券',
customDomain: '自定义域名',
// User
userInform: '用户通知',
/* Common */
// APIKey
@ -33,5 +35,7 @@ export const TagsMap = {
pluginAdmin: '管理员插件管理',
pluginToolAdmin: '管理员系统工具管理',
// Data
adminDashboard: '管理员仪表盘'
adminDashboard: '管理员仪表盘',
// Inform
adminInform: '管理员通知管理'
};

View File

@ -2,8 +2,7 @@ import type { auditLogMap, adminAuditLogMap } from '../../../../web/support/user
export enum AdminAuditEventEnum {
ADMIN_LOGIN = 'ADMIN_LOGIN',
ADMIN_UPDATE_SYSTEM_MODAL = 'ADMIN_UPDATE_SYSTEM_MODAL',
ADMIN_SEND_SYSTEM_INFORM = 'ADMIN_SEND_SYSTEM_INFORM',
ADMIN_ADD_USER = 'ADMIN_ADD_USER',
ADMIN_UPDATE_USER = 'ADMIN_UPDATE_USER',
ADMIN_UPDATE_TEAM = 'ADMIN_UPDATE_TEAM',
@ -21,7 +20,13 @@ export enum AdminAuditEventEnum {
ADMIN_DELETE_PLUGIN = 'ADMIN_DELETE_PLUGIN',
ADMIN_CREATE_PLUGIN_GROUP = 'ADMIN_CREATE_PLUGIN_GROUP',
ADMIN_UPDATE_PLUGIN_GROUP = 'ADMIN_UPDATE_PLUGIN_GROUP',
ADMIN_DELETE_PLUGIN_GROUP = 'ADMIN_DELETE_PLUGIN_GROUP'
ADMIN_DELETE_PLUGIN_GROUP = 'ADMIN_DELETE_PLUGIN_GROUP',
// Inform
ADMIN_UPDATE_SYSTEM_MODAL = 'ADMIN_UPDATE_SYSTEM_MODAL',
ADMIN_SEND_SYSTEM_INFORM = 'ADMIN_SEND_SYSTEM_INFORM',
ADMIN_UPDATE_ACTIVITY_AD = 'ADMIN_UPDATE_ACTIVITY_AD',
ADMIN_UPDATE_OPERATIONAL_AD = 'ADMIN_UPDATE_OPERATIONAL_AD'
}
export enum AuditEventEnum {

View File

@ -1,4 +0,0 @@
export type SystemMsgModalValueType = {
id: string;
content: string;
};

View File

@ -19,7 +19,9 @@
"admin_login": "Administrator login",
"admin_save_template_type": "Update template classification",
"admin_send_system_inform": "Send system notifications",
"admin_update_activity_ad": "Bottom advertising configuration",
"admin_update_app_template": "Update templates",
"admin_update_operational_ad": "Activity page configuration",
"admin_update_plan": "Editorial Team Package",
"admin_update_plugin": "Plugin Update",
"admin_update_plugin_group": "Plugin group update",
@ -128,7 +130,9 @@
"log_admin_login": "【{{name}}】Logined in the administrator background",
"log_admin_save_template_type": "【{{name}}】Added template classification called [{{typeName}}]",
"log_admin_send_system_inform": "【{{name}}】Sent a system notification titled [{{informTitle}}], with the level of [{{level}}]",
"log_admin_update_activity_ad": "[{{name}}] has configured bottom ads",
"log_admin_update_app_template": "【{{name}}】Updated template information named [{{templateName}}]",
"log_admin_update_operational_ad": "[{{name}}] has configured the event page",
"log_admin_update_plan": "【{{name}}】Edited the package information of the team with the team id [{{teamId}}]",
"log_admin_update_plugin": "【{{name}}】Updated plugin information called [{{pluginName}}]",
"log_admin_update_plugin_group": "【{{name}}】Updated plug-in grouping called [{{groupName}}]",

View File

@ -19,7 +19,9 @@
"admin_login": "管理员登录",
"admin_save_template_type": "更新模板分类",
"admin_send_system_inform": "发送系统通知",
"admin_update_activity_ad": "底部广告配置",
"admin_update_app_template": "更新模板",
"admin_update_operational_ad": "活动页配置",
"admin_update_plan": "编辑团队套餐",
"admin_update_plugin": "插件更新",
"admin_update_plugin_group": "插件分组更新",
@ -130,7 +132,9 @@
"log_admin_login": "【{{name}}】登录了管理员后台",
"log_admin_save_template_type": "【{{name}}】添加了名为【{{typeName}}】的模板分类",
"log_admin_send_system_inform": "【{{name}}】发送了标题为【{{informTitle}}】的系统通知,等级为【{{level}}】",
"log_admin_update_activity_ad": "【{{name}}】进行了底部广告配置",
"log_admin_update_app_template": "【{{name}}】更新了名为【{{templateName}}】的模板信息",
"log_admin_update_operational_ad": "【{{name}}】进行了活动页配置",
"log_admin_update_plan": "【{{name}}】编辑了团队id为【{{teamId}}】的团队的套餐信息",
"log_admin_update_plugin": "【{{name}}】更新了名为【{{pluginName}}】的插件信息",
"log_admin_update_plugin_group": "【{{name}}】更新了名为【{{groupName}}】的插件分组",

View File

@ -19,7 +19,9 @@
"admin_login": "管理員登錄",
"admin_save_template_type": "更新模板分類",
"admin_send_system_inform": "發送系統通知",
"admin_update_activity_ad": "底部廣告配置",
"admin_update_app_template": "更新模板",
"admin_update_operational_ad": "活動頁配置",
"admin_update_plan": "編輯團隊套餐",
"admin_update_plugin": "插件更新",
"admin_update_plugin_group": "插件分組更新",
@ -128,7 +130,9 @@
"log_admin_login": "【{{name}}】登錄了管理員後台",
"log_admin_save_template_type": "【{{name}}】添加了名為【{{typeName}}】的模板分類",
"log_admin_send_system_inform": "【{{name}}】發送了標題為【{{informTitle}}】的系統通知,等級為【{{level}}】",
"log_admin_update_activity_ad": "【{{name}}】進行了底部廣告配置",
"log_admin_update_app_template": "【{{name}}】更新了名為【{{templateName}}】的模板信息",
"log_admin_update_operational_ad": "【{{name}}】進行了活動頁配置",
"log_admin_update_plan": "【{{name}}】編輯了團隊id為【{{teamId}}】的團隊的套餐信息",
"log_admin_update_plugin": "【{{name}}】更新了名為【{{pluginName}}】的插件信息",
"log_admin_update_plugin_group": "【{{name}}】更新了名為【{{groupName}}】的插件分組",

View File

@ -7,16 +7,6 @@ export const adminAuditLogMap = {
typeLabel: i18nT('account_team:admin_login'),
params: {} as { name?: string }
},
[AdminAuditEventEnum.ADMIN_UPDATE_SYSTEM_MODAL]: {
content: i18nT('account_team:log_admin_update_system_modal'),
typeLabel: i18nT('account_team:admin_update_system_modal'),
params: {} as { name?: string }
},
[AdminAuditEventEnum.ADMIN_SEND_SYSTEM_INFORM]: {
content: i18nT('account_team:log_admin_send_system_inform'),
typeLabel: i18nT('account_team:admin_send_system_inform'),
params: {} as { name?: string; informTitle?: string; level?: string }
},
[AdminAuditEventEnum.ADMIN_ADD_USER]: {
content: i18nT('account_team:log_admin_add_user'),
typeLabel: i18nT('account_team:admin_add_user'),
@ -108,6 +98,28 @@ export const adminAuditLogMap = {
content: i18nT('account_team:log_admin_delete_plugin_group'),
typeLabel: i18nT('account_team:admin_delete_plugin_group'),
params: {} as { name?: string; groupName: string }
},
// Inform
[AdminAuditEventEnum.ADMIN_UPDATE_SYSTEM_MODAL]: {
content: i18nT('account_team:log_admin_update_system_modal'),
typeLabel: i18nT('account_team:admin_update_system_modal'),
params: {} as { name?: string }
},
[AdminAuditEventEnum.ADMIN_SEND_SYSTEM_INFORM]: {
content: i18nT('account_team:log_admin_send_system_inform'),
typeLabel: i18nT('account_team:admin_send_system_inform'),
params: {} as { name?: string; informTitle?: string; level?: string }
},
[AdminAuditEventEnum.ADMIN_UPDATE_ACTIVITY_AD]: {
content: i18nT('account_team:log_admin_update_activity_ad'),
typeLabel: i18nT('account_team:admin_update_activity_ad'),
params: {}
},
[AdminAuditEventEnum.ADMIN_UPDATE_OPERATIONAL_AD]: {
content: i18nT('account_team:log_admin_update_operational_ad'),
typeLabel: i18nT('account_team:admin_update_operational_ad'),
params: {}
}
};

View File

@ -13,6 +13,7 @@ import {
ModalContent,
ModalCloseButton
} from '@chakra-ui/react';
import { useSystemStore } from '@/web/common/system/useSystemStore';
const CLOSED_AD_KEY = 'activity_ad_closed';
const CLOSED_AD_DURATION = 24 * 60 * 60 * 1000; // 24 hours
@ -20,6 +21,7 @@ const CLOSED_AD_DURATION = 24 * 60 * 60 * 1000; // 24 hours
const ActivityAdModal = () => {
const { isOpen, onOpen, onClose } = useDisclosure();
const { t } = useTranslation();
const { feConfigs } = useSystemStore();
// Check if ad was recently closed
const shouldShowAd = useMemo(() => {
@ -38,6 +40,7 @@ const ActivityAdModal = () => {
const { data } = useRequest2(
async () => {
if (!feConfigs?.isPlus) return;
return getActivityAd();
},
{
@ -61,8 +64,7 @@ const ActivityAdModal = () => {
if (data?.activityAdLink) {
window.open(data.activityAdLink, '_blank');
}
// handleClose();
}, [data?.activityAdLink, handleClose]);
}, [data?.activityAdLink]);
if (!data?.activityAdImage) {
return null;
@ -173,7 +175,7 @@ const ActivityAdModal = () => {
>
{t('common:activity_ad.join_now')}
</Button>
<Button width="100%" variant="outline" h={10} onClick={handleClose}>
<Button width="100%" variant="whiteBase" h={10} onClick={handleClose}>
{t('common:activity_ad.later')}
</Button>
</Flex>

View File

@ -24,6 +24,7 @@ export const updateModelCollaborators = (props: UpdateClbPermissionProps & { mod
export const getMyModels = (props: GetMyModelsQuery) =>
GET<GetMyModelsResponse>('/core/ai/model/getMyModels', props);
/* 活动 banner */
export const getOperationalAd = () =>
GET<{ id: string; operationalAdImage: string; operationalAdLink: string }>(
'/proApi/support/user/inform/getOperationalAd'

View File

@ -1,6 +1,6 @@
import { GET, POST } from '@/web/common/api/request';
import type { UserInformType } from '@fastgpt/global/support/user/inform/type';
import type { SystemMsgModalValueType } from '@fastgpt/service/support/user/inform/type';
import type { SystemMsgModalValueType } from '@fastgpt/global/openapi/admin/support/user/inform/api';
import type { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
export const getInforms = (data: PaginationProps) =>