BlogDetailPage.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. <template>
  2. <q-page>
  3. <div class="row justify-center">
  4. <div class="col-12 col-md-9" style="min-height: 500px">
  5. <div class="text-weight-bold text-h3 q-pa-xl">
  6. {{ title }}
  7. </div>
  8. <div class="row col-12" style="min-height: 50px">
  9. <div class="q-ml-xl">
  10. <q-avatar size="86px">
  11. <img :src="authorProfileImageUrl" />
  12. </q-avatar>
  13. </div>
  14. <div class="col-8 q-ml-md">
  15. <div class="text-weight-bold text-h6">{{ username }}</div>
  16. <div><q-btn color="primary" icon="add" label="Follow" /></div>
  17. </div>
  18. </div>
  19. <div class="row q-px-xl q-py-md text-h5">
  20. <div class="col-5">{{ createdTime }}</div>
  21. <div class="col-3">
  22. <q-icon color="blue" name="visibility" />{{ pageViewCnt }}
  23. </div>
  24. <div class="col-4">
  25. Collect this<q-btn
  26. class="q-ml-sm"
  27. round
  28. color="primary"
  29. icon="bookmark"
  30. size="xs"
  31. />
  32. </div>
  33. </div>
  34. <div
  35. class="q-px-xl q-pt-md"
  36. style="border-top: 1px solid black"
  37. v-html="content"
  38. ></div>
  39. </div>
  40. </div>
  41. </q-page>
  42. </template>
  43. <script>
  44. import { ref, onMounted, getCurrentInstance, reactive } from "vue";
  45. import { api } from "boot/axios";
  46. import { useRoute } from "vue-router";
  47. import { useQuasar } from "quasar";
  48. import { useSeoMeta } from "unhead";
  49. export default {
  50. name: "BlogDetail",
  51. setup() {
  52. const route = useRoute();
  53. const instance = getCurrentInstance();
  54. const app = getCurrentInstance().appContext.app;
  55. const gp = app.config.globalProperties;
  56. const $q = useQuasar();
  57. const pageViewCnt = ref(0);
  58. const authorProfileImageUrl = ref("");
  59. const title = ref("");
  60. const username = ref("");
  61. const content = ref("");
  62. const createdTime = ref("");
  63. const siteData = reactive({
  64. title: "My Awesome Blog",
  65. shortContent: "Hichina Travel Blog",
  66. });
  67. function logView() {
  68. api
  69. .post("/api/public/pagestats/view-blog/" + route.params.blogId)
  70. .then((res) => {
  71. console.log("view cnt of this blog:");
  72. console.log(res.data);
  73. pageViewCnt.value = res.data.data;
  74. })
  75. .catch((err) => {
  76. console.error("Error:", err);
  77. });
  78. }
  79. function getAuthorPrincipal() {
  80. api
  81. .get(
  82. "/api/public/blog/blog-author-profile-image/" + route.params.blogId
  83. )
  84. .then(function (response) {
  85. console.log("blog author profile image");
  86. console.log(response.data);
  87. if (response.data.ok == true) {
  88. authorProfileImageUrl.value = response.data.data;
  89. if (
  90. authorProfileImageUrl.value == null ||
  91. authorProfileImageUrl.value.length < 1
  92. ) {
  93. authorProfileImageUrl.value =
  94. "https://photoprism.hichinatravel.com/api/v1/t/8623903789c65a160279faa0b33159413cb18af4/32mcf2k4/fit_2048";
  95. }
  96. } else {
  97. gp.$generalNotify($q, false, response.data.message);
  98. }
  99. })
  100. .catch(function (error) {
  101. console.log(error);
  102. });
  103. }
  104. function loadBlogDetail() {
  105. api
  106. .get("/api/public/blog/" + route.params.blogId)
  107. .then((response) => {
  108. title.value = response.data.data.title;
  109. username.value = response.data.data.authorName;
  110. content.value = response.data.data.content;
  111. createdTime.value = response.data.data.createdTime;
  112. // set head meta for seo
  113. // Set the title meta tag
  114. siteData.title = title.value;
  115. siteData.shortContent = gp
  116. .$removeHtmlTag(content.value)
  117. .substring(0, 50);
  118. useSeoMeta({
  119. title: siteData.title,
  120. description: siteData.shortContent,
  121. ogDescription: siteData.shortContent,
  122. ogTitle: siteData.title,
  123. ogImage:
  124. "https://www.hichinatravel.com/static/png/name-67280b81.png",
  125. twitterCard: "summary_large_image",
  126. });
  127. })
  128. .catch((e) => {
  129. console.log("get blog detail err");
  130. console.log(e);
  131. });
  132. }
  133. onMounted(() => {
  134. logView();
  135. getAuthorPrincipal();
  136. loadBlogDetail();
  137. });
  138. return {
  139. title,
  140. authorProfileImageUrl,
  141. username,
  142. createdTime,
  143. pageViewCnt,
  144. content,
  145. };
  146. },
  147. };
  148. </script>