zrug пре 6 месеци
родитељ
комит
c1cbecbeab
46 измењених фајлова са 1182 додато и 0 уклоњено
  1. 31 0
      .eslintrc.js
  2. 64 0
      app.js
  3. 57 0
      app.json
  4. 1 0
      app.wxss
  5. 105 0
      components/navigation-bar/navigation-bar.js
  6. 5 0
      components/navigation-bar/navigation-bar.json
  7. 64 0
      components/navigation-bar/navigation-bar.wxml
  8. 96 0
      components/navigation-bar/navigation-bar.wxss
  9. 6 0
      config.js
  10. BIN
      images/index/add-cart.png
  11. BIN
      images/index/brand-item.png
  12. BIN
      images/index/buy-now.png
  13. BIN
      images/index/cart.png
  14. BIN
      images/index/category-item.png
  15. BIN
      images/index/hot-item.png
  16. BIN
      images/index/logo.png
  17. BIN
      images/index/search.png
  18. 1 0
      pages/all/all.js
  19. 4 0
      pages/all/all.json
  20. 3 0
      pages/all/all.wxml
  21. 0 0
      pages/all/all.wxss
  22. 1 0
      pages/cart/cart.js
  23. 4 0
      pages/cart/cart.json
  24. 3 0
      pages/cart/cart.wxml
  25. 0 0
      pages/cart/cart.wxss
  26. 1 0
      pages/detail/detail.js
  27. 4 0
      pages/detail/detail.json
  28. 3 0
      pages/detail/detail.wxml
  29. 0 0
      pages/detail/detail.wxss
  30. 84 0
      pages/index/index.js
  31. 3 0
      pages/index/index.json
  32. 69 0
      pages/index/index.wxml
  33. 221 0
      pages/index/index.wxss
  34. 1 0
      pages/login/login.js
  35. 4 0
      pages/login/login.json
  36. 3 0
      pages/login/login.wxml
  37. 0 0
      pages/login/login.wxss
  38. 1 0
      pages/my/my.js
  39. 4 0
      pages/my/my.json
  40. 3 0
      pages/my/my.wxml
  41. 0 0
      pages/my/my.wxss
  42. 28 0
      project.config.json
  43. 9 0
      project.private.config.json
  44. 222 0
      service/api.js
  45. 7 0
      sitemap.json
  46. 70 0
      utils/http.js

+ 31 - 0
.eslintrc.js

@@ -0,0 +1,31 @@
+/*
+ * Eslint config file
+ * Documentation: https://eslint.org/docs/user-guide/configuring/
+ * Install the Eslint extension before using this feature.
+ */
+module.exports = {
+  env: {
+    es6: true,
+    browser: true,
+    node: true,
+  },
+  ecmaFeatures: {
+    modules: true,
+  },
+  parserOptions: {
+    ecmaVersion: 2018,
+    sourceType: 'module',
+  },
+  globals: {
+    wx: true,
+    App: true,
+    Page: true,
+    getCurrentPages: true,
+    getApp: true,
+    Component: true,
+    requirePlugin: true,
+    requireMiniProgram: true,
+  },
+  // extends: 'eslint:recommended',
+  rules: {},
+}

+ 64 - 0
app.js

@@ -0,0 +1,64 @@
+// app.js
+
+const { baseUrl } = require('./config.js');
+
+App({
+
+// config.service.pathUrl
+// https://mpapitest.gululuq.com/
+
+  data: {
+    loginSuccess: false,
+  },
+
+  globalData: {
+    storeId: null,
+    mUser: null,
+  },
+
+  onLaunch() {
+
+    // 登录
+    wx.login({
+      success: res => {
+        // 发送 res.code 到后台换取 openId, sessionKey, unionId
+        console.log("code", res);
+        if (res.code){
+          wx.request({
+            url: baseUrl + '/api/store/wxlogin',
+            method: 'POST',
+            data: {
+              jsCode: res.code
+            },
+            header: {
+              'content-type': 'application/x-www-form-urlencoded',
+              // 'X-Referrer-Id': codeUrl[1] || '',
+              // 'X-Store-Id': codeUrl[0] || ''
+              'X-Referrer-Id': '',
+              'X-Store-Id': ''
+            },
+            success:(res)=> {
+              console.log(res);
+              // this.globalData.mUser = res.data.data;
+              // this.globalData.storeId = '';
+              // this.data.loginSuccess = true;
+            },
+            fail: function(res){
+              console.log(res);
+            }
+          })
+        }
+      },
+      fail: function(e){
+        console.log(e);
+      }
+    })
+  },
+})
+
+
+wx.login({
+  success: res => {
+    // 发送 res.code 到后台换取 openId, sessionKey, unionId
+  },
+})

