react help pages

dev_hss
p31729568 6 years ago
parent a60195f660
commit df66bde600

@ -0,0 +1,44 @@
class HelpsController < ApplicationController
before_action :require_login, only: [:feedback]
helper_method :current_help
def about
render_ok(content: current_help&.about_us)
end
def contact
@cooperations = Cooperation.all.group(:user_type)
end
def cooperatives
@data = { 'alliance_coop' => [], 'com_coop' => [], 'edu_coop' => [] }
@data = @data.merge CooImg.all.group_by(&:img_type)
end
def agreement
render_ok(content: current_help&.agreement)
end
def help_center
render_ok(content: current_help&.help_center)
end
def feedback
content = "<p>[#{params[:question_kind]}]</p><p>问题页面网址:#{params[:url]}</p>#{params[:description]}"
ActiveRecord::Base.transaction do
attr = { sender_id: User.current.id, receiver_id: 1, content: content, send_time: Time.now }
PrivateMessage.create!(attr.merge(user_id: User.current.id, target_id: 1, status: 1))
PrivateMessage.create!(attr.merge(user_id: 1, target_id: User.current.id, status: 0))
end
render_ok
end
private
def current_help
@_current_help ||= Help.first
end
end

@ -258,7 +258,7 @@ module TidingDecorator
def manager_join_project_content
project = Project.find_by(id: container_id)
I18n.t(locale_format(extra)) % [user&.show_real_name, project.name]
I18n.t(locale_format(extra)) % [trigger_user&.show_real_name, project.name]
end
def reporter_join_project_content

@ -0,0 +1,8 @@
json.contacts do
json.array! @cooperations.each do |item|
json.extract! item, :name, :qq, :mail
json.type item.user_type_text
end
end
json.address current_help.status

@ -0,0 +1,11 @@
json.data do
json.array! @data.each do |type, objs|
json.name I18n.t("enumerize.coo_img.img_type.#{type}")
json.values do
json.array! objs.sort_by(&:position).each do |obj|
json.img obj.url_states || (Util::FileManage.exist?('CooImg', obj.id) ? Util::FileManage.disk_file_url('CooImg', obj.id) : '')
json.url obj.src_states
end
end
end
end

File diff suppressed because it is too large Load Diff

@ -256,6 +256,12 @@ const Topicbank= Loadable({
loader: () => import('./modules/topic_bank/Topic_bank'),
loading: Loading,
})
const Help = Loadable({
loader: () => import('./modules/help/Help'),
loading: Loading,
})
class App extends Component {
constructor(props) {
super(props)
@ -513,6 +519,10 @@ class App extends Component {
(props)=>(<Messagerouting {...this.props} {...props} {...this.state}></Messagerouting>)
}
></Route>
<Route path="/help/:type"
render={
(props)=>(<Help {...this.props} {...props} {...this.state}></Help>)
}/>
<Route exact path="/" component={ShixunsHome}/>
<Route component={Shixunnopage}/>

@ -0,0 +1,12 @@
import Loadable from 'react-loadable';
import Loading from "./Loading";
const CustomLoadable = (loader, loading = Loading) => {
return Loadable({
loader,
loading
})
}
export default CustomLoadable

@ -0,0 +1,53 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Card } from "antd";
import axios from 'axios';
import { MarkdownToHtml } from 'educoder';
class AboutUs extends React.Component {
constructor (props) {
super(props);
this.state = {
loading: true,
content: null
}
}
componentDidMount(){
this.getContent();
}
getContent(){
axios.get("/helps/about.json").then((result) => {
if(result){
this.setState({
content: result.data.content,
loading: false
})
}
}).catch((error) => {
console.log(error);
this.setState({ loading: false });
})
}
render() {
let { loading, content } = this.state;
return (
<div>
<div className="about-us-container">
<Card title="关于我们" bordered={false} loading={loading} style={{ minHeight: 600 }}>
<div className="about-us-content">
{ content && <MarkdownToHtml content={content} selector="work_content" className=""></MarkdownToHtml> }
</div>
</Card>
</div>
</div>
)
}
}
export default AboutUs;

@ -0,0 +1,53 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Card } from "antd";
import axios from 'axios';
import { MarkdownToHtml } from 'educoder';
class Agreement extends React.Component {
constructor (props) {
super(props);
this.state = {
loading: true,
content: null
}
}
componentDidMount(){
this.getContent();
}
getContent(){
axios.get("/helps/agreement.json").then((result) => {
if(result){
this.setState({
content: result.data.content,
loading: false
})
}
}).catch((error) => {
console.log(error);
this.setState({ loading: false });
})
}
render() {
let { loading, content } = this.state;
return (
<div>
<div className="agreement-container">
<Card title="服务协议" bordered={false} loading={loading} style={{ minHeight: 600 }}>
<div className="agreement-content">
{ content && <MarkdownToHtml content={content} selector="work_content" className=""></MarkdownToHtml> }
</div>
</Card>
</div>
</div>
)
}
}
export default Agreement;

