Files
chat-deploy/internal/api/admin/start.go
kim.dev.6789 b7f8db7d08 复制项目
2026-01-14 22:35:45 +08:00

315 lines
16 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package admin
import (
"context"
"errors"
"fmt"
"net/http"
"os"
"os/signal"
"syscall"
"time"
chatmw "git.imall.cloud/openim/chat/internal/api/mw"
"git.imall.cloud/openim/chat/internal/api/util"
"git.imall.cloud/openim/chat/pkg/common/config"
"git.imall.cloud/openim/chat/pkg/common/imapi"
"git.imall.cloud/openim/chat/pkg/common/kdisc"
disetcd "git.imall.cloud/openim/chat/pkg/common/kdisc/etcd"
adminclient "git.imall.cloud/openim/chat/pkg/protocol/admin"
chatclient "git.imall.cloud/openim/chat/pkg/protocol/chat"
"github.com/gin-gonic/gin"
"github.com/openimsdk/tools/discovery"
"github.com/openimsdk/tools/discovery/etcd"
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/mw"
"github.com/openimsdk/tools/system/program"
"github.com/openimsdk/tools/utils/datautil"
"github.com/openimsdk/tools/utils/runtimeenv"
clientv3 "go.etcd.io/etcd/client/v3"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
type Config struct {
*config.AllConfig
RuntimeEnv string
ConfigPath string
}
func Start(ctx context.Context, index int, config *Config) error {
config.RuntimeEnv = runtimeenv.PrintRuntimeEnvironment()
if len(config.Share.ChatAdmin) == 0 {
return errs.New("share chat admin not configured")
}
apiPort, err := datautil.GetElemByIndex(config.AdminAPI.Api.Ports, index)
if err != nil {
return err
}
client, err := kdisc.NewDiscoveryRegister(&config.Discovery, config.RuntimeEnv, nil)
if err != nil {
return err
}
chatConn, err := client.GetConn(ctx, config.Discovery.RpcService.Chat, grpc.WithTransportCredentials(insecure.NewCredentials()), mw.GrpcClient())
if err != nil {
return err
}
adminConn, err := client.GetConn(ctx, config.Discovery.RpcService.Admin, grpc.WithTransportCredentials(insecure.NewCredentials()), mw.GrpcClient())
if err != nil {
return err
}
chatClient := chatclient.NewChatClient(chatConn)
adminClient := adminclient.NewAdminClient(adminConn)
im := imapi.New(config.Share.OpenIM.ApiURL, config.Share.OpenIM.Secret, config.Share.OpenIM.AdminUserID)
base := util.Api{
ImUserID: config.Share.OpenIM.AdminUserID,
ProxyHeader: config.Share.ProxyHeader,
ChatAdminUserID: config.Share.ChatAdmin[0],
}
adminApi := New(chatClient, adminClient, im, &base)
mwApi := chatmw.New(adminClient)
gin.SetMode(gin.ReleaseMode)
engine := gin.New()
engine.Use(gin.Recovery(), mw.CorsHandler(), mw.GinParseOperationID(), func(c *gin.Context) {
// 确保 operationID 被正确设置到 context 中
operationID := c.GetHeader("operationid")
if operationID != "" {
c.Set("operationID", operationID)
}
c.Next()
})
SetAdminRoute(engine, adminApi, mwApi, config, client)
if config.Discovery.Enable == kdisc.ETCDCONST {
cm := disetcd.NewConfigManager(client.(*etcd.SvcDiscoveryRegistryImpl).GetClient(), config.GetConfigNames())
cm.Watch(ctx)
}
var (
netDone = make(chan struct{}, 1)
netErr error
)
server := http.Server{Addr: fmt.Sprintf(":%d", apiPort), Handler: engine}
go func() {
err = server.ListenAndServe()
if err != nil && !errors.Is(err, http.ErrServerClosed) {
netErr = errs.WrapMsg(err, fmt.Sprintf("api start err: %s", server.Addr))
netDone <- struct{}{}
}
}()
shutdown := func() error {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
err := server.Shutdown(ctx)
if err != nil {
return errs.WrapMsg(err, "shutdown err")
}
return nil
}
disetcd.RegisterShutDown(shutdown)
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGTERM)
select {
case <-sigs:
program.SIGTERMExit()
if err := shutdown(); err != nil {
return err
}
case <-netDone:
close(netDone)
return netErr
}
return nil
}
func SetAdminRoute(router gin.IRouter, admin *Api, mw *chatmw.MW, cfg *Config, client discovery.SvcDiscoveryRegistry) {
adminRouterGroup := router.Group("/account")
adminRouterGroup.POST("/login", admin.AdminLogin) // Login
adminRouterGroup.POST("/update", mw.CheckAdmin, admin.AdminUpdateInfo) // Modify information
adminRouterGroup.POST("/info", mw.CheckAdmin, admin.AdminInfo) // Get information
adminRouterGroup.POST("/change_password", mw.CheckAdmin, admin.ChangeAdminPassword) // Change admin account's password
adminRouterGroup.POST("/change_operation_password", mw.CheckAdmin, admin.ChangeOperationPassword) // Change operation password
adminRouterGroup.POST("/set_google_auth_key", mw.CheckAdmin, admin.SetGoogleAuthKey) // Set Google Authenticator key
adminRouterGroup.POST("/add_admin", mw.CheckAdmin, admin.AddAdminAccount) // Add admin account
adminRouterGroup.POST("/add_user", mw.CheckAdmin, admin.AddUserAccount) // Add user account
adminRouterGroup.POST("/del_admin", mw.CheckAdmin, admin.DelAdminAccount) // Delete admin
adminRouterGroup.POST("/search", mw.CheckAdmin, admin.SearchAdminAccount) // Get admin list
adminRouterGroup.POST("/statistics", mw.CheckAdmin, admin.GetStatistics) // Get system statistics
//account.POST("/add_notification_account")
importGroup := router.Group("/user/import")
importGroup.POST("/json", mw.CheckAdmin, admin.ImportUserByJson)
importGroup.POST("/xlsx", mw.CheckAdmin, admin.ImportUserByXlsx)
importGroup.GET("/xlsx", admin.BatchImportTemplate)
allowRegisterGroup := router.Group("/user/allow_register", mw.CheckAdmin)
allowRegisterGroup.POST("/get", admin.GetAllowRegister)
allowRegisterGroup.POST("/set", admin.SetAllowRegister)
defaultRouter := router.Group("/default", mw.CheckAdmin)
defaultUserRouter := defaultRouter.Group("/user")
defaultUserRouter.POST("/add", admin.AddDefaultFriend) // Add default friend at registration
defaultUserRouter.POST("/del", admin.DelDefaultFriend) // Delete default friend at registration
defaultUserRouter.POST("/find", admin.FindDefaultFriend) // Default friend list
defaultUserRouter.POST("/search", admin.SearchDefaultFriend) // Search default friend list at registration
defaultGroupRouter := defaultRouter.Group("/group")
defaultGroupRouter.POST("/add", admin.AddDefaultGroup) // Add default group at registration
defaultGroupRouter.POST("/del", admin.DelDefaultGroup) // Delete default group at registration
defaultGroupRouter.POST("/find", admin.FindDefaultGroup) // Get default group list at registration
defaultGroupRouter.POST("/search", admin.SearchDefaultGroup) // Search default group list at registration
invitationCodeRouter := router.Group("/invitation_code", mw.CheckAdmin)
invitationCodeRouter.POST("/add", admin.AddInvitationCode) // Add invitation code
invitationCodeRouter.POST("/gen", admin.GenInvitationCode) // Generate invitation code
invitationCodeRouter.POST("/del", admin.DelInvitationCode) // Delete invitation code
invitationCodeRouter.POST("/search", admin.SearchInvitationCode) // Search invitation code
forbiddenRouter := router.Group("/forbidden", mw.CheckAdmin)
ipForbiddenRouter := forbiddenRouter.Group("/ip")
ipForbiddenRouter.POST("/add", admin.AddIPForbidden) // Add forbidden IP for registration/login
ipForbiddenRouter.POST("/del", admin.DelIPForbidden) // Delete forbidden IP for registration/login
ipForbiddenRouter.POST("/search", admin.SearchIPForbidden) // Search forbidden IPs for registration/login
userForbiddenRouter := forbiddenRouter.Group("/user")
userForbiddenRouter.POST("/add", admin.AddUserIPLimitLogin) // Add limit for user login on specific IP
userForbiddenRouter.POST("/del", admin.DelUserIPLimitLogin) // Delete user limit on specific IP for login
userForbiddenRouter.POST("/search", admin.SearchUserIPLimitLogin) // Search limit for user login on specific IP
appletRouterGroup := router.Group("/applet", mw.CheckAdmin)
appletRouterGroup.POST("/add", admin.AddApplet) // Add applet
appletRouterGroup.POST("/del", admin.DelApplet) // Delete applet
appletRouterGroup.POST("/update", admin.UpdateApplet) // Modify applet
appletRouterGroup.POST("/search", admin.SearchApplet) // Search applet
blockRouter := router.Group("/block", mw.CheckAdmin)
blockRouter.POST("/add", admin.BlockUser) // Block user
blockRouter.POST("/del", admin.UnblockUser) // Unblock user
blockRouter.POST("/search", admin.SearchBlockUser) // Search blocked users
userRouter := router.Group("/user", mw.CheckAdmin)
userRouter.POST("/password/reset", admin.ResetUserPassword) // Reset user password
initGroup := router.Group("/client_config", mw.CheckAdmin)
initGroup.POST("/get", admin.GetClientConfig) // Get client initialization configuration
initGroup.POST("/set", admin.SetClientConfig) // Set client initialization configuration
initGroup.POST("/del", admin.DelClientConfig) // Delete client initialization configuration
statistic := router.Group("/statistic", mw.CheckAdmin)
statistic.POST("/new_user_count", admin.NewUserCount)
statistic.POST("/login_user_count", admin.LoginUserCount)
statistic.POST("/online_user_count", admin.OnlineUserCount)
statistic.POST("/online_user_count_trend", admin.OnlineUserCountTrend)
statistic.POST("/user_send_msg_count", admin.UserSendMsgCount)
statistic.POST("/user_send_msg_count_trend", admin.UserSendMsgCountTrend)
statistic.POST("/user_send_msg_query", admin.UserSendMsgQuery)
applicationGroup := router.Group("application")
applicationGroup.POST("/add_version", mw.CheckAdmin, admin.AddApplicationVersion)
applicationGroup.POST("/update_version", mw.CheckAdmin, admin.UpdateApplicationVersion)
applicationGroup.POST("/delete_version", mw.CheckAdmin, admin.DeleteApplicationVersion)
applicationGroup.POST("/latest_version", admin.LatestApplicationVersion)
applicationGroup.POST("/page_versions", admin.PageApplicationVersion)
var etcdClient *clientv3.Client
if cfg.Discovery.Enable == kdisc.ETCDCONST {
etcdClient = client.(*etcd.SvcDiscoveryRegistryImpl).GetClient()
}
cm := NewConfigManager(cfg.AllConfig, etcdClient, cfg.ConfigPath, cfg.RuntimeEnv)
{
configGroup := router.Group("/config", mw.CheckAdmin)
configGroup.POST("/get_config_list", cm.GetConfigList)
configGroup.POST("/get_config", cm.GetConfig)
configGroup.POST("/set_config", cm.SetConfig)
configGroup.POST("/set_configs", cm.SetConfigs)
configGroup.POST("/reset_config", cm.ResetConfig)
configGroup.POST("/get_enable_config_manager", cm.GetEnableConfigManager)
configGroup.POST("/set_enable_config_manager", cm.SetEnableConfigManager)
}
{
router.POST("/restart", mw.CheckAdmin, cm.Restart)
}
// ==================== 敏感词管理路由 ====================
sensitiveWordRouter := router.Group("/sensitive_word") // 暂时注释掉 mw.CheckAdmin 用于测试
// 敏感词管理
sensitiveWordRouter.POST("/add", mw.CheckAdmin, admin.AddSensitiveWord) // 添加敏感词
sensitiveWordRouter.POST("/update", mw.CheckAdmin, admin.UpdateSensitiveWord) // 更新敏感词
sensitiveWordRouter.POST("/delete", mw.CheckAdmin, admin.DeleteSensitiveWord) // 删除敏感词
sensitiveWordRouter.POST("/get", mw.CheckAdmin, admin.GetSensitiveWord) // 获取敏感词
sensitiveWordRouter.POST("/search", mw.CheckAdmin, admin.SearchSensitiveWords) // 搜索敏感词
sensitiveWordRouter.POST("/batch_add", mw.CheckAdmin, admin.BatchAddSensitiveWords) // 批量添加敏感词
sensitiveWordRouter.POST("/batch_update", mw.CheckAdmin, admin.BatchUpdateSensitiveWords) // 批量更新敏感词
sensitiveWordRouter.POST("/batch_delete", mw.CheckAdmin, admin.BatchDeleteSensitiveWords) // 批量删除敏感词
// 敏感词分组管理
groupRouter := sensitiveWordRouter.Group("/group")
groupRouter.POST("/add", mw.CheckAdmin, admin.AddSensitiveWordGroup) // 添加敏感词分组
groupRouter.POST("/update", mw.CheckAdmin, admin.UpdateSensitiveWordGroup) // 更新敏感词分组
groupRouter.POST("/delete", mw.CheckAdmin, admin.DeleteSensitiveWordGroup) // 删除敏感词分组
groupRouter.POST("/get", mw.CheckAdmin, admin.GetSensitiveWordGroup) // 获取敏感词分组
groupRouter.POST("/list", mw.CheckAdmin, admin.GetAllSensitiveWordGroups) // 获取所有敏感词分组
// 敏感词配置管理
configRouter := sensitiveWordRouter.Group("/config")
configRouter.GET("/", mw.CheckAdmin, admin.GetSensitiveWordConfig) // 获取敏感词配置
configRouter.POST("/get", mw.CheckAdmin, admin.GetSensitiveWordConfig) // 获取敏感词配置
configRouter.POST("/update", mw.CheckAdmin, admin.UpdateSensitiveWordConfig) // 更新敏感词配置
// 敏感词日志管理
logRouter := sensitiveWordRouter.Group("/log")
logRouter.POST("/list", mw.CheckAdmin, admin.GetSensitiveWordLogs) // 获取敏感词日志
// 用户登录记录管理
loginRecordRouter := router.Group("/user_login_record", mw.CheckAdmin)
loginRecordRouter.POST("/list", admin.GetUserLoginRecords) // 查询用户登录记录
logRouter.POST("/delete", mw.CheckAdmin, admin.DeleteSensitiveWordLogs) // 删除敏感词日志
// 敏感词统计
statsRouter := sensitiveWordRouter.Group("/stats")
statsRouter.GET("/", mw.CheckAdmin, admin.GetSensitiveWordStats) // 获取敏感词统计
statsRouter.POST("/word_stats", mw.CheckAdmin, admin.GetSensitiveWordStats) // 获取敏感词统计
statsRouter.POST("/log_stats", mw.CheckAdmin, admin.GetSensitiveWordLogStats) // 获取敏感词日志统计
// ==================== 定时任务管理路由 ====================
scheduledTaskRouter := router.Group("/scheduled_task", mw.CheckAdmin)
scheduledTaskRouter.POST("/list", admin.GetScheduledTasks) // 获取定时任务列表
scheduledTaskRouter.POST("/delete", admin.DeleteScheduledTask) // 删除定时任务
// ==================== 系统配置管理路由 ====================
systemConfigRouter := router.Group("/system_config", mw.CheckAdmin)
systemConfigRouter.POST("/create", admin.CreateSystemConfig) // 创建系统配置
systemConfigRouter.POST("/get", admin.GetSystemConfig) // 获取系统配置详情
systemConfigRouter.POST("/list", admin.GetAllSystemConfigs) // 获取所有系统配置(分页)
systemConfigRouter.POST("/update", admin.UpdateSystemConfig) // 更新系统配置
systemConfigRouter.POST("/update_value", admin.UpdateSystemConfigValue) // 更新系统配置值
systemConfigRouter.POST("/update_enabled", admin.UpdateSystemConfigEnabled) // 更新系统配置启用状态
systemConfigRouter.POST("/delete", admin.DeleteSystemConfig) // 删除系统配置
systemConfigRouter.POST("/get_enabled", admin.GetEnabledSystemConfigs) // 获取所有已启用的配置
// ==================== 钱包管理路由 ====================
walletRouter := router.Group("/wallet", mw.CheckAdmin)
walletRouter.POST("/get", admin.GetUserWallet) // 获取用户钱包信息
walletRouter.POST("/get_wallets", admin.GetWallets) // 获取钱包列表
walletRouter.POST("/update_balance", admin.UpdateUserWalletBalance) // 更新用户余额(后台充值/扣款)
walletRouter.POST("/batch_update_balance", admin.BatchUpdateWalletBalance) // 批量更新用户余额(后台批量充值/扣款)
walletRouter.POST("/balance_records", admin.GetUserWalletBalanceRecords) // 获取用户余额变动记录列表
walletRouter.POST("/update_payment_password", admin.UpdateUserPaymentPassword) // 修改用户支付密码
walletRouter.POST("/set_withdraw_account", admin.SetUserWithdrawAccount) // 设置用户提款账号
// ==================== 提现管理路由(操作 withdraw_applications====================
withdrawRouter := router.Group("/withdraw", mw.CheckAdmin)
withdrawRouter.POST("/get", admin.GetWithdraw) // 获取提现申请详情
withdrawRouter.POST("/list", admin.GetWithdraws) // 获取提现申请列表(支持按状态筛选)
withdrawRouter.POST("/user_list", admin.GetUserWithdraws) // 获取用户的提现申请列表
withdrawRouter.POST("/audit", admin.AuditWithdraw) // 审核提现申请
// ==================== 实名认证审核路由 ====================
realNameAuthRouter := router.Group("/real_name_auth", mw.CheckAdmin)
realNameAuthRouter.POST("/list", admin.GetRealNameAuths) // 获取实名认证列表(支持按审核状态筛选)
realNameAuthRouter.POST("/audit", admin.AuditRealNameAuth) // 审核实名认证(通过/拒绝)
}