xiongzhu 5 жил өмнө
parent
commit
c8e5eb6f52

+ 1 - 1
.env.production

@@ -1 +1 @@
-VUE_APP_BASE_URL=https://mr.1meter.world
+VUE_APP_BASE_URL=https://jiashanxia.izouma.com

+ 148 - 140
project.config.json

@@ -1,152 +1,160 @@
 {
-  "description": "项目配置文件",
-  "packOptions": {
-    "ignore": []
-  },
-  "setting": {
-    "urlCheck": false,
-    "es6": true,
-    "enhance": false,
-    "postcss": true,
-    "preloadBackgroundData": false,
-    "minified": true,
-    "newFeature": true,
-    "coverView": true,
-    "nodeModules": false,
-    "autoAudits": false,
-    "showShadowRootInWxmlPanel": true,
-    "scopeDataCheck": false,
-    "uglifyFileName": false,
-    "checkInvalidKey": true,
-    "checkSiteMap": true,
-    "uploadWithSourceMap": true,
-    "compileHotReLoad": false,
-    "useMultiFrameRuntime": false,
-    "useApiHook": true,
-    "babelSetting": {
-      "ignore": [],
-      "disablePlugins": [],
-      "outputPath": ""
+    "description": "项目配置文件",
+    "packOptions": {
+        "ignore": []
     },
-    "enableEngineNative": false,
-    "useIsolateContext": true,
-    "useCompilerModule": true,
-    "userConfirmedUseCompilerModuleSwitch": false,
-    "packNpmManually": false,
-    "packNpmRelationList": [],
-    "minifyWXSS": true
-  },
-  "compileType": "miniprogram",
-  "libVersion": "2.11.0",
-  "appid": "wxde386c1d6f9fc0c8",
-  "projectname": "%E7%94%B2%E5%B1%B1%E4%B8%8B",
-  "cloudfunctionTemplateRoot": "",
-  "watchOptions": {
-    "ignore": []
-  },
-  "debugOptions": {
-    "hidedInDevtools": []
-  },
-  "scripts": {},
-  "simulatorType": "wechat",
-  "simulatorPluginLibVersion": {},
-  "condition": {
-    "search": {
-      "list": []
-    },
-    "conversation": {
-      "list": []
-    },
-    "plugin": {
-      "list": []
+    "setting": {
+        "urlCheck": false,
+        "es6": true,
+        "enhance": false,
+        "postcss": true,
+        "preloadBackgroundData": false,
+        "minified": true,
+        "newFeature": true,
+        "coverView": true,
+        "nodeModules": false,
+        "autoAudits": false,
+        "showShadowRootInWxmlPanel": true,
+        "scopeDataCheck": false,
+        "uglifyFileName": false,
+        "checkInvalidKey": true,
+        "checkSiteMap": true,
+        "uploadWithSourceMap": true,
+        "compileHotReLoad": false,
+        "useMultiFrameRuntime": false,
+        "useApiHook": true,
+        "babelSetting": {
+            "ignore": [],
+            "disablePlugins": [],
+            "outputPath": ""
+        },
+        "enableEngineNative": false,
+        "useIsolateContext": true,
+        "useCompilerModule": true,
+        "userConfirmedUseCompilerModuleSwitch": false,
+        "packNpmManually": false,
+        "packNpmRelationList": [],
+        "minifyWXSS": true
     },
-    "game": {
-      "list": []
+    "compileType": "miniprogram",
+    "libVersion": "2.11.0",
+    "appid": "wxde386c1d6f9fc0c8",
+    "projectname": "%E7%94%B2%E5%B1%B1%E4%B8%8B",
+    "cloudfunctionTemplateRoot": "",
+    "watchOptions": {
+        "ignore": []
     },
-    "gamePlugin": {
-      "list": []
+    "debugOptions": {
+        "hidedInDevtools": []
     },
-    "miniprogram": {
-      "list": [
-        {
-          "id": -1,
-          "name": "详情",
-          "pathName": "pages/detail",
-          "scene": null
-        },
-        {
-          "id": -1,
-          "name": "关于",
-          "pathName": "pages/about",
-          "scene": null
-        },
-        {
-          "id": -1,
-          "name": "我的",
-          "pathName": "pages/my",
-          "scene": null
-        },
-        {
-          "id": -1,
-          "name": "支付",
-          "pathName": "pages/pay",
-          "scene": null
-        },
-        {
-          "id": -1,
-          "name": "vip",
-          "pathName": "pages/vip",
-          "scene": null
-        },
-        {
-          "id": -1,
-          "name": "登录",
-          "pathName": "pages/login",
-          "scene": null
-        },
-        {
-          "id": -1,
-          "name": "资料编辑",
-          "pathName": "pages/profile",
-          "scene": null
-        },
-        {
-          "id": -1,
-          "name": "我的佣金",
-          "pathName": "pages/commission",
-          "scene": null
+    "scripts": {},
+    "simulatorType": "wechat",
+    "simulatorPluginLibVersion": {},
+    "condition": {
+        "search": {
+            "list": []
         },
-        {
-          "id": -1,
-          "name": "我的推广",
-          "pathName": "pages/promote",
-          "scene": null
+        "conversation": {
+            "list": []
         },
-        {
-          "id": -1,
-          "name": "提现",
-          "pathName": "pages/withdraw",
-          "scene": null
+        "plugin": {
+            "list": []
         },
-        {
-          "id": -1,
-          "name": "订单",
-          "pathName": "pages/order",
-          "scene": null
+        "game": {
+            "list": []
         },
-        {
-          "id": -1,
-          "name": "订单详情",
-          "pathName": "pages/orderDetail",
-          "scene": null
+        "gamePlugin": {
+            "list": []
         },
-        {
-          "id": -1,
-          "name": "余额记录",
-          "pathName": "pages/record",
-          "scene": null
+        "miniprogram": {
+            "list": [
+                {
+                    "id": -1,
+                    "name": "分享",
+                    "pathName": "pages/home",
+                    "scene": null,
+                    "query": "invitor=68"
+                },
+                {
+                    "id": -1,
+                    "name": "详情",
+                    "pathName": "pages/detail",
+                    "scene": null,
+                    "query": "id=17"
+                },
+                {
+                    "id": -1,
+                    "name": "关于",
+                    "pathName": "pages/about",
+                    "scene": null
+                },
+                {
+                    "id": -1,
+                    "name": "我的",
+                    "pathName": "pages/my",
+                    "scene": null
+                },
+                {
+                    "id": -1,
+                    "name": "支付",
+                    "pathName": "pages/pay",
+                    "scene": null
+                },
+                {
+                    "id": -1,
+                    "name": "vip",
+                    "pathName": "pages/vip",
+                    "scene": null
+                },
+                {
+                    "id": -1,
+                    "name": "登录",
+                    "pathName": "pages/login",
+                    "scene": null
+                },
+                {
+                    "id": -1,
+                    "name": "资料编辑",
+                    "pathName": "pages/profile",
+                    "scene": null
+                },
+                {
+                    "id": -1,
+                    "name": "我的佣金",
+                    "pathName": "pages/commission",
+                    "scene": null
+                },
+                {
+                    "id": -1,
+                    "name": "我的推广",
+                    "pathName": "pages/promote",
+                    "scene": null
+                },
+                {
+                    "id": -1,
+                    "name": "提现",
+                    "pathName": "pages/withdraw",
+                    "scene": null
+                },
+                {
+                    "id": -1,
+                    "name": "订单",
+                    "pathName": "pages/order",
+                    "scene": null
+                },
+                {
+                    "id": -1,
+                    "name": "订单详情",
+                    "pathName": "pages/orderDetail",
+                    "scene": null
+                },
+                {
+                    "id": -1,
+                    "name": "余额记录",
+                    "pathName": "pages/record",
+                    "scene": null
+                }
+            ]
         }
-      ]
     }
-  }
-}
+}

+ 8 - 3
src/App.vue

@@ -1,13 +1,18 @@
 <script>
 export default {
     onLaunch(options) {
+        console.log(options);
         wx.login({
             success: res => {
                 new Promise((resolve, reject) => {
+                    let data = { code: res.code };
+                    if (options.query.invitor) {
+                        data.parent = options.query.invitor;
+                    }
                     wx.request({
                         method: 'post',
                         url: this.$http.parseUrl('/auth/maLogin'),
-                        data: { code: res.code },
+                        data: data,
                         dataType: 'json',
                         header: {
                             Accept: 'application/json',
@@ -26,7 +31,7 @@ export default {
                     });
                 })
                     .then(res => {
-                        this.$http.setToken(res.token);
+                        this.$http.token = res.token;
                         this.$store.commit('setSessionKey', res.sessionKey);
                         this.$http.get('/user/my').then(res => {
                             this.$store.commit('setUserInfo', res);
@@ -39,7 +44,7 @@ export default {
                     });
 
                 // this.$http.post('/auth/maLogin', { code: res.code }).then(res => {
-                //     this.$http.setToken(res.token);
+                //     this.$http.token = res.token;
                 //     this.$store.commit('setSessionKey', res.sessionKey);
                 //     this.$http.get('/user/my').then(res => {
                 //         this.$store.commit('setUserInfo', res);

+ 2 - 2
src/main.js

@@ -29,8 +29,8 @@ Vue.mixin({
         share() {
             return {
                 title: '甲山下',
-                path: 'pages/home',
-                imageUrl: 'https://mr-yimishijie.oss-cn-hangzhou.aliyuncs.com/share.png'
+                path: 'pages/home?invitor=' + this.$store.state.userInfo.id,
+                imageUrl: 'https://jiashanxia.oss-cn-hangzhou.aliyuncs.com/image/2020-11-30-15-41-01dgYYeraK.png'
             };
         },
         navigateTo(url) {

+ 1 - 1
src/native/components/priceTag/priceTag.js

@@ -38,7 +38,7 @@ Component({
                 let fraction = '.00';
                 let number = 0;
                 if (typeof newVal === 'number') {
-                    number = number || 0;
+                    number = newVal || 0;
                 } else {
                     number = Number(newVal) || 0;
                 }

+ 38 - 18
src/pages/detail.vue

@@ -17,28 +17,25 @@
         :bounces="false"
     >
         <div class="page-scroll">
-            <div class="cover">
-                <img
-                    class="cover-img"
-                    mode="aspectFill"
-                    src="https://jiashanxia.oss-cn-hangzhou.aliyuncs.com/image/xiangqing01_img_01%402x.png"
-                />
-            </div>
+            <swiper class="cover">
+                <swiper-item v-for="item in packageInfo.img" :key="item">
+                    <img class="cover-img" mode="aspectFill" :src="item" />
+                </swiper-item>
+            </swiper>
             <div class="bg"></div>
             <div class="title">
-                <div class="content">甲山下游玩会员套餐A</div>
+                <div class="content">{{ packageInfo.name }}</div>
                 <button class="btn-share" open-type="share">
                     <img src="../static/imgs/icon_share.png" class="icon-share" />
                 </button>
             </div>
-            <div class="desc">599元购买价值3999元景区</div>
+            <div class="desc">{{ packageInfo.title }}</div>
             <div class="price">
                 <price-tag color="red" value="599"></price-tag>
             </div>
             <div class="feature">
                 <div class="label">特点</div>
-                <div class="tag">会员套餐</div>
-                <div class="tag">可多次使用</div>
+                <div class="tag" v-for="item in packageInfo.tag" :key="item">{{ item }}</div>
             </div>
             <div class="card">
                 <div class="card-title">套餐内容</div>
@@ -48,18 +45,18 @@
                         <div class="col2">数量</div>
                         <div class="col3">零售价</div>
                     </div>
-                    <div class="row" v-for="n in 10" :key="n">
-                        <div class="col1">大锅灶/烧烤套餐</div>
-                        <div class="col2">1套</div>
+                    <div class="row" v-for="item in packageGoods" :key="item.id">
+                        <div class="col1">{{ item.name }}</div>
+                        <div class="col2">{{ item.num }}{{ item.unit }}</div>
                         <div class="col3">
-                            <price-tag color="black" size="22" value="500"></price-tag>
+                            <price-tag color="black" size="22" :value="item.price"></price-tag>
                         </div>
                     </div>
                     <div class="row" style="margin-bottom: 0;">
                         <div class="col1">零售价合计</div>
                         <div class="col2"></div>
                         <div class="col3">
-                            <price-tag color="red" size="22" value="500"></price-tag>
+                            <price-tag color="red" size="22" :value="sum"></price-tag>
                         </div>
                     </div>
                 </div>
@@ -71,6 +68,7 @@
                 </div>
             </div>
             <div class="tip">温馨提示:由于会员套餐特殊性,出售后不可退款!</div>
+            <div style="height:70px"></div>
         </div>
         <navigation-bar :color="style" :title="transparent ? '' : title" :transparent="transparent"></navigation-bar>
         <div class="bottom-wrapper">
@@ -86,9 +84,26 @@ export default {
         return {
             title: '甲山下游玩会员套餐A',
             style: 'dark',
-            transparent: true
+            transparent: true,
+            packageInfo: {
+                img: []
+            },
+            packageGoods: []
         };
     },
+    onShow() {
+        this.$http.get(`/package/get/${this.$mp.query.id}`).then(res => {
+            this.packageInfo = res;
+        });
+        this.$http.postJson('/packageGoods/all', { size: 10000, query: { packageId: this.$mp.query.id } }).then(res => {
+            this.packageGoods = res.content;
+        });
+    },
+    computed: {
+        sum() {
+            return this.packageGoods.map(i => i.price).reduce((a, b) => a + b, 0);
+        }
+    },
     methods: {
         chngeNavi() {
             if (this.style === 'light') {
@@ -111,7 +126,11 @@ export default {
         buy() {
             if (this.checkLogin()) {
                 wx.navigateTo({
-                    url: '/pages/pay'
+                    url: '/pages/pay',
+                    events: {},
+                    success: res => {
+                        res.eventChannel.emit('packageInfo', this.packageInfo);
+                    }
                 });
             }
         }
@@ -124,6 +143,7 @@ export default {
 <style lang="less">
 .cover {
     position: relative;
+    height: 100vw;
     .cover-img {
         width: 100vw;
         height: 100vw;

+ 17 - 14
src/pages/home.vue

@@ -51,19 +51,14 @@
                 </div>
             </div>
             <div class="page-title">超值套餐</div>
-            <div class="card" @click="detail">
-                <img
-                    src="https://jiashanxia.oss-cn-hangzhou.aliyuncs.com/image/home_taocan_img_01%403x.png"
-                    mode="aspectFill"
-                    class="cover"
-                />
-                <div class="name">甲山下游玩会员套餐A</div>
-                <div class="desc">599元购买价值3999元景区</div>
+            <div class="card" v-for="item in packages" :key="item.id" @click="detail(item)">
+                <img :src="item.img[0]" mode="aspectFill" class="cover" />
+                <div class="name">{{ item.name }}</div>
+                <div class="desc">{{ item.title }}</div>
                 <div class="info">
-                    <div class="tag">会员套餐</div>
-                    <div class="tag">可多次使用</div>
+                    <div class="tag" v-for="(tag, t) in item.tag" :key="t">{{ tag }}</div>
                     <div class="price">
-                        <price-tag class="price" value="599"></price-tag>
+                        <price-tag class="price" :value="item.amount"></price-tag>
                     </div>
                 </div>
             </div>
@@ -74,6 +69,13 @@
 export default {
     onShow() {
         this.$mp.page.getTabBar().setData({ selected: 0 });
+        let type = 'PERSONAL';
+        if (this.$mp.query.scene) {
+            type = this.$mp.query.scene;
+        }
+        this.$http.postJson('/package/all', { size: 10000, query: { type } }).then(res => {
+            this.packages = res.content;
+        });
     },
     data() {
         return {
@@ -81,16 +83,17 @@ export default {
             banners: [
                 'https://jiashanxia.oss-cn-hangzhou.aliyuncs.com/image/home_topbanner_01%402x.png',
                 'https://jiashanxia.oss-cn-hangzhou.aliyuncs.com/image/home_taocan_img_01%403x.png'
-            ]
+            ],
+            packages: []
         };
     },
     methods: {
         onSwiperChange(e) {
             this.swiperIndex = e.detail.current;
         },
-        detail() {
+        detail(item) {
             wx.navigateTo({
-                url: '/pages/detail'
+                url: '/pages/detail?id=' + item.id
             });
         }
     }

+ 3 - 3
src/pages/my.vue

@@ -57,14 +57,14 @@
                         </div>
                     </div>
                 </div>
-                <div class="vip" @click="navigateTo('/pages/vip')">
+                <div class="vip" v-else @click="navigateTo('/pages/vip')">
                     <img src="../static/imgs/bg_vip.png" class="bg" mode="widthFix" />
                     <div class="btn">查看详情</div>
                 </div>
                 <div class="row">
-                    <div class="col" style="background: #fff4e3;">
+                    <div class="col" style="background: #fff4e3;" @click="order">
                         <img src="../static/imgs/icon_order.png" class="icon" />
-                        <div class="info" @click="order">
+                        <div class="info">
                             <div class="label">我的订单</div>
                             <div class="desc">2个订单</div>
                         </div>

+ 108 - 9
src/pages/order.vue

@@ -18,10 +18,10 @@
                 </van-tabs>
             </van-sticky>
             <div class="list">
-                <div class="item" v-for="n in 10" :key="n">
+                <div class="item" v-for="item in orders" :key="item.id" @click="detail(item)">
                     <div class="title">
                         <div class="name">超值套餐</div>
-                        <div class="status">待付款</div>
+                        <div class="status">{{ status(item) }}</div>
                     </div>
                     <div class="info">
                         <img
@@ -30,12 +30,12 @@
                             mode="aspectFill"
                         />
                         <div class="content">
-                            <div class="name">甲山下游玩会员套餐A</div>
+                            <div class="name">{{ item.name }}</div>
                             <div class="numbers">
                                 <div class="price">
                                     <span style="font-size: 12px;">¥</span>
-                                    <span>599</span>
-                                    <span style="font-size: 12px;">.00</span>
+                                    <span>{{ integer(item) }}</span>
+                                    <span style="font-size: 12px;">.{{ fraction(item) }}</span>
                                 </div>
                                 <div class="num">×1</div>
                             </div>
@@ -45,26 +45,125 @@
                         <div style="margin-right: 4px; margin-top: 2px;">总金额</div>
                         <price-tag color="black" size="22" value="599"></price-tag>
                     </div>
-                    <div class="btns">
-                        <div class="btn btn-cancel">取消订单</div>
-                        <div class="btn btn-pay">立即支付</div>
+                    <div class="btns" v-if="item.status !== 'CANCELLED'">
+                        <div class="btn btn-cancel" @click.stop="cancel(item)" v-if="item.status === 'UNPAID'">
+                            取消订单
+                        </div>
+                        <div class="btn btn-pay" @click.stop="pay(item)" v-if="item.status === 'UNPAID'">立即支付</div>
+                        <div class="btn btn-cancel" v-if="item.status !== 'UNPAID' && item.status !== 'CANCELLED'">
+                            查看详情
+                        </div>
                     </div>
                 </div>
             </div>
         </div>
+        <van-dialog id="van-dialog"></van-dialog>
     </div>
 </template>
 <script>
 export default {
     data() {
         return {
-            tab: 'all'
+            tab: 'all',
+            orders: [],
+            orderStatus: [
+                { label: '待支付', value: 'UNPAID' },
+                { label: '已完成', value: 'PAID' },
+                { label: '已取消', value: 'CANCELLED' },
+                { label: '已完成', value: 'OFFLINE_PAID' }
+            ]
         };
     },
+    onShow() {
+        this.getData();
+    },
     methods: {
+        getData() {
+            this.$http
+                .postJson('/orderInfo/all', {
+                    size: 10000,
+                    query: {
+                        userId: this.$store.state.userInfo.id
+                    },
+                    sort: 'createdAt,desc'
+                })
+                .then(res => {
+                    this.orders = res.content;
+                });
+        },
         tabChange(e) {
             console.log(e);
             this.tab = e.detail.name;
+        },
+        detail(item) {
+            this.navigateTo(`/pages/orderDetail?id=` + item.id);
+        },
+        status(item) {
+            return (this.orderStatus.find(i => i.value === item.status) || {}).label;
+        },
+        integer(item) {
+            return item.price.toFixed(2).split('.')[0];
+        },
+        fraction(item) {
+            return item.price.toFixed(2).split('.')[1];
+        },
+        cancel(item) {
+            this.$dialog
+                .confirm({
+                    title: '提示',
+                    message: '确定取消订单?'
+                })
+                .then(() => {
+                    wx.showLoading({
+                        title: ''
+                    });
+                    this.$http.post('/orderInfo/cancel', { orderId: item.id }).then(res => {
+                        wx.hideLoading();
+                        wx.showToast({
+                            icon: 'none',
+                            title: '订单已取消'
+                        });
+                        item.status = 'CANCELLED';
+                    });
+                })
+                .catch(() => {
+                    // on cancel
+                });
+        },
+        pay(item) {
+            wx.showLoading({
+                title: '加载中'
+            });
+            this.$http
+                .get('/pay/wx', { orderId: item.id })
+                .then(res => {
+                    res.package = res.packageValue;
+                    wx.requestPayment({
+                        ...res,
+                        success: () => {
+                            wx.hideLoading();
+                            wx.showToast({
+                                title: '支付成功'
+                            });
+                            this.getData();
+                        },
+                        fail: e => {
+                            console.log(e);
+                            wx.hideLoading();
+                            wx.showToast({
+                                icon: 'none',
+                                title: '支付失败'
+                            });
+                        }
+                    });
+                })
+                .catch(e => {
+                    wx.hideLoading();
+                    wx.showToast({
+                        title: e.error,
+                        icon: 'none'
+                    });
+                });
         }
     }
 };

+ 103 - 26
src/pages/orderDetail.vue

@@ -11,20 +11,16 @@
     <div class="page-container">
         <div class="page-scroll">
             <div class="container">
-                <div class="status">待支付</div>
+                <div class="status">{{ status }}</div>
                 <div class="info">
-                    <img
-                        class="cover"
-                        src="https://jiashanxia.oss-cn-hangzhou.aliyuncs.com/image/home_topbanner_01%402x.png"
-                        mode="aspectFill"
-                    />
+                    <img class="cover" :src="((packageInfo || {}).img || [])[0]" mode="aspectFill" />
                     <div class="content">
-                        <div class="name">甲山下游玩会员套餐A</div>
+                        <div class="name">{{ packageInfo.name }}</div>
                         <div class="numbers">
                             <div class="price">
                                 <span style="font-size: 12px;">¥</span>
-                                <span>599</span>
-                                <span style="font-size: 12px;">.00</span>
+                                <span>{{ integer }}</span>
+                                <span style="font-size: 12px;">.{{ fraction }}</span>
                             </div>
                             <div class="num">×1</div>
                         </div>
@@ -32,7 +28,7 @@
                 </div>
                 <div class="total-price">
                     <div style="margin-right: 4px; margin-top: 2px;">总金额</div>
-                    <price-tag color="black" size="22" value="599"></price-tag>
+                    <price-tag color="black" size="22" :value="orderInfo.price || 0"></price-tag>
                 </div>
                 <div class="divider">
                     <div class="circle" style="left:-31px"></div>
@@ -44,9 +40,9 @@
                         <div class="name">包含项目</div>
                         <div class="num">数量</div>
                     </div>
-                    <div class="row" v-for="n in 10" :key="n">
-                        <div class="name">大锅灶/烧烤套餐二选一</div>
-                        <div class="num">1套</div>
+                    <div class="row" v-for="item in packageGoods" :key="item.id">
+                        <div class="name">{{ item.name }}</div>
+                        <div class="num">{{ item.num }}{{ item.unit }}</div>
                     </div>
                 </div>
                 <div class="group">
@@ -63,35 +59,81 @@
                     <div class="row">
                         <div class="name">订单编号</div>
                         <div class="value">
-                            12345678
+                            {{ orderInfo.id }}
                             <div class="btn-copy" @click="copy">复制</div>
                         </div>
                     </div>
                     <div class="row">
                         <div class="name">创建时间</div>
-                        <div class="value">2019-05-20 08:02:24</div>
+                        <div class="value">{{ orderInfo.createdAt }}</div>
                     </div>
-                    <div class="row" style="margin-top:14px">
+                    <div class="row" v-if="orderInfo.paidAt">
                         <div class="name">付款时间</div>
-                        <div class="value">2019-05-20 08:02:24</div>
+                        <div class="value">{{ orderInfo.paidAt }}</div>
                     </div>
                 </div>
             </div>
+            <div style="height:80px"></div>
         </div>
-        <div class="bottom">
-            <div class="btn-large btn-pay">立即支付</div>
+        <div class="bottom" v-if="orderInfo.status === 'UNPAID'">
+            <div class="btn-large btn-pay" @click="pay">立即支付</div>
         </div>
     </div>
 </template>
 <script>
 export default {
     data() {
-        return {};
+        return {
+            orderInfo: {},
+            packageInfo: {},
+            packageGoods: [],
+            orderStatus: [
+                { label: '待支付', value: 'UNPAID' },
+                { label: '已完成', value: 'PAID' },
+                { label: '已取消', value: 'CANCELLED' },
+                { label: '已完成', value: 'OFFLINE_PAID' }
+            ]
+        };
+    },
+    onShow() {
+        this.$http.get(`/orderInfo/get/${this.$mp.query.id}`).then(res => {
+            this.orderInfo = res;
+            this.$http.get(`/package/get/${res.packageId}`).then(res => {
+                this.packageInfo = res;
+            });
+            this.$http.postJson('/packageGoods/all', { size: 10000, query: { packageId: res.packageId } }).then(res => {
+                this.packageGoods = res.content;
+            });
+        });
+    },
+    computed: {
+        integer() {
+            return (this.orderInfo.price || 0).toFixed(2).split('.')[0];
+        },
+        fraction() {
+            return (this.orderInfo.price || 0).toFixed(2).split('.')[1];
+        },
+        status() {
+            return (this.orderStatus.find(i => i.value === this.orderInfo.status) || {}).label;
+        }
     },
     methods: {
+        getData() {
+            this.$http.get(`/orderInfo/get/${this.$mp.query.id}`).then(res => {
+                this.orderInfo = res;
+                this.$http.get(`/package/get/${res.packageId}`).then(res => {
+                    this.packageInfo = res;
+                });
+                this.$http
+                    .postJson('/packageGoods/all', { size: 10000, query: { packageId: res.packageId } })
+                    .then(res => {
+                        this.packageGoods = res.content;
+                    });
+            });
+        },
         copy() {
             wx.setClipboardData({
-                data: 'data',
+                data: this.orderInfo.id,
                 success(res) {
                     wx.getClipboardData({
                         success(res) {
@@ -102,6 +144,42 @@ export default {
                     });
                 }
             });
+        },
+        pay() {
+            wx.showLoading({
+                title: '加载中'
+            });
+            this.$http
+                .get('/pay/wx', { orderId: this.orderInfo.id })
+                .then(res => {
+                    res.package = res.packageValue;
+                    wx.requestPayment({
+                        ...res,
+                        success: () => {
+                            wx.hideLoading();
+                            wx.showToast({
+                                title: '支付成功'
+                            });
+                            this.$set(this.orderInfo, 'status', 'PAID');
+                            this.getData();
+                        },
+                        fail: e => {
+                            console.log(e);
+                            wx.hideLoading();
+                            wx.showToast({
+                                icon: 'none',
+                                title: '支付失败'
+                            });
+                        }
+                    });
+                })
+                .catch(e => {
+                    wx.hideLoading();
+                    wx.showToast({
+                        title: e.error,
+                        icon: 'none'
+                    });
+                });
         }
     }
 };
@@ -110,14 +188,16 @@ export default {
 page {
     background: @prim;
 }
+.page-scroll {
+    padding-bottom: 0 !important;
+}
 .container {
     background: white;
     border-radius: 12px;
     margin: 48px 12px 0 12px;
     position: relative;
     padding: 50px 20px 50px 20px;
-    padding-bottom: 80px;
-    padding-bottom: calc(env(safe-area-inset-bottom) + 80px);
+    padding-bottom: 30px;
     .status {
         width: 130px;
         height: 44px;
@@ -250,9 +330,6 @@ page {
         }
     }
 }
-.page-scroll {
-    padding-bottom: 0 !important;
-}
 .bottom {
     padding-bottom: env(safe-area-inset-bottom);
     height: 60px;

+ 55 - 10
src/pages/pay.vue

@@ -10,17 +10,13 @@
     <div class="page-container">
         <div class="page-scroll">
             <div class="product">
-                <img
-                    class="cover"
-                    mode="aspectFill"
-                    src="https://jiashanxia.oss-cn-hangzhou.aliyuncs.com/image/home_topbanner_01%402x.png"
-                />
+                <img class="cover" mode="aspectFill" :src="packageInfo.img[0]" />
                 <div class="info">
                     <div class="name">
-                        甲山下游玩会员套餐A
+                        {{ packageInfo.name }}
                     </div>
                     <div class="amount">
-                        <div class="price">¥599</div>
+                        <div class="price">¥{{ packageInfo.amount }}</div>
                         <div class="number">×1</div>
                     </div>
                 </div>
@@ -28,7 +24,7 @@
             <div class="cell" style="margin-top: 20px;">
                 <div class="label">总金额</div>
                 <div class="value">
-                    <price-tag value="599" color="black" size="26"></price-tag>
+                    <price-tag :value="packageInfo.amount" color="black" size="26"></price-tag>
                 </div>
             </div>
             <div class="border"></div>
@@ -55,7 +51,19 @@
 import { mapState } from 'vuex';
 export default {
     data() {
-        return {};
+        return {
+            packageInfo: {
+                img: []
+            }
+        };
+    },
+    onShow() {
+        let eventChannel = this.$mp.page.getOpenerEventChannel();
+        if (eventChannel && eventChannel.on) {
+            eventChannel.on('packageInfo', data => {
+                this.packageInfo = data;
+            });
+        }
     },
     computed: {
         ...mapState(['userInfo'])
@@ -88,7 +96,44 @@ export default {
         onError(e) {
             console.log(e);
         },
-        createOrder() {}
+        createOrder() {
+            wx.showLoading({
+                title: '加载中'
+            });
+            this.$http
+                .post('/orderInfo/create', { packageId: this.packageInfo.id, payMethod: 'WEIXIN' })
+                .then(res => {
+                    return this.$http.get('/pay/wx', { orderId: res.id });
+                })
+                .then(res => {
+                    res.package = res.packageValue;
+                    wx.requestPayment({
+                        ...res,
+                        success: () => {
+                            wx.hideLoading();
+                            wx.showToast({
+                                title: '支付成功'
+                            });
+                            this.navigateTo('/pages/order');
+                        },
+                        fail: e => {
+                            console.log(e);
+                            wx.hideLoading();
+                            wx.showToast({
+                                icon: 'none',
+                                title: '支付失败'
+                            });
+                        }
+                    });
+                })
+                .catch(e => {
+                    wx.hideLoading();
+                    wx.showToast({
+                        title: e.error,
+                        icon: 'none'
+                    });
+                });
+        }
     }
 };
 </script>

+ 124 - 66
src/plugins/http.js

@@ -13,11 +13,22 @@ function parseUrl(url) {
     return _baseUrl + url;
 }
 const http = {
-    parseUrl: parseUrl,
-    setToken(token) {
-        wx.setStorageSync('token', token);
-        this.token = token;
+    waitList: [],
+    _token: null,
+    get token() {
+        if (!this._token) {
+            try {
+                this._token = wx.getStorageSync('token');
+            } catch (e) {}
+        }
+        return this._token;
+    },
+    set token(x) {
+        wx.setStorageSync('token', x);
+        this._token = x;
+        this.waitList.forEach(i => i());
     },
+    parseUrl: parseUrl,
     clearToken() {
         this.token = '';
         wx.removeStorageSync('token');
@@ -31,87 +42,134 @@ const http = {
         }
         return this.token;
     },
+    waitForToken() {
+        if (this.token) {
+            return Promise.resolve();
+        } else {
+            try {
+                this.token = wx.getStorageSync('token');
+            } catch (e) {}
+            return new Promise((resolve, reject) => {
+                this.waitList.push(resolve);
+            });
+        }
+    },
     get(url, params, options) {
         options = options || {};
         return new Promise((resolve, reject) => {
-            wx.request({
-                method: 'GET',
-                url: parseUrl(url),
-                data: params,
-                dataType: 'json',
-                header: {
-                    Accept: 'application/json',
-                    Authorization: this.getToken() ? 'Bearer ' + this.getToken() : '',
-                    ...(options.header || {})
-                },
-                success(res) {
-                    if (res && res.statusCode === 200) {
-                        resolve(res.data);
-                    } else {
-                        reject(res.data || res);
+            this.waitForToken().then(() => {
+                wx.request({
+                    method: 'GET',
+                    url: parseUrl(url),
+                    data: params,
+                    dataType: 'json',
+                    header: {
+                        Accept: 'application/json',
+                        Authorization: this.token ? 'Bearer ' + this.token : '',
+                        ...(options.header || {})
+                    },
+                    success(res) {
+                        if (res && res.statusCode === 200) {
+                            resolve(res.data);
+                        } else {
+                            reject(res.data || res);
+                        }
+                    },
+                    fail(err) {
+                        reject(err.data || err);
                     }
-                },
-                fail(err) {
-                    reject(err.data || err);
-                }
+                });
             });
         });
     },
     post(url, data, options) {
         options = options || {};
         return new Promise((resolve, reject) => {
-            wx.request({
-                method: 'post',
-                url: parseUrl(url),
-                data: data,
-                dataType: 'json',
-                header: {
-                    Accept: 'application/json',
-                    'content-type': 'application/x-www-form-urlencoded',
-                    Authorization: this.getToken() ? 'Bearer ' + this.getToken() : '',
-                    ...(options.header || {})
-                },
-                success(res) {
-                    if (res && res.statusCode === 200) {
-                        resolve(res.data);
-                    } else {
-                        reject(res.data || res);
+            this.waitForToken().then(() => {
+                wx.request({
+                    method: 'post',
+                    url: parseUrl(url),
+                    data: data,
+                    dataType: 'json',
+                    header: {
+                        Accept: 'application/json',
+                        'content-type': 'application/x-www-form-urlencoded',
+                        Authorization: this.token ? 'Bearer ' + this.token : '',
+                        ...(options.header || {})
+                    },
+                    success(res) {
+                        if (res && res.statusCode === 200) {
+                            resolve(res.data);
+                        } else {
+                            reject(res.data || res);
+                        }
+                    },
+                    fail(err) {
+                        reject(err.data || err);
                     }
-                },
-                fail(err) {
-                    reject(err.data || err);
-                }
+                });
+            });
+        });
+    },
+    postJson(url, data, options) {
+        options = options || {};
+        return new Promise((resolve, reject) => {
+            this.waitForToken().then(() => {
+                wx.request({
+                    method: 'post',
+                    url: parseUrl(url),
+                    data: data,
+                    dataType: 'json',
+                    header: {
+                        Accept: 'application/json',
+                        'Content-Type': 'application/json',
+                        Authorization: this.token ? 'Bearer ' + this.token : '',
+                        ...(options.header || {})
+                    },
+                    success(res) {
+                        if (res && res.statusCode === 200) {
+                            resolve(res.data);
+                        } else {
+                            reject(res.data || res);
+                        }
+                    },
+                    fail(err) {
+                        reject(err.data || err);
+                    }
+                });
             });
         });
     },
     uploadFile(filePath, options) {
         options = options || {};
         return new Promise((resolve, reject) => {
-            wx.uploadFile({
-                url: baseUrl + '/upload/file',
-                filePath: filePath,
-                name: 'file',
-                header: {
-                    Accept: 'application/json',
-                    'content-type': 'application/x-www-form-urlencoded',
-                    Authorization: this.getToken() ? 'Bearer ' + this.getToken() : '',
-                    ...(options.header || {})
-                },
-                formData: options.formData || {},
-                success(res) {
-                    if (res && res.statusCode === 200) {
-                        try {
-                            resolve(JSON.parse(res.data));
-                        } catch (e) {
-                            reject(e);
+            this.waitForToken().then(() => {
+                wx.uploadFile({
+                    url: baseUrl + '/upload/file',
+                    filePath: filePath,
+                    name: 'file',
+                    header: {
+                        Accept: 'application/json',
+                        'content-type': 'application/x-www-form-urlencoded',
+                        Authorization: this.token ? 'Bearer ' + this.token : '',
+                        ...(options.header || {})
+                    },
+                    formData: options.formData || {},
+                    success(res) {
+                        if (res && res.statusCode === 200) {
+                            try {
+                                resolve(JSON.parse(res.data));
+                            } catch (e) {
+                                reject(e);
+                            }
+                        } else {
+                            reject(res);
                         }
-                    } else {
-                        reject(res);
+                    },
+                    fail(err) {
+                        reject(err);
                     }
-                },
-                fail(err) {
-                    reject(err);
-                }
+                });
             });
         });
     }