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