From 645eb4b97bdf8860a9e4bf6db2474a5ab9180cae Mon Sep 17 00:00:00 2001
From: 杨磊 <505174330@qq.com>
Date: 星期日, 24 八月 2025 11:30:34 +0800
Subject: [PATCH] 收藏

---
 src/assets/images/xiehe/detail/Collection.png      |    0 
 src/views/home/index.vue                           |   26 ++++
 src/layout/components/login.vue                    |  217 +++++++++++++++++-------------------
 src/layout/baseLayout.vue                          |    9 +
 src/views/bookStore/detail.vue                     |  103 +++++++---------
 src/assets/images/header/dialogLeftImg.png         |    0 
 src/assets/images/xiehe/detail/Collection_fill.png |    0 
 src/layout/components/headerPage.vue               |    2 
 8 files changed, 182 insertions(+), 175 deletions(-)

diff --git a/src/assets/images/header/dialogLeftImg.png b/src/assets/images/header/dialogLeftImg.png
index e546dc6..5df3c51 100644
--- a/src/assets/images/header/dialogLeftImg.png
+++ b/src/assets/images/header/dialogLeftImg.png
Binary files differ
diff --git a/src/assets/images/xiehe/detail/Collection.png b/src/assets/images/xiehe/detail/Collection.png
new file mode 100644
index 0000000..b550a2f
--- /dev/null
+++ b/src/assets/images/xiehe/detail/Collection.png
Binary files differ
diff --git a/src/assets/images/xiehe/detail/Collection_fill.png b/src/assets/images/xiehe/detail/Collection_fill.png
new file mode 100644
index 0000000..a4378eb
--- /dev/null
+++ b/src/assets/images/xiehe/detail/Collection_fill.png
Binary files differ
diff --git a/src/layout/baseLayout.vue b/src/layout/baseLayout.vue
index eed2949..6b3b00b 100644
--- a/src/layout/baseLayout.vue
+++ b/src/layout/baseLayout.vue
@@ -5,12 +5,21 @@
       <RouterView />
       <Footer class="footer"></Footer>
     </div>
+    <login ref="loginRef"></login>
   </div>
 </template>
 
 <script setup lang="ts">
 import Header from './components/headerPage.vue'
 import Footer from './components/footerPage.vue'
+import login from './components/login.vue'
+import { provide, ref } from 'vue'
+
+const logIn = () => {
+  loginRef.value.logIn()
+}
+const loginRef = ref()
+provide('logIn', logIn)
 </script>
 
 <style lang="less" scoped>
diff --git a/src/layout/components/headerPage.vue b/src/layout/components/headerPage.vue
index 1a793ca..e186393 100644
--- a/src/layout/components/headerPage.vue
+++ b/src/layout/components/headerPage.vue
@@ -76,7 +76,7 @@
 
 <script setup lang="ts">
 import login from './login.vue'
-import { onMounted, ref } from 'vue'
+import { onMounted, provide, ref } from 'vue'
 import { Search } from '@element-plus/icons-vue'
 import { useUserStore } from '@/store'
 import { useRouter } from 'vue-router'
diff --git a/src/layout/components/login.vue b/src/layout/components/login.vue
index 173eb42..d4d9b81 100644
--- a/src/layout/components/login.vue
+++ b/src/layout/components/login.vue
@@ -50,23 +50,19 @@
                   validator: (_, value, callback) => {
                     if (
                       !/^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/.test(
-                        value
+                        value,
                       )
                     ) {
-                      callback('璇疯緭鍏�11浣嶇數璇濆彿鐮�');
+                      callback('璇疯緭鍏�11浣嶇數璇濆彿鐮�')
                     } else {
-                      callback();
+                      callback()
                     }
                   },
                 },
               ]"
               prop="telNumber"
             >
-              <el-input
-                v-model="passFormData.telNumber"
-                placeholder="璇疯緭鍏ユ墜鏈哄彿"
-                size="large"
-              >
+              <el-input v-model="passFormData.telNumber" placeholder="璇疯緭鍏ユ墜鏈哄彿" size="large">
                 <template #prepend>
                   <el-select
                     v-model="select"
