Browse Source

uni-app框架搭建完成

zhengJ_docnet 4 months ago
parent
commit
68b95ebfda
48 changed files with 9242 additions and 0 deletions
  1. 20 0
      App.vue
  2. 184 0
      colorui/animation.css
  3. 65 0
      colorui/components/cu-custom.vue
  4. 139 0
      colorui/components/curry-slide.vue
  5. 410 0
      colorui/components/curry-swiper.vue
  6. 1226 0
      colorui/icon.css
  7. 4090 0
      colorui/main.css
  8. 346 0
      common/iconfont.css
  9. 0 0
      common/main.css
  10. 125 0
      common/utils/airport.js
  11. 1 0
      common/utils/amap-wx.js
  12. 239 0
      common/utils/https.js
  13. 34 0
      common/utils/request.js
  14. 60 0
      common/utils/tips.js
  15. 419 0
      components/icon/icon.vue
  16. 268 0
      components/indexed-list/indexed-list.vue
  17. 20 0
      main.js
  18. 131 0
      manifest.json
  19. 377 0
      package-lock.json
  20. 57 0
      pages.json
  21. 8 0
      pages/components/login/login.vue
  22. 8 0
      pages/components/login/pLogin.vue
  23. 8 0
      pages/components/login/wLogin.vue
  24. 103 0
      pages/components/personal/index.vue
  25. 200 0
      pages/components/signin/sign.vue
  26. 227 0
      pages/index/index.vue
  27. 68 0
      pages/list/list.vue
  28. 146 0
      pages/mypersonal/personal.vue
  29. 145 0
      pages/setting/setting.vue
  30. BIN
      static/arrow.png
  31. BIN
      static/close.png
  32. BIN
      static/cloud.jpg
  33. BIN
      static/danger.png
  34. BIN
      static/home.png
  35. BIN
      static/home_light.png
  36. BIN
      static/icon.png
  37. BIN
      static/info.png
  38. BIN
      static/location.png
  39. BIN
      static/logo.png
  40. BIN
      static/menu.png
  41. BIN
      static/people.png
  42. BIN
      static/people_light.png
  43. BIN
      static/question.png
  44. BIN
      static/setting.png
  45. BIN
      static/share_circle.png
  46. 12 0
      store/index.js
  47. 19 0
      store/modules/global.js
  48. 87 0
      uni.scss

+ 20 - 0
App.vue

@@ -0,0 +1,20 @@
+<script>
+	export default {
+		onLaunch: function() {
+			console.log('App Launch')
+		},
+		onShow: function() {
+			console.log('App Show')
+		},
+		onHide: function() {
+			console.log('App Hide')
+		}
+	}
+</script>
+
+<style lang="scss">
+	@import "colorui/main.css";
+	@import "colorui/icon.css";
+	@import "common/main.css"; /* 你的项目css */
+	@import "common/iconfont.css"
+</style>

+ 184 - 0
colorui/animation.css

@@ -0,0 +1,184 @@
+/* 
+  Animation 微动画  
+  基于ColorUI组建库的动画模块 by 文晓港 2019年3月26日19:52:28
+ */
+
+/* css 滤镜 控制黑白底色gif的 */
+.gif-black{  
+  mix-blend-mode: screen;  
+}
+.gif-white{  
+  mix-blend-mode: multiply; 
+}
+
+
+/* Animation css */
+[class*=animation-] {
+    animation-duration: .5s;
+    animation-timing-function: ease-out;
+    animation-fill-mode: both
+}
+
+.animation-fade {
+    animation-name: fade;
+    animation-duration: .8s;
+    animation-timing-function: linear
+}
+
+.animation-scale-up {
+    animation-name: scale-up
+}
+
+.animation-scale-down {
+    animation-name: scale-down
+}
+
+.animation-slide-top {
+    animation-name: slide-top
+}
+
+.animation-slide-bottom {
+    animation-name: slide-bottom
+}
+
+.animation-slide-left {
+    animation-name: slide-left
+}
+
+.animation-slide-right {
+    animation-name: slide-right
+}
+
+.animation-shake {
+    animation-name: shake
+}
+
+.animation-reverse {
+    animation-direction: reverse
+}
+
+@keyframes fade {
+    0% {
+        opacity: 0
+    }
+
+    100% {
+        opacity: 1
+    }
+}
+
+@keyframes scale-up {
+    0% {
+        opacity: 0;
+        transform: scale(.2)
+    }
+
+    100% {
+        opacity: 1;
+        transform: scale(1)
+    }
+}
+
+@keyframes scale-down {
+    0% {
+        opacity: 0;
+        transform: scale(1.8)
+    }
+
+    100% {
+        opacity: 1;
+        transform: scale(1)
+    }
+}
+
+@keyframes slide-top {
+    0% {
+        opacity: 0;
+        transform: translateY(-100%)
+    }
+
+    100% {
+        opacity: 1;
+        transform: translateY(0)
+    }
+}
+
+@keyframes slide-bottom {
+    0% {
+        opacity: 0;
+        transform: translateY(100%)
+    }
+
+    100% {
+        opacity: 1;
+        transform: translateY(0)
+    }
+}
+
+@keyframes shake {
+
+    0%,
+    100% {
+        transform: translateX(0)
+    }
+
+    10% {
+        transform: translateX(-9px)
+    }
+
+    20% {
+        transform: translateX(8px)
+    }
+
+    30% {
+        transform: translateX(-7px)
+    }
+
+    40% {
+        transform: translateX(6px)
+    }
+
+    50% {
+        transform: translateX(-5px)
+    }
+
+    60% {
+        transform: translateX(4px)
+    }
+
+    70% {
+        transform: translateX(-3px)
+    }
+
+    80% {
+        transform: translateX(2px)
+    }
+
+    90% {
+        transform: translateX(-1px)
+    }
+}
+
+@keyframes slide-left {
+    0% {
+        opacity: 0;
+        transform: translateX(-100%)
+    }
+
+    100% {
+        opacity: 1;
+        transform: translateX(0)
+    }
+}
+
+@keyframes slide-right {
+    0% {
+        opacity: 0;
+        transform: translateX(100%)
+    }
+
+    100% {
+        opacity: 1;
+        transform: translateX(0)
+    }
+}

