Просмотр исходного кода

Merge branch 'dev' of http://git.ycjcjy.com/shigongli/miniapp-v2 into dev

李志伟 3 лет назад
Родитель
Сommit
3650ca5466

+ 40
- 34
src/components/CompoentsOrder/OrderCard/index.jsx Просмотреть файл

@@ -1,6 +1,9 @@
1 1
 import Taro from "@tarojs/taro";
2 2
 import { View, Text } from '@tarojs/components'
3 3
 import formatTime from "@/utils/formatTime";
4
+import SlideViewOrder from '@/components/SlideViewOrder';
5
+import { getOrderSub, deleteOrder } from "@/services/payOrder";
6
+
4 7
 import CouponCard from '@/components/CouponCard'
5 8
 import QRcode from "@/assets/icons/UserCenter/QRcode.png";
6 9
 import refund from "@/assets/icons/GuideCheck/refund.png";
@@ -17,7 +20,7 @@ const CouponMedia = CouponCard.Media
17 20
 const Action = CouponCard.Action
18 21
 
19 22
 export default (props) => {
20
-  const { item, setShowCutover, show, sh, kkp } = props
23
+  const { item, setShowCutover, show, sh, kkp, handeDelete } = props
21 24
 
22 25
   const handleDetail = () => {
23 26
     if (item.status === 0) {
@@ -27,6 +30,8 @@ export default (props) => {
27 30
     }
28 31
   }
29 32
 
33
+
34
+
30 35
   //核销
31 36
   const onWriteOff = (item) => {
32 37
     Taro.scanCode({
@@ -70,44 +75,45 @@ export default (props) => {
70 75
                   item.isVerified == true && item.isEvaluated > 0 ? <Action.Image image={Evaluated} /> :
71 76
                     item.isVerified == true ? <Action.Icon icon={Evaluation} text='评价' onClick={() => evaluation(item)} /> : null
72 77
 
73
-
74 78
   return (
75 79
     <>
76 80
       {
77
-        sh != '1'|| kkp == '1'? <view className='OrderNumber'>订单编号:{item.orderId}</view> : null
81
+        sh != '1' || kkp == '1' ? <view className='OrderNumber'>订单编号:{item.orderId}</view> : null
78 82
       }
79
-      <CouponCard action={PayAction}>
80
-        <CouponMedia>
81
-          <CouponMedia.Header
82
-            cashback={item.cashback}
83
-            image={item.poster}
84
-            badge='food'
85
-          />
86
-          <CouponMedia.Body star={kkp == '1' ? 'ss' : item.score}>
87
-            <View className='orderCard'>
88
-              <View className='cpn-card-text'>
89
-                <View style={{ flex: '1' }}>{(item.packageDescription).toString().length > 25 ? (item.packageDescription).substring(0, 25) + '...' : (item.packageDescription)}</View>
90
-                <text className={kkp == '1' ? 'shanchu' : 'title-money-2'}>
91
-                  数量:{item.amount}张
92
-                </text>
93
-              </View>
94
-              <View className='cpn-card-text' style={{ marginTop: '10rpx' }}>
95
-                <Text className='cpn-card-text_mn'>¥{`${(item.unitPrice / 100)?.toFixed(2)}元`}</Text>
96
-              </View>
97
-              <View className='cpn-md-act'>
98
-                <view className={item.isVerified == 1 ? 'title-time' : ''}>
99
-                  {
100
-                    sh == 1 ? '有效期:' + formatTime(item.endTime, "yyyy/MM/dd") :
101
-                      item.isVerified == 1 ? '核销时间 :' + formatTime(item?.verifiedDate, "yyyy/MM/dd") :
102
-                        '有效期:' + formatTime(item?.startTime, "yyyy/MM/dd") + '-' +
103
-                        formatTime(item.endTime, "yyyy/MM/dd")
104
-                  }
105
-                </view>
83
+      <SlideViewOrder del onDelete={() => handeDelete(item)} >
84
+        <CouponCard action={PayAction}>
85
+          <CouponMedia>
86
+            <CouponMedia.Header
87
+              cashback={item.cashback}
88
+              image={item.poster}
89
+              badge='food'
90
+            />
91
+            <CouponMedia.Body star={kkp == '1' ? 'ss' : item.score}>
92
+              <View className='orderCard'>
93
+                <View className='cpn-card-text'>
94
+                  <View style={{ flex: '1' }}>{(item.packageDescription).toString().length > 25 ? (item.packageDescription).substring(0, 25) + '...' : (item.packageDescription)}</View>
95
+                  <text className={kkp == '1' ? 'shanchu' : 'title-money-2'}>
96
+                    数量:{item.amount}张
97
+                  </text>
98
+                </View>
99
+                <View className='cpn-card-text' style={{ marginTop: '10rpx' }}>
100
+                  <Text className='cpn-card-text_mn'>¥{`${(item.unitPrice / 100)?.toFixed(2)}元`}</Text>
101
+                </View>
102
+                <View className='cpn-md-act'>
103
+                  <view className={item.isVerified == 1 ? 'title-time' : ''}>
104
+                    {
105
+                      sh == 1 ? '有效期:' + formatTime(item.endTime, "yyyy/MM/dd") :
106
+                        item.isVerified == 1 ? '核销时间 :' + formatTime(item?.verifiedDate, "yyyy/MM/dd") :
107
+                          '有效期:' + formatTime(item?.startTime, "yyyy/MM/dd") + '-' +
108
+                          formatTime(item.endTime, "yyyy/MM/dd")
109
+                    }
110
+                  </view>
111
+                </View>
106 112
               </View>
107
-            </View>
108
-          </CouponMedia.Body>
109
-        </CouponMedia>
110
-      </CouponCard>
113
+            </CouponMedia.Body>
114
+          </CouponMedia>
115
+        </CouponCard>
116
+      </SlideViewOrder>
111 117
     </>
112 118
   )
113 119
 }

+ 6
- 5
src/components/CompoentsOrder/complete/index.jsx Просмотреть файл

@@ -7,6 +7,7 @@ import AlreadyUsed from "../AlreadyUsed";
7 7
 import OrderCard from '../OrderCard'
8 8
 import "./style.less";
9 9
 import { View } from "@tarojs/components";
10
+import SlideViewOrder from '@/components/SlideViewOrder';
10 11
 
11 12
 
12 13
 const dict = {
@@ -117,11 +118,11 @@ export default (props) => {
117 118
                 /* 待支付 */
118 119
                 if (item.status === 0) {
119 120
                   return (
120
-                    <mp-slideview buttons={button} onButtontap={() => slideButtonTap(item)} icon >
121
-                      <view key={`${type}-${item.orderId}`}  >
122
-                        <OrderCard item={item} />
123
-                      </view>
124
-                    </mp-slideview>
121
+                    // <SlideViewOrder del onDelete={() => slideButtonTap(item)}>
122
+                    <view key={`${type}-${item.orderId}`}  >
123
+                      <OrderCard item={item} handeDelete={slideButtonTap} />
124
+                    </view>
125
+                    // </SlideViewOrder>
125 126
                   );
126 127
                 }
127 128
                 /* 已使用 */

+ 97
- 0
src/components/SlideViewOrder/index.jsx Просмотреть файл

@@ -0,0 +1,97 @@
1
+
2
+import React, { useEffect, useMemo, useRef, useState } from 'react'
3
+import Taro from '@tarojs/taro';
4
+import { ScrollView, View, Image, Text } from '@tarojs/components';
5
+import deleteIcon from '@/assets/icons/landlord/delete.png';
6
+import './style.less'
7
+
8
+export default (props) => {
9
+  const { className, action, del, onDelete } = props;
10
+
11
+  const contextRef = useRef()
12
+  const contentHeightRef = useRef(0)
13
+  const [actStyle, setActStyle]= useState()
14
+
15
+  const uqClass = useMemo(() => `f-${Math.random().toString(36).substring(2)}`, [])
16
+  const classes = [className, 'slideview-wrapper', uqClass].filter(Boolean).join(' ');
17
+
18
+  const handleScrollLeft = () => {
19
+    if (contextRef.current) {
20
+      contextRef.current.scrollIntoView('.slideview-content')
21
+    }
22
+  }
23
+
24
+  const handleScrollRight = () => {
25
+    if (contextRef.current) {
26
+      contextRef.current.scrollIntoView('.slideview-actions')
27
+    }
28
+  }
29
+
30
+  const handleDelete = (e) => {
31
+    if (onDelete) {
32
+      onDelete(e)
33
+    }
34
+  }
35
+
36
+  useEffect(() => {
37
+    Taro.nextTick(() => {
38
+      Taro.createSelectorQuery()
39
+      .select(`.${uqClass}`)
40
+      .node()
41
+      .exec((res) => {
42
+        contextRef.current = res[0].node;
43
+      })
44
+    })
45
+  }, [])
46
+
47
+  useEffect(() => {
48
+    Taro.nextTick(() => {
49
+      // 不清楚为什么, 此处获取高度一直不准确
50
+      const t = setTimeout(() => {
51
+        Taro.createSelectorQuery()
52
+        .select(`.${uqClass}`)
53
+        .boundingClientRect()
54
+        .exec((res) => {
55
+          if (res && res[0]) {
56
+            const { height } = res[0]
57
+            if (height && height !== contentHeightRef.current) {
58
+              setActStyle({
59
+                height: `${height}px`,
60
+              })
61
+              contentHeightRef.current = height
62
+            }
63
+          }
64
+        })
65
+        clearTimeout(t)
66
+      }, 500)
67
+    })
68
+  })
69
+
70
+  return (
71
+    <ScrollView
72
+      className={classes}
73
+      upperThreshold={20}
74
+      lowerThreshold={20}
75
+      scrollX
76
+      scrollWithAnimation
77
+      enhanced
78
+      onScrollToUpper={handleScrollLeft}
79
+      onScrollToLower={handleScrollRight}
80
+    >
81
+      <View className='slideview-content'>{props.children}</View>
82
+      <View className='slideview-actions' style={actStyle}>
83
+        <View className='slideview-action'>
84
+          {
85
+            del && (
86
+              <View className='slideview-action_delete' onClick={handleDelete}>
87
+                <Image src={deleteIcon} />
88
+                <View>删除</View>
89
+              </View>
90
+            )
91
+          }
92
+          {action}
93
+        </View>
94
+      </View>
95
+    </ScrollView>
96
+  )
97
+}

+ 52
- 0
src/components/SlideViewOrder/style.less Просмотреть файл

@@ -0,0 +1,52 @@
1
+.slideview-wrapper {
2
+  box-sizing: border-box;
3
+  white-space: nowrap;
4
+
5
+  &::-webkit-scrollbar{
6
+    width: 0;
7
+    height: 0;
8
+    color: transparent;
9
+  }
10
+
11
+  .slideview-content {
12
+    min-width: 100%;
13
+    display: inline-block;
14
+    vertical-align: middle;
15
+  }
16
+
17
+  .slideview-actions {
18
+    display: inline-block;
19
+    vertical-align: middle;
20
+    margin: 0 20px;
21
+    background: #FFFFFF;
22
+    box-shadow: 0px 8px 38px 0px rgba(0, 0, 0, 0.12);
23
+    border-radius: 12px;
24
+
25
+    .slideview-action {
26
+      height: 100%;
27
+      display: flex;
28
+      align-items: center;
29
+      justify-content: center;
30
+      
31
+      &_delete {
32
+        display: block;
33
+        flex: none;
34
+        height: 74px;
35
+        width: 67px;
36
+        text-align: center;
37
+        padding: 10px;
38
+        font-size: 24px;
39
+        font-weight: bold;
40
+        color: #FF3434;
41
+
42
+        & > image {
43
+          width: 28px;
44
+          height: 30px;
45
+          display: block;
46
+          margin: 0 auto 20px;
47
+        }
48
+      }
49
+    }
50
+
51
+  }
52
+}

+ 24
- 0
src/components/Spin/SpinBox.jsx Просмотреть файл

@@ -0,0 +1,24 @@
1
+
2
+import React, { useMemo } from 'react'
3
+import { View } from '@tarojs/components'
4
+import Spin from '.'
5
+import './style.less'
6
+
7
+export default (props) => {
8
+  const { className, style, loading, size = '64rpx', ...leftProps } = props
9
+
10
+  const cls = useMemo(() => [className, 'loading-wrapper'].filter(Boolean).join(' '), [className])
11
+
12
+  return (
13
+    <View className={cls} style={style}>
14
+      {
15
+        loading && (
16
+          <View className='loading-box'>
17
+            <Spin size={size} {...leftProps} />
18
+          </View>
19
+        )
20
+      }
21
+      {props.children}
22
+    </View>
23
+  )
24
+}

+ 19
- 0
src/components/Spin/style.less Просмотреть файл

@@ -130,3 +130,22 @@
130 130
     transform: translate(-50%, -50%);
131 131
   }
132 132
 }
133
+
134
+
135
+.loading-wrapper {
136
+  position: relative;
137
+
138
+  .loading-box {
139
+    position: absolute;
140
+    z-index: 10;
141
+    top: 0;
142
+    left: 0;
143
+    width: 100%;
144
+    height: 100%;
145
+    min-height: 72px;
146
+    padding-top: 60%;
147
+    padding-left: 50%;
148
+    background: rgba(255, 255, 255, .95);
149
+    box-sizing: border-box;
150
+  }
151
+}

+ 69
- 0
src/components/add-tips/index.js Просмотреть файл

@@ -0,0 +1,69 @@
1
+
2
+const STORAGE_KEY = 'PLUG-ADD-MYAPP-KEY'
3
+Component({
4
+  properties: {
5
+    name: {
6
+      type: String,
7
+      value: '测试'
8
+    },
9
+    duration: {
10
+      type: Number,
11
+      value: 10
12
+    },
13
+    delay: {
14
+      type: Number,
15
+      value: 2
16
+    },
17
+    logo: {
18
+      type: String,
19
+      value: 'https://cdn.blog.makergyt.com/mini/assets/component-add_tips.png'
20
+    },
21
+    custom: {
22
+      type: Boolean,
23
+      value: false
24
+    }
25
+  },
26
+  lifetimes: {
27
+    attached: function () {
28
+      if (wx.getStorageSync(STORAGE_KEY)) return;
29
+      let rect = wx.getMenuButtonBoundingClientRect ? wx.getMenuButtonBoundingClientRect() : null
30
+      let { screenWidth } = wx.getSystemInfoSync()
31
+      this.setData({
32
+        navbarHeight: rect.bottom,
33
+        arrowR: screenWidth - rect.right + rect.width * 3 / 4 - 5,
34
+        bodyR: screenWidth - rect.right
35
+      })
36
+      this.startTimer = setTimeout(() => {
37
+        this.setData({
38
+          SHOW_TOP: true
39
+        })
40
+      }, this.data.delay * 1000)
41
+      this.duraTimer = setTimeout(() => {
42
+        this.shrink();
43
+      }, (this.data.duration + this.data.delay) * 1000)
44
+    },
45
+    detached: function () {
46
+      if (this.startTimer) clearTimeout(this.startTimer)
47
+      if (this.duraTimer) clearTimeout(this.duraTimer)
48
+    },
49
+  },
50
+  data: {
51
+    SHOW_TOP: false
52
+  },
53
+  methods: {
54
+    hidden: function () {
55
+      wx.setStorageSync(STORAGE_KEY, true)
56
+      this.shrink()
57
+    },
58
+    shrink: function () {
59
+      this.animate('#add-tips', [
60
+        { scale: [1, 1] },
61
+        { scale: [0, 0], ease: 'ease', transformOrigin: `calc(600rpx - ${this.data.arrowR}px) 1%` }
62
+      ], 500, function () {
63
+        this.setData({
64
+          SHOW_TOP: false
65
+        })
66
+      }.bind(this))
67
+    }
68
+  }
69
+})

+ 3
- 0
src/components/add-tips/index.json Просмотреть файл

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

+ 7
- 0
src/components/add-tips/index.wxml Просмотреть файл

@@ -0,0 +1,7 @@
1
+<view class="box" wx:if="{{SHOW_TOP}}" style="top:{{custom?navbarHeight:0}}px;" id="add-tips">
2
+  <view class='arrow' style="margin-right:{{arrowR}}px;"></view>
3
+  <view class='body' bindtap='hidden' style="margin-right:{{bodyR}}px;">
4
+    <image src="{{logo}}" class="logo"></image>
5
+    <view class="tips"></view>
6
+  </view>
7
+</view>

+ 49
- 0
src/components/add-tips/index.wxss Просмотреть файл

@@ -0,0 +1,49 @@
1
+.box {
2
+  position: fixed;
3
+  right: 0;
4
+  z-index: 999;
5
+  display: flex;
6
+  justify-content: flex-end;
7
+  align-items: flex-end;
8
+  flex-direction: column;
9
+  width: 600px;
10
+}
11
+.arrow {
12
+  width: 0;
13
+  height: 0;
14
+  border-width: 5px;
15
+  border-style: solid;
16
+  border-color: transparent transparent rgba(0, 0, 0, 0.75) transparent;
17
+}
18
+.body {
19
+  background-color: rgba(0, 0, 0, 0.75);
20
+  border-radius: 15px;
21
+  display: flex;
22
+  align-items: center;
23
+  justify-content: center;
24
+  height: 42px;
25
+  padding: 10px;
26
+  zoom: 1.5;
27
+}
28
+.tips {
29
+  height: 200px;
30
+  width: 200px;
31
+  flex: 1;
32
+  color: #fff;
33
+  font-size: 20px;
34
+  font-weight: 700;
35
+}
36
+.logo {
37
+  height: 200px;
38
+  width: 200px;
39
+  border-radius: 8px;
40
+  margin-right: 10px;
41
+}
42
+
43
+.button-view {
44
+  color: #04b040;
45
+  text-align: center;
46
+  font-size: 20px;
47
+  /* line-height: 22px; */
48
+  display: initial;
49
+}

+ 2
- 1
src/hotel/pages/landlord/landlord.jsx Просмотреть файл

@@ -5,6 +5,7 @@ import { getHotelManage, getNowHotelManage } from '@/services/landlord'
5 5
 import NoData from '@/components/NoData'
6 6
 import CustomNav from '@/components/CustomNav'
7 7
 import { withSubscribeMessage } from '@/utils/subscribeMessage'
8
+import { TPL_MESSAGE_HOTEL_CHECK_IN } from '@/utils/constants'
8 9
 import HouseManage from '../../components/HouseManage/houseManage'
9 10
 import Income from '../../components/Income/income'
10 11
 import tabList from './Roomtabbar'
@@ -45,7 +46,7 @@ export default withLayout((props) => {
45 46
   const handleTabChange = (e) => {
46 47
     const { index } = e.detail
47 48
     setCurrentTab(index)
48
-    withSubscribeMessage('hotel_check_in')
49
+    withSubscribeMessage(TPL_MESSAGE_HOTEL_CHECK_IN)
49 50
   }
50 51
 
51 52
   useEffect(() => {

+ 3
- 1
src/layouts/Loading.jsx Просмотреть файл

@@ -22,7 +22,9 @@ export default (props) => {
22 22
           position: 'absolute',
23 23
           left: '-4vh',
24 24
           textAlign: 'center',
25
-          opacity: '0.8'
25
+          opacity: '0.8',
26
+          animation: ' logo-opacity 2s linear infinite',
27
+
26 28
         }}
27 29
       >
28 30
         收集人间美好

+ 2
- 3
src/pages/MineUserAll/RefundMoney/CheckRefund/style.less Просмотреть файл

@@ -18,7 +18,6 @@
18 18
       .title-title-boss {
19 19
         font-size: 32px;
20 20
         font-weight: 800;
21
-
22 21
       }
23 22
     }
24 23
   }
@@ -66,7 +65,7 @@
66 65
       color: #ff3434;
67 66
     }
68 67
   }
69
-  
68
+
70 69
   .ul-li-text {
71 70
     .ul-li-view {
72 71
       display: inline-block;
@@ -89,7 +88,7 @@
89 88
       margin-top: 60px;
90 89
       height: 92px;
91 90
       line-height: 92px;
92
-      background: #1A3B83;      
91
+      background: #1a3b83;
93 92
       border-radius: 12px;
94 93
       color: @whiteColor;
95 94
       font-size: 30px;

+ 2
- 1
src/pages/RoomOrder/index.jsx Просмотреть файл

@@ -4,6 +4,7 @@ import CustomNav from '@/components/CustomNav'
4 4
 import withLayout from '@/layouts'
5 5
 import { getTaRoom, goToRoomForm, personSubmit } from '@/services/taRoom​'
6 6
 import { withSubscribeMessage } from "@/utils/subscribeMessage"
7
+import { TPL_MESSAGE_HOTEL_CHECK_OUT } from '@/utils/constants'
7 8
 import RoomForm from './components/RoomForm'
8 9
 import './style.less'
9 10
 
@@ -25,7 +26,7 @@ export default withLayout((props) => {
25 26
   const handleSubmit = (e) => {
26 27
 
27 28
     // 订阅消息
28
-    withSubscribeMessage('hotel_check_out', () => {
29
+    withSubscribeMessage(TPL_MESSAGE_HOTEL_CHECK_OUT, () => {
29 30
       for (let i = 0, len = formData.length; i < len; i++) {
30 31
         const item = formData[i];
31 32
         if (!item.customerName || !item.customerPhone) {

+ 60
- 20
src/pages/TobeShop/index.jsx Просмотреть файл

@@ -7,6 +7,7 @@ import { getShopDetail, getShopPackage, getExtendContent } from '@/services/home
7 7
 import { getVerifyTargetList, putVerifyTarget } from "@/services/payOrder";
8 8
 import formatTime from '@/utils/formatTime'
9 9
 import Popup from "@/components/Popup";
10
+import SpinBox from "@/components/Spin/SpinBox";
10 11
 import formatPrice from "@/utils/formatPrice";
11 12
 
12 13
 import LocationBig from "@/assets/icons/UserCenter/LocationBig.png";
@@ -22,13 +23,15 @@ import "./style.less";
22 23
 export default withLayout((props) => {
23 24
   const { router, person, location } = props;
24 25
   const { id, subOrderId } = props.router.params;
26
+  const [submiting, setSubmiting] = useState(false)
25 27
   const [showDialog, setShowDialog] = useState(false);
26 28
   //核销
27 29
   const [Consumption, setConsumption] = useState(false);
28 30
 
29
-  const [checked, setChecked] = useState();
31
+  const [checked, setChecked] = useState([]);
30 32
   const [shopContent, setShopContent] = useState([])
31 33
 
34
+  const [loading, setLoading] = useState(false)
32 35
   const [list, setList] = useState([]);
33 36
 
34 37
 
@@ -40,6 +43,7 @@ export default withLayout((props) => {
40 43
   }
41 44
 
42 45
   const getList = (params) => {
46
+    setLoading(true)
43 47
     getVerifyTargetList({
44 48
       shopId: id,
45 49
       isMine: true,
@@ -50,39 +54,73 @@ export default withLayout((props) => {
50 54
       if (res) {
51 55
         setList(res.records)
52 56
 
53
-        setChecked(res?.records.filter(x => x.subOrderId == subOrderId)[0]?.verifyNo)
54
-
55
-        // if(item.verifyNo==checked)
57
+        if (res.records && res.records.length > 0) {
58
+          if (res.records.length === 1) {
59
+            setChecked([res.records[0].verifyNo])
60
+          } else {
61
+            setChecked([res?.records.filter(x => x.subOrderId == subOrderId)[0]?.verifyNo].filter(Boolean))
62
+          }
63
+        } else {
64
+          Taro.navigateBack({ delta: 1 })
65
+        }
56 66
       }
57 67
 
58
-    });
68
+      setLoading(false)
69
+    }).catch(() => setLoading(false));
59 70
   };
60 71
 
61 72
   useEffect(() => {
62
-    getList();
63
-    getShop();
64
-  }, []);
73
+    if (id) {
74
+      getList();
75
+      getShop();
76
+    }
77
+  }, [id]);
78
+
79
+  const handleCheck = (verifyNo) => {
80
+    const inx = checked.indexOf(verifyNo)
81
+    if (inx === -1) {
82
+      setChecked([...checked, verifyNo])
83
+    } else {
84
+      const p1 = checked.slice(0, inx)
85
+      const p2 = checked.slice(inx + 1)
86
+      setChecked(p1.concat(p2))
87
+    }
88
+  }
89
+
90
+  const handleVerifyClick = () => {
91
+    if (!checked || !checked.length) {
92
+      Taro.showToast({
93
+        title: '请选择待核销套餐',
94
+        icon: 'none',
95
+      })
96
+
97
+      return;
98
+    }
65 99
 
66
-  const ShowMoldeOn = () => {
67 100
     setShowDialog(true);
68 101
   };
69 102
   const ButtonCancel = () => {
70 103
     setShowDialog(false);
71 104
   };
72 105
   const ButtonOK = (e) => {
73
-    if (!checked) return
74
-    if (showDialog === true) {
106
+    if (!submiting) {
75 107
       Taro.showLoading({
76 108
         title: '核销中'
77 109
       })
78 110
 
79
-      putVerifyTarget(checked).then(res => {
111
+      setSubmiting(true);
112
+      Promise.all(checked.map(verifyNo => putVerifyTarget(verifyNo)))
113
+      .then(res => {
80 114
         Taro.hideLoading()
115
+        setSubmiting(false);
81 116
         setShowDialog(false);
82 117
         setConsumption(true);
83
-      }).catch(e => {
118
+      })
119
+      .catch(e => {
84 120
         Taro.hideLoading()
85 121
         setShowDialog(false);
122
+        setSubmiting(false);
123
+        getList();  // 刷新数据
86 124
         Taro.showToast({
87 125
           title: '核销失败',
88 126
           icon: 'none',
@@ -101,6 +139,8 @@ export default withLayout((props) => {
101 139
     }
102 140
   };
103 141
 
142
+  const btnText = ['确认核销', checked && checked.length > 0  ? `(${checked.length})` : undefined].filter(Boolean).join(' ')
143
+
104 144
   return (
105 145
     <view className='shop-Eat'>      
106 146
       <view className='index-navbar'>
@@ -114,7 +154,7 @@ export default withLayout((props) => {
114 154
           <button className='button-Cancel' onClick={ButtonCancel}>
115 155
             取消
116 156
           </button>
117
-          <button className='button-OK' onClick={ButtonOK}>
157
+          <button className='button-OK' onClick={ButtonOK} loading={submiting}>
118 158
             确定
119 159
           </button>
120 160
         </view>
@@ -147,10 +187,10 @@ export default withLayout((props) => {
147 187
           />
148 188
           <text className='shop-title-title'>请选择你要核销的套餐</text>
149 189
         </view>
150
-        <view>
190
+        <SpinBox loading={loading}>
151 191
           {(list || []).map((item) => {
152 192
             return (
153
-              <view class='wrapper' key={item.verifyNo} onClick={() => setChecked(item.verifyNo)}>
193
+              <view class='wrapper' key={item.verifyNo} onClick={() => handleCheck(item.verifyNo)}>
154 194
                 <view class='left-complete-one'>
155 195
                   <image className='left-image-1' src={ProCard_hot}></image>
156 196
                   <view className='left-viewText'>返现¥{(item.cashback / 100).toFixed(2)}</view>
@@ -182,18 +222,18 @@ export default withLayout((props) => {
182 222
                 <view class='right-complete-two'>
183 223
                   <view className='right-content'>
184 224
                     <view className='Check_OK-box'>
185
-                      <image className='Check_OK-image' src={item.verifyNo == checked ? Check_OK : Check_NO} />
225
+                      <image className='Check_OK-image' src={checked.indexOf(item.verifyNo) > -1 ? Check_OK : Check_NO} />
186 226
                     </view>
187 227
                   </view>
188 228
                 </view>
189 229
               </view>
190 230
             );
191 231
           })}
192
-        </view>
232
+        </SpinBox>
193 233
 
194 234
         <view className='button-info'>
195
-          <Button className='button-box' disabled={!checked} onClick={ShowMoldeOn}>
196
-            确定核销
235
+          <Button className='button-box' onClick={handleVerifyClick}>
236
+            {btnText}
197 237
           </Button>
198 238
         </view>
199 239
       </view>

+ 10
- 8
src/pages/details/foodDetails/foodDetails.jsx Просмотреть файл

@@ -12,6 +12,7 @@ import { Button, Swiper, SwiperItem } from "@tarojs/components";
12 12
 import Star from "@/components/Star/Star.jsx";
13 13
 import NoData from '@/components/NoData'
14 14
 import Cards from "@/components/foodCards/foodCards.jsx";
15
+import SpinBox from "@/components/Spin/SpinBox";
15 16
 import ax from "@/assets/icons/housemantj/onlove.png";
16 17
 import yysj from "@/assets/icons/housemantj/openTime.png";
17 18
 import dw from "@/assets/icons/housemantj/loc.png";
@@ -48,6 +49,7 @@ export default withLayout((props) => {
48 49
   }, [id, scene, subOrderId]);
49 50
 
50 51
   //商铺基础信息
52
+  const [loading, setLoading] = useState(false)
51 53
   const [detail, setDetail] = useState({});
52 54
   //商铺套餐
53 55
   const [spackage, setPackage] = useState([]);
@@ -104,12 +106,14 @@ export default withLayout((props) => {
104 106
 
105 107
   useEffect(() => {
106 108
     if (id) {
109
+      setLoading(true)
107 110
       getShopDetail(id, { location }).then((res) => {
108 111
         setDetail(res);
109 112
         log.current = res.locaton.toString().split(",")[0];
110 113
         lat.current = res.locaton.toString().split(",")[1];
111 114
         setimglist(res.imageList || []);
112
-      });
115
+        setLoading(false)
116
+      }).catch(() => setLoading(false));
113 117
       getShopPackage(id).then((res) => {
114 118
         setPackage(res.records || []);
115 119
         setNewpgNum(res.records.length);
@@ -142,9 +146,7 @@ export default withLayout((props) => {
142 146
       <view className='index-navbar'>
143 147
         <CustomNav title='十公里' />
144 148
       </view>
145
-      <view
146
-        style={{ overflow: "hidden", padding: "0 30rpx", height: '100%', background: "#F8F8F8" }}
147
-      >
149
+      <SpinBox loading={loading} className='index-container' style={{ padding: '0 30rpx' }}>
148 150
         <scroll-view
149 151
           scrollY
150 152
           style={{ height: '100%' }}
@@ -156,8 +158,8 @@ export default withLayout((props) => {
156 158
               current={index}
157 159
               onChange={handchange}
158 160
             >
159
-              {imglist.map((item) => (
160
-                <SwiperItem>
161
+              {imglist.map((item, inx) => (
162
+                <SwiperItem key={inx}>
161 163
                   <image src={item.url} mode='aspectFit' className='storeImage'>
162 164
                     <view className='tpPage'>
163 165
                       <text>
@@ -269,8 +271,8 @@ export default withLayout((props) => {
269 271
               </>
270 272
           }
271 273
         </scroll-view>
272
-      </view>
273
-      <view className='bottomTab'>
274
+      </SpinBox>
275
+      <view className='bottomTab custom-tabbar'>
274 276
         <Button openType='share' className='sharebtn'>
275 277
           分享
276 278
         </Button>

+ 75
- 63
src/pages/details/foodDetails/foodDetails.less Просмотреть файл

@@ -1,73 +1,73 @@
1
-.storeDetails{
2
-  background-color: #fff;  
1
+.storeDetails {
2
+  background-color: #fff;
3 3
   border-radius: 12px;
4 4
   margin-bottom: 20px;
5 5
 
6
-  .swiper{
6
+  .swiper {
7 7
     height: calc((100vw - 60px) * 0.6);
8 8
   }
9
-  .storeImage{
9
+  .storeImage {
10 10
     position: relative;
11 11
     border-radius: 22px;
12 12
     width: 100%;
13 13
     height: 100%;
14
-    .tpPage{
14
+    .tpPage {
15 15
       position: absolute;
16 16
       right: 20px;
17 17
       bottom: 20px;
18 18
       background: #000000;
19
-      border-radius: 16px;  
20
-      font-size: 24px;       
21
-      color: #FFFFFF;
22
-      padding:0 7px;
23
-      opacity: 0.4;  
19
+      border-radius: 16px;
20
+      font-size: 24px;
21
+      color: #ffffff;
22
+      padding: 0 7px;
23
+      opacity: 0.4;
24 24
       line-height: 32px;
25 25
       padding: 7px 8px 8px 7px;
26
-      text{
26
+      text {
27 27
         opacity: 0.64;
28 28
       }
29 29
     }
30
-  }  
31
-  .storeJs{
30
+  }
31
+  .storeJs {
32 32
     padding: 20px;
33
-    .storeName{      
34
-      font-size: 32px;         
33
+    .storeName {
34
+      font-size: 32px;
35 35
       font-weight: bold;
36 36
       color: #202020;
37 37
     }
38
-    .sprice{
38
+    .sprice {
39 39
       color: #202020;
40
-      font-size: 32px;         
40
+      font-size: 32px;
41 41
       font-weight: bold;
42
-      .t1{        
42
+      .t1 {
43 43
         font-size: 24px;
44 44
         padding-right: 10px;
45 45
       }
46
-      .bzRight{        
46
+      .bzRight {
47 47
         font-weight: 400;
48 48
         font-size: 24px;
49 49
         float: right;
50 50
       }
51 51
     }
52
-    .appraise{
52
+    .appraise {
53 53
       line-height: 0;
54 54
       margin-top: 28px;
55 55
       margin-bottom: 37px;
56
-      font-size: 24px;         
56
+      font-size: 24px;
57 57
       font-weight: bold;
58 58
       color: #020200;
59
-      .t1{
59
+      .t1 {
60 60
         margin-left: 10px;
61 61
       }
62
-      .comment{
62
+      .comment {
63 63
         color: #666;
64 64
       }
65 65
     }
66
-    .yysj{
66
+    .yysj {
67 67
       line-height: 0;
68 68
       font-size: 24px;
69 69
       color: #666;
70
-      .yysjImg{
70
+      .yysjImg {
71 71
         width: 26px;
72 72
         height: 26px;
73 73
         position: relative;
@@ -75,50 +75,49 @@
75 75
         padding-right: 10px;
76 76
       }
77 77
     }
78
-    .dpPosition{
78
+    .dpPosition {
79 79
       margin-top: 40px;
80 80
       position: relative;
81
-      .dwTip{
81
+      .dwTip {
82 82
         width: 28px;
83 83
         height: 28px;
84 84
         position: absolute;
85 85
         top: 4px;
86
-        left:0;
86
+        left: 0;
87 87
       }
88
-      view{
89
-        font-size: 24px;         
88
+      view {
89
+        font-size: 24px;
90 90
         color: #666666;
91 91
         padding-left: 34px;
92 92
         padding-bottom: 40px;
93
-        .zhuandao{
93
+        .zhuandao {
94 94
           width: 14px;
95 95
           height: 24px;
96 96
           transform: rotate(180deg);
97 97
           position: relative;
98 98
           left: 8px;
99 99
           top: 5px;
100
-        }        
100
+        }
101 101
       }
102
-      
103 102
     }
104 103
   }
105 104
 }
106
-.title{
105
+.title {
107 106
   margin: 59px 0 41px 0;
108
-  image{
107
+  image {
109 108
     width: 30px;
110 109
     height: 30px;
111 110
     position: relative;
112 111
     top: 5px;
113 112
   }
114
-  text{
115
-    font-size: 34px;       
113
+  text {
114
+    font-size: 34px;
116 115
     font-weight: bold;
117 116
     color: #202020;
118 117
     margin-left: 10px;
119 118
   }
120 119
 }
121
-.cs{
120
+.cs {
122 121
   height: 500px;
123 122
   // background: rgb(240, 142, 142);
124 123
   // background: radial-gradient(circle at top left, transparent 15px, rgb(240, 142, 142) 0) top left,
@@ -126,66 +125,79 @@
126 125
   //           radial-gradient(circle at bottom left, transparent 15px, #58a 0) bottom left,
127 126
   //           radial-gradient(circle at bottom right, transparent 15px, #58a 0) bottom right;
128 127
 
128
+  background: radial-gradient(
129
+        circle at 82% top,
130
+        transparent 15px,
131
+        rgb(240, 140, 140) 0
132
+      )
133
+      top,
134
+    radial-gradient(
135
+        circle at 82% bottom,
136
+        transparent 15px,
137
+        rgb(230, 120, 120) 0
138
+      )
139
+      bottom;
129 140
 
130
-  background: radial-gradient(circle at 82% top,transparent 15px,rgb(240,140,140) 0) top,
131
-              radial-gradient(circle at 82% bottom,transparent 15px,rgb(230,120,120) 0) bottom;
132
-
133
-background-repeat: no-repeat;
134
-background-size: auto 50%;
141
+  background-repeat: no-repeat;
142
+  background-size: auto 50%;
135 143
 }
136 144
 
137
-.showMore{
145
+.showMore {
138 146
   width: 100%;
139
-  background: linear-gradient(0deg, rgba(248, 248, 248, 0.58) 42%, rgba(248, 248, 248, 0) 100%);
147
+  background: linear-gradient(
148
+    0deg,
149
+    rgba(248, 248, 248, 0.58) 42%,
150
+    rgba(248, 248, 248, 0) 100%
151
+  );
140 152
   font-size: 28px;
141 153
   font-weight: bold;
142 154
   color: #202020;
143 155
   text-align: center;
144 156
   position: absolute;
145
-  bottom: -100px;
157
+  bottom: -140px;
146 158
   padding-top: 77px;
147 159
   padding-bottom: 20px;
148
-  .moreTip{
160
+  .moreTip {
149 161
     width: 38px;
150 162
     height: 19px;
151 163
     margin-top: 14px;
152 164
   }
153 165
 }
154
-.storezn{
155
-  font-size: 28px;    
166
+.storezn {
167
+  font-size: 28px;
156 168
   color: #202020;
157 169
   line-height: 54px;
158 170
   margin-bottom: 44px;
159 171
 }
160
-.storezn+image{
172
+.storezn + image {
161 173
   width: 100%;
162 174
   margin-bottom: 40px;
163 175
 }
164 176
 
165
-.botton{
166
-  font-size: 28px;   
167
-  color: #C0C8D3;
177
+.botton {
178
+  font-size: 28px;
179
+  color: #c0c8d3;
168 180
   line-height: 34px;
169 181
   text-align: center;
170
-  padding:40px 0 68px 0;
171
-  background-color: #F8F8F8;
182
+  padding: 40px 0 68px 0;
183
+  background-color: #f8f8f8;
172 184
 }
173
-.bottomTab{
174
-  background: #FFF;
185
+.bottomTab {
186
+  background: #fff;
175 187
   border-radius: 12px;
176 188
   column-count: 3;
177
-  text-align: center;  
178
-  .sharebtn{
189
+  text-align: center;
190
+  .sharebtn {
179 191
     position: absolute;
180 192
     width: 260px;
181 193
     opacity: 0;
182 194
   }
183
-  .tab{
195
+  .tab {
184 196
     line-height: 96px;
185
-    font-size: 28px;     
197
+    font-size: 28px;
186 198
     font-weight: bold;
187 199
     color: #202020;
188
-    image{
200
+    image {
189 201
       width: 31px;
190 202
       height: 31px;
191 203
       position: relative;
@@ -193,4 +205,4 @@ background-size: auto 50%;
193 205
       margin-right: 12px;
194 206
     }
195 207
   }
196
-}
208
+}

+ 1
- 0
src/pages/index/index.config.js Просмотреть файл

@@ -11,5 +11,6 @@ export default {
11 11
     "mp-cells": "weui-miniprogram/cells/cells",
12 12
     "mp-dialog": "weui-miniprogram/dialog/dialog",
13 13
     "mp-slideview": "weui-miniprogram/slideview/slideview",
14
+    "add-tips": "../../components/add-tips/index"
14 15
   }
15 16
 }

+ 8
- 6
src/pages/index/index.jsx Просмотреть файл

@@ -1,17 +1,18 @@
1 1
 
2 2
 
3 3
 import React, { useState, useEffect } from 'react'
4
-import { useDidShow } from '@tarojs/taro'
4
+import Taro, { useDidShow } from '@tarojs/taro'
5 5
 import CustomNav from '@/components/CustomNav'
6 6
 import logo from '@/assets/icons/comm/logo_small.png'
7 7
 import { getHotelDetail } from '@/services/landlord'
8 8
 import { getTaRoom } from '@/services/taRoom​'
9 9
 import withLayout from '@/layouts'
10
+import { withSubscribeMessage } from '@/utils/subscribeMessage'
11
+import { TPL_MESSAGE_HOTEL_CHECK_OUT } from '@/utils/constants'
10 12
 import tabList from './tabbar'
11 13
 import Guide from './tabs/Guide'
12 14
 import Mine from './tabs/Mine'
13 15
 import Recommend from './tabs/Recommend'
14
-import { withSubscribeMessage } from '@/utils/subscribeMessage'
15 16
 import './index.less'
16 17
 
17 18
 
@@ -40,7 +41,7 @@ export default withLayout((props) => {
40 41
     setCurrentTab(index)
41 42
 
42 43
     if (index === 1) {
43
-      withSubscribeMessage('hotel_check_out')
44
+      withSubscribeMessage(TPL_MESSAGE_HOTEL_CHECK_OUT)
44 45
     }
45 46
   }
46 47
   useEffect(() => {
@@ -49,9 +50,7 @@ export default withLayout((props) => {
49 50
     }
50 51
   }, [tab])
51 52
 
52
-  useEffect(() => {
53 53
 
54
-  }, [])
55 54
 
56 55
   useEffect(() => {
57 56
     if (roomId) {
@@ -72,9 +71,12 @@ export default withLayout((props) => {
72 71
 
73 72
   }, [roomId, hotelId])
74 73
 
75
-
76 74
   return (
77 75
     <view className='page-index'>
76
+      <add-tips
77
+        logo={logo}
78
+        custom
79
+        duration={-1} />
78 80
       <view className='index-navbar'>
79 81
         <CustomNav logo={titleLogo} title={titleRoom} />
80 82
       </view>

+ 4
- 3
src/shop/pages/spread/spreadIndex.jsx Просмотреть файл

@@ -2,9 +2,9 @@ import React, { useState, useEffect, useRef } from 'react'
2 2
 import CustomNav from '@/components/CustomNav'
3 3
 import { useRouter } from '@tarojs/taro'
4 4
 import { getShopList, getShopMoney, getAccount, getVerifiedOrder, setGetVerifiedOrder } from '@/services/shopBoss'
5
-
6
-
5
+import { withSubscribeMessage } from '@/utils/subscribeMessage'
7 6
 import withLayout from '@/layouts'
7
+import { TPL_MESSAGE_SHOP_PAY_SUCCESS } from '@/utils/constants'
8 8
 import tabList from './Shoptabbar'
9 9
 import ShopKeeper from '../../components/ShopKeeper/shopKeeper'
10 10
 import Sparead from '../../components/Sparead/spreadMoney'
@@ -36,8 +36,9 @@ export default withLayout((props) => {
36 36
     //如果context有的话代表他滚动了   那么切换tab页就置顶
37 37
     if (listRef.current?.context) {
38 38
       listRef.current.context.scrollTo({ top: 0 })
39
-
40 39
     }
40
+
41
+    withSubscribeMessage(TPL_MESSAGE_SHOP_PAY_SUCCESS)
41 42
   }
42 43
   const handelTypeOrder = () => {
43 44
 

+ 4
- 0
src/utils/constants.js Просмотреть файл

@@ -0,0 +1,4 @@
1
+
2
+export const TPL_MESSAGE_HOTEL_CHECK_IN = "hotel_check_in";       // 民宿入住消息
3
+export const TPL_MESSAGE_HOTEL_CHECK_OUT = "hotel_check_out";     // 民宿离店消息
4
+export const TPL_MESSAGE_SHOP_PAY_SUCCESS = "shop_pay_success";   // 商铺下单成功通知

+ 0
- 38
src/utils/copyTxt.js Просмотреть файл

@@ -1,38 +0,0 @@
1
-
2
-export default function copyTxt(text, fn) { // 复制功能
3
-  if (typeof document.execCommand !== 'function') {
4
-    console.log('复制失败,请长按复制')
5
-    return
6
-  }
7
-  var dom = document.createElement('textarea')
8
-  dom.value = text
9
-  dom.setAttribute('style', 'display: block;width: 1px;height: 1px;')
10
-  document.body.appendChild(dom)
11
-  dom.select()
12
-  var result = document.execCommand('copy')
13
-  document.body.removeChild(dom)
14
-  if (result) {
15
-    console.log('复制成功')
16
-    typeof fn === 'function' && fn()
17
-    return
18
-  }
19
-  if (typeof document.createRange !== 'function') {
20
-    console.log('复制失败,请长按复制')
21
-    return
22
-  }
23
-  var range = document.createRange()
24
-  var div = document.createElement('div')
25
-  div.innerhtml = text
26
-  div.setAttribute('style', 'height: 1px;fontSize: 1px;overflow: hidden;')
27
-  document.body.appendChild(div)
28
-  range.selectNode(div)
29
-  var selection = window.getSelection()
30
-  console.log(selection)
31
-  if (selection.rangeCount > 0) {
32
-    selection.removeAllRanges()
33
-  }
34
-  selection.addRange(range)
35
-  document.execCommand('copy')
36
-  typeof fn === 'function' && fn()
37
-  console.log('复制成功')
38
-}