Quellcode durchsuchen

整体更新,预约-券码核销-门店核销-线下订单核销-登录授权-日历接口、bug修改

duanqichao vor 4 Jahren
Ursprung
Commit
daca825c96
100 geänderte Dateien mit 6561 neuen und 43 gelöschten Zeilen
  1. 7 1
      app.json
  2. 1 1
      bargain/goods/goods.js
  3. 43 0
      components/_toast/_toast1.wxml
  4. 48 0
      components/_toast/_toast1.wxss
  5. 0 1
      components/calendar/calendar-converter.js
  6. 0 1
      components/calendar/calendar.wxml
  7. 0 1
      components/calendar/calendar.wxss
  8. 144 0
      components/calendar/core.js
  9. 12 0
      components/calendar/helper.js
  10. 225 0
      components/calendar/index.js
  11. 3 0
      components/calendar/index.json
  12. 58 0
      components/calendar/index.wxml
  13. 214 0
      components/calendar/index.wxss
  14. 224 0
      components/calendar/plugins/holidays/holidays-map.js
  15. 153 0
      components/calendar/plugins/holidays/index.js
  16. 18 0
      components/calendar/plugins/index.js
  17. 274 0
      components/calendar/plugins/preset/base.js
  18. 69 0
      components/calendar/plugins/preset/get-calendar-data.js
  19. 9 0
      components/calendar/plugins/preset/index.js
  20. 222 0
      components/calendar/plugins/selectable.js
  21. 1036 0
      components/calendar/plugins/solarLunar/convertSolarLunar.js
  22. 47 0
      components/calendar/plugins/solarLunar/index.js
  23. 305 0
      components/calendar/plugins/time-range.js
  24. 150 0
      components/calendar/plugins/todo.js
  25. 432 0
      components/calendar/plugins/week.js
  26. 51 0
      components/calendar/render.js
  27. 2 0
      components/calendar/theme/iconfont.wxss
  28. 61 0
      components/calendar/theme/theme-default.wxss
  29. 58 0
      components/calendar/theme/theme-elegant.wxss
  30. 285 0
      components/calendar/utils/index.js
  31. 23 0
      components/calendar/utils/logger.js
  32. 30 0
      components/calendar/utils/wxData.js
  33. 5 1
      components/common/common.wxml
  34. 0 0
      components/goods/goods_buy.js
  35. 0 0
      components/goods/goods_buy.wxml
  36. 31 1
      components/goods/goods_recommend.js
  37. 0 0
      components/quick-navigation/quick-navigation.wxml
  38. 11 1
      core/api.js
  39. 14 1
      core/config.js
  40. 0 0
      core/const.js
  41. 4 1
      core/getUser.js
  42. 11 1
      core/login.js
  43. 0 0
      core/order-pay.js
  44. 8 1
      core/page.js
  45. 72 1
      core/request.js
  46. BIN
      images/icon-login-index.png
  47. BIN
      images/icon-login-index2.png
  48. 42 0
      pages/balance/balance-detail.js
  49. 3 0
      pages/balance/balance-detail.json
  50. 30 0
      pages/balance/balance-detail.wxml
  51. 213 0
      pages/balance/balance-detail.wxss
  52. 0 0
      pages/balance/balance.wxml
  53. 2 1
      pages/balance/balance.wxss
  54. 38 1
      pages/balance/detail.js
  55. 0 0
      pages/book/submit/submit.js
  56. 167 0
      pages/check-submit/check-submit.js
  57. 3 0
      pages/check-submit/check-submit.json
  58. 16 0
      pages/check-submit/check-submit.wxml
  59. 38 0
      pages/check-submit/check-submit.wxss
  60. 244 0
      pages/check/check.js
  61. 7 0
      pages/check/check.json
  62. 54 0
      pages/check/check.wxml
  63. 78 0
      pages/check/check.wxss
  64. 244 0
      pages/check/checksg.js
  65. 7 0
      pages/check/checksg.json
  66. 53 0
      pages/check/checksg.wxml
  67. 78 0
      pages/check/checksg.wxss
  68. 82 1
      pages/clerk/clerk.js
  69. 0 0
      pages/clerk/clerk.wxml
  70. 9 2
      pages/coupon-list/coupon-list.js
  71. 1 0
      pages/coupon-subsidy/coupon-subsidy.js
  72. 3 0
      pages/coupon-subsidy/coupon-subsidy.json
  73. 73 0
      pages/coupon-subsidy/coupon-subsidy.wxml
  74. 14 0
      pages/coupon-subsidy/coupon-subsidy.wxss
  75. 0 0
      pages/coupon/coupon.wxml
  76. 1 1
      pages/goods/goods.js
  77. 2 2
      pages/goods/goods.wxml
  78. 5 1
      pages/index/index.json
  79. 1 1
      pages/index/index.wxml
  80. 0 0
      pages/integral-mall/order/order.js
  81. 62 1
      pages/login/login.js
  82. 11 9
      pages/new-order-submit/new-order-submit.js
  83. 3 3
      pages/new-order-submit/new-order-submit.wxml
  84. 88 0
      pages/order-detail-clerk/order-detail-clerk.js
  85. 3 0
      pages/order-detail-clerk/order-detail-clerk.json
  86. 85 0
      pages/order-detail-clerk/order-detail-clerk.wxml
  87. 10 0
      pages/order-detail-clerk/order-detail-clerk.wxss
  88. 44 1
      pages/order-detail/order-detail.js
  89. 52 4
      pages/order-detail/order-detail.wxml
  90. 13 1
      pages/order-detail/order-detail.wxss
  91. 0 0
      pages/order/order.js
  92. 9 1
      pages/order/order.wxml
  93. 0 0
      pages/share/index.js
  94. 174 0
      pages/store-order/store-order.js
  95. 3 0
      pages/store-order/store-order.json
  96. 85 0
      pages/store-order/store-order.wxml
  97. 10 0
      pages/store-order/store-order.wxss
  98. 8 0
      pages/test/cxj.js
  99. 4 0
      pages/test/cxj.json
  100. 29 0
      pages/test/cxj.wxml

+ 7 - 1
app.json

xqd xqd xqd
@@ -96,6 +96,7 @@
     "pages/order-submit/order-submit",
     "pages/order/order",
     "pages/order-detail/order-detail",
+    "pages/order-detail-clerk/order-detail-clerk",
     "pages/address/address",
     "pages/address-edit/address-edit",
     "pages/address-picker/address-picker",
@@ -167,6 +168,7 @@
     "pages/fxhb/detail/detail",
     "pages/quick-purchase/index/index",
     "pages/balance/balance",
+    "pages/balance/balance-detail",
     "pages/recharge/recharge",
     "pages/bangding/bangding",
     "pages/web/login/login",
@@ -195,7 +197,11 @@
     "pages/kabaw/kabaw_center",
     "pages/kabaw/viplist",
     "pages/kabaw/buyvip",
-    "pages/kabaw/carddetail"
+    "pages/kabaw/carddetail",
+    "pages/check/check",
+    "pages/check/checksg",
+    "pages/check-submit/check-submit",
+    "pages/store-order/store-order"
   ],
   "navigateToMiniProgramAppIdList": [
     "wx1f57f137a8575932",

+ 1 - 1
bargain/goods/goods.js

xqd
@@ -31,7 +31,7 @@ Page({
       var o = app.query;
       app.query = null, e.goods_id = o.gid
     }
-    this.getGoods(e.goods_id)
+    this.getGoods(e.buyNow)
   },
   getGoods: function(e) {
     var a = this;

+ 43 - 0
components/_toast/_toast1.wxml

xqd
@@ -0,0 +1,43 @@
+<view id="_toast" wx:if="{{_toast}}">
+    <view class="{{_toast.hide?'hide':''}}" id="_toast_title">
+        <text>{{_toast.title}}</text>
+    </view>
+</view>
+<view class=" flex-row flex-x-center flex-y-center" id="_loading" wx:if="{{_loading}}">
+    <view class="{{_loading?'hide':''}}">
+        <image src="{{__wxapp_img.system.loading2.url}}"></image>
+    </view>
+</view>
+<view class="new-modal" wx:if="{{user_info_show}}">
+    <view class="new-modal-content" style="width: 650rpx">
+        <view class="new-modal-body" style="min-height:0;margin-bottom:0;max-height:none;padding: 0;position:relative;">
+            <image src="/images/icon-login-index.png" style="width:650rpx;height:700rpx;"></image>
+            <view style="position: absolute;width: 224rpx;height: 80rpx;top: 566rpx;left: 340rpx;">
+                <button bindgetuserinfo="getUserInfo" bindtap="myLogin" class="btn new-modal-btn" openType="getUserInfo" style="width:100%;height:100%;" wx:if="{{__platform=='wx'}}"></button>
+                <button class="btn new-modal-btn" onGetAuthorize="myLogin" openType="getAuthorize" scope="userInfo" style="width:100%;height:100%;" wx:if="{{__platform=='my'}}"></button>
+            </view>
+            <view bindtap="cancelLogin" style="position: absolute;width: 224rpx;height: 80rpx;top: 566rpx;left: 84rpx;"></view>
+        </view>
+    </view>
+</view>
+<block wx:if="{{user_bind_show}}">
+    <view class="new-modal" wx:if="{{!__user_info.binding&&store.option.phone_auth==1}}">
+        <view class="new-modal-content">
+            <view class="new-modal-header" style="padding:30rpx 0;line-height:60rpx;font-size:11pt;border-bottom: 1rpx solid #eee;">授权获取手机号</view>
+            <view class="new-modal-body" style="min-height:0;margin-bottom:0;">
+                <view style="padding:32rpx 0 40rpx 0;text-align: center">
+                    <image src="{{__wxapp_img.system.wechatapp.url}}" style="width: 88rpx;height: 88rpx;" wx:if="{{__platform=='wx'}}"></image>
+                    <image src="{{__wxapp_img.system.alipay.url}}" style="width: 88rpx;height: 88rpx;" wx:else></image>
+                </view>
+                <view style="padding:0 41rpx;">
+                    <view class="flex-x-center" style="margin-bottom:40rpx;">申请获取您微信绑定的手机号</view>
+                </view>
+                <view class="flex-x-center">
+                    <view>
+                        <button bindgetphonenumber="getPhoneNumber" class="btn new-modal-btn" hoverClass="none" openType="getPhoneNumber" style="background-color:#04be01;width:500rpx;height:80rpx;border-radius:80rpx;color:#fff;margin-bottom:40rpx;">确认</button>
+                    </view>
+                </view>
+            </view>
+        </view>
+    </view>
+</block>

+ 48 - 0
components/_toast/_toast1.wxss

xqd
@@ -0,0 +1,48 @@
+#_toast {
+  position: fixed;
+  top: 20%;
+  left: 0;
+  width: 100%;
+  height: 0;
+  background: #ff0;
+  z-index: 10000;
+  padding: 0 120rpx;
+  text-align: center;
+}
+
+#_toast_title {
+  font-size: 11pt;
+  display: inline-block;
+  background: rgba(0,0,0,0.85);
+  color: #fff;
+  margin: 0 auto;
+  padding: 16rpx 32rpx;
+  border-radius: 16rpx;
+  max-height: 60vh;
+  overflow-y: auto;
+  overflow-x: hidden;
+  text-align: left;
+  transition: 150ms;
+  word-break: break-all;
+  box-shadow: 0 0 25rpx 5rpx rgba(0,0,0,0.5);
+}
+
+#_toast_title.hide {
+  opacity: 0;
+  visibility: hidden;
+}
+
+#_loading {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background: #fff;
+  z-index: 10000;
+}
+
+#_loading image {
+  width: 200rpx;
+  height: 200rpx;
+}

+ 0 - 1
components/calendar/calendar-converter.js

xqd
@@ -1 +0,0 @@
-var calendarSignData,date,calendarSignDay,app=getApp();Page({data:{},onLoad:function(a){var e=new Date,n=e.getFullYear(),t=e.getMonth()+1;date=e.getDate();var r,c=e.getDay(),g=7-(date-c)%7;1==t||3==t||5==t||7==t||8==t||10==t||12==t?r=31:4==t||6==t||9==t||11==t?r=30:2==t&&(r=(n-2e3)%4==0?29:28),null!=getApp().core.getStorageSync("calendarSignData")&&""!=getApp().core.getStorageSync("calendarSignData")||getApp().core.setStorageSync("calendarSignData",new Array(r)),null!=getApp().core.getStorageSync("calendarSignDay")&&""!=getApp().core.getStorageSync("calendarSignDay")||getApp().core.setStorageSync("calendarSignDay",0),calendarSignData=getApp().core.getStorageSync("calendarSignData"),calendarSignDay=getApp().core.getStorageSync("calendarSignDay"),this.setData({year:n,month:t,nbsp:g,monthDaySize:r,date:date,calendarSignData:calendarSignData,calendarSignDay:calendarSignDay})},onReady:function(){},onShow:function(){},onHide:function(){},onUnload:function(){},onPullDownRefresh:function(){},onReachBottom:function(){},onShareAppMessage:function(){},register_rule:function(){this.setData({register_rule:!0})},hideModal:function(){this.setData({register_rule:!1})},calendarSign:function(){calendarSignData[date]=date,calendarSignDay+=1,getApp().core.setStorageSync("calendarSignData",calendarSignData),getApp().core.setStorageSync("calendarSignDay",calendarSignDay),getApp().core.showToast({title:"签到成功",icon:"success",duration:2e3}),this.setData({calendarSignData:calendarSignData,calendarSignDay:calendarSignDay})}});

+ 0 - 1
components/calendar/calendar.wxml

xqd
@@ -1 +0,0 @@
-<view class='top-handle'><view bindtap='doDay' class='prev' data-key='left'><image src='{{__wxapp_img.register.left.url}}'></image></view><view class='today'>{{currentDate}}</view><view bindtap='doDay' class='next' data-key='right'><image src='{{__wxapp_img.register.right.url}}'></image></view></view><view class='week'><block wx:for='{{weeks}}' wx:for-item='item' wx:for-index='index' wx:key='{{item.id}}'><view class='weeks-day'>{{item.day}}</view></block></view><view class='box-flex'><block wx:for='{{currentDayList}}' wx:for-item='vo' wx:for-index='key' wx:key='{{key}}'><view class='flex-item'><block wx:if='{{vo.is_re == 1}}'><block wx:if='{{currentDay != vo.date}}'><view bindtap='selectDay' class='item-content {{!(selectCSS)}}' data-day='{{vo.date}}'><image class='re_pic' src='{{__wxapp_img.register.quan.url}}'></image>                {{vo.date}}            </view></block></block><block wx:else><block wx:if='{{currentDay != vo.date}}'><view bindtap='selectDay' class='item-content {{!(selectCSS)}}' data-day='{{vo.date}}'>                {{vo.date}}            </view></block></block><block wx:if='{{vo.is_re == 1}}'><block wx:if='{{currentDay == vo.date}}'><view bindtap='selectDay' class='item-content {{selectCSS}}' data-day='{{vo.date}}'><image class='re_pic' src='{{__wxapp_img.register.quan.url}}'></image>                {{vo.date}}            </view></block></block><block wx:else><block wx:if='{{currentDay == vo.date}}'><view bindtap='selectDay' class='item-content {{selectCSS}}' data-day='{{vo.date}}'>                {{vo.date}}            </view></block></block></view></block></view>

+ 0 - 1
components/calendar/calendar.wxss

xqd
@@ -1 +0,0 @@
-@import '/import/css0_2.wxss';

+ 144 - 0
components/calendar/core.js

xqd
@@ -0,0 +1,144 @@
+import { dateUtil, getCalendarConfig } from './utils/index'
+
+/**
+ * 计算当前月份前后两月应占的格子
+ * @param {number} year 年份
+ * @param {number} month 月份
+ */
+function calculateEmptyGrids(year, month, config) {
+  const prevMonthGrids = calculatePrevMonthGrids(year, month, config)
+  const nextMonthGrids = calculateNextMonthGrids(year, month, config)
+  return {
+    prevMonthGrids,
+    nextMonthGrids
+  }
+}
+
+/**
+ * 计算上月应占的格子
+ * @param {number} year 年份
+ * @param {number} month 月份
+ */
+function calculatePrevMonthGrids(year, month, config) {
+  let emptyGrids = []
+  const prevMonthDays = dateUtil.getDatesCountOfMonth(year, month - 1)
+  let firstDayOfWeek = dateUtil.firstDayOfWeek(year, month)
+  if (config.firstDayOfWeek === 'Mon') {
+    if (firstDayOfWeek === 0) {
+      firstDayOfWeek = 6
+    } else {
+      firstDayOfWeek -= 1
+    }
+  }
+  if (firstDayOfWeek > 0) {
+    const len = prevMonthDays - firstDayOfWeek
+    const { onlyShowCurrentMonth } = config
+    const YMInfo = dateUtil.getPrevMonthInfo({ year, month })
+    for (let i = prevMonthDays; i > len; i--) {
+      if (onlyShowCurrentMonth) {
+        emptyGrids.push('')
+      } else {
+        const week = dateUtil.getDayOfWeek(+year, +month, i)
+        emptyGrids.push({
+          ...YMInfo,
+          date: i,
+          week
+        })
+      }
+    }
+    emptyGrids.reverse()
+  }
+  return emptyGrids
+}
+/**
+ * 计算下一月日期是否需要多展示的日期
+ * 某些月份日期为5排,某些月份6排,统一为6排
+ * @param {number} year
+ * @param {number} month
+ * @param {object} config
+ */
+function calculateExtraEmptyDate(year, month, config) {
+  let extDate = 0
+  if (+month === 2) {
+    extDate += 7
+    let firstDayofMonth = dateUtil.getDayOfWeek(year, month, 1)
+    if (config.firstDayOfWeek === 'Mon') {
+      if (+firstDayofMonth === 1) extDate += 7
+    } else {
+      if (+firstDayofMonth === 0) extDate += 7
+    }
+  } else {
+    let firstDayofMonth = dateUtil.getDayOfWeek(year, month, 1)
+    if (config.firstDayOfWeek === 'Mon') {
+      if (firstDayofMonth !== 0 && firstDayofMonth < 6) {
+        extDate += 7
+      }
+    } else {
+      if (firstDayofMonth <= 5) {
+        extDate += 7
+      }
+    }
+  }
+  return extDate
+}
+/**
+ * 计算下月应占的格子
+ * @param {number} year 年份
+ * @param {number} month  月份
+ */
+function calculateNextMonthGrids(year, month, config) {
+  let emptyGrids = []
+  const datesCount = dateUtil.getDatesCountOfMonth(year, month)
+  let lastDayWeek = dateUtil.getDayOfWeek(year, month, datesCount)
+  if (config.firstDayOfWeek === 'Mon') {
+    if (lastDayWeek === 0) {
+      lastDayWeek = 6
+    } else {
+      lastDayWeek -= 1
+    }
+  }
+  let len = 7 - (lastDayWeek + 1)
+  const { onlyShowCurrentMonth } = config
+  if (!onlyShowCurrentMonth) {
+    len = len + calculateExtraEmptyDate(year, month, config)
+  }
+  const YMInfo = dateUtil.getNextMonthInfo({ year, month })
+  for (let i = 1; i <= len; i++) {
+    const week = dateUtil.getDayOfWeek(+year, +month, i)
+    if (onlyShowCurrentMonth) {
+      emptyGrids.push('')
+    } else {
+      emptyGrids.push({
+        id: i - 1,
+        ...YMInfo,
+        date: i,
+        week: week || 7
+      })
+    }
+  }
+  return emptyGrids
+}
+/**
+ * 设置日历面板数据
+ * @param {number} year 年份
+ * @param {number} month  月份
+ * @param {number} curDate  日期
+ */
+function calculateCurrentMonthDates(year, month) {
+  return dateUtil.calcDates(year, month)
+}
+
+export function calcJumpData({ dateInfo, config, component }) {
+  dateInfo = dateInfo || dateUtil.todayFMD()
+  const { year, month, date } = dateInfo
+  const calendarConfig = config || getCalendarConfig(component)
+  const emptyGrids = calculateEmptyGrids(year, month, calendarConfig)
+  const calendar = {
+    curYear: year,
+    curMonth: month,
+    curDate: date,
+    dates: calculateCurrentMonthDates(year, month),
+    ...emptyGrids
+  }
+  return calendar
+}

+ 12 - 0
components/calendar/helper.js

xqd
@@ -0,0 +1,12 @@
+import { dateUtil } from './utils/index'
+
+export function calcTargetYMInfo() {
+  return {
+    right: dateUtil.getPrevMonthInfo,
+    left: dateUtil.getNextMonthInfo,
+    prev_month: dateUtil.getPrevMonthInfo,
+    next_month: dateUtil.getNextMonthInfo,
+    prev_year: dateUtil.getPrevYearInfo,
+    next_year: dateUtil.getNextYearInfo
+  }
+}

+ 225 - 0
components/calendar/index.js

xqd
@@ -0,0 +1,225 @@
+import plugins from './plugins/index'
+import { calcJumpData } from './core'
+import { renderCalendar } from './render'
+import { calcTargetYMInfo } from './helper'
+import { dateUtil, calendarGesture, logger } from './utils/index'
+
+Component({
+  options: {
+    styleIsolation: 'apply-shared',
+    multipleSlots: true // 在组件定义时的选项中启用多slot支持
+  },
+  properties: {
+    config: {
+      type: Object,
+      value: {}
+    }
+  },
+  lifetimes: {
+    attached: function() {
+      this.initComp()
+    }
+  },
+  methods: {
+    initComp() {
+      const calendarConfig = this.setDefaultDisableDate()
+      this.setConfig(calendarConfig)
+    },
+    // 禁用某天日期配置默认为今天
+    setDefaultDisableDate() {
+      const calendarConfig = this.properties.config || {}
+      if (calendarConfig.disableMode && !calendarConfig.disableMode.date) {
+        calendarConfig.disableMode.date = dateUtil.toTimeStr(
+          dateUtil.todayFMD()
+        )
+      }
+      return calendarConfig
+    },
+    initCalendar(config) {
+      const { defaultDate } = config
+      let date = dateUtil.todayFMD()
+      if (defaultDate && typeof defaultDate === 'string') {
+        const dateInfo = defaultDate.split('-')
+        if (dateInfo.length < 3) {
+          return logger.warn('defaultDate配置格式应为: 2018-4-2 或 2018-04-02')
+        } else {
+          date = {
+            year: +dateInfo[0],
+            month: +dateInfo[1],
+            date: +dateInfo[2]
+          }
+        }
+      }
+      const waitRenderData = calcJumpData({
+        dateInfo: date,
+        config
+      })
+      const timestamp = dateUtil.todayTimestamp()
+      if (config.autoChoosedWhenJump) {
+        const target = waitRenderData.dates.filter(
+          item => dateUtil.toTimeStr(item) === dateUtil.toTimeStr(date)
+        )
+        if (target && target.length) {
+          if (!waitRenderData.selectedDates) {
+            waitRenderData.selectedDates = target
+          } else {
+            waitRenderData.selectedDates.push(target[0])
+          }
+        }
+      }
+      return {
+        ...waitRenderData,
+        todayTimestamp: timestamp,
+        weeksCh: dateUtil.getWeekHeader(config.firstDayOfWeek)
+      }
+    },
+    setConfig(config) {
+      if (config.markToday && typeof config.markToday === 'string') {
+        config.highlightToday = true
+      }
+      config.theme = config.theme || 'default'
+      this.setData(
+        {
+          config
+        },
+        () => {
+          for (let plugin of plugins.installed) {
+            const [, p] = plugin
+            if (typeof p.install === 'function') {
+              p.install(this)
+            }
+            if (typeof p.methods === 'function') {
+              const methods = p.methods(this)
+              for (let fnName in methods) {
+                if (fnName.startsWith('__')) continue
+                const fn = methods[fnName]
+                if (typeof fn === 'function') {
+                  if (!this.calendar) this.calendar = {}
+                  this.calendar[fnName] = fn
+                }
+              }
+            }
+          }
+          const initData = this.initCalendar(config)
+          renderCalendar.call(this, initData, config)
+        }
+      )
+    },
+    tapDate(e) {
+      const { info } = e.currentTarget.dataset
+      const { date, disable } = info || {}
+      if (disable || !date) return
+      const { calendar, config } = this.data
+      let calendarData = calendar
+      let calendarConfig = config
+      if (config.takeoverTap) {
+        return this.triggerEvent('takeoverTap', info)
+      }
+      for (let plugin of plugins.installed) {
+        const [, p] = plugin
+        if (typeof p.onTapDate === 'function') {
+          const {
+            calendarData: __calendarData,
+            calendarConfig: __calendarConfig
+          } = p.onTapDate(info, calendarData, calendarConfig)
+          calendarData = __calendarData
+          calendarConfig = __calendarConfig
+        }
+      }
+      renderCalendar.call(this, calendarData, calendarConfig).then(() => {
+        this.triggerEvent('afterTapDate', info)
+      })
+    },
+    /**
+     * 日历滑动开始
+     * @param {object} e
+     */
+    calendarTouchstart(e) {
+      const t = e.touches[0]
+      const startX = t.clientX
+      const startY = t.clientY
+      this.swipeLock = true
+      this.setData({
+        'gesture.startX': startX,
+        'gesture.startY': startY
+      })
+    },
+    /**
+     * 日历滑动中
+     * @param {object} e
+     */
+    calendarTouchmove(e) {
+      const { gesture } = this.data
+      const { preventSwipe } = this.properties.config
+      if (!this.swipeLock || preventSwipe) return
+      if (calendarGesture.isLeft(gesture, e.touches[0])) {
+        this.handleSwipe('left')
+        this.swipeLock = false
+      }
+      if (calendarGesture.isRight(gesture, e.touches[0])) {
+        this.handleSwipe('right')
+        this.swipeLock = false
+      }
+    },
+    calendarTouchend(e) {
+      this.setData({
+        'calendar.leftSwipe': 0,
+        'calendar.rightSwipe': 0
+      })
+    },
+    handleSwipe(direction) {
+      let swipeKey = 'calendar.leftSwipe'
+      if (direction === 'right') {
+        swipeKey = 'calendar.rightSwipe'
+      }
+      this.setData({
+        [swipeKey]: 1
+      })
+      const { calendar } = this.data
+      let calendarData = calendar
+      const { curYear, curMonth } = calendarData
+      const getMonthInfo = calcTargetYMInfo()[direction]
+      const target = getMonthInfo({
+        year: +curYear,
+        month: +curMonth
+      })
+      target.direction = direction
+      this.renderCalendar(target)
+    },
+    changeDate(e) {
+      const { type } = e.currentTarget.dataset
+      const { calendar: calendarData } = this.data
+      const { curYear, curMonth } = calendarData
+      const getMonthInfo = calcTargetYMInfo()[type]
+      const target = getMonthInfo({
+        year: +curYear,
+        month: +curMonth
+      })
+      target.direction = type
+      this.renderCalendar(target)
+    },
+    renderCalendar(target) {
+      let { calendar: calendarData, config } = this.data
+      const { curYear, curMonth } = calendarData || {}
+      for (let plugin of plugins.installed) {
+        const [, p] = plugin
+        if (typeof p.onSwitchCalendar === 'function') {
+          calendarData = p.onSwitchCalendar(target, calendarData, this)
+        }
+      }
+      return renderCalendar.call(this, calendarData, config).then(() => {
+        let triggerEventName = 'whenChangeMonth'
+        if (config.weekMode) {
+          triggerEventName = 'whenChangeWeek'
+        }
+        this.triggerEvent(triggerEventName, {
+          current: {
+            year: +curYear,
+            month: +curMonth
+          },
+          next: target
+        })
+      })
+    }
+  }
+})

+ 3 - 0
components/calendar/index.json

xqd
@@ -0,0 +1,3 @@
+{
+  "component": true
+}

+ 58 - 0
components/calendar/index.wxml

xqd
@@ -0,0 +1,58 @@
+<view class="flex b tb ac" wx:if="{{calendar}}">
+  <view class="calendar b tb">
+    <!-- 头部操作栏 -->
+    <view class="handle {{config.theme}}_handle-color fs28 b lr ac pc">
+      <view class="prev fs36" wx:if="{{!config.weekMode}}">
+        <text class="prev-handle iconfont icon-doubleleft" bindtap="changeDate" data-type="prev_year"></text>
+        <text class="prev-handle iconfont icon-left" bindtap="changeDate" data-type="prev_month"></text>
+      </view>
+      <view class="flex date-in-handle b lr cc" bindtap="doubleClickToToday">{{calendar.curYear || "--"}} 年 {{calendar.curMonth || "--"}} 月</view>
+      <view class="next fs36" wx:if="{{!config.weekMode}}">
+        <text class="next-handle iconfont icon-right" bindtap="changeDate" data-type="next_month"></text>
+        <text class="next-handle iconfont icon-doubleright" bindtap="changeDate" data-type="next_year"></text>
+      </view>
+    </view>
+    <!-- 星期栏 -->
+    <view class="weeks b lr ac {{config.theme}}_week-color">
+      <view class="week fs28" wx:for="{{calendar.weeksCh}}" wx:key="index" data-idx="{{index}}">{{item}}</view>
+    </view>
+    <!-- 日历面板主体 -->
+    <view class="b lr wrap" bindtouchstart="calendarTouchstart" catchtouchmove="calendarTouchmove" catchtouchend="calendarTouchend">
+      <!-- 上月日期格子 -->
+      <view class="grid b ac pc {{config.theme}}_prev-month-date" wx:for="{{calendar.prevMonthGrids}}" wx:key="index" data-idx="{{index}}">
+        <view class="date-wrap b cc">
+          <view class="date">
+                {{item.date}}
+          </view>
+        </view>
+      </view>
+      <!-- 本月日期格子 -->
+      <view wx:for="{{calendar.dates}}" wx:key="index" data-idx="{{index}}" data-info="{{item}}" bindtap="tapDate" class="grid {{item.class ? item.class  : ''}} {{config.theme}}_normal-date b ac pc">
+        <view class="date-wrap b cc {{config.emphasisWeek && (item.week === 0 || item.week === 6) ? config.theme + '_weekend-color' : ''}}">
+          <view class="date b ac pc {{item.class ? item.class  : ''}} {{item.isToday && config.highlightToday ? config.theme + '_today' : ''}} {{item.choosed ? config.theme + '_choosed' : ''}} {{item.disable ? config.theme + '_date-disable' : ''}} {{config.chooseAreaMode ? 'date-area-mode' : ''}}  {{calendar.todoLabelCircle && item.showTodoLabel && !item.choosed ? config.theme + '_todo-circle todo-circle' : '' }}">
+                {{config.markToday && item.isToday ? config.markToday : item.date}}
+                <view
+                  wx:if="{{(config.showLunar && item.lunar && !item.showTodoLabel) || (item.showTodoLabel && calendar.todoLabelPos !== 'bottom') || config.showHolidays}}"
+                  class="date-desc {{config.theme}}_date-desc date-desc-bottom {{(item.choosed || item.isToday) ? 'date-desc-bottom-always' : ''}} {{item.disable ? config.theme + '_date-desc-disable' : ''}}">
+                  <text class="{{config.showHolidays && !item.showTodoLabel && item.label && !item.choosed ? config.theme + '_date-desc-lunar' : ''}} {{item.type === 'festival' ? config.theme + '_festival' : ''}}">{{item.label || item.lunar.Term || item.lunar.IDayCn}}</text>
+                </view>
+                <view
+                  wx:if="{{item.showTodoLabel && !calendar.todoLabelCircle}}"
+                  class="{{item.todoText ? 'date-desc' : config.theme + '_todo-dot todo-dot'}} {{config.showLunar ? config.theme + '_date-desc-lunar' : ''}} {{calendar.todoLabelPos === 'bottom' ? 'date-desc-bottom todo-dot-bottom' : 'date-desc-top todo-dot-top'}} {{calendar.showLabelAlways && item.choosed && calendar.todoLabelPos === 'bottom' ? 'date-desc-bottom-always todo-dot-bottom-always' : ''}} {{calendar.showLabelAlways && item.choosed && calendar.todoLabelPos === 'top' ? 'date-desc-top-always todo-dot-top-always' : ''}}"
+                  style="background-color: {{item.todoText ? '' : item.color || calendar.todoLabelColor}}; color: {{item.color}}">
+                    {{item.todoText}}
+                </view>
+          </view>
+        </view>
+      </view>
+      <!-- 下月日期格子 -->
+      <view class="grid b ac pc {{config.theme}}_next-month-date" wx:for="{{calendar.nextMonthGrids}}" wx:key="index" data-idx="{{index}}">
+        <view class="date-wrap b cc">
+          <view class="date">
+              {{item.date}}
+          </view>
+        </view>
+      </view>
+    </view>
+  </view>
+</view>

