Merge branch 'guange_dev' into weixin_guange

# Conflicts:
#	Gemfile
#	db/schema.rb
chenlw_dev
guange 10 years ago
parent 6ae4cd0767
commit fbe1b2dac2

@ -7,6 +7,8 @@ module Mobile
require_relative 'apis/upgrade'
require_relative 'apis/homeworks'
require_relative 'apis/comments'
require_relative 'apis/issues'
class API < Grape::API
version 'v1', using: :path
format :json
@ -39,6 +41,7 @@ module Mobile
mount Apis::Upgrade
mount Apis::Homeworks
mount Apis::Comments
mount Apis::Issues
#add_swagger_documentation ({api_version: 'v1', base_path: 'http://u06.shellinfo.cn/trustie/api'})
#add_swagger_documentation ({api_version: 'v1', base_path: '/api'}) if Rails.env.development?

@ -0,0 +1,17 @@
#coding=utf-8
module Mobile
module Apis
class Issues< Grape::API
resources :issues do
desc "get special issuse"
get ':id' do
issue = Issue.find(params[:id])
present :data, issue, with: Mobile::Entities::Issue
present :status, 0
end
end
end
end
end

@ -0,0 +1,9 @@
module Mobile
module Entities
class Issue <Grape::Entity
expose :subject
expose :description
expose :author, using: Mobile::Entities::User
end
end
end

@ -237,7 +237,7 @@ class WechatsController < ActionController::Base
when 'Project'
case user_activity.act_type.to_s
when 'Issue'
[act.project.name.to_s+" | 项目问题", act.subject.to_s, url_to_avatar(act.author),project_issues_url(act.project)]
[act.project.name.to_s+" | 项目问题", act.subject.to_s, url_to_avatar(act.author),"http://wechat.trustie.net/app.html#/issue/#{act.id}"]
end
end
end