+ 57 - 0
app.json

@@ -0,0 +1,57 @@
+{
+  "pages": [
+    "pages/index/index",
+    "pages/all/all",
+    "pages/cart/cart",
+    "pages/my/my",
+    "pages/detail/detail",
+    "pages/login/login"
+  ],
+  "window": {
+    "backgroundColor": "#FFFFFF",
+    "backgroundTextStyle": "dark",
+    "navigationBarBackgroundColor": "#dfefec",
+    "navigationBarTitleText": "谷鹿鹿Q",
+    "navigationBarTextStyle": "black",
+    "pageOrientation": "portrait"
+  },
+  "style": "v2",
+  "renderer": "skyline",
+  "rendererOptions": {
+    "skyline": {
+      "defaultDisplayBlock": true,
+      "defaultContentBox": true,
+      "tagNameStyleIsolation": "legacy",
+      "disableABTest": true,
+      "sdkVersionBegin": "3.0.0",
+      "sdkVersionEnd": "15.255.255"
+    }
+  },
+  "componentFramework": "glass-easel",
+  "sitemapLocation": "sitemap.json",
+  "lazyCodeLoading": "requiredComponents",
+  "tabBar": {
+    "color": "#333333",
+    "selectedColor": "#8dbbb8",
+    "borderStyle": "white",
+    "backgroundColor": "#dfefec",
+    "list": [
+      {
+        "pagePath": "pages/index/index",
+        "text": "主页"
+      },
+      {
+        "pagePath": "pages/all/all",
+        "text": "全部商品"
+      },
+      {
+        "pagePath": "pages/cart/cart",
+        "text": "购物车"
+      },
+      {
+        "pagePath": "pages/my/my",
+        "text": "我的"
+      }
+    ]
+  }
+}

+ 1 - 0
app.wxss

@@ -0,0 +1 @@
+/**app.wxss**/

+ 105 - 0
components/navigation-bar/navigation-bar.js

@@ -0,0 +1,105 @@
+Component({
+  options: {
+    multipleSlots: true // 在组件定义时的选项中启用多slot支持
+  },
+  /**
+   * 组件的属性列表
+   */
+  properties: {
+    extClass: {
+      type: String,
+      value: ''
+    },
+    title: {
+      type: String,
+      value: ''
+    },
+    background: {
+      type: String,
+      value: ''
+    },
+    color: {
+      type: String,
+      value: ''
+    },
+    back: {
+      type: Boolean,
+      value: true
+    },
+    loading: {
+      type: Boolean,
+      value: false
+    },
+    homeButton: {
+      type: Boolean,
+      value: false,
+    },
+    animated: {
+      // 显示隐藏的时候opacity动画效果
+      type: Boolean,
+      value: true
+    },
+    show: {
+      // 显示隐藏导航,隐藏的时候navigation-bar的高度占位还在
+      type: Boolean,
+      value: true,
+      observer: '_showChange'
+    },
+    // back为true的时候,返回的页面深度
+    delta: {
+      type: Number,
+      value: 1
+    },
+  },
+  /**
+   * 组件的初始数据
+   */
+  data: {
+    displayStyle: ''
+  },
+  lifetimes: {
+    attached() {
+      const rect = wx.getMenuButtonBoundingClientRect()
+      wx.getSystemInfo({
+        success: (res) => {
+          const isAndroid = res.platform === 'android'
+          const isDevtools = res.platform === 'devtools'
+          this.setData({
+            ios: !isAndroid,
+            innerPaddingRight: `padding-right: ${res.windowWidth - rect.left}px`,
+            leftWidth: `width: ${res.windowWidth - rect.left }px`,
+            safeAreaTop: isDevtools || isAndroid ? `height: calc(var(--height) + ${res.safeArea.top}px); padding-top: ${res.safeArea.top}px` : ``
+          })
+        }
+      })
+    },
+  },
+  /**
+   * 组件的方法列表
+   */
+  methods: {
+    _showChange(show) {
+      const animated = this.data.animated
+      let displayStyle = ''
+      if (animated) {
+        displayStyle = `opacity: ${
+          show ? '1' : '0'
+        };transition:opacity 0.5s;`
+      } else {
+        displayStyle = `display: ${show ? '' : 'none'}`
+      }
+      this.setData({
+        displayStyle
+      })
+    },
+    back() {
+      const data = this.data
+      if (data.delta) {
+        wx.navigateBack({
+          delta: data.delta
+        })
+      }
+      this.triggerEvent('back', { delta: data.delta }, {})
+    }
+  },
+})