@@ -80,9 +76,7 @@
               </el-input>
             </el-form-item>
             <el-form-item>
-              <el-button class="yanzhengBtn" @click="sliderImgDialogVisable = true"
-                >楠岃瘉</el-button
-              >
+              <el-button class="yanzhengBtn" @click="sliderImgDialogVisable = true">楠岃瘉</el-button>
             </el-form-item>
             <el-form-item
               v-if="signUpWay === 'authSignUp'"
@@ -93,19 +87,13 @@
               ]"
               prop="telCode"
             >
-              <el-input
-                v-model="passFormData.telCode"
-                placeholder="璇疯緭鍏ラ獙璇佺爜"
-                size="large"
-              />
+              <el-input v-model="passFormData.telCode" placeholder="璇疯緭鍏ラ獙璇佺爜" size="large" />
               <el-button
                 type="primary"
                 class="codeBtn"
                 :disabled="countDown != 0"
                 @click="getCode(passFormRef)"
-                >{{
-                  countDown == 0 ? "鑾峰彇楠岃瘉鐮�" : "楠岃瘉鐮�(" + countDown + "s)"
-                }}</el-button
+                >{{ countDown == 0 ? '鑾峰彇楠岃瘉鐮�' : '楠岃瘉鐮�(' + countDown + 's)' }}</el-button
               >
             </el-form-item>
             <el-form-item
@@ -116,9 +104,9 @@
                 {
                   validator: (rule, value, callback) => {
                     if (!/\d/.test(value) || /^\d+$/.test(value)) {
-                      callback('瀵嗙爜涓嶈兘涓虹函鏁板瓧鎴栧瓧姣�');
+                      callback('瀵嗙爜涓嶈兘涓虹函鏁板瓧鎴栧瓧姣�')
                     } else {
-                      callback();
+                      callback()
                     }
                   },
                 },
@@ -174,49 +162,49 @@
 </template>
 
 <script setup>
-import { ref, inject, watchEffect, reactive, nextTick } from "vue";
-import dialogLeftImg from "@/assets/images/header/dialogLeftImg.png";
-import verify from "@/components/sliderImg/component/verify.vue";
-import "@/components/sliderImg/sliderImg.js";
-import "@/components/sliderImg/sliderImg.css";
-import { ElMessage } from "element-plus";
-import { useUserStore } from "@/store";
-import { useRouter } from "vue-router";
-const router = useRouter();
+import { ref, inject, watchEffect, reactive, nextTick } from 'vue'
+import dialogLeftImg from '@/assets/images/header/dialogLeftImg.png'
+import verify from '@/components/sliderImg/component/verify.vue'
+import '@/components/sliderImg/sliderImg.js'
+import '@/components/sliderImg/sliderImg.css'
+import { ElMessage } from 'element-plus'
+import { useUserStore } from '@/store'
+import { useRouter } from 'vue-router'
+const router = useRouter()
 
-const userStore = useUserStore();
+const userStore = useUserStore()
 
-const MG = inject("MG");
-const config = inject("config");
-const dialogFormVisible = ref(false);
-const sliderImgDialogVisable = ref(false);
-const flag = ref("logIn"); // 鐧诲綍鎴栨敞鍐�
+const MG = inject('MG')
+const config = inject('config')
+const dialogFormVisible = ref(false)
+const sliderImgDialogVisable = ref(false)
+const flag = ref('logIn') // 鐧诲綍鎴栨敞鍐�
 
