Просмотр исходного кода

add: 添加客户模块,权限模块,定时消息

zqbao 11 месяцев назад
Родитель
Сommit
d6c71facd3

+ 1 - 0
.gitignore

@@ -3,3 +3,4 @@
 /etalogs/
 *.exe
 *.exe~
+go.sum

+ 2 - 1
controllers/base_auth1.go → controllers/base_auth.go

@@ -82,7 +82,8 @@ func (c *BaseAuthController) Prepare() {
 				c.StopRun()
 				return
 			}
-
+			c.SysUser = sysUser
+			c.Session = session
 		}
 	}
 }

+ 53 - 0
controllers/chart_permission.go

@@ -0,0 +1,53 @@
+package controllers
+
+import (
+	"eta/eta_mini_crm/models"
+	"eta/eta_mini_crm/models/response"
+	"eta/eta_mini_crm/services"
+)
+
+type ChartPermissionController struct {
+	BaseAuthController
+}
+
+// List
+// @Title 系统品种列表
+// @Description 系统品种列表
+// @Param   UserId   query   int  true       "角色ID"
+// @Success 200 {object} models.LoginResp
+// @router /list [get]
+func (this *ChartPermissionController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	userId, _ := this.GetInt("UserId")
+
+	publicMap, privateMap, err := services.GetChartPermissionList()
+	if err != nil {
+		br.Msg = "权限列表获取失败"
+		br.ErrMsg = "权限列表获取失败,系统错误,Err:" + err.Error()
+		return
+	}
+	resp := new(response.ChartPermissionListresp)
+	if userId > 0 {
+		ids, err := models.GetChartPermissionIdByUserId(userId)
+		if err != nil {
+			br.Msg = "权限列表获取失败"
+			br.ErrMsg = "权限列表获取失败,系统错误,Err:" + err.Error()
+		}
+		resp.SelectedList = ids
+	}
+	for _, per := range publicMap {
+		resp.PublicList = append(resp.PublicList, per)
+	}
+	for _, per := range privateMap {
+		resp.PrivateList = append(resp.PrivateList, per)
+	}
+
+	br.Ret = 200
+	br.Data = resp
+	br.Msg = "列表获取成功"
+	br.Success = true
+}

+ 108 - 0
controllers/sys_message_report.go

