Detail.vue 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246
  1. <template>
  2. <van-pull-refresh v-model="loading" disabled style="min-height:100vh">
  3. <!-- <div class="content-swipe" v-if="bannerDataList.length > 0">
  4. <van-swipe class="my-swipe" :autoplay="4000" :show-indicators="false">
  5. <van-swipe-item v-for="item in bannerDataList" :key="item.id" @click="bannerSwiperHandler(item)">
  6. <img :src="item.image_url_mobile" />
  7. </van-swipe-item>
  8. </van-swipe>
  9. </div> -->
  10. <div class="report-detail-page" @click="closeAttention" v-if="info" :style="{paddingBottom:$store.state.hzyb.audioData.url&&'80px'}">
  11. <!-- 晨报、周报章节 -->
  12. <div class="chapter-list-wrap" v-if="info.report_info.has_chapter&&info.report_detail_show_type===2">
  13. <div class="top-box" :style="'background-image:url(' + info.report_info.banner_url + ')'">
  14. <div class="title">{{info.report_info.classify_name_first}}</div>
  15. <div class="sub-title">{{info.report_info.title}}</div>
  16. <div class="flex top-bot">
  17. <div class="flex time-box">
  18. <div class="day">{{formatChapterTime(info.report_info.publish_time,'day')}}</div>
  19. <div>
  20. <div>{{formatChapterTime(info.report_info.publish_time,'week')}}</div>
  21. <div>{{formatChapterTime(info.report_info.publish_time,'year-month')}}</div>
  22. </div>
  23. </div>
  24. <div class="audio-play-list-box" @click="handleGoSetAudioList" v-if="info.report_info.classify_name_first=='周报'&&info.auth_ok">播放清单</div>
  25. <div class="attention-box" v-if="showAttention">
  26. 点击<span style="color:#E3B377">播放清单</span>,打开章节列表,进行<span style="color:#E3B377">播放清单配置</span>
  27. <img class="close-icon" src="@/assets/hzyb/report/close.png" alt="" @click.stop="closeAttention">
  28. </div>
  29. </div>
  30. <div :class="['stage-num',info.report_info.classify_name_first=='晨报'?'stage-num-day':'']">第{{info.report_info.stage}}期</div>
  31. </div>
  32. <div class="list-box">
  33. <div class="flex item" v-for="item in chapterList" :key="item.report_chapter_id" @click="goChapterDetail(item)">
  34. <div class="img-box">
  35. <van-image class="img" :src="item.report_chapter_type_thumb" mode="aspectFill" />
  36. </div>
  37. <div class="con">
  38. <div class="title">
  39. {{item.report_chapter_type_name}}
  40. <text class="tag" :style="{backgroundColor:getTagColor(tag)}" v-for="tag in item.trend.split(',')" :key="tag">{{tag}}</text>
  41. </div>
  42. <div class="van-multi-ellipsis--l2 sub-title">{{item.title}}</div>
  43. <div class="update-time">更新至:{{formatChapterTime(item.publish_time,'year-month-day')}}</div>
  44. <div
  45. :class="['audio-icon-box',item.video_url==$store.state.hzyb.audioData.list[$store.state.hzyb.audioData.index]?.url?'audio-icon-box_active':'']"
  46. v-if="info.report_info.classify_name_first=='周报'&&item.is_close==0"
  47. @click.stop="handlePlayWeekAudio(item)"
  48. ></div>
  49. </div>
  50. </div>
  51. </div>
  52. <!-- 无权限 -->
  53. <div class="no-auth-box" v-if="!info.auth_ok">
  54. <img class="img" src="https://hzstatic.hzinsights.com/static/icon/hzyb/activity_no_auth.png" mode="widthFix" />
  55. <div class="apply-box" v-if="info.permission_check.type=='apply'">
  56. <div>您暂无权限查看报告,若想查看请申请开通</div>
  57. <div class="btn" @click="handleGoApply">立即申请</div>
  58. </div>
  59. <div class="apply-box" v-else>
  60. <div>您暂无权限查看报告 </div>
  61. <div>若想查看请联系对口销售:{{info.permission_check.name}}</div>
  62. <a class="btn" :href="'tel:'+info.permission_check.mobile" tag="div">立即联系</a>
  63. </div>
  64. </div>
  65. </div>
  66. <!-- 报告详情 -->
  67. <div :class="['main-box',!info.auth_ok&&'main-box-noauth']" v-else>
  68. <!-- <div class="title">【第{{info.report_info.stage}}期|{{info.report_info.classify_name_second}}】{{info.report_info.title}}</div> -->
  69. <div :style="{backgroundColor:info.report_info.canvas_color||''}">
  70. <!-- 无版头板尾显示标题 -->
  71. <template v-if="(!info.report_info.head_img) && (!info.report_info.end_img)">
  72. <div class="title">{{title}}</div>
  73. <div class="flex time">
  74. <span>{{info.report_info.author}}</span>
  75. <span>{{formatTime(info.report_info.publish_time)}}</span>
  76. </div>
  77. </template>
  78. <!-- 拼接版头 -->
  79. <div class="html-head-img-box" v-if="info.auth_ok&&info.report_info.head_img">
  80. <img :src="info.report_info.head_img" alt="" style="display:block;width:100%">
  81. <div class="head-layout-item" v-for="item in headImgStyle" :key="item.value"
  82. :style="{fontFamily:item.family,fontSize:(item.size*2)+'px',fontWeight:item.weight,textAlign:item.align,color:item.color,
  83. width:item.width,height:item.height,left:item.left,top:item.top
  84. }">
  85. {{ layoutBaseInfo[item.value] }}
  86. </div>
  87. </div>
  88. <!-- 音频模块 -->
  89. <AudioBox :audioData="audioData" v-if="info.report_info.video_url&&info.report_info.video_play_seconds>0"></AudioBox>
  90. <div class="flex tips">
  91. <div style="flex:1">
  92. <div v-if="info.road_video_id">点击<span style="color: #e3b377;" @click="goVideoPage">查看视频</span></div>
  93. <div class="abstract" v-if="info.report_info.abstract">摘要:{{info.report_info.abstract}}</div>
  94. <div>
  95. <span v-if="disclaimer">注:请务必阅读</span>
  96. <span v-if="disclaimer" style="color:#E3B377;margin-left:20px" @click="showDisclaimers=true">免责声明</span>
  97. <span
  98. v-if="info.report_info.video_url&&info.report_info.video_play_seconds>0"
  99. style="float:right;background:#E3B377;color:#fff;border-radius:30px;padding:0 10px;font-size:0.9em" @click="handlePlayAudioBG"
  100. >背景播放</span>
  101. </div>
  102. </div>
  103. </div>
  104. <div id="report-rich-content" class="rich-content" style="position: relative;" ref="richConBox">
  105. <!-- 单人报告 -->
  106. <template v-if="info.auth_ok">
  107. <div v-if="!info.report_info.has_chapter">
  108. <ul>
  109. <li v-for="item in realContent" :key="item" v-html="item"></li>
  110. </ul>
  111. </div>
  112. <!-- 展示拼接的章节报告 -->
  113. <template v-if="info.report_info.has_chapter && info.report_detail_show_type===1">
  114. <div
  115. class="chapter-concat-item"
  116. v-for="chapter in info.report_chapter_list"
  117. :key="chapter.report_chapter_id"
  118. >
  119. <div class="chapter-title">
  120. <h3 class="chapter-title-text">{{chapter.title}}</h3>
  121. </div>
  122. <div class="html-cont" v-html="chapter.content"></div>
  123. </div>
  124. </template>
  125. </template>
  126. <div v-html="info.report_info.content_sub" v-else></div>
  127. <!-- 隐藏的水印 -->
  128. <div class="hide-watermark-box" v-if="userInfo">
  129. <div v-for="item in 20" :key="item">{{userInfo.mobile}}</div>
  130. </div>
  131. </div>
  132. <!-- 拼接版尾 -->
  133. <div class="html-end-img-box" v-if="info.auth_ok&&info.report_info.end_img">
  134. <img :src="info.report_info.end_img" alt="" style="display:block;width:100%">
  135. <div class="head-layout-item" v-for="item in endImgStyle" :key="item.value"
  136. :style="{fontFamily:item.family,fontSize:(item.size*2)+'px',fontWeight:item.weight,textAlign:item.align,color:item.color,
  137. width:item.width,height:item.height,left:item.left,top:item.top
  138. }">
  139. {{ layoutBaseInfo[item.value] }}
  140. </div>
  141. </div>
  142. </div>
  143. <!-- 无权限 -->
  144. <div class="no-auth-wrap" v-if="!info.auth_ok">
  145. <div class="apply-box" v-if="info.permission_check.type=='apply'">
  146. <div>您暂无权限查看报告,若想查看请申请开通</div>
  147. <div class="btn" @click="handleGoApply">立即申请</div>
  148. </div>
  149. <div class="apply-box" v-else>
  150. <div>您暂无权限查看报告 </div>
  151. <div>若想查看请联系对口销售:{{info.permission_check.name}}</div>
  152. <a class="btn" :href="'tel:'+info.permission_check.mobile" tag="div">立即联系</a>
  153. </div>
  154. </div>
  155. <!-- 右侧悬浮操作栏 -->
  156. <div class="right-fix-box">
  157. <!-- 收藏 -->
  158. <img v-if="info.auth_ok" @click="handleCollect" class="item collect-icon" :src="info.collection_id>0?collectIcons:collectIcon" alt="">
  159. <!-- ppt -->
  160. <img class="item ppt-icon" v-if="hasPPt" @click="goPPtDetail" src="@/assets/hzyb/report/ppt-icon.png" alt="">
  161. <!-- 分享海报 -->
  162. <SharePoster
  163. v-if="info.auth_ok"
  164. :isSlot="true"
  165. :shareData="{
  166. type:'report_detail',
  167. code_page:'pages-report/reportDetail',
  168. code_scene:code_scene,
  169. data:posterParams
  170. }"
  171. >
  172. <img class="item share-icon" src="@/assets/hzyb/share-poster-icon.png"/>
  173. </SharePoster>
  174. <!-- 返回顶部 -->
  175. <div class="item back-top-img">
  176. <img v-show="showToTop&&info.auth_ok" @click="handleBackTop" class="back-top-img" src="@/assets/hzyb/report/back-top.png"/>
  177. </div>
  178. </div>
  179. </div>
  180. <!-- 留言点赞模块 -->
  181. <div id="messgaeBoardCont" v-if="info.auth_ok && (!info.report_info.has_chapter||info.report_detail_show_type===1)">
  182. <LeaveMessage
  183. :info="info"
  184. @like_change="giveOrCancelLike"
  185. />
  186. </div>
  187. <!-- 免责声明 -->
  188. <Disclaimer v-model:show="showDisclaimers"/>
  189. <!-- 申请提示弹窗 -->
  190. <van-popup :show="pupData.show" @close="pupData.show=false" :close-on-click-overlay="false">
  191. <div class="global-pup">
  192. <div class="content">
  193. <div v-html="pupData.content"></div>
  194. </div>
  195. <div class="flex bot">
  196. <div @click="pupData.show=false">知道了</div>
  197. </div>
  198. </div>
  199. </van-popup>
  200. </div>
  201. <reportCancel v-if="isReportPublishCancel"/>
  202. </van-pull-refresh>
  203. </template>
  204. <script>
  205. // 由于当时写在uni中 直接复制过来的 也不想改了就写成vue2形式吧
  206. import moment from 'moment'
  207. import 'moment/dist/locale/zh-cn'
  208. moment.locale('zh-cn')
  209. import {addTokenToIframe} from '../utils/common'
  210. import { apiBaseConfig } from '@/api/hzyb/common'
  211. import {apiReportDetail,apiRddpShareImg,apiReportPPtImgs,apiPublicBannerMark,apiPublicBannerList} from '@/api/hzyb/report'
  212. import {apiApplyPermission,apiUserInfo,apiSetCollect,apiCancelCollect} from '@/api/hzyb/user'
  213. import {Popup,Image as VanImage,PullRefresh,Dialog, Toast,Swipe, SwipeItem} from 'vant'
  214. import AudioBox from './components/AudioBox.vue'
  215. import SharePoster from '../components/SharePoster.vue'
  216. import _ from 'lodash';
  217. import LeaveMessage from '../components/leaveMessage/index.vue'
  218. import collectIcon from '@/assets/hzyb/collect-icon.png'
  219. import collectIcons from '@/assets/hzyb/collect-icon-s.png'
  220. import reportCancel from './components/reportCancel.vue'
  221. import Disclaimer from '../components/Disclaimer.vue'
  222. export default {
  223. components:{
  224. [Popup.name]:Popup,
  225. [VanImage.name]:VanImage,
  226. [PullRefresh.name]:PullRefresh,
  227. [Swipe.name]:Swipe,
  228. [SwipeItem.name]:SwipeItem,
  229. [Dialog.name]:Dialog,
  230. AudioBox,
  231. SharePoster,
  232. LeaveMessage,
  233. reportCancel,
  234. Disclaimer
  235. },
  236. computed:{
  237. code_scene(){
  238. return JSON.stringify({
  239. reportId:this.reportId
  240. })
  241. },
  242. posterParams(){
  243. return {
  244. report_type:this.info.report_info.classify_name_first,
  245. // report_title:`【第${this.info.report_info.stage}期 | ${this.info.report_info.classify_name_second}】${this.info.report_info.title}`,
  246. report_title:this.title,
  247. report_abstract:this.info.report_info.content
  248. }
  249. }
  250. },
  251. data () {
  252. return {
  253. showDisclaimers:false,//显示免责声明
  254. reportId:0,
  255. info:null,
  256. title:'',//标题数据
  257. audioData:{},//音频数据
  258. chapterList:[],
  259. pupData:{
  260. show:false,
  261. content:'',//弹窗html字符串
  262. },
  263. loading:false,
  264. showToTop:false,
  265. totalContent:[],
  266. realContent:[],
  267. page_no: 0,
  268. pageSize: 20,//默认初始加载20个p标签
  269. total_page: 0,
  270. fromPage: '', // message定位到留言板
  271. hasPPt:false,//是否有ppt
  272. userInfo:null,
  273. shareData:{},//分享的数据传给ppt页
  274. collectIcon,
  275. collectIcons,
  276. showAttention:false,//是否显示配置播放清单提示
  277. isReportPublishCancel:false,//报告取消发布
  278. bannerDataList:[],
  279. headImgStyle:null,//版头style
  280. endImgStyle:null,//版尾style
  281. layoutBaseInfo:{
  282. 研报标题:'',
  283. 研报作者:'',
  284. 创建时间:''
  285. },
  286. disclaimer:''//免责声明
  287. }
  288. },
  289. beforeCreate(){
  290. if(this.$route.query.token){
  291. localStorage.setItem('hzyb-token',this.$route.query.token)
  292. localStorage.setItem('hzyb-userId',this.$route.query.userId)
  293. }
  294. },
  295. created(options) {
  296. this.reportId=this.$route.query.reportId
  297. this.fromPage = this.$route.query.fromPage || ''
  298. this.getDetail()
  299. this.getUserInfo()
  300. this.getConfig()
  301. // this.getBannerList()
  302. },
  303. mounted(){
  304. $(document).on('click', '.rich-content img',function(event) {
  305. let imgArray = [];
  306. let curImageSrc = $(this).attr('src');
  307. let oParent = $(this).parent();
  308. if (curImageSrc && !oParent.attr('href')) {
  309. $('.rich-content img').each(function(index, el) {
  310. let itemSrc = $(this).attr('src');
  311. imgArray.push(itemSrc);
  312. });
  313. wx.previewImage({current:curImageSrc,urls:imgArray});
  314. }
  315. })
  316. window.addEventListener('scroll',this.loadMoreHandle)
  317. },
  318. destroyed () {
  319. window.removeEventListener('scroll',this.loadMoreHandle)
  320. },
  321. methods: {
  322. // banner 获取列表
  323. async getBannerList(){
  324. console.log(112233333);
  325. const res = await apiPublicBannerList()
  326. if(res.code ===200){
  327. this.bannerDataList = res.data
  328. }
  329. },
  330. getConfig() {
  331. apiBaseConfig().then(res => {
  332. if (res.code == 200) {
  333. this.disclaimer = res.data.disclaimer
  334. }
  335. })
  336. },
  337. // banner 点击事件
  338. async bannerSwiperHandler(item){
  339. const res = await apiPublicBannerMark({
  340. first_source: 1, //一级来源 1小程序移动 2小程序pc 3研报官网
  341. second_source: 2, //二级来源 1首页 2研报详情页
  342. id:item.id
  343. })
  344. if(res.code===200){
  345. wx.miniProgram.navigateTo({
  346. url:"/pages-report/disseminatePage/disseminatePage?imgHb="+item.jump_url_mobile+'&title='+item.remark
  347. })
  348. }
  349. },
  350. // 点击开始播放周报的列表中的音频
  351. handlePlayWeekAudio(e){
  352. const arr=[]
  353. this.chapterList.forEach(item=>{
  354. if(item.is_close==0){
  355. arr.push({
  356. url:item.video_url,
  357. videoTime:item.video_play_seconds,
  358. videoName:item.video_name,
  359. videoImg:'https://hzstatic.hzinsights.com/static/yb_wx/report_list_zhou.png'
  360. })
  361. }
  362. })
  363. console.log(arr);
  364. let index=0
  365. arr.forEach((_item,idx)=>{
  366. if(_item.url==e.video_url) index=idx
  367. })
  368. this.$store.commit('hzyb/addAudio',{
  369. list:arr,
  370. index:index
  371. })
  372. },
  373. // 设置周报的播放清单
  374. handleGoSetAudioList(){
  375. wx.miniProgram.navigateTo({
  376. url:`/pages-report/audioPlayListSet?reportId=${this.reportId}`,
  377. })
  378. },
  379. closeAttention(){
  380. if(this.info.report_info.classify_name_first=='晨报'&&!this.info.auth_ok) return
  381. localStorage.setItem('showAttention','true')
  382. this.showAttention=false
  383. },
  384. //背景音频播放报告音频
  385. handlePlayAudioBG(){
  386. wx.miniProgram.navigateTo({
  387. url:`/pages-report/reportBgAudio?chapterId=0&reportId=${this.reportId}&ctime=${parseInt(this.$store.state.hzyb.videoCtime)}`,
  388. })
  389. },
  390. async getUserInfo(){
  391. const res=await apiUserInfo()
  392. if(res.code===200){
  393. this.userInfo=res.data
  394. if(this.userInfo.is_bind===0){
  395. Dialog.confirm({
  396. title:'温馨提示',
  397. message:'为了优化您的用户体验,\n 请登录后查看更多信息!',
  398. confirmButtonText:'去登录',
  399. confirmButtonColor:'#E6B77D',
  400. cancelButtonColor:'#666'
  401. }).then(res=>{
  402. wx.miniProgram.reLaunch({url:'/pages/login'})
  403. })
  404. }
  405. }
  406. },
  407. // 页面滚动
  408. // handelPageScroll(){
  409. // const top=document.documentElement.scrollTop||document.body.scrollTop
  410. // if(top>window.outerHeight){
  411. // this.showToTop=true
  412. // }else{
  413. // this.showToTop=false
  414. // }
  415. // },
  416. //跳转ppt预览页
  417. goPPtDetail(){
  418. wx.miniProgram.navigateTo({
  419. url:`/pages-report/previewImage?reportId=${this.reportId}&chapterId=0&shareImg=${this.shareData.shareImg}&shareTitle=${this.shareData.title}`,
  420. })
  421. },
  422. //获取报告对应的ppt图片
  423. async getReportPPtImg(){
  424. const res=await apiReportPPtImgs({
  425. report_id:Number(this.reportId),
  426. report_chapter_id:0
  427. })
  428. if(res.code===200&&res.data.length>0){
  429. this.hasPPt=true
  430. }
  431. },
  432. //跳转线上路演
  433. goVideoPage(){
  434. wx.miniProgram.navigateTo(
  435. {
  436. url:`/pages-roadShow/video/list?videoId=${this.info.road_video_id}&chart_permission_id=${-1}&fromPage=report`
  437. }
  438. )
  439. },
  440. //获取报告详情
  441. async getDetail(){
  442. const res=await apiReportDetail({report_id:Number(this.reportId)})
  443. if(res.code===200){
  444. this.info=res.data
  445. this.headImgStyle=res.data.report_info.head_style?JSON.parse(res.data.report_info.head_style):[]
  446. this.endImgStyle=res.data.report_info.end_style?JSON.parse(res.data.report_info.end_style):[]
  447. this.layoutBaseInfo['研报标题']=res.data.report_info.title
  448. this.layoutBaseInfo['研报作者']=res.data.report_info.author
  449. // 已发布已通过的报告才显示发布时间
  450. this.layoutBaseInfo['创建时间']=moment(res.data.report_info.publish_time).format('YYYY.MM.DD HH:mm')
  451. this.audioData={
  452. auth_ok:res.data.auth_ok,
  453. video_name:res.data.report_info.video_name||`${res.data.report_info.title}(${moment(res.data.report_info.publish_time).format('MMDD')})`,
  454. video_play_seconds:res.data.report_info.video_play_seconds,
  455. video_url:res.data.report_info.video_url,
  456. video_img:res.data.report_info.video_img
  457. }
  458. this.chapterList=res.data.report_chapter_list
  459. document.title = res.data.report_info.classify_name_first||'';
  460. //非章节报告处理内容分页
  461. (!res.data.report_info.has_chapter) && this.splitContentHandle(this.info.report_info.content);
  462. //章节拼接报告拼接iframe token
  463. if(res.data.report_info.has_chapter&&res.data.report_detail_show_type===1) {
  464. res.data.report_chapter_list.forEach(chapter => {
  465. chapter.content = addTokenToIframe(chapter.content,this.reportId,chapter.report_chapter_id)
  466. })
  467. }
  468. if(!res.data.auth_ok){
  469. // 获取详情如果为联系销售根据判断条件是否主动申请一次
  470. if(this.info.permission_check.type=='contact'&&!this.info.permission_check.customer_info.has_apply){
  471. if(this.info.permission_check.customer_info.status=='冻结'||(this.info.permission_check.customer_info.status=='试用'&&this.info.permission_check.customer_info.is_suspend==1)){
  472. apiApplyPermission({
  473. company_name:this.info.permission_check.customer_info.company_name,
  474. real_name:this.info.permission_check.customer_info.name,
  475. source:4,
  476. from_page:'报告详情'
  477. }).then(res=>{
  478. if(res.code===200){
  479. console.log('主动申请成功');
  480. }
  481. })
  482. }
  483. }
  484. }
  485. if(res.data.auth_ok){
  486. this.getReportPPtImg()
  487. this.$nextTick(()=>{
  488. this.waterMark(res.data.permission_check.customer_info.mobile,this.$refs.richConBox)
  489. })
  490. }
  491. // 处理报告标题数据
  492. // if(!this.info.report_info.has_chapter){
  493. const time=moment(res.data.report_info.publish_time).format('MMDD')
  494. if(res.data.report_info.classify_name_second==res.data.report_info.title){
  495. this.title=`【第${res.data.report_info.stage}期】${res.data.report_info.title}(${time})`
  496. }else{
  497. this.title=`【第${res.data.report_info.stage}期|${res.data.report_info.classify_name_second}】${res.data.report_info.title}(${time})`
  498. }
  499. // }
  500. //向小程序发送分享数据
  501. //处理分享标题
  502. let shareTitle=''
  503. let shareImg=''
  504. let imgText=''//分享图上需要显示的内容
  505. const shareTime=moment(res.data.report_info.publish_time).format('MMDD')
  506. if(res.data.report_info.abstract){
  507. shareTitle=res.data.report_info.abstract
  508. imgText=`<div style="font-size:78px">第${res.data.report_info.stage}期 | ${res.data.report_info.title}(${shareTime})</div>`
  509. }else{
  510. shareTitle=res.data.report_info.title
  511. imgText=`<div style="font-size:78px">${moment(res.data.report_info.publish_time).format('YYYY/MM/DD')}</div><div style="font-size:78px">第${res.data.report_info.stage}期 | ${res.data.report_info.classify_name_second}</div>`
  512. if(this.info.report_info.has_chapter){
  513. imgText=`<div style="font-size:78px">${moment(res.data.report_info.publish_time).format('YYYY/MM/DD')}</div><div style="font-size:78px">第${res.data.report_info.stage}期 | ${res.data.report_info.classify_name_first} </div>`
  514. }
  515. }
  516. const rddpImgRes=await apiRddpShareImg({
  517. pars:JSON.stringify({
  518. title:imgText,
  519. time_format:moment(res.data.report_info.publish_time).format('YYYY/MM/DD'),
  520. background_img:res.data.report_info.share_bg_img
  521. })
  522. })
  523. if(rddpImgRes.code===200){
  524. shareImg=rddpImgRes.data
  525. }
  526. this.shareData={
  527. title:shareTitle,
  528. reportId:this.reportId,
  529. shareImg:shareImg
  530. }
  531. wx.miniProgram.postMessage({
  532. data: {
  533. title:shareTitle,
  534. reportId:this.reportId,
  535. shareImg:shareImg
  536. }
  537. });
  538. // 周报判断是否要显示提示
  539. if(res.data.report_info.classify_name_first=='周报'){
  540. const showAtt=localStorage.getItem('showAttention')||""
  541. if(showAtt){
  542. this.showAttention=false
  543. }else{
  544. this.showAttention=true
  545. }
  546. }
  547. }else if(res.code===4002){
  548. this.isReportPublishCancel=true
  549. }
  550. },
  551. //添加水印
  552. waterMark(text,target){
  553. if(!target) return
  554. const canvas = document.createElement("canvas");
  555. const ctx = canvas.getContext("2d");
  556. ctx.font = "18px Arial";
  557. ctx.rotate((-45 * Math.PI) / 200);
  558. ctx.fillStyle='#F1F1F1'
  559. ctx.fillText(text, 30, 200);
  560. ctx.fillText(text, -40, 100);
  561. // 将canvas的内容转换为base64编码
  562. const data = canvas.toDataURL("image/png");
  563. target.style.background = "url(" + data + ") repeat";
  564. },
  565. // 智能布局内容排版全部变成1个1行的顺排
  566. formatSmartStyle() {
  567. this.$nextTick(() =>{
  568. $('.report-drag-item-wrap_child-wrap').css({
  569. 'flex-wrap': 'wrap',
  570. });
  571. $('.report-drag-item-wrap_child-wrap').children().css({
  572. 'flex': 'none',
  573. 'width': '100%'
  574. });
  575. })
  576. },
  577. /*内容分割*/
  578. splitContentHandle(content) {
  579. content=addTokenToIframe(content,this.reportId,0)
  580. const arr = content.split('</p>');
  581. this.totalContent = arr.map(_ => _+'</p>');
  582. this.realContent = this.totalContent.slice(0,this.pageSize)
  583. this.total_page = parseInt(this.totalContent.length / this.pageSize) + 1;
  584. this.formatSmartStyle()
  585. },
  586. /* 加载下一页内容 */
  587. loadContent() {
  588. this.realContent = this.realContent.concat(this.totalContent.slice(this.page_no*this.pageSize, (this.page_no + 1)*this.pageSize))
  589. this.formatSmartStyle()
  590. },
  591. loadMoreHandle: _.throttle(function() {
  592. const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; // 滚动的高度
  593. if(scrollTop>window.outerHeight){
  594. this.showToTop=true
  595. }else{
  596. this.showToTop=false
  597. }
  598. if(this.page_no >= this.total_page) return
  599. const clientHeight = document.documentElement.clientHeight || document.body.clientHeight; // 可视高度
  600. const scrollHeight = document.body.scrollHeight; // 总高度
  601. const bufferHeight = 400;
  602. if((scrollHeight - scrollTop - clientHeight) < bufferHeight+100) {
  603. console.log('触底')
  604. this.page_no = this.page_no+1;
  605. this.loadContent();
  606. }
  607. },300),
  608. //返回顶部
  609. handleBackTop(){
  610. document.body.scrollTop=document.documentElement.scrollTop=0
  611. },
  612. //跳转章节详情
  613. goChapterDetail(item){
  614. // this.$router.push({
  615. // path:'/hzyb/report/chapterdetail',
  616. // query:{
  617. // chapterId:item.report_chapter_id
  618. // }
  619. // })
  620. wx.miniProgram.navigateTo({
  621. url:`/pages-report/chapterDetail?chapterId=${item.report_chapter_id}&fromPage=reportdetail`
  622. })
  623. },
  624. // 格式化时间
  625. formatTime(time){
  626. return moment(time).format('YYYY.MM.DD HH:mm:ss')
  627. },
  628. //格式化音频时间
  629. formatVoiceTime(e){
  630. let minus=parseInt(e/60)
  631. let sec=parseInt(e%60)
  632. return `${minus>9?minus:'0'+minus}分${sec>9?sec:'0'+sec}秒`
  633. },
  634. // 格式化章节列表时间
  635. formatChapterTime(time,type){
  636. if(type==='day'){
  637. return moment(time).format('DD')
  638. }
  639. if(type==='week'){
  640. return moment(time).format('dddd')
  641. }
  642. if(type==='year-month'){
  643. return moment(time).format('YYYY-MM')
  644. }
  645. if(type==='year-month-day'){
  646. return moment(time).format('YYYY-MM-DD')
  647. }
  648. },
  649. // 联系销售
  650. // handleContact(){
  651. // uni.makePhoneCall({
  652. // phoneNumber: this.info.permission_check.mobile
  653. // });
  654. // },
  655. //点击申请
  656. async handleGoApply(){
  657. if(this.userInfo.is_bind===0){
  658. Dialog.confirm({
  659. title:'温馨提示',
  660. message:'为了优化您的用户体验,\n 请登录后查看更多信息!',
  661. confirmButtonText:'去登录',
  662. confirmButtonColor:'#E6B77D',
  663. cancelButtonColor:'#666'
  664. }).then(res=>{
  665. wx.miniProgram.reLaunch({url:'/pages/login'})
  666. })
  667. return
  668. }
  669. if(this.info.permission_check.type=='apply'){
  670. if(this.info.permission_check.customer_info.has_apply){// 已经申请过
  671. this.pupData.show=true
  672. this.pupData.content=`<p>您已提交过申请,请耐心等待</p>`
  673. }else{
  674. if(!this.info.permission_check.customer_info.status||this.info.permission_check.customer_info.status!='流失'||this.info.permission_check.customer_info.status!='关闭'){
  675. wx.miniProgram.redirectTo({
  676. url:"/pages-applyPermission/applyPermission?source=4&from_page=报告详情"
  677. })
  678. }else{//主动调一次申请权限接口
  679. const res=await apiApplyPermission({
  680. company_name:this.info.permission_check.customer_info.company_name,
  681. real_name:this.info.permission_check.customer_info.name,
  682. source:4,
  683. from_page:'报告详情'
  684. })
  685. if(res.code===200){
  686. this.pupData.show=true
  687. this.pupData.content=`<p>申请已提交</p><p>请等待销售人员与您联系</p>`
  688. this.getDetail()
  689. }
  690. }
  691. }
  692. }
  693. },
  694. /* 点赞/取消点赞 */
  695. giveOrCancelLike({like_enabled,like_num}) {
  696. this.info.like_num = like_num;
  697. this.info.like_enabled = like_enabled;
  698. },
  699. onRefresh() {
  700. this.getDetail()
  701. setTimeout(() => {
  702. this.loading=false
  703. }, 1500);
  704. },
  705. // 设置tag颜色
  706. getTagColor(str){
  707. if( str.includes('多')||str.includes('强')||str.includes('反弹') ){
  708. return "#DF6051";
  709. }else if( str.includes('空')||str.includes('调整') ){
  710. return "#6FC5B4";
  711. }else{
  712. return "#009fe6";
  713. }
  714. },
  715. // 收藏
  716. handleCollect(){
  717. if(this.info.collection_id>0){
  718. apiCancelCollect({
  719. collection_id:Number(this.info.collection_id)
  720. }).then(res=>{
  721. if(res.code===200){
  722. Toast('取消收藏!')
  723. this.info.collection_id=0
  724. }
  725. })
  726. }else{
  727. apiSetCollect({
  728. collection_type:1,
  729. primary_id:Number(this.reportId),
  730. extend_id:0
  731. }).then(res=>{
  732. if(res.code===200){
  733. Toast('收藏成功!')
  734. this.info.collection_id=res.data
  735. }
  736. })
  737. }
  738. }
  739. }
  740. }
  741. </script>
  742. <style lang="scss" scoped>
  743. /* 公共弹窗 */
  744. .global-pup{
  745. background-color: #fff;
  746. width: 90vw;
  747. min-height: 200px;
  748. font-size: 32px;
  749. .content{
  750. padding: 34px;
  751. text-align: center;
  752. min-height: 250px;
  753. display: flex;
  754. align-items: center;
  755. text-align: center;
  756. line-height: 1.7;
  757. div{
  758. flex: 1;
  759. }
  760. }
  761. .bot{
  762. border-top: 1px solid #dedede;
  763. div{
  764. line-height: 96px;
  765. flex: 1;
  766. text-align: center;
  767. border-right: 1px solid #dedede;
  768. color:#E3B377;
  769. }
  770. div:last-child {
  771. border: none;
  772. }
  773. }
  774. }
  775. .flex{
  776. display: flex;
  777. }
  778. .report-detail-page{
  779. /* padding-bottom: 50px; */
  780. .main-box{
  781. padding: 34px;
  782. .title{
  783. display: inline;
  784. margin-left: -26px;
  785. }
  786. }
  787. .main-box-noauth{
  788. height: calc(100vh - 50px);
  789. overflow: hidden;
  790. }
  791. .title{
  792. font-size: 40px;
  793. font-weight: bold;
  794. margin-bottom: 30px;
  795. }
  796. .time{
  797. justify-content: space-between;
  798. font-size: 30px;
  799. margin-top: 30px;
  800. }
  801. .audio-wrap{
  802. height: 160px;
  803. background: #FAF7EE;
  804. border-radius: 16px;
  805. margin-top: 20px;
  806. padding: 10px 31px;
  807. margin-bottom: 31px;
  808. align-items: center;
  809. img{
  810. width: 110px;
  811. height: 110px;
  812. display: block;
  813. margin-right: 16px;
  814. }
  815. }
  816. .tips{
  817. font-size: 34px;
  818. margin-bottom: 51px;
  819. position: relative;
  820. &::before{
  821. content: '';
  822. width: 10px;
  823. // height: 100%;
  824. display: inline-block;
  825. background-color: #E3B377;
  826. margin-right: 20px;
  827. // position: relative;
  828. // top: 10px;
  829. }
  830. .abstract{
  831. font-size: 34px;
  832. margin-bottom: 20px;
  833. line-height: 1.5;
  834. }
  835. }
  836. .disclaimers-box{
  837. width: 94vw;
  838. padding: 32px;
  839. }
  840. .rich-content{
  841. line-height: 1.8;
  842. font-size: 36px;
  843. :deep(img){
  844. width: 100% !important;
  845. }
  846. :deep(span){
  847. font-size: 36px !important;
  848. line-height: 1.8 !important;
  849. background-color: rgba(255, 255, 255, 0) !important;
  850. }
  851. :deep(p){
  852. font-size: 36px !important;
  853. line-height: 1.8 !important;
  854. background-color: rgba(255, 255, 255, 0) !important;
  855. }
  856. :deep(ul){
  857. font-size: 36px !important;
  858. line-height: 1.8 !important;
  859. background-color: rgba(255, 255, 255, 0) !important;
  860. }
  861. :deep(ol){
  862. font-size: 36px !important;
  863. line-height: 1.8 !important;
  864. background-color: rgba(255, 255, 255, 0) !important;
  865. }
  866. :deep(iframe){
  867. width: 100% !important;
  868. }
  869. :deep(li) {
  870. font-size: 36px !important;
  871. line-height: 1.8 !important;
  872. background-color: rgba(255, 255, 255, 0) !important;
  873. list-style: inherit !important;
  874. list-style-position: inside !important;
  875. }
  876. :deep(span.fr-emoticon) {
  877. width: 36px !important;
  878. height: 36px !important;
  879. background-repeat: no-repeat !important;
  880. background-size: cover !important;
  881. display: inline-block !important;
  882. vertical-align: middle !important;
  883. }
  884. }
  885. .no-auth-wrap{
  886. min-height: 200px;
  887. padding: 0 34px 50px 34px;
  888. background: linear-gradient(360deg, #FFFFFF 60%, rgba(255, 255, 255, 0) 88%);
  889. // position: relative;
  890. // top: -150px;
  891. position: fixed;
  892. left: 0;
  893. right: 0;
  894. bottom: 0;
  895. z-index: 99;
  896. text-align: center;
  897. font-size: 32px;
  898. color: #E3B377;
  899. .apply-box{
  900. padding-top: 250px;
  901. }
  902. .btn{
  903. width: 100%;
  904. margin-left: auto;
  905. margin-right: auto;
  906. line-height: 80px;
  907. background-color: #E6B77D;
  908. border-radius: 4px;
  909. color: #fff;
  910. margin-top: 100px;
  911. display: block;
  912. }
  913. }
  914. .chapter-list-wrap{
  915. .top-box{
  916. height: 418px;
  917. background-color: rgba($color: #000000, $alpha: 0.7);
  918. background-size: cover;
  919. color: #fff;
  920. position: relative;
  921. .title{
  922. text-align: center;
  923. font-size: 34px;
  924. font-weight: 600;
  925. padding-top: 78px;
  926. }
  927. .sub-title{
  928. font-size: 32px;
  929. text-align: center;
  930. width: 70%;
  931. margin-left: auto;
  932. margin-right: auto;
  933. }
  934. .top-bot{
  935. position: absolute;
  936. bottom: 70px;
  937. left: 34px;
  938. right: 34px;
  939. justify-content: space-between;
  940. align-items: center;
  941. .time-box{
  942. align-items: center;
  943. font-size: 24px;
  944. .day{
  945. font-size: 32px;
  946. border-right: 1px solid #fff;
  947. padding-right: 15px;
  948. margin-right: 15px;
  949. }
  950. }
  951. .audio-play-list-box{
  952. background-color: #E3B377;
  953. color: #fff;
  954. font-size: 24px;
  955. width: 180px;
  956. line-height: 52px;
  957. border-radius: 25px;
  958. text-align: center;
  959. }
  960. .attention-box{
  961. position: absolute;
  962. bottom: 110%;
  963. background-color: #fff;
  964. color: #333;
  965. box-shadow: 0px 0px 10px 4px rgba(0, 0, 0, 0.16);
  966. padding: 20px 54px 20px 20px;
  967. border-radius: 8px;
  968. .close-icon{
  969. width: 24px;
  970. height: 24px;
  971. position: absolute;
  972. top: 50%;
  973. transform: translateY(-50%);
  974. right: 20px;
  975. }
  976. &::after{
  977. content: '';
  978. display:block;
  979. width: 0;
  980. height: 0;
  981. border: 10px solid transparent;
  982. border-top-color: #fff;
  983. position: absolute;
  984. bottom: -20px;
  985. right: 20px;
  986. }
  987. }
  988. }
  989. .stage-num{
  990. position: absolute;
  991. bottom: 350px;
  992. right: 34px;
  993. }
  994. .stage-num-day{
  995. bottom: 70px;
  996. }
  997. }
  998. .list-box{
  999. margin-top: -50px;
  1000. border-top-left-radius: 40px;
  1001. border-top-right-radius: 40px;
  1002. min-height: 100px;
  1003. background-color: #fff;
  1004. position: relative;
  1005. z-index: 2;
  1006. .item{
  1007. padding: 30px 34px;
  1008. border-bottom: 1px solid #E5E5E5;
  1009. .img-box{
  1010. width: 104px;
  1011. height: 104px;
  1012. box-sizing: border-box;
  1013. border-radius: 8px;
  1014. border: solid 2.5px #E5E5E5;
  1015. display: flex;
  1016. align-items: center;
  1017. justify-content: center;
  1018. margin-right: 20px;
  1019. .img{
  1020. width: 60px;
  1021. height: 60px;
  1022. }
  1023. }
  1024. // .img{
  1025. // width: 104px;
  1026. // height: 104px;
  1027. // // background-color: #f5f5f5;
  1028. // flex-shrink: 0;
  1029. // // margin-right: 20px;
  1030. // }
  1031. .con{
  1032. flex: 1;
  1033. position: relative;
  1034. .title{
  1035. font-size: 28px;
  1036. color: #57768D;
  1037. font-weight: bold;
  1038. margin-bottom: 5px;
  1039. .tag{
  1040. font-size: 20px;
  1041. color: #fff;
  1042. font-weight: normal;
  1043. display: inline-block;
  1044. background-color: #1E88E5;
  1045. line-height: 37px;
  1046. padding: 0 6px;
  1047. border-radius: 4px;
  1048. margin-left: 10px;
  1049. }
  1050. }
  1051. .sub-title{
  1052. color: #999;
  1053. }
  1054. .update-time{
  1055. color: #D4D4D4;
  1056. font-size: 24px;
  1057. margin-top: 5px;
  1058. }
  1059. .audio-icon-box{
  1060. position: absolute;
  1061. top: 0;
  1062. right: 0;
  1063. width: 44px;
  1064. height: 40px;
  1065. background-image: url('@/assets/hzyb/report/icon-1.png');
  1066. background-size: cover;
  1067. }
  1068. .audio-icon-box_active{
  1069. background-image: url('@/assets/hzyb/report/icon-2.png');
  1070. }
  1071. }
  1072. }
  1073. }
  1074. .no-auth-box{
  1075. text-align: center;
  1076. font-size: 32px;
  1077. color: #E3B377;
  1078. img{
  1079. width: 100%;
  1080. margin-bottom: 50px;
  1081. }
  1082. .btn{
  1083. width: 90%;
  1084. margin-left: auto;
  1085. margin-right: auto;
  1086. line-height: 80px;
  1087. background-color: #E6B77D;
  1088. border-radius: 4px;
  1089. color: #fff;
  1090. margin-top: 100px;
  1091. display: block;
  1092. }
  1093. }
  1094. }
  1095. .right-fix-box{
  1096. position: fixed;
  1097. z-index: 99;
  1098. right: 34px;
  1099. bottom: 130px;
  1100. .item{
  1101. margin-top: 10px;
  1102. }
  1103. .back-top-img{
  1104. width: 100px;
  1105. height: 100px;
  1106. display: block;
  1107. }
  1108. .share-icon{
  1109. width: 100px;
  1110. height: 100px;
  1111. display: block;
  1112. }
  1113. .ppt-icon{
  1114. width: 100px;
  1115. height: 100px;
  1116. display: block;
  1117. }
  1118. .collect-icon{
  1119. width: 100px;
  1120. height: 100px;
  1121. display: block;
  1122. }
  1123. }
  1124. }
  1125. .content-swipe {
  1126. width: 100%;
  1127. padding: 30px 34px 0 34px;
  1128. .my-swipe {
  1129. width: 100%;
  1130. .van-swipe-item {
  1131. width: 100%;
  1132. height: auto;
  1133. overflow: hidden;
  1134. }
  1135. img {
  1136. object-fit: contain;
  1137. width: 100%;
  1138. height: 100%;
  1139. }
  1140. }
  1141. }
  1142. .html-head-img-box,.html-end-img-box{
  1143. margin-bottom: 10px;
  1144. position: relative;
  1145. overflow: hidden;
  1146. .head-layout-item{
  1147. position: absolute;
  1148. overflow: hidden;
  1149. box-sizing: border-box
  1150. }
  1151. }
  1152. .chapter-concat-item {
  1153. padding: 20px 0;
  1154. .chapter-title {
  1155. display: flex;
  1156. align-items: center;
  1157. font-size: 30px;
  1158. .type {
  1159. height: fit-content;
  1160. display: inline-block;
  1161. color: #fff;
  1162. padding: 10px 20px;
  1163. background-color: #E6A23C;
  1164. border-radius: 8px;
  1165. margin-right: 20px;
  1166. }
  1167. .chapter-title-text {
  1168. font-size: 30px;
  1169. }
  1170. }
  1171. }
  1172. </style>