package base import ( "context" "database/sql" "encoding/json" "fmt" "time" "dashoo.cn/opms_libary/myerrors" "github.com/gogf/gf/container/garray" "github.com/gogf/gf/database/gdb" "github.com/gogf/gf/frame/g" "github.com/gogf/gf/os/gtime" "github.com/gogf/gf/util/gconv" "github.com/gogf/gf/util/gvalid" "dashoo.cn/micro/app/dao/base" contractdao "dashoo.cn/micro/app/dao/contract" projdao "dashoo.cn/micro/app/dao/proj" model "dashoo.cn/micro/app/model/base" contractmodel "dashoo.cn/micro/app/model/contract" projmodel "dashoo.cn/micro/app/model/proj" "dashoo.cn/micro/app/service" ) type distributorService struct { *service.ContextService Dao *base.BaseDistributorDao DynamicsDao *base.BaseDistributorDynamicsDao TargetDao *base.BaseDistributorTargetDao RecordDao *base.BaseDistributorRecordDao ProjDao *projdao.ProjBusinessDao ContractDao *contractdao.CtrContractDao } func NewDistributorService(ctx context.Context) (svc *distributorService, err error) { svc = new(distributorService) if svc.ContextService, err = svc.Init(ctx); err != nil { return nil, err } svc.Dao = base.NewBaseDistributorDao(svc.Tenant) svc.DynamicsDao = base.NewBaseDistributorDynamicsDao(svc.Tenant) svc.ProjDao = projdao.NewProjBusinessDao(svc.Tenant) svc.ContractDao = contractdao.NewCtrContractDao(svc.Tenant) svc.TargetDao = base.NewBaseDistributorTargetDao(svc.Tenant) svc.RecordDao = base.NewBaseDistributorRecordDao(svc.Tenant) return svc, nil } // GetList 经销商信息列表 func (s *distributorService) GetList(req *model.BaseDistributorSearchReq) (total int, distributorList []*model.BaseDistributorListRsp, err error) { distributorModel := s.Dao.FieldsEx(s.Dao.C.DeletedTime) // 用户仅有销售工程师角色展示自己的数据,其他人可以看到所有数据 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+"%") } if req.DistName != "" { distributorModel = distributorModel.WhereLike(s.Dao.C.DistName, "%"+req.DistName+"%") } if req.BelongSale != "" { distributorModel = distributorModel.WhereLike(s.Dao.C.BelongSale, "%"+req.BelongSale+"%") } if len(req.ProvinceId) > 0 { distributorModel = distributorModel.WhereIn(s.Dao.C.ProvinceId, req.ProvinceId) } if req.DistType != "" { distributorModel = distributorModel.WhereIn(s.Dao.C.DistType, req.DistType) } total, err = distributorModel.Count() if err != nil { err = myerrors.DbError("获取总行数失败。") return } err = distributorModel.Page(req.GetPage()).Order("id desc").Scan(&distributorList) if req.WithStatistic { for i, dist := range distributorList { statistic, err := s.statistic(dist.Id) if err != nil { return 0, nil, err } distributorList[i].BaseDistributorStatistic = statistic } } return } func (s *distributorService) statistic(id int) (stat model.BaseDistributorStatistic, err error) { v, err := s.Dao.DB.GetValue("select count(*) from proj_business where distributor_id=? and appro_status ='30' and nbo_type in (10,20,30) and deleted_time is null", id) if err != nil { return stat, err } stat.ProjectNum = v.Int() v, err = s.Dao.DB.GetValue("select sum(est_trans_price) from proj_business where distributor_id=? and appro_status ='30' and nbo_type in (10,20,30) and deleted_time is null", id) if err != nil { return stat, err } stat.AllProductAmount = v.Float64() v, err = s.Dao.DB.GetValue("select count(distinct(b.id)) from ctr_contract a left join proj_business b on a.nbo_id=b.id where a.distributor_id=? and a.appro_status ='30' and b.appro_status ='30' and a.deleted_time is null and b.deleted_time is null", id) if err != nil { return stat, err } stat.SaledProjectNum = v.Int() v, err = s.Dao.DB.GetValue("select sum(contract_amount) from ctr_contract where distributor_id=? and appro_status='30' and deleted_time is null", id) if err != nil { return stat, err } stat.SaledAmount = v.Float64() v, err = s.Dao.DB.GetValue("select sum(contract_amount - collected_amount) from ctr_contract where distributor_id=? and appro_status='30' and deleted_time is null", id) if err != nil { return stat, err } stat.UnpaidAmount = v.Float64() v, err = s.Dao.DB.GetValue("select sum(invoice_amount) from ctr_contract where distributor_id=? and appro_status='30' and deleted_time is null", id) if err != nil { return stat, err } stat.InvoicedAmount = v.Float64() return } // 获取经销商编号 func (s *distributorService) getDistributorCode(distCode string) (string, error) { sequence, err := service.Sequence(s.Dao.DB, "distributor_code") if err != nil { return "", err } return distCode + sequence, nil } // Create 经销商创建 func (s *distributorService) Create(req *model.AddDistributor) (lastId int64, err error) { DistributorData := new(model.BaseDistributor) if err = gconv.Struct(req, DistributorData); err != nil { return } DistributorData.DistCode, err = s.getDistributorCode("JXS") if err != nil { return 0, err } service.SetCreatedInfo(DistributorData, s.GetCxtUserId(), s.GetCxtUserName()) lastId, err = s.Dao.InsertAndGetId(DistributorData) if err != nil { return 0, err } err = s.Dao.DB.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error { err = s.AddDynamicsByCurrentUser(tx, int(lastId), "创建经销商/代理商", map[string]interface{}{}) return err }) return } // GetEntityById 详情 func (s *distributorService) GetEntityById(id int64) (distributorInfo *model.BaseDistributorListRsp, err error) { err = s.Dao.Where(base.BaseProduct.C.Id, id).Scan(&distributorInfo) if err != nil { return nil, err } statistic, err := s.statistic(int(id)) if err != nil { return nil, err } distributorInfo.BaseDistributorStatistic = statistic target, err := s.TargetDao.Where("dist_id = ?", id).Where("year = ?", time.Now().Year()).One() if err != nil { return nil, err } if target != nil { distributorInfo.YearTarget = target.Total } return } // UpdateById 修改数据 func (s *distributorService) UpdateById(req *model.UpdateDistributorReq) (err error) { count, err := s.Dao.Where("id = ", req.Id).Count() if err != nil { g.Log().Error(err) return } if count == 0 { err = myerrors.TipsError("无修改数据") return } distData := new(model.BaseDistributor) if err = gconv.Struct(req, distData); err != nil { return } service.SetUpdatedInfo(distData, s.GetCxtUserId(), s.GetCxtUserName()) _, err = s.Dao.FieldsEx(s.Dao.C.DistCode, s.Dao.C.Id, s.Dao.C.CreatedName, s.Dao.C.CreatedBy, s.Dao.C.CreatedTime).WherePri(s.Dao.C.Id, req.Id).Update(distData) if err != nil { g.Log().Error(err) return } err = s.Dao.DB.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error { err = s.AddDynamicsByCurrentUser(tx, req.Id, "更新经销商/代理商", map[string]interface{}{}) return err }) return } func (s *distributorService) ToProxy(ctx context.Context, req *model.DistributorToProxyReq) (err error) { validErr := gvalid.CheckStruct(ctx, req, nil) if validErr != nil { return myerrors.TipsError(validErr.Current().Error()) } ent, err := s.Dao.Where("id = ?", req.Id).One() if err != nil { return err } if ent == nil { return myerrors.TipsError(fmt.Sprintf("代理商/经销商不存在: %d", req.Id)) } txerr := s.Dao.DB.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error { _, err = tx.Update("base_distributor", map[string]interface{}{ "dist_type": "20", "customer_type": req.CustomerType, "proxy_start_time": req.ProxyStartTime, "proxy_end_time": req.ProxyEndTime, "proxy_district": req.ProxyDistrict, "contract_url": req.ContractUrl, }, "id = ?", req.Id) if err != nil { return err } _, err = tx.Insert("base_distributor_record", model.BaseDistributorRecord{ DistId: req.Id, DistType: "20", BusinessScope: ent.BusinessScope, CustomerType: req.CustomerType, ProxyDistrict: req.ProxyDistrict, ProxyStartTime: req.ProxyStartTime, ProxyEndTime: req.ProxyEndTime, ContractUrl: req.ContractUrl, ExistedProduct: ent.ExistedProduct, HistoryCustomer: ent.HistoryCustomer, ToDistReason: "", Remark: "", CreatedBy: s.GetCxtUserId(), CreatedName: s.GetCxtUserName(), CreatedTime: gtime.Now(), UpdatedBy: s.GetCxtUserId(), UpdatedName: s.GetCxtUserName(), UpdatedTime: gtime.Now(), }) if err != nil { return err } err = s.AddDynamicsByCurrentUser(tx, req.Id, "转为代理商", map[string]interface{}{}) if err != nil { return err } return nil }) return txerr } func (s *distributorService) Renew(ctx context.Context, req *model.DistributorRenewReq) (err error) { validErr := gvalid.CheckStruct(ctx, req, nil) if validErr != nil { return myerrors.TipsError(validErr.Current().Error()) } ent, err := s.Dao.Where("id = ?", req.Id).One() if err != nil { return err } if ent == nil { return myerrors.TipsError(fmt.Sprintf("代理商/经销商不存在: %d", req.Id)) } txerr := s.Dao.DB.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error { _, err = tx.Update("base_distributor", map[string]interface{}{ "customer_type": req.CustomerType, "proxy_start_time": req.ProxyStartTime, "proxy_end_time": req.ProxyEndTime, "proxy_district": req.ProxyDistrict, "contract_url": req.ContractUrl, }, "id = ?", req.Id) if err != nil { return err } _, err = tx.Insert("base_distributor_record", model.BaseDistributorRecord{ DistId: req.Id, DistType: "20", BusinessScope: ent.BusinessScope, CustomerType: req.CustomerType, ProxyDistrict: req.ProxyDistrict, ProxyStartTime: req.ProxyStartTime, ProxyEndTime: req.ProxyEndTime, ContractUrl: req.ContractUrl, ExistedProduct: ent.ExistedProduct, HistoryCustomer: ent.HistoryCustomer, ToDistReason: "", Remark: "", CreatedBy: s.GetCxtUserId(), CreatedName: s.GetCxtUserName(), CreatedTime: gtime.Now(), UpdatedBy: s.GetCxtUserId(), UpdatedName: s.GetCxtUserName(), UpdatedTime: gtime.Now(), }) if err != nil { return err } err = s.AddDynamicsByCurrentUser(tx, req.Id, "续签代理商", map[string]interface{}{}) if err != nil { return err } return nil }) return txerr } func (s *distributorService) ToDist(ctx context.Context, req *model.DistributorToDistReq) (err error) { validErr := gvalid.CheckStruct(ctx, req, nil) if validErr != nil { return myerrors.TipsError(validErr.Current().Error()) } ent, err := s.Dao.Where("id = ?", req.Id).One() if err != nil { return err } if ent == nil { return myerrors.TipsError(fmt.Sprintf("代理商/经销商不存在: %d", req.Id)) } txerr := s.Dao.DB.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error { _, err = tx.Update("base_distributor", map[string]interface{}{ "dist_type": "10", }, "id = ?", req.Id) if err != nil { return err } _, err = tx.Insert("base_distributor_record", model.BaseDistributorRecord{ DistId: req.Id, DistType: "10", BusinessScope: ent.BusinessScope, CustomerType: ent.CustomerType, ProxyDistrict: "", ProxyStartTime: nil, ProxyEndTime: nil, ContractUrl: "", ExistedProduct: ent.ExistedProduct, HistoryCustomer: ent.HistoryCustomer, ToDistReason: req.ToDistReason, Remark: "", CreatedBy: s.GetCxtUserId(), CreatedName: s.GetCxtUserName(), CreatedTime: gtime.Now(), UpdatedBy: s.GetCxtUserId(), UpdatedName: s.GetCxtUserName(), UpdatedTime: gtime.Now(), }) if err != nil { return err } err = s.AddDynamicsByCurrentUser(tx, req.Id, "转为经销商", map[string]interface{}{}) if err != nil { return err } return nil }) return txerr } func (s *distributorService) TransRecord(ctx context.Context, req *model.DistributorTransRecordReq) (int, []*model.BaseDistributorRecord, error) { dao := s.RecordDao.As("a") if req.DistId != 0 { dao = dao.Where("a.dist_id = ?", req.DistId) } total, err := dao.Count() if err != nil { return 0, nil, err } if req.PageNum != 0 { dao = dao.Page(req.GetPage()) } orderby := "a.created_time desc" if req.OrderBy != "" { orderby = req.OrderBy } dao = dao.Order(orderby) ents := []*model.BaseDistributorRecord{} err = dao.Structs(&ents) if err != nil && err != sql.ErrNoRows { return 0, nil, err } return total, ents, nil } // DeleteByIds 删除 func (s *distributorService) DeleteByIds(ids []int64) (err error) { _, err = s.Dao.WhereIn(s.Dao.C.Id, ids).Delete() if err != nil { return err } return } func (s distributorService) AddDynamicsByCurrentUser(tx *gdb.TX, distId int, opnType string, content map[string]interface{}) error { contentByte, err := json.Marshal(content) if err != nil { return err } _, err = tx.InsertAndGetId("base_distributor_dynamics", model.BaseDistributorDynamics{ DistId: distId, OpnPeopleId: s.GetCxtUserId(), OpnPeople: s.GetCxtUserName(), OpnDate: gtime.Now(), OpnType: opnType, OpnContent: string(contentByte), Remark: "", CreatedBy: s.GetCxtUserId(), CreatedName: s.GetCxtUserName(), CreatedTime: gtime.Now(), UpdatedBy: s.GetCxtUserId(), UpdatedName: s.GetCxtUserName(), UpdatedTime: gtime.Now(), }) return err } func (s distributorService) ContractList(ctx context.Context, req *model.DistributorContractListReq) (int, []*contractmodel.CtrContractListRsp, error) { dao := s.ContractDao.As("a") if req.DistId != 0 { dao = dao.Where("a.distributor_id = ?", req.DistId) } if req.SearchText != "" { likestr := fmt.Sprintf("%%%s%%", req.SearchText) dao = dao.Where("(a.contract_code LIKE ? || a.contract_name LIKE ? || a.cust_name LIKE ? || a.nbo_name LIKE ?)", likestr, likestr, likestr, likestr) } if req.ContractCode != "" { likestr := fmt.Sprintf("%%%s%%", req.ContractCode) dao = dao.Where("a.contract_code like ?", likestr) } if req.ContractName != "" { likestr := fmt.Sprintf("%%%s%%", req.ContractName) dao = dao.Where("a.contract_name like ?", likestr) } if req.CustId != 0 { dao = dao.Where("a.cust_id = ?", req.CustId) } if req.CustName != "" { likestr := fmt.Sprintf("%%%s%%", req.CustName) dao = dao.Where("a.cust_name like ?", likestr) } if req.NboId != 0 { dao = dao.Where("a.nbo_id = ?", req.NboId) } if req.NboName != "" { likestr := fmt.Sprintf("%%%s%%", req.NboName) dao = dao.Where("a.nbo_name like ?", likestr) } if req.ApproStatus != "" { dao = dao.Where("a.appro_status = ?", req.ApproStatus) } if req.ContractType != "" { dao = dao.Where("a.contract_type = ?", req.ContractType) } if req.InchargeId != 0 { dao = dao.Where("a.incharge_id = ?", req.InchargeId) } if req.InchargeName != "" { likestr := fmt.Sprintf("%%%s%%", req.InchargeName) dao = dao.Where("a.incharge_name like ?", likestr) } if req.SignatoryId != 0 { dao = dao.Where("a.signatory_id = ?", req.SignatoryId) } if req.SignatoryName != "" { likestr := fmt.Sprintf("%%%s%%", req.SignatoryName) dao = dao.Where("a.signatory_name like ?", likestr) } if req.DistributorName != "" { likestr := fmt.Sprintf("%%%s%%", req.DistributorName) dao = dao.Where("a.distributor_name like ?", likestr) } if req.BeginTime != "" { dao = dao.Where("a.created_time > ?", req.BeginTime) } if req.EndTime != "" { dao = dao.Where("a.created_time < ?", req.EndTime) } total, err := dao.Count() if err != nil { return 0, nil, err } if req.PageNum != 0 { dao = dao.Page(req.GetPage()) } orderby := "a.created_time desc" if req.OrderBy != "" { orderby = req.OrderBy } dao = dao.Order(orderby) ents := []*contractmodel.CtrContractListRsp{} err = dao.Structs(&ents) if err != nil && err != sql.ErrNoRows { return 0, nil, err } return total, ents, nil } func (s distributorService) ProjectList(ctx context.Context, req *model.DistributorProjectListReq) (int, []*projmodel.ProjBusiness, error) { dao := &s.ProjDao.ProjBusinessDao if req.DistId != 0 { dao = dao.Where("distributor_id = ?", req.DistId) } if req.SearchText != "" { likestr := fmt.Sprintf("%%%s%%", req.SearchText) dao = dao.Where("(cust_name LIKE ? || nbo_name LIKE ?)", likestr, likestr) } if req.NboName != "" { likestr := fmt.Sprintf("%%%s%%", req.NboName) dao = dao.Where("nbo_name like ?", likestr) } if req.CustName != "" { likestr := fmt.Sprintf("%%%s%%", req.CustName) dao = dao.Where("cust_name like ?", likestr) } if req.CreatedTimeStart != nil { dao = dao.Where("created_time > ?", req.CreatedTimeStart) } if req.CreatedTimeEnd != nil { dao = dao.Where("created_time < ?", req.CreatedTimeEnd) } total, err := dao.Count() if err != nil { return 0, nil, err } if req.PageNum != 0 { dao = dao.Page(req.GetPage()) } orderby := "created_time desc" if req.OrderBy != "" { orderby = req.OrderBy } dao = dao.Order(orderby) ents := []*projmodel.ProjBusiness{} err = dao.Structs(&ents) if err != nil && err != sql.ErrNoRows { return 0, nil, err } return total, ents, nil } func (s distributorService) DynamicsList(ctx context.Context, req *model.DistributorDynamicsListReq) (int, interface{}, error) { dao := &s.DynamicsDao.BaseDistributorDynamicsDao if req.SearchText != "" { likestr := fmt.Sprintf("%%%s%%", req.SearchText) dao = dao.Where("(opn_people LIKE ? || opn_content LIKE ?)", likestr, likestr) } if req.DistId != 0 { dao = dao.Where("dist_id = ?", req.DistId) } if req.OpnPeopleId != 0 { dao = dao.Where("opn_people_id = ?", req.OpnPeopleId) } if req.OpnPeople != "" { likestr := fmt.Sprintf("%%%s%%", req.OpnPeople) dao = dao.Where("opn_people like ?", likestr) } if req.OpnType != "" { dao = dao.Where("opn_type = ?", req.OpnType) } if req.BeginTime != "" { dao = dao.Where("created_time > ?", req.BeginTime) } if req.EndTime != "" { dao = dao.Where("created_time < ?", req.EndTime) } total, err := dao.Count() if err != nil { return 0, nil, err } if req.PageNum != 0 { dao = dao.Page(req.GetPage()) } orderby := "created_time desc" if req.OrderBy != "" { orderby = req.OrderBy } dao = dao.Order(orderby) ents := []*model.BaseDistributorDynamics{} err = dao.Structs(&ents) if err != nil && err != sql.ErrNoRows { return 0, nil, err } ret := map[string][]*model.BaseDistributorDynamics{} for _, ent := range ents { date := ent.OpnDate.Format("Y-m-d") ret[date] = append(ret[date], ent) } return total, ret, err }