package controllers import ( "encoding/json" "eta/eta_mini_crm_ht/models" "eta/eta_mini_crm_ht/models/request" "eta/eta_mini_crm_ht/models/response" "eta/eta_mini_crm_ht/services" "eta/eta_mini_crm_ht/utils" "fmt" "github.com/rdlucklib/rdluck_tools/paging" "github.com/xuri/excelize/v2" "net/http" "net/url" "strconv" "strings" "time" ) type UserController struct { BaseAuthController } var ( templateCols = map[string]utils.ExcelColMapping{ "A": {"手机号", "Mobile"}, "B": {"最近一次阅读时间", "LastReadTime"}, "C": {"累计阅读次数", "ReadCount"}, "D": {"注册时间", "CreatedTime"}, } userCols = map[string]utils.ExcelColMapping{ "A": {"姓名", "RealName"}, "B": {"手机号", "Mobile"}, "C": {"公司名称", "CompanyName"}, "D": {"注册时间", "CreatedTime"}, "E": {"是否关注公众号", "FollowingGzhStr"}, "F": {"最近一次阅读时间", "LastReadTime"}, "G": {"累计阅读次数", "ReadCount"}, } ) // TemplateList // @Title 临时用户列表 // @Description 临时用户列表 // @Param PageSize query int true "每页数据条数" // @Param CurrentIndex query int true "当前页页码,从1开始" // @Param Keyword query string false "手机号" // @Param SortParam query string false "排序字段参数,用来排序的字段, 枚举值:0:注册时间,1:阅读数,2:最近一次阅读时间" // @Param SortType query string true "如何排序,是正序还是倒序,0:倒序,1:正序" // @Success 200 {object} response.TemplateUserListResp // @router /temporary/list [get] func (this *UserController) TemplateList() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() pageSize, _ := this.GetInt("PageSize") currentIndex, _ := this.GetInt("CurrentIndex") keyword := this.GetString("Keyword") if pageSize <= 0 { pageSize = utils.PageSize20 } else if pageSize > utils.PageSize100 { pageSize = utils.PageSize100 } if currentIndex <= 0 { currentIndex = 1 } if pageSize <= 0 { pageSize = utils.PageSize20 } else if pageSize > utils.PageSize100 { pageSize = utils.PageSize100 } if currentIndex <= 0 { currentIndex = 1 } startSize := utils.StartIndex(currentIndex, pageSize) sortParamInt, _ := this.GetInt("SortParam", 0) sortTypeInt, _ := this.GetInt("SortType", 0) var sortCondtion string var condition string var pars []interface{} sortParamMap := map[int]string{0: "created_time", 1: "read_count", 2: "last_read_time"} sortTypeMap := map[int]string{0: "desc", 1: "asc"} sortParam, ok := sortParamMap[sortParamInt] if !ok { br.Msg = "错误的排序字段参数" br.ErrMsg = fmt.Sprint("错误的排序字段:", sortParamInt) return } sortType, ok := sortTypeMap[sortTypeInt] if !ok { br.Msg = "错误的排序字段" br.ErrMsg = fmt.Sprint("错误的排序字段:", sortTypeInt) return } sortCondtion = fmt.Sprintf("%s %s,updated_time desc ", sortParam, sortType) if keyword != "" { condition += ` AND mobile LIKE ? ` pars = utils.GetLikeKeywordPars(pars, keyword, 1) } resp := new(response.TemplateUserListResp) total, userList, err := models.GetPageTemplateUserList(condition, pars, sortCondtion, startSize, pageSize) if err != nil { br.Msg = "查询用户失败" br.Msg = "查询用户失败,系统错误,Err:" + err.Error() return } list := make([]models.TemplateUsersItem, 0) for _, v := range userList { list = append(list, v.ToItem()) } page := paging.GetPaging(currentIndex, pageSize, total) resp.Paging = page resp.List = list br.Data = resp br.Ret = 200 br.Success = true br.Msg = "获取成功" } // OfficialList // @Title 正式用户列表 // @Description 正式用户列表 // @Param PageSize query int true "每页数据条数" // @Param CurrentIndex query int true "当前页页码,从1开始" // @Param Keyword query string false "手机号" // @Param SortParam query string false "排序字段参数,用来排序的字段, 枚举值:0:注册时间,1:阅读数,2:最近一次阅读时间" // @Param SortType query string true "如何排序,是正序还是倒序,0:倒序,1:正序" // @Success 200 {object} response.TemplateUserListResp // @router /official/list [get] func (this *UserController) OfficialList() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() pageSize, _ := this.GetInt("PageSize") currentIndex, _ := this.GetInt("CurrentIndex") keyword := this.GetString("Keyword") FollowingGzh := this.GetString("FollowingGzh") RegisterBeginDate := this.GetString("RegisterBeginDate") RegisterEndDate := this.GetString("RegisterEndDate") if pageSize <= 0 { pageSize = utils.PageSize20 } else if pageSize > utils.PageSize100 { pageSize = utils.PageSize100 } if currentIndex <= 0 { currentIndex = 1 } if pageSize <= 0 { pageSize = utils.PageSize20 } else if pageSize > utils.PageSize100 { pageSize = utils.PageSize100 } if currentIndex <= 0 { currentIndex = 1 } startSize := utils.StartIndex(currentIndex, pageSize) sortParamInt, _ := this.GetInt("SortParam", 0) sortTypeInt, _ := this.GetInt("SortType", 0) var sortCondtion string var condition string var pars []interface{} sortParamMap := map[int]string{0: "created_time", 1: "read_count", 2: "last_read_time"} sortTypeMap := map[int]string{0: "desc", 1: "asc"} sortParam, ok := sortParamMap[sortParamInt] if !ok { br.Msg = "错误的排序字段参数" br.ErrMsg = fmt.Sprint("错误的排序字段:", sortParamInt) return } sortType, ok := sortTypeMap[sortTypeInt] if !ok { br.Msg = "错误的排序字段" br.ErrMsg = fmt.Sprintf("错误的排序字段:%v", sortTypeInt) return } sortCondtion = fmt.Sprintf("%s %s,updated_time desc ", sortParam, sortType) if FollowingGzh != "" { switch FollowingGzh { case "true": condition += ` AND following_gzh=1 ` case "false": condition += ` AND following_gzh=0 ` default: br.Msg = "关注公众号字段非法字段" br.ErrMsg = fmt.Sprintf("错误的关注公众号字段:%s", FollowingGzh) return } } if RegisterBeginDate != "" || RegisterEndDate != "" { var beginDate, endDate time.Time var parseErr error if RegisterBeginDate != "" { beginDate, parseErr = time.Parse(time.DateOnly, RegisterBeginDate) if parseErr != nil { br.Msg = "注册时间开始字段非法字段" br.ErrMsg = fmt.Sprintf("错误的注册时间开始字段:%s", RegisterBeginDate) return } } if RegisterEndDate != "" { endDate, parseErr = time.Parse(time.DateOnly, RegisterEndDate) if parseErr != nil { br.Msg = "注册时间结束字段非法字段" br.ErrMsg = fmt.Sprintf("错误的注册时间结束字段:%s", RegisterEndDate) return } } if RegisterBeginDate != "" { if RegisterEndDate != "" { if beginDate.After(endDate) { br.Msg = "结束时间不能早于开始时间" br.ErrMsg = fmt.Sprintf("错误的注册时间结束字段:开始时间:%s,结束时间:%s", RegisterBeginDate, RegisterEndDate) return } condition += ` AND DATE_FORMAT(created_time,'%Y-%m-%d') BETWEEN ? AND ?` pars = append(pars, RegisterBeginDate, RegisterEndDate) } else { condition += ` AND DATE_FORMAT(created_time,'%Y-%m-%d') >= ?` pars = append(pars, RegisterBeginDate) } } else { condition += ` AND DATE_FORMAT(created_time,'%Y-%m-%d') <= ?` pars = append(pars, RegisterEndDate) } } if keyword != "" { condition += ` AND ( mobile LIKE ? or real_name like ?)` pars = utils.GetLikeKeywordPars(pars, keyword, 2) } resp := new(response.UserListResp) total, userList, err := models.GetPageOfficialUserList(condition, pars, sortCondtion, startSize, pageSize) if err != nil { br.Msg = "查询用户失败" br.Msg = "查询用户失败,系统错误,Err:" + err.Error() return } //list := make([]*models.UserView, 0) //var wg sync.WaitGroup //wg.Add(len(userList)) //for _, v := range userList { // go func(v *models.User) { // defer wg.Done() // tempUser, _ := models.GetTemplateUser(v.TemplateUserId) // userView := v.FillUserInfo(tempUser) // list = append(list, &userView) // }(&v) //} //wg.Wait() page := paging.GetPaging(currentIndex, pageSize, total) resp.Paging = page resp.List = userList br.Data = resp br.Ret = 200 br.Success = true br.Msg = "获取成功" } // readRecordList // @Title 用户阅读记录 // @Description 用户阅读记录 // @Param PageSize query int true "每页数据条数" // @Param CurrentIndex query int true "当前页页码,从1开始" // @Param ChartPermissionIds query string true "品种列表" // @Param ClassifyIds query string true "品种列表" // @Success 200 {object} models.LoginResp // @router /readRecordList [get] func (this *UserController) ReadRecordList() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() UserId, _ := this.GetInt("UserId") pageSize, _ := this.GetInt("PageSize") currentIndex, _ := this.GetInt("CurrentIndex") permissionIds := this.GetString("PermissionIds") productType := this.GetString("ProductType") if UserId <= 0 { br.Msg = "查询用户失败,用户id不合法" return } if pageSize <= 0 { pageSize = utils.PageSize20 } else if pageSize > utils.PageSize100 { pageSize = utils.PageSize100 } if currentIndex <= 0 { currentIndex = 1 } startSize := utils.StartIndex(currentIndex, pageSize) user, err := models.GetTemplateUser(UserId) if err != nil { if err.Error() == utils.ErrNoRow() { br.Msg = "用户不存在或已删除,请刷新页面" return } br.Msg = "查询用户失败" br.ErrMsg = "查询用户失败,系统错误,Err:" + err.Error() return } if user == nil { br.Msg = "用户不存在或已删除,请刷新页面" return } var condition string var pars []interface{} var sourceType models.SourceType if productType != "" { sourceType = transSourceType(productType) if sourceType == "" { br.Msg = "错误的产品类型" br.ErrMsg = "错误的产品类型:" + productType return } condition += `and source_type= ?` pars = append(pars, sourceType) } var permissionIdList []int if permissionIds != "" { permissionIdStrList := strings.Split(permissionIds, ",") for _, permissionIdStr := range permissionIdStrList { permissionId, parseErr := strconv.Atoi(permissionIdStr) if parseErr != nil { continue } permissionIdList = append(permissionIdList, permissionId) } } total, condition, pars, err := services.GetUserSourceClickFlowListCountByUserId(UserId, condition, pars, permissionIdList, sourceType) if err != nil { br.Msg = "查询阅读记录失败" br.ErrMsg = "查询阅读记录失败,Err:" + err.Error() return } if total <= 0 { br.Msg = "暂无数据" br.Data = new(response.UserSourceClickFlowResp) br.Success = true br.Ret = 200 return } readList, err := services.GetUserSourceClickFlowListByUserId(UserId, condition, pars, startSize, pageSize) if err != nil { br.Msg = "查询阅读记录失败" br.ErrMsg = "查询阅读记录失败,系统错误,Err:" + err.Error() return } page := paging.GetPaging(currentIndex, pageSize, total) resp := new(response.UserSourceClickFlowResp) resp.Paging = page resp.List = readList br.Msg = "获取成功" br.Data = resp br.Success = true br.Ret = 200 } func transSourceType(productType string) (sourceType models.SourceType) { if productType == "" { return "" } switch productType { case Report: sourceType = models.ReportSourceType return case Video: sourceType = models.VideoSourceType return case Audio: sourceType = models.AudioSourceType return default: return "" } } // ExportTemplateUsers // @Title 临时用户列表 // @Description 临时用户列表 // @Param PageSize query int true "每页数据条数" // @Param CurrentIndex query int true "当前页页码,从1开始" // @Param Keyword query string false "手机号" // @Param SortParam query string false "排序字段参数,用来排序的字段, 枚举值:0:注册时间,1:阅读数,2:最近一次阅读时间" // @Param SortType query string true "如何排序,是正序还是倒序,0:倒序,1:正序" // @Success 200 {object} response.TemplateUserListResp // @router /temporary/export [get] func (this *UserController) ExportTemplateUsers() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() keyword := this.GetString("Keyword") sortParamInt, _ := this.GetInt("SortParam", 0) sortTypeInt, _ := this.GetInt("SortType", 0) var sortStr = `` var condition string var pars []interface{} sortParamMap := map[int]string{0: "created_time", 1: "read_count", 2: "last_read_time"} sortTypeMap := map[int]string{0: "desc", 1: "asc"} sortParam, ok := sortParamMap[sortParamInt] if !ok { br.Msg = "错误的排序字段参数" br.ErrMsg = fmt.Sprint("错误的排序字段:", sortParamInt) return } sortType, ok := sortTypeMap[sortTypeInt] if !ok { br.Msg = "错误的排序字段" br.ErrMsg = fmt.Sprint("错误的排序字段:", sortTypeInt) return } sortStr = fmt.Sprintf("%s %s,updated_time desc ", sortParam, sortType) if keyword != "" { condition += ` AND mobile LIKE ? ` pars = utils.GetLikeKeywordPars(pars, keyword, 1) } userList, err := models.GetTemplateUserListByCondition(condition, pars, sortStr) if err != nil { br.Msg = "查询用户失败" br.Msg = "查询用户失败,系统错误,Err:" + err.Error() return } list := make([]models.TemplateUsersItem, 0) for _, v := range userList { list = append(list, v.ToItem()) } year, month, day := time.Now().Date() yearStr := strconv.Itoa(year)[2:] fileName := fmt.Sprintf("临时用户表%s.%d.%d.xlsx", yearStr, month, day) file, err := utils.ExportExcel("临时用户表", templateCols, list) _ = this.downloadExcelFile(file, fileName) br.Ret = 200 br.Success = true br.Msg = "下载成功" } // encodeChineseFilename 将中文文件名编码为 ISO-8859-1 func (this *UserController) downloadExcelFile(file *excelize.File, filename string) (err error) { // 对文件名进行 ISO-8859-1 编码 fn := url.QueryEscape(filename) if filename == fn { fn = "filename=" + fn } else { fn = "filename=" + filename + "; filename*=utf-8''" + fn } this.Ctx.ResponseWriter.Header().Set("Access-Control-Expose-Headers", "Content-Disposition") this.Ctx.ResponseWriter.Header().Set("Content-Disposition", "attachment; "+fn) this.Ctx.ResponseWriter.Header().Set("Content-Description", "File Transfer") this.Ctx.ResponseWriter.Header().Set("Content-Type", "application/octet-stream") this.Ctx.ResponseWriter.Header().Set("Content-Transfer-Encoding", "binary") this.Ctx.ResponseWriter.Header().Set("Expires", "0") this.Ctx.ResponseWriter.Header().Set("Cache-Control", "must-revalidate") this.Ctx.ResponseWriter.Header().Set("Pragma", "public") this.Ctx.ResponseWriter.Header().Set("File-Name", filename) // 写入文件 if err = file.Write(this.Ctx.ResponseWriter); err != nil { utils.FileLog.Error("导出excel文件失败:", err) http.Error(this.Ctx.ResponseWriter, "导出excel文件失败", http.StatusInternalServerError) } return } // ExportOfficialUsers // @Title 正式用户列表 // @Description 正式用户列表 // @Param PageSize query int true "每页数据条数" // @Param CurrentIndex query int true "当前页页码,从1开始" // @Param Keyword query string false "手机号" // @Param SortParam query string false "排序字段参数,用来排序的字段, 枚举值:0:注册时间,1:阅读数,2:最近一次阅读时间" // @Param SortType query string true "如何排序,是正序还是倒序,0:倒序,1:正序" // @Success 200 {object} response.TemplateUserListResp // @router /official/export [get] func (this *UserController) ExportOfficialUsers() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() keyword := this.GetString("Keyword") FollowingGzh := this.GetString("FollowingGzh") RegisterBeginDate := this.GetString("RegisterBeginDate") RegisterEndDate := this.GetString("RegisterEndDate") sortParamInt, _ := this.GetInt("SortParam", 0) sortTypeInt, _ := this.GetInt("SortType", 0) var sortStr = `` var condition string var pars []interface{} sortParamMap := map[int]string{0: "created_time", 1: "read_count", 2: "last_read_time"} sortTypeMap := map[int]string{0: "desc", 1: "asc"} sortParam, ok := sortParamMap[sortParamInt] if !ok { br.Msg = "错误的排序字段参数" br.ErrMsg = fmt.Sprint("错误的排序字段:", sortParamInt) return } sortType, ok := sortTypeMap[sortTypeInt] if !ok { br.Msg = "错误的排序字段" br.ErrMsg = fmt.Sprintf("错误的排序字段:%v", sortTypeInt) return } sortStr = fmt.Sprintf("%s %s,updated_time desc ", sortParam, sortType) if FollowingGzh != "" { switch FollowingGzh { case "true": condition += ` AND following_gzh=1 ` case "false": condition += ` AND following_gzh=0 ` default: br.Msg = "关注公众号字段非法字段" br.ErrMsg = fmt.Sprintf("错误的关注公众号字段:%s", FollowingGzh) return } } if RegisterBeginDate != "" || RegisterEndDate != "" { var beginDate, endDate time.Time var parseErr error if RegisterBeginDate != "" { beginDate, parseErr = time.Parse(time.DateOnly, RegisterBeginDate) if parseErr != nil { br.Msg = "注册时间开始字段非法字段" br.ErrMsg = fmt.Sprintf("错误的注册时间开始字段:%s", RegisterBeginDate) return } } if RegisterEndDate != "" { endDate, parseErr = time.Parse(time.DateOnly, RegisterEndDate) if parseErr != nil { br.Msg = "注册时间结束字段非法字段" br.ErrMsg = fmt.Sprintf("错误的注册时间结束字段:%s", RegisterEndDate) return } } if RegisterBeginDate != "" { if RegisterEndDate != "" { if beginDate.After(endDate) { br.Msg = "结束时间不能早于开始时间" br.ErrMsg = fmt.Sprintf("错误的注册时间结束字段:开始时间:%s,结束时间:%s", RegisterBeginDate, RegisterEndDate) return } condition += ` AND DATE_FORMAT(created_time,'%Y-%m-%d') BETWEEN ? AND ?` pars = append(pars, RegisterBeginDate, RegisterEndDate) } else { condition += ` AND DATE_FORMAT(created_time,'%Y-%m-%d') >= ?` pars = append(pars, RegisterBeginDate) } } else { condition += ` AND DATE_FORMAT(created_time,'%Y-%m-%d') <= ?` pars = append(pars, RegisterEndDate) } } if keyword != "" { condition += ` AND ( mobile LIKE ? or real_name like ?)` pars = utils.GetLikeKeywordPars(pars, keyword, 2) } userList, err := models.GetPageOfficialUserByCondition(condition, pars, sortStr) if err != nil { br.Msg = "查询用户失败" br.Msg = "查询用户失败,系统错误,Err:" + err.Error() return } year, month, day := time.Now().Date() yearStr := strconv.Itoa(year)[2:] fileName := fmt.Sprintf("用户列表%s.%d.%d.xlsx", yearStr, month, day) file, err := utils.ExportExcel("用户列表", userCols, userList) _ = this.downloadExcelFile(file, fileName) br.Ret = 200 br.Success = true br.Msg = "获取成功" } // MessageList 获取未读消息 // @Summary 获取未读消息 // @Description 获取未读消息 // @Success 200 {object} controllers.BaseResponse // @router /message [get] func (u *UserController) MessageList() { br := new(models.BaseResponse).Init() defer func() { u.Data["json"] = br u.ServeJSON() }() pageSize, _ := u.GetInt("PageSize") currentIndex, _ := u.GetInt("CurrentIndex") if currentIndex <= 0 { currentIndex = 1 } if pageSize <= 0 { pageSize = utils.PageSize20 } else if pageSize > utils.PageSize100 { pageSize = utils.PageSize100 } startSize := utils.StartIndex(currentIndex, pageSize) total, err := models.GetMessageListCount(u.SysUser.SysUserId) if err != nil { br.Msg = "查询退款通知失败" br.Msg = "查询退款通知失败,Err:" + err.Error() return } messages, err := models.GetMessageList(u.SysUser.SysUserId, startSize, pageSize) if err != nil { br.Msg = "查询退款通知失败" br.Msg = "查询退款通知失败,Err:" + err.Error() return } var list []*models.UserMessageView for _, message := range messages { list = append(list, message.ToView()) } resp := new(response.MessageListResp) page := paging.GetPaging(currentIndex, pageSize, total) resp.Paging = page resp.List = list br.Ret = 200 br.Success = true br.Data = resp br.Msg = "获取成功" } // ReadMessage 获取未读消息 // @Summary 获取未读消息 // @Description 获取未读消息 // @Success 200 {object} controllers.BaseResponse // @router /readMessage [post] func (u *UserController) ReadMessage() { br := new(models.BaseResponse).Init() defer func() { u.Data["json"] = br u.ServeJSON() }() var req request.ReadMessageReq if err := json.Unmarshal(u.Ctx.Input.RequestBody, &req); err != nil { br.Msg = "参数解析失败" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } if req.MessageId <= 0 { br.Msg = "消息Id非法" br.Msg = "已读退款通知失败,消息Id非法" return } if models.ReadMessage(u.SysUser.SysUserId, req.MessageId) { br.Ret = 200 br.Success = true br.Msg = "已读成功" return } else { br.Msg = "已读退款通知失败" br.ErrMsg = "已读退款通知失败" return } } // ReadMessages 获取未读消息 // @Summary 获取未读消息 // @Description 获取未读消息 // @Success 200 {object} controllers.BaseResponse // @router /readMessages [post] func (u *UserController) ReadMessages() { br := new(models.BaseResponse).Init() defer func() { u.Data["json"] = br u.ServeJSON() }() if models.ReadMessages(u.SysUser.SysUserId) { br.Ret = 200 br.Success = true br.Msg = "已读成功" return } else { br.Msg = "批量已读退款通知失败" br.ErrMsg = "批量已读退款通知失败" return } }