@ -0,0 +1,108 @@
/**
* Created by guange on 16/3/19.
*/
var CommentBox = React.createClass({
loadFromServer: function(){
$.ajax({
url: this.props.url,
dataType: 'json',
success: function(data){
this.setState({data: data});
}.bind(this),
error: function(xhr,status,err){
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
onCommentSubmit: function(comment){
console.log(comment);
},
getInitialState: function(){
return {data: []};
},
componentDidMount: function(){
this.loadFromServer();
setInterval(this.loadFromServer, 2000);
},
render: function(){
return(
<div className="commentBox">
<CommentForm onCommentSubmit={this.onCommentSubmit}/>
<CommentList data={this.state.data}/>
</div>
);
}
});
var CommentList = React.createClass({
render: function(){
var commentNodes = this.props.data.map(function(comment){
return (
<Comment author={comment.author}>
{comment.text}
</Comment>
)
});
return (
<div className="commentList">
{commentNodes}
</div>
);
}
});
var CommentForm = React.createClass({
handleSubmit: function(e){
e.preventDefault();
var author = this.refs.author.value.trim();
var text = this.refs.text.value.trim();
if(!text || !author){
return;
}
this.props.onCommentSubmit({author: author, text: text});
this.refs.author.value = '';
this.refs.text.value = '';
return;
},
render: function(){
return (
<form className="commentForm" onSubmit={this.handleSubmit}>
<input type="text" placeholder="Your name" ref="author" />
<input type="text" placeholder="Say something..." ref="text" />
<input type="submit" value="Post" />
</form>
);
}
});
var Comment = React.createClass({
rawMarkup: function() {
var rawMarkup = marked(this.props.children.toString(), {sanitize: true});
return { __html: rawMarkup };
},
render: function(){
return (
<div className="comment">
<h2 className="commentAuthor">
{this.props.author}
</h2>
<span dangerouslySetInnerHTML={this.rawMarkup()}></span>
</div>
)
}
})
React.render(<CommentBox url="api/comment.json"/>, document.getElementById("example"));

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,42 @@
/**
* ReactDOM v0.14.0
*
* Copyright 2013-2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
// Based off https://github.com/ForbesLindesay/umd/blob/master/template.js
;(function(f) {
// CommonJS
if (typeof exports === "object" && typeof module !== "undefined") {
module.exports = f(require('react'));
// RequireJS
} else if (typeof define === "function" && define.amd) {
define(['react'], f);
// <script>
} else {
var g
if (typeof window !== "undefined") {
g = window;
} else if (typeof global !== "undefined") {
g = global;
} else if (typeof self !== "undefined") {
g = self;
} else {
// works providing we're not in "use strict";
// needed for Java 8 Nashorn
// see https://github.com/facebook/react/issues/3037
g = this;
}
g.ReactDOM = f(g.React);
}
})(function(React) {
return React.__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
});

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -0,0 +1,81 @@
/**
* Created by guange on 16/3/21.
*/
var Index = React.createClass({
render: function(){
return (<div>index page</div>);
}
});
var apiUrl = 'http://localhost:3000/api/v1/';
var PostContainer = React.createClass({
loadDataFromServer: function(){
$.ajax({
url: apiUrl + 'issues/' + this.props.params.id,
dataType: 'json',
success: function(data){
this.setState({data: data.data});
}.bind(this),
error: function(xhr,status,err){
console.log(err);
}.bind(this)
})
},
componentDidMount: function(){
this.loadDataFromServer();
},
getInitialState: function(){
return {data: null};
},
render: function(){
return (
<div className="post-container">
<div className="post-wrapper">
<PostView data={this.state.data}/>
</div>
</div>
)
}
});
var PostView = React.createClass({
render: function(){
if(!this.props.data){
return <div></div>
}
return (
<div className="post-main">
<div className="post-avatar fl"><img src={this.props.data.author.img_url} width="45" height="45" className="border-radius" /></div>
<div className="post-title hidden mb5"><span className="c-grey3 f15 fb">{this.props.data.subject}</span></div>
<div className="post-title hidden"><a herf="javascript:void(0);" className="mr10">{this.props.data.author.nickname}</a>项目问题</div>
<div className="cl"></div>
<div className="post-content c-grey2 mt10">
<p className="post-all-content">{this.props.data.description}</p>
</div>
<a herf="javascript:void(0);" className="link-blue f13 fl mt5 post-more undis" style={{textDecoration: 'underline'}}>点击展开</a>
<div className="cl"></div>
<span className="c-grey f13 mt10 fl">{this.props.data.time}</span>
<div className="cl"></div>
</div>
)
}
});
var Route = ReactRouter.Route;
var Router = ReactRouter.Router;
var routes = (
<Router>
<Route path="/" component={Index}/>
<Route path="issue/:id" component={PostContainer} />
</Router>
);
React.render(routes, document.getElementById("container"));

@ -0,0 +1,41 @@
@charset "utf-8";
/* CSS Document */
/*基本样式*/
body,table,input,textarea,select,button { font-family: "微软雅黑","宋体";}
h1,h2,h3,h4,h5,p {padding:0px; margin:0px;}
.f13 {font-size:13px;}
.f15 {font-size:15px;}
.fb {font-weight:bold;}
.mt5 {margin-top:5px;}
.mt10 {margin-top:10px;}
.mb5 {margin-bottom:5px;}
.ml10 {margin-left:10px;}
.mr10 {margin-right:10px;}
.ml15 {margin-left:15px;}
.mr15 {margin-right:15px;}
.c-blue {color:#269ac9;}
.c-grey {color:#9a9a9a;}
.c-grey2 {color:#707070;}
.c-grey3 {color:#555555;}
a:link,a:visited{text-decoration:none;}
a:hover,a:active{cursor:pointer;}
a.link-blue {color:#269ac9;}
.border-radius {border-radius:5px;}
.max-width-60 {max-width:60px;}
.max-width-130 {max-width:130px;}
.hidden {overflow:hidden; white-space:nowrap; text-overflow:ellipsis;}
.inline-block {display:inline-block;}
.undis {display:none;}
/*动态样式*/
.post-container {width:100%;}
.post-wrapper {width:98%; border:1px solid #e6e6e6; border-radius:3px; background-color:#ffffff; margin:15px auto;}
.post-main {padding:10px; color:#9a9a9a;}
.post-avatar {width:45px; height:45px; margin-right:10px;}
.post-title {font-size:13px; text-align:left;}
.fl {float:left;}
.cl {clear:both; overflow:hidden;}
.post-content {width:100%; font-size:13px; line-height:18px; height:90px; overflow:hidden;}
.post-interactive {width:100%; height:35px; line-height:35px; vertical-align:middle; border-top:1px solid #e6e6e6; background-color:#f8f9fb;}
.post-interactive-column {width:50%; text-align:center; float:left; font-size:13px;}
Loading…
Cancel
Save