ソースを参照

Merge branch 'featrue/tongji' into develop

ZZH-wl 3 年 前
コミット
29553c42c8

+ 9 - 4
opms_admin/app/handler/user.go

@@ -5,7 +5,6 @@ import (
 	"dashoo.cn/opms_libary/myerrors"
 	"strings"
 
-	"dashoo.cn/common_definition/admin/user_def"
 	"github.com/gogf/gf/util/gvalid"
 
 	"dashoo.cn/micro/app/model"
@@ -213,7 +212,7 @@ func (h *RoleHandler) GetDataScope(ctx context.Context, nullParams interface{},
 }
 
 // GetUserByDept 获取部门下所属用户
-func (h *UserHandler) GetUserByDept(ctx context.Context, req *user_def.DeptIdReq, rsp *comm_def.CommonMsg) error {
+func (h *UserHandler) GetUserByDept(ctx context.Context, req *model.DeptIdReq, rsp *comm_def.CommonMsg) error {
 	// 参数校验
 	if req.DeptId == 0 {
 		return myerrors.TipsError("请求参数不存在。")
@@ -222,8 +221,14 @@ func (h *UserHandler) GetUserByDept(ctx context.Context, req *user_def.DeptIdReq
 	if err != nil {
 		return err
 	}
-
-	list, err := userService.GetUserByDept(req.DeptId)
+	var list interface{}
+	if req.Include {
+		req := &model.SysUserSearchReq{DeptId: req.DeptId}
+		req.PageSize = 1000
+		_, list, err = userService.GetUsersByDeptEx(req)
+	} else {
+		list, err = userService.GetUserByDept(req.DeptId)
+	}
 	if err != nil {
 		return err
 	}

+ 5 - 0
opms_admin/app/model/sys_user.go

@@ -132,3 +132,8 @@ type SysUserNickNameRes struct {
 	Id           int    `json:"id" orm:"id"`
 	UserNickname string `json:"userNickname" orm:"nick_name"`
 }
+
+type DeptIdReq struct {
+	DeptId  int  `json:"dept_id,omitempty"`
+	Include bool `json:"include,omitempty"`
+}

+ 2 - 2
opms_admin/app/service/sys_send_message.go

@@ -26,7 +26,7 @@ func (c *contextService) SendUserEmailMsg(userId, msgTitle, msgContent string) e
 	m.SetHeader("From", g.Config().GetString("email.From"))
 	m.SetHeader("To", userInfo.Email)
 	m.SetHeader("Subject", msgTitle)
-	m.SetBody("text/plain", msgContent)
+	m.SetBody("text/html", msgContent)
 
 	err = email.Client.DialAndSend(m)
 	if err != nil {
@@ -52,7 +52,7 @@ func (c *contextService) BatchSendUserEmailMsg(userIds []string, msgTitle, msgCo
 		m.SetHeader("From", g.Config().GetString("email.From"))
 		m.SetHeader("To", userInfo.Email)
 		m.SetHeader("Subject", msgTitle)
-		m.SetBody("text/plain", msgContent)
+		m.SetBody("text/html", msgContent)
 
 		err = email.Client.DialAndSend(m)
 		if err != nil {

+ 8 - 11
opms_admin/app/service/sys_user.go

@@ -165,7 +165,7 @@ func (s *UserService) GetUserByDept(deptId int) (userList []*model.SysUser, err
 
 // GetUsersByDeptEx 获取部门及子部门下的用户
 func (s *UserService) GetUsersByDeptEx(req *model.SysUserSearchReq) (total int, userList []*model.SysUser, err error) {
-	depts, err := s.Dao.DB.Model("sys_dept").Fields("id").Wheref("find_in_set( %d , ancestors )", req.DeptId).FindAll()
+	depts, err := dao.NewSysDeptDao(s.Tenant).Fields(dao.SysDept.C.Id).Wheref("find_in_set( %d , ancestors )", req.DeptId).Array()
 	if err != nil {
 		if err == sql.ErrNoRows {
 			return 0, nil, gerror.New("无部门数据")
@@ -175,28 +175,25 @@ func (s *UserService) GetUsersByDeptEx(req *model.SysUserSearchReq) (total int,
 	if len(depts) == 0 {
 		return 0, nil, gerror.New("无部门数据")
 	}
-	var depIds []int
-	for _, dep := range depts {
-		depIds = append(depIds, dep["id"].Int())
-	}
+	depIds := gconv.Ints(depts)
 
 	userModel := s.Dao.M
-	if req.Phone != "" {
-		userModel = userModel.Where("sys_user.phone", "%"+req.Phone+"%")
-	}
 	if req.KeyWords != "" {
 		keyWords := "%" + req.KeyWords + "%"
-		userModel = userModel.Where("sys_user.user_name like ? or  sys_user.nick_name like ?", keyWords, keyWords)
+		userModel = userModel.Where("user_name like ? or nick_name like ?", keyWords, keyWords)
+	}
+	if req.Phone != "" {
+		userModel = userModel.WhereLike(s.Dao.C.Phone, "%"+req.Phone+"%")
 	}
 	if len(depts) > 0 {
-		userModel = userModel.Where("dept_id IN (?)", depIds)
+		userModel = userModel.WhereIn(s.Dao.C.DeptId, depIds)
 	}
 	total, err = userModel.Count()
 	if err != nil {
 		return 0, nil, err
 	}
 
-	err = userModel.Page(req.GetPage()).Order("Id ASC").FieldsEx(s.Dao.C.Password, s.Dao.C.UserSalt).Scan(&userList)
+	err = userModel.Page(req.GetPage()).OrderAsc(s.Dao.C.Id).FieldsEx(s.Dao.C.Password, s.Dao.C.UserSalt).Scan(&userList)
 	return total, userList, err
 }
 

+ 20 - 0
opms_parent/app/handler/home/home.go

@@ -5,6 +5,7 @@ import (
 	"dashoo.cn/common_definition/comm_def"
 	model "dashoo.cn/micro/app/model/home"
 	service "dashoo.cn/micro/app/service/home"
+	"github.com/gogf/gf/util/gvalid"
 )
 
 type HomeHandler struct{}
@@ -89,3 +90,22 @@ func (h *HomeHandler) GetWechatHomeNumReportData(ctx context.Context, req *model
 	rsp.Data = resp
 	return nil
 }
+
+// GetSalesEngineerFollowUpNum 统计销售工程师跟进记录频次
+func (h *HomeHandler) GetSalesEngineerFollowUpNum(ctx context.Context, req *model.SearchFollowUpReportData, rsp *comm_def.CommonMsg) error {
+	svc, err := service.NewHomeService(ctx)
+	if err != nil {
+		return err
+	}
+	if err := gvalid.CheckStruct(ctx, req, nil); err != nil {
+		return err
+	}
+	resp, err := svc.QuerySalesEngineerFollowUpNum(req.Month)
+	if err != nil {
+		return err
+	}
+	rsp.Code = 200
+	rsp.Msg = "查询成功"
+	rsp.Data = resp
+	return nil
+}

+ 6 - 0
opms_parent/app/model/home/home.go

@@ -1,5 +1,7 @@
 package home
 
+import "github.com/gogf/gf/os/gtime"
+
 type SetUpHomeConfig struct {
 	ModuleCode       string              `json:"module_code"`
 	NumReportConfig  []*NumReportConfig  `json:"num_report_config"`
@@ -63,3 +65,7 @@ type SearchWechatNumReportDataRes struct {
 	NewBusiness int `json:"newBusiness"` // 新增项目数量
 	NewTask     int `json:"newTask"`     // 未处理督办事项
 }
+
+type SearchFollowUpReportData struct {
+	Month *gtime.Time `json:"month" v:"required#月份不能为空"`
+}

+ 53 - 1
opms_parent/app/service/base.go

@@ -4,7 +4,9 @@ import (
 	"context"
 	"dashoo.cn/opms_libary/myerrors"
 	"fmt"
+	"github.com/gogf/gf/container/gmap"
 	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/util/gconv"
 	"github.com/smallnest/rpcx/share"
 	"log"
 	"reflect"
@@ -144,7 +146,7 @@ type GetDictReq struct {
 	DefaultValue string `p:"defaultValue"`
 }
 
-func GetDictDataByType(ctx context.Context, typ string) (map[string]string, error) {
+func baseGetDictDataByType(ctx context.Context, typ string) ([]interface{}, error) {
 	srv := micro_srv.InitMicroSrvClient("Dict", "micro_srv.auth")
 	defer srv.Close()
 	resp := &comm_def.CommonMsg{}
@@ -157,6 +159,13 @@ func GetDictDataByType(ctx context.Context, typ string) (map[string]string, erro
 	fmt.Println(resp.Data)
 	data := resp.Data.(map[string]interface{})["Values"].([]interface{})
 	fmt.Println(data)
+	return data, nil
+}
+func GetDictDataByType(ctx context.Context, typ string) (map[string]string, error) {
+	data, err := baseGetDictDataByType(ctx, typ)
+	if err != nil {
+		return nil, err
+	}
 	res := map[string]string{}
 	for _, i := range data {
 		info := i.(map[string]interface{})
@@ -165,6 +174,20 @@ func GetDictDataByType(ctx context.Context, typ string) (map[string]string, erro
 	return res, nil
 }
 
+// 有序
+func GetDictDataTreeByType(ctx context.Context, typ string) (*gmap.ListMap, error) {
+	data, err := baseGetDictDataByType(ctx, typ)
+	if err != nil {
+		return nil, err
+	}
+	res := gmap.NewListMap(true)
+	for _, i := range data {
+		info := i.(map[string]interface{})
+		res.Set(info["DictValue"], info["DictLabel"])
+	}
+	return res, nil
+}
+
 func StringSlicecontains(s []string, ele string) bool {
 	for _, i := range s {
 		if i == ele {
@@ -174,6 +197,7 @@ func StringSlicecontains(s []string, ele string) bool {
 	return false
 }
 
+// CreateSystemMessage 创建系统消息
 func CreateSystemMessage(msg g.MapStrStr) error {
 	srv := micro_srv.InitMicroSrvClient("SystemMessage", "micro_srv.auth")
 	defer srv.Close()
@@ -188,3 +212,31 @@ func CreateSystemMessage(msg g.MapStrStr) error {
 	fmt.Println(resp.Data)
 	return nil
 }
+
+type DeptIdReq struct {
+	DeptId  int  `json:"dept_id,omitempty"`
+	Include bool `json:"include,omitempty"`
+}
+
+// GetUsersByDept 根据部门获取用户获取系统
+func GetUsersByDept(ctx context.Context, req *DeptIdReq) (map[string]int, error) {
+	srv := micro_srv.InitMicroSrvClient("User", "micro_srv.auth")
+	defer srv.Close()
+	resp := &comm_def.CommonMsg{}
+	err := srv.Call(ctx, "GetUserByDept", req, resp)
+	if err != nil {
+		return nil, myerrors.MicroCallError("获取部门下用户失败")
+	}
+	if resp.Data == nil {
+		return nil, myerrors.TipsError("部门不存在")
+	}
+	fmt.Println(resp.Data)
+	data := resp.Data.([]interface{})
+	fmt.Println(data)
+	res := map[string]int{}
+	for _, i := range data {
+		info := i.(map[string]interface{})
+		res[info["NickName"].(string)] = gconv.Int(info["Id"])
+	}
+	return res, nil
+}

+ 3 - 0
opms_parent/app/service/cust/cust_customer.go

@@ -149,6 +149,9 @@ func (s *CustomerService) customerCode(province, industry string) (string, error
 }
 
 func (s *CustomerService) customerProvinceCode(province string) string {
+	if province == "重庆市" {
+		return "CQ"
+	}
 	province = strings.Trim(province, "市")
 	province = strings.Trim(province, "省")
 	province = strings.Trim(province, "特别行政区")

+ 95 - 0
opms_parent/app/service/home/report.go

@@ -3,6 +3,7 @@ package home
 import (
 	"context"
 	contDao "dashoo.cn/micro/app/dao/contract"
+	platDao "dashoo.cn/micro/app/dao/plat"
 	projDao "dashoo.cn/micro/app/dao/proj"
 	"dashoo.cn/micro/app/model/home"
 	"dashoo.cn/micro/app/model/plat"
@@ -15,6 +16,7 @@ import (
 	"database/sql"
 	"fmt"
 	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
 	"github.com/gogf/gf/os/gtime"
 	"github.com/gogf/gf/util/gconv"
 	"math"
@@ -719,3 +721,96 @@ func arrayReversal(result [][]float64) [][]float64 {
 	}
 	return data
 }
+
+type FollowUpCount struct {
+	CreatedBy   int    `json:"createdBy"`
+	CreatedName string `json:"createdName"`
+	FollowType  string `json:"followType"`
+	Count       int    `json:"count"`
+}
+
+// QuerySalesEngineerFollowUpNum 查询销售工程师跟进记录频次
+func (s *HomeService) QuerySalesEngineerFollowUpNum(day *gtime.Time) (interface{}, error) {
+	weekData := GetMonthWeekDay(day)
+	followUpDao := platDao.NewPlatFollowupDao(s.Tenant)
+	followUpMonthData := make([][]FollowUpCount, 0)
+	for _, item := range weekData {
+		data := make([]FollowUpCount, 0)
+		err := followUpDao.Fields("created_by, created_name, follow_type, COUNT(id) as count").
+			WhereGTE(followUpDao.C.FollowDate, item[0]).WhereLTE(followUpDao.C.FollowDate, item[1]).
+			Group("created_by, follow_type").Order("created_by ASC, follow_type ASC").Scan(&data)
+		if err != nil {
+			return nil, err
+		}
+		followUpMonthData = append(followUpMonthData, data)
+	}
+	// 409022238
+	userList, err := service.GetUsersByDept(s.Ctx, &service.DeptIdReq{DeptId: 409022238, Include: true})
+	if err != nil {
+		return nil, err
+	}
+	followMethod, err := service.GetDictDataTreeByType(s.Ctx, "plat_follow_method")
+	if err != nil {
+		return nil, err
+	}
+	header, data := make([]g.Map, 0), make([]g.Map, 0)
+	header = append(header, g.Map{"prop": "userName", "label": "销售工程师"})
+	header = append(header, g.Map{"prop": "followType", "label": "跟进方式"})
+	for k, _ := range weekData {
+		header = append(header, g.Map{"prop": fmt.Sprintf("W%d", k+1), "label": fmt.Sprintf("第%d周", k+1)})
+	}
+	header = append(header, g.Map{"prop": "monthTotal", "label": "月度合计"})
+
+	for userName, id := range userList {
+		for _, key := range followMethod.Keys() {
+			data = append(data, followUpReportDataConvert(g.Map{
+				"userName":      userName,
+				"userId":        id,
+				"followTypeKey": key,
+				"followType":    followMethod.Get(key),
+			}, followUpMonthData))
+		}
+	}
+	return g.Map{"header": header, "data": data}, nil
+}
+
+func followUpReportDataConvert(data g.Map, followUpMonthData [][]FollowUpCount) g.Map {
+	var total int
+	for k, items := range followUpMonthData {
+		data[fmt.Sprintf("W%d", k+1)] = 0
+		for _, item := range items {
+			if item.CreatedBy == data["userId"] && item.FollowType == data["followTypeKey"] {
+				data[fmt.Sprintf("W%d", k+1)] = item.Count
+				total += item.Count
+				break
+			}
+		}
+	}
+	data["monthTotal"] = total
+	return data
+}
+
+// GetMonthWeekDay 获取月份下的每周日期
+func GetMonthWeekDay(day *gtime.Time) [][]*gtime.Time {
+	fmt.Println(day)
+	result := make([][]*gtime.Time, 0)
+	monthStart, monthEnd := day.StartOfMonth(), day.EndOfMonth()
+	startWeekS, startWeekE := monthStart.StartOfWeek(), monthStart.EndOfWeek()
+	endWeekS, endWeekE := monthEnd.StartOfWeek(), monthEnd.EndOfWeek()
+	// 计算开始
+	if startWeekS.Before(monthStart) || startWeekS.Equal(monthStart) {
+		result = append(result, []*gtime.Time{monthStart, startWeekE})
+	}
+	// 计算整周
+	sub := int(endWeekS.Sub(startWeekE).Hours() / 24 / 7)
+	forDay := startWeekE.AddDate(0, 0, 1)
+	for i := 1; i <= sub; i++ {
+		result = append(result, []*gtime.Time{forDay.StartOfDay(), forDay.EndOfWeek()})
+		forDay = forDay.AddDate(0, 0, 7)
+	}
+	// 计算结束
+	if endWeekE.After(monthEnd) || endWeekE.Equal(monthEnd) {
+		result = append(result, []*gtime.Time{endWeekS, monthEnd})
+	}
+	return result
+}

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

@@ -19,7 +19,6 @@ import (
 
 type followupService struct {
 	*service.ContextService
-
 	Dao *plat.PlatFollowupDao
 }
 

+ 32 - 3
opms_parent/app/service/plat/plat_followup_comment.go

@@ -2,8 +2,9 @@ package plat
 
 import (
 	"context"
-
 	"dashoo.cn/opms_libary/myerrors"
+	"database/sql"
+	"fmt"
 	"github.com/gogf/gf/frame/g"
 	"github.com/gogf/gf/util/gconv"
 
@@ -14,8 +15,8 @@ import (
 
 type followupCommentService struct {
 	*service.ContextService
-
-	Dao *plat.PlatFollowupCommentDao
+	Dao         *plat.PlatFollowupCommentDao
+	FollowupDao *plat.PlatFollowupDao
 }
 
 func NewFollowupCommentService(ctx context.Context) (svc *followupCommentService, err error) {
@@ -24,6 +25,7 @@ func NewFollowupCommentService(ctx context.Context) (svc *followupCommentService
 		return nil, err
 	}
 	svc.Dao = plat.NewPlatFollowupCommentDao(svc.Tenant)
+	svc.FollowupDao = plat.NewPlatFollowupDao(svc.Tenant)
 	return svc, nil
 }
 
@@ -50,6 +52,11 @@ func (s *followupCommentService) GetList(req *model.SearchPlatFollowupCommentReq
 
 // 添加信息
 func (s *followupCommentService) Create(req *model.AddPlatFollowupCommentReq) (err error) {
+	followup, err := s.FollowupDao.WherePri(req.FollowId).One()
+	if err != nil {
+		return err
+	}
+
 	platFollowupComment := new(model.PlatFollowupComment)
 	if err = gconv.Struct(req, platFollowupComment); err != nil {
 		return
@@ -63,5 +70,27 @@ func (s *followupCommentService) Create(req *model.AddPlatFollowupCommentReq) (e
 		return
 	}
 
+	// 从配置中获取消息提醒设置
+	config, err := g.DB(s.Tenant).Model("sys_config").Where("config_key = 'SalesAssociate'").One()
+	if err != nil && err != sql.ErrNoRows {
+		g.Log().Error(err)
+		return
+	}
+	// 销售助理用户Id
+	salesAssociate := config["config_value"].String()
+	recvUserIds := salesAssociate + "," + gconv.String(followup.CreatedBy)
+
+	msg := g.MapStrStr{
+		"msgTitle":    "跟进记录评论提醒",
+		"msgContent":  fmt.Sprintf("<p>%v %v 评论:%v</p>", followup.TargetName, platFollowupComment.CreatedName, platFollowupComment.Content),
+		"msgType":     "20",
+		"recvUserIds": recvUserIds,
+		"msgStatus":   "10",
+		"sendType":    "10",
+	}
+	if err := service.CreateSystemMessage(msg); err != nil {
+		g.Log().Error("消息提醒异常:", err)
+	}
+
 	return
 }

+ 2 - 2
opms_parent/app/service/proj/business.go

@@ -837,7 +837,7 @@ func (p *businessService) BusinessUpgradeNotify(flow *workflowModel.PlatWorkflow
 		data = gconv.Map(updateData)
 		data[p.Dao.C.ApproStatus] = ApprovalOK
 		remarkMap := gconv.Map(dynamics.OpnContent)
-		remark = gconv.String(g.Map{"nboType": remarkMap["remarkMap"], "origNboType": remarkMap["origNboType"]})
+		remark = gconv.String(g.Map{"nboType": remarkMap["nboType"], "origNboType": remarkMap["origNboType"]})
 	}
 
 	// 项目修改
@@ -1006,7 +1006,7 @@ func (p *businessService) BusinessDowngradeNotify(flow *workflowModel.PlatWorkfl
 		data = gconv.Map(updateData)
 		data[p.Dao.C.ApproStatus] = ApprovalOK
 		remarkMap := gconv.Map(dynamics.OpnContent)
-		remark = gconv.String(g.Map{"nboType": remarkMap["remarkMap"], "origNboType": remarkMap["origNboType"]})
+		remark = gconv.String(g.Map{"nboType": remarkMap["nboType"], "origNboType": remarkMap["origNboType"]})
 	}
 
 	// 项目修改