| | |
| | | "dependencies": { |
| | | "@amap/amap-jsapi-loader": "^1.0.1", |
| | | "axios": "^1.11.0", |
| | | "echarts": "^5.6.0", |
| | | "element-plus": "^2.10.7", |
| | | "less": "^4.4.0", |
| | | "moment": "^2.30.1", |
| | |
| | | "node": ">= 0.4" |
| | | } |
| | | }, |
| | | "node_modules/echarts": { |
| | | "version": "5.6.0", |
| | | "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.6.0.tgz", |
| | | "integrity": "sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==", |
| | | "license": "Apache-2.0", |
| | | "dependencies": { |
| | | "tslib": "2.3.0", |
| | | "zrender": "5.6.1" |
| | | } |
| | | }, |
| | | "node_modules/echarts/node_modules/tslib": { |
| | | "version": "2.3.0", |
| | | "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz", |
| | | "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", |
| | | "license": "0BSD" |
| | | }, |
| | | "node_modules/electron-to-chromium": { |
| | | "version": "1.5.201", |
| | | "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.201.tgz", |
| | |
| | | "funding": { |
| | | "url": "https://github.com/sponsors/sindresorhus" |
| | | } |
| | | }, |
| | | "node_modules/zrender": { |
| | | "version": "5.6.1", |
| | | "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.6.1.tgz", |
| | | "integrity": "sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==", |
| | | "license": "BSD-3-Clause", |
| | | "dependencies": { |
| | | "tslib": "2.3.0" |
| | | } |
| | | }, |
| | | "node_modules/zrender/node_modules/tslib": { |
| | | "version": "2.3.0", |
| | | "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz", |
| | | "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", |
| | | "license": "0BSD" |
| | | } |
| | | }, |
| | | "dependencies": { |
| | |
| | | "gopd": "^1.2.0" |
| | | } |
| | | }, |
| | | "echarts": { |
| | | "version": "5.6.0", |
| | | "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.6.0.tgz", |
| | | "integrity": "sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==", |
| | | "requires": { |
| | | "tslib": "2.3.0", |
| | | "zrender": "5.6.1" |
| | | }, |
| | | "dependencies": { |
| | | "tslib": { |
| | | "version": "2.3.0", |
| | | "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz", |
| | | "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" |
| | | } |
| | | } |
| | | }, |
| | | "electron-to-chromium": { |
| | | "version": "1.5.201", |
| | | "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.201.tgz", |
| | |
| | | "resolved": "https://registry.npmmirror.com/yoctocolors/-/yoctocolors-2.1.1.tgz", |
| | | "integrity": "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==", |
| | | "dev": true |
| | | }, |
| | | "zrender": { |
| | | "version": "5.6.1", |
| | | "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.6.1.tgz", |
| | | "integrity": "sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==", |
| | | "requires": { |
| | | "tslib": "2.3.0" |
| | | }, |
| | | "dependencies": { |
| | | "tslib": { |
| | | "version": "2.3.0", |
| | | "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz", |
| | | "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | "dependencies": { |
| | | "@amap/amap-jsapi-loader": "^1.0.1", |
| | | "axios": "^1.11.0", |
| | | "echarts": "^5.6.0", |
| | | "element-plus": "^2.10.7", |
| | | "less": "^4.4.0", |
| | | "moment": "^2.30.1", |
| | | "pinia": "^3.0.3", |
| | | "spark-md5": "^3.0.2", |
| | | "vue": "^3.5.18", |
| | | "vue-clipboard3": "^2.0.0", |
| | | "vue-baidu-map-3x": "^1.0.40", |
| | | "vue-clipboard3": "^2.0.0", |
| | | "vue-router": "^4.5.1" |
| | | }, |
| | | "devDependencies": { |
| | |
| | | export const goodsStore = `defaultGoodsStore${appId}` // 默认商品库(书城) |
| | | export const publicStore = `defaultPublicStore${appId}` // 默认资源开放仓储 |
| | | export const publicRepository = `defaultPublicRepository${appId}` // 默认资源开放库 |
| | | export const textBookResourceUrl = 'https://yxjy.pumcp.com/books/resource/' |
| | | |
| | | export const reg_tel = |
| | | /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/ // 电话号正则 |
| | |
| | | () => { |
| | | $router.push({ |
| | | path: '/home', |
| | | }); |
| | | }) |
| | | } |
| | | " |
| | | src="@/assets/images/xiehe/home/Group_303.png" |
| | |
| | | <a |
| | | @click=" |
| | | () => { |
| | | console.log(loginRef.value); |
| | | loginRef.logIn(); |
| | | console.log(loginRef.value) |
| | | loginRef.logIn() |
| | | } |
| | | " |
| | | >注册/登录</a |
| | |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import login from "./login.vue"; |
| | | import { onMounted, ref } from "vue"; |
| | | import { Search } from "@element-plus/icons-vue"; |
| | | import { useUserStore } from "@/store"; |
| | | import { useRouter } from "vue-router"; |
| | | const userStore = useUserStore(); |
| | | const router = useRouter(); |
| | | import login from './login.vue' |
| | | import { onMounted, ref } from 'vue' |
| | | import { Search } from '@element-plus/icons-vue' |
| | | import { useUserStore } from '@/store' |
| | | import { useRouter } from 'vue-router' |
| | | const userStore = useUserStore() |
| | | const router = useRouter() |
| | | |
| | | const loginRef = ref(); |
| | | const loginRef = ref() |
| | | const props = defineProps({ |
| | | hideSerch: { |
| | | type: Boolean, |
| | |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | }); |
| | | }) |
| | | |
| | | let searchKey = ref(""); |
| | | let userInfo = ref(""); |
| | | let searchKey = ref('') |
| | | let userInfo = ref('') |
| | | const navData = ref([ |
| | | { |
| | | name: "首页", |
| | | path: "/home", |
| | | name: '首页', |
| | | path: '/home', |
| | | }, |
| | | { |
| | | name: "教育出版", |
| | | path: "/bookStore", |
| | | name: '教育出版', |
| | | path: '/bookStore', |
| | | }, |
| | | { |
| | | name: "读者服务", |
| | | path: "/teachingServices", |
| | | name: '读者服务', |
| | | path: '/teachingServices', |
| | | }, |
| | | { |
| | | name: "关于我们", |
| | | path: "/aboutUs", |
| | | name: '关于我们', |
| | | path: '/aboutUs', |
| | | }, |
| | | ]); |
| | | ]) |
| | | |
| | | onMounted(() => { |
| | | userInfo.value = userStore.userInfo; |
| | | console.log(userInfo.value, "userInfo"); |
| | | }); |
| | | userInfo.value = userStore.userInfo |
| | | console.log(userInfo.value, 'userInfo') |
| | | }) |
| | | |
| | | const gotoSearch = () => {}; |
| | | const gotoSearch = () => {} |
| | | const handleCommand = (item) => { |
| | | if (item === "gotoPersonalCenter") { |
| | | if (item === 'gotoPersonalCenter') { |
| | | router.push({ |
| | | path: "/personalCenter", |
| | | }); |
| | | path: '/personalCenter', |
| | | }) |
| | | } |
| | | if (item === "logout") { |
| | | localStorage.clear(); |
| | | if (item === 'logout') { |
| | | localStorage.clear() |
| | | router.push({ |
| | | path: "/home", |
| | | }); |
| | | path: '/home', |
| | | }) |
| | | } |
| | | }; |
| | | } |
| | | const gotoPage = (item) => { |
| | | router.push(item.path); |
| | | }; |
| | | router.push(item.path) |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | |
| | | import MG from '@/assets/js/middleGround/WebMiddleGroundApi.js' |
| | | import toolClass from '@/assets/js/toolClass.js' |
| | | import config from '@/assets/js/config.js' |
| | | import zhCn from 'element-plus/dist/locale/zh-cn.mjs' |
| | | |
| | | const app = createApp(App) |
| | | |
| | |
| | | app.use(ElementPlus) |
| | | app.use(createPinia()) |
| | | app.use(router) |
| | | |
| | | app.use(ElementPlus, { |
| | | locale: zhCn, |
| | | }) |
| | | app.mount('#app') |
| | |
| | | name: 'bookStore', |
| | | component: bookStore, |
| | | }, |
| | | { |
| | | path: '/textBookApply', |
| | | name: 'textBookApply', |
| | | component: () => import('@/views/bookStore/textBookApply.vue'), |
| | | }, |
| | | //个人中心 |
| | | { |
| | | path: '/personalCenter', |
| | |
| | | <el-button v-if="currentRoute == 'teachingServices'" plain @click="addPaperBook" |
| | | >纸质样书</el-button |
| | | > |
| | | <el-button plain @click="applyTextBook">申请使用</el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | <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 == '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="recommendBox"></div> |
| | | <div class="right"> |
| | | <div> |
| | | <p>资源种类</p> |
| | | <p> |
| | | <span class="num">{{ resourceData.length }}</span |
| | | >种 |
| | | </p> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </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 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') |
| | | 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) |
| | | var chartDom = null |
| | | var myChart = {} |
| | | var option = null |
| | | const editableTabs = reactive([ |
| | | { |
| | | title: '教材信息', |
| | |
| | | onMounted(() => { |
| | | digitalTextId.value = route.query.bookId |
| | | getBookDetail(digitalTextId.value) |
| | | getRecommendBookList() |
| | | }) |
| | | |
| | | watchEffect(() => { |
| | | if (editableTabsValue.value == '6') { |
| | | getBookResource() |
| | | } |
| | | }) |
| | | |
| | | //申请试用 |
| | | 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) => { |
| | | const query = { |
| | |
| | | |
| | | .detailContent { |
| | | margin-top: 30px; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | .resourceBox { |
| | | width: 80%; |
| | | width: 76%; |
| | | } |
| | | .textbookInfo { |
| | | padding: 20px 0; |
| | |
| | | .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; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <div class="classificationBox"> |
| | | <div style="width: 100px">分类:</div> |
| | | <div class="classificaListBox"> |
| | | <div class="classificaItem" v-for="(item, index) in classfeild" :key="index"> |
| | | <div |
| | | class="classificaItem" |
| | | :class="{ active: currentLevel == item.value }" |
| | | v-for="(item, index) in classfeild" |
| | | :key="index" |
| | | @click="changeLevel(item)" |
| | | > |
| | | {{ item.name }} |
| | | </div> |
| | | </div> |
| | |
| | | <div class="bookList"> |
| | | <div class="bookfilterList"> |
| | | <div class="listTitle"> |
| | | <div>结果:共计***条</div> |
| | | <div>结果:共计{{ total }}条</div> |
| | | <div style="width: 300px"> |
| | | <el-input |
| | | v-model="input3" |
| | |
| | | class="input-with-select" |
| | | > |
| | | <template #append> |
| | | <el-button :icon="Search" /> |
| | | <el-button :icon="Search" @click="getBookList" /> |
| | | </template> |
| | | </el-input> |
| | | </div> |
| | |
| | | <div class="recommendBox"> |
| | | <div class="recommendTitle">推荐教材</div> |
| | | <div class="newRecommendList"> |
| | | <div class="recommendItem" v-for="item in bookListData" :key="item.id"> |
| | | <div class="recommendItem" v-for="item in recommendBookListData" :key="item.id"> |
| | | <div class="recommendItemImg"> |
| | | <img class="autoImg" :src="item.icon" /> |
| | | </div> |
| | |
| | | import { Search } from '@element-plus/icons-vue' |
| | | const input3 = ref('') |
| | | let bookListData = ref([]) |
| | | const total = ref(50) |
| | | let recommendBookListData = ref([]) |
| | | const total = ref(0) |
| | | const currentPage1 = ref(1) |
| | | const router = useRouter() |
| | | let currentLevel = ref('all') |
| | | |
| | | const toDetail = (item) => { |
| | | router.push({ |
| | |
| | | }) |
| | | } |
| | | |
| | | const changeLevel = (item) => { |
| | | currentLevel.value = item.value |
| | | getBookList() |
| | | } |
| | | |
| | | const getBanner = () => { |
| | | MG.resource |
| | | .getItem({ |
| | | path: 'banner\\educationPublishing', |
| | | fields: { link: [] }, |
| | | paging: { start: 0, size: 9 }, |
| | | paging: { start: 0, size: 20 }, |
| | | }) |
| | | .then((res) => { |
| | | banner.push(...res.datas) |
| | |
| | | getBookList() |
| | | } |
| | | |
| | | const getBookList = () => { |
| | | const getRecommendBookList = () => { |
| | | MG.store |
| | | .getProductList({ |
| | | path: 'recommendedTextbooks', |
| | |
| | | }) |
| | | .then((res) => { |
| | | console.log(res, '推荐教材') |
| | | recommendBookListData.value = res.datas |
| | | }) |
| | | } |
| | | |
| | | const getBookList = () => { |
| | | const query = { |
| | | path: '*', |
| | | queryType: '*', |
| | | storeInfo: 'defaultGoodsStore1', |
| | | paging: { |
| | | start: (currentPage1.value - 1) * 20, |
| | | size: 20, |
| | | }, |
| | | fields: {}, |
| | | } |
| | | if (currentLevel.value !== 'all') { |
| | | query.fields['teachingLevel='] = currentLevel.value |
| | | } |
| | | if (input3.value) { |
| | | query.fields['Name*'] = input3.value |
| | | } |
| | | MG.store.getProductList(query).then((res) => { |
| | | console.log(res, '11111111111') |
| | | bookListData.value = res.datas |
| | | total.value = res.total |
| | | }) |
| | | } |
| | | |
| | |
| | | getBanner() |
| | | classifList() |
| | | getBookList() |
| | | getRecommendBookList() |
| | | }) |
| | | </script> |
| | | |
| | |
| | | margin: 20px 0; |
| | | padding-bottom: 30px; |
| | | } |
| | | |
| | | .active { |
| | | background-color: #ebf8f8; |
| | | border: 1px solid #144941; |
| | | color: #144941; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="contentBox"> |
| | | <div class="generateEorder"> |
| | | <div class="crumbBox"> |
| | | <el-breadcrumb separator-class="el-icon-arrow-right"> |
| | | <span style="float: left">当前位置:</span> |
| | | <el-breadcrumb-item :to="{ path: '/textbooks' }">数字教材</el-breadcrumb-item> |
| | | <el-breadcrumb-item>申请试用</el-breadcrumb-item> |
| | | </el-breadcrumb> |
| | | </div> |
| | | </div> |
| | | <div class="content"> |
| | | <div class="title">协和云课堂数字教材试用申请表</div> |
| | | <div class="center"> |
| | | <div class="headline">教材申请</div> |
| | | <div class="book-list"> |
| | | <div class="book-example"> |
| | | <div class="imgBox"> |
| | | <img :src="textBookInfo.icon" alt /> |
| | | </div> |
| | | <div class="bookname">{{ textBookInfo.name }}</div> |
| | | </div> |
| | | </div> |
| | | <div class="headline">授课情况</div> |
| | | <el-form |
| | | label-width="200px" |
| | | label-position="right" |
| | | :model="formData" |
| | | class="teachingSituationForm" |
| | | :rules="rules" |
| | | ref="teachingSituationForm" |
| | | > |
| | | <el-form-item label="课程名称:" prop="courseName"> |
| | | <el-input v-model="formData.courseName"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="学生层次:" prop="studentLevel"> |
| | | <el-input v-model="formData.studentLevel"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="学生人数/年:" prop="studentsNumber"> |
| | | <el-input v-model="formData.studentsNumber"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="现在使用教材所属出版社:" prop="teachingMaterialPress"> |
| | | <el-input v-model="formData.teachingMaterialPress"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="所用教材:" prop="teachingMaterials"> |
| | | <el-input v-model="formData.teachingMaterials"></el-input> |
| | | </el-form-item> |
| | | </el-form> |
| | | <div class="btn"> |
| | | <el-button :loading="loading" @click="submit(teachingSituationForm)">提交</el-button> |
| | | <el-button @click="toSelectBook()">返回</el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, inject, onMounted } from 'vue' |
| | | import { useRoute } from 'vue-router' |
| | | const MG = inject('MG') |
| | | import { useUserStore } from '@/store' |
| | | import { ElMessage, ElMessageBox } from 'element-plus' |
| | | |
| | | import { useRouter } from 'vue-router' |
| | | const toolClass = inject('toolClass') |
| | | const userStore = useUserStore() |
| | | onMounted(() => { |
| | | getType() |
| | | }) |
| | | |
| | | let textBookInfo = ref(JSON.parse(localStorage.getItem('applyBookInfo'))) |
| | | let loading = ref(false) |
| | | let formData = ref({ |
| | | courseName: '', |
| | | studentLevel: '', |
| | | studentsNumber: '', |
| | | teachingMaterialPress: '', |
| | | teachingMaterials: '', |
| | | }) |
| | | |
| | | let workInfo = ref([]) |
| | | const teachingSituationForm = ref() |
| | | |
| | | const rules = { |
| | | courseName: [{ required: true, message: '请填写课程名称' }], |
| | | studentLevel: [{ required: true, message: '请填写学生层次' }], |
| | | studentsNumber: [{ required: true, message: '请填写学生人数/年' }], |
| | | teachingMaterialPress: [{ required: true, message: '请填写现在使用教材所属出版社' }], |
| | | teachingMaterials: [{ required: true, message: '请填写所用教材' }], |
| | | } |
| | | |
| | | const getType = () => { |
| | | const data = { |
| | | refCodes: ['sampleBook'], |
| | | } |
| | | MG.resource.getCmsTypeByRefCode(data).then((res) => { |
| | | console.log(res, 'sampleBook') |
| | | workInfo.value = res[0].cmsTypeLinks[0].children |
| | | }) |
| | | } |
| | | |
| | | const submit = async (formEl) => { |
| | | if (!formEl) return |
| | | formEl.validate((valid) => { |
| | | if (valid) { |
| | | loading.value = true |
| | | const contentData = { |
| | | id: textBookInfo.value.id, |
| | | title: textBookInfo.value.name, |
| | | icon: textBookInfo.value.icon, |
| | | isbn: textBookInfo.value.tourism_ISBN, |
| | | author: textBookInfo.value.tourism_author, |
| | | price: textBookInfo.value.price, |
| | | } |
| | | const data = { |
| | | topicIdOrRefCode: 'applyDigitalBook', |
| | | name: userStore.userInfo?.name || '-', |
| | | cmsTypeRefCode: 'sampleBook ', |
| | | content: JSON.stringify([contentData]), |
| | | state: 'WaitAudit', |
| | | type: 'applyDigitalBook', |
| | | newDataListRequest: toolClass.worksDataBytool(workInfo.value, formData.value), |
| | | } |
| | | MG.ugc.newTopicMessage(data).then((res) => { |
| | | loading.value = false |
| | | if (res) { |
| | | ElMessageBox.confirm('您的试用申请已提交,管理员审核中!', 'success', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'success', |
| | | }) |
| | | .then(() => { |
| | | this.$router.go(-1) |
| | | formEl.resetFields() |
| | | }) |
| | | .catch(() => { |
| | | this.$router.go(-1) |
| | | formEl.resetFields() |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | const toSelectBook = () => {} |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .imgBox { |
| | | display: inline-block; |
| | | position: relative; |
| | | width: 100px; |
| | | height: 140px; |
| | | background: #fff; |
| | | } |
| | | .imgBox img { |
| | | width: auto; |
| | | height: auto; |
| | | max-width: 100%; |
| | | max-height: 100%; |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | margin: auto; |
| | | } |
| | | .contentBox { |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | .generateEorder { |
| | | width: 1200px; |
| | | margin: 0 auto; |
| | | padding: 20px 0; |
| | | } |
| | | .xian { |
| | | width: 100%; |
| | | height: 5px; |
| | | } |
| | | /* content */ |
| | | .content { |
| | | border: 1px solid #dcdcdc; |
| | | margin: 11px auto 111px; |
| | | } |
| | | .content .title { |
| | | margin: 0 auto; |
| | | width: 1160px; |
| | | border-bottom: 2px dashed #dcdcdc; |
| | | font-size: 24px; |
| | | color: #333; |
| | | text-align: center; |
| | | line-height: 70px; |
| | | font-weight: bold; |
| | | } |
| | | .content .center { |
| | | width: 1100px; |
| | | margin: 0 auto; |
| | | } |
| | | .headline { |
| | | font-size: 16px; |
| | | color: #333; |
| | | font-weight: bold; |
| | | padding-top: 40px; |
| | | } |
| | | .list { |
| | | background-color: #f1f8fe; |
| | | border-radius: 2px; |
| | | font-size: 14px; |
| | | line-height: 28px; |
| | | margin-top: 20px; |
| | | color: #333; |
| | | padding: 10px 0 15px 20px; |
| | | } |
| | | .personal { |
| | | font-weight: bold; |
| | | } |
| | | .checkBox { |
| | | position: absolute; |
| | | top: 86px; |
| | | left: 30px; |
| | | } |
| | | .book-example { |
| | | position: relative; |
| | | display: inline-block; |
| | | overflow: hidden; |
| | | padding: 20px 40px; |
| | | text-align: center; |
| | | } |
| | | .book-example img { |
| | | border: 1px solid #dcdcdc; |
| | | } |
| | | .bookname { |
| | | width: 100%; |
| | | white-space: nowrap; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | font-size: 15px; |
| | | color: #333; |
| | | line-height: 29px; |
| | | } |
| | | .book-list { |
| | | margin-top: 10px; |
| | | border: 1px solid #dcdcdc; |
| | | overflow: hidden; |
| | | margin-bottom: 10px; |
| | | } |
| | | .btn { |
| | | margin: 50px 0; |
| | | text-align: center; |
| | | } |
| | | .teachingSituationForm { |
| | | margin-top: 20px; |
| | | } |
| | | </style> |
| | | <style> |
| | | .generateEorder .el-button { |
| | | width: 120px; |
| | | height: 40px; |
| | | background-color: #2b68cd; |
| | | color: #fff; |
| | | } |
| | | .generateEorder .el-button:last-child { |
| | | border: solid 1px #2b68cd; |
| | | color: #2b68cd; |
| | | background-color: #fff; |
| | | } |
| | | |
| | | .generateEorder .el-input__inner { |
| | | border-radius: 0; |
| | | border: none; |
| | | border-bottom: 1px solid #eee; |
| | | width: 315px; |
| | | height: 30px; |
| | | } |
| | | </style> |
| | |
| | | </div> |
| | | <div class="contentBox"> |
| | | <div class="funBox"> |
| | | <div class="authentication"></div> |
| | | <div class="manual"></div> |
| | | <div class="authentication"> |
| | | <div class="cardNav" @click="toAuthentication(true)"> |
| | | <div class="cardTitle">教师认证</div> |
| | | <div class="cardText"> |
| | | 学校任课老师上传教师证明文件,通过认证后,可进行样书与教学资源下载申请 |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="manual"> |
| | | <div class="cardNav" @click="toAuthentication(false)"> |
| | | <div class="cardTitle">操作手册</div> |
| | | <div class="cardText">快速了解使用步骤,轻松开启教学支持之旅。</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="bookListTitle"> |
| | | <div class="title" style="display: flex; line-height: 50px"> |
| | | <div>新闻资讯</div> |
| | | <div class="titleTabs"> |
| | | <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick"> |
| | | <el-tab-pane label="高等职业教材" name="first"> </el-tab-pane> |
| | | <el-tab-pane label="专升本教材" name="second"></el-tab-pane> |
| | | <el-tab-pane label="协和医学院教材" name="third"></el-tab-pane> |
| | | <div>教学导航</div> |
| | | <div class="titleTabs" v-if="classfeild.length > 0"> |
| | | <el-tabs v-model="activeName" @tab-change="handleClick"> |
| | | <el-tab-pane |
| | | v-for="item in classfeild" |
| | | :key="item.value" |
| | | :label="item.name" |
| | | :name="item.value" |
| | | /> |
| | | </el-tabs> |
| | | </div> |
| | | </div> |
| | |
| | | <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 navBookList" :key="item.id"> |
| | | <div class="recommendItemImg"> |
| | | <img class="autoImg" :src="item.icon" /> |
| | | </div> |
| | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <teacherCertification :isShow="teacherDialog" @dialog-Change="dialogChange" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import moment from 'moment' |
| | | import { ElMessage } from 'element-plus' |
| | | import teacherCertification from '@/views/personalCenter/teacherCertification.vue' |
| | | import { ref, onBeforeMount, inject, reactive, onMounted } from 'vue' |
| | | let screenheight = ref(document.documentElement.clientHeight / 2) |
| | | const MG = inject('MG') |
| | | const config = inject('config') |
| | | const tool = inject('tool') |
| | | const toolClass = inject('toolClass') |
| | | const banner = reactive([]) |
| | | const informationList = reactive([]) |
| | | let classfeild = ref([]) |
| | | let activeName = ref('A1') |
| | | |
| | | let bookListData = ref([]) |
| | | let navBookList = ref([]) |
| | | let teacherDialog = ref(false) |
| | | onBeforeMount(() => { |
| | | console.log(document.documentElement.clientWidth / 2.628) |
| | | |
| | | window.onresize = () => { |
| | | let c = 2.628 |
| | | if (document.documentElement.clientWidth >= 1220) { |
| | |
| | | |
| | | onMounted(() => { |
| | | getBanner() |
| | | classifList() |
| | | getInformationList() |
| | | getBookList() |
| | | getNavBookList() |
| | | }) |
| | | |
| | | const handleClick = (tab, event) => { |
| | | console.log(tab) |
| | | |
| | | activeName.value = tab |
| | | getNavBookList() |
| | | } |
| | | |
| | | const classifList = () => { |
| | | const query = { |
| | | refCodes: ['digitalTextbooks'], |
| | | } |
| | | MG.resource.getCmsTypeByRefCode(query).then((res) => { |
| | | const types = toolClass.handleTypeList(res) |
| | | const typeData = types[0].cmsTypeLinks[0].children |
| | | const temp_classfeild = typeData.find((item) => item.typeField.refCode === 'teachingLevel') |
| | | ?.typeField.cfg.option |
| | | |
| | | const noCheck = temp_classfeild.map((item) => { |
| | | return { |
| | | name: item.name, |
| | | value: item.value, |
| | | } |
| | | }) |
| | | console.log(noCheck, 'noCheck') |
| | | |
| | | classfeild.value = noCheck |
| | | console.log(classfeild, 'classfeild') |
| | | }) |
| | | } |
| | | |
| | | const getNavBookList = () => { |
| | | MG.store |
| | | .getProductList({ |
| | | path: '*', |
| | | queryType: '*', |
| | | storeInfo: 'defaultGoodsStore1', |
| | | paging: { |
| | | start: 0, |
| | | size: 5, |
| | | }, |
| | | fields: { |
| | | 'teachingLevel=': activeName.value, |
| | | }, |
| | | }) |
| | | .then((res) => { |
| | | console.log(res, '11111111111') |
| | | navBookList.value = res.datas |
| | | }) |
| | | } |
| | | |
| | | const dialogChange = (val) => { |
| | | getTeacherInfo() |
| | | if (val == false) { |
| | | teacherDialog.value = false |
| | | } else { |
| | | teacherDialog.value = true |
| | | } |
| | | } |
| | | |
| | | //教师信息 |
| | | function getTeacherInfo() { |
| | | const data = { |
| | | start: 0, |
| | | size: 10, |
| | | topicIdOrRefCode: 'teacherRoleApproval', |
| | | appRefCode: config.appRefCode, |
| | | sort: { |
| | | type: 'Desc', |
| | | field: 'CreateDate', |
| | | }, |
| | | } |
| | | MG.ugc.getTopicMessageList(data).then((res) => { |
| | | try { |
| | | const resData = res.datas.find((i) => i.appUserCreator.userId == userId.value) |
| | | if (resData) { |
| | | teacherState.value = resData.state |
| | | if (resData.feedBack != null) { |
| | | reasonTxt.value = JSON.parse(resData.feedBack).reason |
| | | } |
| | | } else { |
| | | teacherState.value = '' |
| | | } |
| | | loading.value = false |
| | | } catch (error) { |
| | | loading.value = false |
| | | } |
| | | }) |
| | | } |
| | | |
| | | const toAuthentication = (type) => { |
| | | if (type) { |
| | | teacherDialog.value = true |
| | | } else { |
| | | ElMessage({ |
| | | message: '建设中...', |
| | | type: 'warning', |
| | | }) |
| | | } |
| | | } |
| | | |
| | | const getBookList = () => { |
| | | MG.store |
| | |
| | | margin-bottom: 60px; |
| | | .authentication { |
| | | width: 40%; |
| | | height: 80px; |
| | | height: 100px; |
| | | background-repeat: no-repeat; |
| | | background-size: 100% 100%; |
| | | background-image: url('@/assets/images/xiehe/home/jiaoshirenzheng.png'); |
| | | } |
| | | .manual { |
| | | width: 40%; |
| | | height: 80px; |
| | | height: 100px; |
| | | background-repeat: no-repeat; |
| | | background-size: 100% 100%; |
| | | background-image: url('@/assets/images/xiehe/home/jiaoshirenzheng.png'); |
| | |
| | | |
| | | .titleTabs { |
| | | margin-left: 50px; |
| | | width: 70%; |
| | | } |
| | | .bookListTitle { |
| | | display: flex; |
| | |
| | | cursor: pointer; |
| | | } |
| | | } |
| | | .cardNav { |
| | | margin-left: 30%; |
| | | margin-top: 20px; |
| | | padding-right: 20px; |
| | | cursor: pointer; |
| | | .cardTitle { |
| | | font-size: 28px; |
| | | color: #ffffff; |
| | | } |
| | | .cardText { |
| | | font-size: 14px; |
| | | color: #ccc; |
| | | margin-top: 10px; |
| | | } |
| | | } |
| | | </style> |