当前位置: 首页 > news >正文

FastGPT如何增减用户

背景

开源版本的FastGPT默认只有一个超级用户root,为了更好地管理应用和知识库,可以通过操作MongoDB数据库来增加新的用户和团队。

所需环境
  • 已安装并运行的FastGPT实例
  • MongoDB客户端工具(如Mongo Shell或Robo 3T等)
操作步骤
  1. 启动MongoDB客户端
    在命令行中启动MongoDB客户端,并连接到FastGPT使用的数据库。

  2. 增加新用户
    users集合中插入一条新记录,这条记录包含新用户的详细信息,包括用户名、密码等字段。

    db.getCollection("users").insert({username: "demo",password: "756bc47cb5215dc3329ca7e1f7be33a2dad68990bb94b76d90aa07f4e44a233a", // 请使用安全的方式加密密码status: "active",avatar: "/icon/human.svg",balance: NumberInt("100000"),promotionRate: NumberInt("10"),timezone: "Asia/Shanghai",createTime: new ISODate()
    });
    
  3. 创建新团队
    teams集合中插入一条新记录,这条记录包含团队的基本信息。

    db.getCollection("teams").insert({name: "New Team",ownerId: ObjectId("65916f1a52ac39c5d10bb505"), // 新创建用户的ObjectIdavatar: "/icon/newteam.svg",createTime: new ISODate(),balance: NumberInt("100000"),maxSize: NumberInt("10"),__v: NumberInt("0")
    });
    
  4. 将用户加入团队
    team_members集合中插入一条新记录,这条记录关联了用户和团队。

    db.getCollection("team_members").insert({teamId: ObjectId("65916f3952ac39c5d10bb506"), // 团队的ObjectIduserId: ObjectId("65916f1a52ac39c5d10bb505"), // 用户的ObjectIdname: "Owner",role: "owner",status: "active",createTime: new ISODate(),defaultTeam: true
    });
    
更方便的方式

有了这么多AI,当然可以直接增加管理页面
在这里插入图片描述

  • user.tsx
import React, { useState, useEffect } from 'react';
import {Box,Button,FormControl,FormLabel,Input,VStack,HStack,Table,Thead,Tbody,Tr,Th,Td,Modal,ModalOverlay,ModalContent,ModalHeader,ModalBody,ModalCloseButton,useDisclosure,useToast,Select,
} from '@chakra-ui/react';
import { serviceSideProps } from '@/web/common/utils/i18n';
const fetchUsers = async () => {const response = await fetch('/api/admin/users');if (!response.ok) throw new Error('Failed to fetch users');return response.json();
};const addUser = async (userData) => {const response = await fetch('/api/admin/users', {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify(userData),});if (!response.ok) throw new Error('Failed to add user');return response.json();
};const updateUser = async (userId, userData) => {const response = await fetch(`/api/admin/users/${userId}`, {method: 'PUT',headers: { 'Content-Type': 'application/json' },body: JSON.stringify(userData),});if (!response.ok) throw new Error('Failed to update user');return response.json();
};const deleteUser = async (userId) => {const response = await fetch(`/api/admin/users/${userId}`, { method: 'DELETE' });if (!response.ok) throw new Error('Failed to delete user');return response.json();
};export default function UserManagement() {const [users, setUsers] = useState([]);const [currentUser, setCurrentUser] = useState(null);const { isOpen, onOpen, onClose } = useDisclosure();const toast = useToast();useEffect(() => {loadUsers();}, []);const loadUsers = async () => {try {const fetchedUsers = await fetchUsers();setUsers(fetchedUsers);} catch (error) {toast({title: "Failed to load users.",description: error.message,status: "error",duration: 3000,isClosable: true,});}};const handleAddUser = async (userData) => {try {const newUser = await addUser(userData);setUsers([...users, newUser.user]);onClose();toast({title: "User added.",status: "success",duration: 2000,isClosable: true,});} catch (error) {toast({title: "Failed to add user.",description: error.message,status: "error",duration: 3000,isClosable: true,});}};const handleUpdateUser = async (userData) => {try {const updatedUser = await updateUser(currentUser._id, userData);setUsers(users.map(user => user._id === updatedUser._id ? updatedUser : user));onClose();toast({title: "User updated.",status: "success",duration: 2000,isClosable: true,});} catch (error) {toast({title: "Failed to update user.",description: error.message,status: "error",duration: 3000,isClosable: true,});}};const handleDeleteUser = async (userId) => {try {await deleteUser(userId);setUsers(users.filter(user => user._id !== userId));toast({title: "User deleted.",status: "success",duration: 2000,isClosable: true,});} catch (error) {toast({title: "Failed to delete user.",description: error.message,status: "error",duration: 3000,isClosable: true,});}};const openAddModal = () => {setCurrentUser(null);onOpen();};const openEditModal = (user) => {setCurrentUser(user);onOpen();};return (<Box p={5}><Button onClick={openAddModal} colorScheme="blue" mb={4}>Add User</Button><Table variant="simple"><Thead><Tr><Th>Username</Th><Th>Status</Th><Th>Balance</Th><Th>Promotion Rate</Th><Th>Timezone</Th><Th>Actions</Th></Tr></Thead><Tbody>{users.map((user) => (<Tr key={user._id}><Td>{user.username}</Td><Td>{user.status}</Td><Td>{user.balance}</Td><Td>{user.promotionRate}%</Td><Td>{user.timezone}</Td><Td><HStack spacing={2}><Button size="sm" onClick={() => openEditModal(user)}>Edit</Button><Button size="sm" colorScheme="red" onClick={() => handleDeleteUser(user._id)}>Delete</Button></HStack></Td></Tr>))}</Tbody></Table><Modal isOpen={isOpen} onClose={onClose}><ModalOverlay /><ModalContent><ModalHeader>{currentUser ? 'Edit User' : 'Add User'}</ModalHeader><ModalCloseButton /><ModalBody><UserForm user={currentUser} onSubmit={currentUser ? handleUpdateUser : handleAddUser} /></ModalBody></ModalContent></Modal></Box>);
}function UserForm({ user, onSubmit }) {const [formData, setFormData] = useState(user || {username: '',password: '',status: 'active',balance: 100000,promotionRate: 10,timezone: 'Asia/Shanghai'});const handleChange = (e) => {const { name, value } = e.target;setFormData({ ...formData, [name]: value });};const handleSubmit = (e) => {e.preventDefault();onSubmit(formData);};return (<form onSubmit={handleSubmit}><VStack spacing={4}><FormControl isRequired><FormLabel>Username</FormLabel><Input name="username" value={formData.username} onChange={handleChange} /></FormControl>{!user && (<FormControl isRequired><FormLabel>Password</FormLabel><Input name="password" type="password" value={formData.password} onChange={handleChange} /></FormControl>)}<FormControl><FormLabel>Status</FormLabel><Select name="status" value={formData.status} onChange={handleChange}><option value="active">Active</option><option value="inactive">Inactive</option></Select></FormControl><FormControl><FormLabel>Balance</FormLabel><Input name="balance" type="number" value={formData.balance} onChange={handleChange} /></FormControl><FormControl><FormLabel>Promotion Rate (%)</FormLabel><Input name="promotionRate" type="number" value={formData.promotionRate} onChange={handleChange} /></FormControl><FormControl><FormLabel>Timezone</FormLabel><Input name="timezone" value={formData.timezone} onChange={handleChange} /></FormControl><Button type="submit" colorScheme="blue">{user ? 'Update' : 'Add'} User</Button></VStack></form>);
}export async function getServerSideProps(content: any) {return {props: {...(await serviceSideProps(content, ['publish', 'user']))}};
}
  • [id].js