-const signUpWay = ref("authSignUp"); // 鐧诲綍鏂瑰紡
-const select = ref("涓浗+86");
-const countDown = ref(0); // 鍊掕鏃舵椂闂�
-let timer = null; // 鍊掕鏃跺疄渚�
-const passFormRef = ref();
+const signUpWay = ref('authSignUp') // 鐧诲綍鏂瑰紡
+const select = ref('涓浗+86')
+const countDown = ref(0) // 鍊掕鏃舵椂闂�
+let timer = null // 鍊掕鏃跺疄渚�
+const passFormRef = ref()
 const passFormData = ref({
-  telNumber: "",
-  password: "",
-  telCode: "",
-  password: "",
-  confirmPassword: "",
-});
+  telNumber: '',
+  password: '',
+  telCode: '',
+  password: '',
+  confirmPassword: '',
+})
 const closeDialog = () => {
-  countDown.value = 0;
-  clearInterval(timer);
+  countDown.value = 0
+  clearInterval(timer)
   if (passFormRef.value) {
-    passFormRef.value.resetFields();
+    passFormRef.value.resetFields()
   }
-  dialogFormVisible.value = false;
-};
+  dialogFormVisible.value = false
+}
 // 寮圭獥鎵撳紑浜嬩欢
-const openDialog = () => {};
+const openDialog = () => {}
 
 const loginImgVerify = (code) => {
-  sliderImgDialogVisable.value = false;
+  sliderImgDialogVisable.value = false
   MG.identity
     .getPhoneCode({
       phoneNumber: passFormData.value.telNumber,
@@ -224,19 +212,19 @@
       appRefCode: config.appRefCode,
     })
     .then((res) => {
-      if (res == "楠岃瘉鐮佸彂閫佹垚鍔�") {
-        getSecond(60);
-        ElMessage.success(res);
+      if (res == '楠岃瘉鐮佸彂閫佹垚鍔�') {
+        getSecond(60)
+        ElMessage.success(res)
       } else {
-        ElMessage.error(res);
+        ElMessage.error(res)
       }
-    });
-};
+    })
+}
 
 watchEffect(() => {
   if (dialogFormVisible.value) {
   }
-});
+})
 
 //鐧诲綍
 
@@ -245,39 +233,38 @@
     phoneNumber: passFormData.value.telNumber,
     phoneCaptcha: passFormData.value.telCode,
     appRefCode: config.appRefCode,
