微信小店联盟带货小程序

detail.js 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. // pages/goods/detail.js
  2. const app = getApp()
  3. Page({
  4. data: {
  5. id: null,
  6. goods: {
  7. title: '',
  8. price: '0.00',
  9. marketPrice: '0.00',
  10. commission: '0.00',
  11. commission_rate: 0,
  12. sales: 0,
  13. shares: 0,
  14. images: [],
  15. tags: [],
  16. detailImages: []
  17. },
  18. current: 0,
  19. cartCount: 0,
  20. isFavorite: false,
  21. showShare: false,
  22. showPoster: false,
  23. posterUrl: '',
  24. loading: true,
  25. hotRecommendations: [],
  26. posterTemplates: [
  27. {
  28. id: 1,
  29. name: '简约风格',
  30. desc: '清新简约,突出商品主图',
  31. preview: '/static/images/poster/template1.png'
  32. },
  33. {
  34. id: 2,
  35. name: '活力主题',
  36. desc: '色彩明快,突出价格优势',
  37. preview: '/static/images/poster/template2.png'
  38. },
  39. {
  40. id: 3,
  41. name: '高级黑金',
  42. desc: '高端大气,突出品质感',
  43. preview: '/static/images/poster/template3.png'
  44. }
  45. ],
  46. currentTemplate: 1,
  47. showPosterModal: false,
  48. showBackToTop: false
  49. },
  50. onLoad(options) {
  51. const { id } = options
  52. this.setData({ id })
  53. this.loadGoodsDetail()
  54. this.getCartCount()
  55. this.checkFavorite()
  56. this.loadHotRecommendations()
  57. },
  58. onPageScroll(e) {
  59. // 页面滚动超过一屏时显示返回顶部按钮
  60. const showBackToTop = e.scrollTop > wx.getSystemInfoSync().windowHeight
  61. if (showBackToTop !== this.data.showBackToTop) {
  62. this.setData({
  63. showBackToTop
  64. })
  65. }
  66. },
  67. onShow() {
  68. this.getCartCount()
  69. },
  70. // 加载商品详情
  71. async loadGoodsDetail() {
  72. wx.showLoading({ title: '加载中' })
  73. try {
  74. // TODO: 替换为实际的API调用
  75. // 模拟数据
  76. const goods = {
  77. title: 'iPhone 14 Pro Max',
  78. price: '9299.00',
  79. marketPrice: '9999.00',
  80. commission: '186.00',
  81. commission_rate: 2,
  82. sales: 8526,
  83. shares: 1253,
  84. images: [
  85. '/static/images/goods/iphone-1.png',
  86. '/static/images/goods/iphone-2.png',
  87. '/static/images/goods/iphone-3.png'
  88. ],
  89. tags: ['官方正品', '全网最低价', '24期免息', '顺丰包邮'],
  90. detailImages: [
  91. '/static/images/goods/detail-1.png',
  92. '/static/images/goods/detail-2.png',
  93. '/static/images/goods/detail-3.png'
  94. ]
  95. }
  96. this.setData({
  97. goods,
  98. loading: false
  99. })
  100. wx.hideLoading()
  101. } catch (error) {
  102. console.error('加载商品详情失败:', error)
  103. wx.hideLoading()
  104. wx.showToast({
  105. title: '加载失败',
  106. icon: 'none'
  107. })
  108. }
  109. },
  110. // 轮播图切换
  111. onSwiperChange(e) {
  112. this.setData({
  113. current: e.detail.current
  114. })
  115. },
  116. // 预览图片
  117. previewImage(e) {
  118. const { current } = e.currentTarget.dataset
  119. const { images } = this.data.goods
  120. wx.previewImage({
  121. current,
  122. urls: images
  123. })
  124. },
  125. // 预览详情图片
  126. previewDetailImage(e) {
  127. const { current } = e.currentTarget.dataset
  128. const { detailImages } = this.data.goods
  129. wx.previewImage({
  130. current,
  131. urls: detailImages
  132. })
  133. },
  134. // 获取购物车数量
  135. async getCartCount() {
  136. try {
  137. const cartList = wx.getStorageSync('cart') || []
  138. const cartCount = cartList.reduce((sum, item) => sum + item.quantity, 0)
  139. this.setData({ cartCount })
  140. } catch (error) {
  141. console.error('获取购物车数量失败:', error)
  142. }
  143. },
  144. // 检查是否已收藏
  145. checkFavorite() {
  146. try {
  147. const favorites = wx.getStorageSync('favorites') || []
  148. const isFavorite = favorites.includes(this.data.id)
  149. this.setData({ isFavorite })
  150. } catch (error) {
  151. console.error('检查收藏状态失败:', error)
  152. }
  153. },
  154. // 切换收藏状态
  155. async toggleFavorite() {
  156. try {
  157. if (checkNeedLogin()) {
  158. try {
  159. await doLogin()
  160. } catch (err) {
  161. console.error('登录失败:', err)
  162. wx.showToast({
  163. title: '登录失败',
  164. icon: 'none'
  165. })
  166. return
  167. }
  168. }
  169. const { id, isFavorite } = this.data
  170. let favorites = wx.getStorageSync('favorites') || []
  171. if (isFavorite) {
  172. favorites = favorites.filter(item => item !== id)
  173. } else {
  174. favorites.push(id)
  175. }
  176. wx.setStorageSync('favorites', favorites)
  177. this.setData({ isFavorite: !isFavorite })
  178. wx.showToast({
  179. title: isFavorite ? '已取消收藏' : '已收藏',
  180. icon: 'success'
  181. })
  182. } catch (error) {
  183. console.error('收藏操作失败:', error)
  184. wx.showToast({
  185. title: '操作失败',
  186. icon: 'none'
  187. })
  188. }
  189. },
  190. // 加入购物车
  191. addToCart() {
  192. try {
  193. const { id, goods } = this.data
  194. let cartList = wx.getStorageSync('cart') || []
  195. const existItem = cartList.find(item => item.id === id)
  196. if (existItem) {
  197. existItem.quantity += 1
  198. } else {
  199. cartList.push({
  200. id,
  201. title: goods.title,
  202. price: goods.price,
  203. image: goods.images[0],
  204. quantity: 1
  205. })
  206. }
  207. wx.setStorageSync('cart', cartList)
  208. this.getCartCount()
  209. wx.showToast({
  210. title: '已加入购物车',
  211. icon: 'success'
  212. })
  213. } catch (error) {
  214. console.error('加入购物车失败:', error)
  215. wx.showToast({
  216. title: '操作失败',
  217. icon: 'none'
  218. })
  219. }
  220. },
  221. // 立即购买
  222. buyNow() {
  223. const { id } = this.data
  224. wx.navigateTo({
  225. url: `/pages/order/confirm?goods_id=${id}&quantity=1`
  226. })
  227. },
  228. // 检查推客身份
  229. checkPromoterStatus() {
  230. const userData = wx.getStorageSync('user_data')
  231. return userData && userData.is_promoter === 1
  232. },
  233. // 显示非推客提示弹窗
  234. showPromoterTips() {
  235. return new Promise((resolve) => {
  236. wx.showModal({
  237. title: '温馨提示',
  238. content: '您还不是推客,购买/分享商品将无法获得收益',
  239. confirmText: '去授权',
  240. cancelText: '暂不收益',
  241. success(res) {
  242. if (res.confirm) {
  243. // 跳转到推客授权页面
  244. wx.navigateTo({
  245. url: '/pages/promoter/auth'
  246. })
  247. resolve(false)
  248. } else {
  249. resolve(true)
  250. }
  251. },
  252. fail() {
  253. resolve(false)
  254. }
  255. })
  256. })
  257. },
  258. // 显示分享面板
  259. async showSharePanel() {
  260. if (!this.checkPromoterStatus()) {
  261. const continue_share = await this.showPromoterTips()
  262. if (!continue_share) return
  263. }
  264. this.setData({
  265. showShare: true
  266. })
  267. },
  268. // 隐藏分享面板
  269. hideSharePanel() {
  270. this.setData({ showShare: false })
  271. },
  272. // 加载热门推荐
  273. async loadHotRecommendations() {
  274. try {
  275. // TODO: 替换为实际的API调用
  276. const recommendations = [
  277. {
  278. id: 1,
  279. title: '2023新款时尚潮流女装连衣裙',
  280. price: '299.00',
  281. sales: 1234,
  282. tag: '新品',
  283. image: '/static/images/goods/recommend1.png'
  284. },
  285. {
  286. id: 2,
  287. title: '夏季薄款防晒衣女士外套',
  288. price: '199.00',
  289. sales: 856,
  290. tag: '热销',
  291. image: '/static/images/goods/recommend2.png'
  292. },
  293. {
  294. id: 3,
  295. title: '高腰显瘦牛仔裤女装新款',
  296. price: '258.00',
  297. sales: 2341,
  298. tag: '爆款',
  299. image: '/static/images/goods/recommend3.png'
  300. },
  301. {
  302. id: 4,
  303. title: '轻奢小香风名媛气质套装',
  304. price: '458.00',
  305. sales: 1567,
  306. tag: '推荐',
  307. image: '/static/images/goods/recommend4.png'
  308. },
  309. {
  310. id: 5,
  311. title: '夏季新款韩版休闲运动套装',
  312. price: '228.00',
  313. sales: 987,
  314. tag: '特惠',
  315. image: '/static/images/goods/recommend5.png'
  316. },
  317. {
  318. id: 6,
  319. title: '法式复古碎花连衣裙',
  320. price: '328.00',
  321. sales: 1876,
  322. tag: '流行',
  323. image: '/static/images/goods/recommend6.png'
  324. },
  325. {
  326. id: 7,
  327. title: '时尚百搭小黑裙',
  328. price: '269.00',
  329. sales: 2156,
  330. tag: '经典',
  331. image: '/static/images/goods/recommend7.png'
  332. },
  333. {
  334. id: 8,
  335. title: '轻薄透气运动鞋',
  336. price: '399.00',
  337. sales: 1432,
  338. tag: '新款',
  339. image: '/static/images/goods/recommend8.png'
  340. },
  341. {
  342. id: 9,
  343. title: '高档真丝阔腿裤套装',
  344. price: '599.00',
  345. sales: 876,
  346. tag: '精选',
  347. image: '/static/images/goods/recommend9.png'
  348. }
  349. ]
  350. this.setData({
  351. hotRecommendations: recommendations
  352. })
  353. } catch (error) {
  354. console.error('加载推荐商品失败:', error)
  355. }
  356. },
  357. // 跳转到商品详情
  358. navigateToGoods(e) {
  359. const { id } = e.currentTarget.dataset
  360. wx.navigateTo({
  361. url: `/pages/goods/detail?id=${id}`
  362. })
  363. },
  364. // 生成分享海报
  365. async generatePoster() {
  366. if (!this.checkPromoterStatus()) {
  367. const continue_share = await this.showPromoterTips()
  368. if (!continue_share) return
  369. }
  370. this.setData({
  371. showPosterModal: true
  372. })
  373. },
  374. // 切换海报模板
  375. switchTemplate(e) {
  376. const { templateId } = e.currentTarget.dataset
  377. this.setData({
  378. currentTemplate: templateId
  379. })
  380. },
  381. // 确认生成海报
  382. async confirmGeneratePoster() {
  383. wx.showLoading({ title: '生成中' })
  384. try {
  385. const { goods, currentTemplate } = this.data
  386. // TODO: 替换为实际的海报生成API调用
  387. const posterConfig = {
  388. template: currentTemplate,
  389. goods: {
  390. title: goods.title,
  391. price: goods.price,
  392. image: goods.images[0]
  393. }
  394. }
  395. // 模拟API调用
  396. setTimeout(() => {
  397. this.setData({
  398. posterUrl: '/static/images/poster/sample.png',
  399. showPosterModal: false,
  400. showPoster: true
  401. })
  402. wx.hideLoading()
  403. }, 1000)
  404. } catch (error) {
  405. console.error('生成海报失败:', error)
  406. wx.hideLoading()
  407. wx.showToast({
  408. title: '生成失败',
  409. icon: 'none'
  410. })
  411. }
  412. },
  413. // 关闭海报模态框
  414. closePosterModal() {
  415. this.setData({
  416. showPosterModal: false
  417. })
  418. },
  419. // 关闭海报预览
  420. closePosterPreview() {
  421. this.setData({
  422. showPoster: false,
  423. posterUrl: ''
  424. })
  425. },
  426. // 保存海报
  427. async savePoster() {
  428. try {
  429. await wx.saveImageToPhotosAlbum({
  430. filePath: this.data.posterUrl
  431. })
  432. wx.showToast({
  433. title: '保存成功',
  434. icon: 'success'
  435. })
  436. this.hidePoster()
  437. } catch (error) {
  438. console.error('保存海报失败:', error)
  439. if (error.errMsg.includes('auth deny')) {
  440. wx.showModal({
  441. title: '提示',
  442. content: '需要您授权保存图片到相册',
  443. success: (res) => {
  444. if (res.confirm) {
  445. wx.openSetting()
  446. }
  447. }
  448. })
  449. } else {
  450. wx.showToast({
  451. title: '保存失败',
  452. icon: 'none'
  453. })
  454. }
  455. }
  456. },
  457. // 分享给好友
  458. onShareAppMessage() {
  459. const { goods } = this.data
  460. return {
  461. title: goods.title,
  462. imageUrl: goods.images[0],
  463. path: `/pages/goods/detail?id=${this.data.id}`
  464. }
  465. },
  466. // 分享到朋友圈
  467. onShareTimeline() {
  468. const { goods } = this.data
  469. return {
  470. title: goods.title,
  471. imageUrl: goods.images[0],
  472. query: `id=${this.data.id}`
  473. }
  474. },
  475. // 返回顶部
  476. scrollToTop() {
  477. wx.pageScrollTo({
  478. scrollTop: 0,
  479. duration: 300
  480. })
  481. },
  482. })