Selaa lähdekoodia

Merge branch 'test' of gitee.com:yiguanjia/php into test

north 6 vuotta sitten
vanhempi
sitoutus
a86bc36a93
39 muutettua tiedostoa jossa 2580 lisäystä ja 132 poistoa
  1. 1 1
      www/protected/modules/o2o/views/web/index.php
  2. 0 0
      www/webapp/o2o_new/dist/static/js/app.js
  3. 18 13
      www/webapp/o2o_new/src/components/homeList.vue
  4. 0 0
      www/webapp/scg/asset/css/app.css
  5. 0 0
      www/webapp/scg/asset/css/app.css.map
  6. 0 0
      www/webapp/scg/asset/js/app.js
  7. 0 0
      www/webapp/scg/asset/js/app.js.map
  8. 0 0
      www/webapp/scg/asset/js/manifest.js.map
  9. 0 0
      www/webapp/scg/asset/js/vendor.js
  10. 0 0
      www/webapp/scg/asset/js/vendor.js.map
  11. 1 1
      www/webapp/scg/build/webpack.dev.conf.js
  12. 17 3
      www/webapp/scg/config/index.js
  13. 14 2
      www/webapp/scg/src/App.vue
  14. 15 7
      www/webapp/scg/src/api/index.js
  15. 52 0
      www/webapp/scg/src/components/header.vue
  16. 2 0
      www/webapp/scg/src/components/index.js
  17. 2 2
      www/webapp/scg/src/components/tabBar.vue
  18. 72 4
      www/webapp/scg/src/lib/baseUrl.js
  19. 8 0
      www/webapp/scg/src/lib/isDev.js
  20. 3 0
      www/webapp/scg/src/lib/name.js
  21. 442 0
      www/webapp/scg/src/lib/product.js
  22. 14 8
      www/webapp/scg/src/lib/userID.js
  23. 279 0
      www/webapp/scg/src/lib/util.js
  24. 11 4
      www/webapp/scg/src/main.js
  25. 47 0
      www/webapp/scg/src/router/index.js
  26. 182 7
      www/webapp/scg/src/store.js
  27. 28 27
      www/webapp/scg/src/theme.styl
  28. 191 0
      www/webapp/scg/src/views/address/edit.vue
  29. 90 7
      www/webapp/scg/src/views/address/index.vue
  30. 107 0
      www/webapp/scg/src/views/address/position.vue
  31. 7 2
      www/webapp/scg/src/views/home/index.vue
  32. 13 7
      www/webapp/scg/src/views/home/list.vue
  33. 200 0
      www/webapp/scg/src/views/login/index.vue
  34. 31 26
      www/webapp/scg/src/views/mine/index.vue
  35. 456 0
      www/webapp/scg/src/views/order/addOrder.vue
  36. 138 0
      www/webapp/scg/src/views/order/detail.vue
  37. 34 11
      www/webapp/scg/src/views/order/index.vue
  38. 36 0
      www/webapp/scg/src/views/pay/index.vue
  39. 69 0
      www/webapp/scg/src/views/product/index.vue

+ 1 - 1
www/protected/modules/o2o/views/web/index.php

@@ -1,5 +1,5 @@
 <?php $host = $_SERVER['HTTP_HOST']; /*资源路径设置*/ ?>
-<?php $newVersion = 2018030502;/*vue~资源版本号*/ ?>
+<?php $newVersion = 2019041801;/*vue~资源版本号*/ ?>
 <!DOCTYPE html>
 <html>
 <head>

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
www/webapp/o2o_new/dist/static/js/app.js


+ 18 - 13
www/webapp/o2o_new/src/components/homeList.vue

@@ -2,7 +2,7 @@
   <div class="home-list">
     <!--<button @click="btn">调试</button>-->
     <ul>
-      <li v-for="items in productIcon" v-on:click="pro(items.id)" :key="items" >
+      <li v-for="items in productIcon" v-on:click="pro(items.id)" :key="items">
         <div class="product-icon">
           <img :src='items.url'>
         </div>
@@ -15,39 +15,44 @@
 </template>
 
 <script>
-  import config from '../config/config'
-  import product from '../config/product'
+  import config from '../config/config';
+  import product from '../config/product';
+
   export default {
     name: 'home',
-    data () {
+    data() {
       return {
         productIcon: product.productIcon
-      }
+      };
+    },
+    created() {
     },
-    created () {},
     methods: {
       btn: function () {
 //        console.log(this.$store.state.product)
       },
       pro: function (id) {
- /*       this.$vux.alert.show({
-          title: '春节放假安排',
-          content: '根据国家规定,春节等国定节假日,本公司2月11号~3月2号暂停服务!3月3日恢复正常!'
-        })
-        return*/
+        /*       this.$vux.alert.show({
+                 title: '春节放假安排',
+                 content: '根据国家规定,春节等国定节假日,本公司2月11号~3月2号暂停服务!3月3日恢复正常!'
+               })
+               return*/
         // 循环判断被用户点击的商品,并将该商品的详细信息保存到全局变量config.productInfo
         config.productInfo = [];
         let products = this.$store.state.product.products.products;
         for (let i = 0; i < products.length; i++) {
           if (products[i].id === id) {
-            config.productInfo = products[i]
+            config.productInfo = products[i];
           }
         }
+        config.productInfo.pics.forEach((key, value) => {
+          config.productInfo.pics[value].url = config.productInfo.pics[value].url.replace(/oduj3utzz\.bkt\.clouddn\.com/, 'icon.yiguanjia.me');
+        });
         // 带查询参数,变成 /register?plan=private
         this.$router.push({path: '/product'})
       }
     }
-  }
+  };
 </script>
 
 <!-- 添加“scoped”属性来限制CSS到此组件 -->

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
www/webapp/scg/asset/css/app.css


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
www/webapp/scg/asset/css/app.css.map


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
www/webapp/scg/asset/js/app.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
www/webapp/scg/asset/js/app.js.map


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
www/webapp/scg/asset/js/manifest.js.map


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
www/webapp/scg/asset/js/vendor.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
www/webapp/scg/asset/js/vendor.js.map


+ 1 - 1
www/webapp/scg/build/webpack.dev.conf.js