+ 65 - 0
colorui/components/cu-custom.vue

@@ -0,0 +1,65 @@
+<template>
+	<view>
+		<view class="cu-custom" :style="[{height:CustomBar + 'px'}]">
+			<view class="cu-bar fixed" :style="style" :class="[bgImage!=''?'none-bg text-white bg-img':'',bgColor]">
+				<view class="action" @tap="BackPage" v-if="isBack">
+					<text class="cuIcon-back"></text>
+					<slot name="backText"></slot>
+				</view>
+				<view class="content" :style="[{top:StatusBar + 'px'}]">
+					<slot name="content"></slot>
+				</view>
+				<slot name="right"></slot>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				StatusBar: this.StatusBar,
+				CustomBar: this.CustomBar
+			};
+		},
+		name: 'cu-custom',
+		computed: {
+			style() {
+				var StatusBar= this.StatusBar;
+				var CustomBar= this.CustomBar;
+				var bgImage = this.bgImage;
+				var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+				if (this.bgImage) {
+					style = `${style}background-image:url(${bgImage});`;
+				}
+				return style
+			}
+		},
+		props: {
+			bgColor: {
+				type: String,
+				default: ''
+			},
+			isBack: {
+				type: [Boolean, String],
+				default: false
+			},
+			bgImage: {
+				type: String,
+				default: ''
+			},
+		},
+		methods: {
+			BackPage() {
+				uni.navigateBack({
+					delta: 1
+				});
+			}
+		}
+	}
+</script>
+
+<style>
+
+</style>

+ 139 - 0
colorui/components/curry-slide.vue

@@ -0,0 +1,139 @@
+<template>
+  <view class="carousel-3d-slide" :style="slideStyle" :class="computedClasses" @click="goTo()">
+    <slot :index="index" :isCurrent="isCurrent" :leftIndex="leftIndex" :rightIndex="rightIndex"/>
+  </view>
+</template>
+
+<script>
+/* eslint-disable */
+export default {
+  name: 'curry-slide',
+  props: {
+    index: {
+      type: Number
+    }
+  },
+  data () {
+    return {
+      parent: this.$parent,
+      styles: {},
+      zIndex: 999
+    }
+  },
+  computed: {
+    isCurrent () {
+      return this.index === this.parent.currentIndex
+    },
+    leftIndex () {
+      return this.getSideIndex(this.parent.leftIndices)
+    },
+    rightIndex () {
+      return this.getSideIndex(this.parent.rightIndices)
+    },
+    slideStyle () {
+      let styles = {}
+      if (!this.isCurrent) {
+        const rIndex = this.leftIndex
+        const lIndex = this.rightIndex
+        if (rIndex >= 0 || lIndex >= 0) {
+          styles = rIndex >= 0 ? this.calculatePosition(rIndex, true, this.zIndex) : this.calculatePosition(lIndex, false, this.zIndex)
+          styles.opacity = 1
+          styles.visibility = 'visible'
+        }
+        if (this.parent.hasHiddenSlides) {
+          if (this.matchIndex(this.parent.leftOutIndex)) {
+            styles = this.calculatePosition(this.parent.leftIndices.length - 1, false, this.zIndex)
+          } else if (this.matchIndex(this.parent.rightOutIndex)) {
+            styles = this.calculatePosition(this.parent.rightIndices.length - 1, true, this.zIndex)
+          }
+        }
+      }
+      return Object.assign(styles, {
+        'border-width': this.parent.border + 'px',
+        'width': this.parent.slideWidth + 'px',
+        'height': this.parent.slideHeight + 'px',
+        'transition': ' transform ' + this.parent.animationSpeed + 'ms, ' +
+        '               opacity ' + this.parent.animationSpeed + 'ms, ' +
+        '               visibility ' + this.parent.animationSpeed + 'ms'
+      })
+    },
+    computedClasses () {
+      return {
+        [`left-${this.leftIndex + 1}`]: this.leftIndex >= 0,
+        [`right-${this.rightIndex + 1}`]: this.rightIndex >= 0,
+        'current': this.isCurrent
+      }
+    }
+  },
+  methods: {
+    getSideIndex (array) {
+      let index = -1
+      array.forEach((pos, i) => {
+        if (this.matchIndex(pos)) {
+          index = i
+        }
+      })
+      return index
+    },
+    matchIndex (index) {
+      return (index >= 0) ? this.index === index : (this.parent.total + index) === this.index
+    },
+    calculatePosition (i, positive, zIndex) {
+      const z = !this.parent.disable3d ? parseInt(this.parent.inverseScaling) + ((i + 1) * 100) : 0
+      const y = !this.parent.disable3d ? parseInt(this.parent.perspective) : 0
+      const leftRemain = (this.parent.space === 'auto')
+        ? parseInt((i + 1) * (this.parent.width / 1.2), 10) // 1.5
+        : parseInt((i + 1) * (this.parent.space), 10)
+      const transform = (positive)
+        ? 'translateX(' + (leftRemain) + 'px) translateZ(-' + z + 'px) ' +
+        'rotateY(-' + y + 'deg)'
+        : 'translateX(-' + (leftRemain) + 'px) translateZ(-' + z + 'px) ' +
+        'rotateY(' + y + 'deg)'
+      const top = this.parent.space === 'auto' ? 0 : parseInt((i + 1) * (this.parent.space))
+      return {
+        transform: transform,
+        top: top,
+        zIndex: zIndex - (Math.abs(i) + 1)
+      }
+    },
+    goTo () {
+      if (!this.isCurrent) {
+        if (this.parent.clickable === true) {
+          this.parent.goFar(this.index)
+        }
+      } else {
+        this.parent.onMainSlideClick()
+      }
+    }
+  }
+}
+</script>
+
+<style>
+  .carousel-3d-slide {
+    position: absolute;
+    opacity: 0;
+    visibility: hidden;
+    overflow: hidden;
+    top: 0;
+    border-color: #023c41;
+    border-style: solid;
+    background-size: cover;
+    background-color: #ccc;
+    display: block;
+    margin: 0;
+    box-sizing: border-box;
+  }
+  .carousel-3d-slide {
+    text-align: left;
+  }
+  .carousel-3d-slide img {
+    width: 100%;
+  }
+  .carousel-3d-slide.current {
+    opacity: 1 !important;
+    visibility: visible !important;
+    transform: none !important;
+    z-index: 999;
+  }
+</style>

