business.go 52 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649
  1. package proj
  2. import (
  3. "context"
  4. platDao "dashoo.cn/micro/app/dao/plat"
  5. "os"
  6. contractDao "dashoo.cn/micro/app/dao/contract"
  7. custDao "dashoo.cn/micro/app/dao/cust"
  8. projDao "dashoo.cn/micro/app/dao/proj"
  9. contractModel "dashoo.cn/micro/app/model/contract"
  10. model "dashoo.cn/micro/app/model/proj"
  11. workflowModel "dashoo.cn/micro/app/model/workflow"
  12. workflowService "dashoo.cn/micro/app/service/workflow"
  13. "dashoo.cn/opms_libary/plugin/dingtalk"
  14. "fmt"
  15. "strconv"
  16. "strings"
  17. "dashoo.cn/micro/app/service"
  18. "dashoo.cn/opms_libary/multipart"
  19. "dashoo.cn/opms_libary/myerrors"
  20. "dashoo.cn/opms_libary/plugin/dingtalk/message"
  21. "dashoo.cn/opms_libary/plugin/dingtalk/workflow"
  22. "dashoo.cn/opms_libary/utils"
  23. "github.com/gogf/gf/database/gdb"
  24. "github.com/gogf/gf/frame/g"
  25. "github.com/gogf/gf/os/gtime"
  26. "github.com/gogf/gf/util/gconv"
  27. "github.com/shopspring/decimal"
  28. )
  29. type businessService struct {
  30. *service.ContextService
  31. Dao *projDao.ProjBusinessDao
  32. ContactDao *projDao.ProjBusinessContactDao
  33. FollowDao *platDao.PlatFollowupDao
  34. fileDao *projDao.ProjBusinessFileDao
  35. }
  36. func NewBusinessService(ctx context.Context) (svc *businessService, err error) {
  37. svc = new(businessService)
  38. if svc.ContextService, err = svc.Init(ctx); err != nil {
  39. return nil, err
  40. }
  41. svc.Dao = projDao.NewProjBusinessDao(svc.Tenant)
  42. svc.ContactDao = projDao.NewProjBusinessContactDao(svc.Tenant)
  43. svc.FollowDao = platDao.NewPlatFollowupDao(svc.Tenant)
  44. svc.fileDao = projDao.NewProjBusinessFileDao(svc.Tenant)
  45. return svc, nil
  46. }
  47. func (p *businessService) GetList(req *model.ProjBusinessSearchReq) (total int, businessList []*model.ProjBusinessRes, err error) {
  48. db := p.Dao.As("proj").DataScope(p.Ctx, "sale_id")
  49. if req.NboName != "" {
  50. db = db.WhereLike("proj."+p.Dao.C.NboName, "%"+req.NboName+"%")
  51. }
  52. if req.CustName != "" {
  53. db = db.WhereLike("proj."+p.Dao.C.CustName, "%"+req.CustName+"%")
  54. }
  55. if req.SaleName != "" {
  56. db = db.WhereLike("proj."+p.Dao.C.SaleName, "%"+req.SaleName+"%")
  57. }
  58. if req.NboType != "" {
  59. db = db.Where("proj."+p.Dao.C.NboType, req.NboType)
  60. }
  61. if req.ProductLine != "" {
  62. db = db.Where("proj."+p.Dao.C.ProductLine, req.ProductLine)
  63. }
  64. if req.NboSource != "" {
  65. db = db.Where("proj."+p.Dao.C.NboSource, req.NboSource)
  66. }
  67. if req.DistributorName != "" {
  68. db = db.WhereLike("proj."+p.Dao.C.DistributorName, "%"+req.DistributorName+"%")
  69. }
  70. if req.BeginTime != "" {
  71. db = db.WhereGTE("proj."+p.Dao.C.FilingTime, req.BeginTime)
  72. }
  73. if req.EndTime != "" {
  74. db = db.WhereLTE("proj."+p.Dao.C.FilingTime, req.EndTime)
  75. }
  76. if req.ProvinceId != 0 {
  77. db = db.Where("proj."+p.Dao.C.CustProvinceId, req.ProvinceId)
  78. }
  79. total, err = db.Count()
  80. if err != nil {
  81. err = myerrors.DbError("获取总行数失败。")
  82. return
  83. }
  84. if req.NboType == StatusDeal {
  85. db = db.Unscoped().WhereNull(`proj.deleted_time`).
  86. LeftJoin(contractDao.CtrContract.Table, "contract", "`proj`.id=`contract`.nbo_id AND `contract`.`deleted_time` IS NULL ").
  87. Fields("`proj`.cust_city_id as cust_city_id,`contract`.contract_amount, `contract`.created_time as proj_closing_time")
  88. }
  89. db = db.Fields("`proj`.*")
  90. err = db.Page(req.GetPage()).OrderDesc("id").Scan(&businessList)
  91. return
  92. }
  93. func (p *businessService) GetEntityById(id int64) (business *model.ProjBusinessRes, err error) {
  94. err = p.Dao.Where(projDao.ProjBusiness.C.Id, id).Scan(&business)
  95. if err != nil {
  96. return nil, err
  97. }
  98. if business == nil {
  99. return nil, myerrors.TipsError("项目不存在")
  100. }
  101. return
  102. }
  103. func (p *businessService) GetBusinessInfoById(id int64) (business *model.ProjBusinessRes, err error) {
  104. err = p.Dao.Where(projDao.ProjBusiness.C.Id, id).Scan(&business)
  105. if err != nil {
  106. return nil, err
  107. }
  108. if business == nil {
  109. return nil, myerrors.TipsError("项目不存在")
  110. }
  111. business.FollowCount, err = p.FollowDao.Where(p.FollowDao.C.TargetType, "20").Where(p.FollowDao.C.TargetId, business.Id).Count()
  112. if err != nil {
  113. return nil, err
  114. }
  115. productList, err := p.GetBusinessProduct(id)
  116. if err != nil {
  117. return nil, err
  118. }
  119. if err := gconv.Structs(productList, &business.Products); err != nil {
  120. return nil, err
  121. }
  122. files, err := p.fileDao.Where(p.fileDao.C.BusId, id).WhereLike(p.fileDao.C.FileSource, "%报价单%").OrderDesc(p.fileDao.C.Id).Limit(1).All()
  123. if err != nil {
  124. return nil, err
  125. }
  126. business.QuotationFileList = files
  127. return
  128. }
  129. func (p *businessService) GetBusinessProduct(id int64) (productList []*model.ProjBusinessProduct, err error) {
  130. productDao := projDao.NewProjBusinessProductDao(p.Tenant)
  131. err = productDao.Where(productDao.ProjBusinessProductDao.C.BusId, id).Scan(&productList)
  132. return
  133. }
  134. func (p *businessService) GetBusinessDynamics(req *model.BusinessReq) (total int, result g.MapStrAny, err error) {
  135. result = make(g.MapStrAny, 0)
  136. dynamicsDao := projDao.NewProjBusinessDynamicsDao(p.Tenant).ProjBusinessDynamicsDao.Where(projDao.ProjBusinessDynamics.C.BusId, req.BusId)
  137. total, err = dynamicsDao.Count()
  138. if err != nil {
  139. g.Log().Error(err)
  140. return
  141. }
  142. dynamicsList, err := dynamicsDao.Page(req.GetPage()).Order("created_time desc").All()
  143. if err != nil || dynamicsList == nil {
  144. return
  145. }
  146. // 数据树格式转换
  147. opnDateFlag := gtime.New(dynamicsList[0].OpnDate).Format("Y-m-d")
  148. for k, v := range dynamicsList {
  149. opnDate := gtime.New(v.OpnDate).Format("Y-m-d")
  150. if opnDateFlag == opnDate && k != 0 {
  151. result[opnDate] = append(result[opnDate].(g.ListStrAny), g.Map{
  152. "opnPeople": v.OpnPeople,
  153. "opnDate": v.OpnDate,
  154. "opnType": v.OpnType,
  155. "remark": v.Remark,
  156. "opnContent": gconv.Map(v.OpnContent),
  157. })
  158. } else {
  159. temp := make(g.ListStrAny, 0)
  160. temp = append(temp, g.Map{
  161. "opnPeople": v.OpnPeople,
  162. "opnDate": v.OpnDate,
  163. "opnType": v.OpnType,
  164. "remark": v.Remark,
  165. "opnContent": gconv.Map(v.OpnContent),
  166. })
  167. result[opnDate] = temp
  168. opnDateFlag = opnDate
  169. }
  170. }
  171. return
  172. }
  173. func (p *businessService) GetBusinessDynamicsList(req *model.BusinessDynamicsReq) (total int, list []map[string]interface{}, err error) {
  174. dynamicsDao := projDao.NewProjBusinessDynamicsDao(p.Tenant).Where(projDao.ProjBusinessDynamics.C.BusId, req.BusId)
  175. if req.OpnType != "" {
  176. dynamicsDao = dynamicsDao.Where(projDao.ProjBusinessDynamics.C.OpnType+" = ?", req.OpnType)
  177. }
  178. total, err = dynamicsDao.Count()
  179. if err != nil {
  180. g.Log().Error(err)
  181. return
  182. }
  183. dynamicsList, err := dynamicsDao.Page(req.GetPage()).Order("created_time desc").All()
  184. for _, v := range dynamicsList {
  185. val := gconv.Map(v)
  186. val["opnContent"] = gconv.Map(v.OpnContent)
  187. list = append(list, val)
  188. }
  189. return
  190. }
  191. // 获取项目编号
  192. func (p *businessService) getNboCode(customerCode string) (string, error) {
  193. sequence, err := service.Sequence(p.Dao.DB, "nbo_code")
  194. if err != nil {
  195. return "", err
  196. }
  197. return customerCode + sequence, nil
  198. }
  199. func (p *businessService) Create(req *model.AddProjBusinessReq) (err error) {
  200. // 获取客户信息
  201. customer, err := custDao.NewCustCustomerDao(p.Tenant).WherePri(req.CustId).One()
  202. if err != nil {
  203. return err
  204. }
  205. if customer == nil {
  206. return myerrors.TipsError("客户不存在")
  207. }
  208. // 获取项目编号
  209. nboCode, err := p.getNboCode(customer.CustCode)
  210. if err != nil {
  211. return err
  212. }
  213. // 初始化项目信息
  214. business := new(model.ProjBusiness)
  215. if err = gconv.Struct(req, business); err != nil {
  216. return
  217. }
  218. business.NboCode = nboCode
  219. if business.NboType == "" {
  220. business.NboType = StatusC
  221. }
  222. business.ApproStatus = ApprovalWaiting
  223. business.CustProvinceId = customer.CustProvinceId
  224. business.CustProvince = customer.CustProvince
  225. business.CustCityId = customer.CustCityId
  226. business.CustCity = customer.CustCity
  227. business.CustRegionId = customer.CustRegionId
  228. business.CustRegion = customer.CustRegion
  229. business.DeptId = p.GetCxtUserDeptId()
  230. service.SetCreatedInfo(business, p.GetCxtUserId(), p.GetCxtUserName())
  231. business.FilingTime = business.CreatedTime
  232. productLine, _ := service.GetDictLabelByTypeAndValue(p.Ctx, "sys_product_line", business.ProductLine)
  233. nboSource, _ := service.GetDictLabelByTypeAndValue(p.Ctx, "proj_nbo_source", business.NboSource)
  234. salesModel, _ := service.GetDictLabelByTypeAndValue(p.Ctx, "proj_sales_model", business.SalesModel)
  235. // 事务
  236. err = p.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  237. // 添加项目
  238. lastId, err := p.Dao.TX(tx).InsertAndGetId(business)
  239. if err != nil {
  240. return err
  241. }
  242. // 添加项目动态
  243. dynamics := model.ProjBusinessDynamics{
  244. BusId: int(lastId),
  245. OpnType: OpnCreate,
  246. Remark: business.Remark,
  247. }
  248. _, err = p.CreateProjBusinessDynamics(tx, dynamics, business)
  249. // 审批流
  250. workflowSrv, _ := workflowService.NewFlowService(p.Ctx)
  251. // OMS项目转移 审批
  252. bizCode := business.NboCode + ":" + gconv.String(lastId)
  253. _, err = workflowSrv.StartProcessInstance(bizCode, workflowModel.ProjectCreate, "", &workflow.StartProcessInstanceRequest{
  254. ProcessCode: &BusinessCreateRequestProcessCode,
  255. FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
  256. {
  257. Id: utils.String("TextField-K2AD4O5B"),
  258. Name: utils.String("项目编码"),
  259. Value: utils.String(business.NboCode),
  260. },
  261. {
  262. Id: utils.String("TextField_BDLSECETVSG0"),
  263. Name: utils.String("项目名称"),
  264. Value: utils.String(business.NboName),
  265. },
  266. {
  267. Id: utils.String("DDSelectField_213JKZA1OUO00"),
  268. Name: utils.String("产品线"),
  269. Value: utils.String(productLine),
  270. },
  271. {
  272. Id: utils.String("TextField_1J9BJMOZ18F40"),
  273. Name: utils.String("客户名称"),
  274. Value: utils.String(business.CustName),
  275. },
  276. {
  277. Id: utils.String("DDSelectField_6CQD451D3800"),
  278. Name: utils.String("项目来源"),
  279. Value: utils.String(nboSource),
  280. },
  281. {
  282. Id: utils.String("TextField_1UQFU5BUEWDC"),
  283. Name: utils.String("历史招标信息"),
  284. Value: utils.String(req.BidInfo),
  285. },
  286. {
  287. Id: utils.String("TextField_AEUWH63LJ0O0"),
  288. Name: utils.String("销售工程师"),
  289. Value: utils.String(business.SaleName),
  290. },
  291. {
  292. Id: utils.String("DDSelectField_34QSUGHO2SO0"),
  293. Name: utils.String("销售模式"),
  294. Value: utils.String(salesModel),
  295. },
  296. {
  297. Id: utils.String("TextField_1PWK6WHMGITC0"),
  298. Name: utils.String("经销商/代理商"),
  299. Value: utils.String(business.DistributorName),
  300. },
  301. {
  302. Id: utils.String("DDSelectField_5R11VVM6GI00"),
  303. Name: utils.String("是否为大项目"),
  304. Value: utils.String(yesOrNoType[business.IsBig]),
  305. },
  306. {
  307. Id: utils.String("TextareaField_1GEL8JJL3H5S0"),
  308. Name: utils.String("备注"),
  309. Value: utils.String(business.Remark),
  310. },
  311. },
  312. })
  313. if err != nil {
  314. g.Log().Error(err)
  315. return err
  316. }
  317. return err
  318. })
  319. return
  320. }
  321. // BusinessCreatedNotify 项目创建 审批结果通知
  322. func (p *businessService) BusinessCreatedNotify(flow *workflowModel.PlatWorkflow, msg *message.MixMessage) error {
  323. business, err := p.checkDingTalkNotify(flow, msg)
  324. if err != nil {
  325. return err
  326. }
  327. var data = g.Map{}
  328. if msg.ProcessType == "terminate" {
  329. data[p.Dao.C.ApproStatus] = ApprovalReturn
  330. }
  331. if msg.ProcessType == "finish" && msg.Result == "refuse" {
  332. data[p.Dao.C.ApproStatus] = ApprovalRejection
  333. }
  334. if msg.ProcessType == "finish" && msg.Result == "agree" {
  335. data[p.Dao.C.ApproStatus] = ApprovalOK
  336. }
  337. // 项目修改
  338. _, err = p.Dao.WherePri(business.Id).FieldsEx(service.UpdateFieldEx...).Data(data).Update()
  339. if err != nil {
  340. return err
  341. }
  342. // 添加项目动态
  343. dynamics := model.ProjBusinessDynamics{
  344. BusId: business.Id,
  345. OpnType: OpnCreatedApproval,
  346. }
  347. _, err = p.CreateProjBusinessDynamics(nil, dynamics, data)
  348. if err != nil {
  349. return err
  350. }
  351. return err
  352. }
  353. // setProductInfo 设置产品信息
  354. func (p *businessService) setProductInfo(busId int, productInfo []model.BusinessProduct) (total float64, products []*model.ProjBusinessProduct, err error) {
  355. products = make([]*model.ProjBusinessProduct, len(productInfo))
  356. if err = gconv.Structs(productInfo, &products); err != nil {
  357. return 0, nil, err
  358. }
  359. var totalPrice decimal.Decimal
  360. for _, v := range products {
  361. v.Id = 0
  362. v.BusId = busId
  363. v.TotalPrice = decimal.NewFromFloat(v.ProdPrice).Mul(decimal.NewFromInt(int64(v.ProdNum))).InexactFloat64()
  364. totalPrice = totalPrice.Add(decimal.NewFromFloat(v.TotalPrice))
  365. service.SetCreatedInfo(v, p.GetCxtUserId(), p.GetCxtUserName())
  366. }
  367. return totalPrice.InexactFloat64(), products, nil
  368. }
  369. // setBusinessContact 设置项目联系人
  370. func (p *businessService) setBusinessContact(tx *gdb.TX, contactList []model.SetBusinessContactReq) (err error) {
  371. for _, item := range contactList {
  372. count, err := p.ContactDao.Where(p.ContactDao.C.BusId, item.BusId).Where(p.ContactDao.C.ContactType, item.ContactType).Count()
  373. if err != nil {
  374. return err
  375. }
  376. if count == 0 {
  377. data := new(model.ProjBusinessContact)
  378. data.BusId = item.BusId
  379. data.ContactId = item.ContactId
  380. data.ContactType = item.ContactType
  381. service.SetCreatedInfo(data, p.GetCxtUserId(), p.GetCxtUserName())
  382. _, err = p.ContactDao.TX(tx).Data(data).Insert()
  383. if err != nil {
  384. return err
  385. }
  386. }
  387. }
  388. return
  389. }
  390. func (p *businessService) UpdateById(req *model.UpdateProjBusinessReq) error {
  391. record, err := p.Dao.WherePri(req.Id).Count()
  392. if err != nil {
  393. return err
  394. }
  395. if record == 0 {
  396. return myerrors.TipsError("项目不存在。")
  397. }
  398. // 设置产品信息
  399. totalPrice, products, err := p.setProductInfo(req.Id, req.Products)
  400. if err != nil {
  401. return err
  402. }
  403. // 设置默认联系人
  404. contactList := make([]model.SetBusinessContactReq, 0)
  405. if req.ContactId != 0 {
  406. contactList = append(contactList, model.SetBusinessContactReq{
  407. BusId: req.Id,
  408. ContactId: req.ContactId,
  409. ContactType: "10",
  410. })
  411. }
  412. if req.DealerSalesId != 0 {
  413. contactList = append(contactList, model.SetBusinessContactReq{
  414. BusId: req.Id,
  415. ContactId: req.DealerSalesId,
  416. ContactType: "20",
  417. })
  418. }
  419. // 设置项目信息
  420. req.EstTransPrice = totalPrice
  421. businessData := gconv.Map(req)
  422. service.SetUpdatedInfo(businessData, p.GetCxtUserId(), p.GetCxtUserName())
  423. err = p.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  424. // 更新项目
  425. updateFieldEx := append(service.UpdateFieldEx, p.Dao.C.SaleId, p.Dao.C.SaleName, p.Dao.C.NboType, p.Dao.C.NboCode)
  426. _, err = p.Dao.TX(tx).FieldsEx(updateFieldEx...).WherePri(projDao.ProjBusiness.C.Id, req.Id).Update(businessData)
  427. if err != nil {
  428. return err
  429. }
  430. // 删除项目产品
  431. _, err = projDao.NewProjBusinessProductDao(p.Tenant).TX(tx).Where(projDao.ProjBusinessProduct.C.BusId, req.Id).Delete()
  432. if err != nil {
  433. return err
  434. }
  435. // 添加项目产品
  436. _, err = projDao.NewProjBusinessProductDao(p.Tenant).TX(tx).Insert(products)
  437. if err != nil {
  438. return err
  439. }
  440. // 关联联系人
  441. err = p.setBusinessContact(tx, contactList)
  442. if err != nil {
  443. return err
  444. }
  445. // 添加项目动态
  446. dynamics := model.ProjBusinessDynamics{
  447. BusId: req.Id,
  448. OpnType: OpnUpdate,
  449. Remark: req.Remark,
  450. }
  451. _, err = p.CreateProjBusinessDynamics(tx, dynamics, req)
  452. return err
  453. })
  454. return err
  455. }
  456. // UpdateBusinessContactInfo 清理项目表联系人信息
  457. func (p *businessService) UpdateBusinessContactInfo(tx *gdb.TX, busId int, data g.Map) (err error) {
  458. fields := []interface{}{p.Dao.C.ContactId, p.Dao.C.ContactName, p.Dao.C.ContactPostion, p.Dao.C.ContactTelephone, p.Dao.C.DealerSalesId, p.Dao.C.DealerSalesName, p.Dao.C.DealerSalesContact}
  459. _, err = p.Dao.TX(tx).Fields(fields...).WherePri(busId).Data(data).Update()
  460. return
  461. }
  462. func (p *businessService) DeleteByIds(ids []int64) (err error) {
  463. _, err = p.Dao.WhereIn(projDao.ProjBusiness.C.Id, ids).Delete()
  464. return
  465. }
  466. // BusinessTransfer 项目转移
  467. func (p *businessService) BusinessTransfer(req *model.BusinessTransferReq) error {
  468. business, err := p.Dao.WherePri(req.Id).WhereNot(p.Dao.C.ApproStatus, ApprovalWaiting).One()
  469. if err != nil {
  470. return err
  471. }
  472. if business == nil {
  473. return myerrors.TipsError("项目已提交审批任务,无法重复提交。")
  474. }
  475. businessMap := g.Map{
  476. p.Dao.C.ApproStatus: ApprovalWaiting,
  477. }
  478. service.SetUpdatedInfo(businessMap, p.GetCxtUserId(), p.GetCxtUserName())
  479. opnContent := gconv.Map(gconv.String(businessMap))
  480. opnContent["origSaleId"] = business.SaleId
  481. opnContent["origSaleName"] = business.SaleName
  482. opnContent["saleId"] = req.UserId
  483. opnContent["saleName"] = req.UserName
  484. opnContent["remark"] = req.Remark
  485. productLine, _ := service.GetDictLabelByTypeAndValue(p.Ctx, "sys_product_line", business.ProductLine)
  486. // 审批流
  487. workflowSrv, _ := workflowService.NewFlowService(p.Ctx)
  488. err = p.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  489. // 更新项目
  490. _, err = p.Dao.TX(tx).WherePri(projDao.ProjBusiness.C.Id, req.Id).Data(businessMap).Update()
  491. if err != nil {
  492. return err
  493. }
  494. // 添加项目动态
  495. dynamics := model.ProjBusinessDynamics{
  496. BusId: req.Id,
  497. OpnType: OpnTransfer,
  498. Remark: req.Remark,
  499. }
  500. _, err = p.CreateProjBusinessDynamics(tx, dynamics, opnContent)
  501. if err != nil {
  502. g.Log().Error(err)
  503. return err
  504. }
  505. // OMS项目转移 审批
  506. bizCode := business.NboCode + ":" + strconv.Itoa(business.Id)
  507. _, err = workflowSrv.StartProcessInstance(bizCode, workflowModel.ProjectTransfer, "", &workflow.StartProcessInstanceRequest{
  508. ProcessCode: &BusinessTransferRequestProcessCode,
  509. FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
  510. {
  511. Id: utils.String("TextField-K2AD4O5B"),
  512. Name: utils.String("项目编码"),
  513. Value: utils.String(business.NboCode),
  514. },
  515. {
  516. Id: utils.String("TextField_7EFHRQ9DDF80"),
  517. Name: utils.String("项目名称"),
  518. Value: utils.String(business.NboName),
  519. },
  520. {
  521. Id: utils.String("TextField_1T3DEY5FWV7K0"),
  522. Name: utils.String("客户名称"),
  523. Value: utils.String(business.CustName),
  524. },
  525. {
  526. Id: utils.String("TextField_QDU06LXYKK00"),
  527. Name: utils.String("所在省"),
  528. Value: utils.String(business.CustProvince),
  529. },
  530. {
  531. Id: utils.String("TextField_MVSOO6EG6YO0"),
  532. Name: utils.String("所在市"),
  533. Value: utils.String(business.CustCity),
  534. },
  535. {
  536. Id: utils.String("DDSelectField_6OMVO1JV0980"),
  537. Name: utils.String("产品线"),
  538. Value: utils.String(productLine),
  539. },
  540. {
  541. Id: utils.String("TextField_1E1WOYGKRTDS0"),
  542. Name: utils.String("项目级别"),
  543. Value: utils.String(nboType[business.NboType]),
  544. },
  545. {
  546. Id: utils.String("TextField_NRQXWLJ17HC0"),
  547. Name: utils.String("申请人"),
  548. Value: utils.String(p.GetCxtUserName()),
  549. },
  550. {
  551. Id: utils.String("TextField_GHSQYDGD13K0"),
  552. Name: utils.String("转移原因"),
  553. Value: utils.String(req.Remark),
  554. },
  555. {
  556. Id: utils.String("TextField_76P8FPHH0UC0"),
  557. Name: utils.String("接收人"),
  558. Value: utils.String(req.UserName),
  559. },
  560. },
  561. })
  562. if err != nil {
  563. g.Log().Error(err)
  564. return err
  565. }
  566. return nil
  567. })
  568. return err
  569. }
  570. // BusinessTransferNotify 项目转移 审批结果通知
  571. func (p *businessService) BusinessTransferNotify(flow *workflowModel.PlatWorkflow, msg *message.MixMessage) error {
  572. business, err := p.checkDingTalkNotify(flow, msg)
  573. if err != nil {
  574. return err
  575. }
  576. var data = g.Map{}
  577. if msg.ProcessType == "terminate" {
  578. data[p.Dao.C.ApproStatus] = ApprovalReturn
  579. }
  580. if msg.ProcessType == "finish" && msg.Result == "refuse" {
  581. data[p.Dao.C.ApproStatus] = ApprovalRejection
  582. }
  583. if msg.ProcessType == "finish" && msg.Result == "agree" {
  584. // 从项目动态内获取变更信息
  585. var transferDynamics model.ProjBusinessDynamics
  586. dynamicsDao := projDao.NewProjBusinessDynamicsDao(p.Tenant).Where(projDao.ProjBusinessDynamics.C.BusId, business.Id)
  587. err = dynamicsDao.Where(projDao.ProjBusinessDynamics.C.OpnType, OpnTransfer).OrderDesc("created_time").Scan(&transferDynamics)
  588. if err != nil {
  589. return err
  590. }
  591. changeData := gconv.Map(transferDynamics.OpnContent)
  592. data[p.Dao.C.SaleId] = changeData["saleId"]
  593. data[p.Dao.C.SaleName] = changeData["saleName"]
  594. data[p.Dao.C.Remark] = changeData["remark"]
  595. data[p.Dao.C.ApproStatus] = ApprovalOK
  596. }
  597. // 项目修改
  598. _, err = p.Dao.WherePri(business.Id).FieldsEx(service.UpdateFieldEx...).Data(data).Update()
  599. if err != nil {
  600. return err
  601. }
  602. // 添加项目动态
  603. dynamics := model.ProjBusinessDynamics{
  604. BusId: business.Id,
  605. OpnType: OpnTransferApproval,
  606. }
  607. _, err = p.CreateProjBusinessDynamics(nil, dynamics, data)
  608. if err != nil {
  609. return err
  610. }
  611. return err
  612. }
  613. // BusinessGradation 项目调级
  614. func (p *businessService) BusinessGradation(busId int, nboType, busType string) (*model.ProjBusiness, error) {
  615. business, err := p.Dao.WherePri(busId).WhereNot(p.Dao.C.ApproStatus, ApprovalWaiting).One()
  616. if err != nil {
  617. return nil, err
  618. }
  619. if business == nil {
  620. return nil, myerrors.TipsError("项目已提交审批任务,无法重复提交。")
  621. }
  622. if business.NboType == nboType {
  623. return nil, myerrors.TipsError("同级别无法进行调级。")
  624. }
  625. if business.NboType == StatusDeal {
  626. return nil, myerrors.TipsError("成交项目无法进行调级。")
  627. }
  628. if business.NboType == StatusReserve && nboType == StatusDeal {
  629. return nil, myerrors.TipsError("储备项目无法直接转为成交项目。")
  630. }
  631. if busType == "up" && gconv.Int(business.NboType) < gconv.Int(nboType) {
  632. return nil, myerrors.TipsError("项目级别错误。")
  633. }
  634. if busType == "down" && gconv.Int(business.NboType) > gconv.Int(nboType) {
  635. return nil, myerrors.TipsError("项目级别错误。")
  636. }
  637. return business, err
  638. }
  639. // BusinessUpgrade 项目升级
  640. func (p *businessService) BusinessUpgrade(req *model.BusinessUpgradeReq, fileMap map[string]*multipart.FileHeader) error {
  641. business, err := p.BusinessGradation(req.Id, req.NboType, "up")
  642. if err != nil {
  643. return err
  644. }
  645. businessMap := g.Map{p.Dao.C.ApproStatus: ApprovalWaiting}
  646. service.SetUpdatedInfo(businessMap, p.GetCxtUserId(), p.GetCxtUserName())
  647. opnContent := gconv.Map(req)
  648. opnContent["origNboType"] = business.NboType
  649. opnContent["approStatus"] = ApprovalWaiting
  650. service.SetUpdatedInfo(opnContent, p.GetCxtUserId(), p.GetCxtUserName())
  651. if fileMap == nil {
  652. fileMap = make(map[string]*multipart.FileHeader)
  653. }
  654. if (req.NboType == StatusA || req.NboType == StatusB) && !strings.HasPrefix(req.QuotationFile, "dingtalk") {
  655. fileMap["quotationFile"], err = service.DownloadTempFile(req.QuotationFile)
  656. if err != nil {
  657. return err
  658. }
  659. defer os.Remove(fileMap["quotationFile"].File.Name())
  660. }
  661. if req.NboType == StatusA && req.IsAdoptDashoo == "10" {
  662. fileMap["dashooParamFile"], err = service.DownloadTempFile(req.DashooParamFile)
  663. if err != nil {
  664. return err
  665. }
  666. defer os.Remove(fileMap["dashooParamFile"].File.Name())
  667. }
  668. contactList := make([]model.SetBusinessContactReq, 0)
  669. if req.ContactId != 0 {
  670. contactList = append(contactList, model.SetBusinessContactReq{
  671. BusId: req.Id,
  672. ContactId: req.ContactId,
  673. ContactType: "10",
  674. })
  675. }
  676. if req.DealerSalesId != 0 {
  677. contactList = append(contactList, model.SetBusinessContactReq{
  678. BusId: req.Id,
  679. ContactId: req.DealerSalesId,
  680. ContactType: "20",
  681. })
  682. }
  683. err = p.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  684. // 更新项目调级
  685. _, err = p.Dao.TX(tx).WherePri(req.Id).Data(businessMap).Update()
  686. if err != nil {
  687. return err
  688. }
  689. // 关联联系人
  690. err = p.setBusinessContact(tx, contactList)
  691. if err != nil {
  692. return err
  693. }
  694. // 添加项目动态
  695. dynamics := model.ProjBusinessDynamics{
  696. BusId: business.Id,
  697. OpnType: OpnUpgrade,
  698. Remark: req.Remark,
  699. }
  700. _, err = p.CreateProjBusinessDynamics(tx, dynamics, opnContent)
  701. if err != nil {
  702. return err
  703. }
  704. err = p.BusUpgradeDingEvent(business, req, fileMap)
  705. return err
  706. })
  707. if err != nil {
  708. return err
  709. }
  710. return nil
  711. }
  712. // 获取项目的钉钉审批的升级类型
  713. func (p *businessService) getBusDingUpgradeType(dbNboType, reqNboType string) string {
  714. var upgradeType string
  715. switch true {
  716. case dbNboType == StatusReserve && reqNboType == StatusC: // 储备转C/option_0
  717. upgradeType = "储备转C"
  718. case dbNboType == StatusReserve && reqNboType == StatusB: // 储备转B/option_1
  719. upgradeType = "储备转B"
  720. case dbNboType == StatusReserve && reqNboType == StatusA: // 储备转A/option_KTAX3Y9K5340
  721. upgradeType = "储备转A"
  722. case dbNboType == StatusC && reqNboType == StatusB: // C转B/option_0
  723. upgradeType = "C转B"
  724. case dbNboType == StatusC && reqNboType == StatusA: // C转A/option_0
  725. upgradeType = "C转A"
  726. case dbNboType == StatusB && reqNboType == StatusA: // B转A/option_1
  727. upgradeType = "B转A"
  728. default:
  729. }
  730. return upgradeType
  731. }
  732. // BusUpgradeDingEvent 项目升级钉钉审批流调用
  733. func (p *businessService) BusUpgradeDingEvent(business *model.ProjBusiness, req *model.BusinessUpgradeReq, fileMap map[string]*multipart.FileHeader) error {
  734. var err error
  735. upgradeType := p.getBusDingUpgradeType(business.NboType, req.NboType)
  736. if upgradeType == "" {
  737. return myerrors.TipsError("错误的升级类型")
  738. }
  739. productLineMap, err := service.GetDictDataTreeByType(p.Ctx, "sys_product_line")
  740. if err != nil {
  741. return err
  742. }
  743. productLine := gconv.String(productLineMap.Get(business.ProductLine))
  744. dingProductList := make([][]*workflow.StartProcessInstanceRequestFormComponentValues, 0)
  745. for _, item := range req.Products {
  746. pInfo := make([]*workflow.StartProcessInstanceRequestFormComponentValues, 0)
  747. pInfo = append(pInfo, &workflow.StartProcessInstanceRequestFormComponentValues{
  748. Id: utils.String("TextField_8P2W917Q5I40"),
  749. Name: utils.String("产品编码"),
  750. Value: utils.String(item.ProdCode),
  751. })
  752. pInfo = append(pInfo, &workflow.StartProcessInstanceRequestFormComponentValues{
  753. Id: utils.String("TextField_1W2HGNQFLLA80"),
  754. Name: utils.String("产品名称"),
  755. Value: utils.String(item.ProdName),
  756. })
  757. pInfo = append(pInfo, &workflow.StartProcessInstanceRequestFormComponentValues{
  758. Id: utils.String("TextField_1OPT3MZL76GW0"),
  759. Name: utils.String("产品类别"),
  760. Value: utils.String(gconv.String(productLineMap.Get(item.ProdClass))),
  761. })
  762. pInfo = append(pInfo, &workflow.StartProcessInstanceRequestFormComponentValues{
  763. Id: utils.String("TextField_O405QBZMPW00"),
  764. Name: utils.String("产品单价"),
  765. Value: utils.String(gconv.String(item.ProdPrice)),
  766. })
  767. pInfo = append(pInfo, &workflow.StartProcessInstanceRequestFormComponentValues{
  768. Id: utils.String("TextField_23P54AZUW4SG0"),
  769. Name: utils.String("数量"),
  770. Value: utils.String(gconv.String(item.ProdNum)),
  771. })
  772. dingProductList = append(dingProductList, pInfo)
  773. }
  774. // 审批流
  775. workflowSrv, _ := workflowService.NewFlowService(p.Ctx)
  776. // OMS项目升级 审批
  777. var dingReq *workflow.StartProcessInstanceRequest
  778. bizCode := business.NboCode + ":" + strconv.Itoa(business.Id)
  779. switch req.NboType {
  780. case StatusC:
  781. dingReq = &workflow.StartProcessInstanceRequest{
  782. ProcessCode: &BusinessUpgradeCRequestProcessCode,
  783. FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
  784. {
  785. Id: utils.String("TextField-K2AD4O5B"),
  786. Name: utils.String("项目编码"),
  787. Value: utils.String(business.NboCode),
  788. },
  789. {
  790. Id: utils.String("TextField_BDLSECETVSG0"),
  791. Name: utils.String("项目名称"),
  792. Value: utils.String(business.NboName),
  793. },
  794. {
  795. Id: utils.String("DDSelectField_1MJU37HGJX4W0"),
  796. Name: utils.String("产品线"),
  797. Value: utils.String(productLine),
  798. },
  799. {
  800. Id: utils.String("DDSelectField_VSA3U380ZK00"),
  801. Name: utils.String("升级类型"),
  802. Value: utils.String(upgradeType),
  803. },
  804. {
  805. Id: utils.String("TextField_1J9BJMOZ18F40"),
  806. Name: utils.String("客户名称"),
  807. Value: utils.String(business.CustName),
  808. },
  809. {
  810. Id: utils.String("TextField_AEUWH63LJ0O0"),
  811. Name: utils.String("销售工程师"),
  812. Value: utils.String(business.SaleName),
  813. },
  814. {
  815. Id: utils.String("TextareaField_1LO81IKHH91C0"),
  816. Name: utils.String("转化原因"),
  817. Value: utils.String(req.ProjConversionReason),
  818. },
  819. },
  820. }
  821. case StatusB:
  822. quotationFile := make([]contractModel.DingFileInfo, 0)
  823. if len(fileMap) > 0 {
  824. for k, files := range fileMap {
  825. // 报价单
  826. if k == "quotationFile" {
  827. if quotationFile, err = p.txCreateBusinessDingTalkFile(business.Id, upgradeType, k, files); err != nil {
  828. return err
  829. }
  830. }
  831. }
  832. }
  833. if len(quotationFile) == 0 {
  834. return myerrors.TipsError("请上传报价单文件")
  835. }
  836. processCode := &BusinessUpgradeBRequestProcessCode
  837. dingReq = &workflow.StartProcessInstanceRequest{
  838. ProcessCode: processCode,
  839. FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
  840. {
  841. Id: utils.String("TextField-K2AD4O5B"),
  842. Name: utils.String("项目编码"),
  843. Value: utils.String(business.NboCode),
  844. },
  845. {
  846. Id: utils.String("TextField_BDLSECETVSG0"),
  847. Name: utils.String("项目名称"),
  848. Value: utils.String(business.NboName),
  849. },
  850. {
  851. Id: utils.String("DDSelectField_213JKZA1OUO00"),
  852. Name: utils.String("产品线"),
  853. Value: utils.String(productLine),
  854. },
  855. {
  856. Id: utils.String("DDSelectField_VSA3U380ZK00"),
  857. Name: utils.String("升级类型"),
  858. Value: utils.String(upgradeType),
  859. },
  860. {
  861. Id: utils.String("TextField_1J9BJMOZ18F40"),
  862. Name: utils.String("客户名称"),
  863. Value: utils.String(business.CustName),
  864. },
  865. {
  866. Id: utils.String("NumberField_1F88MCD0W8KG0"),
  867. Name: utils.String("项目预算"),
  868. Value: utils.String(gconv.String(req.NboBudget)),
  869. },
  870. {
  871. Id: utils.String("TextField_1PWK6WHMGITC0"),
  872. Name: utils.String("渠道销售人员"),
  873. Value: utils.String(req.DealerSalesName),
  874. },
  875. {
  876. Id: utils.String("TextField_M06MZK20POG0"),
  877. Name: utils.String("渠道销售电话/微信"),
  878. Value: utils.String(req.DealerSalesContact),
  879. },
  880. {
  881. Id: utils.String("TextField_GL59OGH2Z1S0"),
  882. Name: utils.String("预计出货金额"),
  883. Value: utils.String(gconv.String(business.EstTransPrice)),
  884. },
  885. {
  886. Id: utils.String("TableField_1CGSRAWT8YG0"),
  887. Name: utils.String("产品列表"),
  888. Value: utils.String(gconv.String(dingProductList)),
  889. },
  890. {
  891. Id: utils.String("TextField_AEUWH63LJ0O0"),
  892. Name: utils.String("销售工程师"),
  893. Value: utils.String(business.SaleName),
  894. },
  895. {
  896. Id: utils.String("DDAttachment_KZPWZJS9GHO0"),
  897. Name: utils.String("上传报价单"),
  898. Value: utils.String(gconv.String(quotationFile)),
  899. },
  900. {
  901. Id: utils.String("TextareaField_1GEL8JJL3H5S0"),
  902. Name: utils.String("备注"),
  903. Value: utils.String(req.Remark),
  904. },
  905. },
  906. }
  907. case StatusA:
  908. var dashooParamFile []contractModel.DingFileInfo
  909. var quotationFile []contractModel.DingFileInfo
  910. if len(fileMap) > 0 {
  911. for k, files := range fileMap {
  912. // 报价单
  913. if k == "quotationFile" {
  914. if quotationFile, err = p.txCreateBusinessDingTalkFile(business.Id, upgradeType, k, files); err != nil {
  915. return err
  916. }
  917. }
  918. // 大数参数文件
  919. if k == "dashooParamFile" {
  920. if dashooParamFile, err = p.txCreateBusinessDingTalkFile(business.Id, upgradeType, k, files); err != nil {
  921. return err
  922. }
  923. }
  924. }
  925. }
  926. if strings.HasPrefix(req.QuotationFile, "dingtalk") {
  927. arr := strings.Split(req.QuotationFile, ":")
  928. quotationFile = append(quotationFile, contractModel.DingFileInfo{
  929. SpaceId: arr[1],
  930. FileId: arr[2],
  931. FileName: fmt.Sprintf("%v报价单", business.NboName),
  932. FileSize: 10,
  933. FileType: "",
  934. })
  935. }
  936. if len(quotationFile) == 0 {
  937. return myerrors.TipsError("请上传报价单文件")
  938. }
  939. processCode := &BusinessUpgradeARequestProcessCode
  940. dingReq = &workflow.StartProcessInstanceRequest{
  941. ProcessCode: processCode,
  942. FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
  943. {
  944. Id: utils.String("TextField-K2AD4O5B"),
  945. Name: utils.String("项目编码"),
  946. Value: utils.String(business.NboCode),
  947. },
  948. {
  949. Id: utils.String("TextField_BDLSECETVSG0"),
  950. Name: utils.String("项目名称"),
  951. Value: utils.String(business.NboName),
  952. },
  953. {
  954. Id: utils.String("DDSelectField_L4CSUVLU1NK"),
  955. Name: utils.String("产品线"),
  956. Value: utils.String(productLine),
  957. },
  958. {
  959. Id: utils.String("DDSelectField_VSA3U380ZK00"),
  960. Name: utils.String("升级类型"),
  961. Value: utils.String(upgradeType),
  962. },
  963. {
  964. Id: utils.String("TextField_1J9BJMOZ18F40"),
  965. Name: utils.String("客户名称"),
  966. Value: utils.String(business.CustName),
  967. },
  968. {
  969. Id: utils.String("DDSelectField_21ASEWDIB3MO0"),
  970. Name: utils.String("采购方式"),
  971. Value: utils.String(gconv.String(purchasingWayType[req.PurchasingWay])),
  972. },
  973. {
  974. Id: utils.String("TextField_3AIYCSEQLQC0"),
  975. Name: utils.String("资金来源"),
  976. Value: utils.String(req.CapitalSource),
  977. },
  978. {
  979. Id: utils.String("DDDateField_1FW1QZQYBZVK0"),
  980. Name: utils.String("计划采购时间"),
  981. Value: utils.String(gconv.String(req.PlanPurchaseTime.Format("Y-m-d"))),
  982. },
  983. {
  984. Id: utils.String("TextField_1PWK6WHMGITC0"),
  985. Name: utils.String("客户决策人"),
  986. Value: utils.String(req.MakerName),
  987. },
  988. {
  989. Id: utils.String("TextField_16RIJRRF8B340"),
  990. Name: utils.String("客户决策部门"),
  991. Value: utils.String(req.MakerDept),
  992. },
  993. {
  994. Id: utils.String("TextField_7EE0LTUVUSK0"),
  995. Name: utils.String("客户联系人"),
  996. Value: utils.String(req.ContactName),
  997. },
  998. {
  999. Id: utils.String("TextField_E8TFCZUBV940"),
  1000. Name: utils.String("客户联系人电话/微信"),
  1001. Value: utils.String(req.ContactTelephone),
  1002. },
  1003. {
  1004. Id: utils.String("DDSelectField_5R11VVM6GI00"),
  1005. Name: utils.String("是否我司参数"),
  1006. Value: utils.String(gconv.String(yesOrNoType[req.IsAdoptDashoo])),
  1007. },
  1008. {
  1009. Id: utils.String("DDAttachment_11Q7DBRKE6HC0"),
  1010. Name: utils.String("附件"),
  1011. Value: utils.String(gconv.String(dashooParamFile)),
  1012. },
  1013. {
  1014. Id: utils.String("TextField_FJI7GL9E8W80"),
  1015. Name: utils.String("竞争公司"),
  1016. Value: utils.String(req.Competitor),
  1017. },
  1018. {
  1019. Id: utils.String("TextField_1NC9MEUBDBR40"),
  1020. Name: utils.String("客户倾向厂家"),
  1021. Value: utils.String(req.CustomerIntentionFactory),
  1022. },
  1023. {
  1024. Id: utils.String("TextField_AEUWH63LJ0O0"),
  1025. Name: utils.String("销售工程师"),
  1026. Value: utils.String(business.SaleName),
  1027. },
  1028. {
  1029. Id: utils.String("DDAttachment_19Y01ZRBFWXS0"),
  1030. Name: utils.String("上传报价单"),
  1031. Value: utils.String(gconv.String(quotationFile)),
  1032. },
  1033. {
  1034. Id: utils.String("TextareaField_1GEL8JJL3H5S0"),
  1035. Name: utils.String("备注"),
  1036. Value: utils.String(req.Remark),
  1037. },
  1038. },
  1039. }
  1040. default:
  1041. return nil
  1042. }
  1043. _, err = workflowSrv.StartProcessInstance(bizCode, workflowModel.ProjectUpGrade, "", dingReq)
  1044. if err != nil {
  1045. g.Log().Error(err)
  1046. return err
  1047. }
  1048. return nil
  1049. }
  1050. // 项目上传文件至钉钉
  1051. func (p *businessService) txCreateBusinessDingTalkFile(businessId int, upgradeType, fileType string, file *multipart.FileHeader) ([]contractModel.DingFileInfo, error) {
  1052. dingTalkFiles := make([]contractModel.DingFileInfo, 0)
  1053. //for _, file := range files {
  1054. resp, err := dingtalk.Client.GetStorage().UploadFile(service.DingTalkSpaceId, p.GetCxtUserDingtalkId(), file.FileName, file.File.Name())
  1055. if err != nil {
  1056. g.Log().Error(err)
  1057. return nil, myerrors.TipsError("钉钉上传文件异常")
  1058. }
  1059. typ := "项目" + upgradeType
  1060. if fileType == "quotationFile" {
  1061. typ += "上传报价单文件"
  1062. }
  1063. if fileType == "dashooParamFile" {
  1064. typ += "上传大数技术参数文件"
  1065. }
  1066. g.Log().Info(typ, resp)
  1067. dingTalkFiles = append(dingTalkFiles, contractModel.DingFileInfo{
  1068. SpaceId: resp.Dentry.SpaceId,
  1069. FileId: resp.Dentry.Id,
  1070. FileName: resp.Dentry.Name,
  1071. FileSize: resp.Dentry.Size,
  1072. FileType: resp.Dentry.Extension,
  1073. })
  1074. //}
  1075. err = p.txCreateBusinessFile(businessId, typ, dingTalkFiles)
  1076. if err != nil {
  1077. return nil, err
  1078. }
  1079. return dingTalkFiles, nil
  1080. }
  1081. // 采用大数参数文件记录
  1082. func (p *businessService) txCreateBusinessFile(busId int, fileSource string, files []contractModel.DingFileInfo) error {
  1083. dataList := make([]*model.ProjBusinessFile, 0)
  1084. for _, v := range files {
  1085. data := new(model.ProjBusinessFile)
  1086. data.BusId = busId
  1087. data.FileName = v.FileName
  1088. data.FileSource = fileSource
  1089. data.FileSize = gconv.String(v.FileSize)
  1090. data.FileUrl = strings.Join([]string{"dingtalk", v.SpaceId, v.FileId}, ":")
  1091. service.SetCreatedInfo(data, p.GetCxtUserId(), p.GetCxtUserName())
  1092. dataList = append(dataList, data)
  1093. }
  1094. _, err := projDao.NewProjBusinessFileDao(p.Tenant).Insert(&dataList)
  1095. return err
  1096. }
  1097. // BusinessUpgradeNotify 项目升级 审批结果通知
  1098. func (p *businessService) BusinessUpgradeNotify(flow *workflowModel.PlatWorkflow, msg *message.MixMessage) error {
  1099. business, err := p.checkDingTalkNotify(flow, msg)
  1100. if err != nil {
  1101. return err
  1102. }
  1103. var data = g.Map{}
  1104. var updateData *model.BusinessUpgradeReq
  1105. var remark string
  1106. if msg.ProcessType == "terminate" {
  1107. data[p.Dao.C.ApproStatus] = ApprovalReturn
  1108. }
  1109. if msg.ProcessType == "finish" && msg.Result == "refuse" {
  1110. data[p.Dao.C.ApproStatus] = ApprovalRejection
  1111. }
  1112. if msg.ProcessType == "finish" && msg.Result == "agree" {
  1113. // 从项目动态内获取变更信息
  1114. dynamics := new(model.ProjBusinessDynamics)
  1115. dynamicsDao := projDao.NewProjBusinessDynamicsDao(p.Tenant).Where(projDao.ProjBusinessDynamics.C.BusId, business.Id)
  1116. err = dynamicsDao.Where(projDao.ProjBusinessDynamics.C.OpnType, OpnUpgrade).OrderDesc("created_time").Scan(dynamics)
  1117. if err != nil {
  1118. return err
  1119. }
  1120. updateData = new(model.BusinessUpgradeReq)
  1121. gconv.Struct(dynamics.OpnContent, updateData)
  1122. data = gconv.Map(updateData)
  1123. data[p.Dao.C.ApproStatus] = ApprovalOK
  1124. remarkMap := gconv.Map(dynamics.OpnContent)
  1125. remark = gconv.String(g.Map{"nboType": remarkMap["nboType"], "origNboType": remarkMap["origNboType"]})
  1126. }
  1127. err = p.Dao.Transaction(p.Ctx, func(ctx context.Context, tx *gdb.TX) error {
  1128. // 添加产品
  1129. if updateData != nil && (updateData.NboType == "20" || updateData.NboType == "10") {
  1130. // 设置产品信息
  1131. totalPrice, products, err := p.setProductInfo(updateData.Id, updateData.Products)
  1132. if err != nil {
  1133. return err
  1134. }
  1135. // 删除项目产品
  1136. _, err = projDao.NewProjBusinessProductDao(p.Tenant).TX(tx).Where(projDao.ProjBusinessProduct.C.BusId, updateData.Id).Delete()
  1137. if err != nil {
  1138. return err
  1139. }
  1140. // 添加项目产品
  1141. _, err = projDao.NewProjBusinessProductDao(p.Tenant).TX(tx).Insert(products)
  1142. if err != nil {
  1143. return err
  1144. }
  1145. data[p.Dao.C.EstTransPrice] = totalPrice
  1146. }
  1147. // 项目修改
  1148. _, err = p.Dao.TX(tx).WherePri(business.Id).FieldsEx(service.UpdateFieldEx...).Data(data).Update()
  1149. if err != nil {
  1150. return err
  1151. }
  1152. // 添加项目动态
  1153. dynamics := model.ProjBusinessDynamics{
  1154. BusId: business.Id,
  1155. OpnType: OpnUpgradeApproval,
  1156. Remark: remark,
  1157. }
  1158. _, err = p.CreateProjBusinessDynamics(tx, dynamics, data)
  1159. if err != nil {
  1160. return err
  1161. }
  1162. return nil
  1163. })
  1164. if err != nil {
  1165. return err
  1166. }
  1167. return nil
  1168. }
  1169. // 获取项目的钉钉审批的降级类型
  1170. func (p *businessService) getBusDingDowngradeType(dbNboType, reqNboType string) string {
  1171. var downgradeType string
  1172. switch true {
  1173. case dbNboType == StatusB && reqNboType == StatusC: // B转C/option_0
  1174. downgradeType = "B转C"
  1175. case dbNboType == StatusA && reqNboType == StatusB: // A转B/option_1
  1176. downgradeType = "A转B"
  1177. case dbNboType == StatusA && reqNboType == StatusC: // A转C/option_2
  1178. downgradeType = "A转C"
  1179. case dbNboType == StatusA && reqNboType == StatusReserve: // A转储备/option_YZMFJYQQK6O0
  1180. downgradeType = "A转储备"
  1181. case dbNboType == StatusB && reqNboType == StatusReserve: // B转储备/option_232GR5NMFCSG0
  1182. downgradeType = "B转储备"
  1183. case dbNboType == StatusC && reqNboType == StatusReserve: // C转储备/option_1ZV2GJLDKQOW0
  1184. downgradeType = "C转储备"
  1185. default:
  1186. }
  1187. return downgradeType
  1188. }
  1189. // BusinessDowngrade 项目降级
  1190. func (p *businessService) BusinessDowngrade(req *model.BusinessDowngradeReq) error {
  1191. business, err := p.BusinessGradation(req.Id, req.NboType, "down")
  1192. if err != nil {
  1193. return err
  1194. }
  1195. downgradeType := p.getBusDingDowngradeType(business.NboType, req.NboType)
  1196. if downgradeType == "" {
  1197. return myerrors.TipsError("错误的降级类型")
  1198. }
  1199. businessMap := g.Map{
  1200. p.Dao.C.ApproStatus: ApprovalWaiting,
  1201. }
  1202. service.SetUpdatedInfo(businessMap, p.GetCxtUserId(), p.GetCxtUserName())
  1203. opnContent := gconv.Map(req)
  1204. opnContent["origNboType"] = business.NboType
  1205. opnContent["approStatus"] = ApprovalWaiting
  1206. service.SetUpdatedInfo(opnContent, p.GetCxtUserId(), p.GetCxtUserName())
  1207. productLine, _ := service.GetDictLabelByTypeAndValue(p.Ctx, "sys_product_line", business.ProductLine)
  1208. // 审批流
  1209. workflowSrv, _ := workflowService.NewFlowService(p.Ctx)
  1210. err = p.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  1211. // 更新项目调级
  1212. _, err = p.Dao.TX(tx).WherePri(req.Id).Data(businessMap).Update()
  1213. if err != nil {
  1214. return err
  1215. }
  1216. // 添加项目动态
  1217. dynamics := model.ProjBusinessDynamics{
  1218. BusId: business.Id,
  1219. OpnType: OpnDowngrade,
  1220. Remark: req.Remark,
  1221. }
  1222. _, err = p.CreateProjBusinessDynamics(tx, dynamics, opnContent)
  1223. if err != nil {
  1224. return err
  1225. }
  1226. // OMS项目降级 审批
  1227. bizCode := business.NboCode + ":" + strconv.Itoa(business.Id)
  1228. _, err = workflowSrv.StartProcessInstance(bizCode, workflowModel.ProjectDownGrade, "", &workflow.StartProcessInstanceRequest{
  1229. ProcessCode: &BusinessDowngradeRequestProcessCode,
  1230. FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
  1231. {
  1232. Id: utils.String("TextField-K2AD4O5B"),
  1233. Name: utils.String("项目编码"),
  1234. Value: utils.String(business.NboCode),
  1235. },
  1236. {
  1237. Id: utils.String("TextField_BDLSECETVSG0"),
  1238. Name: utils.String("项目名称"),
  1239. Value: utils.String(business.NboName),
  1240. },
  1241. {
  1242. Id: utils.String("TextField_1J9BJMOZ18F40"),
  1243. Name: utils.String("客户名称"),
  1244. Value: utils.String(business.CustName),
  1245. },
  1246. {
  1247. Id: utils.String("TextField_GL7MQUB723K0"),
  1248. Name: utils.String("所在省"),
  1249. Value: utils.String(business.CustProvince),
  1250. },
  1251. {
  1252. Id: utils.String("TextField_CFA88QQQUUO0"),
  1253. Name: utils.String("所在市"),
  1254. Value: utils.String(business.CustCity),
  1255. },
  1256. {
  1257. Id: utils.String("DDSelectField_VSA3U380ZK00"),
  1258. Name: utils.String("降级类型"),
  1259. Value: utils.String(downgradeType),
  1260. },
  1261. {
  1262. Id: utils.String("DDSelectField_1UCNHJ0P8C5C0"),
  1263. Name: utils.String("产品线"),
  1264. Value: utils.String(productLine),
  1265. },
  1266. {
  1267. Id: utils.String("TextField_X4D3QGARU7K0"),
  1268. Name: utils.String("支持内容"),
  1269. Value: utils.String("无"),
  1270. },
  1271. {
  1272. Id: utils.String("TextField_AEUWH63LJ0O0"),
  1273. Name: utils.String("销售工程师"),
  1274. Value: utils.String(business.SaleName),
  1275. },
  1276. {
  1277. Id: utils.String("TextareaField_PTGJOKD3J7K0"),
  1278. Name: utils.String("降级原因"),
  1279. Value: utils.String(req.Remark),
  1280. },
  1281. },
  1282. })
  1283. if err != nil {
  1284. g.Log().Error(err)
  1285. return err
  1286. }
  1287. return nil
  1288. })
  1289. return err
  1290. }
  1291. // BusinessDowngradeNotify 项目降级 审批结果通知
  1292. func (p *businessService) BusinessDowngradeNotify(flow *workflowModel.PlatWorkflow, msg *message.MixMessage) error {
  1293. business, err := p.checkDingTalkNotify(flow, msg)
  1294. if err != nil {
  1295. return err
  1296. }
  1297. var data = g.Map{}
  1298. var remark string
  1299. if msg.ProcessType == "terminate" {
  1300. data[p.Dao.C.ApproStatus] = ApprovalReturn
  1301. }
  1302. if msg.ProcessType == "finish" && msg.Result == "refuse" {
  1303. data[p.Dao.C.ApproStatus] = ApprovalRejection
  1304. }
  1305. if msg.ProcessType == "finish" && msg.Result == "agree" {
  1306. // 从项目动态内获取变更信息
  1307. dynamics := new(model.ProjBusinessDynamics)
  1308. dynamicsDao := projDao.NewProjBusinessDynamicsDao(p.Tenant).Where(projDao.ProjBusinessDynamics.C.BusId, business.Id)
  1309. err = dynamicsDao.Where(projDao.ProjBusinessDynamics.C.OpnType, OpnDowngrade).OrderDesc("created_time").Scan(dynamics)
  1310. if err != nil {
  1311. return err
  1312. }
  1313. updateData := new(model.BusinessDowngradeReq)
  1314. gconv.Struct(dynamics.OpnContent, updateData)
  1315. data = gconv.Map(updateData)
  1316. data[p.Dao.C.ApproStatus] = ApprovalOK
  1317. remarkMap := gconv.Map(dynamics.OpnContent)
  1318. remark = gconv.String(g.Map{"nboType": remarkMap["nboType"], "origNboType": remarkMap["origNboType"]})
  1319. }
  1320. // 项目修改
  1321. _, err = p.Dao.WherePri(business.Id).FieldsEx(service.UpdateFieldEx...).Data(data).Update()
  1322. if err != nil {
  1323. return err
  1324. }
  1325. // 添加项目动态
  1326. dynamics := model.ProjBusinessDynamics{
  1327. BusId: business.Id,
  1328. OpnType: OpnDowngradeApproval,
  1329. Remark: remark,
  1330. }
  1331. _, err = p.CreateProjBusinessDynamics(nil, dynamics, data)
  1332. if err != nil {
  1333. return err
  1334. }
  1335. return nil
  1336. }
  1337. // SetPrimacyContact 项目设置首要联系人
  1338. func (p *businessService) SetPrimacyContact(req *model.BusinessPrimacyContactReq) (err error) {
  1339. business, err := p.Dao.Where(projDao.ProjBusiness.C.Id, req.Id).One()
  1340. if err != nil {
  1341. return err
  1342. }
  1343. if business == nil {
  1344. return myerrors.TipsError("项目不存在。")
  1345. }
  1346. businessMap := g.Map{
  1347. p.Dao.C.ContactId: req.ContactId,
  1348. p.Dao.C.ContactName: req.ContactName,
  1349. p.Dao.C.ContactPostion: req.ContactPostion,
  1350. p.Dao.C.ContactTelephone: req.ContactTelephone,
  1351. }
  1352. service.SetUpdatedInfo(businessMap, p.GetCxtUserId(), p.GetCxtUserName())
  1353. opnContent := gconv.Map(gconv.String(businessMap))
  1354. opnContent["origContactId"] = business.ContactId
  1355. opnContent["origContactName"] = business.ContactName
  1356. opnContent["origContactPostion"] = business.ContactPostion
  1357. opnContent["origContactTelephone"] = business.ContactTelephone
  1358. err = p.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  1359. // 更新项目
  1360. _, err = p.Dao.TX(tx).WherePri(projDao.ProjBusiness.C.Id, req.Id).Data(businessMap).Update()
  1361. if err != nil {
  1362. return err
  1363. }
  1364. // 添加项目动态
  1365. dynamics := model.ProjBusinessDynamics{
  1366. BusId: req.Id,
  1367. OpnType: OpnPrimacyContact,
  1368. Remark: req.Remark,
  1369. }
  1370. _, err = p.CreateProjBusinessDynamics(tx, dynamics, opnContent)
  1371. return err
  1372. })
  1373. return err
  1374. }
  1375. // UpdateBusinessStatus 更新项目状态
  1376. func (p *businessService) UpdateBusinessStatus(req *model.UpdateBusinessStatusReq) error {
  1377. business, err := p.Dao.WherePri(req.Id).One()
  1378. if err != nil {
  1379. return err
  1380. }
  1381. if business == nil {
  1382. return myerrors.TipsError("项目不存在。")
  1383. }
  1384. businessMap := g.Map{
  1385. p.Dao.C.NboStatus: req.NboStatus,
  1386. p.Dao.C.Remark: req.Remark,
  1387. }
  1388. service.SetUpdatedInfo(businessMap, p.GetCxtUserId(), p.GetCxtUserName())
  1389. opnContent := gconv.Map(gconv.String(businessMap))
  1390. opnContent["origNboStatus"] = business.NboStatus
  1391. err = p.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  1392. // 更新项目
  1393. _, err = p.Dao.TX(tx).WherePri(projDao.ProjBusiness.C.Id, req.Id).Data(businessMap).Update()
  1394. if err != nil {
  1395. return err
  1396. }
  1397. // 添加项目动态
  1398. dynamics := model.ProjBusinessDynamics{
  1399. BusId: req.Id,
  1400. OpnType: OpnStatus,
  1401. Remark: req.Remark,
  1402. }
  1403. _, err = p.CreateProjBusinessDynamics(tx, dynamics, opnContent)
  1404. return err
  1405. })
  1406. return err
  1407. }
  1408. // CreateProjBusinessDynamics 创建项目动态
  1409. func (p *businessService) CreateProjBusinessDynamics(tx *gdb.TX, dynamics model.ProjBusinessDynamics, opnContent interface{}) (int64, error) {
  1410. if v, ok := opnContent.(g.Map); ok {
  1411. opnContent = utils.MapKeySnakeCamelCase(v)
  1412. }
  1413. // 添加项目动态
  1414. dynamics.OpnPeopleId = p.GetCxtUserId()
  1415. dynamics.OpnPeople = p.GetCxtUserName()
  1416. dynamics.OpnDate = gtime.Now()
  1417. dynamics.OpnContent = gconv.String(opnContent)
  1418. service.SetCreatedInfo(&dynamics, p.GetCxtUserId(), p.GetCxtUserName())
  1419. dao := projDao.NewProjBusinessDynamicsDao(p.Tenant).M
  1420. if tx != nil {
  1421. dao = dao.TX(tx)
  1422. }
  1423. lastId, err := dao.InsertAndGetId(&dynamics)
  1424. return lastId, err
  1425. }
  1426. // ConvertToReserve 转为储备项目
  1427. func (p *businessService) ConvertToReserve(req *model.BusinessToReserveReq) error {
  1428. business, err := p.Dao.WherePri(req.Id).WhereNot(p.Dao.C.ApproStatus, ApprovalWaiting).One()
  1429. if err != nil {
  1430. return err
  1431. }
  1432. if business == nil {
  1433. return myerrors.TipsError("项目已提交审批任务,无法重复提交。")
  1434. }
  1435. productLine, _ := service.GetDictLabelByTypeAndValue(p.Ctx, "sys_product_line", business.ProductLine)
  1436. // 审批流
  1437. workflowSrv, _ := workflowService.NewFlowService(p.Ctx)
  1438. err = p.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  1439. // 更新项目
  1440. businessMap := g.Map{
  1441. p.Dao.C.ApproStatus: ApprovalWaiting,
  1442. p.Dao.C.ProjConversionTime: gtime.Now(),
  1443. p.Dao.C.ProjConversionReason: req.ProjConversionReason,
  1444. }
  1445. service.SetUpdatedInfo(businessMap, p.GetCxtUserId(), p.GetCxtUserName())
  1446. _, err = p.Dao.TX(tx).WherePri(business.Id).Data(businessMap).Update()
  1447. if err != nil {
  1448. return err
  1449. }
  1450. // 添加项目动态
  1451. dynamics := model.ProjBusinessDynamics{
  1452. BusId: business.Id,
  1453. OpnType: OpnToReserve,
  1454. Remark: req.ProjConversionReason,
  1455. }
  1456. _, err = p.CreateProjBusinessDynamics(tx, dynamics, businessMap)
  1457. if err != nil {
  1458. return err
  1459. }
  1460. // OMS项目转储备 审批
  1461. bizCode := business.NboCode + ":" + strconv.Itoa(business.Id)
  1462. _, err = workflowSrv.StartProcessInstance(bizCode, workflowModel.ProjectToReserve, "", &workflow.StartProcessInstanceRequest{
  1463. ProcessCode: &ConvertToReserveRequestProcessCode,
  1464. FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
  1465. {
  1466. Id: utils.String("TextField-K2AD4O5B"),
  1467. Name: utils.String("项目编码"),
  1468. Value: utils.String(business.NboCode),
  1469. },
  1470. {
  1471. Id: utils.String("TextField_CMH6TBXYR5S0"),
  1472. Name: utils.String("项目名称"),
  1473. Value: utils.String(business.NboName),
  1474. },
  1475. {
  1476. Id: utils.String("TextField_YQBGGYHQPS00"),
  1477. Name: utils.String("客户名称"),
  1478. Value: utils.String(business.CustName),
  1479. },
  1480. {
  1481. Id: utils.String("DDSelectField_VBY9YAIOK5C0"),
  1482. Name: utils.String("项目级别"),
  1483. Value: utils.String(convertToReserveType[business.NboType]),
  1484. },
  1485. {
  1486. Id: utils.String("DDSelectField_1UVBB1LZHIJK0"),
  1487. Name: utils.String("产品线"),
  1488. Value: utils.String(productLine),
  1489. },
  1490. {
  1491. Id: utils.String("TextField_1NDD3TY8KJB40"),
  1492. Name: utils.String("销售工程师"),
  1493. Value: utils.String(business.SaleName),
  1494. },
  1495. {
  1496. Id: utils.String("TextareaField_15KZFM4YHQ8W0"),
  1497. Name: utils.String("转化原因"),
  1498. Value: utils.String(req.ProjConversionReason),
  1499. },
  1500. },
  1501. })
  1502. if err != nil {
  1503. g.Log().Error(err)
  1504. return err
  1505. }
  1506. return nil
  1507. })
  1508. return err
  1509. }
  1510. // ConvertToReserveNotify 转为储备项目 审批结果通知
  1511. func (p *businessService) ConvertToReserveNotify(flow *workflowModel.PlatWorkflow, msg *message.MixMessage) error {
  1512. business, err := p.checkDingTalkNotify(flow, msg)
  1513. if err != nil {
  1514. return err
  1515. }
  1516. var data = g.Map{}
  1517. if msg.ProcessType == "terminate" {
  1518. data[p.Dao.C.ApproStatus] = ApprovalReturn
  1519. }
  1520. if msg.ProcessType == "finish" && msg.Result == "refuse" {
  1521. data[p.Dao.C.ApproStatus] = ApprovalRejection
  1522. }
  1523. if msg.ProcessType == "finish" && msg.Result == "agree" {
  1524. data[p.Dao.C.NboType] = StatusReserve
  1525. data[p.Dao.C.ApproStatus] = ApprovalOK
  1526. }
  1527. // 项目修改
  1528. _, err = p.Dao.WherePri(business.Id).FieldsEx(service.UpdateFieldEx...).Data(data).Update()
  1529. if err != nil {
  1530. return err
  1531. }
  1532. // 添加项目动态
  1533. dynamics := model.ProjBusinessDynamics{
  1534. BusId: business.Id,
  1535. OpnType: OpnToReserveApproval,
  1536. }
  1537. _, err = p.CreateProjBusinessDynamics(nil, dynamics, data)
  1538. if err != nil {
  1539. return err
  1540. }
  1541. return err
  1542. }
  1543. // 钉钉审批通知检查
  1544. func (p *businessService) checkDingTalkNotify(flow *workflowModel.PlatWorkflow, msg *message.MixMessage) (*model.ProjBusiness, error) {
  1545. bizCode := strings.Split(flow.BizCode, ":")
  1546. if len(bizCode) != 2 {
  1547. return nil, fmt.Errorf("项目审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id)
  1548. }
  1549. nboCode := bizCode[0]
  1550. busId, err := strconv.Atoi(bizCode[1])
  1551. if err != nil {
  1552. return nil, fmt.Errorf("项目审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id)
  1553. }
  1554. if msg.ProcessType != "finish" && msg.ProcessType != "terminate" {
  1555. return nil, fmt.Errorf("无法识别的 ProcessType :%s", msg.ProcessType)
  1556. }
  1557. if msg.Result != "agree" && msg.Result != "refuse" && msg.Result != "" {
  1558. return nil, fmt.Errorf("无法识别的 Result :%s", msg.Result)
  1559. }
  1560. fmt.Println(msg)
  1561. business, err := p.Dao.WherePri(busId).Where(p.Dao.C.NboCode, nboCode).One()
  1562. if err != nil {
  1563. return nil, err
  1564. }
  1565. if business == nil {
  1566. return nil, fmt.Errorf("项目不存在:%s Id: %d", flow.BizCode, flow.Id)
  1567. }
  1568. return business, nil
  1569. }