版本提交
Showing
15 changed files
with
1363 additions
and
46 deletions
| ... | @@ -7,7 +7,9 @@ | ... | @@ -7,7 +7,9 @@ |
| 7 | </view> | 7 | </view> |
| 8 | <view class="name">{{item.commodityTitle}}</view> | 8 | <view class="name">{{item.commodityTitle}}</view> |
| 9 | <button class="btn" bindtap="onInnerButtonHandler">{{innerButton}}</button> | 9 | <button class="btn" bindtap="onInnerButtonHandler">{{innerButton}}</button> |
| 10 | <view wx:if="{{item.commodityType == 'packet'}}" class="tips">您可以在“个人中心→我的订单”中查看物流进度</view> | 10 | <view wx:if="{{item.commodityType == 'packet'}}" class="tips"> |
| 11 | <view wx:else class="tips">后台审核通过后,红包将会通过公众号消息或微信服务消息发送,届时请及时领取!</view> | 11 | 后台审核通过后,红包将会通过公众号消息或微信服务消息发送,届时请及时领取! |
| 12 | </view> | ||
| 13 | <view wx:else class="tips">您可以在“个人中心→我的订单”中查看物流进度</view> | ||
| 12 | </view> | 14 | </view> |
| 13 | </view> | 15 | </view> | ... | ... |
| ... | @@ -33,7 +33,7 @@ module.exports = { | ... | @@ -33,7 +33,7 @@ module.exports = { |
| 33 | scanPersonQrcode: '/scan/person/qrcode', // post 扫个人二维码 | 33 | scanPersonQrcode: '/scan/person/qrcode', // post 扫个人二维码 |
| 34 | signInfo: '/sign/info', // post 签到信息 用户注册接口 | 34 | signInfo: '/sign/info', // post 签到信息 用户注册接口 |
| 35 | sign: '/sign', // post 签到动作 用户注册接口 | 35 | sign: '/sign', // post 签到动作 用户注册接口 |
| 36 | sginRecord: '/sgin/record', // post 签到记录 用户注册接口 | 36 | signRecord: '/sign/record', // post 签到记录 用户注册接口 |
| 37 | 37 | ||
| 38 | areaQuery: 'https://api.k.wxpai.cn/bizproxy/kdapi/area', // post 区域查询 | 38 | areaQuery: 'https://api.k.wxpai.cn/bizproxy/kdapi/area', // post 区域查询 |
| 39 | 39 | ... | ... |
| ... | @@ -118,7 +118,7 @@ Page({ | ... | @@ -118,7 +118,7 @@ Page({ |
| 118 | } = this.data; | 118 | } = this.data; |
| 119 | wx.showModal({ | 119 | wx.showModal({ |
| 120 | title: '兑换确认', | 120 | title: '兑换确认', |
| 121 | content: `将花费${item.commodityPrice}兑换${commodityTitle}一份`, | 121 | content: `将花费${item.commodityPrice}兑换${item.commodityTitle}一份`, |
| 122 | success(res) { | 122 | success(res) { |
| 123 | if (res.confirm) { | 123 | if (res.confirm) { |
| 124 | app.post({ | 124 | app.post({ |
| ... | @@ -126,7 +126,7 @@ Page({ | ... | @@ -126,7 +126,7 @@ Page({ |
| 126 | data: { | 126 | data: { |
| 127 | commodityCode: item.commodityCode, | 127 | commodityCode: item.commodityCode, |
| 128 | receiverCode: defaultReceiver.receiverCode, | 128 | receiverCode: defaultReceiver.receiverCode, |
| 129 | remark: this.data.remark | 129 | remark: _this.data.remark |
| 130 | } | 130 | } |
| 131 | }).then((result) => { | 131 | }).then((result) => { |
| 132 | _this.initData().then((result) => { | 132 | _this.initData().then((result) => { |
| ... | @@ -134,8 +134,6 @@ Page({ | ... | @@ -134,8 +134,6 @@ Page({ |
| 134 | orderSubmitSuccessCompVisible: true | 134 | orderSubmitSuccessCompVisible: true |
| 135 | }) | 135 | }) |
| 136 | }) | 136 | }) |
| 137 | |||
| 138 | |||
| 139 | }) | 137 | }) |
| 140 | } | 138 | } |
| 141 | } | 139 | } | ... | ... |
| 1 | import { | ||
| 2 | getBindtapData | ||
| 3 | } from '../../utils/util'; | ||
| 4 | let Date = require('../../utils/date.js'); | ||
| 5 | |||
| 1 | let app = getApp(); | 6 | let app = getApp(); |
| 2 | Page({ | 7 | Page({ |
| 3 | data: { | 8 | data: { |
| 4 | authorizeVisible: false, | 9 | authorizeVisible: false, |
| 10 | userInfo: {}, | ||
| 11 | dateStart: "", | ||
| 12 | dateEnd: "", | ||
| 13 | dateStr: "", | ||
| 14 | total: 0, | ||
| 15 | page: 1, | ||
| 16 | size: 10, | ||
| 17 | status: "", | ||
| 18 | dataList: [], | ||
| 5 | navIndex: 0, | 19 | navIndex: 0, |
| 6 | navList: [{ | 20 | navList: [{ |
| 7 | t1: "全部", | 21 | t1: "全部", |
| 8 | t2: "", | 22 | t2: "", |
| 9 | index: 0, | 23 | index: "0", |
| 10 | }, | 24 | }, |
| 11 | { | 25 | { |
| 12 | t1: "300", | 26 | t1: "300", |
| 13 | t2: "购买积分", | 27 | t2: "购买积分", |
| 14 | index: 1, | 28 | index: "1", |
| 15 | }, | 29 | }, |
| 16 | { | 30 | { |
| 17 | t1: "200", | 31 | t1: "200", |
| 18 | t2: "推广积分", | 32 | t2: "推广积分", |
| 19 | index: 2, | 33 | index: "2", |
| 20 | }, | 34 | }, |
| 21 | { | 35 | { |
| 22 | t1: "50", | 36 | t1: "50", |
| 23 | t2: "签到积分", | 37 | t2: "签到积分", |
| 24 | index: 3, | 38 | index: "3", |
| 25 | }, | 39 | }, |
| 26 | { | 40 | { |
| 27 | t1: "300", | 41 | t1: "300", |
| 28 | t2: "奖励积分", | 42 | t2: "奖励积分", |
| 29 | index: 4, | 43 | index: "4", |
| 30 | }, | 44 | }, |
| 31 | { | 45 | { |
| 32 | t1: "300", | 46 | t1: "300", |
| 33 | t2: "兑换积分", | 47 | t2: "兑换积分", |
| 34 | index: 5, | 48 | index: "5", |
| 35 | }, | 49 | }, |
| 36 | ], | 50 | ], |
| 37 | }, | 51 | }, |
| ... | @@ -41,5 +55,157 @@ Page({ | ... | @@ -41,5 +55,157 @@ Page({ |
| 41 | authorizeVisible: true | 55 | authorizeVisible: true |
| 42 | }) | 56 | }) |
| 43 | }, | 57 | }, |
| 44 | onLoad(options) {} | 58 | onLoad(options) { |
| 59 | let dateStart = new Date().last().week().toString("yyyy-MM-dd"); | ||
| 60 | let dateEnd = Date.today().toString("yyyy-MM-dd"); | ||
| 61 | let dateStr = Date.today().toString("yyyy-MM"); | ||
| 62 | this.setData({ | ||
| 63 | dateStart, | ||
| 64 | dateEnd, | ||
| 65 | dateStr | ||
| 66 | }) | ||
| 67 | this.refreshStatus(); | ||
| 68 | this.initData(); | ||
| 69 | }, | ||
| 70 | |||
| 71 | initData() { | ||
| 72 | this.queryMember().then((result) => {}); | ||
| 73 | }, | ||
| 74 | |||
| 75 | // 到达底部 | ||
| 76 | onReachBottom() { | ||
| 77 | if (this.data.dataList.length < this.data.total) { | ||
| 78 | this.setData({ | ||
| 79 | page: this.data.page + 1 | ||
| 80 | }); | ||
| 81 | this.queryOrder(); | ||
| 82 | } | ||
| 83 | }, | ||
| 84 | |||
| 85 | // 重置页面列表 点击搜索条件时需要 | ||
| 86 | resetPage() { | ||
| 87 | this.setData({ | ||
| 88 | page: 1, | ||
| 89 | dataList: [] | ||
| 90 | }) | ||
| 91 | }, | ||
| 92 | |||
| 93 | /** | ||
| 94 | * 获取会员信息 | ||
| 95 | */ | ||
| 96 | queryMember() { | ||
| 97 | return new Promise((resolve, reject) => { | ||
| 98 | app.post({ | ||
| 99 | url: app.api.member, | ||
| 100 | data: {} | ||
| 101 | }).then((result) => { | ||
| 102 | this.setData({ | ||
| 103 | userInfo: result | ||
| 104 | }) | ||
| 105 | resolve(); | ||
| 106 | }) | ||
| 107 | }); | ||
| 108 | }, | ||
| 109 | |||
| 110 | /** | ||
| 111 | * 积分概览 | ||
| 112 | */ | ||
| 113 | queryPointsOverview() { | ||
| 114 | return new Promise((resolve, reject) => { | ||
| 115 | let year = this.data.dateStr.slice(0, 4); | ||
| 116 | let month = this.data.dateStr.slice(5, 7); | ||
| 117 | app.post({ | ||
| 118 | url: app.api.pointsOverview, | ||
| 119 | data: { | ||
| 120 | page: this.data.page, | ||
| 121 | size: this.data.size, | ||
| 122 | pointsType: this.data.status, | ||
| 123 | year: year, | ||
| 124 | month: month, | ||
| 125 | } | ||
| 126 | }).then((result) => { | ||
| 127 | console.log("result:", result); | ||
| 128 | let dataList = result.list; | ||
| 129 | dataList = this.data.dataList.concat(dataList); | ||
| 130 | dataList.forEach(element => { | ||
| 131 | element.time = new Date(element.createTime).toString("yyyy.MM.dd") | ||
| 132 | }); | ||
| 133 | this.setData({ | ||
| 134 | dataList: dataList, | ||
| 135 | total: result.total | ||
| 136 | }) | ||
| 137 | resolve(); | ||
| 138 | }) | ||
| 139 | }); | ||
| 140 | }, | ||
| 141 | |||
| 142 | bindDateChange(e) { | ||
| 143 | this.setData({ | ||
| 144 | dateStr: e.detail.value | ||
| 145 | }) | ||
| 146 | this.resetPage(); | ||
| 147 | this.refreshStatus(); | ||
| 148 | }, | ||
| 149 | |||
| 150 | /** | ||
| 151 | * 选择导航 | ||
| 152 | * @param {*} evt | ||
| 153 | */ | ||
| 154 | onNavSelectHandler(evt) { | ||
| 155 | let navIndex = this.data.navIndex; | ||
| 156 | let curIndex = getBindtapData(evt, "index"); | ||
| 157 | if (navIndex != curIndex) { | ||
| 158 | this.setData({ | ||
| 159 | navIndex: curIndex | ||
| 160 | }) | ||
| 161 | this.refreshStatus(); | ||
| 162 | } | ||
| 163 | }, | ||
| 164 | |||
| 165 | /** | ||
| 166 | * 刷新状态重新请求 | ||
| 167 | */ | ||
| 168 | refreshStatus() { | ||
| 169 | let status = ""; | ||
| 170 | let navIndex = this.data.navIndex + ""; | ||
| 171 | switch (navIndex) { | ||
| 172 | // 全部 | ||
| 173 | case "0": | ||
| 174 | status = ""; | ||
| 175 | break; | ||
| 176 | |||
| 177 | // 购买积分 | ||
| 178 | case "1": | ||
| 179 | status = "buy"; | ||
| 180 | break; | ||
| 181 | |||
| 182 | // 推广积分 | ||
| 183 | case "2": | ||
| 184 | status = "promotion"; | ||
| 185 | break; | ||
| 186 | |||
| 187 | // 签到积分 | ||
| 188 | case "3": | ||
| 189 | status = "sign"; | ||
| 190 | break; | ||
| 191 | |||
| 192 | // 奖励积分 | ||
| 193 | case "4": | ||
| 194 | status = "award"; | ||
| 195 | break; | ||
| 196 | |||
| 197 | // 兑换积分 | ||
| 198 | case "5": | ||
| 199 | status = "exchange"; | ||
| 200 | break; | ||
| 201 | |||
| 202 | default: | ||
| 203 | break; | ||
| 204 | } | ||
| 205 | this.setData({ | ||
| 206 | status: status | ||
| 207 | }) | ||
| 208 | this.resetPage(); | ||
| 209 | this.queryPointsOverview(); | ||
| 210 | } | ||
| 45 | }) | 211 | }) | ... | ... |
| ... | @@ -26,7 +26,7 @@ $contentWidth:690px; | ... | @@ -26,7 +26,7 @@ $contentWidth:690px; |
| 26 | width: $contentWidth; | 26 | width: $contentWidth; |
| 27 | margin: 0 auto; | 27 | margin: 0 auto; |
| 28 | 28 | ||
| 29 | .func { | 29 | .header { |
| 30 | display: flex; | 30 | display: flex; |
| 31 | justify-content: space-between; | 31 | justify-content: space-between; |
| 32 | align-items: flex-end; | 32 | align-items: flex-end; |
| ... | @@ -55,6 +55,55 @@ $contentWidth:690px; | ... | @@ -55,6 +55,55 @@ $contentWidth:690px; |
| 55 | height: 32px; | 55 | height: 32px; |
| 56 | margin: 8px; | 56 | margin: 8px; |
| 57 | } | 57 | } |
| 58 | |||
| 59 | .d1{ | ||
| 60 | margin-left: 8px; | ||
| 61 | } | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 65 | .func-wrap { | ||
| 66 | display: flex; | ||
| 67 | justify-content: space-between; | ||
| 68 | // padding: 4px 0; | ||
| 69 | } | ||
| 70 | |||
| 71 | .func { | ||
| 72 | @extend .fcc; | ||
| 73 | height: 80px; | ||
| 74 | // border-bottom: solid 1px #DDDDDD; | ||
| 75 | font-size: 26px; | ||
| 76 | color: #3680EB; | ||
| 77 | |||
| 78 | .icon { | ||
| 79 | width: 32px; | ||
| 80 | height: 32px; | ||
| 81 | margin: 0 8px; | ||
| 82 | } | ||
| 83 | |||
| 84 | .arrow { | ||
| 85 | width: 12px; | ||
| 86 | height: 8px; | ||
| 87 | margin: 0 8px; | ||
| 88 | } | ||
| 89 | } | ||
| 90 | |||
| 91 | // 时间 | ||
| 92 | .time { | ||
| 93 | .sel { | ||
| 94 | font-size: 28px; | ||
| 95 | color: #3680EB; | ||
| 96 | padding: 4px 16px; | ||
| 97 | @extend .fcc; | ||
| 98 | background-color: rgba($color: #3680EB, $alpha: 0.05); | ||
| 99 | border-radius: 4px; | ||
| 100 | margin-bottom: 12px; | ||
| 101 | |||
| 102 | .icon { | ||
| 103 | width: 32px; | ||
| 104 | height: 32px; | ||
| 105 | margin: 8px; | ||
| 106 | } | ||
| 58 | } | 107 | } |
| 59 | } | 108 | } |
| 60 | 109 | ... | ... |
| ... | @@ -4,20 +4,49 @@ | ... | @@ -4,20 +4,49 @@ |
| 4 | <view class="app__content main"> | 4 | <view class="app__content main"> |
| 5 | <view class="top-space"></view> | 5 | <view class="top-space"></view> |
| 6 | <view class="content"> | 6 | <view class="content"> |
| 7 | <view class="func"> | 7 | <view class="header"> |
| 8 | <view class="info"> | 8 | <view class="info"> |
| 9 | 现有积分 | 9 | 现有积分 |
| 10 | <span class="t1">360</span> | 10 | <span class="t1">{{userInfo.memberPoints}}</span> |
| 11 | 分 | 11 | 分 |
| 12 | </view> | 12 | </view> |
| 13 | <picker mode="date" fields="month" value="{{date}}" bindchange="bindDateChange"> | ||
| 14 | <view class="sel"> | ||
| 15 | <image class="icon" mode="aspectFit" src="../../image/icon/icon-calendar.png" /> | ||
| 16 | 时间筛选 | ||
| 17 | <span class="d1">{{dateStr}}</span> | ||
| 18 | </view> | ||
| 19 | </picker> | ||
| 20 | </view> | ||
| 21 | <!-- 时间 --> | ||
| 22 | <!-- <view class="time"> | ||
| 13 | <view class="sel"> | 23 | <view class="sel"> |
| 14 | <image class="icon" mode="aspectFit" src="../../image/icon/icon-calendar.png" /> | 24 | <image class="icon" mode="aspectFit" src="../../image/icon/icon-calendar.png" /> |
| 15 | 时间筛选 | 25 | 起始时间 |
| 16 | </view> | 26 | </view> |
| 17 | </view> | 27 | </view> --> |
| 28 | <!-- 时间选择器 --> | ||
| 29 | <!-- <view class="func-wrap"> | ||
| 30 | <picker mode="date" value="{{dateStart}}" bindchange="bindDateStartChange"> | ||
| 31 | <view class="func"> | ||
| 32 | <image class="icon" mode="aspectFit" src="../../image/icon/icon-sign-record.png" /> | ||
| 33 | 起始时间 | ||
| 34 | <image class="arrow" mode="aspectFit" src="../../image/icon/icon-filter-down-on.png" /> | ||
| 35 | {{dateStart}} | ||
| 36 | </view> | ||
| 37 | </picker> | ||
| 38 | <picker mode="date" value="{{dateEnd}}" bindchange="bindDateEndChange"> | ||
| 39 | <view class="func"> | ||
| 40 | <image class="icon" mode="aspectFit" src="../../image/icon/icon-sign-record.png" /> | ||
| 41 | 结束时间 | ||
| 42 | <image class="arrow" mode="aspectFit" src="../../image/icon/icon-filter-down-on.png" /> | ||
| 43 | {{dateEnd}} | ||
| 44 | </view> | ||
| 45 | </picker> | ||
| 46 | </view> --> | ||
| 18 | <!-- 标签 --> | 47 | <!-- 标签 --> |
| 19 | <view class="tag"> | 48 | <view class="tag"> |
| 20 | <view data-index="{{index}}" wx:for="{{navList}}" wx:key="{{index}}" class="tag-item"> | 49 | <view bindtap="onNavSelectHandler" data-data="{{item}}" data-index="{{index}}" wx:for="{{navList}}" wx:key="{{index}}" class="tag-item"> |
| 21 | <image wx:if="{{navIndex==index}}" class="ebg" mode="aspectFit" src="../../image/icon/icon-integral-tag.png" /> | 50 | <image wx:if="{{navIndex==index}}" class="ebg" mode="aspectFit" src="../../image/icon/icon-integral-tag.png" /> |
| 22 | <view class="desc {{navIndex == index ? 'act' : ''}}"> | 51 | <view class="desc {{navIndex == index ? 'act' : ''}}"> |
| 23 | <view class="t1">{{item.t1}}</view> | 52 | <view class="t1">{{item.t1}}</view> |
| ... | @@ -29,19 +58,22 @@ | ... | @@ -29,19 +58,22 @@ |
| 29 | <view class="tit"> | 58 | <view class="tit"> |
| 30 | <view class="tt t1">时间</view> | 59 | <view class="tt t1">时间</view> |
| 31 | <view class="tt t2">获取方式</view> | 60 | <view class="tt t2">获取方式</view> |
| 32 | <view class="tt t3">积分</view> | 61 | <view class="tt t3">名称</view> |
| 33 | <view class="tt t4 minus">积分</view> | 62 | <view class="tt t4 minus">积分</view> |
| 34 | </view> | 63 | </view> |
| 35 | <!-- 积分 --> | 64 | <!-- 积分 --> |
| 36 | <view class="integral"> | 65 | <view class="integral"> |
| 37 | <view class="integral-item"> | 66 | <view wx:for="{{dataList}}" wx:key="{{item}}" class="integral-item"> |
| 38 | <view class="tt t1">2019.03.13</view> | 67 | <view class="tt t1">{{item.time}}</view> |
| 39 | <view class="tt t2">扫码获取</view> | 68 | <view class="tt t2">{{item.subTitle}}</view> |
| 40 | <view class="tt t3">产品名称</view> | 69 | <view class="tt t3">产品名称</view> |
| 41 | <view class="tt t4 minus">+1000</view> | 70 | <view class="tt t4 {{item.pointsIp == 0 ? 'minus':''}}"> |
| 71 | {{item.pointsIp == 1 ? '+':'-'}} {{item.pointsNum}} | ||
| 72 | </view> | ||
| 42 | </view> | 73 | </view> |
| 43 | </view> | 74 | </view> |
| 44 | </view> | 75 | </view> |
| 76 | <empty-tips wx:if="{{dataList.length <= 0}}"></empty-tips> | ||
| 45 | </view> | 77 | </view> |
| 46 | </view> | 78 | </view> |
| 47 | <van-popup show="{{ authorizeVisible }}"> | 79 | <van-popup show="{{ authorizeVisible }}"> | ... | ... |
| ... | @@ -11,6 +11,7 @@ Page({ | ... | @@ -11,6 +11,7 @@ Page({ |
| 11 | page: 1, | 11 | page: 1, |
| 12 | size: 10, | 12 | size: 10, |
| 13 | dataList: [], | 13 | dataList: [], |
| 14 | orderStatus: "" | ||
| 14 | }, | 15 | }, |
| 15 | onShareAppMessage() {}, | 16 | onShareAppMessage() {}, |
| 16 | showAuth() { | 17 | showAuth() { |
| ... | @@ -27,11 +28,12 @@ Page({ | ... | @@ -27,11 +28,12 @@ Page({ |
| 27 | navIndex: navIndex | 28 | navIndex: navIndex |
| 28 | }) | 29 | }) |
| 29 | } | 30 | } |
| 30 | this.initData(); | 31 | this.refreshOrderStatus(); |
| 32 | // this.initData(); | ||
| 31 | }, | 33 | }, |
| 32 | 34 | ||
| 33 | initData() { | 35 | initData() { |
| 34 | this.queryOrder(); | 36 | // this.queryOrder(); |
| 35 | }, | 37 | }, |
| 36 | 38 | ||
| 37 | // 到达底部 | 39 | // 到达底部 |
| ... | @@ -44,6 +46,14 @@ Page({ | ... | @@ -44,6 +46,14 @@ Page({ |
| 44 | } | 46 | } |
| 45 | }, | 47 | }, |
| 46 | 48 | ||
| 49 | // 重置页面列表 点击搜索条件时需要 | ||
| 50 | resetPage() { | ||
| 51 | this.setData({ | ||
| 52 | page: 1, | ||
| 53 | dataList: [] | ||
| 54 | }) | ||
| 55 | }, | ||
| 56 | |||
| 47 | /** | 57 | /** |
| 48 | * 订单状态 | 58 | * 订单状态 |
| 49 | */ | 59 | */ |
| ... | @@ -54,7 +64,7 @@ Page({ | ... | @@ -54,7 +64,7 @@ Page({ |
| 54 | data: { | 64 | data: { |
| 55 | page: this.data.page, | 65 | page: this.data.page, |
| 56 | size: this.data.size, | 66 | size: this.data.size, |
| 57 | orderStatus: "" | 67 | orderStatus: this.data.orderStatus |
| 58 | } | 68 | } |
| 59 | }).then((result) => { | 69 | }).then((result) => { |
| 60 | let dataList = result.list; | 70 | let dataList = result.list; |
| ... | @@ -75,12 +85,53 @@ Page({ | ... | @@ -75,12 +85,53 @@ Page({ |
| 75 | onNavSelectHandler(evt) { | 85 | onNavSelectHandler(evt) { |
| 76 | let navIndex = this.data.navIndex; | 86 | let navIndex = this.data.navIndex; |
| 77 | let curIndex = getBindtapData(evt, "index"); | 87 | let curIndex = getBindtapData(evt, "index"); |
| 78 | console.log("curIndex:", curIndex); | ||
| 79 | if (navIndex != curIndex) { | 88 | if (navIndex != curIndex) { |
| 80 | this.setData({ | 89 | this.setData({ |
| 81 | navIndex: curIndex | 90 | navIndex: curIndex |
| 82 | }) | 91 | }) |
| 92 | this.refreshOrderStatus(); | ||
| 83 | } | 93 | } |
| 84 | }, | 94 | }, |
| 95 | /** | ||
| 96 | * 更新状态 | ||
| 97 | */ | ||
| 98 | refreshOrderStatus() { | ||
| 99 | let orderStatus = ""; | ||
| 100 | let navIndex = this.data.navIndex; | ||
| 101 | switch (navIndex) { | ||
| 102 | // 全部 | ||
| 103 | case "0": | ||
| 104 | orderStatus = ""; | ||
| 105 | break; | ||
| 106 | |||
| 107 | // 待审核 | ||
| 108 | case "1": | ||
| 109 | orderStatus = "unaudited"; | ||
| 110 | break; | ||
| 111 | |||
| 112 | // 已通过 | ||
| 113 | case "2": | ||
| 114 | orderStatus = "pass"; | ||
| 115 | break; | ||
| 116 | |||
| 117 | // 已发货 | ||
| 118 | case "3": | ||
| 119 | orderStatus = "deliver"; | ||
| 120 | break; | ||
| 121 | |||
| 122 | // 未通过 | ||
| 123 | case "4": | ||
| 124 | orderStatus = "audit_faild"; | ||
| 125 | break; | ||
| 126 | |||
| 127 | default: | ||
| 128 | break; | ||
| 129 | } | ||
| 130 | this.setData({ | ||
| 131 | orderStatus: orderStatus | ||
| 132 | }) | ||
| 133 | this.resetPage(); | ||
| 134 | this.queryOrder(); | ||
| 135 | } | ||
| 85 | 136 | ||
| 86 | }) | 137 | }) | ... | ... |
| ... | @@ -28,7 +28,71 @@ | ... | @@ -28,7 +28,71 @@ |
| 28 | </view> | 28 | </view> |
| 29 | </view> | 29 | </view> |
| 30 | <!-- 卡片 --> | 30 | <!-- 卡片 --> |
| 31 | 31 | <view class="card"> | |
| 32 | <view wx:for="{{dataList}}" wx:key="{{index}}" class="border card-item"> | ||
| 33 | <view class="no">订单编号:{{item.orderCode}}</view> | ||
| 34 | <view class="line"></view> | ||
| 35 | <view class="cont"> | ||
| 36 | <view class="prize"> | ||
| 37 | <image class="image" mode="aspectFit" /> | ||
| 38 | </view> | ||
| 39 | <view class="detail"> | ||
| 40 | <view class="t1">{{item.orderCommodityTitle}}</view> | ||
| 41 | <view class="t1 t2">{{item.orderCommodityPoints}}</view> | ||
| 42 | <view class="t1 t3"> | ||
| 43 | <span wx:if="{{item.orderStatus == 'unaudited'}}">待审核</span> | ||
| 44 | <span wx:if="{{item.orderStatus == 'pass'}}">已通过</span> | ||
| 45 | <span wx:if="{{item.orderStatus == 'deliver'}}">已发货</span> | ||
| 46 | <span wx:if="{{item.orderStatus == 'audit_faild'}}">未通过</span> | ||
| 47 | </view> | ||
| 48 | </view> | ||
| 49 | </view> | ||
| 50 | <view class="line"></view> | ||
| 51 | <view class="logistics"> | ||
| 52 | <view class="logistics-item"> | ||
| 53 | <view class="label">收货地址</view> | ||
| 54 | <view class="val">{{item.orderAddress}}</view> | ||
| 55 | </view> | ||
| 56 | <view class="logistics-item"> | ||
| 57 | <view class="label">物流公司</view> | ||
| 58 | <view class="val">{{item.logisticsCompany}}</view> | ||
| 59 | </view> | ||
| 60 | <view class="logistics-item"> | ||
| 61 | <view class="label">物流单号</view> | ||
| 62 | <view class="val">{{item.logisticsOdd}}</view> | ||
| 63 | </view> | ||
| 64 | </view> | ||
| 65 | </view> | ||
| 66 | <!-- <view class="border card-item"> | ||
| 67 | <view class="no">订单编号:2357123413491</view> | ||
| 68 | <view class="line"></view> | ||
| 69 | <view class="cont"> | ||
| 70 | <view class="prize"> | ||
| 71 | <image class="image" mode="aspectFit" /> | ||
| 72 | </view> | ||
| 73 | <view class="detail"> | ||
| 74 | <view class="t1">某东购物卡200元</view> | ||
| 75 | <view class="t1 t2">消耗积分:1000分</view> | ||
| 76 | <view class="t1 t3">处理中</view> | ||
| 77 | </view> | ||
| 78 | </view> | ||
| 79 | <view class="line"></view> | ||
| 80 | <view class="logistics"> | ||
| 81 | <view class="logistics-item"> | ||
| 82 | <view class="label">收货地址</view> | ||
| 83 | <view class="val">深圳市龙岗区XXX路</view> | ||
| 84 | </view> | ||
| 85 | <view class="logistics-item"> | ||
| 86 | <view class="label">物流公司</view> | ||
| 87 | <view class="val">待定</view> | ||
| 88 | </view> | ||
| 89 | <view class="logistics-item"> | ||
| 90 | <view class="label">物流单号</view> | ||
| 91 | <view class="val">暂定</view> | ||
| 92 | </view> | ||
| 93 | </view> | ||
| 94 | </view> --> | ||
| 95 | </view> | ||
| 32 | </view> | 96 | </view> |
| 33 | <empty-tips wx:if="{{dataList.length <= 0}}"></empty-tips> | 97 | <empty-tips wx:if="{{dataList.length <= 0}}"></empty-tips> |
| 34 | </view> | 98 | </view> | ... | ... |
| 1 | import QR from '../../utils/qrcode' | ||
| 2 | |||
| 1 | let app = getApp(); | 3 | let app = getApp(); |
| 2 | Page({ | 4 | Page({ |
| 3 | data: { | 5 | data: { |
| 4 | authorizeVisible: false, | 6 | authorizeVisible: false, |
| 7 | userInfo: {}, | ||
| 8 | qrImagePath: "", | ||
| 5 | }, | 9 | }, |
| 6 | onShareAppMessage() {}, | 10 | onShareAppMessage() {}, |
| 7 | showAuth() { | 11 | showAuth() { |
| ... | @@ -9,5 +13,73 @@ Page({ | ... | @@ -9,5 +13,73 @@ Page({ |
| 9 | authorizeVisible: true | 13 | authorizeVisible: true |
| 10 | }) | 14 | }) |
| 11 | }, | 15 | }, |
| 12 | onLoad(options) {} | 16 | onLoad(options) { |
| 17 | this.initData(); | ||
| 18 | }, | ||
| 19 | initData() { | ||
| 20 | this.queryMember().then((result) => { | ||
| 21 | }); | ||
| 22 | }, | ||
| 23 | /** | ||
| 24 | * 获取会员信息 | ||
| 25 | */ | ||
| 26 | queryMember() { | ||
| 27 | return new Promise((resolve, reject) => { | ||
| 28 | app.post({ | ||
| 29 | url: app.api.member, | ||
| 30 | data: {} | ||
| 31 | }).then((result) => { | ||
| 32 | this.setData({ | ||
| 33 | userInfo: result | ||
| 34 | }) | ||
| 35 | |||
| 36 | // 设置二维码 | ||
| 37 | let qrSize = this.setCanvasSize(440); | ||
| 38 | let codeContent = "xxx"; | ||
| 39 | this.createQrCode(codeContent, 'qrcanvas', qrSize.w, qrSize.h); | ||
| 40 | |||
| 41 | resolve(); | ||
| 42 | }) | ||
| 43 | }); | ||
| 44 | }, | ||
| 45 | |||
| 46 | createQrCode(content, canvasId, cavW, cavH) { | ||
| 47 | //调用插件中的draw方法,绘制二维码图片 | ||
| 48 | QR.api.draw(content, canvasId, cavW, cavH); | ||
| 49 | this.canvasToTempImage(canvasId); | ||
| 50 | }, | ||
| 51 | //获取临时缓存图片路径,存入data中 | ||
| 52 | canvasToTempImage(canvasId) { | ||
| 53 | let that = this; | ||
| 54 | wx.canvasToTempFilePath({ | ||
| 55 | canvasId, // 这里canvasId即之前创建的canvas-id | ||
| 56 | success: function (res) { | ||
| 57 | let tempFilePath = res.tempFilePath; | ||
| 58 | console.log(tempFilePath); | ||
| 59 | that.setData({ // 如果采用mpvue,即 this.imagePath = tempFilePath | ||
| 60 | qrImagePath: tempFilePath, | ||
| 61 | }); | ||
| 62 | }, | ||
| 63 | fail: function (res) { | ||
| 64 | console.log(res); | ||
| 65 | } | ||
| 66 | }); | ||
| 67 | }, | ||
| 68 | //适配不同屏幕大小的canvas | ||
| 69 | setCanvasSize(sz) { | ||
| 70 | var size = {}; | ||
| 71 | try { | ||
| 72 | var res = wx.getSystemInfoSync(); | ||
| 73 | var scale = 750 / sz; //不同屏幕下canvas的适配比例;设计稿是750宽 | ||
| 74 | var width = res.windowWidth / scale; | ||
| 75 | var height = width; //canvas画布为正方形 | ||
| 76 | size.w = width; | ||
| 77 | size.h = height; | ||
| 78 | } catch (e) { | ||
| 79 | // Do something when catch error | ||
| 80 | console.log("获取设备信息失败" + e); | ||
| 81 | } | ||
| 82 | return size; | ||
| 83 | }, | ||
| 84 | |||
| 13 | }) | 85 | }) | ... | ... |
| ... | @@ -5,9 +5,11 @@ | ... | @@ -5,9 +5,11 @@ |
| 5 | <view class="top-space"></view> | 5 | <view class="top-space"></view> |
| 6 | <view class="content"> | 6 | <view class="content"> |
| 7 | <view class="card"> | 7 | <view class="card"> |
| 8 | <image class="avatar" mode="widthFix" src="../../image/icon/icon-default-avatar.png" /> | 8 | <image class="avatar" mode="widthFix" src="{{userInfo.avatar}}" /> |
| 9 | <view class="nickname">昵称填充</view> | 9 | <view class="nickname">{{userInfo.nickname}}</view> |
| 10 | <image class="qrcode" mode="widthFix" src="../../image/icon/icon-default-qrcode.png" /> | 10 | <!-- <image class="qrcode" mode="widthFix" src="../../image/icon/icon-default-qrcode.png" /> --> |
| 11 | <image wx:if="{{qrImagePath}}" class="qrcode" mode="widthFix" src="{{qrImagePath}}" /> | ||
| 12 | <canvas wx:else class="qrcode" canvas-id="qrcanvas" /> | ||
| 11 | <view class="t1">深士照明</view> | 13 | <view class="t1">深士照明</view> |
| 12 | <view class="t1 t2">扫码即获专属积分,兑换超值奖品</view> | 14 | <view class="t1 t2">扫码即获专属积分,兑换超值奖品</view> |
| 13 | </view> | 15 | </view> | ... | ... |
| 1 | let Date = require('../../utils/date.js'); | ||
| 2 | |||
| 1 | let app = getApp(); | 3 | let app = getApp(); |
| 2 | Page({ | 4 | Page({ |
| 3 | data: { | 5 | data: { |
| 4 | authorizeVisible: false, | 6 | authorizeVisible: false, |
| 7 | dateStart: "", | ||
| 8 | dateEnd: "", | ||
| 9 | total: 0, | ||
| 10 | page: 1, | ||
| 11 | size: 10, | ||
| 12 | dataList: [], | ||
| 5 | }, | 13 | }, |
| 6 | onShareAppMessage() {}, | 14 | onShareAppMessage() {}, |
| 7 | showAuth() { | 15 | showAuth() { |
| ... | @@ -9,5 +17,73 @@ Page({ | ... | @@ -9,5 +17,73 @@ Page({ |
| 9 | authorizeVisible: true | 17 | authorizeVisible: true |
| 10 | }) | 18 | }) |
| 11 | }, | 19 | }, |
| 12 | onLoad(options) {} | 20 | onLoad(options) { |
| 21 | let dateStart = new Date().last().week().toString("yyyy-MM-dd"); | ||
| 22 | let dateEnd = Date.today().toString("yyyy-MM-dd"); | ||
| 23 | this.setData({ | ||
| 24 | dateStart, | ||
| 25 | dateEnd | ||
| 26 | }) | ||
| 27 | this.initData(); | ||
| 28 | }, | ||
| 29 | initData() { | ||
| 30 | this.querySginRecord(); | ||
| 31 | }, | ||
| 32 | // 到达底部 | ||
| 33 | onReachBottom() { | ||
| 34 | if (this.data.dataList.length < this.data.total) { | ||
| 35 | this.setData({ | ||
| 36 | page: this.data.page + 1 | ||
| 37 | }); | ||
| 38 | this.queryAnnouncementList(); | ||
| 39 | } | ||
| 40 | }, | ||
| 41 | // 重置页面列表 点击搜索条件时需要 | ||
| 42 | resetPage() { | ||
| 43 | this.setData({ | ||
| 44 | page: 1, | ||
| 45 | dataList: [] | ||
| 46 | }) | ||
| 47 | }, | ||
| 48 | /** | ||
| 49 | * 请求签到记录 | ||
| 50 | */ | ||
| 51 | querySginRecord() { | ||
| 52 | return new Promise((resolve, reject) => { | ||
| 53 | app.post({ | ||
| 54 | url: app.api.signRecord, | ||
| 55 | data: { | ||
| 56 | start: this.data.dateStart, | ||
| 57 | end: this.data.dateEnd, | ||
| 58 | page: this.data.page, | ||
| 59 | size: this.data.size, | ||
| 60 | } | ||
| 61 | }).then((result) => { | ||
| 62 | let dataList = result.list; | ||
| 63 | dataList = this.data.dataList.concat(dataList); | ||
| 64 | this.setData({ | ||
| 65 | dataList: dataList, | ||
| 66 | total: result.total | ||
| 67 | }) | ||
| 68 | resolve(); | ||
| 69 | }) | ||
| 70 | }); | ||
| 71 | }, | ||
| 72 | |||
| 73 | // 起始时间 | ||
| 74 | bindDateStartChange(e) { | ||
| 75 | this.setData({ | ||
| 76 | dateStart: e.detail.value | ||
| 77 | }) | ||
| 78 | this.resetPage(); | ||
| 79 | this.querySginRecord(); | ||
| 80 | }, | ||
| 81 | // 结束时间 | ||
| 82 | bindDateEndChange(e) { | ||
| 83 | this.setData({ | ||
| 84 | dateEnd: e.detail.value | ||
| 85 | }) | ||
| 86 | this.resetPage(); | ||
| 87 | this.querySginRecord(); | ||
| 88 | }, | ||
| 13 | }) | 89 | }) | ... | ... |
| ... | @@ -13,7 +13,7 @@ $contentWidth:690px; | ... | @@ -13,7 +13,7 @@ $contentWidth:690px; |
| 13 | color: #333333; | 13 | color: #333333; |
| 14 | 14 | ||
| 15 | .top-space { | 15 | .top-space { |
| 16 | height: 0px; | 16 | height: 20px; |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | .content { | 19 | .content { |
| ... | @@ -21,10 +21,12 @@ $contentWidth:690px; | ... | @@ -21,10 +21,12 @@ $contentWidth:690px; |
| 21 | width: 690px; | 21 | width: 690px; |
| 22 | margin: 0 auto; | 22 | margin: 0 auto; |
| 23 | 23 | ||
| 24 | .func-wrap{ | ||
| 25 | } | ||
| 24 | .func { | 26 | .func { |
| 25 | @extend .fcc; | 27 | @extend .fcc; |
| 26 | height: 80px; | 28 | height: 80px; |
| 27 | border-bottom: solid 1px #DDDDDD; | 29 | // border-bottom: solid 1px #DDDDDD; |
| 28 | font-size: 32px; | 30 | font-size: 32px; |
| 29 | color: #3680EB; | 31 | color: #3680EB; |
| 30 | 32 | ... | ... |
| ... | @@ -5,22 +5,36 @@ | ... | @@ -5,22 +5,36 @@ |
| 5 | <view class="app__content main"> | 5 | <view class="app__content main"> |
| 6 | <view class="top-space"></view> | 6 | <view class="top-space"></view> |
| 7 | <view class="content"> | 7 | <view class="content"> |
| 8 | <view class="func"> | 8 | <view class="func-wrap"> |
| 9 | <image class="icon" mode="aspectFit" src="../../image/icon/icon-sign-record.png" /> | 9 | <picker mode="date" value="{{dateStart}}" bindchange="bindDateStartChange"> |
| 10 | 时间筛选 | 10 | <view class="func"> |
| 11 | <image class="arrow" mode="aspectFit" src="../../image/icon/icon-filter-down-on.png" /> | 11 | <image class="icon" mode="aspectFit" src="../../image/icon/icon-sign-record.png" /> |
| 12 | 起始时间 | ||
| 13 | <image class="arrow" mode="aspectFit" src="../../image/icon/icon-filter-down-on.png" /> | ||
| 14 | {{dateStart}} | ||
| 15 | </view> | ||
| 16 | </picker> | ||
| 17 | <picker mode="date" value="{{dateEnd}}" bindchange="bindDateEndChange"> | ||
| 18 | <view class="func"> | ||
| 19 | <image class="icon" mode="aspectFit" src="../../image/icon/icon-sign-record.png" /> | ||
| 20 | 结束时间 | ||
| 21 | <image class="arrow" mode="aspectFit" src="../../image/icon/icon-filter-down-on.png" /> | ||
| 22 | {{dateEnd}} | ||
| 23 | </view> | ||
| 24 | </picker> | ||
| 12 | </view> | 25 | </view> |
| 13 | <view class="sign"> | 26 | <view class="sign"> |
| 14 | <view class="sign-item"> | 27 | <view wx:for="{{dataList}}" wx:key="{{index}}" class="sign-item"> |
| 15 | <view class="date">2019.03.13</view> | 28 | <view class="date">{{item.signTime}}</view> |
| 16 | <view class="desc"> | 29 | <view class="desc"> |
| 17 | 签到成功,获得 | 30 | 签到成功,获得 |
| 18 | <span class="green red">1</span> | 31 | <span class="green {{item.prizeType == 'packet' ? 'red':''}}">{{item.prizeSize}}</span> |
| 19 | 红包 | 32 | {{item.prizeType == 'packet' ? '元红包' : '积分' }} |
| 20 | </view> | 33 | </view> |
| 21 | </view> | 34 | </view> |
| 22 | </view> | 35 | </view> |
| 23 | </view> | 36 | </view> |
| 37 | <empty-tips wx:if="{{dataList.length <= 0}}"></empty-tips> | ||
| 24 | </view> | 38 | </view> |
| 25 | </view> | 39 | </view> |
| 26 | <van-popup show="{{ authorizeVisible }}"> | 40 | <van-popup show="{{ authorizeVisible }}"> | ... | ... |
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