Detail.vue 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. <script setup>
  2. import apiReport from '@/api/modules/report'
  3. import { useRoute } from 'vue-router'
  4. import { Message } from 'tdesign-mobile-vue';
  5. import apiCommon from '@/api/modules/common'
  6. import apiUser from '@/api/modules/user'
  7. const route = useRoute()
  8. // 获取系统配置
  9. let systemConfig = null
  10. function getSystemConfig() {
  11. apiCommon.systemConfig().then(res => {
  12. if (res.Ret === 200) {
  13. systemConfig = res.Data
  14. }
  15. })
  16. }
  17. getSystemConfig()
  18. // 获取用户信息
  19. let userInfo = null
  20. function getUserInfo() {
  21. apiUser.userInfo().then(res => {
  22. if (res.Ret === 200) {
  23. userInfo = res.Data
  24. }
  25. })
  26. }
  27. getUserInfo()
  28. const reportId = route.query.reportid
  29. const reportInfo = ref(null)
  30. const reportContent = ref('')
  31. const reportStatus = ref(0)//1已过期,2没有该品种权限,3没有权限,4有权限
  32. const reportCollected = ref(false)//报告是否收藏
  33. async function getReportInfo() {
  34. if (!reportId) return
  35. const res = await apiReport.getReportDetail({
  36. ReportId: Number(reportId)
  37. })
  38. if (res.Ret === 200) {
  39. reportInfo.value = res.Data.Report
  40. reportStatus.value = res.Data.Status
  41. reportCollected.value = res.Data.IsCollect || false
  42. if (res.Data.Status === 4) {
  43. formatIframeData()
  44. } else {//无权限
  45. reportContent.value = reportInfo.value.ContentSub
  46. }
  47. nextTick(() => {
  48. handlePreviewImgs()
  49. })
  50. // 设置分享文案
  51. wx.miniProgram.postMessage({
  52. data: {
  53. title: res.Data.Report.Title
  54. }
  55. });
  56. }
  57. }
  58. getReportInfo()
  59. // 给报告详情中图表加参数
  60. function formatIframeData() {
  61. reportContent.value = reportInfo.value.Content.replace(/\/chartshow\?code=/g, `/chartshow?source=etamini&token=${localStorage.getItem('token')}&reportId=${reportId}&code=`)
  62. }
  63. // 拨打电话
  64. function handleCallPhone() {
  65. let tel = userInfo.SellerPhone
  66. if (!tel) {
  67. systemConfig.forEach(item => {
  68. if (item.ConfKey === 'ServicePhone') {
  69. tel = item.ConfVal
  70. }
  71. });
  72. }
  73. var phoneLink = 'tel:' + tel;
  74. var link = document.createElement('a');
  75. link.setAttribute('href', phoneLink);
  76. link.onclick = function () {
  77. return true;
  78. };
  79. link.click();
  80. }
  81. // 点击收藏
  82. async function handleCollect() {
  83. const res = reportCollected.value ? await apiReport.reportCollectCancel({ ReportId: Number(reportId) }) : await apiReport.reportCollect({ ReportId: Number(reportId) })
  84. if (res.Ret === 200) {
  85. Message.success(reportCollected.value ? '取消收藏成功' : '收藏成功')
  86. reportCollected.value = !reportCollected.value
  87. // 通知更新收藏列表
  88. wx.miniProgram.postMessage({
  89. data: 'refreshCollectList'
  90. });
  91. }
  92. }
  93. // 显示免责声明
  94. const isShowMZSM = ref(false)
  95. // 显示返回顶部
  96. const showToTop = ref(false)
  97. function handlePageScroll() {
  98. const top = document.documentElement.scrollTop || document.body.scrollTop
  99. if (top > window.outerHeight) {
  100. showToTop.value = true
  101. } else {
  102. showToTop.value = false
  103. }
  104. }
  105. function handleBackTop() {
  106. document.body.scrollTop = document.documentElement.scrollTop = 0
  107. }
  108. // 点击报告内容中的图片
  109. function handlePreviewImgs() {
  110. document.getElementById('rich-content').addEventListener('click', function (event) {
  111. let imgArray = [];
  112. let curImageSrc = event.target.src;
  113. let oParent = event.target.parentNode;
  114. if (curImageSrc && !oParent.hasAttribute('href')) {
  115. let imgs = document.querySelectorAll('.rich-content img');
  116. for (let i = 0; i < imgs.length; i++) {
  117. let itemSrc = imgs[i].src;
  118. imgArray.push(itemSrc);
  119. }
  120. wx.previewImage({ current: curImageSrc, urls: imgArray });
  121. }
  122. });
  123. }
  124. onMounted(() => {
  125. window.addEventListener('scroll', handlePageScroll)
  126. })
  127. onUnmounted(() => {
  128. window.removeEventListener('scroll', handlePageScroll)
  129. })
  130. </script>
  131. <template>
  132. <div class="report-detail-page" v-if="reportInfo">
  133. <div class="title-box">{{ reportInfo.Title }}</div>
  134. <div class="author-box">{{ reportInfo.Author }}</div>
  135. <div class="time-box">
  136. <span>{{ reportInfo.PublishTime }}</span>
  137. <span class="btn" @click="isShowMZSM = true">免责声明</span>
  138. </div>
  139. <div class="des-box" v-if="reportInfo.Abstract">
  140. <svg-icon name="icon01"></svg-icon>
  141. <div>{{ reportInfo.Abstract }}</div>
  142. </div>
  143. <div
  144. id="rich-content"
  145. class="report-content-box rich-content"
  146. v-html="reportContent"
  147. ></div>
  148. <!-- 右侧悬浮操作栏 -->
  149. <div class="right-fix-box">
  150. <!-- 收藏 -->
  151. <svg-icon
  152. @click="handleCollect"
  153. class="item collect-icon"
  154. :name="reportCollected ? 'collected' : 'collect'"
  155. v-if="reportStatus === 4"
  156. />
  157. <!-- 返回顶部 -->
  158. <div class="item back-top-img">
  159. <svg-icon
  160. name="backtop"
  161. v-show="showToTop"
  162. @click="handleBackTop"
  163. class="back-top-img"
  164. />
  165. </div>
  166. </div>
  167. </div>
  168. <!-- 无权限 -->
  169. <div class="no-auth-wrap" v-if="reportStatus !== 4">
  170. <div class="opcity-box"></div>
  171. <div class="content-box">
  172. <img class="icon" src="@/assets/imgs/lock-img.png" alt="" />
  173. <div class="text" v-if="reportStatus === 3">
  174. 您暂无权限查看,<br />请联系客服人员开通!
  175. </div>
  176. <div class="text" v-if="reportStatus === 2">
  177. 您暂无该品种权限,<br />请联系销售人员开通!
  178. </div>
  179. <div class="text" v-if="reportStatus === 1">
  180. 您的权限已过期,<br />请联系销售人员开通!
  181. </div>
  182. <t-button
  183. theme="primary"
  184. block
  185. style="width: 300px; margin: 30px auto"
  186. @click="handleCallPhone"
  187. >立即联系</t-button
  188. >
  189. </div>
  190. </div>
  191. <!-- 免责声明 -->
  192. <disclaimers-wrap v-model:show="isShowMZSM" />
  193. </template>
  194. <style lang="scss" scoped>
  195. .report-detail-page {
  196. background-color: #fff;
  197. padding: var(--page-padding);
  198. .title-box {
  199. font-size: 36px;
  200. line-height: 44px;
  201. margin-bottom: 20px;
  202. }
  203. .time-box {
  204. margin-top: 10px;
  205. font-size: var(--font-size-small);
  206. color: var(--text-color-grey);
  207. .btn {
  208. float: right;
  209. color: var(--primary-color);
  210. }
  211. }
  212. .des-box {
  213. background-color: #f8f8f8;
  214. padding: 20px;
  215. margin: 20px 0;
  216. display: flex;
  217. gap: 0 10px;
  218. color: --text-color-sub;
  219. font-size: var(--font-size-small);
  220. line-height: 36px;
  221. }
  222. .report-content-box {
  223. margin-top: 20px;
  224. line-height: 1.8;
  225. font-size: 36px;
  226. :deep(img) {
  227. width: 100% !important;
  228. }
  229. :deep(span) {
  230. font-size: 36px !important;
  231. line-height: 1.8 !important;
  232. background-color: rgba(255, 255, 255, 0) !important;
  233. }
  234. :deep(p) {
  235. font-size: 36px !important;
  236. line-height: 1.8 !important;
  237. background-color: rgba(255, 255, 255, 0) !important;
  238. }
  239. :deep(ul) {
  240. font-size: 36px !important;
  241. line-height: 1.8 !important;
  242. background-color: rgba(255, 255, 255, 0) !important;
  243. }
  244. :deep(ol) {
  245. font-size: 36px !important;
  246. line-height: 1.8 !important;
  247. background-color: rgba(255, 255, 255, 0) !important;
  248. }
  249. :deep(iframe) {
  250. width: 100% !important;
  251. }
  252. :deep(li) {
  253. font-size: 36px !important;
  254. line-height: 1.8 !important;
  255. background-color: rgba(255, 255, 255, 0) !important;
  256. list-style: inherit !important;
  257. list-style-position: inside !important;
  258. }
  259. :deep(span.fr-emoticon) {
  260. width: 36px !important;
  261. height: 36px !important;
  262. background-repeat: no-repeat !important;
  263. background-size: cover !important;
  264. display: inline-block !important;
  265. vertical-align: middle !important;
  266. }
  267. }
  268. .right-fix-box {
  269. position: fixed;
  270. z-index: 99;
  271. right: 34px;
  272. bottom: 130px;
  273. .item {
  274. margin-top: 10px;
  275. }
  276. .back-top-img {
  277. width: 100px;
  278. height: 100px;
  279. display: block;
  280. }
  281. .collect-icon {
  282. width: 100px;
  283. height: 100px;
  284. display: block;
  285. }
  286. }
  287. }
  288. .no-auth-wrap {
  289. position: fixed;
  290. left: 0;
  291. right: 0;
  292. bottom: 0;
  293. z-index: 99;
  294. .opcity-box {
  295. height: 129px;
  296. background: linear-gradient(
  297. 360deg,
  298. #ffffff 0%,
  299. rgba(255, 255, 255, 0) 100%
  300. );
  301. }
  302. .content-box {
  303. background-color: #fff;
  304. padding-bottom: 200px;
  305. text-align: center;
  306. color: var(--primary-color);
  307. }
  308. .icon {
  309. display: block;
  310. margin: 0 auto;
  311. width: 200px;
  312. height: 200px;
  313. }
  314. }
  315. @media (min-width: 600px) {
  316. .report-detail-page {
  317. .title-box {
  318. font-size: 18px;
  319. line-height: 22px;
  320. margin-bottom: 10px;
  321. }
  322. .time-box {
  323. margin-top: 5px;
  324. }
  325. .des-box {
  326. padding: 10px;
  327. margin: 10px 0;
  328. gap: 0 5px;
  329. line-height: 18px;
  330. }
  331. .report-content-box {
  332. margin-top: 10px;
  333. font-size: 18px;
  334. :deep(span) {
  335. font-size: 18px !important;
  336. }
  337. :deep(p) {
  338. font-size: 18px !important;
  339. }
  340. :deep(ul) {
  341. font-size: 18px !important;
  342. }
  343. :deep(ol) {
  344. font-size: 18px !important;
  345. }
  346. :deep(li) {
  347. font-size: 18px !important;
  348. }
  349. :deep(span.fr-emoticon) {
  350. width: 18px !important;
  351. height: 18px !important;
  352. }
  353. }
  354. .right-fix-box {
  355. right: 17px;
  356. bottom: 65px;
  357. .item {
  358. margin-top: 5px;
  359. }
  360. .back-top-img {
  361. width: 50px;
  362. height: 50px;
  363. }
  364. .collect-icon {
  365. width: 50px;
  366. height: 50px;
  367. }
  368. }
  369. }
  370. .no-auth-wrap {
  371. .opcity-box {
  372. height: 65px;
  373. }
  374. .content-box {
  375. padding-bottom: 100px;
  376. }
  377. .icon {
  378. width: 100px;
  379. height: 100px;
  380. }
  381. }
  382. }
  383. </style>