+ 5 - 0
components/navigation-bar/navigation-bar.json

@@ -0,0 +1,5 @@
+{
+  "component": true,
+  "styleIsolation": "apply-shared",
+  "usingComponents": {}
+}

+ 64 - 0
components/navigation-bar/navigation-bar.wxml

@@ -0,0 +1,64 @@
+<view class="weui-navigation-bar {{extClass}}">
+  <view class="weui-navigation-bar__inner {{ios ? 'ios' : 'android'}}" style="color: {{color}}; background: {{background}}; {{displayStyle}}; {{innerPaddingRight}}; {{safeAreaTop}};">
+
+    <!-- 左侧按钮 -->
+    <view class='weui-navigation-bar__left' style="{{leftWidth}};">
+      <block wx:if="{{back || homeButton}}">
+        <!-- 返回上一页 -->
+        <block wx:if="{{back}}">
+          <view class="weui-navigation-bar__buttons weui-navigation-bar__buttons_goback">
+            <view
+              bindtap="back"
+              class="weui-navigation-bar__btn_goback_wrapper"
+              hover-class="weui-active"
+              hover-stay-time="100"
+              aria-role="button"
+              aria-label="返回"
+            >
+              <view class="weui-navigation-bar__button weui-navigation-bar__btn_goback"></view>
+            </view>
+          </view>
+        </block>
+        <!-- 返回首页 -->
+        <block wx:if="{{homeButton}}">
+          <view class="weui-navigation-bar__buttons weui-navigation-bar__buttons_home">
+            <view
+              bindtap="home"
+              class="weui-navigation-bar__btn_home_wrapper"
+              hover-class="weui-active"
+              aria-role="button"
+              aria-label="首页"
+            >
+              <view class="weui-navigation-bar__button weui-navigation-bar__btn_home"></view>
+            </view>
+          </view>
+        </block>
+      </block>
+      <block wx:else>
+        <slot name="left"></slot>
+      </block>
+    </view>
+
+    <!-- 标题 -->
+    <view class='weui-navigation-bar__center'>
+      <view wx:if="{{loading}}" class="weui-navigation-bar__loading" aria-role="alert">
+        <view
+          class="weui-loading"
+          aria-role="img"
+          aria-label="加载中"
+        ></view>
+      </view>
+      <block wx:if="{{title}}">
+        <text>{{title}}</text>
+      </block>
+      <block wx:else>
+        <slot name="center"></slot>
+      </block>
+    </view>
+    
+    <!-- 右侧留空 -->
+    <view class='weui-navigation-bar__right'>
+      <slot name="right"></slot>
+    </view>
+  </view>
+</view>

+ 96 - 0
components/navigation-bar/navigation-bar.wxss

