diff --git a/app/api/mobile/apis/users.rb b/app/api/mobile/apis/users.rb index 6ce3cacbb..7800382ad 100644 --- a/app/api/mobile/apis/users.rb +++ b/app/api/mobile/apis/users.rb @@ -4,6 +4,17 @@ module Mobile class Users < Grape::API resource :users do + + desc "绑定微信用户" + params do + requires :login, type: String, desc: 'username' + requires :mail, type: String, desc: 'mail' + requires :password, type: String, desc: 'password' + end + post '/bindwx' do + + end + desc "注册用户" params do requires :login, type: String, desc: 'username' diff --git a/app/controllers/wechats_controller.rb b/app/controllers/wechats_controller.rb index 169a33fce..887587a5f 100644 --- a/app/controllers/wechats_controller.rb +++ b/app/controllers/wechats_controller.rb @@ -145,7 +145,7 @@ class WechatsController < ActionController::Base 您还未绑定确实的用户,请先绑定,谢谢!" } } request.reply.news(news) do |article, n, index| # article is return object - url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=#{Wechat.config.appid}&redirect_uri=#{login_wechat_url}&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect" + url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=#{Wechat.config.appid}&redirect_uri=#{root_url+'/assets/wechat/app.html#login'}&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect" pic_url = "#{Setting.protocol}://#{Setting.host_name}/images/weixin_pic.jpg" article.item title: "#{n[:title]}", description: n[:content], @@ -175,7 +175,7 @@ class WechatsController < ActionController::Base code = params[:code] || session[:wechat_code] openid = get_openid_from_code(code) - raise "无法获取到openid" unless openid + raise "无法获取到openid,请在微信中打开本页面" unless openid raise "此微信号已绑定用户, 不能重复绑定" if user_binded?(openid) user, last_login_on = User.try_to_login(params[:username], params[:password]) diff --git a/app/models/course.rb b/app/models/course.rb index d379b24d3..c9ef010e6 100644 --- a/app/models/course.rb +++ b/app/models/course.rb @@ -465,11 +465,6 @@ class Course < ActiveRecord::Base code end - def - - end - - end diff --git a/public/assets/wechat/app.html b/public/assets/wechat/app.html index cabd224c4..6965d24f3 100644 --- a/public/assets/wechat/app.html +++ b/public/assets/wechat/app.html @@ -10,6 +10,7 @@ + @@ -17,8 +18,9 @@
+ @@ -30,8 +32,12 @@ + + + + diff --git a/public/assets/wechat/login.html b/public/assets/wechat/login.html new file mode 100644 index 000000000..d34d0054c --- /dev/null +++ b/public/assets/wechat/login.html @@ -0,0 +1,25 @@ +
+
+ +
+
绑定注册
+ + + + + +
+
+ + \ No newline at end of file diff --git a/public/assets/wechat/reg.html b/public/assets/wechat/reg.html new file mode 100644 index 000000000..9184fd0ed --- /dev/null +++ b/public/assets/wechat/reg.html @@ -0,0 +1,43 @@ +
+
+
注册登录
+ + + + + + + + + +
+
+ + \ No newline at end of file diff --git a/public/assets/wechat/templates/alert.html b/public/assets/wechat/templates/alert.html new file mode 100644 index 000000000..b59a1b87f --- /dev/null +++ b/public/assets/wechat/templates/alert.html @@ -0,0 +1,12 @@ + +
+
+
+
{{title}}
+
{{message}}
+
+ 确定 +
+
+
+ \ No newline at end of file diff --git a/public/images/wechat/QR-code.jpg b/public/images/wechat/QR-code.jpg new file mode 100644 index 000000000..ba2a9e6a3 Binary files /dev/null and b/public/images/wechat/QR-code.jpg differ diff --git a/public/images/wechat/arrow.png b/public/images/wechat/arrow.png new file mode 100644 index 000000000..f9f9b18c5 Binary files /dev/null and b/public/images/wechat/arrow.png differ diff --git a/public/images/wechat/checked.png b/public/images/wechat/checked.png new file mode 100644 index 000000000..77986d62e Binary files /dev/null and b/public/images/wechat/checked.png differ diff --git a/public/images/wechat/dot.png b/public/images/wechat/dot.png new file mode 100644 index 000000000..bf1c0104e Binary files /dev/null and b/public/images/wechat/dot.png differ diff --git a/public/images/wechat/female.jpg b/public/images/wechat/female.jpg new file mode 100644 index 000000000..219865572 Binary files /dev/null and b/public/images/wechat/female.jpg differ diff --git a/public/images/wechat/female.png b/public/images/wechat/female.png new file mode 100644 index 000000000..a13733ffc Binary files /dev/null and b/public/images/wechat/female.png differ diff --git a/public/images/wechat/male.jpg b/public/images/wechat/male.jpg new file mode 100644 index 000000000..46d58f26e Binary files /dev/null and b/public/images/wechat/male.jpg differ diff --git a/public/images/wechat/male.png b/public/images/wechat/male.png new file mode 100644 index 000000000..9f1214a4c Binary files /dev/null and b/public/images/wechat/male.png differ diff --git a/public/images/wechat/minus.png b/public/images/wechat/minus.png new file mode 100644 index 000000000..32d82ea84 Binary files /dev/null and b/public/images/wechat/minus.png differ diff --git a/public/images/wechat/plus.png b/public/images/wechat/plus.png new file mode 100644 index 000000000..e5d83d212 Binary files /dev/null and b/public/images/wechat/plus.png differ diff --git a/public/images/wechat/post-avatar.jpg b/public/images/wechat/post-avatar.jpg new file mode 100644 index 000000000..bd2597dd2 Binary files /dev/null and b/public/images/wechat/post-avatar.jpg differ diff --git a/public/images/wechat/search.png b/public/images/wechat/search.png new file mode 100644 index 000000000..a04c1496c Binary files /dev/null and b/public/images/wechat/search.png differ diff --git a/public/images/wechat/setting.png b/public/images/wechat/setting.png new file mode 100644 index 000000000..3c1159fc9 Binary files /dev/null and b/public/images/wechat/setting.png differ diff --git a/public/images/wechat/tr-like.png b/public/images/wechat/tr-like.png new file mode 100644 index 000000000..9d9d38dc3 Binary files /dev/null and b/public/images/wechat/tr-like.png differ diff --git a/public/images/wechat/tr-reply.png b/public/images/wechat/tr-reply.png new file mode 100644 index 000000000..aef9cffcf Binary files /dev/null and b/public/images/wechat/tr-reply.png differ diff --git a/public/javascripts/wechat/app.js b/public/javascripts/wechat/app.js index 4d947e440..d4275e9df 100644 --- a/public/javascripts/wechat/app.js +++ b/public/javascripts/wechat/app.js @@ -1 +1,8 @@ var app = angular.module('wechat', ['ngRoute']); + +app.constant('config', { + rootPath: '/assets/wechat/', + rootUrl: '/', + apiUrl: '/api/v1/' + +}); \ No newline at end of file diff --git a/public/javascripts/wechat/controllers/login.js b/public/javascripts/wechat/controllers/login.js new file mode 100644 index 000000000..011f11baa --- /dev/null +++ b/public/javascripts/wechat/controllers/login.js @@ -0,0 +1,54 @@ +app.controller('LoginController', ['$scope', '$http', '$location', '$routeParams', 'alertService', 'config','auth','session', + function ($scope, $http, $location, $routeParams, alertService, config, auth,session) { + + if($routeParams.code){ + session.save('code', $routeParams.code); + } + + var vm = $scope; + vm.loginFailed = false; + vm.alertService = alertService.create(); + vm.findPwdDialog = alertService.create(); + + vm.login = function (frm, user) { + frm.$setSubmitted(); + console.log(user); + + if (!frm.$valid) { + console.log(frm.$error); + return; + } + + console.log(apiUrl + "auth"); + + auth.getOpenId().then( + function(){ + return $http.post( + config.rootUrl + "wxbind", + {login: user.login, password: user.password, openid: openid} + ); + } + ).then( + function(response) { + vm.loginFailed = (response.data.status != 0); + console.log(response.data); + vm.alertService.showMessage('出错了', response.data.msg); + + if (!$scope.loginFailed) { //绑定成功 + } else { + vm.alertService.showMessage('出错了', response.data.msg); + } + } + ).catch(function(e){ + vm.alertService.showMessage('出错了', e); + }); + }; + + vm.showBox = function () { + vm.findPwdDialog.showMessage("提示", "请访问www.trustie.net获取密码,谢谢!"); + } + + vm.goReg = function () { + $location.path('/reg'); + } + }]); diff --git a/public/javascripts/wechat/controllers/reg.js b/public/javascripts/wechat/controllers/reg.js new file mode 100644 index 000000000..dfa010ad7 --- /dev/null +++ b/public/javascripts/wechat/controllers/reg.js @@ -0,0 +1,42 @@ +app.controller('RegController', ['$scope', '$http', '$location', 'alertService', + function ($scope, $http, $location, alertService) { + + var vm = $scope; + vm.errDialog = alertService.create(); + + vm.goLogin = function () { + $location.path("/login"); + } + + vm.isagreed = true; + vm.agreed = function (_isagreed) { + vm.isagreed = !_isagreed; + }; + + vm.reg = function (frm, user) { + + frm.$setSubmitted(); + + console.log(frm); + if (!frm.$valid) { + console.log(frm.$error); + return; + } + + console.log(user); + + $http.post( + apiUrl + "users", + {login: user.username, password: user.password, mail: user.email} + ).then(function (response) { + if (response.data.status != 0) { + vm.errDialog.showMessage('出错了',response.data.message); + } else { + vm.errDialog.showMessage("提示","注册且绑定微信成功"); + } + }, function (response) { + vm.errDialo.showMessage('出错了',response.data); + }); + } + + }]); \ No newline at end of file diff --git a/public/javascripts/wechat/directives/alert.js b/public/javascripts/wechat/directives/alert.js new file mode 100644 index 000000000..aa346cb8c --- /dev/null +++ b/public/javascripts/wechat/directives/alert.js @@ -0,0 +1,16 @@ +app.directive('myAlert', ['config', function(config){ + return { + templateUrl: config.rootPath+ 'templates/alert.html', + scope: { + message: "=", + title: "=", + visible: "=" + }, + link: function(scope){ + scope.visible = false; + scope.dismiss = function(){ + scope.visible = false; + }; + } + } +}]); \ No newline at end of file diff --git a/public/javascripts/wechat/directives/form_validate.js b/public/javascripts/wechat/directives/form_validate.js new file mode 100644 index 000000000..553560c56 --- /dev/null +++ b/public/javascripts/wechat/directives/form_validate.js @@ -0,0 +1,10 @@ +app.directive('pwdconfirm', function(){ + return { + require: 'ngModel', + link: function(scope, elm, attrs, ctrl){ + ctrl.$validators.pwdconfirm = function(modelValue, viewValue) { + return scope.user && scope.user.password == viewValue; + } + } + } +}); \ No newline at end of file diff --git a/public/javascripts/wechat/others/factory.js b/public/javascripts/wechat/others/factory.js index cefef3ab9..27fbeb1c4 100644 --- a/public/javascripts/wechat/others/factory.js +++ b/public/javascripts/wechat/others/factory.js @@ -1,23 +1,60 @@ -app.factory('auth', ['$http','$routeParams', '$q', function($http,$routeParams, $q){ +app.factory('alertService', function(){ + function Alert(){ + this.title = null; + this.message = null; + this.visible = null; + } + + Alert.prototype.showMessage = function(title, msg){ + this.message = msg; + this.title = title; + this.visible = true; + } + + Alert.prototype.dismiss = function(){ + this.message = null; + this.title = null; + this.visible = false; + } + + return { + create: function(){ + return new Alert(); + } + } +}); + + +app.factory('auth', ['$http','$routeParams', '$q', 'session', function($http,$routeParams, $q, session){ var _openid = ''; if(typeof g_openid !== 'undefined'){ _openid = g_openid; } + if(!_openid){ + _openid = session.get("openid"); + } + var getOpenId = function() { var deferred = $q.defer(); - if (typeof _openid !== 'undefined' && _openid.length > 0){ + console.log(_openid); + if (typeof _openid !== 'undefined' && _openid && _openid.length > 0){ deferred.resolve(_openid); } else { - var code = $routeParams.code; + var code = $routeParams.code || session.get("code"); $http({ url: '/wechat/get_open_id', data: {code: code}, method: 'POST' }).then(function successCallback(response) { - _openid = response.data.openid; - deferred.resolve(_openid); + if(response.data.status != 0){ + deferred.reject(response.data.msg); + } else{ + _openid = response.data.openid; + session.save("openid", _openid); + deferred.resolve(_openid); + } }, function errorCallback(response) { deferred.reject(response); }); @@ -30,6 +67,16 @@ app.factory('auth', ['$http','$routeParams', '$q', function($http,$routeParams, return {getOpenId: getOpenId, openid: openid}; }]); +app.factory("session", function(){ + return { + save: function(key,value){ + sessionStorage.setItem(key,value); + }, + get: function(key){ + return sessionStorage.getItem(key); + } + } +}); app.factory('rms', function(){ var _saveStorage = {}; diff --git a/public/javascripts/wechat/others/routes.js b/public/javascripts/wechat/others/routes.js index 7ea270c6e..ded374930 100644 --- a/public/javascripts/wechat/others/routes.js +++ b/public/javascripts/wechat/others/routes.js @@ -1,7 +1,15 @@ -app.config(['$routeProvider',"$httpProvider", "$locationProvider",function ($routeProvider, $httpProvider, $locationProvider) { - var rootPath = '/assets/wechat/' +app.config(['$routeProvider',"$httpProvider", "$locationProvider",'config', function ($routeProvider, $httpProvider, $locationProvider, config) { + var rootPath = config.rootPath; //$locationProvider.html5Mode(true); $routeProvider + .when('/login', { + templateUrl: rootPath + 'login.html', + controller: 'LoginController' + }) + .when('/reg', { + templateUrl: rootPath + 'reg.html', + controller: 'RegController' + }) .when('/activites', { templateUrl: rootPath + 'activities.html', controller: 'ActivityController' diff --git a/public/stylesheets/weui/weixin.css b/public/stylesheets/weui/weixin.css index 6cccb3615..fd5a56bd6 100644 --- a/public/stylesheets/weui/weixin.css +++ b/public/stylesheets/weui/weixin.css @@ -3,7 +3,8 @@ /*基本样式*/ body,table,input,textarea,select,button { font-family: "微软雅黑","宋体";} -h1,h2,h3,h4,h5,p,pre {padding:0px; margin:0px;} +body, ul, h1,h2,h3,h4,h5,p,pre {padding:0px; margin:0px;} +ul li {list-style:none;} img {max-width:100%;} blockquote {border:1px solid #d4d4d4; padding: 0.6em; margin-left: 1.4em; margin-right: 0.4em; border-radius: 4px; font-family: "Microsoft YaHei"; background-size: 100% 100%; margin-top:5px;} .text-control {word-break:normal; word-wrap:break-word;} @@ -12,29 +13,42 @@ blockquote {border:1px solid #d4d4d4; padding: 0.6em; margin-left: 1.4em; margin .f15 {font-size:15px;} .fb {font-weight:bold;} .mt2 {margin-top:2px;} +.mt4 {margin-top:4px;} .mt5 {margin-top:5px;} .mt10 {margin-top:10px;} +.mt11 {margin-top:11px;} +.mt15 {margin-top:15px;} +.mt30 {margin-top:30px;} +.mt70 {margin-top:70px;} .mb5 {margin-bottom:5px;} .mb10 {margin-bottom:10px;} +.mb20 {margin-bottom:20px;} .ml10 {margin-left:10px;} .mr5 {margin-right:5px;} .mr10 {margin-right:10px;} .ml15 {margin-left:15px;} .mr15 {margin-right:15px;} .mr20 {margin-right:20px;} +.ml25 {margin-left:25px;} .mr25 {margin-right:25px;} .ml55 {margin-left:55px;} .mr55 {margin-right:55px;} +.c-red {color:#e81a1a;} .c-blue {color:#269ac9;} .c-grey {color:#9a9a9a;} .c-grey2 {color:#707070;} .c-grey3 {color:#555555;} +.c-grey4 {color:#888888;} +.c-grey5 {color:#aaaaaa;} +.c-grey6 {color:#777777;} +.c-blue {color:#3b94d6;} a {color:#707070;} a.c-grey {color:#707070;} a.c-grey2 {color:#9a9a9a;} a:link,a:visited{text-decoration:none;} a:hover,a:active{cursor:pointer;} a.link-blue {color:#269ac9;} +a.link-blue2 {color:#3b94d6;} a.underline {text-decoration:underline;} .border-radius {border-radius:5px;} .w36 {width:36px;} @@ -42,9 +56,21 @@ a.underline {text-decoration:underline;} .max-width-130 {max-width:130px;} .hidden {overflow:hidden; white-space:nowrap; text-overflow:ellipsis;} .inline-block {display:inline-block;} +.dis {display:block;} .undis {display:none;} .text-nowrap {white-space:nowrap;} .v-top {vertical-align:top;} +.tac {text-align:center;} +.block-center {margin-left:auto; margin-right:auto; display:block;} + +/*背景色*/ +.bg-grey {background-color:#c1c1c1;} +.bg-blue {background-color:#3b94d6;} + +/*按钮样式*/ +.btn1 {width:100%; height:40px; line-height:40px; vertical-align:middle; text-align:center; color:#fff; display:block; border-radius:5px;} +.bg-blue:not(.btn-disabled):active {background-color:#2780c2;} +.btn-disabled {background-color:#ccc;} /*动态样式*/ .post-container {width:100%;} @@ -88,4 +114,63 @@ a.underline {text-decoration:underline;} /*帖子锁定样式*/ .locked_btn_cir {background: url("/images/locked.png") 0 0 no-repeat; cursor: default;} -.bg-grey {background-color:#c1c1c1;} +/*20150612加入班级样式*/ +.add-class-box {width:80%; max-width:300px; min-width:240px; height:150px; font-size:15px; color:#444; background-color:#fff; margin:0 auto; box-shadow: 0px 2px 8px rgba(146, 153, 169, 0.5); border-radius:5px; margin-top:100px;} +.add-class-tip {padding-top:20px; padding-bottom:20px;} +.class-number-input {width:80%; max-width:240px; height:28px; border:1px solid #ccc; padding-left:5px; margin:0 auto; display:block;} +.cancel-btn {width:49%; height:37px; line-height:37px; text-align:center; vertical-align:middle; border-top:1px solid #ccc;} +.submit-btn {width:49%; height:37px; line-height:37px; text-align:center; vertical-align:middle; border-top:1px solid #ccc;} +.slice {width:2%; text-align:center; border-top:1px solid #ccc;} +.slice-line {width:1px; height:37px; margin:auto; background:#ccc;} + +/*20160613邀请码样式*/ +.qr-code-wrap {width:100%; padding:40px 0; background-color:#3b94d6;} +.qr-code-box {width:225px; height:332px; background-color:#fff; border-radius:3px; margin:0 auto;} +.share-class-name {font-size:18px; color:#3b3b3b; text-align:center; padding:12px; border-bottom:1px solid #cccccc; overflow:hidden; white-space:nowrap; text-overflow:ellipsis;} +.qr-img-wrap {width:100%; border-bottom:1px dashed #ccc;} +.qr-code-img {margin:36px auto; display:block;} +.invitation-code-wrap {text-align:center; font-size:18px; color:#3b3b3b; padding:16px;} +.share-code-wrap {width:100%; background-color:#efeff4;} +.share-code-btn, .finish-btn {width:145px; height:35px; color:#fff; font-size:15px; line-height:35px; text-align:center; vertical-align:middle; background-color:#ff7239; margin:18px auto 20px auto; border-radius:50px; display:block;} +.share-code-instruction {max-width:228px; font-size:12px; color:#666; line-height:20px; margin:0 auto;} + +/*20160613班级详情*/ +.class-detail-name, .blue-title {width:100%; height:45px; line-height:45px; vertical-align:middle; background-color:#3b94d6; color:#fff; font-size:18px; text-align:center;} +.blue-title-sub {position:absolute; right:10px;} +.slice2 {width:2%; text-align:center; background-color:#fff; border-bottom:1px solid #ccc;} +.slice3 {width:1%; height:38px; text-align:center; background-color:#fff; border-bottom:1px solid #ccc;} +.slice-line2 {width:1px; height:38px; margin:auto; background:#ccc;} +.class-detail-tab {width:23%; height:38px; line-height:38px; font-size:13px; color:#444; background-color:#fff; float:left; text-align:center; vertical-align:middle; border-bottom:1px solid #ccc;} +.class-detail-tab2 {width:32%; height:38px; line-height:38px; font-size:13px; color:#444; background-color:#fff; float:left; text-align:center; vertical-align:middle; border-bottom:1px solid #ccc;} +.class-tab-active {border-bottom:1px solid #3b94d6;} +.class-search-wrap {padding:8px 12px; position:relative;} +.class-search-inner {padding:0 30px; background-color:#fff;} +.class-search-icon {position:absolute; top:16px; left:16px;} +.class-detail-search {width:100%; height:33px; color:#999; background-color:#fff; border:none; outline:none;} +.border-top {border-top:1px solid #ccc;} +.class-detail-row {width:100%; height:38px; line-height:38px; vertical-align:middle; border-bottom:1px solid #ccc; background-color:#fff;} +.class-test-tip {text-align:center; font-size:13px; color:#444; padding-top:40px;} +.img-circle {border-radius:50%;} + +/*20160614班级列表*/ +.course-list-row {width:100%; height:38px; line-height:38px; vertical-align:middle; border-top:1px solid #ccc; border-bottom:1px solid #ccc; background-color:#fff;} +.class-list {width:100%; border-bottom:1px solid #ccc;} +.class-list li {height:40px; line-height:40px; vertical-align:middle; margin:0 25px; border-left:1px solid #ccc; border-bottom:1px solid #ccc; position:relative;} +.class-list-name {max-width:75%; display:inline-block;} +.class-list-dot {position:absolute; top:13px; left:-8px;} +.border-bottom-none {border-bottom:none !important;} +.students-amount {height:14px; line-height:14px; vertical-align:middle; padding:2px 5px; background-color:#e6e6e6; border-radius:10px;} +.new-class-btn {font-size:15px; color:#fff; background-color:#3b94d6; padding:10px 40px; border-radius:20px; display:inline-block; margin:0 auto;} +.join-class-btn {font-size:15px; color:#444; background-color:#ccc; padding:10px 40px; border-radius:20px; display:inline-block; margin:0 auto;} +.new-class-input {width:60%; color:#aaa; height:35px; line-height:35px; vertical-align:middle; border:none; outline:none;} + +/*20160616登录注册*/ +.login-wrap {padding:0 10px;} +.input-box-wrap {padding-right:17px;} +.input-box {width:100%; height:36px; padding-left:5px; line-height:36px; vertical-align:middle; border:1px solid #ccc; border-radius:5px;} +.login-op-wrap {height:30px; line-height:30px; vertical-align:middle;} +.login-box{display:inline-block; width:14px; height:14px; line-height:14px; text-align:center; vertical-align:middle; border:1px solid #ccc; background:#fff; border-radius:3px; color:#fff; cursor:pointer;} +.login-box.checked{background:#63c360;} +.login-box.checked:after{content:url(/images/wechat/checked.png);} +.forget-psw-wrap {width:60px; margin:0 auto;} +.forget-psw {position:fixed; bottom:10px;} \ No newline at end of file