import { connectToDatabase } from '@/service/mongo';
import { hashStr } from '@fastgpt/global/common/string/tools';
import { MongoUser } from '@fastgpt/service/support/user/schema';
import { MongoTeam } from '@fastgpt/service/support/user/team/teamSchema';
import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema';export default async function handler(req, res) {const {query: { id },method,} = req;await connectToDatabase();switch (method) {case 'GET':try {const user = await MongoUser.findById(id).select('-password');if (!user) {return res.status(404).json({ error: 'User not found' });}res.status(200).json(user);} catch (error) {res.status(500).json({ error: 'Error fetching user' });}break;case 'PUT':try {const { username, status, avatar, balance, promotionRate, timezone, password } = req.body;const updateDoc = {username,status,avatar,balance,promotionRate,timezone,};if (password) {updateDoc.password = hashStr(password);}const user = await MongoUser.findByIdAndUpdate(id, updateDoc, {new: true,runValidators: true,}).select('-password');if (!user) {return res.status(404).json({ error: 'User not found' });}res.status(200).json(user);} catch (error) {res.status(500).json({ error: 'Error updating user' });}break;case 'DELETE':try {const deletedUser = await MongoUser.findByIdAndDelete(id);if (!deletedUser) {return res.status(404).json({ error: 'User not found' });}// Remove user from teamsawait MongoTeamMember.deleteMany({ userId: id });// Delete teams owned by this userconst ownedTeams = await MongoTeam.find({ ownerId: id });for (const team of ownedTeams) {await MongoTeamMember.deleteMany({ teamId: team._id });await MongoTeam.findByIdAndDelete(team._id);}res.status(200).json({ success: true });} catch (error) {res.status(500).json({ error: 'Error deleting user' });}break;default:res.setHeader('Allow', ['GET', 'PUT', 'DELETE']);res.status(405).end(`Method ${method} Not Allowed`);}
}
  • index.js