+ 214 - 0
components/calendar/index.wxss

xqd
@@ -0,0 +1,214 @@
+@import './theme/iconfont.wxss';
+@import './theme/theme-default.wxss';
+@import './theme/theme-elegant.wxss';
+
+.b {
+    display: flex;
+}
+
+.lr {
+    flex-direction: row;
+}
+
+.tb {
+    flex-direction: column;
+}
+
+.pc {
+    justify-content: center;
+}
+
+.ac {
+    align-items: center;
+}
+
+.cc {
+    align-items: center;
+    justify-content: center;
+}
+
+.wrap {
+    flex-wrap: wrap;
+}
+
+.flex {
+    flex-grow: 1;
+}
+
+.bg {
+    background-image: linear-gradient(to bottom, #faefe7, #ffcbd7);
+    overflow: hidden;
+}
+
+.white-color {
+    color: #fff;
+}
+
+.fs24 {
+    font-size: 24rpx;
+}
+
+.fs28 {
+    font-size: 28rpx;
+}
+
+.fs32 {
+    font-size: 32rpx;
+}
+
+.fs36 {
+    font-size: 36rpx;
+}
+
+.calendar {
+    width: 100%;
+    box-sizing: border-box;
+}
+
+/* 日历操作栏 */
+
+.handle {
+    height: 80rpx;
+}
+
+.prev-handle,
+.next-handle {
+    padding: 20rpx;
+}
+
+.date-in-handle {
+    height: 80rpx;
+}
+
+/* 星期栏 */
+
+.weeks {
+    height: 50rpx;
+    line-height: 50rpx;
+    opacity: 0.5;
+}
+
+.week {
+    text-align: center;
+}
+
+.grid,
+.week {
+    width: 14.286014285714286%;
+}
+
+.date-wrap {
+    width: 100%;
+    height: 80rpx;
+    position: relative;
+    left: 0;
+    top: 0;
+}
+
+.date {
+    position: relative;
+    left: 0;
+    top: 0;
+    width: 55rpx;
+    height: 55rpx;
+    text-align: center;
+    line-height: 55rpx;
+    font-size: 26rpx;
+    font-weight: 200;
+    border-radius: 50%;
+    transition: all 0.3s;
+    animation-name: choosed;
+    animation-duration: 0.5s;
+    animation-timing-function: linear;
+    animation-iteration-count: 1;
+}
+
+.date-area-mode {
+    width: 100%;
+    border-radius: 0;
+}
+
+.date-desc {
+    width: 150%;
+    height: 32rpx;
+    font-size: 20rpx;
+    line-height: 32rpx;
+    position: absolute;
+    left: 50%;
+    transform: translateX(-50%);
+    overflow: hidden;
+    word-break: break-all;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    -webkit-line-clamp: 1;
+    text-align: center;
+}
+
+@keyframes choosed {
+    from {
+        transform: scale(1);
+    }
+
+    50% {
+        transform: scale(0.9);
+    }
+
+    to {
+        transform: scale(1);
+    }
+}
+
+/* 日期圆圈标记 */
+.todo-circle {
+    border-width: 1rpx;
+    border-style: solid;
+    box-sizing: border-box;
+}
+
+/* 待办点标记相关样式 */
+.todo-dot {
+    width: 10rpx;
+    height: 10rpx;
+    border-radius: 50%;
+    position: absolute;
+    left: 50%;
+    transform: translateX(-50%);
+}
+
+.todo-dot-top {
+    top: 3rpx;
+}
+
+.todo-dot.todo-dot-top-always {
+    top: -8rpx;
+}
+
+.todo-dot.todo-dot-bottom {
+    bottom: 0;
+}
+
+.todo-dot.todo-dot-bottom-always {
+    bottom: -10rpx;
+}
+
+/* 日期描述文字(待办文字/农历)相关样式 */
+
+.date-desc.date-desc-top {
+    top: -6rpx;
+}
+
+.date-desc.date-desc-top-always {
+    top: -20rpx;
+}
+
+.date-desc.date-desc-bottom {
+    bottom: -14rpx;
+}
+
+.todo-circle .date-desc.date-desc-bottom {
+    bottom: -30rpx;
+}
+
+.date-desc.date-desc-bottom-always {
+    bottom: -28rpx;
+}

+ 224 - 0
components/calendar/plugins/holidays/holidays-map.js

xqd
@@ -0,0 +1,224 @@
+/* *
+  @Author: drfu*
+  @Description: 数据来源于国务院办公厅关于2020年部分节假日安排的通知(国办发明电〔2019〕16号)_政府信息公开专栏,http://www.gov.cn/zhengce/content/2019-11/21/content_5454164.htm
+  @Date: 2020-10-12 14:29:45*
+ * @Last Modified by: drfu
+ * @Last Modified time: 2020-10-16 17:38:08
+*/
+
+// 节日列表
+export const festival = {
+  // 农历固定日期节日
+  lunar: {
+    1: {
+      1: {
+        type: 'festival',
+        name: '春节',
+        label: '春节'
+      },
+      8: {
+        type: 'festival',
+        name: '腊八节',
+        label: '腊八'
+      },
+      15: {
+        type: 'festival',
+        name: '元宵节',
+        label: '元宵'
+      }
+    },
+    7: {
+      7: {
+        type: 'festival',
+        name: '七夕节',
+        label: '七夕'
+      },
+      15: {
+        type: 'festival',
+        name: '中元节',
+        label: '中元节'
+      }
+    },
+    9: {
+      9: {
+        type: 'festival',
+        name: '重阳节',
+        label: '重阳节'
+      }
+    },
+    12: {
+      30: {
+        type: 'festival',
+        name: '除夕',
+        label: '除夕'
+      }
+    }
+  },
+  // 阳历固定日期节日
+  solar: {
+    2: {
+      14: {
+        type: 'festival',
+        name: '情人节',
+        label: '情人节'
+      }
+    },
+    3: {
+      12: {
+        type: 'festival',
+        name: '植树节',
+        label: '植树节'
+      }
+    },
+    4: {
+      1: {
+        type: 'festival',
+        name: '愚人节',
+        label: '愚人节'
+      },
+      5: {
+        type: 'festival',
+        name: '清明节',
+        label: '清明节'
+      }
+    },
+    5: {
+      1: {
+        type: 'festival',
+        name: '劳动节',
+        label: '劳动节'
+      },
+      6: {
+        type: 'festival',
+        name: '立夏',
+        label: '立夏'
+      }
+    },
+    6: {
+      1: {
+        type: 'festival',
+        name: '儿童节',
+        label: '儿童节'
+      }
+    },
+    7: {
+      1: {
+        type: 'festival',
+        name: '建党节',
+        label: '建党节'
+      }
+    },
+    8: {
+      1: {
+        type: 'festival',
+        name: '建军节',
+        label: '建军节'
+      }
+    },
+    9: {
+      10: {
+        type: 'festival',
+        name: '教师节',
+        label: '教师节'
+      }
+    },
+    10: {
+      1: {
+        type: 'festival',
+        name: '国庆节',
+        label: '国庆节'
+      }
+    },
+    12: {
+      25: {
+        type: 'festival',
+        name: '圣诞节',
+        label: '圣诞节'
+      }
+    }
+  }
+}
+
+export const holidays = {
+  2020: {
+    1: {
+      1: {
+        type: 'holiday',
+        name: '元旦',
+        label: '休'
+      },
+      19: {
+        type: 'work',
+        name: '调班',
+        label: '班'
+      },
+      '24-30': {
+        type: 'holiday',
+        name: '春节',
+        label: '休'
+      }
+    },
+    2: {
+      1: {
+        type: 'work',
+        name: '调班',
+        label: '班'
+      }
+    },
+    4: {
+      '4-6': {
+        type: 'holiday',
+        name: '清明节',
+        label: '休'
+      },
+      26: {
+        type: 'work',
+        name: '调班',
+        label: '班'
+      }
+    },
+    5: {
+      '1-5': {
+        type: 'holiday',
+        name: '劳动节',
+        label: '休'
+      },
+      9: {
+        type: 'work',
+        name: '调班',
+        label: '班'
+      }
+    },
+    6: {
+      '25-27': {
+        type: 'holiday',
+        name: '端午节',
+        label: '休'
+      },
+      28: {
+        type: 'work',
+        name: '调班',
+        label: '班'
+      }
+    },
+    9: {
+      27: {
+        type: 'work',
+        name: '调班',
+        label: '班'
+      }
+    },
+    10: {
+      '1-8': {
+        type: 'holiday',
+        name: '国庆节/中秋节',
+        label: '休'
+      },
+      10: {
+        type: 'work',
+        name: '调班',
+        label: '班'
+      }
+    }
+  }
+}

+ 153 - 0
components/calendar/plugins/holidays/index.js

xqd
@@ -0,0 +1,153 @@
+/* *
+  @Author: drfu*
+  @Description: 显示法定节假日班/休情况
+  @Date: 2020-10-12 14:29:45*
+ * @Last Modified by: drfu
+ * @Last Modified time: 2020-10-16 17:34:13
+*/
+
+import { holidays, festival } from './holidays-map'
+import { dateUtil, getCalendarData, logger } from '../../utils/index'
+
+/**
+ * 当前是否在休假期内
+ * @param {object} { year, month }
+ * @param {object} { start, end, current }
+ * @returns
+ */
+function inHolidays({ year, month }, { start, end, current }) {
+  const getTimeStamp = dateUtil.getTimeStamp
+  const startTimestamp = getTimeStamp({
+    year,
+    month,
+    date: start
+  })
+  const endTimestamp = getTimeStamp({
+    year,
+    month,
+    date: end
+  })
+  const currentDateTimestamp = getTimeStamp({
+    year,
+    month,
+    date: current
+  })
+  if (
+    currentDateTimestamp >= startTimestamp &&
+    currentDateTimestamp <= endTimestamp
+  ) {
+    return true
+  }
+  return false
+}
+/**
+ * 是否匹配到节日
+ * @param {object} [dateInfo={}]
+ * @param {object} [component={}]
+ * @returns
+ */
+function hasFestivalDate(dateInfo = {}, component = {}) {
+  const { month, date } = dateInfo
+  let festivalDate = festival.solar[month] && festival.solar[month][date]
+  if (!festivalDate) {
+    const { convertSolarLunar } = component.calendar || {}
+    if (typeof convertSolarLunar === 'function') {
+      const { lMonth, lDay } = convertSolarLunar(dateInfo)
+      festivalDate = festival.lunar[lMonth] && festival.lunar[lMonth][lDay]
+    } else {
+      logger.warn(
+        '农历节日显示需要引入农历插件(/component/v2/plugins/solarLunar)'
+      )
+    }
+  }
+  return festivalDate
+}
+
+export default () => {
+  return {
+    name: 'holidays',
+    beforeRender(calendarData = {}, calendarConfig = {}, component) {
+      let { dates = [] } = calendarData
+      if (calendarConfig.showHolidays || calendarConfig.showFestival) {
+        dates = dates.map(d => {
+          let item = { ...d }
+          const { year, month, date } = item
+          const hasHolidaysOfThisMonth =
+            (holidays[year] && holidays[year][month]) || {}
+          const holidayDate = hasHolidaysOfThisMonth[date]
+          if (holidayDate) {
+            item = {
+              ...item,
+              ...holidayDate
+            }
+          } else {
+            const holidayKeys = Object.keys(
+              hasHolidaysOfThisMonth
+            ).filter(item => item.includes('-'))
+            let target = ''
+            for (let v of holidayKeys) {
+              const [start, end] = v.split('-')
+              if (+d.date >= +start && +d.date <= +end) {
+                target = v
+                break
+              }
+            }
+            const [start, end] = target.split('-')
+            const isInHolidays = inHolidays(
+              {
+                year,
+                month
+              },
+              {
+                start,
+                end,
+                current: date
+              }
+            )
+            if (isInHolidays) {
+              item = {
+                ...item,
+                ...hasHolidaysOfThisMonth[target]
+              }
+            } else if (calendarConfig.showFestival) {
+              const festivalDate = hasFestivalDate(item, component)
+              if (festivalDate) {
+                item = {
+                  ...item,
+                  ...festivalDate
+                }
+              }
+            }
+          }
+          return item
+        })
+      }
+      return {
+        calendarData: {
+          ...calendarData,
+          dates: dates
+        },
+        calendarConfig
+      }
+    },
+    methods(component) {
+      return {
+        getHolidaysOfCurrentYear() {
+          const calendar = getCalendarData('calendar', component)
+          const { curYear } = calendar
+          return this.methods(component).getHolidaysOfYear(curYear)
+        },
+        getHolidaysOfYear(year) {
+          if (!year) return logger.warn('getHolidaysOfCurrentYear() 入参错误')
+          if (!holidays[year]) {
+            logger.warn('未匹配到当前年份节假日信息,请自行补充')
+            return {
+              err: 'not match'
+            }
+          }
+          return holidays[year]
+        }
+      }
+    }
+  }
+}

+ 18 - 0
components/calendar/plugins/index.js

xqd
@@ -0,0 +1,18 @@
+import preset from './preset/index'
+
+export default {
+  installed: [...preset],
+  use(plugin) {
+    if (typeof plugin !== 'function') return
+    const info = plugin() || {}
+    const { name } = info
+    if (
+      name &&
+      name !== 'methods' &&
+      !this.installed.some(p => p[0] === name)
+    ) {
+      this.installed.unshift([name, info])
+    }
+    return this
+  }
+}

+ 274 - 0
components/calendar/plugins/preset/base.js

xqd
@@ -0,0 +1,274 @@
+/**
+ * @Author: drfu*
+ * @Description: 基础功能
+ * @Date: 2020-10-08 21:22:09*
+ * @Last Modified by: drfu
+ * @Last Modified time: 2020-10-11 13:28:52
+ * */
+
+import { calcJumpData } from '../../core'
+import { renderCalendar } from '../../render'
+import {
+  dateUtil,
+  getCalendarData,
+  setCalendarData,
+  getCalendarConfig
+} from '../../utils/index'
+
+export default () => {
+  return {
+    name: 'base',
+    beforeRender(calendarData = {}, calendarConfig) {
+      const calendar = calendarData
+      const { selectedDates = [], dates } = calendar
+      let _dates = [...dates]
+      if (selectedDates.length) {
+        const selectedDatesStr = selectedDates.map(date =>
+          dateUtil.toTimeStr(date)
+        )
+        _dates.forEach(date => {
+          const dateStr = dateUtil.toTimeStr(date)
+          if (selectedDatesStr.includes(dateStr)) {
+            date.choosed = true
+          }
+        })
+      }
+      return {
+        calendarData: {
+          ...calendarData,
+          dates: _dates
+        },
+        calendarConfig
+      }
+    },
+    onTapDate(tapedDate, calendarData = {}, calendarConfig = {}) {
+      const calendar = {
+        ...calendarData
+      }
+      const dateIndex = dateUtil.findDateIndexInArray(
+        tapedDate,
+        calendarData.dates
+      )
+      const { multi, inverse } = calendarConfig
+      let dates = [...calendar.dates]
+      const { selectedDates = [] } = calendar
+      if (!multi) {
+        let preSelectedDate = {}
+        if (selectedDates.length) {
+          preSelectedDate = [...selectedDates].pop() || {}
+        }
+        if (!inverse && +preSelectedDate.date === +tapedDate.date) {
+          return calendar
+        }
+        let _tapedDate = { ...tapedDate, choosed: !tapedDate.choosed }
+
+        dates[dateIndex] = _tapedDate
+        if (preSelectedDate.date) {
+          const idx = dateUtil.findDateIndexInArray(preSelectedDate, dates)
+          const date = dates[idx]
+          if (date) {
+            date.choosed = false
+          }
+        }
+        if (dates[dateIndex].choosed) {
+          calendar.selectedDates = [dates[dateIndex]]
+        } else {
+          calendar.selectedDates = []
+        }
+      } else {
+        dates[dateIndex] = {
+          ...dates[dateIndex],
+          choosed: !dates[dateIndex].choosed
+        }
+        if (!calendar.selectedDates) {
+          calendar.selectedDates = []
+        }
+        if (dates[dateIndex].choosed) {
+          calendar.selectedDates.push(dates[dateIndex])
+        } else {
+          calendar.selectedDates = calendar.selectedDates.filter(
+            date =>
+              dateUtil.toTimeStr(date) !== dateUtil.toTimeStr(dates[dateIndex])
+          )
+        }
+      }
+      return {
+        calendarData: {
+          ...calendar,
+          dates
+        },
+        calendarConfig
+      }
+    },
+    onSwitchCalendar(date, calendarData = {}, component) {
+      const calendarConfig = getCalendarConfig(component)
+      if (calendarConfig.weekMode) {
+        return calendarData
+      }
+      const updatedRenderData = calcJumpData({
+        dateInfo: date,
+        config: calendarConfig
+      })
+      return {
+        ...calendarData,
+        ...updatedRenderData
+      }
+    },
+    methods(component) {
+      return {
+        jump: dateInfo => {
+          if (Object.prototype.toString.call(dateInfo) !== '[object Object]')
+            return
+          const updatedRenderData = calcJumpData({
+            dateInfo,
+            component
+          })
+          const existCalendarData = getCalendarData('calendar', component)
+          const config = getCalendarConfig(component)
+          if (config.autoChoosedWhenJump) {
+            const target = updatedRenderData.dates[dateInfo.date - 1]
+            if (!updatedRenderData.selectedDates) {
+              updatedRenderData.selectedDates = [target]
+            } else {
+              updatedRenderData.selectedDates.push(target)
+            }
+          }
+          return renderCalendar.call(component, {
+            ...existCalendarData,
+            ...updatedRenderData
+          })
+        },
+        getCalendarConfig() {
+          return getCalendarConfig(component)
+        },
+        setCalendarConfig(config) {
+          return new Promise((resolve, reject) => {
+            if (!component || !component.config) {
+              reject('异常:未找到组件配置信息')
+              return
+            }
+            let conf = { ...component.config, ...config }
+            component.config = conf
+            setCalendarData('calendar.config', conf)
+          })
+        },
+        cancelSelectedDates(cancelDates = []) {
+          const existCalendarData = getCalendarData('calendar', component) || {}
+          const { dates = [], selectedDates = [] } = existCalendarData
+          let updatedRenderData = {}
+          const config = getCalendarConfig(component)
+          let chooseAreaData = {}
+          if (config.chooseAreaMode) {
+            chooseAreaData = {
+              chooseAreaTimestamp: [],
+              tempChooseAreaTimestamp: []
+            }
+          }
+          if (!cancelDates.length) {
+            dates.forEach(item => {
+              item.choosed = false
+            })
+            updatedRenderData = {
+              dates,
+              selectedDates: []
+            }
+          } else {
+            const cancelDatesStr = cancelDates.map(date =>
+              dateUtil.toTimeStr(date)
+            )
+            const filterSelectedDates = selectedDates.filter(
+              date => !cancelDatesStr.includes(dateUtil.toTimeStr(date))
+            )
+            dates.forEach(date => {
+              if (cancelDatesStr.includes(dateUtil.toTimeStr(date))) {
+                date.choosed = false
+              }
+            })
+            updatedRenderData = {
+              dates,
+              selectedDates: filterSelectedDates
+            }
+          }
+
+          return renderCalendar.call(component, {
+            ...existCalendarData,
+            ...updatedRenderData,
+            ...chooseAreaData
+          })
+        },
+        setSelectedDates: targetDates => {
+          const existCalendarData = getCalendarData('calendar', component)
+          let { dates, selectedDates = [] } = existCalendarData || {}
+          let __selectedDates = []
+          let __dates = dates
+          if (!targetDates) {
+            __dates = dates.map(item => {
+              const date = { ...item }
+              date.choosed = true
+              if (existCalendarData.showLabelAlways && date.showTodoLabel) {
+                date.showTodoLabel = true
+              } else {
+                date.showTodoLabel = false
+              }
+              return date
+            })
+            __selectedDates = dates
+          } else if (targetDates && targetDates.length) {
+            const allSelected = dateUtil.uniqueArrayByDate(
+              selectedDates.concat(targetDates)
+            )
+            const allSelectedDateStr = allSelected.map(d =>
+              dateUtil.toTimeStr(d)
+            )
+            __dates = dates.map(item => {
+              const date = { ...item }
+              if (allSelectedDateStr.includes(dateUtil.toTimeStr(date))) {
+                date.choosed = true
+                __selectedDates.push(date)
+              }
+              if (existCalendarData.showLabelAlways && date.showTodoLabel) {
+                date.showTodoLabel = true
+              } else {
+                date.showTodoLabel = false
+              }
+              return date
+            })
+          }
+          return renderCalendar.call(component, {
+            ...existCalendarData,
+            dates: __dates,
+            selectedDates: __selectedDates
+          })
+        },
+        setDateStyle: toSetDates => {
+          if (!Array.isArray(toSetDates)) return Promise.reject()
+          const existCalendarData = getCalendarData('calendar', component)
+          const { dates = [], specialStyleDates } = existCalendarData || {}
+          if (Array.isArray(specialStyleDates)) {
+            toSetDates = dateUtil.uniqueArrayByDate([
+              ...specialStyleDates,
+              ...toSetDates
+            ])
+          }
+          const toSetDatesStr = toSetDates.map(item => dateUtil.toTimeStr(item))
+          const _dates = dates.map(item => {
+            const idx = toSetDatesStr.indexOf(dateUtil.toTimeStr(item))
+            if (idx > -1) {
+              return {
+                ...item,
+                class: toSetDates[idx].class
+              }
+            } else {
+              return item
+            }
+          })
+          return renderCalendar.call(component, {
+            ...existCalendarData,
+            dates: _dates,
+            specialStyleDates: toSetDates
+          })
+        }
+      }
+    }
+  }
+}

+ 69 - 0
components/calendar/plugins/preset/get-calendar-data.js

xqd
@@ -0,0 +1,69 @@
+/**
+ * @Author: drfu*
+ * @Description: 获取日历数据
+ * @Date: 2020-10-08 21:22:09*
+ * @Last Modified by: drfu
+ * @Last Modified time: 2020-10-11 13:42:37
+ * */
+
+import { getCalendarData, logger, getCalendarConfig } from '../../utils/index'
+
+function wrapDateWithLunar(dates = [], convertFn) {
+  const datesWithLunar = JSON.parse(JSON.stringify(dates)).map(date => ({
+    ...date,
+    lunar: convertFn(date)
+  }))
+  return datesWithLunar
+}
+
+export default () => {
+  return {
+    name: 'getData',
+    methods(component) {
+      return {
+        getCurrentYM: () => {
+          const { curYear, curMonth } = getCalendarData('calendar', component)
+          return {
+            year: curYear,
+            month: curMonth
+          }
+        },
+        getSelectedDates: (options = {}) => {
+          const dates =
+            getCalendarData('calendar.selectedDates', component) || []
+          const config = getCalendarConfig(component) || {}
+          if (options.lunar && !config.showLunar) {
+            const injectedFns = component.calendar || {}
+            if (typeof injectedFns.convertSolarLunar === 'function') {
+              return wrapDateWithLunar(dates, injectedFns.convertSolarLunar)
+            } else {
+              logger.warn('获取农历信息需引入农历插件')
+            }
+          } else {
+            return dates
+          }
+        },
+        getCalendarDates: (options = {}) => {
+          const config = getCalendarConfig(component) || {}
+          const dates = getCalendarData('calendar.dates', component)
+          if (options.lunar && !config.showLunar) {
+            const injectedFns = component.calendar || {}
+            if (typeof injectedFns.convertSolarLunar === 'function') {
+              return wrapDateWithLunar(dates, injectedFns.convertSolarLunar)
+            } else {
+              logger.warn('获取农历信息需引入农历插件')
+            }
+          } else {
+            return dates
+          }
+        },
+        getCalendarAllData: () => {
+          return {
+            data: getCalendarData('calendar', component) || {},
+            config: getCalendarConfig(component) || {}
+          }
+        }
+      }
+    }
+  }
+}

+ 9 - 0
components/calendar/plugins/preset/index.js

xqd
@@ -0,0 +1,9 @@
+import base from './base'
+import getCalendarData from './get-calendar-data'
+
+const preset = [
+  ['base', base()],
+  ['get-calendar-data', getCalendarData()]
+]
+
+export default preset

+ 222 - 0
components/calendar/plugins/selectable.js

xqd
@@ -0,0 +1,222 @@
+/**
+ * @Author: drfu*
+ * @Description: 禁用、启用日期选择
+ * @Date: 2020-10-08 21:22:09*
+ * @Last Modified by: drfu
+ * @Last Modified time: 2020-10-08 21:25:00
+ * */
+
+import { getCalendarData, dateUtil, logger } from '../utils/index'
+import { renderCalendar } from '../render'
+
+function convertEnableAreaToTimestamp(timearea = []) {
+  const start = timearea[0].split('-')
+  const end = timearea[1].split('-')
+  if (start.length !== 3 || end.length !== 3) {
+    logger.warn('enableArea() 参数格式为: ["2018-2-1", "2018-3-1"]')
+    return {}
+  }
+  const startTimestamp = dateUtil
+    .newDate(start[0], start[1], start[2])
+    .getTime()
+  const endTimestamp = dateUtil.newDate(end[0], end[1], end[2]).getTime()
+  return {
+    start,
+    end,
+    startTimestamp,
+    endTimestamp
+  }
+}
+
+function isValiditeOfDateArea(dateArea) {
+  const {
+    start,
+    end,
+    startTimestamp,
+    endTimestamp
+  } = convertEnableAreaToTimestamp(dateArea)
+  if (!start || !end) return
+  const datesCountOfStart = dateUtil.getDatesCountOfMonth(start[0], start[1])
+  const datesCountOfEnd = dateUtil.getDatesCountOfMonth(end[0], end[1])
+  if (start[2] > datesCountOfStart || start[2] < 1) {
+    logger.warn('enableArea() 开始日期错误,指定日期不在指定月份天数范围内')
+    return false
+  } else if (start[1] > 12 || start[1] < 1) {
+    logger.warn('enableArea() 开始日期错误,月份超出1-12月份')
+    return false
+  } else if (end[2] > datesCountOfEnd || end[2] < 1) {
+    logger.warn('enableArea() 截止日期错误,指定日期不在指定月份天数范围内')
+    return false
+  } else if (end[1] > 12 || end[1] < 1) {
+    logger.warn('enableArea() 截止日期错误,月份超出1-12月份')
+    return false
+  } else if (startTimestamp > endTimestamp) {
+    logger.warn('enableArea()参数最小日期大于了最大日期')
+    return false
+  } else {
+    return true
+  }
+}
+
+function handleDisableMode(calendarConfig) {
+  const { disableMode } = calendarConfig
+  if (!disableMode) return {}
+  const disableBound =
+    dateUtil.getTimeStamp(disableMode.date) || dateUtil.todayTimestamp()
+  return {
+    disableBound,
+    disableType: disableMode.type
+  }
+}
+
+function disabledByConfig(dateInfo, currentDate, calendarConfig) {
+  const date = { ...dateInfo }
+  const { disableType, disableBound } = handleDisableMode(calendarConfig)
+  if (
+    (disableType === 'before' && disableBound && currentDate < disableBound) ||
+    (disableType === 'after' && disableBound && currentDate > disableBound)
+  ) {
+    date.disable = true
+  } else {
+    date.disable = false
+  }
+  return date
+}
+
+export default () => {
+  return {
+    name: 'enable',
+    beforeRender(calendarData = {}, calendarConfig = {}) {
+      const {
+        dates,
+        enableArea,
+        enableDates,
+        disableDates,
+        renderCausedBy
+      } = calendarData
+      const _dates = [...dates].map(date => {
+        let item = { ...date }
+        const timeStr = dateUtil.toTimeStr(date)
+        const timestamp = +dateUtil.getTimeStamp(item)
+        if (renderCausedBy === 'enableDates') {
+          if (enableDates && enableDates.length) {
+            if (enableDates.includes(timeStr)) {
+              item.disable = false
+            } else {
+              item.disable = true
+            }
+            return item
+          }
+        } else if (renderCausedBy === 'enableArea') {
+          if (enableArea && enableArea.length) {
+            const [startTimestamp, endTimestamp] = enableArea || []
+            const ifOutofArea =
+              +startTimestamp > timestamp || timestamp > +endTimestamp
+            item.disable = ifOutofArea
+            return item
+          }
+        } else if (renderCausedBy === 'disableDates') {
+          if (disableDates && disableDates.length) {
+            if (disableDates && disableDates.includes(timeStr)) {
+              item.disable = true
+            } else {
+              item.disable = false
+            }
+            return item
+          }
+        }
+        return disabledByConfig(item, timestamp, calendarConfig)
+      })
+
+      return {
+        calendarData: {
+          ...calendarData,
+          dates: _dates
+        },
+        calendarConfig
+      }
+    },
+    methods(component) {
+      return {
+        enableArea: (dateArea = []) => {
+          if (dateArea.length === 2) {
+            const validate = isValiditeOfDateArea(dateArea)
+            if (validate) {
+              const existCalendarData = getCalendarData('calendar', component)
+              const {
+                startTimestamp,
+                endTimestamp
+              } = convertEnableAreaToTimestamp(dateArea)
+
+              return renderCalendar.call(component, {
+                ...existCalendarData,
+                renderCausedBy: 'enableArea',
+                enableArea: [startTimestamp, endTimestamp]
+              })
+            }
+          } else {
+            return Promise.inject(
+              'enableArea()参数需为时间范围数组,形如:["2018-8-4" , "2018-8-24"]'
+            )
+          }
+        },
+        enableDates: (toSet = []) => {
+          if (!toSet.length) return
+          const existCalendarData = getCalendarData('calendar', component)
+          const { enableDates = [] } = existCalendarData || {}
+          let toSetDates = toSet.map(item => {
+            let date = { ...item }
+            if (typeof date === 'string') {
+              return dateUtil.transformDateRow2Dict(item)
+            }
+            return item
+          })
+          if (enableDates.length) {
+            toSetDates = dateUtil.uniqueArrayByDate([
+              ...toSetDates,
+              ...enableDates.map(d => dateUtil.transformDateRow2Dict(d))
+            ])
+          }
+          return renderCalendar.call(component, {
+            ...existCalendarData,
+            renderCausedBy: 'enableDates',
+            enableDates: toSetDates.map(date => {
+              if (typeof date !== 'string') {
+                return dateUtil.toTimeStr(date)
+              }
+              return date
+            })
+          })
+        },
+        disableDates: toSet => {
+          const existCalendarData = getCalendarData('calendar', component)
+          const { disableDates = [], dates = [] } = existCalendarData || {}
+          let toSetDates = toSet.map(item => {
+            let date = { ...item }
+            if (typeof date === 'string') {
+              return dateUtil.transformDateRow2Dict(item)
+            }
+            return item
+          })
+          if (disableDates && disableDates.length) {
+            toSetDates = dateUtil.uniqueArrayByDate([
+              ...toSetDates,
+              ...disableDates.map(d => dateUtil.transformDateRow2Dict(d))
+            ])
+          }
+          return renderCalendar.call(component, {
+            ...existCalendarData,
+            renderCausedBy: 'disableDates',
+            dates,
+            disableDates: toSetDates.map(date => {
+              if (typeof date !== 'string') {
+                return dateUtil.toTimeStr(date)
+              }
+              return date
+            })
+          })
+        }
+      }
+    }
+  }
+}

+ 1036 - 0
components/calendar/plugins/solarLunar/convertSolarLunar.js

xqd
@@ -0,0 +1,1036 @@
+/**
+ * @1900-2100区间内的公历、农历互转
+ * @Version 1.0.3
+ * @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0]
+ * @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0]
+ */
+/* 公历年月日转农历数据 返回json */
+// calendar.solar2lunar(1987,11,01);
+/** 农历年月日转公历年月日 **/
+// calendar.lunar2solar(1987,9,10);
+// 调用以上方法后返回类似如下object(json)具体以上就不需要解释了吧!
+// c开头的是公历各属性值 l开头的自然就是农历咯 gz开头的就是天干地支纪年的数据啦~
+// {
+//  Animal: "兔",
+//  IDayCn: "初十",
+//  IMonthCn: "九月",
+//  Term: null,
+//  astro: "天蝎座",
+//  cDay: 1,
+//  cMonth: 11,
+//  cYear: 1987,
+//  gzDay: "甲寅",
+//  gzMonth: "庚戌",
+//  gzYear: "丁卯",
+//  isLeap: false,
+//  isTerm: false,
+//  isToday: false,
+//  lDay: 10,
+//  lMonth: 9,
+//  lYear: 1987,
+//  nWeek: 7,
+//  ncWeek: "星期日"
+// }
+// 该代码还有其他可以调用的方法,请自己查看代码中的详细注释
+const calendar = {
+  /**
+   * 农历1900-2100的润大小信息表
+   * @Array Of Property
+   * @return Hex
+   */
+  lunarInfo: [
+    0x04bd8,
+    0x04ae0,
+    0x0a570,
+    0x054d5,
+    0x0d260,
+    0x0d950,
+    0x16554,
+    0x056a0,
+    0x09ad0,
+    0x055d2, // 1900-1909
+    0x04ae0,
+    0x0a5b6,
+    0x0a4d0,
+    0x0d250,
+    0x1d255,
+    0x0b540,
+    0x0d6a0,
+    0x0ada2,
+    0x095b0,
+    0x14977, // 1910-1919
+    0x04970,
+    0x0a4b0,
+    0x0b4b5,
+    0x06a50,
+    0x06d40,
+    0x1ab54,
+    0x02b60,
+    0x09570,
+    0x052f2,
+    0x04970, // 1920-1929
+    0x06566,
+    0x0d4a0,
+    0x0ea50,
+    0x06e95,
+    0x05ad0,
+    0x02b60,
+    0x186e3,
+    0x092e0,
+    0x1c8d7,
+    0x0c950, // 1930-1939
+    0x0d4a0,
+    0x1d8a6,
+    0x0b550,
+    0x056a0,
+    0x1a5b4,
+    0x025d0,
+    0x092d0,
+    0x0d2b2,
+    0x0a950,
+    0x0b557, // 1940-1949
+    0x06ca0,
+    0x0b550,
+    0x15355,
+    0x04da0,
+    0x0a5b0,
+    0x14573,
+    0x052b0,
+    0x0a9a8,
+    0x0e950,
+    0x06aa0, // 1950-1959
+    0x0aea6,
+    0x0ab50,
+    0x04b60,
+    0x0aae4,
+    0x0a570,
+    0x05260,
+    0x0f263,
+    0x0d950,
+    0x05b57,
+    0x056a0, // 1960-1969
+    0x096d0,
+    0x04dd5,
+    0x04ad0,
+    0x0a4d0,
+    0x0d4d4,
+    0x0d250,
+    0x0d558,
+    0x0b540,
+    0x0b6a0,
+    0x195a6, // 1970-1979
+    0x095b0,
+    0x049b0,
+    0x0a974,
+    0x0a4b0,
+    0x0b27a,
+    0x06a50,
+    0x06d40,
+    0x0af46,
+    0x0ab60,
+    0x09570, // 1980-1989
+    0x04af5,
+    0x04970,
+    0x064b0,
+    0x074a3,
+    0x0ea50,
+    0x06b58,
+    0x055c0,
+    0x0ab60,
+    0x096d5,
+    0x092e0, // 1990-1999
+    0x0c960,
+    0x0d954,
+    0x0d4a0,
+    0x0da50,
+    0x07552,
+    0x056a0,
+    0x0abb7,
+    0x025d0,
+    0x092d0,
+    0x0cab5, // 2000-2009
+    0x0a950,
+    0x0b4a0,
+    0x0baa4,
+    0x0ad50,
+    0x055d9,
+    0x04ba0,
+    0x0a5b0,
+    0x15176,
+    0x052b0,
+    0x0a930, // 2010-2019
+    0x07954,
+    0x06aa0,
+    0x0ad50,
+    0x05b52,
+    0x04b60,
+    0x0a6e6,
+    0x0a4e0,
+    0x0d260,
+    0x0ea65,
+    0x0d530, // 2020-2029
+    0x05aa0,
+    0x076a3,
+    0x096d0,
+    0x04afb,
+    0x04ad0,
+    0x0a4d0,
+    0x1d0b6,
+    0x0d250,
+    0x0d520,
+    0x0dd45, // 2030-2039
+    0x0b5a0,
+    0x056d0,
+    0x055b2,
+    0x049b0,
+    0x0a577,
+    0x0a4b0,
+    0x0aa50,
+    0x1b255,
+    0x06d20,
+    0x0ada0, // 2040-2049
+    /** Add By JJonline@JJonline.Cn **/
+    0x14b63,
+    0x09370,
+    0x049f8,
+    0x04970,
+    0x064b0,
+    0x168a6,
+    0x0ea50,
+    0x06b20,
+    0x1a6c4,
+    0x0aae0, // 2050-2059
+    0x0a2e0,
+    0x0d2e3,
+    0x0c960,
+    0x0d557,
+    0x0d4a0,
+    0x0da50,
+    0x05d55,
+    0x056a0,
+    0x0a6d0,
+    0x055d4, // 2060-2069
+    0x052d0,
+    0x0a9b8,
+    0x0a950,
+    0x0b4a0,
+    0x0b6a6,
+    0x0ad50,
+    0x055a0,
+    0x0aba4,
+    0x0a5b0,
+    0x052b0, // 2070-2079
+    0x0b273,
+    0x06930,
+    0x07337,
+    0x06aa0,
+    0x0ad50,
+    0x14b55,
+    0x04b60,
+    0x0a570,
+    0x054e4,
+    0x0d160, // 2080-2089
+    0x0e968,
+    0x0d520,
+    0x0daa0,
+    0x16aa6,
+    0x056d0,
+    0x04ae0,
+    0x0a9d4,
+    0x0a2d0,
+    0x0d150,
+    0x0f252, // 2090-2099
+    0x0d520
+  ], // 2100
+
+  /**
+   * 公历每个月份的天数普通表
+   * @Array Of Property
+   * @return Number
+   */
+  solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
+
+  /**
+   * 天干地支之天干速查表
+   * @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"]
+   * @return Cn string
+   */
+  Gan: [
+    '\u7532',
+    '\u4e59',
+    '\u4e19',
+    '\u4e01',
+    '\u620a',
+    '\u5df1',
+    '\u5e9a',
+    '\u8f9b',
+    '\u58ec',
+    '\u7678'
+  ],
+
+  /**
+   * 天干地支之地支速查表
+   * @Array Of Property
+   * @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"]
+   * @return Cn string
+   */
+  Zhi: [
+    '\u5b50',
+    '\u4e11',
+    '\u5bc5',
+    '\u536f',
+    '\u8fb0',
+    '\u5df3',
+    '\u5348',
+    '\u672a',
+    '\u7533',
+    '\u9149',
+    '\u620c',
+    '\u4ea5'
+  ],
+
+  /**
+   * 天干地支之地支速查表<=>生肖
+   * @Array Of Property
+   * @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"]
+   * @return Cn string
+   */
+  Animals: [
+    '\u9f20',
+    '\u725b',
+    '\u864e',
+    '\u5154',
+    '\u9f99',
+    '\u86c7',
+    '\u9a6c',
+    '\u7f8a',
+    '\u7334',
+    '\u9e21',
+    '\u72d7',
+    '\u732a'
+  ],
+
+  /**
+   * 24节气速查表
+   * @Array Of Property
+   * @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"]
+   * @return Cn string
+   */
+  solarTerm: [
+    '\u5c0f\u5bd2',
+    '\u5927\u5bd2',
+    '\u7acb\u6625',
+    '\u96e8\u6c34',
+    '\u60ca\u86f0',
+    '\u6625\u5206',
+    '\u6e05\u660e',
+    '\u8c37\u96e8',
+    '\u7acb\u590f',
+    '\u5c0f\u6ee1',
+    '\u8292\u79cd',
+    '\u590f\u81f3',
+    '\u5c0f\u6691',
+    '\u5927\u6691',
+    '\u7acb\u79cb',
+    '\u5904\u6691',
+    '\u767d\u9732',
+    '\u79cb\u5206',
+    '\u5bd2\u9732',
+    '\u971c\u964d',
+    '\u7acb\u51ac',
+    '\u5c0f\u96ea',
+    '\u5927\u96ea',
+    '\u51ac\u81f3'
+  ],
+
+  /**
+   * 1900-2100各年的24节气日期速查表
+   * @Array Of Property
+   * @return 0x string For splice
+   */
+  sTermInfo: [
+    '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b97bd19801ec9210c965cc920e',
+    '97bcf97c3598082c95f8c965cc920f',
+    '97bd0b06bdb0722c965ce1cfcc920f',
+    'b027097bd097c36b0b6fc9274c91aa',
+    '97b6b97bd19801ec9210c965cc920e',
+    '97bcf97c359801ec95f8c965cc920f',
+    '97bd0b06bdb0722c965ce1cfcc920f',
+    'b027097bd097c36b0b6fc9274c91aa',
+    '97b6b97bd19801ec9210c965cc920e',
+    '97bcf97c359801ec95f8c965cc920f',
+    '97bd0b06bdb0722c965ce1cfcc920f',
+    'b027097bd097c36b0b6fc9274c91aa',
+    '9778397bd19801ec9210c965cc920e',
+    '97b6b97bd19801ec95f8c965cc920f',
+    '97bd09801d98082c95f8e1cfcc920f',
+    '97bd097bd097c36b0b6fc9210c8dc2',
+    '9778397bd197c36c9210c9274c91aa',
+    '97b6b97bd19801ec95f8c965cc920e',
+    '97bd09801d98082c95f8e1cfcc920f',
+    '97bd097bd097c36b0b6fc9210c8dc2',
+    '9778397bd097c36c9210c9274c91aa',
+    '97b6b97bd19801ec95f8c965cc920e',
+    '97bcf97c3598082c95f8e1cfcc920f',
+    '97bd097bd097c36b0b6fc9210c8dc2',
+    '9778397bd097c36c9210c9274c91aa',
+    '97b6b97bd19801ec9210c965cc920e',
+    '97bcf97c3598082c95f8c965cc920f',
+    '97bd097bd097c35b0b6fc920fb0722',
+    '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b97bd19801ec9210c965cc920e',
+    '97bcf97c3598082c95f8c965cc920f',
+    '97bd097bd097c35b0b6fc920fb0722',
+    '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b97bd19801ec9210c965cc920e',
+    '97bcf97c359801ec95f8c965cc920f',
+    '97bd097bd097c35b0b6fc920fb0722',
+    '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b97bd19801ec9210c965cc920e',
+    '97bcf97c359801ec95f8c965cc920f',
+    '97bd097bd097c35b0b6fc920fb0722',
+    '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b97bd19801ec9210c965cc920e',
+    '97bcf97c359801ec95f8c965cc920f',
+    '97bd097bd07f595b0b6fc920fb0722',
+    '9778397bd097c36b0b6fc9210c8dc2',
+    '9778397bd19801ec9210c9274c920e',
+    '97b6b97bd19801ec95f8c965cc920f',
+    '97bd07f5307f595b0b0bc920fb0722',
+    '7f0e397bd097c36b0b6fc9210c8dc2',
+    '9778397bd097c36c9210c9274c920e',
+    '97b6b97bd19801ec95f8c965cc920f',
+    '97bd07f5307f595b0b0bc920fb0722',
+    '7f0e397bd097c36b0b6fc9210c8dc2',
+    '9778397bd097c36c9210c9274c91aa',
+    '97b6b97bd19801ec9210c965cc920e',
+    '97bd07f1487f595b0b0bc920fb0722',
+    '7f0e397bd097c36b0b6fc9210c8dc2',
+    '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b97bd19801ec9210c965cc920e',
+    '97bcf7f1487f595b0b0bb0b6fb0722',
+    '7f0e397bd097c35b0b6fc920fb0722',
+    '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b97bd19801ec9210c965cc920e',
+    '97bcf7f1487f595b0b0bb0b6fb0722',
+    '7f0e397bd097c35b0b6fc920fb0722',
+    '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b97bd19801ec9210c965cc920e',
+    '97bcf7f1487f531b0b0bb0b6fb0722',
+    '7f0e397bd097c35b0b6fc920fb0722',
+    '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b97bd19801ec9210c965cc920e',
+    '97bcf7f1487f531b0b0bb0b6fb0722',
+    '7f0e397bd07f595b0b6fc920fb0722',
+    '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b97bd19801ec9210c9274c920e',
+    '97bcf7f0e47f531b0b0bb0b6fb0722',
+    '7f0e397bd07f595b0b0bc920fb0722',
+    '9778397bd097c36b0b6fc9210c91aa',
+    '97b6b97bd197c36c9210c9274c920e',
+    '97bcf7f0e47f531b0b0bb0b6fb0722',
+    '7f0e397bd07f595b0b0bc920fb0722',
+    '9778397bd097c36b0b6fc9210c8dc2',
+    '9778397bd097c36c9210c9274c920e',
+    '97b6b7f0e47f531b0723b0b6fb0722',
+    '7f0e37f5307f595b0b0bc920fb0722',
+    '7f0e397bd097c36b0b6fc9210c8dc2',
+    '9778397bd097c36b0b70c9274c91aa',
+    '97b6b7f0e47f531b0723b0b6fb0721',
+    '7f0e37f1487f595b0b0bb0b6fb0722',
+    '7f0e397bd097c35b0b6fc9210c8dc2',
+    '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b7f0e47f531b0723b0b6fb0721',
+    '7f0e27f1487f595b0b0bb0b6fb0722',
+    '7f0e397bd097c35b0b6fc920fb0722',
+    '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b7f0e47f531b0723b0b6fb0721',
+    '7f0e27f1487f531b0b0bb0b6fb0722',
+    '7f0e397bd097c35b0b6fc920fb0722',
+    '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b7f0e47f531b0723b0b6fb0721',
+    '7f0e27f1487f531b0b0bb0b6fb0722',
+    '7f0e397bd097c35b0b6fc920fb0722',
+    '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b7f0e47f531b0723b0b6fb0721',
+    '7f0e27f1487f531b0b0bb0b6fb0722',
+    '7f0e397bd07f595b0b0bc920fb0722',
+    '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b7f0e47f531b0723b0787b0721',
+    '7f0e27f0e47f531b0b0bb0b6fb0722',
+    '7f0e397bd07f595b0b0bc920fb0722',
+    '9778397bd097c36b0b6fc9210c91aa',
+    '97b6b7f0e47f149b0723b0787b0721',
+    '7f0e27f0e47f531b0723b0b6fb0722',
+    '7f0e397bd07f595b0b0bc920fb0722',
+    '9778397bd097c36b0b6fc9210c8dc2',
+    '977837f0e37f149b0723b0787b0721',
+    '7f07e7f0e47f531b0723b0b6fb0722',
+    '7f0e37f5307f595b0b0bc920fb0722',
+    '7f0e397bd097c35b0b6fc9210c8dc2',
+    '977837f0e37f14998082b0787b0721',
+    '7f07e7f0e47f531b0723b0b6fb0721',
+    '7f0e37f1487f595b0b0bb0b6fb0722',
+    '7f0e397bd097c35b0b6fc9210c8dc2',
+    '977837f0e37f14998082b0787b06bd',
+    '7f07e7f0e47f531b0723b0b6fb0721',
+    '7f0e27f1487f531b0b0bb0b6fb0722',
+    '7f0e397bd097c35b0b6fc920fb0722',
+    '977837f0e37f14998082b0787b06bd',
+    '7f07e7f0e47f531b0723b0b6fb0721',
+    '7f0e27f1487f531b0b0bb0b6fb0722',
+    '7f0e397bd097c35b0b6fc920fb0722',
+    '977837f0e37f14998082b0787b06bd',
+    '7f07e7f0e47f531b0723b0b6fb0721',
+    '7f0e27f1487f531b0b0bb0b6fb0722',
+    '7f0e397bd07f595b0b0bc920fb0722',
+    '977837f0e37f14998082b0787b06bd',
+    '7f07e7f0e47f531b0723b0b6fb0721',
+    '7f0e27f1487f531b0b0bb0b6fb0722',
+    '7f0e397bd07f595b0b0bc920fb0722',
+    '977837f0e37f14998082b0787b06bd',
+    '7f07e7f0e47f149b0723b0787b0721',
+    '7f0e27f0e47f531b0b0bb0b6fb0722',
+    '7f0e397bd07f595b0b0bc920fb0722',
+    '977837f0e37f14998082b0723b06bd',
+    '7f07e7f0e37f149b0723b0787b0721',
+    '7f0e27f0e47f531b0723b0b6fb0722',
+    '7f0e397bd07f595b0b0bc920fb0722',
+    '977837f0e37f14898082b0723b02d5',
+    '7ec967f0e37f14998082b0787b0721',
+    '7f07e7f0e47f531b0723b0b6fb0722',
+    '7f0e37f1487f595b0b0bb0b6fb0722',
+    '7f0e37f0e37f14898082b0723b02d5',
+    '7ec967f0e37f14998082b0787b0721',
+    '7f07e7f0e47f531b0723b0b6fb0722',
+    '7f0e37f1487f531b0b0bb0b6fb0722',
+    '7f0e37f0e37f14898082b0723b02d5',
+    '7ec967f0e37f14998082b0787b06bd',
+    '7f07e7f0e47f531b0723b0b6fb0721',
+    '7f0e37f1487f531b0b0bb0b6fb0722',
+    '7f0e37f0e37f14898082b072297c35',
+    '7ec967f0e37f14998082b0787b06bd',
+    '7f07e7f0e47f531b0723b0b6fb0721',
+    '7f0e27f1487f531b0b0bb0b6fb0722',
+    '7f0e37f0e37f14898082b072297c35',
+    '7ec967f0e37f14998082b0787b06bd',
+    '7f07e7f0e47f531b0723b0b6fb0721',
+    '7f0e27f1487f531b0b0bb0b6fb0722',
+    '7f0e37f0e366aa89801eb072297c35',
+    '7ec967f0e37f14998082b0787b06bd',
+    '7f07e7f0e47f149b0723b0787b0721',
+    '7f0e27f1487f531b0b0bb0b6fb0722',
+    '7f0e37f0e366aa89801eb072297c35',
+    '7ec967f0e37f14998082b0723b06bd',
+    '7f07e7f0e47f149b0723b0787b0721',
+    '7f0e27f0e47f531b0723b0b6fb0722',
+    '7f0e37f0e366aa89801eb072297c35',
+    '7ec967f0e37f14998082b0723b06bd',
+    '7f07e7f0e37f14998083b0787b0721',
+    '7f0e27f0e47f531b0723b0b6fb0722',
+    '7f0e37f0e366aa89801eb072297c35',
+    '7ec967f0e37f14898082b0723b02d5',
+    '7f07e7f0e37f14998082b0787b0721',
+    '7f07e7f0e47f531b0723b0b6fb0722',
+    '7f0e36665b66aa89801e9808297c35',
+    '665f67f0e37f14898082b0723b02d5',
+    '7ec967f0e37f14998082b0787b0721',
+    '7f07e7f0e47f531b0723b0b6fb0722',
+    '7f0e36665b66a449801e9808297c35',
+    '665f67f0e37f14898082b0723b02d5',
+    '7ec967f0e37f14998082b0787b06bd',
+    '7f07e7f0e47f531b0723b0b6fb0721',
+    '7f0e36665b66a449801e9808297c35',
+    '665f67f0e37f14898082b072297c35',
+    '7ec967f0e37f14998082b0787b06bd',
+    '7f07e7f0e47f531b0723b0b6fb0721',
+    '7f0e26665b66a449801e9808297c35',
+    '665f67f0e37f1489801eb072297c35',
+    '7ec967f0e37f14998082b0787b06bd',
+    '7f07e7f0e47f531b0723b0b6fb0721',
+    '7f0e27f1487f531b0b0bb0b6fb0722'
+  ],
+
+  /**
+   * 数字转中文速查表
+   * @Array Of Property
+   * @trans ['日','一','二','三','四','五','六','七','八','九','十']
+   * @return Cn string
+   */
+  nStr1: [
+    '\u65e5',
+    '\u4e00',
+    '\u4e8c',
+    '\u4e09',
+    '\u56db',
+    '\u4e94',
+    '\u516d',
+    '\u4e03',
+    '\u516b',
+    '\u4e5d',
+    '\u5341'
+  ],
+
+  /**
+   * 日期转农历称呼速查表
+   * @Array Of Property
+   * @trans ['初','十','廿','卅']
+   * @return Cn string
+   */
+  nStr2: ['\u521d', '\u5341', '\u5eff', '\u5345'],
+
+  /**
+   * 月份转农历称呼速查表
+   * @Array Of Property
+   * @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊']
+   * @return Cn string
+   */
+  nStr3: [
+    '\u6b63',
+    '\u4e8c',
+    '\u4e09',
+    '\u56db',
+    '\u4e94',
+    '\u516d',
+    '\u4e03',
+    '\u516b',
+    '\u4e5d',
+    '\u5341',
+    '\u51ac',
+    '\u814a'
+  ],
+
+  /**
+   * 返回农历y年一整年的总天数
+   * @param lunar Year
+   * @return Number
+   * @eg:var count = calendar.lYearDays(1987) ;//count=387
+   */
+  lYearDays: function(y) {
+    let i
+    let sum = 348
+    for (i = 0x8000; i > 0x8; i >>= 1) {
+      sum += calendar.lunarInfo[y - 1900] & i ? 1 : 0
+    }
+    return sum + calendar.leapDays(y)
+  },
+
+  /**
+   * 返回农历y年闰月是哪个月;若y年没有闰月 则返回0
+   * @param lunar Year
+   * @return Number (0-12)
+   * @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6
+   */
+  leapMonth: function(y) {
+    // 闰字编码 \u95f0
+    return calendar.lunarInfo[y - 1900] & 0xf
+  },
+
+  /**
+   * 返回农历y年闰月的天数 若该年没有闰月则返回0
+   * @param lunar Year
+   * @return Number (0、29、30)
+   * @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29
+   */
+  leapDays: function(y) {
+    if (calendar.leapMonth(y)) {
+      return calendar.lunarInfo[y - 1900] & 0x10000 ? 30 : 29
+    }
+    return 0
+  },
+
+  /**
+   * 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法
+   * @param lunar Year
+   * @return Number (-1、29、30)
+   * @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29
+   */
+  monthDays: function(y, m) {
+    if (m > 12 || m < 1) return -1 // 月份参数从1至12,参数错误返回-1
+    return calendar.lunarInfo[y - 1900] & (0x10000 >> m) ? 30 : 29
+  },
+
+  /**
+   * 返回公历(!)y年m月的天数
+   * @param solar Year
+   * @return Number (-1、28、29、30、31)
+   * @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30
+   */
+  solarDays: function(y, m) {
+    if (m > 12 || m < 1) return -1 // 若参数错误 返回-1
+    const ms = m - 1
+    if (+ms === 1) {
+      // 2月份的闰平规律测算后确认返回28或29
+      return (y % 4 === 0 && y % 100 !== 0) || y % 400 === 0 ? 29 : 28
+    } else {
+      return calendar.solarMonth[ms]
+    }
+  },
+
+  /**
+   * 农历年份转换为干支纪年
+   * @param  lYear 农历年的年份数
+   * @return Cn string
+   */
+  toGanZhiYear: function(lYear) {
+    let ganKey = (lYear - 3) % 10
+    let zhiKey = (lYear - 3) % 12
+    if (+ganKey === 0) ganKey = 10 // 如果余数为0则为最后一个天干
+    if (+zhiKey === 0) zhiKey = 12 // 如果余数为0则为最后一个地支
+    return calendar.Gan[ganKey - 1] + calendar.Zhi[zhiKey - 1]
+  },
+
+  /**
+   * 公历月、日判断所属星座
+   * @param  cMonth [description]
+   * @param  cDay [description]
+   * @return Cn string
+   */
+  toAstro: function(cMonth, cDay) {
+    const s =
+      '\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf'
+    const arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22]
+    return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + '\u5ea7' // 座
+  },
+
+  /**
+   * 传入offset偏移量返回干支
+   * @param offset 相对甲子的偏移量
+   * @return Cn string
+   */
+  toGanZhi: function(offset) {
+    return calendar.Gan[offset % 10] + calendar.Zhi[offset % 12]
+  },
+
+  /**
+   * 传入公历(!)y年获得该年第n个节气的公历日期
+   * @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起
+   * @return day Number
+   * @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春
+   */
+  getTerm: function(y, n) {
+    if (y < 1900 || y > 2100) return -1
+    if (n < 1 || n > 24) return -1
+    const _table = calendar.sTermInfo[y - 1900]
+    const _info = [
+      parseInt('0x' + _table.substr(0, 5)).toString(),
+      parseInt('0x' + _table.substr(5, 5)).toString(),
+      parseInt('0x' + _table.substr(10, 5)).toString(),
+      parseInt('0x' + _table.substr(15, 5)).toString(),
+      parseInt('0x' + _table.substr(20, 5)).toString(),
+      parseInt('0x' + _table.substr(25, 5)).toString()
+    ]
+    const _calday = [
+      _info[0].substr(0, 1),
+      _info[0].substr(1, 2),
+      _info[0].substr(3, 1),
+      _info[0].substr(4, 2),
+
+      _info[1].substr(0, 1),
+      _info[1].substr(1, 2),
+      _info[1].substr(3, 1),
+      _info[1].substr(4, 2),
+
+      _info[2].substr(0, 1),
+      _info[2].substr(1, 2),
+      _info[2].substr(3, 1),
+      _info[2].substr(4, 2),
+
+      _info[3].substr(0, 1),
+      _info[3].substr(1, 2),
+      _info[3].substr(3, 1),
+      _info[3].substr(4, 2),
+
+      _info[4].substr(0, 1),
+      _info[4].substr(1, 2),
+      _info[4].substr(3, 1),
+      _info[4].substr(4, 2),
+
+      _info[5].substr(0, 1),
+      _info[5].substr(1, 2),
+      _info[5].substr(3, 1),
+      _info[5].substr(4, 2)
+    ]
+    return parseInt(_calday[n - 1])
+  },
+
+  /**
+   * 传入农历数字月份返回汉语通俗表示法
+   * @param lunar month
+   * @return Cn string
+   * @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月'
+   */
+  toChinaMonth: function(m) {
+    // 月 => \u6708
+    if (m > 12 || m < 1) return -1 // 若参数错误 返回-1
+    let s = calendar.nStr3[m - 1]
+    s += '\u6708' // 加上月字
+    return s
+  },
+
+  /**
+   * 传入农历日期数字返回汉字表示法
+   * @param lunar day
+   * @return Cn string
+   * @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一'
+   */
+  toChinaDay: function(d) {
+    // 日 => \u65e5
+    let s
+    switch (d) {
+      case 10:
+        s = '\u521d\u5341'
+        break
+      case 20:
+        s = '\u4e8c\u5341'
+        break
+      case 30:
+        s = '\u4e09\u5341'
+        break
+      default:
+        s = calendar.nStr2[Math.floor(d / 10)]
+        s += calendar.nStr1[d % 10]
+    }
+    return s
+  },
+
+  /**
+   * 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春”
+   * @param y year
+   * @return Cn string
+   * @eg:var animal = calendar.getAnimal(1987) ;//animal='兔'
+   */
+  getAnimal: function(y) {
+    return calendar.Animals[(y - 4) % 12]
+  },
+
+  /**
+   * 传入阳历年月日获得详细的公历、农历object信息 <=>JSON
+   * @param y  solar year
+   * @param m  solar month
+   * @param d  solar day
+   * @return JSON object
+   * @eg:console.log(calendar.solar2lunar(1987,11,01));
+   */
+  solar2lunar: function(y, m, d) {
+    // 参数区间1900.1.31~2100.12.31
+    // 年份限定、上限
+    if (y < 1900 || y > 2100) {
+      return -1 // undefined转换为数字变为NaN
+    }
+    // 公历传参最下限
+    if (+y === 1900 && +m === 1 && +d < 31) {
+      return -1
+    }
+    // 未传参 获得当天
+    let objDate
+    if (!y) {
+      objDate = new Date()
+    } else {
+      objDate = new Date(y, parseInt(m) - 1, d)
+    }
+    let i
+    let leap = 0
+    let temp = 0
+    // 修正ymd参数
+    y = objDate.getFullYear()
+    m = objDate.getMonth() + 1
+    d = objDate.getDate()
+    let offset =
+      (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) -
+        Date.UTC(1900, 0, 31)) /
+      86400000
+    for (i = 1900; i < 2101 && offset > 0; i++) {
+      temp = calendar.lYearDays(i)
+      offset -= temp
+    }
+    if (offset < 0) {
+      offset += temp
+      i--
+    }
+
+    // 是否今天
+    const isTodayObj = new Date()
+    let isToday = false
+    if (
+      isTodayObj.getFullYear() === +y &&
+      isTodayObj.getMonth() + 1 === +m &&
+      isTodayObj.getDate() === +d
+    ) {
+      isToday = true
+    }
+    // 星期几
+    let nWeek = objDate.getDay()
+    const cWeek = calendar.nStr1[nWeek]
+    // 数字表示周几顺应天朝周一开始的惯例
+    if (+nWeek === 0) {
+      nWeek = 7
+    }
+    // 农历年
+    const year = i
+    leap = calendar.leapMonth(i) // 闰哪个月
+    let isLeap = false
+
+    // 效验闰月
+    for (i = 1; i < 13 && offset > 0; i++) {
+      // 闰月
+      if (leap > 0 && i === leap + 1 && isLeap === false) {
+        --i
+        isLeap = true
+        temp = calendar.leapDays(year) // 计算农历闰月天数
+      } else {
+        temp = calendar.monthDays(year, i) // 计算农历普通月天数
+      }
+      // 解除闰月
+      if (isLeap === true && i === leap + 1) isLeap = false
+      offset -= temp
+    }
+    // 闰月导致数组下标重叠取反
+    if (offset === 0 && leap > 0 && i === leap + 1) {
+      if (isLeap) {
+        isLeap = false
+      } else {
+        isLeap = true
+        --i
+      }
+    }
+    if (offset < 0) {
+      offset += temp
+      --i
+    }
+    // 农历月
+    const month = i
+    // 农历日
+    const day = offset + 1
+    // 天干地支处理
+    const sm = m - 1
+    const gzY = calendar.toGanZhiYear(year)
+
+    // 当月的两个节气
+    // bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year`
+    const firstNode = calendar.getTerm(y, m * 2 - 1) // 返回当月「节」为几日开始
+    const secondNode = calendar.getTerm(y, m * 2) // 返回当月「节」为几日开始
+
+    // 依据12节气修正干支月
+    let gzM = calendar.toGanZhi((y - 1900) * 12 + m + 11)
+    if (d >= firstNode) {
+      gzM = calendar.toGanZhi((y - 1900) * 12 + m + 12)
+    }
+
+    // 传入的日期的节气与否
+    let isTerm = false
+    let Term = null
+    if (+firstNode === d) {
+      isTerm = true
+      Term = calendar.solarTerm[m * 2 - 2]
+    }
+    if (+secondNode === d) {
+      isTerm = true
+      Term = calendar.solarTerm[m * 2 - 1]
+    }
+    // 日柱 当月一日与 1900/1/1 相差天数
+    const dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10
+    const gzD = calendar.toGanZhi(dayCyclical + d - 1)
+    // 该日期所属的星座
+    const astro = calendar.toAstro(m, d)
+
+    return {
+      lYear: year,
+      lMonth: month,
+      lDay: day,
+      Animal: calendar.getAnimal(year),
+      IMonthCn: (isLeap ? '\u95f0' : '') + calendar.toChinaMonth(month),
+      IDayCn: calendar.toChinaDay(day),
+      cYear: y,
+      cMonth: m,
+      cDay: d,
+      gzYear: gzY,
+      gzMonth: gzM,
+      gzDay: gzD,
+      isToday: isToday,
+      isLeap: isLeap,
+      nWeek: nWeek,
+      ncWeek: '\u661f\u671f' + cWeek,
+      isTerm: isTerm,
+      Term: Term,
+      astro: astro
+    }
+  },
+
+  /**
+   * 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON
+   * @param y  lunar year
+   * @param m  lunar month
+   * @param d  lunar day
+   * @param isLeapMonth  lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可]
+   * @return JSON object
+   * @eg:console.log(calendar.lunar2solar(1987,9,10));
+   */
+  lunar2solar: function(y, m, d, isLeapMonth) {
+    // 参数区间1900.1.31~2100.12.1
+    isLeapMonth = !!isLeapMonth
+    // let leapOffset = 0;
+    const leapMonth = calendar.leapMonth(y)
+    // let leapDay = calendar.leapDays(y);
+    if (isLeapMonth && leapMonth !== m) return -1 // 传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同
+    if (
+      (+y === 2100 && +m === 12 && +d > 1) ||
+      (+y === 1900 && +m === 1 && +d < 31)
+    )
+      return -1 // 超出了最大极限值
+    const day = calendar.monthDays(y, m)
+    let _day = day
+    // bugFix 2016-9-25
+    // if month is leap, _day use leapDays method
+    if (isLeapMonth) {
+      _day = calendar.leapDays(y, m)
+    }
+    if (y < 1900 || y > 2100 || d > _day) return -1 // 参数合法性效验
+
+    // 计算农历的时间差
+    let offset = 0
+    for (let i = 1900; i < y; i++) {
+      offset += calendar.lYearDays(i)
+    }
+    let leap = 0
+    let isAdd = false
+    for (let i = 1; i < m; i++) {
+      leap = calendar.leapMonth(y)
+      if (!isAdd) {
+        // 处理闰月
+        if (leap <= i && leap > 0) {
+          offset += calendar.leapDays(y)
+          isAdd = true
+        }
+      }
+      offset += calendar.monthDays(y, i)
+    }
+    // 转换闰月农历 需补充该年闰月的前一个月的时差
+    if (isLeapMonth) offset += day
+    // 1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点)
+    const stmap = Date.UTC(1900, 1, 30, 0, 0, 0)
+    const calObj = new Date((offset + d - 31) * 86400000 + stmap)
+    const cY = calObj.getUTCFullYear()
+    const cM = calObj.getUTCMonth() + 1
+    const cD = calObj.getUTCDate()
+
+    return calendar.solar2lunar(cY, cM, cD)
+  }
+}
+
+const {
+  Gan,
+  Zhi,
+  nStr1,
+  nStr2,
+  nStr3,
+  Animals,
+  solarTerm,
+  lunarInfo,
+  sTermInfo,
+  solarMonth,
+  ...rest
+} = calendar
+
+export default rest