@@ -67,7 +67,7 @@ module.exports = new Promise((resolve, reject) => {
       // Add FriendlyErrorsPlugin
       devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
         compilationSuccessInfo: {
-          messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
+          messages: [`Your application is running here:\n http://${devWebpackConfig.devServer.host}:${port}\n http://localhost:${port}`],
         },
         onErrors: config.dev.notifyOnErrors
         ? utils.createNotifierCallback()

+ 17 - 3
www/webapp/scg/config/index.js

@@ -3,7 +3,7 @@
 // see http://vuejs-templates.github.io/webpack for documentation.
 
 const path = require('path');
-const psth = 'http://common.yiguanjia.me';
+const psth = 'http://commontest.yiguanjia.me';
 module.exports = {
   dev: {
     
@@ -24,7 +24,21 @@ module.exports = {
         target: psth + '/index.php?r=', //你的目标域名
         changeOrigin: true,
         pathRewrite: {
-          "^/o2o": "/o2o"
+          '^/o2o': '/o2o'
+        }
+      },
+      '/api': {
+        target: psth + '/index.php?r=', //你的目标域名
+        changeOrigin: true,
+        pathRewrite: {
+          '^/api': '/api'
+        }
+      },
+      '/construction': {
+        target: psth + '/index.php?r=', //你的目标域名
+        changeOrigin: true,
+        pathRewrite: {
+          '^/construction': '/construction'
         }
       },
       '/ch': {
@@ -57,7 +71,7 @@ module.exports = {
     },
     
     // Various Dev Server settings
-    host: 'localhost', // can be overwritten by process.env.HOST
+    host: '0.0.0.0', // can be overwritten by process.env.HOST
     port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
     autoOpenBrowser: false,
     errorOverlay: true,

+ 14 - 2
www/webapp/scg/src/App.vue

@@ -1,12 +1,11 @@
 <template>
   <div id="app">
-    <!--    <img src="./assets/logo.png">-->
     <router-view/>
   </div>
 </template>
 
 <script>
-  import { mapActions } from 'vuex';
+  import { mapActions, mapGetters } from 'vuex';
 
   export default {
     name: 'app',
@@ -16,6 +15,19 @@
     created() {
       this.getUserInfo();
     },
+    watch: {
+      // eslint-disable-next-line
+      ifLogin: function (val, oVal) {
+        if (val) {
+          this.$router.push({ name: 'login' });
+        }
+      }
+    },
+    computed: {
+      ...mapGetters({
+        ifLogin: 'getIfLogin'
+      })
+    },
     methods: {
       ...mapActions(['getUserInfo'])
     }

+ 15 - 7
www/webapp/scg/src/api/index.js

@@ -27,7 +27,8 @@ function errorState(response) {
     type: 'alert',
     title: '提示',
     content: '网络异常',
-  }).show();
+  })
+  .show();
 }
 
 const httpServer = (opts, data) => {
@@ -39,13 +40,13 @@ const httpServer = (opts, data) => {
   const httpDefaultOpts = { // http默认配置
     method: opts.method,
     // baseURL,
-    url: apiPath + opts.url,
+    url: opts.url.indexOf('https://') > -1 ? opts.url : apiPath + opts.url,
     timeout: 10000,
     params: Object.assign(Public, data),
     data: qs.stringify(Object.assign(Public, data)),
     headers: opts.method === 'get' ? {
       // eslint-disable-next-line
-      "X-Requested-With": 'XMLHttpRequest',
+      'X-Requested-With': 'XMLHttpRequest',
       // eslint-disable-next-line
       'Accept': 'application/json',
       'Content-Type': 'application/json; charset=UTF-8'
@@ -55,7 +56,8 @@ const httpServer = (opts, data) => {
     }
   };
   if (opts.method === 'get') {
-    Object.keys(httpDefaultOpts.params).forEach(key => {
+    Object.keys(httpDefaultOpts.params)
+    .forEach(key => {
       httpDefaultOpts.url += `&${key}=${httpDefaultOpts.params[key]}`;
     });
     delete httpDefaultOpts.data;
@@ -63,11 +65,17 @@ const httpServer = (opts, data) => {
   delete httpDefaultOpts.params;
   const promise = new Promise((resolve, reject) => {
     // console.log(httpDefaultOpts);
-    axios(httpDefaultOpts).then(
+    axios(httpDefaultOpts)
+    .then(
       (res) => {
-        resolve(res.data.data);
+        if (httpDefaultOpts.url.indexOf('baidu') > 0) {
+          resolve(res.data);
+        } else {
+          resolve(res.data.data);
+        }
       }
-    ).catch(
+    )
+    .catch(
       (response) => {
         errorState(response);
         reject(response);

+ 52 - 0
www/webapp/scg/src/components/header.vue

@@ -0,0 +1,52 @@
+<template>
+  <header class="header">
+    <h1>{{title}}</h1>
+    <i @click="back" class="cubeic-back"></i>
+  </header>
+</template>
+<script type="text/ecmascript-6">
+  export default {
+    props: {
+      title: {
+        type: String,
+        default: '',
+        required: true
+      },
+      isAddress: {
+        type: Boolean,
+        default: false,
+        required: false
+      }
+    },
+    methods: {
+      back() {
+        if (!this.isAddress) {
+          this.$router.back();
+        } else {
+          this.$emit('back');
+        }
+      }
+    }
+  };
+</script>
+<style lang="stylus" scoped>
+  .header
+    position: relative
+    height: 44px
+    line-height: 44px
+    text-align: center
+    background-color: #edf0f4
+    box-shadow: 0 1px 6px #ccc
+    -webkit-backface-visibility: hidden
+    backface-visibility: hidden
+    z-index: 5
+    h1
+      font-size: 16px
+      font-weight: 700
+    .cubeic-back
+      position: absolute
+      top: 0
+      left: 0
+      padding: 0 15px
+      color: #fc9153
+</style>

+ 2 - 0
www/webapp/scg/src/components/index.js

@@ -1,6 +1,8 @@
 import tabBar from './tabBar';
+import header from './header';
 
 export default function addGlobalComponent(vue) {
   vue.component('tabBar', tabBar);
+  vue.component('h-header', header);
 }
 

+ 2 - 2
www/webapp/scg/src/components/tabBar.vue

@@ -65,7 +65,7 @@
     z-index 1
 
     &.border-top-1px:before
-      border-top-color $color-dark-orange
+      border-top-color h-color-dark-orange
 
     .cube-tab
       i
@@ -73,6 +73,6 @@
 
       div
         font-size otherSize
-        margin-top 5px
+        margin-top: 2px
 </style>
 

+ 72 - 4
www/webapp/scg/src/lib/baseUrl.js

@@ -7,16 +7,13 @@ const serviceModule = {
   * @params {string} user_id
   * */
   GetUserInfo: {
-    // url: '/o2o/user/info&user_id=57e245989f5160ca048b456f',
     url: '/o2o/user/info',
     method: 'get'
   },
   /*
   * 获取订单列表
-  *
   * http://avatar.yiguanjia.me/57fa0dee73.jpg
   * http://odulcd8g1.bkt.clouddn.com/57fa0dee73.jpg
-  *
   * @params {string} user_id
   * @params {number} type 1=>预约中;2=>已完成;3=>已取消
   * @params {number} page 1
@@ -25,10 +22,81 @@ const serviceModule = {
     url: 'o2o/order/list',
     method: 'post'
   },
+  addOrder: {
+    url: 'o2o/order/add',
+    method: 'post'
+  },
+  /*
+  * 用户注册
+  * @params {string} user_id
+  * @params {string} username
+  * @params {string} card_number
+  * @params {string} password
+  * */
   AddUserInfo: {
-    url: '/j/HouseKeeping/AddUserInfo',
+    url: 'construction/default/index',
+    method: 'get'
+  },
+  /*
+  * 获取商品列表
+  * */
+  getProductList: {
+    url: 'o2o/product/list',
+    method: 'get'
+  },
+  /*
+  * 短信验证码
+  * @params {number} type 3
+  * @params {number} mobile
+  * */
+  getSMSCode: {
+    url: '/moonclub/reserve/code',
+    method: 'get'
+  },
+  /*
+  * 根据城市获取地址
+  * @param {string=B349f0b32ef6e78b2e678f45cb9fddaf} ak
+  * @param {string=json} optput
+  * @param {string} region 搜索的城市
+  * @param {string} query 搜索地址
+  * */
+  getSuggestionList: {
+    url: 'https://bird.ioliu.cn/v1?url=http://api.map.baidu.com/place/v2/suggestion?',
     method: 'get'
   },
+  /*
+  * 添加地址
+  * @param {String} request_from:weixin
+  * @param {String} name
+  * @param {Number} mobile
+  * @param {String} user_id
+  * @param {String} user_id
+  * */
+  addAddress: {
+    url: 'api/shop/addAddress',
+    method: 'post'
+  },
+  editAddress: {
+    url: 'api/shop/editAddress',
+    method: 'post'
+  },
+  /*
+  * 检测用户地址是否在服务站范围内
+  * @param {Strting} user_id 用户ID
+  * @param {Strting} address_id 用户地址ID
+  * */
+  checkAddress: {
+    url: 'o2o/order/checkAddress',
+    method: 'get'
+  },
+  delAddress: {
+    url: 'api/shop/delAddress',
+    method: 'post'
+  },
+  pay: {
+    url: 'o2o/order/pay',
+    method: 'post'
+  }
 };
 const ApiSetting = { ...serviceModule };
 

+ 8 - 0
www/webapp/scg/src/lib/isDev.js

@@ -0,0 +1,8 @@
+export default function () {
+  const url = location.href;
+  let dev = false;
+  if (url.indexOf('common.yiguanjia.me') < 0) {
+    dev = true;
+  }
+  return dev;
+}

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 3 - 0
www/webapp/scg/src/lib/name.js


+ 442 - 0
www/webapp/scg/src/lib/product.js

@@ -0,0 +1,442 @@
+export default {
+  success: true,
+  message: 'true',
+  data: {
+    products: [
+      {
+        id: '57e3a5a49f5160c9048b457c',
+        price: '',
+        name: '母婴清洁',
+        desc: '[{"type":1,"content":"http://icon.yiguanjia.me/29650b1c3c7a91480490276220.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/7b40fe1b14fc1480490279077.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/d3e060f3ead4b1480490333346.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/28ef635fdf9061480490344521.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/9fdc93aa391761480490347557.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/eb27390e9e7a61480490350592.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/993949a8a718a1480490353292.jpg"}]',
+        status: 1,
+        is_extra: 0,
+        order: 200,
+        type: '8',
+        type_str: '母婴房清洁',
+        extra: [
+          {
+            type: '整间深度清洁',
+            price: '888'
+          },
+          {
+            type: '整间日常清洁',
+            price: '388'
+          }
+        ],
+        action_user: '',
+        action_time: '',
+        action_log: '',
+        pics: [
+          {
+            url: 'http://icon.yiguanjia.me/9ff6558673ea71500523539085.jpg',
+            width: 750,
+            height: 585
+          },
+          {
+            url: 'http://icon.yiguanjia.me/2de4b5863734f1500523545618.jpg',
+            width: 720,
+            height: 1327
+          },
+          {
+            url: 'http://icon.yiguanjia.me/2e5687d0a88751500523548579.jpg',
+            width: 720,
+            height: 545
+          },
+          {
+            url: 'http://icon.yiguanjia.me/dc23ea5821d9a1500523551017.jpg',
+            width: 720,
+            height: 1066
+          },
+          {
+            url: 'http://icon.yiguanjia.me/19b71d095f5b91500523564591.jpg',
+            width: 720,
+            height: 1024
+          }
+        ]
+      },
+      {
+        id: '57e0e0189f5160dc048b4568',
+        price: '',
+        name: '深度清洁',
+        desc: '[{ "type": 1,  "content": "http://icon.yiguanjia.me/e4c29bbe45c911475913783707.jpg"},{ "type": 1,  "content": "http://icon.yiguanjia.me/2aa238fb222661475913799166.jpg"},{ "type": 1,  "content": "http://icon.yiguanjia.me/e295c92da2e7c1475913803198.png"},{ "type": 1,  "content": "http://icon.yiguanjia.me/363f18ed617211475913944488.jpg"},{ "type": 1,  "content": "http://icon.yiguanjia.me/64a1375694e091475913947183.png"},{ "type": 1,  "content": "http://icon.yiguanjia.me/8cf32629eece91475913957779.png"}, { "type": 1,  "content": "http://icon.yiguanjia.me/0ef470cf13ea51475914131334.jpg"},{ "type": 1,  "content": "http://icon.yiguanjia.me/341746e8065381475978339748.jpg"},{ "type": 1,  "content": "http://icon.yiguanjia.me/beb99ec9850041475978342874.jpg"} ]',
+        status: 1,
+        is_extra: 0,
+        order: 2,
+        type: '2',
+        type_str: '深度清洁',
+        extra: [
+          {
+            type: '卧室清洁',
+            price: '188'
+          },
+          {
+            type: '客厅清洁',
+            price: '288'
+          },
+          {
+            type: '厨房清洁',
+            price: '388'
+          },
+          {
+            type: '卫生间清洁',
+            price: '188'
+          }
+        ],
+        action_user: '',
+        action_time: '',
+        action_log: '',
+        pics: [
+          {
+            url: 'http://icon.yiguanjia.me/1797607a982b21500523584641.jpg',
+            width: 750,
+            height: 585
+          },
+          {
+            url: 'http://icon.yiguanjia.me/4f335da2f5481500523587165.jpg',
+            width: 720,
+            height: 832
+          },
+          {
+            url: 'http://icon.yiguanjia.me/56b2b00de21511500523589215.jpg',
+            width: 720,
+            height: 1178
+          },
+          {
+            url: 'http://icon.yiguanjia.me/24167ab96746f1500523591257.jpg',
+            width: 720,
+            height: 473
+          },
+          {
+            url: 'http://icon.yiguanjia.me/29679ed29175e1500523605080.jpg',
+            width: 720,
+            height: 1204
+          }
+        ]
+      },
+      {
+        id: '57e0dffc9f5160dd048b4568',
+        price: '',
+        name: '日常清洁',
+        desc: '[{"type":1,"content":"http://icon.yiguanjia.me/15d8ec3241b41480492100598.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/5782ced3b6a221480492104947.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/0b4d8988278011480492111752.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/0b4f25923689b1480492121452.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/ec449c658a7a81480492126559.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/bdad1bc6934f81480492135364.jpg"}]',
+        status: 1,
+        is_extra: 0,
+        order: 1,
+        type: '1',
+        type_str: '日常清洁',
+        extra: [
+          {
+            type: '一室一卫',
+            price: '98'
+          },
+          {
+            type: '两室一卫',
+            price: '118'
+          },
+          {
+            type: '两室两卫',
+            price: '138'
+          },
+          {
+            type: '三室两卫',
+            price: '158'
+          },
+          {
+            type: '四室三卫',
+            price: '228'
+          },
+          {
+            type: '200-250平米',
+            price: '298'
+          },
+          {
+            type: '200-300平米',
+            price: '398'
+          },
+          {
+            type: '三层别墅',
+            price: '498'
+          },
+          {
+            type: '四层别墅',
+            price: '598'
+          },
+          {
+            type: '其他',
+            price: '1'
+          }
+        ],
+        action_user: '',
+        action_time: '',
+        action_log: '',
+        pics: [
+          {
+            url: 'http://icon.yiguanjia.me/7f212bc8efe831500523627492.jpg',
+            width: 750,
+            height: 585
+          },
+          {
+            url: 'http://icon.yiguanjia.me/27331c95fb2261500523632088.jpg',
+            width: 720,
+            height: 1127
+          },
+          {
+            url: 'http://icon.yiguanjia.me/4549043c51ad31500523635167.jpg',
+            width: 720,
+            height: 1178
+          },
+          {
+            url: 'http://icon.yiguanjia.me/ce1ef0e22dc931500523645931.jpg',
+            width: 720,
+            height: 520
+          },
+          {
+            url: 'http://icon.yiguanjia.me/0d3b572c069e91500523649185.gif',
+            width: 720,
+            height: 1158
+          }
+        ]
+      },
+      {
+        id: '57e0e0369f5160b1048b456b',
+        price: '',
+        name: '专业除螨',
+        desc: '[{"type":1,"content":"http://icon.yiguanjia.me/11cc40af11871480493869084.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/ea7a4586b5d2b1480494780841.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/57718bb459ea81480494783551.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/a1cf6e6da1db71480494785987.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/b875e4c126d041480494790474.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/f7a3590ed10f51480494806345.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/e244149a548451480494810267.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/757bcf11f3a451480494813003.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/d9405553aae8a1480494815467.jpg"}]',
+        status: 1,
+        is_extra: 0,
+        order: 0,
+        type: '3',
+        type_str: '除螨杀菌',
+        extra: [
+          {
+            type: '儿童床',
+            price: '80'
+          },
+          {
+            type: '布艺窗帘',
+            price: '100'
+          },
+          {
+            type: '整床除螨',
+            price: '180'
+          },
+          {
+            type: '布艺沙发',
+            price: '50'
+          }
+        ],
+        action_user: '',
+        action_time: '',
+        action_log: '',
+        pics: [
+          {
+            url: 'http://icon.yiguanjia.me/79cffb41d4c011500523673639.jpg',
+            width: 750,
+            height: 585
+          },
+          {
+            url: 'https://icon.yiguanjia.me/866141749a7221500523677347.jpg',
+            width: 720,
+            height: 832
+          },
+          {
+            url: 'http://icon.yiguanjia.me/0e2d0a08924a1500523681022.jpg',
+            width: 720,
+            height: 1697
+          },
+          {
+            url: 'http://icon.yiguanjia.me/5ad5109e340681500523684107.jpg',
+            width: 720,
+            height: 1204
+          }
+        ]
+      },
+      {
+        id: '57e0e04e9f5160af048b456b',
+        price: '',
+        name: '家电清洗',
+        desc: '[{"type":1,"content":"http://icon.yiguanjia.me/534317519e9b1480493689815.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/db190005bd9fc1480493702868.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/9c84cd5e00c5a1480493706280.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/de04da4b769a41480493709817.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/37b9518e8cfb51480493713410.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/b43780afa98691480493719152.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/7d55b5fe3c5e31480493723053.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/26353540295a41480493726622.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/17eed959130011480493729623.jpg"}]',
+        status: 1,
+        is_extra: 0,
+        order: 0,
+        type: '4',
+        type_str: '家电清洗',
+        extra: [
+          {
+            type: '微波炉',
+            price: '60'
+          },
+          {
+            type: '洗衣机',
+            price: '100'
+          },
+          {
+            type: '油烟机',
+            price: '120'
+          },
+          {
+            type: '挂式空调',
+            price: '100'
+          },
+          {
+            type: '立式空调',
+            price: '130'
+          },
+          {
+            type: '冰箱-单开门',
+            price: '100'
+          },
+          {
+            type: '冰箱-双开门',
+            price: '130'
+          }
+        ],
+        action_user: '',
+        action_time: '',
+        action_log: '',
+        pics: [
+          {
+            url: 'http://icon.yiguanjia.me/a4dc8d2541381500523702857.jpg',
+            width: 750,
+            height: 585
+          },
+          {
+            url: 'http://icon.yiguanjia.me/0f66d5802d05c1500523706243.jpg',
+            width: 720,
+            height: 844
+          },
+          {
+            url: 'http://icon.yiguanjia.me/36766992f4f2e1500523708676.jpg',
+            width: 720,
+            height: 1204
+          }
+        ]
+      },
+      {
+        id: '57e0e0879f5160b8048b4571',
+        price: '8',
+        name: '新居开荒',
+        desc: '[{"type":1,"content":"http://icon.yiguanjia.me/67b4871c13f781480493497023.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/b02e5765e45dc1480495231912.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/9f693fab851d61480495234559.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/2a7f5284e1eea1480495236431.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/08058efd85011480495238403.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/2c7f8c9e602bb1480495247880.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/5c449e8bbe7161480495250019.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/12a7fa370563b1480495252148.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/026a46e2bde0f1480495253918.jpg"}]',
+        status: 1,
+        is_extra: 0,
+        order: 0,
+        type: '6',
+        type_str: '新居开荒',
+        extra: [],
+        action_user: '',
+        action_time: '',
+        action_log: '',
+        pics: [
+          {
+            url: 'http://icon.yiguanjia.me/f779503941d941500523732301.jpg',
+            width: 750,
+            height: 585
+          },
+          {
+            url: 'http://icon.yiguanjia.me/4c3d505c72a291500523734883.jpg',
+            width: 720,
+            height: 654
+          },
+          {
+            url: 'http://icon.yiguanjia.me/ae9a8484065751500523737604.jpg',
+            width: 720,
+            height: 691
+          },
+          {
+            url: 'http://icon.yiguanjia.me/96e8b0424bda21500523740183.gif',
+            width: 720,
+            height: 558
+          },
+          {
+            url: 'http://icon.yiguanjia.me/7cd4392a4d9ac1500523742839.gif',
+            width: 720,
+            height: 306
+          }
+        ]
+      },
+      {
+        id: '57fb4a909f5160b2048b4a0e',
+        price: '10',
+        name: '擦玻璃',
+        desc: '[{"type":1,"content":"http://icon.yiguanjia.me/f8edd60a959da1480493218526.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/323188edb50cb1480493223005.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/8a2528607ef231480493226505.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/7b8bcb7ae71891480493229856.jpg"}]',
+        status: 1,
+        is_extra: 0,
+        order: 0,
+        type: '10',
+        type_str: '擦玻璃',
+        extra: [],
+        action_user: '',
+        action_time: '',
+        action_log: '',
+        pics: [
+          {
+            url: 'http://icon.yiguanjia.me/f90733e3ba9a51500523759715.jpg',
+            width: 750,
+            height: 585
+          },
+          {
+            url: 'http://icon.yiguanjia.me/49172465934811500523763351.jpg',
+            width: 720,
+            height: 820
+          },
+          {
+            url: 'http://icon.yiguanjia.me/faac0f58e40b51500523766805.jpg',
+            width: 720,
+            height: 829
+          },
+          {
+            url: 'http://icon.yiguanjia.me/c9918fb586dae1500523769439.jpg',
+            width: 720,
+            height: 1099
+          }
+        ]
+      },
+      {
+        id: '58085f4b9f5160a9048b490e',
+        price: '12',
+        name: '租房大扫除',
+        desc: '[{"type":1,"content":"http://icon.yiguanjia.me/7279bbc724e8c1480490663038.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/85b1c8466aa071480490672287.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/005fd813ba16e1480490676184.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/f3f60d0bae84b1480490679162.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/fb670ff173dc91480490682528.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/4af72d8222de11480490690122.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/eed8c9bedb58b1480490693776.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/6b95c86a172921480490696603.jpg"},{"type":1,"content":"http://icon.yiguanjia.me/02dc92eef9c7f1480490700649.jpg"}]',
+        status: 1,
+        is_extra: 0,
+        order: 0,
+        type: '5',
+        type_str: '民宿保洁',
+        extra: [],
+        action_user: '',
+        action_time: '',
+        action_log: '',
+        pics: [
+          {
+            url: 'http://icon.yiguanjia.me/944fc213e95041500523782518.jpg',
+            width: 750,
+            height: 585
+          },
+          {
+            url: 'http://icon.yiguanjia.me/5d1176e5c13311500523785187.jpg',
+            width: 720,
+            height: 840
+          },
+          {
+            url: 'http://icon.yiguanjia.me/fcbe8b95b069c1500523788434.jpg',
+            width: 720,
+            height: 822
+          },
+          {
+            url: 'http://icon.yiguanjia.me/66ac5c700c0451500523790605.jpg',
+            width: 720,
+            height: 1128
+          }
+        ]
+      }
+    ]
+  },
+  sum_count: 9999,
+  sum_page: 99,
+  page_size: null,
+  current_page: 1,
+  holiday: [
+    ''
+  ],
+  error_code: 200,
+  exec_time: 0.040411949157715,
+  memory_usage: '3,460KB'
+};

+ 14 - 8
www/webapp/scg/src/lib/userID.js

@@ -1,18 +1,24 @@
 export default function userId() {
-  const id = {
-    care: [
+  const id = [
       '57e245989f5160ca048b456f', // 余零雨
       '57eb6d449f5160a6048b46f9', // 焦孟骁
       '5befffbf9f5160c03c8b547b', // Sherry
       '5befd8d19f5160c03c8b5478', // Koala
       '5bef8e3e9f5160123e8b5451', // jjhuman
-    ],
-    client: [
-      '57e22bb59f5160c2048b456c', // charlie
       '57e237ea9f5160b6048b4568', // 陌上歌
       '57e238929f5160d6048b456d', // .
       '57e38f1b9f5160ac048b457d', // 塘下七武海-涛
-    ],
-  };
-  return localStorage.getItem('wxUserID1') != null ? localStorage.getItem('wxUserID1') : id.client[3];
+      '59e41443fb48a7552f8b459e', // 笨笨_8119619
+    ]
+  ;
+  return localStorage.getItem('wxUserID1') != null ? localStorage.getItem('wxUserID1') : id[7];
 }
+/*
+card: {
+      "card_number": "SCG0000001",
+      "index": NumberLong(10),
+      "password": "6086vbqf",
+      "status": NumberLong(0),
+      "_need_ruser_log": false
+    }
+*/

+ 279 - 0
www/webapp/scg/src/lib/util.js

@@ -0,0 +1,279 @@
+export default {
+  /**
+   * Determine if a value is an Array
+   *
+   * @param {Object} val The value to test
+   * @returns {boolean} True if value is an Array, otherwise false
+   */
+  isArray(val) {
+    return toString.call(val) === '[object Array]';
+  },
+  /**
+   * Determine if a value is an ArrayBuffer
+   *
+   * @param {Object} val The value to test
+   * @returns {boolean} True if value is an ArrayBuffer, otherwise false
+   */
+  isArrayBuffer(val) {
+    return toString.call(val) === '[object ArrayBuffer]';
+  },
+  /**
+   * Determine if a value is a FormData
+   *
+   * @param {Object} val The value to test
+   * @returns {boolean} True if value is an FormData, otherwise false
+   */
+  isFormData(val) {
+    return (typeof FormData !== 'undefined') && (val instanceof FormData);
+  },
+  /**
+   * Determine if a value is a view on an ArrayBuffer
+   *
+   * @param {Object} val The value to test
+   * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false
+   */
+  isArrayBufferView(val) {
+    let result;
+    if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {
+      result = ArrayBuffer.isView(val);
+    } else {
+      result = (val) && (val.buffer) && (val.buffer instanceof ArrayBuffer);
+    }
+    return result;
+  },
+  /**
+   * Determine if a value is a String
+   *
+   * @param {Object} val The value to test
+   * @returns {boolean} True if value is a String, otherwise false
+   */
+  isString(val) {
+    return typeof val === 'string';
+  },
+  /**
+   * Determine if a value is a Number
+   *
+   * @param {Object} val The value to test
+   * @returns {boolean} True if value is a Number, otherwise false
+   */
+  isNumber(val) {
+    return typeof val === 'number';
+  },
+  /**
+   * Determine if a value is undefined
+   *
+   * @param {Object} val The value to test
+   * @returns {boolean} True if the value is undefined, otherwise false
+   */
+  isUndefined(val) {
+    return typeof val === 'undefined';
+  },
+  /**
+   * Determine if a value is an Object
+   *
+   * @param {Object} val The value to test
+   * @returns {boolean} True if value is an Object, otherwise false
+   */
+  isObject(val) {
+    return val !== null && typeof val === 'object';
+  },
+  /**
+   * Determine if a value is a Date
+   *
+   * @param {Object} val The value to test
+   * @returns {boolean} True if value is a Date, otherwise false
+   */
+  isDate(val) {
+    return toString.call(val) === '[object Date]';
+  },
+  /**
+   * Determine if a value is a File
+   *
+   * @param {Object} val The value to test
+   * @returns {boolean} True if value is a File, otherwise false
+   */
+  isFile(val) {
+    return toString.call(val) === '[object File]';
+  },
+  /**
+   * Determine if a value is a Blob
+   *
+   * @param {Object} val The value to test
+   * @returns {boolean} True if value is a Blob, otherwise false
+   */
+  isBlob(val) {
+    return toString.call(val) === '[object Blob]';
+  },
+  /**
+   * Determine if a value is a Function
+   *
+   * @param {Object} val The value to test
+   * @returns {boolean} True if value is a Function, otherwise false
+   */
+  isFunction(val) {
+    return toString.call(val) === '[object Function]';
+  },
+  /**
+   * Determine if a value is a Stream
+   *
+   * @param {Object} val The value to test
+   * @returns {boolean} True if value is a Stream, otherwise false
+   */
+  isStream(val) {
+    return this.isObject(val) && this.isFunction(val.pipe);
+  },
+  /**
+   * Determine if a value is a URLSearchParams object
+   *
+   * @param {Object} val The value to test
+   * @returns {boolean} True if value is a URLSearchParams object, otherwise false
+   */
+  isURLSearchParams(val) {
+    return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams;
+  },
+  /**
+   * Trim excess whitespace off the beginning and end of a string
+   *
+   * @param {String} str The String to trim
+   * @returns {String} The String freed of excess whitespace
+   */
+  trim(str) {
+    return str.replace(/^\s*/, '')
+    .replace(/\s*$/, '');
+  },
+  /**
+   * Determine if we're running in a standard browser environment
+   *
+   * This allows axios to run in a web worker, and react-native.
+   * Both environments support XMLHttpRequest, but not fully standard globals.
+   *
+   * web workers:
+   *  typeof window -> undefined
+   *  typeof document -> undefined
+   *
+   * react-native:
+   *  navigator.product -> 'ReactNative'
+   */
+  isStandardBrowserEnv() {
+    if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {
+      return false;
+    }
+    return (
+      typeof window !== 'undefined' &&
+      typeof document !== 'undefined'
+    );
+  },
+  /**
+   * Iterate over an Array or an Object invoking a function for each item.
+   *
+   * If `obj` is an Array callback will be called passing
+   * the value, index, and complete array for each item.
+   *
+   * If 'obj' is an Object callback will be called passing
+   * the value, key, and complete object for each property.
+   *
+   * @param {Object|Array} obj The object to iterate
+   * @param {Function} fn The callback to invoke for each item
+   */
+  forEach(obj, fn) {
+    // Don't bother if no value provided
+    if (obj === null || typeof obj === 'undefined') {
+      return;
+    }
+    // Force an array if not already something iterable
+    if (typeof obj !== 'object') {
+      /* eslint no-param-reassign:0 */
+      obj = [obj];
+    }
+    if (this.isArray(obj)) {
+      // Iterate over array values
+      for (let i = 0, l = obj.length; i < l; i += 1) {
+        fn.call(null, obj[i], i, obj);
+      }
+    } else {
+      // Iterate over object keys
+      // eslint-disable-next-line
+      for (const key in obj) {
+        if (Object.prototype.hasOwnProperty.call(obj, key)) {
+          fn.call(null, obj[key], key, obj);
+        }
+      }
+    }
+  },
+  /**
+   * Accepts varargs expecting each argument to be an object, then
+   * immutably merges the properties of each object and returns result.
+   *
+   * When multiple objects contain the same key the later object in
+   * the arguments list will take precedence.
+   *
+   * Example:
+   *
+   * ```js
+   * var result = merge({foo: 123}, {foo: 456});
+   * console.log(result.foo); // outputs 456
+   * ```
+   *
+   * @param {Object} obj1 Object to merge
+   * @returns {Object} Result of all merge properties
+   */
+  merge(/* obj1, obj2, obj3, ... */) {
+    const result = {};
+
+    function assignValue(val, key) {
+      if (typeof result[key] === 'object' && typeof val === 'object') {
+        result[key] = this.merge(result[key], val);
+      } else {
+        result[key] = val;
+      }
+    }
+
+    for (let i = 0, l = arguments.length; i < l; i += 1) {
+      // eslint-disable-next-line
+      this.forEach(arguments[i], assignValue);
+    }
+    return result;
+  },
+  /**
+   * Extends object a by mutably adding to it the properties of object b.
+   *
+   * @param {Object} a The object to be extended
+   * @param {Object} b The object to copy properties from
+   * @param {Object} thisArg The object to bind function to
+   * @return {Object} The resulting value of object a
+   */
+  extend(a, b, thisArg) {
+    function assignValue(val, key) {
+      if (thisArg && typeof val === 'function') {
+        a[key] = this.bind(val, thisArg);
+      } else {
+        a[key] = val;
+      }
+    }
+
+    this.forEach(b, assignValue);
+    return a;
+  },
+  bind(fn, thisArg) {
+    return function wrap() {
+      const args = new Array(arguments.length);
+      for (let i = 0; i < args.length; i += 1) {
+        // eslint-disable-next-line
+        args[i] = arguments[i];
+      }
+      return fn.apply(thisArg, args);
+    };
+  },
+  /**
+   * 检测当前系统会否属于测试环境
+   * @return {Boolean} true 为测试环境;false 为生产环境
+   * */
+  isDev() {
+    const url = location.href;
+    let dev = false;
+    if (url.indexOf('common.yiguanjia.me') < 0) {
+      dev = true;
+    }
+    return dev;
+  }
+};

+ 11 - 4
www/webapp/scg/src/main.js

@@ -2,17 +2,24 @@
 // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
 import Vue from 'vue';
 import Cube from 'cube-ui';
-import userID from 'lib/userID';
 import addGlobalComponent from './components';
 import App from './App';
 import router from './router';
 import store from './store';
 
+Vue.use(addGlobalComponent);
 Vue.use(Cube);
-Vue.prototype.userID = userID();
-addGlobalComponent(Vue);
-Vue.config.productionTip = false;
 
+Vue.config.productionTip = false;
+router.beforeEach((to, from, next) => {
+  // ...
+  console.log(`${from.name}-->${to.name}`);
+  store.state.addressRouter = {
+    from: from.name,
+    to: to.name
+  };
+  next();
+});
 /* eslint-disable no-new */
 new Vue({
   el: '#app',

+ 47 - 0
www/webapp/scg/src/router/index.js

@@ -2,8 +2,15 @@ import Vue from 'vue';
 import Router from 'vue-router';
 import home from 'views/home/index';
 import order from 'views/order/index';
+import product from 'views/product/index';
+import addOrder from 'views/order/addOrder';
+import orderDetail from 'views/order/detail';
 import mine from 'views/mine/index';
+import login from 'views/login/index';
 import address from 'views/address/index';
+import addressEdit from 'views/address/edit';
+import addressPosition from 'views/address/position';
+import pay from 'views/pay/index';
 
 Vue.use(Router);
 
@@ -14,11 +21,36 @@ export default new Router({
       name: 'home',
       component: home,
     },
+    {
+      path: '/login',
+      name: 'login',
+      component: login,
+    },
     {
       path: '/order',
       name: 'order',
       component: order,
     },
+    {
+      path: '/order/add',
+      name: 'addOrder',
+      component: addOrder,
+    },
+    {
+      path: '/product',
+      name: 'product',
+      component: product,
+    },
+    {
+      path: '/order/detail',
+      name: 'orderDetail',
+      component: orderDetail,
+    },
+    {
+      path: '/pay',
+      name: 'pay',
+      component: pay,
+    },
     {
       path: '/mine',
       name: 'mine',
@@ -29,5 +61,20 @@ export default new Router({
       name: 'address',
       component: address,
     },
+    {
+      path: '/address/edit',
+      name: 'addressEdit',
+      component: addressEdit,
+    },
+    {
+      path: '/address/edit',
+      name: 'addressEdit',
+      component: addressEdit,
+    },
+    {
+      path: '/address/position',
+      name: 'addressPosition',
+      component: addressPosition,
+    },
   ],
 });

+ 182 - 7
www/webapp/scg/src/store.js

@@ -2,30 +2,205 @@ import Vue from 'vue';
 import Vuex from 'vuex';
 import http from 'api';
 import ApiSetting from 'lib/baseUrl';
+import userID from 'lib/userID';
+import util from 'lib/util';
+import Name from 'lib/name';
+import {
+  createAPI, Dialog
+} from 'cube-ui';
 
-Vue.use(Vuex);
+// 创建 this.$createHello and $Hello.create API
+createAPI(Vue, Dialog, ['click'], true);
 
+Vue.use(Vuex);
+// const { log: print } = console;
 export default new Vuex.Store({
   state: {
-    userInfo: ''
+    user_id: userID(),
+    isDev: util.isDev(),
+    userInfo: {},
+    ifLogin: '',
+    name: Name,
+    addressRouter: {},
+    addressInformation: {},
+    order: {},
+    product: {},
+    productList: {}
   },
   getters: {
-    getUserInfo: state => state.userInfo
+    getUserInfo: state => state.userInfo,
+    getIfLogin: state => state.ifLogin
   },
   mutations: {
     getUserInfo(state) {
+      const self = state;
       http(ApiSetting.GetUserInfo, {
-        user_id: Vue.prototype.userID
-      }).then(res => {
+        user_id: state.user_id
+      })
+      .then(res => {
         // eslint-disable-next-line
-        state.userInfo = res;
-        // console.log(res);
+        self.userInfo = res;
+        if (self.userInfo.avatar.indexOf('odulcd8g1.bkt.clouddn.com')) {
+          self.userInfo.avatar = self.userInfo.avatar.replace(/odulcd8g1\.bkt\.clouddn\.com/, 'avatar.yiguanjia.me');
+        }
+      })
+      .then(() => {
+        if (self.userInfo.source === '建工' && self.userInfo.user_info.phone !== '' && self.userInfo.type === '微信') {
+          self.ifLogin = false;
+        } else {
+          self.ifLogin = true;
+        }
+      })
+      .then(() => {
+        // console.log('准备获取商品列表');
+        // self.productList = product.data.products;
+        http(ApiSetting.getProductList)
+        .then(res => {
+          console.log(res);
+          const products = {};
+          res.products.forEach((key, i) => {
+            products[i] = key;
+            products[i].pics.forEach((p, index) => {
+              products[i].pics[index].url = products[i].pics[index].url.replace(/oduj3utzz\.bkt\.clouddn\.com/, 'icon.yiguanjia.me');
+            });
+          });
+          self.productList = products;
+        });
+      });
+    },
+    addOrder(state) {
+      // 检测用户地址是否在服务范围内
+      // http(ApiSetting.checkAddress, {
+      //   user_id: this.$store.state.userInfo.id,
+      //   address_id: this.order.address.address_id
+      // })
+      //   .then(res=>{
+      //
+      //   })
+      console.log(state.order);
+      console.log(state.userInfo);
+      console.log(state.product);
+      const json = {
+        balance: state.userInfo.balance,
+        products: JSON.stringify({
+          product_id: state.product.id,
+          count: state.order.num
+        }),
+        memo: state.order.remarks !== undefined ? state.order.remarks : '',
+        precedence: '0',
+        booking_time: `${state.order.time.other.selectedVal[0]}-${state.order.time.other.selectedVal[1]}-${state.order.time.other.selectedVal[2]} ${state.order.time.other.selectedVal[3] === 9 ? '09' : state.order.time.other.selectedVal[3]}:00`,
+        address_id: state.order.address.address_id,
+        station: state.order.station,
+        type: state.product.type,
+        counts: state.order.num,
+        extra: `[${JSON.stringify(state.order.active.extra)}]`,
+        order_channel: 'wx_pub',
+        user_id: ''
+      };
+      console.log(json);
+      /* http(ApiSetting.addOrder,{
+        balance: state.userInfo.balance,
+        products: JSON.stringify({
+          product_id:state.product.id.
+          count: state.order.num
+        }),
+        memo: this.order.remarks!==undefined?this.order.remarks:'',
+        precedence: '0',
+        booking_time: this.bookingDate + ' ' + this.bookingTime + ':00',
+        address_id: this.order.address.address_id,
+        coupons: JSON.stringify(coupons),
+        station: this.stationID,
+        type: this.productType,
+        counts: this.productCount,
+        extra: extraJson,
+        tech_id: this.beautician.id,
+        user_id: userID,
+        order_channel: channel
+      }) */
+    },
+    addAddress(state) {
+      console.log(state);
+      const that = state;
+      http(ApiSetting.addAddress, {
+        request_from: 'weixin',
+        name: that.addressInformation.name,
+        mobile: that.addressInformation.mobile,
+        user_id: userID(),
+        address_position: JSON.stringify(that.addressInformation.addressPosition),
+        address: JSON.stringify(that.addressInformation.addressDetail)
+      })
+      .then(() => {
+        this.commit('dialog', '地址添加成功!');
+      });
+    },
+    editAddress(state) {
+      const that = state;
+      http(ApiSetting.editAddress, {
+        request_from: 'weixin',
+        name: that.addressInformation.name,
+        mobile: that.addressInformation.mobile,
+        user_id: userID(),
+        address_id: that.addressInformation.address_id,
+        address_position: JSON.stringify(that.addressInformation.addressPosition),
+        address: JSON.stringify(that.addressInformation.addressDetail)
+      })
+      .then(() => {
+        this.commit('dialog', '地址编辑成功!');
+      });
+    },
+    delAddress(state) {
+      const that = state;
+      http(ApiSetting.delAddress, {
+        user_id: userID(),
+        request_from: 'weixin',
+        address_id: that.addressInformation.address_id
+      })
+      .then(() => {
+        this.commit('dialog', '地址删除成功!');
+      });
+    },
+    pay(state) {
+      const that = state;
+      http(ApiSetting.pay, {
+        user_id: userID(),
+        order_id: that.order.order_id,
+        pay_channel: 'wx_pub'
+      })
+      .then(res => {
+        console.log(res);
+      });
+    },
+    dialog(state, msg) {
+      this.dispatch('getUserInfo');
+      const dialog = Dialog.$create({
+        type: 'alert',
+        // title: '成功',
+        content: msg,
+        onConfirm: () => {
+          window.history.go(-1);
+        }
       });
+      dialog.show();
     }
   },
   actions: {
     getUserInfo({ commit }) {
       commit('getUserInfo');
+    },
+    addAddress({ commit }) {
+      commit('addAddress');
+    },
+    editAddress({ commit }) {
+      commit('editAddress');
+    },
+    delAddress({ commit }) {
+      commit('delAddress');
+    },
+    pay({ commit }) {
+      commit('pay');
+    },
+    addOrder({ commit }) {
+      commit('addOrder');
     }
   },
 });

+ 28 - 27
www/webapp/scg/src/theme.styl

@@ -1,8 +1,9 @@
 @require "~cube-ui/src/common/stylus/var/color.styl"
-
+h-color-orange = #927603
+h-color-dark-orange = #a68a03
 // action-sheet
 $action-sheet-color := $color-grey
-$action-sheet-active-color := $color-orange
+$action-sheet-active-color := h-color-orange
 $action-sheet-bgc := $color-white
 $action-sheet-active-bgc := $color-light-grey-opacity
 $action-sheet-title-color := $color-dark-grey
@@ -17,8 +18,8 @@ $btn-bgc := $color-regular-blue
 $btn-active-bgc := $color-blue
 /// primary
 $btn-primary-color := $color-white
-$btn-primary-bgc := $color-orange
-$btn-primary-active-bgc := $color-dark-orange
+$btn-primary-bgc := h-color-orange
+$btn-primary-active-bgc := h-color-dark-orange
 /// light
 $btn-light-color := $color-grey
 $btn-light-bgc := $color-light-grey-sss
@@ -30,11 +31,11 @@ $btn-outline-bdc := $color-grey
 $btn-outline-active-bgc := $color-grey-opacity
 $btn-outline-active-bdc := $color-grey
 /// outline-primary
-$btn-outline-primary-color := $color-orange
+$btn-outline-primary-color := h-color-orange
 $btn-outline-primary-bgc := transparent
-$btn-outline-primary-bdc := $color-orange
-$btn-outline-primary-active-bgc := $color-orange-opacity
-$btn-outline-primary-active-bdc := $color-dark-orange
+$btn-outline-primary-bdc := h-color-orange
+$btn-outline-primary-active-bgc := h-color-orange-opacity
+$btn-outline-primary-active-bdc := h-color-dark-orange
 /// disabled
 $btn-disabled-color := $color-white
 $btn-disabled-bgc := $color-light-grey-s
@@ -48,13 +49,13 @@ $toolbar-active-bgc := $color-active-grey
 $checkbox-color := $color-grey
 $checkbox-icon-color := $color-light-grey-s
 /// checked
-$checkbox-checked-icon-color := $color-orange
+$checkbox-checked-icon-color := h-color-orange
 $checkbox-checked-icon-bgc := $color-white
 /// disabled
 $checkbox-disabled-icon-color := $color-light-grey-ss
 $checkbox-disabled-icon-bgc := $color-light-grey-ss
 // checkbox hollow
-$checkbox-hollow-checked-icon-color := $color-orange
+$checkbox-hollow-checked-icon-color := h-color-orange
 $checkbox-hollow-disabled-icon-color := $color-light-grey-ss
 // checkbox-group
 $checkbox-group-bgc := $color-white
@@ -67,19 +68,19 @@ $radio-color := $color-grey
 $radio-icon-color := $color-light-grey-s
 /// selected
 $radio-selected-icon-color := $color-white
-$radio-selected-icon-bgc := $color-orange
+$radio-selected-icon-bgc := h-color-orange
 /// disabled
 $radio-disabled-icon-bgc := $color-light-grey-ss
 // radio hollow
-$radio-hollow-selected-icon-color := $color-orange
+$radio-hollow-selected-icon-color := h-color-orange
 $radio-hollow-disabled-icon-color := $color-light-grey-ss
 
 //checker
 $checker-item-color := $color-grey
 $checker-item-bdc := $color-light-grey-sss
 $checker-item-bgc := $color-white
-$checker-item-active-color := $color-orange
-$checker-item-active-bdc := $color-orange
+$checker-item-active-color := h-color-orange
+$checker-item-active-bdc := h-color-orange
 $checker-item-active-bgc := $color-light-orange-opacity
 
 // dialog
@@ -92,7 +93,7 @@ $dialog-close-color := $color-light-grey
 $dialog-btn-color := $color-light-grey
 $dialog-btn-bgc := $color-white
 $dialog-btn-active-bgc := $color-light-grey-opacity
-$dialog-btn-highlight-color := $color-orange
+$dialog-btn-highlight-color := h-color-orange
 $dialog-btn-highlight-active-bgc := $color-light-orange-opacity
 $dialog-btn-disabled-color := $color-light-grey
 $dialog-btn-disabled-active-bgc := transparent
@@ -106,13 +107,13 @@ $index-list-anchor-bgc := #f7f7f7
 $index-list-item-color := $color-dark-grey
 $index-list-item-active-bgc := $color-light-grey-opacity
 $index-list-nav-color := $color-grey
-$index-list-nav-active-color := $color-orange
+$index-list-nav-active-color := h-color-orange
 
 // picker
 $picker-bgc := $color-white
 $picker-title-color := $color-dark-grey
 $picker-subtitle-color := $color-light-grey
-$picker-confirm-btn-color := $color-orange
+$picker-confirm-btn-color := h-color-orange
 $picker-confirm-btn-active-color := $color-light-orange
 $picker-cancel-btn-color := $color-light-grey
 $picker-cancel-btn-active-color := $color-light-grey-s
@@ -124,7 +125,7 @@ $popup-mask-opacity := .4
 
 // slide
 $slide-dot-bgc := $color-light-grey-s
-$slide-dot-active-bgc := $color-orange
+$slide-dot-active-bgc := h-color-orange
 
 // time-picker
 
@@ -146,13 +147,13 @@ $upload-file-bgc := $color-white
 $upload-file-remove-color := rgba(0, 0, 0, .8)
 $upload-file-remove-bgc := $color-white
 $upload-file-state-bgc := $color-mask-bg
-$upload-file-success-color := $color-orange
+$upload-file-success-color := h-color-orange
 $upload-file-error-color := #f43530
 $upload-file-status-bgc := $color-white
 $upload-file-progress-color := $color-white
 
 // switch
-$switch-on-bgc := $color-orange
+$switch-on-bgc := h-color-orange
 $switch-off-bgc := $color-white
 $switch-off-border-color := #e4e4e4
 
@@ -160,7 +161,7 @@ $switch-off-border-color := #e4e4e4
 $input-color := $color-grey
 $input-bgc := $color-white
 $input-border-color := $color-row-line
-$input-focus-border-color := $color-orange
+$input-focus-border-color := h-color-orange
 $input-placeholder-color := $color-light-grey-s
 $input-clear-icon-color := $color-light-grey
 
@@ -168,8 +169,8 @@ $input-clear-icon-color := $color-light-grey
 $textarea-color := $color-grey
 $textarea-bgc := $color-white
 $textarea-border-color := $color-row-line
-$textarea-focus-border-color := $color-orange
-$textarea-outline-color := $color-orange
+$textarea-focus-border-color := h-color-orange
+$textarea-outline-color := h-color-orange
 $textarea-placeholder-color := $color-light-grey-s
 $textarea-indicator-color := $color-light-grey-s
 
@@ -182,7 +183,7 @@ $select-bgc := $color-white
 $select-disabled-color := #b8b8b8
 $select-disabled-bgc := $color-light-grey-opacity
 $select-border-color := $color-light-grey-s
-$select-border-active-color := $color-orange
+$select-border-active-color := h-color-orange
 $select-icon-color := $color-light-grey
 $select-placeholder-color := $color-light-grey-s
 
@@ -207,12 +208,12 @@ $drawer-item-active-bgc := $color-light-grey-opacity
 // scroll-nav
 $scroll-nav-bgc := $color-white
 $scroll-nav-color := $color-grey
-$scroll-nav-active-color := $color-orange
+$scroll-nav-active-color := h-color-orange
 
 // image-preview
 $image-preview-counter-color := $color-white
 
 // tab-bar & tab-panel
 $tab-color := $color-grey
-$tab-active-color := $color-dark-orange
-$tab-slider-bgc := $color-dark-orange
+$tab-active-color := h-color-dark-orange
+$tab-slider-bgc := h-color-dark-orange

+ 191 - 0
www/webapp/scg/src/views/address/edit.vue

@@ -0,0 +1,191 @@
+<template>
+  <div class="edit-wrapper">
+    <h-header :isAddress="true" @back="back" :title="name"></h-header>
+    <div class="edit">
+      <cube-input @focus="focus" @blur="blur" v-model="addressInformation.name" placeholder="怎么称呼您">
+        <div slot="prepend">姓&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;名</div>
+      </cube-input>
+      <cube-input @focus="focus" @blur="blur" v-model="addressInformation.mobile" placeholder="您的手机号">
+        <div slot="prepend">手&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;机</div>
+      </cube-input>
+      <div class="cube-input location" @click="search">
+        <div class="cube-input-field">{{location}}</div>
+        <div class="cube-input-append">
+          <i class="cubeic-arrow"></i>
+        </div>
+      </div>
+      <cube-input @focus="focus" @blur="blur" placeholder="填写详细地址如15号楼1单元201室" v-model="addressInformation.address.detail">
+        <div slot="prepend">详细地址</div>
+      </cube-input>
+    </div>
+    <div class="btn-wrapper" v-if="isBlur">
+      <cube-button :primary="true" @click="edit" v-if="isEdit">更新地址</cube-button>
+      <cube-button :primary="true" @click="del" v-if="isEdit">删除地址</cube-button>
+      <cube-button :primary="true" @click="add" v-else>添加地址</cube-button>
+    </div>
+  </div>
+</template>
+<script>
+  export default {
+    name: 'edit',
+    data() {
+      return {
+        name: '',
+        isEdit: false,
+        isBlur: true,
+        location: '',
+        addressInformation: {
+          name: '',
+          mobile: '',
+          address: {
+            detail: ''
+          }
+        },
+      };
+    },
+    created() {
+      if (JSON.stringify(this.$store.state.addressInformation) === '{}') {
+        this.$router.push({ name: 'address' });
+      }
+      // isEdit
+      this.isEdit = this.$store.state.addressInformation.isEdit;
+      this.location = this.isEdit ? this.$store.state.addressInformation.address.poi.name : '请定位您的小区或者街道';
+      this.name = this.isEdit ? '编辑地址' : '添加地址';
+      // 定位之后,数据绑定
+      if (this.$store.state.addressInformation.addressPosition) {
+        this.copy(this.addressInformation, this.$store.state.addressInformation);
+      }
+      if (this.isEdit) {
+        this.copy(this.addressInformation, this.$store.state.addressInformation);
+      }
+      if (!this.isEdit && this.$store.state.addressInformation.addressDetail) {
+        this.location = this.$store.state.addressInformation.addressDetail.poi.name;
+      }
+    },
+    methods: {
+      search() {
+        this.copy(this.$store.state.addressInformation, this.addressInformation);
+        this.$router.push({
+          name: 'addressPosition',
+          query: {
+            location: this.location
+          }
+        });
+      },
+      add() {
+        if (this.test()) {
+          this.$store.state.addressInformation.addressDetail.detail = this.addressInformation.address.detail;
+          this.$store.state.addressInformation.name = this.addressInformation.name;
+          this.$store.state.addressInformation.mobile = this.addressInformation.mobile;
+          this.$store.dispatch('addAddress');
+        }
+      },
+      edit() {
+        if (!this.$store.state.addressInformation.addressPosition) {
+          const addressPosition = this.$store.state.addressInformation.position;
+          this.$store.state.addressInformation.addressPosition = addressPosition;
+        }
+        if (!this.$store.state.addressInformation.addressDetail) {
+          const addressDetail = {
+            province: this.addressInformation.address.province,
+            city: this.addressInformation.address.city,
+            area: this.addressInformation.address.area,
+            detail: this.addressInformation.address.detail,
+            poi: this.addressInformation.address.poi
+          };
+          this.$store.state.addressInformation.addressDetail = addressDetail;
+        }
+        if (this.test()) {
+          this.$store.dispatch('editAddress');
+        }
+      },
+      del() {
+        this.$store.dispatch('delAddress');
+      },
+      test() {
+        if (this.addressInformation.name === '') {
+          this.$createDialog({
+            type: 'alert',
+            title: '提示',
+            content: '请输入您的名字'
+          })
+            .show();
+          return false;
+        }
+        if (this.addressInformation.mobile.length !== 11) {
+          this.$createDialog({
+            type: 'alert',
+            title: '提示',
+            content: '请输入正确的手机号'
+          })
+            .show();
+          return false;
+        }
+        if (this.addressInformation.address.detail === '') {
+          this.$createDialog({
+            type: 'alert',
+            title: '提示',
+            content: '请输入您的详细地址'
+          })
+            .show();
+          return false;
+        }
+        if (!this.$store.state.addressInformation.addressPosition || !this.$store.state.addressInformation.addressDetail) {
+          this.$createDialog({
+            type: 'alert',
+            title: '错误',
+            content: '请定位您的小区或者街道'
+          })
+            .show();
+          return false;
+        }
+        return true;
+      },
+      copy(obj1, obj2) {
+        const obj = obj1;
+        Object.keys(this.addressInformation)
+          .forEach(key => {
+            obj[key] = obj2[key];
+          });
+        // Object.keys(this.$store.state.addressInformation)
+        //   .forEach(key => {
+        //     this.addressInformation[key] = this.$store.state.addressInformation[key];
+        //   });
+      },
+      back() {
+        this.$router.go(-1);
+      },
+      focus() {
+        this.isBlur = true;
+      },
+      blur() {
+        this.isBlur = true;
+        // setTimeout(() => {
+        //   this.isBlur = true;
+        // }, 300);
+      }
+    }
+  };
+</script>
+<style lang="stylus">
+  .edit-wrapper
+    .edit
+      .cube-input
+        margin-top 10px
+      .cube-input-prepend
+        padding-left 15px
+      .location
+        text-align left
+        padding-right: 15px
+        .cube-input-field
+          color black
+          padding-left: 15px
+    .btn-wrapper
+      position fixed
+      display flex
+      bottom: 10px
+      left: 5px
+      right: 5px
+      > button
+        margin: 0 5px
+</style>

+ 90 - 7
www/webapp/scg/src/views/address/index.vue

@@ -1,21 +1,104 @@
 <template>
-  <div class="order-wrapper">
-    这里是地址
-    <tabBar/>
+  <div class="address-wrapper" v-if="userInfo && userInfo.shop_address">
+    <div class="row">
+      <cube-scroll ref="scroll">
+        <div class="address" v-for="(item,index) in userInfo.shop_address" :key="index" @click="select(item)">
+          <div class="left">
+            <div class="header">
+              <span class="user-name">{{item.name}}</span>
+              <span class="user-mobile">{{item.mobile}}</span>
+            </div>
+            <div class="footer">{{item.address.city}} {{item.address.area}} {{item.address.detail}}</div>
+          </div>
+          <div class="right">
+            <cube-button @click.stop="edit(item)" :inline="true" :primary="true">编辑</cube-button>
+          </div>
+        </div>
+      </cube-scroll>
+    </div>
+    <cube-button :primary="true" @click="addAddress">添加地址</cube-button>
   </div>
 </template>
 <script>
+  import { mapGetters } from 'vuex';
+  import hEdit from './edit';
+
   export default {
     name: 'order',
     data() {
-      return {};
+      return {
+        addressRouter: {},
+      };
     },
     created() {
+      this.addressRouter = this.$store.state.addressRouter;
+    },
+    computed: {
+      ...mapGetters({
+        userInfo: 'getUserInfo'
+      })
+    },
+    components: {
+      hEdit
+    },
+    methods: {
+      select(address) {
+        if (this.addressRouter.from === null) {
+          this.$router.push({ name: 'mine' });
+          return;
+        }
+        this.$store.state.order.address = address;
+        // console.log(this.addressRouter);
+        // this.$router.push({ name: this.addressRouter.from });
+        this.$router.go(-1);
+      },
+      edit(address) {
+        const userAddress = address;
+        userAddress.isEdit = true;
+        this.$router.push({
+          name: 'addressEdit'
+        });
+        Object.keys(userAddress)
+          .forEach(key => {
+            this.$store.state.addressInformation[key] = userAddress[key];
+          });
+      },
+      addAddress() {
+        this.$store.state.addressInformation = {
+          isEdit: false
+        };
+        this.$router.push({
+          name: 'addressEdit',
+        });
+      },
     },
-    methods: {},
   };
 </script>
 <style lang="stylus" scoped>
-  .order-wrapper
-    background-color #0aa9dc
+  .address-wrapper
+    .row
+      height calc(100vh - 80px)
+      padding: 15px
+    .address
+      background url("http://pics.yiguanjia.me/mine-%E5%BA%95%E7%BA%B9.jpg")
+      background-size: 100%
+      border-radius: 0
+      color: rgba(233, 233, 216, 1)
+      position: relative
+      text-align: left
+      display flex
+      justify-content space-between
+      padding: 15px
+      margin-bottom: 15px
+      .left
+        .header
+          color white
+        .footer
+          margin-top: 10px
+          color #777
+          font-size otherSize
+      .right
+        flex 0 0 40px
+        display flex
+        align-items center
 </style>

+ 107 - 0
www/webapp/scg/src/views/address/position.vue

@@ -0,0 +1,107 @@
+<template>
+  <div class="position-wrapper">
+    <h-header :isAddress="true" @back="back" title="定位地点"></h-header>
+    <div class="search-wrapper">
+      <div class="search">
+        <cube-input v-model="location" placeholder="请定位您的小区或者街道">
+          <i class="cubeic-search" slot="prepend"></i>
+          <cube-button slot="append" :primary="true" @click="search">搜索</cube-button>
+        </cube-input>
+      </div>
+      <div class="position-wrapper border-top-1px">
+        <cube-scroll ref="scroll" :options="options">
+          <div class="position border-bottom-1px" v-for="item in result" @click="callback(item)">
+            <p>{{item.city}}&nbsp;&nbsp;{{item.district}}</p>
+            <div>{{item.name}}</div>
+          </div>
+        </cube-scroll>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+  import http from 'api';
+  import ApiSetting from 'lib/baseUrl';
+
+  export default {
+    name: 'position',
+    data() {
+      return {
+        location: '',
+        result: [],
+        userLocation: '上海市',
+        options: {
+          click: true
+        }
+      };
+    },
+    created() {
+      if (this.$route.query.location !== '请定位您的小区或者街道') {
+        this.location = this.$route.query.location;
+      }
+      if (this.location !== '') {
+        this.search();
+      }
+    },
+    methods: {
+      search() {
+        const toast = this.$createToast({
+          txt: '查询中...',
+          mask: true
+        });
+        toast.show();
+        http(ApiSetting.getSuggestionList, {
+          ak: 'B349f0b32ef6e78b2e678f45cb9fddaf',
+          output: 'json',
+          region: this.userLocation,
+          query: this.location
+        })
+        .then(res => {
+          setTimeout(() => {
+            toast.hide();
+            this.scroll.refresh();
+          }, 300);
+          this.result = res.result;
+        });
+      },
+      callback(info) {
+        const addressPosition = {
+          lat: info.location.lat,
+          lng: info.location.lng
+        };
+        const addressDetail = {
+          province: info.province,
+          city: info.city,
+          area: info.district,
+          detail: this.$store.state.addressInformation.address.detail,
+          poi: {
+            uid: info.uid,
+            name: info.name
+          }
+        };
+        this.$store.state.addressInformation.addressPosition = addressPosition;
+        this.$store.state.addressInformation.addressDetail = addressDetail;
+        console.log(this.$store.state.addressInformation.address);
+        this.back();
+      },
+      back() {
+        this.$router.go(-1);
+      }
+    }
+  };
+</script>
+<style lang="stylus">
+  .position-wrapper
+    .search-wrapper
+      .search
+        .cube-input-prepend
+          margin: 0 5px
+      .position-wrapper
+        height calc(100vh - 94px)
+        overflow hidden
+        .position
+          padding 15px
+          text-align left
+          div
+            padding-top 5px
+</style>

+ 7 - 2
www/webapp/scg/src/views/home/index.vue

@@ -8,7 +8,6 @@
 </template>
 
 <script>
-  // import tabBar from '@/components/tabBar.vue';
   import HomeList from './list';
 
   export default {
@@ -24,6 +23,12 @@
         },
       };
     },
+    created() {
+      // 判断用户是否注册
+      if (this.$store.state.ifLogin) {
+        this.$router.push({ name: 'login' });
+      }
+    },
     components: {
       HomeList
     },
@@ -39,7 +44,7 @@
 
   };
 </script>
-<style lang="stylus">
+<style lang="stylus" scoped>
   .home
     .banner
       width 100%

+ 13 - 7
www/webapp/scg/src/views/home/list.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="list-box">
-    <div v-for="(item, index) in productIcon" :key="index" @click="test">
+    <div v-for="(item, index) in productIcon" :key="index" @click="toProduct(item)">
       <div class="icon">
         <img :src="item.url" :alt="item.title">
       </div>
@@ -65,14 +65,22 @@
       };
     },
     methods: {
-      test() {
-        // console.log(69);
+      toProduct(info) {
+        console.log(info);
+        // Object.keys(this.$store.state.productList)
+        //   .forEach(key => {
+        //     if (this.$store.state.productList[key].name === info.title) {
+        //       this.$store.state.product = this.$store.state.productList[key];
+        //     }
+        //   });
+        // // console.log(this.$store.state.product);
+        // this.$store.state.order = {};
+        // this.$router.push({ name: 'product' });
       }
     }
-
   };
 </script>
-<style lang="stylus">
+<style lang="stylus" scoped>
   len = 15px
   .list-box
     display grid
@@ -81,11 +89,9 @@
     grid-column-gap len
     grid-row-gap len
     padding-bottom: 70px
-
     & > div
       .icon > img
         width 100%
-
       .title
         margin-top: 5px
 </style>

+ 200 - 0
www/webapp/scg/src/views/login/index.vue

@@ -0,0 +1,200 @@
+<template>
+  <div class="login-wrapper">
+    <h-header title="注册"></h-header>
+    <div class="from-wrapper">
+      <cube-input type="text" v-model="user.name">
+        <div slot="prepend">姓&nbsp;&nbsp;&nbsp;名</div>
+      </cube-input>
+      <cube-input type="text" v-model="user.phone">
+        <div slot="prepend">手&nbsp;&nbsp;&nbsp;机</div>
+      </cube-input>
+      <cube-input type="text" :maxlength="4" v-model="code.sbm.user">
+        <div slot="prepend">识别码</div>
+        <input
+          type="button"
+          @click='getCreateCode'
+          :value="code.sbm.scg"
+          class="v-code"
+          slot="append">
+      </cube-input>
+      <cube-input type="text" :maxlength="4" v-model="code.dxm.user">
+        <div slot="prepend">短信码</div>
+        <cube-button slot="append" @click="getSMS" :inline="true">获取</cube-button>
+      </cube-input>
+      <cube-input type="text" :maxlength="10" v-model="user.card_number">
+        <div slot="prepend">卡&nbsp;&nbsp;&nbsp;号</div>
+      </cube-input>
+      <cube-input type="password" :maxlength="8" v-model="user.password">
+        <div slot="prepend">卡&nbsp;&nbsp;&nbsp;密</div>
+      </cube-input>
+      <cube-button @click="submit" :primary="true">提交</cube-button>
+    </div>
+  </div>
+</template>
+<script type="text/ecmascript-6">
+  import http from 'api';
+  import ApiSetting from 'lib/baseUrl';
+  import { mapActions } from 'vuex';
+
+  export default {
+    name: 'login',
+    data() {
+      return {
+        code: {
+          sbm: {
+            user: '',
+            scg: ''
+          },
+          dxm: {
+            user: '',
+            scg: ''
+          },
+          end_time: ''
+        },
+        user: {
+          name: '',
+          phone: '',
+          card_number: '',
+          password: ''
+        }
+      };
+    },
+    created() {
+      // 初始化识别码
+      this.getCreateCode();
+    },
+    methods: {
+      ...mapActions(['getUserInfo']),
+      getSMS() {
+        if (this.test('sms')) {
+          http(ApiSetting.getSMSCode, {
+            user_id: this.userID,
+            type: 3,
+            mobile: this.user.phone,
+          }).then(res => {
+            this.code.dxm.scg = res.code;
+            if (this.$store.state.ifDev) {
+              this.code.dxm.user = `${res.code}`;
+            }
+          }).catch(err => {
+            console.log(err);
+          });
+        }
+      },
+      submit() {
+        if (!this.test()) return;
+        http(ApiSetting.AddUserInfo, {
+          user_id: this.$store.state.user_id,
+          username: this.user.name,
+          phone: this.user.phone,
+          card_number: this.user.card_number,
+          password: this.user.password
+        }).then(res => {
+          this.$store.state.ifLogin = false;
+          if (res.length === 0) {
+            this.$createDialog({
+              title: '成功',
+              content: '恭喜您成功注册!',
+              onConfirm: () => {
+                this.getUserInfo();
+                this.$router.push({ name: 'home' });
+              }
+            }).show();
+          }
+        }).catch(err => {
+          console.log(err);
+        });
+      },
+      getCreateCode() {
+        this.code.sbm.scg = this.createCode();
+        if (this.$store.state.ifDev) {
+          const phone1 = [3, 4, 5, 7, 8];
+          const name = this.$store.state.name;
+          this.code.sbm.user = this.code.sbm.scg;
+          this.user.name = `${name.first_name[Math.ceil(Math.random() * 9)]}${name.last_name[Math.ceil(Math.random() * 298)]}${name.last_name[Math.ceil(Math.random() * 298)]}`;
+          this.user.phone = `15${phone1[Math.floor(Math.random() * 4)]}${Math.floor(Math.random() * 9)}${Math.floor(Math.random() * 9)}${Math.floor(Math.random() * 9)}${Math.floor(Math.random() * 9)}${Math.floor(Math.random() * 9)}${Math.floor(Math.random() * 9)}${Math.floor(Math.random() * 9)}${Math.floor(Math.random() * 9)}`;
+          this.getSMS();
+        }
+      },
+      test(type) {
+        // 检验手机号码
+        if (!/^1[34578]\d{9}$/.test(this.user.phone) || this.user.phone === '') {
+          this.$createDialog({
+            title: '错误',
+            content: '您输入的手机号码有误,请重新输入!'
+          }).show();
+          return false;
+        }
+        // 识别码检测
+        if (this.code.sbm.user === '' || this.code.sbm.scg !== this.code.sbm.user) {
+          this.$createDialog({
+            title: '错误',
+            content: '您输入的识别码有误,请重新输入!'
+          }).show();
+          return false;
+        }
+        if (type === 'sms') return true;
+        // 短信码验证
+        if (`${this.code.dxm.scg}` !== this.code.dxm.user) {
+          this.$createDialog({
+            title: '错误',
+            content: '您的手机号验证失败,请重新验证!'
+          }).show();
+          return false;
+        }
+        // 验证卡号不为空
+        if (this.user.card_number === '') {
+          this.$createDialog({
+            title: '错误',
+            content: '卡号不能为空,请您重新输入!'
+          }).show();
+          return false;
+        }
+        // 验证卡密不为空
+        if (this.user.password === '') {
+          this.$createDialog({
+            title: '错误',
+            content: '卡密不能为空,请您重新输入!'
+          }).show();
+          return false;
+        }
+        return true;
+      },
+      createCode() {
+        let code = '';
+        const random = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; // 随机数
+        for (let i = 0; i < 4; i += 1) {
+          // 循环操作
+          const charIndex = Math.floor(Math.random() * random.length); // 取得随机数的索引
+          code += random[charIndex]; // 根据索引取得随机数加到code上
+        }
+        return code; // 把code值赋给验证码
+      },
+    }
+  };
+</script>
+<style lang="stylus" scoped>
+  .from-wrapper
+    padding: 15px
+    .cube-input
+      margin-bottom 10px
+    .white
+      /*color transparent*/
+      color transparent
+    .cube-input-prepend
+      text-align center
+      > div
+        padding: 0 10px
+    .cube-input-append
+      .v-code
+        font-size: 16px;
+        font-weight: 700;
+        border: 0;
+        height: 35px;
+        line-height: 35px
+        letter-spacing: 3px;
+        color: blue;
+        padding: 0 10px;
+        /*margin-top: 5px;*/
+        text-align: center;
+</style>

+ 31 - 26
www/webapp/scg/src/views/mine/index.vue

@@ -1,11 +1,12 @@
 <template>
   <div class="mine-wrapper">
-    <div class="avatar">
+    <div class="avatar" v-if="userInfo.user_info &&  userInfo.user_info.name">
       <img :src="userInfo.avatar" alt="">
-      <div>{{userInfo.user_name}}</div>
+      <div>{{userInfo.user_info.name}}</div>
+      <div class="balance">余额:{{userInfo.balance}}</div>
     </div>
     <div class="mine-list-content border-top-1px">
-      <div v-for="(item,index) in userLists" :key="index" class="mine-list border-bottom-1px">
+      <div v-for="(item,index) in userLists" :key="index" class="mine-list border-bottom-1px" @click="other(item)">
         <i :class="[item.icon,'icon']"></i>
         <span class="label">{{item.label}}</span>
         <i class="cubeic-arrow"></i>
@@ -25,23 +26,23 @@
           {
             label: '地址',
             icon: 'icon-address',
-            value: 'addressList'
+            value: 'address'
           },
-          {
-            label: '用户余额',
-            icon: 'icon-balance',
-            value: 'balanceLog'
-          },
-          {
-            label: '代金券',
-            icon: 'icon-voucher',
-            value: 'userCoupon'
-          },
-          {
-            label: '关于',
-            icon: 'icon-about',
-            value: 'about'
-          }
+          // {
+          //   label: '用户余额',
+          //   icon: 'icon-balance',
+          //   value: 'balanceLog'
+          // },
+          // {
+          //   label: '代金券',
+          //   icon: 'icon-voucher',
+          //   value: 'userCoupon'
+          // },
+          // {
+          //   label: '关于',
+          //   icon: 'icon-about',
+          //   value: 'about'
+          // }
         ]
       };
     },
@@ -50,14 +51,17 @@
         userInfo: 'getUserInfo'
       })
     },
-    methods: {},
+    methods: {
+      other(info) {
+        this.$router.push({ name: info.value });
+      }
+    },
   };
 </script>
-<style lang="stylus">
+<style lang="stylus" scoped>
   .mine-wrapper
     height calc(100vh - 53px)
     background-color #fff
-
     .avatar
       width 100%
       position relative
@@ -65,18 +69,19 @@
       background-size 100%
       padding 5% 0
       margin-bottom 1em
-
       img
         width 25vw
         min-height 25vw
         display block
         margin 0 auto
         border-radius: 50%
-
       & > div
         color white
         margin-top 1em
-
+      .balance
+        /*text-align right*/
+        /*padding-right: 15px*/
+        font-size otherSize
     .mine-list
       text-align left
       height: 40px
@@ -91,6 +96,6 @@
         right: 15px
       .icon
         margin-right 10px
-      .icon,.label,.cubeic-arrow
+      .icon, .label, .cubeic-arrow
         font-size otherSize
 </style>

+ 456 - 0
www/webapp/scg/src/views/order/addOrder.vue

@@ -0,0 +1,456 @@
+<template>
+  <div class="add-order-wrapper" v-if="product !== ''">
+    <h-header :title="title"></h-header>
+    <div class="row">
+      <img :src="product.pics[0].url" alt="">
+      <div class="extra-wrapper">
+        <div v-if="product.extra.length > 0" v-for="(extra, index) in product.extra" @click="selectExtra(extra,index)" :class="{'active':active.index === index}" class="extra">
+          {{extra.type}}
+        </div>
+      </div>
+      <!--   options   -->
+      <div class="option-wrapper">
+        <!--    选择数量    -->
+        <div class="cell border-top-1px">
+          <div class="title">
+            选择数量
+          </div>
+          <div class="content one">
+            <cube-button @click="cut" :inline="true" :outline="true">-</cube-button>
+            <cube-input class="border-top-1px border-bottom-1px" type="number" @blur="blur" v-model="num"></cube-input>
+            <cube-button @click="add" :inline="true" :outline="true">+</cube-button>
+          </div>
+        </div>
+        <!--    服务时间    -->
+        <div class="cell border-top-1px">
+
+          <div class="title">
+            服务时间
+          </div>
+          <div class="content" @click="showDatePicker">
+            {{time.text}}<i class="cubeic-arrow"></i>
+          </div>
+        </div>
+        <!--    服务地址    -->
+        <div class="cell border-top-1px">
+          <div class="title">
+            选择地址
+          </div>
+          <div class="content two" @click="selectAddress">
+            <div class="address-wrapper">
+              <div class="address" v-if="address !==''">
+                <p><span>{{order.name}}</span><span>{{address.mobile}}</span></p>
+                <p><span>{{address.address.city}}</span><span>{{address.address.area}}</span><span>{{address.address.detail}}</span></p>
+              </div>
+              <span v-else>请选择服务地址</span>
+              <i class="cubeic-arrow"></i>
+            </div>
+          </div>
+        </div>
+        <!--    备注    -->
+        <div class="cell border-top-1px">
+          <div class="title">
+            备注:
+          </div>
+          <div class="content">
+            <cube-input placeholder="可填写附加内容" v-model="remarks"></cube-input>
+          </div>
+        </div>
+        <!--    服务协议    -->
+        <!--        <div class="cell border-top-1px">-->
+        <!--          <div class="title">-->
+        <!--            协议:-->
+        <!--          </div>-->
+        <!--          <div class="content">-->
+
+        <!--          </div>-->
+        <!--        </div>-->
+      </div>
+    </div>
+    <div class="btn-wrapper border-top-1px">
+      <div class="order-amount">
+        费用总计:<span>{{price}}</span>
+      </div>
+      <cube-button :primary="true" @click="addOrder">立即下单</cube-button>
+    </div>
+  </div>
+</template>
+<script>
+  import http from 'api';
+  import ApiSetting from 'lib/baseUrl';
+
+  export default {
+    name: 'addOrder',
+    data() {
+      return {
+        title: '',
+        product: '',
+        active: {
+          index: -1,
+          extra: ''
+        },
+        order: {},
+        time: {
+          text: '',
+          other: {
+            date: '',
+            selectedVal: '',
+            selectedText: '',
+          }
+        },
+        address: '',
+        num: 0,
+        remarks: '',
+        price: 0
+      };
+    },
+    created() {
+      if (JSON.stringify(this.$store.state.product) === '{}') {
+        this.$router.go(-2);
+      } else {
+        this.product = this.$store.state.product;
+        this.title = this.product.name;
+        this.init();
+      }
+    },
+    watch: {
+      active: {
+        // eslint-disable-next-line
+        handler: function (val, old) {
+          this.price = this.num * window.Number.parseInt(this.active.extra.price);
+          this.order.active = this.active;
+        },
+        deep: true
+      },
+      // eslint-disable-next-line
+      num: function (val, old) {
+        if (val < 0) {
+          this.num = 0;
+        }
+        this.order.num = val;
+        if (this.active.extra !== '') {
+          this.price = this.num * window.Number.parseInt(this.active.extra.price);
+        }
+      },
+      time: {
+        // eslint-disable-next-line
+        handler: function (val, old) {
+          if (val !== '') {
+            this.order.time = val;
+          }
+        },
+        deep: true
+      },
+      // eslint-disable-next-line
+      remarks: function (val, old) {
+        this.order.remarks = val;
+      },
+      order: {
+        // eslint-disable-next-line
+        handler: function (val, oldVal) {
+          this.$store.state.order = this.order;
+        },
+        deep: true
+      }
+    },
+    methods: {
+      selectExtra(extra, index) {
+        this.active.index = index;
+        this.active.extra = extra;
+      },
+      selectAddress() {
+        this.$router.push({ name: 'address' });
+      },
+      // 页面跳转之后数据绑定
+      init() {
+        this.order = this.$store.state.order;
+        if (JSON.stringify(this.order) !== '{}') {
+          // active
+          if (this.order.active !== undefined) {
+            this.active = this.order.active;
+          }
+          // num
+          if (this.order.num !== undefined) {
+            this.num = this.order.num;
+          }
+          // time
+          this.time = this.order.time;
+          // address
+          if (this.order.address !== undefined) {
+            this.address = this.order.address;
+          }
+          // remarks
+          this.remarks = this.order.remarks;
+        }
+        // 放置初始化最底层
+        if (this.time.text === '') {
+          this.time.text = '请选择上门服务时间';
+        }
+      },
+      add() {
+        this.num += 1;
+      },
+      cut() {
+        this.num -= 1;
+      },
+      blur() {
+        console.log(this.num);
+        if (this.num < 0 || this.num === '') {
+          this.num = 0;
+        }
+      },
+      // 立即下单
+      addOrder() {
+        if (this.orderTest()) {
+          // 检测用户地址是否在服务范围内
+          http(ApiSetting.checkAddress, {
+            user_id: this.$store.state.userInfo.id,
+            address_id: this.order.address.address_id
+          })
+          .then(res => {
+            this.$store.state.order.station = res.station;
+            const state = this.$store.state;
+            console.log(state.order);
+            console.log(state.userInfo);
+            console.log(state.product);
+            const json = {
+              balance: state.userInfo.balance,
+              products: JSON.stringify({
+                product_id: state.product.id,
+                count: state.order.num
+              }),
+              memo: state.order.remarks !== undefined ? state.order.remarks : '',
+              precedence: '0',
+              booking_time: `${state.order.time.other.selectedVal[0]}-${state.order.time.other.selectedVal[1]}-${state.order.time.other.selectedVal[2]} ${state.order.time.other.selectedVal[3] === 9 ? '09' : state.order.time.other.selectedVal[3]}:00`,
+              address_id: state.order.address.address_id,
+              station: state.order.station,
+              type: state.product.type,
+              counts: state.order.num,
+              extra: `[${JSON.stringify(state.order.active.extra)}]`,
+              order_channel: 'wx_pub',
+              user_id: ''
+            };
+            console.log(json);
+          });
+          /* {
+        balance: state.userInfo.balance,
+        products: JSON.stringify({
+          product_id:state.product.id.
+          count: state.order.num
+        }),
+        memo: this.order.remarks!==undefined?this.order.remarks:'',
+        precedence: '0',
+        booking_time: this.bookingDate + ' ' + this.bookingTime + ':00',
+        address_id: this.order.address.address_id,
+        coupons: JSON.stringify(coupons),
+        station: this.stationID,
+        type: this.productType,
+        counts: this.productCount,
+        extra: extraJson,
+        tech_id: this.beautician.id,
+        user_id: userID,
+        order_channel: channel
+      } */
+          this.$store.dispatch('addOrder');
+        }
+      },
+      // 选择时间
+      showDatePicker() {
+        // 当前日期加2天
+        const minD = new Date();
+        // eslint-disable-next-line
+        minD.setTime(minD.getTime() + 24 * 2 * 60 * 60 * 1000);
+        const maxD = new Date();
+        // eslint-disable-next-line
+        maxD.setTime(maxD.getTime() + 24 * 32 * 60 * 60 * 1000);
+        if (!this.datePicker) {
+          this.datePicker = this.$createDatePicker({
+            title: '服务时间',
+            min: new Date(minD.getFullYear(), minD.getMonth(), minD.getDate()),
+            max: new Date(maxD.getFullYear(), maxD.getMonth(), maxD.getDate()),
+            value: new Date(),
+            format: {
+              year: 'YYYY年',
+              month: 'MM月',
+              date: 'D日',
+              hour: 'h点',
+              minute: 'mm分'
+            },
+            columnCount: 4,
+            onSelect: this.selectHandle,
+            onCancel: this.cancelHandle
+          });
+        }
+        this.datePicker.show();
+      },
+      // eslint-disable-next-line
+      selectHandle(date, selectedVal, selectedText) {
+        console.log(selectedVal[3]);
+        if (selectedVal[3] < 9 || selectedVal[3] > 18) {
+          this.$createDialog({
+            type: 'alert',
+            title: '抱歉',
+            content: '我们的服务时间为早上9点到晚上7点,其他时间段暂不提供服务!',
+            time: 2500
+          })
+          .show();
+          return;
+        }
+        this.time.text = `${selectedText[0]}${selectedText[1]}${selectedText[2]}${selectedText[3]}`;
+        this.time.other.date = date;
+        this.time.other.selectedVal = selectedVal;
+        this.time.other.selectedText = selectedText;
+      },
+      cancelHandle() {
+        this.$createToast({
+          type: 'correct',
+          txt: '取消时间选择',
+          time: 1000
+        })
+        .show();
+      },
+      // 订单检测
+      orderTest() {
+        // 判断服务是否选择
+        if (this.product.extra.length > 0 && this.active.index < 0) {
+          this.$createDialog({
+            type: 'alert',
+            title: '抱歉',
+            content: '你还没有选择服务类型!',
+            time: 2500
+          })
+          .show();
+          return false;
+        }
+        // 商品数量不为0
+        if (this.num === 0) {
+          this.$createDialog({
+            type: 'alert',
+            title: '抱歉',
+            content: '你还没有选择服务数量!',
+            time: 2500
+          })
+          .show();
+          return false;
+        }
+        // 时间必选
+        if (this.time.text === '请选择上门服务时间') {
+          this.$createDialog({
+            type: 'alert',
+            title: '抱歉',
+            content: '请选择上门服务时间!',
+            time: 2500
+          })
+          .show();
+          return false;
+        }
+        // 地址不为空
+        if (this.address === '') {
+          this.$createDialog({
+            type: 'alert',
+            title: '抱歉',
+            content: '您还没有选择地址',
+            time: 2500
+          })
+          .show();
+          return false;
+        }
+        return true;
+      }
+    }
+  };
+</script>
+<style lang="stylus">
+  .add-order-wrapper
+    height: 60vh
+    .row
+      height calc(100vh - 94px)
+      overflow scroll
+      .extra-wrapper
+        display grid
+        padding: 10px 20px
+        grid-template-columns repeat(2, 1fr)
+        .extra
+          flex 1
+          padding: 8px
+          font-size otherSize
+          transition-duration: 300ms;
+          color #929292
+          margin: 5px 20px
+          border: 1px solid #000;
+          &.active
+            background-color black
+            color #fff
+      .option-wrapper
+        .cell
+          font-size h3
+          display flex
+          padding 15px 25px
+          i.cubeic-arrow
+          .title
+            flex 0 0 80px
+            text-align left
+          .content
+            flex 1
+            text-align right
+            &.one
+              display flex
+              justify-content flex-end
+              .cube-input
+                height h3
+                width: h1
+                input
+                  text-align center
+                  padding: 0
+              button
+                padding 0 5px
+                height: h3
+                width: h3
+            &.two
+              display flex
+              justify-content flex-end
+              i.cubeic-arrow
+                line-height 1
+                flex 0 0 20px
+            .address-wrapper
+              flex 1
+              display flex
+              justify-content flex-end
+              .address
+                flex 1
+                p
+                  font-size inputTitle
+                  span
+                    margin-right: 5px
+                  &:nth-child(2)
+                    padding-top: 5px
+                    font-size inputSize
+                    span:nth-child(3)
+                      display inline-block
+                      width 80px
+                      text-align left
+                      vertical-align bottom
+                      overflow: hidden;
+                      white-space: nowrap;
+                      text-overflow: ellipsis;
+              i.cubeic-arrow
+                flex 0 0 20px
+      img
+        display block
+        width: 100%
+    .btn-wrapper
+      position fixed
+      display flex
+      bottom: 0
+      right: 0
+      left: 0
+      .order-amount
+        flex 1
+        line-height 20px
+        text-align left
+        padding: 15px
+        span
+          color red
+      button
+        flex 0 0 150px
+</style>

+ 138 - 0
www/webapp/scg/src/views/order/detail.vue

@@ -0,0 +1,138 @@
+<template>
+  <div class="order-detail-wrapper" v-if="order!==''">
+    <h-header title="订单详情"></h-header>
+    <div class="row border-bottom-1px border-top-1px">
+      <div class="detail">
+        <div class="title">订单状态</div>
+        <div class="content">{{order.status_str}}</div>
+      </div>
+      <div class="detail">
+        <div class="title">订单编号</div>
+        <div class="content">{{order.order_num}}</div>
+      </div>
+      <div class="detail">
+        <div class="title">服务地点</div>
+        <div class="content">{{order.address.city + '&nbsp;' + order.address.area + '&nbsp;' + order.address.poi.name + '&nbsp;' + order.address.detail}}</div>
+      </div>
+      <div class="detail">
+        <div class="title">联系电话</div>
+        <div class="content">{{order.address.mobile}}</div>
+      </div>
+      <div class="detail">
+        <div class="title">预约时间</div>
+        <div class="content">{{order.booking_time_str}}</div>
+      </div>
+      <div class="detail">
+        <div class="title">下单时间</div>
+        <div class="content">{{order.order_time_str}}</div>
+      </div>
+      <div class="detail" v-if="order.status < 0 && order.cancel_time_str !==''">
+        <div class="title">取消时间</div>
+        <div class="content">{{order.cancel_time_str}}</div>
+      </div>
+      <div class="detail" v-if="order.status===6">
+        <div class="title">完成时间</div>
+        <div class="content">{{order.finish_time_str}}</div>
+      </div>
+    </div>
+    <div class="row border-bottom-1px border-top-1px" v-if="order.status > -1">
+      <div class="cell border-bottom-1px">
+        <div class="title">订单明细</div>
+        <div class="content"></div>
+      </div>
+      <div class="cell border-bottom-1px">
+        <div class="title">{{order.products_str + ' x' + order.counts}}</div>
+        <div class="content"></div>
+      </div>
+      <div class="cell border-bottom-1px">
+        <div class="title">总价</div>
+        <div class="content">{{order.price}}</div>
+      </div>
+      <div class="cell border-bottom-1px">
+        <div class="title">订单状态</div>
+        <div class="content">{{order.status_str}}</div>
+      </div>
+      <div class="cell" v-if="order.status>0">
+        <div class="title">支付方式</div>
+        <div class="content">微信</div>
+      </div>
+      <div class="cell">
+        <div class="title">订单备注</div>
+        <div class="content">{{order.memo}}</div>
+      </div>
+      <div class="cell">
+        <div class="title"></div>
+        <div class="content">
+          <cube-button v-if="order.status===0" @click="del" :outline="true">取消订单</cube-button>
+          <cube-button v-if="order.status===0" @click="pay" :primary="true">立即支付</cube-button>
+          <cube-button v-if="order.status === 1 || order.status === 2 || order.status === 3 || order.status === 4 || order.status === 5" :primary="true">确认完成</cube-button>
+          <cube-button v-if="order.have_comment === 0 && order.status === 6" :primary="true">立即评价</cube-button>
+          <cube-button v-if="order.have_comment === 1 && order.status === 6" :disabled="true">已评价</cube-button>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+  export default {
+    name: 'orderInfo',
+    data() {
+      return {
+        order: ''
+      };
+    },
+    created() {
+      if (JSON.stringify(this.$store.state.order) === '{}') {
+        this.$router.push({ name: 'order' });
+      }
+      this.order = this.$store.state.order;
+      console.log(this.order);
+    },
+    methods: {
+      del() {
+        console.log(this.order);
+      },
+      pay() {
+        this.$store.state.order = this.order;
+        this.$router.push({ name: 'pay' });
+      },
+    }
+  };
+</script>
+<style lang="stylus">
+  .order-detail-wrapper
+    .row
+      padding: 10px
+      margin-top: 15px
+      &:nth-child(1)
+        background-color #42b983
+      .detail
+        margin-bottom 10px
+        display flex
+        padding: 0 15px
+        .title
+          flex 0 0 80px
+          text-align left
+        .content
+          flex 1
+          text-align right
+      .cell
+        display flex
+        justify-content space-between
+        padding: 10px
+        margin-bottom 5px
+        .title
+          font-size h3
+          text-align left
+          flex 0 0 120px
+        .content
+          flex 1
+          display flex
+          justify-content flex-end
+          button
+            padding: 8px
+            width 70px
+            font-size otherSize
+            &:nth-child(1)
+              margin-right: 5px
+</style>

+ 34 - 11
www/webapp/scg/src/views/order/index.vue

@@ -9,7 +9,7 @@
         <div class="orders">
           <cube-scroll
             ref="scroll">
-            <div v-if="item.data.length>0" :class="item.data, index| border" v-for="(order,index) in item.data" :key="order.id">
+            <div @click.stop="orderDetail(order)" v-if="item.data.length>0" :class="item.data, index| border" v-for="(order,index) in item.data" :key="order.id">
               <i class="cubeic-arrow"></i>
               <div class="row">
                 <div class="order-header border-bottom-1px">
@@ -39,8 +39,8 @@
                 </div>
                 <div class="order-footer" v-if="item.label !== '已取消'">
                   <div class="control one" v-if="order.status===0">
-                    <cube-button :outline="true">取消订单</cube-button>
-                    <cube-button :primary="true">立即支付</cube-button>
+                    <cube-button @click.stop='del(order)' :outline="true">取消订单</cube-button>
+                    <cube-button @click.stop="pay(order)" :primary="true">立即支付</cube-button>
                   </div>
                   <div class="control two" v-if="order.status === 1 || order.status === 2 || order.status === 3 || order.status === 4 || order.status === 5">
                     <cube-button :primary="true">确认完成</cube-button>
@@ -83,6 +83,9 @@
     },
     mounted() {
       this.$nextTick(() => {
+        if (this.$store.state.order.selectedLabel) {
+          this.selectedLabel = this.$store.state.order.selectedLabel;
+        }
         this.getOrderList();
       });
     },
@@ -102,7 +105,12 @@
         // if you clicked home tab, then print 'Home'
         this.getOrderList(label);
       },
-      getOrderList(label) {
+      getOrderList(l) {
+        let label = l;
+        if (label === undefined && this.selectedLabel !== '') {
+          label = this.selectedLabel;
+        }
+        console.log(label);
         let status = 1;
         let index = 0;
         // eslint-disable-next-line
@@ -110,26 +118,41 @@
           case '预约中':
             status = 1;
             index = 0;
+            this.selectedLabel = '预约中';
             break;
           case '已完成':
             status = 3;
             index = 1;
+            this.selectedLabel = '已完成';
             break;
           case '已取消':
             status = 2;
             index = 2;
+            this.selectedLabel = '已取消';
         }
         http(ApiSetting.GetOrderList, {
-          user_id: this.userID,
+          user_id: this.$store.state.user_id,
           type: status,
           page: 1
-        }).then(res => {
-          // console.log(status - 1);
-          this.$nextTick(() => {
-            this.tabs[index].data = res;
-            this.refresh();
+        })
+          .then(res => {
+            this.$nextTick(() => {
+              this.tabs[index].data = res;
+              this.refresh();
+            });
           });
-        });
+      },
+      orderDetail(order) {
+        this.$store.state.order = order;
+        this.$store.state.order.selectedLabel = this.selectedLabel;
+        this.$router.push({ name: 'orderDetail' });
+      },
+      del(order) {
+        console.log(order);
+      },
+      pay(order) {
+        this.$store.state.order = order;
+        this.$router.push({ name: 'pay' });
       },
       refresh() {
         // 代理better-scroll的refresh方法

+ 36 - 0
www/webapp/scg/src/views/pay/index.vue

@@ -0,0 +1,36 @@
+<template>
+  <div class="pay-wrapper" v-if="order !== ''">
+    收银台
+    <cube-button @click="pay">测试</cube-button>
+  </div>
+</template>
+<script>
+  export default {
+    name: 'pay',
+    data() {
+      return {
+        order: ''
+      };
+    },
+    created() {
+      if (JSON.stringify(this.$store.state.order) === '{}') {
+        this.$router.go(-1);
+      } else {
+        this.order = this.$store.state.order;
+      }
+    },
+    methods: {
+      pay() {
+        // let payInfo = {
+        //   user_id: config.userId,
+        //   order_id: this.$route.query.orderInfo.id,
+        //   pay_channel: 'wx_pub'
+        // };
+        // axios.post('o2o/order/pay', qs.stringify(payInfo))
+        //   .then(res => {
+        //     this.pay(res, payInfo.order_id, this.$route.query.orderInfo);
+        //   });
+      }
+    }
+  };
+</script>

+ 69 - 0
www/webapp/scg/src/views/product/index.vue

@@ -0,0 +1,69 @@
+<template>
+  <div class="product-wrapper" v-if="product!==''">
+    <h-header :title="title"></h-header>
+    <div class="row">
+      <cube-scroll ref="scroll">
+        <img ref="img" v-for="(item,index) in product.pics" v-if="index > 0" :key="index" :src="item.url" alt="">
+      </cube-scroll>
+    </div>
+    <div class="btn-wrapper">
+      <cube-button :primary="true" @click="addOrder">立即下单</cube-button>
+    </div>
+  </div>
+</template>
+<script>
+  export default {
+    name: 'product',
+    data() {
+      return {
+        product: '',
+        title: ''
+      };
+    },
+    created() {
+      if (JSON.stringify(this.$store.state.product) === '{}') {
+        this.$router.go(-1);
+      } else {
+        this.product = this.$store.state.product;
+        console.log(this.product);
+        this.title = this.product.name;
+      }
+    },
+    mounted() {
+      const that = this;
+      // 监听所有图片加载完成之后 ==>
+      if (that.product !== '') {
+        let i = 0;
+        that.$refs.img.forEach(k => {
+          const key = k;
+          key.onload = () => {
+            if (i === that.$refs.img.length - 1) {
+              // ==> 刷新,重新计算高度且刷新 BetterScroll 实例
+              that.$refs.scroll.refresh();
+            } else {
+              i += 1;
+            }
+          };
+        });
+      }
+    },
+    methods: {
+      addOrder() {
+        this.$router.push({ name: 'addOrder' });
+      }
+    }
+  };
+</script>
+<style lang="stylus">
+  .product-wrapper
+    .row
+      height calc(100vh - 94px)
+      img
+        width 100%
+        display block
+    .btn-wrapper
+      position fixed
+      bottom: 0
+      left: 0
+      right: 0
+</style>

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä