浏览代码

no message

LAPTOP-1LHD2FP6\joeny 1 年之前
当前提交
0cbb4f3ee2
共有 100 个文件被更改,包括 20048 次插入0 次删除
  1. 16 0
      .gitignore
  2. 340 0
      App.vue
  3. 72 0
      LICENSE
  4. 2 0
      README.md
  5. 475 0
      appletXcx/Alipay/Versioning.vue
  6. 485 0
      appletXcx/Alipay/addExamine.vue
  7. 246 0
      appletXcx/Alipay/addVersion.vue
  8. 451 0
      appletXcx/Alipay/deploy.vue
  9. 187 0
      appletXcx/Alipay/index.vue
  10. 250 0
      appletXcx/Alipay/qrCode.vue
  11. 135 0
      appletXcx/Alipay/sign.vue
  12. 663 0
      appletXcx/Wechat/Versioning.vue
  13. 258 0
      appletXcx/Wechat/addVersion.vue
  14. 11 0
      appletXcx/Wechat/data.js
  15. 995 0
      appletXcx/Wechat/deploy.vue
  16. 304 0
      appletXcx/Wechat/getXcx.vue
  17. 186 0
      appletXcx/Wechat/index.vue
  18. 217 0
      appletXcx/Wechat/interface.vue
  19. 259 0
      appletXcx/Wechat/interfaceDetail.vue
  20. 327 0
      appletXcx/Wechat/qrCode.vue
  21. 418 0
      appletXcx/WechatShop/addPay.vue
  22. 276 0
      appletXcx/WechatShop/basics.vue
  23. 273 0
      appletXcx/WechatShop/getShop.vue
  24. 175 0
      appletXcx/WechatShop/index.vue
  25. 251 0
      appletXcx/WechatShop/qrCode.vue
  26. 1201 0
      appletXcx/components/tki-qrcode/qrcode.js
  27. 260 0
      appletXcx/components/tki-qrcode/tki-qrcode.vue
  28. 267 0
      appletXcx/components/uni-scroll/uni-scroll-cate.vue
  29. 192 0
      appletXcx/components/uni-scroll/uni-scroll.vue
  30. 194 0
      appletXcx/components/uni-scroll/uni-scrollail1.vue
  31. 19 0
      appletXcx/css/style.css
  32. 二进制
      appletXcx/static/images/icon_1.png
  33. 二进制
      appletXcx/static/images/icon_6.png
  34. 二进制
      appletXcx/static/images/shanchu.png
  35. 98 0
      appletXcx/wechatMarket/index.vue
  36. 505 0
      appletXcx/wechatMarket/templateMessage.vue
  37. 495 0
      appletXcx/wechatMarket/vipCardMessage.vue
  38. 二进制
      components/.DS_Store
  39. 107 0
      components/drag-sort/1px.less
  40. 237 0
      components/drag-sort/index.vue
  41. 864 0
      components/flow-pool/flow-pool.vue
  42. 124 0
      components/header/header-title.vue
  43. 175 0
      components/liuyuno-tabs/liuyuno-tabs.vue
  44. 188 0
      components/module/short_video.vue
  45. 105 0
      components/page-btm-bar/page-btm-bar.vue
  46. 165 0
      components/u-charts/component.vue
  47. 0 0
      components/u-charts/u-charts.min.js
  48. 198 0
      components/uni-scroll/uni-scroll.vue
  49. 292 0
      components/uni-swipe-action-item/bindingx.js
  50. 266 0
      components/uni-swipe-action-item/index.wxs
  51. 207 0
      components/uni-swipe-action-item/mpalipay.js
  52. 252 0
      components/uni-swipe-action-item/mpother.js
  53. 119 0
      components/uni-swipe-action-item/mpwxs.js
  54. 367 0
      components/uni-swipe-action-item/uni-swipe-action-item.vue
  55. 42 0
      components/uni-swipe-action/uni-swipe-action.vue
  56. 279 0
      components/uni-transition/uni-transition-a.vue
  57. 34 0
      components/uni-ui/uni-badge/readme.md
  58. 109 0
      components/uni-ui/uni-badge/uni-badge.vue
  59. 61 0
      components/uni-ui/uni-card/readme.md
  60. 165 0
      components/uni-ui/uni-card/uni-card.vue
  61. 203 0
      components/uni-ui/uni-grid/uni-grid.vue
  62. 35 0
      components/uni-ui/uni-icon/readme.md
  63. 39 0
      components/uni-ui/uni-icon/uni-icon.vue
  64. 95 0
      components/uni-ui/uni-notice-bar/readme.md
  65. 243 0
      components/uni-ui/uni-notice-bar/uni-notice-bar.vue
  66. 162 0
      components/uni-ui/uni-swiper-dot/uni-swiper-dot.vue
  67. 20 0
      components/wyb-pagination/iconfont.css
  68. 442 0
      components/wyb-pagination/wyb-pagination.vue
  69. 119 0
      components/zx-footer-bar/zx-footer-bar.vue
  70. 22 0
      components/zx-uni-popup/message.js
  71. 26 0
      components/zx-uni-popup/popup.js
  72. 271 0
      components/zx-uni-popup/uni-popup-top.vue
  73. 298 0
      components/zx-uni-popup/uni-popup.vue
  74. 4 0
      components/zx-uni-search-bar/i18n/en.json
  75. 8 0
      components/zx-uni-search-bar/i18n/index.js
  76. 4 0
      components/zx-uni-search-bar/i18n/zh-Hans.json
  77. 4 0
      components/zx-uni-search-bar/i18n/zh-Hant.json
  78. 287 0
      components/zx-uni-search-bar/uni-search-bar.vue
  79. 30 0
      jweixin-module/README.md
  80. 714 0
      jweixin-module/lib/index.js
  81. 54 0
      jweixin-module/package.json
  82. 46 0
      main.js
  83. 112 0
      manifest.json
  84. 299 0
      merchant/Applied.vue
  85. 560 0
      merchant/CouponDetails.vue
  86. 328 0
      merchant/addCoupons.vue
  87. 217 0
      merchant/coupon.vue
  88. 376 0
      merchant/flow-record.vue
  89. 171 0
      merchant/merchant.vue
  90. 二进制
      merchant/static/images/add-coupon.png
  91. 二进制
      merchant/static/images/add-hexiao.png
  92. 二进制
      merchant/static/images/ali_code.png
  93. 二进制
      merchant/static/images/ali_ua.png
  94. 二进制
      merchant/static/images/coupon.png
  95. 二进制
      merchant/static/images/coupun-bg.png
  96. 二进制
      merchant/static/images/darw/FltcHBBH8X84Uzs5llLo_pGBnuvv.png
  97. 二进制
      merchant/static/images/darw/FoIzpLTMwSQZDcJYrL_FD_07iBte.png
  98. 二进制
      merchant/static/images/darw/FrKRY-mHF7fQmkO3lUQjWRCDlCRI.png
  99. 二进制
      merchant/static/images/darw/FrnXmarfaxXY9i3FCkZGuQJyR6Rj.png
  100. 二进制
      merchant/static/images/darw/Fv1xujnIn1r7XecrvEc-Mp9dqM4C.png

+ 16 - 0
.gitignore

@@ -0,0 +1,16 @@
+# ---> Actionscript
+# Build and Release Folders
+bin/
+bin-debug/
+bin-release/
+
+.hbuilderx
+unpackage/
+# Other files and folders
+
+.settings/
+
+# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
+# should NOT be excluded as they contain compiler settings and other important
+# information for Eclipse / Flash Builder.
+

+ 340 - 0
App.vue

@@ -0,0 +1,340 @@
+<script>
+    import siteinfo from './siteinfo.js';
+    import http from './static/js/http.js'
+    export default {
+        onLaunch: function() {
+            // console.log('App Launch')
+        },
+        onShow: function(options) {
+            // console.log(options, 'App Show')
+            // 判断是否开启语音播报
+            if (this.globalData.openYuyin && this.globalData.yuyinStoreId) {
+                this.initSocket(this.globalData.yuyinStoreId)
+            }
+            if (options.query.scene) {
+                uni.setStorageSync("is_login", 2);
+                uni.setStorageSync("admin_id", options.query.scene);
+            }
+
+            if (options.referrerInfo.extraData) {
+                uni.setStorageSync("token", options.referrerInfo.extraData.token);
+            }
+
+            const updateManager = uni.getUpdateManager(); // 获取更新管理器对象
+            updateManager.onCheckForUpdate(function(res) {
+                if (res.hasUpdate) {
+                    updateManager.onUpdateReady(function() {
+                        uni.showModal({
+                            title: '更新提示',
+                            content: '新版本已经准备好,是否重启应用?',
+                            showCancel: false,
+                            success: res => {
+                                if (res.confirm) {
+                                    updateManager.applyUpdate();
+                                }
+                            }
+                        })
+                    })
+                    updateManager.onUpdateFailed(function() {
+                        uni.showModal({
+                            title: '提示',
+                            content: '检查到有新版本,但是下载失败,请检查网络设置',
+                            showCancel: false
+                        })
+                    })
+                }
+            })
+        },
+
+        onHide: function() {
+            // console.log('App Hide')
+            this.closeSocket()
+        },
+
+        globalData: {
+            URL: siteinfo.siteroot,
+            token: null,
+            playList: [],
+            isPlay: false,
+            yuyinSocket: null,
+            openYuyin: false,
+            yuyinStoreId: ''
+        },
+        methods: {
+            closeSocket(msg = '', exit = false) {
+                uni.closeSocket({
+                    code: 100,
+                    reason: msg || "退出小程序 关闭链接",
+                    complete: (r) => {
+
+                        // console.log("退出时 关闭websocket")
+                    }
+                })
+                if (exit) {
+                    this.globalData.openYuyin = false
+                }
+            },
+            connectSocket(urlNoProtocol) {
+                uni.connectSocket({
+                    url: `wss://${urlNoProtocol}/wss:8282`,
+                    // url:'ws://121.40.165.18:8800',//测试链接
+                    complete: e => {
+                        // console.warn("connect socket complete", e);
+                    }
+                })
+            },
+            initSocket(store_id = '') {
+                this.globalData.openYuyin = true
+                this.globalData.yuyinStoreId = store_id
+                console.log(store_id, '链接websocket')
+                let that = this,
+                    url = siteinfo.siteroot;
+                var urlNoProtocol = url.replace(/^https?\:\/\//i, "");
+               
+                this.connectSocket(urlNoProtocol)
+                this.globalData.yuyinSocket = uni.onSocketOpen(res => {
+                    uni.onSocketMessage(res => {
+                        console.warn("socket message", res)
+                        let data = JSON.parse(res.data)
+                        if (data.type == 'init') {
+                            http({
+                                url: 'yy/bindSocket',
+                                data: {
+                                    store_id,
+                                    client_id: data.client_id
+                                },
+                                showLoading:true
+                            }).then(res => {
+                                console.log(res)
+                            })
+
+                        } else if (data.type == 'yuyin') {
+                          
+                            this.play(`${url}${data.route}`)
+                        }
+
+                    })
+                    uni.onSocketClose(res => {
+                        console.error("socket close", res)
+                        if (res.code != 100) {
+                            // console.warn("重新链接websocket")
+                            this.connectSocket(urlNoProtocol)
+                        }
+
+                    })
+                })
+                uni.onSocketError(res => {
+                    // console.warn("socket error", res)
+                    // this.connectSocket(urlNoProtocol)
+                })
+
+            },
+            // 播放语音
+            play(src = '', isNext = false) {
+                // console.log(this.globalData.isPlay, !isNext, 'isPlay')
+                if (this.globalData.isPlay && !isNext) {
+                    // console.log("加入队列");
+                    this.globalData.playList.push(src)
+                    // console.log(this.globalData.playList);
+                    return false
+                }
+                this.globalData.isPlay = true
+                // console.log("播放来单提醒", src)
+                const innerAudioContext = uni.createInnerAudioContext();
+                innerAudioContext.autoplay = true;
+                innerAudioContext.src = src;
+                innerAudioContext.onPlay(() => {
+                    // console.log('开始播放');
+                });
+                innerAudioContext.onError((res) => {
+                    // console.log(res.errMsg);
+                    // console.log(res.errCode);
+                });
+                innerAudioContext.onEnded((res) => {
+                    //播放完成,播放下一条
+                    // console.log("播放完成", res);
+                    this.execPlayList()
+                })
+            },
+            //播放队列
+            execPlayList() {
+                // console.log("播放队列");
+                let list = this.globalData.playList
+                if (list.length > 0) {
+                    let src = list.splice(0, 1)[0]
+                    this.globalData.play = list
+                    this.play(src, true)
+                } else {
+                    this.globalData.isPlay = false
+
+                }
+            },
+
+
+        }
+
+    }
+</script>
+
+<style>
+    /*每个页面公共css */
+    @import url("/static/css/iconfont.css");
+    @import url("/static/css/flex.css");
+    @import url("/static/css/common.css");
+    @import url("/static/css/public.css");
+
+    page {
+        font-family: PingFang SC, PingFang SC-Regular;
+    }
+
+    swiper.square-dot .wx-swiper-dot,
+    swiper.square-dot .a-swiper-dot,
+    swiper.square-dot .uni-swiper-dot {
+        background-color: #ffffff;
+        opacity: 0.4;
+        width: 10upx;
+        height: 10upx;
+        border-radius: 20upx;
+        margin: 0 8upx !important;
+    }
+
+    swiper.square-dot .wx-swiper-dot.wx-swiper-dot-active,
+    swiper.square-dot .a-swiper-dot.a-swiper-dot-active,
+    swiper.square-dot .uni-swiper-dot.uni-swiper-dot-active {
+        opacity: 1;
+        width: 30upx;
+    }
+
+    /*  */
+    .text-1 {
+        width: 100%;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+    }
+
+    .text-2 {
+        display: -webkit-box;
+        -webkit-box-orient: vertical;
+        -webkit-line-clamp: 2;
+        overflow: hidden;
+    }
+
+    /* 粘性布局 */
+    .sticky {
+        position: sticky;
+        top: 0;
+        z-index: 100;
+    }
+
+    /* 空列表 */
+    .list-have-no {
+        padding: 50rpx 0;
+    }
+
+    .list-have-no-img {
+        display: block;
+        width: 598rpx;
+        height: 222rpx;
+        margin: 0 auto;
+    }
+
+    /* 页面底部按钮 */
+    .public-btm-btn-block {
+        height: 200rpx;
+        width: 100%;
+    }
+
+    .public-btm-btn-block .btn {
+        width: 600rpx;
+        height: 80rpx;
+        padding: 0;
+        margin: 0;
+        border-radius: 16rpx;
+        background: #C79A4E;
+        box-shadow: 0 0 20rpx #DDC59D;
+        position: absolute;
+        left: 50%;
+        bottom: 60rpx;
+        margin-left: -300rpx;
+        text-align: center;
+        line-height: 80rpx;
+        font-size: 32rpx;
+        font-weight: 500;
+        color: #fff;
+    }
+
+    /*  */
+    .input-placeholder {
+        font-size: 28rpx;
+        color: #969696;
+    }
+
+    /* flex */
+    .flex-row {
+        display: flex;
+        flex-flow: row nowrap;
+        justify-content: flex-start;
+        align-items: center;
+    }
+
+    .flex-row-between {
+        display: flex;
+        flex-flow: row nowrap;
+        justify-content: space-between;
+        align-items: center;
+    }
+
+    .flex-row-center {
+        display: flex;
+        flex-flow: row nowrap;
+        justify-content: center;
+        align-items: center;
+    }
+
+    .flex-row-start {
+        display: flex;
+        flex-flow: row nowrap;
+        justify-content: flex-start;
+        align-items: flex-start;
+    }
+
+    .flex-column {
+        display: flex;
+        flex-flow: column nowrap;
+        justify-content: flex-start;
+        align-items: center;
+    }
+
+    .flex-column-center {
+        display: flex;
+        flex-flow: column nowrap;
+        justify-content: center;
+        align-items: center;
+    }
+
+    .flex-column-between {
+        display: flex;
+        flex-flow: column nowrap;
+        justify-content: space-between;
+        align-items: center;
+    }
+
+    .flex-column-between-start {
+        display: flex;
+        flex-flow: column nowrap;
+        justify-content: space-between;
+        align-items: start;
+    }
+
+    .flex-y-bottom {
+        display: -webkit-box;
+        display: -webkit-flex;
+        display: flex;
+        -webkit-box-align: end;
+        -webkit-align-items: flex-end;
+        -ms-flex-align: end;
+        -ms-grid-row-align: flex-end;
+        align-items: flex-end;
+    }
+</style>

+ 72 - 0
LICENSE

@@ -0,0 +1,72 @@
+Apache License 
+Version 2.0, January 2004 
+http://www.apache.org/licenses/
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+(d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License"); 
+you may not use this file except in compliance with the License. 
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software 
+distributed under the License is distributed on an "AS IS" BASIS, 
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+See the License for the specific language governing permissions and 
+limitations under the License.

+ 2 - 0
README.md

@@ -0,0 +1,2 @@
+# xcxManager
+

+ 475 - 0
appletXcx/Alipay/Versioning.vue

@@ -0,0 +1,475 @@
+<template>
+	<view class="">
+		<view class="step">
+			<uni-steps active-color="#3387FF" :options="[{title: '扫码授权',url:'./qrCode'}, {title: '小程序配置',url:'./deploy'}, 
+			{title: '提交版本',url:'./addVersion'},
+		    {title: '提交审核',url:'./addExamine'},{title: '版本管理',url:'./Versioning'} ]" :active="4"></uni-steps>
+		</view>
+		<view style="height: 130rpx;"></view>
+		<view class="version">
+			<view class="versionTip">
+				Tip:如审核失败,请先将审核失败的版本退回开发,再返回上一步重新提交,如审核通过直接发布即可
+			</view>
+			<view class="versionOnline" v-if="release_obj.user_version">
+				<view class="versionOnlineTitle box-pack-between">
+					<text>线上版本</text>
+					<view class="flex-y-center por">
+						<view class="versionOnlineTitle-btn flex-center" @click.stop="versionBack()">
+							版本回退
+						</view>
+					</view>
+				</view>
+				<view class="versionOnlineTitleBg ">
+					<view class="versionOnlineTitleNum ft32">
+						{{release_obj.user_version}}
+					</view>
+					<view class="versionOnlineTitleTime ft24">
+						在 {{release_obj.tijiao_time}} 提交上传
+					</view>
+					<view class="versionOnlineTitleTime ft24">
+						在 {{release_obj.fabu_time}} 提交发布
+					</view>
+				</view>
+			</view>
+			<view class="versionOnline" v-if="shen_obj.user_version">
+
+				<view class="versionOnlineTitle box-pack-between">
+					<text>审核版本 <text
+							style="color: red;">({{shen_obj.status==2?'审核中':shen_obj.status==1?'审核被拒绝':shen_obj.status==0?'审核通过':''}})</text></text>
+					<view class="flex-y-center" style="font-weight: 400;" @click="bindWithdraw(shen_obj.id)">
+						<text>{{shen_obj.status==2?'撤回审核':shen_obj.status==1?'撤回开发':shen_obj.status==0?'发布上线':''}}
+						</text>
+						<text class="iconfont icongengduo"></text>
+					</view>
+				</view>
+
+				<view class="versionOnlineTitleBgShen"
+					:style="{backgroundColor:shen_obj.status==1?'#f73131':'#4395ff'}">
+					<view class="versionOnlineTitleNum ft32 box-pack-between" @click="bindRefuse(shen_obj.id)">
+						<text>{{shen_obj.user_version}}</text>
+						<text v-if="shen_obj.status==1" class="ft24">失败详情 <text
+								style="font-size: 24rpx;padding-left: 10rpx;" class="iconfont icontishi"></text></text>
+					</view>
+					<view class="versionOnlineTitleTime ft24">
+						在 {{shen_obj.create_time}} 提交上传
+					</view>
+					<view class="versionOnlineTitleTime ft24">
+						在 {{shen_obj.tijiao_time}} 审核时间
+					</view>
+				</view>
+			</view>
+
+			<view class="versionOnline" v-if="tiyan_obj.user_version">
+				<view class="versionOnlineTitle box-pack-between">
+					<text>体验版本</text>
+					<view class="flex-y-center" style="font-weight: 400;" @click="bindPreview(tiyan_obj.id)">
+						<text>预览</text>
+						<text class="iconfont icongengduo"></text>
+					</view>
+				</view>
+				<view class="versionOnlineTitleBg " style="background-color: #4395ff;">
+					<view class="versionOnlineTitleNum ft32 box-pack-between">
+						<text>{{tiyan_obj.user_version}}</text>
+						<image class="versionCode" src="../../static/images/ali.png"></image>
+					</view>
+					<view class="versionOnlineTitleTime ft24">
+						在 {{tiyan_obj.create_time}} 提交上传
+					</view>
+					<view class="versionOnlineTitleTime ft24">
+						在 {{tiyan_obj.create_time}} 提交
+					</view>
+				</view>
+			</view>
+		</view>
+
+		<uni-popup ref="popup" type="center">
+			<view class="popup-content" v-if="type==1">
+				<image :src="qrcodeImg"></image>
+				<view class="save-btn flex-center" @click="upCode">
+					保存图片
+				</view>
+			</view>
+			<view v-if="type==2" class="popup-content-desc">
+				<scroll-view scroll-y="true" style="height: 100%;">
+					{{desc}}
+				</scroll-view>
+			</view>
+		</uni-popup>
+
+	</view>
+</template>
+
+<script>
+	// #ifdef MP-WEIXIN
+	import saveImgToPhotosAlbum from "@/static/js/saveImgToPhotosAlbum.js";
+	// #endif
+	export default {
+		data() {
+			return {
+				release_obj: {},
+				tiyan_obj: {},
+				shen_obj: {},
+				qrcodeImg: '',
+
+				type: 1,
+				desc: ''
+			}
+		},
+		onLoad() {
+			this.releaseVenson();
+			this.tiyanVenson();
+			this.shenVenson();
+		},
+		methods: {
+			// 版本回退
+			versionBack() {
+				//
+				uni.showModal({
+					content: "确定要版本回退",
+					success: (r) => {
+						if (r.confirm) {
+							this.request({
+								url: 'setting/rollback',
+								data: {
+									admin_id: uni.getStorageSync("admin_id"),
+								}
+							}).then(res => {
+								if (res.code == 200) {
+									uni.showModal({
+										content: res.message,
+										showCancel: false,
+										success: (r) => {
+											this.releaseVenson();
+											this.tiyanVenson();
+											this.shenVenson();
+										}
+									})
+								}
+							})
+						}
+					}
+				})
+			},
+			//撤回审核2、撤回开发1、发布上线0
+			bindWithdraw(id) {
+				if (this.shen_obj.status == 0) {
+					this.request({
+						url: 'setting/onlineMiniVersion',
+						data: {
+							admin_id: uni.getStorageSync("admin_id"),
+							id: id,
+						}
+					}).then(res => {
+						if (res.code == 200) {
+							uni.showToast({
+								title: res.message
+							})
+							setTimeout(() => {
+								this.shenVenson();
+							}, 2000)
+						}
+					})
+				}
+
+				if (this.shen_obj.status == 1) {
+					this.request({
+						url: 'setting/cancelMiniVersion',
+						data: {
+							admin_id: uni.getStorageSync("admin_id"),
+							id: id,
+						}
+					}).then(res => {
+						if (res.code == 200) {
+							uni.showToast({
+								title: res.message
+							})
+							setTimeout(() => {
+								this.shenVenson();
+							}, 2000)
+						}
+					})
+				}
+
+				if (this.shen_obj.status == 2) {
+					uni.showModal({
+						title: '提示',
+						content: "是否要撤回审核?",
+						showCancel: true,
+						cancelText: '取消',
+						confirmText: '确定',
+						success: r => {
+							if (r.confirm) {
+								this.request({
+									url: 'setting/withdrawMiniVersion',
+									data: {
+										admin_id: uni.getStorageSync("admin_id"),
+										id: id,
+									}
+								}).then(res => {
+									if (res.code == 200) {
+										uni.showToast({
+											title: res.message
+										})
+										setTimeout(() => {
+											this.shenVenson();
+										}, 2000)
+									}
+								})
+
+							}
+						},
+						fail: () => {},
+						complete: () => {}
+					});
+				}
+			},
+
+			bindPreview(id) {
+				this.request({
+					url: 'setting/createMiniExperience',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+						id,
+					}
+				}).then(res => {
+					if (res.code == 200) {
+						this.qrcodeImg = res.data.exp_qr_code_url;
+						this.type = 1;
+						this.$refs.popup.open();
+					}
+				})
+			},
+
+			bindRefuse(id) {
+				this.request({
+					url: 'setting/alipayjujue',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+						id,
+					}
+				}).then(res => {
+					if (res.code == 200) {
+						this.desc = res.message;
+						// uni.showModal({
+						// 	title: '失败详情',
+						// 	content:res.data.message,
+						// 	showCancel: false,
+						// 	cancelText: '',
+						// 	confirmText: '',
+						// 	success: res => {},
+						// 	fail: () => {},
+						// 	complete: () => {}
+						// });
+						this.type = 2;
+						this.$refs.popup.open();
+					}
+				})
+			},
+
+			// 线上版本
+			releaseVenson(e) {
+				this.request({
+					url: 'setting/release_venson',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+					}
+				}).then(res => {
+					if (res.code == 200) {
+						this.release_obj = res.data;
+					}
+				})
+			},
+
+			// 体验版本
+			tiyanVenson(e) {
+				this.request({
+					url: 'setting/tiyan_venson',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+					}
+				}).then(res => {
+					if (res.code == 200) {
+						this.tiyan_obj = res.data;
+					}
+				})
+			},
+			// 审核版本
+			shenVenson(e) {
+				this.request({
+					url: 'setting/shen_venson',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+					}
+				}).then(res => {
+					if (res.code == 200) {
+						this.shen_obj = res.data;
+					}
+				})
+			},
+
+			upCode(e) {
+				// #ifdef H5
+				uni.showModal({
+					title: '提示',
+					content: '请长按二维码图片进行保存',
+					showCancel: false,
+					confirmText: '好的',
+				});
+				// #endif
+				// #ifdef MP-WEIXIN 
+				var url = this.qrcodeImg;
+				console.log(url, "url")
+				saveImgToPhotosAlbum.saveImgToPhotosAlbum(url).then((res) => {
+					//成功的逻辑
+					console.log(res, "保存成功")
+					wx.showToast({
+						title: '保存成功',
+						icon: 'none',
+						mask: true,
+					})
+					setTimeout(() => {
+						this.$refs.popup.close();
+					}, 2000)
+				}).catch((err) => {
+					console.log(err, "保存失败")
+					if (err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" ||
+						err.errMsg === "saveImageToPhotosAlbum:fail auth deny" || err.errMsg ===
+						"saveImageToPhotosAlbum:fail authorize no response") {
+						// 这边微信做过调整,必须要在按钮中触发,因此需要在弹框回调中进行调用
+						uni.showModal({
+							title: '提示',
+							content: '需要您设置授权保存相册',
+							showCancel: false,
+							success: modalSuccess => {
+								uni.openSetting({
+									success(settingdata) {
+										console.log("settingdata", settingdata)
+										if (settingdata.authSetting[
+												'scope.writePhotosAlbum']) {
+											uni.showModal({
+												title: '提示',
+												content: '获取权限成功,再次点击图片即可保存',
+												showCancel: false,
+											})
+										} else {
+											uni.showModal({
+												title: '提示',
+												content: '获取权限失败,将无法保存到相册哦~',
+												showCancel: false,
+											})
+										}
+									},
+									fail(failData) {
+										console.log("failData", failData)
+									},
+									complete(finishData) {
+										console.log("finishData", finishData)
+									}
+								})
+
+							}
+						})
+					}
+					// 失败后的逻辑
+				})
+				// #endif			
+			},
+		}
+	}
+</script>
+
+<style>
+	.versionTip {
+		color: red;
+		font-size: 26rpx;
+		padding-bottom: 20rpx;
+	}
+
+	.version {
+		padding: 0 30rpx;
+	}
+
+	.versionOnline {
+		padding-bottom: 50rpx;
+	}
+
+	.versionOnlineTitle {
+		font-size: 30rpx;
+		font-weight: 600;
+		padding-bottom: 20rpx;
+	}
+
+	.versionOnlineTitleBg {
+		background-color: #42b983;
+		color: #FFFFFF;
+		padding: 20rpx;
+		border-radius: 10rpx;
+	}
+
+	.versionOnlineTitleBgShen {
+		background-color: #4395ff;
+		color: #FFFFFF;
+		padding: 20rpx;
+		border-radius: 10rpx;
+	}
+
+	.versionOnlineTitleNum {
+		padding-bottom: 10rpx;
+		font-weight: 600;
+	}
+
+	.versionOnlineTitleTime {
+		padding-bottom: 10rpx;
+	}
+
+	.versionCode {
+		width: 50rpx;
+		height: 50rpx;
+	}
+
+	.popup-content-desc {
+		background: #fff;
+		text-align: center;
+		width: 500rpx;
+		height: 500rpx;
+		word-break: break-all;
+		padding: 25rpx;
+	}
+
+	.popup-content image {
+		width: 350rpx;
+		height: 350rpx;
+		background: #fff;
+	}
+
+	.save-btn {
+		width: 330rpx;
+		height: 90rpx;
+		background: linear-gradient(315deg, #3387ff 2%, #569bff 99%);
+		opacity: 1;
+		border-radius: 6rpx;
+		margin: 0 auto;
+		color: #FFFFFF;
+		font-size: 30rpx;
+		font-family: Source Han Sans CN;
+		font-weight: 500;
+		opacity: 1;
+		margin-top: 30rpx;
+	}
+	.versionOnlineTitle-btn {
+		background-color: #42b983;
+		color: #ffffff;
+		font-weight: normal;
+		line-height: 60rpx;
+		/* padding: 0 32rpx; */
+		min-width: 180rpx;
+		font-size: 26rpx;
+		letter-spacing: 0;
+		border-radius: 6rpx;
+		box-sizing: border-box;
+		border: none;
+		cursor: pointer;
+		text-align: center;
+		margin-right: 20rpx;
+	}
+</style>

+ 485 - 0
appletXcx/Alipay/addExamine.vue

@@ -0,0 +1,485 @@
+<template>
+	<view class="content">
+		<!-- 基本用法 -->
+		<view class="step">
+			<uni-steps active-color="#3387FF" :options="[{title: '扫码授权',url:'./qrCode'}, {title: '小程序配置',url:'./deploy'}, 
+			{title: '提交版本',url:'./addVersion'},
+		    {title: '提交审核',url:'./addExamine'},{title: '版本管理',url:'./Versioning'} ]" :active="3"></uni-steps>
+		</view>
+		<view style="height: 130rpx;"></view>
+		<form @submit="save">
+			<view class="bgf" style="padding: 0 30rpx;">
+
+				<view class="box-pack-between border-b header-version flex-y-center">
+					<view class="header-img">
+						营业执照照片
+						<view class="ft22">
+							(最大宽度 2160px,最大高度 3840px,不超过1M)
+						</view>
+					</view>
+					<view class="home-img" @click="uploadFile" data-type='1'>
+						<image :src="URL+license_pic" class="home-img-icon"></image>
+					</view>
+				</view>
+
+				<view class="box-pack-between border-b header-version flex-y-center">
+					<view class="header-img">
+						资质照片
+						<view class="ft22">
+							(最大宽度 2160px,最大高度 3840px,不超过1M)
+						</view>
+					</view>
+					<view class="home-img" @click="uploadFile" data-type='2'>
+						<image :src="URL+special_license_pic" class="home-img-icon" ></image>
+					</view>
+				</view>
+
+				<view class="box-pack-between border-b header-version flex-y-center">
+					<view class="header-img">
+						小程序logo图标
+						<view class="ft22">
+							(上传像素为180*180 px,logo图片最大 256KB,图片高度与宽度必须一致,如果头像过大,加载会慢点)
+						</view>
+					</view>
+					<view class="home-img" @click="uploadFile" data-type='3'>
+						<image :src="URL+app_logo" class="home-img-icon"></image>
+					</view>
+				</view>
+			</view>
+
+			<view class="bgf">
+				<view class="box-pack-between list flex-y-center br">
+					<text class="ft28">营业执照名称:</text>
+					<input class="flex-grow-1 tr ft28" :value="info.name" maxlength="128" name='name'
+						placeholder="请输入营业执照名称" />
+				</view>
+			</view>
+
+			<view class="bgf">
+				<view class="box-pack-between list flex-y-center br">
+					<text class="ft28">营业执照有效期:</text>
+					
+					<input class="flex-grow-1 tr ft28" :value="info.date" maxlength="64" name='date'
+						placeholder="营业执照有效期" />
+						
+				</view>
+			</view>
+
+			<view class="ft24 tip" >
+				Tip:营业执照有效期,格式为 yyyy-MM-dd,9999-12-31表示长期有效。
+			</view>
+
+			<!-- <view class="bgf">
+				<view class="box-pack-between list flex-y-center br">
+					<text class="ft28">小程序应用名称:</text>
+					<input class="flex-grow-1 tr ft28" :value="info.app_name" maxlength="64" name='app_name'
+						placeholder="请输入小程序应用名称" />
+				</view>
+			</view> -->
+			
+			<view class="bgf">
+				<view class="box-pack-between list flex-y-center br">
+					<text class="ft28">小程序客服电话:</text>
+					<input class="flex-grow-1 tr ft28" :value="info.phone" maxlength="32" name='phone'
+						placeholder="请输入小程序客服电话" />
+				</view>
+			</view>
+			
+			<view class="bgf">
+				<view class="box-pack-between list br" style="height: auto;padding: 20rpx 30rpx;">
+					<text class="ft28" style="min-width: 230rpx;">小程序版本描述:</text>
+					<textarea auto-height="true" class="flex-grow-1 tr ft28" :value="info.version_desc" maxlength="128" name='version_desc'
+						placeholder="小程序版本描述,30-500个字符。"  />
+						
+				</view>
+				<view class="tip ft24" @click="copy">
+					*参考:优化支付成功之后需要点击完成,才监听状态订单状态,修改为接口回调监听
+					 <text class="copy">点击复制</text>
+				</view>	
+				
+			</view>
+			 
+			<view class="bgf mar-24" @click="open" data-type="1">
+				<view class="box-pack-between list flex-y-center br">
+					<text class="ft28">门店地址</text>
+					<view class="flex-y-center ft26">
+						{{address.Prov_title || ''}} {{address.City_title || ''}} {{address.Dist_title || ''}}
+						<text class="iconfont icongengduo"></text>
+					</view>
+				</view>
+			</view>
+			
+			<view class="bgf" @click="open" data-type="2">
+				<view class="box-pack-between list flex-y-center br">
+					<text class="ft28" style="min-width: 120rpx;">小程序类目:</text>
+					<view class="flex-y-center ft26">
+						{{Mcc.mccCd1_title || ''}} {{Mcc.mccCd2_title || ''}} {{Mcc.mccCd3_title || ''}}
+						<text class="iconfont icongengduo"></text>
+					</view>
+				</view>
+			</view>
+			<view style="height: 140rpx;">
+				
+			</view>
+			<view class="flex-center pof">
+				<button formType="submit" class="flex-center login-btn">提交审核</button>
+			</view>
+			
+		</form>
+
+		<uni-popup ref="uniScroll" type="bottom">
+			<uni-scroll :Prov_arr="Prov_arr" @select="select"></uni-scroll>
+		</uni-popup>
+
+		<uni-popup ref="uniScrollailOne" type="bottom">
+			<uni-scrollail-one :Prov_arr="MccCd" @setlet="selectOne"></uni-scrollail-one>
+		</uni-popup>
+
+	</view>
+</template>
+<script>
+	import uniScroll from '../components/uni-scroll/uni-scroll.vue'
+	import uniScrollailOne from '../components/uni-scroll/uni-scrollail1.vue'
+	export default {
+		components: {
+			uniScroll,
+			uniScrollailOne,
+		},
+		data() {
+			return {
+				category_arr: [],
+				category_index: -1,
+				category_id: "",
+				URL: getApp().globalData.URL,				
+				license_pic: "",
+				special_license_pic: "",
+				app_logo:"",
+				Mcc: {
+					mccCd1_title: "请选择",
+					mccCd2_title: "",
+					mccCd3_title: "",
+				},
+				address: {
+					Prov_title: "请选择",
+					City_title: "",
+					Dist_title: "",
+				},
+				Prov_arr: [],
+				MccCd: [],
+				back_arr: [],
+				back_index: -1,
+				bank_name: "请选择",
+				info: {},
+				date:"",
+			}
+		},
+		
+		onLoad(e) {
+			this.merchant_id = e.merchant_id;
+			this.getCategory();
+			this.Prov();
+			this.preview();
+		},
+		
+		methods: {
+			copy(){
+				let content='优化支付成功之后需要点击完成,才监听状态订单状态,修改为接口回调监听';
+				uni.setClipboardData({
+					data: content,
+					success: function (r) {
+					    getApp().globalData.isApp = false
+						console.log('赋能成功',r);
+					}
+				});
+			},
+			getBusiness() {
+				this.request({
+					url: "alipay/getBusiness",
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code === '200') {
+						this.category_arr = res.data;
+						
+					}
+				})
+			},
+			
+			pickerDate(e){
+				this.date=e.detail.value;
+			},
+			
+			uploadFile(e) {
+				var type = e.currentTarget.dataset.type,
+				    url = type==3?"setting/logo_upload":"setting/upload";
+				uni.chooseImage({
+					success: (res) => {
+						res.tempFilePaths.forEach((v, i) => {
+							console.log(v)
+							this.Upload({
+								url:url,
+								data: {
+									url: v,
+									admin_id:uni.getStorageSync("admin_id"),
+								}
+							}).then(res => {
+								console.log(res, "res")
+									type == 1 ? (this.license_pic = res.src) :
+									type == 2 ? (this.special_license_pic = res.src) :
+									type == 3 ? (this.app_logo = res.src) : '';
+							}).catch({
+							});
+						})
+			
+					}
+				});
+			},
+			
+			preview(e) {
+				this.request({
+					url: "setting/alipayxcx",
+					data: {
+					admin_id:uni.getStorageSync("admin_id")
+					},
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code === '200') {
+						this.info = res.data;
+						this.app_logo = res.data.app_logo;
+						this.license_pic = res.data.license_pic;
+						this.special_license_pic = res.data.special_license_pic;
+									
+						this.address = {
+							Prov_title: res.data.province_name,
+							Prov_code: res.data.province_code,
+							City_title: res.data.city_name,
+							City_code: res.data.city_code,
+							Dist_title: res.data.area_name,
+							Dist_code: res.data.area_code,
+						}
+						this.Mcc = {
+							mccCd1_title: res.data.code1_name,
+							mccCd2_title: res.data.code2_name,
+							mccCd3_title: res.data.code3_name,
+							mccCd1: res.data.code1,
+							mccCd2: res.data.code2,
+							mccCd3: res.data.code3,
+						}
+					}
+				})
+			},
+
+			picker_back(e) {
+				this.bank_name = this.back_arr[e.target.value].bank_name;
+				this.back_index = e.target.value;
+			},
+
+			picker_category(e) {
+				this.category_id = this.category_arr[e.target.value].id;
+				this.category_index = e.target.value;
+			},
+			
+			// 获取一级分类
+			getCategory(e) {
+				this.request({
+					url: "setting/xcx_type",
+					data: {
+					},
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code === '200') {
+						this.MccCd = res.data;
+					}
+				});
+			},
+
+			open(e) {
+				var type = e.currentTarget.dataset.type;
+				if (type == 1) {
+					this.$refs.uniScroll.open();
+				} else {
+					this.$refs.uniScrollailOne.open();
+				}
+			},
+			
+          // 获取省
+			Prov(e) {
+				this.request({
+					url: "setting/getprovince",
+					data: {
+					},
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code === '200') {
+						this.Prov_arr = res.data;
+					}
+				});
+			},
+			
+			// 获取地址
+			select(e) {
+				console.log(e)
+				this.address = e;
+			},
+			// 获取分类
+			selectOne(e) {
+				console.log(e)
+				this.Mcc = e;
+			},
+
+			save(e) {
+				let data = e.detail.value;
+			    data.admin_id=uni.getStorageSync("admin_id");
+				data.license_pic= this.license_pic;   //营业执照照片
+				data.special_license_pic= this.special_license_pic;   //资质照片
+				data.app_logo=this.app_logo;
+				data.code1 = this.Mcc.mccCd1;   
+				data.code2 = this.Mcc.mccCd2;
+				data.code3 = this.Mcc.mccCd3;
+				data.province_code = this.address.Prov_code;
+				data.city_code = this.address.City_code;
+				data.area_code = this.address.Dist_code;
+				data.id = this.info.id;
+				
+				// if (!data.contact_email || !data.contact_name || !data.name || !data.oneCategory || !data.threeCategory ||
+				// 	!data.twoCategory || !data.detail_address) {
+				// 	uni.showToast({
+				// 		title: "必填项不能为空",
+				// 		icon: 'none'
+				// 	})
+				// 	return
+				// }
+             
+				this.request({
+					url: "setting/alipaysubmit",
+					data,
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code === '200') {
+						uni.showToast({
+							title: "提交成功"
+						})
+						setTimeout(() => {
+							uni.redirectTo({
+								url: "./Versioning",
+							})
+						}, 2000)
+					}
+				});
+			},
+
+
+		},
+	}
+</script>
+
+<style>
+	.copy{
+		margin-left: 10px;
+		color: #000000;
+	}
+	page {
+		background: #F1F1F1;
+	}
+
+	page .act {
+		color: #007AFF;
+	}
+	
+	.tip{
+		padding: 20rpx;
+		color: red;
+	}
+	.tr {
+		text-align: right;
+	}
+
+	.header-version {
+		padding: 20rpx 0;
+	}
+
+	.header-img {
+		max-width: 300rpx;
+	}
+
+	.mar-24 {
+		margin-top: 24rpx;
+	}
+
+	.list {
+		height: 100rpx;
+		padding: 0 30rpx;
+		background: #fff;
+		position: relative;
+	}
+
+	.addimg {
+		width: 90rpx;
+		height: 90rpx;
+	}
+
+	.icongengduo {
+		font-size: 28rpx;
+	}
+
+	.btm-btn-block {
+		width: 100%;
+		padding: 0 30rpx;
+		margin: 30px 0;
+	}
+
+	.btm-btn-block .btn {
+		width: 325rpx;
+		height: 98rpx;
+		border-radius: 8rpx;
+		text-align: center;
+		line-height: 98rpx;
+		font-size: 32rpx;
+		font-weight: 500;
+		margin: 0 auto;
+	}
+
+	.btm-btn-block .btn11 {
+		box-shadow: 0px 0px 8px 0px rgba(207, 219, 234, 0.4);
+		color: #3387FF;
+		border: 1rpx solid #3387FF;
+	}
+
+	.btm-btn-block .btn22 {
+		background: linear-gradient(315deg, #3387ff 2%, #569bff 99%);
+		box-shadow: 0 0 8rpx 0 rgba(51, 135, 255, 0.2);
+		color: #fff;
+	}
+
+	.login-btn {
+		width: 630rpx;
+		height: 98rpx;
+		background: linear-gradient(315deg, #3387ff 2%, #569bff 99%);
+		border-radius: 8rpx;
+		box-shadow: 0px 0px 8rpx 0px rgba(51, 135, 255, 0.2);
+		font-size: 32rpx;
+		font-weight: 500;
+		text-align: center;
+		color: #fff;
+		line-height: 98rpx;
+		/* margin: 100rpx auto 0; */
+	}
+
+	.home-img {
+		font-size: 26rpx;
+		text-align: center;
+		display: inline-block;
+		/* width: 50%; */
+	}
+
+	.home-img-icon {
+		border: 1rpx solid #ccc;
+		width: 200rpx;
+		height: 200rpx;
+	}
+	.pof{
+		position: fixed;
+		width: 100%;
+		bottom: 10rpx;
+		z-index: 11;
+	}
+</style>

+ 246 - 0
appletXcx/Alipay/addVersion.vue

@@ -0,0 +1,246 @@
+<template>
+	<view class="page">
+		<view class="step">
+			<uni-steps active-color="#3387FF" :options="[{title: '扫码授权',url:'./qrCode'}, {title: '小程序配置',url:'./deploy'}, 
+			{title: '提交版本',url:'./addVersion'},
+		    {title: '提交审核',url:'./addExamine'},{title: '版本管理',url:'./Versioning'} ]" :active="2"></uni-steps>
+		</view>
+
+		<view style="height: 130rpx;"></view>
+
+		<view class="home">
+
+			<form @submit="addVersion">
+
+				<view class="homeForm ft28">
+					<picker mode="selector" :range="tableTypeList" range-key="title" @change="onTableTypeChange">
+						<view class="item flex-y-center box-pack-between">
+							<text>门店id(仅限审核使用)</text>
+
+							<view>
+								<text>{{tableTypeActive}}</text>
+								<text class="iconfont icongengduo" style="font-size: 26rpx;"></text>
+							</view>
+
+						</view>
+					</picker>
+					<picker mode="selector" :range="tableList" range-key="id" @change="onTableChange">
+						<view class="item flex-y-center box-pack-between">
+							<text>位置id(仅限审核使用): </text>
+							<view>
+								<text>{{table_id}}</text>
+								<text class="iconfont icongengduo" style="font-size: 26rpx;"></text>
+							</view>
+
+							<input type="text" :value="table_id" name="table_id" placeholder="请输入餐桌id"
+								class="hide-input" />
+						</view>
+					</picker>
+
+					<view class="item flex-y-center box-pack-between">
+						<text>版本号:</text>
+						<view class="border">
+							<input type="text" :value="obj.user_version" name="user_version" placeholder="请输入版本号" />
+						</view>
+					</view>
+
+					<view class="tip">
+						Tip:进入门店列表(对应审核门店id)>进入位置管理>即可找到位置ID。提交的版本号需大于当前版本号。
+					</view>
+
+					<button hover-class="none" form-type="submit" class="flex-grow-1 flex-center submit ft28">
+						提交版本
+					</button>
+
+				</view>
+			</form>
+		</view>
+
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				tableTypeList: [],
+				tableTypeActive: "请选择",
+				table_id: '',
+				store_id: '',
+				obj: {},
+				tableList: []
+			}
+		},
+
+		onLoad() {
+			this.MiniVersion();
+		},
+
+		methods: {
+
+			addVersion(e) {
+				let {
+					table_id,
+					user_version
+				} = e.detail.value;
+				this.request({
+					url: 'setting/uploadMiniVersion',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+						store_id: this.store_id,
+						table_id,
+						user_version,
+					}
+				}).then(res => {
+					if (res.code == '200') {
+						console.log(res, "showModal")
+
+
+
+						uni.showModal({
+							title: '提示',
+							content: res.message,
+							showCancel: true,
+							cancelText: '关闭',
+							confirmText: '提交审核',
+							success: r => {
+								if (r.confirm) {
+									uni.redirectTo({
+										url: "./addExamine"
+									})
+								} else {
+									uni.navigateBack({
+										delta: 1
+									})
+								}
+							},
+							fail: () => {},
+							complete: () => {}
+						});
+					}
+				})
+			},
+
+			onTableTypeChange(e) {
+				let store_id = this.tableTypeList[e.detail.value].id
+				if (store_id != this.store_id) {
+					this.tableTypeActive = this.tableTypeList[e.detail.value].title;
+					this.store_id = store_id
+					this.table_id = ""
+					this.getTableList(this.store_id)
+				}
+
+			},
+			onTableChange(e) {
+				let table_id = this.tableList[e.detail.value].id
+				this.table_id = table_id
+			},
+
+			// 版本列表
+			MiniVersion(e) {
+				this.request({
+					url: 'setting/MiniVersion',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+					}
+				}).then(res => {
+					if (res.code == 200) {
+						this.obj = res.data;
+						this.shop_store_index();
+
+					}
+				})
+			},
+
+			shop_store_index() {
+				this.request({
+					url: 'Smdcshop/shop_store_index',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+					}
+				}).then(res => {
+					if (res.code == 200) {
+						this.tableTypeList = res.data;
+						if (this.obj.store_id) {
+							let info = res.data.find((item) => item.id == this.obj.store_id)
+							this.tableTypeActive = info.title;
+							this.store_id = info.id;
+
+						} else {
+							this.tableTypeActive = res.data[0].title;
+							this.store_id = res.data[0].id;
+						}
+						if (this.obj.table_id) {
+							this.table_id = this.obj.table_id
+						}
+						this.getTableList(this.store_id)
+					}
+				})
+			},
+			getTableList(store_id) {
+				this.request({
+					url: 'setting/tablelist',
+					data: {
+						store_id
+					}
+				}).then(res => {
+					if (res.code == 200) {
+						this.tableList = res.data;
+					}
+				})
+			},
+
+
+		}
+	}
+</script>
+
+<style>
+	@import url("../css/style.css");
+
+	.tip {
+		color: red;
+		font-size: 24rpx;
+	}
+
+	.homeForm {
+		padding: 20rpx;
+		padding-bottom: 40rpx;
+	}
+
+	.border {
+		padding: 10rpx;
+		border-bottom: 1rpx solid #F1F1F1;
+		text-align: right;
+	}
+
+	.submit {
+		background-color: #007AFF;
+		color: #FFFFFF;
+		width: 630rpx;
+		margin: 0 auto;
+		height: 98rpx;
+		margin-top: 30rpx;
+	}
+
+	.Transfer {
+		position: absolute;
+		bottom: 100rpx;
+		width: 100%;
+		text-align: center;
+		font-size: 28rpx;
+		color: #007AFF;
+	}
+
+	.Transfer navigator {
+		display: inline-block;
+	}
+
+	.hide-input {
+		position: fixed;
+		left: 1000px;
+		top: -1000px;
+		width: 0;
+		height: 0;
+	}
+</style>

+ 451 - 0
appletXcx/Alipay/deploy.vue

@@ -0,0 +1,451 @@
+<template>
+	<view>
+		<view class="step">
+			<uni-steps active-color="#3387FF" :options="[{title: '扫码授权',url:'./qrCode'}, {title: '小程序配置',url:'./deploy'}, 
+			{title: '提交版本',url:'./addVersion'},
+		    {title: '提交审核',url:'./addExamine'},{title: '版本管理',url:'./Versioning'} ]" :active="1"></uni-steps>
+		</view>
+		<view  style="height: 130rpx;"></view>
+		
+		<view class="home">
+			<view class="box-pack-between item flex-y-center border-b">
+				<text>小程序APPID</text>
+				<view  @click="copy(appid)">{{appid||''}} <text class="ft26" style="color:#3387FF;margin-left: 20rpx;">复制</text></view>
+			</view>
+
+			<view class="box-pack-between item flex-y-center">
+				<text>体验版成员</text>
+				<button class="deploy-add flex-center" hover="true" hover-class="detail-hover" @click="open">新增</button>
+			</view>
+
+			<view class="deploy-list" v-if="deplist.length>0">
+				<view class="item-bg" >
+					<view class="box-pack-between mar64 flex-y-center" v-for="(item,index) of deplist" :key='index'>
+						<view class="flex-y-center flex-grow-1 pdr-20">
+							<view class="deploy-list-nick text-1">
+								{{item.nick_name}}
+							</view>
+							<view class="deploy-list-logon text-1">
+								{{item.logon_id}}
+							</view>
+
+							{{item.status}}
+						</view>
+						<view class="iconfont iconshanjian item-del" @click="del(index)"></view>
+					</view>
+				</view>
+			</view>
+			
+		</view>
+
+		<view class="home">
+
+			<view class="box-pack-between item flex-y-center pd20">
+				<text>二维码规则配置</text>
+				<view class="flex">
+				<!-- 	<button class="deploy-add flex-center" hover="true" hover-class="detail-hover"
+						@click="ConfigRule">配置规则</button> -->
+					<button class="deploy-add flex-center" hover="true" hover-class="detail-hover"
+						@click="AppendRule">配置规则</button>
+				</view>
+			</view>
+
+			<view class="flex-y-center box-pack-between ft28 border-b pd2-3" v-for="(item,index) of linkArr"
+				:key='index'>
+				<view class="word">
+					<view class="qr_link">
+						地址:{{item.https}}
+					</view>
+					<view class="qr_link">
+						路径:{{item.pages}}
+					</view>
+				</view>
+				<view class="iconfont iconshanjian item-del" @click="DelRule(index)"></view>
+			</view>
+		</view>
+
+		<!-- 纵向排列 -->
+		<uni-popup ref="popup" type="center">
+			<view class="model">
+				<form @submit="addDeploy">
+					<view class="model-refund-title ft28">
+						请输入支付宝账号(体验者账号)
+					</view>
+					<view style="padding: 20rpx;">
+						<view class="amount-input">
+							<input type="text" name="logon_id" placeholder="请输入支付宝账号" />
+						</view>
+					</view>
+					<view class="flex-y-center model-refund-btn">
+						<view class="flex-grow-1 flex-center cancel" @click="cancel">
+							取消
+						</view>
+						<button hover-class="none" form-type="submit" class="flex-grow-1 flex-center submit ft28">
+							添加
+						</button>
+					</view>
+				</form>
+			</view>
+		</uni-popup>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				appid: "",
+				deplist: [],
+				linkArr: [],
+			}
+		},
+		onLoad() {
+			this.getAppid();
+			this.alipay_MiniUserlist();
+			this.ewmguizhe();
+		},
+		methods: {
+			
+			open() {
+				this.$refs.popup.open();
+			},
+			cancel() {
+				this.$refs.popup.close();
+			},
+	
+			copy(appid) {
+				// #ifdef MP-WEIXIN
+				uni.setClipboardData({
+					data:appid,
+					success: function() {
+						console.log('success');
+					}
+				});
+				// #endif
+
+				// #ifdef H5
+				let content = appid;
+				if (!document.queryCommandSupported('copy')) {
+					// 不支持
+					return false
+				}
+				let textarea = document.createElement("input")
+				textarea.value = content
+				textarea.readOnly = "readOnly"
+				document.body.appendChild(textarea)
+				textarea.select() // 选择对象
+				textarea.setSelectionRange(0, content.length) //核心
+				let result = document.execCommand("copy") // 执行浏览器复制命令
+				textarea.remove();
+				uni.showToast({
+					title: "复制成功",
+					icon: 'none'
+				})
+				return result
+				// #endif
+			},
+			// 删除支付宝体验者
+			del(index) {
+				uni.showModal({
+					title: '提示',
+					content: '确定要删除用户吗?',
+					showCancel: true,
+					cancelText: '取消',
+					confirmText: '确定',
+					success: res => {
+						if (res.confirm) {
+							this.request({
+								url: 'setting/delMiniUser',
+								data: {
+									admin_id: uni.getStorageSync("admin_id"),
+									user_id: this.deplist[index].user_id,
+								}
+							}).then(res => {
+
+								uni.showToast({
+									title: res.message,
+									icon: 'none'
+								})
+								this.deplist.splice(index, 1);
+							})
+						}
+					},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+			// 新增规则
+			ConfigRule(e) {
+				this.request({
+					url: 'setting/oldaddqrcode',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+					}
+				}).then(res => {
+					if (res.code == 200) {
+						uni.showToast({
+							title: res.message,
+							icon: 'none'
+						})
+						setTimeout(()=>{
+							this.ewmguizhe();
+						},2000)
+					}
+				})
+			},
+			// 追加规则
+			AppendRule(e) {
+				this.request({
+					url: 'setting/addqrcode',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+					}
+				}).then(res => {
+					if (res.code == 200) {
+						uni.showToast({
+							title: res.message,
+							icon: 'none'
+						})
+						setTimeout(()=>{
+							this.ewmguizhe();
+						},2000)
+					}
+				})
+			},
+			// 删除规则
+			DelRule(index) {
+				uni.showModal({
+					title: '提示',
+					content: '确定要删除规则吗?',
+					showCancel: true,
+					cancelText: '取消',
+					confirmText: '确定',
+					success: res => {
+						if (res.confirm) {
+							this.request({
+								url: 'setting/delewmgz',
+								data: {
+									admin_id: uni.getStorageSync("admin_id"),
+									id: this.linkArr[index].id,
+								}
+							}).then(res => {
+								uni.showToast({
+									title: res.message,
+									icon: 'none'
+								})
+								
+								this.linkArr.splice(index, 1);
+							})
+						}
+					},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+			// 规则列表
+			ewmguizhe(e) {
+				this.request({
+					url: 'setting/ewmguizhe',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+					}
+				}).then(res => {
+					if (res.code == 200) {
+						this.linkArr = res.data;
+					}
+				})
+			},
+			
+			// 添加支付宝体验者
+			addDeploy(e) {
+				let {
+					logon_id
+				} = e.detail.value;
+				this.request({
+					url: 'setting/addMiniUser',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+						logon_id: logon_id,
+					}
+				}).then(res => {
+					if (res.code == 200) {
+						this.alipay_MiniUserlist();
+						this.$refs.popup.close();
+					}
+				})
+			},
+			// 获取appid
+			getAppid() {
+				this.request({
+					url: 'setting/alipay_Appid',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+					}
+				}).then(res => {
+					if (res.code == 200) {
+						this.appid = res.data.appid;
+					}
+				})
+			},
+			// 获取体验者
+			alipay_MiniUserlist() {
+				this.request({
+					url: 'setting/alipay_MiniUserlist',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+					}
+				}).then(res => {
+					if (res.code == 200) {
+						this.deplist = res.data;
+					}
+				})
+			},
+		}
+	}
+</script>
+
+<style>
+	@import url("../css/style.css");
+
+	page .detail-hover {
+		opacity: 0.6;
+		transform: scale(0.8, 0.8);
+		/*缩放*/
+		/* background-color: #999999; */
+		/* color: #999999; */
+	}
+
+	.pd20 {
+		padding: 20rpx;
+	}
+
+	.pd2-3 {
+		padding: 20rpx 30rpx;
+	}
+
+	.step {
+		padding: 20rpx 0;
+		position: fixed;
+		width: 100%;
+		background: #FFFFFF;
+		z-index: 999;
+	}
+
+/* 	.home {
+		background-color: #FFFFFF;
+		margin-bottom: 20rpx;
+	}
+
+	.item {
+		height: 100rpx;
+		padding: 0 20rpx;
+	} */
+
+	.deploy-add {
+		padding: 0 22rpx;
+		height: 60rpx;
+		text-align: center;
+		border-radius: 10rpx;
+		font-size: 28rpx;
+		background-color: #007AFF;
+		color: #FFFFFF;
+		margin-left: 20rpx;
+	}
+
+	.deploy-list {
+		padding: 24rpx;
+
+	}
+
+	.item-bg {
+		background: #f6f8fe;
+		border-radius: 12rpx;
+		margin: 0 auto;
+		font-size: 28rpx;
+		font-family: PingFang SC, PingFang SC-Regular;
+		font-weight: 400;
+		color: #333333;
+		padding: 36rpx 32rpx;
+	}
+
+	.item-del {
+		color: red;
+	}
+
+	.item-bg-32 {
+		margin-right: 32rpx;
+	}
+
+	.item-bg .mar64:last-child {
+		margin-bottom: 0rpx;
+	}
+
+	.deploy-list-nick {
+		width: 150rpx;
+		margin-right: 20rpx;
+	}
+
+	.deploy-list-logon {
+		width: 180rpx;
+		margin-right: 30rpx;
+	}
+
+	.mar64 {
+		margin-bottom: 64rpx;
+	}
+
+	.amount-input {
+		padding: 20rpx;
+		border: 1rpx solid #F1F1F1;
+	}
+
+	.model {
+		background: #FFFFFF;
+		border-radius: 10rpx;
+		width: 600rpx;
+		overflow: hidden;
+	}
+
+	.model-refund-title {
+		text-align: center;
+		padding: 20rpx 0;
+	}
+
+	.model-refund-btn {
+		border-top-color: #f5f5f5;
+		border-top-style: solid;
+		border-top-width: 1px;
+
+	}
+
+	.model-refund-btn .cancel {
+		height: 90rpx;
+	}
+
+	.model-refund-btn .submit {
+
+		height: 90rpx;
+		border-left: 1rpx solid #f1f1f1;
+		border-radius: 0;
+	}
+
+	button {
+		background-color: #fff;
+		padding: 0;
+		margin: 0;
+		line-height: 1rpx;
+		/* border: 1px solid #cccccc; */
+		min-height: 0;
+		font-size: 28rpx;
+		background: #fff;
+		border-radius: none;
+	}
+
+	button::after {
+		border: none;
+	}
+
+	.qr_link {
+		margin-bottom: 10rpx;
+	}
+</style>

+ 187 - 0
appletXcx/Alipay/index.vue

@@ -0,0 +1,187 @@
+<template>
+	<view class="content">
+		
+		
+		<view class="header">
+			<image src="../../static/images/skm_fn_bg.png" mode="aspectFill" class="bg-img"></image>
+			<view class="info-block flex-y-center">
+				<view class="info">
+					<view class="title">支付宝小程序管理</view>
+					<view class="desc">手机管理方便又快捷</view>
+				</view>
+			</view>
+		</view>
+		
+		<view class="content-row">
+			
+			<view class="setup flex-y-center ft32">
+				常用应用
+			</view>
+			
+			<view class="table">
+				
+				<view class="table-tr">
+					
+					<navigator class="table-td" url="./qrCode?type=1">
+						<view class="iconfont iconz-alipay"></view>
+						<view class="">支付宝授权</view>
+					</navigator>
+					
+					<navigator class="table-td" url="./deploy">
+						<view class="iconfont iconpeizhi"></view>
+						<view class="">小程序配置</view>
+					</navigator>
+					
+					<navigator class="table-td" url="./addVersion">
+						<view class="iconfont iconbanben"></view>
+						<view class="">提交版本</view>
+					</navigator>
+					
+					<navigator class="table-td" url="./addExamine">
+						<view class="iconfont iconshenhe"></view>
+						<view class="">提交审核</view>
+					</navigator>
+					
+					<navigator class="table-td" url="./Versioning">
+						<view class="iconfont iconbanbengengxin"></view>
+						<view class="">版本管理</view>
+					</navigator>
+					
+					<navigator class="table-td" url="./sign">
+						<view class="iconfont iconrenwuqianyue"></view>
+						<view class="">订单中心签约</view>
+					</navigator>
+
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+	export default {
+		data() {
+			return {
+				is_admin:1
+			}
+		},
+
+		onLoad(e) {
+			this.is_admin=e.is_admin||1;
+		},
+
+		methods: {
+
+
+		}
+	}
+</script>
+
+<style>
+	.setup {
+		width: 100%;
+		height: 90rpx;
+
+		opacity: 1;
+		padding: 0 22rpx;
+	}
+
+	.table,
+	.table div {
+		margin: 0 auto;
+	}
+
+	.table {
+		/* display: table; */
+		width: 100%;
+		border-collapse: collapse;
+		box-sizing: border-box;
+	}
+
+	.table-tr {
+		/* display: table-row; */
+		/* height: 92rpx; */
+	}
+
+	.table-th {
+		display: table-cell;
+		font-weight: bold;
+		border: 1rpx solid #FAFAFA;
+		text-align: center;
+		vertical-align: middle;
+	}
+
+	.table-td {
+		display: inline-block;
+		border: 1rpx solid #FAFAFA;
+		text-align: center;
+		vertical-align: middle;
+		background: #fff;
+		font-size: 27rpx;
+		color: #666666;
+		padding: 62rpx 0;
+		width: 33.333%;
+	}
+
+	.table-td image {
+		width: 50rpx;
+		height: 50rpx;
+		margin-bottom: 23rpx;
+	}
+
+	.header {
+		width: 100%;
+		height: 198rpx;
+		position: relative;
+	}
+
+	.header .bg-img {
+		display: block;
+		position: absolute;
+		left: 0;
+		top: 0;
+		z-index: 1;
+		width: 100%;
+		height: 198rpx;
+	}
+
+	.header .info-block {
+		padding: 0 40rpx 0 48rpx;
+		height: 198rpx;
+		position: relative;
+		z-index: 2;
+	}
+
+	.header .info-block .title {
+		font-size: 36rpx;
+		color: #fff;
+		font-weight: 500;
+		line-height: 50rpx;
+	}
+
+	.header .info-block .desc {
+		font-size: 28rpx;
+		font-weight: 500;
+		color: #fff;
+		line-height: 40rpx;
+		margin-top: 8rpx;
+	}
+
+	.header .info-block .btn {
+		width: 170rpx;
+		height: 56rpx;
+		border-radius: 28rpx;
+		background-color: rgb(255, 255, 255);
+		text-align: center;
+		line-height: 52rpx;
+		font-size: 28rpx;
+		font-weight: 500;
+		color: #3387FF;
+	}
+	
+	.table-td .iconfont{
+		font-size: 50rpx;
+		color: #3b93fc;
+		margin-bottom: 10rpx;
+	}
+</style>
+

+ 250 - 0
appletXcx/Alipay/qrCode.vue

@@ -0,0 +1,250 @@
+<template>
+	<view class="content">
+		
+		<view class="step">
+			<uni-steps active-color="#3387FF" :options="[{title: '扫码授权',url:'./qrCode'}, {title: '小程序配置',url:'./deploy'}, 
+			{title: '提交版本',url:'./addVersion'},
+		    {title: '提交审核',url:'./addExamine'},{title: '版本管理',url:'./Versioning'} ]" :active="0"></uni-steps>
+		</view>
+		<view  style="height: 130rpx;"></view>
+		
+		<view class="hg72"></view>
+		<view class="home-content">
+			<view class="home-content-title flex-center">
+				支付宝授权二维码
+			</view>
+			<view class="home-content-code flex-center">
+				<view class="">
+					<tki-qrcode v-if="ifShow" cid="qrcode1" ref="qrcode" :val="qrcodeVal" :size="size" :unit="unit"
+						:background="background" :foreground="foreground" :pdground="pdground" :icon="icon"
+						:iconSize="iconsize" :lv="lv" :onval="onval" :loadMake="loadMake" :usingComponents="true"
+						@result="qrR"/>
+				</view>
+			</view>
+		</view>
+		<view class="bottom-bar" style="background: none;">
+			<button @click="upCode">
+				下载二维码
+			</button>
+		</view>
+		
+	</view>
+</template>
+
+<script>
+	// #ifdef MP-WEIXIN
+	import saveImgToPhotosAlbum from "@/static/js/saveImgToPhotosAlbum.js";
+	// #endif
+	import tkiQrcode from "../components/tki-qrcode/tki-qrcode.vue"
+	export default {
+		components: {
+			tkiQrcode,
+		},
+		data() {
+			return { //二维码相关参数
+				ifShow: true,
+				val: '二维码', // 要生成的二维码值
+				size: 350, // 二维码大小
+				unit: 'upx', // 单位
+				background: '#000000', // 背景色
+				foreground: '#ffffff', // 前景色
+				pdground: '#ffffff', // 角标色
+				icon: '', // 二维码图标
+				iconsize: 40, // 二维码图标大小
+				lv: 3, // 二维码容错级别 , 一般不用设置,默认就行
+				onval: false, // val值变化时自动重新生成二维码
+				loadMake: true, // 组件加载完成后自动生成二维码
+				src: '', // 二维码生成后的图片地址或base64
+				info: {},
+				id: "",
+				URL: getApp().globalData.URL,
+				qrcodeVal: "",
+				wxqr: 1,
+				qrcodeImg:'',
+			}
+		},
+		
+		onLoad(e) {
+			this.http();
+		},
+
+		methods: { 
+			
+			//传入组件的方法
+			
+			qrR(e) {
+				this.qrcodeImg=e;
+				console.log(e, "ee")
+			},
+			
+			http() {
+				this.request({
+					url: 'Smdcshop/alipay_shouquan',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+					},
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code === "200") {
+						this.qrcodeVal = res.data
+						setTimeout(()=>{
+							this.$refs.qrcode._makeCode()
+						},50)
+					}
+				});
+			},
+
+			upCode(e) {
+				// #ifdef H5
+				uni.showModal({
+					title: '提示',
+					content: '请长按二维码图片进行保存',
+					showCancel: false,
+					confirmText: '好的',
+				});
+				// #endif
+				// #ifdef MP-WEIXIN 
+				this.$refs.qrcode._saveCode()
+				
+				return
+				
+				var url = this.qrcodeImg;
+				console.log(url, "url")
+				saveImgToPhotosAlbum.saveImgToPhotosAlbum(url).then((res) => {
+					//成功的逻辑
+					console.log(res, "保存成功")
+					uni.showToast({
+						title: '保存成功',
+						icon: 'none',
+						mask: true,
+					})
+				}).catch((err) => {
+					console.log(err, "保存失败")
+					if (err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" ||
+						err.errMsg === "saveImageToPhotosAlbum:fail auth deny" || err.errMsg ===
+						"saveImageToPhotosAlbum:fail authorize no response") {
+						// 这边微信做过调整,必须要在按钮中触发,因此需要在弹框回调中进行调用
+						uni.showModal({
+							title: '提示',
+							content: '需要您设置授权保存相册',
+							showCancel: false,
+							success: modalSuccess => {
+								uni.openSetting({
+									success(settingdata) {
+										console.log("settingdata", settingdata)
+										if (settingdata.authSetting[
+												'scope.writePhotosAlbum']) {
+											uni.showModal({
+												title: '提示',
+												content: '获取权限成功,再次点击图片即可保存',
+												showCancel: false,
+											})
+										} else {
+											uni.showModal({
+												title: '提示',
+												content: '获取权限失败,将无法保存到相册哦~',
+												showCancel: false,
+											})
+										}
+									},
+									fail(failData) {
+										console.log("failData", failData)
+									},
+									complete(finishData) {
+										console.log("finishData", finishData)
+									}
+								})
+
+							}
+						})
+					}
+					// 失败后的逻辑
+				})
+				// #endif			
+			},
+		}
+	}
+</script>
+
+<style>
+	page {
+		background: #F5F7FA;
+	}
+
+	.hg72 {
+		height: 72rpx;
+	}
+
+	.home-content {
+		background: #FFFFFF;
+		width: 670rpx;
+		height: 843rpx;
+		margin: 0 auto;
+		position: relative;
+
+	}
+
+	.home-content-title {
+		width: 100%;
+		height: 154rpx;
+		background: linear-gradient(180deg, #449efb, #3387ff);
+		border-radius: 16rpx 16rpx 0px 0px;
+		font-size: 36rpx;
+		font-family: PingFang SC, PingFang SC-Medium;
+		font-weight: 500;
+		color: #ffffff;
+	}
+
+	.home-content-code {
+		width: 100%;
+		height: 689rpx;
+		font-size: 32rpx;
+		font-family: PingFang SC, PingFang SC-Regular;
+		font-weight: 400;
+		color: #464646;
+		text-align: center;
+	}
+
+	.home-content-code image {
+		width: 400rpx;
+		height: 400rpx;
+		margin-bottom: 64rpx;
+	}
+
+	.home-content-code-title {
+		padding: 0 30rpx;
+		color: red;
+	}
+
+	.code-btn {
+		font-size: 32rpx;
+		font-family: PingFang SC, PingFang SC-Regular;
+		font-weight: 400;
+		color: #3c8cff;
+		margin-bottom: 35rpx;
+	}
+
+	.bottom-bar {
+		position: fixed;
+		/* bottom: 50rpx; */
+		width: 100%;
+		z-index: 1000;
+		padding: 30rpx 0;
+
+	}
+
+	.bottom-bar button {
+		text-align: center;
+		width: 690rpx;
+		height: 90rpx;
+		background: linear-gradient(132deg, #3387FF 0%, #3387FF 100%);
+		box-shadow: 0px 2rpx 12rpx #3387FF;
+		opacity: 1;
+		border-radius: 10rpx;
+		color: #fff;
+		font-size: 32rpx;
+		font-family: Source Han Sans CN, Source Han Sans CN-Medium;
+		font-weight: 500;
+		color: #ffffff;
+	}
+</style>

+ 135 - 0
appletXcx/Alipay/sign.vue

@@ -0,0 +1,135 @@
+<template>
+	<view class="pages">
+
+		<view class="title">
+			添加能力
+		</view>
+
+		<view class="">
+			小程序创建完成后,开发者登录 开放平台控制台 > 找到已创建的小程序 > 点击进入小程序管理后台 > 在 版本管理 页面的 能力列表 部分点击添加能力 > 勾选 小程序订单中心 能力并点击 确定 完成能力添加。
+		</view>
+
+		<view class="hg20">
+
+		</view>
+
+		<view class="title">
+			签约能力
+		</view>
+
+		<view class="">
+			小程序创建完成后,开发者登录 开放平台控制台 > 找到已创建的小程序 > 点击进入小程序管理后台 > 在 版本管理 页面的 能力列表 部分点击添加能力 > 勾选 小程序订单中心 能力并点击 确定 完成能力添加。
+		</view>
+		<view class="hg20">
+
+		</view>
+		<view class="red">
+			*小程序上线后再进行签约
+		</view>
+
+		<button hover-class="none" @click="bindSign" class="flex-grow-1 flex-center submit ft28">
+			签约小程序订单中心
+		</button>
+		
+		<view class="desc">
+			{{desc}}
+		</view>
+		
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				desc: '',
+			}
+		},
+		onLoad() {
+			this.queryAgent();
+		},
+
+		methods: {
+			queryAgent() {
+				this.request({
+					url: 'setting/order_center_queryAgent',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+					}
+				}).then(res => {
+					if (res.code == 200) {
+						this.desc = res.data.msg;
+					}
+				})
+			},
+			// 规则列表
+			bindSign(e) {
+				uni.showModal({
+					title: '提示',
+					content: "是否要签约订单中心?",
+					showCancel: true,
+					cancelText: '取消',
+					confirmText: '确定',
+					success: r => {
+						if (r.confirm) {
+							this.request({
+								url: 'setting/qianyue',
+								data: {
+									admin_id: uni.getStorageSync("admin_id"),
+									type: 1,
+								}
+							}).then(res => {
+								if (res.code == 200) {
+									uni.showToast({
+										title: res.message
+									})
+
+								}
+							})
+
+						}
+					},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+
+		}
+	}
+</script>
+
+<style>
+	.pages {
+		padding: 30rpx;
+	}
+
+	.desc {
+		width: 630rpx;
+		margin: 0 auto;
+		color: red;
+		text-align: center;
+		padding-top: 30rpx;
+	}
+
+	.title {
+		font-size: 32rpx;
+		font-weight: 600;
+	}
+
+	.hg20 {
+		height: 20rpx;
+	}
+
+	.red {
+		color: red;
+	}
+
+	.submit {
+		background-color: #007AFF;
+		color: #FFFFFF;
+		width: 630rpx;
+		margin: 0 auto;
+		height: 98rpx;
+		margin-top: 30rpx;
+	}
+</style>

+ 663 - 0
appletXcx/Wechat/Versioning.vue

@@ -0,0 +1,663 @@
+<template>
+	<view class="pages" @click="openExpers">
+		<view class="step">
+			<uni-steps active-color="#07c160" :options="options" :active="5"></uni-steps>
+		</view>
+		<view style="height: 130rpx;"></view>
+
+		<view class="version">
+			<view class="versionTip">
+				Tip:如审核失败,请先将看审核失败的详情,根据详情修改完成之后,再重新提交审核,审核通过直接发布即可
+			</view>
+			<view class="versionOnline" v-if="release_obj.user_version">
+				<view class="versionOnlineTitle box-pack-between">
+					<text>线上版本</text>
+					<view class="flex-y-center por">
+						<view class="versionOnlineTitle-btn flex-center" @click.stop="versionBack()">
+							版本回退
+						</view>
+					</view>
+				</view>
+				<view class="versionOnlineTitleBg ">
+					<view class="versionOnlineTitleNum ft32">
+						{{release_obj.user_version}}
+					</view>
+					<view class="versionOnlineTitleTime ft24">
+						在 {{release_obj.tijiao_time}} 提交上传
+					</view>
+					<view class="versionOnlineTitleTime ft24">
+						在 {{release_obj.fabu_time}} 提交发布
+					</view>
+				</view>
+			</view>
+
+			<view class="versionOnline" v-if="shen_obj.user_version">
+				<view class="versionOnlineTitle box-pack-between">
+					<text>审核版本 <text style="color: red;">({{shen_obj.status==2?'审核中':shen_obj.status==1?'审核被拒绝':
+							shen_obj.status==0?'审核通过':''}})</text></text>
+
+					<view class="flex-y-center" style="font-weight: 400;" @click.stop="bindWithdraw(shen_obj.id)">
+						<text>{{shen_obj.status==2?'撤回审核':shen_obj.status==1?'失败详情':shen_obj.status==0?'发布上线':''}}
+						</text>
+						<text class="iconfont icongengduo"></text>
+					</view>
+				</view>
+
+				<view class="versionOnlineTitleBgShen"
+					:style="{backgroundColor:shen_obj.status==1?'#f73131':'#4395ff'}">
+					<view class="versionOnlineTitleNum ft32 box-pack-between" @click.stop="bindRefuse(shen_obj.id)">
+						<text>{{shen_obj.user_version}}</text>
+						<text v-if="shen_obj.status==1" class="ft24">失败详情 <text
+								style="font-size: 24rpx;padding-left: 10rpx;" class="iconfont icontishi"></text></text>
+					</view>
+					<view class="versionOnlineTitleTime ft24">
+						在 {{shen_obj.tijiao_time}} 提交上传
+					</view>
+					<view class="versionOnlineTitleTime ft24">
+						在 {{shen_obj.tijiao_time}} 审核时间
+
+						项目备注:{{tiyan_obj.user_desc}}
+					</view>
+				</view>
+
+			</view>
+
+			<view class="versionOnline" v-if="tiyan_obj.user_version">
+				<view class="versionOnlineTitle box-pack-between">
+					<text>体验版本</text>
+					<view class="flex-y-center por">
+						<view class="versionOnlineTitle-btn flex-center" @click.stop="open(3)">
+							提交审核
+						</view>
+						<view class="versionOnlineTitle-down" @click.stop="openExper">
+							<view class="iconfont iconiconfontjiantou"></view>
+						</view>
+						<view class="poa Experience" v-if="is_experience" @click.stop="bindPreview(tiyan_obj.id)">
+							生成体验版
+						</view>
+					</view>
+				</view>
+				<view class="versionOnlineTitleBg " style="background-color: #42b983;">
+					<view class="versionOnlineTitleNum ft32 box-pack-between">
+						<text>{{tiyan_obj.user_version}}</text>
+					</view>
+					<view class="versionOnlineTitleTime ft24">
+						在 {{tiyan_obj.create_time}} 提交上传
+					</view>
+					<view class="versionOnlineTitleTime ft24">
+						项目备注:{{tiyan_obj.user_desc}}
+					</view>
+				</view>
+			</view>
+		</view>
+		<uni-popup ref="popup" type="center">
+			<view class="popup-content" v-if="type==1">
+				<image :src="qrcodeImg"></image>
+				<view class="save-btn flex-center" @click.stop="upCode">
+					保存图片
+				</view>
+			</view>
+
+			<view v-if="type==2" class="popup-content-desc">
+				<scroll-view scroll-y="true" style="height: 100%;">
+					<!-- {{desc}} -->
+					<rich-text :nodes="desc"></rich-text>
+					<image v-for="(item,index) in imgAudit" :src="item" @click="bindImg(item)" mode="widthFix"
+						class="imgAudit"></image>
+				</scroll-view>
+			</view>
+
+			<block v-if="type==3">
+				<view class="model">
+					<form @submit="bindSubmit">
+						<view class="model-refund-title ft28">
+							提交审核
+						</view>
+						<view style="padding: 20rpx;">
+							<view class="amount-input">
+								<textarea type="text" placeholder-style="font-size:26rpx" maxlength="60"
+									auto-height="true" name="tag" placeholder="版本描述" />
+							</view>
+						</view>
+						<view class="flex-y-center model-refund-btn">
+							<view class="flex-grow-1 flex-center cancel ft26" @click.stop="cancel">
+								取消
+							</view>
+							<button hover-class="none" form-type="submit" class="flex-grow-1 flex-center submit ft28">
+								确定
+							</button>
+						</view>
+					</form>
+				</view>
+			</block>
+		</uni-popup>
+	</view>
+</template>
+
+<script>
+	import optionsData from './data.js'
+	// #ifdef MP-WEIXIN
+	import saveImgToPhotosAlbum from "@/static/js/saveImgToPhotosAlbum.js";
+	// #endif
+	export default {
+		data() {
+			return {
+				release_obj: {},
+				tiyan_obj: {},
+				shen_obj: {},
+				qrcodeImg: '',
+				type: 1,
+				desc: '',
+				is_experience: false,
+				URL: getApp().globalData.URL,
+				imgAudit: [],
+				options:optionsData.options
+			}
+		},
+
+		onLoad() {
+			this.releaseVenson();
+			this.tiyanVenson();
+			this.shenVenson();
+		},
+
+		methods: {
+			// 版本回退
+			versionBack() {
+				//
+				uni.showModal({
+					content:"确定要版本回退",
+					success: (r) => {
+						if(r.confirm){
+							this.request({
+								url:'setting/revertcoderelease',
+								data: {
+									admin_id: uni.getStorageSync("admin_id"),
+								}
+							}).then(res=>{
+								if (res.code == 200) {
+									uni.showModal({
+										content:res.message,
+										showCancel:false,
+										success: (r) => {
+											this.releaseVenson();
+											this.tiyanVenson();
+											this.shenVenson();
+										}
+									})
+								}								
+							})
+						}
+					}
+				})
+			},
+			cancel() {
+				this.$refs.popup.close();
+			},
+
+			openExpers(e) {
+				this.is_experience = false;
+			},
+			openExper(e) {
+				this.is_experience = !this.is_experience;
+			},
+
+			//撤回审核2、失败详情1、发布上线0
+			bindWithdraw(id) {
+
+				if (this.shen_obj.status == 0) {
+					this.request({
+						url: 'setting/release',
+						data: {
+							admin_id: uni.getStorageSync("admin_id"),
+							id: id,
+						}
+					}).then(res => {
+						if (res.code == 200) {
+							uni.showToast({
+								title: res.message
+							})
+							setTimeout(() => {
+								this.releaseVenson();
+								this.tiyanVenson();
+								this.shenVenson();
+							}, 2000)
+						}
+					})
+				}
+				if (this.shen_obj.status == 1) {
+					this.request({
+						url: 'setting/getLastAudit',
+						data: {
+							admin_id: uni.getStorageSync("admin_id"),
+							// id,
+						}
+					}).then(res => {
+						if (res.code == 200) {
+							this.desc = res.data.reason;
+							this.imgAudit = res.data.screenshot;
+							this.type = 2;
+							this.$refs.popup.open();
+						}
+					})
+				}
+				if (this.shen_obj.status == 2) {
+					uni.showModal({
+						title: '提示',
+						content: "是否要撤回审核?",
+						showCancel: true,
+						cancelText: '取消',
+						confirmText: '确定',
+						success: r => {
+							if (r.confirm) {
+								this.request({
+									url: 'setting/unDoCodeAudit',
+									data: {
+										admin_id: uni.getStorageSync("admin_id"),
+										id: id,
+									}
+								}).then(res => {
+									if (res.code == 200) {
+										uni.showToast({
+											title: "撤回成功"
+										})
+										setTimeout(() => {
+											this.shenVenson();
+										}, 2000)
+									}
+								})
+
+							}
+						},
+						fail: () => {},
+						complete: () => {}
+					});
+				}
+			},
+
+			open() {
+				this.type = 3;
+				this.$refs.popup.open();
+			},
+
+			// 体验版二维码
+			bindPreview(id) {
+				this.request({
+					url: 'setting/getExpVersion',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+						id,
+					}
+				}).then(res => {
+					if (res.code == 200) {
+						this.qrcodeImg = getApp().globalData.URL + res.data;
+						this.type = 1;
+						this.is_experience = false;
+						this.$refs.popup.open();
+					}
+				})
+			},
+
+			// 提交审核
+			bindSubmit(e) {
+				this.request({
+					url: 'setting/submitReview',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+						tag: e.detail.value.tag,
+					},
+					hide:true
+				}).then(res => {
+					
+					if (res.code == 200 || res.code == '200') {
+						uni.showToast({
+							title: res.message,
+						})
+						this.shenVenson();
+						this.$refs.popup.close();
+					}
+					
+				}).catch((err)=>{
+					
+					uni.showModal({
+						title: '提示',
+						content: err.message,
+						showCancel: false,
+						cancelText: '取消',
+						confirmText: '确定',
+						success: r => {
+						}
+					})
+					
+				})
+			},
+
+			// 失败详情
+			bindRefuse(id) {
+				this.request({
+					url: 'setting/getLastAudit',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+						// id,
+					}
+				}).then(res => {
+					if (res.code == 200) {
+						this.desc = res.data.reason;
+						this.imgAudit = res.data.screenshot;
+						this.type = 2;
+						this.$refs.popup.open();
+					}
+				})
+			},
+			bindImg(url) {
+				uni.previewImage({
+					urls: [url],
+				});
+			},
+			// 线上版本
+			releaseVenson(e) {
+				this.request({
+					url: 'setting/wechat_release',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+					}
+				}).then(res => {
+					if (res.code == 200) {
+						this.release_obj = res.data;
+					}
+				})
+			},
+
+			// 体验版本
+			tiyanVenson(e) {
+				this.request({
+					url: 'setting/wechat_tiyan',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+					}
+				}).then(res => {
+					if (res.code == 200) {
+						this.tiyan_obj = res.data;
+					}
+				})
+			},
+
+			// 审核版本
+			shenVenson(e) {
+				this.request({
+					url: 'setting/wechat_shen',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+					}
+				}).then(res => {
+					if (res.code == 200) {
+						this.shen_obj = res.data;
+					}
+				})
+			},
+
+
+			upCode(e) {
+				// #ifdef H5
+				uni.showModal({
+					title: '提示',
+					content: '请长按二维码图片进行保存',
+					showCancel: false,
+					confirmText: '好的',
+				});
+				// #endif
+				// #ifdef MP-WEIXIN 
+				var url = this.qrcodeImg;
+				console.log(url, "url")
+				saveImgToPhotosAlbum.saveImgToPhotosAlbum(url).then((res) => {
+					//成功的逻辑
+					console.log(res, "保存成功")
+					wx.showToast({
+						title: '保存成功',
+						icon: 'none',
+						mask: true,
+					})
+					setTimeout(() => {
+						this.$refs.popup.close();
+					}, 2000)
+				}).catch((err) => {
+					console.log(err, "保存失败")
+					if (err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" ||
+						err.errMsg === "saveImageToPhotosAlbum:fail auth deny" || err.errMsg ===
+						"saveImageToPhotosAlbum:fail authorize no response") {
+						// 这边微信做过调整,必须要在按钮中触发,因此需要在弹框回调中进行调用
+						uni.showModal({
+							title: '提示',
+							content: '需要您设置授权保存相册',
+							showCancel: false,
+							success: modalSuccess => {
+								uni.openSetting({
+									success(settingdata) {
+										console.log("settingdata", settingdata)
+										if (settingdata.authSetting[
+												'scope.writePhotosAlbum']) {
+											uni.showModal({
+												title: '提示',
+												content: '获取权限成功,再次点击图片即可保存',
+												showCancel: false,
+											})
+										} else {
+											uni.showModal({
+												title: '提示',
+												content: '获取权限失败,将无法保存到相册哦~',
+												showCancel: false,
+											})
+										}
+									},
+									fail(failData) {
+										console.log("failData", failData)
+									},
+									complete(finishData) {
+										console.log("finishData", finishData)
+									}
+								})
+
+							}
+						})
+					}
+					// 失败后的逻辑
+				})
+				// #endif			
+			},
+		}
+	}
+</script>
+
+<style>
+	page {
+		height: 100%;
+	}
+
+	.pages {
+		height: 100%;
+	}
+
+	.versionTip {
+		color: red;
+		font-size: 26rpx;
+		padding-bottom: 20rpx;
+	}
+
+	.imgAudit {
+		display: block;
+		width: 100%;
+	}
+
+	.Experience {
+		position: absolute;
+		bottom: -80rpx;
+		min-width: 180rpx;
+		left: auto;
+		right: 0;
+		margin: 0;
+		line-height: 36px;
+		background-color: #fff;
+		background: #fff;
+		box-shadow: 0 1px 20px 0 rgb(0 0 0 0.5);
+		border-radius: 8rpx;
+		z-index: 4000;
+		font-weight: 400;
+		text-align: center;
+		font-size: 26rpx;
+	}
+
+	.versionOnlineTitle-btn {
+		background-color: #42b983;
+		color: #ffffff;
+		font-weight: normal;
+		line-height: 60rpx;
+		/* padding: 0 32rpx; */
+		min-width: 180rpx;
+		font-size: 26rpx;
+		letter-spacing: 0;
+		border-radius: 6rpx;
+		box-sizing: border-box;
+		border: none;
+		cursor: pointer;
+		text-align: center;
+		margin-right: 20rpx;
+	}
+
+	.versionOnlineTitle-down {
+		line-height: 58rpx;
+		background-color: #42b983;
+		color: #ffffff;
+		padding: 0 15rpx;
+		border-radius: 6rpx;
+
+	}
+
+	.versionOnlineTitle-down .iconiconfontjiantou {
+		font-size: 26rpx;
+	}
+
+	.version {
+		padding: 0 30rpx;
+	}
+
+	.versionOnline {
+		padding-bottom: 50rpx;
+	}
+
+	.versionOnlineTitle {
+		font-size: 30rpx;
+		font-weight: 600;
+		padding-bottom: 20rpx;
+	}
+
+	.versionOnlineTitleBg {
+		background-color: #42b983;
+		color: #FFFFFF;
+		padding: 20rpx;
+		border-radius: 10rpx;
+	}
+
+	.versionOnlineTitleBgShen {
+		background-color: #4395ff;
+		color: #FFFFFF;
+		padding: 20rpx;
+		border-radius: 10rpx;
+	}
+
+	.versionOnlineTitleNum {
+		padding-bottom: 10rpx;
+		font-weight: 600;
+	}
+
+	.versionOnlineTitleTime {
+		padding-bottom: 10rpx;
+	}
+
+	.versionCode {
+		width: 50rpx;
+		height: 50rpx;
+	}
+
+	.popup-content-desc {
+		background: #fff;
+		text-align: center;
+		width: 600rpx;
+		height: 500rpx;
+		word-break: break-all;
+		padding: 25rpx;
+	}
+
+	.popup-content image {
+		width: 350rpx;
+		height: 350rpx;
+		background: #fff;
+	}
+
+	.save-btn {
+		width: 330rpx;
+		height: 90rpx;
+		background: linear-gradient(315deg, #42b983 2%, #42b983 99%);
+		opacity: 1;
+		border-radius: 6rpx;
+		margin: 0 auto;
+		color: #FFFFFF;
+		font-size: 30rpx;
+		font-family: Source Han Sans CN;
+		font-weight: 500;
+		opacity: 1;
+		margin-top: 30rpx;
+	}
+
+	.amount-input {
+		padding: 20rpx;
+		border: 1rpx solid #F1F1F1;
+	}
+
+	.amount-input textarea {
+		width: 100%;
+	}
+
+	.model {
+		background: #FFFFFF;
+		border-radius: 10rpx;
+		width: 600rpx;
+		overflow: hidden;
+	}
+
+	.model-refund-title {
+		text-align: center;
+		padding: 20rpx 0;
+	}
+
+	.model-refund-btn {
+		border-top-color: #f5f5f5;
+		border-top-style: solid;
+		border-top-width: 1px;
+
+	}
+
+	.model-refund-btn .cancel {
+		height: 90rpx;
+	}
+
+	.model-refund-btn .submit {
+		height: 90rpx;
+		border-left: 1rpx solid #f1f1f1;
+		border-radius: 0;
+	}
+
+	button {
+		background-color: #fff;
+		padding: 0;
+		margin: 0;
+		line-height: 1rpx;
+		min-height: 0;
+		font-size: 28rpx;
+		background: #fff;
+		border-radius: none;
+	}
+
+	button::after {
+		border: none;
+	}
+</style>

+ 258 - 0
appletXcx/Wechat/addVersion.vue

@@ -0,0 +1,258 @@
+<template>
+	<view class="page">
+		<view class="step">
+			<uni-steps active-color="#07c160" :options="options" :active="4"></uni-steps>
+		</view>
+		<view style="height: 130rpx;"></view>
+
+		<view class="home">
+			<form @submit="addVersion">
+				<view class="homeForm ft28">
+					<picker mode="selector" :range="tableTypeList" range-key="title" @change="onTableTypeChange">
+						<view class="item flex-y-center box-pack-between">
+							<text>门店id(仅限审核使用)</text>
+
+							<view>
+								<text>{{tableTypeActive}}</text>
+								<text class="iconfont icongengduo" style="font-size: 26rpx;"></text>
+							</view>
+
+						</view>
+					</picker>
+					<picker mode="selector" :range="tableList" range-key="id" @change="onTableChange">
+						<view class="item flex-y-center box-pack-between">
+							<text>位置id(仅限审核使用): </text>
+							<view>
+								<text>{{table_id}}</text>
+								<text class="iconfont icongengduo" style="font-size: 26rpx;"></text>
+							</view>
+							<input type="text" :value="table_id" name="table_id" placeholder="请输入餐桌id"
+								class="hide-input" />
+						</view>
+					</picker>
+					<view class="item flex-y-center box-pack-between">
+						<text>版本号:</text>
+						<view class="border">
+							<input type="text" :value="obj.user_version" name="user_version" placeholder="请输入版本号" />
+						</view>
+					</view>
+
+					<view class="item box-pack-between" style="height: auto;padding: 20rpx 0;">
+						<text class="flex-center" style="min-width:150rpx;">项目备注:</text>
+						<view class="border itemTextarea flex-grow-1">
+							<textarea type="text" auto-height="true" :value="obj.user_desc" name="user_desc"
+								placeholder="请输入项目备注" />
+						</view>
+					</view>
+
+					<!-- 				
+					<view class="tip">
+						Tip:进入门店列表(对应审核门店id)>进入餐桌管理>即可找到餐桌ID。提交的版本号需大于当前版本号。
+					</view> -->
+
+					<button hover-class="none" form-type="submit" class="flex-grow-1 flex-center submit ft28">
+						提交版本
+					</button>
+
+				</view>
+			</form>
+		</view>
+
+	</view>
+</template>
+
+<script>
+	import optionsData from './data.js'
+	export default {
+		data() {
+			return {
+				tableTypeList: [],
+				tableTypeActive: "请选择",
+				table_id: "",
+				store_id: '',
+				obj: {},
+				tableList: [],
+				options:optionsData.options
+			}
+		},
+
+		onLoad() {
+			this.MiniVersion();
+		},
+
+		methods: {
+			addVersion(e) {
+				let {
+					table_id,
+					user_version,
+					user_desc
+				} = e.detail.value;
+				this.request({
+					url: 'setting/uploadCode',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+						store_id: this.store_id,
+						table_id,
+						user_version,
+						user_desc,
+					}
+				}).then(res => {
+					if (res.code == '200') {
+						console.log(res, "showModal")
+						uni.showModal({
+							title: '提示',
+							content: res.message,
+							showCancel: true,
+							cancelText: '关闭',
+							confirmText: '提交审核',
+							success: r => {
+								if (r.confirm) {
+									uni.redirectTo({
+										url: "./Versioning"
+									})
+								} else {
+									uni.navigateBack({
+										delta: 1
+									})
+								}
+							},
+							fail: () => {},
+							complete: () => {}
+						});
+					}
+				})
+			},
+
+
+			onTableTypeChange(e) {
+				let store_id = this.tableTypeList[e.detail.value].id
+				if (store_id != this.store_id) {
+					this.tableTypeActive = this.tableTypeList[e.detail.value].title;
+					this.store_id = store_id
+					this.table_id = ""
+					this.getTableList(this.store_id)
+				}
+
+			},
+			onTableChange(e) {
+				let table_id = this.tableList[e.detail.value].id
+				this.table_id = table_id
+			},
+
+			// 版本列表
+			MiniVersion(e) {
+				this.request({
+					url: 'setting/wechat_infos',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+					}
+				}).then(res => {
+					if (res.code == 200) {
+
+
+						this.obj = res.data
+
+						this.shop_store_index();
+					}
+				})
+			},
+
+			shop_store_index() {
+				this.request({
+					url: 'Smdcshop/shop_store_index',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+					}
+				}).then(res => {
+					if (res.code == 200) {
+						this.tableTypeList = res.data;
+						if (this.obj.store_id) {
+							let info = res.data.find((item) => item.id == this.obj.store_id)
+							this.tableTypeActive = info.title;
+							this.store_id = info.id;
+						} else {
+							this.tableTypeActive = res.data[0].title;
+							this.store_id = res.data[0].id;
+						}
+						if(this.obj.table_id){
+							this.table_id = this.obj.table_id
+						}
+						this.getTableList(this.store_id)
+					}
+				})
+			},
+			getTableList(store_id) {
+				this.request({
+					url: 'setting/tablelist',
+					data: {
+						store_id
+					}
+				}).then(res => {
+					if (res.code == 200) {
+						this.tableList = res.data;
+					}
+				})
+			},
+
+
+		}
+	}
+</script>
+
+<style>
+	@import url("../css/style.css");
+
+	.tip {
+		color: red;
+		font-size: 24rpx;
+	}
+
+	.itemTextarea {
+		/* border: 1rpx solid #F1F1F1; */
+	}
+
+	.itemTextarea textarea {
+		width: 100%;
+	}
+
+	.homeForm {
+		padding: 20rpx;
+		padding-bottom: 40rpx;
+	}
+
+	.border {
+		padding: 10rpx;
+		border-bottom: 1rpx solid #F1F1F1;
+		text-align: right;
+	}
+
+	.submit {
+		background-color: #07c160;
+		color: #FFFFFF;
+		width: 630rpx;
+		margin: 0 auto;
+		height: 98rpx;
+		margin-top: 30rpx;
+	}
+
+	.Transfer {
+		position: absolute;
+		bottom: 100rpx;
+		width: 100%;
+		text-align: center;
+		font-size: 28rpx;
+		color: #007AFF;
+	}
+
+	.Transfer navigator {
+		display: inline-block;
+	}
+
+	.hide-input {
+		position: fixed;
+		left: 1000px;
+		top: -1000px;
+		width: 0;
+		height: 0;
+	}
+</style>

+ 11 - 0
appletXcx/Wechat/data.js

@@ -0,0 +1,11 @@
+
+export default {
+	options:[
+		{title: '创建小程序',url:'./getXcx'},
+		{title: '扫码授权',url:'./qrCode'},
+		{title: '小程序配置',url:'./deploy'}, 
+		{title: '接口设置',url:'./interface'}, 
+		{title: '提交审核',url:'./addVersion'},
+		{title: '版本管理',url:'./Versioning'},
+		]
+}

+ 995 - 0
appletXcx/Wechat/deploy.vue

@@ -0,0 +1,995 @@
+<template>
+    <view class="">
+        <view class="step">
+            <uni-steps active-color="#07c160" :options="options" :active="2"></uni-steps>
+        </view>
+        <view style="height: 130rpx;"></view>
+
+        <view class="home">
+            <form @submit="save">
+                <view class="box-pack-between item flex-y-center border-b">
+                    <text>基本信息</text>
+                </view>
+
+                <view class="bgf" style="padding: 0 30rpx;">
+
+                    <view class="box-pack-between list flex-y-center border-b ft28">
+                        <text>小程序APPID</text>
+                        <view @click="copy(info.appid)">{{info.appid||''}} <text class="ft26"
+                                style="color:#3387FF;margin-left: 20rpx;">复制</text></view>
+                    </view>
+
+                    <view class="bgf">
+                        <view class="box-pack-between list flex-y-center br">
+                            <text class="ft28">小程序名称</text>
+                            <text class="setup_a" v-if="!info.nickname" @click="setup(1)">设置</text>
+                            <view class="flex-grow-1 tr ft28" v-else>
+                                {{info.nickname||''}}
+                            </view>
+                        </view>
+                    </view>
+
+                    <view class="box-pack-between border-b header-version flex-y-center">
+                        <view class="header-img ft28">
+                            小程序头像
+                            <view class="ft22">
+                                (最大宽度 500px,最大高度 500px,不超过2M,如果头像过大,加载会慢点)
+
+                                <view style="margin-top: 20rpx;color: red;">
+                                    一年内可申请修改{{info.head_image_info.modify_quota}}次
+                                </view>
+                                <view style="color: red;">
+                                    今年还可修改{{info.head_image_info.modify_quota-info.head_image_info.modify_used_count}}次
+                                </view>
+                            </view>
+                        </view>
+                        <text class="setup_a" v-if="!xcx_logo" @click="setup(3)">设置</text>
+                        <view class="home-img" v-else @click="setup(3)">
+                            <image :src="xcx_logo" class="home-img-icon"></image>
+                        </view>
+                    </view>
+
+                    <view class="bgf">
+                        <view class="box-pack-between list flex-y-center br" style="height: auto;padding: 20rpx 0;">
+                            <view class="ft28" style="min-width: 200rpx;">
+                                小程序简介
+                                <view class="modify_quota">
+                                    一年内可申请修改{{info.signature_info.modify_quota}}次
+                                </view>
+                                <view class="modify_quota">
+                                    今年还可修改{{info.signature_info.modify_quota-info.signature_info.modify_used_count}}次
+                                </view>
+                            </view>
+                            <view>
+                                <view class="setup_a" style="text-align: right;"
+                                    v-if="(info.signature_info.modify_quota-info.signature_info.modify_used_count)>0"
+                                    @click="setup(2)">设置</view>
+                                <view class="flex-grow-1 break tr ft28" @click="setup(2)">
+                                    {{info.signature_info.signature}}
+                                </view>
+                            </view>
+                        </view>
+                    </view>
+                    <!-- <view class="flex-center pof">
+						<button formType="submit" class="flex-center login-btn">提交审核</button>
+					</view> -->
+                </view>
+            </form>
+        </view>
+
+        <view class="home">
+
+            <view class="box-pack-between flex-y-center border-b itemTitle">
+                <view class="">
+                    <text>服务类目</text>
+                    <view class="ft24">
+                        (已添加{{category.length}}个,最多5个,一个月只能修改5次)
+                    </view>
+                </view>
+                <view class="deploy-add flex-center ft26" @click="open" hover="true" hover-class="detail-hover">
+                    添加类目
+                </view>
+            </view>
+
+            <view class="bgf" style="padding: 0 30rpx;">
+                <template v-for="(item,index) of category">
+                    <view class="list flex flex-y-center" style="height: auto;" :key='index'>
+                        <text class="ft28" style="margin-right: 10rpx;">{{item.first_name}}>{{item.second_name}}</text>
+                        <text class="setup_a" style="min-width: 120rpx;">
+                            {{item.audit_status==1? '审核中':item.audit_status==2? '审核不通过' :item.audit_status==3? '审核通过':''}}
+                        </text>
+                        <view class="iconfont iconshanjian item-del" style="margin-left: 10rpx;"
+                            @click.stop="deleteItem(index)" v-if="item.audit_status != 3"></view>
+
+                    </view>
+                    <view class="reason" v-if="item.audit_status == 2">{{item.audit_reason}}</view>
+                    <view class="br"></view>
+                </template>
+
+
+            </view>
+        </view>
+
+        <view class="home">
+
+            <view class="box-pack-between item flex-y-center">
+                <text>体验版成员</text>
+                <button class="deploy-add flex-center" hover="true" hover-class="detail-hover"
+                    @click="setup(4)">新增</button>
+            </view>
+
+            <view class="deploy-list" v-if="deplist.length>0">
+                <view class="item-bg">
+                    <view class="box-pack-between mar64 flex-y-center" v-for="(item,index) of deplist" :key='index'>
+                        <view class="flex-y-center flex-grow-1 pdr-20">
+                            <view class="deploy-list-nick text-1">
+                                {{item.wechatid}}
+                            </view>
+                        </view>
+                        <view class="iconfont iconshanjian item-del" @click="del(index)"></view>
+                    </view>
+                </view>
+            </view>
+
+        </view>
+
+
+        <view class="home">
+
+            <view class="box-pack-between item flex-y-center">
+                <text>服务器域名</text>
+                <button class="deploy-add flex-center" hover="true" hover-class="detail-hover"
+                    @click="setup(5)">设置</button>
+            </view>
+
+            <view class="flex-y-center box-pack-between ft28 border-b pd2-3">
+
+                <view class="word flex-grow-0">
+                    服务器域名
+                </view>
+
+                <view class="qr_link flex-grow-1 tr">
+                    {{info.fwq_url||''}}
+                </view>
+
+            </view>
+
+        </view>
+        <view class="home">
+
+            <view class="box-pack-between item flex-y-center">
+                <text>业务域名</text>
+                <button class="deploy-add flex-center" hover="true" hover-class="detail-hover"
+                    @click="setup(6)">设置</button>
+            </view>
+
+            <view class="flex-y-center box-pack-between ft28 border-b pd2-3">
+
+                <view class="word flex-grow-0">
+                    业务域名
+                </view>
+
+                <view class="qr_link flex-grow-1 tr">
+                    {{info.yw_url||''}}
+                </view>
+
+            </view>
+
+        </view>
+
+        <view class="home">
+
+            <view class="box-pack-between item flex-y-center pd20" style="height: auto;">
+                <view class="">
+                    <text>二维码规则配置 <text class="ft26" style="color: #999999;">(小程序发布上线之后再配置)</text>
+                    </text>
+                </view>
+
+                <view class="flex">
+                    <!--  -->
+                    <block v-if="info.file==1">
+                        <!-- <button style="min-width:170rpx;" class="deploy-add flex-center" hover="true"
+                            hover-class="detail-hover" @click="ConfigRule">配置规则</button> -->
+                        <button style="min-width:170rpx;" class="deploy-add flex-center" hover="true"
+                            hover-class="detail-hover" @click="AppendRule">配置规则</button>
+                    </block>
+                    <button v-else class="deploy-add flex-center" hover="true" style="min-width:170rpx;"
+                        hover-class="detail-hover" @click="qrcodejumpdownload">上传文件</button>
+                </view>
+            </view>
+
+            <view class="flex-y-center box-pack-between ft28 border-b pd2-3" v-for="(item,index) of linkArr"
+                :key='index'>
+                <view class="word">
+                    <view class="qr_link">
+                        地址:{{item.prefix}}
+                    </view>
+                    <view class="qr_link">
+                        路径:{{item.path}}
+                    </view>
+                </view>
+                <view class="iconfont iconshanjian item-del" @click="DelRule(index)"></view>
+            </view>
+        </view>
+
+
+        <uni-popup ref="uniScroll" type="bottom">
+            <uni-scroll :Prov_arr="Prov_arr" @select="select"></uni-scroll>
+        </uni-popup>
+
+        <uni-popup ref="popup" type="center">
+            <view class="model">
+                <view v-if="type==3">
+                    <view class="model-refund-title ft28">
+                        小程序头像
+                    </view>
+                    <view class="box-pack-between flex-y-center" style="padding: 0 40rpx;">
+                        <view class="home-img" @click="uploadFile" data-type='1'>
+                            <image class="home-img-icon" :src="URL+xcx_logo"></image>
+                        </view>
+                        <view class="home-upload flex-center" @click="uploadFile" data-type='1'>上传文件</view>
+                    </view>
+                    <view class="tips">
+                        新头像不允许涉及政治敏感与色情;
+                        图片格式必须为:png,bmp,jpeg,jpg,gif;不可大于2M;建议使用png格式图片,以保持最佳效果;建议图片尺寸为144px*144px
+                    </view>
+                    <view class="flex-y-center model-refund-btn">
+                        <view class="flex-grow-1 flex-center cancel ft26" @click="cancel">
+                            取消
+                        </view>
+                        <button hover-class="none" @click="saveImg" class="flex-grow-1 flex-center submit ft28">
+                            确定
+                        </button>
+                    </view>
+                </view>
+
+                <block v-else>
+                    <form @submit="saveName">
+                        <view class="model-refund-title ft28">
+                            {{type==1?'小程序名称':type==2?'小程序简介':type==4?'添加体验者':type==5?'服务器域名':type == 6?'业务域名':''}}
+                        </view>
+                        <view style="padding: 20rpx;">
+                            <view class="amount-input">
+                                <textarea v-if="type==1" type="text" maxlength="15" auto-height="true" name="nickname"
+                                    placeholder="请输入小程序名称" />
+
+                                <textarea v-if="type==2" type="text"
+                                    :value="info.signature_info.signature || signature_info" auto-height="true"
+                                    name="signature" placeholder="请输入小程序简介" />
+
+                                <textarea v-if="type==4" type="text" auto-height="true" name="wechatid"
+                                    placeholder="请添加体验者" />
+
+                                <textarea v-if="type==5" type="text" :value="info.fwq_url || URL_DEF || ''"
+                                    auto-height="true" name="fwq_url" placeholder="请添加服务器域名" />
+                                <textarea v-if="type==6" type="text" :value="info.yewu_url || URL || ''"
+                                    auto-height="true" name="yw_url" placeholder="请添加业务域名" />
+
+                            </view>
+                        </view>
+
+                        <view class="tips" v-if="type!=4">
+                            {{type==1?'Tip:小程序名称可以由中文、数字、英文、空格及部分特殊符号组成。长度在4-30个字符之间,一个中文字等于2个字符,名称设置完成不可更改,起名请谨慎。':
+							 type==2?'●功能介绍长度不超过120个字符,一个中文字等于2个字符,请确认介绍内容不含国家相关法律法规禁止内容':
+							 type==5?'设置小程序服务器地址,无需加https前缀,但域名必须可以通过https访问,多个使用;隔开':''}}
+                        </view>
+
+                        <view class="flex-y-center model-refund-btn">
+                            <view class="flex-grow-1 flex-center cancel ft26" @click="cancel">
+                                取消
+                            </view>
+                            <button hover-class="none" form-type="submit" class="flex-grow-1 flex-center submit ft28">
+                                确定
+                            </button>
+                        </view>
+
+                    </form>
+
+                </block>
+            </view>
+        </uni-popup>
+    </view>
+</template>
+
+<script>
+    import optionsData from './data.js'
+    import uniScroll from '../components/uni-scroll/uni-scroll-cate.vue'
+    export default {
+        components: {
+            uniScroll,
+        },
+        data() {
+            return {
+                URL: getApp().globalData.URL,
+                URL_DEF: "",
+                info: null,
+                xcx_logo: '',
+                type: 1,
+                category: [],
+                Prov_arr: [],
+                deplist: [],
+                linkArr: [],
+                signature_info: "智慧经营系统,会员积分管理,DIY模块化,积分商城,无痕赋能。",
+                options: optionsData.options
+            }
+        },
+
+        onLoad() {
+            this.wechat_info();
+            this.wechat_category();
+            this.wechat_firstcategory();
+            this.listMember();
+            this.ewmguizhe();
+            this.URL_DEF = this.URL ? this.URL.split('//')[1] : ''
+        },
+
+        methods: {
+            // 删除类目
+            deleteItem(index) {
+
+                console.log("lll")
+                let {
+                    first,
+                    second,
+                    second_name,
+                    audit_status
+                } = this.category[index];
+                if (audit_status == 3) {
+                    return false
+                }
+                uni.showModal({
+                    title: '提示',
+                    content: `确定要删除${second_name}类目吗?`,
+                    showCancel: true,
+                    cancelText: '取消',
+                    confirmText: '确定',
+                    success: res => {
+                        if (res.confirm) {
+                            this.request({
+                                url: 'setting/delcategory',
+                                data: {
+                                    admin_id: uni.getStorageSync("admin_id"),
+                                    first,
+                                    second,
+                                },
+                            }).then(res => {
+                                console.log(res, "res")
+                                if (res.code === "200") {
+                                    uni.showToast({
+                                        title: res.message,
+                                        icon: 'none'
+                                    })
+                                    setTimeout(() => {
+                                        this.wechat_category();
+                                    }, 2000)
+                                }
+                            });
+                        }
+                    },
+                    fail: () => {},
+                    complete: () => {}
+                });
+            },
+
+            // 获取分类
+            select(e) {
+                console.log(e)
+                // this.Mcc = e;
+                let {
+                    code1,
+                    code2,
+                    special_license_pic,
+                    zzzs_name,
+                } = e;
+                this.request({
+                    url: 'setting/addcategory',
+                    data: {
+                        admin_id: uni.getStorageSync("admin_id"),
+                        code1,
+                        code2,
+                        special_license_pic,
+                        zzzs_name,
+                    },
+                }).then(res => {
+                    console.log(res, "res")
+                    if (res.code === "200") {
+                        uni.showToast({
+                            title: res.message,
+                            icon: 'none'
+                        })
+                        setTimeout(() => {
+                            this.wechat_category();
+                        }, 2000)
+
+                    }
+                });
+            },
+
+            open(e) {
+                this.$refs.uniScroll.open();
+            },
+
+            cancel() {
+                this.$refs.popup.close();
+            },
+
+            setup(type) {
+                this.type = type;
+                if (type == 2 && this.info.signature_info.modify_quota - this.info.signature_info.modify_used_count <=
+                    0) {
+                    return
+                }
+                if (type == 3 && this.info.head_image_info.modify_quota - this.info.head_image_info.modify_used_count <=
+                    0) {
+                    return
+                }
+                this.$refs.popup.open();
+            },
+
+            // 获取一级类目
+            wechat_firstcategory() {
+                this.request({
+                    url: 'setting/wechat_firstcategory',
+                    data: {
+                        admin_id: uni.getStorageSync("admin_id"),
+                    },
+                }).then(res => {
+                    console.log(res, "res")
+                    if (res.code === "200") {
+                        this.Prov_arr = res.data;
+                    }
+                });
+            },
+
+            // 获取已设置类目
+            wechat_category() {
+                this.request({
+                    url: 'setting/wechat_category',
+                    data: {
+                        admin_id: uni.getStorageSync("admin_id"),
+                    },
+                }).then(res => {
+                    console.log(res, "res")
+                    if (res.code === "200") {
+                        this.category = res.data;
+                    }
+                });
+            },
+            // 获取基础信息
+            wechat_info() {
+                this.request({
+                    url: 'setting/wechat_info',
+                    data: {
+                        admin_id: uni.getStorageSync("admin_id"),
+                    },
+                }).then(res => {
+                    console.log(res, "wechat_info")
+                    if (res.code === "200") {
+                        this.info = res.data;
+                        this.xcx_logo = res.data.head_image_info.head_image_url;
+                    }
+                });
+            },
+            // 设置头像
+            saveImg(e) {
+                this.request({
+                    url: 'setting/modifyheadimage',
+                    data: {
+                        admin_id: uni.getStorageSync("admin_id"),
+                        license_pic: this.xcx_logo,
+                    },
+                }).then(res => {
+                    console.log(res, "res")
+                    if (res.code === "200") {
+                        this.$refs.popup.close();
+                        uni.showToast({
+                            title: res.message,
+                            icon: 'none'
+                        })
+                        setTimeout(() => {
+                            this.wechat_info()
+                        }, 2000)
+                    }
+                });
+            },
+            // 设置名称/简介/体验者
+            saveName(e) {
+                console.log(e)
+                let url, data = {
+                    admin_id: uni.getStorageSync("admin_id"),
+                };
+                if (this.type == 1) {
+                    url = 'setting/setnickname';
+                    data.nickname = e.detail.value.nickname;
+                }
+                if (this.type == 2) {
+                    url = 'setting/modifysignature';
+                    data.signature = e.detail.value.signature;
+                }
+                if (this.type == 4) {
+                    url = 'setting/bindMember';
+                    data.wechatid = e.detail.value.wechatid;
+                }
+                if (this.type == 5) {
+                    url = 'setting/modify_domain';
+                    data.fwq_url = e.detail.value.fwq_url;
+                }
+                if (this.type == 6) {
+                    url = 'setting/setBusinessDomain';
+                    data.ywurl = e.detail.value.yw_url;
+                }
+                this.request({
+                    url,
+                    data,
+                }).then(res => {
+                    console.log(res, "res")
+                    if (res.code === "200") {
+                        uni.showToast({
+                            title: res.message,
+                            icon: 'none'
+                        })
+                        this.$refs.popup.close();
+                        setTimeout(() => {
+                            this.type == 4 ? this.listMember() : this.wechat_info();
+                        }, 2000)
+
+                    }
+                });
+            },
+
+            uploadFile(e) {
+                var type = e.currentTarget.dataset.type,
+                    url = type == 3 ? "setting/logo_upload" : "setting/upload";
+                uni.chooseImage({
+                    success: (res) => {
+                        res.tempFilePaths.forEach((v, i) => {
+                            console.log(v)
+                            this.Upload({
+                                url: url,
+                                data: {
+                                    url: v,
+                                    admin_id: uni.getStorageSync("admin_id"),
+                                }
+                            }).then(res => {
+                                console.log(res, "res")
+                                type == 1 ? (this.xcx_logo = res.src) :
+                                    type == 2 ? (this.special_license_pic = res.src) :
+                                    type == 3 ? (this.app_logo = res.src) : '';
+                            }).catch({});
+                        })
+                    }
+                });
+            },
+
+            // 删除体验者
+            del(index) {
+                uni.showModal({
+                    title: '提示',
+                    content: '确定要删除用户吗?',
+                    showCancel: true,
+                    cancelText: '取消',
+                    confirmText: '确定',
+                    success: res => {
+                        if (res.confirm) {
+                            this.request({
+                                url: 'setting/unBindMember',
+                                data: {
+                                    admin_id: uni.getStorageSync("admin_id"),
+                                    wechatid: this.deplist[index].wechatid,
+                                }
+                            }).then(res => {
+
+                                uni.showToast({
+                                    title: res.message,
+                                    icon: 'none'
+                                })
+                                this.deplist.splice(index, 1);
+                            })
+                        }
+                    },
+                    fail: () => {},
+                    complete: () => {}
+                });
+            },
+            qrcodejumpdownload() {
+                this.request({
+                    url: 'setting/qrcodejumpdownload',
+                    data: {
+                        admin_id: uni.getStorageSync("admin_id"),
+                    }
+                }).then(res => {
+                    if (res.code == 200) {
+                        uni.showToast({
+                            title: res.message,
+                            icon: 'none'
+                        })
+                        setTimeout(() => {
+                            this.wechat_info()
+                        }, 2000)
+                    }
+                })
+            },
+
+            // 新增规则
+            ConfigRule(e) {
+                this.request({
+                    url: 'setting/oldewmqrcode',
+                    data: {
+                        admin_id: uni.getStorageSync("admin_id"),
+                    }
+                }).then(res => {
+                    if (res.code == 200) {
+                        uni.showToast({
+                            title: res.message,
+                            icon: 'none'
+                        })
+                        setTimeout(() => {
+                            this.ewmguizhe();
+                        }, 2000)
+                    }
+                })
+            },
+            // 追加规则
+            AppendRule(e) {
+                this.request({
+                    url: 'setting/newewmqrcode',
+                    data: {
+                        admin_id: uni.getStorageSync("admin_id"),
+                    }
+                }).then(res => {
+                    if (res.code == 200) {
+                        uni.showToast({
+                            title: res.message,
+                            icon: 'none'
+                        })
+                        setTimeout(() => {
+                            this.ewmguizhe();
+                        }, 2000)
+                    }
+                })
+            },
+            // 删除规则
+            DelRule(index) {
+                uni.showModal({
+                    title: '提示',
+                    content: '确定要删除规则吗?',
+                    showCancel: true,
+                    cancelText: '取消',
+                    confirmText: '确定',
+                    success: res => {
+                        if (res.confirm) {
+                            this.request({
+                                url: 'setting/delqrcodejumpget',
+                                data: {
+                                    admin_id: uni.getStorageSync("admin_id"),
+                                    prefix: this.linkArr[index].prefix,
+                                }
+                            }).then(res => {
+                                uni.showToast({
+                                    title: res.message,
+                                    icon: 'none'
+                                })
+
+                                this.linkArr.splice(index, 1);
+                            })
+                        }
+                    },
+                    fail: () => {},
+                    complete: () => {}
+                });
+            },
+
+            // 规则列表
+            ewmguizhe(e) {
+                this.request({
+                    url: 'setting/qrcodejumpget',
+                    data: {
+                        admin_id: uni.getStorageSync("admin_id"),
+                    }
+                }).then(res => {
+                    if (res.code == 200) {
+                        this.linkArr = res.data;
+                    }
+                })
+            },
+            // 获取体验者
+            listMember() {
+                this.request({
+                    url: 'setting/listMember',
+                    data: {
+                        admin_id: uni.getStorageSync("admin_id"),
+                    }
+                }).then(res => {
+                    if (res.code == 200) {
+                        this.deplist = res.data;
+                    }
+                })
+            },
+
+            copy(appid) {
+                // #ifdef MP-WEIXIN
+                uni.setClipboardData({
+                    data: appid,
+                    success: function() {
+                        console.log('success');
+                    }
+                });
+                // #endif
+
+                // #ifdef H5
+                let content = appid;
+                if (!document.queryCommandSupported('copy')) {
+                    // 不支持
+                    return false
+                }
+                let textarea = document.createElement("input")
+                textarea.value = content
+                textarea.readOnly = "readOnly"
+                document.body.appendChild(textarea)
+                textarea.select() // 选择对象
+                textarea.setSelectionRange(0, content.length) //核心
+                let result = document.execCommand("copy") // 执行浏览器复制命令
+                textarea.remove();
+                uni.showToast({
+                    title: "复制成功",
+                    icon: 'none'
+                })
+                return result
+                // #endif
+            },
+        }
+    }
+</script>
+
+<style>
+    @import url("../css/style.css");
+
+    page .detail-hover {
+        opacity: 0.6;
+        transform: scale(0.8, 0.8);
+    }
+
+    .itemTitle {
+        padding: 30rpx 20rpx;
+    }
+
+    .setup_a {
+        flex: none;
+        color: #576B95;
+        font-size: 26rpx;
+        margin-left: auto;
+    }
+
+    .reason {
+        font-size: 24rpx;
+        padding: 10rpx;
+        background-color: #f0f0f0;
+        color: #f00;
+        line-height: 1.5;
+        border-radius: 6rpx;
+        margin-bottom: 20rpx;
+    }
+
+    .pd20 {
+        padding: 20rpx;
+    }
+
+    .pd2-3 {
+        padding: 20rpx 30rpx;
+    }
+
+    .step {
+        padding: 20rpx 0;
+        position: fixed;
+        width: 100%;
+        background: #FFFFFF;
+        z-index: 999;
+    }
+
+    .deploy-add {
+        padding: 0 15rpx;
+        height: 60rpx;
+        text-align: center;
+        border-radius: 10rpx;
+        background-color: #07C160;
+        color: #FFFFFF;
+        margin-left: 20rpx;
+    }
+
+    .deploy-list {
+        padding: 24rpx;
+
+    }
+
+    .item-bg {
+        background: #f6f8fe;
+        border-radius: 12rpx;
+        margin: 0 auto;
+        font-size: 28rpx;
+        font-family: PingFang SC, PingFang SC-Regular;
+        font-weight: 400;
+        color: #333333;
+        padding: 36rpx 32rpx;
+    }
+
+    .item-del {
+        flex: none;
+        color: red;
+    }
+
+    .item-bg-32 {
+        margin-right: 32rpx;
+    }
+
+    .item-bg .mar64:last-child {
+        margin-bottom: 0rpx;
+    }
+
+    .deploy-list-nick {
+        width: 300rpx;
+        margin-right: 20rpx;
+    }
+
+    .deploy-list-logon {
+        width: 180rpx;
+        margin-right: 30rpx;
+    }
+
+    .mar64 {
+        margin-bottom: 64rpx;
+    }
+
+    .amount-input {
+        padding: 20rpx;
+        border: 1rpx solid #F1F1F1;
+    }
+
+    .model {
+        background: #FFFFFF;
+        border-radius: 10rpx;
+        width: 600rpx;
+        overflow: hidden;
+    }
+
+    .model-refund-title {
+        text-align: center;
+        padding: 20rpx 0;
+    }
+
+    .model-refund-btn {
+        border-top-color: #f5f5f5;
+        border-top-style: solid;
+        border-top-width: 1px;
+
+    }
+
+    .model-refund-btn .cancel {
+        height: 90rpx;
+    }
+
+    .model-refund-btn .submit {
+
+        height: 90rpx;
+        border-left: 1rpx solid #f1f1f1;
+        border-radius: 0;
+    }
+
+    .list {
+        height: auto;
+        background: #fff;
+        position: relative;
+        padding: 30rpx 0;
+    }
+
+    .header-version {
+        padding: 20rpx 0;
+    }
+
+    .home-img {
+        font-size: 26rpx;
+        text-align: center;
+        display: inline-block;
+    }
+
+    .home-upload {
+        border: 1rpx solid #e3e4e5;
+        height: 80rpx;
+        border-radius: 6rpx;
+        padding: 0 32rpx;
+        min-width: 180rpx;
+        font-size: 28rpx;
+        letter-spacing: 0;
+        background: #f6f7f8;
+    }
+
+    .home-img-icon {
+        border: 1rpx solid #ccc;
+        width: 200rpx;
+        height: 200rpx;
+    }
+
+    .header-img {
+        max-width: 300rpx;
+    }
+
+    button {
+        background-color: #fff;
+        padding: 0;
+        margin: 0;
+        line-height: 1rpx;
+        min-height: 0;
+        font-size: 28rpx;
+        background: #fff;
+        border-radius: none;
+    }
+
+    button::after {
+        border: none;
+    }
+
+    .qr_link {
+        margin-bottom: 10rpx;
+    }
+
+    .tips {
+        font-size: 24rpx;
+        color: red;
+        padding: 10rpx 20rpx;
+    }
+
+    .model {
+        background: #FFFFFF;
+        border-radius: 10rpx;
+        width: 600rpx;
+        overflow: hidden;
+    }
+
+    .amount-input textarea {
+        width: 100%;
+    }
+
+    .model-refund-title {
+        text-align: center;
+        padding: 20rpx 0;
+    }
+
+    .model-refund-btn {
+        border-top-color: #f5f5f5;
+        border-top-style: solid;
+        border-top-width: 1px;
+
+    }
+
+    .model-refund-btn .cancel {
+        height: 90rpx;
+    }
+
+    .model-refund-btn .submit {
+
+        height: 90rpx;
+        border-left: 1rpx solid #f1f1f1;
+        border-radius: 0;
+    }
+
+    button {
+        background-color: #fff;
+        padding: 0;
+        margin: 0;
+        line-height: 1rpx;
+        /* border: 1px solid #cccccc; */
+        min-height: 0;
+        font-size: 28rpx;
+        background: #fff;
+        border-radius: none;
+    }
+
+    button::after {
+        border: none;
+    }
+
+    .modify_quota {
+        font-size: 20rpx;
+        margin-top: 10rpx;
+        color: red;
+    }
+</style>

+ 304 - 0
appletXcx/Wechat/getXcx.vue

@@ -0,0 +1,304 @@
+<template>
+	<view class="container">
+		
+		<view class="step">
+			<uni-steps active-color="#07c160" 
+			:options="options" :active="0"></uni-steps>
+		</view>
+		<view  style="height: 130rpx;"></view>
+		
+		<form @submit="onSubmit">
+			
+			<view class="content">
+				
+				<view class="content-tips">
+					请商家法人先关注“微信公众平台安全助手”
+				</view>
+				
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>企业名称:</text>
+					</view>
+					<view class="desc">
+						<input type="text" :value="info.name" name="name" class="input-box" placeholder="请输入企业名称"
+							placeholder-class="desc-placeholder">
+					</view>
+				</view>
+
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>企业代码:</text>
+					</view>
+					<view class="desc">
+						<input type="text" :value="info.code" name="code" class="input-box" placeholder="请输入企业代码"
+							placeholder-class="desc-placeholder">
+					</view>
+				</view>
+
+
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>企业代码类型:</text>
+					</view>
+					<view class="desc ft30 flex-grow-1 box-pack-between" @click="onPrinterStatusChange">
+						<text></text>
+						<view class="flex-y-center">
+							{{codeStatus}}
+							<text class="iconfont icongengduo"></text>
+						</view>
+					</view>
+				</view>
+
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>法人微信号:</text>
+					</view>
+					<view class="desc">
+						<input type="text" :value="info.legal_persona_wechat" name="legal_persona_wechat"
+							class="input-box" placeholder="请输入法人微信号" placeholder-class="desc-placeholder">
+					</view>
+				</view>
+
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>法人姓名:</text>
+					</view>
+					<view class="desc">
+						<input type="text" :value="info.legal_persona_name" name="legal_persona_name" class="input-box"
+							placeholder="请输入法人姓名" placeholder-class="desc-placeholder">
+					</view>
+				</view>
+
+
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>第三方联系电话:</text>
+					</view>
+					<view class="desc">
+						<input type="number" :value="info.component_phone" name="component_phone" class="input-box"
+							placeholder="请输入第三方联系电话" placeholder-class="desc-placeholder">
+					</view>
+				</view>
+
+			</view>
+			<button class="sub-btn" hover-class="none" form-type="submit">
+				立即提交
+			</button>
+
+		</form>
+	</view>
+</template>
+
+<script>
+	import optionsData from './data.js'
+	export default {
+		data() {
+			return {
+				info: {},
+
+				ali_arr: [
+					'关闭', '开启'
+				],
+				is_coupon: 0,
+				setColor: "",
+				code_type: 1,
+				codeStatus: '统一社会代码',
+				options:optionsData.options
+			}
+		},
+
+		onLoad() {
+			this.getdata();
+		},
+
+		methods: {
+			onPrinterStatusChange() {
+				let statusArr = ['统一社会代码', '组织机构代码', '营业执照注册号']
+				uni.showActionSheet({
+					itemList: statusArr,
+					success: (r) => {
+						console.log(r.tapIndex)
+						this.code_type = Number(r.tapIndex) + 1
+						this.codeStatus = statusArr[r.tapIndex]
+					}
+				})
+			},
+
+			bindColor(e) {
+				this.setColor = e.detail.value;
+			},
+
+			choicemenber(index) {
+				this.is_coupon = index;
+			},
+
+			getdata(e) {
+				this.request({
+					url: "Smdcshop/xcx_list",
+					data: {
+						admin_id: uni.getStorageSync("admin_id")
+					},
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code === '200') {
+						this.info = res.data;
+						this.code_type = res.data.code_type;
+						this.codeStatus = res.data.code_type == 1 ? '统一社会代码' : res.data.code_type == 2 ? '组织机构代码' :
+							'营业执照注册号';
+					}
+				});
+			},
+
+			onSubmit(e) {
+				let data = e.detail.value;
+				data.admin_id = uni.getStorageSync("admin_id");
+				data.code_type = this.code_type;
+				this.request({
+					url: "Smdcshop/fastregisterbetaweapp",
+					data: data,
+				}).then(res => {
+					if (res.code == 200) {
+						uni.showToast({
+							title: res.message,
+							icon: 'none'
+						})
+						setTimeout(() => {
+							uni.navigateBack()
+						}, 2000)
+					}
+				}).catch((res) => {
+					uni.showToast({
+						title: res.message,
+						icon: 'none'
+					})
+				})
+			},
+
+		}
+	}
+</script>
+
+<style>
+	page {
+		background-color: #F4F5F7;
+	}
+	.content-tips{
+		text-align: right;
+		font-size: 26rpx;
+		color: red;
+		padding: 20rpx;
+	}
+	.item {
+		background-color: #FFF;
+		padding: 0 25rpx;
+	}
+
+	.title-block {
+		margin-right: 20rpx;
+	}
+
+	.desc {
+		text-align: right;
+		flex: 1;
+		padding: 25rpx 0;
+		border-bottom: 1rpx solid #F1F1F1;
+	}
+
+	.rund {
+		width: 40rpx;
+		height: 40rpx;
+	}
+
+	.red {
+		color: red;
+		padding: 10rpx 25rpx;
+		font-size: 26rpx;
+	}
+
+	.sub-btn {
+		width: 690rpx;
+		height: 100rpx;
+		background: linear-gradient(315deg, #07c160 2%, #07c160 99%);
+		border-radius: 8rpx;
+		box-shadow: 0px 0px 8rpx 0px rgba(51, 135, 255, 0.20);
+		text-align: center;
+		line-height: 100rpx;
+		color: #fff;
+		font-size: 36rpx;
+		font-weight: bold;
+		margin: 0 auto;
+		margin-top: 30px;
+	}
+
+	.checklist-box {
+		display: -webkit-box;
+		display: -webkit-flex;
+		display: flex;
+		-webkit-box-orient: horizontal;
+		-webkit-box-direction: normal;
+		-webkit-flex-direction: row;
+		flex-direction: row;
+		-webkit-box-align: center;
+		-webkit-align-items: center;
+		align-items: center;
+		margin: 5px 0;
+		margin-right: 22px;
+	}
+
+	.radio__inner {
+		-webkit-flex-shrink: 0;
+		flex-shrink: 0;
+
+		display: -webkit-box;
+		display: -webkit-flex;
+		display: flex;
+
+		-webkit-box-pack: center;
+		-webkit-justify-content: center;
+		justify-content: center;
+		-webkit-box-align: center;
+		-webkit-align-items: center;
+		align-items: center;
+		position: relative;
+		border: 1px solid #DCDFE6;
+		border-radius: 2px;
+		box-sizing: border-box;
+		width: 16px;
+		height: 16px;
+		border-radius: 16px;
+		background-color: #fff;
+		z-index: 1;
+		-webkit-transition: border-color .3s;
+		transition: border-color .3s;
+	}
+
+	.radio__inner-icon {
+		width: 8px;
+		height: 8px;
+		border-radius: 10px;
+		opacity: 0;
+		-webkit-transition: -webkit-transform .3s;
+		transition: -webkit-transform .3s;
+		transition: transform .3s;
+		transition: transform .3s, -webkit-transform .3s;
+	}
+
+	.is-default-checked {
+		opacity: 1;
+		background-color: #07c160;
+		-webkit-transform: rotate(45deg) scaleY(1);
+		transform: rotate(45deg) scaleY(1);
+	}
+
+	.act_border {
+		border: 1rpx solid #07c160;
+	}
+
+	.checklist-text {
+		font-size: 28rpx;
+		margin-left: 5px;
+		-webkit-transition: color 0.2s;
+		transition: color 0.2s;
+		color: #000;
+	}
+</style>

+ 186 - 0
appletXcx/Wechat/index.vue

@@ -0,0 +1,186 @@
+<template>
+	<view class="content">
+		<view class="header">
+			<!-- <image src="../../static/images/skm_fn_bg.png" mode="aspectFill" class="bg-img"></image> -->
+			<view class="info-block flex-y-center">
+				<view class="info">
+					<view class="title">微信小程序管理</view>
+					<view class="desc">手机管理方便又快捷</view>
+				</view>
+			</view>
+		</view>
+
+		<view class="content-row">
+			<view class="setup flex-y-center ft32">
+				常用应用
+			</view>
+			<view class="table">
+				<view class="table-tr">
+					
+					<navigator class="table-td" url="./getXcx">
+						<view class="iconfont iconpeizhi"></view>
+						<view class="">创建小程序</view>
+					</navigator>
+
+					<navigator class="table-td" url="./qrCode">
+						<view class="iconfont iconweixin"></view>
+						<view class="">微信授权</view>
+					</navigator>
+
+					<navigator class="table-td" url="./deploy">
+						<view class="iconfont iconshenhe"></view>
+						<view class="">小程序配置</view>
+					</navigator>
+
+					<navigator class="table-td" url="./interface">
+						<view class="iconfont iconshenhe"></view>
+						<view class="">接口设置</view>
+					</navigator>
+
+
+					<navigator class="table-td" url="./addVersion">
+						<view class="iconfont iconbanben"></view>
+						<view class="">提交版本</view>
+					</navigator>
+
+
+					<navigator class="table-td" url="./Versioning">
+						<view class="iconfont iconbanbengengxin"></view>
+						<view class="">版本管理</view>
+					</navigator>
+
+
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+	export default {
+		data() {
+			return {
+				is_admin: 1
+			}
+		},
+
+		onLoad(e) {
+			this.is_admin = e.is_admin || 1;
+		},
+
+		methods: {
+
+
+		}
+	}
+</script>
+
+<style>
+	.setup {
+		width: 100%;
+		height: 90rpx;
+
+		opacity: 1;
+		padding: 0 22rpx;
+	}
+
+	.table,
+	.table div {
+		margin: 0 auto;
+	}
+
+	.table {
+		/* display: table; */
+		width: 100%;
+		border-collapse: collapse;
+		box-sizing: border-box;
+	}
+
+	.table-tr {
+		/* display: table-row; */
+		/* height: 92rpx; */
+	}
+
+	.table-th {
+		display: table-cell;
+		font-weight: bold;
+		border: 1rpx solid #FAFAFA;
+		text-align: center;
+		vertical-align: middle;
+	}
+
+	.table-td {
+		display: inline-block;
+		border: 1rpx solid #FAFAFA;
+		text-align: center;
+		vertical-align: middle;
+		background: #fff;
+		font-size: 27rpx;
+		color: #666666;
+		padding: 62rpx 0;
+		width: 33.333%;
+	}
+
+	.table-td image {
+		width: 50rpx;
+		height: 50rpx;
+		margin-bottom: 23rpx;
+	}
+
+	.header {
+		width: 100%;
+		height: 198rpx;
+		position: relative;
+	}
+
+	.header .bg-img {
+		display: block;
+		position: absolute;
+		left: 0;
+		top: 0;
+		z-index: 1;
+		width: 100%;
+		height: 198rpx;
+	}
+
+	.header .info-block {
+		padding: 0 40rpx 0 48rpx;
+		height: 198rpx;
+		position: relative;
+		z-index: 2;
+		background: #3C94FC;
+/* 		background: #07c160; */
+	}
+
+	.header .info-block .title {
+		font-size: 36rpx;
+		color: #fff;
+		font-weight: 500;
+		line-height: 50rpx;
+	}
+
+	.header .info-block .desc {
+		font-size: 28rpx;
+		font-weight: 500;
+		color: #fff;
+		line-height: 40rpx;
+		margin-top: 8rpx;
+	}
+
+	.header .info-block .btn {
+		width: 170rpx;
+		height: 56rpx;
+		border-radius: 28rpx;
+		background-color: rgb(255, 255, 255);
+		text-align: center;
+		line-height: 52rpx;
+		font-size: 28rpx;
+		font-weight: 500;
+		color: #3387FF;
+	}
+
+	.table-td .iconfont {
+		font-size: 50rpx;
+		color: #44B549;
+		margin-bottom: 10rpx;
+	}
+</style>

+ 217 - 0
appletXcx/Wechat/interface.vue

@@ -0,0 +1,217 @@
+<template>
+	<view>
+		<view class="step">
+			<uni-steps active-color="#07c160" :options="options" :active="3"></uni-steps>
+		</view>
+		<view style="height: 130rpx;"></view>
+
+		<view class="main">
+			<view class="mainHeader">
+				地理位置
+			</view>
+
+			<view class="box-pack-between mainItem">
+				<view class="">
+					<view class="mainItemJk">
+						获取当前的地理位置、速度
+					</view>
+					<view class="mainItemdesc">
+						接口:wx.getLocation
+					</view>
+					<view class="red" v-if="obj.wx_getLocation_reason">
+						{{obj.wx_getLocation_reason}}
+					</view>
+				</view>
+				<view class="flex-center">
+					<!-- 已开通 -->
+					<!-- 		1	待申请开通
+								2	无权限
+								3	申请中
+								4	申请失败
+								5	已开通 -->
+					<block v-if="obj.wx_getLocation_status==1">
+						<button @click="go_Out('wx.getLocation')" type="primary" size="mini">
+							去开通
+						</button>
+					</block>
+					<block v-else-if="obj.wx_getLocation_status==2">
+						无权限
+					</block>
+					<block v-else-if="obj.wx_getLocation_status==3">
+						申请中
+					</block>
+					<block v-else-if="obj.wx_getLocation_status==4">
+						<text>申请失败</text>
+						<button @click="go_Out('wx.getLocation')" type="primary" size="mini">
+							重新开通
+						</button>
+					</block>
+					<block v-else-if="obj.wx_getLocation_status==5">
+						已开通
+					</block>
+				</view>
+			</view>
+
+			<view class="box-pack-between mainItem">
+				<view class="">
+					<view class="mainItemJk">
+						打开地图选择位置
+					</view>
+					<view class="mainItemdesc">
+						接口:wx.chooseLocation
+					</view>
+					<view class="red" v-if="obj.wx_chooseLocation_reason">
+						{{obj.wx_chooseLocation_reason}}
+					</view>
+				</view>
+				<view class="flex-center">
+					<!-- 已开通 -->
+					<block v-if="obj.wx_chooseLocation_status==1">
+						<button @click="go_Out('wx.chooseLocation')" type="primary" size="mini">去开通</button>
+					</block>
+					<block v-else-if="obj.wx_chooseLocation_status==2">
+						无权限
+					</block>
+					<block v-else-if="obj.wx_chooseLocation_status==3">
+						申请中
+					</block>
+					<block v-else-if="obj.wx_chooseLocation_status==4">
+						<text>申请失败</text>
+						<button @click="go_Out('wx.chooseLocation')" type="primary" size="mini">重新开通</button>
+					</block>
+					<block v-else-if="obj.wx_chooseLocation_status==5">
+						已开通
+					</block>
+				</view>
+			</view>
+			<view class="box-pack-between mainItem">
+				<view class="">
+					<view class="mainItemJk">
+						获取用户收货地址
+					</view>
+					<view class="mainItemdesc">
+						接口:wx.chooseAddress
+					</view>
+					<view class="red" v-if="obj.wx_chooseAddress_reason">
+						{{obj.wx_chooseAddress_reason}}
+					</view>
+				</view>
+				<view class="flex-center">
+					<!-- 已开通 -->
+					<block v-if="obj.wx_chooseAddress_status==1">
+						<button @click="go_Out('wx.chooseAddress')" type="primary" size="mini">去开通</button>
+					</block>
+					<block v-else-if="obj.wx_chooseAddress_status==2">
+						无权限
+					</block>
+					<block v-else-if="obj.wx_chooseAddress_status==3">
+						申请中
+					</block>
+					<block v-else-if="obj.wx_chooseAddress_status==4">
+						<text>申请失败</text>
+					   <button @click="go_Out('wx.chooseAddress')" type="primary" size="mini">去开通</button>
+					</block>
+					<block v-else-if="obj.wx_chooseAddress_status==5">
+						已开通
+					</block>
+				</view>
+			</view>
+
+		</view>
+	</view>
+</template>
+
+<script>
+	import optionsData from './data.js'
+	export default {
+		data() {
+			return {
+				obj: {},
+				options: optionsData.options,
+
+			}
+		},
+		onShow() {
+			this.getData()
+		},
+		methods: {
+
+			getData() {
+				this.request({
+					url: "Smdcshop/privacy_interface_info",
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+					},
+				}).then(res => {
+					/* 
+						"wx_getLocation_status": 5, //状态码
+						1	待申请开通
+						2	无权限
+						3	申请中
+						4	申请失败
+						5	已开通
+						"wx_chooseLocation_status": 5, //状态码
+						1	待申请开通
+						2	无权限
+						3	申请中
+						4	申请失败
+						5	已开通
+						"wx_chooseAddress_status": 5, //状态码
+						1	待申请开通
+						2	无权限
+						3	申请中
+						4	申请失败
+						5	已开通
+						"wx_getLocation_reason": "", //失败原因  记得做判断 有内容的时候再显示出来
+						"wx_chooseLocation_reason": "", //失败原因  记得做判断 有内容的时候再显示出来
+						"wx_chooseAddress_reason": "" //失败原因  记得做判断 有内容的时候再显示出来
+					   */
+					if (res.code == '200' || res.code == 200) {
+						console.log(res, "res")
+						this.obj = res.data
+					}
+				})
+			},
+
+			go_Out(e) {
+				uni.navigateTo({
+					url: "./interfaceDetail?api_name=" + e
+				})
+			},
+
+		}
+	}
+</script>
+
+<style>
+	.main {
+		padding: 0 20rpx;
+	}
+
+	.mainHeader {
+		font-size: 32rpx;
+		padding: 20rpx 0;
+	}
+
+	.mainItem {
+		font-size: 28rpx;
+		box-shadow: 0 1px 2px #f0f0f0;
+		border: 1px solid #f0f0f0;
+		padding: 50rpx 30rpx;
+		border-radius: 6rpx;
+		margin-bottom: 40rpx;
+	}
+
+	.mainItemJk {
+		margin-bottom: 20rpx;
+	}
+
+	.mainItemdesc {
+		color: #999;
+		font-size: 26rpx;
+	}
+	.red{
+		margin-top: 6rpx;
+		color: red;
+	}
+</style>

+ 259 - 0
appletXcx/Wechat/interfaceDetail.vue

@@ -0,0 +1,259 @@
+<template>
+	<view class="Address">
+		<view class="Address_haeder">
+			<view class="Address_haeder_title">
+				{{api_name}}接口申请
+			</view>
+			你正在提交接口申请,所有信息请如实填写,所填信息只用于审核。
+		</view>
+		<form @submit="save">
+			<view class="Address_main">
+				<view class="Address_item">
+					<view class="Address_item_title">
+						申请原因
+					</view>
+					<view class="">
+						<textarea name="content" maxlength="300" placeholder-class="Address_item_placeholder" :value="my_value"
+							placeholder="详细描述接口能力的具体使用场景如:因当前业务涉及外卖送餐服务,需获取用户地理位置信息。" />
+					</view>
+				</view>
+				<view class="Address_item">
+					<view class="Address_item_title">
+						辅助网页
+						(选填)
+					</view>
+					<view>
+						<input name="url"  type="text" placeholder-class="Address_item_placeholder" placeholder="可上传官网链接协助审核" />
+					</view>
+				</view>
+				<view class="Address_item">
+					<view class="Address_item_title">
+						辅助图片
+						(选填)
+					</view>
+					<view>
+						<view class="tip">
+							可上传小程序截图,最多上传10张图片。图片支持jpg、jpeg、bmp、gif或png格式,图片大小不超过5M。
+						</view>
+						<image class="add_icon" @click="uploadFile" src="../static/images/icon_6.png">
+						</image>
+						<block v-if="img_arr.length>0">
+							<view class="add_icon" v-for="(item,index) of img_arr">
+								<image class="img" :src="URL+item" :key='index'></image>
+								<image @click="bindDel(index)" src="../static/images/shanchu.png" class="del"></image>
+							</view>
+						</block>
+					</view>
+					<view>
+						<view class="tip">
+							可上传小程序使用录屏,最多上传1个视频。视频支持mp4格式,视频大小不超过20M。
+						</view>
+						<image class="add_icon" @click="chooseVideo" src="../static/images/icon_6.png">
+						</image>
+						<view v-if="video_url">
+							<video style="width: 100%;" :src="URLVideo+video_url" controls></video>
+						</view>
+					</view>
+				</view>
+				<button type="primary" formType="submit">提交申请</button>
+			</view>
+		</form>
+
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				img_arr: [],
+				URL: getApp().globalData.URL,
+				URLVideo: getApp().globalData.URL + '/uploads/video/',
+				video_url: '',
+				api_name:'',
+				my_value:'',
+			}
+		},
+		onLoad(e) {
+			this.api_name= e.api_name ||'wx.getLocation';
+			let my_value;
+			if(e.api_name == 'wx.getLocation'){
+				my_value="需要获取用户定位,用于计算客户与我司的位置距离,方便客户导航到我司。"
+			}else if(e.api_name == 'wx.chooseLocation'){
+				my_value="打开地图选择位置:因涉及消费者填写收货地址,需要申请打开地图选择位置方便用户选择位置;商家把线下把货送给消费者。"
+			}else if(e.api_name == 'wx.chooseAddress'){
+				my_value="因涉及商家把货送给用户,需要申请获取用户收货地址。"
+			}
+			
+			this.my_value =my_value
+		},
+		methods: {
+			save(e){
+				let params = e.detail.value;
+				let data = Object.assign({
+					admin_id:uni.getStorageSync("admin_id"),
+					images:this.img_arr.join(","),
+					video:this.video_url,
+					api_name:this.api_name
+				}, params);
+				this.request({
+					url: "Smdcshop/apply_privacy_interface",
+					data,
+					hide:true
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code === '200') {
+						console.log(res)
+						
+						uni.showToast({
+							title: "提交成功",
+							icon: 'none',
+							duration: 1000
+						})
+						
+						setTimeout(() => {
+							uni.navigateBack({
+								delta: 1
+							})
+						}, 1500)
+						
+					}
+				}).catch((err) => {
+					console.log(err)
+					uni.showModal({
+						title:"提示",
+						content: err.message,
+						showCancel:true,
+						confirmText:"复制错误",
+						success:(res)=>{
+							res.confirm && uni.setClipboardData({
+							data: err.message,
+							success: function(r) {
+								console.log('赋能成功', r);
+							}
+						  });
+						}
+					})
+					// uni.showToast({
+					// 	title: err.message,
+					// 	icon: 'none',
+					// 	duration: 2000
+					// })
+					
+				})
+			},
+			uploadFile(e) {
+				uni.chooseImage({
+					success: (res) => {
+						res.tempFilePaths.forEach((v, i) => {
+							console.log(v)
+							this.Upload({
+								url: "setting/upload",
+								data: {
+									url: v,
+									admin_id: uni.getStorageSync("admin_id"),
+								}
+							}).then(res => {
+								console.log(res, "res")
+								this.img_arr.push(res.src);
+							}).catch({});
+						})
+					}
+				});
+			},
+			chooseVideo(e) {
+				// 上传视频
+				uni.chooseVideo({
+					maxDuration: 60,
+					sourceType: ['album', 'camera'],
+					success: (responent) => {
+						let videoFile = responent.tempFilePath;
+						this.Upload({
+							url: "videofuneng/video_upload",
+							data: {
+								url: videoFile,
+								type: 0,
+								// token: uni.getStorageSync("token"),
+							}
+						}).then(res => {
+							console.log(res, "res")
+							this.video_url = res.file_name;
+						}).catch({
+
+						});
+					}
+				})
+			},
+			bindDel(index) {
+				this.img_arr.splice(index, 1)
+			},
+		}
+	}
+</script>
+
+<style>
+	page {
+		background: #F1F1F1;
+	}
+
+	.Address {
+		padding: 20rpx;
+	}
+
+	.Address_haeder {
+		font-size: 24rpx;
+		color: #999
+	}
+
+	.Address_haeder_title {
+		font-size: 34rpx;
+		color: #000;
+	}
+
+	.Address_main {
+		background: #FFFFFF;
+		border-radius: 6rpx;
+		margin-top: 20rpx;
+	}
+
+	.Address_item {
+		padding: 20rpx;
+		margin-bottom: 10rpx;
+		border-bottom: 1rpx solid #F1F1F1;
+	}
+
+	.Address_item_title {
+		padding-bottom: 20rpx;
+	}
+
+	.Address_item_placeholder {
+		font-size: 24rpx;
+	}
+
+	.add_icon {
+		display: inline-block;
+		width: 200rpx;
+		height: 200rpx;
+		border: 1rpx solid #F1F1F1;
+		margin: 20rpx 10rpx 20rpx 0;
+		position: relative;
+	}
+
+	.add_icon .img {
+		width: 100%;
+		height: 100%;
+	}
+
+	.tip {
+		font-size: 24rpx;
+		color: #999
+	}
+
+	.add_icon .del {
+		position: absolute;
+		right: 0;
+		top: 0;
+		width: 40rpx;
+		height: 40rpx;
+	}
+</style>

+ 327 - 0
appletXcx/Wechat/qrCode.vue

@@ -0,0 +1,327 @@
+<template>
+	<view class="content">
+		
+		<view class="step">
+			<uni-steps active-color="#07c160" :options="options" :active="1"></uni-steps>
+		</view>
+		<view  style="height: 130rpx;"></view>
+		<!-- <view class="hg72"></view> -->
+		<block v-if="obj.state==1">
+			<view v-if="is_auth">
+				<view class="home-content">
+					<view class="home-content-title flex-center">
+							 微信授权二维码
+					</view>
+					<view class="home-content-code ">
+						<view class="home-content-tip">
+							*新创建的小程序请先保存图片微信长按识别后,再让商家扫码进行授权。或者复制链接在微信打开,再让商家扫码进行授权
+						</view>
+						<view class="flex-center">
+							<tki-qrcode v-if="ifShow" cid="qrcode1" ref="qrcode" :val="qrcodeVal" :size="size" :unit="unit"
+								:background="background" :foreground="foreground" :pdground="pdground" :icon="icon"
+								:iconSize="iconsize" :lv="lv" :onval="onval" :loadMake="loadMake" :usingComponents="true"
+								@result="qrR" />
+						</view>
+						<view @click="Refresh" class="flex-center" style="font-size: 26rpx;">
+							<uni-icons color="#999" type="refreshempty" size="25"></uni-icons> 
+							如授权完成,点击此处刷新页面
+						</view>
+				<!-- 		<view class="">
+							{{qrcodeVal}}
+						</view> -->
+					</view>
+				</view>
+				
+				<view class="bottom-bar" style="background: none;">
+					<button @click="upCode">
+						下载二维码
+					</button>
+					
+					<button @click="upCopy" style="margin-top: 25rpx;">
+						复制链接
+					</button>
+					
+				</view>
+				
+			</view>
+			
+			<view v-else class="bottom-bar">
+				<view class="auth-text flex-center">
+					<uni-icons color="#999" type="checkbox-filled" size="30"></uni-icons> 已授权
+				</view>
+				<button @click="rest" style="width: 500rpx;">
+					重新授权
+				</button>
+			</view>
+		</block>
+		
+		
+	</view>
+</template>
+
+<script>
+		import optionsData from './data.js'
+	// #ifdef MP-WEIXIN
+	import saveImgToPhotosAlbum from "@/static/js/saveImgToPhotosAlbum.js";
+	// #endif
+	import tkiQrcode from "../components/tki-qrcode/tki-qrcode.vue"
+	export default {
+		components: {
+			tkiQrcode,
+		},
+		data() {
+			return { //二维码相关参数
+				ifShow: true,
+				val: '二维码', // 要生成的二维码值
+				size: 350, // 二维码大小
+				unit: 'upx', // 单位
+				background: '#000000', // 背景色
+				foreground: '#ffffff', // 前景色
+				pdground: '#ffffff', // 角标色
+				icon: '', // 二维码图标
+				iconsize: 40, // 二维码图标大小
+				lv: 3, // 二维码容错级别 , 一般不用设置,默认就行
+				onval: false, // val值变化时自动重新生成二维码
+				loadMake: true, // 组件加载完成后自动生成二维码
+				src: '', // 二维码生成后的图片地址或base64
+				info: {},
+				id: "",
+				URL: getApp().globalData.URL,
+				qrcodeVal: "",
+				wxqr: 1,
+				qrcodeImg:'',
+				obj:null,
+				is_auth:false,
+				options:optionsData.options
+			}
+		},
+		
+		onLoad(e) {
+			this.wechat_index();
+		},
+
+		methods: { 
+			upCopy(){
+				uni.setClipboardData({
+					data: this.qrcodeVal,
+					success: function (r) {
+					}
+				});
+			},
+			Refresh(){
+				this.wechat_index();
+			},
+			  wechat_index() {
+				this.request({
+					url: 'setting/wechat_index',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+					},
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code === "200") {
+						this.obj = res.data;
+						this.is_auth= false;
+						// 未授权
+						if(res.data.state==1 && res.data.status==0){
+							this.is_auth= true;
+							this.https();
+						}
+						
+					}
+				});
+			},
+			rest(){
+				this.is_auth= true;
+				this.https();
+			},
+			
+			qrR(e) {
+				this.qrcodeImg=e;
+				console.log(e, "ee")
+			},
+			 
+			https() {
+				this.request({
+					url: 'WechatAuthorization/index',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+					},
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code === "200") {
+						this.qrcodeVal = res.data;
+						setTimeout(()=>{
+							this.$refs.qrcode._makeCode()
+						},50)
+						
+					}
+				});
+			},
+			
+			upCode(e) {
+				// #ifdef H5
+				uni.showModal({
+					title: '提示',
+					content: '请长按二维码图片进行保存',
+					showCancel: false,
+					confirmText: '好的',
+				});
+				// #endif
+				// #ifdef MP-WEIXIN 
+				this.$refs.qrcode._saveCode()
+				
+				return
+				
+				var url = this.qrcodeImg;
+				console.log(url, "url")
+				saveImgToPhotosAlbum.saveImgToPhotosAlbum(url).then((res) => {
+					//成功的逻辑
+					console.log(res, "保存成功")
+					uni.showToast({
+						title: '保存成功',
+						icon: 'none',
+						mask: true,
+					})
+				}).catch((err) => {
+					console.log(err, "保存失败")
+					if (err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" ||
+						err.errMsg === "saveImageToPhotosAlbum:fail auth deny" || err.errMsg ===
+						"saveImageToPhotosAlbum:fail authorize no response") {
+						// 这边微信做过调整,必须要在按钮中触发,因此需要在弹框回调中进行调用
+						uni.showModal({
+							title: '提示',
+							content: '需要您设置授权保存相册',
+							showCancel: false,
+							success: modalSuccess => {
+								uni.openSetting({
+									success(settingdata) {
+										console.log("settingdata", settingdata)
+										if (settingdata.authSetting[
+												'scope.writePhotosAlbum']) {
+											uni.showModal({
+												title: '提示',
+												content: '获取权限成功,再次点击图片即可保存',
+												showCancel: false,
+											})
+										} else {
+											uni.showModal({
+												title: '提示',
+												content: '获取权限失败,将无法保存到相册哦~',
+												showCancel: false,
+											})
+										}
+									},
+									fail(failData) {
+										console.log("failData", failData)
+									},
+									complete(finishData) {
+										console.log("finishData", finishData)
+									}
+								})
+
+							}
+						})
+					}
+					// 失败后的逻辑
+				})
+				// #endif			
+			},
+		}
+	}
+</script>
+
+<style>
+	page {
+		background: #F5F7FA;
+	}
+		.home-content-tip{
+			font-size: 28rpx;
+			color: red;
+			padding: 10rpx 10rpx 0 10rpx;
+			
+		}
+	.hg72 {
+		height: 72rpx;
+	}
+
+	.home-content {
+		background: #FFFFFF;
+		width: 670rpx;
+		height: 843rpx;
+		margin: 0 auto;
+		position: relative;
+
+	}
+
+	.home-content-title {
+		width: 100%;
+		height: 154rpx;
+		background: linear-gradient(180deg, #07c160, #07c160);
+		border-radius: 16rpx 16rpx 0px 0px;
+		font-size: 36rpx;
+		font-family: PingFang SC, PingFang SC-Medium;
+		font-weight: 500;
+		color: #ffffff;
+	}
+
+	.home-content-code {
+		width: 100%;
+		height: 689rpx;
+		font-size: 32rpx;
+		font-family: PingFang SC, PingFang SC-Regular;
+		font-weight: 400;
+		color: #464646;
+		text-align: center;
+	}
+
+	.home-content-code image {
+		width: 400rpx;
+		height: 400rpx;
+		
+		margin-bottom: 64rpx;	margin-top: 64rpx;
+	}
+
+	.home-content-code-title {
+		padding: 0 30rpx;
+		color: red;
+	}
+
+	.code-btn {
+		font-size: 32rpx;
+		font-family: PingFang SC, PingFang SC-Regular;
+		font-weight: 400;
+		color: #3c8cff;
+		margin-bottom: 35rpx;
+	}
+
+	.bottom-bar {
+		position: fixed;
+		/* bottom: 50rpx; */
+		width: 100%;
+		z-index: 1000;
+		padding: 30rpx 0;
+
+	}
+
+	.bottom-bar button {
+		text-align: center;
+		width: 690rpx;
+		height: 90rpx;
+		background: linear-gradient(132deg, #07c160 0%, #07c160 100%);
+		box-shadow: 0px 2rpx 12rpx #07c160;
+		opacity: 1;
+		border-radius: 10rpx;
+		color: #fff;
+		font-size: 32rpx;
+		font-family: Source Han Sans CN, Source Han Sans CN-Medium;
+		font-weight: 500;
+		color: #ffffff;
+	}
+	.auth-text{
+		    text-align: center;
+		    font-size: 52rpx;
+		    padding-bottom: 100rpx;
+			color: #999;
+	}
+</style>

+ 418 - 0
appletXcx/WechatShop/addPay.vue

@@ -0,0 +1,418 @@
+<template>
+	<view class="">
+		<view class="step">
+			<uni-steps active-color="#FF6A69" :options="[
+			{title: '注册账号',url:'./getShop'},
+			{title: '扫码授权',url:'./qrCode'},
+			{title: '提交支付资质',url:'./addPay'}, 
+			{title: '基础信息',url:'./basics'} ]" :active="2"></uni-steps>
+		</view>
+
+		<view style="height: 130rpx;"></view>
+
+		<form @submit="onSubmit">
+			<view class="content">
+
+<!-- 				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>小程序APPID</text>
+					</view>
+					<view class="desc">
+						<text>{{obj.appid}}</text>
+					</view>
+				</view> -->
+
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>主体类型</text>
+					</view>
+					<view class="desc ft30 flex-grow-1 box-pack-between" @click="onPrinterStatusChange">
+						<text></text>
+						<view class="flex-y-center">
+							{{codeStatus}}
+							<text class="iconfont icongengduo"></text>
+						</view>
+					</view>
+				</view>
+
+				<view class="box-pack-between border-b header-version flex-y-center item" @click="uploadFile(1)">
+					<view class="header-img ft28">
+						营业执照照片
+						<view class="ft22">
+							(最大1M,暂不限制宽高)
+						</view>
+					</view>
+					<view class="home-img">
+						<image :src="URL+business_license_photo.src" class="home-img-icon"></image>
+					</view>
+				</view>
+
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>注册号/统一社会信用代码</text>
+					</view>
+					<view class="desc">
+						<input type="text" :value="info.license_number" name="license_number" class="input-box"
+							placeholder="注册号/统一社会信用代码" placeholder-class="desc-placeholder">
+					</view>
+				</view>
+
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>商户名称</text>
+					</view>
+					<view class="desc">
+						<input type="text" :value="info.merchant_name" name="merchant_name" class="input-box"
+							placeholder="请输入商户名称" placeholder-class="desc-placeholder">
+					</view>
+				</view>
+
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>商户简称</text>
+					</view>
+					<view class="desc">
+						<input type="text" :value="info.merchant_shortname" name="merchant_shortname" class="input-box"
+							placeholder="请输入商户简称" placeholder-class="desc-placeholder">
+					</view>
+				</view>
+
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>个体户经营者/法人姓名</text>
+					</view>
+					<view class="desc">
+						<input type="text" :value="info.legal_person" name="legal_person" class="input-box"
+							placeholder="请输入个体户经营者/法人姓名" placeholder-class="desc-placeholder">
+					</view>
+				</view>
+
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>法人手机</text>
+					</view>
+					<view class="desc">
+						<input type="text" :value="info.contact_phone" name="contact_phone" class="input-box"
+							placeholder="请输入法人手机" placeholder-class="desc-placeholder">
+					</view>
+				</view>
+
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>法人邮箱</text>
+					</view>
+					<view class="desc">
+						<input type="text" :value="info.contact_email" name="contact_email" class="input-box"
+							placeholder="请输入法人邮箱" placeholder-class="desc-placeholder">
+					</view>
+				</view>
+
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>证件类型</text>
+					</view>
+					<view class="desc">
+						中国大陆居民-身份证
+					</view>
+				</view>
+
+				<view class="box-pack-between border-b header-version flex-y-center item" @click="uploadFile(2)">
+					<view class="header-img ft28">
+						身份证正面(人像)
+						<view class="ft22">
+							(最大1M,暂不限制宽高)
+						</view>
+					</view>
+					<view class="home-img">
+						<image :src="URL+id_card_photo1.src" class="home-img-icon"></image>
+					</view>
+				</view>
+
+				<view class="box-pack-between border-b header-version flex-y-center item" @click="uploadFile(3)">
+					<view class="header-img ft28">
+						身份证反面(国徽)
+						<view class="ft22">
+							(最大1M,暂不限制宽高)
+						</view>
+					</view>
+					<view class="home-img">
+						<image :src="URL+id_card_photo2.src" class="home-img-icon"></image>
+					</view>
+				</view>
+
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>身份证姓名</text>
+					</view>
+					<view class="desc">
+						<input type="text" :value="info.id_card_name" name="id_card_name" class="input-box"
+							placeholder="请输入身份证姓名" placeholder-class="desc-placeholder">
+					</view>
+				</view>
+
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>身份证号码</text>
+					</view>
+					<view class="desc">
+						<input type="text" :value="info.id_card_number" name="id_card_number" class="input-box"
+							placeholder="请输入身份证号码" placeholder-class="desc-placeholder">
+					</view>
+				</view>
+
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>身份证有效期开始时间</text>
+					</view>
+					<view class="desc">
+						<input type="text" :value="info.card_period_begin" name="card_period_begin" class="input-box"
+							placeholder="请输入身份证有效期开始时间" placeholder-class="desc-placeholder">
+					</view>
+				</view>
+
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>身份证有效期结束时间</text>
+					</view>
+					<view class="desc">
+						<input type="text" :value="info.card_period_end" name="card_period_end" class="input-box"
+							placeholder="请输入身份证有效期结束时间" placeholder-class="desc-placeholder">
+					</view>
+				</view>
+
+				<view class="box-pack-between border-b header-version flex-y-center item" @click="uploadFile(4)">
+					<view class="header-img ft28">
+						特殊资质
+						<view class="ft22">
+							(最大1M,暂不限制宽高)
+						</view>
+					</view>
+					<view class="home-img">
+						<image :src="URL+qualifications_photo.src" class="home-img-icon"></image>
+					</view>
+				</view>
+
+			</view>
+
+			<button class="sub-btn" hover-class="none" form-type="submit">
+				立即提交
+			</button>
+
+		</form>
+
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				URL: getApp().globalData.URL,
+				codeStatus: '个体工商户(营业执照上的主体类型一般为个体户、个体工商户、个体经营)',
+				// obj: {},
+				
+				business_license_photo:{},
+				
+				id_card_photo1:{},
+				
+				id_card_photo2:{},
+				
+				qualifications_photo:{},
+				info:{},
+			}
+		},
+
+		onLoad(e) {
+			this.wechat_store();
+		},
+
+		methods: {
+			
+			uploadFile(type) {
+				var url =  "Wechatstore/upload";
+				uni.chooseImage({
+					success: (res) => {
+						res.tempFilePaths.forEach((v, i) => {
+							console.log(v)
+							this.Upload({
+								url: url,
+								data: {
+									url: v,
+									admin_id: uni.getStorageSync("admin_id"),
+								}
+							}).then(r => {
+								console.log(r, "res")
+									let res={
+										pay_media_id:r.pay_media_id,
+										src:r.src,
+										url:r.url,
+									}
+								    type == 1 ? (this.business_license_photo = res) :
+									type == 2 ? (this.id_card_photo1 = res) :
+									type == 3 ? (this.id_card_photo2 = res) : (this.qualifications_photo = res);
+							}).catch({});
+						})
+					}
+				});
+			},
+
+			onPrinterStatusChange() {
+				let statusArr = ['个体工商户(营业执照上的主体类型一般为个体户、个体工商户、个体经营)',
+					'企业(营业执照上的主体类型一般为有限公司、有限责任公司)'
+				]
+				uni.showActionSheet({
+					itemList: statusArr,
+					success: (r) => {
+						console.log(r.tapIndex)
+						this.code_type = r.tapIndex==1?2:4;
+						this.codeStatus = statusArr[r.tapIndex];
+					}
+				})
+			},
+
+			wechat_store() {
+				this.request({
+					url: 'Wechatstore/wechat_store',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+					}
+				}).then(res => {
+					this.info = res.data;
+			this.codeStatus = res.data.subject_type == 2 ? '企业(营业执照上的主体类型一般为有限公司、有限责任公司)' : res.data.subject_type == 4 ? '个体工商户(营业执照上的主体类型一般为个体户、个体工商户、个体经营)' :
+				'';
+			this.code_type = res.data.subject_type;
+			
+			this.business_license_photo=res.data.business_license_photo;
+			
+			this.id_card_photo1=res.data.id_card_photo1;
+			
+			this.id_card_photo2=res.data.id_card_photo2;
+			
+			this.qualifications_photo=res.data.qualifications_photo;
+
+				})
+			},
+			
+			onSubmit(e){
+				
+				let data=e.detail.value;
+				data.subject_type=this.code_type;
+				
+				data.admin_id=uni.getStorageSync("admin_id");
+				
+				data.business_license_photo=this.business_license_photo;
+				
+				data.id_card_photo1=this.id_card_photo1;
+				
+				data.id_card_photo2=this.id_card_photo2;
+				
+				data.qualifications_photo=this.qualifications_photo;
+				
+				data.id_doc_type='IDENTIFICATION_TYPE_IDCARD';
+				
+				console.log(data,"data")
+				// return
+				this.request({
+					url: "Wechatstore/wechat_store_submit",
+					data: data,
+				}).then(res => {
+					if (res.code == 200) {
+						uni.showToast({
+							title: res.message,
+							icon: 'none'
+						})
+						setTimeout(() => {
+							uni.redirectTo({
+								url:'./basics'
+							})
+						}, 2000)
+					}
+				}).catch((res) => {
+					uni.showToast({
+						title: res.message,
+						icon: 'none'
+					})
+				})
+			},
+
+
+		},
+	}
+</script>
+
+<style>
+	page {
+		background-color: #F4F5F7;
+	}
+
+	.item {
+		background-color: #FFF;
+		padding: 0 25rpx;
+	}
+
+	.title-block {
+		margin-right: 20rpx;
+		max-width: 220rpx;
+	}
+	
+	.title-block text{
+		font-size: 28rpx;
+	}
+	.desc {
+		text-align: right;
+		flex: 1;
+		padding: 25rpx 0;
+		border-bottom: 1rpx solid #F1F1F1;
+	}
+
+	.rund {
+		width: 40rpx;
+		height: 40rpx;
+	}
+
+	.red {
+		color: red;
+		padding: 10rpx 25rpx;
+		font-size: 26rpx;
+	}
+
+	.sub-btn {
+		width: 690rpx;
+		height: 100rpx;
+		background: linear-gradient(315deg, #FF6A69 2%, #FF6A69 99%);
+		border-radius: 8rpx;
+		box-shadow: 0px 0px 8rpx 0px rgba(51, 135, 255, 0.20);
+		text-align: center;
+		line-height: 100rpx;
+		color: #fff;
+		font-size: 36rpx;
+		font-weight: bold;
+		margin: 0 auto;
+		margin-top: 30px;
+	}
+
+	.home-upload {
+		border: 1rpx solid #e3e4e5;
+		height: 80rpx;
+		border-radius: 6rpx;
+		padding: 0 32rpx;
+		min-width: 180rpx;
+		font-size: 28rpx;
+		letter-spacing: 0;
+		background: #f6f7f8;
+	}
+
+	.home-img-icon {
+		border: 1rpx solid #ccc;
+		width: 200rpx;
+		height: 200rpx;
+	}
+
+	.header-img {
+		max-width: 300rpx;
+	}
+
+	.header-version {
+		padding: 20rpx 25rpx;
+	}
+</style>

+ 276 - 0
appletXcx/WechatShop/basics.vue

@@ -0,0 +1,276 @@
+<template>
+	<view class="">
+		<view class="step">
+
+			<uni-steps active-color="#FF6A69" :options="[
+			{title: '注册账号',url:'./getShop'},
+			{title: '扫码授权',url:'./qrCode'},
+			{title: '提交支付资质',url:'./addPay'}, 
+			{title: '基础信息',url:'./basics'} ]" :active="3"></uni-steps>
+		</view>
+
+		<view style="height: 130rpx;"></view>
+
+		<form @submit="onSubmit">
+
+			<view class="box-pack-between item flex-y-center border-b" style="padding: 30rpx;">
+				<text>基本信息</text>
+			</view>
+
+			<view class="content">
+
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>小程序名称</text>
+					</view>
+					<view class="desc">
+						<input type="text" :value="info.nickname" name="nickname" class="input-box"
+							placeholder="请输入小程序名称" placeholder-class="desc-placeholder">
+					</view>
+				</view>
+
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>小程序简称</text>
+					</view>
+					<view class="desc">
+						<input type="text" :value="info.abbr" name="abbr" class="input-box" placeholder="请输入小程序简称"
+							placeholder-class="desc-placeholder">
+					</view>
+				</view>
+
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>介绍内容</text>
+					</view>
+					<view class="desc">
+						<input type="text" :value="info.introduction" name="introduction" class="input-box"
+							placeholder="请输入介绍内容" placeholder-class="desc-placeholder">
+					</view>
+				</view>
+			</view>
+
+			<view class="box-pack-between item flex-y-center border-b" style="padding: 30rpx;margin-top: 20rpx;">
+				<text>退货信息</text>
+			</view>
+
+			<view class="item flex flex-y-center">
+				<view class="title-block required">
+					<text>收货人姓名</text>
+				</view>
+				<view class="desc">
+					<input type="text" :value="info.user_name" name="user_name" class="input-box" placeholder="请输入收货人姓名"
+						placeholder-class="desc-placeholder">
+				</view>
+			</view>
+			<view class="item flex flex-y-center">
+				<view class="title-block required">
+					<text>邮箱</text>
+				</view>
+				<view class="desc">
+					<input type="text" :value="info.mail" name="mail" class="input-box" placeholder="请输入邮箱"
+						placeholder-class="desc-placeholder">
+				</view>
+			</view>
+
+			<view class="item flex flex-y-center">
+				<view class="title-block required">
+					<text>联系号码</text>
+				</view>
+				<view class="desc">
+					<input type="text" :value="info.tel_number" name="tel_number" class="input-box"
+						placeholder="请输入联系号码" placeholder-class="desc-placeholder">
+				</view>
+			</view>
+
+			<view class="item flex flex-y-center box-pack-between" @click="open">
+				<view class="title-block required">
+					<text>商户地址</text>
+				</view>
+				<view class="desc">
+					{{address.Prov_title}} {{address.City_title}} {{address.Dist_title}}
+					<text class="iconfont icongengduo"></text>
+				</view>
+			</view>
+
+			<!-- 			<view class="bgf mar-24 item box-pack-between" @click="open" data-type="1">
+				<text class="ft28">商户地址</text>
+				<view class=" flex-y-center br desc">
+					<view class="flex-y-center ft26">
+						{{address.Prov_title}} {{address.City_title}} {{address.Dist_title}}
+						<text class="iconfont icongengduo"></text>
+					</view>
+				</view>
+			</view> -->
+
+
+			<view class="item flex flex-y-center">
+				<view class="title-block required">
+					<text>详细地址</text>
+				</view>
+				<view class="desc">
+					<input type="text" :value="info.detail_info" name="detail_info" class="input-box"
+						placeholder="请输入详细地址" placeholder-class="desc-placeholder">
+				</view>
+			</view>
+
+			<button class="sub-btn" hover-class="none" form-type="submit">
+				立即提交
+			</button>
+
+		</form>
+		<uni-popup ref="uniScroll" type="bottom">
+			<uni-scroll :Prov_arr="Prov_arr" @select="select"></uni-scroll>
+		</uni-popup>
+	</view>
+</template>
+
+<script>
+	import uniScroll from '../components/uni-scroll/uni-scroll.vue'
+	export default {
+		components: {
+			uniScroll,
+		},
+		data() {
+			return {
+				Prov_arr: [],
+				address: {
+					Prov_title: "请选择",
+					City_title: "",
+					Dist_title: "",
+				},	
+				info:{}
+			}
+		},
+		onLoad() {
+			this.wechat_store();
+			this.Prov();
+		},
+		methods: {
+			open(e) {
+				var type = e.currentTarget.dataset.type;
+				this.$refs.uniScroll.open();
+			},
+			
+			wechat_store() {
+				this.request({
+					url: 'Wechatstore/wechat_store',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+					}
+				}).then(res => {
+					this.info = res.data;
+					this.address = {
+						Prov_title: res.data.province_name,
+						Prov_code: res.data.s_province,
+						City_title: res.data.city_name,
+						City_code: res.data.s_city,
+						Dist_title: res.data.county_name,
+						Dist_code: res.data.s_area,
+					}
+				})
+			},
+			
+			// 获取省
+			Prov(e) {
+				this.request({
+					url: "setting/getprovince",
+					data: {},
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code === '200') {
+						this.Prov_arr = res.data;
+					}
+				});
+			},
+			
+			// 获取地址
+			select(e) {
+				console.log(e)
+				this.address = e;
+			},
+
+			onSubmit(e) {
+				let data = e.detail.value;
+				data.admin_id = uni.getStorageSync("admin_id");
+				data.s_province = this.address.Prov_code;
+				data.s_city = this.address.City_code;
+				data.s_area = this.address.Dist_code;
+				// console.log(data, "data")
+				// return
+				this.request({
+					url: "Wechatstore/submit_basicinfo",
+					data: data,
+				}).then(res => {
+					if (res.code == 200) {
+						uni.showToast({
+							title: res.message,
+							icon: 'none'
+						})
+						setTimeout(() => {
+							uni.navigateBack()
+						}, 2000)
+					}
+				}).catch((res) => {
+					uni.showToast({
+						title: res.message,
+						icon: 'none'
+					})
+				})
+			},
+		}
+	}
+</script>
+
+<style>
+	page {
+		background-color: #F4F5F7;
+	}
+
+	.item {
+		background-color: #FFF;
+		padding: 0 25rpx;
+	}
+
+	.title-block {
+		margin-right: 20rpx;
+		max-width: 220rpx;
+	}
+
+	.title-block text {
+		font-size: 28rpx;
+	}
+
+	.desc {
+		text-align: right;
+		flex: 1;
+		padding: 25rpx 0;
+		border-bottom: 1rpx solid #F1F1F1;
+	}
+
+	.rund {
+		width: 40rpx;
+		height: 40rpx;
+	}
+
+	.red {
+		color: red;
+		padding: 10rpx 25rpx;
+		font-size: 26rpx;
+	}
+
+	.sub-btn {
+		width: 690rpx;
+		height: 100rpx;
+		background: linear-gradient(315deg, #FF6A69 2%, #FF6A69 99%);
+		border-radius: 8rpx;
+		box-shadow: 0px 0px 8rpx 0px rgba(51, 135, 255, 0.20);
+		text-align: center;
+		line-height: 100rpx;
+		color: #fff;
+		font-size: 36rpx;
+		font-weight: bold;
+		margin: 0 auto;
+		margin-top: 30px;
+	}
+</style>

+ 273 - 0
appletXcx/WechatShop/getShop.vue

@@ -0,0 +1,273 @@
+<template>
+	<view class="container">
+		
+		<view class="step">
+			<uni-steps active-color="#FF6A69" :options="[
+			{title: '注册账号',url:'./getShop'},
+			{title: '扫码授权',url:'./qrCode'},
+			{title: '提交支付资质',url:'./addPay'}, 
+			{title: '基础信息',url:'./basics'} ]" :active="0"></uni-steps>
+		</view>
+		<view  style="height: 130rpx;"></view>
+		<form @submit="onSubmit">
+			<view class="content">
+	
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>微信号:</text>
+					</view>
+					<view class="desc">
+						<input type="text" :value="info.wx_name" name="wx_name" class="input-box" placeholder="请输入微信号"
+							placeholder-class="desc-placeholder">
+					</view>
+				</view>
+
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>身份证姓名:</text>
+					</view>
+					<view class="desc">
+						<input type="text" :value="info.id_card_name" name="id_card_name" class="input-box" placeholder="请输入身份证姓名"
+							placeholder-class="desc-placeholder">
+					</view>
+				</view>
+				
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>身份证号:</text>
+					</view>
+					<view class="desc">
+						<input type="text" :value="info.id_card_number" name="id_card_number"
+							class="input-box" placeholder="请输入身份证号" placeholder-class="desc-placeholder">
+					</view>
+				</view>
+
+				<view class="item flex flex-y-center">
+					<view class="title-block required">
+						<text>开通类型:</text>
+					</view>
+					<view class="desc ft30 flex-grow-1 box-pack-between" @click="onPrinterStatusChange">
+						<text></text>
+						<view class="flex-y-center">
+							{{codeStatus}}
+							<text class="iconfont icongengduo"></text>
+						</view>
+					</view>
+				</view>
+			</view>
+			
+			<button class="sub-btn" hover-class="none" form-type="submit">
+				立即提交
+			</button>
+			
+		</form>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				info: {},
+				ali_arr: [
+					'关闭', '开启'
+				],
+				is_coupon: 0,
+				setColor: "",
+				code_type: 1,
+				codeStatus: '整店打包(开通小商店)',
+			}
+		},
+
+		onLoad() {
+			this.getdata();
+		},
+
+		methods: {
+			onPrinterStatusChange() {
+				let statusArr = ['整店打包(开通小商店)', '组件开放(开通小程序,并且已经完整的嵌入电商功能)',]
+				uni.showActionSheet({
+					itemList: statusArr,
+					success: (r) => {
+						console.log(r.tapIndex)
+						this.code_type = Number(r.tapIndex) + 1
+						this.codeStatus = statusArr[r.tapIndex]
+					}
+				})
+			},
+
+			bindColor(e) {
+				this.setColor = e.detail.value;
+			},
+
+			choicemenber(index) {
+				this.is_coupon = index;
+			},
+
+			getdata(e) {
+				this.request({
+					url: "Wechatstore/wechat_info_list",
+					data: {
+						admin_id: uni.getStorageSync("admin_id")
+					},
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code === '200') {
+						this.info = res.data;
+						this.code_type = res.data.api_openstore_type;
+						this.codeStatus = res.data.api_openstore_type == 1 ? '整店打包(开通小商店)' : res.data.api_openstore_type == 2 ? '组件开放(开通小程序,并且已经完整的嵌入电商功能)' :
+							'';
+					}
+				});
+			},
+
+			onSubmit(e) {
+				let data = e.detail.value;
+				data.admin_id = uni.getStorageSync("admin_id");
+				data.api_openstore_type = this.code_type;
+				this.request({
+					url: "Wechatstore/register_shop",
+					data: data,
+				}).then(res => {
+					if (res.code == 200) {
+						uni.showToast({
+							title: res.message,
+							icon: 'none'
+						})
+						setTimeout(() => {
+							uni.redirectTo({
+								url:'./qrCode'
+							})
+						}, 2000)
+					}
+				}).catch((res) => {
+					uni.showToast({
+						title: res.message,
+						icon: 'none'
+					})
+				})
+			},
+
+		}
+	}
+</script>
+
+<style>
+	page {
+		background-color: #F4F5F7;
+	}
+
+	.item {
+		background-color: #FFF;
+		padding: 0 25rpx;
+	}
+
+	.title-block {
+		margin-right: 20rpx;
+	}
+
+	.desc {
+		text-align: right;
+		flex: 1;
+		padding: 25rpx 0;
+		border-bottom: 1rpx solid #F1F1F1;
+	}
+
+	.rund {
+		width: 40rpx;
+		height: 40rpx;
+	}
+
+	.red {
+		color: red;
+		padding: 10rpx 25rpx;
+		font-size: 26rpx;
+	}
+
+	.sub-btn {
+		width: 690rpx;
+		height: 100rpx;
+		background: linear-gradient(315deg, #FF6A69 2%, #FF6A69 99%);
+		border-radius: 8rpx;
+		box-shadow: 0px 0px 8rpx 0px rgba(51, 135, 255, 0.20);
+		text-align: center;
+		line-height: 100rpx;
+		color: #fff;
+		font-size: 36rpx;
+		font-weight: bold;
+		margin: 0 auto;
+		margin-top: 30px;
+	}
+
+	.checklist-box {
+		display: -webkit-box;
+		display: -webkit-flex;
+		display: flex;
+		-webkit-box-orient: horizontal;
+		-webkit-box-direction: normal;
+		-webkit-flex-direction: row;
+		flex-direction: row;
+		-webkit-box-align: center;
+		-webkit-align-items: center;
+		align-items: center;
+		margin: 5px 0;
+		margin-right: 22px;
+	}
+
+	.radio__inner {
+		-webkit-flex-shrink: 0;
+		flex-shrink: 0;
+
+		display: -webkit-box;
+		display: -webkit-flex;
+		display: flex;
+
+		-webkit-box-pack: center;
+		-webkit-justify-content: center;
+		justify-content: center;
+		-webkit-box-align: center;
+		-webkit-align-items: center;
+		align-items: center;
+		position: relative;
+		border: 1px solid #DCDFE6;
+		border-radius: 2px;
+		box-sizing: border-box;
+		width: 16px;
+		height: 16px;
+		border-radius: 16px;
+		background-color: #fff;
+		z-index: 1;
+		-webkit-transition: border-color .3s;
+		transition: border-color .3s;
+	}
+
+	.radio__inner-icon {
+		width: 8px;
+		height: 8px;
+		border-radius: 10px;
+		opacity: 0;
+		-webkit-transition: -webkit-transform .3s;
+		transition: -webkit-transform .3s;
+		transition: transform .3s;
+		transition: transform .3s, -webkit-transform .3s;
+	}
+
+	.is-default-checked {
+		opacity: 1;
+		background-color: #FF6A69;
+		-webkit-transform: rotate(45deg) scaleY(1);
+		transform: rotate(45deg) scaleY(1);
+	}
+
+	.act_border {
+		border: 1rpx solid #FF6A69;
+	}
+
+	.checklist-text {
+		font-size: 28rpx;
+		margin-left: 5px;
+		-webkit-transition: color 0.2s;
+		transition: color 0.2s;
+		color: #000;
+	}
+</style>

+ 175 - 0
appletXcx/WechatShop/index.vue

@@ -0,0 +1,175 @@
+<template>
+	<view class="content">
+		<view class="header">
+			<view class="info-block flex-y-center">
+				<view class="info">
+					<view class="title">微信小商店</view>
+					<view class="desc">手机管理方便又快捷</view>
+				</view>
+			</view>
+		</view>
+
+		<view class="content-row">
+			<view class="setup flex-y-center ft32">
+				常用应用
+			</view>
+
+			<view class="table">
+
+				<view class="table-tr">
+
+					<navigator class="table-td" url="./getShop">
+						<view class="iconfont iconzhuce"></view>
+						<view class="">注册小商店账号</view>
+					</navigator>
+
+					<navigator class="table-td" url="./qrCode">
+						<view class="iconfont iconweixin"></view>
+						<view class="">微信授权</view>
+					</navigator>
+
+					<navigator class="table-td" url="./addPay">
+						<view class="iconfont iconpay-order"></view>
+						<view class="">提交支付资质</view>
+					</navigator>
+
+					<navigator class="table-td" url="./basics">
+						<view class="iconfont iconjichuxinxi"></view>
+						<view class="">小商店基础信息</view>
+					</navigator>
+
+
+
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+	export default {
+		data() {
+			return {
+				is_admin: 1
+			}
+		},
+
+		onLoad(e) {
+			this.is_admin = e.is_admin || 1;
+		},
+
+		methods: {
+
+
+		}
+	}
+</script>
+
+<style>
+	.setup {
+		width: 100%;
+		height: 90rpx;
+
+		opacity: 1;
+		padding: 0 22rpx;
+	}
+
+	.table,
+	.table div {
+		margin: 0 auto;
+	}
+
+	.table {
+		/* display: table; */
+		width: 100%;
+		border-collapse: collapse;
+		box-sizing: border-box;
+	}
+
+	.table-tr {
+		/* display: table-row; */
+		/* height: 92rpx; */
+	}
+
+	.table-th {
+		display: table-cell;
+		font-weight: bold;
+		border: 1rpx solid #FAFAFA;
+		text-align: center;
+		vertical-align: middle;
+	}
+
+	.table-td {
+		display: inline-block;
+		border: 1rpx solid #FAFAFA;
+		text-align: center;
+		vertical-align: middle;
+		background: #fff;
+		font-size: 27rpx;
+		color: #666666;
+		padding: 62rpx 0;
+		width: 33.333%;
+	}
+
+	.table-td image {
+		width: 50rpx;
+		height: 50rpx;
+		margin-bottom: 23rpx;
+	}
+
+	.header {
+		width: 100%;
+		height: 198rpx;
+		position: relative;
+	}
+
+	.header .bg-img {
+		display: block;
+		position: absolute;
+		left: 0;
+		top: 0;
+		z-index: 1;
+		width: 100%;
+		height: 198rpx;
+	}
+
+	.header .info-block {
+		padding: 0 40rpx 0 48rpx;
+		height: 198rpx;
+		position: relative;
+		z-index: 2;
+		background: #FF6A69;
+	}
+
+	.header .info-block .title {
+		font-size: 36rpx;
+		color: #fff;
+		font-weight: 500;
+		line-height: 50rpx;
+	}
+
+	.header .info-block .desc {
+		font-size: 28rpx;
+		font-weight: 500;
+		color: #fff;
+		line-height: 40rpx;
+		margin-top: 8rpx;
+	}
+
+	.header .info-block .btn {
+		width: 170rpx;
+		height: 56rpx;
+		border-radius: 28rpx;
+		background-color: rgb(255, 255, 255);
+		text-align: center;
+		line-height: 52rpx;
+		font-size: 28rpx;
+		font-weight: 500;
+		color: #3387FF;
+	}
+
+	.table-td .iconfont {
+		font-size: 50rpx;
+		color: #FF6A69;
+		margin-bottom: 10rpx;
+	}
+</style>

+ 251 - 0
appletXcx/WechatShop/qrCode.vue

@@ -0,0 +1,251 @@
+<template>
+	<view class="content">
+		
+		<view class="step">
+			<uni-steps active-color="#FF6A69" :options="[
+			{title: '注册账号',url:'./getShop'},
+			{title: '扫码授权',url:'./qrCode'},
+			{title: '提交支付资质',url:'./addPay'}, 
+			{title: '基础信息',url:'./basics'} ]" :active="1"></uni-steps>
+		</view>
+		<view  style="height: 130rpx;"></view>
+		
+		<view class="hg72"></view>
+		<view class="home-content">
+			<view class="home-content-title flex-center">
+				微信授权二维码
+			</view>
+			<view class="home-content-code flex-center">
+				<view class="">
+					<tki-qrcode v-if="ifShow" cid="qrcode1" ref="qrcode" :val="qrcodeVal" :size="size" :unit="unit"
+						:background="background" :foreground="foreground" :pdground="pdground" :icon="icon"
+						:iconSize="iconsize" :lv="lv" :onval="onval" :loadMake="loadMake" :usingComponents="true"
+						@result="qrR" />
+				</view>
+			</view>
+		</view>
+		
+		<view class="bottom-bar" style="background: none;">
+			<button @click="upCode">
+				下载二维码
+			</button>
+		</view>
+		
+	</view>
+</template>
+
+<script>
+	// #ifdef MP-WEIXIN
+	import saveImgToPhotosAlbum from "@/static/js/saveImgToPhotosAlbum.js";
+	// #endif
+	import tkiQrcode from "../components/tki-qrcode/tki-qrcode.vue"
+	export default {
+		components: {
+			tkiQrcode,
+		},
+		data() {
+			return { //二维码相关参数
+				ifShow: true,
+				val: '二维码', // 要生成的二维码值
+				size: 350, // 二维码大小
+				unit: 'upx', // 单位
+				background: '#000000', // 背景色
+				foreground: '#ffffff', // 前景色
+				pdground: '#ffffff', // 角标色
+				icon: '', // 二维码图标
+				iconsize: 40, // 二维码图标大小
+				lv: 3, // 二维码容错级别 , 一般不用设置,默认就行
+				onval: false, // val值变化时自动重新生成二维码
+				loadMake: true, // 组件加载完成后自动生成二维码
+				src: '', // 二维码生成后的图片地址或base64
+
+				info: {},
+				id: "",
+				URL: getApp().globalData.URL,
+				qrcodeVal: "",
+				wxqr: 1,
+				qrcodeImg:'',
+			}
+		},
+		
+		onLoad(e) {
+			this.https();
+		},
+
+		methods: { //传入组件的方法
+			qrR(e) {
+				this.qrcodeImg=e;
+				console.log(e, "ee")
+			},
+			https() {
+				this.request({
+					url: 'Wechatstore/index',
+					data: {
+						admin_id: uni.getStorageSync("admin_id"),
+					},
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code === "200") {
+						this.qrcodeVal = res.data;
+						setTimeout(()=>{
+							this.$refs.qrcode._makeCode()
+						},50)
+						
+					}
+				});
+			},
+			
+			upCode(e) {
+				// #ifdef H5
+				uni.showModal({
+					title: '提示',
+					content: '请长按二维码图片进行保存',
+					showCancel: false,
+					confirmText: '好的',
+				});
+				// #endif
+				// #ifdef MP-WEIXIN 
+				this.$refs.qrcode._saveCode()
+				
+				return
+				
+				var url = this.qrcodeImg;
+				console.log(url, "url")
+				saveImgToPhotosAlbum.saveImgToPhotosAlbum(url).then((res) => {
+					//成功的逻辑
+					console.log(res, "保存成功")
+					uni.showToast({
+						title: '保存成功',
+						icon: 'none',
+						mask: true,
+					})
+				}).catch((err) => {
+					console.log(err, "保存失败")
+					if (err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" ||
+						err.errMsg === "saveImageToPhotosAlbum:fail auth deny" || err.errMsg ===
+						"saveImageToPhotosAlbum:fail authorize no response") {
+						// 这边微信做过调整,必须要在按钮中触发,因此需要在弹框回调中进行调用
+						uni.showModal({
+							title: '提示',
+							content: '需要您设置授权保存相册',
+							showCancel: false,
+							success: modalSuccess => {
+								uni.openSetting({
+									success(settingdata) {
+										console.log("settingdata", settingdata)
+										if (settingdata.authSetting[
+												'scope.writePhotosAlbum']) {
+											uni.showModal({
+												title: '提示',
+												content: '获取权限成功,再次点击图片即可保存',
+												showCancel: false,
+											})
+										} else {
+											uni.showModal({
+												title: '提示',
+												content: '获取权限失败,将无法保存到相册哦~',
+												showCancel: false,
+											})
+										}
+									},
+									fail(failData) {
+										console.log("failData", failData)
+									},
+									complete(finishData) {
+										console.log("finishData", finishData)
+									}
+								})
+
+							}
+						})
+					}
+					// 失败后的逻辑
+				})
+				// #endif			
+			},
+		}
+	}
+</script>
+
+<style>
+	page {
+		background: #F5F7FA;
+	}
+
+	.hg72 {
+		height: 72rpx;
+	}
+
+	.home-content {
+		background: #FFFFFF;
+		width: 670rpx;
+		height: 843rpx;
+		margin: 0 auto;
+		position: relative;
+
+	}
+
+	.home-content-title {
+		width: 100%;
+		height: 154rpx;
+		background: linear-gradient(180deg, #FF6A69, #FF6A69);
+		border-radius: 16rpx 16rpx 0px 0px;
+		font-size: 36rpx;
+		font-family: PingFang SC, PingFang SC-Medium;
+		font-weight: 500;
+		color: #ffffff;
+	}
+
+	.home-content-code {
+		width: 100%;
+		height: 689rpx;
+		font-size: 32rpx;
+		font-family: PingFang SC, PingFang SC-Regular;
+		font-weight: 400;
+		color: #464646;
+		text-align: center;
+	}
+
+	.home-content-code image {
+		width: 400rpx;
+		height: 400rpx;
+		margin-bottom: 64rpx;
+	}
+
+	.home-content-code-title {
+		padding: 0 30rpx;
+		color: red;
+	}
+
+	.code-btn {
+		font-size: 32rpx;
+		font-family: PingFang SC, PingFang SC-Regular;
+		font-weight: 400;
+		color: #3c8cff;
+		margin-bottom: 35rpx;
+	}
+
+	.bottom-bar {
+		position: fixed;
+		/* bottom: 50rpx; */
+		width: 100%;
+		z-index: 1000;
+		padding: 30rpx 0;
+
+	}
+
+	.bottom-bar button {
+		text-align: center;
+		width: 690rpx;
+		height: 90rpx;
+		background: linear-gradient(132deg, #FF6A69 0%, #FF6A69 100%);
+		box-shadow: 0px 2rpx 12rpx #FF6A69;
+		opacity: 1;
+		border-radius: 10rpx;
+		color: #fff;
+		font-size: 32rpx;
+		font-family: Source Han Sans CN, Source Han Sans CN-Medium;
+		font-weight: 500;
+		color: #ffffff;
+	}
+</style>

+ 1201 - 0
appletXcx/components/tki-qrcode/qrcode.js

@@ -0,0 +1,1201 @@
+let QRCode = {};
+(function () {
+    /**
+     * 获取单个字符的utf8编码
+     * unicode BMP平面约65535个字符
+     * @param {num} code
+     * return {array}
+     */
+    function unicodeFormat8(code) {
+        // 1 byte
+        var c0, c1, c2;
+        if (code < 128) {
+            return [code];
+            // 2 bytes
+        } else if (code < 2048) {
+            c0 = 192 + (code >> 6);
+            c1 = 128 + (code & 63);
+            return [c0, c1];
+            // 3 bytes
+        } else {
+            c0 = 224 + (code >> 12);
+            c1 = 128 + (code >> 6 & 63);
+            c2 = 128 + (code & 63);
+            return [c0, c1, c2];
+        }
+    }
+    /**
+     * 获取字符串的utf8编码字节串
+     * @param {string} string
+     * @return {array}
+     */
+    function getUTF8Bytes(string) {
+        var utf8codes = [];
+        for (var i = 0; i < string.length; i++) {
+            var code = string.charCodeAt(i);
+            var utf8 = unicodeFormat8(code);
+            for (var j = 0; j < utf8.length; j++) {
+                utf8codes.push(utf8[j]);
+            }
+        }
+        return utf8codes;
+    }
+    /**
+     * 二维码算法实现
+     * @param {string} data              要编码的信息字符串
+     * @param {num} errorCorrectLevel 纠错等级
+     */
+    function QRCodeAlg(data, errorCorrectLevel) {
+        this.typeNumber = -1; //版本
+        this.errorCorrectLevel = errorCorrectLevel;
+        this.modules = null; //二维矩阵,存放最终结果
+        this.moduleCount = 0; //矩阵大小
+        this.dataCache = null; //数据缓存
+        this.rsBlocks = null; //版本数据信息
+        this.totalDataCount = -1; //可使用的数据量
+        this.data = data;
+        this.utf8bytes = getUTF8Bytes(data);
+        this.make();
+    }
+    QRCodeAlg.prototype = {
+        constructor: QRCodeAlg,
+        /**
+         * 获取二维码矩阵大小
+         * @return {num} 矩阵大小
+         */
+        getModuleCount: function () {
+            return this.moduleCount;
+        },
+        /**
+         * 编码
+         */
+        make: function () {
+            this.getRightType();
+            this.dataCache = this.createData();
+            this.createQrcode();
+        },
+        /**
+         * 设置二位矩阵功能图形
+         * @param  {bool} test 表示是否在寻找最好掩膜阶段
+         * @param  {num} maskPattern 掩膜的版本
+         */
+        makeImpl: function (maskPattern) {
+            this.moduleCount = this.typeNumber * 4 + 17;
+            this.modules = new Array(this.moduleCount);
+            for (var row = 0; row < this.moduleCount; row++) {
+                this.modules[row] = new Array(this.moduleCount);
+            }
+            this.setupPositionProbePattern(0, 0);
+            this.setupPositionProbePattern(this.moduleCount - 7, 0);
+            this.setupPositionProbePattern(0, this.moduleCount - 7);
+            this.setupPositionAdjustPattern();
+            this.setupTimingPattern();
+            this.setupTypeInfo(true, maskPattern);
+            if (this.typeNumber >= 7) {
+                this.setupTypeNumber(true);
+            }
+            this.mapData(this.dataCache, maskPattern);
+        },
+        /**
+         * 设置二维码的位置探测图形
+         * @param  {num} row 探测图形的中心横坐标
+         * @param  {num} col 探测图形的中心纵坐标
+         */
+        setupPositionProbePattern: function (row, col) {
+            for (var r = -1; r <= 7; r++) {
+                if (row + r <= -1 || this.moduleCount <= row + r) continue;
+                for (var c = -1; c <= 7; c++) {
+                    if (col + c <= -1 || this.moduleCount <= col + c) continue;
+                    if ((0 <= r && r <= 6 && (c == 0 || c == 6)) || (0 <= c && c <= 6 && (r == 0 || r == 6)) || (2 <= r && r <= 4 && 2 <= c && c <= 4)) {
+                        this.modules[row + r][col + c] = true;
+                    } else {
+                        this.modules[row + r][col + c] = false;
+                    }
+                }
+            }
+        },
+        /**
+         * 创建二维码
+         * @return {[type]} [description]
+         */
+        createQrcode: function () {
+            var minLostPoint = 0;
+            var pattern = 0;
+            var bestModules = null;
+            for (var i = 0; i < 8; i++) {
+                this.makeImpl(i);
+                var lostPoint = QRUtil.getLostPoint(this);
+                if (i == 0 || minLostPoint > lostPoint) {
+                    minLostPoint = lostPoint;
+                    pattern = i;
+                    bestModules = this.modules;
+                }
+            }
+            this.modules = bestModules;
+            this.setupTypeInfo(false, pattern);
+            if (this.typeNumber >= 7) {
+                this.setupTypeNumber(false);
+            }
+        },
+        /**
+         * 设置定位图形
+         * @return {[type]} [description]
+         */
+        setupTimingPattern: function () {
+            for (var r = 8; r < this.moduleCount - 8; r++) {
+                if (this.modules[r][6] != null) {
+                    continue;
+                }
+                this.modules[r][6] = (r % 2 == 0);
+                if (this.modules[6][r] != null) {
+                    continue;
+                }
+                this.modules[6][r] = (r % 2 == 0);
+            }
+        },
+        /**
+         * 设置矫正图形
+         * @return {[type]} [description]
+         */
+        setupPositionAdjustPattern: function () {
+            var pos = QRUtil.getPatternPosition(this.typeNumber);
+            for (var i = 0; i < pos.length; i++) {
+                for (var j = 0; j < pos.length; j++) {
+                    var row = pos[i];
+                    var col = pos[j];
+                    if (this.modules[row][col] != null) {
+                        continue;
+                    }
+                    for (var r = -2; r <= 2; r++) {
+                        for (var c = -2; c <= 2; c++) {
+                            if (r == -2 || r == 2 || c == -2 || c == 2 || (r == 0 && c == 0)) {
+                                this.modules[row + r][col + c] = true;
+                            } else {
+                                this.modules[row + r][col + c] = false;
+                            }
+                        }
+                    }
+                }
+            }
+        },
+        /**
+         * 设置版本信息(7以上版本才有)
+         * @param  {bool} test 是否处于判断最佳掩膜阶段
+         * @return {[type]}      [description]
+         */
+        setupTypeNumber: function (test) {
+            var bits = QRUtil.getBCHTypeNumber(this.typeNumber);
+            for (var i = 0; i < 18; i++) {
+                var mod = (!test && ((bits >> i) & 1) == 1);
+                this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod;
+                this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
+            }
+        },
+        /**
+         * 设置格式信息(纠错等级和掩膜版本)
+         * @param  {bool} test
+         * @param  {num} maskPattern 掩膜版本
+         * @return {}
+         */
+        setupTypeInfo: function (test, maskPattern) {
+            var data = (QRErrorCorrectLevel[this.errorCorrectLevel] << 3) | maskPattern;
+            var bits = QRUtil.getBCHTypeInfo(data);
+            // vertical
+            for (var i = 0; i < 15; i++) {
+                var mod = (!test && ((bits >> i) & 1) == 1);
+                if (i < 6) {
+                    this.modules[i][8] = mod;
+                } else if (i < 8) {
+                    this.modules[i + 1][8] = mod;
+                } else {
+                    this.modules[this.moduleCount - 15 + i][8] = mod;
+                }
+                // horizontal
+                var mod = (!test && ((bits >> i) & 1) == 1);
+                if (i < 8) {
+                    this.modules[8][this.moduleCount - i - 1] = mod;
+                } else if (i < 9) {
+                    this.modules[8][15 - i - 1 + 1] = mod;
+                } else {
+                    this.modules[8][15 - i - 1] = mod;
+                }
+            }
+            // fixed module
+            this.modules[this.moduleCount - 8][8] = (!test);
+        },
+        /**
+         * 数据编码
+         * @return {[type]} [description]
+         */
+        createData: function () {
+            var buffer = new QRBitBuffer();
+            var lengthBits = this.typeNumber > 9 ? 16 : 8;
+            buffer.put(4, 4); //添加模式
+            buffer.put(this.utf8bytes.length, lengthBits);
+            for (var i = 0, l = this.utf8bytes.length; i < l; i++) {
+                buffer.put(this.utf8bytes[i], 8);
+            }
+            if (buffer.length + 4 <= this.totalDataCount * 8) {
+                buffer.put(0, 4);
+            }
+            // padding
+            while (buffer.length % 8 != 0) {
+                buffer.putBit(false);
+            }
+            // padding
+            while (true) {
+                if (buffer.length >= this.totalDataCount * 8) {
+                    break;
+                }
+                buffer.put(QRCodeAlg.PAD0, 8);
+                if (buffer.length >= this.totalDataCount * 8) {
+                    break;
+                }
+                buffer.put(QRCodeAlg.PAD1, 8);
+            }
+            return this.createBytes(buffer);
+        },
+        /**
+         * 纠错码编码
+         * @param  {buffer} buffer 数据编码
+         * @return {[type]}
+         */
+        createBytes: function (buffer) {
+            var offset = 0;
+            var maxDcCount = 0;
+            var maxEcCount = 0;
+            var length = this.rsBlock.length / 3;
+            var rsBlocks = new Array();
+            for (var i = 0; i < length; i++) {
+                var count = this.rsBlock[i * 3 + 0];
+                var totalCount = this.rsBlock[i * 3 + 1];
+                var dataCount = this.rsBlock[i * 3 + 2];
+                for (var j = 0; j < count; j++) {
+                    rsBlocks.push([dataCount, totalCount]);
+                }
+            }
+            var dcdata = new Array(rsBlocks.length);
+            var ecdata = new Array(rsBlocks.length);
+            for (var r = 0; r < rsBlocks.length; r++) {
+                var dcCount = rsBlocks[r][0];
+                var ecCount = rsBlocks[r][1] - dcCount;
+                maxDcCount = Math.max(maxDcCount, dcCount);
+                maxEcCount = Math.max(maxEcCount, ecCount);
+                dcdata[r] = new Array(dcCount);
+                for (var i = 0; i < dcdata[r].length; i++) {
+                    dcdata[r][i] = 0xff & buffer.buffer[i + offset];
+                }
+                offset += dcCount;
+                var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
+                var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1);
+                var modPoly = rawPoly.mod(rsPoly);
+                ecdata[r] = new Array(rsPoly.getLength() - 1);
+                for (var i = 0; i < ecdata[r].length; i++) {
+                    var modIndex = i + modPoly.getLength() - ecdata[r].length;
+                    ecdata[r][i] = (modIndex >= 0) ? modPoly.get(modIndex) : 0;
+                }
+            }
+            var data = new Array(this.totalDataCount);
+            var index = 0;
+            for (var i = 0; i < maxDcCount; i++) {
+                for (var r = 0; r < rsBlocks.length; r++) {
+                    if (i < dcdata[r].length) {
+                        data[index++] = dcdata[r][i];
+                    }
+                }
+            }
+            for (var i = 0; i < maxEcCount; i++) {
+                for (var r = 0; r < rsBlocks.length; r++) {
+                    if (i < ecdata[r].length) {
+                        data[index++] = ecdata[r][i];
+                    }
+                }
+            }
+            return data;
+
+        },
+        /**
+         * 布置模块,构建最终信息
+         * @param  {} data
+         * @param  {} maskPattern
+         * @return {}
+         */
+        mapData: function (data, maskPattern) {
+            var inc = -1;
+            var row = this.moduleCount - 1;
+            var bitIndex = 7;
+            var byteIndex = 0;
+            for (var col = this.moduleCount - 1; col > 0; col -= 2) {
+                if (col == 6) col--;
+                while (true) {
+                    for (var c = 0; c < 2; c++) {
+                        if (this.modules[row][col - c] == null) {
+                            var dark = false;
+                            if (byteIndex < data.length) {
+                                dark = (((data[byteIndex] >>> bitIndex) & 1) == 1);
+                            }
+                            var mask = QRUtil.getMask(maskPattern, row, col - c);
+                            if (mask) {
+                                dark = !dark;
+                            }
+                            this.modules[row][col - c] = dark;
+                            bitIndex--;
+                            if (bitIndex == -1) {
+                                byteIndex++;
+                                bitIndex = 7;
+                            }
+                        }
+                    }
+                    row += inc;
+                    if (row < 0 || this.moduleCount <= row) {
+                        row -= inc;
+                        inc = -inc;
+                        break;
+                    }
+                }
+            }
+        }
+    };
+    /**
+     * 填充字段
+     */
+    QRCodeAlg.PAD0 = 0xEC;
+    QRCodeAlg.PAD1 = 0x11;
+    //---------------------------------------------------------------------
+    // 纠错等级对应的编码
+    //---------------------------------------------------------------------
+    var QRErrorCorrectLevel = [1, 0, 3, 2];
+    //---------------------------------------------------------------------
+    // 掩膜版本
+    //---------------------------------------------------------------------
+    var QRMaskPattern = {
+        PATTERN000: 0,
+        PATTERN001: 1,
+        PATTERN010: 2,
+        PATTERN011: 3,
+        PATTERN100: 4,
+        PATTERN101: 5,
+        PATTERN110: 6,
+        PATTERN111: 7
+    };
+    //---------------------------------------------------------------------
+    // 工具类
+    //---------------------------------------------------------------------
+    var QRUtil = {
+        /*
+        每个版本矫正图形的位置
+         */
+        PATTERN_POSITION_TABLE: [
+            [],
+            [6, 18],
+            [6, 22],
+            [6, 26],
+            [6, 30],
+            [6, 34],
+            [6, 22, 38],
+            [6, 24, 42],
+            [6, 26, 46],
+            [6, 28, 50],
+            [6, 30, 54],
+            [6, 32, 58],
+            [6, 34, 62],
+            [6, 26, 46, 66],
+            [6, 26, 48, 70],
+            [6, 26, 50, 74],
+            [6, 30, 54, 78],
+            [6, 30, 56, 82],
+            [6, 30, 58, 86],
+            [6, 34, 62, 90],
+            [6, 28, 50, 72, 94],
+            [6, 26, 50, 74, 98],
+            [6, 30, 54, 78, 102],
+            [6, 28, 54, 80, 106],
+            [6, 32, 58, 84, 110],
+            [6, 30, 58, 86, 114],
+            [6, 34, 62, 90, 118],
+            [6, 26, 50, 74, 98, 122],
+            [6, 30, 54, 78, 102, 126],
+            [6, 26, 52, 78, 104, 130],
+            [6, 30, 56, 82, 108, 134],
+            [6, 34, 60, 86, 112, 138],
+            [6, 30, 58, 86, 114, 142],
+            [6, 34, 62, 90, 118, 146],
+            [6, 30, 54, 78, 102, 126, 150],
+            [6, 24, 50, 76, 102, 128, 154],
+            [6, 28, 54, 80, 106, 132, 158],
+            [6, 32, 58, 84, 110, 136, 162],
+            [6, 26, 54, 82, 110, 138, 166],
+            [6, 30, 58, 86, 114, 142, 170]
+        ],
+        G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
+        G18: (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),
+        G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
+        /*
+        BCH编码格式信息
+         */
+        getBCHTypeInfo: function (data) {
+            var d = data << 10;
+            while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
+                d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15)));
+            }
+            return ((data << 10) | d) ^ QRUtil.G15_MASK;
+        },
+        /*
+        BCH编码版本信息
+         */
+        getBCHTypeNumber: function (data) {
+            var d = data << 12;
+            while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
+                d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18)));
+            }
+            return (data << 12) | d;
+        },
+        /*
+        获取BCH位信息
+         */
+        getBCHDigit: function (data) {
+            var digit = 0;
+            while (data != 0) {
+                digit++;
+                data >>>= 1;
+            }
+            return digit;
+        },
+        /*
+        获取版本对应的矫正图形位置
+         */
+        getPatternPosition: function (typeNumber) {
+            return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];
+        },
+        /*
+        掩膜算法
+         */
+        getMask: function (maskPattern, i, j) {
+            switch (maskPattern) {
+                case QRMaskPattern.PATTERN000:
+                    return (i + j) % 2 == 0;
+                case QRMaskPattern.PATTERN001:
+                    return i % 2 == 0;
+                case QRMaskPattern.PATTERN010:
+                    return j % 3 == 0;
+                case QRMaskPattern.PATTERN011:
+                    return (i + j) % 3 == 0;
+                case QRMaskPattern.PATTERN100:
+                    return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0;
+                case QRMaskPattern.PATTERN101:
+                    return (i * j) % 2 + (i * j) % 3 == 0;
+                case QRMaskPattern.PATTERN110:
+                    return ((i * j) % 2 + (i * j) % 3) % 2 == 0;
+                case QRMaskPattern.PATTERN111:
+                    return ((i * j) % 3 + (i + j) % 2) % 2 == 0;
+                default:
+                    throw new Error("bad maskPattern:" + maskPattern);
+            }
+        },
+        /*
+        获取RS的纠错多项式
+         */
+        getErrorCorrectPolynomial: function (errorCorrectLength) {
+            var a = new QRPolynomial([1], 0);
+            for (var i = 0; i < errorCorrectLength; i++) {
+                a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0));
+            }
+            return a;
+        },
+        /*
+        获取评价
+         */
+        getLostPoint: function (qrCode) {
+            var moduleCount = qrCode.getModuleCount(),
+                lostPoint = 0,
+                darkCount = 0;
+            for (var row = 0; row < moduleCount; row++) {
+                var sameCount = 0;
+                var head = qrCode.modules[row][0];
+                for (var col = 0; col < moduleCount; col++) {
+                    var current = qrCode.modules[row][col];
+                    //level 3 评价
+                    if (col < moduleCount - 6) {
+                        if (current && !qrCode.modules[row][col + 1] && qrCode.modules[row][col + 2] && qrCode.modules[row][col + 3] && qrCode.modules[row][col + 4] && !qrCode.modules[row][col + 5] && qrCode.modules[row][col + 6]) {
+                            if (col < moduleCount - 10) {
+                                if (qrCode.modules[row][col + 7] && qrCode.modules[row][col + 8] && qrCode.modules[row][col + 9] && qrCode.modules[row][col + 10]) {
+                                    lostPoint += 40;
+                                }
+                            } else if (col > 3) {
+                                if (qrCode.modules[row][col - 1] && qrCode.modules[row][col - 2] && qrCode.modules[row][col - 3] && qrCode.modules[row][col - 4]) {
+                                    lostPoint += 40;
+                                }
+                            }
+                        }
+                    }
+                    //level 2 评价
+                    if ((row < moduleCount - 1) && (col < moduleCount - 1)) {
+                        var count = 0;
+                        if (current) count++;
+                        if (qrCode.modules[row + 1][col]) count++;
+                        if (qrCode.modules[row][col + 1]) count++;
+                        if (qrCode.modules[row + 1][col + 1]) count++;
+                        if (count == 0 || count == 4) {
+                            lostPoint += 3;
+                        }
+                    }
+                    //level 1 评价
+                    if (head ^ current) {
+                        sameCount++;
+                    } else {
+                        head = current;
+                        if (sameCount >= 5) {
+                            lostPoint += (3 + sameCount - 5);
+                        }
+                        sameCount = 1;
+                    }
+                    //level 4 评价
+                    if (current) {
+                        darkCount++;
+                    }
+                }
+            }
+            for (var col = 0; col < moduleCount; col++) {
+                var sameCount = 0;
+                var head = qrCode.modules[0][col];
+                for (var row = 0; row < moduleCount; row++) {
+                    var current = qrCode.modules[row][col];
+                    //level 3 评价
+                    if (row < moduleCount - 6) {
+                        if (current && !qrCode.modules[row + 1][col] && qrCode.modules[row + 2][col] && qrCode.modules[row + 3][col] && qrCode.modules[row + 4][col] && !qrCode.modules[row + 5][col] && qrCode.modules[row + 6][col]) {
+                            if (row < moduleCount - 10) {
+                                if (qrCode.modules[row + 7][col] && qrCode.modules[row + 8][col] && qrCode.modules[row + 9][col] && qrCode.modules[row + 10][col]) {
+                                    lostPoint += 40;
+                                }
+                            } else if (row > 3) {
+                                if (qrCode.modules[row - 1][col] && qrCode.modules[row - 2][col] && qrCode.modules[row - 3][col] && qrCode.modules[row - 4][col]) {
+                                    lostPoint += 40;
+                                }
+                            }
+                        }
+                    }
+                    //level 1 评价
+                    if (head ^ current) {
+                        sameCount++;
+                    } else {
+                        head = current;
+                        if (sameCount >= 5) {
+                            lostPoint += (3 + sameCount - 5);
+                        }
+                        sameCount = 1;
+                    }
+                }
+            }
+            // LEVEL4
+            var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
+            lostPoint += ratio * 10;
+            return lostPoint;
+        }
+
+    };
+    //---------------------------------------------------------------------
+    // QRMath使用的数学工具
+    //---------------------------------------------------------------------
+    var QRMath = {
+        /*
+        将n转化为a^m
+         */
+        glog: function (n) {
+            if (n < 1) {
+                throw new Error("glog(" + n + ")");
+            }
+            return QRMath.LOG_TABLE[n];
+        },
+        /*
+        将a^m转化为n
+         */
+        gexp: function (n) {
+            while (n < 0) {
+                n += 255;
+            }
+            while (n >= 256) {
+                n -= 255;
+            }
+            return QRMath.EXP_TABLE[n];
+        },
+        EXP_TABLE: new Array(256),
+        LOG_TABLE: new Array(256)
+
+    };
+    for (var i = 0; i < 8; i++) {
+        QRMath.EXP_TABLE[i] = 1 << i;
+    }
+    for (var i = 8; i < 256; i++) {
+        QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] ^ QRMath.EXP_TABLE[i - 5] ^ QRMath.EXP_TABLE[i - 6] ^ QRMath.EXP_TABLE[i - 8];
+    }
+    for (var i = 0; i < 255; i++) {
+        QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i;
+    }
+    //---------------------------------------------------------------------
+    // QRPolynomial 多项式
+    //---------------------------------------------------------------------
+    /**
+     * 多项式类
+     * @param {Array} num   系数
+     * @param {num} shift a^shift
+     */
+    function QRPolynomial(num, shift) {
+        if (num.length == undefined) {
+            throw new Error(num.length + "/" + shift);
+        }
+        var offset = 0;
+        while (offset < num.length && num[offset] == 0) {
+            offset++;
+        }
+        this.num = new Array(num.length - offset + shift);
+        for (var i = 0; i < num.length - offset; i++) {
+            this.num[i] = num[i + offset];
+        }
+    }
+    QRPolynomial.prototype = {
+        get: function (index) {
+            return this.num[index];
+        },
+        getLength: function () {
+            return this.num.length;
+        },
+        /**
+         * 多项式乘法
+         * @param  {QRPolynomial} e 被乘多项式
+         * @return {[type]}   [description]
+         */
+        multiply: function (e) {
+            var num = new Array(this.getLength() + e.getLength() - 1);
+            for (var i = 0; i < this.getLength(); i++) {
+                for (var j = 0; j < e.getLength(); j++) {
+                    num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j)));
+                }
+            }
+            return new QRPolynomial(num, 0);
+        },
+        /**
+         * 多项式模运算
+         * @param  {QRPolynomial} e 模多项式
+         * @return {}
+         */
+        mod: function (e) {
+            var tl = this.getLength(),
+                el = e.getLength();
+            if (tl - el < 0) {
+                return this;
+            }
+            var num = new Array(tl);
+            for (var i = 0; i < tl; i++) {
+                num[i] = this.get(i);
+            }
+            while (num.length >= el) {
+                var ratio = QRMath.glog(num[0]) - QRMath.glog(e.get(0));
+
+                for (var i = 0; i < e.getLength(); i++) {
+                    num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio);
+                }
+                while (num[0] == 0) {
+                    num.shift();
+                }
+            }
+            return new QRPolynomial(num, 0);
+        }
+    };
+
+    //---------------------------------------------------------------------
+    // RS_BLOCK_TABLE
+    //---------------------------------------------------------------------
+    /*
+    二维码各个版本信息[块数, 每块中的数据块数, 每块中的信息块数]
+     */
+    var RS_BLOCK_TABLE = [
+        // L
+        // M
+        // Q
+        // H
+        // 1
+        [1, 26, 19],
+        [1, 26, 16],
+        [1, 26, 13],
+        [1, 26, 9],
+
+        // 2
+        [1, 44, 34],
+        [1, 44, 28],
+        [1, 44, 22],
+        [1, 44, 16],
+
+        // 3
+        [1, 70, 55],
+        [1, 70, 44],
+        [2, 35, 17],
+        [2, 35, 13],
+
+        // 4
+        [1, 100, 80],
+        [2, 50, 32],
+        [2, 50, 24],
+        [4, 25, 9],
+
+        // 5
+        [1, 134, 108],
+        [2, 67, 43],
+        [2, 33, 15, 2, 34, 16],
+        [2, 33, 11, 2, 34, 12],
+
+        // 6
+        [2, 86, 68],
+        [4, 43, 27],
+        [4, 43, 19],
+        [4, 43, 15],
+
+        // 7
+        [2, 98, 78],
+        [4, 49, 31],
+        [2, 32, 14, 4, 33, 15],
+        [4, 39, 13, 1, 40, 14],
+
+        // 8
+        [2, 121, 97],
+        [2, 60, 38, 2, 61, 39],
+        [4, 40, 18, 2, 41, 19],
+        [4, 40, 14, 2, 41, 15],
+
+        // 9
+        [2, 146, 116],
+        [3, 58, 36, 2, 59, 37],
+        [4, 36, 16, 4, 37, 17],
+        [4, 36, 12, 4, 37, 13],
+
+        // 10
+        [2, 86, 68, 2, 87, 69],
+        [4, 69, 43, 1, 70, 44],
+        [6, 43, 19, 2, 44, 20],
+        [6, 43, 15, 2, 44, 16],
+
+        // 11
+        [4, 101, 81],
+        [1, 80, 50, 4, 81, 51],
+        [4, 50, 22, 4, 51, 23],
+        [3, 36, 12, 8, 37, 13],
+
+        // 12
+        [2, 116, 92, 2, 117, 93],
+        [6, 58, 36, 2, 59, 37],
+        [4, 46, 20, 6, 47, 21],
+        [7, 42, 14, 4, 43, 15],
+
+        // 13
+        [4, 133, 107],
+        [8, 59, 37, 1, 60, 38],
+        [8, 44, 20, 4, 45, 21],
+        [12, 33, 11, 4, 34, 12],
+
+        // 14
+        [3, 145, 115, 1, 146, 116],
+        [4, 64, 40, 5, 65, 41],
+        [11, 36, 16, 5, 37, 17],
+        [11, 36, 12, 5, 37, 13],
+
+        // 15
+        [5, 109, 87, 1, 110, 88],
+        [5, 65, 41, 5, 66, 42],
+        [5, 54, 24, 7, 55, 25],
+        [11, 36, 12],
+
+        // 16
+        [5, 122, 98, 1, 123, 99],
+        [7, 73, 45, 3, 74, 46],
+        [15, 43, 19, 2, 44, 20],
+        [3, 45, 15, 13, 46, 16],
+
+        // 17
+        [1, 135, 107, 5, 136, 108],
+        [10, 74, 46, 1, 75, 47],
+        [1, 50, 22, 15, 51, 23],
+        [2, 42, 14, 17, 43, 15],
+
+        // 18
+        [5, 150, 120, 1, 151, 121],
+        [9, 69, 43, 4, 70, 44],
+        [17, 50, 22, 1, 51, 23],
+        [2, 42, 14, 19, 43, 15],
+
+        // 19
+        [3, 141, 113, 4, 142, 114],
+        [3, 70, 44, 11, 71, 45],
+        [17, 47, 21, 4, 48, 22],
+        [9, 39, 13, 16, 40, 14],
+
+        // 20
+        [3, 135, 107, 5, 136, 108],
+        [3, 67, 41, 13, 68, 42],
+        [15, 54, 24, 5, 55, 25],
+        [15, 43, 15, 10, 44, 16],
+
+        // 21
+        [4, 144, 116, 4, 145, 117],
+        [17, 68, 42],
+        [17, 50, 22, 6, 51, 23],
+        [19, 46, 16, 6, 47, 17],
+
+        // 22
+        [2, 139, 111, 7, 140, 112],
+        [17, 74, 46],
+        [7, 54, 24, 16, 55, 25],
+        [34, 37, 13],
+
+        // 23
+        [4, 151, 121, 5, 152, 122],
+        [4, 75, 47, 14, 76, 48],
+        [11, 54, 24, 14, 55, 25],
+        [16, 45, 15, 14, 46, 16],
+
+        // 24
+        [6, 147, 117, 4, 148, 118],
+        [6, 73, 45, 14, 74, 46],
+        [11, 54, 24, 16, 55, 25],
+        [30, 46, 16, 2, 47, 17],
+
+        // 25
+        [8, 132, 106, 4, 133, 107],
+        [8, 75, 47, 13, 76, 48],
+        [7, 54, 24, 22, 55, 25],
+        [22, 45, 15, 13, 46, 16],
+
+        // 26
+        [10, 142, 114, 2, 143, 115],
+        [19, 74, 46, 4, 75, 47],
+        [28, 50, 22, 6, 51, 23],
+        [33, 46, 16, 4, 47, 17],
+
+        // 27
+        [8, 152, 122, 4, 153, 123],
+        [22, 73, 45, 3, 74, 46],
+        [8, 53, 23, 26, 54, 24],
+        [12, 45, 15, 28, 46, 16],
+
+        // 28
+        [3, 147, 117, 10, 148, 118],
+        [3, 73, 45, 23, 74, 46],
+        [4, 54, 24, 31, 55, 25],
+        [11, 45, 15, 31, 46, 16],
+
+        // 29
+        [7, 146, 116, 7, 147, 117],
+        [21, 73, 45, 7, 74, 46],
+        [1, 53, 23, 37, 54, 24],
+        [19, 45, 15, 26, 46, 16],
+
+        // 30
+        [5, 145, 115, 10, 146, 116],
+        [19, 75, 47, 10, 76, 48],
+        [15, 54, 24, 25, 55, 25],
+        [23, 45, 15, 25, 46, 16],
+
+        // 31
+        [13, 145, 115, 3, 146, 116],
+        [2, 74, 46, 29, 75, 47],
+        [42, 54, 24, 1, 55, 25],
+        [23, 45, 15, 28, 46, 16],
+
+        // 32
+        [17, 145, 115],
+        [10, 74, 46, 23, 75, 47],
+        [10, 54, 24, 35, 55, 25],
+        [19, 45, 15, 35, 46, 16],
+
+        // 33
+        [17, 145, 115, 1, 146, 116],
+        [14, 74, 46, 21, 75, 47],
+        [29, 54, 24, 19, 55, 25],
+        [11, 45, 15, 46, 46, 16],
+
+        // 34
+        [13, 145, 115, 6, 146, 116],
+        [14, 74, 46, 23, 75, 47],
+        [44, 54, 24, 7, 55, 25],
+        [59, 46, 16, 1, 47, 17],
+
+        // 35
+        [12, 151, 121, 7, 152, 122],
+        [12, 75, 47, 26, 76, 48],
+        [39, 54, 24, 14, 55, 25],
+        [22, 45, 15, 41, 46, 16],
+
+        // 36
+        [6, 151, 121, 14, 152, 122],
+        [6, 75, 47, 34, 76, 48],
+        [46, 54, 24, 10, 55, 25],
+        [2, 45, 15, 64, 46, 16],
+
+        // 37
+        [17, 152, 122, 4, 153, 123],
+        [29, 74, 46, 14, 75, 47],
+        [49, 54, 24, 10, 55, 25],
+        [24, 45, 15, 46, 46, 16],
+
+        // 38
+        [4, 152, 122, 18, 153, 123],
+        [13, 74, 46, 32, 75, 47],
+        [48, 54, 24, 14, 55, 25],
+        [42, 45, 15, 32, 46, 16],
+
+        // 39
+        [20, 147, 117, 4, 148, 118],
+        [40, 75, 47, 7, 76, 48],
+        [43, 54, 24, 22, 55, 25],
+        [10, 45, 15, 67, 46, 16],
+
+        // 40
+        [19, 148, 118, 6, 149, 119],
+        [18, 75, 47, 31, 76, 48],
+        [34, 54, 24, 34, 55, 25],
+        [20, 45, 15, 61, 46, 16]
+    ];
+
+    /**
+     * 根据数据获取对应版本
+     * @return {[type]} [description]
+     */
+    QRCodeAlg.prototype.getRightType = function () {
+        for (var typeNumber = 1; typeNumber < 41; typeNumber++) {
+            var rsBlock = RS_BLOCK_TABLE[(typeNumber - 1) * 4 + this.errorCorrectLevel];
+            if (rsBlock == undefined) {
+                throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + this.errorCorrectLevel);
+            }
+            var length = rsBlock.length / 3;
+            var totalDataCount = 0;
+            for (var i = 0; i < length; i++) {
+                var count = rsBlock[i * 3 + 0];
+                var dataCount = rsBlock[i * 3 + 2];
+                totalDataCount += dataCount * count;
+            }
+            var lengthBytes = typeNumber > 9 ? 2 : 1;
+            if (this.utf8bytes.length + lengthBytes < totalDataCount || typeNumber == 40) {
+                this.typeNumber = typeNumber;
+                this.rsBlock = rsBlock;
+                this.totalDataCount = totalDataCount;
+                break;
+            }
+        }
+    };
+
+    //---------------------------------------------------------------------
+    // QRBitBuffer
+    //---------------------------------------------------------------------
+    function QRBitBuffer() {
+        this.buffer = new Array();
+        this.length = 0;
+    }
+    QRBitBuffer.prototype = {
+        get: function (index) {
+            var bufIndex = Math.floor(index / 8);
+            return ((this.buffer[bufIndex] >>> (7 - index % 8)) & 1);
+        },
+        put: function (num, length) {
+            for (var i = 0; i < length; i++) {
+                this.putBit(((num >>> (length - i - 1)) & 1));
+            }
+        },
+        putBit: function (bit) {
+            var bufIndex = Math.floor(this.length / 8);
+            if (this.buffer.length <= bufIndex) {
+                this.buffer.push(0);
+            }
+            if (bit) {
+                this.buffer[bufIndex] |= (0x80 >>> (this.length % 8));
+            }
+            this.length++;
+        }
+    };
+
+
+
+    // xzedit
+    let qrcodeAlgObjCache = [];
+    /**
+     * 二维码构造函数,主要用于绘制
+     * @param  {参数列表} opt 传递参数
+     * @return {}
+     */
+    QRCode = function (opt) {
+        //设置默认参数
+        this.options = {
+            text: '',
+            size: 256,
+            correctLevel: 3,
+            background: '#ffffff',
+            foreground: '#000000',
+            pdground: '#000000',
+            image: '',
+            imageSize: 30,
+            canvasId: opt.canvasId,
+            context: opt.context,
+            usingComponents: opt.usingComponents,
+            showLoading: opt.showLoading,
+            loadingText: opt.loadingText,
+        };
+        if (typeof opt === 'string') { // 只编码ASCII字符串
+            opt = {
+                text: opt
+            };
+        }
+        if (opt) {
+            for (var i in opt) {
+                this.options[i] = opt[i];
+            }
+        }
+        //使用QRCodeAlg创建二维码结构
+        var qrCodeAlg = null;
+        for (var i = 0, l = qrcodeAlgObjCache.length; i < l; i++) {
+            if (qrcodeAlgObjCache[i].text == this.options.text && qrcodeAlgObjCache[i].text.correctLevel == this.options.correctLevel) {
+                qrCodeAlg = qrcodeAlgObjCache[i].obj;
+                break;
+            }
+        }
+        if (i == l) {
+            qrCodeAlg = new QRCodeAlg(this.options.text, this.options.correctLevel);
+            qrcodeAlgObjCache.push({
+                text: this.options.text,
+                correctLevel: this.options.correctLevel,
+                obj: qrCodeAlg
+            });
+        }
+        /**
+         * 计算矩阵点的前景色
+         * @param {Obj} config
+         * @param {Number} config.row 点x坐标
+         * @param {Number} config.col 点y坐标
+         * @param {Number} config.count 矩阵大小
+         * @param {Number} config.options 组件的options
+         * @return {String}
+         */
+        let getForeGround = function (config) {
+            var options = config.options;
+            if (options.pdground && (
+                (config.row > 1 && config.row < 5 && config.col > 1 && config.col < 5) ||
+                (config.row > (config.count - 6) && config.row < (config.count - 2) && config.col > 1 && config.col < 5) ||
+                (config.row > 1 && config.row < 5 && config.col > (config.count - 6) && config.col < (config.count - 2))
+            )) {
+                return options.pdground;
+            }
+            return options.foreground;
+        }
+        // 创建canvas
+        let createCanvas = function (options) {
+            if (options.showLoading) {
+                uni.showLoading({
+                    title: options.loadingText,
+                    mask: true
+                });
+            }
+            var ctx = uni.createCanvasContext(options.canvasId, options.context);
+            var count = qrCodeAlg.getModuleCount();
+            var ratioSize = options.size;
+            var ratioImgSize = options.imageSize;
+            //计算每个点的长宽
+            var tileW = (ratioSize / count).toPrecision(4);
+            var tileH = (ratioSize / count).toPrecision(4);
+            //绘制
+            for (var row = 0; row < count; row++) {
+                for (var col = 0; col < count; col++) {
+                    var w = (Math.ceil((col + 1) * tileW) - Math.floor(col * tileW));
+                    var h = (Math.ceil((row + 1) * tileW) - Math.floor(row * tileW));
+                    var foreground = getForeGround({
+                        row: row,
+                        col: col,
+                        count: count,
+                        options: options
+                    });
+                    ctx.setFillStyle(qrCodeAlg.modules[row][col] ? foreground : options.background);
+                    ctx.fillRect(Math.round(col * tileW), Math.round(row * tileH), w, h);
+                }
+            }
+            if (options.image) {
+                var x = Number(((ratioSize - ratioImgSize) / 2).toFixed(2));
+                var y = Number(((ratioSize - ratioImgSize) / 2).toFixed(2));
+                drawRoundedRect(ctx, x, y, ratioImgSize, ratioImgSize, 2, 6, true, true)
+                ctx.drawImage(options.image, x, y, ratioImgSize, ratioImgSize);
+                // 画圆角矩形
+                function drawRoundedRect(ctxi, x, y, width, height, r, lineWidth, fill, stroke) {
+                    ctxi.setLineWidth(lineWidth);
+                    ctxi.setFillStyle(options.background);
+                    ctxi.setStrokeStyle(options.background);
+                    ctxi.beginPath(); // draw top and top right corner 
+                    ctxi.moveTo(x + r, y);
+                    ctxi.arcTo(x + width, y, x + width, y + r, r); // draw right side and bottom right corner 
+                    ctxi.arcTo(x + width, y + height, x + width - r, y + height, r); // draw bottom and bottom left corner 
+                    ctxi.arcTo(x, y + height, x, y + height - r, r); // draw left and top left corner 
+                    ctxi.arcTo(x, y, x + r, y, r);
+                    ctxi.closePath();
+                    if (fill) {
+                        ctxi.fill();
+                    }
+                    if (stroke) {
+                        ctxi.stroke();
+                    }
+                }
+            }
+            setTimeout(() => {
+                ctx.draw(true, () => {
+                    // 保存到临时区域
+                    setTimeout(() => {
+                        uni.canvasToTempFilePath({
+                            width: options.width,
+                            height: options.height,
+                            destWidth: options.width,
+                            destHeight: options.height,
+                            canvasId: options.canvasId,
+                            quality: Number(1),
+                            success: function (res) {
+                                if (options.cbResult) {
+                                    options.cbResult(res.tempFilePath)
+                                }
+                            },
+                            fail: function (res) {
+                                if (options.cbResult) {
+                                    options.cbResult(res)
+                                }
+                            },
+                            complete: function () {
+                                if (options.showLoading){
+                                    uni.hideLoading();
+                                }
+                            },
+                        }, options.context);
+                    }, options.text.length + 100);
+                });
+            }, options.usingComponents ? 0 : 150);
+        }
+        createCanvas(this.options);
+        // 空判定
+        let empty = function (v) {
+            let tp = typeof v,
+                rt = false;
+            if (tp == "number" && String(v) == "") {
+                rt = true
+            } else if (tp == "undefined") {
+                rt = true
+            } else if (tp == "object") {
+                if (JSON.stringify(v) == "{}" || JSON.stringify(v) == "[]" || v == null) rt = true
+            } else if (tp == "string") {
+                if (v == "" || v == "undefined" || v == "null" || v == "{}" || v == "[]") rt = true
+            } else if (tp == "function") {
+                rt = false
+            }
+            return rt
+        }
+    };
+    QRCode.prototype.clear = function (fn) {
+        var ctx = uni.createCanvasContext(this.options.canvasId, this.options.context)
+        ctx.clearRect(0, 0, this.options.size, this.options.size)
+        ctx.draw(false, () => {
+            if (fn) {
+                fn()
+            }
+        })
+    };
+})()
+
+export default QRCode

+ 260 - 0
appletXcx/components/tki-qrcode/tki-qrcode.vue

@@ -0,0 +1,260 @@
+<template xlang="wxml" minapp="mpvue">
+	<view class="tki-qrcode">
+		<!-- #ifndef MP-ALIPAY -->
+		<canvas class="tki-qrcode-canvas" :canvas-id="cid" :style="{width:cpSize+'px',height:cpSize+'px'}" />
+		<!-- #endif -->
+		<!-- #ifdef MP-ALIPAY -->
+		<canvas :id="cid" :width="cpSize" :height="cpSize" class="tki-qrcode-canvas" />
+		<!-- #endif -->
+		<image @click="openIMG"  v-show="show" :src="result" :style="{width:cpSize+'px',height:cpSize+'px'}" />
+	</view>
+</template>
+
+<script>
+import QRCode from "./qrcode.js"
+let qrcode
+export default {
+	name: "tki-qrcode",
+	props: {
+		cid: {
+			type: String,
+			default: 'tki-qrcode-canvas'
+		},
+		size: {
+			type: Number,
+			default: 200
+		}, 
+		unit: {
+			type: String,
+			default: 'upx'
+		},
+		show: {
+			type: Boolean,
+			default: true
+		},
+		val: {
+			type: String,
+			default: ''
+		},
+		background: {
+			type: String,
+			default: '#ffffff'
+		},
+		foreground: {
+			type: String,
+			default: '#000000'
+		},
+		pdground: {
+			type: String,
+			default: '#000000'
+		},
+		icon: {
+			type: String,
+			default: ''
+		},
+		iconSize: {
+			type: Number,
+			default: 40
+		},
+		lv: {
+			type: Number,
+			default: 1
+		},
+		onval: {
+			type: Boolean,
+			default: false
+		},
+		loadMake: {
+			type: Boolean,
+			default: false
+		},
+		usingComponents: {
+			type: Boolean,
+			default: true
+		},
+		showLoading: {
+			type: Boolean,
+			default: true
+		},
+		loadingText: {
+			type: String,
+			default: '二维码生成中'
+		},
+	},
+	data() {
+		return {
+			result: '',
+		}
+	},
+	methods: {
+		openIMG(){
+			uni.previewImage({
+				urls:[this.result]
+			})
+		},
+		_makeCode() {
+			console.log(this.cpSize,this.val,"that.cpSize");
+			let that = this
+			if (!this._empty(this.val)) {
+				qrcode = new QRCode({
+					context: that, // 上下文环境
+					canvasId:that.cid, // canvas-id
+					usingComponents: that.usingComponents, // 是否是自定义组件
+					showLoading: that.showLoading, // 是否显示loading
+					loadingText: that.loadingText, // loading文字
+					text: that.val, // 生成内容
+					size: that.cpSize, // 二维码大小
+					background: that.background, // 背景色
+					foreground: that.foreground, // 前景色
+					pdground: that.pdground, // 定位角点颜色
+					correctLevel: that.lv, // 容错级别
+					image: that.icon, // 二维码图标
+					imageSize: that.iconSize,// 二维码图标大小
+					cbResult: function (res) { // 生成二维码的回调
+						that._result(res)
+					},
+				});
+			} else {
+				// uni.showToast({
+				// 	title: '二维码内容不能为空',
+				// 	icon: 'none',
+				// 	duration: 2000
+				// });
+			}
+		},
+		_clearCode() {
+			this._result('')
+			qrcode.clear()
+		},
+		_saveCode() {
+			// this.$emit('')
+			let that = this;
+			if (this.result != "") {
+				// this.$emit('saveCode',  that.result)
+				uni.saveImageToPhotosAlbum({
+					filePath: that.result,
+					success: function () {
+						uni.showToast({
+							title: '二维码保存成功',
+							icon: 'success',
+							duration: 2000
+						});
+					},
+					fail:(err)=>{
+						console.log(err,"err")
+						if (err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" ||
+							err.errMsg === "saveImageToPhotosAlbum:fail auth deny" || err.errMsg ===
+							"saveImageToPhotosAlbum:fail authorize no response") {
+							// 这边微信做过调整,必须要在按钮中触发,因此需要在弹框回调中进行调用
+							uni.showModal({
+								title: '提示',
+								content: '需要您设置授权保存相册',
+								showCancel: false,
+								success: modalSuccess => {
+									uni.openSetting({
+										success(settingdata) {
+											console.log("settingdata", settingdata)
+											if (settingdata.authSetting[
+													'scope.writePhotosAlbum']) {
+												uni.showModal({
+													title: '提示',
+													content: '获取权限成功,再次点击图片即可保存',
+													showCancel: false,
+												})
+											} else {
+												uni.showModal({
+													title: '提示',
+													content: '获取权限失败,将无法保存到相册哦~',
+													showCancel: false,
+												})
+											}
+										},
+										fail(failData) {
+											console.log("failData", failData)
+										},
+										complete(finishData) {
+											console.log("finishData", finishData)
+										}
+									})
+						
+								}
+							})
+						}
+					}
+				});
+			}
+		},
+		_result(res) {
+			this.result = res;
+			this.$emit('result', res)
+		},
+		_empty(v) {
+			let tp = typeof v,
+				rt = false;
+			if (tp == "number" && String(v) == "") {
+				rt = true
+			} else if (tp == "undefined") {
+				rt = true
+			} else if (tp == "object") {
+				if (JSON.stringify(v) == "{}" || JSON.stringify(v) == "[]" || v == null) rt = true
+			} else if (tp == "string") {
+				if (v == "" || v == "undefined" || v == "null" || v == "{}" || v == "[]") rt = true
+			} else if (tp == "function") {
+				rt = false
+			}
+			return rt
+		}
+	},
+	watch: {
+		size: function (n, o) {
+			if (n != o && !this._empty(n)) {
+				this.cSize = n
+				if (!this._empty(this.val)) {
+					setTimeout(() => {
+						this._makeCode()
+					}, 100);
+				}
+			}
+		},
+		val: function (n, o) {
+			if (this.onval) {
+				if (n != o && !this._empty(n)) {
+					setTimeout(() => {
+						this._makeCode()
+					}, 0);
+				}
+			}
+		}
+	},
+	computed: {
+		
+		cpSize() {
+			if(this.unit == "upx"){
+				return uni.upx2px(this.size)
+			}else{
+				return this.size
+			}
+		}
+	},
+	mounted: function () {
+		if (this.loadMake) {
+			if (!this._empty(this.val)) {
+				setTimeout(() => {
+					this._makeCode()
+				}, 0);
+			}
+		}
+	},
+}
+</script>
+<style>
+.tki-qrcode {
+  position: relative;
+}
+.tki-qrcode-canvas {
+  position: fixed;
+  top: -99999upx;
+  left: -99999upx;
+  z-index: -99999;
+}
+</style>

+ 267 - 0
appletXcx/components/uni-scroll/uni-scroll-cate.vue

@@ -0,0 +1,267 @@
+<template>
+	<view class="content">
+		<view class="popup-content">
+			
+			<view class="">
+				<view class="box-pack-between ft32 flex-center popup-content-title">
+					<text @click="close">关闭</text>
+					<text style="color: #003A9B;" @click="confirm">确认</text>
+				</view>
+				<view class="ft22 tips cate border-b">
+					<view class="">
+						Tip:请根据小程序自身的功能,正确选择服务类目。
+					</view>	
+					餐饮行业选择服务类型是:餐饮 > 餐饮服务场所/餐饮服务管理企业,商业服务 > 公关/推广/市场调查
+				</view>
+				
+			</view>
+			
+			<view class="flex">
+				<scroll-view scroll-y class="popup-content-scroll">
+					<view @click="bindProv" :data-title="item.name" :data-code="item.id" :class="item.id==Prov_code?'act':''"
+					 class="popup-content-scroll-li flex-center" v-for="(item,index) of Prov_arr" :key='index'>
+						{{item.name}}
+					</view>
+				</scroll-view>
+				
+				<scroll-view scroll-y class="popup-content-scroll">
+					<block v-if="City_arr.length>0">
+						<view @click="bindCity" :data-innername="item.inner_name" :data-title="item.name" 
+						:class="item.id==City_code?'act':''" :data-code="item.id"
+						 class="popup-content-scroll-li flex-center " v-for="(item,index) of City_arr" :key='index'>
+							{{item.name}}
+						</view>
+					</block>
+					<view v-else class="City  popup-content-scroll-li flex-center">
+						请选择
+					</view>
+				</scroll-view>
+				
+				<scroll-view scroll-y class="popup-content-scroll">
+			<!-- 		<block v-if="Dist_arr.length>0">
+						<view @click="bindDist" :data-title="item.city_name" :class="item.cityid==Dist_code?'act':''" :data-code="item.cityid"
+						 class="popup-content-scroll-li flex-center" v-for="(item,index) of Dist_arr" :key='index'>
+							{{item.city_name}}
+						</view>
+					</block> -->
+					<block v-if="innername">
+					<view  class="City popup-content-scroll-li flex-center ft26">
+						{{innername}}
+					</view>
+					<view class="home-img" @click="uploadFile" data-type='1'>
+						<image :src="URL+xcx_logo" class="home-img-icon"></image>
+					</view>
+					</block>
+				</scroll-view>
+				
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'uniScroll',
+		props: {
+			Prov_arr: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			type: {
+				type: Number,
+				default: 1,
+			},
+		},
+		inject: ['popup'],
+		data() {
+			return {
+				
+				City_arr: [],
+				Dist_arr: [],
+				Prov_code: "",
+				City_code: "",
+				Dist_code: "",
+
+				Prov_title1: "",
+				City_title1: "",
+				Dist_title1: "",
+				Prov_title: "",
+				City_title: "",
+				Dist_title: "",
+				innername:"",
+				xcx_logo:"",			
+				URL: getApp().globalData.URL,
+			}
+		},
+		onLoad() {
+
+		},
+
+		methods: {
+			uploadFile(e) {
+				uni.chooseImage({
+					success: (res) => {
+						res.tempFilePaths.forEach((v, i) => {
+							console.log(v)
+							this.Upload({
+								url: "setting/upload",
+								data: {
+									url: v,
+									admin_id: uni.getStorageSync("admin_id"),
+								}
+							}).then(res => {
+								console.log(res, "res")
+								this.xcx_logo = res.src;
+							}).catch({});
+						})
+					}
+				});
+			},
+			
+			// 商户地址省
+			bindProv(e) {
+				this.Prov_code = e.currentTarget.dataset.code;
+				this.Prov_title1 = e.currentTarget.dataset.title;
+				this.Dist_arr = [];
+				this.Dist_code = "";
+				this.City_code = "";
+				this.City();
+			},
+			
+			// 商户地址市
+			bindCity(e) {
+				console.log(e)
+				let {code,title,innername }=e.currentTarget.dataset;
+				this.City_code = code;
+				this.City_title1 = title;
+				this.innername=innername;
+				this.Dist_code = "";
+				// this.wechat_secondcode();
+			},
+			
+			// 商户地址区
+			bindDist(e) {
+				
+				this.Dist_title1 = e.currentTarget.dataset.title;
+				this.Dist_code = e.currentTarget.dataset.code;
+				
+			},
+			
+			close(e) {
+				this.popup.close();
+				// this.$refs.popup.close();
+			},
+
+			confirm(e) {
+				let info;
+				if (!this.City_code||!this.Prov_code) {
+					uni.showToast({
+						title: "请选择",
+						icon: "none"
+					})
+					return
+				} 
+				info = {
+						code1: this.Prov_code,
+						code2: this.City_code,
+						// Dist_code: this.Dist_code,
+						Prov_title: this.Prov_title1,
+						City_title: this.City_title1,
+						special_license_pic :this.xcx_logo,
+						zzzs_name :this.innername,
+						// Dist_title: this.Dist_title1,
+				}
+				this.$emit('select', info)
+				this.popup.close();
+			},
+
+
+			City(e) {
+				this.request({
+					url: "setting/wechat_secondcategory",
+					data: {
+						id: this.Prov_code,
+					},
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code =="200") {
+						this.City_arr = res.data;
+					}
+				}).catch((res) => {
+					// this.City_arr = [];
+				});
+			},
+			
+			wechat_secondcode(){
+				this.request({
+					url: "setting/wechat_secondcode",
+					data: {
+						id: this.City_code,
+					},
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code === '200') {
+					
+					}
+				}).catch((res) => {
+				
+				});
+			},
+			
+			Dist(e) {
+				
+				this.Dist_arr = res.data;
+				
+				return
+				this.request({
+					url: "setting/getcity",
+					data: {
+						cityid: this.City_code,
+					},
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code === '200') {
+						this.Dist_arr = res.data;
+					}
+				}).catch((res) => {
+					this.Dist_arr = [];
+				});
+			},
+			
+			
+		}
+	}
+</script>
+
+<style>
+	page .act {
+		color: #007AFF;
+	}
+	.popup-content {
+		width: 100%;
+		background: #fff;
+		padding: 0rpx 40rpx;
+	}
+
+	.popup-content-title {
+		border-bottom: 1rpx solid #F1F1F1;
+		padding: 10rpx 0rpx;
+	}
+
+	.popup-content-scroll {
+		height: 590rpx;
+		width: 33%;
+		text-align: center;
+	}
+
+	.popup-content-scroll-li {
+		padding: 8rpx 0;
+	}
+	.home-img-icon {
+		border: 1rpx solid #ccc;
+		width: 200rpx;
+		height: 200rpx;
+	}
+</style>

+ 192 - 0
appletXcx/components/uni-scroll/uni-scroll.vue

@@ -0,0 +1,192 @@
+<template>
+	<view class="content">
+		<view class="popup-content">
+			<view class="box-pack-between ft32 flex-center popup-content-title">
+				<text @click="close">关闭</text>
+				<text style="color: #003A9B;" @click="confirm">确认</text>
+			</view>
+			<view class="flex">
+				<scroll-view scroll-y class="popup-content-scroll">
+					<view @click="bindProv" :data-title="item.city_name" :data-code="item.cityid" :class="item.cityid==Prov_code?'act':''"
+					 class="popup-content-scroll-li flex-center" v-for="(item,index) of Prov_arr" :key='index'>
+						{{item.city_name}}
+					</view>
+				</scroll-view>
+				<scroll-view scroll-y class="popup-content-scroll">
+					<block v-if="City_arr.length>0">
+						<view @click="bindCity" :data-title="item.city_name" :class="item.cityid==City_code?'act':''" :data-code="item.cityid"
+						 class="popup-content-scroll-li flex-center " v-for="(item,index) of City_arr" :key='index'>
+							{{item.city_name}}
+						</view>
+					</block>
+					<view v-else class="City  popup-content-scroll-li flex-center">
+						请选择
+					</view>
+				</scroll-view>
+				<scroll-view scroll-y class="popup-content-scroll">
+					<block v-if="Dist_arr.length>0">
+						<view @click="bindDist" :data-title="item.city_name" :class="item.cityid==Dist_code?'act':''" :data-code="item.cityid"
+						 class="popup-content-scroll-li flex-center" v-for="(item,index) of Dist_arr" :key='index'>
+							{{item.city_name}}
+						</view>
+					</block>
+					<view v-else class="City popup-content-scroll-li flex-center">
+						请选择
+					</view>
+				</scroll-view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'uniScroll',
+		props: {
+			Prov_arr: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			type: {
+				type: Number,
+				default: 1,
+			},
+		},
+		inject: ['popup'],
+		data() {
+			return {
+				City_arr: [],
+				Dist_arr: [],
+				Prov_code: "",
+				City_code: "",
+				Dist_code: "",
+
+				Prov_title1: "",
+				City_title1: "",
+				Dist_title1: "",
+				Prov_title: "",
+				City_title: "",
+				Dist_title: "",
+			}
+		},
+		onLoad() {
+
+		},
+
+		methods: {
+			// 商户地址省
+			bindProv(e) {
+				this.Prov_code = e.currentTarget.dataset.code;
+				this.Prov_title1 = e.currentTarget.dataset.title;
+				this.Dist_arr = [];
+				this.Dist_code = "";
+				this.City();
+			},
+			// 商户地址市
+			bindCity(e) {
+				this.City_code = e.currentTarget.dataset.code;
+				this.City_title1 = e.currentTarget.dataset.title;
+				this.Dist_code = "";
+				this.Dist();
+			},
+			// 商户地址区
+			bindDist(e) {
+				this.Dist_title1 = e.currentTarget.dataset.title;
+				this.Dist_code = e.currentTarget.dataset.code;
+			},
+			close(e) {
+				this.$refs.popup.close();
+			},
+
+			confirm(e) {
+				let info;
+				if (!this.Dist_code) {
+					uni.showToast({
+						title: "请选择区",
+						icon: "none"
+					})
+					return
+				}
+				// if (this.type == 1) {
+					info = {
+						Prov_code: this.Prov_code,
+						City_code: this.City_code,
+						Dist_code: this.Dist_code,
+						Prov_title: this.Prov_title1,
+						City_title: this.City_title1,
+						Dist_title: this.Dist_title1,
+					}
+				// } 
+				console.log(info)
+				this.$emit('select', info)
+				this.popup.close();
+			},
+
+			City(e) {
+				this.request({
+					url: "setting/getcity",
+					data: {
+						// token: uni.getStorageSync("token"),
+						cityid: this.Prov_code,
+					},
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code =="200") {
+						this.City_arr = res.data;
+					console.log(this.City_arr, "City_arr")
+					}
+				}).catch((res) => {
+					// this.City_arr = [];
+				});
+			},
+			
+			Dist(e) {
+				this.request({
+					url: "setting/getcity",
+					data: {
+						cityid: this.City_code,
+					},
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code === '200') {
+						this.Dist_arr = res.data;
+					}
+				}).catch((res) => {
+					this.Dist_arr = [];
+				});
+			},
+			
+			
+		}
+	}
+</script>
+
+<style>
+	page .act {
+		color: #007AFF;
+	}
+
+	.popup-content {
+		width: 100%;
+		height: 656rpx;
+		background: #fff;
+		padding: 0rpx 40rpx;
+	}
+
+	.popup-content-title {
+		border-bottom: 1rpx solid #F1F1F1;
+		padding: 10rpx 0rpx;
+	}
+
+	.popup-content-scroll {
+		height: 590rpx;
+		width: 33%;
+		text-align: center;
+	}
+
+	.popup-content-scroll-li {
+		padding: 8rpx 0;
+	}
+</style>

+ 194 - 0
appletXcx/components/uni-scroll/uni-scrollail1.vue

@@ -0,0 +1,194 @@
+<template>
+	<view class="content">
+		<view class="popup-content ffffffff">
+			<view class="box-pack-between ft32 flex-center popup-content-title">
+				<text @click="close">关闭</text>
+				<text style="color: #003A9B;" @click="confirm">确认</text>
+			</view>
+			<view class="flex">
+				<scroll-view scroll-y class="popup-content-scroll">
+					<view @click="bindProv" :data-title="item.category_name" :data-code="item.category_id" 
+					:class="item.category_id==Prov_code?'act':''" class="popup-content-scroll-li flex-center"
+					 v-for="(item,index) of Prov_arr" :key='index'>
+						{{item.category_name}}
+					</view>
+				</scroll-view>
+				<scroll-view scroll-y class="popup-content-scroll">
+					<block v-if="City_arr.length>0">
+						<view @click="bindCity" :data-title="item.category_name" :class="item.category_id==City_code?'act':''" 
+						:data-code="item.category_id" class="popup-content-scroll-li flex-center "
+						 v-for="(item,index) of City_arr" :key='index'>
+							{{item.category_name}}
+						</view>
+					</block>
+					<view v-else class="City  popup-content-scroll-li flex-center">
+						请选择
+					</view>
+				</scroll-view>
+				<scroll-view scroll-y class="popup-content-scroll">
+					<block v-if="Dist_arr.length>0">
+						<view @click="bindDist" :data-title="item.category_name" :class="item.category_id==Dist_code?'act':''" :data-code="item.category_id"
+						 class="popup-content-scroll-li flex-center" v-for="(item,index) of Dist_arr" :key='index'>
+							{{item.category_name}}
+						</view>
+					</block>
+					<view v-else class="City popup-content-scroll-li flex-center">
+						请选择
+					</view>
+				</scroll-view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'uniScrollailOne',
+		props: {
+			Prov_arr: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			type: {
+				type: Number,
+				default: 2,
+			},
+		},
+		inject: ['popup'],
+		data() {
+			return {
+				City_arr: [],
+				Dist_arr: [],
+				Prov_code: "",
+				City_code: "",
+				Dist_code: "",
+
+				Prov_title1: "",
+				City_title1: "",
+				Dist_title1: "",
+				Prov_title: "",
+				City_title: "",
+				Dist_title: "",
+			}
+		},
+		onLoad() {
+
+		},
+
+		methods: {
+			// 商户地址省
+			bindProv(e) {
+				this.Prov_code = e.currentTarget.dataset.code;
+				this.Prov_title1 = e.currentTarget.dataset.title;
+				this.Dist_arr = [];
+				this.Dist_code = "";
+				this.City();
+			},
+			// 商户地址市
+			bindCity(e) {
+				this.City_code = e.currentTarget.dataset.code;
+				this.City_title1 = e.currentTarget.dataset.title;
+				this.Dist_code = "";
+				this.Dist();
+			},
+			
+			// 商户地址区
+			bindDist(e) {
+				this.Dist_title1 = e.currentTarget.dataset.title;
+				this.Dist_code = e.currentTarget.dataset.code;
+			},
+
+			close(e) {
+				this.$refs.popup.close();
+			},
+
+			confirm(e) {
+				console.log("info")
+				let info;
+				if (!this.City_code) {
+					uni.showToast({
+						title: "请选择分类",
+						icon: "none"
+					})
+					return
+				}
+				if (this.type == 2) {
+					info = {
+						mccCd1: this.Prov_code,
+						mccCd2: this.City_code,
+						mccCd3: this.Dist_code,
+						mccCd1_title: this.Prov_title1,
+						mccCd2_title: this.City_title1,
+						mccCd3_title: this.Dist_title1,
+					}
+				}
+				console.log(info)
+				this.$emit('setlet', info)
+				this.popup.close();
+			},
+
+			City(e) {
+				this.request({
+					url: "setting/get_type",
+					data: {
+						category_id: this.Prov_code,
+					},
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code === '200') {
+						this.City_arr = res.data;
+					}
+				}).catch((res) => {
+					this.City_arr = [];
+				});
+			},
+
+			Dist(e) {
+				this.request({
+					url: "setting/get_type",
+					data: {
+						category_id: this.City_code,
+					},
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code === '200') {
+						this.Dist_arr = res.data;
+					}
+				}).catch((res) => {
+					this.Dist_arr = [];
+				});
+			},
+			
+		}
+	}
+</script>
+
+<style>
+	page .act {
+		color: #007AFF;
+	}
+
+	.popup-content {
+		width: 100%;
+		height: 656rpx;
+		background: #fff;
+		padding: 0rpx 40rpx;
+	}
+
+	.popup-content-title {
+		border-bottom: 1rpx solid #F1F1F1;
+		padding: 10rpx 0rpx;
+	}
+
+	.popup-content-scroll {
+		height: 590rpx;
+		width: 33%;
+		text-align: center;
+	}
+
+	.popup-content-scroll-li {
+		padding: 8rpx 0;
+	}
+</style>

+ 19 - 0
appletXcx/css/style.css

@@ -0,0 +1,19 @@
+page {
+		background-color: #F1F1F1;
+	}
+
+	.home {
+		background-color: #FFFFFF;
+		width: 720rpx;
+		border-radius: 8rpx;
+		margin: 0 auto;
+		margin-bottom: 20rpx;
+	}
+
+	.item {
+		height: 100rpx;
+		padding: 0 20rpx;
+	}
+	.tr{
+		text-align: right;
+	}

二进制
appletXcx/static/images/icon_1.png


二进制
appletXcx/static/images/icon_6.png


二进制
appletXcx/static/images/shanchu.png


+ 98 - 0
appletXcx/wechatMarket/index.vue

@@ -0,0 +1,98 @@
+<template>
+    <view class="main-block">
+        <view class="page-block">
+            <view class="btn-list">
+				<block v-for="(item,index) in power_list" :key='index'>
+						<navigator v-if="item.id!=858" class="item flex flex-col flex-center" :url="item.address">
+							<image :src="item.image" class="icon-img" mode="aspectFit"></image>
+							<view class="name">{{item.name}}</view>
+						</navigator>
+						<view v-if="item.id==858" @click="navToIntegral" class="item flex flex-col flex-center">
+							<image src="../static/images/icon_1.png" class="icon-img" mode="aspectFit"></image>
+							<view class="name">积分推送</view>
+						</view>
+				</block>
+            </view>
+        </view>
+    </view>
+</template>
+
+<script>
+    export default {
+		data() {
+		    return {
+				power_list:[],
+		    }
+		},
+			
+		onLoad(e) {
+			this.sid=e.id;
+			let { list } = this.$store.state.management_list_store.find((v, i) => v.id == e.id)
+			this.power_list = list
+		},
+		
+        methods: {
+            navToIntegral() {
+                let urls = ['./templateMessage', './vipCardMessage']
+                uni.showActionSheet({
+                    itemList: ['模板消息推送', '会员卡消息推送'],
+                    success: (r) => {
+                        uni.navigateTo({
+                            url: urls[r.tapIndex]
+                        })
+                    }
+                })
+            },
+			
+			
+        }
+    }
+</script>
+
+<style>
+    .main-block {
+        padding: 50rpx 25rpx 0;
+    }
+
+    .btn-list {
+        display: -webkit-box;
+        display: -webkit-flex;
+        display: flex;
+        -webkit-box-orient: horizontal;
+        -webkit-box-direction: normal;
+        -webkit-flex-flow: row wrap;
+        flex-flow: row wrap;
+        -webkit-box-pack: start;
+        -webkit-justify-content: flex-start;
+        justify-content: flex-start;
+        -webkit-align-content: flex-start;
+        align-content: flex-start;
+    }
+
+    .page-block {
+        width: 700rpx;
+        background-color: #fff;
+        box-sizing: border-box;
+        border-radius: 8rpx;
+        margin-bottom: 30rpx;
+
+    }
+
+    .btn-list .item {
+        width: 33.33%;
+        height: 145rpx;
+    }
+
+    .btn-list .item .icon-img {
+        display: block;
+        width: 48rpx;
+        height: 48rpx;
+    }
+
+    .btn-list .item .name {
+        font-size: 24rpx;
+        line-height: 33rpx;
+        margin-top: 16rpx;
+        color: #666;
+    }
+</style>

+ 505 - 0
appletXcx/wechatMarket/templateMessage.vue

@@ -0,0 +1,505 @@
+<template>
+    <view class="content">
+        <no-none v-if='list.length<=0'></no-none>
+        <block v-else>
+            <view style="margin-top: 30rpx;" class="item" v-for="(item,index) of list" :key='index'>
+                <view class="border-b item-title flex-y-center">
+                    <image :src="item.avatar" mode="aspectFill" class="avatar" @click="previewImg(item.avatar)"></image>
+                    <text>{{item.nickname || '未知用户'}} {{item.tel || ''}}</text>
+                    <switch :checked="item.checked" type="checkbox" @change="onChooseUser($event,index)"
+                        style="margin-left: auto;" />
+                </view>
+
+                <view class="item-bottom flex-y-center">
+                    <view class="flex-grow-1">
+                        <view class="box-pack-between item-bottom-right">
+                            <text><text class="item-bottom-number">会员等级</text>:{{item.level}}</text>
+                        </view>
+                        <view class="box-pack-between item-bottom-right flex-y-center">
+                            <text><text class="item-bottom-number">门店昵称</text>:{{item.store_id}} </text>
+                        </view>
+                        <view class="box-pack-between item-bottom-right flex-y-center">
+                            <text><text class="item-bottom-number">已推送</text>:{{item.yitui}} </text>
+                        </view>
+                        <view class="box-pack-between item-bottom-right flex-y-center">
+                            <text><text class="item-bottom-number">剩余</text>:{{item.shengyu}} </text>
+                        </view>
+                        <view class="box-pack-between item-bottom-right flex-y-center">
+                            <text><text class="item-bottom-number">类型</text>:{{item.type == 1?'微信':'支付宝'}} </text>
+                        </view>
+                        <view class="box-pack-between item-bottom-right flex-y-center">
+                            <text><text class="item-bottom-number">时间</text>:{{item.createtime}} </text>
+                        </view>
+                    </view>
+                </view>
+            </view>
+
+        </block>
+
+        <view style="height: 90px;"></view>
+
+        <navigator style="margin-bottom:0" url='./addCoupon' hover-class="none" class="bottom-bar">
+            <view class="btn" style="background: #fff;border:1px solid #ddd;color:#888" @click="showScreen">筛选</view>
+            <view class="btn" @click="showAddPop">+新增推送</view>
+        </navigator>
+        <uni-popup ref="popup" type="bottom" background-color="#fff" style="z-index:100" :is-mask-click="false"
+            :mask-click="false">
+            <view class="screen-pop">
+                <view class="cell">
+                    <view class="label">会员昵称</view>
+                    <view class="desc"><input type="text" v-model="screen.name" class="input-box" placeholder="请输入" />
+                    </view>
+                </view>
+                <view class="cell">
+                    <view class="label">手机号码</view>
+                    <view class="desc"><input type="text" v-model="screen.tel" class="input-box" placeholder="请输入" />
+                    </view>
+                </view>
+                <view class="cell">
+                    <view class="label">身份</view>
+                    <view class="desc">
+                        <picker :range="levels" range-key="name" @change="onChangeLevel">
+                            <input type="text" :value="screen.level_name" class="input-box" placeholder="请输入" />
+                        </picker>
+                    </view>
+                </view>
+                <view class="cell">
+                    <view class="label">时间</view>
+                    <view class="desc flex flex-between flex-y-center">
+                        <picker mode="date" @change="onChangeTime($event,'start_time')">
+                            <input type="text" :value="screen.start_time" placeholder="开始时间" class="input-box"
+                                style="text-align: center;" disabled>
+                        </picker>
+                        <view>—</view>
+                        <picker mode="date" @change="onChangeTime($event,'end_time')">
+                            <input type="text" :value="screen.end_time" placeholder="结束时间" class="input-box"
+                                style="text-align: center;" disabled>
+                        </picker>
+                    </view>
+                </view>
+                <view class="btns">
+                    <view class="btn reset-btn" @click="onResetScreen">重置</view>
+                    <view class="btn submit-btn" @click="onSubmitScreen">确定</view>
+                </view>
+                <view class="is-iphone-x"></view>
+            </view>
+        </uni-popup>
+        <uni-popup ref="addPopup" type="bottom" background-color="#fff" style="z-index:100" :is-mask-click="false"
+            :mask-click="false">
+            <view class="screen-pop">
+                <view class="cell">
+                    <view class="label">推送文案</view>
+                    <view class="desc"><input type="text" v-model="sendInfo.textarea" class="input-box"
+                            placeholder="请输入" />
+                    </view>
+                    <view class="tips">注意:文案加起来不能超过19个字符。如果有赠送积分,推送文案内要写推送积分数。举例:您好,本次积分活动赠送34积分</view>
+                </view>
+                <view class="cell">
+                    <view class="label">赠送积分</view>
+                    <view class="desc"><input type="text" v-model="sendInfo.integral" class="input-box"
+                            placeholder="请输入" />
+                    </view>
+                    <view class="tips">注意注意:假设不赠送积分,则填0</view>
+                </view>
+                <view class="btns">
+                    <view class="btn reset-btn" @click="onResetAdd">取消</view>
+                    <view class="btn submit-btn" @click="onSubmitAdd">推送</view>
+                </view>
+                <view class="is-iphone-x"></view>
+            </view>
+        </uni-popup>
+    </view>
+
+</template>
+
+<script>
+    export default {
+        data() {
+            return {
+
+                list: [],
+                page: 1,
+                is_load: false,
+                levels: [{
+                    id: 55,
+                    name: "普通会员"
+                }],
+                screen: {
+                    name: "",
+                    level: "",
+                    tel: "",
+                    start_time: "",
+                    end_time: ""
+                },
+                sendUserIds: "",
+                sendInfo: {
+                    textarea: "",
+                    integral: ""
+                }
+            }
+        },
+
+        onLoad() {
+            this.getLevels()
+        },
+
+        onShow() {
+            this.page = 1;
+            this.list = [];
+            this.http();
+        },
+
+        onReachBottom(e) {
+            if (!this.is_load) {
+                this.page = this.page + 1;
+                this.http();
+            }
+        },
+
+        methods: {
+            onChooseUser(e, index) {
+                console.log(e, index)
+                this.list[index].checked = e.detail.value
+            },
+            showScreen() {
+                this.$refs.popup.open('bottom')
+            },
+            getLevels() {
+                this.request({
+                    url: "alipaycoupon/level_index",
+                    data: {
+                        admin_id: uni.getStorageSync("admin_id"),
+                    },
+                    showLoading: true,
+                }).then(res => {
+                    console.log(res, "res")
+                    if (res.code === "200") {
+                        this.levels = this.levels.concat(res.data)
+                    }
+                });
+            },
+            onChangeLevel(e) {
+                this.screen.level_name = this.levels[e.detail.value].name
+                this.screen.level = this.levels[e.detail.value].id
+            },
+            onChangeTime(e, name) {
+                // console.log(e)
+                this.screen[name] = e.detail.value
+            },
+            onResetScreen() {
+                this.screen = {
+                    name: "",
+                    level: "",
+                    tel: "",
+                    start_time: "",
+                    end_time: ""
+                }
+                this.$refs.popup.close()
+                this.http()
+            },
+            onSubmitScreen() {
+                this.page = 1
+                this.list = []
+                if (this.screen.start_time && this.screen.end_time) {
+                    let start = this.screen.start_time
+                    let end = this.screen.end_time
+                    if (Date.parse(start.replace(/-/g, '/')) > Date.parse(end.replace(/-/g, '/'))) {
+                        this.screen.start_time = end
+                        this.screen.end_time = start
+                    }
+                }
+                this.$refs.popup.close()
+                this.http()
+            },
+            showAddPop() {
+                let arr = this.list.filter(item => {
+                    return item.checked
+                })
+                console.log(arr)
+                if (arr.length > 0) {
+                    this.sendUserIds = arr.map(item => {
+                        return item.id
+                    })
+                    this.$refs.addPopup.open("bottom")
+                } else {
+                    uni.showToast({
+                        title: "请选择推送对象",
+                        icon: "none"
+                    })
+                }
+            },
+            onResetAdd() {
+                this.list.map(item => {
+                    item.checked = false
+                })
+                this.sendInfo = {
+                    textarea: "",
+                    integral: ""
+                }
+                this.$refs.addPopup.close()
+            },
+            onSubmitAdd() {
+                if (this.sendInfo.textarea == '' || this.sendInfo.integral == '') {
+                    uni.showToast({
+                        title: "请完善表单后提交",
+                        icon: "none"
+                    })
+                    return false
+                }
+                this.request({
+                    url: 'alipaycoupon/weintegral_get',
+                    data: {
+                        admin_id: uni.getStorageSync("admin_id"),
+                        textarea: this.sendInfo.textarea,
+                        integral: this.sendInfo.integral,
+                        data_id: this.sendUserIds.join(',')
+                    },
+                }).then(res => {
+                    if (res.code == 200) {
+                        uni.showModal({
+                            content: res.message,
+                            showCancel: false,
+                            success: (r) => {
+                                this.sendInfo = {
+                                    textarea: "",
+                                    integral: ""
+                                }
+                                this.$refs.addPopup.close()
+                                this.list = []
+                                this.page = 1
+                                this.http()
+                            }
+                        })
+                    } else {
+                        uni.showToast({
+                            title: res.message,
+                            icon: 'none'
+                        })
+                    }
+                }).catch(res => {
+                    uni.showToast({
+                        title: res.message,
+                        icon: 'none'
+                    })
+                })
+
+            },
+            previewImg(src) {
+                if (src) {
+                    uni.previewImage({
+                        urls: [src]
+                    });
+                }
+
+            },
+
+
+            http() {
+                let url = "alipaycoupon/integral_data";
+                this.request({
+                    url,
+                    data: {
+                        admin_id: uni.getStorageSync("admin_id"),
+                        page: this.page,
+                        limit: 10,
+                        name: this.screen.name,
+                        level: this.screen.level,
+                        tel: this.screen.tel,
+                        start_time: this.screen.start_time,
+                        end_time: this.screen.end_time,
+                    },
+                    showLoading: true,
+                }).then(res => {
+                    console.log(res, "res")
+                    if (res.code === "200") {
+                        let arr = res.data
+                        if (arr.length > 0) {
+                            arr.map(item => {
+                                item.checked = false
+                            })
+                            this.list = this.list.concat(arr);
+                            this.is_load = false
+
+                        } else {
+                            this.is_load = true
+                        }
+
+                    }
+                });
+            },
+
+
+
+
+        },
+    }
+</script>
+
+<style lang="scss">
+    page {
+        background: #F5F7FA;
+    }
+
+    .page-top {
+        background: #fff;
+        position: sticky;
+        top: 0;
+        z-index: 99;
+        padding: 10rpx 0;
+        box-shadow: 0 5rpx 10rpx #f0f0f0;
+    }
+
+    .item {
+        width: 690rpx;
+        background: #ffffff;
+        margin: 0 auto;
+        padding: 0rpx 24rpx;
+        opacity: 1;
+        border-radius: 8rpx;
+        box-shadow: 0rpx 6rpx 10rpx 0rpx rgba(213, 213, 213, 0.04);
+
+        .item-title {
+            opacity: 1;
+            font-size: 28rpx;
+            font-family: PingFang SC, PingFang SC-Medium;
+            font-weight: 500;
+            color: #333333;
+            padding: 24rpx 0;
+
+            .avatar {
+                display: block;
+                width: 48rpx;
+                height: 48rpx;
+                border-radius: 50%;
+                margin-right: 16rpx;
+            }
+
+        }
+
+        .item-bottom {
+            font-size: 26rpx;
+            padding: 20rpx 0 24rpx 0;
+            color: #666666;
+
+            .item-bottom-left {
+                width: 90rpx;
+                height: 90rpx;
+                margin-right: 24rpx;
+                min-width: 90rpx;
+                margin-bottom: 16rpx;
+            }
+
+            .item-bottom-right {
+                margin-bottom: 16rpx;
+
+                .item-bottom-number {
+                    color: #99A0AD;
+                }
+            }
+
+        }
+
+    }
+
+    .color-ffa {
+        color: #3387FF;
+    }
+
+    .icongengduo {
+        color: #999;
+        font-size: 24rpx;
+    }
+
+    .bottom-bar {
+        position: fixed;
+        bottom: 0px;
+        width: 100%;
+        z-index: 50;
+        background: #FFFFFF;
+        padding: 30rpx 0;
+        display: flex;
+        flex-flow: row nowrap;
+        justify-content: space-around;
+        align-items: center;
+    }
+
+    .bottom-bar .btn {
+
+        width: 300rpx;
+        height: 98rpx;
+        opacity: 1;
+        background: #04BE02;
+        border-radius: 49rpx;
+        box-shadow: 0rpx 0rpx 8rpx 0rpx rgba(51, 135, 255, 0.20);
+        opacity: 1;
+        font-size: 36rpx;
+        text-align: center;
+        line-height: 98rpx;
+        font-family: PingFang SC, PingFang SC-Medium;
+        font-weight: 500;
+        color: #ffffff;
+
+    }
+
+    .screen-pop {
+        background: #fff;
+        padding: 40rpx 0 0;
+        border-radius: 20rpx 20rpx 0 0;
+
+        .cell {
+            padding: 0 24rpx;
+            margin-bottom: 40rpx;
+
+            .label {
+                font-size: 30rpx;
+                color: #555;
+                width: 160rpx;
+            }
+
+            .desc {
+                margin-top: 30rpx;
+                background: #f4f5f6;
+                border-radius: 8rpx;
+                height: 88rpx;
+
+                .input-box {
+                    padding: 0 16rpx;
+                    height: 88rpx;
+                    font-size: 28rpx;
+                    color: #555;
+                }
+            }
+        }
+
+        .btns {
+            display: flex;
+            flex-flow: row nowrap;
+
+
+            .btn {
+                width: 50%;
+                height: 88rpx;
+                text-align: center;
+                line-height: 88rpx;
+                font-size: 32rpx;
+                font-weight: 500;
+            }
+
+            .reset-btn {
+                background-color: #F4F5F7;
+                color: #04BE02;
+            }
+
+            .submit-btn {
+                background-color: #04BE02;
+                color: #fff;
+            }
+        }
+
+        .tips {
+            margin-top: 16rpx;
+            font-size: 24rpx;
+            color: #f00;
+        }
+    }
+</style>

+ 495 - 0
appletXcx/wechatMarket/vipCardMessage.vue

@@ -0,0 +1,495 @@
+<template>
+    <view class="content">
+        <no-none v-if='list.length<=0'></no-none>
+        <block v-else>
+            <view style="margin-top: 30rpx;" class="item" v-for="(item,index) of list" :key='index'>
+                <view class="border-b item-title flex-y-center">
+                    <image :src="item.avatar" mode="aspectFill" class="avatar" @click="previewImg(item.avatar)"></image>
+                    <text>{{item.nickname || '未知用户'}} {{item.mobile || ''}}</text>
+                    <switch :checked="item.checked" type="checkbox" @change="onChooseUser($event,index)"
+                        style="margin-left: auto;" />
+                </view>
+
+                <view class="item-bottom flex-y-center">
+                    <view class="flex-grow-1">
+                        <view class="box-pack-between item-bottom-right flex-y-center">
+                            <text><text class="item-bottom-number">所属门店</text>:{{item.store_name}} </text>
+                        </view>
+                        <view class="box-pack-between item-bottom-right">
+                            <text><text class="item-bottom-number">会员等级</text>:{{item.level_name}}</text>
+                        </view>
+                        <view class="box-pack-between item-bottom-right flex-y-center">
+                            <text><text class="item-bottom-number">当前积分</text>:{{item.integral}} </text>
+                        </view>
+                        <view class="box-pack-between item-bottom-right flex-y-center">
+                            <text><text class="item-bottom-number">当前余额</text>:{{item.balance}} </text>
+                        </view>
+
+                        <view class="box-pack-between item-bottom-right flex-y-center">
+                            <text><text class="item-bottom-number">领卡时间</text>:{{item.addtime}} </text>
+                        </view>
+                    </view>
+                </view>
+            </view>
+
+        </block>
+
+        <view style="height: 90px;"></view>
+
+        <navigator style="margin-bottom:0" url='./addCoupon' hover-class="none" class="bottom-bar">
+            <view class="btn" style="background: #fff;border:1px solid #ddd;color:#888" @click="showScreen">筛选</view>
+            <view class="btn" @click="showAddPop">+新增推送</view>
+        </navigator>
+        <uni-popup ref="popup" type="bottom" background-color="#fff" style="z-index:100" :is-mask-click="false"
+            :mask-click="false">
+            <view class="screen-pop">
+                <view class="cell">
+                    <view class="label">手机号码</view>
+                    <view class="desc"><input type="text" v-model="screen.tel" class="input-box" placeholder="请输入" />
+                    </view>
+                </view>
+                <view class="cell">
+                    <view class="label">身份</view>
+                    <view class="desc">
+                        <picker :range="levels" range-key="name" @change="onChangeLevel">
+                            <input type="text" :value="screen.level_name" class="input-box" placeholder="请输入" />
+                        </picker>
+                    </view>
+                </view>
+                <view class="cell">
+                    <view class="label">时间</view>
+                    <view class="desc flex flex-between flex-y-center">
+                        <picker mode="date" @change="onChangeTime($event,'start_time')">
+                            <input type="text" :value="screen.start_time" placeholder="开始时间" class="input-box"
+                                style="text-align: center;" disabled>
+                        </picker>
+                        <view>—</view>
+                        <picker mode="date" @change="onChangeTime($event,'end_time')">
+                            <input type="text" :value="screen.end_time" placeholder="结束时间" class="input-box"
+                                style="text-align: center;" disabled>
+                        </picker>
+                    </view>
+                </view>
+                <view class="btns">
+                    <view class="btn reset-btn" @click="onResetScreen">重置</view>
+                    <view class="btn submit-btn" @click="onSubmitScreen">确定</view>
+                </view>
+                <view class="is-iphone-x"></view>
+            </view>
+        </uni-popup>
+        <uni-popup ref="addPopup" type="bottom" background-color="#fff" style="z-index:100" :is-mask-click="false"
+            :mask-click="false">
+            <view class="screen-pop">
+                <view class="cell">
+                    <view class="label">推送文案</view>
+                    <view class="desc"><input type="text" v-model="sendInfo.textarea" class="input-box"
+                            placeholder="请输入" />
+                    </view>
+                    <view class="tips">注意:文案加起来不能超过19个字符。如果有赠送积分,推送文案内要写推送积分数。举例:您好,本次积分活动赠送34积分</view>
+                </view>
+                <view class="cell">
+                    <view class="label">赠送积分</view>
+                    <view class="desc"><input type="text" v-model="sendInfo.integral" class="input-box"
+                            placeholder="请输入" />
+                    </view>
+                    <view class="tips">注意注意:假设不赠送积分,则填0</view>
+                </view>
+                <view class="btns">
+                    <view class="btn reset-btn" @click="onResetAdd">取消</view>
+                    <view class="btn submit-btn" @click="onSubmitAdd">推送</view>
+                </view>
+                <view class="is-iphone-x"></view>
+            </view>
+        </uni-popup>
+    </view>
+
+</template>
+
+<script>
+    export default {
+        data() {
+            return {
+
+                list: [],
+                page: 1,
+                is_load: false,
+                levels: [{
+                    id: 55,
+                    name: "普通会员"
+                }],
+                screen: {
+                    level: "",
+                    tel: "",
+                    start_time: "",
+                    end_time: ""
+                },
+                sendUserIds: "",
+                sendInfo: {
+                    textarea: "",
+                    integral: ""
+                }
+            }
+        },
+
+        onLoad() {
+            this.getLevels()
+        },
+
+        onShow() {
+            this.page = 1;
+            this.list = [];
+            this.http();
+        },
+
+        onReachBottom(e) {
+            if (!this.is_load) {
+                this.page = this.page + 1;
+                this.http();
+            }
+        },
+
+        methods: {
+            onChooseUser(e, index) {
+                console.log(e, index)
+                this.list[index].checked = e.detail.value
+            },
+            showScreen() {
+                this.$refs.popup.open('bottom')
+            },
+            getLevels() {
+                this.request({
+                    url: "alipaycoupon/level_index",
+                    data: {
+                        admin_id: uni.getStorageSync("admin_id"),
+                    },
+                    showLoading: true,
+                }).then(res => {
+                    console.log(res, "res")
+                    if (res.code === "200") {
+                        this.levels = this.levels.concat(res.data)
+                    }
+                });
+            },
+            onChangeLevel(e) {
+                this.screen.level_name = this.levels[e.detail.value].name
+                this.screen.level = this.levels[e.detail.value].id
+            },
+            onChangeTime(e, name) {
+                // console.log(e)
+                this.screen[name] = e.detail.value
+            },
+            onResetScreen() {
+                this.screen = {
+                    level: "",
+                    tel: "",
+                    start_time: "",
+                    end_time: ""
+                }
+                this.$refs.popup.close()
+                this.http()
+            },
+            onSubmitScreen() {
+                this.page = 1
+                this.list = []
+                if (this.screen.start_time && this.screen.end_time) {
+                    let start = this.screen.start_time
+                    let end = this.screen.end_time
+                    if (Date.parse(start.replace(/-/g, '/')) > Date.parse(end.replace(/-/g, '/'))) {
+                        this.screen.start_time = end
+                        this.screen.end_time = start
+                    }
+                }
+                this.$refs.popup.close()
+                this.http()
+            },
+            showAddPop() {
+                let arr = this.list.filter(item => {
+                    return item.checked
+                })
+                console.log(arr)
+                if (arr.length > 0) {
+                    this.sendUserIds = arr.map(item => {
+                        return item.id
+                    })
+                    this.$refs.addPopup.open("bottom")
+                } else {
+                    uni.showToast({
+                        title: "请选择推送对象",
+                        icon: "none"
+                    })
+                }
+            },
+            onResetAdd() {
+                this.list.map(item => {
+                    item.checked = false
+                })
+                this.sendInfo = {
+                    textarea: "",
+                    integral: ""
+                }
+                this.$refs.addPopup.close()
+            },
+            onSubmitAdd() {
+                if (this.sendInfo.textarea == '' || this.sendInfo.integral == '') {
+                    uni.showToast({
+                        title: "请完善表单后提交",
+                        icon: "none"
+                    })
+                    return false
+                }
+                this.request({
+                    url: 'alipaycoupon/tuisoinglist',
+                    data: {
+                        admin_id: uni.getStorageSync("admin_id"),
+                        textarea: this.sendInfo.textarea,
+                        integral: this.sendInfo.integral,
+                        ids: this.sendUserIds.join(',')
+                    },
+                }).then(res => {
+                    if (res.code == 200) {
+                        uni.showModal({
+                            content: res.message,
+                            showCancel: false,
+                            success: (r) => {
+                                this.sendInfo = {
+                                    textarea: "",
+                                    integral: ""
+                                }
+                                this.$refs.addPopup.close()
+                                this.list = []
+                                this.page = 1
+                                this.http()
+                            }
+                        })
+                    } else {
+                        uni.showToast({
+                            title: res.message,
+                            icon: 'none'
+                        })
+                    }
+                }).catch(res => {
+                    uni.showToast({
+                        title: res.message,
+                        icon: 'none'
+                    })
+                })
+
+            },
+            previewImg(src) {
+                if (src) {
+                    uni.previewImage({
+                        urls: [src]
+                    });
+                }
+
+            },
+
+
+            http() {
+                let url = "alipaycoupon/gzh_list";
+                this.request({
+                    url,
+                    data: {
+                        admin_id: uni.getStorageSync("admin_id"),
+                        page: this.page,
+                        limit: 10,
+                        level: this.screen.level,
+                        tel: this.screen.tel,
+                        start_time: this.screen.start_time,
+                        end_time: this.screen.end_time,
+                    },
+                    showLoading: true,
+                }).then(res => {
+                    console.log(res, "res")
+                    if (res.code == 200) {
+                        let arr = res.data
+                        if (arr.length > 0) {
+                            arr.map(item => {
+                                item.checked = false
+                            })
+                            this.list = this.list.concat(arr);
+                            this.is_load = false
+
+                        } else {
+                            this.is_load = true
+                        }
+
+                    }
+                });
+            },
+
+
+
+
+        },
+    }
+</script>
+
+<style lang="scss">
+    page {
+        background: #F5F7FA;
+    }
+
+    .page-top {
+        background: #fff;
+        position: sticky;
+        top: 0;
+        z-index: 99;
+        padding: 10rpx 0;
+        box-shadow: 0 5rpx 10rpx #f0f0f0;
+    }
+
+    .item {
+        width: 690rpx;
+        background: #ffffff;
+        margin: 0 auto;
+        padding: 0rpx 24rpx;
+        opacity: 1;
+        border-radius: 8rpx;
+        box-shadow: 0rpx 6rpx 10rpx 0rpx rgba(213, 213, 213, 0.04);
+
+        .item-title {
+            opacity: 1;
+            font-size: 28rpx;
+            font-family: PingFang SC, PingFang SC-Medium;
+            font-weight: 500;
+            color: #333333;
+            padding: 24rpx 0;
+
+            .avatar {
+                display: block;
+                width: 48rpx;
+                height: 48rpx;
+                border-radius: 50%;
+                margin-right: 16rpx;
+            }
+
+        }
+
+        .item-bottom {
+            font-size: 26rpx;
+            padding: 20rpx 0 24rpx 0;
+            color: #666666;
+
+            .item-bottom-left {
+                width: 90rpx;
+                height: 90rpx;
+                margin-right: 24rpx;
+                min-width: 90rpx;
+                margin-bottom: 16rpx;
+            }
+
+            .item-bottom-right {
+                margin-bottom: 16rpx;
+
+                .item-bottom-number {
+                    color: #99A0AD;
+                }
+            }
+
+        }
+
+    }
+
+    .color-ffa {
+        color: #3387FF;
+    }
+
+    .icongengduo {
+        color: #999;
+        font-size: 24rpx;
+    }
+
+    .bottom-bar {
+        position: fixed;
+        bottom: 0px;
+        width: 100%;
+        z-index: 50;
+        background: #FFFFFF;
+        padding: 30rpx 0;
+        display: flex;
+        flex-flow: row nowrap;
+        justify-content: space-around;
+        align-items: center;
+    }
+
+    .bottom-bar .btn {
+
+        width: 300rpx;
+        height: 98rpx;
+        opacity: 1;
+        background: #04BE02;
+        border-radius: 49rpx;
+        box-shadow: 0rpx 0rpx 8rpx 0rpx rgba(51, 135, 255, 0.20);
+        opacity: 1;
+        font-size: 36rpx;
+        text-align: center;
+        line-height: 98rpx;
+        font-family: PingFang SC, PingFang SC-Medium;
+        font-weight: 500;
+        color: #ffffff;
+
+    }
+
+    .screen-pop {
+        background: #fff;
+        padding: 40rpx 0 0;
+        border-radius: 20rpx 20rpx 0 0;
+
+        .cell {
+            padding: 0 24rpx;
+            margin-bottom: 40rpx;
+
+            .label {
+                font-size: 30rpx;
+                color: #555;
+                width: 160rpx;
+            }
+
+            .desc {
+                margin-top: 30rpx;
+                background: #f4f5f6;
+                border-radius: 8rpx;
+                height: 88rpx;
+
+                .input-box {
+                    padding: 0 16rpx;
+                    height: 88rpx;
+                    font-size: 28rpx;
+                    color: #555;
+                }
+            }
+        }
+
+        .btns {
+            display: flex;
+            flex-flow: row nowrap;
+
+
+            .btn {
+                width: 50%;
+                height: 88rpx;
+                text-align: center;
+                line-height: 88rpx;
+                font-size: 32rpx;
+                font-weight: 500;
+            }
+
+            .reset-btn {
+                background-color: #F4F5F7;
+                color: #04BE02;
+            }
+
+            .submit-btn {
+                background-color: #04BE02;
+                color: #fff;
+            }
+        }
+
+        .tips {
+            margin-top: 16rpx;
+            font-size: 24rpx;
+            color: #f00;
+        }
+    }
+</style>

二进制
components/.DS_Store


+ 107 - 0
components/drag-sort/1px.less

@@ -0,0 +1,107 @@
+.setLine(@c: #eee) {
+  content: " ";
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 200%;
+  border: 1rpx solid @c;
+  color: @c;
+  height: 200%;
+  transform-origin: left top;
+  transform: scale(0.5);
+}
+
+.vh-1px, .vh-1px-t, .vh-1px-b, .vh-1px-tb, .vh-1px-l, .vh-1px-r {
+  position: relative;
+}
+
+.vh-1px {
+  &:before {
+    .setLine();
+  }
+}
+
+.vh-1px-t {
+  &:before {
+    .setTopLine();
+  }
+}
+
+.vh-1px-b {
+  &:after {
+    .setBottomLine();
+  }
+}
+
+.vh-1px-tb {
+  &:before {
+    .setTopLine();
+  }
+  &:after {
+    .setBottomLine();
+  }
+}
+
+.vh-1px-l {
+  &:before {
+    .setLeftLine();
+  }
+}
+
+.vh-1px-r {
+  &:after {
+    .setRightLine();
+  }
+}
+
+.setTopLine(@c: #eee) {
+  content: " ";
+  position: absolute;
+  left: 0;
+  top: 0;
+  right: 0;
+  height: 1rpx;
+  border-top: 1rpx solid @c;
+  color: @c;
+  transform-origin: 0 0;
+  transform: scaleY(0.5);
+}
+
+.setBottomLine(@c: #eee) {
+  content: " ";
+  position: absolute;
+  left: 0;
+  bottom: 0;
+  right: 0;
+  height: 1rpx;
+  border-bottom: 1rpx solid @c;
+  color: @c;
+  transform-origin: 0 100%;
+  transform: scaleY(0.5);
+}
+
+.setLeftLine(@c: #eee) {
+  content: " ";
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 1rpx;
+  bottom: 0;
+  border-left: 1rpx solid @c;
+  color: @c;
+  transform-origin: 0 0;
+  transform: scaleX(0.5);
+}
+
+.setRightLine(@c: #eee) {
+  content: " ";
+  position: absolute;
+  right: 0;
+  top: 0;
+  width: 1rpx;
+  bottom: 0;
+  border-right: 1rpx solid @c;
+  color: @c;
+  transform-origin: 100% 0;
+  transform: scaleX(0.5);
+}

+ 237 - 0
components/drag-sort/index.vue

@@ -0,0 +1,237 @@
+<template>
+  <movable-area class="drag-sort" :style="{height: currentListLength * height + 'px'}" id="drag">
+    <movable-view
+    v-for="(item, index) in currentList"
+    :key="index"
+    :x="0"
+    :y="item.y"
+    direction="vertical"
+    disabled
+    damping="40"
+    :animation="active !== index"
+    class="drag-sort-item"
+    style="height:55px"
+    :class="{'active': active === index, 'vh-1px-t': item.index > 0}">
+	  
+      <view @click="label(item.label)" class="item-content"  :class="avt==item.label?'act':''">{{item.label}}</view>
+	  
+      <view class="touch-tight">
+        <view class="ico_drag"></view>
+      </view>
+    </movable-view>
+    <movable-view
+    class="touch"
+    :x="2000"
+    @touchstart="touchstart"
+    @touchmove="touchmove"
+    @touchend="touchend"
+
+	></movable-view>
+  </movable-area>
+</template>
+
+<script>
+export default {
+  name: 'drag-sort',
+  mixins: [],
+  components: {},
+  data () {
+    return {
+      height: 55, // 高度
+      currentList: [],
+      active: -1, // 当前激活的item
+      itemIndex: 0, // 当前激活的item的原index
+      topY: 0, // 距离顶部的距离
+      deviationY: 0 ,// 偏移量
+	  avt:-1,
+    }
+  },
+  computed: {
+	  
+    currentListLength (){ 
+      return  3
+    }
+	
+  },
+  props: {
+    list: {
+      type: Array,
+      default: () => {
+        return []
+      }
+    },
+    props: {
+      type: Object,
+      default: () => {
+        return {
+          label: 'label',
+          value: 'value'
+        }
+      }
+    }
+  },
+  watch: {
+    list (val) {
+      this.onUpdateCurrentList()
+    }
+  },
+  created () {
+    this.onUpdateCurrentList()
+  },
+  mounted () {
+  },
+  updated () {},
+  filters: {},
+  methods: {
+    onUpdateCurrentList () {
+      let arr = []
+      for (const key in this.list) {
+        arr.push({
+          ...this.list[key],
+          index: Number(key),
+          y: key * this.height,
+          animation: true
+        })
+      }
+      this.currentList = arr
+    },
+    touchstart (e) {
+      // 计算y轴点击位置
+      var query = wx.createSelectorQuery().in(this)
+      query.select('#drag').boundingClientRect()
+      query.exec((res) => {
+        this.topY = res[0].top
+        let touchY = e.mp.touches[0].clientY - res[0].top
+        this.deviationY = touchY % this.height
+        // console.log(touchY)
+        for (const key in this.currentList) {
+          if ((this.currentList[key].index * this.height < touchY) && ((this.currentList[key].index + 1) * this.height > touchY)) {
+            this.active = Number(key)
+            this.itemIndex = this.currentList[key].index
+            break
+          }
+        }
+      })
+    },
+    touchmove (e) {
+      if (this.active < 0) return
+      let touchY = (e.mp.touches[0].clientY - this.topY) - this.deviationY
+      // console.log(touchY)
+      this.currentList[this.active].y = touchY
+      for (const key in this.currentList) {
+        // 跳过当前操作的item
+        if (this.currentList[key].index !== this.currentList[this.active].index) {
+          if (this.currentList[key].index > this.currentList[this.active].index) {
+            if (touchY > this.currentList[key].index * this.height - this.height / 2) {
+              this.currentList[this.active].index = this.currentList[key].index
+              this.currentList[key].index = this.currentList[key].index - 1
+              this.currentList[key].y = this.currentList[key].index * this.height
+              break
+            }
+          } else {
+            if (touchY < this.currentList[key].index * this.height + this.height / 2) {
+              this.currentList[this.active].index = this.currentList[key].index
+              this.currentList[key].index = this.currentList[key].index + 1
+              this.currentList[key].y = this.currentList[key].index * this.height
+              break
+            }
+          }
+        }
+      }
+    },
+
+    touchend (e) {
+      if ((this.itemIndex !== this.currentList[this.active].index) && (this.active > -1)) {
+		this.$emit('change', {
+          // 操作值
+          data: (() => {
+            let data = {
+              ...this.currentList[this.active]
+            }
+            delete data.index
+            delete data.y
+            delete data.animation
+            return data
+          })(),
+          // 插队的位置前面的值
+          frontData: (() => {
+            for (const iterator of this.currentList) {
+				// console.log(iterator,"99")
+              if (this.currentList[this.active].index - 1 === iterator.index) {
+                let data = {
+                  ...iterator
+                }
+                delete data.index
+                delete data.y
+                delete data.animation
+                return data
+              }
+            }
+          })()
+        })
+      }
+      this.currentList[this.active].animation = true
+      this.currentList[this.active].y = this.currentList[this.active].index * this.height
+      this.active = -1
+	  this.avt=-1
+    },
+	
+	label(index){
+		console.log(index,"dxc")
+		this.avt=index;
+	    this.$emit('bindlabel',index)
+	},
+	
+  }
+}
+</script>
+
+<style lang='less' scoped>
+@import "~./1px.less";
+.drag-sort {
+  width: 100%;
+}
+.drag-sort-item {
+  position: absolute !important;
+  display: flex;
+  align-items: center;
+  width: 100%;
+  padding: 0;
+  margin: 0;
+  background: #fff;
+  padding: 0 15px;
+  box-sizing: border-box;
+  .item-content {
+    flex: 1;    
+	margin-right: 40rpx;
+    padding: 30rpx;    
+	border-radius: 4rpx;
+  }
+  .touch-tight {
+    width: 24px;
+    display: flex;
+    justify-content: center;
+  }
+}
+.drag-sort-item .act{
+	background: #007AFF;
+   color: #FFFFFF;
+}
+
+
+.touch {
+  height: 100%;
+  width: 50px;
+}
+.ico_drag {
+  display: inline-block;
+  width: 24px;
+  height: 12px;
+  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAYCAYAAAC8/X7cAAAAAXNSR0IArs4c6QAAAEtJREFUWAnt1cEJACAMA0B1/506moIr5FEK51+Jl0d2Vd01+JzB2X90H5jeoPwECBDIBLYlzgDj25Y4JvQAAQIERgtY4u76LHF3Aw8rGQnK3sYAXQAAAABJRU5ErkJggg==) 0 0 no-repeat;
+  background-size: 100% auto;
+}
+.active {
+  box-shadow: 0 0 40rpx #DDDDDD;
+  z-index: 99;
+}
+</style>

+ 864 - 0
components/flow-pool/flow-pool.vue

@@ -0,0 +1,864 @@
+<template>
+	<view class="content">
+		<view class="box-pack-between ft32 item flex-y-center flex-grow-1" style="margin: 0;">
+			<text>模式设置</text>
+			<view class="ft24 item-off flex">
+				<view class="flex-grow-1 flex-center" @click="bindcheck(item.type)" :data-index="index" v-for="(item,index) of switch_list"
+				 :key="index" :class="item.type==moshi?'act':''">{{item.name}}</view>
+			</view>
+		</view>
+
+		<block v-if="moshi==2">
+
+			<view class="box-pack-between ft32 item flex-y-center flex-grow-1" style="margin: 0;">
+				<text>展示方式</text>
+				<view class="ft24 item-off flex">
+					<view class="flex-grow-1 flex-center" @click="bindtime(item.type)" :data-index="index" v-for="(item,index) of switch_time"
+					 :key="index" :class="item.type==moshi_type?'act':''">{{item.name}}</view>
+				</view>
+			</view>
+
+			<view class="item" v-if="moshi_type==1&&list_way.length>0">
+				<view class="por list_way-item" v-if="item.name&&item.checked" v-for="(item,index) of list_way" :key='index'>
+					<view class="flex-y-center">
+						<image class="list_way-item-del" @click="delScene(index)" src="../../static/images/del.png"></image>
+						<text class="">{{item.name}}</text>
+					</view>
+				</view>
+			</view>
+
+			<view class="item-bg" v-if="moshi_type==2">
+				<view class="mgr57">
+					<view class="box-pack-between" @click="getll">
+						<text class="item-bg-32">默认流量池</text>
+						<text class="iconfont icon-prev"></text>
+					</view>
+					<view style="margin-top: 20rpx;">
+						<view class="por list_way-item" style="background: #FFFFFF;" v-if="item.name&&item.checked" v-for="(item,index) of list_way"
+						 :key='index'>
+							<view class="flex-y-center">
+								<image class="list_way-item-del" @click="delScene(index)" :data-index='index' src="../../static/images/del.png"></image>
+								<text class="">{{item.name}}</text>
+							</view>
+						</view>
+					</view>
+				</view>
+
+				<view class="mgr40">
+					<view class="item-bg-32 box-pack-between" style="padding-bottom: 20rpx;">
+						<text>优先级</text>
+						<text class="enit" @click="enit" v-if="rule_val.length>0">重新编辑</text>
+					</view>
+					<view v-if="rule_val.length>0" class="main-home">
+						<view class="main-home-deta" v-for="(item,index) of rule_val" :key='index'>
+							<view class="box-pack-between">
+								<text class="text-1 wd80px">{{item.type==2?'周':item.type==3?'月':'天'}}</text>
+								<view class="text-1 wd180px"> {{item.type==1?item.val_name:item.val}}</view>
+								<view class="text-1 wd200px">{{item.powerpool_name}}</view>
+							</view>
+						</view>
+					</view>
+					<block v-else>
+						<dragSort :list="deta" :props="props" @bindlabel="bindTimeChange" @change="onDragSortChange"></dragSort>
+					</block>
+				</view>
+
+				<view class="main-home" v-if="deta_index=='天'">
+					<view class="main-home-deta" v-for="(item,index) of arr_time" :key='index'>
+						<view class="box-pack-between">
+							<text>{{item.time_name}}</text>
+							<text @click="addfn">{{item.fnname}}</text>
+							<image class="del" @click="del(index)" :data-title="item" src="../../static/images/del.png" mode=""></image>
+						</view>
+					</view>
+
+					<view class="ft26 flex-center" @click="addtime">
+						<view class="main-item">+添加时间 </view>
+					</view>
+				</view>
+
+				<view class="main-home" v-if="deta_index=='周'">
+					<view class="main-home-deta" v-for="(item,index) of week" :key='index'>
+						<view class="box-pack-between">
+							<text>{{item.week_name}}</text>
+							<text @click="addfn">{{item.fnname}}</text>
+							<image class="del" @click="del(index)" :data-title="item" src="../../static/images/del.png" mode=""></image>
+						</view>
+					</view>
+					<view class="ft26 flex-center" @click="addtime">
+						<view class="main-item">+添加星期</view>
+					</view>
+				</view>
+
+				<view class="main-home" v-if="deta_index=='月'">
+					<view class="main-home-deta" v-for="(item,index) of month" :key='index'>
+						<view class="box-pack-between">
+							<text>{{item.month_name}}</text>
+							<text @click="addfn">{{item.fnname}}</text>
+							<image class="del" @click="del(index)" :data-title="item" src="../../static/images/del.png" mode=""></image>
+						</view>
+					</view>
+					<view class="ft26 flex-center" @click="addtime">
+						<view class="main-item">+添加日期 </view>
+					</view>
+				</view>
+
+			</view>
+		</block>
+
+		<!-- 授权 -->
+		<zx-uni-popup ref="popup" type="bottom">
+			<view class="shoot">
+				<view class="flex shoot-header box-pack-between">
+					<text class="" @click="cancel">取消</text>
+					<text class="confirm" @click="confirm">确认</text>
+				</view>
+				<view class="flex">
+					<block v-if="deta_index=='天'">
+						<scroll-view scroll-y class="flex-grow-1 hg400">
+							<view class="header-item flex-center" :class="act_index1==index?'act':''" @click="choise1" :data-title="item"
+							 :data-index="index" :key="index" v-for="(item,index) of time_list1">
+								{{item}}
+							</view>
+						</scroll-view>
+						<scroll-view scroll-y class="flex-grow-1 hg400">
+							<view class="header-item flex-center" @click="choise2" :data-title="item" :data-index="index" :class="act_index2==index?'act':''"
+							 :key="index" v-for="(item,index) of time_list2">
+								{{item}}
+							</view>
+						</scroll-view>
+					</block>
+
+					<block v-if="deta_index=='周'">
+						<scroll-view scroll-y class="flex-grow-1 hg400">
+							<view class="header-item flex-center" @click="choise1" :data-num="item.num" :data-title="item.name" :data-index="index"
+							 :class="act_index1==index?'act':''" :key="index" v-for="(item,index) of week1">
+								{{item.name}}
+							</view>
+						</scroll-view>
+					</block>
+
+					<block v-if="deta_index=='月'">
+						<scroll-view scroll-y class="flex-grow-1 hg400">
+							<view class="header-item-month" @click="choise1" :data-num="item.num" :data-title="item.name" :data-index="index"
+							 :class="act_index1==index?'act':''" :key="index" v-for="(item,index) of month1">
+								<view class="flex-center">
+									{{item.name}}
+								</view>
+							</view>
+						</scroll-view>
+					</block>
+
+					<scroll-view :class="deta_index=='月'?'wd40':''" scroll-y class="flex-grow-1 hg400" bindscrolltolower="bindscrolltolower">
+						<view class="header-item text-1" @click="choise3" :data-title="item.name" :data-id="item.id" :data-index="index"
+						 :class="act_index3==index?'act':''" :key="index" v-for="(item,index) of list">
+							{{item.name}}
+						</view>
+					</scroll-view>
+
+				</view>
+			</view>
+		</zx-uni-popup>
+
+	</view>
+</template>
+
+<script>
+	import dragSort from '../../components/drag-sort/index.vue'
+	import zxUniPopup from '@/components/zx-uni-popup/uni-popup.vue';
+	export default {
+		components: {
+			dragSort,
+			zxUniPopup,
+		},
+
+		props: {
+			list_way: Array,
+			thismoshi: Number,
+			this_moshi_type: Number,
+			rule_arr_val: Array,
+		},
+
+		watch: {
+			thismoshi: {
+				deep: true, // 深度监听
+				handler(newVal, oldVal) {
+					this.moshi = newVal;
+				}
+			},
+			this_moshi_type: {
+				deep: true,
+				handler(newVal, oldVal) {
+					this.moshi_type = newVal;
+				}
+			},
+			rule_arr_val: {
+				deep: true,
+				handler(newVal, oldVal) {
+					var rule_arr = [];
+					for (var i of newVal) {
+						if (i.type == 1) {
+							var val_arr = i.val.split(",");
+							var pp = val_arr[0] + ':00' + '-' + val_arr[1] + ':00';
+							i.val_name = pp;
+						}
+						rule_arr.push(i.type + '-' + i.val + '-' + i.powerpool_id);
+					}
+					this.rule_val = newVal;
+					this.$emit('confirm', rule_arr.join(";"))
+				}
+			},
+		},
+
+		data() {
+			return {
+				rule_val: [],
+				moshi: this.thismoshi,
+				moshi_type: this.this_moshi_type,
+				switch_list: [{
+					name: "普通模式",
+					type: 1,
+				}, {
+					name: "高级模式",
+					type: 2,
+				}, ],
+				switch_time: [{
+						name: "时间",
+						type: 2,
+					},
+					{
+						name: "轮询",
+						type: 1,
+					},
+				],
+
+				props: {
+					label: 'label'
+				},
+
+				deta: [{
+						label: "天"
+					},
+					{
+						label: "周"
+					},
+					{
+						label: "月"
+					},
+				],
+				deta_index: -1,
+
+				time_list1: [
+					"01:00",
+					"02:00",
+					"03:00", "04:00", "05:00", "06:00", "07:00", "08:00", "09:00", "10:00", "11:00",
+					"12:00", "13:00", "14:00", "15:00", "16:00", "17:00", "18:00", "19:00", "20:00", "21:00", "22:00", "23:00",
+					"24:00",
+				],
+
+				time_list2: [
+					"01:00", "02:00", "03:00", "04:00", "05:00", "06:00", "07:00", "08:00", "09:00", "10:00", "11:00",
+					"12:00", "13:00", "14:00", "15:00", "16:00", "17:00", "18:00", "19:00", "20:00", "21:00", "22:00", "23:00",
+					"24:00",
+				],
+
+				week: [],
+				week1: [{
+						name: "星期日",
+						num: 7,
+					},
+					{
+						name: "星期一",
+						num: 1,
+					}, {
+						name: "星期二",
+						num: 2,
+					}, {
+						name: "星期三",
+						num: 3,
+					}, {
+						name: "星期四",
+						num: 4,
+					}, {
+						name: "星期五",
+						num: 5,
+					}, {
+						name: "星期六",
+						num: 6,
+					}
+				],
+				month: [],
+				month1: [{
+						name: 1,
+					}, {
+						name: 2
+					}, {
+						name: 3,
+					}, {
+						name: 4
+					}, {
+						name: 5,
+					}, {
+						name: 6
+					}, {
+						name: 7,
+					}, {
+						name: 8
+					}, {
+						name: 9,
+					}, {
+						name: 10
+					}, {
+						name: 11,
+					}, {
+						name: 12
+					}, {
+						name: 13,
+					},
+					{
+						name: 14
+					}, {
+						name: 15,
+					}, {
+						name: 16
+					}, {
+						name: 17,
+					}, {
+						name: 18
+					}, {
+						name: 19,
+					}, {
+						name: 20
+					}, {
+						name: 21,
+					}, {
+						name: 22
+					}, {
+						name: 23,
+					}, {
+						name: 24
+					}, {
+						name: 25,
+					}, {
+						name: 26
+					}, {
+						name: 27,
+					}, {
+						name: 28
+					}, {
+						name: 29
+					},
+					{
+						name: 30
+					}, {
+						name: 31
+					},
+
+				],
+				act_index1: -1,
+				act_index2: -1,
+				act_index3: -1,
+				time1: "",
+				time2: "",
+				fnname: "",
+				fnid: "",
+				arr_time: [],
+				time_arr: [],
+				list: [],
+				// moshi: 1,
+				// moshi_type: 2,
+				powerpool_id: "",
+				level: "",
+				// rule: "",
+				page: 1,
+				rule: [],
+				month_name: "",
+				deta: [{
+					label: "天",
+					level: 1,
+				}, {
+					label: "周",
+					level: 2
+				}, {
+					label: "月",
+					level: 3
+				}, ],
+				rule_arr: [],
+			}
+		},
+
+		computed: {
+
+		},
+
+		onShow(e) {
+			
+		},
+
+		onLoad() {
+
+		},
+
+		methods: {
+
+			enit(e) {
+				this.rule_val = [];
+				this.$emit('confirm', "")
+			},
+
+			onDragSortChange(e) {
+				var array = this.deta;
+				var label = e.data;
+				for (var i in array) {
+					if (array[i].label == e.data.label) {
+						array.splice(i, 1)
+					}
+				}
+				var arr = array;
+				if (e.frontData) {
+					for (var i in arr) {
+						if (arr[i].label == e.frontData.label) {
+							arr.splice(Number(i) + 1, 0, label);
+						}
+					}
+					this.deta = arr;
+				}
+				if (!e.frontData) {
+					array.unshift(label)
+					this.deta = array;
+				}
+				for (var i of this.deta) {
+					if (i.label == '天') {
+						i.level = 1
+					}
+					if (i.label == '周') {
+						i.level = 2
+					}
+					if (i.label == '月') {
+						i.level = 3
+					}
+				}
+				this.$emit('bindlevel', this.deta)
+			},
+
+
+			addfn(e) {
+
+			},
+
+			bindscrolltolower(e) {
+				this.http();
+			},
+
+			http() {
+				this.request({
+					url: "powerpool/poollists",
+					data: {
+						page: this.page,
+						token: uni.getStorageSync("token"),
+					},
+				}).then(res => {
+					if (res.code === '200') {
+						for (var i of res.data) {
+							i.checked = false;
+						}
+						this.list = this.list.concat(res.data);
+						this.page = this.page + 1;
+					}
+				})
+			},
+
+			del(index) {
+				if (this.deta_index == '天') {
+					this.arr_time.splice(index, 1)
+				}
+				if (this.deta_index == '周') {
+					this.week.splice(index, 1)
+				}
+				if (this.deta_index == '月') {
+					this.month.splice(index, 1);
+				}
+				this.publue()
+			},
+
+
+			delScene(index) {
+				this.$emit('ondel', index)
+			},
+
+			cancel() {
+				this.$refs.popup.close();
+			},
+
+			addtime(e) {
+				this.page = 1;
+				this.list = [];
+				this.http();
+				this.$refs.popup.open();
+			},
+
+			choise1(e) {
+				let index = e.currentTarget.dataset.index,
+					title = e.currentTarget.dataset.title;
+				this.time1 = title;
+				this.act_index1 = index;
+				if (this.deta_index == '周') {
+					var num = e.currentTarget.dataset.num;
+					this.num = num;
+					this.week_name = title;
+				}
+
+				if (this.deta_index == '月') {
+					this.month_name = title;
+				}
+
+			},
+
+			choise2(e) {
+				let index = e.currentTarget.dataset.index,
+					title = e.currentTarget.dataset.title;
+				this.time2 = title;
+				this.act_index2 = index;
+			},
+
+			choise3(e) {
+				let id = e.currentTarget.dataset.id,
+					index = e.currentTarget.dataset.index,
+					title = e.currentTarget.dataset.title;
+				this.fnname = title;
+				this.fnid = id;
+				this.act_index3 = index;
+			},
+
+			confirm(e) {
+				if (!this.fnid) {
+					uni.showToast({
+						title: "请选择记录",
+						icon: 'none'
+					})
+					return
+				}
+				if (this.deta_index == '周') {
+					this.week.push({
+						level: 2,
+						week_name: this.week_name,
+						time: this.num,
+						fnid: this.fnid,
+						fnname: this.fnname,
+					})
+				} else if (this.deta_index == '月') {
+					this.month.push({
+						level: 3,
+						month_name: this.month_name,
+						fnid: this.fnid,
+						fnname: this.fnname,
+						time: this.month_name,
+					})
+				} else {
+					var time_sting = parseInt(this.time1) + "," + parseInt(this.time2);
+					var time = this.time1 + "-" + this.time2;
+					this.arr_time.push({
+						level: 1,
+						time_name: time,
+						time: time_sting,
+						fnid: this.fnid,
+						fnname: this.fnname,
+					});
+					//展示
+					this.time_arr.push(time_sting);
+					this.check_time(JSON.stringify(this.time_arr));
+				}
+				this.publue()
+			},
+			publue() {
+				var arr3;
+				if (this.deta[0].level == 1 && this.deta[1].level == 2 && this.deta[2].level == 3) {
+					arr3 = [...this.arr_time, ...this.week, ...this.month];
+				}
+
+				if (this.deta[0].level == 1 && this.deta[1].level == 3 && this.deta[2].level == 2) {
+
+					arr3 = [...this.arr_time, ...this.month, ...this.week];
+
+				}
+
+				if (this.deta[0].level == 2 && this.deta[1].level == 1 && this.deta[2].level == 3) {
+					arr3 = [...this.week, ...this.arr_time, ...this.month];
+				}
+				if (this.deta[0].level == 2 && this.deta[1].level == 3 && this.deta[2].level == 1) {
+					arr3 = [...this.week, ...this.month, ...this.arr_time];
+				}
+
+				if (this.deta[0].level == 3 && this.deta[1].level == 1 && this.deta[2].level == 2) {
+					arr3 = [...this.month, ...this.arr_time, ...this.week];
+				}
+
+				if (this.deta[0].level == 3 && this.deta[1].level == 2 && this.deta[2].level == 1) {
+					arr3 = [...this.month, ...this.week, ...this.arr_time];
+				}
+				var rule_arr = [];
+				for (var i of arr3) {
+					rule_arr.push(i.level + '-' + i.time + '-' + i.fnid);
+				}
+				// this.rule_arr = rule_arr.join(";");
+				this.$emit('confirm', rule_arr.join(";"))
+				this.$refs.popup.close();
+			},
+
+
+			check_time(arr) {
+				this.request({
+					url: "videofuneng/check_time",
+					data: {
+						time: arr,
+					},
+				}).then(res => {
+					if (res.code === '200') {
+
+					}
+				}).catch(res => {
+					this.arr_time.pop();
+					this.time_arr.pop();
+					uni.showToast({
+						title: res.message,
+						icon: 'none'
+					})
+				});
+			},
+
+			// 模式
+			bindcheck(index) {
+				this.moshi = index;
+				this.$emit('oncheck', index)
+			},
+
+			// 优先级 天,
+			bindTimeChange(index) {
+				this.act_index1 = -1;
+				this.act_index2 = -1;
+				this.act_index3 = -1;
+				this.time1 = "";
+				this.time2 = "";
+				this.fnname = "";
+				this.fnid = "";
+				this.deta_index = index;
+			},
+
+			getll() {
+				this.$emit('onTime', 3)
+			},
+
+			bindtime(index) {
+				this.moshi_type = index;
+				this.$emit('onTime', index)
+			},
+		},
+	}
+</script>
+
+<style>
+	.item {
+		padding: 32rpx 40rpx;
+	}
+
+	.wd80px {
+		width: 80rpx;
+		text-align: center;
+	}
+
+	.wd180px {
+		width: 180rpx;
+		text-align: center;
+	}
+
+	.wd200px {
+		width: 200rpx;
+		text-align: center;
+	}
+
+	.shoot {
+		height: 500rpx;
+		background: #FFFFFF;
+	}
+
+	.header-item {
+		padding: 10rpx 0;
+		/* height: 70rpx; */
+		text-align: center;
+	}
+
+	.header-item-month {
+		height: 70rpx;
+		display: inline-block;
+		width: 100rpx;
+	}
+
+	.header-item-month view {
+		height: 100%;
+	}
+
+	.shoot .wd40 {
+		width: 40%;
+	}
+
+	.hg400 {
+		height: 400rpx;
+	}
+
+	.shoot-header {
+		padding: 20rpx;
+		border-bottom: 1rpx solid #f1f1f1;
+	}
+
+	.confirm {
+		color: #007AFF;
+	}
+
+	.shoot .act {
+		color: #007AFF;
+	}
+
+	.main-home {
+		padding: 20rpx 30rpx;
+		background: #FFFFFF;
+		border-radius: 12rpx;
+		margin: 0 auto;
+		font-size: 28rpx;
+		font-family: PingFang SC, PingFang SC-Regular;
+		font-weight: 400;
+		color: #333333;
+		margin-bottom: 20rpx;
+	}
+
+	.del {
+		width: 32rpx;
+		height: 32rpx;
+	}
+
+	.main-item {
+		color: #3387ff;
+		border: 2rpx solid #3387ff;
+		padding: 6rpx 10rpx;
+		margin: 0 auto;
+		display: inline-block;
+		border-radius: 4rpx;
+	}
+
+	.moshi_level .act {
+		background: #3387ff;
+		;
+		color: #FFFFFF;
+		border: 1rpx solid #3387ff;
+	}
+
+	.main-home-deta {
+		margin-bottom: 20rpx;
+	}
+
+	.mgr40 {
+		margin-bottom: 40rpx;
+	}
+
+	.enit {
+		padding: 8rpx 10rpx;
+		border: 1rpx solid #ccc;
+		font-size: 22rpx;
+	}
+
+	.qr_content {
+		padding: 0 40rpx;
+	}
+
+	.qr_content_img {
+		display: inline-block;
+		position: relative;
+	}
+
+	.qr_content_img .qr_content_img_li {
+		margin-left: 20rpx;
+		width: 120rpx;
+		height: 120rpx;
+	}
+
+	.qr_content_img_del {
+		width: 40rpx;
+		height: 40rpx;
+		position: absolute;
+		top: 0;
+		right: 0;
+	}
+
+	.tr {
+		text-align: right;
+	}
+
+	.pdr-20 {
+		padding-right: 20rpx;
+	}
+
+	.item {
+		padding: 32rpx 40rpx;
+	}
+
+	.upimg {
+		width: 126rpx;
+		height: 126rpx;
+	}
+
+	.add-home {
+		color: #FFFFFF;
+		width: 126rpx;
+		height: 54rpx;
+		background: linear-gradient(315deg, #3387ff 2%, #569bff 99%);
+		border-radius: 8rpx;
+		box-shadow: 0px 0px 8rpx 0px rgba(51, 135, 255, 0.2);
+	}
+
+	.item-bg {
+		width: 670rpx;
+		/* height: 298rpx; */
+		background: #f6f8fe;
+		border-radius: 12rpx;
+		margin: 0 auto;
+		font-size: 28rpx;
+		font-family: PingFang SC, PingFang SC-Regular;
+		font-weight: 400;
+		color: #333333;
+		padding: 36rpx 32rpx;
+	}
+
+	.item-del {
+		width: 40rpx;
+		height: 40rpx;
+	}
+
+	.mar64 {
+		margin-bottom: 64rpx;
+	}
+
+	.item-bg .mar64:last-child {
+		margin-bottom: 0rpx;
+	}
+
+	.hg200rpx {
+		height: 100rpx;
+	}
+
+	.mgr57 {
+		margin-bottom: 57rpx;
+	}
+
+	.item-bg-32 {
+		margin-right: 32rpx;
+	}
+
+	.qrupimg {
+		width: 80rpx;
+		height: 80rpx;
+	}
+
+	.tips {
+		font-size: 26rpx;
+		color: #999;
+	}
+</style>

+ 124 - 0
components/header/header-title.vue

@@ -0,0 +1,124 @@
+<template>
+	<view class="header">
+		<image src="../../static/images/skm_fn_bg.png" mode="aspectFill" class="bg-img"></image>
+		<view class="info-block flex-row-between">
+			<view class="info">
+				<view class="title">{{title}}</view>
+				<view class="desc">{{$test.$desc}}</view>
+			</view>
+
+			<view v-if="title=='收款码'+$test.$test" @click="look" class="btn flex-center">查看指引 <image class="zhiyin" src="../../static/images/zhiyin.png"
+				 mode=""></image>
+			</view>
+
+			<view v-if="title=='普通二维码'+$test.$test" @click="lookCode" class="btn flex-center">查看指引 <image class="zhiyin" src="../../static/images/zhiyin.png"
+				 mode=""></image>
+			</view>
+
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+
+		name: 'headerTitle',
+		props: {
+			title: {
+				type: String,
+				default () {
+					return ""
+				},
+			}
+		},
+		data() {
+			return {
+		       $test:this.$test.$test,
+			}
+		},
+		methods: {
+			look() {
+				uni.showModal({
+					title: '温馨提示',
+					content: '上传多张收款码视为多码合一,请勿上传第三方聚合收款码。多码合一只支持支付宝收款二维码、云闪付钱包收款二维码',
+					showCancel: false,
+					cancelText: '',
+					confirmText: '好的',
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+			lookCode() {
+				uni.showModal({
+					title: '温馨提示',
+					content: `图片${this.$test.$test}只支持能有效进行访问的网址链接,非网址链接的二维码,不建议进行${this.$test.$test}操作。`,
+					showCancel: false,
+					cancelText: '',
+					confirmText: '好的',
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+
+		}
+	}
+</script>
+
+<style>
+	.header {
+		width: 100%;
+		height: 198rpx;
+		position: relative;
+	}
+
+	.header .bg-img {
+		display: block;
+		position: absolute;
+		left: 0;
+		top: 0;
+		z-index: -1;
+		width: 100%;
+		height: 198rpx;
+
+	}
+
+	.header .info-block {
+		padding: 0 40rpx 0 48rpx;
+		height: 198rpx;
+	}
+
+	.header .info-block .title {
+		font-size: 36rpx;
+		color: #fff;
+		font-weight: 500;
+		line-height: 50rpx;
+	}
+
+	.header .info-block .desc {
+		font-size: 28rpx;
+		font-weight: 500;
+		color: #fff;
+		line-height: 40rpx;
+		margin-top: 8rpx;
+	}
+
+	.header .info-block .btn {
+		width: 176rpx;
+		height: 56rpx;
+		border: 2rpx solid #fff;
+		border-radius: 28rpx;
+		text-align: center;
+		line-height: 52rpx;
+		font-size: 28rpx;
+		font-weight: 500;
+		color: #fff;
+	}
+
+	.zhiyin {
+		width: 28rpx;
+		height: 28rpx;
+		margin-left: 6rpx;
+	}
+</style>

+ 175 - 0
components/liuyuno-tabs/liuyuno-tabs.vue

@@ -0,0 +1,175 @@
+<template>
+	<view class="tab-box" id="tab-box" v-if="tabList.length > 0">
+		<view class="horizontal">
+			<scroll-view :scroll-x="true" style="white-space: nowrap; display: flex;" scroll-with-animation 
+			:scroll-left="slider.scrollLeft">
+				<view class="flex-y-center">
+					<block v-for="(item, index) in tabList" :key="index">
+						<view class="flex-grow-1 flex-center">
+							<view class="item" :class="{ active: activeIndex === index }" :id="'tab_'+index"
+							 @click="tabClick(index)">{{ item.text || item }}
+							</view>
+						</view>
+					</block>
+				</view>
+				<view class="underline" :style="'transform:translateX(' + slider.left + 'px);width:' + slider.width + 'px'"></view>
+			</scroll-view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'liuyuno-tabs',
+		props: {
+			tabData: {
+				type: Array,
+				default: () => []
+			},
+			defaultIndex: {
+				type: Number,
+				default: 0
+			},
+			underLinePadding: {
+				type: Number,
+				default: 10
+			},
+		},
+		data() {
+			return {
+				tabList: [],
+				tabListSlider: [],
+				box: {
+					left: 0,
+					right: 0,
+					top: 0,
+					width: 0,
+					height: 0,
+					bottom: 0,
+				},
+				
+				slider: {
+					left: 0,
+					width: 0,
+					scrollLeft: 0
+				},
+				
+				activeIndex: 0
+			};
+		},
+		watch: {
+			tabData(value) {
+				this.tabList = value;
+				setTimeout(() => {
+					this.updateTabWidth();
+				}, 500);
+			},
+		},
+		mounted() {
+			this.tabList = this.tabData;
+			this.activeIndex = this.defaultIndex;
+			setTimeout(() => {
+
+				const query = uni.createSelectorQuery().in(this);
+				query.select('.tab-box').boundingClientRect((res) => {
+					console.log(res)
+					this.box = res;
+					this.updateTabWidth();
+				}).exec();
+
+			}, 500);
+
+		},
+		methods: {
+
+			tabClick(index) {
+				this.activeIndex = index;
+				this.tabToIndex(index);
+				this.$emit('tabClick', index);
+			},
+
+			tabToIndex(index) {
+				let _slider = this.tabListSlider[index];
+				this.slider = {
+					        left: _slider.left  + (_slider.width / 2) - (_slider.width / 4),
+					        width: (_slider.width) / 2,
+					        scrollLeft: _slider.scrollLeft,
+					// left: _slider.left + this.underLinePadding,
+					// width: _slider.width - this.underLinePadding * 2,
+					// scrollLeft: _slider.scrollLeft,
+				}
+				
+			},
+
+			updateTabWidth(index = 0) {
+				let data = this.tabList;
+
+				if (data.length == 0) return false;
+
+				const query = uni.createSelectorQuery().in(this);
+
+				query.select('#tab_' + index).boundingClientRect((res) => {
+					let _prev_slider = this.tabListSlider[index - 1];
+					this.tabListSlider[index] = {
+						left: res.left - this.box.left,
+						width: res.width,
+						scrollLeft: res.left - this.box.left - (_prev_slider ? _prev_slider.width : 0),
+					}
+
+					if (this.activeIndex == index) {
+						this.tabToIndex(this.activeIndex);
+					}
+
+					index++;
+					if (data.length > index) {
+						this.updateTabWidth(index);
+					}
+				}).exec();
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.tab-box {
+		width: 100%;
+		color: rgba(0, 0, 0, 0.8);
+		display: flex;
+		height:100rpx;
+		background: #fff;
+		font-size: 28upx;
+		box-shadow: 0 1px 5px rgba(0, 0, 0, 0.06);
+		position: relative;
+		z-index: 10;
+		overflow: hidden;
+	}
+
+	.horizontal .active {
+		color: #000;
+	}
+
+	.horizontal {
+		width: 100%;
+	}
+
+	.wd33 {
+		width: 33%;
+	}
+
+	.item {
+		display: inline-block;
+		text-align: center;
+		padding: 0 30upx;
+		height: 80rpx;
+		line-height: 90upx;
+		font-size: 32rpx;
+		color: #A0A0A0;
+	}
+
+	.underline {
+		height: 4upx;
+		background-color:#000;
+		border-radius: 3px;
+		transition: .5s;
+	}
+</style>

+ 188 - 0
components/module/short_video.vue

@@ -0,0 +1,188 @@
+<template>
+	<view class="video_box">
+		<video v-if="play"
+		    x5-video-player-type="h5-page" webkit-playsinline="true"
+		    x5-video-orientation="portraint"
+			class="video_file"
+			:id="`video_${src}`"
+			:ref="`video_${src}`"
+			:src="src"
+			loop
+			:show-play-btn="false"
+			:show-center-play-btn="false"
+			:controls="false"
+			:enable-progress-gesture="false"
+			object-fit="contain"
+			:autoplay="play"
+			@timeupdate="onScheduleChange"
+			@waiting="onWaiting"
+		></video>
+		<image v-else class="video_file" src="../../static/images/template.png" mode=""></image>
+		<!-- 播放按钮 -->
+		<view class="play_btn" @click="onPlay">
+			<image class="icon_play" v-if="playState == 1000" src="../../static/images/ic_play.png" mode="aspectFit"></image>
+			</view>
+		<view class="play_schedule">
+			<view class="schedule" :style="{ width: schedule + '%' }"><view v-if="progressDrag" class="progress_drag_dot"></view></view>
+		</view>
+
+	</view>
+</template>
+
+<script>
+export default {
+	props: {
+		src: {
+			type: String,
+			default: ''
+		},
+		play: {
+			type: Boolean,
+			default: false
+		},
+		poster: {
+			//视频封面的图片
+			type: String,
+			default: ''
+		},
+		progress: {
+			type: Number,
+			default: 0
+		},
+		progressValue: {
+			type: Number,
+			default: 0
+		}
+	},
+	data() {
+		return {
+			schedule: 0,
+			// 1000 待播放
+			// 2000 播放中
+			// 3000 播放缓冲中
+			playState: 1000,
+			// 是否拖动进度
+			progressDrag: false,
+			// 视频总长度
+			duration: 0
+		};
+	},
+	watch: {
+		
+		play(val) {
+			// console.log(val,"watch")
+			if (val) {
+				setTimeout(() => {
+					this.videoCtx.play();
+					this.playState = 2000;
+				}, 300);
+			} else {
+				setTimeout(() => {
+					this.videoCtx.pause();
+					this.videoCtx.seek(0);
+					this.playState = 1000;
+					this.schedule = 0;
+				},100);
+			}
+		},
+		
+		progress(val) {
+			if (this.play) {
+				if (val == 0) {
+					this.progressDrag = true;
+				} else {
+					this.schedule = val;
+				}
+			}
+		},
+		progressValue(val) {
+			if (this.play) {
+				this.schedule = val;
+				this.progressDrag = false;
+				this.videoCtx.seek(this.duration * (val / 100));
+			}
+		}
+	},
+	mounted() {
+		this.videoCtx = uni.createVideoContext(`video_${this.src}`, this);
+		// this.videoCtx.requestFullScreen();
+		if(this.play){
+			this.playState = 2000;
+		}
+	},
+	methods: {
+		onScheduleChange(e) {
+			this.duration = e.detail.duration;
+			if (!this.progressDrag) {
+				this.schedule = (e.detail.currentTime / e.detail.duration) * 100;
+			}
+		},
+		onPlay() {
+			if (this.playState == 2000) {
+				this.videoCtx.pause();
+				this.playState = 1000;
+			} else if (this.playState == 1000) {
+				this.videoCtx.play();
+				this.playState = 2000;
+			} else if (this.playState == 3000) {
+				this.videoCtx.play();
+				this.playState = 2000;
+			}
+		},
+		// 视频进入缓冲中
+		onWaiting() {
+			this.playState = 3000;
+		}
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+// @import '@/style/mixin.scss';
+.video_box {
+	position: relative;
+	width: 100%;
+}
+
+.video_file {
+	width: 100%;
+	height: calc(100vh - var(--window-bottom));
+}
+.play_schedule {
+	position: absolute;
+	bottom: 6rpx;
+	left: 0;
+	height: 2rpx;
+	width: 100%;
+	background-color: rgba(255, 255, 255, 0.2);
+	z-index: 3;
+}
+.schedule {
+	background-color: #fff;
+	height: 2rpx;
+	width: 0%;
+	position: relative;
+}
+.progress_drag_dot {
+	position: absolute;
+	right: -8rpx;
+	top: -6rpx;
+	width: 16rpx;
+	height: 16rpx;
+	border-radius: 50%;
+	background-color: #fff;
+}
+.play_btn {
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+	justify-content: center;
+	align-items: center;
+}
+.icon_play {
+	width: 90rpx;
+	height: 90rpx;
+}
+</style>

+ 105 - 0
components/page-btm-bar/page-btm-bar.vue

@@ -0,0 +1,105 @@
+<template>
+	<view class="container">
+		<view class="content">
+			<view class="item" :class="active == 1?'active':''" @click="navTo(1,'/pages/index/index')">
+				<i class="iconfont" :class="active == 1?'iconxuanzhongshouye':'iconxuanzhongshouye-2'"></i>
+				<text class="title">首页</text>
+			</view>
+			<view class="item" :class="active == 2?'active':''" @click="navTo(2,'/pages/jiaocheng/jiaocheng')">
+				<i class="iconfont" :class="active == 2?'iconzixunxuanzhong':'iconzixunweixuanzhong'"></i>
+				<text class="title">教程</text>
+			</view>
+			<view class="item" :class="active == 3?'active':''" @click="navTo(3,'/pages/my/my')">
+				<i class="iconfont" :class="active == 3?'iconwodeweixuanzhong-2':'iconwodeweixuanzhong'"></i>
+				<text class="title">我的</text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props: {
+			active: {
+				type: Number,
+				default: 1
+			}
+		},
+		data() {
+			return {
+
+			};
+		},
+		methods: {
+			navTo(index, url) {
+				if (index != this.active) {
+					uni.reLaunch({
+						url: url
+					})
+				}
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	@import url("/static/css/iconfont.css");
+
+	.container {
+		width: 100%;
+		height: 100rpx;
+		/*兼容 IOS<11.2*/
+		padding-bottom: constant(safe-area-inset-bottom);
+		/*兼容 IOS>11.2*/
+		padding-bottom: env(safe-area-inset-bottom);
+	}
+
+	.content {
+		background-color: #fff;
+		width: 100vw;
+		height: 100rpx;
+		/*兼容 IOS<11.2*/
+		padding-bottom: constant(safe-area-inset-bottom);
+		/*兼容 IOS>11.2*/
+		padding-bottom: env(safe-area-inset-bottom);
+		display: flex;
+		flex-flow: row nowrap;
+		justify-content: space-around;
+		align-items: center;
+		box-shadow: 0 20rpx 20rpx #f6f6f6 inset;
+		position: fixed;
+		left: 0;
+		bottom: 0;
+		z-index: 900;
+	}
+
+	.content .item {
+		flex: auto;
+		display: flex;
+		flex-flow: column nowrap;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.content .iconfont {
+		display: block;
+		font-size: 48rpx;
+		color: #8a8a8a;
+	}
+
+	.content .active .iconfont {
+		color: #3387FF;
+	}
+
+	.content .title {
+		font-size: 24rpx;
+		height: 28rpx;
+		line-height: 28rpx;
+		text-align: center;
+		color: #8a8a8a;
+	}
+
+	.content .active .title {
+		color: #3387FF;
+	}
+</style>

+ 165 - 0
components/u-charts/component.vue

@@ -0,0 +1,165 @@
+<template>
+	<canvas v-if="canvasId" :id="canvasId" :canvasId="canvasId" :style="{'width':cWidth*pixelRatio+'px','height':cHeight*pixelRatio+'px', 'transform': 'scale('+(1/pixelRatio)+')','margin-left':-cWidth*(pixelRatio-1)/2+'px','margin-top':-cHeight*(pixelRatio-1)/2+'px'}"
+	 @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd" @error="error">
+	</canvas>
+</template>
+
+<script>
+	import uCharts from './u-charts.min.js';
+	var canvases = {};
+	
+	export default {
+		props: {
+			chartType: {
+				required: true,
+				type: String,
+				default: 'column'
+			},
+			opts: {
+				required: true,
+				type: Object,
+				default () {
+					return null;
+				},
+			},
+			canvasId: {
+				type: String,
+				default: 'u-canvas',
+			},
+			cWidth: {
+				default: 375,
+			},
+			cHeight: {
+				default: 250,
+			},
+			pixelRatio: {
+				type: Number,
+				default: 1,
+			},
+		},
+		mounted() {
+			this.init();
+		},
+		methods: {
+			init() {
+				switch (this.chartType) {
+					case 'column':
+						this.initColumnChart();
+						break;
+					case 'line':
+						this.initLineChart();
+						break;
+					default:
+						break;
+				}
+			},
+			initColumnChart() {
+				canvases[this.canvasId] = new uCharts({
+					$this: this,
+					canvasId: this.canvasId,
+					type: 'column',
+					legend: true,
+					fontSize: 11,
+					background: '#FFFFFF',
+					pixelRatio: this.pixelRatio,
+					animation: true,
+					categories: this.opts.categories,
+					series: this.opts.series,
+					enableScroll: true,
+					xAxis: {
+						disableGrid: true,
+						itemCount: 4,
+						scrollShow: true
+					},
+					yAxis: {
+						//disabled:true
+					},
+					dataLabel: true,
+					width: this.cWidth * this.pixelRatio,
+					height: this.cHeight * this.pixelRatio,
+					extra: {
+						column: {
+							type: 'group',
+						}
+					}
+				});
+			},
+			initLineChart() {
+				canvases[this.canvasId] = new uCharts({
+					$this: this,
+					canvasId: this.canvasId,
+					type: 'line',
+					fontSize: 11,
+					legend: true,
+					dataLabel: false,
+					dataPointShape: true,
+					background: '#FFFFFF',
+					pixelRatio: this.pixelRatio,
+					categories: this.opts.categories,
+					series: this.opts.series,
+					animation: true,
+					enableScroll: true,
+					xAxis: {
+						type: 'grid',
+						gridColor: '#CCCCCC',
+						gridType: 'dash',
+						dashLength: 8,
+						itemCount: 4,
+						scrollShow: true
+					},
+					yAxis: {
+						gridType: 'dash',
+						gridColor: '#CCCCCC',
+						dashLength: 8,
+						splitNumber: 5,
+						min: 10,
+						max: 180,
+						format: (val) => {
+							return val.toFixed(0) + '元'
+						}
+					},
+					width: this.cWidth * this.pixelRatio,
+					height: this.cHeight * this.pixelRatio,
+					extra: {
+						line: {
+							type: 'straight'
+						}
+					}
+				});
+			},
+			// 这里仅作为示例传入两个参数,cid为canvas-id,newdata为更新的数据,需要更多参数请自行修改
+			changeData(cid,newdata) {
+				canvases[cid].updateData({
+					series: newdata.series,
+					categories: newdata.categories
+				});
+			},
+			touchStart(e) {
+				canvases[this.canvasId].showToolTip(e, {
+					format: function(item, category) {
+						return category + ' ' + item.name + ':' + item.data
+					}
+				});
+				canvases[this.canvasId].scrollStart(e);
+			},
+			touchMove(e) {
+				canvases[this.canvasId].scroll(e);
+			},
+			touchEnd(e) {
+				canvases[this.canvasId].scrollEnd(e);
+			},
+			error(e) {
+				// console.log(e)
+			}
+		},
+	};
+</script>
+
+<style scoped>
+	.charts {
+		width: 100%;
+		height: 100%;
+		flex: 1;
+		background-color: #FFFFFF;
+	}
+</style>

文件差异内容过多而无法显示
+ 0 - 0
components/u-charts/u-charts.min.js


+ 198 - 0
components/uni-scroll/uni-scroll.vue

@@ -0,0 +1,198 @@
+<template>
+	<view class="content">
+		<view class="popup-content">
+			<view class="box-pack-between ft32 flex-center popup-content-title">
+				<text @click="close">关闭</text>
+				<text style="color: #003A9B;" @click="confirm">确认</text>
+			</view>
+			<view class="flex">
+				
+				<scroll-view scroll-y class="popup-content-scroll">
+					<view @click="bindProv" :data-title="item.city_name" :data-code="item.cityid" :class="item.cityid==Prov_code?'act':''"
+					 class="popup-content-scroll-li flex-center" v-for="(item,index) of Prov_arr" :key='index'>
+						{{item.city_name}}
+					</view>
+				</scroll-view>
+				
+				<scroll-view scroll-y class="popup-content-scroll">
+					<block v-if="City_arr.length>0">
+						<view @click="bindCity" :data-title="item.city_name" :class="item.cityid==City_code?'act':''" :data-code="item.cityid"
+						 class="popup-content-scroll-li flex-center " v-for="(item,index) of City_arr" :key='index'>
+							{{item.city_name}}
+						</view>
+					</block>
+					<view v-else class="City  popup-content-scroll-li flex-center">
+						请选择
+					</view>
+				</scroll-view>
+                <scroll-view scroll-y class="popup-content-scroll">
+                	<block v-if="Dist_arr.length>0">
+                		<view @click="bindDist" :data-title="item.city_name" :class="item.cityid==Dist_code?'act':''" :data-code="item.cityid"
+                		 class="popup-content-scroll-li flex-center " v-for="(item,index) of Dist_arr" :key='index'>
+                			{{item.city_name}}
+                		</view>
+                	</block>
+                	<view v-else class="City  popup-content-scroll-li flex-center">
+                		请选择
+                	</view>
+                </scroll-view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'uniScroll',
+		props: {
+			Prov_arr: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			type: {
+				type: Number,
+				default: 1,
+			},
+		},
+		inject: ['popup'],
+		data() {
+			return {
+				City_arr: [],
+				Dist_arr: [],
+				Prov_code: "",
+				City_code: "",
+				Dist_code: "",
+
+				Prov_title1: "",
+				City_title1: "",
+				Dist_title1: "",
+				Prov_title: "",
+				City_title: "",
+				Dist_title: "",
+			}
+		},
+		
+		onLoad() {
+
+		},
+
+		methods: {
+			// 商户地址省
+			bindProv(e) {
+				this.Prov_code = e.currentTarget.dataset.code;
+				this.Prov_title1 = e.currentTarget.dataset.title;
+				this.Dist_arr = [];
+				this.Dist_code = "";
+				this.City();
+			},
+			
+			// 商户地址市
+			bindCity(e) {
+				this.City_code = e.currentTarget.dataset.code;
+				this.City_title1 = e.currentTarget.dataset.title;
+				this.Dist_code = "";
+				this.Dist();
+			},
+			
+			// 商户地址区
+			bindDist(e) {
+				this.Dist_title1 = e.currentTarget.dataset.title;
+				this.Dist_code = e.currentTarget.dataset.code;
+			},
+			
+			close(e) {
+				this.popup.close();
+			},
+
+			confirm(e) {
+				let info;
+				
+				if (!this.City_code) {
+					uni.showToast({
+						title: "请选择市",
+						icon: "none"
+					})
+					return
+				}
+		
+				info = {
+						Prov_code: this.Prov_code,
+						City_code: this.City_code,
+						Dist_code: this.Dist_code,
+						Prov_title: this.Prov_title1,
+						City_title: this.City_title1,
+						Dist_title: this.Dist_title1,
+				}
+					
+				console.log(info)
+				this.$emit('select', info)
+				this.popup.close();
+			},
+
+			City(e) {
+				this.request({
+					url: "Smdcshop/getcity",
+					data: {
+						cityid: this.Prov_code,
+					},
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code =="200") {
+						this.City_arr = res.data;
+					console.log(this.City_arr, "City_arr")
+					}
+				}).catch((res) => {
+					// this.City_arr = [];
+				});
+			},
+
+			Dist(e) {
+				this.request({
+					url: "Smdcshop/getcity",
+					data: {
+						token: uni.getStorageSync("token"),
+						cityid: this.City_code,
+					},
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code === '200') {
+						this.Dist_arr = res.data;
+					}
+				}).catch((res) => {
+					this.Dist_arr = [];
+				});
+			},
+		}
+	}
+</script>
+
+<style>
+	
+	page .act {
+		color: #007AFF;
+	}
+
+	.popup-content {
+		width: 100%;
+		height: 656rpx;
+		background: #fff;
+		padding: 0rpx 40rpx;
+	}
+
+	.popup-content-title {
+		border-bottom: 1rpx solid #F1F1F1;
+		padding: 10rpx 0rpx;
+	}
+
+	.popup-content-scroll {
+		height: 590rpx;
+		width: 50%;
+		text-align: center;
+	}
+
+	.popup-content-scroll-li {
+		padding: 8rpx 0;
+	}
+</style>

+ 292 - 0
components/uni-swipe-action-item/bindingx.js

@@ -0,0 +1,292 @@
+const BindingX = uni.requireNativePlugin('bindingx');
+const dom = uni.requireNativePlugin('dom');
+const animation = uni.requireNativePlugin('animation');
+
+export default {
+	data() {
+		return {}
+	},
+
+	watch: {
+		show(newVal) {
+			if (this.autoClose) return
+			if (this.stop) return
+			this.stop = true
+			if (newVal) {
+				this.open(newVal)
+			} else {
+				this.close()
+			}
+		},
+		leftOptions() {
+			this.getSelectorQuery()
+			this.init()
+		},
+		rightOptions(newVal) {
+			this.init()
+		}
+	},
+	created() {
+		if (this.swipeaction.children !== undefined) {
+			this.swipeaction.children.push(this)
+		}
+	},
+	mounted() {
+		this.box = this.getEl(this.$refs['selector-box--hock'])
+		this.selector = this.getEl(this.$refs['selector-content--hock']);
+		this.leftButton = this.getEl(this.$refs['selector-left-button--hock']);
+		this.rightButton = this.getEl(this.$refs['selector-right-button--hock']);
+		this.init()
+	},
+	beforeDestroy() {
+		this.swipeaction.children.forEach((item, index) => {
+			if (item === this) {
+				this.swipeaction.children.splice(index, 1)
+			}
+		})
+	},
+	methods: {
+		init() {
+			this.$nextTick(() => {
+				this.x = 0
+				this.button = {
+					show: false
+				}
+				setTimeout(() => {
+					this.getSelectorQuery()
+				}, 200)
+			})
+		},
+		onClick(index, item, position) {
+			this.$emit('click', {
+				content: item,
+				index,
+				position
+			})
+		},
+		touchstart(e) {
+			// 每次只触发一次,避免多次监听造成闪烁
+			if (this.stop) return
+			this.stop = true
+			if (this.autoClose) {
+				this.swipeaction.closeOther(this)
+			}
+				
+			const leftWidth = this.button.left.width
+			const rightWidth = this.button.right.width
+			let expression = this.range(this.x, -rightWidth, leftWidth)
+			let leftExpression = this.range(this.x - leftWidth, -leftWidth, 0)
+			let rightExpression = this.range(this.x + rightWidth, 0, rightWidth)
+
+			this.eventpan = BindingX.bind({
+				anchor: this.box,
+				eventType: 'pan',
+				props: [{
+					element: this.selector,
+					property: 'transform.translateX',
+					expression
+				}, {
+					element: this.leftButton,
+					property: 'transform.translateX',
+					expression: leftExpression
+				}, {
+					element: this.rightButton,
+					property: 'transform.translateX',
+					expression: rightExpression
+				}, ]
+			}, (e) => {
+				// nope
+				if (e.state === 'end') {
+					this.x = e.deltaX + this.x;
+					this.isclick = true
+					this.bindTiming(e.deltaX)
+				}
+			});
+		},
+		touchend(e) {
+			if (this.isopen !== 'none' && !this.isclick) {
+				this.open('none')
+			}
+		},
+		bindTiming(x) {
+			const left = this.x
+			const leftWidth = this.button.left.width
+			const rightWidth = this.button.right.width
+			const threshold = this.threshold
+			if (!this.isopen || this.isopen === 'none') {
+				if (left > threshold) {
+					this.open('left')
+				} else if (left < -threshold) {
+					this.open('right')
+				} else {
+					this.open('none')
+				}
+			} else {
+				if ((x > -leftWidth && x < 0) || x > rightWidth) {
+					if ((x > -threshold && x < 0) || (x - rightWidth > threshold)) {
+						this.open('left')
+					} else {
+						this.open('none')
+					}
+				} else {
+					if ((x < threshold && x > 0) || (x + leftWidth < -threshold)) {
+						this.open('right')
+					} else {
+						this.open('none')
+					}
+				}
+			}
+		},
+
+		/**
+		 * 移动范围
+		 * @param {Object} num
+		 * @param {Object} mix
+		 * @param {Object} max
+		 */
+		range(num, mix, max) {
+			return `min(max(x+${num}, ${mix}), ${max})`
+		},
+
+		/**
+		 * 开启swipe
+		 */
+		open(type) {
+			this.animation(type)
+		},
+
+		/**
+		 * 关闭swipe
+		 */
+		close() {
+			this.animation('none')
+		},
+
+		/**
+		 * 开启关闭动画
+		 * @param {Object} type
+		 */
+		animation(type) {
+			const time = 300
+			const leftWidth = this.button.left.width
+			const rightWidth = this.button.right.width
+			if (this.eventpan && this.eventpan.token) {
+				BindingX.unbind({
+					token: this.eventpan.token,
+					eventType: 'pan'
+				})
+			}
+
+			switch (type) {
+				case 'left':
+					Promise.all([
+						this.move(this.selector, leftWidth),
+						this.move(this.leftButton, 0),
+						this.move(this.rightButton, rightWidth * 2)
+					]).then(() => {
+						this.setEmit(leftWidth, type)
+					})
+					break
+				case 'right':
+					Promise.all([
+						this.move(this.selector, -rightWidth),
+						this.move(this.leftButton, -leftWidth * 2),
+						this.move(this.rightButton, 0)
+					]).then(() => {
+						this.setEmit(-rightWidth, type)
+					})
+					break
+				default:
+					Promise.all([
+						this.move(this.selector, 0),
+						this.move(this.leftButton, -leftWidth),
+						this.move(this.rightButton, rightWidth)
+					]).then(() => {
+						this.setEmit(0, type)
+					})
+
+			}
+		},
+		setEmit(x, type) {
+			const leftWidth = this.button.left.width
+			const rightWidth = this.button.right.width
+			this.isopen = this.isopen || 'none'
+			this.stop = false
+			this.isclick = false
+			// 只有状态不一致才会返回结果
+			if (this.isopen !== type && this.x !== x) {
+				if (type === 'left' && leftWidth > 0) {
+					this.$emit('change', 'left')
+				}
+				if (type === 'right' && rightWidth > 0) {
+					this.$emit('change', 'right')
+				}
+				if (type === 'none') {
+					this.$emit('change', 'none')
+				}
+			}
+			this.x = x
+			this.isopen = type
+		},
+		move(ref, value) {
+			return new Promise((resolve, reject) => {
+				animation.transition(ref, {
+					styles: {
+						transform: `translateX(${value})`,
+					},
+					duration: 150, //ms
+					timingFunction: 'linear',
+					needLayout: false,
+					delay: 0 //ms
+				}, function(res) {
+					resolve(res)
+				})
+			})
+
+		},
+
+		/**
+		 * 获取ref
+		 * @param {Object} el
+		 */
+		getEl(el) {
+			return el.ref
+		},
+		/**
+		 * 获取节点信息
+		 */
+		getSelectorQuery() {
+			Promise.all([
+				this.getDom('left'),
+				this.getDom('right'),
+			]).then((data) => {
+				let show = 'none'
+				if (this.autoClose) {
+					show = 'none'
+				} else {
+					show = this.show
+				}
+
+				if (show === 'none') {
+					// this.close()
+				} else {
+					this.open(show)
+				}
+
+			})
+
+		},
+		getDom(str) {
+			return new Promise((resolve, reject) => {
+				dom.getComponentRect(this.$refs[`selector-${str}-button--hock`], (data) => {
+					if (data) {
+						this.button[str] = data.size
+						resolve(data)
+					} else {
+						reject()
+					}
+				})
+			})
+		}
+	}
+}

+ 266 - 0
components/uni-swipe-action-item/index.wxs

@@ -0,0 +1,266 @@
+var MIN_DISTANCE = 10;
+
+/**
+ * 监听页面内值的变化,主要用于动态开关swipe-action
+ * @param {Object} newValue
+ * @param {Object} oldValue
+ * @param {Object} ownerInstance
+ * @param {Object} instance
+ */
+function sizeReady(newValue, oldValue, ownerInstance, instance) {
+	var state = instance.getState()
+	var buttonPositions = JSON.parse(newValue)
+	if (!buttonPositions || !buttonPositions.data || buttonPositions.data.length === 0) return
+	state.leftWidth = buttonPositions.data[0].width
+	state.rightWidth = buttonPositions.data[1].width
+	state.threshold = instance.getDataset().threshold
+
+	if (buttonPositions.show && buttonPositions.show !== 'none') {
+		openState(buttonPositions.show, instance, ownerInstance)
+		return
+	}
+
+	if (state.left) {
+		openState('none', instance, ownerInstance)
+	}
+	resetTouchStatus(instance)
+}
+
+/**
+ * 开始触摸操作
+ * @param {Object} e
+ * @param {Object} ins
+ */
+function touchstart(e, ins) {
+	var instance = e.instance;
+	var disabled = instance.getDataset().disabled
+	var state = instance.getState();
+	// fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
+	disabled = (typeof(disabled) === 'string' ? JSON.parse(disabled) : disabled) || false;
+	if (disabled) return
+	// 开始触摸时移除动画类
+	instance.requestAnimationFrame(function(){
+		instance.removeClass('ani');
+		ins.callMethod('closeSwipe');
+	})
+
+	// 记录上次的位置
+	state.x = state.left || 0
+	// 计算滑动开始位置
+	stopTouchStart(e, ins)
+}
+
+/**
+ * 开始滑动操作
+ * @param {Object} e
+ * @param {Object} ownerInstance
+ */
+function touchmove(e, ownerInstance) {
+
+	var instance = e.instance;
+	var disabled = instance.getDataset().disabled
+	var state = instance.getState()
+	// fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
+	disabled = (typeof(disabled) === 'string' ? JSON.parse(disabled) : disabled) || false;
+	if (disabled) return
+	// 是否可以滑动页面
+	stopTouchMove(e);
+	if (state.direction !== 'horizontal') {
+		return;
+	}
+
+	if (e.preventDefault) {
+		// 阻止页面滚动
+		e.preventDefault()
+	}
+
+	move(state.x + state.deltaX, instance, ownerInstance)
+}
+
+/**
+ * 结束触摸操作
+ * @param {Object} e
+ * @param {Object} ownerInstance
+ */
+function touchend(e, ownerInstance) {
+	var instance = e.instance;
+	var disabled = instance.getDataset().disabled
+	var state = instance.getState()
+	// fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
+	disabled = (typeof(disabled) === 'string' ? JSON.parse(disabled) : disabled) || false;
+
+	if (disabled) return
+	// 滑动过程中触摸结束,通过阙值判断是开启还是关闭
+	// fixed by mehaotian 定时器解决点击按钮,touchend 触发比 click 事件时机早的问题 ,主要是 ios13
+	moveDirection(state.left, instance, ownerInstance)
+
+}
+
+/**
+ * 设置移动距离
+ * @param {Object} value
+ * @param {Object} instance
+ * @param {Object} ownerInstance
+ */
+function move(value, instance, ownerInstance) {
+	value = value || 0
+	var state = instance.getState()
+	var leftWidth = state.leftWidth
+	var rightWidth = state.rightWidth
+	// 获取可滑动范围
+	state.left = range(value, -rightWidth, leftWidth);
+	instance.requestAnimationFrame(function(){
+		instance.setStyle({
+			transform: 'translateX(' + state.left + 'px)',
+			'-webkit-transform': 'translateX(' + state.left + 'px)'
+		})
+	})
+
+}
+
+/**
+ * 获取范围
+ * @param {Object} num
+ * @param {Object} min
+ * @param {Object} max
+ */
+function range(num, min, max) {
+	return Math.min(Math.max(num, min), max);
+}
+
+
+/**
+ * 移动方向判断
+ * @param {Object} left
+ * @param {Object} value
+ * @param {Object} ownerInstance
+ * @param {Object} ins
+ */
+function moveDirection(left, ins, ownerInstance) {
+	var state = ins.getState()
+	var threshold = state.threshold
+	var position = state.position
+	var isopen = state.isopen || 'none'
+	var leftWidth = state.leftWidth
+	var rightWidth = state.rightWidth
+	if (state.deltaX === 0) {
+		openState('none', ins, ownerInstance)
+		return
+	}
+	if ((isopen === 'none' && rightWidth > 0 && -left > threshold) || (isopen !== 'none' && rightWidth > 0 && rightWidth +
+			left < threshold)) {
+		// right
+		openState('right', ins, ownerInstance)
+	} else if ((isopen === 'none' && leftWidth > 0 && left > threshold) || (isopen !== 'none' && leftWidth > 0 &&
+			leftWidth - left < threshold)) {
+		// left
+		openState('left', ins, ownerInstance)
+	} else {
+		// default
+		openState('none', ins, ownerInstance)
+	}
+}
+
+
+/**
+ * 开启状态
+ * @param {Boolean} type
+ * @param {Object} ins
+ * @param {Object} ownerInstance
+ */
+function openState(type, ins, ownerInstance) {
+	var state = ins.getState()
+	var position = state.position
+	var leftWidth = state.leftWidth
+	var rightWidth = state.rightWidth
+	var left = ''
+	state.isopen = state.isopen ? state.isopen : 'none'
+	switch (type) {
+		case "left":
+			left = leftWidth
+			break
+		case "right":
+			left = -rightWidth
+			break
+		default:
+			left = 0
+	}
+
+	// && !state.throttle
+
+	if (state.isopen !== type ) {
+		state.throttle = true
+		ownerInstance.callMethod('change', {
+			open: type
+		})
+
+	}
+
+	state.isopen = type
+	// 添加动画类
+	ins.requestAnimationFrame(function(){
+		ins.addClass('ani');
+		move(left, ins, ownerInstance)
+	})
+	// 设置最终移动位置,理论上只要进入到这个函数,肯定是要打开的
+}
+
+
+function getDirection(x, y) {
+	if (x > y && x > MIN_DISTANCE) {
+		return 'horizontal';
+	}
+	if (y > x && y > MIN_DISTANCE) {
+		return 'vertical';
+	}
+	return '';
+}
+
+/**
+ * 重置滑动状态
+ * @param {Object} event
+ */
+function resetTouchStatus(instance) {
+	var state = instance.getState();
+	state.direction = '';
+	state.deltaX = 0;
+	state.deltaY = 0;
+	state.offsetX = 0;
+	state.offsetY = 0;
+}
+
+/**
+ * 设置滑动开始位置
+ * @param {Object} event
+ */
+function stopTouchStart(event) {
+	var instance = event.instance;
+	var state = instance.getState();
+	resetTouchStatus(instance);
+	var touch = event.touches[0];
+	state.startX = touch.clientX;
+	state.startY = touch.clientY;
+}
+
+/**
+ * 滑动中,是否禁止打开
+ * @param {Object} event
+ */
+function stopTouchMove(event) {
+	var instance = event.instance;
+	var state = instance.getState();
+	var touch = event.touches[0];
+	state.deltaX = touch.clientX - state.startX;
+	state.deltaY = touch.clientY - state.startY;
+	state.offsetX = Math.abs(state.deltaX);
+	state.offsetY = Math.abs(state.deltaY);
+	state.direction = state.direction || getDirection(state.offsetX, state.offsetY);
+}
+
+
+module.exports = {
+	sizeReady: sizeReady,
+	touchstart: touchstart,
+	touchmove: touchmove,
+	touchend: touchend
+}

+ 207 - 0
components/uni-swipe-action-item/mpalipay.js

@@ -0,0 +1,207 @@
+export default {
+	data() {
+		return {
+			x: 0,
+			transition: false,
+			width: 0,
+			viewWidth: 0,
+			swipeShow: 0
+		}
+	},
+	watch: {
+		show(newVal) {
+			if (this.autoClose) return
+			if (newVal && newVal !== 'none' ) {
+				this.transition = true
+				this.open(newVal)
+			} else {
+				this.close()
+			}
+		}
+	},
+	created() {
+		if (this.swipeaction.children !== undefined) {
+			this.swipeaction.children.push(this)
+		}
+	},
+
+	beforeDestroy() {
+		this.swipeaction.children.forEach((item, index) => {
+			if (item === this) {
+				this.swipeaction.children.splice(index, 1)
+			}
+		})
+	},
+	mounted() {
+		this.isopen = false
+		setTimeout(() => {
+			this.getQuerySelect()
+		}, 50)
+	},
+	methods: {
+		appTouchStart(e) {
+			const {
+				clientX
+			} = e.changedTouches[0]
+			this.clientX = clientX
+			this.timestamp = new Date().getTime()
+		},
+		appTouchEnd(e, index, item, position) {
+			const {
+				clientX
+			} = e.changedTouches[0]
+			// fixed by xxxx 模拟点击事件,解决 ios 13 点击区域错位的问题
+			let diff = Math.abs(this.clientX - clientX)
+			let time = (new Date().getTime()) - this.timestamp
+			if (diff < 40 && time < 300) {
+				this.$emit('click', {
+					content: item,
+					index,
+					position
+				})
+			}
+		},
+		// onClick(index, item, position) {
+		// 	this.$emit('click', {
+		// 		content: item,
+		// 		index,
+		// 		position
+		// 	})
+		// },
+		/**
+		 * 移动触发
+		 * @param {Object} e
+		 */
+		onChange(e) {
+			this.moveX = e.detail.x
+			this.isclose = false
+		},
+		touchstart(e) {
+			this.transition = false
+			this.isclose = true
+			this.autoClose && this.swipeaction.closeOther(this)
+		},
+		touchmove(e) {},
+		touchend(e) {
+			// 0的位置什么都不执行
+			if (this.isclose && this.isopen === 'none') return
+			if (this.isclose && this.isopen !== 'none') {
+				this.transition = true
+				this.close()
+			} else {
+				this.move(this.moveX + this.leftWidth)
+			}
+		},
+
+		/**
+		 * 移动
+		 * @param {Object} moveX
+		 */
+		move(moveX) {
+			// 打开关闭的处理逻辑不太一样
+			this.transition = true
+			// 未打开状态
+			if (!this.isopen || this.isopen === 'none') {
+				if (moveX > this.threshold) {
+					this.open('left')
+				} else if (moveX < -this.threshold) {
+					this.open('right')
+				} else {
+					this.close()
+				}
+			} else {
+				if (moveX < 0 && moveX < this.rightWidth) {
+					const rightX = this.rightWidth + moveX
+					if (rightX < this.threshold) {
+						this.open('right')
+					} else {
+						this.close()
+					}
+				} else if (moveX > 0 && moveX < this.leftWidth) {
+					const leftX = this.leftWidth - moveX
+					if (leftX < this.threshold) {
+						this.open('left')
+					} else {
+						this.close()
+					}
+				}
+
+			}
+
+		},
+
+		/**
+		 * 打开
+		 */
+		open(type) {
+			this.x = this.moveX
+			this.animation(type)
+		},
+
+		/**
+		 * 关闭
+		 */
+		close() {
+			this.x = this.moveX
+			// TODO 解决 x 值不更新的问题,所以会多触发一次 nextTick ,待优化
+			this.$nextTick(() => {
+				this.x = -this.leftWidth
+				if(this.isopen!=='none'){
+					this.$emit('change', 'none')
+				}
+				this.isopen = 'none'
+			})
+		},
+
+		/**
+		 * 执行结束动画
+		 * @param {Object} type
+		 */
+		animation(type) {
+			this.$nextTick(() => {
+				if (type === 'left') {
+					this.x = 0
+				} else {
+					this.x = -this.rightWidth - this.leftWidth
+				}
+				
+				if(this.isopen!==type){
+					this.$emit('change', type)
+				}
+				this.isopen = type
+			})
+
+		},
+		getSlide(x) {},
+		getQuerySelect() {
+			const query = uni.createSelectorQuery().in(this);
+			query.selectAll('.movable-view--hock').boundingClientRect(data => {
+				this.leftWidth = data[1].width
+				this.rightWidth = data[2].width
+				this.width = data[0].width
+				this.viewWidth = this.width + this.rightWidth + this.leftWidth
+				if (this.leftWidth === 0) {
+					// TODO 疑似bug ,初始化的时候如果x 是0,会导致移动位置错误,所以让元素超出一点
+					this.x = -0.1
+				} else {
+					this.x = -this.leftWidth
+				}
+				this.moveX = this.x
+				this.$nextTick(() => {
+					this.swipeShow = 1
+				})
+
+				if (!this.buttonWidth) {
+					this.disabledView = true
+				}
+
+				if (this.autoClose) return
+				if (this.show !== 'none') {
+					this.transition = true
+					this.open(this.shows)
+				}
+			}).exec();
+
+		}
+	}
+}

+ 252 - 0
components/uni-swipe-action-item/mpother.js

@@ -0,0 +1,252 @@
+const MIN_DISTANCE = 10;
+export default {
+	data() {
+		return {
+			uniShow: false,
+			left: 0,
+			buttonShow: 'none',
+			ani: false,
+			moveLeft:''
+		}
+	},
+	watch: {
+		show(newVal) {
+			if (this.autoClose) return
+			this.openState(newVal)
+		},
+		left(){
+			this.moveLeft = `translateX(${this.left}px)`
+		},
+		buttonShow(newVal){
+			if (this.autoClose) return
+			this.openState(newVal)
+		},
+		leftOptions() {
+			this.init()
+		},
+		rightOptions() {
+			this.init()
+		}
+	},
+	mounted() {
+		// this.position = {}
+		if (this.swipeaction.children !== undefined) {
+			this.swipeaction.children.push(this)
+		}
+		this.init()
+	},
+	beforeDestoy() {
+		this.swipeaction.children.forEach((item, index) => {
+			if (item === this) {
+				this.swipeaction.children.splice(index, 1)
+			}
+		})
+	},
+	methods: {
+		init(){
+			clearTimeout(this.timer)
+			this.timer = setTimeout(() => {
+				this.getSelectorQuery()
+			}, 100)
+			// 移动距离
+			this.left = 0
+			this.x = 0
+		},
+		closeSwipe(e) {
+			if (!this.autoClose) return
+			this.swipeaction.closeOther(this)
+		},
+		appTouchStart(e) {
+			const {
+				clientX
+			} = e.changedTouches[0]
+			this.clientX = clientX
+			this.timestamp = new Date().getTime()
+		},
+		appTouchEnd(e, index, item, position) {
+			const {
+				clientX
+			} = e.changedTouches[0]
+			// fixed by xxxx 模拟点击事件,解决 ios 13 点击区域错位的问题
+			let diff = Math.abs(this.clientX - clientX)
+			let time = (new Date().getTime()) - this.timestamp
+			if (diff < 40 && time < 300) {
+				this.$emit('click', {
+					content: item,
+					index,
+					position
+				})
+			}
+		},
+		touchstart(e) {
+			if (this.disabled) return
+			this.ani = false
+			this.x = this.left || 0
+			this.stopTouchStart(e)
+			this.autoClose && this.closeSwipe()
+		},
+		touchmove(e) {
+			if (this.disabled) return
+			// 是否可以滑动页面
+			this.stopTouchMove(e);
+			if (this.direction !== 'horizontal') {
+				return;
+			}
+
+			this.move(this.x + this.deltaX)
+		},
+		touchend() {
+			if (this.disabled) return
+			this.moveDirection(this.left)
+		},
+		/**
+		 * 设置移动距离
+		 * @param {Object} value
+		 */
+		move(value) {
+			value = value || 0
+			const leftWidth = this.leftWidth
+			const rightWidth = this.rightWidth
+			// 获取可滑动范围
+			this.left = this.range(value, -rightWidth, leftWidth);
+		},
+
+		/**
+		 * 获取范围
+		 * @param {Object} num
+		 * @param {Object} min
+		 * @param {Object} max
+		 */
+		range(num, min, max) {
+			return Math.min(Math.max(num, min), max);
+		},
+		/**
+		 * 移动方向判断
+		 * @param {Object} left
+		 * @param {Object} value
+		 */
+		moveDirection(left) {
+			const threshold = this.threshold
+			const isopen = this.isopen || 'none'
+			const leftWidth = this.leftWidth
+			const rightWidth = this.rightWidth
+			if (this.deltaX === 0) {
+				this.openState('none')
+				return
+			}
+			if ((isopen === 'none' && rightWidth > 0 && -left > threshold) || (isopen !== 'none' && rightWidth > 0 && rightWidth +
+					left < threshold)) {
+				// right
+				this.openState('right')
+			} else if ((isopen === 'none' && leftWidth > 0 && left > threshold) || (isopen !== 'none' && leftWidth > 0 &&
+					leftWidth - left < threshold)) {
+				// left
+				this.openState('left')
+			} else {
+				// default
+				this.openState('none')
+			}
+		},
+
+		/**
+		 * 开启状态
+		 * @param {Boolean} type
+		 */
+		openState(type) {
+			const leftWidth = this.leftWidth
+			const rightWidth = this.rightWidth
+			let left = ''
+			this.isopen = this.isopen ? this.isopen : 'none'
+			switch (type) {
+				case "left":
+					left = leftWidth
+					break
+				case "right":
+					left = -rightWidth
+					break
+				default:
+					left = 0
+			}
+
+
+			if (this.isopen !== type) {
+				this.throttle = true
+				this.$emit('change', type)
+			}
+
+			this.isopen = type
+			// 添加动画类
+			this.ani = true
+			this.$nextTick(() => {
+				this.move(left)
+			})
+			// 设置最终移动位置,理论上只要进入到这个函数,肯定是要打开的
+		},
+		close() {
+			this.openState('none')
+		},
+		getDirection(x, y) {
+			if (x > y && x > MIN_DISTANCE) {
+				return 'horizontal';
+			}
+			if (y > x && y > MIN_DISTANCE) {
+				return 'vertical';
+			}
+			return '';
+		},
+
+		/**
+		 * 重置滑动状态
+		 * @param {Object} event
+		 */
+		resetTouchStatus() {
+			this.direction = '';
+			this.deltaX = 0;
+			this.deltaY = 0;
+			this.offsetX = 0;
+			this.offsetY = 0;
+		},
+
+		/**
+		 * 设置滑动开始位置
+		 * @param {Object} event
+		 */
+		stopTouchStart(event) {
+			this.resetTouchStatus();
+			const touch = event.touches[0];
+			this.startX = touch.clientX;
+			this.startY = touch.clientY;
+		},
+
+		/**
+		 * 滑动中,是否禁止打开
+		 * @param {Object} event
+		 */
+		stopTouchMove(event) {
+			const touch = event.touches[0];
+			this.deltaX = touch.clientX - this.startX;
+			this.deltaY = touch.clientY - this.startY;
+			this.offsetX = Math.abs(this.deltaX);
+			this.offsetY = Math.abs(this.deltaY);
+			this.direction = this.direction || this.getDirection(this.offsetX, this.offsetY);
+		},
+
+		getSelectorQuery() {
+			const views = uni.createSelectorQuery().in(this)
+			views
+				.selectAll('.uni-swipe_button-group')
+				.boundingClientRect(data => {
+					let show = 'none'
+					if (this.autoClose) {
+						show = 'none'
+					} else {
+						show = this.show
+					}
+					this.leftWidth = data[0].width || 0
+					this.rightWidth = data[1].width || 0
+					this.buttonShow = show
+				})
+				.exec()
+		}
+	}
+}

+ 119 - 0
components/uni-swipe-action-item/mpwxs.js

@@ -0,0 +1,119 @@
+export default {
+	data() {
+		return {
+			position: [],
+			button: {},
+			btn: "[]"
+		}
+	},
+	// computed: {
+	// 	pos() {
+	// 		return JSON.stringify(this.position)
+	// 	},
+	// 	btn() {
+	// 		return JSON.stringify(this.button)
+	// 	}
+	// },
+	watch: {
+		button: {
+			handler(newVal) {
+				this.btn = JSON.stringify(newVal)
+			},
+			deep: true
+		},
+		show(newVal) {
+			if (this.autoClose) return
+			if (!this.button) {
+				this.init()
+				return
+			}
+			this.button.show = newVal
+		},
+		leftOptions() {
+			this.init()
+		},
+		rightOptions() {
+			this.init()
+		}
+	},
+	created() {
+		if (this.swipeaction.children !== undefined) {
+			this.swipeaction.children.push(this)
+		}
+	},
+	mounted() {
+		this.init()
+	},
+	beforeDestroy() {
+		this.swipeaction.children.forEach((item, index) => {
+			if (item === this) {
+				this.swipeaction.children.splice(index, 1)
+			}
+		})
+	},
+	methods: {
+		init() {
+			clearTimeout(this.swipetimer)
+			this.swipetimer = setTimeout(() => {
+				this.getButtonSize()
+			}, 50)
+		},
+		closeSwipe(e) {
+			if (!this.autoClose) return
+			this.swipeaction.closeOther(this)
+		},
+
+		change(e) {
+			this.$emit('change', e.open)
+			let show = this.button.show
+			if (show !== e.open) {
+				this.button.show = e.open
+			}
+
+		},
+
+		appTouchStart(e) {
+			const {
+				clientX
+			} = e.changedTouches[0]
+			this.clientX = clientX
+			this.timestamp = new Date().getTime()
+		},
+		
+		appTouchEnd(e, index, item, position) {
+			const {
+				clientX
+			} = e.changedTouches[0]
+			// fixed by xxxx 模拟点击事件,解决 ios 13 点击区域错位的问题
+			let diff = Math.abs(this.clientX - clientX)
+			let time = (new Date().getTime()) - this.timestamp
+			if (diff < 40 && time < 300) {
+				this.$emit('click', {
+					content: item,
+					index,
+					position
+				})
+			}
+		},
+		
+		
+		getButtonSize() {
+			const views = uni.createSelectorQuery().in(this)
+			views
+				.selectAll('.uni-swipe_button-group')
+				.boundingClientRect(data => {
+					let show = 'none'
+					if (this.autoClose) {
+						show = 'none'
+					} else {
+						show = this.show
+					}
+					this.button = {
+						data,
+						show
+					}
+				})
+				.exec()
+		}
+	}
+}

+ 367 - 0
components/uni-swipe-action-item/uni-swipe-action-item.vue

@@ -0,0 +1,367 @@
+<template>
+	<!-- 在微信小程序 app vue端 h5 使用wxs 实现-->
+	<!-- #ifdef APP-VUE || MP-WEIXIN || H5 -->
+	<view class="uni-swipe">
+		<view
+		    class="uni-swipe_box"
+		    :data-threshold="threshold"
+		    :data-disabled="disabled"
+		    :change:prop="swipe.sizeReady"
+		    :prop="btn"
+		    @touchstart="swipe.touchstart"
+		    @touchmove="swipe.touchmove"
+		    @touchend="swipe.touchend"
+		>
+			<!-- 在微信小程序 app vue端 h5 使用wxs 实现-->
+			<view class="uni-swipe_button-group button-group--left">
+				<slot name="left">
+					<view
+					    v-for="(item,index) in leftOptions"
+					    :data-button="btn"
+					    :key="index"
+					    :style="{
+					  backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD',
+					  fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'
+					}"
+					    class="uni-swipe_button button-hock"
+					    @touchstart.stop="appTouchStart"
+					    @touchend.stop="appTouchEnd($event,index,item,'left')"
+					><text
+						    class="uni-swipe_button-text"
+						    :style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',}"
+						>{{ item.text }}</text>
+						</view>
+				</slot>
+			</view>
+			<slot></slot>
+			<view class="uni-swipe_button-group button-group--right">
+				<slot name="right">
+					<view
+					    v-for="(item,index) in rightOptions"
+					    :data-button="btn"
+					    :key="index"
+					    :style="{
+					  backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD',
+					  fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'
+					}"
+					    class="uni-swipe_button button-hock"
+					    @touchstart.stop="appTouchStart"
+					    @touchend.stop="appTouchEnd($event,index,item,'right')"
+	
+					><text
+						    class="uni-swipe_button-text"
+						    :style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',}"
+						>{{ item.text }}</text></view>
+				</slot>
+			</view>
+		</view>
+	</view>
+	<!-- #endif -->
+	<!-- app nvue端 使用 bindingx -->
+	<!-- #ifdef APP-NVUE -->
+	<view
+	    ref="selector-box--hock"
+	    class="uni-swipe"
+	    @horizontalpan="touchstart"
+	    @touchend="touchend"
+	>
+		<view
+		    ref='selector-left-button--hock'
+		    class="uni-swipe_button-group button-group--left"
+		>
+			<slot name="left">
+				<view
+				    v-for="(item,index) in leftOptions"
+				    :data-button="btn"
+				    :key="index"
+				    :style="{
+				  backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD',
+				  fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'
+				}"
+				    class="uni-swipe_button button-hock"
+				    @click.stop="onClick(index,item,'left')"
+				><text
+					    class="uni-swipe_button-text"
+					    :style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',}"
+					>{{ item.text }}</text></view>
+			</slot>
+		</view>
+		<view
+		    ref='selector-right-button--hock'
+		    class="uni-swipe_button-group button-group--right"
+		>
+			<slot name="right">
+				<view
+				    v-for="(item,index) in rightOptions"
+				    :data-button="btn"
+				    :key="index"
+				    :style="{
+				  backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD',
+				  fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'
+				}"
+				    class="uni-swipe_button button-hock"
+				    @click.stop="onClick(index,item,'right')"
+				><text
+					    class="uni-swipe_button-text"
+					    :style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',}"
+					>{{ item.text }}</text></view>
+			</slot>
+		</view>
+		<view
+		    ref='selector-content--hock'
+		    class="uni-swipe_box"
+		>
+			<slot></slot>
+		</view>
+	</view>
+	<!-- #endif -->
+	<!-- 其他平台使用 js ,长列表性能可能会有影响-->
+	<!-- #ifdef MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ -->
+	<view class="uni-swipe">
+		<view
+		    class="uni-swipe_box"
+		    @touchstart="touchstart"
+		    @touchmove="touchmove"
+		    @touchend="touchend"
+		    :style="{transform:moveLeft}"
+		    :class="{ani:ani}"
+		>
+			<view class="uni-swipe_button-group button-group--left">
+				<slot name="left">
+					<view
+					    v-for="(item,index) in leftOptions"
+					    :data-button="btn"
+					    :key="index"
+					    :style="{
+					  backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD',
+					  fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'
+					}"
+					    class="uni-swipe_button button-hock"
+					    @touchstart="appTouchStart"
+					    @touchend="appTouchEnd($event,index,item,'left')"
+					><text
+						    class="uni-swipe_button-text"
+						    :style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',}"
+						>{{ item.text }}</text></view>
+				</slot>
+			</view>
+			<slot></slot>
+			<view class="uni-swipe_button-group button-group--right">
+				<slot name="right">
+					<view
+					    v-for="(item,index) in rightOptions"
+					    :data-button="btn"
+					    :key="index"
+					    :style="{
+					  backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD',
+					  fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'
+					}"
+					    @touchstart="appTouchStart"
+					    @touchend="appTouchEnd($event,index,item,'right')"
+					    class="uni-swipe_button button-hock"
+					><text
+						    class="uni-swipe_button-text"
+						    :style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',}"
+						>{{ item.text }}</text></view>
+				</slot>
+			</view>
+		</view>
+	</view>
+	<!-- #endif -->
+
+</template>
+<script
+    src="./index.wxs"
+    module="swipe"
+    lang="wxs"
+></script>
+<script>
+	// #ifdef APP-VUE|| MP-WEIXIN || H5
+	import mpwxs from './mpwxs'
+	// #endif
+
+	// #ifdef APP-NVUE
+	import bindingx from './bindingx.js'
+	// #endif
+
+	// #ifndef APP-PLUS|| MP-WEIXIN  ||  H5
+	import mixins from './mpother'
+	// #endif
+
+	/**
+	 * SwipeActionItem 滑动操作子组件
+	 * @description 通过滑动触发选项的容器
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=181
+	 * @property {Boolean} show = [left|right|none] 	开启关闭组件,auto-close = false 时生效
+	 * @property {Boolean} disabled = [true|false] 		是否禁止滑动
+	 * @property {Boolean} autoClose = [true|false] 	滑动打开当前组件,是否关闭其他组件
+	 * @property {Number}  threshold 					滑动缺省值
+	 * @property {Array} leftOptions 					左侧选项内容及样式
+	 * @property {Array} rgihtOptions 					右侧选项内容及样式
+	 * @event {Function} click 							点击选项按钮时触发事件,e = {content,index} ,content(点击内容)、index(下标)
+	 * @event {Function} change 						组件打开或关闭时触发,left\right\none
+	 */
+
+	export default {
+		// #ifdef APP-VUE|| MP-WEIXIN||H5
+		mixins: [mpwxs],
+		// #endif
+
+		// #ifdef APP-NVUE
+		mixins: [bindingx],
+		// #endif
+
+		// #ifndef APP-PLUS|| MP-WEIXIN ||  H5
+		mixins: [mixins],
+		// #endif
+
+		props: {
+			// 控制开关
+			show: {
+				type: String,
+				default: 'none'
+			},
+
+			// 禁用
+			disabled: {
+				type: Boolean,
+				default: false
+			},
+
+			// 是否自动关闭
+			autoClose: {
+				type: Boolean,
+				default: true
+			},
+
+			// 滑动缺省距离
+			threshold: {
+				type: Number,
+				default: 20
+			},
+
+			// 左侧按钮内容
+			leftOptions: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+
+			// 右侧按钮内容
+			rightOptions: {
+				type: Array,
+				default () {
+					return []
+				}
+			}
+
+		},
+		inject: ['swipeaction']
+	}
+</script>
+<style
+    lang="scss"
+    scoped
+>
+	.uni-swipe {
+		position: relative;
+		/* #ifndef APP-NVUE */
+		overflow: hidden;
+		/* #endif */
+	}
+
+	.uni-swipe_box {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		flex-shrink: 0;
+		/* #endif */
+		position: relative;
+	}
+
+	.uni-swipe_content {
+		// border: 1px red solid;
+	}
+
+	.uni-swipe_button-group {
+		/* #ifndef APP-NVUE */
+		box-sizing: border-box;
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		position: absolute;
+		top: 0;
+		bottom: 0;
+	}
+
+	.button-group--left {
+		left: 0;
+		transform: translateX(-100%)
+	}
+
+	.button-group--right {
+		right: 0;
+		transform: translateX(100%)
+	}
+
+	.uni-swipe_button {
+		/* #ifdef APP-NVUE */
+		flex: 1;
+		/* #endif */
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		padding: 0 20px;
+	}
+
+	.uni-swipe_button-text {
+		/* #ifndef APP-NVUE */
+		flex-shrink: 0;
+		/* #endif */
+		font-size: 14px;
+	}
+
+	.ani {
+		transition-property: transform;
+		transition-duration: 0.3s;
+		transition-timing-function: cubic-bezier(0.165, 0.84, 0.44, 1);
+	}
+
+	/* #ifdef MP-ALIPAY */
+	.movable-area {
+		/* width: 100%; */
+		height: 45px;
+	}
+
+	.movable-view {
+		display: flex;
+		/* justify-content: center; */
+		position: relative;
+		flex: 1;
+		height: 45px;
+		z-index: 2;
+	}
+
+	.movable-view-button {
+		display: flex;
+		flex-shrink: 0;
+		flex-direction: row;
+		height: 100%;
+		background: #C0C0C0;
+	}
+
+	/* .transition {
+		transition: all 0.3s;
+	} */
+
+	.movable-view-box {
+		flex-shrink: 0;
+		height: 100%;
+		background-color: #fff;
+	}
+
+	/* #endif */
+</style>

+ 42 - 0
components/uni-swipe-action/uni-swipe-action.vue

@@ -0,0 +1,42 @@
+<template>
+	<view>
+		<slot></slot>
+	</view>
+</template>
+
+<script>
+	/**
+	 * SwipeAction 滑动操作
+	 * @description 通过滑动触发选项的容器
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=181
+	 */
+	export default {
+		data() {
+			return {};
+		},
+		provide() {
+			return {
+				swipeaction: this
+			};
+		},
+		created() {
+			this.children = [];
+		},
+		methods: {
+			closeOther(vm) {
+				if (this.openItem && this.openItem !== vm) {
+					// #ifdef APP-VUE || H5 || MP-WEIXIN
+					this.openItem.button.show = 'none'
+					// #endif
+
+					// #ifndef APP-VUE || H5 || MP-WEIXIN
+					this.openItem.close()
+					// #endif
+				}
+				this.openItem = vm
+			}
+		}
+	};
+</script>
+
+<style></style>

+ 279 - 0
components/uni-transition/uni-transition-a.vue

@@ -0,0 +1,279 @@
+<template>
+	<view v-if="isShow" ref="ani" class="uni-transition" :class="[ani.in]" :style="'transform:' +transform+';'+stylesObject"
+	 @click="change">
+		 <slot></slot>
+	</view>
+</template>
+
+<script>
+	// #ifdef APP-NVUE
+	const animation = uni.requireNativePlugin('animation');
+	// #endif
+	/**
+	 * Transition 过渡动画
+	 * @description 简单过渡动画组件
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=985
+	 * @property {Boolean} show = [false|true] 控制组件显示或隐藏
+     * @property {Array} modeClass = [fade|slide-top|slide-right|slide-bottom|slide-left|zoom-in|zoom-out] 过渡动画类型
+     *  @value fade 渐隐渐出过渡
+     *  @value slide-top 由上至下过渡
+     *  @value slide-right 由右至左过渡
+     *  @value slide-bottom 由下至上过渡
+     *  @value slide-left 由左至右过渡
+     *  @value zoom-in 由小到大过渡
+     *  @value zoom-out 由大到小过渡
+	 * @property {Number} duration 过渡动画持续时间
+	 * @property {Object} styles 组件样式,同 css 样式,注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red`
+	 */
+	export default {
+		name: 'uniTransition',
+		props: {
+			show: {
+				type: Boolean,
+				default: false
+			},
+			modeClass: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			duration: {
+				type: Number,
+				default: 300
+			},
+			styles: {
+				type: Object,
+				default () {
+					return {}
+				}
+			}
+		},
+		data() {
+			return {
+				isShow: false,
+				transform: '',
+				ani: { in: '',
+					active: ''
+				}
+			};
+		},
+		watch: {
+			show: {
+				handler(newVal) {
+					if (newVal) {
+						this.open()
+					} else {
+						this.close()
+					}
+				},
+				immediate: true
+			}
+		},
+		computed: {
+			stylesObject() {
+				let styles = {
+					...this.styles,
+					'transition-duration': this.duration / 1000 + 's'
+				}
+				let transfrom = ''
+				for (let i in styles) {
+					let line = this.toLine(i)
+					transfrom += line + ':' + styles[i] + ';'
+				}
+				return transfrom
+			}
+		},
+		created() {
+			// this.timer = null
+			// this.nextTick = (time = 50) => new Promise(resolve => {
+			// 	clearTimeout(this.timer)
+			// 	this.timer = setTimeout(resolve, time)
+			// 	return this.timer
+			// });
+		},
+		methods: {
+			change() {
+				this.$emit('click', {
+					detail: this.isShow
+				})
+			},
+			open() {
+				clearTimeout(this.timer)
+				this.isShow = true
+				this.transform = ''
+				this.ani.in = ''
+				for (let i in this.getTranfrom(false)) {
+					if (i === 'opacity') {
+						this.ani.in = 'fade-in'
+					} else {
+						this.transform += `${this.getTranfrom(false)[i]} `
+					}
+				}
+				this.$nextTick(() => {
+					setTimeout(() => {
+						this._animation(true)
+					}, 50)
+				})
+
+			},
+			close(type) {
+				clearTimeout(this.timer)
+				this._animation(false)
+			},
+			_animation(type) {
+				let styles = this.getTranfrom(type)
+				// #ifdef APP-NVUE
+				if(!this.$refs['ani']) return
+				animation.transition(this.$refs['ani'].ref, {
+					styles,
+					duration: this.duration, //ms
+					timingFunction: 'ease',
+					needLayout: false,
+					delay: 0 //ms
+				}, () => {
+					if (!type) {
+						this.isShow = false
+					}
+					this.$emit('change', {
+						detail: this.isShow
+					})
+				})
+				// #endif
+				// #ifndef APP-NVUE
+				this.transform = ''
+				for (let i in styles) {
+					if (i === 'opacity') {
+						this.ani.in = `fade-${type?'out':'in'}`
+					} else {
+						this.transform += `${styles[i]} `
+					}
+				}
+				this.timer = setTimeout(() => {
+					if (!type) {
+						this.isShow = false
+					}
+					this.$emit('change', {
+						detail: this.isShow
+					})
+
+				}, this.duration)
+				// #endif
+
+			},
+			getTranfrom(type) {
+				let styles = {
+					transform: ''
+				}
+				this.modeClass.forEach((mode) => {
+					switch (mode) {
+						case 'fade':
+							styles.opacity = type ? 1 : 0
+							break;
+						case 'slide-top':
+							styles.transform += `translateY(${type?'0':'-100%'}) `
+							break;
+						case 'slide-right':
+							styles.transform += `translateX(${type?'0':'100%'}) `
+							break;
+						case 'slide-bottom':
+							styles.transform += `translateY(${type?'0':'100%'}) `
+							break;
+						case 'slide-left':
+							styles.transform += `translateX(${type?'0':'-100%'}) `
+							break;
+						case 'zoom-in':
+							styles.transform += `scale(${type?1:0.8}) `
+							break;
+						case 'zoom-out':
+							styles.transform += `scale(${type?1:1.2}) `
+							break;
+					}
+				})
+				return styles
+			},
+			_modeClassArr(type) {
+				let mode = this.modeClass
+				if (typeof(mode) !== "string") {
+					let modestr = ''
+					mode.forEach((item) => {
+						modestr += (item + '-' + type + ',')
+					})
+					return modestr.substr(0, modestr.length - 1)
+				} else {
+					return mode + '-' + type
+				}
+			},
+			// getEl(el) {
+			// 	console.log(el || el.ref || null);
+			// 	return el || el.ref || null
+			// },
+			toLine(name) {
+				return name.replace(/([A-Z])/g, "-$1").toLowerCase();
+			}
+		}
+	}
+</script>
+
+<style>
+	.uni-transition {
+		transition-timing-function: ease;
+		transition-duration: 0.3s;
+		transition-property: transform, opacity;
+	}
+
+	.fade-in {
+		opacity: 0;
+	}
+
+	.fade-active {
+		opacity: 1;
+	}
+
+	.slide-top-in {
+		/* transition-property: transform, opacity; */
+		transform: translateY(-100%);
+	}
+
+	.slide-top-active {
+		transform: translateY(0);
+		/* opacity: 1; */
+	}
+
+	.slide-right-in {
+		transform: translateX(100%);
+	}
+
+	.slide-right-active {
+		transform: translateX(0);
+	}
+
+	.slide-bottom-in {
+		transform: translateY(100%);
+	}
+
+	.slide-bottom-active {
+		transform: translateY(0);
+	}
+
+	.slide-left-in {
+		transform: translateX(-100%);
+	}
+
+	.slide-left-active {
+		transform: translateX(0);
+		opacity: 1;
+	}
+
+	.zoom-in-in {
+		transform: scale(0.8);
+	}
+
+	.zoom-out-active {
+		transform: scale(1);
+	}
+
+	.zoom-out-in {
+		transform: scale(1.2);
+	}
+</style>

+ 34 - 0
components/uni-ui/uni-badge/readme.md

@@ -0,0 +1,34 @@
+### Badge 数字角标
+
+数字角标一般和其它控件(列表、9宫格等)配合使用,用于进行数量提示,默认为实心灰色背景,组件名:``uni-badge``,代码块: uBadge。
+
+**使用方式:**
+
+在 ``script`` 中引用组件 
+
+```javascript
+import uniBadge from "@/components/uni-badge/uni-badge.vue"
+export default {
+    components: {uniBadge}
+}
+```
+
+在 ``template`` 中使用组件
+
+```html
+<uni-badge text="1"></uni-badge>
+<uni-badge text="2" type="success" @click="bindClick"></uni-badge>
+<uni-badge text="3" type="primary" :inverted="true"></uni-badge>
+```
+
+实际效果参考:[https://github.com/dcloudio/uni-ui](https://github.com/dcloudio/uni-ui)
+
+**Badge 属性说明:**
+
+|属性名		|类型		|默认值	|说明																											|
+|---		|----		|---	|---																											|
+|text		|String		|-		|角标内容																										|
+|type		|String		|default|颜色类型,可选值:default(灰色)、primary(蓝色)、success(绿色)、warning(黄色)、error(红色)	|
+|size		|String		|normal|Badge 大小,可取值:normal、small|
+|inverted	|Boolean	|false	|是否无需背景颜色,为 true 时,背景颜色将变为文字的字体颜色														|
+|@click		|EventHandle|	-	|点击 Badge 触发事件																							|

+ 109 - 0
components/uni-ui/uni-badge/uni-badge.vue

@@ -0,0 +1,109 @@
+<template>
+	<text class="uni-badge" v-if="text" :class="setClass" @click="onClick()">{{text}}</text>
+</template>
+
+<script>
+	export default {
+		name: 'uni-badge',
+		props: {
+			type: {
+				type: String,
+				default: 'default'
+			},
+			inverted: {
+				type: Boolean,
+				default: false
+			},
+			text: {
+				type: String,
+				default: ''
+			},
+			size: { //small.normal
+				type: String,
+				default: 'normal'
+			}
+		},
+		computed: {
+			setClass() {
+				let classList = ['uni-badge-' + this.type, 'uni-badge--' + this.size];
+				if (this.inverted === true) {
+					classList.push('uni-badge-inverted')
+				}
+				return classList.join(" ")
+			}
+		},
+		methods: {
+			onClick() {
+				this.$emit('click')
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	$bage-size:12px;
+	$bage-small:scale(0.8);
+
+	.uni-badge {
+		font-family: 'Helvetica Neue', Helvetica, sans-serif;
+		box-sizing: border-box;
+		font-size: $bage-size;
+		line-height: 1;
+		display: inline-block;
+		padding: 3px 6px;
+		color: $uni-text-color;
+		border-radius: 100px;
+		background-color: $uni-bg-color-hover;
+
+		&.uni-badge-inverted {
+			padding: 0 5px 0 0;
+			color: $uni-text-color-grey;
+			background-color: transparent;
+		}
+
+		&-primary {
+			color: $uni-text-color-inverse;
+			background-color: $uni-color-primary;
+
+			&.uni-badge-inverted {
+				color: $uni-color-primary;
+				background-color: transparent
+			}
+		}
+
+		&-success {
+			color: $uni-text-color-inverse;
+			background-color: $uni-color-success;
+
+			&.uni-badge-inverted {
+				color: $uni-color-success;
+				background-color: transparent
+			}
+		}
+
+		&-warning {
+			color: $uni-text-color-inverse;
+			background-color: $uni-color-warning;
+
+			&.uni-badge-inverted {
+				color: $uni-color-warning;
+				background-color: transparent
+			}
+		}
+
+		&-error {
+			color: $uni-text-color-inverse;
+			background-color: $uni-color-error;
+
+			&.uni-badge-inverted {
+				color: $uni-color-error;
+				background-color: transparent
+			}
+		}
+
+		&--small {
+			transform: $bage-small;
+			transform-origin: center center;
+		}
+	}
+</style>

+ 61 - 0
components/uni-ui/uni-card/readme.md

@@ -0,0 +1,61 @@
+### Card 卡片
+
+卡片视图组件,组件名:``uni-card``,代码块: uCard。
+
+**使用方式:**
+
+在 ``script`` 中引用组件 
+
+```javascript
+import uniCard from "@/components/uni-card/uni-card.vue"
+export default {
+    components: {uniCard}
+}
+```
+
+一般用法
+
+```html
+<uni-card 
+    title="标题文字" 
+    thumbnail="http://img-cdn-qiniu.dcloud.net.cn/new-page/uni.png" 
+    extra="额外信息" 
+    note="Tips">
+    内容主体,可自定义内容及样式
+</uni-card>
+```
+
+内容通栏
+
+```html
+<uni-card 
+    is-full="true" 
+    title="DCloud" 
+    thumbnail="http://img-cdn-qiniu.dcloud.net.cn/new-page/uni.png" 
+    extra="2018.12.12"
+    note="Tips">
+    内容主体,可自定义内容及样式,内容主体,可自定义内容及样式,内容主体,可自定义内容及样式
+</uni-card>
+```
+
+**uniCard 属性说明:**
+
+|属性名|类型|默认值	|说明|
+|---|----|---|---|
+|title|String|-|标题文字|
+|extra|String|-|标题额外信息|
+|note|String|-|底部信息|
+|thumbnail|String|-|标题左侧缩略图|
+|is-full|Boolean|false|卡片内容是否通栏,为true时将去除padding值|
+
+**uniCard 事件说明:**
+
+|事件称名|说明|返回参数|
+|---|----|---|
+|click|点击 uniCard 触发事件|-|
+
+
+Tips
+
+* 组件实际运行效果参考:[https://github.com/dcloudio/uni-ui](https://github.com/dcloudio/uni-ui)
+* npm 使用方式参考:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55)

+ 165 - 0
components/uni-ui/uni-card/uni-card.vue

@@ -0,0 +1,165 @@
+<template>
+	<view class="uni-card" :class="isFull === true || isFull === 'true' ? 'uni-card--full' : ''" @click="onClick">
+		<view class="uni-card__header" :style="{'background-color':bgcolor? bgcolor: '#FFFFFF'}" v-if="title">
+			<view class="uni-card__header-extra-img-view" v-if="thumbnail">
+				<image class="uni-card__header-extra-img" :src="thumbnail"></image>
+			</view>
+			<view class="uni-card__header-title-text">{{title}}</view>
+			<view class="uni-card__header-extra-text" v-if="extra">{{extra}}</view>
+		</view>
+		<view class="uni-card__content uni-card__content--pd">
+			<image :src="images" mode="scaleToFill" class="demoimages" v-if="images"></image>
+			<text v-if="texts">{{texts}}</text>
+		</view>
+		<view class="uni-card__footer" v-if="note">{{note}}</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: "uni-card",
+		props: {
+			title: String, //标题
+			bgcolor: String, //背景颜色
+			extra: String, //扩展信息
+			note: String, //Tips
+			images: String, 
+			texts: String, 
+			thumbnail: String, //缩略图
+			isFull: { //内容区域是否通栏
+				type: [Boolean, String],
+				default: false
+			}
+		},
+		methods: {
+			onClick() {
+				this.$emit('click')
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+    $card-extra-width: 30%;
+    $uni-spacing-marign:16upx;
+    
+	@mixin text-omit {
+		text-overflow: ellipsis;
+		white-space: nowrap;
+		overflow: hidden;
+	}
+
+	.uni-card {
+		margin-left: $uni-spacing-marign;
+		margin-right: $uni-spacing-marign;
+		margin-top: $uni-spacing-marign;
+		background: $uni-bg-color;
+		position: relative;
+		display: flex;
+		flex-direction: column;
+
+		&:after {
+			content: '';
+			position: absolute;
+			transform-origin: center;
+			box-sizing: border-box;
+			pointer-events: none;
+			top: -50%;
+			left: -50%;
+			right: -50%;
+			bottom: -50%;
+			border: 1px solid $uni-border-color;
+			border-radius: $uni-border-radius-lg;
+			transform: scale(.5);
+		}
+
+		&__footer{
+			position: relative;
+			display: flex;
+			flex-direction: row;
+			padding: $uni-spacing-col-base;
+			align-items: center;
+			background-color: $uni-bg-color;
+		}
+		
+		&__header {
+			position: relative;
+			display: flex;
+			flex-direction: row;
+			padding: $uni-spacing-col-base;
+			align-items: center;
+		}
+
+		&__header {
+			
+			&:after {
+				position: absolute;
+				bottom: 0;
+				right: 0;
+				left: 0;
+				height: 1px;
+				content: '';
+				-webkit-transform: scaleY(.5);
+				transform: scaleY(.5);
+				background-color: $uni-border-color;
+				
+			}
+
+			&-title {
+				flex: 1;
+				margin-right: $uni-spacing-col-base;
+				display: flex;
+				flex-direction: row;
+				justify-content: flex-start;
+				align-items: center;
+
+				&-text {
+					font-size: $uni-font-size-lg;
+					flex: 1;
+					@include text-omit;
+				}
+			}
+
+			&-extra {
+				&-img-view {
+					display: flex;
+				}
+
+				&-img {
+					height: $uni-img-size-sm;
+					width: $uni-img-size-sm;
+					margin-right: $uni-spacing-col-base;
+				}
+
+				&-text {
+					flex: 0 0 auto;
+					width: $card-extra-width;
+					margin-left: $uni-spacing-col-base;
+					font-size: $uni-font-size-base;
+					text-align: right;
+					@include text-omit;
+				}
+			}
+
+		}
+
+		&__content {
+			&--pd {
+				padding: $uni-spacing-col-base;
+			}
+		}
+
+		&__footer {
+			justify-content: space-between;
+			color: $uni-text-color-grey;
+			font-size: $uni-font-size-sm;
+			padding-top: 0;
+		}
+        &--full{
+            margin: 0;
+        }
+	}
+.demoimages{width: 100%;height: 400upx;}
+text{font-size: 32upx;color: #000000;}
+
+</style>

+ 203 - 0
components/uni-ui/uni-grid/uni-grid.vue

@@ -0,0 +1,203 @@
+<template>
+	<view class="uni-grid" :class="{'uni-grid-no-border':!showBorder,'uni-grid-no-out-border':showBorder && !showOutBorder}">
+		<view class="uni-grid__flex" v-for="(items,i) in gridGroup" :key="i">
+			<view class="uni-grid-item" hover-class="uni-grid-item-hover" :hover-start-time="20" :hover-stay-time="70" v-for="(item,index) in items"
+			 :key="index" :class="[index == columnNum ? 'uni-grid-item-last' : '','uni-grid-item-' + type]" @click="onClick(i,index,item.url)" :style="{visibility:item.seize ? 'hidden' : 'inherit'}">
+				<view class="uni-grid-item__content" v-if="!item.seize">
+					<image class="uni-grid-item-image" :src="item.image"></image>
+					<text class="uni-grid-item-text">{{item.text}}</text>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: "uni-grid",
+		props: {
+			options: Array,
+			type: { //布局格式,长方形oblong,正方形square
+				type: String,
+				default: 'square'
+			},
+			columnNum: { //每一行有多少个
+				type: [Number, String],
+				default: 3
+			},
+			showOutBorder: { //显示外边框
+				type: [Boolean, String],
+				default: true
+			},
+			showBorder: { //是否显示border,如果为false,showOutBorder无效
+				type: [Boolean, String],
+				default: true
+			}
+		},
+		data() {
+			return {}
+		},
+		created() {
+			this.columnNumber = this.gridGroup[0].length
+		},
+		computed: {
+			gridGroup() {
+				let group = []
+				let groupItem = []
+				this.options && this.options.forEach((item, index) => {
+					groupItem.push(item)
+					if (index % this.columnNum === this.columnNum - 1) {
+						group.push(groupItem)
+						groupItem = []
+					}
+				})
+				if (groupItem.length > 0) {
+					if (this.columnNum > groupItem.length) {
+						for (let i = 0,length = groupItem.length; i < this.columnNum - length; i++) {
+							groupItem.push({seize:true})
+						}
+					}
+					group.push(groupItem)
+				}
+				groupItem = null
+				return group
+			}
+		},
+		methods: {
+			onClick(index, num,url) {
+				uni.navigateTo({
+					url: url
+				});
+			}
+		}
+	}
+</script>
+
+<style>
+	@charset "UTF-8";
+
+	.uni-grid {
+		position: relative;
+		display: flex;
+		flex-direction: column;
+	}
+
+	.uni-grid__flex {
+		display: flex;
+		flex-direction: row;
+	}
+
+	.uni-grid-item {
+		display: flex;
+		position: relative;
+		flex-direction: column;
+		background-color: #FFFFFF;
+		flex: 1
+	}
+
+	.uni-grid-item:before {
+		display: block;
+		content: " ";
+		padding-bottom: 100%
+	}
+
+	.uni-grid-item:after {
+		content: '';
+		position: absolute;
+		z-index: 1;
+		transform-origin: center;
+		box-sizing: border-box;
+		top: -50%;
+		left: -50%;
+		right: -50%;
+		bottom: -50%;
+		border-color: #c8c7cc;
+		border-style: solid;
+		border-width: 1px;
+		-webkit-transform: scale(.5);
+		transform: scale(.5);
+		border-top-width: 0;
+		border-left-width: 0
+	}
+
+	.uni-grid-item__content {
+		position: absolute;
+		left: 0;
+		top: 0;
+		width: 100%;
+		height: 100%;
+		display: flex;
+		flex-direction: column;
+		justify-content: center;
+		align-items: center
+	}
+
+	.uni-grid-item-text {
+		font-size: 32upx;
+		color: #333;
+		margin-top: 12upx
+	}
+
+	.uni-grid-item-hover {
+		background-color: #f1f1f1
+	}
+
+	.uni-grid-item-image {
+		width: 80upx;
+		height: 80upx
+	}
+
+	.uni-grid .uni-grid__flex:first-child .uni-grid-item:after {
+		border-top-width: 1px
+	}
+
+	.uni-grid .uni-grid__flex .uni-grid-item:first-child:after {
+		border-left-width: 1px
+	}
+
+	.uni-grid.uni-grid-no-out-border .uni-grid__flex:first-child .uni-grid-item:after {
+		border-top-width: 0
+	}
+
+	.uni-grid.uni-grid-no-out-border .uni-grid__flex:last-child .uni-grid-item:after {
+		border-bottom-width: 0
+	}
+
+	.uni-grid.uni-grid-no-out-border .uni-grid__flex .uni-grid-item:first-child:after {
+		border-left-width: 0
+	}
+
+	.uni-grid.uni-grid-no-out-border .uni-grid__flex .uni-grid-item:last-child:after {
+		border-right-width: 0
+	}
+
+	.uni-grid.uni-grid-no-border .uni-grid-item:after {
+		border-width: 0
+	}
+
+	.uni-grid.uni-grid-no-border .uni-grid__flex:first-child .uni-grid-item:after {
+		border-top-width: 0
+	}
+
+	.uni-grid.uni-grid-no-border .uni-grid__flex .uni-grid-item:first-child:after {
+		border-left-width: 0
+	}
+
+	.uni-grid-item-oblong.uni-grid-item:before {
+		padding-bottom: 60%
+	}
+
+	.uni-grid-item-oblong .uni-grid-item__content {
+		flex-direction: row
+	}
+
+	.uni-grid-item-oblong .uni-grid-item-image {
+		width: 52upx;
+		height: 52upx
+	}
+
+	.uni-grid-item-oblong .uni-grid-item-text {
+		margin-top: 0;
+		margin-left: 12upx
+	}
+</style>

+ 35 - 0
components/uni-ui/uni-icon/readme.md

@@ -0,0 +1,35 @@
+### Icon 图标
+
+用于展示 icon,组件名:``uni-icon``,代码块: uIcon。
+
+**使用方式:**
+
+在 ``script`` 中引用组件 
+
+```javascript
+import uniIcon from "@/components/uni-icon/uni-icon.vue"
+export default {
+    components: {uniIcon}
+}
+```
+
+在 ``template`` 中使用组件
+
+```html
+<uni-icon type="contact" size="30"></uni-icon>
+```
+
+实际效果参考:[https://github.com/dcloudio/uni-ui](https://github.com/dcloudio/uni-ui)
+
+**Icon 属性说明:**
+
+|属性名		|类型|默认值	|说明|
+|---|----|---|---|
+|type	|String	|-|图标图案,参考下表|
+|color	|String	|-|图标颜色	|
+|size	|Number	|24|图标大小|
+|@click	|EventHandle|-|点击 Icon 触发事件|
+
+**type 类型:**
+
+![icon](https://img-cdn-qiniu.dcloud.net.cn/img/icon.png)

文件差异内容过多而无法显示
+ 39 - 0
components/uni-ui/uni-icon/uni-icon.vue


+ 95 - 0
components/uni-ui/uni-notice-bar/readme.md

@@ -0,0 +1,95 @@
+### NoticeBar 通告栏
+
+通告栏组件,组件名:``uni-notice-bar``,代码块: uNoticeBar。
+
+**使用方式:**
+
+在 ``script`` 中引用组件 
+
+```javascript
+import uniNoticeBar from "@/components/uni-notice-bar/uni-notice-bar.vue"
+export default {
+    components: {uniNoticeBar}
+}
+```
+
+基本用法
+
+```html
+<uni-notice-bar 
+    single="true" 
+    text="[单行] 这是 NoticeBar 通告栏,这是 NoticeBar 通告栏,这是 NoticeBar 通告栏">
+</uni-notice-bar>
+<uni-notice-bar 
+    text="[多行] 这是 NoticeBar 通告栏,这是 NoticeBar 通告栏,这是 NoticeBar 通告栏,这是 NoticeBar 通告栏">
+</uni-notice-bar>
+```
+
+文字滚动
+
+```html
+<uni-notice-bar 
+    show-icon="true" 
+    scrollable="true" single="true" 
+    text="[单行] 这是 NoticeBar 通告栏,这是 NoticeBar 通告栏,这是 NoticeBar 通告栏">
+</uni-notice-bar>
+```
+
+显示图标
+
+```html
+<uni-notice-bar 
+    show-icon="true" 
+    text="[多行] 这是 NoticeBar 通告栏,这是 NoticeBar 通告栏,这是 NoticeBar 通告栏这是 NoticeBar 通告栏,这是 NoticeBar 通告栏,这是 NoticeBar 通告栏">
+</uni-notice-bar>
+```
+
+显示关闭按钮
+
+```html
+<uni-notice-bar 
+    show-close="true" 
+    show-icon="true" text="这是 NoticeBar 通告栏,这是 NoticeBar 通告栏,这是 NoticeBar 通告栏">
+</uni-notice-bar>
+```
+
+查看更多
+
+```html
+ <uni-notice-bar 
+    @getmore="getMore" 
+    more-text="查看更多" 
+    single="true" 
+    text="[单行] 这是 NoticeBar 通告栏,这是 NoticeBar 通告栏,这是 NoticeBar 通告栏">
+</uni-notice-bar>
+```
+
+**属性说明:**
+
+|属性名|类型|默认值	|说明|
+|---|----|---|---|
+|text|String|-|显示文字|
+|more-text|String|-|“查看更多”的文本,如果设置文字,NoticeBar为单行|
+|speed|Number|100|文字滚动的速度,默认100px/秒|
+|background-color|String|#fffbe8|背景颜色|
+|color|String|#de8c17|文字颜色|
+|single|Boolean|false|是否单行|
+|scrollable|Boolean|false|是否滚动,为true时,NoticeBar为单行|
+|show-icon|Boolean|false|是否显示左侧喇叭图标|
+|show-close|Boolean|false|是否显示左侧关闭按钮|
+
+**事件说明:**
+
+|事件名称	|说明						|
+|---		|---						|
+|click		|点击 NoticeBar 触发事件	|
+|close		|关闭 NoticeBar 触发事件	|
+|getmore	|点击”查看更多“时触发事件	|
+
+
+
+Tips
+
+* 组件实际运行效果参考:[https://github.com/dcloudio/uni-ui](https://github.com/dcloudio/uni-ui)
+* npm 使用方式参考:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55)
+* 由于H5端默认加了scope导致此组件的滚动功能将不会生效

+ 243 - 0
components/uni-ui/uni-notice-bar/uni-notice-bar.vue

@@ -0,0 +1,243 @@
+<template>
+	<view v-if="show" class="uni-noticebar" :style="{backgroundColor:backgroundColor,color:color}" @click="onClick">
+		<view v-if="showClose === 'true' || showClose === true" class="uni-noticebar__close">
+			<uni-icon type="closefill" size="12"></uni-icon>
+		</view>
+		<view class="uni-noticebar__content" :class="setContenClass">
+			<view v-if="showIcon === 'true' || showIcon === true" class="uni-noticebar__content-icon" :style="{backgroundColor:backgroundColor,color:color}">
+				<uni-icon type="sound" size="14" :color="color"></uni-icon>
+			</view>
+			<view class="uni-noticebar__content-text" :class="setTextClass">
+				<!-- #ifdef H5 -->
+				<view class="uni-noticebar__content-inner" :id="elId" :style="{'animation-duration': animation,'-webkit-animation-duration': animation}">{{text}}</view>
+				<!-- #endif -->
+				<!-- #ifndef H5 -->
+				<view class="uni-noticebar__content-inner" :id="elId" :style="{'animation': animation,'-webkit-animation': animation}">{{text}}</view>
+				<!-- #endif -->
+			</view>
+			<view class="uni-noticebar__content-more" v-if="showGetMore === 'true' || showGetMore === true" @click="clickMore" :style="{width:moreText ? '180upx' : '20px'}">
+				<view class="uni-noticebar__content-more-text" v-if="moreText">{{moreText}}</view>
+				<uni-icon type="arrowright" size="14"></uni-icon>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import uniIcon from '../uni-icon/uni-icon.vue'
+	export default {
+		name: "uni-notice-bar",
+		components: {
+			uniIcon
+		},
+		props: {
+			text: String,
+			moreText: String,
+			backgroundColor: {
+				type: String,
+				default: '#fffbe8'
+			},
+			speed: { //默认1s滚动100px
+				default: 100
+			},
+			color: {
+				default: '#de8c17'
+			},
+			single: { //是否单行
+				default: false
+			},
+			scrollable: { //是否滚动,添加后控制单行效果取消
+				default: false
+			},
+			showIcon: { //是否显示左侧icon
+				default: false
+			},
+			showGetMore: { //是否显示右侧查看更多
+				default: false
+			},
+			showClose: { //是否显示左侧关闭按钮
+				default: false
+			}
+		},
+		data() {
+			const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
+			return {
+				elId: elId,
+				show: true,
+				animation: ''
+			}
+		},
+		watch: {
+			text(newValue, oldValue) {
+				this.$nextTick(() => {
+					setTimeout(this.setAnimation, 200)
+				})
+			}
+		},
+		computed: {
+			setTextClass() {
+				let classList = []
+				if (this.scrollable === true || this.scrollable === 'true') {
+					classList.push('uni-noticebar--scrollable')
+				} else {
+					if (this.single === 'true' || this.single === true || this.moreText) {
+						classList.push('uni-noticebar--single')
+					}
+				}
+				return classList
+			},
+			setContenClass() {
+				let classList = []
+				if (this.scrollable === true || this.scrollable === 'true' || this.single === 'true' || this.single === true ||
+					this.moreText) {
+					classList.push('uni-noticebar--flex')
+				}
+				return classList
+			}
+		},
+		mounted() { 
+			this.setAnimation()
+		},
+		methods: {
+			clickMore() {
+				this.$emit('getmore')
+			},
+			onClick(e) {
+				let clientX = e.touches ? (e.touches[0] ? e.touches[0].clientX : e.changedTouches[0].clientX) : e.detail.clientX;
+				if (uni.upx2px(48) + 12 > clientX && (String(this.showClose) === 'true')) {
+					this.show = false
+					this.$emit('close')
+				}
+				this.$emit('click')
+			},
+			setAnimation() {
+				if (this.scrollable === false || this.scrollable === 'false') {
+					return;
+				}
+				//#ifdef MP-TOUTIAO
+				setTimeout(() => {
+					uni.createSelectorQuery().in(this).select(`#${this.elId}`).boundingClientRect().exec((ret) => {
+						console.log(ret)
+						this.animation = `notice ${ret[0].width / this.speed}s linear infinite both`;
+					});
+				}, 500)
+				// #endif
+				//#ifdef H5
+				setTimeout(() => {
+					uni.createSelectorQuery().in(this).select(`#${this.elId}`).boundingClientRect().exec((ret) => {
+						this.animation = `${ret[0].width / this.speed}s`;
+					});
+				}, 200)
+				// #endif
+				// #ifndef MP-TOUTIAO || H5
+				setTimeout(() => {
+					uni.createSelectorQuery().in(this).select(`#${this.elId}`).boundingClientRect().exec((ret) => {
+						this.animation = `notice ${ret[0].width / this.speed}s linear infinite both`;
+					});
+				}, 200)
+				// #endif
+			}
+		}
+	}
+</script>
+
+<style>
+	@charset "UTF-8";
+
+	.uni-noticebar {
+		padding: 12upx 24upx;
+		font-size: 24upx;
+		line-height: 1.5;
+		margin: 10upx 0;
+		display: flex;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		justify-content: left
+	}
+
+	.uni-noticebar__close {
+		color: #999;
+		margin-right: 24upx;
+		display: flex;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center
+	}
+
+	.uni-noticebar__content {
+		flex: 1;
+		overflow: hidden
+	}
+
+	.uni-noticebar__content.uni-noticebar--flex {
+		flex: 1;
+		display: flex;
+		flex-direction: row
+	}
+
+	.uni-noticebar__content-icon {
+		display: inline-block;
+		z-index: 1;
+		padding-right: 12upx
+	}
+
+	.uni-noticebar__content-more {
+		width: 180upx;
+		display: flex;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		justify-content: flex-end;
+		word-break: keep-all;
+		margin-left: 10upx;
+		color: #999
+	}
+
+	.uni-noticebar__content-more-text {
+		font-size: 24upx;
+		white-space: nowrap
+	}
+
+	.uni-noticebar__content-text {
+		word-break: break-all;
+		line-height: 1.5;
+		display: inline
+	}
+
+	.uni-noticebar__content-text.uni-noticebar--single {
+		text-overflow: ellipsis;
+		white-space: nowrap;
+		overflow: hidden
+	}
+
+	.uni-noticebar__content-text.uni-noticebar--scrollable {
+		flex: 1;
+		display: block;
+		overflow: hidden
+	}
+
+	.uni-noticebar__content-text.uni-noticebar--scrollable .uni-noticebar__content-inner {
+		padding-left: 100%;
+		white-space: nowrap;
+		display: inline-block;
+		/* #ifdef H5 */
+		animation-name: notice;
+		animation-timing-function: linear;
+		animation-fill-mode: both;
+		animation-iteration-count: infinite;
+		/* #endif */
+		transform: translateZ(0)
+	}
+
+	.uni-noticebar__content-inner {
+		font-size: 24upx;
+		display: inline
+	}
+
+	@keyframes notice {
+		100% {
+			transform: translate3d(-100%, 0, 0)
+		}
+	}
+</style>

+ 162 - 0
components/uni-ui/uni-swiper-dot/uni-swiper-dot.vue

@@ -0,0 +1,162 @@
+<template>
+	<view class="uni-swiper__warp">
+		<slot></slot>
+		<view v-if="mode === 'default'" class="uni-swiper__dots-box" :style="{'bottom':dots.bottom + 'px'}">
+			<view class="uni-swiper__dots-item" v-for="(item,index) in info" :style="{
+				 'width': dots.width + 'px','height':dots.height +'px' ,'background-color':index !== current?dots.backgroundColor:dots.selectedBackgroundColor,'border':index !==current ? dots.border:dots.selectedBorder}"
+			 :key="index"></view>
+		</view>
+		<view v-if="mode === 'long'" class="uni-swiper__dots-box" :style="{'bottom':dots.bottom + 'px'}">
+			<view class="uni-swiper__dots-item " v-for="(item,index) in info" :class="[index === current&&'uni-swiper__dots-long']"
+			 :style="{
+				 'width':(index === current? dots.width*3:dots.width ) + 'px','height':dots.height +'px' ,'background-color':index !== current?dots.backgroundColor:dots.selectedBackgroundColor,'border':index !==current ? dots.border:dots.selectedBorder}"
+			 :key="index"></view>
+		</view>
+		<view v-if="mode === 'nav'" class="uni-swiper__dots-box uni-swiper__dots-nav" :style="{'background-color':dotsStyles.backgroundColor}">
+			<view class="uni-swiper__dots-nav-item" :style="{'color':dotsStyles.color}">{{(current+1)+"/"+info.length}}
+				{{info[current][field]}}</view>
+		</view>
+		<view v-if="mode === 'indexes'" class="uni-swiper__dots-box" :style="{'bottom':dots.bottom + 'px'}">
+			<view class="uni-swiper__dots-item uni-swiper__dots-indexes" v-for="(item,index) in info" :style="{
+				 'width':dots.width + 'px','height':dots.height +'px' ,'color':index === current?dots.selectedColor:dots.color,'background-color':index !== current?dots.backgroundColor:dots.selectedBackgroundColor,'border':index !==current ? dots.border:dots.selectedBorder}"
+			 :key="index">{{index+1}}</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'uni-swiper-dot',
+		props: {
+			info: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			current: {
+				info: Number,
+				default: 0
+			},
+			dotsStyles: {
+				type: Object,
+				default () {
+					return {}
+				}
+			},
+			// 类型 :default(默认) indexes long nav
+			mode: {
+				type: String,
+				default: 'default'
+			},
+			// 只在 nav 模式下生效,变量名称
+			field: {
+				type: String,
+				default: ''
+			}
+		},
+		data() {
+			return {
+				dots: {
+					width: 8,
+					height: 8,
+					bottom: 10,
+					color: '#fff',
+					backgroundColor: 'rgba(0, 0, 0, .3)',
+					border: '1px rgba(0, 0, 0, .3) solid',
+					selectedBackgroundColor: '#333',
+					selectedBorder: '1px rgba(0, 0, 0, .9) solid'
+				}
+			};
+		},
+		created() {
+			if (this.mode === 'indexes') {
+				this.dots.width = 20
+				this.dots.height = 20
+			}
+			this.dots = Object.assign(this.dots, this.dotsStyles)
+		},
+		watch: {
+			dotsStyles(newVal) {
+				this.dots = Object.assign(this.dots, this.dotsStyles)
+			},
+			mode(newVal) {
+				if (newVal === 'indexes') {
+					this.dots.width = 20
+					this.dots.height = 20
+				} else {
+					this.dots.width = 8
+					this.dots.height = 8
+				}
+			}
+
+		}
+	}
+</script>
+
+<style>
+	.uni-swiper__warp {
+		position: relative;
+		width: 100%;
+		box-sizing: border-box;
+		overflow: hidden;
+	}
+
+	.uni-swiper__dots-box {
+		position: absolute;
+		bottom: 20upx;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		box-sizing: box-sizing;
+		width: 100%;
+	}
+
+	.uni-swiper__dots-item {
+		flex-shrink: 0;
+		width: 16upx;
+		border-radius: 50%;
+		margin-left: 12upx;
+		background: rgba(0, 0, 0, .3);
+		transition: all 0.2s linear;
+	}
+
+	.uni-swiper__dots-item:first-child {
+		margin: 0;
+	}
+
+	.uni-swiper__dots-default {
+		border-radius: 50%;
+	}
+
+	.uni-swiper__dots-long {
+		border-radius: 100upx;
+	}
+
+	.uni-swiper__dots-nav {
+		bottom: 0;
+		height: 80upx;
+		justify-content: flex-start;
+		background: rgba(0, 0, 0, 0.2);
+		box-sizing: box-sizing;
+		overflow: hidden;
+	}
+
+	.uni-swiper__dots-nav-item {
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+		font-size: 28upx;
+		color: #fff;
+		box-sizing: box-sizing;
+		margin: 0 30upx;
+	}
+
+	.uni-swiper__dots-indexes {
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		color: #fff;
+		font-size: 24upx;
+	}
+</style>

+ 20 - 0
components/wyb-pagination/iconfont.css

@@ -0,0 +1,20 @@
+@font-face {font-family: "iconfont";
+  src: url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAALUAAsAAAAABtwAAAKFAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCCfgqBQIE1ATYCJAMMCwgABCAFhG0HRBsBBhEVjCOyrw7sYPj4I0QqzNq3zfnzDrGGnxGGLSGIJLifI6jWsJ7dDaIDIM/lo6IIVFyEAVaJdC8Ma5KsX18DIvAAvNrML65E6KwwVPnjwadURdk9jquzLCnj43Q3FiERMuvuW6CtkLIwkLa2RJ8WB1673A9cYIWJ1mV/lpeyxOTL57kc310BZdH8QIGltvZ+PiZgggWyN0aRFViUecPYBS/wPoFG/WbFduUD1CvsZYG41DlCfSGsKCxXL9Q27C3iTY369JLe4zX6fPyzHJHUZPZDOxcuwfrP5M0rFXuZ6+WcYIfImEUhdhvTO7JgjKwxXYxyrGnBz/RX/EwCqzgqMxF/nVvdDCahKj2RxFN7NAk8IIEMapPsCjYQvTsQUof9hYqOoxqqWHWbqJ9LAh/W3Mq8UOvnzz9Gr1/8fZwsnhvGHNLy5fPH0Q1H/TAu1g7uN/MIVHJPFhG/fhEIau4W/277/5oK+Govv4JgpdC81J/RE/w9ycCuYshsSy6a2BNb3mx4ojMBhdynmu3v9GO6tmdwNaFeT4akTh+yeqNEoc+iRpNV1KonXkOjGfXhJl3YXpQGTPsACO0+kbR6h6zdQhT6ihq9/lGrPfZotBtdZzYZD33YYmwEe2jfQXfBk2uTQ1x7hWq2DedlEesOedIxKNK8nKvRIy+xYXpRpQgBcXBQgcfQ2gCRw4idpINIPGcZNb0o7YLbHGxhqCFQD7TeAa0TeBQMFofK+68gZWY1uKOuzn8HsYkeHhRS+QCiVvtBdY/yzOSFUhKCAMICB1RgFrKsAMTmWSPUEalhQjI6y5x+NFSdbq91P1DEmrDX5EiRo2g8a/yovQUS5ourYW68Kpg2GwAAAA==') format('woff2')
+}
+
+.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-danjiantou:before {
+  content: "\e62d";
+}
+
+.icon-shuangjiantou:before {
+  content: "\e62e";
+}
+

+ 442 - 0
components/wyb-pagination/wyb-pagination.vue

@@ -0,0 +1,442 @@
+<template>
+	<view class="wyb-pagination-box" :style="{
+		paddingLeft: padding + 'rpx',
+		paddingRight: padding + 'rpx',
+		'--hover': autoHover}">
+		<view class="wyb-pagination-left" :style="{opacity: currentPage === 1 ? 0.5 : 1}">
+			<view v-if="showFirst" :class="'wyb-pagination-first-page-' + (showIcon ? 'i' : 't')" :style="btnStyleStr"
+				:hover-class="currentPage === 1 ? '' : 'wyb-pagination-hover'" @tap="onPageBtnTap('first-page')">
+				<view v-if="showIcon" class="iconfont icon-shuangjiantou left-arrow" />
+				<text v-else>{{firstText}}</text>
+			</view>
+			<view :class="'wyb-pagination-prev-page-' + (showIcon ? 'i' : 't')" :style="btnStyleStr"
+				:hover-class="currentPage === 1 ? '' : 'wyb-pagination-hover'" @tap="onPageBtnTap('prev-page')">
+				<view v-if="showIcon" class="iconfont icon-danjiantou left-arrow" />
+				<text v-else>{{prevText}}</text>
+			</view>
+		</view>
+		<view class="wyb-pagination-info" @tap.stop="onInfoTap">
+			<view class="wyb-pagination-num" v-if="!infoClick">
+				<text :style="{color: currentColor}">{{currentPage}}</text>
+				<text class="wyb-pagination-span" :style="{color: pageInfoColor}">/</text>
+				<text :style="{color: pageInfoColor}">{{totalPage}}</text>
+				<text v-if="showTotalItem" class="wyb-pagination-info-total"
+					:style="{color: RGBChange(pageInfoColor, 0.5, 'light')}">
+					({{totalItems}})
+				</text>
+			</view>
+			<!-- #ifndef MP-WEIXIN || APP-VUE || APP-NVUE || APP-PLUS || APP-PLUS-NVUE -->
+			<view class="wyb-pagination-input" v-else>
+				<input type="number" v-model="inputPage" :onpaste="false" :focus="infoFocus" :value="currentPage"
+					:style="{color: currentColor}" :cursor-spacing="cursorSpacing" @confirm="onInfoConfirm"
+					@blur="onInfoBlur" />
+			</view>
+			<!-- #endif -->
+			<!-- #ifdef MP-WEIXIN || APP-VUE || APP-NVUE || APP-PLUS || APP-PLUS-NVUE -->
+			<view class="wyb-pagination-input" v-else>
+				<input type="number" v-model="inputPage" :focus="infoFocus" :name="currentPage"
+					:style="{color: currentColor}" :cursor-spacing="cursorSpacing" @confirm="onInfoConfirm"
+					@blur="onInfoBlur" />
+			</view>
+			<!-- #endif -->
+		</view>
+		<view class="wyb-pagination-right" :style="{opacity: currentPage === totalPage ? 0.5 : 1}">
+			<view :class="'wyb-pagination-next-page-' + (showIcon ? 'i' : 't')" :style="btnStyleStr"
+				:hover-class="currentPage === totalPage ? '' : 'wyb-pagination-hover'" @tap="onPageBtnTap('next-page')">
+				<view v-if="showIcon" class="iconfont icon-danjiantou right-arrow" />
+				<text v-else>{{nextText}}</text>
+			</view>
+			<view v-if="showLast" :class="'wyb-pagination-last-page-' + (showIcon ? 'i' : 't')" :style="btnStyleStr"
+				:hover-class="currentPage === totalPage ? '' : 'wyb-pagination-hover'" @tap="onPageBtnTap('last-page')">
+				<view v-if="showIcon" class="iconfont icon-shuangjiantou right-arrow" />
+				<text v-else>{{lastText}}</text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				currentPage: this.current || 1,
+				inputPage: '',
+				infoClick: false,
+				infoFocus: false
+			}
+		},
+		computed: {
+			totalPage() {
+				console.log(parseFloat(this.totalItems),parseFloat(this.pageItems),"this.totalItems)")
+				return Math.ceil(parseFloat(this.totalItems) / parseFloat(this.pageItems))
+			},
+			autoHover() {
+				if (this.btnStyle.backgroundColor) {
+					return this.RGBChange(this.btnStyle.backgroundColor, 0.1, 'dark')
+				} else {
+					return this.RGBChange('#f8f8f8', 0.05, 'dark')
+				}
+			},
+			btnStyleStr() {
+				let styleStr = ''
+				for (let key in this.btnStyle) {
+					styleStr += `${this.sortFieldMatch(key)}: ${this.btnStyle[key]}; `
+				}
+				return styleStr
+			}
+		},
+		watch: {
+			current(val) {
+				console.log(val, "currentPage")
+				const oPage = this.currentPage
+				if (!Object.is(oPage, val)) {
+					this.currentPage = val
+					this.$emit('change', {
+						type: 'prop-page',
+						current: this.currentPage,
+					})
+				}
+			}
+		},
+		props: {
+			totalItems: {
+				type: [String, Number],
+				default: 20
+			},
+			pageItems: {
+				type: [String, Number],
+				default: 5
+			},
+			current: {
+				type: [String, Number],
+				default: 1
+			},
+			prevText: {
+				type: String,
+				default: '上一页'
+			},
+			nextText: {
+				type: String,
+				default: '下一页'
+			},
+			firstText: {
+				type: String,
+				default: '首页'
+			},
+			lastText: {
+				type: String,
+				default: '尾页'
+			},
+			pageInfoColor: {
+				type: String,
+				default: '#494949'
+			},
+			currentColor: {
+				type: String,
+				default: '#007aff'
+			},
+			padding: {
+				type: [String, Number],
+				default: 15
+			},
+			btnStyle: {
+				type: Object,
+				default () {
+					return {}
+				}
+			},
+			showIcon: {
+				type: Boolean,
+				default: false
+			},
+			showTotalItem: {
+				type: Boolean,
+				default: false
+			},
+			showFirst: {
+				type: Boolean,
+				default: true
+			},
+			showLast: {
+				type: Boolean,
+				default: true
+			},
+			couldInput: {
+				type: Boolean,
+				default: true
+			},
+			cursorSpacing: {
+				type: Number,
+				default: 0
+			}
+		},
+		methods: {
+			onPageBtnTap(type) {
+				switch (type) {
+					case 'first-page':
+						if (!Object.is(this.currentPage, 1)) {
+							this.currentPage = 1
+							this.$emit('change', {
+								type,
+								current: this.currentPage
+							})
+						}
+						break
+					case 'prev-page':
+						if (!Object.is(this.currentPage, 1)) {
+							this.currentPage--
+							this.$emit('change', {
+								type,
+								current: this.currentPage
+							})
+						}
+						break
+					case 'next-page':
+						if (!Object.is(this.currentPage, this.totalPage)) {
+							this.currentPage++
+							this.$emit('change', {
+								type,
+								current: this.currentPage
+							})
+						}
+						break
+					case 'last-page':
+						if (!Object.is(this.currentPage, this.totalPage)) {
+							this.currentPage = this.totalPage
+							this.$emit('change', {
+								type,
+								current: this.currentPage
+							})
+						}
+						break
+				}
+			},
+			onInfoTap() {
+				if (this.couldInput) {
+					this.infoClick = true
+					this.inputPage = this.currentPage
+					setTimeout(() => {
+						this.infoFocus = true
+					}, 10)
+				}
+			},
+			onInfoConfirm(e) {
+				let input = e.detail.value
+				const oPage = this.currentPage
+				if (parseFloat(input) > this.totalPage) {
+					this.currentPage = this.totalPage
+				} else if (parseFloat(input) < 1) {
+					this.currentPage = 1
+				} else if (input === '') {
+					this.currentPage = oPage
+				} else {
+					this.currentPage = parseFloat(input)
+				}
+				if (!Object.is(oPage, this.currentPage)) {
+					this.$emit('change', {
+						type: 'input-page',
+						current: this.currentPage,
+					})
+				}
+				this.infoClick = false
+				this.$nextTick(() => {
+					this.infoFocus = false
+				})
+			},
+			onInfoBlur(e) {
+				let input = e.detail.value
+				const oPage = this.currentPage
+				if (parseFloat(input) > this.totalPage) {
+					this.currentPage = this.totalPage
+				} else if (parseFloat(input) < 1) {
+					this.currentPage = 1
+				} else if (input === '') {
+					this.currentPage = oPage
+				} else {
+					this.currentPage = parseFloat(input)
+				}
+				if (!Object.is(oPage, this.currentPage)) {
+					this.$emit('change', {
+						type: 'input-page',
+						current: this.currentPage,
+					})
+				}
+				this.infoClick = false
+				this.$nextTick(() => {
+					this.infoFocus = false
+				})
+			},
+			RGBChange(color, level, type) {
+				// 判断颜色类型
+				let r = 0,
+					g = 0,
+					b = 0,
+					hasAlpha = false,
+					alpha = 1
+				if (color.indexOf('#') !== -1) {
+					// hex转rgb
+					if (color.length === 4) {
+						let arr = color.split('')
+						color = '#' + arr[1] + arr[1] + arr[2] + arr[2] + arr[3] + arr[3]
+					}
+					let color16List = [color.substring(1, 3), color.substring(3, 5), color.substring(5, 7)]
+					r = parseInt(color16List[0], 16)
+					g = parseInt(color16List[1], 16)
+					b = parseInt(color16List[2], 16)
+
+				} else {
+					hasAlpha = color.indexOf('a') !== -1
+					let root = color.slice()
+					let idx = root.indexOf('(') + 1
+					root = root.substring(idx)
+					let firstDotIdx = root.indexOf(',')
+					r = parseFloat(root.substring(0, firstDotIdx))
+					root = root.substring(firstDotIdx + 1)
+					let secondDotIdx = root.indexOf(',')
+					g = parseFloat(root.substring(0, secondDotIdx))
+					root = root.substring(secondDotIdx + 1)
+					if (hasAlpha) {
+						let thirdDotIdx = root.indexOf(',')
+						b = parseFloat(root.substring(0, thirdDotIdx))
+						alpha = parseFloat(root.substring(thirdDotIdx + 1))
+					} else {
+						b = parseFloat(root)
+					}
+				}
+
+				let rgbc = [r, g, b]
+				// 减淡或加深
+				for (var i = 0; i < 3; i++)
+					type === 'light' ? rgbc[i] = Math.floor((255 - rgbc[i]) * level + rgbc[i]) : rgbc[i] = Math.floor(rgbc[
+						i] * (1 -
+						level))
+
+				if (hasAlpha) {
+					return `rgba(${rgbc[0]}, ${rgbc[1]}, ${rgbc[2]}, ${alpha})`
+				} else {
+					return `rgb(${rgbc[0]}, ${rgbc[1]}, ${rgbc[2]})`
+				}
+			},
+			sortFieldMatch(field) {
+				const stringArray = field.split('')
+				let newField = field
+				stringArray.forEach(t => {
+					if (/[A-Z]/.test(t)) {
+						newField = field.replace(t, `-${t.toLowerCase()}`)
+					}
+				})
+				return newField
+			}
+		}
+	}
+</script>
+
+<style>
+	@import 'iconfont.css';
+
+	.wyb-pagination-box {
+		width: 100%;
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		box-sizing: border-box;
+		justify-content: space-between;
+		flex-wrap: nowrap;
+	}
+
+	.wyb-pagination-left {
+		flex: 1;
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		flex-wrap: nowrap;
+		justify-content: flex-start;
+	}
+
+	.wyb-pagination-right {
+		flex: 1;
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		flex-wrap: nowrap;
+		justify-content: flex-end;
+	}
+
+	.wyb-pagination-first-page-t,
+	.wyb-pagination-prev-page-t,
+	.wyb-pagination-next-page-t,
+	.wyb-pagination-last-page-t {
+		font-size: 27rpx;
+		padding: 14rpx 25rpx;
+		box-sizing: border-box;
+		background-color: #f8f8f8;
+		border: 1px solid #e5e5e5;
+		white-space: nowrap;
+	}
+
+	.wyb-pagination-first-page-i,
+	.wyb-pagination-prev-page-i,
+	.wyb-pagination-next-page-i,
+	.wyb-pagination-last-page-i {
+		font-size: 27rpx;
+		padding: 14rpx 33rpx;
+		box-sizing: border-box;
+		background-color: #f8f8f8;
+		border: 1px solid #e5e5e5;
+		white-space: nowrap;
+	}
+
+	.wyb-pagination-first-page-t,
+	.wyb-pagination-first-page-i {
+		margin-right: 15rpx;
+	}
+
+	.wyb-pagination-last-page-t,
+	.wyb-pagination-last-page-i {
+		margin-left: 15rpx;
+	}
+
+	.wyb-pagination-info {
+		font-size: 33rpx;
+		white-space: nowrap;
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+		flex: 1;
+	}
+
+	.wyb-pagination-input input {
+		text-align: center;
+	}
+
+	.wyb-pagination-span {
+		margin: 0 2rpx;
+	}
+
+	.wyb-pagination-info-total {
+		margin-left: 10rpx;
+	}
+
+	.wyb-pagination-first-page-t:active,
+	.wyb-pagination-prev-page-t:active,
+	.wyb-pagination-next-page-t:active,
+	.wyb-pagination-last-page-t:active,
+	.wyb-pagination-first-page-i:active,
+	.wyb-pagination-prev-page-i:active,
+	.wyb-pagination-next-page-i:active,
+	.wyb-pagination-last-page-i:active {
+		background-color: var(--hover) !important;
+	}
+
+	.left-arrow {
+		transform: scale(0.9);
+		margin-right: 5rpx;
+	}
+
+	.right-arrow {
+		margin-left: 5rpx;
+		transform: scale(0.9) rotate(180deg);
+		-webkit-transform: scale(0.8) rotate(180deg);
+	}
+</style>

+ 119 - 0
components/zx-footer-bar/zx-footer-bar.vue

@@ -0,0 +1,119 @@
+<template>
+	<view class="container">
+		
+		<view class="content">
+			
+			<view class="item" :class="[active == 0?'active':'']" 
+			   @click="navTo(0,'/statistics/index/index?type=')">
+				<image :src="active == 0 ?'/static/images/tabBar/index1_act.png':'/static/images/tabBar/index1.png'" 
+				mode="aspectFit" class="icon-img"></image>
+				<text class="title">首页</text>
+			</view>
+			
+			<view class="item" :class="[active == 1?'active':'']" @click="navTo(1,'/saomaDiancan/index/index?type=')">
+				<image :src="active == 1 ?'/static/images/tabBar/icon_20_on.png':'/static/images/tabBar/icon_20.png'" mode="aspectFit" class="icon-img"></image>
+				<text class="title">门店管理</text>
+			</view>
+
+			<view class="item" :class="[active == 2?'active':'']" @click="navTo(2,'/saomaDiancan/my/my?type=')">
+				<image :src="active == 2 ?'/static/images/tabBar/icon_21_on.png':'/static/images/tabBar/icon_21.png'"  class="icon-img"></image>
+				<text class="title">个人中心</text>
+			</view>
+			
+		</view>
+		
+	</view>
+</template>
+
+<script>
+	export default {
+		props: {
+			active: {
+				type: Number,
+				default: 0
+			}, 
+			// 扫码点餐2,无痕跳转2
+			type: {
+				type: Number,
+				default: 1
+			},
+		},
+		data() {
+			return {
+
+			};
+		},
+		methods: {
+			navTo(index, url) {
+				console.log("index, url", this.active,index, url)
+				if (index != this.active) {
+					uni.redirectTo({
+						url: url+this.type
+					})
+				}
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	
+
+	.container {
+		width: 100%;
+		height: 100rpx;
+		/*兼容 IOS<11.2*/
+		padding-bottom: constant(safe-area-inset-bottom);
+		/*兼容 IOS>11.2*/
+		padding-bottom: env(safe-area-inset-bottom);
+		box-sizing: content-box;
+	}
+
+	.content {
+		background-color: #fff;
+		width: 100vw;
+		height: 100rpx;
+		/*兼容 IOS<11.2*/
+		padding-bottom: constant(safe-area-inset-bottom);
+		/*兼容 IOS>11.2*/
+		padding-bottom: env(safe-area-inset-bottom);
+		display: flex;
+		flex-flow: row nowrap;
+		justify-content: space-around;
+		align-items: center;
+		/* box-shadow: 0 20rpx 20rpx #f6f6f6 inset; */
+		position: fixed;
+		left: 0;
+		bottom: 0;
+		z-index: 900;
+		box-sizing: content-box;
+	}
+
+	.content .item {
+		flex: auto;
+		display: flex;
+		flex-flow: column nowrap;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.content .icon-img {
+		display: block;
+		width: 48rpx;
+		height: 48rpx;
+	}
+
+
+
+	.content .title {
+		font-size: 24rpx;
+		height: 28rpx;
+		line-height: 28rpx;
+		text-align: center;
+		color: #ABADC2;
+	}
+
+	.content .active .title {
+		color: #3387FF;
+	}
+</style>

+ 22 - 0
components/zx-uni-popup/message.js

@@ -0,0 +1,22 @@
+export default {
+	created() {
+		if (this.type === 'message') {
+			// 不显示遮罩
+			this.maskShow = false 
+			// 获取子组件对象
+			this.childrenMsg = null
+		}
+	},
+	methods: {
+		customOpen() {
+			if (this.childrenMsg) {
+				this.childrenMsg.open()
+			}
+		},
+		customClose() {
+			if (this.childrenMsg) {
+				this.childrenMsg.close()
+			}
+		}
+	}
+}

+ 26 - 0
components/zx-uni-popup/popup.js

@@ -0,0 +1,26 @@
+import message from './message.js';
+// 定义 type 类型:弹出类型:top/bottom/center
+const config = {
+	// 顶部弹出
+	top:'top',
+	// 底部弹出
+	bottom:'bottom',
+	// 居中弹出
+	center:'center',
+	// 消息提示
+	message:'top',
+	// 对话框
+	dialog:'center',
+	// 分享
+	share:'bottom',
+    auth:'bottom',
+}
+
+export default {
+	data(){
+		return {
+			config:config
+		}
+	},
+	mixins: [message],
+}

+ 271 - 0
components/zx-uni-popup/uni-popup-top.vue

@@ -0,0 +1,271 @@
+<template>
+	<view v-if="showPopup" class="uni-popup" :style="'top:'+top" @touchmove.stop.prevent="clear">
+		<uni-transition :mode-class="['fade']" :styles="maskClass" :duration="duration" :show="showTrans" @click="onTap" />
+		<uni-transition :mode-class="ani" :styles="transClass" :duration="duration" :show="showTrans" @click="onTap">
+			<view class="uni-popup__wrapper-box" @click.stop="clear">
+				<slot />
+			</view>
+		</uni-transition>
+	</view>
+</template>
+<script>
+	import uniTransition from '../uni-transition/uni-transition-a.vue'
+	/**
+	 * PopUp 弹出层
+	 * @description 弹出层组件,为了解决遮罩弹层的问题
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=329
+	 * @property {String} type = [top|center|bottom] 弹出方式
+	 * 	@value top 顶部弹出
+	 * 	@value center 中间弹出
+	 * 	@value bottom 底部弹出
+	 * @property {Boolean} animation = [ture|false] 是否开启动画
+	 * @property {Boolean} maskClick = [ture|false] 蒙版点击是否关闭弹窗
+	 * @event {Function} change 打开关闭弹窗触发,e={show: false}
+	 */
+	export default {
+		name: 'UniPopup',
+		components: {
+			uniTransition
+		},
+		props: {
+			// 开启动画
+			animation: {
+				type: Boolean,
+				default: true
+			},
+			// 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
+			type: {
+				type: String,
+				default: 'center'
+			},
+			// maskClick
+			maskClick: {
+				type: Boolean,
+				default: true
+			},
+			top:String,
+			position:String,
+			maskClass:Object
+		},
+		data() {
+			return {
+				duration: 300,
+				ani: [],
+				showPopup: false,
+				showTrans: false,
+				// maskClass: {
+				// 	'position': 'fixed',
+				// 	'bottom': 0,
+				// 	'top': "226rpx",
+				// 	'left': 0,
+				// 	'right': 0,
+				// 	'backgroundColor': 'rgba(0, 0, 0, 0.4)'
+				// },
+				transClass: {
+					'position': 'fixed',
+					'left': 0,
+					'right': 0,
+				}
+			}
+		},
+		watch: {
+			type: {
+				handler: function(newVal) {
+					switch (this.type) {
+						case 'top':
+							this.ani = ['slide-top']
+							this.transClass = {
+								'position': 'fixed',
+								'left': 0,
+								'right': 0,
+							}
+							break
+						case 'bottom':
+							this.ani = ['slide-bottom']
+							this.transClass = {
+								'position': 'fixed',
+								'left': 0,
+								'right': 0,
+								'bottom': 0
+							}
+							break
+						case 'center':
+							this.ani = ['zoom-out', 'fade']
+							this.transClass = {
+								'position': 'fixed',
+								/* #ifndef APP-NVUE */
+								'display': 'flex',
+								'flexDirection': 'column',
+								/* #endif */
+								'bottom': 0,
+								'left': 0,
+								'right': 0,
+								'top': 0,
+								'justifyContent': 'center',
+								'alignItems': 'center'
+							}
+
+							break
+					}
+				},
+				immediate: true
+			}
+		},
+		created() {
+			if (this.animation) {
+				this.duration = 300
+			} else {
+				this.duration = 0
+			}
+		},
+		methods: {
+			clear(e) {
+				// TODO nvue 取消冒泡
+				e.stopPropagation()
+			},
+			open() {
+				this.showPopup = true
+				this.$nextTick(() => {
+					clearTimeout(this.timer)
+					this.timer = setTimeout(() => {
+						this.showTrans = true
+					}, 50);
+				})
+				this.$emit('change', {
+					show: true
+				})
+			},
+			close(type) {
+				this.showTrans = false
+				this.$nextTick(() => {
+					clearTimeout(this.timer)
+					this.timer = setTimeout(() => {
+						this.$emit('change', {
+							show: false
+						})
+						this.showPopup = false
+					}, 300)
+				})
+			},
+			onTap() {
+				if (!this.maskClick) return
+				this.close()
+			}
+		}
+	}
+</script>
+<style scoped>
+	.uni-popup {
+		position: fixed;
+		
+		/* #ifdef H5 */
+		/* top: var(--window-top); */
+		/* #endif */
+		
+		/* #ifndef H5 */
+		/* top: 0; */
+		/* #endif */
+		
+		top: 226rpx;
+		
+		bottom: 0;
+		left: 0;
+		right: 0;
+		z-index: 100;
+		
+		/* #ifndef APP-NVUE */
+	
+		/* #endif */
+	}
+
+	.uni-popup__mask {
+		position: absolute;
+		top: 0;
+		bottom: 0;
+		left: 0;
+		right: 0;
+		background-color: rgba(0, 0, 0, 0.4);
+		opacity: 0;
+	}
+
+	.mask-ani {
+		transition-property: opacity;
+		transition-duration: 0.2s;
+	}
+
+	.uni-top-mask {
+		opacity: 1;
+	}
+
+	.uni-bottom-mask {
+		opacity: 1;
+	}
+
+	.uni-center-mask {
+		opacity: 1;
+	}
+
+	.uni-popup__wrapper {
+		/* #ifndef APP-NVUE */
+		display: block;
+		/* #endif */
+		position: absolute;
+	}
+
+	.top {
+		top: 0;
+		left: 0;
+		right: 0;
+		transform: translateY(-500px);
+	}
+
+	.bottom {
+		bottom: 0;
+		left: 0;
+		right: 0;
+		transform: translateY(500px);
+	}
+
+	.center {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		flex-direction: column;
+		/* #endif */
+		bottom: 0;
+		left: 0;
+		right: 0;
+		top: 0;
+		justify-content: center;
+		align-items: center;
+		transform: scale(1.2);
+		opacity: 0;
+	}
+
+	.uni-popup__wrapper-box {
+		/* #ifndef APP-NVUE */
+		display: block;
+		/* #endif */
+		position: relative;
+	}
+
+	.content-ani {
+		/* transition: transform 0.3s;
+ */
+		transition-property: transform, opacity;
+		transition-duration: 0.2s;
+	}
+
+
+	.uni-top-content {
+		transform: translateY(0);
+	}
+
+	.uni-bottom-content {
+		transform: translateY(0);
+	}
+
+	.uni-center-content {
+		transform: scale(1);
+		opacity: 1;
+	}
+</style>

+ 298 - 0
components/zx-uni-popup/uni-popup.vue

@@ -0,0 +1,298 @@
+<template>
+	<view v-if="showPopup" class="uni-popup" @touchmove.stop.prevent="clear">
+		<uni-transition :mode-class="['fade']" :styles="maskClass" :duration="duration" :show="showTrans"
+			@click="onTap" />
+		<uni-transition :mode-class="ani" :styles="transClass" :duration="duration" :show="showTrans" @click="onTap">
+			<view class="uni-popup__wrapper-box" @click.stop="clear">
+				<slot />
+			</view>
+		</uni-transition>
+	</view>
+</template>
+
+<script>
+	import uniTransition from '../uni-transition/uni-transition-a.vue'
+	import popup from './popup.js'
+	/**
+	 * PopUp 弹出层
+	 * @description 弹出层组件,为了解决遮罩弹层的问题
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=329
+	 * @property {String} type = [top|center|bottom] 弹出方式
+	 * 	@value top 顶部弹出
+	 * 	@value center 中间弹出
+	 * 	@value bottom 底部弹出
+	 * @property {Boolean} animation = [ture|false] 是否开启动画
+	 * @property {Boolean} maskClick = [ture|false] 蒙版点击是否关闭弹窗
+	 * @event {Function} change 打开关闭弹窗触发,e={show: false}
+	 */
+	export default {
+		name: 'UniPopup',
+		components: {
+			uniTransition
+		},
+		props: {
+			// 开启动画
+			animation: {
+				type: Boolean,
+				default: true
+			},
+			// 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
+			type: {
+				type: String,
+				default: 'center'
+			},
+			// maskClick
+			maskClick: {
+				type: Boolean,
+				default: true
+			}
+		},
+		data() {
+			return {
+				duration: 300,
+				ani: [],
+				showPopup: false,
+				showTrans: false,
+				maskClass: {
+					'position': 'fixed',
+					'bottom': 0,
+					'top': 0,
+					'left': 0,
+					'right': 0,
+					'backgroundColor': 'rgba(0, 0, 0, 0.4)'
+				},
+				transClass: {
+					'position': 'fixed',
+					'left': 0,
+					'right': 0,
+				}
+			}
+		},
+		watch: {
+			type: {
+				handler: function(newVal) {
+					switch (this.type) {
+						case 'top':
+							this.ani = ['slide-top']
+							this.transClass = {
+								'position': 'fixed',
+								'left': 0,
+								'right': 0,
+							}
+							break
+						case 'bottom':
+							this.ani = ['slide-bottom']
+							this.transClass = {
+								'position': 'fixed',
+								'left': 0,
+								'right': 0,
+								'bottom': 0
+							}
+							break
+						case 'center':
+							this.ani = ['zoom-out', 'fade']
+							this.transClass = {
+								'position': 'fixed',
+								/* #ifndef APP-NVUE */
+								'display': 'flex',
+								'flexDirection': 'column',
+								/* #endif */
+								'bottom': 0,
+								'left': 0,
+								'right': 0,
+								'top': 0,
+								'justifyContent': 'center',
+								'alignItems': 'center'
+							}
+
+							break
+					}
+				},
+				immediate: true
+			}
+		},
+		created() {
+			if (this.animation) {
+				this.duration = 300
+			} else {
+				this.duration = 0
+			} 
+		},
+		provide() {
+			return {
+				popup: this
+			}
+		},
+		mixins: [popup],
+
+		methods: {
+			clear(e) {
+				// TODO nvue 取消冒泡
+				e.stopPropagation()
+			},
+
+			open() {
+				this.showPopup = true
+				this.$nextTick(() => {
+					new Promise(resolve => {
+						clearTimeout(this.timer)
+						this.timer = setTimeout(() => {
+							this.showTrans = true
+							// fixed by mehaotian 兼容 app 端
+							this.$nextTick(() => {
+								resolve();
+							})
+						}, 50);
+					}).then(res => {
+						// 自定义打开事件
+						clearTimeout(this.msgtimer)
+						this.msgtimer = setTimeout(() => {
+							this.customOpen && this.customOpen()
+						}, 100)
+						this.$emit('change', {
+							show: true,
+							type: this.type
+						})
+					})
+				})
+			},
+
+			// open() {
+			// 	this.showPopup = true
+			// 	this.$nextTick(() => {
+			// 		clearTimeout(this.timer)
+			// 		this.timer = setTimeout(() => {
+			// 			this.showTrans = true
+			// 		}, 50);
+			// 	})
+			// 	this.$emit('change', {
+			// 		show: true
+			// 	})
+			// },
+			close(type) {
+				this.showTrans = false
+				this.$nextTick(() => {
+					clearTimeout(this.timer)
+					this.timer = setTimeout(() => {
+						this.$emit('change', {
+							show: false
+						})
+						this.showPopup = false
+					}, 300)
+				})
+			},
+			onTap() {
+				if (!this.maskClick) return
+				this.close()
+			}
+		}
+	}
+</script>
+<style scoped>
+	.uni-popup {
+		position: fixed;
+		/* #ifdef H5 */
+		top: var(--window-top);
+		/* #endif */
+		/* #ifndef H5 */
+		top: 0;
+		/* #endif */
+		bottom: 0;
+		left: 0;
+		right: 0;
+		/* #ifndef APP-NVUE */
+		z-index: 99;
+		/* #endif */
+	}
+
+	.uni-popup__mask {
+		position: absolute;
+		top: 0;
+		bottom: 0;
+		left: 0;
+		right: 0;
+		background-color: rgba(0, 0, 0, 0.4);
+		opacity: 0;
+	}
+
+	.mask-ani {
+		transition-property: opacity;
+		transition-duration: 0.2s;
+	}
+
+	.uni-top-mask {
+		opacity: 1;
+	}
+
+	.uni-bottom-mask {
+		opacity: 1;
+	}
+
+	.uni-center-mask {
+		opacity: 1;
+	}
+
+	.uni-popup__wrapper {
+		/* #ifndef APP-NVUE */
+		display: block;
+		/* #endif */
+		position: absolute;
+	}
+
+	.top {
+		top: 0;
+		left: 0;
+		right: 0;
+		transform: translateY(-500px);
+	}
+
+	.bottom {
+		bottom: 0;
+		left: 0;
+		right: 0;
+		transform: translateY(500px);
+	}
+
+	.center {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		flex-direction: column;
+		/* #endif */
+		bottom: 0;
+		left: 0;
+		right: 0;
+		top: 0;
+		justify-content: center;
+		align-items: center;
+		transform: scale(1.2);
+		opacity: 0;
+	}
+
+	.uni-popup__wrapper-box {
+		/* #ifndef APP-NVUE */
+		display: block;
+		/* #endif */
+		position: relative;
+	}
+
+	.content-ani {
+		/* transition: transform 0.3s;
+ */
+		transition-property: transform, opacity;
+		transition-duration: 0.2s;
+	}
+
+
+	.uni-top-content {
+		transform: translateY(0);
+	}
+
+	.uni-bottom-content {
+		transform: translateY(0);
+	}
+
+	.uni-center-content {
+		transform: scale(1);
+		opacity: 1;
+	}
+</style>

+ 4 - 0
components/zx-uni-search-bar/i18n/en.json

@@ -0,0 +1,4 @@
+{
+	"uni-search-bar.cancel": "cancel",
+	"uni-search-bar.placeholder": "Search enter content"
+}

+ 8 - 0
components/zx-uni-search-bar/i18n/index.js

@@ -0,0 +1,8 @@
+import en from './en.json'
+import zhHans from './zh-Hans.json'
+import zhHant from './zh-Hant.json'
+export default {
+	en,
+	'zh-Hans': zhHans,
+	'zh-Hant': zhHant
+}

+ 4 - 0
components/zx-uni-search-bar/i18n/zh-Hans.json

@@ -0,0 +1,4 @@
+{
+	"uni-search-bar.cancel": "cancel",
+	"uni-search-bar.placeholder": "请输入搜索内容"
+}

+ 4 - 0
components/zx-uni-search-bar/i18n/zh-Hant.json

@@ -0,0 +1,4 @@
+{
+	"uni-search-bar.cancel": "cancel",
+	"uni-search-bar.placeholder": "請輸入搜索內容"
+}

+ 287 - 0
components/zx-uni-search-bar/uni-search-bar.vue

@@ -0,0 +1,287 @@
+s<template>
+	<view class="uni-searchbar">
+		<view :style="{borderRadius:radius+'px',backgroundColor: bgColor}" class="uni-searchbar__box" @click="searchClick">
+			<view class="uni-searchbar__box-icon-search">
+				<slot name="searchIcon">
+					<uni-icons color="#c0c4cc" size="18" type="search" />
+				</slot>
+			</view>
+			<input v-if="show || searchVal" :focus="showSync" :placeholder="placeholderText" :maxlength="maxlength" class="uni-searchbar__box-search-input"
+			 confirm-type="search" type="text" v-model="searchVal" @confirm="confirm" @blur="blur" @focus="emitFocus" />
+			<text v-else class="uni-searchbar__text-placeholder">{{ placeholder }}</text>
+			<view v-if="show && (clearButton==='always'||clearButton==='auto'&&searchVal!=='')" class="uni-searchbar__box-icon-clear"
+			 @click="clear">
+				<slot name="clearIcon">
+					<uni-icons color="#c0c4cc" size="20" type="clear" />
+				</slot>
+			</view>
+		</view>
+		<text @click="cancel" class="uni-searchbar__cancel" v-if="cancelButton ==='always' || show && cancelButton ==='auto'">{{cancelTextI18n}}</text>
+	</view>
+</template>
+
+<script>
+	import {
+	initVueI18n
+	} from '@dcloudio/uni-i18n'
+	import messages from './i18n/index.js'
+	const {	t	} = initVueI18n(messages)
+
+	/**
+	 * SearchBar 搜索栏
+	 * @description 搜索栏组件,通常用于搜索商品、文章等
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=866
+	 * @property {Number} radius 搜索栏圆角
+	 * @property {Number} maxlength 输入最大长度
+	 * @property {String} placeholder 搜索栏Placeholder
+	 * @property {String} clearButton = [always|auto|none] 是否显示清除按钮
+	 * 	@value always 一直显示
+	 * 	@value auto 输入框不为空时显示
+	 * 	@value none 一直不显示
+	 * @property {String} cancelButton = [always|auto|none] 是否显示取消按钮
+	 * 	@value always 一直显示
+	 * 	@value auto 输入框不为空时显示
+	 * 	@value none 一直不显示
+	 * @property {String} cancelText 取消按钮的文字
+	 * @property {String} bgColor 输入框背景颜色
+	 * @property {Boolean} focus 是否自动聚焦
+	 * @event {Function} confirm uniSearchBar 的输入框 confirm 事件,返回参数为uniSearchBar的value,e={value:Number}
+	 * @event {Function} input uniSearchBar 的 value 改变时触发事件,返回参数为uniSearchBar的value,e=value
+	 * @event {Function} cancel 点击取消按钮时触发事件,返回参数为uniSearchBar的value,e={value:Number}
+	 * @event {Function} clear 点击清除按钮时触发事件,返回参数为uniSearchBar的value,e={value:Number}
+	 * @event {Function} blur input失去焦点时触发事件,返回参数为uniSearchBar的value,e={value:Number}
+	 */
+
+	export default {
+		name: "UniSearchBar",
+		emits:['input','update:modelValue','clear','cancel','confirm','blur','focus'],
+		props: {
+			placeholder: {
+				type: String,
+				default: ""
+			},
+			radius: {
+				type: [Number, String],
+				default: 5
+			},
+			clearButton: {
+				type: String,
+				default: "auto"
+			},
+			cancelButton: {
+				type: String,
+				default: "auto"
+			},
+			cancelText: {
+				type: String,
+				default: '取消'
+			},
+			bgColor: {
+				type: String,
+				default: "#F8F8F8"
+			},
+			maxlength: {
+				type: [Number, String],
+				default: 100
+			},
+			value: {
+				type: [Number, String],
+				default: ""
+			},
+			modelValue: {
+				type: [Number, String],
+				default: ""
+			},
+			focus: {
+				type: Boolean,
+				default: false
+			}
+		},
+		data() {
+			return {
+				show: false,
+				showSync: false,
+				searchVal: ''
+			}
+		},
+		computed:{
+			cancelTextI18n() {
+				return this.cancelText || t("uni-search-bar.cancel")
+			},
+			placeholderText() {
+				return this.placeholder || t("uni-search-bar.placeholder")
+			}
+		},
+		watch: {
+			// #ifndef VUE3
+			value: {
+				immediate: true,
+				handler(newVal) {
+					this.searchVal = newVal
+					if (newVal) {
+						this.show = true
+					}
+				}
+			},
+			// #endif
+			// #ifdef VUE3
+			modelValue: {
+				immediate: true,
+				handler(newVal) {
+					this.searchVal = newVal
+					if (newVal) {
+						this.show = true
+					}
+				}
+			},
+			// #endif
+			focus: {
+				immediate: true,
+				handler(newVal) {
+					if (newVal) {
+						this.show = true;
+						this.$nextTick(() => {
+							this.showSync = true
+						})
+					}
+				}
+			},
+			searchVal(newVal, oldVal) {
+				// #ifndef VUE3
+				this.$emit("input", newVal)
+				// #endif
+				// #ifdef VUE3
+				this.$emit("update:modelValue", newVal)
+				// #endif
+			}
+		},
+		methods: {
+			searchClick() {
+				if (this.show) {
+					return
+				}
+				this.show = true;
+				this.$nextTick(() => {
+					this.showSync = true
+				})
+			},
+			clear() {
+				this.$emit("clear", {
+					value: this.searchVal
+				})
+				this.searchVal = ""
+			},
+			cancel() {
+				this.$emit("cancel", {
+					value: this.searchVal
+				});
+				this.searchVal = ""
+				this.show = false
+				this.showSync = false
+				// #ifndef APP-PLUS
+				uni.hideKeyboard()
+				// #endif
+				// #ifdef APP-PLUS
+				plus.key.hideSoftKeybord()
+				// #endif
+			},
+			confirm() {
+				// #ifndef APP-PLUS
+				uni.hideKeyboard();
+				// #endif
+				// #ifdef APP-PLUS
+				plus.key.hideSoftKeybord()
+				// #endif
+				this.$emit("confirm", {
+					value: this.searchVal
+				})
+			},
+			blur() {
+				// #ifndef APP-PLUS
+				uni.hideKeyboard();
+				// #endif
+				// #ifdef APP-PLUS
+				plus.key.hideSoftKeybord()
+				// #endif
+				this.$emit("blur", {
+					value: this.searchVal
+				})
+			},
+			emitFocus(e) {
+				this.$emit("focus", e.detail)
+			}
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	$uni-searchbar-height: 36px;
+
+	.uni-searchbar {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		position: relative;
+		padding: 10px;
+		// background-color: #fff;
+	}
+
+	.uni-searchbar__box {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		box-sizing: border-box;
+		/* #endif */
+		overflow: hidden;
+		position: relative;
+		flex: 1;
+		justify-content: center;
+		flex-direction: row;
+		align-items: center;
+		height: $uni-searchbar-height;
+		padding: 5px 8px 5px 0px;
+	}
+
+	.uni-searchbar__box-icon-search {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		// width: 32px;
+		padding: 0 8px;
+		justify-content: center;
+		align-items: center;
+		color: #B3B3B3;
+	}
+
+	.uni-searchbar__box-search-input {
+		flex: 1;
+		font-size: 14px;
+		color: #333;
+	}
+
+	.uni-searchbar__box-icon-clear {
+		align-items: center;
+		line-height: 24px;
+		padding-left: 8px;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-searchbar__text-placeholder {
+		font-size: 14px;
+		color: #B3B3B3;
+		margin-left: 5px;
+	}
+
+	.uni-searchbar__cancel {
+		padding-left: 10px;
+		line-height: $uni-searchbar-height;
+		font-size: 14px;
+		color: #333333;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+</style>

+ 30 - 0
jweixin-module/README.md

@@ -0,0 +1,30 @@
+# jweixin-module
+
+微信JS-SDK
+
+## 安装
+
+### NPM
+
+```shell
+npm install jweixin-module --save
+```
+
+### UMD
+
+```http
+https://unpkg.com/jweixin-module/out/index.js
+```
+
+## 使用
+
+```js
+var jweixin = require('jweixin-module')
+jweixin.ready(function(){
+    // TODO
+});
+```
+
+## 完整API
+
+>[微信JS-SDK说明文档](https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115)

+ 714 - 0
jweixin-module/lib/index.js

@@ -0,0 +1,714 @@
+! function(e, n) {
+	"function" == typeof define && (define.amd || define.cmd) ? define(function() {
+		return n(e)
+	}) : n(e, !0)
+}(window, function(o, e) {
+	if (!o.jWeixin) {
+		var n, c = {
+				config: "preVerifyJSAPI",
+				onMenuShareTimeline: "menu:share:timeline",
+				onMenuShareAppMessage: "menu:share:appmessage",
+				onMenuShareQQ: "menu:share:qq",
+				onMenuShareWeibo: "menu:share:weiboApp",
+				onMenuShareQZone: "menu:share:QZone",
+				previewImage: "imagePreview",
+				getLocation: "geoLocation",
+				openProductSpecificView: "openProductViewWithPid",
+				addCard: "batchAddCard",
+				openCard: "batchViewCard",
+				chooseWXPay: "getBrandWCPayRequest",
+				openEnterpriseRedPacket: "getRecevieBizHongBaoRequest",
+				startSearchBeacons: "startMonitoringBeacons",
+				stopSearchBeacons: "stopMonitoringBeacons",
+				onSearchBeacons: "onBeaconsInRange",
+				consumeAndShareCard: "consumedShareCard",
+				openAddress: "editAddress"
+			},
+			a = function() {
+				var e = {};
+				for (var n in c) e[c[n]] = n;
+				return e
+			}(),
+			i = o.document,
+			t = i.title,
+			r = navigator.userAgent.toLowerCase(),
+			s = navigator.platform.toLowerCase(),
+			d = !(!s.match("mac") && !s.match("win")),
+			u = -1 != r.indexOf("wxdebugger"),
+			l = -1 != r.indexOf("micromessenger"),
+			p = -1 != r.indexOf("android"),
+			f = -1 != r.indexOf("iphone") || -1 != r.indexOf("ipad"),
+			m = (n = r.match(/micromessenger\/(\d+\.\d+\.\d+)/) || r.match(/micromessenger\/(\d+\.\d+)/)) ? n[1] : "",
+			g = {
+				initStartTime: L(),
+				initEndTime: 0,
+				preVerifyStartTime: 0,
+				preVerifyEndTime: 0
+			},
+			h = {
+				version: 1,
+				appId: "",
+				initTime: 0,
+				preVerifyTime: 0,
+				networkType: "",
+				isPreVerifyOk: 1,
+				systemType: f ? 1 : p ? 2 : -1,
+				clientVersion: m,
+				url: encodeURIComponent(location.href)
+			},
+			v = {},
+			S = {
+				_completes: []
+			},
+			y = {
+				state: 0,
+				data: {}
+			};
+		O(function() {
+			g.initEndTime = L()
+		});
+		var I = !1,
+			_ = [],
+			w = {
+				config: function(e) {
+					B("config", v = e);
+					var t = !1 !== v.check;
+					O(function() {
+						if (t) M(c.config, {
+							verifyJsApiList: C(v.jsApiList),
+							verifyOpenTagList: C(v.openTagList)
+						}, function() {
+							S._complete = function(e) {
+								g.preVerifyEndTime = L(), y.state = 1, y.data = e
+							}, S.success = function(e) {
+								h.isPreVerifyOk = 0
+							}, S.fail = function(e) {
+								S._fail ? S._fail(e) : y.state = -1
+							};
+							var t = S._completes;
+							return t.push(function() {
+								! function() {
+									if (!(d || u || v.debug || m < "6.0.2" || h.systemType < 0)) {
+										var i = new Image;
+										h.appId = v.appId, h.initTime = g.initEndTime - g.initStartTime, h.preVerifyTime = g.preVerifyEndTime -
+											g.preVerifyStartTime, w.getNetworkType({
+												isInnerInvoke: !0,
+												success: function(e) {
+													h.networkType = e.networkType;
+													var n = "https://open.weixin.qq.com/sdk/report?v=" + h.version + "&o=" + h.isPreVerifyOk + "&s=" +
+														h.systemType + "&c=" + h.clientVersion + "&a=" + h.appId + "&n=" + h.networkType + "&i=" + h.initTime +
+														"&p=" + h.preVerifyTime + "&u=" + h.url;
+													i.src = n
+												}
+											})
+									}
+								}()
+							}), S.complete = function(e) {
+								for (var n = 0, i = t.length; n < i; ++n) t[n]();
+								S._completes = []
+							}, S
+						}()), g.preVerifyStartTime = L();
+						else {
+							y.state = 1;
+							for (var e = S._completes, n = 0, i = e.length; n < i; ++n) e[n]();
+							S._completes = []
+						}
+					}), w.invoke || (w.invoke = function(e, n, i) {
+						o.WeixinJSBridge && WeixinJSBridge.invoke(e, x(n), i)
+					}, w.on = function(e, n) {
+						o.WeixinJSBridge && WeixinJSBridge.on(e, n)
+					})
+				},
+				ready: function(e) {
+					0 != y.state ? e() : (S._completes.push(e), !l && v.debug && e())
+				},
+				error: function(e) {
+					m < "6.0.2" || (-1 == y.state ? e(y.data) : S._fail = e)
+				},
+				checkJsApi: function(e) {
+					M("checkJsApi", {
+						jsApiList: C(e.jsApiList)
+					}, (e._complete = function(e) {
+						if (p) {
+							var n = e.checkResult;
+							n && (e.checkResult = JSON.parse(n))
+						}
+						e = function(e) {
+							var n = e.checkResult;
+							for (var i in n) {
+								var t = a[i];
+								t && (n[t] = n[i], delete n[i])
+							}
+							return e
+						}(e)
+					}, e))
+				},
+				onMenuShareTimeline: function(e) {
+					P(c.onMenuShareTimeline, {
+						complete: function() {
+							M("shareTimeline", {
+								title: e.title || t,
+								desc: e.title || t,
+								img_url: e.imgUrl || "",
+								link: e.link || location.href,
+								type: e.type || "link",
+								data_url: e.dataUrl || ""
+							}, e)
+						}
+					}, e)
+				},
+				onMenuShareAppMessage: function(n) {
+					P(c.onMenuShareAppMessage, {
+						complete: function(e) {
+							"favorite" === e.scene ? M("sendAppMessage", {
+								title: n.title || t,
+								desc: n.desc || "",
+								link: n.link || location.href,
+								img_url: n.imgUrl || "",
+								type: n.type || "link",
+								data_url: n.dataUrl || ""
+							}) : M("sendAppMessage", {
+								title: n.title || t,
+								desc: n.desc || "",
+								link: n.link || location.href,
+								img_url: n.imgUrl || "",
+								type: n.type || "link",
+								data_url: n.dataUrl || ""
+							}, n)
+						}
+					}, n)
+				},
+				onMenuShareQQ: function(e) {
+					P(c.onMenuShareQQ, {
+						complete: function() {
+							M("shareQQ", {
+								title: e.title || t,
+								desc: e.desc || "",
+								img_url: e.imgUrl || "",
+								link: e.link || location.href
+							}, e)
+						}
+					}, e)
+				},
+				onMenuShareWeibo: function(e) {
+					P(c.onMenuShareWeibo, {
+						complete: function() {
+							M("shareWeiboApp", {
+								title: e.title || t,
+								desc: e.desc || "",
+								img_url: e.imgUrl || "",
+								link: e.link || location.href
+							}, e)
+						}
+					}, e)
+				},
+				onMenuShareQZone: function(e) {
+					P(c.onMenuShareQZone, {
+						complete: function() {
+							M("shareQZone", {
+								title: e.title || t,
+								desc: e.desc || "",
+								img_url: e.imgUrl || "",
+								link: e.link || location.href
+							}, e)
+						}
+					}, e)
+				},
+				updateTimelineShareData: function(e) {
+					M("updateTimelineShareData", {
+						title: e.title,
+						link: e.link,
+						imgUrl: e.imgUrl
+					}, e)
+				},
+				updateAppMessageShareData: function(e) {
+					M("updateAppMessageShareData", {
+						title: e.title,
+						desc: e.desc,
+						link: e.link,
+						imgUrl: e.imgUrl
+					}, e)
+				},
+				startRecord: function(e) {
+					M("startRecord", {}, e)
+				},
+				stopRecord: function(e) {
+					M("stopRecord", {}, e)
+				},
+				onVoiceRecordEnd: function(e) {
+					P("onVoiceRecordEnd", e)
+				},
+				playVoice: function(e) {
+					M("playVoice", {
+						localId: e.localId
+					}, e)
+				},
+				pauseVoice: function(e) {
+					M("pauseVoice", {
+						localId: e.localId
+					}, e)
+				},
+				stopVoice: function(e) {
+					M("stopVoice", {
+						localId: e.localId
+					}, e)
+				},
+				onVoicePlayEnd: function(e) {
+					P("onVoicePlayEnd", e)
+				},
+				uploadVoice: function(e) {
+					M("uploadVoice", {
+						localId: e.localId,
+						isShowProgressTips: 0 == e.isShowProgressTips ? 0 : 1
+					}, e)
+				},
+				downloadVoice: function(e) {
+					M("downloadVoice", {
+						serverId: e.serverId,
+						isShowProgressTips: 0 == e.isShowProgressTips ? 0 : 1
+					}, e)
+				},
+				translateVoice: function(e) {
+					M("translateVoice", {
+						localId: e.localId,
+						isShowProgressTips: 0 == e.isShowProgressTips ? 0 : 1
+					}, e)
+				},
+				chooseImage: function(e) {
+					M("chooseImage", {
+						scene: "1|2",
+						count: e.count || 9,
+						sizeType: e.sizeType || ["original", "compressed"],
+						sourceType: e.sourceType || ["album", "camera"]
+					}, (e._complete = function(e) {
+						if (p) {
+							var n = e.localIds;
+							try {
+								n && (e.localIds = JSON.parse(n))
+							} catch (e) {}
+						}
+					}, e))
+				},
+				getLocation: function(e) {},
+				previewImage: function(e) {
+					M(c.previewImage, {
+						current: e.current,
+						urls: e.urls
+					}, e)
+				},
+				uploadImage: function(e) {
+					M("uploadImage", {
+						localId: e.localId,
+						isShowProgressTips: 0 == e.isShowProgressTips ? 0 : 1
+					}, e)
+				},
+				downloadImage: function(e) {
+					M("downloadImage", {
+						serverId: e.serverId,
+						isShowProgressTips: 0 == e.isShowProgressTips ? 0 : 1
+					}, e)
+				},
+				getLocalImgData: function(e) {
+					!1 === I ? (I = !0, M("getLocalImgData", {
+						localId: e.localId
+					}, (e._complete = function(e) {
+						if (I = !1, 0 < _.length) {
+							var n = _.shift();
+							wx.getLocalImgData(n)
+						}
+					}, e))) : _.push(e)
+				},
+				getNetworkType: function(e) {
+					M("getNetworkType", {}, (e._complete = function(e) {
+						e = function(e) {
+							var n = e.errMsg;
+							e.errMsg = "getNetworkType:ok";
+							var i = e.subtype;
+							if (delete e.subtype, i) e.networkType = i;
+							else {
+								var t = n.indexOf(":"),
+									o = n.substring(t + 1);
+								switch (o) {
+									case "wifi":
+									case "edge":
+									case "wwan":
+										e.networkType = o;
+										break;
+									default:
+										e.errMsg = "getNetworkType:fail"
+								}
+							}
+							return e
+						}(e)
+					}, e))
+				},
+				openLocation: function(e) {
+					M("openLocation", {
+						latitude: e.latitude,
+						longitude: e.longitude,
+						name: e.name || "",
+						address: e.address || "",
+						scale: e.scale || 28,
+						infoUrl: e.infoUrl || ""
+					}, e)
+				},
+				getLocation: function(e) {
+					M(c.getLocation, {
+						type: (e = e || {}).type || "wgs84"
+					}, (e._complete = function(e) {
+						delete e.type
+					}, e))
+				},
+				hideOptionMenu: function(e) {
+					M("hideOptionMenu", {}, e)
+				},
+				showOptionMenu: function(e) {
+					M("showOptionMenu", {}, e)
+				},
+				closeWindow: function(e) {
+					M("closeWindow", {}, e = e || {})
+				},
+				hideMenuItems: function(e) {
+					M("hideMenuItems", {
+						menuList: e.menuList
+					}, e)
+				},
+				showMenuItems: function(e) {
+					M("showMenuItems", {
+						menuList: e.menuList
+					}, e)
+				},
+				hideAllNonBaseMenuItem: function(e) {
+					M("hideAllNonBaseMenuItem", {}, e)
+				},
+				showAllNonBaseMenuItem: function(e) {
+					M("showAllNonBaseMenuItem", {}, e)
+				},
+				scanQRCode: function(e) {
+					M("scanQRCode", {
+						needResult: (e = e || {}).needResult || 0,
+						scanType: e.scanType || ["qrCode", "barCode"]
+					}, (e._complete = function(e) {
+						if (f) {
+							var n = e.resultStr;
+							if (n) {
+								var i = JSON.parse(n);
+								e.resultStr = i && i.scan_code && i.scan_code.scan_result
+							}
+						}
+					}, e))
+				},
+				openAddress: function(e) {
+					M(c.openAddress, {}, (e._complete = function(e) {
+						e = function(e) {
+							return e.postalCode = e.addressPostalCode, delete e.addressPostalCode, e.provinceName = e.proviceFirstStageName,
+								delete e.proviceFirstStageName, e.cityName = e.addressCitySecondStageName, delete e.addressCitySecondStageName,
+								e.countryName = e.addressCountiesThirdStageName, delete e.addressCountiesThirdStageName, e.detailInfo = e
+								.addressDetailInfo, delete e.addressDetailInfo, e
+						}(e)
+					}, e))
+				},
+				openProductSpecificView: function(e) {
+					M(c.openProductSpecificView, {
+						pid: e.productId,
+						view_type: e.viewType || 0,
+						ext_info: e.extInfo
+					}, e)
+				},
+				addCard: function(e) {
+					for (var n = e.cardList, i = [], t = 0, o = n.length; t < o; ++t) {
+						var r = n[t],
+							a = {
+								card_id: r.cardId,
+								card_ext: r.cardExt
+							};
+						i.push(a)
+					}
+					M(c.addCard, {
+						card_list: i
+					}, (e._complete = function(e) {
+						var n = e.card_list;
+						if (n) {
+							for (var i = 0, t = (n = JSON.parse(n)).length; i < t; ++i) {
+								var o = n[i];
+								o.cardId = o.card_id, o.cardExt = o.card_ext, o.isSuccess = !!o.is_succ, delete o.card_id, delete o.card_ext,
+									delete o.is_succ
+							}
+							e.cardList = n, delete e.card_list
+						}
+					}, e))
+				},
+				chooseCard: function(e) {
+					M("chooseCard", {
+						app_id: v.appId,
+						location_id: e.shopId || "",
+						sign_type: e.signType || "SHA1",
+						card_id: e.cardId || "",
+						card_type: e.cardType || "",
+						card_sign: e.cardSign,
+						time_stamp: e.timestamp + "",
+						nonce_str: e.nonceStr
+					}, (e._complete = function(e) {
+						e.cardList = e.choose_card_info, delete e.choose_card_info
+					}, e))
+				},
+				openCard: function(e) {
+					for (var n = e.cardList, i = [], t = 0, o = n.length; t < o; ++t) {
+						var r = n[t],
+							a = {
+								card_id: r.cardId,
+								code: r.code
+							};
+						i.push(a)
+					}
+					M(c.openCard, {
+						card_list: i
+					}, e)
+				},
+				consumeAndShareCard: function(e) {
+					M(c.consumeAndShareCard, {
+						consumedCardId: e.cardId,
+						consumedCode: e.code
+					}, e)
+				},
+				chooseWXPay: function(e) {
+					M(c.chooseWXPay, V(e), e)
+				},
+				openEnterpriseRedPacket: function(e) {
+					M(c.openEnterpriseRedPacket, V(e), e)
+				},
+				startSearchBeacons: function(e) {
+					M(c.startSearchBeacons, {
+						ticket: e.ticket
+					}, e)
+				},
+				stopSearchBeacons: function(e) {
+					M(c.stopSearchBeacons, {}, e)
+				},
+				onSearchBeacons: function(e) {
+					P(c.onSearchBeacons, e)
+				},
+				openEnterpriseChat: function(e) {
+					M("openEnterpriseChat", {
+						useridlist: e.userIds,
+						chatname: e.groupName
+					}, e)
+				},
+				launchMiniProgram: function(e) {
+					M("launchMiniProgram", {
+						targetAppId: e.targetAppId,
+						path: function(e) {
+							if ("string" == typeof e && 0 < e.length) {
+								var n = e.split("?")[0],
+									i = e.split("?")[1];
+								return n += ".html", void 0 !== i ? n + "?" + i : n
+							}
+						}(e.path),
+						envVersion: e.envVersion
+					}, e)
+				},
+				openBusinessView: function(e) {
+					M("openBusinessView", {
+						businessType: e.businessType,
+						queryString: e.queryString || "",
+						envVersion: e.envVersion
+					}, (e._complete = function(n) {
+						if (p) {
+							var e = n.extraData;
+							if (e) try {
+								n.extraData = JSON.parse(e)
+							} catch (e) {
+								n.extraData = {}
+							}
+						}
+					}, e))
+				},
+				miniProgram: {
+					navigateBack: function(e) {
+						e = e || {}, O(function() {
+							M("invokeMiniProgramAPI", {
+								name: "navigateBack",
+								arg: {
+									delta: e.delta || 1
+								}
+							}, e)
+						})
+					},
+					navigateTo: function(e) {
+						O(function() {
+							M("invokeMiniProgramAPI", {
+								name: "navigateTo",
+								arg: {
+									url: e.url
+								}
+							}, e)
+						})
+					},
+					redirectTo: function(e) {
+						O(function() {
+							M("invokeMiniProgramAPI", {
+								name: "redirectTo",
+								arg: {
+									url: e.url
+								}
+							}, e)
+						})
+					},
+					switchTab: function(e) {
+						O(function() {
+							M("invokeMiniProgramAPI", {
+								name: "switchTab",
+								arg: {
+									url: e.url
+								}
+							}, e)
+						})
+					},
+					reLaunch: function(e) {
+						O(function() {
+							M("invokeMiniProgramAPI", {
+								name: "reLaunch",
+								arg: {
+									url: e.url
+								}
+							}, e)
+						})
+					},
+					postMessage: function(e) {
+						O(function() {
+							M("invokeMiniProgramAPI", {
+								name: "postMessage",
+								arg: e.data || {}
+							}, e)
+						})
+					},
+					getEnv: function(e) {
+						O(function() {
+							e({
+								miniprogram: "miniprogram" === o.__wxjs_environment
+							})
+						})
+					}
+				}
+			},
+			T = 1,
+			k = {};
+		return i.addEventListener("error", function(e) {
+			if (!p) {
+				var n = e.target,
+					i = n.tagName,
+					t = n.src;
+				if ("IMG" == i || "VIDEO" == i || "AUDIO" == i || "SOURCE" == i)
+					if (-1 != t.indexOf("wxlocalresource://")) {
+						e.preventDefault(), e.stopPropagation();
+						var o = n["wx-id"];
+						if (o || (o = T++, n["wx-id"] = o), k[o]) return;
+						k[o] = !0, wx.ready(function() {
+							wx.getLocalImgData({
+								localId: t,
+								success: function(e) {
+									n.src = e.localData
+								}
+							})
+						})
+					}
+			}
+		}, !0), i.addEventListener("load", function(e) {
+			if (!p) {
+				var n = e.target,
+					i = n.tagName;
+				n.src;
+				if ("IMG" == i || "VIDEO" == i || "AUDIO" == i || "SOURCE" == i) {
+					var t = n["wx-id"];
+					t && (k[t] = !1)
+				}
+			}
+		}, !0), e && (o.wx = o.jWeixin = w), w
+	}
+
+	function M(n, e, i) {
+		o.WeixinJSBridge ? WeixinJSBridge.invoke(n, x(e), function(e) {
+			A(n, e, i)
+		}) : B(n, i)
+	}
+
+	function P(n, i, t) {
+		o.WeixinJSBridge ? WeixinJSBridge.on(n, function(e) {
+			t && t.trigger && t.trigger(e), A(n, e, i)
+		}) : B(n, t || i)
+	}
+
+	function x(e) {
+		return (e = e || {}).appId = v.appId, e.verifyAppId = v.appId, e.verifySignType = "sha1", e.verifyTimestamp = v.timestamp +
+			"", e.verifyNonceStr = v.nonceStr, e.verifySignature = v.signature, e
+	}
+
+	function V(e) {
+		return {
+			timeStamp: e.timestamp + "",
+			nonceStr: e.nonceStr,
+			package: e.package,
+			paySign: e.paySign,
+			signType: e.signType || "SHA1"
+		}
+	}
+
+	function A(e, n, i) {
+		"openEnterpriseChat" != e && "openBusinessView" !== e || (n.errCode = n.err_code), delete n.err_code, delete n.err_desc,
+			delete n.err_detail;
+		var t = n.errMsg;
+		t || (t = n.err_msg, delete n.err_msg, t = function(e, n) {
+				var i = e,
+					t = a[i];
+				t && (i = t);
+				var o = "ok";
+				if (n) {
+					var r = n.indexOf(":");
+					"confirm" == (o = n.substring(r + 1)) && (o = "ok"), "failed" == o && (o = "fail"), -1 != o.indexOf("failed_") &&
+						(o = o.substring(7)), -1 != o.indexOf("fail_") && (o = o.substring(5)), "access denied" != (o = (o = o.replace(
+							/_/g, " ")).toLowerCase()) && "no permission to execute" != o || (o = "permission denied"), "config" == i &&
+						"function not exist" == o && (o = "ok"), "" == o && (o = "fail")
+				}
+				return n = i + ":" + o
+			}(e, t), n.errMsg = t), (i = i || {})._complete && (i._complete(n), delete i._complete), t = n.errMsg || "", v.debug &&
+			!i.isInnerInvoke && alert(JSON.stringify(n));
+		var o = t.indexOf(":");
+		switch (t.substring(o + 1)) {
+			case "ok":
+				i.success && i.success(n);
+				break;
+			case "cancel":
+				i.cancel && i.cancel(n);
+				break;
+			default:
+				i.fail && i.fail(n)
+		}
+		i.complete && i.complete(n)
+	}
+
+	function C(e) {
+		if (e) {
+			for (var n = 0, i = e.length; n < i; ++n) {
+				var t = e[n],
+					o = c[t];
+				o && (e[n] = o)
+			}
+			return e
+		}
+	}
+
+	function B(e, n) {
+		if (!(!v.debug || n && n.isInnerInvoke)) {
+			var i = a[e];
+			i && (e = i), n && n._complete && delete n._complete, console.log('"' + e + '",', n || "")
+		}
+	}
+
+	function L() {
+		return (new Date).getTime()
+	}
+
+	function O(e) {
+		l && (o.WeixinJSBridge ? e() : i.addEventListener && i.addEventListener("WeixinJSBridgeReady", e, !1))
+	}
+});

+ 54 - 0
jweixin-module/package.json

@@ -0,0 +1,54 @@
+{
+  "_from": "jweixin-module",
+  "_id": "jweixin-module@1.6.0",
+  "_inBundle": false,
+  "_integrity": "sha512-dGk9cf+ipipHmtzYmKZs5B2toX+p4hLyllGLF6xuC8t+B05oYxd8fYoaRz0T30U2n3RUv8a4iwvjhA+OcYz52w==",
+  "_location": "/jweixin-module",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "tag",
+    "registry": true,
+    "raw": "jweixin-module",
+    "name": "jweixin-module",
+    "escapedName": "jweixin-module",
+    "rawSpec": "",
+    "saveSpec": null,
+    "fetchSpec": "latest"
+  },
+  "_requiredBy": [
+    "#USER",
+    "/"
+  ],
+  "_resolved": "https://registry.npmjs.org/jweixin-module/-/jweixin-module-1.6.0.tgz",
+  "_shasum": "4a7ea614083e3c9c3f49e2fdc2bb882cfa58dfcd",
+  "_spec": "jweixin-module",
+  "_where": "D:\\",
+  "author": {
+    "name": "Shengqiang Guo"
+  },
+  "bugs": {
+    "url": "https://github.com/zhetengbiji/jweixin-module/issues"
+  },
+  "bundleDependencies": false,
+  "deprecated": false,
+  "description": "微信JS-SDK",
+  "devDependencies": {},
+  "homepage": "https://github.com/zhetengbiji/jweixin-module#readme",
+  "keywords": [
+    "wxjssdk",
+    "weixin",
+    "jweixin",
+    "wechat",
+    "jssdk",
+    "wx"
+  ],
+  "license": "ISC",
+  "main": "lib/index.js",
+  "name": "jweixin-module",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/zhetengbiji/jweixin-module.git"
+  },
+  "scripts": {},
+  "version": "1.6.0"
+}

+ 46 - 0
main.js

@@ -0,0 +1,46 @@
+import Vue from 'vue'
+import App from './App'
+
+import http from './static/js/http.js'
+// import http2 from './static/js/http2.js'
+
+import noNone from './static/html/no-none.vue'
+import noNoneTwo from './static/html/no-none2.vue'
+
+import httpUpload from './static/js/http-upload.js'
+
+import siteinfo from './siteinfo.js'
+Vue.prototype.$siteroot = siteinfo.siteroot
+
+import test from './static/js/test.js'
+Vue.prototype.$test = test
+
+import utils from './static/js/utils.js'
+Vue.prototype.$utils = utils
+ // #ifdef H5
+var jweixin = require('@/jweixin-module/lib/index.js');
+Vue.prototype.$wx = jweixin 
+// #endif
+import load from './static/html/load.vue'
+
+import store from './store/index.js'
+Vue.prototype.$store = store
+
+Vue.component('loading',load)
+Vue.config.productionTip = false
+import pageBtmBar from './components/page-btm-bar/page-btm-bar.vue'
+Vue.component('page-btm-bar',pageBtmBar)
+import VueJsonp from 'vue-jsonp';
+Vue.use(VueJsonp);
+Vue.prototype.request = http
+// Vue.prototype.http2 = http2
+Vue.component('no-none',noNone)
+Vue.component('no-none-two',noNoneTwo)
+
+Vue.prototype.Upload = httpUpload
+App.mpType = 'app'
+
+const app = new Vue({
+    ...App
+})
+app.$mount()

+ 112 - 0
manifest.json

@@ -0,0 +1,112 @@
+{
+    "name" : "无痕广告",
+    "appid" : "__UNI__C7A7BA2",
+    "description" : "",
+    "versionName" : "1.0.0",
+    "versionCode" : "100",
+    "transformPx" : false,
+    /* 5+App特有相关 */
+    "app-plus" : {
+        "usingComponents" : true,
+        "nvueCompiler" : "uni-app",
+        "compilerVersion" : 3,
+        "splashscreen" : {
+            "alwaysShowBeforeRender" : true,
+            "waiting" : true,
+            "autoclose" : true,
+            "delay" : 0
+        },
+        /* 模块配置 */
+        "modules" : {},
+        /* 应用发布信息 */
+        "distribute" : {
+            /* android打包配置 */
+            "android" : {
+                "permissions" : [
+                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
+                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+                    "<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
+                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+                    "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+                    "<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
+                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+                ]
+            },
+            /* ios打包配置 */
+            "ios" : {},
+            /* SDK配置 */
+            "sdkConfigs" : {}
+        }
+    },
+    /* 快应用特有相关 */
+    "quickapp" : {},
+    /* 小程序特有相关 */
+    "mp-weixin" : {
+        "appid" : "wx9afe1e38049ad81b",
+        "setting" : {
+            "urlCheck" : false,
+            "es6" : false,
+            "postcss" : true,
+            "minified" : true
+        },
+        "usingComponents" : true,
+        "optimization" : {
+            "subPackages" : true
+        },
+        "permission" : {
+            "scope.userLocation" : {
+                "desc" : "获取地址"
+            }
+        },
+        "requiredPrivateInfos" : [ "chooseLocation" ]
+    },
+    "mp-alipay" : {
+        "usingComponents" : true
+    },
+    "mp-baidu" : {
+        "usingComponents" : true
+    },
+    "mp-toutiao" : {
+        "usingComponents" : true
+    },
+    "uniStatistics" : {
+        "enable" : false
+    },
+    "h5" : {
+        "devServer" : {
+            "https" : false
+        },
+        "router" : {
+            "mode" : "history",
+            "base" : "/forward/"
+        },
+        "title" : " ",
+        "sdkConfigs" : {
+            "maps" : {
+                "qqmap" : {
+                    "key" : "SOUBZ-3EQWO-FVRWG-SFXV2-O3WYO-VJBMP"
+                }
+            }
+        },
+        "optimization" : {
+            "treeShaking" : {
+                "enable" : true
+            }
+        }
+    }
+}

+ 299 - 0
merchant/Applied.vue

@@ -0,0 +1,299 @@
+<template>
+	<view>
+
+		<view class="" style="height: 20rpx;"></view>
+
+		<!-- 核销号码 -->
+		<view class="appliedNum flex-y-center flex-between ">
+			<view class="appliedNumText">优惠券核销码</view>
+			<input type="text" :value="codes" @input="appliedTab" class="appliedNuminput" placeholder-class="appliedNumpleahode"
+			 placeholder="请输入优惠券核销码" />
+		</view>
+
+		<!-- 圆圈扩散 -->
+		<view class="point point-flicker" @click="scan">
+			<image src="./static/images/my_icon_6.png" mode="" class="scanTextsImgs"></image>
+			<view class="scanTexts">扫码核销</view>
+		</view>
+		<!-- 圆圈扩散end -->
+
+		<!-- 底部按钮 -->
+		<view class="bottomButton" @click="confirm">核销</view>
+	</view>
+</template>
+
+<script>
+	// #ifdef H5
+	import getWXSign from "@/static/js/config.js";
+	// #endif 
+	export default {
+		data() {
+			return {
+				codes: '', //优惠券code码
+				is_hexiao:false
+			}
+		},
+
+		onLoad() {
+			
+			if(uni.getStorageSync("is_login")=="2"){
+				this.is_hexiao=true;
+			}
+			
+		},
+		
+		onShow() {
+
+		},
+
+
+		methods: {
+			//输入核销码
+			appliedTab(e) {
+				this.codes = e.detail.value;
+			},
+			
+			//扫描核销
+			scan() {
+				// #ifdef MP-WEIXIN
+		         uni.scanCode({
+					success: (res)=> {
+						this.verification(res.result);
+					}
+				});
+				// #endif
+				// #ifdef H5
+				getWXSign().then(res => {
+					console.log('wx_getLocation');
+					this.$wx.scanQRCode({
+						needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
+						scanType: ["qrCode", "barCode"], // 可以指定扫二维码还是一维码,默认二者都有
+						success: (res) => {
+							console.log(res, "qrCode")
+							this.verification(res.resultStr);
+						}
+					})
+				})
+				// #endif	
+			},
+			
+			//确定核销
+			confirm() {
+				if (!this.codes) {
+					uni.showToast({
+						title: '请输入核销码',
+						icon: 'none'
+					})
+					return false
+				}
+				this.verification(this.codes);
+			},
+
+			//请求详情
+			verification(code) {
+				this.request({
+					url:"coupon/verification",
+					data: {
+						token: uni.getStorageSync('token'),
+						code: code,
+					},
+				   }).then(res => {
+					if (res.code == "200") {
+						uni.showModal({
+							title: '温馨提示',
+							content: '核销成功',
+							showCancel: false,
+							confirmColor:"#000000",
+							confirmText: '确定',
+							success: (res) => {
+								if (res.confirm) {
+					                   this.codes = "";
+								}
+							},
+							fail: () => {},
+							complete: () => {}
+						});
+					}
+				}).catch((res) => {
+					console.log(res,"666")
+					uni.showToast({
+						title: res.message,
+						icon: 'none'
+					})
+				});
+			},
+			
+		}
+	}
+</script>
+
+<style>
+	page {
+		background: #F5F7FA;
+	}
+
+	.flex-between {
+		display: flex;
+		flex-flow: row nowrap;
+		justify-content: space-between;
+		align-items: center;
+	}
+
+	.flex-y-center {
+		display: -webkit-box;
+		display: -webkit-flex;
+		display: flex;
+		-webkit-box-align: center;
+		-webkit-align-items: center;
+		-ms-flex-align: center;
+		-ms-grid-row-align: center;
+		align-items: center;
+	}
+
+	.appliedNum {
+		height: 100rpx;
+		background: #fff;
+		/* margin-top: 10rpx; */
+	}
+
+	.appliedNumText {
+		padding-left: 30rpx;
+		font-size: 28rpx;
+		font-family: PingFang SC, PingFang SC-Regular;
+		font-weight: 400;
+		color: #333333;
+
+	}
+
+	.appliedNuminput {
+		flex: 1;
+		text-align: right;
+		padding: 0 30rpx 0 150rpx;
+		font-size: 28rpx;
+		font-family: PingFang SC, PingFang SC-Regular;
+		font-weight: 400;
+		color: #333;
+	}
+
+	.appliedNumpleahode {
+		font-size: 28rpx;
+		font-family: PingFang SC, PingFang SC-Regular;
+		font-weight: 400;
+		color: #666;
+	}
+
+	.appliedNumRgo {
+		height: 100rpx;
+	}
+
+	.appliedNumRgotext {
+		font-size: 28rpx;
+		font-family: PingFang SC, PingFang SC-Regular;
+		font-weight: 400;
+		color: #666666;
+	}
+
+	.appliedNumRgoimg {
+		width: 26rpx;
+		height: 26rpx;
+		margin: 0 30rpx 0 6rpx;
+	}
+
+
+	/* 圆圈扩散 */
+	.point {
+		width: 400rpx;
+		height: 400rpx;
+		position: /* absolute */;
+		left: 170rpx;
+		top: 220rpx;
+		background: linear-gradient(180deg, #6fa5ff, #438aff);
+		position: relative;
+		border-radius: 50%;
+	}
+
+	/* 设置动画前颜色 */
+	.point-flicker:after {
+		background: linear-gradient(180deg, #6fa5ff, #438aff);
+	}
+
+	/* 设置动画后颜色 */
+	.point-flicker:before {
+		background: linear-gradient(180deg, #6fa5ff, #438aff);
+	}
+
+	/* 设置动画 */
+	.point-flicker:before,
+	.point-flicker:after {
+		content: '';
+		width: 400rpx;
+		height: 400rpx;
+		position: absolute;
+		left: 10%;
+		top: 10%;
+		margin-left: -40rpx;
+		margin-top: -40rpx;
+		border-radius: 50%;
+		animation: warn 1.5s ease-out 0s infinite;
+	}
+
+
+	/* @keyframes 规则用于创建动画。在 @keyframes 中规定某项 CSS 样式,就能创建由当前样式逐渐改为新样式的动画效果。 */
+	@keyframes warn {
+
+		0% {
+			transform: scale(0.5);
+			opacity: 1;
+		}
+
+		30% {
+			opacity: 1;
+		}
+
+		100% {
+			transform: scale(1.4);
+			opacity: 0;
+		}
+	}
+
+	/* 圆圈扩散 end*/
+	.scanTextsImgs {
+		width: 100rpx;
+		height: 100rpx;
+		position: absolute;
+		left: 50%;
+		top: 45%;
+		transform: translate(-50%, -50%);
+		z-index: 998;
+	}
+
+	.scanTexts {
+		position: absolute;
+		left: 50%;
+		top: 70%;
+		transform: translate(-50%, -50%);
+		color: #fff;
+		font-size: 36rpx;
+		z-index: 999;
+	}
+
+
+
+	/* 底部按钮 */
+	.bottomButton {
+		position: absolute;
+		left: 60rpx;
+		bottom: 100rpx;
+		width: 630rpx;
+		height: 98rpx;
+		line-height: 98rpx;
+		text-align: center;
+		background: linear-gradient(180deg, #6fa5ff, #438aff);
+		border-radius: 8rpx;
+		box-shadow: 0px 0px 8rpx 0px rgba(51, 135, 255, 0.2);
+		font-size: 32rpx;
+		font-family: Source Han Sans CN, Source Han Sans CN-Medium;
+		font-weight: 500;
+		color: #ffffff;
+	}
+</style>

+ 560 - 0
merchant/CouponDetails.vue

@@ -0,0 +1,560 @@
+<template>
+
+	<view class="page-home">
+		<view class="page-home-bg">
+			<image class="page-home-bg-img" src="./static/images/coupun-bg.png"></image>
+		</view>
+		<!-- 优惠券详情 -->
+		<view style="height: 100rpx;"></view>
+		<view class="get_bg">
+			<image src="./static/images/getbg.png" mode=""></image>
+			<view class="get_bg_content">
+				<view class="flex-center get_bg_content_title">
+					<view class="">
+						<view class="ft48 get_bg_cut_price"> <text style="font-size: 30rpx;">¥</text>
+							{{CouponLists.cut_price}}<text class="ft26">元</text>
+						</view>
+						<view class="get_bg_title text-2" style="padding: 0 30rpx;">{{CouponLists.title}}</view>
+						<view class="get_bg_full_price">满{{CouponLists.full_price}}可用</view>
+					</view>
+				</view>
+
+				<view style="margin-top: 40rpx;">
+					<view class="DEtilename flex-y-center">
+						<view class="DEtilenameL">优惠券标题:</view>
+						<view class="DEtilenameR ">{{CouponLists.title}}</view>
+					</view>
+
+					<view class="DEtilename flex-y-center">
+						<view class="DEtilenameL">剩余数量:</view>
+						<view class="DEtilenameR">{{CouponLists.num}}</view>
+					</view>
+
+					<view class="DEtilename flex-y-center">
+						<view class="DEtilenameL">已领取数量:</view>
+						<view class="DEtilenameR">{{CouponLists.use_times}}</view>
+					</view>
+
+					<view class="DEtilename flex-y-center">
+						<view class="DEtilenameL">可用时间:</view>
+						<view class="DEtilenameR">{{CouponLists.start_time}}</view>
+					</view>
+
+					<view class="DEtilename flex-y-center">
+						<view class="DEtilenameL">截止时间:</view>
+						<view class="DEtilenameR">{{CouponLists.end_time}}</view>
+					</view>
+				</view>
+
+				<!-- 		<view class="bottomButton flex-between">
+					<view class="buttonL" @click="deletes">删除</view>
+					<view class="buttons" style="background: #3387ff;" @click="amend">修改</view>
+				</view> -->
+
+				<!-- 领取优惠券   -->
+				<view class="getcoupon" v-if="CouponLists.is_show == 1 && CouponLists.is_edit !=1" @click="getcoupon">
+					领取优惠券
+				</view>
+
+				<!-- 领取优惠券  -->
+				<view class="getcoupon" style="background: #CCCCCC;"
+					v-if="CouponLists.is_show == 3&& CouponLists.is_edit !=1">
+					优惠券已过期
+				</view>
+
+				<view class="Isgetcoupon" style="background: #CCCCCC;"
+					v-if="CouponLists.is_show == 2&& CouponLists.is_edit !=1">
+					已领取
+				</view>
+
+				<view class="bottomButton flex-between" v-if="CouponLists.is_edit ==1">
+					<view class="buttonL" @click="deletes">删除</view>
+					<view class="buttons" style="background: #ffa000;" @click="amend">修改</view>
+				</view>
+			</view>
+
+			<view class="getcoupon-rule">
+				<view class="getcoupon-rule-title flex-center">
+					<view class="line">
+					</view>
+					<text style="margin: 0 20rpx;"></text> 领取规则
+					<view class="line">
+					</view>
+				</view>
+
+				<view class="getcoupon-rule-content">
+					<view class="">
+						1.优惠劵只可在线下核销使用
+					</view>
+					<view class="">
+						2.优惠劵在指定的日期使用,过期无法使用
+					</view>
+					<view class="">
+						3.平台对发放的优惠劵享有最终解释权
+					</view>
+					<!-- #ifdef H5 -->
+					<view class="" @click="Copy">
+						4.复制此链接可发送给用户领取优惠劵 <text style="color:rgb(255, 160, 0);margin-left: 10px;">复制</text> 
+					</view>
+					<!-- #endif -->
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	// #ifdef H5
+	import getWXSign from "@/static/js/config.js";
+	// #endif 
+	export default {
+		data() {
+			return {
+				id: '', //跳转接受的id
+				token: '',
+				CouponLists: [],		
+				URL: getApp().globalData.URL,
+			}
+		},
+
+		onLoad(option) {
+			this.id = option.id;
+			this.token = option.token; //读取缓存手机号码
+		},
+
+		onShow() {
+			this.is_web();
+		},
+
+		onShareAppMessage(option) {
+
+		},
+
+		methods: {
+			//请求详情
+			Coupons() {
+				let that = this;
+				let token = that.token;
+				let id = that.id;
+				this.request({
+					url: "coupon/detail",
+					data: {
+						token: token ? token : "",
+						coupon_id: id
+					},
+				}).then(res => {
+					if (res.code == "200") {
+						this.CouponLists = res.data.detail
+					}
+				}).catch((res) => {
+					uni.showToast({
+						title: res.message,
+						icon: 'none'
+					})
+				});
+			},
+			// 修改
+			amend() {
+				let id = this.id;
+				uni.navigateTo({
+					url: './addCoupons?id=' + id
+				})
+			},
+			// 删除
+			deletes() {
+				let that = this;
+				let token = that.token;
+				let coupon_id = that.id;
+				uni.showModal({
+					title: '提示',
+					content: '确定删除吗?',
+					confirmColor: "#000000",
+					success: (res) => {
+						if (res.confirm) {
+							this.request({
+								url: "coupon/delete",
+								data: {
+									token: token,
+									coupon_id: coupon_id,
+								},
+							}).then(res => {
+								console.log(res, "res")
+								if (res.code == "200") {
+									uni.showToast({
+										title: "删除成功",
+										icon: 'none'
+									})
+									setTimeout(() => {
+										uni.navigateBack({
+											delta: 1
+										})
+									}, 2000)
+								}
+							}).catch((res) => {
+								uni.showToast({
+									title: res.message,
+									icon: 'none'
+								})
+							});
+
+						} else if (res.cancel) {
+							console.log('用户点击取消');
+						}
+					}
+				});
+			},
+
+			//领取优惠券
+			getcoupon() {
+				let id = this.id,
+					that = this;
+				let TikTok = uni.getStorageSync('userToken');
+				console.log(TikTok)
+				// 判断用户是否授权
+				if (TikTok) {
+					console.log('当前授权了')
+					this.request({
+						url: "Coupon/draw",
+						data: {
+							coupon_id: id,
+							token: TikTok
+						},
+						// is_agent: 'member',
+					}).then(res => {
+						if (res.code == "200") {
+							uni.showModal({
+								title: '温馨提示',
+								content: '优惠劵领取成功',
+								showCancel: false,
+								confirmColor: "#000000",
+								confirmText: '确定',
+								success: (res) => {
+									if (res.confirm) {
+										uni.reLaunch({
+											url: "../discountCouponIndex/discountCouponIndex"
+										})
+									}
+								},
+								fail: () => {},
+								complete: () => {}
+							});
+						}
+					}).catch((res) => {
+						uni.showToast({
+							title: res.message,
+							icon: 'none'
+						})
+					});
+				} else {
+					console.log('当前没有授权了')
+					this.gzhurl();
+				}
+			},
+
+			gzhurl(e) {
+				this.request({
+					url: "user/gzhurl",
+					data: {
+						type: 4,
+						id: this.id,
+					},
+				}).then(res => {
+					if (res.data.url) {
+						window.location.href = res.data.url
+					}
+				}).catch((res) => {
+					console.log("message", res)
+				});
+			},
+
+			is_web() {
+				this.Coupons();
+				function GetRequest() {
+					var url = location.search; //获取url中"?"符后的字串
+					var theRequest = new Object();
+					if (url.indexOf("?") != -1) {
+						//判断是否有参数
+						var str = url.substr(1); //从第一个字符开始 因为第0个是?号 获取所有除问号的所有符串
+						var strs = str.split("&");
+						console.log(strs)
+						for (var i = 0; i < strs.length; i++) {
+							theRequest[strs[i].split("=")[0]] = (strs[i].split("=")[1]);
+						}
+					}
+					return theRequest;
+				}
+				console.log(GetRequest().code,GetRequest().id)
+				if (GetRequest().code) {
+					//发起网络请求
+					this.request({
+						url: "user/gzh_login",
+						data: {
+							code: GetRequest().code,
+							type:3,
+						},
+					}).then(res => {
+						console.log(res, "res")
+						uni.setStorageSync("userToken", res.data.token);
+						this.getcoupon();
+					}).catch((res) => {
+						console.log("message", res)
+						if (res.message == "获取openid失败") {
+							return
+						}
+						uni.showToast({
+							title: res.message,
+							icon: 'none'
+						})
+					});
+				}
+				// else{
+				// 	this.Coupons();
+				// }
+			},
+			
+			Copy(e) {
+				// alert("Copy_nav_ali")
+				let id=this.id;
+				let content = this.URL+`/forward/#/merchant/CouponDetails?id=${id}`;
+				if (!document.queryCommandSupported('copy')) {
+					// 不支持
+					return false
+				}
+				let textarea = document.createElement("textarea")
+				textarea.value = content
+				textarea.readOnly = "readOnly"
+				document.body.appendChild(textarea)
+				textarea.select() // 选择对象
+				textarea.setSelectionRange(0, content.length) //核心
+				let result = document.execCommand("copy") // 执行浏览器复制命令
+				uni.showToast({
+					title: "复制成功",
+					icon: 'none'
+				})
+				textarea.remove();
+				return result
+			},
+			
+		}
+	}
+</script>
+
+<style>
+	page {
+		height: 800rpx;
+		width: 100%;
+	}
+
+	.page-home {
+		width: 100%;
+		height: 100%;
+	}
+
+	.page-home-bg {
+		width: 100%;
+		height: 100%;
+		position: absolute;
+		top: 0;
+		left: 0;
+	}
+
+	.page-home-bg-img {
+		display: block;
+		width: 100%;
+		height: 100%;
+	}
+
+	.get_bg {
+		width: 650rpx;
+		height: 800rpx;
+		margin: 0 auto;
+		position: relative;
+	}
+
+	.get_bg image {
+		height: 100%;
+		width: 100%;
+		position: absolute;
+		top: 0;
+		left: 0;
+	}
+
+	.get_bg_content {
+		position: relative;
+		width: 100%;
+		height: 100%;
+		text-align: center;
+	}
+
+	.get_bg_content_title {
+		height: 270rpx;
+	}
+
+	.get_bg_cut_price {
+		font-size: 60rpx;
+		color: #ffa024;
+	}
+
+	.get_bg_title {
+		font-size: 35rpx;
+		color: #000000;
+		margin: 15rpx 0;
+		padding: 0 15rpx;
+	}
+
+	.get_bg_full_price {
+		font-size: 26rpx;
+		color: #999
+	}
+
+	.getcoupon {
+		width: 500rpx;
+		background: rgba(255, 190, 44);
+		height: 98rpx;
+		line-height: 98rpx;
+		text-align: center;
+		border-radius: 8rpx;
+		font-size: 30rpx;
+		font-family: Source Han Sans CN, Source Han Sans CN-Medium;
+		font-weight: 500;
+		color: #fff;
+		margin: 0 auto;
+		margin-top: 80rpx;
+		position: relative;
+	}
+
+	.Isgetcoupon {
+		width: 640rpx;
+		background: #f0f0f0;
+		height: 98rpx;
+		line-height: 98rpx;
+		text-align: center;
+		background: #ccc;
+		border: 2rpx solid #f0f0f0;
+		border-radius: 8rpx;
+		font-size: 30rpx;
+		font-family: Source Han Sans CN, Source Han Sans CN-Medium;
+		font-weight: 500;
+		color: #f4f4f4;
+		margin-top: 80rpx;
+	}
+
+	page {
+		background: #F5F7FA;
+	}
+
+	.flex-between {
+		display: flex;
+		flex-flow: row nowrap;
+		justify-content: space-between;
+		align-items: center;
+	}
+
+	.flex-y-center {
+		display: -webkit-box;
+		display: -webkit-flex;
+		display: flex;
+		-webkit-box-align: center;
+		-webkit-align-items: center;
+		-ms-flex-align: center;
+		-ms-grid-row-align: center;
+		align-items: center;
+	}
+
+	.DEtile {
+		background: #Fff;
+		position: relative;
+		margin-top: 20rpx;
+	}
+
+	.DEtilename {
+		margin-top: 20rpx;
+	}
+
+	.DEtilenameL {
+		padding: 0 40rpx;
+		font-size: 28rpx;
+		font-family: PingFang SC, PingFang SC-Regular;
+		font-weight: 400;
+		color: #666666;
+		min-width: 250rpx;
+	}
+
+	.DEtilenameR {
+		font-size: 28rpx;
+		font-family: PingFang SC, PingFang SC-Regular;
+		font-weight: 400;
+		color: #333333;
+		padding-right: 40rpx;
+		width: 400rpx;
+		display: -webkit-box;
+		-webkit-box-orient: vertical;
+		-webkit-line-clamp: 1;
+		overflow: hidden;
+	}
+
+
+	.bottomButton {
+		position: relative;
+		left: 0;
+		width: 100%;
+		margin-top: 62rpx;
+		padding: 0 60rpx;
+	}
+
+	.buttonL {
+		width: 300rpx;
+		height: 98rpx;
+		line-height: 98rpx;
+		text-align: center;
+		background: #ffffff;
+		border: 2rpx solid #ccc;
+		border-radius: 8rpx;
+		font-size: 32rpx;
+		font-family: Source Han Sans CN, Source Han Sans CN-Medium;
+		font-weight: 500;
+		color: #707070;
+		margin-right: 40rpx;
+	}
+
+	.buttons {
+		width: 300rpx;
+		height: 98rpx;
+		line-height: 98rpx;
+		text-align: center;
+		/* background: linear-gradient(180deg, rgba(255, 190, 44), rgba(255, 190, 44)); */
+		border-radius: 8rpx;
+		box-shadow: 0px 0px 8rpx 0px rgba(51, 135, 255, 0.2);
+		font-size: 32rpx;
+		font-family: Source Han Sans CN, Source Han Sans CN-Medium;
+		font-weight: 500;
+		color: #ffffff;
+		margin-left: 40rpx;
+	}
+
+	.getcoupon-rule {
+		font-size: 24rpx;
+		text-align: left;
+		color: #FFFFFF;
+	}
+
+	.getcoupon-rule-title {
+		text-align: center;
+		margin-top: 50rpx;
+		margin-bottom: 20rpx;
+		font-size: 28rpx;
+	}
+
+	.getcoupon-rule-content {
+		width: 550rpx;
+		margin: 0 auto;
+		line-height: 45rpx;
+	}
+
+	.line {
+		width: 50rpx;
+		height: 2rpx;
+		background: #FFFFFF;
+
+	}
+</style>

+ 328 - 0
merchant/addCoupons.vue

@@ -0,0 +1,328 @@
+<template>
+	<view>
+		<form @submit="addCoupons">
+
+			<view class="couponsTitle  flex-y-center flex-between">
+				<view class="couponsTitleL">优惠券名称</view>
+				<input type="text" name="couponsName" class="couponsTitleLInput" placeholder-class="couponsTitleLPleahold"
+				 placeholder="请输入优惠券名称" :value="info.title" maxlength="32" />
+			</view>
+
+			<view class="couponsTitle  flex-y-center flex-between">
+				<view class="couponsTitleL">满额</view>
+				<input type="digit" class="couponsTitleLInput" name="couponsFull" placeholder-class="couponsTitleLPleahold"
+				 placeholder="请输入满额" :value="info.full_price" maxlength="6" />
+			</view>
+
+			<view class="couponsTitle  flex-y-center flex-between">
+				<view class="couponsTitleL">优惠金额</view>
+				<input type="digit" class="couponsTitleLInput" name="couponsDiscounts" placeholder-class="couponsTitleLPleahold"
+				 placeholder="请输入优惠金额" :value="info.cut_price" maxlength="5" />
+			</view>
+
+			<view class="couponsTitle  flex-y-center flex-between">
+				<view class="couponsTitleL">开始时间</view>
+				<view class="timeSelete">
+					<picker mode="date" :value="info.start_time" :start="startDate" :end="endDate" @change="bindDateChangeStart">
+						<view class="uni-input">{{startDates}}</view>
+					</picker>
+
+				</view>
+			</view>
+
+			<view class="couponsTitle  flex-y-center flex-between">
+				<view class="couponsTitleL">结束时间</view>
+				<view class="timeSelete">
+
+					<picker mode="date" :value="info.end_time" :start="startDate" :end="endDate" @change="bindDateChangeEnd">
+						<view class="uni-input">{{endDates}}</view>
+					</picker>
+				</view>
+			</view>
+
+			<view class="couponsTitle  flex-y-center flex-between">
+				<view class="couponsTitleL">优惠券数量</view>
+				<input type="number" name="couponsNum" class="couponsTitleLInput" placeholder-class="couponsTitleLPleahold"
+				 placeholder="请输入优惠券数量" :value="info.num" maxlength="4" />
+			</view>
+
+			<!-- 底部按钮 -->
+
+			<button class="bottomButton" form-type="submit">添加优惠券</button>
+
+		</form>
+
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				token: '',
+				info: "",
+				startDates:"请选择优惠券开始时间",
+				endDates:"请选择优惠券结束时间",
+				id:""
+			}
+
+		},
+		computed: {
+			startDate() {
+				return this.getDate('start');
+			},
+			endDate() {
+				return this.getDate('end');
+			}
+		},
+
+		onLoad(e) {
+			this.token = uni.getStorageSync('token'); //读取缓存手机号码
+		
+			if (e.id) {
+					this.id = e.id;
+				this.Coupons();
+			
+			}
+		},
+
+		onShow() {
+
+		},
+
+		methods: {
+			//请求详情
+			Coupons() {
+				this.request({
+					url: "coupon/detail",
+					data: {
+						token: this.token,
+						coupon_id: this.id,
+					},
+				}).then(res => {
+					if (res.code == "200") {
+						this.info = res.data.detail;
+						this.startDates=res.data.detail.start_time;
+						this.endDates=res.data.detail.end_time;
+						
+					}
+				}).catch((res) => {
+					uni.showToast({
+						title: res.message,
+						icon: 'none'
+					})
+				});
+			},
+
+			getDate(type) {
+				const date = new Date();
+				let year = date.getFullYear();
+				let month = date.getMonth() + 1;
+				let day = date.getDate();
+
+				if (type === 'start') {
+					year = year - 60;
+				} else if (type === 'end') {
+					year = year + 2;
+				}
+				month = month > 9 ? month : '0' + month;;
+				day = day > 9 ? day : '0' + day;
+				return `${year}-${month}-${day}`;
+			},
+
+			// 开始时间
+			bindDateChangeStart(e) {
+				this.startDates = e.target.value;
+			},
+			//结束时间
+			bindDateChangeEnd(e) {
+				this.endDates = e.target.value;
+			},
+
+			//添加优惠券
+			addCoupons(e) {
+
+            console.log(e)
+		    let {couponsName,couponsFull,couponsDiscounts,couponsNum}=	e.detail.value;
+			
+				let token = this.token;
+				let startDates = this.startDates;
+				let endDates = this.endDates;
+		        let a = ((Date.parse(new Date(startDates))) / 1000); //开始的时间戳
+				let b = ((Date.parse(new Date(endDates))) / 1000); //结束的时间戳
+
+				if (couponsName == "") {
+					uni.showToast({
+						title: '请输入优惠券名称',
+						icon: 'none',
+						duration: 2000
+					});
+					return false
+				} else if (couponsFull == "") {
+					uni.showToast({
+						title: '请输入优惠券满额',
+						icon: 'none',
+						duration: 2000
+					});
+					return false
+				} else if (couponsDiscounts == "") {
+					uni.showToast({
+						title: '请输入优惠券金额',
+						icon: 'none',
+						duration: 2000
+					});
+					return false
+				} else if (Number(couponsDiscounts)>Number(couponsFull) ) {
+					uni.showToast({
+						title: '优惠金额不可以大于满额哦!',
+						icon: 'none',
+						duration: 2000
+					});
+					return false	
+				} else if (!startDates||startDates=="请选择优惠券开始时间") {
+					uni.showToast({
+						title: '请选择开始时间',
+						icon: 'none',
+						duration: 2000
+					});
+					return false
+				} else if (!endDates||endDates=="请选择优惠券结束时间") {
+					uni.showToast({
+						title: '请选择结束时间',
+						icon: 'none',
+						duration: 2000
+					});
+					return false
+				} else if (a > b) {
+					uni.showToast({
+						title: '开始时间不能大于结束时间哦',
+						icon: 'none',
+						duration: 2000
+					});
+					return false
+				} else if (couponsNum == "") {
+					uni.showToast({
+						title: '请输入优惠券数量 ',
+						icon: 'none',
+						duration: 2000
+					});
+					return false
+				}
+				// coupon/edit
+				let url=this.id?"coupon/edit":"coupon/create";
+				this.request({
+					url:url,
+					data: {
+						token: token,
+						title: couponsName,
+						cut_price: Number(couponsDiscounts),
+						full_price: Number(couponsFull),
+						start_time: startDates,
+						end_time: endDates,
+						num: Number(couponsNum),
+						url:"https://",
+						coupon_id:this.id,
+					},
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code == "200") {
+						uni.showModal({
+							title: '提示',
+							showCancel: false,
+							content: '添加成功',
+							success: function(res) {
+								
+								if (res.confirm) {
+									uni.navigateBack({
+										delta:1
+									})
+									// uni.reLaunch({
+									// 	url: "../index/index"
+									// })
+								}
+								
+							}
+						});
+					}
+				}).catch((res) => {
+					uni.showToast({
+						title: res.message,
+						icon: 'none'
+					})
+				});
+
+
+
+
+			},
+		},
+
+	}
+</script>
+
+<style>
+	page {
+		background: #f4f4f4;
+	}
+
+	.couponsTitle {
+		height: 100rpx;
+		width: 750rpx;
+		background: #Fff;
+	}
+
+	.couponsTitleL {
+		font-size: 28rpx;
+		font-family: PingFang SC, PingFang SC-Regular;
+		font-weight: 400;
+		color: #333333;
+		padding-left: 30rpx;
+
+	}
+
+	.couponsTitleLInput {
+		font-size: 28rpx;
+		font-family: PingFang SC, PingFang SC-Regular;
+		font-weight: 400;
+		color: #333;
+		text-align: right;
+		padding: 0 30rpx 0 200rpx;
+		flex: 1;
+	}
+
+	.couponsTitleLPleahold {
+		font-size: 28rpx;
+		font-family: PingFang SC, PingFang SC-Regular;
+		font-weight: 400;
+		color: #cbcbcb;
+	}
+
+	/* 选择时间 */
+	.timeSelete {
+		text-align: right;
+		flex: 1;
+		font-size: 24rpx;
+		padding-right: 30rpx;
+		font-family: PingFang SC, PingFang SC-Regular;
+		font-weight: 400;
+		color: #7d7d7d;
+	}
+
+	/* 添加优惠券 */
+	.bottomButton {
+		position: absolute;
+		left: 60rpx;
+		bottom: 100rpx;
+		width: 630rpx;
+		height: 98rpx;
+		line-height: 98rpx;
+		background: linear-gradient(180deg, #6fa5ff, #438aff);
+		border-radius: 8rpx;
+		box-shadow: 0px 0px 8rpx 0px rgba(51, 135, 255, 0.2);
+		font-size: 32rpx;
+		font-family: Source Han Sans CN, Source Han Sans CN-Medium;
+		font-weight: 500;
+		text-align: center;
+		color: #ffffff;
+	}
+</style>

+ 217 - 0
merchant/coupon.vue

@@ -0,0 +1,217 @@
+<template>
+	<view>
+		<no-none v-if='CouponList.length<=0'></no-none>
+		<block v-else>
+			<view class="CouponList flex" @click="CouponUse" v-for=" (item,index) in CouponList" :key="index" :data-id="item.id">
+				<view class="CouponL flex-grow-1">
+					<view class="CouponContenttitle text-1">{{item.title}}</view>
+					<view class="CouponContentC">
+						<text>有效期:</text>
+						<text>{{item.start_time}}-{{item.end_time}}</text>
+					</view>
+				</view>
+				<view class="CouponR flex-grow-0">
+					<view class="coupon-center">
+						<view class="rund top">
+						</view>
+						<view class="line">
+						</view>
+						<view class="rund bottom">
+						</view>
+					</view>
+					<view class="CouponLmoney"> <text class="unit">¥</text>{{ Number(item.cut_price) }}</view>
+					<view class="CouponLmoneys">满{{ Number(item.full_price)}}可用</view>
+					<view class="CouponRtext">立即查看</view>
+				</view>
+			</view>
+			<loading :is_load="is_load" :is_load_more='is_load_more'></loading>
+		</block>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				token: '', //获取用户的token
+				page: 1,
+				limit: 10,
+				CouponList: [], //优惠券列表
+				page: 1,
+				is_load: false,
+				is_load_more: false,
+			}
+		},
+
+		onLoad() {
+			this.token = uni.getStorageSync('token'); //读取缓存手机号码
+		},
+
+		onShow() {
+			this.page = 1;
+			this.CouponList = [];
+			this.Coupon();
+		},
+
+		onPullDownRefresh() {
+			console.log("下拉")
+			this.page = 1;
+			this.CouponList = [];
+			this.Coupon();
+			setTimeout(() => {
+				uni.stopPullDownRefresh();
+			}, 1000)
+		},
+		onReachBottom() {
+			if (!this.is_load) {
+				this.page = this.page + 1;
+				this.Coupon();
+			}
+		},
+		methods: {
+			CouponUse(e) {
+				console.log(e.currentTarget.dataset.id)
+				let id = e.currentTarget.dataset.id,token=uni.getStorageSync('token'); 
+				uni.navigateTo({
+					url: './CouponDetails?id='+id+'&token='+token
+				})
+			},
+			loginOut() {
+				uni.removeStorageSync("token")
+				uni.removeStorage({
+					key: 'login',
+					success: (res) => {
+						uni.reLaunch({
+							url: "../login/login"
+						})
+					}
+				})
+			},
+			Coupon() {
+				this.request({
+					url: "coupon/lists",
+					data: {
+						token: uni.getStorageSync('token'),
+						page: this.page,
+						limit: 15,
+					},
+				}).then(res => {
+					console.log(res, "res")
+					if (res.data.list.length == 0) {
+						this.is_load = true,
+							this.is_load_more = true,
+							setTimeout(() => {
+								this.is_load_more = false
+							}, 1e3);
+						return
+					}
+					this.is_load = false;
+					this.CouponList = this.CouponList.concat(res.data.list);
+				}).catch((res) => {
+					uni.showToast({
+						title: res.message,
+						icon: 'none'
+					})
+				});
+			},
+
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		background: #fff;
+	}
+
+	.no-more {
+		font-size: 28rpx;
+		color: #999999;
+		text-align: center;
+		padding: 20rpx 0;
+	}
+
+	.CouponList {
+		margin: 0 40rpx;
+		margin-top: 20rpx;
+		border-radius: 8rpx;
+		height: 180rpx;
+		overflow: hidden;
+		.CouponL {
+			text-align: left;
+			padding: 10rpx 20rpx;
+			border: 1rpx solid #F1F1F1;
+
+			.CouponContenttitle {
+				font-size: 34rpx;
+				padding-top: 15rpx;
+			}
+
+			.CouponContentC {
+				color: #999;
+				font-size: 24rpx;
+				padding-top: 15rpx;
+			}
+		}
+
+		.CouponR {
+			background: linear-gradient(0deg, rgba(2, 126, 251, 1) 0%, rgba(0, 172, 238, 1) 100%);
+			color: #FFFFFF;
+			width: 200rpx;
+			text-align: center;
+			position: relative;
+
+			.coupon-center {
+				position: absolute;
+				left: -16rpx;
+				top: 0;
+				width: 30rpx;
+
+				.rund {
+					width: 24rpx;
+					height: 24rpx;
+					background: #FFFFFF;
+					border-radius: 50%;
+					position: absolute;
+				}
+
+				.top {
+					top: -15rpx;
+				}
+
+				.bottom {
+					bottom: -15rpx;
+				}
+
+				.line {
+					width: 1rpx;
+					height: 180rpx;
+				}
+			}
+
+			.CouponLmoney {
+				font-size: 47rpx;
+				padding-top: 15rpx;
+
+				.unit {
+					font-size: 28rpx;
+				}
+			}
+
+			.CouponRtext {
+				font-size: 22rpx;
+				border: 1rpx solid #FFFFFF;
+				text-align: center;
+				border-radius: 50px;
+				display: inline-block;
+				padding: 4rpx 18rpx;
+			}
+
+			.CouponLmoneys {
+				font-size: 20rpx;
+				margin-bottom: 10rpx;
+			}
+
+		}
+	}
+</style>

+ 376 - 0
merchant/flow-record.vue

@@ -0,0 +1,376 @@
+<template>
+	<view class="">
+		<view id="header-id">
+			<view class="header-content flex-y-center">
+				<view class="flex-y-center header">
+					<icon type="search" size="15" style="margin-right: 10rpx;"></icon>
+					<input type="text" value="" @input="onInput" @confirm="search" confirm-type="search" placeholder="输入订单编号查询"  />
+				</view>
+			</view>
+			<view class="tabs">
+				<liuyuno-tabs :tabData="tabs" :defaultIndex="defaultIndex" @tabClick='tabClick' />
+			</view>
+		</view>
+
+		<view class="hg226"></view>
+
+		<view class="home">
+			<view class="box-pack-between total">
+				<text class="price-color ft32">总计:¥{{total_money}}</text>
+				<view class="total-right flex-y-center">
+					<picker :range="type_arr" @change="bindCge">
+						<view class="flex-y-center">
+							{{type_arr[type_index]}}
+							<image src="../static/images/san.png" mode=""></image>
+						</view>
+					</picker>
+				</view>
+			</view>
+			<view style="height:100rpx;"></view>
+			<no-none v-if='list.length<=0'></no-none>
+			<block v-else>
+				<view class="list" v-for="(item,index) in list" :key="index">
+					<view class="box-pack-between top">
+						<text>{{item.out_trade_no}}</text>
+						<view class="flex-center stutas">
+							<image :src="item.pay_type==1?pay_type:pay_type1" mode=""></image>
+							{{item.order_status=='SUCCESS'?'支付成功':'未支付'}}
+						</view>
+					</view>
+					<view class="text-color ft28 center">
+						付款时间:<text>{{item.pay_time}}</text>
+					</view>
+					<view class="text-color ft28">
+						付款金额:<text class="price-color ft28">{{item.pay_price}}</text>
+					</view>
+				</view>
+				<loading :is_load="is_load" :is_load_more='is_load_more'></loading>
+			</block>
+		</view>
+
+		<uni-popup-top ref="popup" type="top" :top="top" :maskClass="maskClass">
+			<view class="model">
+				<view class="flex-y-center box-pack-between model-date">
+					<view class="model-item " :class="act_index==1?'act':''">
+						<picker mode='date' :value="start" :start="startDate" :end="endDate" @change="bindDateChange1" data-index="1">
+							<view class="flex-center">
+								<text>{{start}}</text>
+							</view>
+						</picker>
+					</view>
+					<text>至</text>
+					<view class="model-item" :class="act_index2==2?'act':''">
+						<picker mode='date' :value="end" :start="startDate" :end="endDate" @change="bindDateChange2" data-index="2">
+							<view class="flex-center">
+								<text>{{end}}</text>
+							</view>
+						</picker>
+					</view>
+				</view>
+				<view class="model-btn flex-center" @click="sure">
+					确定
+				</view>
+			</view>
+		</uni-popup-top>
+	</view>
+</template>
+
+<script>
+	import liuyunoTabs from "@/components/liuyuno-tabs/liuyuno-tabs.vue";
+	import uniPopupTop from '@/components/zx-uni-popup/uni-popup-top.vue'
+	export default {
+		components: {
+			uniPopupTop,
+			liuyunoTabs
+		},
+		data() {
+			return {
+				tabs: [
+					"今日",
+					"昨日",
+					"本周",
+					"筛选"
+				],
+				defaultIndex: 0,
+				startDate: "2020-10-01",
+				endDate: "2030-10-01",
+				start: "开始时间",
+				end: "结束时间",
+				act_index: 0,
+				act_index2: 0,
+				type_arr: [
+					"全部", "微信", "支付宝",
+				],
+				type_index: 0,
+				list: [],
+				page: 1,
+				is_load: false,
+				is_load_more: false,
+				total_money: 0,
+				time: "",
+				pay_type: "../static/images/wx.png",
+				pay_type1: "../static/images/ali.png",
+				keywords:"",
+				top:"226rpx",
+				maskClass: {
+					'position': 'fixed',
+					'bottom': 0,
+					'top': "226rpx",
+					'left': 0,
+					'right': 0,
+					'backgroundColor': 'rgba(0, 0, 0, 0.4)'
+				},
+			}
+		},
+		onLoad() {
+			this.http();
+		},
+		onReady() {},
+		onReachBottom() {
+			console.log("dddd")
+			if (!this.is_load) {
+				this.page = this.page + 1;
+				this.http();
+			}
+		},
+		methods: {
+			tabClick(e) {
+				this.defaultIndex = e;
+				if (e == 3) {
+					this.$refs.popup.open();
+					return
+				} else {
+					this.act_index = 0;
+					this.act_index2 = 0;
+					this.start = "开始时间";
+					this.end = "结束时间";
+					this.time = "";
+					this.clear();
+				}
+				this.$refs.popup.close();
+			},
+
+			clear() {
+				this.page = 1;
+				this.list = [];
+				this.http();
+			},
+
+			bindDateChange1(e) {
+				this.act_index = e.currentTarget.dataset.index;
+				this.start = e.target.value;
+			},
+
+			bindDateChange2(e) {
+				this.act_index2 = e.currentTarget.dataset.index;
+				this.end = e.target.value;
+			},
+
+			sure(e) {
+				this.time = this.start + " - " + this.end;
+				this.clear();
+				this.$refs.popup.close();
+			},
+
+			bindCge(e) {
+				console.log(e, "e")
+				this.type_index = e.detail.value;
+				this.clear();
+			},
+			search(e){
+				this.keywords=e.detail.value;
+				this.clear();
+			},
+			onInput(e)
+			{	
+				if(!e.detail.value){
+					this.keywords="";
+					this.clear();
+				}
+			},
+			http() {
+				let type = this.defaultIndex,
+					pay_type = this.type_index;
+				this.request({
+					url: "user/getList",
+					data: {
+						token: uni.getStorageSync('token'),
+						page: this.page,
+						limit: 5,
+						time: this.time,
+						paytime: type == 0 ? "today" : type == 1 ? "yesterday" : type == 2 ? "week" : "",
+						pay_type,
+						keywords:this.keywords,
+					},
+				}).then(res => {
+					console.log(res, "res")
+					if (res.code === '200') {
+					
+						if (res.data.data.length == 0) {
+							this.is_load = true,
+								this.is_load_more = true,
+								setTimeout(() => {
+									this.is_load_more = false
+								}, 1e3);
+							return
+						}
+						
+						this.total_money += res.data.total_money;
+						this.is_load = false;
+						this.list = this.list.concat(res.data.data);
+					}
+				}).catch((res) => {
+					uni.showToast({
+						title: res.message,
+						icon: 'none'
+					})
+				});
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	$yellow: #FFA024;
+
+	page {
+		background: #F5F7FA;
+	}
+
+	#header-id {
+		position: fixed;
+		top: 0;
+		width: 100%;
+		z-index: 999;
+	}
+
+	.hg226 {
+		height: 226rpx;
+	}
+
+	.header-content {
+		background: #FFFFFF;
+		height: 126rpx;
+
+		.header {
+			width: 670rpx;
+			height: 70rpx;
+			opacity: 1;
+			background: #f5f6f9;
+			border-radius: 4rpx;
+			font-size: 28rpx;
+			padding: 0 30rpx;
+			margin: 0 auto;
+		}
+	}
+
+	.tabs {
+		font-size: 32rpx;
+	}
+
+	.price-color {
+		color: $yellow;
+	}
+
+	.text-color {
+		color: #99A0AD
+	}
+
+	.home {
+		width: 670rpx;
+		margin: 0 auto;
+		position: relative;
+
+		.total {
+			padding: 24rpx 0;
+			position: fixed;
+			width: 670rpx;
+			background: #F5F7FA;
+			z-index: 99;
+
+			.total-right {
+				font-size: 28rpx;
+				color: #666666;
+
+				image {
+					width: 15rpx;
+					height: 10rpx;
+					margin-left: 10rpx;
+				}
+			}
+		}
+
+		.list {
+			width: 670rpx;
+			height: 227rpx;
+			opacity: 1;
+			background: #ffffff;
+			border-radius: 8rpx;
+			box-shadow: 0px 6rpx 10rpx 0px rgba(213, 213, 213, 0.04);
+			margin: 0 auto;
+			padding: 20rpx 32rpx;
+			margin-bottom: 20rpx;
+
+			.top {
+				margin-bottom: 43rpx;
+			}
+
+			.center {
+				margin-bottom: 22rpx;
+			}
+
+			.stutas {
+				image {
+					width: 32rpx;
+					height: 32rpx;
+					margin-right: 10rpx;
+				}
+			}
+		}
+	}
+
+	.model {
+		width: 100%;
+		z-index: 155;
+		background: #FFFFFF;
+		padding-bottom: 20rpx;
+
+		.model-date {
+			width: 100%;
+			padding: 20rpx 80rpx;
+			border-bottom: 1rpx solid #F1F1F1;
+
+			.model-item {
+				width: 225rpx;
+				text-align: center;
+				font-size: 28rpx;
+				color: #999;
+				position: relative;
+				padding: 10rpx 0;
+				text-align: center;
+				border-radius: 8rpx;
+				border: 1rpx solid #999;
+			}
+
+			.act {
+				color: #FFFFFF;
+				background: #FFBE2C;
+				border: 1rpx solid #FFBE2C;
+			}
+		}
+
+		.model-btn {
+			text-align: center;
+			color: #FFFFFF;
+			height: 80rpx;
+			border-radius: none;
+			width: 80%;
+			opacity: 1;
+			background: linear-gradient(315deg, #3387ff 2%, #569bff 99%);
+			border-radius: 8rpx;
+			box-shadow: 0px 0px 8rpx 0px rgba(51, 135, 255, 0.20);
+			margin: 0 auto;
+			margin-top: 20rpx;
+		}
+	}
+</style>

+ 171 - 0
merchant/merchant.vue

@@ -0,0 +1,171 @@
+<template>
+	<view class="content">
+		<view class="header">
+			<image src="../static/images/skm_fn_bg.png" mode="aspectFill" class="bg-img"></image>
+			<view class="info-block flex-y-center">
+				<view class="info">
+					<view class="title">商户管理</view>
+					<view class="desc">查看管理商户应用</view>
+				</view>
+			</view>
+		</view>
+		<view class="content-row">
+			<view class="setup flex-y-center ft32">
+				常用应用
+			</view>
+
+			<view class="table">
+				<view class="table-tr">
+					<navigator class="table-td" url="flow-record?shop=1">
+						<image src="./static/images/liu.png" mode=""></image>
+						<view class="">流水记录</view>
+					</navigator>
+
+					<navigator class="table-td" url="coupon">
+						<image src="./static/images/coupon.png" mode=""></image>
+						<view class="">优惠券列表</view>
+					</navigator>
+
+					<navigator class="table-td" url="addCoupons">
+						<image src="./static/images/add-coupon.png" mode=""></image>
+						<view class="">添加优惠券</view>
+					</navigator>
+
+					<navigator class="table-td" url="Applied">
+						<image src="./static/images/add-hexiao.png" mode=""></image>
+						<view class="">核销优惠券</view>
+					</navigator>
+
+					<navigator class="table-td" url="verification">
+						<image src="./static/images/hexiao.png" mode=""></image>
+						<view class="">核销记录</view>
+					</navigator>
+
+					<navigator class="table-td" v-if="admin_id" url="../saomaDiancan/index/index?type=1">
+						<image src="./static/images/hexiao.png" mode=""></image>
+						<view class="">餐饮管理</view>
+					</navigator>
+
+				</view>
+			</view>
+
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				user_info: {},
+				admin_id: "",
+			}
+		},
+		onLoad(e) {
+			this.admin_id = e.admin_id;
+			if (e.admin_id) {
+				uni.setStorageSync("admin_id", e.admin_id);
+			}
+		},
+
+		methods: {
+
+		}
+	}
+</script>
+
+<style>
+	.header {
+		width: 100%;
+		height: 198rpx;
+		position: relative;
+	}
+
+	.header .bg-img {
+		display: block;
+		position: absolute;
+		left: 0;
+		top: 0;
+		z-index: 1;
+		width: 100%;
+		height: 198rpx;
+	}
+
+	.header .info-block {
+		padding: 0 40rpx 0 48rpx;
+		height: 198rpx;
+		position: relative;
+		z-index: 2;
+	}
+
+	.header .info-block .title {
+		font-size: 36rpx;
+		color: #fff;
+		font-weight: 500;
+		line-height: 50rpx;
+	}
+
+	.header .info-block .desc {
+		font-size: 28rpx;
+		font-weight: 500;
+		color: #fff;
+		line-height: 40rpx;
+		margin-top: 8rpx;
+	}
+
+	.content-row {
+		background-color: #fff;
+		border-radius: 10px 10px 0 0;
+		margin-top: -10px;
+		padding: 10px 21px 0;
+		z-index: 3;
+		position: relative;
+	}
+
+	.setup {
+		width: 100%;
+		height: 90rpx;
+
+		opacity: 1;
+		padding: 0 22rpx;
+	}
+
+	.table,
+	.table div {
+		margin: 0 auto;
+	}
+
+	.table {
+		width: 100%;
+		border-collapse: collapse;
+		box-sizing: border-box;
+	}
+
+	.table-tr {}
+
+	.table-th {
+		display: table-cell;
+		font-weight: bold;
+		border: 1rpx solid #FAFAFA;
+		text-align: center;
+		vertical-align: middle;
+	}
+
+	.table-td {
+		display: inline-block;
+		/* border: 1rpx solid #FAFAFA; */
+		text-align: center;
+		vertical-align: middle;
+		background: #fff;
+		font-size: 27rpx;
+		color: #666666;
+		padding: 62rpx 0;
+		width: 33.333%;
+	}
+
+	.table-td image {
+		width: 50rpx;
+		height: 50rpx;
+		margin-bottom: 23rpx;
+	}
+</style>

二进制
merchant/static/images/add-coupon.png


二进制
merchant/static/images/add-hexiao.png


二进制
merchant/static/images/ali_code.png


二进制
merchant/static/images/ali_ua.png


二进制
merchant/static/images/coupon.png


二进制
merchant/static/images/coupun-bg.png


二进制
merchant/static/images/darw/FltcHBBH8X84Uzs5llLo_pGBnuvv.png


二进制
merchant/static/images/darw/FoIzpLTMwSQZDcJYrL_FD_07iBte.png


二进制
merchant/static/images/darw/FrKRY-mHF7fQmkO3lUQjWRCDlCRI.png


二进制
merchant/static/images/darw/FrnXmarfaxXY9i3FCkZGuQJyR6Rj.png


二进制
merchant/static/images/darw/Fv1xujnIn1r7XecrvEc-Mp9dqM4C.png


部分文件因为文件数量过多而无法显示