base_distributor.go 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267
  1. package base
  2. import (
  3. "context"
  4. "database/sql"
  5. "encoding/json"
  6. "fmt"
  7. "io/ioutil"
  8. "net/http"
  9. "os"
  10. "path"
  11. "strconv"
  12. "strings"
  13. "time"
  14. "dashoo.cn/opms_libary/micro_srv"
  15. "dashoo.cn/opms_libary/myerrors"
  16. "dashoo.cn/opms_libary/plugin/dingtalk"
  17. "github.com/gogf/gf/database/gdb"
  18. "github.com/gogf/gf/frame/g"
  19. "github.com/gogf/gf/os/gtime"
  20. "github.com/gogf/gf/util/gconv"
  21. "github.com/gogf/gf/util/gvalid"
  22. "dashoo.cn/micro/app/dao/base"
  23. contractdao "dashoo.cn/micro/app/dao/contract"
  24. projdao "dashoo.cn/micro/app/dao/proj"
  25. model "dashoo.cn/micro/app/model/base"
  26. contractmodel "dashoo.cn/micro/app/model/contract"
  27. projmodel "dashoo.cn/micro/app/model/proj"
  28. workflowmodel "dashoo.cn/micro/app/model/workflow"
  29. "dashoo.cn/micro/app/service"
  30. workflowService "dashoo.cn/micro/app/service/workflow"
  31. "dashoo.cn/opms_libary/plugin/dingtalk/message"
  32. "dashoo.cn/opms_libary/plugin/dingtalk/workflow"
  33. "dashoo.cn/opms_libary/utils"
  34. )
  35. type distributorService struct {
  36. *service.ContextService
  37. Dao *base.BaseDistributorDao
  38. DynamicsDao *base.BaseDistributorDynamicsDao
  39. TargetDao *base.BaseDistributorTargetDao
  40. RecordDao *base.BaseDistributorRecordDao
  41. ProjDao *projdao.ProjBusinessDao
  42. ContractDao *contractdao.CtrContractDao
  43. }
  44. func NewDistributorService(ctx context.Context) (svc *distributorService, err error) {
  45. svc = new(distributorService)
  46. if svc.ContextService, err = svc.Init(ctx); err != nil {
  47. return nil, err
  48. }
  49. svc.Dao = base.NewBaseDistributorDao(svc.Tenant)
  50. svc.DynamicsDao = base.NewBaseDistributorDynamicsDao(svc.Tenant)
  51. svc.ProjDao = projdao.NewProjBusinessDao(svc.Tenant)
  52. svc.ContractDao = contractdao.NewCtrContractDao(svc.Tenant)
  53. svc.TargetDao = base.NewBaseDistributorTargetDao(svc.Tenant)
  54. svc.RecordDao = base.NewBaseDistributorRecordDao(svc.Tenant)
  55. return svc, nil
  56. }
  57. // GetList 经销商信息列表
  58. func (s *distributorService) GetList(ctx context.Context, req *model.BaseDistributorSearchReq) (total int, distributorList []*model.BaseDistributorListRsp, err error) {
  59. distributorModel := s.Dao.FieldsEx(s.Dao.C.DeletedTime)
  60. distributorModel = distributorModel.DataScope(ctx, "belong_sale_id")
  61. if req.DistCode != "" {
  62. distributorModel = distributorModel.WhereLike(s.Dao.C.DistCode, "%"+req.DistCode+"%")
  63. }
  64. if req.DistName != "" {
  65. distributorModel = distributorModel.WhereLike(s.Dao.C.DistName, "%"+req.DistName+"%")
  66. }
  67. if req.BelongSale != "" {
  68. distributorModel = distributorModel.WhereLike(s.Dao.C.BelongSale, "%"+req.BelongSale+"%")
  69. }
  70. if len(req.ProvinceId) > 0 {
  71. distributorModel = distributorModel.WhereIn(s.Dao.C.ProvinceId, req.ProvinceId)
  72. }
  73. if req.DistType != "" {
  74. distributorModel = distributorModel.WhereIn(s.Dao.C.DistType, req.DistType)
  75. }
  76. total, err = distributorModel.Count()
  77. if err != nil {
  78. err = myerrors.DbError("获取总行数失败。")
  79. return
  80. }
  81. err = distributorModel.Page(req.GetPage()).Order("id desc").Scan(&distributorList)
  82. if req.WithStatistic {
  83. for i, dist := range distributorList {
  84. statistic, err := s.statistic(dist.Id)
  85. if err != nil {
  86. return 0, nil, err
  87. }
  88. distributorList[i].BaseDistributorStatistic = statistic
  89. }
  90. }
  91. return
  92. }
  93. func (s *distributorService) statistic(id int) (stat model.BaseDistributorStatistic, err error) {
  94. 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)
  95. if err != nil {
  96. return stat, err
  97. }
  98. stat.ProjectNum = v.Int()
  99. 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)
  100. if err != nil {
  101. return stat, err
  102. }
  103. stat.AllProductAmount = v.Float64()
  104. 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)
  105. if err != nil {
  106. return stat, err
  107. }
  108. stat.SaledProjectNum = v.Int()
  109. 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)
  110. if err != nil {
  111. return stat, err
  112. }
  113. stat.SaledAmount = v.Float64()
  114. 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)
  115. if err != nil {
  116. return stat, err
  117. }
  118. stat.UnpaidAmount = v.Float64()
  119. 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)
  120. if err != nil {
  121. return stat, err
  122. }
  123. stat.InvoicedAmount = v.Float64()
  124. return
  125. }
  126. // 获取经销商编号
  127. func (s *distributorService) getDistributorCode(distCode string) (string, error) {
  128. sequence, err := service.Sequence(s.Dao.DB, "distributor_code")
  129. if err != nil {
  130. return "", err
  131. }
  132. return distCode + sequence, nil
  133. }
  134. // Create 经销商创建
  135. func (s *distributorService) Create(ctx context.Context, req *model.AddDistributor) (int64, error) {
  136. if req.DistType == "10" {
  137. if req.DistName == "" {
  138. return 0, myerrors.TipsError("经销商名称不能为空")
  139. }
  140. if req.ProvinceId == 0 {
  141. return 0, myerrors.TipsError("所属省份Id不能为空")
  142. }
  143. if req.ProvinceDesc == "" {
  144. return 0, myerrors.TipsError("所属省份名称不能为空")
  145. }
  146. if req.RegisterDistrict == "" {
  147. return 0, myerrors.TipsError("注册地不能为空")
  148. }
  149. } else {
  150. if err := gvalid.CheckStruct(ctx, req, nil); err != nil {
  151. return 0, err
  152. }
  153. }
  154. DistributorData := new(model.BaseDistributor)
  155. if err := gconv.Struct(req, DistributorData); err != nil {
  156. return 0, err
  157. }
  158. code, err := s.getDistributorCode("JXS")
  159. if err != nil {
  160. return 0, err
  161. }
  162. DistributorData.DistCode = code
  163. if DistributorData.DistType == "20" {
  164. DistributorData.ApproItem = "创建代理商"
  165. DistributorData.ApproStatus = "20"
  166. if req.ContractUrl != "" && req.ContractFileName == "" {
  167. return 0, myerrors.TipsError("合同文件名不能为空")
  168. }
  169. }
  170. service.SetCreatedInfo(DistributorData, s.GetCxtUserId(), s.GetCxtUserName())
  171. var id int64
  172. txerr := s.Dao.DB.Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error {
  173. id, err = tx.InsertAndGetId("base_distributor", DistributorData)
  174. if err != nil {
  175. return err
  176. }
  177. DistributorData.Id = int(id)
  178. if DistributorData.DistType == "20" {
  179. err = s.createDingtalkProcess(ctx, DistributorData, req.ContractFileName)
  180. if err != nil {
  181. return err
  182. }
  183. }
  184. err = s.AddDynamicsByCurrentUser(tx, int(id), "创建经销商/代理商", map[string]interface{}{})
  185. return err
  186. })
  187. return id, txerr
  188. }
  189. var ProcessCodeDistProxyCreate = "PROC-9494B87D-DE96-49EE-B676-D3913911BE21" // 创建代理商
  190. func (s *distributorService) createDingtalkProcess(ctx context.Context, ent *model.BaseDistributor, contractFileName string) error {
  191. var fileinfoByte []byte
  192. if ent.ContractUrl != "" {
  193. var err error
  194. fileinfoByte, err = UploadDingtalk(s.CxtUser.DingtalkId, ent.ContractUrl, contractFileName)
  195. if err != nil {
  196. return err
  197. }
  198. }
  199. workflowSrv, err := workflowService.NewFlowService(ctx)
  200. if err != nil {
  201. return err
  202. }
  203. bizCode := strconv.Itoa(ent.Id)
  204. form := []*workflow.StartProcessInstanceRequestFormComponentValues{
  205. {
  206. Id: utils.String("TextField-K2AD4O5B"),
  207. Name: utils.String("代理商名称"),
  208. Value: utils.String(ent.DistName),
  209. },
  210. {
  211. Id: utils.String("TextField_DZ2HNXRKHCG"),
  212. Name: utils.String("所在省"),
  213. Value: utils.String(ent.ProvinceDesc),
  214. },
  215. {
  216. Id: utils.String("TextField_1M07EV7YVOPS0"),
  217. Name: utils.String("业务范围"),
  218. Value: utils.String(ent.BusinessScope),
  219. },
  220. {
  221. Id: utils.String("TextField_UGJ0UKCU5DS0"),
  222. Name: utils.String("注册资金(万元)"),
  223. Value: utils.String(strconv.FormatFloat(ent.Capital, 'f', 2, 64)),
  224. },
  225. {
  226. Id: utils.String("TextField_1RC4FO1WUZ4W0"),
  227. Name: utils.String("注册地"),
  228. Value: utils.String(ent.RegisterDistrict),
  229. },
  230. {
  231. Id: utils.String("TextField_FKM6LUQYLFS0"),
  232. Name: utils.String("现有销售人数"),
  233. Value: utils.String(strconv.Itoa(ent.SaleNum)),
  234. },
  235. {
  236. Id: utils.String("TextField_1L89WCJM3ZMO0"),
  237. Name: utils.String("已有代理名牌和产品"),
  238. Value: utils.String(ent.ExistedProduct),
  239. },
  240. {
  241. Id: utils.String("TextField_P5JA5OZ5XKW0"),
  242. Name: utils.String("历史合作的终端客户名称"),
  243. Value: utils.String(ent.HistoryCustomer),
  244. },
  245. }
  246. if len(fileinfoByte) != 0 {
  247. form = append(form, &workflow.StartProcessInstanceRequestFormComponentValues{
  248. Id: utils.String("DDAttachment_SD6QFFBOSAO0"),
  249. Name: utils.String("代理合同"),
  250. Value: utils.String(string(fileinfoByte)),
  251. })
  252. }
  253. _, err = workflowSrv.StartProcessInstance(bizCode, workflowmodel.DistProxyCreate, "", &workflow.StartProcessInstanceRequest{
  254. ProcessCode: &ProcessCodeDistProxyCreate,
  255. FormComponentValues: form,
  256. })
  257. return err
  258. }
  259. // GetEntityById 详情
  260. func (s *distributorService) GetEntityById(id int64) (distributorInfo *model.BaseDistributorListRsp, err error) {
  261. err = s.Dao.Where(base.BaseProduct.C.Id, id).Scan(&distributorInfo)
  262. if err != nil {
  263. return nil, err
  264. }
  265. statistic, err := s.statistic(int(id))
  266. if err != nil {
  267. return nil, err
  268. }
  269. distributorInfo.BaseDistributorStatistic = statistic
  270. target, err := s.TargetDao.Where("dist_id = ?", id).Where("year = ?", time.Now().Year()).One()
  271. if err != nil {
  272. return nil, err
  273. }
  274. if target != nil {
  275. distributorInfo.YearTarget = target.Total
  276. }
  277. return
  278. }
  279. // UpdateById 修改数据
  280. func (s *distributorService) UpdateById(req *model.UpdateDistributorReq) (err error) {
  281. ent, err := s.Dao.Where("id = ", req.Id).One()
  282. if err != nil {
  283. g.Log().Error(err)
  284. return
  285. }
  286. if ent == nil {
  287. err = myerrors.TipsError("无修改数据")
  288. return
  289. }
  290. if ent.ApproStatus == "20" {
  291. err = myerrors.TipsError("不能修改待审核数据")
  292. return
  293. }
  294. distData := new(model.BaseDistributor)
  295. if err = gconv.Struct(req, distData); err != nil {
  296. return
  297. }
  298. service.SetUpdatedInfo(distData, s.GetCxtUserId(), s.GetCxtUserName())
  299. _, err = s.Dao.FieldsEx(s.Dao.C.DistCode, s.Dao.C.Id,
  300. s.Dao.C.CreatedName, s.Dao.C.CreatedBy, s.Dao.C.CreatedTime).WherePri(s.Dao.C.Id, req.Id).Update(distData)
  301. if err != nil {
  302. g.Log().Error(err)
  303. return
  304. }
  305. err = s.Dao.DB.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  306. err = s.AddDynamicsByCurrentUser(tx, req.Id, "更新经销商/代理商", map[string]interface{}{})
  307. return err
  308. })
  309. return
  310. }
  311. func (s *distributorService) ToProxy(ctx context.Context, req *model.DistributorToProxyReq) (err error) {
  312. validErr := gvalid.CheckStruct(ctx, req, nil)
  313. if validErr != nil {
  314. return myerrors.TipsError(validErr.Current().Error())
  315. }
  316. if req.ContractUrl != "" && req.ContractFileName == "" {
  317. return myerrors.TipsError("合同文件名不能为空")
  318. }
  319. ent, err := s.Dao.Where("id = ?", req.Id).One()
  320. if err != nil {
  321. return err
  322. }
  323. if ent == nil {
  324. return myerrors.TipsError(fmt.Sprintf("代理商/经销商不存在: %d", req.Id))
  325. }
  326. approvalData := model.ToProxyApproveData{
  327. CustomerType: req.CustomerType,
  328. ProxyStartTime: req.ProxyStartTime,
  329. ProxyEndTime: req.ProxyEndTime,
  330. ProxyDistrict: req.ProxyDistrict,
  331. ContractUrl: req.ContractUrl,
  332. OperatedId: s.CxtUser.Id,
  333. OperatedName: s.CxtUser.NickName,
  334. }
  335. approvalDataByte, err := json.Marshal(approvalData)
  336. if err != nil {
  337. return err
  338. }
  339. txerr := s.Dao.DB.Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error {
  340. _, err = tx.Update("base_distributor", map[string]interface{}{
  341. "appro_status": "20",
  342. "appro_data": string(approvalDataByte),
  343. "appro_item": "经销商转代理商",
  344. }, "id = ?", req.Id)
  345. if err != nil {
  346. return err
  347. }
  348. return s.toProxyDingtalkProcess(ctx, ent, req)
  349. })
  350. return txerr
  351. }
  352. var ProcessCodeDistToProxy = "PROC-39C96165-131C-48EC-B8C0-AA528E0C9F3A" // 经销商转代理商
  353. func (s *distributorService) toProxyDingtalkProcess(ctx context.Context, ent *model.BaseDistributor, req *model.DistributorToProxyReq) error {
  354. var fileinfoByte []byte
  355. if req.ContractUrl != "" {
  356. var err error
  357. fileinfoByte, err = UploadDingtalk(s.CxtUser.DingtalkId, req.ContractUrl, req.ContractFileName)
  358. if err != nil {
  359. return err
  360. }
  361. }
  362. cusTypeMap, err := service.GetDictDataByType(ctx, "cust_idy")
  363. if err != nil {
  364. return err
  365. }
  366. cusType := []string{}
  367. for _, t := range strings.Split(req.CustomerType, ",") {
  368. if v := cusTypeMap[t]; v != "" {
  369. cusType = append(cusType, v)
  370. }
  371. }
  372. custTypeByte, err := json.Marshal(cusType)
  373. if err != nil {
  374. return err
  375. }
  376. proxyTime := req.ProxyStartTime.Time.Format("2006/01/02") + "-" +
  377. req.ProxyEndTime.Time.Format("2006/01/02")
  378. workflowSrv, err := workflowService.NewFlowService(ctx)
  379. if err != nil {
  380. return err
  381. }
  382. form := []*workflow.StartProcessInstanceRequestFormComponentValues{
  383. {
  384. Id: utils.String("TextField-K2AD4O5B"),
  385. Name: utils.String("代理商名称"),
  386. Value: utils.String(ent.DistName),
  387. },
  388. {
  389. Id: utils.String("DDSelectField_X3ALRAZA4BK0"),
  390. Name: utils.String("授权客户类型"),
  391. Value: utils.String(string(custTypeByte)),
  392. },
  393. {
  394. Id: utils.String("TextField_1M07EV7YVOPS0"),
  395. Name: utils.String("授权代理区域"),
  396. Value: utils.String(req.ProxyDistrict),
  397. },
  398. {
  399. Id: utils.String("TextField_UGJ0UKCU5DS0"),
  400. Name: utils.String("代理签约有效期"),
  401. Value: utils.String(proxyTime),
  402. },
  403. }
  404. if len(fileinfoByte) != 0 {
  405. form = append(form, &workflow.StartProcessInstanceRequestFormComponentValues{
  406. Id: utils.String("DDAttachment_SD6QFFBOSAO0"),
  407. Name: utils.String("代理合同"),
  408. Value: utils.String(string(fileinfoByte)),
  409. })
  410. }
  411. bizCode := strconv.Itoa(ent.Id)
  412. _, err = workflowSrv.StartProcessInstance(bizCode, workflowmodel.DistToProxy, "", &workflow.StartProcessInstanceRequest{
  413. ProcessCode: &ProcessCodeDistToProxy,
  414. FormComponentValues: form,
  415. })
  416. return err
  417. }
  418. func (s *distributorService) Renew(ctx context.Context, req *model.DistributorRenewReq) (err error) {
  419. validErr := gvalid.CheckStruct(ctx, req, nil)
  420. if validErr != nil {
  421. return myerrors.TipsError(validErr.Current().Error())
  422. }
  423. if req.ContractUrl != "" && req.ContractFileName == "" {
  424. return myerrors.TipsError("合同文件名不能为空")
  425. }
  426. ent, err := s.Dao.Where("id = ?", req.Id).One()
  427. if err != nil {
  428. return err
  429. }
  430. if ent == nil {
  431. return myerrors.TipsError(fmt.Sprintf("代理商/经销商不存在: %d", req.Id))
  432. }
  433. approvalData := model.RenewApproveData{
  434. CustomerType: req.CustomerType,
  435. ProxyStartTime: req.ProxyStartTime,
  436. ProxyEndTime: req.ProxyEndTime,
  437. ProxyDistrict: req.ProxyDistrict,
  438. ContractUrl: req.ContractUrl,
  439. OperatedId: s.CxtUser.Id,
  440. OperatedName: s.CxtUser.NickName,
  441. }
  442. approvalDataByte, err := json.Marshal(approvalData)
  443. if err != nil {
  444. return err
  445. }
  446. txerr := s.Dao.DB.Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error {
  447. _, err = tx.Update("base_distributor", map[string]interface{}{
  448. "appro_status": "20",
  449. "appro_data": string(approvalDataByte),
  450. "appro_item": "代理商续签",
  451. }, "id = ?", req.Id)
  452. if err != nil {
  453. return err
  454. }
  455. return s.renewDingtalkProcess(ctx, ent, req)
  456. })
  457. return txerr
  458. }
  459. var ProcessCodeDistRenew = "PROC-33514974-4E38-430F-A852-D5694944F20B" // 代理商续签
  460. func (s *distributorService) renewDingtalkProcess(ctx context.Context, ent *model.BaseDistributor, req *model.DistributorRenewReq) error {
  461. var fileinfoByte []byte
  462. if req.ContractUrl != "" {
  463. var err error
  464. fileinfoByte, err = UploadDingtalk(s.CxtUser.DingtalkId, req.ContractUrl, req.ContractFileName)
  465. if err != nil {
  466. return err
  467. }
  468. }
  469. cusTypeMap, err := service.GetDictDataByType(ctx, "cust_idy")
  470. if err != nil {
  471. return err
  472. }
  473. cusType := []string{}
  474. for _, t := range strings.Split(req.CustomerType, ",") {
  475. if v := cusTypeMap[t]; v != "" {
  476. cusType = append(cusType, v)
  477. }
  478. }
  479. custTypeByte, err := json.Marshal(cusType)
  480. if err != nil {
  481. return err
  482. }
  483. proxyTime := req.ProxyStartTime.Time.Format("2006/01/02") + "-" +
  484. req.ProxyEndTime.Time.Format("2006/01/02")
  485. workflowSrv, err := workflowService.NewFlowService(ctx)
  486. if err != nil {
  487. return err
  488. }
  489. form := []*workflow.StartProcessInstanceRequestFormComponentValues{
  490. {
  491. Id: utils.String("TextField-K2AD4O5B"),
  492. Name: utils.String("代理商名称"),
  493. Value: utils.String(ent.DistName),
  494. },
  495. {
  496. Id: utils.String("DDSelectField_X3ALRAZA4BK0"),
  497. Name: utils.String("授权客户类型"),
  498. Value: utils.String(string(custTypeByte)),
  499. },
  500. {
  501. Id: utils.String("TextField_1M07EV7YVOPS0"),
  502. Name: utils.String("授权代理区域"),
  503. Value: utils.String(req.ProxyDistrict),
  504. },
  505. {
  506. Id: utils.String("TextField_UGJ0UKCU5DS0"),
  507. Name: utils.String("代理签约有效期"),
  508. Value: utils.String(proxyTime),
  509. },
  510. }
  511. if len(fileinfoByte) != 0 {
  512. form = append(form, &workflow.StartProcessInstanceRequestFormComponentValues{
  513. Id: utils.String("DDAttachment_SD6QFFBOSAO0"),
  514. Name: utils.String("代理合同"),
  515. Value: utils.String(string(fileinfoByte)),
  516. })
  517. }
  518. bizCode := strconv.Itoa(ent.Id)
  519. _, err = workflowSrv.StartProcessInstance(bizCode, workflowmodel.DistProxyRenew, "", &workflow.StartProcessInstanceRequest{
  520. ProcessCode: &ProcessCodeDistRenew,
  521. FormComponentValues: form,
  522. })
  523. return err
  524. }
  525. func (s *distributorService) ToDist(ctx context.Context, req *model.DistributorToDistReq) (err error) {
  526. validErr := gvalid.CheckStruct(ctx, req, nil)
  527. if validErr != nil {
  528. return myerrors.TipsError(validErr.Current().Error())
  529. }
  530. ent, err := s.Dao.Where("id = ?", req.Id).One()
  531. if err != nil {
  532. return err
  533. }
  534. if ent == nil {
  535. return myerrors.TipsError(fmt.Sprintf("代理商/经销商不存在: %d", req.Id))
  536. }
  537. approvalData := model.ToDistApproveData{
  538. ToDistReason: req.ToDistReason,
  539. OperatedId: s.CxtUser.Id,
  540. OperatedName: s.CxtUser.NickName,
  541. }
  542. approvalDataByte, err := json.Marshal(approvalData)
  543. if err != nil {
  544. return err
  545. }
  546. txerr := s.Dao.DB.Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error {
  547. _, err = tx.Update("base_distributor", map[string]interface{}{
  548. "appro_status": "20",
  549. "appro_data": string(approvalDataByte),
  550. "appro_item": "代理商转经销商",
  551. }, "id = ?", req.Id)
  552. if err != nil {
  553. return err
  554. }
  555. return s.toDistDingtalkProcess(ctx, ent, req)
  556. })
  557. return txerr
  558. }
  559. var ProcessCodeProxyToDist = "PROC-59A0E9F5-8233-41D5-B36D-021F3E8B48D2" // 代理商转经销商
  560. func (s *distributorService) toDistDingtalkProcess(ctx context.Context, ent *model.BaseDistributor, req *model.DistributorToDistReq) error {
  561. workflowSrv, err := workflowService.NewFlowService(ctx)
  562. if err != nil {
  563. return err
  564. }
  565. form := []*workflow.StartProcessInstanceRequestFormComponentValues{
  566. {
  567. Id: utils.String("TextField-K2AD4O5B"),
  568. Name: utils.String("代理商名称"),
  569. Value: utils.String(ent.DistName),
  570. },
  571. {
  572. Id: utils.String("TextareaField_5XMN9CGTDAS0"),
  573. Name: utils.String("转移原因"),
  574. Value: utils.String(req.ToDistReason),
  575. },
  576. }
  577. bizCode := strconv.Itoa(ent.Id)
  578. _, err = workflowSrv.StartProcessInstance(bizCode, workflowmodel.DistToDist, "", &workflow.StartProcessInstanceRequest{
  579. ProcessCode: &ProcessCodeProxyToDist,
  580. FormComponentValues: form,
  581. })
  582. return err
  583. }
  584. func (s *distributorService) TransRecord(ctx context.Context, req *model.DistributorTransRecordReq) (int, []*model.BaseDistributorRecord, error) {
  585. dao := s.RecordDao.As("a")
  586. if req.DistId != 0 {
  587. dao = dao.Where("a.dist_id = ?", req.DistId)
  588. }
  589. total, err := dao.Count()
  590. if err != nil {
  591. return 0, nil, err
  592. }
  593. if req.PageNum != 0 {
  594. dao = dao.Page(req.GetPage())
  595. }
  596. orderby := "a.created_time desc"
  597. if req.OrderBy != "" {
  598. orderby = req.OrderBy
  599. }
  600. dao = dao.Order(orderby)
  601. ents := []*model.BaseDistributorRecord{}
  602. err = dao.Structs(&ents)
  603. if err != nil && err != sql.ErrNoRows {
  604. return 0, nil, err
  605. }
  606. return total, ents, nil
  607. }
  608. // DeleteByIds 删除
  609. func (s *distributorService) DeleteByIds(ids []int64) (err error) {
  610. _, err = s.Dao.WhereIn(s.Dao.C.Id, ids).Delete()
  611. if err != nil {
  612. return err
  613. }
  614. return
  615. }
  616. func (s distributorService) AddDynamicsByCurrentUser(tx *gdb.TX, distId int, opnType string, content map[string]interface{}) error {
  617. contentByte, err := json.Marshal(content)
  618. if err != nil {
  619. return err
  620. }
  621. _, err = tx.InsertAndGetId("base_distributor_dynamics", model.BaseDistributorDynamics{
  622. DistId: distId,
  623. OpnPeopleId: s.GetCxtUserId(),
  624. OpnPeople: s.GetCxtUserName(),
  625. OpnDate: gtime.Now(),
  626. OpnType: opnType,
  627. OpnContent: string(contentByte),
  628. Remark: "",
  629. CreatedBy: s.GetCxtUserId(),
  630. CreatedName: s.GetCxtUserName(),
  631. CreatedTime: gtime.Now(),
  632. UpdatedBy: s.GetCxtUserId(),
  633. UpdatedName: s.GetCxtUserName(),
  634. UpdatedTime: gtime.Now(),
  635. })
  636. return err
  637. }
  638. func (s distributorService) ContractList(ctx context.Context, req *model.DistributorContractListReq) (int, []*contractmodel.CtrContractListRsp, error) {
  639. dao := s.ContractDao.As("a")
  640. if req.DistId != 0 {
  641. dao = dao.Where("a.distributor_id = ?", req.DistId)
  642. }
  643. if req.SearchText != "" {
  644. likestr := fmt.Sprintf("%%%s%%", req.SearchText)
  645. dao = dao.Where("(a.contract_code LIKE ? || a.contract_name LIKE ? || a.cust_name LIKE ? || a.nbo_name LIKE ?)", likestr, likestr, likestr, likestr)
  646. }
  647. if req.ContractCode != "" {
  648. likestr := fmt.Sprintf("%%%s%%", req.ContractCode)
  649. dao = dao.Where("a.contract_code like ?", likestr)
  650. }
  651. if req.ContractName != "" {
  652. likestr := fmt.Sprintf("%%%s%%", req.ContractName)
  653. dao = dao.Where("a.contract_name like ?", likestr)
  654. }
  655. if req.CustId != 0 {
  656. dao = dao.Where("a.cust_id = ?", req.CustId)
  657. }
  658. if req.CustName != "" {
  659. likestr := fmt.Sprintf("%%%s%%", req.CustName)
  660. dao = dao.Where("a.cust_name like ?", likestr)
  661. }
  662. if req.NboId != 0 {
  663. dao = dao.Where("a.nbo_id = ?", req.NboId)
  664. }
  665. if req.NboName != "" {
  666. likestr := fmt.Sprintf("%%%s%%", req.NboName)
  667. dao = dao.Where("a.nbo_name like ?", likestr)
  668. }
  669. if req.ApproStatus != "" {
  670. dao = dao.Where("a.appro_status = ?", req.ApproStatus)
  671. }
  672. if req.ContractType != "" {
  673. dao = dao.Where("a.contract_type = ?", req.ContractType)
  674. }
  675. if req.InchargeId != 0 {
  676. dao = dao.Where("a.incharge_id = ?", req.InchargeId)
  677. }
  678. if req.InchargeName != "" {
  679. likestr := fmt.Sprintf("%%%s%%", req.InchargeName)
  680. dao = dao.Where("a.incharge_name like ?", likestr)
  681. }
  682. if req.SignatoryId != 0 {
  683. dao = dao.Where("a.signatory_id = ?", req.SignatoryId)
  684. }
  685. if req.SignatoryName != "" {
  686. likestr := fmt.Sprintf("%%%s%%", req.SignatoryName)
  687. dao = dao.Where("a.signatory_name like ?", likestr)
  688. }
  689. if req.DistributorName != "" {
  690. likestr := fmt.Sprintf("%%%s%%", req.DistributorName)
  691. dao = dao.Where("a.distributor_name like ?", likestr)
  692. }
  693. if req.BeginTime != "" {
  694. dao = dao.Where("a.created_time > ?", req.BeginTime)
  695. }
  696. if req.EndTime != "" {
  697. dao = dao.Where("a.created_time < ?", req.EndTime)
  698. }
  699. total, err := dao.Count()
  700. if err != nil {
  701. return 0, nil, err
  702. }
  703. if req.PageNum != 0 {
  704. dao = dao.Page(req.GetPage())
  705. }
  706. orderby := "a.created_time desc"
  707. if req.OrderBy != "" {
  708. orderby = req.OrderBy
  709. }
  710. dao = dao.Order(orderby)
  711. ents := []*contractmodel.CtrContractListRsp{}
  712. err = dao.Structs(&ents)
  713. if err != nil && err != sql.ErrNoRows {
  714. return 0, nil, err
  715. }
  716. return total, ents, nil
  717. }
  718. func (s distributorService) ProjectList(ctx context.Context, req *model.DistributorProjectListReq) (int, []*projmodel.ProjBusiness, error) {
  719. dao := &s.ProjDao.ProjBusinessDao
  720. if req.DistId != 0 {
  721. dao = dao.Where("distributor_id = ?", req.DistId)
  722. }
  723. if req.SearchText != "" {
  724. likestr := fmt.Sprintf("%%%s%%", req.SearchText)
  725. dao = dao.Where("(cust_name LIKE ? || nbo_name LIKE ?)", likestr, likestr)
  726. }
  727. if req.NboName != "" {
  728. likestr := fmt.Sprintf("%%%s%%", req.NboName)
  729. dao = dao.Where("nbo_name like ?", likestr)
  730. }
  731. if req.CustName != "" {
  732. likestr := fmt.Sprintf("%%%s%%", req.CustName)
  733. dao = dao.Where("cust_name like ?", likestr)
  734. }
  735. if req.CreatedTimeStart != nil {
  736. dao = dao.Where("created_time > ?", req.CreatedTimeStart)
  737. }
  738. if req.CreatedTimeEnd != nil {
  739. dao = dao.Where("created_time < ?", req.CreatedTimeEnd)
  740. }
  741. total, err := dao.Count()
  742. if err != nil {
  743. return 0, nil, err
  744. }
  745. if req.PageNum != 0 {
  746. dao = dao.Page(req.GetPage())
  747. }
  748. orderby := "created_time desc"
  749. if req.OrderBy != "" {
  750. orderby = req.OrderBy
  751. }
  752. dao = dao.Order(orderby)
  753. ents := []*projmodel.ProjBusiness{}
  754. err = dao.Structs(&ents)
  755. if err != nil && err != sql.ErrNoRows {
  756. return 0, nil, err
  757. }
  758. return total, ents, nil
  759. }
  760. func (s distributorService) DynamicsList(ctx context.Context, req *model.DistributorDynamicsListReq) (int, interface{}, error) {
  761. dao := &s.DynamicsDao.BaseDistributorDynamicsDao
  762. if req.SearchText != "" {
  763. likestr := fmt.Sprintf("%%%s%%", req.SearchText)
  764. dao = dao.Where("(opn_people LIKE ? || opn_content LIKE ?)", likestr, likestr)
  765. }
  766. if req.DistId != 0 {
  767. dao = dao.Where("dist_id = ?", req.DistId)
  768. }
  769. if req.OpnPeopleId != 0 {
  770. dao = dao.Where("opn_people_id = ?", req.OpnPeopleId)
  771. }
  772. if req.OpnPeople != "" {
  773. likestr := fmt.Sprintf("%%%s%%", req.OpnPeople)
  774. dao = dao.Where("opn_people like ?", likestr)
  775. }
  776. if req.OpnType != "" {
  777. dao = dao.Where("opn_type = ?", req.OpnType)
  778. }
  779. if req.BeginTime != "" {
  780. dao = dao.Where("created_time > ?", req.BeginTime)
  781. }
  782. if req.EndTime != "" {
  783. dao = dao.Where("created_time < ?", req.EndTime)
  784. }
  785. total, err := dao.Count()
  786. if err != nil {
  787. return 0, nil, err
  788. }
  789. if req.PageNum != 0 {
  790. dao = dao.Page(req.GetPage())
  791. }
  792. orderby := "created_time desc"
  793. if req.OrderBy != "" {
  794. orderby = req.OrderBy
  795. }
  796. dao = dao.Order(orderby)
  797. ents := []*model.BaseDistributorDynamics{}
  798. err = dao.Structs(&ents)
  799. if err != nil && err != sql.ErrNoRows {
  800. return 0, nil, err
  801. }
  802. ret := map[string][]*model.BaseDistributorDynamics{}
  803. for _, ent := range ents {
  804. date := ent.OpnDate.Format("Y-m-d")
  805. ret[date] = append(ret[date], ent)
  806. }
  807. return total, ret, err
  808. }
  809. func DownFile(url string) ([]byte, error) {
  810. r, err := http.Get(url)
  811. if err != nil {
  812. return nil, err
  813. }
  814. if r.StatusCode != http.StatusOK {
  815. return nil, fmt.Errorf("DownFile from %s StatusCode %d", url, r.StatusCode)
  816. }
  817. defer r.Body.Close()
  818. return ioutil.ReadAll(r.Body)
  819. }
  820. // '审核状态 20 待审核 30 审核已同意 40 审核已拒绝 50 审核已撤销'
  821. func ApprovalProxyCreate(ctx context.Context, flow *workflowmodel.PlatWorkflow, msg *message.MixMessage) error {
  822. tenant, err := micro_srv.GetTenant(ctx)
  823. if err != nil {
  824. return fmt.Errorf("获取租户码异常:%s", err.Error())
  825. }
  826. distdao := base.NewBaseDistributorDao(tenant)
  827. entId, err := strconv.Atoi(flow.BizCode)
  828. if err != nil {
  829. return fmt.Errorf("创建代理商钉钉审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id)
  830. }
  831. ent, err := distdao.Where("id = ?", entId).One()
  832. if err != nil {
  833. return err
  834. }
  835. if ent == nil {
  836. return fmt.Errorf("代理商不存在:%s Id: %d", flow.BizCode, flow.Id)
  837. }
  838. if msg.ProcessType != "finish" && msg.ProcessType != "terminate" {
  839. return fmt.Errorf("无法识别的 ProcessType :%s", msg.ProcessType)
  840. }
  841. if msg.Result != "agree" && msg.Result != "refuse" && msg.Result != "" {
  842. return fmt.Errorf("无法识别的 Result :%s", msg.Result)
  843. }
  844. if msg.ProcessType == "terminate" {
  845. _, err = distdao.Where("id = ?", entId).Data(map[string]interface{}{
  846. "appro_status": "50",
  847. "appro_data": "",
  848. }).Update()
  849. return err
  850. }
  851. pass := msg.Result == "agree"
  852. if !pass {
  853. _, err = distdao.Where("id = ?", entId).Data(map[string]interface{}{
  854. "appro_status": "40",
  855. "appro_data": "",
  856. }).Update()
  857. return err
  858. }
  859. _, err = distdao.Where("id = ?", entId).Data(map[string]interface{}{
  860. "appro_status": "30",
  861. "appro_data": "",
  862. }).Update()
  863. return err
  864. }
  865. func ApprovalDistToProxy(ctx context.Context, flow *workflowmodel.PlatWorkflow, msg *message.MixMessage) error {
  866. tenant, err := micro_srv.GetTenant(ctx)
  867. if err != nil {
  868. return fmt.Errorf("获取租户码异常:%s", err.Error())
  869. }
  870. distdao := base.NewBaseDistributorDao(tenant)
  871. entId, err := strconv.Atoi(flow.BizCode)
  872. if err != nil {
  873. return fmt.Errorf("经销商转代理商钉钉审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id)
  874. }
  875. ent, err := distdao.Where("id = ?", entId).One()
  876. if err != nil {
  877. return err
  878. }
  879. if ent == nil {
  880. return fmt.Errorf("经销商不存在:%s Id: %d", flow.BizCode, flow.Id)
  881. }
  882. if msg.ProcessType != "finish" && msg.ProcessType != "terminate" {
  883. return fmt.Errorf("无法识别的 ProcessType :%s", msg.ProcessType)
  884. }
  885. if msg.Result != "agree" && msg.Result != "refuse" && msg.Result != "" {
  886. return fmt.Errorf("无法识别的 Result :%s", msg.Result)
  887. }
  888. if msg.ProcessType == "terminate" {
  889. _, err = distdao.Where("id = ?", entId).Data(map[string]interface{}{
  890. "appro_status": "50",
  891. "appro_data": "",
  892. }).Update()
  893. return err
  894. }
  895. pass := msg.Result == "agree"
  896. if !pass {
  897. _, err = distdao.Where("id = ?", entId).Data(map[string]interface{}{
  898. "appro_status": "40",
  899. "appro_data": "",
  900. }).Update()
  901. return err
  902. }
  903. approData := model.ToProxyApproveData{}
  904. err = json.Unmarshal([]byte(ent.ApproData), &approData)
  905. if err != nil {
  906. return fmt.Errorf("经销商转代理商钉钉审批 ApproData 解析异常:%s Id: %d ApproData:%s", flow.BizCode, flow.Id, ent.ApproData)
  907. }
  908. txerr := distdao.DB.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  909. _, err = tx.Update("base_distributor", map[string]interface{}{
  910. "dist_type": "20",
  911. "appro_status": "30",
  912. "appro_data": "",
  913. "customer_type": approData.CustomerType,
  914. "proxy_start_time": approData.ProxyStartTime,
  915. "proxy_end_time": approData.ProxyEndTime,
  916. "proxy_district": approData.ProxyDistrict,
  917. "contract_url": approData.ContractUrl,
  918. }, "id = ?", ent.Id)
  919. if err != nil {
  920. return err
  921. }
  922. _, err = tx.Insert("base_distributor_record", model.BaseDistributorRecord{
  923. DistId: ent.Id,
  924. DistType: "20",
  925. BusinessScope: ent.BusinessScope,
  926. CustomerType: approData.CustomerType,
  927. ProxyDistrict: approData.ProxyDistrict,
  928. ProxyStartTime: approData.ProxyStartTime,
  929. ProxyEndTime: approData.ProxyEndTime,
  930. ContractUrl: approData.ContractUrl,
  931. ExistedProduct: ent.ExistedProduct,
  932. HistoryCustomer: ent.HistoryCustomer,
  933. ToDistReason: "",
  934. Remark: "",
  935. CreatedBy: approData.OperatedId,
  936. CreatedName: approData.OperatedName,
  937. CreatedTime: gtime.Now(),
  938. UpdatedBy: approData.OperatedId,
  939. UpdatedName: approData.OperatedName,
  940. UpdatedTime: gtime.Now(),
  941. })
  942. if err != nil {
  943. return err
  944. }
  945. err = addDynamicsByCurrentUser(tx, ent.Id, "转为代理商",
  946. approData, approData.OperatedId, approData.OperatedName)
  947. if err != nil {
  948. return err
  949. }
  950. return nil
  951. })
  952. return txerr
  953. }
  954. func ApprovalDistRenew(ctx context.Context, flow *workflowmodel.PlatWorkflow, msg *message.MixMessage) error {
  955. tenant, err := micro_srv.GetTenant(ctx)
  956. if err != nil {
  957. return fmt.Errorf("获取租户码异常:%s", err.Error())
  958. }
  959. distdao := base.NewBaseDistributorDao(tenant)
  960. entId, err := strconv.Atoi(flow.BizCode)
  961. if err != nil {
  962. return fmt.Errorf("代理商续签钉钉审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id)
  963. }
  964. ent, err := distdao.Where("id = ?", entId).One()
  965. if err != nil {
  966. return err
  967. }
  968. if ent == nil {
  969. return fmt.Errorf("代理商不存在:%s Id: %d", flow.BizCode, flow.Id)
  970. }
  971. if msg.ProcessType != "finish" && msg.ProcessType != "terminate" {
  972. return fmt.Errorf("无法识别的 ProcessType :%s", msg.ProcessType)
  973. }
  974. if msg.Result != "agree" && msg.Result != "refuse" && msg.Result != "" {
  975. return fmt.Errorf("无法识别的 Result :%s", msg.Result)
  976. }
  977. if msg.ProcessType == "terminate" {
  978. _, err = distdao.Where("id = ?", entId).Data(map[string]interface{}{
  979. "appro_status": "50",
  980. "appro_data": "",
  981. }).Update()
  982. return err
  983. }
  984. pass := msg.Result == "agree"
  985. if !pass {
  986. _, err = distdao.Where("id = ?", entId).Data(map[string]interface{}{
  987. "appro_status": "40",
  988. "appro_data": "",
  989. }).Update()
  990. return err
  991. }
  992. approData := model.RenewApproveData{}
  993. err = json.Unmarshal([]byte(ent.ApproData), &approData)
  994. if err != nil {
  995. return fmt.Errorf("代理商续签钉钉审批 ApproData 解析异常:%s Id: %d ApproData:%s", flow.BizCode, flow.Id, ent.ApproData)
  996. }
  997. txerr := distdao.DB.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  998. _, err = tx.Update("base_distributor", map[string]interface{}{
  999. "appro_status": "30",
  1000. "appro_data": "",
  1001. "customer_type": approData.CustomerType,
  1002. "proxy_start_time": approData.ProxyStartTime,
  1003. "proxy_end_time": approData.ProxyEndTime,
  1004. "proxy_district": approData.ProxyDistrict,
  1005. "contract_url": approData.ContractUrl,
  1006. }, "id = ?", ent.Id)
  1007. if err != nil {
  1008. return err
  1009. }
  1010. _, err = tx.Insert("base_distributor_record", model.BaseDistributorRecord{
  1011. DistId: ent.Id,
  1012. DistType: "20",
  1013. BusinessScope: ent.BusinessScope,
  1014. CustomerType: approData.CustomerType,
  1015. ProxyDistrict: approData.ProxyDistrict,
  1016. ProxyStartTime: approData.ProxyStartTime,
  1017. ProxyEndTime: approData.ProxyEndTime,
  1018. ContractUrl: approData.ContractUrl,
  1019. ExistedProduct: ent.ExistedProduct,
  1020. HistoryCustomer: ent.HistoryCustomer,
  1021. ToDistReason: "",
  1022. Remark: "",
  1023. CreatedBy: approData.OperatedId,
  1024. CreatedName: approData.OperatedName,
  1025. CreatedTime: gtime.Now(),
  1026. UpdatedBy: approData.OperatedId,
  1027. UpdatedName: approData.OperatedName,
  1028. UpdatedTime: gtime.Now(),
  1029. })
  1030. if err != nil {
  1031. return err
  1032. }
  1033. err = addDynamicsByCurrentUser(tx, ent.Id, "续签代理商",
  1034. approData, approData.OperatedId, approData.OperatedName)
  1035. if err != nil {
  1036. return err
  1037. }
  1038. return nil
  1039. })
  1040. return txerr
  1041. }
  1042. func ApprovalDistToDist(ctx context.Context, flow *workflowmodel.PlatWorkflow, msg *message.MixMessage) error {
  1043. tenant, err := micro_srv.GetTenant(ctx)
  1044. if err != nil {
  1045. return fmt.Errorf("获取租户码异常:%s", err.Error())
  1046. }
  1047. distdao := base.NewBaseDistributorDao(tenant)
  1048. entId, err := strconv.Atoi(flow.BizCode)
  1049. if err != nil {
  1050. return fmt.Errorf("代理商转经销商钉钉审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id)
  1051. }
  1052. ent, err := distdao.Where("id = ?", entId).One()
  1053. if err != nil {
  1054. return err
  1055. }
  1056. if ent == nil {
  1057. return fmt.Errorf("代理商不存在:%s Id: %d", flow.BizCode, flow.Id)
  1058. }
  1059. if msg.ProcessType != "finish" && msg.ProcessType != "terminate" {
  1060. return fmt.Errorf("无法识别的 ProcessType :%s", msg.ProcessType)
  1061. }
  1062. if msg.Result != "agree" && msg.Result != "refuse" && msg.Result != "" {
  1063. return fmt.Errorf("无法识别的 Result :%s", msg.Result)
  1064. }
  1065. if msg.ProcessType == "terminate" {
  1066. _, err = distdao.Where("id = ?", entId).Data(map[string]interface{}{
  1067. "appro_status": "50",
  1068. "appro_data": "",
  1069. }).Update()
  1070. return err
  1071. }
  1072. pass := msg.Result == "agree"
  1073. if !pass {
  1074. _, err = distdao.Where("id = ?", entId).Data(map[string]interface{}{
  1075. "appro_status": "40",
  1076. "appro_data": "",
  1077. }).Update()
  1078. return err
  1079. }
  1080. approData := model.ToDistApproveData{}
  1081. err = json.Unmarshal([]byte(ent.ApproData), &approData)
  1082. if err != nil {
  1083. return fmt.Errorf("代理商转经销商钉钉审批 ApproData 解析异常:%s Id: %d ApproData:%s", flow.BizCode, flow.Id, ent.ApproData)
  1084. }
  1085. txerr := distdao.DB.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  1086. _, err = tx.Update("base_distributor", map[string]interface{}{
  1087. "dist_type": "10",
  1088. "appro_status": "30",
  1089. "appro_data": "",
  1090. }, "id = ?", ent.Id)
  1091. if err != nil {
  1092. return err
  1093. }
  1094. _, err = tx.Insert("base_distributor_record", model.BaseDistributorRecord{
  1095. DistId: ent.Id,
  1096. DistType: "10",
  1097. BusinessScope: ent.BusinessScope,
  1098. CustomerType: ent.CustomerType,
  1099. ProxyDistrict: "",
  1100. ProxyStartTime: nil,
  1101. ProxyEndTime: nil,
  1102. ContractUrl: "",
  1103. ExistedProduct: ent.ExistedProduct,
  1104. HistoryCustomer: ent.HistoryCustomer,
  1105. ToDistReason: approData.ToDistReason,
  1106. Remark: "",
  1107. CreatedBy: approData.OperatedId,
  1108. CreatedName: approData.OperatedName,
  1109. CreatedTime: gtime.Now(),
  1110. UpdatedBy: approData.OperatedId,
  1111. UpdatedName: approData.OperatedName,
  1112. UpdatedTime: gtime.Now(),
  1113. })
  1114. if err != nil {
  1115. return err
  1116. }
  1117. err = addDynamicsByCurrentUser(tx, ent.Id, "转为经销商",
  1118. approData, approData.OperatedId, approData.OperatedName)
  1119. if err != nil {
  1120. return err
  1121. }
  1122. return nil
  1123. })
  1124. return txerr
  1125. }
  1126. func addDynamicsByCurrentUser(tx *gdb.TX, distId int, opnType string, content interface{}, operatedId int, opreatedName string) error {
  1127. contentByte, err := json.Marshal(content)
  1128. if err != nil {
  1129. return err
  1130. }
  1131. _, err = tx.InsertAndGetId("base_distributor_dynamics", model.BaseDistributorDynamics{
  1132. DistId: distId,
  1133. OpnPeopleId: operatedId,
  1134. OpnPeople: opreatedName,
  1135. OpnDate: gtime.Now(),
  1136. OpnType: opnType,
  1137. OpnContent: string(contentByte),
  1138. Remark: "",
  1139. CreatedBy: operatedId,
  1140. CreatedName: opreatedName,
  1141. CreatedTime: gtime.Now(),
  1142. UpdatedBy: operatedId,
  1143. UpdatedName: opreatedName,
  1144. UpdatedTime: gtime.Now(),
  1145. })
  1146. return err
  1147. }
  1148. func UploadDingtalk(uid, url, name string) ([]byte, error) {
  1149. if uid == "" {
  1150. return nil, fmt.Errorf("该用户钉钉 uid 为空")
  1151. }
  1152. filedata, err := DownFile(url)
  1153. if err != nil {
  1154. return nil, err
  1155. }
  1156. filepath := path.Join(os.TempDir(), name)
  1157. err = ioutil.WriteFile(filepath, filedata, 0644)
  1158. if err != nil {
  1159. return nil, fmt.Errorf("WriteFile %s %s", filepath, err)
  1160. }
  1161. defer os.Remove(filepath)
  1162. resp, err := dingtalk.Client.GetStorage().UploadFile(service.DingTalkSpaceId, uid, name, filepath)
  1163. if err != nil {
  1164. return nil, fmt.Errorf("钉钉上传文件异常 %s", err.Error())
  1165. }
  1166. file := []contractmodel.DingFileInfo{
  1167. {
  1168. SpaceId: resp.Dentry.SpaceId,
  1169. FileId: resp.Dentry.Id,
  1170. FileName: resp.Dentry.Name,
  1171. FileSize: resp.Dentry.Size,
  1172. FileType: resp.Dentry.Extension,
  1173. },
  1174. }
  1175. return json.Marshal(file)
  1176. }