| @@ -182,12 +182,18 @@ class TourGuideInfo(CreateUpdateMixin): | ||
| 182 | 182 | return unicode(self.pk) | 
| 183 | 183 |  | 
| 184 | 184 | @property | 
| 185 | + def photo_url(self): | |
| 186 | + return '' | |
| 187 | + | |
| 188 | + @property | |
| 185 | 189 | def data(self): | 
| 186 | 190 |          return { | 
| 187 | 191 | 'name': self.name, | 
| 188 | 192 | 'sex': self.sex, | 
| 189 | 193 | 'phone': self.phone, | 
| 190 | 194 | 'location': self.location, | 
| 195 | + 'no': self.no, | |
| 196 | + 'photo': self.photo_url, | |
| 191 | 197 | 'status': self.user_status, | 
| 192 | 198 | 'refused_reason': self.refused_reason, | 
| 193 | 199 | } | 
| @@ -21,6 +21,10 @@ def tourguide_submit_api(request): | ||
| 21 | 21 |      openid = request.POST.get('openid', '') | 
| 22 | 22 |      phone = request.POST.get('phone', '') | 
| 23 | 23 |  | 
| 24 | +    serverIds = request.POST.getlist('serverIds[]', []) | |
| 25 | + | |
| 26 | + # TODO: get tour guide photo from wx server | |
| 27 | + | |
| 24 | 28 | if TourGuideInfo.objects.filter(phone=phone).exclude(unionid=unionid).exists(): | 
| 25 | 29 | return response(TourGuideStatusCode.TOURGUIDE_PHONE_ALREADY_EXISTS) | 
| 26 | 30 |  | 
| @@ -18,6 +18,10 @@ | ||
| 18 | 18 |              input:required:valid { | 
| 19 | 19 | color: rgb(0, 0, 0); | 
| 20 | 20 | } | 
| 21 | +            #tour_guide_photo { | |
| 22 | + width: 60%; | |
| 23 | + margin-left: 20%; | |
| 24 | + } | |
| 21 | 25 | </style> | 
| 22 | 26 | </head> | 
| 23 | 27 | <body> | 
| @@ -57,6 +61,39 @@ | ||
| 57 | 61 |                          <input id="no" class="weui_input" type="text" required="required" value="{{ tourguide_info.no }}" placeholder="请输入导游证编号" {% if not modified %}disabled{% endif %}> | 
| 58 | 62 | </div> | 
| 59 | 63 | </div> | 
| 64 | + | |
| 65 | + <div class="weui_cell"> | |
| 66 | + <div class="weui_cell_bd weui_cell_primary"> | |
| 67 | + <div class="weui_uploader"> | |
| 68 | + <div class="weui_uploader_hd weui_cell"> | |
| 69 | + <div class="weui_cell_bd weui_cell_primary">导游证照片</div> | |
| 70 | +{#                            <div class="weui_cell_ft">0/2</div>#} | |
| 71 | + </div> | |
| 72 | + <div class="weui_uploader_bd"> | |
| 73 | +                            <img id="tour_guide_photo" src="{{ tourguide_info.photo_url }}"> | |
| 74 | +{#                            <ul class="weui_uploader_files">#} | |
| 75 | +{#                                <li class="weui_uploader_file" style="background-image:url(http://shp.qpic.cn/weixinsrc_pic/pScBR7sbqjOBJomcuvVJ6iacVrbMJaoJZkFUIq4nzQZUIqzTKziam7ibg/)"></li>#} | |
| 76 | +{#                                <li class="weui_uploader_file" style="background-image:url(http://shp.qpic.cn/weixinsrc_pic/pScBR7sbqjOBJomcuvVJ6iacVrbMJaoJZkFUIq4nzQZUIqzTKziam7ibg/)"></li>#} | |
| 77 | +{#                                <li class="weui_uploader_file" style="background-image:url(http://shp.qpic.cn/weixinsrc_pic/pScBR7sbqjOBJomcuvVJ6iacVrbMJaoJZkFUIq4nzQZUIqzTKziam7ibg/)"></li>#} | |
| 78 | +{#                                <li class="weui_uploader_file weui_uploader_status" style="background-image:url(http://shp.qpic.cn/weixinsrc_pic/pScBR7sbqjOBJomcuvVJ6iacVrbMJaoJZkFUIq4nzQZUIqzTKziam7ibg/)">#} | |
| 79 | +{#                                    <div class="weui_uploader_status_content">#} | |
| 80 | +{#                                        <i class="weui_icon_warn"></i>#} | |
| 81 | +{#                                    </div>#} | |
| 82 | +{#                                </li>#} | |
| 83 | +{#                                <li class="weui_uploader_file weui_uploader_status" style="background-image:url(http://shp.qpic.cn/weixinsrc_pic/pScBR7sbqjOBJomcuvVJ6iacVrbMJaoJZkFUIq4nzQZUIqzTKziam7ibg/)">#} | |
| 84 | +{#                                    <div class="weui_uploader_status_content">50%</div>#} | |
| 85 | +{#                                </li>#} | |
| 86 | +{#                            </ul>#} | |
| 87 | +                            {% if modified %} | |
| 88 | + <div class="weui_uploader_input_wrp"> | |
| 89 | +{#                                <input class="weui_uploader_input" type="file" accept="image/*" multiple="">#} | |
| 90 | + </div> | |
| 91 | +                            {% endif %} | |
| 92 | + </div> | |
| 93 | + </div> | |
| 94 | + </div> | |
| 95 | + </div> | |
| 96 | + | |
| 60 | 97 | </div> | 
| 61 | 98 |  | 
| 62 | 99 |              {% if tourguide_info %} | 
| @@ -113,7 +150,9 @@ | ||
| 113 | 150 | </div> | 
| 114 | 151 | </div> | 
| 115 | 152 |  | 
| 116 | - <script src="//cdn.bootcss.com/zepto/1.1.6/zepto.min.js"></script> | |
| 153 | + <script type="text/javascript" src="http://cdn.bootcss.com/zepto/1.1.6/zepto.min.js"></script> | |
| 154 | + <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> | |
| 155 | +        <script type="text/javascript" src="{% static 'pai2/js/jswe.js' %}?v=15"></script> | |
| 117 | 156 | <script> | 
| 118 | 157 |              {% if modified %} | 
| 119 | 158 |              $(function() { | 
| @@ -158,6 +197,18 @@ | ||
| 158 | 197 | return false; | 
| 159 | 198 | } | 
| 160 | 199 |  | 
| 200 | + var localIds = V.images.localIds; | |
| 201 | +                    if (localIds.length == 0) { | |
| 202 | +                        show_error_dialog('照片', '请上传导游证照片'); | |
| 203 | + return false; | |
| 204 | + } | |
| 205 | + | |
| 206 | + var serverIds = V.images.serverIds; | |
| 207 | +                    if (serverIds.length == 0) { | |
| 208 | +                        show_error_dialog('网络异常', '请稍后重试'); | |
| 209 | + return false; | |
| 210 | + } | |
| 211 | + | |
| 161 | 212 |                      return { | 
| 162 | 213 | unionid: unionid, | 
| 163 | 214 |                          openid: getURLParameter('openid'), | 
| @@ -166,6 +217,7 @@ | ||
| 166 | 217 |                          phone: $('#phone').val(), | 
| 167 | 218 |  {#                        location: location,#} | 
| 168 | 219 | no: no, | 
| 220 | + serverIds: serverIds, | |
| 169 | 221 | } | 
| 170 | 222 | } | 
| 171 | 223 |  | 
| @@ -193,13 +245,14 @@ | ||
| 193 | 245 |  | 
| 194 | 246 |                  $('#dialog .weui_btn_dialog').click(function () { | 
| 195 | 247 |                      $('#dialog').hide(); | 
| 196 | - }) | |
| 248 | + }); | |
| 197 | 249 | }); | 
| 198 | 250 |              {% endif %} | 
| 199 | 251 | </script> | 
| 200 | - <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> | |
| 201 | -        <script type="text/javascript" src="{% static 'pai2/js/jswe.js' %}?v=1"></script> | |
| 202 | 252 | <script> | 
| 253 | +            V.wxChooseImageSuccess = function (res) { | |
| 254 | +                $('#tour_guide_photo')[0].src = V.images.localIds[0]; | |
| 255 | + } | |
| 203 | 256 |              V.initWxData({ | 
| 204 | 257 | imgUrl: "http://pai.ai/static/pai2/img/paiai_96_96.png", | 
| 205 | 258 | link: 'http://api.pai.ai/wx_oauth2?redirect_url=http://pai.ai/page/tourguide&scope=snsapi_base', | 
| @@ -208,6 +261,9 @@ | ||
| 208 | 261 | timeLine: "" | 
| 209 | 262 | }, true); | 
| 210 | 263 | V.hideOptionMenu(); | 
| 264 | +            $('.weui_uploader_input_wrp').click(function () { | |
| 265 | + V.chooseImage(1, true); | |
| 266 | + }) | |
| 211 | 267 | </script> | 
| 212 | 268 | </body> | 
| 213 | 269 | </html> | 
| @@ -43,6 +43,7 @@ | ||
| 43 | 43 | 'closeWindow', | 
| 44 | 44 | 'scanQRCode', | 
| 45 | 45 | 'chooseWXPay', | 
| 46 | + 'openEnterpriseRedPacket', | |
| 46 | 47 | 'openProductSpecificView', | 
| 47 | 48 | 'addCard', | 
| 48 | 49 | 'chooseCard', | 
| @@ -100,19 +101,19 @@ | ||
| 100 | 101 |          var callbacks = { | 
| 101 | 102 |              trigger: function (res) { | 
| 102 | 103 |                  // alert('用户点击发送给朋友') | 
| 103 | -                if (JSWE.wxTrigger) {JSWE.wxTrigger()} | |
| 104 | +                if (JSWE.wxTrigger) {JSWE.wxTrigger(res)} | |
| 104 | 105 | }, | 
| 105 | 106 |              success: function (res) { | 
| 106 | 107 |                  // alert('已分享') | 
| 107 | -                if (JSWE.wxSuccess) {JSWE.wxSuccess()} | |
| 108 | +                if (JSWE.wxSuccess) {JSWE.wxSuccess(res)} | |
| 108 | 109 | }, | 
| 109 | 110 |              cancel: function (res) { | 
| 110 | 111 |                  // alert('已取消') | 
| 111 | -                if (JSWE.wxCancel) {JSWE.wxCancel()} | |
| 112 | +                if (JSWE.wxCancel) {JSWE.wxCancel(res)} | |
| 112 | 113 | }, | 
| 113 | 114 |              fail: function (res) { | 
| 114 | 115 | // alert(JSON.stringify(res)) | 
| 115 | -                if (JSWE.wxFail) {JSWE.wxFail()} | |
| 116 | +                if (JSWE.wxFail) {JSWE.wxFail(res)} | |
| 116 | 117 | } | 
| 117 | 118 |          }, shareInfo = function(flag) { | 
| 118 | 119 |              var _share = { | 
| @@ -126,7 +127,7 @@ | ||
| 126 | 127 | } | 
| 127 | 128 | if (flag) _share.desc = wxData.desc | 
| 128 | 129 | return _share | 
| 129 | -        }, wxApi = function() { | |
| 130 | +        }, wxShareApi = function() { | |
| 130 | 131 | // 2. 分享接口 | 
| 131 | 132 | // 2.1 监听“分享给朋友”,按钮点击、自定义分享内容及分享结果接口 | 
| 132 | 133 | wx.onMenuShareAppMessage(shareInfo(1)) | 
| @@ -136,12 +137,16 @@ | ||
| 136 | 137 | wx.onMenuShareQQ(shareInfo(1)) | 
| 137 | 138 | // 2.4 监听“分享到微博”按钮点击、自定义分享内容及分享结果接口 | 
| 138 | 139 | wx.onMenuShareWeibo(shareInfo(1)) | 
| 139 | - // 8 界面操作接口 | |
| 140 | +        }, wxMenuApi = function () { | |
| 141 | + // 8. 界面操作接口 | |
| 140 | 142 | // 8.1 隐藏右上角菜单 | 
| 141 | 143 | // 8.2 显示右上角菜单 | 
| 142 | 144 |              if (wxConfig.hide) {wx.hideOptionMenu()} else {wx.showOptionMenu()} | 
| 143 | 145 | // 8.7 关闭当前窗口 | 
| 144 | 146 |              if (wxConfig.close) {wx.closeWindow()} | 
| 147 | +        }, wxApi = function () { | |
| 148 | + wxShareApi() | |
| 149 | + wxMenuApi() | |
| 145 | 150 | } | 
| 146 | 151 |  | 
| 147 | 152 | wx.ready(wxApi) | 
| @@ -177,6 +182,85 @@ | ||
| 177 | 182 |          if ('undefined' !== typeof wxApiFun) wxApiFun() | 
| 178 | 183 | } | 
| 179 | 184 |  | 
| 185 | + // 5 图片接口 | |
| 186 | + // 5.1 拍照、本地选图 | |
| 187 | +    var images = { | |
| 188 | + localIds: [], | |
| 189 | + serverIds: [] | |
| 190 | + }; | |
| 191 | +    function chooseImage(count, directUpload, isShowProgressTips) { | |
| 192 | +        if ('undefined' === typeof count) {count = 9} | |
| 193 | +        if ('undefined' === typeof directUpload) {directUpload = false} | |
| 194 | +        if ('undefined' === typeof isShowProgressTips) {isShowProgressTips = 1} | |
| 195 | +        wx.chooseImage({ | |
| 196 | + count: count, // 默认9 | |
| 197 | + sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有 | |
| 198 | + sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有 | |
| 199 | +            success: function (res) { | |
| 200 | + var localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片 | |
| 201 | + images.localIds = localIds; | |
| 202 | + // 判断是否直接上传 | |
| 203 | +                if (directUpload) {setTimeout(uploadImages(localIds, isShowProgressTips), 100)} | |
| 204 | + // 拍照、本地选图成功后的回调函数 | |
| 205 | +                if (JSWE.wxChooseImageSuccess) {JSWE.wxChooseImageSuccess(res)} | |
| 206 | + } | |
| 207 | + }); | |
| 208 | + } | |
| 209 | + | |
| 210 | + // 5.3 上传图片 | |
| 211 | +    function uploadImage(localId, isShowProgressTips) { | |
| 212 | + // 上传图片为异步处理,重复上传同一图片,返回的serverId也是不同的 | |
| 213 | +        wx.uploadImage({ | |
| 214 | + localId: localId, // 需要上传的图片的本地ID,由chooseImage接口获得 | |
| 215 | + isShowProgressTips: 1, // 默认为1,显示进度提示 | |
| 216 | +            success: function (res) { | |
| 217 | + var serverId = res.serverId; // 返回图片的服务器端ID | |
| 218 | + images.serverIds.push(serverId); | |
| 219 | + // 上传图片成功后的回调函数 | |
| 220 | +                if (JSWE.wxUploadImageSuccess) {JSWE.wxUploadImageSuccess(res)} | |
| 221 | + } | |
| 222 | + }); | |
| 223 | + } | |
| 224 | + | |
| 225 | +    function uploadImages(localIds, isShowProgressTips) { | |
| 226 | +        if ('undefined' === typeof localIds) {localIds = images.localIds} | |
| 227 | +        if ('undefined' === typeof isShowProgressTips) {isShowProgressTips = 1} | |
| 228 | + images.serverIds = []; | |
| 229 | +        for (var index in localIds) {uploadImage(localIds[index], isShowProgressTips)} | |
| 230 | + } | |
| 231 | + | |
| 232 | + // 10 微信支付接口 | |
| 233 | + // 10.1 发起一个支付请求 | |
| 234 | +    function chooseWXPay(wxpay_params) { | |
| 235 | +        wx.chooseWXPay({ | |
| 236 | + timestamp: wxpay_params.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符 | |
| 237 | + nonceStr: wxpay_params.nonceStr, // 支付签名随机串,不长于 32 位 | |
| 238 | + package: wxpay_params.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***) | |
| 239 | + signType: wxpay_params.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5' | |
| 240 | + paySign: wxpay_params.paySign, // 支付签名 | |
| 241 | +            success: function (res) { | |
| 242 | + // 支付成功后的回调函数 | |
| 243 | +                if (JSWE.wxPaySuccess) {JSWE.wxPaySuccess(res)} | |
| 244 | + } | |
| 245 | + }) | |
| 246 | + } | |
| 247 | + | |
| 248 | + // xx 微信原生企业红包接口 | |
| 249 | + // xx.1 发起一个发送原生企业红包请求 | |
| 250 | +    function openEnterpriseRedPacket(wxredpack_params) { | |
| 251 | +        wx.openEnterpriseRedPacket({ | |
| 252 | + timeStamp: wxredpack_params.timeStamp, // 红包签名时间戳,注意原生企业红包接口timeStamp字段名需大写其中的S字符,而支付接口timeStamp字段名无需大写其中的S字符。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符 | |
| 253 | + nonceStr: wxredpack_params.nonceStr, // 红包签名随机串,不长于 32 位 | |
| 254 | + package: encodeURIComponent(wxredpack_params.package), // 发放红包接口返回的prepay_id参数值,提交格式如:prepay_id=***) | |
| 255 | + signType: wxredpack_params.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5' | |
| 256 | + paySign: wxredpack_params.paySign, // 红包签名 | |
| 257 | +            success: function (res) { | |
| 258 | + // 发送原生企业红包成功后的回调函数 | |
| 259 | +                if (JSWE.wxEnterpriseRedPacketSuccess) {JSWE.wxEnterpriseRedPacketSuccess(res)} | |
| 260 | + } | |
| 261 | + }) | |
| 262 | + } | |
| 263 | + | |
| 180 | 264 |      var v = { | 
| 181 | 265 | version: '1.0.5', | 
| 182 | 266 |  | 
| @@ -198,7 +282,19 @@ | ||
| 198 | 282 | // Share Function | 
| 199 | 283 | initWxData: initWxData, | 
| 200 | 284 | changeWxData: changeWxData, | 
| 201 | - fixedWxData: fixedWxData | |
| 285 | + fixedWxData: fixedWxData, | |
| 286 | + | |
| 287 | + // Image Function | |
| 288 | + images: images, | |
| 289 | + chooseImage: chooseImage, | |
| 290 | + uploadImage: uploadImage, | |
| 291 | + uploadImages: uploadImages, | |
| 292 | + | |
| 293 | + // Pay Function | |
| 294 | + chooseWXPay: chooseWXPay, | |
| 295 | + | |
| 296 | + // EnterpriseRedPacket Function | |
| 297 | + openEnterpriseRedPacket: openEnterpriseRedPacket | |
| 202 | 298 | } | 
| 203 | 299 | e.JSWE = e.V = v | 
| 204 | -})(window) | |
| 300 | +})(window) |