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

564 lines
15 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. <template>
  2. <view>
  3. <lf-nav :spreadOut="false" :showIcon="true" bgColor="transparent!important"></lf-nav>
  4. <view class="shop-head">
  5. <image class="lf-w-100 lf-h-100" :src="detail.images[0].path" mode="aspectFill"></image>
  6. </view>
  7. <view class="shop-title">
  8. <view class="shop-flex">
  9. <view class="shop-img">
  10. <image class="shop-img" :src="detail.logo" mode="widthFix"></image>
  11. </view>
  12. <view>
  13. <view class="lf-color-black lf-font-36">{{ detail.name }}</view>
  14. <view class="lf-font-24 lf-color-black">
  15. <text class="lf-iconfont icon-dizhi lf-font-24 lf-color-primary"></text>
  16. <text class="lf-m-l-10">{{ detail.floor }}</text>
  17. </view>
  18. </view>
  19. </view>
  20. <view class="function-total">
  21. <button class="lf-row-center lf-flex-column menu-btn" @click="call">
  22. <view><text class="lf-iconfont icon-pinglun shop-function"></text></view>
  23. <view class="lf-font-24 lf-color-33">客服</view>
  24. </button>
  25. <button class="lf-row-center lf-flex-column menu-btn" @click="switchCollect">
  26. <view>
  27. <text class="lf-iconfont icon-shoucang2 shop-function lf-color-price" v-if="is_collect"></text>
  28. <text class="lf-iconfont icon-shoucang11 shop-function" v-else></text>
  29. </view>
  30. <view class="lf-font-24 lf-color-333">{{ is_collect ? '已收藏' : '收藏' }}</view>
  31. </button>
  32. <button class="lf-row-center lf-flex-column menu-btn" open-type="share">
  33. <view><text class="lf-iconfont icon-fenxiang shop-function"></text></view>
  34. <view class="lf-font-24 lf-color-333">分享</view>
  35. </button>
  36. </view>
  37. </view>
  38. <view v-if="title_tab.length">
  39. <u-tabs :list="title_tab" active-color="#15716E" inactive-color='#777777' :is-scroll="true" :current="title_current" @change="titletabChange"></u-tabs>
  40. </view>
  41. <!-- 推荐 -->
  42. <view v-if="title_current==0">
  43. <view class="lf-row-between lf-p-l-32 lf-p-t-40 lf-p-r-32">
  44. <view class="lf-font-32 lf-color-black lf-font-bold">在售商品</view>
  45. <view class="lf-font-24 lf-color-555" @click="titletabChange(1)">
  46. <text>查看全部</text>
  47. <text class="lf-iconfont icon-xiangyou lf-font-24 lf-m-l-10"></text>
  48. </view>
  49. </view>
  50. <view class="recommend-box">
  51. <view class="goods-rom" v-for="(item,index) of detail.goods" :key="index" v-if="detail.goods.length" @click="$url('/pages/shop/goodsdetail?id='+item.id)">
  52. <!-- <u-lazy-load threshold="-450" border-radius="8px 8px 0 0" :image="item.img" :index="index">
  53. </u-lazy-load> -->
  54. <image :src="item.img" mode="aspectFill" style="width: 332rpx;height: 332rpx;border-radius: 20rpx 20rpx 0 0;"></image>
  55. <view class="lf-p-20">
  56. <view class="list-title">
  57. {{item.name}}
  58. </view>
  59. <view class="list-price">
  60. <!-- <text>{{item.price}}</text> -->
  61. <lf-price :price="item.min_price"></lf-price>
  62. <text class="lf-m-l-20 lf-font-24 lf-color-666 lf-line-through">{{item.min_market_price}}</text>
  63. </view>
  64. </view>
  65. </view>
  66. <lf-nocontent src="/static/images/empty.png" v-else></lf-nocontent>
  67. </view>
  68. <view class="introduct">
  69. <text class="lf-font-32 lf-color-black">品牌故事</text>
  70. <view class="lf-font-28 lf-color-333 lf-m-t-20">{{ detail.story }}</view>
  71. </view>
  72. </view>
  73. <view class="lf-p-t-30 lf-p-b-30" v-else>
  74. <view class="lf-m-b-30 lf-flex lf-w-100">
  75. <u-icon name="search" class="search-icon"></u-icon>
  76. <input class="rom-search" v-model="search_val" @confirm="search" type="text" placeholder="请输入商品名称" />
  77. </view>
  78. <view class="special_tab" style="position: relative;">
  79. <u-tabs :list="tab_list" active-color="#15716E" inactive-color='#777777' :is-scroll="true" :current="current" @change="tabChange"></u-tabs>
  80. <view style="position: absolute;right: 30rpx;top: 20rpx;display: flex;flex-direction: column;z-index: 9999;" @click="changeSort()">
  81. <u-icon name="arrow-up" style="font-size: 20rpx;" :class="sort=='desc'?'':'lf-special-green'"></u-icon>
  82. <u-icon name="arrow-down" style="font-size: 20rpx;" :class="sort=='desc'?'lf-special-green':''"></u-icon>
  83. </view>
  84. </view>
  85. <swiper :style="{height: '800rpx', width: '750rpx'}" :current="current" @change="swiperChange">
  86. <swiper-item v-for="(tabItem, tabIndex) in tab_list" :key="tabIndex">
  87. <scroll-view class="com" :scroll-y="true" :refresher-enabled="true" :refresher-triggered="tabItem.isRefresher" @scrolltolower="onScrolltolower" @refresherrefresh="onRefresherrefresh">
  88. <shop-list :list="tabItem.list"></shop-list>
  89. <view class="loading-more lf-m-b-10">
  90. <text :class="{'loading-more-text': tabItem.loadingClass}" v-if="tabItem.list.length">{{tabItem.loadingText}}</text>
  91. <lf-nocontent src="/static/images/empty.png" v-else></lf-nocontent>
  92. <!-- <view>
  93. {{tabItem.list.length}}
  94. </view> -->
  95. </view>
  96. </scroll-view>
  97. </swiper-item>
  98. </swiper>
  99. </view>
  100. </view>
  101. </template>
  102. <script>
  103. import shopList from '@/components/shopList/shopList.vue';
  104. export default {
  105. components: {
  106. shopList
  107. },
  108. data() {
  109. return {
  110. title_tab: [
  111. {name:'推荐'},
  112. {name:'商品'}
  113. ],
  114. tab_list: [],
  115. current: 0,
  116. title_current:0,
  117. brand_id: 0,
  118. detail: {},
  119. search_val: '',
  120. is_collect: false,
  121. sort: 'desc'
  122. }
  123. },
  124. onLoad(options){
  125. this.brand_id = options.id;
  126. this.getShopDetail();
  127. },
  128. methods: {
  129. changeSort(sort) {
  130. if(this.sort == 'desc') {
  131. this.sort = 'asc';
  132. }else {
  133. this.sort = 'desc';
  134. }
  135. let tab_item = this.tab_list[this.current];
  136. tab_item.list = [];
  137. this.getData();
  138. },
  139. // 切换商品收藏
  140. switchCollect(){
  141. let userInfo = this.$cookieStorage.get('user_token') || {};
  142. if(!userInfo){
  143. this.$url('/pages/login/index');
  144. return;
  145. }
  146. this.addCollcet()
  147. },
  148. addCollcet() {
  149. this.$http.post({
  150. api: 'api/collect/create',
  151. data: {
  152. type:'jc_brand',
  153. collect_id: this.brand_id,
  154. },
  155. header: {
  156. Authorization: this.$cookieStorage.get('user_token')
  157. }
  158. }).then(res => {
  159. this.$msg(res.data.data);
  160. this.getShopDetail();
  161. }).catch(err => {
  162. console.log("====", err);
  163. })
  164. },
  165. getShopDetail(){
  166. this.$http.get({
  167. api: 'api/brand/detail',
  168. data: {
  169. brand_id: this.brand_id
  170. },
  171. header: {
  172. Authorization: this.$cookieStorage.get('user_token')
  173. }
  174. }).then(res => {
  175. this.detail = res.data.data;
  176. this.is_collect = Boolean(res.data.data.is_collect) || false;
  177. })
  178. },
  179. tabChange(index){
  180. this.current = index;
  181. this.clearTabItem();
  182. this.getData();
  183. },
  184. titletabChange(index){
  185. this.title_current = index;
  186. if(this.tab_list.length <= 0){
  187. this.initGoodsTabs();
  188. this.getData();
  189. }
  190. },
  191. call(){
  192. uni.makePhoneCall({
  193. phoneNumber: String(this.detail.tel)
  194. })
  195. },
  196. initGoodsTabs(){
  197. let _public = {
  198. isRefresher: false,
  199. loadingClass: true,
  200. loadingText: '正在加载中',
  201. page: 1,
  202. isPage: true
  203. };
  204. this.tab_list = [{
  205. name: '综合',
  206. list: [],
  207. ..._public
  208. },{
  209. name: '销量',
  210. list: [],
  211. ..._public
  212. },{
  213. name: '上新',
  214. list: [],
  215. ..._public
  216. },{
  217. name: '价格',
  218. list: [],
  219. ..._public
  220. }]
  221. },
  222. getData() {
  223. let par = {
  224. brand_id: this.brand_id,
  225. sort: this.sort
  226. }
  227. let orderBy = ['','sale_count','updated_at','sell_price'][this.current];
  228. if(orderBy){
  229. par.orderBy = orderBy;
  230. }
  231. if(this.search_val){
  232. par.keyword = this.search_val;
  233. }
  234. this.$http.get({
  235. api: 'api/store/list',
  236. data: par
  237. }).then(res => {
  238. console.log("getDat", res);
  239. let tab_item = this.tab_list[this.current];
  240. let isPage = false; // TODO 默认没有下一页
  241. tab_item.isPage = isPage;
  242. if(!isPage){
  243. tab_item.loadingClass = false;
  244. tab_item.loadingText = '没有更多数据啦~';
  245. }
  246. tab_item.isRefresher = false;
  247. let data_list = res.data.data || [];
  248. let list = data_list.map(item => {
  249. return {
  250. id: item.id,
  251. original_price: item.market_price,
  252. picture: item.img,
  253. pictures: [item.img],
  254. price: item.min_price,
  255. product_id: item.brand_id,
  256. sale: item.sale_count,
  257. title: item.name
  258. }
  259. })
  260. if(tab_item.page == 1){
  261. console.log('当前页数',tab_item.page);
  262. tab_item.list = list;
  263. console.log(tab_item.list)
  264. }else{
  265. tab_item.list.push(...list);
  266. }
  267. })
  268. },
  269. search(event){
  270. this.clearTabItem();
  271. this.getData();
  272. },
  273. // 滑块下标值变化
  274. swiperChange(event){
  275. this.current = event.detail.current;
  276. if(event.detail.source == '') return; // 如果是被动出发,没有事件类型则不做处理
  277. this.clearTabItem();
  278. this.getData();
  279. },
  280. // 页面触底,加载下一页
  281. onScrolltolower(){
  282. let tab_item = this.tab_list[this.current];
  283. if(tab_item.isPage){
  284. tab_item.page = tab_item.page + 1;
  285. this.getData();
  286. }
  287. },
  288. // scroll-view 下拉刷新
  289. onRefresherrefresh(){
  290. this.$u.throttle(() => {
  291. this.clearTabItem();
  292. this.getData();
  293. }, 200);
  294. },
  295. clearTabItem(){
  296. let tab_item = this.tab_list[this.current];
  297. tab_item.page = 1;
  298. tab_item.isPage = true;
  299. tab_item.isRefresher = true;
  300. tab_item.loadingClass = true;
  301. tab_item.loadingText = '正在加载中';
  302. tab_item.list = [];
  303. this.$set(this.tab_list, this.current, tab_item);
  304. }
  305. },
  306. onShareAppMessage(){
  307. return {
  308. title: `给你分享一家店铺[${this.detail.name}],我觉得很不错哦~`,
  309. path: '/pages/route/index?route=shop&id='+ this.brand_id
  310. }
  311. }
  312. }
  313. </script>
  314. <style>
  315. page {
  316. background-color: white;
  317. }
  318. </style>
  319. <style lang="scss" scoped>
  320. .lf-special-green {
  321. color: #15716E!important;
  322. }
  323. .search-icon {
  324. position: relative;
  325. bottom: 0;
  326. left: 54rpx;
  327. }
  328. /deep/.input-placeholder{
  329. color: #777;
  330. font-size: 28rpx;
  331. }
  332. .rom-search {
  333. width: 686rpx;
  334. height: 60rpx;
  335. background: #F4F8F8;
  336. border-radius: 30rpx;
  337. padding-left: 74rpx;
  338. font-size: 28rpx;
  339. }
  340. .recommend-box{
  341. display: flex;
  342. justify-content: space-between;
  343. padding: 30rpx 32rpx;
  344. flex-wrap: wrap;
  345. }
  346. .goods-rom {
  347. border-radius: 20rpx;
  348. width: 333rpx;
  349. height: max-content;
  350. background-color: white;
  351. box-shadow: 0px 2rpx 8rpx 1rpx rgba(0, 0, 0, 0.1);
  352. &:nth-child(2n) {
  353. margin-right: 0;
  354. }
  355. &:nth-child(n + 3) {
  356. margin-top: 20rpx;
  357. }
  358. }
  359. .introduct {
  360. padding: 30rpx 32rpx;
  361. }
  362. .com{
  363. width: 100%;
  364. height: 100%;
  365. box-sizing: border-box;
  366. // padding: 0rpx 28rpx;
  367. }
  368. .shop-head {
  369. width: 100%;
  370. height: 400rpx;
  371. position: relative;
  372. }
  373. .shop-flex {
  374. display: flex;
  375. padding: 30rpx;
  376. }
  377. .shop-title {
  378. width: 686rpx;
  379. height: 274rpx;
  380. border-radius: 20rpx;
  381. background-color: white;
  382. box-shadow: 0rpx 2rpx 8rpx 1rpx rgba(0, 0, 0, 0.1);
  383. margin: 0 auto;
  384. position: relative;
  385. top: -32rpx;
  386. }
  387. .shop-img {
  388. width: 90rpx;
  389. height: 90rpx;
  390. margin-right: 15rpx;
  391. border-radius: 5rpx;
  392. }
  393. .shop-function {
  394. width: 80rpx;
  395. height: 80rpx;
  396. border-radius: 50%;
  397. font-size: 40rpx;
  398. }
  399. .function-total {
  400. display: flex;
  401. justify-content: space-between;
  402. padding: 0 65rpx 0 65rpx;
  403. }
  404. .menu-btn{
  405. margin: 0;
  406. padding: 0;
  407. background-color: transparent;
  408. line-height: 1.5;
  409. }
  410. /deep/.u-scroll-box {
  411. display: flex;
  412. justify-content: center;
  413. align-items: center;
  414. border-bottom: 1rpx solid rgba(0, 0, 0, 0.1);
  415. }
  416. /deep/.u-scroll-box .u-tab-bar {
  417. background-color: #15716E!important;
  418. width: 80rpx!important;
  419. position: absolute;
  420. left: 0;
  421. bottom: -12rpx;
  422. }
  423. /deep/.special_tab .u-tabs .u-scroll-box .u-tab-bar {
  424. background-color: #15716E!important;
  425. width: 56rpx!important;
  426. position: absolute;
  427. height: 5rpx!important;
  428. left: 8rpx;
  429. bottom: -4rpx;
  430. }
  431. /deep/ .u-tab-item {
  432. font-size: 28rpx!important;
  433. }
  434. //价格筛选伪类
  435. // /deep/.special_tab .u-tab-item:nth-child(4n) ::after{
  436. // font-size: 48rpx!important;
  437. // content: '';
  438. // color: red;
  439. // }
  440. // loading加载
  441. .loading-more {
  442. align-items: center;
  443. justify-content: center;
  444. padding-top: 10px;
  445. padding-bottom: 10px;
  446. text-align: center;
  447. font-size: 28rpx;
  448. color: #999;
  449. }
  450. .loading-more-text::before {
  451. content: '';
  452. width: 20px;
  453. height: 20px;
  454. display: inline-block;
  455. vertical-align: middle;
  456. -webkit-animation: weuiLoading 1s steps(12, end) infinite;
  457. animation: weuiLoading 1s steps(12, end) infinite;
  458. background-repeat: no-repeat;
  459. background-image: url("data:image/svg+xml;charset=utf8, %3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 100 100'%3E%3Cpath fill='none' d='M0 0h100v100H0z'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='%23E9E9E9' rx='5' ry='5' transform='translate(0 -30)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='%23989697' rx='5' ry='5' transform='rotate(30 105.98 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='%239B999A' rx='5' ry='5' transform='rotate(60 75.98 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='%23A3A1A2' rx='5' ry='5' transform='rotate(90 65 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='%23ABA9AA' rx='5' ry='5' transform='rotate(120 58.66 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='%23B2B2B2' rx='5' ry='5' transform='rotate(150 54.02 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='%23BAB8B9' rx='5' ry='5' transform='rotate(180 50 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='%23C2C0C1' rx='5' ry='5' transform='rotate(-150 45.98 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='%23CBCBCB' rx='5' ry='5' transform='rotate(-120 41.34 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='%23D2D2D2' rx='5' ry='5' transform='rotate(-90 35 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='%23DADADA' rx='5' ry='5' transform='rotate(-60 24.02 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='%23E2E2E2' rx='5' ry='5' transform='rotate(-30 -5.98 65)'/%3E%3C/svg%3E");
  460. background-size: 100%;
  461. }
  462. @keyframes weuiLoading {
  463. 0% {
  464. transform: rotate3d(0, 0, 1, 0deg);
  465. }
  466. 100% {
  467. transform: rotate3d(0, 0, 1, 360deg);
  468. }
  469. }
  470. .list-warter {
  471. border-radius: 20rpx;
  472. margin: 10px 5px;
  473. margin-top: 0px;
  474. background-color: #ffffff;
  475. // padding: 8px;
  476. position: relative;
  477. overflow: hidden;
  478. box-shadow: 0rpx 2rpx 8rpx 1rpx rgba(0, 0, 0, 0.1);
  479. }
  480. .u-close {
  481. position: absolute;
  482. top: 32rpx;
  483. right: 32rpx;
  484. }
  485. .list-image {
  486. width: 100%;
  487. border-radius: 4px;
  488. }
  489. .list-title {
  490. font-size: 28rpx;
  491. font-weight: bold;
  492. color: $u-main-color;
  493. }
  494. .list-label{
  495. position: absolute;
  496. bottom: 0;
  497. right: 0;
  498. background-color: rgba(0,0,0,0.5);
  499. width: 140rpx;
  500. height: 48rpx;
  501. border-radius: 20rpx 0rpx 0rpx 0rpx;
  502. font-size: 22rpx;
  503. color: #FFFFFF;
  504. line-height: 48rpx;
  505. text-align: center;
  506. }
  507. .list-tag {
  508. display: flex;
  509. margin-top: 5px;
  510. }
  511. .list-tag-owner {
  512. background-color: $u-type-error;
  513. color: #FFFFFF;
  514. display: flex;
  515. align-items: center;
  516. padding: 4rpx 14rpx;
  517. border-radius: 50rpx;
  518. font-size: 20rpx;
  519. line-height: 1;
  520. }
  521. .list-tag-text {
  522. border: 1px solid $u-type-primary;
  523. color: $u-type-primary;
  524. margin-left: 10px;
  525. border-radius: 50rpx;
  526. line-height: 1;
  527. padding: 4rpx 14rpx;
  528. display: flex;
  529. align-items: center;
  530. border-radius: 50rpx;
  531. font-size: 20rpx;
  532. }
  533. .list-price {
  534. font-size: 30rpx;
  535. color: $u-type-error;
  536. margin-top: 5px;
  537. display: flex;
  538. align-items: center;
  539. }
  540. </style>