Browse Source

Merge branch 'develop' into feature/项目管理

ZZH-wl 3 years ago
parent
commit
abb9de66b0

+ 40 - 29
opms_admin/app/handler/user.go

@@ -212,35 +212,46 @@ func (e *UserHandler) SetStatus(ctx context.Context, req *model.SysUserStatusReq
 	return nil
 }
 
-//// GetUserBelongDept 获取部门下所属用户
-//func (e *UserHandler) GetUserBelongDept(ctx context.Context, req *user_def.DeptIdReq, rsp *comm_def.CommonMsg) error {
-//	// 获取租户码
-//	tenant, err := micro_srv.GetTenant(ctx)
-//	if err != nil {
-//		return err
-//	}
-//	g.Log().Info("Received UserHandler.GetUserBelongDept request @ " + tenant)
-//	// 参数校验
-//	if req.DeptId == 0 {
-//		return NoParamsErr
-//	}
-//	service, err := user.NewService(tenant)
-//	if err != nil {
-//		g.Log().Error(err)
-//		return gerror.New("系统异常,请重新尝试")
-//	}
-//
-//	list, err := service.GetUserBelongDept(req.DeptId)
-//	_, err, code, msg := myerrors.CheckError(err)
-//	if err != nil {
-//		return err
-//	}
-//	rsp.Code = code
-//	rsp.Msg = msg
-//	rsp.Data = list
-//	return nil
-//}
-//
+// GetUserByDept 获取部门下所属用户
+func (e *UserHandler) GetUserByDept(ctx context.Context, req *user_def.DeptIdReq, rsp *comm_def.CommonMsg) error {
+	// 参数校验
+	if req.DeptId == 0 {
+		return NoParamsErr
+	}
+	userService, err := service.NewUserService(ctx)
+	if err != nil {
+		return gerror.New("系统异常,请重新尝试")
+	}
+
+	list, err := userService.GetUserByDept(req.DeptId)
+	_, err, rsp.Code, rsp.Msg = myerrors.CheckError(err)
+	if err != nil {
+		return err
+	}
+	rsp.Data = list
+	return nil
+}
+
+// GetUserByRole 获取角色关联用户
+func (e *UserHandler) GetUserByRole(ctx context.Context, req *model.SysUserRoleReq, rsp *comm_def.CommonMsg) error {
+	// 参数校验
+	if req.RoleId == 0 {
+		return NoParamsErr
+	}
+	userService, err := service.NewUserService(ctx)
+	if err != nil {
+		return gerror.New("系统异常,请重新尝试")
+	}
+
+	list, err := userService.GetUserByRole(req.RoleId)
+	_, err, rsp.Code, rsp.Msg = myerrors.CheckError(err)
+	if err != nil {
+		return err
+	}
+	rsp.Data = list
+	return nil
+}
+
 //// GetIdByUuid 根据uuid 获取用户id
 //func (e *UserHandler) GetIdByUuid(ctx context.Context, req *user_def.UuIdReq, rsp *comm_def.CommonMsg) error {
 //	// 获取租户码

+ 5 - 1
opms_admin/app/model/sys_user_role.go

