Przeglądaj źródła

Merge branch '管理后台' of http://1.15.137.157:3000/front_end/tingbang into 管理后台

alienzhang 3 lat temu
rodzic
commit
605a74d764
77 zmienionych plików z 1105 dodań i 795 usunięć
  1. 13 0
      htmldev/dashboard/src/App.vue
  2. 0 0
      htmldev/dashboard/src/assets/fonts/sell-icon.eot
  3. 0 0
      htmldev/dashboard/src/assets/fonts/sell-icon.svg
  4. 0 0
      htmldev/dashboard/src/assets/fonts/sell-icon.ttf
  5. 0 0
      htmldev/dashboard/src/assets/fonts/sell-icon.woff
  6. 0 0
      htmldev/dashboard/src/assets/js/date.js
  7. 0 0
      htmldev/dashboard/src/assets/js/store.js
  8. 0 0
      htmldev/dashboard/src/assets/js/util.js
  9. 65 0
      htmldev/dashboard/src/assets/styles/icon.scss
  10. 42 2
      htmldev/dashboard/src/assets/styles/variable.scss
  11. 0 26
      htmldev/dashboard/src/common/stylus/base.styl
  12. 0 55
      htmldev/dashboard/src/common/stylus/icon.styl
  13. 0 3
      htmldev/dashboard/src/common/stylus/index.styl
  14. 0 19
      htmldev/dashboard/src/common/stylus/mixin.styl
  15. 1 0
      htmldev/dashboard/src/main.js
  16. 1 1
      htmldev/dashboard/src/router/index.js
  17. 79 25
      htmldev/dashboard/src/views/sell/cartcontrol/cartcontrol.vue
  18. 219 1
      htmldev/dashboard/src/views/sell/food/food.vue
  19. 165 21
      htmldev/dashboard/src/views/sell/goods/index.vue
  20. BIN
      htmldev/dashboard/src/views/sell/header/brand@2x.png
  21. BIN
      htmldev/dashboard/src/views/sell/header/brand@3x.png
  22. BIN
      htmldev/dashboard/src/views/sell/header/bulletin@2x.png
  23. BIN
      htmldev/dashboard/src/views/sell/header/bulletin@3x.png
  24. BIN
      htmldev/dashboard/src/views/sell/header/decrease_1@2x.png
  25. BIN
      htmldev/dashboard/src/views/sell/header/decrease_1@3x.png
  26. BIN
      htmldev/dashboard/src/views/sell/header/decrease_2@2x.png
  27. BIN
      htmldev/dashboard/src/views/sell/header/decrease_2@3x.png
  28. BIN
      htmldev/dashboard/src/views/sell/header/discount_1@2x.png
  29. BIN
      htmldev/dashboard/src/views/sell/header/discount_1@3x.png
  30. BIN
      htmldev/dashboard/src/views/sell/header/discount_2@2x.png
  31. BIN
      htmldev/dashboard/src/views/sell/header/discount_2@3x.png
  32. BIN
      htmldev/dashboard/src/views/sell/header/guarantee_1@2x.png
  33. BIN
      htmldev/dashboard/src/views/sell/header/guarantee_1@3x.png
  34. BIN
      htmldev/dashboard/src/views/sell/header/guarantee_2@2x.png
  35. BIN
      htmldev/dashboard/src/views/sell/header/guarantee_2@3x.png
  36. 0 98
      htmldev/dashboard/src/views/sell/header/header.vue
  37. BIN
      htmldev/dashboard/src/views/sell/header/invoice_1@2x.png
  38. BIN
      htmldev/dashboard/src/views/sell/header/invoice_1@3x.png
  39. BIN
      htmldev/dashboard/src/views/sell/header/invoice_2@2x.png
  40. BIN
      htmldev/dashboard/src/views/sell/header/invoice_2@3x.png
  41. BIN
      htmldev/dashboard/src/views/sell/header/special_1@2x.png
  42. BIN
      htmldev/dashboard/src/views/sell/header/special_1@3x.png
  43. BIN
      htmldev/dashboard/src/views/sell/header/special_2@2x.png
  44. BIN
      htmldev/dashboard/src/views/sell/header/special_2@3x.png
  45. 0 132
      htmldev/dashboard/src/views/sell/ratings/ratings.vue
  46. 125 53
      htmldev/dashboard/src/views/sell/ratingselect/ratingselect.vue
  47. BIN
      htmldev/dashboard/src/views/sell/seller/decrease_4@2x.png
  48. BIN
      htmldev/dashboard/src/views/sell/seller/decrease_4@3x.png
  49. BIN
      htmldev/dashboard/src/views/sell/seller/discount_4@2x.png
  50. BIN
      htmldev/dashboard/src/views/sell/seller/discount_4@3x.png
  51. BIN
      htmldev/dashboard/src/views/sell/seller/guarantee_4@2x.png
  52. BIN
      htmldev/dashboard/src/views/sell/seller/guarantee_4@3x.png
  53. BIN
      htmldev/dashboard/src/views/sell/seller/invoice_4@2x.png
  54. BIN
      htmldev/dashboard/src/views/sell/seller/invoice_4@3x.png
  55. 0 153
      htmldev/dashboard/src/views/sell/seller/seller.vue
  56. BIN
      htmldev/dashboard/src/views/sell/seller/special_4@2x.png
  57. BIN
      htmldev/dashboard/src/views/sell/seller/special_4@3x.png
  58. 395 162
      htmldev/dashboard/src/views/sell/shopcart/shopcart.vue
  59. 0 44
      htmldev/dashboard/src/views/sell/star/star.vue
  60. BIN
      htmldev/dashboard/src/views/sell/star/star24_half@2x.png
  61. BIN
      htmldev/dashboard/src/views/sell/star/star24_half@3x.png
  62. BIN
      htmldev/dashboard/src/views/sell/star/star24_off@2x.png
  63. BIN
      htmldev/dashboard/src/views/sell/star/star24_off@3x.png
  64. BIN
      htmldev/dashboard/src/views/sell/star/star24_on@2x.png
  65. BIN
      htmldev/dashboard/src/views/sell/star/star24_on@3x.png
  66. BIN
      htmldev/dashboard/src/views/sell/star/star36_half@2x.png
  67. BIN
      htmldev/dashboard/src/views/sell/star/star36_half@3x.png
  68. BIN
      htmldev/dashboard/src/views/sell/star/star36_off@2x.png
  69. BIN
      htmldev/dashboard/src/views/sell/star/star36_off@3x.png
  70. BIN
      htmldev/dashboard/src/views/sell/star/star36_on@2x.png
  71. BIN
      htmldev/dashboard/src/views/sell/star/star36_on@3x.png
  72. BIN
      htmldev/dashboard/src/views/sell/star/star48_half@2x.png
  73. BIN
      htmldev/dashboard/src/views/sell/star/star48_half@3x.png
  74. BIN
      htmldev/dashboard/src/views/sell/star/star48_off@2x.png
  75. BIN
      htmldev/dashboard/src/views/sell/star/star48_off@3x.png
  76. BIN
      htmldev/dashboard/src/views/sell/star/star48_on@2x.png
  77. BIN
      htmldev/dashboard/src/views/sell/star/star48_on@3x.png

+ 13 - 0
htmldev/dashboard/src/App.vue

