index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857
  1. <template>
  2. <mobile-frame>
  3. <view class="main">
  4. <view class="one">
  5. <view class="one_1" v-if="barActive=='0'">
  6. <scroll-view scroll-y="true" class="scroll-view">
  7. <view class="one_1_1">
  8. <image class="image" :src="info.logo&&info.logo.length>0?info.logo[0].url:''" mode="">
  9. </image>
  10. </view>
  11. <view class="one_1_2">
  12. <view class="pubu">
  13. <view class="list" v-for="(item,index) in shoplist" :key="index">
  14. <image class="image" :src="item.file&&item.file.length>0?item.file[0].url:''"
  15. mode=""></image>
  16. <view class="name">
  17. {{item.name}}
  18. </view>
  19. <view class="other">
  20. <view class="money">
  21. <text>¥</text>
  22. <text>{{item.sell_money}}</text>
  23. </view>
  24. <view class="btn">
  25. <button type="default" size="mini" @click="toBuy(item)">购买</button>
  26. </view>
  27. </view>
  28. </view>
  29. </view>
  30. </view>
  31. </scroll-view>
  32. </view>
  33. <view class="one_3" v-else-if="barActive=='1'">
  34. <view class="first">
  35. <input type="text" v-model="searchInfo.name" @blur="toInput" placeholder="搜索商品">
  36. </view>
  37. <view class="second">
  38. <scroll-view scroll-y="true" class="scroll-view" @scrolltolower="toPage" @scroll="toScroll">
  39. <view class="list-scroll-view">
  40. <view class="second_1">
  41. <view :class="['list',condActive==index?'activeList':'']"
  42. v-for="(item,index) in condList" :key="index" @tap="toCond(index,item)">
  43. <view class="name">
  44. {{item.name}}
  45. </view>
  46. <view class="icon">
  47. <view class="icon_1">
  48. <text :class="['iconfont',item.shangActive]"
  49. v-if="condActive==index&&shang=='1'"></text>
  50. <text :class="['iconfont',item.shang]" v-else></text>
  51. </view>
  52. <view class="icon_1">
  53. <text :class="['iconfont', item.xiaActive]"
  54. v-if="condActive==index&&xia=='-1'"></text>
  55. <text :class="['iconfont', item.xia]" v-else></text>
  56. </view>
  57. </view>
  58. </view>
  59. </view>
  60. <view class="second_2">
  61. <view class="pubu">
  62. <view class="list" v-for="(item,index) in list" :key="index">
  63. <image class="image"
  64. :src="item.file&&item.file.length>0?item.file[0].url:''" mode="">
  65. </image>
  66. <view class="sale" v-if="item.is_sale==true">
  67. <text>已售尽</text>
  68. </view>
  69. <view class="name">
  70. {{item.name}}
  71. </view>
  72. <view class="other">
  73. <view class="money">
  74. <text>¥</text>
  75. <text>{{item.sell_money}}</text>
  76. </view>
  77. <view class="btn">
  78. <button type="default" size="mini" @click="toBuy(item)">购买</button>
  79. </view>
  80. </view>
  81. </view>
  82. </view>
  83. </view>
  84. <view class="is_bottom" v-if="is_bottom">
  85. <text>我们也是有底线的!</text>
  86. </view>
  87. </view>
  88. </scroll-view>
  89. </view>
  90. </view>
  91. <view class="one_4" v-else-if="barActive=='2'">
  92. <view class="first">
  93. <image class="image" :src="info.logo&&info.logo.length>0?info.logo[0].url:''" mode=""></image>
  94. <view class="name">{{info.name}}</view>
  95. </view>
  96. <view class="second">
  97. <view class="second_1">
  98. <view class="grade">
  99. <view>{{info.goods_score||5}}</view>
  100. 商品
  101. </view>
  102. <view class="grade">
  103. <view>{{info.send_score||5}}</view>
  104. 发货
  105. </view>
  106. <view class="grade">
  107. <view>{{info.service_score||5}}</view>
  108. 服务
  109. </view>
  110. </view>
  111. <view class="qrcode_1">
  112. <view class="qrcode_1_1">
  113. <uqrcode ref="uqrcode" canvas-id="qrcode" :value="uqrcodeInfo" :options="{ margin:10 }">
  114. </uqrcode>
  115. <view class="txt">
  116. 店铺二维码
  117. </view>
  118. </view>
  119. </view>
  120. </view>
  121. <view class="collect">
  122. <text v-if="!collection" @click="toCollect" class="iconfont icon-yduishoucangkongxin"></text>
  123. <text v-else @click="toCollect" class="iconfont icon-yduishoucangshixin"></text>
  124. </view>
  125. </view>
  126. </view>
  127. <view class="two">
  128. <view class="list" v-for="(item,index) in barList" :key="index" @tap="barChange(index,item)">
  129. <view class="icon">
  130. <text :class="['iconfont',barActive==index?item.acticon:item.icon]"></text>
  131. </view>
  132. <view :class="['name',barActive==index?'activename':'']">
  133. {{item.name}}
  134. </view>
  135. </view>
  136. </view>
  137. </view>
  138. </mobile-frame>
  139. </template>
  140. <script>
  141. export default {
  142. data() {
  143. return {
  144. user: {},
  145. id: '',
  146. barActive: '0',
  147. barList: [ //底部菜单
  148. {
  149. icon: 'icon-shangdian',
  150. acticon: "icon-shangdian-copy",
  151. name: '微店首页'
  152. },
  153. {
  154. icon: 'icon-shangpinfenlei',
  155. acticon: "icon-shangpinfenlei-copy",
  156. name: '全部商品'
  157. },
  158. {
  159. icon: 'icon-qiyejianjie',
  160. acticon: "icon-qiyejianjie-copy",
  161. name: '店铺简介'
  162. }
  163. ],
  164. // 店铺信息
  165. info: {},
  166. // 店铺部分商品
  167. shoplist: [],
  168. // 收藏
  169. collection: false,
  170. // 全部商品
  171. searchInfo: {},
  172. list: [],
  173. total: 0,
  174. page: 0,
  175. skip: 0,
  176. limit: 5,
  177. condActive: 0,
  178. shang: '',
  179. xia: '',
  180. condList: [ // 筛选
  181. {
  182. name: '默认',
  183. },
  184. {
  185. name: '销量',
  186. shang: 'icon-shangjiantou',
  187. shangActive: 'icon-shangjiantou-copy',
  188. xia: 'icon-xiajiantou',
  189. xiaActive: 'icon-xiajiantou-copy'
  190. },
  191. {
  192. name: '价格',
  193. shang: 'icon-shangjiantou',
  194. shangActive: 'icon-shangjiantou-copy',
  195. xia: 'icon-xiajiantou',
  196. xiaActive: 'icon-xiajiantou-copy'
  197. },
  198. {
  199. name: '浏览量',
  200. shang: 'icon-shangjiantou',
  201. shangActive: 'icon-shangjiantou-copy',
  202. xia: 'icon-xiajiantou',
  203. xiaActive: 'icon-xiajiantou-copy'
  204. }
  205. ],
  206. // 数据是否触底
  207. is_bottom: false,
  208. scrollTop: 0,
  209. // 二维码内容
  210. uqrcodeInfo: ''
  211. };
  212. },
  213. onLoad: async function(e) {
  214. const that = this;
  215. that.$set(that, `id`, e.id || '');
  216. await that.watchLogin();
  217. await that.search();
  218. await that.searchOther();
  219. },
  220. methods: {
  221. // 监听用户是否登录
  222. watchLogin() {
  223. const that = this;
  224. uni.getStorage({
  225. key: 'token',
  226. success: function(res) {
  227. let user = that.$jwt(res.data);
  228. that.$set(that, `user`, user);
  229. },
  230. fail: function(err) {}
  231. })
  232. },
  233. // 查询信息
  234. async search() {
  235. const that = this;
  236. if (that.id) {
  237. // 查询店铺信息
  238. const res = await that.$api(`/shop/${that.id}`, 'GET');
  239. if (res.errcode == '0') that.$set(that, `info`, res.data);
  240. let arr = await that.$api(`/storeShop/check`, `GET`, {
  241. customer: that.user._id,
  242. shop: that.id
  243. });
  244. if (arr.errcode == '0') {
  245. that.$set(that, `collection`, arr.data)
  246. }
  247. // 查询店铺商品
  248. that.searchShopMarket();
  249. // 查询全部商品
  250. that.searchAll();
  251. }
  252. },
  253. // 查询店铺商品
  254. async searchShopMarket() {
  255. const that = this;
  256. const res = await that.$api(`/viewGoods/indexGoodsList`, 'GET', {
  257. shop: that.id,
  258. skip: 0,
  259. limit: 20
  260. })
  261. if (res.errcode == '0') that.$set(that, `shoplist`, res.data);
  262. },
  263. // 查询全部产品
  264. async searchAll() {
  265. const that = this;
  266. let info = {
  267. shop: that.id,
  268. skip: that.skip,
  269. limit: that.limit
  270. }
  271. const res = await that.$api(`/viewGoods/indexGoodsList`, `GET`, {
  272. ...info,
  273. ...that.searchInfo
  274. })
  275. if (res.errcode == '0') {
  276. let list = [...that.list, ...res.data];
  277. that.$set(that, `list`, list)
  278. that.$set(that, `total`, res.total)
  279. } else {
  280. uni.showToast({
  281. title: res.errmsg,
  282. });
  283. }
  284. },
  285. // 创建二维码
  286. createQrcode() {
  287. const that = this;
  288. if (that.id) {
  289. const url = `${that.$config.serverUrl}/shopinfo?id=${that.id}`;
  290. that.$set(that, `uqrcodeInfo`, url);
  291. that.$refs.uqrcode.make({
  292. enableDelay: true
  293. })
  294. .then(res => {
  295. console.log(res);
  296. })
  297. .finally(() => {
  298. console.log('2');
  299. })
  300. }
  301. },
  302. // 购买
  303. toBuy(item) {
  304. if (item && item._id) {
  305. uni.navigateTo({
  306. url: `/pagesHome/order/detail?id=${item._id}`
  307. })
  308. }
  309. },
  310. // 全部产品-分页
  311. async toPage() {
  312. const that = this;
  313. let list = that.list;
  314. let limit = that.limit;
  315. if (that.total > list.length) {
  316. uni.showLoading({
  317. title: '加载中',
  318. mask: true
  319. })
  320. let page = that.page + 1;
  321. that.$set(that, `page`, page)
  322. let skip = page * limit;
  323. that.$set(that, `skip`, skip)
  324. that.searchAll();
  325. uni.hideLoading();
  326. } else that.$set(that, `is_bottom`, true)
  327. },
  328. toScroll(e) {
  329. const that = this;
  330. let up = that.scrollTop;
  331. that.$set(that, `scrollTop`, e.detail.scrollTop);
  332. let num = Math.sign(up - e.detail.scrollTop);
  333. if (num == 1) that.$set(that, `is_bottom`, false);
  334. },
  335. // 输入框
  336. toInput(e) {
  337. const that = this;
  338. that.$set(that.searchInfo, `name`, e.detail.value);
  339. that.clearPage();
  340. that.searchAll();
  341. },
  342. // 筛选
  343. toCond(index, e) {
  344. const that = this;
  345. let condActive = that.condActive;
  346. that.$set(that, `condActive`, index);
  347. if (condActive != index && that.xia == '') {
  348. that.$set(that, `shang`, '0');
  349. that.$set(that, `xia`, '-1');
  350. } else if (condActive == index && that.xia == '-1') {
  351. that.$set(that, `shang`, '1');
  352. that.$set(that, `xia`, '0');
  353. } else if (condActive == index && that.shang == '1') {
  354. that.$set(that, `shang`, '0');
  355. that.$set(that, `xia`, '-1');
  356. } else if (condActive = index && that.shang == '1') {
  357. that.$set(that, `shang`, '0');
  358. that.$set(that, `xia`, '-1');
  359. }
  360. let key = '';
  361. let value;
  362. if (index != 0) {
  363. value = that.shang == '0' ? that.xia : that.shang;
  364. }
  365. if (index == 1) {
  366. key = 'sell_num';
  367. } else if (index == 2) {
  368. key = 'sell_money';
  369. } else if (index == 3) {
  370. key = 'view_num';
  371. }
  372. that.$set(that.searchInfo, `key`, key);
  373. that.$set(that.searchInfo, `value`, value);
  374. that.clearPage();
  375. that.searchAll();
  376. },
  377. // 查询其他信息
  378. async searchOther() {
  379. const that = this;
  380. let user = that.user;
  381. let shop = that.info;
  382. if (user && user._id && shop && shop._id) {
  383. // 商铺是否收藏
  384. let arr = await that.$api(`/storeShop/check`, `GET`, {
  385. customer: user._id,
  386. shop: shop._id
  387. });
  388. if (arr.errcode == '0') {
  389. that.$set(that, `collection`, arr.data)
  390. }
  391. }
  392. },
  393. // 收藏
  394. async toCollect() {
  395. const that = this;
  396. let user = that.user;
  397. let shop = that.info;
  398. if (user && user._id && shop && shop._id) {
  399. let res = await that.$api(`/storeShop`, `POST`, {
  400. customer: user._id,
  401. shop: shop._id
  402. });
  403. if (res.errcode == '0') {
  404. uni.showToast({
  405. title: res.data.msg,
  406. icon: 'none'
  407. })
  408. that.$set(that, `collection`, res.data.result)
  409. }
  410. } else {
  411. uni.showToast({
  412. title: '缺少必要信息,无法收藏',
  413. icon: 'none'
  414. })
  415. }
  416. },
  417. // 选择底部菜单
  418. barChange(index, item) {
  419. const that = this;
  420. that.$set(that, `barActive`, index);
  421. uni.setNavigationBarTitle({
  422. title: item.name
  423. });
  424. // 店铺简介时,绘制二维码
  425. if (index == '2') that.createQrcode();
  426. },
  427. // 清空列表
  428. clearPage() {
  429. const that = this;
  430. that.$set(that, `list`, [])
  431. that.$set(that, `skip`, 0)
  432. that.$set(that, `limit`, 5)
  433. that.$set(that, `page`, 0)
  434. }
  435. }
  436. }
  437. </script>
  438. <style lang="scss">
  439. .main {
  440. display: flex;
  441. flex-direction: column;
  442. width: 100vw;
  443. height: 100vh;
  444. .one {
  445. position: relative;
  446. flex-grow: 1;
  447. .one_1 {
  448. height: 92vh;
  449. background-color: var(--fFB1Color);
  450. .one_1_1 {
  451. padding: 2vw;
  452. .image {
  453. width: 100%;
  454. height: 50vw;
  455. }
  456. }
  457. .one_1_2 {
  458. padding: 0 2vw 2vw 2vw;
  459. .pubu {
  460. column-count: 2;
  461. column-gap: 2vw;
  462. .list {
  463. background: #fff;
  464. padding: 2vw;
  465. border-radius: 5px;
  466. margin: 0 0 2vw 0;
  467. break-inside: avoid;
  468. .image {
  469. width: 100%;
  470. height: 50vw;
  471. }
  472. .name {
  473. font-size: var(--font15Size);
  474. margin: 0 0 2vw 0;
  475. }
  476. .other {
  477. display: flex;
  478. flex-direction: row;
  479. justify-content: space-between;
  480. .money {
  481. color: var(--ff0Color);
  482. text:nth-child(1) {
  483. font-size: var(--font12Size);
  484. }
  485. }
  486. .btn {
  487. button {
  488. border-radius: 25px;
  489. color: var(--fffColor);
  490. background-color: var(--ff0Color);
  491. font-size: var(--font12Size);
  492. }
  493. }
  494. }
  495. }
  496. }
  497. }
  498. }
  499. .one_2 {
  500. height: 91vh;
  501. display: flex;
  502. flex-direction: row;
  503. padding: 2vw;
  504. .first_1 {
  505. position: relative;
  506. width: 25vw;
  507. background-color: #fafafa;
  508. display: flex;
  509. flex-direction: column;
  510. .list {
  511. text-align: center;
  512. padding: 2.5vw 0;
  513. border-bottom: 1px solid var(--f1Color);
  514. text {
  515. font-size: var(--font14Size);
  516. }
  517. }
  518. .listActive {
  519. background-color: var(--fffColor);
  520. }
  521. }
  522. .first_2 {
  523. padding: 2vw;
  524. flex-grow: 1;
  525. position: relative;
  526. display: flex;
  527. flex-direction: column;
  528. .list {
  529. margin: 0 0 2vw 0;
  530. padding: 2vw;
  531. .title {
  532. font-size: var(--font16Size);
  533. margin: 0 0 2vw 0;
  534. }
  535. .market {
  536. display: flex;
  537. flex-direction: row;
  538. flex-wrap: wrap;
  539. .marketList {
  540. text-align: center;
  541. margin: 0 2vw 2vw 0;
  542. width: 22vw;
  543. .image {
  544. width: 100%;
  545. height: 15vw;
  546. }
  547. .name {
  548. font-size: var(--font14Size);
  549. }
  550. }
  551. .marketList:nth-child(3n) {
  552. margin: 0 0 2vw 0;
  553. }
  554. }
  555. }
  556. }
  557. }
  558. .one_3 {
  559. display: flex;
  560. flex-direction: column;
  561. width: 100vw;
  562. height: 92vh;
  563. .first {
  564. border-bottom: 1px solid var(--f85Color);
  565. padding: 2vw;
  566. input {
  567. padding: 2vw;
  568. background-color: var(--f1Color);
  569. font-size: var(--font14Size);
  570. border-radius: 5px;
  571. }
  572. }
  573. .second {
  574. position: relative;
  575. flex-grow: 1;
  576. .second_1 {
  577. width: 96vw;
  578. background-color: var(--fffColor);
  579. padding: 2vw;
  580. display: flex;
  581. flex-direction: row;
  582. justify-content: space-around;
  583. .list {
  584. display: flex;
  585. flex-direction: row;
  586. .icon {
  587. position: relative;
  588. top: -5px;
  589. left: 2px;
  590. .icon_1 {
  591. height: 10px;
  592. .iconfont {
  593. font-size: 12px;
  594. }
  595. }
  596. }
  597. }
  598. .activeList {
  599. .name {
  600. color: #ff0000;
  601. }
  602. }
  603. }
  604. .second_2 {
  605. padding: 2vw;
  606. background-color: var(--f1Color);
  607. .pubu {
  608. column-count: 2;
  609. column-gap: 2vw;
  610. .list {
  611. position: relative;
  612. margin: 0 0 2vw 0;
  613. padding: 2vw;
  614. border-radius: 10px;
  615. background-color: var(--fffColor);
  616. break-inside: avoid;
  617. .image {
  618. width: 100%;
  619. height: 40vw;
  620. }
  621. .sale {
  622. position: absolute;
  623. top: 18vw;
  624. text-align: center;
  625. width: 43vw;
  626. text {
  627. background-color: #0000005f;
  628. border-radius: 90px;
  629. display: inline-block;
  630. width: 15vw;
  631. height: 15vw;
  632. color: var(--fffColor);
  633. text-align: center;
  634. line-height: 15vw;
  635. }
  636. }
  637. .name {
  638. font-size: var(--font16Size);
  639. margin: 0 0 1vw 0;
  640. }
  641. .other {
  642. display: flex;
  643. flex-direction: row;
  644. justify-content: space-between;
  645. .money {
  646. font-size: var(--font14Size);
  647. color: var(--ff0Color);
  648. text:nth-child(1) {
  649. font-size: var(--font12Size);
  650. }
  651. }
  652. .other_1 {
  653. flex-grow: 1;
  654. margin: 0 0 0 2vw;
  655. font-size: var(--font12Size);
  656. color: var(--f85Color);
  657. }
  658. .btn {
  659. button {
  660. border-radius: 25px;
  661. color: var(--fffColor);
  662. background-color: var(--ff0Color);
  663. font-size: var(--font12Size);
  664. }
  665. }
  666. }
  667. }
  668. }
  669. }
  670. }
  671. }
  672. .one_4 {
  673. .first {
  674. display: flex;
  675. flex-direction: column;
  676. align-items: center;
  677. background-color: var(--fFB1Color);
  678. border-bottom-right-radius: 10vw;
  679. border-bottom-left-radius: 10vw;
  680. .image {
  681. width: 20vw;
  682. height: 20vw;
  683. border-radius: 20vw;
  684. }
  685. .name {
  686. margin: 2vw 0;
  687. font-size: var(--font16Szie);
  688. font-weight: bold;
  689. color: var(--mainColor);
  690. }
  691. }
  692. .second {
  693. margin: 2vw 0;
  694. .second_1 {
  695. display: flex;
  696. justify-content: space-evenly;
  697. .grade {
  698. display: flex;
  699. flex-direction: column;
  700. align-items: center;
  701. color: var(--f85Color);
  702. font-size: var(--font13Size);
  703. view {
  704. margin: 1vw 0 0 0;
  705. color: var(--ff0Color);
  706. }
  707. }
  708. }
  709. .qrcode_1 {
  710. display: flex;
  711. justify-content: center;
  712. text-align: center;
  713. margin: 5vw 0;
  714. .qrcode_1_1 {
  715. padding: 2vw;
  716. background: red;
  717. .uqrcode {
  718. display: flex;
  719. justify-content: center;
  720. width: 216px !important;
  721. height: 216px !important;
  722. .uqrcode-canvas {
  723. -webkit-transform-origin: center;
  724. }
  725. }
  726. .txt {
  727. margin: 2vw 0 0 0;
  728. color: var(--mainColor);
  729. }
  730. }
  731. }
  732. }
  733. }
  734. .collect {
  735. position: fixed;
  736. top: 0;
  737. right: 2vw;
  738. .iconfont {
  739. font-size: 25px;
  740. }
  741. }
  742. }
  743. .two {
  744. display: flex;
  745. flex-direction: row;
  746. justify-content: space-around;
  747. border-top: 1px solid #f1f1f1;
  748. .list {
  749. padding: 1vw 0;
  750. text-align: center;
  751. .icon {}
  752. .name {
  753. font-size: 12px;
  754. }
  755. .activename {
  756. color: var(--fFB1Color);
  757. }
  758. }
  759. }
  760. }
  761. .scroll-view {
  762. position: absolute;
  763. top: 0;
  764. left: 0;
  765. right: 0;
  766. bottom: 0;
  767. .list-scroll-view {
  768. display: flex;
  769. flex-direction: row;
  770. flex-wrap: wrap;
  771. }
  772. }
  773. .is_bottom {
  774. width: 100%;
  775. text-align: center;
  776. text {
  777. padding: 1vw 0;
  778. display: inline-block;
  779. }
  780. }
  781. </style>