-    platform: "string",
-  };
+    platform: 'string',
+  }
   MG.identity.loginByMobilePhone(query).then((res) => {
-    console.log("res", res);
-    userStore.setToken(res.data.accessToken);
+    console.log('res', res)
+    userStore.setToken(res.data.accessToken)
 
-    getUserInfo();
-  });
-};
+    getUserInfo()
+  })
+}
 
 const getUserInfo = () => {
   MG.identity.getCurrentAppUser().then((res) => {
-    console.log("res", res);
+    console.log('res', res)
     if (res) {
-      let userInfo = res.infoList.find((item) => item.type == "userInfo");
-      let userTypeObj = res.infoList.find((item) => item.type == "userType");
+      let userInfo = res.infoList.find((item) => item.type == 'userInfo')
+      let userTypeObj = res.infoList.find((item) => item.type == 'userType')
       const userData = {
-        userName: userInfo && userInfo.data ? JSON.parse(userInfo.data).name : "",
-        school: userInfo && userInfo.data ? JSON.parse(userInfo.data).school : "",
-        city: userInfo && userInfo.data ? JSON.parse(userInfo.data).city : "",
-        cityCode: userInfo && userInfo.data ? JSON.parse(userInfo.data).cityCode : "",
-        address: userInfo && userInfo.data ? JSON.parse(userInfo.data).address : "",
-        userType:
-          userTypeObj && userTypeObj.data ? JSON.parse(userTypeObj.data).userType : "",
-      };
-      localStorage.setItem("xiehe-isUserInfo", userData?.userType == "" ? "-1" : "1");
-      let teacherRole = res.roleLinks.find((item) => item.role.refCode == "teacher");
-      let teacherInfos = res.infoList.find((item) => item.type == "teacherInfo");
-      let wechatInfo = res.infoList.find((item) => item.type == "WeChat");
-      let studentInfo = res.infoList.find((item) => item.type == "Default");
-      let phoneInfo = res.secretList.find((item) => item.type == "MobilePhone");
+        userName: userInfo && userInfo.data ? JSON.parse(userInfo.data).name : '',
+        school: userInfo && userInfo.data ? JSON.parse(userInfo.data).school : '',
+        city: userInfo && userInfo.data ? JSON.parse(userInfo.data).city : '',
+        cityCode: userInfo && userInfo.data ? JSON.parse(userInfo.data).cityCode : '',
+        address: userInfo && userInfo.data ? JSON.parse(userInfo.data).address : '',
+        userType: userTypeObj && userTypeObj.data ? JSON.parse(userTypeObj.data).userType : '',
+      }
+      localStorage.setItem('xiehe-isUserInfo', userData?.userType == '' ? '-1' : '1')
+      let teacherRole = res.roleLinks.find((item) => item.role.refCode == 'teacher')
+      let teacherInfos = res.infoList.find((item) => item.type == 'teacherInfo')
+      let wechatInfo = res.infoList.find((item) => item.type == 'WeChat')
+      let studentInfo = res.infoList.find((item) => item.type == 'Default')
+      let phoneInfo = res.secretList.find((item) => item.type == 'MobilePhone')
       // let nameAndPassword = res.secretList.find((item) => item.type == 'LoginNameAndPassword')
-      let emailInfo = res.secretList.find((item) => item.type == "EMail");
+      let emailInfo = res.secretList.find((item) => item.type == 'EMail')
       if (teacherRole && teacherInfos) {
         userStore.setUserInfo({
           ...userData,
@@ -285,19 +272,19 @@
           phoneNumber: phoneInfo?.credential,
           Email: emailInfo ? emailInfo.credential : JSON.parse(teacherInfos.data).email,
           icon: wechatInfo?.icon,
-          role: "Teacher",
+          role: 'Teacher',
           roleId: teacherRole.role.id,
           userId: res.userId,
-        });
+        })
       } else if (wechatInfo) {
         userStore.setUserInfo({
           ...userData,
           ...wechatInfo,
           phoneNumber: phoneInfo?.credential,
           Email: emailInfo?.credential,
-          role: "Student",
+          role: 'Student',
           userId: res.userId,
-        });
+        })
       } else if (studentInfo) {
         userStore.setUserInfo({
           ...userData,
@@ -305,9 +292,9 @@
           icon: wechatInfo?.icon,
           phoneNumber: phoneInfo?.credential,
           Email: emailInfo?.credential,
-          role: "Student",
+          role: 'Student',
           userId: res.userId,
-        });
+        })
       } else if (phoneInfo) {
         userStore.setUserInfo({
           ...userData,
@@ -315,32 +302,32 @@
           name: phoneInfo?.credential,
           icon: phoneInfo?.icon,
           phoneNumber: phoneInfo?.credential,
-          role: "Student",
+          role: 'Student',
           userId: res.userId,
-        });
+        })
       }
     }
-    router.go(0);
-  });
-};
+    router.go(0)
+  })
+}
 
 // 鍊掕鏃�
 const getSecond = (time) => {
   if (!timer) {
-    countDown.value = time;
+    countDown.value = time
     timer = setInterval(() => {
-      countDown.value--;
+      countDown.value--
       if (countDown.value == 0) {
-        clearInterval(timer);
-        timer = null;
+        clearInterval(timer)
+        timer = null
       }
-    }, 1000);
+    }, 1000)
   }
-};
+}
 
 // 鐧诲綍鍜岄噸缃瘑鐮佹寜閽寜閽�
 const signInSystem = async (formEl) => {
-  if (!formEl) return;
+  if (!formEl) return
   formEl.validate((valid) => {
     if (valid) {
       // if (signUpWay.value === 'phone') {
@@ -354,27 +341,27 @@
       //   changePassword()
       // }
     }
-  });
-};
+  })
+}
 
 const logIn = () => {
-  dialogFormVisible.value = true;
-  flag.value = "logIn";
-};
+  dialogFormVisible.value = true
+  flag.value = 'logIn'
+}
 
 // 鎵撳紑娉ㄥ唽寮圭獥
 const signUp = () => {
-  dialogFormVisible.value = true;
-  flag.value = "signUp";
-};
+  dialogFormVisible.value = true
+  flag.value = 'signUp'
+}
 const wechatLoginOpen = () => {
-  signUpWay.value = "wechat";
-};
+  signUpWay.value = 'wechat'
+}
 
 defineExpose({
   logIn,
   signUp,
-});
+})
 </script>
 
 <style lang="less" scoped>