// pages/api/users/index.js
import { connectToDatabase } from '@/service/mongo';
import { MongoUser } from '@fastgpt/service/support/user/schema';
import { MongoTeam } from '@fastgpt/service/support/user/team/teamSchema';
import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema';
import { hashStr } from '@fastgpt/global/common/string/tools';
import { authCert } from '@fastgpt/service/support/permission/auth/common';export default async function handler(req, res) {const { method } = req;await connectToDatabase();const { userId } = await authCert({ req, authToken: true });const curUser = await MongoUser.findById(userId).select('-password');if (curUser.username !== 'root') {return res.status(200).json([]);}switch (method) {case 'GET':try {console.log('GET /api/users', MongoUser);const users = await MongoUser.find({ username: { $ne: 'root' } }).select('-password');res.status(200).json(users);} catch (error) {console.log(error);res.status(500).json({ error: 'Error fetching users' });}break;case 'POST':try {const { username, password, status, avatar, balance, promotionRate, timezone } = req.body;// Check if user already existsconst existingUser = await MongoUser.findOne({ username });if (existingUser) {return res.status(400).json({ error: 'Username already exists' });}console.log('POST /api/users', password, hashStr(password), hashStr(hashStr(password)));// Hash passwordconst hashedPassword = hashStr(password);const newUser = new MongoUser({username,password: hashedPassword,status,avatar,balance,promotionRate,timezone,});const savedUser = await newUser.save();// Create a new team for the userconst team = new MongoTeam({name: `${username}'s Team`,ownerId: savedUser._id,});const savedTeam = await team.save();// Add user to team_membersconst teamMember = new MongoTeamMember({teamId: savedTeam._id,userId: savedUser._id,name: 'Owner',role: 'owner',defaultTeam: true,});await teamMember.save();res.status(201).json({ success: true, user: savedUser.toObject({ versionKey: false, transform: (doc, ret) => { delete ret.password; return ret; } }) });} catch (error) {console.log(error);res.status(500).json({ error: 'Error creating user' });}break;default:res.setHeader('Allow', ['GET', 'POST']);res.status(405).end(`Method ${method} Not Allowed`);}
}// pages/api/users/[id].js
  • 访问/admin/user
    在这里插入图片描述

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • React项目-less、antd配置
  • 半路出家程序员感受:非科班出身如何转行程序员? 答案在这
  • VTK随笔一:初识VTK(QT中嵌入VTK窗口)
  • Java方法的使用
  • 快排里面找基准值的算法
  • threadlocal的一些用法,以及如何解决可重入分布式redis锁
  • springboot系列教程(三十二):SpringBoot 教程之处理异步请求
  • Clickhouse篇之数据的备份与恢复
  • 基于R语言的统计分析基础:数据结构
  • Python编码系列—Python CI/CD 实战:构建高效的自动化流程
  • [数据集][目标检测]电力场景输电线异物检测数据集VOC+YOLO格式2060张1类别
  • html+css网页制作 自定义网站 钻石戒指:专业领域应用现状、前沿及发展展望、10个页面
  • 编写 prometheus exporter监控 mysql group replication
  • jmeter中导入java方法并使用
  • 奇文网盘项目对应windows版本的中间件下载,otp,rabbitmq,postgresql,onlyoffice(在线预览编辑等)
  • [iOS]Core Data浅析一 -- 启用Core Data
  • Docker下部署自己的LNMP工作环境
  • extjs4学习之配置
  • HTTP中的ETag在移动客户端的应用
  • JavaScript服务器推送技术之 WebSocket
  • React Transition Group -- Transition 组件
  • SQLServer插入数据
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • V4L2视频输入框架概述
  • 服务器之间,相同帐号,实现免密钥登录
  • 什么软件可以剪辑音乐?
  • 用element的upload组件实现多图片上传和压缩
  • 与 ConTeXt MkIV 官方文档的接驳
  • 积累各种好的链接
  • 进程与线程(三)——进程/线程间通信
  • ​LeetCode解法汇总2670. 找出不同元素数目差数组
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • # 利刃出鞘_Tomcat 核心原理解析(八)-- Tomcat 集群
  • (c语言)strcpy函数用法
  • (待修改)PyG安装步骤
  • (附源码)spring boot智能服药提醒app 毕业设计 102151
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (中等) HDU 4370 0 or 1,建模+Dijkstra。
  • (自适应手机端)行业协会机构网站模板
  • . NET自动找可写目录
  • ..回顾17,展望18
  • .apk文件,IIS不支持下载解决
  • .net core 的缓存方案
  • .net core 客户端缓存、服务器端响应缓存、服务器内存缓存
  • .Net Winform开发笔记(一)
  • .NET/C# 在 64 位进程中读取 32 位进程重定向后的注册表
  • .net6 webapi log4net完整配置使用流程
  • .NET处理HTTP请求
  • .net后端程序发布到nignx上,通过nginx访问
  • .Net下的签名与混淆
  • .Net中间语言BeforeFieldInit
  • [ C++ ] STL---string类的使用指南
  • [ vulhub漏洞复现篇 ] Django SQL注入漏洞复现 CVE-2021-35042
  • [ 数据结构 - C++] AVL树原理及实现