@@ -62,6 +62,19 @@ export default {
 <style lang="scss">
 @import "./assets/styles/reset";
 
+.clearfix {
+  display: inline-block;
+
+  &:after {
+    display: block;
+    content: ".";
+    height: 0;
+    line-height: 0;
+    clear: both;
+    visibility: hidden;
+  }
+}
+
 .af-entry {
   height: 100%;
   overflow-y: scroll;

+ 0 - 0
htmldev/dashboard/src/common/fonts/sell-icon.eot → htmldev/dashboard/src/assets/fonts/sell-icon.eot


+ 0 - 0
htmldev/dashboard/src/common/fonts/sell-icon.svg → htmldev/dashboard/src/assets/fonts/sell-icon.svg


+ 0 - 0
htmldev/dashboard/src/common/fonts/sell-icon.ttf → htmldev/dashboard/src/assets/fonts/sell-icon.ttf


+ 0 - 0
htmldev/dashboard/src/common/fonts/sell-icon.woff → htmldev/dashboard/src/assets/fonts/sell-icon.woff


+ 0 - 0
htmldev/dashboard/src/common/js/date.js → htmldev/dashboard/src/assets/js/date.js


+ 0 - 0
htmldev/dashboard/src/common/js/store.js → htmldev/dashboard/src/assets/js/store.js


+ 0 - 0
htmldev/dashboard/src/common/js/util.js → htmldev/dashboard/src/assets/js/util.js


+ 65 - 0
htmldev/dashboard/src/assets/styles/icon.scss

@@ -0,0 +1,65 @@
+@charset "utf-8";
+@font-face {
+  font-family: 'sell-icon';
+  src: url('../fonts/sell-icon.eot?k5xf13');
+  src: url('../fonts/sell-icon.eot?k5xf13#iefix') format('embedded-opentype'),
+  url('../fonts/sell-icon.ttf?k5xf13') format('truetype'),
+  url('../fonts/sell-icon.woff?k5xf13') format('woff'),
+  url('../fonts/sell-icon.svg?k5xf13#sell-icon') format('svg');
+  font-weight: normal;
+  font-style: normal;
+}
+
+[class^="icon-"], [class*=" icon-"] { /* use !important to prevent issues with browser extensions that change fonts */
+  font-family: 'sell-icon' !important;
+  speak: none;
+  font-style: normal;
+  font-weight: normal;
+  font-variant: normal;
+  text-transform: none;
+  line-height: 1;
+
+  /* Better Font Rendering =========== */
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-arrow_lift:before {
+  content: "\e900";
+}
+
+.icon-thumb_up:before {
+  content: "\e901";
+}
+
+.icon-thumb_down:before {
+  content: "\e902";
+}
+
+.icon-shopping_cart:before {
+  content: "\e903";
+}
+
+.icon-favorite:before {
+  content: "\e904";
+}
+
+.icon-check_circle:before {
+  content: "\e905";
+}
+
+.icon-close:before {
+  content: "\e906";
+}
+
+.icon-remove_circle_outline:before {
+  content: "\e907";
+}
+
+.icon-add_circle:before {
+  content: "\e908";
+}
+
+.icon-keyboard_arrow_right:before {
+  content: "\e909";
+}

+ 42 - 2
htmldev/dashboard/src/assets/styles/variable.scss

@@ -109,6 +109,46 @@
   }
 }
 
-@function w750($width) {
-  @return $width * 750 / 828;
+@media (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5) {
+  .border-1px {
+    &::after {
+      -webkit-transform: scaleY(0.7);
+      transform: scaleY(0.7);
+    }
+  }
+}
+
+@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2) {
+  .border-1px {
+    &::after {
+      -webkit-transform: scaleY(0.5);
+      transform: scaleY(0.5);
+    }
+  }
+}
+
+@mixin border-1px($color) {
+  position: relative;
+  &:after {
+    display: block;
+    position: absolute;
+    left: 0;
+    bottom: 0;
+    width: 100%;
+    border-top: 1px solid $color;
+    content: ' ';
+  }
+}
+
+@mixin border-none() {
+  &:after {
+    display: none;
+  }
+}
+
+@mixin bg-image($url) {
+  background-image: url($url + "@2x.png");
+  @media (-webkit-min-device-pixel-ratio: 3), (min-device-pixel-ratio: 3) {
+    background-image: url($url + "@3x.png");
+  }
 }

+ 0 - 26
htmldev/dashboard/src/common/stylus/base.styl

@@ -1,26 +0,0 @@
-body, html
-  line-height: 1
-  font-weight: 200
-  font-family: 'PingFang SC', 'STHeitiSC-Light', 'Helvetica-Light', arial, sans-serif
-
-.clearfix
-  display: inline-block
-  &:after
-    display: block
-    content: "."
-    height: 0
-    line-height: 0
-    clear: both
-    visibility: hidden
-
-@media (-webkit-min-device-pixel-ratio: 1.5),(min-device-pixel-ratio: 1.5)
-  .border-1px
-    &::after
-      -webkit-transform: scaleY(0.7)
-      transform: scaleY(0.7)
-
-@media (-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2)
-  .border-1px
-    &::after
-      -webkit-transform: scaleY(0.5)
-      transform: scaleY(0.5)

+ 0 - 55
htmldev/dashboard/src/common/stylus/icon.styl

@@ -1,55 +0,0 @@
-@font-face
-  font-family: 'sell-icon'
-  src: url('../fonts/sell-icon.eot?k5xf13');
-  src: url('../fonts/sell-icon.eot?k5xf13#iefix') format('embedded-opentype'),
-          url('../fonts/sell-icon.ttf?k5xf13') format('truetype'),
-          url('../fonts/sell-icon.woff?k5xf13') format('woff'),
-          url('../fonts/sell-icon.svg?k5xf13#sell-icon') format('svg')
-  font-weight: normal
-  font-style: normal
-
-[class^="icon-"], [class*=" icon-"]
-  /* use !important to prevent issues with browser extensions that change fonts */
-  font-family: 'sell-icon' !important
-  speak: none
-  font-style: normal
-  font-weight: normal
-  font-variant: normal
-  text-transform: none
-  line-height: 1
-
-  /* Better Font Rendering =========== */
-  -webkit-font-smoothing: antialiased
-  -moz-osx-font-smoothing: grayscale
-
-.icon-arrow_lift:before
-  content: "\e900"
-
-.icon-thumb_up:before
-  content: "\e901"
-
-.icon-thumb_down:before
-  content: "\e902"
-
-.icon-shopping_cart:before
-  content: "\e903"
-
-.icon-favorite:before
-  content: "\e904"
-
-.icon-check_circle:before
-  content: "\e905"
-
-.icon-close:before
-  content: "\e906"
-
-.icon-remove_circle_outline:before
-  content: "\e907"
-
-.icon-add_circle:before
-  content: "\e908"
-
-.icon-keyboard_arrow_right:before
-  content: "\e909"
-
-

+ 0 - 3
htmldev/dashboard/src/common/stylus/index.styl

@@ -1,3 +0,0 @@
-@import "./mixin"
-@import "./icon"
-@import "./base"

+ 0 - 19
htmldev/dashboard/src/common/stylus/mixin.styl

@@ -1,19 +0,0 @@
-border-1px($color)
-  position: relative
-  &:after
-    display: block
-    position: absolute
-    left: 0
-    bottom: 0
-    width: 100%
-    border-top: 1px solid $color
-    content: ' '
-
-border-none()
-  &:after
-    display: none
-
-bg-image($url)
-  background-image: url($url + "@2x.png")
-  @media (-webkit-min-device-pixel-ratio: 3),(min-device-pixel-ratio: 3)
-    background-image: url($url + "@3x.png")

+ 1 - 0
htmldev/dashboard/src/main.js

@@ -6,6 +6,7 @@ import cloneDeep from 'lodash/cloneDeep'
 import VueCookie from 'vue-cookie'
 import refreshTitle from './utils/refreshTitle'
 import './utils/filter'
+import './assets/styles/icon.scss'
 // 全站配置
 window.SITE_CONFIG = {}
 Vue.prototype.$refreshTitle = refreshTitle

+ 1 - 1
htmldev/dashboard/src/router/index.js

@@ -120,7 +120,7 @@ const routes = [
   {
     path: '/orderDetail',
     name: 'OrderDetail',
-    component: _import('views/orderDetail/index'),
+    component: _import('views/ordrDetail/index'),
     meta: {
       title: '订单已支付',
       isUseCache: false,

+ 79 - 25
htmldev/dashboard/src/views/sell/cartcontrol/cartcontrol.vue

@@ -11,34 +11,88 @@
 </template>
 
 <script type="text/ecmascript-6">
-  import Vue from 'vue';
+import Vue from 'vue'
 
-  export default {
-    props: {
-      food: {
-        type: Object
+export default {
+  props: {
+    food: {
+      type: Object
+    }
+  },
+  methods: {
+    addCart (event) {
+      if (!event._constructed) {
+        return
+      }
+      if (!this.food.count) {
+        Vue.set(this.food, 'count', 1)
+      } else {
+        this.food.count++
       }
+      this.$emit('add', event.target)
     },
-    methods: {
-      addCart(event) {
-        if (!event._constructed) {
-          return;
-        }
-        if (!this.food.count) {
-          Vue.set(this.food, 'count', 1);
-        } else {
-          this.food.count++;
-        }
-        this.$emit('add', event.target);
-      },
-      decreaseCart(event) {
-        if (!event._constructed) {
-          return;
-        }
-        if (this.food.count) {
-          this.food.count--;
-        }
+    decreaseCart (event) {
+      if (!event._constructed) {
+        return
+      }
+      if (this.food.count) {
+        this.food.count--
       }
     }
-  };
+  }
+}
 </script>
+
+<style lang="scss" scoped>
+.cartcontrol {
+  font-size: 0;
+
+  .cart-decrease {
+    display: inline-block;
+    padding: 6px;
+    opacity: 1;
+    transform: translate3d(0, 0, 0);
+  }
+
+  .inner {
+    display: inline-block;
+    line-height: 24px;
+    font-size: 24px;
+    color: rgb(0, 160, 220);
+    transition: all 0.4s linear;
+    transform: rotate(0);
+  }
+
+  &.move-enter-active, &.move-leave-active {
+    transition: all 0.4s linear;
+  }
+
+  &.move-enter, &.move-leave-active {
+    opacity: 0;
+    transform: translate3d(24px, 0, 0);
+  }
+
+  .inner {
+    transform: rotate(180deg);
+  }
+
+  .cart-count {
+    display: inline-block;
+    vertical-align: top;
+    width: 12px;
+    padding-top: 6px;
+    line-height: 24px;
+    text-align: center;
+    font-size: 10px;
+    color: rgb(147, 153, 159);
+  }
+
+  .cart-add {
+    display: inline-block;
+    padding: 6px;
+    line-height: 24px;
+    font-size: 24px;
+    color: rgb(0, 160, 220);
+  }
+}
+</style>

+ 219 - 1
htmldev/dashboard/src/views/sell/food/food.vue

@@ -63,7 +63,7 @@
 <script type="text/ecmascript-6">
 import BScroll from 'better-scroll'
 import Vue from 'vue'
-import { formatDate } from '../../../common/js/date'
+import { formatDate } from '../../../assets/js/date'
 import cartcontrol from '../cartcontrol/cartcontrol'
 import ratingselect from '../ratingselect/ratingselect'
 import split from '../split/split'
@@ -152,3 +152,221 @@ export default {
   }
 }
 </script>
+<style lang="scss" scoped>
+.food {
+  position: fixed;
+  left: 0;
+  top: 0;
+  bottom: 48px;
+  z-index: 30;
+  width: 100%;
+  background: #fff;
+  transform: translate3d(0, 0, 0);
+
+  &.move-enter-active, &.move-leave-active {
+    transition: all 0.2s linear;
+  }
+
+  &.move-enter, &.move-leave-active {
+    transform: translate3d(100%, 0, 0);
+  }
+
+  .image-header {
+    position: relative;
+    width: 100%;
+    height: 0;
+    padding-top: 100%;
+
+    img {
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+    }
+
+    .back {
+      position: absolute;
+      top: 10px;
+      left: 0;
+
+      .icon-arrow_lift {
+        display: block;
+        padding: 10px;
+        font-size: 20px;
+        color: #fff;
+      }
+    }
+
+  }
+
+  .content {
+    position: relative;
+    padding: 18px;
+
+    .title {
+      line-height: 14px;
+      margin-bottom: 8px;
+      font-size: 14px;
+      font-weight: 700;
+      color: rgb(7, 17, 27);
+    }
+
+    .detail {
+      margin-bottom: 18px;
+      line-height: 10px;
+      height: 10px;
+      font-size: 0;
+
+      .sell-count, .rating {
+        font-size: 10px;
+        color: rgb(147, 153, 159);
+      }
+
+      .sell-count {
+        margin-right: 12px;
+      }
+    }
+
+    .price {
+      font-weight: 700;
+      line-height: 24px;
+    }
+
+    .now {
+      margin-right: 8px;
+      font-size: 14px;
+      color: rgb(240, 20, 20);
+    }
+
+    .old {
+      text-decoration: line-through;
+      font-size: 10px;
+      color: rgb(147, 153, 159);
+    }
+
+    .cartcontrol-wrapper {
+      position: absolute;
+      right: 12px;
+      bottom: 12px;
+    }
+
+    .buy {
+      position: absolute;
+      right: 18px;
+      bottom: 18px;
+      z-index: 10;
+      height: 24px;
+      line-height: 24px;
+      padding: 0 12px;
+      box-sizing: border-box;
+      border-radius: 12px;
+      font-size: 10px;
+      color: #fff;
+      background: rgb(0, 160, 220);
+      opacity: 1;
+
+      &.fade-enter-active, &.fade-leave-active {
+        transition: all 0.2s;
+      }
+
+      &.fade-enter, &.fade-leave-active {
+        opacity: 0;
+        z-index: -1;
+      }
+    }
+  }
+
+  .info {
+    padding: 18px;
+
+    .title {
+      line-height: 14px;
+      margin-bottom: 6px;
+      font-size: 14px;
+      color: rgb(7, 17, 27);
+    }
+
+    .text {
+      line-height: 24px;
+      padding: 0 8px;
+      font-size: 12px;
+      color: rgb(77, 85, 93);
+    }
+  }
+
+  .rating {
+    padding-top: 18px;
+
+    .title {
+      line-height: 14px;
+      margin-left: 18px;
+      font-size: 14px;
+      color: rgb(7, 17, 27);
+    }
+
+    .rating-wrapper {
+      padding: 0 18px;
+
+      .rating-item {
+        position: relative;
+        padding: 16px 0;
+        @include border-1px(rgba(7, 17, 27, 0.1));
+
+        .user {
+          position: absolute;
+          right: 0;
+          top: 16px;
+          line-height: 12px;
+          font-size: 0;
+        }
+
+        .name {
+          display: inline-block;
+          margin-right: 6px;
+          vertical-align: top;
+          font-size: 10px;
+          color: rgb(147, 153, 159);
+        }
+
+        .avatar {
+          border-radius: 50%;
+        }
+
+        .time {
+          margin-bottom: 6px;
+          line-height: 12px;
+          font-size: 10px;
+          color: rgb(147, 153, 159);
+        }
+
+        .text {
+          line-height: 16px;
+          font-size: 12px;
+          color: rgb(7, 17, 27);
+        }
+
+        .icon-thumb_up, .icon-thumb_down {
+          margin-right: 4px;
+          line-height: 16px;
+          font-size: 12px;
+        }
+
+        .icon-thumb_up {
+          color: rgb(0, 160, 220);
+        }
+
+        .icon-thumb_down {
+          color: rgb(147, 153, 159);
+        }
+      }
+    }
+
+    .no-rating {
+      padding: 16px 0;
+      font-size: 12px;
+      color: rgb(147, 153, 159);
+    }
+  }
+}
+</style>

+ 165 - 21
htmldev/dashboard/src/views/sell/goods/index.vue

@@ -52,22 +52,16 @@ import shopcart from '../shopcart/shopcart'
 import cartcontrol from '../cartcontrol/cartcontrol'
 import food from '../food/food'
 
-const ERR_OK = 0
-const debug = process.env.NODE_ENV !== 'production'
-const goods = require('../../../mock/data.json')
+const mockDataJson = require('../../../mock/data.json')
 
 export default {
-  props: {
-    seller: {
-      type: Object
-    }
-  },
   data () {
     return {
       goods: [],
       listHeight: [],
       scrollY: 0,
-      selectedFood: {}
+      selectedFood: {},
+      seller: {}
     }
   },
   computed: {
@@ -96,17 +90,11 @@ export default {
   },
   created () {
     this.classMap = ['decrease', 'discount', 'special', 'invoice', 'guarantee']
-
-    const url = 'http://ustbhuangyi.com/sell/api/goods'
-    this.$http.get(url).then((response) => {
-      response = response.body
-      if (response.errno === ERR_OK) {
-        this.goods = response.data
-        this.$nextTick(() => {
-          this._initScroll()
-          this._calculateHeight()
-        })
-      }
+    this.seller = mockDataJson.seller
+    this.goods = mockDataJson.goods
+    this.$nextTick(() => {
+      this._initScroll()
+      this._calculateHeight()
     })
   },
   methods: {
@@ -175,4 +163,160 @@ export default {
 }
 </script>
 
-<style lang="scss" scoped></style>
+<style lang="scss" scoped>
+.goods {
+  display: flex;
+  position: absolute;
+  top: 174px;
+  bottom: 46px;
+  width: 100%;
+  overflow: hidden;
+
+  .menu-wrapper {
+    flex: 0 0 80px;
+    width: 80px;
+    background: #f3f5f7;
+
+    .menu-item {
+      display: table;
+      height: 54px;
+      width: 56px;
+      padding: 0 12px;
+      line-height: 14px;
+
+      &.current {
+        position: relative;
+        z-index: 10;
+        margin-top: -1px;
+        background: #fff;
+        font-weight: 700;
+
+        .text {
+          @include border-none();
+        }
+      }
+
+      .icon {
+        display: inline-block;
+        vertical-align: top;
+        width: 12px;
+        height: 12px;
+        margin-right: 2px;
+        background-size: 12px 12px;
+        background-repeat: no-repeat;
+
+        &.decrease {
+          @include bg-image('decrease_3');
+        }
+
+        &.discount {
+          @include bg-image('discount_3');
+        }
+
+        &.guarantee {
+          @include bg-image('guarantee_3');
+        }
+
+        &.invoice {
+          @include bg-image('invoice_3');
+        }
+
+        &.special {
+          @include bg-image('special_3');
+        }
+      }
+
+      .text {
+        display: table-cell;
+        width: 56px;
+        vertical-align: middle;
+        @include border-1px(rgba(7, 17, 27, 0.1));
+        font-size: 12px;
+      }
+    }
+  }
+}
+
+.foods-wrapper {
+  flex: 1;
+
+  .title {
+    padding-left: 14px;
+    height: 26px;
+    line-height: 26px;
+    border-left: 2px solid #d9dde1;
+    font-size: 12px;
+    color: rgb(147, 153, 159);
+    background: #f3f5f7;
+  }
+
+  .food-item {
+    display: flex;
+    margin: 18px;
+    padding-bottom: 18px;
+    @include border-1px(rgba(7, 17, 27, 0.1));
+  }
+
+  &:last-child {
+    @include border-none();
+    margin-bottom: 0;
+  }
+
+  .icon {
+    flex: 0 0 57px;
+    margin-right: 10px;
+  }
+
+  .content {
+    flex: 1;
+
+    .name {
+      margin: 2px 0 8px 0;
+      height: 14px;
+      line-height: 14px;
+      font-size: 14px;
+      color: rgb(7, 17, 27);
+    }
+
+    .desc, .extra {
+      line-height: 10px;
+      font-size: 10px;
+      color: rgb(147, 153, 159);
+    }
+
+    .desc {
+      line-height: 12px;
+      margin-bottom: 8px;
+    }
+
+    .extra {
+      .count {
+        margin-right: 12px;
+      }
+    }
+
+    .price {
+      font-weight: 700;
+      line-height: 24px;
+    }
+
+    .now {
+      margin-right: 8px;
+      font-size: 14px;
+      color: rgb(240, 20, 20);
+    }
+
+    .old {
+      text-decoration: line-through;
+      font-size: 10px;
+      color: rgb(147, 153, 159);
+    }
+
+    .cartcontrol-wrapper {
+      position: absolute;
+      right: 0;
+      bottom: 12px;
+    }
+  }
+}
+</style>

BIN
htmldev/dashboard/src/views/sell/header/brand@2x.png


BIN
htmldev/dashboard/src/views/sell/header/brand@3x.png


BIN
htmldev/dashboard/src/views/sell/header/bulletin@2x.png


BIN
htmldev/dashboard/src/views/sell/header/bulletin@3x.png


BIN
htmldev/dashboard/src/views/sell/header/decrease_1@2x.png


BIN
htmldev/dashboard/src/views/sell/header/decrease_1@3x.png


BIN
htmldev/dashboard/src/views/sell/header/decrease_2@2x.png


BIN
htmldev/dashboard/src/views/sell/header/decrease_2@3x.png


BIN
htmldev/dashboard/src/views/sell/header/discount_1@2x.png


BIN
htmldev/dashboard/src/views/sell/header/discount_1@3x.png


BIN
htmldev/dashboard/src/views/sell/header/discount_2@2x.png


BIN
htmldev/dashboard/src/views/sell/header/discount_2@3x.png


BIN
htmldev/dashboard/src/views/sell/header/guarantee_1@2x.png


BIN
htmldev/dashboard/src/views/sell/header/guarantee_1@3x.png


BIN
htmldev/dashboard/src/views/sell/header/guarantee_2@2x.png


BIN
htmldev/dashboard/src/views/sell/header/guarantee_2@3x.png


+ 0 - 98
htmldev/dashboard/src/views/sell/header/header.vue

@@ -1,98 +0,0 @@
-<template>
-  <div class="header">
-    <div class="content-wrapper">
-      <div class="avatar">
-        <img width="64" height="64" :src="seller.avatar">
-      </div>
-      <div class="content">
-        <div class="title">
-          <span class="brand"></span>
-          <span class="name">{{seller.name}}</span>
-        </div>
-        <div class="description">
-          {{seller.description}}/{{seller.deliveryTime}}分钟送达
-        </div>
-        <div v-if="seller.supports" class="support">
-          <span class="icon" :class="classMap[seller.supports[0].type]"></span>
-          <span class="text">{{seller.supports[0].description}}</span>
-        </div>
-      </div>
-      <div v-if="seller.supports" class="support-count" @click="showDetail">
-        <span class="count">{{seller.supports.length}}个</span>
-        <i class="icon-keyboard_arrow_right"></i>
-      </div>
-    </div>
-    <div class="bulletin-wrapper" @click="showDetail">
-      <span class="bulletin-title"></span><span class="bulletin-text">{{seller.bulletin}}</span>
-      <i class="icon-keyboard_arrow_right"></i>
-    </div>
-    <div class="background">
-      <img :src="seller.avatar" width="100%" height="100%">
-    </div>
-    <transition name="fade">
-      <div v-show="detailShow" class="detail">
-        <div class="detail-wrapper clearfix">
-          <div class="detail-main">
-            <h1 class="name">{{seller.name}}</h1>
-            <div class="star-wrapper">
-              <star :size="48" :score="seller.score"></star>
-            </div>
-            <div class="title">
-              <div class="line"></div>
-              <div class="text">优惠信息</div>
-              <div class="line"></div>
-            </div>
-            <ul v-if="seller.supports" class="supports">
-              <li class="support-item" v-for="(item,index) in seller.supports">
-                <span class="icon" :class="classMap[seller.supports[index].type]"></span>
-                <span class="text">{{seller.supports[index].description}}</span>
-              </li>
-            </ul>
-            <div class="title">
-              <div class="line"></div>
-              <div class="text">商家公告</div>
-              <div class="line"></div>
-            </div>
-            <div class="bulletin">
-              <p class="content">{{seller.bulletin}}</p>
-            </div>
-          </div>
-        </div>
-        <div class="detail-close" @click="hideDetail">
-          <i class="icon-close"></i>
-        </div>
-      </div>
-    </transition>
-  </div>
-</template>
-
-<script type="text/ecmascript-6">
-  import star from '../star/star';
-
-  export default {
-    props: {
-      seller: {
-        type: Object
-      }
-    },
-    data() {
-      return {
-        detailShow: false
-      };
-    },
-    methods: {
-      showDetail() {
-        this.detailShow = true;
-      },
-      hideDetail() {
-        this.detailShow = false;
-      }
-    },
-    created() {
-      this.classMap = ['decrease', 'discount', 'special', 'invoice', 'guarantee'];
-    },
-    components: {
-      star
-    }
-  };
-</script>

BIN
htmldev/dashboard/src/views/sell/header/invoice_1@2x.png


BIN
htmldev/dashboard/src/views/sell/header/invoice_1@3x.png


BIN
htmldev/dashboard/src/views/sell/header/invoice_2@2x.png


BIN
htmldev/dashboard/src/views/sell/header/invoice_2@3x.png


BIN
htmldev/dashboard/src/views/sell/header/special_1@2x.png


BIN
htmldev/dashboard/src/views/sell/header/special_1@3x.png


BIN
htmldev/dashboard/src/views/sell/header/special_2@2x.png


BIN
htmldev/dashboard/src/views/sell/header/special_2@3x.png


+ 0 - 132
htmldev/dashboard/src/views/sell/ratings/ratings.vue

@@ -1,132 +0,0 @@
-<template>
-  <div class="ratings" ref="ratings">
-    <div class="ratings-content">
-      <div class="overview">
-        <div class="overview-left">
-          <h1 class="score">{{seller.score}}</h1>
-          <div class="title">综合评分</div>
-          <div class="rank">高于周边商家{{seller.rankRate}}%</div>
-        </div>
-        <div class="overview-right">
-          <div class="score-wrapper">
-            <span class="title">服务态度</span>
-            <star :size="36" :score="seller.serviceScore"></star>
-            <span class="score">{{seller.serviceScore}}</span>
-          </div>
-          <div class="score-wrapper">
-            <span class="title">商品评分</span>
-            <star :size="36" :score="seller.foodScore"></star>
-            <span class="score">{{seller.foodScore}}</span>
-          </div>
-          <div class="delivery-wrapper">
-            <span class="title">送达时间</span>
-            <span class="delivery">{{seller.deliveryTime}}分钟</span>
-          </div>
-        </div>
-      </div>
-      <split></split>
-      <ratingselect @select="selectRating" @toggle="toggleContent" :selectType="selectType" :onlyContent="onlyContent"
-                    :ratings="ratings"></ratingselect>
-      <div class="rating-wrapper">
-        <ul>
-          <li v-for="rating in ratings" v-show="needShow(rating.rateType, rating.text)" class="rating-item">
-            <div class="avatar">
-              <img width="28" height="28" :src="rating.avatar">
-            </div>
-            <div class="content">
-              <h1 class="name">{{rating.username}}</h1>
-              <div class="star-wrapper">
-                <star :size="24" :score="rating.score"></star>
-                <span class="delivery" v-show="rating.deliveryTime">{{rating.deliveryTime}}</span>
-              </div>
-              <p class="text">{{rating.text}}</p>
-              <div class="recommend" v-show="rating.recommend && rating.recommend.length">
-                <span class="icon-thumb_up"></span>
-                <span class="item" v-for="item in rating.recommend">{{item}}</span>
-              </div>
-              <div class="time">
-                {{rating.rateTime | formatDate}}
-              </div>
-            </div>
-          </li>
-        </ul>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script type="text/ecmascript-6">
-  import BScroll from 'better-scroll';
-  import {formatDate} from '../../../common/js/date';
-  import star from '../star/star';
-  import ratingselect from '../ratingselect/ratingselect';
-  import split from '../split/split';
-
-  const ALL = 2;
-  const ERR_OK = 0;
-  const debug = process.env.NODE_ENV !== 'production';
-
-  export default {
-    props: {
-      seller: {
-        type: Object
-      }
-    },
-    data() {
-      return {
-        ratings: [],
-        selectType: ALL,
-        onlyContent: true
-      };
-    },
-    created() {
-      const url = debug ? '/api/ratings' : 'http://ustbhuangyi.com/sell/api/ratings';
-      this.$http.get(url).then((response) => {
-        response = response.body;
-        if (response.errno === ERR_OK) {
-          this.ratings = response.data;
-          this.$nextTick(() => {
-            this.scroll = new BScroll(this.$refs.ratings, {
-              click: true
-            });
-          });
-        }
-      });
-    },
-    methods: {
-      needShow(type, text) {
-        if (this.onlyContent && !text) {
-          return false;
-        }
-        if (this.selectType === ALL) {
-          return true;
-        } else {
-          return type === this.selectType;
-        }
-      },
-      selectRating(type) {
-        this.selectType = type;
-        this.$nextTick(() => {
-          this.scroll.refresh();
-        });
-      },
-      toggleContent() {
-        this.onlyContent = !this.onlyContent;
-        this.$nextTick(() => {
-          this.scroll.refresh();
-        });
-      }
-    },
-    filters: {
-      formatDate(time) {
-        let date = new Date(time);
-        return formatDate(date, 'yyyy-MM-dd hh:mm');
-      }
-    },
-    components: {
-      star,
-      split,
-      ratingselect
-    }
-  };
-</script>

+ 125 - 53
htmldev/dashboard/src/views/sell/ratingselect/ratingselect.vue

@@ -2,11 +2,11 @@
   <div class="ratingselect">
     <div class="rating-type border-1px">
       <span @click="select(2,$event)" class="block positive" :class="{'active':selectType===2}">{{desc.all}}<span
-          class="count">{{ratings.length}}</span></span>
+        class="count">{{ratings.length}}</span></span>
       <span @click="select(0,$event)" class="block positive" :class="{'active':selectType===0}">{{desc.positive}}<span
-          class="count">{{positives.length}}</span></span>
+        class="count">{{positives.length}}</span></span>
       <span @click="select(1,$event)" class="block negative" :class="{'active':selectType===1}">{{desc.negative}}<span
-          class="count">{{negatives.length}}</span></span>
+        class="count">{{negatives.length}}</span></span>
     </div>
     <div @click="toggleContent" class="switch" :class="{'on':onlyContent}">
       <span class="icon-check_circle"></span>
@@ -16,62 +16,134 @@
 </template>
 
 <script type="text/ecmascript-6">
-  const POSITIVE = 0;
-  const NEGATIVE = 1;
-  const ALL = 2;
+const POSITIVE = 0
+const NEGATIVE = 1
+const ALL = 2
 
-  export default {
-    props: {
-      ratings: {
-        type: Array,
-        default() {
-          return [];
-        }
-      },
-      selectType: {
-        type: Number,
-        default: ALL
-      },
-      onlyContent: {
-        type: Boolean,
-        default: false
-      },
-      desc: {
-        type: Object,
-        default() {
-          return {
-            all: '全部',
-            positive: '满意',
-            negative: '不满意'
-          };
+export default {
+  props: {
+    ratings: {
+      type: Array,
+      default () {
+        return []
+      }
+    },
+    selectType: {
+      type: Number,
+      default: ALL
+    },
+    onlyContent: {
+      type: Boolean,
+      default: false
+    },
+    desc: {
+      type: Object,
+      default () {
+        return {
+          all: '全部',
+          positive: '满意',
+          negative: '不满意'
         }
       }
+    }
+  },
+  computed: {
+    positives () {
+      return this.ratings.filter((rating) => {
+        return rating.rateType === POSITIVE
+      })
     },
-    computed: {
-      positives() {
-        return this.ratings.filter((rating) => {
-          return rating.rateType === POSITIVE;
-        });
-      },
-      negatives() {
-        return this.ratings.filter((rating) => {
-          return rating.rateType === NEGATIVE;
-        });
+    negatives () {
+      return this.ratings.filter((rating) => {
+        return rating.rateType === NEGATIVE
+      })
+    }
+  },
+  methods: {
+    select (type, event) {
+      if (!event._constructed) {
+        return
       }
+      this.$emit('select', type)
     },
-    methods: {
-      select(type, event) {
-        if (!event._constructed) {
-          return;
-        }
-        this.$emit('select', type);
-      },
-      toggleContent(event) {
-        if (!event._constructed) {
-          return;
-        }
-        this.$emit('toggle');
+    toggleContent (event) {
+      if (!event._constructed) {
+        return
       }
+      this.$emit('toggle')
     }
-  };
+  }
+}
 </script>
+<style lang="scss" scoped>
+.ratingselect {
+  .rating-type {
+    padding: 18px 0;
+    margin: 0 18px;
+    @include border-1px(rgba(7, 17, 27, 0.1));
+    font-size: 0;
+
+    .block {
+      display: inline-block;
+      padding: 8px 12px;
+      margin-right: 8px;
+      line-height: 16px;
+      border-radius: 1px;
+      font-size: 12px;
+      color: rgb(77, 85, 93);
+
+      &.active {
+        color: #fff;
+      }
+
+      .count {
+        margin-left: 2px;
+        font-size: 8px;
+      }
+
+      &.positive {
+        background: rgba(0, 160, 220, 0.2);
+      }
+
+      &.active {
+        background: rgb(0, 160, 220);
+      }
+
+      &.negative {
+        background: rgba(77, 85, 93, 0.2);
+      }
+
+      &.active {
+        background: rgb(77, 85, 93);
+      }
+    }
+  }
+
+  .switch {
+    padding: 12px 18px;
+    line-height: 24px;
+    border-bottom: 1px solid rgba(7, 17, 27, 0.1);
+    color: rgb(147, 153, 159);
+    font-size: 0;
+
+    &.on {
+      .icon-check_circle {
+        color: #00c850;
+      }
+    }
+
+    .icon-check_circle {
+      display: inline-block;
+      vertical-align: top;
+      margin-right: 4px;
+      font-size: 24px;
+    }
+
+    .text {
+      display: inline-block;
+      vertical-align: top;
+      font-size: 12px;
+    }
+  }
+}
+</style>

BIN
htmldev/dashboard/src/views/sell/seller/decrease_4@2x.png


BIN
htmldev/dashboard/src/views/sell/seller/decrease_4@3x.png


BIN
htmldev/dashboard/src/views/sell/seller/discount_4@2x.png


BIN
htmldev/dashboard/src/views/sell/seller/discount_4@3x.png


BIN
htmldev/dashboard/src/views/sell/seller/guarantee_4@2x.png


BIN
htmldev/dashboard/src/views/sell/seller/guarantee_4@3x.png


BIN
htmldev/dashboard/src/views/sell/seller/invoice_4@2x.png


BIN
htmldev/dashboard/src/views/sell/seller/invoice_4@3x.png


+ 0 - 153
htmldev/dashboard/src/views/sell/seller/seller.vue

@@ -1,153 +0,0 @@
-<template>
-  <div class="seller" ref="seller">
-    <div class="seller-content">
-      <div class="overview">
-        <h1 class="title">{{seller.name}}</h1>
-        <div class="desc border-1px">
-          <star :size="36" :score="seller.score"></star>
-          <span class="text">({{seller.ratingCount}})</span>
-          <span class="text">月售{{seller.sellCount}}单</span>
-        </div>
-        <ul class="remark">
-          <li class="block">
-            <h2>起送价</h2>
-            <div class="content">
-              <span class="stress">{{seller.minPrice}}</span>元
-            </div>
-          </li>
-          <li class="block">
-            <h2>商家配送</h2>
-            <div class="content">
-              <span class="stress">{{seller.deliveryPrice}}</span>元
-            </div>
-          </li>
-          <li class="block">
-            <h2>平均配送时间</h2>
-            <div class="content">
-              <span class="stress">{{seller.deliveryTime}}</span>分钟
-            </div>
-          </li>
-        </ul>
-        <div class="favorite" @click="toggleFavorite">
-          <span class="icon-favorite" :class="{'active':favorite}"></span>
-          <span class="text">{{favoriteText}}</span>
-        </div>
-      </div>
-      <split></split>
-      <div class="bulletin">
-        <h1 class="title">公告与活动</h1>
-        <div class="content-wrapper border-1px">
-          <p class="content">{{seller.bulletin}}</p>
-        </div>
-        <ul v-if="seller.supports" class="supports">
-          <li class="support-item border-1px" v-for="(item,index) in seller.supports">
-            <span class="icon" :class="classMap[seller.supports[index].type]"></span>
-            <span class="text">{{seller.supports[index].description}}</span>
-          </li>
-        </ul>
-      </div>
-      <split></split>
-      <div class="pics">
-        <h1 class="title">商家实景</h1>
-        <div class="pic-wrapper" ref="picWrapper">
-          <ul class="pic-list" ref="picList">
-            <li class="pic-item" v-for="pic in seller.pics">
-              <img :src="pic" width="120" height="90">
-            </li>
-          </ul>
-        </div>
-      </div>
-      <split></split>
-      <div class="info">
-        <h1 class="title border-1px">商家信息</h1>
-        <ul>
-          <li class="info-item" v-for="info in seller.infos">{{info}}</li>
-        </ul>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script type="text/ecmascript-6">
-  import BScroll from 'better-scroll';
-  import {saveToLocal, loadFromLocal} from '../../../common/js/store';
-  import star from '../star/star';
-  import split from '../split/split';
-
-  export default {
-    props: {
-      seller: {
-        type: Object
-      }
-    },
-    data() {
-      return {
-        favorite: (() => {
-          return loadFromLocal(this.seller.id, 'favorite', false);
-        })()
-      };
-    },
-    computed: {
-      favoriteText() {
-        return this.favorite ? '已收藏' : '收藏';
-      }
-    },
-    created() {
-      this.classMap = ['decrease', 'discount', 'special', 'invoice', 'guarantee'];
-    },
-    watch: {
-      'seller'() {
-        this.$nextTick(() => {
-          this._initScroll();
-          this._initPics();
-        });
-      }
-    },
-    mounted() {
-      this.$nextTick(() => {
-        this._initScroll();
-        this._initPics();
-      });
-    },
-    methods: {
-      toggleFavorite(event) {
-        if (!event._constructed) {
-          return;
-        }
-        this.favorite = !this.favorite;
-        saveToLocal(this.seller.id, 'favorite', this.favorite);
-      },
-      _initScroll() {
-        if (!this.scroll) {
-          this.scroll = new BScroll(this.$refs.seller, {
-            click: true
-          });
-        } else {
-          this.scroll.refresh();
-        }
-      },
-      _initPics() {
-        if (this.seller.pics) {
-          let picWidth = 120;
-          let margin = 6;
-          let width = (picWidth + margin) * this.seller.pics.length - margin;
-          this.$refs.picList.style.width = width + 'px';
-          this.$nextTick(() => {
-            if (!this.picScroll) {
-              this.picScroll = new BScroll(this.$refs.picWrapper, {
-                scrollX: true,
-                eventPassthrough: 'vertical'
-              });
-            } else {
-              this.picScroll.refresh();
-            }
-          });
-        }
-      }
-    },
-    components: {
-      star,
-      split
-    }
-  };
-</script>

BIN
htmldev/dashboard/src/views/sell/seller/special_4@2x.png


BIN
htmldev/dashboard/src/views/sell/seller/special_4@3x.png


+ 395 - 162
htmldev/dashboard/src/views/sell/shopcart/shopcart.vue

@@ -38,7 +38,7 @@
               <li class="food" v-for="food in selectFoods">
                 <span class="name">{{food.name}}</span>
                 <div class="price">
-                  <span>¥{{food.price*food.count}}</span>
+                  <span>¥{{food.price * food.count}}</span>
                 </div>
                 <div class="cartcontrol-wrapper">
                   <cartcontrol @add="addFood" :food="food"></cartcontrol>
@@ -56,180 +56,413 @@
 </template>
 
 <script type="text/ecmascript-6">
-  import BScroll from 'better-scroll';
-  import cartcontrol from '../cartcontrol/cartcontrol';
-
-  export default {
-    props: {
-      selectFoods: {
-        type: Array,
-        default() {
-          return [
-            {
-              price: 10,
-              count: 1
-            }
-          ];
-        }
-      },
-      deliveryPrice: {
-        type: Number,
-        default: 0
-      },
-      minPrice: {
-        type: Number,
-        default: 0
-      }
-    },
-    data() {
-      return {
-        balls: [
-          {
-            show: false
-          },
-          {
-            show: false
-          },
-          {
-            show: false
-          },
-          {
-            show: false
-          },
+import BScroll from 'better-scroll'
+import cartcontrol from '../cartcontrol/cartcontrol'
+
+export default {
+  props: {
+    selectFoods: {
+      type: Array,
+      default () {
+        return [
           {
-            show: false
+            price: 10,
+            count: 1
           }
-        ],
-        dropBalls: [],
-        fold: true
-      };
+        ]
+      }
     },
-    computed: {
-      totalPrice() {
-        let total = 0;
-        this.selectFoods.forEach((food) => {
-          total += food.price * food.count;
-        });
-        return total;
-      },
-      totalCount() {
-        let count = 0;
-        this.selectFoods.forEach((food) => {
-          count += food.count;
-        });
-        return count;
-      },
-      payDesc() {
-        if (this.totalPrice === 0) {
-          return `¥${this.minPrice}元起送`;
-        } else if (this.totalPrice < this.minPrice) {
-          let diff = this.minPrice - this.totalPrice;
-          return `还差¥${diff}元起送`;
-        } else {
-          return '去结算';
-        }
-      },
-      payClass() {
-        if (this.totalPrice < this.minPrice) {
-          return 'not-enough';
-        } else {
-          return 'enough';
+    deliveryPrice: {
+      type: Number,
+      default: 0
+    },
+    minPrice: {
+      type: Number,
+      default: 0
+    }
+  },
+  data () {
+    return {
+      balls: [
+        {
+          show: false
+        },
+        {
+          show: false
+        },
+        {
+          show: false
+        },
+        {
+          show: false
+        },
+        {
+          show: false
         }
-      },
-      listShow() {
-        if (!this.totalCount) {
-          this.fold = true;
-          return false;
+      ],
+      dropBalls: [],
+      fold: true
+    }
+  },
+  computed: {
+    totalPrice () {
+      let total = 0
+      this.selectFoods.forEach((food) => {
+        total += food.price * food.count
+      })
+      return total
+    },
+    totalCount () {
+      let count = 0
+      this.selectFoods.forEach((food) => {
+        count += food.count
+      })
+      return count
+    },
+    payDesc () {
+      if (this.totalPrice === 0) {
+        return `¥${this.minPrice}元起送`
+      } else if (this.totalPrice < this.minPrice) {
+        let diff = this.minPrice - this.totalPrice
+        return `还差¥${diff}元起送`
+      } else {
+        return '去结算'
+      }
+    },
+    payClass () {
+      if (this.totalPrice < this.minPrice) {
+        return 'not-enough'
+      } else {
+        return 'enough'
+      }
+    },
+    listShow () {
+      if (!this.totalCount) {
+        this.fold = true
+        return false
+      }
+      let show = !this.fold
+      if (show) {
+        this.$nextTick(() => {
+          if (!this.scroll) {
+            this.scroll = new BScroll(this.$refs.listContent, {
+              click: true
+            })
+          } else {
+            this.scroll.refresh()
+          }
+        })
+      }
+      return show
+    }
+  },
+  methods: {
+    drop (el) {
+      for (let i = 0; i < this.balls.length; i++) {
+        let ball = this.balls[i]
+        if (!ball.show) {
+          ball.show = true
+          ball.el = el
+          this.dropBalls.push(ball)
+          return
         }
-        let show = !this.fold;
-        if (show) {
-          this.$nextTick(() => {
-            if (!this.scroll) {
-              this.scroll = new BScroll(this.$refs.listContent, {
-                click: true
-              });
-            } else {
-              this.scroll.refresh();
-            }
-          });
+      }
+    },
+    toggleList () {
+      if (!this.totalCount) {
+        return
+      }
+      this.fold = !this.fold
+    },
+    hideList () {
+      this.fold = true
+    },
+    empty () {
+      this.selectFoods.forEach((food) => {
+        food.count = 0
+      })
+    },
+    pay () {
+      if (this.totalPrice < this.minPrice) {
+        return
+      }
+      window.alert(`支付${this.totalPrice}元`)
+    },
+    addFood (target) {
+      this.drop(target)
+    },
+    beforeDrop (el) {
+      let count = this.balls.length
+      while (count--) {
+        let ball = this.balls[count]
+        if (ball.show) {
+          let rect = ball.el.getBoundingClientRect()
+          let x = rect.left - 32
+          let y = -(window.innerHeight - rect.top - 22)
+          el.style.display = ''
+          el.style.webkitTransform = `translate3d(0,${y}px,0)`
+          el.style.transform = `translate3d(0,${y}px,0)`
+          let inner = el.getElementsByClassName('inner-hook')[0]
+          inner.style.webkitTransform = `translate3d(${x}px,0,0)`
+          inner.style.transform = `translate3d(${x}px,0,0)`
         }
-        return show;
       }
     },
-    methods: {
-      drop(el) {
-        for (let i = 0; i < this.balls.length; i++) {
-          let ball = this.balls[i];
-          if (!ball.show) {
-            ball.show = true;
-            ball.el = el;
-            this.dropBalls.push(ball);
-            return;
+    dropping (el, done) {
+      /* eslint-disable no-unused-vars */
+      let rf = el.offsetHeight
+      this.$nextTick(() => {
+        el.style.webkitTransform = 'translate3d(0,0,0)'
+        el.style.transform = 'translate3d(0,0,0)'
+        let inner = el.getElementsByClassName('inner-hook')[0]
+        inner.style.webkitTransform = 'translate3d(0,0,0)'
+        inner.style.transform = 'translate3d(0,0,0)'
+        el.addEventListener('transitionend', done)
+      })
+    },
+    afterDrop (el) {
+      let ball = this.dropBalls.shift()
+      if (ball) {
+        ball.show = false
+        el.style.display = 'none'
+      }
+    }
+  },
+  components: {
+    cartcontrol
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.shopcart {
+  position: fixed;
+  left: 0;
+  bottom: 0;
+  z-index: 50;
+  width: 100%;
+  height: 48px;
+
+  .content {
+    display: flex;
+    background: #141d27;
+    font-size: 0;
+    color: rgba(255, 255, 255, 0.4);
+
+    .content-left {
+      flex: 1;
+
+      .logo-wrapper {
+        display: inline-block;
+        vertical-align: top;
+        position: relative;
+        top: -10px;
+        margin: 0 12px;
+        padding: 6px;
+        width: 56px;
+        height: 56px;
+        box-sizing: border-box;
+        border-radius: 50%;
+        background: #141d27;
+
+        .logo {
+          width: 100%;
+          height: 100%;
+          border-radius: 50%;
+          text-align: center;
+          background: #2b343c;
+
+          &.highlight {
+            background: rgb(0, 160, 220);
+          }
+
+          .icon-shopping_cart {
+            line-height: 44px;
+            font-size: 24px;
+            color: #80858a;
+          }
+
+          &.highlight {
+            color: #fff;
           }
         }
-      },
-      toggleList() {
-        if (!this.totalCount) {
-          return;
+
+        .num {
+          position: absolute;
+          top: 0;
+          right: 0;
+          width: 24px;
+          height: 16px;
+          line-height: 16px;
+          text-align: center;
+          border-radius: 16px;
+          font-size: 9px;
+          font-weight: 700;
+          color: #fff;
+          background: rgb(240, 20, 20);
+          box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.4);
         }
-        this.fold = !this.fold;
-      },
-      hideList() {
-        this.fold = true;
-      },
-      empty() {
-        this.selectFoods.forEach((food) => {
-          food.count = 0;
-        });
-      },
-      pay() {
-        if (this.totalPrice < this.minPrice) {
-          return;
+
+      }
+
+      .price {
+        display: inline-block;
+        vertical-align: top;
+        margin-top: 12px;
+        line-height: 24px;
+        padding-right: 12px;
+        box-sizing: border-box;
+        border-right: 1px solid rgba(255, 255, 255, 0.1);
+        font-size: 16px;
+        font-weight: 700;
+
+        &.highlight {
+          color: #fff
         }
-        window.alert(`支付${this.totalPrice}元`);
-      },
-      addFood(target) {
-        this.drop(target);
-      },
-      beforeDrop(el) {
-        let count = this.balls.length;
-        while (count--) {
-          let ball = this.balls[count];
-          if (ball.show) {
-            let rect = ball.el.getBoundingClientRect();
-            let x = rect.left - 32;
-            let y = -(window.innerHeight - rect.top - 22);
-            el.style.display = '';
-            el.style.webkitTransform = `translate3d(0,${y}px,0)`;
-            el.style.transform = `translate3d(0,${y}px,0)`;
-            let inner = el.getElementsByClassName('inner-hook')[0];
-            inner.style.webkitTransform = `translate3d(${x}px,0,0)`;
-            inner.style.transform = `translate3d(${x}px,0,0)`;
-          }
+      }
+
+      .desc {
+        display: inline-block;
+        vertical-align: top;
+        margin: 12px 0 0 12px;
+        line-height: 24px;
+        font-size: 10px;
+      }
+    }
+
+    .content-right {
+      flex: 0 0 105px;
+      width: 105px;
+
+      .pay {
+        height: 48px;
+        line-height: 48px;
+        text-align: center;
+        font-size: 12px;
+        font-weight: 700;
+
+        &.not-enough {
+          background: #2b333b;
         }
-      },
-      dropping(el, done) {
-        /* eslint-disable no-unused-vars */
-        let rf = el.offsetHeight;
-        this.$nextTick(() => {
-          el.style.webkitTransform = 'translate3d(0,0,0)';
-          el.style.transform = 'translate3d(0,0,0)';
-          let inner = el.getElementsByClassName('inner-hook')[0];
-          inner.style.webkitTransform = 'translate3d(0,0,0)';
-          inner.style.transform = 'translate3d(0,0,0)';
-          el.addEventListener('transitionend', done);
-        });
-      },
-      afterDrop(el) {
-        let ball = this.dropBalls.shift();
-        if (ball) {
-          ball.show = false;
-          el.style.display = 'none';
+
+        &.enough {
+          background: #00b43c;
+          color: #fff;
         }
       }
-    },
-    components: {
-      cartcontrol
     }
-  };
-</script>
+  }
+}
+
+.ball-container {
+  .ball {
+    position: fixed;
+    left: 32px;
+    bottom: 22px;
+    z-index: 200;
+    transition: all 0.4s cubic-bezier(0.49, -0.29, 0.75, 0.41);
+
+    .inner {
+      width: 16px;
+      height: 16px;
+      border-radius: 50%;
+      background: rgb(0, 160, 220);
+      transition: all 0.4s linear;
+    }
+  }
+}
+
+.shopcart-list {
+  position: absolute;
+  left: 0;
+  top: 0;
+  z-index: -1;
+  width: 100%;
+  transform: translate3d(0, -100%, 0);
+
+  &.fold-enter-active, &.fold-leave-active {
+    transition: all 0.5s;
+  }
+
+  &.fold-enter, &.fold-leave-active {
+    transform: translate3d(0, 0, 0);
+  }
+
+  .list-header {
+    height: 40px;
+    line-height: 40px;
+    padding: 0 18px;
+    background: #f3f5f7;
+    border-bottom: 1px solid rgba(7, 17, 27, 0.1);
+
+    .title {
+      float: left;
+      font-size: 14px;
+      color: rgb(7, 17, 27);
+    }
+
+    .empty {
+      float: right;
+      font-size: 12px;
+      color: rgb(0, 160, 220);
+    }
+  }
+
+  .list-content {
+    padding: 0 18px;
+    max-height: 217px;
+    overflow: hidden;
+    background: #fff;
+
+    .food {
+      position: relative;
+      padding: 12px 0;
+      box-sizing: border-box;
+      @include border-1px(rgba(7, 17, 27, 0.1));
+
+      .name {
+        line-height: 24px;
+        font-size: 14px;
+        color: rgb(7, 17, 27);
+      }
+
+      .price {
+        position: absolute;
+        right: 90px;
+        bottom: 12px;
+        line-height: 24px;
+        font-size: 14px;
+        font-weight: 700;
+        color: rgb(240, 20, 20);
+      }
+
+      .cartcontrol-wrapper {
+        position: absolute;
+        right: 0;
+        bottom: 6px;
+      }
+    }
+  }
+}
+
+.list-mask {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 40;
+  backdrop-filter: blur(10px);
+  opacity: 1;
+  background: rgba(7, 17, 27, 0.6);
+
+  &.fade-enter-active, &.fade-leave-active {
+    transition: all 0.5s;
+  }
+
+  &.fade-enter, &.fade-leave-active {
+    opacity: 0;
+    background: rgba(7, 17, 27, 0);
+  }
+}
+</style>

+ 0 - 44
htmldev/dashboard/src/views/sell/star/star.vue

@@ -1,44 +0,0 @@
-<template>
-  <div class="star" :class="starType">
-    <span v-for="(itemClass,index) in itemClasses" :class="itemClass" class="star-item" :key="index"></span>
-  </div>
-</template>
-
-<script type="text/ecmascript-6">
-  const LENGTH = 5;
-  const CLS_ON = 'on';
-  const CLS_HALF = 'half';
-  const CLS_OFF = 'off';
-
-  export default {
-    props: {
-      size: {
-        type: Number
-      },
-      score: {
-        type: Number
-      }
-    },
-    computed: {
-      starType() {
-        return 'star-' + this.size;
-      },
-      itemClasses() {
-        let result = [];
-        let score = Math.floor(this.score * 2) / 2;
-        let hasDecimal = score % 1 !== 0;
-        let integer = Math.floor(score);
-        for (let i = 0; i < integer; i++) {
-          result.push(CLS_ON);
-        }
-        if (hasDecimal) {
-          result.push(CLS_HALF);
-        }
-        while (result.length < LENGTH) {
-          result.push(CLS_OFF);
-        }
-        return result;
-      }
-    }
-  };
-</script>

BIN
htmldev/dashboard/src/views/sell/star/star24_half@2x.png


BIN
htmldev/dashboard/src/views/sell/star/star24_half@3x.png


BIN
htmldev/dashboard/src/views/sell/star/star24_off@2x.png


BIN
htmldev/dashboard/src/views/sell/star/star24_off@3x.png


BIN
htmldev/dashboard/src/views/sell/star/star24_on@2x.png


BIN
htmldev/dashboard/src/views/sell/star/star24_on@3x.png


BIN
htmldev/dashboard/src/views/sell/star/star36_half@2x.png


BIN
htmldev/dashboard/src/views/sell/star/star36_half@3x.png


BIN
htmldev/dashboard/src/views/sell/star/star36_off@2x.png


BIN
htmldev/dashboard/src/views/sell/star/star36_off@3x.png


BIN
htmldev/dashboard/src/views/sell/star/star36_on@2x.png


BIN
htmldev/dashboard/src/views/sell/star/star36_on@3x.png


BIN
htmldev/dashboard/src/views/sell/star/star48_half@2x.png


BIN
htmldev/dashboard/src/views/sell/star/star48_half@3x.png


BIN
htmldev/dashboard/src/views/sell/star/star48_off@2x.png


BIN
htmldev/dashboard/src/views/sell/star/star48_off@3x.png


BIN
htmldev/dashboard/src/views/sell/star/star48_on@2x.png


BIN
htmldev/dashboard/src/views/sell/star/star48_on@3x.png