版本提交
Showing
17 changed files
with
1702 additions
and
106 deletions
... | @@ -132,7 +132,7 @@ function sassCompile() { | ... | @@ -132,7 +132,7 @@ function sassCompile() { |
132 | })) | 132 | })) |
133 | .pipe(replace('.scss', '.wxss')) | 133 | .pipe(replace('.scss', '.wxss')) |
134 | // .pipe(replace('%ASSETS_IMG%/', res)) | 134 | // .pipe(replace('%ASSETS_IMG%/', res)) |
135 | .pipe(replace('../../image/oss/', res)) // 自定义图片地址 | 135 | // .pipe(replace('../../image/oss/', res)) // 自定义图片地址 |
136 | .pipe(replace('src/assets/images', res)) // 雪碧图CSS RUL 中的图片路径 | 136 | .pipe(replace('src/assets/images', res)) // 雪碧图CSS RUL 中的图片路径 |
137 | .pipe(gulp.dest(paths.dist.baseDir)) | 137 | .pipe(gulp.dest(paths.dist.baseDir)) |
138 | } | 138 | } |
... | @@ -231,7 +231,7 @@ var watchHandler = function (type, file) { | ... | @@ -231,7 +231,7 @@ var watchHandler = function (type, file) { |
231 | var tmp = file.replace('src/', 'dist/') | 231 | var tmp = file.replace('src/', 'dist/') |
232 | del([tmp]); | 232 | del([tmp]); |
233 | } else { | 233 | } else { |
234 | copyWXML(); | 234 | // copyWXML(); |
235 | wxmlImgRewrite(); | 235 | wxmlImgRewrite(); |
236 | } | 236 | } |
237 | } | 237 | } | ... | ... |
... | @@ -22,5 +22,10 @@ | ... | @@ -22,5 +22,10 @@ |
22 | "navigationBarBackgroundColor": "#fff", | 22 | "navigationBarBackgroundColor": "#fff", |
23 | "navigationBarTitleText": "心愿单", | 23 | "navigationBarTitleText": "心愿单", |
24 | "navigationBarTextStyle": "black" | 24 | "navigationBarTextStyle": "black" |
25 | }, | ||
26 | "permission": { | ||
27 | "scope.userLocation": { | ||
28 | "desc": "你的位置信息将用显示附近门店" | ||
29 | } | ||
25 | } | 30 | } |
26 | } | 31 | } | ... | ... |
1 | import { | ||
2 | getBindtapData, | ||
3 | } from '../../utils/util'; | ||
4 | let app = getApp(); | ||
5 | |||
1 | Component({ | 6 | Component({ |
2 | properties: { | 7 | properties: { |
3 | // 这里定义了innerText属性,属性值可以在组件使用时指定 | 8 | // 这里定义了innerText属性,属性值可以在组件使用时指定 |
4 | innerText: { | 9 | innerText: { |
5 | type: String, | 10 | type: String, |
6 | value: 'default value', | 11 | value: 'default value', |
12 | }, | ||
13 | wishInfo: { | ||
14 | type: Object, | ||
15 | value: {}, | ||
16 | }, | ||
17 | location: { | ||
18 | type: Object, | ||
19 | value: {}, | ||
20 | }, | ||
21 | //是否选择模式 | ||
22 | selectedMode: { | ||
23 | type: Boolean, | ||
24 | value: false | ||
7 | } | 25 | } |
8 | }, | 26 | }, |
9 | data: { | 27 | data: { |
10 | // 这里是一些组件内部数据 | 28 | // 这里是一些组件内部数据 |
11 | someData: {} | 29 | someData: {}, |
30 | searchMode: 1, // 查询模式 1.根据位置自动查询 2.省市区查询 | ||
31 | provinceId: "", | ||
32 | cityId: "", | ||
33 | districtId: "", | ||
34 | provinceList: [], | ||
35 | cityList: [], | ||
36 | districtList: [], | ||
37 | provinceIndex: -1, | ||
38 | cityIndex: -1, | ||
39 | districtIndex: -1, | ||
40 | addressList: [], | ||
41 | total: 0, | ||
42 | curAddress: null | ||
12 | }, | 43 | }, |
13 | methods: { | 44 | methods: { |
45 | /** | ||
46 | * 请求门店地址 | ||
47 | */ | ||
48 | queryShop() { | ||
49 | return new Promise((resolve, reject) => { | ||
50 | let { | ||
51 | location, | ||
52 | wishInfo, | ||
53 | provinceId, | ||
54 | cityId, | ||
55 | districtId, | ||
56 | } = this.data; | ||
57 | app.post({ | ||
58 | url: app.api.storeQuery, | ||
59 | data: { | ||
60 | couponId: wishInfo.couponId, | ||
61 | latitude: location.latitude, | ||
62 | longitude: location.longitude, | ||
63 | provinceId: provinceId, | ||
64 | cityId: cityId, | ||
65 | districtId: districtId, | ||
66 | page: 1, | ||
67 | size: 100, | ||
68 | } | ||
69 | }).then((result) => { | ||
70 | this.setData({ | ||
71 | addressList: result.list, | ||
72 | total: result.total | ||
73 | }) | ||
74 | resolve(); | ||
75 | }) | ||
76 | }); | ||
77 | }, | ||
78 | |||
79 | /** | ||
80 | * 选择地址 item | ||
81 | */ | ||
82 | onSelectHandler(evt) { | ||
83 | let item = getBindtapData(evt); | ||
84 | let index = getBindtapData(evt, "index"); | ||
85 | let addressList = this.data.addressList; | ||
86 | addressList.forEach((element, idx) => { | ||
87 | element.selected = index == idx; | ||
88 | }); | ||
89 | |||
90 | this.setData({ | ||
91 | addressList: addressList, | ||
92 | curAddress: item | ||
93 | }) | ||
94 | }, | ||
95 | |||
96 | /** | ||
97 | * 提交门店 | ||
98 | */ | ||
99 | onSubmitHandler(evt) { | ||
100 | let curAddress = this.data.curAddress; | ||
101 | if (!curAddress) { | ||
102 | wx.showToast({ | ||
103 | title: "请选择门店", | ||
104 | icon: 'none' | ||
105 | }); | ||
106 | return; | ||
107 | } | ||
108 | let wishInfo = this.properties.wishInfo; | ||
109 | app.post({ | ||
110 | url: app.api.wishbillStoreAppoint, | ||
111 | data: { | ||
112 | instanceCode: wishInfo.instanceCode, | ||
113 | storeCode: curAddress.storeCode, | ||
114 | storeName: curAddress.storeName, | ||
115 | storeAddress: curAddress.storeAddress, | ||
116 | latitude: curAddress.latitude, | ||
117 | longitude: curAddress.longitude | ||
118 | } | ||
119 | }).then((result) => { | ||
120 | this.triggerEvent('evtcomp', { | ||
121 | name: "_evt_submit_store_complete" | ||
122 | }) | ||
123 | }); | ||
124 | }, | ||
125 | |||
126 | /** | ||
127 | * 显示位置 | ||
128 | * @param {*} e | ||
129 | */ | ||
130 | onShowLocHandler(evt) { | ||
131 | let item = getBindtapData(evt); | ||
132 | |||
133 | wx.openLocation({ | ||
134 | latitude: item.latitude, // 纬度,范围为-90~90,负数表示南纬 | ||
135 | longitude: item.longitude, // 经度,范围为-180~180,负数表示西经 | ||
136 | scale: 18, // 缩放比例 | ||
137 | name: item.storeName, // 位置名 | ||
138 | address: item.storeAddress, // 地址的详细说明 | ||
139 | success: function (res) { | ||
140 | // success | ||
141 | } | ||
142 | }) | ||
143 | }, | ||
144 | |||
145 | // 转换成手动模式 | ||
146 | onSearchHandModeHandler() { | ||
147 | this.setData({ | ||
148 | searchMode: 2 | ||
149 | }); | ||
150 | }, | ||
151 | |||
152 | // 转换为自动模式 | ||
153 | onSearchAutoModeHandler() { | ||
154 | this.setData({ | ||
155 | searchMode: 1, | ||
156 | provinceId: "", | ||
157 | cityId: "", | ||
158 | districtId: "", | ||
159 | }) | ||
160 | }, | ||
161 | |||
162 | getProvince() { | ||
163 | return new Promise((resolve, reject) => { | ||
164 | app.post({ | ||
165 | url: app.api.provinceQuery | ||
166 | }).then((result) => { | ||
167 | this.setData({ | ||
168 | provinceList: result | ||
169 | }) | ||
170 | console.log("getProvince result:", result); | ||
171 | }) | ||
172 | }); | ||
173 | }, | ||
174 | |||
175 | getCity() { | ||
176 | return new Promise((resolve, reject) => { | ||
177 | app.post({ | ||
178 | url: app.api.cityQuery, | ||
179 | data: { | ||
180 | parentId: this.data.provinceId | ||
181 | } | ||
182 | }).then((result) => { | ||
183 | console.log("getCity result:", result); | ||
184 | }) | ||
185 | }); | ||
186 | }, | ||
187 | |||
188 | getDistrict() { | ||
189 | return new Promise((resolve, reject) => { | ||
190 | app.post({ | ||
191 | url: app.api.districtQuery, | ||
192 | data: { | ||
193 | parentId: this.data.cityId | ||
194 | } | ||
195 | }).then((result) => { | ||
196 | console.log("getDistrict result:", result); | ||
197 | }) | ||
198 | }); | ||
199 | }, | ||
200 | |||
201 | bindPickerChangeProvince(e) { | ||
202 | let index = e.detail.value; | ||
203 | this.setData({ | ||
204 | provinceIndex: index, | ||
205 | provinceId: this.data.provinceList[index].id, | ||
206 | cityList: [], | ||
207 | districtList: [], | ||
208 | }) | ||
209 | // 选市 | ||
210 | this.getCity() | ||
211 | }, | ||
212 | |||
213 | bindPickerChangeCity(e) { | ||
214 | let index = e.detail.value; | ||
215 | this.setData({ | ||
216 | cityIndex: index, | ||
217 | cityId: this.data.cityList[index].id, | ||
218 | districtList: [], | ||
219 | }) | ||
220 | this.getDistrict(); | ||
221 | }, | ||
222 | |||
223 | bindPickerChangeDistrict(e) { | ||
224 | let index = e.detail.value; | ||
225 | this.setData({ | ||
226 | districtIndex: index, | ||
227 | districtId: this.data.districtList[index].id, | ||
228 | }) | ||
229 | }, | ||
230 | |||
231 | |||
232 | |||
14 | // 这里是一个自定义方法 | 233 | // 这里是一个自定义方法 |
15 | customMethod() { | 234 | customMethod() { |
16 | this.triggerEvent('evtcomp', { | 235 | this.triggerEvent('evtcomp', { |
... | @@ -23,5 +242,9 @@ Component({ | ... | @@ -23,5 +242,9 @@ Component({ |
23 | name: "_evt_hide_mask" | 242 | name: "_evt_hide_mask" |
24 | }); | 243 | }); |
25 | } | 244 | } |
245 | }, | ||
246 | // | ||
247 | ready() { | ||
248 | this.getProvince(); | ||
26 | } | 249 | } |
27 | }) | 250 | }) | ... | ... |
... | @@ -53,6 +53,10 @@ $contentWidth:690px; | ... | @@ -53,6 +53,10 @@ $contentWidth:690px; |
53 | padding: 0 20px; | 53 | padding: 0 20px; |
54 | margin-right: 10px; | 54 | margin-right: 10px; |
55 | 55 | ||
56 | .val { | ||
57 | @include ellipsis(1); | ||
58 | } | ||
59 | |||
56 | .icon { | 60 | .icon { |
57 | width: 30px; | 61 | width: 30px; |
58 | height: 17px; | 62 | height: 17px; |
... | @@ -155,6 +159,11 @@ $contentWidth:690px; | ... | @@ -155,6 +159,11 @@ $contentWidth:690px; |
155 | margin: 0 auto; | 159 | margin: 0 auto; |
156 | @include cb(); | 160 | @include cb(); |
157 | } | 161 | } |
162 | |||
163 | .disable { | ||
164 | background: transparent; | ||
165 | background-color: #d2d2d2; | ||
166 | } | ||
158 | } | 167 | } |
159 | 168 | ||
160 | } | 169 | } | ... | ... |
1 | <view class="comp-item"> | 1 | <view class="comp-item"> |
2 | <view class="cont"> | 2 | <view class="cont"> |
3 | <!-- 导航 --> | 3 | <!-- 导航 --> |
4 | <view wx:if="{{1>10}}" class="nav nav1"> | 4 | <view wx:if="{{searchMode == 1}}" class="nav nav1"> |
5 | <view class="place"> | 5 | <view class="place"> |
6 | 您当前所在城市: | 6 | 您当前所在城市: |
7 | <span class="city">深圳市</span> | 7 | <span class="city">深圳市</span> |
8 | </view> | 8 | </view> |
9 | <view class="btn">切换城市</view> | 9 | <view bindtap="onSearchHandModeHandler" data-data="1" class="btn">手动选择</view> |
10 | </view> | 10 | </view> |
11 | <view wx:else class="nav nav2"> | 11 | <view wx:else class="nav nav2"> |
12 | <view class="area"> | 12 | <view class="area"> |
13 | <view class="area-item"> | 13 | <!-- 省 --> |
14 | 省 | 14 | <picker bindchange="bindPickerChangeProvince" value="{{provinceIndex}}" range="{{provinceList}}" range-key="name"> |
15 | <view bindtap="getProvince" class="area-item"> | ||
16 | <span class="val"> | ||
17 | {{provinceList[provinceIndex].name ? provinceList[provinceIndex].name : '省'}} | ||
18 | </span> | ||
15 | <image class="icon" mode="widthFix" src="../../image/oss/icon/icon-drow-down.png" /> | 19 | <image class="icon" mode="widthFix" src="../../image/oss/icon/icon-drow-down.png" /> |
16 | </view> | 20 | </view> |
21 | </picker> | ||
22 | <!-- 市 --> | ||
23 | <picker bindchange="bindPickerChangeCity" value="{{cityIndex}}" range="{{cityList}}" range-key="name"> | ||
17 | <view class="area-item"> | 24 | <view class="area-item"> |
18 | 市 | 25 | <span class="val">{{cityList[cityIndex].name ? cityList[cityIndex].name : '市'}}</span> |
19 | <image class="icon" mode="widthFix" src="../../image/oss/icon/icon-drow-down.png" /> | 26 | <image class="icon" mode="widthFix" src="../../image/oss/icon/icon-drow-down.png" /> |
20 | </view> | 27 | </view> |
28 | </picker> | ||
29 | <!-- 区 --> | ||
30 | <picker bindchange="bindPickerChangeDistrict" value="{{districtIndex}}" range="{{districtList}}" range-key="name"> | ||
21 | <view class="area-item"> | 31 | <view class="area-item"> |
22 | 区 | 32 | <span class="val"> |
33 | {{districtList[districtIndex].name ? districtList[districtIndex].name : '区'}} | ||
34 | </span> | ||
23 | <image class="icon" mode="widthFix" src="../../image/oss/icon/icon-drow-down.png" /> | 35 | <image class="icon" mode="widthFix" src="../../image/oss/icon/icon-drow-down.png" /> |
24 | </view> | 36 | </view> |
37 | </picker> | ||
25 | </view> | 38 | </view> |
26 | <view class="btn">切换城市</view> | 39 | <view bindtap="onSearchAutoModeHandler" data-data="2" class="btn">自动选择</view> |
27 | </view> | 40 | </view> |
28 | <!-- 门店列表 --> | 41 | <!-- 门店列表 --> |
29 | <scroll-view scroll-y="{{true}}" class="pos"> | 42 | <scroll-view scroll-y="{{true}}" class="pos"> |
30 | <view class="pos-item"> | 43 | <view bindtap="onSelectHandler" data-data="{{item}}" data-index="{{index}}" wx:for="{{addressList}}" wx:key="{{index}}" class="pos-item"> |
31 | <view wx:if="{{1>10}}" class="check"> | 44 | <view wx:if="{{selectedMode}}" class="check"> |
32 | <image class="icon" mode="widthFix" src="../../image/oss/icon/icon-check.png" /> | 45 | <image wx:if="{{item.selected}}" class="icon" mode="widthFix" src="../../image/oss/icon/icon-check.png" /> |
33 | </view> | ||
34 | <view class="info"> | ||
35 | <view class="tit"> | ||
36 | <view class="name">坂田天虹店</view> | ||
37 | <view class="distance">距您1.2公里</view> | ||
38 | </view> | ||
39 | <view class="address">地址:安徽省安庆市大观区集贤南路43号八佰伴购物中心一楼</view> | ||
40 | </view> | ||
41 | <view class="loc"> | ||
42 | <image class="icon" mode="widthFix" src="../../image/oss/icon/icon-loc.png" /> | ||
43 | <view class="txt">导航</view> | ||
44 | </view> | ||
45 | </view> | ||
46 | <view class="pos-item"> | ||
47 | <view class="check"> | ||
48 | <image class="icon" mode="widthFix" src="../../image/oss/icon/icon-check.png" /> | ||
49 | </view> | 46 | </view> |
50 | <view class="info"> | 47 | <view class="info"> |
51 | <view class="tit"> | 48 | <view class="tit"> |
52 | <view class="name">坂田天虹店</view> | 49 | <view class="name">{{item.storeName}}</view> |
53 | <view class="distance">距您1.2公里</view> | 50 | <view class="distance">距您{{item.distance}}</view> |
54 | </view> | 51 | </view> |
55 | <view class="address">地址:安徽省安庆市大观区集贤南路43号八佰伴购物中心一楼</view> | 52 | <view class="address">{{item.storeAddress}}</view> |
56 | </view> | 53 | </view> |
57 | <view class="loc"> | 54 | <view bindtap="onShowLocHandler" data-data="{{item}}" class="loc"> |
58 | <image class="icon" mode="widthFix" src="../../image/oss/icon/icon-loc.png" /> | 55 | <image class="icon" mode="widthFix" src="../../image/oss/icon/icon-loc.png" /> |
59 | <view class="txt">导航</view> | 56 | <view class="txt">导航</view> |
60 | </view> | 57 | </view> |
61 | </view> | 58 | </view> |
62 | </scroll-view> | 59 | </scroll-view> |
63 | <!-- 按钮 --> | 60 | <!-- 按钮 --> |
64 | <view wx:if="{{1>10}}" class="btn-wrap"> | 61 | <view wx:if="{{selectedMode}}" class="btn-wrap"> |
65 | <view bindtap="onSelectHandler" class="store-btn">选择门店</view> | 62 | <view wx:if="{{curAddress}}" bindtap="onSubmitHandler" class="store-btn">选择门店</view> |
63 | <view wx:else class="store-btn disable">选择门店</view> | ||
66 | </view> | 64 | </view> |
67 | </view> | 65 | </view> |
68 | </view> | 66 | </view> | ... | ... |
... | @@ -6,26 +6,10 @@ Component({ | ... | @@ -6,26 +6,10 @@ Component({ |
6 | type: String, | 6 | type: String, |
7 | value: 'default value', | 7 | value: 'default value', |
8 | }, | 8 | }, |
9 | eleList: { | ||
10 | type: Object, | ||
11 | value: [], | ||
12 | }, | ||
13 | eleVal: { | ||
14 | type: Number, | ||
15 | value: 0, | ||
16 | }, | ||
17 | wishBillInfo: { | ||
18 | type: Object, | ||
19 | value: {}, | ||
20 | }, | ||
21 | wishInfo: { | 9 | wishInfo: { |
22 | type: Object, | 10 | type: Object, |
23 | value: {}, | 11 | value: {}, |
24 | }, | 12 | }, |
25 | wishList: { | ||
26 | type: Object, | ||
27 | value: [], | ||
28 | }, | ||
29 | // 1正常(有库存) 2无库存 | 13 | // 1正常(有库存) 2无库存 |
30 | status: { | 14 | status: { |
31 | type: Number, | 15 | type: Number, |
... | @@ -49,19 +33,51 @@ Component({ | ... | @@ -49,19 +33,51 @@ Component({ |
49 | name: "_evt_hide_mask" | 33 | name: "_evt_hide_mask" |
50 | }); | 34 | }); |
51 | }, | 35 | }, |
52 | // 自提 要带上参数 | 36 | /** |
37 | * 提交礼品领取方式 | ||
38 | |||
39 | */ | ||
40 | queryWishbillAcceptTypeSubmit(acceptType) { | ||
41 | return new Promise((resolve, reject) => { | ||
42 | let wishInfo = this.properties.wishInfo; | ||
43 | app.post({ | ||
44 | url: app.api.wishbillAcceptTypeSubmit, | ||
45 | data: { | ||
46 | instanceCode: wishInfo.instanceCode, | ||
47 | acceptType: acceptType | ||
48 | } | ||
49 | }).then((result) => { | ||
50 | resolve(result) | ||
51 | }) | ||
52 | }); | ||
53 | }, | ||
54 | |||
55 | // 自提 | ||
53 | toSelfLiftHandler() { | 56 | toSelfLiftHandler() { |
57 | this.queryWishbillAcceptTypeSubmit(2).then((result) => { | ||
58 | console.log("prize-self-result:", result); | ||
59 | let wishInfo = this.properties.wishInfo; | ||
60 | let query = Object.assign(wishInfo, result); | ||
61 | console.log("prize-self-query:", query); | ||
54 | this.hideMask(); | 62 | this.hideMask(); |
55 | app.router.push({ | 63 | app.router.push({ |
56 | path: "prizeDetail", | 64 | path: "prizeDetail", |
57 | query: this.properties.wishInfo | 65 | query: query |
66 | }) | ||
58 | }) | 67 | }) |
59 | }, | 68 | }, |
60 | // 邮寄 | 69 | // 邮寄 |
61 | toUserTableHandler() { | 70 | toUserTableHandler() { |
71 | this.queryWishbillAcceptTypeSubmit(1).then((result) => { | ||
72 | console.log("prize-table-result:", result); | ||
73 | let wishInfo = this.properties.wishInfo; | ||
74 | let query = Object.assign(wishInfo, result); | ||
75 | console.log("prize-table-query:", query); | ||
62 | this.hideMask(); | 76 | this.hideMask(); |
63 | app.router.push({ | 77 | app.router.push({ |
64 | path: "userTable", | 78 | path: "userTable", |
79 | query: query | ||
80 | }) | ||
65 | }) | 81 | }) |
66 | }, | 82 | }, |
67 | 83 | ... | ... |
... | @@ -169,6 +169,199 @@ let productMap = { | ... | @@ -169,6 +169,199 @@ let productMap = { |
169 | 169 | ||
170 | } | 170 | } |
171 | 171 | ||
172 | |||
173 | |||
174 | /** | ||
175 | * @my-wish | ||
176 | * 点击领取心愿单奖品 | ||
177 | */ | ||
178 | let wishbillGiftAccept = { | ||
179 | "status": 1, | ||
180 | "order": { | ||
181 | "acceptType": 0, | ||
182 | "instanceCode": "162951b667a746188c83491bd5601164", | ||
183 | "prizeName": "丸美弹力蛋白眼精华素10g+10g", | ||
184 | "prizePic": "", | ||
185 | "commodityNo": "11059001" | ||
186 | }, | ||
187 | "coupon": null | ||
188 | } | ||
189 | |||
190 | /** | ||
191 | * @my-wish | ||
192 | * 点击单个心愿单奖品 | ||
193 | */ | ||
194 | let curWish = { | ||
195 | accessStatus: 1, | ||
196 | commodityNo: "11059001", | ||
197 | conditionElasticValue: 5480, | ||
198 | coupon: null, | ||
199 | elasticValue: 10000, | ||
200 | initialElasticValue: 33, | ||
201 | instanceCode: "162951b667a746188c83491bd5601164", | ||
202 | name: "丸美弹力蛋白眼精华素10g+10g", | ||
203 | order: { | ||
204 | acceptType: 0, | ||
205 | instanceCode: "162951b667a746188c83491bd5601164", | ||
206 | prizeName: "丸美弹力蛋白眼精华素10g+10g", | ||
207 | prizePic: "", | ||
208 | commodityNo: "11059001" | ||
209 | }, | ||
210 | point: { | ||
211 | left: 558, | ||
212 | top: 437 | ||
213 | }, | ||
214 | price: "548", | ||
215 | prizeDefineCode: "P000000000000000000000000000001", | ||
216 | prizeName: "丸美弹力蛋白眼精华素10g+10g", | ||
217 | prizePic: "", | ||
218 | progress: 100, | ||
219 | progressLeft: 169.00000000000003, | ||
220 | sence: 1, | ||
221 | status: 1, | ||
222 | storeRemain: 99, | ||
223 | tag: 3, | ||
224 | tips: { | ||
225 | type: "top-left", | ||
226 | point: { | ||
227 | fixLeft: -188, | ||
228 | fixTop: -314 | ||
229 | } | ||
230 | } | ||
231 | } | ||
232 | |||
233 | // 读取心愿单奖品 | ||
234 | let wishbillGiftQuery = { | ||
235 | "status": 1, | ||
236 | "order": { | ||
237 | "coupon": { | ||
238 | "couponId": "20839", | ||
239 | "couponCode": "RLLW18Q1", | ||
240 | "rule": "RLLW18Q1", | ||
241 | "startDate": 1564912960000, | ||
242 | "endDate": 1567526399000, | ||
243 | "type": 4, | ||
244 | "name": "眼部护理体验券-7月24日", | ||
245 | "state": 0 | ||
246 | }, | ||
247 | "acceptType": 2, | ||
248 | "instanceCode": "0924988c7fb0437b99c31b97bd1f1d6c", | ||
249 | "storeCode": "", | ||
250 | "storeName": "", | ||
251 | "storeAddress": "", | ||
252 | "latitude": 0.0, | ||
253 | "longitude": 0.0, | ||
254 | "prizeName": "丸美巧克力青春丝滑眼乳霜25g", | ||
255 | "orderSn": "MW20190804180237100003", | ||
256 | "commodityNo": "11039003" | ||
257 | }, | ||
258 | "coupon": null | ||
259 | } | ||
260 | |||
261 | /** | ||
262 | * @tips-prize-comp | ||
263 | * 自提数据 | ||
264 | */ | ||
265 | let prizeLiftQuery = { | ||
266 | "coupon": { | ||
267 | "couponId": "20839", | ||
268 | "couponCode": "RLLW18Q1", | ||
269 | "rule": "RLLW18Q1", | ||
270 | "startDate": 1564912960000, | ||
271 | "endDate": 1567526399000, | ||
272 | "type": 4, | ||
273 | "name": "眼部护理体验券-7月24日", | ||
274 | "state": 0 | ||
275 | }, | ||
276 | "acceptType": 2, | ||
277 | "instanceCode": "0924988c7fb0437b99c31b97bd1f1d6c", | ||
278 | "storeCode": "", | ||
279 | "storeName": "", | ||
280 | "storeAddress": "", | ||
281 | "latitude": 0.0, | ||
282 | "longitude": 0.0, | ||
283 | "prizeName": "丸美巧克力青春丝滑眼乳霜25g", | ||
284 | "orderSn": "MW20190804180237100003", | ||
285 | "commodityNo": "11039003" | ||
286 | } | ||
287 | |||
288 | /** | ||
289 | * @tips-prize-comp | ||
290 | * 邮寄提交返回数据 | ||
291 | */ | ||
292 | let prizeTableQuery = { | ||
293 | address: "", | ||
294 | associateMobile: "", | ||
295 | associateName: "", | ||
296 | city: "", | ||
297 | commodityNo: "11059001", | ||
298 | district: "", | ||
299 | instanceCode: "162951b667a746188c83491bd5601164", | ||
300 | logisticsCompany: "", | ||
301 | logisticsSn: "", | ||
302 | memberCode: "654b8d70164e4c1e83e1503d44f325db", | ||
303 | orderSn: "MW20190804152353100001", | ||
304 | prizeName: "丸美弹力蛋白眼精华素10g+10g", | ||
305 | prizePic: "", | ||
306 | province: "", | ||
307 | } | ||
308 | |||
309 | /** | ||
310 | * @tips-prize-comp | ||
311 | * 邮寄提交返回数据 合并 | ||
312 | */ | ||
313 | let prizeTableQueryAssign = { | ||
314 | accessStatus: 2, | ||
315 | address: "", | ||
316 | associateMobile: "", | ||
317 | associateName: "", | ||
318 | city: "", | ||
319 | commodityNo: "11059001", | ||
320 | conditionElasticValue: 5480, | ||
321 | coupon: null, | ||
322 | district: "", | ||
323 | elasticValue: 10000, | ||
324 | initialElasticValue: 33, | ||
325 | instanceCode: "162951b667a746188c83491bd5601164", | ||
326 | logisticsCompany: "", | ||
327 | logisticsSn: "", | ||
328 | memberCode: "654b8d70164e4c1e83e1503d44f325db", | ||
329 | name: "丸美弹力蛋白眼精华素10g+10g", | ||
330 | order: { | ||
331 | acceptType: 0, | ||
332 | instanceCode: "162951b667a746188c83491bd5601164", | ||
333 | prizeName: "丸美弹力蛋白眼精华素10g+10g", | ||
334 | prizePic: "", | ||
335 | commodityNo: "11059001" | ||
336 | }, | ||
337 | orderSn: "MW20190804152353100001", | ||
338 | point: { | ||
339 | left: 558, | ||
340 | top: 437 | ||
341 | }, | ||
342 | price: "548", | ||
343 | prizeDefineCode: "P000000000000000000000000000001", | ||
344 | prizeName: "丸美弹力蛋白眼精华素10g+10g", | ||
345 | prizePic: "", | ||
346 | progress: 100, | ||
347 | progressLeft: 169.00000000000003, | ||
348 | province: "", | ||
349 | sence: 1, | ||
350 | status: 1, | ||
351 | storeRemain: 98, | ||
352 | tag: 3, | ||
353 | tips: { | ||
354 | type: "top-left", | ||
355 | point: { | ||
356 | fixLeft: -188, | ||
357 | fixTop: -314 | ||
358 | }, | ||
359 | }, | ||
360 | } | ||
361 | |||
172 | module.exports = { | 362 | module.exports = { |
173 | productMap: productMap | 363 | productMap: productMap, |
364 | prizeTableQueryAssign: prizeTableQueryAssign, | ||
365 | prizeLiftQuery: prizeLiftQuery, | ||
366 | wishbillGiftQuery: wishbillGiftQuery | ||
174 | } | 367 | } | ... | ... |
... | @@ -22,5 +22,10 @@ module.exports = { | ... | @@ -22,5 +22,10 @@ module.exports = { |
22 | wishbillAcceptTypeSubmit: '/warubiEyeCreamApi/app/wishbill/accept/type/submit', // post 提交礼品领取方式 | 22 | wishbillAcceptTypeSubmit: '/warubiEyeCreamApi/app/wishbill/accept/type/submit', // post 提交礼品领取方式 |
23 | wishbillAddressSubmit: '/warubiEyeCreamApi/app/wishbill/address/submit', // post 提交邮寄地址 | 23 | wishbillAddressSubmit: '/warubiEyeCreamApi/app/wishbill/address/submit', // post 提交邮寄地址 |
24 | wishbillStoreAppoint: '/warubiEyeCreamApi/app/wishbill/store/appoint', // post 预约自提门店 | 24 | wishbillStoreAppoint: '/warubiEyeCreamApi/app/wishbill/store/appoint', // post 预约自提门店 |
25 | |||
26 | provinceQuery: '/warubiEyeCreamApi/app/store/province', // post 省 | ||
27 | cityQuery: '/warubiEyeCreamApi/app/store/city', // post 市 | ||
28 | districtQuery: '/warubiEyeCreamApi/app/store/district', // post 区 | ||
29 | |||
25 | wxacodeGet: '/warubiEyeCreamApi/app/qrcode/create', // | 30 | wxacodeGet: '/warubiEyeCreamApi/app/qrcode/create', // |
26 | } | 31 | } | ... | ... |
1 | import { | 1 | import { |
2 | getBindtapData | 2 | wishbillGiftQuery |
3 | } from '../../const/custom-data'; | ||
4 | |||
5 | import { | ||
6 | getBindtapData, | ||
7 | pxToRpx | ||
3 | } from '../../utils/util'; | 8 | } from '../../utils/util'; |
4 | import Date from '../../utils/date'; | 9 | import Date from '../../utils/date'; |
10 | |||
11 | import QR from '../../utils/qrcode' | ||
12 | |||
13 | |||
5 | let app = getApp(); | 14 | let app = getApp(); |
6 | Page({ | 15 | Page({ |
7 | data: { | 16 | data: { |
8 | userInfo: {}, | 17 | userInfo: {}, |
9 | used: false, //优惠券已使用,另外的样式 | 18 | used: false, //优惠券已使用,另外的样式 |
10 | couponInfo: { | 19 | wishInfo: {}, |
11 | "couponId": "20839", | 20 | couponInfo: {}, |
12 | "couponCode": "RLLL1IHG", | 21 | nearbyStoreVisible: false, |
13 | "rule": "RLLL1IHG", | 22 | qrImagePath: "", |
14 | "startDate": 1564479217000, | 23 | location: {}, |
15 | "endDate": 1567094399000, | ||
16 | "type": 4, | ||
17 | "name": "眼部护理体验券-7月24日", | ||
18 | "state": 0, | ||
19 | "endDateStr": "19-08-29" | ||
20 | } | ||
21 | }, | 24 | }, |
22 | onShareAppMessage() {}, | 25 | onShareAppMessage() {}, |
23 | onLoad(options) { | 26 | onLoad(options) { |
24 | let couponInfo = options; | 27 | // let wishInfo = options; |
28 | let wishInfo = wishbillGiftQuery.order; | ||
29 | let couponInfo = wishInfo.coupon; | ||
30 | |||
31 | // 设置起止时间 | ||
25 | couponInfo.startDateStr = new Date(couponInfo.startDate).toString("yyyy.MM.dd"); | 32 | couponInfo.startDateStr = new Date(couponInfo.startDate).toString("yyyy.MM.dd"); |
26 | couponInfo.endDateStr = new Date(couponInfo.endDate).toString("yyyy.MM.dd"); | 33 | couponInfo.endDateStr = new Date(couponInfo.endDate).toString("yyyy.MM.dd"); |
34 | |||
35 | // 判断是否使用 | ||
36 | // 自提券 使用状态(0=未使用 1=已过期,2=已使用) | ||
37 | let used = couponInfo.state != 0; | ||
38 | // used = true; | ||
39 | |||
40 | // 设置数据 | ||
27 | this.setData({ | 41 | this.setData({ |
28 | couponInfo: couponInfo | 42 | wishInfo: wishInfo, |
43 | couponInfo: couponInfo, | ||
44 | used: used | ||
29 | }) | 45 | }) |
30 | console.log("couponInfo:", couponInfo); | ||
31 | this.initData(); | 46 | this.initData(); |
32 | }, | 47 | }, |
33 | initData() { | 48 | initData() { |
... | @@ -35,11 +50,124 @@ Page({ | ... | @@ -35,11 +50,124 @@ Page({ |
35 | this.setData({ | 50 | this.setData({ |
36 | userInfo: app.globalData.userInfo | 51 | userInfo: app.globalData.userInfo |
37 | }) | 52 | }) |
53 | |||
54 | // 设置二维码 | ||
55 | let couponInfo = this.data.couponInfo; | ||
56 | let qrSize = this.setCanvasSize(300); | ||
57 | console.log("couponInfo:", couponInfo); | ||
58 | let codeContent = couponInfo.couponCode || ''; | ||
59 | this.createQrCode(codeContent, 'qrcanvas', qrSize.w, qrSize.h); | ||
60 | |||
61 | }) | ||
62 | }, | ||
63 | /** | ||
64 | * 请求门店地址 | ||
65 | */ | ||
66 | queryShop() { | ||
67 | this.selectComponent("#nearbyStoreComp").queryShop().then((result) => { | ||
68 | this.setData({ | ||
69 | nearbyStoreVisible: true | ||
70 | }) | ||
38 | }) | 71 | }) |
39 | }, | 72 | }, |
40 | // 查看可用门店 | 73 | // 查看可用门店 |
41 | onNearbyStoreHandler(evt) { | 74 | onNearbyStoreHandler(evt) { |
42 | console.log("onNearbyStoreHandler couponInfo:", this.data.couponInfo); | 75 | this.wxLocation(); |
76 | }, | ||
77 | // 使用微信位置 | ||
78 | wxLocation() { | ||
79 | let _this = this; | ||
80 | wx.getLocation({ | ||
81 | type: 'wgs84', | ||
82 | success(res) { | ||
83 | _this.setData({ | ||
84 | location: res | ||
85 | }) | ||
86 | _this.queryShop(); | ||
87 | }, | ||
88 | fail(err) { | ||
89 | wx.getSetting({ | ||
90 | success: (res) => { | ||
91 | if (!res.authSetting['scope.userLocation']) { | ||
92 | // 未授权 | ||
93 | wx.showModal({ | ||
94 | title: '提示', | ||
95 | content: '小程序请求访问地理位置', | ||
96 | confirmText: '前往授权', | ||
97 | success(res) { | ||
98 | if (res.confirm) { | ||
99 | wx.openSetting({ | ||
100 | complete() { | ||
101 | //设置完后重拉一遍位置,拉不到就算了 | ||
102 | wx.getLocation({ | ||
103 | type: 'wgs84', // 默认为 wgs84 返回 gps 坐标,gcj02 返回可用于 wx.openLocation 的坐标 | ||
104 | success: function (res) { | ||
105 | _this.setData({ | ||
106 | location: res | ||
107 | }) | ||
108 | _this.queryShop(); | ||
109 | }, | ||
110 | fail: function () { | ||
111 | _this.queryShop(); | ||
112 | } | ||
113 | }) | ||
114 | } | ||
115 | }) | ||
116 | } else if (res.cancel) { | ||
117 | // 模态窗取消 | ||
118 | _this.queryShop(); | ||
119 | } | ||
120 | } | ||
121 | }) | ||
122 | } | ||
123 | } | ||
124 | }) | ||
125 | } | ||
126 | }) | ||
127 | }, | ||
128 | createQrCode(content, canvasId, cavW, cavH) { | ||
129 | //调用插件中的draw方法,绘制二维码图片 | ||
130 | QR.api.draw(content, canvasId, cavW, cavH); | ||
131 | this.canvasToTempImage(canvasId); | ||
132 | }, | ||
133 | //获取临时缓存图片路径,存入data中 | ||
134 | canvasToTempImage(canvasId) { | ||
135 | let that = this; | ||
136 | wx.canvasToTempFilePath({ | ||
137 | canvasId, // 这里canvasId即之前创建的canvas-id | ||
138 | success: function (res) { | ||
139 | let tempFilePath = res.tempFilePath; | ||
140 | console.log(tempFilePath); | ||
141 | that.setData({ // 如果采用mpvue,即 this.imagePath = tempFilePath | ||
142 | qrImagePath: tempFilePath, | ||
143 | }); | ||
144 | }, | ||
145 | fail: function (res) { | ||
146 | console.log(res); | ||
147 | } | ||
148 | }); | ||
149 | }, | ||
150 | //适配不同屏幕大小的canvas | ||
151 | setCanvasSize(sz) { | ||
152 | var size = {}; | ||
153 | try { | ||
154 | var res = wx.getSystemInfoSync(); | ||
155 | var scale = 750 / sz; //不同屏幕下canvas的适配比例;设计稿是750宽 | ||
156 | var width = res.windowWidth / scale; | ||
157 | var height = width; //canvas画布为正方形 | ||
158 | size.w = width; | ||
159 | size.h = height; | ||
160 | } catch (e) { | ||
161 | // Do something when catch error | ||
162 | console.log("获取设备信息失败" + e); | ||
163 | } | ||
164 | return size; | ||
165 | }, | ||
166 | |||
167 | hideMask() { | ||
168 | this.setData({ | ||
169 | nearbyStoreVisible: false | ||
170 | }) | ||
43 | }, | 171 | }, |
44 | // 子组件事件 | 172 | // 子组件事件 |
45 | evtcomp(evt) { | 173 | evtcomp(evt) { |
... | @@ -50,6 +178,18 @@ Page({ | ... | @@ -50,6 +178,18 @@ Page({ |
50 | switch (name) { | 178 | switch (name) { |
51 | 179 | ||
52 | case "_evt_hide": | 180 | case "_evt_hide": |
181 | this.hideMask(); | ||
182 | break; | ||
183 | |||
184 | // 提交完毕 | ||
185 | case "_evt_submit_store_complete": | ||
186 | // 刷新状态 | ||
187 | this.hideMask(); | ||
188 | wx.showModal({ | ||
189 | content: '预约成功', | ||
190 | showCancel: false, | ||
191 | success(res) {} | ||
192 | }); | ||
53 | break; | 193 | break; |
54 | 194 | ||
55 | default: | 195 | default: | ... | ... |
1 | { | 1 | { |
2 | "navigationBarTitleText": "卡券详情", | 2 | "navigationBarTitleText": "卡券详情", |
3 | "usingComponents": { | 3 | "usingComponents": { |
4 | "use-notice-comp": "../../component/use-notice-comp/use-notice-comp" | 4 | "use-notice-comp": "../../component/use-notice-comp/use-notice-comp", |
5 | "tips-nearby-store-comp": "../../component/tips-nearby-store-comp/tips-nearby-store-comp", | ||
6 | "van-popup": "../../ui/vant-weapp/popup/index" | ||
5 | } | 7 | } |
6 | } | 8 | } | ... | ... |
... | @@ -2,6 +2,7 @@ | ... | @@ -2,6 +2,7 @@ |
2 | @import '../../assets/scss/utils'; | 2 | @import '../../assets/scss/utils'; |
3 | 3 | ||
4 | .page { | 4 | .page { |
5 | position: relative; | ||
5 | padding-bottom: $pageBottom; | 6 | padding-bottom: $pageBottom; |
6 | font-weight: 300; | 7 | font-weight: 300; |
7 | 8 | ||
... | @@ -82,8 +83,12 @@ | ... | @@ -82,8 +83,12 @@ |
82 | .qrcode { | 83 | .qrcode { |
83 | width: 300px; | 84 | width: 300px; |
84 | height: 300px; | 85 | height: 300px; |
85 | background-color: wheat; | ||
86 | margin: 0 auto; | 86 | margin: 0 auto; |
87 | |||
88 | image { | ||
89 | width: 300px; | ||
90 | height: 300px; | ||
91 | } | ||
87 | } | 92 | } |
88 | 93 | ||
89 | // 数字码 | 94 | // 数字码 |
... | @@ -215,14 +220,20 @@ | ... | @@ -215,14 +220,20 @@ |
215 | // 已使用 | 220 | // 已使用 |
216 | .used { | 221 | .used { |
217 | $alp: 0.3; | 222 | $alp: 0.3; |
218 | |||
219 | .qrcode { | ||
220 | opacity: $alp; | 223 | opacity: $alp; |
221 | } | ||
222 | 224 | ||
223 | .info { | 225 | // .qrcode { |
224 | opacity: $alp; | 226 | // opacity: $alp; |
225 | } | 227 | // } |
228 | |||
229 | // .info { | ||
230 | // opacity: $alp; | ||
231 | // } | ||
232 | |||
233 | // .code{ | ||
234 | // opacity: $alp; | ||
235 | // } | ||
236 | |||
226 | } | 237 | } |
227 | 238 | ||
228 | 239 | ... | ... |
1 | <canvas style="width: 300rpx;height: 300rpx;visibility: hidden;position:absolute;" canvas-id="qrcanvas" /> | ||
1 | <view class="page"> | 2 | <view class="page"> |
2 | <view class="app__bgc bgc"></view> | 3 | <view class="app__bgc bgc"></view> |
3 | <view class="app__bg bg"></view> | 4 | <view class="app__bg bg"></view> |
... | @@ -26,10 +27,14 @@ | ... | @@ -26,10 +27,14 @@ |
26 | </view> | 27 | </view> |
27 | </view> | 28 | </view> |
28 | <!-- 二维码 --> | 29 | <!-- 二维码 --> |
29 | <view class="qrcode"></view> | 30 | <view class="qrcode"> |
31 | <image class="image" mode="widthFix" src="{{qrImagePath}}" /> | ||
32 | </view> | ||
30 | <view class="code">{{couponInfo.couponCode}}</view> | 33 | <view class="code">{{couponInfo.couponCode}}</view> |
31 | <!-- 预约自提按钮 --> | 34 | <!-- 预约自提按钮 --> |
32 | <view wx:if="{{1<10}}" bindtap="onNearbyStoreHandler" class="reservation-btn">预约自提门店</view> | 35 | <view wx:if="{{1<10}}" bindtap="onNearbyStoreHandler" class="reservation-btn"> |
36 | 预约自提门店 | ||
37 | </view> | ||
33 | <!-- 预约成功 --> | 38 | <!-- 预约成功 --> |
34 | <view wx:else class="reservation-complete"> | 39 | <view wx:else class="reservation-complete"> |
35 | <view class="tips">您已成功预约,请在有效期内前往领取</view> | 40 | <view class="tips">您已成功预约,请在有效期内前往领取</view> |
... | @@ -57,3 +62,6 @@ | ... | @@ -57,3 +62,6 @@ |
57 | </view> | 62 | </view> |
58 | </view> | 63 | </view> |
59 | </view> | 64 | </view> |
65 | <van-popup show="{{ nearbyStoreVisible }}" position="bottom" bind:click-overlay="hideMask"> | ||
66 | <tips-nearby-store-comp id="nearbyStoreComp" bind:evtcomp="evtcomp" wish-info="{{wishInfo}}" location="{{location}}" selectedMode="{{true}}"></tips-nearby-store-comp> | ||
67 | </van-popup> | ... | ... |
1 | import { | ||
2 | prizeTableQueryAssign | ||
3 | } from '../../const/custom-data'; | ||
4 | |||
5 | import { | ||
6 | getBindtapData, | ||
7 | checkMobile, | ||
8 | } from '../../utils/util'; | ||
9 | |||
1 | let app = getApp(); | 10 | let app = getApp(); |
2 | Page({ | 11 | Page({ |
3 | data: { | 12 | data: { |
... | @@ -5,17 +14,122 @@ Page({ | ... | @@ -5,17 +14,122 @@ Page({ |
5 | receiverName: "", | 14 | receiverName: "", |
6 | receiverMobile: "", | 15 | receiverMobile: "", |
7 | receiverAddress: "", | 16 | receiverAddress: "", |
17 | addressStr: "", // 省市区合并地址 | ||
8 | region: [], | 18 | region: [], |
9 | regionStr: "", | 19 | regionStr: "", |
10 | prize: {} | 20 | prize: {}, |
21 | wishInfo: {} | ||
11 | }, | 22 | }, |
12 | onShareAppMessage() {}, | 23 | onShareAppMessage() {}, |
13 | onLoad(options) {}, | 24 | onLoad(options) { |
25 | // let wishInfo = options; | ||
26 | let wishInfo = prizeTableQueryAssign; | ||
27 | console.log("wishInfo:", wishInfo); | ||
28 | this.setData({ | ||
29 | wishInfo: wishInfo | ||
30 | }) | ||
31 | if (wishInfo.associateMobile) { | ||
32 | // 如果初始化回显,则要设置 表单信息 | ||
33 | // 显示省市区 | ||
34 | this.setData({ | ||
35 | receiverName: wishInfo.associateName, | ||
36 | receiverMobile: wishInfo.associateMobile, | ||
37 | receiverAddress: wishInfo.address, | ||
38 | regionStr: wishInfo.province + wishInfo.city + wishInfo.district, | ||
39 | }) | ||
40 | this.setStatus(1); | ||
41 | } else { | ||
42 | this.setStatus(0); | ||
43 | } | ||
44 | |||
45 | |||
46 | }, | ||
14 | /** | 47 | /** |
15 | * 提交表单 | 48 | * 提交表单 |
16 | * @param {*} evt | 49 | * @param {*} evt |
17 | */ | 50 | */ |
18 | onSubmitHandler(evt) {}, | 51 | onSubmitHandler(evt) { |
52 | let wishInfo = this.data.wishInfo; | ||
53 | let { | ||
54 | receiverName, | ||
55 | receiverMobile, | ||
56 | receiverAddress, | ||
57 | region, | ||
58 | } = this.data; | ||
59 | let receiverProvince = region[0]; | ||
60 | let receiverCity = region[1]; | ||
61 | let receiverDistrict = region[2]; | ||
62 | |||
63 | let tips = ""; | ||
64 | if (!receiverName) { | ||
65 | tips = "请输入姓名"; | ||
66 | this.showTips(tips); | ||
67 | return; | ||
68 | } | ||
69 | if (!receiverMobile) { | ||
70 | tips = "请输入手机号码"; | ||
71 | this.showTips(tips); | ||
72 | return; | ||
73 | } | ||
74 | if (!checkMobile(receiverMobile)) { | ||
75 | tips = "请输入正确的手机号"; | ||
76 | this.showTips(tips); | ||
77 | return; | ||
78 | } | ||
79 | if (!receiverProvince || !receiverCity || !receiverDistrict) { | ||
80 | tips = "请选择区域"; | ||
81 | this.showTips(tips); | ||
82 | return; | ||
83 | } | ||
84 | if (!receiverAddress) { | ||
85 | tips = "请填写地址"; | ||
86 | this.showTips(tips); | ||
87 | return; | ||
88 | } | ||
89 | |||
90 | |||
91 | let data = { | ||
92 | instanceCode: wishInfo.instanceCode, | ||
93 | associateName: receiverName, | ||
94 | associateMobile: receiverMobile, | ||
95 | province: receiverProvince, | ||
96 | city: receiverCity, | ||
97 | district: receiverDistrict, | ||
98 | address: receiverAddress, | ||
99 | } | ||
100 | console.log("data:", data); | ||
101 | |||
102 | app.post({ | ||
103 | url: app.api.wishbillAddressSubmit, | ||
104 | data: data | ||
105 | }).then((result) => { | ||
106 | this.setStatus(1); | ||
107 | }) | ||
108 | }, | ||
109 | |||
110 | // 设置显示状态 0:填写 1:回显 | ||
111 | setStatus(tableIndex) { | ||
112 | if (tableIndex == 1) { | ||
113 | // 回显,拼接完整地址 | ||
114 | this.refreshFullAddress(); | ||
115 | } | ||
116 | this.setData({ | ||
117 | tableIndex: tableIndex | ||
118 | }) | ||
119 | }, | ||
120 | /** | ||
121 | * 配置完整地址 | ||
122 | */ | ||
123 | refreshFullAddress() { | ||
124 | let { | ||
125 | receiverAddress, | ||
126 | regionStr, | ||
127 | } = this.data; | ||
128 | let addressStr = regionStr + receiverAddress; | ||
129 | this.setData({ | ||
130 | addressStr: addressStr | ||
131 | }) | ||
132 | }, | ||
19 | /** | 133 | /** |
20 | * 返回心愿单页面 | 134 | * 返回心愿单页面 |
21 | * @param {*} evt | 135 | * @param {*} evt |
... | @@ -26,17 +140,39 @@ Page({ | ... | @@ -26,17 +140,39 @@ Page({ |
26 | path: "wish" | 140 | path: "wish" |
27 | }) | 141 | }) |
28 | }, | 142 | }, |
143 | |||
144 | bindNameInput(e) { | ||
145 | this.setData({ | ||
146 | receiverName: e.detail.value | ||
147 | }) | ||
148 | }, | ||
149 | bindPhoneInput(e) { | ||
150 | this.setData({ | ||
151 | receiverMobile: e.detail.value | ||
152 | }) | ||
153 | }, | ||
154 | bindAddressInput(e) { | ||
155 | this.setData({ | ||
156 | receiverAddress: e.detail.value | ||
157 | }) | ||
158 | }, | ||
29 | bindRegionChange(e) { | 159 | bindRegionChange(e) { |
30 | let region = e.detail.value; | 160 | let region = e.detail.value; |
31 | let regionStr = ""; | 161 | let regionStr = ""; |
32 | if (region.length > 0) { | 162 | if (region.length > 0) { |
33 | regionStr = region.join(","); | 163 | regionStr = region.join(""); |
34 | } | 164 | } |
35 | this.setData({ | 165 | this.setData({ |
36 | region, | 166 | region, |
37 | regionStr | 167 | regionStr |
38 | }) | 168 | }) |
39 | }, | 169 | }, |
170 | showTips(tips) { | ||
171 | wx.showToast({ | ||
172 | title: tips, | ||
173 | icon: 'none' | ||
174 | }) | ||
175 | }, | ||
40 | // 子组件事件 | 176 | // 子组件事件 |
41 | evtcomp(evt) { | 177 | evtcomp(evt) { |
42 | let { | 178 | let { | ... | ... |
... | @@ -165,13 +165,24 @@ $iptHeight:80px; | ... | @@ -165,13 +165,24 @@ $iptHeight:80px; |
165 | align-items: center; | 165 | align-items: center; |
166 | width: 140px; | 166 | width: 140px; |
167 | @extend .bb; | 167 | @extend .bb; |
168 | padding: 0 20px; | 168 | padding: 0 12px; |
169 | font-size: 26px; | ||
169 | 170 | ||
170 | .icon { | 171 | .icon { |
171 | width: 15px; | 172 | width: 15px; |
172 | height: 9px; | 173 | height: 9px; |
173 | margin-left: 8px; | 174 | margin-left: 8px; |
174 | } | 175 | } |
176 | |||
177 | .val{ | ||
178 | // @extend | ||
179 | |||
180 | @include ellipsis(1); | ||
181 | } | ||
182 | |||
183 | .holder{ | ||
184 | |||
185 | } | ||
175 | } | 186 | } |
176 | 187 | ||
177 | .line { | 188 | .line { | ... | ... |
... | @@ -14,9 +14,9 @@ | ... | @@ -14,9 +14,9 @@ |
14 | <image mode="widthFix" src="../../image/oss/user-table/user-table-c1.png" /> | 14 | <image mode="widthFix" src="../../image/oss/user-table/user-table-c1.png" /> |
15 | </view> | 15 | </view> |
16 | <view class="display"> | 16 | <view class="display"> |
17 | <image class="prod" mode="aspectFit" src="../../image/prize/prize-1.png" /> | 17 | <image wx:if="{{wishInfo.tag}}" class="prod" mode="aspectFit" src="../../image/prize/prize-{{wishInfo.tag}}.png" /> |
18 | </view> | 18 | </view> |
19 | <view class="name">丸美弹力蛋白凝时紧致乳</view> | 19 | <view class="name">{{wishInfo.prizeName}}</view> |
20 | </view> | 20 | </view> |
21 | <!-- 表单 --> | 21 | <!-- 表单 --> |
22 | <view class="table"> | 22 | <view class="table"> |
... | @@ -28,28 +28,31 @@ | ... | @@ -28,28 +28,31 @@ |
28 | <view class="form"> | 28 | <view class="form"> |
29 | <view class="ipt"> | 29 | <view class="ipt"> |
30 | <view class="label">姓名</view> | 30 | <view class="label">姓名</view> |
31 | <input class="input" placeholder="请输入" /> | 31 | <input value="{{receiverName}}" bindinput="bindNameInput" class="input" placeholder="请输入" /> |
32 | </view> | 32 | </view> |
33 | <view class="ipt"> | 33 | <view class="ipt"> |
34 | <view class="label">电话</view> | 34 | <view class="label">电话</view> |
35 | <input class="input" placeholder="请输入" /> | 35 | <input value="{{receiverMobile}}" bindinput="bindPhoneInput" class="input" placeholder="请输入" /> |
36 | </view> | 36 | </view> |
37 | <view class="ipt"> | 37 | <view class="ipt"> |
38 | <view class="label">区域</view> | 38 | <view class="label">区域</view> |
39 | <picker class="form-detail-item-label" mode="region" bindchange="bindRegionChange" value="{{region}}"> | 39 | <picker class="form-detail-item-label" mode="region" bindchange="bindRegionChange" value="{{region}}"> |
40 | <view class="input area"> | 40 | <view class="input area"> |
41 | <view class="area-item area-item2"> | 41 | <view class="area-item area-item2"> |
42 | 省 | 42 | <span class="val">{{region[0]?region[0]:'省'}}</span> |
43 | <!-- <span wx:if="{{!region[0]}}" class="holder">省</span> --> | ||
43 | <image class="icon" mode="widthFix" src="../../image/oss/icon/icon-drow-down.png" /> | 44 | <image class="icon" mode="widthFix" src="../../image/oss/icon/icon-drow-down.png" /> |
44 | </view> | 45 | </view> |
45 | <view class="line"></view> | 46 | <view class="line"></view> |
46 | <view class="area-item area-item2"> | 47 | <view class="area-item area-item2"> |
47 | 市 | 48 | <span class="val">{{region[1]?region[1]:'市'}}</span> |
49 | <!-- <span wx:if="{{!region[1]}}" class="holder">市</span> --> | ||
48 | <image class="icon" mode="widthFix" src="../../image/oss/icon/icon-drow-down.png" /> | 50 | <image class="icon" mode="widthFix" src="../../image/oss/icon/icon-drow-down.png" /> |
49 | </view> | 51 | </view> |
50 | <view class="line"></view> | 52 | <view class="line"></view> |
51 | <view class="area-item area-item2"> | 53 | <view class="area-item area-item2"> |
52 | 区 | 54 | <span class="val">{{region[2]?region[2]:'区'}}</span> |
55 | <!-- <span wx:if="{{!region[2]}}" class="holder">区</span> --> | ||
53 | <image class="icon" mode="widthFix" src="../../image/oss/icon/icon-drow-down.png" /> | 56 | <image class="icon" mode="widthFix" src="../../image/oss/icon/icon-drow-down.png" /> |
54 | </view> | 57 | </view> |
55 | </view> | 58 | </view> |
... | @@ -57,7 +60,7 @@ | ... | @@ -57,7 +60,7 @@ |
57 | </view> | 60 | </view> |
58 | <view class="ipt ipt2"> | 61 | <view class="ipt ipt2"> |
59 | <view class="label">地址</view> | 62 | <view class="label">地址</view> |
60 | <textarea class="input textarea" placeholder="请输入"></textarea> | 63 | <textarea value="{{receiverAddress}}" bindinput="bindAddressInput" class="input textarea" placeholder="请输入"></textarea> |
61 | </view> | 64 | </view> |
62 | </view> | 65 | </view> |
63 | <view bindtap="onSubmitHandler" class="submit-btn">确认提交</view> | 66 | <view bindtap="onSubmitHandler" class="submit-btn">确认提交</view> |
... | @@ -68,16 +71,16 @@ | ... | @@ -68,16 +71,16 @@ |
68 | <view class="tips">*感谢您提交的地址,我们将尽快为您送出以上礼品</view> | 71 | <view class="tips">*感谢您提交的地址,我们将尽快为您送出以上礼品</view> |
69 | <view class="form"> | 72 | <view class="form"> |
70 | <view class="form-item"> | 73 | <view class="form-item"> |
71 | <view class="label">姓名</view> | 74 | <view class="label">{{wishInfo.associateName}}</view> |
72 | <view class="val">林小美</view> | 75 | <view class="val">林小美</view> |
73 | </view> | 76 | </view> |
74 | <view class="form-item"> | 77 | <view class="form-item"> |
75 | <view class="label">电话</view> | 78 | <view class="label">电话</view> |
76 | <view class="val">18812345678</view> | 79 | <view class="val">{{wishInfo.associateMobile}}</view> |
77 | </view> | 80 | </view> |
78 | <view class="form-item"> | 81 | <view class="form-item"> |
79 | <view class="label">地址</view> | 82 | <view class="label">地址</view> |
80 | <view class="val">广州市天河区珠江新城花城大道路xx广州市天河区珠江新城花城大道路xx广州市天河区珠江新城花城大道路xx</view> | 83 | <view class="val">{{regionStr}}{{wishInfo.addressStr}}</view> |
81 | </view> | 84 | </view> |
82 | </view> | 85 | </view> |
83 | <view bindtap="onWishHandler" class="submit-btn">返回首页</view> | 86 | <view bindtap="onWishHandler" class="submit-btn">返回首页</view> | ... | ... |
... | @@ -16,7 +16,18 @@ Page({ | ... | @@ -16,7 +16,18 @@ Page({ |
16 | wishInfo: {}, | 16 | wishInfo: {}, |
17 | wishList: [], | 17 | wishList: [], |
18 | helperInfo: {}, | 18 | helperInfo: {}, |
19 | curWish: {}, | 19 | // curWish: {}, |
20 | curWish: { | ||
21 | "status": 1, | ||
22 | "order": { | ||
23 | "acceptType": 0, | ||
24 | "instanceCode": "162951b667a746188c83491bd5601164", | ||
25 | "prizeName": "丸美弹力蛋白眼精华素10g+10g", | ||
26 | "prizePic": "", | ||
27 | "commodityNo": "11059001" | ||
28 | }, | ||
29 | "coupon": null | ||
30 | }, | ||
20 | status: 1, // 1正常(有库存) 2无库存 | 31 | status: 1, // 1正常(有库存) 2无库存 |
21 | }, | 32 | }, |
22 | onShareAppMessage() {}, | 33 | onShareAppMessage() {}, |
... | @@ -38,28 +49,64 @@ Page({ | ... | @@ -38,28 +49,64 @@ Page({ |
38 | onGetGiftHandler(evt) { | 49 | onGetGiftHandler(evt) { |
39 | let curData = getBindtapData(evt); | 50 | let curData = getBindtapData(evt); |
40 | console.log("curData:", curData); | 51 | console.log("curData:", curData); |
41 | this.setData({ | 52 | app.post({ |
42 | curWish: curData, | ||
43 | tipsPirzeVisible: true, | ||
44 | }) | ||
45 | return; | ||
46 | app.poster({ | ||
47 | url: app.api.wishbillGiftAccept, | 53 | url: app.api.wishbillGiftAccept, |
48 | data: curData | 54 | data: { |
55 | instanceCode: curData.instanceCode | ||
56 | } | ||
49 | }).then((result) => { | 57 | }).then((result) => { |
50 | // let curData | 58 | curData = Object.assign(curData, result); |
51 | this.setData({ | 59 | this.setData({ |
52 | curWish: curData, | 60 | curWish: curData, |
53 | tipsPirzeVisible: true, | 61 | tipsPirzeVisible: true, |
62 | status: curData.status | ||
54 | }) | 63 | }) |
55 | }); | 64 | }); |
56 | }, | 65 | }, |
57 | /** | 66 | /** |
58 | * 查看我的奖品 | 67 | * 查看我的奖品 |
68 | * 点击领取 | ||
59 | */ | 69 | */ |
60 | onCheckGiftHandler(evt) { | 70 | onCheckGiftHandler(evt) { |
61 | let curData = getBindtapData(evt); | 71 | let curData = getBindtapData(evt); |
62 | console.log("curData:", curData); | 72 | // console.log("curData:", curData); |
73 | app.post({ | ||
74 | url: app.api.wishbillGiftQuery, | ||
75 | data: { | ||
76 | instanceCode: curData.instanceCode | ||
77 | } | ||
78 | }).then((result) => { | ||
79 | curData = Object.assign(curData, result); | ||
80 | console.log("curData 222:", curData); | ||
81 | this.setData({ | ||
82 | curWish: curData, | ||
83 | status: curData.status | ||
84 | }) | ||
85 | // 领取状态 | ||
86 | // 领取类型:0=未提交;1=邮寄(填写邮寄信息);2=自提(填门店预约信息) | ||
87 | let acceptType = curData.order.acceptType; | ||
88 | console.log("acceptType:",acceptType); | ||
89 | if (acceptType == 0) { | ||
90 | // 未提交,显示领取选择 | ||
91 | this.setData({ | ||
92 | tipsPirzeVisible: true, | ||
93 | }) | ||
94 | } else if (acceptType == 1) { | ||
95 | // 已经选择邮寄 | ||
96 | // 判断是否已经填写邮寄信息 | ||
97 | app.router.push({ | ||
98 | path: "userTable" | ||
99 | }) | ||
100 | } else if (acceptType == 2) { | ||
101 | // 已经选择自提 | ||
102 | app.router.push({ | ||
103 | path: "prizeDetail" | ||
104 | }) | ||
105 | } | ||
106 | |||
107 | // 查看是否已经预约 | ||
108 | |||
109 | }) | ||
63 | }, | 110 | }, |
64 | // 显示规则页面 | 111 | // 显示规则页面 |
65 | onShowRuleHandler() { | 112 | onShowRuleHandler() { | ... | ... |
src/utils/qrcode.js
0 → 100755
1 | !(function () { | ||
2 | |||
3 | // alignment pattern | ||
4 | var adelta = [ | ||
5 | 0, 11, 15, 19, 23, 27, 31, | ||
6 | 16, 18, 20, 22, 24, 26, 28, 20, 22, 24, 24, 26, 28, 28, 22, 24, 24, | ||
7 | 26, 26, 28, 28, 24, 24, 26, 26, 26, 28, 28, 24, 26, 26, 26, 28, 28 | ||
8 | ]; | ||
9 | |||
10 | // version block | ||
11 | var vpat = [ | ||
12 | 0xc94, 0x5bc, 0xa99, 0x4d3, 0xbf6, 0x762, 0x847, 0x60d, | ||
13 | 0x928, 0xb78, 0x45d, 0xa17, 0x532, 0x9a6, 0x683, 0x8c9, | ||
14 | 0x7ec, 0xec4, 0x1e1, 0xfab, 0x08e, 0xc1a, 0x33f, 0xd75, | ||
15 | 0x250, 0x9d5, 0x6f0, 0x8ba, 0x79f, 0xb0b, 0x42e, 0xa64, | ||
16 | 0x541, 0xc69 | ||
17 | ]; | ||
18 | |||
19 | // final format bits with mask: level << 3 | mask | ||
20 | var fmtword = [ | ||
21 | 0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976, //L | ||
22 | 0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0, //M | ||
23 | 0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed, //Q | ||
24 | 0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b //H | ||
25 | ]; | ||
26 | |||
27 | // 4 per version: number of blocks 1,2; data width; ecc width | ||
28 | var eccblocks = [ | ||
29 | 1, 0, 19, 7, 1, 0, 16, 10, 1, 0, 13, 13, 1, 0, 9, 17, | ||
30 | 1, 0, 34, 10, 1, 0, 28, 16, 1, 0, 22, 22, 1, 0, 16, 28, | ||
31 | 1, 0, 55, 15, 1, 0, 44, 26, 2, 0, 17, 18, 2, 0, 13, 22, | ||
32 | 1, 0, 80, 20, 2, 0, 32, 18, 2, 0, 24, 26, 4, 0, 9, 16, | ||
33 | 1, 0, 108, 26, 2, 0, 43, 24, 2, 2, 15, 18, 2, 2, 11, 22, | ||
34 | 2, 0, 68, 18, 4, 0, 27, 16, 4, 0, 19, 24, 4, 0, 15, 28, | ||
35 | 2, 0, 78, 20, 4, 0, 31, 18, 2, 4, 14, 18, 4, 1, 13, 26, | ||
36 | 2, 0, 97, 24, 2, 2, 38, 22, 4, 2, 18, 22, 4, 2, 14, 26, | ||
37 | 2, 0, 116, 30, 3, 2, 36, 22, 4, 4, 16, 20, 4, 4, 12, 24, | ||
38 | 2, 2, 68, 18, 4, 1, 43, 26, 6, 2, 19, 24, 6, 2, 15, 28, | ||
39 | 4, 0, 81, 20, 1, 4, 50, 30, 4, 4, 22, 28, 3, 8, 12, 24, | ||
40 | 2, 2, 92, 24, 6, 2, 36, 22, 4, 6, 20, 26, 7, 4, 14, 28, | ||
41 | 4, 0, 107, 26, 8, 1, 37, 22, 8, 4, 20, 24, 12, 4, 11, 22, | ||
42 | 3, 1, 115, 30, 4, 5, 40, 24, 11, 5, 16, 20, 11, 5, 12, 24, | ||
43 | 5, 1, 87, 22, 5, 5, 41, 24, 5, 7, 24, 30, 11, 7, 12, 24, | ||
44 | 5, 1, 98, 24, 7, 3, 45, 28, 15, 2, 19, 24, 3, 13, 15, 30, | ||
45 | 1, 5, 107, 28, 10, 1, 46, 28, 1, 15, 22, 28, 2, 17, 14, 28, | ||
46 | 5, 1, 120, 30, 9, 4, 43, 26, 17, 1, 22, 28, 2, 19, 14, 28, | ||
47 | 3, 4, 113, 28, 3, 11, 44, 26, 17, 4, 21, 26, 9, 16, 13, 26, | ||
48 | 3, 5, 107, 28, 3, 13, 41, 26, 15, 5, 24, 30, 15, 10, 15, 28, | ||
49 | 4, 4, 116, 28, 17, 0, 42, 26, 17, 6, 22, 28, 19, 6, 16, 30, | ||
50 | 2, 7, 111, 28, 17, 0, 46, 28, 7, 16, 24, 30, 34, 0, 13, 24, | ||
51 | 4, 5, 121, 30, 4, 14, 47, 28, 11, 14, 24, 30, 16, 14, 15, 30, | ||
52 | 6, 4, 117, 30, 6, 14, 45, 28, 11, 16, 24, 30, 30, 2, 16, 30, | ||
53 | 8, 4, 106, 26, 8, 13, 47, 28, 7, 22, 24, 30, 22, 13, 15, 30, | ||
54 | 10, 2, 114, 28, 19, 4, 46, 28, 28, 6, 22, 28, 33, 4, 16, 30, | ||
55 | 8, 4, 122, 30, 22, 3, 45, 28, 8, 26, 23, 30, 12, 28, 15, 30, | ||
56 | 3, 10, 117, 30, 3, 23, 45, 28, 4, 31, 24, 30, 11, 31, 15, 30, | ||
57 | 7, 7, 116, 30, 21, 7, 45, 28, 1, 37, 23, 30, 19, 26, 15, 30, | ||
58 | 5, 10, 115, 30, 19, 10, 47, 28, 15, 25, 24, 30, 23, 25, 15, 30, | ||
59 | 13, 3, 115, 30, 2, 29, 46, 28, 42, 1, 24, 30, 23, 28, 15, 30, | ||
60 | 17, 0, 115, 30, 10, 23, 46, 28, 10, 35, 24, 30, 19, 35, 15, 30, | ||
61 | 17, 1, 115, 30, 14, 21, 46, 28, 29, 19, 24, 30, 11, 46, 15, 30, | ||
62 | 13, 6, 115, 30, 14, 23, 46, 28, 44, 7, 24, 30, 59, 1, 16, 30, | ||
63 | 12, 7, 121, 30, 12, 26, 47, 28, 39, 14, 24, 30, 22, 41, 15, 30, | ||
64 | 6, 14, 121, 30, 6, 34, 47, 28, 46, 10, 24, 30, 2, 64, 15, 30, | ||
65 | 17, 4, 122, 30, 29, 14, 46, 28, 49, 10, 24, 30, 24, 46, 15, 30, | ||
66 | 4, 18, 122, 30, 13, 32, 46, 28, 48, 14, 24, 30, 42, 32, 15, 30, | ||
67 | 20, 4, 117, 30, 40, 7, 47, 28, 43, 22, 24, 30, 10, 67, 15, 30, | ||
68 | 19, 6, 118, 30, 18, 31, 47, 28, 34, 34, 24, 30, 20, 61, 15, 30 | ||
69 | ]; | ||
70 | |||
71 | // Galois field log table | ||
72 | var glog = [ | ||
73 | 0xff, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6, 0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b, | ||
74 | 0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81, 0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71, | ||
75 | 0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21, 0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45, | ||
76 | 0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9, 0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6, | ||
77 | 0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd, 0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88, | ||
78 | 0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd, 0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40, | ||
79 | 0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e, 0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d, | ||
80 | 0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b, 0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57, | ||
81 | 0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d, 0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18, | ||
82 | 0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c, 0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e, | ||
83 | 0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd, 0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61, | ||
84 | 0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e, 0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2, | ||
85 | 0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76, 0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6, | ||
86 | 0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa, 0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a, | ||
87 | 0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51, 0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7, | ||
88 | 0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8, 0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf | ||
89 | ]; | ||
90 | |||
91 | // Galios field exponent table | ||
92 | var gexp = [ | ||
93 | 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26, | ||
94 | 0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9, 0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, | ||
95 | 0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35, 0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23, | ||
96 | 0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0, 0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1, | ||
97 | 0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc, 0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0, | ||
98 | 0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f, 0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2, | ||
99 | 0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88, 0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce, | ||
100 | 0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93, 0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc, | ||
101 | 0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9, 0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54, | ||
102 | 0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa, 0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73, | ||
103 | 0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e, 0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff, | ||
104 | 0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4, 0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41, | ||
105 | 0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6, | ||
106 | 0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef, 0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09, | ||
107 | 0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5, 0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16, | ||
108 | 0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, 0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x00 | ||
109 | ]; | ||
110 | |||
111 | // Working buffers: | ||
112 | // data input and ecc append, image working buffer, fixed part of image, run lengths for badness | ||
113 | var strinbuf = [], eccbuf = [], qrframe = [], framask = [], rlens = []; | ||
114 | // Control values - width is based on version, last 4 are from table. | ||
115 | var version, width, neccblk1, neccblk2, datablkw, eccblkwid; | ||
116 | var ecclevel = 2; | ||
117 | // set bit to indicate cell in qrframe is immutable. symmetric around diagonal | ||
118 | function setmask(x, y) { | ||
119 | var bt; | ||
120 | if (x > y) { | ||
121 | bt = x; | ||
122 | x = y; | ||
123 | y = bt; | ||
124 | } | ||
125 | // y*y = 1+3+5... | ||
126 | bt = y; | ||
127 | bt *= y; | ||
128 | bt += y; | ||
129 | bt >>= 1; | ||
130 | bt += x; | ||
131 | framask[bt] = 1; | ||
132 | } | ||
133 | |||
134 | // enter alignment pattern - black to qrframe, white to mask (later black frame merged to mask) | ||
135 | function putalign(x, y) { | ||
136 | var j; | ||
137 | |||
138 | qrframe[x + width * y] = 1; | ||
139 | for (j = -2; j < 2; j++) { | ||
140 | qrframe[(x + j) + width * (y - 2)] = 1; | ||
141 | qrframe[(x - 2) + width * (y + j + 1)] = 1; | ||
142 | qrframe[(x + 2) + width * (y + j)] = 1; | ||
143 | qrframe[(x + j + 1) + width * (y + 2)] = 1; | ||
144 | } | ||
145 | for (j = 0; j < 2; j++) { | ||
146 | setmask(x - 1, y + j); | ||
147 | setmask(x + 1, y - j); | ||
148 | setmask(x - j, y - 1); | ||
149 | setmask(x + j, y + 1); | ||
150 | } | ||
151 | } | ||
152 | |||
153 | //======================================================================== | ||
154 | // Reed Solomon error correction | ||
155 | // exponentiation mod N | ||
156 | function modnn(x) { | ||
157 | while (x >= 255) { | ||
158 | x -= 255; | ||
159 | x = (x >> 8) + (x & 255); | ||
160 | } | ||
161 | return x; | ||
162 | } | ||
163 | |||
164 | var genpoly = []; | ||
165 | |||
166 | // Calculate and append ECC data to data block. Block is in strinbuf, indexes to buffers given. | ||
167 | function appendrs(data, dlen, ecbuf, eclen) { | ||
168 | var i, j, fb; | ||
169 | |||
170 | for (i = 0; i < eclen; i++) | ||
171 | strinbuf[ecbuf + i] = 0; | ||
172 | for (i = 0; i < dlen; i++) { | ||
173 | fb = glog[strinbuf[data + i] ^ strinbuf[ecbuf]]; | ||
174 | if (fb != 255) /* fb term is non-zero */ | ||
175 | for (j = 1; j < eclen; j++) | ||
176 | strinbuf[ecbuf + j - 1] = strinbuf[ecbuf + j] ^ gexp[modnn(fb + genpoly[eclen - j])]; | ||
177 | else | ||
178 | for (j = ecbuf; j < ecbuf + eclen; j++) | ||
179 | strinbuf[j] = strinbuf[j + 1]; | ||
180 | strinbuf[ecbuf + eclen - 1] = fb == 255 ? 0 : gexp[modnn(fb + genpoly[0])]; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | //======================================================================== | ||
185 | // Frame data insert following the path rules | ||
186 | |||
187 | // check mask - since symmetrical use half. | ||
188 | function ismasked(x, y) { | ||
189 | var bt; | ||
190 | if (x > y) { | ||
191 | bt = x; | ||
192 | x = y; | ||
193 | y = bt; | ||
194 | } | ||
195 | bt = y; | ||
196 | bt += y * y; | ||
197 | bt >>= 1; | ||
198 | bt += x; | ||
199 | return framask[bt]; | ||
200 | } | ||
201 | |||
202 | //======================================================================== | ||
203 | // Apply the selected mask out of the 8. | ||
204 | function applymask(m) { | ||
205 | var x, y, r3x, r3y; | ||
206 | |||
207 | switch (m) { | ||
208 | case 0: | ||
209 | for (y = 0; y < width; y++) | ||
210 | for (x = 0; x < width; x++) | ||
211 | if (!((x + y) & 1) && !ismasked(x, y)) | ||
212 | qrframe[x + y * width] ^= 1; | ||
213 | break; | ||
214 | case 1: | ||
215 | for (y = 0; y < width; y++) | ||
216 | for (x = 0; x < width; x++) | ||
217 | if (!(y & 1) && !ismasked(x, y)) | ||
218 | qrframe[x + y * width] ^= 1; | ||
219 | break; | ||
220 | case 2: | ||
221 | for (y = 0; y < width; y++) | ||
222 | for (r3x = 0, x = 0; x < width; x++ , r3x++) { | ||
223 | if (r3x == 3) | ||
224 | r3x = 0; | ||
225 | if (!r3x && !ismasked(x, y)) | ||
226 | qrframe[x + y * width] ^= 1; | ||
227 | } | ||
228 | break; | ||
229 | case 3: | ||
230 | for (r3y = 0, y = 0; y < width; y++ , r3y++) { | ||
231 | if (r3y == 3) | ||
232 | r3y = 0; | ||
233 | for (r3x = r3y, x = 0; x < width; x++ , r3x++) { | ||
234 | if (r3x == 3) | ||
235 | r3x = 0; | ||
236 | if (!r3x && !ismasked(x, y)) | ||
237 | qrframe[x + y * width] ^= 1; | ||
238 | } | ||
239 | } | ||
240 | break; | ||
241 | case 4: | ||
242 | for (y = 0; y < width; y++) | ||
243 | for (r3x = 0, r3y = ((y >> 1) & 1), x = 0; x < width; x++ , r3x++) { | ||
244 | if (r3x == 3) { | ||
245 | r3x = 0; | ||
246 | r3y = !r3y; | ||
247 | } | ||
248 | if (!r3y && !ismasked(x, y)) | ||
249 | qrframe[x + y * width] ^= 1; | ||
250 | } | ||
251 | break; | ||
252 | case 5: | ||
253 | for (r3y = 0, y = 0; y < width; y++ , r3y++) { | ||
254 | if (r3y == 3) | ||
255 | r3y = 0; | ||
256 | for (r3x = 0, x = 0; x < width; x++ , r3x++) { | ||
257 | if (r3x == 3) | ||
258 | r3x = 0; | ||
259 | if (!((x & y & 1) + !(!r3x | !r3y)) && !ismasked(x, y)) | ||
260 | qrframe[x + y * width] ^= 1; | ||
261 | } | ||
262 | } | ||
263 | break; | ||
264 | case 6: | ||
265 | for (r3y = 0, y = 0; y < width; y++ , r3y++) { | ||
266 | if (r3y == 3) | ||
267 | r3y = 0; | ||
268 | for (r3x = 0, x = 0; x < width; x++ , r3x++) { | ||
269 | if (r3x == 3) | ||
270 | r3x = 0; | ||
271 | if (!(((x & y & 1) + (r3x && (r3x == r3y))) & 1) && !ismasked(x, y)) | ||
272 | qrframe[x + y * width] ^= 1; | ||
273 | } | ||
274 | } | ||
275 | break; | ||
276 | case 7: | ||
277 | for (r3y = 0, y = 0; y < width; y++ , r3y++) { | ||
278 | if (r3y == 3) | ||
279 | r3y = 0; | ||
280 | for (r3x = 0, x = 0; x < width; x++ , r3x++) { | ||
281 | if (r3x == 3) | ||
282 | r3x = 0; | ||
283 | if (!(((r3x && (r3x == r3y)) + ((x + y) & 1)) & 1) && !ismasked(x, y)) | ||
284 | qrframe[x + y * width] ^= 1; | ||
285 | } | ||
286 | } | ||
287 | break; | ||
288 | } | ||
289 | return; | ||
290 | } | ||
291 | |||
292 | // Badness coefficients. | ||
293 | var N1 = 3, N2 = 3, N3 = 40, N4 = 10; | ||
294 | |||
295 | // Using the table of the length of each run, calculate the amount of bad image | ||
296 | // - long runs or those that look like finders; called twice, once each for X and Y | ||
297 | function badruns(length) { | ||
298 | var i; | ||
299 | var runsbad = 0; | ||
300 | for (i = 0; i <= length; i++) | ||
301 | if (rlens[i] >= 5) | ||
302 | runsbad += N1 + rlens[i] - 5; | ||
303 | // BwBBBwB as in finder | ||
304 | for (i = 3; i < length - 1; i += 2) | ||
305 | if (rlens[i - 2] == rlens[i + 2] | ||
306 | && rlens[i + 2] == rlens[i - 1] | ||
307 | && rlens[i - 1] == rlens[i + 1] | ||
308 | && rlens[i - 1] * 3 == rlens[i] | ||
309 | // white around the black pattern? Not part of spec | ||
310 | && (rlens[i - 3] == 0 // beginning | ||
311 | || i + 3 > length // end | ||
312 | || rlens[i - 3] * 3 >= rlens[i] * 4 || rlens[i + 3] * 3 >= rlens[i] * 4) | ||
313 | ) | ||
314 | runsbad += N3; | ||
315 | return runsbad; | ||
316 | } | ||
317 | |||
318 | // Calculate how bad the masked image is - blocks, imbalance, runs, or finders. | ||
319 | function badcheck() { | ||
320 | var x, y, h, b, b1; | ||
321 | var thisbad = 0; | ||
322 | var bw = 0; | ||
323 | |||
324 | // blocks of same color. | ||
325 | for (y = 0; y < width - 1; y++) | ||
326 | for (x = 0; x < width - 1; x++) | ||
327 | if ((qrframe[x + width * y] && qrframe[(x + 1) + width * y] | ||
328 | && qrframe[x + width * (y + 1)] && qrframe[(x + 1) + width * (y + 1)]) // all black | ||
329 | || !(qrframe[x + width * y] || qrframe[(x + 1) + width * y] | ||
330 | || qrframe[x + width * (y + 1)] || qrframe[(x + 1) + width * (y + 1)])) // all white | ||
331 | thisbad += N2; | ||
332 | |||
333 | // X runs | ||
334 | for (y = 0; y < width; y++) { | ||
335 | rlens[0] = 0; | ||
336 | for (h = b = x = 0; x < width; x++) { | ||
337 | if ((b1 = qrframe[x + width * y]) == b) | ||
338 | rlens[h]++; | ||
339 | else | ||
340 | rlens[++h] = 1; | ||
341 | b = b1; | ||
342 | bw += b ? 1 : -1; | ||
343 | } | ||
344 | thisbad += badruns(h); | ||
345 | } | ||
346 | |||
347 | // black/white imbalance | ||
348 | if (bw < 0) | ||
349 | bw = -bw; | ||
350 | |||
351 | var big = bw; | ||
352 | var count = 0; | ||
353 | big += big << 2; | ||
354 | big <<= 1; | ||
355 | while (big > width * width) | ||
356 | big -= width * width, count++; | ||
357 | thisbad += count * N4; | ||
358 | |||
359 | // Y runs | ||
360 | for (x = 0; x < width; x++) { | ||
361 | rlens[0] = 0; | ||
362 | for (h = b = y = 0; y < width; y++) { | ||
363 | if ((b1 = qrframe[x + width * y]) == b) | ||
364 | rlens[h]++; | ||
365 | else | ||
366 | rlens[++h] = 1; | ||
367 | b = b1; | ||
368 | } | ||
369 | thisbad += badruns(h); | ||
370 | } | ||
371 | return thisbad; | ||
372 | } | ||
373 | |||
374 | function genframe(instring) { | ||
375 | var x, y, k, t, v, i, j, m; | ||
376 | |||
377 | // find the smallest version that fits the string | ||
378 | t = instring.length; | ||
379 | version = 0; | ||
380 | do { | ||
381 | version++; | ||
382 | k = (ecclevel - 1) * 4 + (version - 1) * 16; | ||
383 | neccblk1 = eccblocks[k++]; | ||
384 | neccblk2 = eccblocks[k++]; | ||
385 | datablkw = eccblocks[k++]; | ||
386 | eccblkwid = eccblocks[k]; | ||
387 | k = datablkw * (neccblk1 + neccblk2) + neccblk2 - 3 + (version <= 9); | ||
388 | if (t <= k) | ||
389 | break; | ||
390 | } while (version < 40); | ||
391 | |||
392 | // FIXME - insure that it fits insted of being truncated | ||
393 | width = 17 + 4 * version; | ||
394 | |||
395 | // allocate, clear and setup data structures | ||
396 | v = datablkw + (datablkw + eccblkwid) * (neccblk1 + neccblk2) + neccblk2; | ||
397 | for (t = 0; t < v; t++) | ||
398 | eccbuf[t] = 0; | ||
399 | strinbuf = instring.slice(0); | ||
400 | |||
401 | for (t = 0; t < width * width; t++) | ||
402 | qrframe[t] = 0; | ||
403 | |||
404 | for (t = 0; t < (width * (width + 1) + 1) / 2; t++) | ||
405 | framask[t] = 0; | ||
406 | |||
407 | // insert finders - black to frame, white to mask | ||
408 | for (t = 0; t < 3; t++) { | ||
409 | k = 0; | ||
410 | y = 0; | ||
411 | if (t == 1) | ||
412 | k = (width - 7); | ||
413 | if (t == 2) | ||
414 | y = (width - 7); | ||
415 | qrframe[(y + 3) + width * (k + 3)] = 1; | ||
416 | for (x = 0; x < 6; x++) { | ||
417 | qrframe[(y + x) + width * k] = 1; | ||
418 | qrframe[y + width * (k + x + 1)] = 1; | ||
419 | qrframe[(y + 6) + width * (k + x)] = 1; | ||
420 | qrframe[(y + x + 1) + width * (k + 6)] = 1; | ||
421 | } | ||
422 | for (x = 1; x < 5; x++) { | ||
423 | setmask(y + x, k + 1); | ||
424 | setmask(y + 1, k + x + 1); | ||
425 | setmask(y + 5, k + x); | ||
426 | setmask(y + x + 1, k + 5); | ||
427 | } | ||
428 | for (x = 2; x < 4; x++) { | ||
429 | qrframe[(y + x) + width * (k + 2)] = 1; | ||
430 | qrframe[(y + 2) + width * (k + x + 1)] = 1; | ||
431 | qrframe[(y + 4) + width * (k + x)] = 1; | ||
432 | qrframe[(y + x + 1) + width * (k + 4)] = 1; | ||
433 | } | ||
434 | } | ||
435 | |||
436 | // alignment blocks | ||
437 | if (version > 1) { | ||
438 | t = adelta[version]; | ||
439 | y = width - 7; | ||
440 | for (; ;) { | ||
441 | x = width - 7; | ||
442 | while (x > t - 3) { | ||
443 | putalign(x, y); | ||
444 | if (x < t) | ||
445 | break; | ||
446 | x -= t; | ||
447 | } | ||
448 | if (y <= t + 9) | ||
449 | break; | ||
450 | y -= t; | ||
451 | putalign(6, y); | ||
452 | putalign(y, 6); | ||
453 | } | ||
454 | } | ||
455 | |||
456 | // single black | ||
457 | qrframe[8 + width * (width - 8)] = 1; | ||
458 | |||
459 | // timing gap - mask only | ||
460 | for (y = 0; y < 7; y++) { | ||
461 | setmask(7, y); | ||
462 | setmask(width - 8, y); | ||
463 | setmask(7, y + width - 7); | ||
464 | } | ||
465 | for (x = 0; x < 8; x++) { | ||
466 | setmask(x, 7); | ||
467 | setmask(x + width - 8, 7); | ||
468 | setmask(x, width - 8); | ||
469 | } | ||
470 | |||
471 | // reserve mask-format area | ||
472 | for (x = 0; x < 9; x++) | ||
473 | setmask(x, 8); | ||
474 | for (x = 0; x < 8; x++) { | ||
475 | setmask(x + width - 8, 8); | ||
476 | setmask(8, x); | ||
477 | } | ||
478 | for (y = 0; y < 7; y++) | ||
479 | setmask(8, y + width - 7); | ||
480 | |||
481 | // timing row/col | ||
482 | for (x = 0; x < width - 14; x++) | ||
483 | if (x & 1) { | ||
484 | setmask(8 + x, 6); | ||
485 | setmask(6, 8 + x); | ||
486 | } | ||
487 | else { | ||
488 | qrframe[(8 + x) + width * 6] = 1; | ||
489 | qrframe[6 + width * (8 + x)] = 1; | ||
490 | } | ||
491 | |||
492 | // version block | ||
493 | if (version > 6) { | ||
494 | t = vpat[version - 7]; | ||
495 | k = 17; | ||
496 | for (x = 0; x < 6; x++) | ||
497 | for (y = 0; y < 3; y++ , k--) | ||
498 | if (1 & (k > 11 ? version >> (k - 12) : t >> k)) { | ||
499 | qrframe[(5 - x) + width * (2 - y + width - 11)] = 1; | ||
500 | qrframe[(2 - y + width - 11) + width * (5 - x)] = 1; | ||
501 | } | ||
502 | else { | ||
503 | setmask(5 - x, 2 - y + width - 11); | ||
504 | setmask(2 - y + width - 11, 5 - x); | ||
505 | } | ||
506 | } | ||
507 | |||
508 | // sync mask bits - only set above for white spaces, so add in black bits | ||
509 | for (y = 0; y < width; y++) | ||
510 | for (x = 0; x <= y; x++) | ||
511 | if (qrframe[x + width * y]) | ||
512 | setmask(x, y); | ||
513 | |||
514 | // convert string to bitstream | ||
515 | // 8 bit data to QR-coded 8 bit data (numeric or alphanum, or kanji not supported) | ||
516 | v = strinbuf.length; | ||
517 | |||
518 | // string to array | ||
519 | for (i = 0; i < v; i++) | ||
520 | eccbuf[i] = strinbuf.charCodeAt(i); | ||
521 | strinbuf = eccbuf.slice(0); | ||
522 | |||
523 | // calculate max string length | ||
524 | x = datablkw * (neccblk1 + neccblk2) + neccblk2; | ||
525 | if (v >= x - 2) { | ||
526 | v = x - 2; | ||
527 | if (version > 9) | ||
528 | v--; | ||
529 | } | ||
530 | |||
531 | // shift and repack to insert length prefix | ||
532 | i = v; | ||
533 | if (version > 9) { | ||
534 | strinbuf[i + 2] = 0; | ||
535 | strinbuf[i + 3] = 0; | ||
536 | while (i--) { | ||
537 | t = strinbuf[i]; | ||
538 | strinbuf[i + 3] |= 255 & (t << 4); | ||
539 | strinbuf[i + 2] = t >> 4; | ||
540 | } | ||
541 | strinbuf[2] |= 255 & (v << 4); | ||
542 | strinbuf[1] = v >> 4; | ||
543 | strinbuf[0] = 0x40 | (v >> 12); | ||
544 | } | ||
545 | else { | ||
546 | strinbuf[i + 1] = 0; | ||
547 | strinbuf[i + 2] = 0; | ||
548 | while (i--) { | ||
549 | t = strinbuf[i]; | ||
550 | strinbuf[i + 2] |= 255 & (t << 4); | ||
551 | strinbuf[i + 1] = t >> 4; | ||
552 | } | ||
553 | strinbuf[1] |= 255 & (v << 4); | ||
554 | strinbuf[0] = 0x40 | (v >> 4); | ||
555 | } | ||
556 | // fill to end with pad pattern | ||
557 | i = v + 3 - (version < 10); | ||
558 | while (i < x) { | ||
559 | strinbuf[i++] = 0xec; | ||
560 | // buffer has room if (i == x) break; | ||
561 | strinbuf[i++] = 0x11; | ||
562 | } | ||
563 | |||
564 | // calculate and append ECC | ||
565 | |||
566 | // calculate generator polynomial | ||
567 | genpoly[0] = 1; | ||
568 | for (i = 0; i < eccblkwid; i++) { | ||
569 | genpoly[i + 1] = 1; | ||
570 | for (j = i; j > 0; j--) | ||
571 | genpoly[j] = genpoly[j] | ||
572 | ? genpoly[j - 1] ^ gexp[modnn(glog[genpoly[j]] + i)] : genpoly[j - 1]; | ||
573 | genpoly[0] = gexp[modnn(glog[genpoly[0]] + i)]; | ||
574 | } | ||
575 | for (i = 0; i <= eccblkwid; i++) | ||
576 | genpoly[i] = glog[genpoly[i]]; // use logs for genpoly[] to save calc step | ||
577 | |||
578 | // append ecc to data buffer | ||
579 | k = x; | ||
580 | y = 0; | ||
581 | for (i = 0; i < neccblk1; i++) { | ||
582 | appendrs(y, datablkw, k, eccblkwid); | ||
583 | y += datablkw; | ||
584 | k += eccblkwid; | ||
585 | } | ||
586 | for (i = 0; i < neccblk2; i++) { | ||
587 | appendrs(y, datablkw + 1, k, eccblkwid); | ||
588 | y += datablkw + 1; | ||
589 | k += eccblkwid; | ||
590 | } | ||
591 | // interleave blocks | ||
592 | y = 0; | ||
593 | for (i = 0; i < datablkw; i++) { | ||
594 | for (j = 0; j < neccblk1; j++) | ||
595 | eccbuf[y++] = strinbuf[i + j * datablkw]; | ||
596 | for (j = 0; j < neccblk2; j++) | ||
597 | eccbuf[y++] = strinbuf[(neccblk1 * datablkw) + i + (j * (datablkw + 1))]; | ||
598 | } | ||
599 | for (j = 0; j < neccblk2; j++) | ||
600 | eccbuf[y++] = strinbuf[(neccblk1 * datablkw) + i + (j * (datablkw + 1))]; | ||
601 | for (i = 0; i < eccblkwid; i++) | ||
602 | for (j = 0; j < neccblk1 + neccblk2; j++) | ||
603 | eccbuf[y++] = strinbuf[x + i + j * eccblkwid]; | ||
604 | strinbuf = eccbuf; | ||
605 | |||
606 | // pack bits into frame avoiding masked area. | ||
607 | x = y = width - 1; | ||
608 | k = v = 1; // up, minus | ||
609 | /* inteleaved data and ecc codes */ | ||
610 | m = (datablkw + eccblkwid) * (neccblk1 + neccblk2) + neccblk2; | ||
611 | for (i = 0; i < m; i++) { | ||
612 | t = strinbuf[i]; | ||
613 | for (j = 0; j < 8; j++ , t <<= 1) { | ||
614 | if (0x80 & t) | ||
615 | qrframe[x + width * y] = 1; | ||
616 | do { // find next fill position | ||
617 | if (v) | ||
618 | x--; | ||
619 | else { | ||
620 | x++; | ||
621 | if (k) { | ||
622 | if (y != 0) | ||
623 | y--; | ||
624 | else { | ||
625 | x -= 2; | ||
626 | k = !k; | ||
627 | if (x == 6) { | ||
628 | x--; | ||
629 | y = 9; | ||
630 | } | ||
631 | } | ||
632 | } | ||
633 | else { | ||
634 | if (y != width - 1) | ||
635 | y++; | ||
636 | else { | ||
637 | x -= 2; | ||
638 | k = !k; | ||
639 | if (x == 6) { | ||
640 | x--; | ||
641 | y -= 8; | ||
642 | } | ||
643 | } | ||
644 | } | ||
645 | } | ||
646 | v = !v; | ||
647 | } while (ismasked(x, y)); | ||
648 | } | ||
649 | } | ||
650 | |||
651 | // save pre-mask copy of frame | ||
652 | strinbuf = qrframe.slice(0); | ||
653 | t = 0; // best | ||
654 | y = 30000; // demerit | ||
655 | // for instead of while since in original arduino code | ||
656 | // if an early mask was "good enough" it wouldn't try for a better one | ||
657 | // since they get more complex and take longer. | ||
658 | for (k = 0; k < 8; k++) { | ||
659 | applymask(k); // returns black-white imbalance | ||
660 | x = badcheck(); | ||
661 | if (x < y) { // current mask better than previous best? | ||
662 | y = x; | ||
663 | t = k; | ||
664 | } | ||
665 | if (t == 7) | ||
666 | break; // don't increment i to a void redoing mask | ||
667 | qrframe = strinbuf.slice(0); // reset for next pass | ||
668 | } | ||
669 | if (t != k) // redo best mask - none good enough, last wasn't t | ||
670 | applymask(t); | ||
671 | |||
672 | // add in final mask/ecclevel bytes | ||
673 | y = fmtword[t + ((ecclevel - 1) << 3)]; | ||
674 | // low byte | ||
675 | for (k = 0; k < 8; k++ , y >>= 1) | ||
676 | if (y & 1) { | ||
677 | qrframe[(width - 1 - k) + width * 8] = 1; | ||
678 | if (k < 6) | ||
679 | qrframe[8 + width * k] = 1; | ||
680 | else | ||
681 | qrframe[8 + width * (k + 1)] = 1; | ||
682 | } | ||
683 | // high byte | ||
684 | for (k = 0; k < 7; k++ , y >>= 1) | ||
685 | if (y & 1) { | ||
686 | qrframe[8 + width * (width - 7 + k)] = 1; | ||
687 | if (k) | ||
688 | qrframe[(6 - k) + width * 8] = 1; | ||
689 | else | ||
690 | qrframe[7 + width * 8] = 1; | ||
691 | } | ||
692 | return qrframe; | ||
693 | } | ||
694 | |||
695 | |||
696 | |||
697 | |||
698 | var _canvas = null; | ||
699 | |||
700 | var api = { | ||
701 | |||
702 | get ecclevel() { | ||
703 | return ecclevel; | ||
704 | }, | ||
705 | |||
706 | set ecclevel(val) { | ||
707 | ecclevel = val; | ||
708 | }, | ||
709 | |||
710 | get size() { | ||
711 | return _size; | ||
712 | }, | ||
713 | |||
714 | set size(val) { | ||
715 | _size = val | ||
716 | }, | ||
717 | |||
718 | get canvas() { | ||
719 | return _canvas; | ||
720 | }, | ||
721 | |||
722 | set canvas(el) { | ||
723 | _canvas = el; | ||
724 | }, | ||
725 | |||
726 | getFrame: function (string) { | ||
727 | return genframe(string); | ||
728 | }, | ||
729 | //这里的utf16to8(str)是对Text中的字符串进行转码,让其支持中文 | ||
730 | utf16to8: function (str) { | ||
731 | var out, i, len, c; | ||
732 | |||
733 | out = ""; | ||
734 | len = str.length; | ||
735 | for (i = 0; i < len; i++) { | ||
736 | c = str.charCodeAt(i); | ||
737 | if ((c >= 0x0001) && (c <= 0x007F)) { | ||
738 | out += str.charAt(i); | ||
739 | } else if (c > 0x07FF) { | ||
740 | out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F)); | ||
741 | out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F)); | ||
742 | out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F)); | ||
743 | } else { | ||
744 | out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F)); | ||
745 | out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F)); | ||
746 | } | ||
747 | } | ||
748 | return out; | ||
749 | }, | ||
750 | /** | ||
751 | * 新增$this参数,传入组件的this,兼容在组件中生成 | ||
752 | */ | ||
753 | draw: function (str, canvas, cavW, cavH, $this, ecc) { | ||
754 | var that = this; | ||
755 | ecclevel = ecc || ecclevel; | ||
756 | canvas = canvas || _canvas; | ||
757 | if (!canvas) { | ||
758 | console.warn('No canvas provided to draw QR code in!') | ||
759 | return; | ||
760 | } | ||
761 | |||
762 | var size = Math.min(cavW, cavH); | ||
763 | str = that.utf16to8(str);//增加中文显示 | ||
764 | |||
765 | var frame = that.getFrame(str), | ||
766 | // 组件中生成qrcode需要绑定this | ||
767 | ctx = wx.createCanvasContext(canvas,$this), | ||
768 | px = Math.round(size / (width + 8)); | ||
769 | var roundedSize = px * (width + 8), | ||
770 | offset = Math.floor((size - roundedSize) / 2); | ||
771 | size = roundedSize; | ||
772 | //ctx.clearRect(0, 0, cavW, cavW); | ||
773 | ctx.setFillStyle('#ffffff') | ||
774 | ctx.fillRect(0, 0, cavW, cavW); | ||
775 | ctx.setFillStyle('#000000'); | ||
776 | for (var i = 0; i < width; i++) { | ||
777 | for (var j = 0; j < width; j++) { | ||
778 | if (frame[j * width + i]) { | ||
779 | ctx.fillRect(px * (4 + i) + offset, px * (4 + j) + offset, px, px); | ||
780 | } | ||
781 | } | ||
782 | } | ||
783 | ctx.draw(); | ||
784 | } | ||
785 | } | ||
786 | module.exports = { api } | ||
787 | // exports.draw = api; | ||
788 | |||
789 | })(); | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or sign in to post a comment