123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454 |
- package api
- import (
- "copter-train/log"
- "copter-train/utils"
- "errors"
- "fmt"
- "net/url"
- "time"
- "copter-train/db/model"
- "copter-train/db/repo"
- "github.com/gin-gonic/gin"
- "github.com/xuri/excelize/v2"
- "go.mongodb.org/mongo-driver/bson"
- "go.mongodb.org/mongo-driver/bson/primitive"
- )
- type UserLoginPasswordReq struct {
- LoginName string `json:"loginName"`
- Password string `json:"password"`
- Role string `json:"role"`
- }
- func UserLoginPassword(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- var form UserLoginPasswordReq
- err := c.ShouldBindJSON(&form)
- if err != nil {
- return nil, err
- }
- // 查找用户:根据longinName/password/role是否在roles中
- user := &model.User{}
- found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
- CollectName: repo.CollectionUser,
- Query: repo.Map{
- "loginName": form.LoginName,
- "password": utils.UtilMd5(form.Password),
- "roles": bson.M{"$elemMatch": bson.M{"$eq": form.Role}},
- },
- }, user)
- if err != nil {
- return nil, err
- }
- if !found {
- return nil, errors.New("账号/密码/角色不正确")
- }
- jwtU := &JWTUser{ID: user.GetID()}
- token, _, err := apictx.Svc.JWT.JwtCreateToken(jwtU)
- if err != nil {
- return nil, err
- }
- // 前端返回处理
- user.Password = ""
- out := map[string]interface{}{
- "token": token,
- "user": user,
- }
- return out, nil
- }
- // 用户唯一
- // db.users.createIndex({ nid: 1 }, { unique: true })
- func CreateUser(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- // 验证是否为管理员
- isAdmin, err := IsAdmin(c, apictx)
- if err != nil {
- return nil, err
- }
- if !isAdmin {
- return nil, errors.New("没有权限")
- }
- user := &model.User{}
- err = c.ShouldBindJSON(&user)
- if err != nil {
- log.Error(err)
- return nil, err
- }
- // 验证编号是否存在
- found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
- CollectName: repo.CollectionUser,
- Query: repo.Map{"nid": user.Nid},
- }, user)
- if err != nil {
- return nil, err
- }
- if found {
- return nil, errors.New("该编号已存在")
- }
- // ! 编号唯一 验证了编号就不用验证登录名是否存在
- // found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
- // CollectName: repo.CollectionUser,
- // Query: repo.Map{"loginName": user.LoginName},
- // }, user)
- // if err != nil {
- // return nil, err
- // }
- // if found {
- // return nil, errors.New("该账号已存在")
- // }
- // student,teacher,admin
- if len(user.Roles) < 1 {
- user.Roles = []string{"student"}
- }
- user.Password = UtilMd5(user.Password)
- user.CreateTime = time.Now()
- user.UpdateTime = time.Now()
- return repo.RepoAddDoc(apictx.CreateRepoCtx(), repo.CollectionUser, &user)
- }
- func DeleteUser(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- // 验证是否为管理员
- isAdmin, err := IsAdmin(c, apictx)
- if err != nil {
- return nil, err
- }
- if !isAdmin {
- return nil, errors.New("没有权限")
- }
- _id := c.Param("id")
- id, _ := primitive.ObjectIDFromHex(_id)
- if id.IsZero() {
- return nil, errors.New("id错误")
- }
- return repo.RepoDeleteDoc(apictx.CreateRepoCtx(), repo.CollectionUser, _id)
- }
- type BatchDeleteUserReq struct {
- Ids []string `json:"ids"`
- }
- func BatchDeleteUser(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- // 验证是否为管理员
- isAdmin, err := IsAdmin(c, apictx)
- if err != nil {
- return nil, err
- }
- if !isAdmin {
- return nil, errors.New("没有权限")
- }
- var form BatchDeleteUserReq
- err = c.ShouldBindJSON(&form)
- if err != nil {
- return nil, errors.New("参数错误")
- }
- if len(form.Ids) > 0 {
- for _, id := range form.Ids {
- repo.RepoDeleteDoc(apictx.CreateRepoCtx(), repo.CollectionUser, id)
- }
- }
- return true, nil
- }
- // 用户列表
- // /user/list?role=student&name=xxx&nid=xxx&page=1&size=10
- func UserList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- // 验证是否为管理员
- isStudent, err := IsStudent(c, apictx)
- if err != nil {
- return nil, err
- }
- if isStudent {
- return nil, errors.New("没有权限")
- }
- page, size, query := UtilQueryPageSize(c)
- role := c.Query("role")
- name := c.Query("name")
- nid := c.Query("nid")
- if len(role) > 0 {
- query["roles"] = bson.M{"$elemMatch": bson.M{"$eq": role}}
- }
- if len(name) > 0 {
- query["name"] = bson.M{"$regex": name, "$options": "$i"}
- }
- if len(nid) > 0 {
- query["nid"] = bson.M{"$regex": nid, "$options": "$i"}
- }
- return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
- CollectName: repo.CollectionUser,
- Page: page,
- Size: size,
- Query: query,
- Sort: bson.D{bson.E{Key: "createTime", Value: -1}, bson.E{Key: "_id", Value: -1}},
- Project: []string{"nid", "name", "loginName", "avatar", "roles", "createTime", "updateTime"},
- })
- }
- func UserDetail(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- // 验证是否为管理员
- isAdmin, err := IsAdmin(c, apictx)
- if err != nil {
- return nil, err
- }
- if !isAdmin {
- return nil, errors.New("没有权限")
- }
- _id := c.Param("id")
- id, _ := primitive.ObjectIDFromHex(_id)
- if id.IsZero() {
- return nil, errors.New("id错误")
- }
- return GetUserById(apictx, _id)
- }
- func UpdateUser(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- // 验证是否为管理员
- isAdmin, err := IsAdmin(c, apictx)
- if err != nil {
- return nil, err
- }
- if !isAdmin {
- return nil, errors.New("没有权限")
- }
- user := &model.User{}
- err = c.ShouldBindJSON(&user)
- if err != nil {
- log.Error(err)
- return nil, err
- }
- if user.Id.IsZero() {
- return nil, errors.New("id错误")
- }
- su := &model.User{}
- found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
- CollectName: repo.CollectionUser,
- Query: repo.Map{"nid": user.Nid},
- }, su)
- if err != nil {
- return nil, err
- }
- if found {
- return nil, errors.New("该编号已存在")
- }
- return repo.RepoUpdateSetDoc(apictx.CreateRepoCtx(), repo.CollectionUser, user.Id.Hex(), user)
- }
- // 获取自己的信息
- func UserProfile(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- return GetUserById(apictx, apictx.User.ID)
- }
- // 根据id获取用户信息
- func GetUserById(apictx *ApiSession, id string) (*model.User, error) {
- user := &model.User{}
- found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
- CollectName: repo.CollectionUser,
- Query: repo.Map{"_id": id},
- }, user)
- if err != nil {
- log.Error(err)
- return nil, err
- }
- if !found {
- return nil, errors.New("未找到该数据")
- }
- user.Password = ""
- return user, nil
- }
- // 是否是管理员
- func IsAdmin(c *gin.Context, apictx *ApiSession) (bool, error) {
- user, err := GetUserById(apictx, apictx.User.ID)
- if err != nil {
- return false, err
- }
- for _, v := range user.Roles {
- if v == "admin" {
- return true, nil
- }
- }
- return false, nil
- }
- // 是否是老师
- func IsTeacher(c *gin.Context, apictx *ApiSession) (bool, error) {
- user, err := GetUserById(apictx, apictx.User.ID)
- if err != nil {
- return false, err
- }
- for _, v := range user.Roles {
- if v == "teacher" {
- return true, nil
- }
- }
- return false, nil
- }
- // 是否是学生
- func IsStudent(c *gin.Context, apictx *ApiSession) (bool, error) {
- user, err := GetUserById(apictx, apictx.User.ID)
- if err != nil {
- return false, err
- }
- for _, v := range user.Roles {
- if v == "student" {
- return true, nil
- }
- }
- return false, nil
- }
- // 导入用户
- func ImportUser(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- isAdmin, err := IsAdmin(c, apictx)
- if err != nil {
- return nil, err
- }
- if !isAdmin {
- 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
- }
- excelIndex := excel.GetActiveSheetIndex()
- sheetName := excel.GetSheetName(excelIndex)
- users, err := excel.GetRows(sheetName)
- if err != nil {
- return nil, err
- }
- errors := []string{}
- if len(users) > 0 {
- for index, us := range users {
- rowNum := index + 1
- // 标题行
- if index == 0 {
- continue
- }
- // 表头
- if index == 1 {
- continue
- }
- // 去除可能的空行
- if len(us) == 0 {
- continue
- }
- // 用户名name 编号nid 密码password 角色roles
- user := &model.User{}
- user.Name = us[0]
- user.Nid = us[1]
- if len(us[0]) == 0 {
- errors = append(errors, fmt.Sprintf("第%d行错误: %s", rowNum, "用户名不能为空"))
- continue
- }
- if len(us[1]) == 0 {
- errors = append(errors, fmt.Sprintf("第%d行错误: %s", rowNum, "编号不能为空"))
- continue
- }
- roles := []string{}
- if us[2] == "管理员" {
- roles = []string{"admin"}
- }
- if us[2] == "教员" {
- roles = []string{"teacher"}
- }
- if us[2] == "学员" {
- roles = []string{"student"}
- }
- user.Roles = roles
- user.Password = UtilMd5(us[3])
- if len(us[3]) == 0 {
- user.Password = UtilMd5("123456")
- } else if len(us[3]) == 32 {
- user.Password = us[3]
- }
- user.LoginName = fmt.Sprintf("%s_%s", user.Name, user.Nid)
- user.CreateTime = time.Now()
- user.UpdateTime = time.Now()
- _, err = repo.RepoAddDoc(apictx.CreateRepoCtx(), repo.CollectionUser, user)
- if err != nil {
- errors = append(errors, fmt.Sprintf("第%d行错误: %s", rowNum, "保存数据失败, 请检查数据格式是否正确/编号是否重复"))
- log.Error(err)
- }
- }
- }
- return errors, nil
- }
- // 导出用户
- func ExportUser(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- isAdmin, err := IsAdmin(c, apictx)
- if err != nil {
- return nil, err
- }
- if !isAdmin {
- return nil, errors.New("没有权限")
- }
- f := excelize.NewFile()
- index, _ := f.NewSheet("Sheet1")
- f.SetActiveSheet(index)
- f.SetDefaultFont("宋体")
- testExcel := NewUserExcel(f)
- testExcel.Title = "用户信息"
- _, _, query := UtilQueryPageSize(c)
- // 获取试题列表
- users := make([]*model.User, 0)
- err = repo.RepoSeachDocs(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
- CollectName: repo.CollectionUser,
- Query: query,
- Sort: bson.M{"createTime": 1},
- }, &users)
- if err != nil {
- return nil, err
- }
- testExcel.Content = users
- testExcel.Draws()
- fileName := url.PathEscape("用户信息.xlsx")
- c.Header("Content-Type", "application/octet-stream")
- c.Header("Content-Disposition", "attachment; filename="+fileName)
- c.Header("Content-Transfer-Encoding", "binary")
- err = f.Write(c.Writer)
- if err != nil {
- return nil, err
- }
- return nil, nil
- }
- // 下载用户模板
- func UserTmplate(c *gin.Context, apictx *ApiSession) (interface{}, error) {
- filename := "用户信息模板.xlsx"
- // url.PathEscape将字符串中的特殊字符进行编码,使其符合URL规范
- filename = url.PathEscape(filename)
- // 设置下载的文件名
- c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename))
- // 设置文件类型
- c.Writer.Header().Add("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
- c.File(USERS_TMPLATE_FILE)
- return nil, nil
- }
|