+ 47 - 0
components/calendar/plugins/solarLunar/index.js

xqd
@@ -0,0 +1,47 @@
+import { dateUtil } from '../../utils/index'
+import convertSolarLunar from './convertSolarLunar'
+
+export default () => {
+  return {
+    name: 'convertSolarLunar',
+    beforeRender(calendarData = {}, calendarConfig = {}) {
+      let { dates = [], selectedDates = [] } = calendarData
+      if (calendarConfig.showLunar) {
+        dates = dates.map(dataInfo => {
+          const { year, month, date } = dataInfo
+          return {
+            ...dataInfo,
+            lunar: convertSolarLunar.solar2lunar(year, month, date)
+          }
+        })
+        selectedDates = selectedDates.map(dataInfo => {
+          const { year, month, date } = dataInfo
+          return {
+            ...dataInfo,
+            lunar: convertSolarLunar.solar2lunar(year, month, date)
+          }
+        })
+      }
+      return {
+        calendarData: {
+          ...calendarData,
+          dates: dates,
+          selectedDates: selectedDates
+        },
+        calendarConfig
+      }
+    },
+    methods() {
+      return {
+        convertSolarLunar: dateInfo => {
+          if (!dateInfo) return dateInfo
+          if (typeof dateInfo === 'string' && dateInfo.includes('-')) {
+            dateInfo = dateUtil.transformDateRow2Dict(dateInfo)
+          }
+          const { year, month, date } = dateInfo
+          return convertSolarLunar.solar2lunar(year, month, date)
+        }
+      }
+    }
+  }
+}