@@ -0,0 +1,96 @@
+.weui-navigation-bar {
+  --weui-FG-0:rgba(0,0,0,.9);
+  --height: 44px;
+  --left: 16px;
+}
+.weui-navigation-bar .android {
+  --height: 48px;
+}
+
+.weui-navigation-bar {
+  overflow: hidden;
+  color: var(--weui-FG-0);
+  flex: none;
+}
+
+.weui-navigation-bar__inner {
+  position: relative;
+  top: 0;
+  left: 0;
+  height: calc(var(--height) + env(safe-area-inset-top));
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: center;
+  padding-top: env(safe-area-inset-top);
+  width: 100%;
+  box-sizing: border-box;
+}
+
+.weui-navigation-bar__left {
+  position: relative;
+  padding-left: var(--left);
+  display: flex;
+  flex-direction: row;
+  align-items: flex-start;
+  height: 100%;
+  box-sizing: border-box;
+}
+
+.weui-navigation-bar__btn_goback_wrapper {
+  padding: 11px 18px 11px 16px;
+  margin: -11px -18px -11px -16px;
+}
+
+.weui-navigation-bar__btn_goback_wrapper.weui-active {
+  opacity: 0.5;
+}
+
+.weui-navigation-bar__btn_goback {
+  font-size: 12px;
+  width: 12px;
+  height: 24px;
+  -webkit-mask: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='24' viewBox='0 0 12 24'%3E  %3Cpath fill-opacity='.9' fill-rule='evenodd' d='M10 19.438L8.955 20.5l-7.666-7.79a1.02 1.02 0 0 1 0-1.42L8.955 3.5 10 4.563 2.682 12 10 19.438z'/%3E%3C/svg%3E") no-repeat 50% 50%;
+  mask: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='24' viewBox='0 0 12 24'%3E  %3Cpath fill-opacity='.9' fill-rule='evenodd' d='M10 19.438L8.955 20.5l-7.666-7.79a1.02 1.02 0 0 1 0-1.42L8.955 3.5 10 4.563 2.682 12 10 19.438z'/%3E%3C/svg%3E") no-repeat 50% 50%;
+  -webkit-mask-size: cover;
+  mask-size: cover;
+  background-color: var(--weui-FG-0);
+}
+
+.weui-navigation-bar__center {
+  font-size: 17px;
+  text-align: center;
+  position: relative;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: center;
+  font-weight: bold;
+  flex: 1;
+  height: 100%;
+}
+
+.weui-navigation-bar__loading {
+  margin-right: 4px;
+  align-items: center;
+}
+
+.weui-loading {
+  font-size: 16px;
+  width: 16px;
+  height: 16px;
+  display: block;
+  background: transparent url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg width='80px' height='80px' viewBox='0 0 80 80' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Ctitle%3Eloading%3C/title%3E%3Cdefs%3E%3ClinearGradient x1='94.0869141%25' y1='0%25' x2='94.0869141%25' y2='90.559082%25' id='linearGradient-1'%3E%3Cstop stop-color='%23606060' stop-opacity='0' offset='0%25'%3E%3C/stop%3E%3Cstop stop-color='%23606060' stop-opacity='0.3' offset='100%25'%3E%3C/stop%3E%3C/linearGradient%3E%3ClinearGradient x1='100%25' y1='8.67370605%25' x2='100%25' y2='90.6286621%25' id='linearGradient-2'%3E%3Cstop stop-color='%23606060' offset='0%25'%3E%3C/stop%3E%3Cstop stop-color='%23606060' stop-opacity='0.3' offset='100%25'%3E%3C/stop%3E%3C/linearGradient%3E%3C/defs%3E%3Cg stroke='none' stroke-width='1' fill='none' fill-rule='evenodd' opacity='0.9'%3E%3Cg%3E%3Cpath d='M40,0 C62.09139,0 80,17.90861 80,40 C80,62.09139 62.09139,80 40,80 L40,73 C58.2253967,73 73,58.2253967 73,40 C73,21.7746033 58.2253967,7 40,7 L40,0 Z' fill='url(%23linearGradient-1)'%3E%3C/path%3E%3Cpath d='M40,0 L40,7 C21.7746033,7 7,21.7746033 7,40 C7,58.2253967 21.7746033,73 40,73 L40,80 C17.90861,80 0,62.09139 0,40 C0,17.90861 17.90861,0 40,0 Z' fill='url(%23linearGradient-2)'%3E%3C/path%3E%3Ccircle id='Oval' fill='%23606060' cx='40.5' cy='3.5' r='3.5'%3E%3C/circle%3E%3C/g%3E%3C/g%3E%3C/svg%3E%0A") no-repeat;
+  background-size: 100%;
+  margin-left: 0;
+  animation: loading linear infinite 1s;
+}
+
+@keyframes loading {
+  from {
+    transform: rotate(0);
+  }
+  to {
+    transform: rotate(360deg);
+  }
+}

+ 6 - 0
config.js

@@ -0,0 +1,6 @@
+export const baseUrl = "https://mpapitest.gululuq.com"; // 服务器地址
+// export const baseUrl = "http://测试接口地址"; // 测试服务器地址
+
+// export const ossHost = "https://res.zrug.top";
+export const version = "0.0.1"; // 版本号
+export const version_desc = "接口基础";

BIN
images/index/add-cart.png


BIN
images/index/brand-item.png


BIN
images/index/buy-now.png


BIN
images/index/cart.png


BIN
images/index/category-item.png


BIN
images/index/hot-item.png


BIN
images/index/logo.png


BIN
images/index/search.png


+ 1 - 0
pages/all/all.js

@@ -0,0 +1 @@
+Page({})

+ 4 - 0
pages/all/all.json

@@ -0,0 +1,4 @@
+{
+  "navigationStyle": "custom",
+  "usingComponents": {}
+}

+ 3 - 0
pages/all/all.wxml

@@ -0,0 +1,3 @@
+<view>
+  all
+</view>

+ 0 - 0
pages/all/all.wxss


+ 1 - 0
pages/cart/cart.js

@@ -0,0 +1 @@
+Page({})

+ 4 - 0
pages/cart/cart.json

@@ -0,0 +1,4 @@
+{
+  "navigationStyle": "custom",
+  "usingComponents": {}
+}

+ 3 - 0
pages/cart/cart.wxml

@@ -0,0 +1,3 @@
+<view>
+  cart
+</view>

