Pārlūkot izejas kodu

feature(bug、优化):
1、合并客户、编辑客户-客户来源问题
2、打卡记录
3、项目升级添加大数参数文件
4、经销商权限问题

ZZH-wl 2 gadi atpakaļ
vecāks
revīzija
22a255e63d

+ 5 - 5
opms_libary/micro_srv/micro_srv.go

@@ -69,11 +69,6 @@ func CreateAndInitService(basePath string) *server.Server {
 
 	s := server.NewServer()
 
-	if fileAddr != "" {
-		p := server.NewStreamService(fileAddr, streamHandler, nil, 1000)
-		s.EnableStreamService(share.StreamServiceName, p)
-	}
-
 	advertiseAddr := srvAddr
 	if g.Config().GetBool("setting.need-advertise-addr") {
 		advertiseAddr = g.Config().GetString("setting.advertise-addr")
@@ -89,6 +84,11 @@ func CreateAndInitService(basePath string) *server.Server {
 		addConsulRegistryPlugin(s, basePath, advertiseAddr, etcdAddr)
 	}
 
+	if fileAddr != "" {
+		p := server.NewStreamService(fileAddr, streamHandler, nil, 1000)
+		s.EnableStreamService(share.StreamServiceName, p)
+	}
+
 	return s
 }
 

+ 15 - 0
opms_parent/app/handler/plat/punch_records.go

@@ -28,6 +28,21 @@ func (h *PunchRecordsHandler) GetList(ctx context.Context, req *platModel.Search
 	return nil
 }
 
+// GetListByDay 打卡记录时间线列表
+// Swagger:PunchRecords 打卡记录 打卡记录时间线列表
+func (h *PunchRecordsHandler) GetListByDay(ctx context.Context, req *platModel.SearchPunchRecordsReq, rsp *comm_def.CommonMsg) error {
+	punchService, err := platService.NewPunchRecordsService(ctx)
+	if err != nil {
+		return err
+	}
+	total, list, err := punchService.GetListByDay(req)
+	if err != nil {
+		return err
+	}
+	rsp.Data = g.Map{"list": list, "total": total}
+	return nil
+}
+
 // Create 添加打卡记录
 // Swagger:PunchRecords 打卡记录 打卡
 func (h *PunchRecordsHandler) Create(ctx context.Context, req *platModel.AddPunchRecordsReq, rsp *comm_def.CommonMsg) error {

+ 20 - 2
opms_parent/app/handler/proj/business.go

@@ -2,8 +2,11 @@ package base
 
 import (
 	"context"
+	"dashoo.cn/opms_libary/multipart"
 	"dashoo.cn/opms_libary/myerrors"
+	"fmt"
 	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/util/gconv"
 	"github.com/gogf/gf/util/gvalid"
 
 	"dashoo.cn/common_definition/comm_def"
@@ -155,7 +158,22 @@ func (p *BusinessHandler) DeleteByIds(ctx context.Context, req *comm_def.IdsReq,
 
 // BusinessUpgrade 项目升级
 // Swagger:Business 项目 项目升级
-func (p *BusinessHandler) BusinessUpgrade(ctx context.Context, req *projModel.BusinessUpgradeReq, rsp *comm_def.CommonMsg) error {
+func (p *BusinessHandler) BusinessUpgrade(ctx context.Context, args *multipart.MultipartFile, rsp *comm_def.CommonMsg) error {
+	req := new(projModel.BusinessUpgradeReq)
+	if err := gconv.Struct(args.Meta, req); err != nil {
+		return err
+	}
+	if req.NboType == projSrv.StatusA && req.IsAdoptDashoo == "10" {
+		if args.FileName == "" {
+			return fmt.Errorf("文件名称不能为空")
+		}
+		if args.File == nil {
+			return fmt.Errorf("文件不能为空")
+		}
+		if args.File.Name() == "" {
+			return fmt.Errorf("文件路径不能为空")
+		}
+	}
 	// 参数校验
 	if err := gvalid.CheckStruct(ctx, req, nil); err != nil {
 		return err
@@ -164,7 +182,7 @@ func (p *BusinessHandler) BusinessUpgrade(ctx context.Context, req *projModel.Bu
 	if err != nil {
 		return err
 	}
-	err = businessService.BusinessUpgrade(req)
+	err = businessService.BusinessUpgrade(req, args)
 	if err != nil {
 		return err
 	}

+ 20 - 20
opms_parent/app/model/cust/cust_customer.go

@@ -46,25 +46,25 @@ type CustExport struct {
 
 // CustomerAddSeq 单表添加客户信息表
 type CustomerAddSeq struct {
-	CustName       string      `p:"custName"        json:"custName"      v:"required#客户名称不能为空"` // 客户名称
-	AbbrName       string      `p:"abbrName"        json:"abbrName"   `                         // 助计名
-	CustLocation   string      `p:"custLocation"    json:"custLocation"    `                    // 所在地区
-	CustAddress    string      `p:"custAddress"     json:"custAddress"   `                      // 详细地址
-	CustProvinceId int         `json:"custProvinceId"`                                          // 所在省ID
-	CustProvince   string      `json:"custProvince"`                                            // 所在省
-	CustCityId     int         `json:"custCityId"`                                              // 所在市ID
-	CustCity       string      `json:"custCity"`                                                // 所在市
-	CustRegionId   int         `json:"custRegionId"`                                            // 所在区县ID
-	CustRegion     string      `json:"custRegion"`                                              // 所在区县
-	FollowUpDate   *gtime.Time `p:"followUpDate"    json:"followUpDate"   `                     //跟进时间
-	CustIndustry   string      `p:"custIndustry"    json:"custIndustry"  v:"required#客户行业不能为空"` //客户行业
-	CustLevel      string      `p:"custLevel"       json:"custLevel"`                           //客户级别
-	CustSource     string      `p:"custSource"      json:"source"        v:"required#客户来源不能为空"` //客户来源
-	CustDistCode   int         `p:"custDistCode"    json:"custDistCode"  v:"required#省份不能为空" `  // 省份Id
-	Remark         string      `p:"remark"          json:"remark"`                              //备注
-	SalesName      string      `p:"salesName"       json:"salesName"   `                        // 销售名称
-	SalesId        int         `p:"salesId"         json:"salesId"   `                          // 销售id
-	InvoiceHeader  string      `json:"invoiceHeader"`                                           // 开票抬头
+	CustName       string      `p:"custName"        json:"custName"      v:"required#客户名称不能为空"`     // 客户名称
+	AbbrName       string      `p:"abbrName"        json:"abbrName"   `                             // 助计名
+	CustLocation   string      `p:"custLocation"    json:"custLocation"    `                        // 所在地区
+	CustAddress    string      `p:"custAddress"     json:"custAddress"   `                          // 详细地址
+	CustProvinceId int         `json:"custProvinceId"`                                              // 所在省ID
+	CustProvince   string      `json:"custProvince"`                                                // 所在省
+	CustCityId     int         `json:"custCityId"`                                                  // 所在市ID
+	CustCity       string      `json:"custCity"`                                                    // 所在市
+	CustRegionId   int         `json:"custRegionId"`                                                // 所在区县ID
+	CustRegion     string      `json:"custRegion"`                                                  // 所在区县
+	FollowUpDate   *gtime.Time `p:"followUpDate"    json:"followUpDate"   `                         //跟进时间
+	CustIndustry   string      `p:"custIndustry"    json:"custIndustry"  v:"required#客户行业不能为空"`     //客户行业
+	CustLevel      string      `p:"custLevel"       json:"custLevel"`                               //客户级别
+	CustSource     string      `p:"custSource"      json:"custSource"        v:"required#客户来源不能为空"` //客户来源
+	CustDistCode   int         `p:"custDistCode"    json:"custDistCode"  v:"required#省份不能为空" `      // 省份Id
+	Remark         string      `p:"remark"          json:"remark"`                                  //备注
+	SalesName      string      `p:"salesName"       json:"salesName"   `                            // 销售名称
+	SalesId        int         `p:"salesId"         json:"salesId"   `                              // 销售id
+	InvoiceHeader  string      `json:"invoiceHeader"`                                               // 开票抬头
 }
 
 // 客户联系人信息
@@ -97,7 +97,7 @@ type CustList struct {
 	FollowUpMan    string `json:"followUpMan"`                       // 最后跟进人
 	CustIndustry   string `orm:"cust_industry"  json:"custIndustry"` // 客户行业
 	CustLevel      string `orm:"cust_level"     json:"custLevel"`    // 客户级别(10 重点客户 20 普通客户 30非优客户)
-	CustSource     string `orm:"cust_soucrce"    json:"source"`      // 客户来源
+	CustSource     string `orm:"cust_soucrce"    json:"custSource"`  // 客户来源
 	CreatedName    string `orm:"created_name"   json:"createdName"`  // 创建人
 	CreatedTime    string `orm:"created_time"   json:"createdTime"`  // 创建时间
 	SalesId        int    `orm:"sales_id"   json:"salesId"`          //

+ 8 - 1
opms_parent/app/model/plat/plat_punch_records.go

@@ -15,7 +15,8 @@ type PlatPunchRecords internal.PlatPunchRecords
 // Fill with you ideas below.
 
 type SearchPunchRecordsReq struct {
-	UserId int `json:"userId"` // 关联用户
+	UserNickName    string `json:"userNickName"` // 关联用户
+	DaysBeforeToday int    `json:"daysBeforeToday"`
 	request.PageReq
 }
 
@@ -28,3 +29,9 @@ type AddPunchRecordsReq struct {
 	PunchLocation string `json:"punchLocation"    v:"required#打卡地址不能为空"` // 打卡地址
 	Remark        string `json:"remark"`                                 // 备注
 }
+
+// 打卡记录详情展示,按日期返回前端结果
+type PunchRecordsRes struct {
+	PunchTime            string              `json:"punchTime"`            // 打卡记录的当天日期
+	PlatPunchRecordsList []*PlatPunchRecords `json:"platPunchRecordsList"` // 打卡记录
+}

+ 2 - 2
opms_parent/app/service/base/base_distributor.go

@@ -31,8 +31,8 @@ func NewDistributorService(ctx context.Context) (svc *distributorService, err er
 func (s *distributorService) GetList(req *model.BaseDistributorSearchReq) (total int, distributorList []*model.DistributorRonp, err error) {
 	distributorModel := s.Dao.FieldsEx(s.Dao.C.DeletedTime)
 	// 用户仅有销售工程师角色展示自己的数据,其他人可以看到所有数据
-	if len(s.CxtUser.Roles) == 1 && garray.NewStrArrayFrom(s.CxtUser.Roles, true).Contains("SalesEngineer") {
-		distributorModel = distributorModel.DataScope(s.Ctx, "belong_sale_id")
+	if garray.NewStrArrayFrom(s.CxtUser.Roles, true).Contains("SalesEngineer") {
+		distributorModel = distributorModel.WhereIn("belong_sale_id", s.DataScope["userIds"])
 	}
 	if req.DistCode != "" {
 		distributorModel = distributorModel.WhereLike(s.Dao.C.DistCode, "%"+req.DistCode+"%")

+ 51 - 4
opms_parent/app/service/plat/plat_punch_records.go

@@ -2,10 +2,11 @@ package plat
 
 import (
 	"context"
-	"github.com/gogf/gf/os/gtime"
-
 	"dashoo.cn/opms_libary/myerrors"
+	"database/sql"
+	"github.com/gogf/gf/os/gtime"
 	"github.com/gogf/gf/util/gconv"
+	"strings"
 
 	"dashoo.cn/micro/app/dao/plat"
 	model "dashoo.cn/micro/app/model/plat"
@@ -26,7 +27,7 @@ func NewPunchRecordsService(ctx context.Context) (svc *PunchRecordsService, err
 	return svc, nil
 }
 
-func (s *PunchRecordsService) GetList(req *model.SearchPunchRecordsReq) (total int, taskProgressList []*model.PlatPunchRecords, err error) {
+func (s *PunchRecordsService) GetList(req *model.SearchPunchRecordsReq) (total int, punchRecordsList []*model.PlatPunchRecords, err error) {
 	db := s.Dao.Where(s.Dao.C.UserId, s.GetCxtUserId())
 	if req.BeginTime != "" {
 		db = db.WhereGTE(s.Dao.C.CreatedTime, req.BeginTime)
@@ -40,7 +41,53 @@ func (s *PunchRecordsService) GetList(req *model.SearchPunchRecordsReq) (total i
 		return
 	}
 
-	err = db.OrderDesc(s.Dao.C.CreatedTime).Page(req.GetPage()).Scan(&taskProgressList)
+	err = db.OrderDesc(s.Dao.C.CreatedTime).Page(req.GetPage()).Scan(&punchRecordsList)
+	return
+}
+func (s *PunchRecordsService) GetListByDay(req *model.SearchPunchRecordsReq) (total int, list []*model.PunchRecordsRes, err error) {
+	db := s.Dao.FieldsEx(s.Dao.C.DeletedTime)
+	if req.UserNickName != "" {
+		db = db.WhereLike(s.Dao.C.UserNickName, "%"+req.UserNickName+"%")
+	}
+	// 日期条件
+	if req.DaysBeforeToday > 0 { // 获取前N天的跟进记录
+		now := gtime.Now()
+		begin := now.AddDate(0, 0, -req.DaysBeforeToday).Format("Y-m-d 00:00:00")
+		db = db.WhereGTE(s.Dao.C.PunchTime, begin)
+	}
+	// 获取日期区间范围内的记录
+	if req.BeginTime != "" {
+		begin := strings.Split(req.BeginTime, " ")[0] + " 00:00:00"
+		db = db.WhereGTE(s.Dao.C.PunchTime, begin)
+	}
+	if req.EndTime != "" {
+		end := strings.Split(req.EndTime, " ")[0] + " 23:59:59"
+		db = db.WhereLTE(s.Dao.C.PunchTime, end)
+	}
+
+	// 查询原始记录
+	originalRecords, err := db.OrderDesc(s.Dao.C.PunchTime).All()
+	if err != nil && err != sql.ErrNoRows {
+		return
+	}
+	// 构造数据
+	var days []string
+	recordsMap := make(map[string][]*model.PlatPunchRecords, 0)
+	// 跟进记录map
+	for index, punch := range originalRecords {
+		if _, ok := recordsMap[punch.PunchTime.Format("Y-m-d")]; !ok {
+			days = append(days, punch.PunchTime.Format("Y-m-d"))
+			recordsMap[punch.PunchTime.Format("Y-m-d")] = make([]*model.PlatPunchRecords, 0)
+		}
+		recordsMap[punch.PunchTime.Format("Y-m-d")] = append(recordsMap[punch.PunchTime.Format("Y-m-d")], originalRecords[index])
+	}
+
+	for _, day := range days {
+		var records model.PunchRecordsRes
+		records.PunchTime = day
+		records.PlatPunchRecordsList = recordsMap[day]
+		list = append(list, &records)
+	}
 	return
 }
 

+ 97 - 9
opms_parent/app/service/proj/business.go

@@ -5,11 +5,15 @@ import (
 	contractDao "dashoo.cn/micro/app/dao/contract"
 	custDao "dashoo.cn/micro/app/dao/cust"
 	projDao "dashoo.cn/micro/app/dao/proj"
+	contractModel "dashoo.cn/micro/app/model/contract"
 	model "dashoo.cn/micro/app/model/proj"
 	workflowModel "dashoo.cn/micro/app/model/workflow"
-	"dashoo.cn/micro/app/service"
 	workflowService "dashoo.cn/micro/app/service/workflow"
+
+	"dashoo.cn/micro/app/service"
+	"dashoo.cn/opms_libary/multipart"
 	"dashoo.cn/opms_libary/myerrors"
+	"dashoo.cn/opms_libary/plugin/dingtalk"
 	"dashoo.cn/opms_libary/plugin/dingtalk/message"
 	"dashoo.cn/opms_libary/plugin/dingtalk/workflow"
 	"dashoo.cn/opms_libary/utils"
@@ -152,8 +156,8 @@ func (p *businessService) GetBusinessDynamicsList(req *model.BusinessDynamicsReq
 }
 
 // 获取项目编号
-func (s *businessService) getNboCode(customerCode string) (string, error) {
-	sequence, err := service.Sequence(s.Dao.DB, "nbo_code")
+func (p *businessService) getNboCode(customerCode string) (string, error) {
+	sequence, err := service.Sequence(p.Dao.DB, "nbo_code")
 	if err != nil {
 		return "", err
 	}
@@ -507,7 +511,7 @@ func (p *businessService) BusinessGradation(busId int, nboType, busType string)
 }
 
 // BusinessUpgrade 项目升级
-func (p *businessService) BusinessUpgrade(req *model.BusinessUpgradeReq) error {
+func (p *businessService) BusinessUpgrade(req *model.BusinessUpgradeReq, args *multipart.MultipartFile) error {
 	business, err := p.BusinessGradation(req.Id, req.NboType, "up")
 	if err != nil {
 		return err
@@ -538,7 +542,7 @@ func (p *businessService) BusinessUpgrade(req *model.BusinessUpgradeReq) error {
 		if err != nil {
 			return err
 		}
-		err = p.BusUpgradeDingEvent(business, req)
+		err = p.BusUpgradeDingEvent(business, req, args)
 		return err
 	})
 	return err
@@ -566,7 +570,7 @@ func (p *businessService) getBusDingUpgradeType(dbNboType, reqNboType string) st
 }
 
 // BusUpgradeDingEvent 项目升级钉钉审批流调用
-func (p *businessService) BusUpgradeDingEvent(business *model.ProjBusiness, req *model.BusinessUpgradeReq) error {
+func (p *businessService) BusUpgradeDingEvent(business *model.ProjBusiness, req *model.BusinessUpgradeReq, args *multipart.MultipartFile) error {
 	upgradeType := p.getBusDingUpgradeType(business.NboType, req.NboType)
 	if upgradeType == "" {
 		return myerrors.TipsError("错误的升级类型")
@@ -615,11 +619,89 @@ func (p *businessService) BusUpgradeDingEvent(business *model.ProjBusiness, req
 			},
 		}
 
-	case StatusB, StatusA: // 目前转B、A表单提交参数一致,仅A比B多几个必填-----2023.02.27
+	case StatusB:
 		processCode := &BusinessUpgradeBRequestProcessCode
-		if req.NboType == StatusA {
-			processCode = &BusinessUpgradeARequestProcessCode
+		dingReq = &workflow.StartProcessInstanceRequest{
+			ProcessCode: processCode,
+			FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
+				{
+					Id:    utils.String("TextField-K2AD4O5B"),
+					Name:  utils.String("项目编码"),
+					Value: utils.String(business.NboCode),
+				},
+				{
+					Id:    utils.String("TextField_BDLSECETVSG0"),
+					Name:  utils.String("项目名称"),
+					Value: utils.String(business.NboName),
+				},
+				{
+					Id:    utils.String("DDSelectField_VSA3U380ZK00"),
+					Name:  utils.String("升级类型"),
+					Value: utils.String(upgradeType),
+				},
+				{
+					Id:    utils.String("TextField_1J9BJMOZ18F40"),
+					Name:  utils.String("客户名称"),
+					Value: utils.String(business.CustName),
+				},
+				{
+					Id:    utils.String("NumberField_1F88MCD0W8KG0"),
+					Name:  utils.String("项目预算"),
+					Value: utils.String(gconv.String(req.NboBudget)),
+				},
+				{
+					Id:    utils.String("TextField_1PWK6WHMGITC0"),
+					Name:  utils.String("经销商/代理商"),
+					Value: utils.String(req.DistributorName),
+				},
+				{
+					Id:    utils.String("TextField_X4D3QGARU7K0"),
+					Name:  utils.String("支持内容"),
+					Value: utils.String(req.TechnicalSupportContent),
+				},
+				{
+					Id:    utils.String("TextField_AEUWH63LJ0O0"),
+					Name:  utils.String("销售工程师"),
+					Value: utils.String(business.SaleName),
+				},
+				{
+					Id:    utils.String("DDDateField_1FW1QZQYBZVK0"),
+					Name:  utils.String("采购时间"),
+					Value: utils.String(gconv.String(req.PurchasingTime.Format("Y-m-d"))),
+				},
+				{
+					Id:    utils.String("DDSelectField_21ASEWDIB3MO0"),
+					Name:  utils.String("采购方式"),
+					Value: utils.String(gconv.String(purchasingWayType[req.PurchasingWay])),
+				},
+				{
+					Id:    utils.String("DDSelectField_5R11VVM6GI00"),
+					Name:  utils.String("是否我司参数"),
+					Value: utils.String(gconv.String(yesOrNoType[req.IsAdoptDashoo])),
+				},
+				{
+					Id:    utils.String("TextareaField_1GEL8JJL3H5S0"),
+					Name:  utils.String("备注"),
+					Value: utils.String(req.Remark),
+				},
+			},
+		}
+
+	case StatusA:
+		resp, err := dingtalk.Client.GetStorage().UploadFile(spaceId, p.GetCxtUserDingtalkId(), args.FileName, args.File.Name())
+		if err != nil {
+			return fmt.Errorf("钉钉上传文件异常 %s", err.Error())
 		}
+		g.Log().Info("项目转A类提交大数参数文件", resp)
+		file := []contractModel.DingFileInfo{{
+			SpaceId:  resp.Dentry.SpaceId,
+			FileId:   resp.Dentry.Id,
+			FileName: resp.Dentry.Name,
+			FileSize: resp.Dentry.Size,
+			FileType: resp.Dentry.Extension,
+		}}
+
+		processCode := &BusinessUpgradeARequestProcessCode
 		dingReq = &workflow.StartProcessInstanceRequest{
 			ProcessCode: processCode,
 			FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
@@ -678,6 +760,11 @@ func (p *businessService) BusUpgradeDingEvent(business *model.ProjBusiness, req
 					Name:  utils.String("是否我司参数"),
 					Value: utils.String(gconv.String(yesOrNoType[req.IsAdoptDashoo])),
 				},
+				{
+					Id:    utils.String("DDAttachment_11Q7DBRKE6HC0"),
+					Name:  utils.String("附件"),
+					Value: utils.String(gconv.String(file)),
+				},
 				{
 					Id:    utils.String("TextareaField_1GEL8JJL3H5S0"),
 					Name:  utils.String("备注"),
@@ -685,6 +772,7 @@ func (p *businessService) BusUpgradeDingEvent(business *model.ProjBusiness, req
 				},
 			},
 		}
+
 	default:
 		return nil
 	}

+ 2 - 0
opms_parent/app/service/proj/const.go

@@ -76,3 +76,5 @@ var yesOrNoType = g.MapStrStr{
 	"10": "是", // 是/option_0
 	"20": "否", // 否/option_1
 }
+
+var spaceId = "21077726250"

+ 8 - 9
opms_parent/main.go

@@ -4,24 +4,22 @@ import (
 	"context"
 	"net/http"
 
+	"dashoo.cn/micro/app/handler/base"
+	"dashoo.cn/micro/app/handler/contract"
+	"dashoo.cn/micro/app/handler/cust"
 	"dashoo.cn/micro/app/handler/dingtalk"
 	"dashoo.cn/micro/app/handler/home"
+	"dashoo.cn/micro/app/handler/plat"
+	projHandler "dashoo.cn/micro/app/handler/proj"
 	"dashoo.cn/micro/app/handler/sysreport"
+	"dashoo.cn/micro/app/handler/work"
 	"dashoo.cn/micro/app/handler/workflow"
 	"dashoo.cn/opms_libary/dynamic"
-	"dashoo.cn/opms_libary/myerrors"
-
 	"dashoo.cn/opms_libary/micro_srv"
+	"dashoo.cn/opms_libary/myerrors"
 	"github.com/gogf/gf/frame/g"
 	"github.com/gogf/gf/os/glog"
 	"github.com/smallnest/rpcx/protocol"
-
-	"dashoo.cn/micro/app/handler/base"
-	"dashoo.cn/micro/app/handler/contract"
-	"dashoo.cn/micro/app/handler/cust"
-	"dashoo.cn/micro/app/handler/plat"
-	projHandler "dashoo.cn/micro/app/handler/proj"
-	"dashoo.cn/micro/app/handler/work"
 )
 
 func main() {
@@ -72,6 +70,7 @@ func main() {
 	s.RegisterName("DingEvent", new(dingtalk.DingHandler), "")
 
 	dynamic.Invoker.Register(new(contract.CtrContractHandler))
+	dynamic.Invoker.Register(new(projHandler.BusinessHandler))
 	// 注册服务对象
 	//s.RegisterName("Auth", new(handler.Auth), "")