golang 的 rabbitmq 消费项目
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 25 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  1. package svc
  2. import (
  3. "applet/app/db"
  4. "applet/app/e"
  5. svc2 "applet/app/svc"
  6. "applet/app/utils"
  7. "applet/app/utils/cache"
  8. "applet/app/utils/logx"
  9. db2 "applet/supply/db"
  10. "applet/supply/db/model"
  11. "applet/supply/enum"
  12. "applet/supply/md"
  13. "errors"
  14. "fmt"
  15. "github.com/gin-gonic/gin"
  16. "github.com/jinzhu/copier"
  17. cregex "github.com/mingrammer/commonregex"
  18. "github.com/shopspring/decimal"
  19. "regexp"
  20. "strings"
  21. "time"
  22. )
  23. //处理图片
  24. func DealImg(c *gin.Context, imageListUrl []string) []string {
  25. //七牛云配置
  26. scheme, host, subDomain, moreSubDomain := ImageBucketNew(c)
  27. domain := fmt.Sprintf("%s://%s/", scheme, host)
  28. secondDomain := fmt.Sprintf("%s://%s/", scheme, subDomain)
  29. fmt.Println("")
  30. //处理图片链接
  31. for k, v := range imageListUrl {
  32. imageListUrl[k] = strings.ReplaceAll(v, domain, "{{host}}")
  33. imageListUrl[k] = strings.ReplaceAll(imageListUrl[k], secondDomain, "{{subhost}}")
  34. //兼容商品是迁移过来的
  35. for moreK, moreV := range moreSubDomain {
  36. keys := strings.ReplaceAll(moreK, "file_bucket_sub_host", "")
  37. moreDomain := fmt.Sprintf("%s://%s/", scheme, moreV)
  38. imageListUrl[k] = strings.ReplaceAll(imageListUrl[k], moreDomain, "{{subhost"+keys+"}}")
  39. }
  40. }
  41. return imageListUrl
  42. }
  43. func CloudChainFenXiaoGoodsChangeMallGoods(c *gin.Context, cloudChainGoods map[string]interface{}, mallGoods *md.AddGoodsReq) error {
  44. defer func() {
  45. if err := recover(); err != nil {
  46. logx.Error(err)
  47. }
  48. }()
  49. productInfo, ok := cloudChainGoods["productInfo"].(map[string]interface{})
  50. if !ok {
  51. return logx.Error("错误的数据")
  52. }
  53. shippingInfo, ok := productInfo["shippingInfo"].(map[string]interface{})
  54. if !ok {
  55. return logx.Error("错误的数据")
  56. }
  57. tem, err := CloudChainGoodsShippingTemChangeMallShippingTem(c, shippingInfo, mallGoods.Base.CloudChainGoodsId, mallGoods.Base.MerchantId)
  58. if err != nil {
  59. return err
  60. }
  61. key := fmt.Sprintf("%s:merchant_1688_line_price_rete", c.GetString("mid"))
  62. rate, _ := cache.GetString(key)
  63. if rate == "" {
  64. rate = "50"
  65. }
  66. rateD, _ := decimal.NewFromString(rate)
  67. rateD = rateD.Div(decimal.NewFromInt(100))
  68. rate = rateD.String()
  69. rateF := utils.AnyToFloat64(rate)
  70. mallGoods.Base.GoodsCode = "f1x688" + mallGoods.Base.CloudChainGoodsId
  71. mallGoods.Base.ShippingType = enum.MallShippingTypeExpress
  72. if tem.Id == 1 && tem.CloudChainTemId == "1" {
  73. mallGoods.Base.ShippingFeeType = enum.MallShippingFeeTypeUnify
  74. mallGoods.Base.ShippingTplID = 0
  75. mallGoods.Base.ShippingFee = "0"
  76. } else if tem.Id == 0 && tem.CloudChainTemId == "1" {
  77. mallGoods.Base.ShippingFeeType = enum.MallShippingFeeTypeUnify
  78. mallGoods.Base.ShippingTplID = 0
  79. mallGoods.Base.ShippingFee = "0"
  80. } else if tem.Id == 0 && tem.CloudChainTemId != "" {
  81. mallGoods.Base.ShippingFeeType = enum.MallShippingFeeTypeUnify
  82. mallGoods.Base.ShippingTplID = 0
  83. mallGoods.Base.ShippingFee = "0"
  84. } else {
  85. mallGoods.Base.ShippingFeeType = enum.MallShippingFeeTypeTpl
  86. mallGoods.Base.ShippingTplID = tem.Id
  87. }
  88. //将1688的商品属性转换成custom_property
  89. var cloudChainGoodsSpeMap []struct {
  90. GroupName string `json:"group_name" label:"属性组别名称"`
  91. Index int `json:"index" label:"属性值索引"`
  92. Name string `json:"name" label:"属性值"`
  93. } // 自定义参数
  94. type Attribute struct {
  95. AttributeID int64 `json:"attributeID"`
  96. AttributeName string `json:"attributeName"`
  97. IsCustom bool `json:"isCustom"`
  98. Value string `json:"value"`
  99. }
  100. var attributes []*Attribute
  101. utils.Unserialize([]byte(utils.SerializeStr(productInfo["attributes"])), &attributes)
  102. for index, attribute := range attributes {
  103. cloudChainGoodsSpeMap = append(cloudChainGoodsSpeMap, struct {
  104. GroupName string `json:"group_name" label:"属性组别名称"`
  105. Index int `json:"index" label:"属性值索引"`
  106. Name string `json:"name" label:"属性值"`
  107. }{
  108. attribute.AttributeName,
  109. index,
  110. attribute.Value,
  111. })
  112. }
  113. //标题
  114. mallGoods.Base.Title = utils.AnyToString(productInfo["subject"])
  115. mallGoods.Base.CustomProperty = cloudChainGoodsSpeMap
  116. //最低限购
  117. mallGoods.Base.MinOrderQuantity = utils.AnyToString(productInfo["saleInfo"].(map[string]interface{})["minOrderQuantity"])
  118. //商品主图
  119. utils.Unserialize([]byte(utils.SerializeStr(productInfo["image"].(map[string]interface{})["images"])),
  120. &mallGoods.Base.ImageList)
  121. for i, image := range mallGoods.Base.ImageList {
  122. //https://cbu01.alicdn.com/
  123. if !strings.Contains(image, "https") || !strings.Contains(image, "http") {
  124. if !strings.Contains(image, "https://cbu01.alicdn.com") {
  125. mallGoods.Base.ImageList[i] = "https://cbu01.alicdn.com/" + image
  126. }
  127. }
  128. }
  129. //商品详情图
  130. if _, ok := productInfo["description"]; ok {
  131. compile := regexp.MustCompile("src=\"https://.*?\"")
  132. tmpsLinks := compile.FindAllString(utils.AnyToString(productInfo["description"]), -1)
  133. Links := cregex.Links(utils.AnyToString(tmpsLinks))
  134. mallGoods.Base.Detail = Links
  135. if len(mallGoods.Base.Detail) == 0 {
  136. mallGoods.Base.Detail = mallGoods.Base.ImageList
  137. }
  138. } else {
  139. if _, ok := productInfo["intelligentInfo"]; ok {
  140. utils.Unserialize([]byte(utils.SerializeStr(productInfo["intelligentInfo"].(map[string]interface{})["descriptionImages"])),
  141. &mallGoods.Base.Detail)
  142. if len(mallGoods.Base.Detail) == 0 {
  143. mallGoods.Base.Detail = mallGoods.Base.ImageList
  144. }
  145. } else {
  146. mallGoods.Base.Detail = mallGoods.Base.ImageList
  147. }
  148. }
  149. //处理sku
  150. type skuAttribute struct {
  151. AttributeID int64 `json:"attributeID"`
  152. AttributeName string `json:"attributeName"`
  153. AttributeValue string `json:"attributeValue"`
  154. SkuImageURL string `json:"skuImageUrl,omitempty"`
  155. }
  156. type skuInfo struct {
  157. RetailPrice float64 `json:"retailPrice"` //建议零售价
  158. AmountOnSale int `json:"amountOnSale"` //可销售数量
  159. Attributes []skuAttribute `json:"attributes"` //SKU属性值,可填多组信息
  160. CargoNumber string `json:"cargoNumber"` //指定规格的货号
  161. ConsignPrice float64 `json:"consignPrice"` //分销基准价。代销场景均使用该价格。无SKU商品查看saleInfo中的consignPrice
  162. Price float64 `json:"price"` // 报价时该规格的单价
  163. ChannelPrice float64 `json:"channelPrice"` // 厂货通渠道专享价(单位:元)
  164. CpsSuggestPrice float64 `json:"cpsSuggestPrice"` //CPS建议价(单位:元)
  165. SkuID int64 `json:"skuId"` //skuId,该规格在所有商品中的唯一标记
  166. SpecID string `json:"specId"` //specId,该规格在本商品内的唯一标记
  167. }
  168. var skuInfos []*skuInfo
  169. utils.Unserialize([]byte(utils.SerializeStr(productInfo["skuInfos"])), &skuInfos)
  170. BaseSpe := make(map[string]map[string]string)
  171. for _, info := range skuInfos {
  172. for _, attribute := range info.Attributes {
  173. valuesMap := BaseSpe[attribute.AttributeName]
  174. if valuesMap == nil {
  175. valuesMap = make(map[string]string)
  176. }
  177. valuesMap[attribute.AttributeValue] = ""
  178. BaseSpe[attribute.AttributeName] = valuesMap
  179. }
  180. }
  181. for name, valueMap := range BaseSpe {
  182. var spe md.Spe
  183. spe.Name = name
  184. values := make([]string, 0)
  185. for value, _ := range valueMap {
  186. values = append(values, value)
  187. }
  188. spe.Values = values
  189. mallGoods.Base.Spe = append(mallGoods.Base.Spe, spe)
  190. }
  191. for _, info := range skuInfos {
  192. var skuMd md.MallGoodsSku
  193. consignPrice := info.ConsignPrice
  194. if info.RetailPrice > 0 {
  195. consignPrice = info.RetailPrice
  196. } else {
  197. if consignPrice < info.ChannelPrice {
  198. consignPrice = info.ChannelPrice
  199. }
  200. }
  201. skuMd.LinePrice = utils.AnyToString(consignPrice + consignPrice*rateF)
  202. skuMd.Price = utils.AnyToString(consignPrice)
  203. skuMd.Stock = info.AmountOnSale
  204. skuMd.CloudChainSkuId = utils.AnyToString(info.SkuID)
  205. skuMd.SpecID = info.SpecID
  206. skuMd.Weight = utils.AnyToString(shippingInfo["unitWeight"])
  207. skuMd.SkuCode = "f1x688" + skuMd.CloudChainSkuId
  208. if len(info.Attributes) > 0 {
  209. skuMd.CloudChainSkuImgUrl = info.Attributes[0].SkuImageURL
  210. //https://cbu01.alicdn.com/
  211. if !strings.Contains(skuMd.CloudChainSkuImgUrl, "https") || !strings.Contains(skuMd.CloudChainSkuImgUrl, "http") {
  212. if !strings.Contains(skuMd.CloudChainSkuImgUrl, "https://cbu01.alicdn.com") {
  213. skuMd.CloudChainSkuImgUrl = "https://cbu01.alicdn.com/" + skuMd.CloudChainSkuImgUrl
  214. }
  215. }
  216. }
  217. skuSkuMap := make(map[string]*md.MallGoodsSkuSku)
  218. for _, attribute := range info.Attributes {
  219. var skuSkuMd md.MallGoodsSkuSku
  220. skuSkuMd.Name = attribute.AttributeName
  221. skuSkuMd.Value = attribute.AttributeValue
  222. _, ok := skuSkuMap[attribute.AttributeName]
  223. if !ok {
  224. skuMd.Sku = append(skuMd.Sku, skuSkuMd)
  225. skuSkuMap[attribute.AttributeName] = &skuSkuMd
  226. } else {
  227. break
  228. }
  229. }
  230. mallGoods.SkuList = append(mallGoods.SkuList, &skuMd)
  231. }
  232. if len(mallGoods.SkuList) == 0 {
  233. type PriceRange struct {
  234. Price float64 `json:"price"`
  235. StartQuantity int `json:"startQuantity"`
  236. }
  237. type saleInfo struct {
  238. AmountOnSale int `json:"amountOnSale"`
  239. MinOrderQuantity int `json:"minOrderQuantity"`
  240. MixWholeSale bool `json:"mixWholeSale"`
  241. PriceAuth bool `json:"priceAuth"`
  242. PriceRanges []PriceRange `json:"priceRanges"`
  243. QuoteType int `json:"quoteType"`
  244. SupportOnlineTrade bool `json:"supportOnlineTrade"`
  245. Unit string `json:"unit"`
  246. BatchNumber int `json:"batchNumber"`
  247. RetailPrice float64 `json:"retailprice"`
  248. Sellunit string `json:"sellunit"`
  249. ConsignPrice float64 `json:"consignPrice"`
  250. CpsSuggestPrice float64 `json:"cpsSuggestPrice"`
  251. ChannelPrice float64 `json:"channelPrice"`
  252. }
  253. var saleInfoMd saleInfo
  254. utils.Unserialize([]byte(utils.SerializeStr(productInfo["saleInfo"])), &saleInfoMd)
  255. consignPrice := saleInfoMd.ConsignPrice
  256. if consignPrice < saleInfoMd.ChannelPrice {
  257. consignPrice = saleInfoMd.ChannelPrice
  258. }
  259. for _, priceRange := range saleInfoMd.PriceRanges {
  260. if consignPrice < priceRange.Price {
  261. consignPrice = priceRange.Price
  262. }
  263. }
  264. var skuMd md.MallGoodsSku
  265. skuMd.LinePrice = utils.AnyToString(consignPrice + consignPrice*rateF)
  266. skuMd.Price = utils.AnyToString(consignPrice)
  267. skuMd.Stock = saleInfoMd.AmountOnSale
  268. skuMd.CloudChainSkuId = utils.AnyToString(mallGoods.Base.CloudChainGoodsId)
  269. skuMd.SpecID = ""
  270. skuMd.Weight = utils.AnyToString(shippingInfo["unitWeight"])
  271. skuMd.Sku = make([]md.MallGoodsSkuSku, 0)
  272. mallGoods.SkuList = append(mallGoods.SkuList, &skuMd)
  273. }
  274. return nil
  275. }
  276. func CalculateFirstAddPriceNumByMainSystem(price float64) float64 {
  277. var basicSetting model.SupplyBasicSetting
  278. get, _ := db.Db.Get(&basicSetting)
  279. if get {
  280. if basicSetting.PriceAdjustBaseType == 2 {
  281. if basicSetting.PriceAdjustType == 1 {
  282. afterPrice := price + utils.StrToFloat64(basicSetting.PriceAdjustValue)
  283. return afterPrice
  284. } else if basicSetting.PriceAdjustType == 2 {
  285. afterPrice := price + (price * (utils.StrToFloat64(basicSetting.PriceAdjustValue) / 100))
  286. return afterPrice
  287. }
  288. }
  289. return price
  290. }
  291. return price
  292. }
  293. func CloudChainGoodsChangeMallGoodsV2(c *gin.Context, cloudChainGoods map[string]interface{}, mallGoods *md.AddGoodsReq) error {
  294. defer func() {
  295. if err := recover(); err != nil {
  296. logx.Error(err)
  297. }
  298. }()
  299. productInfo, ok := cloudChainGoods["productInfo"].(map[string]interface{})
  300. if !ok {
  301. return logx.Error("错误的数据")
  302. }
  303. shippingInfo, ok := productInfo["shippingInfo"].(map[string]interface{})
  304. if !ok {
  305. return logx.Error("错误的数据")
  306. }
  307. key := fmt.Sprintf("%s:merchant_1688_line_price_rete", c.GetString("mid"))
  308. rate, _ := cache.GetString(key)
  309. if rate == "" {
  310. rate = "50"
  311. }
  312. rateD, _ := decimal.NewFromString(rate)
  313. rateD = rateD.Div(decimal.NewFromInt(100))
  314. rate = rateD.String()
  315. rateF := utils.AnyToFloat64(rate)
  316. mallGoods.Base.ShippingType = enum.MallShippingTypeExpress
  317. //将1688的商品属性转换成spe
  318. cloudChainGoodsSpeMap := make(map[string][]string)
  319. type Attribute struct {
  320. AttributeID int64 `json:"attributeID"`
  321. AttributeName string `json:"attributeName"`
  322. IsCustom bool `json:"isCustom"`
  323. Value string `json:"value"`
  324. }
  325. var attributes []*Attribute
  326. utils.Unserialize([]byte(utils.SerializeStr(productInfo["attributes"])), &attributes)
  327. for _, attribute := range attributes {
  328. cloudChainGoodsSpeMap[attribute.AttributeName] = append(cloudChainGoodsSpeMap[attribute.AttributeName], attribute.Value)
  329. }
  330. //标题
  331. mallGoods.Base.Title = utils.AnyToString(productInfo["subject"])
  332. //最低限购
  333. mallGoods.Base.MinOrderQuantity = utils.AnyToString(productInfo["saleInfo"].(map[string]interface{})["minOrderQuantity"])
  334. //商品主图
  335. utils.Unserialize([]byte(utils.SerializeStr(productInfo["image"].(map[string]interface{})["images"])),
  336. &mallGoods.Base.ImageList)
  337. for i, image := range mallGoods.Base.ImageList {
  338. //https://cbu01.alicdn.com/
  339. if !strings.Contains(image, "https") || !strings.Contains(image, "http") {
  340. if !strings.Contains(image, "https://cbu01.alicdn.com") {
  341. mallGoods.Base.ImageList[i] = "https://cbu01.alicdn.com/" + image
  342. }
  343. }
  344. }
  345. //商品详情图
  346. if _, ok := productInfo["description"]; ok {
  347. Links := cregex.Links(utils.AnyToString(productInfo["description"]))
  348. mallGoods.Base.Detail = Links
  349. if len(mallGoods.Base.Detail) == 0 {
  350. mallGoods.Base.Detail = mallGoods.Base.ImageList
  351. }
  352. } else {
  353. if _, ok := productInfo["intelligentInfo"]; ok {
  354. utils.Unserialize([]byte(utils.SerializeStr(productInfo["intelligentInfo"].(map[string]interface{})["descriptionImages"])),
  355. &mallGoods.Base.Detail)
  356. if len(mallGoods.Base.Detail) == 0 {
  357. mallGoods.Base.Detail = mallGoods.Base.ImageList
  358. }
  359. for i, img := range mallGoods.Base.Detail {
  360. if strings.Contains("\\", img) {
  361. mallGoods.Base.Detail[i] = strings.ReplaceAll(img, "\\", "")
  362. }
  363. }
  364. } else {
  365. mallGoods.Base.Detail = mallGoods.Base.ImageList
  366. }
  367. }
  368. //处理sku
  369. type skuAttribute struct {
  370. AttributeID int64 `json:"attributeID"`
  371. AttributeName string `json:"attributeName"`
  372. AttributeValue string `json:"attributeValue"`
  373. SkuImageURL string `json:"skuImageUrl,omitempty"`
  374. }
  375. type skuInfo struct {
  376. RetailPrice float64 `json:"retailPrice"` //建议零售价
  377. AmountOnSale int `json:"amountOnSale"` //可销售数量
  378. Attributes []skuAttribute `json:"attributes"` //SKU属性值,可填多组信息
  379. CargoNumber string `json:"cargoNumber"` //指定规格的货号
  380. ConsignPrice float64 `json:"consignPrice"` //分销基准价。代销场景均使用该价格。无SKU商品查看saleInfo中的consignPrice
  381. Price float64 `json:"price"` // 报价时该规格的单价
  382. ChannelPrice float64 `json:"channelPrice"` // 厂货通渠道专享价(单位:元)
  383. CpsSuggestPrice float64 `json:"cpsSuggestPrice"` //CPS建议价(单位:元)
  384. SkuID int64 `json:"skuId"` //skuId,该规格在所有商品中的唯一标记
  385. SpecID string `json:"specId"` //specId,该规格在本商品内的唯一标记
  386. }
  387. var skuInfos []*skuInfo
  388. utils.Unserialize([]byte(utils.SerializeStr(productInfo["skuInfos"])), &skuInfos)
  389. BaseSpe := make(map[string]map[string]string)
  390. for _, info := range skuInfos {
  391. for _, attribute := range info.Attributes {
  392. valuesMap := BaseSpe[attribute.AttributeName]
  393. if valuesMap == nil {
  394. valuesMap = make(map[string]string)
  395. }
  396. valuesMap[attribute.AttributeValue] = ""
  397. BaseSpe[attribute.AttributeName] = valuesMap
  398. }
  399. }
  400. for name, valueMap := range BaseSpe {
  401. var spe md.Spe
  402. spe.Name = name
  403. values := make([]string, 0)
  404. for value, _ := range valueMap {
  405. values = append(values, value)
  406. }
  407. spe.Values = values
  408. mallGoods.Base.Spe = append(mallGoods.Base.Spe, spe)
  409. }
  410. for _, info := range skuInfos {
  411. var skuMd md.MallGoodsSku
  412. consignPrice := info.ConsignPrice
  413. if info.RetailPrice > 0 {
  414. consignPrice = info.RetailPrice
  415. } else {
  416. if consignPrice < info.ChannelPrice {
  417. consignPrice = info.ChannelPrice
  418. }
  419. }
  420. skuMd.LinePrice = utils.AnyToString(consignPrice + consignPrice*rateF)
  421. skuMd.Price = utils.AnyToString(consignPrice)
  422. skuMd.Stock = info.AmountOnSale
  423. skuMd.CloudChainSkuId = utils.AnyToString(info.SkuID)
  424. skuMd.SpecID = info.SpecID
  425. skuMd.Weight = utils.AnyToString(shippingInfo["unitWeight"])
  426. if len(info.Attributes) > 0 {
  427. skuMd.CloudChainSkuImgUrl = info.Attributes[0].SkuImageURL
  428. //https://cbu01.alicdn.com/
  429. if skuMd.CloudChainSkuImgUrl != "" {
  430. if !strings.Contains(skuMd.CloudChainSkuImgUrl, "https") || !strings.Contains(skuMd.CloudChainSkuImgUrl, "http") {
  431. if !strings.Contains(skuMd.CloudChainSkuImgUrl, "https://cbu01.alicdn.com") {
  432. skuMd.CloudChainSkuImgUrl = "https://cbu01.alicdn.com/" + skuMd.CloudChainSkuImgUrl
  433. }
  434. }
  435. }
  436. }
  437. skuSkuMap := make(map[string]*md.MallGoodsSkuSku)
  438. for _, attribute := range info.Attributes {
  439. var skuSkuMd md.MallGoodsSkuSku
  440. skuSkuMd.Name = attribute.AttributeName
  441. skuSkuMd.Value = attribute.AttributeValue
  442. _, ok := skuSkuMap[attribute.AttributeName]
  443. if !ok {
  444. skuMd.Sku = append(skuMd.Sku, skuSkuMd)
  445. skuSkuMap[attribute.AttributeName] = &skuSkuMd
  446. } else {
  447. break
  448. }
  449. }
  450. mallGoods.SkuList = append(mallGoods.SkuList, &skuMd)
  451. }
  452. if len(mallGoods.SkuList) == 0 {
  453. type PriceRange struct {
  454. Price float64 `json:"price"`
  455. StartQuantity int `json:"startQuantity"`
  456. }
  457. type saleInfo struct {
  458. AmountOnSale int `json:"amountOnSale"`
  459. MinOrderQuantity int `json:"minOrderQuantity"`
  460. MixWholeSale bool `json:"mixWholeSale"`
  461. PriceAuth bool `json:"priceAuth"`
  462. PriceRanges []PriceRange `json:"priceRanges"`
  463. QuoteType int `json:"quoteType"`
  464. SupportOnlineTrade bool `json:"supportOnlineTrade"`
  465. Unit string `json:"unit"`
  466. BatchNumber int `json:"batchNumber"`
  467. RetailPrice float64 `json:"retailprice"`
  468. Sellunit string `json:"sellunit"`
  469. ConsignPrice float64 `json:"consignPrice"`
  470. CpsSuggestPrice float64 `json:"cpsSuggestPrice"`
  471. ChannelPrice float64 `json:"channelPrice"`
  472. }
  473. var saleInfoMd saleInfo
  474. utils.Unserialize([]byte(utils.SerializeStr(productInfo["saleInfo"])), &saleInfoMd)
  475. consignPrice := saleInfoMd.ConsignPrice
  476. if saleInfoMd.RetailPrice > 0 {
  477. consignPrice = saleInfoMd.RetailPrice
  478. } else {
  479. if consignPrice < saleInfoMd.ChannelPrice {
  480. consignPrice = saleInfoMd.ChannelPrice
  481. }
  482. for _, priceRange := range saleInfoMd.PriceRanges {
  483. if consignPrice < priceRange.Price {
  484. consignPrice = priceRange.Price
  485. }
  486. }
  487. }
  488. var skuMd md.MallGoodsSku
  489. skuMd.LinePrice = utils.AnyToString(consignPrice + consignPrice*rateF)
  490. skuMd.Price = utils.AnyToString(consignPrice)
  491. skuMd.Stock = saleInfoMd.AmountOnSale
  492. skuMd.CloudChainSkuId = utils.AnyToString(mallGoods.Base.CloudChainGoodsId)
  493. skuMd.SpecID = ""
  494. skuMd.Weight = utils.AnyToString(shippingInfo["unitWeight"])
  495. skuMd.Sku = make([]md.MallGoodsSkuSku, 0)
  496. mallGoods.SkuList = append(mallGoods.SkuList, &skuMd)
  497. }
  498. return nil
  499. }
  500. // AddMallGoods 添加、编辑商品
  501. func AddMallGoods(c *gin.Context, req *md.AddGoodsReq) error {
  502. if req.Base.GoodsId != "" {
  503. _, has, err := db.GetComm(svc2.MasterDb(c), &model.MallGoods{GoodsId: utils.StrToInt64(req.Base.GoodsId)})
  504. if err != nil {
  505. return e.NewErr(e.ERR_DB_ORM, err.Error())
  506. }
  507. if !has {
  508. return e.NewErr(e.ERR_INVALID_ARGS, "编辑的商品ID不存在")
  509. }
  510. }
  511. sess := svc2.MasterDb(c).NewSession()
  512. defer func() {
  513. _ = sess.Close()
  514. }()
  515. err := sess.Begin()
  516. if err != nil {
  517. return e.NewErr(e.ERR_DB_ORM, err.Error())
  518. }
  519. // 基本信息保存
  520. var goodsModel model.MallGoods
  521. err = copier.Copy(&goodsModel, req.Base)
  522. goodsModel.GoodsId = utils.StrToInt64(req.Base.GoodsId)
  523. if err != nil {
  524. return e.NewErr(e.ERR_DB_ORM, err.Error())
  525. }
  526. now := time.Now()
  527. goodsModel.CloudChainGoodsId = req.Base.CloudChainGoodsId
  528. goodsModel.MinOrderQuantity = req.Base.MinOrderQuantity
  529. goodsModel.SaleState = 0 //TODO::所有商家端编辑的产品,都需要重新审核
  530. goodsModel.MerchantId = req.Base.MerchantId
  531. goodsModel.GoodsCode = req.Base.GoodsCode
  532. goodsModel.CreateTime = now
  533. goodsModel.UpdateTime = now
  534. goodsModel.CustomProperty = utils.SerializeStr(req.Base.CustomProperty)
  535. SaleStartTime, _ := utils.TimeParse("2006-01-02 15:04:05", req.Base.SaleStartTime)
  536. goodsModel.SaleStartTime = SaleStartTime
  537. //处理图片链接
  538. req.Base.ImageListUrl = DealImg(c, req.Base.ImageList)
  539. goodsModel.ImageList = utils.SerializeStr(req.Base.ImageListUrl)
  540. goodsModel.Spe = utils.SerializeStr(req.Base.Spe)
  541. //处理图片链接
  542. req.Base.SpeImagesUrl = DealImg(c, req.Base.SpeImages)
  543. goodsModel.SpeImages = utils.SerializeStr(req.Base.SpeImagesUrl)
  544. //处理图片链接
  545. req.Base.DetailUrl = DealImg(c, req.Base.Detail)
  546. goodsModel.Detail = utils.SerializeStr(req.Base.DetailUrl) // detail为详情图列表
  547. if req.Base.Service != nil {
  548. goodsModel.Service = utils.SerializeStr(req.Base.Service) // 支持的服务
  549. }
  550. goodsModel.IsSpeImageInDetail = req.Base.IsSpeImageInDetail
  551. goodsModel.IsSpeImageOn = req.Base.IsSpeImageOn
  552. goodsModel.ShippingFeeType = int(req.Base.ShippingFeeType)
  553. goodsModel.ShippingFee = req.Base.ShippingFee
  554. goodsModel.ShippingTplId = req.Base.ShippingTplID
  555. if req.Base.GoodsId == "" {
  556. category, err := db2.GetCategoryById(svc2.MasterDb(c), utils.AnyToString(req.Base.CategoryId))
  557. if err != nil {
  558. _ = sess.Rollback()
  559. return err
  560. }
  561. goodsId, err := MakeGoodsId(c, utils.AnyToString(category.McId), utils.AnyToString(req.Base.CategoryId), utils.AnyToString(goodsModel.MerchantId))
  562. if err != nil {
  563. _ = sess.Rollback()
  564. return err
  565. }
  566. goodsModel.GoodsId = utils.StrToInt64(goodsId)
  567. merchant, err := db2.GetMerchantById(svc2.MasterDb(c), goodsModel.MerchantId)
  568. if err != nil {
  569. _ = sess.Rollback()
  570. return err
  571. }
  572. if merchant == nil {
  573. _ = sess.Rollback()
  574. return errors.New("未查询到对应供应商商家记录")
  575. }
  576. goodsModel.SaleState = 1
  577. if merchant.IsOpenAuditGoods == 1 {
  578. goodsModel.SaleState = 0
  579. }
  580. affect, err := sess.Insert(&goodsModel)
  581. if err != nil || affect != 1 {
  582. _ = sess.Rollback()
  583. return e.NewErr(e.ERR_DB_ORM, "插入商品失败")
  584. }
  585. } else {
  586. affect, err := sess.Where("goods_id=?", req.Base.GoodsId).AllCols().Update(&goodsModel)
  587. if err != nil || affect != 1 {
  588. return e.NewErr(e.ERR_DB_ORM, "更新商品失败")
  589. }
  590. }
  591. // 统计总库存
  592. var stockAll int
  593. // sku保存
  594. // 创建商品,则全部为插入
  595. skuModelList := make([]*model.MallSku, 0, len(req.SkuList))
  596. for key, item := range req.SkuList {
  597. stockAll += item.Stock
  598. skuModelList = append(skuModelList, &model.MallSku{
  599. SkuId: utils.StrToInt64(utils.AnyToString(goodsModel.GoodsId) + utils.AnyToString(key)),
  600. GoodsId: goodsModel.GoodsId,
  601. SkuCode: item.SkuCode,
  602. Price: item.Price,
  603. LinePrice: item.LinePrice,
  604. Weight: item.Weight,
  605. Stock: item.Stock,
  606. Indexes: GetIndexesStr(&req.Base, item),
  607. Sku: utils.SerializeStr(&item.Sku),
  608. CreateTime: now,
  609. UpdateTime: now,
  610. SpecId: item.SpecID,
  611. CloudChainSkuId: item.CloudChainSkuId,
  612. CloudChainSkuImgUrl: item.CloudChainSkuImgUrl,
  613. })
  614. }
  615. if req.Base.GoodsId != "" {
  616. // 如果是更新 先删除旧的再插入
  617. _, err = sess.Delete(&model.MallSku{GoodsId: goodsModel.GoodsId})
  618. if err != nil {
  619. return e.NewErr(e.ERR_DB_ORM, "规格更新失败")
  620. }
  621. }
  622. // 插入sku
  623. insert, err := sess.Insert(skuModelList)
  624. if err != nil {
  625. fmt.Println(err)
  626. logx.Warn(err)
  627. return err
  628. }
  629. if insert < 1 {
  630. return e.NewErr(e.ERR_DB_ORM, "插入商品规格失败")
  631. }
  632. minProfit := GetMinProfitRate(skuModelList)
  633. minPrice := GetMinPrice(skuModelList)
  634. // 更新总库存
  635. _, err = sess.Where("goods_id=?", goodsModel.GoodsId).Update(&model.MallGoods{
  636. Stock: stockAll,
  637. ProfitRate: utils.AnyToString(minProfit),
  638. Price: utils.AnyToString(minPrice),
  639. })
  640. if err != nil {
  641. return e.NewErr(e.ERR_DB_ORM, "更新总库存失败")
  642. }
  643. err = sess.Commit()
  644. if err != nil {
  645. return e.NewErr(e.ERR_DB_ORM, "更新商品失败")
  646. }
  647. return nil
  648. }
  649. func MakeGoodsId(c *gin.Context, mcId, categoryId, merchantId string) (string, error) {
  650. var goodsId = mcId + utils.AnyToString(time.Now().UnixNano()/1e6)
  651. return goodsId, nil
  652. }
  653. func GetIndexesStr(baseGoods *md.MallBaseGoods, goodsSku *md.MallGoodsSku) string {
  654. spe := baseGoods.Spe
  655. sku := goodsSku.Sku
  656. result := ""
  657. for index, item := range sku {
  658. for _, itm := range spe {
  659. if item.Name == itm.Name {
  660. for i, v := range spe[index].Values {
  661. if v == item.Value {
  662. result = result + utils.IntToStr(i) + "-"
  663. }
  664. }
  665. }
  666. }
  667. }
  668. return strings.Trim(result, "-")
  669. }