+ 305 - 0
components/calendar/plugins/time-range.js

xqd
@@ -0,0 +1,305 @@
+/**
+ * @Author: drfu*
+ * @Description: 时间区域选择
+ * @Date: 2020-10-08 21:22:09*
+ * @Last Modified by: drfu
+ * @Last Modified time: 2020-10-11 13:56:32
+ * */
+
+import { renderCalendar } from '../render'
+import {
+  logger,
+  dateUtil,
+  getCalendarConfig,
+  getCalendarData
+} from '../utils/index'
+
+function pusheNextMonthDateArea(
+  dateInfo = {},
+  startTimestamp,
+  endTimestamp,
+  selectedDates = []
+) {
+  let tempOfSelectedDate = [...selectedDates]
+  const dates = dateUtil.calcDates(dateInfo.year, dateInfo.month)
+  let datesLen = dates.length
+  for (let i = 0; i < datesLen; i++) {
+    const date = dates[i]
+    const timeStamp = dateUtil.getTimeStamp(date)
+    if (timeStamp <= endTimestamp && timeStamp >= startTimestamp) {
+      tempOfSelectedDate.push({
+        ...date,
+        choosed: true
+      })
+    }
+    if (i === datesLen - 1 && timeStamp < endTimestamp) {
+      pusheNextMonthDateArea(
+        dateUtil.getNextMonthInfo(date),
+        startTimestamp,
+        endTimestamp,
+        tempOfSelectedDate
+      )
+    }
+  }
+  return tempOfSelectedDate
+}
+function pushPrevMonthDateArea(
+  dateInfo = {},
+  startTimestamp,
+  endTimestamp,
+  selectedDates = []
+) {
+  let tempOfSelectedDate = [...selectedDates]
+  const dates = dateUtil.sortDatesByTime(
+    dateUtil.calcDates(dateInfo.year, dateInfo.month),
+    'desc'
+  )
+  let datesLen = dates.length
+  let firstDate = dateUtil.getTimeStamp(dates[0])
+  for (let i = 0; i < datesLen; i++) {
+    const date = dates[i]
+    const timeStamp = dateUtil.getTimeStamp(date)
+    if (timeStamp >= startTimestamp && timeStamp <= endTimestamp) {
+      tempOfSelectedDate.push({
+        ...date,
+        choosed: true
+      })
+    }
+    if (i === datesLen - 1 && firstDate > startTimestamp) {
+      pushPrevMonthDateArea(
+        dateUtil.getPrevMonthInfo(date),
+        startTimestamp,
+        endTimestamp,
+        tempOfSelectedDate
+      )
+    }
+  }
+  return tempOfSelectedDate
+}
+/**
+ * 当设置日期区域非当前时保存其他月份的日期至已选日期数组
+ * @param {object} info
+ */
+function calcDateWhenNotInOneMonth(info) {
+  const { firstDate, lastDate, startTimestamp, endTimestamp } = info
+  let { selectedDate } = info
+  if (dateUtil.getTimeStamp(firstDate) > startTimestamp) {
+    selectedDate = pushPrevMonthDateArea(
+      dateUtil.getPrevMonthInfo(firstDate),
+      startTimestamp,
+      endTimestamp,
+      selectedDate
+    )
+  }
+  if (dateUtil.getTimeStamp(lastDate) < endTimestamp) {
+    selectedDate = pusheNextMonthDateArea(
+      dateUtil.getNextMonthInfo(lastDate),
+      startTimestamp,
+      endTimestamp,
+      selectedDate
+    )
+  }
+  return [...selectedDate]
+}
+
+/**
+ *  指定日期区域转时间戳
+ * @param {array} timearea 时间区域
+ */
+export function convertTimeRangeToTimestamp(timearea = []) {
+  const start = timearea[0].split('-')
+  const end = timearea[1].split('-')
+  if (start.length !== 3 || end.length !== 3) {
+    logger.warn('enableArea() 参数格式为: ["2018-2-1", "2018-3-1"]')
+    return {}
+  }
+  const startTimestamp = dateUtil
+    .newDate(start[0], start[1], start[2])
+    .getTime()
+  const endTimestamp = dateUtil.newDate(end[0], end[1], end[2]).getTime()
+  return {
+    start,
+    end,
+    startTimestamp,
+    endTimestamp
+  }
+}
+
+/**
+ * 校验时间区域是否合法
+ * @param {array} dateArea 时间区域
+ */
+function validateTimeRange(dateArea) {
+  const {
+    start,
+    end,
+    startTimestamp,
+    endTimestamp
+  } = convertTimeRangeToTimestamp(dateArea)
+  if (!start || !end) return
+  const startMonthDays = dateUtil.getDatesCountOfMonth(start[0], start[1])
+  const endMonthDays = dateUtil.getDatesCountOfMonth(end[0], end[1])
+  if (start[2] > startMonthDays || start[2] < 1) {
+    logger.warn('enableArea() 开始日期错误,指定日期不在当前月份天数范围内')
+    return false
+  } else if (start[1] > 12 || start[1] < 1) {
+    logger.warn('enableArea() 开始日期错误,月份超出1-12月份')
+    return false
+  } else if (end[2] > endMonthDays || end[2] < 1) {
+    logger.warn('enableArea() 截止日期错误,指定日期不在当前月份天数范围内')
+    return false
+  } else if (end[1] > 12 || end[1] < 1) {
+    logger.warn('enableArea() 截止日期错误,月份超出1-12月份')
+    return false
+  } else if (startTimestamp > endTimestamp) {
+    logger.warn('enableArea()参数最小日期大于了最大日期')
+    return false
+  } else {
+    return true
+  }
+}
+
+export default () => {
+  return {
+    name: 'timeRange',
+    beforeRender(calendarData = {}, calendarConfig = {}) {
+      const {
+        chooseAreaTimestamp = [],
+        dates = [],
+        selectedDates = []
+      } = calendarData
+      let __dates = dates
+      let __selectedDates = selectedDates
+      const [startDateTimestamp, endDateTimestamp] = chooseAreaTimestamp
+      if (chooseAreaTimestamp.length === 2) {
+        __selectedDates = []
+        __dates = dates.map(d => {
+          const date = { ...d }
+          const dateTimeStamp = dateUtil.getTimeStamp(date)
+          if (
+            dateTimeStamp >= startDateTimestamp &&
+            endDateTimestamp >= dateTimeStamp
+          ) {
+            date.choosed = true
+            __selectedDates.push(date)
+          } else {
+            date.choosed = false
+            __selectedDates = __selectedDates.filter(
+              item => dateUtil.getTimeStamp(item) !== dateTimeStamp
+            )
+          }
+          return date
+        })
+        const monthOfStartDate = new Date(startDateTimestamp).getMonth()
+        const monthOfEndDate = new Date(endDateTimestamp).getMonth()
+        if (monthOfStartDate !== monthOfEndDate) {
+          __selectedDates = calcDateWhenNotInOneMonth({
+            firstDate: __dates[0],
+            lastDate: __dates[__dates.length - 1],
+            startTimestamp: startDateTimestamp,
+            endTimestamp: endDateTimestamp,
+            selectedDate: __selectedDates
+          })
+        }
+      }
+      return {
+        calendarData: {
+          ...calendarData,
+          dates: __dates,
+          selectedDates: dateUtil.sortDatesByTime(
+            dateUtil.uniqueArrayByDate(__selectedDates)
+          )
+        },
+        calendarConfig
+      }
+    },
+    onTapDate(tapedDate, calendarData = {}, calendarConfig = {}) {
+      if (!calendarConfig.chooseAreaMode) {
+        return {
+          calendarData,
+          calendarConfig
+        }
+      }
+      let {
+        tempChooseAreaTimestamp = [],
+        chooseAreaTimestamp: existChooseAreaTimestamp = [],
+        selectedDates = [],
+        dates = []
+      } = calendarData
+      const timestamp = dateUtil.getTimeStamp(tapedDate)
+      let __dates = [...dates]
+      let __selectedDates = [...selectedDates]
+      if (
+        tempChooseAreaTimestamp.length === 2 ||
+        existChooseAreaTimestamp.length === 2
+      ) {
+        tempChooseAreaTimestamp = [tapedDate]
+        __selectedDates = []
+        __dates.forEach(d => (d.choosed = false))
+      } else if (tempChooseAreaTimestamp.length === 1) {
+        const preChoosedDate = tempChooseAreaTimestamp[0]
+        const preTimestamp = dateUtil.getTimeStamp(preChoosedDate)
+        if (preTimestamp <= timestamp) {
+          tempChooseAreaTimestamp.push(tapedDate)
+        } else if (preTimestamp > timestamp) {
+          tempChooseAreaTimestamp.unshift(tapedDate)
+        }
+      } else {
+        tempChooseAreaTimestamp = [tapedDate]
+      }
+      let chooseAreaTimestamp = []
+      if (tempChooseAreaTimestamp.length === 2) {
+        const [startDate, endDate] = tempChooseAreaTimestamp
+        const startDateTimestamp = dateUtil.getTimeStamp(startDate)
+        const endDateTimestamp = dateUtil.getTimeStamp(endDate)
+        chooseAreaTimestamp = [startDateTimestamp, endDateTimestamp]
+      }
+      return {
+        calendarData: {
+          ...calendarData,
+          chooseAreaTimestamp,
+          tempChooseAreaTimestamp,
+          dates: __dates,
+          selectedDates: __selectedDates
+        },
+        calendarConfig: {
+          ...calendarConfig,
+          multi: true
+        }
+      }
+    },
+    methods(component) {
+      return {
+        /**
+         * 设置连续日期选择区域
+         * @param {array} dateArea 区域开始结束日期数组
+         */
+        chooseDateArea: (dateArea = []) => {
+          if (dateArea.length === 1) {
+            dateArea = dateArea.concat(dateArea)
+          }
+          if (dateArea.length !== 2) return
+          const isRight = validateTimeRange(dateArea)
+          if (!isRight) return
+          const config = getCalendarConfig(component) || {}
+          const { startTimestamp, endTimestamp } = convertTimeRangeToTimestamp(
+            dateArea
+          )
+          const existCalendarData = getCalendarData('calendar', component)
+          return renderCalendar.call(
+            component,
+            {
+              ...existCalendarData,
+              chooseAreaTimestamp: [startTimestamp, endTimestamp]
+            },
+            {
+              ...config,
+              multi: true,
+              chooseAreaMode: true
+            }
+          )
+        }
+      }
+    }
+  }
+}

+ 150 - 0
components/calendar/plugins/todo.js

xqd
@@ -0,0 +1,150 @@
+/**
+ * @Author: drfu*
+ * @Description: 代办事项
+ * @Date: 2020-10-08 21:22:09*
+ * @Last Modified by: drfu
+ * @Last Modified time: 2020-10-11 14:23:02
+ * */
+
+import { getCalendarData, dateUtil } from '../utils/index'
+import { renderCalendar } from '../render'
+
+function filterTodos({ curYear, curMonth, exsitedTodos, toSetTodos }) {
+  const exsitedCurrentMonthTodos = dateUtil.filterDatesByYM(
+    {
+      year: curYear,
+      month: curMonth
+    },
+    exsitedTodos
+  )
+  const toSetTodosOfThisMonth = dateUtil.filterDatesByYM(
+    {
+      year: curYear,
+      month: curMonth
+    },
+    toSetTodos
+  )
+  const allTodosOfThisMonths = dateUtil.uniqueArrayByDate(
+    exsitedCurrentMonthTodos.concat(toSetTodosOfThisMonth)
+  )
+  return allTodosOfThisMonths
+}
+
+function updateDatePropertyOfTodoLabel(todos, dates, showLabelAlways) {
+  const datesInfo = [...dates]
+  for (let todo of todos) {
+    let target = datesInfo[todo.date - 1]
+    if (!target) continue
+    if (showLabelAlways) {
+      target.showTodoLabel = true
+    } else {
+      target.showTodoLabel = !target.choosed
+    }
+    if (target.showTodoLabel) {
+      target.todoText = todo.todoText
+    }
+    target.color = todo.color
+  }
+  return datesInfo
+}
+
+export default () => {
+  return {
+    name: 'todo',
+    methods(component) {
+      return {
+        setTodos: (options = {}) => {
+          const calendar = getCalendarData('calendar', component)
+          if (!calendar || !calendar.dates) {
+            return Promise.reject('请等待日历初始化完成后再调用该方法')
+          }
+          let dates = [...calendar.dates]
+          const { curYear, curMonth } = calendar
+          const {
+            circle,
+            dotColor = '',
+            pos = 'bottom',
+            showLabelAlways,
+            dates: todoDates = []
+          } = options
+          const { todos = [] } = calendar
+          const allTodosOfThisMonths = filterTodos({
+            curYear,
+            curMonth,
+            exsitedTodos: todos,
+            toSetTodos: todoDates
+          })
+          dates = updateDatePropertyOfTodoLabel(
+            allTodosOfThisMonths,
+            dates,
+            showLabelAlways
+          )
+          const calendarData = {
+            dates,
+            todos: dateUtil.uniqueArrayByDate(
+              todos.concat(
+                todoDates.map(date => dateUtil.tranformStr2NumOfDate(date))
+              )
+            )
+          }
+          if (!circle) {
+            calendarData.todoLabelPos = pos
+            calendarData.todoLabelColor = dotColor
+          }
+          calendarData.todoLabelCircle = circle || false
+          calendarData.showLabelAlways = showLabelAlways || false
+          const existCalendarData = getCalendarData('calendar', component)
+          return renderCalendar.call(component, {
+            ...existCalendarData,
+            ...calendarData
+          })
+        },
+        deleteTodos(todos = []) {
+          if (!(todos instanceof Array) || !todos.length)
+            return Promise.reject('deleteTodos()应为入参为非空数组')
+          const existCalendarData = getCalendarData('calendar', component)
+          const allTodos = existCalendarData.todos || []
+          const toDeleteTodos = todos.map(item => dateUtil.toTimeStr(item))
+          const remainTodos = allTodos.filter(
+            item => !toDeleteTodos.includes(dateUtil.toTimeStr(item))
+          )
+          const { dates, curYear, curMonth } = existCalendarData
+          const _dates = [...dates]
+          const currentMonthTodos = dateUtil.filterDatesByYM(
+            {
+              year: curYear,
+              month: curMonth
+            },
+            remainTodos
+          )
+          _dates.forEach(item => {
+            item.showTodoLabel = false
+          })
+          currentMonthTodos.forEach(item => {
+            _dates[item.date - 1].showTodoLabel = !_dates[item.date - 1].choosed
+          })
+          return renderCalendar.call(component, {
+            ...existCalendarData,
+            dates: _dates,
+            todos: remainTodos
+          })
+        },
+        clearTodos() {
+          const existCalendarData = getCalendarData('calendar', component)
+          const _dates = [...existCalendarData.dates]
+          _dates.forEach(item => {
+            item.showTodoLabel = false
+          })
+          return renderCalendar.call(component, {
+            ...existCalendarData,
+            dates: _dates,
+            todos: []
+          })
+        },
+        getTodos() {
+          return getCalendarData('calendar.todos', component) || []
+        }
+      }
+    }
+  }
+}

+ 432 - 0
components/calendar/plugins/week.js

xqd
@@ -0,0 +1,432 @@
+/**
+ * @Author: drfu*
+ * @Description: 周视图
+ * @Date: 2020-10-08 21:22:09*
+ * @Last Modified by: drfu
+ * @Last Modified time: 2020-10-12 14:39:45
+ * */
+
+import { renderCalendar } from '../render'
+import {
+  getCalendarConfig,
+  getCalendarData,
+  logger,
+  dateUtil
+} from '../utils/index'
+import { calcJumpData } from '../core'
+
+/**
+ * 当月第一周所有日期
+ */
+function firstWeekInMonth(
+  target = {},
+  calendarDates = [],
+  calendarConfig = {}
+) {
+  const { firstDayOfWeek } = calendarConfig
+  const firstDayOfWeekIsMon = firstDayOfWeek === 'Mon'
+  const { year, month } = target
+  let firstDay = dateUtil.getDayOfWeek(year, month, 1)
+  if (firstDayOfWeekIsMon && firstDay === 0) {
+    firstDay = 7
+  }
+  const [, end] = [0, 7 - firstDay]
+  return calendarDates.slice(0, firstDayOfWeekIsMon ? end + 1 : end)
+}
+
+/**
+ * 当月最后一周所有日期
+ */
+function lastWeekInMonth(target = {}, calendarDates = [], calendarConfig = {}) {
+  const { firstDayOfWeek } = calendarConfig
+  const firstDayOfWeekIsMon = firstDayOfWeek === 'Mon'
+  const { year, month } = target
+  const lastDay = dateUtil.getDatesCountOfMonth(year, month)
+  let lastDayWeek = dateUtil.getDayOfWeek(year, month, lastDay)
+  if (firstDayOfWeekIsMon && lastDayWeek === 0) {
+    lastDayWeek = 7
+  }
+  const [start, end] = [lastDay - lastDayWeek, lastDay]
+  return calendarDates.slice(firstDayOfWeekIsMon ? start : start - 1, end)
+}
+
+/**
+ * 判断目标日期是否在某些指定日历内
+ */
+function dateIsInDatesRange(target, dates) {
+  if (!target || !dates || !dates.length) return false
+  const targetDateStr = dateUtil.toTimeStr(target)
+  let rst = false
+  for (let date of dates) {
+    const dateStr = dateUtil.toTimeStr(date)
+    if (dateStr === targetDateStr) {
+      rst = true
+      return rst
+    }
+    rst = false
+  }
+  return rst
+}
+
+function getDatesWhenTargetInFirstWeek(target, firstWeekDates) {
+  const { year, month } = target
+  const prevMonthInfo = dateUtil.getPrevMonthInfo({ year, month })
+  let lastMonthDatesCount = dateUtil.getDatesCountOfMonth(
+    prevMonthInfo.year,
+    prevMonthInfo.month
+  )
+  let dates = firstWeekDates
+  let firstWeekCount = firstWeekDates.length
+  for (let i = 0; i < 7 - firstWeekCount; i++) {
+    const week = dateUtil.getDayOfWeek(+year, +month, lastMonthDatesCount)
+    dates.unshift({
+      year: prevMonthInfo.year,
+      month: prevMonthInfo.month,
+      date: lastMonthDatesCount,
+      week
+    })
+    lastMonthDatesCount -= 1
+  }
+  return dates
+}
+
+function getDatesWhenTargetInLastWeek(target, lastWeekDates) {
+  const { year, month } = target
+  const prevMonthInfo = dateUtil.getNextMonthInfo({ year, month })
+  let dates = lastWeekDates
+  let lastWeekCount = lastWeekDates.length
+  for (let i = 0; i < 7 - lastWeekCount; i++) {
+    const week = dateUtil.getDayOfWeek(+year, +month, i + 1)
+    dates.push({
+      year: prevMonthInfo.year,
+      month: prevMonthInfo.month,
+      date: i + 1,
+      week
+    })
+  }
+  return dates
+}
+
+function getDates(target, calendarDates = [], calendarConfig = {}) {
+  const { year, month, date } = target
+  const targetDay = dateUtil.getDayOfWeek(year, month, date)
+  const { firstDayOfWeek } = calendarConfig
+  const firstDayOfWeekIsMon = firstDayOfWeek === 'Mon'
+  if (firstDayOfWeekIsMon) {
+    const startIdx = date - targetDay
+    return calendarDates.splice(startIdx, 7)
+  } else {
+    const startIdx = date - targetDay - 1
+    return calendarDates.splice(startIdx, 7)
+  }
+}
+
+function getTargetWeekDates(target, calendarConfig) {
+  if (!target) return
+  const { year, month } = target
+  const calendarDates = dateUtil.calcDates(year, month)
+  const firstWeekDates = firstWeekInMonth(target, calendarDates, calendarConfig)
+  const lastWeekDates = lastWeekInMonth(target, calendarDates, calendarConfig)
+  if (dateIsInDatesRange(target, firstWeekDates)) {
+    return getDatesWhenTargetInFirstWeek(target, firstWeekDates)
+  } else if (dateIsInDatesRange(target, lastWeekDates)) {
+    return getDatesWhenTargetInLastWeek(target, lastWeekDates)
+  } else {
+    return getDates(target, calendarDates, calendarConfig)
+  }
+}
+
+/**
+ * 计算周视图下当前这一周最后一天
+ */
+function calculateLastDateOfCurrentWeek(calendarData = {}) {
+  const { dates = [] } = calendarData
+  return dates[dates.length - 1]
+}
+/**
+ * 计算周视图下当前这一周第一天
+ */
+function calculateFirstDateOfCurrentWeek(calendarData = {}) {
+  const { dates } = calendarData
+  return dates[0]
+}
+
+/**
+ * 计算下一周的日期
+ */
+function calculateNextWeekDates(calendarData = {}) {
+  let { curYear, curMonth } = calendarData
+  let calendarDates = []
+  let lastDateInThisWeek = calculateLastDateOfCurrentWeek(calendarData)
+  const { year: LYear, month: LMonth } = lastDateInThisWeek
+  if (curYear !== LYear || curMonth !== LMonth) {
+    calendarDates = dateUtil.calcDates(LYear, LMonth)
+    curYear = LYear
+    curMonth = LMonth
+  } else {
+    calendarDates = dateUtil.calcDates(curYear, curMonth)
+  }
+  const lastDateInThisMonth = dateUtil.getDatesCountOfMonth(curYear, curMonth)
+  const count = lastDateInThisMonth - lastDateInThisWeek.date
+  const lastDateIdx = calendarDates.findIndex(
+    date => dateUtil.toTimeStr(date) === dateUtil.toTimeStr(lastDateInThisWeek)
+  )
+  const startIdx = lastDateIdx + 1
+  if (count >= 7) {
+    return {
+      dates: calendarDates.splice(startIdx, 7),
+      year: curYear,
+      month: curMonth
+    }
+  } else {
+    const nextMonth = dateUtil.getNextMonthInfo({
+      year: curYear,
+      month: curMonth
+    })
+    const { year, month } = nextMonth || {}
+    const calendarDatesOfNextMonth = dateUtil.calcDates(year, month)
+    const remainDatesOfThisMonth = calendarDates.splice(startIdx)
+    const patchDatesOfNextMonth = calendarDatesOfNextMonth.splice(
+      0,
+      7 - remainDatesOfThisMonth.length
+    )
+    return {
+      dates: [...remainDatesOfThisMonth, ...patchDatesOfNextMonth],
+      ...nextMonth
+    }
+  }
+}
+
+/**
+ * 计算上一周的日期
+ */
+function calculatePrevWeekDates(calendarData = {}) {
+  let { curYear, curMonth } = calendarData
+  let firstDateInThisWeek = calculateFirstDateOfCurrentWeek(calendarData)
+  let calendarDates = []
+  const { year: FYear, month: FMonth } = firstDateInThisWeek
+  if (curYear !== FYear || curMonth !== FMonth) {
+    calendarDates = dateUtil.calcDates(FYear, FMonth)
+    curYear = FYear
+    curMonth = FMonth
+  } else {
+    calendarDates = dateUtil.calcDates(curYear, curMonth)
+  }
+  const firstDateIdx = calendarDates.findIndex(
+    date => dateUtil.toTimeStr(date) === dateUtil.toTimeStr(firstDateInThisWeek)
+  )
+  if (firstDateIdx - 7 >= 0) {
+    const startIdx = firstDateIdx - 7
+    return {
+      dates: calendarDates.splice(startIdx, 7),
+      year: curYear,
+      month: curMonth
+    }
+  } else {
+    const prevMonth = dateUtil.getPrevMonthInfo({
+      year: curYear,
+      month: curMonth
+    })
+    const { year, month } = prevMonth || {}
+    const calendarDatesOfPrevMonth = dateUtil.calcDates(year, month)
+    const remainDatesOfThisMonth = calendarDates.splice(
+      0,
+      firstDateInThisWeek.date - 1
+    )
+    const patchDatesOfPrevMonth = calendarDatesOfPrevMonth.splice(
+      -(7 - remainDatesOfThisMonth.length)
+    )
+    return {
+      dates: [...patchDatesOfPrevMonth, ...remainDatesOfThisMonth],
+      ...prevMonth
+    }
+  }
+}
+
+export default () => {
+  return {
+    name: 'week',
+    beforeRender(calendarData = {}, calendarConfig = {}, component) {
+      const { initializedWeekMode, selectedDates } = calendarData
+      if (calendarConfig.weekMode && !initializedWeekMode) {
+        const { defaultDate } = calendarConfig
+        const target =
+          (selectedDates && selectedDates[0]) ||
+          (defaultDate && dateUtil.transformDateRow2Dict(defaultDate)) ||
+          dateUtil.todayFMD()
+        const waitRenderData = this.methods(
+          component
+        ).__calcDatesWhenSwitchView('week', target)
+        const { data, config } = waitRenderData || {}
+        const setSelectDates = this.methods(
+          component
+        ).__selectTargetDateWhenJump(target, data.dates, config)
+        return {
+          calendarData: {
+            ...data,
+            ...setSelectDates,
+            weeksCh: dateUtil.getWeekHeader(calendarConfig.firstDayOfWeek),
+            initializedWeekMode: true
+          },
+          calendarConfig
+        }
+      }
+      return {
+        calendarData,
+        calendarConfig
+      }
+    },
+    onSwitchCalendar(target = {}, calendarData = {}, component) {
+      const { direction } = target
+      const { curYear, curMonth } = calendarData
+      const calendarConfig = getCalendarConfig(component)
+      let waitRenderData = {}
+      if (calendarConfig.weekMode) {
+        if (direction === 'left') {
+          waitRenderData = calculateNextWeekDates(calendarData)
+        } else {
+          waitRenderData = calculatePrevWeekDates(calendarData)
+        }
+        const { dates, year, month } = waitRenderData
+        return {
+          ...calendarData,
+          dates,
+          curYear: year || curYear,
+          curMonth: month || curMonth
+        }
+      }
+      return calendarData
+    },
+    methods(component) {
+      return {
+        __selectTargetDateWhenJump: (target = {}, dates = [], config = {}) => {
+          let selectedDate = target
+          const weekDates = dates.map((date, idx) => {
+            const tmp = { ...date }
+            tmp.id = idx
+            const isTarget =
+              dateUtil.toTimeStr(target) === dateUtil.toTimeStr(tmp)
+            if (isTarget && !target.choosed && config.autoChoosedWhenJump) {
+              tmp.choosed = true
+              selectedDate = tmp
+            }
+            return tmp
+          })
+          return {
+            dates: weekDates,
+            selectedDates: [selectedDate]
+          }
+        },
+        __calcDatesForWeekMode(target, config = {}, calendarData = {}) {
+          const { year, month } = target || {}
+          const weekDates = getTargetWeekDates(target, config)
+          weekDates.forEach((date, idx) => (date.id = idx))
+          return {
+            data: {
+              ...calendarData,
+              prevMonthGrids: null,
+              nextMonthGrids: null,
+              dates: weekDates,
+              curYear: year,
+              curMonth: month
+            },
+            config: {
+              ...config,
+              weekMode: true
+            }
+          }
+        },
+        __calcDatesForMonthMode(target, config = {}, calendarData = {}) {
+          const { year, month } = target || {}
+          const waitRenderData = calcJumpData({
+            dateInfo: target,
+            config
+          })
+          return {
+            data: {
+              ...calendarData,
+              ...waitRenderData,
+              curYear: year,
+              curMonth: month
+            },
+            config: {
+              ...config,
+              weekMode: false
+            }
+          }
+        },
+        /**
+         * 周、月视图切换
+         * @param {string} view  视图 [week, month]
+         * @param {object} target
+         */
+        __calcDatesWhenSwitchView: (view, target) => {
+          const calendarConfig = getCalendarConfig(component)
+          if (calendarConfig.multi)
+            return logger.warn('多选模式不能切换周月视图')
+          const existCalendarData = getCalendarData('calendar', component) || {}
+          const {
+            selectedDates = [],
+            dates = [],
+            curYear,
+            curMonth
+          } = existCalendarData
+          const currentMonthSelected = selectedDates.filter(
+            item => curYear === +item.year || curMonth === +item.month
+          )
+          let jumpTarget = {}
+          if (target) {
+            jumpTarget = target
+          } else {
+            if (currentMonthSelected.length) {
+              jumpTarget = currentMonthSelected.pop()
+            } else {
+              jumpTarget = dates[0]
+            }
+          }
+          if (view === 'week') {
+            return this.methods(component).__calcDatesForWeekMode(
+              jumpTarget,
+              calendarConfig,
+              existCalendarData
+            )
+          } else {
+            return this.methods(component).__calcDatesForMonthMode(
+              jumpTarget,
+              calendarConfig,
+              existCalendarData
+            )
+          }
+        },
+        weekModeJump: dateInfo => {
+          const target = dateInfo || dateUtil.todayFMD()
+          const existCalendarData = getCalendarData('calendar', component) || {}
+          const waitRenderData = this.methods(
+            component
+          ).__calcDatesWhenSwitchView('week', target)
+          const { data, config } = waitRenderData || {}
+          const setSelectDates = this.methods(
+            component
+          ).__selectTargetDateWhenJump(target, data.dates, config)
+          return renderCalendar.call(
+            component,
+            {
+              ...existCalendarData,
+              ...data,
+              ...setSelectDates
+            },
+            config
+          )
+        },
+        switchView: (view, target) => {
+          const waitRenderData = this.methods(
+            component
+          ).__calcDatesWhenSwitchView(view, target)
+          const { data, config } = waitRenderData || {}
+          if (!data) return logger.warn('当前状态不能切换为周视图')
+          return renderCalendar.call(component, data, config)
+        }
+      }
+    }
+  }
+}

