From 7568b0435a424647370292f62148561a3b78a529 Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Fri, 8 Sep 2023 21:54:47 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4UDM=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=AF=BC=E5=87=BACSV=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- features/udm_user/api_udm_user.go | 39 +++++++++++-- features/udm_user/repo/repo_udm_auth_user.go | 55 ++++++++++++++++++- features/udm_user/repo/repo_udm_sub_user.go | 53 ++++++++++++++++++ .../udm_user/service/service_udm_auth_user.go | 32 ++++------- .../udm_user/service/service_udm_sub_user.go | 39 +++++-------- lib/core/file/csv.go | 43 +++++++++++++++ lib/core/utils/ctx/ctx.go | 8 +++ 7 files changed, 217 insertions(+), 52 deletions(-) create mode 100644 lib/core/file/csv.go diff --git a/features/udm_user/api_udm_user.go b/features/udm_user/api_udm_user.go index f8c2161d..5511572a 100644 --- a/features/udm_user/api_udm_user.go +++ b/features/udm_user/api_udm_user.go @@ -4,7 +4,9 @@ import ( "fmt" "net/http" + "ems.agt/features/udm_user/model" "ems.agt/features/udm_user/service" + "ems.agt/lib/core/file" mmlclient "ems.agt/lib/core/mml_client" "ems.agt/lib/core/utils/ctx" "ems.agt/lib/core/vo/result" @@ -42,6 +44,12 @@ func Routers() []services.RouterItem { Handler: apis.UdmAuthUserInfo, Middleware: nil, //midware.Authorize(nil), }, + { + Method: "POST", + Pattern: "/auth/export", + Handler: apis.UdmAuthUserExport, + Middleware: nil, //midware.Authorize(nil), + }, // UDM签约用户 { Method: "GET", @@ -101,7 +109,7 @@ type UdmUserApi struct { // GET /auths func (s *UdmUserApi) UdmAuthUserList(w http.ResponseWriter, r *http.Request) { querys := ctx.QueryMap(r) - data := s.authUser.AuthUserList(querys) + data := s.authUser.Page(querys) ctx.JSON(w, 200, result.Ok(data)) } @@ -109,7 +117,7 @@ func (s *UdmUserApi) UdmAuthUserList(w http.ResponseWriter, r *http.Request) { // // POST /auth/getSave func (s *UdmUserApi) UdmAuthUserSave(w http.ResponseWriter, r *http.Request) { - data := s.authUser.AuthUserSave("") + data := s.authUser.Save("") ctx.JSON(w, 200, result.OkData(data)) } @@ -141,12 +149,35 @@ func (s *UdmUserApi) UdmAuthUserInfo(w http.ResponseWriter, r *http.Request) { ctx.JSON(w, 200, result.OkData(data)) } +// UDM鉴权用户-导出 +// +// POST /auth/export +func (s *UdmUserApi) UdmAuthUserExport(w http.ResponseWriter, r *http.Request) { + list := s.authUser.List(model.UdmAuthUser{}) + // 文件名 + fileName := "OMC_AUTH_100.csv" + filePath := "C:/AMP/Probject/ems_backend/restagent/OMC_AUTH_100.csv" + // 转换数据 + data := [][]string{} + data = append(data, []string{"ID", "Msisdn", "Imsi", "Amf", "Status", "Ki", "AlgoIndex", "Opc"}) + for _, v := range list { + data = append(data, []string{v.ID, v.Msisdn, v.Imsi, v.Amf, v.Status, v.Ki, v.AlgoIndex, v.Opc}) + } + // 输出到文件 + err := file.WriterCSVFile(data, filePath) + if err != nil { + ctx.JSON(w, 200, result.ErrMsg(err.Error())) + return + } + ctx.FileAttachment(w, r, filePath, fileName) +} + // UDM签约用户 // // GET /subs func (s *UdmUserApi) UdmSubUserList(w http.ResponseWriter, r *http.Request) { querys := ctx.QueryMap(r) - data := s.subUser.SubUserList(querys) + data := s.subUser.Page(querys) ctx.JSON(w, 200, result.Ok(data)) } @@ -154,7 +185,7 @@ func (s *UdmUserApi) UdmSubUserList(w http.ResponseWriter, r *http.Request) { // // POST /sub/getSave func (s *UdmUserApi) UdmSubUserSave(w http.ResponseWriter, r *http.Request) { - data := s.subUser.SubUserSave("") + data := s.subUser.Save("") ctx.JSON(w, 200, result.OkData(data)) } diff --git a/features/udm_user/repo/repo_udm_auth_user.go b/features/udm_user/repo/repo_udm_auth_user.go index ad1280af..532d9f74 100644 --- a/features/udm_user/repo/repo_udm_auth_user.go +++ b/features/udm_user/repo/repo_udm_auth_user.go @@ -51,7 +51,7 @@ func (r *RepoUdmAuthUser) convertResultRows(rows []map[string]any) []model.UdmAu return arr } -// SelectPage 根据条件分页查询字典类型 +// SelectPage 根据条件分页查询 func (r *RepoUdmAuthUser) SelectPage(query map[string]any) map[string]any { // 查询条件拼接 var conditions []string @@ -105,3 +105,56 @@ func (r *RepoUdmAuthUser) SelectPage(query map[string]any) map[string]any { "rows": rows, } } + +// SelectList 根据实体查询 +func (r *RepoUdmAuthUser) SelectList(auth model.UdmAuthUser) []model.UdmAuthUser { + // 查询条件拼接 + var conditions []string + var params []any + if auth.Imsi != "" { + conditions = append(conditions, "msisdn like concat(?, '%')") + params = append(params, auth.Imsi) + } + if auth.NeID != "" { + conditions = append(conditions, "ne_id = ?") + params = append(params, auth.NeID) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + // 查询数据 + querySql := r.selectSql + whereSql + results, err := datasource.RawDB("", querySql, params) + if err != nil { + log.Errorf("query err => %v", err) + } + + // 转换实体 + return r.convertResultRows(results) +} + +// Insert 清空ne_id后新增实体 +func (r *RepoUdmAuthUser) Inserts(neID string, authArr []model.UdmAuthUser) int64 { + var num int64 = 0 + + // 清空指定ne_id + _, err := datasource.ExecDB("", "DELETE FROM u_auth_user WHERE ne_id = ?", []any{neID}) + if err != nil { + log.Errorf("TRUNCATE err => %v", err) + return num + } + + for _, u := range authArr { + u.NeID = neID + results, err := datasource.DefaultDB().Table("u_auth_user").Insert(u) + if err != nil { + return num + } + num += results + } + return num +} diff --git a/features/udm_user/repo/repo_udm_sub_user.go b/features/udm_user/repo/repo_udm_sub_user.go index aa7d4d66..e5f95614 100644 --- a/features/udm_user/repo/repo_udm_sub_user.go +++ b/features/udm_user/repo/repo_udm_sub_user.go @@ -112,3 +112,56 @@ func (r *RepoUdmSubUser) SelectPage(query map[string]any) map[string]any { "rows": rows, } } + +// SelectList 根据实体查询 +func (r *RepoUdmSubUser) SelectList(auth model.UdmSubUser) []model.UdmSubUser { + // 查询条件拼接 + var conditions []string + var params []any + if auth.Imsi != "" { + conditions = append(conditions, "msisdn like concat(?, '%')") + params = append(params, auth.Imsi) + } + if auth.NeID != "" { + conditions = append(conditions, "ne_id = ?") + params = append(params, auth.NeID) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + // 查询数据 + querySql := r.selectSql + whereSql + results, err := datasource.RawDB("", querySql, params) + if err != nil { + log.Errorf("query err => %v", err) + } + + // 转换实体 + return r.convertResultRows(results) +} + +// Insert 清空ne_id后新增实体 +func (r *RepoUdmSubUser) Inserts(neID string, authArr []model.UdmSubUser) int64 { + var num int64 = 0 + + // 清空指定ne_id + // _, err := datasource.ExecDB("", "TRUNCATE TABLE u_sub_user", nil) + _, err := datasource.ExecDB("", "DELETE FROM u_sub_user WHERE ne_id = ?", []any{neID}) + if err != nil { + log.Errorf("TRUNCATE err => %v", err) + } + + for _, u := range authArr { + u.NeID = neID + results, err := datasource.DefaultDB().Table("u_sub_user").Insert(u) + if err != nil { + return num + } + num += results + } + return num +} diff --git a/features/udm_user/service/service_udm_auth_user.go b/features/udm_user/service/service_udm_auth_user.go index 6625f110..c708ca9c 100644 --- a/features/udm_user/service/service_udm_auth_user.go +++ b/features/udm_user/service/service_udm_auth_user.go @@ -1,9 +1,8 @@ package service import ( + "ems.agt/features/udm_user/model" "ems.agt/features/udm_user/repo" - "ems.agt/lib/core/datasource" - "ems.agt/lib/log" ) // 实例化服务层 ServiceUdmAuthUser 结构体 @@ -16,32 +15,23 @@ type ServiceUdmAuthUser struct { repoAuthUser repo.RepoUdmAuthUser } -// AuthUserSave UDM鉴权用户-获取全部保存数据库 -func (r *ServiceUdmAuthUser) AuthUserSave(neID string) int64 { +// Save UDM鉴权用户-获取全部保存数据库 +func (r *ServiceUdmAuthUser) Save(neID string) int64 { var num int64 = 0 authArr := redisUdmAuthUserList() // 有数据才清空 if len(authArr) == 0 { return num } - - _, err := datasource.ExecDB("", "DELETE FROM u_auth_user WHERE ne_id = ?", []any{neID}) - if err != nil { - log.Errorf("TRUNCATE err => %v", err) - } - - for _, u := range authArr { - results, err := datasource.DefaultDB().Table("u_auth_user").Insert(u) - if err != nil { - log.Errorf("Insert err => %v", err) - return 0 - } - num += results - } - return num + return r.repoAuthUser.Inserts(neID, authArr) } -// SubUserSave UDM签约用户-分页查询数据库 -func (r *ServiceUdmAuthUser) AuthUserList(query map[string]any) map[string]any { +// Page UDM签约用户-分页查询数据库 +func (r *ServiceUdmAuthUser) Page(query map[string]any) map[string]any { return r.repoAuthUser.SelectPage(query) } + +// List UDM签约用户-查询数据库 +func (r *ServiceUdmAuthUser) List(authUser model.UdmAuthUser) []model.UdmAuthUser { + return r.repoAuthUser.SelectList(authUser) +} diff --git a/features/udm_user/service/service_udm_sub_user.go b/features/udm_user/service/service_udm_sub_user.go index c0904c0d..9d8d10a4 100644 --- a/features/udm_user/service/service_udm_sub_user.go +++ b/features/udm_user/service/service_udm_sub_user.go @@ -1,50 +1,37 @@ package service import ( + "ems.agt/features/udm_user/model" "ems.agt/features/udm_user/repo" - "ems.agt/lib/core/datasource" - "ems.agt/lib/log" ) // 实例化服务层 ServiceUdmSubUser 结构体 var NewServiceUdmSubUser = &ServiceUdmSubUser{ - repoAuthUser: *repo.NewRepoUdmAuthUser, - repoSunUser: *repo.NewRepoUdmSubUser, + repoSunUser: *repo.NewRepoUdmSubUser, } // ServiceUdmSubUser UDM签约用户 服务层处理 type ServiceUdmSubUser struct { - repoAuthUser repo.RepoUdmAuthUser - repoSunUser repo.RepoUdmSubUser + repoSunUser repo.RepoUdmSubUser } -// SubUserSave UDM签约用户-获取全部保存数据库 -func (r *ServiceUdmSubUser) SubUserSave(neID string) int64 { +// Save UDM签约用户-获取全部保存数据库 +func (r *ServiceUdmSubUser) Save(neID string) int64 { var num int64 = 0 subArr := redisUdmSubUserList() // 有数据才清空 if len(subArr) == 0 { return num } - - // _, err := datasource.ExecDB("", "TRUNCATE TABLE u_sub_user", nil) - _, err := datasource.ExecDB("", "DELETE FROM u_sub_user WHERE ne_id = ?", []any{neID}) - if err != nil { - log.Errorf("TRUNCATE err => %v", err) - } - - for _, u := range subArr { - results, err := datasource.DefaultDB().Table("u_sub_user").Insert(u) - if err != nil { - log.Errorf("Insert err => %v", err) - return 0 - } - num += results - } - return num + return r.repoSunUser.Inserts(neID, subArr) } -// SubUserSave UDM签约用户-分页查询数据库 -func (r *ServiceUdmSubUser) SubUserList(query map[string]any) map[string]any { +// Page UDM签约用户-分页查询数据库 +func (r *ServiceUdmSubUser) Page(query map[string]any) map[string]any { return r.repoSunUser.SelectPage(query) } + +// List UDM签约用户-查询数据库 +func (r *ServiceUdmSubUser) List(subUser model.UdmSubUser) []model.UdmSubUser { + return r.repoSunUser.SelectList(subUser) +} diff --git a/lib/core/file/csv.go b/lib/core/file/csv.go new file mode 100644 index 00000000..ad7763f5 --- /dev/null +++ b/lib/core/file/csv.go @@ -0,0 +1,43 @@ +package file + +import ( + "encoding/csv" + "os" + "path/filepath" + + "ems.agt/lib/log" +) + +// 写入CSV文件,需要转换数据 +// 例如: +// data := [][]string{} +// data = append(data, []string{"姓名", "年龄", "城市"}) +// data = append(data, []string{"1", "2", "3"}) +// err := file.WriterCSVFile(data, filePath) +func WriterCSVFile(data [][]string, filePath string) error { + // 获取文件所在的目录路径 + dirPath := filepath.Dir(filePath) + + // 确保文件夹路径存在 + err := os.MkdirAll(dirPath, os.ModePerm) + if err != nil { + log.Errorf("创建文件夹失败 CreateFile %v", err) + } + + // 创建或打开文件 + file, err := os.Create(filePath) + if err != nil { + return err + } + defer file.Close() + + // 创建CSV编写器 + writer := csv.NewWriter(file) + defer writer.Flush() + + // 写入数据 + for _, row := range data { + writer.Write(row) + } + return nil +} diff --git a/lib/core/utils/ctx/ctx.go b/lib/core/utils/ctx/ctx.go index 21570310..59a5f2e4 100644 --- a/lib/core/utils/ctx/ctx.go +++ b/lib/core/utils/ctx/ctx.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "net/http" + "net/url" "ems.agt/lib/core/vo" "github.com/gorilla/mux" @@ -59,6 +60,13 @@ func JSON(w http.ResponseWriter, code int, data any) { } } +// 将文件导出到外部下载 +func FileAttachment(w http.ResponseWriter, r *http.Request, filepath, filename string) { + w.Header().Set("Content-Disposition", `attachment; filename=`+url.QueryEscape(filename)) + w.Header().Set("Content-Type", "application/octet-stream") + http.ServeFile(w, r, filepath) +} + /// ==== 登录用户信息, 通过中间件后预置入 // 定义自定义类型作为键