index.tsx 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import { Button, Col, Row, Image, Spin, Space, Drawer, Empty } from "antd";
  2. import { useEffect, useRef, useState } from "react";
  3. import { MyIcon } from "@/global";
  4. import { useToken } from "@ant-design/pro-components";
  5. function ReadBook(props: { next: (listData: { id: number }) => Promise<any>, listData: any }) {
  6. let { next, listData } = props;
  7. const divRef = useRef<HTMLDivElement>(null);
  8. let { token } = useToken()
  9. const [content, setContent] = useState<any>(null)
  10. useEffect(() => {
  11. const handleKeyDown = (event: KeyboardEvent) => {
  12. if (divRef.current) {
  13. if (event.key === "ArrowDown") {
  14. divRef.current.scrollBy(0, 50);
  15. } else if (event.key === "ArrowUp") {
  16. divRef.current.scrollBy(0, -50);
  17. }
  18. }
  19. };
  20. window.addEventListener("keydown", handleKeyDown);
  21. return () => {
  22. window.removeEventListener("keydown", handleKeyDown);
  23. };
  24. }, []);
  25. async function getBookContent(params: any) {
  26. let content = await next(params)
  27. setContent(content)
  28. }
  29. useEffect(() => {
  30. if (divRef.current) {
  31. divRef.current.scrollTop = 0
  32. }
  33. }, [content, divRef])
  34. return (
  35. listData && <div
  36. style={{ height: '85vh', overflow: 'hidden', display: 'flex', justifyContent: 'space-around' }}
  37. >
  38. <div style={{ width: '20%', flexFlow: 'column', alignItems: 'center', display: 'flex', borderRight: '1px solid #efefef' }}>
  39. <div style={{ marginBottom: 20, marginTop: 20 }}>
  40. {listData?.vipFree && <MyIcon type="icon-vipmianfei" style={{ fontSize: 70, position: 'absolute', zIndex: 1 }} />}
  41. <Image src={listData?.picUrl} style={{ width: 150 }} onError={(e: any) => {
  42. e.target.src = localStorage.getItem("nocover")
  43. }} />
  44. </div>
  45. <Row style={{ width: '80%' }} gutter={[10, 5]}>
  46. <Col span={24} style={{ fontSize: 14, color: token.colorTextSecondary }}><span style={{ color: token.colorText }}><span>作者</span>:</span>{listData?.authorInfo?.authorName}</Col>
  47. <Col span={24} style={{ fontSize: 14, color: token.colorTextSecondary }}><span style={{ color: token.colorText }}><span>类别</span>:</span>{listData?.categoryInfo?.name}</Col>
  48. <Col span={24} style={{ fontSize: 14, color: token.colorTextSecondary }}><span style={{ color: token.colorText }}><span>来源</span>:</span>{({ "UPLOAD": "管理员", "CREATOR": "创作者" } as any)[listData.source]}</Col>
  49. <Col span={24} style={{ fontSize: 14, color: token.colorTextSecondary }}><span style={{ color: token.colorText }}><span>频道</span>:</span>{listData?.corpUserName == 0 ? "男频" : "女频"}</Col>
  50. <Col span={24} style={{ fontSize: 14, color: token.colorTextSecondary }}><span style={{ color: token.colorText }}>标签:</span> {
  51. listData?.labelInfoList?.map((tags: { id: string, name: string }, index: number) => {
  52. return tags?.name
  53. }).join(',')
  54. }</Col>
  55. <Col span={24} style={{ fontSize: 14, color: token.colorTextSecondary }} ><span style={{ color: token.colorText }}><span>状态</span>:</span>{["连载中", "已完结"][listData.bookStatus]}</Col>
  56. <Col span={24} style={{ fontSize: 14, color: token.colorTextSecondary }}><span style={{ color: token.colorText }}>评分:</span>{listData?.score || 0}</Col>
  57. <Col span={24} style={{ fontSize: 14, color: token.colorTextSecondary }}><span style={{ color: token.colorText }}>点击量:</span>{listData?.visitCount || 0}</Col>
  58. <Col span={24} style={{ fontSize: 14, color: token.colorTextSecondary }}><span style={{ color: token.colorText }}>总字数:</span>{listData?.wordCount || 0}</Col>
  59. <Col span={24} style={{ fontSize: 14, color: token.colorTextSecondary }}><span style={{ color: token.colorText }}>上架状态:</span>{["上架中", "已下架"][listData.shelveStatus]}</Col>
  60. <Col span={24} style={{ fontSize: 14, color: token.colorTextSecondary }}><span style={{ color: token.colorText }}>描述:</span>{listData?.bookDesc}</Col>
  61. </Row>
  62. </div>
  63. <div
  64. style={{ overflowY: 'auto', display: 'flex', flexFlow: "column", width: '75%', paddingTop: 20, paddingBottom: 20 }}
  65. ref={divRef}
  66. >
  67. <div >
  68. {listData.list?.map((ele: any, index: number) => (
  69. <a
  70. key={index}
  71. style={{ display: 'inline-block', marginRight: ele.index % 4 === 0 ? 0 : 20, marginBottom: 10, width: 190, overflow: 'hidden' }}
  72. onClick={() => { getBookContent({ bookId: ele?.chapterInfo?.bookId, chapterNo: ele?.chapterInfo?.chapterNo }) }}
  73. >
  74. <div style={{ display: 'flex', alignItems: 'center' }}>
  75. {ele.needPay && <MyIcon type="icon-jiesuo" style={{ marginRight: 5 }} />}
  76. <span >{ele?.chapterInfo?.chapterName}</span>
  77. </div>
  78. </a>
  79. ))}
  80. {listData.list?.length === 0 && <div style={{ width: "100%", height: "100%", marginTop: "10%" }}><Empty description={<Space direction='vertical'><div>暂无章节</div></Space>} /></div>}
  81. </div>
  82. {/* 阅读小说 */}
  83. <Drawer
  84. open={!!content}
  85. placement="right"
  86. onClose={() => { setContent(null) }}
  87. footer={null}
  88. width={'60%'}
  89. destroyOnClose={true}
  90. styles={{ body: { padding: 0 } }}
  91. closeIcon={false}
  92. title={<div style={{ fontSize: 20 }}>{content?.chapterName}</div>}
  93. >
  94. {
  95. content && <>
  96. <div
  97. ref={divRef}
  98. style={{ borderTop: '1px solid #efefef', fontSize: 17, lineHeight: 2, padding: '0 40px', height: '87vh', overflowY: 'auto', paddingBottom: 50, paddingTop: 15, boxSizing: 'border-box' }} dangerouslySetInnerHTML={{ __html: content.content.replace(/\n/g, '<br/>') }}></div>
  99. <div style={{ borderTop: '1px solid #efefef', display: 'flex', justifyContent: 'center' }}>
  100. <Space style={{ marginTop: 15 }}>
  101. {content?.chapterNo > 1 && <Button onClick={() => {
  102. getBookContent({ bookId: content?.bookId, chapterNo: content?.chapterNo - 1 })
  103. }}>上一章</Button>}
  104. {content?.chapterNo < listData?.list?.length && <Button onClick={() => {
  105. getBookContent({ bookId: content?.bookId, chapterNo: content?.chapterNo + 1 })
  106. }}>下一章</Button>}
  107. </Space>
  108. </div>
  109. </>
  110. }
  111. </Drawer>
  112. </div>
  113. </div>
  114. );
  115. }
  116. export default ReadBook;