+ 51 - 0
components/calendar/render.js

xqd
@@ -0,0 +1,51 @@
+import plugins from './plugins/index'
+import { getCalendarConfig } from './utils/index'
+
+/**
+ * 渲染日历
+ */
+export function renderCalendar(calendarData, calendarConfig) {
+  return new Promise(resolve => {
+    const Component = this
+    if (Component.firstRender === void 0) {
+      Component.firstRender = true
+    } else {
+      Component.firstRender = false
+    }
+    const exitData = Component.data.calendar || {}
+    for (let plugin of plugins.installed) {
+      const [, p] = plugin
+      if (typeof p.beforeRender === 'function') {
+        const {
+          calendarData: newData,
+          calendarConfig: newConfig
+        } = p.beforeRender(
+          { ...exitData, ...calendarData },
+          calendarConfig || getCalendarConfig(Component),
+          Component
+        )
+        calendarData = newData
+        calendarConfig = newConfig
+      }
+    }
+
+    Component.setData(
+      {
+        config: calendarConfig,
+        calendar: calendarData
+      },
+      () => {
+        const rst = {
+          calendar: calendarData,
+          config: calendarConfig,
+          firstRender: Component.firstRender
+        }
+        resolve(rst)
+        if (Component.firstRender) {
+          Component.triggerEvent('afterCalendarRender', rst)
+          Component.firstRender = false
+        }
+      }
+    )
+  })
+}

Datei-Diff unterdrückt, da er zu groß ist
+ 2 - 0
components/calendar/theme/iconfont.wxss


+ 61 - 0
components/calendar/theme/theme-default.wxss

xqd
@@ -0,0 +1,61 @@
+
+/* 日历主要颜色相关样式 */
+
+.default_color,
+.default_weekend-color,
+.default_handle-color,
+.default_week-color {
+    color: #ff629a;
+}
+
+.default_today {
+    color: #fff;
+    background-color: #874fb4;
+}
+
+.default_choosed {
+    color: #fff;
+    background-color: #ff629a;
+}
+
+.default_date-disable {
+    color: #c7c7c7;
+}
+
+.default_choosed.default_date-disable {
+    color: #e2e2e2;
+    background-color: #c2afb6;
+}
+
+.default_prev-month-date,
+.default_next-month-date {
+    color: #e2e2e2;
+}
+
+.default_normal-date {
+    color: #88d2ac;
+}
+
+.default_todo-circle {
+    border-color: #88d2ac;
+}
+
+.default_todo-dot {
+    background-color: #e54d42;
+}
+
+.default_date-desc {
+    color: #c2c2c2;
+}
+
+.default_date-desc-lunar {
+    color: #e54d42;
+}
+
+.default_date-desc-disable {
+    color: #e2e2e2;
+}
+
+.default_festival {
+    color: #c2c2c2;
+}

+ 58 - 0
components/calendar/theme/theme-elegant.wxss

xqd
@@ -0,0 +1,58 @@
+.elegant_color,
+.elegant_weekend-color,
+.elegant_handle-color,
+.elegant_week-color {
+    color: #333;
+}
+
+.elegant_today {
+    color: #000;
+    background-color: #e1e7f5;
+}
+
+.elegant_choosed {
+    color: #000;
+    background-color: #e2e2e2;
+}
+
+.elegant_date-disable {
+    color: #c7c7c7;
+}
+
+.elegant_choosed.elegant_date-disable {
+    color: #999;
+    background-color: #ebebeb;
+}
+
+.elegant_prev-month-date,
+.elegant_next-month-date {
+    color: #e2e2e2;
+}
+
+.elegant_normal-date {
+    color: #777;
+}
+
+.elegant_todo-circle {
+    border-color: #161035;
+}
+
+.elegant_todo-dot {
+    background-color: #161035;
+}
+
+.elegant_date-desc {
+    color: #c2c2c2;
+}
+
+.elegant_date-desc-lunar {
+    color: #161035;
+}
+
+.elegant_date-desc-disable {
+    color: #e2e2e2;
+}
+
+.elegant_festival {
+    color: #c2c2c2;
+}

+ 285 - 0
components/calendar/utils/index.js

xqd
@@ -0,0 +1,285 @@
+import Logger from './logger'
+import WxData from './wxData'
+
+let systemInfo
+export function getSystemInfo() {
+  if (systemInfo) return systemInfo
+  systemInfo = wx.getSystemInfoSync()
+  return systemInfo
+}
+
+export function isIos() {
+  const sys = getSystemInfo()
+  return /iphone|ios/i.test(sys.platform)
+}
+
+class Gesture {
+  /**
+   * 左滑
+   * @param {object} e 事件对象
+   * @returns {boolean} 布尔值
+   */
+  isLeft(gesture = {}, touche = {}) {
+    const { startX, startY } = gesture
+    const deltaX = touche.clientX - startX
+    const deltaY = touche.clientY - startY
+    if (deltaX < -60 && deltaY < 20 && deltaY > -20) {
+      return true
+    } else {
+      return false
+    }
+  }
+  /**
+   * 右滑
+   * @param {object} e 事件对象
+   * @returns {boolean} 布尔值
+   */
+  isRight(gesture = {}, touche = {}) {
+    const { startX, startY } = gesture
+    const deltaX = touche.clientX - startX
+    const deltaY = touche.clientY - startY
+
+    if (deltaX > 60 && deltaY < 20 && deltaY > -20) {
+      return true
+    } else {
+      return false
+    }
+  }
+}
+
+class DateUtil {
+  newDate(year, month, date) {
+    let cur = `${+year}-${+month}-${+date}`
+    if (isIos()) {
+      cur = `${+year}/${+month}/${+date}`
+    }
+    return new Date(cur)
+  }
+  /**
+   * 计算指定日期时间戳
+   * @param {object} date
+   */
+  getTimeStamp(dateInfo) {
+    if (typeof dateInfo === 'string') {
+      dateInfo = this.transformDateRow2Dict(dateInfo)
+    }
+    if (Object.prototype.toString.call(dateInfo) !== '[object Object]') return
+    const dateUtil = new DateUtil()
+    return dateUtil
+      .newDate(dateInfo.year, dateInfo.month, dateInfo.date)
+      .getTime()
+  }
+  /**
+   * 计算指定月份共多少天
+   * @param {number} year 年份
+   * @param {number} month  月份
+   */
+  getDatesCountOfMonth(year, month) {
+    return new Date(Date.UTC(year, month, 0)).getUTCDate()
+  }
+  /**
+   * 计算指定月份第一天星期几
+   * @param {number} year 年份
+   * @param {number} month  月份
+   */
+  firstDayOfWeek(year, month) {
+    return new Date(Date.UTC(year, month - 1, 1)).getUTCDay()
+  }
+  /**
+   * 计算指定日期星期几
+   * @param {number} year 年份
+   * @param {number} month  月份
+   * @param {number} date 日期
+   */
+  getDayOfWeek(year, month, date) {
+    return new Date(Date.UTC(year, month - 1, date)).getUTCDay()
+  }
+  todayFMD() {
+    const _date = new Date()
+    const year = _date.getFullYear()
+    const month = _date.getMonth() + 1
+    const date = _date.getDate()
+    return {
+      year: +year,
+      month: +month,
+      date: +date
+    }
+  }
+  todayTimestamp() {
+    const { year, month, date } = this.todayFMD()
+    const timestamp = this.newDate(year, month, date).getTime()
+    return timestamp
+  }
+  toTimeStr(dateInfo = {}) {
+    return `${+dateInfo.year}-${+dateInfo.month}-${+dateInfo.date}`
+  }
+  transformDateRow2Dict(dateStr) {
+    if (typeof dateStr === 'string' && dateStr.includes('-')) {
+      const [year, month, date] = dateStr.split('-')
+      return this.tranformStr2NumOfDate({
+        year,
+        month,
+        date
+      })
+    }
+    return {}
+  }
+  tranformStr2NumOfDate(date = {}) {
+    const target = { ...date }
+    // 可能传入字符串
+    target.year = +target.year
+    target.month = +target.month
+    target.date = +target.date
+    return target
+  }
+  sortDatesByTime(dates = [], sortType) {
+    return dates.sort((a, b) => {
+      const at = this.getTimeStamp(a)
+      const bt = this.getTimeStamp(b)
+      if (at < bt && sortType !== 'desc') {
+        return -1
+      } else {
+        return 1
+      }
+    })
+  }
+  getPrevMonthInfo(date = {}) {
+    const prevMonthInfo =
+      Number(date.month) > 1
+        ? {
+            year: +date.year,
+            month: Number(date.month) - 1
+          }
+        : {
+            year: Number(date.year) - 1,
+            month: 12
+          }
+    return prevMonthInfo
+  }
+  getNextMonthInfo(date = {}) {
+    const nextMonthInfo =
+      Number(date.month) < 12
+        ? {
+            year: +date.year,
+            month: Number(date.month) + 1
+          }
+        : {
+            year: Number(date.year) + 1,
+            month: 1
+          }
+    return nextMonthInfo
+  }
+  getPrevYearInfo(date = {}) {
+    return {
+      year: Number(date.year) - 1,
+      month: +date.month
+    }
+  }
+  getNextYearInfo(date = {}) {
+    return {
+      year: Number(date.year) + 1,
+      month: +date.month
+    }
+  }
+  findDateIndexInArray(target, dates) {
+    return dates.findIndex(
+      item => dateUtil.toTimeStr(item) === dateUtil.toTimeStr(target)
+    )
+  }
+  calcDates(year, month) {
+    const datesCount = this.getDatesCountOfMonth(year, month)
+    const dates = []
+    const today = dateUtil.todayFMD()
+    for (let i = 1; i <= datesCount; i++) {
+      const week = dateUtil.getDayOfWeek(+year, +month, i)
+      const date = {
+        year: +year,
+        id: i - 1,
+        month: +month,
+        date: i,
+        week,
+        isToday:
+          +today.year === +year && +today.month === +month && i === +today.date
+      }
+      dates.push(date)
+    }
+    return dates
+  }
+  /**
+   * 日期数组根据日期去重
+   * @param {array} array 数组
+   */
+  uniqueArrayByDate(array = []) {
+    let uniqueObject = {}
+    let uniqueArray = []
+    array.forEach(item => {
+      uniqueObject[dateUtil.toTimeStr(item)] = item
+    })
+    for (let i in uniqueObject) {
+      uniqueArray.push(uniqueObject[i])
+    }
+    return uniqueArray
+  }
+  /**
+   * 筛选指定年月日期
+   * @param {object} target 指定年月
+   * @param {array} dates 待筛选日期
+   */
+  filterDatesByYM(target, dates) {
+    if (target) {
+      const { year, month } = target
+      const _dates = dates.filter(
+        item => +item.year === +year && +item.month === +month
+      )
+      return _dates
+    }
+    return dates
+  }
+  getWeekHeader(firstDayOfWeek) {
+    let weeksCh = ['日', '一', '二', '三', '四', '五', '六']
+    if (firstDayOfWeek === 'Mon') {
+      weeksCh = ['一', '二', '三', '四', '五', '六', '日']
+    }
+    return weeksCh
+  }
+}
+
+/**
+ * 获取当前页面实例
+ */
+export function getCurrentPage() {
+  const pages = getCurrentPages() || []
+  const last = pages.length - 1
+  return pages[last] || {}
+}
+
+export function getComponentById(componentId) {
+  const logger = new Logger()
+  let page = getCurrentPage() || {}
+  if (page.selectComponent && typeof page.selectComponent === 'function') {
+    if (componentId) {
+      return page.selectComponent(componentId)
+    } else {
+      logger.warn('请传入组件ID')
+    }
+  } else {
+    logger.warn('该基础库暂不支持多个小程序日历组件')
+  }
+}
+
+export const logger = new Logger()
+export const calendarGesture = new Gesture()
+export const dateUtil = new DateUtil()
+export const getCalendarData = (key, component) =>
+  new WxData(component).getData(key)
+export const setCalendarData = (data, component) =>
+  new WxData(component).setData(data)
+export const getCalendarConfig = component =>
+  getCalendarData('config', component)
+export const setCalendarConfig = (config, component) =>
+  setCalendarData(
+    {
+      config
+    },
+    component
+  )

+ 23 - 0
components/calendar/utils/logger.js

xqd
@@ -0,0 +1,23 @@
+export default class Logger {
+  info(msg) {
+    console.log(
+      '%cInfo: %c' + msg,
+      'color:#FF0080;font-weight:bold',
+      'color: #FF509B'
+    )
+  }
+  warn(msg) {
+    console.log(
+      '%cWarn: %c' + msg,
+      'color:#FF6600;font-weight:bold',
+      'color: #FF9933'
+    )
+  }
+  tips(msg) {
+    console.log(
+      '%cTips: %c' + msg,
+      'color:#00B200;font-weight:bold',
+      'color: #00CC33'
+    )
+  }
+}

+ 30 - 0
components/calendar/utils/wxData.js

xqd
@@ -0,0 +1,30 @@
+class WxData {
+  constructor(component) {
+    this.Component = component
+  }
+  getData(key) {
+    const data = this.Component.data
+    if (!key) return data
+    if (key.includes('.')) {
+      let keys = key.split('.')
+      const tmp = keys.reduce((prev, next) => {
+        return prev[next]
+      }, data)
+      return tmp
+    } else {
+      return this.Component.data[key]
+    }
+  }
+  setData(data) {
+    return new Promise((resolve, reject) => {
+      if (!data) return reject('no data to set')
+      if (typeof data === 'object') {
+        this.Component.setData(data, () => {
+          resolve(data)
+        })
+      }
+    })
+  }
+}
+
+export default WxData

+ 5 - 1
components/common/common.wxml

xqd
@@ -1 +1,5 @@
-<view class='common'><include src='/components/_toast/_toast'></include><include src='./get-coupon'></include><include src='./navbar'></include></view>
+<view class='common'>
+	<include src='/components/_toast/_toast1'></include>
+	<include src='./get-coupon'></include>
+	<include src='./navbar'></include>
+</view>

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
components/goods/goods_buy.js


Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
components/goods/goods_buy.wxml


+ 31 - 1
components/goods/goods_recommend.js

xqd
@@ -1 +1,31 @@
-module.exports={currentPage:null,init:function(o){var t=this;void 0===(t.currentPage=o).goods_recommend&&(o.goods_recommend=function(o){t.goods_recommend(o)})},goods_recommend:function(a){var e=this.currentPage;e.setData({is_loading:!0});var d=e.data.page||2;getApp().request({url:getApp().api.default.goods_recommend,data:{goods_id:a.goods_id,page:d},success:function(o){if(0==o.code){if(a.reload)var t=o.data.list;if(a.loadmore)t=e.data.goods_list.concat(o.data.list);e.data.drop=!0,e.setData({goods_list:t}),e.setData({page:d+1})}},complete:function(){e.setData({is_loading:!1})}})}};
+module.exports = {
+  currentPage: null,
+  init: function (o) {
+    var t = this;
+    void 0 === (t.currentPage = o).goods_recommend &&
+      (o.goods_recommend = function (o) {
+        t.goods_recommend(o);
+      });
+  },
+  goods_recommend: function (a) {
+    var e = this.currentPage;
+    e.setData({ is_loading: !0 });
+    var d = e.data.page || 2;
+    getApp().request({
+      url: getApp().api.default.goods_recommend,
+      data: { goods_id: a.goods_id, page: d },
+      success: function (o) {
+        if (0 == o.code) {
+          if (a.reload) var t = o.data.list;
+          if (a.loadmore) t = e.data.goods_list.concat(o.data.list);
+          (e.data.drop = !0),
+            e.setData({ goods_list: t }),
+            e.setData({ page: d + 1 });
+        }
+      },
+      complete: function () {
+        e.setData({ is_loading: !1 });
+      },
+    });
+  },
+};

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
components/quick-navigation/quick-navigation.wxml


+ 11 - 1
core/api.js

xqd xqd xqd
@@ -72,7 +72,11 @@ var api = {
     location: _api_root + "order/location",
     refund_send: _api_root + "order/refund-send",
     new_submit_preview: _api_root + "order/new-submit-preview",
-    new_submit: _api_root + "order/new-submit"
+    new_submit: _api_root + "order/new-submit",
+    get_goods_qrcode: _api_root + "order/get-goods-qrcode",
+    clerk_goods: _api_root + "order/clerk-goods",
+    offline_goods_detail: _api_root + "order/offline-goods-detail",
+    clerk_goods_detail: _api_root + "order/clerk-goods-detail"
   },
   everyday_coupon:{
     user_info: _api_root + "everyday-coupon/user-info",
@@ -235,6 +239,9 @@ var api = {
     record: _api_root + "recharge/record",
     detail: _api_root + "recharge/detail"
   },
+  balance: {
+	detail: _api_root + "user/balance-detail"
+  },
   mch: {
     apply: _api_root + "mch/index/apply",
     apply_submit: _api_root + "mch/index/apply-submit",
@@ -333,6 +340,9 @@ var api = {
   diy: {
     detail: _api_root + "diy/diy-template/detail"
   },
+  yuyue: {
+    submit: _api_root + "order/car-appoint"
+  },
   step: {
     index: _api_root + "step/default/index",
     setting: _api_root + "step/default/setting",

+ 14 - 1
core/config.js

xqd
@@ -1 +1,14 @@
-module.exports=function(e){getApp().api;var t=getApp().core,g=getApp();if(e&&"function"==typeof e){var n=t.getStorageSync(g.const.STORE_CONFIG);n&&e(n),g.config?n=g.config:(getApp().trigger.add(getApp().trigger.events.callConfig,"call",function(t){e(t)}),getApp().configReadyCall&&"function"==typeof getApp().configReadyCall||(getApp().configReadyCall=function(t){getApp().trigger.run(getApp().trigger.events.callConfig,function(){},t)}))}};
+module.exports = function(e) {
+	getApp().api;
+	var t = getApp().core,
+		g = getApp();
+	if (e && "function" == typeof e) {
+		var n = t.getStorageSync(g.const.STORE_CONFIG);
+		n && e(n), g.config ? n = g.config : (getApp().trigger.add(getApp().trigger.events.callConfig, "call", function(t) {
+			e(t)
+		}), getApp().configReadyCall && "function" == typeof getApp().configReadyCall || (getApp().configReadyCall =
+			function(t) {
+				getApp().trigger.run(getApp().trigger.events.callConfig, function() {}, t)
+			}))
+	}
+};

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
core/const.js


+ 4 - 1
core/getUser.js

xqd
@@ -1 +1,4 @@
-module.exports=function(){var t=this.core.getStorageSync(this.const.USER_INFO);return t||""};
+module.exports = function() {
+	var t = this.core.getStorageSync(this.const.USER_INFO);
+	return t || ""
+};

+ 11 - 1
core/login.js

xqd
@@ -1 +1,11 @@
-module.exports=function(e){var t=this,r=t.page.currentPage;t.page.currentPageOptions;r&&"pages/index/index"===r.route&&"my"===t.platform||this.request({url:this.api.share.index,success:function(e){0==e.code&&(t.page.setPhone(),t.trigger.run(t.trigger.events.login))}})};
+module.exports = function (e) {
+  var t = this,
+    r = t.page.currentPage;
+  t.page.currentPageOptions;
+  r && "pages/index/index" === r.route && "my" === t.platform || this.request({
+    url: this.api.share.index,
+    success: function (e) {
+      0 == e.code && (t.page.setPhone(), t.trigger.run(t.trigger.events.login))
+    }
+  })
+};

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
core/order-pay.js


+ 8 - 1
core/page.js

xqd xqd
@@ -59,7 +59,11 @@ module.exports = {
       o.relevanceError(e)
     }), void 0 === t.saveQrcode && (t.saveQrcode = function(e) {
       o.saveQrcode(e)
-    })
+    }), void 0 === t.setUserInfoShowFalse && (t.setUserInfoShowFalse = function(e) {
+      o.setUserInfoShowFalse();
+    }), void 0 === t.cancelLogin && (t.cancelLogin = function(e) {
+        o.cancelLogin();
+    });
   },
   onReady: function(e) {
     this.currentPage = e
@@ -614,5 +618,8 @@ module.exports = {
       content: "当前版本过低,无法使用该功能,请升级到最新版本后重试。",
       showCancel: !1
     })
+  },
+  cancelLogin: function() {
+      this.setUserInfoShowFalse();
   }
 };

+ 72 - 1
core/request.js

xqd
@@ -1 +1,72 @@
-module.exports=function(a){a.data||(a.data={});var o=this.core,e=this.core.getStorageSync(this.const.ACCESS_TOKEN),t=this.core.getStorageSync(this.const.FORM_ID_LIST);e&&(a.data.access_token=e),a.data._version=this._version,a.data._platform=this.platform,!this.is_login&&this.page.currentPage&&(this.is_login=!0,this.login({}));var s=this;t&&1<=t.length&&s.is_form_id_request&&(s.is_form_id_request=!1,s.request({url:s.api.default.form_id,method:"POST",data:{formIdList:JSON.stringify(t)},success:function(e){s.core.removeStorageSync(s.const.FORM_ID_LIST)},complete:function(){s.is_form_id_request=!0}})),o.request({url:a.url,header:a.header||{"content-type":"application/x-www-form-urlencoded"},data:a.data||{},method:a.method||"GET",dataType:a.dataType||"json",success:function(e){-1==e.data.code?(s.core.hideLoading(),s.page.setUserInfoShow(),s.is_login=!1):-2==e.data.code?o.redirectTo({url:"/pages/store-disabled/store-disabled"}):a.success&&a.success(e.data)},fail:function(e){if(console.warn("--- request fail >>>"),console.warn("--- "+a.url+" ---"),console.warn(e),console.warn("<<< request fail ---"),a&&a.noHandlerFail)"function"==typeof a.fail&&a.fail(e.data);else{var t=getApp();t.is_on_launch?(t.is_on_launch=!1,o.showModal({title:"网络请求出错",content:e.errMsg||"",showCancel:!1,success:function(e){e.confirm&&a.fail&&a.fail(e)}})):(o.showToast({title:e.errMsg,image:"/images/icon-warning.png"}),a.fail&&a.fail(e))}},complete:function(t){if(200!=t.statusCode&&t.data&&t.data.code&&500==t.data.code){var e=t.data.data.message;o.showModal({title:"系统错误",content:e+";\r\n请将错误内容复制发送给我们,以便进行问题追踪。",cancelText:"关闭",confirmText:"复制",success:function(e){e.confirm&&o.setClipboardData({data:JSON.stringify({data:t.data.data,object:a})})}})}a.complete&&a.complete(t)}})};
+module.exports = function(a) {
+	a.data || (a.data = {});
+	var o = this.core,
+		e = this.core.getStorageSync(this.const.ACCESS_TOKEN),
+		t = this.core.getStorageSync(this.const.FORM_ID_LIST);
+	e && (a.data.access_token = e), a.data._version = this._version, a.data._platform = this.platform;
+	var s = this;
+	t && 1 <= t.length && s.is_form_id_request && (s.is_form_id_request = !1, s.request({
+		url: s.api.default.form_id,
+		method: "POST",
+		data: {
+			formIdList: JSON.stringify(t)
+		},
+		success: function(e) {
+			s.core.removeStorageSync(s.const.FORM_ID_LIST)
+		},
+		complete: function() {
+			s.is_form_id_request = !0
+		}
+	})), o.request({
+		url: a.url,
+		header: a.header || {
+			"content-type": "application/x-www-form-urlencoded"
+		},
+		data: a.data || {},
+		method: a.method || "GET",
+		dataType: a.dataType || "json",
+		success: function(e) {
+			-1 == e.data.code ? (s.core.hideLoading(), s.page.setUserInfoShow(), s.is_login = !1) : -2 == e.data.code ? o.redirectTo({
+				url: "/pages/store-disabled/store-disabled"
+			}) : a.success && a.success(e.data)
+		},
+		fail: function(e) {
+			if (console.warn("--- request fail >>>"), console.warn("--- " + a.url + " ---"), console.warn(e), console.warn(
+					"<<< request fail ---"), a && a.noHandlerFail) "function" == typeof a.fail && a.fail(e.data);
+			else {
+				var t = getApp();
+				t.is_on_launch ? (t.is_on_launch = !1, o.showModal({
+					title: "网络请求出错",
+					content: e.errMsg || "",
+					showCancel: !1,
+					success: function(e) {
+						e.confirm && a.fail && a.fail(e)
+					}
+				})) : (o.showToast({
+					title: e.errMsg,
+					image: "/images/icon-warning.png"
+				}), a.fail && a.fail(e))
+			}
+		},
+		complete: function(t) {
+			if (200 != t.statusCode && t.data && t.data.code && 500 == t.data.code) {
+				var e = t.data.data.message;
+				o.showModal({
+					title: "系统错误",
+					content: e + ";\r\n请将错误内容复制发送给我们,以便进行问题追踪。",
+					cancelText: "关闭",
+					confirmText: "复制",
+					success: function(e) {
+						e.confirm && o.setClipboardData({
+							data: JSON.stringify({
+								data: t.data.data,
+								object: a
+							})
+						})
+					}
+				})
+			}
+			a.complete && a.complete(t)
+		}
+	})
+};