+ 410 - 0
colorui/components/curry-swiper.vue

@@ -0,0 +1,410 @@
+<template>
+  <view class="carousel-3d-container" :style="{height: this.slideHeight + 'px'}">
+    <view class="carousel-3d-slider" :style="{width: this.slideWidth + 'px', height: this.slideHeight + 'px'}">
+      <slot></slot>
+    </view>
+  </view>
+</template>
+
+<script>
+/* eslint-disable */
+  const noop = () => {
+  }
+  export default {
+    name: 'curry-swiper',
+    props: {
+      // Number of slides
+      count: {
+        type: [Number, String],
+        default: 0
+      },
+      // Slides perspective position
+      perspective: {
+        type: [Number, String],
+        default: 35
+      },
+      // Number of slides displayed on each page
+      display: {
+        type: [Number, String],
+        default: 3
+      },
+      loop: {
+        type: Boolean,
+        default: true
+      },
+      // Animation between slides in milliseconds
+      animationSpeed: {
+        type: [Number, String],
+        default: 500
+      },
+      // Animation direction
+      dir: {
+        type: String,
+        default: 'ltr'
+      },
+      width: {
+        type: [Number, String],
+        default: 360
+      },
+      height: {
+        type: [Number, String],
+        default: 270
+      },
+      border: {
+        type: [Number, String],
+        default: 1
+      },
+      // Space between slides in pixels
+      space: {
+        type: [Number, String],
+        default: 'auto'
+      },
+      // Start slide index. First slide has 0 index
+      startIndex: {
+        type: [Number, String],
+        default: 0
+      },
+      // Enable navigation by clicking on slide
+      clickable: {
+        type: Boolean,
+        default: true
+      },
+      disable3d: {
+        type: Boolean,
+        default: false
+      },
+      // Minimum distance in pixels to swipe before a slide advance is triggered
+      minSwipeDistance: {
+        type: Number,
+        default: 10
+      },
+      // Slide inverse scaling
+      inverseScaling: {
+        type: [Number, String],
+        default: 300
+      },
+      onLastSlide: {
+        type: Function,
+        default: noop
+      },
+      onSlideChange: {
+        type: Function,
+        default: noop
+      },
+      bias: {
+        type: String,
+        default: 'left'
+      },
+      onMainSlideClick: {
+        type: Function,
+        default: noop
+      }
+    },
+    data () {
+      return {
+        viewport: 0,
+        currentIndex: 0,
+        total: 0,
+        dragOffset: 0,
+        dragStartX: 0,
+        mousedown: false,
+        zIndex: 998
+      }
+    },
+    watch: {
+      count () {
+        this.computeData()
+      }
+    },
+    computed: {
+      isLastSlide () {
+        return this.currentIndex === this.total - 1
+      },
+      isFirstSlide () {
+        return this.currentIndex === 0
+      },
+      isNextPossible () {
+        return !(!this.loop && this.isLastSlide)
+      },
+      isPrevPossible () {
+        return !(!this.loop && this.isFirstSlide)
+      },
+      slideWidth () {
+        const vw = this.viewport
+        const sw = parseInt(this.width) + (parseInt(this.border, 10) * 2)
+        return vw < sw ? vw : sw
+      },
+      slideHeight () {
+        const sw = parseInt(this.width, 10) + (parseInt(this.border, 10) * 2)
+        const sh = parseInt(parseInt(this.height) + (this.border * 2), 10)
+        const ar = this.calculateAspectRatio(sw, sh)
+        return this.slideWidth / ar
+      },
+      visible () {
+        const v = (this.display > this.total) ? this.total : this.display
+        return v
+      },
+      hasHiddenSlides () {
+        return this.total > this.visible
+      },
+      leftIndices () {
+        let n = (this.visible - 1) / 2
+        n = (this.bias.toLowerCase() === 'left' ? Math.ceil(n) : Math.floor(n))
+        const indices = []
+        for (let m = 1; m <= n; m++) {
+          indices.push((this.dir === 'ltr')
+            ? (this.currentIndex + m) % (this.total)
+            : (this.currentIndex - m) % (this.total))
+        }
+        return indices
+      },
+      rightIndices () {
+        let n = (this.visible - 1) / 2
+        n = (this.bias.toLowerCase() === 'right' ? Math.ceil(n) : Math.floor(n))
+        const indices = []
+        for (let m = 1; m <= n; m++) {
+          indices.push((this.dir === 'ltr')
+            ? (this.currentIndex - m) % (this.total)
+            : (this.currentIndex + m) % (this.total))
+        }
+        return indices
+      },
+      leftOutIndex () {
+        let n = (this.visible - 1) / 2
+        n = (this.bias.toLowerCase() === 'left' ? Math.ceil(n) : Math.floor(n))
+        n++
+        if (this.dir === 'ltr') {
+          return ((this.total - this.currentIndex - n) <= 0)
+            ? (-parseInt(this.total - this.currentIndex - n))
+            : (this.currentIndex + n)
+        } else {
+          return (this.currentIndex - n)
+        }
+      },
+      rightOutIndex () {
+        let n = (this.visible - 1) / 2
+        n = (this.bias.toLowerCase() === 'right' ? Math.ceil(n) : Math.floor(n))
+        n++
+        if (this.dir === 'ltr') {
+          return (this.currentIndex - n)
+        } else {
+          return ((this.total - this.currentIndex - n) <= 0)
+            ? (-parseInt(this.total - this.currentIndex - n, 10))
+            : (this.currentIndex + n)
+        }
+      }
+    },
+    methods: {
+      /**
+       * Go to next slide
+       */
+      goNext () {
+        if (this.isNextPossible) {
+          this.isLastSlide ? this.goSlide(0) : this.goSlide(this.currentIndex + 1)
+        }
+      },
+      /**
+       * Go to previous slide
+       */
+      goPrev () {
+        if (this.isPrevPossible) {
+          this.isFirstSlide ? this.goSlide(this.total - 1) : this.goSlide(this.currentIndex - 1)
+        }
+      },
+      /**
+       * Go to slide
+       * @param  {String} index of slide where to go
+       */
+      goSlide (index) {
+        this.currentIndex = (index < 0 || index > this.total - 1) ? 0 : index
+        if (this.isLastSlide) {
+          if (this.onLastSlide !== noop) {
+            console.warn('onLastSlide deprecated, please use @last-slide')
+          }
+          this.onLastSlide(this.currentIndex)
+          this.$emit('last-slide', this.currentIndex)
+        }
+        this.$emit('before-slide-change', this.currentIndex)
+        setTimeout(() => this.animationEnd(), this.animationSpeed)
+      },
+      /**
+       * Go to slide far slide
+       */
+      goFar (index) {
+        let diff = (index === this.total - 1 && this.isFirstSlide) ? -1 : (index - this.currentIndex)
+        if (this.isLastSlide && index === 0) {
+          diff = 1
+        }
+        const diff2 = (diff < 0) ? -diff : diff
+        let timeBuff = 0
+        let i = 0
+        while (i < diff2) {
+          i += 1
+          const timeout = (diff2 === 1) ? 0 : (timeBuff)
+          setTimeout(() => (diff < 0) ? this.goPrev(diff2) : this.goNext(diff2), timeout)
+          timeBuff += (this.animationSpeed / (diff2))
+        }
+      },
+      /**
+       * Trigger actions when animation ends
+       */
+      animationEnd () {
+        if (this.onSlideChange !== noop) {
+          console.warn('onSlideChange deprecated, please use @after-slide-change')
+        }
+        this.onSlideChange(this.currentIndex)
+        this.$emit('after-slide-change', this.currentIndex)
+      },
+      /**
+       * Trigger actions when mouse is released
+       * @param  {Object} e The event object
+       */
+      handleMouseup () {
+        this.mousedown = false
+        this.dragOffset = 0
+      },
+      /**
+       * Trigger actions when mouse is pressed
+       * @param  {Object} e The event object
+       */
+      handleMousedown (e) {
+        if (!e.touches) {
+          e.preventDefault()
+        }
+        this.mousedown = true
+        this.dragStartX = ('ontouchstart' in window) ? e.touches[0].clientX : e.clientX
+      },
+      /**
+       * Trigger actions when mouse is pressed and then moved (mouse drag)
+       * @param  {Object} e The event object
+       */
+      handleMousemove (e) {
+          if (!this.mousedown) {
+            return
+          }
+          const eventPosX = ('ontouchstart' in window) ? e.touches[0].clientX : e.clientX
+          const deltaX = (this.dragStartX - eventPosX)
+          this.dragOffset = deltaX
+          if (this.dragOffset > this.minSwipeDistance) {
+            this.handleMouseup()
+            this.goNext()
+          } else if (this.dragOffset < -this.minSwipeDistance) {
+            this.handleMouseup()
+            this.goPrev()
+          }
+      },
+      /**
+       * A mutation observer is used to detect changes to the containing node
+       * in order to keep the magnet container in sync with the height its reference node.
+       */
+      attachMutationObserver () {
+        const MutationObserver = window.MutationObserver ||
+          window.WebKitMutationObserver ||
+          window.MozMutationObserver
+        if (MutationObserver) {
+          const config = {
+            attributes: true,
+            childList: true,
+            characterData: true
+          }
+          this.mutationObserver = new MutationObserver(() => {
+            this.$nextTick(() => {
+              this.computeData()
+            })
+          })
+          if (this.$el) {
+            this.mutationObserver.observe(this.$el, config)
+          }
+        }
+      },
+      /**
+       * Stop listening to mutation changes
+       */
+      detachMutationObserver () {
+        if (this.mutationObserver) {
+          this.mutationObserver.disconnect()
+        }
+      },
+      /**
+       * Get the number of slides
+       * @return {Number} Number of slides
+       */
+      getSlideCount () {
+        if (this.$slots.default !== undefined) {
+          return this.$slots.default.filter((value) => {
+            return value.tag !== void 0
+          }).length
+        }
+        return 0
+      },
+      /**
+       * Calculate slide with and keep defined aspect ratio
+       * @return {Number} Aspect ratio number
+       */
+      calculateAspectRatio (width, height) {
+        return Math.min(width / height)
+      },
+      /**
+       * Re-compute the number of slides and current slide
+       */
+      computeData (firstRun) {
+        this.total = this.getSlideCount()
+        if (firstRun || this.currentIndex >= this.total) {
+          this.currentIndex = parseInt(this.startIndex) > this.total - 1 ? this.total - 1 : parseInt(this.startIndex)
+        }
+        this.viewport = this.$el.clientWidth
+      },
+      setSize () {
+        this.$el.style.cssText += 'height:' + this.slideHeight + 'px;'
+        this.$el.childNodes[0].style.cssText += 'width:' + this.slideWidth + 'px;' + ' height:' + this.slideHeight + 'px;'
+      }
+    },
+    mounted () {
+      this.computeData(true)
+      this.attachMutationObserver()
+      if (!this.$isServer) {
+        window.addEventListener('resize', this.setSize)
+        if ('ontouchstart' in window) {
+          this.$el.addEventListener('touchstart', this.handleMousedown)
+          this.$el.addEventListener('touchend', this.handleMouseup)
+          this.$el.addEventListener('touchmove', this.handleMousemove)
+        } else {
+          this.$el.addEventListener('mousedown', this.handleMousedown)
+          this.$el.addEventListener('mouseup', this.handleMouseup)
+          this.$el.addEventListener('mousemove', this.handleMousemove)
+        }
+      }
+    },
+    beforeDestroy () {
+      if (!this.$isServer) {
+        this.detachMutationObserver()
+        if ('ontouchstart' in window) {
+          this.$el.removeEventListener('touchmove', this.handleMousemove)
+        } else {
+          this.$el.removeEventListener('mousemove', this.handleMousemove)
+        }
+        window.removeEventListener('resize', this.setSize)
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+  .carousel-3d-container {
+    min-height: 1px;
+    width: 100%;
+    position: relative;
+    z-index: 0;
+    overflow: hidden;
+    margin: 0px auto;
+    box-sizing: border-box;
+  }
+  .carousel-3d-slider {
+    position: relative;
+    margin: 0 auto;
+    transform-style: preserve-3d;
+    -webkit-perspective: 1000px;
+    -moz-perspective: 1000px;
+    perspective: 1000px;
+  }
+</style>

File diff suppressed because it is too large
+ 1226 - 0
colorui/icon.css


File diff suppressed because it is too large
+ 4090 - 0
colorui/main.css


+ 346 - 0
common/iconfont.css

@@ -0,0 +1,346 @@
+@font-face {
+  font-family: 'iconfont';  /* project id 878519 */
+  src: url('//at.alicdn.com/t/font_878519_lkhdlz7l07h.eot');
+  src: url('//at.alicdn.com/t/font_878519_lkhdlz7l07h.eot?#iefix') format('embedded-opentype'),
+  url('//at.alicdn.com/t/font_878519_lkhdlz7l07h.woff2') format('woff2'),
+  url('//at.alicdn.com/t/font_878519_lkhdlz7l07h.woff') format('woff'),
+  url('//at.alicdn.com/t/font_878519_lkhdlz7l07h.ttf') format('truetype'),
+  url('//at.alicdn.com/t/font_878519_lkhdlz7l07h.svg#iconfont') format('svg');
+}
+
+.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-30:before {
+  content: "\e686";
+}
+
+.icon-05:before {
+  content: "\e688";
+}
+
+.icon-menu:before {
+  content: "\e630";
+}
+
+.icon-unie64d:before {
+  content: "\e6b0";
+}
+
+.icon-31:before {
+  content: "\e637";
+}
+
+.icon-19:before {
+  content: "\e8b7";
+}
+
+.icon-09:before {
+  content: "\e758";
+}
+
+.icon-tishi:before {
+  content: "\e653";
+}
+
+.icon-xiaoxizhongxin:before {
+  content: "\e665";
+}
+
+.icon-shezhi:before {
+  content: "\e68f";
+}
+
+.icon-xitongcaidan:before {
+  content: "\e696";
+}
+
+.icon-16:before {
+  content: "\e6f1";
+}
+
+.icon-10:before {
+  content: "\e6f2";
+}
+
+.icon-01:before {
+  content: "\e6f4";
+}
+
+.icon-leidian:before {
+  content: "\e6f5";
+}
+
+.icon-00:before {
+  content: "\e6f6";
+}
+
+.icon-14:before {
+  content: "\e6f7";
+}
+
+.icon-07:before {
+  content: "\e6f9";
+}
+
+.icon-02:before {
+  content: "\e6fa";
+}
+
+.icon-13:before {
+  content: "\e6fb";
+}
+
+.icon-03:before {
+  content: "\e6fc";
+}
+
+.icon-15:before {
+  content: "\e6fd";
+}
+
+.icon-08:before {
+  content: "\e6fe";
+}
+
+.icon-fanhui:before {
+  content: "\e6ff";
+}
+
+.icon-bingbao:before {
+  content: "\e706";
+}
+
+.icon-53:before {
+  content: "\e709";
+}
+
+.icon-18:before {
+  content: "\e70a";
+}
+
+.icon-06:before {
+  content: "\e70b";
+}
+
+.icon-yuyan:before {
+  content: "\e62c";
+}
+
+.icon-qingchu:before {
+  content: "\e64a";
+}
+
+.icon-04:before {
+  content: "\e658";
+}
+
+.icon-gengduo-hengxiang:before {
+  content: "\e8c4";
+}
+
+.icon-xiazaidaoru:before {
+  content: "\e8c6";
+}
+
+.icon-add:before {
+  content: "\e6df";
+}
+
+.icon-addition:before {
+  content: "\e6e0";
+}
+
+.icon-document:before {
+  content: "\e6f3";
+}
+
+.icon-enter:before {
+  content: "\e6f8";
+}
+
+.icon-like_fill:before {
+  content: "\e707";
+}
+
+.icon-like:before {
+  content: "\e708";
+}
+
+.icon-play_fill:before {
+  content: "\e717";
+}
+
+.icon-trash:before {
+  content: "\e738";
+}
+
+.icon-search:before {
+  content: "\e741";
+}
+
+.icon-tongzhi:before {
+  content: "\e61d";
+}
+
+.icon-29:before {
+  content: "\e60b";
+}
+
+.icon-bofang:before {
+  content: "\e624";
+}
+
+.icon-zanting:before {
+  content: "\e629";
+}
+
+.icon-shoucang:before {
+  content: "\e627";
+}
+
+.icon-jiantouxia:before {
+  content: "\e62d";
+}
+
+.icon-dizhiguanli:before {
+  content: "\e63f";
+}
+
+.icon-11:before {
+  content: "\e614";
+}
+
+.icon-yinle:before {
+  content: "\e990";
+}
+
+.icon-yinle1:before {
+  content: "\e62b";
+}
+
+.icon-17:before {
+  content: "\e631";
+}
+
+.icon-tubiaolunkuo-:before {
+  content: "\e613";
+}
+
+.icon-unmap:before {
+  content: "\e600";
+}
+
+.icon-home:before {
+  content: "\e7c6";
+}
+
+.icon-comf:before {
+  content: "\e669";
+}
+
+.icon-20:before {
+  content: "\e6d6";
+}
+
+.icon-sousuo1:before {
+  content: "\eafe";
+}
+
+.icon-kuaisugongzuoliu_o:before {
+  content: "\eb55";
+}
+
+.icon-shouye:before {
+  content: "\e632";
+}
+
+.icon-wode:before {
+  content: "\e633";
+}
+
+.icon-liebiao:before {
+  content: "\e63a";
+}
+
+.icon-xingbiao:before {
+  content: "\e642";
+}
+
+.icon-sousuo:before {
+  content: "\e644";
+}
+
+.icon-sousuo_light-copy:before {
+  content: "\e645";
+}
+
+.icon-xingbiao_light-copy:before {
+  content: "\e646";
+}
+
+.icon-liebiao_light-copy:before {
+  content: "\e647";
+}
+
+.icon-wode_light-copy:before {
+  content: "\e648";
+}
+
+.icon-shouye_light-copy:before {
+  content: "\e649";
+}
+
+.icon-play-copy:before {
+  content: "\eb57";
+}
+
+.icon-stop-copy:before {
+  content: "\eb58";
+}
+
+.icon-left-copy:before {
+  content: "\eb59";
+}
+
+.icon-12:before {
+  content: "\e743";
+}
+
+.icon-air:before {
+  content: "\e604";
+}
+
+.icon-trav:before {
+  content: "\e61c";
+}
+
+.icon-drsg:before {
+  content: "\e602";
+}
+
+.icon-flu:before {
+  content: "\e603";
+}
+
+.icon-uv:before {
+  content: "\e601";
+}
+
+.icon-guanbi:before {
+  content: "\e610";
+}
+
+.icon-sport:before {
+  content: "\e656";
+}
+
+.icon-cw:before {
+  content: "\e62f";
+}
+

+ 0 - 0
common/main.css


File diff suppressed because it is too large
+ 125 - 0
common/utils/airport.js


File diff suppressed because it is too large
+ 1 - 0
common/utils/amap-wx.js


+ 239 - 0
common/utils/https.js

@@ -0,0 +1,239 @@
+const weather = 'https://free-api.heweather.net/s6/weather'
+const future = 'http://v.juhe.cn/weather/index'
+const air = 'https://free-api.heweather.net/s6/air/now'
+const locl = 'http://apis.juhe.cn/geo/'
+const QQ_MAP_KEY1 = '630ac2e3d80941b48c80fe3a8ed1a042'
+const QQ_MAP_KEY2 = 'c649beb3621c84ee57c365f45a9a6ed4'
+const QQ_MAP_KEY3 = 'dd35eaa26348f268f1f02b4a8fbe4aaf'
+
+
+//添加finally事件
+Promise.prototype.finally = function (callback) {
+    var Promise = this.constructor;
+    return this.then(
+        function (value) {
+            Promise.resolve(callback()).then(
+                function () {
+                    return value;
+                }
+            );
+        },
+        function (reason) {
+            Promise.resolve(callback()).then(
+                function () {
+                    throw reason;
+                }
+            );
+        }
+    );
+}
+
+// 实况天气
+function getWeather(location) {
+	return new Promise((resolve, reject) => {
+		uni.request({
+			url: weather+"/now",
+			data: {
+				location:location,
+				key: QQ_MAP_KEY1
+			},
+			success: (res) => {
+				resolve({result: res.data})
+			},
+			fail: (e) => {
+				reject(e)
+			},
+			complete: (e) => {
+		  	
+			}
+		})
+	})
+}
+// 未来天气
+function getFuture(location) {
+	return new Promise((resolve, reject) => {
+		uni.request({
+			// url: "/v/weather/index",
+			url: weather+"/forecast",
+			data: {
+				// cityname:location,
+				// key: QQ_MAP_KEY2
+				
+				location:location,
+				key: QQ_MAP_KEY1
+			},
+			success: (res) => {
+				resolve({result: res.data})
+			},
+			fail: (e) => {
+				reject(e)
+			},
+			complete: (e) => {
+		  	
+			}
+		})
+	})
+}
+// 生活指数
+function getLift(location) {
+	return new Promise((resolve, reject) => {
+	    uni.request({
+	        url: weather+"/lifestyle",
+	        data: {
+	            location:location,
+	            key: QQ_MAP_KEY1,
+	        },
+	        success: (res) => {
+	            resolve({result:res.data})
+	        },
+	        fail: (e) => {
+	            reject(e)
+	        }
+	    })
+	})
+}
+// 空气质量---废弃
+function getAir(location) {
+	return new Promise((resolve, reject) => {
+	    uni.request({
+	        url: air,
+	        data: {
+	            location:location,
+	            key: QQ_MAP_KEY1,
+	        },
+	        success: (res) => {
+	            resolve({result:res.data})
+	        },
+	        fail: (e) => {
+	            reject(e)
+	        }
+	    })
+	})
+}
+// 經緯度逆解析
+function gelocation(obj) {
+	return new Promise((resolve, reject) => {
+	    uni.request({
+	        url: "/api/geo/",
+	        data: {
+	          key: QQ_MAP_KEY3,
+	          lat:obj.lat,
+	          lng:obj.lng,
+	          type:1
+	        },
+	        success: (res) => {
+	            resolve({result:res.data})
+	        },
+	        fail: (e) => {
+	            reject(e)
+	        }
+	    })
+	})
+}
+
+export {
+	getWeather,
+	getFuture,
+	getLift,
+	getAir,
+	gelocation
+}
+
+
+// export const getWeather = (location) => {
+//   return new Promise((resolve, reject) => {
+//     wx.request({
+//       url: 'https://free-api.heweather.net/s6/weather/now',
+//       data: {
+//         location:location,
+//         key: QQ_MAP_KEY1
+//       },
+//       success: (res) => {
+//         resolve({result: res.data})
+//       },
+//       fail: (e) => {
+//         reject(e)
+//       },
+// 	  complete: (e) => {
+// 	  	
+// 	  }
+//     })
+//   })
+// }
+// 未来七天天气
+// export const getFuture = (location) => {
+//   return new Promise((resolve, reject) => {
+//     wx.request({
+//       url: 'http://v.juhe.cn/weather/index',
+//       data: {
+//         cityname:location,
+//         key: QQ_MAP_KEY2
+//       },
+//       success: (res) => {
+//         console.log(res)
+//         resolve({result: res.data})
+//       },
+//       fail: (e) => {
+//         console.log("haha  chucuo 2 ")
+//         reject(e)
+//       }
+//     })
+//   })
+// }
+// 生活指数
+// export const getLift = (location) => {
+//     return new Promise((resolve, reject) => {
+//         wx.request({
+//             url: 'https://free-api.heweather.net/s6/weather/lifestyle',
+//             data: {
+//                 location:location,
+//                 key: QQ_MAP_KEY1,
+//             },
+//             success: (res) => {
+//                 resolve({result:res.data})
+//             },
+//             fail: (e) => {
+//                 reject(e)
+//             }
+//         })
+//     })
+// }
+// 获取空气质量
+// export const getAir = (location) => {
+//   return new Promise((resolve, reject) => {
+//       wx.request({
+//           url: 'https://free-api.heweather.net/s6/air/now',
+//           data: {
+//               location:location,
+//               key: QQ_MAP_KEY1,
+//           },
+//           success: (res) => {
+//               resolve({result:res.data})
+//           },
+//           fail: (e) => {
+//               reject(e)
+//           }
+//       })
+//   })
+// }
+// 经纬度逆向解析
+// export const gelocation = (obj) => {
+//   return new Promise((resolve, reject) => {
+//       wx.request({
+//           url: 'http://apis.juhe.cn/geo/',
+//           data: {
+//             key: QQ_MAP_KEY3,
+//             lat:obj.lat,
+//             lng:obj.lng,
+//             type:1
+//           },
+//           success: (res) => {
+//               resolve({result:res.data})
+//           },
+//           fail: (e) => {
+//               reject(e)
+//           }
+//       })
+//   })
+// }
+

+ 34 - 0
common/utils/request.js

@@ -0,0 +1,34 @@
+// get方法
+const Get =  function(url, msg) {
+	return new Promise((resolve, reject) => {
+		uni.request({
+			url: url,
+			success: (res) => {
+				resolve({result: res.data})
+			},
+			fail: (e) => {
+				reject(e)
+			}
+		})
+	})
+}
+// post方法
+const Post = function(url, data, msg) {
+	return new Promise((resolve, reject) => {
+		uni.request({
+			url: url,
+			data: data,
+			success: (res) => {
+				resolve({result: res.data})
+			},
+			fail: (e) => {
+				reject(e)
+			}
+		})
+	})
+}
+
+export default {
+	Get,
+	Post
+}

+ 60 - 0
common/utils/tips.js

@@ -0,0 +1,60 @@
+var WEEK_NAME = ['周一', '周二', '周三', '周四', '周五', '周六', '周日', '周一', '周二', '周三', '周四', '周五', '周六', '周日']
+
+function tip(str) {
+	uni.showToast({
+		title: str,
+		icon:"none",
+		duration:5000
+	})
+}
+
+function tips(str) {
+	uni.showToast({
+		title: str,
+		icon:"success",
+		duration:2000
+	})
+}
+
+function Loding(str) {
+	uni.showLoading({
+		title:str,
+		mask:true
+	})
+}
+
+function HideLoding() {
+	uni.hideLoading();
+}
+
+function cutting(val){
+	var strArr = val.split("~")
+	return strArr
+}
+
+function humidity(h) {
+    if (h) {
+        return '湿度 ' + h + '%'
+    }
+    return h
+}
+
+function formatWeeklyDate(i) {
+	var now = getDate()
+	var names = ['今天', '明天', '后天']
+	if (names[i]) {
+		return names[i]
+	}
+	var curWeek = now.getDay() - 1 + i
+	return WEEK_NAME[curWeek]
+}
+
+export {
+	tip,
+	tips,
+	Loding,
+	HideLoding,
+	cutting,
+	humidity,
+	formatWeeklyDate
+}

File diff suppressed because it is too large
+ 419 - 0
components/icon/icon.vue


+ 268 - 0
components/indexed-list/indexed-list.vue

@@ -0,0 +1,268 @@
+<template>
+	<view class="uni-indexed">
+		<scroll-view :scroll-into-view="scrollViewId" :style="{ height: winHeight + 'px' }" class="uni-indexed__list" scroll-y>
+			<block v-for="(list, idx) in lists" :key="idx">
+				<view v-if="list.items && list.items.length > 0" :id="'uni-indexed-list-' + list.key" class="uni-indexed__list-title">{{ list.key }}</view>
+				<view v-if="list.items && list.items.length > 0" class="uni-list">
+					<view v-for="(item, index) in list.items" :key="index" class="uni-list-item" hover-class="uni-list-item--hover">
+						<view class="uni-list-item__container" @click="onClick(idx, index)">
+							<view v-if="showSelect" style="margin-right: 20upx;">
+								<uni-icon :type="item.checked ? 'checkbox-filled' : 'circle'" :color="item.checked ? '#007aff' : '#aaa'" size="24" />
+							</view>
+							<view class="uni-list-item__content">{{ item.name }}</view>
+						</view>
+					</view>
+				</view>
+			</block>
+		</scroll-view>
+		<view :class="touchmove ? 'active' : ''" :style="{ height: winHeight + 'px' }" class="uni-indexed__menu" @touchstart="touchStart" @touchmove.stop.prevent="touchMove" @touchend="touchEnd">
+			<text v-for="(list, key) in lists" :key="key" :class="touchmoveIndex == key ? 'active' : ''" :style="{ height: itemHeight + 'px', lineHeight: itemHeight + 'px' }" class="uni-indexed__menu-item">
+				{{ list.key }}
+			</text>
+		</view>
+		<view v-if="touchmove" class="uni-indexed--alert">{{ lists[touchmoveIndex].key }}</view>
+	</view>
+</template>
+<script>
+	import uniIcon from '../icon/icon.vue';
+	export default {
+		name: 'UniIndexedList',
+		components: {
+			uniIcon
+		},
+		props: {
+			options: {
+				type: Array,
+				default () {
+					return [];
+				}
+			},
+			showSelect: {
+				type: Boolean,
+				default: false
+			}
+		},
+		data() {
+			return {
+				lists: [],
+				touchmove: false,
+				touchmoveIndex: -1,
+				itemHeight: 0,
+				winHeight: 0,
+				scrollViewId: ''
+			};
+		},
+		created() {
+			let winHeight = uni.getSystemInfoSync().windowHeight;
+			this.itemHeight = winHeight / this.options.length;
+			this.winHeight = winHeight;
+
+			// if (!this.showSelect) {
+			// 	this.lists = this.options;
+			// 	return;
+			// }
+			// console.log(this.options)
+			this.lists = this.options.map(value => {
+				// console.log(value)
+				let items = value.data.map(item => {
+					let obj = {};
+					// for (let key in item) {
+					obj['key'] = value.letter;
+					obj['name'] = item
+					// }
+					obj.checked = item.checked ? item.checked : false;
+					return obj;
+				});
+				return {
+					title: value.letter,
+					key: value.letter,
+					items: items
+				};
+			});
+			// console.log(this.lists)
+		},
+		methods: {
+			touchStart(e) {
+				this.touchmove = true;
+				let pageY = e.touches[0].pageY;
+				let index = Math.floor(pageY / this.itemHeight);