+ 0 - 0
pages/cart/cart.wxss


+ 1 - 0
pages/detail/detail.js

@@ -0,0 +1 @@
+Page({})

+ 4 - 0
pages/detail/detail.json

@@ -0,0 +1,4 @@
+{
+  "navigationStyle": "custom",
+  "usingComponents": {}
+}

+ 3 - 0
pages/detail/detail.wxml

@@ -0,0 +1,3 @@
+<view>
+  detail
+</view>

+ 0 - 0
pages/detail/detail.wxss


+ 84 - 0
pages/index/index.js

@@ -0,0 +1,84 @@
+// index.js
+Component({
+  data: {
+    brandList: [
+      {
+        name: "全部IP",
+      },
+      {
+        name: "火影忍者",
+      },
+      {
+        name: "原神",
+      },
+      {
+        name: "柯南",
+      },
+      {
+        name: "非人哉",
+      },
+      {
+        name: "海贼王",
+      },
+      {
+        name: "初音",
+      },
+      {
+        name: "千与千寻",
+      },
+      {
+        name: "樱木花道",
+      },
+      {
+        name: "原神",
+      },
+    ],
+    categoryList: [
+      {
+        name: "立绘",
+      },
+      {
+        name: "立绘",
+      },
+      {
+        name: "立绘",
+      },
+      {
+        name: "立绘",
+      },
+      {
+        name: "立绘",
+      },
+      {
+        name: "立绘",
+      },
+      {
+        name: "立绘",
+      },
+      {
+        name: "立绘",
+      },
+    ],
+    goodsList: [
+      {
+        name: "哪吒魔童闹海周边",
+        price: 49.5
+      },
+      {
+        name: "若来十二生肖盲盒 桌面手办",
+        price: 49.5
+      },
+      {
+        name: "官方正版姜子牙电影四不像",
+        price: 49.5
+      },
+      {
+        name: "若来十二生肖盲盒 十二节气祖国版",
+        price: 49.5
+      },
+    ],
+  },
+
+  methods: {
+  },
+})

+ 3 - 0
pages/index/index.json

@@ -0,0 +1,3 @@
+{
+  "usingComponents": {}
+}

+ 69 - 0
pages/index/index.wxml

@@ -0,0 +1,69 @@
+<!--index.wxml-->
+<view class="container">
+  <view class="header">
+    <view class="header-bg"></view>
+    <view class="logo logo-at-left">
+      <image src="/images/index/logo.png" class="logo-image"></image>
+    </view>
+    <view class="search-and-cart">
+      <view class="search">
+        <image src="/images/index/search.png" class="search-icon"></image>
+      </view>
+      <view class="cart">
+        <image src="/images/index/cart.png" class="cart-icon"></image>
+      </view>
+    </view>
+  </view>
+  <view class="banner">
+    <view class="banner-item">
+      banner
+    </view>
+  </view>
+  <view class="hot-bar">
+    <view class="hot-A">
+      <image src="/images/index/hot-item.png" class="hot-image"></image>
+    </view>
+    <view class="hot-B">
+      <image src="/images/index/hot-item.png" class="hot-image"></image>
+    </view>
+    <view class="hot-C">
+      <image src="/images/index/hot-item.png" class="hot-image"></image>
+    </view>
+  </view>
+  <view class="brand-bar">
+    <view wx:for="{{brandList}}" wx:key="index" class="brand-item">
+      <image src="/images/index/brand-item.png" class="brand-image"></image>
+      <!-- <text class="brand-name">{{item.name}}</text> -->
+    </view>
+  </view>
+  <view class="slider">
+    <view class="slider-item">
+      slider
+    </view>
+  </view>
+  <view class="category">
+    <view wx:for="{{categoryList}}" wx:key="index" class="category-item">
+      <image src="/images/index/category-item.png" class="category-image"></image>
+    </view>
+  </view>
+  <view class="goods">
+    <view class="goods-row" wx:for="{{goodsList}}" wx:key="index" wx:for-item="row">
+      <view class="goods-item" wx:for="{{row}}" wx:key="itemIndex">
+        <view class="goods-image">
+          <image src="{{item.imageUrl}}" class="goods-image-inner"></image>
+        </view>
+        <view class="goods-info">
+          <text class="goods-name">{{item.name}}</text>
+          <text class="goods-price">¥{{item.price}}</text>
+        </view>
+        <view class="goods-action">
+          <view class="favorite">
+            <image src="/images/index/fav.png" class="favorite-icon"></image>
+          </view>
+          <button class="add-to-cart">加入购物车</button>
+          <button class="buy-now">立即购买</button>
+        </view>
+      </view>
+    </view>
+  </view>
+</view>