BIN
images/icon-login-index.png


BIN
images/icon-login-index2.png


+ 42 - 0
pages/balance/balance-detail.js

xqd
@@ -0,0 +1,42 @@
+Page({
+	data: {
+		balanceDetail: []
+	},
+	onLoad: function(e) {
+		getApp().page.onLoad(this, e);
+		var t = this;
+		t.setData(e),
+		getApp().core.showLoading({
+			title: "加载中"
+		}), 
+		getApp().request({
+			url: getApp().api.balance.detail,
+			method: "GET",
+			data: {
+				order_type: e.order_type,
+				id: e.id
+			},
+			success: function(e) {
+				getApp().core.hideLoading(), 
+				0 == e.code ? t.setData({
+					balanceDetail: e.data
+				}) : getApp().core.showModal({
+					title: "提示",
+					content: e.msg
+				})
+			}
+		})
+	},
+	onReady: function() {
+		getApp().page.onReady(this)
+	},
+	onShow: function() {
+		getApp().page.onShow(this)
+	},
+	onHide: function() {
+		getApp().page.onHide(this)
+	},
+	onUnload: function() {
+		getApp().page.onUnload(this)
+	}
+});

+ 3 - 0
pages/balance/balance-detail.json

xqd
@@ -0,0 +1,3 @@
+{
+    "navigationBarTitleText":"余额明细"
+}

+ 30 - 0
pages/balance/balance-detail.wxml

xqd
@@ -0,0 +1,30 @@
+<view class='page'>
+	<block wx:for='{{balanceDetail.user_subsidies}}' wx:for-item='item' wx:for-index='index' wx:key='{{item.id}}'>
+	  <div class="hm-balance-card">
+		<div class="box">
+		  <image class="layer" src="http://t29.9026.com/core/web/statics/images/recharge/icon-balance-bg.png" />
+		  <div class="hd">
+			<text class="info">{{ item.name }}</text>
+			<div class="wrap">
+			  <div class="empty" />
+			  <image class="zhanghaoguanli" :src="item.zhanghaoguanli" />
+			</div>
+		  </div>
+		  <text class="bd">{{ item.total_balance }}</text>
+		  <text class="main">余额:{{ item.balance }}</text>
+		  <div class="ft">
+			<div class="block">
+			  <text class="date">发放日期</text>
+			  <text class="word">{{ item.created_at }}</text>
+			</div>
+			<!-- <div class="group">
+			  <text class="cvv">结束日期</text>
+			  <text class="num">{{ item.updated_at }}</text>
+			</div> -->
+			<image class="largeIcon" :src="item.largeIcon" />
+		  </div>
+		</div>
+	  </div>
+	</block>
+	
+</view>

+ 213 - 0
pages/balance/balance-detail.wxss

