智慧食堂
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

374 рядки
13 KiB

  1. package svc
  2. import (
  3. "applet/app/customer/md"
  4. "applet/app/db"
  5. "applet/app/db/model"
  6. enum2 "applet/app/enum"
  7. "applet/app/utils"
  8. "applet/app/utils/logx"
  9. "encoding/json"
  10. "errors"
  11. "fmt"
  12. "github.com/gin-gonic/gin"
  13. "io/ioutil"
  14. "net/url"
  15. "time"
  16. )
  17. func BuyPackage(c *gin.Context, req md.BuyPackageReq) (outTradeNo, tradeNo, total string, err error) {
  18. user := GetUser(c)
  19. session := db.Db.NewSession()
  20. defer session.Close()
  21. session.Begin()
  22. if err != nil {
  23. _ = session.Rollback()
  24. return
  25. }
  26. //1、判断是否为教师
  27. isTeacher := false
  28. userIdentityDb := db.UserIdentityDb{}
  29. userIdentityDb.Set(0)
  30. userIdentity, err := userIdentityDb.GetUserIdentity(req.UserIdentityId)
  31. if err != nil {
  32. return
  33. }
  34. if userIdentity == nil {
  35. err = errors.New("未查询到对应身份记录")
  36. return
  37. }
  38. if userIdentity.Identity == enum2.UserIdentityForCentralKitchenForTeacher {
  39. isTeacher = true
  40. }
  41. //2、计算数据(1:按学期购买 2:按月购买 3:按天购买 4:补餐)
  42. var totalPrice float64
  43. var data []*model.CentralKitchenForSchoolUserWithDay
  44. if req.Kind == 1 {
  45. totalPrice, data, err = CalcBySchoolTerm(user.Id, isTeacher, req)
  46. if err != nil {
  47. return
  48. }
  49. }
  50. if req.Kind == 2 {
  51. totalPrice, data, err = CalcByMonth(user.Id, isTeacher, req)
  52. if err != nil {
  53. return
  54. }
  55. }
  56. if req.Kind == 3 {
  57. totalPrice, data, err = CalcByDay(user.Id, isTeacher, req)
  58. if err != nil {
  59. return
  60. }
  61. }
  62. if req.Kind == 4 {
  63. totalPrice, data, err = CalcByDay(user.Id, isTeacher, req)
  64. if err != nil {
  65. return
  66. }
  67. }
  68. total = utils.Float64ToStr(totalPrice)
  69. //3、生成订单号
  70. outTradeNo = utils.OrderUUID(user.Id)
  71. //4、请求 alipay.trade.create(统一收单交易创建接口)
  72. sysCfgDb := db.SysCfgDb{}
  73. sysCfgDb.Set()
  74. sysCfg := sysCfgDb.SysCfgFindWithDb(enum2.OpenAppletAppid, enum2.OpenAlipayAppid, enum2.OpenAlipayAppPrivateKey, enum2.OpenAlipayPublicKey, enum2.JsapiPayAppAutToken, enum2.JsapiPayNotifyUrl)
  75. err, resp := CurlAlipayTradeCreate(md.CurlAlipayTradeCreateReq{
  76. Config: struct {
  77. PayAliAppId string `json:"pay_ali_app_id" label:"支付宝开放平台-第三方应用-appid"`
  78. PayAliPrivateKey string `json:"pay_ali_private_key" label:"支付宝开放平台-第三方应用-接口加签-应用私钥"`
  79. PayAliPublicKey string `json:"pay_ali_public_key" label:"支付宝开放平台-第三方应用-接口加签-支付宝公钥"`
  80. }{
  81. PayAliAppId: sysCfg[enum2.OpenAlipayAppid],
  82. PayAliPrivateKey: sysCfg[enum2.OpenAlipayAppPrivateKey],
  83. PayAliPublicKey: sysCfg[enum2.OpenAlipayPublicKey],
  84. },
  85. OpAppId: sysCfg[enum2.OpenAppletAppid],
  86. BuyerId: user.UserId,
  87. TotalAmount: total,
  88. OutTradeNo: outTradeNo,
  89. Subject: "购买食堂套餐",
  90. AppAuthToken: sysCfg[enum2.JsapiPayAppAutToken],
  91. NotifyUrl: sysCfg[enum2.JsapiPayNotifyUrl],
  92. })
  93. if err != nil {
  94. return
  95. }
  96. //5、插入订单记录
  97. now := time.Now()
  98. centralKitchenForSchoolPackageOrd := db.CentralKitchenForSchoolPackageOrd{}
  99. centralKitchenForSchoolPackageOrd.Set(outTradeNo)
  100. _, err = centralKitchenForSchoolPackageOrd.CentralKitchenForSchoolPackageOrdInsertBySession(session, &model.CentralKitchenForSchoolPackageOrd{
  101. EnterpriseId: req.EnterpriseId,
  102. Uid: user.Id,
  103. UserIdentityId: req.UserIdentityId,
  104. UserIdentityName: userIdentity.Name,
  105. TotalPrice: total,
  106. Kind: req.Kind,
  107. OutTradeNo: outTradeNo,
  108. TradeNo: resp.TradeNo,
  109. State: enum2.CentralKitchenForSchoolPackageOrdStateForWait,
  110. OrdState: enum2.CentralKitchenForSchoolPackageOrdOrdStateForWait,
  111. ReqContent: string(utils.Serialize(req)),
  112. WithDayData: string(utils.Serialize(data)),
  113. CreateAt: now.Format("2006-01-02 15:04:05"),
  114. UpdateAt: now.Format("2006-01-02 15:04:05"),
  115. })
  116. if err != nil {
  117. _ = session.Rollback()
  118. return
  119. }
  120. session.Commit()
  121. tradeNo = resp.TradeNo
  122. return
  123. }
  124. func NursingHomeBuyPackageReq(c *gin.Context, req md.NursingHomeBuyPackageReq) (outTradeNo, tradeNo, total string, err error) {
  125. user := GetUser(c)
  126. session := db.Db.NewSession()
  127. defer session.Close()
  128. session.Begin()
  129. if err != nil {
  130. _ = session.Rollback()
  131. return
  132. }
  133. userIdentityDb := db.UserIdentityDb{}
  134. userIdentityDb.Set(0)
  135. userIdentity, err := userIdentityDb.GetUserIdentity(req.UserIdentityId)
  136. if err != nil {
  137. return
  138. }
  139. if userIdentity == nil {
  140. err = errors.New("未查询到对应身份记录")
  141. return
  142. }
  143. //1、计算数据(1:按年购买 2:按月购买 3:按天购买 4:补餐)
  144. var totalPrice float64
  145. var data []*model.NursingHomeUserWithDay
  146. if req.Kind == 1 {
  147. totalPrice, data, err = CalcByYearForNursingHome(user.Id, req)
  148. if err != nil {
  149. return
  150. }
  151. }
  152. if req.Kind == 2 {
  153. totalPrice, data, err = CalcByMonthForNursingHome(user.Id, req)
  154. if err != nil {
  155. return
  156. }
  157. }
  158. if req.Kind == 3 {
  159. totalPrice, data, err = CalcByDayForNursingHome(user.Id, req)
  160. if err != nil {
  161. return
  162. }
  163. }
  164. if req.Kind == 4 {
  165. totalPrice, data, err = CalcByDayForNursingHome(user.Id, req)
  166. if err != nil {
  167. return
  168. }
  169. }
  170. total = utils.Float64ToStr(totalPrice)
  171. //3、生成订单号
  172. outTradeNo = utils.OrderUUID(user.Id)
  173. //4、请求 alipay.trade.create(统一收单交易创建接口)
  174. sysCfgDb := db.SysCfgDb{}
  175. sysCfgDb.Set()
  176. sysCfg := sysCfgDb.SysCfgFindWithDb(enum2.OpenAppletAppid, enum2.OpenAlipayAppid, enum2.OpenAlipayAppPrivateKey, enum2.OpenAlipayPublicKey, enum2.JsapiPayAppAutToken)
  177. err, resp := CurlAlipayTradeCreate(md.CurlAlipayTradeCreateReq{
  178. Config: struct {
  179. PayAliAppId string `json:"pay_ali_app_id" label:"支付宝开放平台-第三方应用-appid"`
  180. PayAliPrivateKey string `json:"pay_ali_private_key" label:"支付宝开放平台-第三方应用-接口加签-应用私钥"`
  181. PayAliPublicKey string `json:"pay_ali_public_key" label:"支付宝开放平台-第三方应用-接口加签-支付宝公钥"`
  182. }{
  183. PayAliAppId: sysCfg[enum2.OpenAlipayAppid],
  184. PayAliPrivateKey: sysCfg[enum2.OpenAlipayAppPrivateKey],
  185. PayAliPublicKey: sysCfg[enum2.OpenAlipayPublicKey],
  186. },
  187. OpAppId: sysCfg[enum2.OpenAppletAppid],
  188. BuyerId: user.UserId,
  189. TotalAmount: total,
  190. OutTradeNo: outTradeNo,
  191. Subject: "购买食堂套餐",
  192. AppAuthToken: sysCfg[enum2.JsapiPayAppAutToken],
  193. })
  194. if err != nil {
  195. return
  196. }
  197. //5、插入订单记录
  198. now := time.Now()
  199. NursingHomePackageOrd := db.NursingHomePackageOrd{}
  200. NursingHomePackageOrd.Set(outTradeNo)
  201. _, err = NursingHomePackageOrd.NursingHomePackageOrdInsertBySession(session, &model.NursingHomePackageOrd{
  202. EnterpriseId: req.EnterpriseId,
  203. Uid: user.Id,
  204. UserIdentityId: req.UserIdentityId,
  205. UserIdentityName: userIdentity.Name,
  206. TotalPrice: total,
  207. Kind: req.Kind,
  208. OutTradeNo: outTradeNo,
  209. TradeNo: resp.TradeNo,
  210. State: enum2.NursingHomePackageOrdStateForWait,
  211. OrdState: enum2.NursingHomePackageOrdOrdStateForWait,
  212. ReqContent: string(utils.Serialize(req)),
  213. WithDayData: string(utils.Serialize(data)),
  214. CreateAt: now.Format("2006-01-02 15:04:05"),
  215. UpdateAt: now.Format("2006-01-02 15:04:05"),
  216. })
  217. if err != nil {
  218. _ = session.Rollback()
  219. return
  220. }
  221. session.Commit()
  222. tradeNo = resp.TradeNo
  223. return
  224. }
  225. func DealCentralKitchenForSchoolOrderCallBack(outTradeNo, tradeStatus string) (state int, err error) {
  226. centralKitchenForSchoolPackageOrd := db.CentralKitchenForSchoolPackageOrd{}
  227. centralKitchenForSchoolPackageOrd.Set(outTradeNo)
  228. ord, err := centralKitchenForSchoolPackageOrd.GetCentralKitchenForSchoolPackageOrd()
  229. if err != nil {
  230. return
  231. }
  232. if ord == nil {
  233. err = errors.New("未查询到对应订单记录")
  234. return
  235. }
  236. if ord.State == enum2.CentralKitchenForSchoolPackageOrdStateForWait {
  237. if tradeStatus == "TRADE_CLOSED" {
  238. ord.State = enum2.CentralKitchenForSchoolPackageOrdStateForFail
  239. }
  240. if tradeStatus == "TRADE_SUCCESS" {
  241. ord.State = enum2.CentralKitchenForSchoolPackageOrdStateForSuccess
  242. ord.OrdState = enum2.CentralKitchenForSchoolPackageOrdOrdStateForSuccess
  243. //TODO::将预留数据插入到 `central_kitchen_for_school_user_with_day`
  244. var data []*model.CentralKitchenForSchoolUserWithDay
  245. err = json.Unmarshal([]byte(ord.WithDayData), &data)
  246. if err != nil {
  247. return
  248. }
  249. var hasMonths = map[string]map[string]interface{}{}
  250. var hasKinds = map[string]map[string]string{}
  251. var hasTotalPrice = map[string]map[string]float64{}
  252. for _, v := range data {
  253. date, _ := time.ParseInLocation("2006-01-02", v.Date, time.Local)
  254. if hasMonths[utils.TimeParseStd(v.Date).Month().String()] == nil {
  255. hasMonths[utils.TimeParseStd(v.Date).Month().String()] = make(map[string]interface{})
  256. hasMonths[utils.TimeParseStd(v.Date).Month().String()]["meal_time_start"] = date.Format("2006-01-02")
  257. hasMonths[utils.TimeParseStd(v.Date).Month().String()]["meal_time_end"] = date.Format("2006-01-02")
  258. } else {
  259. startTime, _ := time.ParseInLocation("2006-01-02", utils.AnyToString(hasMonths[utils.TimeParseStd(v.Date).Month().String()]["meal_time_start"]), time.Local)
  260. if startTime.After(date) {
  261. hasMonths[utils.TimeParseStd(v.Date).Month().String()]["meal_time_start"] = date.Format("2006-01-02")
  262. }
  263. endTime, _ := time.ParseInLocation("2006-01-02", utils.AnyToString(hasMonths[utils.TimeParseStd(v.Date).Month().String()]["meal_time_end"]), time.Local)
  264. if endTime.Before(date) {
  265. hasMonths[utils.TimeParseStd(v.Date).Month().String()]["meal_time_end"] = date.Format("2006-01-02")
  266. }
  267. }
  268. if hasTotalPrice[utils.TimeParseStd(v.Date).Month().String()] == nil {
  269. hasTotalPrice[utils.TimeParseStd(v.Date).Month().String()] = make(map[string]float64)
  270. }
  271. if hasKinds[utils.TimeParseStd(v.Date).Month().String()] == nil {
  272. hasKinds[utils.TimeParseStd(v.Date).Month().String()] = make(map[string]string)
  273. }
  274. hasMonths[utils.TimeParseStd(v.Date).Month().String()]["month"] = int(utils.TimeParseStd(v.Date).Month())
  275. hasKinds[utils.TimeParseStd(v.Date).Month().String()][utils.IntToStr(v.Kind)] = utils.IntToStr(v.Kind)
  276. hasTotalPrice[utils.TimeParseStd(v.Date).Month().String()][utils.IntToStr(v.Kind)] += utils.StrToFloat64(v.Amount)
  277. v.OrdNo = outTradeNo
  278. }
  279. centralKitchenForSchoolUserWithDayDb := db.CentralKitchenForSchoolUserWithDayDb{}
  280. centralKitchenForSchoolUserWithDayDb.Set(0)
  281. _, err = centralKitchenForSchoolUserWithDayDb.BatchAddCentralKitchenForSchoolUserWithDays(data)
  282. if err != nil {
  283. return
  284. }
  285. //TODO::插入数据至 `central_kitchen_for_school_package_ord_for_reserve`
  286. centralKitchenForSchoolPackageOrdForReserve := db.CentralKitchenForSchoolPackageOrdForReserve{}
  287. centralKitchenForSchoolPackageOrdForReserve.Set(outTradeNo)
  288. for k, v := range hasMonths {
  289. for _, v1 := range hasKinds[k] {
  290. _, err = centralKitchenForSchoolPackageOrdForReserve.CentralKitchenForSchoolPackageOrdForReserveInsert(&model.CentralKitchenForSchoolPackageOrdForReserve{
  291. EnterpriseId: ord.EnterpriseId,
  292. Uid: ord.Uid,
  293. UserIdentityName: ord.UserIdentityName,
  294. UserIdentityId: ord.UserIdentityId,
  295. Kind: utils.StrToInt(v1),
  296. OutTradeNo: ord.OutTradeNo,
  297. ReserveMonth: utils.AnyToString(v["month"]),
  298. MealTimeStart: utils.AnyToString(v["meal_time_start"]),
  299. MealTimeEnd: utils.AnyToString(v["meal_time_end"]),
  300. TotalPrice: utils.Float64ToStr(hasTotalPrice[k][v1]),
  301. CreateAt: time.Now().Format("2006-01-02 15:04:05"),
  302. UpdateAt: time.Now().Format("2006-01-02 15:04:05"),
  303. })
  304. if err != nil {
  305. return
  306. }
  307. }
  308. }
  309. }
  310. _, err = centralKitchenForSchoolPackageOrd.CentralKitchenForSchoolPackageOrdUpdate(ord, "state", "ord_state")
  311. if err != nil {
  312. return
  313. }
  314. }
  315. state = ord.State
  316. return
  317. }
  318. func CheckAllCallbackParams(c *gin.Context) interface{} {
  319. body, _ := ioutil.ReadAll(c.Request.Body)
  320. utils.FilePutContents("CheckAllCallbackParams", utils.SerializeStr(string(body)))
  321. dataAlipay, _ := GetAlipayCallbackParams(body)
  322. if dataAlipay != nil {
  323. return dataAlipay
  324. }
  325. return nil
  326. }
  327. // GetAlipayCallbackParams 支付宝参数解析
  328. func GetAlipayCallbackParams(body []byte) (*md.AliPayCallback, error) {
  329. decodeArgs, err := url.QueryUnescape(string(body))
  330. if err != nil {
  331. _ = logx.Warn(err)
  332. return nil, logx.Warn("回调参数解码错误")
  333. }
  334. data, err := url.ParseQuery(decodeArgs)
  335. if err != nil {
  336. return nil, err
  337. }
  338. dataMap := make(map[string]interface{})
  339. for k := range data {
  340. dataMap[k] = data.Get(k)
  341. }
  342. callbackStr := utils.Serialize(dataMap)
  343. fmt.Println("支付宝回调数据", string(callbackStr))
  344. var args md.AliPayCallback
  345. if err := json.Unmarshal(callbackStr, &args); err != nil {
  346. return nil, logx.Warn(err)
  347. }
  348. return &args, nil
  349. }