|
@@ -0,0 +1,377 @@
|
|
|
+package api
|
|
|
+
|
|
|
+import (
|
|
|
+ "errors"
|
|
|
+ "fmt"
|
|
|
+ "oilseal-train/db/model"
|
|
|
+ "oilseal-train/db/repo"
|
|
|
+ "os"
|
|
|
+ "strings"
|
|
|
+ "time"
|
|
|
+
|
|
|
+ "github.com/gin-gonic/gin"
|
|
|
+ "github.com/xuri/excelize/v2"
|
|
|
+ "go.mongodb.org/mongo-driver/bson"
|
|
|
+ "go.mongodb.org/mongo-driver/bson/primitive"
|
|
|
+)
|
|
|
+
|
|
|
+func User(r *GinRouter) {
|
|
|
+ r.POST("/user/login", Login)
|
|
|
+ r.POST("/user/register", Register)
|
|
|
+ r.POSTJWT("/user/create", UserAdd)
|
|
|
+ r.GETJWT("/user/list", UserList)
|
|
|
+ r.POSTJWT("/user/update", UserEdit)
|
|
|
+ r.POSTJWT("/user/delete/:id", UserDelete)
|
|
|
+ r.GETJWT("/user/exportXls", UserExportXls)
|
|
|
+ r.POSTJWT("/user/importXls", UserImportXls)
|
|
|
+}
|
|
|
+
|
|
|
+// 用户登录 student teacher admin
|
|
|
+func Login(c *gin.Context, apictx *ApiSession) (interface{}, error) {
|
|
|
+ var form model.User
|
|
|
+
|
|
|
+ err := c.ShouldBindJSON(&form)
|
|
|
+ if err != nil {
|
|
|
+ return nil, errors.New("参数错误")
|
|
|
+ }
|
|
|
+
|
|
|
+ ctx := apictx.CreateRepoCtx()
|
|
|
+ // 查找用户
|
|
|
+ user := &model.User{}
|
|
|
+ options := &repo.DocSearchOptions{
|
|
|
+ Query: repo.Map{"loginName": form.LoginName, "password": UtilMd5(form.Password)},
|
|
|
+ CollectName: repo.CollectionUser,
|
|
|
+ }
|
|
|
+ found, err := repo.RepoSeachDoc(ctx, options, user)
|
|
|
+ if err != nil {
|
|
|
+ return false, err
|
|
|
+ }
|
|
|
+ if !found {
|
|
|
+ return false, NewError("账号密码不对")
|
|
|
+ }
|
|
|
+ if user.State == -1 {
|
|
|
+ return false, NewError("当前用户已禁用")
|
|
|
+ }
|
|
|
+ if form.Role != user.Role {
|
|
|
+ return false, NewError("当前账号角色不正确")
|
|
|
+ }
|
|
|
+
|
|
|
+ // 封装JWT
|
|
|
+ jwtU := &JWTUser{ID: user.Id.Hex(), Name: user.Name, LoginName: user.LoginName, State: 1, Role: user.Role}
|
|
|
+
|
|
|
+ token, _, err := apictx.Svc.JWT.JwtCreateToken(jwtU)
|
|
|
+ if err != nil {
|
|
|
+ return false, err
|
|
|
+ }
|
|
|
+
|
|
|
+ // 前端返回处理
|
|
|
+ user.Password = ""
|
|
|
+ out := map[string]interface{}{
|
|
|
+ "token": token,
|
|
|
+ "user": user,
|
|
|
+ }
|
|
|
+ return out, nil
|
|
|
+}
|
|
|
+
|
|
|
+// 创建账号 主要用于admin注册
|
|
|
+func Register(c *gin.Context, apictx *ApiSession) (interface{}, error) {
|
|
|
+ var form model.User
|
|
|
+ err := c.ShouldBindJSON(&form)
|
|
|
+ if err != nil {
|
|
|
+ return nil, errors.New("参数错误")
|
|
|
+ }
|
|
|
+ if form.LoginName == "" {
|
|
|
+ return nil, errors.New("登录名为空")
|
|
|
+ }
|
|
|
+ if form.Password == "" {
|
|
|
+ return nil, errors.New("密码为空")
|
|
|
+ }
|
|
|
+ form.Role = "admin"
|
|
|
+ form.State = 1
|
|
|
+ form.Password = UtilMd5(form.Password)
|
|
|
+ form.CreateTime = time.Now()
|
|
|
+ form.UpdateTime = time.Now()
|
|
|
+ return repo.RepoAddDoc(apictx.CreateRepoCtx(), repo.CollectionUser, &form)
|
|
|
+}
|
|
|
+
|
|
|
+// 添加用户
|
|
|
+func UserAdd(c *gin.Context, apictx *ApiSession) (interface{}, error) {
|
|
|
+ // 操作用户为admin
|
|
|
+ if apictx.User.Role != "admin" {
|
|
|
+ return nil, errors.New("当前用户不是管理员")
|
|
|
+ }
|
|
|
+ var form model.User
|
|
|
+ err := c.ShouldBindJSON(&form)
|
|
|
+ if err != nil {
|
|
|
+ return nil, errors.New("参数错误")
|
|
|
+ }
|
|
|
+ if form.LoginName == "" {
|
|
|
+ return nil, errors.New("登录名为空")
|
|
|
+ }
|
|
|
+ if form.Password == "" {
|
|
|
+ return nil, errors.New("密码为空")
|
|
|
+ }
|
|
|
+ if form.Role == "" {
|
|
|
+ return nil, errors.New("角色为空")
|
|
|
+ }
|
|
|
+ form.State = 1
|
|
|
+ form.Password = UtilMd5(form.Password)
|
|
|
+ form.CreateTime = time.Now()
|
|
|
+ form.UpdateTime = time.Now()
|
|
|
+ return repo.RepoAddDoc(apictx.CreateRepoCtx(), repo.CollectionUser, &form)
|
|
|
+}
|
|
|
+
|
|
|
+// 用户列表 模糊匹配
|
|
|
+func UserList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
|
|
|
+ // 操作用户为admin
|
|
|
+ if apictx.User.Role != "admin" {
|
|
|
+ return nil, errors.New("当前用户不是管理员")
|
|
|
+ }
|
|
|
+ page, size, query := UtilQueryPageSize(c)
|
|
|
+ if _name, ok := query["name"]; ok {
|
|
|
+ query["name"] = bson.M{"$regex": _name.(string)}
|
|
|
+ }
|
|
|
+ if _loginName, ok := query["loginName"]; ok {
|
|
|
+ query["loginName"] = bson.M{"$regex": _loginName.(string)}
|
|
|
+ }
|
|
|
+ return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
|
|
|
+ CollectName: repo.CollectionUser,
|
|
|
+ Page: page,
|
|
|
+ Size: size,
|
|
|
+ Query: query,
|
|
|
+ Project: []string{"name", "loginName", "role", "createTime", "updateTime"},
|
|
|
+ Sort: bson.M{"_id": -1},
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 更新用户
|
|
|
+func UserEdit(c *gin.Context, apictx *ApiSession) (interface{}, error) {
|
|
|
+ // 操作用户为admin
|
|
|
+ if apictx.User.Role != "admin" {
|
|
|
+ return nil, errors.New("当前用户不是管理员")
|
|
|
+ }
|
|
|
+ var form model.User
|
|
|
+ err := c.ShouldBindJSON(&form)
|
|
|
+ if err != nil {
|
|
|
+ return nil, errors.New("参数错误")
|
|
|
+ }
|
|
|
+ if len(form.Id) != 12 {
|
|
|
+ return nil, errors.New("id不正确")
|
|
|
+ }
|
|
|
+
|
|
|
+ return repo.RepoUpdateSetDoc(apictx.CreateRepoCtx(), repo.CollectionUser, form.Id.Hex(), &form)
|
|
|
+}
|
|
|
+
|
|
|
+// 删除用户
|
|
|
+func UserDelete(c *gin.Context, apictx *ApiSession) (interface{}, error) {
|
|
|
+ // 操作用户为admin
|
|
|
+ if apictx.User.Role != "admin" {
|
|
|
+ return nil, errors.New("当前用户不是管理员")
|
|
|
+ }
|
|
|
+ _id := c.Param("id")
|
|
|
+ _, err := primitive.ObjectIDFromHex(_id)
|
|
|
+ if err != nil {
|
|
|
+ return nil, errors.New("id错误")
|
|
|
+ }
|
|
|
+ return repo.RepoDeleteDoc(apictx.CreateRepoCtx(), repo.CollectionUser, _id)
|
|
|
+}
|
|
|
+
|
|
|
+type ExcelColumn struct {
|
|
|
+ Style int
|
|
|
+ Width float64
|
|
|
+ Header string
|
|
|
+ Key string
|
|
|
+}
|
|
|
+
|
|
|
+// 6396e841e90c9e38d70793d0,6396e841e90c9e38d70793d0
|
|
|
+func UserExportXls(c *gin.Context, apictx *ApiSession) (interface{}, error) {
|
|
|
+ // 操作用户为admin
|
|
|
+ if apictx.User.Role != "admin" {
|
|
|
+ return nil, errors.New("当前用户不是管理员")
|
|
|
+ }
|
|
|
+ selections := c.Query("selections")
|
|
|
+ query := repo.Map{}
|
|
|
+ if len(selections) > 12 {
|
|
|
+ selects := strings.Split(selections, ",")
|
|
|
+ query["_id"] = bson.M{"$in": selects}
|
|
|
+ }
|
|
|
+ users := make([]map[string]interface{}, 0)
|
|
|
+ err := repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
|
|
|
+ CollectName: repo.CollectionUser,
|
|
|
+ Query: query,
|
|
|
+ Sort: bson.M{"_id": -1},
|
|
|
+ }, &users)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ if len(users) < 1 {
|
|
|
+ return users, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ f := excelize.NewFile()
|
|
|
+ defer f.Close()
|
|
|
+
|
|
|
+ sheetName := "用户列表"
|
|
|
+ f.SetSheetName("Sheet1", sheetName)
|
|
|
+ f.SetPageLayout(sheetName, excelize.PageLayoutOrientation("portrait"), excelize.PageLayoutPaperSize(9))
|
|
|
+
|
|
|
+ f.SetHeaderFooter(sheetName, &excelize.FormatHeaderFooter{
|
|
|
+ FirstHeader: "用户列表",
|
|
|
+ FirstFooter: "用户列表",
|
|
|
+ OddFooter: "第 &P 页,共 &N页",
|
|
|
+ })
|
|
|
+
|
|
|
+ style, _ := f.NewStyle(&excelize.Style{
|
|
|
+ Alignment: &excelize.Alignment{
|
|
|
+ Horizontal: "center",
|
|
|
+ Vertical: "center",
|
|
|
+ },
|
|
|
+ })
|
|
|
+ columns := []ExcelColumn{
|
|
|
+ {
|
|
|
+ Style: style,
|
|
|
+ Width: 20,
|
|
|
+ Header: "登录名",
|
|
|
+ Key: "loginName",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Style: style,
|
|
|
+ Width: 20,
|
|
|
+ Header: "姓名",
|
|
|
+ Key: "name",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Style: style,
|
|
|
+ Width: 20,
|
|
|
+ Header: "角色",
|
|
|
+ Key: "role",
|
|
|
+ },
|
|
|
+ {
|
|
|
+
|
|
|
+ Style: style,
|
|
|
+ Width: 40,
|
|
|
+ Header: "密码",
|
|
|
+ Key: "password",
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ // 代表每列的单元格字符
|
|
|
+ cos := []string{"A", "B", "C", "D"}
|
|
|
+ // 设置列格式 和 表头内容(第一列)
|
|
|
+ i := 1
|
|
|
+ for k, col := range columns {
|
|
|
+ f.SetColStyle(sheetName, cos[k], col.Style)
|
|
|
+ f.SetColWidth(sheetName, cos[k], cos[k], col.Width) // A,A,10
|
|
|
+ setstring := fmt.Sprintf("%s%d", cos[k], i)
|
|
|
+ f.SetCellValue(sheetName, setstring, col.Header)
|
|
|
+ }
|
|
|
+
|
|
|
+ setCellKey := map[string]string{
|
|
|
+ "A": "name",
|
|
|
+ "B": "loginName",
|
|
|
+ "C": "role",
|
|
|
+ "D": "password",
|
|
|
+ }
|
|
|
+
|
|
|
+ i++
|
|
|
+ // rows
|
|
|
+ for _, user := range users {
|
|
|
+ // 每行的单元格
|
|
|
+ for k, v := range user {
|
|
|
+ for _, c := range cos {
|
|
|
+ // "id" == "id" -- set A3
|
|
|
+ if setCellKey[c] == k { // A,B,C与item.key的关系
|
|
|
+ setString := fmt.Sprintf("%s%d", c, i)
|
|
|
+ f.SetCellValue(sheetName, setString, v)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ i++
|
|
|
+
|
|
|
+ }
|
|
|
+ // 另存为
|
|
|
+ _ = os.MkdirAll("excel", os.ModePerm)
|
|
|
+ filename1 := time.Now().Format("20060102150405") + ".xlsx"
|
|
|
+ err = f.SaveAs(filename1)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ filename := time.Now().Format("20060102150405") + ".xlsx"
|
|
|
+ c.Header("Content-Type", "application/octet-stream")
|
|
|
+ c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename))
|
|
|
+ c.Header("Content-Transfer-Encoding", "binary")
|
|
|
+ err = f.Write(c.Writer)
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println(err)
|
|
|
+ return false, err
|
|
|
+ }
|
|
|
+
|
|
|
+ return true, nil
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+func UserImportXls(c *gin.Context, apictx *ApiSession) (interface{}, error) {
|
|
|
+ // 操作用户为admin
|
|
|
+ if apictx.User.Role != "admin" {
|
|
|
+ return nil, errors.New("当前用户不是管理员")
|
|
|
+ }
|
|
|
+ file, _, err := c.Request.FormFile("file")
|
|
|
+ if err != nil {
|
|
|
+ return nil, errors.New("文件错误")
|
|
|
+ }
|
|
|
+ excel, err := excelize.OpenReader(file)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ users, err := excel.GetRows("用户列表")
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ errors := []error{}
|
|
|
+ if len(users) > 0 {
|
|
|
+ for index, user := range users {
|
|
|
+ if index == 0 {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ addUser, err := formatUser(user, index)
|
|
|
+ if err != nil {
|
|
|
+ errors = append(errors, err)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ _, err = repo.RepoAddDoc(apictx.CreateRepoCtx(), repo.CollectionUser, addUser)
|
|
|
+ if err != nil {
|
|
|
+ errf := fmt.Errorf("第%d行%s", index, err.Error())
|
|
|
+ errors = append(errors, errf)
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return errors, nil
|
|
|
+}
|
|
|
+
|
|
|
+func formatUser(u []string, rowNum int) (*model.User, error) {
|
|
|
+ user := &model.User{
|
|
|
+ LoginName: u[0],
|
|
|
+ Name: u[1],
|
|
|
+ Role: u[2],
|
|
|
+ Password: u[3],
|
|
|
+ }
|
|
|
+
|
|
|
+ if user.LoginName == "" {
|
|
|
+ return nil, fmt.Errorf("第%d行%s", rowNum, "登录名为空")
|
|
|
+ }
|
|
|
+
|
|
|
+ if user.Role == "" {
|
|
|
+ return nil, fmt.Errorf("第%d行%s", rowNum, "角色为空")
|
|
|
+ }
|
|
|
+ if user.Password == "" {
|
|
|
+ return nil, fmt.Errorf("第%d行%s", rowNum, "角色为空")
|
|
|
+ }
|
|
|
+ user.State = 1
|
|
|
+ user.CreateTime = time.Now()
|
|
|
+ user.UpdateTime = time.Now()
|
|
|
+ return user, nil
|
|
|
+}
|