diff --git a/src/views/bookStore/detail.vue b/src/views/bookStore/detail.vue
index 8f3f4dd..e012616 100644
--- a/src/views/bookStore/detail.vue
+++ b/src/views/bookStore/detail.vue
@@ -39,7 +39,7 @@
                   @click="collectBook"
                   v-if="bookInfo.isFavourite"
                   class="buyIcon"
-                  src="@/assets/images/bookStore/shoucang.svg"
+                  src="@/assets/images/xiehe/detail/Collection_fill.png"
                   style="margin-right: 10px"
                 />
                 <span
@@ -52,7 +52,16 @@
                 <div class="collectText" @click="collectBook" v-if="bookInfo.isFavourite">
                   宸叉敹钘�
                 </div>
-                <div class="collectText" @click="collectBook" v-else>鏀惰棌</div>
+
+                <div class="collectText" @click="collectBook" v-else>
+                  <img
+                    @click="collectBook"
+                    class="buyIcon"
+                    src="@/assets/images/xiehe/detail/Collection.png"
+                    style="margin-right: 10px"
+                  />
+                  鏀惰棌
+                </div>
               </div>
             </div>
             <div class="authorBox">
@@ -171,60 +180,6 @@
             </div>
           </div>
         </div>
-        <el-dialog title="鑱旂郴缂栬緫" :visible.sync="contactVisible" width="30%" :lock-scroll="false">
-          <div class="contactBox" v-if="bookInfo.editor">
-            <div class="contacItem">
-              <i class="iconfont icon-renwu-ren contacIcon"></i>
-              {{ bookInfo.editor.name }}
-            </div>
-            <div class="contacItem">
-              <i class="iconfont icon-QQ contacIcon"></i>
-              {{ bookInfo.editor.qq }}
-            </div>
-            <div class="contacItem">
-              <i class="iconfont icon-tongxunlu contacIcon"></i>
-              {{ bookInfo.editor.phone }}
-            </div>
-            <div class="contacItem">
-              <i class="iconfont icon-dianhua contacIcon"></i>
-              {{ bookInfo.editor.telephone }}
-            </div>
-          </div>
-          <el-empty v-else description="鏆傛棤鏁版嵁" class="empty" :image-size="100"></el-empty>
-        </el-dialog>
-        <el-dialog title="淇℃伅鍙嶉" :visible.sync="dialogVisible" width="50%" :lock-scroll="false">
-          <div class="infoDialog">
-            <el-input
-              type="textarea"
-              :rows="8"
-              placeholder="璇︾粏鎻忚堪鎮ㄦ墍閬囧埌鐨勯棶棰橈紝鏈夊姪浜庡揩閫熺粰鎮ㄥ弽棣堬紒"
-              v-model="textarea"
-            >
-            </el-input>
-            <div class="subBtn">
-              <el-button type="primary" @click="sendDiscuss">鎻愪氦</el-button>
-            </div>
-            <div class="infoList">
-              <div class="infoItem" v-for="(item, index) in commentList" :key="index">
-                <div class="infoImg">
-                  <img v-if="item.icon" class="autoImg" :src="item.icon" alt="" />
-                  <i v-else class="el-icon-user-solid"></i>
-                </div>
-                <div class="infoContent">
-                  <div class="infoTitle">
-                    <div class="userNameBox">{{ item.content.name }}</div>
-                    <div class="userNameBox">
-                      {{ moment(item.createDate).format('YYYY-MM-DD') }}
-                    </div>
-                  </div>
-                  <div class="infoText">
-                    {{ item.content.content }}
-                  </div>
-                </div>
-              </div>
-            </div>
-          </div>
-        </el-dialog>
       </div>
     </div>
 
