Commit 623218a7807f802a9975ace9daa262299fb9baae

Authored by season
2 parents 31c1af0b 60661c6d

qa

Showing 56 changed files with 8014 additions and 840 deletions
... ... @@ -718,6 +718,12 @@ App({
718 718 resolve(user_info);
719 719 };
720 720 });
  721 +
  722 +
  723 +
  724 +
  725 +
  726 +
721 727 },
722 728  
723 729  
... ...
app.json
... ... @@ -54,11 +54,7 @@
54 54 "pages/payment/pay_success/pay_success",
55 55 "pages/user/plus/plus",
56 56 "pages/user/cardinfo/cardinfo",
57   -<<<<<<< HEAD
58   - "pages/user/Detailed/Detailed",
59   -=======
60 57 "pages/user/Detailed/Detailed",
61   ->>>>>>> 875625f38c1972869416e1894a992442d54ae75a
62 58 "pages/user/my_service/appment_main",
63 59 "pages/user/my_service/i_service",
64 60 "pages/user/my_service/cosmetology_list",
... ... @@ -92,12 +88,6 @@
92 88 "pages/user/deposit/prepaid/prepaid",
93 89 "pages/distribution/distribution"
94 90 ],
95   - "plugins": {
96   - "live-player-plugin": {
97   - "version": "1.3.0",
98   - "provider": "wx2b03c6e691cd7370"
99   - }
100   - },
101 91 "subPackages": [{
102 92 "root": "packageA/",
103 93 "name":"pack1",
... ...
app.wxss
1 1 @import './utils/weapp-icon.wxss';
2 2 @import "./utils/wxParse/wxParse.wxss";
3 3  
  4 +.pdt4 {
  5 + padding-top: 4rpx;
  6 +}
4 7 .pd10 {
5 8 padding: 10rpx;
6 9 }
... ... @@ -703,9 +706,9 @@ background: #ffe3e2;
703 706 /* 图标字体(ty) */
704 707 @font-face {
705 708 font-family: 'iconfont'; /* Project id 2054717 */
706   - src: url('//at.alicdn.com/t/font_2054717_nzwl8grylfi.woff2?t=1627287108388') format('woff2'),
707   - url('//at.alicdn.com/t/font_2054717_nzwl8grylfi.woff?t=1627287108388') format('woff'),
708   - url('//at.alicdn.com/t/font_2054717_nzwl8grylfi.ttf?t=1627287108388') format('truetype');
  709 + src: url('//at.alicdn.com/t/font_2054717_3fwbtkdbxhl.woff2?t=1627893975776') format('woff2'),
  710 + url('//at.alicdn.com/t/font_2054717_3fwbtkdbxhl.woff?t=1627893975776') format('woff'),
  711 + url('//at.alicdn.com/t/font_2054717_3fwbtkdbxhl.ttf?t=1627893975776') format('truetype');
709 712 }
710 713  
711 714 .iconfont {
... ... @@ -716,6 +719,17 @@ background: #ffe3e2;
716 719 -moz-osx-font-smoothing: grayscale;
717 720 }
718 721  
  722 +.icon-zhuanfa1:before {
  723 + content: "\e614";
  724 +}
  725 +
  726 +
  727 +.icon-zhiwen:before {
  728 + content: "\e6aa";
  729 +}
  730 +
  731 +
  732 +
719 733 .icon-guan:before {
720 734 content: "\e612";
721 735 }
... ...
components/catch/catch.js 0 → 100644
  1 +// pages/user/yhq/qr_code/qr_code.js
  2 +const {
  3 + barcode,
  4 + qrcode
  5 +} = require('../../utils/index.js')
  6 +
  7 +Component({
  8 + data: {
  9 + q_show:0,
  10 + object:null,
  11 + index:0,
  12 + is_fw:0,
  13 +
  14 + barcode_canvas:null,
  15 + qrcode_canvas:null,
  16 + },
  17 + properties: {
  18 + // 这里定义了innerText属性,属性值可以在组件使用时指定
  19 + },
  20 + ready: function () {
  21 + },
  22 +
  23 + methods: {
  24 + //关闭
  25 + close: function (e) {
  26 + this.setData({q_show: 0,barcode_canvas:null,qrcode_canvas:null });
  27 + this.triggerEvent('close',{},{bubbles: true});
  28 + },
  29 +
  30 + //打开
  31 + open:function (e) {
  32 + this.data.index++;
  33 + var list=[{index:this.data.index }];
  34 +
  35 + this.setData({q_show: 1,object:e,barcode_canvas:list,qrcode_canvas:list,is_fw:e.is_fw });
  36 + var val=e.val;
  37 +
  38 + // barcode('barcode'+this.data.index,val, 620, 160,this);
  39 + qrcode('qrcode'+this.data.index, val, 520, 520,this);
  40 + }
  41 + },
  42 +
  43 +
  44 +
  45 +
  46 +})
0 47 \ No newline at end of file
... ...
pages/user/binding_info/binding_info.json renamed to components/catch/catch.json
1 1 {
2   - "navigationBarTitleText": "关联手机号",
3   - "enablePullDownRefresh": false
  2 + "component": true,
  3 + "usingComponents": {}
4 4 }
5 5 \ No newline at end of file
... ...
components/catch/catch.wxml 0 → 100644
  1 +<view class="container">
  2 + <view class="container-wrapper">
  3 + <view>
  4 + <text class="t-icon t-icon-gowudai mgb20"></text>
  5 + <view class="fs28"><slot></slot></view>
  6 + </view>
  7 + <view class="mgt60">
  8 + <text class="btn">进店逛逛</text>
  9 + </view>
  10 + </view>
  11 +</view>
  12 +
... ...
components/catch/catch.wxss 0 → 100644
  1 +@import '../../app.wxss';
  2 +
  3 +
  4 +.container {
  5 + background-color: #f5f5f5;
  6 + position: fixed;
  7 + top: 0;
  8 + bottom: 0;
  9 + left: 0;
  10 + right: 0;
  11 +}
  12 +
  13 +.container-wrapper {
  14 + position: absolute;
  15 + top: 50%;
  16 + left: 50%;
  17 + transform: translate(-50%, -50%);
  18 + text-align: center;
  19 + color: rgb(173,173,173);
  20 +}
  21 +
  22 +.t-icon {
  23 + width: 200rpx;
  24 + height: 200rpx;
  25 +}
  26 +
  27 +.btn {
  28 + display: inline-block;
  29 + padding: 10rpx 50rpx;
  30 + border: 2rpx solid red;
  31 + color: red;
  32 + font-size: 30rpx;
  33 + border-radius: 30rpx;
  34 + box-sizing: border-box;
  35 +}
  36 +
  37 +.mgt60 {
  38 + margin-top: 60rpx;
  39 +}
0 40 \ No newline at end of file
... ...
components/diy_store_select/diy_store_select.js
... ... @@ -44,10 +44,6 @@ Component({
44 44  
45 45 //获取顶部的门店
46 46 getApp().get_user_store(function(){
47   - var top_store=getApp().globalData.pk_store;
48   - if(top_store){
49   - th.setData({top_store:top_store});
50   - }else{
51 47 wx.getLocation({
52 48 type: 'gcj02',
53 49 success: function(res) {
... ... @@ -61,9 +57,12 @@ Component({
61 57 }
62 58 }
63 59 })
64   - }
  60 +
65 61 })
66 62 },
  63 +
  64 +
  65 +
67 66 //-- 设置最近的店为默认的店,一开始加载的时候 --
68 67 set_fir_store_to_def(){
69 68 var th=this;
... ... @@ -74,7 +73,13 @@ Component({
74 73 page:1,
75 74 };
76 75 dd.lat = th.data.lat;
77   - dd.lon = th.data.lon;
  76 + dd.lon = th.data.lon;
  77 +
  78 + var top_store=getApp().globalData.pk_store;
  79 + if(top_store){
  80 + dd.pickup_id=top_store.pickup_id;
  81 + }
  82 +
78 83 //----------获取门店,最近的门店----------------
79 84 getApp().request.promiseGet("/api/weshop/pickup/list", {
80 85 data: dd,
... ... @@ -173,8 +178,7 @@ Component({
173 178 this.deal_pickup(this.data.all_pick_list,func)
174 179 return false;
175 180 }
176   - var th = this,that=this;
177   - var i = getApp().request;
  181 + var th = this,that=this;
178 182 var dd = {
179 183 store_id: o.stoid,
180 184 isstop: 0,
... ...
components/diy_store_select/diy_store_select.wxml
  1 +<wxs module="filters" src="../../utils/filter.wxs"></wxs>
  2 +
1 3 <!-- 如果是自定义模板的时候 -->
2 4 <block wx:if="{{object}}">
3 5 <view class="store_sele1 flex ai_c" bindtap="sele_top_store" style="background-color:{{object.bgcolor}};color: {{object.word_color}};">
... ... @@ -51,7 +53,7 @@
51 53 </view>
52 54 <view>
53 55 <view class="distance fs24 address-val"wx:if="{{item.distance!=null}}">
54   - 距离:{{item.distance>1000?filters.toFix(item.distance/1000,2)+'km':filters.toFix(item.distance,0)+"m"}}</view>
  56 + 距离: {{item.distance>1000?filters.toFix(item.distance/1000,2)+'km':filters.toFix(item.distance,0)+"m"}}</view>
55 57 </view>
56 58 </view>
57 59 <view class="fs24 xc-ash-9f">地址:{{item.fulladdress}}</view>
... ...
components/my_confirm/my_confirm.wxml
... ... @@ -6,8 +6,8 @@
6 6 <view class="shut" bindtap="close_yu_e">ⅹ</view>
7 7 <view class="fs32 xc-black3 flex jc-center ai-center" style="padding: 10rpx 20rpx;min-height:220rpx;"><text>{{title}}</text></view>
8 8 <view class="flex jc-center ai_center" style="width: 100%;height: 75rpx;">
9   - <view bindtap="go_sure" class="fs30 white flex jc-center ai-center ck_btn color color" style="margin-right: 20rpx;">{{s_text}}</view>
10   - <view bindtap='go_cancle' class="fs30 xc-ash flex jc-center ai-center ck_btn"style="background:#ececea;">{{c_text}}</view>
  9 + <view bindtap="go_sure" class="fs30 white flex jc-center ai-center ck_btn" style="margin-right: 20rpx;background:#ececea;">{{s_text}}</view>
  10 + <view bindtap='go_cancle' class="fs30 xc-ash flex jc-center ai-center ck_btn color" >{{c_text}}</view>
11 11 </view>
12 12 </view>
13 13 </view>
... ...
components/my_confirm/my_confirm.wxss
1   -
  1 +@import '../../app.wxss';
2 2 /* 弹窗样式 */
3 3 .xc-pop-up{
4 4 width: 100%;
... ... @@ -23,19 +23,19 @@
23 23  
24 24 .shut{
25 25 display: block;
26   - width: 54rpx;
27   - height: 54rpx;
28   - font-size: 50rpx;
29   - line-height:47rpx;
  26 + width: 45rpx;
  27 + height: 45rpx;
  28 + line-height:36rpx;
30 29 border-radius: 50%;
31 30 -moz-border-radius: 50%;
32 31 -webkit-border-radius: 50%;
  32 + font-size: 40rpx;
33 33 color: #fff;
34 34 text-align: center;
35 35 position: fixed;
36   - margin-top: -23rpx;
37 36 z-index: 66666;
38   - right: 60rpx;
  37 + right: 75rpx;
  38 + top: 465rpx;
39 39 background: #c8162c;
40 40 }
41 41 .xc-qr-frame{
... ... @@ -50,7 +50,7 @@
50 50 margin-left: -280rpx; border-radius:10rpx
51 51 }
52 52  
53   -.ck_btn{width:44%;height:52rpx;line-height:60rpx;background:#f35e73;border-radius:10rpx;}
  53 +.ck_btn{color: #000; width:44%;height:52rpx;line-height:60rpx;background:#f35e73;border-radius:10rpx;}
54 54  
55 55 .fs36{ font-size: 36rpx; }
56 56 .fs30{ font-size: 30rpx; }
... ...
components/qr_code/qr_code.wxml
... ... @@ -24,7 +24,7 @@
24 24 </view>
25 25  
26 26 </view>
27   - <view class="shut" bindtap="close"></view>
  27 + <view class="shut" bindtap="close"><text class="iconfont icon-close"></text></view>
28 28 </view>
29 29 <!-- </scroll-view> -->
30 30 </view>
31 31 \ No newline at end of file
... ...
components/qr_code/qr_code.wxss
  1 +@import '../../app.wxss';
  2 +
1 3 .xc-pop-up{
2 4 width: 100%;
3 5 height: 100%;
... ... @@ -90,36 +92,39 @@ top: 5rpx;
90 92 .qrcode{
91 93 width:520rpx;
92 94 height:520rpx;
93   - margin-top:-27rpx
  95 + margin-top:-18rpx
94 96  
95 97  
96 98 }
97 99 .r-code{
98 100 font-size:28rpx;
99   - padding-left: 25rpx;
100   -margin-top: -5.5rpx;
  101 + margin-top: -5.5rpx;
  102 + text-align: center;
101 103  
102 104 }
103 105  
104 106 .shut{
105   - display: block;
  107 + /* display: block;
106 108 width: 54rpx;
107 109 height: 54rpx;
108 110 border: 2rpx solid #fff;
109 111 font-size: 50rpx;
110   - z-index:55;
111   - line-height:47rpx;
  112 + line-height:54rpx;
112 113 margin-top: 45rpx;
113 114 border-radius: 50%;
114 115 -moz-border-radius: 50%;
115   - -webkit-border-radius: 50%;
  116 + -webkit-border-radius: 50%; */
  117 + z-index:55;
116 118 color: #fff;
117 119 text-align: center;
118 120 position: fixed;
119 121 top:940rpx;
120   - left:345rpx;
121   -
122   -
  122 + left:50%;
  123 + transform: translateX(-50%);
  124 +}
  125 +.icon-close:before {
  126 + content: "\e62e";
  127 + font-size: 50rpx;
123 128 }
124 129  
125 130 .mt{ margin-top:130rpx}
... ...
packageA/pages/myGift/myGift.js
... ... @@ -144,8 +144,9 @@ Page({
144 144 isShowLoading: true,
145 145 })
146 146 .then(function(res) {
  147 + console.log(res);
147 148 if(res.data.code == 0) {
148   -
  149 +
149 150 self.setData({
150 151 isLoading: false
151 152 });
... ... @@ -154,10 +155,12 @@ Page({
154 155 self.setData({
155 156 list: res.data.data
156 157 });
  158 + // console.log(this.data.list);
157 159 } else {
158 160 self.setData({
159 161 'list.pageData': self.data.list.pageData.concat(res.data.data.pageData)
160 162 });
  163 +
161 164 };
162 165  
163 166 if((res.data.data.pageData.length == 0) || (res.data.data.pageSize * res.data.data.page >= res.data.data.total)) {
... ... @@ -312,5 +315,19 @@ Page({
312 315  
313 316 })
314 317 },
  318 +
  319 +
  320 + show_remark:function(e){
  321 + var index=e.currentTarget.dataset.index;
  322 + var item=this.data.list.pageData[index];
  323 + this.setData({
  324 + show_rem_pop:1,
  325 + pop_remark_text:item.lbintro
  326 + })
  327 + },
  328 +
  329 + close_remark:function(){
  330 + this.setData({show_rem_pop:0,})
  331 + }
315 332  
316 333 })
317 334 \ No newline at end of file
... ...
packageA/pages/myGift/myGift.wxml
... ... @@ -8,7 +8,10 @@
8 8 <view class="tab-item" wx:for="{{list.pageData}}">
9 9 <view bindtap="goto" data-url="{{'/packageA/pages/myGiftDetails/myGiftDetails?index=0&id=' + item.id}}">
10 10 <!-- 图片 -->
11   - <view class="img-container"><image src="{{imghost + (item.lburl ? item.lburl:'miniapp/images/default_g_img.gif')}}" class="img" mode="widthFix"/></view>
  11 + <view class="img-container rel">
  12 + <image src="{{imghost + (item.lburl ? item.lburl:'miniapp/images/default_g_img.gif')}}" class="img" mode="widthFix"/>
  13 + <view catchtap="show_remark" data-index="{{index}}" class="lb_remark ellipsis-1" wx:if="{{item.lbintro}}">活动说明:{{item.lbintro}}</view>
  14 + </view>
12 15 <view class="desc-container">
13 16 <!-- 标题 -->
14 17 <view class="mgb10 ellipsis-2 lh taj">{{item.lbtitle}}</view>
... ... @@ -33,7 +36,7 @@
33 36 <view class="fs24 c-a4">已售{{item.salenum}}件</view>
34 37 </view>
35 38 <!-- 时间 -->
36   - <view class="date">活动截止日期 {{filter.format_time(item.expdate)}}</view>
  39 + <view class="date">活动结束日期 {{filter.format_time(item.endtime)}}</view>
37 40 <!-- 按钮 -->
38 41 </view>
39 42 </view>
... ... @@ -52,10 +55,11 @@
52 55 <!-- 标题 -->
53 56 <view class="mgb10 ellipsis-2 lh taj">{{item.lbtitle}}</view>
54 57 <!-- 时间 -->
55   - <view class="date pdb20">活动截止日期 {{filter.format_time(item.endtime)}}</view>
  58 + <view class="date pdb20" wx:if="{{item.lbtype==1}}">兑换截止日期 {{filter.format_time(item.expdate,1)}}</view>
  59 + <view catchtap="show_remark" data-index="{{index}}" wx:if="{{item.lbintro}}" class="date pdb20">活动说明</view>
56 60 </view>
57 61 <!-- 说明 -->
58   - <view class="c-red fs24">*请到线下门店兑换</view>
  62 + <view wx:if="{{item.lbtype==1}}" class="c-red fs24">注:请到线下门店兑换</view>
59 63 </view>
60 64 </view>
61 65 </block>
... ... @@ -68,3 +72,13 @@
68 72 <!-- 引入提示组件 -->
69 73 <warn id="warn"></warn>
70 74 <my_confirm id="my_confirm"></my_confirm>
  75 +<view wx:if="{{show_rem_pop}}">
  76 + <view class="cover-layer" bindtap="close_remark"></view>
  77 + <view class="rem_pop;">
  78 + <view style="text-align: right;"bindtap="close_remark"><text class="iconfont icon-close" style="font-size: 40rpx;"></text></view>
  79 + <view style="padding: 0 16rpx;">
  80 + <view class="fs32">活动说明:</view>
  81 + <view class="fs30">{{pop_remark_text}}</view>
  82 + </view>
  83 + </view>
  84 +</view>
71 85 \ No newline at end of file
... ...
packageA/pages/myGift/myGift.wxss
... ... @@ -164,4 +164,28 @@ page {
164 164 color: #bbb;
165 165 text-align: center;
166 166 font-size: 22rpx;
167   -}
168 167 \ No newline at end of file
  168 +}
  169 +.lb_remark{
  170 + position: absolute;
  171 + bottom: 0;
  172 + left: 0;
  173 + width: 100%;
  174 + height: 50rpx;
  175 + line-height: 50rpx;
  176 + font-size: 30rpx;
  177 + color: #333;
  178 + padding-left: 10rpx;
  179 + background-color: rgba(250,250,250,0.5);
  180 +}
  181 +
  182 +.rem_pop{
  183 + position: fixed;
  184 + top: 30%;
  185 + left: 6%;
  186 + width: 88%;
  187 + margin: 0 auto;
  188 + height: 460rpx;
  189 + background-color: #fff;
  190 + z-index: 100; border-radius: 10rpx;
  191 + padding: 10rpx;
  192 +}
... ...
packageA/pages/myGiftDetails/myGiftDetails.js
... ... @@ -11,7 +11,7 @@ Page({
11 11 data: {
12 12 qr_code_object: {
13 13 val: "12121",
14   - content: "请将二维码展示给核销员,服务更快捷!"
  14 + content: "当前核销码仅限当面使用!"
15 15 },
16 16 },
17 17  
... ... @@ -72,7 +72,7 @@ Page({
72 72 if(res.data.code==0 && res.data.data && res.data.data.pageData && res.data.data.pageData.length>0){
73 73 var da= res.data.data.pageData[0]
74 74 self.setData({ details:da, });
75   -
  75 + console.log(da);
76 76 //礼包有俩种类型
77 77 if(da.lbtype==1){
78 78 app.request.promiseGet('/api/weshop/libao/libaoList/page', {
... ... @@ -94,6 +94,7 @@ Page({
94 94 },
95 95 isShowLoading: true,
96 96 }).then(function(res) {
  97 + console.log(res);
97 98 if(res.data.code==0){
98 99 self.setData({
99 100 list: res.data.data,
... ... @@ -150,6 +151,7 @@ Page({
150 151 },
151 152 isShowLoading: true,
152 153 }).then(function(res) {
  154 + console.log(res);
153 155 // console.log('res4-->', res);
154 156 if(res.data.code==0 && res.data.data) {
155 157 self.setData({
... ... @@ -290,6 +292,7 @@ Page({
290 292 getApp().request.get("/api/weshop/libao/libaoListvip/getLibaoCode",{
291 293 data:data,
292 294 success:function (res){
  295 + console.log(res);
293 296 if(res.data.code==0){
294 297 th.data.qr_code_object.val=res.data.data;
295 298 var qc_com = th.selectComponent("#qrcode"); //组件的id
... ...
packageA/pages/myGiftDetails/myGiftDetails.wxml
... ... @@ -3,7 +3,17 @@
3 3 <!-- 图片 -->
4 4 <view><image src="{{imghost + (details.lburl ? details.lburl:'miniapp/images/default_g_img.gif')}}" class="img" mode="widthFix"/></view>
5 5  
6   - <view wx:if="{{index==1}}" class="fs26 exp_title">兑换结束时间:{{filter.format_time(details.expdate,1)}}</view>
  6 + <!-- 未买 -->
  7 + <block wx:if="{{index==0}}">
  8 + <view class="fs26 exp_title">活动结束时间:{{filter.format_time(details.endtime,1)}}</view>
  9 + </block>
  10 + <!-- 已买 -->
  11 + <block wx:else>
  12 + <view wx:if="{{details.lbtype==1}}"class="fs26 exp_title">兑换结束时间:{{filter.format_time(details.expdate,1)}}</view>
  13 + </block>
  14 +
  15 +
  16 +
7 17 <!-- 描述-->
8 18 <view class="desc-container">
9 19 <!-- 标题 -->
... ... @@ -30,7 +40,7 @@
30 40 <view class="fs24 c-a4">已售{{details.salenum}}件</view>
31 41 </view>
32 42 <!-- 时间 -->
33   - <view class="date">活动截止日期 {{details.expdate ? filter.format_time(details.expdate):filter.format_time(details.endtime)}}</view>
  43 + <!-- <view class="date">活动结束日期 {{filter.format_time(details.endtime)}}</view> -->
34 44 </view>
35 45  
36 46  
... ... @@ -71,16 +81,40 @@
71 81 </view>
72 82  
73 83 <view wx:if="{{details.lbtype==2}}" class="flex" style="flex-wrap: wrap;">
74   - <block wx:for="{{list}}">
  84 + <block wx:for="{{list}}" wx:for-index="f_idx">
75 85 <block wx:for="{{item.goods_num-0}}" wx:for-item="nitem" wx:for-index="idx">
76 86 <view class="lb_quan" style="background-image: url({{imghost}}/miniapp/images/yhq_{{index%2+1}}.png)">
77 87 <view class="flex fs28 fir_view">
78   - <view>满1000.00使用</view>
79   - <view class="fs38" style="text-align: right">¥1000</view>
  88 + <view>满{{item.condition}}使用</view>
  89 + <view class="fs8" style="text-align: right">¥{{item.money}}</view>
80 90 </view>
81   - <view style="font-size: 16rpx; text-align: center">活动结束日期: 2022-06-02 00:00:00 </view>
  91 +
  92 +
  93 + <view style="font-size: 16rpx; text-align: center"> {{index==0?'活动结束日期':'截至时间'}}:
  94 +
  95 + <block wx:if="{{item.endtype<1}}">
  96 + <block wx:if="{{item.use_end_time}}">
  97 + {{filter.format_time(item.use_end_time,1)}}
  98 + </block>
  99 + <block wx:else>
  100 + 不限
  101 + </block>
  102 + </block>
  103 +
  104 + <block wx:else>
  105 + <block wx:if="{{item.days>0}}">
  106 + 有效期{{item.days}}天
  107 + </block>
  108 + <block wx:else>
  109 + 不限
  110 + </block>
  111 +
  112 + </block>
  113 + </view>
  114 +
  115 +
82 116 </view>
83   - </block>
  117 + </block>
84 118 </block>
85 119 </view>
86 120  
... ... @@ -106,7 +140,7 @@
106 140 <view wx:if="{{details.lbprice>0}}" bindtap="GetBuyPrice" class="btn pink">立即购买</view>
107 141 </block>
108 142 <block wx:else>
109   - <view wx:if="{{details.isget}}" data-type="1" class="btn" style="background-color:#aaa;color: #fff">已领</view>
  143 + <view wx:if="{{details.isget}}" data-type="1" class="btn" style="background-color:#aaa;color: #fff">已领</view>
110 144 <view wx:else bindtap="show_get_quan" data-type="1" class="btn red">一键领取优惠券→</view>
111 145 </block>
112 146 </view>
... ...
packageB/components/painter/lib/downloader.js 0 → 100644
  1 +/**
  2 + * LRU 文件存储,使用该 downloader 可以让下载的文件存储在本地,下次进入小程序后可以直接使用
  3 + * 详细设计文档可查看 https://juejin.im/post/5b42d3ede51d4519277b6ce3
  4 + */
  5 +const util = require('./util');
  6 +
  7 +const SAVED_FILES_KEY = 'savedFiles';
  8 +const KEY_TOTAL_SIZE = 'totalSize';
  9 +const KEY_PATH = 'path';
  10 +const KEY_TIME = 'time';
  11 +const KEY_SIZE = 'size';
  12 +
  13 +// 可存储总共为 6M,目前小程序可允许的最大本地存储为 10M
  14 +let MAX_SPACE_IN_B = 6 * 1024 * 1024;
  15 +let savedFiles = {};
  16 +
  17 +export default class Dowloader {
  18 + constructor() {
  19 + // app 如果设置了最大存储空间,则使用 app 中的
  20 + if (getApp().PAINTER_MAX_LRU_SPACE) {
  21 + MAX_SPACE_IN_B = getApp().PAINTER_MAX_LRU_SPACE;
  22 + }
  23 + wx.getStorage({
  24 + key: SAVED_FILES_KEY,
  25 + success: function (res) {
  26 + if (res.data) {
  27 + savedFiles = res.data;
  28 + }
  29 + },
  30 + });
  31 + }
  32 +
  33 + /**
  34 + * 下载文件,会用 lru 方式来缓存文件到本地
  35 + * @param {String} url 文件的 url
  36 + */
  37 + download(url, lru) {
  38 + return new Promise((resolve, reject) => {
  39 + if (!(url && util.isValidUrl(url))) {
  40 + resolve(url);
  41 + return;
  42 + }
  43 + if (!lru) {
  44 + // 无 lru 情况下直接判断 临时文件是否存在,不存在重新下载
  45 + wx.getFileInfo({
  46 + filePath: url,
  47 + success: () => {
  48 + resolve(url);
  49 + },
  50 + fail: () => {
  51 + downloadFile(url, lru).then((path) => {
  52 + resolve(path);
  53 + }, () => {
  54 + reject();
  55 + });
  56 + },
  57 + })
  58 + return
  59 + }
  60 +
  61 + const file = getFile(url);
  62 +
  63 + if (file) {
  64 + // 检查文件是否正常,不正常需要重新下载
  65 + wx.getSavedFileInfo({
  66 + filePath: file[KEY_PATH],
  67 + success: (res) => {
  68 + resolve(file[KEY_PATH]);
  69 + },
  70 + fail: (error) => {
  71 + console.error(`the file is broken, redownload it, ${JSON.stringify(error)}`);
  72 + downloadFile(url, lru).then((path) => {
  73 + resolve(path);
  74 + }, () => {
  75 + reject();
  76 + });
  77 + },
  78 + });
  79 + } else {
  80 + downloadFile(url, lru).then((path) => {
  81 + resolve(path);
  82 + }, () => {
  83 + reject();
  84 + });
  85 + }
  86 + });
  87 + }
  88 +}
  89 +
  90 +function downloadFile(url, lru) {
  91 + return new Promise((resolve, reject) => {
  92 + wx.downloadFile({
  93 + url: url,
  94 + success: function (res) {
  95 + if (res.statusCode !== 200) {
  96 + console.error(`downloadFile ${url} failed res.statusCode is not 200`);
  97 + reject();
  98 + return;
  99 + }
  100 + const {
  101 + tempFilePath
  102 + } = res;
  103 + wx.getFileInfo({
  104 + filePath: tempFilePath,
  105 + success: (tmpRes) => {
  106 + const newFileSize = tmpRes.size;
  107 + lru ? doLru(newFileSize).then(() => {
  108 + saveFile(url, newFileSize, tempFilePath).then((filePath) => {
  109 + resolve(filePath);
  110 + });
  111 + }, () => {
  112 + resolve(tempFilePath);
  113 + }) : resolve(tempFilePath);
  114 + },
  115 + fail: (error) => {
  116 + // 文件大小信息获取失败,则此文件也不要进行存储
  117 + console.error(`getFileInfo ${res.tempFilePath} failed, ${JSON.stringify(error)}`);
  118 + resolve(res.tempFilePath);
  119 + },
  120 + });
  121 + },
  122 + fail: function (error) {
  123 + console.error(`downloadFile failed, ${JSON.stringify(error)} `);
  124 + reject();
  125 + },
  126 + });
  127 + });
  128 +}
  129 +
  130 +function saveFile(key, newFileSize, tempFilePath) {
  131 + return new Promise((resolve, reject) => {
  132 + wx.saveFile({
  133 + tempFilePath: tempFilePath,
  134 + success: (fileRes) => {
  135 + const totalSize = savedFiles[KEY_TOTAL_SIZE] ? savedFiles[KEY_TOTAL_SIZE] : 0;
  136 + savedFiles[key] = {};
  137 + savedFiles[key][KEY_PATH] = fileRes.savedFilePath;
  138 + savedFiles[key][KEY_TIME] = new Date().getTime();
  139 + savedFiles[key][KEY_SIZE] = newFileSize;
  140 + savedFiles['totalSize'] = newFileSize + totalSize;
  141 + wx.setStorage({
  142 + key: SAVED_FILES_KEY,
  143 + data: savedFiles,
  144 + });
  145 + resolve(fileRes.savedFilePath);
  146 + },
  147 + fail: (error) => {
  148 + console.error(`saveFile ${key} failed, then we delete all files, ${JSON.stringify(error)}`);
  149 + // 由于 saveFile 成功后,res.tempFilePath 处的文件会被移除,所以在存储未成功时,我们还是继续使用临时文件
  150 + resolve(tempFilePath);
  151 + // 如果出现错误,就直接情况本地的所有文件,因为你不知道是不是因为哪次lru的某个文件未删除成功
  152 + reset();
  153 + },
  154 + });
  155 + });
  156 +}
  157 +
  158 +/**
  159 + * 清空所有下载相关内容
  160 + */
  161 +function reset() {
  162 + wx.removeStorage({
  163 + key: SAVED_FILES_KEY,
  164 + success: () => {
  165 + wx.getSavedFileList({
  166 + success: (listRes) => {
  167 + removeFiles(listRes.fileList);
  168 + },
  169 + fail: (getError) => {
  170 + console.error(`getSavedFileList failed, ${JSON.stringify(getError)}`);
  171 + },
  172 + });
  173 + },
  174 + });
  175 +}
  176 +
  177 +function doLru(size) {
  178 + if (size > MAX_SPACE_IN_B) {
  179 + return Promise.reject()
  180 + }
  181 + return new Promise((resolve, reject) => {
  182 + let totalSize = savedFiles[KEY_TOTAL_SIZE] ? savedFiles[KEY_TOTAL_SIZE] : 0;
  183 +
  184 + if (size + totalSize <= MAX_SPACE_IN_B) {
  185 + resolve();
  186 + return;
  187 + }
  188 + // 如果加上新文件后大小超过最大限制,则进行 lru
  189 + const pathsShouldDelete = [];
  190 + // 按照最后一次的访问时间,从小到大排序
  191 + const allFiles = JSON.parse(JSON.stringify(savedFiles));
  192 + delete allFiles[KEY_TOTAL_SIZE];
  193 + const sortedKeys = Object.keys(allFiles).sort((a, b) => {
  194 + return allFiles[a][KEY_TIME] - allFiles[b][KEY_TIME];
  195 + });
  196 +
  197 + for (const sortedKey of sortedKeys) {
  198 + totalSize -= savedFiles[sortedKey].size;
  199 + pathsShouldDelete.push(savedFiles[sortedKey][KEY_PATH]);
  200 + delete savedFiles[sortedKey];
  201 + if (totalSize + size < MAX_SPACE_IN_B) {
  202 + break;
  203 + }
  204 + }
  205 +
  206 + savedFiles['totalSize'] = totalSize;
  207 +
  208 + wx.setStorage({
  209 + key: SAVED_FILES_KEY,
  210 + data: savedFiles,
  211 + success: () => {
  212 + // 保证 storage 中不会存在不存在的文件数据
  213 + if (pathsShouldDelete.length > 0) {
  214 + removeFiles(pathsShouldDelete);
  215 + }
  216 + resolve();
  217 + },
  218 + fail: (error) => {
  219 + console.error(`doLru setStorage failed, ${JSON.stringify(error)}`);
  220 + reject();
  221 + },
  222 + });
  223 + });
  224 +}
  225 +
  226 +function removeFiles(pathsShouldDelete) {
  227 + for (const pathDel of pathsShouldDelete) {
  228 + let delPath = pathDel;
  229 + if (typeof pathDel === 'object') {
  230 + delPath = pathDel.filePath;
  231 + }
  232 + wx.removeSavedFile({
  233 + filePath: delPath,
  234 + fail: (error) => {
  235 + console.error(`removeSavedFile ${pathDel} failed, ${JSON.stringify(error)}`);
  236 + },
  237 + });
  238 + }
  239 +}
  240 +
  241 +function getFile(key) {
  242 + if (!savedFiles[key]) {
  243 + return;
  244 + }
  245 + savedFiles[key]['time'] = new Date().getTime();
  246 + wx.setStorage({
  247 + key: SAVED_FILES_KEY,
  248 + data: savedFiles,
  249 + });
  250 + return savedFiles[key];
  251 +}
0 252 \ No newline at end of file
... ...
packageB/components/painter/lib/gradient.js 0 → 100644
  1 +/* eslint-disable */
  2 +// 当ctx传入当前文件,const grd = ctx.createCircularGradient() 和
  3 +// const grd = this.ctx.createLinearGradient() 无效,因此只能分开处理
  4 +// 先分析,在外部创建grd,再传入使用就可以
  5 +
  6 +!(function () {
  7 +
  8 + var api = {
  9 + isGradient: function(bg) {
  10 + if (bg && (bg.startsWith('linear') || bg.startsWith('radial'))) {
  11 + return true;
  12 + }
  13 + return false;
  14 + },
  15 +
  16 + doGradient: function(bg, width, height, ctx) {
  17 + if (bg.startsWith('linear')) {
  18 + linearEffect(width, height, bg, ctx);
  19 + } else if (bg.startsWith('radial')) {
  20 + radialEffect(width, height, bg, ctx);
  21 + }
  22 + },
  23 + }
  24 +
  25 + function analizeGrad(string) {
  26 + const colorPercents = string.substring(0, string.length - 1).split("%,");
  27 + const colors = [];
  28 + const percents = [];
  29 + for (let colorPercent of colorPercents) {
  30 + colors.push(colorPercent.substring(0, colorPercent.lastIndexOf(" ")).trim());
  31 + percents.push(colorPercent.substring(colorPercent.lastIndexOf(" "), colorPercent.length) / 100);
  32 + }
  33 + return {colors: colors, percents: percents};
  34 + }
  35 +
  36 + function radialEffect(width, height, bg, ctx) {
  37 + const colorPer = analizeGrad(bg.match(/radial-gradient\((.+)\)/)[1]);
  38 + const grd = ctx.createRadialGradient(0, 0, 0, 0, 0, width < height ? height / 2 : width / 2);
  39 + for (let i = 0; i < colorPer.colors.length; i++) {
  40 + grd.addColorStop(colorPer.percents[i], colorPer.colors[i]);
  41 + }
  42 + ctx.fillStyle = grd;
  43 + //ctx.fillRect(-(width / 2), -(height / 2), width, height);
  44 + }
  45 +
  46 + function analizeLinear(bg, width, height) {
  47 + const direction = bg.match(/([-]?\d{1,3})deg/);
  48 + const dir = direction && direction[1] ? parseFloat(direction[1]) : 0;
  49 + let coordinate;
  50 + switch (dir) {
  51 + case 0: coordinate = [0, -height / 2, 0, height / 2]; break;
  52 + case 90: coordinate = [width / 2, 0, -width / 2, 0]; break;
  53 + case -90: coordinate = [-width / 2, 0, width / 2, 0]; break;
  54 + case 180: coordinate = [0, height / 2, 0, -height / 2]; break;
  55 + case -180: coordinate = [0, -height / 2, 0, height / 2]; break;
  56 + default:
  57 + let x1 = 0;
  58 + let y1 = 0;
  59 + let x2 = 0;
  60 + let y2 = 0;
  61 + if (direction[1] > 0 && direction[1] < 90) {
  62 + x1 = (width / 2) - ((width / 2) * Math.tan((90 - direction[1]) * Math.PI * 2 / 360) - height / 2) * Math.sin(2 * (90 - direction[1]) * Math.PI * 2 / 360) / 2;
  63 + y2 = Math.tan((90 - direction[1]) * Math.PI * 2 / 360) * x1;
  64 + x2 = -x1;
  65 + y1 = -y2;
  66 + } else if (direction[1] > -180 && direction[1] < -90) {
  67 + x1 = -(width / 2) + ((width / 2) * Math.tan((90 - direction[1]) * Math.PI * 2 / 360) - height / 2) * Math.sin(2 * (90 - direction[1]) * Math.PI * 2 / 360) / 2;
  68 + y2 = Math.tan((90 - direction[1]) * Math.PI * 2 / 360) * x1;
  69 + x2 = -x1;
  70 + y1 = -y2;
  71 + } else if (direction[1] > 90 && direction[1] < 180) {
  72 + x1 = (width / 2) + (-(width / 2) * Math.tan((90 - direction[1]) * Math.PI * 2 / 360) - height / 2) * Math.sin(2 * (90 - direction[1]) * Math.PI * 2 / 360) / 2;
  73 + y2 = Math.tan((90 - direction[1]) * Math.PI * 2 / 360) * x1;
  74 + x2 = -x1;
  75 + y1 = -y2;
  76 + } else {
  77 + x1 = -(width / 2) - (-(width / 2) * Math.tan((90 - direction[1]) * Math.PI * 2 / 360) - height / 2) * Math.sin(2 * (90 - direction[1]) * Math.PI * 2 / 360) / 2;
  78 + y2 = Math.tan((90 - direction[1]) * Math.PI * 2 / 360) * x1;
  79 + x2 = -x1;
  80 + y1 = -y2;
  81 + }
  82 + coordinate = [x1, y1, x2, y2];
  83 + break;
  84 + }
  85 + return coordinate;
  86 + }
  87 +
  88 + function linearEffect(width, height, bg, ctx) {
  89 + const param = analizeLinear(bg, width, height);
  90 + const grd = ctx.createLinearGradient(param[0], param[1], param[2], param[3]);
  91 + const content = bg.match(/linear-gradient\((.+)\)/)[1];
  92 + const colorPer = analizeGrad(content.substring(content.indexOf(',') + 1));
  93 + for (let i = 0; i < colorPer.colors.length; i++) {
  94 + grd.addColorStop(colorPer.percents[i], colorPer.colors[i]);
  95 + }
  96 + ctx.fillStyle = grd
  97 + //ctx.fillRect(-(width / 2), -(height / 2), width, height);
  98 + }
  99 +
  100 + module.exports = { api }
  101 +
  102 +})();
... ...
packageB/components/painter/lib/pen.js 0 → 100644
  1 +const QR = require('./qrcode.js');
  2 +const GD = require('./gradient.js');
  3 +
  4 +export default class Painter {
  5 + constructor(ctx, data) {
  6 + this.ctx = ctx;
  7 + this.data = data;
  8 + this.globalWidth = {};
  9 + this.globalHeight = {};
  10 + }
  11 +
  12 + isMoving = false
  13 + movingCache = {}
  14 + paint(callback, isMoving, movingCache) {
  15 + this.style = {
  16 + width: this.data.width.toPx(),
  17 + height: this.data.height.toPx(),
  18 + };
  19 + if (isMoving) {
  20 + this.isMoving = true
  21 + this.movingCache = movingCache
  22 + }
  23 + this._background();
  24 + for (const view of this.data.views) {
  25 + this._drawAbsolute(view);
  26 + }
  27 + this.ctx.draw(false, () => {
  28 + callback && callback(this.callbackInfo);
  29 + });
  30 + }
  31 +
  32 + _background() {
  33 + this.ctx.save();
  34 + const {
  35 + width,
  36 + height,
  37 + } = this.style;
  38 + const bg = this.data.background;
  39 + this.ctx.translate(width / 2, height / 2);
  40 +
  41 + this._doClip(this.data.borderRadius, width, height);
  42 + if (!bg) {
  43 + // 如果未设置背景,则默认使用透明色
  44 + this.ctx.fillStyle = 'transparent';
  45 + this.ctx.fillRect(-(width / 2), -(height / 2), width, height);
  46 + } else if (bg.startsWith('#') || bg.startsWith('rgba') || bg.toLowerCase() === 'transparent') {
  47 + // 背景填充颜色
  48 + this.ctx.fillStyle = bg;
  49 + this.ctx.fillRect(-(width / 2), -(height / 2), width, height);
  50 + } else if (GD.api.isGradient(bg)) {
  51 + GD.api.doGradient(bg, width, height, this.ctx);
  52 + this.ctx.fillRect(-(width / 2), -(height / 2), width, height);
  53 + } else {
  54 + // 背景填充图片
  55 + this.ctx.drawImage(bg, -(width / 2), -(height / 2), width, height);
  56 + }
  57 + this.ctx.restore();
  58 + }
  59 +
  60 + _drawAbsolute(view) {
  61 + if (!(view && view.type)) {
  62 + // 过滤无效 view
  63 + return
  64 + }
  65 + // 证明 css 为数组形式,需要合并
  66 + if (view.css && view.css.length) {
  67 + /* eslint-disable no-param-reassign */
  68 + view.css = Object.assign(...view.css);
  69 + }
  70 + switch (view.type) {
  71 + case 'image':
  72 + this._drawAbsImage(view);
  73 + break;
  74 + case 'text':
  75 + this._fillAbsText(view);
  76 + break;
  77 + case 'rect':
  78 + this._drawAbsRect(view);
  79 + break;
  80 + case 'qrcode':
  81 + this._drawQRCode(view);
  82 + break;
  83 + default:
  84 + break;
  85 + }
  86 + }
  87 +
  88 + _border({
  89 + borderRadius = 0,
  90 + width,
  91 + height,
  92 + borderWidth = 0,
  93 + borderStyle = 'solid'
  94 + }) {
  95 + let r1 = 0,
  96 + r2 = 0,
  97 + r3 = 0,
  98 + r4 = 0
  99 + const minSize = Math.min(width, height);
  100 + if (borderRadius) {
  101 + const border = borderRadius.split(/\s+/)
  102 + if (border.length === 4) {
  103 + r1 = Math.min(border[0].toPx(false, minSize), width / 2, height / 2);
  104 + r2 = Math.min(border[1].toPx(false, minSize), width / 2, height / 2);
  105 + r3 = Math.min(border[2].toPx(false, minSize), width / 2, height / 2);
  106 + r4 = Math.min(border[3].toPx(false, minSize), width / 2, height / 2);
  107 + } else {
  108 + r1 = r2 = r3 = r4 = Math.min(borderRadius && borderRadius.toPx(false, minSize), width / 2, height / 2);
  109 + }
  110 + }
  111 + const lineWidth = borderWidth && borderWidth.toPx(false, minSize);
  112 + this.ctx.lineWidth = lineWidth;
  113 + if (borderStyle === 'dashed') {
  114 + this.ctx.setLineDash([lineWidth * 4 / 3, lineWidth * 4 / 3]);
  115 + // this.ctx.lineDashOffset = 2 * lineWidth
  116 + } else if (borderStyle === 'dotted') {
  117 + this.ctx.setLineDash([lineWidth, lineWidth]);
  118 + }
  119 + const notSolid = borderStyle !== 'solid'
  120 + this.ctx.beginPath();
  121 +
  122 + notSolid && r1 === 0 && this.ctx.moveTo(-width / 2 - lineWidth, -height / 2 - lineWidth / 2) // 顶边虚线规避重叠规则
  123 + r1 !== 0 && this.ctx.arc(-width / 2 + r1, -height / 2 + r1, r1 + lineWidth / 2, 1 * Math.PI, 1.5 * Math.PI); //左上角圆弧
  124 + this.ctx.lineTo(r2 === 0 ? notSolid ? width / 2 : width / 2 + lineWidth / 2 : width / 2 - r2, -height / 2 - lineWidth / 2); // 顶边线
  125 +
  126 + notSolid && r2 === 0 && this.ctx.moveTo(width / 2 + lineWidth / 2, -height / 2 - lineWidth) // 右边虚线规避重叠规则
  127 + r2 !== 0 && this.ctx.arc(width / 2 - r2, -height / 2 + r2, r2 + lineWidth / 2, 1.5 * Math.PI, 2 * Math.PI); // 右上角圆弧
  128 + this.ctx.lineTo(width / 2 + lineWidth / 2, r3 === 0 ? notSolid ? height / 2 : height / 2 + lineWidth / 2 : height / 2 - r3); // 右边线
  129 +
  130 + notSolid && r3 === 0 && this.ctx.moveTo(width / 2 + lineWidth, height / 2 + lineWidth / 2) // 底边虚线规避重叠规则
  131 + r3 !== 0 && this.ctx.arc(width / 2 - r3, height / 2 - r3, r3 + lineWidth / 2, 0, 0.5 * Math.PI); // 右下角圆弧
  132 + this.ctx.lineTo(r4 === 0 ? notSolid ? -width / 2 : -width / 2 - lineWidth / 2 : -width / 2 + r4, height / 2 + lineWidth / 2); // 底边线
  133 +
  134 + notSolid && r4 === 0 && this.ctx.moveTo(-width / 2 - lineWidth / 2, height / 2 + lineWidth) // 左边虚线规避重叠规则
  135 + r4 !== 0 && this.ctx.arc(-width / 2 + r4, height / 2 - r4, r4 + lineWidth / 2, 0.5 * Math.PI, 1 * Math.PI); // 左下角圆弧
  136 + this.ctx.lineTo(-width / 2 - lineWidth / 2, r1 === 0 ? notSolid ? -height / 2 : -height / 2 - lineWidth / 2 : -height / 2 + r1); // 左边线
  137 + notSolid && r1 === 0 && this.ctx.moveTo(-width / 2 - lineWidth, -height / 2 - lineWidth / 2) // 顶边虚线规避重叠规则
  138 +
  139 + if (!notSolid) {
  140 + this.ctx.closePath();
  141 + }
  142 + }
  143 +
  144 + /**
  145 + * 根据 borderRadius 进行裁减
  146 + */
  147 + _doClip(borderRadius, width, height, borderStyle) {
  148 + if (borderRadius && width && height) {
  149 + // 防止在某些机型上周边有黑框现象,此处如果直接设置 fillStyle 为透明,在 Android 机型上会导致被裁减的图片也变为透明, iOS 和 IDE 上不会
  150 + // globalAlpha 在 1.9.90 起支持,低版本下无效,但把 fillStyle 设为了 white,相对默认的 black 要好点
  151 + this.ctx.globalAlpha = 0;
  152 + this.ctx.fillStyle = 'white';
  153 + this._border({
  154 + borderRadius,
  155 + width,
  156 + height,
  157 + borderStyle
  158 + })
  159 + this.ctx.fill();
  160 + // 在 ios 的 6.6.6 版本上 clip 有 bug,禁掉此类型上的 clip,也就意味着,在此版本微信的 ios 设备下无法使用 border 属性
  161 + if (!(getApp().systemInfo &&
  162 + getApp().systemInfo.version <= '6.6.6' &&
  163 + getApp().systemInfo.platform === 'ios')) {
  164 + this.ctx.clip();
  165 + }
  166 + this.ctx.globalAlpha = 1;
  167 + }
  168 + }
  169 +
  170 + /**
  171 + * 画边框
  172 + */
  173 + _doBorder(view, width, height) {
  174 + if (!view.css) {
  175 + return;
  176 + }
  177 + const {
  178 + borderRadius,
  179 + borderWidth,
  180 + borderColor,
  181 + borderStyle
  182 + } = view.css;
  183 + if (!borderWidth) {
  184 + return;
  185 + }
  186 + this.ctx.save();
  187 + this._preProcess(view, true);
  188 + this.ctx.strokeStyle = (borderColor || 'black');
  189 + this._border({
  190 + borderRadius,
  191 + width,
  192 + height,
  193 + borderWidth,
  194 + borderStyle
  195 + })
  196 + this.ctx.stroke();
  197 + this.ctx.restore();
  198 + }
  199 +
  200 + _preProcess(view, notClip) {
  201 + let width = 0;
  202 + let height;
  203 + let extra;
  204 + const paddings = this._doPaddings(view);
  205 + switch (view.type) {
  206 + case 'text': {
  207 + const textArray = view.text.split('\n');
  208 + // 处理多个连续的'\n'
  209 + for (let i = 0; i < textArray.length; ++i) {
  210 + if (textArray[i] === '') {
  211 + textArray[i] = ' ';
  212 + }
  213 + }
  214 + const fontWeight = view.css.fontWeight || '400';
  215 + const textStyle = view.css.textStyle || 'normal';
  216 + if (!view.css.fontSize) {
  217 + view.css.fontSize = '20rpx';
  218 + }
  219 + this.ctx.font = `${textStyle} ${fontWeight} ${view.css.fontSize.toPx()}px "${view.css.fontFamily || 'sans-serif'}"`;
  220 + // 计算行数
  221 + let lines = 0;
  222 + const linesArray = [];
  223 + for (let i = 0; i < textArray.length; ++i) {
  224 + const textLength = this.ctx.measureText(textArray[i]).width;
  225 + const minWidth = view.css.fontSize.toPx() + paddings[1] + paddings[3];
  226 + let partWidth = view.css.width ? view.css.width.toPx(false, this.style.width) - paddings[1] - paddings[3] : textLength;
  227 + if (partWidth < minWidth) {
  228 + partWidth = minWidth;
  229 + }
  230 + const calLines = Math.ceil(textLength / partWidth);
  231 + // 取最长的作为 width
  232 + width = partWidth > width ? partWidth : width;
  233 + lines += calLines;
  234 + linesArray[i] = calLines;
  235 + }
  236 + lines = view.css.maxLines < lines ? view.css.maxLines : lines;
  237 + const lineHeight = view.css.lineHeight ? view.css.lineHeight.toPx() : view.css.fontSize.toPx();
  238 + height = lineHeight * lines;
  239 + extra = {
  240 + lines: lines,
  241 + lineHeight: lineHeight,
  242 + textArray: textArray,
  243 + linesArray: linesArray,
  244 + };
  245 + break;
  246 + }
  247 + case 'image': {
  248 + // image的长宽设置成auto的逻辑处理
  249 + const ratio = getApp().systemInfo.pixelRatio ? getApp().systemInfo.pixelRatio : 2;
  250 + // 有css却未设置width或height,则默认为auto
  251 + if (view.css) {
  252 + if (!view.css.width) {
  253 + view.css.width = 'auto';
  254 + }
  255 + if (!view.css.height) {
  256 + view.css.height = 'auto';
  257 + }
  258 + }
  259 + if (!view.css || (view.css.width === 'auto' && view.css.height === 'auto')) {
  260 + width = Math.round(view.sWidth / ratio);
  261 + height = Math.round(view.sHeight / ratio);
  262 + } else if (view.css.width === 'auto') {
  263 + height = view.css.height.toPx(false, this.style.height);
  264 + width = view.sWidth / view.sHeight * height;
  265 + } else if (view.css.height === 'auto') {
  266 + width = view.css.width.toPx(false, this.style.width);
  267 + height = view.sHeight / view.sWidth * width;
  268 + } else {
  269 + width = view.css.width.toPx(false, this.style.width);
  270 + height = view.css.height.toPx(false, this.style.height);
  271 + }
  272 + break;
  273 + }
  274 + default:
  275 + if (!(view.css.width && view.css.height)) {
  276 + console.error('You should set width and height');
  277 + return;
  278 + }
  279 + width = view.css.width.toPx(false, this.style.width);
  280 + height = view.css.height.toPx(false, this.style.height);
  281 + break;
  282 + }
  283 + let x;
  284 + if (view.css && view.css.right) {
  285 + if (typeof view.css.right === 'string') {
  286 + x = this.style.width - view.css.right.toPx(true, this.style.width);
  287 + } else {
  288 + // 可以用数组方式,把文字长度计算进去
  289 + // [right, 文字id, 乘数(默认 1)]
  290 + const rights = view.css.right;
  291 + x = this.style.width - rights[0].toPx(true, this.style.width) - this.globalWidth[rights[1]] * (rights[2] || 1);
  292 + }
  293 + } else if (view.css && view.css.left) {
  294 + if (typeof view.css.left === 'string') {
  295 + x = view.css.left.toPx(true, this.style.width);
  296 + } else {
  297 + const lefts = view.css.left;
  298 + x = lefts[0].toPx(true, this.style.width) + this.globalWidth[lefts[1]] * (lefts[2] || 1);
  299 + }
  300 + } else {
  301 + x = 0;
  302 + }
  303 + //const y = view.css && view.css.bottom ? this.style.height - height - view.css.bottom.toPx(true) : (view.css && view.css.top ? view.css.top.toPx(true) : 0);
  304 + let y;
  305 + if (view.css && view.css.bottom) {
  306 + y = this.style.height - height - view.css.bottom.toPx(true, this.style.height);
  307 + } else {
  308 + if (view.css && view.css.top) {
  309 + if (typeof view.css.top === 'string') {
  310 + y = view.css.top.toPx(true, this.style.height);
  311 + } else {
  312 + const tops = view.css.top;
  313 + y = tops[0].toPx(true, this.style.height) + this.globalHeight[tops[1]] * (tops[2] || 1);
  314 + }
  315 + } else {
  316 + y = 0
  317 + }
  318 + }
  319 +
  320 + const angle = view.css && view.css.rotate ? this._getAngle(view.css.rotate) : 0;
  321 + // 当设置了 right 时,默认 align 用 right,反之用 left
  322 + const align = view.css && view.css.align ? view.css.align : (view.css && view.css.right ? 'right' : 'left');
  323 + const verticalAlign = view.css && view.css.verticalAlign ? view.css.verticalAlign : 'top';
  324 + // 记录绘制时的画布
  325 + let xa = 0;
  326 + switch (align) {
  327 + case 'center':
  328 + xa = x;
  329 + break;
  330 + case 'right':
  331 + xa = x - width / 2;
  332 + break;
  333 + default:
  334 + xa = x + width / 2;
  335 + break;
  336 + }
  337 + let ya = 0;
  338 + switch (verticalAlign) {
  339 + case 'center':
  340 + ya = y;
  341 + break;
  342 + case 'bottom':
  343 + ya = y - height / 2;
  344 + break;
  345 + default:
  346 + ya = y + height / 2;
  347 + break;
  348 + }
  349 + this.ctx.translate(xa, ya);
  350 + // 记录该 view 的有效点击区域
  351 + // TODO ,旋转和裁剪的判断
  352 + // 记录在真实画布上的左侧
  353 + let left = x
  354 + if (align === 'center') {
  355 + left = x - width / 2
  356 + } else if (align === 'right') {
  357 + left = x - width
  358 + }
  359 + var top = y;
  360 + if (verticalAlign === 'center') {
  361 + top = y - height / 2;
  362 + } else if (verticalAlign === 'bottom') {
  363 + top = y - height
  364 + }
  365 + if (view.rect) {
  366 + view.rect.left = left;
  367 + view.rect.top = top;
  368 + view.rect.right = left + width;
  369 + view.rect.bottom = top + height;
  370 + view.rect.x = view.css && view.css.right ? x - width : x;
  371 + view.rect.y = y;
  372 + } else {
  373 + view.rect = {
  374 + left: left,
  375 + top: top,
  376 + right: left + width,
  377 + bottom: top + height,
  378 + x: view.css && view.css.right ? x - width : x,
  379 + y: y
  380 + };
  381 + }
  382 +
  383 + view.rect.left = view.rect.left - paddings[3];
  384 + view.rect.top = view.rect.top - paddings[0];
  385 + view.rect.right = view.rect.right + paddings[1];
  386 + view.rect.bottom = view.rect.bottom + paddings[2];
  387 + if (view.type === 'text') {
  388 + view.rect.minWidth = view.css.fontSize.toPx() + paddings[1] + paddings[3];
  389 + }
  390 +
  391 + this.ctx.rotate(angle);
  392 + if (!notClip && view.css && view.css.borderRadius && view.type !== 'rect') {
  393 + this._doClip(view.css.borderRadius, width, height, view.css.borderStyle);
  394 + }
  395 + this._doShadow(view);
  396 + if (view.id) {
  397 + this.globalWidth[view.id] = width;
  398 + this.globalHeight[view.id] = height;
  399 + }
  400 + return {
  401 + width: width,
  402 + height: height,
  403 + x: x,
  404 + y: y,
  405 + extra: extra,
  406 + };
  407 + }
  408 +
  409 + _doPaddings(view) {
  410 + const {
  411 + padding,
  412 + } = view.css ? view.css : {};
  413 + let pd = [0, 0, 0, 0];
  414 + if (padding) {
  415 + const pdg = padding.split(/\s+/);
  416 + if (pdg.length === 1) {
  417 + const x = pdg[0].toPx();
  418 + pd = [x, x, x, x];
  419 + }
  420 + if (pdg.length === 2) {
  421 + const x = pdg[0].toPx();
  422 + const y = pdg[1].toPx();
  423 + pd = [x, y, x, y];
  424 + }
  425 + if (pdg.length === 3) {
  426 + const x = pdg[0].toPx();
  427 + const y = pdg[1].toPx();
  428 + const z = pdg[2].toPx();
  429 + pd = [x, y, z, y];
  430 + }
  431 + if (pdg.length === 4) {
  432 + const x = pdg[0].toPx();
  433 + const y = pdg[1].toPx();
  434 + const z = pdg[2].toPx();
  435 + const a = pdg[3].toPx();
  436 + pd = [x, y, z, a];
  437 + }
  438 + }
  439 + return pd;
  440 + }
  441 +
  442 + // 画文字的背景图片
  443 + _doBackground(view) {
  444 + this.ctx.save();
  445 + const {
  446 + width: rawWidth,
  447 + height: rawHeight,
  448 + } = this._preProcess(view, true);
  449 +
  450 + const {
  451 + background,
  452 + } = view.css;
  453 + let pd = this._doPaddings(view);
  454 + const width = rawWidth + pd[1] + pd[3];
  455 + const height = rawHeight + pd[0] + pd[2];
  456 +
  457 + this._doClip(view.css.borderRadius, width, height, view.css.borderStyle)
  458 + if (GD.api.isGradient(background)) {
  459 + GD.api.doGradient(background, width, height, this.ctx);
  460 + } else {
  461 + this.ctx.fillStyle = background;
  462 + }
  463 + this.ctx.fillRect(-(width / 2), -(height / 2), width, height);
  464 +
  465 + this.ctx.restore();
  466 + }
  467 +
  468 + _drawQRCode(view) {
  469 + this.ctx.save();
  470 + const {
  471 + width,
  472 + height,
  473 + } = this._preProcess(view);
  474 + QR.api.draw(view.content, this.ctx, -width / 2, -height / 2, width, height, view.css.background, view.css.color);
  475 + this.ctx.restore();
  476 + this._doBorder(view, width, height);
  477 + }
  478 +
  479 + _drawAbsImage(view) {
  480 + if (!view.url) {
  481 + return;
  482 + }
  483 + this.ctx.save();
  484 + const {
  485 + width,
  486 + height,
  487 + } = this._preProcess(view);
  488 + // 获得缩放到图片大小级别的裁减框
  489 + let rWidth = view.sWidth;
  490 + let rHeight = view.sHeight;
  491 + let startX = 0;
  492 + let startY = 0;
  493 + // 绘画区域比例
  494 + const cp = width / height;
  495 + // 原图比例
  496 + const op = view.sWidth / view.sHeight;
  497 + if (cp >= op) {
  498 + rHeight = rWidth / cp;
  499 + startY = Math.round((view.sHeight - rHeight) / 2);
  500 + } else {
  501 + rWidth = rHeight * cp;
  502 + startX = Math.round((view.sWidth - rWidth) / 2);
  503 + }
  504 + if (view.css && view.css.mode === 'scaleToFill') {
  505 + this.ctx.drawImage(view.url, -(width / 2), -(height / 2), width, height);
  506 + } else {
  507 + this.ctx.drawImage(view.url, startX, startY, rWidth, rHeight, -(width / 2), -(height / 2), width, height);
  508 + view.rect.startX = startX / view.sWidth;
  509 + view.rect.startY = startY / view.sHeight;
  510 + view.rect.endX = (startX + rWidth) / view.sWidth;
  511 + view.rect.endY = (startY + rHeight) / view.sHeight;
  512 + }
  513 + this.ctx.restore();
  514 + this._doBorder(view, width, height);
  515 + }
  516 +
  517 + callbackInfo = {}
  518 + _fillAbsText(view) {
  519 + if (!view.text) {
  520 + return;
  521 + }
  522 + if (view.css.background) {
  523 + // 生成背景
  524 + this._doBackground(view);
  525 + }
  526 + this.ctx.save();
  527 + const {
  528 + width,
  529 + height,
  530 + extra,
  531 + } = this._preProcess(view, view.css.background && view.css.borderRadius);
  532 + this.ctx.fillStyle = (view.css.color || 'black');
  533 + if (this.isMoving && JSON.stringify(this.movingCache) !== JSON.stringify({})) {
  534 + this.globalWidth[view.id] = this.movingCache.globalWidth
  535 + this.ctx.textAlign = view.css.textAlign ? view.css.textAlign : 'left';
  536 + for (const i of this.movingCache.lineArray) {
  537 + const {
  538 + measuredWith,
  539 + text,
  540 + x,
  541 + y,
  542 + textDecoration
  543 + } = i
  544 + if (view.css.textStyle === 'stroke') {
  545 + this.ctx.strokeText(text, x, y, measuredWith);
  546 + } else {
  547 + this.ctx.fillText(text, x, y, measuredWith);
  548 + }
  549 + if (textDecoration) {
  550 + const fontSize = view.css.fontSize.toPx();
  551 + this.ctx.lineWidth = fontSize / 13;
  552 + this.ctx.beginPath();
  553 + this.ctx.moveTo(...textDecoration.moveTo);
  554 + this.ctx.lineTo(...textDecoration.lineTo);
  555 + this.ctx.closePath();
  556 + this.ctx.strokeStyle = view.css.color;
  557 + this.ctx.stroke();
  558 + }
  559 + }
  560 + } else {
  561 + const {
  562 + lines,
  563 + lineHeight,
  564 + textArray,
  565 + linesArray,
  566 + } = extra;
  567 + // 如果设置了id,则保留 text 的长度
  568 + if (view.id) {
  569 + let textWidth = 0;
  570 + for (let i = 0; i < textArray.length; ++i) {
  571 + const _w = this.ctx.measureText(textArray[i]).width
  572 + textWidth = _w > textWidth ? _w : textWidth;
  573 + }
  574 + this.globalWidth[view.id] = width ? (textWidth < width ? textWidth : width) : textWidth;
  575 + if (!this.isMoving) {
  576 + Object.assign(this.callbackInfo, {
  577 + globalWidth: this.globalWidth[view.id]
  578 + })
  579 + }
  580 + }
  581 + let lineIndex = 0;
  582 + for (let j = 0; j < textArray.length; ++j) {
  583 + const preLineLength = Math.ceil(textArray[j].length / linesArray[j]);
  584 + let start = 0;
  585 + let alreadyCount = 0;
  586 +
  587 + for (let i = 0; i < linesArray[j]; ++i) {
  588 + // 绘制行数大于最大行数,则直接跳出循环
  589 + if (lineIndex >= lines) {
  590 + break;
  591 + }
  592 + alreadyCount = preLineLength;
  593 + let text = textArray[j].substr(start, alreadyCount);
  594 + let measuredWith = this.ctx.measureText(text).width;
  595 + // 如果测量大小小于width一个字符的大小,则进行补齐,如果测量大小超出 width,则进行减除
  596 + // 如果已经到文本末尾,也不要进行该循环
  597 + while ((start + alreadyCount <= textArray[j].length) && (width - measuredWith > view.css.fontSize.toPx() || measuredWith - width > view.css.fontSize.toPx())) {
  598 + if (measuredWith < width) {
  599 + text = textArray[j].substr(start, ++alreadyCount);
  600 + } else {
  601 + if (text.length <= 1) {
  602 + // 如果只有一个字符时,直接跳出循环
  603 + break;
  604 + }
  605 + text = textArray[j].substr(start, --alreadyCount);
  606 + // break;
  607 + }
  608 + measuredWith = this.ctx.measureText(text).width;
  609 + }
  610 + start += text.length
  611 + // 如果是最后一行了,发现还有未绘制完的内容,则加...
  612 + if (lineIndex === lines - 1 && (j < textArray.length - 1 || start < textArray[j].length)) {
  613 + while (this.ctx.measureText(`${text}...`).width > width) {
  614 + if (text.length <= 1) {
  615 + // 如果只有一个字符时,直接跳出循环
  616 + break;
  617 + }
  618 + text = text.substring(0, text.length - 1);
  619 + }
  620 + text += '...';
  621 + measuredWith = this.ctx.measureText(text).width;
  622 + }
  623 + this.ctx.textAlign = view.css.textAlign ? view.css.textAlign : 'left';
  624 + let x;
  625 + let lineX;
  626 + switch (view.css.textAlign) {
  627 + case 'center':
  628 + x = 0;
  629 + lineX = x - measuredWith / 2;
  630 + break;
  631 + case 'right':
  632 + x = (width / 2);
  633 + lineX = x - measuredWith;
  634 + break;
  635 + default:
  636 + x = -(width / 2);
  637 + lineX = x;
  638 + break;
  639 + }
  640 + const y = -(height / 2) + (lineIndex === 0 ? view.css.fontSize.toPx() : (view.css.fontSize.toPx() + lineIndex * lineHeight));
  641 + lineIndex++;
  642 + if (view.css.textStyle === 'stroke') {
  643 + this.ctx.strokeText(text, x, y, measuredWith);
  644 + } else {
  645 + this.ctx.fillText(text, x, y, measuredWith);
  646 + }
  647 + const fontSize = view.css.fontSize.toPx();
  648 + let textDecoration;
  649 + if (view.css.textDecoration) {
  650 + this.ctx.lineWidth = fontSize / 13;
  651 + this.ctx.beginPath();
  652 + if (/\bunderline\b/.test(view.css.textDecoration)) {
  653 + this.ctx.moveTo(lineX, y);
  654 + this.ctx.lineTo(lineX + measuredWith, y);
  655 + textDecoration = {
  656 + moveTo: [lineX, y],
  657 + lineTo: [lineX + measuredWith, y]
  658 + }
  659 + }
  660 + if (/\boverline\b/.test(view.css.textDecoration)) {
  661 + this.ctx.moveTo(lineX, y - fontSize);
  662 + this.ctx.lineTo(lineX + measuredWith, y - fontSize);
  663 + textDecoration = {
  664 + moveTo: [lineX, y - fontSize],
  665 + lineTo: [lineX + measuredWith, y - fontSize]
  666 + }
  667 + }
  668 + if (/\bline-through\b/.test(view.css.textDecoration)) {
  669 + this.ctx.moveTo(lineX, y - fontSize / 3);
  670 + this.ctx.lineTo(lineX + measuredWith, y - fontSize / 3);
  671 + textDecoration = {
  672 + moveTo: [lineX, y - fontSize / 3],
  673 + lineTo: [lineX + measuredWith, y - fontSize / 3]
  674 + }
  675 + }
  676 + this.ctx.closePath();
  677 + this.ctx.strokeStyle = view.css.color;
  678 + this.ctx.stroke();
  679 + }
  680 + if (!this.isMoving) {
  681 + this.callbackInfo.lineArray ? this.callbackInfo.lineArray.push({
  682 + text,
  683 + x,
  684 + y,
  685 + measuredWith,
  686 + textDecoration
  687 + }) : this.callbackInfo.lineArray = [{
  688 + text,
  689 + x,
  690 + y,
  691 + measuredWith,
  692 + textDecoration
  693 + }]
  694 + }
  695 + }
  696 + }
  697 + }
  698 + this.ctx.restore();
  699 + this._doBorder(view, width, height);
  700 + }
  701 +
  702 + _drawAbsRect(view) {
  703 + this.ctx.save();
  704 + const {
  705 + width,
  706 + height,
  707 + } = this._preProcess(view);
  708 + if (GD.api.isGradient(view.css.color)) {
  709 + GD.api.doGradient(view.css.color, width, height, this.ctx);
  710 + } else {
  711 + this.ctx.fillStyle = view.css.color;
  712 + }
  713 + const {
  714 + borderRadius,
  715 + borderStyle,
  716 + borderWidth
  717 + } = view.css
  718 + this._border({
  719 + borderRadius,
  720 + width,
  721 + height,
  722 + borderWidth,
  723 + borderStyle
  724 + })
  725 + this.ctx.fill();
  726 + this.ctx.restore();
  727 + this._doBorder(view, width, height);
  728 + }
  729 +
  730 + // shadow 支持 (x, y, blur, color), 不支持 spread
  731 + // shadow:0px 0px 10px rgba(0,0,0,0.1);
  732 + _doShadow(view) {
  733 + if (!view.css || !view.css.shadow) {
  734 + return;
  735 + }
  736 + const box = view.css.shadow.replace(/,\s+/g, ',').split(/\s+/);
  737 + if (box.length > 4) {
  738 + console.error('shadow don\'t spread option');
  739 + return;
  740 + }
  741 + this.ctx.shadowOffsetX = parseInt(box[0], 10);
  742 + this.ctx.shadowOffsetY = parseInt(box[1], 10);
  743 + this.ctx.shadowBlur = parseInt(box[2], 10);
  744 + this.ctx.shadowColor = box[3];
  745 + }
  746 +
  747 + _getAngle(angle) {
  748 + return Number(angle) * Math.PI / 180;
  749 + }
  750 +}
... ...
packageB/components/painter/lib/qrcode.js 0 → 100644
  1 +/* eslint-disable */
  2 +!(function () {
  3 +
  4 + // alignment pattern
  5 + var adelta = [
  6 + 0, 11, 15, 19, 23, 27, 31,
  7 + 16, 18, 20, 22, 24, 26, 28, 20, 22, 24, 24, 26, 28, 28, 22, 24, 24,
  8 + 26, 26, 28, 28, 24, 24, 26, 26, 26, 28, 28, 24, 26, 26, 26, 28, 28
  9 + ];
  10 +
  11 + // version block
  12 + var vpat = [
  13 + 0xc94, 0x5bc, 0xa99, 0x4d3, 0xbf6, 0x762, 0x847, 0x60d,
  14 + 0x928, 0xb78, 0x45d, 0xa17, 0x532, 0x9a6, 0x683, 0x8c9,
  15 + 0x7ec, 0xec4, 0x1e1, 0xfab, 0x08e, 0xc1a, 0x33f, 0xd75,
  16 + 0x250, 0x9d5, 0x6f0, 0x8ba, 0x79f, 0xb0b, 0x42e, 0xa64,
  17 + 0x541, 0xc69
  18 + ];
  19 +
  20 + // final format bits with mask: level << 3 | mask
  21 + var fmtword = [
  22 + 0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976, //L
  23 + 0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0, //M
  24 + 0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed, //Q
  25 + 0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b //H
  26 + ];
  27 +
  28 + // 4 per version: number of blocks 1,2; data width; ecc width
  29 + var eccblocks = [
  30 + 1, 0, 19, 7, 1, 0, 16, 10, 1, 0, 13, 13, 1, 0, 9, 17,
  31 + 1, 0, 34, 10, 1, 0, 28, 16, 1, 0, 22, 22, 1, 0, 16, 28,
  32 + 1, 0, 55, 15, 1, 0, 44, 26, 2, 0, 17, 18, 2, 0, 13, 22,
  33 + 1, 0, 80, 20, 2, 0, 32, 18, 2, 0, 24, 26, 4, 0, 9, 16,
  34 + 1, 0, 108, 26, 2, 0, 43, 24, 2, 2, 15, 18, 2, 2, 11, 22,
  35 + 2, 0, 68, 18, 4, 0, 27, 16, 4, 0, 19, 24, 4, 0, 15, 28,
  36 + 2, 0, 78, 20, 4, 0, 31, 18, 2, 4, 14, 18, 4, 1, 13, 26,
  37 + 2, 0, 97, 24, 2, 2, 38, 22, 4, 2, 18, 22, 4, 2, 14, 26,
  38 + 2, 0, 116, 30, 3, 2, 36, 22, 4, 4, 16, 20, 4, 4, 12, 24,
  39 + 2, 2, 68, 18, 4, 1, 43, 26, 6, 2, 19, 24, 6, 2, 15, 28,
  40 + 4, 0, 81, 20, 1, 4, 50, 30, 4, 4, 22, 28, 3, 8, 12, 24,
  41 + 2, 2, 92, 24, 6, 2, 36, 22, 4, 6, 20, 26, 7, 4, 14, 28,
  42 + 4, 0, 107, 26, 8, 1, 37, 22, 8, 4, 20, 24, 12, 4, 11, 22,
  43 + 3, 1, 115, 30, 4, 5, 40, 24, 11, 5, 16, 20, 11, 5, 12, 24,
  44 + 5, 1, 87, 22, 5, 5, 41, 24, 5, 7, 24, 30, 11, 7, 12, 24,
  45 + 5, 1, 98, 24, 7, 3, 45, 28, 15, 2, 19, 24, 3, 13, 15, 30,
  46 + 1, 5, 107, 28, 10, 1, 46, 28, 1, 15, 22, 28, 2, 17, 14, 28,
  47 + 5, 1, 120, 30, 9, 4, 43, 26, 17, 1, 22, 28, 2, 19, 14, 28,
  48 + 3, 4, 113, 28, 3, 11, 44, 26, 17, 4, 21, 26, 9, 16, 13, 26,
  49 + 3, 5, 107, 28, 3, 13, 41, 26, 15, 5, 24, 30, 15, 10, 15, 28,
  50 + 4, 4, 116, 28, 17, 0, 42, 26, 17, 6, 22, 28, 19, 6, 16, 30,
  51 + 2, 7, 111, 28, 17, 0, 46, 28, 7, 16, 24, 30, 34, 0, 13, 24,
  52 + 4, 5, 121, 30, 4, 14, 47, 28, 11, 14, 24, 30, 16, 14, 15, 30,
  53 + 6, 4, 117, 30, 6, 14, 45, 28, 11, 16, 24, 30, 30, 2, 16, 30,
  54 + 8, 4, 106, 26, 8, 13, 47, 28, 7, 22, 24, 30, 22, 13, 15, 30,
  55 + 10, 2, 114, 28, 19, 4, 46, 28, 28, 6, 22, 28, 33, 4, 16, 30,
  56 + 8, 4, 122, 30, 22, 3, 45, 28, 8, 26, 23, 30, 12, 28, 15, 30,
  57 + 3, 10, 117, 30, 3, 23, 45, 28, 4, 31, 24, 30, 11, 31, 15, 30,
  58 + 7, 7, 116, 30, 21, 7, 45, 28, 1, 37, 23, 30, 19, 26, 15, 30,
  59 + 5, 10, 115, 30, 19, 10, 47, 28, 15, 25, 24, 30, 23, 25, 15, 30,
  60 + 13, 3, 115, 30, 2, 29, 46, 28, 42, 1, 24, 30, 23, 28, 15, 30,
  61 + 17, 0, 115, 30, 10, 23, 46, 28, 10, 35, 24, 30, 19, 35, 15, 30,
  62 + 17, 1, 115, 30, 14, 21, 46, 28, 29, 19, 24, 30, 11, 46, 15, 30,
  63 + 13, 6, 115, 30, 14, 23, 46, 28, 44, 7, 24, 30, 59, 1, 16, 30,
  64 + 12, 7, 121, 30, 12, 26, 47, 28, 39, 14, 24, 30, 22, 41, 15, 30,
  65 + 6, 14, 121, 30, 6, 34, 47, 28, 46, 10, 24, 30, 2, 64, 15, 30,
  66 + 17, 4, 122, 30, 29, 14, 46, 28, 49, 10, 24, 30, 24, 46, 15, 30,
  67 + 4, 18, 122, 30, 13, 32, 46, 28, 48, 14, 24, 30, 42, 32, 15, 30,
  68 + 20, 4, 117, 30, 40, 7, 47, 28, 43, 22, 24, 30, 10, 67, 15, 30,
  69 + 19, 6, 118, 30, 18, 31, 47, 28, 34, 34, 24, 30, 20, 61, 15, 30
  70 + ];
  71 +
  72 + // Galois field log table
  73 + var glog = [
  74 + 0xff, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6, 0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
  75 + 0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81, 0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71,
  76 + 0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21, 0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
  77 + 0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9, 0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6,
  78 + 0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd, 0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88,
  79 + 0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd, 0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
  80 + 0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e, 0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d,
  81 + 0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b, 0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57,
  82 + 0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d, 0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
  83 + 0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c, 0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e,
  84 + 0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd, 0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61,
  85 + 0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e, 0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
  86 + 0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76, 0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6,
  87 + 0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa, 0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a,
  88 + 0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51, 0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
  89 + 0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8, 0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf
  90 + ];
  91 +
  92 + // Galios field exponent table
  93 + var gexp = [
  94 + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26,
  95 + 0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9, 0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
  96 + 0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35, 0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23,
  97 + 0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0, 0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1,
  98 + 0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc, 0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0,
  99 + 0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f, 0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2,
  100 + 0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88, 0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce,
  101 + 0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93, 0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc,
  102 + 0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9, 0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
  103 + 0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa, 0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73,
  104 + 0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e, 0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff,
  105 + 0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4, 0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41,
  106 + 0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6,
  107 + 0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef, 0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09,
  108 + 0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5, 0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16,
  109 + 0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, 0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x00
  110 + ];
  111 +
  112 + // Working buffers:
  113 + // data input and ecc append, image working buffer, fixed part of image, run lengths for badness
  114 + var strinbuf = [], eccbuf = [], qrframe = [], framask = [], rlens = [];
  115 + // Control values - width is based on version, last 4 are from table.
  116 + var version, width, neccblk1, neccblk2, datablkw, eccblkwid;
  117 + var ecclevel = 2;
  118 + // set bit to indicate cell in qrframe is immutable. symmetric around diagonal
  119 + function setmask(x, y) {
  120 + var bt;
  121 + if (x > y) {
  122 + bt = x;
  123 + x = y;
  124 + y = bt;
  125 + }
  126 + // y*y = 1+3+5...
  127 + bt = y;
  128 + bt *= y;
  129 + bt += y;
  130 + bt >>= 1;
  131 + bt += x;
  132 + framask[bt] = 1;
  133 + }
  134 +
  135 + // enter alignment pattern - black to qrframe, white to mask (later black frame merged to mask)
  136 + function putalign(x, y) {
  137 + var j;
  138 +
  139 + qrframe[x + width * y] = 1;
  140 + for (j = -2; j < 2; j++) {
  141 + qrframe[(x + j) + width * (y - 2)] = 1;
  142 + qrframe[(x - 2) + width * (y + j + 1)] = 1;
  143 + qrframe[(x + 2) + width * (y + j)] = 1;
  144 + qrframe[(x + j + 1) + width * (y + 2)] = 1;
  145 + }
  146 + for (j = 0; j < 2; j++) {
  147 + setmask(x - 1, y + j);
  148 + setmask(x + 1, y - j);
  149 + setmask(x - j, y - 1);
  150 + setmask(x + j, y + 1);
  151 + }
  152 + }
  153 +
  154 + //========================================================================
  155 + // Reed Solomon error correction
  156 + // exponentiation mod N
  157 + function modnn(x) {
  158 + while (x >= 255) {
  159 + x -= 255;
  160 + x = (x >> 8) + (x & 255);
  161 + }
  162 + return x;
  163 + }
  164 +
  165 + var genpoly = [];
  166 +
  167 + // Calculate and append ECC data to data block. Block is in strinbuf, indexes to buffers given.
  168 + function appendrs(data, dlen, ecbuf, eclen) {
  169 + var i, j, fb;
  170 +
  171 + for (i = 0; i < eclen; i++)
  172 + strinbuf[ecbuf + i] = 0;
  173 + for (i = 0; i < dlen; i++) {
  174 + fb = glog[strinbuf[data + i] ^ strinbuf[ecbuf]];
  175 + if (fb != 255) /* fb term is non-zero */
  176 + for (j = 1; j < eclen; j++)
  177 + strinbuf[ecbuf + j - 1] = strinbuf[ecbuf + j] ^ gexp[modnn(fb + genpoly[eclen - j])];
  178 + else
  179 + for (j = ecbuf; j < ecbuf + eclen; j++)
  180 + strinbuf[j] = strinbuf[j + 1];
  181 + strinbuf[ecbuf + eclen - 1] = fb == 255 ? 0 : gexp[modnn(fb + genpoly[0])];
  182 + }
  183 + }
  184 +
  185 + //========================================================================
  186 + // Frame data insert following the path rules
  187 +
  188 + // check mask - since symmetrical use half.
  189 + function ismasked(x, y) {
  190 + var bt;
  191 + if (x > y) {
  192 + bt = x;
  193 + x = y;
  194 + y = bt;
  195 + }
  196 + bt = y;
  197 + bt += y * y;
  198 + bt >>= 1;
  199 + bt += x;
  200 + return framask[bt];
  201 + }
  202 +
  203 + //========================================================================
  204 + // Apply the selected mask out of the 8.
  205 + function applymask(m) {
  206 + var x, y, r3x, r3y;
  207 +
  208 + switch (m) {
  209 + case 0:
  210 + for (y = 0; y < width; y++)
  211 + for (x = 0; x < width; x++)
  212 + if (!((x + y) & 1) && !ismasked(x, y))
  213 + qrframe[x + y * width] ^= 1;
  214 + break;
  215 + case 1:
  216 + for (y = 0; y < width; y++)
  217 + for (x = 0; x < width; x++)
  218 + if (!(y & 1) && !ismasked(x, y))
  219 + qrframe[x + y * width] ^= 1;
  220 + break;
  221 + case 2:
  222 + for (y = 0; y < width; y++)
  223 + for (r3x = 0, x = 0; x < width; x++ , r3x++) {
  224 + if (r3x == 3)
  225 + r3x = 0;
  226 + if (!r3x && !ismasked(x, y))
  227 + qrframe[x + y * width] ^= 1;
  228 + }
  229 + break;
  230 + case 3:
  231 + for (r3y = 0, y = 0; y < width; y++ , r3y++) {
  232 + if (r3y == 3)
  233 + r3y = 0;
  234 + for (r3x = r3y, x = 0; x < width; x++ , r3x++) {
  235 + if (r3x == 3)
  236 + r3x = 0;
  237 + if (!r3x && !ismasked(x, y))
  238 + qrframe[x + y * width] ^= 1;
  239 + }
  240 + }
  241 + break;
  242 + case 4:
  243 + for (y = 0; y < width; y++)
  244 + for (r3x = 0, r3y = ((y >> 1) & 1), x = 0; x < width; x++ , r3x++) {
  245 + if (r3x == 3) {
  246 + r3x = 0;
  247 + r3y = !r3y;
  248 + }
  249 + if (!r3y && !ismasked(x, y))
  250 + qrframe[x + y * width] ^= 1;
  251 + }
  252 + break;
  253 + case 5:
  254 + for (r3y = 0, y = 0; y < width; y++ , r3y++) {
  255 + if (r3y == 3)
  256 + r3y = 0;
  257 + for (r3x = 0, x = 0; x < width; x++ , r3x++) {
  258 + if (r3x == 3)
  259 + r3x = 0;
  260 + if (!((x & y & 1) + !(!r3x | !r3y)) && !ismasked(x, y))
  261 + qrframe[x + y * width] ^= 1;
  262 + }
  263 + }
  264 + break;
  265 + case 6:
  266 + for (r3y = 0, y = 0; y < width; y++ , r3y++) {
  267 + if (r3y == 3)
  268 + r3y = 0;
  269 + for (r3x = 0, x = 0; x < width; x++ , r3x++) {
  270 + if (r3x == 3)
  271 + r3x = 0;
  272 + if (!(((x & y & 1) + (r3x && (r3x == r3y))) & 1) && !ismasked(x, y))
  273 + qrframe[x + y * width] ^= 1;
  274 + }
  275 + }
  276 + break;
  277 + case 7:
  278 + for (r3y = 0, y = 0; y < width; y++ , r3y++) {
  279 + if (r3y == 3)
  280 + r3y = 0;
  281 + for (r3x = 0, x = 0; x < width; x++ , r3x++) {
  282 + if (r3x == 3)
  283 + r3x = 0;
  284 + if (!(((r3x && (r3x == r3y)) + ((x + y) & 1)) & 1) && !ismasked(x, y))
  285 + qrframe[x + y * width] ^= 1;
  286 + }
  287 + }
  288 + break;
  289 + }
  290 + return;
  291 + }
  292 +
  293 + // Badness coefficients.
  294 + var N1 = 3, N2 = 3, N3 = 40, N4 = 10;
  295 +
  296 + // Using the table of the length of each run, calculate the amount of bad image
  297 + // - long runs or those that look like finders; called twice, once each for X and Y
  298 + function badruns(length) {
  299 + var i;
  300 + var runsbad = 0;
  301 + for (i = 0; i <= length; i++)
  302 + if (rlens[i] >= 5)
  303 + runsbad += N1 + rlens[i] - 5;
  304 + // BwBBBwB as in finder
  305 + for (i = 3; i < length - 1; i += 2)
  306 + if (rlens[i - 2] == rlens[i + 2]
  307 + && rlens[i + 2] == rlens[i - 1]
  308 + && rlens[i - 1] == rlens[i + 1]
  309 + && rlens[i - 1] * 3 == rlens[i]
  310 + // white around the black pattern? Not part of spec
  311 + && (rlens[i - 3] == 0 // beginning
  312 + || i + 3 > length // end
  313 + || rlens[i - 3] * 3 >= rlens[i] * 4 || rlens[i + 3] * 3 >= rlens[i] * 4)
  314 + )
  315 + runsbad += N3;
  316 + return runsbad;
  317 + }
  318 +
  319 + // Calculate how bad the masked image is - blocks, imbalance, runs, or finders.
  320 + function badcheck() {
  321 + var x, y, h, b, b1;
  322 + var thisbad = 0;
  323 + var bw = 0;
  324 +
  325 + // blocks of same color.
  326 + for (y = 0; y < width - 1; y++)
  327 + for (x = 0; x < width - 1; x++)
  328 + if ((qrframe[x + width * y] && qrframe[(x + 1) + width * y]
  329 + && qrframe[x + width * (y + 1)] && qrframe[(x + 1) + width * (y + 1)]) // all black
  330 + || !(qrframe[x + width * y] || qrframe[(x + 1) + width * y]
  331 + || qrframe[x + width * (y + 1)] || qrframe[(x + 1) + width * (y + 1)])) // all white
  332 + thisbad += N2;
  333 +
  334 + // X runs
  335 + for (y = 0; y < width; y++) {
  336 + rlens[0] = 0;
  337 + for (h = b = x = 0; x < width; x++) {
  338 + if ((b1 = qrframe[x + width * y]) == b)
  339 + rlens[h]++;
  340 + else
  341 + rlens[++h] = 1;
  342 + b = b1;
  343 + bw += b ? 1 : -1;
  344 + }
  345 + thisbad += badruns(h);
  346 + }
  347 +
  348 + // black/white imbalance
  349 + if (bw < 0)
  350 + bw = -bw;
  351 +
  352 + var big = bw;
  353 + var count = 0;
  354 + big += big << 2;
  355 + big <<= 1;
  356 + while (big > width * width)
  357 + big -= width * width, count++;
  358 + thisbad += count * N4;
  359 +
  360 + // Y runs
  361 + for (x = 0; x < width; x++) {
  362 + rlens[0] = 0;
  363 + for (h = b = y = 0; y < width; y++) {
  364 + if ((b1 = qrframe[x + width * y]) == b)
  365 + rlens[h]++;
  366 + else
  367 + rlens[++h] = 1;
  368 + b = b1;
  369 + }
  370 + thisbad += badruns(h);
  371 + }
  372 + return thisbad;
  373 + }
  374 +
  375 + function genframe(instring) {
  376 + var x, y, k, t, v, i, j, m;
  377 +
  378 + // find the smallest version that fits the string
  379 + t = instring.length;
  380 + version = 0;
  381 + do {
  382 + version++;
  383 + k = (ecclevel - 1) * 4 + (version - 1) * 16;
  384 + neccblk1 = eccblocks[k++];
  385 + neccblk2 = eccblocks[k++];
  386 + datablkw = eccblocks[k++];
  387 + eccblkwid = eccblocks[k];
  388 + k = datablkw * (neccblk1 + neccblk2) + neccblk2 - 3 + (version <= 9);
  389 + if (t <= k)
  390 + break;
  391 + } while (version < 40);
  392 +
  393 + // FIXME - insure that it fits insted of being truncated
  394 + width = 17 + 4 * version;
  395 +
  396 + // allocate, clear and setup data structures
  397 + v = datablkw + (datablkw + eccblkwid) * (neccblk1 + neccblk2) + neccblk2;
  398 + for (t = 0; t < v; t++)
  399 + eccbuf[t] = 0;
  400 + strinbuf = instring.slice(0);
  401 +
  402 + for (t = 0; t < width * width; t++)
  403 + qrframe[t] = 0;
  404 +
  405 + for (t = 0; t < (width * (width + 1) + 1) / 2; t++)
  406 + framask[t] = 0;
  407 +
  408 + // insert finders - black to frame, white to mask
  409 + for (t = 0; t < 3; t++) {
  410 + k = 0;
  411 + y = 0;
  412 + if (t == 1)
  413 + k = (width - 7);
  414 + if (t == 2)
  415 + y = (width - 7);
  416 + qrframe[(y + 3) + width * (k + 3)] = 1;
  417 + for (x = 0; x < 6; x++) {
  418 + qrframe[(y + x) + width * k] = 1;
  419 + qrframe[y + width * (k + x + 1)] = 1;
  420 + qrframe[(y + 6) + width * (k + x)] = 1;
  421 + qrframe[(y + x + 1) + width * (k + 6)] = 1;
  422 + }
  423 + for (x = 1; x < 5; x++) {
  424 + setmask(y + x, k + 1);
  425 + setmask(y + 1, k + x + 1);
  426 + setmask(y + 5, k + x);
  427 + setmask(y + x + 1, k + 5);
  428 + }
  429 + for (x = 2; x < 4; x++) {
  430 + qrframe[(y + x) + width * (k + 2)] = 1;
  431 + qrframe[(y + 2) + width * (k + x + 1)] = 1;
  432 + qrframe[(y + 4) + width * (k + x)] = 1;
  433 + qrframe[(y + x + 1) + width * (k + 4)] = 1;
  434 + }
  435 + }
  436 +
  437 + // alignment blocks
  438 + if (version > 1) {
  439 + t = adelta[version];
  440 + y = width - 7;
  441 + for (; ;) {
  442 + x = width - 7;
  443 + while (x > t - 3) {
  444 + putalign(x, y);
  445 + if (x < t)
  446 + break;
  447 + x -= t;
  448 + }
  449 + if (y <= t + 9)
  450 + break;
  451 + y -= t;
  452 + putalign(6, y);
  453 + putalign(y, 6);
  454 + }
  455 + }
  456 +
  457 + // single black
  458 + qrframe[8 + width * (width - 8)] = 1;
  459 +
  460 + // timing gap - mask only
  461 + for (y = 0; y < 7; y++) {
  462 + setmask(7, y);
  463 + setmask(width - 8, y);
  464 + setmask(7, y + width - 7);
  465 + }
  466 + for (x = 0; x < 8; x++) {
  467 + setmask(x, 7);
  468 + setmask(x + width - 8, 7);
  469 + setmask(x, width - 8);
  470 + }
  471 +
  472 + // reserve mask-format area
  473 + for (x = 0; x < 9; x++)
  474 + setmask(x, 8);
  475 + for (x = 0; x < 8; x++) {
  476 + setmask(x + width - 8, 8);
  477 + setmask(8, x);
  478 + }
  479 + for (y = 0; y < 7; y++)
  480 + setmask(8, y + width - 7);
  481 +
  482 + // timing row/col
  483 + for (x = 0; x < width - 14; x++)
  484 + if (x & 1) {
  485 + setmask(8 + x, 6);
  486 + setmask(6, 8 + x);
  487 + }
  488 + else {
  489 + qrframe[(8 + x) + width * 6] = 1;
  490 + qrframe[6 + width * (8 + x)] = 1;
  491 + }
  492 +
  493 + // version block
  494 + if (version > 6) {
  495 + t = vpat[version - 7];
  496 + k = 17;
  497 + for (x = 0; x < 6; x++)
  498 + for (y = 0; y < 3; y++ , k--)
  499 + if (1 & (k > 11 ? version >> (k - 12) : t >> k)) {
  500 + qrframe[(5 - x) + width * (2 - y + width - 11)] = 1;
  501 + qrframe[(2 - y + width - 11) + width * (5 - x)] = 1;
  502 + }
  503 + else {
  504 + setmask(5 - x, 2 - y + width - 11);
  505 + setmask(2 - y + width - 11, 5 - x);
  506 + }
  507 + }
  508 +
  509 + // sync mask bits - only set above for white spaces, so add in black bits
  510 + for (y = 0; y < width; y++)
  511 + for (x = 0; x <= y; x++)
  512 + if (qrframe[x + width * y])
  513 + setmask(x, y);
  514 +
  515 + // convert string to bitstream
  516 + // 8 bit data to QR-coded 8 bit data (numeric or alphanum, or kanji not supported)
  517 + v = strinbuf.length;
  518 +
  519 + // string to array
  520 + for (i = 0; i < v; i++)
  521 + eccbuf[i] = strinbuf.charCodeAt(i);
  522 + strinbuf = eccbuf.slice(0);
  523 +
  524 + // calculate max string length
  525 + x = datablkw * (neccblk1 + neccblk2) + neccblk2;
  526 + if (v >= x - 2) {
  527 + v = x - 2;
  528 + if (version > 9)
  529 + v--;
  530 + }
  531 +
  532 + // shift and repack to insert length prefix
  533 + i = v;
  534 + if (version > 9) {
  535 + strinbuf[i + 2] = 0;
  536 + strinbuf[i + 3] = 0;
  537 + while (i--) {
  538 + t = strinbuf[i];
  539 + strinbuf[i + 3] |= 255 & (t << 4);
  540 + strinbuf[i + 2] = t >> 4;
  541 + }
  542 + strinbuf[2] |= 255 & (v << 4);
  543 + strinbuf[1] = v >> 4;
  544 + strinbuf[0] = 0x40 | (v >> 12);
  545 + }
  546 + else {
  547 + strinbuf[i + 1] = 0;
  548 + strinbuf[i + 2] = 0;
  549 + while (i--) {
  550 + t = strinbuf[i];
  551 + strinbuf[i + 2] |= 255 & (t << 4);
  552 + strinbuf[i + 1] = t >> 4;
  553 + }
  554 + strinbuf[1] |= 255 & (v << 4);
  555 + strinbuf[0] = 0x40 | (v >> 4);
  556 + }
  557 + // fill to end with pad pattern
  558 + i = v + 3 - (version < 10);
  559 + while (i < x) {
  560 + strinbuf[i++] = 0xec;
  561 + // buffer has room if (i == x) break;
  562 + strinbuf[i++] = 0x11;
  563 + }
  564 +
  565 + // calculate and append ECC
  566 +
  567 + // calculate generator polynomial
  568 + genpoly[0] = 1;
  569 + for (i = 0; i < eccblkwid; i++) {
  570 + genpoly[i + 1] = 1;
  571 + for (j = i; j > 0; j--)
  572 + genpoly[j] = genpoly[j]
  573 + ? genpoly[j - 1] ^ gexp[modnn(glog[genpoly[j]] + i)] : genpoly[j - 1];
  574 + genpoly[0] = gexp[modnn(glog[genpoly[0]] + i)];
  575 + }
  576 + for (i = 0; i <= eccblkwid; i++)
  577 + genpoly[i] = glog[genpoly[i]]; // use logs for genpoly[] to save calc step
  578 +
  579 + // append ecc to data buffer
  580 + k = x;
  581 + y = 0;
  582 + for (i = 0; i < neccblk1; i++) {
  583 + appendrs(y, datablkw, k, eccblkwid);
  584 + y += datablkw;
  585 + k += eccblkwid;
  586 + }
  587 + for (i = 0; i < neccblk2; i++) {
  588 + appendrs(y, datablkw + 1, k, eccblkwid);
  589 + y += datablkw + 1;
  590 + k += eccblkwid;
  591 + }
  592 + // interleave blocks
  593 + y = 0;
  594 + for (i = 0; i < datablkw; i++) {
  595 + for (j = 0; j < neccblk1; j++)
  596 + eccbuf[y++] = strinbuf[i + j * datablkw];
  597 + for (j = 0; j < neccblk2; j++)
  598 + eccbuf[y++] = strinbuf[(neccblk1 * datablkw) + i + (j * (datablkw + 1))];
  599 + }
  600 + for (j = 0; j < neccblk2; j++)
  601 + eccbuf[y++] = strinbuf[(neccblk1 * datablkw) + i + (j * (datablkw + 1))];
  602 + for (i = 0; i < eccblkwid; i++)
  603 + for (j = 0; j < neccblk1 + neccblk2; j++)
  604 + eccbuf[y++] = strinbuf[x + i + j * eccblkwid];
  605 + strinbuf = eccbuf;
  606 +
  607 + // pack bits into frame avoiding masked area.
  608 + x = y = width - 1;
  609 + k = v = 1; // up, minus
  610 + /* inteleaved data and ecc codes */
  611 + m = (datablkw + eccblkwid) * (neccblk1 + neccblk2) + neccblk2;
  612 + for (i = 0; i < m; i++) {
  613 + t = strinbuf[i];
  614 + for (j = 0; j < 8; j++ , t <<= 1) {
  615 + if (0x80 & t)
  616 + qrframe[x + width * y] = 1;
  617 + do { // find next fill position
  618 + if (v)
  619 + x--;
  620 + else {
  621 + x++;
  622 + if (k) {
  623 + if (y != 0)
  624 + y--;
  625 + else {
  626 + x -= 2;
  627 + k = !k;
  628 + if (x == 6) {
  629 + x--;
  630 + y = 9;
  631 + }
  632 + }
  633 + }
  634 + else {
  635 + if (y != width - 1)
  636 + y++;
  637 + else {
  638 + x -= 2;
  639 + k = !k;
  640 + if (x == 6) {
  641 + x--;
  642 + y -= 8;
  643 + }
  644 + }
  645 + }
  646 + }
  647 + v = !v;
  648 + } while (ismasked(x, y));
  649 + }
  650 + }
  651 +
  652 + // save pre-mask copy of frame
  653 + strinbuf = qrframe.slice(0);
  654 + t = 0; // best
  655 + y = 30000; // demerit
  656 + // for instead of while since in original arduino code
  657 + // if an early mask was "good enough" it wouldn't try for a better one
  658 + // since they get more complex and take longer.
  659 + for (k = 0; k < 8; k++) {
  660 + applymask(k); // returns black-white imbalance
  661 + x = badcheck();
  662 + if (x < y) { // current mask better than previous best?
  663 + y = x;
  664 + t = k;
  665 + }
  666 + if (t == 7)
  667 + break; // don't increment i to a void redoing mask
  668 + qrframe = strinbuf.slice(0); // reset for next pass
  669 + }
  670 + if (t != k) // redo best mask - none good enough, last wasn't t
  671 + applymask(t);
  672 +
  673 + // add in final mask/ecclevel bytes
  674 + y = fmtword[t + ((ecclevel - 1) << 3)];
  675 + // low byte
  676 + for (k = 0; k < 8; k++ , y >>= 1)
  677 + if (y & 1) {
  678 + qrframe[(width - 1 - k) + width * 8] = 1;
  679 + if (k < 6)
  680 + qrframe[8 + width * k] = 1;
  681 + else
  682 + qrframe[8 + width * (k + 1)] = 1;
  683 + }
  684 + // high byte
  685 + for (k = 0; k < 7; k++ , y >>= 1)
  686 + if (y & 1) {
  687 + qrframe[8 + width * (width - 7 + k)] = 1;
  688 + if (k)
  689 + qrframe[(6 - k) + width * 8] = 1;
  690 + else
  691 + qrframe[7 + width * 8] = 1;
  692 + }
  693 + return qrframe;
  694 + }
  695 +
  696 +
  697 +
  698 +
  699 + var _canvas = null;
  700 +
  701 + var api = {
  702 +
  703 + get ecclevel() {
  704 + return ecclevel;
  705 + },
  706 +
  707 + set ecclevel(val) {
  708 + ecclevel = val;
  709 + },
  710 +
  711 + get size() {
  712 + return _size;
  713 + },
  714 +
  715 + set size(val) {
  716 + _size = val
  717 + },
  718 +
  719 + get canvas() {
  720 + return _canvas;
  721 + },
  722 +
  723 + set canvas(el) {
  724 + _canvas = el;
  725 + },
  726 +
  727 + getFrame: function (string) {
  728 + return genframe(string);
  729 + },
  730 + //这里的utf16to8(str)是对Text中的字符串进行转码,让其支持中文
  731 + utf16to8: function (str) {
  732 + var out, i, len, c;
  733 +
  734 + out = "";
  735 + len = str.length;
  736 + for (i = 0; i < len; i++) {
  737 + c = str.charCodeAt(i);
  738 + if ((c >= 0x0001) && (c <= 0x007F)) {
  739 + out += str.charAt(i);
  740 + } else if (c > 0x07FF) {
  741 + out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
  742 + out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
  743 + out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
  744 + } else {
  745 + out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
  746 + out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
  747 + }
  748 + }
  749 + return out;
  750 + },
  751 + /**
  752 + * 新增$this参数,传入组件的this,兼容在组件中生成
  753 + * @param bg 目前只能设置颜色值
  754 + */
  755 + draw: function (str, ctx, startX, startY, cavW, cavH, bg, color, $this, ecc) {
  756 + var that = this;
  757 + ecclevel = ecc || ecclevel;
  758 + if (!ctx) {
  759 + console.warn('No canvas provided to draw QR code in!')
  760 + return;
  761 + }
  762 + var size = Math.min(cavW, cavH);
  763 + str = that.utf16to8(str);//增加中文显示
  764 +
  765 + var frame = that.getFrame(str);
  766 + var px = size / width;
  767 + if (bg) {
  768 + ctx.fillStyle = bg;
  769 + ctx.fillRect(startX, startY, cavW, cavW);
  770 + }
  771 + ctx.fillStyle = color || 'black';
  772 + for (var i = 0; i < width; i++) {
  773 + for (var j = 0; j < width; j++) {
  774 + if (frame[j * width + i]) {
  775 + ctx.fillRect(startX + px * i, startY + px * j, px, px);
  776 + }
  777 + }
  778 + }
  779 + }
  780 + }
  781 + module.exports = { api }
  782 + // exports.draw = api;
  783 +
  784 +})();
0 785 \ No newline at end of file
... ...
packageB/components/painter/lib/util.js 0 → 100644
  1 +
  2 +function isValidUrl(url) {
  3 + return /(ht|f)tp(s?):\/\/([^ \\/]*\.)+[^ \\/]*(:[0-9]+)?\/?/.test(url);
  4 +}
  5 +
  6 +/**
  7 + * 深度对比两个对象是否一致
  8 + * from: https://github.com/epoberezkin/fast-deep-equal
  9 + * @param {Object} a 对象a
  10 + * @param {Object} b 对象b
  11 + * @return {Boolean} 是否相同
  12 + */
  13 +/* eslint-disable */
  14 +function equal(a, b) {
  15 + if (a === b) return true;
  16 +
  17 + if (a && b && typeof a == 'object' && typeof b == 'object') {
  18 + var arrA = Array.isArray(a)
  19 + , arrB = Array.isArray(b)
  20 + , i
  21 + , length
  22 + , key;
  23 +
  24 + if (arrA && arrB) {
  25 + length = a.length;
  26 + if (length != b.length) return false;
  27 + for (i = length; i-- !== 0;)
  28 + if (!equal(a[i], b[i])) return false;
  29 + return true;
  30 + }
  31 +
  32 + if (arrA != arrB) return false;
  33 +
  34 + var dateA = a instanceof Date
  35 + , dateB = b instanceof Date;
  36 + if (dateA != dateB) return false;
  37 + if (dateA && dateB) return a.getTime() == b.getTime();
  38 +
  39 + var regexpA = a instanceof RegExp
  40 + , regexpB = b instanceof RegExp;
  41 + if (regexpA != regexpB) return false;
  42 + if (regexpA && regexpB) return a.toString() == b.toString();
  43 +
  44 + var keys = Object.keys(a);
  45 + length = keys.length;
  46 +
  47 + if (length !== Object.keys(b).length)
  48 + return false;
  49 +
  50 + for (i = length; i-- !== 0;)
  51 + if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;
  52 +
  53 + for (i = length; i-- !== 0;) {
  54 + key = keys[i];
  55 + if (!equal(a[key], b[key])) return false;
  56 + }
  57 +
  58 + return true;
  59 + }
  60 +
  61 + return a!==a && b!==b;
  62 +}
  63 +
  64 +module.exports = {
  65 + isValidUrl,
  66 + equal
  67 +};
  68 +
... ...
packageB/components/painter/lib/wx-canvas.js 0 → 100644
  1 +// @ts-check
  2 +export default class WxCanvas {
  3 + ctx;
  4 + type;
  5 + canvasId;
  6 + canvasNode;
  7 + stepList = [];
  8 + canvasPrototype = {};
  9 +
  10 + constructor(type, ctx, canvasId, isNew, canvasNode) {
  11 + this.ctx = ctx;
  12 + this.canvasId = canvasId;
  13 + this.type = type;
  14 + if (isNew) {
  15 + this.canvasNode = canvasNode || {};
  16 + }
  17 + }
  18 +
  19 + set width(w) {
  20 + if (this.canvasNode) this.canvasNode.width = w;
  21 + }
  22 +
  23 + get width() {
  24 + if (this.canvasNode) return this.canvasNode.width;
  25 + return 0;
  26 + }
  27 +
  28 + set height(h) {
  29 + if (this.canvasNode) this.canvasNode.height = h;
  30 + }
  31 +
  32 + get height() {
  33 + if (this.canvasNode) return this.canvasNode.height;
  34 + return 0;
  35 + }
  36 +
  37 + set lineWidth(args) {
  38 + this.canvasPrototype.lineWidth = args;
  39 + this.stepList.push({
  40 + action: "lineWidth",
  41 + args,
  42 + actionType: "set",
  43 + });
  44 + }
  45 +
  46 + get lineWidth() {
  47 + return this.canvasPrototype.lineWidth;
  48 + }
  49 +
  50 + set lineCap(args) {
  51 + this.canvasPrototype.lineCap = args;
  52 + this.stepList.push({
  53 + action: "lineCap",
  54 + args,
  55 + actionType: "set",
  56 + });
  57 + }
  58 +
  59 + get lineCap() {
  60 + return this.canvasPrototype.lineCap;
  61 + }
  62 +
  63 + set lineJoin(args) {
  64 + this.canvasPrototype.lineJoin = args;
  65 + this.stepList.push({
  66 + action: "lineJoin",
  67 + args,
  68 + actionType: "set",
  69 + });
  70 + }
  71 +
  72 + get lineJoin() {
  73 + return this.canvasPrototype.lineJoin;
  74 + }
  75 +
  76 + set miterLimit(args) {
  77 + this.canvasPrototype.miterLimit = args;
  78 + this.stepList.push({
  79 + action: "miterLimit",
  80 + args,
  81 + actionType: "set",
  82 + });
  83 + }
  84 +
  85 + get miterLimit() {
  86 + return this.canvasPrototype.miterLimit;
  87 + }
  88 +
  89 + set lineDashOffset(args) {
  90 + this.canvasPrototype.lineDashOffset = args;
  91 + this.stepList.push({
  92 + action: "lineDashOffset",
  93 + args,
  94 + actionType: "set",
  95 + });
  96 + }
  97 +
  98 + get lineDashOffset() {
  99 + return this.canvasPrototype.lineDashOffset;
  100 + }
  101 +
  102 + set font(args) {
  103 + this.canvasPrototype.font = args;
  104 + this.ctx.font = args;
  105 + this.stepList.push({
  106 + action: "font",
  107 + args,
  108 + actionType: "set",
  109 + });
  110 + }
  111 +
  112 + get font() {
  113 + return this.canvasPrototype.font;
  114 + }
  115 +
  116 + set textAlign(args) {
  117 + this.canvasPrototype.textAlign = args;
  118 + this.stepList.push({
  119 + action: "textAlign",
  120 + args,
  121 + actionType: "set",
  122 + });
  123 + }
  124 +
  125 + get textAlign() {
  126 + return this.canvasPrototype.textAlign;
  127 + }
  128 +
  129 + set textBaseline(args) {
  130 + this.canvasPrototype.textBaseline = args;
  131 + this.stepList.push({
  132 + action: "textBaseline",
  133 + args,
  134 + actionType: "set",
  135 + });
  136 + }
  137 +
  138 + get textBaseline() {
  139 + return this.canvasPrototype.textBaseline;
  140 + }
  141 +
  142 + set fillStyle(args) {
  143 + this.canvasPrototype.fillStyle = args;
  144 + this.stepList.push({
  145 + action: "fillStyle",
  146 + args,
  147 + actionType: "set",
  148 + });
  149 + }
  150 +
  151 + get fillStyle() {
  152 + return this.canvasPrototype.fillStyle;
  153 + }
  154 +
  155 + set strokeStyle(args) {
  156 + this.canvasPrototype.strokeStyle = args;
  157 + this.stepList.push({
  158 + action: "strokeStyle",
  159 + args,
  160 + actionType: "set",
  161 + });
  162 + }
  163 +
  164 + get strokeStyle() {
  165 + return this.canvasPrototype.strokeStyle;
  166 + }
  167 +
  168 + set globalAlpha(args) {
  169 + this.canvasPrototype.globalAlpha = args;
  170 + this.stepList.push({
  171 + action: "globalAlpha",
  172 + args,
  173 + actionType: "set",
  174 + });
  175 + }
  176 +
  177 + get globalAlpha() {
  178 + return this.canvasPrototype.globalAlpha;
  179 + }
  180 +
  181 + set globalCompositeOperation(args) {
  182 + this.canvasPrototype.globalCompositeOperation = args;
  183 + this.stepList.push({
  184 + action: "globalCompositeOperation",
  185 + args,
  186 + actionType: "set",
  187 + });
  188 + }
  189 +
  190 + get globalCompositeOperation() {
  191 + return this.canvasPrototype.globalCompositeOperation;
  192 + }
  193 +
  194 + set shadowColor(args) {
  195 + this.canvasPrototype.shadowColor = args;
  196 + this.stepList.push({
  197 + action: "shadowColor",
  198 + args,
  199 + actionType: "set",
  200 + });
  201 + }
  202 +
  203 + get shadowColor() {
  204 + return this.canvasPrototype.shadowColor;
  205 + }
  206 +
  207 + set shadowOffsetX(args) {
  208 + this.canvasPrototype.shadowOffsetX = args;
  209 + this.stepList.push({
  210 + action: "shadowOffsetX",
  211 + args,
  212 + actionType: "set",
  213 + });
  214 + }
  215 +
  216 + get shadowOffsetX() {
  217 + return this.canvasPrototype.shadowOffsetX;
  218 + }
  219 +
  220 + set shadowOffsetY(args) {
  221 + this.canvasPrototype.shadowOffsetY = args;
  222 + this.stepList.push({
  223 + action: "shadowOffsetY",
  224 + args,
  225 + actionType: "set",
  226 + });
  227 + }
  228 +
  229 + get shadowOffsetY() {
  230 + return this.canvasPrototype.shadowOffsetY;
  231 + }
  232 +
  233 + set shadowBlur(args) {
  234 + this.canvasPrototype.shadowBlur = args;
  235 + this.stepList.push({
  236 + action: "shadowBlur",
  237 + args,
  238 + actionType: "set",
  239 + });
  240 + }
  241 +
  242 + get shadowBlur() {
  243 + return this.canvasPrototype.shadowBlur;
  244 + }
  245 +
  246 + save() {
  247 + this.stepList.push({
  248 + action: "save",
  249 + args: null,
  250 + actionType: "func",
  251 + });
  252 + }
  253 +
  254 + restore() {
  255 + this.stepList.push({
  256 + action: "restore",
  257 + args: null,
  258 + actionType: "func",
  259 + });
  260 + }
  261 +
  262 + setLineDash(...args) {
  263 + this.canvasPrototype.lineDash = args;
  264 + this.stepList.push({
  265 + action: "setLineDash",
  266 + args,
  267 + actionType: "func",
  268 + });
  269 + }
  270 +
  271 + moveTo(...args) {
  272 + this.stepList.push({
  273 + action: "moveTo",
  274 + args,
  275 + actionType: "func",
  276 + });
  277 + }
  278 +
  279 + closePath() {
  280 + this.stepList.push({
  281 + action: "closePath",
  282 + args: null,
  283 + actionType: "func",
  284 + });
  285 + }
  286 +
  287 + lineTo(...args) {
  288 + this.stepList.push({
  289 + action: "lineTo",
  290 + args,
  291 + actionType: "func",
  292 + });
  293 + }
  294 +
  295 + quadraticCurveTo(...args) {
  296 + this.stepList.push({
  297 + action: "quadraticCurveTo",
  298 + args,
  299 + actionType: "func",
  300 + });
  301 + }
  302 +
  303 + bezierCurveTo(...args) {
  304 + this.stepList.push({
  305 + action: "bezierCurveTo",
  306 + args,
  307 + actionType: "func",
  308 + });
  309 + }
  310 +
  311 + arcTo(...args) {
  312 + this.stepList.push({
  313 + action: "arcTo",
  314 + args,
  315 + actionType: "func",
  316 + });
  317 + }
  318 +
  319 + arc(...args) {
  320 + this.stepList.push({
  321 + action: "arc",
  322 + args,
  323 + actionType: "func",
  324 + });
  325 + }
  326 +
  327 + rect(...args) {
  328 + this.stepList.push({
  329 + action: "rect",
  330 + args,
  331 + actionType: "func",
  332 + });
  333 + }
  334 +
  335 + scale(...args) {
  336 + this.stepList.push({
  337 + action: "scale",
  338 + args,
  339 + actionType: "func",
  340 + });
  341 + }
  342 +
  343 + rotate(...args) {
  344 + this.stepList.push({
  345 + action: "rotate",
  346 + args,
  347 + actionType: "func",
  348 + });
  349 + }
  350 +
  351 + translate(...args) {
  352 + this.stepList.push({
  353 + action: "translate",
  354 + args,
  355 + actionType: "func",
  356 + });
  357 + }
  358 +
  359 + transform(...args) {
  360 + this.stepList.push({
  361 + action: "transform",
  362 + args,
  363 + actionType: "func",
  364 + });
  365 + }
  366 +
  367 + setTransform(...args) {
  368 + this.stepList.push({
  369 + action: "setTransform",
  370 + args,
  371 + actionType: "func",
  372 + });
  373 + }
  374 +
  375 + clearRect(...args) {
  376 + this.stepList.push({
  377 + action: "clearRect",
  378 + args,
  379 + actionType: "func",
  380 + });
  381 + }
  382 +
  383 + fillRect(...args) {
  384 + this.stepList.push({
  385 + action: "fillRect",
  386 + args,
  387 + actionType: "func",
  388 + });
  389 + }
  390 +
  391 + strokeRect(...args) {
  392 + this.stepList.push({
  393 + action: "strokeRect",
  394 + args,
  395 + actionType: "func",
  396 + });
  397 + }
  398 +
  399 + fillText(...args) {
  400 + this.stepList.push({
  401 + action: "fillText",
  402 + args,
  403 + actionType: "func",
  404 + });
  405 + }
  406 +
  407 + strokeText(...args) {
  408 + this.stepList.push({
  409 + action: "strokeText",
  410 + args,
  411 + actionType: "func",
  412 + });
  413 + }
  414 +
  415 + beginPath() {
  416 + this.stepList.push({
  417 + action: "beginPath",
  418 + args: null,
  419 + actionType: "func",
  420 + });
  421 + }
  422 +
  423 + fill() {
  424 + this.stepList.push({
  425 + action: "fill",
  426 + args: null,
  427 + actionType: "func",
  428 + });
  429 + }
  430 +
  431 + stroke() {
  432 + this.stepList.push({
  433 + action: "stroke",
  434 + args: null,
  435 + actionType: "func",
  436 + });
  437 + }
  438 +
  439 + drawFocusIfNeeded(...args) {
  440 + this.stepList.push({
  441 + action: "drawFocusIfNeeded",
  442 + args,
  443 + actionType: "func",
  444 + });
  445 + }
  446 +
  447 + clip() {
  448 + this.stepList.push({
  449 + action: "clip",
  450 + args: null,
  451 + actionType: "func",
  452 + });
  453 + }
  454 +
  455 + isPointInPath(...args) {
  456 + this.stepList.push({
  457 + action: "isPointInPath",
  458 + args,
  459 + actionType: "func",
  460 + });
  461 + }
  462 +
  463 + drawImage(...args) {
  464 + this.stepList.push({
  465 + action: "drawImage",
  466 + args,
  467 + actionType: "func",
  468 + });
  469 + }
  470 +
  471 + addHitRegion(...args) {
  472 + this.stepList.push({
  473 + action: "addHitRegion",
  474 + args,
  475 + actionType: "func",
  476 + });
  477 + }
  478 +
  479 + removeHitRegion(...args) {
  480 + this.stepList.push({
  481 + action: "removeHitRegion",
  482 + args,
  483 + actionType: "func",
  484 + });
  485 + }
  486 +
  487 + clearHitRegions(...args) {
  488 + this.stepList.push({
  489 + action: "clearHitRegions",
  490 + args,
  491 + actionType: "func",
  492 + });
  493 + }
  494 +
  495 + putImageData(...args) {
  496 + this.stepList.push({
  497 + action: "putImageData",
  498 + args,
  499 + actionType: "func",
  500 + });
  501 + }
  502 +
  503 + getLineDash() {
  504 + return this.canvasPrototype.lineDash;
  505 + }
  506 +
  507 + createLinearGradient(...args) {
  508 + return this.ctx.createLinearGradient(...args);
  509 + }
  510 +
  511 + createRadialGradient(...args) {
  512 + if (this.type === "2d") {
  513 + return this.ctx.createRadialGradient(...args);
  514 + } else {
  515 + return this.ctx.createCircularGradient(...args.slice(3, 6));
  516 + }
  517 + }
  518 +
  519 + createPattern(...args) {
  520 + return this.ctx.createPattern(...args);
  521 + }
  522 +
  523 + measureText(...args) {
  524 + return this.ctx.measureText(...args);
  525 + }
  526 +
  527 + createImageData(...args) {
  528 + return this.ctx.createImageData(...args);
  529 + }
  530 +
  531 + getImageData(...args) {
  532 + return this.ctx.getImageData(...args);
  533 + }
  534 +
  535 + async draw(reserve, func) {
  536 + const realstepList = this.stepList.slice();
  537 + this.stepList.length = 0;
  538 + if (this.type === "mina") {
  539 + if (realstepList.length > 0) {
  540 + for (const step of realstepList) {
  541 + this.implementMinaStep(step);
  542 + }
  543 + this.ctx.draw(reserve, func);
  544 + realstepList.length = 0;
  545 + }
  546 + } else if (this.type === "2d") {
  547 + if (!reserve) {
  548 + this.ctx.clearRect(0, 0, this.canvasNode.width, this.canvasNode.height);
  549 + }
  550 + if (realstepList.length > 0) {
  551 + for (const step of realstepList) {
  552 + await this.implement2DStep(step);
  553 + }
  554 + realstepList.length = 0;
  555 + }
  556 + if (func) {
  557 + func();
  558 + }
  559 + }
  560 + realstepList.length = 0;
  561 + }
  562 +
  563 + implementMinaStep(step) {
  564 + switch (step.action) {
  565 + case "textAlign": {
  566 + this.ctx.setTextAlign(step.args);
  567 + break;
  568 + }
  569 + case "textBaseline": {
  570 + this.ctx.setTextBaseline(step.args);
  571 + break;
  572 + }
  573 + default: {
  574 + if (step.actionType === "set") {
  575 + this.ctx[step.action] = step.args;
  576 + } else if (step.actionType === "func") {
  577 + if (step.args) {
  578 + this.ctx[step.action](...step.args);
  579 + } else {
  580 + this.ctx[step.action]();
  581 + }
  582 + }
  583 + break;
  584 + }
  585 + }
  586 + }
  587 +
  588 + implement2DStep(step) {
  589 + return new Promise((resolve) => {
  590 + if (step.action === "drawImage") {
  591 + const img = this.canvasNode.createImage();
  592 + img.src = step.args[0];
  593 + img.onload = () => {
  594 + this.ctx.drawImage(img, ...step.args.slice(1));
  595 + resolve();
  596 + };
  597 + } else {
  598 + if (step.actionType === "set") {
  599 + this.ctx[step.action] = step.args;
  600 + } else if (step.actionType === "func") {
  601 + if (step.args) {
  602 + this.ctx[step.action](...step.args);
  603 + } else {
  604 + this.ctx[step.action]();
  605 + }
  606 + }
  607 + resolve();
  608 + }
  609 + });
  610 + }
  611 +}
... ...
packageB/components/painter/painter.js 0 → 100644
  1 +import Pen from './lib/pen';
  2 +import Downloader from './lib/downloader';
  3 +import WxCanvas from './lib/wx-canvas';
  4 +
  5 +const util = require('./lib/util');
  6 +
  7 +const downloader = new Downloader();
  8 +
  9 +// 最大尝试的绘制次数
  10 +const MAX_PAINT_COUNT = 5;
  11 +const ACTION_DEFAULT_SIZE = 24;
  12 +const ACTION_OFFSET = '2rpx';
  13 +Component({
  14 + canvasWidthInPx: 0,
  15 + canvasHeightInPx: 0,
  16 + canvasNode: null,
  17 + paintCount: 0,
  18 + currentPalette: {},
  19 + movingCache: {},
  20 + outterDisabled: false,
  21 + isDisabled: false,
  22 + needClear: false,
  23 + /**
  24 + * 组件的属性列表
  25 + */
  26 + properties: {
  27 + use2D: {
  28 + type: Boolean,
  29 + },
  30 + customStyle: {
  31 + type: String,
  32 + },
  33 + // 运行自定义选择框和删除缩放按钮
  34 + customActionStyle: {
  35 + type: Object,
  36 + },
  37 + palette: {
  38 + type: Object,
  39 + observer: function (newVal, oldVal) {
  40 + if (this.isNeedRefresh(newVal, oldVal)) {
  41 + this.paintCount = 0;
  42 + this.startPaint();
  43 + }
  44 + },
  45 + },
  46 + dancePalette: {
  47 + type: Object,
  48 + observer: function (newVal, oldVal) {
  49 + if (!this.isEmpty(newVal) && !this.properties.use2D) {
  50 + this.initDancePalette(newVal);
  51 + }
  52 + },
  53 + },
  54 + // 缩放比,会在传入的 palette 中统一乘以该缩放比
  55 + scaleRatio: {
  56 + type: Number,
  57 + value: 1
  58 + },
  59 + widthPixels: {
  60 + type: Number,
  61 + value: 0
  62 + },
  63 + // 启用脏检查,默认 false
  64 + dirty: {
  65 + type: Boolean,
  66 + value: false,
  67 + },
  68 + LRU: {
  69 + type: Boolean,
  70 + value: true,
  71 + },
  72 + action: {
  73 + type: Object,
  74 + observer: function (newVal, oldVal) {
  75 + if (newVal && !this.isEmpty(newVal) && !this.properties.use2D) {
  76 + this.doAction(newVal, (callbackInfo) => {
  77 + this.movingCache = callbackInfo
  78 + }, false, true)
  79 + }
  80 + },
  81 + },
  82 + disableAction: {
  83 + type: Boolean,
  84 + observer: function (isDisabled) {
  85 + this.outterDisabled = isDisabled
  86 + this.isDisabled = isDisabled
  87 + }
  88 + },
  89 + clearActionBox: {
  90 + type: Boolean,
  91 + observer: function (needClear) {
  92 + if (needClear && !this.needClear) {
  93 + if (this.frontContext) {
  94 + setTimeout(() => {
  95 + this.frontContext.draw();
  96 + }, 100);
  97 + this.touchedView = {};
  98 + this.prevFindedIndex = this.findedIndex
  99 + this.findedIndex = -1;
  100 + }
  101 + }
  102 + this.needClear = needClear
  103 + }
  104 + },
  105 + },
  106 +
  107 + data: {
  108 + picURL: '',
  109 + showCanvas: true,
  110 + painterStyle: '',
  111 + },
  112 +
  113 + methods: {
  114 +
  115 + /**
  116 + * 判断一个 object 是否为 空
  117 + * @param {object} object
  118 + */
  119 + isEmpty(object) {
  120 + for (const i in object) {
  121 + return false;
  122 + }
  123 + return true;
  124 + },
  125 +
  126 + isNeedRefresh(newVal, oldVal) {
  127 + if (!newVal || this.isEmpty(newVal) || (this.data.dirty && util.equal(newVal, oldVal))) {
  128 + return false;
  129 + }
  130 + return true;
  131 + },
  132 +
  133 + getBox(rect, type) {
  134 + const boxArea = {
  135 + type: 'rect',
  136 + css: {
  137 + height: `${rect.bottom - rect.top}px`,
  138 + width: `${rect.right - rect.left}px`,
  139 + left: `${rect.left}px`,
  140 + top: `${rect.top}px`,
  141 + borderWidth: '4rpx',
  142 + borderColor: '#1A7AF8',
  143 + color: 'transparent'
  144 + }
  145 + }
  146 + if (type === 'text') {
  147 + boxArea.css = Object.assign({}, boxArea.css, {
  148 + borderStyle: 'dashed'
  149 + })
  150 + }
  151 + if (this.properties.customActionStyle && this.properties.customActionStyle.border) {
  152 + boxArea.css = Object.assign({}, boxArea.css, this.properties.customActionStyle.border)
  153 + }
  154 + Object.assign(boxArea, {
  155 + id: 'box'
  156 + })
  157 + return boxArea
  158 + },
  159 +
  160 + getScaleIcon(rect, type) {
  161 + let scaleArea = {}
  162 + const {
  163 + customActionStyle
  164 + } = this.properties
  165 + if (customActionStyle && customActionStyle.scale) {
  166 + scaleArea = {
  167 + type: 'image',
  168 + url: type === 'text' ? customActionStyle.scale.textIcon : customActionStyle.scale.imageIcon,
  169 + css: {
  170 + height: `${2 * ACTION_DEFAULT_SIZE}rpx`,
  171 + width: `${2 * ACTION_DEFAULT_SIZE}rpx`,
  172 + borderRadius: `${ACTION_DEFAULT_SIZE}rpx`,
  173 + }
  174 + }
  175 + } else {
  176 + scaleArea = {
  177 + type: 'rect',
  178 + css: {
  179 + height: `${2 * ACTION_DEFAULT_SIZE}rpx`,
  180 + width: `${2 * ACTION_DEFAULT_SIZE}rpx`,
  181 + borderRadius: `${ACTION_DEFAULT_SIZE}rpx`,
  182 + color: '#0000ff',
  183 + }
  184 + }
  185 + }
  186 + scaleArea.css = Object.assign({}, scaleArea.css, {
  187 + align: 'center',
  188 + left: `${rect.right + ACTION_OFFSET.toPx()}px`,
  189 + top: type === 'text' ? `${rect.top - ACTION_OFFSET.toPx() - scaleArea.css.height.toPx() / 2}px` : `${rect.bottom - ACTION_OFFSET.toPx() - scaleArea.css.height.toPx() / 2}px`
  190 + })
  191 + Object.assign(scaleArea, {
  192 + id: 'scale'
  193 + })
  194 + return scaleArea
  195 + },
  196 +
  197 + getDeleteIcon(rect) {
  198 + let deleteArea = {}
  199 + const {
  200 + customActionStyle
  201 + } = this.properties
  202 + if (customActionStyle && customActionStyle.scale) {
  203 + deleteArea = {
  204 + type: 'image',
  205 + url: customActionStyle.delete.icon,
  206 + css: {
  207 + height: `${2 * ACTION_DEFAULT_SIZE}rpx`,
  208 + width: `${2 * ACTION_DEFAULT_SIZE}rpx`,
  209 + borderRadius: `${ACTION_DEFAULT_SIZE}rpx`,
  210 + }
  211 + }
  212 + } else {
  213 + deleteArea = {
  214 + type: 'rect',
  215 + css: {
  216 + height: `${2 * ACTION_DEFAULT_SIZE}rpx`,
  217 + width: `${2 * ACTION_DEFAULT_SIZE}rpx`,
  218 + borderRadius: `${ACTION_DEFAULT_SIZE}rpx`,
  219 + color: '#0000ff',
  220 + }
  221 + }
  222 + }
  223 + deleteArea.css = Object.assign({}, deleteArea.css, {
  224 + align: 'center',
  225 + left: `${rect.left - ACTION_OFFSET.toPx()}px`,
  226 + top: `${rect.top - ACTION_OFFSET.toPx() - deleteArea.css.height.toPx() / 2}px`
  227 + })
  228 + Object.assign(deleteArea, {
  229 + id: 'delete'
  230 + })
  231 + return deleteArea
  232 + },
  233 +
  234 + doAction(action, callback, isMoving, overwrite) {
  235 + if (this.properties.use2D) {
  236 + return;
  237 + }
  238 + let newVal = null
  239 + if (action) {
  240 + newVal = action.view
  241 + }
  242 + if (newVal && newVal.id && this.touchedView.id !== newVal.id) {
  243 + // 带 id 的动作给撤回时使用,不带 id,表示对当前选中对象进行操作
  244 + const {
  245 + views
  246 + } = this.currentPalette;
  247 + for (let i = 0; i < views.length; i++) {
  248 + if (views[i].id === newVal.id) {
  249 + // 跨层回撤,需要重新构建三层关系
  250 + this.touchedView = views[i];
  251 + this.findedIndex = i;
  252 + this.sliceLayers();
  253 + break
  254 + }
  255 + }
  256 + }
  257 +
  258 + const doView = this.touchedView
  259 +
  260 + if (!doView || this.isEmpty(doView)) {
  261 + return
  262 + }
  263 + if (newVal && newVal.css) {
  264 + if (overwrite) {
  265 + doView.css = newVal.css
  266 + } else if (Array.isArray(doView.css) && Array.isArray(newVal.css)) {
  267 + doView.css = Object.assign({}, ...doView.css, ...newVal.css)
  268 + } else if (Array.isArray(doView.css)) {
  269 + doView.css = Object.assign({}, ...doView.css, newVal.css)
  270 + } else if (Array.isArray(newVal.css)) {
  271 + doView.css = Object.assign({}, doView.css, ...newVal.css)
  272 + } else {
  273 + doView.css = Object.assign({}, doView.css, newVal.css)
  274 + }
  275 + }
  276 + if (newVal && newVal.rect) {
  277 + doView.rect = newVal.rect;
  278 + }
  279 + if (newVal && newVal.url && doView.url && newVal.url !== doView.url) {
  280 + downloader.download(newVal.url, this.properties.LRU).then((path) => {
  281 + if (newVal.url.startsWith('https')) {
  282 + doView.originUrl = newVal.url
  283 + }
  284 + doView.url = path;
  285 + wx.getImageInfo({
  286 + src: path,
  287 + success: (res) => {
  288 + doView.sHeight = res.height
  289 + doView.sWidth = res.width
  290 + this.reDraw(doView, callback, isMoving)
  291 + },
  292 + fail: () => {
  293 + this.reDraw(doView, callback, isMoving)
  294 + }
  295 + })
  296 + }).catch((error) => {
  297 + // 未下载成功,直接绘制
  298 + console.error(error)
  299 + this.reDraw(doView, callback, isMoving)
  300 + })
  301 + } else {
  302 + (newVal && newVal.text && doView.text && newVal.text !== doView.text) && (doView.text = newVal.text);
  303 + (newVal && newVal.content && doView.content && newVal.content !== doView.content) && (doView.content = newVal.content);
  304 + this.reDraw(doView, callback, isMoving)
  305 + }
  306 + },
  307 +
  308 + reDraw(doView, callback, isMoving) {
  309 + const draw = {
  310 + width: this.currentPalette.width,
  311 + height: this.currentPalette.height,
  312 + views: this.isEmpty(doView) ? [] : [doView]
  313 + }
  314 + const pen = new Pen(this.globalContext, draw);
  315 +
  316 + if (isMoving && doView.type === 'text') {
  317 + pen.paint((callbackInfo) => {
  318 + callback && callback(callbackInfo);
  319 + this.triggerEvent('viewUpdate', {
  320 + view: this.touchedView
  321 + });
  322 + }, true, this.movingCache);
  323 + } else {
  324 + // 某些机型(华为 P20)非移动和缩放场景下,只绘制一遍会偶然性图片绘制失败
  325 + // if (!isMoving && !this.isScale) {
  326 + // pen.paint()
  327 + // }
  328 + pen.paint((callbackInfo) => {
  329 + callback && callback(callbackInfo);
  330 + this.triggerEvent('viewUpdate', {
  331 + view: this.touchedView
  332 + });
  333 + })
  334 + }
  335 +
  336 + const {
  337 + rect,
  338 + css,
  339 + type
  340 + } = doView
  341 +
  342 + this.block = {
  343 + width: this.currentPalette.width,
  344 + height: this.currentPalette.height,
  345 + views: this.isEmpty(doView) ? [] : [this.getBox(rect, doView.type)]
  346 + }
  347 + if (css && css.scalable) {
  348 + this.block.views.push(this.getScaleIcon(rect, type))
  349 + }
  350 + if (css && css.deletable) {
  351 + this.block.views.push(this.getDeleteIcon(rect))
  352 + }
  353 + const topBlock = new Pen(this.frontContext, this.block)
  354 + topBlock.paint();
  355 + },
  356 +
  357 + isInView(x, y, rect) {
  358 + return (x > rect.left &&
  359 + y > rect.top &&
  360 + x < rect.right &&
  361 + y < rect.bottom
  362 + )
  363 + },
  364 +
  365 + isInDelete(x, y) {
  366 + for (const view of this.block.views) {
  367 + if (view.id === 'delete') {
  368 + return (x > view.rect.left &&
  369 + y > view.rect.top &&
  370 + x < view.rect.right &&
  371 + y < view.rect.bottom)
  372 + }
  373 + }
  374 + return false
  375 + },
  376 +
  377 + isInScale(x, y) {
  378 + for (const view of this.block.views) {
  379 + if (view.id === 'scale') {
  380 + return (x > view.rect.left &&
  381 + y > view.rect.top &&
  382 + x < view.rect.right &&
  383 + y < view.rect.bottom)
  384 + }
  385 + }
  386 + return false
  387 + },
  388 +
  389 + touchedView: {},
  390 + findedIndex: -1,
  391 + onClick() {
  392 + const x = this.startX
  393 + const y = this.startY
  394 + const totalLayerCount = this.currentPalette.views.length
  395 + let canBeTouched = []
  396 + let isDelete = false
  397 + let deleteIndex = -1
  398 + for (let i = totalLayerCount - 1; i >= 0; i--) {
  399 + const view = this.currentPalette.views[i]
  400 + const {
  401 + rect
  402 + } = view
  403 + if (this.touchedView && this.touchedView.id && this.touchedView.id === view.id && this.isInDelete(x, y, rect)) {
  404 + canBeTouched.length = 0
  405 + deleteIndex = i
  406 + isDelete = true
  407 + break
  408 + }
  409 + if (this.isInView(x, y, rect)) {
  410 + canBeTouched.push({
  411 + view,
  412 + index: i
  413 + })
  414 + }
  415 + }
  416 + this.touchedView = {}
  417 + if (canBeTouched.length === 0) {
  418 + this.findedIndex = -1
  419 + } else {
  420 + let i = 0
  421 + const touchAble = canBeTouched.filter(item => Boolean(item.view.id))
  422 + if (touchAble.length === 0) {
  423 + this.findedIndex = canBeTouched[0].index
  424 + } else {
  425 + for (i = 0; i < touchAble.length; i++) {
  426 + if (this.findedIndex === touchAble[i].index) {
  427 + i++
  428 + break
  429 + }
  430 + }
  431 + if (i === touchAble.length) {
  432 + i = 0
  433 + }
  434 + this.touchedView = touchAble[i].view
  435 + this.findedIndex = touchAble[i].index
  436 + this.triggerEvent('viewClicked', {
  437 + view: this.touchedView
  438 + })
  439 + }
  440 + }
  441 + if (this.findedIndex < 0 || (this.touchedView && !this.touchedView.id)) {
  442 + // 证明点击了背景 或无法移动的view
  443 + this.frontContext.draw();
  444 + if (isDelete) {
  445 + this.triggerEvent('touchEnd', {
  446 + view: this.currentPalette.views[deleteIndex],
  447 + index: deleteIndex,
  448 + type: 'delete'
  449 + })
  450 + this.doAction()
  451 + } else if (this.findedIndex < 0) {
  452 + this.triggerEvent('viewClicked', {})
  453 + }
  454 + this.findedIndex = -1
  455 + this.prevFindedIndex = -1
  456 + } else if (this.touchedView && this.touchedView.id) {
  457 + this.sliceLayers();
  458 + }
  459 + },
  460 +
  461 + sliceLayers() {
  462 + const bottomLayers = this.currentPalette.views.slice(0, this.findedIndex)
  463 + const topLayers = this.currentPalette.views.slice(this.findedIndex + 1)
  464 + const bottomDraw = {
  465 + width: this.currentPalette.width,
  466 + height: this.currentPalette.height,
  467 + background: this.currentPalette.background,
  468 + views: bottomLayers
  469 + }
  470 + const topDraw = {
  471 + width: this.currentPalette.width,
  472 + height: this.currentPalette.height,
  473 + views: topLayers
  474 + }
  475 + if (this.prevFindedIndex < this.findedIndex) {
  476 + new Pen(this.bottomContext, bottomDraw).paint();
  477 + this.doAction(null, (callbackInfo) => {
  478 + this.movingCache = callbackInfo
  479 + })
  480 + new Pen(this.topContext, topDraw).paint();
  481 + } else {
  482 + new Pen(this.topContext, topDraw).paint();
  483 + this.doAction(null, (callbackInfo) => {
  484 + this.movingCache = callbackInfo
  485 + })
  486 + new Pen(this.bottomContext, bottomDraw).paint();
  487 + }
  488 + this.prevFindedIndex = this.findedIndex
  489 + },
  490 +
  491 + startX: 0,
  492 + startY: 0,
  493 + startH: 0,
  494 + startW: 0,
  495 + isScale: false,
  496 + startTimeStamp: 0,
  497 + onTouchStart(event) {
  498 + if (this.isDisabled) {
  499 + return
  500 + }
  501 + const {
  502 + x,
  503 + y
  504 + } = event.touches[0]
  505 + this.startX = x
  506 + this.startY = y
  507 + this.startTimeStamp = new Date().getTime()
  508 + if (this.touchedView && !this.isEmpty(this.touchedView)) {
  509 + const {
  510 + rect
  511 + } = this.touchedView
  512 + if (this.isInScale(x, y, rect)) {
  513 + this.isScale = true
  514 + this.movingCache = {}
  515 + this.startH = rect.bottom - rect.top
  516 + this.startW = rect.right - rect.left
  517 + } else {
  518 + this.isScale = false
  519 + }
  520 + } else {
  521 + this.isScale = false
  522 + }
  523 + },
  524 +
  525 + onTouchEnd(e) {
  526 + if (this.isDisabled) {
  527 + return
  528 + }
  529 + const current = new Date().getTime()
  530 + if ((current - this.startTimeStamp) <= 500 && !this.hasMove) {
  531 + !this.isScale && this.onClick(e)
  532 + } else if (this.touchedView && !this.isEmpty(this.touchedView)) {
  533 + this.triggerEvent('touchEnd', {
  534 + view: this.touchedView,
  535 + })
  536 + }
  537 + this.hasMove = false
  538 + },
  539 +
  540 + onTouchCancel(e) {
  541 + if (this.isDisabled) {
  542 + return
  543 + }
  544 + this.onTouchEnd(e)
  545 + },
  546 +
  547 + hasMove: false,
  548 + onTouchMove(event) {
  549 + if (this.isDisabled) {
  550 + return
  551 + }
  552 + this.hasMove = true
  553 + if (!this.touchedView || (this.touchedView && !this.touchedView.id)) {
  554 + return
  555 + }
  556 + const {
  557 + x,
  558 + y
  559 + } = event.touches[0]
  560 + const offsetX = x - this.startX
  561 + const offsetY = y - this.startY
  562 + const {
  563 + rect,
  564 + type
  565 + } = this.touchedView
  566 + let css = {}
  567 + if (this.isScale) {
  568 + const newW = this.startW + offsetX > 1 ? this.startW + offsetX : 1
  569 + if (this.touchedView.css && this.touchedView.css.minWidth) {
  570 + if (newW < this.touchedView.css.minWidth.toPx()) {
  571 + return
  572 + }
  573 + }
  574 + if (this.touchedView.rect && this.touchedView.rect.minWidth) {
  575 + if (newW < this.touchedView.rect.minWidth) {
  576 + return
  577 + }
  578 + }
  579 + const newH = this.startH + offsetY > 1 ? this.startH + offsetY : 1
  580 + css = {
  581 + width: `${newW}px`,
  582 + }
  583 + if (type !== 'text') {
  584 + if (type === 'image') {
  585 + css.height = `${(newW) * this.startH / this.startW }px`
  586 + } else {
  587 + css.height = `${newH}px`
  588 + }
  589 + }
  590 + } else {
  591 + this.startX = x
  592 + this.startY = y
  593 + css = {
  594 + left: `${rect.x + offsetX}px`,
  595 + top: `${rect.y + offsetY}px`,
  596 + right: undefined,
  597 + bottom: undefined
  598 + }
  599 + }
  600 + this.doAction({
  601 + view: {
  602 + css
  603 + }
  604 + }, (callbackInfo) => {
  605 + if (this.isScale) {
  606 + this.movingCache = callbackInfo
  607 + }
  608 + }, !this.isScale)
  609 + },
  610 +
  611 + initScreenK() {
  612 + if (!(getApp() && getApp().systemInfo && getApp().systemInfo.screenWidth)) {
  613 + try {
  614 + getApp().systemInfo = wx.getSystemInfoSync();
  615 + } catch (e) {
  616 + console.error(`Painter get system info failed, ${JSON.stringify(e)}`);
  617 + return;
  618 + }
  619 + }
  620 + this.screenK = 0.5;
  621 + if (getApp() && getApp().systemInfo && getApp().systemInfo.screenWidth) {
  622 + this.screenK = getApp().systemInfo.screenWidth / 750;
  623 + }
  624 + setStringPrototype(this.screenK, this.properties.scaleRatio);
  625 + },
  626 +
  627 + initDancePalette() {
  628 + if (this.properties.use2D) {
  629 + return;
  630 + }
  631 + this.isDisabled = true;
  632 + this.initScreenK();
  633 + this.downloadImages(this.properties.dancePalette).then(async (palette) => {
  634 + this.currentPalette = palette
  635 + const {
  636 + width,
  637 + height
  638 + } = palette;
  639 +
  640 + if (!width || !height) {
  641 + console.error(`You should set width and height correctly for painter, width: ${width}, height: ${height}`);
  642 + return;
  643 + }
  644 + this.setData({
  645 + painterStyle: `width:${width.toPx()}px;height:${height.toPx()}px;`,
  646 + });
  647 + this.frontContext || (this.frontContext = await this.getCanvasContext(this.properties.use2D, 'front'));
  648 + this.bottomContext || (this.bottomContext = await this.getCanvasContext(this.properties.use2D, 'bottom'));
  649 + this.topContext || (this.topContext = await this.getCanvasContext(this.properties.use2D, 'top'));
  650 + this.globalContext || (this.globalContext = await this.getCanvasContext(this.properties.use2D, 'k-canvas'));
  651 + new Pen(this.bottomContext, palette, this.properties.use2D).paint(() => {
  652 + this.isDisabled = false;
  653 + this.isDisabled = this.outterDisabled;
  654 + this.triggerEvent('didShow');
  655 + });
  656 + this.globalContext.draw();
  657 + this.frontContext.draw();
  658 + this.topContext.draw();
  659 + });
  660 + this.touchedView = {};
  661 + },
  662 +
  663 + startPaint() {
  664 + this.initScreenK();
  665 +
  666 + this.downloadImages(this.properties.palette).then(async (palette) => {
  667 + const {
  668 + width,
  669 + height
  670 + } = palette;
  671 +
  672 + if (!width || !height) {
  673 + console.error(`You should set width and height correctly for painter, width: ${width}, height: ${height}`);
  674 + return;
  675 + }
  676 +
  677 + let needScale = false;
  678 + // 生成图片时,根据设置的像素值重新绘制
  679 + if (width.toPx() !== this.canvasWidthInPx) {
  680 + this.canvasWidthInPx = width.toPx();
  681 + needScale = this.properties.use2D;
  682 + }
  683 + if (this.properties.widthPixels) {
  684 + setStringPrototype(this.screenK, this.properties.widthPixels / this.canvasWidthInPx)
  685 + this.canvasWidthInPx = this.properties.widthPixels
  686 + }
  687 +
  688 + if (this.canvasHeightInPx !== height.toPx()) {
  689 + this.canvasHeightInPx = height.toPx();
  690 + needScale = needScale || this.properties.use2D;
  691 + }
  692 + this.setData({
  693 + photoStyle: `width:${this.canvasWidthInPx}px;height:${this.canvasHeightInPx}px;`,
  694 + });
  695 + if (!this.photoContext) {
  696 + this.photoContext = await this.getCanvasContext(this.properties.use2D, 'photo');
  697 + }
  698 + if (needScale) {
  699 + const scale = getApp().systemInfo.pixelRatio;
  700 + this.photoContext.width = this.canvasWidthInPx * scale;
  701 + this.photoContext.height = this.canvasHeightInPx * scale;
  702 + this.photoContext.scale(scale, scale);
  703 + }
  704 + new Pen(this.photoContext, palette).paint(() => {
  705 + this.saveImgToLocal();
  706 + });
  707 + setStringPrototype(this.screenK, this.properties.scaleRatio);
  708 + });
  709 + },
  710 +
  711 + downloadImages(palette) {
  712 + return new Promise((resolve, reject) => {
  713 + let preCount = 0;
  714 + let completeCount = 0;
  715 + const paletteCopy = JSON.parse(JSON.stringify(palette));
  716 + if (paletteCopy.background) {
  717 + preCount++;
  718 + downloader.download(paletteCopy.background, this.properties.LRU).then((path) => {
  719 + paletteCopy.background = path;
  720 + completeCount++;
  721 + if (preCount === completeCount) {
  722 + resolve(paletteCopy);
  723 + }
  724 + }, () => {
  725 + completeCount++;
  726 + if (preCount === completeCount) {
  727 + resolve(paletteCopy);
  728 + }
  729 + });
  730 + }
  731 + if (paletteCopy.views) {
  732 + for (const view of paletteCopy.views) {
  733 + if (view && view.type === 'image' && view.url) {
  734 + preCount++;
  735 + /* eslint-disable no-loop-func */
  736 + downloader.download(view.url, this.properties.LRU).then((path) => {
  737 + view.originUrl = view.url;
  738 + view.url = path;
  739 + wx.getImageInfo({
  740 + src: path,
  741 + success: (res) => {
  742 + // 获得一下图片信息,供后续裁减使用
  743 + view.sWidth = res.width;
  744 + view.sHeight = res.height;
  745 + },
  746 + fail: (error) => {
  747 + // 如果图片坏了,则直接置空,防止坑爹的 canvas 画崩溃了
  748 + view.url = "";
  749 + // console.error(`getImageInfo ${view.url} failed, ${JSON.stringify(error)}`);
  750 + },
  751 + complete: () => {
  752 + completeCount++;
  753 + if (preCount === completeCount) {
  754 + resolve(paletteCopy);
  755 + }
  756 + },
  757 + });
  758 + }, () => {
  759 + completeCount++;
  760 + if (preCount === completeCount) {
  761 + resolve(paletteCopy);
  762 + }
  763 + });
  764 + }
  765 + }
  766 + }
  767 + if (preCount === 0) {
  768 + resolve(paletteCopy);
  769 + }
  770 + });
  771 + },
  772 +
  773 + saveImgToLocal() {
  774 + const that = this;
  775 + setTimeout(() => {
  776 + wx.canvasToTempFilePath({
  777 + canvasId: 'photo',
  778 + canvas: that.properties.use2D ? that.canvasNode : null,
  779 + destWidth: that.canvasWidthInPx * getApp().systemInfo.pixelRatio,
  780 + destHeight: that.canvasHeightInPx * getApp().systemInfo.pixelRatio,
  781 + success: function (res) {
  782 + that.getImageInfo(res.tempFilePath);
  783 + },
  784 + fail: function (error) {
  785 + console.error(`canvasToTempFilePath failed, ${JSON.stringify(error)}`);
  786 + that.triggerEvent('imgErr', {
  787 + error: error
  788 + });
  789 + },
  790 + }, this);
  791 + }, 300);
  792 + },
  793 +
  794 +
  795 + getCanvasContext(use2D, id) {
  796 + const that = this;
  797 + return new Promise(resolve => {
  798 + if (use2D) {
  799 + const query = wx.createSelectorQuery().in(that);
  800 + const selectId = `#${id}`;
  801 + query.select(selectId)
  802 + .fields({ node: true, size: true })
  803 + .exec((res) => {
  804 + that.canvasNode = res[0].node;
  805 + const ctx = that.canvasNode.getContext('2d');
  806 + const wxCanvas = new WxCanvas('2d', ctx, id, true, that.canvasNode);
  807 + resolve(wxCanvas);
  808 + });
  809 + } else {
  810 + const temp = wx.createCanvasContext(id, that);
  811 + resolve(new WxCanvas('mina', temp, id, true));
  812 + }
  813 + })
  814 + },
  815 +
  816 + getImageInfo(filePath) {
  817 + const that = this;
  818 + wx.getImageInfo({
  819 + src: filePath,
  820 + success: (infoRes) => {
  821 + if (that.paintCount > MAX_PAINT_COUNT) {
  822 + const error = `The result is always fault, even we tried ${MAX_PAINT_COUNT} times`;
  823 + console.error(error);
  824 + that.triggerEvent('imgErr', {
  825 + error: error
  826 + });
  827 + return;
  828 + }
  829 + // 比例相符时才证明绘制成功,否则进行强制重绘制
  830 + if (Math.abs((infoRes.width * that.canvasHeightInPx - that.canvasWidthInPx * infoRes.height) / (infoRes.height * that.canvasHeightInPx)) < 0.01) {
  831 + that.triggerEvent('imgOK', {
  832 + path: filePath
  833 + });
  834 + } else {
  835 + that.startPaint();
  836 + }
  837 + that.paintCount++;
  838 + },
  839 + fail: (error) => {
  840 + console.error(`getImageInfo failed, ${JSON.stringify(error)}`);
  841 + that.triggerEvent('imgErr', {
  842 + error: error
  843 + });
  844 + },
  845 + });
  846 + },
  847 + },
  848 +});
  849 +
  850 +
  851 +function setStringPrototype(screenK, scale) {
  852 + /* eslint-disable no-extend-native */
  853 + /**
  854 + * 是否支持负数
  855 + * @param {Boolean} minus 是否支持负数
  856 + * @param {Number} baseSize 当设置了 % 号时,设置的基准值
  857 + */
  858 + String.prototype.toPx = function toPx(minus, baseSize) {
  859 + if (this === '0') {
  860 + return 0
  861 + }
  862 + let reg;
  863 + if (minus) {
  864 + reg = /^-?[0-9]+([.]{1}[0-9]+){0,1}(rpx|px|%)$/g;
  865 + } else {
  866 + reg = /^[0-9]+([.]{1}[0-9]+){0,1}(rpx|px|%)$/g;
  867 + }
  868 + const results = reg.exec(this);
  869 + if (!this || !results) {
  870 + console.error(`The size: ${this} is illegal`);
  871 + return 0;
  872 + }
  873 + const unit = results[2];
  874 + const value = parseFloat(this);
  875 +
  876 + let res = 0;
  877 + if (unit === 'rpx') {
  878 + res = Math.round(value * (screenK || 0.5) * (scale || 1));
  879 + } else if (unit === 'px') {
  880 + res = Math.round(value * (scale || 1));
  881 + } else if (unit === '%') {
  882 + res = Math.round(value * baseSize / 100);
  883 + }
  884 + return res;
  885 + };
  886 +}
0 887 \ No newline at end of file
... ...
packageB/components/painter/painter.json 0 → 100644
  1 +{
  2 + "component": true,
  3 + "usingComponents": {}
  4 +}
0 5 \ No newline at end of file
... ...
packageB/components/painter/painter.wxml 0 → 100644
  1 +<view style='position: relative;{{customStyle}};{{painterStyle}}'>
  2 + <block wx:if="{{!use2D}}">
  3 + <canvas canvas-id="photo" style="{{photoStyle}};position: absolute; left: -9999px; top: -9999rpx;" />
  4 + <canvas canvas-id="bottom" style="{{painterStyle}};position: absolute;" />
  5 + <canvas canvas-id="k-canvas" style="{{painterStyle}};position: absolute;" />
  6 + <canvas canvas-id="top" style="{{painterStyle}};position: absolute;" />
  7 + <canvas
  8 + canvas-id="front"
  9 + style="{{painterStyle}};position: absolute;"
  10 + bindtouchstart="onTouchStart"
  11 + bindtouchmove="onTouchMove"
  12 + bindtouchend="onTouchEnd"
  13 + bindtouchcancel="onTouchCancel"
  14 + disable-scroll="{{true}}" />
  15 + </block>
  16 + <block wx:if="{{use2D}}">
  17 + <canvas type="2d" id="photo" style="{{photoStyle}};" />
  18 + <!-- <canvas type="2d" id="bottom" style="{{painterStyle}};position: absolute;" />
  19 + <canvas type="2d" id="k-canvas" style="{{painterStyle}};position: absolute;" />
  20 + <canvas type="2d" id="top" style="{{painterStyle}};position: absolute;" />
  21 + <canvas
  22 + type="2d"
  23 + id="front"
  24 + style="{{painterStyle}};position: absolute;"
  25 + bindtouchstart="onTouchStart"
  26 + bindtouchmove="onTouchMove"
  27 + bindtouchend="onTouchEnd"
  28 + bindtouchcancel="onTouchCancel"
  29 + disable-scroll="{{true}}" /> -->
  30 + </block>
  31 +</view>
... ...
packageB/images/luckDraw/jiang.png 0 → 100644

19.6 KB

packageB/pages/luckactivity/index/index.js
... ... @@ -35,6 +35,7 @@ Page({
35 35  
36 36 if(index == 0) {
37 37 data.is_end = 0;
  38 + data.timetype = 1;
38 39 } else if(index == 1) {
39 40 data.is_end = 1;
40 41 };
... ... @@ -82,6 +83,7 @@ Page({
82 83 store_id: app.globalData.setting.stoid,
83 84 user_id: app.globalData.userInfo.user_id,
84 85 is_end: 0,
  86 + timetype:1
85 87 };
86 88  
87 89 this.setData({
... ...
packageB/pages/luckactivity/index/index.wxml
... ... @@ -20,7 +20,7 @@
20 20 <block wx:for="{{list.pageData}}">
21 21 <view class="tab-item" bindtap="goto" data-id="{{item.id}}" data-title="{{item.act_name}}">
22 22 <view class="img-container">
23   - <image wx:if="{{item.imageurl}}" src="{{imghost + item.imageurl}}" class="img"></image>
  23 + <image wx:if="{{item.imageurl}}" src="{{imghost + item.imageurl}}" class="img" mode="aspectFit"></image>
24 24 <text class="iconfont icon-zhuanpan" wx:else></text>
25 25 </view>
26 26 <view class="desc-container">
... ...
packageB/pages/luckactivity/index/index.wxss
... ... @@ -97,15 +97,15 @@ page {
97 97 }
98 98  
99 99 .icon-zhuanpan {
100   - font-size: 120rpx;
  100 + font-size: 140rpx;
101 101 color: #FF6768;
102 102 }
103 103  
104 104 .img-container {
105 105 /* background-color: #dedede; */
106 106 /* height: 300rpx; */
107   - width: 160rpx;
108   - height: 160rpx;
  107 + width: 140rpx;
  108 + height: 140rpx;
109 109 line-height: 160rpx;
110 110 text-align: center;
111 111 }
... ...
packageB/pages/luckactivity/luckinfo/luckinfo.js
  1 +var util = require("../../../../utils/util.js");
1 2 var WxParse = require('../../../../utils/wxParse/wxParse.js');
2 3 const app = getApp();
3 4 let imghost = app.globalData.setting.imghost;
4 5 let self = null;
  6 +let imgDraw = {
  7 + "width": "554px",
  8 + "height": "899px",
  9 + "background": imghost + "miniapp/images/share_bg.png",
  10 + "views": [
  11 + { //0.头像
  12 + "type": "image",
  13 + // "url": app.globalData.userInfo.head_pic,
  14 + "css": {
  15 + "background": "white",
  16 + "width": "80px",
  17 + "height": "80px",
  18 + "top": "24px",
  19 + "left": "40px",
  20 + "borderRadius": "80px",
  21 + }
  22 + },
  23 + { //1.昵称
  24 + "type": "text",
  25 + // "text": "",
  26 + "css": {
  27 + "color": "#000000",
  28 + "width": "400px",
  29 + "top": "25px",
  30 + "left": "140px",
  31 + "fontSize": "26px",
  32 + "maxLines": "1",
  33 + }
  34 + },
  35 + { //2.强烈推荐
  36 + "type": "text",
  37 + "text": "强烈推荐",
  38 + "css": {
  39 + "color": "#fff",
  40 + "background": "#FF6768",
  41 + "width": "105px",
  42 + "height": "26px",
  43 + "lineHeight": "26px",
  44 + "top": "70px",
  45 + "left": "140px",
  46 + "borderRadius": "10px",
  47 + "fontSize": "18px",
  48 + "textAlign": "center"
  49 +
  50 + }
  51 + },
  52 + { //3.分享标题
  53 + "type": "text",
  54 + "text": "",
  55 + "css": {
  56 + "width": "554px",
  57 + "padding": "20px",
  58 + "left": "20px",
  59 + "top": "160px",
  60 + "fontSize": "28px",
  61 + "textAlign": "left",
  62 + "maxLines": "1",
  63 + }
  64 + },
  65 + { //4.分享内容
  66 + "type": "text",
  67 + // "text": "",
  68 + "css": {
  69 + "color": "#000000",
  70 + "width": "554px",
  71 + "padding": "20px",
  72 + "left": "20px",
  73 + "top": "190px",
  74 + "fontSize": "26px",
  75 + "textAlign": "center",
  76 + "maxLines": "1",
  77 + }
  78 + },
  79 + { //5.分享图片
  80 + "type": "image",
  81 + "url": "/packageB/images/luckDraw/jiang.png",
  82 + "css": {
  83 + "width": "auto",
  84 + "height": "380px",
  85 + "top": "220px",
  86 + "left": "277px",
  87 + "align": "center",
  88 + "mode": "aspectFill",
  89 + }
  90 + },
  91 + { //6
  92 + "type": "image",
  93 + "url": "/images/share/s_gou.png",
  94 + "css": {
  95 + "width": "30px",
  96 + "height": "30px",
  97 + "top": "630px",
  98 + "left": "18px",
  99 + "rotate": "0",
  100 + "borderRadius": "30px",
  101 + }
  102 + },
  103 + { //7
  104 + "type": "text",
  105 + "text": "正品保障",
  106 + "css": {
  107 + "color": "red",
  108 + "width": "110px",
  109 + "top": "630px",
  110 + "left": "52px",
  111 + "fontSize": "22px",
  112 + }
  113 + },
  114 + { //8
  115 + "type": "image",
  116 + "url": "/images/share/s_gou.png",
  117 + "css": {
  118 + "width": "30px",
  119 + "height": "30px",
  120 + "top": "630px",
  121 + "left": "208px",
  122 + "borderRadius": "30px",
  123 + }
  124 + },
  125 + { //9
  126 + "type": "text",
  127 + "text": "纯实体店",
  128 + "css": {
  129 + "color": "red",
  130 + "width": "129px",
  131 + "top": "630px",
  132 + "left": "243px",
  133 + "fontSize": "22px",
  134 + }
  135 + },
  136 + { //10
  137 + "type": "image",
  138 + "url": "/images/share/s_gou.png",
  139 + "css": {
  140 + "width": "30px",
  141 + "height": "30px",
  142 + "top": "630px",
  143 + "left": "410px",
  144 + "borderRadius": "30px",
  145 + }
  146 + },
  147 + { //11
  148 + "type": "text",
  149 + "text": "官方验证",
  150 + "css": {
  151 + "color": "red",
  152 + "width": "121px",
  153 + "top": "630px",
  154 + "left": "450px",
  155 + "fontSize": "22px",
  156 + }
  157 + },
  158 + { //12.横线
  159 + "type": "rect",
  160 + "css": {
  161 + "background": "#f8f8f8",
  162 + "width": "554px",
  163 + "height": "1px",
  164 + "top": "676px",
  165 + "left": "0px",
  166 + }
  167 + },
  168 + { //13
  169 + "type": "text",
  170 + "text": "特惠活动时间仅限",
  171 + "css": {
  172 + "color": "#000000",
  173 + "width": "245px",
  174 + "top": "730px",
  175 + "left": "28px",
  176 + "fontSize": "24px",
  177 + "textAlign": "left"
  178 + }
  179 + },
  180 + { //14.时间
  181 + "type": "text",
  182 + // "text": "",
  183 + "css": {
  184 + "width": "377px",
  185 + "top": "770px",
  186 + "left": "28px",
  187 + "fontSize": "24px",
  188 + }
  189 + },
  190 + { //15
  191 + "type": "text",
  192 + "text": "长按识别小程序码有惊喜哦!",
  193 + "css": {
  194 + "color": "#7c7c7c",
  195 + "width": "348px",
  196 + "top": "820px",
  197 + "left": "27px",
  198 + "fontSize": "24px",
  199 + }
  200 + },
  201 +
  202 + { //16.码
  203 + "type": "image",
  204 + // "url": "",
  205 + "css": {
  206 + "width": "150px",
  207 + "height": "150px",
  208 + "top": "715px",
  209 + "left": "380px",
  210 + "mode": "scaleToFill"
  211 + }
  212 + },
  213 +
  214 + ]
  215 + };
  216 +
5 217  
6 218 Page({
7 219 data: {
  220 + imgDraw: {},
  221 +
8 222 start: false,
9 223 list: null,
10 224 isLoading: false, // 检测是否已经发送请求,防止重复发送请求
... ... @@ -12,6 +226,8 @@ Page({
12 226 pageNum: 1, // 当前页数
13 227 imghost: imghost,
14 228 num: 3,
  229 + canStart: false,
  230 +
15 231  
16 232 prizes: [],
17 233 defaultConfig: {
... ... @@ -21,75 +237,111 @@ Page({
21 237 // fontColor: '#d64737',
22 238 // fontSize: '14px'
23 239 // },
24   - blocks: [ //背景图
25   - // { padding: '13px', background: '#d64737', top: '20rpx' }
26   - {
27   - padding: '76rpx',
28   - // background: 'pink',
29   - imgs: [{
30   - src: imghost + 'miniapp/images/luckDraw/weel.png',
31   - width: '700rpx',
32   - height: '700rpx',
33   - rotate: true,
34   - }]
35   - }
36   - ],
37   - buttons: [
38   - // { radius: '50px', background: '#d64737' },
39   - // { radius: '45px', background: '#fff' },
40   - // { radius: '41px', background: '#f6c66f', pointer: true },
41   - // {
42   - // radius: '35px', background: '#ffdea0',
43   - // fonts: [{ text: '开始\n抽奖', fontSize: '18px', top: -18 }]
44   - // }
45   - {
46   - radius: '60rpx',
47   - // background: 'black',
48   - // pointer: true,
49   - imgs: [{
50   - src: imghost + 'miniapp/images/luckDraw/pointer.png',
51   - width: '188rpx',
52   - height: '230rpx',
53   - top: '-130rpx',
54   - }],
55   - }
56   - ],
  240 + blocks: [{
  241 + padding: '76rpx',
  242 + imgs: [{
  243 + src: imghost + 'miniapp/images/luckDraw/weel.png?v=3',
  244 + width: '700rpx',
  245 + height: '700rpx',
  246 + rotate: true,
  247 + }],
  248 + }],
  249 + buttons: [{
  250 + radius: '60rpx',
  251 + imgs: [{
  252 + src: imghost + 'miniapp/images/luckDraw/pointer.png?v=3',
  253 + width: '188rpx',
  254 + height: '230rpx',
  255 + top: '-130rpx',
  256 + }],
  257 + }],
57 258 },
58 259  
59 260 onLoad(options) {
60   - // console.log('imghost+++++', imghost);
61 261 self = this;
  262 + let first_leader = null;
62 263 this.data.options = options;
63   - // this.setData({
64   - // options,
65   - // imghost,
66   - // });
67   - // console.log('this data', this.data.imghost);
  264 +
  265 +
68 266 wx.setNavigationBarTitle({
69 267 title: options.title,
70 268 });
  269 +
  270 +
71 271 app.isLogin().then(function(data) {//进入页面前已经授权登录成功
72 272 self.setData({
73 273 userInfo: data,
74   - // imghost,
75 274 });
76 275 });
  276 +
  277 +
  278 +
  279 + //从分享的跳转过来
  280 + if (options.id == undefined || options.id == null || options.id == '') {
  281 + var scene = decodeURIComponent(options.scene);
  282 + scene = scene.split('_');
  283 + first_leader = scene[0];
  284 + this.data.options.id = scene[1];
  285 + };
  286 +
  287 + if(first_leader) {
  288 + // console.log("log---", first_leader);
  289 + app.globalData.first_leader = first_leader;
  290 + //调用接口判断是不是会员
  291 + app.request.promiseGet("/api/weshop/shoppingGuide/get/" + app.globalData.setting.stoid +"/" + first_leader,{}).then(res=>{
  292 + if(res.data.code==0){
  293 + app.globalData.guide_id = res.data.data.id;
  294 + }
  295 + })
  296 + };
  297 +
77 298 },
78 299  
79 300 onShow() {
  301 + // console.log('show~~`');
  302 +
80 303 if(app.globalData.userInfo) {
81 304 if(!this.data.isLogin) {
82 305  
  306 + // 下载头像
  307 + let path = app.globalData.userInfo.head_pic;
  308 + path = path.replace("http://thirdwx.qlogo.cn", "https://wx.qlogo.cn");
  309 + path = path.replace("https://thirdwx.qlogo.cn", "https://wx.qlogo.cn");
  310 + wx.downloadFile({
  311 + url: path, //仅为示例,并非真实的资源
  312 + success (res) {
  313 + // 只要服务器有响应数据,就会把响应内容写入文件并进入 success 回调,业务需要自行判断是否下载到了想要的内容
  314 + if (res.statusCode === 200) {
  315 + self.setData({
  316 + 'imgDraw.views[0].url': res.tempFilePath,//头像
  317 + });
  318 +
  319 + }
  320 + }
  321 + });
  322 +
  323 +
83 324 this.setData({
  325 + imgDraw: imgDraw,
84 326 userInfo: app.globalData.userInfo,
85 327 isLogin: true,
  328 + 'imgDraw.views[1].text': app.globalData.userInfo.nickname,//昵称
86 329 });
87   -
88   - // console.log('imghost', this.data.imghost);
  330 +
  331 +
  332 + // console.log('imgDraw.views[1].text+++++++++', imgDraw.views[1], app.globalData.userInfo.nickname);
89 333 let user_id = app.globalData.userInfo.user_id;
90 334 let store_id = app.globalData.setting.stoid;
91 335 let id = this.data.options.id;
92 336 let url = `/api/weshop/marketing/marketingLuckForm/getLuckInfo/${store_id}/${id}/${user_id}`;
  337 +
  338 + //获取小程序码
  339 + this.getMiniCode({
  340 + url: app.globalData.setting.url,
  341 + store_id: app.globalData.setting.stoid,
  342 + user_id: app.globalData.userInfo.user_id,
  343 + id: this.data.options.id,
  344 + });
93 345  
94 346  
95 347 app.request.get(url, {
... ... @@ -105,32 +357,109 @@ Page({
105 357 icon: 'none',
106 358 });
107 359 self.data.msg = res.data.msg;
  360 + // self.setData({
  361 + // bannerUrl: imghost + 'miniapp/images/luckDraw/bg.png?v=2',
  362 + // 'blocks[0].imgs[0].src': imghost + 'miniapp/images/luckDraw/weel.png?v=3', //转盘
  363 + // 'buttons[0].imgs[0].src': imghost + 'miniapp/images/luckDraw/pointer.png?v=3', //指针
  364 + // });
  365 +
108 366 };
109 367  
110 368 // console.log('luckInfo', res.data.data);
111 369 let luckInfo = res.data.data;
112 370  
  371 +
  372 +
  373 + self.setData({
  374 + 'imgDraw.views[3].text': self.data.luckInfo.act_name,//分享标题
  375 + // 'imgDraw.views[4].text': '快来一起抽奖吧,精美奖品等着你!',//分享内容
  376 + 'imgDraw.views[14].text': util.formar_no_full(luckInfo.begindate) + ' 至 ' + util.formar_no_full(luckInfo.enddate),//活动时间
  377 + });
  378 +
  379 +
  380 +
  381 + let luckStyle = null;
  382 +
113 383  
114 384 if(luckInfo && luckInfo.template_type != null && luckInfo.template_type == 1) { //获取模板
115   - let url = `/api/weshop/marketing/marketingLuckTemplate/get/${store_id}/${luckInfo.template_id}`;
  385 + let url = `/api/weshop/marketing/marketingLuckTemplate/get/0/${luckInfo.template_id}`;
116 386 app.request.get(url, {
117 387 success: function(res) {
118   - // console.log('prizes//////', res.data.data);
119   - self.setData({
120   - template: res.data.data,
121   - bannerUrl: imghost + ((res.data.data&&res.data.data.bannerUrl) ? res.data.data.bannerUrl:'miniapp/images/luckDraw/bg.png'), //背景图
122   - 'blocks[0].imgs[0].src': imghost + ((res.data.data&&res.data.data.wheelBaseUrl) ? res.data.data.wheelBaseUrl:'miniapp/images/luckDraw/weel.png'), //转盘
123   - 'buttons[0].imgs[0].src': imghost + ((res.data.data&&res.data.data.wheelPointerUrl) ? res.data.data.wheelPointerUrl:'miniapp/images/luckDraw/pointer.png'), //指针
124   - });
  388 + let template = null;
  389 + if(res.data.code == 0) {
  390 + template = res.data.data;
  391 + self.setData({
  392 + template,
  393 + bannerUrl: imghost + template.bannerUrl, //背景图
  394 + 'blocks[0].imgs[0].src': imghost + ((template&&template.wheelBaseUrl) ? template.wheelBaseUrl:'miniapp/images/luckDraw/weel.png?v=3'),
  395 + 'buttons[0].imgs[0].src': imghost + ((template&&template.wheelPointerUrl) ? template.wheelPointerUrl:'miniapp/images/luckDraw/pointer.png?v=3'), //指针
  396 + 'imgDraw.views[3].text': template.share_title ? template.share_title:self.data.luckInfo.act_name, //分享标题
  397 + 'imgDraw.views[5].url': imghost + (template&&template.share_image ? template.share_image:self.data.luckInfo.imageurl), //分享图片
  398 +
  399 + });
  400 +
  401 + let color = template&&template.colorCode ? template.colorCode:'#da104b';
  402 + luckStyle = `background: ${color} url(${self.data.bannerUrl}) no-repeat;`;
  403 + self.setData({
  404 + luckStyle,
  405 +
  406 + });
  407 + // self.setData({
  408 + // template: res.data.data,
  409 + // bannerUrl: imghost + res.data.data.bannerUrl, //背景图
  410 + // //bannerUrl: imghost + ((res.data.data&&res.data.data.bannerUrl) ? res.data.data.bannerUrl:'miniapp/images/luckDraw/bg.png?v=2'), //背景图
  411 + // 'blocks[0].imgs[0].src': imghost + res.data.data&&res.data.data.wheelBaseUrl) ? res.data.data.wheelBaseUrl:'miniapp/images/luckDraw/weel.png?v=2'), //转盘
  412 + // 'buttons[0].imgs[0].src': imghost + ((res.data.data&&res.data.data.wheelPointerUrl) ? res.data.data.wheelPointerUrl:'miniapp/images/luckDraw/pointer.png?v=2'), //指针
  413 + // 'imgDraw.views[3].text': (res.data.data&&res.data.data.title) ? res.data.data.title : self.data.luckInfo.act_name,//分享标题
  414 + // // 'imgDraw.views[4].text': (res.data.data&&res.data.data.share_content) ? res.data.data.share_content : '快来一起抽奖吧,精美奖品等着你!',//分享内容
  415 + // 'imgDraw.views[5].url': (res.data.data&&res.data.data.share_image) ? (imghost + res.data.data.share_image):(self.data.luckInfo.imageurl ? (imghost + self.data.luckInfo.imageurl):'/packpageB/images/luckDraw/jiang.png'),//分享图片
  416 + // 'imgDraw.views[14].text': util.formar_no_full(self.data.luckInfo.begindate) + ' 至 ' + util.formar_no_full(self.data.luckInfo.enddate),//活动时间
  417 + // });
  418 + } else {
  419 + luckStyle = `background: #da104b url(${imghost + 'miniapp/images/luckDraw/bg.png?v=2'}) no-repeat;`;
  420 + self.setData({
  421 + luckStyle,
  422 + 'imgDraw.views[5].url': self.data.luckInfo.imageurl ? (imghost + self.data.luckInfo.imageurl):'/packageB/images/luckDraw/jiang.png', //分享图片
  423 + 'blocks[0].imgs[0].src': imghost + 'miniapp/images/luckDraw/weel.png?v=3', //转盘
  424 + 'buttons[0].imgs[0].src': imghost + 'miniapp/images/luckDraw/pointer.png?v=3', //指针
  425 + });
  426 + // let color = template&&template.colorCode ? template.colorCode:'#da104b';
  427 +
  428 + // self.setData({
  429 + // luckStyle,
  430 + // });
  431 + };
  432 +
125 433 },
126 434 });
127 435 } else {
  436 +
  437 + if(luckInfo && luckInfo.imageurl) {
  438 + self.setData({
  439 + 'imgDraw.views[5].url': imghost + self.data.luckInfo.imageurl, //分享图片
  440 + });
  441 + };
  442 +
128 443 if(luckInfo && luckInfo.store_bannerUrl) {
129 444 self.setData({
130 445 bannerUrl: imghost + luckInfo.store_bannerUrl,
  446 + custom: true,
  447 + });
  448 + } else {
  449 + self.setData({
  450 + bannerUrl: imghost + 'miniapp/images/luckDraw/bg.png?v=2',
  451 + custom: false,
131 452 });
132 453 };
133   -
  454 +
  455 + let color = self.data.custom ? '#f0f0f0':'#da104b';
  456 + luckStyle = `background: ${color} url(${self.data.bannerUrl}) no-repeat;`;
  457 + self.setData({
  458 + luckStyle,
  459 + 'blocks[0].imgs[0].src': imghost + 'miniapp/images/luckDraw/weel.png?v=3', //转盘
  460 + 'buttons[0].imgs[0].src': imghost + 'miniapp/images/luckDraw/pointer.png?v=3', //指针
  461 + });
  462 +
134 463 };
135 464  
136 465  
... ... @@ -139,7 +468,6 @@ Page({
139 468 title: self.data.luckInfo.msgInfo,
140 469 icon: 'none',
141 470 });
142   - // return;
143 471 };
144 472  
145 473 },
... ... @@ -157,7 +485,7 @@ Page({
157 485 self.setData({
158 486 award,
159 487 });
160   - console.log('award', award);
  488 + // console.log('award', award);
161 489 self.prizeLayout(award);
162 490  
163 491 },
... ... @@ -178,8 +506,8 @@ Page({
178 506 self.setData({
179 507 record: res.data.data.pageData,
180 508 });
181   - };
182   - },
  509 + }
  510 + },
183 511 });
184 512  
185 513  
... ... @@ -201,10 +529,27 @@ Page({
201 529 },
202 530 });
203 531  
  532 +
  533 +
  534 +
204 535 };
205 536 };
206 537 },
207 538  
  539 + //获取小程序码
  540 + getMiniCode(objData) {
  541 + wx.getImageInfo({
  542 + src: `${objData.url}/api/wx/open/app/user/getWeAppEwm/${objData.store_id}?sceneValue=${objData.user_id}_${objData.id}&pageValue=pages/index/index/index`,
  543 + success (res) {
  544 + if(res.code != -1) {
  545 + self.setData({
  546 + 'imgDraw.views[16].url': res.path,
  547 + });
  548 + };
  549 + }
  550 + });
  551 + },
  552 +
208 553 // 设置转盘奖品布局
209 554 prizeLayout(award) {
210 555 let prizes = [];
... ... @@ -423,7 +768,6 @@ Page({
423 768 // 根据lbtype指定奖品类别图标
424 769 prizeSrc(lbtype) {
425 770 let src = '';
426   - // let imghost = this.data.imghost;
427 771 switch(lbtype) {
428 772 case 1: { //积分
429 773 src = imghost + 'miniapp/images/luckDraw/jf.png';
... ... @@ -493,129 +837,184 @@ Page({
493 837 return;
494 838 };
495 839  
496   -
497   - if(this.data.luckInfo.user_LuckNumDay > 0 || this.data.luckInfo.vip_act_num == 0) {
498   - // console.log('start choujiang');
499   - // let start = false;
500   - if(!this.data.start) {
501   - this.data.start = true;
502   - // 获取抽奖组件实例
503   - const $lucky = this.selectComponent('#myLucky');
504   - // 调用play方法开始旋转
505   - $lucky.play();
  840 + // 获取积分
  841 + app.request.promisePost('/api/weshop/marketing/marketingLuckForm/startLuckIntegral', {
  842 + isShowLoading: false,
  843 + data: {
  844 + storeId: app.globalData.setting.stoid,
  845 + userId: app.globalData.userInfo.user_id,
  846 + LuckId: this.data.options.id,
  847 + },
  848 + })
  849 + .then(function(res) {
  850 + if(res.data.code == -1) {
  851 + //积分不足,弹出提示
  852 + self.data.luckInfo.msgInfo = res.data.msg
  853 + wx.showToast({
  854 + title: res.data.msg,
  855 + icon: 'none',
  856 + });
  857 + return;
  858 + };
  859 +
  860 + if(res.data.code == 0) {
506 861  
507   - // 获取抽奖结果
508   - app.request.post('/api/weshop/marketing/marketingLuckForm/startLuck', {
509   - isShowLoading: false,
510   - data: {
511   - storeId: app.globalData.setting.stoid,
512   - userId: app.globalData.userInfo.user_id,
513   - LuckId: this.data.options.id,
514   - },
515   - success: function(res) {
  862 + if(self.data.luckInfo.user_LuckNumDay > 0 || self.data.luckInfo.vip_act_num == 0) {
  863 + // console.log('start choujiang');
  864 + // let start = false;
  865 + if(!self.data.start) {
  866 + self.data.start = true;
  867 + // 获取抽奖组件实例
  868 + const $lucky = self.selectComponent('#myLucky');
  869 + // 调用play方法开始旋转
  870 + $lucky.play();
516 871  
517   - if(res.data.code == 0) {
518   - console.log('开始摇奖', res.data.data);
519   - if(self.data.luckInfo.vip_act_num != 0) {
520   - self.setData({
521   - 'luckInfo.user_LuckNumDay': self.data.luckInfo.user_LuckNumDay - 1,
522   - // isActive: true,
523   - });
524   - };
525   -
526   - self.setData({
527   - // 'luckInfo.user_LuckNumDay': self.data.luckInfo.user_LuckNumDay - 1,
528   - isActive: true,
529   - });
530   - // console.log('请求成功', res.data.data);
531   - let luckyId = res.data.data.id;
532   - let indexArr = self.luckyIndex(self.data.prizes, luckyId);
533   - // console.log('抽奖奖品id', luckyId);
534   - // console.log('奖品列表', self.data.prizes);
535   - // console.log('奖品对应的索引数组', indexArr);
536   - let random = Math.random() * indexArr.length >> 0;
537   - // console.log('random', random);
538   - let index = indexArr[random];
539   - setTimeout(() => {
540   - $lucky.stop(index);
541   - self.data.start = false;
542   - }, 3000);
  872 + // 获取抽奖结果
  873 + app.request.post('/api/weshop/marketing/marketingLuckForm/startLuck', {
  874 + isShowLoading: false,
  875 + data: {
  876 + storeId: app.globalData.setting.stoid,
  877 + userId: app.globalData.userInfo.user_id,
  878 + LuckId: self.data.options.id,
  879 + },
  880 + success: function(res) {
  881 +
  882 + if(res.data.code == 0) {
  883 + // console.log('开始摇奖', res.data.data);
  884 + if(self.data.luckInfo.vip_act_num != 0) {
  885 + self.setData({
  886 + 'luckInfo.user_LuckNumDay': self.data.luckInfo.user_LuckNumDay - 1,
  887 + // isActive: true,
  888 + });
  889 + };
  890 +
  891 + self.setData({
  892 + // 'luckInfo.user_LuckNumDay': self.data.luckInfo.user_LuckNumDay - 1,
  893 + isActive: true,
  894 + wow: res.data.data,
  895 + });
  896 + // console.log('wow', self.data.wow);
  897 + // console.log('请求成功', res.data.data);
  898 + let luckyId = res.data.data.id;
  899 + let indexArr = self.luckyIndex(self.data.prizes, luckyId);
  900 + // console.log('抽奖奖品id', luckyId);
  901 + // console.log('奖品列表', self.data.prizes);
  902 + // console.log('奖品对应的索引数组', indexArr);
  903 + let random = Math.random() * indexArr.length >> 0;
  904 + // console.log('random', random);
  905 + let index = indexArr[random];
  906 + setTimeout(() => {
  907 + $lucky.stop(index);
  908 + self.data.start = false;
  909 + }, 3000);
  910 +
  911 +
  912 + //获取兑奖记录
  913 + // app.request.get('/api/weshop/marketing/marketingLuckRecord/page', {
  914 + // isShowLoading: false,
  915 + // data: {
  916 + // store_id: app.globalData.setting.stoid,
  917 + // user_id: app.globalData.userInfo.user_id,
  918 + // luck_formid: self.data.options.id,
  919 + // luck_state: 1
  920 + // },
  921 + // success: function(res) {
  922 + // if(res.data.code == 0) {
  923 + // // console.log('res===>', res.data.data.pageData);
  924 + // self.setData({
  925 + // record: res.data.data.pageData,
  926 + // });
  927 + // };
  928 + // },
  929 + // });
  930 +
  931 +
  932 + } else {
  933 + let thxIndexArr = self.data.thxIndexArr;
  934 + const random = Math.random() * thxIndexArr.length >> 0;
  935 + const index = thxIndexArr[random];
  936 + // console.log('谢谢参与数组', thxIndexArr);
  937 + // console.log('请求出错产生谢谢参与的随机数', index);
  938 + setTimeout(() => {
  939 + $lucky.stop(index);
  940 + self.data.start = false;
  941 + }, 3000);
  942 +
  943 +
  944 +
  945 +
  946 + if(res.data.code == -1) {
  947 + wx.showToast({
  948 + title: res.data.msg,
  949 + icon: 'none',
  950 + });
  951 + self.data.luckInfo.msgInfo = res.data.msg;
  952 + return;
  953 + // self.data.start = true;
  954 + };
  955 +
  956 +
  957 + if(res.data.code == -2 && self.data.luckInfo.vip_act_num != 0) {
  958 + self.setData({
  959 + 'luckInfo.user_LuckNumDay': self.data.luckInfo.user_LuckNumDay - 1,
  960 + });
  961 + };
  962 +
  963 +
  964 + };
  965 +
543 966  
  967 + },
544 968  
545   - //获取兑奖记录
546   - // app.request.get('/api/weshop/marketing/marketingLuckRecord/page', {
547   - // isShowLoading: false,
548   - // data: {
549   - // store_id: app.globalData.setting.stoid,
550   - // user_id: app.globalData.userInfo.user_id,
551   - // luck_formid: self.data.options.id,
552   - // luck_state: 1
553   - // },
554   - // success: function(res) {
555   - // if(res.data.code == 0) {
556   - // // console.log('res===>', res.data.data.pageData);
557   - // self.setData({
558   - // record: res.data.data.pageData,
559   - // });
560   - // };
561   - // },
562   - // });
  969 + fail: function(res) {
  970 + // console.log('出错');
  971 + wx.showToast({
  972 + title: '数据请求失败',
  973 + icon: 'error',
  974 + });
  975 + let thxIndexArr = self.data.thxIndexArr;
  976 + const random = Math.random() * thxIndexArr.length >> 0;
  977 + const index = thxIndexArr[random];
  978 + setTimeout(() => {
  979 + $lucky.stop(index);
  980 + self.data.start = false;
  981 + }, 3000);
  982 + },
563 983  
564 984  
565   - } else {
566   - // console.log('请求出错');
567   - if(self.data.luckInfo.vip_act_num != 0) {
568   - self.setData({
569   - 'luckInfo.user_LuckNumDay': self.data.luckInfo.user_LuckNumDay - 1,
570   - });
571   - };
572 985  
573   - let thxIndexArr = self.data.thxIndexArr;
574   - const random = Math.random() * thxIndexArr.length >> 0;
575   - const index = thxIndexArr[random];
576   - // console.log('谢谢参与数组', thxIndexArr);
577   - // console.log('请求出错产生谢谢参与的随机数', index);
578   - setTimeout(() => {
579   - $lucky.stop(index);
580   - self.data.start = false;
581   - }, 3000);
582   - };
583   - },
584   -
585   - fail: function(res) {
586   - // console.log('出错');
587   - wx.showToast({
588   - title: '数据请求失败',
589   - icon: 'error',
590 986 });
591   - let thxIndexArr = self.data.thxIndexArr;
592   - const random = Math.random() * thxIndexArr.length >> 0;
593   - const index = thxIndexArr[random];
594   - setTimeout(() => {
595   - $lucky.stop(index);
596   - self.data.start = false;
597   - }, 3000);
598   - },
  987 +
  988 + }
599 989  
600   - });
  990 +
  991 + } else {
  992 + wx.showToast({
  993 + title: '你今天的抽奖次数已用完啦!~',
  994 + icon: 'none',
  995 + });
  996 + };
601 997  
602   - }
603   -
604   -
605   - } else {
606   - wx.showToast({
607   - title: '你今天的抽奖次数已用完啦!~',
608   - icon: 'none',
609   - });
610   - };
  998 + };
  999 + });
  1000 +
  1001 +
  1002 +
  1003 +
  1004 +
611 1005  
612 1006 },
613 1007 end (event) {
614 1008 // 中奖奖品详情
615   - // console.log('zjiangla~~',event.detail.lbtype);
  1009 + console.log('抽奖结果:',event.detail);
616 1010 let no_luck_urltype = this.data.luckInfo.no_luck_urltype;
617   - let lbtype;
  1011 + let lbtype = null;
  1012 + // let good_id = null;
618 1013 let resultTitle = event.detail.fonts[0].text.replace('\n','');
  1014 + // if(event.detail.id) {
  1015 + // console.log('~~~~~~----++++++',event.detail.id);
  1016 + // good_id = event.detail.id;
  1017 + // };
619 1018 if(event.detail.lbtype == 5) {
620 1019 lbtype = 5;
621 1020 } else {
... ... @@ -627,13 +1026,15 @@ Page({
627 1026 showResult: true,
628 1027 showMask: true,
629 1028 resultTitle,
  1029 + showPopup: false,
630 1030 currentLbtype: lbtype,
  1031 + // good_id,
631 1032 });
632 1033  
633 1034  
634 1035  
635 1036  
636   - if(no_luck_urltype == 1) {
  1037 + if(no_luck_urltype == 1 && resultTitle == '谢谢参与') {
637 1038 if(this.data.luckInfo.no_luck_weappurl) {
638 1039 let num = this.data.num;
639 1040 let url = this.data.luckInfo.no_luck_weappurl;
... ... @@ -649,8 +1050,47 @@ Page({
649 1050 }, 1000);
650 1051  
651 1052 };
  1053 +
  1054 + };
  1055 +
  1056 +
  1057 + if(self.data.luckInfo.give_user) {
  1058 + if(resultTitle == '谢谢参与') {
  1059 + if(self.data.luckInfo.give_type == 1) {
  1060 + if(self.data.luckInfo.give_integral > 0) {
  1061 + wx.showToast({
  1062 + title: `获得游戏奖励积分${self.data.luckInfo.give_integral}`,
  1063 + icon: 'none',
  1064 + });
  1065 + };
  1066 + } else if((self.data.luckInfo.give_type == 2)) {
  1067 + if(self.data.luckInfo.give_growth > 0) {
  1068 + wx.showToast({
  1069 + title: `获得游戏奖励成长值${self.data.luckInfo.give_growth}`,
  1070 + icon: 'none',
  1071 + });
  1072 + };
  1073 + };
  1074 + };
  1075 + } else {
  1076 + if(self.data.luckInfo.give_type == 1) {
  1077 + if(self.data.luckInfo.give_integral > 0) {
  1078 + wx.showToast({
  1079 + title: `获得游戏奖励积分${self.data.luckInfo.give_integral}`,
  1080 + icon: 'none',
  1081 + });
  1082 + };
  1083 + } else if((self.data.luckInfo.give_type == 2)) {
  1084 + if(self.data.luckInfo.give_growth > 0) {
  1085 + wx.showToast({
  1086 + title: `获得游戏奖励成长值${self.data.luckInfo.give_growth}`,
  1087 + icon: 'none',
  1088 + });
  1089 + };
  1090 + };
652 1091 };
653 1092  
  1093 +
654 1094 },
655 1095  
656 1096 showPopup() {
... ... @@ -786,6 +1226,14 @@ Page({
786 1226 goto(e) {
787 1227 let url = '';
788 1228 let type = e.currentTarget.dataset.type;
  1229 + let ordersn = null;
  1230 + let buyreceive_id = null;
  1231 + if(e.currentTarget.dataset.ordersn) {
  1232 + ordersn = e.currentTarget.dataset.ordersn;
  1233 + };
  1234 + if(e.currentTarget.dataset.buyreceiveid) {
  1235 + buyreceive_id = e.currentTarget.dataset.buyreceiveid;
  1236 + };
789 1237 switch(type) {
790 1238 case 1: {
791 1239 url = '/pages/user/integral/integral';
... ... @@ -804,7 +1252,7 @@ Page({
804 1252 break;
805 1253 };
806 1254 case 6: {
807   - url = '/packageA/pages/myGift/myGift';
  1255 + url = `/pages/giftpack/giftpacklist/giftpacklist?isBuy=0&orderSn=${ordersn}&lbId=${buyreceive_id}`;
808 1256 break;
809 1257 };
810 1258 };
... ... @@ -812,20 +1260,30 @@ Page({
812 1260 },
813 1261  
814 1262 showQr(e) {
  1263 + let id = null;
815 1264 let store_id = app.globalData.setting.stoid;
816   - let id = e.currentTarget.dataset.id;
  1265 + if(e && e.currentTarget.dataset.id) {
  1266 + id = e.currentTarget.dataset.id;
  1267 + } else {
  1268 + id = this.data.wow.record_id;
  1269 + };
817 1270 let url = `/api/weshop/marketing/marketingLuckList/updateGoodsVerifyCode/${store_id}/${id}`;
  1271 + // console.log('good_id', id, url);
818 1272 app.request.put(url, {
819 1273 success: function(res) {
820 1274 if(res.data.code == 0) {
821 1275 let data = res.data.data;
822   - console.log('data!!!!', data);
823 1276 let barcode = self.selectComponent("#qrcode");
824 1277 barcode.open({val: data});
825 1278 self.setData({
826 1279 hiddenCanvas: true,
827 1280 showPopup: false,
828 1281 });
  1282 + } else {
  1283 + wx.showToast({
  1284 + title: res.data.msg,
  1285 + icon: 'none',
  1286 + });
829 1287 };
830 1288 },
831 1289  
... ... @@ -843,6 +1301,39 @@ Page({
843 1301 this.setData({
844 1302 showResult: false,
845 1303 });
846   - this.showPopup();
  1304 + this.showQr();
  1305 + },
  1306 +
  1307 + showPoster() {
  1308 + wx.showLoading({
  1309 + title: '生成海报中',
  1310 + });
  1311 + setTimeout(function() {
  1312 + self.setData({
  1313 + hiddenCanvas: true,
  1314 + showMask: true,
  1315 + showPoster: true,
  1316 + });
  1317 + wx.hideLoading();
  1318 + }, 3000)
  1319 +
  1320 +
  1321 + },
  1322 +
  1323 + closePoster() {
  1324 + this.setData({
  1325 + showMask: false,
  1326 + showPoster: false,
  1327 + hiddenCanvas: false,
  1328 + });
  1329 + },
  1330 +
  1331 +
  1332 +
  1333 + onImgOK(e) {
  1334 + this.setData({
  1335 + myimg: e.detail.path,
  1336 + });
847 1337 },
  1338 +
848 1339 })
849 1340 \ No newline at end of file
... ...
packageB/pages/luckactivity/luckinfo/luckinfo.json
... ... @@ -2,7 +2,8 @@
2 2 "usingComponents": {
3 3 "lucky-wheel":"/packageB/miniprogram_npm/mini-luck-draw/lucky-wheel/index",
4 4 "qrcode": "/components/my-qrcode/my-qrcode",
5   - "nodata": "/components/nodata/nodata"
  5 + "nodata": "/components/nodata/nodata",
  6 + "painter": "/packageB/components/painter/painter"
6 7 },
7 8 "enablePullDownRefresh": false,
8 9 "navigationBarTitleText": "幸运大转盘"
... ...
packageB/pages/luckactivity/luckinfo/luckinfo.wxml
1 1 <wxs module="filter" src="../../../../utils/filter.wxs"></wxs>
2 2 <wxs module="tool" src="./tool.wxs"></wxs>
3   -<view class="luck-container" style="background: {{template.colorCode ? template.colorCode:'#8102FD'}} url({{bannerUrl ? bannerUrl:(imghost + 'miniapp/images/luckDraw/bg.png')}}) no-repeat;">
4   -<!-- <view class="luck-container" style="background: url({{ bannerUrl}}) no-repeat;"> -->
  3 +<view class="luck-container {{!template&&custom ? 'on':''}}" style="{{luckStyle}}">
  4 +<!-- <view class="luck-container {{!template&&custom ? 'on':''}}" style="background: {{template&&template.colorCode ? template.colorCode:(custom ? '#f0f0f0':'#da104b')}} url({{bannerUrl ? bannerUrl:''}}) no-repeat;"> -->
5 5 <!-- 中奖人员 -->
6 6 <view class="swiper-container" wx:if="{{nameList && nameList.length != 0}}">
7 7 <swiper class="swiper" autoplay="true" circular="true" vertical="true" interval="3000">
... ... @@ -36,17 +36,17 @@
36 36 hiddenCanvas="{{hiddenCanvas}}"
37 37 />
38 38 </view>
39   - <view class="fs28 white t-c pdt10" wx:if="{{luckInfo.vip_act_num == 0}}">今天你有 <text class="fs50 c-yellow">不限次</text> 抽奖机会</view>
40   - <view class="fs28 white t-c pdt10" wx:else>今天你还有 <text class="fs50 c-yellow">{{filter.show_default(luckInfo.user_LuckNumDay, '0')}}</text> 次抽奖机会</view>
  39 + <view class="weel-txt fs28 white t-c pdt10" wx:if="{{luckInfo.vip_act_num == 0}}">今天你有 <text class="fs50 c-yellow cs">不限次</text> 抽奖机会</view>
  40 + <view class="weel-txt fs28 white t-c pdt10" wx:else>今天你还有 <text class="fs50 c-yellow cs">{{filter.show_default(luckInfo.user_LuckNumDay < 0 ? 0:luckInfo.user_LuckNumDay, '0')}}</text> 次抽奖机会</view>
41 41 <view class="tip-to-down expand-transition">
42 42 <text></text>
43 43 <text></text>
44 44 </view>
45 45 </view>
46 46 <!-- 奖品展示 -->
47   - <view wx:if="{{award}}">
  47 + <view wx:if="{{award && award.length != 0}}">
48 48 <view class="badge-container"><image src="{{imghost + 'miniapp/images/luckDraw/badge.png'}}" class="badge prizes" lazy-load></image></view>
49   - <view class="list br12 bg-white">
  49 + <view class="panel list br12 bg-white">
50 50 <view class="list-item" wx:for="{{award}}">
51 51 <view class="img-container">
52 52 <image wx:if="{{item.luck_goods_img}}" src="{{imghost + item.luck_goods_img}}" class="img" mode="aspectFit"></image>
... ... @@ -63,28 +63,24 @@
63 63 </view>
64 64 </view>
65 65 <!-- 活动展示 -->
66   - <view wx:if="{{luckInfo.remark}}">
  66 + <view>
67 67 <view class="badge-container"><image src="{{imghost + 'miniapp/images/luckDraw/badge.png'}}" class="badge activity" lazy-load></image></view>
68   - <view class="bg-white br12 pd20 fs28">
  68 + <view class="panel bg-white br12 pd20 fs28">
69 69 <!-- {{luckInfo.remark}} -->
70 70 <import src="../../../../utils/wxParse/wxParse.wxml"/>
71   - <template is="wxParse" data="{{wxParseData:content.nodes}}"/>
  71 + <!-- <template is="wxParse" data="{{wxParseData:content.nodes}}"/> -->
72 72 <!-- 时间 -->
73   - <!-- <view class="bdb">
74   - <view class="">
  73 + <view class="bdt">
  74 + <!-- <view class=""> -->
75 75 <view class="txt-red">活动时间:</view>
76   - <view class="fs28 pdv20">187606546456</view>
77   - </view>
78   - <view>
79   - <view class="txt-red">兑换时间:</view>
80   - <view class="fs28 pdv20">-</view>
81   - </view>
82   - </view> -->
  76 + <view class="fs28 pdv20">{{filter.format_time(luckInfo.begindate, 1) + ' 至 ' + filter.format_time(luckInfo.enddate, 1)}}</view>
  77 + <!-- </view> -->
  78 + </view>
83 79 <!-- 规则 -->
84   - <!-- <view class="bdb">
85   - <view class="txt-red pdt20">活动规则:</view>
86   - <view class="fs28 pdv20">-</view>
87   - </view> -->
  80 + <view class="bdt" wx:if="{{luckInfo.remark}}">
  81 + <view class="txt-red pdt20">活动说明:</view>
  82 + <view class="fs28 pdv20"><template is="wxParse" data="{{wxParseData:content.nodes}}"/></view>
  83 + </view>
88 84 <!-- 电话 -->
89 85 <!-- <view class="bdb">
90 86 <view class="txt-red pdt20">联系电话:</view>
... ... @@ -121,14 +117,17 @@
121 117 </view>
122 118 </view> -->
123 119 <!-- 技术支持 -->
124   - <view class="t-c">
  120 + <view class="logo-container t-c">
125 121 <!-- <view class="pdt20 fs26 text-underline">帮美店免费开通这个玩法</view> -->
126   - <view class="flex ai_c fs24 jc-center pdv20 white"><image src="{{imghost + 'miniapp/images/luckDraw/logo.png'}}" class="logo" lazy-load></image>提供技术支持</view>
  122 + <view class="flex ai_c fs24 jc-center pdv20 white"><image src="{{imghost + 'miniapp/images/luckDraw/logo.png?v=3'}}" class="logo" lazy-load></image>提供技术支持</view>
127 123 </view>
128 124 </view>
129 125  
  126 +<!-- 分享按钮 -->
  127 +<view class="circle-container zhuanfa" bindtap="showPoster"><text class="iconfont icon-zhuanfa1"></text></view>
  128 +
130 129 <!-- 悬浮按钮 -->
131   -<view class="gift-container {{((record && record.length != 0) || isActive) ? 'active':''}}" bindtap="showPopup"><text class="iconfont icon-liwu"></text></view>
  130 +<view class="circle-container gift {{((record && record.length != 0) || isActive) ? 'active':''}}" bindtap="showPopup"><text class="iconfont icon-liwu"></text></view>
132 131  
133 132 <!-- 弹窗 -->
134 133 <view class="popup-container" wx:if="{{showPopup}}">
... ... @@ -142,10 +141,11 @@
142 141 <view class="ellipsis-2 fs28">{{item.luck_name}}</view>
143 142 <view class="pdt20">
144 143 <view class="fs26 xc-black3">价值:<text class="rmb">{{item.luck_goods_price}}</text></view>
145   - <view class="flex ai_c jc_fe fs26 xc-black3 ">
  144 + <view class="flex ai_c {{item.luck_type == 5 ? 'jc_sb':'jc_fe'}} fs26 xc-black3 ">
146 145 <!-- <view style="visibility: {{item.luck_type == 5 ? 'visible':'hidden'}};">兑换状态:{{item.state == 0 ? '未兑换':'已兑换'}}</view> -->
147 146 <!-- <view style="">兑换状态:{{item.state == 0 ? '未兑换':'已兑换'}}</view> -->
148   - <view class="btn" bindtap="{{item.luck_type == 5 ? (item.state == 0 ? 'showQr':''):'goto'}}" data-type="{{item.luck_type}}" data-id="{{item.id}}">{{item.luck_type == 5 ? (item.state == 1 ? '已兑换':'兑换'):'查看'}}</view>
  147 + <view class="fs24 c-a" wx:if="{{item.luck_type == 5}}">兑换截止时间:{{filter.show_default(item.changeDate, '不限')}}</view>
  148 + <view class="btn" bindtap="{{item.luck_type == 5 ? (item.state == 0 ? 'showQr':''):'goto'}}" data-type="{{item.luck_type}}" data-id="{{item.id}}" data-ordersn="{{item.order_sn}}" data-buyreceiveid="{{item.buyreceive_id}}">{{item.luck_type == 5 ? (item.state == 1 ? '已兑换':'兑换'):'查看'}}</view>
149 149 </view>
150 150 </view>
151 151 </view>
... ... @@ -164,25 +164,45 @@
164 164 <block wx:if="{{resultTitle == '谢谢参与'}}">
165 165 <view class="bold c-tb fs40">{{luckInfo.no_luck_name}}</view>
166 166 <view class="pdt10">{{luckInfo.no_luck_remark}}</view>
167   - <view class="img-container2"><image src="{{imghost + (luckInfo.no_luck_img ? luckInfo.no_luck_img:'miniapp/images/luckDraw/gift.png')}}" class="img" mode="aspectFit"></image></view>
168   - <view class="pdt40 fs26 c9" wx:if="{{luckInfo.no_luck_urltype == 1 && luckInfo.no_luck_weappurl}}">{{num}}s后自动跳转...</view>
  167 + <view class="img-container2"><image src="{{imghost + (luckInfo.no_luck_img ? luckInfo.no_luck_img:'/miniapp/images/luckDraw/nolockimg.png')}}" class="img" mode="aspectFit" lazy-load></image></view>
  168 + <view class="pdt40 fs26 c9 t-c" wx:if="{{(luckInfo.no_luck_urltype == 1) && luckInfo.no_luck_weappurl}}">{{num}}s后自动跳转...</view>
169 169 </block>
170 170 <block wx:else>
171 171 <view class="bold c-tb fs40">恭喜你获得</view>
172 172 <view class="pdt10">{{resultTitle}} </view>
173   - <view class="img-container2"><image src="{{imghost + 'miniapp/images/luckDraw/gift.png'}}" class="img" mode="aspectFit"></image></view>
  173 + <view class="img-container2">
  174 + <!-- <image src="{{imghost + 'miniapp/images/luckDraw/gift.png'}}" class="img" mode="aspectFit"></image> -->
  175 + <image wx:if="{{wow.luck_goods_img}}" src="{{imghost + wow.luck_goods_img}}" class="img" mode="aspectFit" lazy-load></image>
  176 + <image src="{{imghost + tool.showDefaultImg(wow.lbtype)}}" class="img" mode="aspectFit" lazy-load wx:else></image>
  177 + </view>
174 178 </block>
175 179 </view>
176 180  
177 181 <view class="pdt40" wx:if="{{currentLbtype == 5}}">
178   - <view class="btn btn2" bindtap="clickReceive">立即领取</view>
  182 + <view class="btn btn2" bindtap="clickReceive">立即兑换</view>
179 183 </view>
  184 +
  185 +
180 186 <!-- <view class="note">注:未领取就关闭弹窗视为主动放弃奖品。</view> -->
181 187 </view>
182 188 </view>
183 189  
184 190  
  191 +<!-- 海报 -->
  192 + <view class="poster-container" hidden="{{!showPoster}}">
  193 + <view class="t-r pdb20 white2"><text class="iconfont icon-close fs40" bindtap="closePoster"></text></view>
  194 + <image src="{{myimg}}" class="poster" show-menu-by-longpress lazy-load></image>
  195 + <view class="pdt10 fs26 white2"><text class="iconfont icon-zhiwen"></text> 长按图片保存至相册</view>
  196 + </view>
  197 +
  198 +
185 199 <!-- 遮罩层 -->
186 200 <view class="mask" wx:if="{{showMask}}"></view>
187 201  
188   -<qrcode id="qrcode" bind:close="closeQr"></qrcode>
189 202 \ No newline at end of file
  203 +<!-- 遮罩层2 -->
  204 +<!-- <cover-view class="mask2"></cover-view> -->
  205 +
  206 +<qrcode id="qrcode" bind:close="closeQr"></qrcode>
  207 +
  208 +
  209 +<painter style="position: absolute; top: -9999rpx;" palette="{{imgDraw}}" bind:imgOK="onImgOK"/>
190 210 \ No newline at end of file
... ...
packageB/pages/luckactivity/luckinfo/luckinfo.wxss
... ... @@ -13,7 +13,7 @@ page,
13 13  
14 14 .luck-container {
15 15 background-size: 100% auto !important;
16   - padding: 50% 20rpx 0;
  16 + padding: 42% 20rpx 0;
17 17 }
18 18  
19 19 .weel-container {
... ... @@ -68,7 +68,7 @@ page,
68 68 width: 140rpx;
69 69 height: 140rpx;
70 70 margin-right: 20rpx;
71   - background-color: #f5f5f5;
  71 + /* background-color: #f5f5f5; */
72 72 }
73 73  
74 74 .img {
... ... @@ -113,12 +113,12 @@ page,
113 113 }
114 114  
115 115 .logo {
116   - width: 120rpx;
117   - height: 40rpx;
  116 + width: 132rpx;
  117 + height: 37rpx;
118 118 margin-right: 10rpx;
119 119 }
120 120  
121   -.gift-container {
  121 +.circle-container {
122 122 background-color: rgba(44, 44, 44, 0.2);
123 123 width: 100rpx;
124 124 height: 100rpx;
... ... @@ -126,14 +126,21 @@ page,
126 126 color: white;
127 127 position: fixed;
128 128 right: 20rpx;
129   - bottom: 20rpx;
130 129 display: flex;
131 130 justify-content: center;
132 131 align-items: center;
133 132 z-index: 1;
134 133 }
135 134  
136   -.gift-container.active::after {
  135 +.circle-container.gift {
  136 + bottom: 20rpx;
  137 +}
  138 +
  139 +.circle-container.zhuanfa {
  140 + bottom: 160rpx;
  141 +}
  142 +
  143 +.circle-container.active::after {
137 144 content: '';
138 145 position: absolute;
139 146 width: 14rpx;
... ... @@ -145,7 +152,8 @@ page,
145 152 right: 10rpx;
146 153 }
147 154  
148   -.icon-liwu {
  155 +.icon-liwu,
  156 +.icon-zhuanfa1 {
149 157 font-size: 40rpx;
150 158 }
151 159  
... ... @@ -161,7 +169,7 @@ page,
161 169 width: 6rem;
162 170 z-index: 2;
163 171 -webkit-transform: translate(0, -50%); */
164   - transform: translate(0, -50%);
  172 + /* transform: translate(0, -50%); */
165 173 /* color: #fff;
166 174 font: normal 400 20px/1 'Josefin Sans', sans-serif;
167 175 letter-spacing: .1em;
... ... @@ -175,9 +183,10 @@ page,
175 183 left: 50%;
176 184 width: 1rem;
177 185 height: 1rem;
178   - margin-left: -12px;
179   - border-left: 1px solid #fff;
180   - border-bottom: 1px solid #fff;
  186 + /* transform: translateX(-50%); */
  187 + margin-left: -13rpx;
  188 + border-left: 2rpx solid #fff;
  189 + border-bottom: 2rpx solid #fff;
181 190 -webkit-transform: rotate(-45deg);
182 191 transform: rotate(-45deg);
183 192 -webkit-animation: sdb07 2s infinite;
... ... @@ -190,7 +199,7 @@ page,
190 199 animation-delay: 0s;
191 200 }
192 201 .tip-to-down text:nth-of-type(2) {
193   - top: 16px;
  202 + top: 32rpx;
194 203 -webkit-animation-delay: .15s;
195 204 animation-delay: .15s;
196 205 }
... ... @@ -311,9 +320,7 @@ page,
311 320 color: #ff2d4b;
312 321 }
313 322  
314   -.bdb {
315   - border-bottom: 2rpx solid #ebedf0;
316   -}
  323 +
317 324  
318 325 .c-yellow {
319 326 color: yellow;
... ... @@ -327,7 +334,7 @@ page,
327 334 width: 100%;
328 335 height: 100%;
329 336 top: 0;
330   - background-color: rgba(0,0,0,.5);
  337 + background-color: rgba(0,0,0,.7);
331 338 z-index: 1;
332 339 }
333 340  
... ... @@ -427,4 +434,53 @@ page,
427 434 color: #FFE12F;
428 435 padding: 0 10rpx;
429 436 }
  437 +.bdt:only-child {
  438 + border-top: none;
  439 +}
  440 +.bdt ~ .bdt {
  441 + border-top: 2rpx solid #ebedf0;
  442 +}
  443 +
  444 +.poster-container {
  445 + text-align: center;
  446 + color: white;
  447 + position: fixed;
  448 + top: 50%;
  449 + left: 50%;
  450 + transform: translate(-50%, -50%);
  451 + z-index: 9;
  452 +}
  453 +
  454 +.poster {
  455 + width: 620rpx;
  456 + height: 995rpx;
  457 + /* border-radius: 16rpx; */
  458 + margin: 0 auto;
  459 + /* background-color: pink; */
  460 +}
  461 +
  462 +
  463 +.luck-container.on .weel-txt {
  464 + color: black;
  465 +}
  466 +
  467 +.luck-container.on .badge,
  468 +.luck-container.on .logo-container,
  469 +.luck-container.on .tip-to-down {
  470 + -webkit-filter: brightness(60%);
  471 + filter: brightness(60%);
  472 +}
  473 +
  474 +.luck-container.on .panel {
  475 + box-shadow: 0 0 24rpx #e7e9eb;
  476 +}
  477 +
  478 +.luck-container.on .cs {
  479 + color: #ff5000;
  480 +}
  481 +
  482 +
  483 +
  484 +
  485 +
430 486  
... ...
packageB/pages/user/binding_info/binding_info.js 0 → 100644
  1 +// packageB/pages/user/binding_info/binding_info.js
  2 +Page({
  3 +
  4 + /**
  5 + * 页面的初始数据
  6 + */
  7 + data: {
  8 +
  9 + },
  10 +
  11 + /**
  12 + * 生命周期函数--监听页面加载
  13 + */
  14 + onLoad: function (options) {
  15 +
  16 + },
  17 +
  18 + /**
  19 + * 生命周期函数--监听页面初次渲染完成
  20 + */
  21 + onReady: function () {
  22 +
  23 + },
  24 +
  25 + /**
  26 + * 生命周期函数--监听页面显示
  27 + */
  28 + onShow: function () {
  29 +
  30 + },
  31 +
  32 + /**
  33 + * 生命周期函数--监听页面隐藏
  34 + */
  35 + onHide: function () {
  36 +
  37 + },
  38 +
  39 + /**
  40 + * 生命周期函数--监听页面卸载
  41 + */
  42 + onUnload: function () {
  43 +
  44 + },
  45 +
  46 + /**
  47 + * 页面相关事件处理函数--监听用户下拉动作
  48 + */
  49 + onPullDownRefresh: function () {
  50 +
  51 + },
  52 +
  53 + /**
  54 + * 页面上拉触底事件的处理函数
  55 + */
  56 + onReachBottom: function () {
  57 +
  58 + },
  59 +
  60 + /**
  61 + * 用户点击右上角分享
  62 + */
  63 + onShareAppMessage: function () {
  64 +
  65 + }
  66 +})
0 67 \ No newline at end of file
... ...
packageB/pages/user/binding_info/binding_info.json 0 → 100644
  1 +{
  2 + "usingComponents": {}
  3 +}
0 4 \ No newline at end of file
... ...
packageB/pages/user/binding_info/binding_info.wxml 0 → 100644
  1 +<!--packageB/pages/user/binding_info/binding_info.wxml-->
  2 +<text>packageB/pages/user/binding_info/binding_info.wxml</text>
... ...
packageB/pages/user/binding_info/binding_info.wxss 0 → 100644
  1 +/* packageB/pages/user/binding_info/binding_info.wxss */
0 2 \ No newline at end of file
... ...
packageB/pages/zuhegou/index/index.js 0 → 100644
  1 +const app = getApp();
  2 +let self = null;
  3 +var os = app.globalData.setting;
  4 +var ut = require("../../../../utils/util.js");
  5 +var oo = app.globalData;
  6 +
  7 +
  8 +let imgDraw = {
  9 + "width": "650px",
  10 + "height": "843px",
  11 + "background": "https://mshopimg.yolipai.net/miniapp/images/zhg/bg-zuhegou.jpg",
  12 + "views": [
  13 + { // 头像
  14 + "type": "image",
  15 + "url": "https://desk-fd.zol-img.com.cn/t_s960x600c5/g5/M00/0F/08/ChMkJlauzXWIDrXBAAdCg2xP7oYAAH9FQOpVAIAB0Kb342.jpg",
  16 + "css": {
  17 + "width": "100px",
  18 + "height": "100px",
  19 + "top": "20px",
  20 + "left": "275px",
  21 + "borderRadius": "100px",
  22 + "mode": "scaleToFill",
  23 + "borderWidth": "2px",
  24 + "borderColor": "#fff",
  25 + }
  26 + },
  27 + { //昵称
  28 + "type": "text",
  29 + "text": "我是店铺名",
  30 + "css": {
  31 + "width": "650px",
  32 + "color": "#fff",
  33 + "top": "136px",
  34 + // "left": "137px",
  35 + "textAlign": "center",
  36 + "fontSize": "26px",
  37 + "maxLines": "1",
  38 + }
  39 + },
  40 + { //10元任选3件
  41 + "type": "text",
  42 + "text": "10元任选3件",
  43 + "css": {
  44 + "color": "#fff",
  45 + "width": "650px",
  46 + "top": "270px",
  47 + "fontSize": "70px",
  48 + "maxLines": "1",
  49 + "textAlign": "center",
  50 + "fontWeight": "bold",
  51 + }
  52 + },
  53 + { //活动时间
  54 + "type": "text",
  55 + "text": "活动时间:2021.07.06 - 2021.07.08",
  56 + "css": {
  57 + "color": "#333",
  58 + "width": "650px",
  59 + "top": "440px",
  60 + "fontSize": "26px",
  61 + "fontWeight": "normal",
  62 + "maxLines": "1",
  63 + "textAlign": "center"
  64 + }
  65 + },
  66 + { // 码
  67 + "type": "image",
  68 + "url": "https://desk-fd.zol-img.com.cn/t_s960x600c5/g5/M00/0F/08/ChMkJlauzXWIDrXBAAdCg2xP7oYAAH9FQOpVAIAB0Kb342.jpg",
  69 + "css": {
  70 + "color": "#000",
  71 + "width": "200px",
  72 + "height": "200px",
  73 + "top": "525px",
  74 + "left": "225px",
  75 + }
  76 + },
  77 + { // 扫码提示
  78 + "type": "text",
  79 + "text": "长按扫码即可参与活动",
  80 + "css": {
  81 + "color": "#666",
  82 + "width": "650px",
  83 + "top": "750px",
  84 + "fontSize": "26px",
  85 + "textAlign": "center"
  86 + }
  87 + },
  88 + ]
  89 +};
  90 +
  91 +
  92 +Page({
  93 +
  94 + /**
  95 + * 页面的初始数据
  96 + */
  97 + data: {
  98 + iurl: os.imghost,
  99 + showRule: false,
  100 + showMask: false,
  101 + showNum: false,
  102 + haveAdded: false,
  103 + //imgDraw: imgDraw, 分享内容
  104 + id: 0, //获得活动id
  105 + page: 1, //第一页
  106 + no_more: 0, //没有更多
  107 + loading: 0, //加载中
  108 + list: [], //商品列表的显示
  109 + act: null, //组合活动
  110 + all_price: 0, //合计价格
  111 + all_num: 0, //全部数量
  112 + sele_pick_id: 0, //默认选择门店,当用户什么商品都没有选,sele_pick_id=0
  113 + def_store: null, //用户默认的门店
  114 + sele_store: 0, //是不是选择了门店
  115 + more_store: 0, //选择门店
  116 + sort_store: 0, //门店分类
  117 + choice_sort_store: 0, //选择分类门店
  118 + fir_pick_index: 0, //门店选择的下标
  119 + sec_pick_index: 0 //门店选择的下标,地区选择之后的内页
  120 + },
  121 +
  122 + /**
  123 + * 生命周期函数--监听页面加载
  124 + */
  125 + onLoad: function (options) {
  126 + self = this;
  127 + this.data.id = options.id;
  128 +
  129 + //获取活动信息
  130 + var url = "/api/weshop/prom/zhbuy/get/" + os.stoid + "/" + options.id;
  131 + getApp().request.get(url, {
  132 + success: function (e) {
  133 + if (e.data.code == 0 && e.data.data) {
  134 + self.setData({act: e.data.data});
  135 + if (e.data.data.is_end == 0) {
  136 + //-- 获取商品列表 --
  137 + self.get_list();
  138 + self.countDown();
  139 + }
  140 + } else {
  141 + wx.showToast({
  142 + title: e.data.msg,
  143 + icon: 'none',
  144 + duration: 2000
  145 + })
  146 + }
  147 + }
  148 + });
  149 + },
  150 +
  151 + /**
  152 + * 生命周期函数--监听页面显示
  153 + */
  154 + onShow: function () {
  155 + var th = this, that = this, ee = this;
  156 + this.data.is_timer = 1;
  157 + if (this.data.act) this.countDown();
  158 + //如果有会员的时候
  159 + var userInfo = getApp().globalData.userInfo;
  160 + if (userInfo) {
  161 + //等待活动值
  162 + this.waitfor(10, th.data.act, function () {
  163 + //获取头像的分享
  164 + th.get_head_temp(function () {
  165 + var txt = th.data.act.zhprice + "元任选" + th.data.act.zhbuyqty + "件";
  166 + imgDraw.views[0].url = th.data.share_head;
  167 + imgDraw.views[1].text = userInfo.nickname;
  168 + imgDraw.views[2].text = txt;
  169 +
  170 + var start = ut.formar_no_full(th.data.act.start_time, '.');
  171 + var end = ut.formar_no_full(th.data.act.end_time, '.');
  172 + txt = "活动时间:" + start + " - " + end;
  173 + imgDraw.views[3].text = txt;
  174 +
  175 + var scene = th.data.gid + "";
  176 + var user_id = getApp().globalData.user_id;
  177 + scene += "_" + user_id;
  178 + ///二微码
  179 + var path3 = os.url + "/api/wx/open/app/user/getWeAppEwm/" +
  180 + os.stoid + "?sceneValue=" + scene + "&pageValue=pages/goods/goodsInfo/goodsInfo";
  181 + wx.getImageInfo({
  182 + src: path3,
  183 + success: function (res) {
  184 + var vpath = res.path;
  185 + imgDraw.views[4].url = vpath;
  186 + th.setData({imgDraw: imgDraw})
  187 + }
  188 + })
  189 + })
  190 + })
  191 + //获取用户的默认门店
  192 + getApp().get_user_store(function (e) {
  193 + if (!e) {
  194 + th.data.fir_def_store = {}; //赋值空对象
  195 + return false;
  196 + }
  197 + var ee = JSON.parse(JSON.stringify(e));
  198 + var appd = getApp().globalData;
  199 + //-- 等待定位系统的开启 --
  200 + th.waitfor(15, th.data.is_get_local_ok, function () {
  201 + var e = JSON.parse(JSON.stringify(ee));
  202 + //如果有开启近距离的话,同时距离优不一样了
  203 + if (that.data.lat != null) {
  204 + //如果经纬度有变化的话
  205 + if (e && appd.lat == that.data.lat && appd.lon == that.data.lon && e.distance > 0) {
  206 + that.set_def_storage(e);
  207 + } else {
  208 + //要用接口是获取距离,js的计算不准
  209 + getApp().request.promiseGet("/api/weshop/pickup/list", {
  210 + data: {
  211 + store_id: os.stoid,
  212 + pickup_id: e.pickup_id,
  213 + lat: th.data.lat,
  214 + lon: th.data.lon
  215 + },
  216 + }).then(res => {
  217 + if (res.data.code == 0) {
  218 + e = res.data.data.pageData[0];
  219 + if (e) {
  220 + e.is_no_dis = ee.is_no_dis;
  221 + appd.pk_store = e;
  222 + that.set_def_storage(e);
  223 + }
  224 +
  225 + }
  226 + })
  227 + }
  228 + appd.lat = that.data.lat;
  229 + appd.lon = that.data.lon;
  230 + } else {
  231 + if (e) {
  232 + e.distance = null;
  233 + that.set_def_storage(e);
  234 + }
  235 + }
  236 + })
  237 + });
  238 + }
  239 +
  240 + //----获取系统参数-----
  241 + getApp().getConfig2(function (e) {
  242 + ee.setData({
  243 + bconfig: e,
  244 + sales_rules: e.sales_rules,
  245 + });
  246 + //设置基本参数
  247 + th.wait_for_store_config(e);
  248 +
  249 + var json_d = JSON.parse(e.switch_list);
  250 + ee.setData({
  251 + store_config: e,
  252 + sys_switch: json_d,
  253 + is_closecoupon: json_d.is_closecoupon,
  254 + is_newsales_rules: json_d.is_newsales_rules,
  255 + is_open_offline: json_d.is_pricing_open,
  256 + sales_rules: e.sales_rules
  257 + });
  258 +
  259 + //-- 计算等级价相关 --
  260 + var swithc_list = e.switch_list;
  261 + var sw_arr = JSON.parse(swithc_list);
  262 + //---如果后台又开等级卡的开关---
  263 + if (sw_arr.rank_switch && sw_arr.rank_switch == "2") {
  264 + th.setData({rank_switch: true});
  265 + //---回调卡的列表---
  266 + th.getPlusCardType(function (ob) {
  267 + th.setData({card_list: ob.card_list});
  268 + var user = getApp().globalData.userInfo;
  269 + if (!user) return false;
  270 + if (user.card_field && user['card_expiredate']) {
  271 + var str = user['card_expiredate'].replace(/-/g, '/');
  272 + var end = new Date(str);
  273 + end = Date.parse(end) / 1000;
  274 + var now = ut.gettimestamp();
  275 + //--- 判断是等级会员,且在有效期范围内 ---
  276 + if (user.card_field && now < end) {
  277 + var card_name = ob.name_map.get(user.card_field);
  278 + th.setData({
  279 + card_field: user.card_field,
  280 + card_name: card_name,
  281 + card_list: ob.card_list
  282 + });
  283 + }
  284 + }
  285 +
  286 + })
  287 + }
  288 + }, 1);
  289 +
  290 + },
  291 +
  292 + onHide: function () {
  293 + this.data.is_timer = 0;
  294 + },
  295 +
  296 + //-- 调用接口的LIST,获取商品 --
  297 + get_list: function () {
  298 + var th = this;
  299 + if (this.data.loading) return false;
  300 + if (this.data.no_more) return false;
  301 + this.data.loading = 1;
  302 + var url = "/api/weshop/prom/zhbuyGoods/page";
  303 + var req_data = {
  304 + page: this.data.page,
  305 + pageSize: 10,
  306 + store_id: os.stoid,
  307 + zh_id: this.data.id
  308 + }
  309 + //开始调用接口
  310 + getApp().request.get(url, {
  311 + data: req_data,
  312 + success: function (res) {
  313 + th.data.loading = 0;
  314 + th.setData({is_get: 1})
  315 + if (ut.ajax_ok(res)) {
  316 + th.data.page++;
  317 + var list = th.data.list;
  318 + for (var i in res.data.data.pageData) {
  319 + list.push(res.data.data.pageData[i]);
  320 + }
  321 + th.setData({list: list});
  322 + if (res.data.data.total <= 10) {
  323 + th.setData({no_more: 1});
  324 + }
  325 + } else {
  326 + th.setData({no_more: 1});
  327 + }
  328 + }
  329 + })
  330 + },
  331 +
  332 + //-- 滚动到底部触发 --
  333 + get_more_list: function () {
  334 + this.get_list();
  335 + },
  336 +
  337 + /**
  338 + * 用户点击右上角分享
  339 + */
  340 + onShareAppMessage: function () {
  341 + },
  342 +
  343 + /**
  344 + * 点击规则详情,弹出规则
  345 + */
  346 + showRule() {
  347 + this.setData({
  348 + type: 0, //控制显示规则详情还是提示信息,0规则详情,1提示信息
  349 + showRule: true,
  350 + showMask: true,
  351 + });
  352 + },
  353 +
  354 + /**
  355 + * 点击关闭按钮关闭规则详情弹窗
  356 + */
  357 + closeRule() {
  358 + this.setData({
  359 + showRule: false,
  360 + showMask: false,
  361 + });
  362 + },
  363 +
  364 + /**
  365 + * 点击提示信息
  366 + */
  367 + showInfo() {
  368 + this.setData({
  369 + type: 1,
  370 + showRule: true,
  371 + showMask: true,
  372 + });
  373 + },
  374 +
  375 + /**
  376 + * 加入购物车
  377 + */
  378 + addToCart(e) {
  379 + var th = this;
  380 + var index = e.currentTarget.dataset.index;
  381 + var userInfo = getApp().globalData.userInfo;
  382 + if (!userInfo) {
  383 + getApp().goto("/pages/togoin/togoin");
  384 + return false;
  385 + }
  386 + let haveAdded = this.data.list[index].haveAdded;
  387 + this.data.sele_index = index;
  388 + let title = '';
  389 + self = this;
  390 +
  391 + //说明是加入购物车是时候
  392 + this.data.is_zuhe_addcart = 1;
  393 + if (!haveAdded) {
  394 + th.data.sele_g = this.data.list[index];
  395 + if (!th.data.sele_g.num) th.data.goodsInputNum = 1;
  396 +
  397 + //如果没有门店,活动商品的配送方式和门店的配送方式不一样
  398 + if (!th.data.def_pick_store ||
  399 + (th.data.sele_g.distr_type != 0 && th.data.def_pick_store.distr_type != 0 && th.data.sele_g.distr_type != th.data.def_pick_store.distr_type)) {
  400 + //选择了门店
  401 + if (th.data.sele_store) {
  402 + wx.showToast({
  403 + title: "该商品的物流配送方式和默认门店不匹配!",
  404 + icon: 'none',
  405 + duration: 2000
  406 + })
  407 + } else {
  408 + wx.showModal({
  409 + title: '温馨提示',
  410 + content: '该商品的物流配送方式和默认门店不匹配,是否要切换门店?',
  411 + success (res) {
  412 + if (res.confirm) {
  413 + //物流的配送方式不一样
  414 + th.get_sto();
  415 + var set_data = {
  416 + store: 1
  417 + };
  418 + if (th.data.def_pick_store) {
  419 + set_data.is_no_pipei = th.data.def_pick_store.pickup_id;
  420 + }
  421 + th.setData(set_data);
  422 + }
  423 + }
  424 + })
  425 + }
  426 + return false;
  427 + } else {
  428 + th.setData({is_no_pipei: 0});
  429 + th.add_cart_func();
  430 + }
  431 + } else {
  432 + wx.showModal({
  433 + title: '温馨提示',
  434 + content: '确定将该商品移出购物车?',
  435 + success (res) {
  436 + if (res.confirm) {
  437 + console.log('用户点击确定');
  438 + title = '移除购物车成功';
  439 + th.setData({
  440 + [txt1]: 1,
  441 + [txt2]: false,
  442 + [txt]: !haveAdded,
  443 + });
  444 + wx.showToast({
  445 + title: title,
  446 + icon: 'success',
  447 + });
  448 + } else if (res.cancel) {
  449 + console.log('用户点击取消')
  450 + self.setData({
  451 + haveAdded: true,
  452 + });
  453 + }
  454 + }
  455 + })
  456 + }
  457 +
  458 + },
  459 +
  460 + /**
  461 + * 增加数量
  462 + */
  463 + add(e) {
  464 +
  465 + var th = this;
  466 + var userInfo = getApp().globalData.userInfo;
  467 + if (!userInfo) {
  468 + getApp().goto("/pages/togoin/togoin");
  469 + return false;
  470 + }
  471 +
  472 + var index = e.currentTarget.dataset.index;
  473 + this.data.sele_g = this.data.list[index];
  474 + this.data.sele_index=index;
  475 + th.data.goodsInputNum = this.data.sele_g.num + 1;
  476 + th.add_cart_func();
  477 + },
  478 +
  479 + /**
  480 + * 减少数量
  481 + */
  482 + sub(e) {
  483 + var userInfo = getApp().globalData.userInfo;
  484 + if (!userInfo) {
  485 + getApp().goto("/pages/togoin/togoin");
  486 + return false;
  487 + }
  488 +
  489 + var th = this;
  490 + var index = e.currentTarget.dataset.index;
  491 + var item = this.data.list[index];
  492 + let num = item.num;
  493 +
  494 + if (num >= 2) {
  495 + var check_num = num - 1;
  496 + //小于起购数
  497 + if (check_num < item.zhqty) {
  498 + wx.showToast({
  499 + title: "该商品至少要购买" + item.zhqty + "件",
  500 + icon: 'none',
  501 + duration: 2000
  502 + })
  503 + return false;
  504 + }
  505 +
  506 + th.data.sele_g = item;
  507 + th.data.sele_index = index;
  508 + th.data.goodsInputNum = check_num;
  509 + th.sub_updata_cart();
  510 + return false;
  511 + }
  512 +
  513 + wx.showModal({
  514 + title: '温馨提示',
  515 + content: '确定将该商品移出购物车?',
  516 + success (res) {
  517 + if (res.confirm) {
  518 +
  519 + self.setData({
  520 + showNum: false,
  521 + haveAdded: false,
  522 + });
  523 + wx.showToast({
  524 + title: '移除购物车成功',
  525 + icon: 'success',
  526 + });
  527 + th.re_sum_price();//重新统计数量和总金额
  528 + } else if (res.cancel) {
  529 + console.log('用户点击取消')
  530 + self.setData({
  531 + haveAdded: true,
  532 + });
  533 + }
  534 + }
  535 + })
  536 + return false;
  537 +
  538 + },
  539 +
  540 + /** 分享 **/
  541 + share() {
  542 + var th = this;
  543 + var userInfo = getApp().globalData.userInfo;
  544 + if (!userInfo) {
  545 + getApp().goto("/pages/togoin/togoin");
  546 + return false;
  547 + }
  548 + wx.showLoading();
  549 + setTimeout(function () {
  550 + th.setData({
  551 + showMask: true,
  552 + showPoster: true,
  553 + });
  554 + wx.hideLoading();
  555 + }, 1000);
  556 + },
  557 +
  558 + /**
  559 + * 关闭海报
  560 + */
  561 + closePoster() {
  562 + this.setData({
  563 + showMask: false,
  564 + showPoster: false,
  565 + });
  566 + },
  567 +
  568 + onImgOK(e) {
  569 + console.log(e.detail.path);
  570 + this.setData({
  571 + myimg: e.detail.path,
  572 + });
  573 +
  574 + },
  575 +
  576 + //---小于10的格式化函数----
  577 + timeFormat(param) {
  578 + return param < 10 ? '0' + param : param;
  579 + },
  580 +
  581 + //----倒计时函数-----
  582 + countDown() {
  583 + if (!this.data.is_timer) return false;
  584 + var th = this;
  585 + // 获取当前时间,同时得到活动结束时间数组
  586 + var endTime = this.data.act.end_time;
  587 + var newTime = ut.gettimestamp();
  588 + // 对结束时间进行处理渲染到页面
  589 + var obj = null;
  590 + // 如果活动未结束,对时间进行处理
  591 + if (endTime - newTime > 0) {
  592 + var time = (endTime - newTime);
  593 + // 获取天、时、分、秒
  594 + var day = parseInt(time / (60 * 60 * 24));
  595 + var hou = parseInt(time % (60 * 60 * 24) / 3600);
  596 + var min = parseInt(time % (60 * 60 * 24) % 3600 / 60);
  597 + var sec = parseInt(time % (60 * 60 * 24) % 3600 % 60);
  598 + obj = {
  599 + hou: this.timeFormat(hou),
  600 + min: this.timeFormat(min),
  601 + sec: this.timeFormat(sec)
  602 + }
  603 + if (day > 0) {
  604 + obj.day = this.timeFormat(day);
  605 + }
  606 + } else {
  607 + //活动已结束,全部设置为'00'
  608 + obj = {
  609 + day: '00',
  610 + hou: '00',
  611 + min: '00',
  612 + sec: '00'
  613 + }
  614 + th.setData({
  615 + prom_time_text: '活动已经结束:',
  616 + prom_st: 3
  617 + })
  618 + th.setData({
  619 + djs: obj
  620 + });
  621 + return false;
  622 + }
  623 +
  624 + th.setData({
  625 + djs: obj
  626 + });
  627 + setTimeout(function () {
  628 + th.countDown()
  629 + }, 1000);
  630 + },
  631 +
  632 + close_all: function () {
  633 + this.setData({
  634 + showMask: false,
  635 + showPoster: false,
  636 + showRule: false
  637 + });
  638 + },
  639 +
  640 +
  641 + //------定时等待某个值,有值才进行运算--------
  642 + waitfor: function (n, pop_value, func) {
  643 + var th = this;
  644 + if (n <= 0) {
  645 + func()
  646 + return false
  647 + }
  648 + if (pop_value) {
  649 + func();
  650 + return false;
  651 + }
  652 + setTimeout(function () {
  653 + --n;
  654 + th.waitfor(n, pop_value, func)
  655 + }, 1000);
  656 + },
  657 +
  658 + //--获取头像的本地缓存,回调写法--
  659 + get_head_temp: function (tt) {
  660 + var ee = this;
  661 + if (ee.data.share_head) {
  662 + tt();
  663 + return false;
  664 + }
  665 + //---获取分享图片的本地地址,头像和商品图片----
  666 + var path2 = getApp().globalData.userInfo.head_pic;
  667 + if (path2 == "") {
  668 + ee.data.share_head = "../../../../images/share/hui_hear_pic.png";
  669 + tt();
  670 + } else {
  671 + path2 = path2.replace("http://thirdwx.qlogo.cn", "https://wx.qlogo.cn");
  672 + path2 = path2.replace("https://thirdwx.qlogo.cn", "https://wx.qlogo.cn");
  673 + wx.getImageInfo({
  674 + src: path2,
  675 + success: function (res) {
  676 + //res.path是网络图片的本地地址
  677 + console.log(res);
  678 + ee.data.share_head = res.path;
  679 + tt();
  680 + },
  681 + fail: function () {
  682 + ee.data.share_head = "../../../../images/share/hui_hear_pic.png"; //分享的图片不能用网络的
  683 + tt();
  684 + }
  685 + });
  686 + }
  687 + },
  688 +
  689 + go_url: function (e) {
  690 + var url = e.currentTarget.dataset.url;
  691 + getApp().goto(url);
  692 + },
  693 +
  694 + //-- 加入购物的函数 --
  695 + add_cart_func: function () {
  696 + if (oo.user_id == null) {
  697 + return getApp().my_warnning("还未登录!", 0, this);
  698 + }
  699 + if (!getApp().globalData.userInfo) {
  700 + return getApp().my_warnning("还未登录!", 0, this);
  701 + }
  702 +
  703 + var e = this,
  704 + th = e,
  705 + o = this.data.sele_g,
  706 + a = o.goods_id;
  707 +
  708 + //----------添加到购物车时,要判断限购数量,--------
  709 + e.get_buy_num(o, function (ee) {
  710 + //---判断商品是否超出限购---
  711 + if (th.data.g_buy_num != null && th.data.sele_g.viplimited > 0) {
  712 + if (th.data.goodsInputNum + th.data.g_buy_num.get(th.data.sele_g.goods_id) > th.data.sele_g.viplimited) {
  713 + wx.showModal({
  714 + title: '提示',
  715 + content: '超出商品限购'
  716 + });
  717 + return false;
  718 + }
  719 + }
  720 + //---判断商品是否超出活动限购---
  721 + if (th.data.sele_g.buyqty > 0) {
  722 + if (th.data.goodsInputNum > th.data.sele_g.buyqty) {
  723 + wx.showModal({
  724 + title: '提示',
  725 + content: '超出商品活动限购'
  726 + });
  727 + return false;
  728 + }
  729 + }
  730 +
  731 + if (th.data.goodsInputNum <= 0) return s.my_warnning("商品数量不能为0", 0, th);
  732 + if (th.data.sto_sele_name == null || th.data.sto_sele_name == undefined)
  733 + this.setData({
  734 + sto_sele_name: ""
  735 + });
  736 + if (th.data.sto_sele_name == "") return s.my_warnning("请选择门店", 0, th);
  737 +
  738 + //--------------此时操作的数据------------
  739 + var newd = {
  740 + goods_id: o.goods_id,
  741 + goods_num: th.data.goodsInputNum,
  742 + pick_id: th.data.sto_sele_id,
  743 + user_id: oo.user_id,
  744 + store_id: os.stoid,
  745 + goods_price: o.shop_price,
  746 + member_goods_price: o.shop_price,
  747 + goods_name: o.goods_name,
  748 + goods_sn: o.goods_sn,
  749 + };
  750 +
  751 + //---是不是从收藏夹出来的---
  752 + if (th.data.c_guide_id) {
  753 + newd['guide_id'] = th.data.c_guide_id;
  754 + newd['guide_type'] = 2;
  755 + if ("add" == t.currentTarget.dataset.action) newd['guide_type'] = 3;
  756 + } else {
  757 + if (getApp().globalData.guide_id) {
  758 + newd['guide_id'] = getApp().globalData.guide_id;
  759 + newd['guide_type'] = 0;
  760 + if ("add" == t.currentTarget.dataset.action) newd['guide_type'] = 1;
  761 + }
  762 + }
  763 +
  764 + //让商品带上房间号
  765 + if (th.data.sys_switch.is_skuroom_id == 1) {
  766 + if (th.data.data.goods_id == getApp().globalData.room_goods_id) {
  767 + newd.room_id = getApp().globalData.room_id;
  768 + }
  769 + } else {
  770 + if (newd.goods_id == getApp().globalData.room_goods_id) newd.room_id = getApp().globalData.room_id;
  771 + }
  772 +
  773 + if (o.store_count <= 0) return getApp().my_warnning("库存已为空!", 0, th);
  774 + if (o.store_count < e.data.goodsInputNum) return getApp().my_warnning("库存不足!", 0, th);
  775 + th.add_cart_next(o, newd); //加入购物车下一步
  776 +
  777 + })
  778 + },
  779 +
  780 + //---加入购物车的最后一步---
  781 + add_cart_next(o, newd){
  782 + var th = this;
  783 + //如果会员有等级价
  784 + if (th.data.card_field) {
  785 + var card_price = o[th.data.card_field];
  786 + if (card_price > 0) {
  787 + newd.goods_price = card_price;
  788 + newd.member_goods_price = card_price;
  789 + }
  790 + }
  791 +
  792 + var index = this.data.sele_index;
  793 + var txt = "list[" + index + "].haveAdded";
  794 + var txt1 = "list[" + index + "].num";
  795 + var txt2 = "list[" + index + "].showNum";
  796 + var txt3 = "list[" + index + "].current_price";
  797 +
  798 +
  799 + newd.prom_type = 7;
  800 + newd.prom_id = th.data.act.id;
  801 +
  802 + if (th.data.adding) return false;
  803 + th.data.adding = 1;
  804 + //-------如果购物车中有相关的数据---------
  805 + if (th.data.goodsInputNum > 1) {
  806 + var item = th.data.sele_g;
  807 + if (th.data.goodsInputNum > o.store_count) {
  808 + th.data.adding = 0;
  809 + return getApp().my_warnning("库存不足!", 0, th);
  810 + }
  811 + if (th.data.goodsInputNum > o.buyqty) {
  812 + th.data.adding = 0;
  813 + return getApp().my_warnning("超出商品活动限购!", 0, th);
  814 + }
  815 + if (th.data.goodsInputNum + th.data.g_buy_num.get(th.data.sele_g.goods_id) > th.data.sele_g.viplimited
  816 + && th.data.sele_g.viplimited > 0
  817 + ) {
  818 + th.data.adding = 0;
  819 + return getApp().my_warnning("超出商品限购!", 0, th);
  820 + }
  821 +
  822 + //如果商品没有其他活动,要取一下线下价格
  823 + var updata = {
  824 + id: item.cart_id,
  825 + goods_num: th.data.goodsInputNum,
  826 + goods_price: newd.goods_price,
  827 + member_goods_price: newd.goods_price,
  828 + store_id: os.stoid,
  829 + };
  830 +
  831 + //---是不是从收藏夹出来的---
  832 + if (th.data.c_guide_id) {
  833 + updata['guide_id'] = th.data.c_guide_id;
  834 + updata['guide_type'] = 3; //加入购物车之后就变成了3
  835 + } else {
  836 + if (getApp().globalData.guide_id) {
  837 + updata['guide_id'] = getApp().globalData.guide_id;
  838 + updata['guide_type'] = 0;
  839 + }
  840 + }
  841 + getApp().request.put("/api/weshop/cart/update", {
  842 + data: updata,
  843 + success: function (t) {
  844 + th.setData({
  845 + [txt1]: updata.goods_num,
  846 + [txt2]: true,
  847 + [txt]: true,
  848 + [txt3]: newd.goods_price,
  849 + });
  850 + th.data.adding = 0;
  851 + th.data.sele_store = 1;
  852 + th.re_sum_price();//重新统计数量和总金额
  853 + }
  854 + });
  855 +
  856 +
  857 + } else {
  858 +
  859 + getApp().request.post("/api/weshop/cart/save", {
  860 + data: newd,
  861 + success: function (t) {
  862 + if (t.data.code == 0) {
  863 + var txt4 = "list[" + th.data.sele_index + "].cart_id";
  864 + th.setData({
  865 + [txt1]: newd.goods_num,
  866 + [txt2]: true,
  867 + [txt3]: newd.goods_price,
  868 + [txt]: true,
  869 + [txt4]: t.data.data.id,
  870 + });
  871 +
  872 + th.data.adding = 0;
  873 + th.data.sele_store = 1;
  874 + th.re_sum_price();//重新统计数量和总金额
  875 + }
  876 + }
  877 + });
  878 + }
  879 + },
  880 +
  881 + //等待获取配置
  882 + wait_for_store_config: function (bconfig) {
  883 + var th = this;
  884 + var e = bconfig;
  885 + if (e && e.is_sort_storage) {
  886 + wx.getLocation({
  887 + type: 'gcj02',
  888 + success: function (res) {
  889 + th.data.lat = res.latitude;
  890 + th.data.lon = res.longitude;
  891 + th.data.is_get_local_ok = 1;
  892 + },
  893 + fail: function (res) {
  894 + if (res.errCode == 2) {
  895 + th.setData({
  896 + is_gps: 0
  897 + });
  898 + if (th.data.is_gps == 0) {
  899 + getApp().confirmBox("请开启GPS定位", null, 10000, !1);
  900 + }
  901 +
  902 + } else {
  903 + th.setData({
  904 + is_gps: "3"
  905 + });
  906 + }
  907 +
  908 + th.data.is_get_local_ok = 1;
  909 + }
  910 + })
  911 + } else {
  912 + th.data.is_get_local_ok = 1;
  913 + }
  914 + },
  915 +
  916 + //--- 获取卡类列表 ---
  917 + getPlusCardType: function (func) {
  918 + var storid = os.stoid;
  919 + var user = getApp().globalData.userInfo;
  920 + if (!user) return false;
  921 + getApp().request.promiseGet("/api/weshop/plus/vip/mem/bership/list?" + "storeId=" + storid, {}).then(res => {
  922 + var plusCard = res.data.data;
  923 + var arr = [1219, 2089, 3031];
  924 + var new_arr = new Array();
  925 + var card_name_map = new Map();
  926 +
  927 + var list = [];
  928 + for (var i = 0; i < plusCard.length; i++) {
  929 + if ((!user || user.card_field == null || user.card_field == "") && plusCard[i].IsStopBuy == true) continue;
  930 + var name = "card" + plusCard[i].CorrPrice.toLowerCase();
  931 + card_name_map.set(name, plusCard[i].CardName);
  932 + list.push(plusCard[i]);
  933 + }
  934 +
  935 + var ob = {"card_list": list, "name_map": card_name_map};
  936 + func(ob);
  937 + })
  938 + },
  939 +
  940 +
  941 + //--- 设置一下默认库存的数量 ----
  942 + set_def_storage(ee){
  943 + var that = this;
  944 + that.data.fir_def_store = ee;
  945 + that.setData({
  946 + def_pick_store: ee,
  947 + sto_sele_name: ee.pickup_name,
  948 + sto_sele_id: ee.pickup_id,
  949 + sto_sele_distr: ee.distr_type
  950 + })
  951 + },
  952 +
  953 + //---------拿出门店分类和门店------------
  954 + get_sto(e) {
  955 + var th = this;
  956 + this.waitfor(15, th.data.is_get_local_ok, function () {
  957 + if (!th.data.sele_g) return false;
  958 + var dd = null;
  959 + var g_distr_type = th.data.sele_g.distr_type;
  960 + if (g_distr_type != 0) {
  961 + dd = {
  962 + store_id: os.stoid,
  963 + distr_type: g_distr_type,
  964 + isstop: 0,
  965 + pageSize: 2000
  966 + }
  967 + } else {
  968 + dd = {
  969 + store_id: o.stoid,
  970 + isstop: 0,
  971 + pageSize: 2000
  972 + }
  973 + }
  974 +
  975 + //如果有距离的话
  976 + if (th.data.lat != null) {
  977 + dd.lat = th.data.lat;
  978 + dd.lon = th.data.lon;
  979 + }
  980 +
  981 + //如果会员是有默认的门店话
  982 + if (!th.data.def_pick_store && th.data.fir_def_store) {
  983 + th.setData({def_pick_store: th.data.fir_def_store});
  984 + }
  985 +
  986 + wx.showLoading({
  987 + title: '加载中.'
  988 + });
  989 + //----------获取门店----------------
  990 + getApp().request.promiseGet("/api/weshop/pickup/list", {
  991 + data: dd,
  992 + }).then(res => {
  993 + var e = res;
  994 + if (e.data.code == 0 && e.data.data && e.data.data.pageData && e.data.data.pageData.length > 0) {
  995 +
  996 + //如果有开启距离的功能,没有设置默认门店,要用最近的门店作为默认门店
  997 + if (dd.lat && (!th.data.def_pick_store || JSON.stringify(th.data.def_pick_store) == '{}') && th.data.bconfig && th.data.bconfig.is_sort_storage) {
  998 + th.setData({
  999 + def_pick_store: e.data.data.pageData[0],
  1000 + sto_sele_name: e.data.data.pageData[0].pickup_name,
  1001 + sto_sele_id: e.data.data.pageData[0].pickup_id,
  1002 + sto_sele_distr: e.data.data.pageData[0].distr_type
  1003 + });
  1004 + th.data.fir_def_store = e.data.data.pageData[0];
  1005 + }
  1006 +
  1007 + //-- 如果有默认选择门店的时候,要把默认门店放在第一位,修改不要配送方式的判断 --
  1008 + if (th.data.def_pick_store && JSON.stringify(th.data.def_pick_store) != '{}') {
  1009 + for (var k = 0; k < e.data.data.pageData.length; k++) {
  1010 + if (e.data.data.pageData[k].pickup_id == th.data.def_pick_store.pickup_id) {
  1011 + e.data.data.pageData.splice(k, 1); //删除
  1012 + break;
  1013 + }
  1014 + }
  1015 + e.data.data.pageData.splice(0, 0, th.data.def_pick_store); //添加
  1016 + }
  1017 +
  1018 + th.setData({all_pick_list: e.data.data.pageData});
  1019 + th.deal_pickup(e);
  1020 +
  1021 +
  1022 + }
  1023 + })
  1024 + })
  1025 + },
  1026 + //------------处理门店---------------
  1027 + deal_pickup(e){
  1028 + var th = this;
  1029 + wx.hideLoading();
  1030 + //单总量超出5个的时候
  1031 + if (e.data.data.total > 5) {
  1032 + getApp().request.get("/api/weshop/storagecategory/page", {
  1033 + data: {
  1034 + store_id: os.stoid,
  1035 + is_show: 1,
  1036 + pageSize: 1000,
  1037 + orderField: "sort",
  1038 + orderType: 'asc',
  1039 + },
  1040 + success: function (ee) {
  1041 + if (ee.data.code == 0) {
  1042 + if (ee.data.data && ee.data.data.pageData && ee.data.data.pageData.length > 0) {
  1043 + var def_arr = new Array();
  1044 + //-- 开始就看5个门店 --
  1045 + for (var k = 0; k < 5; k++) {
  1046 + if (k == e.data.data.pageData.length) break;
  1047 + def_arr.push(e.data.data.pageData[k]);
  1048 + }
  1049 +
  1050 + th.setData({
  1051 + def_pickpu_list: def_arr,
  1052 + pickpu_list: ee.data.data.pageData
  1053 + });
  1054 + var sto_cate = ee.data.data.pageData;
  1055 + var sto_arr = e.data.data.pageData;
  1056 + var newarr = new Array();
  1057 + var qita = new Array();
  1058 +
  1059 + //----要进行门店分组--------
  1060 + for (var i = 0; i < sto_arr.length; i++) {
  1061 + //找一下这个门店有没有在分类数组内
  1062 + var find2 = 0, find2name = "", sort = 0;
  1063 + for (var m = 0; m < sto_cate.length; m++) {
  1064 + if (sto_arr[i].category_id == sto_cate[m].cat_id) {
  1065 + find2 = sto_cate[m].cat_id;
  1066 + find2name = sto_cate[m].cat_name;
  1067 + sort = sto_cate[m].sort;
  1068 + break;
  1069 + }
  1070 + }
  1071 +
  1072 + if (newarr.length > 0) {
  1073 + var find = 0;
  1074 + //如果有找到,那门店就在这个分组内,否则,分类就要排在其他
  1075 + if (find2 != 0) {
  1076 + for (var ii = 0; ii < newarr.length; ii++) {
  1077 + if (sto_arr[i].category_id == newarr[ii].cat_id) {
  1078 + newarr[ii].s_arr.push(sto_arr[i]);
  1079 + find = 1;
  1080 + break;
  1081 + }
  1082 + }
  1083 + if (find == 0) {
  1084 + var arr0 = new Array();
  1085 + arr0.push(sto_arr[i]);
  1086 + var item = {
  1087 + cat_id: find2,
  1088 + name: find2name,
  1089 + sort: sort,
  1090 + s_arr: arr0
  1091 + };
  1092 + newarr.push(item);
  1093 + }
  1094 + } else {
  1095 + qita.push(sto_arr[i]);
  1096 + }
  1097 + } else {
  1098 + //如果有找到,那门店就在这个分组内,否则,分类就要排在其他
  1099 + if (find2 != 0) {
  1100 + var arr0 = new Array();
  1101 + arr0.push(sto_arr[i]);
  1102 + var item = {
  1103 + cat_id: find2,
  1104 + name: find2name,
  1105 + sort: sort,
  1106 + s_arr: arr0
  1107 + };
  1108 + newarr.push(item);
  1109 + } else {
  1110 + qita.push(sto_arr[i]);
  1111 + }
  1112 + }
  1113 + }
  1114 +
  1115 + //门店分类要排序下
  1116 + function compare(property) {
  1117 + return function (a, b) {
  1118 + var value1 = a[property];
  1119 + var value2 = b[property];
  1120 + return value1 - value2;
  1121 + }
  1122 + }
  1123 +
  1124 + if (newarr.length > 0)
  1125 + newarr.sort(compare("sort"));
  1126 + //----安排其他的分类-----
  1127 + if (qita.length > 0) {
  1128 + var item = {
  1129 + cat_id: -1,
  1130 + name: "其他",
  1131 + s_arr: qita
  1132 + };
  1133 + newarr.push(item);
  1134 + }
  1135 + th.setData({
  1136 + is_show_sto_cat: 1,
  1137 + all_sto: newarr
  1138 + });
  1139 +
  1140 + } else {
  1141 + th.setData({
  1142 + is_show_sto_cat: -1,
  1143 + only_pk: e.data.data.pageData
  1144 + });
  1145 + //-----如果没有默认门店,要取第一个门店作为默认店.此时没有门店分类的情况------
  1146 + if (!th.data.def_pick_store) {
  1147 + th.setData({def_pick_store: e.data.data.pageData[0]})
  1148 + }
  1149 + }
  1150 + } else {
  1151 + th.setData({
  1152 + is_show_sto_cat: -1,
  1153 + only_pk: e.data.data.pageData
  1154 + });
  1155 + //-----如果没有默认门店,要取第一个门店作为默认店.此时没有门店分类的情况------
  1156 + if (!th.data.def_pick_store) {
  1157 + th.setData({def_pick_store: e.data.data.pageData[0]})
  1158 + }
  1159 + }
  1160 + }
  1161 + });
  1162 + } else {
  1163 + th.setData({
  1164 + is_show_sto_cat: 0,
  1165 + only_pk: e.data.data.pageData
  1166 + });
  1167 + //-----如果没有默认门店,要取第一个门店作为默认店------
  1168 + if (!th.data.def_pick_store && th.data.bconfig && th.data.bconfig.is_sort_storage) {
  1169 + if (e.data.data && e.data.data.pageData && e.data.data.pageData.length > 0) {
  1170 + th.setData({
  1171 + def_pick_store: e.data.data.pageData[0],
  1172 + sto_sele_name: e.data.data.pageData[0].pickup_name,
  1173 + sto_sele_id: e.data.data.pageData[0].pickup_id,
  1174 + sto_sele_distr: e.data.data.pageData[0].distr_type
  1175 + })
  1176 + }
  1177 + }
  1178 + }
  1179 + },
  1180 +
  1181 + //---选择分类门店---
  1182 + choice_sort_store: function (e) {
  1183 + var index = e.currentTarget.dataset.index;
  1184 + var region_name = e.currentTarget.dataset.region;
  1185 + var item = this.data.all_sto[index];
  1186 + this.setData({
  1187 + region_name: region_name,
  1188 + sort_store: 0,
  1189 + choice_sort_store: 1,
  1190 + sec_sto: item,
  1191 + sec_pick_index: 0
  1192 + });
  1193 + },
  1194 +
  1195 + choose_for_store_fir: function (e) {
  1196 + var index_c = e.currentTarget.dataset.ind;
  1197 + var th = this;
  1198 + th.setData({
  1199 + fir_pick_index: index_c
  1200 + })
  1201 + },
  1202 +
  1203 + //确定def_pick为选择的门店
  1204 + sure_pick: function (e) {
  1205 + var th = this;
  1206 + var item = null;
  1207 + var openindstore = th.data.open_ind_store;
  1208 +
  1209 + if (th.data.choice_sort_store == 0) {
  1210 + var index = th.data.fir_pick_index;
  1211 + if (th.data.is_show_sto_cat == 1) {
  1212 + item = th.data.def_pickpu_list[index];
  1213 + } else {
  1214 + item = th.data.only_pk[index]; //当没有门店分类的时候
  1215 + }
  1216 +
  1217 + } else {
  1218 + var index = th.data.sec_pick_index;
  1219 + item = th.data.sec_sto.s_arr[index];
  1220 + }
  1221 +
  1222 + if (!th.data.sele_g) return false;
  1223 + //判断门店的配送方式是不是匹配
  1224 + var g_distr_type = th.data.sele_g.distr_type;
  1225 + if (item.distr_type != 0 && g_distr_type != 0 && item.distr_type != g_distr_type) {
  1226 + wx.showToast({
  1227 + title: "门店配送方式不匹配",
  1228 + icon: 'none',
  1229 + duration: 2000
  1230 + });
  1231 + return false;
  1232 + }
  1233 +
  1234 + th.setData({
  1235 + def_pick_store: item,
  1236 + sto_sele_name: item.pickup_name,
  1237 + sto_sele_id: item.pickup_id,
  1238 + sto_sele_distr: item.distr_type,
  1239 + store: 0,
  1240 + choice_sort_store: 0,
  1241 + fir_pick_index: 0,
  1242 + sort_store: 0
  1243 + });
  1244 +
  1245 + //只是单纯的选择门店
  1246 + if (this.data.only) {
  1247 + this.data.only = 0;
  1248 + return false;
  1249 + }
  1250 + th.check_is_in_cart(function () {
  1251 + th.add_cart_func();
  1252 + })
  1253 + },
  1254 +
  1255 +
  1256 + //---点击二级之后的选择---
  1257 + choose_for_store: function (e) {
  1258 + var index_c = e.currentTarget.dataset.ind;
  1259 + var th = this;
  1260 + th.setData({
  1261 + sec_pick_index: index_c,
  1262 + fir_pick_index: index_c
  1263 + })
  1264 +
  1265 + },
  1266 + //把选择的门店设置成默认的门店def_pick
  1267 + set_def_pick: function (e) {
  1268 + var th = this;
  1269 + var item = null;
  1270 + if (th.data.choice_sort_store == 0) {
  1271 + var index = th.data.fir_pick_index;
  1272 + if (th.data.is_show_sto_cat == 1) {
  1273 + item = th.data.def_pickpu_list[index];
  1274 + } else {
  1275 + item = th.data.only_pk[index]; //当没有门店分类的时候
  1276 + }
  1277 + } else {
  1278 + var index = th.data.sec_pick_index;
  1279 + item = th.data.sec_sto.s_arr[index];
  1280 + }
  1281 +
  1282 + //判断门店的配送方式是不是匹配
  1283 + var g_distr_type = th.data.sele_g.distr_type;
  1284 + if (item.distr_type != 0 && g_distr_type != 0 && item.distr_type != g_distr_type) {
  1285 + wx.showToast({
  1286 + title: "门店配送方式不匹配",
  1287 + icon: 'none',
  1288 + duration: 2000
  1289 + });
  1290 + return false;
  1291 + }
  1292 +
  1293 + //先设置之前,要判断是不是有库存
  1294 + var user_id = getApp().globalData.user_id;
  1295 + var def_pickup_id = item.pickup_id;
  1296 +
  1297 + getApp().request.put('/api/weshop/users/update', {
  1298 + data: {
  1299 + user_id: user_id,
  1300 + def_pickup_id: def_pickup_id
  1301 + },
  1302 + success: function (res) {
  1303 + if (res.data.code == 0) {
  1304 + if (th.data.choice_sort_store == 0) th.setData({
  1305 + fir_pick_index: 0
  1306 + });
  1307 + getApp().globalData.pk_store = item;
  1308 + } else {
  1309 + //s.showWarning("设置默认门店地址失败", null, 500, !1);
  1310 + getApp().my_warnning("设置默认门店地址失败", 0, th)
  1311 + }
  1312 +
  1313 + }
  1314 + });
  1315 +
  1316 + th.setData({
  1317 + def_pick_store: item,
  1318 + sto_sele_name: item.pickup_name,
  1319 + sto_sele_id: item.pickup_id,
  1320 + sto_sele_distr: item.distr_type,
  1321 + store: 0,
  1322 + choice_sort_store: 0,
  1323 + sort_store: 0, //关闭门店2级
  1324 + });
  1325 +
  1326 + th.add_cart_func();
  1327 + },
  1328 +
  1329 + // 返回按钮
  1330 + returns: function () {
  1331 + this.setData({
  1332 + sort_store: 0,
  1333 + choice_sort_store: 0
  1334 + });
  1335 + },
  1336 + //选择更多门店
  1337 + more_store: function () {
  1338 + this.setData({
  1339 + sort_store: 1
  1340 + });
  1341 + },
  1342 + //关闭选择门店
  1343 + close_popup: function (e) {
  1344 + var th = this;
  1345 + this.setData({
  1346 + store: 0,
  1347 + choice_sort_store: 0,
  1348 + sort_store: 0,
  1349 + fir_pick_index: 0,
  1350 + sec_pick_index: 0
  1351 + })
  1352 + },
  1353 +
  1354 + //-------------获取购买数量的总函数----------------
  1355 + get_buy_num: function (gd, func) {
  1356 + var map = this.data.g_buy_num,
  1357 + th = this, user_id = getApp().globalData.user_id;
  1358 +
  1359 + if (user_id == null) {
  1360 + getApp().goto("/pages/togoin/togoin");
  1361 + return false;
  1362 + }
  1363 + if (map && map.has(gd.goods_id)) {
  1364 + "function" == typeof func && func();
  1365 + } else {
  1366 + //----获取商品购买数----
  1367 + getApp().request.get("/api/weshop/ordergoods/getUserBuyGoodsNum", {
  1368 + data: {
  1369 + store_id: os.stoid,
  1370 + user_id: user_id,
  1371 + goods_id: gd.goods_id
  1372 + },
  1373 + success: function (t) {
  1374 + if (t.data.code == 0) {
  1375 + var g_buy_num = t.data.data.goodsbuynum;
  1376 + if (!map) map = new Map();
  1377 + map.set(gd.goods_id, g_buy_num);
  1378 + th.setData({
  1379 + g_buy_num: map
  1380 + });
  1381 + "function" == typeof func && func();
  1382 + }
  1383 + }
  1384 + });
  1385 + }
  1386 + },
  1387 +
  1388 + //-- 当是减数量的调用 --
  1389 + sub_updata_cart(){
  1390 + var th = this;
  1391 + var index = this.data.sele_index;
  1392 + var txt = "list[" + index + "].haveAdded";
  1393 + var txt1 = "list[" + index + "].num";
  1394 + var txt2 = "list[" + index + "].showNum";
  1395 +
  1396 + var cur_price = this.data.sele_g.shop_price;
  1397 + if (th.data.card_field && this.data.sele_g[th.data.card_field]) {
  1398 + cur_price = this.data.sele_g[th.data.card_field];
  1399 + }
  1400 + var updata = {
  1401 + id: th.data.sele_g.cart_id,
  1402 + goods_num: th.data.goodsInputNum,
  1403 + goods_price: cur_price,
  1404 + store_id: os.stoid,
  1405 + };
  1406 + //---是不是从收藏夹出来的---
  1407 + if (th.data.c_guide_id) {
  1408 + updata['guide_id'] = th.data.c_guide_id;
  1409 + updata['guide_type'] = 3; //加入购物车之后就变成了3
  1410 + } else {
  1411 + if (getApp().globalData.guide_id) {
  1412 + updata['guide_id'] = getApp().globalData.guide_id;
  1413 + updata['guide_type'] = 0;
  1414 + }
  1415 + }
  1416 + //调用接口,更新购物车
  1417 + getApp().request.put("/api/weshop/cart/update", {
  1418 + data: updata,
  1419 + success: function (t) {
  1420 + th.setData({
  1421 + [txt1]: updata.goods_num,
  1422 + [txt2]: true,
  1423 + [txt]: true,
  1424 + });
  1425 +
  1426 + th.data.adding = 0;
  1427 + th.data.sele_store = 1;
  1428 + th.re_sum_price();//重新统计数量和总金额
  1429 + }
  1430 + });
  1431 + },
  1432 + //一 开始的选择门店 --
  1433 + choose_store: function (e) {
  1434 + var userInfo = getApp().globalData.userInfo;
  1435 + if (!userInfo) {
  1436 + getApp().goto("/pages/togoin/togoin");
  1437 + return false;
  1438 + }
  1439 + this.data.only = 1;
  1440 + this.setData({
  1441 + store: 1
  1442 + })
  1443 + },
  1444 +
  1445 + // -- 加入之前,先判断有没有在购物车中,没有商品就添加 --
  1446 + check_is_in_cart: function (func) {
  1447 + var th = this;
  1448 + var index = th.data.sele_index;
  1449 + var txt = "list[" + index + "].haveAdded";
  1450 + var txt1 = "list[" + index + "].num";
  1451 + var txt2 = "list[" + index + "].showNum";
  1452 + var txt3 = "list[" + index + "].cart_id";
  1453 + var txt4 = "list[" + index + "].current_price";
  1454 +
  1455 +
  1456 +
  1457 + //----先看会员在购物车中是否加入了该商品-----
  1458 + getApp().request.get("/api/weshop/cart/page", {
  1459 + data: {
  1460 + store_id: os.stoid,
  1461 + user_id: oo.user_id,
  1462 + goods_id: th.data.sele_g.goods_id,
  1463 + pick_id: th.data.sto_sele_id,
  1464 + },
  1465 + success: function (re) {
  1466 + if (re.data.data.total > 0) {
  1467 + var item = re.data.data.pageData[0];
  1468 +
  1469 + //当前的价格要更新进去
  1470 + var cur_price = th.data.sele_g.shop_price;
  1471 + if (th.data.card_field && th.data.sele_g[th.data.card_field]) {
  1472 + cur_price = th.data.sele_g[th.data.card_field];
  1473 + }
  1474 +
  1475 + th.setData({
  1476 + [txt1]: item.goods_num,
  1477 + [txt2]: true,
  1478 + [txt]: true,
  1479 + [txt3]: item.id,
  1480 + [txt4]: cur_price,
  1481 + });
  1482 +
  1483 + var updata = {
  1484 + id: item.id,
  1485 + prom_type: 7,
  1486 + goods_price: cur_price,
  1487 + prom_id: th.data.act.id
  1488 + };
  1489 + if (getApp().globalData.guide_id) {
  1490 + updata['guide_id'] = getApp().globalData.guide_id;
  1491 + updata['guide_type'] = 0;
  1492 + }
  1493 +
  1494 + getApp().request.put("/api/weshop/cart/update", {
  1495 + data: updata,
  1496 + success: function (t) {
  1497 + }
  1498 + });
  1499 +
  1500 + th.re_sum_price();
  1501 + } else {
  1502 + func();
  1503 + }
  1504 + }
  1505 + })
  1506 + },
  1507 +
  1508 + //-- 计算统计之后的金额 --
  1509 + re_sum_price: function () {
  1510 + var all_num = 0; //商品数量之和
  1511 + var all_price = 0;
  1512 + var need_to_buy = 0;
  1513 + var data = this.data.list;
  1514 + var all_zhqty = 0; //所有商品要求起购数之后
  1515 +
  1516 + var no_in_arr = [];
  1517 + for (var i in data) {
  1518 + var item = data[i];
  1519 + if (item.num) {
  1520 + all_num += item.num;
  1521 + all_price += item.num * item.current_price;
  1522 + //当有起购数的控制的时候
  1523 + if (item.zhqty) {
  1524 + all_zhqty += item.zhqty;
  1525 + if (item.num < item.zhqty) {
  1526 + need_to_buy += item.zhqty - item.num;
  1527 + }
  1528 + if (item.num > item.zhqty) {
  1529 + for (var i = 0; i < item.num - item.zhqty; i++) {
  1530 + no_in_arr.push({price: item.current_price})
  1531 + }
  1532 + }
  1533 + } else {
  1534 + for (var j = 0; j < item.num; j++) {
  1535 + no_in_arr.push({price: item.current_price})
  1536 + }
  1537 + }
  1538 + } else {
  1539 + if (item.zhqty) need_to_buy += item.zhqty;
  1540 + }
  1541 + }
  1542 +
  1543 + //当满足组合的要求:总数要满足,起购数要满足
  1544 + if (all_num >= this.data.act.zhbuyqty && !need_to_buy) {
  1545 + function sortData(a, b) {
  1546 + return a.price - b.price
  1547 + }
  1548 +
  1549 + no_in_arr.sort(sortData);
  1550 + var aprice = this.data.act.zhprice;
  1551 + if (this.data.act.zhbuyqty > all_zhqty) {
  1552 + for (var n = 0; n < this.data.act.zhbuyqty; n++) {
  1553 + no_in_arr.pop();
  1554 + }
  1555 + }
  1556 +
  1557 + //看一下剩下的数量有没有满足组合购的要求,以及要不要倍增
  1558 + if (this.data.act.is_bz && no_in_arr.length > this.data.act.zhbuyqty) {
  1559 + //看一下是几倍
  1560 + var be = parseInt(no_in_arr / this.data.act.zhbuyqty);
  1561 + aprice += be * aprice;
  1562 + for (var m = 0; m < be * this.data.act.zhbuyqty; m++) {
  1563 + no_in_arr.pop();
  1564 + }
  1565 + }
  1566 +
  1567 + //算一下剩余的钱
  1568 + if (no_in_arr.length) {
  1569 + for (var ii in no_in_arr) {
  1570 + var item = no_in_arr[ii];
  1571 + aprice += item.price;
  1572 + }
  1573 + }
  1574 + all_price = aprice;
  1575 + }
  1576 +
  1577 + this.setData({
  1578 + all_price: all_price,
  1579 + need_to_buy: need_to_buy,
  1580 + all_num: all_num
  1581 + })
  1582 + },
  1583 +
  1584 + go_cart:function () {
  1585 + getApp().goto("/pages/cart/cart/cart");
  1586 + }
  1587 +
  1588 +})
0 1589 \ No newline at end of file
... ...
packageB/pages/zuhegou/index/index.json 0 → 100644
  1 +{
  2 + "usingComponents": {
  3 + "catch": "/components/catch/catch",
  4 + "nodata": "/components/nodata/nodata",
  5 + "painter": "/packageB/components/painter/painter",
  6 + "warn": "/components/long_warn/long_warn"
  7 + },
  8 + "enablePullDownRefresh": false,
  9 + "navigationBarTitleText": "组合购"
  10 +}
0 11 \ No newline at end of file
... ...
packageB/pages/zuhegou/index/index.wxml 0 → 100644
  1 +<wxs module="filters" src="../../../../utils/filter.wxs"></wxs>
  2 +<view class="container">
  3 + <view class="flex jc_sb">
  4 + <view class="white">以下商品{{act.zhprice}}元任选{{act.zhbuyqty}}件</view>
  5 + <view class="rule-container" bindtap="showRule">规则详情
  6 + <text class="iconfont icon-arrow_right"></text>
  7 + </view>
  8 + </view>
  9 + <view wx:if="{{djs}}" class="countdown-container">距结束还剩
  10 + <text wx:if="{{djs.day}}">{{djs.day}}天</text>
  11 + <text class="num-box">{{djs.hou}}</text>
  12 + :
  13 + <text class="num-box">{{djs.min}}</text>
  14 + :
  15 + <text class="num-box">{{djs.sec}}</text>
  16 + </view>
  17 +
  18 +
  19 + <view class="c_w mt20 fs32">门店:
  20 + <text wx:if="{{def_pick_store}}">{{def_pick_store.pickup_name}}</text>
  21 + <text wx:else bindtap="choose_store" >请选择门店</text>
  22 + </view>
  23 +
  24 + <!-- 商品列表 -->
  25 + <view class="list-container">
  26 + <scroll-view class="list" scroll-y bindscrolltolower="get_more_list">
  27 + <block wx:for="{{list}}">
  28 + <view class="list-item" bindtap="go_url"
  29 + data-url="/pages/goods/goodsInfo/goodsInfo?goods_id={{item.goods_id}}">
  30 + <view class="img-container">
  31 + <image src="{{iurl}}{{item.original_img?item.original_img:'/miniapp/images/default_g_img.gif'}}"
  32 + mode="aspectFit" class="img-block"></image>
  33 + </view>
  34 + <view class="pdl20 flex f1 fdc jc_sb" >
  35 + <view>
  36 + <view class="fs30 ellipsis-2">{{item.goods_name}}</view>
  37 + <view class="c-fa8b2b fs28" wx:if="{{item.zhqty && (item.num<item.zhqty || !item.num)}}">此商品还需购买{{item.zhqty-(item.num?item.num:0)}}件</view>
  38 + <view class="num-container" wx:if="{{item.showNum}}">
  39 + <text class="num-box {{item.num<=1?'c-dedfe3':''}}" catchtap="sub"
  40 + data-index="{{index}}">-</text>
  41 + <text class="num-box">{{item.num}}</text>
  42 + <text class="num-box" catchtap="add" data-index="{{index}}">+</text>
  43 + </view>
  44 + </view>
  45 +
  46 + <view class="flex jc_sb ai_end pdt12">
  47 + <view>
  48 + <!-- 要判断实际价格,因为有等级卡价 -->
  49 + <block wx:if="{{card_field && item[card_field]>0}}">
  50 + <text class="rmb fs30 c-red">{{filters.toFix(item[card_field],2)}}</text>
  51 + </block>
  52 + <block wx:else>
  53 + <text class="rmb fs30 c-red">{{filters.toFix(item.shop_price,2)}}</text>
  54 + </block>
  55 + <text class="rmb fs20 line-through cb">{{filters.toFix(item.market_price,2)}}</text>
  56 + </view>
  57 + <view class="c-red pdr10 {{item.haveAdded ? 'active':''}}" catchtap="addToCart"
  58 + data-index="{{index}}">
  59 + <text class="iconfont icon-gouwuche fs60"></text>
  60 + </view>
  61 + </view>
  62 + </view>
  63 + </view>
  64 + </block>
  65 +
  66 + <nodata wx:if="{{list.length==0 && is_get}}" nodataContainer="t-c"></nodata>
  67 + <view wx:if="{{no_more}}" class="noMore">没有更多了</view>
  68 + </scroll-view>
  69 +
  70 + </view>
  71 +
  72 + <!-- 底部栏 -->
  73 + <view class="bar-container">
  74 + <block wx:if="{{all_num>=act.zhbuyqty}}">
  75 + <view wx:if="{{need_to_buy}}" class="t-c bg-fcfb c-fa8b2b fs28 pd20">
  76 + 再买{{need_to_buy}}件,下单立享【{{act.zhprice}}元任选{{act.zhbuyqty}}件】
  77 + </view>
  78 + <view wx:else class="t-c bg-fcfb c-fa8b2b fs28 pd20">下单立享【{{act.zhprice}}元任选{{act.zhbuyqty}}件】</view>
  79 + </block>
  80 + <block wx:else>
  81 + <view wx:if="{{all_num>0}}" class="t-c bg-fcfb c-fa8b2b fs28 pd20">
  82 + 再买{{act.zhbuyqty-all_num>need_to_buy?act.zhbuyqty-all_num:need_to_buy}}件,下单立享【{{act.zhprice}}元任选{{act.zhbuyqty}}件】
  83 + </view>
  84 + <view wx:else class="t-c bg-fcfb c-fa8b2b fs28 pd20">
  85 + 买{{act.zhbuyqty}}件,下单立享【{{act.zhprice}}元任选{{act.zhbuyqty}}件】
  86 + </view>
  87 + </block>
  88 + <view class="flex jc_sb ai_c pd20">
  89 + <view class="fs30">合计:
  90 + <text class="rmb c-red fs40">{{filters.toFix(all_price,2)}}</text>
  91 + <text class="iconfont icon-info cb fs24 mgl10" bindtap="showInfo"></text>
  92 + </view>
  93 + <view bindtap="go_cart" class="btn-container">去购物车</view>
  94 + </view>
  95 + </view>
  96 + <!-- 分享 -->
  97 + <view wx:if="{{imgDraw}}" class="share-container" bindtap="share">
  98 + <text class="iconfont icon-zhuanfa fs40"></text>
  99 + <view class="fs22 c-8">分享</view>
  100 + </view>
  101 +
  102 +
  103 + <!-- 规则详情和提示信息弹窗 -->
  104 + <view class="rule-pop-container" wx:if="{{showRule}}">
  105 + <view class="pop-title">{{!type ? '规则详情':'提示'}}
  106 + <text class="iconfont icon-guan" bindtap="closeRule"></text>
  107 + </view>
  108 + <block wx:if="{{!type}}">
  109 + <view class="pdt40">
  110 + <view class="pdb20">活动时间</view>
  111 + <view class="">{{filters.format_time(act.start_time,1)}} 至 {{filters.format_time(act.end_time,1)}}
  112 + </view>
  113 + </view>
  114 + <view class="pdt40">
  115 + <view class="pdb20">活动内容</view>
  116 + <view class="">
  117 + <view class="pdb10">{{act.remark}}</view>
  118 + </view>
  119 + </view>
  120 + </block>
  121 +
  122 + <!-- 小的提示按钮的展示 -->
  123 + <block wx:else>
  124 + <view class="pdt40 pdb20">
  125 + <view class="">合计金额及提示仅为初步预估,请以最终下单金额为准。</view>
  126 + </view>
  127 + </block>
  128 +
  129 + <view class="pdv20">
  130 + <view class="btn" bindtap="closeRule">我知道了</view>
  131 + </view>
  132 + </view>
  133 +
  134 + <!-- 遮罩层 -->
  135 + <view class="mask" wx:if="{{showMask}}" bindtap="close_all"></view>
  136 + <!-- 海报 -->
  137 + <view class="poster-container" wx:if="{{showPoster}}">
  138 + <view class="t-r pdb20 white2">
  139 + <text class="iconfont icon-close fs40" bindtap="closePoster"></text>
  140 + </view>
  141 + <image src="{{myimg}}" class="poster" show-menu-by-longpress></image>
  142 + <view class="pdt10 fs26 white2">
  143 + <text class="iconfont icon-zhiwen"></text>
  144 + 长按图片保存至相册
  145 + </view>
  146 + </view>
  147 +
  148 +</view>
  149 +
  150 +<painter style="position: absolute; top: -9999rpx;" palette="{{imgDraw}}" bind:imgOK="onImgOK"/>
  151 +<!-- 活动异常提醒 -->
  152 +<!-- <catch>当前活动已结束</catch> -->
  153 +<warn id="warn"></warn>
  154 +<!-- 选择门店的弹框,1.1版最新的 -->
  155 +<block wx:if="{{store==1}}">
  156 + <view class="mongolia-layer" bindtap="close_popup"></view>
  157 + <view class="popup-frame">
  158 + <block wx:if="{{sort_store==0}}">
  159 + <!-- 头部 标题 -->
  160 + <view class="popup-top flex-space-between">
  161 + <text class="fs32 nearby_store">{{choice_sort_store==0?'附近的门店':region_name}}</text>
  162 + <view>
  163 + <view>
  164 + <icon bindtap="close_popup" class="modal-closes" color="black" size="22" type="cancel"></icon>
  165 + </view>
  166 + <view class="flex choose_more" bindtap="more_store">
  167 + <text class="fs26 red-co" style="line-height: 30rpx;height: 30rpx" wx:if="{{is_show_sto_cat}}">{{choice_sort_store==0?'更多门店':'返回'}}</text>
  168 + <view class="bg_rights" wx:if="{{is_show_sto_cat}}"></view>
  169 + </view>
  170 + </view>
  171 + </view>
  172 + <!-- 门店列表,最外层的门店列表,一开始 -->
  173 + <view class="store-list">
  174 + <!--如果还没有点击更多门店的时候 -->
  175 + <block wx:if="{{choice_sort_store==0}}">
  176 + <!-- 需要for循环 -->
  177 + <block wx:if="{{is_show_sto_cat==1}}">
  178 + <view class="store_choose flex" wx:for="{{def_pickpu_list}}" bindtap="choose_for_store_fir"
  179 + data-ind="{{index}}">
  180 + <view class="store flex-vertical">
  181 + <!-- 需要点击事件 -->
  182 + <block wx:if="{{index==fir_pick_index}}">
  183 + <view class="circle white xc-hook fs20 red-b">Г</view>
  184 + </block>
  185 + <block wx:else>
  186 + <view class="circle xc-hooks"></view>
  187 + </block>
  188 + <view class="address-frame xc-ash">
  189 + <view class="flex-vertical-between butttem5">
  190 + <view class="flex xc-ash">
  191 + <view class="fs30 xc-black3 address_name">{{item.pickup_name}}
  192 + <text wx:if="{{item.pickup_id==is_no_pipei}}" class="c-red">(不匹配)</text>
  193 + </view>
  194 + </view>
  195 + <view>
  196 + <view class="distance fs24 address-val" wx:if="{{item.distance!=null}}">
  197 + 距离:{{item.distance>1000?filters.toFix(item.distance/1000,2)+'km':filters.toFix(item.distance,0)+"m"}}
  198 + </view>
  199 + </view>
  200 + </view>
  201 + <view class="fs24 xc-ash-9f">地址:{{item.fulladdress}}</view>
  202 + </view>
  203 + </view>
  204 + </view>
  205 + </block>
  206 + <block wx:else>
  207 + <view class="store_choose flex" wx:for="{{only_pk}}" bindtap="choose_for_store_fir"
  208 + data-ind="{{index}}">
  209 + <view class="store flex-vertical">
  210 + <!-- 需要点击事件 -->
  211 + <block wx:if="{{index==fir_pick_index}}">
  212 + <view class="circle white xc-hook fs20 red-b">Г</view>
  213 + </block>
  214 + <block wx:else>
  215 + <view class="circle xc-hooks"></view>
  216 + </block>
  217 +
  218 + <view class="address-frame xc-ash">
  219 + <view class="flex-vertical-between ">
  220 + <view class="flex xc-ash">
  221 + <view class="fs30 xc-black3 address_name">{{item.pickup_name}}
  222 + <text wx:if="{{item.pickup_id==is_no_pipei}}" class="c-red">(不匹配)</text>
  223 + </view>
  224 + </view>
  225 + <view>
  226 + <view class="distance fs24 address-val"
  227 + wx:if="{{item.distance!=null}}">
  228 + 距离:{{item.distance>1000?filters.toFix(item.distance/1000,2)+"km":filters.toFix(item.distance,0)+"m"}}
  229 + </view>
  230 + </view>
  231 + </view>
  232 + <view class="fs24 xc-ash-9f">地址:{{item.fulladdress}}</view>
  233 + </view>
  234 + </view>
  235 + </view>
  236 + </block>
  237 + </block>
  238 + <block wx:else> <!-- 如果是点击选择门店分类后显示分类下的门店 -->
  239 + <view class="store_choose flex" wx:for="{{sec_sto.s_arr}}" data-ind="{{index}}"
  240 + bindtap="choose_for_store">
  241 + <view class="store flex-vertical">
  242 + <!-- 需要点击事件 -->
  243 + <block wx:if="{{index==sec_pick_index}}">
  244 + <view class="circle white xc-hook fs20 red-b">Г</view>
  245 + </block>
  246 + <block wx:else>
  247 + <view class="circle xc-hooks"></view>
  248 + </block>
  249 +
  250 + <view class="address-frame xc-ash">
  251 + <view class="flex-vertical-between ">
  252 + <view class="flex xc-ash">
  253 + <view class="fs28 xc-black3 address_name">{{item.pickup_name}}</view>
  254 + </view>
  255 + <view>
  256 + <view class="distance fs24 address-val" wx:if="{{item.distance!=null}}">
  257 + 距离:{{item.distance>1000?filters.toFix(item.distance/1000,2)+"km":filters.toFix(item.distance,0)+"m"}}
  258 + </view>
  259 + </view>
  260 + </view>
  261 + <view class="fs24 xc-ash-9f">地址:{{item.fulladdress}}</view>
  262 + </view>
  263 + </view>
  264 + </view>
  265 + </block>
  266 +
  267 + </view>
  268 +
  269 + <!-- 门店列表底部 -->
  270 + <view class="store-bottom-frame">
  271 + <view class="store-bottom flex-vertical-between">
  272 + <view class="determine red-b fs28 white t-c" bindtap="sure_pick"
  273 + data-openindstore="{{open_ind_store}}">确定
  274 + </view>
  275 + <view class="default t-c fs28" bindtap="set_def_pick" data-openindstore="{{open_ind_store}}">设为默认
  276 + </view>
  277 + </view>
  278 + </view>
  279 +
  280 + </block>
  281 +
  282 +
  283 + <block wx:else>
  284 + <view class="popup-top flex-space-between">
  285 + <text class="fs32 nearby_store">门店分类选择</text>
  286 + <view>
  287 + <view>
  288 + <icon bindtap="close_popup" class="modal-closes" color="black" size="22" type="cancel"></icon>
  289 + </view>
  290 + <view class="felx choose_mores" bindtap="returns">
  291 + <text class="fs26 red-co">返回</text>
  292 + </view>
  293 + </view>
  294 + </view>
  295 + <view class="sort_store_list">
  296 +
  297 + <view class="sort-store-frame" wx:for="{{all_sto}}" data-index="{{index}}" bindtap="choice_sort_store"
  298 + data-region="{{item.name}}">
  299 + <view class="sort-store flex-vertical-between">
  300 + <view class="fs30" di>{{item.name}}</view>
  301 + <view class="black_rights-frame">
  302 + <view class="black_rights"></view>
  303 + </view>
  304 + </view>
  305 + </view>
  306 +
  307 + </view>
  308 + </block>
  309 + </view>
  310 +</block>
  311 +
  312 +
  313 +
... ...
packageB/pages/zuhegou/index/index.wxss 0 → 100644
  1 +/* packageB//pages/zuhegou/index/index.wxss */
  2 +page {
  3 + background: #f5f5f5 linear-gradient(to bottom, #FB5A2F, #FA7958, #f5f5f5 26%) no-repeat;
  4 +}
  5 +.container {
  6 + padding: 20rpx;
  7 +}
  8 +.countdown-container {
  9 + font-size: 26rpx;
  10 + padding-top: 10rpx;
  11 + color: white;
  12 +}
  13 +
  14 +.num-box {
  15 + display: inline-block;
  16 + background-color: rgba(255,255,255,.2);
  17 + box-sizing: border-box;
  18 + min-width: 40rpx;
  19 + padding: 4rpx;
  20 + margin: 0 8rpx;
  21 + border-radius: 6rpx;
  22 + text-align: center;
  23 +}
  24 +
  25 +.rule-container {
  26 + font-size: 24rpx;
  27 + background-color: rgba(255,255,255,.2);
  28 + padding: 10rpx 5rpx 10rpx 20rpx;
  29 + border-radius: 26rpx 0 0 26rpx;
  30 + margin-right: -20rpx;
  31 + color: white;
  32 +}
  33 +
  34 +.icon-arrow_right {
  35 + font-size: 24rpx;
  36 +}
  37 +
  38 +.list-container {
  39 + padding-top: 30rpx;
  40 +}
  41 +
  42 +.list {
  43 + border-radius: 10rpx;
  44 + background-color: white;
  45 + max-height:calc(100vh - 360rpx);
  46 +}
  47 +
  48 +.list-item {
  49 + padding: 20rpx;
  50 + display: flex;
  51 +}
  52 +
  53 +.img-container {
  54 + width: 200rpx;
  55 + height: 200rpx;
  56 + background-color: #f0f0f0;
  57 + border-radius: 8rpx;
  58 +}
  59 +
  60 +.num-container {
  61 + font-size: 28rpx;
  62 + padding-top: 10rpx;
  63 + text-align: right;
  64 +}
  65 +
  66 +.num-container .num-box {
  67 + background-color: #f3f3f3;
  68 +}
  69 +
  70 +
  71 +
  72 +.noMore {
  73 + padding: 20rpx;
  74 + color: #bbb;
  75 + text-align: center;
  76 + font-size: 26rpx;
  77 +}
  78 +
  79 +.rmb::before {
  80 + content: '¥';
  81 + font-size: 22rpx;
  82 +}
  83 +
  84 +.bar-container {
  85 + position: fixed;
  86 + left: 0;
  87 + bottom: 0;
  88 + width: 100%;
  89 + background-color: white;
  90 +}
  91 +
  92 +.bg-fcfb {
  93 + background-color: #FCFBE5;
  94 +}
  95 +
  96 +.c-fa8b2b {
  97 + color: #FA8B2B;
  98 +}
  99 +
  100 +.c-8 {
  101 + color: #888;
  102 +}
  103 +
  104 +.c-dedfe3 {
  105 + color: #DEDFE3;
  106 +}
  107 +
  108 +.btn-container {
  109 + padding: 16rpx 40rpx;
  110 + background-color: red;
  111 + color: white;
  112 + font-size: 30rpx;
  113 + border-radius: 36rpx;
  114 + background: -webkit-linear-gradient(left,#ff5000,#ff2000) no-repeat;
  115 +}
  116 +
  117 +.share-container {
  118 + position: fixed;
  119 + right: 20rpx;
  120 + bottom: 200rpx;
  121 + width: 100rpx;
  122 + height: 100rpx;
  123 + border-radius: 50%;
  124 + background-color: white;
  125 + display: flex;
  126 + flex-direction: column;
  127 + justify-content: center;
  128 + align-items: center;
  129 + box-shadow: 0 0 16rpx #CCC;
  130 +}
  131 +
  132 +.mask {
  133 + position: fixed;
  134 + top: 0;
  135 + bottom: 0;
  136 + left: 0;
  137 + right: 0;
  138 + background-color: rgba(0,0,0,.6);
  139 +}
  140 +
  141 +.rule-pop-container {
  142 + position: fixed;
  143 + left: 0;
  144 + bottom: 0;
  145 + width: 100%;
  146 + background-color: white;
  147 + z-index: 1;
  148 + border-radius: 16rpx 16rpx 0 0;
  149 + padding: 0 40rpx;
  150 + box-sizing: border-box;
  151 + font-size: 28rpx;
  152 + color: #444;
  153 +}
  154 +
  155 +.pop-title {
  156 + padding: 20rpx 0;
  157 + text-align: center;
  158 + font-size: 32rpx;
  159 + position: relative;
  160 +}
  161 +.icon-guan {
  162 + position: absolute;
  163 + right: 0;
  164 + font-size: 26rpx;
  165 + top: 50%;
  166 + transform: translateY(-50%);
  167 + color: #ccc;
  168 +}
  169 +
  170 +.btn {
  171 + color: white;
  172 + padding: 20rpx 0;
  173 + text-align: center;
  174 + border-radius: 40rpx;
  175 + background: -webkit-linear-gradient(left,#ff5000,#ff2000) no-repeat;
  176 +}
  177 +
  178 +.active {
  179 + color: #ccc;
  180 +}
  181 +
  182 +.poster-container {
  183 + text-align: center;
  184 + color: white;
  185 + position: fixed;
  186 + top: 50%;
  187 + left: 50%;
  188 + transform: translate(-50%, -50%);
  189 +}
  190 +
  191 +.poster {
  192 + width: 650rpx;
  193 + height: 843rpx;
  194 + border-radius: 16rpx;
  195 + margin: 0 auto;
  196 +}
  197 +
  198 +.white2 {
  199 + color: rgba(255,255,255,.8);
  200 +}
  201 +
  202 +
  203 +
  204 +/* 选择门店的弹窗 */
  205 +.mongolia-layer{
  206 + position: fixed;
  207 + left: 0;
  208 + top: 0;
  209 + right: 0;
  210 + bottom: 0;
  211 + z-index: 11;
  212 + background: rgba(0,0,0,0.4);
  213 + width: 100%;
  214 + height: 91.9%;
  215 +
  216 +}
  217 +
  218 +.popup-frame{
  219 + position: fixed;
  220 + z-index: 20;
  221 + background: white;
  222 + width: 100%;
  223 + border-radius: 20rpx 20rpx 0 0;
  224 + height: auto;
  225 + bottom: 0;
  226 +}
  227 +.popup-top{
  228 + border-bottom: 1rpx solid #eee;
  229 + height: 155rpx;
  230 + width: 95%;
  231 + margin: auto;
  232 + line-height: 155rpx;
  233 +
  234 +}
  235 +.bg_rights{
  236 + border-top: 2rpx solid ;
  237 + border-right: 2rpx solid ;
  238 + transform: rotate(45deg);
  239 + display:inline-block;
  240 + width:15rpx;height:15rpx;
  241 + border-color:#da0b31;
  242 + position: relative;
  243 + top:5rpx
  244 +}
  245 +.modal-closes {
  246 + position: absolute;
  247 + right: 30rpx;
  248 + top: -15rpx;
  249 + height: 25rpx;
  250 +
  251 +}
  252 +.choose_more{
  253 + margin-top: 100rpx;
  254 + margin-right: 20rpx;
  255 +
  256 +}
  257 +.choose_mores{
  258 + margin-top: 30rpx;
  259 + margin-right: 15rpx;
  260 +
  261 +}
  262 +.store-list{
  263 + width: 95%;
  264 + min-height: 300rpx;
  265 + overflow-y: scroll;
  266 + margin: auto;
  267 + max-height: 610rpx;
  268 +}
  269 +.store-list .store_choose{
  270 + width: 100%;
  271 + height: 120rpx;
  272 + line-height: 125rpx;
  273 + border-bottom: 1rpx solid #eee;
  274 +
  275 +}
  276 +.store-list .store_choose .store{
  277 + width: 100%;
  278 + margin: auto;
  279 + line-height: 37rpx;
  280 + padding-left: 20rpx;
  281 +
  282 +}
  283 +.xc-hook{
  284 + width: 35rpx;
  285 + height: 35rpx;
  286 + transform: rotate(-145deg);
  287 + line-height: 37rpx;
  288 + text-align: center;
  289 +}
  290 +.xc-hooks{
  291 + width: 30rpx;
  292 + height: 30rpx;
  293 + border: 1rpx solid #999;
  294 +}
  295 +.address-frame{
  296 + width: 93%;
  297 + margin-left: 7rpx;
  298 +
  299 +}
  300 +.nearby_store{
  301 + margin-left: 17rpx;
  302 +}
  303 +.address_name{
  304 + margin-right: 10rpx;
  305 +
  306 +}
  307 +.address-val{
  308 + height: 38rpx;
  309 + line-height: 38rpx;
  310 +
  311 +}
  312 +.store-bottom{
  313 + width: 85%;
  314 + margin: auto;
  315 + height: 90rpx;
  316 +}
  317 +.determine{
  318 + width: 260rpx;
  319 + height: 55rpx;
  320 + border-radius: 50rpx;
  321 + line-height: 55rpx;
  322 +}
  323 +.default{
  324 + width: 260rpx;
  325 + height: 55rpx;
  326 + border:3rpx solid #c8c8c8;
  327 + border-radius: 50rpx;
  328 + line-height: 55rpx;
  329 +}
  330 +.store-bottom-frame{
  331 + width: 95%;
  332 + margin: auto;
  333 +
  334 +}
  335 +/* 门店分类列表 */
  336 +.sort_store_list{
  337 + height: 82%;
  338 + overflow: hidden;
  339 + overflow-y: scroll;
  340 + width: 95%;
  341 + margin: auto;
  342 +}
  343 +.sort_store_list .sort-store-frame{
  344 + width: 100%;
  345 + height: 100rpx;
  346 + line-height:100rpx;
  347 + border-bottom: 1rpx solid #eee;
  348 +
  349 +}
  350 +.sort_store_list .sort-store-frame .sort-store{
  351 + width: 94.5%;
  352 + margin: auto;
  353 +}
  354 +
  355 +.c_w{ color: #fff;}
  356 +.mt10{ margin-top: 10rpx;}
  357 +.mt20{ margin-top: 20rpx;}
0 358 \ No newline at end of file
... ...
pages/giftpack/festival/festival.js
... ... @@ -175,21 +175,20 @@ Page({
175 175 }
176 176 },
177 177 function (res) {
178   -
179 178 }
180   -
181 179 )
182   -
183 180 }
184 181 },
185 182 //获取节日有礼信息
186 183 is_festival: function(e) {
187 184 var th = this;
188 185 var url = "/api/weshop/marketing/holiday/act/judge";
  186 + console.log(th.data.getActId);
189 187 getApp().request.promiseGet(url, {
190 188 data: {
191 189 storeId: a.stoid, //商家ID
192   - userId: d.user_id //用户ID
  190 + userId: d.user_id, //用户ID
  191 + id:th.data.getActId
193 192 }
194 193 }).then(res => {
195 194 if (res.data.code == 0) {
... ... @@ -197,7 +196,6 @@ Page({
197 196 bimg: res.data.data.actImg,
198 197 actFontColor: res.data.data.actFontColor, //字体颜色
199 198 actBgColor: res.data.data.actBgColor, //背景颜色
200   -
201 199 })
202 200 }
203 201 })
... ...
pages/giftpack/festival/festival.wxml
1 1 <view style="background-color:{{actBgColor==undefined?'#FFB72D':actBgColor}}">
2 2 <view class="image_box">
3   - <image src="{{iurl+bimg}}" lazy-load="true"></image>
  3 + <image src="{{iurl+bimg?bimg:'/miniapp/images/default_g_img.gif'}}" binderror="bind_bnerr1" data-errorimg="bimg" lazy-load="true"></image>
4 4 </view>
5 5 <block wx:if="{{itemShow}}">
6 6 <view class="top rel">
... ...
pages/goods/goodsInfo/goodsInfo.js
... ... @@ -253,9 +253,9 @@ Page({
253 253  
254 254 //------初始化加载----------
255 255 onLoad: function(t) {
256   - wx.setNavigationBarTitle({
257   - title: t.title,
258   - })
  256 +
  257 +
  258 +
259 259 var ee = this,
260 260 that = ee,
261 261 th = ee,
... ... @@ -773,7 +773,11 @@ Page({
773 773 });
774 774 }
775 775 }
776   -
  776 + //动态获取商品名称
  777 + wx.setNavigationBarTitle({
  778 + title: t.data.data.goods_name,
  779 + })
  780 +
777 781 //-- 把商品的赋值 --
778 782 ee.data.fir_goods=JSON.parse(JSON.stringify(t.data.data));
779 783 ee.check_is_youhui(ee.data.gid);
... ... @@ -2098,7 +2102,6 @@ Page({
2098 2102 async get_sku(stoid, gd, g_id, is_normal, func) {
2099 2103 var tt = this,arrdata=null;
2100 2104 var now=ut.gettimestamp();
2101   -
2102 2105 await getApp().request.promiseGet("/api/weshop/goods/page", {
2103 2106 data: {
2104 2107 store_id: o.stoid,
... ... @@ -4210,10 +4213,10 @@ Page({
4210 4213 if(th.data.poster){
4211 4214 var erm_x= parseFloat(th.data.poster.ewm_x)*2;
4212 4215 var erm_y= parseFloat(th.data.poster.ewm_y)*2;
4213   - context.drawImage(vpath, erm_x * unit, erm_y * unit, 120 * unit, 120 * unit);
  4216 + context.drawImage(vpath, erm_x * unit, erm_y * unit, 136 * unit, 136 * unit);
4214 4217 }else{
4215 4218 //---二维吗图---
4216   - context.drawImage(vpath, 410 * unit, 726 * unit, 115 * unit, 125 * unit);
  4219 + context.drawImage(vpath, 390 * unit, 726 * unit, 136 * unit, 136 * unit);
4217 4220 }
4218 4221  
4219 4222 break;
... ... @@ -4243,10 +4246,10 @@ Page({
4243 4246 if(th.data.poster){
4244 4247 var erm_x= parseFloat(th.data.poster.ewm_x)*2;
4245 4248 var erm_y= parseFloat(th.data.poster.ewm_y)*2;
4246   - context.drawImage(vpath, erm_x * unit, erm_y * unit, 120 * unit, 120 * unit);
  4249 + context.drawImage(vpath, erm_x * unit, erm_y * unit, 135 * unit, 135 * unit);
4247 4250 }else{
4248 4251 //---二维吗图---
4249   - context.drawImage(vpath, 420 * unit, 726 * unit, 120 * unit, 120 * unit);
  4252 + context.drawImage(vpath, 390 * unit, 726 * unit, 135 * unit, 135 * unit);
4250 4253 }
4251 4254 break;
4252 4255  
... ... @@ -4290,10 +4293,10 @@ Page({
4290 4293 if(th.data.poster){
4291 4294 var erm_x= parseFloat(th.data.poster.ewm_x)*2;
4292 4295 var erm_y= parseFloat(th.data.poster.ewm_y)*2;
4293   - context.drawImage(vpath, erm_x * unit, erm_y * unit, 120 * unit, 120 * unit);
  4296 + context.drawImage(vpath, erm_x * unit, erm_y * unit, 136 * unit, 136 * unit);
4294 4297 }else{
4295 4298 //---二维吗图---
4296   - context.drawImage(vpath, 420 * unit, 726 * unit, 120 * unit, 120 * unit);
  4299 + context.drawImage(vpath, 390 * unit, 726 * unit, 136 * unit, 136 * unit);
4297 4300 }
4298 4301 break
4299 4302 case 3: //阶梯团的展示
... ... @@ -4334,7 +4337,7 @@ Page({
4334 4337 context.setFillStyle("black")
4335 4338 context.fillText("快来和我一起拼团吧!", 40 * unit, 820 * unit);
4336 4339 //context.font = 'normal bold 18px sans-serif';
4337   - context.setFontSize(22 * unit)
  4340 + context.setFontSize(21 * unit)
4338 4341 context.fillText("长按识别二维码,立即参团", 40 * unit, 850 * unit);
4339 4342  
4340 4343  
... ... @@ -4342,10 +4345,10 @@ Page({
4342 4345 if(th.data.poster){
4343 4346 var erm_x= parseFloat(th.data.poster.ewm_x)*2;
4344 4347 var erm_y= parseFloat(th.data.poster.ewm_y)*2;
4345   - context.drawImage(vpath, erm_x * unit, erm_y * unit, 120 * unit, 120 * unit);
  4348 + context.drawImage(vpath, erm_x * unit, erm_y * unit, 136 * unit, 136 * unit);
4346 4349 }else{
4347 4350 //---二维吗图---
4348   - context.drawImage(vpath, 420 * unit, 726 * unit, 120 * unit, 120 * unit);
  4351 + context.drawImage(vpath, 390 * unit, 726 * unit, 136 * unit, 136 * unit);
4349 4352 }
4350 4353 break
4351 4354  
... ...
pages/index/index/index.js
... ... @@ -978,15 +978,25 @@ Page({
978 978 var giftBagId = res.data.data.gifBagId; //礼包id
979 979 var nav_url = "/pages/giftpack/festival/festival?actId=" + actid + '&' + 'actType=' + 3 + '&' + 'giftBagId=' + giftBagId;
980 980 var swiperimage = th.data.swiperimage;
981   - var actBoundImg = res.data.data.actBoundImg;
  981 + var actBoundImg = res.data.data.actBoundImg?res.data.data.actBoundImg:'/miniapp/images/default_g_img.gif';
982 982  
983 983 th.data.holiday_image= res.data.data.actImg;
984 984 th.data.holiday_url=nav_url;
985 985  
986 986 var img = {
987 987 image: actBoundImg,
988   - nav_url: nav_url
  988 + nav_url: nav_url,
  989 + id:res.data.data.id,
  990 + type:'festival'
989 991 }
  992 +
  993 + for(var i in swiperimage){
  994 + var item=swiperimage[i];
  995 + if(item.id ==img.id && item.type==img.type){
  996 + return false;
  997 + }
  998 + }
  999 +
990 1000 swiperimage.unshift(img);
991 1001 th.setData({
992 1002 swiperimage: swiperimage,
... ...
pages/index/index/index.wxml
... ... @@ -9,7 +9,7 @@
9 9 <!--普通界面-->
10 10 <wxs module="filter" src="../../../utils/filter.wxs"></wxs>
11 11  
12   -<view class="container rel" wx:if="{{ishow}}">
  12 +<view class="container rel nor" wx:if="{{ishow}}">
13 13 <block wx:if="{{banner}}">
14 14 <image class="xc-top-img abs" src="{{url}}/miniapp/images/top-img.png"></image>
15 15 </block>
... ...
pages/index/index/index.wxss
... ... @@ -9,7 +9,6 @@
9 9 z-index: 99;
10 10 }
11 11  
12   -
13 12 .search-box {
14 13 /* position: fixed;
15 14 top: 0;
... ... @@ -976,6 +975,10 @@ page {
976 975  
977 976 .container {
978 977 overflow: hidden;
  978 + /* padding-top: 140rpx; */
  979 +}
  980 +
  981 +.container.nor{
979 982 padding-top: 140rpx;
980 983 }
981 984  
... ...
pages/user/binding_info/binding_info.js deleted
1   -var e = getApp(),app=e, a = e.request, t = e.globalData.setting,os=t, i = require("../../../utils/common.js");
2   -
3   -Page({
4   - data: {
5   - url: t.url,
6   - iurl: t.imghost,
7   - nickName: "",
8   - userHeadPic: "",
9   - isRegist: !1,
10   - bindMobile: "",
11   - bindCode: "",
12   - regMobile: "",
13   - regCode: "",
14   - regPwd: "",
15   - isAgree: !1,
16   - canGetCode: !1,
17   -
18   - config:null,
19   -
20   - store: null,
21   - imghots: os.imghost,
22   - gettime:0,
23   - },
24   - onLoad: function(e) {
25   - var th=this;
26   - app.getConfig(function (e) {
27   - th.setData({ store: e });
28   - })
29   - app.getConfig2(function (e) {
30   - var cf = JSON.parse(e.sms_send_type);
31   - th.setData({ config: cf });
32   - console.log(th.data.config);
33   - })
34   -
35   -
36   - },
37   - account: function() {
38   - this.setData({
39   - isRegist: !1
40   - });
41   - },
42   - regist: function() {
43   - this.setData({
44   - isRegist: !0
45   - });
46   - },
47   - setMobile: function(e) {
48   - this.data.bindMobile = e.detail.value;
49   - },
50   - setCode: function(e) {
51   - this.data.bindCode = e.detail.value;
52   - },
53   -
54   - //---获取短信验证码---
55   - getCode: function(t) {
56   - var th=this;
57   - if ("" != this.data.bindMobile) {
58   - var s = this;
59   - a.post("/api/weshop/smslog/sendsms", {
60   - data: {
61   - mobile: this.data.bindMobile,
62   - store_id: os.stoid,
63   - wxopenid: app.globalData.openid,
64   - },
65   - success: function(e) {
66   - if(e.data.code==0){
67   - th.setData({ gettime: th.data.config.time_out, canGetCode:1});
68   - th.setInt();
69   - }else{
70   - e.showWarning(e.data.msg);
71   - }
72   - }
73   - });
74   - } else e.showWarning("请输入手机号码");
75   - },
76   -
77   - //----发送验证码的推送时间倒计时---
78   - setInt:function(){
79   - var th=this;
80   - var it=setInterval(function(){
81   - var ti = th.data.gettime-1;
82   - if (ti<=0){
83   - th.setData({ gettime:0, canGetCode: !1 });
84   - clearInterval(it);
85   - }
86   - else{
87   - th.setData({ gettime: ti,});
88   - }
89   - },1000);
90   - },
91   -
92   - setRegMobile: function(e) {
93   - this.data.regMobile = e.detail.value;
94   - },
95   - setRegPwd: function(e) {
96   - this.data.regPwd = e.detail.value;
97   - },
98   - setRegCode: function(e) {
99   - this.data.regCode = e.detail.value;
100   - },
101   - getRegCode: function(t) {
102   - if ("" != this.data.regMobile) {
103   - var s = this;
104   - a.post("/Home/Api/checkRegMobile", {
105   - data: {
106   - mobile: this.data.regMobile
107   - },
108   - success: function(e) {
109   - i.sendBindSmsCode(s.data.regMobile);
110   - }
111   - });
112   - } else e.showWarning("请输入手机号码");
113   - },
114   - check: function() {
115   - this.setData({
116   - isAgree: !this.data.isAgree
117   - });
118   - },
119   - bindAccount: function() {
120   - var t = this;
121   - var r = getApp().globalData.getu;
122   - var openid = getApp().globalData.openid;
123   -
124   - "" != this.data.bindMobile ? "" != this.data.bindCode ? a.get("/api/weshop/users/thirdLogin", {
125   - data: {
126   - mobile: t.data.bindMobile,
127   - code: t.data.bindCode,
128   - openid: openid,
129   - nickname: r.nickName,
130   - head_pic: r.avatarUrl,
131   - sex: r.gender,
132   - store_id:os.stoid,
133   - },
134   - success: function(a) {
135   - if(a.data.code==0){
136   - wx.setStorageSync("isAuth", !0),
137   - e.globalData.userInfo = a.data.data,
138   - e.globalData.user_id = e.globalData.userInfo.user_id, e.globalData.userInfo.head_pic = i.getFullUrl(e.globalData.userInfo.head_pic),
139   - "function" == typeof cb && cb(e.globalData.userInfo, e.globalData.wechatUser);
140   - e.showWarning("绑定成功");
141   - setTimeout(function(){
142   - wx.navigateTo({
143   - url: '/pages/user/index/index',
144   - })
145   - },1000);
146   - }else{
147   - e.showWarning("请输入验证码")
148   - }
149   - }
150   - }) : e.showWarning("请输入验证码") : e.showWarning("请输入手机号码");
151   - },
152   -
153   - bindReg: function() {
154   - var t = this;
155   - if( "" != this.data.regMobile ){
156   - e.showWarning("请输入手机号码"); return false;
157   - }else if( "" != this.data.regCode){
158   - e.showWarning("请输入验证码"); return false;
159   - }else {
160   - var openid = getApp().globalData.openid;
161   - var r = getApp().globalData.getu;
162   - a.post("/api/weshop/users/thirdLogin", {
163   - data: {
164   - mobile: t.data.regMobile,
165   - verify_code: t.data.regCode,
166   - openid: openid,
167   - nickname: r.nickName,
168   - head_pic: r.avatarUrl,
169   - sex: r.gender,
170   - },
171   - success: function(a) {
172   - console.log("thirdLogin");
173   - console.log(e);
174   - if (e.data.code == 0) {
175   - app.globalData.user_id = e.data.data.user_id;
176   - } else {
177   - return app.showWarning("授权登入失败!");
178   - }
179   - wx.setStorageSync("isAuth", !0), a.globalData.userInfo = e.data.data, a.globalData.userInfo.head_pic = t.getFullUrl(a.globalData.userInfo.head_pic);
180   - wx.navigateBack({ delta: 1 })
181   - }
182   - })
183   - }
184   - }
185   -});
186   -
187   -function randomNum(min, max) {
188   - return Math.floor(Math.random() * (max - min) + min);
189   -}
190   -/**生成一个随机色**/
191   -function randomColor(min, max) {
192   - var r = randomNum(min, max);
193   - var g = randomNum(min, max);
194   - var b = randomNum(min, max);
195   - return "rgb(" + r + "," + g + "," + b + ")";
196   -}
197   -
198   -/**绘制验证码图片**/
199   -function drawPic(that) {
200   - ctx = wx.createCanvasContext('canvas');
201   - /**绘制背景色**/
202   - ctx.fillStyle = randomColor(180, 240); //颜色若太深可能导致看不清
203   - ctx.fillRect(0, 0, 90, 28)
204   - /**绘制文字**/
205   - var arr;
206   - var text = '';
207   - var str = 'ABCEFGHJKLMNPQRSTWXY123456789';
208   - for (var i = 0; i < 4; i++) {
209   - var txt = str[randomNum(0, str.length)];
210   - ctx.fillStyle = randomColor(50, 160); //随机生成字体颜色
211   - ctx.font = randomNum(20, 26) + 'px SimHei'; //随机生成字体大小
212   - var x = 5 + i * 20;
213   - var y = randomNum(20, 25);
214   - var deg = randomNum(-20, 20);
215   - //修改坐标原点和旋转角度
216   - ctx.translate(x, y);
217   - ctx.rotate(deg * Math.PI / 180);
218   - ctx.fillText(txt, 5, 0);
219   - text = text + txt;
220   - //恢复坐标原点和旋转角度
221   - ctx.rotate(-deg * Math.PI / 180);
222   - ctx.translate(-x, -y);
223   - }
224   - /**绘制干扰线**/
225   - for (var i = 0; i < 4; i++) {
226   - ctx.strokeStyle = randomColor(40, 180);
227   - ctx.beginPath();
228   - ctx.moveTo(randomNum(0, 90), randomNum(0, 28));
229   - ctx.lineTo(randomNum(0, 90), randomNum(0, 28));
230   - ctx.stroke();
231   - }
232   - /**绘制干扰点**/
233   - for (var i = 0; i < 20; i++) {
234   - ctx.fillStyle = randomColor(0, 255);
235   - ctx.beginPath();
236   - ctx.arc(randomNum(0, 90), randomNum(0, 28), 1, 0, 2 * Math.PI);
237   - ctx.fill();
238   - }
239   - ctx.draw(false, function () {
240   - that.setData({
241   - text: text
242   - })
243   - });
244   -}
245 0 \ No newline at end of file
pages/user/binding_info/binding_info.wxml deleted
1   -<view>
2   - <view class="binding-top" style="background-image:url('{{iurl}}/miniapp/images/binding-bj.png')">
3   - <view class="user-logo">
4   - <image src="{{imghots+store.store_logo}}"></image>
5   - </view>
6   - <view class="user-text">
7   - <text>{{store.store_name}}</text>
8   -
9   - </view>
10   - <view class="userbj-cover">
11   - <image src="{{iurl}}/miniapp/images/white-cover.png"></image>
12   - </view>
13   - </view>
14   - <view class="binding-container">
15   - <!-- <view class="binding-tips">
16   - <text>为了给您更好地服务,请关注一个TPshop账号
17   -若还没有TPshop账号,则注册后默认完成关联</text>
18   - </view> -->
19   - <view>
20   - <!-- <view class="correlation-cont">
21   - <view bindtap="account" class="connect-item {{isRegist?'':'tp-list-bg'}}">关联已有账号</view>
22   - <view bindtap="regist" class="connect-item {{isRegist?'tp-list-bg':''}}">注册并关联账号</view>
23   - </view> -->
24   -
25   - <view class="correlation-input-wrap">
26   - <view class="items-warp" hidden="{{isRegist}}">
27   - <view class="item_cont">
28   - <image src="{{iurl}}/miniapp/images/numb.png"></image>
29   - <text>手机号码</text>
30   - <input bindinput="setMobile" id="username" name="username" placeholder="请输入手机号码" type="number"></input>
31   - </view>
32   -
33   - <view class="item_cont ">
34   - <image src="{{iurl}}/miniapp/images/code.png"></image>
35   - <text decode="{{true}}" space="{{true}}">验&nbsp;证&nbsp;&nbsp;码</text>
36   - <input bindinput="setCode" id="password" name="password" placeholder="请输入验证码" type="number"></input>
37   - <button wx:if="{{canGetCode}}" class="tp-get-gode btn-disable">
38   - {{gettime>0?gettime:""}}秒后重发
39   - </button>
40   - <button wx:else bindtap="getCode" class="tp-get-gode"> 获取验证码</button>
41   - </view>
42   - <view class="item-cont">
43   - <button bindtap="bindAccount" class="correlation-submit">立即绑定</button>
44   - </view>
45   - </view>
46   - <view class="items-warp" hidden="{{!isRegist}}">
47   - <view class="item_cont">
48   - <image src="{{iurl}}/miniapp/images/numb.png"></image>
49   - <text>手机号码</text>
50   - <input bindinput="setRegMobile" id="username" name="username" placeholder="请输入手机号码" type="number"></input>
51   - </view>
52   - <view class="item_cont ">
53   - <image src="{{iurl}}/miniapp/images/password.png"></image>
54   - <text>设置密码</text>
55   - <input bindinput="setRegPwd" id="username" name="username" placeholder="字母和数字组成的6-16位字符" type="password"></input>
56   - </view>
57   - <view class="item_cont">
58   - <image src="{{iurl}}/miniapp/images/code.png"></image>
59   - <text decode="{{true}}" space="{{true}}">验&nbsp;证&nbsp;&nbsp;码</text>
60   - <input bindinput="setRegCode" id="password" name="password" placeholder="请输入验证码" type="number"></input>
61   - <button bindtap="getRegCode" class="tp-get-gode">获取验证码</button>
62   - </view>
63   - <view class="item-cont">
64   - <button bindtap="bindReg" class="correlation-submit">立即绑定</button>
65   - </view>
66   - </view>
67   - </view>
68   - </view>
69   - <view class="bingding-agreement" hidden="{{!isRegist}}">
70   - <checkbox bindtap="check" checked="{{isAgree}}"></checkbox>
71   - <label>我已阅读并同意</label>
72   - <navigator>《TPshop商城用户注册协议》</navigator>
73   - </view>
74   - </view>
75   -</view>
76   -
77   -
pages/user/binding_info/binding_info.wxss deleted
1   -page {
2   - background-color: #fff;
3   -}
4   -
5   -.binding-top {
6   - width: 100%;
7   - height: 450rpx;
8   - text-align: center;
9   - position: relative;
10   - overflow: hidden;
11   -}
12   -
13   -.user-logo {
14   - width: 190rpx;
15   - height: 190rpx;
16   - border-radius: 50%;
17   - border: 2px solid #fff;
18   - overflow: hidden;
19   - position: absolute;
20   - left: 50%;
21   - margin-left: -95rpx;
22   - top: 60rpx;
23   -}
24   -
25   -.user-logo image {
26   - width: 100%;
27   - height: 100%;
28   -}
29   -
30   -.user-text {
31   - margin-top: 142px;
32   -}
33   -
34   -.user-text text {
35   - display: block;
36   - margin-top: 16rpx;
37   - color: #fff;
38   -}
39   -
40   -.userbj-cover {
41   - width: 100%;
42   - height: 46rpx;
43   - position: absolute;
44   - left: 0;
45   - bottom: 0;
46   - z-index: 20;
47   -}
48   -
49   -.userbj-cover image {
50   - width: 100%;
51   - height: 46rpx;
52   -}
53   -
54   -.binding-container {
55   - width: 100%;
56   - padding-top: 15px;
57   -}
58   -
59   -.binding-tips {
60   - font-size: 14px;
61   - color: #666;
62   - text-align: center;
63   - letter-spacing: 2rpx;
64   -}
65   -
66   -.correlation-cont {
67   - width: 600rpx;
68   - margin: 0 auto;
69   - margin-top: 40rpx;
70   - overflow: hidden;
71   -}
72   -
73   -.connect-item {
74   - width: 296rpx;
75   - height: 78rpx;
76   - line-height: 78rpx;
77   - font-size: 16px;
78   - text-align: center;
79   - border: 1px solid #b7b7b7;
80   - float: left;
81   -}
82   -
83   -.correlation-cont .connect-item:first-child {
84   - border-bottom-left-radius: 30px;
85   - border-top-left-radius: 30px;
86   -}
87   -
88   -.correlation-cont .connect-item:last-child {
89   - border-bottom-right-radius: 30px;
90   - border-top-right-radius: 30px;
91   -}
92   -
93   -.tp-list-bg {
94   - color: #fff;
95   - background: #e23435;
96   - border: 1px solid #e23435!important;
97   -}
98   -
99   -.correlation-input-wrap {
100   - margin-top: 56rpx;
101   - width: 100%;
102   -}
103   -
104   -.item_cont {
105   - width: 660rpx;
106   - height: 96rpx;
107   - margin: 0 auto;
108   - position: relative;
109   - line-height: 96rpx;
110   - border-bottom: 1px solid #e6e6e6;
111   -}
112   -
113   -.item_cont image {
114   - width: 48rpx;
115   - height: 48rpx;
116   - vertical-align: middle;
117   -}
118   -
119   -.item_cont text {
120   - font-size: 16px;
121   - vertical-align: middle;
122   - color: #666;
123   - margin-left: 16rpx;
124   -}
125   -
126   -.item_cont input {
127   - border: 0px;
128   - font-size: 16px;
129   - height: 50rpx;
130   - line-height: 50rpx;
131   - display: inline-block;
132   - vertical-align: middle;
133   - width: 432rpx;
134   - margin-left: 30rpx;
135   -}
136   -
137   -.tp-get-gode {
138   - position: absolute;
139   - right: 0;
140   - top: 20rpx;
141   - border-radius: 30rpx;
142   - background-color: #f05052;
143   - color: #fff;
144   - height: 56rpx;
145   - width: 140rpx;
146   - font-size: 22rpx;
147   - line-height: 56rpx;
148   - z-index: 50;
149   -}
150   -.tp-get-gode.btn-disable{
151   - background-color: #e6e6e6;
152   - color: #999;
153   -}
154   -
155   -.correlation-submit {
156   - width: 660rpx;
157   - height: 96rpx;
158   - line-height: 96rpx;
159   - background: #db261e;
160   - border: none;
161   - border-radius: 6px;
162   - color: #ffffff;
163   - font-size: 20px;
164   - margin-top: 40rpx;
165   -}
166   -
167   -.bingding-agreement {
168   - width: 660rpx;
169   - margin: 0 auto;
170   - margin-top: 20rpx;
171   - font-size: 14px;
172   - margin-bottom: 30px;
173   -}
174   -
175   -.bingding-agreement label {
176   - vertical-align: middle;
177   - color: #333;
178   - margin-left: 10rpx;
179   -}
180   -
181   -.bingding-agreement navigator {
182   - vertical-align: middle;
183   - color: #0094ca;
184   - display: inline-block;
185   -}
186   -
187   -checkbox .wx-checkbox-input {
188   - border-radius: 50%;
189   - width: 36rpx;
190   - height: 36rpx;
191   -}
192   -
193   -checkbox .wx-checkbox-input.wx-checkbox-input-checked {
194   - border: none;
195   - background: red;
196   - width: 40rpx;
197   - height: 40rpx;
198   -}
199   -
200   -checkbox .wx-checkbox-input.wx-checkbox-input-checked::before {
201   - border-radius: 50%;
202   - width: 36rpx;
203   - height: 36rpx;
204   - line-height: 36rpx;
205   - text-align: center;
206   - font-size: 30rpx;
207   - color: #fff;
208   - background: transparent;
209   - transform: translate(-50%,-50%) scale(1);
210   -}
211 0 \ No newline at end of file
pages/user/order_detail/order_detail.js
... ... @@ -19,10 +19,11 @@ Page({
19 19  
20 20 getApp().getConfig2(function (e) {
21 21  
22   - th.setData({conf: e,sales_rules:e.sales_rules });
  22 + th.setData({conf: e,sales_rules:e.sales_rules, userInfo: getApp().globalData.userInfo});
23 23 //--- 看后台是不是有开通等级卡 ---
24 24 if(e.switch_list){
25 25 var s_list=JSON.parse(e.switch_list);
  26 + th.setData({sys_switch: s_list});
26 27 var is_open_offline=s_list.is_pricing_open;
27 28 var user=getApp().globalData.userInfo;
28 29 //如果后台有开启等级价的功能
... ...
pages/user/order_detail/order_detail.wxml
... ... @@ -52,7 +52,19 @@
52 52 </view>
53 53 <view class="order-operate">
54 54 <view bindtap="checkTeam" class="contact-us check-btn" wx:if="{{optionIsGoup}}">查看拼团详情</view>
55   - <view bindtap="contactService" class="contact-us goods-btn">联系客服</view>
  55 + <view>
  56 + <!-- <button wx:if="{{sys_switch.weapp_customertype}}" class="custom-service cart-ico new_split" open-type="contact" session-from="wechat|{{userInfo.user_id}}|{{userInfo.nickname}}|{{userInfo.head_pic}}"> -->
  57 + <!-- <image class="cs-img" src="{{iurl}}/miniapp/images/custom-service.png"></image>
  58 + <view></view> -->
  59 + <!-- </button> -->
  60 + <button wx:if="{{sys_switch.weapp_customertype}}" class="contact-us goods-btn" open-type="contact" session-from="wechat|{{userInfo.user_id}}|{{userInfo.nickname}}|{{userInfo.head_pic}}">联系客服</button>
  61 + <!-- <view wx:else class="custom-service cart-ico new_split" bindtap="contactService">
  62 + <image class="cs-img" src="{{iurl}}/miniapp/images/custom-service.png"></image>
  63 + <view>联系客服</view>
  64 + </view> -->
  65 + <view wx:else bindtap="contactService" class="contact-us goods-btn">联系客服</view>
  66 + </view>
  67 + <!-- <view bindtap="contactService" class="contact-us goods-btn">联系客服</view> -->
56 68 <view bindtap="cancelOrder" class="cancel-order goods-btn" data-id="{{order.order_id}}"
57 69 hidden="{{!(order.order_status==0&&order.pay_status==0)}}">取消订单</view>
58 70 </view>
... ...
pages/user/order_detail/order_detail.wxss
... ... @@ -170,4 +170,9 @@
170 170 background-color: #f23030;
171 171 /* margin-left: 2rpx; */
172 172 margin-right: 8rpx
  173 +}
  174 +
  175 +
  176 +.contact-us.goods-btn::after {
  177 + content: none;
173 178 }
174 179 \ No newline at end of file
... ...
project.config.json 0 → 100644
  1 +{
  2 + "description": "项目配置文件",
  3 + "packOptions": {
  4 + "ignore": []
  5 + },
  6 + "setting": {
  7 + "urlCheck": false,
  8 + "es6": true,
  9 + "enhance": true,
  10 + "postcss": true,
  11 + "preloadBackgroundData": false,
  12 + "minified": true,
  13 + "newFeature": true,
  14 + "coverView": true,
  15 + "nodeModules": true,
  16 + "autoAudits": false,
  17 + "showShadowRootInWxmlPanel": true,
  18 + "scopeDataCheck": false,
  19 + "uglifyFileName": false,
  20 + "checkInvalidKey": true,
  21 + "checkSiteMap": true,
  22 + "uploadWithSourceMap": true,
  23 + "compileHotReLoad": false,
  24 + "useMultiFrameRuntime": true,
  25 + "useApiHook": true,
  26 + "useApiHostProcess": true,
  27 + "babelSetting": {
  28 + "ignore": [],
  29 + "disablePlugins": [],
  30 + "outputPath": ""
  31 + },
  32 + "enableEngineNative": false,
  33 + "useIsolateContext": true,
  34 + "userConfirmedBundleSwitch": false,
  35 + "packNpmManually": false,
  36 + "packNpmRelationList": [],
  37 + "minifyWXSS": true,
  38 + "showES6CompileOption": false,
  39 + "useSummerCompiler": false
  40 + },
  41 + "compileType": "miniprogram",
  42 + "libVersion": "2.16.0",
  43 + "appid": "wx7406a86b64b58a1d",
  44 + "projectname": "MShopWeApp",
  45 + "debugOptions": {
  46 + "hidedInDevtools": []
  47 + },
  48 + "isGameTourist": false,
  49 + "simulatorType": "wechat",
  50 + "simulatorPluginLibVersion": {},
  51 + "condition": {
  52 + "search": {
  53 + "list": []
  54 + },
  55 + "conversation": {
  56 + "list": []
  57 + },
  58 + "plugin": {
  59 + "list": []
  60 + },
  61 + "game": {
  62 + "currentL": -1,
  63 + "list": []
  64 + },
  65 + "gamePlugin": {
  66 + "list": []
  67 + },
  68 + "miniprogram": {
  69 + "list": [
  70 + {
  71 + "id": 0,
  72 + "name": "启动直播列表页",
  73 + "pathName": "pages/justTest/justTest",
  74 + "query": "",
  75 + "scene": null
  76 + },
  77 + {
  78 + "id": 1,
  79 + "name": "liveStreamDetails",
  80 + "pathName": "packageA/pages/liveStreamDetails/liveStreamDetails",
  81 + "query": "",
  82 + "scene": null
  83 + },
  84 + {
  85 + "id": 2,
  86 + "name": "justTest",
  87 + "pathName": "pages/justTest/justTest",
  88 + "query": "",
  89 + "scene": null
  90 + },
  91 + {
  92 + "id": 3,
  93 + "name": "pages/goods/goodsInfo/goodsInfo",
  94 + "pathName": "pages/goods/goodsInfo/goodsInfo",
  95 + "query": "",
  96 + "scene": null
  97 + },
  98 + {
  99 + "id": -1,
  100 + "name": "pages/team/team_show/team_show",
  101 + "pathName": "pages/team/team_show/team_show",
  102 + "query": "",
  103 + "scene": null
  104 + },
  105 + {
  106 + "id": -1,
  107 + "name": "pages/index/index/index",
  108 + "pathName": "pages/index/index/index",
  109 + "query": "",
  110 + "scene": null
  111 + },
  112 + {
  113 + "id": -1,
  114 + "name": "pages/store/index",
  115 + "pathName": "pages/store/index",
  116 + "query": "",
  117 + "scene": null
  118 + },
  119 + {
  120 + "id": 7,
  121 + "name": "packageA/pages/goods_share/goods_share",
  122 + "pathName": "packageA/pages/goods_share/goods_share",
  123 + "query": "",
  124 + "scene": null
  125 + },
  126 + {
  127 + "id": 8,
  128 + "name": "packageA/pages/live_share/live_share",
  129 + "pathName": "packageA/pages/live_share/live_share",
  130 + "query": "",
  131 + "scene": null
  132 + },
  133 + {
  134 + "id": -1,
  135 + "name": "pages/cart/cart2_pt/cart2_pt",
  136 + "pathName": "pages/cart/cart2_pt/cart2_pt",
  137 + "query": "",
  138 + "scene": null
  139 + },
  140 + {
  141 + "id": -1,
  142 + "name": "pages/cart/cart2_pt/cart2_pt",
  143 + "pathName": "pages/cart/cart2_pt/cart2_pt",
  144 + "query": "",
  145 + "scene": null
  146 + },
  147 + {
  148 + "id": -1,
  149 + "name": "pages/cart/cart_wk/cart_wk",
  150 + "pathName": "pages/index/index/index",
  151 + "query": "",
  152 + "scene": null
  153 + },
  154 + {
  155 + "id": -1,
  156 + "name": "pages/cart_wk/cart_wk/cart_wk",
  157 + "pathName": "pages/cart_wk/cart_wk/cart_wk",
  158 + "query": "",
  159 + "scene": null
  160 + },
  161 + {
  162 + "id": -1,
  163 + "name": "pages/cart/cart_wk/cart_wk",
  164 + "pathName": "pages/cart/cart_wk/cart_wk",
  165 + "query": "",
  166 + "scene": null
  167 + },
  168 + {
  169 + "id": -1,
  170 + "name": "pages/user/assistance/assistance",
  171 + "pathName": "pages/user/assistance/assistance",
  172 + "query": "",
  173 + "scene": null
  174 + },
  175 + {
  176 + "id": -1,
  177 + "name": "pages/goods/search/search",
  178 + "pathName": "pages/goods/search/search",
  179 + "query": "",
  180 + "scene": null
  181 + },
  182 + {
  183 + "id": -1,
  184 + "name": "pages/goods/search/search",
  185 + "pathName": "pages/goods/search/search",
  186 + "query": "",
  187 + "scene": null
  188 + },
  189 + {
  190 + "id": -1,
  191 + "name": "pages/user/userinfo/userinfo",
  192 + "pathName": "pages/user/userinfo/userinfo",
  193 + "query": "",
  194 + "scene": null
  195 + },
  196 + {
  197 + "id": -1,
  198 + "name": "pages/user/goods_share/goods_share",
  199 + "pathName": "pages/user/goods_share/goods_share",
  200 + "query": "",
  201 + "scene": null
  202 + },
  203 + {
  204 + "id": -1,
  205 + "name": "packageA//pages/user/goods_share/goods_share",
  206 + "pathName": "packageA//pages/user/goods_share/goods_share",
  207 + "query": "",
  208 + "scene": null
  209 + },
  210 + {
  211 + "id": -1,
  212 + "name": "packageA/pages/user/goods_share/goods_share",
  213 + "pathName": "packageA/pages/user/goods_share/goods_share",
  214 + "query": "",
  215 + "scene": null
  216 + },
  217 + {
  218 + "id": 21,
  219 + "name": "packageA/pages/goods_share/goods_share",
  220 + "pathName": "packageA/pages/addCustomer/addCustomer",
  221 + "query": "",
  222 + "scene": null
  223 + },
  224 + {
  225 + "id": -1,
  226 + "name": "packageA/pages/goods_share/goods_share",
  227 + "pathName": "packageA/pages/goods_share/goods_share",
  228 + "query": "",
  229 + "scene": null
  230 + },
  231 + {
  232 + "id": -1,
  233 + "name": "packageA/pages/goods_share/goods_share",
  234 + "pathName": "packageA/pages/goods_share/goods_share",
  235 + "query": "",
  236 + "scene": null
  237 + },
  238 + {
  239 + "id": -1,
  240 + "name": "packageA/pages/activity_share/activity_share",
  241 + "pathName": "packageA/pages/activity_share/activity_share",
  242 + "query": "",
  243 + "scene": null
  244 + },
  245 + {
  246 + "id": -1,
  247 + "name": "packageA/pages/quan_list/quan_list",
  248 + "pathName": "packageA/pages/quan_list/quan_list",
  249 + "query": "",
  250 + "scene": null
  251 + },
  252 + {
  253 + "id": -1,
  254 + "name": "packageA/pages/quan_pro/quan_pro",
  255 + "pathName": "packageA/pages/quan_pro/quan_pro",
  256 + "query": "",
  257 + "scene": null
  258 + },
  259 + {
  260 + "id": -1,
  261 + "name": "packageA/pages/quan_list/quan_list",
  262 + "pathName": "packageA/pages/quan_list/quan_list",
  263 + "query": "",
  264 + "scene": null
  265 + },
  266 + {
  267 + "id": -1,
  268 + "name": "packageA/pages/quan/quan",
  269 + "pathName": "packageA/pages/quan/quan",
  270 + "query": "",
  271 + "scene": null
  272 + },
  273 + {
  274 + "id": -1,
  275 + "name": "packageA/pages/addCustomer/addCustomer",
  276 + "pathName": "packageA/pages/addCustomer/addCustomer",
  277 + "query": "",
  278 + "scene": null
  279 + },
  280 + {
  281 + "id": -1,
  282 + "name": "packageA/pages/quan/quan",
  283 + "pathName": "packageA/pages/quan/quan",
  284 + "query": "",
  285 + "scene": null
  286 + },
  287 + {
  288 + "id": -1,
  289 + "name": "pages/user/assistance/assistance",
  290 + "pathName": "pages/user/assistance/assistance",
  291 + "query": "",
  292 + "scene": null
  293 + },
  294 + {
  295 + "id": -1,
  296 + "name": "packageA/pages/live_share/live_share",
  297 + "pathName": "packageA/pages/live_share/live_share",
  298 + "query": "",
  299 + "scene": null
  300 + },
  301 + {
  302 + "id": -1,
  303 + "name": "packageA/pages/quan/quan",
  304 + "pathName": "packageA/pages/quan/quan",
  305 + "query": "",
  306 + "scene": null
  307 + },
  308 + {
  309 + "id": -1,
  310 + "name": "pages/user/assistance/assistance",
  311 + "pathName": "pages/user/assistance/assistance",
  312 + "query": "",
  313 + "scene": null
  314 + },
  315 + {
  316 + "id": -1,
  317 + "name": "packageA/pages/live_share/live_share",
  318 + "pathName": "packageA/pages/live_share/live_share",
  319 + "query": "",
  320 + "scene": null
  321 + },
  322 + {
  323 + "id": -1,
  324 + "name": "packageA/pages/jfbuy/jfbuy",
  325 + "pathName": "packageA/pages/jfbuy/jfbuy",
  326 + "query": "",
  327 + "scene": null
  328 + },
  329 + {
  330 + "id": -1,
  331 + "name": "packageA/pages/goods_share/goods_share",
  332 + "pathName": "packageA/pages/goods_share/goods_share",
  333 + "query": "",
  334 + "scene": null
  335 + },
  336 + {
  337 + "id": -1,
  338 + "name": "packageA/pages/live_share/live_share",
  339 + "pathName": "packageA/pages/live_share/live_share",
  340 + "query": "",
  341 + "scene": null
  342 + },
  343 + {
  344 + "id": -1,
  345 + "name": "packageA/pages/activity_share/activity_share",
  346 + "pathName": "packageA/pages/activity_share/activity_share",
  347 + "query": "",
  348 + "scene": null
  349 + },
  350 + {
  351 + "id": -1,
  352 + "name": "packageA/pages/jfbuy/jfbuy",
  353 + "pathName": "packageA/pages/jfbuy/jfbuy",
  354 + "query": "",
  355 + "scene": null
  356 + },
  357 + {
  358 + "id": -1,
  359 + "name": "packageA/pages/jfbuy/jfbuy",
  360 + "pathName": "packageA/pages/jfbuy/jfbuy",
  361 + "query": "",
  362 + "scene": null
  363 + },
  364 + {
  365 + "id": -1,
  366 + "name": "pages/user/order_list/order_list",
  367 + "pathName": "pages/user/order_list/order_list",
  368 + "query": "",
  369 + "scene": null
  370 + },
  371 + {
  372 + "id": -1,
  373 + "name": "pages/shop_details/shop_details",
  374 + "pathName": "pages/shop_details/shop_details",
  375 + "query": "",
  376 + "scene": null
  377 + },
  378 + {
  379 + "id": -1,
  380 + "name": "pages/index/index/index",
  381 + "pathName": "pages/index/index/index",
  382 + "query": "",
  383 + "scene": null
  384 + },
  385 + {
  386 + "id": -1,
  387 + "name": "packageA/pages/quan/quan",
  388 + "pathName": "packageA/pages/quan/quan",
  389 + "query": "",
  390 + "scene": null
  391 + },
  392 + {
  393 + "id": -1,
  394 + "name": "packageA/pages/quan/quan",
  395 + "pathName": "packageA/pages/quan/quan",
  396 + "query": "",
  397 + "scene": null
  398 + },
  399 + {
  400 + "id": -1,
  401 + "name": "pages/user/order_list/order_list",
  402 + "pathName": "pages/user/order_list/order_list",
  403 + "query": "",
  404 + "scene": null
  405 + },
  406 + {
  407 + "id": -1,
  408 + "name": "packageA/pages/chongzhi/chongzhi",
  409 + "pathName": "packageA/pages/chongzhi/chongzhi",
  410 + "query": "",
  411 + "scene": null
  412 + },
  413 + {
  414 + "id": -1,
  415 + "name": "packageA/pages/chongzhiDetails/chongzhiDetails",
  416 + "pathName": "packageA/pages/chongzhiDetails/chongzhiDetails",
  417 + "query": "",
  418 + "scene": null
  419 + },
  420 + {
  421 + "id": -1,
  422 + "name": "packageA/pages/chongzhi/chongzhi",
  423 + "pathName": "packageA/pages/chongzhi/chongzhi",
  424 + "query": "",
  425 + "scene": null
  426 + },
  427 + {
  428 + "id": -1,
  429 + "name": "packageA/pages/chongzhiDetails/chongzhiDetails",
  430 + "pathName": "packageA/pages/chongzhiDetails/chongzhiDetails",
  431 + "query": "",
  432 + "scene": null
  433 + },
  434 + {
  435 + "id": -1,
  436 + "name": "pages/user/deposit/prepaid/prepaid",
  437 + "pathName": "pages/user/deposit/prepaid/prepaid",
  438 + "query": "",
  439 + "scene": null
  440 + },
  441 + {
  442 + "id": -1,
  443 + "name": "packageA/pages/chongzhi/chongzhi",
  444 + "pathName": "packageA/pages/chongzhi/chongzhi",
  445 + "query": "",
  446 + "scene": null
  447 + },
  448 + {
  449 + "id": -1,
  450 + "name": "packageA/pages/chongzhi/chongzhi",
  451 + "pathName": "packageA/pages/chongzhi/chongzhi",
  452 + "query": "",
  453 + "scene": null
  454 + },
  455 + {
  456 + "id": -1,
  457 + "name": "packageA/pages/chongzhi/chongzhi",
  458 + "pathName": "packageA/pages/chongzhi/chongzhi",
  459 + "query": "",
  460 + "scene": null
  461 + },
  462 + {
  463 + "id": -1,
  464 + "name": "packageA/pages/chongzhiDetails/chongzhiDetails",
  465 + "pathName": "packageA/pages/chongzhiDetails/chongzhiDetails",
  466 + "query": "",
  467 + "scene": null
  468 + },
  469 + {
  470 + "id": -1,
  471 + "name": "packageA/pages/chongzhi/chongzhi",
  472 + "pathName": "packageA/pages/chongzhi/chongzhi",
  473 + "query": "",
  474 + "scene": null
  475 + },
  476 + {
  477 + "id": -1,
  478 + "name": "packageA/pages/chongzhiDetails/chongzhiDetails",
  479 + "pathName": "packageA/pages/chongzhiDetails/chongzhiDetails",
  480 + "query": "",
  481 + "scene": null
  482 + },
  483 + {
  484 + "id": -1,
  485 + "name": "packageA/pages/chongzhi/chongzhi",
  486 + "pathName": "packageA/pages/chongzhi/chongzhi",
  487 + "query": "",
  488 + "scene": null
  489 + },
  490 + {
  491 + "id": -1,
  492 + "name": "packageA/pages/checkin/checkin",
  493 + "pathName": "packageA/pages/checkin/checkin",
  494 + "query": "",
  495 + "scene": null
  496 + },
  497 + {
  498 + "id": -1,
  499 + "name": "packageA/pages/jfbuy/jfbuy",
  500 + "pathName": "packageA/pages/jfbuy/jfbuy",
  501 + "query": "",
  502 + "scene": null
  503 + },
  504 + {
  505 + "id": -1,
  506 + "name": "packageA/pages/checkin/checkin",
  507 + "pathName": "packageA/pages/checkin/checkin",
  508 + "query": "",
  509 + "scene": null
  510 + },
  511 + {
  512 + "id": -1,
  513 + "name": "pages/user/integral/integral",
  514 + "pathName": "pages/user/integral/integral",
  515 + "query": "",
  516 + "scene": null
  517 + },
  518 + {
  519 + "id": -1,
  520 + "name": "packageA/pages/checkin/checkin",
  521 + "pathName": "packageA/pages/checkin/checkin",
  522 + "query": "",
  523 + "scene": null
  524 + },
  525 + {
  526 + "id": -1,
  527 + "name": "packageA/pages/checkin/checkin",
  528 + "pathName": "packageA/pages/checkin/checkin",
  529 + "query": "",
  530 + "scene": null
  531 + },
  532 + {
  533 + "id": -1,
  534 + "name": "packageA/pages/jfbuy/jfbuy",
  535 + "pathName": "packageA/pages/jfbuy/jfbuy",
  536 + "query": "",
  537 + "scene": null
  538 + },
  539 + {
  540 + "id": -1,
  541 + "name": "packageA/pages/checkin/checkin",
  542 + "pathName": "packageA/pages/checkin/checkin",
  543 + "query": "",
  544 + "scene": null
  545 + },
  546 + {
  547 + "id": -1,
  548 + "name": "packageA/pages/quan_list/quan_list",
  549 + "pathName": "packageA/pages/quan_list/quan_list",
  550 + "query": "",
  551 + "scene": null
  552 + },
  553 + {
  554 + "id": -1,
  555 + "name": "packageA/pages/quan/quan",
  556 + "pathName": "packageA/pages/quan/quan",
  557 + "query": "",
  558 + "scene": null
  559 + },
  560 + {
  561 + "id": -1,
  562 + "name": "packageA/pages/quan_list/quan_list",
  563 + "pathName": "packageA/pages/quan_list/quan_list",
  564 + "query": "",
  565 + "scene": null
  566 + },
  567 + {
  568 + "id": -1,
  569 + "name": "packageA/pages/quan/quan",
  570 + "pathName": "packageA/pages/quan/quan",
  571 + "query": "",
  572 + "scene": null
  573 + },
  574 + {
  575 + "id": -1,
  576 + "name": "packageA/pages/quan/quan",
  577 + "pathName": "packageA/pages/quan/quan",
  578 + "query": "",
  579 + "scene": null
  580 + },
  581 + {
  582 + "id": -1,
  583 + "name": "packageA/pages/checkin/checkin",
  584 + "pathName": "packageA/pages/checkin/checkin",
  585 + "query": "",
  586 + "scene": null
  587 + },
  588 + {
  589 + "id": -1,
  590 + "name": "packageA/pages/chongzhi/chongzhi",
  591 + "pathName": "packageA/pages/chongzhi/chongzhi",
  592 + "query": "",
  593 + "scene": null
  594 + },
  595 + {
  596 + "id": -1,
  597 + "name": "pages/user/assistance/assistance",
  598 + "pathName": "pages/user/assistance/assistance",
  599 + "query": "",
  600 + "scene": null
  601 + },
  602 + {
  603 + "id": -1,
  604 + "name": "pages/giftpack/mygiftpack/mygiftpack",
  605 + "pathName": "pages/giftpack/mygiftpack/mygiftpack",
  606 + "query": "",
  607 + "scene": null
  608 + },
  609 + {
  610 + "id": -1,
  611 + "name": "packageA/pages/quan_list/quan_list",
  612 + "pathName": "packageA/pages/quan_list/quan_list",
  613 + "query": "",
  614 + "scene": null
  615 + },
  616 + {
  617 + "id": -1,
  618 + "name": "packageA/pages/service_record/service_record",
  619 + "pathName": "packageA/pages/service_record/service_record",
  620 + "query": "",
  621 + "scene": null
  622 + },
  623 + {
  624 + "id": -1,
  625 + "name": "packageA/pages/hongBao/hongBao",
  626 + "pathName": "packageA/pages/hongBao/hongBao",
  627 + "query": "",
  628 + "scene": null
  629 + },
  630 + {
  631 + "id": -1,
  632 + "name": "packageA/pages/hongBaoDetails/hongBaoDetails",
  633 + "pathName": "packageA/pages/hongBao/hongBao",
  634 + "query": "",
  635 + "scene": null
  636 + },
  637 + {
  638 + "id": -1,
  639 + "name": "packageA/pages/hongBaoDetails/hongBaoDetails",
  640 + "pathName": "packageA/pages/hongBaoDetails/hongBaoDetails",
  641 + "query": "",
  642 + "scene": null
  643 + },
  644 + {
  645 + "id": -1,
  646 + "name": "packageA/pages/hongBaoDetails/hongBaoDetails",
  647 + "pathName": "packageA/pages/hongBaoDetails/hongBaoDetails",
  648 + "query": "",
  649 + "scene": null
  650 + },
  651 + {
  652 + "id": -1,
  653 + "name": "packageA/pages/hongBao/hongBao",
  654 + "pathName": "packageA/pages/hongBao/hongBao",
  655 + "query": "",
  656 + "scene": null
  657 + },
  658 + {
  659 + "id": -1,
  660 + "name": "packageA/pages/hongBaoDetails/hongBaoDetails",
  661 + "pathName": "packageA/pages/hongBaoDetails/hongBaoDetails",
  662 + "query": "",
  663 + "scene": null
  664 + },
  665 + {
  666 + "id": -1,
  667 + "name": "packageA/pages/hongBao/hongBao",
  668 + "pathName": "packageA/pages/hongBao/hongBao",
  669 + "query": "",
  670 + "scene": null
  671 + },
  672 + {
  673 + "id": -1,
  674 + "name": "packageA/pages/service_record/service_record",
  675 + "pathName": "packageA/pages/service_record/service_record",
  676 + "query": "",
  677 + "scene": null
  678 + },
  679 + {
  680 + "id": -1,
  681 + "name": "packageA/pages/distribution/main/main",
  682 + "pathName": "packageA/pages/distribution/main/main",
  683 + "query": "",
  684 + "scene": null
  685 + },
  686 + {
  687 + "id": -1,
  688 + "name": "packageA/pages/distribution/myteam/myteam",
  689 + "pathName": "packageA/pages/distribution/myteam/myteam",
  690 + "query": "",
  691 + "scene": null
  692 + },
  693 + {
  694 + "id": -1,
  695 + "name": "packageA/pages/distribution/myteam/myteam",
  696 + "pathName": "packageA/pages/distribution/myteam/myteam",
  697 + "query": "",
  698 + "scene": null
  699 + },
  700 + {
  701 + "id": -1,
  702 + "name": "packageA/pages/myteam/myteam",
  703 + "pathName": "packageA/pages/myteam/myteam",
  704 + "query": "",
  705 + "scene": null
  706 + },
  707 + {
  708 + "id": -1,
  709 + "name": "pages/giftpack/newvipgift/newvipgift",
  710 + "pathName": "pages/giftpack/newvipgift/newvipgift",
  711 + "query": "",
  712 + "scene": null
  713 + },
  714 + {
  715 + "id": -1,
  716 + "name": "packageA/pages/distribution/myteam/myteam",
  717 + "pathName": "packageA/pages/distribution/myteam/myteam",
  718 + "query": "",
  719 + "scene": null
  720 + },
  721 + {
  722 + "id": -1,
  723 + "name": "packageA/pages/distribution/order/order",
  724 + "pathName": "packageA/pages/distribution/order/order",
  725 + "query": "",
  726 + "scene": null
  727 + },
  728 + {
  729 + "id": -1,
  730 + "name": "packageA/pages/distribution/myteam/myteam",
  731 + "pathName": "packageA/pages/distribution/myteam/myteam",
  732 + "query": "",
  733 + "scene": null
  734 + },
  735 + {
  736 + "id": -1,
  737 + "name": "packageA/pages/distribution/order/order",
  738 + "pathName": "packageA/pages/distribution/order/order",
  739 + "query": "",
  740 + "scene": null
  741 + },
  742 + {
  743 + "id": -1,
  744 + "name": "packageA/pages/distribution/commision/commision",
  745 + "pathName": "packageA/pages/distribution/commision/commision",
  746 + "query": "",
  747 + "scene": null
  748 + },
  749 + {
  750 + "id": -1,
  751 + "name": "packageA/pages/distribution/commision/commision",
  752 + "pathName": "packageA/pages/distribution/commision/commision",
  753 + "query": "",
  754 + "scene": null
  755 + },
  756 + {
  757 + "id": -1,
  758 + "name": "packageA/pages/distribution/commision/commision",
  759 + "pathName": "packageA/pages/distribution/commision/commision",
  760 + "query": "",
  761 + "scene": null
  762 + },
  763 + {
  764 + "id": -1,
  765 + "name": "packageA/pages/distribution/rank/rank",
  766 + "pathName": "packageA/pages/distribution/rank/rank",
  767 + "query": "",
  768 + "scene": null
  769 + },
  770 + {
  771 + "id": -1,
  772 + "name": "packageA/pages/distribution/commision/commision",
  773 + "pathName": "packageA/pages/distribution/commision/commision",
  774 + "query": "",
  775 + "scene": null
  776 + },
  777 + {
  778 + "id": -1,
  779 + "name": "packageA/pages/distribution/order/order",
  780 + "pathName": "packageA/pages/distribution/order/order",
  781 + "query": "",
  782 + "scene": null
  783 + },
  784 + {
  785 + "id": -1,
  786 + "name": "packageA/pages/distribution/myteam/myteam",
  787 + "pathName": "packageA/pages/distribution/myteam/myteam",
  788 + "query": "",
  789 + "scene": null
  790 + },
  791 + {
  792 + "id": -1,
  793 + "name": "packageA/pages/distribution/main/main",
  794 + "pathName": "packageA/pages/distribution/main/main",
  795 + "query": "",
  796 + "scene": null
  797 + },
  798 + {
  799 + "id": -1,
  800 + "name": "packageA/pages/distribution/card/card",
  801 + "pathName": "packageA/pages/distribution/card/card",
  802 + "query": "",
  803 + "scene": null
  804 + },
  805 + {
  806 + "id": -1,
  807 + "name": "packageA/pages/distribution/rank/rank",
  808 + "pathName": "packageA/pages/distribution/rank/rank",
  809 + "query": "",
  810 + "scene": null
  811 + },
  812 + {
  813 + "id": -1,
  814 + "name": "packageA/pages/distribution/goods/goods",
  815 + "pathName": "packageA/pages/distribution/goods/goods",
  816 + "query": "",
  817 + "scene": null
  818 + },
  819 + {
  820 + "id": -1,
  821 + "name": "packageA/pages/distribution/main/main",
  822 + "pathName": "packageA/pages/distribution/main/main",
  823 + "query": "",
  824 + "scene": null
  825 + },
  826 + {
  827 + "id": -1,
  828 + "name": "packageA/pages/distribution/shop/shop",
  829 + "pathName": "packageA/pages/distribution/shop/shop",
  830 + "query": "",
  831 + "scene": null
  832 + },
  833 + {
  834 + "id": -1,
  835 + "name": "packageA/pages/distribution/rookie/rookie",
  836 + "pathName": "packageA/pages/distribution/rookie/rookie",
  837 + "query": "",
  838 + "scene": null
  839 + },
  840 + {
  841 + "id": -1,
  842 + "name": "packageA/pages/distribution/main/main",
  843 + "pathName": "packageA/pages/distribution/main/main",
  844 + "query": "",
  845 + "scene": null
  846 + },
  847 + {
  848 + "id": -1,
  849 + "name": "pages/index/index/index",
  850 + "pathName": "pages/index/index/index",
  851 + "query": "",
  852 + "scene": null
  853 + },
  854 + {
  855 + "id": -1,
  856 + "name": "packageA/pages/distribution/main/main",
  857 + "pathName": "packageA/pages/distribution/main/main",
  858 + "query": "",
  859 + "scene": null
  860 + },
  861 + {
  862 + "id": -1,
  863 + "name": "packageA/pages/distribution/order/order",
  864 + "pathName": "packageA/pages/distribution/order/order",
  865 + "query": "",
  866 + "scene": null
  867 + },
  868 + {
  869 + "id": -1,
  870 + "name": "packageA/pages/distribution/order/order",
  871 + "pathName": "packageA/pages/distribution/order/order",
  872 + "query": "",
  873 + "scene": null
  874 + },
  875 + {
  876 + "id": -1,
  877 + "name": "packageA/pages/distribution/rank/rank",
  878 + "pathName": "packageA/pages/distribution/rank/rank",
  879 + "query": "",
  880 + "scene": null
  881 + },
  882 + {
  883 + "id": -1,
  884 + "name": "packageA/pages/distribution/myteam/myteam",
  885 + "pathName": "packageA/pages/distribution/myteam/myteam",
  886 + "query": "",
  887 + "scene": null
  888 + },
  889 + {
  890 + "id": -1,
  891 + "name": "packageA/pages/distribution/myteam/myteam",
  892 + "pathName": "packageA/pages/distribution/myteam/myteam",
  893 + "query": "",
  894 + "scene": null
  895 + },
  896 + {
  897 + "id": -1,
  898 + "name": "packageA/pages/distribution/main/main",
  899 + "pathName": "packageA/pages/distribution/main/main",
  900 + "query": "",
  901 + "scene": null
  902 + },
  903 + {
  904 + "id": -1,
  905 + "name": "packageA/pages/distribution/commision/commision",
  906 + "pathName": "packageA/pages/distribution/commision/commision",
  907 + "query": "",
  908 + "scene": null
  909 + },
  910 + {
  911 + "id": -1,
  912 + "name": "packageA/pages/distribution/shop/shop",
  913 + "pathName": "packageA/pages/distribution/shop/shop",
  914 + "query": "",
  915 + "scene": null
  916 + },
  917 + {
  918 + "id": -1,
  919 + "name": "packageA/pages/distribution/shop/shop",
  920 + "pathName": "packageA/pages/distribution/shop/shop",
  921 + "query": "",
  922 + "scene": null
  923 + },
  924 + {
  925 + "id": -1,
  926 + "name": "packageA/pages/distribution/shop/shop",
  927 + "pathName": "packageA/pages/distribution/shop/shop",
  928 + "query": "",
  929 + "scene": null
  930 + },
  931 + {
  932 + "id": -1,
  933 + "name": "packageA/pages/distribution/card/card",
  934 + "pathName": "packageA/pages/distribution/card/card",
  935 + "query": "",
  936 + "scene": null
  937 + },
  938 + {
  939 + "id": -1,
  940 + "name": "packageA/pages/distribution/main/main",
  941 + "pathName": "packageA/pages/distribution/main/main",
  942 + "query": "",
  943 + "scene": null
  944 + },
  945 + {
  946 + "id": -1,
  947 + "name": "packageA/pages/distribution/card/card",
  948 + "pathName": "packageA/pages/distribution/card/card",
  949 + "query": "",
  950 + "scene": null
  951 + },
  952 + {
  953 + "id": -1,
  954 + "name": "packageA/pages/distribution/main/main",
  955 + "pathName": "packageA/pages/distribution/main/main",
  956 + "query": "",
  957 + "scene": null
  958 + },
  959 + {
  960 + "id": -1,
  961 + "name": "pages/index/index/index",
  962 + "pathName": "pages/index/index/index",
  963 + "query": "",
  964 + "scene": null
  965 + },
  966 + {
  967 + "id": -1,
  968 + "name": "packageA/pages/distribution/main/main",
  969 + "pathName": "packageA/pages/distribution/main/main",
  970 + "query": "",
  971 + "scene": null
  972 + },
  973 + {
  974 + "id": -1,
  975 + "name": "pages/index/index/index",
  976 + "pathName": "pages/index/index/index",
  977 + "query": "",
  978 + "scene": null
  979 + },
  980 + {
  981 + "id": -1,
  982 + "name": "packageA/pages/distribution/main/main",
  983 + "pathName": "packageA/pages/distribution/main/main",
  984 + "query": "",
  985 + "scene": null
  986 + },
  987 + {
  988 + "id": -1,
  989 + "name": "packageA/pages/activity_share/activity_share",
  990 + "pathName": "packageA/pages/activity_share/activity_share",
  991 + "query": "",
  992 + "scene": null
  993 + },
  994 + {
  995 + "id": -1,
  996 + "name": "packageA/pages/goods_share/goods_share",
  997 + "pathName": "packageA/pages/goods_share/goods_share",
  998 + "query": "",
  999 + "scene": null
  1000 + },
  1001 + {
  1002 + "id": -1,
  1003 + "name": "packageA/pages/service_share/service_share",
  1004 + "pathName": "packageA/pages/service_share/service_share",
  1005 + "query": "",
  1006 + "scene": null
  1007 + },
  1008 + {
  1009 + "id": -1,
  1010 + "name": "packageA/pages/distribution/main/main",
  1011 + "pathName": "packageA/pages/distribution/main/main",
  1012 + "query": "",
  1013 + "scene": null
  1014 + },
  1015 + {
  1016 + "id": -1,
  1017 + "name": "packageA/pages/cardDetails/cardDetails",
  1018 + "pathName": "packageA/pages/cardDetails/cardDetails",
  1019 + "query": "",
  1020 + "scene": null
  1021 + },
  1022 + {
  1023 + "id": -1,
  1024 + "name": "pages/user/my_service/i_service",
  1025 + "pathName": "pages/user/appment_main/appment_main",
  1026 + "query": "",
  1027 + "scene": null
  1028 + },
  1029 + {
  1030 + "id": -1,
  1031 + "name": "pages/user/appment_main/appment_main",
  1032 + "pathName": "pages/user/my_service/appment_main/appment_main",
  1033 + "query": "",
  1034 + "scene": null
  1035 + },
  1036 + {
  1037 + "id": -1,
  1038 + "name": "pages/user/my_service/appment_main",
  1039 + "pathName": "pages/user/my_service/appment_main",
  1040 + "query": "",
  1041 + "scene": null
  1042 + },
  1043 + {
  1044 + "id": -1,
  1045 + "name": "packageA/pages/distribution/main/main",
  1046 + "pathName": "packageA/pages/distribution/main/main",
  1047 + "query": "",
  1048 + "scene": null
  1049 + },
  1050 + {
  1051 + "id": -1,
  1052 + "name": "pages/index/index/index",
  1053 + "pathName": "pages/index/index/index",
  1054 + "query": "",
  1055 + "scene": null
  1056 + },
  1057 + {
  1058 + "id": -1,
  1059 + "name": "packageA/pages/distribution/main/main",
  1060 + "pathName": "packageA/pages/distribution/main/main",
  1061 + "scene": null
  1062 + }
  1063 + ]
  1064 + }
  1065 + }
  1066 +}
0 1067 \ No newline at end of file
... ...