OriginLink.vue 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. <template>
  2. <span class="origin-link-container">
  3. <span
  4. v-bound-phone="bindPhoneViewOrigin()"
  5. class="highlight-text origin-link clickable"
  6. @click="viewOriginLink"
  7. >
  8. 查看原文链接
  9. </span>
  10. <van-dialog
  11. v-model="dialog.show"
  12. title="查看原文链接"
  13. show-cancel-button
  14. @confirm="useFreeChance"
  15. >
  16. <p class="content-text">
  17. 确定消耗
  18. <span class="highlight-text">1次</span>
  19. 查看原文链接的机会吗?
  20. </p>
  21. <p class="sub-content-text">
  22. 您当前是免费用户,有1次查看原文链接的机会,如需更多查看次数,您可点击
  23. <span
  24. class="highlight-text"
  25. @click="leaveInfo('article_original_more_membership')"
  26. >升级大会员 ></span>
  27. </p>
  28. </van-dialog>
  29. <van-dialog
  30. v-model="dialog.see"
  31. title=""
  32. class="see-dialog"
  33. close-on-click-overlay
  34. confirm-button-text="立即前往"
  35. @confirm="leaveSource('article_original')"
  36. >
  37. <p class="see-content">
  38. 为给您匹配精准的推荐信息,请完善个人信息,免费查看原文
  39. <AppIcon class="icons" name="close_heidi" @click="dialog.see = false" />
  40. </p>
  41. </van-dialog>
  42. </span>
  43. </template>
  44. <script>
  45. import { mapGetters, mapState } from 'vuex'
  46. import { LINKS } from '@/data'
  47. import { AppIcon } from '@/ui/'
  48. import { appCallOpenWindow } from '@/utils/callFn/appFn'
  49. import { openAppOrWxPage } from '@/utils/'
  50. import { getArticleOriginalText } from '@/api/modules/article'
  51. import EventBus from '@/utils/eventBus'
  52. export default {
  53. name: 'OriginLink',
  54. components: {
  55. AppIcon
  56. },
  57. props: {
  58. id: {
  59. type: String,
  60. required: true,
  61. default: ''
  62. },
  63. beforeLeavePage: Function
  64. },
  65. data() {
  66. return {
  67. dialog: {
  68. show: false,
  69. see: false
  70. },
  71. o_url: ''
  72. }
  73. },
  74. computed: {
  75. ...mapState({
  76. content: state => state.article.mainModel.content
  77. }),
  78. ...mapGetters('user', ['isFree']),
  79. url() {
  80. return this.content.originalUrl || this.o_url
  81. },
  82. toBCustom() {
  83. return this.IsCustomTopNet || this.yyszbContent
  84. },
  85. yyszbContent() {
  86. return this.content.yyszbContent || false
  87. },
  88. IsCustomTopNet() {
  89. return this.content.IsCustomTopNet || false
  90. }
  91. },
  92. created() {
  93. window.t = this
  94. this.eventBusListening()
  95. },
  96. methods: {
  97. eventBusListening() {
  98. EventBus.$on('originLink:view', () => {
  99. this.viewOriginLink()
  100. })
  101. // 及时解绑 EventBus 的事件监听
  102. this.$once('hook:beforeDestroy', () => {
  103. EventBus.$off('originLink:view')
  104. })
  105. },
  106. async viewOriginLink() {
  107. if (this.url) {
  108. // 如果已经获取过链接,则可以直接打开
  109. return this.openUrl()
  110. }
  111. const { inH5 } = this.$envs
  112. if (inH5) {
  113. if (this.beforeLeavePage) {
  114. await this.beforeLeavePage()
  115. }
  116. openAppOrWxPage(LINKS.下载APP, {
  117. query: {
  118. source: this.$env.platform.toUpperCase()
  119. }
  120. })
  121. }
  122. else {
  123. const loading = this.$toast.loading()
  124. try {
  125. const {
  126. error_code: code,
  127. error_msg: msg,
  128. data
  129. } = await this.getText()
  130. loading.clear()
  131. if (code === 0 && data) {
  132. if (data.url) {
  133. this.o_url = data.url
  134. this.openUrlAuth()
  135. }
  136. else if (data.status === 1) {
  137. this.leaveInfo('article_original_one', {
  138. signId: encodeURIComponent(this.id),
  139. article: this.extractString(location.href)
  140. })
  141. }
  142. else if (data.status === 2) {
  143. this.dialog.show = true
  144. }
  145. else if (data.status === 3) {
  146. this.leaveInfo('article_original_more', {
  147. signId: encodeURIComponent(this.id),
  148. article: this.extractString(location.href)
  149. })
  150. }
  151. else if (data.status === 4) {
  152. this.$dialog
  153. .confirm({
  154. title: '暂无更多查看原文链接权限',
  155. message: '如需开通更多权限获得商机,请联系客服。',
  156. className: 'j-confirm-dialog',
  157. showCancelButton: true,
  158. confirmButtonText: '联系客服',
  159. cancelButtonText: '返回',
  160. confirmButtonColor: '#2ABDD1',
  161. cancelButtonColor: '#171826',
  162. width: 303
  163. })
  164. .then(async () => {
  165. if (this.beforeLeavePage) {
  166. await this.beforeLeavePage()
  167. }
  168. openAppOrWxPage(LINKS.客服)
  169. })
  170. }
  171. else {
  172. this.$toast(data.msg)
  173. }
  174. }
  175. else {
  176. console.log(msg)
  177. }
  178. }
  179. catch (error) {
  180. loading.clear()
  181. }
  182. }
  183. },
  184. async getText(use) {
  185. const param = {
  186. id: this.id
  187. }
  188. if (use) {
  189. param.use = true
  190. }
  191. return getArticleOriginalText(param)
  192. },
  193. async openUrlAuth() {
  194. if (!this.url)
  195. return
  196. if (this.toBCustom) {
  197. return this.openUrl()
  198. }
  199. if (this.isFree) {
  200. // 检查是否已经留资。已留资返回true
  201. const source = 'article_original'
  202. try {
  203. const leavedInfo = await this.$leaveInfo.checkNeedLeaveInfo(source)
  204. if (!leavedInfo) {
  205. // 没有留资,弹窗留资
  206. this.dialog.see = true
  207. return
  208. }
  209. }
  210. catch (error) {
  211. console.log(error)
  212. }
  213. }
  214. this.openUrl()
  215. },
  216. async useFreeChance() {
  217. try {
  218. const {
  219. error_code: code,
  220. error_msg: msg,
  221. data
  222. } = await this.getText(true)
  223. if (code === 0 && data) {
  224. if (data.url) {
  225. this.o_url = data.url
  226. this.openUrlAuth()
  227. }
  228. else {
  229. if (msg) {
  230. console.log(msg)
  231. }
  232. }
  233. }
  234. }
  235. catch (error) {
  236. console.log(error)
  237. }
  238. },
  239. openUrl() {
  240. if (!this.url)
  241. return
  242. const { inApp } = this.$envs
  243. if (inApp) {
  244. appCallOpenWindow(this.url, '查看原文')
  245. }
  246. else {
  247. this.clickA(this.url)
  248. }
  249. },
  250. clickA(link) {
  251. const eleLink = document.createElement('a') // 新建A标签
  252. eleLink.href = link
  253. eleLink.rel = 'no-referrer'
  254. eleLink.style.display = 'none'
  255. document.body.appendChild(eleLink)
  256. eleLink.click() // 触发点击事件
  257. },
  258. extractString(str) {
  259. const regex = /\/article\/(.*?)\//
  260. const match = str.match(regex)
  261. return match ? match[1] : null
  262. },
  263. async leaveSource(source, query = {}) {
  264. if (this.beforeLeavePage) {
  265. await this.beforeLeavePage()
  266. }
  267. openAppOrWxPage(LINKS.留资, {
  268. query: {
  269. source,
  270. ...query
  271. }
  272. })
  273. },
  274. leaveInfo(key, query = {}) {
  275. const { platform } = this.$env
  276. const source = `${platform}_${key}`
  277. this.leaveSource(source, query)
  278. },
  279. bindPhoneViewOrigin() {
  280. return {
  281. props: {
  282. name: '标讯详情页-查看原文链接'
  283. },
  284. next: () => {
  285. this.viewOriginLink()
  286. }
  287. }
  288. }
  289. }
  290. }
  291. </script>
  292. <style lang="scss" scoped>
  293. ::v-deep {
  294. .van-dialog__header {
  295. font-size: 18px;
  296. }
  297. .van-dialog__content {
  298. padding: 8px 16px;
  299. }
  300. .van-dialog__confirm {
  301. color: $main;
  302. }
  303. }
  304. .content-text {
  305. font-size: 14px;
  306. color: #5f5e64;
  307. text-align: center;
  308. }
  309. .sub-content-text {
  310. margin-top: 16px;
  311. width: 270px;
  312. font-size: 12px;
  313. line-height: 18px;
  314. color: #9b9ca3;
  315. text-align: center;
  316. }
  317. .see-dialog {
  318. width: 270px;
  319. }
  320. .see-content {
  321. position: relative;
  322. padding: 22px 12px;
  323. font-size: 15px;
  324. line-height: 22px;
  325. color: #5f5e64;
  326. .icons {
  327. position: absolute;
  328. top: 0;
  329. right: -8px;
  330. font-size: 20px;
  331. color: #ccc;
  332. }
  333. }
  334. .origin-link {
  335. color: #05a6f3;
  336. }
  337. </style>