├── README.md ├── app.js ├── app.json ├── app.wxss ├── images ├── aithinker-mini.png ├── bluetooth.png └── mini_nodemcu.png ├── pages └── index │ ├── index.js │ ├── index.json │ ├── index.wxml │ └── index.wxss ├── project.config.json ├── sitemap.json ├── utils ├── .DS_Store ├── mqtt.min.js └── util.js └── weui.wxss /README.md: -------------------------------------------------------------------------------- 1 | - 安信可微信小程序控制 NodeMCU 模组的方案 微信小程序源码; 2 | 3 |

4 | Banner 5 |

6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | //app.js 2 | App({ 3 | onLaunch: function () { 4 | // 展示本地存储能力 5 | var logs = wx.getStorageSync('logs') || [] 6 | logs.unshift(Date.now()) 7 | wx.setStorageSync('logs', logs) 8 | 9 | // 登录 10 | wx.login({ 11 | success: res => { 12 | // 发送 res.code 到后台换取 openId, sessionKey, unionId 13 | } 14 | }) 15 | // 获取用户信息 16 | wx.getSetting({ 17 | success: res => { 18 | if (res.authSetting['scope.userInfo']) { 19 | // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 20 | wx.getUserInfo({ 21 | success: res => { 22 | // 可以将 res 发送给后台解码出 unionId 23 | this.globalData.userInfo = res.userInfo 24 | 25 | // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 26 | // 所以此处加入 callback 以防止这种情况 27 | if (this.userInfoReadyCallback) { 28 | this.userInfoReadyCallback(res) 29 | } 30 | } 31 | }) 32 | } 33 | } 34 | }) 35 | }, 36 | globalData: { 37 | userInfo: null 38 | } 39 | }) -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages":[ 3 | "pages/index/index" 4 | ], 5 | "window":{ 6 | "backgroundTextStyle":"light", 7 | "navigationBarBackgroundColor": "#fff", 8 | "navigationBarTitleText": "微信七彩控制安信可NodeMCU", 9 | "navigationBarTextStyle":"black" 10 | }, 11 | "style": "v2", 12 | "sitemapLocation": "sitemap.json" 13 | } 14 | -------------------------------------------------------------------------------- /app.wxss: -------------------------------------------------------------------------------- 1 | @import "weui.wxss" -------------------------------------------------------------------------------- /images/aithinker-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ai-Thinker-Open/WCMiniColorControl/f82a701d21c51806686d3af7507d7fe8ce1bce8c/images/aithinker-mini.png -------------------------------------------------------------------------------- /images/bluetooth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ai-Thinker-Open/WCMiniColorControl/f82a701d21c51806686d3af7507d7fe8ce1bce8c/images/bluetooth.png -------------------------------------------------------------------------------- /images/mini_nodemcu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ai-Thinker-Open/WCMiniColorControl/f82a701d21c51806686d3af7507d7fe8ce1bce8c/images/mini_nodemcu.png -------------------------------------------------------------------------------- /pages/index/index.js: -------------------------------------------------------------------------------- 1 | //index.js 2 | //获取应用实例 3 | const app = getApp() 4 | const util = require('../../utils/util.js') 5 | //引进我们的 mqtt 库 6 | const mqtt = require('../../utils/mqtt.min.js') 7 | //连接mqtt 的域名,我提供的这个库的域名入参参数是 以 wxs 开头 还支持阿里小程序,后缀的 /mqtt 表示是一种服务 8 | // 域名 a0je61a.mqtt.iot.gz.baidubce.com 9 | const host = 'wxs://a0je61a.mqtt.iot.gz.baidubce.com/mqtt' 10 | 11 | let colorPickerCtx = {}; 12 | let sliderCtx = {}; 13 | let _this = null 14 | Page({ 15 | data: { 16 | pickColor: null, 17 | raduis: 550, //这里最大为750rpx铺满屏幕 18 | valueWidthOrHerght: 0, 19 | client: null, 20 | //记录重连的次数 21 | reconnectCounts: 0, 22 | //MQTT连接的配置 23 | options: { 24 | protocolVersion: 4, //MQTT连接协议版本 25 | clientId: 'miniTest', 26 | clean: false, 27 | password: 'OHiLItaGMsEx0cwh', 28 | username: 'a0je61a/wechat', 29 | reconnectPeriod: 1000, //1000毫秒,两次重新连接之间的间隔 30 | connectTimeout: 30 * 1000, //1000毫秒,两次重新连接之间的间隔 31 | resubscribe: true //如果连接断开并重新连接,则会再次自动订阅已订阅的主题(默认true) 32 | } 33 | }, 34 | mqttConnect: function() { 35 | 36 | var that = this; 37 | //开始连接 38 | this.data.client = mqtt.connect(host, this.data.options); 39 | this.data.client.on('connect', function(connack) { 40 | wx.showToast({ 41 | title: '连接成功' 42 | }) 43 | 44 | that.onClickSync() 45 | }) 46 | 47 | 48 | //设备端上报消息的回调 49 | that.data.client.on("message", function(topic, payload) { 50 | let data = JSON.parse(payload) 51 | 52 | let h = util.rgb2hsl(data.Red, data.Green, data.Blue); 53 | util.drawSlider(sliderCtx, _this.data.valueWidthOrHerght, that.data.valueWidthOrHerght, h[0]); 54 | that.setData({ 55 | pickColor: JSON.stringify({ 56 | red: data.Red, 57 | green: data.Green, 58 | blue: data.Blue 59 | }) 60 | }) 61 | }) 62 | 63 | 64 | //服务器连接异常的回调 65 | that.data.client.on("error", function(error) { 66 | console.log(" 服务器 error 的回调" + error) 67 | 68 | }) 69 | 70 | //服务器重连连接异常的回调 71 | that.data.client.on("reconnect", function() { 72 | console.log(" 服务器 reconnect的回调") 73 | 74 | }) 75 | 76 | 77 | //服务器连接异常的回调 78 | that.data.client.on("offline", function(errr) { 79 | console.log(" 服务器offline的回调") 80 | 81 | }) 82 | 83 | 84 | }, 85 | mqttSubTopic: function() { 86 | if (this.data.client && this.data.client.connected) { 87 | //仅订阅单个主题 88 | this.data.client.subscribe('/light/deviceOut', function(err, granted) { 89 | if (!err) { 90 | wx.showToast({ 91 | title: '订阅主题成功' 92 | }) 93 | } else { 94 | wx.showToast({ 95 | title: '订阅主题失败', 96 | icon: 'fail', 97 | duration: 2000 98 | }) 99 | } 100 | }) 101 | } else { 102 | wx.showToast({ 103 | title: '请先连接服务器', 104 | icon: 'none', 105 | duration: 2000 106 | }) 107 | } 108 | }, 109 | onLoad: function() { 110 | _this = this 111 | this.mqttConnect() 112 | colorPickerCtx = wx.createCanvasContext('colorPicker'); 113 | colorPickerCtx.fillStyle = 'rgb(255, 255, 255)'; 114 | sliderCtx = wx.createCanvasContext('colorPickerSlider'); 115 | 116 | let isInit = true; 117 | wx.createSelectorQuery().select('#colorPicker').boundingClientRect(function(rect) { 118 | _this.setData({ 119 | valueWidthOrHerght: rect.width, 120 | }) 121 | if(isInit){ 122 | colorPickerCtx.fillRect(0, 0, rect.width, rect.height); 123 | util.drawRing(colorPickerCtx, rect.width, rect.height); 124 | // 设置默认位置 125 | util.drawSlider(sliderCtx, rect.width, rect.height, 1.0); 126 | isInit = false; 127 | } 128 | 129 | _this.setData({ 130 | pickColor: JSON.stringify({ 131 | red: 255, 132 | green: 0, 133 | blue: 0 134 | }) 135 | }) 136 | }).exec(); 137 | }, 138 | mqttPubMsg: function(payload) { 139 | if (this.data.client && this.data.client.connected) { 140 | this.data.client.publish('/light/deviceIn', payload); 141 | } else { 142 | wx.showToast({ 143 | title: '请先连接服务器', 144 | icon: 'none', 145 | duration: 2000 146 | }) 147 | } 148 | }, 149 | 150 | onClickRedColor: function() { 151 | 152 | let obj = { 153 | "change": "pwm", 154 | "value": [255, 0, 0] 155 | } 156 | this.mqttPubMsg(JSON.stringify(obj)) 157 | let h = util.rgb2hsl(255, 0, 0); 158 | util.drawSlider(sliderCtx, _this.data.valueWidthOrHerght, _this.data.valueWidthOrHerght, h[0]); 159 | this.setData({ 160 | pickColor: JSON.stringify({ 161 | red: 255, 162 | green: 0, 163 | blue: 0 164 | }) 165 | }) 166 | }, 167 | 168 | onClickGreenColor: function() { 169 | let obj = { 170 | "change": "pwm", 171 | "value": [0, 255, 0] 172 | } 173 | this.mqttPubMsg(JSON.stringify(obj)) 174 | 175 | let h = util.rgb2hsl(0, 255, 0); 176 | util.drawSlider(sliderCtx, _this.data.valueWidthOrHerght, _this.data.valueWidthOrHerght, h[0]); 177 | this.setData({ 178 | pickColor: JSON.stringify({ 179 | red: 0, 180 | green: 255, 181 | blue: 0 182 | }) 183 | }) 184 | }, 185 | 186 | onClickBlueColor: function() { 187 | let obj = { 188 | "change": "pwm", 189 | "value": [0, 0, 255] 190 | } 191 | this.mqttPubMsg(JSON.stringify(obj)) 192 | 193 | let h = util.rgb2hsl(0, 0, 255); 194 | util.drawSlider(sliderCtx, _this.data.valueWidthOrHerght, _this.data.valueWidthOrHerght, h[0]); 195 | this.setData({ 196 | pickColor: JSON.stringify({ 197 | red: 0, 198 | green: 0, 199 | blue: 255 200 | }) 201 | }) 202 | }, 203 | onClickOpen:function(){ 204 | let obj = { 205 | "change": "power", 206 | "value": "true" 207 | } 208 | this.mqttPubMsg(JSON.stringify(obj)) 209 | }, 210 | onClickOff:function(){ 211 | let obj = { 212 | "change": "power", 213 | "value": "false" 214 | } 215 | this.mqttPubMsg(JSON.stringify(obj)) 216 | }, 217 | onClickSync:function(){ 218 | let obj = { 219 | "change": "query", 220 | "value": "false" 221 | } 222 | this.mqttPubMsg(JSON.stringify(obj)) 223 | }, 224 | onSlide: function(e) { 225 | let that = this; 226 | if (e.touches && ( e.type === 'touchend')) { 227 | console.log("ok"); 228 | let x = e.changedTouches[0].x; 229 | let y = e.changedTouches[0].y; 230 | if (e.type !== 'touchend') { 231 | x = e.touches[0].x; 232 | y = e.touches[0].y; 233 | } 234 | //复制画布上指定矩形的像素数据 235 | wx.canvasGetImageData({ 236 | canvasId: "colorPicker", 237 | x: x, 238 | y: y, 239 | width: 1, 240 | height: 1, 241 | success(res) { 242 | 243 | 244 | // 转换成hsl格式,获取旋转角度 245 | let h = util.rgb2hsl(res.data[0], res.data[1], res.data[2]); 246 | that.setData({ 247 | pickColor: JSON.stringify({ 248 | red: res.data[0], 249 | green: res.data[1], 250 | blue: res.data[2] 251 | }) 252 | }) 253 | // 判断是否在圈内 254 | if (h[1] !== 1.0) { 255 | return; 256 | } 257 | let obj = { 258 | "change": "pwm", 259 | "value": [res.data[0], res.data[1], res.data[2]] 260 | } 261 | that.mqttPubMsg(JSON.stringify(obj)) 262 | 263 | 264 | util.drawSlider(sliderCtx, _this.data.valueWidthOrHerght, _this.data.valueWidthOrHerght, h[0]); 265 | // 设置设备 266 | if (e.type !== 'touchEnd') { 267 | // 触摸结束才设置设备属性 268 | return; 269 | } 270 | } 271 | }); 272 | } 273 | } 274 | }) 275 | -------------------------------------------------------------------------------- /pages/index/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": { 3 | } 4 | } -------------------------------------------------------------------------------- /pages/index/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 采集结果:{{pickColor}} 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | Copyright ©半颗心脏 https://github.com/xuhongv 17 | 18 | -------------------------------------------------------------------------------- /pages/index/index.wxss: -------------------------------------------------------------------------------- 1 | .color-picker-view { 2 | background-color: #fff; 3 | display: flex; 4 | justify-content: center; 5 | } 6 | 7 | 8 | .color-picker-slider { 9 | position: absolute; 10 | background-color: #fff; 11 | } -------------------------------------------------------------------------------- /project.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "项目配置文件", 3 | "packOptions": { 4 | "ignore": [] 5 | }, 6 | "setting": { 7 | "urlCheck": false, 8 | "es6": true, 9 | "postcss": true, 10 | "preloadBackgroundData": false, 11 | "minified": true, 12 | "newFeature": true, 13 | "coverView": true, 14 | "autoAudits": false, 15 | "showShadowRootInWxmlPanel": true, 16 | "scopeDataCheck": false, 17 | "checkInvalidKey": true, 18 | "checkSiteMap": true, 19 | "uploadWithSourceMap": true, 20 | "babelSetting": { 21 | "ignore": [], 22 | "disablePlugins": [], 23 | "outputPath": "" 24 | } 25 | }, 26 | "compileType": "miniprogram", 27 | "libVersion": "2.11.1", 28 | "appid": "wx610ea582556c983e", 29 | "projectname": "BaiduMini", 30 | "debugOptions": { 31 | "hidedInDevtools": [] 32 | }, 33 | "isGameTourist": false, 34 | "simulatorType": "wechat", 35 | "simulatorPluginLibVersion": {}, 36 | "condition": { 37 | "search": { 38 | "current": -1, 39 | "list": [] 40 | }, 41 | "conversation": { 42 | "current": -1, 43 | "list": [] 44 | }, 45 | "game": { 46 | "currentL": -1, 47 | "list": [] 48 | }, 49 | "miniprogram": { 50 | "current": -1, 51 | "list": [] 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /sitemap.json: -------------------------------------------------------------------------------- 1 | { 2 | "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html", 3 | "rules": [{ 4 | "action": "allow", 5 | "page": "*" 6 | }] 7 | } -------------------------------------------------------------------------------- /utils/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ai-Thinker-Open/WCMiniColorControl/f82a701d21c51806686d3af7507d7fe8ce1bce8c/utils/.DS_Store -------------------------------------------------------------------------------- /utils/util.js: -------------------------------------------------------------------------------- 1 | let rgb2hsl = function(r, g, b) { 2 | r /= 255, g /= 255, b /= 255; 3 | var max = Math.max(r, g, b), 4 | min = Math.min(r, g, b); 5 | var h, s, l = (max + min) / 2; 6 | 7 | if (max == min) { 8 | h = s = 0; // achromatic 9 | } else { 10 | var d = max - min; 11 | s = l > 0.5 ? d / (2 - max - min) : d / (max + min); 12 | switch (max) { 13 | case r: 14 | h = (g - b) / d + (g < b ? 6 : 0); 15 | break; 16 | case g: 17 | h = (b - r) / d + 2; 18 | break; 19 | case b: 20 | h = (r - g) / d + 4; 21 | break; 22 | } 23 | h /= 6; 24 | } 25 | return [h, s, l]; 26 | } 27 | 28 | let hslToRgb = function(h, s, l) { 29 | var r, g, b; 30 | if (s == 0) { 31 | r = g = b = l; // achromatic 32 | } else { 33 | var hue2rgb = function hue2rgb(p, q, t) { 34 | if (t < 0) t += 1; 35 | if (t > 1) t -= 1; 36 | if (t < 1 / 6) return p + (q - p) * 6 * t; 37 | if (t < 1 / 2) return q; 38 | if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; 39 | return p; 40 | } 41 | var q = l < 0.5 ? l * (1 + s) : l + s - l * s; 42 | var p = 2 * l - q; 43 | r = hue2rgb(p, q, h + 1 / 3); 44 | g = hue2rgb(p, q, h); 45 | b = hue2rgb(p, q, h - 1 / 3); 46 | } 47 | return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; 48 | } 49 | 50 | let drawRing = function(ctx, width, height) { 51 | // 画圆环 52 | var radius = width / 2; 53 | var toRad = (2 * Math.PI) / 360; 54 | var step = 0.1; 55 | for (var i = 0; i < 360; i += step) { 56 | var rad = i * toRad; 57 | var color = hslToRgb(i / 360, 1, 0.5); 58 | ctx.strokeStyle = `rgb(${color[0]},${color[1]},${color[2]})`; 59 | ctx.beginPath(); 60 | ctx.moveTo(radius, radius); 61 | ctx.lineTo(radius + radius * Math.cos(rad), radius + radius * Math.sin(rad)); 62 | ctx.stroke(); 63 | } 64 | 65 | ctx.fillStyle = 'rgb(255, 255, 255)'; 66 | ctx.strokeStyle = 'rgb(0, 255, 255)'; 67 | ctx.beginPath(); 68 | ctx.arc(radius, radius, radius * 0.65, 0, Math.PI * 2, true); 69 | ctx.closePath(); 70 | ctx.fill(); 71 | ctx.draw(); 72 | }; 73 | 74 | let drawSlider = function(ctx, width, height, angle) { 75 | var radius = width / 2; 76 | 77 | ctx.save(); 78 | ctx.clearRect(0, 0, width, height); 79 | ctx.translate(width / 2, height / 2); 80 | 81 | var color = hslToRgb(angle, 1, 0.5); 82 | 83 | ctx.fillStyle = `rgb(${color[0]},${color[1]},${color[2]})`; 84 | ctx.beginPath(); 85 | ctx.arc(0, 0, radius * 0.3, 0, Math.PI * 2, true); 86 | ctx.closePath(); 87 | ctx.fill(); 88 | ctx.rotate((angle * 360) * Math.PI / 180); 89 | 90 | ctx.beginPath() 91 | ctx.setLineWidth(height * 0.015); 92 | //圆心的 x 坐标 , 圆心的 Y 坐标 , 圆的半径 93 | ctx.arc(height * 0.41, 0, 17, 0, 2 * Math.PI) 94 | ctx.strokeStyle = 'rgb(255, 255, 255)'; 95 | ctx.stroke() 96 | 97 | ctx.draw(); 98 | ctx.restore(); 99 | }; 100 | 101 | 102 | module.exports = { 103 | rgb2hsl: rgb2hsl, 104 | hslToRgb: hslToRgb, 105 | drawRing: drawRing, 106 | drawSlider: drawSlider, 107 | } -------------------------------------------------------------------------------- /weui.wxss: -------------------------------------------------------------------------------- 1 | /*! 2 | * WeUI v1.1.1 (https://github.com/weui/weui-wxss) 3 | * Copyright 2017 Tencent, Inc. 4 | * Licensed under the MIT license 5 | */ 6 | page{line-height:1.6;font-family:-apple-system-font,Helvetica Neue,sans-serif}icon{vertical-align:middle}.weui-cells{position:relative;margin-top:1.17647059em;background-color:#fff;line-height:1.41176471;font-size:17px}.weui-cells:before{top:0;border-top:1rpx solid #d9d9d9}.weui-cells:after,.weui-cells:before{content:" ";position:absolute;left:0;right:0;height:1px;color:#d9d9d9}.weui-cells:after{bottom:0;border-bottom:1rpx solid #d9d9d9}.weui-cells__title{margin-top:.77em;margin-bottom:.3em;padding-left:15px;padding-right:15px;color:#999;font-size:14px}.weui-cells_after-title{margin-top:0}.weui-cells__tips{margin-top:.3em;color:#999;padding-left:15px;padding-right:15px;font-size:14px}.weui-cell{padding:10px 15px;position:relative;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.weui-cell:before{content:" ";position:absolute;left:0;top:0;right:0;height:1px;border-top:1rpx solid #d9d9d9;color:#d9d9d9;left:15px}.weui-cell:first-child:before{display:none}.weui-cell_active{background-color:#ececec}.weui-cell_primary{-webkit-box-align:start;-webkit-align-items:flex-start;align-items:flex-start}.weui-cell__bd{-webkit-box-flex:1;-webkit-flex:1;flex:1}.weui-cell__ft{text-align:right;color:#999}.weui-cell_access{color:inherit}.weui-cell__ft_in-access{padding-right:13px;position:relative}.weui-cell__ft_in-access:after{content:" ";display:inline-block;height:6px;width:6px;border-width:2px 2px 0 0;border-color:#c8c8cd;border-style:solid;-webkit-transform:matrix(.71,.71,-.71,.71,0,0);transform:matrix(.71,.71,-.71,.71,0,0);position:relative;top:-2px;position:absolute;top:50%;margin-top:-4px;right:2px}.weui-cell_link{color:#586c94;font-size:14px}.weui-cell_link:active{background-color:#ececec}.weui-cell_link:first-child:before{display:block}.weui-icon-radio{margin-left:3.2px;margin-right:3.2px}.weui-icon-checkbox_circle,.weui-icon-checkbox_success{margin-left:4.6px;margin-right:4.6px}.weui-check__label:active{background-color:#ececec}.weui-check{position:absolute;left:-9999px}.weui-check__hd_in-checkbox{padding-right:.35em}.weui-cell__ft_in-radio{padding-left:.35em}.weui-cell_input{padding-top:0;padding-bottom:0}.weui-label{width:105px;word-wrap:break-word;word-break:break-all}.weui-input{height:2.58823529em;min-height:2.58823529em;line-height:2.58823529em}.weui-toptips{position:fixed;-webkit-transform:translateZ(0);transform:translateZ(0);top:0;left:0;right:0;padding:5px;font-size:14px;text-align:center;color:#fff;z-index:5000;word-wrap:break-word;word-break:break-all}.weui-toptips_warn{background-color:#e64340}.weui-textarea{display:block;width:100%}.weui-textarea-counter{color:#b2b2b2;text-align:right}.weui-cell_warn,.weui-textarea-counter_warn{color:#e64340}.weui-form-preview{position:relative;background-color:#fff}.weui-form-preview:before{top:0;border-top:1rpx solid #d9d9d9}.weui-form-preview:after,.weui-form-preview:before{content:" ";position:absolute;left:0;right:0;height:1px;color:#d9d9d9}.weui-form-preview:after{bottom:0;border-bottom:1rpx solid #d9d9d9}.weui-form-preview__value{font-size:14px}.weui-form-preview__value_in-hd{font-size:26px}.weui-form-preview__hd{position:relative;padding:10px 15px;text-align:right;line-height:2.5em}.weui-form-preview__hd:after{content:" ";position:absolute;left:0;bottom:0;right:0;height:1px;border-bottom:1rpx solid #d9d9d9;color:#d9d9d9;left:15px}.weui-form-preview__bd{padding:10px 15px;font-size:.9em;text-align:right;color:#999;line-height:2}.weui-form-preview__ft{position:relative;line-height:50px;display:-webkit-box;display:-webkit-flex;display:flex}.weui-form-preview__ft:after{content:" ";position:absolute;left:0;top:0;right:0;height:1px;border-top:1rpx solid #d5d5d6;color:#d5d5d6}.weui-form-preview__item{overflow:hidden}.weui-form-preview__label{float:left;margin-right:1em;min-width:4em;color:#999;text-align:justify;text-align-last:justify}.weui-form-preview__value{display:block;overflow:hidden;word-break:normal;word-wrap:break-word}.weui-form-preview__btn{position:relative;display:block;-webkit-box-flex:1;-webkit-flex:1;flex:1;color:#3cc51f;text-align:center}.weui-form-preview__btn:after{content:" ";position:absolute;left:0;top:0;width:1px;bottom:0;border-left:1rpx solid #d5d5d6;color:#d5d5d6}.weui-form-preview__btn:first-child:after{display:none}.weui-form-preview__btn_active{background-color:#eee}.weui-form-preview__btn_default{color:#999}.weui-form-preview__btn_primary{color:#0bb20c}.weui-cell_select{padding:0}.weui-select{position:relative;padding-left:15px;padding-right:30px;height:2.58823529em;min-height:2.58823529em;line-height:2.58823529em;border-right:1rpx solid #d9d9d9}.weui-select:before{content:" ";display:inline-block;height:6px;width:6px;border-width:2px 2px 0 0;border-color:#c8c8cd;border-style:solid;-webkit-transform:matrix(.71,.71,-.71,.71,0,0);transform:matrix(.71,.71,-.71,.71,0,0);position:relative;top:-2px;position:absolute;top:50%;right:15px;margin-top:-4px}.weui-select_in-select-after{padding-left:0}.weui-cell__bd_in-select-before,.weui-cell__hd_in-select-after{padding-left:15px}.weui-cell_vcode{padding-right:0}.weui-vcode-btn,.weui-vcode-img{margin-left:5px;height:2.58823529em;vertical-align:middle}.weui-vcode-btn{display:inline-block;padding:0 .6em 0 .7em;border-left:1px solid #e5e5e5;line-height:2.58823529em;font-size:17px;color:#3cc51f;white-space:nowrap}.weui-vcode-btn:active{color:#52a341}.weui-cell_switch{padding-top:6px;padding-bottom:6px}.weui-uploader__hd{display:-webkit-box;display:-webkit-flex;display:flex;padding-bottom:10px;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.weui-uploader__title{-webkit-box-flex:1;-webkit-flex:1;flex:1}.weui-uploader__info{color:#b2b2b2}.weui-uploader__bd{margin-bottom:-4px;margin-right:-9px;overflow:hidden}.weui-uploader__file{float:left;margin-right:9px;margin-bottom:9px}.weui-uploader__img{display:block;width:79px;height:79px}.weui-uploader__file_status{position:relative}.weui-uploader__file_status:before{content:" ";position:absolute;top:0;right:0;bottom:0;left:0;background-color:rgba(0,0,0,.5)}.weui-uploader__file-content{position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);color:#fff}.weui-uploader__input-box{float:left;position:relative;margin-right:9px;margin-bottom:9px;width:77px;height:77px;border:1px solid #d9d9d9}.weui-uploader__input-box:after,.weui-uploader__input-box:before{content:" ";position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);background-color:#d9d9d9}.weui-uploader__input-box:before{width:2px;height:39.5px}.weui-uploader__input-box:after{width:39.5px;height:2px}.weui-uploader__input-box:active{border-color:#999}.weui-uploader__input-box:active:after,.weui-uploader__input-box:active:before{background-color:#999}.weui-uploader__input{position:absolute;z-index:1;top:0;left:0;width:100%;height:100%;opacity:0}.weui-article{padding:20px 15px;font-size:15px}.weui-article__section{margin-bottom:1.5em}.weui-article__h1{font-size:18px;font-weight:400;margin-bottom:.9em}.weui-article__h2{font-size:16px;font-weight:400;margin-bottom:.34em}.weui-article__h3{font-weight:400;font-size:15px;margin-bottom:.34em}.weui-article__p{margin:0 0 .8em}.weui-msg{padding-top:36px;text-align:center}.weui-msg__link{display:inline;color:#586c94}.weui-msg__icon-area{margin-bottom:30px}.weui-msg__text-area{margin-bottom:25px;padding:0 20px}.weui-msg__title{margin-bottom:5px;font-weight:400;font-size:20px}.weui-msg__desc{font-size:14px;color:#999}.weui-msg__opr-area{margin-bottom:25px}.weui-msg__extra-area{margin-bottom:15px;font-size:14px;color:#999}@media screen and (min-height:438px){.weui-msg__extra-area{position:fixed;left:0;bottom:0;width:100%;text-align:center}}.weui-flex{display:-webkit-box;display:-webkit-flex;display:flex}.weui-flex__item{-webkit-box-flex:1;-webkit-flex:1;flex:1}.weui-btn{margin-top:15px}.weui-btn:first-child{margin-top:0}.weui-btn-area{margin:1.17647059em 15px .3em}.weui-agree{display:block;padding:.5em 15px;font-size:13px}.weui-agree__text{color:#999}.weui-agree__link{display:inline;color:#586c94}.weui-agree__checkbox{position:absolute;left:-9999px}.weui-agree__checkbox-icon{position:relative;top:2px;display:inline-block;border:1px solid #d1d1d1;background-color:#fff;border-radius:3px;width:11px;height:11px}.weui-agree__checkbox-icon-check{position:absolute;top:1px;left:1px}.weui-footer{color:#999;font-size:14px;text-align:center}.weui-footer_fixed-bottom{position:fixed;bottom:.52em;left:0;right:0}.weui-footer__links{font-size:0}.weui-footer__link{display:inline-block;vertical-align:top;margin:0 .62em;position:relative;font-size:14px;color:#586c94}.weui-footer__link:before{content:" ";position:absolute;left:0;top:0;width:1px;bottom:0;border-left:1rpx solid #c7c7c7;color:#c7c7c7;left:-.65em;top:.36em;bottom:.36em}.weui-footer__link:first-child:before{display:none}.weui-footer__text{padding:0 .34em;font-size:12px}.weui-grids{border-top:1rpx solid #d9d9d9;border-left:1rpx solid #d9d9d9;overflow:hidden}.weui-grid{position:relative;float:left;padding:20px 10px;width:33.33333333%;box-sizing:border-box;border-right:1rpx solid #d9d9d9;border-bottom:1rpx solid #d9d9d9}.weui-grid_active{background-color:#ececec}.weui-grid__icon{display:block;width:28px;height:28px;margin:0 auto}.weui-grid__label{margin-top:5px;display:block;text-align:center;color:#000;font-size:14px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.weui-loading{margin:0 5px;width:20px;height:20px;display:inline-block;vertical-align:middle;-webkit-animation:a 1s steps(12) infinite;animation:a 1s steps(12) infinite;background:transparent url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAiIGhlaWdodD0iMTIwIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgxMDB2MTAwSDB6Ii8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTlFOUU5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgLTMwKSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iIzk4OTY5NyIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgzMCAxMDUuOTggNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjOUI5OTlBIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDYwIDc1Ljk4IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0EzQTFBMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSg5MCA2NSA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNBQkE5QUEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoMTIwIDU4LjY2IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0IyQjJCMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgxNTAgNTQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjQkFCOEI5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDE4MCA1MCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDMkMwQzEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTE1MCA0NS45OCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDQkNCQ0IiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTEyMCA0MS4zNCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNEMkQyRDIiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTkwIDM1IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0RBREFEQSIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgtNjAgMjQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTJFMkUyIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKC0zMCAtNS45OCA2NSkiLz48L3N2Zz4=) no-repeat;background-size:100%}.weui-loading.weui-loading_transparent{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 100 100'%3E%3Cpath fill='none' d='M0 0h100v100H0z'/%3E%3Crect xmlns='http://www.w3.org/2000/svg' width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.56)' rx='5' ry='5' transform='translate(0 -30)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.5)' rx='5' ry='5' transform='rotate(30 105.98 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.43)' rx='5' ry='5' transform='rotate(60 75.98 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.38)' rx='5' ry='5' transform='rotate(90 65 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.32)' rx='5' ry='5' transform='rotate(120 58.66 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.28)' rx='5' ry='5' transform='rotate(150 54.02 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.25)' rx='5' ry='5' transform='rotate(180 50 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.2)' rx='5' ry='5' transform='rotate(-150 45.98 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.17)' rx='5' ry='5' transform='rotate(-120 41.34 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.14)' rx='5' ry='5' transform='rotate(-90 35 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.1)' rx='5' ry='5' transform='rotate(-60 24.02 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.03)' rx='5' ry='5' transform='rotate(-30 -5.98 65)'/%3E%3C/svg%3E")}@-webkit-keyframes a{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes a{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.weui-badge{display:inline-block;padding:.15em .4em;min-width:8px;border-radius:18px;background-color:#e64340;color:#fff;line-height:1.2;text-align:center;font-size:12px;vertical-align:middle}.weui-badge_dot{padding:.4em;min-width:0}.weui-loadmore{width:65%;margin:1.5em auto;line-height:1.6em;font-size:14px;text-align:center}.weui-loadmore__tips{display:inline-block;vertical-align:middle}.weui-loadmore_line{border-top:1px solid #e5e5e5;margin-top:2.4em}.weui-loadmore__tips_in-line{position:relative;top:-.9em;padding:0 .55em;background-color:#fff;color:#999}.weui-loadmore__tips_in-dot{position:relative;padding:0 .16em;width:4px;height:1.6em}.weui-loadmore__tips_in-dot:before{content:" ";position:absolute;top:50%;left:50%;margin-top:-1px;margin-left:-2px;width:4px;height:4px;border-radius:50%;background-color:#e5e5e5}.weui-panel{background-color:#fff;margin-top:10px;position:relative;overflow:hidden}.weui-panel:first-child{margin-top:0}.weui-panel:before{top:0;border-top:1rpx solid #e5e5e5}.weui-panel:after,.weui-panel:before{content:" ";position:absolute;left:0;right:0;height:1px;color:#e5e5e5}.weui-panel:after{bottom:0;border-bottom:1rpx solid #e5e5e5}.weui-panel__hd{padding:14px 15px 10px;color:#999;font-size:13px;position:relative}.weui-panel__hd:after{content:" ";position:absolute;left:0;bottom:0;right:0;height:1px;border-bottom:1rpx solid #e5e5e5;color:#e5e5e5;left:15px}.weui-media-box{padding:15px;position:relative}.weui-media-box:before{content:" ";position:absolute;left:0;top:0;right:0;height:1px;border-top:1rpx solid #e5e5e5;color:#e5e5e5;left:15px}.weui-media-box:first-child:before{display:none}.weui-media-box__title{font-weight:400;font-size:17px;width:auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-wrap:normal;word-wrap:break-word;word-break:break-all}.weui-media-box__desc{color:#999;font-size:13px;line-height:1.2;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.weui-media-box__info{margin-top:15px;padding-bottom:5px;font-size:13px;color:#cecece;line-height:1em;list-style:none;overflow:hidden}.weui-media-box__info__meta{float:left;padding-right:1em}.weui-media-box__info__meta_extra{padding-left:1em;border-left:1px solid #cecece}.weui-media-box__title_in-text{margin-bottom:8px}.weui-media-box_appmsg{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.weui-media-box__thumb{width:100%;height:100%;vertical-align:top}.weui-media-box__hd_in-appmsg{margin-right:.8em;width:60px;height:60px;line-height:60px;text-align:center}.weui-media-box__bd_in-appmsg{-webkit-box-flex:1;-webkit-flex:1;flex:1;min-width:0}.weui-media-box_small-appmsg{padding:0}.weui-cells_in-small-appmsg{margin-top:0}.weui-cells_in-small-appmsg:before{display:none}.weui-progress{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.weui-progress__bar{-webkit-box-flex:1;-webkit-flex:1;flex:1}.weui-progress__opr{margin-left:15px;font-size:0}.weui-navbar{display:-webkit-box;display:-webkit-flex;display:flex;position:absolute;z-index:500;top:0;width:100%;border-bottom:1rpx solid #ccc}.weui-navbar__item{position:relative;display:block;-webkit-box-flex:1;-webkit-flex:1;flex:1;padding:13px 0;text-align:center;font-size:0}.weui-navbar__item.weui-bar__item_on{color:#1aad19}.weui-navbar__slider{position:absolute;content:" ";left:0;bottom:0;width:6em;height:3px;background-color:#1aad19;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s}.weui-navbar__title{display:inline-block;font-size:15px;max-width:8em;width:auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-wrap:normal}.weui-tab{position:relative;height:100%}.weui-tab__panel{box-sizing:border-box;height:100%;padding-top:50px;overflow:auto;-webkit-overflow-scrolling:touch}.weui-search-bar{position:relative;padding:8px 10px;display:-webkit-box;display:-webkit-flex;display:flex;box-sizing:border-box;background-color:#efeff4;border-top:1rpx solid #d7d6dc;border-bottom:1rpx solid #d7d6dc}.weui-icon-search{margin-right:8px;font-size:inherit}.weui-icon-search_in-box{position:absolute;left:10px;top:7px}.weui-search-bar__text{display:inline-block;font-size:14px;vertical-align:middle}.weui-search-bar__form{position:relative;-webkit-box-flex:1;-webkit-flex:auto;flex:auto;border-radius:5px;background:#fff;border:1rpx solid #e6e6ea}.weui-search-bar__box{position:relative;padding-left:30px;padding-right:30px;width:100%;box-sizing:border-box;z-index:1}.weui-search-bar__input{height:28px;line-height:28px;font-size:14px}.weui-icon-clear{position:absolute;top:0;right:0;padding:7px 8px;font-size:0}.weui-search-bar__label{position:absolute;top:0;right:0;bottom:0;left:0;z-index:2;border-radius:3px;text-align:center;color:#9b9b9b;background:#fff;line-height:28px}.weui-search-bar__cancel-btn{margin-left:10px;line-height:28px;color:#09bb07;white-space:nowrap} --------------------------------------------------------------------------------