detail.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  1. <template>
  2. <mobile-frame>
  3. <view class="main">
  4. <view class="onemain">
  5. <scroll-view scroll-y="true" class="scroll-view" scroll-with-animation :scroll-into-view="topItem"
  6. @scroll="handleScroll">
  7. <view class="list-scroll-view" id="top">
  8. <view class="one">
  9. <swiper class="swiper" circular :indicator-dots="true" indicator-color="#ffffff"
  10. indicator-active-color="#FB1438" :autoplay="true" :interval="3000" :duration="1000">
  11. <swiper-item class="list" v-for="(item,index) in bannerList" :key="index">
  12. <image class="image" :src="item.url" mode="aspectFit">
  13. </image>
  14. </swiper-item>
  15. </swiper>
  16. </view>
  17. <view class="two">
  18. <view class="two_1">
  19. <view class="money_1">
  20. <text>¥</text>
  21. <text>{{specs&&specs.length>0?specs[0].sell_money:0}}</text>
  22. </view>
  23. <view class="money_2">
  24. <text>¥</text>
  25. <text>{{specs&&specs.length>0?specs[0].flow_money:0}}</text>
  26. </view>
  27. </view>
  28. <view class="two_2">{{info.name}}</view>
  29. <view class="two_3">{{info.shot_brief}}</view>
  30. <view class="two_4">
  31. <text>运费{{specs&&specs.length>0?specs[0].freight:0}}元</text>
  32. <text>{{info.send_time}}内发货</text>
  33. </view>
  34. </view>
  35. <view class="thr">
  36. <view v-if="comment" class="thr_1" @click="toAppraise(info)">
  37. <view class="title">商品评价({{comment||0}})</view>
  38. <text class="iconfont icon-jiantouyou"></text>
  39. </view>
  40. <view v-else class="thr_1">
  41. <view class="title">暂无评价</view>
  42. <text class="iconfont icon-jiantouyou"></text>
  43. </view>
  44. </view>
  45. <view class="four">
  46. <view class="four_1">
  47. <image class="image" :src="shop.logo&&shop.logo.length>0?shop.logo[0].url:''"></image>
  48. <view class="other">
  49. <view class="name">{{shop.name}}</view>
  50. <view class="other_1"><text>宝贝数</text>{{shop.goods_num||0}}</view>
  51. </view>
  52. </view>
  53. <view class="four_2">
  54. <view class="grade">商品:<text>{{shop.goods_score||5}}</text></view>|
  55. <view class="grade">发货:<text>{{shop.send_score||5}}</text></view>|
  56. <view class="grade">服务:<text>{{shop.service_score||5}}</text></view>
  57. </view>
  58. <view class="four_2">
  59. <view class="btn" @tap="toShop('pagesHome/shop/index')">进入店铺</view>
  60. <view class="btn" @tap="shopCollect">{{shop_collect==true?'已关注':'关注'}}</view>
  61. </view>
  62. </view>
  63. <view class="five">
  64. <view class="five_1">
  65. <!-- <u-parse :content="info.brief"></u-parse> -->
  66. <rich-text :nodes="info.brief"></rich-text>
  67. </view>
  68. </view>
  69. </view>
  70. </scroll-view>
  71. </view>
  72. <view class="foot">
  73. <uni-goods-nav :options="options" :button-group="buttonGroup" @click="onClick"
  74. @buttonClick="buttonClick" />
  75. </view>
  76. </view>
  77. <view class="menu">
  78. <text @click="toMenu" class="iconfont icon-gengduo"></text>
  79. </view>
  80. <view class="menu_1" v-if="menu">
  81. <view class="title" v-for="(item,index) in barList" :key="index" @click="toPath(item)">
  82. <image class="image" :src="item.normal"></image>
  83. <view class="name">{{item.name}}</view>
  84. </view>
  85. </view>
  86. <view class="backTop" v-if="isShow==true">
  87. <text @click="backTop" class="iconfont icon-fanhuidingbu"></text>
  88. </view>
  89. <uni-popup ref="popup" background-color="#fff" type="bottom">
  90. <view class="content">
  91. <view class="one">
  92. <image class="image" v-if="specsInfo.file&&specsInfo.file.length>0"
  93. :src="specsInfo.file&&specsInfo.file.length>0?specsInfo.file[0].url:''"></image>
  94. <image class="image" v-else :src="info.file&&info.file.length>0?info.file[0].url:''"></image>
  95. <view class="other">
  96. <view class="money">
  97. <text>¥</text>
  98. <text>{{specsInfo.sell_money}}</text>
  99. </view>
  100. <view class="other_1">
  101. 已选: <text>{{specsInfo.name}}</text>
  102. </view>
  103. </view>
  104. <view class="button">
  105. <text @click="toClose" class="iconfont icon-shanchu"></text>
  106. </view>
  107. </view>
  108. <view class="two">
  109. <view class="two_1">规格</view>
  110. <view class="two_2">
  111. <text v-for="(item,index) in specs" :key="index" @click="toStyle(item,index)"
  112. :class="{ 'style': isActive==index}">{{item.name}}
  113. </text>
  114. </view>
  115. </view>
  116. <!-- <view class="thr">
  117. <text>数量</text>
  118. <view class="count">
  119. <uni-number-box :min="1" :max="specsInfo.num" :disabled="disabled" v-model="num"
  120. @change="toCount">
  121. </uni-number-box>
  122. </view>
  123. <text>库存{{specsInfo.num||0}}</text>
  124. </view> -->
  125. <view class="btn" @click="toBuy">
  126. 立即兑换
  127. </view>
  128. </view>
  129. </uni-popup>
  130. </mobile-frame>
  131. </template>
  132. <script>
  133. export default {
  134. components: {},
  135. data() {
  136. return {
  137. barList: [{
  138. name: '首页',
  139. route: 'pages/home/index',
  140. normal: require('@/static/shouye.png'),
  141. },
  142. {
  143. name: '微店',
  144. route: 'pages/store/index',
  145. normal: require('@/static/store.png'),
  146. },
  147. {
  148. name: '购物车',
  149. route: 'pages/market/index',
  150. normal: require('@/static/market.png'),
  151. },
  152. {
  153. name: '我的',
  154. route: 'pages/my/index',
  155. normal: require('@/static/my.png'),
  156. },
  157. ],
  158. options: [
  159. // {
  160. // icon: 'shop',
  161. // text: '店铺',
  162. // route: 'pagesHome/shop/index',
  163. // },
  164. // {
  165. // icon: 'cart',
  166. // text: '购物车',
  167. // route: 'pages/market/index',
  168. // },
  169. // {
  170. // icon: 'chat',
  171. // text: '客服',
  172. // }
  173. ],
  174. buttonGroup: [{
  175. text: '立即兑换',
  176. backgroundColor: 'linear-gradient(90deg, #EF1224, #EF1224)',
  177. color: '#fff',
  178. }],
  179. // 商品id
  180. id: '',
  181. user: {},
  182. // 轮播图
  183. bannerList: [],
  184. // 商品详情
  185. info: {},
  186. // 商店详情
  187. shop: {},
  188. // 规格情况
  189. specs: [],
  190. // 已选
  191. specsInfo: {},
  192. // 是否显示返回顶部
  193. isShow: false,
  194. topItem: '',
  195. // 商品收藏
  196. collection: false,
  197. // 店铺收藏
  198. shop_collect: false,
  199. // 菜单显示
  200. menu: false,
  201. disabled: true,
  202. // 显示文字判断
  203. type: '0',
  204. // 选择规格
  205. isActive: -1,
  206. // 计数器
  207. num: 1,
  208. // 评论数
  209. comment: 0,
  210. };
  211. },
  212. onLoad: async function(e) {
  213. const that = this;
  214. that.$set(that, `id`, e.id || '');
  215. },
  216. onShow: async function() {
  217. const that = this;
  218. await that.search();
  219. await that.configShare();
  220. },
  221. methods: {
  222. //店铺,
  223. // 购物车,客服跳转
  224. onClick(e) {
  225. const that = this;
  226. if (e.index == '0' && e.content.route) {
  227. // 进入店铺
  228. that.toShop();
  229. } else {
  230. uni.reLaunch({
  231. url: `/${e.content.route}`
  232. })
  233. }
  234. },
  235. // 进入店铺
  236. toShop() {
  237. const that = this;
  238. uni.navigateTo({
  239. url: `/pagesHome/shop/index?id=${that.shop._id}`
  240. })
  241. },
  242. // 商品评价
  243. toAppraise(e) {
  244. const that = this;
  245. uni.navigateTo({
  246. url: `/pagesHome/order/appraise?id=${that.id}`
  247. })
  248. },
  249. // 关注商铺
  250. async shopCollect() {
  251. const that = this;
  252. let user = that.user;
  253. if (user && user._id) {
  254. let res = await that.$api(`/storeShop`, `POST`, {
  255. customer: user._id,
  256. shop: that.shop._id
  257. });
  258. if (res.errcode == '0') {
  259. uni.showToast({
  260. title: res.data.msg,
  261. icon: 'none'
  262. })
  263. that.$set(that, `shop_collect`, res.data.result)
  264. }
  265. } else {
  266. uni.showToast({
  267. title: '无用户登录无法关注商铺',
  268. icon: 'none'
  269. })
  270. }
  271. },
  272. //主菜单跳转
  273. toPath(e) {
  274. if (e && e.route) uni.reLaunch({
  275. url: `/${e.route}`
  276. })
  277. },
  278. // 菜单展开
  279. toMenu() {
  280. const that = this;
  281. that.menu = !that.menu
  282. },
  283. // 计算高度
  284. handleScroll(e) {
  285. const that = this;
  286. let scrollTop = e.detail.scrollTop;
  287. that.isShow = scrollTop > 500;
  288. that.topItem = '';
  289. },
  290. // 返回顶部
  291. backTop() {
  292. const that = this;
  293. that.topItem = 'top'
  294. },
  295. //立即兑换弹窗
  296. buttonClick(e) {
  297. const that = this;
  298. that.$refs.popup.open();
  299. },
  300. // 修改样式
  301. toStyle(e, index) {
  302. const that = this;
  303. that.$set(that, `isActive`, index)
  304. that.$set(that, `specsInfo`, e)
  305. that.disabled = false;
  306. },
  307. // 计数器
  308. toCount(e) {
  309. const that = this;
  310. that.num = e;
  311. },
  312. // 立即兑换
  313. toBuy(e) {
  314. const that = this;
  315. uni.getStorage({
  316. key: 'token',
  317. success: async function(res) {
  318. let user = that.$jwt(res.data);
  319. that.$set(that, `user`, user)
  320. if (that.specsInfo._id) {
  321. let specs_id = that.specsInfo._id
  322. let data = {
  323. customer: user._id,
  324. shop: that.shop._id,
  325. goods: that.info._id,
  326. goodsSpec: specs_id,
  327. num: that.num
  328. }
  329. let arr = await that.$api(`/util/checkCanBuy`, 'POST', data)
  330. if (arr.errcode == '0') {
  331. if (arr.data.result == true) {
  332. uni.navigateTo({
  333. url: `/pagesIntegral/order/index?key=${arr.data.key}`
  334. })
  335. } else {
  336. uni.showToast({
  337. title: arr.data.msg,
  338. icon: 'none'
  339. })
  340. }
  341. } else {
  342. uni.showToast({
  343. title: arr.errmsg,
  344. icon: 'none'
  345. })
  346. }
  347. } else {
  348. uni.showModal({
  349. title: '提示',
  350. content: '请选择规格',
  351. confirmColor: '#ff0000',
  352. showCancel: false,
  353. success: function(res) {}
  354. });
  355. }
  356. },
  357. fail: function(err) {
  358. uni.navigateTo({
  359. url: `/pages/login/index`
  360. })
  361. }
  362. });
  363. },
  364. // 关闭弹框
  365. toClose() {
  366. const that = this;
  367. that.$refs.popup.close()
  368. },
  369. // 详情数据
  370. async search() {
  371. const that = this;
  372. uni.getStorage({
  373. key: 'token',
  374. success: function(res) {
  375. let user = that.$jwt(res.data);
  376. if (user) that.$set(that, `user`, user);
  377. that.searchOther();
  378. },
  379. fail: function(err) {}
  380. });
  381. let res = await that.$api(`/viewGoods/goodsDetail`, `POST`, {
  382. id: that.id
  383. });
  384. if (res.errcode == '0') {
  385. let data = res.data;
  386. if (data.goods.brief) data.goods.brief = data.goods.brief.replace(/\<img/gi,
  387. '<img class="rich-img"');
  388. that.$set(that, `info`, data.goods)
  389. that.$set(that, `specs`, data.specs)
  390. that.$set(that, `shop`, data.shop)
  391. if (data.specs.length > 0) that.$set(that.specsInfo, `sell_money`, data.specs[0].sell_money)
  392. that.$set(that, `bannerList`, data.goods.file)
  393. let con = await that.$api(`/goodsRate`, `GET`, {
  394. goods: data.goods._id
  395. })
  396. if (con.errcode == '0') {
  397. that.$set(that, `comment`, con.total)
  398. }
  399. }
  400. },
  401. async searchOther() {
  402. const that = this;
  403. let user = that.user;
  404. // 商铺是否收藏
  405. let arr = await that.$api(`/storeShop/check`, `GET`, {
  406. customer: user._id,
  407. shop: that.shop._id
  408. });
  409. if (arr.errcode == '0') {
  410. that.$set(that, `shop_collect`, arr.data)
  411. }
  412. },
  413. // 配置分享内容
  414. configShare() {
  415. const that = this;
  416. let user_id = that.user && that.user._id ? that.user._id : '';
  417. let id = that.info && that.info._id ? that.info._id : '';
  418. that.$config.share = {
  419. title: that.info.name,
  420. path: `/pagesHome/order/detail?id=${id}&user_id=${user_id}`,
  421. imageUrl: that.info.file[0].url
  422. }
  423. }
  424. }
  425. }
  426. </script>
  427. <style lang="scss">
  428. .scrollView {
  429. height: 100vh;
  430. }
  431. .main {
  432. display: flex;
  433. flex-direction: column;
  434. width: 100vw;
  435. height: 100vh;
  436. .onemain {
  437. position: relative;
  438. flex-grow: 1;
  439. background-color: var(--f1Color);
  440. .one {
  441. swiper {
  442. height: 70vw;
  443. }
  444. .list {
  445. border-radius: 5px;
  446. .image {
  447. width: 100%;
  448. height: 100%;
  449. border-radius: 5px;
  450. background-color: #fff;
  451. }
  452. }
  453. }
  454. .two {
  455. padding: 0 0 2vw 0;
  456. background-color: var(--mainColor);
  457. .two_1 {
  458. display: flex;
  459. align-items: center;
  460. border-bottom: 0.5vw solid var(--f9Color);
  461. padding: 2vw;
  462. .money_1 {
  463. color: var(--ff0Color);
  464. text {
  465. margin: 0 1vw 0 0;
  466. }
  467. text:last-child {
  468. font-size: var(--font20Szie);
  469. font-weight: bold;
  470. }
  471. }
  472. .money_2 {
  473. text-decoration: line-through;
  474. color: var(--f99Color);
  475. text {
  476. margin: 0 1vw 0 0;
  477. }
  478. text:last-child {
  479. font-size: var(--font16Size);
  480. }
  481. }
  482. }
  483. .two_2 {
  484. font-size: var(--font18Szie);
  485. font-weight: bold;
  486. padding: 1vw 2vw;
  487. }
  488. .two_3 {
  489. font-size: var(--font16Szie);
  490. color: var(--f85Color);
  491. padding: 1vw 2vw;
  492. }
  493. .two_4 {
  494. font-size: var(--font12Size);
  495. color: var(--fcColor);
  496. padding: 1vw 2vw;
  497. text {
  498. margin: 0 2vw 0 0;
  499. }
  500. }
  501. }
  502. .thr {
  503. .thr_1 {
  504. display: flex;
  505. flex-direction: row;
  506. justify-content: space-between;
  507. margin: 2vw 0 2vw 0;
  508. padding: 2vw;
  509. background-color: var(--mainColor);
  510. }
  511. }
  512. .four {
  513. padding: 2vw;
  514. background-color: var(--mainColor);
  515. .four_1 {
  516. display: flex;
  517. justify-content: space-between;
  518. .image {
  519. width: 15vw;
  520. height: 15vw;
  521. border: 0.1vw solid var(--fcColor);
  522. }
  523. .other {
  524. flex-grow: 1;
  525. margin: 0 0 0 2vw;
  526. .name {
  527. font-size: var(--font16Szie);
  528. }
  529. .other_1 {
  530. font-size: var(--font12Size);
  531. text {
  532. color: var(--fcColor);
  533. margin: 0 2vw 0 0;
  534. }
  535. }
  536. }
  537. }
  538. .four_2 {
  539. display: flex;
  540. flex-direction: row;
  541. justify-content: space-evenly;
  542. padding: 2vw 0;
  543. color: var(--f99Color);
  544. .grade {
  545. font-size: var(--font14Size);
  546. color: var(--f85Color);
  547. text {
  548. color: var(--ff0Color);
  549. }
  550. }
  551. .btn {
  552. border: 0.1vw solid var(--fcColor);
  553. padding: 1vw 6vw;
  554. border-radius: 1vw;
  555. color: var(--f00Color);
  556. }
  557. .btn:last-child {
  558. padding: 1vw 10vw;
  559. }
  560. }
  561. }
  562. .five {
  563. margin: 2vw 0 0 0;
  564. .five_1 {
  565. background-color: var(--mainColor);
  566. padding: 2vw;
  567. .rich-img {
  568. width: 100% !important;
  569. display: block;
  570. }
  571. }
  572. }
  573. }
  574. }
  575. .scroll-view {
  576. position: absolute;
  577. top: 0;
  578. left: 0;
  579. right: 0;
  580. bottom: 0;
  581. .list-scroll-view {
  582. display: flex;
  583. flex-direction: column;
  584. }
  585. }
  586. .scrollView {
  587. height: 100vh;
  588. }
  589. .menu {
  590. position: fixed;
  591. bottom: 30vw;
  592. right: 5vw;
  593. text {
  594. font-size: 30px;
  595. background-color: #0000005f;
  596. border-radius: 90px;
  597. }
  598. }
  599. .menu_1 {
  600. position: fixed;
  601. bottom: 40vw;
  602. right: 5vw;
  603. background-color: var(--mainColor);
  604. padding: 2vw;
  605. .title {
  606. display: flex;
  607. padding: 2vw;
  608. border-bottom: 0.1vw solid var(--fcColor);
  609. .image {
  610. width: 7vw;
  611. height: 6vw;
  612. }
  613. .name {
  614. margin: 0 0 0 1vw;
  615. font-size: var(--font14Size);
  616. }
  617. }
  618. }
  619. .backTop {
  620. position: fixed;
  621. bottom: 20vw;
  622. right: 5vw;
  623. text {
  624. font-size: 30px;
  625. background-color: #0000005f;
  626. border-radius: 90px;
  627. }
  628. }
  629. uni-popup {
  630. z-index: 999999 !important;
  631. }
  632. .content {
  633. height: 100vw;
  634. .one {
  635. display: flex;
  636. flex-direction: row;
  637. justify-content: space-between;
  638. margin: 2vw;
  639. padding: 2vw 0;
  640. border-bottom: 1px solid var(--f9Color);
  641. .image {
  642. width: 25vw;
  643. height: 25vw;
  644. margin: 0 2vw 0 0;
  645. }
  646. .other {
  647. display: flex;
  648. flex-direction: column;
  649. flex-grow: 1;
  650. margin: 0 0 0 2vw;
  651. .money {
  652. color: var(--fFB1Color);
  653. font-size: var(--font20Szie);
  654. padding: 2vw 0;
  655. }
  656. .other_1 {
  657. font-size: var(--font14Size);
  658. text {
  659. padding: 0 2vw;
  660. color: var(--f85Color);
  661. }
  662. }
  663. }
  664. }
  665. .two {
  666. margin: 0 2vw;
  667. padding: 2vw 0;
  668. font-size: var(--font12Size);
  669. border-bottom: 1px solid var(--f9Color);
  670. .two_2 {
  671. display: flex;
  672. flex-wrap: wrap;
  673. padding: 1vw;
  674. margin: 1vw 0 0 0;
  675. text {
  676. margin: 1vw 2vw 0 0;
  677. padding: 1vw;
  678. border-radius: 1vw;
  679. background-color: var(--f9Color);
  680. }
  681. .style {
  682. color: var(--mainColor);
  683. background-color: var(--ff0Color);
  684. }
  685. }
  686. }
  687. .thr {
  688. display: flex;
  689. justify-content: flex-start;
  690. margin: 0 2vw;
  691. padding: 2vw 0;
  692. text {
  693. margin: 0 2vw 0 0;
  694. }
  695. text:last-child {
  696. margin: 0 0 0 2vw;
  697. font-size: var(--font12Size);
  698. color: var(--f85Color);
  699. }
  700. }
  701. .btn {
  702. position: fixed;
  703. bottom: 0;
  704. width: 100vw;
  705. padding: 4vw 0;
  706. background-color: var(--fFB1Color);
  707. text-align: center;
  708. font-size: var(--font18Szie);
  709. color: var(--mainColor);
  710. }
  711. }
  712. .uni-tab__cart-sub-left {
  713. padding: 0 !important;
  714. }
  715. </style>