复制项目
This commit is contained in:
1663
internal/api/admin/admin.go
Normal file
1663
internal/api/admin/admin.go
Normal file
File diff suppressed because it is too large
Load Diff
337
internal/api/admin/config_manager.go
Normal file
337
internal/api/admin/config_manager.go
Normal file
@@ -0,0 +1,337 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"git.imall.cloud/openim/chat/pkg/common/apistruct"
|
||||
"git.imall.cloud/openim/chat/pkg/common/config"
|
||||
"git.imall.cloud/openim/chat/pkg/common/kdisc"
|
||||
"git.imall.cloud/openim/chat/pkg/common/kdisc/etcd"
|
||||
"git.imall.cloud/openim/chat/version"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/openimsdk/tools/apiresp"
|
||||
"github.com/openimsdk/tools/errs"
|
||||
"github.com/openimsdk/tools/log"
|
||||
"github.com/openimsdk/tools/utils/datautil"
|
||||
"github.com/openimsdk/tools/utils/runtimeenv"
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
)
|
||||
|
||||
const (
|
||||
// wait for Restart http call return
|
||||
waitHttp = time.Millisecond * 200
|
||||
)
|
||||
|
||||
type ConfigManager struct {
|
||||
config *config.AllConfig
|
||||
client *clientv3.Client
|
||||
configPath string
|
||||
runtimeEnv string
|
||||
}
|
||||
|
||||
func NewConfigManager(cfg *config.AllConfig, client *clientv3.Client, configPath string, runtimeEnv string) *ConfigManager {
|
||||
return &ConfigManager{
|
||||
config: cfg,
|
||||
client: client,
|
||||
configPath: configPath,
|
||||
runtimeEnv: runtimeEnv,
|
||||
}
|
||||
}
|
||||
|
||||
func (cm *ConfigManager) GetConfig(c *gin.Context) {
|
||||
var req apistruct.GetConfigReq
|
||||
if err := c.BindJSON(&req); err != nil {
|
||||
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
|
||||
return
|
||||
}
|
||||
conf := cm.config.Name2Config(req.ConfigName)
|
||||
if conf == nil {
|
||||
apiresp.GinError(c, errs.ErrArgs.WithDetail("config name not found").Wrap())
|
||||
return
|
||||
}
|
||||
b, err := json.Marshal(conf)
|
||||
if err != nil {
|
||||
apiresp.GinError(c, err)
|
||||
return
|
||||
}
|
||||
apiresp.GinSuccess(c, string(b))
|
||||
}
|
||||
|
||||
func (cm *ConfigManager) GetConfigList(c *gin.Context) {
|
||||
var resp apistruct.GetConfigListResp
|
||||
resp.ConfigNames = cm.config.GetConfigNames()
|
||||
resp.Environment = runtimeenv.PrintRuntimeEnvironment()
|
||||
resp.Version = version.Version
|
||||
|
||||
apiresp.GinSuccess(c, resp)
|
||||
}
|
||||
|
||||
func (cm *ConfigManager) SetConfig(c *gin.Context) {
|
||||
if cm.config.Discovery.Enable != kdisc.ETCDCONST {
|
||||
apiresp.GinError(c, errs.New("only etcd support set config").Wrap())
|
||||
return
|
||||
}
|
||||
var req apistruct.SetConfigReq
|
||||
if err := c.BindJSON(&req); err != nil {
|
||||
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
|
||||
return
|
||||
}
|
||||
var err error
|
||||
switch req.ConfigName {
|
||||
case config.DiscoveryConfigFileName:
|
||||
err = compareAndSave[config.Discovery](c, cm.config.Name2Config(req.ConfigName), &req, cm.client)
|
||||
case config.LogConfigFileName:
|
||||
err = compareAndSave[config.Log](c, cm.config.Name2Config(req.ConfigName), &req, cm.client)
|
||||
case config.MongodbConfigFileName:
|
||||
err = compareAndSave[config.Mongo](c, cm.config.Name2Config(req.ConfigName), &req, cm.client)
|
||||
case config.ChatAPIAdminCfgFileName:
|
||||
err = compareAndSave[config.API](c, cm.config.Name2Config(req.ConfigName), &req, cm.client)
|
||||
case config.ChatAPIChatCfgFileName:
|
||||
err = compareAndSave[config.API](c, cm.config.Name2Config(req.ConfigName), &req, cm.client)
|
||||
case config.ChatRPCAdminCfgFileName:
|
||||
err = compareAndSave[config.Admin](c, cm.config.Name2Config(req.ConfigName), &req, cm.client)
|
||||
case config.ChatRPCChatCfgFileName:
|
||||
err = compareAndSave[config.Chat](c, cm.config.Name2Config(req.ConfigName), &req, cm.client)
|
||||
case config.ShareFileName:
|
||||
err = compareAndSave[config.Share](c, cm.config.Name2Config(req.ConfigName), &req, cm.client)
|
||||
case config.RedisConfigFileName:
|
||||
err = compareAndSave[config.Redis](c, cm.config.Name2Config(req.ConfigName), &req, cm.client)
|
||||
default:
|
||||
apiresp.GinError(c, errs.ErrArgs.Wrap())
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
|
||||
return
|
||||
}
|
||||
apiresp.GinSuccess(c, nil)
|
||||
}
|
||||
|
||||
func (cm *ConfigManager) SetConfigs(c *gin.Context) {
|
||||
if cm.config.Discovery.Enable != kdisc.ETCDCONST {
|
||||
apiresp.GinError(c, errs.New("only etcd support set config").Wrap())
|
||||
return
|
||||
}
|
||||
var req apistruct.SetConfigsReq
|
||||
if err := c.BindJSON(&req); err != nil {
|
||||
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
|
||||
return
|
||||
}
|
||||
var (
|
||||
err error
|
||||
ops []*clientv3.Op
|
||||
)
|
||||
|
||||
for _, cf := range req.Configs {
|
||||
var op *clientv3.Op
|
||||
switch cf.ConfigName {
|
||||
case config.DiscoveryConfigFileName:
|
||||
op, err = compareAndOp[config.Discovery](c, cm.config.Name2Config(cf.ConfigName), &cf, cm.client)
|
||||
case config.LogConfigFileName:
|
||||
op, err = compareAndOp[config.Log](c, cm.config.Name2Config(cf.ConfigName), &cf, cm.client)
|
||||
case config.MongodbConfigFileName:
|
||||
op, err = compareAndOp[config.Mongo](c, cm.config.Name2Config(cf.ConfigName), &cf, cm.client)
|
||||
case config.ChatAPIAdminCfgFileName:
|
||||
op, err = compareAndOp[config.API](c, cm.config.Name2Config(cf.ConfigName), &cf, cm.client)
|
||||
case config.ChatAPIChatCfgFileName:
|
||||
op, err = compareAndOp[config.API](c, cm.config.Name2Config(cf.ConfigName), &cf, cm.client)
|
||||
case config.ChatRPCAdminCfgFileName:
|
||||
op, err = compareAndOp[config.Admin](c, cm.config.Name2Config(cf.ConfigName), &cf, cm.client)
|
||||
case config.ChatRPCChatCfgFileName:
|
||||
op, err = compareAndOp[config.Chat](c, cm.config.Name2Config(cf.ConfigName), &cf, cm.client)
|
||||
case config.ShareFileName:
|
||||
op, err = compareAndOp[config.Share](c, cm.config.Name2Config(cf.ConfigName), &cf, cm.client)
|
||||
case config.RedisConfigFileName:
|
||||
op, err = compareAndOp[config.Redis](c, cm.config.Name2Config(cf.ConfigName), &cf, cm.client)
|
||||
default:
|
||||
apiresp.GinError(c, errs.ErrArgs.Wrap())
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
|
||||
return
|
||||
}
|
||||
if op != nil {
|
||||
ops = append(ops, op)
|
||||
}
|
||||
}
|
||||
if len(ops) > 0 {
|
||||
tx := cm.client.Txn(c)
|
||||
if _, err = tx.Then(datautil.Batch(func(op *clientv3.Op) clientv3.Op { return *op }, ops)...).Commit(); err != nil {
|
||||
apiresp.GinError(c, errs.WrapMsg(err, "save to etcd failed"))
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
apiresp.GinSuccess(c, nil)
|
||||
}
|
||||
|
||||
func compareAndOp[T any](c *gin.Context, old any, req *apistruct.SetConfigReq, client *clientv3.Client) (*clientv3.Op, error) {
|
||||
conf := new(T)
|
||||
err := json.Unmarshal([]byte(req.Data), &conf)
|
||||
if err != nil {
|
||||
return nil, errs.ErrArgs.WithDetail(err.Error()).Wrap()
|
||||
}
|
||||
eq := reflect.DeepEqual(old, conf)
|
||||
if eq {
|
||||
return nil, nil
|
||||
}
|
||||
data, err := json.Marshal(conf)
|
||||
if err != nil {
|
||||
return nil, errs.ErrArgs.WithDetail(err.Error()).Wrap()
|
||||
}
|
||||
op := clientv3.OpPut(etcd.BuildKey(req.ConfigName), string(data))
|
||||
return &op, nil
|
||||
}
|
||||
|
||||
func compareAndSave[T any](c *gin.Context, old any, req *apistruct.SetConfigReq, client *clientv3.Client) error {
|
||||
conf := new(T)
|
||||
err := json.Unmarshal([]byte(req.Data), &conf)
|
||||
if err != nil {
|
||||
return errs.ErrArgs.WithDetail(err.Error()).Wrap()
|
||||
}
|
||||
eq := reflect.DeepEqual(old, conf)
|
||||
if eq {
|
||||
return nil
|
||||
}
|
||||
data, err := json.Marshal(conf)
|
||||
if err != nil {
|
||||
return errs.ErrArgs.WithDetail(err.Error()).Wrap()
|
||||
}
|
||||
_, err = client.Put(c, etcd.BuildKey(req.ConfigName), string(data))
|
||||
if err != nil {
|
||||
return errs.WrapMsg(err, "save to etcd failed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cm *ConfigManager) ResetConfig(c *gin.Context) {
|
||||
go func() {
|
||||
if err := cm.resetConfig(c, true); err != nil {
|
||||
log.ZError(c, "reset config err", err)
|
||||
}
|
||||
}()
|
||||
apiresp.GinSuccess(c, nil)
|
||||
}
|
||||
|
||||
func (cm *ConfigManager) resetConfig(c *gin.Context, checkChange bool, ops ...clientv3.Op) error {
|
||||
txn := cm.client.Txn(c)
|
||||
type initConf struct {
|
||||
old any
|
||||
new any
|
||||
}
|
||||
configMap := map[string]*initConf{
|
||||
config.DiscoveryConfigFileName: {old: &cm.config.Discovery, new: new(config.Discovery)},
|
||||
config.LogConfigFileName: {old: &cm.config.Log, new: new(config.Log)},
|
||||
config.MongodbConfigFileName: {old: &cm.config.Mongo, new: new(config.Mongo)},
|
||||
config.ChatAPIAdminCfgFileName: {old: &cm.config.AdminAPI, new: new(config.API)},
|
||||
config.ChatAPIChatCfgFileName: {old: &cm.config.ChatAPI, new: new(config.API)},
|
||||
config.ChatRPCAdminCfgFileName: {old: &cm.config.Admin, new: new(config.Admin)},
|
||||
config.ChatRPCChatCfgFileName: {old: &cm.config.Chat, new: new(config.Chat)},
|
||||
config.RedisConfigFileName: {old: &cm.config.Redis, new: new(config.Redis)},
|
||||
config.ShareFileName: {old: &cm.config.Share, new: new(config.Share)},
|
||||
}
|
||||
|
||||
changedKeys := make([]string, 0, len(configMap))
|
||||
for k, v := range configMap {
|
||||
err := config.Load(
|
||||
cm.configPath,
|
||||
k,
|
||||
config.EnvPrefixMap[k],
|
||||
cm.runtimeEnv,
|
||||
v.new,
|
||||
)
|
||||
if err != nil {
|
||||
log.ZError(c, "load config failed", err)
|
||||
continue
|
||||
}
|
||||
equal := reflect.DeepEqual(v.old, v.new)
|
||||
if !checkChange || !equal {
|
||||
changedKeys = append(changedKeys, k)
|
||||
}
|
||||
}
|
||||
|
||||
for _, k := range changedKeys {
|
||||
data, err := json.Marshal(configMap[k].new)
|
||||
if err != nil {
|
||||
log.ZError(c, "marshal config failed", err)
|
||||
continue
|
||||
}
|
||||
ops = append(ops, clientv3.OpPut(etcd.BuildKey(k), string(data)))
|
||||
}
|
||||
if len(ops) > 0 {
|
||||
txn.Then(ops...)
|
||||
_, err := txn.Commit()
|
||||
if err != nil {
|
||||
return errs.WrapMsg(err, "commit etcd txn failed")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cm *ConfigManager) Restart(c *gin.Context) {
|
||||
go cm.restart(c)
|
||||
apiresp.GinSuccess(c, nil)
|
||||
}
|
||||
|
||||
func (cm *ConfigManager) restart(c *gin.Context) {
|
||||
time.Sleep(waitHttp) // wait for Restart http call return
|
||||
t := time.Now().Unix()
|
||||
_, err := cm.client.Put(c, etcd.BuildKey(etcd.RestartKey), strconv.Itoa(int(t)))
|
||||
if err != nil {
|
||||
log.ZError(c, "restart etcd put key failed", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (cm *ConfigManager) SetEnableConfigManager(c *gin.Context) {
|
||||
var req apistruct.SetEnableConfigManagerReq
|
||||
if err := c.BindJSON(&req); err != nil {
|
||||
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
|
||||
return
|
||||
}
|
||||
var enableStr string
|
||||
if req.Enable {
|
||||
enableStr = etcd.Enable
|
||||
} else {
|
||||
enableStr = etcd.Disable
|
||||
}
|
||||
resp, err := cm.client.Get(c, etcd.BuildKey(etcd.EnableConfigCenterKey))
|
||||
if err != nil {
|
||||
apiresp.GinError(c, errs.WrapMsg(err, "getEnableConfigManager failed"))
|
||||
return
|
||||
}
|
||||
if !(resp.Count > 0 && string(resp.Kvs[0].Value) == etcd.Enable) && req.Enable {
|
||||
go func() {
|
||||
time.Sleep(waitHttp) // wait for Restart http call return
|
||||
err := cm.resetConfig(c, false, clientv3.OpPut(etcd.BuildKey(etcd.EnableConfigCenterKey), enableStr))
|
||||
if err != nil {
|
||||
log.ZError(c, "writeAllConfig failed", err)
|
||||
}
|
||||
}()
|
||||
} else {
|
||||
_, err = cm.client.Put(c, etcd.BuildKey(etcd.EnableConfigCenterKey), enableStr)
|
||||
if err != nil {
|
||||
apiresp.GinError(c, errs.WrapMsg(err, "setEnableConfigManager failed"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
apiresp.GinSuccess(c, nil)
|
||||
}
|
||||
|
||||
func (cm *ConfigManager) GetEnableConfigManager(c *gin.Context) {
|
||||
resp, err := cm.client.Get(c, etcd.BuildKey(etcd.EnableConfigCenterKey))
|
||||
if err != nil {
|
||||
apiresp.GinError(c, errs.WrapMsg(err, "getEnableConfigManager failed"))
|
||||
return
|
||||
}
|
||||
var enable bool
|
||||
if resp.Count > 0 && string(resp.Kvs[0].Value) == etcd.Enable {
|
||||
enable = true
|
||||
}
|
||||
apiresp.GinSuccess(c, &apistruct.GetEnableConfigManagerResp{Enable: enable})
|
||||
}
|
||||
314
internal/api/admin/start.go
Normal file
314
internal/api/admin/start.go
Normal file
@@ -0,0 +1,314 @@
|
||||
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) // 审核实名认证(通过/拒绝)
|
||||
}
|
||||
Reference in New Issue
Block a user