orderHandler.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. package controller
  2. import (
  3. . "app.yhyue.com/moapp/jybase/api"
  4. "app.yhyue.com/moapp/jybase/common"
  5. "context"
  6. "fmt"
  7. "github.com/gogf/gf/v2/database/gdb"
  8. "github.com/gogf/gf/v2/errors/gerror"
  9. "github.com/gogf/gf/v2/frame/g"
  10. "github.com/gogf/gf/v2/net/ghttp"
  11. "github.com/gogf/gf/v2/util/gconv"
  12. "github.com/pkg/errors"
  13. "jyOrderManager/internal/jyutil"
  14. "jyOrderManager/internal/logic/order"
  15. "jyOrderManager/internal/logic/product"
  16. "jyOrderManager/internal/model"
  17. "jyOrderManager/internal/service"
  18. "strings"
  19. "time"
  20. )
  21. var checkOrderProduct = func(ctx context.Context, orderCode string, param model.OrderParams, oldOrderRes ...g.Map) (productArr []product.JyProduct, removeOrderDetailIds []int64, masterKey string, err error) {
  22. var (
  23. actProduct = map[string]map[string]product.JyProduct{}
  24. orderMap g.Map
  25. existsOrderDetailIds = map[int64]bool{}
  26. update = false
  27. )
  28. if len(oldOrderRes) > 0 {
  29. orderMap, update = oldOrderRes[0], true
  30. }
  31. if update { //待审核和已完成订单禁止修改
  32. var orderDetailRes gdb.Result
  33. orderDetailRes, err = g.DB().Query(ctx, "SELECT id FROM jy_order_detail WHERE order_code=?", param.OrderCode)
  34. if err != nil || orderDetailRes.IsEmpty() {
  35. err = gerror.Wrapf(err, "为查询到订单明细")
  36. return
  37. }
  38. var (
  39. orderStatus = gconv.Int(orderMap["order_status"])
  40. auditStatus = gconv.Int(orderMap["audit_status"])
  41. )
  42. if auditStatus > 0 || orderStatus == 1 {
  43. err = errors.New("当前订单状态禁止修改")
  44. return
  45. }
  46. for _, m := range orderDetailRes.List() {
  47. existsOrderDetailIds[gconv.Int64(m["id"])] = true
  48. }
  49. }
  50. var (
  51. maxPrice int64
  52. )
  53. for _, tParam := range param.ProductArr {
  54. orderDetailId := gconv.Int64(tParam["id"])
  55. if update {
  56. if orderDetailId == 0 {
  57. err = fmt.Errorf("商品修改缺少id")
  58. return
  59. }
  60. existsOrderDetailIds[orderDetailId] = false
  61. }
  62. //参数注入
  63. tParam["phone"] = param.PersonPhone //开通手机号
  64. tParam["order_code"] = orderCode //订单号
  65. tParam["reqBuySet"] = param.BuySubject //购买主体
  66. tParam["reqCompanyName"] = param.CompanyName //公司名称
  67. productCode := gconv.String(tParam["product_code"])
  68. pFunc, pErr := product.JyProFunc.GetProductInitFuncByCode(productCode)
  69. if pErr != nil {
  70. err = gerror.Wrapf(pErr, "获取商品异常")
  71. return
  72. }
  73. pObj, pErr := pFunc(tParam)
  74. if pErr != nil {
  75. err = gerror.Wrap(pErr, fmt.Sprintf("获取%s商品异常", productCode))
  76. return
  77. }
  78. //获取价格最贵的商品作为主商品
  79. if amount := gconv.Int64(tParam["amount"]); amount > maxPrice {
  80. maxPrice = amount
  81. masterKey = fmt.Sprintf("%s_%d", productCode, amount)
  82. }
  83. var (
  84. actCode = gconv.String(tParam["activityCode"]) //活动code
  85. checkCode = common.If(actCode != "", 2, 1).(int) //1:普通商品 2:活动商品
  86. )
  87. if actCode != "" {
  88. if _, ok := actProduct[actCode]; ok {
  89. actProduct[actCode][productCode] = pObj
  90. } else {
  91. actProduct[actCode] = map[string]product.JyProduct{productCode: pObj}
  92. }
  93. }
  94. if err = pObj.Check(ctx, checkCode); err != nil {
  95. return
  96. }
  97. productArr = append(productArr, pObj)
  98. }
  99. if len(productArr) == 0 {
  100. err = fmt.Errorf("订单商品为空")
  101. return
  102. }
  103. // 活动商品校验完整,防止缺少增加商品
  104. if len(actProduct) > 0 {
  105. now := time.Now()
  106. for actCode, productList := range actProduct {
  107. act := service.Product().GetActivityByCode(actCode)
  108. //当前用户是否有权限
  109. if !service.Product().PowerCheck(act.Code, jyutil.GetUserDeptIdFromCtx(ctx)) {
  110. err = fmt.Errorf("没有创建%s活动的权限", act.Name)
  111. return
  112. }
  113. if act == nil {
  114. err = fmt.Errorf("未知活动code %s", actCode)
  115. return
  116. }
  117. if now.After(act.EndTime) || now.Before(act.StartTime) {
  118. err = fmt.Errorf("活动%s不在有效期", actCode)
  119. return
  120. }
  121. if len(productList) != len(act.Products) {
  122. err = fmt.Errorf("活动产品不完整 %s", actCode)
  123. return
  124. }
  125. }
  126. }
  127. for orderDetailId, ok := range existsOrderDetailIds {
  128. if !ok {
  129. removeOrderDetailIds = append(removeOrderDetailIds, orderDetailId)
  130. }
  131. }
  132. return
  133. }
  134. // SaveOrderHandler 创建订单
  135. func SaveOrderHandler(r *ghttp.Request) {
  136. rData, err := func() (interface{}, error) {
  137. var (
  138. param model.OrderParams
  139. ctx = r.Context()
  140. uMsg = jyutil.GetUserMsgFromCtx(ctx)
  141. userName = uMsg.EntUserName
  142. entUserId = uMsg.EntUserId
  143. masterKey string
  144. )
  145. err := gconv.Struct(r.GetBody(), &param)
  146. if err != nil {
  147. return nil, gerror.Wrapf(err, "数据校验异常")
  148. }
  149. var (
  150. productArr []product.JyProduct
  151. orderCode = fmt.Sprintf("%s%s", time.Now().Format("150405"), common.GetRandom(6))
  152. )
  153. //产品参数校验
  154. productArr, _, masterKey, err = checkOrderProduct(ctx, orderCode, param)
  155. if err != nil {
  156. return nil, err
  157. }
  158. //数据库操作
  159. if err := g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
  160. //todo 插入订单表
  161. if _, err := g.DB().Ctx(ctx).Insert(ctx, "dataexport_order", g.Map{
  162. "order_code": orderCode,
  163. "order_money": param.OrderMoney,
  164. "pay_money": param.ContractMoney,
  165. "pay_way": param.PayType,
  166. "product_type": getProductNameByMasterKey(masterKey),
  167. "order_status": 0,
  168. "user_phone": param.PersonPhone,
  169. "company_name": param.CompanyName,
  170. "is_backstage_order": 1,
  171. "commission": param.ChannelCommission,
  172. "order_channel": param.OrderChannel,
  173. "create_person": userName,
  174. "last_update_person": userName,
  175. "salesperson_id": entUserId,
  176. "signing_subject": param.PaybackCompany,
  177. "audit_status": common.If(param.Save == 1, 0, 1),
  178. "buy_subject": param.BuySubject,
  179. "payment_user": param.PaymentUser,
  180. "zero_type": param.ZeroOrderType,
  181. "mark": param.OrderRemark,
  182. }); err != nil {
  183. return gerror.Wrap(err, "插入订单表异常")
  184. }
  185. //todo 订单详情表
  186. for _, p := range productArr {
  187. //是否是主商品
  188. if err := p.SaveUpdate(ctx, masterKey); err != nil {
  189. return gerror.Wrapf(err, "插入商品明细异常")
  190. }
  191. }
  192. //todo 销售业绩
  193. if err := order.SaveOrUpdateSaleMoneyTmp(ctx, orderCode, userName, param.SaleMoney); err != nil {
  194. return gerror.Wrapf(err, "销售业绩异常")
  195. }
  196. //todo 合同
  197. if err := order.SaveOrUpdateContract(ctx, orderCode, param.CompanyName, param.ContractMoney, param.Contract); err != nil {
  198. return gerror.Wrapf(err, "合同异常")
  199. }
  200. //回款计划
  201. if err := order.SaveOrUpdateReturnPlant(ctx, orderCode, param.ContractMoney, param.ReturnPlant); err != nil {
  202. return gerror.Wrapf(err, "回款计划异常")
  203. }
  204. return nil
  205. }); err != nil {
  206. return nil, gerror.Wrapf(err, "数据库操作异常")
  207. }
  208. return orderCode, nil
  209. }()
  210. if err != nil {
  211. g.Log().Errorf(r.Context(), "创建订单异常 %v", err)
  212. }
  213. r.Response.WriteJson(NewResult(rData, err))
  214. }
  215. // UpdateOrderHandler 订单修改
  216. func UpdateOrderHandler(r *ghttp.Request) {
  217. rData, err := func() (interface{}, error) {
  218. var (
  219. param model.OrderParams
  220. ctx = r.Context()
  221. uMsg = jyutil.GetUserMsgFromCtx(ctx)
  222. userName = uMsg.EntUserName
  223. entUserId = uMsg.EntUserId
  224. masterKey string
  225. )
  226. err := gconv.Struct(r.GetBody(), &param)
  227. if err != nil {
  228. return nil, gerror.Wrapf(err, "数据校验异常")
  229. }
  230. orderRes, err := g.DB().GetOne(ctx, "SELECT * FROM dataexport_order WHERE order_code=?", param.OrderCode)
  231. if err != nil || orderRes.IsEmpty() {
  232. err = gerror.Wrapf(err, "未知订单")
  233. return nil, err
  234. }
  235. //产品参数校验
  236. productArr, removeIds, masterKey, err := checkOrderProduct(ctx, param.OrderCode, param, orderRes.Map())
  237. if err != nil {
  238. return nil, err
  239. }
  240. //数据库操作
  241. if err := g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
  242. upOrder := g.Map{
  243. "order_money": param.OrderMoney,
  244. "pay_money": param.ContractMoney,
  245. "pay_way": param.PayType,
  246. "product_type": getProductNameByMasterKey(masterKey),
  247. "order_status": param.OrderStatus,
  248. "user_phone": param.PersonPhone,
  249. "company_name": param.CompanyName,
  250. "is_backstage_order": 1,
  251. "commission": param.ChannelCommission,
  252. "order_channel": param.OrderChannel,
  253. "create_person": userName,
  254. "last_update_person": userName,
  255. "salesperson_id": entUserId,
  256. "signing_subject": param.PaybackCompany,
  257. "audit_status": common.If(param.Save == 1, 0, 1),
  258. "buy_subject": param.BuySubject,
  259. "payment_user": param.PaymentUser,
  260. "zero_type": param.ZeroOrderType,
  261. "mark": param.OrderRemark,
  262. }
  263. //退回单子重新编辑提交后更改审核状态
  264. if auditStatus := gconv.Int(orderRes.Map()["audit_status"]); auditStatus < 0 {
  265. upOrder["audit_status"] = SwitchAudit(auditStatus)
  266. }
  267. if _, err = g.DB().Ctx(ctx).Update(ctx, "dataexport_order", upOrder, "order_code=? and order_status=0", param.OrderCode); err != nil {
  268. return gerror.Wrap(err, "修改订单表内容异常")
  269. }
  270. //todo 删除已经不存在的商品
  271. for _, id := range removeIds {
  272. if _, err := g.DB().Update(ctx, "jy_order_detail", g.Map{
  273. "status": 2,
  274. }, "id=? and order_code=?", id, param.OrderCode); err != nil {
  275. return gerror.Wrapf(err, "删除旧订单明细内容异常")
  276. }
  277. }
  278. //todo 订单详情表
  279. for _, p := range productArr {
  280. if err := p.SaveUpdate(ctx, masterKey); err != nil {
  281. return gerror.Wrapf(err, "插入商品明细异常")
  282. }
  283. }
  284. //todo 销售业绩 p610.管理后台创建订单,订单状态为已完成(不包含从未完成改成已完成,未提交的状态),“销售人员”、“销售业绩”、“销售渠道”不支持编辑;
  285. if gconv.Int(orderRes["order_status"]) == 0 {
  286. err = order.SaveOrUpdateSaleMoneyTmp(ctx, param.OrderCode, userName, param.SaleMoney)
  287. if err != nil {
  288. return err
  289. }
  290. }
  291. //todo 合同
  292. if err := order.SaveOrUpdateContract(ctx, param.OrderCode, param.CompanyName, param.ContractMoney, param.Contract); err != nil {
  293. return gerror.Wrapf(err, "合同异常")
  294. }
  295. //todo 回款计划
  296. if err := order.SaveOrUpdateReturnPlant(ctx, param.OrderRemark, param.ContractMoney, param.ReturnPlant); err != nil {
  297. return gerror.Wrapf(err, "回款计划异常")
  298. }
  299. return nil
  300. }); err != nil {
  301. return nil, gerror.Wrapf(err, "数据库操作异常")
  302. }
  303. return nil, err
  304. }()
  305. if err != nil {
  306. g.Log().Errorf(r.Context(), "订单修改异常 %v", err)
  307. }
  308. r.Response.WriteJson(NewResult(rData, err))
  309. }
  310. // GetContractPdfHandler 电子pdf合同
  311. func GetContractPdfHandler(r *ghttp.Request) {
  312. rData, err := func() (interface{}, error) {
  313. rj, err := r.GetJson()
  314. if err != nil {
  315. return nil, errors.Wrap(err, "请求参数格式异常")
  316. }
  317. var (
  318. orderCode = rj.Get("orderCode").String()
  319. ctx = r.Context()
  320. uMsg = jyutil.GetUserMsgFromCtx(ctx)
  321. userName = uMsg.EntUserName
  322. )
  323. pdfPath, err := order.GetContractPdf(ctx, orderCode, userName)
  324. if err != nil {
  325. return nil, err
  326. }
  327. return pdfPath, nil
  328. }()
  329. if err != nil {
  330. g.Log().Errorf(r.Context(), "生成电子pdf合同出错 %v", err)
  331. }
  332. r.Response.WriteJson(NewResult(rData, err))
  333. }
  334. func getProductNameByMasterKey(masterKey string) string {
  335. if arr := strings.Split(masterKey, "_"); len(arr) > 0 {
  336. var productCode = arr[0]
  337. mp, err := service.Product().GetProduct(productCode)
  338. if err != nil {
  339. return ""
  340. }
  341. mc, err := service.Product().GetProductClass(mp.ProductClassId)
  342. if err != nil {
  343. return ""
  344. }
  345. if mc.ClassName == "超级订阅" {
  346. return "VIP订阅"
  347. }
  348. return mc.ClassName
  349. }
  350. return ""
  351. }
  352. // 订单审核状态
  353. const (
  354. OrderUncommitted = 0 // 待提交
  355. OrderPending = 1 // 待审核
  356. OrderFirstPassed = 2 // 一审通过
  357. OrderPassed = 3 // 审核通过
  358. OrderSecondPassed = 4 // 审核通过
  359. OrderFirstReturn = -2 // 一审退回
  360. OrderSecondReturn = -3 // 二审退回
  361. OrderThreeReturn = -4 // 二审退回
  362. )
  363. // SwitchAudit 订单审核轨迹状态流转
  364. func SwitchAudit(auditStatus int) (saveAuditStatus int) {
  365. // 我的订单-编辑订单 只能编辑订单审核状态为已退回、待提交 不开通权限
  366. switch auditStatus {
  367. case OrderUncommitted:
  368. saveAuditStatus = OrderPending // 待一审
  369. case OrderFirstReturn:
  370. saveAuditStatus = OrderPending // 待一审
  371. case OrderSecondReturn:
  372. saveAuditStatus = OrderFirstPassed // 一审通过 待二审
  373. case OrderThreeReturn: //三审退回状态下,编辑订单后,审核状态是二审通过
  374. saveAuditStatus = OrderSecondPassed // 一审通过 待二审
  375. }
  376. return
  377. }