order_service.go 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. package order
  2. import (
  3. "errors"
  4. logger "eta/eta_mini_ht_api/common/component/log"
  5. "eta/eta_mini_ht_api/common/exception"
  6. "eta/eta_mini_ht_api/common/utils/page"
  7. merchantService "eta/eta_mini_ht_api/domian/merchant"
  8. productService "eta/eta_mini_ht_api/domian/merchant"
  9. orderService "eta/eta_mini_ht_api/domian/order"
  10. userService "eta/eta_mini_ht_api/domian/user"
  11. merchantDao "eta/eta_mini_ht_api/models/merchant"
  12. orderDao "eta/eta_mini_ht_api/models/order"
  13. "eta/eta_mini_ht_api/service/user"
  14. "fmt"
  15. "gorm.io/gorm"
  16. "sync"
  17. "time"
  18. )
  19. const (
  20. permanentlyValid = "永久有效"
  21. OnSale = "on_sale" //上架
  22. OffSale = "off_sale" //下架
  23. )
  24. var (
  25. productOrderStatusMap = map[orderDao.OrderStatus]string{
  26. orderDao.OrderStatusPending: "pending",
  27. orderDao.OrderStatusPaid: "paid",
  28. orderDao.OrderStatusClosed: "closed",
  29. orderDao.OrderStatusRefund: "refund",
  30. }
  31. accessStatusMap = map[merchantDao.SubscribeStatus]string{
  32. merchantDao.SubscribeValid: "valid",
  33. merchantDao.SubscribeExpired: "expired",
  34. merchantDao.SubscribeClose: "closed",
  35. }
  36. )
  37. type ProductOrderInfo struct {
  38. Buyer BuyerInfo `json:"buyer"`
  39. ProductInfo ProductInfo `json:"productInfo"`
  40. Order ProductOrder `json:"order"`
  41. }
  42. type ProductInfo struct {
  43. Name string
  44. Type string
  45. Price string
  46. ValidDuration string
  47. }
  48. type ProductOrder struct {
  49. OrderNo string
  50. CreatedTime string
  51. }
  52. type BuyerInfo struct {
  53. Name string
  54. Mobile string
  55. AreaCode string
  56. }
  57. func GenerateProductOrderNo() string {
  58. return orderService.GenerateProductOrderNo()
  59. }
  60. func CreateProductOrder(templateUser user.User, productId int, orderNo string) (orderInfo ProductOrderInfo, err error) {
  61. if productId <= 0 {
  62. err = exception.New(exception.IllegalProductId)
  63. }
  64. productInfo, err := productService.GetMerchantProductById(productId)
  65. if err != nil {
  66. err = exception.NewWithException(exception.ProductInfoError, err.Error())
  67. return
  68. }
  69. if productInfo.Deleted {
  70. err = exception.New(exception.ProductInfoError)
  71. return
  72. }
  73. if productInfo.SaleStatus == OffSale {
  74. err = exception.New(exception.ProductOffSale)
  75. return
  76. }
  77. officialUser, err := userService.GetUserByTemplateUserId(templateUser.Id)
  78. if err != nil {
  79. if errors.Is(err, gorm.ErrRecordNotFound) {
  80. err = exception.New(exception.OfficialUserNotFound)
  81. } else {
  82. err = exception.NewWithException(exception.OfficialUserFoundError, err.Error())
  83. }
  84. return
  85. }
  86. //校验是否有相同待支付的产品订单
  87. var existOrder orderService.ProductOrderDTO
  88. existOrder, err = orderService.GetUserOrderByProduct(productId, templateUser.Id, productOrderStatusMap[orderDao.OrderStatusPending])
  89. if (err != nil && !errors.Is(err, gorm.ErrRecordNotFound)) || existOrder.Status == productOrderStatusMap[orderDao.OrderStatusPending] {
  90. err = exception.NewWithException(exception.DuplicateSubscribe, "当前产品有正在进行中的订单,请勿重复下单")
  91. return
  92. }
  93. //是否在有效期的产品
  94. var access merchantService.UserAccessDTO
  95. access, err = merchantService.GetUserSubscribe(templateUser.Id, productId)
  96. if (err != nil && !errors.Is(err, gorm.ErrRecordNotFound)) || access.Status == accessStatusMap[merchantDao.SubscribeValid] {
  97. err = exception.NewWithException(exception.DuplicateSubscribe, "当前产品已订阅,请勿重复下单")
  98. return
  99. }
  100. var orderCreated orderService.ProductOrderDTO
  101. orderCreated, err = orderService.CreateProductOrder(orderService.ProductOrderDTO{
  102. OrderID: orderNo,
  103. UserID: officialUser.ID,
  104. TemplateUserID: templateUser.Id,
  105. RealName: templateUser.Username,
  106. AreaCode: templateUser.AreaCode,
  107. Mobile: templateUser.Mobile,
  108. ProductID: productId,
  109. ProductType: productInfo.Type,
  110. ProductName: productInfo.ProductTile,
  111. TotalAmount: productInfo.Price,
  112. })
  113. if err != nil {
  114. logger.Error("创建订单失败:%v", err)
  115. if errors.Is(err, gorm.ErrDuplicatedKey) {
  116. err = exception.NewWithException(exception.SubscribeFailed, "请勿重复下单")
  117. return
  118. }
  119. err = exception.NewWithException(exception.SubscribeFailed, err.Error())
  120. return
  121. }
  122. buyer := BuyerInfo{
  123. Name: officialUser.RealName,
  124. Mobile: templateUser.Mobile,
  125. AreaCode: templateUser.AreaCode,
  126. }
  127. var duration string
  128. if !productInfo.IsPermanent {
  129. beginDate := time.Now().Format(time.DateOnly)
  130. endDate := time.Now().Add(time.Duration(productInfo.ValidDays*24) * time.Hour).Format(time.DateOnly)
  131. duration = fmt.Sprintf("%s~%s", beginDate, endDate)
  132. } else {
  133. duration = permanentlyValid
  134. }
  135. product := ProductInfo{
  136. Name: productInfo.Title,
  137. Type: productInfo.Type,
  138. Price: productInfo.Price,
  139. ValidDuration: duration,
  140. }
  141. order := ProductOrder{
  142. OrderNo: orderCreated.OrderID,
  143. CreatedTime: orderCreated.CreatedTime,
  144. }
  145. orderInfo = ProductOrderInfo{
  146. Buyer: buyer,
  147. ProductInfo: product,
  148. Order: order,
  149. }
  150. return
  151. }
  152. func PreViewProductOrder(templateUser user.User, productId int) (orderInfo ProductOrderInfo, err error) {
  153. if productId <= 0 {
  154. err = exception.New(exception.IllegalProductId)
  155. }
  156. productInfo, err := productService.GetMerchantProductById(productId)
  157. if err != nil {
  158. err = exception.NewWithException(exception.ProductInfoError, err.Error())
  159. return
  160. }
  161. if productInfo.SaleStatus == OffSale {
  162. err = exception.New(exception.ProductOffSale)
  163. return
  164. }
  165. officialUser, err := userService.GetUserByTemplateUserId(templateUser.Id)
  166. if err != nil {
  167. if errors.Is(err, gorm.ErrRecordNotFound) {
  168. err = exception.New(exception.OfficialUserNotFound)
  169. } else {
  170. err = exception.NewWithException(exception.OfficialUserFoundError, err.Error())
  171. }
  172. return
  173. }
  174. buyer := BuyerInfo{
  175. Name: officialUser.RealName,
  176. Mobile: templateUser.Mobile,
  177. AreaCode: templateUser.AreaCode,
  178. }
  179. var duration string
  180. if !productInfo.IsPermanent {
  181. beginDate := time.Now().Format(time.DateOnly)
  182. endDate := time.Now().Add(time.Duration(productInfo.ValidDays*24) * time.Hour).Format(time.DateOnly)
  183. duration = fmt.Sprintf("%s~%s", beginDate, endDate)
  184. } else {
  185. duration = permanentlyValid
  186. }
  187. product := ProductInfo{
  188. Name: productInfo.Title,
  189. Type: productInfo.Type,
  190. Price: productInfo.Price,
  191. ValidDuration: duration,
  192. }
  193. orderInfo = ProductOrderInfo{
  194. Buyer: buyer,
  195. ProductInfo: product,
  196. }
  197. return
  198. }
  199. func GetTotalPageCountByUserId(userId int, orderStatus string) (total int64, latestId int64) {
  200. return orderService.GetTotalPageCountByUserId(userId, orderStatus)
  201. }
  202. func GetOrderPage(pageInfo page.PageInfo, userId int, orderStatus string) (orderList []orderService.ProductOrderDTO, err error) {
  203. orderList, err = orderService.GetOrderPage(pageInfo, userId, orderStatus)
  204. if err != nil {
  205. err = exception.NewWithException(exception.GetOrderListFailed, err.Error())
  206. }
  207. var wg sync.WaitGroup
  208. wg.Add(len(orderList))
  209. logger.Info("获取产品信息")
  210. for i := 0; i < len(orderList); i++ {
  211. go func(order *orderService.ProductOrderDTO) {
  212. defer wg.Done()
  213. product, pdErr := productService.GetMerchantProductById(order.ProductID)
  214. if pdErr != nil {
  215. logger.Error("获取产品信息失败:%v", err)
  216. }
  217. order.ProductName = product.Title
  218. }(&orderList[i])
  219. }
  220. wg.Wait()
  221. return
  222. }
  223. func GetOrderDetail(orderId string, userId int) (order orderService.ProductOrderDetailDTO, err error) {
  224. order, err = orderService.GetOrderDetail(orderId, userId)
  225. return
  226. }
  227. func GetProductOrderByUser(templateUserId int, orderNo string) (order orderService.ProductOrderDTO, err error) {
  228. return orderService.GetOrderByUser(templateUserId, orderNo)
  229. }
  230. func CloseProductOrder(templateUserId int, productOrderNo string) (err error) {
  231. return orderService.CloseProductOrder(templateUserId, productOrderNo)
  232. }
  233. func GetTradeOrderByNo(tradeOrderNo string) (dto orderService.TradeOrderDTO, err error) {
  234. return orderService.GetTradeOrderByNo(tradeOrderNo)
  235. }
  236. func CheckProductStatus(productOrder orderService.ProductOrderDTO) (err error) {
  237. product, err := productService.GetMerchantProductById(productOrder.ProductID)
  238. if err != nil {
  239. return exception.NewWithException(exception.ProductInfoError, err.Error())
  240. }
  241. if product.SaleStatus == "off_sale" {
  242. err = orderService.CloseProductOrder(productOrder.TemplateUserID, productOrder.OrderID)
  243. if err != nil {
  244. logger.Error("关闭订单失败:%v,订单编号:%s", err, product)
  245. }
  246. return exception.New(exception.ProductOffSale)
  247. }
  248. if product.Deleted {
  249. err = orderService.CloseProductOrder(productOrder.TemplateUserID, productOrder.OrderID)
  250. if err != nil {
  251. logger.Error("关闭订单失败:%v,订单编号:%s", err, product)
  252. }
  253. return exception.New(exception.ProductNotFound)
  254. }
  255. return
  256. }