+ 221 - 0
pages/index/index.wxss

@@ -0,0 +1,221 @@
+/**index.wxss**/
+page {
+  overflow-x: hidden;
+  overflow-y: scroll;
+  display: flex;
+  flex-direction: column;
+}
+
+.header {
+  height: 330rpx;
+  position: relative;
+}
+.header .header-bg {
+  z-index: 1;
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100vw;
+  height: 295rpx;
+  background: #dfefec;
+}
+.header .logo {
+  width: 150rpx;
+  height: 150rpx;
+  z-index: 99;
+}
+.header .logo.logo-at-left {
+  position: absolute;
+  top: 96rpx;
+  left: 36rpx;
+}
+.header .logo-image {
+  width: 100%;
+  height: 100%;
+}
+.header .search-icon {
+  position: absolute;
+  z-index: 99;
+  top: 260rpx;
+  left: 30rpx;
+  height: 65rpx;
+  width: 530rpx;
+}
+.header .cart-icon {
+  position: absolute;
+  z-index: 99;
+  top: 260rpx;
+  right: 30rpx;
+  height: 65rpx;
+  width: 146rpx;
+}
+
+.banner {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  padding: 24rpx 0 10rpx;
+}
+.banner .banner-item {
+  border: 1px solid #dfefec;
+  width: 690rpx;
+  height: 310rpx;
+  display: block;
+  border-radius: 25rpx;
+}
+.hot-bar {
+  padding: 14rpx 30rpx 10rpx;
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  justify-content: space-between;
+  align-items: center;
+}
+.hot-bar .hot-image {
+  width: 220rpx;
+  height: 300rpx;
+}
+.brand-bar {
+  padding: 14rpx 30rpx 10rpx;
+  display: flex;
+  flex-direction: row;
+  flex-wrap: wrap;
+  justify-content: space-between;
+  align-items: center;
+}
+.brand-bar .brand-item {
+  width: 120rpx;
+  height: 120rpx;
+  margin-bottom: 20rpx;
+}
+.brand-bar .brand-item .brand-image {
+  width: 100%;
+  height: 100%;
+}
+.slider {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  padding: 24rpx 0 10rpx;
+}
+.slider .slider-item {
+  border: 1px solid #dfefec;
+  width: 690rpx;
+  height: 220rpx;
+  display: block;
+  border-radius: 25rpx;
+}
+.category {
+  height: 300rpx;
+  margin: 14rpx 30rpx 10rpx 30rpx;
+  border: 1px solid #dfefec;
+  border-radius: 25rpx;
+  padding: 20rpx;
+  display: flex;
+  flex-direction: row;
+  flex-wrap: wrap;
+  justify-content: space-between;
+  align-items: center;
+}
+.category .category-item {
+  width: 144rpx;
+  height: 144rpx;
+  margin-bottom: 20rpx;
+}
+.category .category-item .category-image {
+  width: 100%;
+  height: 100%;
+}
+.goods {
+  display: flex;
+  flex-direction: column;
+  padding: 21rpx 21rpx 0 21rpx;
+}
+
+.goods-row {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-evenly;
+  margin-bottom: 21rpx;
+}
+
+.goods-item {
+  width: 326rpx; /* 313*1.0417 */
+  background: #fff;
+  border-radius: 21rpx; /* 20*1.0417 */
+  box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.05);
+  overflow: hidden;
+  display: flex;
+  flex-direction: column;
+}
+
+.goods-image {
+  width: 326rpx;
+  height: 326rpx;
+  margin: 0;
+  border-top-left-radius: 21rpx;
+  border-top-right-radius: 21rpx;
+  border-bottom-left-radius: 0;
+  border-bottom-right-radius: 0;
+  overflow: hidden;
+  background: #f7f7f7;
+}
+.goods-image-inner {
+  width: 100%;
+  height: 100%;
+  object-fit: cover;
+}
+.goods-info {
+  padding: 16rpx 21rpx 0 21rpx;
+}
+.goods-name {
+  font-size: 18rpx;
+  color: #333;
+  display: block;
+  margin-bottom: 8rpx;
+  font-weight: bold;
+}
+.goods-price {
+  font-size: 20rpx;
+  color: #e4393c;
+  font-weight: bold;
+}
+.goods-action {
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
+  padding: 16rpx 21rpx 21rpx 21rpx;
+}
+.favorite {
+  width: 32rpx;
+  height: 32rpx;
+}
+.favorite-icon {
+  width: 100%;
+  height: 100%;
+}
+.add-to-cart,
+.buy-now {
+  width: 105rpx;
+  height: 36rpx;
+  line-height: 36rpx;
+  font-size: 16rpx;
+  border-radius: 6rpx;
+  margin-left: 8rpx;
+  padding: 0;
+  border: none;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  box-sizing: border-box;
+}
+.add-to-cart {
+  background: #fff;
+  color: #7AC7B5;
+  border: 2rpx solid #7AC7B5;
+}
+.buy-now {
+  background: #7AC7B5;
+  color: #fff;
+  border: none;
+}

