feat: sync org from wecom, pref: member list pagination (#3549)
* feat: sync org * chore: fe * chore: loading * chore: type * pref: team member list change to pagination. Edit a sort of list apis. * feat: member update avatar * chore: user avatar move to tmb * chore: init scripts move user avatar * chore: sourceMember * fix: list api sourceMember * fix: member sync * fix: pagination * chore: adjust code * chore: move changeOwner to pro * chore: init v4819 script * chore: adjust code * chore: UserBox
This commit is contained in:
@@ -40,7 +40,7 @@ export type FastGPTConfigFileType = {
|
|||||||
|
|
||||||
export type FastGPTFeConfigsType = {
|
export type FastGPTFeConfigsType = {
|
||||||
show_emptyChat?: boolean;
|
show_emptyChat?: boolean;
|
||||||
register_method?: ['email' | 'phone'];
|
register_method?: ['email' | 'phone' | 'sync'];
|
||||||
login_method?: ['email' | 'phone']; // Attention: login method is diffrent with oauth
|
login_method?: ['email' | 'phone']; // Attention: login method is diffrent with oauth
|
||||||
find_password_method?: ['email' | 'phone'];
|
find_password_method?: ['email' | 'phone'];
|
||||||
bind_notification_method?: ['email' | 'phone'];
|
bind_notification_method?: ['email' | 'phone'];
|
||||||
@@ -76,7 +76,6 @@ export type FastGPTFeConfigsType = {
|
|||||||
wecom?: {
|
wecom?: {
|
||||||
corpid?: string;
|
corpid?: string;
|
||||||
agentid?: string;
|
agentid?: string;
|
||||||
secret?: string;
|
|
||||||
};
|
};
|
||||||
microsoft?: {
|
microsoft?: {
|
||||||
clientId?: string;
|
clientId?: string;
|
||||||
|
|||||||
4
packages/global/core/app/type.d.ts
vendored
4
packages/global/core/app/type.d.ts
vendored
@@ -12,8 +12,9 @@ import { TeamTagSchema as TeamTagsSchemaType } from '@fastgpt/global/support/use
|
|||||||
import { StoreEdgeItemType } from '../workflow/type/edge';
|
import { StoreEdgeItemType } from '../workflow/type/edge';
|
||||||
import { AppPermission } from '../../support/permission/app/controller';
|
import { AppPermission } from '../../support/permission/app/controller';
|
||||||
import { ParentIdType } from '../../common/parentFolder/type';
|
import { ParentIdType } from '../../common/parentFolder/type';
|
||||||
import { FlowNodeInputTypeEnum } from 'core/workflow/node/constant';
|
import { FlowNodeInputTypeEnum } from '../../core/workflow/node/constant';
|
||||||
import { WorkflowTemplateBasicType } from '@fastgpt/global/core/workflow/type';
|
import { WorkflowTemplateBasicType } from '@fastgpt/global/core/workflow/type';
|
||||||
|
import { SourceMemberType } from '../../support/user/type';
|
||||||
|
|
||||||
export type AppSchema = {
|
export type AppSchema = {
|
||||||
_id: string;
|
_id: string;
|
||||||
@@ -63,6 +64,7 @@ export type AppListItemType = {
|
|||||||
permission: AppPermission;
|
permission: AppPermission;
|
||||||
inheritPermission?: boolean;
|
inheritPermission?: boolean;
|
||||||
private?: boolean;
|
private?: boolean;
|
||||||
|
sourceMember: SourceMemberType;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AppDetailType = AppSchema & {
|
export type AppDetailType = AppSchema & {
|
||||||
|
|||||||
3
packages/global/core/app/version.d.ts
vendored
3
packages/global/core/app/version.d.ts
vendored
@@ -1,5 +1,7 @@
|
|||||||
|
import { TeamMemberStatusEnum } from 'support/user/team/constant';
|
||||||
import { StoreEdgeItemType } from '../workflow/type/edge';
|
import { StoreEdgeItemType } from '../workflow/type/edge';
|
||||||
import { AppChatConfigType, AppSchema } from './type';
|
import { AppChatConfigType, AppSchema } from './type';
|
||||||
|
import { SourceMemberType } from 'support/user/type';
|
||||||
|
|
||||||
export type AppVersionSchemaType = {
|
export type AppVersionSchemaType = {
|
||||||
_id: string;
|
_id: string;
|
||||||
@@ -20,4 +22,5 @@ export type VersionListItemType = {
|
|||||||
time: Date;
|
time: Date;
|
||||||
isPublish: boolean | undefined;
|
isPublish: boolean | undefined;
|
||||||
tmbId: string;
|
tmbId: string;
|
||||||
|
sourceMember: SourceMemberType;
|
||||||
};
|
};
|
||||||
|
|||||||
2
packages/global/core/dataset/type.d.ts
vendored
2
packages/global/core/dataset/type.d.ts
vendored
@@ -11,6 +11,7 @@ import {
|
|||||||
import { DatasetPermission } from '../../support/permission/dataset/controller';
|
import { DatasetPermission } from '../../support/permission/dataset/controller';
|
||||||
import { Permission } from '../../support/permission/controller';
|
import { Permission } from '../../support/permission/controller';
|
||||||
import { APIFileServer, FeishuServer, YuqueServer } from './apiDataset';
|
import { APIFileServer, FeishuServer, YuqueServer } from './apiDataset';
|
||||||
|
import { SourceMemberType } from 'support/user/type';
|
||||||
|
|
||||||
export type DatasetSchemaType = {
|
export type DatasetSchemaType = {
|
||||||
_id: string;
|
_id: string;
|
||||||
@@ -165,6 +166,7 @@ export type DatasetListItemType = {
|
|||||||
vectorModel: VectorModelItemType;
|
vectorModel: VectorModelItemType;
|
||||||
inheritPermission: boolean;
|
inheritPermission: boolean;
|
||||||
private?: boolean;
|
private?: boolean;
|
||||||
|
sourceMember?: SourceMemberType;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DatasetItemType = Omit<DatasetSchemaType, 'vectorModel' | 'agentModel'> & {
|
export type DatasetItemType = Omit<DatasetSchemaType, 'vectorModel' | 'agentModel'> & {
|
||||||
|
|||||||
1
packages/global/core/workflow/type/node.d.ts
vendored
1
packages/global/core/workflow/type/node.d.ts
vendored
@@ -89,6 +89,7 @@ export type NodeTemplateListItemType = {
|
|||||||
hasTokenFee?: boolean; // 是否配置积分
|
hasTokenFee?: boolean; // 是否配置积分
|
||||||
instructions?: string; // 使用说明
|
instructions?: string; // 使用说明
|
||||||
courseUrl?: string; // 教程链接
|
courseUrl?: string; // 教程链接
|
||||||
|
sourceMember?: SourceMember;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type NodeTemplateListType = {
|
export type NodeTemplateListType = {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ export type CreateTeamProps = {
|
|||||||
avatar?: string;
|
avatar?: string;
|
||||||
defaultTeam?: boolean;
|
defaultTeam?: boolean;
|
||||||
memberName?: string;
|
memberName?: string;
|
||||||
|
memberAvatar?: string;
|
||||||
};
|
};
|
||||||
export type UpdateTeamProps = Omit<ThirdPartyAccountType, 'externalWorkflowVariable'> & {
|
export type UpdateTeamProps = Omit<ThirdPartyAccountType, 'externalWorkflowVariable'> & {
|
||||||
name?: string;
|
name?: string;
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ export const OrgMemberCollectionName = 'team_org_members';
|
|||||||
|
|
||||||
export const getOrgChildrenPath = (org: OrgSchemaType) => `${org.path}/${org.pathId}`;
|
export const getOrgChildrenPath = (org: OrgSchemaType) => `${org.path}/${org.pathId}`;
|
||||||
|
|
||||||
// export enum OrgMemberRole {
|
export enum SyncOrgSourceEnum {
|
||||||
// owner = 'owner',
|
wecom = 'wecom'
|
||||||
// admin = 'admin',
|
}
|
||||||
// member = 'member'
|
|
||||||
// }
|
|
||||||
|
|||||||
1
packages/global/support/user/team/type.d.ts
vendored
1
packages/global/support/user/team/type.d.ts
vendored
@@ -44,6 +44,7 @@ export type TeamMemberSchema = {
|
|||||||
name: string;
|
name: string;
|
||||||
role: `${TeamMemberRoleEnum}`;
|
role: `${TeamMemberRoleEnum}`;
|
||||||
status: `${TeamMemberStatusEnum}`;
|
status: `${TeamMemberStatusEnum}`;
|
||||||
|
avatar: string;
|
||||||
defaultTeam: boolean;
|
defaultTeam: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
10
packages/global/support/user/type.d.ts
vendored
10
packages/global/support/user/type.d.ts
vendored
@@ -1,12 +1,12 @@
|
|||||||
import { TeamPermission } from '../permission/user/controller';
|
import { TeamPermission } from '../permission/user/controller';
|
||||||
import { UserStatusEnum } from './constant';
|
import { UserStatusEnum } from './constant';
|
||||||
|
import { TeamMemberStatusEnum } from './team/constant';
|
||||||
import { TeamTmbItemType } from './team/type';
|
import { TeamTmbItemType } from './team/type';
|
||||||
|
|
||||||
export type UserModelSchema = {
|
export type UserModelSchema = {
|
||||||
_id: string;
|
_id: string;
|
||||||
username: string;
|
username: string;
|
||||||
password: string;
|
password: string;
|
||||||
avatar: string;
|
|
||||||
promotionRate: number;
|
promotionRate: number;
|
||||||
inviterId?: string;
|
inviterId?: string;
|
||||||
openaiKey: string;
|
openaiKey: string;
|
||||||
@@ -22,7 +22,7 @@ export type UserModelSchema = {
|
|||||||
export type UserType = {
|
export type UserType = {
|
||||||
_id: string;
|
_id: string;
|
||||||
username: string;
|
username: string;
|
||||||
avatar: string;
|
avatar: string; // it should be team member's avatar after 4.8.18
|
||||||
timezone: string;
|
timezone: string;
|
||||||
promotionRate: UserModelSchema['promotionRate'];
|
promotionRate: UserModelSchema['promotionRate'];
|
||||||
team: TeamTmbItemType;
|
team: TeamTmbItemType;
|
||||||
@@ -30,3 +30,9 @@ export type UserType = {
|
|||||||
notificationAccount?: string;
|
notificationAccount?: string;
|
||||||
permission: TeamPermission;
|
permission: TeamPermission;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type SourceMemberType = {
|
||||||
|
name: string;
|
||||||
|
avatar: string;
|
||||||
|
status: `${TeamMemberStatusEnum}`;
|
||||||
|
};
|
||||||
|
|||||||
21
packages/service/common/api/pagination.ts
Normal file
21
packages/service/common/api/pagination.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
|
||||||
|
import { ApiRequestProps } from '../../type/next';
|
||||||
|
|
||||||
|
export function parsePaginationRequest(req: ApiRequestProps) {
|
||||||
|
const {
|
||||||
|
pageSize = 10,
|
||||||
|
pageNum = 1,
|
||||||
|
offset = 0
|
||||||
|
} = Object.keys(req.body).includes('pageSize')
|
||||||
|
? req.body
|
||||||
|
: Object.keys(req.query).includes('pageSize')
|
||||||
|
? req.query
|
||||||
|
: {};
|
||||||
|
if (!pageSize || (pageNum === undefined && offset === undefined)) {
|
||||||
|
throw new Error(CommonErrEnum.missingParams);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
pageSize: Number(pageSize),
|
||||||
|
offset: offset ? Number(offset) : (Number(pageNum) - 1) * Number(pageSize)
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ import type { NextApiResponse, NextApiRequest } from 'next';
|
|||||||
import NextCors from 'nextjs-cors';
|
import NextCors from 'nextjs-cors';
|
||||||
|
|
||||||
export async function withNextCors(req: NextApiRequest, res: NextApiResponse) {
|
export async function withNextCors(req: NextApiRequest, res: NextApiResponse) {
|
||||||
const methods = ['GET', 'eHEAD', 'PUT', 'PATCH', 'POST', 'DELETE'];
|
const methods = ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE'];
|
||||||
|
|
||||||
const allowedOrigins = process.env.ALLOWED_ORIGINS?.split(',');
|
const allowedOrigins = process.env.ALLOWED_ORIGINS?.split(',');
|
||||||
const origin = req.headers.origin;
|
const origin = req.headers.origin;
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import { ParentIdType } from '@fastgpt/global/common/parentFolder/type';
|
|||||||
import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
|
import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
|
||||||
import { MemberGroupSchemaType } from '@fastgpt/global/support/permission/memberGroup/type';
|
import { MemberGroupSchemaType } from '@fastgpt/global/support/permission/memberGroup/type';
|
||||||
import { TeamMemberSchema } from '@fastgpt/global/support/user/team/type';
|
import { TeamMemberSchema } from '@fastgpt/global/support/user/team/type';
|
||||||
import { UserModelSchema } from '@fastgpt/global/support/user/type';
|
|
||||||
import { OrgSchemaType } from '@fastgpt/global/support/user/team/org/type';
|
import { OrgSchemaType } from '@fastgpt/global/support/user/team/org/type';
|
||||||
import { getOrgIdSetWithParentByTmbId } from './org/controllers';
|
import { getOrgIdSetWithParentByTmbId } from './org/controllers';
|
||||||
|
|
||||||
@@ -151,13 +150,9 @@ export const getClbsAndGroupsWithInfo = async ({
|
|||||||
$exists: true
|
$exists: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.populate<{ tmb: TeamMemberSchema & { user: UserModelSchema } }>({
|
.populate<{ tmb: TeamMemberSchema }>({
|
||||||
path: 'tmb',
|
path: 'tmb',
|
||||||
select: 'name userId role',
|
select: 'name userId avatar'
|
||||||
populate: {
|
|
||||||
path: 'user',
|
|
||||||
select: 'avatar'
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.lean(),
|
.lean(),
|
||||||
MongoResourcePermission.find({
|
MongoResourcePermission.find({
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export async function getUserDetail({
|
|||||||
return {
|
return {
|
||||||
_id: user._id,
|
_id: user._id,
|
||||||
username: user.username,
|
username: user.username,
|
||||||
avatar: user.avatar,
|
avatar: tmb.avatar,
|
||||||
timezone: user.timezone,
|
timezone: user.timezone,
|
||||||
promotionRate: user.promotionRate,
|
promotionRate: user.promotionRate,
|
||||||
team: tmb,
|
team: tmb,
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ const { Schema } = connectionMongo;
|
|||||||
import { hashStr } from '@fastgpt/global/common/string/tools';
|
import { hashStr } from '@fastgpt/global/common/string/tools';
|
||||||
import type { UserModelSchema } from '@fastgpt/global/support/user/type';
|
import type { UserModelSchema } from '@fastgpt/global/support/user/type';
|
||||||
import { UserStatusEnum, userStatusMap } from '@fastgpt/global/support/user/constant';
|
import { UserStatusEnum, userStatusMap } from '@fastgpt/global/support/user/constant';
|
||||||
import { getRandomUserAvatar } from '@fastgpt/global/support/user/utils';
|
|
||||||
|
|
||||||
export const userCollectionName = 'users';
|
export const userCollectionName = 'users';
|
||||||
|
|
||||||
@@ -33,11 +32,6 @@ const UserSchema = new Schema({
|
|||||||
type: Date,
|
type: Date,
|
||||||
default: () => new Date()
|
default: () => new Date()
|
||||||
},
|
},
|
||||||
avatar: {
|
|
||||||
type: String,
|
|
||||||
default: () => getRandomUserAvatar()
|
|
||||||
},
|
|
||||||
|
|
||||||
promotionRate: {
|
promotionRate: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 15
|
default: 15
|
||||||
@@ -62,7 +56,10 @@ const UserSchema = new Schema({
|
|||||||
ref: userCollectionName
|
ref: userCollectionName
|
||||||
},
|
},
|
||||||
fastgpt_sem: Object,
|
fastgpt_sem: Object,
|
||||||
sourceDomain: String
|
sourceDomain: String,
|
||||||
|
|
||||||
|
/** @deprecated */
|
||||||
|
avatar: String
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ async function getTeamMember(match: Record<string, any>): Promise<TeamTmbItemTyp
|
|||||||
teamAvatar: tmb.team.avatar,
|
teamAvatar: tmb.team.avatar,
|
||||||
teamName: tmb.team.name,
|
teamName: tmb.team.name,
|
||||||
memberName: tmb.name,
|
memberName: tmb.name,
|
||||||
avatar: tmb.team.avatar,
|
avatar: tmb.avatar,
|
||||||
balance: tmb.team.balance,
|
balance: tmb.team.balance,
|
||||||
tmbId: String(tmb._id),
|
tmbId: String(tmb._id),
|
||||||
teamDomain: tmb.team?.teamDomain,
|
teamDomain: tmb.team?.teamDomain,
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
TeamMemberCollectionName,
|
TeamMemberCollectionName,
|
||||||
TeamCollectionName
|
TeamCollectionName
|
||||||
} from '@fastgpt/global/support/user/team/constant';
|
} from '@fastgpt/global/support/user/team/constant';
|
||||||
|
import { getRandomUserAvatar } from '@fastgpt/global/support/user/utils';
|
||||||
|
|
||||||
const TeamMemberSchema = new Schema({
|
const TeamMemberSchema = new Schema({
|
||||||
teamId: {
|
teamId: {
|
||||||
@@ -35,11 +36,14 @@ const TeamMemberSchema = new Schema({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
avatar: {
|
||||||
|
type: String,
|
||||||
|
default: getRandomUserAvatar()
|
||||||
|
},
|
||||||
|
|
||||||
// Abandoned
|
// Abandoned
|
||||||
role: {
|
role: {
|
||||||
type: String
|
type: String
|
||||||
// enum: Object.keys(TeamMemberRoleMap) // disable enum validation for old data
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
15
packages/web/common/fetch/type.d.ts
vendored
15
packages/web/common/fetch/type.d.ts
vendored
@@ -1,8 +1,13 @@
|
|||||||
export type PaginationProps<T = {}> = T & {
|
import { RequireOnlyOne } from '@fastgpt/global/common/type/utils';
|
||||||
offset: number;
|
|
||||||
pageSize: number;
|
type PaginationProps<T = {}> = T & {
|
||||||
};
|
pageSize: number | string;
|
||||||
export type PaginationResponse<T = any> = {
|
} & RequireOnlyOne<{
|
||||||
|
offset: number | string;
|
||||||
|
pageNum: number | string;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
type PaginationResponse<T = {}> = {
|
||||||
total: number;
|
total: number;
|
||||||
list: T[];
|
list: T[];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,7 +21,15 @@ import type { ButtonProps, MenuItemProps } from '@chakra-ui/react';
|
|||||||
import MyIcon from '../Icon';
|
import MyIcon from '../Icon';
|
||||||
import { useRequest2 } from '../../../hooks/useRequest';
|
import { useRequest2 } from '../../../hooks/useRequest';
|
||||||
import MyDivider from '../MyDivider';
|
import MyDivider from '../MyDivider';
|
||||||
|
import { useScrollPagination } from '../../../hooks/useScrollPagination';
|
||||||
|
|
||||||
|
/** 选择组件 Props 类型
|
||||||
|
* value: 选中的值
|
||||||
|
* placeholder: 占位符
|
||||||
|
* list: 列表数据
|
||||||
|
* isLoading: 是否加载中
|
||||||
|
* ScrollData: 分页滚动数据控制器 [useScrollPagination] 的返回值
|
||||||
|
* */
|
||||||
export type SelectProps<T = any> = ButtonProps & {
|
export type SelectProps<T = any> = ButtonProps & {
|
||||||
value?: T;
|
value?: T;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
@@ -34,6 +42,7 @@ export type SelectProps<T = any> = ButtonProps & {
|
|||||||
}[];
|
}[];
|
||||||
isLoading?: boolean;
|
isLoading?: boolean;
|
||||||
onchange?: (val: T) => any | Promise<any>;
|
onchange?: (val: T) => any | Promise<any>;
|
||||||
|
ScrollData?: ReturnType<typeof useScrollPagination>['ScrollData'];
|
||||||
};
|
};
|
||||||
|
|
||||||
const MySelect = <T = any,>(
|
const MySelect = <T = any,>(
|
||||||
@@ -44,6 +53,7 @@ const MySelect = <T = any,>(
|
|||||||
list = [],
|
list = [],
|
||||||
onchange,
|
onchange,
|
||||||
isLoading = false,
|
isLoading = false,
|
||||||
|
ScrollData,
|
||||||
...props
|
...props
|
||||||
}: SelectProps<T>,
|
}: SelectProps<T>,
|
||||||
ref: ForwardedRef<{
|
ref: ForwardedRef<{
|
||||||
@@ -154,7 +164,8 @@ const MySelect = <T = any,>(
|
|||||||
maxH={'40vh'}
|
maxH={'40vh'}
|
||||||
overflowY={'auto'}
|
overflowY={'auto'}
|
||||||
>
|
>
|
||||||
{list.map((item, i) => (
|
{(() => {
|
||||||
|
const component = list.map((item, i) => (
|
||||||
<Box key={i}>
|
<Box key={i}>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
{...menuItemStyles}
|
{...menuItemStyles}
|
||||||
@@ -186,7 +197,12 @@ const MySelect = <T = any,>(
|
|||||||
</MenuItem>
|
</MenuItem>
|
||||||
{item.showBorder && <MyDivider my={2} />}
|
{item.showBorder && <MyDivider my={2} />}
|
||||||
</Box>
|
</Box>
|
||||||
))}
|
));
|
||||||
|
if (ScrollData) {
|
||||||
|
return <ScrollData>{component}</ScrollData>;
|
||||||
|
}
|
||||||
|
return component;
|
||||||
|
})()}
|
||||||
</MenuList>
|
</MenuList>
|
||||||
</Menu>
|
</Menu>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
23
packages/web/components/common/UserBox/index.tsx
Normal file
23
packages/web/components/common/UserBox/index.tsx
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { Box, HStack, type StackProps } from '@chakra-ui/react';
|
||||||
|
import { SourceMemberType } from '@fastgpt/global/support/user/type';
|
||||||
|
import React from 'react';
|
||||||
|
import Avatar from '../Avatar';
|
||||||
|
import { useTranslation } from 'next-i18next';
|
||||||
|
import Tag from '../Tag';
|
||||||
|
|
||||||
|
export type UserBoxProps = {
|
||||||
|
sourceMember: SourceMemberType;
|
||||||
|
avatarSize?: string;
|
||||||
|
} & StackProps;
|
||||||
|
function UserBox({ sourceMember, avatarSize = '1.25rem', ...props }: UserBoxProps) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
return (
|
||||||
|
<HStack space="1" {...props}>
|
||||||
|
<Avatar src={sourceMember.avatar} w={avatarSize} />
|
||||||
|
<Box>{sourceMember.name}</Box>
|
||||||
|
{sourceMember.status === 'leave' && <Tag color="gray">{t('account_team:leaved')}</Tag>}
|
||||||
|
</HStack>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default React.memo(UserBox);
|
||||||
@@ -4,7 +4,6 @@ import { ArrowBackIcon, ArrowForwardIcon } from '@chakra-ui/icons';
|
|||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { useToast } from './useToast';
|
import { useToast } from './useToast';
|
||||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
useBoolean,
|
useBoolean,
|
||||||
useLockFn,
|
useLockFn,
|
||||||
@@ -14,19 +13,15 @@ import {
|
|||||||
useThrottleEffect
|
useThrottleEffect
|
||||||
} from 'ahooks';
|
} from 'ahooks';
|
||||||
|
|
||||||
|
import { PaginationProps, PaginationResponse } from '../common/fetch/type';
|
||||||
|
|
||||||
const thresholdVal = 200;
|
const thresholdVal = 200;
|
||||||
|
|
||||||
type PagingData<T> = {
|
export function usePagination<DataT, ResT = {}>(
|
||||||
pageNum: number;
|
api: (data: PaginationProps<DataT>) => Promise<PaginationResponse<ResT>>,
|
||||||
pageSize: number;
|
{
|
||||||
data: T[];
|
|
||||||
total?: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function usePagination<ResT = any>({
|
|
||||||
api,
|
|
||||||
pageSize = 10,
|
pageSize = 10,
|
||||||
params = {},
|
params,
|
||||||
defaultRequest = true,
|
defaultRequest = true,
|
||||||
type = 'button',
|
type = 'button',
|
||||||
onChange,
|
onChange,
|
||||||
@@ -34,9 +29,8 @@ export function usePagination<ResT = any>({
|
|||||||
scrollLoadType = 'bottom',
|
scrollLoadType = 'bottom',
|
||||||
EmptyTip
|
EmptyTip
|
||||||
}: {
|
}: {
|
||||||
api: (data: any) => Promise<PagingData<ResT>>;
|
|
||||||
pageSize?: number;
|
pageSize?: number;
|
||||||
params?: Record<string, any>;
|
params?: DataT;
|
||||||
defaultRequest?: boolean;
|
defaultRequest?: boolean;
|
||||||
type?: 'button' | 'scroll';
|
type?: 'button' | 'scroll';
|
||||||
onChange?: (pageNum: number) => void;
|
onChange?: (pageNum: number) => void;
|
||||||
@@ -44,7 +38,8 @@ export function usePagination<ResT = any>({
|
|||||||
throttleWait?: number;
|
throttleWait?: number;
|
||||||
scrollLoadType?: 'top' | 'bottom';
|
scrollLoadType?: 'top' | 'bottom';
|
||||||
EmptyTip?: React.JSX.Element;
|
EmptyTip?: React.JSX.Element;
|
||||||
}) {
|
}
|
||||||
|
) {
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
@@ -64,7 +59,7 @@ export function usePagination<ResT = any>({
|
|||||||
setTrue();
|
setTrue();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res: PagingData<ResT> = await api({
|
const res = await api({
|
||||||
pageNum: num,
|
pageNum: num,
|
||||||
pageSize,
|
pageSize,
|
||||||
...params
|
...params
|
||||||
@@ -93,13 +88,13 @@ export function usePagination<ResT = any>({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
setData((prevData) => (num === 1 ? res.data : [...res.data, ...prevData]));
|
setData((prevData) => (num === 1 ? res.list : [...res.list, ...prevData]));
|
||||||
adjustScrollPosition();
|
adjustScrollPosition();
|
||||||
} else {
|
} else {
|
||||||
setData((prevData) => (num === 1 ? res.data : [...prevData, ...res.data]));
|
setData((prevData) => (num === 1 ? res.list : [...prevData, ...res.list]));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setData(res.data);
|
setData(res.list);
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange?.(num);
|
onChange?.(num);
|
||||||
|
|||||||
@@ -35,5 +35,9 @@
|
|||||||
"user_team_invite_member": "邀请成员",
|
"user_team_invite_member": "邀请成员",
|
||||||
"user_team_leave_team": "离开团队",
|
"user_team_leave_team": "离开团队",
|
||||||
"user_team_leave_team_failed": "离开团队失败",
|
"user_team_leave_team_failed": "离开团队失败",
|
||||||
"waiting": "待接受"
|
"leaved": "已离职",
|
||||||
|
"waiting": "待接受",
|
||||||
|
"sync_immediately": "立即同步",
|
||||||
|
"sync_member_failed": "同步成员失败",
|
||||||
|
"sync_member_success": "同步成员成功"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ const InputGuideConfig = ({
|
|||||||
onChange: (e: ChatInputGuideConfigType) => void;
|
onChange: (e: ChatInputGuideConfigType) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { chatT, commonT } = useI18n();
|
const { chatT } = useI18n();
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
const {
|
const {
|
||||||
isOpen: isOpenLexiconConfig,
|
isOpen: isOpenLexiconConfig,
|
||||||
@@ -220,7 +220,7 @@ const LexiconConfigModal = ({ appId, onClose }: { appId: string; onClose: () =>
|
|||||||
});
|
});
|
||||||
|
|
||||||
const { run: createNewData, loading: isCreating } = useRequest2(
|
const { run: createNewData, loading: isCreating } = useRequest2(
|
||||||
(textList: string[]) => {
|
async (textList: string[]) => {
|
||||||
if (textList.filter(Boolean).length === 0) {
|
if (textList.filter(Boolean).length === 0) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
import { getTeamMembers } from '@/web/support/user/team/api';
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Flex,
|
Flex,
|
||||||
@@ -15,6 +15,7 @@ import Icon from '@fastgpt/web/components/common/Icon';
|
|||||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||||
import MyTag from '@fastgpt/web/components/common/Tag';
|
import MyTag from '@fastgpt/web/components/common/Tag';
|
||||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||||
|
import { useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
@@ -31,13 +32,12 @@ export function ChangeOwnerModal({
|
|||||||
onChangeOwner
|
onChangeOwner
|
||||||
}: ChangeOwnerModalProps & { onClose: () => void }) {
|
}: ChangeOwnerModalProps & { onClose: () => void }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { loadAndGetTeamMembers } = useUserStore();
|
|
||||||
|
|
||||||
const [inputValue, setInputValue] = React.useState('');
|
const [inputValue, setInputValue] = React.useState('');
|
||||||
|
|
||||||
const { data: teamMembers = [] } = useRequest2(loadAndGetTeamMembers, {
|
const { data: teamMembers, ScrollData } = useScrollPagination(getTeamMembers, {
|
||||||
manual: false
|
pageSize: 15
|
||||||
});
|
});
|
||||||
|
|
||||||
const memberList = teamMembers.filter((item) => {
|
const memberList = teamMembers.filter((item) => {
|
||||||
return item.memberName.includes(inputValue);
|
return item.memberName.includes(inputValue);
|
||||||
});
|
});
|
||||||
@@ -101,11 +101,6 @@ export function ChangeOwnerModal({
|
|||||||
onOpenMemberListMenu();
|
onOpenMemberListMenu();
|
||||||
setSelectedMember(null);
|
setSelectedMember(null);
|
||||||
}}
|
}}
|
||||||
// onBlur={() => {
|
|
||||||
// setTimeout(() => {
|
|
||||||
// onCloseMemberListMenu();
|
|
||||||
// }, 10);
|
|
||||||
// }}
|
|
||||||
{...(selectedMember && { pl: '10' })}
|
{...(selectedMember && { pl: '10' })}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
@@ -123,6 +118,7 @@ export function ChangeOwnerModal({
|
|||||||
maxH={'300px'}
|
maxH={'300px'}
|
||||||
overflow={'auto'}
|
overflow={'auto'}
|
||||||
>
|
>
|
||||||
|
<ScrollData>
|
||||||
{memberList.map((item) => (
|
{memberList.map((item) => (
|
||||||
<Box
|
<Box
|
||||||
key={item.tmbId}
|
key={item.tmbId}
|
||||||
@@ -143,6 +139,7 @@ export function ChangeOwnerModal({
|
|||||||
</Flex>
|
</Flex>
|
||||||
</Box>
|
</Box>
|
||||||
))}
|
))}
|
||||||
|
</ScrollData>
|
||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ import { ParentTreePathItemType } from '@fastgpt/global/common/parentFolder/type
|
|||||||
import { OrgType } from '@fastgpt/global/support/user/team/org/type';
|
import { OrgType } from '@fastgpt/global/support/user/team/org/type';
|
||||||
import { useContextSelector } from 'use-context-selector';
|
import { useContextSelector } from 'use-context-selector';
|
||||||
import { CollaboratorContext } from './context';
|
import { CollaboratorContext } from './context';
|
||||||
|
import { getTeamMembers } from '@/web/support/user/team/api';
|
||||||
|
import { getGroupList } from '@/web/support/user/team/group/api';
|
||||||
|
import { getOrgList } from '@/web/support/user/team/org/api';
|
||||||
|
import { useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination';
|
||||||
|
|
||||||
const HoverBoxStyle = {
|
const HoverBoxStyle = {
|
||||||
bgColor: 'myGray.50',
|
bgColor: 'myGray.50',
|
||||||
@@ -47,22 +51,18 @@ function MemberModal({
|
|||||||
addPermissionOnly?: boolean;
|
addPermissionOnly?: boolean;
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { userInfo, loadAndGetTeamMembers, loadAndGetGroups, loadAndGetOrgs } = useUserStore();
|
const { userInfo, myGroups } = useUserStore();
|
||||||
|
|
||||||
const collaboratorList = useContextSelector(CollaboratorContext, (v) => v.collaboratorList);
|
const collaboratorList = useContextSelector(CollaboratorContext, (v) => v.collaboratorList);
|
||||||
|
|
||||||
const [searchText, setSearchText] = useState<string>('');
|
const [searchText, setSearchText] = useState<string>('');
|
||||||
const [filterClass, setFilterClass] = useState<'member' | 'org' | 'group'>();
|
const [filterClass, setFilterClass] = useState<'member' | 'org' | 'group'>();
|
||||||
|
const { data: members, ScrollData } = useScrollPagination(getTeamMembers, {
|
||||||
|
pageSize: 15
|
||||||
|
});
|
||||||
|
|
||||||
const { data: [members = [], groups = [], orgs = []] = [], loading: loadingMembersAndGroups } =
|
const { data: [groups = [], orgs = []] = [], loading: loadingGroupsAndOrgs } = useRequest2(
|
||||||
useRequest2(
|
|
||||||
async () => {
|
async () => {
|
||||||
if (!userInfo?.team?.teamId) return [[], []];
|
if (!userInfo?.team?.teamId) return [[], []];
|
||||||
return Promise.all([
|
return Promise.all([getGroupList(), getOrgList()]);
|
||||||
loadAndGetTeamMembers(true),
|
|
||||||
loadAndGetGroups(true),
|
|
||||||
loadAndGetOrgs(true)
|
|
||||||
]);
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
manual: false,
|
manual: false,
|
||||||
@@ -71,6 +71,7 @@ function MemberModal({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const [parentPath, setParentPath] = useState('');
|
const [parentPath, setParentPath] = useState('');
|
||||||
|
|
||||||
const paths = useMemo(() => {
|
const paths = useMemo(() => {
|
||||||
const splitPath = parentPath.split('/').filter(Boolean);
|
const splitPath = parentPath.split('/').filter(Boolean);
|
||||||
return splitPath
|
return splitPath
|
||||||
@@ -212,7 +213,7 @@ function MemberModal({
|
|||||||
h={'100%'}
|
h={'100%'}
|
||||||
maxH={'90vh'}
|
maxH={'90vh'}
|
||||||
isCentered
|
isCentered
|
||||||
isLoading={loadingMembersAndGroups}
|
isLoading={loadingGroupsAndOrgs}
|
||||||
>
|
>
|
||||||
<ModalBody flex={'1'}>
|
<ModalBody flex={'1'}>
|
||||||
<Grid
|
<Grid
|
||||||
@@ -299,11 +300,9 @@ function MemberModal({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<Flex flexDirection={'column'} gap={1} userSelect={'none'}>
|
<Flex flexDirection={'column'} gap={1} userSelect={'none'}>
|
||||||
|
<ScrollData>
|
||||||
{filterMembers.map((member) => {
|
{filterMembers.map((member) => {
|
||||||
const collaborator = collaboratorList?.find((v) => v.tmbId === member.tmbId);
|
|
||||||
const disabled = addOnly && collaborator !== undefined;
|
|
||||||
const onChange = () => {
|
const onChange = () => {
|
||||||
if (disabled) return;
|
|
||||||
setSelectedMembers((state) => {
|
setSelectedMembers((state) => {
|
||||||
if (state.includes(member.tmbId)) {
|
if (state.includes(member.tmbId)) {
|
||||||
return state.filter((v) => v !== member.tmbId);
|
return state.filter((v) => v !== member.tmbId);
|
||||||
@@ -311,6 +310,7 @@ function MemberModal({
|
|||||||
return [...state, member.tmbId];
|
return [...state, member.tmbId];
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
const collaborator = collaboratorList?.find((v) => v.tmbId === member.tmbId);
|
||||||
return (
|
return (
|
||||||
<HStack
|
<HStack
|
||||||
justifyContent="space-between"
|
justifyContent="space-between"
|
||||||
@@ -323,25 +323,19 @@ function MemberModal({
|
|||||||
onClick={onChange}
|
onClick={onChange}
|
||||||
>
|
>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
isDisabled={disabled}
|
isChecked={selectedMemberIdList.includes(member.tmbId)}
|
||||||
isChecked={disabled || selectedMemberIdList.includes(member.tmbId)}
|
|
||||||
pointerEvents="none"
|
pointerEvents="none"
|
||||||
/>
|
/>
|
||||||
<MyAvatar src={member.avatar} w="1.5rem" borderRadius={'50%'} />
|
<MyAvatar src={member.avatar} w="1.5rem" borderRadius={'50%'} />
|
||||||
<Box w="full" ml="2">
|
<Box w="full" ml="2">
|
||||||
{member.memberName}
|
{member.memberName}
|
||||||
</Box>
|
</Box>
|
||||||
<PermissionTags
|
<PermissionTags permission={collaborator?.permission.value} />
|
||||||
permission={addOnly ? undefined : collaborator?.permission.value}
|
|
||||||
/>
|
|
||||||
</HStack>
|
</HStack>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
{filterOrgs.map((org) => {
|
{filterOrgs.map((org) => {
|
||||||
const collaborator = collaboratorList?.find((v) => v.orgId === org._id);
|
|
||||||
const disabled = addOnly && collaborator !== undefined;
|
|
||||||
const onChange = () => {
|
const onChange = () => {
|
||||||
if (disabled) return;
|
|
||||||
setSelectedOrgIdList((state) => {
|
setSelectedOrgIdList((state) => {
|
||||||
if (state.includes(org._id)) {
|
if (state.includes(org._id)) {
|
||||||
return state.filter((v) => v !== org._id);
|
return state.filter((v) => v !== org._id);
|
||||||
@@ -349,6 +343,7 @@ function MemberModal({
|
|||||||
return [...state, org._id];
|
return [...state, org._id];
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
const collaborator = collaboratorList?.find((v) => v.orgId === org._id);
|
||||||
return (
|
return (
|
||||||
<HStack
|
<HStack
|
||||||
justifyContent="space-between"
|
justifyContent="space-between"
|
||||||
@@ -361,22 +356,21 @@ function MemberModal({
|
|||||||
onClick={onChange}
|
onClick={onChange}
|
||||||
>
|
>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
isDisabled={disabled}
|
isChecked={selectedOrgIdList.includes(org._id)}
|
||||||
isChecked={disabled || selectedOrgIdList.includes(org._id)}
|
|
||||||
pointerEvents="none"
|
pointerEvents="none"
|
||||||
/>
|
/>
|
||||||
<MyAvatar src={org.avatar} w="1.5rem" borderRadius={'50%'} />
|
<MyAvatar src={org.avatar} w="1.5rem" borderRadius={'50%'} />
|
||||||
<HStack ml="2" w="full" gap="5px">
|
<HStack ml="2" w="full" gap="5px">
|
||||||
<Text>{org.name}</Text>
|
<Text>{org.name}</Text>
|
||||||
{org.count && (
|
{org.count && (
|
||||||
|
<>
|
||||||
<Tag size="sm" my="auto">
|
<Tag size="sm" my="auto">
|
||||||
{org.count}
|
{org.count}
|
||||||
</Tag>
|
</Tag>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</HStack>
|
</HStack>
|
||||||
<PermissionTags
|
<PermissionTags permission={collaborator?.permission.value} />
|
||||||
permission={addOnly ? undefined : collaborator?.permission.value}
|
|
||||||
/>
|
|
||||||
{org.count && (
|
{org.count && (
|
||||||
<MyIcon
|
<MyIcon
|
||||||
name="core/chat/chevronRight"
|
name="core/chat/chevronRight"
|
||||||
@@ -386,8 +380,7 @@ function MemberModal({
|
|||||||
_hover={{
|
_hover={{
|
||||||
bgColor: 'myGray.200'
|
bgColor: 'myGray.200'
|
||||||
}}
|
}}
|
||||||
onClick={(e) => {
|
onClick={() => {
|
||||||
e.stopPropagation();
|
|
||||||
setParentPath(getOrgChildrenPath(org));
|
setParentPath(getOrgChildrenPath(org));
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -396,10 +389,7 @@ function MemberModal({
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
{filterGroups.map((group) => {
|
{filterGroups.map((group) => {
|
||||||
const collaborator = collaboratorList?.find((v) => v.groupId === group._id);
|
|
||||||
const disabled = addOnly && collaborator !== undefined;
|
|
||||||
const onChange = () => {
|
const onChange = () => {
|
||||||
if (disabled) return;
|
|
||||||
setSelectedGroupIdList((state) => {
|
setSelectedGroupIdList((state) => {
|
||||||
if (state.includes(group._id)) {
|
if (state.includes(group._id)) {
|
||||||
return state.filter((v) => v !== group._id);
|
return state.filter((v) => v !== group._id);
|
||||||
@@ -407,6 +397,7 @@ function MemberModal({
|
|||||||
return [...state, group._id];
|
return [...state, group._id];
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
const collaborator = collaboratorList?.find((v) => v.groupId === group._id);
|
||||||
return (
|
return (
|
||||||
<HStack
|
<HStack
|
||||||
justifyContent="space-between"
|
justifyContent="space-between"
|
||||||
@@ -419,20 +410,18 @@ function MemberModal({
|
|||||||
onClick={onChange}
|
onClick={onChange}
|
||||||
>
|
>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
isDisabled={disabled}
|
isChecked={selectedGroupIdList.includes(group._id)}
|
||||||
isChecked={disabled || selectedGroupIdList.includes(group._id)}
|
|
||||||
pointerEvents="none"
|
pointerEvents="none"
|
||||||
/>
|
/>
|
||||||
<MyAvatar src={group.avatar} w="1.5rem" borderRadius={'50%'} />
|
<MyAvatar src={group.avatar} w="1.5rem" borderRadius={'50%'} />
|
||||||
<Box ml="2" w="full">
|
<Box ml="2" w="full">
|
||||||
{group.name === DefaultGroupName ? userInfo?.team.teamName : group.name}
|
{group.name === DefaultGroupName ? userInfo?.team.teamName : group.name}
|
||||||
</Box>
|
</Box>
|
||||||
<PermissionTags
|
<PermissionTags permission={collaborator?.permission.value} />
|
||||||
permission={addOnly ? undefined : collaborator?.permission.value}
|
|
||||||
/>
|
|
||||||
</HStack>
|
</HStack>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
</ScrollData>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|||||||
6
projects/app/src/global/core/api/appReq.d.ts
vendored
6
projects/app/src/global/core/api/appReq.d.ts
vendored
@@ -1,7 +1,7 @@
|
|||||||
import { RequestPaging } from '@/types';
|
import { PaginationProps } from '@fastgpt/web/common/fetch/type';
|
||||||
|
|
||||||
export type GetAppChatLogsParams = RequestPaging & {
|
export type GetAppChatLogsParams = PaginationProps<{
|
||||||
appId: string;
|
appId: string;
|
||||||
dateStart: Date;
|
dateStart: Date;
|
||||||
dateEnd: Date;
|
dateEnd: Date;
|
||||||
};
|
}>;
|
||||||
|
|||||||
@@ -3,24 +3,24 @@ import {
|
|||||||
DatasetCollectionTypeEnum,
|
DatasetCollectionTypeEnum,
|
||||||
DatasetTypeEnum
|
DatasetTypeEnum
|
||||||
} from '@fastgpt/global/core/dataset/constants';
|
} from '@fastgpt/global/core/dataset/constants';
|
||||||
import type { RequestPaging } from '@/types';
|
|
||||||
import { TrainingModeEnum } from '@fastgpt/global/core/dataset/constants';
|
import { TrainingModeEnum } from '@fastgpt/global/core/dataset/constants';
|
||||||
import type { SearchTestItemType } from '@/types/core/dataset';
|
import type { SearchTestItemType } from '@/types/core/dataset';
|
||||||
import { UploadChunkItemType } from '@fastgpt/global/core/dataset/type';
|
import { UploadChunkItemType } from '@fastgpt/global/core/dataset/type';
|
||||||
import { DatasetCollectionSchemaType } from '@fastgpt/global/core/dataset/type';
|
import { DatasetCollectionSchemaType } from '@fastgpt/global/core/dataset/type';
|
||||||
import { PermissionTypeEnum } from '@fastgpt/global/support/permission/constant';
|
import { PermissionTypeEnum } from '@fastgpt/global/support/permission/constant';
|
||||||
import type { LLMModelItemType } from '@fastgpt/global/core/ai/model.d';
|
import type { LLMModelItemType } from '@fastgpt/global/core/ai/model.d';
|
||||||
|
import { PaginationProps } from '@fastgpt/web/common/fetch/type';
|
||||||
|
|
||||||
/* ===== dataset ===== */
|
/* ===== dataset ===== */
|
||||||
|
|
||||||
/* ======= collections =========== */
|
/* ======= collections =========== */
|
||||||
export type GetDatasetCollectionsProps = RequestPaging & {
|
export type GetDatasetCollectionsProps = PaginationProps<{
|
||||||
datasetId: string;
|
datasetId: string;
|
||||||
parentId?: string;
|
parentId?: string;
|
||||||
searchText?: string;
|
searchText?: string;
|
||||||
filterTags?: string[];
|
filterTags?: string[];
|
||||||
simple?: boolean;
|
simple?: boolean;
|
||||||
selectFolder?: boolean;
|
selectFolder?: boolean;
|
||||||
};
|
}>;
|
||||||
|
|
||||||
/* ==== data ===== */
|
/* ==== data ===== */
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useCallback, useMemo, useEffect } from 'react';
|
import React, { useState, useMemo, useEffect } from 'react';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Table,
|
Table,
|
||||||
@@ -25,7 +25,6 @@ import {
|
|||||||
billStatusMap,
|
billStatusMap,
|
||||||
billTypeMap
|
billTypeMap
|
||||||
} from '@fastgpt/global/support/wallet/bill/constants';
|
} from '@fastgpt/global/support/wallet/bill/constants';
|
||||||
// import { usePagination } from '@/web/common/hooks/usePagination';
|
|
||||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||||
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
||||||
import { standardSubLevelMap, subModeMap } from '@fastgpt/global/support/wallet/sub/constants';
|
import { standardSubLevelMap, subModeMap } from '@fastgpt/global/support/wallet/sub/constants';
|
||||||
@@ -33,25 +32,23 @@ import MySelect from '@fastgpt/web/components/common/MySelect';
|
|||||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||||
import { usePagination } from '@fastgpt/web/hooks/usePagination';
|
import { usePagination } from '@fastgpt/web/hooks/usePagination';
|
||||||
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
|
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
|
||||||
import { useI18n } from '@/web/context/I18n';
|
|
||||||
const BillTable = () => {
|
const BillTable = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { commonT } = useI18n();
|
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const [billType, setBillType] = useState<BillTypeEnum | ''>('');
|
const [billType, setBillType] = useState<BillTypeEnum | undefined>(undefined);
|
||||||
const [billDetail, setBillDetail] = useState<BillSchemaType>();
|
const [billDetail, setBillDetail] = useState<BillSchemaType>();
|
||||||
|
|
||||||
const billTypeList = useMemo(
|
const billTypeList = useMemo(
|
||||||
() =>
|
() =>
|
||||||
[
|
[
|
||||||
{ label: t('account_bill:all'), value: '' },
|
{ label: t('account_bill:all'), value: undefined },
|
||||||
...Object.entries(billTypeMap).map(([key, value]) => ({
|
...Object.entries(billTypeMap).map(([key, value]) => ({
|
||||||
label: t(value.label as any),
|
label: t(value.label as any),
|
||||||
value: key
|
value: key
|
||||||
}))
|
}))
|
||||||
] as {
|
] as {
|
||||||
label: string;
|
label: string;
|
||||||
value: BillTypeEnum | '';
|
value: BillTypeEnum | undefined;
|
||||||
}[],
|
}[],
|
||||||
[t]
|
[t]
|
||||||
);
|
);
|
||||||
@@ -62,8 +59,7 @@ const BillTable = () => {
|
|||||||
Pagination,
|
Pagination,
|
||||||
getData,
|
getData,
|
||||||
total
|
total
|
||||||
} = usePagination({
|
} = usePagination(getBills, {
|
||||||
api: getBills,
|
|
||||||
pageSize: 20,
|
pageSize: 20,
|
||||||
params: {
|
params: {
|
||||||
type: billType
|
type: billType
|
||||||
@@ -110,7 +106,7 @@ const BillTable = () => {
|
|||||||
<Tr>
|
<Tr>
|
||||||
<Th>#</Th>
|
<Th>#</Th>
|
||||||
<Th>
|
<Th>
|
||||||
<MySelect<BillTypeEnum | ''>
|
<MySelect
|
||||||
list={billTypeList}
|
list={billTypeList}
|
||||||
value={billType}
|
value={billType}
|
||||||
size={'sm'}
|
size={'sm'}
|
||||||
@@ -181,7 +177,6 @@ export default BillTable;
|
|||||||
|
|
||||||
function BillDetailModal({ bill, onClose }: { bill: BillSchemaType; onClose: () => void }) {
|
function BillDetailModal({ bill, onClose }: { bill: BillSchemaType; onClose: () => void }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { commonT } = useI18n();
|
|
||||||
return (
|
return (
|
||||||
<MyModal
|
<MyModal
|
||||||
isOpen={true}
|
isOpen={true}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { getInvoiceRecords } from '@/web/support/wallet/bill/invoice/api';
|
import { getInvoiceRecords } from '@/web/support/wallet/bill/invoice/api';
|
||||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { useEffect, useState } from 'react';
|
import { useState } from 'react';
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
@@ -30,8 +30,7 @@ const InvoiceTable = () => {
|
|||||||
isLoading,
|
isLoading,
|
||||||
Pagination,
|
Pagination,
|
||||||
total
|
total
|
||||||
} = usePagination({
|
} = usePagination(getInvoiceRecords, {
|
||||||
api: getInvoiceRecords,
|
|
||||||
pageSize: 20
|
pageSize: 20
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useCallback, useMemo, useRef } from 'react';
|
import React, { useCallback, useMemo } from 'react';
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Flex,
|
Flex,
|
||||||
@@ -160,6 +160,7 @@ const MyInfo = ({ onOpenContact }: { onOpenContact: () => void }) => {
|
|||||||
color: 'myGray.900'
|
color: 'myGray.900'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isSyncMember = feConfigs.register_method?.includes('sync');
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
{/* user info */}
|
{/* user info */}
|
||||||
@@ -224,6 +225,7 @@ const MyInfo = ({ onOpenContact }: { onOpenContact: () => void }) => {
|
|||||||
<Box {...labelStyles}>{t('account_info:member_name')}: </Box>
|
<Box {...labelStyles}>{t('account_info:member_name')}: </Box>
|
||||||
<Input
|
<Input
|
||||||
flex={'1 0 0'}
|
flex={'1 0 0'}
|
||||||
|
disabled={isSyncMember}
|
||||||
defaultValue={userInfo?.team?.memberName || 'Member'}
|
defaultValue={userInfo?.team?.memberName || 'Member'}
|
||||||
title={t('account_info:click_modify_nickname')}
|
title={t('account_info:click_modify_nickname')}
|
||||||
borderColor={'transparent'}
|
borderColor={'transparent'}
|
||||||
@@ -590,11 +592,6 @@ const Other = ({ onOpenContact }: { onOpenContact: () => void }) => {
|
|||||||
const { feConfigs } = useSystemStore();
|
const { feConfigs } = useSystemStore();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { isPc } = useSystem();
|
const { isPc } = useSystem();
|
||||||
const { userInfo, updateUserInfo } = useUserStore();
|
|
||||||
|
|
||||||
const { reset } = useForm<UserUpdateParams>({
|
|
||||||
defaultValues: userInfo as UserType
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Box, Button, Flex, useTheme } from '@chakra-ui/react';
|
import { Box, Button, Flex, useTheme } from '@chakra-ui/react';
|
||||||
import { getInforms, readInform } from '@/web/support/user/inform/api';
|
import { getInforms, readInform } from '@/web/support/user/inform/api';
|
||||||
import type { UserInformSchema } from '@fastgpt/global/support/user/inform/type';
|
|
||||||
import { formatTimeToChatTime } from '@fastgpt/global/common/string/time';
|
import { formatTimeToChatTime } from '@fastgpt/global/common/string/time';
|
||||||
import { usePagination } from '@fastgpt/web/hooks/usePagination';
|
import { usePagination } from '@fastgpt/web/hooks/usePagination';
|
||||||
import { useLoading } from '@fastgpt/web/hooks/useLoading';
|
import { useLoading } from '@fastgpt/web/hooks/useLoading';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
|
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
|
||||||
import AccountContainer, { TabEnum } from './components/AccountContainer';
|
import AccountContainer from './components/AccountContainer';
|
||||||
import { serviceSideProps } from '@fastgpt/web/common/system/nextjs';
|
import { serviceSideProps } from '@fastgpt/web/common/system/nextjs';
|
||||||
|
|
||||||
const InformTable = () => {
|
const InformTable = () => {
|
||||||
@@ -23,8 +22,7 @@ const InformTable = () => {
|
|||||||
Pagination,
|
Pagination,
|
||||||
getData,
|
getData,
|
||||||
pageNum
|
pageNum
|
||||||
} = usePagination<UserInformSchema>({
|
} = usePagination(getInforms, {
|
||||||
api: getInforms,
|
|
||||||
pageSize: 20
|
pageSize: 20
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import { usePagination } from '@fastgpt/web/hooks/usePagination';
|
|||||||
import { useLoading } from '@fastgpt/web/hooks/useLoading';
|
import { useLoading } from '@fastgpt/web/hooks/useLoading';
|
||||||
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
||||||
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
|
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
|
||||||
import AccountContainer, { TabEnum } from './components/AccountContainer';
|
import AccountContainer from './components/AccountContainer';
|
||||||
import { serviceSideProps } from '@fastgpt/web/common/system/nextjs';
|
import { serviceSideProps } from '@fastgpt/web/common/system/nextjs';
|
||||||
|
|
||||||
const Promotion = () => {
|
const Promotion = () => {
|
||||||
@@ -41,8 +41,7 @@ const Promotion = () => {
|
|||||||
total,
|
total,
|
||||||
pageSize,
|
pageSize,
|
||||||
Pagination
|
Pagination
|
||||||
} = usePagination({
|
} = usePagination(getPromotionRecords, {
|
||||||
api: getPromotionRecords,
|
|
||||||
pageSize: 20
|
pageSize: 20
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import {
|
|||||||
Tr,
|
Tr,
|
||||||
useDisclosure
|
useDisclosure
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { TeamMemberRoleEnum } from '@fastgpt/global/support/user/team/constant';
|
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||||
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
||||||
@@ -30,6 +29,8 @@ import { useToast } from '@fastgpt/web/hooks/useToast';
|
|||||||
import { TeamErrEnum } from '@fastgpt/global/common/error/code/team';
|
import { TeamErrEnum } from '@fastgpt/global/common/error/code/team';
|
||||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||||
import { delLeaveTeam } from '@/web/support/user/team/api';
|
import { delLeaveTeam } from '@/web/support/user/team/api';
|
||||||
|
import { postSyncMembers } from '@/web/support/user/api';
|
||||||
|
import MyLoading from '@fastgpt/web/components/common/MyLoading';
|
||||||
|
|
||||||
const InviteModal = dynamic(() => import('./InviteModal'));
|
const InviteModal = dynamic(() => import('./InviteModal'));
|
||||||
const TeamTagModal = dynamic(() => import('@/components/support/user/team/TeamTagModal'));
|
const TeamTagModal = dynamic(() => import('@/components/support/user/team/TeamTagModal'));
|
||||||
@@ -40,8 +41,16 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
|
|||||||
const { userInfo, teamPlanStatus } = useUserStore();
|
const { userInfo, teamPlanStatus } = useUserStore();
|
||||||
const { feConfigs, setNotSufficientModalType } = useSystemStore();
|
const { feConfigs, setNotSufficientModalType } = useSystemStore();
|
||||||
|
|
||||||
const { groups, refetchGroups, myTeams, refetchTeams, members, refetchMembers, onSwitchTeam } =
|
const {
|
||||||
useContextSelector(TeamContext, (v) => v);
|
groups,
|
||||||
|
refetchGroups,
|
||||||
|
myTeams,
|
||||||
|
refetchTeams,
|
||||||
|
members,
|
||||||
|
refetchMembers,
|
||||||
|
onSwitchTeam,
|
||||||
|
MemberScrollData
|
||||||
|
} = useContextSelector(TeamContext, (v) => v);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isOpen: isOpenTeamTagsAsync,
|
isOpen: isOpenTeamTagsAsync,
|
||||||
@@ -54,6 +63,8 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
|
|||||||
type: 'delete'
|
type: 'delete'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const isSyncMember = feConfigs.register_method?.includes('sync');
|
||||||
|
|
||||||
const { runAsync: onLeaveTeam } = useRequest2(
|
const { runAsync: onLeaveTeam } = useRequest2(
|
||||||
async () => {
|
async () => {
|
||||||
const defaultTeam = myTeams.find((item) => item.defaultTeam) || myTeams[0];
|
const defaultTeam = myTeams.find((item) => item.defaultTeam) || myTeams[0];
|
||||||
@@ -72,8 +83,17 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
|
|||||||
content: t('account_team:confirm_leave_team')
|
content: t('account_team:confirm_leave_team')
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { runAsync: onSyncMember, loading: isSyncing } = useRequest2(postSyncMembers, {
|
||||||
|
onSuccess() {
|
||||||
|
refetchMembers();
|
||||||
|
},
|
||||||
|
successToast: t('account_team:sync_member_success'),
|
||||||
|
errorToast: t('account_team:sync_member_failed')
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{isSyncing && <MyLoading />}
|
||||||
<Flex justify={'space-between'} align={'center'} pb={'1rem'}>
|
<Flex justify={'space-between'} align={'center'} pb={'1rem'}>
|
||||||
{Tabs}
|
{Tabs}
|
||||||
<HStack>
|
<HStack>
|
||||||
@@ -91,7 +111,21 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
|
|||||||
{t('account_team:label_sync')}
|
{t('account_team:label_sync')}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{userInfo?.team.permission.hasManagePer && (
|
{userInfo?.team.permission.hasManagePer && isSyncMember && (
|
||||||
|
<Button
|
||||||
|
variant={'primary'}
|
||||||
|
size="md"
|
||||||
|
borderRadius={'md'}
|
||||||
|
ml={3}
|
||||||
|
leftIcon={<MyIcon name="common/retryLight" w={'16px'} color={'white'} />}
|
||||||
|
onClick={() => {
|
||||||
|
onSyncMember();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t('account_team:sync_immediately')}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
{userInfo?.team.permission.hasManagePer && !isSyncMember && (
|
||||||
<Button
|
<Button
|
||||||
variant={'primary'}
|
variant={'primary'}
|
||||||
size="md"
|
size="md"
|
||||||
@@ -135,6 +169,8 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
|
|||||||
|
|
||||||
<Box flex={'1 0 0'} overflow={'auto'}>
|
<Box flex={'1 0 0'} overflow={'auto'}>
|
||||||
<TableContainer overflow={'unset'} fontSize={'sm'}>
|
<TableContainer overflow={'unset'} fontSize={'sm'}>
|
||||||
|
{MemberScrollData && (
|
||||||
|
<MemberScrollData>
|
||||||
<Table overflow={'unset'}>
|
<Table overflow={'unset'}>
|
||||||
<Thead>
|
<Thead>
|
||||||
<Tr bgColor={'white !important'}>
|
<Tr bgColor={'white !important'}>
|
||||||
@@ -142,9 +178,11 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
|
|||||||
{t('account_team:user_name')}
|
{t('account_team:user_name')}
|
||||||
</Th>
|
</Th>
|
||||||
<Th bgColor="myGray.100">{t('account_team:member_group')}</Th>
|
<Th bgColor="myGray.100">{t('account_team:member_group')}</Th>
|
||||||
|
{!isSyncMember && (
|
||||||
<Th borderRightRadius="6px" bgColor="myGray.100">
|
<Th borderRightRadius="6px" bgColor="myGray.100">
|
||||||
{t('common:common.Action')}
|
{t('common:common.Action')}
|
||||||
</Th>
|
</Th>
|
||||||
|
)}
|
||||||
</Tr>
|
</Tr>
|
||||||
</Thead>
|
</Thead>
|
||||||
<Tbody>
|
<Tbody>
|
||||||
@@ -166,15 +204,17 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
|
|||||||
<Td maxW={'300px'}>
|
<Td maxW={'300px'}>
|
||||||
<GroupTags
|
<GroupTags
|
||||||
names={groups
|
names={groups
|
||||||
?.filter((group) => group.members.map((m) => m.tmbId).includes(item.tmbId))
|
?.filter((group) =>
|
||||||
|
group.members.map((m) => m.tmbId).includes(item.tmbId)
|
||||||
|
)
|
||||||
.map((g) => g.name)}
|
.map((g) => g.name)}
|
||||||
max={3}
|
max={3}
|
||||||
/>
|
/>
|
||||||
</Td>
|
</Td>
|
||||||
|
{!isSyncMember && (
|
||||||
<Td>
|
<Td>
|
||||||
{userInfo?.team.permission.hasManagePer &&
|
userInfo?.team.permission.hasManagePer && item.role !==
|
||||||
item.role !== TeamMemberRoleEnum.owner &&
|
TeamMemberRoleEnum.owner && item.tmbId !== userInfo?.team.tmbId && (
|
||||||
item.tmbId !== userInfo?.team.tmbId && (
|
|
||||||
<Icon
|
<Icon
|
||||||
name={'common/trash'}
|
name={'common/trash'}
|
||||||
cursor={'pointer'}
|
cursor={'pointer'}
|
||||||
@@ -198,13 +238,15 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
|
|||||||
)();
|
)();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)
|
||||||
</Td>
|
</Td>
|
||||||
|
)}
|
||||||
</Tr>
|
</Tr>
|
||||||
))}
|
))}
|
||||||
</Tbody>
|
</Tbody>
|
||||||
</Table>
|
</Table>
|
||||||
|
</MemberScrollData>
|
||||||
|
)}
|
||||||
<ConfirmRemoveMemberModal />
|
<ConfirmRemoveMemberModal />
|
||||||
</TableContainer>
|
</TableContainer>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { deleteOrg, deleteOrgMember } from '@/web/support/user/team/org/api';
|
|
||||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
@@ -27,7 +26,7 @@ import { useMemo, useState } from 'react';
|
|||||||
import { useContextSelector } from 'use-context-selector';
|
import { useContextSelector } from 'use-context-selector';
|
||||||
import MemberTag from '@/components/support/user/team/Info/MemberTag';
|
import MemberTag from '@/components/support/user/team/Info/MemberTag';
|
||||||
import { TeamContext } from '../context';
|
import { TeamContext } from '../context';
|
||||||
import { getOrgList } from '@/web/support/user/team/org/api';
|
import { deleteOrg, deleteOrgMember, getOrgList } from '@/web/support/user/team/org/api';
|
||||||
|
|
||||||
import IconButton from './IconButton';
|
import IconButton from './IconButton';
|
||||||
import { defaultOrgForm, type OrgFormType } from './OrgInfoModal';
|
import { defaultOrgForm, type OrgFormType } from './OrgInfoModal';
|
||||||
@@ -37,6 +36,7 @@ import MyBox from '@fastgpt/web/components/common/MyBox';
|
|||||||
import Path from '@/components/common/folder/Path';
|
import Path from '@/components/common/folder/Path';
|
||||||
import { ParentTreePathItemType } from '@fastgpt/global/common/parentFolder/type';
|
import { ParentTreePathItemType } from '@fastgpt/global/common/parentFolder/type';
|
||||||
import { getOrgChildrenPath } from '@fastgpt/global/support/user/team/org/constant';
|
import { getOrgChildrenPath } from '@fastgpt/global/support/user/team/org/constant';
|
||||||
|
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||||
|
|
||||||
const OrgInfoModal = dynamic(() => import('./OrgInfoModal'));
|
const OrgInfoModal = dynamic(() => import('./OrgInfoModal'));
|
||||||
const OrgMemberManageModal = dynamic(() => import('./OrgMemberManageModal'));
|
const OrgMemberManageModal = dynamic(() => import('./OrgMemberManageModal'));
|
||||||
@@ -76,7 +76,9 @@ function OrgTable({ Tabs }: { Tabs: React.ReactNode }) {
|
|||||||
const { userInfo, isTeamAdmin } = useUserStore();
|
const { userInfo, isTeamAdmin } = useUserStore();
|
||||||
|
|
||||||
const { members } = useContextSelector(TeamContext, (v) => v);
|
const { members } = useContextSelector(TeamContext, (v) => v);
|
||||||
|
const { feConfigs } = useSystemStore();
|
||||||
|
|
||||||
|
const isSyncMember = feConfigs.register_method?.includes('sync');
|
||||||
const [parentPath, setParentPath] = useState('');
|
const [parentPath, setParentPath] = useState('');
|
||||||
const {
|
const {
|
||||||
data: orgs = [],
|
data: orgs = [],
|
||||||
@@ -174,9 +176,11 @@ function OrgTable({ Tabs }: { Tabs: React.ReactNode }) {
|
|||||||
<Th bg="myGray.100" borderLeftRadius="6px">
|
<Th bg="myGray.100" borderLeftRadius="6px">
|
||||||
{t('common:Name')}
|
{t('common:Name')}
|
||||||
</Th>
|
</Th>
|
||||||
|
{!isSyncMember && (
|
||||||
<Th bg="myGray.100" borderRightRadius="6px">
|
<Th bg="myGray.100" borderRightRadius="6px">
|
||||||
{t('common:common.Action')}
|
{t('common:common.Action')}
|
||||||
</Th>
|
</Th>
|
||||||
|
)}
|
||||||
</Tr>
|
</Tr>
|
||||||
</Thead>
|
</Thead>
|
||||||
<Tbody>
|
<Tbody>
|
||||||
@@ -197,8 +201,8 @@ function OrgTable({ Tabs }: { Tabs: React.ReactNode }) {
|
|||||||
/>
|
/>
|
||||||
</HStack>
|
</HStack>
|
||||||
</Td>
|
</Td>
|
||||||
|
{isTeamAdmin && !isSyncMember && (
|
||||||
<Td w={'6rem'}>
|
<Td w={'6rem'}>
|
||||||
{isTeamAdmin && (
|
|
||||||
<MyMenu
|
<MyMenu
|
||||||
trigger="hover"
|
trigger="hover"
|
||||||
Button={<IconButton name="more" />}
|
Button={<IconButton name="more" />}
|
||||||
@@ -225,8 +229,8 @@ function OrgTable({ Tabs }: { Tabs: React.ReactNode }) {
|
|||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
)}
|
|
||||||
</Td>
|
</Td>
|
||||||
|
)}
|
||||||
</Tr>
|
</Tr>
|
||||||
))}
|
))}
|
||||||
{currentOrg?.members.map((member) => {
|
{currentOrg?.members.map((member) => {
|
||||||
@@ -239,7 +243,7 @@ function OrgTable({ Tabs }: { Tabs: React.ReactNode }) {
|
|||||||
<MemberTag name={memberInfo.memberName} avatar={memberInfo.avatar} />
|
<MemberTag name={memberInfo.memberName} avatar={memberInfo.avatar} />
|
||||||
</Td>
|
</Td>
|
||||||
<Td w={'6rem'}>
|
<Td w={'6rem'}>
|
||||||
{isTeamAdmin && (
|
{isTeamAdmin && !isSyncMember && (
|
||||||
<MyMenu
|
<MyMenu
|
||||||
trigger={'hover'}
|
trigger={'hover'}
|
||||||
Button={<IconButton name="more" />}
|
Button={<IconButton name="more" />}
|
||||||
@@ -268,6 +272,7 @@ function OrgTable({ Tabs }: { Tabs: React.ReactNode }) {
|
|||||||
</Table>
|
</Table>
|
||||||
</TableContainer>
|
</TableContainer>
|
||||||
{/* Slider */}
|
{/* Slider */}
|
||||||
|
{!isSyncMember && (
|
||||||
<VStack w={'180px'} alignItems={'start'}>
|
<VStack w={'180px'} alignItems={'start'}>
|
||||||
<HStack gap={'6px'}>
|
<HStack gap={'6px'}>
|
||||||
<Avatar src={currentOrg?.avatar} w={'1rem'} h={'1rem'} rounded={'xs'} />
|
<Avatar src={currentOrg?.avatar} w={'1rem'} h={'1rem'} rounded={'xs'} />
|
||||||
@@ -319,6 +324,7 @@ function OrgTable({ Tabs }: { Tabs: React.ReactNode }) {
|
|||||||
</VStack>
|
</VStack>
|
||||||
)}
|
)}
|
||||||
</VStack>
|
</VStack>
|
||||||
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
{!!editOrg && (
|
{!!editOrg && (
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React, { ReactNode, useState } from 'react';
|
|||||||
import { createContext } from 'use-context-selector';
|
import { createContext } from 'use-context-selector';
|
||||||
import type { EditTeamFormDataType } from './EditInfoModal';
|
import type { EditTeamFormDataType } from './EditInfoModal';
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
import { getTeamList, putSwitchTeam } from '@/web/support/user/team/api';
|
import { getTeamList, getTeamMembers, putSwitchTeam } from '@/web/support/user/team/api';
|
||||||
import { TeamMemberStatusEnum } from '@fastgpt/global/support/user/team/constant';
|
import { TeamMemberStatusEnum } from '@fastgpt/global/support/user/team/constant';
|
||||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||||
import type { TeamTmbItemType, TeamMemberItemType } from '@fastgpt/global/support/user/team/type';
|
import type { TeamTmbItemType, TeamMemberItemType } from '@fastgpt/global/support/user/team/type';
|
||||||
@@ -10,7 +10,7 @@ import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
|||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { getGroupList } from '@/web/support/user/team/group/api';
|
import { getGroupList } from '@/web/support/user/team/group/api';
|
||||||
import { MemberGroupListType } from '@fastgpt/global/support/permission/memberGroup/type';
|
import { MemberGroupListType } from '@fastgpt/global/support/permission/memberGroup/type';
|
||||||
import { OrgType } from '@fastgpt/global/support/user/team/org/type';
|
import { useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination';
|
||||||
|
|
||||||
const EditInfoModal = dynamic(() => import('./EditInfoModal'));
|
const EditInfoModal = dynamic(() => import('./EditInfoModal'));
|
||||||
|
|
||||||
@@ -26,6 +26,7 @@ type TeamModalContextType = {
|
|||||||
refetchTeams: () => void;
|
refetchTeams: () => void;
|
||||||
refetchGroups: () => void;
|
refetchGroups: () => void;
|
||||||
teamSize: number;
|
teamSize: number;
|
||||||
|
MemberScrollData?: ReturnType<typeof useScrollPagination>['ScrollData'];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const TeamContext = createContext<TeamModalContextType>({
|
export const TeamContext = createContext<TeamModalContextType>({
|
||||||
@@ -49,13 +50,14 @@ export const TeamContext = createContext<TeamModalContextType>({
|
|||||||
throw new Error('Function not implemented.');
|
throw new Error('Function not implemented.');
|
||||||
},
|
},
|
||||||
|
|
||||||
teamSize: 0
|
teamSize: 0,
|
||||||
|
MemberScrollData: undefined
|
||||||
});
|
});
|
||||||
|
|
||||||
export const TeamModalContextProvider = ({ children }: { children: ReactNode }) => {
|
export const TeamModalContextProvider = ({ children }: { children: ReactNode }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [editTeamData, setEditTeamData] = useState<EditTeamFormDataType>();
|
const [editTeamData, setEditTeamData] = useState<EditTeamFormDataType>();
|
||||||
const { userInfo, initUserInfo, loadAndGetTeamMembers } = useUserStore();
|
const { userInfo, initUserInfo } = useUserStore();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: myTeams = [],
|
data: myTeams = [],
|
||||||
@@ -69,18 +71,11 @@ export const TeamModalContextProvider = ({ children }: { children: ReactNode })
|
|||||||
// member action
|
// member action
|
||||||
const {
|
const {
|
||||||
data: members = [],
|
data: members = [],
|
||||||
runAsync: refetchMembers,
|
isLoading: loadingMembers,
|
||||||
loading: loadingMembers
|
refreshList: refetchMembers,
|
||||||
} = useRequest2(
|
total: memberTotal,
|
||||||
() => {
|
ScrollData: MemberScrollData
|
||||||
if (!userInfo?.team?.teamId) return Promise.resolve([]);
|
} = useScrollPagination(getTeamMembers, {});
|
||||||
return loadAndGetTeamMembers(true);
|
|
||||||
},
|
|
||||||
{
|
|
||||||
manual: false,
|
|
||||||
refreshDeps: [userInfo?.team?.teamId]
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const { runAsync: onSwitchTeam, loading: isSwitchingTeam } = useRequest2(
|
const { runAsync: onSwitchTeam, loading: isSwitchingTeam } = useRequest2(
|
||||||
async (teamId: string) => {
|
async (teamId: string) => {
|
||||||
@@ -115,7 +110,8 @@ export const TeamModalContextProvider = ({ children }: { children: ReactNode })
|
|||||||
refetchMembers,
|
refetchMembers,
|
||||||
groups,
|
groups,
|
||||||
refetchGroups,
|
refetchGroups,
|
||||||
teamSize: members.length
|
teamSize: memberTotal,
|
||||||
|
MemberScrollData
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { serviceSideProps } from '@fastgpt/web/common/system/nextjs';
|
import { serviceSideProps } from '@fastgpt/web/common/system/nextjs';
|
||||||
import AccountContainer from '../components/AccountContainer';
|
import AccountContainer from '../components/AccountContainer';
|
||||||
import { Box, Flex, useDisclosure } from '@chakra-ui/react';
|
import { Box, Flex } from '@chakra-ui/react';
|
||||||
import Icon from '@fastgpt/web/components/common/Icon';
|
import Icon from '@fastgpt/web/components/common/Icon';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import TeamSelector from '../components/TeamSelector';
|
import TeamSelector from '../components/TeamSelector';
|
||||||
@@ -13,11 +13,10 @@ import MyIcon from '@fastgpt/web/components/common/Icon';
|
|||||||
import { TeamMemberRoleEnum } from '@fastgpt/global/support/user/team/constant';
|
import { TeamMemberRoleEnum } from '@fastgpt/global/support/user/team/constant';
|
||||||
import { TeamContext, TeamModalContextProvider } from './components/context';
|
import { TeamContext, TeamModalContextProvider } from './components/context';
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
import MemberTable from './components/MemberTable';
|
|
||||||
|
|
||||||
|
const MemberTable = dynamic(() => import('./components/MemberTable'));
|
||||||
const PermissionManage = dynamic(() => import('./components/PermissionManage/index'));
|
const PermissionManage = dynamic(() => import('./components/PermissionManage/index'));
|
||||||
const GroupManage = dynamic(() => import('./components/GroupManage/index'));
|
const GroupManage = dynamic(() => import('./components/GroupManage/index'));
|
||||||
|
|
||||||
const OrgManage = dynamic(() => import('./components/OrgManage/index'));
|
const OrgManage = dynamic(() => import('./components/OrgManage/index'));
|
||||||
|
|
||||||
export enum TeamTabEnum {
|
export enum TeamTabEnum {
|
||||||
@@ -34,7 +33,7 @@ const Team = () => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { userInfo } = useUserStore();
|
const { userInfo } = useUserStore();
|
||||||
|
|
||||||
const { setEditTeamData, teamSize, isLoading } = useContextSelector(TeamContext, (v) => v);
|
const { setEditTeamData, isLoading, teamSize } = useContextSelector(TeamContext, (v) => v);
|
||||||
|
|
||||||
const Tabs = useMemo(
|
const Tabs = useMemo(
|
||||||
() => (
|
() => (
|
||||||
|
|||||||
@@ -23,15 +23,16 @@ import DateRangePicker, {
|
|||||||
import { addDays } from 'date-fns';
|
import { addDays } from 'date-fns';
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { useQuery } from '@tanstack/react-query';
|
|
||||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||||
import MySelect from '@fastgpt/web/components/common/MySelect';
|
import MySelect from '@fastgpt/web/components/common/MySelect';
|
||||||
import { formatNumber } from '@fastgpt/global/common/math/tools';
|
import { formatNumber } from '@fastgpt/global/common/math/tools';
|
||||||
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
|
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
|
||||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||||
import AccountContainer, { TabEnum } from '../components/AccountContainer';
|
import AccountContainer from '../components/AccountContainer';
|
||||||
import { serviceSideProps } from '@fastgpt/web/common/system/nextjs';
|
import { serviceSideProps } from '@fastgpt/web/common/system/nextjs';
|
||||||
|
import { useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination';
|
||||||
|
import { getTeamMembers } from '@/web/support/user/team/api';
|
||||||
|
|
||||||
const UsageDetail = dynamic(() => import('./UsageDetail'));
|
const UsageDetail = dynamic(() => import('./UsageDetail'));
|
||||||
|
|
||||||
@@ -44,7 +45,7 @@ const UsageTable = () => {
|
|||||||
});
|
});
|
||||||
const [usageSource, setUsageSource] = useState<UsageSourceEnum | ''>('');
|
const [usageSource, setUsageSource] = useState<UsageSourceEnum | ''>('');
|
||||||
const { isPc } = useSystem();
|
const { isPc } = useSystem();
|
||||||
const { userInfo, loadAndGetTeamMembers } = useUserStore();
|
const { userInfo } = useUserStore();
|
||||||
const [usageDetail, setUsageDetail] = useState<UsageItemType>();
|
const [usageDetail, setUsageDetail] = useState<UsageItemType>();
|
||||||
|
|
||||||
const sourceList = useMemo(
|
const sourceList = useMemo(
|
||||||
@@ -63,10 +64,7 @@ const UsageTable = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const [selectTmbId, setSelectTmbId] = useState(userInfo?.team?.tmbId);
|
const [selectTmbId, setSelectTmbId] = useState(userInfo?.team?.tmbId);
|
||||||
const { data: members = [] } = useQuery(['getMembers', userInfo?.team?.teamId], () => {
|
const { data: members, ScrollData } = useScrollPagination(getTeamMembers, {});
|
||||||
if (!userInfo?.team?.teamId) return [];
|
|
||||||
return loadAndGetTeamMembers();
|
|
||||||
});
|
|
||||||
const tmbList = useMemo(
|
const tmbList = useMemo(
|
||||||
() =>
|
() =>
|
||||||
members.map((item) => ({
|
members.map((item) => ({
|
||||||
@@ -86,14 +84,13 @@ const UsageTable = () => {
|
|||||||
isLoading,
|
isLoading,
|
||||||
Pagination,
|
Pagination,
|
||||||
getData
|
getData
|
||||||
} = usePagination<UsageItemType>({
|
} = usePagination(getUserUsages, {
|
||||||
api: getUserUsages,
|
|
||||||
pageSize: isPc ? 20 : 10,
|
pageSize: isPc ? 20 : 10,
|
||||||
params: {
|
params: {
|
||||||
dateStart: dateRange.from || new Date(),
|
dateStart: dateRange.from || new Date(),
|
||||||
dateEnd: addDays(dateRange.to || new Date(), 1),
|
dateEnd: addDays(dateRange.to || new Date(), 1),
|
||||||
source: usageSource,
|
source: usageSource as UsageSourceEnum,
|
||||||
teamMemberId: selectTmbId
|
teamMemberId: selectTmbId ?? ''
|
||||||
},
|
},
|
||||||
defaultRequest: false
|
defaultRequest: false
|
||||||
});
|
});
|
||||||
@@ -120,6 +117,7 @@ const UsageTable = () => {
|
|||||||
<MySelect
|
<MySelect
|
||||||
size={'sm'}
|
size={'sm'}
|
||||||
minW={'100px'}
|
minW={'100px'}
|
||||||
|
ScrollData={ScrollData}
|
||||||
list={tmbList}
|
list={tmbList}
|
||||||
value={selectTmbId}
|
value={selectTmbId}
|
||||||
onchange={setSelectTmbId}
|
onchange={setSelectTmbId}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import { jiebaSplit } from '@fastgpt/service/common/string/jieba';
|
|||||||
import { MongoDatasetDataText } from '@fastgpt/service/core/dataset/data/dataTextSchema';
|
import { MongoDatasetDataText } from '@fastgpt/service/core/dataset/data/dataTextSchema';
|
||||||
import { MongoDatasetData } from '@fastgpt/service/core/dataset/data/schema';
|
import { MongoDatasetData } from '@fastgpt/service/core/dataset/data/schema';
|
||||||
import { authCert } from '@fastgpt/service/support/permission/auth/common';
|
import { authCert } from '@fastgpt/service/support/permission/auth/common';
|
||||||
|
import { MongoUser } from '@fastgpt/service/support/user/schema';
|
||||||
|
import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema';
|
||||||
import { NextApiRequest, NextApiResponse } from 'next';
|
import { NextApiRequest, NextApiResponse } from 'next';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -14,6 +16,7 @@ import { NextApiRequest, NextApiResponse } from 'next';
|
|||||||
2. 执行升级脚本,不要删除 MongoDatasetData 里的数据。
|
2. 执行升级脚本,不要删除 MongoDatasetData 里的数据。
|
||||||
3. 切换正式版镜像,让 MongoDatasetDataText 生效。
|
3. 切换正式版镜像,让 MongoDatasetDataText 生效。
|
||||||
4. 删除 MongoDatasetData 里的索引和多余字段。(4819 再删
|
4. 删除 MongoDatasetData 里的索引和多余字段。(4819 再删
|
||||||
|
5. 移动 User 表中的 avatar 字段到 TeamMember 表中。
|
||||||
*/
|
*/
|
||||||
let success = 0;
|
let success = 0;
|
||||||
async function handler(req: NextApiRequest, res: NextApiResponse) {
|
async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
@@ -109,15 +112,26 @@ const initData = async (batchSize: number) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const batchUpdateFields = async (batchSize = 2000) => {
|
// const batchUpdateFields = async (batchSize = 2000) => {
|
||||||
// Update in batches
|
// // Find documents that still have these fields
|
||||||
await MongoDatasetData.updateMany(
|
// const documents = await MongoDatasetData.find({ initFullText: { $exists: true } }, '_id')
|
||||||
{ initFullText: { $exists: true } },
|
// .limit(batchSize)
|
||||||
{
|
// .lean();
|
||||||
$unset: {
|
|
||||||
initFullText: 1,
|
// if (documents.length === 0) return;
|
||||||
fullTextToken: 1
|
|
||||||
}
|
// // Update in batches
|
||||||
}
|
// await MongoDatasetData.updateMany(
|
||||||
);
|
// { _id: { $in: documents.map((doc) => doc._id) } },
|
||||||
};
|
// {
|
||||||
|
// $unset: {
|
||||||
|
// initFullText: 1
|
||||||
|
// // fullTextToken: 1
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
|
||||||
|
// success += documents.length;
|
||||||
|
// console.log('Delete success:', success);
|
||||||
|
// await batchUpdateFields(batchSize);
|
||||||
|
// };
|
||||||
|
|||||||
37
projects/app/src/pages/api/admin/initv4819.ts
Normal file
37
projects/app/src/pages/api/admin/initv4819.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import { NextAPI } from '@/service/middleware/entry';
|
||||||
|
import { authCert } from '@fastgpt/service/support/permission/auth/common';
|
||||||
|
import { MongoUser } from '@fastgpt/service/support/user/schema';
|
||||||
|
import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema';
|
||||||
|
import { NextApiRequest, NextApiResponse } from 'next';
|
||||||
|
|
||||||
|
/*
|
||||||
|
简单版迁移:直接升级到最新镜像,会去除 MongoDatasetData 里的索引。直接执行这个脚本。
|
||||||
|
无缝迁移:
|
||||||
|
1. 移动 User 表中的 avatar 字段到 TeamMember 表中。
|
||||||
|
*/
|
||||||
|
async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
|
await authCert({ req, authRoot: true });
|
||||||
|
await moveUserAvatar();
|
||||||
|
return { success: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NextAPI(handler);
|
||||||
|
|
||||||
|
const moveUserAvatar = async () => {
|
||||||
|
try {
|
||||||
|
const users = await MongoUser.find({});
|
||||||
|
for await (const user of users) {
|
||||||
|
await MongoTeamMember.updateOne(
|
||||||
|
{
|
||||||
|
_id: user._id
|
||||||
|
},
|
||||||
|
{
|
||||||
|
avatar: (user as any).avatar // 删除 avatar 字段, 因为 Type 改了,所以这里不能直接写 user.avatar
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
console.log('Move avatar success:', users.length);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||||
import { MongoChat } from '@fastgpt/service/core/chat/chatSchema';
|
import { MongoChat } from '@fastgpt/service/core/chat/chatSchema';
|
||||||
import type { PagingData } from '@/types';
|
|
||||||
import { AppLogsListItemType } from '@/types/app';
|
import { AppLogsListItemType } from '@/types/app';
|
||||||
import { Types } from '@fastgpt/service/common/mongo';
|
import { Types } from '@fastgpt/service/common/mongo';
|
||||||
import { addDays } from 'date-fns';
|
import { addDays } from 'date-fns';
|
||||||
@@ -10,19 +9,22 @@ import { ChatItemCollectionName } from '@fastgpt/service/core/chat/chatItemSchem
|
|||||||
import { NextAPI } from '@/service/middleware/entry';
|
import { NextAPI } from '@/service/middleware/entry';
|
||||||
import { WritePermissionVal } from '@fastgpt/global/support/permission/constant';
|
import { WritePermissionVal } from '@fastgpt/global/support/permission/constant';
|
||||||
import { readFromSecondary } from '@fastgpt/service/common/mongo/utils';
|
import { readFromSecondary } from '@fastgpt/service/common/mongo/utils';
|
||||||
|
import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination';
|
||||||
|
import { TeamMemberCollectionName } from '@fastgpt/global/support/user/team/constant';
|
||||||
|
import { PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
||||||
|
|
||||||
async function handler(
|
async function handler(
|
||||||
req: NextApiRequest,
|
req: NextApiRequest,
|
||||||
_res: NextApiResponse
|
_res: NextApiResponse
|
||||||
): Promise<PagingData<AppLogsListItemType>> {
|
): Promise<PaginationResponse<AppLogsListItemType>> {
|
||||||
const {
|
const {
|
||||||
pageNum = 1,
|
|
||||||
pageSize = 20,
|
|
||||||
appId,
|
appId,
|
||||||
dateStart = addDays(new Date(), -7),
|
dateStart = addDays(new Date(), -7),
|
||||||
dateEnd = new Date()
|
dateEnd = new Date()
|
||||||
} = req.body as GetAppChatLogsParams;
|
} = req.body as GetAppChatLogsParams;
|
||||||
|
|
||||||
|
const { pageSize = 20, offset } = parsePaginationRequest(req);
|
||||||
|
|
||||||
if (!appId) {
|
if (!appId) {
|
||||||
throw new Error('缺少参数');
|
throw new Error('缺少参数');
|
||||||
}
|
}
|
||||||
@@ -39,7 +41,7 @@ async function handler(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const [data, total] = await Promise.all([
|
const [list, total] = await Promise.all([
|
||||||
MongoChat.aggregate(
|
MongoChat.aggregate(
|
||||||
[
|
[
|
||||||
{ $match: where },
|
{ $match: where },
|
||||||
@@ -51,7 +53,7 @@ async function handler(
|
|||||||
updateTime: -1
|
updateTime: -1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ $skip: (pageNum - 1) * pageSize },
|
{ $skip: offset },
|
||||||
{ $limit: pageSize },
|
{ $limit: pageSize },
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
@@ -80,6 +82,14 @@ async function handler(
|
|||||||
as: 'chatitems'
|
as: 'chatitems'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
$lookup: {
|
||||||
|
from: TeamMemberCollectionName,
|
||||||
|
localField: 'tmbId',
|
||||||
|
foreignField: '_id',
|
||||||
|
as: 'member'
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
$addFields: {
|
$addFields: {
|
||||||
userGoodFeedbackCount: {
|
userGoodFeedbackCount: {
|
||||||
@@ -133,7 +143,12 @@ async function handler(
|
|||||||
customFeedbacksCount: 1,
|
customFeedbacksCount: 1,
|
||||||
markCount: 1,
|
markCount: 1,
|
||||||
outLinkUid: 1,
|
outLinkUid: 1,
|
||||||
tmbId: 1
|
tmbId: 1,
|
||||||
|
sourceMember: {
|
||||||
|
name: '$member.name',
|
||||||
|
avatar: '$member.avatar',
|
||||||
|
status: '$member.status'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -145,9 +160,7 @@ async function handler(
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pageNum,
|
list,
|
||||||
pageSize,
|
|
||||||
data,
|
|
||||||
total
|
total
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import { replaceRegChars } from '@fastgpt/global/common/string/tools';
|
|||||||
import { concatPer } from '@fastgpt/service/support/permission/controller';
|
import { concatPer } from '@fastgpt/service/support/permission/controller';
|
||||||
import { getGroupsByTmbId } from '@fastgpt/service/support/permission/memberGroup/controllers';
|
import { getGroupsByTmbId } from '@fastgpt/service/support/permission/memberGroup/controllers';
|
||||||
import { getOrgIdSetWithParentByTmbId } from '@fastgpt/service/support/permission/org/controllers';
|
import { getOrgIdSetWithParentByTmbId } from '@fastgpt/service/support/permission/org/controllers';
|
||||||
|
import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema';
|
||||||
|
|
||||||
export type ListAppBody = {
|
export type ListAppBody = {
|
||||||
parentId?: ParentIdType;
|
parentId?: ParentIdType;
|
||||||
@@ -201,7 +202,15 @@ async function handler(req: ApiRequestProps<ListAppBody>): Promise<AppListItemTy
|
|||||||
})
|
})
|
||||||
.filter((app) => app.permission.hasReadPer);
|
.filter((app) => app.permission.hasReadPer);
|
||||||
|
|
||||||
return formatApps.map((app) => ({
|
// get member info
|
||||||
|
const memberInfo = await MongoTeamMember.find(
|
||||||
|
{ _id: { $in: formatApps.map((app) => app.tmbId) } },
|
||||||
|
'_id name avatar status'
|
||||||
|
).lean();
|
||||||
|
|
||||||
|
return formatApps.map((app) => {
|
||||||
|
const member = memberInfo.find((item) => String(item._id) === String(app.tmbId))!;
|
||||||
|
return {
|
||||||
_id: app._id,
|
_id: app._id,
|
||||||
tmbId: app.tmbId,
|
tmbId: app.tmbId,
|
||||||
avatar: app.avatar,
|
avatar: app.avatar,
|
||||||
@@ -212,8 +221,14 @@ async function handler(req: ApiRequestProps<ListAppBody>): Promise<AppListItemTy
|
|||||||
permission: app.permission,
|
permission: app.permission,
|
||||||
pluginData: app.pluginData,
|
pluginData: app.pluginData,
|
||||||
inheritPermission: app.inheritPermission ?? true,
|
inheritPermission: app.inheritPermission ?? true,
|
||||||
private: app.privateApp
|
private: app.privateApp,
|
||||||
}));
|
sourceMember: {
|
||||||
|
name: member.name,
|
||||||
|
avatar: member.avatar,
|
||||||
|
status: member.status
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export default NextAPI(handler);
|
export default NextAPI(handler);
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import { ApiRequestProps } from '@fastgpt/service/type/next';
|
|||||||
import { authApp } from '@fastgpt/service/support/permission/app/auth';
|
import { authApp } from '@fastgpt/service/support/permission/app/auth';
|
||||||
import { WritePermissionVal } from '@fastgpt/global/support/permission/constant';
|
import { WritePermissionVal } from '@fastgpt/global/support/permission/constant';
|
||||||
import { VersionListItemType } from '@fastgpt/global/core/app/version';
|
import { VersionListItemType } from '@fastgpt/global/core/app/version';
|
||||||
|
import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination';
|
||||||
|
import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema';
|
||||||
|
|
||||||
export type versionListBody = PaginationProps<{
|
export type versionListBody = PaginationProps<{
|
||||||
appId: string;
|
appId: string;
|
||||||
@@ -15,24 +17,44 @@ export type versionListResponse = PaginationResponse<VersionListItemType>;
|
|||||||
|
|
||||||
async function handler(
|
async function handler(
|
||||||
req: ApiRequestProps<versionListBody>,
|
req: ApiRequestProps<versionListBody>,
|
||||||
res: NextApiResponse<any>
|
_res: NextApiResponse<any>
|
||||||
): Promise<versionListResponse> {
|
): Promise<versionListResponse> {
|
||||||
const { offset, pageSize, appId } = req.body;
|
const { appId } = req.body;
|
||||||
|
const { offset, pageSize } = parsePaginationRequest(req);
|
||||||
|
|
||||||
await authApp({ appId, req, per: WritePermissionVal, authToken: true });
|
await authApp({ appId, req, per: WritePermissionVal, authToken: true });
|
||||||
|
|
||||||
const [result, total] = await Promise.all([
|
const [result, total] = await Promise.all([
|
||||||
MongoAppVersion.find(
|
(async () => {
|
||||||
{
|
const versions = await MongoAppVersion.find({
|
||||||
appId
|
appId
|
||||||
},
|
})
|
||||||
'_id appId versionName time isPublish tmbId'
|
|
||||||
)
|
|
||||||
.sort({
|
.sort({
|
||||||
time: -1
|
time: -1
|
||||||
})
|
})
|
||||||
.skip(offset)
|
.skip(offset)
|
||||||
.limit(pageSize),
|
.limit(pageSize)
|
||||||
|
.lean();
|
||||||
|
|
||||||
|
const memberList = await MongoTeamMember.find(
|
||||||
|
{
|
||||||
|
_id: { $in: versions.map((item) => item.tmbId) }
|
||||||
|
},
|
||||||
|
'_id name avatar status'
|
||||||
|
).lean();
|
||||||
|
|
||||||
|
return versions.map((item) => {
|
||||||
|
const member = memberList.find((member) => String(member._id) === String(item.tmbId));
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
sourceMember: {
|
||||||
|
name: member?.name || '',
|
||||||
|
avatar: member?.avatar || '',
|
||||||
|
status: member?.status || ''
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
})(),
|
||||||
MongoAppVersion.countDocuments({ appId })
|
MongoAppVersion.countDocuments({ appId })
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -43,7 +65,8 @@ async function handler(
|
|||||||
versionName: item.versionName,
|
versionName: item.versionName,
|
||||||
time: item.time,
|
time: item.time,
|
||||||
isPublish: item.isPublish,
|
isPublish: item.isPublish,
|
||||||
tmbId: item.tmbId
|
tmbId: item.tmbId,
|
||||||
|
sourceMember: item.sourceMember
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ describe('发布应用版本测试', () => {
|
|||||||
nodes: [],
|
nodes: [],
|
||||||
edges: [],
|
edges: [],
|
||||||
chatConfig: {},
|
chatConfig: {},
|
||||||
type: AppTypeEnum.simple,
|
|
||||||
isPublish: false,
|
isPublish: false,
|
||||||
versionName: '1'
|
versionName: '1'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { NextAPI } from '@/service/middleware/entry';
|
|||||||
import { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next';
|
import { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next';
|
||||||
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
||||||
import { GetHistoriesProps } from '@/global/core/chat/api';
|
import { GetHistoriesProps } from '@/global/core/chat/api';
|
||||||
|
import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination';
|
||||||
import { addMonths } from 'date-fns';
|
import { addMonths } from 'date-fns';
|
||||||
|
|
||||||
export type getHistoriesQuery = {};
|
export type getHistoriesQuery = {};
|
||||||
@@ -17,9 +18,10 @@ export type getHistoriesResponse = {};
|
|||||||
|
|
||||||
async function handler(
|
async function handler(
|
||||||
req: ApiRequestProps<getHistoriesBody, getHistoriesQuery>,
|
req: ApiRequestProps<getHistoriesBody, getHistoriesQuery>,
|
||||||
res: ApiResponseType<any>
|
_res: ApiResponseType<any>
|
||||||
): Promise<PaginationResponse<getHistoriesResponse>> {
|
): Promise<PaginationResponse<getHistoriesResponse>> {
|
||||||
const { appId, shareId, outLinkUid, teamId, teamToken, offset, pageSize, source } = req.body;
|
const { appId, shareId, outLinkUid, teamId, teamToken, source } = req.body;
|
||||||
|
const { offset, pageSize } = parsePaginationRequest(req);
|
||||||
|
|
||||||
const match = await (async () => {
|
const match = await (async () => {
|
||||||
if (shareId && outLinkUid) {
|
if (shareId && outLinkUid) {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import { filterPublicNodeResponseData } from '@fastgpt/global/core/chat/utils';
|
|||||||
import { GetChatTypeEnum } from '@/global/core/chat/constants';
|
import { GetChatTypeEnum } from '@/global/core/chat/constants';
|
||||||
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
||||||
import { ChatItemType } from '@fastgpt/global/core/chat/type';
|
import { ChatItemType } from '@fastgpt/global/core/chat/type';
|
||||||
|
import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination';
|
||||||
|
|
||||||
export type getPaginationRecordsQuery = {};
|
export type getPaginationRecordsQuery = {};
|
||||||
|
|
||||||
@@ -22,16 +23,11 @@ export type getPaginationRecordsResponse = PaginationResponse<ChatItemType>;
|
|||||||
|
|
||||||
async function handler(
|
async function handler(
|
||||||
req: ApiRequestProps<getPaginationRecordsBody, getPaginationRecordsQuery>,
|
req: ApiRequestProps<getPaginationRecordsBody, getPaginationRecordsQuery>,
|
||||||
res: ApiResponseType<any>
|
_res: ApiResponseType<any>
|
||||||
): Promise<getPaginationRecordsResponse> {
|
): Promise<getPaginationRecordsResponse> {
|
||||||
const {
|
const { appId, chatId, loadCustomFeedbacks, type = GetChatTypeEnum.normal } = req.body;
|
||||||
appId,
|
|
||||||
chatId,
|
const { offset, pageSize } = parsePaginationRequest(req);
|
||||||
offset,
|
|
||||||
pageSize = 10,
|
|
||||||
loadCustomFeedbacks,
|
|
||||||
type = GetChatTypeEnum.normal
|
|
||||||
} = req.body;
|
|
||||||
|
|
||||||
if (!appId || !chatId) {
|
if (!appId || !chatId) {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { ApiRequestProps } from '@fastgpt/service/type/next';
|
|||||||
import { ChatInputGuideSchemaType } from '@fastgpt/global/core/chat/inputGuide/type';
|
import { ChatInputGuideSchemaType } from '@fastgpt/global/core/chat/inputGuide/type';
|
||||||
import { authApp } from '@fastgpt/service/support/permission/app/auth';
|
import { authApp } from '@fastgpt/service/support/permission/app/auth';
|
||||||
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
||||||
|
import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination';
|
||||||
|
|
||||||
export type ChatInputGuideProps = PaginationProps<{
|
export type ChatInputGuideProps = PaginationProps<{
|
||||||
appId: string;
|
appId: string;
|
||||||
@@ -17,7 +18,8 @@ async function handler(
|
|||||||
req: ApiRequestProps<ChatInputGuideProps>,
|
req: ApiRequestProps<ChatInputGuideProps>,
|
||||||
res: NextApiResponse<any>
|
res: NextApiResponse<any>
|
||||||
): Promise<ChatInputGuideResponse> {
|
): Promise<ChatInputGuideResponse> {
|
||||||
const { appId, pageSize, offset, searchKey } = req.body;
|
const { appId, searchKey } = req.body;
|
||||||
|
const { offset, pageSize } = parsePaginationRequest(req);
|
||||||
|
|
||||||
await authApp({ req, appId, authToken: true, per: ReadPermissionVal });
|
await authApp({ req, appId, authToken: true, per: ReadPermissionVal });
|
||||||
|
|
||||||
|
|||||||
@@ -10,14 +10,15 @@ import { DatasetDataCollectionName } from '@fastgpt/service/core/dataset/data/sc
|
|||||||
import { startTrainingQueue } from '@/service/core/dataset/training/utils';
|
import { startTrainingQueue } from '@/service/core/dataset/training/utils';
|
||||||
import { NextAPI } from '@/service/middleware/entry';
|
import { NextAPI } from '@/service/middleware/entry';
|
||||||
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
||||||
import { PagingData } from '@/types';
|
|
||||||
import { readFromSecondary } from '@fastgpt/service/common/mongo/utils';
|
import { readFromSecondary } from '@fastgpt/service/common/mongo/utils';
|
||||||
import { collectionTagsToTagLabel } from '@fastgpt/service/core/dataset/collection/utils';
|
import { collectionTagsToTagLabel } from '@fastgpt/service/core/dataset/collection/utils';
|
||||||
|
import { PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
||||||
|
import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination';
|
||||||
|
|
||||||
async function handler(req: NextApiRequest): Promise<PagingData<DatasetCollectionsListItemType>> {
|
async function handler(
|
||||||
|
req: NextApiRequest
|
||||||
|
): Promise<PaginationResponse<DatasetCollectionsListItemType>> {
|
||||||
let {
|
let {
|
||||||
pageNum = 1,
|
|
||||||
pageSize = 10,
|
|
||||||
datasetId,
|
datasetId,
|
||||||
parentId = null,
|
parentId = null,
|
||||||
searchText = '',
|
searchText = '',
|
||||||
@@ -25,8 +26,9 @@ async function handler(req: NextApiRequest): Promise<PagingData<DatasetCollectio
|
|||||||
filterTags = [],
|
filterTags = [],
|
||||||
simple = false
|
simple = false
|
||||||
} = req.body as GetDatasetCollectionsProps;
|
} = req.body as GetDatasetCollectionsProps;
|
||||||
searchText = searchText?.replace(/'/g, '');
|
let { pageSize, offset } = parsePaginationRequest(req);
|
||||||
pageSize = Math.min(pageSize, 30);
|
pageSize = Math.min(pageSize, 30);
|
||||||
|
searchText = searchText?.replace(/'/g, '');
|
||||||
|
|
||||||
// auth dataset and get my role
|
// auth dataset and get my role
|
||||||
const { teamId, permission } = await authDataset({
|
const { teamId, permission } = await authDataset({
|
||||||
@@ -78,9 +80,7 @@ async function handler(req: NextApiRequest): Promise<PagingData<DatasetCollectio
|
|||||||
.lean();
|
.lean();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pageNum,
|
list: await Promise.all(
|
||||||
pageSize,
|
|
||||||
data: await Promise.all(
|
|
||||||
collections.map(async (item) => ({
|
collections.map(async (item) => ({
|
||||||
...item,
|
...item,
|
||||||
tags: await collectionTagsToTagLabel({
|
tags: await collectionTagsToTagLabel({
|
||||||
@@ -105,7 +105,7 @@ async function handler(req: NextApiRequest): Promise<PagingData<DatasetCollectio
|
|||||||
$sort: { updateTime: -1 }
|
$sort: { updateTime: -1 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$skip: (pageNum - 1) * pageSize
|
$skip: offset
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$limit: pageSize
|
$limit: pageSize
|
||||||
@@ -167,7 +167,7 @@ async function handler(req: NextApiRequest): Promise<PagingData<DatasetCollectio
|
|||||||
})
|
})
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const data = await Promise.all(
|
const list = await Promise.all(
|
||||||
collections.map(async (item) => ({
|
collections.map(async (item) => ({
|
||||||
...item,
|
...item,
|
||||||
tags: await collectionTagsToTagLabel({
|
tags: await collectionTagsToTagLabel({
|
||||||
@@ -178,15 +178,13 @@ async function handler(req: NextApiRequest): Promise<PagingData<DatasetCollectio
|
|||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
|
||||||
if (data.find((item) => item.trainingAmount > 0)) {
|
if (list.find((item) => item.trainingAmount > 0)) {
|
||||||
startTrainingQueue();
|
startTrainingQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
// count collections
|
// count collections
|
||||||
return {
|
return {
|
||||||
pageNum,
|
list,
|
||||||
pageSize,
|
|
||||||
data,
|
|
||||||
total
|
total
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
|
|||||||
import { ApiRequestProps } from '@fastgpt/service/type/next';
|
import { ApiRequestProps } from '@fastgpt/service/type/next';
|
||||||
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
||||||
import type { DatasetCollectionsListItemType } from '@/global/core/dataset/type.d';
|
import type { DatasetCollectionsListItemType } from '@/global/core/dataset/type.d';
|
||||||
|
import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination';
|
||||||
|
|
||||||
export type GetScrollCollectionsProps = PaginationProps<{
|
export type GetScrollCollectionsProps = PaginationProps<{
|
||||||
datasetId: string;
|
datasetId: string;
|
||||||
@@ -25,8 +26,6 @@ async function handler(
|
|||||||
): Promise<PaginationResponse<DatasetCollectionsListItemType>> {
|
): Promise<PaginationResponse<DatasetCollectionsListItemType>> {
|
||||||
let {
|
let {
|
||||||
datasetId,
|
datasetId,
|
||||||
pageSize = 10,
|
|
||||||
offset,
|
|
||||||
parentId = null,
|
parentId = null,
|
||||||
searchText = '',
|
searchText = '',
|
||||||
selectFolder = false,
|
selectFolder = false,
|
||||||
@@ -36,6 +35,7 @@ async function handler(
|
|||||||
if (!datasetId) {
|
if (!datasetId) {
|
||||||
return Promise.reject(CommonErrEnum.missingParams);
|
return Promise.reject(CommonErrEnum.missingParams);
|
||||||
}
|
}
|
||||||
|
let { offset, pageSize } = parsePaginationRequest(req);
|
||||||
|
|
||||||
searchText = searchText?.replace(/'/g, '');
|
searchText = searchText?.replace(/'/g, '');
|
||||||
pageSize = Math.min(pageSize, 30);
|
pageSize = Math.min(pageSize, 30);
|
||||||
|
|||||||
@@ -3,19 +3,21 @@ import { MongoDatasetData } from '@fastgpt/service/core/dataset/data/schema';
|
|||||||
import { replaceRegChars } from '@fastgpt/global/common/string/tools';
|
import { replaceRegChars } from '@fastgpt/global/common/string/tools';
|
||||||
import { NextAPI } from '@/service/middleware/entry';
|
import { NextAPI } from '@/service/middleware/entry';
|
||||||
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
||||||
import { PagingData, RequestPaging } from '@/types';
|
|
||||||
import { ApiRequestProps } from '@fastgpt/service/type/next';
|
import { ApiRequestProps } from '@fastgpt/service/type/next';
|
||||||
import { DatasetDataListItemType } from '@/global/core/dataset/type';
|
import { DatasetDataListItemType } from '@/global/core/dataset/type';
|
||||||
|
import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination';
|
||||||
|
import { PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
||||||
|
|
||||||
export type GetDatasetDataListProps = RequestPaging & {
|
export type GetDatasetDataListProps = {
|
||||||
searchText?: string;
|
searchText?: string;
|
||||||
collectionId: string;
|
collectionId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
async function handler(
|
async function handler(
|
||||||
req: ApiRequestProps<GetDatasetDataListProps>
|
req: ApiRequestProps<GetDatasetDataListProps>
|
||||||
): Promise<PagingData<DatasetDataListItemType>> {
|
): Promise<PaginationResponse<DatasetDataListItemType>> {
|
||||||
let { pageNum = 1, pageSize = 10, searchText = '', collectionId } = req.body;
|
let { searchText = '', collectionId } = req.body;
|
||||||
|
let { offset, pageSize } = parsePaginationRequest(req);
|
||||||
|
|
||||||
pageSize = Math.min(pageSize, 30);
|
pageSize = Math.min(pageSize, 30);
|
||||||
|
|
||||||
@@ -40,19 +42,17 @@ async function handler(
|
|||||||
: {})
|
: {})
|
||||||
};
|
};
|
||||||
|
|
||||||
const [data, total] = await Promise.all([
|
const [list, total] = await Promise.all([
|
||||||
MongoDatasetData.find(match, '_id datasetId collectionId q a chunkIndex')
|
MongoDatasetData.find(match, '_id datasetId collectionId q a chunkIndex')
|
||||||
.sort({ chunkIndex: 1, updateTime: -1 })
|
.sort({ chunkIndex: 1, updateTime: -1 })
|
||||||
.skip((pageNum - 1) * pageSize)
|
.skip(offset)
|
||||||
.limit(pageSize)
|
.limit(pageSize)
|
||||||
.lean(),
|
.lean(),
|
||||||
MongoDatasetData.countDocuments(match)
|
MongoDatasetData.countDocuments(match)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pageNum,
|
list,
|
||||||
pageSize,
|
|
||||||
data,
|
|
||||||
total
|
total
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
|||||||
import { ApiRequestProps } from '@fastgpt/service/type/next';
|
import { ApiRequestProps } from '@fastgpt/service/type/next';
|
||||||
import { DatasetDataListItemType } from '@/global/core/dataset/type';
|
import { DatasetDataListItemType } from '@/global/core/dataset/type';
|
||||||
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
||||||
|
import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination';
|
||||||
|
|
||||||
export type GetDatasetDataListProps = PaginationProps & {
|
export type GetDatasetDataListProps = PaginationProps & {
|
||||||
searchText?: string;
|
searchText?: string;
|
||||||
@@ -16,7 +17,8 @@ export type GetDatasetDataListRes = PaginationResponse<DatasetDataListItemType>;
|
|||||||
async function handler(
|
async function handler(
|
||||||
req: ApiRequestProps<GetDatasetDataListProps>
|
req: ApiRequestProps<GetDatasetDataListProps>
|
||||||
): Promise<GetDatasetDataListRes> {
|
): Promise<GetDatasetDataListRes> {
|
||||||
let { offset, pageSize = 10, searchText = '', collectionId } = req.body;
|
let { searchText = '', collectionId } = req.body;
|
||||||
|
let { offset, pageSize } = parsePaginationRequest(req);
|
||||||
|
|
||||||
pageSize = Math.min(pageSize, 30);
|
pageSize = Math.min(pageSize, 30);
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import type { DatasetListItemType } from '@fastgpt/global/core/dataset/type.d';
|
|||||||
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
|
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
|
||||||
import { MongoDataset } from '@fastgpt/service/core/dataset/schema';
|
import { MongoDataset } from '@fastgpt/service/core/dataset/schema';
|
||||||
import { authUserPer } from '@fastgpt/service/support/permission/user/auth';
|
import { authUserPer } from '@fastgpt/service/support/permission/user/auth';
|
||||||
import { getVectorModel } from '@fastgpt/service/core/ai/model';
|
|
||||||
import { NextAPI } from '@/service/middleware/entry';
|
import { NextAPI } from '@/service/middleware/entry';
|
||||||
import { DatasetPermission } from '@fastgpt/global/support/permission/dataset/controller';
|
import { DatasetPermission } from '@fastgpt/global/support/permission/dataset/controller';
|
||||||
import {
|
import {
|
||||||
@@ -19,6 +18,7 @@ import { replaceRegChars } from '@fastgpt/global/common/string/tools';
|
|||||||
import { getGroupsByTmbId } from '@fastgpt/service/support/permission/memberGroup/controllers';
|
import { getGroupsByTmbId } from '@fastgpt/service/support/permission/memberGroup/controllers';
|
||||||
import { concatPer } from '@fastgpt/service/support/permission/controller';
|
import { concatPer } from '@fastgpt/service/support/permission/controller';
|
||||||
import { getOrgIdSetWithParentByTmbId } from '@fastgpt/service/support/permission/org/controllers';
|
import { getOrgIdSetWithParentByTmbId } from '@fastgpt/service/support/permission/org/controllers';
|
||||||
|
import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema';
|
||||||
|
|
||||||
export type GetDatasetListBody = {
|
export type GetDatasetListBody = {
|
||||||
parentId: ParentIdType;
|
parentId: ParentIdType;
|
||||||
@@ -174,19 +174,20 @@ async function handler(req: ApiRequestProps<GetDatasetListBody>) {
|
|||||||
})
|
})
|
||||||
.filter((app) => app.permission.hasReadPer);
|
.filter((app) => app.permission.hasReadPer);
|
||||||
|
|
||||||
const data = formatDatasets.map<DatasetListItemType>((item) => ({
|
const tmbIds = formatDatasets.map((item) => item.tmbId);
|
||||||
_id: item._id,
|
const memberInfo = await MongoTeamMember.find({ _id: { $in: tmbIds } }, '_id name avatar').lean();
|
||||||
avatar: item.avatar,
|
|
||||||
name: item.name,
|
const data = formatDatasets.map((item) => {
|
||||||
intro: item.intro,
|
const member = memberInfo.find((member) => String(member._id) === String(item.tmbId));
|
||||||
type: item.type,
|
|
||||||
permission: item.permission,
|
return {
|
||||||
vectorModel: getVectorModel(item.vectorModel),
|
...item,
|
||||||
inheritPermission: item.inheritPermission,
|
sourceMember: {
|
||||||
tmbId: item.tmbId,
|
name: member!.name,
|
||||||
updateTime: item.updateTime,
|
avatar: member!.avatar
|
||||||
private: item.privateDataset
|
}
|
||||||
}));
|
};
|
||||||
|
});
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
import { MongoUser } from '@fastgpt/service/support/user/schema';
|
import { MongoUser } from '@fastgpt/service/support/user/schema';
|
||||||
import { authCert } from '@fastgpt/service/support/permission/auth/common';
|
import { authCert } from '@fastgpt/service/support/permission/auth/common';
|
||||||
import { UserUpdateParams } from '@/types/user';
|
import { UserUpdateParams } from '@/types/user';
|
||||||
import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema';
|
|
||||||
|
|
||||||
/* update user info */
|
/* update user info */
|
||||||
import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next';
|
import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next';
|
||||||
import { NextAPI } from '@/service/middleware/entry';
|
import { NextAPI } from '@/service/middleware/entry';
|
||||||
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
|
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
|
||||||
import { getUserDetail } from '@fastgpt/service/support/user/controller';
|
|
||||||
import { refreshSourceAvatar } from '@fastgpt/service/common/file/image/controller';
|
import { refreshSourceAvatar } from '@fastgpt/service/common/file/image/controller';
|
||||||
|
import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema';
|
||||||
|
|
||||||
export type UserAccountUpdateQuery = {};
|
export type UserAccountUpdateQuery = {};
|
||||||
export type UserAccountUpdateBody = UserUpdateParams;
|
export type UserAccountUpdateBody = UserUpdateParams;
|
||||||
export type UserAccountUpdateResponse = {};
|
export type UserAccountUpdateResponse = {};
|
||||||
|
|
||||||
async function handler(
|
async function handler(
|
||||||
req: ApiRequestProps<UserAccountUpdateBody, UserAccountUpdateQuery>,
|
req: ApiRequestProps<UserAccountUpdateBody, UserAccountUpdateQuery>,
|
||||||
_res: ApiResponseType<any>
|
_res: ApiResponseType<any>
|
||||||
@@ -19,21 +20,33 @@ async function handler(
|
|||||||
const { avatar, timezone } = req.body;
|
const { avatar, timezone } = req.body;
|
||||||
|
|
||||||
const { tmbId } = await authCert({ req, authToken: true });
|
const { tmbId } = await authCert({ req, authToken: true });
|
||||||
const user = await getUserDetail({ tmbId });
|
// const user = await getUserDetail({ tmbId });
|
||||||
|
|
||||||
// 更新对应的记录
|
// 更新对应的记录
|
||||||
await mongoSessionRun(async (session) => {
|
await mongoSessionRun(async (session) => {
|
||||||
|
const tmb = await MongoTeamMember.findById(tmbId).session(session);
|
||||||
|
if (timezone) {
|
||||||
await MongoUser.updateOne(
|
await MongoUser.updateOne(
|
||||||
{
|
{
|
||||||
_id: user._id
|
_id: tmb?.userId
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
...(avatar && { avatar }),
|
timezone
|
||||||
...(timezone && { timezone })
|
|
||||||
}
|
}
|
||||||
).session(session);
|
).session(session);
|
||||||
|
}
|
||||||
await refreshSourceAvatar(avatar, user.avatar, session);
|
// if avatar, update team member avatar
|
||||||
|
if (avatar) {
|
||||||
|
await MongoTeamMember.updateOne(
|
||||||
|
{
|
||||||
|
_id: tmbId
|
||||||
|
},
|
||||||
|
{
|
||||||
|
avatar
|
||||||
|
}
|
||||||
|
).session(session);
|
||||||
|
await refreshSourceAvatar(avatar, tmb?.avatar, session);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
ModalBody,
|
ModalBody,
|
||||||
HStack
|
HStack
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
import UserBox from '@fastgpt/web/components/common/UserBox';
|
||||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { getAppChatLogs } from '@/web/core/app/api';
|
import { getAppChatLogs } from '@/web/core/app/api';
|
||||||
@@ -30,8 +30,6 @@ import { cardStyles } from '../constants';
|
|||||||
|
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
|
||||||
import { useMount } from 'ahooks';
|
|
||||||
|
|
||||||
const DetailLogsModal = dynamic(() => import('./DetailLogsModal'));
|
const DetailLogsModal = dynamic(() => import('./DetailLogsModal'));
|
||||||
|
|
||||||
@@ -40,17 +38,11 @@ const Logs = () => {
|
|||||||
const { isPc } = useSystem();
|
const { isPc } = useSystem();
|
||||||
|
|
||||||
const appId = useContextSelector(AppContext, (v) => v.appId);
|
const appId = useContextSelector(AppContext, (v) => v.appId);
|
||||||
const { teamMembers, loadAndGetTeamMembers } = useUserStore();
|
|
||||||
|
|
||||||
useMount(() => {
|
|
||||||
loadAndGetTeamMembers();
|
|
||||||
});
|
|
||||||
|
|
||||||
const [dateRange, setDateRange] = useState<DateRangeType>({
|
const [dateRange, setDateRange] = useState<DateRangeType>({
|
||||||
from: addDays(new Date(), -7),
|
from: addDays(new Date(), -7),
|
||||||
to: new Date()
|
to: new Date()
|
||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isOpen: isOpenMarkDesc,
|
isOpen: isOpenMarkDesc,
|
||||||
onOpen: onOpenMarkDesc,
|
onOpen: onOpenMarkDesc,
|
||||||
@@ -63,8 +55,7 @@ const Logs = () => {
|
|||||||
Pagination,
|
Pagination,
|
||||||
getData,
|
getData,
|
||||||
pageNum
|
pageNum
|
||||||
} = usePagination({
|
} = usePagination(getAppChatLogs, {
|
||||||
api: getAppChatLogs,
|
|
||||||
pageSize: 20,
|
pageSize: 20,
|
||||||
params: {
|
params: {
|
||||||
appId,
|
appId,
|
||||||
@@ -139,15 +130,7 @@ const Logs = () => {
|
|||||||
{!!item.outLinkUid ? (
|
{!!item.outLinkUid ? (
|
||||||
item.outLinkUid
|
item.outLinkUid
|
||||||
) : (
|
) : (
|
||||||
<HStack>
|
<UserBox sourceMember={item.sourceMember} />
|
||||||
<Avatar
|
|
||||||
src={teamMembers?.find((v) => v.tmbId === item.tmbId)?.avatar}
|
|
||||||
w="1.25rem"
|
|
||||||
/>
|
|
||||||
<Box fontSize={'sm'} ml={1}>
|
|
||||||
{teamMembers?.find((v) => v.tmbId === item.tmbId)?.memberName}
|
|
||||||
</Box>
|
|
||||||
</HStack>
|
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</Td>
|
</Td>
|
||||||
|
|||||||
@@ -18,12 +18,11 @@ import Tag from '@fastgpt/web/components/common/Tag';
|
|||||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||||
import MyPopover from '@fastgpt/web/components/common/MyPopover';
|
import MyPopover from '@fastgpt/web/components/common/MyPopover';
|
||||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
|
||||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
|
||||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||||
import type { AppVersionSchemaType, VersionListItemType } from '@fastgpt/global/core/app/version';
|
import type { AppVersionSchemaType, VersionListItemType } from '@fastgpt/global/core/app/version';
|
||||||
import type { SimpleAppSnapshotType } from './SimpleApp/useSnapshots';
|
import type { SimpleAppSnapshotType } from './SimpleApp/useSnapshots';
|
||||||
|
import UserBox from '@fastgpt/web/components/common/UserBox';
|
||||||
|
|
||||||
const PublishHistoriesSlider = <T extends SimpleAppSnapshotType | WorkflowSnapshotsType>({
|
const PublishHistoriesSlider = <T extends SimpleAppSnapshotType | WorkflowSnapshotsType>({
|
||||||
onClose,
|
onClose,
|
||||||
@@ -183,10 +182,8 @@ const TeamCloud = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { appDetail } = useContextSelector(AppContext, (v) => v);
|
const { appDetail } = useContextSelector(AppContext, (v) => v);
|
||||||
const { loadAndGetTeamMembers } = useUserStore();
|
|
||||||
const { feConfigs } = useSystemStore();
|
|
||||||
|
|
||||||
const { scrollDataList, ScrollList, isLoading, fetchData, setData } = useVirtualScrollPagination(
|
const { scrollDataList, ScrollList, isLoading, setData } = useVirtualScrollPagination(
|
||||||
getWorkflowVersionList,
|
getWorkflowVersionList,
|
||||||
{
|
{
|
||||||
itemHeight: 40,
|
itemHeight: 40,
|
||||||
@@ -198,9 +195,6 @@ const TeamCloud = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const { data: members = [] } = useRequest2(loadAndGetTeamMembers, {
|
|
||||||
manual: !feConfigs.isPlus
|
|
||||||
});
|
|
||||||
const [editIndex, setEditIndex] = useState<number | undefined>(undefined);
|
const [editIndex, setEditIndex] = useState<number | undefined>(undefined);
|
||||||
const [hoveredIndex, setHoveredIndex] = useState<number | undefined>(undefined);
|
const [hoveredIndex, setHoveredIndex] = useState<number | undefined>(undefined);
|
||||||
|
|
||||||
@@ -241,7 +235,6 @@ const TeamCloud = ({
|
|||||||
{scrollDataList.map((data, index) => {
|
{scrollDataList.map((data, index) => {
|
||||||
const item = data.data;
|
const item = data.data;
|
||||||
const firstPublishedIndex = scrollDataList.findIndex((data) => data.data.isPublish);
|
const firstPublishedIndex = scrollDataList.findIndex((data) => data.data.isPublish);
|
||||||
const tmb = members.find((member) => member.tmbId === item.tmbId);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
@@ -266,23 +259,21 @@ const TeamCloud = ({
|
|||||||
h={'72px'}
|
h={'72px'}
|
||||||
Trigger={
|
Trigger={
|
||||||
<Box>
|
<Box>
|
||||||
<Avatar src={tmb?.avatar} borderRadius={'50%'} w={'24px'} h={'24px'} />
|
<Avatar
|
||||||
|
src={data.data.sourceMember.avatar}
|
||||||
|
borderRadius={'50%'}
|
||||||
|
w={'24px'}
|
||||||
|
h={'24px'}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{({ onClose }) => (
|
{() => (
|
||||||
<Flex alignItems={'center'} h={'full'} pl={5} gap={3}>
|
<Flex alignItems={'center'} h={'full'} pl={5} gap={3}>
|
||||||
<Box>
|
<UserBox sourceMember={data.data.sourceMember} avatarSize="36px" fontSize="sm" />
|
||||||
<Avatar src={tmb?.avatar} borderRadius={'50%'} w={'36px'} h={'36px'} />
|
|
||||||
</Box>
|
|
||||||
<Box>
|
|
||||||
<Box fontSize={'14px'} color={'myGray.900'}>
|
|
||||||
{tmb?.memberName}
|
|
||||||
</Box>
|
|
||||||
<Box fontSize={'12px'} color={'myGray.500'}>
|
<Box fontSize={'12px'} color={'myGray.500'}>
|
||||||
{formatTime2YMDHMS(item.time)}
|
{formatTime2YMDHMS(item.time)}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
</MyPopover>
|
</MyPopover>
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ import { useWorkflowUtils } from './hooks/useUtils';
|
|||||||
import { moduleTemplatesFlat } from '@fastgpt/global/core/workflow/template/constants';
|
import { moduleTemplatesFlat } from '@fastgpt/global/core/workflow/template/constants';
|
||||||
import { cloneDeep } from 'lodash';
|
import { cloneDeep } from 'lodash';
|
||||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
|
||||||
import { LoopStartNode } from '@fastgpt/global/core/workflow/template/system/loop/loopStart';
|
import { LoopStartNode } from '@fastgpt/global/core/workflow/template/system/loop/loopStart';
|
||||||
import { LoopEndNode } from '@fastgpt/global/core/workflow/template/system/loop/loopEnd';
|
import { LoopEndNode } from '@fastgpt/global/core/workflow/template/system/loop/loopEnd';
|
||||||
import { NodeInputKeyEnum, NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
import { NodeInputKeyEnum, NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||||
@@ -89,8 +88,6 @@ enum TemplateTypeEnum {
|
|||||||
const sliderWidth = 460;
|
const sliderWidth = 460;
|
||||||
|
|
||||||
const NodeTemplatesModal = ({ isOpen, onClose }: ModuleTemplateListProps) => {
|
const NodeTemplatesModal = ({ isOpen, onClose }: ModuleTemplateListProps) => {
|
||||||
const { loadAndGetTeamMembers } = useUserStore();
|
|
||||||
|
|
||||||
const [parentId, setParentId] = useState<ParentIdType>('');
|
const [parentId, setParentId] = useState<ParentIdType>('');
|
||||||
const [searchKey, setSearchKey] = useState('');
|
const [searchKey, setSearchKey] = useState('');
|
||||||
const { feConfigs } = useSystemStore();
|
const { feConfigs } = useSystemStore();
|
||||||
@@ -99,10 +96,6 @@ const NodeTemplatesModal = ({ isOpen, onClose }: ModuleTemplateListProps) => {
|
|||||||
const nodeList = useContextSelector(WorkflowContext, (v) => v.nodeList);
|
const nodeList = useContextSelector(WorkflowContext, (v) => v.nodeList);
|
||||||
const appId = useContextSelector(WorkflowContext, (v) => v.appId);
|
const appId = useContextSelector(WorkflowContext, (v) => v.appId);
|
||||||
|
|
||||||
const { data: members = [] } = useRequest2(loadAndGetTeamMembers, {
|
|
||||||
manual: !feConfigs.isPlus
|
|
||||||
});
|
|
||||||
|
|
||||||
const [templateType, setTemplateType] = useState(TemplateTypeEnum.basic);
|
const [templateType, setTemplateType] = useState(TemplateTypeEnum.basic);
|
||||||
|
|
||||||
const { data: basicNodes } = useRequest2(
|
const { data: basicNodes } = useRequest2(
|
||||||
@@ -162,19 +155,10 @@ const NodeTemplatesModal = ({ isOpen, onClose }: ModuleTemplateListProps) => {
|
|||||||
searchVal?: string;
|
searchVal?: string;
|
||||||
}) => {
|
}) => {
|
||||||
if (type === TemplateTypeEnum.teamPlugin) {
|
if (type === TemplateTypeEnum.teamPlugin) {
|
||||||
const teamApps = await getTeamPlugTemplates({
|
return getTeamPlugTemplates({
|
||||||
parentId,
|
parentId,
|
||||||
searchKey: searchVal
|
searchKey: searchVal
|
||||||
}).then((res) => res.filter((app) => app.id !== appId));
|
}).then((res) => res.filter((app) => app.id !== appId));
|
||||||
|
|
||||||
return teamApps.map<NodeTemplateListItemType>((app) => {
|
|
||||||
const member = members.find((member) => member.tmbId === app.tmbId);
|
|
||||||
return {
|
|
||||||
...app,
|
|
||||||
author: member?.memberName,
|
|
||||||
authorAvatar: member?.avatar
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
if (type === TemplateTypeEnum.systemPlugin) {
|
if (type === TemplateTypeEnum.systemPlugin) {
|
||||||
return getSystemPlugTemplates({
|
return getSystemPlugTemplates({
|
||||||
@@ -188,7 +172,7 @@ const NodeTemplatesModal = ({ isOpen, onClose }: ModuleTemplateListProps) => {
|
|||||||
setParentId(parentId);
|
setParentId(parentId);
|
||||||
setTemplateType(type);
|
setTemplateType(type);
|
||||||
},
|
},
|
||||||
refreshDeps: [members, searchKey, templateType]
|
refreshDeps: [searchKey, templateType]
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -420,7 +404,6 @@ const RenderList = React.memo(function RenderList({
|
|||||||
templates,
|
templates,
|
||||||
type,
|
type,
|
||||||
onClose,
|
onClose,
|
||||||
parentId,
|
|
||||||
setParentId
|
setParentId
|
||||||
}: RenderListProps) {
|
}: RenderListProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ import { postCopyApp } from '@/web/core/app/api/app';
|
|||||||
import { formatTimeToChatTime } from '@fastgpt/global/common/string/time';
|
import { formatTimeToChatTime } from '@fastgpt/global/common/string/time';
|
||||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||||
import { useChatStore } from '@/web/core/chat/context/useChatStore';
|
import { useChatStore } from '@/web/core/chat/context/useChatStore';
|
||||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
|
||||||
import { RequireOnlyOne } from '@fastgpt/global/common/type/utils';
|
import { RequireOnlyOne } from '@fastgpt/global/common/type/utils';
|
||||||
|
import UserBox from '@fastgpt/web/components/common/UserBox';
|
||||||
const HttpEditModal = dynamic(() => import('./HttpPluginEditModal'));
|
const HttpEditModal = dynamic(() => import('./HttpPluginEditModal'));
|
||||||
|
|
||||||
const ListItem = () => {
|
const ListItem = () => {
|
||||||
@@ -44,8 +44,6 @@ const ListItem = () => {
|
|||||||
const { parentId = null } = router.query;
|
const { parentId = null } = router.query;
|
||||||
const { isPc } = useSystem();
|
const { isPc } = useSystem();
|
||||||
|
|
||||||
const { loadAndGetTeamMembers } = useUserStore();
|
|
||||||
|
|
||||||
const { openConfirm: openMoveConfirm, ConfirmModal: MoveConfirmModal } = useConfirm({
|
const { openConfirm: openMoveConfirm, ConfirmModal: MoveConfirmModal } = useConfirm({
|
||||||
type: 'common',
|
type: 'common',
|
||||||
title: t('common:move.confirm'),
|
title: t('common:move.confirm'),
|
||||||
@@ -115,10 +113,6 @@ const ListItem = () => {
|
|||||||
successToast: t('app:create_copy_success')
|
successToast: t('app:create_copy_success')
|
||||||
});
|
});
|
||||||
|
|
||||||
const { data: members = [] } = useRequest2(loadAndGetTeamMembers, {
|
|
||||||
manual: false
|
|
||||||
});
|
|
||||||
|
|
||||||
const { runAsync: onResumeInheritPermission } = useRequest2(
|
const { runAsync: onResumeInheritPermission } = useRequest2(
|
||||||
() => {
|
() => {
|
||||||
return resumeInheritPer(editPerApp!._id);
|
return resumeInheritPer(editPerApp!._id);
|
||||||
@@ -145,7 +139,6 @@ const ListItem = () => {
|
|||||||
alignItems={'stretch'}
|
alignItems={'stretch'}
|
||||||
>
|
>
|
||||||
{myApps.map((app, index) => {
|
{myApps.map((app, index) => {
|
||||||
const owner = members.find((v) => v.tmbId === app.tmbId);
|
|
||||||
return (
|
return (
|
||||||
<MyTooltip
|
<MyTooltip
|
||||||
key={app._id}
|
key={app._id}
|
||||||
@@ -229,15 +222,7 @@ const ListItem = () => {
|
|||||||
color={'myGray.500'}
|
color={'myGray.500'}
|
||||||
>
|
>
|
||||||
<HStack spacing={3.5}>
|
<HStack spacing={3.5}>
|
||||||
{owner && (
|
<UserBox sourceMember={app.sourceMember} fontSize="xs" avatarSize="1.25rem" />
|
||||||
<HStack spacing={1}>
|
|
||||||
<Avatar src={owner.avatar} w={'0.875rem'} borderRadius={'50%'} />
|
|
||||||
<Box maxW={'150px'} className="textEllipsis">
|
|
||||||
{owner.memberName}
|
|
||||||
</Box>
|
|
||||||
</HStack>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<PermissionIconText
|
<PermissionIconText
|
||||||
private={app.private}
|
private={app.private}
|
||||||
color={'myGray.500'}
|
color={'myGray.500'}
|
||||||
|
|||||||
@@ -111,8 +111,7 @@ const CollectionPageContextProvider = ({ children }: { children: ReactNode }) =>
|
|||||||
isLoading: isGetting,
|
isLoading: isGetting,
|
||||||
pageNum,
|
pageNum,
|
||||||
pageSize
|
pageSize
|
||||||
} = usePagination<DatasetCollectionsListItemType>({
|
} = usePagination(getDatasetCollections, {
|
||||||
api: getDatasetCollections,
|
|
||||||
pageSize: 20,
|
pageSize: 20,
|
||||||
params: {
|
params: {
|
||||||
datasetId,
|
datasetId,
|
||||||
|
|||||||
@@ -28,10 +28,10 @@ import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
|
|||||||
import { useFolderDrag } from '@/components/common/folder/useFolderDrag';
|
import { useFolderDrag } from '@/components/common/folder/useFolderDrag';
|
||||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
|
||||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||||
import SideTag from './SideTag';
|
import SideTag from './SideTag';
|
||||||
import { getModelProvider } from '@fastgpt/global/core/ai/provider';
|
import { getModelProvider } from '@fastgpt/global/core/ai/provider';
|
||||||
|
import UserBox from '@fastgpt/web/components/common/UserBox';
|
||||||
|
|
||||||
const EditResourceModal = dynamic(() => import('@/components/common/Modal/EditResourceModal'));
|
const EditResourceModal = dynamic(() => import('@/components/common/Modal/EditResourceModal'));
|
||||||
|
|
||||||
@@ -39,7 +39,6 @@ function List() {
|
|||||||
const { setLoading } = useSystemStore();
|
const { setLoading } = useSystemStore();
|
||||||
const { isPc } = useSystem();
|
const { isPc } = useSystem();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { loadAndGetTeamMembers } = useUserStore();
|
|
||||||
const {
|
const {
|
||||||
loadMyDatasets,
|
loadMyDatasets,
|
||||||
setMoveDatasetId,
|
setMoveDatasetId,
|
||||||
@@ -81,10 +80,6 @@ function List() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const { data: members = [] } = useRequest2(loadAndGetTeamMembers, {
|
|
||||||
manual: false
|
|
||||||
});
|
|
||||||
|
|
||||||
const editPerDataset = useMemo(
|
const editPerDataset = useMemo(
|
||||||
() => (editPerDatasetIndex !== undefined ? myDatasets[editPerDatasetIndex] : undefined),
|
() => (editPerDatasetIndex !== undefined ? myDatasets[editPerDatasetIndex] : undefined),
|
||||||
[editPerDatasetIndex, myDatasets]
|
[editPerDatasetIndex, myDatasets]
|
||||||
@@ -156,7 +151,6 @@ function List() {
|
|||||||
alignItems={'stretch'}
|
alignItems={'stretch'}
|
||||||
>
|
>
|
||||||
{formatDatasets.map((dataset, index) => {
|
{formatDatasets.map((dataset, index) => {
|
||||||
const owner = members.find((v) => v.tmbId === dataset.tmbId);
|
|
||||||
const vectorModelAvatar = getModelProvider(dataset.vectorModel.provider)?.avatar;
|
const vectorModelAvatar = getModelProvider(dataset.vectorModel.provider)?.avatar;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -265,14 +259,11 @@ function List() {
|
|||||||
color={'myGray.500'}
|
color={'myGray.500'}
|
||||||
>
|
>
|
||||||
<HStack spacing={3.5}>
|
<HStack spacing={3.5}>
|
||||||
{owner && (
|
<UserBox
|
||||||
<HStack spacing={1}>
|
sourceMember={dataset.sourceMember}
|
||||||
<Avatar src={owner.avatar} w={'0.875rem'} borderRadius={'50%'} />
|
fontSize="xs"
|
||||||
<Box maxW={'150px'} className="textEllipsis" fontSize={'mini'}>
|
avatarSize="1.25rem"
|
||||||
{owner.memberName}
|
/>
|
||||||
</Box>
|
|
||||||
</HStack>
|
|
||||||
)}
|
|
||||||
<PermissionIconText
|
<PermissionIconText
|
||||||
flexShrink={0}
|
flexShrink={0}
|
||||||
private={dataset.private}
|
private={dataset.private}
|
||||||
|
|||||||
3
projects/app/src/types/app.d.ts
vendored
3
projects/app/src/types/app.d.ts
vendored
@@ -13,6 +13,8 @@ import type { FlowNodeTemplateType } from '@fastgpt/global/core/workflow/type/no
|
|||||||
import type { ChatSchema } from '@fastgpt/global/core/chat/type';
|
import type { ChatSchema } from '@fastgpt/global/core/chat/type';
|
||||||
import type { AppSchema } from '@fastgpt/global/core/app/type';
|
import type { AppSchema } from '@fastgpt/global/core/app/type';
|
||||||
import { ChatModelType } from '@/constants/model';
|
import { ChatModelType } from '@/constants/model';
|
||||||
|
import { TeamMemberStatusEnum } from '@fastgpt/global/support/user/team/constant';
|
||||||
|
import { SourceMember } from '@fastgpt/global/support/user/type';
|
||||||
|
|
||||||
export interface ShareAppItem {
|
export interface ShareAppItem {
|
||||||
_id: string;
|
_id: string;
|
||||||
@@ -45,4 +47,5 @@ export type AppLogsListItemType = {
|
|||||||
markCount: number;
|
markCount: number;
|
||||||
outLinkUid?: string;
|
outLinkUid?: string;
|
||||||
tmbId: string;
|
tmbId: string;
|
||||||
|
sourceMember: SourceMember;
|
||||||
};
|
};
|
||||||
|
|||||||
9
projects/app/src/types/index.d.ts
vendored
9
projects/app/src/types/index.d.ts
vendored
@@ -10,15 +10,6 @@ import {
|
|||||||
import { TrackEventName } from '@/web/common/system/constants';
|
import { TrackEventName } from '@/web/common/system/constants';
|
||||||
import { SubPlanType } from '@fastgpt/global/support/wallet/sub/type';
|
import { SubPlanType } from '@fastgpt/global/support/wallet/sub/type';
|
||||||
|
|
||||||
export type PagingData<T> = {
|
|
||||||
pageNum: number;
|
|
||||||
pageSize: number;
|
|
||||||
data: T[];
|
|
||||||
total?: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type RequestPaging = { pageNum: number; pageSize: number; [key]: any };
|
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
var qaQueueLen: number;
|
var qaQueueLen: number;
|
||||||
var vectorQueueLen: number;
|
var vectorQueueLen: number;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { AppUpdateParams, AppChangeOwnerBody } from '@/global/core/app/api';
|
|||||||
import type { CreateAppBody } from '@/pages/api/core/app/create';
|
import type { CreateAppBody } from '@/pages/api/core/app/create';
|
||||||
import type { ListAppBody } from '@/pages/api/core/app/list';
|
import type { ListAppBody } from '@/pages/api/core/app/list';
|
||||||
import { AppLogsListItemType } from '@/types/app';
|
import { AppLogsListItemType } from '@/types/app';
|
||||||
import { PagingData } from '@/types';
|
import { PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取应用列表
|
* 获取应用列表
|
||||||
@@ -39,7 +39,7 @@ export const putAppById = (id: string, data: AppUpdateParams) =>
|
|||||||
|
|
||||||
// =================== chat logs
|
// =================== chat logs
|
||||||
export const getAppChatLogs = (data: GetAppChatLogsParams) =>
|
export const getAppChatLogs = (data: GetAppChatLogsParams) =>
|
||||||
POST<PagingData<AppLogsListItemType>>(`/core/app/getChatLogs`, data);
|
POST<PaginationResponse<AppLogsListItemType>>(`/core/app/getChatLogs`, data);
|
||||||
|
|
||||||
export const resumeInheritPer = (appId: string) =>
|
export const resumeInheritPer = (appId: string) =>
|
||||||
GET(`/core/app/resumeInheritPermission`, { appId });
|
GET(`/core/app/resumeInheritPermission`, { appId });
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ export const getTeamPlugTemplates = (data?: ListAppBody) =>
|
|||||||
intro: app.intro,
|
intro: app.intro,
|
||||||
showStatus: false,
|
showStatus: false,
|
||||||
version: app.pluginData?.nodeVersion || defaultNodeVersion,
|
version: app.pluginData?.nodeVersion || defaultNodeVersion,
|
||||||
isTool: true
|
isTool: true,
|
||||||
|
sourceMember: app.sourceMember
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { PostPublishAppProps } from '@/global/core/app/api';
|
import { PostPublishAppProps } from '@/global/core/app/api';
|
||||||
import { GET, POST, DELETE, PUT } from '@/web/common/api/request';
|
import { GET, POST } from '@/web/common/api/request';
|
||||||
import type { AppVersionSchemaType } from '@fastgpt/global/core/app/version';
|
import type { AppVersionSchemaType } from '@fastgpt/global/core/app/version';
|
||||||
import { PaginationProps } from '@fastgpt/web/common/fetch/type';
|
import { PaginationProps } from '@fastgpt/web/common/fetch/type';
|
||||||
import type {
|
import type {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { getPaginationRecordsBody } from '@/pages/api/core/chat/getPaginationRec
|
|||||||
import { ChatSiteItemType } from '@fastgpt/global/core/chat/type';
|
import { ChatSiteItemType } from '@fastgpt/global/core/chat/type';
|
||||||
import { PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
import { PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
||||||
import { useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination';
|
import { useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination';
|
||||||
import React, { ReactNode, useEffect, useMemo, useState } from 'react';
|
import React, { ReactNode, useMemo, useState } from 'react';
|
||||||
import { createContext, useContextSelector } from 'use-context-selector';
|
import { createContext, useContextSelector } from 'use-context-selector';
|
||||||
import { ChatItemContext } from './chatItemContext';
|
import { ChatItemContext } from './chatItemContext';
|
||||||
import { getChatRecords } from '../api';
|
import { getChatRecords } from '../api';
|
||||||
@@ -68,7 +68,7 @@ const ChatRecordContextProvider = ({
|
|||||||
const res = await getChatRecords(data);
|
const res = await getChatRecords(data);
|
||||||
|
|
||||||
// First load scroll to bottom
|
// First load scroll to bottom
|
||||||
if (data.offset === 0) {
|
if (Number(data.offset) === 0) {
|
||||||
function scrollToBottom() {
|
function scrollToBottom() {
|
||||||
requestAnimationFrame(
|
requestAnimationFrame(
|
||||||
ChatBoxRef?.current ? () => ChatBoxRef?.current?.scrollToBottom?.() : scrollToBottom
|
ChatBoxRef?.current ? () => ChatBoxRef?.current?.scrollToBottom?.() : scrollToBottom
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import type { DatasetCollectionItemType } from '@fastgpt/global/core/dataset/typ
|
|||||||
import { DatasetCollectionSyncResultEnum } from '@fastgpt/global/core/dataset/constants';
|
import { DatasetCollectionSyncResultEnum } from '@fastgpt/global/core/dataset/constants';
|
||||||
import type { DatasetDataItemType } from '@fastgpt/global/core/dataset/type';
|
import type { DatasetDataItemType } from '@fastgpt/global/core/dataset/type';
|
||||||
import type { DatasetCollectionsListItemType } from '@/global/core/dataset/type.d';
|
import type { DatasetCollectionsListItemType } from '@/global/core/dataset/type.d';
|
||||||
import { PagingData } from '@/types';
|
|
||||||
import type { getDatasetTrainingQueueResponse } from '@/pages/api/core/dataset/training/getDatasetTrainingQueue';
|
import type { getDatasetTrainingQueueResponse } from '@/pages/api/core/dataset/training/getDatasetTrainingQueue';
|
||||||
import type { rebuildEmbeddingBody } from '@/pages/api/core/dataset/training/rebuildEmbedding';
|
import type { rebuildEmbeddingBody } from '@/pages/api/core/dataset/training/rebuildEmbedding';
|
||||||
import type {
|
import type {
|
||||||
@@ -66,8 +65,6 @@ import type {
|
|||||||
listExistIdQuery,
|
listExistIdQuery,
|
||||||
listExistIdResponse
|
listExistIdResponse
|
||||||
} from '@/pages/api/core/dataset/apiDataset/listExistId';
|
} from '@/pages/api/core/dataset/apiDataset/listExistId';
|
||||||
import { FeishuServer, YuqueServer } from '@fastgpt/global/core/dataset/apiDataset';
|
|
||||||
import { RequireOnlyOne } from '@fastgpt/global/common/type/utils';
|
|
||||||
|
|
||||||
/* ======================== dataset ======================= */
|
/* ======================== dataset ======================= */
|
||||||
export const getDatasets = (data: GetDatasetListBody) =>
|
export const getDatasets = (data: GetDatasetListBody) =>
|
||||||
@@ -110,7 +107,7 @@ export const postSearchText = (data: SearchTestProps) =>
|
|||||||
|
|
||||||
/* ============================= collections ==================================== */
|
/* ============================= collections ==================================== */
|
||||||
export const getDatasetCollections = (data: GetDatasetCollectionsProps) =>
|
export const getDatasetCollections = (data: GetDatasetCollectionsProps) =>
|
||||||
POST<PagingData<DatasetCollectionsListItemType>>(`/core/dataset/collection/list`, data);
|
POST<PaginationResponse<DatasetCollectionsListItemType>>(`/core/dataset/collection/list`, data);
|
||||||
export const getDatasetCollectionPathById = (parentId: string) =>
|
export const getDatasetCollectionPathById = (parentId: string) =>
|
||||||
GET<ParentTreePathItemType[]>(`/core/dataset/collection/paths`, { parentId });
|
GET<ParentTreePathItemType[]>(`/core/dataset/collection/paths`, { parentId });
|
||||||
export const getDatasetCollectionById = (id: string) =>
|
export const getDatasetCollectionById = (id: string) =>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||||
import ParentPaths from '@/components/common/ParentPaths';
|
import ParentPaths from '@/components/common/ParentPaths';
|
||||||
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
import { useRequest, useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||||
import { getDatasetCollectionPathById, getDatasetCollections } from '@/web/core/dataset/api';
|
import { getDatasetCollectionPathById, getDatasetCollections } from '@/web/core/dataset/api';
|
||||||
import { Box, Flex, ModalFooter, Button, useTheme, Grid, Card, ModalBody } from '@chakra-ui/react';
|
import { Box, Flex, ModalFooter, Button, useTheme, Grid, Card, ModalBody } from '@chakra-ui/react';
|
||||||
import { DatasetCollectionTypeEnum } from '@fastgpt/global/core/dataset/constants';
|
import { DatasetCollectionTypeEnum } from '@fastgpt/global/core/dataset/constants';
|
||||||
@@ -48,7 +48,8 @@ const SelectCollections = ({
|
|||||||
|
|
||||||
useQuery(['loadDatasetDetail', datasetId], () => loadDatasetDetail(datasetId));
|
useQuery(['loadDatasetDetail', datasetId], () => loadDatasetDetail(datasetId));
|
||||||
|
|
||||||
const { data, isLoading } = useQuery(['getDatasetCollections', parentId], () =>
|
const { data, loading: isLoading } = useRequest2(
|
||||||
|
() =>
|
||||||
getDatasetCollections({
|
getDatasetCollections({
|
||||||
datasetId,
|
datasetId,
|
||||||
parentId,
|
parentId,
|
||||||
@@ -56,12 +57,15 @@ const SelectCollections = ({
|
|||||||
simple: true,
|
simple: true,
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 50
|
pageSize: 50
|
||||||
})
|
}),
|
||||||
|
{
|
||||||
|
manual: false,
|
||||||
|
refreshDeps: [datasetId, parentId, type]
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const formatCollections = useMemo(
|
const formatCollections = useMemo(
|
||||||
() =>
|
() =>
|
||||||
data?.data.map((collection) => {
|
data?.list.map((collection) => {
|
||||||
const icon = getCollectionIcon(collection.type, collection.name);
|
const icon = getCollectionIcon(collection.type, collection.name);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -111,7 +115,7 @@ const SelectCollections = ({
|
|||||||
title={
|
title={
|
||||||
<Box>
|
<Box>
|
||||||
<ParentPaths
|
<ParentPaths
|
||||||
paths={paths.map((path, i) => ({
|
paths={paths.map((path) => ({
|
||||||
parentId: path.parentId,
|
parentId: path.parentId,
|
||||||
parentName: path.parentName
|
parentName: path.parentName
|
||||||
}))}
|
}))}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { GET, POST, PUT } from '@/web/common/api/request';
|
import { GET, POST } from '@/web/common/api/request';
|
||||||
import type { PromotionRecordType } from '@/global/support/api/userRes.d';
|
import type { PromotionRecordType } from '@/global/support/api/userRes.d';
|
||||||
import { PagingData, type RequestPaging } from '@/types';
|
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
||||||
|
|
||||||
/* get promotion init data */
|
/* get promotion init data */
|
||||||
export const getPromotionInitData = () =>
|
export const getPromotionInitData = () =>
|
||||||
@@ -10,5 +10,8 @@ export const getPromotionInitData = () =>
|
|||||||
}>('/proApi/support/activity/promotion/getPromotionData');
|
}>('/proApi/support/activity/promotion/getPromotionData');
|
||||||
|
|
||||||
/* promotion records */
|
/* promotion records */
|
||||||
export const getPromotionRecords = (data: RequestPaging) =>
|
export const getPromotionRecords = (data: PaginationProps) =>
|
||||||
POST<PagingData<PromotionRecordType>>(`/proApi/support/activity/promotion/getPromotions`, data);
|
POST<PaginationResponse<PromotionRecordType>>(
|
||||||
|
`/proApi/support/activity/promotion/getPromotions`,
|
||||||
|
data
|
||||||
|
);
|
||||||
|
|||||||
@@ -90,3 +90,5 @@ export const getCaptchaPic = (username: string) =>
|
|||||||
GET<{
|
GET<{
|
||||||
captchaImage: string;
|
captchaImage: string;
|
||||||
}>('/proApi/support/user/account/captcha/getImgCaptcha', { username });
|
}>('/proApi/support/user/account/captcha/getImgCaptcha', { username });
|
||||||
|
|
||||||
|
export const postSyncMembers = () => POST('/proApi/support/user/team/org/sync');
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { GET, POST, PUT } from '@/web/common/api/request';
|
import { GET, POST } from '@/web/common/api/request';
|
||||||
import type { PagingData, RequestPaging } from '@/types';
|
|
||||||
import type { UserInformSchema } from '@fastgpt/global/support/user/inform/type';
|
import type { UserInformSchema } from '@fastgpt/global/support/user/inform/type';
|
||||||
import { SystemMsgModalValueType } from '@fastgpt/service/support/user/inform/type';
|
import { SystemMsgModalValueType } from '@fastgpt/service/support/user/inform/type';
|
||||||
|
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
||||||
|
|
||||||
export const getInforms = (data: RequestPaging) =>
|
export const getInforms = (data: PaginationProps) =>
|
||||||
POST<PagingData<UserInformSchema>>(`/proApi/support/user/inform/list`, data);
|
POST<PaginationResponse<UserInformSchema>>(`/proApi/support/user/inform/list`, data);
|
||||||
|
|
||||||
export const getUnreadCount = () =>
|
export const getUnreadCount = () =>
|
||||||
GET<{
|
GET<{
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
} from '@fastgpt/global/support/user/team/type.d';
|
} from '@fastgpt/global/support/user/team/type.d';
|
||||||
import { FeTeamPlanStatusType, TeamSubSchema } from '@fastgpt/global/support/wallet/sub/type';
|
import { FeTeamPlanStatusType, TeamSubSchema } from '@fastgpt/global/support/wallet/sub/type';
|
||||||
import { TeamInvoiceHeaderType } from '@fastgpt/global/support/user/team/type';
|
import { TeamInvoiceHeaderType } from '@fastgpt/global/support/user/team/type';
|
||||||
|
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
||||||
|
|
||||||
/* --------------- team ---------------- */
|
/* --------------- team ---------------- */
|
||||||
export const getTeamList = (status: `${TeamMemberSchema['status']}`) =>
|
export const getTeamList = (status: `${TeamMemberSchema['status']}`) =>
|
||||||
@@ -30,8 +31,8 @@ export const putSwitchTeam = (teamId: string) =>
|
|||||||
PUT<string>(`/proApi/support/user/team/switch`, { teamId });
|
PUT<string>(`/proApi/support/user/team/switch`, { teamId });
|
||||||
|
|
||||||
/* --------------- team member ---------------- */
|
/* --------------- team member ---------------- */
|
||||||
export const getTeamMembers = () =>
|
export const getTeamMembers = (props: PaginationProps) =>
|
||||||
GET<TeamMemberItemType[]>(`/proApi/support/user/team/member/list`);
|
GET<PaginationResponse<TeamMemberItemType>>(`/proApi/support/user/team/member/list`, props);
|
||||||
export const postInviteTeamMember = (data: InviteMemberProps) =>
|
export const postInviteTeamMember = (data: InviteMemberProps) =>
|
||||||
POST<InviteMemberResponse>(`/proApi/support/user/team/member/invite`, data);
|
POST<InviteMemberResponse>(`/proApi/support/user/team/member/invite`, data);
|
||||||
export const putUpdateMemberName = (name: string) =>
|
export const putUpdateMemberName = (name: string) =>
|
||||||
|
|||||||
@@ -30,9 +30,6 @@ type State = {
|
|||||||
teamPlanStatus: FeTeamPlanStatusType | null;
|
teamPlanStatus: FeTeamPlanStatusType | null;
|
||||||
initTeamPlanStatus: () => Promise<any>;
|
initTeamPlanStatus: () => Promise<any>;
|
||||||
|
|
||||||
teamMembers: TeamMemberItemType[];
|
|
||||||
loadAndGetTeamMembers: (init?: boolean) => Promise<TeamMemberItemType[]>;
|
|
||||||
|
|
||||||
teamMemberGroups: MemberGroupListType;
|
teamMemberGroups: MemberGroupListType;
|
||||||
myGroups: MemberGroupListType;
|
myGroups: MemberGroupListType;
|
||||||
loadAndGetGroups: (init?: boolean) => Promise<MemberGroupListType>;
|
loadAndGetGroups: (init?: boolean) => Promise<MemberGroupListType>;
|
||||||
@@ -102,7 +99,7 @@ export const useUserStore = create<State>()(
|
|||||||
},
|
},
|
||||||
// team
|
// team
|
||||||
teamPlanStatus: null,
|
teamPlanStatus: null,
|
||||||
initTeamPlanStatus() {
|
async initTeamPlanStatus() {
|
||||||
return getTeamPlanStatus().then((res) => {
|
return getTeamPlanStatus().then((res) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.teamPlanStatus = res;
|
state.teamPlanStatus = res;
|
||||||
@@ -110,21 +107,6 @@ export const useUserStore = create<State>()(
|
|||||||
return res;
|
return res;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
teamMembers: [],
|
|
||||||
loadAndGetTeamMembers: async (init = false) => {
|
|
||||||
if (!useSystemStore.getState()?.feConfigs?.isPlus) return [];
|
|
||||||
|
|
||||||
const randomRefresh = Math.random() > 0.7;
|
|
||||||
if (!randomRefresh && !init && get().teamMembers?.length)
|
|
||||||
return Promise.resolve(get().teamMembers);
|
|
||||||
|
|
||||||
const res = await getTeamMembers();
|
|
||||||
set((state) => {
|
|
||||||
state.teamMembers = res;
|
|
||||||
});
|
|
||||||
|
|
||||||
return res;
|
|
||||||
},
|
|
||||||
teamMemberGroups: [],
|
teamMemberGroups: [],
|
||||||
teamOrgs: [],
|
teamOrgs: [],
|
||||||
myGroups: [],
|
myGroups: [],
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { PagingData, RequestPaging } from '@/types';
|
|
||||||
import { GET, POST } from '@/web/common/api/request';
|
import { GET, POST } from '@/web/common/api/request';
|
||||||
import { CreateBillProps, CreateBillResponse } from '@fastgpt/global/support/wallet/bill/api';
|
import { CreateBillProps, CreateBillResponse } from '@fastgpt/global/support/wallet/bill/api';
|
||||||
import { BillTypeEnum } from '@fastgpt/global/support/wallet/bill/constants';
|
import { BillTypeEnum } from '@fastgpt/global/support/wallet/bill/constants';
|
||||||
import type { BillSchemaType } from '@fastgpt/global/support/wallet/bill/type.d';
|
import type { BillSchemaType } from '@fastgpt/global/support/wallet/bill/type.d';
|
||||||
|
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
||||||
|
|
||||||
export const getBills = (
|
export const getBills = (
|
||||||
data: RequestPaging & {
|
data: PaginationProps<{
|
||||||
type?: BillTypeEnum;
|
type?: BillTypeEnum;
|
||||||
}
|
}>
|
||||||
) => POST<PagingData<BillSchemaType>>(`/proApi/support/wallet/bill/list`, data);
|
) => POST<PaginationResponse<BillSchemaType>>(`/proApi/support/wallet/bill/list`, data);
|
||||||
|
|
||||||
export const getWxPayQRCode = (data: CreateBillProps) =>
|
export const getWxPayQRCode = (data: CreateBillProps) =>
|
||||||
POST<CreateBillResponse>(`/proApi/support/wallet/bill/create`, data);
|
POST<CreateBillResponse>(`/proApi/support/wallet/bill/create`, data);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { PagingData, RequestPaging } from '@/types';
|
|
||||||
import { GET, POST } from '@/web/common/api/request';
|
import { GET, POST } from '@/web/common/api/request';
|
||||||
import { BillTypeEnum } from '@fastgpt/global/support/wallet/bill/constants';
|
import { BillTypeEnum } from '@fastgpt/global/support/wallet/bill/constants';
|
||||||
import { InvoiceType } from '@fastgpt/global/support/wallet/bill/type';
|
import { InvoiceType } from '@fastgpt/global/support/wallet/bill/type';
|
||||||
import { InvoiceSchemaType } from '@fastgpt/global/support/wallet/bill/type';
|
import { InvoiceSchemaType } from '@fastgpt/global/support/wallet/bill/type';
|
||||||
|
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
||||||
export type invoiceBillDataType = {
|
export type invoiceBillDataType = {
|
||||||
type: BillTypeEnum;
|
type: BillTypeEnum;
|
||||||
price: number;
|
price: number;
|
||||||
@@ -16,5 +16,5 @@ export const getInvoiceBillsList = () =>
|
|||||||
export const submitInvoice = (data: InvoiceType) =>
|
export const submitInvoice = (data: InvoiceType) =>
|
||||||
POST(`/proApi/support/wallet/bill/invoice/submit`, data);
|
POST(`/proApi/support/wallet/bill/invoice/submit`, data);
|
||||||
|
|
||||||
export const getInvoiceRecords = (data: RequestPaging) =>
|
export const getInvoiceRecords = (data: PaginationProps) =>
|
||||||
POST<PagingData<InvoiceSchemaType>>(`/proApi/support/wallet/bill/invoice/records`, data);
|
POST<PaginationResponse<InvoiceSchemaType>>(`/proApi/support/wallet/bill/invoice/records`, data);
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
import { GET, POST } from '@/web/common/api/request';
|
import { POST } from '@/web/common/api/request';
|
||||||
import { CreateTrainingUsageProps } from '@fastgpt/global/support/wallet/usage/api.d';
|
import { CreateTrainingUsageProps } from '@fastgpt/global/support/wallet/usage/api.d';
|
||||||
import type { PagingData, RequestPaging } from '@/types';
|
import { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants';
|
||||||
import type { UsageItemType } from '@fastgpt/global/support/wallet/usage/type';
|
import type { UsageItemType } from '@fastgpt/global/support/wallet/usage/type';
|
||||||
|
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
||||||
|
|
||||||
export const getUserUsages = (data: RequestPaging) =>
|
export const getUserUsages = (
|
||||||
POST<PagingData<UsageItemType>>(`/proApi/support/wallet/usage/getUsage`, data);
|
data: PaginationProps<{
|
||||||
|
dateStart: Date;
|
||||||
|
dateEnd: Date;
|
||||||
|
source?: UsageSourceEnum;
|
||||||
|
teamMemberId: string;
|
||||||
|
}>
|
||||||
|
) => POST<PaginationResponse<UsageItemType>>(`/proApi/support/wallet/usage/getUsage`, data);
|
||||||
|
|
||||||
export const postCreateTrainingUsage = (data: CreateTrainingUsageProps) =>
|
export const postCreateTrainingUsage = (data: CreateTrainingUsageProps) =>
|
||||||
POST<string>(`/support/wallet/usage/createTrainingUsage`, data);
|
POST<string>(`/support/wallet/usage/createTrainingUsage`, data);
|
||||||
|
|||||||
Reference in New Issue
Block a user