base_distributor.go 37 KB

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