shop.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  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. cats.id,
  68. cats.user,
  69. cats.name,
  70. cats.alias,
  71. cats.lft,
  72. cats.rgt,
  73. cats.depth,
  74. cats.parent_id
  75. FROM
  76. shop_products
  77. LEFT JOIN users ON users.id = shop_products.user
  78. LEFT JOIN shop_currencies ON shop_currencies.id = shop_products.currency
  79. LEFT JOIN (
  80. SELECT
  81. main.id,
  82. main.user,
  83. main.name,
  84. main.alias,
  85. main.lft,
  86. main.rgt,
  87. depth.depth,
  88. MAX(main.parent_id) AS parent_id
  89. FROM
  90. (
  91. SELECT
  92. node.id,
  93. node.user,
  94. node.name,
  95. node.alias,
  96. node.lft,
  97. node.rgt,
  98. parent.id AS parent_id
  99. FROM
  100. shop_cats AS node,
  101. shop_cats AS parent
  102. WHERE
  103. node.lft BETWEEN parent.lft AND parent.rgt AND
  104. node.id > 1
  105. ORDER BY
  106. node.lft ASC
  107. ) AS main
  108. LEFT JOIN (
  109. SELECT
  110. node.id,
  111. (COUNT(parent.id) - 1) AS depth
  112. FROM
  113. shop_cats AS node,
  114. shop_cats AS parent
  115. WHERE
  116. node.lft BETWEEN parent.lft AND parent.rgt
  117. GROUP BY
  118. node.id
  119. ORDER BY
  120. node.lft ASC
  121. ) AS depth ON depth.id = main.id
  122. WHERE
  123. main.id > 1 AND
  124. main.id <> main.parent_id
  125. GROUP BY
  126. main.id
  127. ) AS cats ON cats.id = shop_products.category
  128. WHERE
  129. shop_products.active = 1
  130. ORDER BY
  131. shop_products.id DESC
  132. LIMIT ?, ?;
  133. `
  134. // Category selected
  135. if this.category != nil {
  136. var cat_ids []string
  137. if rows, err := this.wrap.DB.Query(
  138. `SELECT
  139. node.id
  140. FROM
  141. shop_cats AS node,
  142. shop_cats AS parent
  143. WHERE
  144. node.lft BETWEEN parent.lft AND parent.rgt AND
  145. node.id > 1 AND
  146. parent.id = ?
  147. GROUP BY
  148. node.id
  149. ORDER BY
  150. node.lft ASC
  151. ;`,
  152. this.category.Id(),
  153. ); err == nil {
  154. defer rows.Close()
  155. for rows.Next() {
  156. var cat_id string
  157. if err := rows.Scan(&cat_id); err == nil {
  158. cat_ids = append(cat_ids, cat_id)
  159. }
  160. }
  161. }
  162. sql_nums = `
  163. SELECT
  164. COUNT(*)
  165. FROM
  166. (
  167. SELECT
  168. COUNT(*)
  169. FROM
  170. shop_products
  171. LEFT JOIN shop_cat_product_rel ON shop_cat_product_rel.product_id = shop_products.id
  172. WHERE
  173. shop_products.active = 1 AND
  174. shop_cat_product_rel.category_id IN (` + strings.Join(cat_ids, ", ") + `)
  175. GROUP BY
  176. shop_products.id
  177. ) AS tbl
  178. ;
  179. `
  180. sql_rows = `
  181. SELECT
  182. shop_products.id,
  183. shop_products.user,
  184. shop_products.currency,
  185. shop_products.price,
  186. shop_products.name,
  187. shop_products.alias,
  188. shop_products.vendor,
  189. shop_products.quantity,
  190. shop_products.category,
  191. shop_products.briefly,
  192. shop_products.content,
  193. UNIX_TIMESTAMP(shop_products.datetime) AS datetime,
  194. shop_products.active,
  195. users.id,
  196. users.first_name,
  197. users.last_name,
  198. users.email,
  199. users.admin,
  200. users.active,
  201. shop_currencies.id,
  202. shop_currencies.name,
  203. shop_currencies.coefficient,
  204. shop_currencies.code,
  205. shop_currencies.symbol,
  206. cats.id,
  207. cats.user,
  208. cats.name,
  209. cats.alias,
  210. cats.lft,
  211. cats.rgt,
  212. cats.depth,
  213. cats.parent_id
  214. FROM
  215. shop_products
  216. LEFT JOIN shop_cat_product_rel ON shop_cat_product_rel.product_id = shop_products.id
  217. LEFT JOIN users ON users.id = shop_products.user
  218. LEFT JOIN shop_currencies ON shop_currencies.id = shop_products.currency
  219. LEFT JOIN (
  220. SELECT
  221. main.id,
  222. main.user,
  223. main.name,
  224. main.alias,
  225. main.lft,
  226. main.rgt,
  227. depth.depth,
  228. MAX(main.parent_id) AS parent_id
  229. FROM
  230. (
  231. SELECT
  232. node.id,
  233. node.user,
  234. node.name,
  235. node.alias,
  236. node.lft,
  237. node.rgt,
  238. parent.id AS parent_id
  239. FROM
  240. shop_cats AS node,
  241. shop_cats AS parent
  242. WHERE
  243. node.lft BETWEEN parent.lft AND parent.rgt AND
  244. node.id > 1
  245. ORDER BY
  246. node.lft ASC
  247. ) AS main
  248. LEFT JOIN (
  249. SELECT
  250. node.id,
  251. (COUNT(parent.id) - 1) AS depth
  252. FROM
  253. shop_cats AS node,
  254. shop_cats AS parent
  255. WHERE
  256. node.lft BETWEEN parent.lft AND parent.rgt
  257. GROUP BY
  258. node.id
  259. ORDER BY
  260. node.lft ASC
  261. ) AS depth ON depth.id = main.id
  262. WHERE
  263. main.id > 1 AND
  264. main.id <> main.parent_id
  265. GROUP BY
  266. main.id
  267. ) AS cats ON cats.id = shop_products.category
  268. WHERE
  269. shop_products.active = 1 AND
  270. shop_cat_product_rel.category_id IN (` + strings.Join(cat_ids, ", ") + `)
  271. GROUP BY
  272. shop_products.id
  273. ORDER BY
  274. shop_products.id DESC
  275. LIMIT ?, ?;
  276. `
  277. }
  278. product_ids := []string{}
  279. if err := this.wrap.DB.QueryRow(sql_nums).Scan(&this.productsCount); err == nil {
  280. if this.category == nil {
  281. this.productsPerPage = (*this.wrap.Config).Shop.Pagination.Index
  282. } else {
  283. this.productsPerPage = (*this.wrap.Config).Shop.Pagination.Category
  284. }
  285. this.productsMaxPage = int(math.Ceil(float64(this.productsCount) / float64(this.productsPerPage)))
  286. this.productsCurrPage = this.wrap.GetCurrentPage(this.productsMaxPage)
  287. offset := this.productsCurrPage*this.productsPerPage - this.productsPerPage
  288. if rows, err := this.wrap.DB.Query(sql_rows, offset, this.productsPerPage); err == nil {
  289. defer rows.Close()
  290. for rows.Next() {
  291. rp := utils.MySql_shop_product{}
  292. ru := utils.MySql_user{}
  293. rc := utils.MySql_shop_currency{}
  294. ro := utils.MySql_shop_category{}
  295. if err := rows.Scan(
  296. &rp.A_id,
  297. &rp.A_user,
  298. &rp.A_currency,
  299. &rp.A_price,
  300. &rp.A_name,
  301. &rp.A_alias,
  302. &rp.A_vendor,
  303. &rp.A_quantity,
  304. &rp.A_category,
  305. &rp.A_briefly,
  306. &rp.A_content,
  307. &rp.A_datetime,
  308. &rp.A_active,
  309. &ru.A_id,
  310. &ru.A_first_name,
  311. &ru.A_last_name,
  312. &ru.A_email,
  313. &ru.A_admin,
  314. &ru.A_active,
  315. &rc.A_id,
  316. &rc.A_name,
  317. &rc.A_coefficient,
  318. &rc.A_code,
  319. &rc.A_symbol,
  320. &ro.A_id,
  321. &ro.A_user,
  322. &ro.A_name,
  323. &ro.A_alias,
  324. &ro.A_lft,
  325. &ro.A_rgt,
  326. &ro.A_depth,
  327. &ro.A_parent,
  328. ); err == nil {
  329. product_ids = append(product_ids, utils.IntToStr(rp.A_id))
  330. this.products = append(this.products, &ShopProduct{
  331. wrap: this.wrap,
  332. object: &rp,
  333. user: &User{wrap: this.wrap, object: &ru},
  334. currency: &Currency{wrap: this.wrap, object: &rc},
  335. category: &ShopCategory{wrap: this.wrap, object: &ro},
  336. })
  337. }
  338. }
  339. }
  340. }
  341. // Product images
  342. product_images := map[int][]*ShopProductImage{}
  343. if len(product_ids) > 0 {
  344. if rows, err := this.wrap.DB.Query(
  345. `SELECT
  346. shop_product_images.product_id,
  347. shop_product_images.filename
  348. FROM
  349. shop_product_images
  350. WHERE
  351. shop_product_images.product_id IN (` + strings.Join(product_ids, ", ") + `)
  352. ORDER BY
  353. shop_product_images.filename ASC
  354. ;`,
  355. ); err == nil {
  356. defer rows.Close()
  357. for rows.Next() {
  358. img := utils.MySql_shop_product_image{}
  359. if err := rows.Scan(
  360. &img.A_product_id,
  361. &img.A_filename,
  362. ); err == nil {
  363. product_images[img.A_product_id] = append(product_images[img.A_product_id], &ShopProductImage{wrap: this.wrap, object: &img})
  364. }
  365. }
  366. }
  367. }
  368. for index, product := range this.products {
  369. if pimgs, ok := product_images[product.Id()]; ok {
  370. this.products[index].images = pimgs
  371. }
  372. }
  373. // Build pagination
  374. if true {
  375. for i := 1; i < this.productsCurrPage; i++ {
  376. if this.productsCurrPage >= 5 && i > 1 && i < this.productsCurrPage-1 {
  377. continue
  378. }
  379. if this.productsCurrPage >= 5 && i > 1 && i < this.productsCurrPage {
  380. this.pagination = append(this.pagination, &ShopPagination{
  381. Dots: true,
  382. })
  383. }
  384. link := this.wrap.R.URL.Path
  385. if i > 1 {
  386. link = link + "?p=" + utils.IntToStr(i)
  387. }
  388. this.pagination = append(this.pagination, &ShopPagination{
  389. Num: utils.IntToStr(i),
  390. Link: link,
  391. Current: false,
  392. })
  393. }
  394. // Current page
  395. link := this.wrap.R.URL.Path
  396. if this.productsCurrPage > 1 {
  397. link = link + "?p=" + utils.IntToStr(this.productsCurrPage)
  398. }
  399. this.pagination = append(this.pagination, &ShopPagination{
  400. Num: utils.IntToStr(this.productsCurrPage),
  401. Link: link,
  402. Current: true,
  403. })
  404. for i := this.productsCurrPage + 1; i <= this.productsMaxPage; i++ {
  405. if this.productsCurrPage < this.productsMaxPage-3 && i == this.productsCurrPage+3 {
  406. this.pagination = append(this.pagination, &ShopPagination{
  407. Dots: true,
  408. })
  409. }
  410. if this.productsCurrPage < this.productsMaxPage-3 && i > this.productsCurrPage+1 && i <= this.productsMaxPage-1 {
  411. continue
  412. }
  413. link := this.wrap.R.URL.Path
  414. if i > 1 {
  415. link = link + "?p=" + utils.IntToStr(i)
  416. }
  417. this.pagination = append(this.pagination, &ShopPagination{
  418. Num: utils.IntToStr(i),
  419. Link: link,
  420. Current: false,
  421. })
  422. }
  423. } else {
  424. for i := 1; i <= this.productsMaxPage; i++ {
  425. link := this.wrap.R.URL.Path
  426. if i > 1 {
  427. link = link + "?p=" + utils.IntToStr(i)
  428. }
  429. this.pagination = append(this.pagination, &ShopPagination{
  430. Num: utils.IntToStr(i),
  431. Link: link,
  432. Current: i == this.productsCurrPage,
  433. })
  434. }
  435. }
  436. // Pagination prev/next
  437. if this.productsMaxPage > 1 {
  438. link := this.wrap.R.URL.Path
  439. if this.productsCurrPage-1 > 1 {
  440. link = this.wrap.R.URL.Path + "?p=" + utils.IntToStr(this.productsCurrPage-1)
  441. }
  442. this.paginationPrev = &ShopPagination{
  443. Num: utils.IntToStr(this.productsCurrPage - 1),
  444. Link: link,
  445. Current: this.productsCurrPage <= 1,
  446. }
  447. if this.productsCurrPage >= 1 && this.productsCurrPage < this.productsMaxPage {
  448. link = this.wrap.R.URL.Path + "?p=" + utils.IntToStr(this.productsCurrPage+1)
  449. } else {
  450. link = this.wrap.R.URL.Path + "?p=" + utils.IntToStr(this.productsMaxPage)
  451. }
  452. this.paginationNext = &ShopPagination{
  453. Num: utils.IntToStr(this.productsCurrPage + 1),
  454. Link: link,
  455. Current: this.productsCurrPage >= this.productsMaxPage,
  456. }
  457. }
  458. return this
  459. }
  460. func (this *Shop) Category() *ShopCategory {
  461. if this == nil {
  462. return nil
  463. }
  464. return this.category
  465. }
  466. func (this *Shop) Product() *ShopProduct {
  467. if this == nil {
  468. return nil
  469. }
  470. return this.product
  471. }
  472. func (this *Shop) HaveProducts() bool {
  473. if this == nil {
  474. return false
  475. }
  476. if len(this.products) <= 0 {
  477. return false
  478. }
  479. return true
  480. }
  481. func (this *Shop) Products() []*ShopProduct {
  482. if this == nil {
  483. return []*ShopProduct{}
  484. }
  485. return this.products
  486. }
  487. func (this *Shop) ProductsCount() int {
  488. if this == nil {
  489. return 0
  490. }
  491. return this.productsCount
  492. }
  493. func (this *Shop) ProductsPerPage() int {
  494. if this == nil {
  495. return 0
  496. }
  497. return this.productsPerPage
  498. }
  499. func (this *Shop) ProductsMaxPage() int {
  500. if this == nil {
  501. return 0
  502. }
  503. return this.productsMaxPage
  504. }
  505. func (this *Shop) ProductsCurrPage() int {
  506. if this == nil {
  507. return 0
  508. }
  509. return this.productsCurrPage
  510. }
  511. func (this *Shop) Pagination() []*ShopPagination {
  512. if this == nil {
  513. return []*ShopPagination{}
  514. }
  515. return this.pagination
  516. }
  517. func (this *Shop) PaginationPrev() *ShopPagination {
  518. if this == nil {
  519. return nil
  520. }
  521. return this.paginationPrev
  522. }
  523. func (this *Shop) PaginationNext() *ShopPagination {
  524. if this == nil {
  525. return nil
  526. }
  527. return this.paginationNext
  528. }
  529. func (this *Shop) Categories(mlvl int) []*ShopCategory {
  530. if this == nil {
  531. return []*ShopCategory{}
  532. }
  533. if this.bufferCats == nil {
  534. this.bufferCats = map[string][]*ShopCategory{}
  535. }
  536. key := ""
  537. where := ``
  538. if mlvl > 0 {
  539. where += `AND depth.depth <= ` + utils.IntToStr(mlvl)
  540. }
  541. if _, ok := this.bufferCats[key]; !ok {
  542. var cats []*ShopCategory
  543. if rows, err := this.wrap.DB.Query(`
  544. SELECT
  545. main.id,
  546. main.user,
  547. main.name,
  548. main.alias,
  549. main.lft,
  550. main.rgt,
  551. depth.depth,
  552. MAX(main.parent_id) AS parent_id
  553. FROM
  554. (
  555. SELECT
  556. node.id,
  557. node.user,
  558. node.name,
  559. node.alias,
  560. node.lft,
  561. node.rgt,
  562. parent.id AS parent_id
  563. FROM
  564. shop_cats AS node,
  565. shop_cats AS parent
  566. WHERE
  567. node.lft BETWEEN parent.lft AND parent.rgt AND
  568. node.id > 1
  569. ORDER BY
  570. node.lft ASC
  571. ) AS main
  572. LEFT JOIN (
  573. SELECT
  574. node.id,
  575. (COUNT(parent.id) - 1) AS depth
  576. FROM
  577. shop_cats AS node,
  578. shop_cats AS parent
  579. WHERE
  580. node.lft BETWEEN parent.lft AND parent.rgt
  581. GROUP BY
  582. node.id
  583. ORDER BY
  584. node.lft ASC
  585. ) AS depth ON depth.id = main.id
  586. WHERE
  587. main.id > 1 AND
  588. main.id <> main.parent_id
  589. ` + where + `
  590. GROUP BY
  591. main.id
  592. ORDER BY
  593. main.lft ASC
  594. ;
  595. `); err == nil {
  596. defer rows.Close()
  597. for rows.Next() {
  598. row := utils.MySql_shop_category{}
  599. 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 {
  600. cats = append(cats, &ShopCategory{object: &row})
  601. }
  602. }
  603. }
  604. this.bufferCats[key] = cats
  605. }
  606. return this.bufferCats[key]
  607. }