xqd
@@ -0,0 +1,213 @@
+.bg { position: absolute; top: 0; left: 0; width: 100%; height: 324rpx; z-index: 0; }
+.info-img { width: 36rpx; height: 36rpx; margin-right: 20rpx; }
+.info-2 { margin: 30rpx 0; font-size: 30pt; line-height: 1; }
+.info-btn { width: 168rpx; height: 56rpx; font-size: 13pt; border-radius: 28rpx; border: 1rpx solid #fff; }
+.ad { width: 100%; height: 180rpx; margin-bottom: 20rpx; }
+.ad wx-image { width: 100%; height: 100%; }
+.record { background-color: #fff; width: 100%; }
+.record-time { width: 100%; height: 80rpx; color: #353535; }
+.record-img { width: 12rpx; height: 20rpx; }
+.record-list { width: 100%; background-color: #fff; }
+.record-one { width: 100%; height: 140rpx; border-top: 1rpx solid #e2e2e2; padding: 0 24rpx; }
+.record-1 { color: #353535; margin-top: 30rpx; margin-bottom: 15rpx; }
+.record-2 { color: #666; font-size: 9pt; }
+.record-3 { font-size: 13pt; color: #ff4544; }
+.record-4 { font-size: 13pt; color: #3fc24c; }
+.modal-h { position: fixed; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 1000; }
+.body-h { padding: 50rpx; background-color: #fff; width: 600rpx; border-radius: 10rpx; }
+.btn-h { margin-top: 64rpx; width: 100%; height: 80rpx; background-color: #ff4544; border-radius: 10rpx; color: #fff; }
+.hm-balance-card {
+  display: flex;
+  align-items: center;
+  flex-direction: row;
+  justify-content: center;
+  width: 750rpx;
+  height: 400rpx;
+}
+
+.box {
+  display: flex;
+  position: relative;
+  align-items: flex-start;
+  flex-direction: column;
+  width: 719.91rpx;
+  height: 380rpx;
+  border-radius: 10rpx;
+}
+
+.layer {
+  position: absolute;
+  top: 0;
+  align-self: center;
+  width: 719.91rpx;
+  height: 350rpx;
+  overflow: hidden;
+  border-radius: 10rpx;
+}
+
+.hd {
+  display: flex;
+  position: relative;
+  align-items: flex-end;
+  flex-direction: row;
+  justify-content: space-between;
+  margin-top: 32.23rpx;
+  margin-left: 53.72rpx;
+  width: 633.95rpx;
+  height: 51.58rpx;
+}
+
+.info {
+	max-width: 569.48rpx;
+	height: 35rpx;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	line-height: 35rpx;
+	white-space: nowrap;
+	color: rgba(19, 19, 21, 0.5);
+	font-size: 29rpx;
+	font-weight: 400;
+}
+
+.wrap {
+  display: flex;
+  position: relative;
+  align-items: center;
+  flex-direction: row;
+  justify-content: center;
+  background-color: rgba(28, 143, 248, 0);
+  width: 51.58rpx;
+  height: 51.58rpx;
+}
+
+.empty {
+  position: absolute;
+  top: 20.42rpx;
+  left: 19.34rpx;
+  border-width: 2px;
+  border-style: solid;
+  border-radius: 9.67rpx;
+  border-color: rgba(255, 255, 255, 1);
+  width: 12.89rpx;
+  height: 12.89rpx;
+}
+
+.zhanghaoguanli {
+  position: relative;
+  width: 37.61rpx;
+  height: 37.61rpx;
+}
+
+.bd {
+  position: relative;
+  opacity: 1;
+  margin-top: 4.3rpx;
+  margin-left: 53.72rpx;
+  max-width: 653.3rpx;
+  height: 75.21rpx;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  line-height: 75.21rpx;
+  white-space: nowrap;
+  color: #ffffff;
+  font-family: MicrosoftYaHei, Microsoft YaHei;
+  font-size: 69.84rpx;
+  font-weight: normal;
+}
+
+.main {
+  position: relative;
+  opacity: 1;
+  /* margin-top: 133.24rpx; */
+  margin-left: 53.72rpx;
+  max-width: 653.3rpx;
+  height: 36.53rpx;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  line-height: 36.53rpx;
+  white-space: pre;
+  color: #ffffff;
+  font-family: MicrosoftYaHei, Microsoft YaHei;
+  font-size: 32.23rpx;
+  font-weight: normal;
+}
+
+.ft {
+  display: flex;
+  position: relative;
+  align-items: flex-start;
+  flex-direction: row;
+  margin-top: 35.46rpx;
+  margin-left: 53.72rpx;
+  height: 66.62rpx;
+}
+
+.block {
+  display: flex;
+  align-items: flex-start;
+  flex-direction: column;
+  margin-right: 83.81rpx;
+  height: 66.62rpx;
+}
+
+.date {
+  position: relative;
+  /* max-width: 68.77rpx; */
+  height: 25.79rpx;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  line-height: 25.79rpx;
+  white-space: nowrap;
+  color: rgba(19, 19, 21, 0.6);
+  font-family: MicrosoftYaHei, Microsoft YaHei;
+  font-size: 21.49rpx;
+  font-weight: normal;
+}
+
+.word {
+  position: relative;
+  opacity: 1;
+  margin-top: 4.3rpx;
+  line-height: 36.53rpx;
+  white-space: nowrap;
+  color: #ffffff;
+  font-family: MicrosoftYaHei, Microsoft YaHei;
+  font-size: 26.23rpx;
+  font-weight: normal;
+}
+
+.group {
+  display: flex;
+  align-items: flex-start;
+  flex-direction: column;
+  margin-right: 340.62rpx;
+  height: 66.62rpx;
+}
+
+.cvv {
+  position: relative;
+  line-height: 25.79rpx;
+  white-space: nowrap;
+  color: rgba(19, 19, 21, 0.6);
+  font-family: MicrosoftYaHei, Microsoft YaHei;
+  font-size: 21.49rpx;
+  font-weight: normal;
+}
+
+.num {
+  position: relative;
+  opacity: 1;
+  margin-top: 4.3rpx;
+  line-height: 36.53rpx;
+  white-space: nowrap;
+  color: #ffffff;
+  font-family: MicrosoftYaHei, Microsoft YaHei;
+  font-size: 26.23rpx;
+  font-weight: normal;
+}
+
+.largeIcon {
+  margin-top: 18.27rpx;
+  width: 73.07rpx;
+  height: 42.98rpx;
+}

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
pages/balance/balance.wxml


+ 2 - 1
pages/balance/balance.wxss

xqd
@@ -16,4 +16,5 @@
 .record-4 { font-size: 13pt; color: #3fc24c; }
 .modal-h { position: fixed; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 1000; }
 .body-h { padding: 50rpx; background-color: #fff; width: 600rpx; border-radius: 10rpx; }
-.btn-h { margin-top: 64rpx; width: 100%; height: 80rpx; background-color: #ff4544; border-radius: 10rpx; color: #fff; }
+.btn-h { margin-top: 64rpx; width: 100%; height: 80rpx; background-color: #ff4544; border-radius: 10rpx; color: #fff; }.flex-x-space-around{ display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-pack: center; -webkit-justify-content: center; -ms-flex-pack: center; justify-content: space-around; }
+.margin-left{ margin-left: 30rpx; }

+ 38 - 1
pages/balance/detail.js

xqd
@@ -1 +1,38 @@
-var is_more=!1;Page({data:{},onLoad:function(e){getApp().page.onLoad(this,e);var t=this;t.setData(e),getApp().core.showLoading({title:"加载中"}),getApp().request({url:getApp().api.recharge.detail,method:"GET",data:{order_type:e.order_type,id:e.id},success:function(e){getApp().core.hideLoading(),0==e.code?t.setData({list:e.data}):getApp().core.showModal({title:"提示",content:e.msg})}})},onReady:function(){getApp().page.onReady(this)},onShow:function(){getApp().page.onShow(this)},onHide:function(){getApp().page.onHide(this)},onUnload:function(){getApp().page.onUnload(this)}}); 
+var is_more = !1;
+Page({
+	data: {},
+	onLoad: function(e) {
+		getApp().page.onLoad(this, e);
+		var t = this;
+		t.setData(e), getApp().core.showLoading({
+			title: "加载中"
+		}), getApp().request({
+			url: getApp().api.recharge.detail,
+			method: "GET",
+			data: {
+				order_type: e.order_type,
+				id: e.id
+			},
+			success: function(e) {
+				getApp().core.hideLoading(), 0 == e.code ? t.setData({
+					list: e.data
+				}) : getApp().core.showModal({
+					title: "提示",
+					content: e.msg
+				})
+			}
+		})
+	},
+	onReady: function() {
+		getApp().page.onReady(this)
+	},
+	onShow: function() {
+		getApp().page.onShow(this)
+	},
+	onHide: function() {
+		getApp().page.onHide(this)
+	},
+	onUnload: function() {
+		getApp().page.onUnload(this)
+	}
+});

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
pages/book/submit/submit.js


+ 167 - 0
pages/check-submit/check-submit.js

xqd
@@ -0,0 +1,167 @@
+// pages/check-submit/check-submit.js
+Page({
+  data: {
+    mch_list: [],
+    car_appoint_id:''
+  },
+  onLoad: function (options) {
+    this.newSubmitPreview(options.data)
+    this.setData({
+      phone: options.phone
+    })
+  },
+  newSubmitPreview: function(t){
+    let data = JSON.parse(decodeURIComponent(t))
+    console.log('预约接口数据',data)
+    this.setData({
+      car_appoint_id: data.car_appoint_id
+
+    })
+    // 最终数据
+    let o = {
+    	mch_list:[]
+    }
+    // mch数据
+    let mch = {
+    	goods_list:[]
+    }
+    // good_list数据
+    let good_list = {
+    	attr:[]
+    }
+    // atrrId数据
+    let attr = JSON.parse(data.goods.attr)
+    let attr_id = attr[0].attr_list[0].attr_id
+    let attr_group_id = attr[0].attr_list[0].attr_group_id
+
+    // this.data.car_appoint_id  = data.car_appoint_id
+    good_list.goods_id = data.goods.id
+    good_list.num = 1
+    good_list.attr.push({
+    	attr_id:attr_id,
+    	attr_group_id:attr_group_id
+    })
+
+    mch.mch_id = data.goods.mch_id
+    mch.goods_list.push(good_list)
+    console.log(mch,'mch')
+
+    o.mch_list = JSON.stringify([mch])
+    let that = this
+    getApp().request({
+      url: getApp().api.order.new_submit_preview,
+      method: "POST",
+      data: o,
+      success: function (res) {
+        console.log(res,'下单')
+        if(res.code == 0){
+          res.data.mch_list[0].show = false
+          res.data.mch_list[0].show_length = 0
+          res.data.mch_list[0].offline = 0
+          that.setData({
+            mch_list: res.data.mch_list
+          })
+        }else{
+          wx.showToast({
+            icon: 'none',
+            title: res.msg,
+          })
+          setTimeout(()=>{
+            wx.navigateBack()
+          },2000)
+        }
+      }
+    })
+  },
+  pay: function(){
+    let o = {
+      mch_list:[]
+    }
+    o.mch_list = JSON.stringify(this.data.mch_list)
+    o.car_appoint_id = this.data.car_appoint_id
+    o.payment = 3
+    o.phone = this.data.phone
+    o.formId = undefined
+    getApp().request({
+      url: getApp().api.order.new_submit,
+      method: "POST",
+      data: o,
+      success: function (res) {
+        console.log(res,'下单sssss')
+        getApp().request({
+          url: getApp().api.order.pay_data,
+          data: {
+            order_id: res.data.order_id,
+            pay_type: "WECHAT_PAY"
+          },
+          complete: function () {
+            getApp().core.hideLoading()
+          },
+          success: function (t) {
+            0 == t.code && getApp().core.requestPayment({
+              _res: t,
+              timeStamp: t.data.timeStamp,
+              nonceStr: t.data.nonceStr,
+              package: t.data.package,
+              signType: t.data.signType,
+              paySign: t.data.paySign,
+              success: function (t) {},
+              fail: function (t) {},
+              complete: function (t) {
+                "requestPayment:fail" != t.errMsg && "requestPayment:fail cancel" != t.errMsg ? getApp().core.redirectTo({
+                  url: "/pages/order/order?status=2"
+                }) : getApp().core.showModal({
+                  title: "提示",
+                  content: "订单尚未支付",
+                  showCancel: !1,
+                  confirmText: "确认",
+                  success: function (t) {
+                    t.confirm && getApp().core.redirectTo({
+                      url: "/pages/order/order?status=0"
+                    })
+                  }
+                })
+              }
+            }), 1 == t.code && getApp().core.showToast({
+              title: t.msg,
+              image: "/images/icon-warning.png"
+            })
+          }
+        })
+      //   getApp().request({
+      //     url: getApp().api.order.pay_data,
+      //     data: {
+      //       order_id: res.data.order_id,
+      //       pay_type: "WECHAT_PAY"
+      //     },
+      //     success: function (e) {
+      //       0 == e.code ? (getApp().core.hideLoading(), 
+      //       getApp().core.requestPayment({
+      //         _res: e,
+      //         timeStamp: e.data.timeStamp,
+      //         nonceStr: e.data.nonceStr,
+      //         package: e.data.package,
+      //         signType: e.data.signType,
+      //         paySign: e.data.paySign,
+      //         complete: function (e) {
+      //           "requestPayment:fail" != e.errMsg && "requestPayment:fail cancel" != e.errMsg ? "requestPayment:ok" == e.errMsg && getApp().core.redirectTo({
+      //             url: "/pages/integral-mall/order/order?status=1"
+      //           }) : getApp().core.showModal({
+      //             title: "提示",
+      //             content: "订单尚未支付",
+      //             showCancel: !1,
+      //             confirmText: "确认"
+      //           })
+      //         }
+      //       })) : (getApp().core.hideLoading(), getApp().core.showModal({
+      //         title: "提示",
+      //         content: e.msg,
+      //         showCancel: !1,
+      //         confirmText: "确认"
+      //       }))
+      //     }
+      //   })
+      }
+    })
+  },
+})

+ 3 - 0
pages/check-submit/check-submit.json

xqd
@@ -0,0 +1,3 @@
+{
+  "navigationBarTitleText": "预约成功"
+}

+ 16 - 0
pages/check-submit/check-submit.wxml

xqd
@@ -0,0 +1,16 @@
+<!--pages/check-submit/check-submit.wxml-->
+<view class="page">
+	<view class="content">
+		<image src="http://dm.dhcarlife.com/core//image/store_21320/8ecac02530e94ffc443743c929b5ada57cae223c.png" mode='widthFix'></image>
+	</view>
+	<view class="content">
+		<image src="http://dm.dhcarlife.com/core//image/store_21320/2cce22aae597162a006fc764a88ce3087f293855.png" mode='widthFix'></image>
+	</view>
+	<view class="" style="margin-top:10px">
+		<image src="http://dm.dhcarlife.com/core//image/store_21320/f32bed22e55e7945d94414e359f92405161613e8.png" mode='widthFix'></image>
+		<view class="title">预约成功</view>
+	</view>
+	<view class="zfbtn-content">
+		<button class="zfbtn" bindtap="pay">立即支付</button>
+	</view>
+</view>

+ 38 - 0
pages/check-submit/check-submit.wxss

xqd
@@ -0,0 +1,38 @@
+/* pages/check-submit/check-submit.wxss */
+.page{
+  width: 100%;
+  height: 100%;
+  background-color: #fff;
+  padding: 15px 15px 0 15px;
+}
+image{
+  width: 100%;
+  display: block;
+  overflow: hidden;
+}
+.content{
+  width: 100%;
+  margin-top: 10px;
+  box-shadow: 6rpx 6rpx 8rpx rgba(26, 26, 26, 0.2);
+  border-radius: 5px;
+}
+.title{
+  color: #FFB228;
+  font-size: 32rpx;
+  text-align: center;
+}
+.zfbtn-content{
+  margin-top: 30px;
+  text-align: center;
+}
+.zfbtn{
+  background: #FFBF43;
+  color: #fff;
+  border: none;
+  font-size: 36rpx;
+  width: 235rpx;
+  height: 30px;
+  line-height: 30px;
+  border-radius: 70rpx;
+  padding: 0;
+}

+ 244 - 0
pages/check/check.js

xqd
@@ -0,0 +1,244 @@
+
+import todo from '../../components/calendar/plugins/todo'
+import selectable from '../../components/calendar/plugins/selectable'
+import solarLunar from '../../components/calendar/plugins/solarLunar/index'
+import timeRange from '../../components/calendar/plugins/time-range'
+import week from '../../components/calendar/plugins/week'
+import holidays from '../../components/calendar/plugins/holidays/index'
+import plugin from '../../components/calendar/plugins/index'
+
+plugin
+  .use(todo)
+  .use(solarLunar)
+  .use(selectable)
+  .use(week)
+  .use(timeRange)
+  .use(holidays)
+Page({
+	data: {
+		name: '',
+		phone: '',
+		license_number: '',
+		car_model: '',
+		appoint_date: '',
+		appoint_time: '',
+		exchange_code:'',
+		car_appoint_id:'',
+		user_info_show: false,
+		calendarConfig: {
+			theme: 'elegant',
+			disableMode: {
+        // 禁用某一天之前/之后的所有日期
+				type: 'before', // [‘before’, 'after']
+      },
+		},
+	},
+	onLoad: function(t) {
+		this.loadData()
+		console.log(t,66666)
+    getApp().page.onLoad(this, t), t.page_id || (t.page_id = -1), this.setData({
+      options: t
+		});
+	},
+	onShow: function(){
+		var e = this;
+		getApp().getConfig(function(t) {
+      var a = t.store;
+      a && a.name && -1 == e.data.options.page_id && getApp().core.setNavigationBarTitle({
+        title: a.name
+			})
+    })
+	},
+	// 填写姓名
+	bindName:function(e){
+		console.log(e.detail.value)
+		this.setData({
+			name: e.detail.value
+		})
+		console.log('预约')
+	},
+	// 填写电话
+	bindPhone:function(e){
+		console.log(e.detail.value)
+		this.setData({
+			phone: e.detail.value
+		})
+		console.log('预约')
+	},
+	// 填写车牌号
+	bindLicense:function(e){
+		console.log(e.detail.value)
+		this.setData({
+			license_number: e.detail.value
+		})
+		console.log('预约')
+	},
+	// 车辆型号
+	bindModel:function(e){
+		console.log(e.detail.value)
+		this.setData({
+			car_model: e.detail.value
+		})
+		console.log('预约')
+	},
+	// 兑换码
+	bindRedemptionCode:function(e){
+		this.setData({
+			exchange_code: e.detail.value
+		})
+	},
+	// 选中
+  afterTapDate(e) {
+		console.log('afterTapDate', e.detail)
+		if(e.detail.week == 0){
+			console.log('week为周日',e.detail.week)
+			wx.showModal({
+				title: e.detail.date + '日为周末, 周末闭店休息',
+				showCancel: false
+			})
+			this.setData({
+				appoint_date: ''
+			})
+		}else{
+			this.setData({
+				appoint_date: `${e.detail.year}-${e.detail.month}-${e.detail.date}`
+			})
+		}
+	},
+	// 确定预约
+	onSubmit:function(){
+		if(this.data.name == ''){
+			wx.showToast({
+				icon: 'none',
+				title: '请填写预约人姓名',
+			})
+			return
+		}
+		if(this.data.phone == ''){
+			wx.showToast({
+				icon: 'none',
+				title: '请填写预约人电话',
+			})
+			return
+		}
+		if(this.data.license_number == ''){
+			wx.showToast({
+				icon: 'none',
+				title: '请填写预约人车牌号',
+			})
+			return
+		}
+		if(this.data.car_model == ''){
+			wx.showToast({
+				icon: 'none',
+				title: '请填写预约人车辆型号',
+			})
+			return
+		}
+		if(this.data.appoint_time == ''){
+			wx.showToast({
+				icon: 'none',
+				title: '请填写预约时间',
+			})
+			return
+		}
+		if(this.data.appoint_date == ''){
+			wx.showToast({
+				icon: 'none',
+				title: '请选择预约日期',
+			})
+			return
+		}
+		let that = this
+		let e = {}
+		e.name = that.data.name
+		e.phone = that.data.phone
+		e.license_number = that.data.license_number
+		e.car_model = that.data.car_model
+		e.appoint_date = that.data.appoint_date
+		e.exchange_code = that.data.exchange_code
+		e.appoint_time = that.data.appoint_time
+
+		getApp().request({
+			url: getApp().api.yuyue.submit,
+			method: "POST",
+			data: e,
+			success: function (res) {
+				console.log(res)
+				wx.showLoading({
+					title: '提交中',
+				})
+				if(res.code == 0){
+					setTimeout(function(){
+						wx.hideLoading();
+						wx.redirectTo({
+							url: '/pages/check-submit/check-submit?data=' + encodeURIComponent(JSON.stringify(res.data)) + '&phone='+that.data.phone,
+						})
+					},1500)
+				}else{
+					wx.showToast({
+						icon: 'none',
+						title: res.msg,
+					})
+				}
+			},
+			fail: function(res){
+				wx.showToast({
+					icon: 'none',
+					title: res.msg,
+				})
+			}
+	})
+	},
+  formatDate(date) {
+    date = new Date(date);
+    return `${date.getMonth() + 1}/${date.getDate()}`;
+  },
+  onConfirm(event) {
+    this.setData({
+      show: false,
+      date: this.formatDate(event.detail),
+    });
+	},
+	
+  // bindDateChange: function(e) {
+  //   console.log('picker发送选择改变,携带值为', e.detail.value)
+  //   this.setData({
+  //     date: e.detail.value
+  //   })
+	// },
+	bindTimeChange: function(e) {
+    console.log('picker发送选择改变,携带值为', e.detail.value)
+    this.setData({
+      appoint_time: e.detail.value
+    })
+	},
+	loadData: function () {
+    var a = this;
+    getApp().core.showLoading({
+      title: "正在加载",
+      mask: !0
+    }), getApp().request({
+      url: getApp().api.share.index,
+      success: function (e) {
+        if (0 == e.code) {
+          if (e.data.share_setting) var t = e.data.share_setting;
+          else t = e.data;
+          getApp().core.setStorageSync(getApp().const.SHARE_SETTING, t), a.setData({
+            share_setting: t
+					})
+					a.setData({
+						user_info_show: false
+					})
+        }else if (1 == e.code){
+					a.setData({
+						user_info_show: true
+					})
+				}
+      },
+      complete: function () {
+        getApp().core.hideLoading()
+      }
+    })
+  },
+});

+ 7 - 0
pages/check/check.json

xqd
@@ -0,0 +1,7 @@
+{
+  "navigationBarTitleText": "预约",
+  "usingComponents": {
+    "calendar": "/components/calendar/index",
+    "app-navigation":"/components/quick-navigation-components/index"
+  }
+}

+ 54 - 0
pages/check/check.wxml

xqd
@@ -0,0 +1,54 @@
+<view class="page">
+	<include src='../../components/_toast/_toast1'></include>
+	<image src="http://dm.dhcarlife.com/core//image/store_21320/48e46fcfb76593a91572d64b337c7490b7e2d963.png" 
+	data-from="content" mode='widthFix' style="width:100%;"></image>
+	<view class="section">
+		<view class="input-container">
+				<view class="input-border">
+				<text class="label">姓名:</text>
+				<input class="uni-input" bindinput="bindName" value='{{name}}' bind:=""/>
+			</view>
+		</view>
+		<view class="input-container">
+			<view class="input-border">
+				<view class="label">电话:</view>
+				<input class="uni-input"bindinput="bindPhone"  value='{{phone}}' maxlength="11" type="number"/>
+			</view>
+		</view>
+		<view class="input-container">
+			<view class="input-border">
+				<text class="label">车牌号:</text>
+				<input class="uni-input" bindinput="bindLicense"  value='{{license_number}}' />
+			</view>
+		</view>
+		<view class="input-container">
+			<view class="input-border">
+				<text class="label">车辆型号:</text>
+				<input class="uni-input" bindinput="bindModel" value="{{car_model}}"/>
+			</view>
+		</view>
+		<view class="input-container">
+			<view class="input-border">
+				<picker class="picker-input" mode="time" value="{{appoint_time}}" start="09:00" end="17:00" bindchange="bindTimeChange">
+					<view class="picker">
+						<text class="label">预约时间:</text>  {{appoint_time}}
+					</view>
+				</picker>
+			</view>
+		</view>
+		<view class="section">
+			<view class="input-container" style="margin:0;">
+				<calendar 
+				config="{{calendarConfig}}"
+				bind:afterTapDate="afterTapDate" />
+			</view>
+		<view class="input-container" style="margin:0;padding-top:80px">
+			<button class="submit" bindtap="onSubmit">确定预约</button>
+		</view>
+		<view style="text-align: center;font-size:20rpx;padding:30px 0">*注:周一至周六,法定节假日除外可以预约</view>
+	</view>
+	</view>
+	<app-navigation __alipay_mp_config='{{__alipay_mp_config}}' __device='{{__device}}' __platform='{{__platform}}' __user_info='{{__user_info}}'  options='{{options}}' setnavi='{{setnavi}}' store='{{store}}'></app-navigation>
+	<image src="http://dm.dhcarlife.com/core//image/store_21320/ca8117c513a1179864236c6a8eb16a3226ae5754.png" 
+	data-from="content" mode='widthFix' style="width:100%;"></image>
+</view>

+ 78 - 0
pages/check/check.wxss

xqd
@@ -0,0 +1,78 @@
+page{
+	height: 100%;
+	width: 100%;
+}
+
+.section{
+	width: 100%;
+	/* height: 550px; */
+	padding-top: 15px;
+	background-color: #fff;
+}
+image{
+  width: 100%;
+  display: block;
+  overflow: hidden;
+}
+.content{
+	position: relative;
+}
+.input-container{
+	width: 100%;
+	padding: 0 70rpx;
+	margin: 15px 0;
+}
+.input-border{
+	width: 100%;
+	height: 40px;
+	padding: 0 30rpx;
+	/* border: 1rpx solid #A3ACB1; */
+	box-shadow: 6rpx 6rpx 8rpx rgba(26, 26, 26, 0.2);
+	border-radius: 15rpx;
+	display: flex;
+	align-items: center;
+}
+.label{
+	color: #080808;
+	/* width: 20%; */
+}
+/* 输入框 */
+.uni-input{
+	/* background-color: #fff; */
+	background-image: none;
+	border: none;
+	box-sizing: border-box;
+	color: #606266;
+	display: inline-block;
+	font-size: inherit;
+	height: 40rpx;
+	line-height: 40rpx;
+	outline: none;
+	width: 75%;
+	padding-left: 5px;
+	transition: border-color .2s cubic-bezier(.645,.045,.355,1);
+}
+.picker-input{
+	width: 100%;
+	height: 40rpx;
+	line-height: 40rpx;
+}
+.submit{
+	width: 110px;
+	border-radius: 35px;
+	background-color: #CA3B3D;
+	color: #fff;
+	font-size:15px;
+}
+.calendar{
+	height: 300px;
+}
+/* .text-margin{
+	margin: 5px 0;
+} */
+/* 复选框颜色 */
+checkbox .wx-checkbox-input.wx-checkbox-input-checked {
+	color: #fff !important;
+	background: #f5cc57 !important;
+	border: 1px solid #f5cc57 !important;
+}

+ 244 - 0
pages/check/checksg.js

xqd
@@ -0,0 +1,244 @@
+
+import todo from '../../components/calendar/plugins/todo'
+import selectable from '../../components/calendar/plugins/selectable'
+import solarLunar from '../../components/calendar/plugins/solarLunar/index'
+import timeRange from '../../components/calendar/plugins/time-range'
+import week from '../../components/calendar/plugins/week'
+import holidays from '../../components/calendar/plugins/holidays/index'
+import plugin from '../../components/calendar/plugins/index'
+
+plugin
+  .use(todo)
+  .use(solarLunar)
+  .use(selectable)
+  .use(week)
+  .use(timeRange)
+  .use(holidays)
+Page({
+	data: {
+		name: '',
+		phone: '',
+		license_number: '',
+		car_model: '',
+		appoint_date: '',
+		appoint_time: '',
+		exchange_code:'',
+		car_appoint_id:'',
+		user_info_show: false,
+		calendarConfig: {
+			theme: 'elegant',
+			disableMode: {
+        // 禁用某一天之前/之后的所有日期
+				type: 'before', // [‘before’, 'after']
+      },
+		},
+	},
+	onLoad: function(t) {
+		this.loadData()
+		console.log(t,66666)
+    getApp().page.onLoad(this, t), t.page_id || (t.page_id = -1), this.setData({
+      options: t
+		});
+	},
+	onShow: function(){
+		var e = this;
+		getApp().getConfig(function(t) {
+      var a = t.store;
+      a && a.name && -1 == e.data.options.page_id && getApp().core.setNavigationBarTitle({
+        title: a.name
+			})
+    })
+	},
+	// 填写姓名
+	bindName:function(e){
+		console.log(e.detail.value)
+		this.setData({
+			name: e.detail.value
+		})
+		console.log('预约')
+	},
+	// 填写电话
+	bindPhone:function(e){
+		console.log(e.detail.value)
+		this.setData({
+			phone: e.detail.value
+		})
+		console.log('预约')
+	},
+	// 填写车牌号
+	bindLicense:function(e){
+		console.log(e.detail.value)
+		this.setData({
+			license_number: e.detail.value
+		})
+		console.log('预约')
+	},
+	// 车辆型号
+	bindModel:function(e){
+		console.log(e.detail.value)
+		this.setData({
+			car_model: e.detail.value
+		})
+		console.log('预约')
+	},
+	// 兑换码
+	bindRedemptionCode:function(e){
+		this.setData({
+			exchange_code: e.detail.value
+		})
+	},
+	// 选中
+  afterTapDate(e) {
+		console.log('afterTapDate', e.detail)
+		if(e.detail.week == 0){
+			console.log('week为周日',e.detail.week)
+			wx.showModal({
+				title: e.detail.date + '日为周末, 周末闭店休息',
+				showCancel: false
+			})
+			this.setData({
+				appoint_date: ''
+			})
+		}else{
+			this.setData({
+				appoint_date: `${e.detail.year}-${e.detail.month}-${e.detail.date}`
+			})
+		}
+	},
+	// 确定预约
+	onSubmit:function(){
+		if(this.data.name == ''){
+			wx.showToast({
+				icon: 'none',
+				title: '请填写预约人姓名',
+			})
+			return
+		}
+		if(this.data.phone == ''){
+			wx.showToast({
+				icon: 'none',
+				title: '请填写预约人电话',
+			})
+			return
+		}
+		if(this.data.license_number == ''){
+			wx.showToast({
+				icon: 'none',
+				title: '请填写预约人车牌号',
+			})
+			return
+		}
+		if(this.data.car_model == ''){
+			wx.showToast({
+				icon: 'none',
+				title: '请填写预约人车辆型号',
+			})
+			return
+		}
+		if(this.data.appoint_time == ''){
+			wx.showToast({
+				icon: 'none',
+				title: '请填写预约时间',
+			})
+			return
+		}
+		if(this.data.appoint_date == ''){
+			wx.showToast({
+				icon: 'none',
+				title: '请选择预约日期',
+			})
+			return
+		}
+		let that = this
+		let e = {}
+		e.name = that.data.name
+		e.phone = that.data.phone
+		e.license_number = that.data.license_number
+		e.car_model = that.data.car_model
+		e.appoint_date = that.data.appoint_date
+		e.exchange_code = that.data.exchange_code
+		e.appoint_time = that.data.appoint_time
+
+		getApp().request({
+			url: getApp().api.yuyue.submit,
+			method: "POST",
+			data: e,
+			success: function (res) {
+				console.log(res)
+				wx.showLoading({
+					title: '提交中',
+				})
+				if(res.code == 0){
+					setTimeout(function(){
+						wx.hideLoading();
+						wx.redirectTo({
+							url: '/pages/check-submit/check-submit?data=' + encodeURIComponent(JSON.stringify(res.data)) + '&phone='+that.data.phone,
+						})
+					},1500)
+				}else{
+					wx.showToast({
+						icon: 'none',
+						title: res.msg,
+					})
+				}
+			},
+			fail: function(res){
+				wx.showToast({
+					icon: 'none',
+					title: res.msg,
+				})
+			}
+	})
+	},
+  formatDate(date) {
+    date = new Date(date);
+    return `${date.getMonth() + 1}/${date.getDate()}`;
+  },
+  onConfirm(event) {
+    this.setData({
+      show: false,
+      date: this.formatDate(event.detail),
+    });
+	},
+	
+  // bindDateChange: function(e) {
+  //   console.log('picker发送选择改变,携带值为', e.detail.value)
+  //   this.setData({
+  //     date: e.detail.value
+  //   })
+	// },
+	bindTimeChange: function(e) {
+    console.log('picker发送选择改变,携带值为', e.detail.value)
+    this.setData({
+      appoint_time: e.detail.value
+    })
+	},
+	loadData: function () {
+    var a = this;
+    getApp().core.showLoading({
+      title: "正在加载",
+      mask: !0
+    }), getApp().request({
+      url: getApp().api.share.index,
+      success: function (e) {
+        if (0 == e.code) {
+          if (e.data.share_setting) var t = e.data.share_setting;
+          else t = e.data;
+          getApp().core.setStorageSync(getApp().const.SHARE_SETTING, t), a.setData({
+            share_setting: t
+					})
+					a.setData({
+						user_info_show: false
+					})
+        }else if (1 == e.code){
+					a.setData({
+						user_info_show: true
+					})
+				}
+      },
+      complete: function () {
+        getApp().core.hideLoading()
+      }
+    })
+  },
+});

+ 7 - 0
pages/check/checksg.json

xqd
@@ -0,0 +1,7 @@
+{
+  "navigationBarTitleText": "预约",
+  "usingComponents": {
+    "calendar": "/components/calendar/index",
+    "app-navigation":"/components/quick-navigation-components/index"
+  }
+}

+ 53 - 0
pages/check/checksg.wxml

xqd
@@ -0,0 +1,53 @@
+<view class="page">
+	<include src='../../components/_toast/_toast1'></include>
+	<image src="http://dm.dhcarlife.com/core//image/store_21320/48e46fcfb76593a91572d64b337c7490b7e2d963.png" 
+	data-from="content" mode='widthFix' style="width:100%;"></image>
+	<view class="section">
+		<view class="input-container">
+				<view class="input-border">
+				<text class="label">姓名:</text>
+				<input class="uni-input" bindinput="bindName" value='{{name}}' bind:=""/>
+			</view>
+		</view>
+		<view class="input-container">
+			<view class="input-border">
+				<view class="label">电话:</view>
+				<input class="uni-input"bindinput="bindPhone"  value='{{phone}}' maxlength="11" type="number"/>
+			</view>
+		</view>
+		<view class="input-container">
+			<view class="input-border">
+				<text class="label">车牌号:</text>
+				<input class="uni-input" bindinput="bindLicense"  value='{{license_number}}' />
+			</view>
+		</view>
+		<view class="input-container">
+			<view class="input-border">
+				<text class="label">车辆型号:</text>
+				<input class="uni-input" bindinput="bindModel" value="{{car_model}}"/>
+			</view>
+		</view>
+		<view class="input-container">
+			<view class="input-border">
+				<picker class="picker-input" mode="time" value="{{appoint_time}}" start="09:00" end="17:00" bindchange="bindTimeChange">
+					<view class="picker">
+						<text class="label">预约时间:</text>  {{appoint_time}}
+					</view>
+				</picker>
+			</view>
+		</view>
+		<view class="section">
+			<view class="input-container" style="margin:0;">
+				<calendar 
+				config="{{calendarConfig}}"
+				bind:afterTapDate="afterTapDate" />
+			</view>
+		<view class="input-container" style="margin:0;padding-top:80px">
+			<button class="submit" bindtap="onSubmit">确定预约</button>
+		</view>
+		<view style="text-align: center;font-size:20rpx;padding:30px 0">*注:周一至周六,法定节假日除外可以预约</view>
+	</view>
+	</view>
+	<image src="http://dm.dhcarlife.com/core//image/store_21320/ca8117c513a1179864236c6a8eb16a3226ae5754.png" 
+	data-from="content" mode='widthFix' style="width:100%;"></image>
+</view>

+ 78 - 0
pages/check/checksg.wxss

xqd
@@ -0,0 +1,78 @@
+page{
+	height: 100%;
+	width: 100%;
+}
+
+.section{
+	width: 100%;
+	/* height: 550px; */
+	padding-top: 15px;
+	background-color: #fff;
+}
+image{
+  width: 100%;
+  display: block;
+  overflow: hidden;
+}
+.content{
+	position: relative;
+}
+.input-container{
+	width: 100%;
+	padding: 0 70rpx;
+	margin: 15px 0;
+}
+.input-border{
+	width: 100%;
+	height: 40px;
+	padding: 0 30rpx;
+	/* border: 1rpx solid #A3ACB1; */
+	box-shadow: 6rpx 6rpx 8rpx rgba(26, 26, 26, 0.2);
+	border-radius: 15rpx;
+	display: flex;
+	align-items: center;
+}
+.label{
+	color: #080808;
+	/* width: 20%; */
+}
+/* 输入框 */
+.uni-input{
+	/* background-color: #fff; */
+	background-image: none;
+	border: none;
+	box-sizing: border-box;
+	color: #606266;
+	display: inline-block;
+	font-size: inherit;
+	height: 40rpx;
+	line-height: 40rpx;
+	outline: none;
+	width: 75%;
+	padding-left: 5px;
+	transition: border-color .2s cubic-bezier(.645,.045,.355,1);
+}
+.picker-input{
+	width: 100%;
+	height: 40rpx;
+	line-height: 40rpx;
+}
+.submit{
+	width: 110px;
+	border-radius: 35px;
+	background-color: #CA3B3D;
+	color: #fff;
+	font-size:15px;
+}
+.calendar{
+	height: 300px;
+}
+/* .text-margin{
+	margin: 5px 0;
+} */
+/* 复选框颜色 */
+checkbox .wx-checkbox-input.wx-checkbox-input-checked {
+	color: #fff !important;
+	background: #f5cc57 !important;
+	border: 1px solid #f5cc57 !important;
+}

+ 82 - 1
pages/clerk/clerk.js

xqd
@@ -1 +1,82 @@
-Page({data:{order:null,getGoodsTotalPrice:function(){return this.data.order.total_price}},onLoad:function(e){getApp().page.onLoad(this,e);var t=this,o="";if("undefined"==typeof my)o=e.scene;else if(null!==getApp().query){var r=getApp().query;getApp().query=null,o=r.order_no}t.setData({store:getApp().core.getStorageSync(getApp().const.STORE),user_info:getApp().getUser()}),getApp().core.showLoading({title:"正在加载"}),getApp().request({url:getApp().api.order.clerk_detail,data:{order_no:o},success:function(e){0==e.code?t.setData({order:e.data}):getApp().core.showModal({title:"警告!",showCancel:!1,content:e.msg,confirmText:"确认",success:function(e){e.confirm&&getApp().core.redirectTo({url:"/pages/index/index"})}})},complete:function(){getApp().core.hideLoading()}})},clerk:function(e){var t=this;getApp().core.showModal({title:"提示",content:"是否确认核销?",success:function(e){e.confirm&&(getApp().core.showLoading({title:"正在加载"}),getApp().request({url:getApp().api.order.clerk,data:{order_no:t.data.order.order_no},success:function(e){0==e.code?getApp().core.redirectTo({url:"/pages/user/user"}):getApp().core.showModal({title:"警告!",showCancel:!1,content:e.msg,confirmText:"确认",success:function(e){e.confirm&&getApp().core.redirectTo({url:"/pages/index/index"})}})},complete:function(){getApp().core.hideLoading()}}))}})}}); 
+Page({
+	data: {
+		order: null,
+		getGoodsTotalPrice: function() {
+			return this.data.order.total_price
+		}
+	},
+	onLoad: function(e) {
+		getApp().page.onLoad(this, e);
+		var t = this,
+			o = "";
+		if ("undefined" == typeof my) o = e.scene;
+		else if (null !== getApp().query) {
+			var r = getApp().query;
+			getApp().query = null, o = r.order_no
+		}
+		t.setData({
+			store: getApp().core.getStorageSync(getApp().const.STORE),
+			user_info: getApp().getUser()
+		}), getApp().core.showLoading({
+			title: "正在加载"
+		}), getApp().request({
+			url: getApp().api.order.clerk_detail,
+			data: {
+				order_no: o
+			},
+			success: function(e) {
+				0 == e.code ? t.setData({
+					order: e.data
+				}) : getApp().core.showModal({
+					title: "警告!",
+					showCancel: !1,
+					content: e.msg,
+					confirmText: "确认",
+					success: function(e) {
+						e.confirm && getApp().core.redirectTo({
+							url: "/pages/index/index"
+						})
+					}
+				})
+			},
+			complete: function() {
+				getApp().core.hideLoading()
+			}
+		})
+	},
+	clerk: function(e) {
+		var t = this;
+		getApp().core.showModal({
+			title: "提示",
+			content: "是否确认核销?",
+			success: function(e) {
+				e.confirm && (getApp().core.showLoading({
+					title: "正在加载"
+				}), getApp().request({
+					url: getApp().api.order.clerk,
+					data: {
+						order_no: t.data.order.order_no
+					},
+					success: function(e) {
+						0 == e.code ? getApp().core.redirectTo({
+							url: "/pages/user/user"
+						}) : getApp().core.showModal({
+							title: "警告!",
+							showCancel: !1,
+							content: e.msg,
+							confirmText: "确认",
+							success: function(e) {
+								e.confirm && getApp().core.redirectTo({
+									url: "/pages/index/index"
+								})
+							}
+						})
+					},
+					complete: function() {
+						getApp().core.hideLoading()
+					}
+				}))
+			}
+		})
+	}
+});

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
pages/clerk/clerk.wxml


+ 9 - 2
pages/coupon-list/coupon-list.js

xqd
@@ -10,10 +10,17 @@ Page({
 	onShow: function() {
 		getApp().page.onShow(this);
 		var e = this;
+		var data = {};
 		getApp().core.showLoading({
 			mask: !0
-		}), getApp().request({
-			url: getApp().api.default.coupon_list + '&coupon_id=' + e.data.options.coupon_id ,
+		}); 
+		var coupon_id = e.data.options.coupon_id
+		if(typeof(coupon_id) != ('undefined' || undefined || null || '')){
+			data.coupon_id = coupon_id
+		}
+		getApp().request({
+			url: getApp().api.default.coupon_list,
+			data: data,
 			success: function(t) {
 				0 == t.code && e.setData({
 					coupon_list: t.data.list

+ 1 - 0
pages/coupon-subsidy/coupon-subsidy.js

xqd
@@ -0,0 +1 @@
+Page({data:{list:[]},onLoad:function(t){getApp().page.onLoad(this,t),this.setData({status:t.status||0}),this.loadData(t)},loadData:function(t){var a=this;getApp().core.showLoading({title:"加载中"}),getApp().request({url:getApp().api.coupon.index,data:{status:a.data.status},success:function(t){0==t.code&&a.setData({list:t.data.list})},complete:function(){getApp().core.hideLoading()}})},goodsList:function(t){var a=t.currentTarget.dataset.goods_id,s=t.currentTarget.dataset.id,e=this.data.list;for(var i in e)if(parseInt(e[i].user_coupon_id)===parseInt(s))return void(2==e[i].appoint_type&&0<e[i].goods.length&&getApp().core.navigateTo({url:"/pages/list/list?goods_id="+a}))},xia:function(t){var a=t.target.dataset.index;this.setData({check:a})},shou:function(){this.setData({check:-1})}}); 

+ 3 - 0
pages/coupon-subsidy/coupon-subsidy.json

xqd
@@ -0,0 +1,3 @@
+{
+  "navigationBarTitleText": ""
+}

+ 73 - 0
pages/coupon-subsidy/coupon-subsidy.wxml

xqd
@@ -0,0 +1,73 @@
+<view class='page'>
+	<include src='/components/common/common'></include>
+	<include src='/components/header/header'></include>
+	<view class='body after-navber'>
+		<view class='top-bar flex-row'>
+			<navigator class='flex-grow-1 {{(status == 0?"active":"")}}' openType='redirect' url='/pages/coupon/coupon?status=0'><text>未使用</text></navigator>
+			<navigator class='flex-grow-1 {{(status == 1?"active":"")}}' openType='redirect' url='/pages/coupon/coupon?status=1'><text>已使用</text></navigator>
+			<navigator class='flex-grow-1 {{(status == 2?"active":"")}}' openType='redirect' url='/pages/coupon/coupon?status=2'><text>已过期</text></navigator>
+		</view>
+		<block wx:if='{{ (list && list.length > 0) }}'>
+			<view class='coupon-list'>
+				<block wx:for='{{list}}' wx:for-item='coupon' wx:for-index='index' wx:key='{{item.id}}'>
+					<view class='coupon-item coupon-status-{{coupon.status}}' style='margin-top:20rpx;'>
+						<image class='coupon-bg' src='/images/img-coupon-bg-{{(coupon.status == 0?0:1)}}.png'></image>
+						<block wx:if='{{coupon.status != 0}}'>
+							<image class='coupon-status-icon' src='/images/img-coupon-status-icon-{{coupon.status}}.png'></image>
+						</block>
+						<view class='flex-row' style='height: 100%;overflow: hidden;position:relative'>
+							<view class='flex-grow-0 flex-col flex-y-center flex-x-center coupon-left'>
+								<view class='flex-row flex-y-bottom'>
+									<view class='fs-sm'>¥</view>
+									<view style='font-size: {{(coupon.sub_price.length > 4?13:19)}}pt;line-height: .9'> {{coupon.sub_price}}
+									</view>
+								</view>
+								<view class='fs-sm' style='margin-top: 10rpx'>{{coupon.min_price_desc}}</view>
+							</view>
+							<view class='flex-grow-1 flex-y-center coupon-right'>
+								<view style='width:100%;'>
+									<navigator openType='navigateTo' url='/pages/coupon-detail/coupon-detail?user_coupon_id={{coupon.user_coupon_id}}'>
+										<view class='flex-row flex-y-center mb-10' style='margin-bottom:5rpx;'>
+											<view class='flex-grow-1'>{{coupon.event_desc}}</view>
+										</view>
+										<view class='fs-sm' style='color: #666666; font-size: 8pt;'>{{coupon.begin_time}} ~ {{coupon.end_time}}</view>
+										<block wx:if='{{ (coupon.appoint_type == 1 && coupon.cat.length == 0) }}'><text class='user_coupon_font'>全场通用</text></block>
+										<block wx:if='{{ (coupon.appoint_type == 2 && coupon.goods.length == 0) }}'><text class='user_coupon_font'>全场通用</text></block>
+										<block wx:if='{{coupon.appoint_type == NULL}}'><text class='user_coupon_font'>全场通用</text></block>
+									</navigator>
+									<block wx:if='{{ (coupon.appoint_type == 1 && coupon.cat.length > 0) }}'>
+										<view class='user_coupon_font' style='overflow: hidden; white-space: nowrap; text-overflow: ellipsis;width:87%;'>
+											仅限<block wx:for='{{coupon.cat}}' wx:for-item='cat' wx:for-index='index' wx:key='id'><text>{{cat.name}}、</text></block>产品使用
+										</view>
+										<block wx:if='{{coupon.cat.length > 2}}'>
+											<block wx:if='{{index != check}}'>
+												<image bindtap='xia' class='xia' data-index='{{index}}' src='{{__wxapp_img.user.coupon_xia.url}}'></image>
+											</block>
+											<block wx:if='{{index == check}}'>
+												<image bindtap='shou' class='xia' data-index='{{index}}' src='{{__wxapp_img.store.shou.url}}'></image>
+											</block>
+										</block>
+									</block>
+									<block wx:if='{{ (coupon.appoint_type == 2 && coupon.goods.length > 0) }}'>
+										<view bindtap='goodsList' class='user_coupon_font' data-goods_id='{{coupon.goods}}' data-id='{{coupon.user_coupon_id}}'
+										 style='height:50rpx;'>指定商品使用 点进去查看指定商品</view>
+									</block>
+								</view>
+							</view>
+						</view>
+					</view>
+					<block wx:if='{{coupon.cat.length > 2}}'>
+						<block wx:if='{{check == index}}'>
+							<view class='user_coupon' style='padding:10rpx 24rpx;background:#fff;'> 仅限<block wx:for='{{coupon.cat}}'
+								 wx:for-item='cat' wx:for-index='index' wx:key='id'><text>{{cat.name}}、</text></block>产品使用 </view>
+						</block>
+					</block>
+				</block>
+			</view>
+		</block>
+		<block wx:else>
+			<view style='padding-top: 200rpx;color: #888;text-align: center'>暂无相关优惠券</view>
+		</block>
+	</view>
+	<include src='/components/footer/footer'></include>
+</view>

+ 14 - 0
pages/coupon-subsidy/coupon-subsidy.wxss

xqd
@@ -0,0 +1,14 @@
+.top-bar { position: fixed; top: 0; left: 0; width: 100%; background: #fff; border-top: 1rpx solid #e3e3e3; border-bottom: 1rpx solid #e3e3e3; z-index: 999; }
+.top-bar wx-navigator{ text-align: center; }
+.top-bar wx-navigator wx-text{ height: 90rpx; line-height: 90rpx; border-bottom: 2rpx solid transparent; width: auto; display: inline-block; }
+.top-bar wx-navigator.active wx-text{ color: #ff4544; border-bottom-color: #ff4544; }
+.coupon-list{ padding: 122rpx 34rpx 20rpx 34rpx; }
+.coupon-list .coupon-item{ height: 152rpx; width: 682rpx; position: relative; z-index: 10; }
+.coupon-list .coupon-item.coupon-status-1 .coupon-right, .coupon-list .coupon-item.coupon-status-2 .coupon-right{ color: rgba(0,0,0,.35) !important; }
+.coupon-list .coupon-item .coupon-bg{ width: 100%; height: 100%; position: absolute; top:0; left: 0; z-index: 0; }
+.coupon-list .coupon-item .coupon-status-icon{ width: 140rpx; height: 98rpx; position: absolute; top:0; right: 8rpx; z-index: 1; }
+.coupon-list .coupon-item .coupon-left{ color: #fff; width: 202rpx; }
+.coupon-list .coupon-item .coupon-right{ padding: 20rpx 10rpx; }
+.user_coupon_font{ color: #666666; }
+.user_coupon{ color: #666666; }
+.xia{ position: absolute; width:28rpx; height:28rpx; right:15px; bottom:9px; }

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
pages/coupon/coupon.wxml


+ 1 - 1
pages/goods/goods.js

xqd
@@ -80,7 +80,7 @@ Page({
     }
     o.setData({
       id: t.id,
-	  topic_id: t.topic_id
+	    topic_id: t.topic_id
     }), 
 	o.getGoods(), 
 	o.getCommentList()

+ 2 - 2
pages/goods/goods.wxml

xqd
@@ -76,9 +76,9 @@
 				<include src='/components/shopping_cart/shopping_cart'></include>
 			</block>
 			<block wx:else>
-				<navigator class='cart-nav' openType='redirect' url='/pages/cart/cart'>
+				<!-- <navigator class='cart-nav' openType='redirect' url='/pages/cart/cart'>
 					<image src='{{__wxapp_img.nav.cart.url}}'></image>
-				</navigator>
+				</navigator> -->
 				<include src='/components/goods/goods_buy'></include>
 			</block>
 			<include src='/components/common/get-coupon.wxml'></include>

+ 5 - 1
pages/index/index.json

xqd
@@ -1 +1,5 @@
-{"navigationBarTitleText":"","enablePullDownRefresh":true,"usingComponents":{"app-navigation":"/components/quick-navigation-components/index"}}
+{
+  "navigationBarTitleText":"",
+  "enablePullDownRefresh":true,
+  "usingComponents":{"app-navigation":"/components/quick-navigation-components/index"}
+}

+ 1 - 1
pages/index/index.wxml

xqd
@@ -159,5 +159,5 @@
       <template is='act-modal' data='{{__wxapp_img:__wxapp_img,act_modal_list:act_modal_list}}'></template>
     </block>
   </view>
-  <!-- <include src='/components/footer/footer'></include> -->
+  <include src='/components/footer/footer'></include>
 </view>

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
pages/integral-mall/order/order.js


+ 62 - 1
pages/login/login.js

xqd
@@ -1 +1,62 @@
-Page({data:{},onLoad:function(e){getApp().page.onLoad(this,e)},getUserInfo:function(o){var n=this;"getUserInfo:ok"==o.detail.errMsg&&getApp().core.login({success:function(e){var t=e.code;n.unionLogin({code:t,user_info:o.detail.rawData,encrypted_data:o.detail.encryptedData,iv:o.detail.iv,signature:o.detail.signature})},fail:function(e){}})},myLogin:function(){var t=this;"my"===getApp().platform&&my.getAuthCode({scopes:"auth_user",success:function(e){t.unionLogin({code:e.authCode})}})},unionLogin:function(e){getApp().core.showLoading({title:"正在登录",mask:!0}),getApp().request({url:getApp().api.passport.login,method:"POST",data:e,success:function(e){if(0==e.code){getApp().setUser(e.data),getApp().core.setStorageSync(getApp().const.ACCESS_TOKEN,e.data.access_token),getApp().trigger.run(getApp().trigger.events.login);var t=getApp().core.getStorageSync(getApp().const.LOGIN_PRE_PAGE);t&&t.route?getApp().core.redirectTo({url:"/"+t.route+"?"+getApp().helper.objectToUrlParams(t.options)}):getApp().core.redirectTo({url:"/pages/index/index"})}else getApp().core.showModal({title:"提示",content:e.msg,showCancel:!1})},complete:function(){getApp().core.hideLoading()}})}}); 
+Page({
+	data: {},
+	onLoad: function(e) {
+		getApp().page.onLoad(this, e)
+	},
+	getUserInfo: function(o) {
+		var n = this;
+		"getUserInfo:ok" == o.detail.errMsg && getApp().core.login({
+			success: function(e) {
+				var t = e.code;
+				n.unionLogin({
+					code: t,
+					user_info: o.detail.rawData,
+					encrypted_data: o.detail.encryptedData,
+					iv: o.detail.iv,
+					signature: o.detail.signature
+				})
+			},
+			fail: function(e) {}
+		})
+	},
+	myLogin: function() {
+		var t = this;
+		"my" === getApp().platform && my.getAuthCode({
+			scopes: "auth_user",
+			success: function(e) {
+				t.unionLogin({
+					code: e.authCode
+				})
+			}
+		})
+	},
+	unionLogin: function(e) {
+		getApp().core.showLoading({
+			title: "正在登录",
+			mask: !0
+		}), getApp().request({
+			url: getApp().api.passport.login,
+			method: "POST",
+			data: e,
+			success: function(e) {
+				if (0 == e.code) {
+					getApp().setUser(e.data), getApp().core.setStorageSync(getApp().const.ACCESS_TOKEN, e.data.access_token),
+						getApp().trigger.run(getApp().trigger.events.login);
+					var t = getApp().core.getStorageSync(getApp().const.LOGIN_PRE_PAGE);
+					t && t.route ? getApp().core.redirectTo({
+						url: "/" + t.route + "?" + getApp().helper.objectToUrlParams(t.options)
+					}) : getApp().core.redirectTo({
+						url: "/pages/index/index"
+					})
+				} else getApp().core.showModal({
+					title: "提示",
+					content: e.msg,
+					showCancel: !1
+				})
+			},
+			complete: function() {
+				getApp().core.hideLoading()
+			}
+		})
+	}
+});

+ 11 - 9
pages/new-order-submit/new-order-submit.js

xqd xqd xqd xqd
@@ -13,7 +13,7 @@ Page({
         integral_radio: 1,
         new_total_price: 0,
         show_card: !1,
-        payment: -1,
+        payment: 3,
         show_payment: !1,
         show_more: !1,
         index: -1,
@@ -37,11 +37,11 @@ Page({
     },
 	// 虚拟商品电话
     bindMobileInput: function (t) {
-		console.log(t.detail.value)
-		console.log(t.currentTarget.dataset.index)
-        this.data.phone = t.detail.value, 
+		// console.log(t.detail.value)
+		// console.log(t.currentTarget.dataset.index)
+        // this.data.phone = t.detail.value, 
 		this.setData({
-            phone: this.data.phone
+            phone: t.detail.value
         })
     },
     KeyName: function (t) {
@@ -147,7 +147,6 @@ Page({
 		a.payment = e.data.payment, 
 		a.phone = e.data.phone
 		a.formId = t.detail.formId,
-		console.log('最终数据',a)
 		e.order_submit(a, "s")
     },
     onReady: function () {},
@@ -174,15 +173,18 @@ Page({
             title: "正在加载",
             mask: !0
         }), e.mch_list = t.mch_list,
+        console.log('t.mch_list',t.mch_list)
 		 getApp().request({
             url: getApp().api.order.new_submit_preview,
             method: "POST",
             data: e,
             success: function (t) {
-                _.setData({
-                    is_virtual: t.data.is_virtual
-                })
                 if (getApp().core.hideLoading(), 0 == t.code) {
+                    if(t.data.is_virtual){
+                        _.setData({
+                            is_virtual: t.data.is_virtual
+                        })  
+                    }
                     var e = getApp().core.getStorageSync(getApp().const.INPUT_DATA),
                         a = t.data,
                         i = -1,

+ 3 - 3
pages/new-order-submit/new-order-submit.wxml

xqd xqd
@@ -354,8 +354,8 @@
 							<block wx:if='{{pay_type_list.length > 0}}'>
 								<view style='border-top:1rpx solid #e3e3e3'>
 									<block wx:for='{{pay_type_list}}' wx:for-item='item' wx:for-index='index' wx:key='{{item.id}}'>
-										<block wx:if='{{index == 1}}'>
-											<block wx:if="{{is_virtual == 0 ? true:false}}">
+										<!-- <block wx:if='{{index == 1}}'> -->
+											<block wx:if="{{is_virtual == 0 }}">
 												<view bindtap='payPicker' class='pay-block flex-row flex-y-center' data-index='{{item.payment}}'>
 													<view class='flex-grow-0'>
 														<image src='{{item.icon}}' style='width:56rpx;height:56rpx;margin-right:32rpx;'></image>
@@ -368,7 +368,7 @@
 													</block>
 												</view>	
 											</block>
-										</block>
+										<!-- </block> -->
 										<block wx:else>
 											<view bindtap='payPicker' class='pay-block flex-row flex-y-center' data-index='{{item.payment}}'>
 												<view class='flex-grow-0'>

+ 88 - 0
pages/order-detail-clerk/order-detail-clerk.js

xqd
@@ -0,0 +1,88 @@
+Page({
+	data: {
+		order: null,
+		code_id: null,
+		getGoodsTotalPrice: function() {
+			return this.data.order.total_price
+		}
+	},
+	onLoad: function(e) {
+		getApp().page.onLoad(this, e);
+		var t = this,
+			code_id = e.code_id,
+			o = "";
+		if ("undefined" == typeof my) o = e.scene;
+		else if (null !== getApp().query) {
+			var r = getApp().query;
+			getApp().query = null,
+			o = r.order_no
+		}
+		t.setData({
+			store: getApp().core.getStorageSync(getApp().const.STORE),
+			user_info: getApp().getUser(),
+			code_id: e.code_id
+		}), 
+		getApp().core.showLoading({
+			title: "正在加载"
+		}), 
+		getApp().request({
+			url: getApp().api.order.clerk_goods_detail,
+			data: {
+				code_id: o
+			},
+			success: function(e) {
+				0 == e.code ? t.setData({
+					order: e.data
+				}) : getApp().core.showModal({
+					title: "警告!",
+					showCancel: !1,
+					content: e.msg,
+					confirmText: "确认",
+					success: function(e) {
+						e.confirm && getApp().core.redirectTo({
+							url: "/pages/index/index"
+						})
+					}
+				})
+			},
+			complete: function() {
+				getApp().core.hideLoading()
+			}
+		})
+	},
+	clerk: function(e) {
+		var t = this;
+		getApp().core.showModal({
+			title: "提示",
+			content: "是否确认核销?",
+			success: function(e) {
+				e.confirm && (getApp().core.showLoading({
+					title: "正在加载"
+				}), getApp().request({
+					url: getApp().api.order.clerk_goods,
+					data: {
+						code_id: t.data.order.code_id
+					},
+					success: function(e) {
+						0 == e.code ? getApp().core.redirectTo({
+							url: "/pages/user/user"
+						}) : getApp().core.showModal({
+							title: "警告!",
+							showCancel: !1,
+							content: e.msg,
+							confirmText: "确认",
+							success: function(e) {
+								e.confirm && getApp().core.redirectTo({
+									url: "/pages/index/index"
+								})
+							}
+						})
+					},
+					complete: function() {
+						getApp().core.hideLoading()
+					}
+				}))
+			}
+		})
+	}
+});

+ 3 - 0
pages/order-detail-clerk/order-detail-clerk.json

xqd
@@ -0,0 +1,3 @@
+{
+  "navigationBarTitleText": "核销虚拟商品"
+}

+ 85 - 0
pages/order-detail-clerk/order-detail-clerk.wxml

xqd
@@ -0,0 +1,85 @@
+<view class='page'>
+  <include src='/components/common/common'></include>
+  <include src='/components/header/header'></include>
+  <view class='body after-navber'>
+    <view class='block'>
+      <view class='flex-row block-row'>
+        <view class='flex-grow-1'> 商品名称:{{order.name}} </view>
+        <view class='flex-grow-0'> {{order.mobile}} </view>
+      </view>
+      <view>下单时间:{{order.addtime}}</view>
+    </view>
+	<view class='block'>
+		<view class='flex-row block-row'>
+			<view class='flex-grow-1'>兑换期限:{{order.time_limit_text}}</view>
+			<block wx:if='{{order}}'>
+				<view class='flex-grow-0'></view>
+			</block>
+			<block wx:else>
+				<view class='flex-grow-0'>¥0.00</view>
+			</block>
+		</view>
+		<view class='flex-row block-row'>
+		  <view class='flex-grow-1'>兑换说明:{{order.remark}}</view>
+		  <view class='flex-grow-0'></view>
+		</view>
+    </view>
+   <!--   <view class='block'>
+      <view class='flex-row block-row'>
+        <view class='flex-grow-1'>商品总额</view>
+        <block wx:if='{{order}}'>
+          <view class='flex-grow-0'>¥{{order.goods_total_price}}</view>
+      </block>
+        <block wx:else>
+          <view class='flex-grow-0'>¥0.00</view>
+        </block>
+      </view>
+      <view class='flex-row block-row'>
+        <view class='flex-grow-1'>商品数量</view>
+        <view class='flex-grow-0'>×{{order.num}}</view>
+      </view>
+      <view class='flex-row block-row'>
+        <view class='flex-grow-1'>优惠券优惠</view>
+        <view class='flex-grow-0'>-¥{{order.coupon_sub_price}}</view>
+      </view>
+      <view class='flex-row block-row'>
+        <view class='flex-grow-1'>运费</view>
+        <view class='flex-grow-0'>¥{{order.express_price}}</view>
+      </view>
+      <view class='flex-row block-row'>
+        <view class='flex-grow-1'>买家留言</view>
+        <view class='flex-grow-0'>{{order.content}}</view>
+      </view>
+      <view class='block-footer'>合计: <text style='color: #ff4544'>¥{{order.pay_price}}</text></view>
+    </view>
+    <view class='block' style='margin-bottom:200rpx;'>
+      <block wx:for='{{order.goods_list}}' wx:for-item='item' wx:for-index='index' wx:key='{{index}}'>
+        <view class='flex-row goods-item'>
+          <view class='flex-grow-0'>
+            <image mode='aspectFill' src='{{item.goods_pic}}' style='width: 156rpx;height: 156rpx'></image>
+          </view>
+          <view class='flex-grow-1' style='padding-left: 20rpx'>
+            <view style='margin-bottom: 10rpx'> {{item.name}} </view>
+            <view class='flex-row'>
+              <view class='flex-grow-1'>
+                <block wx:for='{{item.attr}}' wx:for-item='item' wx:for-index='index' wx:key='{{index}}'>
+                  <view style='font-size: 9pt;color: #888;margin-right: 20rpx;display: inline-block'>
+                    {{item.attr_group_name}}:{{item.attr_name}} </view>
+                </block>
+              </view>
+              <view class='flex-grow-0' style='text-align: right'>
+                <view>×{{item.num}}</view>
+                <view style='color: #ff4544'>¥:{{item.total_price}}</view>
+              </view>
+            </view>
+          </view>
+        </view>
+      </block>
+    </view> -->
+    <view bindtap='clerk' class='block flex-x-center' style='position:fixed;width:100%;bottom:-20rpx'>
+      <view class='flex-y-center flex-x-center'
+        style='width:100%;padding:10rpx 0;background:#ff4544;color:#fff;border-radius:10rpx;height:100rpx;'>核销订单</view>
+    </view>
+  </view>
+  <include src='/components/footer/footer'></include>
+</view>

+ 10 - 0
pages/order-detail-clerk/order-detail-clerk.wxss

xqd
@@ -0,0 +1,10 @@
+page{ overflow-x: hidden; }
+.status-bar { box-sizing: border-box; padding: 0 88rpx; color: #fff; font-size: 13pt; height: 120rpx; line-height: 120rpx; position: relative; }
+.status-bar wx-image{ position: absolute; left: 0; right: 0; width: 100%; height: 100%; z-index: -1; }
+.block { background: #fff; padding: 32rpx 24rpx; margin-bottom: 20rpx; }
+.block .block-row{ margin-bottom: 10rpx; }
+.block .block-footer{ border-top: 1rpx solid #eee; margin-left: -24rpx; margin-right: -24rpx; padding: 24rpx; padding-bottom: 0; margin-top: 32rpx; text-align: right; font-weight: bold; }
+.goods-item{ border-bottom: 1rpx solid #E3E3E3; padding-bottom: 32rpx; margin-bottom: 32rpx; }
+.goods-item:last-child{ border-bottom: none; margin-bottom: 0; padding-bottom: 0; }
+.refund-btn{ float: right; height: 60rpx; border:1rpx solid #bbb; padding: 0 30rpx; border-radius: 10rpx; margin-top: 20rpx; }
+.refund-text{ float: right; display: inline-block; margin-top: 20rpx; }

+ 44 - 1
pages/order-detail/order-detail.js

xqd xqd
@@ -6,7 +6,9 @@ Page({
         order: null,
         getGoodsTotalPrice: function () {
             return this.data.order.total_price
-        }
+        },
+		hide: 1,
+		qrcode: ""
     },
     onLoad: function (e) {
         getApp().page.onLoad(this, e);
@@ -33,6 +35,47 @@ Page({
             }
         })
     },
+	orderQrcode: function (t) {
+		var e = this,
+	    a = e.data.order.goods_list,
+		b = t.target.dataset.goodlistId,
+	    o = t.target.dataset.index;
+	  getApp().core.showLoading({
+		title: "正在加载",
+		mask: !0
+	  }), 
+	 //  e.data.goods_list[o].offline_qrcode ? (e.setData({
+		// hide: 0,
+		// qrcode: e.data.goods_list[o].offline_qrcode
+	 //  }), 
+	 //  getApp().core.hideLoading()) : 
+	  getApp().request({
+		url: getApp().api.order.get_goods_qrcode,
+		data: {
+		  code_id: a[b].virtual_data[o].code_id
+		},
+		success: function (t) {
+		  0 == t.code ? e.setData({
+			hide: 0,
+			qrcode: t.data.url
+		  }) : getApp().core.showModal({
+			title: "提示",
+			content: t.msg
+		  })
+		  // wx.navigateTo({
+			 //  url:"/pages/order-detail-clerk/order-detail-clerk?code_id=" + a[b].virtual_data[o].code_id
+		  // })
+		},
+		complete: function () {
+		  getApp().core.hideLoading()
+		}
+	  })
+	},
+	hide: function (t) {
+	  this.setData({
+	    hide: 1
+	  })
+	},
     copyText: function (e) {
         var t = e.currentTarget.dataset.text;
         getApp().core.setClipboardData({

+ 52 - 4
pages/order-detail/order-detail.wxml

xqd xqd xqd xqd xqd
@@ -122,6 +122,30 @@
 					<view class='block-footer'>合计: <text style='color: #ff4544'>¥{{order.pay_price}}</text></view>
 				</view>
 
+				<block wx:if="{{order.car_appoint}}">
+					<view class='block'>
+						<view class='block-row flex-row'>
+							<view class='flex-grow-1'>预约人:{{order.car_appoint.name}}</view>
+						</view>
+						<view class='block-row flex-row'>
+							<view class='flex-grow-1'>电话:{{order.car_appoint.phone}}</view>
+						</view>
+						<view class='block-row flex-row'>
+							<view class='flex-grow-1'>车牌号:{{order.car_appoint.license_number}}</view>
+						</view>
+						<view class='block-row flex-row'>
+							<view class='flex-grow-1'>车辆型号:{{order.car_appoint.car_model}}</view>
+						</view>
+						<view class='block-row flex-row'>
+							<view class='flex-grow-1'>预约时间:{{order.car_appoint.appoint_time}}</view>
+						</view>
+						<view class='block-row flex-row'>
+							<view class='flex-grow-1'>预约日期:{{order.car_appoint.appoint_date}}</view>
+						</view>
+						<view class="pay-type"></view>
+					</view>
+					</block>
+
 				<block wx:if="{{order.is_virtual == 1 ? true:false}}">
 					<view class='block'>
 						<block wx:for="{{order.goods_list}}" wx:item="item" wx:index="index" wx:key="{{item.id}}">
@@ -134,7 +158,7 @@
 								</block>
 							</view>
 							
-							<block wx:for="{{item.virtual_data}}" wx:for-item="virtual_data" wx:for-index="index" wx:key="index">
+							<block wx:for="{{item.virtual_data}}" wx:for-item="virtual_data" wx:for-index="virtual_index" wx:key="index">
 								<block wx:if="{{(virtual_data.virtual_name || virtual_data.virtual_time_limit_text) == '' ? false:true}}">
 									<view class='block-row flex-row'>
 										<view class='flex-grow-1'>
@@ -155,13 +179,28 @@
 									</view>	
 								</block>
 
-								<block>
+								<block >
 									<view class='block-row flex-row'>
-										<view class='flex-grow-1'>
+										<view class='flex-grow-1 flex-y-center'>
 											<text class="font-w">二维码</text> 
 										</view>
 										<view class='flex-grow-0'>
-											<text bindtap='viewImg' class='copy-text-btn' data-qrUrl='{{virtual_data.virtual_code_qr}}'>查看</text>
+											<!-- <text bindtap='viewImg' class='copy-text-btn' data-qrUrl='{{virtual_data.virtual_code_qr}}'>查看</text> -->
+											<!-- <block wx:if='{{ ( ( ( (order.is_pay == 1 || order.pay_type == 2)  && (order.is_offline == 1 || order.is_offline == 0))  && order.is_confirm == 0)  && order.apply_delete == 0) && order.is_virtual == 1 }}'> -->
+												<view class='flex-row' wx:if="{{virtual_data.is_check == 0}}">
+													<view class='flex-grow-1 flex-y-center'></view>
+													<view class='flex-grow-0'>
+														<view bindtap='orderQrcode' class='order-option-btn clerk flex-y-center' data-goodlist-id="{{index}}" data-index='{{virtual_index}}'>
+															<image data-goodlist-id="{{index}}" data-index='{{virtual_index}}' src='{{__wxapp_img.store.clerk.url}}' style='width:26rpx;height:26rpx;margin-right:10rpx'></image>
+															核销码
+														</view>
+													</view>
+												</view>
+												<view class='flex-row' wx:else>
+													<view class='flex-grow-1 flex-y-center'></view>
+													<view class='flex-grow-0'>已核销</view>
+												</view>
+											<!-- </block> -->
 										</view>
 									</view>	
 								</block>
@@ -221,6 +260,7 @@
 								</block>
 							</view>
 						</view>
+
 					</block>
 				</view>
 				<block wx:if='{{ (order.is_send == 0 && order.apply_delete == 1) }}'>
@@ -239,6 +279,14 @@
 				</block>
 			</view>
 		</view>
+		<view bindtap='hide' class='flex-row flex-y-center modal {{(hide == 1?"hide":"")}}'>
+			<view class='flex-y-center' style='width:100%;height:800rpx;padding:100rpx;'>
+				<view style='background-color:#fff;width:100%;height:100%;border-radius:10rpx;padding:0 50rpx;'>
+					<view class='flex-x-center' style='width:100%;height:50rpx;margin-top:50rpx;font-size:13pt;margin-bottom:20rpx'>核销二维码</view>
+					<image src='{{qrcode}}' style='width:450rpx;height:450rpx;'></image>
+				</view>
+			</view>
+		</view>
 	</block>
 	<include src='/components/footer/footer'></include>
 </view>

+ 13 - 1
pages/order-detail/order-detail.wxss

xqd
@@ -12,4 +12,16 @@ page{ overflow-x: hidden; }
 .play-btn{ height: 64rpx; border: 1rpx solid #ff5c5c !important; color: #ff5c5c; border-radius:10rpx; line-height: 64rpx; text-align: center; padding:0 20rpx !important; margin: 0 0 0 24rpx !important; background-color:transparent !important; }
 .order-footer{ height: 98rpx; margin-top: 20rpx; border-top: 1rpx solid #e2e2e2; background-color: #ffffff; padding: 0 24rpx; text-align: right; justify-content:flex-end; }
 .font-w{font-weight:bold;}
-.indent-title{text-indent: 30rpx;}
+.indent-title{text-indent: 30rpx;}
+.order-option-btn {
+border: 1rpx solid #bbb;
+background: #fff;
+border-radius: 10rpx;
+height: 60rpx;
+line-height: 60rpx;
+color: inherit;
+margin-left: 30rpx;
+padding: 0 30rpx;
+}
+.hide{ display: none; }
+.modal{ position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 9999; }

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
pages/order/order.js


+ 9 - 1
pages/order/order.wxml

xqd
@@ -115,7 +115,15 @@
 											核销码
 										</view>
 									</view>
-								</block>
+								</block>	
+<!-- 								<block wx:if='{{ ( ( ( (order.is_pay == 1 || order.pay_type == 2)  && (order.is_offline == 1 || order.is_offline == 0))  && order.is_confirm == 0)  && order.apply_delete == 0) && order.is_virtual == 1 }}'>
+									<view class='flex-grow-1'>
+										<view bindtap='orderQrcode' class='order-option-btn clerk flex-y-center' data-index='{{index}}'>
+											<image data-index='{{index}}' src='{{__wxapp_img.store.clerk.url}}' style='width:26rpx;height:26rpx;margin-right:10rpx'></image>
+											核销码
+										</view>
+									</view>
+								</block> -->
 								<block wx:if='{{ (order.is_send == 1 && order.is_confirm == 0) }}'>
 									<view class='flex-grow-1 flex-row'>
 										<block wx:if='{{order.express}}'>

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
pages/share/index.js


+ 174 - 0
pages/store-order/store-order.js

xqd
@@ -0,0 +1,174 @@
+Page({
+	data: {
+		mch_list: [],
+		order: {},
+    id: '',
+    car_appoint_id: ''
+	},
+	onLoad(e){
+		console.log('传过来的数据',e)
+		let id = e.id
+		let that = this
+		if(id != ('' || null || 'undefined' || undefined)){
+			that.setData({
+				id: id
+			})
+			this.getGoods()
+		}
+	},
+	// 获取商品详情
+	getGoods: function(){
+    let id = this.data.id;
+    let that = this
+    let data = {
+      id: id
+    }
+    if(typeof(id) != ('undefined' || undefined || null || '')){
+			data.id = id
+		}
+		getApp().request({
+      url: getApp().api.order.offline_goods_detail,
+      data: data,
+      success: function (t) {
+        if (0 == t.code) {
+          let e = t.data.attr_group_list;
+          let mch_list = []
+          let goods_list = []
+          let attr_list = null;
+          let attr = [];
+          goods_list.push({
+              goods_id: t.data.id,
+              num: 1,
+              attr: attr
+          });
+          mch_list.push({
+            mch_id: 0,
+            goods_list: goods_list
+          })
+          for(let i in e){
+              for (let s in e[i].attr_list){
+                  attr_list = {
+                      attr_id: e[i].attr_list[s].attr_id,
+                      attr_name: e[i].attr_list[s].attr_name
+                  }
+              }
+              attr.push({
+                  attr_group_id: e[i].attr_group_id,
+                  attr_id: attr_list.attr_id
+              })
+          }
+          var d = t.data;
+          that.setData({
+            order: d,
+            attr_group_list: t.data.attr_group_list,
+            btn: !0,
+            mch_list: mch_list
+          }),
+          console.log(mch_list)
+          that.newSubmitPreview()
+        }
+        1 == t.code && getApp().core.showModal({
+          title: "提示",
+          content: t.msg,
+          showCancel: !1,
+          success: function (t) {
+            t.confirm && getApp().core.switchTab({
+              url: "/pages/index/index"
+            })
+          }
+        })
+      }
+    })
+	},
+	newSubmitPreview: function(t){
+
+    let data = {
+      mch_list:[]
+    }
+    let good_list = {
+    	attr:[]
+    }
+    data.mch_list = JSON.stringify(this.data.mch_list)
+    console.log('预约接口数据',data)
+    let that = this
+    getApp().request({
+      url: getApp().api.order.new_submit_preview,
+      method: "POST",
+      data: data,
+      success: function (res) {
+        console.log(res,'下单')
+        if(res.code == 0){
+          res.data.mch_list[0].show = false
+          res.data.mch_list[0].show_length = 0
+          res.data.mch_list[0].offline = 0
+          that.setData({
+            mch_list: res.data.mch_list
+          })
+        }else{
+          wx.showToast({
+            icon: 'none',
+            title: res.msg,
+          })
+          setTimeout(()=>{
+            wx.navigateBack()
+          },2000)
+        }
+      }
+    })
+  },
+	pay: function(){
+    let o = {
+      mch_list:[]
+    }
+    o.mch_list = JSON.stringify(this.data.mch_list)
+    o.payment = 3
+    getApp().request({
+      url: getApp().api.order.new_submit,
+      method: "POST",
+      data: o,
+      success: function (res) {
+        console.log(res,'下单sssss')
+        getApp().request({
+          url: getApp().api.order.pay_data,
+          data: {
+            order_id: res.data.order_id,
+            pay_type: "WECHAT_PAY"
+          },
+          complete: function () {
+            getApp().core.hideLoading()
+          },
+          success: function (t) {
+            0 == t.code && getApp().core.requestPayment({
+              _res: t,
+              timeStamp: t.data.timeStamp,
+              nonceStr: t.data.nonceStr,
+              package: t.data.package,
+              signType: t.data.signType,
+              paySign: t.data.paySign,
+              success: function (t) {},
+              fail: function (t) {},
+              complete: function (t) {
+                "requestPayment:fail" != t.errMsg && "requestPayment:fail cancel" != t.errMsg ? getApp().core.redirectTo({
+                  url: "/pages/order/order?status=2"
+                }) : getApp().core.showModal({
+                  title: "提示",
+                  content: "订单尚未支付",
+                  showCancel: !1,
+                  confirmText: "确认",
+                  success: function (t) {
+                    t.confirm && getApp().core.redirectTo({
+                      url: "/pages/order/order?status=0"
+                    })
+                  }
+                })
+              }
+            }), 1 == t.code && getApp().core.showToast({
+              title: t.msg,
+              image: "/images/icon-warning.png"
+            })
+          }
+        })
+      }
+    })
+  },
+});

+ 3 - 0
pages/store-order/store-order.json

xqd
@@ -0,0 +1,3 @@
+{
+  "navigationBarTitleText": "门店订单"
+}

+ 85 - 0
pages/store-order/store-order.wxml

xqd
@@ -0,0 +1,85 @@
+<view class='page'>
+  <include src='/components/common/common'></include>
+  <include src='/components/header/header'></include>
+  <view class='body after-navber'>
+    <view class='block'>
+
+      <view class='flex-row block-row'>
+        <view class='flex-grow-1'> 下单时间:</view>
+        <view class='flex-grow-0'>{{order.scan_time}}</view>
+      </view>
+      <view class='flex-row block-row'>
+        <view class='flex-grow-1'> 操作员:</view>
+        <view class='flex-grow-0'>{{order.create_name}}</view>
+      </view>
+    </view>
+    <view class='block'>
+      <view class='flex-row block-row'>
+        <view class='flex-grow-1'> 公司名称:</view>
+        <view class='flex-grow-0'> {{order.supplier.name}} </view>
+      </view>
+      <view class='flex-row block-row'>
+        <view class='flex-grow-1'> 门店名称:</view>
+        <view class='flex-grow-0'> {{order.shop.name}} </view>
+      </view>
+      <!-- <view class='flex-row block-row'>
+        <view class='flex-grow-1'> 订单号:{{order.name}} </view>
+        <view class='flex-grow-0'> {{order.mobile}} </view>
+      </view> -->
+    </view>
+    <view class='block'>
+      <view class='flex-row block-row'>
+        <view class='flex-grow-1'>商品总额:</view>
+        <block wx:if='{{order}}'>
+          <view class='flex-grow-0'>¥{{order.price}}</view>
+        </block>
+        <block wx:else>
+          <view class='flex-grow-0'>¥0.00</view>
+        </block>
+      </view>
+      <view class='flex-row block-row'>
+        <view class='flex-grow-1'>商品数量:</view>
+        <view class='flex-grow-0' wx:if='{{order.num}}'>×{{order.num}}</view>
+        <block wx:else>
+          <view class='flex-grow-0'>×1</view>
+        </block>
+      </view>
+      <view class='flex-row block-row'>
+        <view class='flex-grow-1'>订单备注:</view>
+        <view class='flex-grow-0'></view>
+      </view>
+      <!-- <view class="block-row" style="text-indent:112rpx">{{order.detail}}</view> -->
+      <view class="block-row">{{order.detail}}</view>
+      <view class='block-footer'>合计: <text style='color: #ff4544'>¥{{order.price}}</text></view>
+    </view>
+    <!-- <view class='block' style='margin-bottom:200rpx;'>
+      <block wx:for='{{order.goods_list}}' wx:for-item='item' wx:for-index='index' wx:key='{{index}}'>
+        <view class='flex-row goods-item'>
+          <view class='flex-grow-0'>
+            <image mode='aspectFill' src='{{item.goods_pic}}' style='width: 156rpx;height: 156rpx'></image>
+          </view>
+          <view class='flex-grow-1' style='padding-left: 20rpx'>
+            <view style='margin-bottom: 10rpx'> {{item.name}} </view>
+            <view class='flex-row'>
+              <view class='flex-grow-1'>
+                <block wx:for='{{item.attr}}' wx:for-item='item' wx:for-index='index' wx:key='{{index}}'>
+                  <view style='font-size: 9pt;color: #888;margin-right: 20rpx;display: inline-block'>
+                    {{item.attr_group_name}}:{{item.attr_name}} </view>
+                </block>
+              </view>
+              <view class='flex-grow-0' style='text-align: right'>
+                <view>×{{item.num}}</view>
+                <view style='color: #ff4544'>¥:{{item.total_price}}</view>
+              </view>
+            </view>
+          </view>
+        </view>
+      </block>
+    </view> -->
+    <view bindtap='pay' class='block flex-x-center' style='position:fixed;width:100%;bottom:-20rpx'>
+      <view class='flex-y-center flex-x-center'
+        style='width:100%;padding:10rpx 0;background:#ff4544;color:#fff;border-radius:10rpx;height:100rpx;'>支付订单</view>
+    </view>
+  </view>
+  <include src='/components/footer/footer'></include>
+</view>

+ 10 - 0
pages/store-order/store-order.wxss

xqd
@@ -0,0 +1,10 @@
+page{ overflow-x: hidden; }
+.status-bar { box-sizing: border-box; padding: 0 88rpx; color: #fff; font-size: 13pt; height: 120rpx; line-height: 120rpx; position: relative; }
+.status-bar wx-image{ position: absolute; left: 0; right: 0; width: 100%; height: 100%; z-index: -1; }
+.block { background: #fff; padding: 32rpx 24rpx; margin-bottom: 20rpx; }
+.block .block-row{ margin-bottom: 10rpx; }
+.block .block-footer{ border-top: 1rpx solid #eee; margin-left: -24rpx; margin-right: -24rpx; padding: 24rpx; padding-bottom: 0; margin-top: 32rpx; text-align: right; font-weight: bold; }
+.goods-item{ border-bottom: 1rpx solid #E3E3E3; padding-bottom: 32rpx; margin-bottom: 32rpx; }
+.goods-item:last-child{ border-bottom: none; margin-bottom: 0; padding-bottom: 0; }
+.refund-btn{ float: right; height: 60rpx; border:1rpx solid #bbb; padding: 0 30rpx; border-radius: 10rpx; margin-top: 20rpx; }
+.refund-text{ float: right; display: inline-block; margin-top: 20rpx; }

+ 8 - 0
pages/test/cxj.js

xqd
@@ -0,0 +1,8 @@
+// pages/test/cxj.js
+Page({
+
+  data: {
+    imgUrls:''
+  },
+
+})

+ 4 - 0
pages/test/cxj.json

xqd
@@ -0,0 +1,4 @@
+{
+  "usingComponents": {},
+  "navigationBarTitleText": "车享家限时特惠"
+}

+ 29 - 0
pages/test/cxj.wxml

xqd
@@ -0,0 +1,29 @@
+<view class="content">
+      <image src="http://dm.dhcarlife.com/core//image/store_21320/f3bfefd3dd36020956909a48704d1430056b0cee.jpg" 
+       data-src="http://dm.dhcarlife.com/core//image/store_21320/f3bfefd3dd36020956909a48704d1430056b0cee.jpg"
+       data-from="content"
+      bindtap="wxParseImgTap" mode='widthFix' style="width:100%;"></image>
+    <navigator url="/pages/goods/goods?id=101">
+      <image src="http://dm.dhcarlife.com/core//image/store_21320/e9977bceeb0c980e5ae741ef1a61373067656ee0.jpg" mode='widthFix' style="width:100%;"></image>
+    </navigator>
+    <navigator url="/pages/goods/goods?id=99">
+      <image src="http://dm.dhcarlife.com/core//image/store_21320/4668368245b62783b508e957342945c393d5162c.jpg" mode='widthFix' style="width:100%;"></image>
+    </navigator>
+    <navigator  url="/pages/goods/goods?id=88">
+      <image src="http://dm.dhcarlife.com/core//image/store_21320/d3903ed630b6d1ed5b8a7ef9d557ad755377c0f0.jpg" mode='widthFix' style="width:100%;"></image>
+    </navigator>
+    <navigator  url="/pages/goods/goods?id=89">
+      <image src="http://dm.dhcarlife.com/core//image/store_21320/fbb8799bc5d932740e9c6e3e45e50a93593d4719.jpg" mode='widthFix' style="width:100%;"></image>
+    </navigator>
+    <navigator  url="/pages/goods/goods?id=86">
+      <image src="http://dm.dhcarlife.com/core//image/store_21320/8e259dacf872ac19a3e7d6a7a23645e093bd1e0a.jpg" mode='widthFix' style="width:100%;"></image>
+    </navigator>
+    <image src="http://dm.dhcarlife.com/core//image/store_21320/af6a56fde7fe8213aa201f225e95bec7f984745e.jpg" 
+      data-src="http://dm.dhcarlife.com/core//image/store_21320/af6a56fde7fe8213aa201f225e95bec7f984745e.jpg" 
+      data-from="content"
+    bindtap="wxParseImgTap" mode='widthFix' style="width:100%;"></image>
+    <image src="http://dm.dhcarlife.com/core//image/store_21320/dbd90631c27dbe65c9e51f0a00f3bb7865fe8654.jpg" 
+      data-src="http://dm.dhcarlife.com/core//image/store_21320/dbd90631c27dbe65c9e51f0a00f3bb7865fe8654.jpg" 
+      data-from="content"
+    bindtap="wxParseImgTap" mode='widthFix' style="width:100%;"></image>
+</view>

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.