@@ -11,4 +11,8 @@ import (
 // SysUserRole is the golang structure for table sys_user_role.
 type SysUserRole internal.SysUserRole
 
-// Fill with you ideas below.
+// Fill with you ideas below.
+
+type SysUserRoleReq struct {
+	RoleId int `json:"roleId"` // 角色ID
+}

+ 3 - 0
opms_admin/app/service/sys_menu.go

@@ -189,6 +189,9 @@ func (s menuService) GetUserRoleMenuTree(roles []int) ([]model.MenuTree, error)
 	err := s.Dao.Where(s.Dao.Columns.Status, "10").WhereIn(s.Dao.Columns.MenuType, g.Slice{"M", "C"}).
 		WhereIn(s.Dao.Columns.Id, dao.NewSysRoleMenuDao(s.Tenant).WhereIn(dao.SysRoleMenu.Columns.RoleId, roles).Fields(dao.SysRoleMenu.Columns.MenuId)).
 		Order("sort").Scan(&menuList)
+	if err != nil {
+		return nil, err
+	}
 
 	treeMap := make(map[int][]model.MenuTree, 0)
 	for _, v := range menuList {

+ 29 - 0
opms_admin/app/service/sys_user.go

@@ -108,6 +108,35 @@ func (s *userService) GetUserList(req *model.SysUserSearchReq) (total int, userL
 	return
 }
 
+// 获取部门下用户
+func (s userService) GetUserByDept(deptId int) (userList []*model.SysUser, err error) {
+	count, err := dao.NewSysDeptDao(s.Tenant).Where(dao.SysDept.Columns.Id, deptId).Where(dao.SysDept.Columns.Status, "10").Count()
+	if err != nil {
+		return nil, err
+	}
+	if count == 0 {
+		return nil, gerror.New("部门不存在或已停用")
+	}
+	err = s.Dao.Where(s.Dao.Columns.DeptId, deptId).FieldsEx(dao.SysUser.Columns.Password, dao.SysUser.Columns.UserSalt).Scan(&userList)
+	return userList, err
+}
+
+// 获取角色关联的用户
+func (s userService) GetUserByRole(roleId int) (userList []*model.SysUser, err error) {
+	count, err := dao.NewSysRoleDao(s.Tenant).Where(dao.SysRole.Columns.Id, roleId).Where(dao.SysRole.Columns.Status, "10").Count()
+	if err != nil {
+		return nil, err
+	}
+	if count == 0 {
+		return nil, gerror.New("角色不存在或已停用")
+	}
+	userList = make([]*model.SysUser, 0)
+	err = s.Dao.FieldsEx(dao.SysUser.Columns.Password, dao.SysUser.Columns.UserSalt).Where(s.Dao.Columns.Status, "10").
+		WhereIn(s.Dao.Columns.Id, dao.NewSysUserRoleDao(s.Tenant).Fields(dao.SysUserRole.Columns.UserId).WhereIn(dao.SysUserRole.Columns.RoleId, roleId)).
+		Scan(&userList)
+	return userList, err
+}
+
 // GetAdminUserByUsernamePassword 后台登陆验证
 func (s *userService) GetAdminUserByUsernamePassword(ctx context.Context, req *model.LoginParamsReq) (user *model.LoginUserRes, err error) {
 	user, err = s.GetUserByUsernamePassword(ctx, req)

+ 36 - 0
opms_parent/app/handler/plat/task.go

@@ -72,3 +72,39 @@ func (h *TaskHandler) ChangeStatus(ctx context.Context, req *model.ChangeStatusR
 	}
 	return nil
 }
+
+// 导出数据
+func (h *TaskHandler) Export(ctx context.Context, req *model.ExportReq, rsp *comm_def.CommonMsg) error {
+	taskService, err := server.NewTaskService(ctx)
+	if err != nil {
+		g.Log().Error(err)
+		return err
+	}
+	g.Log().Info("搜索值", req)
+	list, err := taskService.Export(req)
+	_, err, rsp.Code, rsp.Msg = myerrors.CheckError(err)
+	if err != nil {
+		g.Log().Error(err)
+		return err
+	}
+	rsp.Data = g.Map{"list": list}
+	return nil
+}
+
+// 统计各类型督办任务数量
+func (h *TaskHandler) StatisticsTaskNumber(ctx context.Context, req *model.SearchPlatTaskReq, rsp *comm_def.CommonMsg) error {
+	taskService, err := server.NewTaskService(ctx)
+	if err != nil {
+		g.Log().Error(err)
+		return err
+	}
+	g.Log().Info("搜索值", req)
+	result, err := taskService.Statistics(req)
+	_, err, rsp.Code, rsp.Msg = myerrors.CheckError(err)
+	if err != nil {
+		g.Log().Error(err)
+		return err
+	}
+	rsp.Data = g.Map{"list": result}
+	return nil
+}

+ 20 - 0
opms_parent/app/model/plat/plat_task.go

@@ -24,6 +24,8 @@ type SearchPlatTaskReq struct {
 	MainUserId  string `json:"mainUserId"`
 	TargetId  string `json:"targetId"`
 	TargetType  string `json:"targetType"`
+	MySelf      string `json:"mySelf"`
+	IsMain      string `json:"isMain"`
 	request.PageReq
 }
 
@@ -53,4 +55,22 @@ type ChangeStatusReq struct {
 	Type         string  `json:"type"  v:"required#类型不能为空"`
 	OldStatus   string `json:"oldStatus"`
 	NowStatus   string `json:"nowStatus"  v:"required#状态不能为空"`
+}
+
+// 数量统计返回接口
+type TaskNumberCount struct {
+	ToDoNumber      int         `orm:"ToDoNumber"        json:"toDoNumber"`       // 我的待办数量
+	CreateNumber    int         `orm:"CreateNumber"      json:"createNumber"`     // 我发起的数量
+	CompletedNumber int         `orm:"CompletedNumber"   json:"completedNumber"`  // 我处理的数量
+}
+
+// 查询
+type ExportReq struct {
+	SearchPlatTaskReq
+	Columns       []string     `json:"columns"`   // 导出列
+}
+
+// 督办任务导出接口
+type ExportContent struct {
+	Content      []byte         `json:"content"`       // 导出数据流
 }

+ 1 - 1
opms_parent/app/model/plat/plat_task_comment.go

@@ -23,7 +23,7 @@ type SearchPlatTaskCommentReq struct {
 
 // 添加数据
 type AddPlatTaskCommentReq struct {
-	TaskId      string      `orm:"task_id"      json:"taskId"     v:"required#关联任务不能为空"`    // 关联任务
+	TaskId      int      `orm:"task_id"      json:"taskId"     v:"required|min:1#关联任务不能为空|关联任务不能为空"`    // 关联任务
 	Content     string      `orm:"content"      json:"content"`                                     // 评论内容
 	Pid         int         `orm:"pid"          json:"pid"`                                         // 回复对象ID
 	Remark      string      `orm:"remark"       json:"remark"`                                      // 备注

+ 35 - 0
opms_parent/app/service/base.go

@@ -83,3 +83,38 @@ func SetUpdatedInfo(entry interface{}, id int, name string) {
 		}
 	}
 }
+
+// Div 数字转字母
+func Div(Num int)  string{
+	var(
+		Str string = ""
+		k int
+		temp []int   //保存转化后每一位数据的值,然后通过索引的方式匹配A-Z
+	)
+	//用来匹配的字符A-Z
+	Slice := []string{"","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O",
+		"P","Q","R","S","T","U","V","W","X","Y","Z"}
+
+	if Num >26 {  //数据大于26需要进行拆分
+		for {
+			k = Num % 26  //从个位开始拆分,如果求余为0,说明末尾为26,也就是Z,如果是转化为26进制数,则末尾是可以为0的,这里必须为A-Z中的一个
+			if k == 0 {
+				temp = append(temp, 26)
+				k = 26
+			} else {
+				temp = append(temp, k)
+			}
+			Num = (Num - k) / 26 //减去Num最后一位数的值,因为已经记录在temp中
+			if Num <= 26{   //小于等于26直接进行匹配,不需要进行数据拆分
+				temp = append(temp, Num)
+				break
+			}
+		}
+	}else{
+		return Slice[Num]
+	}
+	for _,value := range temp{
+		Str = Slice[value] + Str //因为数据切分后存储顺序是反的,所以Str要放在后面
+	}
+	return Str
+}

+ 1 - 1
opms_parent/app/service/cust/cust_customer.go

@@ -123,7 +123,7 @@ func (c *CustomerService) GetList(req *model.CustCustomerSearchReq) (total int,
 	g.Log().Info("serverS", req)
 	Model := c.Dao.M
 	Model = Model.Where(c.Dao.Columns.DeletedTime + " is null")
-	if req.TargetType != "" {
+	if req.TargetType == "" {
 		if !req.IsPublic {
 			Model = Model.Where(c.Dao.Columns.SalesId, c.CxtUser.Id).Where(c.Dao.Columns.IsPublic, noPublic)
 		} else {

+ 6 - 0
opms_parent/app/service/plat/plat_followup.go

@@ -6,6 +6,7 @@ import (
 	model "dashoo.cn/micro/app/model/plat"
 	"dashoo.cn/micro/app/service"
 	"database/sql"
+	"fmt"
 	"github.com/gogf/gf/errors/gerror"
 	"github.com/gogf/gf/frame/g"
 	"github.com/gogf/gf/os/gtime"
@@ -92,7 +93,12 @@ func (s *followupService) Create(req *model.AddPlatFollowupReq) (err error) {
 	// 保存附件信息
 	if len(files) > 0 {
 		_, err = s.Dao.DB.Insert(plat.PlatFollowupFile.Table, files)
+		if err != nil {
+			return
+		}
 	}
+	// 更新客户 最后跟进时间 字段
+	_, err = s.Dao.DB.Update("cust_customer", fmt.Sprintf("follow_up_date='%v'", req.FollowDate.Format("Y-m-d H:i:s")), fmt.Sprintf("id='%v' AND follow_up_date<'%v'", req.CustId, req.FollowDate.Format("Y-m-d H:i:s")))
 
 	return
 }

+ 128 - 7
opms_parent/app/service/plat/plat_task.go

@@ -1,12 +1,14 @@
 package plat
 
 import (
+	"bytes"
 	"context"
 	"dashoo.cn/micro/app/dao/plat"
 	model "dashoo.cn/micro/app/model/plat"
 	"dashoo.cn/micro/app/service"
 	"database/sql"
 	"fmt"
+	"github.com/360EntSecGroup-Skylar/excelize"
 	"github.com/gogf/gf/errors/gerror"
 	"github.com/gogf/gf/frame/g"
 	"github.com/gogf/gf/os/gtime"
@@ -53,6 +55,12 @@ func (s *taskService) GetList(req *model.SearchPlatTaskReq) (total int, TaskList
 	if req.TargetType != "" {
 		TaskModel = TaskModel.Where("target_type", req.TargetType)
 	}
+	if req.MySelf == "1" {
+		TaskModel = TaskModel.Where("created_by", s.GetCxtUserId())
+	}
+	if req.IsMain == "1" {
+		TaskModel = TaskModel.Where("main_user_id", s.GetCxtUserId())
+	}
 	total, err = TaskModel.Count()
 	if err != nil {
 		g.Log().Error(err)
@@ -64,6 +72,121 @@ func (s *taskService) GetList(req *model.SearchPlatTaskReq) (total int, TaskList
 	return
 }
 
+// 导出数据
+func (s *taskService) Export(req *model.ExportReq) (content *model.ExportContent, err error) {
+	var con model.ExportContent
+	// 获取数据
+	total, list, err := s.GetList(&req.SearchPlatTaskReq)
+	if err != nil {
+		return nil, err
+	}
+	//rsp.List
+	f := excelize.NewFile()
+	// Create a new sheet.
+	index := f.NewSheet("Sheet1")
+	for index, item := range req.Columns {
+		sheetPosition := service.Div(index + 1) + "1"
+		f.SetCellValue("Sheet1", sheetPosition, item)
+	}
+
+	if total > 0 {
+		// 构造用户和类型填充数据
+		userMap := make(map[int]string, 0)
+		typeMap := make(map[string]string, 0)
+		users, err := s.Dao.DB.Model("sys_user").FindAll()
+		if err != nil {
+			return nil, err
+		}
+		types, err := s.Dao.DB.Model("sys_dict_data").Where("dict_type='TaskType'").FindAll()
+		if err != nil {
+			return nil, err
+		}
+		for _, item := range users {
+			userMap[item["id"].Int()] = item["user_name"].String()
+		}
+		for _, item := range types {
+			typeMap[item["dict_value"].String()] = item["dict_label"].String()
+		}
+		// 构造excel数据
+		for lineNum, item := range list {
+			for index, value := range req.Columns {
+				if value =="督办标题"{
+					f.SetCellValue("Sheet1", service.Div(index + 1) + strconv.Itoa(lineNum + 2), item.TaskTitle)
+				}
+				if value =="督办类型"{
+					f.SetCellValue("Sheet1", service.Div(index + 1) + strconv.Itoa(lineNum + 2), typeMap[item.TaskType])
+				}
+				if value =="状态"{
+					data := ""
+					if item.TaskStatus == "10" {
+						data = "进行中"
+					} else if item.TaskStatus == "20" {
+						data = "关闭"
+					}
+					f.SetCellValue("Sheet1", service.Div(index + 1) + strconv.Itoa(lineNum + 2), data)
+				}
+				if value =="超期"{
+					data := ""
+					if item.TaskStatus == "10" {
+						data = "否"
+					} else if item.TaskStatus == "20" {
+						data = "是"
+					}
+					f.SetCellValue("Sheet1", service.Div(index + 1) + strconv.Itoa(lineNum + 2), data)
+				}
+				if value =="督办说明"{
+					f.SetCellValue("Sheet1", service.Div(index + 1) + strconv.Itoa(lineNum + 2), item.TaskDesc)
+				}
+				if value =="关联对象"{
+					f.SetCellValue("Sheet1", service.Div(index + 1) + strconv.Itoa(lineNum + 2), item.TargetName)
+				}
+				if value =="负责人"{
+					f.SetCellValue("Sheet1", service.Div(index + 1) + strconv.Itoa(lineNum + 2), userMap[item.MainUserId])
+				}
+				if value =="督办人"{
+					f.SetCellValue("Sheet1", service.Div(index + 1) + strconv.Itoa(lineNum + 2), userMap[item.SupervisorUserId])
+				}
+				if value =="开始时间"{
+					f.SetCellValue("Sheet1", service.Div(index + 1) + strconv.Itoa(lineNum + 2), item.TaskStartDate.Format("Y-m-d H:i:s"))
+				}
+				if value =="结束时间"{
+					f.SetCellValue("Sheet1", service.Div(index + 1) + strconv.Itoa(lineNum + 2), item.TaskEndDate.Format("Y-m-d H:i:s"))
+				}
+				if value =="创建时间"{
+					f.SetCellValue("Sheet1", service.Div(index + 1) + strconv.Itoa(lineNum + 2), item.CreatedTime.Format("Y-m-d H:i:s"))
+				}
+			}
+		}
+	}
+
+	f.SetActiveSheet(index)
+
+	var buffer *bytes.Buffer
+	buffer, _ = f.WriteToBuffer()
+	con.Content = buffer.Bytes()
+
+	return &con, err
+}
+
+// 统计
+func (s *taskService) Statistics(req *model.SearchPlatTaskReq) (*model.TaskNumberCount, error) {
+	var result model.TaskNumberCount
+	// 统计数量
+	err := s.Dao.M.Fields(fmt.Sprintf("SUM(main_user_id='%v' AND task_status='10') ToDoNumber, SUM(main_user_id='%v' AND task_status='20') CompletedNumber, SUM(created_by='%v') CreateNumber", s.GetCxtUserId(), s.GetCxtUserId(), s.GetCxtUserId())).Scan(&result)
+	if err != nil {
+		if err == sql.ErrNoRows {
+			result.CompletedNumber = 0
+			result.CreateNumber = 0
+			result.ToDoNumber = 0
+			return &result, nil
+		} else {
+			return nil, err
+		}
+	}
+
+	return &result, nil
+}
+
 // 添加信息
 func (s *taskService) Create(req *model.AddPlatTaskReq) (err error) {
 	platTask := new(model.PlatTask)
@@ -85,7 +208,7 @@ func (s *taskService) Create(req *model.AddPlatTaskReq) (err error) {
 	}
 	// 流程日志
 	id, _ := res.LastInsertId()
-	err = CreateTaskLog(s, nil, int(id), s.GetCxtUserId(), s.GetCxtUserName(), "创建任务", "创建任务成功", "")
+	err = CreateTaskLog(s, nil, int(id), s.GetCxtUserId(), s.GetCxtUserName(), "创建督办", "创建督办成功", "")
 
 	return
 }
@@ -99,24 +222,22 @@ func (s *taskService) ChangeStatus(req *model.ChangeStatusReq) (err error) {
 	// 类型合规判断
 	if req.Type == "TaskStatus" {
 		data = fmt.Sprintf("task_status='%v'", req.NowStatus)
-		nodeName = "任务状态修改"
+		nodeName = "状态修改"
 		if req.NowStatus == "20" {
-			desc = "任务关闭"
-		} else if req.NowStatus == "30" {
-			desc = "任务完成"
+			desc = "关闭"
 			data += fmt.Sprintf(",task_end_date='%v'", gtime.Now().Format("Y-m-d H:i:s"))
 		}
 	} else if req.Type == "IsOverdue" {
 		nodeName = "超期状态修改"
 		if req.NowStatus == "20" {
-			desc = "任务超期"
+			desc = "超期"
 		}
 		data = fmt.Sprintf("is_overdue='%v'", req.NowStatus)
 	} else {
 		return fmt.Errorf("类型不匹配,请仔细检查")
 	}
 	// 读取现有数据
-	task, err := s.Dao.FindOne(where)
+	task, err := s.Dao.Where(where).FindOne()
 	if err != nil {
 		return err
 	}

+ 2 - 2
opms_parent/app/service/plat/plat_task_progress.go

@@ -39,7 +39,7 @@ func (s *taskProgressService) GetList(req *model.SearchPlatTaskProgressReq) (tot
 		return
 	}
 
-	err = taskProgressModel.Order("created_time DESC").Scan(&taskProgressList)
+	err = taskProgressModel.Order("created_time ASC").Scan(&taskProgressList)
 	return
 }
 
@@ -60,7 +60,7 @@ func (s *taskProgressService) Create(req *model.AddPlatTaskProgressReq) (err err
 	}
 
 	// 流程日志
-	err = CreateTaskLog(nil, s, req.TaskId, s.GetCxtUserId(), s.GetCxtUserName(), "添加进展", "任务进展更新", "")
+	err = CreateTaskLog(nil, s, req.TaskId, s.GetCxtUserId(), s.GetCxtUserName(), "添加进展", "督办进展更新", "")
 
 	return
 }

+ 1 - 0
opms_parent/go.mod

@@ -5,6 +5,7 @@ go 1.16
 require (
 	dashoo.cn/common_definition v0.0.0
 	dashoo.cn/opms_libary v0.0.0
+	github.com/360EntSecGroup-Skylar/excelize v1.4.1
 	github.com/go-redis/redis/v8 v8.11.5 // indirect
 	github.com/gogf/gf v1.16.4
 	github.com/smallnest/rpcx v1.6.10