shop.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. package fetdata
  2. import (
  3. "math"
  4. "strings"
  5. "golang-fave/engine/wrapper"
  6. "golang-fave/utils"
  7. )
  8. type ShopPagination struct {
  9. Num string
  10. Link string
  11. Current bool
  12. Dots bool
  13. }
  14. type Shop struct {
  15. wrap *wrapper.Wrapper
  16. category *ShopCategory
  17. product *ShopProduct
  18. products []*ShopProduct
  19. productsCount int
  20. productsPerPage int
  21. productsMaxPage int
  22. productsCurrPage int
  23. pagination []*ShopPagination
  24. paginationPrev *ShopPagination
  25. paginationNext *ShopPagination
  26. bufferCats map[string][]*ShopCategory
  27. }
  28. func (this *Shop) load() *Shop {
  29. if this == nil {
  30. return this
  31. }
  32. sql_nums := `
  33. SELECT
  34. COUNT(*)
  35. FROM
  36. shop_products
  37. WHERE
  38. active = 1
  39. ;
  40. `
  41. sql_rows := `
  42. SELECT
  43. shop_products.id,
  44. shop_products.user,
  45. shop_products.currency,
  46. shop_products.price,
  47. shop_products.name,
  48. shop_products.alias,
  49. shop_products.vendor,
  50. shop_products.quantity,
  51. shop_products.category,
  52. shop_products.briefly,
  53. shop_products.content,
  54. UNIX_TIMESTAMP(shop_products.datetime) as datetime,
  55. shop_products.active,
  56. users.id,
  57. users.first_name,
  58. users.last_name,
  59. users.email,
  60. users.admin,
  61. users.active,
  62. shop_currencies.id,
  63. shop_currencies.name,
  64. shop_currencies.coefficient,
  65. shop_currencies.code,
  66. shop_currencies.symbol,
  67. shop_cats.id,
  68. shop_cats.user,
  69. shop_cats.name,
  70. shop_cats.alias,
  71. shop_cats.lft,
  72. shop_cats.rgt
  73. FROM
  74. shop_products
  75. LEFT JOIN users ON users.id = shop_products.user
  76. LEFT JOIN shop_currencies ON shop_currencies.id = shop_products.currency
  77. LEFT JOIN shop_cats ON shop_cats.id = shop_products.category
  78. WHERE
  79. shop_products.active = 1
  80. ORDER BY
  81. shop_products.id DESC
  82. LIMIT ?, ?;
  83. `
  84. // Category selected
  85. if this.category != nil {
  86. var cat_ids []string
  87. if rows, err := this.wrap.DB.Query(
  88. `SELECT
  89. node.id
  90. FROM
  91. shop_cats AS node,
  92. shop_cats AS parent
  93. WHERE
  94. node.lft BETWEEN parent.lft AND parent.rgt AND
  95. node.id > 1 AND
  96. parent.id = ?
  97. GROUP BY
  98. node.id
  99. ORDER BY
  100. node.lft ASC
  101. ;`,
  102. this.category.Id(),
  103. ); err == nil {
  104. defer rows.Close()
  105. for rows.Next() {
  106. var cat_id string
  107. if err := rows.Scan(&cat_id); err == nil {
  108. cat_ids = append(cat_ids, cat_id)
  109. }
  110. }
  111. }
  112. sql_nums = `
  113. SELECT
  114. COUNT(*)
  115. FROM
  116. (
  117. SELECT
  118. COUNT(*)
  119. FROM
  120. shop_products
  121. LEFT JOIN shop_cat_product_rel ON shop_cat_product_rel.product_id = shop_products.id
  122. WHERE
  123. shop_products.active = 1 AND
  124. shop_cat_product_rel.category_id IN (` + strings.Join(cat_ids, ", ") + `)
  125. GROUP BY
  126. shop_products.id
  127. ) AS tbl
  128. ;
  129. `
  130. sql_rows = `
  131. SELECT
  132. shop_products.id,
  133. shop_products.user,
  134. shop_products.currency,
  135. shop_products.price,
  136. shop_products.name,
  137. shop_products.alias,
  138. shop_products.vendor,
  139. shop_products.quantity,
  140. shop_products.category,
  141. shop_products.briefly,
  142. shop_products.content,
  143. UNIX_TIMESTAMP(shop_products.datetime) AS datetime,
  144. shop_products.active,
  145. users.id,
  146. users.first_name,
  147. users.last_name,
  148. users.email,
  149. users.admin,
  150. users.active,
  151. shop_currencies.id,
  152. shop_currencies.name,
  153. shop_currencies.coefficient,
  154. shop_currencies.code,
  155. shop_currencies.symbol,
  156. shop_cats.id,
  157. shop_cats.user,
  158. shop_cats.name,
  159. shop_cats.alias,
  160. shop_cats.lft,
  161. shop_cats.rgt
  162. FROM
  163. shop_products
  164. LEFT JOIN shop_cat_product_rel ON shop_cat_product_rel.product_id = shop_products.id
  165. LEFT JOIN users ON users.id = shop_products.user
  166. LEFT JOIN shop_currencies ON shop_currencies.id = shop_products.currency
  167. LEFT JOIN shop_cats ON shop_cats.id = shop_products.category
  168. WHERE
  169. shop_products.active = 1 AND
  170. shop_cat_product_rel.category_id IN (` + strings.Join(cat_ids, ", ") + `)
  171. GROUP BY
  172. shop_products.id
  173. ORDER BY
  174. shop_products.id DESC
  175. LIMIT ?, ?;
  176. `
  177. }
  178. product_ids := []string{}
  179. if err := this.wrap.DB.QueryRow(sql_nums).Scan(&this.productsCount); err == nil {
  180. if this.category == nil {
  181. this.productsPerPage = (*this.wrap.Config).Shop.Pagination.Index
  182. } else {
  183. this.productsPerPage = (*this.wrap.Config).Shop.Pagination.Category
  184. }
  185. this.productsMaxPage = int(math.Ceil(float64(this.productsCount) / float64(this.productsPerPage)))
  186. this.productsCurrPage = this.wrap.GetCurrentPage(this.productsMaxPage)
  187. offset := this.productsCurrPage*this.productsPerPage - this.productsPerPage
  188. if rows, err := this.wrap.DB.Query(sql_rows, offset, this.productsPerPage); err == nil {
  189. defer rows.Close()
  190. for rows.Next() {
  191. rp := utils.MySql_shop_product{}
  192. ru := utils.MySql_user{}
  193. rc := utils.MySql_shop_currency{}
  194. ro := utils.MySql_shop_category{}
  195. if err := rows.Scan(
  196. &rp.A_id,
  197. &rp.A_user,
  198. &rp.A_currency,
  199. &rp.A_price,
  200. &rp.A_name,
  201. &rp.A_alias,
  202. &rp.A_vendor,
  203. &rp.A_quantity,
  204. &rp.A_category,
  205. &rp.A_briefly,
  206. &rp.A_content,
  207. &rp.A_datetime,
  208. &rp.A_active,
  209. &ru.A_id,
  210. &ru.A_first_name,
  211. &ru.A_last_name,
  212. &ru.A_email,
  213. &ru.A_admin,
  214. &ru.A_active,
  215. &rc.A_id,
  216. &rc.A_name,
  217. &rc.A_coefficient,
  218. &rc.A_code,
  219. &rc.A_symbol,
  220. &ro.A_id,
  221. &ro.A_user,
  222. &ro.A_name,
  223. &ro.A_alias,
  224. &ro.A_lft,
  225. &ro.A_rgt,
  226. ); err == nil {
  227. product_ids = append(product_ids, utils.IntToStr(rp.A_id))
  228. this.products = append(this.products, &ShopProduct{
  229. wrap: this.wrap,
  230. object: &rp,
  231. user: &User{wrap: this.wrap, object: &ru},
  232. currency: &Currency{wrap: this.wrap, object: &rc},
  233. category: &ShopCategory{wrap: this.wrap, object: &ro},
  234. })
  235. }
  236. }
  237. }
  238. }
  239. // Product images
  240. product_images := map[int][]*ShopProductImage{}
  241. if len(product_ids) > 0 {
  242. if rows, err := this.wrap.DB.Query(
  243. `SELECT
  244. shop_product_images.product_id,
  245. shop_product_images.filename
  246. FROM
  247. shop_product_images
  248. WHERE
  249. shop_product_images.product_id IN (` + strings.Join(product_ids, ", ") + `)
  250. ORDER BY
  251. shop_product_images.filename ASC
  252. ;`,
  253. ); err == nil {
  254. defer rows.Close()
  255. for rows.Next() {
  256. img := utils.MySql_shop_product_image{}
  257. if err := rows.Scan(
  258. &img.A_product_id,
  259. &img.A_filename,
  260. ); err == nil {
  261. product_images[img.A_product_id] = append(product_images[img.A_product_id], &ShopProductImage{wrap: this.wrap, object: &img})
  262. }
  263. }
  264. }
  265. }
  266. for index, product := range this.products {
  267. if pimgs, ok := product_images[product.Id()]; ok {
  268. this.products[index].images = pimgs
  269. }
  270. }
  271. // Build pagination
  272. if true {
  273. for i := 1; i < this.productsCurrPage; i++ {
  274. if this.productsCurrPage >= 5 && i > 1 && i < this.productsCurrPage-1 {
  275. continue
  276. }
  277. if this.productsCurrPage >= 5 && i > 1 && i < this.productsCurrPage {
  278. this.pagination = append(this.pagination, &ShopPagination{
  279. Dots: true,
  280. })
  281. }
  282. link := this.wrap.R.URL.Path
  283. if i > 1 {
  284. link = link + "?p=" + utils.IntToStr(i)
  285. }
  286. this.pagination = append(this.pagination, &ShopPagination{
  287. Num: utils.IntToStr(i),
  288. Link: link,
  289. Current: false,
  290. })
  291. }
  292. // Current page
  293. link := this.wrap.R.URL.Path
  294. if this.productsCurrPage > 1 {
  295. link = link + "?p=" + utils.IntToStr(this.productsCurrPage)
  296. }
  297. this.pagination = append(this.pagination, &ShopPagination{
  298. Num: utils.IntToStr(this.productsCurrPage),
  299. Link: link,
  300. Current: true,
  301. })
  302. for i := this.productsCurrPage + 1; i <= this.productsMaxPage; i++ {
  303. if this.productsCurrPage < this.productsMaxPage-3 && i == this.productsCurrPage+3 {
  304. this.pagination = append(this.pagination, &ShopPagination{
  305. Dots: true,
  306. })
  307. }
  308. if this.productsCurrPage < this.productsMaxPage-3 && i > this.productsCurrPage+1 && i <= this.productsMaxPage-1 {
  309. continue
  310. }
  311. link := this.wrap.R.URL.Path
  312. if i > 1 {
  313. link = link + "?p=" + utils.IntToStr(i)
  314. }
  315. this.pagination = append(this.pagination, &ShopPagination{
  316. Num: utils.IntToStr(i),
  317. Link: link,
  318. Current: false,
  319. })
  320. }
  321. } else {
  322. for i := 1; i <= this.productsMaxPage; i++ {
  323. link := this.wrap.R.URL.Path
  324. if i > 1 {
  325. link = link + "?p=" + utils.IntToStr(i)
  326. }
  327. this.pagination = append(this.pagination, &ShopPagination{
  328. Num: utils.IntToStr(i),
  329. Link: link,
  330. Current: i == this.productsCurrPage,
  331. })
  332. }
  333. }
  334. // Pagination prev/next
  335. if this.productsMaxPage > 1 {
  336. link := this.wrap.R.URL.Path
  337. if this.productsCurrPage-1 > 1 {
  338. link = this.wrap.R.URL.Path + "?p=" + utils.IntToStr(this.productsCurrPage-1)
  339. }
  340. this.paginationPrev = &ShopPagination{
  341. Num: utils.IntToStr(this.productsCurrPage - 1),
  342. Link: link,
  343. Current: this.productsCurrPage <= 1,
  344. }
  345. if this.productsCurrPage >= 1 && this.productsCurrPage < this.productsMaxPage {
  346. link = this.wrap.R.URL.Path + "?p=" + utils.IntToStr(this.productsCurrPage+1)
  347. } else {
  348. link = this.wrap.R.URL.Path + "?p=" + utils.IntToStr(this.productsMaxPage)
  349. }
  350. this.paginationNext = &ShopPagination{
  351. Num: utils.IntToStr(this.productsCurrPage + 1),
  352. Link: link,
  353. Current: this.productsCurrPage >= this.productsMaxPage,
  354. }
  355. }
  356. return this
  357. }
  358. func (this *Shop) Category() *ShopCategory {
  359. if this == nil {
  360. return nil
  361. }
  362. return this.category
  363. }
  364. func (this *Shop) Product() *ShopProduct {
  365. if this == nil {
  366. return nil
  367. }
  368. return this.product
  369. }
  370. func (this *Shop) HaveProducts() bool {
  371. if this == nil {
  372. return false
  373. }
  374. if len(this.products) <= 0 {
  375. return false
  376. }
  377. return true
  378. }
  379. func (this *Shop) Products() []*ShopProduct {
  380. if this == nil {
  381. return []*ShopProduct{}
  382. }
  383. return this.products
  384. }
  385. func (this *Shop) ProductsCount() int {
  386. if this == nil {
  387. return 0
  388. }
  389. return this.productsCount
  390. }
  391. func (this *Shop) ProductsPerPage() int {
  392. if this == nil {
  393. return 0
  394. }
  395. return this.productsPerPage
  396. }
  397. func (this *Shop) ProductsMaxPage() int {
  398. if this == nil {
  399. return 0
  400. }
  401. return this.productsMaxPage
  402. }
  403. func (this *Shop) ProductsCurrPage() int {
  404. if this == nil {
  405. return 0
  406. }
  407. return this.productsCurrPage
  408. }
  409. func (this *Shop) Pagination() []*ShopPagination {
  410. if this == nil {
  411. return []*ShopPagination{}
  412. }
  413. return this.pagination
  414. }
  415. func (this *Shop) PaginationPrev() *ShopPagination {
  416. if this == nil {
  417. return nil
  418. }
  419. return this.paginationPrev
  420. }
  421. func (this *Shop) PaginationNext() *ShopPagination {
  422. if this == nil {
  423. return nil
  424. }
  425. return this.paginationNext
  426. }
  427. func (this *Shop) Categories(mlvl int) []*ShopCategory {
  428. if this == nil {
  429. return []*ShopCategory{}
  430. }
  431. if this.bufferCats == nil {
  432. this.bufferCats = map[string][]*ShopCategory{}
  433. }
  434. key := ""
  435. where := ``
  436. if mlvl > 0 {
  437. where += `AND depth.depth <= ` + utils.IntToStr(mlvl)
  438. }
  439. if _, ok := this.bufferCats[key]; !ok {
  440. var cats []*ShopCategory
  441. if rows, err := this.wrap.DB.Query(`
  442. SELECT
  443. main.id,
  444. main.user,
  445. main.name,
  446. main.alias,
  447. main.lft,
  448. main.rgt,
  449. depth.depth,
  450. MAX(main.parent_id) AS parent_id
  451. FROM
  452. (
  453. SELECT
  454. node.id,
  455. node.user,
  456. node.name,
  457. node.alias,
  458. node.lft,
  459. node.rgt,
  460. parent.id AS parent_id
  461. FROM
  462. shop_cats AS node,
  463. shop_cats AS parent
  464. WHERE
  465. node.lft BETWEEN parent.lft AND parent.rgt AND
  466. node.id > 1
  467. ORDER BY
  468. node.lft ASC
  469. ) AS main
  470. LEFT JOIN (
  471. SELECT
  472. node.id,
  473. (COUNT(parent.id) - 1) AS depth
  474. FROM
  475. shop_cats AS node,
  476. shop_cats AS parent
  477. WHERE
  478. node.lft BETWEEN parent.lft AND parent.rgt
  479. GROUP BY
  480. node.id
  481. ORDER BY
  482. node.lft ASC
  483. ) AS depth ON depth.id = main.id
  484. WHERE
  485. main.id > 1 AND
  486. main.id <> main.parent_id
  487. ` + where + `
  488. GROUP BY
  489. main.id
  490. ORDER BY
  491. main.lft ASC
  492. ;
  493. `); err == nil {
  494. defer rows.Close()
  495. for rows.Next() {
  496. row := utils.MySql_shop_category{}
  497. if err := rows.Scan(&row.A_id, &row.A_user, &row.A_name, &row.A_alias, &row.A_lft, &row.A_rgt, &row.A_depth, &row.A_parent); err == nil {
  498. cats = append(cats, &ShopCategory{object: &row})
  499. }
  500. }
  501. }
  502. this.bufferCats[key] = cats
  503. }
  504. return this.bufferCats[key]
  505. }