+ 1 - 0
pages/login/login.js

@@ -0,0 +1 @@
+Page({})

+ 4 - 0
pages/login/login.json

@@ -0,0 +1,4 @@
+{
+  "navigationStyle": "custom",
+  "usingComponents": {}
+}

+ 3 - 0
pages/login/login.wxml

@@ -0,0 +1,3 @@
+<view>
+  login
+</view>

+ 0 - 0
pages/login/login.wxss


+ 1 - 0
pages/my/my.js

@@ -0,0 +1 @@
+Page({})

+ 4 - 0
pages/my/my.json

@@ -0,0 +1,4 @@
+{
+  "navigationStyle": "custom",
+  "usingComponents": {}
+}

+ 3 - 0
pages/my/my.wxml

@@ -0,0 +1,3 @@
+<view>
+  my
+</view>

+ 0 - 0
pages/my/my.wxss


+ 28 - 0
project.config.json

@@ -0,0 +1,28 @@
+{
+  "appid": "wx12e34630814e5d30",
+  "compileType": "miniprogram",
+  "libVersion": "3.8.0",
+  "packOptions": {
+    "ignore": [],
+    "include": []
+  },
+  "setting": {
+    "coverView": true,
+    "es6": true,
+    "postcss": true,
+    "minified": true,
+    "enhance": true,
+    "showShadowRootInWxmlPanel": true,
+    "packNpmRelationList": [],
+    "babelSetting": {
+      "ignore": [],
+      "disablePlugins": [],
+      "outputPath": ""
+    }
+  },
+  "condition": {},
+  "editorSetting": {
+    "tabIndent": "insertSpaces",
+    "tabSize": 2
+  }
+}

+ 9 - 0
project.private.config.json

@@ -0,0 +1,9 @@
+{
+  "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
+  "projectname": "GululuQ-mp",
+  "setting": {
+    "compileHotReLoad": true,
+    "urlCheck": false
+  },
+  "libVersion": "3.8.0"
+}

+ 222 - 0
service/api.js