@ -0,0 +1,24 @@
.contact-us-container {
}
.contact-us-container .contact-item {
padding: 20px 15px;
border-bottom: 1px solid #EEEEEE;
}
.contact-us-container .contact-item:first-child {
padding-top: 0;
}
.contact-us-container .contact-item:last-child {
border-bottom: unset;
}
.contact-us-container .contact-item-label {
font-size: 16px;
padding-bottom: 10px;
}
.contact-us-container .contact-item-content {
margin-left: 10px;
}
.contact-us-container .contact-item-content .ant-row {
margin-top: 10px;
}

@ -0,0 +1,88 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Card, Row, Col } from "antd";
import axios from 'axios';
import './ContactUs.css';
class ContactUs extends React.Component {
constructor (props) {
super(props);
this.state = {
loading: true,
contacts: null,
address: null
}
}
componentDidMount(){
this.getData();
}
getData(){
axios.get("/helps/contact.json").then((result) => {
if(result){
this.setState({
contacts: result.data.contacts,
address: result.data.address,
loading: false
})
}
}).catch((error) => {
console.log(error);
this.setState({ loading: false });
})
}
render() {
let { loading, contacts, address } = this.state;
return (
<div>
<div className="contact-us-container">
<Card title="联系我们" bordered={false} loading={loading} style={{ minHeight: 600 }}>
<div className="contact-us-content">
{
contacts && contacts.map((item, _key) => {
return (
<div className="contact-item">
<div className="contact-item-label">{ item.type }</div>
<div className="contact-item-content">
<Row>
<Col span={12}>{ item.name }</Col>
</Row>
<Row>
<Col span={2}>QQ</Col>
<Col span={10}>{ item.qq }</Col>
</Row>
<Row>
<Col span={2}>Email</Col>
<Col span={10}>{ item.mail }</Col>
</Row>
</div>
</div>
)
})
}
{
address && (
<div className="contact-item">
<div className="contact-item-label">公司地址</div>
<div className="contact-item-content">
<Row>
<Col span={12}>{ address }</Col>
</Row>
</div>
</div>
)
}
</div>
</Card>
</div>
</div>
)
}
}
export default ContactUs;

@ -0,0 +1,17 @@
.cooperatives-container {
}
.cooperatives-container .cooperative-item-title {
margin-bottom: 20px;
font-size: 16px;
}
.cooperatives-container .cooperative-item-list-item {
padding: 10px 0;
height: 60px;
border: 1px solid #eee;
}
.cooperatives-container .cooperative-item-list-item img {
width: 100%;
height: 100%;
}

@ -0,0 +1,81 @@
import React from 'react';
import PropTypes from 'prop-types';
import { List, Card } from "antd";
import axios from 'axios';
import { getImageUrl } from 'educoder';
import './Cooperatives.css';
class Cooperatives extends React.Component {
constructor (props) {
super(props);
this.state = {
loading: true,
data: [
{ name: "产学联盟" },
{ name: "知名企业" },
{ name: "各类院校" }
]
}
}
componentDidMount(){
this.getCooperatives();
}
getCooperatives(){
axios.get("/helps/cooperatives.json").then((result) => {
if(result){
this.setState({
data: result.data.data,
loading: false
})
}
}).catch((error) => {
console.log(error);
this.setState({ loading: false });
})
}
render() {
let { loading, data } = this.state;
return (
<div>
<div className="cooperatives-container">
<Card title="合作伙伴" bordered={false} loading={loading} style={{ minHeight: 600 }}>
<div className="cooperatives-content">
{
data && data.length > 0 && data.map((item, _key) => {
return (
<div className="cooperative-item">
<div className="cooperative-item-title">{ item.name }</div>
<div className="cooperative-item-list">
<List
grid={{ gutter: 16, column: 4 }}
dataSource={item.values}
renderItem={obj => (
<List.Item>
<div className="cooperative-item-list-item">
<a href={obj.url || 'javascript:void(0)'} target={obj.url && '_blank'}>
<img className="" height="90" src={getImageUrl(obj.img)} />
</a>
</div>
</List.Item>
)}
/>
</div>
</div>
)
})
}
</div>
</Card>
</div>
</div>
)
}
}
export default Cooperatives;

