金诚优选前端代码
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.

1556 lines
42 KiB

  1. <template>
  2. <view class="">
  3. <view class="content">
  4. <view class="top-image">
  5. <swiper indicator-dots="true" autoplay="true" circular="true">
  6. <swiper-item v-for="(item, index) in detailData.data.photos" :key="index">
  7. <image :src="item.url" :data-url="item.url" class="slide-image" @tap="bigImg"></image>
  8. </swiper-item>
  9. </swiper>
  10. </view>
  11. <view class="basic-information">
  12. <view class="basic-top">
  13. {{detailData.data.name}}
  14. </view>
  15. <view class="basic-bottom">
  16. <text class="price">{{detailData.data.redeem_point}} 积分</text>
  17. </view>
  18. </view>
  19. <view class="detail-item-box">
  20. <!--商品详情-->
  21. <view>
  22. <view class="title mx-1px-bottom" data-type="commodity" @tap="change">
  23. <view class="title-text">
  24. 图文详情
  25. </view>
  26. <view>
  27. </view>
  28. </view>
  29. <view class="content" v-if="expands.commodity">
  30. <!--<wxparser rich-text="{{detailData.data.content}}" />-->
  31. <u-parse :content="detailData.data.content" v-if="detailData.data.content" />
  32. </view>
  33. </view>
  34. </view>
  35. <!--<view class="to-top" hidden="{{!showToTop}}" bindtap="goTop">-->
  36. <!--<i class="iconfont icon-xiangshang"></i>-->
  37. <!--</view>-->
  38. <view class="tabbar">
  39. <view class="tabbar-item item_3" :class="cart_status.status ? 'globalBgcolor' : 'btn_1'" :style="'background: ' + config.mainColor" @tap="showSelect">
  40. {{cart_status.message}}
  41. </view>
  42. </view>
  43. </view>
  44. <view class="maks" :class="!show_select ? 'cur' : ''" @tap="closeSelect">
  45. </view>
  46. <view class="detail-popup" :class="!show_select ? 'detail-active' : ''" :hidden="show_select" :animation="show.animation">
  47. <view class="select_goods_container">
  48. <!--关闭按钮-->
  49. <view class="select_goods_cloese" @tap="closeSelect"></view>
  50. <view class="select_goods_header">
  51. <view class="img_box">
  52. <image v-if="select_product && select_product.img" :src="select_product.img" :alt="select_product.sku"></image>
  53. <image v-else :src="commodity.img + ' '" alt></image>
  54. </view>
  55. <!--<view class="img_box" style="background-color: {{select_product.bac}};width: 78px;height: 78px;" wx:if="{{!select_product.img && !!select_product.color}}"></view>-->
  56. <view class="price_item">
  57. <text>{{detailData.data.redeem_point}} 积分</text>
  58. <text v-if="detailData.data.shop_show_store == 1">库存{{store_count}}</text>
  59. </view>
  60. </view>
  61. <view class="select_spec">
  62. <view class="spec_line" v-for="(spec, index) in specs" :key="index" >
  63. <view class="spec_title">{{spec.label}}</view>
  64. <view class="spec_value">
  65. <view class="spec_block" :class="!!item.disabled ? 'disabled' : '' " v-for="(item, index) in spec.values" :key="index" :data-key="index" :data-index="item.index" :data-disabled="item.disabled ? 1 : 0" :data-id="item.id" :data-active="item.active ? 1 : 0" @tap="selectSpec">
  66. <!--<view class="spec_icon spec_text" wx:if="{{item.spec_img}}">-->
  67. <!--<image src="{{item.spec_img}}" data-alt="{{item.alias || item.value}}"></image>-->
  68. <!--</view>-->
  69. <!--<text class="spec_icon" style="background-color:{{item.color}}" wx:if="{{!item.spec_img && item.color}}"></text>-->
  70. <view class="spec_text" v-if="(item.alias || item.value) && item.spec_img !== ''">
  71. {{item.alias || item.value}}
  72. <view v-if="!!item.active" :style="'border-color: ' + config.mainColor" class="border-color">
  73. </view>
  74. </view>
  75. <view class="spec_text" v-if="!item.spec_img && !item.color">
  76. {{item.alias || item.value}}
  77. <view v-if="!!item.active" :style="'border-color: ' + config.mainColor" class="border-color">
  78. </view>
  79. </view>
  80. </view>
  81. <!--<view class="spec_list" wx:if="{{spec.id != 2}}">尺码表</view>-->
  82. </view>
  83. </view>
  84. <view class="spec_line">
  85. <view class="num_title">数量</view>
  86. <view class="num_value">
  87. <text @tap="changeCount" data-index="0">-</text>
  88. <view class="none_border">
  89. <input @input="modifyCount" :value="select_count" type="number" confirm-type="done"></input>
  90. </view>
  91. <text @tap="changeCount" data-index="1">+</text>
  92. </view>
  93. </view>
  94. <button class="button" :class=" canBuy ? 'disabled' : '' " :loading="loading" :style="'background: ' + config.mainColor" @tap="confirm">确定</button>
  95. <!--<view class="button {{ canBuy ? 'disabled' : '' }}" bindtap="confirm">-->
  96. <!--&lt;!&ndash;<submit-button v-ref:button bindsubmit="confirm" :status="disallow_cart ? 'disabled' : 'normal'">确定</submit-button>&ndash;&gt;-->
  97. <!--</view>-->
  98. </view>
  99. </view>
  100. </view>
  101. </view>
  102. </template>
  103. <script>
  104. var app = getApp();
  105. //import { config, getUrl, weapp, cookieStorage, connect, bindActionCreators, store, actions, sandBox } from '../../../lib/myapp.js';
  106. import {pageLogin, getUrl,config,is} from '@/common/js/utils.js';
  107. import Animation from '@/common/js/animation.js';
  108. import uParse from '@/components/gaoyia-parse/parse.vue';
  109. import ten from "@/components/ten/ten";
  110. export default {
  111. data() {
  112. return {
  113. cart_status: {
  114. status: false,
  115. message: '商品缺货中'
  116. },
  117. id: '',
  118. skuTable: {},
  119. price: 0,
  120. commodity: {},
  121. detailData: {},
  122. specs: [],
  123. detail: '',
  124. attributesList: {
  125. top: [],
  126. bottom: []
  127. },
  128. expands: {
  129. parameter: true,
  130. //商品参数
  131. recommend: true,
  132. //推荐搭配
  133. commodity: true,
  134. //商品详情
  135. story: true,
  136. //产品故事
  137. interest: true,
  138. //TA们也感兴趣
  139. like: true,
  140. //猜你喜欢
  141. history: true //历史浏览
  142. },
  143. showToTop: false,
  144. show_select: true,
  145. //选尺寸
  146. select_product: {},
  147. //当前选中商品
  148. store_count: 0,
  149. store_num: 0,
  150. select_count: 1,
  151. is_login: true,
  152. canBuy: false,
  153. query: {},
  154. animationSelect: {},
  155. loading: false,
  156. coupons: [],
  157. // 可领取的优惠券信息
  158. discounts: [],
  159. // 可享受的优惠折扣信息
  160. show_coupons: false,
  161. // 领取优惠券
  162. show_discounts: false,
  163. // 查看促销活动
  164. show_cart: false,
  165. // 加入购物车弹窗
  166. message: '',
  167. purchaseInfo: {
  168. status: false,
  169. num: 0
  170. },
  171. // 限购
  172. active: false,
  173. type: 0,
  174. endTime: {
  175. interval: '',
  176. day: 0,
  177. hour: 0,
  178. minute: 0,
  179. second: 0,
  180. count: 0
  181. },
  182. startsTime: {
  183. interval: '',
  184. day: 0,
  185. hour: 0,
  186. minute: 0,
  187. second: 0,
  188. count: 0
  189. },
  190. show_ten: false,
  191. // 网络繁忙弹窗
  192. config: '',
  193. animation:'',
  194. show:''
  195. };
  196. },
  197. components: {
  198. ten,
  199. uParse
  200. },
  201. onLoad(e) {
  202. // 第三方平台配置颜色
  203. var gbConfig = this.$cookieStorage.get('globalConfig') || '';
  204. this.setData({
  205. config: gbConfig
  206. });
  207. wx.showLoading({
  208. title: "加载中",
  209. mask: true
  210. });
  211. if (!e.id) wx.redirectTo({
  212. url: '/pages/store/list/list'
  213. });
  214. var is_login = this.$cookieStorage.get('user_token');
  215. this.setData({
  216. id: e.id,
  217. query: e,
  218. is_login: is_login
  219. }); // this.queryDiscounts(e.id);
  220. this.getGoodsDetail({
  221. api: `api/store/detail/${e.id}`,
  222. data: {
  223. include: 'photos,oneComment,guessYouLike,point'
  224. }
  225. }).then(() => {
  226. console.log(this.commodity);
  227. this.attributesListF(this.detailData.meta);
  228. wx.setNavigationBarTitle({
  229. title: this.detailData.data.name
  230. });
  231. this.setData({
  232. price: Number(this.commodity.sell_price).toFixed(2),
  233. store_count: this.commodity.store_nums
  234. });
  235. this.changeText();
  236. this.disallow_cart();
  237. this.queryCommodityStore(e.id);
  238. this.queryFavoriteStatus(e.id, 'goods');
  239. }); // 用户登录后请求限购接口
  240. if (this.is_login) {
  241. this.goodsPurchase(this.id);
  242. }
  243. },
  244. onShareAppMessage(res) {
  245. return {
  246. title: this.commodity.name,
  247. // path: '/' + this.router + '?id=' + this.id,
  248. path: `/${this.route}?id=${this.id}`,
  249. imageUrl: this.commodity.img,
  250. success: function (res) {
  251. wx.showModal({
  252. content: '转发成功',
  253. showCancel: false
  254. });
  255. },
  256. fail: function (res) {
  257. wx.showModal({
  258. content: '转发取消',
  259. showCancel: false
  260. });
  261. }
  262. };
  263. },
  264. props: {},
  265. methods: {
  266. changeStatus() {
  267. var token = this.$cookieStorage.get('user_token');
  268. if (token) {
  269. this.changeFavorite(this.id, 'goods');
  270. } else {
  271. var url = getUrl();
  272. wx.showModal({
  273. content: '请先登录',
  274. success: res => {
  275. if (res.confirm) {
  276. wx.navigateTo({
  277. url: '/pages/user/register/register?url=' + url
  278. });
  279. }
  280. }
  281. });
  282. }
  283. },
  284. // 网络繁忙倒计时
  285. HideTen() {
  286. this.setData({
  287. show_ten: false
  288. });
  289. },
  290. changeText() {
  291. var ret;
  292. var commodity = this.commodity;
  293. var seckill = this.detailData.meta.seckill;
  294. if (!commodity) {
  295. return;
  296. }
  297. if (commodity.is_del != 0) {
  298. ret = {
  299. status: false,
  300. message: '商品已下架'
  301. };
  302. } else if (commodity.store_nums <= 0) {
  303. ret = {
  304. status: false,
  305. message: '商品缺货中'
  306. };
  307. } else {
  308. ret = {
  309. status: true,
  310. message: '立即兑换'
  311. };
  312. }
  313. this.setData({
  314. cart_status: ret
  315. });
  316. },
  317. // 活动开始的倒计时
  318. countTime() {
  319. var d = 86400000,
  320. h = 3600000,
  321. n = 60000,
  322. end = this.detailData.meta.seckill.ends_at,
  323. server = this.detailData.meta.seckill.server_time,
  324. arr = String(end).split(/\D/),
  325. newArr = String(server).split(/\D/);
  326. newArr = newArr.map(Number);
  327. arr = arr.map(Number);
  328. var serverTime = new Date(newArr[0], newArr[1] - 1, newArr[2], newArr[3], newArr[4], newArr[5]).getTime(); // var nowTime = new Date().getTime();
  329. var endTime = new Date(arr[0], arr[1] - 1, arr[2], arr[3], arr[4], arr[5]).getTime(); // 组件才秒杀列表页使用时,没有重新请求列表,服务器时间应该加上未开始倒计时的时间
  330. if (this.mold == 'list') {
  331. serverTime = serverTime + this.startsTime.count;
  332. } // 计算开始时间跟结束时间的差值
  333. var timeDiff = endTime - serverTime; // 在本地计算倒计时
  334. var allTime = this.endTime.count + 1000;
  335. this.setData({
  336. 'endTime.count': allTime
  337. }); // this.endTime.count += 1000;
  338. var interval = timeDiff - this.endTime.count;
  339. if (interval < 0) {
  340. // 活动结束
  341. this.isEnd(); // this.$emit('end',this.index)
  342. } else {
  343. var day = Math.floor(interval / d);
  344. Math.floor(interval -= day * d);
  345. var hour = Math.floor(interval / h);
  346. Math.floor(interval -= hour * h);
  347. var minute = Math.floor(interval / n);
  348. var second = Math.floor(interval % n / 1000);
  349. this.setData({
  350. 'endTime.day': day,
  351. 'endTime.hour': hour,
  352. 'endTime.minute': minute,
  353. 'endTime.second': second
  354. }); // this.endTime.day = day;
  355. // this.endTime.hour = hour;
  356. // this.endTime.minute = minute;
  357. // this.endTime.second = second;
  358. }
  359. },
  360. // 活动未开始的倒计时
  361. countStartsTime() {
  362. var d = 86400000,
  363. h = 3600000,
  364. n = 60000,
  365. sta = this.detailData.meta.seckill.starts_at,
  366. server = this.detailData.meta.seckill.server_time,
  367. arr = String(sta).split(/\D/),
  368. newArr = String(server).split(/\D/);
  369. newArr = newArr.map(Number);
  370. arr = arr.map(Number);
  371. var serverTime = new Date(newArr[0], newArr[1] - 1, newArr[2], newArr[3], newArr[4], newArr[5]).getTime();
  372. var staTime = new Date(arr[0], arr[1] - 1, arr[2], arr[3], arr[4], arr[5]).getTime();
  373. var timeDiff = staTime - serverTime;
  374. var allTime = this.startsTime.count + 1000;
  375. this.setData({
  376. 'startsTime.count': allTime
  377. }); // this.startsTime.count += 1000;
  378. var interval = timeDiff - this.startsTime.count; // var interval = staTime - nowTime;
  379. // 时间差小于一天
  380. if (interval < d) {
  381. this.setData({
  382. type: 1
  383. });
  384. if (interval < 0) {
  385. // 代表活动已经开始了,需要执行活动开始倒计时
  386. var interval = setInterval(this.countTime, 1000);
  387. this.setData({
  388. active: true,
  389. 'endTime.interval': interval
  390. });
  391. this.isStarts(); // this.active = true;
  392. // this.startsTime.count = -(this.startsTime.count - 1000)
  393. // this.$emit('starts',this.index);
  394. // this. = setInterval(this.countTime,1000);
  395. // 清除掉倒计时,以免重复分发事件
  396. clearInterval(this.startsTime.interval);
  397. } else {
  398. var day = Math.floor(interval / d);
  399. Math.floor(interval -= day * d);
  400. var hour = Math.floor(interval / h);
  401. Math.floor(interval -= hour * h);
  402. var minute = Math.floor(interval / n);
  403. var second = Math.floor(interval % n / 1000);
  404. this.setData({
  405. 'startsTime.day': day,
  406. 'startsTime.hour': hour,
  407. 'startsTime.minute': minute,
  408. 'startsTime.second': second
  409. }); // this.startsTime.day = day;
  410. // this.startsTime.hour = hour;
  411. // this.startsTime.minute = minute;
  412. // this.startsTime.second = second;
  413. }
  414. } else {
  415. this.setData({
  416. message: `${arr[1]}${arr[2]} 日,${arr[3]} : ${arr[4]} 开始`
  417. }); // this.message = `${arr[1] - 1} 月 ${arr[2]} 日,${arr[3]} : ${arr[4]} 开始`
  418. }
  419. },
  420. // 秒杀结束执行
  421. isEnd() {
  422. if (this.detailData.meta.seckill) {
  423. var id = this.id;
  424. this.getGoodsDetail({
  425. api: `api/store/detail/${id}`,
  426. data: {
  427. include: 'photos,products,oneComment,guessYouLike,whoLike,point'
  428. }
  429. });
  430. this.queryCommodityStore(id);
  431. }
  432. },
  433. isStarts() {
  434. if (this.detailData.meta.seckill.init_status == 2) {
  435. var id = this.id;
  436. this.getGoodsDetail({
  437. api: `api/store/detail/${id}`,
  438. data: {
  439. include: 'photos,products,oneComment,guessYouLike,whoLike,point'
  440. }
  441. });
  442. this.queryCommodityStore(id);
  443. }
  444. },
  445. // onStateChange(nextState){
  446. // console.log(nextState)
  447. // if (!app.isEmptyObject(nextState.detailData)) {
  448. // Wxparse.wxParse('detailI', 'html', nextState.detailData.data.content, this, 0);
  449. // this.attributesListF(nextState.detailData.meta);
  450. // wx.setNavigationBarTitle({
  451. // title: nextState.detailData.data.name
  452. // })
  453. // this.setData({
  454. // detailData: nextState.detailData,
  455. // commodity: nextState.detailData.data
  456. // })
  457. // wx.hideLoading()
  458. // }
  459. //
  460. // // if (nextState.commoditySpec.length > 0 ) {
  461. // //
  462. // // this.setData({
  463. // // specs:nextState.commoditySpec
  464. // // })
  465. // // }
  466. // //
  467. // // if (!app.isEmptyObject(nextState.resultStore)) {
  468. // // this.specStore(nextState.resultStore,nextState.resultStore.key)
  469. // //
  470. //
  471. // // }
  472. //
  473. // },
  474. change(e) {
  475. var expands = this.expands[e.currentTarget.dataset.type];
  476. this.setData({
  477. [`expands.${e.currentTarget.dataset.type}`]: !expands
  478. });
  479. },
  480. showSelect(e) {
  481. this.setData({
  482. show_select: false
  483. });
  484. // #ifdef MP-WEIXIN
  485. var animation = new Animation('show');
  486. animation.positionInit();
  487. // #endif
  488. },
  489. closeSelect() {
  490. // #ifdef MP-WEIXIN
  491. var animation = new Animation('show');
  492. animation.up().then(() => {
  493. this.setData({
  494. show_select: true
  495. });
  496. });
  497. // #endif
  498. // #ifdef H5 || APP-PLUS
  499. this.show_select=true
  500. // #endif
  501. },
  502. changeCount(e) {
  503. var select_count = parseInt(this.select_count);
  504. var index = e.target.dataset.index;
  505. var val = select_count + (parseInt(index) ? 1 : -1);
  506. if (val > 0 && val <= parseInt(this.store_count)) {
  507. this.setData({
  508. select_count: val
  509. }); // 用户登录并且开启了限购
  510. if (this.purchaseInfo.status && this.is_login) {
  511. if (this.select_count > this.purchaseInfo.num) {
  512. this.setData({
  513. select_count: this.select_count - 1
  514. });
  515. wx.showToast({
  516. title: '超过限购数量',
  517. image: '../../../static/error.png'
  518. });
  519. }
  520. }
  521. } else if (val <= 0) {
  522. wx.showToast({
  523. title: '小于最小库存',
  524. image: '../../../static/error.png'
  525. });
  526. } else if (val > parseInt(this.store_count)) {
  527. wx.showToast({
  528. title: '超出最大库存',
  529. image: '../../../static/error.png'
  530. });
  531. }
  532. },
  533. modifyCount(e) {
  534. var val = parseInt(e.detail.value);
  535. if (!val) {
  536. val = 1;
  537. } else if (!/^[1-9]\d*$/.test(val)) {
  538. val = val.replace(/[^\d].*$/, '');
  539. val = parseInt(val) || 1;
  540. }
  541. if (this.purchaseInfo.status && this.is_login) {
  542. if (val < 0) {
  543. val = 1;
  544. } else if (val > this.purchaseInfo.num) {
  545. val = this.purchaseInfo.num || 1;
  546. wx.showToast({
  547. title: '超过限购数量',
  548. image: '../../../static/error.png'
  549. });
  550. }
  551. } else {
  552. if (val < 0) {
  553. val = 1;
  554. } else if (val > this.store_count) {
  555. wx.showToast({
  556. title: '超过最大库存',
  557. image: '../../../static/error.png'
  558. });
  559. val = parseInt(this.store_count);
  560. }
  561. }
  562. this.setData({
  563. select_count: val
  564. });
  565. },
  566. showCoupons() {
  567. this.setData({
  568. show_coupons: !this.show_coupons
  569. });
  570. },
  571. showDiscounts() {
  572. this.setData({
  573. show_discounts: !this.show_discounts
  574. });
  575. },
  576. getCoupon(e) {
  577. var is_login = this.$cookieStorage.get('user_token');
  578. var code = e.currentTarget.dataset.code;
  579. var index = e.currentTarget.dataset.index;
  580. if (is_login) {
  581. this.goodsConvertCoupon(code, index);
  582. } else {
  583. var url = getUrl();
  584. wx.showModal({
  585. tiele: '',
  586. content: '请先登录',
  587. success: res => {
  588. if (res.confirm) {
  589. wx.navigateTo({
  590. url: '/pages/user/register/register?url=' + url
  591. });
  592. }
  593. }
  594. });
  595. }
  596. },
  597. selectSpec(e) {
  598. var spec = {
  599. key: e.currentTarget.dataset.key,
  600. index: e.currentTarget.dataset.index,
  601. disabled: Number(e.currentTarget.dataset.disabled),
  602. active: Number(e.currentTarget.dataset.active),
  603. id: Number(e.currentTarget.dataset.id)
  604. };
  605. if (spec.disabled) return;
  606. var specs = this.specs;
  607. if (!spec.active) {
  608. for (let item of specs[spec.index].values) {
  609. if (item.active) {
  610. item.active = false;
  611. break;
  612. }
  613. }
  614. }
  615. specs[spec.index].values[spec.key].active = !specs[spec.index].values[spec.key].active;
  616. spec.active = !spec.active;
  617. specs[spec.index].select = spec.active ? spec.id : '';
  618. this.setData({
  619. specs: specs
  620. });
  621. var canBuy = this.disallow_cart();
  622. this.setData({
  623. canBuy: canBuy
  624. }); // this.queryCommodityStore(id, spec.index);
  625. this.specStore(this.result, spec.index);
  626. },
  627. specStore(result, key) {
  628. var query = this.query;
  629. var data = result.data;
  630. var specs = this.specs;
  631. if (key === undefined) {
  632. specs.forEach(spec => {
  633. for (let v of spec.values) {
  634. v.disabled = !data[v.id] || data[v.id].count == 0;
  635. }
  636. });
  637. this.setData({
  638. specs: specs,
  639. skuTable: result.table
  640. });
  641. specs = this.specs;
  642. var canBuy = this.disallow_cart();
  643. this.setData({
  644. canBuy: canBuy
  645. });
  646. specs.forEach(spec => {
  647. let name = 'spec[' + spec.id + ']';
  648. if (query[name]) {
  649. let id = query[name];
  650. for (let v of spec.values) {
  651. if (v.id == id && !v.disabled && data[v.id] && data[v.id].count) {
  652. v.active = true;
  653. spec.select = v.id;
  654. this.setData({
  655. specs: specs
  656. });
  657. specs = this.specs;
  658. var canBuy = this.disallow_cart();
  659. this.setData({
  660. canBuy: canBuy
  661. });
  662. this.specStore(result, v.index);
  663. return;
  664. }
  665. }
  666. }
  667. if (!spec.select) {
  668. for (let v of spec.values) {
  669. if (!v.disabled && data[v.id] && data[v.id].count) {
  670. v.active = true;
  671. spec.select = v.id;
  672. this.setData({
  673. specs: specs
  674. });
  675. specs = this.specs;
  676. var canBuy = this.disallow_cart();
  677. this.setData({
  678. canBuy: canBuy
  679. }); // this.$emit('specStore', result, v.index);
  680. this.specStore(result, v.index);
  681. return;
  682. }
  683. }
  684. return;
  685. }
  686. this.setData({
  687. specs: specs
  688. });
  689. });
  690. return;
  691. }
  692. var spec = specs[key];
  693. if (spec.select) {
  694. this.setData({
  695. store_count: data[spec.select].count
  696. });
  697. for (let i = 0; i < specs.length; i++) {
  698. if (i === key) continue;
  699. specs[i].values.forEach(v => {
  700. v.disabled = !data[spec.select].specs[v.id].count;
  701. });
  702. if (specs[i].select) {
  703. this.setData({
  704. store_count: data[spec.select].specs[specs[i].select].count
  705. });
  706. }
  707. this.setData({
  708. specs: specs
  709. });
  710. }
  711. } else {
  712. this.setData({
  713. store_count: this.commodity.store
  714. });
  715. for (let i = 0; i < specs.length; i++) {
  716. if (i === key) continue;
  717. specs[i].values.forEach(v => {
  718. v.disabled = !data[v.id] || !data[v.id].count;
  719. });
  720. if (specs[i].select) {
  721. this.setData({
  722. store_count: data[specs[i].select].count
  723. });
  724. }
  725. this.setData({
  726. specs: specs
  727. });
  728. console.log(specs);
  729. }
  730. }
  731. if (parseInt(this.select_count) > this.store_count) {
  732. this.setData({
  733. select_count: String(this.store_count)
  734. });
  735. } else if (parseInt(this.select_count) === 0) {
  736. this.setData({
  737. select_count: '1'
  738. });
  739. }
  740. this.setData({
  741. specs: specs
  742. });
  743. var canBuy = this.disallow_cart();
  744. this.setData({
  745. canBuy: canBuy
  746. });
  747. },
  748. confirm() {
  749. if (this.loading) return;
  750. if (this.disallow_cart()) return;
  751. this.setData({
  752. loading: true
  753. });
  754. var select_product = this.select_product;
  755. var select_count = Number(this.select_count);
  756. var data = this.specs.length ? {
  757. id: select_product.id,
  758. name: this.commodity.name,
  759. qty: select_count,
  760. store_count: this.store_count,
  761. price: select_product.price,
  762. market_price: this.commodity.market_price,
  763. attributes: {
  764. img: select_product.img || this.detailData.data.photos[0].url,
  765. size: select_product.size,
  766. color: select_product.color,
  767. com_id: this.commodity.id
  768. }
  769. } : {
  770. id: this.commodity.id,
  771. name: this.commodity.name,
  772. qty: select_count,
  773. store_count: this.store_count,
  774. price: this.commodity.sell_price,
  775. market_price: this.commodity.market_price,
  776. attributes: {
  777. img: this.commodity.img || this.detailData.data.photos[0].url,
  778. com_id: this.commodity.id
  779. }
  780. }; // if (this.channel) data.attributes.channel = 'employee';
  781. if (select_product.sku) data.attributes.sku = select_product.sku; // 判断是否登录
  782. // var is_login = !!Cache.get(cache_keys.token);
  783. var datas = {
  784. product_id: select_product.id,
  785. quantity: select_count
  786. };
  787. if (!select_product.id) {
  788. datas.goods_id = this.id;
  789. }
  790. var token = this.$cookieStorage.get('user_token');
  791. if (!token) {
  792. this.setData({
  793. loading: false
  794. });
  795. wx.showModal({
  796. content: '请先登录',
  797. showCancel: false,
  798. success: res => {
  799. if (res.confirm || !res.cancel && !res.confirm) {
  800. wx.navigateTo({
  801. url: '/pages/user/register/register?url=' + getUrl()
  802. });
  803. }
  804. }
  805. });
  806. } else {
  807. this.pointSore(datas);
  808. }
  809. },
  810. addStoreNum() {
  811. // 判断是否登录
  812. // var is_login = !!Cache.get(cache_keys.token);
  813. // var cache_store_num = Cache.get(cache_keys.cart);
  814. var cache_store_num = this.$cookieStorage.get('cart');
  815. if (this.is_login) {
  816. this.queryShoppingCount();
  817. } else {
  818. if (cache_store_num && cache_store_num.length) {
  819. var store_num = this.store_num;
  820. cache_store_num.forEach(v => {
  821. store_num += v.qty;
  822. });
  823. this.setData({
  824. store_num: store_num
  825. });
  826. }
  827. }
  828. },
  829. disallow_cart() {
  830. if (!this.specs.length) {
  831. return !this.store_count;
  832. }
  833. var ids = [],
  834. select_product = {},
  835. specs = this.specs;
  836. console.log(this.commodity.sell_price);
  837. this.setData({
  838. price: Number(this.commodity.sell_price).toFixed(2)
  839. });
  840. for (let spec of specs) {
  841. if (!spec.select) {
  842. this.setData({
  843. price: Number(this.commodity.sell_price).toFixed(2),
  844. select_product: null
  845. });
  846. return true;
  847. }
  848. ids.push(spec.select);
  849. for (let v of spec.values) {
  850. if (v.id === spec.select) {
  851. switch (spec.label_key) {
  852. case 'color':
  853. select_product.img = v.img;
  854. select_product.color = v.alias || v.value;
  855. select_product.bac = v.color;
  856. break;
  857. default:
  858. select_product.size = v.alias || v.value;
  859. }
  860. break;
  861. }
  862. }
  863. }
  864. if (this.skuTable) {
  865. ids = ids[0] > ids[1] ? [ids[1], ids[0]] : ids;
  866. ids = ids.join('-');
  867. select_product = Object.assign(select_product, this.skuTable[ids]);
  868. }
  869. this.setData({
  870. price: Number(select_product.price).toFixed(2),
  871. select_product: select_product
  872. });
  873. return false;
  874. },
  875. attributesListF(meta) {
  876. var topList = [];
  877. var bottomList = [];
  878. if (meta && meta.attributes) {
  879. var attributes = meta.attributes;
  880. for (var item of attributes) {
  881. if (item.is_chart === 1) {
  882. bottomList.push(item);
  883. } else {
  884. topList.push(item);
  885. }
  886. }
  887. }
  888. this.setData({
  889. 'attributesList.top': topList,
  890. 'attributesList.bottom': bottomList
  891. });
  892. },
  893. jump(e) {
  894. if (e.currentTarget.dataset.type == 'shop') {
  895. wx.switchTab({
  896. url: '/pages/index/index/index'
  897. });
  898. } else if (e.currentTarget.dataset.type == 'cart') {
  899. wx.switchTab({
  900. url: '/pages/store/cart/cart'
  901. });
  902. } else {
  903. wx.navigateTo({
  904. url: '/pages/store/detail/detail?id=' + e.currentTarget.dataset.id
  905. });
  906. }
  907. },
  908. jumpToDetail(e) {
  909. var id = e.currentTarget.dataset.id;
  910. wx.navigateTo({
  911. url: `/pages/store/detail/detail?id=${id}`
  912. });
  913. },
  914. jumpMeal(e) {
  915. var id = e.currentTarget.dataset.suitid;
  916. wx.navigateTo({
  917. url: `/pages/store/meal/meal?id=${id}`
  918. });
  919. },
  920. bigImg(e) {
  921. var srcList = [];
  922. var src = e.currentTarget.dataset.url;
  923. this.detailData.data.photos.forEach(i => {
  924. srcList.push(i.url);
  925. });
  926. if (src && srcList.length) {
  927. wx.previewImage({
  928. current: src,
  929. urls: srcList
  930. });
  931. }
  932. },
  933. // 重要!!!!
  934. move() {},
  935. goCart() {
  936. wx.navigateTo({
  937. url: '/pages/store/cart/cart'
  938. });
  939. this.changeCart();
  940. },
  941. changeCart() {
  942. this.setData({
  943. show_cart: !this.show_cart
  944. });
  945. },
  946. // 查询是否收藏改商品
  947. queryFavoriteStatus(id, type) {
  948. var token = this.$cookieStorage.get('user_token');
  949. if (!token) return;
  950. this.$http.get({
  951. api: 'api/favorite/isfav',
  952. header: {
  953. Authorization: token
  954. },
  955. data: {
  956. favoriteable_id: id,
  957. favoriteable_type: type
  958. }
  959. }).then(res => {
  960. res = res.data;
  961. if (res.status) {
  962. // this.setData({
  963. // is_Fav: !!res.data.is_Fav
  964. // });
  965. this.is_Fav=!!res.data.is_Fav;
  966. } else {
  967. wx.showToast({
  968. image: '../../../static/error.png',
  969. title: res.message
  970. });
  971. }
  972. }).catch(rej => {
  973. console.log(rej);
  974. });
  975. },
  976. queryCommodityStore(id, key) {
  977. var that = this;
  978. this.$http.get({
  979. api: `api/store/detail/${id}/stock`
  980. }).then(res => {
  981. wx.hideLoading();
  982. res = res.data;
  983. if (!res.status || !res.data || !res.data.specs) return;
  984. if (res.data.specs && typeof key === 'undefined') {
  985. let specs = [];
  986. Object.keys(res.data.specs).forEach((key, index) => {
  987. let value = res.data.specs[key];
  988. value.select = '';
  989. value.values = value.list.map(v => {
  990. return Object.assign({
  991. index: index,
  992. active: false,
  993. disabled: false
  994. }, v);
  995. });
  996. delete value.list;
  997. specs.push(value);
  998. });
  999. that.setData({
  1000. specs: specs
  1001. });
  1002. console.log(specs);
  1003. var canBuy = this.disallow_cart();
  1004. this.setData({
  1005. canBuy: canBuy
  1006. });
  1007. }
  1008. if (res.data.stores) {
  1009. let data = {};
  1010. Object.keys(res.data.stores).forEach(key => {
  1011. let value = res.data.stores[key];
  1012. value.ids.forEach(id => {
  1013. data[id] = data[id] || {
  1014. count: 0,
  1015. specs: {}
  1016. };
  1017. data[id].count += Number(value.store);
  1018. value.ids.forEach(i => {
  1019. if (i === id) return;
  1020. data[id].specs[i] = {
  1021. count: Number(value.store)
  1022. };
  1023. });
  1024. });
  1025. }); // console.log(data);
  1026. var result = {
  1027. data,
  1028. table: res.data.stores
  1029. };
  1030. // this.setData({
  1031. // result: result
  1032. // });
  1033. this.result=result;
  1034. that.specStore(result, key); // this.$emit('specStore', result, key);
  1035. }
  1036. }).catch(err => {});
  1037. },
  1038. queryShoppingCount() {
  1039. var oauth = this.is_login;
  1040. this.$http.get({
  1041. api: `api/shopping/cart/count`,
  1042. header: {
  1043. Authorization: oauth
  1044. }
  1045. }).then(res => {}).catch(rej => {});
  1046. },
  1047. appendToCart(data) {
  1048. if (!Array.isArray(data)) {
  1049. data = [data];
  1050. }
  1051. var oauth = this.is_login;
  1052. var json = {};
  1053. data.forEach((v, i) => json[i] = v);
  1054. data = json;
  1055. var that = this;
  1056. this.$http.post({
  1057. api: 'api/shopping/cart',
  1058. header: {
  1059. Authorization: oauth
  1060. },
  1061. data: data
  1062. }).then(res => {
  1063. res = res.data;
  1064. if (res.status) {
  1065. that.addCart(true);
  1066. } else {
  1067. that.addCart(false, res.message);
  1068. }
  1069. }).catch(rej => {
  1070. that.addCart(false);
  1071. });
  1072. },
  1073. addCart(success, message) {
  1074. // this.$refs.button.finish();
  1075. this.setData({
  1076. loading: false
  1077. });
  1078. if (success) {
  1079. this.closeSelect();
  1080. this.changeCart(); // wx.showModal({
  1081. // content: '商品成功加入购物车!',
  1082. // cancelText: '进购物车',
  1083. // confirmText: '继续购物',
  1084. // success: function (res) {
  1085. // if (res.confirm) {
  1086. // console.log('用户点击取消')
  1087. // } else if (res.cancel) {
  1088. // wx.navigateTo({
  1089. // url: '/pages/store/cart/cart'
  1090. // })
  1091. // }
  1092. // },
  1093. // fail: function () {
  1094. // wx.showToast({
  1095. // title: '添加失败',
  1096. // image: '../../../static/error.png',
  1097. // })
  1098. // }
  1099. // })
  1100. // if (typeof window.__analytics == 'function') {
  1101. // console.log('11212132323')
  1102. // var cart = {
  1103. // action :'add to cart',
  1104. // product:{
  1105. // sku: this.$brand.name == 'JackWolfskin' ? this.select_product.id :this.select_product.sku,
  1106. // title: this.commodity.name,
  1107. // category: this.commodity.tags,
  1108. // quantity: this.store_count
  1109. // }
  1110. // }
  1111. //
  1112. // window.__analytics({cart})
  1113. // }
  1114. } else {
  1115. if (message) {
  1116. wx.showToast({
  1117. title: message
  1118. });
  1119. } else {
  1120. wx.showToast({
  1121. title: '添加到购物车失败,请重试'
  1122. });
  1123. }
  1124. }
  1125. },
  1126. pointSore(data) {
  1127. var token = this.$cookieStorage.get('user_token');
  1128. this.$http.post({
  1129. api: 'api/shopping/order/checkout/point',
  1130. header: {
  1131. Authorization: token
  1132. },
  1133. data: data
  1134. }).then(res => {
  1135. res = res.data;
  1136. if (res.status) {
  1137. this.setData({
  1138. loading: false
  1139. });
  1140. this.$cookieStorage.set('point_order', res.data);
  1141. wx.navigateTo({
  1142. url: '/pages/pointStore/order/order'
  1143. });
  1144. } else {
  1145. if (res.message == 'User unbind mobile') {
  1146. wx.showModal({
  1147. content: '请先绑定手机号',
  1148. showCancel: false,
  1149. success: res => {
  1150. if (res.confirm || !res.cancel && !res.confirm) {
  1151. wx.navigateTo({
  1152. url: '/pages/user/phone/phone?url=' + getUrl()
  1153. });
  1154. }
  1155. }
  1156. });
  1157. this.setData({
  1158. loading: false
  1159. });
  1160. return;
  1161. }
  1162. wx.showModal({
  1163. content: res.message || '请求失败',
  1164. showCancel: false
  1165. });
  1166. this.setData({
  1167. loading: false
  1168. });
  1169. }
  1170. });
  1171. },
  1172. changeFavorite(id, type) {
  1173. var token = this.$cookieStorage.get('user_token');
  1174. this.$http.post({
  1175. api: 'api/favorite/store',
  1176. header: {
  1177. Authorization: token
  1178. },
  1179. data: {
  1180. favoriteable_id: id,
  1181. favoriteable_type: type
  1182. }
  1183. }).then(res => {
  1184. res = res.data;
  1185. if (res.status) {
  1186. this.setData({
  1187. is_Fav: !this.is_Fav
  1188. });
  1189. }
  1190. });
  1191. },
  1192. getGoodsDetail(obj) {
  1193. var that = this;
  1194. return new Promise((resolve, reject) => {
  1195. this.$http.get(obj).then(res => {
  1196. res = res.data;
  1197. that.setData({
  1198. detailData: res,
  1199. commodity: res.data
  1200. });
  1201. if (res.meta.seckill) {
  1202. var interval = setInterval(this.countStartsTime, 1000);
  1203. that.setData({
  1204. 'startsTime.interval': interval
  1205. });
  1206. }
  1207. if (res.meta.discounts) {
  1208. res.meta.discounts.coupons.forEach(v => v.receive = false);
  1209. that.setData({
  1210. coupons: res.meta.discounts.coupons,
  1211. discounts: res.meta.discounts.discounts
  1212. });
  1213. }
  1214. resolve();
  1215. }).catch(err => {
  1216. console.log(err);
  1217. reject();
  1218. });
  1219. });
  1220. },
  1221. // 查询商品详情页优惠折扣信息
  1222. // queryDiscounts(id) {
  1223. // wx.request({
  1224. // url: config.GLOBAL.baseUrl + 'api/store/detail/' + id + '/discount',
  1225. // success: res => {
  1226. // if (res.statusCode == 200) {
  1227. // res = res.data;
  1228. // if (res.status) {
  1229. // res.data.coupons.forEach(v => v.receive = false);
  1230. // this.setData({
  1231. // coupons: res.data.coupons,
  1232. // discounts: res.data.discounts
  1233. // })
  1234. // }
  1235. // }
  1236. // }
  1237. // })
  1238. // },
  1239. // 领取优惠券
  1240. goodsConvertCoupon(code, index) {
  1241. var token = this.$cookieStorage.get('user_token');
  1242. this.$http.post({
  1243. api: 'api/coupon/convert',
  1244. header: {
  1245. Authorization: token
  1246. },
  1247. data: {
  1248. coupon_code: code
  1249. }
  1250. }).then(res => {
  1251. if (res.statusCode == 200) {
  1252. res = res.data;
  1253. if (res.status) {
  1254. var coupons = `coupons[${index}]`;
  1255. this.setData({
  1256. [`${coupons}.receive`]: true
  1257. });
  1258. wx.showToast({
  1259. title: '领取成功'
  1260. });
  1261. } else {
  1262. wx.showToast({
  1263. title: res.message,
  1264. image: '../../../static/error.png'
  1265. });
  1266. }
  1267. } else {
  1268. wx.showToast({
  1269. title: '领取失败',
  1270. image: '../../../static/error.png'
  1271. });
  1272. }
  1273. });
  1274. },
  1275. // 秒杀结算
  1276. checkoutSeckillOrder(data) {
  1277. var token = this.$cookieStorage.get('user_token');
  1278. this.$http.post({
  1279. api: 'api/shopping/order/checkout?seckill_item_id=' + data.seckill_item_id,
  1280. header: {
  1281. Authorization: token
  1282. },
  1283. data: data
  1284. }).then(res => {
  1285. if (res.statusCode == 200) {
  1286. res = res.data;
  1287. if (res.status) {
  1288. this.$cookieStorage.set('local_order', res.data);
  1289. this.setData({
  1290. loading: false
  1291. });
  1292. wx.navigateTo({
  1293. url: '/pages/store/order/order?type=seckill'
  1294. });
  1295. } else {
  1296. if (res.data && res.data.server_busy) {
  1297. this.setData({
  1298. show_ten: true
  1299. });
  1300. } else if (res.message == 'User unbind mobile') {
  1301. wx.showModal({
  1302. content: '请先绑定手机号',
  1303. showCancel: false,
  1304. success: res => {
  1305. if (res.confirm || !res.cancel && !res.confirm) {
  1306. wx.navigateTo({
  1307. url: '/pages/user/phone/phone?url=' + getUrl()
  1308. });
  1309. }
  1310. }
  1311. });
  1312. } else {
  1313. wx.showModal({
  1314. content: res.message || '请求失败',
  1315. showCancel: false
  1316. });
  1317. }
  1318. this.setData({
  1319. loading: false
  1320. });
  1321. }
  1322. }
  1323. });
  1324. },
  1325. // 商品限购
  1326. goodsPurchase(id) {
  1327. var token = this.$cookieStorage.get('user_token');
  1328. this.$http.get({
  1329. api: 'api/store/goods/purchase/' + id,
  1330. header: {
  1331. Authorization: token
  1332. }
  1333. }).then(res => {
  1334. if (res.statusCode == 200) {
  1335. res = res.data;
  1336. if (res.status) {
  1337. if (res.data) {
  1338. this.setData({
  1339. 'purchaseInfo.status': true,
  1340. 'purchaseInfo.num': res.data.user_limit
  1341. });
  1342. }
  1343. } else {
  1344. wx.showModal({
  1345. content: res.message || '接口错误',
  1346. showCancel: false
  1347. });
  1348. }
  1349. } else {
  1350. wx.showModal({
  1351. content: '请求失败',
  1352. showCancel: false
  1353. });
  1354. }
  1355. });
  1356. },
  1357. setData: function (obj) {
  1358. let that = this;
  1359. let keys = [];
  1360. let val, data;
  1361. Object.keys(obj).forEach(function (key) {
  1362. keys = key.split('.');
  1363. val = obj[key];
  1364. data = that.$data;
  1365. keys.forEach(function (key2, index) {
  1366. if (index + 1 == keys.length) {
  1367. that.$set(data, key2, val);
  1368. } else {
  1369. if (!data[key2]) {
  1370. that.$set(data, key2, {});
  1371. }
  1372. }
  1373. data = data[key2];
  1374. });
  1375. });
  1376. }
  1377. },
  1378. computed: {},
  1379. watch: {}
  1380. };
  1381. </script>
  1382. <style>
  1383. .detail-active {
  1384. transition: transform 350ms linear 0ms;
  1385. transform: translate3d(0px, -55px, 0px);
  1386. transform-origin: 50% 50% 0px;
  1387. }
  1388. </style>
  1389. <style rel="stylesheet/less" lang="less">
  1390. @import "detail";
  1391. </style>