@@ -0,0 +1,222 @@
+import http from "../utils/http";
+
+// 服务器存活检测接口,返回200表示存活,否则表示不存活
+export const Ping = {
+  get: function () {
+    return http.get("/api/alive/ping");
+  },
+  post: function (data) {
+    return http.post("/api/alive/ping", data);
+  },
+}
+
+// 小程序体量限制1M,图片必须放在外部cdn上
+// 七牛云存储,获取token
+export const Qiniu = {
+  token: function () {
+    // TODO: get token from app first, if expired, request new
+    return http.post("/qiniu/token");
+  },
+}
+
+// HomepageApiController
+export const HomepageApi = {
+  /** 
+   * 返回示例:{
+    "bannerList": [
+      {
+        "createUser": "",
+        "createTime": "",
+        "updateUser": "",
+        "updateTime": "",
+        "remark": "",
+        "params": {
+          "": {}
+        },
+        "bannerId": 0,
+        "bannerUrl": "",
+        "bannerType": "",
+        "prodId": 0,
+        "newsId": 0,
+        "sort": 0,
+        "delFlag": ""
+      }
+    ]
+  }
+  */
+  getBanners: function (payload) {
+    return http.post("/api/store/homepage/banners", {
+      ...payload,
+    });
+  },
+
+  /**
+   * 返回示例:{
+    "ipInfoList": [
+      {
+        "createUser": "",
+        "createTime": "",
+        "updateUser": "",
+        "updateTime": "",
+        "remark": "",
+        "params": {
+          "": {}
+        },
+        "ipId": 0,
+        "ipName": "",
+        "ipUrl": "",
+        "colorNo": "",
+        "sort": 0,
+        "delFlag": ""
+      }
+    ]
+  }
+  */
+  getIpInfos: function (payload) {
+    return http.post("/api/store/homepage/ipInfos", {
+      ...payload,
+    });
+  },
+
+  /**
+   * 返回示例:{
+    "titleList": [
+      ""
+    ]
+  }
+  */
+  getTitles: function (payload) {
+    return http.post("/api/store/homepage/titles", {
+      ...payload,
+    });
+  },
+
+  /**
+   * 返回示例:{
+    "prodList": [
+      {
+        "id": 0,
+        "prodId": 0,
+        "sort": 0,
+        "prodPicList": [
+          {
+            "createUser": "",
+            "createTime": "",
+            "updateUser": "",
+            "updateTime": "",
+            "remark": "",
+            "params": {
+              "": {}
+            },
+            "id": 0,
+            "prodId": 0,
+            "picUrl": "",
+            "sort": 0,
+            "delFlag": ""
+          }
+        ]
+      }
+    ]
+  }
+  */
+  getLeftProds: function (payload) {
+    return http.post("/api/store/homepage/leftProds", {
+      ...payload,
+    });
+  },
+
+  /**
+   * 返回示例:{
+    "prodList": [
+      {
+        "id": 0,
+        "prodId": 0,
+        "sort": 0,
+        "prodPicList": [
+          {
+            "createUser": "",
+            "createTime": "",
+            "updateUser": "",
+            "updateTime": "",
+            "remark": "",
+            "params": {
+              "": {}
+            },
+            "id": 0,
+            "prodId": 0,
+            "picUrl": "",
+            "sort": 0,
+            "delFlag": ""
+          }
+        ]
+      }
+    ]
+  }
+  */
+  getMiddleProds: function (payload) {
+    return http.post("/api/store/homepage/middleProds", {
+      ...payload,
+    });
+  },
+
+  /**
+   * 返回示例:{
+    "prodList": [
+      {
+        "id": 0,
+        "prodId": 0,
+        "sort": 0,
+        "prodPicList": [
+          {
+            "createUser": "",
+            "createTime": "",
+            "updateUser": "",
+            "updateTime": "",
+            "remark": "",
+            "params": {
+              "": {}
+            },
+            "id": 0,
+            "prodId": 0,
+            "picUrl": "",
+            "sort": 0,
+            "delFlag": ""
+          }
+        ]
+      }
+    ]
+  }
+  */
+  getRightProds: function (payload) {
+    return http.post("/api/store/homepage/rightProds", {
+      ...payload,
+    });
+  },
+
+  /**
+   * 返回示例:{
+    "prodClassList": [
+      {
+        "createUser": "",
+        "createTime": "",
+        "updateUser": "",
+        "updateTime": "",
+        "remark": "",
+        "params": {
+          "": {}
+        },
+        "prodClassId": 0,
+        "className": "",
+        "classUrl": "",
+        "sort": 0,
+        "delFlag": ""
+      }
+    ]
+  }
+  */
+  getProdClasses: function (payload) {
+    return http.post("/api/store/homepage/prodClasses", {
+      ...payload,
+    });
+  },
+}

+ 7 - 0
sitemap.json

@@ -0,0 +1,7 @@
+{
+    "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
+    "rules": [{
+    "action": "allow",
+    "page": "*"
+    }]
+}

+ 70 - 0
utils/http.js

@@ -0,0 +1,70 @@
+import { baseUrl } from "../config";
+
+function getHeader() {
+  if (wx.getStorageSync("token")) {
+    return {
+      "content-type": "application/json",
+      "x-token": wx.getStorageSync("token"),
+    };
+  }
+  return {
+    "content-type": "application/json",
+  };
+}
+
+function showErrToast(e) {
+  wx.showToast({
+    title: typeof e === "string" ? e : e.errMsg || e.toString(),
+    icon: "none",
+    duration: 1500,
+  });
+}
+
+function getPromise(url, data, method) {
+  return new Promise((resolve, reject) => {
+    wx.request({
+      url: `${baseUrl}${url}`,
+      header: getHeader(),
+      method: method,
+      data: data,
+      success: function (res) {
+        if (res.data.code === 200) {
+          resolve(res.data.data);
+        } else {
+          if (res.statusCode === 401) {
+            reject(401);
+          } else {
+            reject(res.data.message);
+          }
+        }
+      },
+      fail: function (err) {
+        reject(err);
+      },
+    });
+  }).catch((e) => {
+    if (401 === e) {
+      // redirect to login page
+      wx.navigateTo({
+        url: "/pages/login/login",
+      });
+    } else {
+      console.error(`in promise error, url: ${baseUrl}${url}`);
+      console.error(e);
+      if (e) {
+        showErrToast(e);
+      }
+    }
+  });
+}
+
+const http = {
+  get: function (url, data) {
+    return getPromise(url, data, "GET");
+  },
+  post: function (url, data) {
+    return getPromise(url, data, "POST");
+  },
+};
+
+export default http;