chore: team, orgs, search and so on (#3807)

* feat: clb search support username, memberName, contacts

* feat: popup org names

* feat: update team member table

* feat: restore the member

* feat: search user in team member table

* feat: bind contact

* feat: export members

* feat: org tab could delete member

* feat: org table search

* feat: team notification account bind

* feat: permission tab search

* fix: wecom sso

* chore(init): copy notificationAccount to user.contact

* chore: adjust

* fix: ts error

* fix: useConfirm iconColor customization

* pref: fe

* fix: style

* fix: fix team member manage

* pref: enlarge team member pagesize

* pref: initv4822

* fix: pageSize

* pref: initscritpt
This commit is contained in:
Finley Ge
2025-02-19 17:27:19 +08:00
committed by GitHub
parent 5fd520c794
commit 206325bc5f
35 changed files with 867 additions and 349 deletions

View File

@@ -49,9 +49,7 @@ const StandDetailModal = dynamic(
);
const ConversionModal = dynamic(() => import('@/pageComponents/account/info/ConversionModal'));
const UpdatePswModal = dynamic(() => import('@/pageComponents/account/info/UpdatePswModal'));
const UpdateNotification = dynamic(
() => import('@/components/support/user/inform/UpdateNotificationModal')
);
const UpdateContact = dynamic(() => import('@/components/support/user/inform/UpdateContactModal'));
const CommunityModal = dynamic(() => import('@/components/CommunityModal'));
const ModelPriceModal = dynamic(() =>
@@ -129,9 +127,9 @@ const MyInfo = ({ onOpenContact }: { onOpenContact: () => void }) => {
onOpen: onOpenUpdatePsw
} = useDisclosure();
const {
isOpen: isOpenUpdateNotification,
onClose: onCloseUpdateNotification,
onOpen: onOpenUpdateNotification
isOpen: isOpenUpdateContact,
onClose: onCloseUpdateContact,
onOpen: onOpenUpdateContact
} = useDisclosure();
const {
File,
@@ -259,25 +257,14 @@ const MyInfo = ({ onOpenContact }: { onOpenContact: () => void }) => {
)}
{feConfigs?.isPlus && (
<Flex mt={6} alignItems={'center'}>
<Box {...labelStyles}>{t('account_info:notification_receiving')}:&nbsp;</Box>
<Box
flex={1}
{...(!userInfo?.team.notificationAccount && userInfo?.permission.isOwner
? { color: 'red.600' }
: {})}
>
{userInfo?.team.notificationAccount
? userInfo?.team.notificationAccount
: userInfo?.permission.isOwner
? t('account_info:please_bind_notification_receiving_path')
: t('account_info:reminder_create_bound_notification_account')}
<Box {...labelStyles}>{t('account_info:contact')}:&nbsp;</Box>
<Box flex={1} {...(!userInfo?.contact ? { color: 'red.600' } : {})}>
{userInfo?.contact ? userInfo?.contact : t('account_info:please_bind_contact')}
</Box>
{userInfo?.permission.isOwner && (
<Button size={'sm'} variant={'whitePrimary'} onClick={onOpenUpdateNotification}>
{t('account_info:change')}
</Button>
)}
<Button size={'sm'} variant={'whitePrimary'} onClick={onOpenUpdateContact}>
{t('account_info:change')}
</Button>
</Flex>
)}
{feConfigs.isPlus && (
@@ -310,7 +297,7 @@ const MyInfo = ({ onOpenContact }: { onOpenContact: () => void }) => {
<ConversionModal onClose={onCloseConversionModal} onOpenContact={onOpenContact} />
)}
{isOpenUpdatePsw && <UpdatePswModal onClose={onCloseUpdatePsw} />}
{isOpenUpdateNotification && <UpdateNotification onClose={onCloseUpdateNotification} />}
{isOpenUpdateContact && <UpdateContact onClose={onCloseUpdateContact} mode="contact" />}
<File
onSelect={(e) =>
onSelectImage(e, {

View File

@@ -104,7 +104,8 @@ const Team = () => {
setEditTeamData({
id: userInfo.team.teamId,
name: userInfo.team.teamName,
avatar: userInfo.team.avatar
avatar: userInfo.team.avatar,
notificationAccount: userInfo.team.notificationAccount
});
}}
/>

View File

@@ -0,0 +1,29 @@
import { NextAPI } from '@/service/middleware/entry';
import { authCert } from '@fastgpt/service/support/permission/auth/common';
import { MongoUser } from '@fastgpt/service/support/user/schema';
import { MongoTeam } from '@fastgpt/service/support/user/team/teamSchema';
import { NextApiRequest, NextApiResponse } from 'next';
/*
* 复制 Team 表中的 notificationAccount 到 User 表的 contact 中
*/
async function handler(req: NextApiRequest, _res: NextApiResponse) {
await authCert({ req, authRoot: true });
const users = await MongoUser.find();
const teams = await MongoTeam.find();
for await (const user of users) {
try {
const team = teams.find((team) => String(team.ownerId) === String(user._id));
if (team && !user.contact) {
user.contact = team.notificationAccount;
}
await user.save();
} catch (error) {
console.error(error);
}
}
return { success: true };
}
export default NextAPI(handler);