@ -0,0 +1,7 @@
.feedback-container {
}
.feedback-container .feedback-message {
line-height: 26px;
color: #999999;
}

@ -0,0 +1,47 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import { Card, Form } from "antd";
import "./Feedback.css";
import FeedbackForm from './FeedbackForm';
const NewFeedbackForm = Form.create({ name: 'feedback_form' })(FeedbackForm);
class Feedback extends React.Component {
constructor (props) {
super(props);
}
componentDidUpdate(prevProps) {
if (prevProps.current_user !== this.props.current_user) {
if(!this.props.checkIfLogin()) {
this.props.showLoginDialog();
}
}
}
render() {
return (
<div>
<div className="feedback-container">
<Card title="意见反馈" bordered={false} style={{ minHeight: 600 }}>
<div className="feedback-content ml20">
<div className="feedback-message mb20">
想对我们的平台提供功能建议<br/>
发现网页中的问题或bug想告诉我们<br/>
期望与我们展开合作<br/>
在这里把你想说的一切告诉我们吧
</div>
<div className="feedback-help color-orange mb20">* <Link to="/help/help_center" className="color-orange">看看帮助中心是否有你想要的答案</Link></div>
<NewFeedbackForm {...this.props}/>
</div>
</Card>
</div>
</div>
)
}
}
export default Feedback;

@ -0,0 +1,87 @@
import React from 'react';
import { Form, Input, Radio, Button } from "antd";
import axios from 'axios';
const { TextArea } = Input;
class FeedbackForm extends React.Component {
constructor (props) {
super(props);
}
handleSubmit = e => {
e.preventDefault();
this.props.form.validateFields((err, fieldsValue) => {
if(err){ return }
axios.post("/helps/feedback.json", fieldsValue)
.then((result) => {
if (result.status === 200 && result.data.status === 0) {
this.props.history.push(`/messages/${this.props.current_user.login}/message_detail?target_ids=1`);
}
}).catch((error) => {
console.log(error)
})
})
}
render() {
const { getFieldDecorator } = this.props.form;
return (
<div className="feedback-form">
<Form onSubmit={this.handleSubmit}>
<Form.Item label="问题分类">
{getFieldDecorator('question_kind', {
initialValue: "登录注册",
rules: [
{
required: true,
message: '不能为空',
},
],
})(
<Radio.Group>
<Radio value="登录注册">登录注册</Radio>
<Radio value="信息认证">信息认证</Radio>
<Radio value="实训编程">实训编程</Radio>
<Radio value="实训课程">实训课程</Radio>
<Radio value="课堂">课堂</Radio>
<Radio value="其它">其它</Radio>
</Radio.Group>
)}
</Form.Item>
<Form.Item label="问题页面网址">
{getFieldDecorator('url', {
rules: [
{
required: true,
message: '不能为空',
},
],
})(<Input placeholder="反馈平台问题,请同时填写对应的问题页面链接,以便平台能够及时跟踪解决,谢谢" />)}
</Form.Item>
<Form.Item label="问题描述">
{getFieldDecorator('description', {
rules: [
{
required: true,
message: '不能为空',
},
],
})(<TextArea rows={4} placeholder="反馈平台问题,请同时填写对应的问题页面链接,以便平台能够及时跟踪解决,谢谢" />)}
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">提交</Button>
</Form.Item>
</Form>
</div>
)
}
}
export default FeedbackForm;

@ -0,0 +1,9 @@
.help-container {
margin-top: 30px;
}
.help-container .help-menu {
text-align: center;
}
.help-container .help-content {
margin-bottom: 40px;
}

