Browse Source

feature 1002106

文献收藏
Kevin Jiang 2 years ago
parent
commit
71b7c6d89d

+ 36 - 0
src/client/collection.client.ts

@@ -0,0 +1,36 @@
+import httpClient from "@/services/httpClient";
+import type { Response } from "@/types/response.types";
+import * as urlHelper from "@/libs/url.lib"
+
+const _url = urlHelper.withPrefix("/gw/user/collect");
+
+/**
+ * 收藏文献
+ * @param paperId 文献ID
+ * @param title 文献标题
+ * @returns 收藏的ID
+ */
+export async function add(paperId: number, title: string): Promise<number> {
+  const resp = await httpClient.post<Response<number>>(_url("/add"), {paperId, title})
+  return resp.data.data
+}
+
+export async function remove(id: number): Promise<boolean> {
+  const resp = await httpClient.delete<Response<boolean>>(_url(`/del/${id}`))
+  return resp.data.data
+}
+
+/**
+ * 文献是否已经收藏
+ * @param paperId 文献ID
+ * @returns 收藏ID
+ */
+export async function isCollected(paperId: number): Promise<number> {
+  const resp = await httpClient.get<Response<number>>(_url("/isCollected"), { params: { paperId } })
+  return resp.data.data
+}
+
+export async function list(page: number): Promise<void> {
+  const resp = await httpClient.get<Response<void>>(_url("/getPage"), { params: { page } })
+  return resp.data.data
+}

+ 13 - 0
src/services/collection.service.ts

@@ -0,0 +1,13 @@
+import * as collectionClient from "@/client/collection.client"
+
+export async function add(paperId: number, title: string): Promise<number> {
+  return collectionClient.add(paperId, title)
+}
+
+export async function remove(id: number): Promise<boolean> {
+  return collectionClient.remove(id)
+}
+
+export async function isCollected(paperId: number): Promise<number> {
+  return collectionClient.isCollected(paperId)
+}

+ 45 - 1
src/views/detail/DetailView.vue

@@ -4,6 +4,8 @@ import { useDocDetailStore } from '@/stores/doc-detail';
 import { useSideBarStore } from '@/stores/side-bar';
 import { useRoute } from 'vue-router';
 import PaperSection from './components/PaperSection.vue';
+import { StarOutlined, StarFilled } from '@ant-design/icons-vue';
+import * as collectionService from "@/services/collection.service"
 
 // 当前路由
 const route = useRoute();
@@ -15,19 +17,46 @@ const docDetailStore = useDocDetailStore();
 const detail = computed(() => docDetailStore.detail)
 const pdfPath = computed(() => docDetailStore.pdfUrl)
 const pdfPage = ref(1)
+const isCollected = ref(false)
+const collectId = ref(0)
 
 function onSubSectionClick(page: number) {
   console.log('page', page)
   pdfPage.value = page
 }
 
+function onCollectionClick() {
+  if (detail.value) {
+    if (collectId.value > 0) {
+      collectionService.remove(collectId.value).then((ok) => {
+        if (ok) {
+          isCollected.value = false
+        }
+      })
+    } else {
+      collectionService.add(detail.value.id, detail.value.title).then((id) => {
+        collectId.value = id
+        isCollected.value = true
+      })
+    }
+  }
+}
+
 onMounted(() => {
   // 收起左侧边栏
   sideBarStore.setCollapse(true);
   // 查询文档详情内容
   const id = parseInt(route.params.id as string);
   if (id) {
-    docDetailStore.fetch(id);
+    docDetailStore.fetch(id).then(() => {
+      if (detail.value) {
+        // 查询是否用户已经收藏
+        collectionService.isCollected(detail.value.id).then((id) => {
+          collectId.value = id
+          isCollected.value = id > 0
+        })
+      }
+    });
   }
 });
 
@@ -45,6 +74,16 @@ onUnmounted(() => {
     <a-col :span="19">
       <div v-if="detail?.filePath" class="doc-wrap">
         <!-- <h1 class="title">{{ detail.title }}</h1> -->
+        <div class="toolbar">
+          <a-button @click="onCollectionClick">
+            <template #icon>
+              <star-filled v-if="isCollected" />
+              <star-outlined v-else />
+            </template>
+            <span v-if="isCollected">已收藏</span>
+            <span v-else>收藏</span>
+          </a-button>
+        </div>
         <iframe
           v-if="pdfPath"
           :src="pdfPath + '&page=' + pdfPage + '#page=' + pdfPage"
@@ -72,6 +111,11 @@ onUnmounted(() => {
   .doc-wrap {
     height: 100%;
 
+    .toolbar {
+      text-align: right;
+      padding: 10px 0;
+    }
+
     .pdf-viewer {
       border: 1px solid $border-color-secondary;
     }