index.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. import React, {PureComponent} from 'react';
  2. import {connect} from 'react-redux';
  3. import marked from 'marked';
  4. import hljs from 'highlight.js';
  5. import {ArticleWrapper, ArticleTop, MainWrapper} from './style';
  6. import {getTime} from '../../lib/public';
  7. import 'highlight.js/styles/atom-one-dark.css'
  8. import {Spin} from 'antd';
  9. import Tocify from './tocify';
  10. import Comments from './components/Comments';
  11. import axios from "axios";
  12. class Article extends PureComponent {
  13. constructor(props) {
  14. super(props);
  15. this.state = {
  16. content: '',
  17. timg: '',
  18. id: props.match.params.id,
  19. socialsList: [],
  20. tocify: new Tocify()
  21. }
  22. }
  23. render() {
  24. const {content, socialsList} = this.state;
  25. const {name, avatar} = this.props.userInfo.toJS();
  26. this.state.tocify && this.state.tocify.reset();
  27. if (content.title) document.title = content.title;
  28. return (
  29. <ArticleWrapper>
  30. <div className='pattern-center-blank'/>
  31. <ArticleTop>
  32. <div className='pattern-attachment-img'>
  33. <img className='lazyload' src={content && (content.thumbnail || this.state.timg)} alt=""/>
  34. </div>
  35. <div className='single-header'>
  36. <h1 className='entry-title'>{content.title}</h1>
  37. {content && <p className='entry-census'>
  38. <span><img src={avatar} alt=""/></span>
  39. <span>{name}</span>
  40. <span className="bull">·</span>
  41. <span>{getTime(content.createTime)}</span>
  42. <span className="bull">·</span>
  43. <span>{content.views} 次阅读</span></p>
  44. }
  45. </div>
  46. </ArticleTop>
  47. <MainWrapper>
  48. {content ?
  49. <div className='flex-items'>
  50. <div className='cell'>
  51. <div className='entry-content'
  52. dangerouslySetInnerHTML={{__html: marked(content.content)}}
  53. />
  54. {this.setSocials(socialsList)}
  55. <Comments id={this.state.id} isComment={content.isComment}/>
  56. </div>
  57. {this.state.tocify && this.state.tocify.render()}
  58. </div> : this.Spin()
  59. }
  60. </MainWrapper>
  61. </ArticleWrapper>
  62. )
  63. }
  64. componentDidMount() {
  65. const renderer = new marked.Renderer();
  66. renderer.heading = (text, level) => {
  67. const anchor = this.state.tocify.add(text, level);
  68. return `<h${level} id="${anchor}">${text}</h${level}>`;
  69. };
  70. marked.setOptions({
  71. renderer: renderer,
  72. highlight: code => hljs.highlightAuto(code).value
  73. });
  74. this.getDetail(this.state.id);
  75. this.getTimg();
  76. this.getSocials();
  77. }
  78. getTimg() {
  79. const list = this.props.topImg;
  80. const num = this.getrand(0, list.length - 1);
  81. this.setState({
  82. timg: list[num].img
  83. })
  84. }
  85. getDetail(id) {
  86. axios.get('/posts/posts/v1/' + id).then((res) => {
  87. if (res.success === 1) {
  88. this.setState({
  89. content: res.model
  90. })
  91. }else {
  92. this.props.history.push('/404');
  93. }
  94. });
  95. }
  96. getSocials(){
  97. axios.get('/social/social/v1/socials?code=reward').then((res) => {
  98. if (res.success === 1) {
  99. this.setState({
  100. socialsList: res.models
  101. })
  102. }
  103. });
  104. }
  105. setSocials(socialsList){
  106. if(socialsList.length){
  107. return(
  108. <div className='single-reward'>
  109. <div className='reward-open'>
  110. <p>赏</p>
  111. <div className='reward-main'>
  112. <ul className='reward-row'>
  113. {socialsList.map((item,index)=>{
  114. return(
  115. <li key={index}>
  116. <img src={item.content} alt=""/>
  117. <p>{item.remark}</p>
  118. </li>
  119. )
  120. })}
  121. </ul>
  122. </div>
  123. </div>
  124. </div>
  125. )
  126. }else {
  127. return null
  128. }
  129. }
  130. getrand(m, n) {
  131. return Math.floor(Math.random() * (n - m + 1)) + m;
  132. }
  133. Spin() {
  134. return (
  135. <div className="example">
  136. <Spin size="large"/>
  137. </div>
  138. )
  139. }
  140. }
  141. const mapState = (state) => {
  142. return {
  143. topImg: state.getIn(['image', 'topImg']),
  144. userInfo: state.getIn(['header', 'userInfo']),
  145. }
  146. };
  147. export default connect(mapState)(Article);