@ -0,0 +1,70 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Switch, Route, Link } from 'react-router-dom';
import { Affix, Menu, Row, Col } from "antd";
import { SnackbarHOC } from 'educoder';
import './Help.css';
import CustomLoadable from "../../CustomLoadable";
import {TPMIndexHOC} from "../tpm/TPMIndexHOC";
const AboutUs = CustomLoadable(() => import('./AboutUs'));
const ContactUs = CustomLoadable(() => import('./ContactUs'));
const Cooperatives = CustomLoadable(() => import('./Cooperatives'));
const Agreement = CustomLoadable(() => import('./Agreement'));
const HelpCenter = CustomLoadable(() => import('./HelpCenter'));
const Feedback = CustomLoadable(() => import('./Feedback'));
class Help extends React.Component {
constructor (props) {
super(props);
this.state = {
type: props.match.params.type
}
}
render() {
return (
<div className="newMain clearfix">
<div className="educontent help-container">
<Row gutter={{ xs: 8, sm: 16, md: 24, lg: 32 }}>
<Col span={4}>
<Affix offsetTop={20}>
<div className="help-menu">
<Menu
mode="inline"
defaultSelectedKeys={[this.state.type || 'about_us']}>
<Menu.Item key="about_us"><Link to="/help/about_us">关于我们</Link></Menu.Item>
<Menu.Item key="contact_us"><Link to="/help/contact_us">联系我们</Link></Menu.Item>
<Menu.Item key="cooperatives"><Link to="/help/cooperatives">合作伙伴</Link></Menu.Item>
<Menu.Item key="agreement"><Link to="/help/agreement">服务协议</Link></Menu.Item>
<Menu.Item key="help_center"><Link to="/help/help_center">帮助中心</Link></Menu.Item>
<Menu.Item key="feedback"><Link to="/help/feedback">意见反馈</Link></Menu.Item>
</Menu>
</div>
</Affix>
</Col>
<Col span={20}>
<div className="help-content">
<Switch>
<Route path='/help/about_us' component={AboutUs}></Route>
<Route path='/help/contact_us' component={ContactUs}></Route>
<Route path='/help/cooperatives' component={Cooperatives}></Route>
<Route path='/help/agreement' component={Agreement}></Route>
<Route path='/help/help_center' component={HelpCenter}></Route>
<Route path='/help/feedback' render={ (props)=>(<Feedback {...this.props} {...props} {...this.state}></Feedback>) }></Route>
<Route component={AboutUs}/>
</Switch>
</div>
</Col>
</Row>
</div>
</div>
)
}
}
export default SnackbarHOC() (TPMIndexHOC ( Help ));

@ -0,0 +1,53 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Card } from "antd";
import axios from 'axios';
import { MarkdownToHtml } from 'educoder';
class HelpCenter extends React.Component {
constructor (props) {
super(props);
this.state = {
loading: true,
content: null
}
}
componentDidMount(){
this.getContent();
}
getContent(){
axios.get("/helps/help_center.json").then((result) => {
if(result){
this.setState({
content: result.data.content,
loading: false
})
}
}).catch((error) => {
console.log(error);
this.setState({ loading: false });
})
}
render() {
let { loading, content } = this.state;
return (
<div>
<div className="help-center-container">
<Card title="帮助中心" bordered={false} loading={loading} style={{ minHeight: 600 }}>
<div className="help-center-content">
{ content && <MarkdownToHtml content={content} selector="work_content" className=""></MarkdownToHtml> }
</div>
</Card>
</div>
</div>
)
}
}
export default HelpCenter;

@ -1,5 +1,6 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import { Link } from 'react-router-dom';
import { getImageUrl, toPath } from 'educoder'
import PropTypes from 'prop-types';
@ -29,12 +30,12 @@ class NewFooter extends Component {
</div> */}
<ul className="clearfix inner-footernav">
<li><a href="/" className="fl" target="_blank">网站首页</a></li>
<li><a href={this.props.Footerdown===undefined?"":this.props.Footerdown.about_us} className="fl" target="_blank">关于我们</a></li>
<li><a href={this.props.Footerdown===undefined?"":this.props.Footerdown.connect_us} className="fl" target="_blank">联系我们</a></li>
<li><a href={this.props.Footerdown===undefined?"":this.props.Footerdown.cooperation_partner} className="fl" target="_blank">合作伙伴</a></li>
<li><a href={this.props.Footerdown===undefined?"":this.props.Footerdown.service_agreement} className="fl" target="_blank">服务协议</a></li>
<li><a href={this.props.Footerdown===undefined?"":this.props.Footerdown.help_center} className="fl" target="_blank">帮助中心</a></li>
<li><a href={this.props.Footerdown===undefined?"":this.props.Footerdown.feedback} className="fl" target="_blank">意见反馈</a></li>
<li><Link to="/help/about_us" className="fl" target="_blank">关于我们</Link></li>
<li><Link to="/help/contact_us" className="fl" target="_blank">联系我们</Link></li>
<li><Link to="/help/cooperatives" className="fl" target="_blank">合作伙伴</Link></li>
<li><Link to="/help/agreement" className="fl" target="_blank">服务协议</Link></li>
<li><Link to="/help/help_center" className="fl" target="_blank">帮助中心</Link></li>
<li><Link to="/help/feedback" className="fl" target="_blank">意见反馈</Link></li>
</ul>
</div>
<div>

Loading…
Cancel
Save