@@ -0,0 +1,108 @@
+package controllers
+
+import (
+	"encoding/json"
+	"eta/eta_mini_crm/models"
+	"eta/eta_mini_crm/models/request"
+	"eta/eta_mini_crm/models/response"
+	"eta/eta_mini_crm/utils"
+	"fmt"
+	"time"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+type SysMessageReportController struct {
+	BaseAuthController
+}
+
+// @Title 阅读消息
+// @Description 阅读消息
+// @Param	request	body system.SysRoleDeleteReq true "type json string"
+// @Success 200 查看成功
+// @router /read [post]
+func (this *SysMessageReportController) Read() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req request.SysMessageReadReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if len(req.SysMessageId) <= 0 {
+		br.Msg = "参数异常"
+		return
+	}
+
+	messages, err := models.GetSysMessageReportListById(req.SysMessageId)
+	if err != nil {
+		br.Msg = "查询消息出错"
+		br.ErrMsg = "查询消息出错,系统错误,Err:" + err.Error()
+		return
+	}
+	for _, msg := range messages {
+		msg.IsRead = true
+		msg.ModifyTime = time.Now()
+		msg.Update([]string{"is_read", "modify_time"})
+	}
+
+	br.Msg = "查看成功"
+	br.Success = true
+	br.Ret = 200
+}
+
+// List
+// @Title 系统消息列表
+// @Description 系统消息列表
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Success 200 {object} response.SysRoleListResp
+// @router /list [get]
+func (this *SysMessageReportController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+
+	total, err := models.GetSysMessageReportCountBySysUserId(this.SysUser.SysUserId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	fmt.Println(startSize)
+	fmt.Println(pageSize)
+	list, err := models.GetSysMessageReportBySysUserId(this.SysUser.SysUserId, startSize, pageSize)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp := new(response.SysMessageListResp)
+	resp.List = list
+	resp.Paging = page
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}

+ 27 - 8
controllers/sys_user.go

@@ -88,7 +88,7 @@ func (this *SysUserController) Add() {
 		return
 	}
 
-	_, err = models.GetSysRoleById(req.SysRoleId)
+	sysRole, err := models.GetSysRoleById(req.SysRoleId)
 	if err != nil {
 		if err == orm.ErrNoRows {
 			br.Msg = "所选角色不存在"
@@ -135,6 +135,7 @@ func (this *SysUserController) Add() {
 	sysUser.Email = req.Email
 	sysUser.SysDepartmentId = req.SysDepartmentId
 	sysUser.SysRoleId = req.SysRoleId
+	sysUser.SysRoleName = sysRole.SysRoleName
 	sysUser.Province = req.Province
 	sysUser.City = req.City
 	sysUser.IsEnabled = req.IsEnabled
@@ -163,7 +164,7 @@ func (this *SysUserController) Add() {
 // Detail
 // @Title 系统用户详情信息
 // @Description 用户详情信息
-// @Param	request	body request.SysUserInfoReq true "type json string"
+// @Param   SysUserId   query   int  true       "系统用户id"
 // @Success 200 {object} models.LoginResp
 // @router /detail [get]
 func (this *SysUserController) Detail() {
@@ -348,6 +349,8 @@ func (this *SysUserController) List() {
 	var startSize int
 	if pageSize <= 0 {
 		pageSize = utils.PageSize20
+	} else if pageSize > utils.PageSize100 {
+		pageSize = utils.PageSize100
 	}
 	if currentIndex <= 0 {
 		currentIndex = 1
@@ -575,12 +578,28 @@ func (this *SysUserController) MoveToDepartment() {
 		br.ErrMsg = "获得分组路径失败,系统错误,Err:" + err.Error()
 		return
 	}
-	userDepMapping := &models.SysUserDepartmentMapping{}
-	userDepMapping.SysUserId = req.SysUserId
-	userDepMapping.SysDepartmentId1 = depPathIds[0]
-	userDepMapping.SysDepartmentId2 = depPathIds[1]
-	userDepMapping.SysDepartmentId3 = depPathIds[2]
-	err = userDepMapping.Save()
+	sysUser := &models.SysUser{}
+	sysUser.SysUserId = req.SysUserId
+	sysUser.SysDepartmentId1 = depPathIds[0]
+	sysUser.SysDepartmentId2 = depPathIds[1]
+	sysUser.SysDepartmentId3 = depPathIds[2]
+	if depPathIds[0] != 0 {
+		sysUser.SysDepartmentId = depPathIds[0]
+	}
+	if depPathIds[1] != 0 {
+		sysUser.SysDepartmentId = depPathIds[1]
+	}
+	if depPathIds[2] != 0 {
+		sysUser.SysDepartmentId = depPathIds[2]
+	}
+	err = sysUser.Update([]string{"sys_department_id", "sys_department_id1", "sys_department_id2", "sys_department_id3"})
+
+	// userDepMapping := &models.SysUserDepartmentMapping{}
+	// userDepMapping.SysUserId = req.SysUserId
+	// userDepMapping.SysDepartmentId1 = depPathIds[0]
+	// userDepMapping.SysDepartmentId2 = depPathIds[1]
+	// userDepMapping.SysDepartmentId3 = depPathIds[2]
+	// err = userDepMapping.Save()
 	if err != nil {
 		br.Msg = "移动分组失败,系统错误"
 		br.ErrMsg = "移动分组失败,系统错误,Err:" + err.Error()

+ 621 - 0
controllers/user.go

@@ -0,0 +1,621 @@
+package controllers
+
+import (
+	"encoding/json"
+	"eta/eta_mini_crm/models"
+	"eta/eta_mini_crm/models/request"
+	"eta/eta_mini_crm/models/response"
+	"eta/eta_mini_crm/utils"
+	"strings"
+	"time"
+
+	"github.com/beego/beego/v2/client/orm"
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+type UserController struct {
+	BaseAuthController
+}
+
+// Add
+// @Title 添加新客户
+// @Description 添加新客户
+// @Param   request	body request.UserAddReq true "type json string"
+// @Success 200 {object} request.UserAddReq
+// @router /add [post]
+func (this *UserController) Add() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	var req request.UserAddReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.RealName == "" {
+		br.Msg = "请输入姓名"
+		return
+	}
+	req.Phone = strings.TrimSpace(req.Phone)
+	req.Email = strings.TrimSpace(req.Email)
+	if req.Phone == "" && req.Email == "" {
+		br.Msg = "至少输入一个手机号或邮箱"
+		return
+	}
+
+	var userByPhone, userByEmail *models.User
+	if req.Phone != "" {
+		if req.AreaCode == "86" {
+			if !utils.ValidateMobileFormatat(req.Phone) {
+				br.Msg = "手机号格式有误, 请检查"
+				return
+			}
+		}
+		userByPhone, err = models.GetUserByPhone(req.Phone, req.AreaCode)
+		if err != nil && err != orm.ErrNoRows {
+			br.Msg = "添加用户失败"
+			br.ErrMsg = "查询用户失败,系统错误,Err:" + err.Error()
+			return
+		}
+		if userByPhone != nil {
+			switch userByPhone.Status {
+			case 0:
+				userByPhone.Status = 2
+			case 1:
+				userByPhone.Status = 2
+			default:
+				br.Msg = "手机号已存在,请重新输入"
+				return
+			}
+		}
+	}
+	if req.Email != "" {
+		if !utils.ValidateEmailFormatat(req.Email) {
+			br.Msg = "邮箱格式有误, 请检查"
+			return
+		}
+		userByEmail, err = models.GetUserByEmail(req.Email)
+		if err != nil && err != orm.ErrNoRows {
+			br.Msg = "添加用户失败"
+			br.ErrMsg = "查询用户失败,系统错误,Err:" + err.Error()
+			return
+		}
+		if userByEmail != nil {
+			switch userByEmail.Status {
+			case 0:
+				userByEmail.Status = 2
+			case 1:
+				userByEmail.Status = 2
+			default:
+				br.Msg = "邮箱已存在,请重新输入"
+				return
+			}
+		}
+	}
+	if req.SellerId <= 0 {
+		br.Msg = "请选择营业部/销售"
+		return
+	}
+	if req.ValidStartTime == "" || req.ValidEndTime == "" {
+		br.Msg = "请选择合理的有效期范围"
+		return
+	}
+
+	validStartTime, err := time.Parse("2006-01-02", req.ValidStartTime)
+	if err != nil {
+		br.Msg = "错误的日期格式"
+		return
+	}
+	validEndTime, err := time.Parse("2006-01-02", req.ValidEndTime)
+	if err != nil {
+		br.Msg = "错误的日期格式"
+		return
+	}
+	if !validStartTime.Before(validEndTime) {
+		br.Msg = "请选择合理的有效期范围"
+		return
+	}
+	if req.Company == "" {
+		br.Msg = "请输入所属公司"
+		return
+	}
+	if userByPhone != nil && userByEmail != nil && userByPhone.UserId != userByEmail.UserId {
+		br.Msg = "邮箱已存在,请重新输入"
+		return
+	}
+	user := &models.User{}
+	if userByPhone == nil && userByEmail == nil {
+		user.CreateTime = time.Now()
+		user.ModifyTime = time.Now()
+	}
+
+	validStartTime = validStartTime.Local().Add(-time.Hour * 8)
+	validEndTime = validEndTime.Local().Add(-time.Hour*8 + time.Hour*24)
+	curTime := time.Now()
+	if curTime.Before(validEndTime) && curTime.After(validStartTime) {
+		user.Status = 2
+	} else {
+		user.Status = 0
+	}
+	user.RealName = req.RealName
+	user.AreaCode = req.AreaCode
+	user.Phone = req.Phone
+	user.Email = req.Email
+	user.SellerId = req.SellerId
+	user.ValidStartTime = validStartTime
+	user.ValidEndTime = validEndTime
+	user.Company = req.Company
+	user.ModifyTime = time.Now()
+	err = models.SaveUser(user, req.ChartPermission)
+	if err != nil {
+		br.Msg = "添加客户失败"
+		br.ErrMsg = "添加客户失败,系统错误,Err:" + err.Error()
+		return
+	}
+
+	br.Msg = "添加成功"
+	br.Success = true
+	br.Ret = 200
+
+}
+
+// edit
+// @Title 编辑客户
+// @Description 编辑客户
+// @Param   request	body request.UserEidtReq true "type json string"
+// @Success 200 {object} request.UserAddReq
+// @router /edit [post]
+func (this *UserController) Edit() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	var req request.UserEidtReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.RealName == "" {
+		br.Msg = "请输入姓名"
+		return
+	}
+	req.Phone = strings.TrimSpace(req.Phone)
+	req.Email = strings.TrimSpace(req.Email)
+	if req.Phone == "" && req.Email == "" {
+		br.Msg = "至少输入一个手机号或邮箱"
+		return
+	}
+	if req.Phone != "" {
+		if req.AreaCode == "86" {
+			if !utils.ValidateMobileFormatat(req.Phone) {
+				br.Msg = "手机号格式有误, 请检查"
+				return
+			}
+		}
+		user, err := models.GetUserByPhone(req.Phone, req.AreaCode)
+		if err != nil && err != orm.ErrNoRows {
+			br.Msg = "编辑用户失败"
+			br.ErrMsg = "查询用户失败,系统错误,Err:" + err.Error()
+			return
+		}
+		if user != nil && user.UserId != req.UserId {
+			br.Msg = "手机号已存在,请重新输入"
+			return
+		}
+	}
+	if req.Email != "" {
+		if !utils.ValidateEmailFormatat(req.Email) {
+			br.Msg = "邮箱格式有误, 请检查"
+			return
+		}
+
+		user, err := models.GetUserByEmail(req.Email)
+		if err != nil && err != orm.ErrNoRows {
+			br.Msg = "编辑用户失败"
+			br.ErrMsg = "查询用户失败,系统错误,Err:" + err.Error()
+			return
+		}
+		if user != nil && user.UserId != req.UserId {
+			br.Msg = "邮箱已存在,请重新输入"
+			return
+		}
+	}
+	if req.SellerId <= 0 {
+		br.Msg = "请选择营业部/销售"
+		return
+	}
+	if req.ValidStartTime == "" || req.ValidEndTime == "" {
+		br.Msg = "请选择合理的有效期范围"
+		return
+	}
+
+	validStartTime, err := time.Parse("2006-01-02", req.ValidStartTime)
+	if err != nil {
+		br.Msg = "错误的日期格式"
+		return
+	}
+	validStartTime = validStartTime.In(time.Local).Add(-time.Hour * 8)
+	validEndTime, err := time.Parse("2006-01-02", req.ValidEndTime)
+	if err != nil {
+		br.Msg = "错误的日期格式"
+		return
+	}
+	validEndTime = validEndTime.In(time.Local).Add(-time.Hour*8 + time.Hour*24)
+	if !validStartTime.Before(validEndTime) {
+		br.Msg = "请选择合理的有效期范围"
+		return
+	}
+	if req.Company == "" {
+		br.Msg = "请输入所属公司"
+		return
+	}
+
+	user := &models.User{}
+	user.UserId = req.UserId
+	user.RealName = req.RealName
+	user.AreaCode = req.AreaCode
+	user.Phone = req.Phone
+	user.Email = req.Email
+	user.SellerId = req.SellerId
+	user.ValidStartTime = validStartTime
+	user.ValidEndTime = validEndTime
+	user.Company = req.Company
+	user.ModifyTime = time.Now()
+	curTime := time.Now()
+	if !req.IsEnabled {
+		user.Status = 0
+	} else if curTime.After(validStartTime) && curTime.Before(validEndTime) {
+		user.Status = 2
+	} else {
+		user.Status = 1
+	}
+	err = models.SaveUser(user, req.ChartPermission)
+	if err != nil {
+		br.Msg = "添加客户失败"
+		br.ErrMsg = "添加客户失败,系统错误,Err:" + err.Error()
+		return
+	}
+
+	br.Msg = "编辑成功"
+	br.Success = true
+	br.Ret = 200
+}
+
+// Check
+// @Title 编辑客户
+// @Description 编辑客户
+// @Param   request	body request.UserEidtReq true "type json string"
+// @Success 200 {object} request.UserAddReq
+// @router /check [post]
+func (this *UserController) Check() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	var req request.UserCheckReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	req.Phone = strings.TrimSpace(req.Phone)
+	req.Email = strings.TrimSpace(req.Email)
+	if req.Phone == "" && req.Email == "" {
+		br.Msg = "至少输入一个手机号或邮箱"
+		return
+	}
+	userCheckResp := new(response.UserCheckResp)
+
+	if req.Phone != "" {
+		if req.AreaCode == "86" {
+			if !utils.ValidateMobileFormatat(req.Phone) {
+				br.Msg = "手机号格式有误, 请检查"
+				return
+			}
+		}
+		user, err := models.GetUserByPhone(req.Phone, req.AreaCode)
+		if err != nil && err != orm.ErrNoRows {
+			br.Msg = "编辑用户失败"
+			br.ErrMsg = "查询用户失败,系统错误,Err:" + err.Error()
+			return
+		}
+		if user != nil {
+			userCheckResp.UserId = user.UserId
+			if user.Status == 0 {
+				br.Ret = 200
+				br.Success = true
+				br.Msg = "该用户已被禁用,确认启用并更新用户信息吗?"
+				br.Data = userCheckResp
+				return
+			}
+			if user.Status == 1 {
+				br.Ret = 200
+				br.Success = true
+				br.Msg = "该用户已被禁用,确认启用并更新用户信息吗?"
+				br.Data = userCheckResp
+				return
+			}
+			if user.Status == 2 {
+				br.Msg = "手机号已存在,请重新输入"
+				return
+			}
+		}
+
+	}
+	if req.Email != "" {
+		if !utils.ValidateEmailFormatat(req.Email) {
+			br.Msg = "邮箱格式有误, 请检查"
+			return
+		}
+
+		user, err := models.GetUserByEmail(req.Email)
+		if err != nil && err != orm.ErrNoRows {
+			br.Msg = "编辑用户失败"
+			br.ErrMsg = "查询用户失败,系统错误,Err:" + err.Error()
+			return
+		}
+		if user != nil {
+			userCheckResp.UserId = user.UserId
+			if user.Status == 0 {
+				br.Ret = 200
+				br.Success = true
+				br.Msg = "该用户已被禁用,确认启用并更新用户信息吗?"
+				br.Data = userCheckResp
+				return
+			}
+			if user.Status == 1 {
+				br.Ret = 200
+				br.Success = true
+				br.Msg = "该用户已被禁用,确认启用并更新用户信息吗?"
+				br.Data = userCheckResp
+				return
+			}
+			if user.Status == 2 {
+				br.Msg = "邮箱已存在,请重新输入"
+				return
+			}
+			return
+		}
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "邮箱或手机号合格"
+}
+
+// List
+// @Title 用户列表
+// @Description 用户列表
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   SellerId   query   int  true       "销售id"
+// @Param   Status   query   int  true       "用户状态"
+// @Param   KeyWord   query   string  true       "手机号/邮箱/姓名"
+// @Param   IsRegistered   query   string  true       "是否注册"
+// @Param   IsSubscribed   query   string  true       "是否关注"
+// @Param   RegisterStartDate   query   string  true       "注册开始时间"
+// @Param   RegisterEndDate   query   string  true       "注册结束时间"
+// @Param   CreateStartDate   query   string  true       "创建开始时间"
+// @Param   CreateEndDate   query   string  true       "创建结束时间"
+// @Success 200 {object} models.LoginResp
+// @router /list [get]
+func (this *UserController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	sellerId, _ := this.GetInt("SellerId")
+	status := this.GetString("Status")
+	keyWord := this.GetString("KeyWord")
+	IsRegistered := this.GetString("IsRegisterd")
+	IsSubscribed := this.GetString("IsSubscribed")
+	registerStartDate := this.GetString("RegisterStartDate")
+	registerEndDate := this.GetString("RegisterEndDate")
+	createStartDate := this.GetString("CreateStartDate")
+	createEndDate := this.GetString("CreateEndDate")
+
+	var condition string
+	var pars []interface{}
+
+	if keyWord != "" {
+		condition += ` AND (real_name LIKE ? OR phone LIKE ? OR email LIKE ?) `
+		pars = utils.GetLikeKeywordPars(pars, keyWord, 3)
+	}
+
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	} else if pageSize > utils.PageSize100 {
+		pageSize = utils.PageSize100
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+
+	if sellerId > 0 {
+		condition += " AND seller_id=? "
+		pars = append(pars, sellerId)
+	}
+	switch status {
+	case "禁用":
+		condition += " AND status=? "
+		pars = append(pars, 0)
+	case "潜在":
+		condition += " AND status=? "
+		pars = append(pars, 1)
+	case "正式":
+		condition += " AND status=? "
+		pars = append(pars, 2)
+	}
+	switch IsRegistered {
+	case "是":
+		condition += " AND is_registered=? "
+		pars = append(pars, true)
+	case "否":
+		condition += " AND is_registered=? "
+		pars = append(pars, false)
+	}
+	switch IsSubscribed {
+	case "是":
+		condition += " AND is_subscribed=? "
+		pars = append(pars, true)
+	case "否":
+		condition += " AND is_subscribed=? "
+		pars = append(pars, false)
+	}
+	if registerStartDate != "" {
+		registerStartTime, er := time.Parse("2006-01-02 15:04:05", registerStartDate)
+		if er != nil {
+			br.Msg = "日期格式有误"
+			return
+		}
+		condition += " AND register_time>? "
+		pars = append(pars, registerStartTime)
+	}
+	if registerEndDate != "" {
+		registerEndTime, er := time.Parse("2006-01-02 15:04:05", registerEndDate)
+		if er != nil {
+			br.Msg = "日期格式有误"
+			return
+		}
+		condition += " AND register_time<? "
+		pars = append(pars, registerEndTime)
+	}
+	if createStartDate != "" {
+		createStartTime, er := time.Parse("2006-01-02 15:04:05", createStartDate)
+		if er != nil {
+			br.Msg = "日期格式有误"
+			return
+		}
+		condition += " AND create_time>? "
+		pars = append(pars, createStartTime)
+	}
+	if createEndDate != "" {
+		createEndTime, er := time.Parse("2006-01-02 15:04:05", createEndDate)
+		if er != nil {
+			br.Msg = "日期格式有误"
+			return
+		}
+		condition += " AND create_time<? "
+		pars = append(pars, createEndTime)
+	}
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	} else if pageSize > utils.PageSize100 {
+		pageSize = utils.PageSize100
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize := utils.StartIndex(currentIndex, pageSize)
+
+	total, err := models.GetUserCount(condition, pars)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	userList, err := models.GetUserList(condition, pars, startSize, pageSize)
+	if err != nil {
+		br.Msg = "查询用户失败"
+		br.Msg = "查询用户失败,系统错误,Err:" + err.Error()
+		return
+	}
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp := new(response.UserListResp)
+	resp.Paging = page
+	resp.List = userList
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// Detail
+// @Title 系统用户详情信息
+// @Description 用户详情信息
+// @Param   UserId   query   int  true       "系统用户id"
+// @Success 200 {object} models.LoginResp
+// @router /detail [get]
+func (this *UserController) Detail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	UserId, err := this.GetInt("UserId")
+	if err != nil {
+		br.Msg = "参数解析错误"
+		return
+	}
+	if UserId <= 0 {
+		br.Msg = "查询用户不存在"
+		return
+	}
+	user, err := models.GetUserById(UserId)
+	if err != nil {
+		if err == orm.ErrNoRows {
+			br.Msg = "用户不存在或已删除,请刷新页面"
+			return
+		}
+		br.Msg = "查询用户失败"
+		br.ErrMsg = "查询用户失败,系统错误,Err:" + err.Error()
+		return
+	}
+	if user == nil {
+		br.Msg = "用户不存在或已删除,请刷新页面"
+		return
+	}
+	br.Msg = "查询成功"
+	br.Ret = 200
+	br.Success = true
+	br.Data = user
+}
+
+// Delete
+// @Title 系统用户详情信息
+// @Description 用户详情信息
+// @Param   request	body request.UserDeleteReq true "type json string"
+// @Success 200 {object} models.LoginResp
+// @router /delete [post]
+func (this *UserController) Delete() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	var req request.UserDeleteReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	err = models.DeleteUserById(req.UserId)
+	if err != nil {
+		br.Msg = "删除失败"
+		br.ErrMsg = "删除失败,系统错误,Err:" + err.Error()
+		return
+	}
+	br.Msg = "删除成功"
+	br.Success = true
+	br.Ret = 200
+}

+ 20 - 22
controllers/user_login.go

@@ -3,6 +3,8 @@ package controllers
 import (
 	"encoding/json"
 	"eta/eta_mini_crm/models"
+	"eta/eta_mini_crm/models/request"
+	"eta/eta_mini_crm/models/response"
 	"eta/eta_mini_crm/utils"
 	"fmt"
 	"time"
@@ -30,13 +32,7 @@ func (this *UserLoginController) Login() {
 		this.ServeJSON()
 	}()
 
-	type UserLoginReq struct {
-		UserName string `description:"账号"`
-		Password string `description:"密码"`
-		ReqTime  string `description:"登录时间戳"`
-	}
-
-	var req UserLoginReq
+	var req request.UserLoginReq
 	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
 	if err != nil {
 		br.Msg = "参数解析异常!"
@@ -62,6 +58,12 @@ func (this *UserLoginController) Login() {
 			return
 		}
 	}
+	sysRole, err := models.GetSysRoleById(sysUser.SysRoleId)
+	if err != nil {
+		br.Msg = "登录失败"
+		br.ErrMsg = "查询角色失败, Err:" + err.Error()
+		return
+	}
 	dbPass := utils.MD5(fmt.Sprintf("%s%s%s", sysUser.Password, utils.UserLoginSalt, req.ReqTime))
 	if req.Password != dbPass {
 		br.Msg = "登录失败, 账号或密码错误"
@@ -82,21 +84,7 @@ func (this *UserLoginController) Login() {
 		br.ErrMsg = "新增session信息失败, Err:" + err.Error()
 		return
 	}
-	sysRole, err := models.GetSysRoleById(sysUser.SysRoleId)
-	if err != nil {
-		br.Msg = "登录失败"
-		br.ErrMsg = "查询角色失败, Err:" + err.Error()
-		return
-	}
-	type LoginResp struct {
-		Authorization string
-		SysUserName   string `description:"系统用户名"`
-		SysRealName   string `description:"系统用户姓名"`
-		SysUserId     int    `description:"系统用户id"`
-		RoleName      string `description:"所属角色名称"`
-		RoleId        int    `description:"所属角色id"`
-	}
-	resp := new(LoginResp)
+	resp := new(response.LoginResp)
 	resp.Authorization = "authorization=" + token
 	resp.SysUserName = sysUser.SysUserName
 	resp.SysRealName = sysUser.SysRealName
@@ -109,3 +97,13 @@ func (this *UserLoginController) Login() {
 	br.Success = true
 	br.Msg = "登录成功"
 }
+
+// AreaCodeList
+// @Title 用户登录
+// @Description 用户登录
+// @Param	request	body UserLoginReq true "type json string"
+// @Success 200 {object} models.LoginResp
+// @router /area_code/list [get]
+func (this *UserLoginController) AreaCodeList() {
+
+}

+ 2 - 1
go.mod

@@ -7,6 +7,8 @@ require (
 	github.com/beego/beego/v2 v2.1.0
 	github.com/dgrijalva/jwt-go v3.2.0+incompatible
 	github.com/go-sql-driver/mysql v1.7.0
+	github.com/rdlucklib/rdluck_tools v1.0.3
+	github.com/robfig/cron/v3 v3.0.1
 )
 
 require (
@@ -22,7 +24,6 @@ require (
 	github.com/prometheus/client_model v0.3.0 // indirect
 	github.com/prometheus/common v0.42.0 // indirect
 	github.com/prometheus/procfs v0.9.0 // indirect
-	github.com/rdlucklib/rdluck_tools v1.0.3 // indirect
 	github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 // indirect
 	golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect
 	golang.org/x/net v0.7.0 // indirect

+ 0 - 228
go.sum

@@ -1,228 +0,0 @@
-github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
-github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
-github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
-github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
-github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
-github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
-github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk=
-github.com/astaxie/beego v1.12.3/go.mod h1:p3qIm0Ryx7zeBHLljmd7omloyca1s4yu1a8kM1FkpIA=
-github.com/beego/bee/v2 v2.1.0 h1:4WngbAnkvVOyKy74WXcRH3clon76wkjhuzrV2mx2fQU=
-github.com/beego/bee/v2 v2.1.0/go.mod h1:wDhKy5TNxv46LHKsK2gyxo38ObCOm9PbCN89lWHK3EU=
-github.com/beego/beego/v2 v2.1.0 h1:Lk0FtQGvDQCx5V5yEu4XwDsIgt+QOlNjt5emUa3/ZmA=
-github.com/beego/beego/v2 v2.1.0/go.mod h1:6h36ISpaxNrrpJ27siTpXBG8d/Icjzsc7pU1bWpp0EE=
-github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ=
-github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542/go.mod h1:kSeGC/p1AbBiEp5kat81+DSQrZenVBZXklMLaELspWU=
-github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
-github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
-github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
-github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
-github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
-github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE=
-github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
-github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
-github.com/couchbase/go-couchbase v0.0.0-20200519150804-63f3cdb75e0d/go.mod h1:TWI8EKQMs5u5jLKW/tsb9VwauIrMIxQG1r5fMsswK5U=
-github.com/couchbase/gomemcached v0.0.0-20200526233749-ec430f949808/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c=
-github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
-github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
-github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
-github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
-github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
-github.com/elastic/go-elasticsearch/v6 v6.8.5/go.mod h1:UwaDJsD3rWLM5rKNFzv9hgox93HoX8utj1kxD9aFUcI=
-github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
-github.com/elazarl/go-bindata-assetfs v1.0.1 h1:m0kkaHRKEu7tUIUFVwhGGGYClXvyl4RE03qmvRTNfbw=
-github.com/elazarl/go-bindata-assetfs v1.0.1/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
-github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
-github.com/garyburd/redigo v1.6.3/go.mod h1:rTb6epsqigu3kYKBnaF028A7Tf/Aw5s0cqA47doKKqw=
-github.com/glendc/gopher-json v0.0.0-20170414221815-dc4743023d0c/go.mod h1:Gja1A+xZ9BoviGJNA2E9vFkPjjsl+CoJxSXiQM1UXtw=
-github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
-github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
-github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
-github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
-github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
-github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
-github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
-github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
-github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
-github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
-github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
-github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
-github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
-github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
-github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
-github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
-github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
-github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
-github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
-github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
-github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
-github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
-github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
-github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
-github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
-github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
-github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
-github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
-github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
-github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
-github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
-github.com/ledisdb/ledisdb v0.0.0-20200510135210-d35789ec47e6/go.mod h1:n931TsDuKuq+uX4v1fulaMbA/7ZLLhjc85h7chZGBCQ=
-github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
-github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
-github.com/lib/pq v1.10.5 h1:J+gdV2cUmX7ZqL2B0lFcW0m+egaHC2V3lpO8nWxyYiQ=
-github.com/lib/pq v1.10.5/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
-github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEghA=
-github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
-github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
-github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
-github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
-github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
-github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
-github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
-github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
-github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
-github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
-github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
-github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
-github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
-github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
-github.com/peterh/liner v1.0.1-0.20171122030339-3681c2a91233/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
-github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
-github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
-github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
-github.com/prometheus/client_golang v1.7.0/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
-github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI=
-github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
-github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
-github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
-github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
-github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
-github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
-github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
-github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
-github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
-github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
-github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
-github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
-github.com/rdlucklib/rdluck_tools v1.0.3 h1:iOtK2QPlPQ6CL6c1htCk5VnFCHzyG6DCfJtunrMswK0=
-github.com/rdlucklib/rdluck_tools v1.0.3/go.mod h1:9Onw9o4w19C8KE5lxb8GyxgRBbZweRVkQSc79v38EaA=
-github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
-github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
-github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
-github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 h1:DAYUYH5869yV94zvCES9F51oYtN5oGlwjxJJz7ZCnik=
-github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
-github.com/siddontang/go v0.0.0-20170517070808-cb568a3e5cc0/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
-github.com/siddontang/goredis v0.0.0-20150324035039-760763f78400/go.mod h1:DDcKzU3qCuvj/tPnimWSsZZzvk9qvkvrIL5naVBPh5s=
-github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA=
-github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
-github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
-github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec/go.mod h1:QBvMkMya+gXctz3kmljlUCu/yB3GZ6oee+dUozsezQE=
-github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
-github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
-github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
-github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
-github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
-github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
-github.com/ylywyn/jpush-api-go-client v0.0.0-20190906031852-8c4466c6e369/go.mod h1:Nv7wKD2/bCdKUFNKcJRa99a+1+aSLlCRJFriFYdjz/I=
-github.com/yuin/gopher-lua v0.0.0-20171031051903-609c9cd26973/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU=
-golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd h1:XcWmESyNjXJMLahc3mqVQJcgSTDxFxhETVlfk9uGc38=
-golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
-golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
-golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
-golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
-google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
-google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
-google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
-google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
-google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
-google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
-gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
-gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
-gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
-gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
-gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
-gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
-gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

+ 2 - 0
main.go

@@ -2,10 +2,12 @@ package main
 
 import (
 	_ "eta/eta_mini_crm/routers"
+	"eta/eta_mini_crm/scheduler"
 
 	"github.com/beego/beego/v2/server/web"
 )
 
 func main() {
+	go scheduler.InitJob()
 	web.Run()
 }

+ 86 - 0
models/chart_permission.go

@@ -0,0 +1,86 @@
+package models
+
+import (
+	"time"
+
+	"github.com/beego/beego/v2/client/orm"
+)
+
+type ChartPermission struct {
+	ChartPermissionId     int       `orm:"column(chart_permission_id);pk" description:"问题ID" json:"chart_permission_id"`
+	ChartPermissionName   string    `description:"名称" json:"chart_permission_name"`
+	PermissionName        string    `description:"权限名" json:"permission_name"`
+	Sort                  int       `description:"排序" json:"sort"`
+	Enabled               int       `description:"是否可用" json:"enabled"`
+	CreatedTime           time.Time `description:"创建时间" json:"created_time"`
+	LastUpdatedTime       time.Time `description:"更新时间" json:"last_updated_time"`
+	TeleconferenceSort    int       `description:"电话会类型排序" json:"teleconference_sort"`
+	Remark                string    `description:"备注" json:"remark"`
+	ClassifyName          string    `description:"分类名称" json:"classify_name"`
+	ProductName           string    `description:"产品名称" json:"product_name"`
+	ProductId             int       `description:"产品ID" json:"product_id"`
+	ImageURL              string    `orm:"column(image_url);" description:"图片地址" json:"image_url"`
+	ShowType              int       `description:"1:查研观向小程序展示" json:"show_type"`
+	IsOther               int       `description:"是否是其他,用于查研观向小程序后台展示" json:"is_other"`
+	IsReport              int       `description:"是否是报告,用于查研观向小程序前台报告展示" json:"is_report"`
+	CygxAuth              int       `description:"是否是权限,用于查研观向小程序前台权限校验" json:"cygx_auth"`
+	PermissionType        int       `description:"1主观,2客观" json:"permission_type"`
+	YbImgUrl              string    `description:"研报小程序报告列表icon" json:"yb_img_url"`
+	ProductPermissionName string    `description:"种类权限名称" json:"product_permission_name"`
+	PriceDrivenState      int       `description:"品种价格驱动开启状态 0-关闭 1-开启" json:"price_driven_state"`
+	ImageUrlM             string    `description:"图片地址(查研观向移动端)" json:"image_url_m"`
+	ParentId              int       `description:"父级权限id" json:"parent_id"`
+	IsPublic              int       `description:"是否是公有权限1:公有权限,0私有权限" json:"is_public"`
+}
+
+type ChartPermissionList struct {
+	ChartPermissionId     int                    `orm:"column(chart_permission_id);pk" description:"问题ID" json:"chart_permission_id"`
+	ChartPermissionName   string                 `description:"名称" json:"chart_permission_name"`
+	PermissionName        string                 `description:"权限名" json:"permission_name"`
+	Sort                  int                    `description:"排序" json:"sort"`
+	Enabled               int                    `description:"是否可用" json:"enabled"`
+	CreatedTime           time.Time              `description:"创建时间" json:"created_time"`
+	LastUpdatedTime       time.Time              `description:"更新时间" json:"last_updated_time"`
+	TeleconferenceSort    int                    `description:"电话会类型排序" json:"teleconference_sort"`
+	Remark                string                 `description:"备注" json:"remark"`
+	ClassifyName          string                 `description:"分类名称" json:"classify_name"`
+	ProductName           string                 `description:"产品名称" json:"product_name"`
+	ProductId             int                    `description:"产品ID" json:"product_id"`
+	ImageURL              string                 `orm:"column(image_url);" description:"图片地址" json:"image_url"`
+	ShowType              int                    `description:"1:查研观向小程序展示" json:"show_type"`
+	IsOther               int                    `description:"是否是其他,用于查研观向小程序后台展示" json:"is_other"`
+	IsReport              int                    `description:"是否是报告,用于查研观向小程序前台报告展示" json:"is_report"`
+	CygxAuth              int                    `description:"是否是权限,用于查研观向小程序前台权限校验" json:"cygx_auth"`
+	PermissionType        int                    `description:"1主观,2客观" json:"permission_type"`
+	YbImgUrl              string                 `description:"研报小程序报告列表icon" json:"yb_img_url"`
+	ProductPermissionName string                 `description:"种类权限名称" json:"product_permission_name"`
+	PriceDrivenState      int                    `description:"品种价格驱动开启状态 0-关闭 1-开启" json:"price_driven_state"`
+	ImageUrlM             string                 `description:"图片地址(查研观向移动端)" json:"image_url_m"`
+	ParentId              int                    `description:"父级权限id" json:"parent_id"`
+	IsPublic              int                    `description:"是否是公有权限1:公有权限,0私有权限" json:"is_public"`
+	Child                 []*ChartPermissionList `description:"子权限"`
+}
+
+func GetChartPermissionList(condition string, pars []interface{}) (items []*ChartPermission, err error) {
+	o := orm.NewOrmUsingDB("rddp")
+	sql := `SELECT * FROM chart_permission WHERE enabled=1 `
+	if condition != "" {
+		sql += condition
+	}
+	_, err = o.Raw(sql, pars...).QueryRows(items)
+	return
+}
+
+func GetChildChartPermissionListById(ChartPermissionId int) (items []*ChartPermissionList, err error) {
+	o := orm.NewOrmUsingDB("rddp")
+	sql := `SELECT * FROM chart_permission WHERE enabled=1 AND parent_id=?`
+	_, err = o.Raw(sql, ChartPermissionId).QueryRows(&items)
+	return
+}
+
+func GetChartPermissionByParentId(parentId int) (items []*ChartPermissionList, err error) {
+	o := orm.NewOrmUsingDB("rddp")
+	sql := `SELECT * FROM chart_permission WHERE enabled=1 AND chart_permission_id=?`
+	_, err = o.Raw(sql, parentId).QueryRows(&items)
+	return
+}

+ 4 - 1
models/db.go

@@ -33,6 +33,9 @@ func init() {
 		new(SysDepartment),
 		new(SysMenu),
 		new(SysRoleMenuMapping),
-		new(SysUserDepartmentMapping),
+		new(ChartPermission),
+		new(UserChartPermissionMapping),
+		new(User),
+		new(SysMessageReport),
 	)
 }

+ 5 - 0
models/request/chart_permission.go

@@ -0,0 +1,5 @@
+package request
+
+type ChartPermissionListReq struct {
+	UserId int `description:"用户ID"`
+}

+ 5 - 0
models/request/sys_message_report.go

@@ -0,0 +1,5 @@
+package request
+
+type SysMessageReadReq struct {
+	SysMessageId []int
+}

+ 6 - 0
models/request/sys_user.go

@@ -30,3 +30,9 @@ type MoveToDepartmentReq struct {
 	SysUserId       int `description:"用户id"`
 	SysDepartmentId int `description:"部门id"`
 }
+
+type UserLoginReq struct {
+	UserName string `description:"账号"`
+	Password string `description:"密码"`
+	ReqTime  string `description:"登录时间戳"`
+}

+ 37 - 0
models/request/user.go

@@ -0,0 +1,37 @@
+package request
+
+type UserAddReq struct {
+	RealName        string `description:"姓名"`
+	AreaCode        string `description:"区号"`
+	Phone           string `description:"手机号"`
+	Email           string `description:"邮箱"`
+	SellerId        int    `description:"销售id"`
+	ValidStartTime  string `description:"有效期开始时间"`
+	ValidEndTime    string `description:"有效期结束时间"`
+	Company         string `description:"所属公司"`
+	ChartPermission []int  `description:"所选品种"`
+}
+
+type UserEidtReq struct {
+	UserId          int    `description:"用户id"`
+	RealName        string `description:"姓名"`
+	AreaCode        string `description:"区号"`
+	Phone           string `description:"手机号"`
+	Email           string `description:"邮箱"`
+	SellerId        int    `description:"销售id"`
+	ValidStartTime  string `description:"有效期开始时间"`
+	ValidEndTime    string `description:"有效期结束时间"`
+	Company         string `description:"所属公司"`
+	ChartPermission []int  `description:"所选品种"`
+	IsEnabled       bool   `description:"是否禁用"`
+}
+
+type UserCheckReq struct {
+	AreaCode string `description:"区号"`
+	Phone    string `description:"手机号"`
+	Email    string `description:"邮箱"`
+}
+
+type UserDeleteReq struct {
+	UserId int `description:"用户id"`
+}

+ 9 - 0
models/response/chart_permission.go

@@ -0,0 +1,9 @@
+package response
+
+import "eta/eta_mini_crm/models"
+
+type ChartPermissionListresp struct {
+	PublicList   []*models.ChartPermissionList
+	PrivateList  []*models.ChartPermissionList
+	SelectedList []int
+}

+ 12 - 0
models/response/sys_message_report.go

@@ -0,0 +1,12 @@
+package response
+
+import (
+	"eta/eta_mini_crm/models"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+type SysMessageListResp struct {
+	List   []*models.SysMessageReport
+	Paging *paging.PagingItem `description:"分页数据"`
+}

+ 9 - 0
models/response/sys_user.go

@@ -10,3 +10,12 @@ type SysUserListResp struct {
 	List   []models.SysUserView
 	Paging *paging.PagingItem `description:"分页数据"`
 }
+
+type LoginResp struct {
+	Authorization string
+	SysUserName   string `description:"系统用户名"`
+	SysRealName   string `description:"系统用户姓名"`
+	SysUserId     int    `description:"系统用户id"`
+	RoleName      string `description:"所属角色名称"`
+	RoleId        int    `description:"所属角色id"`
+}

+ 16 - 0
models/response/user.go

@@ -0,0 +1,16 @@
+package response
+
+import (
+	"eta/eta_mini_crm/models"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+type UserListResp struct {
+	List   []*models.User
+	Paging *paging.PagingItem `description:"分页数据"`
+}
+
+type UserCheckResp struct {
+	UserId int
+}

+ 27 - 0
models/sys_department.go

@@ -71,6 +71,33 @@ func DeleteSysDepartmentById(sysDepartmentIds []string, level int) (err error) {
 	return
 }
 
+func DeleteSysDepartmentByIdV2(sysDepartmentIds []string, level int) (err error) {
+	o := orm.NewOrmUsingDB("master")
+	err = o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
+		// sql := `DELETE FROM sys_department WHERE sys_department_id IN (?) `
+		_, e := txOrm.QueryTable(&SysDepartment{}).
+			Filter("sys_department_id__in", sysDepartmentIds).
+			Delete()
+		if e != nil {
+			return e
+		}
+		sql := `UPDATE sys_user SET `
+		for i := level; i <= utils.MaxDepartmentLevel; i++ {
+			sql += fmt.Sprintf("sys_department_id%d=0 ", i)
+			if i != utils.MaxDepartmentLevel {
+				sql += ","
+			}
+		}
+		sql += fmt.Sprintf("WHERE sys_department_id%d=?", level)
+		_, e = txOrm.Raw(sql, sysDepartmentIds[0]).Exec()
+		if e != nil {
+			return e
+		}
+		return nil
+	})
+	return
+}
+
 func UpdateDepartmentSortByIds(sysDepartmentIds []int) (err error) {
 	o := orm.NewOrmUsingDB("master")
 	err = o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {

+ 60 - 0
models/sys_message_report.go

@@ -0,0 +1,60 @@
+package models
+
+import (
+	"time"
+
+	"github.com/beego/beego/v2/client/orm"
+)
+
+type SysMessageReport struct {
+	SysMessageReportId int       `orm:"pk" description:"消息id"`
+	UserId             int       `description:"到期用户id"`
+	ReceiveSysUserId   int       `description:"接收系统用户id"`
+	MessageType        int       `description:"消息类型"`
+	Content            string    `description:"内容"`
+	Remark             string    `description:"备注"`
+	IsRead             bool      `description:"是否已读"`
+	CreateTime         time.Time `description:"创建时间"`
+	ModifyTime         time.Time `description:"修改时间"`
+}
+
+func (s *SysMessageReport) Update(cols []string) (err error) {
+	o := orm.NewOrmUsingDB("master")
+	_, err = o.Update(s, cols...)
+	return
+}
+
+func GetSysMessageReportCountBySysUserId(sysUserId int) (count int, err error) {
+	o := orm.NewOrmUsingDB("master")
+	sql := `SELECT COUNT(*) AS count FROM sys_message_report WHERE receive_sys_user_id=?`
+	err = o.Raw(sql, sysUserId).QueryRow(&count)
+	return
+}
+
+func GetSysMessageReportBySysUserId(sysUserId, startSize, pageSize int) (item []*SysMessageReport, err error) {
+	o := orm.NewOrmUsingDB("master")
+	sql := `SELECT * FROM sys_message_report WHERE receive_sys_user_id=? LIMIT ?,?`
+	_, err = o.Raw(sql, sysUserId, startSize, pageSize).QueryRows(&item)
+	return
+}
+
+func InsertMultiSysMessageReport(sysMessageReportList []SysMessageReport) (err error) {
+	o := orm.NewOrmUsingDB("master")
+	_, err = o.InsertMulti(500, sysMessageReportList)
+	return
+}
+
+func GetSysMessageReportListById(sysMessageReportIds []int) (items []*SysMessageReport, err error) {
+	o := orm.NewOrmUsingDB("master")
+	_, err = o.QueryTable(&SysMessageReport{}).
+		Filter("sys_message_report_id__in", sysMessageReportIds).
+		All(&items)
+	return
+}
+
+func GetSysMessageReportCount(userId int, messageType int) (count int, err error) {
+	o := orm.NewOrmUsingDB("master")
+	sql := `SELECT COUNT(*) AS count FROM sys_message_report WHERE user_id=? AND message_type=? `
+	err = o.Raw(sql, userId, messageType).QueryRow(&count)
+	return
+}

+ 53 - 37
models/sys_user.go

@@ -1,28 +1,30 @@
 package models
 
 import (
-	"context"
 	"time"
 
 	"github.com/beego/beego/v2/client/orm"
 )
 
 type SysUser struct {
-	SysUserId       int       `orm:"pk" description:"系统用户id"`
-	SysUserName     string    `description:"账号"`
-	SysRealName     string    `description:"姓名"`
-	Password        string    `description:"密码"`
-	Email           string    `description:"邮箱"`
-	Phone           string    `description:"手机号"`
-	AreaCode        string    `description:"手机区号"`
-	SysRoleId       int       `description:"角色id"`
-	SysRoleName     string    `description:"角色名称"`
-	SysDepartmentId int       `description:"所属部门id"`
-	Province        string    `description:"省"`
-	City            string    `description:"市"`
-	IsEnabled       bool      `description:"是否启用"`
-	CreateTime      time.Time `description:"创建时间"`
-	ModifyTime      time.Time `description:"更新时间"`
+	SysUserId        int       `orm:"pk" description:"系统用户id"`
+	SysUserName      string    `description:"账号"`
+	SysRealName      string    `description:"姓名"`
+	Password         string    `description:"密码"`
+	Email            string    `description:"邮箱"`
+	Phone            string    `description:"手机号"`
+	AreaCode         string    `description:"手机区号"`
+	SysRoleId        int       `description:"角色id"`
+	SysRoleName      string    `description:"角色名称"`
+	SysDepartmentId  int       `description:"所属部门id"`
+	SysDepartmentId1 int       `description:"所属部门一级id"`
+	SysDepartmentId2 int       `description:"所属部门二级id"`
+	SysDepartmentId3 int       `description:"所属部门三级id"`
+	Province         string    `description:"省"`
+	City             string    `description:"市"`
+	IsEnabled        bool      `description:"是否启用"`
+	CreateTime       time.Time `description:"创建时间"`
+	ModifyTime       time.Time `description:"更新时间"`
 }
 
 type SysUserView struct {
@@ -79,25 +81,34 @@ func (s *SysUser) Update(cols []string) (err error) {
 
 func SaveSysUser(sysUser *SysUser, sysDepartmendPathIds []int) (err error) {
 	o := orm.NewOrmUsingDB("master")
-	err = o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
-		insertId, e := txOrm.InsertOrUpdate(sysUser)
-		if e != nil {
-			return e
-		}
-		userDepMapping := &SysUserDepartmentMapping{}
-		userDepMapping.SysUserId = int(insertId)
-		userDepMapping.SysDepartmentId1 = sysDepartmendPathIds[0]
-		userDepMapping.SysDepartmentId2 = sysDepartmendPathIds[1]
-		userDepMapping.SysDepartmentId3 = sysDepartmendPathIds[2]
-		_, e = txOrm.InsertOrUpdate(userDepMapping)
-		if e != nil {
-			return e
-		}
-		return nil
-	})
+	sysUser.SysDepartmentId1 = sysDepartmendPathIds[0]
+	sysUser.SysDepartmentId2 = sysDepartmendPathIds[1]
+	sysUser.SysDepartmentId3 = sysDepartmendPathIds[2]
+	_, err = o.InsertOrUpdate(sysUser)
 	return
 }
 
+// func SaveSysUser(sysUser *SysUser, sysDepartmendPathIds []int) (err error) {
+// 	o := orm.NewOrmUsingDB("master")
+// 	err = o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
+// 		insertId, e := txOrm.InsertOrUpdate(sysUser)
+// 		if e != nil {
+// 			return e
+// 		}
+// 		userDepMapping := &SysUserDepartmentMapping{}
+// 		userDepMapping.SysUserId = int(insertId)
+// 		userDepMapping.SysDepartmentId1 = sysDepartmendPathIds[0]
+// 		userDepMapping.SysDepartmentId2 = sysDepartmendPathIds[1]
+// 		userDepMapping.SysDepartmentId3 = sysDepartmendPathIds[2]
+// 		_, e = txOrm.InsertOrUpdate(userDepMapping)
+// 		if e != nil {
+// 			return e
+// 		}
+// 		return nil
+// 	})
+// 	return
+// }
+
 func GetSysUserBySysUserName(sysUserName string) (item *SysUser, err error) {
 	sql := `SELECT * FROM sys_user WHERE sys_user_name=?`
 	o := orm.NewOrmUsingDB("master")
@@ -146,14 +157,12 @@ func GetSysUserCountByRoleId(roleId int) (count int, err error) {
 func GetSysUserList(condition string, pars []interface{}, startSize, pageSize int) (items []*SysUserMapping, err error) {
 	sql := `SELECT u.*,d1.sys_department_name sys_department_name1, d2.sys_department_name sys_department_name2, d3.sys_department_name sys_department_name3
 	FROM sys_user u
-	LEFT JOIN sys_user_department_mapping AS ud
-	ON u.sys_user_id = ud.sys_user_id
 	LEFT JOIN sys_department AS d1
-	ON ud.sys_department_id1 = d1.sys_department_id
+	ON u.sys_department_id1 = d1.sys_department_id
 	LEFT JOIN sys_department AS d2
-	ON ud.sys_department_id2 = d2.sys_department_id
+	ON u.sys_department_id2 = d2.sys_department_id
 	LEFT JOIN sys_department AS d3
-	ON ud.sys_department_id3 = d3.sys_department_id
+	ON u.sys_department_id3 = d3.sys_department_id
 	WHERE 1=1 `
 	if condition != "" {
 		sql += condition
@@ -163,3 +172,10 @@ func GetSysUserList(condition string, pars []interface{}, startSize, pageSize in
 	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
 	return
 }
+
+func GetSysUserIdList() (items []int, err error) {
+	sql := ` SELECT sys_user_id FROM sys_user WHERE 1=1 `
+	o := orm.NewOrmUsingDB("master")
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}

+ 0 - 41
models/sys_user_department_mapping.go

@@ -1,41 +0,0 @@
-package models
-
-import (
-	"context"
-
-	"github.com/beego/beego/v2/client/orm"
-)
-
-type SysUserDepartmentMapping struct {
-	SysUserId        int `orm:"pk" description:"系统用户id"`
-	SysDepartmentId1 int `description:"一级部门id"`
-	SysDepartmentId2 int `description:"二级部门id"`
-	SysDepartmentId3 int `description:"三级部门id"`
-}
-
-func (s *SysUserDepartmentMapping) Save() (err error) {
-	o := orm.NewOrmUsingDB("master")
-	err = o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
-		sql := `UPDATE sys_user SET sys_department_id=? WHERE sys_user_id=? `
-		var depId int
-		if s.SysDepartmentId1 != 0 {
-			depId = s.SysDepartmentId1
-		}
-		if s.SysDepartmentId2 != 0 {
-			depId = s.SysDepartmentId2
-		}
-		if s.SysDepartmentId3 != 0 {
-			depId = s.SysDepartmentId3
-		}
-		_, e := txOrm.Raw(sql, depId, s.SysUserId).Exec()
-		if e != nil {
-			return e
-		}
-		_, e = txOrm.InsertOrUpdate(s)
-		if e != nil {
-			return e
-		}
-		return nil
-	})
-	return
-}

+ 112 - 0
models/user.go

@@ -0,0 +1,112 @@
+package models
+
+import (
+	"context"
+	"time"
+
+	"github.com/beego/beego/v2/client/orm"
+)
+
+type User struct {
+	UserId         int       `orm:"pk" description:"用户id"`
+	RealName       string    `description:"姓名"`
+	Phone          string    `description:"手机号"`
+	AreaCode       string    `description:"区号"`
+	Email          string    `description:"邮箱"`
+	SellerId       int       `description:"销售id(SysUserId)"`
+	Company        string    `description:"所属公司"`
+	ValidStartTime time.Time `description:"有效期开始时间"`
+	ValidEndTime   time.Time `description:"有效期结束时间"`
+	Status         int       `description:"用户类型: 0表示禁用,1表示潜在客户,2表示正式客户"`
+	CreateTime     time.Time `description:"系统中首次新增用户的时间"`
+	ModifyTime     time.Time `description:"系统中用户信息变更的时间"`
+	RegisterTime   time.Time `description:"用户首次登录小程序的时间"`
+	IsSubscribed   bool      `description:"是否关注公众号: 0表示没有关注,1表示关注"`
+	IsRegistered   bool      `description:"是否注册: 0表示没有注册,1表示注册"`
+}
+
+func (u *User) Save() (err error) {
+	o := orm.NewOrmUsingDB("master")
+	_, err = o.InsertOrUpdate(u)
+	return
+}
+
+func SaveUser(user *User, chartPermissionIds []int) (err error) {
+	o := orm.NewOrmUsingDB("master")
+	err = o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
+		insertId, er := txOrm.InsertOrUpdate(user)
+		if er != nil {
+			return er
+		}
+		if user.UserId != 0 {
+			insertId = int64(user.UserId)
+		}
+		// 先删除再增加
+		sql := `DELETE FROM user_chart_permission_mapping WHERE user_id=?`
+		_, er = txOrm.Raw(sql, insertId).Exec()
+		if er != nil {
+			return er
+		}
+		for _, id := range chartPermissionIds {
+			userChartPermissionMapping := new(UserChartPermissionMapping)
+			userChartPermissionMapping.UserId = int(insertId)
+			userChartPermissionMapping.ChartPermissionId = id
+			_, er = txOrm.Insert(userChartPermissionMapping)
+			if er != nil {
+				return er
+
+			}
+		}
+		return nil
+	})
+	return
+}
+
+func GetUserByPhone(phone, areaCode string) (item *User, err error) {
+	o := orm.NewOrmUsingDB("master")
+	sql := `SELECT * FROM user WHERE phone=? AND area_code=?`
+	err = o.Raw(sql, phone, areaCode).QueryRow(&item)
+	return
+}
+
+func GetUserByEmail(email string) (item *User, err error) {
+	o := orm.NewOrmUsingDB("master")
+	sql := `SELECT * FROM user WHERE email=? `
+	err = o.Raw(sql, email).QueryRow(&item)
+	return
+}
+
+func GetUserById(userId int) (item *User, err error) {
+	o := orm.NewOrmUsingDB("master")
+	sql := `SELECT * FROM user WHERE user_id=? `
+	err = o.Raw(sql, userId).QueryRow(&item)
+	return
+}
+
+func GetUserList(condition string, pars []interface{}, startSize, pageSize int) (items []*User, err error) {
+	sql := `SELECT * FROM user WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY modify_time DESC LIMIT ?,? `
+	o := orm.NewOrmUsingDB("master")
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+func GetUserCount(condition string, pars []interface{}) (count int, err error) {
+	sql := `SELECT COUNT(*) AS count FROM user WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	o := orm.NewOrmUsingDB("master")
+	err = o.Raw(sql, pars...).QueryRow(&count)
+	return
+}
+
+func DeleteUserById(userId int) (err error) {
+	sql := `DELETE FROM user WHERE user_id=?`
+	o := orm.NewOrmUsingDB("master")
+	_, err = o.Raw(sql, userId).Exec()
+	return
+}

+ 16 - 0
models/user_chart_permission_mapping.go

@@ -0,0 +1,16 @@
+package models
+
+import "github.com/beego/beego/v2/client/orm"
+
+type UserChartPermissionMapping struct {
+	UserChartPermissionMappingId int `orm:"pk" description:"id"`
+	UserId                       int `description:"用户id"`
+	ChartPermissionId            int `description:"品种id"`
+}
+
+func GetChartPermissionIdByUserId(UserId int) (items []int, err error) {
+	o := orm.NewOrmUsingDB("master")
+	sql := `SELECT chart_permission_id FROM user_chart_permission_mapping WHERE user_id=?`
+	_, err = o.Raw(sql, UserId).QueryRows(&items)
+	return
+}

+ 90 - 0
routers/commentsRouter.go

@@ -7,6 +7,15 @@ import (
 
 func init() {
 
+    beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:ChartPermissionController"] = append(beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:ChartPermissionController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:SysDepartmentController"] = append(beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:SysDepartmentController"],
         beego.ControllerComments{
             Method: "Add",
@@ -52,6 +61,24 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:SysMessageReportController"] = append(beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:SysMessageReportController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:SysMessageReportController"] = append(beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:SysMessageReportController"],
+        beego.ControllerComments{
+            Method: "Read",
+            Router: `/read`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:SysRoleController"] = append(beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:SysRoleController"],
         beego.ControllerComments{
             Method: "Add",
@@ -151,6 +178,69 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:UserController"] = append(beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:UserController"],
+        beego.ControllerComments{
+            Method: "Add",
+            Router: `/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:UserController"] = append(beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:UserController"],
+        beego.ControllerComments{
+            Method: "Check",
+            Router: `/check`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:UserController"] = append(beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:UserController"],
+        beego.ControllerComments{
+            Method: "Delete",
+            Router: `/delete`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:UserController"] = append(beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:UserController"],
+        beego.ControllerComments{
+            Method: "Detail",
+            Router: `/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:UserController"] = append(beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:UserController"],
+        beego.ControllerComments{
+            Method: "Edit",
+            Router: `/edit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:UserController"] = append(beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:UserController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:UserLoginController"] = append(beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:UserLoginController"],
+        beego.ControllerComments{
+            Method: "AreaCodeList",
+            Router: `/area_code/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:UserLoginController"] = append(beego.GlobalControllerRouter["eta/eta_mini_crm/controllers:UserLoginController"],
         beego.ControllerComments{
             Method: "Login",

+ 15 - 0
routers/router.go

@@ -32,6 +32,21 @@ func init() {
 				&controllers.SysRoleController{},
 			),
 		),
+		beego.NSNamespace("/chart_permission",
+			beego.NSInclude(
+				&controllers.ChartPermissionController{},
+			),
+		),
+		beego.NSNamespace("/user",
+			beego.NSInclude(
+				&controllers.UserController{},
+			),
+		),
+		beego.NSNamespace("/sys_message",
+			beego.NSInclude(
+				&controllers.SysMessageReportController{},
+			),
+		),
 	)
 	beego.AddNamespace(ns)
 }

+ 122 - 0
scheduler/task.go

@@ -0,0 +1,122 @@
+package scheduler
+
+import (
+	"eta/eta_mini_crm/models"
+	"eta/eta_mini_crm/utils"
+	"fmt"
+	"time"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"github.com/robfig/cron/v3"
+)
+
+func InitJob() {
+	fmt.Println("消息推送任务开启。。。")
+	c := cron.New(cron.WithSeconds())
+
+	// 每天凌晨1点检测
+	_, err := c.AddFunc("0 0 1 * * *", CheckUserTime)
+	if err != nil {
+		utils.ApiLog.Info("cron task err: %s", err.Error())
+	}
+	c.Start()
+}
+
+func CheckUserTime() {
+	retryCount := 10
+	var err error
+	defer func() {
+		if err != nil {
+			utils.ApiLog.Warn("userPermission 定时任务出错,Err: %s", err.Error())
+		}
+	}()
+	for i := 0; i <= retryCount; i++ {
+		err = CheckUserPermissionTime()
+		if err == nil {
+			break
+		}
+	}
+}
+
+func CheckUserPermissionTime() (err error) {
+	var condition string
+	var pars []interface{}
+
+	var userTotal int
+	pageSize := 500
+
+	curTime := time.Now()
+	time7 := time.Now().AddDate(0, 0, 7)
+	time15 := time.Now().AddDate(0, 0, 15)
+	time30 := time.Now().AddDate(0, 0, 30)
+	time60 := time.Now().AddDate(0, 0, 60)
+
+	// 批量查询到期的用户
+	messageMap := make(map[int]int)
+	userTotal, err = models.GetUserCount(condition, pars)
+	if err != nil {
+		utils.ApiLog.Warn("userPermission task err: %s", err.Error())
+	}
+	pageCount := paging.PageCount(userTotal, pageSize)
+	for i := 1; i <= pageCount; i++ {
+		startPage := utils.StartIndex(i, pageSize)
+		userList, err := models.GetUserList(condition, pars, startPage, pageSize)
+		if err != nil {
+			utils.ApiLog.Warn("userPermission task err: %s", err.Error())
+		}
+		for _, user := range userList {
+			if user.Status != 2 {
+				continue
+			}
+			if time60.After(user.ValidEndTime) {
+				messageMap[user.UserId] = 60
+			}
+			if time30.After(user.ValidEndTime) {
+				messageMap[user.UserId] = 30
+			}
+			if time15.After(user.ValidEndTime) {
+				messageMap[user.UserId] = 15
+			}
+			if time7.After(user.ValidEndTime) {
+				messageMap[user.UserId] = 7
+			}
+		}
+	}
+
+	// 把消息发送到系统用户中
+	sysUserIds, err := models.GetSysUserIdList()
+	if err != nil {
+		utils.ApiLog.Warn("userPermission task err: %s", err.Error())
+	}
+	layout := "【%s】到期%d天提醒,请及时跟进"
+	messageList := []models.SysMessageReport{}
+	for k, v := range messageMap {
+		count, err := models.GetSysMessageReportCount(k, v)
+		if err != nil {
+			continue
+		}
+		if count > 0 {
+			continue
+		}
+		user, err := models.GetUserById(k)
+		if err != nil {
+			continue
+		}
+		for _, sysUserId := range sysUserIds {
+			messageList = append(messageList, models.SysMessageReport{
+				UserId:           k,
+				ReceiveSysUserId: sysUserId,
+				MessageType:      v,
+				IsRead:           false,
+				CreateTime:       curTime,
+				ModifyTime:       curTime,
+				Content:          fmt.Sprintf(layout, user.RealName, v),
+			})
+		}
+		err = models.InsertMultiSysMessageReport(messageList)
+		if err != nil {
+			continue
+		}
+	}
+	return
+}

+ 68 - 0
services/chart_permission.go

@@ -0,0 +1,68 @@
+package services
+
+import "eta/eta_mini_crm/models"
+
+// 获得全部的权限结构列表
+func GetChartPermissionList() (publicMap, privateMap map[string]*models.ChartPermissionList, err error) {
+	items, err := models.GetChildChartPermissionListById(0)
+	if err != nil {
+		return
+	}
+	publicMap = make(map[string]*models.ChartPermissionList)
+	privateMap = make(map[string]*models.ChartPermissionList)
+	for _, cpl := range items {
+		childPermissionList, e := models.GetChildChartPermissionListById(cpl.ChartPermissionId)
+		if e != nil {
+			return nil, nil, e
+		}
+		publicTmp := copyChartPermissionList(cpl)
+		privateTmp := copyChartPermissionList(cpl)
+
+		for _, childCpl := range childPermissionList {
+			if childCpl.IsPublic == 1 {
+				// 公有权限
+				publicTmp.Child = append(publicTmp.Child, childCpl)
+			} else {
+				// 私有权限
+				privateTmp.Child = append(privateTmp.Child, childCpl)
+			}
+		}
+		if len(publicTmp.Child) > 0 {
+			publicMap[cpl.ChartPermissionName] = publicTmp
+		}
+		if len(privateTmp.Child) > 0 {
+			privateMap[cpl.ChartPermissionName] = privateTmp
+		}
+	}
+	return
+}
+
+func copyChartPermissionList(src *models.ChartPermissionList) *models.ChartPermissionList {
+	tmp := &models.ChartPermissionList{
+		ChartPermissionId:     src.ChartPermissionId,
+		ChartPermissionName:   src.ChartPermissionName,
+		PermissionName:        src.PermissionName,
+		Sort:                  src.Sort,
+		Enabled:               src.Enabled,
+		CreatedTime:           src.CreatedTime,
+		LastUpdatedTime:       src.LastUpdatedTime,
+		TeleconferenceSort:    src.TeleconferenceSort,
+		Remark:                src.Remark,
+		ClassifyName:          src.ClassifyName,
+		ProductName:           src.ProductName,
+		ImageURL:              src.ImageURL,
+		ShowType:              src.ShowType,
+		IsOther:               src.IsOther,
+		IsReport:              src.IsReport,
+		CygxAuth:              src.CygxAuth,
+		PermissionType:        src.PermissionType,
+		YbImgUrl:              src.YbImgUrl,
+		ProductPermissionName: src.ProductPermissionName,
+		PriceDrivenState:      src.PriceDrivenState,
+		ImageUrlM:             src.ImageUrlM,
+		ParentId:              src.ParentId,
+		IsPublic:              src.IsPublic,
+		Child:                 src.Child,
+	}
+	return tmp
+}

+ 1 - 1
services/sys_department.go

@@ -65,7 +65,7 @@ func DeleteSysDepartmentById(sysDepartmentId, level int) (err error) {
 			curIds = append(curIds, strconv.Itoa(dep.SysDepartmentId))
 		}
 	}
-	err = models.DeleteSysDepartmentById(sysDepartmentIds, level)
+	err = models.DeleteSysDepartmentByIdV2(sysDepartmentIds, level)
 	return
 }
 

+ 8 - 0
services/user.go

@@ -0,0 +1,8 @@
+package services
+
+import "eta/eta_mini_crm/models"
+
+func SaveUser(user models.User) (err error) {
+
+	return
+}

+ 1 - 0
utils/constants.go

@@ -6,6 +6,7 @@ const (
 )
 
 const PageSize20 = 20
+const PageSize100 = 100
 const MaxDepartmentLevel = 3
 
 // 手机号,电子邮箱正则