ChapterDetail.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. <template>
  2. <van-pull-refresh v-model="loading" disabled style="min-height:100vh">
  3. <div class="chapter-detail-page" v-if="info" :style="{paddingBottom:$store.state.hzyb.audioData.url&&'80px'}">
  4. <div :class="['main-box',!info.auth_ok&&'main-box-noauth']">
  5. <!-- <div class="title">【第{{info.report_chapter_item.stage}}期 | {{info.report_chapter_item.classify_name_first}} | {{info.report_chapter_item.type_name}}】{{info.report_chapter_item.title}}</div> -->
  6. <div class="title">{{title}}</div>
  7. <div class="flex time">
  8. <span>{{info.report_chapter_item.author}}</span>
  9. <span>{{formatTime(info.report_chapter_item.publish_time)}}</span>
  10. </div>
  11. <!-- 音频模块 -->
  12. <AudioBox :audioData="audioData" v-if="info.report_chapter_item.video_url&&info.report_chapter_item.video_play_seconds>0"></AudioBox>
  13. <div class="flex tips">
  14. <div>
  15. <div class="abstract" v-if="info.report_chapter_item.abstract">摘要:{{info.report_chapter_item.abstract}}</div>
  16. <div>
  17. <span>注:请务必阅读</span>
  18. <span style="color: #e3b377; margin-left: 20px" @click="showDisclaimers = true">免责声明</span>
  19. </div>
  20. </div>
  21. </div>
  22. <div class="rich-content">
  23. <!-- <div v-html="info.report_chapter_item.content" v-if="info.auth_ok"></div> -->
  24. <div v-if="info.auth_ok">
  25. <ul>
  26. <li v-for="item in realContent" :key="item" v-html="item"></li>
  27. </ul>
  28. </div>
  29. <div v-html="info.report_chapter_item.content_sub" v-else ></div>
  30. </div>
  31. <!-- 指标数据模块 -->
  32. <div class="ticker-wrap" v-if="tickerInfo">
  33. <div class="top-title">{{tickerInfo.ticker_title.report_chapter_type_name}}数据表</div>
  34. <div class="table-box">
  35. <div class="table-row table-head">
  36. <div class="table-item" v-for="item in tickerHead" :key="item.key">{{item.label}}</div>
  37. </div>
  38. <div class="table-row table-body" v-for="(tr,index) in tickerInfo.list" :key="tr.base_column_name">
  39. <div :class="['table-item',index%2==0?'grey':'',tr[td.key]<0?'minus':'']" v-for="td in tickerHead" :key="td.key">{{tr[td.key]}}</div>
  40. </div>
  41. </div>
  42. <div v-if="tickerInfo.ticker_title.report_chapter_type_id ===26" style="text-align:center;font-weight:bold">注:与新加坡TSR20相关数据均取展示日期前一交易日数据</div>
  43. </div>
  44. <!-- 无权限 -->
  45. <div class="no-auth-wrap" v-if="!info.auth_ok">
  46. <div class="apply-box" v-if="info.permission_check.type=='apply'">
  47. <div>您暂无权限查看报告,若想查看请申请开通</div>
  48. <div class="btn" @click="handleGoApply">立即申请</div>
  49. </div>
  50. <div class="apply-box" v-else>
  51. <div>您暂无权限查看报告 </div>
  52. <div>若想查看请联系对口销售:{{info.permission_check.name}}</div>
  53. <a class="btn" :href="'tel:'+info.permission_check.mobile" tag="div">立即联系</a>
  54. </div>
  55. </div>
  56. </div>
  57. <!-- 章节详情底部快速切换 -->
  58. <div class="chapter-list-wrap" v-if="fromPage=='reportdetail'">
  59. <div class="top-text">更多</div>
  60. <van-row gutter="10">
  61. <van-col span="6" v-for="item in info.report_chapter_menu_list" :key="item.report_chapter_id">
  62. <div :class="['item',item.report_chapter_id==chapterId&&'active']" @click="handleChapterChange(item)">
  63. <img :src="item.report_chapter_type_thumb+'?t='+new Date().getTime()" mode="aspectFill"/>
  64. <!-- <text>{{item.report_chapter_type_name}}</text> -->
  65. </div>
  66. </van-col>
  67. </van-row>
  68. </div>
  69. <!-- 返回顶部 -->
  70. <img v-if="showToTop&&info.auth_ok" @click="handleBackTop" class="back-top-img" src="@/assets/hzyb/report/back-top.png" mode="aspectFill"/>
  71. <!-- 免责声明 -->
  72. <van-popup :show="showDisclaimers" @close="showDisclaimers = false" round closeable>
  73. <div class="disclaimers-box">
  74. <div style="text-align: center; font-size: 16px; font-weight: bold; margin-bottom: 20px">免责声明</div>
  75. <div style="margin-bottom: 10rpx">1、本报告仅供弘则弥道(上海)投资咨询有限公司正式签约的机构客户使用,不会仅因接收人/接受机构收到本报告而将其视为客户。</div>
  76. <div style="margin-bottom: 10rpx"
  77. >2、本报告根据国际和行业通行的准则,以合法渠道获得这些信息,尽可能保证可靠、准确和完整,但并不保证报告所述信息的准确性和完整性,也不保证本报告所包含的信息或建议在本报告发出后不会发生任何变更。本报告中所提供的信息仅供参考。</div
  78. >
  79. <div style="margin-bottom: 10rpx"
  80. >3、报告中的内容不对投资者做出的最终操作建议做任何的担保,也没有任何形式的分享投资收益或者分担投资损失的书面或口头承诺。不作为客户在投资、法律、会计或税务等方面的最终操作建议,也不作为道义的、责任的和法律的依据或者凭证,无论是否已经明示或者暗示。</div
  81. >
  82. <div style="margin-bottom: 10rpx">4、在任何情况下,本公司不对客户/接受人/接受机构因使用报告中内容所引致的一切损失负责任,客户/接受人/接受机构需自行承担全部风险。</div>
  83. </div>
  84. </van-popup>
  85. <!-- 申请提示弹窗 -->
  86. <van-popup :show="pupData.show" @close="pupData.show=false" :close-on-click-overlay="false">
  87. <div class="global-pup">
  88. <div class="content">
  89. <div v-html="pupData.content"></div>
  90. </div>
  91. <div class="flex bot">
  92. <div @click="pupData.show=false">知道了</div>
  93. </div>
  94. </div>
  95. </van-popup>
  96. </div>
  97. </van-pull-refresh>
  98. </template>
  99. <script>
  100. // 由于当时写在uni中 直接复制过来的 也不想改了就写成vue2形式吧
  101. import moment from 'moment'
  102. import 'moment/dist/locale/zh-cn'
  103. moment.locale('zh-cn')
  104. import { apiGetNewChapterReport,apiGetEdbData } from '@/api/hzsl/report'
  105. import {apiApplyPermission} from '@/api/hzyb/user'
  106. import {Popup,Image as VanImage,PullRefresh,Col, Row} from 'vant'
  107. import AudioBox from '@/views/hzyb/report/components/AudioBox.vue'
  108. import _ from 'lodash';
  109. export default {
  110. components:{
  111. [Popup.name]:Popup,
  112. [VanImage.name]:VanImage,
  113. [PullRefresh.name]:PullRefresh,
  114. [Col.name]:Col,
  115. [Row.name]:Row,
  116. [PullRefresh.name]:PullRefresh,
  117. AudioBox,
  118. },
  119. data() {
  120. return {
  121. showDisclaimers: false, //显示免责声明
  122. chapterId:0,
  123. fromPage:'',//如果是从首页(home)来的则隐藏底部切换 message定位到留言板
  124. info:null,
  125. title:'',
  126. audioData:{},//音频数据
  127. tickerInfo:null,
  128. tickerHead:[],
  129. pupData:{
  130. show:false,
  131. content:'',//弹窗html字符串
  132. },
  133. loading:false,
  134. showToTop:false,
  135. totalContent:[],
  136. realContent:[],
  137. page_no: 0,
  138. pageSize: 20,//默认初始加载20个p标签
  139. total_page: 0,
  140. };
  141. },
  142. created(options) {
  143. this.fromPage = this.$route.query.fromPage || ''
  144. this.getDetail()
  145. },
  146. mounted(){
  147. $(document).on('click', '.rich-content img',function(event) {
  148. let imgArray = [];
  149. let curImageSrc = $(this).attr('src');
  150. let oParent = $(this).parent();
  151. if (curImageSrc && !oParent.attr('href')) {
  152. $('.rich-content img').each(function(index, el) {
  153. let itemSrc = $(this).attr('src');
  154. imgArray.push(itemSrc);
  155. });
  156. wx.previewImage({current:curImageSrc,urls:imgArray});
  157. }
  158. })
  159. window.addEventListener('scroll',this.loadMoreHandle)
  160. },
  161. destroyed () {
  162. window.removeEventListener('scroll',this.loadMoreHandle)
  163. },
  164. methods: {
  165. async getDetail(){
  166. const params = this.$route.query;
  167. const res=await apiGetNewChapterReport(params)
  168. if(res.code===200){
  169. this.info=res.data
  170. this.audioData={
  171. auth_ok:res.data.auth_ok,
  172. video_name:res.data.report_chapter_item.video_name,
  173. video_play_seconds:res.data.report_chapter_item.video_play_seconds,
  174. video_url:res.data.report_chapter_item.video_url,
  175. video_img:res.data.report_chapter_item.video_img
  176. }
  177. document.title=res.data.report_chapter_item.classify_name_first
  178. if(res.data.auth_ok&&res.data.report_chapter_item.classify_name_first==='晨报'){
  179. this.getTickerValue()
  180. }
  181. this.splitContentHandle(this.info.report_chapter_item.content)
  182. if(!res.data.auth_ok){
  183. // 获取详情如果为联系销售根据判断条件是否主动申请一次
  184. if(this.info.permission_check.type=='contact'&&!this.info.permission_check.customer_info.has_apply){
  185. if(this.info.permission_check.customer_info.status=='冻结'||(this.info.permission_check.customer_info.status=='试用'&&this.info.permission_check.customer_info.is_suspend==1)){
  186. apiApplyPermission({
  187. company_name:this.info.permission_check.customer_info.company_name,
  188. real_name:this.info.permission_check.customer_info.name,
  189. source:4,
  190. from_page:'报告详情'
  191. }).then(res=>{
  192. if(res.code===200){
  193. console.log('主动申请成功');
  194. }
  195. })
  196. }
  197. }
  198. }
  199. this.title=`【第${res.data.report_chapter_item.stage}期 | ${res.data.report_chapter_item.classify_name_first} | ${res.data.report_chapter_item.type_name}】${res.data.report_chapter_item.title}(${moment(res.data.report_chapter_item.publish_time).format('MMDD')})`
  200. }
  201. },
  202. /*内容分割*/
  203. splitContentHandle(content) {
  204. const arr = content.split('</p>');
  205. this.totalContent = arr.map(_ => _+'</p>');
  206. this.realContent = this.totalContent.slice(0,this.pageSize)
  207. this.total_page = parseInt(this.totalContent.length / this.pageSize) + 1;
  208. },
  209. /* 加载下一页内容 */
  210. loadContent() {
  211. this.realContent = this.realContent.concat(this.totalContent.slice(this.page_no*this.pageSize, (this.page_no + 1)*this.pageSize))
  212. },
  213. loadMoreHandle: _.throttle(function() {
  214. const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; // 滚动的高度
  215. if(scrollTop>window.outerHeight){
  216. this.showToTop=true
  217. }else{
  218. this.showToTop=false
  219. }
  220. if(this.page_no >= this.total_page) return
  221. const clientHeight = document.documentElement.clientHeight || document.body.clientHeight; // 可视高度
  222. const scrollHeight = document.body.scrollHeight; // 总高度
  223. const bufferHeight = 400;
  224. if((scrollHeight - scrollTop - clientHeight) < bufferHeight+100) {
  225. console.log('触底')
  226. this.page_no = this.page_no+1;
  227. this.loadContent();
  228. }
  229. },300),
  230. //获取晨报中指标数据
  231. async getTickerValue(){
  232. let params = this.info.ticker_data_param
  233. const res=await apiGetEdbData(params)
  234. if(res.code===200){
  235. if(!res.data||!res.data.list) return
  236. this.tickerInfo=res.data
  237. if(res.data.ticker_title.report_chapter_type_id===17){
  238. this.tickerHead=[
  239. {
  240. label:res.data.ticker_title.ticker_title,
  241. key:'base_column_name'
  242. },
  243. {
  244. label:'公布日期',
  245. key:'date'
  246. },
  247. {
  248. label:'最新值',
  249. key:'ticker_value'
  250. },
  251. {
  252. label:'上期值',
  253. key:'last_value',
  254. }
  255. ]
  256. }else{
  257. this.tickerHead=[
  258. {
  259. label:res.data.ticker_title.ticker_title,
  260. key:'base_column_name'
  261. },
  262. {
  263. label:res.data.list[0].date,
  264. key:'ticker_value'
  265. },
  266. {
  267. label:'当日涨跌',
  268. key:'dd_value'
  269. },
  270. {
  271. label:'一周涨跌',
  272. key:'ww_value'
  273. },
  274. {
  275. label:'一月涨跌',
  276. key:'mm_value'
  277. }
  278. ]
  279. }
  280. }
  281. },
  282. handleBackTop() {
  283. document.body.scrollTop=document.documentElement.scrollTop=0
  284. },
  285. //格式化音频时间
  286. formatVoiceTime(e){
  287. let minus=parseInt(e/60)
  288. let sec=parseInt(e%60)
  289. return `${minus>9?minus:'0'+minus}分${sec>9?sec:'0'+sec}秒`
  290. },
  291. formatTime(time){
  292. return moment(time).format('YYYY.MM.DD HH:mm:ss')
  293. },
  294. handleChapterChange({http_url}){
  295. let params = http_url.split("?")[1];
  296. location.href = `${http_url}&fromPage=reportdetail`;
  297. // location.href=`${location.origin}/xcx_h5/hzsl/report/new/chapter/detail?${params}&fromPage=reportdetail`
  298. },
  299. //点击申请
  300. async handleGoApply(){
  301. if(this.info.permission_check.type=='apply'){
  302. if(this.info.permission_check.customer_info.has_apply){// 已经申请过
  303. this.pupData.show=true
  304. this.pupData.content=`<p>您已提交过申请,请耐心等待</p>`
  305. }else{
  306. this.pupData.show=true
  307. this.pupData.content=`<p>若想查看请联系对口销售</p>`
  308. }
  309. }
  310. },
  311. },
  312. };
  313. </script>
  314. <style lang="scss" scoped>
  315. /* 公共弹窗 */
  316. .global-pup{
  317. background-color: #fff;
  318. width: 90vw;
  319. min-height: 200px;
  320. font-size: 32px;
  321. .content{
  322. padding: 34px;
  323. text-align: center;
  324. min-height: 250px;
  325. display: flex;
  326. align-items: center;
  327. text-align: center;
  328. line-height: 1.7;
  329. div{
  330. flex: 1;
  331. }
  332. }
  333. .bot{
  334. border-top: 1px solid #dedede;
  335. div{
  336. line-height: 96px;
  337. flex: 1;
  338. text-align: center;
  339. border-right: 1px solid #dedede;
  340. color:#E3B377;
  341. }
  342. div:last-child {
  343. border: none;
  344. }
  345. }
  346. }
  347. .flex{
  348. display: flex;
  349. }
  350. .chapter-detail-page {
  351. // padding-bottom: 50px;
  352. .main-box{
  353. padding: 34px;
  354. }
  355. .main-box-noauth{
  356. height: 100vh;
  357. overflow: hidden;
  358. }
  359. .title{
  360. font-size: 40px;
  361. font-weight: bold;
  362. margin-bottom: 30px;
  363. display: inline;
  364. margin-left: -26px;
  365. }
  366. .time{
  367. justify-content: space-between;
  368. font-size: 30px;
  369. margin-top: 30px;
  370. }
  371. .tips{
  372. font-size: 34px;
  373. margin-bottom: 51px;
  374. &::before{
  375. content: '';
  376. width: 10px;
  377. // height: 50px;
  378. display: inline-block;
  379. background-color: #E3B377;
  380. margin-right: 20px;
  381. // position: relative;
  382. // top: 10px;
  383. }
  384. .abstract{
  385. font-size: 34px;
  386. margin-bottom: 20px;
  387. line-height: 1.5;
  388. }
  389. }
  390. .disclaimers-box{
  391. width: 94vw;
  392. padding: 32px;
  393. }
  394. .rich-content{
  395. line-height: 1.8;
  396. font-size: 36px;
  397. :deep(img){
  398. width: 100% !important;
  399. }
  400. :deep(span){
  401. font-size: 36px !important;
  402. line-height: 1.8 !important;
  403. }
  404. :deep(p){
  405. font-size: 36px !important;
  406. line-height: 1.8 !important;
  407. }
  408. :deep(iframe){
  409. width: 100% !important;
  410. }
  411. }
  412. .no-auth-wrap{
  413. min-height: 200px;
  414. background: linear-gradient(360deg, #FFFFFF 60%, rgba(255, 255, 255, 0) 88%);
  415. // position: relative;
  416. // top: -150px;
  417. padding: 0 34px 50px 34px;
  418. position: fixed;
  419. left: 0;
  420. right: 0;
  421. bottom: 0;
  422. z-index: 99;
  423. text-align: center;
  424. font-size: 32px;
  425. color: #E3B377;
  426. .apply-box{
  427. padding-top: 250px;
  428. }
  429. .btn{
  430. width: 100%;
  431. margin-left: auto;
  432. margin-right: auto;
  433. line-height: 80px;
  434. background-color: #E6B77D;
  435. border-radius: 4px;
  436. color: #fff;
  437. margin-top: 100px;
  438. display: block;
  439. }
  440. }
  441. .back-top-img{
  442. position: fixed;
  443. z-index: 99;
  444. width: 76px;
  445. height: 76px;
  446. right: 34px;
  447. bottom: 150px;
  448. }
  449. .chapter-list-wrap {
  450. background-color: #f5f6fa;
  451. padding: 34px;
  452. min-height: 300px;
  453. .top-text {
  454. text-align: center;
  455. color: #666666;
  456. margin-bottom: 30px;
  457. &::before {
  458. content: "";
  459. width: 90px;
  460. height: 1px;
  461. background-color: #999;
  462. display: inline-block;
  463. vertical-align: middle;
  464. margin-right: 10px;
  465. }
  466. &::after {
  467. content: "";
  468. width: 90px;
  469. height: 1px;
  470. background-color: #999;
  471. display: inline-block;
  472. vertical-align: middle;
  473. margin-left: 10px;
  474. }
  475. }
  476. .item {
  477. background-color: #fff;
  478. height: 156px;
  479. margin-bottom: 20px;
  480. text-align: center;
  481. color: #C0CFDA;
  482. font-size: 24px;
  483. // padding-top: 20px;
  484. border-radius: 8px;
  485. overflow: hidden;
  486. img{
  487. width: 156px;
  488. height: 156px;
  489. display: block;
  490. margin-left: auto;
  491. margin-right: auto;
  492. object-fit: cover;
  493. }
  494. }
  495. .active{
  496. border: 1px solid #E3B377;
  497. position: relative;
  498. &::before{
  499. content: '';
  500. display: block;
  501. position: absolute;
  502. left: 0;
  503. top: 0;
  504. width: 0;
  505. height: 0;
  506. border-top: 46px solid #E3B377;
  507. border-right: 46px solid transparent;
  508. }
  509. }
  510. }
  511. .ticker-wrap{
  512. margin-top: 30px;
  513. .top-title{
  514. text-align: center;
  515. font-size: 36px;
  516. font-weight: bold;
  517. vertical-align: middle;
  518. &::before,&::after{
  519. content: '';
  520. display: inline-block;
  521. width: 100px;
  522. height: 4px;
  523. background-color:rgb(204, 204, 204);
  524. vertical-align: middle;
  525. margin: 0 20px;
  526. }
  527. }
  528. .table-box{
  529. margin: 20px 0;
  530. &::-webkit-scrollbar{
  531. width: 0;
  532. }
  533. overflow: auto hidden;
  534. .table-row{
  535. display: flex;
  536. width: 100%;
  537. }
  538. .table-item{
  539. padding: 10px;
  540. min-width: 200px;
  541. max-width: 280px;
  542. display: flex;
  543. align-items: center;
  544. justify-content: center;
  545. }
  546. .table-head{
  547. color: #fff;
  548. background-color: rgb(58, 76, 115);
  549. .table-item{
  550. &:first-child{
  551. position: sticky;
  552. left: 0;
  553. z-index: 5;
  554. border-right-color: rgb(58, 76, 115);
  555. }
  556. background-color: rgb(58, 76, 115);
  557. }
  558. }
  559. .table-body{
  560. .table-item{
  561. background-color: #fff;
  562. &:first-child{
  563. position: sticky;
  564. left: 0;
  565. z-index: 5;
  566. }
  567. }
  568. .grey{
  569. background-color: #ddd;
  570. }
  571. .minus{
  572. color: #006600;
  573. }
  574. }
  575. }
  576. }
  577. }
  578. </style>