面包店
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

svc_goods.go 13 KiB

9 months ago
9 months ago
9 months ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. package goods
  2. import (
  3. "applet/app/admin/enum"
  4. "applet/app/admin/md"
  5. "applet/app/db"
  6. "applet/app/db/model"
  7. "applet/app/e"
  8. "applet/app/svc"
  9. "applet/app/utils"
  10. "applet/app/utils/logx"
  11. "fmt"
  12. "github.com/gin-gonic/gin"
  13. "github.com/jinzhu/copier"
  14. "github.com/pkg/errors"
  15. "reflect"
  16. "strings"
  17. "time"
  18. )
  19. // 处理图片
  20. func DealImg(c *gin.Context, imageListUrl []string) []string {
  21. //七牛云配置
  22. scheme, host, subDomain, moreSubDomain := svc.ImageBucketNew(c)
  23. domain := fmt.Sprintf("%s://%s/", scheme, host)
  24. secondDomain := fmt.Sprintf("%s://%s/", scheme, subDomain)
  25. fmt.Println("")
  26. //处理图片链接
  27. for k, v := range imageListUrl {
  28. imageListUrl[k] = strings.ReplaceAll(v, domain, "{{host}}")
  29. imageListUrl[k] = strings.ReplaceAll(imageListUrl[k], secondDomain, "{{subhost}}")
  30. //兼容商品是迁移过来的
  31. for moreK, moreV := range moreSubDomain {
  32. keys := strings.ReplaceAll(moreK, "file_bucket_sub_host", "")
  33. moreDomain := fmt.Sprintf("%s://%s/", scheme, moreV)
  34. imageListUrl[k] = strings.ReplaceAll(imageListUrl[k], moreDomain, "{{subhost"+keys+"}}")
  35. }
  36. }
  37. return imageListUrl
  38. }
  39. // AddMallGoods 添加、编辑商品
  40. func AddMallGoods(c *gin.Context, req *md.AddGoodsReq) error {
  41. if req.Base.GoodsId != "" {
  42. _, has, err := db.GetComm(db.Db, &model.Goods{GoodsId: utils.StrToInt64(req.Base.GoodsId)})
  43. if err != nil {
  44. return e.NewErr(e.ERR_DB_ORM, err.Error())
  45. }
  46. if !has {
  47. return e.NewErr(e.ERR_INVALID_ARGS, "编辑的商品ID不存在")
  48. }
  49. }
  50. sess := db.Db.NewSession()
  51. defer func() {
  52. _ = sess.Close()
  53. }()
  54. err := sess.Begin()
  55. if err != nil {
  56. return e.NewErr(e.ERR_DB_ORM, err.Error())
  57. }
  58. // 基本信息保存
  59. var goodsModel model.Goods
  60. err = copier.Copy(&goodsModel, req.Base)
  61. goodsModel.GoodsId = utils.StrToInt64(req.Base.GoodsId)
  62. if err != nil {
  63. return e.NewErr(e.ERR_DB_ORM, err.Error())
  64. }
  65. now := time.Now()
  66. goodsModel.SaleState = int(enum.MallGoodsSaleStateOnShelf)
  67. goodsModel.CreateAt = now.Format("2006-01-02 03:04:05")
  68. goodsModel.UpdateAt = now.Format("2006-01-02 03:04:05")
  69. //处理图片链接
  70. req.Base.ImageListUrl = DealImg(c, req.Base.ImageList)
  71. goodsModel.ImageList = utils.SerializeStr(req.Base.ImageListUrl)
  72. goodsModel.Spe = utils.SerializeStr(req.Base.Spe)
  73. //处理图片链接
  74. req.Base.DetailUrl = DealImg(c, req.Base.Detail)
  75. goodsModel.Detail = utils.SerializeStr(req.Base.DetailUrl) // detail为详情图列表
  76. if req.Base.GoodsId == "" {
  77. category, err := db.GetCategoryById(db.Db, utils.AnyToString(req.Base.CategoryId))
  78. if err != nil {
  79. _ = sess.Rollback()
  80. return err
  81. }
  82. goodsId, err := MakeGoodsId(c, utils.AnyToString(category.Id))
  83. if err != nil {
  84. _ = sess.Rollback()
  85. return err
  86. }
  87. goodsModel.GoodsId = utils.StrToInt64(goodsId)
  88. affect, err := sess.Insert(&goodsModel)
  89. if err != nil || affect != 1 {
  90. _ = sess.Rollback()
  91. return e.NewErr(e.ERR_DB_ORM, "插入商品失败")
  92. }
  93. } else {
  94. affect, err := sess.Where("goods_id=?", req.Base.GoodsId).AllCols().Update(&goodsModel)
  95. if err != nil || affect != 1 {
  96. return e.NewErr(e.ERR_DB_ORM, "更新商品失败")
  97. }
  98. }
  99. // 统计总库存
  100. // sku保存
  101. // 创建商品,则全部为插入
  102. skuModelList := make([]*model.Sku, 0, len(req.SkuList))
  103. for key, item := range req.SkuList {
  104. skuModelList = append(skuModelList, &model.Sku{
  105. SkuId: utils.StrToInt64(utils.AnyToString(goodsModel.GoodsId) + utils.AnyToString(key)),
  106. GoodsId: goodsModel.GoodsId,
  107. SkuCode: item.SkuCode,
  108. Price: item.Price,
  109. Indexes: GetIndexesStr(&req.Base, item),
  110. Sku: utils.SerializeStr(&item.Sku),
  111. CreateAt: now.Format("2006-01-02 03:04:05"),
  112. UpdateAt: now.Format("2006-01-02 03:04:05"),
  113. })
  114. }
  115. if req.Base.GoodsId != "" {
  116. // 如果是更新 先删除旧的再插入
  117. _, err = sess.Delete(&model.Sku{GoodsId: goodsModel.GoodsId})
  118. if err != nil {
  119. return e.NewErr(e.ERR_DB_ORM, "规格更新失败")
  120. }
  121. }
  122. // 插入sku
  123. insert, err := sess.Insert(skuModelList)
  124. if err != nil {
  125. fmt.Println(err)
  126. logx.Warn(err)
  127. return err
  128. }
  129. if insert < 1 {
  130. return e.NewErr(e.ERR_DB_ORM, "插入商品规格失败")
  131. }
  132. err = sess.Commit()
  133. if err != nil {
  134. return e.NewErr(e.ERR_DB_ORM, "更新商品失败")
  135. }
  136. return nil
  137. }
  138. // EditMallGoods 編辑商品
  139. func EditMallGoods(c *gin.Context, req *md.AddGoodsReq) error {
  140. _, has, err := db.GetComm(db.Db, &model.Goods{GoodsId: utils.StrToInt64(req.Base.GoodsId)})
  141. if err != nil {
  142. return e.NewErr(e.ERR_DB_ORM, err.Error())
  143. }
  144. if !has {
  145. return e.NewErr(e.ERR_INVALID_ARGS, "编辑的商品ID不存在")
  146. }
  147. sess := db.Db.NewSession()
  148. defer func() {
  149. _ = sess.Close()
  150. }()
  151. err = sess.Begin()
  152. if err != nil {
  153. return e.NewErr(e.ERR_DB_ORM, err.Error())
  154. }
  155. // 基本信息保存
  156. var goodsModel model.Goods
  157. err = copier.Copy(&goodsModel, req.Base)
  158. goodsModel.GoodsId = utils.StrToInt64(req.Base.GoodsId)
  159. if err != nil {
  160. return e.NewErr(e.ERR_DB_ORM, err.Error())
  161. }
  162. now := time.Now()
  163. goodsModel.UpdateAt = now.Format("2006-01-02 03:04:05")
  164. //处理图片链接
  165. req.Base.ImageListUrl = DealImg(c, req.Base.ImageList)
  166. goodsModel.ImageList = utils.SerializeStr(req.Base.ImageListUrl)
  167. goodsModel.Spe = utils.SerializeStr(req.Base.Spe)
  168. //处理图片链接
  169. req.Base.DetailUrl = DealImg(c, req.Base.Detail)
  170. goodsModel.Detail = utils.SerializeStr(req.Base.DetailUrl) // detail为详情图列表
  171. if req.Base.GoodsId == "" {
  172. goodsModel.SaleState = 0
  173. affect, err := sess.Insert(&goodsModel)
  174. if err != nil || affect != 1 {
  175. _ = sess.Rollback()
  176. return e.NewErr(e.ERR_DB_ORM, "插入商品失败")
  177. }
  178. } else {
  179. _, err := sess.Where("goods_id=?", req.Base.GoodsId).AllCols().Update(&goodsModel)
  180. if err != nil {
  181. return e.NewErr(e.ERR_DB_ORM, "更新商品失败")
  182. }
  183. }
  184. // sku保存
  185. // 创建商品,则全部为插入
  186. skuModelList := make([]*model.Sku, 0, len(req.SkuList))
  187. for key, item := range req.SkuList {
  188. skuModelList = append(skuModelList, &model.Sku{
  189. SkuId: utils.StrToInt64(utils.AnyToString(goodsModel.GoodsId) + "0" + utils.AnyToString(key)),
  190. GoodsId: goodsModel.GoodsId,
  191. Price: item.Price,
  192. SkuCode: item.SkuCode,
  193. Indexes: GetIndexesStr(&req.Base, item),
  194. Sku: utils.SerializeStr(&item.Sku),
  195. CreateAt: now.Format("2006-01-02 03:04:05"),
  196. UpdateAt: now.Format("2006-01-02 03:04:05"),
  197. })
  198. }
  199. //先删除旧的再插入
  200. _, err = sess.Delete(&model.Sku{GoodsId: goodsModel.GoodsId})
  201. if err != nil {
  202. return e.NewErr(e.ERR_DB_ORM, "规格更新失败")
  203. }
  204. // 插入sku
  205. insert, err := sess.Insert(skuModelList)
  206. if err != nil || insert < 1 {
  207. return e.NewErr(e.ERR_DB_ORM, "插入商品规格失败")
  208. }
  209. err = sess.Commit()
  210. if err != nil {
  211. return e.NewErr(e.ERR_DB_ORM, "更新商品失败")
  212. }
  213. return nil
  214. }
  215. // GetIndexesStr sku属性值在spe中的index
  216. func GetIndexesStr(baseGoods *md.MallBaseGoods, goodsSku *md.MallGoodsSku) string {
  217. spe := baseGoods.Spe
  218. sku := goodsSku.Sku
  219. result := ""
  220. for index, item := range sku {
  221. for _, itm := range spe {
  222. if item.Name == itm.Name {
  223. for i, v := range spe[index].Values {
  224. if v == item.Value {
  225. result = result + utils.IntToStr(i) + "-"
  226. }
  227. }
  228. }
  229. }
  230. }
  231. return strings.Trim(result, "-")
  232. }
  233. func GetGoodsDetail(c *gin.Context, id int) (map[string]interface{}, error) {
  234. resp := make(map[string]interface{})
  235. var skuList []*model.Sku
  236. var goodsModel *model.Goods
  237. // 新增商品的时候默认数据
  238. if id == 0 {
  239. resp["base_goods"] = nil
  240. resp["sku"] = nil
  241. return resp, nil
  242. }
  243. goodsModelInterface, has, err := db.GetComm(db.Db, &model.Goods{GoodsId: int64(id)})
  244. if !has {
  245. return nil, errors.New("当前商品不存在")
  246. }
  247. if err != nil {
  248. _ = logx.Error(err)
  249. return nil, e.NewErr(e.ERR_DB_ORM, fmt.Sprintf("查询商品失败:%#v", err))
  250. }
  251. goodsModel = goodsModelInterface.(*model.Goods)
  252. err = db.Db.Where("goods_id=?", id).Find(&skuList)
  253. if err != nil || len(skuList) == 0 {
  254. _ = logx.Error(err)
  255. return nil, e.NewErr(e.ERR_DB_ORM, fmt.Sprintf("查询商品规格失败:%#v\n", err))
  256. }
  257. var goodsMap map[string]interface{}
  258. utils.Unserialize([]byte(utils.SerializeStr(goodsModel)), &goodsMap)
  259. goodsMap["goods_id"] = utils.AnyToString(goodsModel.GoodsId)
  260. // 分类名称
  261. if goodsModel != nil && goodsModel.CategoryId != 0 {
  262. categoryInterface, has, err := db.GetComm(db.Db, &model.GoodsCategory{Id: goodsModel.CategoryId})
  263. if err != nil {
  264. return nil, errors.New("查询商品类目失败")
  265. }
  266. categoryModel := categoryInterface.(*model.GoodsCategory)
  267. if !has {
  268. goodsMap["category_name"] = ""
  269. } else {
  270. goodsMap["category_name"] = categoryModel.Name
  271. }
  272. }
  273. // **处理各复合结构**
  274. var tmpMap interface{}
  275. scheme, host, subDomain, moreSubDomain := svc.ImageBucketNew(c)
  276. // 商品主图
  277. if goodsMap["image_list"] != nil && goodsMap["image_list"] != "null" {
  278. utils.Unserialize([]byte(goodsMap["image_list"].(string)), &tmpMap)
  279. goodsMap["image_list"] = tmpMap
  280. var imageListUrlTmp []string
  281. for _, v := range goodsMap["image_list"].([]interface{}) {
  282. imageListUrlTmp = append(imageListUrlTmp, svc.ImageFormatWithBucketNew(scheme, host, subDomain, moreSubDomain, v.(string)))
  283. }
  284. goodsMap["image_list_url"] = imageListUrlTmp
  285. } else {
  286. goodsMap["image_list"] = []struct{}{}
  287. goodsMap["image_list_url"] = []struct{}{}
  288. }
  289. // 详情图
  290. if goodsMap["detail"] != nil && goodsMap["detail"] != "null" {
  291. var tmpDetailImageList []interface{}
  292. utils.Unserialize([]byte(goodsMap["detail"].(string)), &tmpDetailImageList)
  293. goodsMap["detail"] = tmpDetailImageList
  294. var detailImageUrlTmp []string
  295. for _, v := range goodsMap["detail"].([]interface{}) {
  296. detailImageUrlTmp = append(detailImageUrlTmp, svc.ImageFormatWithBucketNew(scheme, host, subDomain, moreSubDomain, v.(string)))
  297. }
  298. goodsMap["detail_url"] = detailImageUrlTmp
  299. }
  300. if goodsMap["detail"] == nil || reflect.ValueOf(goodsMap["detail"]).IsNil() {
  301. goodsMap["detail"] = []interface{}{}
  302. goodsMap["detail_url"] = []interface{}{}
  303. }
  304. // 规格属性
  305. speJson, ok := goodsMap["spe"].(string)
  306. if ok {
  307. if goodsMap["spe"] != nil && speJson != "" && speJson != "null" {
  308. utils.Unserialize([]byte(speJson), &tmpMap)
  309. goodsMap["spe"] = tmpMap
  310. } else {
  311. utils.Unserialize([]byte("[{\"name\": \"默认\",\"values\": [\"默认\"]}]"), &tmpMap)
  312. goodsMap["spe"] = tmpMap
  313. }
  314. } else {
  315. utils.Unserialize([]byte("[{\"name\": \"默认\",\"values\": [\"默认\"]}]"), &tmpMap)
  316. goodsMap["spe"] = tmpMap
  317. }
  318. if goodsMap["spe_images"] != nil && goodsMap["spe_images"] != "null" && goodsMap["spe_images"] != "[]" && goodsMap["spe_images"] != "" {
  319. var speImageListUrlTmp []string
  320. utils.Unserialize([]byte(goodsMap["spe_images"].(string)), &tmpMap)
  321. goodsMap["spe_images"] = tmpMap
  322. for _, v := range goodsMap["spe_images"].([]interface{}) {
  323. speImageListUrlTmp = append(speImageListUrlTmp, svc.ImageFormatWithBucketNew(scheme, host, subDomain, moreSubDomain, v.(string)))
  324. }
  325. goodsMap["spe_images_url"] = speImageListUrlTmp
  326. } else {
  327. goodsMap["spe_images"] = []struct{}{}
  328. goodsMap["spe_images_url"] = []struct{}{}
  329. }
  330. // sku处理
  331. skuListMap := make([]map[string]interface{}, 0, len(skuList))
  332. for _, item := range skuList {
  333. tmp := make(map[string]interface{})
  334. tmp["goods_id"] = item.GoodsId
  335. tmp["sku_id"] = item.SkuId
  336. tmp["sku_code"] = item.SkuCode
  337. tmp["price"] = item.Price
  338. tmp["indexes"] = item.Indexes
  339. utils.Unserialize([]byte(item.Sku), &tmpMap)
  340. tmp["sku"] = tmpMap
  341. if item.Indexes == "" || item.Indexes == " " {
  342. tmp["indexes"] = "0"
  343. utils.Unserialize([]byte("[{\"name\": \"默认\",\"values\": [\"默认\"]}]"), &tmpMap)
  344. tmp["sku"] = tmpMap
  345. }
  346. skuListMap = append(skuListMap, tmp)
  347. }
  348. // 清理不用的字段
  349. if _, ok := goodsMap["create_time"]; ok {
  350. delete(goodsMap, "create_at")
  351. }
  352. if _, ok := goodsMap["update_time"]; ok {
  353. delete(goodsMap, "update_at")
  354. }
  355. if _, ok := goodsMap["delete_at"]; ok {
  356. delete(goodsMap, "delete_at")
  357. }
  358. goodsMap["sale_state_zh"] = ""
  359. if _, ok := goodsMap["sale_state"]; ok {
  360. switch goodsMap["sale_state"] {
  361. case 1.00:
  362. goodsMap["sale_state_zh"] = "销售中"
  363. break
  364. case 2.00:
  365. goodsMap["sale_state_zh"] = "下架"
  366. break
  367. }
  368. }
  369. goodsMap["create_at"] = goodsModel.CreateAt
  370. goodsMap["update_at"] = goodsModel.UpdateAt
  371. resp["base_goods"] = goodsMap
  372. resp["sku"] = skuListMap
  373. return resp, nil
  374. }
  375. func MakeGoodsId(c *gin.Context, categoryId string) (string, error) {
  376. var goodsId = categoryId + utils.AnyToString(time.Now().UnixNano()/1e6)
  377. return goodsId, nil
  378. }
  379. func DelMallGoods(c *gin.Context, ids []string) {
  380. engine := db.Db
  381. session := engine.NewSession()
  382. defer func() {
  383. session.Close()
  384. }()
  385. session.Begin()
  386. _, err := session.Table("goods").Where(fmt.Sprintf("goods_id in (%s)", strings.Join(ids, ","))).Delete(new(model.Goods))
  387. if err != nil {
  388. session.Rollback()
  389. e.OutErr(c, e.ERR_DB_ORM, err)
  390. return
  391. }
  392. _, err = session.Table("sku").In("goods_id", ids).Delete(new(model.Sku))
  393. if err != nil {
  394. session.Rollback()
  395. e.OutErr(c, e.ERR_DB_ORM, err)
  396. return
  397. }
  398. session.Commit()
  399. e.OutSuc(c, []int{}, nil)
  400. }