├── README.md ├── app.js ├── app.json ├── app.wxss ├── pages ├── index │ ├── index.js │ ├── index.wxml │ └── index.wxss ├── logs │ ├── logs.js │ ├── logs.json │ ├── logs.wxml │ └── logs.wxss └── teamtoy │ ├── .DS_Store │ ├── dashboard.js │ ├── dashboard.json │ ├── dashboard.wxml │ ├── dashboard.wxss │ ├── todoadd.js │ └── todoadd.wxml └── utils └── util.js /README.md: -------------------------------------------------------------------------------- 1 | # 带用户登录的微信小程序 Demo 2 | 3 | ![](http://ww2.sinaimg.cn/large/40dfde6fjw1f8743ptc82g20av0iv78l.gif) 4 | 5 | 使用了 TeamToy 的 API http://tt2net.vipsinaapp.com/#api 6 | 7 | 只实现了简单的 用户登录 、 TODO 列表 、 TODO 添加。目的是了解下小程序开发的流程和逻辑。 8 | 9 | 踩坑交流 QQ 群: 240520361 10 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | //app.js 2 | App({ 3 | onLaunch: function () { 4 | //调用API从本地缓存中获取数据 5 | var logs = wx.getStorageSync('logs') || [] 6 | logs.unshift(Date.now()) 7 | wx.setStorageSync('logs', logs) 8 | }, 9 | getUserInfo:function(cb){ 10 | var that = this 11 | if(this.globalData.userInfo){ 12 | typeof cb == "function" && cb(this.globalData.userInfo) 13 | }else{ 14 | //调用登录接口 15 | wx.login({ 16 | success: function () { 17 | wx.getUserInfo({ 18 | success: function (res) { 19 | that.globalData.userInfo = res.userInfo 20 | typeof cb == "function" && cb(that.globalData.userInfo) 21 | } 22 | }) 23 | } 24 | }) 25 | } 26 | }, 27 | globalData:{ 28 | userInfo:null, 29 | ttToken:null, 30 | ttHost:null 31 | } 32 | }) -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages":[ 3 | "pages/index/index", 4 | "pages/teamtoy/dashboard", 5 | "pages/teamtoy/todoadd", 6 | "pages/logs/logs" 7 | ], 8 | "window":{ 9 | "backgroundTextStyle":"light", 10 | "navigationBarBackgroundColor": "#fff", 11 | "navigationBarTitleText": "TeamToy", 12 | "navigationBarTextStyle":"black", 13 | "enablePullDownRefresh":true 14 | }, 15 | "tabBar": { 16 | "list": [{ 17 | "pagePath": "pages/teamtoy/dashboard", 18 | "text": "TODO" 19 | }, { 20 | "pagePath": "pages/teamtoy/pm", 21 | "text": "私信" 22 | },{ 23 | "pagePath": "pages/teamtoy/members", 24 | "text": "同事" 25 | },{ 26 | "pagePath": "pages/teamtoy/settings", 27 | "text": "设置" 28 | } 29 | 30 | ] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app.wxss: -------------------------------------------------------------------------------- 1 | page { 2 | background-color: #fbf9fe; 3 | height: 100%; 4 | } 5 | .container { 6 | display: flex; 7 | flex-direction: column; 8 | min-height: 100%; 9 | justify-content: space-between; 10 | } 11 | .page-header { 12 | display: flex; 13 | font-size: 32rpx; 14 | color: #aaa; 15 | justify-content: center; 16 | margin-top: 50rpx; 17 | } 18 | .page-header-text { 19 | padding: 20rpx 40rpx; 20 | border-bottom: 1px solid #ccc; 21 | } 22 | 23 | .page-body { 24 | width: 100%; 25 | display: flex; 26 | flex-direction: column; 27 | align-items: center; 28 | flex-grow: 1; 29 | overflow-x: hidden; 30 | } 31 | .page-body-wrapper { 32 | margin-top: 100rpx; 33 | display: flex; 34 | flex-direction: column; 35 | align-items: center; 36 | width: 100%; 37 | } 38 | .page-body-wrapper form { 39 | width: 100%; 40 | } 41 | .page-body-wording { 42 | text-align: center; 43 | padding: 200rpx 100rpx; 44 | } 45 | .page-body-info { 46 | display: flex; 47 | flex-direction: column; 48 | align-items: center; 49 | background-color: #fff; 50 | margin-bottom: 50rpx; 51 | width: 100%; 52 | padding: 50rpx 0 150rpx 0; 53 | } 54 | .page-body-title { 55 | margin-bottom: 100rpx; 56 | font-size: 32rpx; 57 | } 58 | .page-body-text { 59 | font-size: 30rpx; 60 | line-height: 26px; 61 | color: #ccc; 62 | } 63 | .page-body-text-small { 64 | font-size: 24rpx; 65 | color: #000; 66 | margin-bottom: 100rpx; 67 | } 68 | .page-body-form { 69 | width: 100%; 70 | background-color: #fff; 71 | display: flex; 72 | flex-direction: column; 73 | width: 100%; 74 | border: 1px solid #eee; 75 | } 76 | .page-body-form-item { 77 | display: flex; 78 | align-items: center; 79 | margin-left: 10rpx; 80 | border-bottom: 1px solid #eee; 81 | height: 80rpx; 82 | } 83 | .page-body-form-key { 84 | width: 180rpx; 85 | } 86 | .page-body-form-value { 87 | flex-grow: 1; 88 | } 89 | 90 | .page-body-form-picker { 91 | display: flex; 92 | justify-content: space-between; 93 | height: 100rpx; 94 | align-items: center; 95 | font-size: 36rpx; 96 | margin-left: 20rpx; 97 | padding-right: 20rpx; 98 | border-bottom: 1px solid #eee; 99 | } 100 | .page-body-form-picker-value { 101 | color: #ccc; 102 | } 103 | 104 | .page-body-buttons { 105 | width: 100%; 106 | } 107 | .page-body-button { 108 | margin: 25rpx; 109 | } 110 | .page-body-button image { 111 | width: 150rpx; 112 | height: 150rpx; 113 | } 114 | .page-footer { 115 | text-align: center; 116 | color: #1aad19; 117 | font-size: 24rpx; 118 | margin: 20rpx 0; 119 | } 120 | 121 | .green{ 122 | color: #09BB07; 123 | } 124 | .red{ 125 | color: #F76260; 126 | } 127 | .blue{ 128 | color: #10AEFF; 129 | } 130 | .yellow{ 131 | color: #FFBE00; 132 | } 133 | .gray{ 134 | color: #C9C9C9; 135 | } 136 | 137 | .strong{ 138 | font-weight: bold; 139 | } 140 | 141 | .bc_green{ 142 | background-color: #09BB07; 143 | } 144 | .bc_red{ 145 | background-color: #F76260; 146 | } 147 | .bc_blue{ 148 | background-color: #10AEFF; 149 | } 150 | .bc_yellow{ 151 | background-color: #FFBE00; 152 | } 153 | .bc_gray{ 154 | background-color: #C9C9C9; 155 | } 156 | 157 | .tc{ 158 | text-align: center; 159 | } 160 | 161 | .page input{ 162 | padding: 10px 15px; 163 | background-color: #fff; 164 | } 165 | checkbox, radio{ 166 | margin-right: 5px; 167 | } 168 | 169 | .btn-area{ 170 | padding: 0 15px; 171 | } 172 | .btn-area button{ 173 | margin-top: 10px; 174 | margin-bottom: 10px; 175 | } 176 | 177 | .page { 178 | min-height: 100%; 179 | flex: 1; 180 | background-color: #FBF9FE; 181 | font-size: 16px; 182 | font-family: -apple-system-font,Helvetica Neue,Helvetica,sans-serif; 183 | overflow: hidden; 184 | } 185 | .page__hd{ 186 | padding: 40px; 187 | } 188 | .page__title{ 189 | display: block; 190 | font-size: 20px; 191 | } 192 | .page__desc{ 193 | margin-top: 5px; 194 | font-size: 14px; 195 | color: #888888; 196 | } 197 | 198 | .section{ 199 | margin-bottom: 40px; 200 | } 201 | .section_gap{ 202 | padding: 0 15px; 203 | } 204 | .section__title{ 205 | margin-bottom: 8px; 206 | padding-left: 15px; 207 | padding-right: 15px; 208 | } 209 | .section_gap .section__title{ 210 | padding-left: 0; 211 | padding-right: 0; 212 | } 213 | 214 | 215 | -------------------------------------------------------------------------------- /pages/index/index.js: -------------------------------------------------------------------------------- 1 | //index.js 2 | //获取应用实例 3 | var app = getApp() 4 | Page({ 5 | 6 | data: { 7 | host:'ttsite.sinaapp.com', 8 | email:'we@teamtoy.net', 9 | password:'think_different' 10 | }, 11 | //事件处理函数 12 | bindViewTap: function() { 13 | wx.navigateTo({ 14 | url: '../logs/logs' 15 | }) 16 | }, 17 | login:function( e ){ 18 | //console.log( this.data ); 19 | var that = this; 20 | var url = 'http://'+ e.detail.value.host + '/?c=api&a=user_get_token'; 21 | wx.request({ 22 | 'url':url , 23 | data:{ 24 | 'email':e.detail.value.email , 25 | 'password':e.detail.value.password 26 | }, 27 | header: { 28 | 'Content-Type': 'application/json' 29 | }, 30 | success:function(res) { 31 | //console.log(res.data); 32 | if( parseInt( res.data.err_code ) == 0 ) 33 | { 34 | // 将 Token 放到全局变量中。 35 | 36 | app.globalData.ttToken = res.data.data.token; 37 | app.globalData.ttHost = e.detail.value.host; 38 | 39 | // then redirct to app page 40 | wx.redirectTo({'url':'../teamtoy/dashboard'}); 41 | } 42 | } 43 | }); 44 | //console.log( e.detail.value ); 45 | }, 46 | onLoad: function () { 47 | console.log('onLoad') 48 | var that = this 49 | //调用应用实例的方法获取全局数据 50 | app.getUserInfo(function(userInfo){ 51 | //更新数据 52 | that.setData({ 53 | userInfo:userInfo 54 | }) 55 | }) 56 | } 57 | }) 58 | -------------------------------------------------------------------------------- /pages/index/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | TeamToy登入 4 | 5 |
6 | 7 | 8 | 9 | 10 | Host 11 | 12 | 13 | 14 | 15 | Email 16 | 17 | 18 | 19 | 20 | 密码 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 |
30 | -------------------------------------------------------------------------------- /pages/index/index.wxss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easychen/teamtoy-mina-demo/3617f3bca43874c662fedbcb11d934e497c89cad/pages/index/index.wxss -------------------------------------------------------------------------------- /pages/logs/logs.js: -------------------------------------------------------------------------------- 1 | //logs.js 2 | var util = require('../../utils/util.js') 3 | Page({ 4 | data: { 5 | logs: [] 6 | }, 7 | onLoad: function () { 8 | this.setData({ 9 | logs: (wx.getStorageSync('logs') || []).map(function (log) { 10 | return util.formatTime(new Date(log)) 11 | }) 12 | }) 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /pages/logs/logs.json: -------------------------------------------------------------------------------- 1 | { 2 | "navigationBarTitleText": "查看启动日志" 3 | } -------------------------------------------------------------------------------- /pages/logs/logs.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{index + 1}}. {{log}} 5 | 6 | 7 | -------------------------------------------------------------------------------- /pages/logs/logs.wxss: -------------------------------------------------------------------------------- 1 | .log-list { 2 | display: flex; 3 | flex-direction: column; 4 | padding: 40rpx; 5 | } 6 | .log-item { 7 | margin: 10rpx; 8 | } 9 | -------------------------------------------------------------------------------- /pages/teamtoy/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easychen/teamtoy-mina-demo/3617f3bca43874c662fedbcb11d934e497c89cad/pages/teamtoy/.DS_Store -------------------------------------------------------------------------------- /pages/teamtoy/dashboard.js: -------------------------------------------------------------------------------- 1 | var app = getApp() 2 | Page({ 3 | 4 | data:{ 5 | todolist:[] 6 | }, 7 | todoAdd:function( e ) 8 | { 9 | //console.log( e ); 10 | wx.navigateTo( { 'url':'todoadd' } ); 11 | }, 12 | onLoad:function() 13 | { 14 | var that = this; 15 | var url = 'http://'+app.globalData.ttHost+'/?c=api&a=todo_list&token='+app.globalData.ttToken; 16 | wx.request({ 17 | 'url':url, 18 | header: { 19 | 'Content-Type': 'application/json' 20 | }, 21 | success:function(res) 22 | { 23 | //console.log( res ); 24 | // 25 | if( res.data && res.data.data ){ 26 | that.setData({ todolist:res.data.data}); 27 | } 28 | 29 | console.log( that.data ); 30 | 31 | } 32 | }); 33 | } 34 | ,onShow:function(){ 35 | this.onLoad(); 36 | } 37 | 38 | 39 | 40 | 41 | // http://ttsite.sinaapp.com/index.php?c=api&a=todo_list 42 | 43 | 44 | }); 45 | -------------------------------------------------------------------------------- /pages/teamtoy/dashboard.json: -------------------------------------------------------------------------------- 1 | { 2 | window:{ 3 | "enablePullDownRefresh":true 4 | } 5 | } -------------------------------------------------------------------------------- /pages/teamtoy/dashboard.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 我的TODO 4 | 5 | {{item.content}} 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /pages/teamtoy/dashboard.wxss: -------------------------------------------------------------------------------- 1 | .todocard 2 | { 3 | margin-top: 1rem; 4 | padding:.5rem; 5 | border:1px solid #eee; 6 | } 7 | 8 | .todobtn 9 | { 10 | margin-top:2rem; 11 | width:100%; 12 | } -------------------------------------------------------------------------------- /pages/teamtoy/todoadd.js: -------------------------------------------------------------------------------- 1 | var app = getApp() 2 | 3 | Page({ 4 | 5 | data: 6 | { 7 | todocontent:'' 8 | }, 9 | todosave:function( e ) 10 | { 11 | var that = this; 12 | console.log( that ); 13 | var url = 'http://'+app.globalData.ttHost+'/?c=api&a=todo_add&token='+app.globalData.ttToken; 14 | wx.request({ 15 | 'url':url, 16 | header: { 17 | 'Content-Type': 'application/json' 18 | }, 19 | data: 20 | { 21 | 'text':e.detail.value.todocontent 22 | }, 23 | success:function(res) 24 | { 25 | console.log( res ); 26 | if( parseInt( res.data.err_code ) == 0 ) 27 | { 28 | // 关掉当前页面 29 | that.setData({'todocontent':''}); 30 | wx.navigateBack(); 31 | } 32 | // 33 | 34 | //console.log( that.data ); 35 | 36 | } 37 | }); 38 | } 39 | 40 | }); -------------------------------------------------------------------------------- /pages/teamtoy/todoadd.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 添加 TODO 4 | 5 |
6 | 7 | 8 | TODO 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 |
-------------------------------------------------------------------------------- /utils/util.js: -------------------------------------------------------------------------------- 1 | function formatTime(date) { 2 | var year = date.getFullYear() 3 | var month = date.getMonth() + 1 4 | var day = date.getDate() 5 | 6 | var hour = date.getHours() 7 | var minute = date.getMinutes() 8 | var second = date.getSeconds() 9 | 10 | 11 | return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':') 12 | } 13 | 14 | function formatNumber(n) { 15 | n = n.toString() 16 | return n[1] ? n : '0' + n 17 | } 18 | 19 | module.exports = { 20 | formatTime: formatTime 21 | } 22 | --------------------------------------------------------------------------------