product_dal.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. package dal
  2. import (
  3. "crypto/md5"
  4. "database/sql"
  5. "errors"
  6. "fmt"
  7. "sort"
  8. "time"
  9. "gopkg.in/guregu/null.v3"
  10. "xiaoniaokuaiyan.com/xiaoniao/entity"
  11. "xiaoniaokuaiyan.com/xiaoniao/util"
  12. )
  13. type Product struct{}
  14. func (pdal *Product) Get(productIds []int) ([]*entity.ProductDB, error) {
  15. if len(productIds) == 0 {
  16. return nil, errors.New("wrong param prooduct id")
  17. }
  18. strSql := ""
  19. for _, pid := range productIds {
  20. strSql += fmt.Sprintf("%d,", pid)
  21. }
  22. //strSql = "select t1.*, group_concat(city_id) as cityIds, group_concat(county_id separator '-') as countyIds from t_product t1 left join t_product_city t2 on t1.id = t2.product_id where id in(" + strSql[0:len(strSql)-1] + ") and is_delete = 0 group by id;"
  23. strSql = "select t1.*, group_concat(city_id) as cityIds from t_product t1 left join v_product_city t2 on t1.id = t2.product_id where id in(" + strSql[0:len(strSql)-1] + ") and is_delete = 0 group by id;"
  24. db := util.GetSqlDB()
  25. plist := []*entity.ProductDB{}
  26. err := db.Select(&plist, strSql)
  27. if err != nil {
  28. return nil, err
  29. }
  30. for _, pitem := range plist {
  31. dps := []entity.DetectProduct{}
  32. db.Select(&dps, "select t1.* from t_detect_product t1 left join t_product_detect_product t2 on t1.id = t2.detect_product_id where t2.product_id = ?", pitem.Id)
  33. picList := []entity.ProductPicture{}
  34. db.Select(&picList, "select * from t_product_picture where product_id = ? order by pic_type desc", pitem.Id)
  35. attrList := []struct {
  36. ProductId int `db:"product_id" json:"product_id"`
  37. Name null.String `db:"name" json:"name"`
  38. Value null.String `db:"value" json:"value"`
  39. Pic string `db:"picture" json:"picture"`
  40. }{}
  41. //db.Select(&attrList, "select * from t_product_attribute where product_id = ?", pitem.Id)
  42. db.Select(&attrList, "select a.*,p.picture from t_product_attribute a left join t_product p on a.value = p.id where a.product_id = ?", pitem.Id)
  43. pitem.Pictures = picList
  44. pitem.Items = dps
  45. pitem.Attributes = attrList
  46. //query add attach city info
  47. cityList := []entity.City{}
  48. db.Select(&cityList, "select * from t_city where id in("+pitem.CityIds.String+");")
  49. //strCountyIds := pitem.CountyIds.String
  50. //countyIds := strings.Split(strCountyIds, "-")
  51. //cityIds := strings.Split(pitem.CityIds.String, ",")
  52. //countyMap := map[string]string{}
  53. //for i, cid := range cityIds {
  54. // for j, ctid := range countyIds {
  55. // if j != i {
  56. // continue
  57. // }
  58. // subCountyIds := strings.Split(ctid, ",")
  59. // for _, sctid := range subCountyIds {
  60. // countyMap[sctid] = cid
  61. // }
  62. // }
  63. //}
  64. //cityMap := map[string]int{}
  65. //for i, cityItem := range cityList {
  66. // cityMap[fmt.Sprintf("%d", cityItem.Id)] = i
  67. //}
  68. //strCountyIds = strings.Replace(strCountyIds, "-", ",", -1)
  69. //countys := []entity.County{}
  70. //db.Select(&countys, "select * from t_county where id in("+strCountyIds+");")
  71. //for _, ct := range countys {
  72. // if cid, ok := countyMap[fmt.Sprintf("%d", ct.Id)]; ok {
  73. // if idx, sok := cityMap[cid]; sok {
  74. // cityList[idx].Countys = append(cityList[idx].Countys, ct)
  75. // }
  76. // }
  77. //}
  78. pitem.Citys = cityList
  79. //pitem.CountyIds.SetValid(strings.Replace(pitem.CountyIds.String, "-", ",", -1))
  80. }
  81. return plist, nil
  82. }
  83. func (pdal *Product) GetByCateId(cids []int, pager Pager, cityId int, sp SortParam) ([]*entity.ProductDB, error) {
  84. if pager.PageIndex < 1 {
  85. pager.PageIndex = 1
  86. }
  87. var skip = (pager.PageIndex - 1) * pager.PageSize
  88. var (
  89. sortDir = "desc"
  90. sortBy = "is_recommend"
  91. )
  92. if sp.SortDir == 1 {
  93. sortDir = "asc"
  94. }
  95. switch sp.SortBy {
  96. case "SALE_NUM":
  97. sortBy = "sale_num"
  98. case "NEW":
  99. sortBy = "t2.created_at"
  100. case "SUM_UP":
  101. sortBy = "sort_no"
  102. case "PRICE":
  103. sortBy = "price"
  104. }
  105. var strCity = "and city_id =" + fmt.Sprintf("%d", cityId)
  106. if cityId == 0 {
  107. strCity = ""
  108. }
  109. db := util.GetSqlDB()
  110. if len(cids) > 0 && cids[0] == -3 {
  111. var childCids = []int{}
  112. db.Select(&childCids, "SELECT id from t_product_category WHERE parent_id in(?);", util.IntJoin(cids[1:], ","))
  113. cids = childCids
  114. }
  115. //strSql := "select t2.*,group_concat(city_id) as cityIds from t_product t2 left join t_product_category_product t1 on t1.product_id = t2.id join t_product_city t3 on t2.id = t3.product_id where t1.cat_id in(?) " + strCity + " and t2.is_putaway = 0 and t2.is_delete = 0 group by t2.id order by " + sortBy + " " + sortDir + ", t2.id desc limit ?,?;"
  116. strSql := "select t2.*,group_concat(city_id) as cityIds from t_product t2 left join t_product_category_product t1 on t1.product_id = t2.id join v_product_city t3 on t2.id = t3.product_id where t1.cat_id in(?) " + strCity + " and t2.is_putaway = 0 and t2.is_delete = 0 group by t2.id order by " + sortBy + " " + sortDir + ", t2.id desc limit ?,?;"
  117. var firstParam interface{} = util.IntJoin(cids, ",")
  118. if len(cids) > 0 {
  119. if cids[0] == -1 { //促销产品
  120. //strSql = "select t1.*, group_concat(city_id) as cityIds from t_product t1 left join t_product_city t2 on t1.id = t2.product_id where t1.id > ? and price <> market_price and market_price > 0 " + strCity + " and t1.is_putaway = 0 and t1.is_delete = 0 group by t1.id order by " + sortBy + " " + sortDir + ", t1.id desc limit ?,?;"
  121. strSql = "select t1.*, group_concat(city_id) as cityIds from t_product t1 left join v_product_city t2 on t1.id = t2.product_id where t1.id > ? and price <> market_price and market_price > 0 " + strCity + " and t1.is_putaway = 0 and t1.is_delete = 0 group by t1.id order by " + sortBy + " " + sortDir + ", t1.id desc limit ?,?;"
  122. firstParam = 0
  123. } else if cids[0] == -2 {
  124. //strSql = "select t1.*, group_concat(city_id) as cityIds from t_product t1 left join t_product_city t2 on t1.id = t2.product_id where t1.id > ? " + strCity + " and t1.is_putaway = 0 and t1.is_delete = 0 group by t1.id order by " + sortBy + " " + sortDir + ",t1.id desc limit ?,?"
  125. strSql = "select t1.*, group_concat(city_id) as cityIds from t_product t1 left join v_product_city t2 on t1.id = t2.product_id where t1.id > ? " + strCity + " and t1.is_putaway = 0 and t1.is_delete = 0 group by t1.id order by " + sortBy + " " + sortDir + ",t1.id desc limit ?,?"
  126. firstParam = 0
  127. }
  128. }
  129. plist := []*entity.ProductDB{}
  130. err := db.Select(&plist, strSql, firstParam, skip, pager.PageSize)
  131. if err != nil {
  132. return nil, err
  133. }
  134. for _, pitem := range plist {
  135. dps := []entity.DetectProduct{}
  136. db.Select(&dps, "select t1.* from t_detect_product t1 left join t_product_detect_product t2 on t1.id = t2.detect_product_id where t2.product_id = ?", pitem.Id)
  137. pitem.Items = dps
  138. }
  139. return plist, nil
  140. }
  141. func (pdal *Product) GetByTags(tags []string, pageIndex, pageSize uint, cityId int) ([]*entity.ProductDB, error) {
  142. if pageIndex < 1 {
  143. pageIndex = 1
  144. }
  145. if pageSize < 5 {
  146. pageSize = 5
  147. }
  148. var skip = pageSize * (pageIndex - 1)
  149. var strTag = ""
  150. for _, tag := range tags {
  151. strTag += "'" + tag + "',"
  152. }
  153. strTag = strTag[0 : len(strTag)-1]
  154. //strSql := "select distinct t3.* from t_tag t1 inner join t_product_tag t2 on t1.id = t2.tag_id inner join t_product t3 on t2.product_id = t3.id left join t_product_city t4 on t3.id = t4.product_id where t4.city_id = ? and t3.is_putaway = 0 and is_delete = 0 and t1.tag_name in (" + strTag + ") order by sort_no desc limit ?,?;"
  155. strSql := "select distinct t3.* from t_tag t1 inner join t_product_tag t2 on t1.id = t2.tag_id inner join t_product t3 on t2.product_id = t3.id left join v_product_city t4 on t3.id = t4.product_id where t4.city_id = ? and t3.is_putaway = 0 and is_delete = 0 and t1.tag_name in (" + strTag + ") order by sort_no desc limit ?,?;"
  156. db := util.GetSqlDB()
  157. plist := []*entity.ProductDB{}
  158. err := db.Select(&plist, strSql, cityId, skip, pageSize)
  159. if err != nil {
  160. return nil, err
  161. }
  162. for _, pitem := range plist {
  163. dps := []entity.DetectProduct{}
  164. db.Select(&dps, "select t1.* from t_detect_product t1 left join t_product_detect_product t2 on t1.id = t2.detect_product_id where t2.product_id = ?", pitem.Id)
  165. pitem.Items = dps
  166. }
  167. return plist, nil
  168. }
  169. func (pdal *Product) GetRecommend(pager Pager, cityId int, sp SortParam) ([]*entity.ProductDB, error) {
  170. if pager.PageIndex < 1 {
  171. pager.PageIndex = 1
  172. }
  173. if pager.PageSize < 5 {
  174. pager.PageSize = 5
  175. }
  176. var skip = (pager.PageIndex - 1) * pager.PageSize
  177. var (
  178. sortDir = "desc"
  179. sortBy = "sort_no"
  180. )
  181. if sp.SortDir == 1 {
  182. sortDir = "asc"
  183. }
  184. switch sp.SortBy {
  185. case "SALE_NUM":
  186. sortBy = "sale_num"
  187. case "NEW":
  188. sortBy = "t1.created_at"
  189. case "PRICE":
  190. sortBy = "price"
  191. }
  192. //strSql := "select * from t_product t1 left join t_product_city t2 on t1.id = t2.product_id where city_id = ? and is_recommend = 1 and is_putaway = 0 and is_delete = 0 order by " + sortBy + " " + sortDir + ", t1.id desc limit ?,?;"
  193. strSql := "select * from t_product t1 left join v_product_city t2 on t1.id = t2.product_id where city_id = ? and is_recommend = 1 and is_putaway = 0 and is_delete = 0 order by " + sortBy + " " + sortDir + ", t1.id desc limit ?,?;"
  194. db := util.GetSqlDB()
  195. plist := []*entity.ProductDB{}
  196. err := db.Select(&plist, strSql, cityId, skip, pager.PageSize)
  197. if err != nil {
  198. return nil, err
  199. }
  200. for _, pitem := range plist {
  201. dps := []entity.DetectProduct{}
  202. db.Select(&dps, "select t1.* from t_detect_product t1 left join t_product_detect_product t2 on t1.id = t2.detect_product_id where t2.product_id = ?", pitem.Id)
  203. pitem.Items = dps
  204. }
  205. return plist, nil
  206. }
  207. func (pdal *Product) GetCate(pid int) ([]entity.ProductCategory, error) {
  208. strSql := "select * from t_product_category where is_leaf = 1 and pos_type = ? order by sort_no desc"
  209. var firstParam interface{} = pid
  210. switch pid {
  211. case -1:
  212. strSql = "select * from t_product_category where id > ? order by sort_no asc;"
  213. firstParam = 0
  214. case -2:
  215. strSql = "select * from t_product_category where id > ? and is_leaf = 1;"
  216. firstParam = 0
  217. default:
  218. strSql = "select * from t_product_category where parent_id = ? order by sort_no asc;"
  219. }
  220. db := util.GetSqlDB()
  221. cateList := []entity.ProductCategory{}
  222. err := db.Select(&cateList, strSql, firstParam)
  223. return cateList, err
  224. }
  225. func (pdal *Product) GetTags(level, cityId int) ([]entity.Tag, error) {
  226. strSql := "select id, tag_name from t_tag where parent_id = ?;"
  227. db := util.GetSqlDB()
  228. tagList := []entity.Tag{}
  229. err := db.Select(&tagList, strSql, level)
  230. return tagList, err
  231. }
  232. func (pdal *Product) GetProductAddingCate() (interface{}, error) {
  233. strSql := "select id, name, picture from t_product_add_classify;"
  234. db := util.GetSqlDB()
  235. cateList := []struct {
  236. Id int `db:"id" json:"cate_id"`
  237. Name string `db:"name" json:"name"`
  238. Picture null.String `db:"picture" json:"picture"`
  239. }{}
  240. err := db.Select(&cateList, strSql)
  241. return cateList, err
  242. }
  243. func (pdal *Product) GetProductByAddingCate(cid int) (interface{}, error) {
  244. strSql := `select t2.id, t2.name, t2.price, GROUP_CONCAT(t5.name) as items from t_product_add t1 LEFT JOIN t_product t2 on t1.product_id = t2.id
  245. LEFT JOIN t_product_detect_product t3 on t2.id = t3.product_id left JOIN t_detect_product_item t4 on t3.detect_product_id = t4.detect_product_id
  246. left join t_detect_item t5 on t4.detect_item_id = t5.id where t1.classify_id = ? GROUP BY(t2.id);`
  247. db := util.GetSqlDB()
  248. plist := []struct {
  249. Id int `db:"id" json:"id"`
  250. Name string `db:"name" json:"name"`
  251. Price int `db:"price" json:"price"`
  252. Items null.String `db:"items" json:"items"`
  253. }{}
  254. err := db.Select(&plist, strSql, cid)
  255. return plist, err
  256. }
  257. func (pdal *Product) AddProductByDpIds(dpids []int) (interface{}, error) {
  258. sort.Ints(dpids)
  259. strDpids := util.IntJoin(dpids, ",")
  260. strSql := "select id, price from t_detect_product where id in(" + strDpids + ");"
  261. db := util.GetWriteSqlDB()
  262. var dpItems = []struct {
  263. Id int `db:"id"`
  264. Price int `db:"price"`
  265. }{}
  266. err := db.Select(&dpItems, strSql)
  267. if err != nil {
  268. return nil, err
  269. }
  270. if len(dpItems) != len(dpids) {
  271. return nil, errors.New("数据错误")
  272. }
  273. var pPrice int
  274. for _, dpItem := range dpItems {
  275. pPrice += dpItem.Price
  276. }
  277. buf := md5.Sum([]byte(strDpids))
  278. strDpids = fmt.Sprintf("%x", buf[:])
  279. strSql = "select id,price from t_product where dpid_str = ? limit 1;"
  280. var pitem = struct {
  281. Id int `db:"id"`
  282. Price int `db:"price"`
  283. }{}
  284. err = db.Get(&pitem, strSql, strDpids)
  285. if err != nil {
  286. if err == sql.ErrNoRows {
  287. //TODO create new product
  288. tx := db.MustBegin()
  289. newPitem := entity.Product{
  290. Name: "专属产品",
  291. IsPutAway: 1,
  292. Picture: "",
  293. CreatedAt: time.Now().Format("2006-01-02 15:04:05"),
  294. Price: pPrice,
  295. MarketPrice: pPrice,
  296. Tube: `{"yellow":2,"green":0,"purple":1,"breathcard":0,"breathbagpowder":0,"breathbaggree":0,"swab":0,"other":""}`,
  297. SaleMode: 100,
  298. Collection: "成人",
  299. Notice: "电子报告,1-2工作日",
  300. Report: "建议空腹",
  301. IsDrawBlood: 1,
  302. Sampling: "静脉血",
  303. TipReportDays: 2,
  304. DpidStr: strDpids,
  305. }
  306. strSql, mkv := util.GenerateInsertSqlFromStruct("t_product", &newPitem)
  307. sqlResult, err := tx.NamedExec(strSql, mkv)
  308. if err != nil {
  309. tx.Tx.Rollback()
  310. return nil, err
  311. }
  312. if ra, _ := sqlResult.RowsAffected(); ra <= 0 {
  313. tx.Tx.Rollback()
  314. return nil, errors.New("failed to generate new product")
  315. }
  316. newPid, _ := sqlResult.LastInsertId()
  317. var strValues string = "insert into t_product_detect_product(product_id,detect_product_id) values"
  318. for _, dpid := range dpids {
  319. strValues += fmt.Sprintf("(%d,%d),", newPid, dpid)
  320. }
  321. strValues = strValues[0 : len(strValues)-1]
  322. sqlResult = tx.MustExec(strValues)
  323. if ra, _ := sqlResult.RowsAffected(); ra <= 0 {
  324. tx.Tx.Rollback()
  325. return nil, errors.New("failed to generate detect_product")
  326. }
  327. strValues = "insert into t_product_city(city_id,county_id,product_id) values"
  328. strValues += fmt.Sprintf("(1,'1,2,5,6,8,11,12,13,14',%d),", newPid)
  329. strValues += fmt.Sprintf("(73,'747,748,749,750,751,752,753,754,755',%d),", newPid)
  330. strValues += fmt.Sprintf("(237,'2156,2157,2158,2159,2160,2175,2176',%d),", newPid)
  331. strValues += fmt.Sprintf("(198,'1812,1813,1814,1815,1816,1817,1818,1819,1820,1821,1822,1823',%d),", newPid)
  332. strValues += fmt.Sprintf("(170,'1591,1593,1592,1588,1590,1589',%d),", newPid)
  333. strValues += fmt.Sprintf("(74,'766,768,769,770,774',%d)", newPid)
  334. sqlResult = tx.MustExec(strValues)
  335. if ra, _ := sqlResult.RowsAffected(); ra <= 0 {
  336. tx.Tx.Rollback()
  337. return nil, errors.New("failed to generate new product_city")
  338. }
  339. strSql = fmt.Sprintf("insert into t_product_picture(product_id, picture,pic_type) values(%d, %s,1", newPid, "")
  340. sqlResult = tx.MustExec(strSql)
  341. if ra, _ := sqlResult.RowsAffected(); ra <= 0 {
  342. tx.Tx.Rollback()
  343. return nil, errors.New("failed to generate new product picture")
  344. }
  345. tx.Commit()
  346. return newPid, nil
  347. } else {
  348. return nil, err
  349. }
  350. }
  351. if pPrice != pitem.Price {
  352. strSql = "update t_product set price = ? where id = ?;"
  353. db.Exec(strSql, pPrice, pitem.Id)
  354. }
  355. return pitem.Id, nil
  356. }
  357. func (pdal *Product) GetTop(n int, cityId int) ([]entity.ProductDB, error) {
  358. var (
  359. now = time.Now()
  360. startDate = now.Add(-time.Hour * 24 * 90).Format("2006-01-02")
  361. endDate = now.Add(time.Hour * 24).Format("2006-01-02")
  362. )
  363. /*strSql := `select * from t_product t1 right join(
  364. select tp.* from (
  365. SELECT product_id, count(*) as num from t_order_product where order_id in(
  366. SELECT id from t_order where actual_payment >0 and (created_at BETWEEN ? and ?) and status not in(1,7,8,9,14)
  367. ) GROUP BY product_id
  368. )tp left JOIN t_product_city tc on tp.product_id = tc.product_id where tc.city_id = ?
  369. ) t2 on t1.id = t2.product_id where is_delete = 0 and is_putaway =0 order by num desc LIMIT ?;`*/
  370. strSql := `select * from t_product t1 right join(
  371. select tp.* from (
  372. SELECT product_id, count(*) as num from t_order_product where order_id in(
  373. SELECT id from t_order where actual_payment >0 and (created_at BETWEEN ? and ?) and status not in(1,7,8,9,14) and retype in ('100','110') and is_delete='N'
  374. ) GROUP BY product_id
  375. )tp left JOIN v_product_city tc on tp.product_id = tc.product_id where tc.city_id = ?
  376. ) t2 on t1.id = t2.product_id where is_delete = 0 and is_putaway =0 order by num desc LIMIT ?;`
  377. db := util.GetSqlDB()
  378. plist := []entity.ProductDB{}
  379. err := db.Select(&plist, strSql, startDate, endDate, cityId, n)
  380. return plist, err
  381. }
  382. var DefaultProductDal = &Product{}