From 019abc739d9e231c2ebfe9ca537f82e2e1843496 Mon Sep 17 00:00:00 2001 From: QYF-GitLab1 <1940665526@qq.com> Date: 星期日, 24 八月 2025 21:24:39 +0800 Subject: [PATCH] 课程班级显示 --- src/views/bookStore/detail.vue | 470 ++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 406 insertions(+), 64 deletions(-) diff --git a/src/views/bookStore/detail.vue b/src/views/bookStore/detail.vue index abef0e0..6387276 100644 --- a/src/views/bookStore/detail.vue +++ b/src/views/bookStore/detail.vue @@ -20,9 +20,9 @@ </div> </el-tooltip> </div> - <div class="bookDetail"> + <div class="bookDetail" v-loading="loading"> <div class="bookImg"> - <img class="autoImg" :src="bookInfo.icon" alt="" /> + <img class="autoImg" :src="bookInfo.icon ? bookInfo.icon : defaultImg" alt="" /> </div> <span class="iconfont icon-tubiaozhizuo"></span> @@ -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"> @@ -167,63 +176,10 @@ <el-button v-if="currentRoute == 'teachingServices'" plain @click="addPaperBook" >绾歌川鏍蜂功</el-button > + <el-button plain @click="applyTextBook">鐢宠浣跨敤</el-button> </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> @@ -244,30 +200,112 @@ <div v-if="editableTabsValue == '1'" class="textbookInfo"> <div class="textbookInfoItem"> <div class="titleBorderBox">鍥句功绠�浠�</div> - <div class="textbookContent"></div> + <div class="textbookContent" v-if="bookInfo.content" v-html="bookInfo.content"></div> + <div v-else> + <el-empty description="鏆傛棤鏁版嵁" /> + </div> </div> <div class="textbookInfoItem"> <div class="titleBorderBox">浣滆�呯畝浠�</div> - <div class="authorInfo"></div> + <div + class="authorInfo" + v-if="bookInfo.authorIntroduction" + v-html="bookInfo.authorIntroduction" + ></div> + <div v-else> + <el-empty description="鏆傛棤鏁版嵁" /> + </div> </div> </div> - <div v-else-if="editableTabsValue == '2'" class="catalogue">bbbb</div> + <div v-else-if="editableTabsValue == '2'" class="catalogue"> + <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"> + <el-empty v-if="!resourceHave" :image-size="150" description="鏆傛棤鍐呭"></el-empty> + <div class="distribution" v-if="resourceHave"> + <div class="title">璧勬簮鍒嗗竷</div> + <div class="echartsBox"> + <div class="left"> + <div id="chartsContent" style="width: 600px; height: 400px"></div> + </div> + <div class="right"> + <div> + <p>璧勬簮绉嶇被</p> + <p> + <span class="num">{{ resourceData.length }}</span + >绉� + </p> + </div> + </div> + </div> + </div> + </div> + </div> + <div v-else class="catalogue"><el-empty description="鏆傛棤鏁版嵁" /></div> </div> - <div class="recommendBox"></div> + <div class="recommendBox"> + <div class="recommendTitle">鎺ㄨ崘鏁欐潗</div> + <div class="newRecommendList"> + <div class="recommendItem" v-for="item in recommendBookListData" :key="item.id"> + <div class="recommendItemImg"> + <img class="autoImg" :src="item.icon" /> + </div> + <div class="infoBox2"> + <div class="bookName2">{{ item.name }}</div> + <div class="author2"> + 浣滆�咃細{{ item.authorcaupress_author ? item.caupress_author : '-' }} + </div> + <div class="priceBox2"> + <span class="oldPrice" v-if="item.oldPrice">鍘熶环锛毬{ item.oldPrice }}</span> + <span class="price" v-if="item.price && item.price > 0"> + 瀹氫环锛毬� + <span>{{ item.price }}</span> + </span> + <span class="price" v-else> 瀹氫环锛�<span class="freePrice">鍏嶈垂</span> </span> + </div> + </div> + </div> + </div> + </div> </div> </div> </template> <script setup> import moment from 'moment' -import { ref, onBeforeMount, inject, reactive, onMounted } from 'vue' +import axios from 'axios' +import * as echarts from 'echarts' +import defaultImg from '@/assets/images/book-cover.png' +import imgIcon from '@/assets/images/digitalTextbooks/img.png' +import AudioIcon from '@/assets/images/digitalTextbooks/Audio.png' +import DIcon from '@/assets/images/digitalTextbooks/3D.png' +import PPTIcon from '@/assets/images/digitalTextbooks/PPT.png' +import shijuanIcon from '@/assets/images/digitalTextbooks/shijuan.png' +import shixunIcon from '@/assets/images/digitalTextbooks/shixun.png' +import tuozhanIcon from '@/assets/images/digitalTextbooks/tuozhan.png' +import videoIcon from '@/assets/images/digitalTextbooks/video.png' +import VRIcon from '@/assets/images/digitalTextbooks/VR.png' +import ziliaoIcon from '@/assets/images/digitalTextbooks/ziliao.png' +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() const router = useRouter() let bookInfo = ref({}) let digitalTextId = ref('') +let resourceData = ref([]) +let recommendBookListData = ref([]) let editableTabsValue = ref('1') +let resourceHave = ref(true) +let loading = ref(false) +var chartDom = null +var myChart = {} +var option = null const editableTabs = reactive([ { @@ -299,9 +337,183 @@ onMounted(() => { digitalTextId.value = route.query.bookId getBookDetail(digitalTextId.value) + getRecommendBookList() }) +watchEffect(() => { + if (editableTabsValue.value == '6') { + 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 = () => { + localStorage.setItem('applyBookInfo', JSON.stringify(bookInfo.value)) + router.push({ + path: '/textBookApply', + }) +} + +const getRecommendBookList = () => { + MG.store + .getProductList({ + path: 'recommendedTextbooks', + paging: { + start: 0, + size: 5, + }, + fields: { + author: [], + }, + }) + .then((res) => { + console.log(res, '鎺ㄨ崘鏁欐潗') + recommendBookListData.value = res.datas + }) +} + +const getBookResource = () => { + try { + axios + .get('https://yxjy.pumcp.com/books/resource/' + bookInfo.value.refCode + '/resource.json') + .then(async (res) => { + console.log(res, 'resource') + if (res.data.length > 0) { + res.data.forEach((item) => { + if (item.resourceTypeShow == '鍥剧墖') { + item.icon = imgIcon + } else if (item.resourceTypeShow == '瑙嗛') { + item.icon = videoIcon + } else if (item.resourceTypeShow == '闊抽') { + item.icon = AudioIcon + } else if (item.resourceTypeShow == 'PPT') { + item.icon = PPTIcon + } else if (item.resourceTypeShow == '鎷撳睍') { + item.icon = tuozhanIcon + } else if (item.resourceTypeShow == '璧勬枡') { + item.icon = ziliaoIcon + } else if (item.resourceTypeShow == '璇曞嵎') { + item.icon = shijuanIcon + } else if (item.resourceTypeShow == '3D') { + item.icon = DIcon + } else if (item.resourceTypeShow == '瀹炶') { + item.icon = shixunIcon + } else if (item.resourceTypeShow == 'VR') { + item.icon = VRIcon + } else { + item.icon = ziliaoIcon + } + }) + resourceData.value = await groupByResourceTypeShow(res.data) + resourceHave.value = true + console.log(resourceData.value, 'resourceData') + initChart(resourceData.value) + } else { + resourceHave.value = false + } + }) + .catch((error) => { + console.log(error, 'error1') + + resourceData = [] + resourceHave = false + }) + } catch (error) { + console.log(error, 'error') + resourceData = [] + resourceHave = false + } +} + +const groupByResourceTypeShow = (resources) => { + const grouped = resources.reduce((acc, item) => { + const key = item.resourceTypeShow + if (!acc[key]) { + acc[key] = { + resourceTypeShow: key, + list: [], + } + } + acc[key].list.push(item) + return acc + }, {}) + return Object.values(grouped) +} + +const initChart = (data) => { + let dataList = [] + let num = [] + data.forEach((item) => { + dataList.push(item.resourceTypeShow) + num.push(item.list.length) + }) + chartDom = document.getElementById('chartsContent') + console.log(chartDom, 'chartDom') + + myChart = echarts.init(chartDom) + myChart.setOption({ + tooltip: {}, + xAxis: { + data: dataList, + }, + yAxis: {}, + series: [ + { + name: '鏁伴噺', + type: 'bar', + data: num, + itemStyle: { + color: function (params) { + // params.dataIndex鏄暟鎹」鐨勭储寮曪紝浣犲彲浠ユ牴鎹繖涓储寮曟潵璁剧疆涓嶅悓鐨勯鑹� + const colors = [ + '#5EA1FF', + '#FF5A85', + '#7E7AFF', + '#3CB768', + '#FF8F54', + '#FF574B', + '#3DB0BF', + '#FBBB3B', + '#3B5EFB', + '#B1FB3B', + ] + return colors[params.dataIndex % colors.length] + }, + }, + }, + ], + }) +} + const getBookDetail = (id) => { + loading.value = true const query = { path: '*', queryType: '*', @@ -328,6 +540,7 @@ MG.store.getProductDetail(query).then((res) => { console.log(res, 'res') bookInfo.value = res.datas + loading.value = false console.log(res.datas, 'res') }) } @@ -572,8 +785,10 @@ .detailContent { margin-top: 30px; + display: flex; + justify-content: space-between; .resourceBox { - width: 80%; + width: 76%; } .textbookInfo { padding: 20px 0; @@ -590,4 +805,131 @@ .textbookInfoItem { margin-top: 20px; } + +.distribution { + .title { + margin: 10px 0; + font-weight: bold; + } + .echartsBox { + height: 400px; + border-radius: 7px 7px 7px 7px; + border: 1px solid #e4e7ed; + display: flex; + justify-content: space-between; + margin-bottom: 20px; + } + .left { + } + .right { + background: rgba(64, 158, 255, 0.09); + display: flex; + align-items: center; + justify-content: center; + text-align: center; + width: 200px; + p { + line-height: 30px; + } + .num { + font-size: 18px; + font-weight: bold; + } + } + .list { + display: flex; + margin-bottom: 40px; + .listItem { + width: 100px; + display: block; + box-sizing: border-box; + .imgBox { + margin: 0 auto; + position: relative; + width: 80px; + height: 80px; + } + .bookInfo { + margin: 0; + overflow: hidden; + text-align: center; + .title { + color: #333; + margin: 10px 0; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + } + } + } + } +} + +.recommendBox { + width: 23%; + border: 1px solid #e4e7ed; + border-radius: 10px; + .recommendTitle { + height: 50px; + line-height: 50px; + padding-left: 20px; + border-bottom: 1px solid #e4e7ed; + color: #333333; + font-weight: 700; + } +} + +.newRecommendList { + padding-top: 0; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + .recommendItem { + margin-right: 20px; + height: 300px; + background-repeat: no-repeat; + background-size: 100% 100%; + cursor: pointer; + background-color: #fff; + padding-top: 10px; + margin-top: 10px; + &:last-child { + margin-right: 0; + } + } + .recommendItemImg { + width: 150px; + height: 200px; + position: relative; + margin: 0 auto; + } + .infoBox2 { + text-align: center; + margin-top: 10px; + } + .author2 { + margin-top: 10px; + } + .priceBox2 { + margin-top: 10px; + .oldPrice { + font-size: 16px; + color: #444444; + text-decoration: line-through; + margin-right: 20px; + } + .price { + span { + font-weight: bold; + font-size: 14px; + } + } + } +} +.textbookContent, +.authorInfo { + margin-top: 20px; + line-height: 28px; +} </style> -- Gitblit v1.9.1