@@ -263,7 +218,8 @@
           </div>
         </div>
         <div v-else-if="editableTabsValue == '2'" class="catalogue">
-          <el-empty description="鏆傛棤鏁版嵁" />
+          <div v-if="bookInfo.catalogue" v-html="bookInfo.catalogue" class="catalogueContent"></div>
+          <el-empty description="鏆傛棤鏁版嵁" v-else />
         </div>
         <div v-else-if="editableTabsValue == '6'" class="supportingResources">
           <div class="resourcesBox">
@@ -334,6 +290,7 @@
 import { ref, onBeforeMount, inject, reactive, onMounted, watchEffect } from 'vue'
 const MG = inject('MG')
 const config = inject('config')
+const logIn = inject('logIn')
 import { useRouter, useRoute } from 'vue-router'
 import { applyBookStore } from '@/store'
 const route = useRoute()
@@ -385,6 +342,33 @@
     getBookResource()
   }
 })
+
+//鏀惰棌涔︾睄
+const collectBook = () => {
+  if (localStorage.getItem(config.tokenKey)) {
+    if (bookInfo.value.isFavourite) {
+      MG.store
+        .delProductLink({
+          productIds: [bookInfo.value.id],
+          linkType: 'FavoriteBookCity',
+        })
+        .then(() => {
+          bookInfo.value.isFavourite = false
+        })
+    } else {
+      let params = {
+        productIds: [bookInfo.value.id],
+        linkType: 'FavoriteBookCity',
+      }
+      MG.store.addProductLink(params).then((res) => {
+        bookInfo.value.isFavourite = true
+      })
+    }
+  } else {
+    logIn()
+    console.log(logIn)
+  }
+}
 
 //鐢宠璇曠敤
 const applyTextBook = () => {
@@ -938,4 +922,9 @@
     }
   }
 }
+.textbookContent,
+.authorInfo {
+  margin-top: 20px;
+  line-height: 28px;
+}
 </style>
diff --git a/src/views/home/index.vue b/src/views/home/index.vue
index 974cb22..3bd821d 100644
--- a/src/views/home/index.vue
+++ b/src/views/home/index.vue
@@ -32,7 +32,12 @@
           <div class="more">鏇村></div>
         </div>
         <div class="recommendList">
-          <div class="recommendItem" v-for="item in bookListData" :key="item.id">
+          <div
+            class="recommendItem"
+            v-for="item in bookListData"
+            :key="item.id"
+            @click="toDetail(item)"
+          >
             <div class="recommendItemImg">
               <img class="autoImg" :src="item.icon" />
             </div>
@@ -90,7 +95,12 @@
         <div class="more">鏇村></div>
       </div>
       <div class="recommendList">
-        <div class="recommendItem" v-for="item in navBookList" :key="item.id">
+        <div
+          class="recommendItem"
+          v-for="item in navBookList"
+          :key="item.id"
+          @click="toDetail(item)"
+        >
           <div class="recommendItemImg">
             <img class="autoImg" :src="item.icon" />
           </div>
@@ -121,6 +131,9 @@
 import teacherCertification from '@/views/personalCenter/teacherCertification.vue'
 import { ref, onBeforeMount, inject, reactive, onMounted } from 'vue'
 let screenheight = ref(document.documentElement.clientHeight / 2)
+import { useRouter, useRoute } from 'vue-router'
+const router = useRouter()
+
 const MG = inject('MG')
 const config = inject('config')
 const tool = inject('tool')
@@ -152,6 +165,15 @@
   getNavBookList()
 })
 
+const toDetail = (item) => {
+  router.push({
+    path: '/bookdetail',
+    query: {
+      bookId: item.id,
+    },
+  })
+}
+
 const handleClick = (tab, event) => {
   console.log(tab)
 

--
Gitblit v1.9.1