Merge branch 'master' of http://182.92.203.7:2001/r/xiehe_website
16个文件已删除
16个文件已添加
1 文件已重命名
29个文件已修改
| | |
| | | "name": "xiehe", |
| | | "version": "0.0.0", |
| | | "dependencies": { |
| | | "@amap/amap-jsapi-loader": "^1.0.1", |
| | | "axios": "^1.11.0", |
| | | "element-plus": "^2.10.7", |
| | | "less": "^4.4.0", |
| | |
| | | "pinia": "^3.0.3", |
| | | "spark-md5": "^3.0.2", |
| | | "vue": "^3.5.18", |
| | | "vue-baidu-map-3x": "^1.0.40", |
| | | "vue-clipboard3": "^2.0.0", |
| | | "vue-router": "^4.5.1" |
| | | }, |
| | |
| | | "engines": { |
| | | "node": "^20.19.0 || >=22.12.0" |
| | | } |
| | | }, |
| | | "node_modules/@amap/amap-jsapi-loader": { |
| | | "version": "1.0.1", |
| | | "resolved": "https://registry.npmmirror.com/@amap/amap-jsapi-loader/-/amap-jsapi-loader-1.0.1.tgz", |
| | | "integrity": "sha512-nPyLKt7Ow/ThHLkSvn2etQlUzqxmTVgK7bIgwdBRTg2HK5668oN7xVxkaiRe3YZEzGzfV2XgH5Jmu2T73ljejw==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/@ampproject/remapping": { |
| | | "version": "2.3.0", |
| | |
| | | } |
| | | } |
| | | }, |
| | | "node_modules/@yangjianfei/bmaplib.lushu": { |
| | | "version": "1.0.0", |
| | | "resolved": "https://registry.npmmirror.com/@yangjianfei/bmaplib.lushu/-/bmaplib.lushu-1.0.0.tgz", |
| | | "integrity": "sha512-qZVijbgUgNs6tsP1muS67x0XzE5fJ3kFireouDvXO3bUYVV6XbpjZXksQTsggihLMIEvC1DO9GS9vVF8CnEeqQ==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/ansis": { |
| | | "version": "4.1.0", |
| | | "resolved": "https://registry.npmmirror.com/ansis/-/ansis-4.1.0.tgz", |
| | |
| | | "funding": { |
| | | "url": "https://github.com/sponsors/antfu" |
| | | } |
| | | }, |
| | | "node_modules/bmaplib.curveline": { |
| | | "version": "1.0.0", |
| | | "resolved": "https://registry.npmmirror.com/bmaplib.curveline/-/bmaplib.curveline-1.0.0.tgz", |
| | | "integrity": "sha512-9wcFMVhiYxNPqpvsLDAADn3qDhNzXp2mA6VyHSHg2XOAgSooC7ZiujdFhy0sp+0QYjTfJ/MjmLuNoUg2HHxH4Q==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/bmaplib.distancetool": { |
| | | "version": "1.0.2", |
| | | "resolved": "https://registry.npmmirror.com/bmaplib.distancetool/-/bmaplib.distancetool-1.0.2.tgz", |
| | | "integrity": "sha512-EvxMnQRH6xM036zx5OLPyTg5tMCTbFBuGTTHOtExLy2/T0X6v5Va0YE7c3IPm/a/Eo5V/ynYpOLOLZbRY8ccyA==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/bmaplib.heatmap": { |
| | | "version": "1.0.4", |
| | | "resolved": "https://registry.npmmirror.com/bmaplib.heatmap/-/bmaplib.heatmap-1.0.4.tgz", |
| | | "integrity": "sha512-rmhqUARBpUSJ9jXzUI2j7dIOqnc38bqubkx/8a349U2qtw/ulLUwyzRD535OrA8G7w5cz4aPKm6/rNvUAarg/Q==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/bmaplib.markerclusterer": { |
| | | "version": "1.0.13", |
| | | "resolved": "https://registry.npmmirror.com/bmaplib.markerclusterer/-/bmaplib.markerclusterer-1.0.13.tgz", |
| | | "integrity": "sha512-VrLyWSiuDEVNi0yUfwOhFQ6z1oEEHS4w36GNu3iASu6p52QIx9uAXMUkuSCHReNR0bj2Cp9SA1dSx5RpojXajQ==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "bmaplib.texticonoverlay": "^1.0.2" |
| | | } |
| | | }, |
| | | "node_modules/bmaplib.texticonoverlay": { |
| | | "version": "1.0.2", |
| | | "resolved": "https://registry.npmmirror.com/bmaplib.texticonoverlay/-/bmaplib.texticonoverlay-1.0.2.tgz", |
| | | "integrity": "sha512-4ZTWr4ZP3B6qEWput5Tut16CfZgII38YwM3bpyb4gFTQyORlKYryFp9WHWrwZZaHlOyYDAXG9SX0hka43jTADg==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/browserslist": { |
| | | "version": "4.25.2", |
| | |
| | | "node_modules/tiny-emitter": { |
| | | "version": "2.1.0", |
| | | "resolved": "https://registry.npmmirror.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz", |
| | | "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" |
| | | "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/tinyglobby": { |
| | | "version": "0.2.14", |
| | |
| | | } |
| | | } |
| | | }, |
| | | "node_modules/vue-baidu-map-3x": { |
| | | "version": "1.0.40", |
| | | "resolved": "https://registry.npmmirror.com/vue-baidu-map-3x/-/vue-baidu-map-3x-1.0.40.tgz", |
| | | "integrity": "sha512-Rq3g1KNsNztkuX3SJIuCpy6HE3xHVX8ySgqS2xC3jut/hvVr5kFBS0Nu7uYppk3xYVz69S1JFxU8WUI0Xftpyg==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "@yangjianfei/bmaplib.lushu": "^1.0.0", |
| | | "bmaplib.curveline": "^1.0.0", |
| | | "bmaplib.distancetool": "^1.0.2", |
| | | "bmaplib.heatmap": "^1.0.4", |
| | | "bmaplib.markerclusterer": "^1.0.13", |
| | | "tiny-emitter": "^2.1.0", |
| | | "vue": "^3.2.25", |
| | | "vue-router": "^4.0.14" |
| | | }, |
| | | "peerDependencies": { |
| | | "vue": "^3.2.25" |
| | | } |
| | | }, |
| | | "node_modules/vue-clipboard3": { |
| | | "version": "2.0.0", |
| | | "resolved": "https://registry.npmmirror.com/vue-clipboard3/-/vue-clipboard3-2.0.0.tgz", |
| | |
| | | } |
| | | }, |
| | | "dependencies": { |
| | | "@amap/amap-jsapi-loader": { |
| | | "version": "1.0.1", |
| | | "resolved": "https://registry.npmmirror.com/@amap/amap-jsapi-loader/-/amap-jsapi-loader-1.0.1.tgz", |
| | | "integrity": "sha512-nPyLKt7Ow/ThHLkSvn2etQlUzqxmTVgK7bIgwdBRTg2HK5668oN7xVxkaiRe3YZEzGzfV2XgH5Jmu2T73ljejw==" |
| | | }, |
| | | "@ampproject/remapping": { |
| | | "version": "2.3.0", |
| | | "resolved": "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.3.0.tgz", |
| | |
| | | } |
| | | } |
| | | }, |
| | | "@yangjianfei/bmaplib.lushu": { |
| | | "version": "1.0.0", |
| | | "resolved": "https://registry.npmmirror.com/@yangjianfei/bmaplib.lushu/-/bmaplib.lushu-1.0.0.tgz", |
| | | "integrity": "sha512-qZVijbgUgNs6tsP1muS67x0XzE5fJ3kFireouDvXO3bUYVV6XbpjZXksQTsggihLMIEvC1DO9GS9vVF8CnEeqQ==" |
| | | }, |
| | | "ansis": { |
| | | "version": "4.1.0", |
| | | "resolved": "https://registry.npmmirror.com/ansis/-/ansis-4.1.0.tgz", |
| | |
| | | "version": "2.5.0", |
| | | "resolved": "https://registry.npmmirror.com/birpc/-/birpc-2.5.0.tgz", |
| | | "integrity": "sha512-VSWO/W6nNQdyP520F1mhf+Lc2f8pjGQOtoHHm7Ze8Go1kX7akpVIrtTa0fn+HB0QJEDVacl6aO08YE0PgXfdnQ==" |
| | | }, |
| | | "bmaplib.curveline": { |
| | | "version": "1.0.0", |
| | | "resolved": "https://registry.npmmirror.com/bmaplib.curveline/-/bmaplib.curveline-1.0.0.tgz", |
| | | "integrity": "sha512-9wcFMVhiYxNPqpvsLDAADn3qDhNzXp2mA6VyHSHg2XOAgSooC7ZiujdFhy0sp+0QYjTfJ/MjmLuNoUg2HHxH4Q==" |
| | | }, |
| | | "bmaplib.distancetool": { |
| | | "version": "1.0.2", |
| | | "resolved": "https://registry.npmmirror.com/bmaplib.distancetool/-/bmaplib.distancetool-1.0.2.tgz", |
| | | "integrity": "sha512-EvxMnQRH6xM036zx5OLPyTg5tMCTbFBuGTTHOtExLy2/T0X6v5Va0YE7c3IPm/a/Eo5V/ynYpOLOLZbRY8ccyA==" |
| | | }, |
| | | "bmaplib.heatmap": { |
| | | "version": "1.0.4", |
| | | "resolved": "https://registry.npmmirror.com/bmaplib.heatmap/-/bmaplib.heatmap-1.0.4.tgz", |
| | | "integrity": "sha512-rmhqUARBpUSJ9jXzUI2j7dIOqnc38bqubkx/8a349U2qtw/ulLUwyzRD535OrA8G7w5cz4aPKm6/rNvUAarg/Q==" |
| | | }, |
| | | "bmaplib.markerclusterer": { |
| | | "version": "1.0.13", |
| | | "resolved": "https://registry.npmmirror.com/bmaplib.markerclusterer/-/bmaplib.markerclusterer-1.0.13.tgz", |
| | | "integrity": "sha512-VrLyWSiuDEVNi0yUfwOhFQ6z1oEEHS4w36GNu3iASu6p52QIx9uAXMUkuSCHReNR0bj2Cp9SA1dSx5RpojXajQ==", |
| | | "requires": { |
| | | "bmaplib.texticonoverlay": "^1.0.2" |
| | | } |
| | | }, |
| | | "bmaplib.texticonoverlay": { |
| | | "version": "1.0.2", |
| | | "resolved": "https://registry.npmmirror.com/bmaplib.texticonoverlay/-/bmaplib.texticonoverlay-1.0.2.tgz", |
| | | "integrity": "sha512-4ZTWr4ZP3B6qEWput5Tut16CfZgII38YwM3bpyb4gFTQyORlKYryFp9WHWrwZZaHlOyYDAXG9SX0hka43jTADg==" |
| | | }, |
| | | "browserslist": { |
| | | "version": "4.25.2", |
| | |
| | | "@vue/shared": "3.5.18" |
| | | } |
| | | }, |
| | | "vue-baidu-map-3x": { |
| | | "version": "1.0.40", |
| | | "resolved": "https://registry.npmmirror.com/vue-baidu-map-3x/-/vue-baidu-map-3x-1.0.40.tgz", |
| | | "integrity": "sha512-Rq3g1KNsNztkuX3SJIuCpy6HE3xHVX8ySgqS2xC3jut/hvVr5kFBS0Nu7uYppk3xYVz69S1JFxU8WUI0Xftpyg==", |
| | | "requires": { |
| | | "@yangjianfei/bmaplib.lushu": "^1.0.0", |
| | | "bmaplib.curveline": "^1.0.0", |
| | | "bmaplib.distancetool": "^1.0.2", |
| | | "bmaplib.heatmap": "^1.0.4", |
| | | "bmaplib.markerclusterer": "^1.0.13", |
| | | "tiny-emitter": "^2.1.0", |
| | | "vue": "^3.2.25", |
| | | "vue-router": "^4.0.14" |
| | | } |
| | | }, |
| | | "vue-clipboard3": { |
| | | "version": "2.0.0", |
| | | "resolved": "https://registry.npmmirror.com/vue-clipboard3/-/vue-clipboard3-2.0.0.tgz", |
| | |
| | | "format": "prettier --write src/" |
| | | }, |
| | | "dependencies": { |
| | | "@amap/amap-jsapi-loader": "^1.0.1", |
| | | "axios": "^1.11.0", |
| | | "element-plus": "^2.10.7", |
| | | "less": "^4.4.0", |
| | |
| | | "spark-md5": "^3.0.2", |
| | | "vue": "^3.5.18", |
| | | "vue-clipboard3": "^2.0.0", |
| | | "vue-baidu-map-3x": "^1.0.40", |
| | | "vue-router": "^4.5.1" |
| | | }, |
| | | "devDependencies": { |
| | |
| | | }) |
| | | }, |
| | | |
| | | getSlideCaptchaImage(options) { |
| | | return request('/identity/GetSlideCaptchaImage', { |
| | | method: 'POST', |
| | | data: options || {}, |
| | | }) |
| | | }, |
| | | // 验证滑动验证码 |
| | | validSlideCaptcha(options) { |
| | | return request('/identity/ValidSlideCaptcha', { |
| | | method: 'POST', |
| | | data: options || {}, |
| | | }) |
| | | }, |
| | | |
| | | // 通过手机号注册用户 |
| | | registerAppUserWithPhone(data) { |
| | | return request({ |
| | |
| | | coverSize, |
| | | itemIdArr, |
| | | SysType, |
| | | tourism_isHighQualityResources, |
| | | isHighQualityResources, |
| | | }) => { |
| | | if (!path) return Promise.reject("接口请求必要参数不能为空!"); |
| | | |
| | |
| | | }; |
| | | if (itemIdArr) query["Id"] = itemIdArr; |
| | | if (SysType) query["SysType="] = [`${SysType}`]; |
| | | if (tourism_isHighQualityResources) |
| | | query["tourism_isHighQualityResources="] = [ |
| | | `${tourism_isHighQualityResources}`, |
| | | if (isHighQualityResources) |
| | | query["isHighQualityResources="] = [ |
| | | `${isHighQualityResources}`, |
| | | ]; |
| | | if (itemId) query["Id="] = [`${itemId}`]; |
| | | if (itemIds) query["Id="] = itemIds; |
| | |
| | | if (params.length > 0) { |
| | | let data = { |
| | | "||Name": [...params], |
| | | "||tourism_content*": [...params], |
| | | "||tourism_workflow*": [...params], |
| | | "||tourism_notes*": [...params], |
| | | "||tourism_caseIndex*": [...params], |
| | | "||tourism_basicCase*": [...params], |
| | | "||tourism_judgmentAndReasons*": [...params], |
| | | "||tourism_legalIssuesInvolvedInThisCase*": [...params], |
| | | "||tourism_referenceAnswerAndLegalAnalysis*": [...params], |
| | | "||tourism_case*": [...params], |
| | | "||tourism_clause*": [...params], |
| | | "||tourism_unscramble*": [...params], |
| | | "||tourism_specialRemind*": [...params], |
| | | "||tourism_fiction*": [...params], |
| | | "||tourism_authorityNature*": [...params], |
| | | "||tourism_authorityGist*": [...params], |
| | | "||tourism_penaltyGist*": [...params], |
| | | "||tourism_penaltyTerms*": [...params], |
| | | "||tourism_penaltyType*": [...params], |
| | | "||tourism_remarksNote*": [...params], |
| | | "||tourism_keyword*": [...params], |
| | | "||content*": [...params], |
| | | "||workflow*": [...params], |
| | | "||notes*": [...params], |
| | | "||caseIndex*": [...params], |
| | | "||basicCase*": [...params], |
| | | "||judgmentAndReasons*": [...params], |
| | | "||legalIssuesInvolvedInThisCase*": [...params], |
| | | "||referenceAnswerAndLegalAnalysis*": [...params], |
| | | "||case*": [...params], |
| | | "||clause*": [...params], |
| | | "||unscramble*": [...params], |
| | | "||specialRemind*": [...params], |
| | | "||fiction*": [...params], |
| | | "||authorityNature*": [...params], |
| | | "||authorityGist*": [...params], |
| | | "||penaltyGist*": [...params], |
| | | "||penaltyTerms*": [...params], |
| | | "||penaltyType*": [...params], |
| | | "||remarksNote*": [...params], |
| | | "||keyword*": [...params], |
| | | }; |
| | | Object.assign(queryBody, data); |
| | | } else { |
| | |
| | | let data = { |
| | | Path: [ |
| | | { |
| | | Repository: "tourism_tourismLawsAndRegulationsDatabase", |
| | | Repository: "tourismLawsAndRegulationsDatabase", |
| | | Path: path, |
| | | }, |
| | | ], |
| | |
| | | import { requestCtx, appId } from '@/assets/js/config.js' |
| | | // import defaultImg from '@/assets/images/default-book-img.png' |
| | | // import defaultBookFair from '@/assets/images/default-bookFair.png' |
| | | // import bookCover from '@/assets/images/book-cover.png' |
| | | import bookCover from '@/assets/images/book-cover.png' |
| | | // import defaultPub from '@/assets/images/math/default-pub.png' |
| | | // import defaultAudio from '@/assets/images/math/default-audio.png' |
| | | import moment from 'moment' |
| | |
| | | storeInfo, |
| | | repositoryInfo, |
| | | coverSize, |
| | | handelEBooK |
| | | handelEBooK, |
| | | }) { |
| | | const dataList = [] |
| | | for (let i = 0; i < datas.length; i++) { |
| | |
| | | subProductCount: parseInt(item.datas.SubProductCount), |
| | | ..._fields, |
| | | datas: item.datas, |
| | | subDatas |
| | | subDatas, |
| | | } |
| | | |
| | | // 统一处理价格 |
| | |
| | | let saleMethod = [] |
| | | try { |
| | | saleMethod = obj.cmsDatas[0].datas.find( |
| | | (item) => item.datas.RefCode == 'tourism_accompanyingResources' |
| | | (item) => item.datas.RefCode == 'accompanyingResources', |
| | | ).datas.SaleMethod |
| | | saleMethod = JSON.parse(saleMethod) |
| | | } catch (error) { |
| | |
| | | itemFields, |
| | | handelEBooK, |
| | | }) { |
| | | item.fileMap = {}; |
| | | let itemFieldsData = []; |
| | | item.fileMap = {} |
| | | let itemFieldsData = [] |
| | | for (const key in itemFields) { |
| | | itemFieldsData.push(key); |
| | | itemFieldsData.push(key) |
| | | } |
| | | let fieldsData = []; |
| | | let fieldsData = [] |
| | | for (const key in fields) { |
| | | fieldsData.push(key); |
| | | fieldsData.push(key) |
| | | } |
| | | for (let i = 0; i < fieldsData.length; i++) { |
| | | const field = fieldsData[i]; |
| | | item.datas[field] = JSON.parse(item.datas[field]); |
| | | const datas = item.datas[field]; |
| | | const field = fieldsData[i] |
| | | item.datas[field] = JSON.parse(item.datas[field]) |
| | | const datas = item.datas[field] |
| | | if (datas.length > 0) { |
| | | if (datas[0].Value) { |
| | | item[field] = datas[0].Value; |
| | | item[field] = datas[0].Value |
| | | if (datas[0].Data.FileLinkList && datas[0].Data.FileLinkList.length) { |
| | | item.fileMap = { |
| | | ...item.fileMap, |
| | |
| | | return { |
| | | ...item.File, |
| | | ...item, |
| | | }; |
| | | }) |
| | | } |
| | | }), |
| | | ), |
| | | }; |
| | | } |
| | | } |
| | | } else if (datas[0].Data) { |
| | | item[field] = datas[0].Data.Value; |
| | | item[field] = datas[0].Data.Value |
| | | if (datas[0].Data.FileLinkList && datas[0].Data.FileLinkList.length) { |
| | | item.fileMap = { |
| | | ...item.fileMap, |
| | |
| | | return { |
| | | ...item.File, |
| | | ...item, |
| | | }; |
| | | }) |
| | | } |
| | | }), |
| | | ), |
| | | }; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 处理cms资源 |
| | | const subDatas = item.subDatas; |
| | | const linkItemsMap = {}; |
| | | const subDatas = item.subDatas |
| | | const linkItemsMap = {} |
| | | if (subDatas) { |
| | | for (const sdata of subDatas) { |
| | | const tag = sdata.queryTag; |
| | | const tag = sdata.queryTag |
| | | for (const subItem of sdata.datas) { |
| | | convertCmsItemBase(subItem, coverSize, handelEBooK); |
| | | subItem.fileMap = {}; |
| | | convertCmsItemBase(subItem, coverSize, handelEBooK) |
| | | subItem.fileMap = {} |
| | | for (let i = 0; i < itemFieldsData.length; i++) { |
| | | const itemField = itemFieldsData[i]; |
| | | const itemField = itemFieldsData[i] |
| | | try { |
| | | subItem.datas[itemField] = JSON.parse(subItem.datas[itemField]); |
| | | subItem.datas[itemField] = JSON.parse(subItem.datas[itemField]) |
| | | } catch (error) { |
| | | subItem.datas[itemField] = []; |
| | | subItem.datas[itemField] = [] |
| | | } |
| | | const itemDatas = subItem.datas[itemField]; |
| | | const itemDatas = subItem.datas[itemField] |
| | | if (itemDatas.length > 0) { |
| | | if (itemDatas[0].Value) { |
| | | subItem[itemField] = itemDatas[0].Value; |
| | | subItem[itemField] = itemDatas[0].Value |
| | | if (itemDatas[0].FileList && itemDatas[0].FileList.length) { |
| | | subItem.fileMap = { |
| | | ...subItem.fileMap, |
| | | ...handleLinkFileInfo(itemDatas[0].FileList), |
| | | }; |
| | | } |
| | | } |
| | | } else if (itemDatas[0].Data) { |
| | | subItem[itemField] = itemDatas[0].Data.Value; |
| | | if ( |
| | | itemDatas[0].Data.FileList && |
| | | itemDatas[0].Data.FileList.length |
| | | ) { |
| | | subItem[itemField] = itemDatas[0].Data.Value |
| | | if (itemDatas[0].Data.FileList && itemDatas[0].Data.FileList.length) { |
| | | subItem.fileMap = { |
| | | ...subItem.fileMap, |
| | | ...handleLinkFileInfo(itemDatas[0].Data.FileList), |
| | | }; |
| | | } |
| | | } |
| | | } else if (itemDatas[0].CmsItemData) { |
| | | subItem[itemField] = itemDatas[0].CmsItemData.Value; |
| | | if ( |
| | | itemDatas[0].CmsItemData.FileList && |
| | | itemDatas[0].CmsItemData.FileList.length |
| | | ) { |
| | | subItem[itemField] = itemDatas[0].CmsItemData.Value |
| | | if (itemDatas[0].CmsItemData.FileList && itemDatas[0].CmsItemData.FileList.length) { |
| | | subItem.fileMap = { |
| | | ...subItem.fileMap, |
| | | ...handleLinkFileInfo(itemDatas[0].CmsItemData.FileList), |
| | | }; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | if (subItem.productLinkInfo && subItem.productLinkInfo.length) { |
| | | let itemProductLinkInfo = subItem.productLinkInfo.find(citem => citem.Name == item.datas.Name) |
| | | let itemProductLinkInfo = subItem.productLinkInfo.find( |
| | | (citem) => citem.Name == item.datas.Name, |
| | | ) |
| | | subItem.productLinkPath = |
| | | itemProductLinkInfo.LinkPath + |
| | | "\\" + |
| | | itemProductLinkInfo.CmsItemId; |
| | | itemProductLinkInfo.LinkPath + '\\' + itemProductLinkInfo.CmsItemId |
| | | } |
| | | if (subItem.linkInfo && subItem.linkInfo.length) |
| | | subItem.linkPath = |
| | | subItem.linkInfo[0].LinkPath + "\\" + subItem.linkInfo[0].CmsItemId; |
| | | subItem.linkPath = subItem.linkInfo[0].LinkPath + '\\' + subItem.linkInfo[0].CmsItemId |
| | | } |
| | | linkItemsMap[tag] = sdata.datas; |
| | | linkItemsMap[tag] = sdata.datas |
| | | } |
| | | } |
| | | convertCmsItemBase(item, coverSize, handelEBooK); |
| | | item.idPath = path + "\\" + item.id; |
| | | item.subItems = linkItemsMap; |
| | | return item; |
| | | convertCmsItemBase(item, coverSize, handelEBooK) |
| | | item.idPath = path + '\\' + item.id |
| | | item.subItems = linkItemsMap |
| | | return item |
| | | } |
| | | |
| | | const handleLinkFileInfo = (linkList) => { |
| | |
| | | size: linkItem.Size, |
| | | // metaData: JSON.parse(linkItem.MetaData ?? "{}"), |
| | | order: linkItem.Order, |
| | | protectType: linkItem.ProtectType |
| | | protectType: linkItem.ProtectType, |
| | | } |
| | | } |
| | | return linkFileMap |
| | |
| | | item.linkStoreId = parseInt(item.datas.LinkStore) |
| | | item.linkRepoId = item.datas.LinkRepository |
| | | item.childrenCount = parseInt(item.datas.ChildrenCount ?? '0') |
| | | ;(item.childrenFolderCount = parseInt(item.datas.ChildrenFolderCount ?? '0')), |
| | | ;((item.childrenFolderCount = parseInt(item.datas.ChildrenFolderCount ?? '0')), |
| | | (item.childrenChannelCount = parseInt(item.datas.ChildrenChannelCount ?? '0')), |
| | | (item.linkId = parseInt(item.datas.LinkId)) |
| | | (item.linkId = parseInt(item.datas.LinkId))) |
| | | item.linkOrg = JSON.parse(item.datas.LinkOrg ?? '[]')[0] |
| | | item.linkDepartment = JSON.parse(item.datas.LinkDepartment ?? '[]')[0] |
| | | item.linkInfo = JSON.parse(item.datas.LinkInfo ?? '[]') |
| | |
| | | if (handelEBooK) { |
| | | // 获取随书资源的销售方式 |
| | | let saleMethod = item.cmsDatas[0].datas.find( |
| | | (item) => item.refCode == 'tourism_accompanyingResources' |
| | | (item) => item.refCode == 'accompanyingResources', |
| | | ).saleMethod |
| | | if (saleMethod && saleMethod.length > 0) { |
| | | Object.keys(saleMethod[0]).map((key) => { |
| | |
| | | src = requestCtx + `/file/GetPreViewImage?md5=${md5}` |
| | | } else { |
| | | if(storeInfo == `defaultGoodsStore${appId}`){ |
| | | return bookCover; |
| | | return bookCover |
| | | }else{ |
| | | return "" |
| | | return '' |
| | | } |
| | | } |
| | | if (width && src) src += `&width=${width}` |
| | |
| | | import SparkMD5 from 'spark-md5' |
| | | import { |
| | | getPublicImage |
| | | } from '@/assets/js/middleGround/tool.js' |
| | | import { getPublicImage } from '@/assets/js/middleGround/tool.js' |
| | | import config from './config' |
| | | import moment from "moment"; |
| | | |
| | | |
| | | |
| | | import moment from 'moment' |
| | | |
| | | var tool = { |
| | | secondToTime(second) { |
| | |
| | | .replace(/\.[\d]{3}Z/, '') |
| | | var time = new Date(newDate) |
| | | return time.getTime() |
| | | }, |
| | | } |
| | | } |
| | | |
| | | |
| | | //处理表单提交数据 |
| | | export function worksData(res) { |
| | |
| | | nrr.push({ |
| | | linkProtectType: e.linkProtectType, |
| | | linkType: e.linkType, |
| | | md5: e.md5 |
| | | }) |
| | | md5: e.md5, |
| | | }), |
| | | ) |
| | | } |
| | | res.forEach((item) => { |
| | |
| | | order: 0, |
| | | typeFieldId: item.typeField.id, |
| | | sequenceNum: item.config ? JSON.parse(item.config).uuid : '', |
| | | newDataAndFileLinkListRequest: [] |
| | | newDataAndFileLinkListRequest: [], |
| | | } |
| | | for (let k in value) { |
| | | if (item.typeField.refCode === k) { |
| | |
| | | id: updateOldData.id, |
| | | typeFieldId: citem.typeField.id, |
| | | sequenceNum: citem.sequenceNum, |
| | | setDataAndFileLinkListRequest: [] |
| | | setDataAndFileLinkListRequest: [], |
| | | } |
| | | for (let k in value) { |
| | | if (citem.typeField.refCode === k) { |
| | |
| | | obj.setDataAndFileLinkListRequest = linkList |
| | | } else if (typeof value[k] == 'object' && k == 'region') { |
| | | obj.strValue = value[k]?.join('/') |
| | | obj.setDataAndFileLinkListRequest = [{ |
| | | area: value[k] |
| | | }] |
| | | obj.setDataAndFileLinkListRequest = [ |
| | | { |
| | | area: value[k], |
| | | }, |
| | | ] |
| | | } else { |
| | | obj.strValue = value[k].toString() |
| | | } |
| | |
| | | order: 0, |
| | | typeFieldId: citem.typeField.id, |
| | | sequenceNum: citem.sequenceNum, |
| | | setDataAndFileLinkListRequest: [] |
| | | setDataAndFileLinkListRequest: [], |
| | | } |
| | | for (let k in value) { |
| | | if (citem.typeField.refCode === k) { |
| | |
| | | }) |
| | | return { |
| | | updateData: arr, |
| | | newData: newArr |
| | | newData: newArr, |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | // 获取文件 |
| | | export function getPublicFile(md5, isToken) { |
| | | const { |
| | | tokenKey, |
| | | requestCtx |
| | | } = config |
| | | const { tokenKey, requestCtx } = config |
| | | let src = null |
| | | let token = localStorage.getItem(tokenKey) |
| | | if (md5) { |
| | |
| | | return src |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | export const handleCmsItemListRequestData = (datas, fields, path, storeId, repositoryId) => { |
| | | const dataList = []; |
| | | const dataList = [] |
| | | for (let i = 0; i < datas.length; i++) { |
| | | const item = datas[i]; |
| | | const _fields = {}; |
| | | const _datas = []; |
| | | const item = datas[i] |
| | | const _fields = {} |
| | | const _datas = [] |
| | | if (fields != null) { |
| | | for (let fieldKey in fields) { |
| | | // 兼容筛选条件的字段值获取,因为后台筛选和取值只能传一个,都会返回值 |
| | | fieldKey = fieldKey.replace(/[!=<>*]/g, ''); |
| | | fieldKey = fieldKey.replace(/[!=<>*]/g, '') |
| | | if (item.datas[fieldKey]) { |
| | | let values = []; |
| | | let values = [] |
| | | if (typeof item.datas[fieldKey] == 'string') { |
| | | values = JSON.parse(item.datas[fieldKey]); |
| | | values = JSON.parse(item.datas[fieldKey]) |
| | | } else { |
| | | values = item.datas[fieldKey]; |
| | | values = item.datas[fieldKey] |
| | | } |
| | | if (values ?.length > 0) { |
| | | // 用字段名处理返回的字段值 |
| | | if (values[0].Value) { |
| | | _fields[fieldKey] = values[0].Value; |
| | | values[0].sequenceNum = values[0].SequenceNum; |
| | | _fields[fieldKey] = values[0].Value |
| | | values[0].sequenceNum = values[0].SequenceNum |
| | | } |
| | | // 兼容处理数据返回的key是CmsItemData |
| | | // if (values[0].CmsItemData) { |
| | |
| | | // values[0].sequenceNum = values[0].CmsItemData.SequenceNum; |
| | | // } |
| | | |
| | | item.datas[fieldKey] = values[0]; |
| | | item.datas[fieldKey] = values[0] |
| | | if (values ?.length > 1) { |
| | | const isFile = values.find((citem) => citem.FileList ?.length > 0); |
| | | const dataItems = deduplicateArray(values, 'FieldId'); |
| | | const isFile = values.find((citem) => citem.FileList?.length > 0) |
| | | const dataItems = deduplicateArray(values, 'FieldId') |
| | | if (!isFile) { |
| | | _datas.push(dataItems[0]); |
| | | _datas.push(dataItems[0]) |
| | | } else { |
| | | const customFile = { |
| | | customFileList: values, |
| | | name: fieldKey, |
| | | md5: _fields[fieldKey], |
| | | FieldId: values[0].FieldId, |
| | | SequenceNum: values[0].SequenceNum |
| | | }; |
| | | _datas.push(customFile); |
| | | SequenceNum: values[0].SequenceNum, |
| | | } |
| | | _datas.push(customFile) |
| | | } |
| | | } else { |
| | | _datas.push(values[0]); |
| | | _datas.push(values[0]) |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | if (item.datas.LogQuery) { |
| | | item.datas.LogQuery = JSON.parse(item.datas.LogQuery); |
| | | item.datas.LogQuery = JSON.parse(item.datas.LogQuery) |
| | | } |
| | | |
| | | const subDatas = {}; |
| | | const subDatas = {} |
| | | if (item.subDatas) { |
| | | for (let subData of item.subDatas) { |
| | | const tag = subData.queryTag.replace('Query', ''); |
| | | subDatas[tag] = subData.datas; |
| | | const tag = subData.queryTag.replace('Query', '') |
| | | subDatas[tag] = subData.datas |
| | | } |
| | | } |
| | | dataList.push({ |
| | |
| | | ..._fields, |
| | | datas: item.datas, |
| | | fieldList: _datas, |
| | | subDatas |
| | | }); |
| | | subDatas, |
| | | }) |
| | | } |
| | | return dataList; |
| | | }; |
| | | return dataList |
| | | } |
| | | |
| | | // type结构处理 |
| | | export const handleTypeList = (list) => { |
| | | for (let i = 0; i < list.length; i++) { |
| | | const type = list[i]; |
| | | const type = list[i] |
| | | try { |
| | | type.cfg = JSON.parse(type.config); |
| | | type.cfg = JSON.parse(type.config) |
| | | } catch (error) { |
| | | type.cfg = null; |
| | | type.cfg = null |
| | | } |
| | | const fieldRefcodeMap = {}; |
| | | const tableHeaderFieldList = []; |
| | | const isSearchFieldList = []; |
| | | const isAdvSearchFieldList = []; |
| | | const isFilterFieldList = []; |
| | | const fieldRefcodeMap = {} |
| | | const tableHeaderFieldList = [] |
| | | const isSearchFieldList = [] |
| | | const isAdvSearchFieldList = [] |
| | | const isFilterFieldList = [] |
| | | console.log(type, 'type') |
| | | handleType({ |
| | | typeFieldList: type.typeLinkList, |
| | | typeFieldList: type.cmsTypeLinks, |
| | | fieldRefcodeMap, |
| | | tableHeaderFieldList, |
| | | isSearchFieldList, |
| | | isAdvSearchFieldList, |
| | | isFilterFieldList |
| | | }); |
| | | type.fieldRefcodeMap = fieldRefcodeMap; |
| | | type.tableHeaderFieldList = tableHeaderFieldList; |
| | | type.isSearchFieldList = isSearchFieldList; |
| | | type.isAdvSearchFieldList = isAdvSearchFieldList; |
| | | type.isFilterFieldList = isFilterFieldList; |
| | | isFilterFieldList, |
| | | }) |
| | | type.fieldRefcodeMap = fieldRefcodeMap |
| | | type.tableHeaderFieldList = tableHeaderFieldList |
| | | type.isSearchFieldList = isSearchFieldList |
| | | type.isAdvSearchFieldList = isAdvSearchFieldList |
| | | type.isFilterFieldList = isFilterFieldList |
| | | } |
| | | |
| | | return list; |
| | | }; |
| | | return list |
| | | } |
| | | |
| | | const handleType = ({ |
| | | typeFieldList, |
| | |
| | | tableHeaderFieldList, |
| | | isSearchFieldList, |
| | | isAdvSearchFieldList, |
| | | isFilterFieldList |
| | | isFilterFieldList, |
| | | }) => { |
| | | for (let i = 0; i < typeFieldList.length; i++) { |
| | | const item = typeFieldList[i]; |
| | | const item = typeFieldList[i] |
| | | try { |
| | | item.cfg = JSON.parse(item.config); |
| | | item.cfg = JSON.parse(item.config) |
| | | } catch (error) { |
| | | item.cfg = null; |
| | | item.cfg = null |
| | | } |
| | | if (item.typeField) { |
| | | try { |
| | | item.typeField.cfg = JSON.parse(item.typeField.config); |
| | | item.typeField.cfg = JSON.parse(item.typeField.config) |
| | | } catch (error) { |
| | | item.typeField.cfg = null; |
| | | item.typeField.cfg = null |
| | | } |
| | | fieldRefcodeMap[item.typeField.refCode] = item; |
| | | fieldRefcodeMap[item.typeField.refCode] = item |
| | | } |
| | | if (item.cfg && item.cfg.isColHeader) { |
| | | tableHeaderFieldList.push(item); |
| | | tableHeaderFieldList.push(item) |
| | | } |
| | | if (item.cfg && item.cfg.isSearch) { |
| | | isSearchFieldList.push(item); |
| | | isSearchFieldList.push(item) |
| | | } |
| | | if (item.cfg && item.cfg.isAdvSearch) { |
| | | isAdvSearchFieldList.push(item); |
| | | isAdvSearchFieldList.push(item) |
| | | } |
| | | if (item.cfg && item.cfg.isFilter) { |
| | | isFilterFieldList.push(item); |
| | | isFilterFieldList.push(item) |
| | | } |
| | | if (item.children && item.children.length) { |
| | | handleType({ |
| | |
| | | tableHeaderFieldList, |
| | | isSearchFieldList, |
| | | isAdvSearchFieldList, |
| | | isFilterFieldList |
| | | }); |
| | | isFilterFieldList, |
| | | }) |
| | | } |
| | | } |
| | | }; |
| | | |
| | | } |
| | | |
| | | //处理树形结构 |
| | | const handleTreeData = (datas, parent, noTriggerSelect = false) => { |
| | | let parentData = {}; |
| | | let parentData = {} |
| | | if (parent) { |
| | | parentData = { ...parent, parent: null }; |
| | | parentData = { ...parent, parent: null } |
| | | } else { |
| | | parentData = null; |
| | | parentData = null |
| | | } |
| | | const list = []; |
| | | const list = [] |
| | | for (let i = 0; i < datas.length; i++) { |
| | | const data = datas[i]; |
| | | const data = datas[i] |
| | | const obj = { |
| | | label: data.name, |
| | | key: parentData ? parentData.key + "_" + i : i + "", |
| | | namePath: parentData ? parentData.namePath + "\\" + data.name : data.name, |
| | | key: parentData ? parentData.key + '_' + i : i + '', |
| | | namePath: parentData ? parentData.namePath + '\\' + data.name : data.name, |
| | | icon: data.icon, |
| | | data: data, |
| | | parent: parentData, |
| | | leaf: false, |
| | | children: [], |
| | | }; |
| | | if (data["children"] && data["children"].length) { |
| | | obj.leaf = false; |
| | | } |
| | | if (data['children'] && data['children'].length) { |
| | | obj.leaf = false |
| | | obj.children = handleTreeData( |
| | | data["children"], |
| | | data['children'], |
| | | { |
| | | ...data, |
| | | key: obj.key, |
| | | namePath: obj.namePath, |
| | | }, |
| | | i == 0 ? false : true // 如果有子数据处理,只有第一条数据需要展开和回调 |
| | | ); |
| | | i == 0 ? false : true, // 如果有子数据处理,只有第一条数据需要展开和回调 |
| | | ) |
| | | } else { |
| | | obj.leaf = |
| | | !data["childrenChannelCount"] || data["childrenChannelCount"] == 0; |
| | | obj.leaf = !data['childrenChannelCount'] || data['childrenChannelCount'] == 0 |
| | | } |
| | | list.push(obj); |
| | | list.push(obj) |
| | | } |
| | | console.log(list, "list"); |
| | | return list; |
| | | }; |
| | | |
| | | console.log(list, 'list') |
| | | return list |
| | | } |
| | | |
| | | //获取资源 |
| | | |
| | | |
| | | |
| | | export default { |
| | | ...tool, |
| | |
| | | --el-color-primary-dark-3: #019e58 !important; |
| | | } |
| | | |
| | | /* 基础样式 */ |
| | | *{ |
| | | outline: none; |
| | | } |
| | | |
| | | /* 居中布局 */ |
| | | .contentBox { |
| | | width: 1200px; |
| | |
| | | color: #00873C !important; |
| | | } */ |
| | | |
| | | .el-input-group__append, |
| | | .el-input-group__prepend { |
| | | vertical-align: initial !important; |
| | | .el-input-group__append, .el-input-group__prepend { |
| | | /* vertical-align: initial !important; */ |
| | | /* align-items: stretch !important; */ |
| | | } |
| | | |
| | | /* 个人中心页面公共样式 */ |
New file |
| | |
| | | <template> |
| | | <div class="map-container"> |
| | | <!-- 地图容器 --> |
| | | <div id="map-container" ref="mapContainer"></div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, onMounted } from 'vue' |
| | | import AMapLoader from '@amap/amap-jsapi-loader' |
| | | |
| | | // 配置安全密钥(推荐) |
| | | window._AMapSecurityConfig = { |
| | | securityJsCode: '4c6cee842f5412a45a781aeaa76e12cc', // 高德控制台获取 |
| | | } |
| | | |
| | | const mapContainer = ref(null) |
| | | const mapInstance = ref(null) |
| | | const marker = ref(null) |
| | | |
| | | // 示例地点数据 |
| | | const location = ref({ |
| | | name: '天安门广场', |
| | | address: '北京市东城区长安街', |
| | | position: [116.413823, 39.912052], |
| | | }) |
| | | |
| | | // 初始化地图 |
| | | onMounted(() => { |
| | | AMapLoader.load({ |
| | | key: '4c6cee842f5412a45a781aeaa76e12cc', // 替换为你的Key |
| | | version: '2.0', // SDK版本 |
| | | plugins: ['AMap.Marker', 'AMap.ToolBar', 'AMap.Scale'], // 所需插件 |
| | | }) |
| | | .then((AMap) => { |
| | | // 创建地图实例 |
| | | mapInstance.value = new AMap.Map(mapContainer.value, { |
| | | viewMode: '2D', // 默认使用2D模式 |
| | | zoom: 15, // 初始缩放级别 |
| | | center: location.value.position, // 初始中心点 |
| | | }) |
| | | |
| | | // 添加控件 |
| | | mapInstance.value.addControl(new AMap.ToolBar()) |
| | | mapInstance.value.addControl(new AMap.Scale()) |
| | | |
| | | // 添加标记点 |
| | | marker.value = new AMap.Marker({ |
| | | position: location.value.position, |
| | | title: location.value.name, |
| | | }) |
| | | mapInstance.value.add(marker.value) |
| | | |
| | | // 点击标记点显示信息 |
| | | marker.value.on('click', () => { |
| | | alert(`您点击了:${location.value.name}`) |
| | | }) |
| | | }) |
| | | .catch((error) => { |
| | | console.error('地图加载失败:', error) |
| | | }) |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .map-container { |
| | | position: relative; |
| | | width: 100%; |
| | | height: 500px; |
| | | } |
| | | |
| | | #map-container { |
| | | width: 100%; |
| | | height: 100%; |
| | | border-radius: 8px; |
| | | box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | .location-card { |
| | | position: absolute; |
| | | bottom: 20px; |
| | | left: 20px; |
| | | background: white; |
| | | padding: 15px; |
| | | border-radius: 8px; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); |
| | | z-index: 10; |
| | | max-width: 300px; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="container"> |
| | | <div id="captcha" style="position: relative"></div> |
| | | </div> |
| | | </template> |
| | | <script> |
| | | export default { |
| | | name: "verify", |
| | | props: { |
| | | msg: String, |
| | | MG: Object, |
| | | }, |
| | | data() { |
| | | return { |
| | | code: "", |
| | | }; |
| | | }, |
| | | |
| | | mounted() { |
| | | this.getImg(); |
| | | }, |
| | | methods: { |
| | | getImg() { |
| | | var that = this; |
| | | this.MG.identity.getSlideCaptchaImage().then((res) => { |
| | | try { |
| | | if (res) { |
| | | /* eslint-disable */ // 参数1:当前画布父级元素 参数2:滑动成功函数,返回滑动距离,接口参数前缀,当前盒子内子元素及方法 参数3:滑动失败函数返回滑动距离,接口参数前缀 参数4:通过接口获取到的图片以及宽高比 参数5:当前页面的this |
| | | jigsaw.init( |
| | | document.getElementById("captcha"), |
| | | function (left, prefix, objCustom) { |
| | | const data = { |
| | | captcha: prefix + left, |
| | | }; |
| | | that.MG.identity.validSlideCaptcha(data).then((res) => { |
| | | if (res && res.result == "验证成功") { |
| | | that.code = res.code; |
| | | console.log(res, "this.code"); |
| | | document.getElementById("msg").innerHTML = res.result; |
| | | objCustom.addClass( |
| | | objCustom.sliderContainer, |
| | | "sliderContainer_success" |
| | | ); |
| | | that.$emit("loginImgVerify", res.code); |
| | | } else { |
| | | document.getElementById("msg").innerHTML = |
| | | res.result + ",点击右上角刷新再试一次"; |
| | | objCustom.addClass( |
| | | objCustom.sliderContainer, |
| | | "sliderContainer_fail" |
| | | ); |
| | | } |
| | | }); |
| | | }, |
| | | function (left, prefix) { |
| | | console.log(left, prefix, "fail"); |
| | | }, |
| | | res, // 图片参数 |
| | | that |
| | | ); |
| | | } |
| | | } catch (error) { |
| | | console.log(error); |
| | | } |
| | | }); |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
New file |
| | |
| | | .container { |
| | | max-width: 400px; |
| | | width: auto; |
| | | margin: auto; |
| | | overflow: hidden; |
| | | } |
| | | input { |
| | | display: block; |
| | | width: 290px; |
| | | line-height: 40px; |
| | | padding: 10px; |
| | | box-sizing: border-box; |
| | | outline: none; |
| | | border: 1px solid #c8cccf; |
| | | border-radius: 4px; |
| | | color: #6a6f77; |
| | | } |
| | | #msg { |
| | | position: absolute; |
| | | bottom: 60px; |
| | | left: 0; |
| | | width: 100%; |
| | | background-color: rgba(0, 0, 0, 0.3); |
| | | line-height: 40px; |
| | | font-size: 14px; |
| | | color: #fff; |
| | | text-align: center; |
| | | z-index: 999; |
| | | } |
| | | |
| | | .msgError { |
| | | color: #ff4c05 !important; |
| | | } |
| | | |
| | | .msgSuccess { |
| | | color: #52ccba !important; |
| | | } |
| | | |
| | | /* a:link, |
| | | a:visited, |
| | | a:hover, |
| | | a:active { |
| | | margin-left: 100px; |
| | | color: #0366d6; |
| | | } */ |
| | | .block { |
| | | position: absolute; |
| | | left: 0; |
| | | top: 0; |
| | | } |
| | | |
| | | .sliderContainer { |
| | | position: relative; |
| | | text-align: center; |
| | | width: 400px; |
| | | height: 40px; |
| | | line-height: 40px; |
| | | margin-top: 15px; |
| | | background: #f7f9fa; |
| | | color: #45494c; |
| | | border: 1px solid #e4e7eb; |
| | | } |
| | | |
| | | .sliderContainer_active .slider { |
| | | height: 38px; |
| | | top: -1px; |
| | | border: 1px solid #1991fa; |
| | | } |
| | | |
| | | .sliderContainer_active .sliderMask { |
| | | height: 38px; |
| | | border-width: 1px; |
| | | } |
| | | |
| | | .sliderContainer_success .slider { |
| | | height: 38px; |
| | | top: -1px; |
| | | border: 1px solid #52ccba; |
| | | background-color: #52ccba !important; |
| | | } |
| | | |
| | | .sliderContainer_success .sliderMask { |
| | | height: 38px; |
| | | border: 1px solid #52ccba; |
| | | background-color: #d2f4ef; |
| | | } |
| | | |
| | | .sliderContainer_success .sliderIcon { |
| | | background-position: 0 -40px !important; |
| | | } |
| | | |
| | | .sliderContainer_fail .slider { |
| | | height: 38px; |
| | | top: -1px; |
| | | border: 1px solid #f57a7a; |
| | | background-color: #f57a7a !important; |
| | | } |
| | | |
| | | .sliderContainer_fail .sliderMask { |
| | | height: 38px; |
| | | border: 1px solid #f57a7a; |
| | | background-color: #fce1e1; |
| | | } |
| | | |
| | | .sliderContainer_fail .sliderIcon { |
| | | background-position: 0 -83px !important; |
| | | } |
| | | .sliderContainer_active .sliderText, |
| | | .sliderContainer_success .sliderText, |
| | | .sliderContainer_fail .sliderText { |
| | | display: none; |
| | | } |
| | | |
| | | .sliderMask { |
| | | position: absolute; |
| | | left: 0; |
| | | top: 0; |
| | | height: 40px; |
| | | border: 0 solid #1991fa; |
| | | background: #d1e9fe; |
| | | } |
| | | |
| | | .slider { |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | width: 40px; |
| | | height: 40px; |
| | | background: #fff; |
| | | box-shadow: 0 0 3px rgba(0, 0, 0, 0.1); |
| | | cursor: pointer; |
| | | transition: background 0.2s linear; |
| | | } |
| | | |
| | | .slider:hover { |
| | | background: #1991fa; |
| | | } |
| | | |
| | | .slider:hover .sliderIcon { |
| | | background-position: 0 -40px; |
| | | } |
| | | |
| | | .sliderIcon { |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 100%; |
| | | background: url("./img/right.jpg"); |
| | | background-size: 100%; |
| | | background-repeat: no-repeat; |
| | | background-position: center; |
| | | } |
| | | |
| | | .refreshIcon { |
| | | position: absolute; |
| | | right: 5px; |
| | | top: 5px; |
| | | width: 25px; |
| | | height: 25px; |
| | | cursor: pointer; |
| | | background: url("./img//refresh.png"); |
| | | background-size: 100%; |
| | | background-repeat: no-repeat; |
| | | background-position: center; |
| | | z-index: 1; |
| | | } |
New file |
| | |
| | | (function (window) { |
| | | let l = 50, // 滑块边长 |
| | | r = 0, // 滑块半径 |
| | | w = 300, // canvas宽度 |
| | | h = 150, // canvas高度 |
| | | PI = Math.PI; |
| | | let L = l + r * 2; // 滑块实际边长 |
| | | |
| | | function createCanvas(width, height) { |
| | | const canvas = createElement("canvas"); |
| | | canvas.width = width; |
| | | canvas.height = height; |
| | | return canvas; |
| | | } |
| | | |
| | | function createImg(onload, info) { |
| | | const img = createElement("img"); |
| | | img.crossOrigin = "Anonymous"; |
| | | img.onload = onload; |
| | | img.onerror = () => { |
| | | img.src = getRandomImg(info.backgroundImage); |
| | | }; |
| | | img.src = getRandomImg(info.backgroundImage); |
| | | return img; |
| | | } |
| | | |
| | | function createImg2(onload, info) { |
| | | const block = createElement("img"); |
| | | block.crossOrigin = "Anonymous"; |
| | | block.onload = onload; |
| | | block.onerror = () => { |
| | | block.src = getRandomImg(info.frontImage); |
| | | }; |
| | | block.src = getRandomImg(info.frontImage); |
| | | return block; |
| | | } |
| | | |
| | | function createElement(tagName) { |
| | | return document.createElement(tagName); |
| | | } |
| | | |
| | | function addClass(tag, className) { |
| | | tag.classList.add(className); |
| | | } |
| | | |
| | | function removeClass(tag, className) { |
| | | tag.classList.remove(className); |
| | | } |
| | | |
| | | function getRandomImg(val) { |
| | | return val; |
| | | } |
| | | |
| | | function sum(x, y) { |
| | | return x + y; |
| | | } |
| | | |
| | | function square(x) { |
| | | return x * x; |
| | | } |
| | | |
| | | function clear(obj) { |
| | | obj.canvasCtx.clearRect(0, 0, w, h); |
| | | obj.blockCtx.clearRect(0, 0, w, h); |
| | | obj.block.width = w; |
| | | document.getElementById("msg").innerHTML = null; |
| | | document.getElementById("captcha").innerHTML = null; |
| | | } |
| | | |
| | | class jigsaw { |
| | | constructor(el, success, fail, info, parent) { |
| | | this.el = el; |
| | | this.success = success; |
| | | this.fail = fail; |
| | | this.info = info; |
| | | this.parent = parent; |
| | | } |
| | | |
| | | init() { |
| | | if (this.info) { |
| | | const { backgroundHeight, backgroundWidth, frontHeight, frontWidth } = |
| | | this.info; |
| | | l = frontHeight; |
| | | r = 0; |
| | | w = backgroundWidth; |
| | | h = backgroundHeight; |
| | | L = frontWidth; |
| | | } |
| | | this.initDOM(); |
| | | this.initImg(); |
| | | this.bindEvents(); |
| | | } |
| | | |
| | | initDOM() { |
| | | const canvas = createCanvas(w, h); // 画布 |
| | | const block = canvas.cloneNode(true); // 滑块 |
| | | const msg = createElement("div"); |
| | | const sliderContainer = createElement("div"); |
| | | const refreshIcon = createElement("div"); |
| | | const sliderMask = createElement("div"); |
| | | const slider = createElement("div"); |
| | | const sliderIcon = createElement("span"); |
| | | const text = createElement("span"); |
| | | |
| | | block.className = "block"; |
| | | msg.id = "msg"; |
| | | sliderContainer.className = "sliderContainer"; |
| | | refreshIcon.className = "refreshIcon"; |
| | | sliderMask.className = "sliderMask"; |
| | | slider.className = "slider"; |
| | | sliderIcon.className = "sliderIcon"; |
| | | text.innerHTML = "向右滑动滑块填充拼图"; |
| | | text.className = "sliderText"; |
| | | |
| | | const el = this.el; |
| | | el.appendChild(canvas); |
| | | el.appendChild(refreshIcon); |
| | | el.appendChild(block); |
| | | el.appendChild(msg); |
| | | slider.appendChild(sliderIcon); |
| | | sliderMask.appendChild(slider); |
| | | sliderContainer.appendChild(sliderMask); |
| | | sliderContainer.appendChild(text); |
| | | el.appendChild(sliderContainer); |
| | | |
| | | Object.assign(this, { |
| | | canvas, |
| | | block, |
| | | sliderContainer, |
| | | refreshIcon, |
| | | slider, |
| | | sliderMask, |
| | | sliderIcon, |
| | | text, |
| | | msg, |
| | | canvasCtx: canvas.getContext("2d"), |
| | | blockCtx: block.getContext("2d"), |
| | | addClass, |
| | | clear, |
| | | }); |
| | | } |
| | | |
| | | initImg() { |
| | | const block = createImg2(() => { |
| | | this.blockCtx.drawImage(block, 0, 0, w, h); |
| | | }, this.info); |
| | | const img = createImg(() => { |
| | | this.canvasCtx.drawImage(img, 0, 0, w, h); |
| | | }, this.info); |
| | | this.img = img; |
| | | } |
| | | |
| | | clean() { |
| | | this.canvasCtx.clearRect(0, 0, w, h); |
| | | this.blockCtx.clearRect(0, 0, w, h); |
| | | this.block.width = w; |
| | | } |
| | | |
| | | bindEvents() { |
| | | this.el.onselectstart = () => false; |
| | | this.refreshIcon.onclick = () => { |
| | | this.reset(); |
| | | }; |
| | | |
| | | let originX, |
| | | originY, |
| | | trail = [], |
| | | isMouseDown = false; |
| | | var that = this; |
| | | |
| | | var handleDragStart = function (e) { |
| | | originX = e.clientX || e.touches[0].clientX; |
| | | originY = e.clientY || e.touches[0].clientY; |
| | | // (originX = e.x), (originY = e.y); |
| | | isMouseDown = true; |
| | | }; |
| | | |
| | | var handleDragMove = function (e) { |
| | | if (!isMouseDown) return false; |
| | | var eventX = e.clientX || e.touches[0].clientX; |
| | | var eventY = e.clientY || e.touches[0].clientY; |
| | | const moveX = eventX - originX; |
| | | const moveY = eventY - originY; |
| | | if (moveX < 0 || moveX + 38 >= w) return false; |
| | | that.slider.style.left = moveX + "px"; |
| | | var blockLeft = ((w - 40 - 20) / (w - 40)) * moveX; |
| | | that.block.style.left = blockLeft + "px"; |
| | | addClass(that.sliderContainer, "sliderContainer_active"); |
| | | that.sliderMask.style.width = moveX + "px"; |
| | | console.log(that.sliderMask.offsetLeft, 4545); |
| | | trail.push(moveY); |
| | | }; |
| | | |
| | | var handleDragEnd = function (e) { |
| | | if (!isMouseDown) return false; |
| | | isMouseDown = false; |
| | | var eventX = e.clientX || e.changedTouches[0].clientX; |
| | | if (eventX == originX) return false; |
| | | removeClass(that.sliderContainer, "sliderContainer_active"); |
| | | that.trail = trail; |
| | | const { left } = that.verify(); |
| | | const { prefix } = that.info; |
| | | if (left && prefix) { |
| | | that.success(left, prefix, that); |
| | | } else { |
| | | addClass(that.sliderContainer, "sliderContainer_fail"); |
| | | that.fail && that.fail(left, prefix); |
| | | setTimeout(() => { |
| | | that.reset(); |
| | | }, 1000); |
| | | } |
| | | }; |
| | | this.slider.addEventListener("mousedown", handleDragStart); |
| | | this.slider.addEventListener("touchstart", handleDragStart); |
| | | document.addEventListener("mousemove", handleDragMove); |
| | | document.addEventListener("touchmove", handleDragMove); |
| | | document.addEventListener("mouseup", handleDragEnd); |
| | | document.addEventListener("touchend", handleDragEnd); |
| | | |
| | | document.addEventListener("mousedown", function () { |
| | | return false; |
| | | }); |
| | | document.addEventListener("touchstart", function () { |
| | | return false; |
| | | }); |
| | | // this.slider.addEventListener("mousedown"); |
| | | // document.addEventListener("mousemove"); |
| | | // document.addEventListener("mouseup"); |
| | | } |
| | | |
| | | verify() { |
| | | const arr = this.trail; // 拖动时y轴的移动距离 |
| | | const average = arr.reduce(sum) / arr.length; // 平均值 |
| | | const deviations = arr.map((x) => x - average); // 偏差数组 |
| | | const stddev = Math.sqrt(deviations.map(square).reduce(sum) / arr.length); // 标准差 |
| | | const left = parseInt(this.block.style.left); |
| | | return { |
| | | // spliced: Math.abs(left - this.x) < 10, |
| | | // TuringTest: average !== stddev, // 只是简单的验证拖动轨迹,相等时一般为0,表示可能非人为操作 |
| | | left, |
| | | // x: this.x, |
| | | }; |
| | | } |
| | | |
| | | reset() { |
| | | this.sliderContainer.className = "sliderContainer"; |
| | | this.slider.style.left = 0; |
| | | this.block.style.left = 0; |
| | | this.sliderMask.style.width = 0; |
| | | clear(this); |
| | | // this.initImg(); |
| | | this.parent.getImg(); |
| | | console.log(this.parent); |
| | | } |
| | | } |
| | | |
| | | window.jigsaw = { |
| | | init: function (element, success, fail, info, callback) { |
| | | new jigsaw(element, success, fail, info, callback).init(); |
| | | }, |
| | | }; |
| | | })(window); |
| | |
| | | () => { |
| | | $router.push({ |
| | | path: '/home', |
| | | }) |
| | | }); |
| | | } |
| | | " |
| | | src="@/assets/images/xiehe/home/Group_303.png" |
| | |
| | | <a |
| | | @click=" |
| | | () => { |
| | | $router.push({ |
| | | path: '/register', |
| | | }) |
| | | console.log(loginRef.value); |
| | | loginRef.logIn(); |
| | | } |
| | | " |
| | | >注册</a |
| | | > |
| | | | |
| | | <a |
| | | @click=" |
| | | () => { |
| | | $router.push({ |
| | | path: '/login', |
| | | query: { |
| | | redirectPath: $route.fullPath, |
| | | }, |
| | | }) |
| | | } |
| | | " |
| | | >登录</a |
| | | >注册/登录</a |
| | | > |
| | | </div> |
| | | <div v-else class="userInfoBox"> |
| | | <el-dropdown @command="handleCommand"> |
| | | <span style="cursor: pointer">欢迎您,{{ userInfo.name }}!</span> |
| | | <el-dropdown-menu slot="dropdown"> |
| | | <span class="el-dropdown-link"> |
| | | 欢迎您,{{ userStore?.userInfo.name }}! |
| | | <el-icon class="el-icon--right"> |
| | | <arrow-down /> |
| | | </el-icon> |
| | | </span> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <el-dropdown-item icon="el-icon-user" command="gotoPersonalCenter" |
| | | >个人中心</el-dropdown-item |
| | | > |
| | |
| | | >退出登录</el-dropdown-item |
| | | > |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <login ref="loginRef"></login> |
| | | <div class="contentBox navBox" v-show="!hideNav"> |
| | | <div |
| | | :class="{ |
| | |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { ref } from 'vue' |
| | | import { Search } from '@element-plus/icons-vue' |
| | | 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 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", |
| | | }, |
| | | ]) |
| | | ]); |
| | | |
| | | const gotoSearch = () => {} |
| | | const handleCommand = () => {} |
| | | const gotoPage = () => {} |
| | | onMounted(() => { |
| | | userInfo.value = userStore.userInfo; |
| | | console.log(userInfo.value, "userInfo"); |
| | | }); |
| | | |
| | | const gotoSearch = () => {}; |
| | | const handleCommand = (item) => { |
| | | if (item === "gotoPersonalCenter") { |
| | | router.push({ |
| | | path: "/personalCenter", |
| | | }); |
| | | } |
| | | if (item === "logout") { |
| | | localStorage.clear(); |
| | | router.push({ |
| | | path: "/home", |
| | | }); |
| | | } |
| | | }; |
| | | const gotoPage = (item) => { |
| | | router.push(item.path); |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | |
| | | p { |
| | | float: left; |
| | | } |
| | | } |
| | | |
| | | .loginInfoBox { |
| | | float: right; |
| | | .loginBtnBox { |
| | | a { |
| | | cursor: pointer; |
| | | text-decoration: none; |
| | | color: inherit; |
| | | margin: 0 4px; |
| | | } |
| | | } |
| | | } |
| | | width: 200px; |
| | | margin-left: 20px; |
| | | } |
| | | .logoBox { |
| | | padding: 25px 0; |
| | |
| | | width: 670px; |
| | | float: right; |
| | | padding-right: 10px; |
| | | line-height: 66px; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | .searchItem { |
| | | width: 120px; |
| | | vertical-align: initial; |
New file |
| | |
| | | <template> |
| | | <el-dialog |
| | | align-center |
| | | append-to-body |
| | | v-model="dialogFormVisible" |
| | | @close="closeDialog" |
| | | @open="openDialog" |
| | | class="fansdialog" |
| | | > |
| | | <div style="display: flex; justify-content: space-around"> |
| | | <el-image :src="dialogLeftImg" class="leftImg" /> |
| | | |
| | | <div class="logIn"> |
| | | <div class="signUpTitle" v-if="flag == 'logIn'"> |
| | | <ul> |
| | | <li |
| | | @click="signUpWay = 'authSignUp'" |
| | | :style="{ |
| | | color: signUpWay == 'authSignUp' ? '#144941' : '#545C63', |
| | | }" |
| | | > |
| | | 手机号登录 |
| | | </li> |
| | | <li>|</li> |
| | | <li |
| | | @click="wechatLoginOpen" |
| | | :style="{ color: signUpWay == 'wechat' ? '#144941' : '#545C63' }" |
| | | > |
| | | 微信登录 |
| | | </li> |
| | | </ul> |
| | | </div> |
| | | <div v-else style="text-align: center; color: #144941">注册</div> |
| | | <div |
| | | class="singUpPhone" |
| | | v-if="signUpWay === 'phone' || 'authSignUp'" |
| | | :style="{ height: signUpWay == 'findPassword' ? '450px' : '400px' }" |
| | | > |
| | | <el-form |
| | | :model="passFormData" |
| | | v-if="signUpWay === 'phone' || 'authSignUp'" |
| | | ref="passFormRef" |
| | | @keyup.enter="signInSystem(passFormRef)" |
| | | > |
| | | <el-form-item |
| | | v-if="signUpWay !== 'findPassword'" |
| | | :rules="[ |
| | | { min: 11, max: 11, message: '请输入11位电话号码' }, |
| | | { |
| | | 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 |
| | | ) |
| | | ) { |
| | | callback('请输入11位电话号码'); |
| | | } else { |
| | | callback(); |
| | | } |
| | | }, |
| | | }, |
| | | ]" |
| | | prop="telNumber" |
| | | > |
| | | <el-input |
| | | v-model="passFormData.telNumber" |
| | | placeholder="请输入手机号" |
| | | size="large" |
| | | > |
| | | <template #prepend> |
| | | <el-select |
| | | v-model="select" |
| | | placeholder="Select" |
| | | style="width: 110px" |
| | | class="selectPhone" |
| | | > |
| | | <el-option label="中国+86" value="86" /> |
| | | </el-select> |
| | | </template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button class="yanzhengBtn" @click="sliderImgDialogVisable = true" |
| | | >验证</el-button |
| | | > |
| | | </el-form-item> |
| | | <el-form-item |
| | | v-if="signUpWay === 'authSignUp'" |
| | | class="codeWay" |
| | | :rules="[ |
| | | { required: true, message: '请输入验证码' }, |
| | | { min: 4, max: 6, message: '请输入有效验证码' }, |
| | | ]" |
| | | prop="telCode" |
| | | > |
| | | <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 |
| | | > |
| | | </el-form-item> |
| | | <el-form-item |
| | | v-if="flag === 'signUp'" |
| | | :rules="[ |
| | | { required: true, message: '请输入密码' }, |
| | | { min: 8, max: 16, message: '密码在8到16位之间' }, |
| | | { |
| | | validator: (rule, value, callback) => { |
| | | if (!/\d/.test(value) || /^\d+$/.test(value)) { |
| | | callback('密码不能为纯数字或字母'); |
| | | } else { |
| | | callback(); |
| | | } |
| | | }, |
| | | }, |
| | | ]" |
| | | prop="password" |
| | | class="passwordInput" |
| | | > |
| | | <el-input |
| | | type="password" |
| | | show-password |
| | | v-model="passFormData.password" |
| | | placeholder="请输入密码" |
| | | size="large" |
| | | style="width: 304px" |
| | | > |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item |
| | | v-if="flag === 'signUp'" |
| | | :rules="[ |
| | | { required: true, message: '请输入确认密码' }, |
| | | { validator: validateLogInPassword }, |
| | | ]" |
| | | prop="confirmPassword" |
| | | class="passwordInput" |
| | | > |
| | | <el-input |
| | | type="password" |
| | | show-password |
| | | v-model="passFormData.confirmPassword" |
| | | placeholder="确认密码" |
| | | size="large" |
| | | style="width: 304px" |
| | | /> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-button class="loginBtn" @click="loginBtn">登录</el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <el-dialog |
| | | v-model="sliderImgDialogVisable" |
| | | align-center |
| | | destroy-on-close="true" |
| | | width="420" |
| | | class="sliderImgDialog" |
| | | > |
| | | <verify :MG="MG" @loginImgVerify="loginImgVerify"></verify> |
| | | </el-dialog> |
| | | </el-dialog> |
| | | </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(); |
| | | |
| | | const userStore = useUserStore(); |
| | | |
| | | 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 passFormData = ref({ |
| | | telNumber: "", |
| | | password: "", |
| | | telCode: "", |
| | | password: "", |
| | | confirmPassword: "", |
| | | }); |
| | | const closeDialog = () => { |
| | | countDown.value = 0; |
| | | clearInterval(timer); |
| | | if (passFormRef.value) { |
| | | passFormRef.value.resetFields(); |
| | | } |
| | | dialogFormVisible.value = false; |
| | | }; |
| | | // 弹窗打开事件 |
| | | const openDialog = () => {}; |
| | | |
| | | const loginImgVerify = (code) => { |
| | | sliderImgDialogVisable.value = false; |
| | | MG.identity |
| | | .getPhoneCode({ |
| | | phoneNumber: passFormData.value.telNumber, |
| | | imageCaptcha: code, |
| | | appRefCode: config.appRefCode, |
| | | }) |
| | | .then((res) => { |
| | | if (res == "验证码发送成功") { |
| | | getSecond(60); |
| | | ElMessage.success(res); |
| | | } else { |
| | | ElMessage.error(res); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | watchEffect(() => { |
| | | if (dialogFormVisible.value) { |
| | | } |
| | | }); |
| | | |
| | | //登录 |
| | | |
| | | const loginBtn = () => { |
| | | let query = { |
| | | phoneNumber: passFormData.value.telNumber, |
| | | phoneCaptcha: passFormData.value.telCode, |
| | | appRefCode: config.appRefCode, |
| | | platform: "string", |
| | | }; |
| | | MG.identity.loginByMobilePhone(query).then((res) => { |
| | | console.log("res", res); |
| | | userStore.setToken(res.data.accessToken); |
| | | |
| | | getUserInfo(); |
| | | }); |
| | | }; |
| | | |
| | | const getUserInfo = () => { |
| | | MG.identity.getCurrentAppUser().then((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"); |
| | | 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"); |
| | | // let nameAndPassword = res.secretList.find((item) => item.type == 'LoginNameAndPassword') |
| | | let emailInfo = res.secretList.find((item) => item.type == "EMail"); |
| | | if (teacherRole && teacherInfos) { |
| | | userStore.setUserInfo({ |
| | | ...userData, |
| | | ...teacherInfos, |
| | | phoneNumber: phoneInfo?.credential, |
| | | Email: emailInfo ? emailInfo.credential : JSON.parse(teacherInfos.data).email, |
| | | icon: wechatInfo?.icon, |
| | | role: "Teacher", |
| | | roleId: teacherRole.role.id, |
| | | userId: res.userId, |
| | | }); |
| | | } else if (wechatInfo) { |
| | | userStore.setUserInfo({ |
| | | ...userData, |
| | | ...wechatInfo, |
| | | phoneNumber: phoneInfo?.credential, |
| | | Email: emailInfo?.credential, |
| | | role: "Student", |
| | | userId: res.userId, |
| | | }); |
| | | } else if (studentInfo) { |
| | | userStore.setUserInfo({ |
| | | ...userData, |
| | | ...studentInfo, |
| | | icon: wechatInfo?.icon, |
| | | phoneNumber: phoneInfo?.credential, |
| | | Email: emailInfo?.credential, |
| | | role: "Student", |
| | | userId: res.userId, |
| | | }); |
| | | } else if (phoneInfo) { |
| | | userStore.setUserInfo({ |
| | | ...userData, |
| | | ...phoneInfo, |
| | | name: phoneInfo?.credential, |
| | | icon: phoneInfo?.icon, |
| | | phoneNumber: phoneInfo?.credential, |
| | | role: "Student", |
| | | userId: res.userId, |
| | | }); |
| | | } |
| | | } |
| | | router.go(0); |
| | | }); |
| | | }; |
| | | |
| | | // 倒计时 |
| | | const getSecond = (time) => { |
| | | if (!timer) { |
| | | countDown.value = time; |
| | | timer = setInterval(() => { |
| | | countDown.value--; |
| | | if (countDown.value == 0) { |
| | | clearInterval(timer); |
| | | timer = null; |
| | | } |
| | | }, 1000); |
| | | } |
| | | }; |
| | | |
| | | // 登录和重置密码按钮按钮 |
| | | const signInSystem = async (formEl) => { |
| | | if (!formEl) return; |
| | | formEl.validate((valid) => { |
| | | if (valid) { |
| | | // if (signUpWay.value === 'phone') { |
| | | // // 账号密码登录 |
| | | // passwordSignUp() |
| | | // } else if (signUpWay.value == 'authSignUp') { |
| | | // // 验证码登录 |
| | | // codeSignUp() |
| | | // } else { |
| | | // // 重置密码 |
| | | // changePassword() |
| | | // } |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const logIn = () => { |
| | | dialogFormVisible.value = true; |
| | | flag.value = "logIn"; |
| | | }; |
| | | |
| | | // 打开注册弹窗 |
| | | const signUp = () => { |
| | | dialogFormVisible.value = true; |
| | | flag.value = "signUp"; |
| | | }; |
| | | const wechatLoginOpen = () => { |
| | | signUpWay.value = "wechat"; |
| | | }; |
| | | |
| | | defineExpose({ |
| | | logIn, |
| | | signUp, |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | // 用户信息填写界面 |
| | | .changeUser { |
| | | .prompt-title { |
| | | width: 80%; |
| | | line-height: 24px; |
| | | color: #000; |
| | | span { |
| | | display: inline-block; |
| | | } |
| | | } |
| | | } |
| | | .fansdialog { |
| | | width: 806px; |
| | | |
| | | .leftImg { |
| | | box-sizing: border-box; |
| | | width: 403px; |
| | | } |
| | | |
| | | .el-dialog__header { |
| | | padding: 0; |
| | | } |
| | | |
| | | .el-dialog__body { |
| | | width: 806px; |
| | | height: 575px; |
| | | display: flex; |
| | | padding: 0 !important; |
| | | } |
| | | |
| | | .leftImg { |
| | | .el-image__inner { |
| | | width: 403px; |
| | | } |
| | | } |
| | | |
| | | .el-dialog__header { |
| | | padding: 0; |
| | | } |
| | | |
| | | .el-dialog__body { |
| | | width: 806px; |
| | | display: flex; |
| | | padding: 0 !important; |
| | | } |
| | | } |
| | | |
| | | .agreementDialog { |
| | | width: 760px; |
| | | height: 600px; |
| | | |
| | | p span { |
| | | line-height: 24px; |
| | | } |
| | | |
| | | .el-dialog__header { |
| | | font-size: 18px; |
| | | color: #333; |
| | | } |
| | | |
| | | .el-dialog__body { |
| | | overflow: auto; |
| | | height: 500px; |
| | | width: 760px; |
| | | } |
| | | |
| | | .el-dialog__footer { |
| | | display: flex; |
| | | justify-content: center; |
| | | } |
| | | } |
| | | |
| | | .wechatTipsDialog { |
| | | .el-dialog__header { |
| | | font-size: 18px; |
| | | } |
| | | |
| | | .el-dialog__body { |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | p { |
| | | margin-left: 10px; |
| | | line-height: 24px; |
| | | } |
| | | } |
| | | } |
| | | .sliderImgDialog { |
| | | .el-dialog__body { |
| | | min-height: 320px; |
| | | } |
| | | } |
| | | </style> |
| | | |
| | | <style lang="less"> |
| | | /** 登录注册弹窗 */ |
| | | .logIn { |
| | | width: 403px; |
| | | height: 100%; |
| | | padding-top: 48px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: space-around; |
| | | |
| | | .signUpTitle { |
| | | width: 100%; |
| | | ul { |
| | | display: flex; |
| | | justify-content: center; |
| | | width: 100%; |
| | | li { |
| | | height: 20px; |
| | | display: flex; |
| | | align-items: center; |
| | | .el-image { |
| | | margin-right: 5px; |
| | | width: 20px; |
| | | } |
| | | } |
| | | li:nth-child(2n + 1) { |
| | | cursor: pointer; |
| | | margin: 0 10px; |
| | | } |
| | | li:first-child { |
| | | margin-left: 0; |
| | | .el-image { |
| | | width: 10px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** 微信登录 */ |
| | | .signUpContent { |
| | | display: flex; |
| | | height: 400px; |
| | | flex-wrap: wrap; |
| | | flex-direction: column; |
| | | justify-content: space-around; |
| | | align-content: center; |
| | | |
| | | .el-image { |
| | | width: 176px; |
| | | } |
| | | |
| | | h2 { |
| | | font-size: 20px; |
| | | color: #000; |
| | | font-weight: 700; |
| | | text-align: center; |
| | | } |
| | | |
| | | p { |
| | | text-align: center; |
| | | line-height: 26px; |
| | | } |
| | | |
| | | .wechatCode { |
| | | h2 { |
| | | margin-bottom: 24px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** 密码登录 */ |
| | | .singUpPhone { |
| | | height: 400px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | |
| | | h2 { |
| | | padding-top: 35px; |
| | | font-size: 20px; |
| | | color: #000; |
| | | font-weight: 700; |
| | | text-align: center; |
| | | } |
| | | |
| | | .back { |
| | | display: flex; |
| | | align-items: center; |
| | | cursor: pointer; |
| | | margin: 10px 0px 0px 20px; |
| | | align-self: flex-start; |
| | | font-size: 12px; |
| | | color: #333; |
| | | } |
| | | |
| | | .el-form { |
| | | margin-top: 26px; |
| | | } |
| | | |
| | | .signInBtn { |
| | | width: 304px; |
| | | height: 41px; |
| | | margin-bottom: 33px; |
| | | border-radius: 3px; |
| | | // opacity: 0.55; |
| | | color: #fff; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .codeBtn { |
| | | width: 101px; |
| | | height: 41px; |
| | | background-color: #019e58; |
| | | // opacity: 0.55; |
| | | } |
| | | .yanzhengBtn { |
| | | width: 100%; |
| | | height: 41px; |
| | | background-color: #019e58; |
| | | color: #fff; |
| | | } |
| | | .loginBtn { |
| | | width: 76%; |
| | | height: 41px; |
| | | background: linear-gradient(90deg, #019e58 0%, #144941 100%); |
| | | color: #fff; |
| | | margin-top: 50px; |
| | | } |
| | | |
| | | .el-image { |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .authSignUp { |
| | | width: 305px; |
| | | flex: 1; |
| | | display: flex; |
| | | justify-content: end; |
| | | align-items: end; |
| | | padding-bottom: 20px; |
| | | |
| | | span { |
| | | cursor: pointer; |
| | | color: #333; |
| | | font-size: 12px; |
| | | } |
| | | } |
| | | |
| | | .codeWay { |
| | | .el-input { |
| | | width: 195px; |
| | | } |
| | | |
| | | .el-button { |
| | | width: 100px; |
| | | padding: 0; |
| | | margin: 0 0 0 10px; |
| | | } |
| | | |
| | | .authCodeBox { |
| | | width: 100px; |
| | | height: 50px; |
| | | margin-left: 10px; |
| | | cursor: pointer; |
| | | position: relative; |
| | | span { |
| | | position: absolute; |
| | | top: 35px; |
| | | height: 10px; |
| | | margin-bottom: 20px; |
| | | font-size: 10px; |
| | | color: #1f971f; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .claus { |
| | | margin-bottom: 10px; |
| | | color: #000; |
| | | font-size: 12px; |
| | | width: 100%; |
| | | text-align: center; |
| | | line-height: 26px; |
| | | } |
| | | } |
| | | .policy { |
| | | cursor: pointer; |
| | | color: #ff6c00; |
| | | } |
| | | /** 注册表单 */ |
| | | .signUp { |
| | | width: 403px; |
| | | justify-content: space-around; |
| | | color: #333; |
| | | font-size: 12px; |
| | | |
| | | span:first-child, |
| | | span:last-child { |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .logInTitle { |
| | | width: 96%; |
| | | font-size: 16px; |
| | | margin: 20px 0 0 20px; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | h4 { |
| | | font-size: 16px; |
| | | color: #ff6c00; |
| | | } |
| | | |
| | | .logInBox { |
| | | margin-top: 20px; |
| | | padding: 0 40px; |
| | | width: 100%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: center; |
| | | align-items: center; |
| | | |
| | | .el-form-item { |
| | | .el-button { |
| | | width: 100px; |
| | | height: 41px; |
| | | border-radius: 3px; |
| | | color: #fff; |
| | | font-size: 14px; |
| | | } |
| | | } |
| | | .agreement { |
| | | height: 40px; |
| | | display: flex; |
| | | align-items: center; |
| | | margin: 30px 0 0 0; |
| | | line-height: 32px; |
| | | height: 32px; |
| | | font-size: 12px; |
| | | color: #000; |
| | | |
| | | .el-checkbox { |
| | | margin-right: 10px; |
| | | } |
| | | |
| | | .el-link { |
| | | font-size: 12px; |
| | | } |
| | | |
| | | p { |
| | | height: 100%; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | } |
| | | |
| | | .hint { |
| | | font-size: 11px; |
| | | color: #545c63; |
| | | } |
| | | |
| | | .codeWay { |
| | | .el-input { |
| | | width: 195px; |
| | | } |
| | | |
| | | .el-button { |
| | | width: 100px; |
| | | padding: 0; |
| | | margin: 0 0 0 10px; |
| | | } |
| | | |
| | | .authCodeBox { |
| | | width: 100px; |
| | | height: 50px; |
| | | margin-left: 10px; |
| | | cursor: pointer; |
| | | position: relative; |
| | | span { |
| | | position: absolute; |
| | | top: 35px; |
| | | left: 0; |
| | | width: 100px; |
| | | font-size: 10px; |
| | | color: #1f971f; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .logInBtn { |
| | | width: 304px; |
| | | height: 41px; |
| | | margin-top: 10px; |
| | | margin-bottom: 20px; |
| | | border-radius: 3px; |
| | | color: #fff; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | /** 选择用户类型 */ |
| | | .changeUser { |
| | | width: 100%; |
| | | height: 100%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | .el-form-item { |
| | | &:last-child { |
| | | margin-bottom: 0; |
| | | } |
| | | .el-button { |
| | | height: 40px; |
| | | margin-left: 10px; |
| | | } |
| | | } |
| | | h2 { |
| | | font-size: 20px; |
| | | margin-top: 70px; |
| | | color: #000; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .el-radio-group { |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .el-radio-button { |
| | | width: 166px; |
| | | } |
| | | |
| | | /deep/ .el-radio-button__inner { |
| | | width: 166px; |
| | | height: 41px; |
| | | line-height: 24px; |
| | | border-radius: 4px; |
| | | border: 0; |
| | | border: 1px solid #dcdfe6; |
| | | } |
| | | |
| | | .el-radio-button:nth-child(n + 1) { |
| | | margin-bottom: 27px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .selectPhone { |
| | | background: #fff; |
| | | } |
| | | |
| | | // .el-select { |
| | | // width: 100px; |
| | | // height: 30px; |
| | | // color: red; |
| | | // border: none !important; |
| | | |
| | | // /deep/ .select-trigger { |
| | | // height: 100%; |
| | | |
| | | // .el-input--suffix { |
| | | // height: 100%; |
| | | // background-color: #fff; |
| | | // } |
| | | // } |
| | | // } |
| | | </style> |
| | |
| | | import axios from "axios"; |
| | | import myConfig from "@/assets/js/config.js"; |
| | | import toolClass from "@/assets/js/toolClass.js"; |
| | | import router from "@/router"; |
| | | import axios from 'axios' |
| | | import myConfig from '@/assets/js/config.js' |
| | | import toolClass from '@/assets/js/toolClass.js' |
| | | import router from '@/router' |
| | | // 创建 axios 实例 |
| | | const service = axios.create({ |
| | | baseURL: myConfig.requestCtx, |
| | | timeout: myConfig.requestTimeOut, // 请求超时时间 |
| | | }); |
| | | }) |
| | | |
| | | // 请求拦截器 |
| | | service.interceptors.request.use( |
| | | (config) => { |
| | | let token = localStorage.getItem(myConfig.tokenKey); |
| | | if (token) config.headers["Authorization"] = `bearer ${token}`; |
| | | return config; |
| | | let token = localStorage.getItem(myConfig.tokenKey) |
| | | console.log(token, 'token') |
| | | |
| | | if (token) config.headers['Authorization'] = `bearer ${token}` |
| | | return config |
| | | }, |
| | | (error) => { |
| | | // 发送失败 |
| | | Promise.reject(error); |
| | | } |
| | | ); |
| | | Promise.reject(error) |
| | | }, |
| | | ) |
| | | |
| | | // 响应拦截器 |
| | | service.interceptors.response.use( |
| | | (response) => { |
| | | // dataAxios 是 axios 返回数据中的 data |
| | | const dataAxios = response.data; |
| | | if (typeof dataAxios.data === "boolean") { |
| | | return dataAxios.data; |
| | | const dataAxios = response.data |
| | | if (typeof dataAxios.data === 'boolean') { |
| | | return dataAxios.data |
| | | } |
| | | if (response.config.responseType == "blob") { |
| | | return dataAxios; |
| | | if (response.config.responseType == 'blob') { |
| | | return dataAxios |
| | | } |
| | | const { success } = dataAxios; |
| | | const { success } = dataAxios |
| | | if (dataAxios.currentDate) { |
| | | sessionStorage.currentDate = new Date(dataAxios.currentDate).getTime(); |
| | | sessionStorage.currentDate = new Date(dataAxios.currentDate).getTime() |
| | | } |
| | | // 根据 code 进行判断 |
| | | if (response.status == 200 && response.statusText == "OK") { |
| | | return dataAxios.data ? dataAxios.data : dataAxios; |
| | | if (success) { |
| | | return dataAxios.data ? dataAxios.data : dataAxios |
| | | } else { |
| | | // 提示错误 |
| | | } |
| | | }, |
| | | (error) => { |
| | | if ( |
| | | (error.response && error.response.status == 401) || |
| | | error.code == "ERR_NETWORK" |
| | | ) { |
| | | console.log(router, "router"); |
| | | if ((error.response && error.response.status == 401) || error.code == 'ERR_NETWORK') { |
| | | console.log(router, 'router') |
| | | |
| | | localStorage.removeItem(myConfig.tokenKey); |
| | | localStorage.removeItem("jesk-userInfo"); |
| | | router.push({ |
| | | name: "login", |
| | | }); |
| | | localStorage.removeItem(myConfig.tokenKey) |
| | | localStorage.removeItem('xiehe-userInfo') |
| | | localStorage.removeItem('xiehe-isUserInfo') |
| | | localStorage.removeItem('alreadyElectronicBook') |
| | | localStorage.removeItem('alreadyPaperBook') |
| | | localStorage.removeItem('electronicBookList') |
| | | localStorage.removeItem('paperBookList') |
| | | sessionStorage.removeItem('cartNumber') |
| | | const url = window.location.hash.slice(1) |
| | | console.log(url, 'url') |
| | | if (url.includes('showLogin=1')) { |
| | | router.push(url) |
| | | } else { |
| | | // router.push(url) |
| | | if (url.includes('?')) { |
| | | console.log(url.includes('?')) |
| | | router.push(url) |
| | | } else { |
| | | router.push(url + '?showLogin=1') |
| | | } |
| | | } |
| | | } else { |
| | | if (error.response && error.response.data && error.response.data.error) { |
| | | console.error(error.response.data.error.msg); |
| | | console.error(error.response.data.error.msg) |
| | | } else { |
| | | console.error("请求发生错误"); |
| | | console.error('请求发生错误') |
| | | } |
| | | } |
| | | return Promise.reject(error); |
| | | } |
| | | ); |
| | | return Promise.reject(error) |
| | | }, |
| | | ) |
| | | |
| | | export default service; |
| | | export default service |
| | |
| | | import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router' |
| | | import HomeView from '../views/home/index.vue' |
| | | import aboutUs from '../views/aboutUs/index.vue' |
| | | import bookStore from '../views/bookStore/index.vue' |
| | | import bookdetail from '../views/bookStore/detail.vue' |
| | | import PageLayout from '../layout/baseLayout.vue' |
| | | const router = createRouter({ |
| | | history: createWebHashHistory(import.meta.env.BASE_URL), |
| | |
| | | name: 'home', |
| | | component: HomeView, |
| | | }, |
| | | { |
| | | path: '/aboutUs', |
| | | name: 'aboutUs', |
| | | component: aboutUs, |
| | | }, |
| | | { |
| | | path: '/bookdetail', |
| | | name: 'bookdetail', |
| | | component: bookdetail, |
| | | }, |
| | | { |
| | | path: '/bookStore', |
| | | name: 'bookStore', |
| | | component: bookStore, |
| | | }, |
| | | //个人中心 |
| | | { |
| | | path: '/personalCenter', |
New file |
| | |
| | | import { createPinia } from 'pinia' |
| | | |
| | | // 创建pinia实例 |
| | | const pinia = createPinia() |
| | | |
| | | export default pinia |
| | | |
| | | // export * from './modules/breadcrumb' |
| | | export * from './modules/user' |
File was renamed from src/store/modules/user.ts |
| | |
| | | // 用户信息 |
| | | import { defineStore } from 'pinia' |
| | | import config from '@/assets/js/config' |
| | | import config from '@/assets/js/config.js' |
| | | import { ref } from 'vue' |
| | | interface userInfo { |
| | | userName: string |
| | | userType: string |
| | | roleId?: any |
| | | role?: any |
| | | userId?: number |
| | | name?: string |
| | | } |
| | | |
| | | const { tokenKey, userInfoKey } = config |
| | | |
| | | |
| | | export const useUserStore = defineStore('user', () => { |
| | | const token = localStorage.getItem(config.tokenKey) |
| | | ? ref<string>(localStorage.getItem(config.tokenKey) as string) |
| | | : ref<string>() |
| | | const userInfo = localStorage.getItem(config.userInfoKey) |
| | | ? ref<userInfo>(JSON.parse(localStorage.getItem(config.userInfoKey) as string)) |
| | | : ref<userInfo>() |
| | | const setToken = (value: string) => { |
| | | const token = localStorage.getItem(tokenKey) ? ref(localStorage.getItem(tokenKey)) : ref() |
| | | const userInfo = localStorage.getItem(userInfoKey) |
| | | ? ref(JSON.parse(localStorage.getItem(userInfoKey))) |
| | | : ref() |
| | | const setToken = (value) => { |
| | | token.value = value |
| | | localStorage.setItem(config.tokenKey, value) |
| | | localStorage.setItem(tokenKey, value) |
| | | } |
| | | const setUserInfo = (value: userInfo) => { |
| | | const setUserInfo = (value) => { |
| | | userInfo.value = value |
| | | localStorage.setItem(config.userInfoKey, JSON.stringify(value)) |
| | | localStorage.setItem(userInfoKey, JSON.stringify(value)) |
| | | } |
| | | // 退出登录 |
| | | const delteUserInfo = () => { |
| | | ;((token.vlaue = ''), (userInfo.value = { userName: '', userType: '' })) |
| | | localStorage.removeItem(config.tokenKey) |
| | | localStorage.removeItem(config.userInfoKey) |
| | | localStorage.removeItem(tokenKey) |
| | | localStorage.removeItem(userInfoKey) |
| | | localStorage.removeItem('xiehe-isUserInfo') |
| | | } |
| | | // 购物车数量 |
| | | let cartNum = ref<number>(1) |
| | | let cartNum = ref(1) |
| | | // 更新右侧弹出框购物车的数量 |
| | | const updateRightPop = () => { |
| | | cartNum.value += 1 |
| | | } |
| | | |
| | | // 购物车商品id |
| | | const shoppingIds = ref<number[]>([]) |
| | | const updateShoppingIds = (ids: number[]) => { |
| | | const shoppingIds = ref([]) |
| | | const updateShoppingIds = (ids) => { |
| | | shoppingIds.value = ids |
| | | } |
| | | |
| | | // 已购买的商品id |
| | | const buyIds = ref<number[]>([]) |
| | | const updateBuyIds = (ids: number[]) => { |
| | | const buyIds = ref([]) |
| | | const updateBuyIds = (ids) => { |
| | | buyIds.value = ids |
| | | } |
| | | |
| | |
| | | ? ref(JSON.parse(localStorage.getItem('alreadyElectronicBook'))) |
| | | : ref([]) |
| | | // 添加电子样书列表 |
| | | const appplyElectronicBook = (value: data) => { |
| | | const appplyElectronicBook = (value) => { |
| | | electronicBookList.value.push(value) |
| | | localStorage.setItem('electronicBookList', JSON.stringify(electronicBookList.value)) |
| | | } |
| | | |
| | | //添加纸质样式列表 |
| | | const appplyPaperBook = (value: data) => { |
| | | const appplyPaperBook = (value) => { |
| | | paperBookList.value.push(value) |
| | | localStorage.setItem('paperBookList', JSON.stringify(paperBookList.value)) |
| | | } |
| | | |
| | | //删除电子样书列表 |
| | | const removeElectronicBook = (value: int) => { |
| | | const removeElectronicBook = (value) => { |
| | | electronicBookList.value.splice(value, 1) |
| | | localStorage.setItem('electronicBookList', JSON.stringify(electronicBookList.value)) |
| | | } |
| | | |
| | | //删除纸质样式 |
| | | const removePaperBook = (value: int) => { |
| | | const removePaperBook = (value) => { |
| | | paperBookList.value.splice(value, 1) |
| | | localStorage.setItem('paperBookList', JSON.stringify(paperBookList.value)) |
| | | } |
| | | const emptyBookList = (value: data) => { |
| | | const emptyBookList = (value) => { |
| | | if (value && value.type == 'eBook') { |
| | | electronicBookList.value = [] |
| | | localStorage.setItem('electronicBookList', JSON.stringify(electronicBookList.value)) |
| | |
| | | } |
| | | |
| | | //已申请图书 |
| | | const alreadyPaperBookList = (value: data) => { |
| | | const alreadyPaperBookList = (value) => { |
| | | alreadyPaperBook.value = value.list |
| | | localStorage.setItem('alreadyPaperBook', JSON.stringify(alreadyPaperBook.value)) |
| | | } |
| | | |
| | | const alreadyElectronicBookList = (value: data) => { |
| | | const alreadyElectronicBookList = (value) => { |
| | | alreadyElectronicBook.value = value.list |
| | | localStorage.setItem('alreadyElectronicBook', JSON.stringify(alreadyElectronicBook.value)) |
| | | } |
| | |
| | | removePaperBook, |
| | | emptyBookList, |
| | | alreadyPaperBookList, |
| | | alreadyElectronicBookList, |
| | | alreadyElectronicBookList |
| | | } |
| | | }) |
| | | |
New file |
| | |
| | | <template> |
| | | <div class="homePage"> |
| | | <el-carousel :height="screenheight + 'px'"> |
| | | <el-carousel-item v-for="(item, index) in banner" :key="index"> |
| | | <div class="bannerBox imgBox"> |
| | | <img id="autoHeight" class="bannerImg" :src="item.icon" @click="bannerLink(item)" /> |
| | | </div> |
| | | </el-carousel-item> |
| | | </el-carousel> |
| | | |
| | | <div class="contentBox"> |
| | | <div class="crumbs"> |
| | | <el-breadcrumb separator-class="el-icon-arrow-right"> |
| | | <el-breadcrumb-item :to="{ name: 'home' }">首页</el-breadcrumb-item> |
| | | <el-breadcrumb-item>关于我们</el-breadcrumb-item> |
| | | </el-breadcrumb> |
| | | </div> |
| | | <div class="aboutUs"> |
| | | <div class="aboutTitle"> |
| | | <div class="titleBox1"> |
| | | <img class="autoImg" src="@/assets/images/xiehe/about/yinhao.png" alt="" /> |
| | | </div> |
| | | <div class="titleText">Publisher Introduction</div> |
| | | </div> |
| | | <div class="textBox" v-html="publisherIntroduction"></div> |
| | | <div class="statisticsBox"> |
| | | <div class="statisticsItem"> |
| | | <div class="statisticsNum"> |
| | | {{ publisherData.focusOnMedical }} <span class="circleBox">年</span> |
| | | </div> |
| | | <div class="statisticsTitle">专注医学出版</div> |
| | | </div> |
| | | <div class="statisticsItem"> |
| | | <div class="statisticsNum">{{ publisherData.topExpertDatabase }}+ 位</div> |
| | | <div class="statisticsTitle">顶级专家库</div> |
| | | </div> |
| | | <div class="statisticsItem"> |
| | | <div class="statisticsNum"> |
| | | {{ publisherData.accumulatedTextbooks }}+ <span class="circleBox">本</span> |
| | | </div> |
| | | <div class="statisticsTitle">累计出版教材教辅</div> |
| | | </div> |
| | | <div class="statisticsItem"> |
| | | <div class="statisticsNum"> |
| | | {{ publisherData.academicJournals }} <span class="circleBox">本</span> |
| | | </div> |
| | | <div class="statisticsTitle">学术期刊</div> |
| | | </div> |
| | | <div class="statisticsItem"> |
| | | <div class="statisticsNum"> |
| | | {{ publisherData.dualCoreJournal }} <span class="circleBox">本</span> |
| | | </div> |
| | | <div class="statisticsTitle">双核心期刊</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="brandCultureBox"> |
| | | <div class="brandCultureTop"> |
| | | <div class="CultureBox"> |
| | | <div class="brandCultureTitle"> |
| | | <div>理念与品牌文化</div> |
| | | <div class="enText">Philosophy & Brand Culture</div> |
| | | </div> |
| | | <div class="cultureList" v-loading="loading"> |
| | | <div class="cultureItem firstItem"> |
| | | <div class="cultureTitle" style="border-bottom: 1px solid rgba(255, 255, 255, 0.1)"> |
| | | <div class="leftIcon"> |
| | | <img class="autoImg" src="@/assets/images/xiehe/about/zongzhi.png" alt="" /> |
| | | </div> |
| | | <div class="titleTextInfo"> |
| | | <div class="itemTitle" style="color: #fff">{{ ideaBrandCulture[0]?.name }}</div> |
| | | <div class="itemSubTitle" style="color: #fff"> |
| | | {{ ideaBrandCulture[0]?.EnglishName }} |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div |
| | | class="itemText" |
| | | style="color: #d5d5d5" |
| | | v-html="ideaBrandCulture[0]?.content" |
| | | ></div> |
| | | </div> |
| | | <div class="cultureItem"> |
| | | <div class="cultureTitle"> |
| | | <div class="leftIcon"> |
| | | <img class="autoImg" src="@/assets/images/xiehe/about/beijing.png" alt="" /> |
| | | </div> |
| | | <div class="titleTextInfo"> |
| | | <div class="itemTitle">{{ ideaBrandCulture[1]?.name }}</div> |
| | | <div class="itemSubTitle"> |
| | | {{ ideaBrandCulture[1]?.EnglishName }} |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="itemText" v-html="ideaBrandCulture[1]?.content"></div> |
| | | </div> |
| | | <div class="cultureItem"> |
| | | <div class="cultureTitle"> |
| | | <div class="leftIcon"> |
| | | <img class="autoImg" src="@/assets/images/xiehe/about/zizhi.png" alt="" /> |
| | | </div> |
| | | <div class="titleTextInfo"> |
| | | <div class="itemTitle">{{ ideaBrandCulture[2]?.name }}</div> |
| | | <div class="itemSubTitle"> |
| | | {{ ideaBrandCulture[2]?.EnglishName }} |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="itemText" v-html="ideaBrandCulture[2]?.content"></div> |
| | | </div> |
| | | <div class="cultureItem"> |
| | | <div class="cultureTitle"> |
| | | <div class="leftIcon"> |
| | | <img class="autoImg" src="@/assets/images/xiehe/about/fazhan.png" alt="" /> |
| | | </div> |
| | | <div class="titleTextInfo"> |
| | | <div class="itemTitle">{{ ideaBrandCulture[3]?.name }}</div> |
| | | <div class="itemSubTitle"> |
| | | {{ ideaBrandCulture[3]?.EnglishName }} |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="itemText" v-html="ideaBrandCulture[3]?.content"></div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="page-container"> |
| | | <MapContainer /> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import moment from 'moment' |
| | | import MapContainer from '@/components/MapContainer.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 banner = reactive([]) |
| | | let publisherIntroduction = ref('') |
| | | let publisherData = ref('') |
| | | let ideaBrandCulture = ref([]) |
| | | let loading = ref(false) |
| | | |
| | | const getBanner = () => { |
| | | MG.resource |
| | | .getItem({ |
| | | path: 'banner\\homeBanner', |
| | | fields: { link: [] }, |
| | | paging: { start: 0, size: 9 }, |
| | | }) |
| | | .then((res) => { |
| | | banner.push(...res.datas) |
| | | console.log(res.datas) |
| | | }) |
| | | } |
| | | const getPublisherIntroduction = () => { |
| | | MG.resource |
| | | .getItem({ |
| | | path: 'aboutUs\\publisherIntroduction', |
| | | fields: { content: [] }, |
| | | paging: { start: 0, size: 9 }, |
| | | }) |
| | | .then((res) => { |
| | | console.log(res.datas) |
| | | publisherIntroduction.value = res.datas[0].content |
| | | }) |
| | | } |
| | | const getIdeaBrandCulture = () => { |
| | | loading.value = true |
| | | MG.resource |
| | | .getItem({ |
| | | path: 'aboutUs\\ideaBrandCulture', |
| | | fields: { content: [], EnglishName: [] }, |
| | | paging: { start: 0, size: 9 }, |
| | | }) |
| | | .then((res) => { |
| | | console.log(res.datas, 'ideaBrandCulture') |
| | | ideaBrandCulture.value = res.datas |
| | | loading.value = false |
| | | }) |
| | | } |
| | | const getPublisherData = () => { |
| | | MG.resource |
| | | .getItem({ |
| | | path: 'aboutUs\\publisherData', |
| | | fields: { |
| | | academicJournals: [], |
| | | accumulatedTextbooks: [], |
| | | dualCoreJournal: [], |
| | | focusOnMedical: [], |
| | | topExpertDatabase: [], |
| | | }, |
| | | paging: { start: 0, size: 1 }, |
| | | }) |
| | | .then((res) => { |
| | | console.log(res.datas, 'publisherData') |
| | | publisherData.value = res.datas[0] |
| | | }) |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getBanner() |
| | | getPublisherIntroduction() |
| | | getPublisherData() |
| | | getIdeaBrandCulture() |
| | | }) |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | .homePage { |
| | | min-width: 1220px; |
| | | min-height: calc(100vh - 61.8%); |
| | | background-color: #fff; |
| | | } |
| | | .contentBox { |
| | | background-color: #fff; |
| | | |
| | | padding-bottom: 100px; |
| | | margin-top: 35px; |
| | | .aboutUs { |
| | | width: 100%; |
| | | font-size: 16px; |
| | | border-top: 1px solid #ededed; |
| | | margin-top: 40px; |
| | | .aboutTitle { |
| | | display: flex; |
| | | width: 100%; |
| | | padding-top: 30px; |
| | | .titleBox1 { |
| | | position: relative; |
| | | width: 50px; |
| | | height: 50px; |
| | | margin-right: 20px; |
| | | } |
| | | .titleText { |
| | | font-size: 48px; |
| | | font-weight: 700; |
| | | opacity: 0.05; |
| | | } |
| | | } |
| | | .block { |
| | | display: inline-block; |
| | | width: 4px; |
| | | height: 4px; |
| | | margin-right: 10px; |
| | | vertical-align: middle; |
| | | background: #dadada; |
| | | } |
| | | .selected { |
| | | background-color: #e7f9ef; |
| | | .block { |
| | | background-color: #008e3f; |
| | | } |
| | | } |
| | | .title { |
| | | padding: 0; |
| | | font-weight: 700; |
| | | text-align: center; |
| | | background: #008e3f; |
| | | color: #fff; |
| | | line-height: 36px; |
| | | border-bottom: 0; |
| | | } |
| | | div { |
| | | cursor: pointer; |
| | | // border-bottom: 1px dashed #ededed; |
| | | } |
| | | .colorText { |
| | | color: #144941; |
| | | } |
| | | .textBox { |
| | | line-height: 20px; |
| | | margin-top: 30px; |
| | | p { |
| | | margin-top: 30px; |
| | | } |
| | | } |
| | | } |
| | | .statisticsBox { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | margin-top: 80px; |
| | | text-align: center; |
| | | .statisticsNum { |
| | | font-size: 48px; |
| | | } |
| | | .statisticsTitle { |
| | | margin-top: 10px; |
| | | } |
| | | .circleBox { |
| | | width: 26px; |
| | | height: 26px; |
| | | display: inline-block; |
| | | font-size: 20px; |
| | | line-height: 26px; |
| | | color: #fff; |
| | | background-color: #144941; |
| | | border-radius: 50%; |
| | | } |
| | | } |
| | | } |
| | | .brandCultureTop { |
| | | background-image: url(@/assets/images/xiehe/about/wenhua_bg.png); |
| | | width: 100%; |
| | | height: 500px; |
| | | padding-top: 55px; |
| | | } |
| | | .brandCultureTitle { |
| | | font-size: 36px; |
| | | color: #fff; |
| | | font-weight: 700; |
| | | text-align: center; |
| | | } |
| | | |
| | | .cultureList { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | width: 100%; |
| | | margin-top: 60px; |
| | | } |
| | | |
| | | .cultureItem { |
| | | width: 320px; |
| | | height: 320px; |
| | | background-color: #fff; |
| | | margin-left: 30px; |
| | | padding: 20px; |
| | | box-sizing: border-box; |
| | | } |
| | | .firstItem { |
| | | background-color: #144941; |
| | | color: #fff; |
| | | width: 320px; |
| | | height: 320px; |
| | | text-align: center; |
| | | margin-left: 0px; |
| | | } |
| | | .CultureBox { |
| | | width: 1200px; |
| | | margin: 0 auto; |
| | | } |
| | | .leftIcon { |
| | | width: 58px; |
| | | height: 58px; |
| | | position: relative; |
| | | } |
| | | .cultureTitle { |
| | | display: flex; |
| | | border-bottom: 1px solid #dedede; |
| | | padding-bottom: 16px; |
| | | } |
| | | .titleTextInfo { |
| | | margin-left: 20px; |
| | | text-align: left; |
| | | } |
| | | .itemTitle { |
| | | font-size: 18px; |
| | | font-weight: 700; |
| | | line-height: 36px; |
| | | color: #333; |
| | | } |
| | | .itemSubTitle { |
| | | color: #000; |
| | | opacity: 0.5; |
| | | } |
| | | .itemText { |
| | | font-size: 16px; |
| | | line-height: 28px; |
| | | color: #000; |
| | | padding-top: 20px; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="homePage"> |
| | | <div class="infoBox"> |
| | | <div class="contentBox"> |
| | | <div class="crumbs"> |
| | | <el-breadcrumb separator-class="el-icon-arrow-right"> |
| | | <el-breadcrumb-item :to="{ name: 'bookStore' }">数字教材</el-breadcrumb-item> |
| | | <el-breadcrumb-item>详情</el-breadcrumb-item> |
| | | </el-breadcrumb> |
| | | </div> |
| | | <div class="infoTag" v-if="bookInfo.projectTitle"> |
| | | <el-tooltip |
| | | class="item" |
| | | effect="dark" |
| | | :content="bookInfo.projectTitle" |
| | | placement="top-start" |
| | | > |
| | | <div class="tagText"> |
| | | {{ bookInfo.projectTitle }} |
| | | </div> |
| | | </el-tooltip> |
| | | </div> |
| | | <div class="bookDetail"> |
| | | <div class="bookImg"> |
| | | <img class="autoImg" :src="bookInfo.icon" alt="" /> |
| | | </div> |
| | | <span class="iconfont icon-tubiaozhizuo"></span> |
| | | |
| | | <div class="detailBox"> |
| | | <div class="bookTitle"> |
| | | <div class="bookName" :title="bookInfo.name"> |
| | | {{ bookInfo.name }} |
| | | </div> |
| | | <div class="bookTag" :title="bookInfo.seriesName"> |
| | | {{ bookInfo.seriesName }} |
| | | </div> |
| | | <div class="collectBox"> |
| | | <img |
| | | @click="collectBook" |
| | | v-if="bookInfo.isFavourite" |
| | | class="buyIcon" |
| | | src="@/assets/images/bookStore/shoucang.svg" |
| | | style="margin-right: 10px" |
| | | /> |
| | | <span |
| | | @click="collectBook" |
| | | v-else |
| | | class="iconfont icon-shoucang" |
| | | style="margin-right: 10px" |
| | | > |
| | | </span> |
| | | <div class="collectText" @click="collectBook" v-if="bookInfo.isFavourite"> |
| | | 已收藏 |
| | | </div> |
| | | <div class="collectText" @click="collectBook" v-else>收藏</div> |
| | | </div> |
| | | </div> |
| | | <div class="authorBox"> |
| | | <div class="titleBox1"> |
| | | <div>作者:</div> |
| | | <div>出版时间:</div> |
| | | </div> |
| | | <div class="valueBox"> |
| | | <div> |
| | | {{ bookInfo.author ? bookInfo.author : '-' }} |
| | | </div> |
| | | <div> |
| | | {{ |
| | | bookInfo.publicationDate |
| | | ? moment(bookInfo.publicationDate).format('YYYY-MM-DD') |
| | | : '-' |
| | | }} |
| | | </div> |
| | | </div> |
| | | <div class="titleBox1" style="margin-left: 30px"> |
| | | <div>ISBN:</div> |
| | | <div>版次:</div> |
| | | </div> |
| | | <div class="valueBox"> |
| | | <div> |
| | | {{ bookInfo.isbn ? bookInfo.isbn : '-' }} |
| | | </div> |
| | | <div> |
| | | {{ bookInfo.pubNumber ? bookInfo.pubNumber : '-' }} |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="authorBox" style="box-sizing: border-box"> |
| | | <div class="titleBox1"> |
| | | <div>一级分类:</div> |
| | | <div>二级分类:</div> |
| | | </div> |
| | | <div class="valueBox"> |
| | | <div>全国高等职业教育预防医学专业规划教材</div> |
| | | <div>高等职业教育</div> |
| | | </div> |
| | | </div> |
| | | <div class="purchaseBox"> |
| | | <div class="priceBox"> |
| | | <span v-if="bookInfo.price && bookInfo.price > 0"> |
| | | <span>定价:</span><span>¥</span> <span>{{ bookInfo.price || '-' }}</span |
| | | ><span v-if="bookInfo.VirtualPrice">原价:¥{{ bookInfo.VirtualPrice }}</span> |
| | | </span> |
| | | |
| | | <span class="price" v-else> |
| | | <span class="freePrice">免费</span> |
| | | </span> |
| | | </div> |
| | | <div |
| | | class="buyInfo" |
| | | v-if=" |
| | | (currentRoute !== 'teachingServices' && bookInfo.paperBookDD) || |
| | | bookInfo.paperBookJD || |
| | | bookInfo.paperBookTmall |
| | | " |
| | | > |
| | | 纸质书其他购买渠道: |
| | | <span @click="toJDLink" v-if="bookInfo.paperBookJD"> |
| | | <img class="buyIcon" src="@/assets/images/bookStore/京东icon-01.svg" />京东</span |
| | | > |
| | | <span @click="toDDLink" v-if="bookInfo.paperBookDD" |
| | | ><img class="buyIcon" src="@/assets/images/bookStore/当当网.svg" />当当</span |
| | | > |
| | | <span @click="toTmLink" v-if="bookInfo.paperBookTmall" |
| | | ><img |
| | | class="buyIcon" |
| | | src="@/assets/images/bookStore/tianmaologo2.svg" |
| | | />天猫</span |
| | | > |
| | | </div> |
| | | </div> |
| | | <div class="btnBox"> |
| | | <el-button |
| | | v-if=" |
| | | currentRoute !== 'teachingServices' && |
| | | !bookInfo.alreadyBuy && |
| | | bookInfo.isSell && |
| | | bookInfo.isSell == '1' |
| | | " |
| | | type="primary" |
| | | :disabled="bookInfo.alreadyBuy" |
| | | @click="gotoOrder" |
| | | >电子书购买</el-button |
| | | > |
| | | <el-button |
| | | v-if="bookInfo.pdfFreeFile && !bookInfo.alreadyBuy" |
| | | type="primary" |
| | | plain |
| | | style="min-width: 98px" |
| | | @click="previewBook" |
| | | >试读</el-button |
| | | > |
| | | <el-button |
| | | v-else-if="bookInfo.pdfFile && bookInfo.alreadyBuy" |
| | | type="primary" |
| | | plain |
| | | style="min-width: 98px" |
| | | @click="previewBook" |
| | | >立即阅读</el-button |
| | | > |
| | | <el-button |
| | | v-if="currentRoute == 'teachingServices' && !bookInfo.alreadyBuy" |
| | | plain |
| | | @click="addEbook" |
| | | >电子样书</el-button |
| | | > |
| | | <el-button v-if="currentRoute == 'teachingServices'" plain @click="addPaperBook" |
| | | >纸质样书</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> |
| | | |
| | | <div class="detailContent contentBox"> |
| | | <div class="resourceBox"> |
| | | <div class="tabsBox"> |
| | | <el-tabs v-model="editableTabsValue" type="card" class="demo-tabs"> |
| | | <el-tab-pane |
| | | v-for="item in editableTabs" |
| | | :key="item.name" |
| | | :label="item.title" |
| | | :name="item.name" |
| | | > |
| | | {{ item.content }} |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </div> |
| | | <div v-if="editableTabsValue == '1'" class="textbookInfo"> |
| | | <div class="textbookInfoItem"> |
| | | <div class="titleBorderBox">图书简介</div> |
| | | <div class="textbookContent"></div> |
| | | </div> |
| | | <div class="textbookInfoItem"> |
| | | <div class="titleBorderBox">作者简介</div> |
| | | <div class="authorInfo"></div> |
| | | </div> |
| | | </div> |
| | | <div v-else-if="editableTabsValue == '2'" class="catalogue">bbbb</div> |
| | | </div> |
| | | <div class="recommendBox"></div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import moment from 'moment' |
| | | import { ref, onBeforeMount, inject, reactive, onMounted } from 'vue' |
| | | const MG = inject('MG') |
| | | import { useRouter, useRoute } from 'vue-router' |
| | | const route = useRoute() |
| | | const router = useRouter() |
| | | let bookInfo = ref({}) |
| | | let digitalTextId = ref('') |
| | | let editableTabsValue = ref('1') |
| | | |
| | | const editableTabs = reactive([ |
| | | { |
| | | title: '教材信息', |
| | | name: '1', |
| | | }, |
| | | { |
| | | title: '目录', |
| | | name: '2', |
| | | }, |
| | | { |
| | | title: '配套资源', |
| | | name: '3', |
| | | }, |
| | | { |
| | | title: '题库', |
| | | name: '4', |
| | | }, |
| | | { |
| | | title: '教师资源', |
| | | name: '5', |
| | | }, |
| | | { |
| | | title: '资源统计', |
| | | name: '6', |
| | | }, |
| | | ]) |
| | | |
| | | onMounted(() => { |
| | | digitalTextId.value = route.query.bookId |
| | | getBookDetail(digitalTextId.value) |
| | | }) |
| | | |
| | | const getBookDetail = (id) => { |
| | | const query = { |
| | | path: '*', |
| | | queryType: '*', |
| | | productId: id, |
| | | storeInfo: 'defaultGoodsStore1', |
| | | coverSize: { |
| | | height: 300, |
| | | width: 210, |
| | | }, |
| | | fields: { |
| | | author: [], |
| | | isbn: [], |
| | | editionPrinting: [], |
| | | publicationDate: [], |
| | | content: [], |
| | | authorIntroduction: [], |
| | | catalogue: [], |
| | | probationPage: [], |
| | | teachingLevel: [], |
| | | professionalCategory: [], |
| | | executiveEditor: [], |
| | | }, |
| | | } |
| | | MG.store.getProductDetail(query).then((res) => { |
| | | console.log(res, 'res') |
| | | bookInfo.value = res.datas |
| | | console.log(res.datas, 'res') |
| | | }) |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | .homePage { |
| | | min-width: 1220px; |
| | | min-height: calc(100vh - 61.8%); |
| | | background-color: #fff; |
| | | padding-bottom: 100px; |
| | | } |
| | | |
| | | .infoBox { |
| | | width: 100%; |
| | | height: 530px; |
| | | padding-top: 10px; |
| | | background-color: #fff; |
| | | background-image: url('@/assets/images/xiehe/detail/details_bg.png'); |
| | | } |
| | | .infoTag { |
| | | position: relative; |
| | | width: 0px; |
| | | height: 0px; |
| | | border-right: 20px solid #fff; |
| | | border-left: 503px solid #e50021; |
| | | border-top: 19px solid #e50021; |
| | | border-bottom: 19px solid #e50021; |
| | | } |
| | | .tagText { |
| | | position: absolute; |
| | | left: -480px; |
| | | top: -9.5px; |
| | | max-width: 480px; |
| | | text-overflow: ellipsis; |
| | | color: #fff; |
| | | font-size: 18px; |
| | | overflow: hidden; |
| | | white-space: nowrap; |
| | | } |
| | | .bookDetail { |
| | | display: flex; |
| | | overflow: hidden; |
| | | margin-top: 30px; |
| | | } |
| | | .bookImg { |
| | | position: relative; |
| | | width: 338px; |
| | | height: 400px; |
| | | box-shadow: 2px 2px 10px #f2f2f2; |
| | | } |
| | | .detailBox { |
| | | flex: 1; |
| | | height: 450px; |
| | | position: relative; |
| | | margin-top: 20px; |
| | | overflow: hidden; |
| | | } |
| | | .collectBox { |
| | | position: absolute; |
| | | right: 80px; |
| | | font-size: 14px; |
| | | color: #999999; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .collectBox span:nth-child(1) { |
| | | margin-right: 10px; |
| | | font-size: 16px; |
| | | } |
| | | .collectBox span:nth-child(2) { |
| | | margin-left: 10px; |
| | | margin-right: 10px; |
| | | |
| | | font-size: 16px; |
| | | } |
| | | .iconfont { |
| | | font-size: 25px !important; |
| | | vertical-align: middle; |
| | | } |
| | | .bookTitle { |
| | | width: 100%; |
| | | height: 40px; |
| | | line-height: 40px; |
| | | padding-left: 100px; |
| | | display: flex; |
| | | padding-right: 240px; |
| | | box-sizing: border-box; |
| | | } |
| | | .collectText { |
| | | font-size: 16px; |
| | | line-height: 25px; |
| | | display: inline-block; |
| | | } |
| | | .bookName { |
| | | flex: 1; |
| | | font-size: 26px; |
| | | color: #333; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | overflow: hidden; |
| | | } |
| | | .bookTag { |
| | | max-width: 200px; |
| | | font-size: 16px; |
| | | color: #333; |
| | | line-height: 36px; |
| | | margin-left: 15px; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | overflow: hidden; |
| | | } |
| | | .authorBox { |
| | | width: 80%; |
| | | display: flex; |
| | | padding: 20px; |
| | | padding-left: 100px; |
| | | position: relative; |
| | | } |
| | | .valueBox { |
| | | margin-left: 20px; |
| | | } |
| | | .valueBox div { |
| | | height: 30px; |
| | | } |
| | | .titleBox1 div { |
| | | height: 30px; |
| | | } |
| | | .relationBox { |
| | | position: absolute; |
| | | right: 50px; |
| | | color: #999; |
| | | cursor: pointer; |
| | | font-size: 14px; |
| | | } |
| | | .purchaseBox { |
| | | margin-left: 100px; |
| | | padding-top: 20px; |
| | | } |
| | | .priceBox { |
| | | border-bottom: 1px dashed #ececec; |
| | | background-color: #b2d9c8; |
| | | height: 50px; |
| | | line-height: 50px; |
| | | padding-left: 20px; |
| | | } |
| | | .priceBox span:nth-child(1) { |
| | | color: #000; |
| | | font-weight: 700; |
| | | font-size: 16px; |
| | | padding-right: 20px; |
| | | } |
| | | .priceBox span:nth-child(2) { |
| | | color: #e50021; |
| | | font-size: 16px; |
| | | } |
| | | .priceBox span:nth-child(3) { |
| | | color: #e50021; |
| | | font-size: 22px; |
| | | font-weight: 700; |
| | | padding-right: 20px; |
| | | } |
| | | .priceBox span:nth-child(4) { |
| | | color: #333; |
| | | font-size: 16px; |
| | | padding-right: 20px; |
| | | text-decoration: line-through; |
| | | } |
| | | .buyInfo { |
| | | padding: 20px 0px; |
| | | border-bottom: 1px dashed #ececec; |
| | | cursor: pointer; |
| | | } |
| | | .buyInfo img { |
| | | margin-left: 10px; |
| | | } |
| | | .btnBox { |
| | | margin-left: 100px; |
| | | margin-top: 30px; |
| | | } |
| | | .infoItem { |
| | | display: flex; |
| | | margin-top: 40px; |
| | | } |
| | | .infoImg { |
| | | width: 50px; |
| | | height: 50px; |
| | | border-radius: 50%; |
| | | border: 1px solid #ccc; |
| | | background: #efefef; |
| | | text-align: center; |
| | | line-height: 60px; |
| | | position: relative; |
| | | } |
| | | .infoImg i { |
| | | font-size: 28px; |
| | | } |
| | | .infoList { |
| | | margin-top: 20px; |
| | | overflow: auto; |
| | | } |
| | | .infoContent { |
| | | flex: 1; |
| | | overflow: hidden; |
| | | padding: 0 20px 0 10px; |
| | | } |
| | | .infoDialog { |
| | | padding: 20px; |
| | | } |
| | | .infoTitle { |
| | | width: 100%; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | } |
| | | .infoText { |
| | | margin-top: 24px; |
| | | line-height: 20px; |
| | | } |
| | | .contactBox { |
| | | padding: 0px 40px; |
| | | } |
| | | .contacItem { |
| | | margin-top: 20px; |
| | | } |
| | | .contacIcon { |
| | | padding-right: 20px; |
| | | } |
| | | .subBtn { |
| | | margin-top: 20px; |
| | | text-align: right; |
| | | } |
| | | .buyIcon { |
| | | width: 24px; |
| | | height: 24px; |
| | | vertical-align: middle; |
| | | } |
| | | .crumbs { |
| | | margin-top: 10px; |
| | | border-bottom: 1px solid rgba(20, 73, 65, 0.26); |
| | | padding-bottom: 20px; |
| | | } |
| | | |
| | | .detailContent { |
| | | margin-top: 30px; |
| | | .resourceBox { |
| | | width: 80%; |
| | | } |
| | | .textbookInfo { |
| | | padding: 20px 0; |
| | | } |
| | | } |
| | | .titleBorderBox { |
| | | height: 30px; |
| | | line-height: 30px; |
| | | font-weight: 700; |
| | | border-left: 6px solid #019e58; |
| | | padding-left: 20px; |
| | | font-size: 18px; |
| | | } |
| | | .textbookInfoItem { |
| | | margin-top: 20px; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="homePage"> |
| | | <div class="bannerBox imgBox"> |
| | | <img class="bannerImg" :src="banner[0]?.icon" @click="bannerLink(item)" /> |
| | | <div class="bannerText"> |
| | | <div>数字教材</div> |
| | | <div class="enText">ABOUT US</div> |
| | | </div> |
| | | </div> |
| | | <div class="contentBox" style="margin-top: 50px"> |
| | | <div class="imgBox"> |
| | | <img class="autoimg" src="@/assets/images/bookStore/feblei.png" /> |
| | | </div> |
| | | <div class="classificationBox"> |
| | | <div style="width: 100px">分类:</div> |
| | | <div class="classificaListBox"> |
| | | <div class="classificaItem" v-for="(item, index) in classfeild" :key="index"> |
| | | {{ item.name }} |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="bookList"> |
| | | <div class="bookfilterList"> |
| | | <div class="listTitle"> |
| | | <div>结果:共计***条</div> |
| | | <div style="width: 300px"> |
| | | <el-input |
| | | v-model="input3" |
| | | placeholder="输入教材名称、作者姓名、出品方名称搜索" |
| | | class="input-with-select" |
| | | > |
| | | <template #append> |
| | | <el-button :icon="Search" /> |
| | | </template> |
| | | </el-input> |
| | | </div> |
| | | </div> |
| | | |
| | | <div> |
| | | <div class="recommendList"> |
| | | <div |
| | | class="recommendItem" |
| | | v-for="item in bookListData" |
| | | :key="item.id" |
| | | @click="toDetail(item)" |
| | | > |
| | | <div class="recommendItemImg"> |
| | | <img class="autoImg" :src="item.icon" /> |
| | | </div> |
| | | <div class="infoBox"> |
| | | <div class="bookName">{{ item.name }}</div> |
| | | <div class="author"> |
| | | 作者:{{ item.authorcaupress_author ? item.caupress_author : '-' }} |
| | | </div> |
| | | <div class="priceBox"> |
| | | <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 v-if="!bookListData.length > 0"> |
| | | <el-empty class="noData" description="暂无数据" /> |
| | | </div> |
| | | |
| | | <div class="pagingBox"> |
| | | <el-pagination |
| | | layout="total, prev, pager, next" |
| | | :total="total" |
| | | v-model:current-page="currentPage1" |
| | | :page-size="20" |
| | | @current-change="handleCurrentChange" |
| | | hide-on-single-page="true" |
| | | /> |
| | | </div> |
| | | </div> |
| | | <div class="recommendBox"> |
| | | <div class="recommendTitle">推荐教材</div> |
| | | <div class="newRecommendList"> |
| | | <div class="recommendItem" v-for="item in bookListData" :key="item.id"> |
| | | <div class="recommendItemImg"> |
| | | <img class="autoImg" :src="item.icon" /> |
| | | </div> |
| | | <div class="infoBox"> |
| | | <div class="bookName">{{ item.name }}</div> |
| | | <div class="author"> |
| | | 作者:{{ item.authorcaupress_author ? item.caupress_author : '-' }} |
| | | </div> |
| | | <div class="priceBox"> |
| | | <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> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, onBeforeMount, inject, reactive, onMounted } from 'vue' |
| | | import { useRouter, useRoute } from 'vue-router' |
| | | |
| | | const MG = inject('MG') |
| | | const toolClass = inject('toolClass') |
| | | const banner = reactive([]) |
| | | const feildList = reactive([]) |
| | | const classfeild = reactive([]) |
| | | import { Search } from '@element-plus/icons-vue' |
| | | const input3 = ref('') |
| | | let bookListData = ref([]) |
| | | const total = ref(50) |
| | | const currentPage1 = ref(1) |
| | | const router = useRouter() |
| | | |
| | | const toDetail = (item) => { |
| | | router.push({ |
| | | path: '/bookdetail', |
| | | query: { |
| | | bookId: item.id, |
| | | }, |
| | | }) |
| | | } |
| | | |
| | | const getBanner = () => { |
| | | MG.resource |
| | | .getItem({ |
| | | path: 'banner\\educationPublishing', |
| | | fields: { link: [] }, |
| | | paging: { start: 0, size: 9 }, |
| | | }) |
| | | .then((res) => { |
| | | banner.push(...res.datas) |
| | | console.log(res.datas) |
| | | }) |
| | | } |
| | | |
| | | const handleCurrentChange = (val) => { |
| | | currentPage1.value = val |
| | | getBookList() |
| | | } |
| | | |
| | | const getBookList = () => { |
| | | MG.store |
| | | .getProductList({ |
| | | path: 'recommendedTextbooks', |
| | | paging: { |
| | | start: 0, |
| | | size: 5, |
| | | }, |
| | | fields: { |
| | | author: [], |
| | | }, |
| | | }) |
| | | .then((res) => { |
| | | console.log(res, '推荐教材') |
| | | bookListData.value = res.datas |
| | | }) |
| | | } |
| | | |
| | | const classifList = () => { |
| | | const query = { |
| | | refCodes: ['digitalTextbooks'], |
| | | } |
| | | MG.resource.getCmsTypeByRefCode(query).then((res) => { |
| | | console.log(res, 'res') |
| | | const types = toolClass.handleTypeList(res) |
| | | const typeData = types[0].cmsTypeLinks[0].children |
| | | feildList.push(...typeData) |
| | | const temp_classfeild = typeData.find((item) => item.typeField.refCode === 'teachingLevel') |
| | | ?.typeField.cfg.option |
| | | classfeild.push({ name: '全部', value: 'all' }, ...temp_classfeild) |
| | | console.log(typeData, 'typeData') |
| | | console.log(classfeild, 'classfeild') |
| | | }) |
| | | } |
| | | onMounted(() => { |
| | | getBanner() |
| | | classifList() |
| | | getBookList() |
| | | }) |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | .homePage { |
| | | min-width: 1220px; |
| | | min-height: calc(100vh - 61.8%); |
| | | background-color: #fff; |
| | | padding-bottom: 100px; |
| | | |
| | | .bannerBox { |
| | | height: 380px; |
| | | position: relative; |
| | | .bannerText { |
| | | position: absolute; |
| | | top: 50%; |
| | | left: 50%; |
| | | transform: translate(-50%, -50%); |
| | | font-size: 36px; |
| | | font-weight: 700; |
| | | color: #fff; |
| | | text-shadow: 0px 0px 10px #000000; |
| | | text-align: center; |
| | | } |
| | | .enText { |
| | | font-size: 36px; |
| | | opacity: 0.45; |
| | | margin-top: 20px; |
| | | } |
| | | } |
| | | |
| | | .classificationBox { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | margin-top: 30px; |
| | | .classificaListBox { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | .classificaItem { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | margin-right: 20px; |
| | | margin-bottom: 20px; |
| | | padding: 10px 16px; |
| | | width: 200px; |
| | | line-height: 20px; |
| | | background: #f5f5f5; |
| | | text-align: center; |
| | | } |
| | | } |
| | | } |
| | | .bookList { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | padding: 20px; |
| | | |
| | | .bookfilterList { |
| | | width: 80%; |
| | | border: 1px solid #e4e7ed; |
| | | height: 100%; |
| | | border-radius: 10px; |
| | | .listTitle { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 20px 30px; |
| | | } |
| | | } |
| | | .recommendBox { |
| | | width: 19%; |
| | | 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; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .recommendList { |
| | | display: flex; |
| | | padding: 20px; |
| | | padding-top: 0; |
| | | flex-wrap: wrap; |
| | | justify-content: start; |
| | | |
| | | .recommendItem { |
| | | margin-right: 20px; |
| | | width: 22%; |
| | | height: 300px; |
| | | background-repeat: no-repeat; |
| | | background-size: 100% 100%; |
| | | cursor: pointer; |
| | | border: 1px solid #dedede; |
| | | background-color: #fff; |
| | | padding-top: 10px; |
| | | margin-top: 10px; |
| | | &:last-child { |
| | | margin-right: 0; |
| | | } |
| | | } |
| | | .recommendItemImg { |
| | | width: 150px; |
| | | height: 200px; |
| | | position: relative; |
| | | margin: 0 auto; |
| | | } |
| | | .infoBox { |
| | | text-align: center; |
| | | margin-top: 10px; |
| | | } |
| | | .author { |
| | | margin-top: 10px; |
| | | } |
| | | .priceBox { |
| | | margin-top: 10px; |
| | | .oldPrice { |
| | | font-size: 16px; |
| | | color: #444444; |
| | | text-decoration: line-through; |
| | | margin-right: 20px; |
| | | } |
| | | .price { |
| | | span { |
| | | font-weight: bold; |
| | | font-size: 14px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .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; |
| | | } |
| | | .infoBox { |
| | | text-align: center; |
| | | margin-top: 10px; |
| | | } |
| | | .author { |
| | | margin-top: 10px; |
| | | } |
| | | .priceBox { |
| | | margin-top: 10px; |
| | | .oldPrice { |
| | | font-size: 16px; |
| | | color: #444444; |
| | | text-decoration: line-through; |
| | | margin-right: 20px; |
| | | } |
| | | .price { |
| | | span { |
| | | font-weight: bold; |
| | | font-size: 14px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .pagingBox { |
| | | display: flex; |
| | | justify-content: center; |
| | | margin: 20px 0; |
| | | padding-bottom: 30px; |
| | | } |
| | | </style> |
| | |
| | | const Sloading = ref(false) |
| | | |
| | | onMounted(() => { |
| | | const userCache: any = localStorage.getItem('jesk-userInfo') |
| | | const userCache: any = localStorage.getItem(config.userInfoKey) |
| | | if (userCache) { |
| | | userInfo.value = JSON.parse(userCache) |
| | | } |
| | |
| | | <WarningFilled /> |
| | | </el-icon> |
| | | <p> |
| | | 如果您已使用【京师智教扫一扫】或【云上书房】 微信注册过,请使用微信扫码登录;如果您已在【 |
| | | 如果您已使用【京师智教扫一扫】或【云上书房】 |
| | | 微信注册过,请使用微信扫码登录;如果您已在【 |
| | | 京师智教】PC端注册过,请使用手机号登录!继续注册将创建全新账户! |
| | | </p> |
| | | <template #footer> |
| | |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import login from '@/layout/components/login.vue' |
| | | // import login from '@/layout/components/login.vue' |
| | | import { onMounted, ref, watchEffect, inject, watch } from 'vue' |
| | | import { ElMessage, ElMessageBox, type FormInstance } from 'element-plus' |
| | | import logo from '@/assets/images/header/logo.png' |
| | | import titleName from '@/assets/images/header/titleName.png' |
| | | // import logo from '@/assets/images/header/logo.png' |
| | | // import titleName from '@/assets/images/header/titleName.png' |
| | | import { useRouter } from 'vue-router' |
| | | import { useUserStore, applyBookStore } from '@/store' |
| | | const loginRef = ref() |
| | |
| | | const userStore = useUserStore() |
| | | const applyBook = applyBookStore() |
| | | const MG = inject('MG') |
| | | const config = inject('config') |
| | | const config:any = inject('config') |
| | | const tipsDialogState = ref<boolean>(false) // 温馨提示弹窗状态 |
| | | const wechatTipsState = ref<boolean>(false) |
| | | const localData = ref(localStorage.getItem('jsek-token')) |
| | | const localData = ref(localStorage.getItem(config.tokenKey)) |
| | | onMounted(() => { |
| | | // 判断是否微信扫码登录 |
| | | var url = window.location.href |
| | |
| | | } |
| | | }) |
| | | watchEffect(() => { |
| | | localData.value = localStorage.getItem('jsek-token') || '0' |
| | | localData.value = localStorage.getItem(config.tokenKey) || '0' |
| | | }) |
| | | |
| | | // 注册按钮 |
| | |
| | | const goHome = () => { |
| | | router.push('/home') |
| | | } |
| | | |
| | | </script> |
| | | |
| | | <style lang="less"> |
| | |
| | | font-size: 24px; |
| | | padding: 0 10px; |
| | | margin-left: 15px; |
| | | border-left: 1px solid #C0C0C0; |
| | | border-left: 1px solid #c0c0c0; |
| | | color:#181818; |
| | | font-family: Microsoft YaHei, Microsoft YaHei; |
| | | font-weight: 400; |
| | |
| | | > |
| | | <span |
| | | :style="{ |
| | | fill: activeIndex == index ? '#fff' : '#000' |
| | | fill: activeIndex == index ? '#fff' : '#000', |
| | | }" |
| | | v-html="item.icon" |
| | | > |
| | |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { ref, watch, provide, onMounted, inject } from 'vue' |
| | | import { useRoute, useRouter, onBeforeRouteUpdate } from 'vue-router' |
| | | import Header from './components/headerPage.vue' |
| | | import { menu } from './config' |
| | | import { getPublicImage } from '@/assets/js/middleGround/tool.js' |
| | | import defaultImg from '@/assets/images/default-book-img.png' |
| | | import { ref, watch, provide, onMounted, inject } from "vue"; |
| | | import { useRoute, useRouter, onBeforeRouteUpdate } from "vue-router"; |
| | | import Header from "./components/headerPage.vue"; |
| | | import { menu } from "./config"; |
| | | import { getPublicImage } from "@/assets/js/middleGround/tool.js"; |
| | | import defaultImg from "@/assets/images/default-book-img.png"; |
| | | |
| | | const router: any = useRouter() |
| | | const route: any = useRoute() |
| | | const MG: any = inject('MG') |
| | | const config: any = inject('config') |
| | | const routerVal = router.currentRoute.value |
| | | const path = ref(routerVal.path) |
| | | const label = ref('') |
| | | const classInfo: any = ref() |
| | | const classIcon: any = ref() |
| | | const listMenu = ref([]) |
| | | const activeIndex = ref(0) |
| | | const userData = ref() |
| | | const router: any = useRouter(); |
| | | const route: any = useRoute(); |
| | | const MG: any = inject("MG"); |
| | | const config: any = inject("config"); |
| | | const routerVal = router.currentRoute.value; |
| | | const path = ref(routerVal.path); |
| | | const label = ref(""); |
| | | const classInfo: any = ref(); |
| | | const classIcon: any = ref(); |
| | | const listMenu = ref([]); |
| | | const activeIndex = ref(0); |
| | | const userData = ref(); |
| | | |
| | | watch(router.currentRoute, (val) => { |
| | | path.value = val.path |
| | | path.value = val.path; |
| | | if (val.query.classInfo) { |
| | | const data: any = val.query.classInfo |
| | | const routerInfo: any = JSON.parse(data) |
| | | activeIndex.value = routerInfo.index |
| | | const data: any = val.query.classInfo; |
| | | const routerInfo: any = JSON.parse(data); |
| | | activeIndex.value = routerInfo.index; |
| | | } |
| | | }) |
| | | }); |
| | | |
| | | watch(classInfo, (val) => { |
| | | if (val) { |
| | | activeIndex.value = val.index |
| | | activeIndex.value = val.index; |
| | | } |
| | | if (!val.index) { |
| | | activeIndex.value = 0 |
| | | activeIndex.value = 0; |
| | | } |
| | | }) |
| | | }); |
| | | |
| | | onBeforeRouteUpdate(async (to, from) => { |
| | | path.value = to.path |
| | | }) |
| | | path.value = to.path; |
| | | }); |
| | | |
| | | onMounted(() => { |
| | | classInfo.value = JSON.parse(route.query.classInfo) |
| | | classIcon.value = classInfo.value.icon ? getPublicImage(classInfo.value.icon, 200) : defaultImg |
| | | classInfo.value = JSON.parse(route.query.classInfo); |
| | | classIcon.value = classInfo.value.icon |
| | | ? getPublicImage(classInfo.value.icon, 200) |
| | | : defaultImg; |
| | | menu.forEach((item) => { |
| | | if ('/' + item.path === path.value) { |
| | | label.value = item.label |
| | | if ("/" + item.path === path.value) { |
| | | label.value = item.label; |
| | | } |
| | | }) |
| | | const userCache: any = localStorage.getItem('jesk-userInfo') |
| | | const userInfo = JSON.parse(userCache) |
| | | userData.value = userInfo |
| | | }); |
| | | const userCache: any = localStorage.getItem(config.userInfoKey); |
| | | const userInfo = JSON.parse(userCache); |
| | | userData.value = userInfo; |
| | | if (!userInfo) { |
| | | router.push({ |
| | | path: '/' |
| | | }) |
| | | return false |
| | | path: "/", |
| | | }); |
| | | return false; |
| | | } |
| | | if (userInfo.role != 'Teacher') { |
| | | if (userInfo.role != "Teacher") { |
| | | const data: any = menu.filter( |
| | | (item: any) => item.path != 'studentManage' && item.path != 'jobAnalysis' |
| | | ) |
| | | listMenu.value = data |
| | | (item: any) => item.path != "studentManage" && item.path != "jobAnalysis" |
| | | ); |
| | | listMenu.value = data; |
| | | } else { |
| | | const data: any = menu |
| | | const data: any = menu; |
| | | // if (!classInfo.bookRefCode) { |
| | | // // 融媒体图书,无数字阅读,无法跳转 |
| | | // const list: any = menu.filter((item: any) => item.path != 'teachingPlan') |
| | | // listMenu.value = list; |
| | | // return false |
| | | // } |
| | | listMenu.value = data |
| | | listMenu.value = data; |
| | | } |
| | | }) |
| | | }); |
| | | |
| | | const goRouter = (item: any, index: number) => { |
| | | activeIndex.value = index |
| | | if (!localStorage.getItem('jsek-token') || localStorage.getItem('jsek-token') == null) { |
| | | activeIndex.value = index; |
| | | if ( |
| | | !localStorage.getItem(config.tokenKey) || |
| | | localStorage.getItem(config.tokenKey) == null |
| | | ) { |
| | | router.push({ |
| | | path: '/home', |
| | | path: "/home", |
| | | query: { |
| | | showLogin: '1' |
| | | } |
| | | }) |
| | | showLogin: "1", |
| | | }, |
| | | }); |
| | | } else { |
| | | label.value = item.label |
| | | classInfo.value.index = index |
| | | label.value = item.label; |
| | | classInfo.value.index = index; |
| | | if (item.key == 5) { |
| | | router.push({ |
| | | path: userData.value.role != 'Teacher' ? '/studentJob' : '/jobManage', |
| | | path: userData.value.role != "Teacher" ? "/studentJob" : "/jobManage", |
| | | query: { |
| | | classInfo: JSON.stringify(classInfo.value) |
| | | } |
| | | }) |
| | | classInfo: JSON.stringify(classInfo.value), |
| | | }, |
| | | }); |
| | | } else { |
| | | router.push({ |
| | | path: item.path, |
| | | query: { |
| | | classInfo: JSON.stringify(classInfo.value) |
| | | } |
| | | }) |
| | | classInfo: JSON.stringify(classInfo.value), |
| | | }, |
| | | }); |
| | | } |
| | | } |
| | | } |
| | | }; |
| | | |
| | | const goBack = () => { |
| | | router.go(-1) |
| | | } |
| | | router.go(-1); |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | |
| | | const pubValue = ref(null) |
| | | |
| | | onMounted(() => { |
| | | const userCache: any = localStorage.getItem('jesk-userInfo') |
| | | const userCache: any = localStorage.getItem(config.userInfoKey) |
| | | if (userCache) { |
| | | userInfo.value = JSON.parse(userCache) |
| | | } |
| | |
| | | const tableData: any = ref([]) |
| | | |
| | | onMounted(() => { |
| | | const userCache: any = localStorage.getItem('jesk-userInfo') |
| | | const userCache: any = localStorage.getItem(config.userInfoKey) |
| | | if (userCache) { |
| | | userInfo.value = JSON.parse(userCache) |
| | | } |
| | |
| | | const childLoading = ref(false) |
| | | |
| | | onMounted(() => { |
| | | const userCache: any = localStorage.getItem('jesk-userInfo') |
| | | const userCache: any = localStorage.getItem(config.userInfoKey) |
| | | if (userCache) { |
| | | userInfo.value = JSON.parse(userCache) |
| | | } |
| | |
| | | } |
| | | |
| | | const submitText = (val: string) => { |
| | | const userCache: any = localStorage.getItem('jesk-userInfo') |
| | | const userCache: any = localStorage.getItem(config.userInfoKey) |
| | | const userInfo = JSON.parse(userCache) |
| | | if (userInfo?.data) { |
| | | const iconData = JSON.parse(userInfo.data) |
| | |
| | | }) |
| | | |
| | | onMounted(() => { |
| | | const userCache: any = localStorage.getItem('jesk-userInfo') |
| | | const userCache: any = localStorage.getItem(config.userInfoKey) |
| | | if (userCache) { |
| | | userInfo.value = JSON.parse(userCache) |
| | | } |
| | |
| | | } |
| | | |
| | | const newTalkMessage = () => { |
| | | const userCache: any = localStorage.getItem('jesk-userInfo') |
| | | const userCache: any = localStorage.getItem(config.userInfoKey) |
| | | const userInfo = JSON.parse(userCache) |
| | | const textObj = { |
| | | content: talkContent.value, |
| | |
| | | const defaultCmsPath = ref('') |
| | | |
| | | onMounted(() => { |
| | | const userCache: any = localStorage.getItem('jesk-userInfo') |
| | | const userCache: any = localStorage.getItem(config.userInfoKey) |
| | | if (userCache) { |
| | | userInfo.value = JSON.parse(userCache) |
| | | } |
| | |
| | | <div class="titleBox"> |
| | | <div class="titleOptions"> |
| | | <span>教学计划</span> |
| | | <el-button v-if="userInfo?.role == 'Teacher'" @click="openPlan()" type="primary" round |
| | | <el-button |
| | | v-if="userInfo?.role == 'Teacher'" |
| | | @click="openPlan()" |
| | | type="primary" |
| | | round |
| | | >新建 <el-icon style="margin-left: 3px"><Plus /></el-icon |
| | | ></el-button> |
| | | </div> |
| | |
| | | @keydown.enter="searchData()" |
| | | > |
| | | <template #append> |
| | | <el-button type="primary" @click="searchData()" class="searchBtn" :icon="Search" /> |
| | | <el-button |
| | | type="primary" |
| | | @click="searchData()" |
| | | class="searchBtn" |
| | | :icon="Search" |
| | | /> |
| | | </template> |
| | | </el-input> |
| | | </div> |
| | |
| | | v-for="(item, index) in scope.row.datas.uploadResources" |
| | | :key="index" |
| | | > |
| | | {{ item.FileName + '.' + item.Extension }} |
| | | {{ item.FileName + "." + item.Extension }} |
| | | </span> |
| | | </div> |
| | | </template> |
| | |
| | | </el-col> |
| | | <el-col :span="20"> |
| | | <div class="grid-content ep-bg-purple-light" /> |
| | | <el-input v-model="taskItem.title" placeholder="请填写名称" size="large" clearable /> |
| | | <el-input |
| | | v-model="taskItem.title" |
| | | placeholder="请填写名称" |
| | | size="large" |
| | | clearable |
| | | /> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | |
| | | </el-cascader> |
| | | </div> |
| | | <div class="btngroup"> |
| | | <el-button type="primary" @click="addGroup" style="height: 40px" :icon="Plus" /> |
| | | <el-button |
| | | type="primary" |
| | | @click="addGroup" |
| | | style="height: 40px" |
| | | :icon="Plus" |
| | | /> |
| | | <el-button |
| | | type="warning" |
| | | :disabled="dynamicList.length == 1" |
| | |
| | | ></el-input> |
| | | </div> |
| | | <div class="btngroup"> |
| | | <el-button type="primary" @click="addGroup" style="height: 40px" :icon="Plus" /> |
| | | <el-button |
| | | type="primary" |
| | | @click="addGroup" |
| | | style="height: 40px" |
| | | :icon="Plus" |
| | | /> |
| | | <el-button |
| | | type="warning" |
| | | :disabled="dynamicList.length == 1" |
| | |
| | | >上传</el-button |
| | | > |
| | | </el-upload> --> |
| | | <el-upload class="upload" drag action="#" multiple :http-request="fileUpload"> |
| | | <el-upload |
| | | class="upload" |
| | | drag |
| | | action="#" |
| | | multiple |
| | | :http-request="fileUpload" |
| | | > |
| | | <el-icon class="el-icon--upload"><upload-filled /></el-icon> |
| | | <div class="el-upload__text">拖拽或点击文件上传</div> |
| | | </el-upload> |
| | |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { Search, ArrowRight, Plus, Minus } from '@element-plus/icons-vue' |
| | | import { ElMessage } from 'element-plus' |
| | | import { reactive, ref, onMounted, inject, watch } from 'vue' |
| | | import { useRoute } from 'vue-router' |
| | | import axios from 'axios' |
| | | import { Search, ArrowRight, Plus, Minus } from "@element-plus/icons-vue"; |
| | | import { ElMessage } from "element-plus"; |
| | | import { reactive, ref, onMounted, inject, watch } from "vue"; |
| | | import { useRoute } from "vue-router"; |
| | | import axios from "axios"; |
| | | |
| | | const route: any = useRoute() |
| | | const MG: any = inject('MG') |
| | | const config: any = inject('config') |
| | | const tool: any = inject('toolClass') |
| | | const classInfo = JSON.parse(route.query.classInfo) |
| | | const userInfo = ref() |
| | | const searchKey = ref('') |
| | | const visible = ref(false) |
| | | const dynamicList: any = ref([]) |
| | | const tableData: any = ref([]) |
| | | const classItem = ref([]) |
| | | const fileList: any = ref([]) |
| | | const chapterList: any = ref([]) |
| | | const childrenList: any = ref([]) |
| | | const taskData: any = ref() |
| | | const route: any = useRoute(); |
| | | const MG: any = inject("MG"); |
| | | const config: any = inject("config"); |
| | | const tool: any = inject("toolClass"); |
| | | const classInfo = JSON.parse(route.query.classInfo); |
| | | const userInfo = ref(); |
| | | const searchKey = ref(""); |
| | | const visible = ref(false); |
| | | const dynamicList: any = ref([]); |
| | | const tableData: any = ref([]); |
| | | const classItem = ref([]); |
| | | const fileList: any = ref([]); |
| | | const chapterList: any = ref([]); |
| | | const childrenList: any = ref([]); |
| | | const taskData: any = ref(); |
| | | // 新建教学计划防抖 |
| | | const newLoading = ref(false) |
| | | const teachPlanvalue = ref('') |
| | | const newLoading = ref(false); |
| | | const teachPlanvalue = ref(""); |
| | | const taskItem = reactive({ |
| | | title: '', |
| | | selectChapter: '', |
| | | referenceMaterial: '', |
| | | explain: '', |
| | | uploadResources: '' |
| | | }) |
| | | title: "", |
| | | selectChapter: "", |
| | | referenceMaterial: "", |
| | | explain: "", |
| | | uploadResources: "", |
| | | }); |
| | | let pages = reactive({ |
| | | page: 1, |
| | | pageSize: 13, |
| | | count: 0, |
| | | loading: false |
| | | }) |
| | | loading: false, |
| | | }); |
| | | |
| | | onMounted(() => { |
| | | const list = [{ key: 1, parentVal: '', childVal: '' }] |
| | | dynamicList.value = list |
| | | const userCache: any = localStorage.getItem('jesk-userInfo') |
| | | const list = [{ key: 1, parentVal: "", childVal: "" }]; |
| | | dynamicList.value = list; |
| | | const userCache: any = localStorage.getItem(config.userInfoKey); |
| | | if (userCache) { |
| | | userInfo.value = JSON.parse(userCache) |
| | | userInfo.value = JSON.parse(userCache); |
| | | } |
| | | pages.loading = true |
| | | getTaskList() |
| | | }) |
| | | pages.loading = true; |
| | | getTaskList(); |
| | | }); |
| | | |
| | | const searchData = () => { |
| | | pages.page = 1 |
| | | getTaskCmsList() |
| | | } |
| | | pages.page = 1; |
| | | getTaskCmsList(); |
| | | }; |
| | | |
| | | const openPlan = () => { |
| | | visible.value = true |
| | | taskItem.title = '' |
| | | taskItem.selectChapter = '' |
| | | taskItem.referenceMaterial = '' |
| | | taskItem.explain = '' |
| | | taskItem.uploadResources = '' |
| | | dynamicList.value = [{ key: 1, parentVal: '', childVal: '' }] |
| | | fileList.value = [] |
| | | } |
| | | visible.value = true; |
| | | taskItem.title = ""; |
| | | taskItem.selectChapter = ""; |
| | | taskItem.referenceMaterial = ""; |
| | | taskItem.explain = ""; |
| | | taskItem.uploadResources = ""; |
| | | dynamicList.value = [{ key: 1, parentVal: "", childVal: "" }]; |
| | | fileList.value = []; |
| | | }; |
| | | |
| | | const reduceGroup = () => { |
| | | dynamicList.value.pop() |
| | | } |
| | | dynamicList.value.pop(); |
| | | }; |
| | | |
| | | const addGroup = () => { |
| | | const source = dynamicList.value[dynamicList.value.length - 1] |
| | | const obj = { key: source.key++, parentVal: '', childVal: '' } |
| | | dynamicList.value.push(obj) |
| | | } |
| | | const source = dynamicList.value[dynamicList.value.length - 1]; |
| | | const obj = { key: source.key++, parentVal: "", childVal: "" }; |
| | | dynamicList.value.push(obj); |
| | | }; |
| | | |
| | | const handleSizeChange = (val: number) => { |
| | | pages.pageSize = val |
| | | getTaskCmsList() |
| | | } |
| | | pages.pageSize = val; |
| | | getTaskCmsList(); |
| | | }; |
| | | |
| | | const handleCurrentChange = (val: number) => { |
| | | pages.page = val |
| | | getTaskCmsList() |
| | | } |
| | | pages.page = val; |
| | | getTaskCmsList(); |
| | | }; |
| | | |
| | | // 新建任务 |
| | | const newTask = () => { |
| | | const data = { |
| | | name: classInfo?.name + '教学计划', |
| | | description: '', |
| | | icon: '', |
| | | name: classInfo?.name + "教学计划", |
| | | description: "", |
| | | icon: "", |
| | | type: config.taskType.teachingPlan, |
| | | state: 'Normal', |
| | | state: "Normal", |
| | | groupId: classInfo?.id, |
| | | order: 0, |
| | | beginDate: '2024-09-09T03:38:07.167Z', |
| | | endDate: '2024-09-09T03:38:07.167Z', |
| | | duration: 0 |
| | | } |
| | | beginDate: "2024-09-09T03:38:07.167Z", |
| | | endDate: "2024-09-09T03:38:07.167Z", |
| | | duration: 0, |
| | | }; |
| | | MG.edu |
| | | .newTask(data) |
| | | .then((res: any) => {}) |
| | | .catch((e: any) => { |
| | | console.log(e) |
| | | }) |
| | | } |
| | | console.log(e); |
| | | }); |
| | | }; |
| | | |
| | | // 获取任务列表 |
| | | const getTaskList = () => { |
| | |
| | | filterList: [ |
| | | { |
| | | value: config.taskType.teachingPlan, |
| | | field: 'Type', |
| | | subFilters: [] |
| | | } |
| | | field: "Type", |
| | | subFilters: [], |
| | | }, |
| | | ], |
| | | searchList: [], |
| | | groupId: classInfo?.id |
| | | } |
| | | groupId: classInfo?.id, |
| | | }; |
| | | MG.edu |
| | | .getTaskList(data) |
| | | .then((res: any) => { |
| | | if (res.datas.length == 0 && userInfo.value.role == 'Teacher') { |
| | | newTask() |
| | | if (res.datas.length == 0 && userInfo.value.role == "Teacher") { |
| | | newTask(); |
| | | } |
| | | if (res.datas.length > 0) { |
| | | taskData.value = res.datas[0] |
| | | classInfo.taskId = taskData.value?.id |
| | | classInfo.rootTaskCmsId = taskData.value?.rootCmsItemId |
| | | taskData.value = res.datas[0]; |
| | | classInfo.taskId = taskData.value?.id; |
| | | classInfo.rootTaskCmsId = taskData.value?.rootCmsItemId; |
| | | } |
| | | getTypeByCode() |
| | | getTypeByCode(); |
| | | if (classInfo.bookRefCode) { |
| | | getCatalogueList() |
| | | getCatalogueList(); |
| | | } |
| | | }) |
| | | .catch((e: any) => { |
| | | console.log(e) |
| | | }) |
| | | } |
| | | console.log(e); |
| | | }); |
| | | }; |
| | | |
| | | // 前往阅读器 |
| | | const toRead = (item: any) => { |
| | |
| | | if (classInfo.bookRefCode) { |
| | | const url = |
| | | config.textReaderUrl + |
| | | '?bookId=' + |
| | | "?bookId=" + |
| | | classInfo?.bookRefCode + |
| | | '&token=' + |
| | | localStorage.getItem('jsek-token') + |
| | | '&chapter=' + |
| | | "&token=" + |
| | | localStorage.getItem(config.tokenKey) + |
| | | "&chapter=" + |
| | | item.parentVal + |
| | | '&startPage=' + |
| | | item.childVal |
| | | window.open(url, '_blank') |
| | | "&startPage=" + |
| | | item.childVal; |
| | | window.open(url, "_blank"); |
| | | } else { |
| | | ElMessage.warning('当前章节无法跳转') |
| | | ElMessage.warning("当前章节无法跳转"); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | // 下载上传资源 |
| | | const downloadRes = (item: any) => { |
| | | const url = config.requestCtx + '/file/api/ApiDownload?md5=' + item.Md5 |
| | | window.open(url, '_blank') |
| | | } |
| | | const url = config.requestCtx + "/file/api/ApiDownload?md5=" + item.Md5; |
| | | window.open(url, "_blank"); |
| | | }; |
| | | |
| | | // 选择器 |
| | | const parentSelect = (val: any, item: any) => { |
| | | if (val?.length) { |
| | | const str = val[2] |
| | | const obj = findObj(chapterList.value, str) |
| | | item.parentVal = obj.chapter |
| | | item.childVal = obj.start |
| | | const str = val[2]; |
| | | const obj = findObj(chapterList.value, str); |
| | | item.parentVal = obj.chapter; |
| | | item.childVal = obj.start; |
| | | } |
| | | } |
| | | }; |
| | | |
| | | // 文件上传 |
| | | const fileUpload = (file: any) => { |
| | |
| | | // ElMessage.error('上传文件大小不能超过 300KB!') |
| | | // return reject() |
| | | // } |
| | | const FileName = file.file.name.split('.')[0] |
| | | const Extension = file.file.name.split('.')[1] |
| | | const FileType = file.file.type |
| | | let size = 1024 |
| | | const FileName = file.file.name.split(".")[0]; |
| | | const Extension = file.file.name.split(".")[1]; |
| | | const FileType = file.file.type; |
| | | let size = 1024; |
| | | tool |
| | | .getFileMd5(file.file, size * 1024) |
| | | .then((e: string) => { |
| | | if (!fileList.value.find((item: any) => item.md5 == e)) { |
| | | const imgData = new FormData() |
| | | imgData.append('Md5', e) |
| | | imgData.append('FileName', FileName) |
| | | imgData.append('Extension', Extension) |
| | | imgData.append('FileType', FileType) |
| | | imgData.append('MetaData', null) |
| | | imgData.append('file', file.file) |
| | | const imgData = new FormData(); |
| | | imgData.append("Md5", e); |
| | | imgData.append("FileName", FileName); |
| | | imgData.append("Extension", Extension); |
| | | imgData.append("FileType", FileType); |
| | | imgData.append("MetaData", null); |
| | | imgData.append("file", file.file); |
| | | MG.file.upload(imgData).then(() => { |
| | | fileList.value.push({ |
| | | md5: e, |
| | | linkType: 'LinkFile', |
| | | linkProtectType: 'Public', |
| | | linkType: "LinkFile", |
| | | linkProtectType: "Public", |
| | | fileName: FileName, |
| | | extension: Extension, |
| | | url: config.requestCtx + `/file/api/ApiDownload?md5=` + e |
| | | }) |
| | | }) |
| | | url: config.requestCtx + `/file/api/ApiDownload?md5=` + e, |
| | | }); |
| | | }); |
| | | } else { |
| | | ElMessage.warning('当前文件已上传,请勿重复操作!') |
| | | ElMessage.warning("当前文件已上传,请勿重复操作!"); |
| | | } |
| | | }) |
| | | .catch((e: any) => { |
| | | console.error(e) |
| | | }) |
| | | }) |
| | | } |
| | | console.error(e); |
| | | }); |
| | | }); |
| | | }; |
| | | |
| | | // 获取章节目录 |
| | | const getCatalogueList = () => { |
| | | const url = config.requestCtx + '/books/resource/' + classInfo?.bookRefCode + '/information.json' |
| | | const url = |
| | | config.requestCtx + "/books/resource/" + classInfo?.bookRefCode + "/information.json"; |
| | | axios |
| | | .get(url) |
| | | .then((res) => { |
| | | if (res.data?.data.length > 0) { |
| | | const datas = res.data.data |
| | | const list = datas?.filter((item: any) => item.children?.length > 0) |
| | | chapterList.value = changeCascaderData(list) |
| | | const datas = res.data.data; |
| | | const list = datas?.filter((item: any) => item.children?.length > 0); |
| | | chapterList.value = changeCascaderData(list); |
| | | } |
| | | }) |
| | | .catch((e) => { |
| | | console.log(e) |
| | | }) |
| | | } |
| | | console.log(e); |
| | | }); |
| | | }; |
| | | |
| | | // 递归更数组 |
| | | const changeCascaderData = (data: any) => { |
| | | for (const item of data) { |
| | | item.value = item.start |
| | | item.value = item.start; |
| | | if (item.children?.length > 0) { |
| | | changeCascaderData(item.children) |
| | | changeCascaderData(item.children); |
| | | } |
| | | } |
| | | return data |
| | | } |
| | | return data; |
| | | }; |
| | | |
| | | // 递归查找 |
| | | const findObj = (arr: any, val: any) => { |
| | | for (let i = 0; i < arr.length; i++) { |
| | | const obj = arr[i] |
| | | const obj = arr[i]; |
| | | if (obj.start === val) { |
| | | return obj // 找到目标对象,直接返回 |
| | | return obj; // 找到目标对象,直接返回 |
| | | } |
| | | if (obj.children && obj.children.length > 0) { |
| | | // 如果当前对象有子对象,递归查找子对象 |
| | | const found: any = findObj(obj.children, val) |
| | | const found: any = findObj(obj.children, val); |
| | | if (found) { |
| | | return found // 在子对象中找到目标对象,返回 |
| | | return found; // 在子对象中找到目标对象,返回 |
| | | } |
| | | } |
| | | } |
| | | return null |
| | | } |
| | | return null; |
| | | }; |
| | | |
| | | // 获取类型字段 |
| | | const getTypeByCode = () => { |
| | | MG.resource |
| | | .getCmsTypeByRefCode({ |
| | | refCodes: [config.refCodes.teachingPlan] |
| | | refCodes: [config.refCodes.teachingPlan], |
| | | }) |
| | | .then((res: any) => { |
| | | const data = res[0]?.cmsTypeLinks[0]?.children |
| | | const data = res[0]?.cmsTypeLinks[0]?.children; |
| | | if (data?.length) { |
| | | classItem.value = data |
| | | classItem.value = data; |
| | | } |
| | | getTaskCmsList() |
| | | getTaskCmsList(); |
| | | }) |
| | | .catch((err: any) => { |
| | | console.log(err) |
| | | }) |
| | | } |
| | | console.log(err); |
| | | }); |
| | | }; |
| | | |
| | | // 获取任务下的资源列表 |
| | | const getTaskCmsList = () => { |
| | |
| | | ? [ |
| | | { |
| | | keywords: searchKey.value, |
| | | field: 'Name', |
| | | compareType: 'Contains' |
| | | } |
| | | field: "Name", |
| | | compareType: "Contains", |
| | | }, |
| | | ] |
| | | : [], |
| | | taskId: classInfo?.taskId, |
| | | path: String(classInfo?.rootTaskCmsId), |
| | | type: '*', |
| | | keys: ['referenceMaterial', 'Name', 'selectChapter', 'uploadResources', 'explain'] |
| | | } |
| | | type: "*", |
| | | keys: ["referenceMaterial", "Name", "selectChapter", "uploadResources", "explain"], |
| | | }; |
| | | MG.edu |
| | | .getTaskCmsItem(data) |
| | | .then((res: any) => { |
| | | pages.loading = false |
| | | pages.count = res.totalSize |
| | | pages.loading = false; |
| | | pages.count = res.totalSize; |
| | | for (let i = 0; i < res.datas.length; i++) { |
| | | const item = res.datas[i] |
| | | const item = res.datas[i]; |
| | | // 处理字段 |
| | | if (taskItem != null) { |
| | | for (let fieldKey in taskItem) { |
| | | if (item.datas[fieldKey]) { |
| | | const values = JSON.parse(item.datas[fieldKey]) |
| | | const values = JSON.parse(item.datas[fieldKey]); |
| | | if (values.length > 0) { |
| | | // 用字段名处理返回的字段值 |
| | | if (values[0].Value) { |
| | | item.datas[fieldKey] = values[0].Value |
| | | item.datas[fieldKey] = values[0].Value; |
| | | } else if (values[0].Data) { |
| | | item.datas[fieldKey] = values[0].Data.Value |
| | | item.datas[fieldKey] = values[0].Data.Value; |
| | | } else if (!values[0].Value && values[0].FileList?.length > 0) { |
| | | item.datas[fieldKey] = values[0].FileList |
| | | item.datas[fieldKey] = values[0].FileList; |
| | | } else { |
| | | item.datas[fieldKey] = '-' |
| | | item.datas[fieldKey] = "-"; |
| | | } |
| | | if (fieldKey == 'selectChapter' && values[0].Value) { |
| | | const data = JSON.parse(values[0].Value) |
| | | item.datas['selectChapter'] = data.map((citem: any) => { |
| | | if (fieldKey == "selectChapter" && values[0].Value) { |
| | | const data = JSON.parse(values[0].Value); |
| | | item.datas["selectChapter"] = data.map((citem: any) => { |
| | | if (classInfo.bookRefCode) { |
| | | const dataS = findObj(chapterList.value, citem.childVal) |
| | | const dataS = findObj(chapterList.value, citem.childVal); |
| | | return { |
| | | ...citem, |
| | | parentName: |
| | | chapterList.value.find((sitem: any) => sitem.chapter == citem.parentVal) |
| | | ?.label + |
| | | '---' + |
| | | dataS?.label |
| | | } |
| | | chapterList.value.find( |
| | | (sitem: any) => sitem.chapter == citem.parentVal |
| | | )?.label + |
| | | "---" + |
| | | dataS?.label, |
| | | }; |
| | | } else { |
| | | return { |
| | | ...citem, |
| | | parentName: citem.parentVal + '---' + citem.childVal |
| | | parentName: citem.parentVal + "---" + citem.childVal, |
| | | }; |
| | | } |
| | | }); |
| | | } |
| | | if (fieldKey == "selectChapter" && !values[0].Value) { |
| | | item.datas["selectChapter"] = []; |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | if (fieldKey == 'selectChapter' && !values[0].Value) { |
| | | item.datas['selectChapter'] = [] |
| | | } |
| | | } |
| | | const index = i |
| | | item.datas['index'] = index + 1 |
| | | const index = i; |
| | | item.datas["index"] = index + 1; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | tableData.value = res.datas |
| | | tableData.value = res.datas; |
| | | }) |
| | | .catch((e: any) => { |
| | | ElMessage({ |
| | | message: '列表获取失败', |
| | | type: 'error' |
| | | }) |
| | | console.log(e) |
| | | }) |
| | | } |
| | | message: "列表获取失败", |
| | | type: "error", |
| | | }); |
| | | console.log(e); |
| | | }); |
| | | }; |
| | | |
| | | // 删除资源 |
| | | const removeTaskItem = (item: any) => { |
| | |
| | | requests: [ |
| | | { |
| | | cmsItemId: item.id, |
| | | path: String(classInfo?.rootTaskCmsId) |
| | | } |
| | | ] |
| | | } |
| | | path: String(classInfo?.rootTaskCmsId), |
| | | }, |
| | | ], |
| | | }; |
| | | MG.edu |
| | | .removeTaskCmsItemList(data) |
| | | .then((res: any) => { |
| | | if (res) { |
| | | ElMessage({ |
| | | message: '删除成功', |
| | | type: 'success' |
| | | }) |
| | | getTaskCmsList() |
| | | message: "删除成功", |
| | | type: "success", |
| | | }); |
| | | getTaskCmsList(); |
| | | } |
| | | }) |
| | | .catch((e: any) => { |
| | | ElMessage({ |
| | | message: '删除失败', |
| | | type: 'error' |
| | | }) |
| | | }) |
| | | } |
| | | message: "删除失败", |
| | | type: "error", |
| | | }); |
| | | }); |
| | | }; |
| | | |
| | | // 为任务新建资源 |
| | | const newTaskCmsItems = () => { |
| | | newLoading.value = true |
| | | taskItem.selectChapter = JSON.stringify(dynamicList.value) |
| | | newLoading.value = true; |
| | | taskItem.selectChapter = JSON.stringify(dynamicList.value); |
| | | if (!taskItem.title) { |
| | | ElMessage({ |
| | | message: '请填写教学名称', |
| | | type: 'warning' |
| | | }) |
| | | newLoading.value = false |
| | | return false |
| | | message: "请填写教学名称", |
| | | type: "warning", |
| | | }); |
| | | newLoading.value = false; |
| | | return false; |
| | | } |
| | | if (dynamicList.value[0]?.parentVal == '') { |
| | | if (dynamicList.value[0]?.parentVal == "") { |
| | | ElMessage({ |
| | | message: '请选择教学章节', |
| | | type: 'warning' |
| | | }) |
| | | newLoading.value = false |
| | | return false |
| | | message: "请选择教学章节", |
| | | type: "warning", |
| | | }); |
| | | newLoading.value = false; |
| | | return false; |
| | | } |
| | | if (fileList.value.length == 0) { |
| | | ElMessage({ |
| | | message: '请上传教学文件', |
| | | type: 'warning' |
| | | }) |
| | | newLoading.value = false |
| | | return false |
| | | message: "请上传教学文件", |
| | | type: "warning", |
| | | }); |
| | | newLoading.value = false; |
| | | return false; |
| | | } |
| | | const data = { |
| | | groupId: classInfo?.id, |
| | |
| | | newGroupCmsItemRequests: [ |
| | | { |
| | | name: taskItem.title, |
| | | description: '', |
| | | icon: '', |
| | | description: "", |
| | | icon: "", |
| | | type: config.refCodes.teachingPlan, |
| | | state: 'Normal', |
| | | state: "Normal", |
| | | order: 0, |
| | | newDataListRequest: tool.worksDataBytool(classItem.value, taskItem, fileList.value), |
| | | newDataListRequest: tool.worksDataBytool( |
| | | classItem.value, |
| | | taskItem, |
| | | fileList.value |
| | | ), |
| | | newCmsItemAndFileLinkListRequest: [], |
| | | newChildrenListRequest: [] |
| | | } |
| | | ] |
| | | } |
| | | newChildrenListRequest: [], |
| | | }, |
| | | ], |
| | | }; |
| | | MG.edu.newTaskCmsItem(data).then((res: any) => { |
| | | newLoading.value = false |
| | | newLoading.value = false; |
| | | if (res) { |
| | | ElMessage({ |
| | | message: '新建成功', |
| | | type: 'success' |
| | | }) |
| | | visible.value = false |
| | | getTaskCmsList() |
| | | message: "新建成功", |
| | | type: "success", |
| | | }); |
| | | visible.value = false; |
| | | getTaskCmsList(); |
| | | } |
| | | }) |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // // 编辑资源 |
| | | // const editOpen = (item: any) => { |
New file |
| | |
| | | <template> |
| | | <div class="homePage"> |
| | | <el-carousel :height="screenheight + 'px'"> |
| | | <el-carousel-item v-for="(item, index) in banner" :key="index"> |
| | | <div class="bannerBox imgBox"> |
| | | <img id="autoHeight" class="bannerImg" :src="item.icon" @click="bannerLink(item)" /> |
| | | </div> |
| | | </el-carousel-item> |
| | | </el-carousel> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, onBeforeMount, inject, reactive, onMounted } from 'vue' |
| | | const MG = inject('MG') |
| | | |
| | | let screenheight = ref(document.documentElement.clientHeight / 2) |
| | | const banner = reactive([]) |
| | | const getBanner = () => { |
| | | MG.resource |
| | | .getItem({ |
| | | path: 'banner\\homeBanner', |
| | | fields: { link: [] }, |
| | | paging: { start: 0, size: 9 }, |
| | | }) |
| | | .then((res) => { |
| | | banner.push(...res.datas) |
| | | console.log(res.datas) |
| | | }) |
| | | } |
| | | onMounted(() => { |
| | | getBanner() |
| | | }) |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | .homePage { |
| | | min-width: 1220px; |
| | | min-height: calc(100vh - 61.8%); |
| | | background-color: #fff; |
| | | padding-bottom: 100px; |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <div class="homePage"> |
| | | <el-carousel :height="screenheight"> |
| | | <el-carousel-item v-for="item in 4" :key="item"> |
| | | <h3 class="small justify-center" text="2xl">{{ item }}</h3> |
| | | <el-carousel :height="screenheight + 'px'"> |
| | | <el-carousel-item v-for="(item, index) in banner" :key="index"> |
| | | <div class="bannerBox imgBox"> |
| | | <img id="autoHeight" class="bannerImg" :src="item.icon" @click="bannerLink(item)" /> |
| | | </div> |
| | | </el-carousel-item> |
| | | </el-carousel> |
| | | <div class="contentBox" style="margin-top: 50px"> |
| | | <div class="informationBox"> |
| | | <div class="bookListTitle"> |
| | | <div class="title">新闻资讯</div> |
| | | <div class="more">更多></div> |
| | | </div> |
| | | <div class="informationList"> |
| | | <div class="informationItem" v-for="(item, index) in informationList" :key="index"> |
| | | <div class="imgBox"><img class="autoImg" :src="item.icon" alt="" /></div> |
| | | <div class="informationContent"> |
| | | <div class="informationTitle" :alt="item.name">{{ item.name }}</div> |
| | | <div class="informationDate">{{ moment(item.publishDate).format('YYYY-MM-DD') }}</div> |
| | | <div class="informationText">{{ item.description }}</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="bookListBox"> |
| | | <div class="contentBox"> |
| | | <div class="bookListTitle"> |
| | | <div class="title">推荐教材</div> |
| | | <div class="more">更多></div> |
| | | </div> |
| | | <div class="recommendList"> |
| | | <div class="recommendItem" v-for="item in bookListData" :key="item.id"> |
| | | <div class="recommendItemImg"> |
| | | <img class="autoImg" :src="item.icon" /> |
| | | </div> |
| | | <div class="infoBox"> |
| | | <div class="bookName">{{ item.name }}</div> |
| | | <div class="author"> |
| | | 作者:{{ item.authorcaupress_author ? item.caupress_author : '-' }} |
| | | </div> |
| | | <div class="priceBox"> |
| | | <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 class="contentBox"> |
| | | <div class="funBox"> |
| | | <div class="authentication"></div> |
| | | <div class="manual"></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> |
| | | </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="recommendItemImg"> |
| | | <img class="autoImg" :src="item.icon" /> |
| | | </div> |
| | | <div class="infoBox"> |
| | | <div class="bookName">{{ item.name }}</div> |
| | | <div class="author"> |
| | | 作者:{{ item.authorcaupress_author ? item.caupress_author : '-' }} |
| | | </div> |
| | | <div class="priceBox"> |
| | | <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> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref } from 'vue' |
| | | let screenheight = ref(document.documentElement.clientHeight / 4) |
| | | import moment from 'moment' |
| | | 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 banner = reactive([]) |
| | | const informationList = reactive([]) |
| | | let bookListData = ref([]) |
| | | onBeforeMount(() => { |
| | | console.log(document.documentElement.clientWidth / 2.628) |
| | | |
| | | window.onresize = () => { |
| | | let c = 2.628 |
| | | if (document.documentElement.clientWidth >= 1220) { |
| | | screenheight.value = document.documentElement.clientWidth / c |
| | | console.log(document.documentElement.clientWidth / c) |
| | | } |
| | | } |
| | | }) |
| | | |
| | | onMounted(() => { |
| | | getBanner() |
| | | getInformationList() |
| | | getBookList() |
| | | }) |
| | | |
| | | const getBookList = () => { |
| | | MG.store |
| | | .getProductList({ |
| | | path: 'recommendedTextbooks', |
| | | paging: { |
| | | start: 0, |
| | | size: 5, |
| | | }, |
| | | fields: { |
| | | author: [], |
| | | }, |
| | | }) |
| | | .then((res) => { |
| | | console.log(res, '推荐教材') |
| | | bookListData.value = res.datas |
| | | }) |
| | | } |
| | | |
| | | const getInformationList = () => { |
| | | MG.resource |
| | | .getItem({ |
| | | path: 'information', |
| | | fields: { publishDate: [], content: [] }, |
| | | paging: { start: 0, size: 9 }, |
| | | }) |
| | | .then((res) => { |
| | | informationList.push(...res.datas) |
| | | console.log(res.datas) |
| | | }) |
| | | } |
| | | |
| | | const getBanner = () => { |
| | | MG.resource |
| | | .getItem({ |
| | | path: 'banner\\homeBanner', |
| | | fields: { link: [] }, |
| | | paging: { start: 0, size: 9 }, |
| | | }) |
| | | .then((res) => { |
| | | banner.push(...res.datas) |
| | | console.log(res.datas) |
| | | }) |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | |
| | | min-width: 1220px; |
| | | min-height: calc(100vh - 61.8%); |
| | | background-color: #fff; |
| | | padding-bottom: 100px; |
| | | } |
| | | .el-carousel__item h3 { |
| | | color: #475669; |
| | |
| | | .el-carousel__item:nth-child(2n + 1) { |
| | | background-color: #d3dce6; |
| | | } |
| | | |
| | | .informationList { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | .informationItem { |
| | | display: flex; |
| | | width: 42%; |
| | | min-height: 100px; |
| | | margin-right: 5%; |
| | | margin-bottom: 20px; |
| | | border: 1px solid #ebebeb; |
| | | border-radius: 10px; |
| | | padding: 10px; |
| | | cursor: pointer; |
| | | .imgBox { |
| | | width: 30%; |
| | | height: 100%; |
| | | position: relative; |
| | | } |
| | | .informationContent { |
| | | width: 70%; |
| | | padding-left: 10px; |
| | | .informationTitle { |
| | | font-size: 14px; |
| | | width: 100%; |
| | | white-space: nowrap; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | color: #333333; |
| | | font-weight: bold; |
| | | margin-bottom: 10px; |
| | | } |
| | | .informationDate { |
| | | margin-top: 10px; |
| | | } |
| | | .informationText { |
| | | color: #666666; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | display: -webkit-box; |
| | | margin-top: 10px; |
| | | display: -webkit-box; /* 将对象作为弹性伸缩盒子模型显示 */ |
| | | -webkit-line-clamp: 3; /* 显示的行数 */ |
| | | -webkit-box-orient: vertical; /* 设置或检索伸缩盒对象的子元素的排列方式 */ |
| | | overflow: hidden; /* 溢出隐藏 */ |
| | | } |
| | | } |
| | | } |
| | | .informationItem:hover { |
| | | border: 1px solid #019e58; |
| | | } |
| | | } |
| | | .bookListBox { |
| | | width: 100%; |
| | | padding: 80px 0; |
| | | margin-top: 30px; |
| | | background-repeat: no-repeat; |
| | | background-size: 100% 100%; |
| | | background-image: url('@/assets/images/tuijian-bg.png'); |
| | | background-repeat: no-repeat; |
| | | background-size: 100% 100%; |
| | | } |
| | | |
| | | .recommendList { |
| | | display: flex; |
| | | padding-top: 20px; |
| | | |
| | | .recommendItem { |
| | | flex: 1; |
| | | margin-right: 20px; |
| | | height: 300px; |
| | | background-repeat: no-repeat; |
| | | background-size: 100% 100%; |
| | | cursor: pointer; |
| | | border: 1px solid #dedede; |
| | | background-color: #fff; |
| | | padding-top: 10px; |
| | | &:last-child { |
| | | margin-right: 0; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .recommendItemImg { |
| | | width: 150px; |
| | | height: 200px; |
| | | position: relative; |
| | | margin: 0 auto; |
| | | } |
| | | |
| | | .infoBox { |
| | | text-align: center; |
| | | margin-top: 10px; |
| | | } |
| | | .author { |
| | | margin-top: 10px; |
| | | } |
| | | .priceBox { |
| | | margin-top: 10px; |
| | | .oldPrice { |
| | | font-size: 16px; |
| | | color: #444444; |
| | | text-decoration: line-through; |
| | | margin-right: 20px; |
| | | } |
| | | .price { |
| | | span { |
| | | font-weight: bold; |
| | | font-size: 14px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .funBox { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-top: 60px; |
| | | margin-bottom: 60px; |
| | | .authentication { |
| | | width: 40%; |
| | | height: 80px; |
| | | background-repeat: no-repeat; |
| | | background-size: 100% 100%; |
| | | background-image: url('@/assets/images/xiehe/home/jiaoshirenzheng.png'); |
| | | } |
| | | .manual { |
| | | width: 40%; |
| | | height: 80px; |
| | | background-repeat: no-repeat; |
| | | background-size: 100% 100%; |
| | | background-image: url('@/assets/images/xiehe/home/jiaoshirenzheng.png'); |
| | | } |
| | | } |
| | | |
| | | .titleTabs { |
| | | margin-left: 50px; |
| | | } |
| | | .bookListTitle { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 20px; |
| | | border-bottom: 1px solid #ebebeb; |
| | | |
| | | padding-bottom: 20px; |
| | | .title { |
| | | font-size: 20px; |
| | | color: #333333; |
| | | font-weight: bold; |
| | | } |
| | | .more { |
| | | font-size: 14px; |
| | | color: #999999; |
| | | cursor: pointer; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | import moment from "moment"; |
| | | import { getPublicImage } from "@/assets/js/middleGround/tool.js"; |
| | | import { ElMessage } from "element-plus"; |
| | | import { useBreadcrumbStore, useUserStore } from "@/store"; |
| | | import { useUserStore } from "@/store"; |
| | | import { useRouter } from "vue-router"; |
| | | import bookCover from "@/assets/images/personalCenter/book-cover.png"; |
| | | const router = useRouter(); |
| | | const crumbStore = useBreadcrumbStore(); |
| | | const userStore = useUserStore(); |
| | | const MG = inject("MG"); |
| | | const activateCode = ref(""); |
| | |
| | | let parentData = await MG.store.getProductBySaleMethod({ |
| | | saleMethodId: defaultSaleMethodId, |
| | | }); |
| | | console.log(parentData, 123); |
| | | if (parentData.storeLinks[0].storeRefCode == "jsek_digitalCourses") { |
| | | let crumbs = [ |
| | | { |
| | | name, |
| | | isCrumbs: true, |
| | | type: "digitalCourses", |
| | | path: "digitalCoursesDetails", |
| | | }, |
| | | ]; |
| | | // 在全局数据中设置面包屑 |
| | | crumbStore.setCrumbs({ |
| | | type: "digitalCourses", |
| | | data: crumbs, |
| | | callback: (key: any) => { |
| | | router.push({ |
| | | name: "digitalCoursesDetails", |
| | | query: { |
| | | crumbsKey: key, |
| | | bookId: parentData.id, |
| | | bookName: parentData.name, |
| | | type: "digitalCourses", |
| | | }, |
| | | }); |
| | | }, |
| | | }); |
| | | } else if (parentData.storeLinks[0].storeRefCode == "jsek_digitalTextbooks") { |
| | | let crumbs = [ |
| | | { |
| | | name, |
| | | isCrumbs: true, |
| | | type: "digitalTextbooks", |
| | | path: "digitalTextbooksDetails", |
| | | }, |
| | | ]; |
| | | // 在全局数据中设置面包屑 |
| | | crumbStore.setCrumbs({ |
| | | type: "digitalTextbooks", |
| | | data: crumbs, |
| | | callback: (key: any) => { |
| | | router.push({ |
| | | name: "digitalTextbooksDetails", |
| | | query: { |
| | | crumbsKey: key, |
| | | bookId: parentData.id, |
| | | bookName: parentData.name, |
| | | type: "digitalTextbooks", |
| | | }, |
| | | }); |
| | | }, |
| | | }); |
| | | } else { |
| | | let crumbs = [ |
| | | { |
| | | name, |
| | | isCrumbs: true, |
| | | type: "bookService", |
| | | path: "/bookService/details", |
| | | }, |
| | | ]; |
| | | // 在全局数据中设置面包屑 |
| | | crumbStore.setCrumbs({ |
| | | type: "bookService", |
| | | data: crumbs, |
| | | callback: (key: any) => { |
| | | router.push({ |
| | | name: "bookDetails", |
| | | name: "bookdetail", |
| | | query: { |
| | | crumbsKey: key, |
| | | bookId: id, |
| | | bookName: name, |
| | | type: "bookService", |
| | | }, |
| | | }); |
| | | }, |
| | | }); |
| | | } |
| | |
| | | > |
| | | 未通过 |
| | | </div> |
| | | <img :src="item.icon" /> |
| | | <img v-if="item.icon" :src="item.icon" /> |
| | | <img v-else :src="defaultImg" alt="" /> |
| | | </div> |
| | | <div class="infoBox"> |
| | | <p class="id">ID:{{ item.id }}</p> |
| | |
| | | textBookPages.loading = true; |
| | | const searchData = [ |
| | | { |
| | | keywords: "jsek_digitalTextbooks", |
| | | keywords: "digitalTextbooks", |
| | | field: "ProductType", |
| | | }, |
| | | { |
| | | keywords: "jsek_mediaBook", |
| | | keywords: "mediaBook", |
| | | field: "ProductType", |
| | | }, |
| | | { |
| | |
| | | margin-bottom: 20px; |
| | | .textBookItem { |
| | | float: left; |
| | | width: 140px; |
| | | height: 200px; |
| | | width: 160px; |
| | | height: 220px; |
| | | margin: 10px; |
| | | position: relative; |
| | | border: 1px solid #eee; |
| | |
| | | } |
| | | } |
| | | |
| | | .imgBox { |
| | | width: 100px; |
| | | height: 110px; |
| | | margin-bottom: 10px; |
| | | } |
| | | |
| | | p { |
| | | line-height: 1.2; |
| | | display: -webkit-box; |
| | |
| | | } |
| | | } |
| | | |
| | | .autoImgBox { |
| | | width: 120px; |
| | | height: 130px; |
| | | margin-bottom: 10px; |
| | | position: relative; |
| | | img { |
| | | width: auto; |
| | | height: auto; |
| | | max-width: 100%; |
| | | max-height: 100%; |
| | | position: absolute; |
| | | top: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | left: 0; |
| | | margin: auto; |
| | | } |
| | | } |
| | | |
| | | .pagination-box { |
| | | display: flex; |
| | | justify-content: center; |
| | |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { ArrowRight } from '@element-plus/icons-vue' |
| | | import { menu } from './config.ts' |
| | | import { useRouter, onBeforeRouteUpdate } from 'vue-router' |
| | | import { ref, onMounted } from 'vue' |
| | | const router = useRouter() |
| | | const routerVal = router.currentRoute.value |
| | | const path = ref(routerVal.path) |
| | | const label = ref('') |
| | | const listMenu: any = ref([]) |
| | | import { ArrowRight } from "@element-plus/icons-vue"; |
| | | import { menu } from "./config.ts"; |
| | | import { useRouter, onBeforeRouteUpdate } from "vue-router"; |
| | | import { ref, onMounted, inject } from "vue"; |
| | | const router = useRouter(); |
| | | const routerVal = router.currentRoute.value; |
| | | const path = ref(routerVal.path); |
| | | const label = ref(""); |
| | | const listMenu: any = ref([]); |
| | | const MG: any = inject("MG"); |
| | | const config: any = inject("config"); |
| | | onBeforeRouteUpdate(async (to, from) => { |
| | | path.value = to.fullPath |
| | | }) |
| | | path.value = to.fullPath; |
| | | }); |
| | | onMounted(() => { |
| | | menu.forEach((item) => { |
| | | if ('/' + item.path === path.value) { |
| | | label.value = item.label |
| | | if ("/" + item.path === path.value) { |
| | | label.value = item.label; |
| | | } |
| | | }) |
| | | // const userCache: any = localStorage.getItem('jesk-userInfo') |
| | | // const userInfo = JSON.parse(userCache) |
| | | // if(!userInfo){ |
| | | // router.push({ |
| | | // path:'/' |
| | | // }) |
| | | // return false; |
| | | // } |
| | | // if (userInfo.role == 'Teacher') { |
| | | // const data: any = menu.filter((item) => item.path != 'class') |
| | | // listMenu.value = data |
| | | // } else { |
| | | const data: any = menu.filter((item) => item.path != 'course') |
| | | listMenu.value = data |
| | | // } |
| | | }) |
| | | }); |
| | | const userCache: any = localStorage.getItem(config.userInfoKey); |
| | | const userInfo = JSON.parse(userCache); |
| | | if (!userInfo) { |
| | | router.push({ |
| | | path: "/", |
| | | }); |
| | | return false; |
| | | } |
| | | if (userInfo.role == "Teacher") { |
| | | const data: any = menu.filter((item) => item.path != "myClass"); |
| | | listMenu.value = data; |
| | | } else { |
| | | const data: any = menu.filter((item) => item.path != "myCourse"); |
| | | listMenu.value = data; |
| | | } |
| | | }); |
| | | const goRouter = (item: any) => { |
| | | // if (!localStorage.getItem('jsek-token') || localStorage.getItem('jsek-token') == null) { |
| | | // router.push({ |
| | | // path: '/home', |
| | | // query: { |
| | | // showLogin: '1' |
| | | // } |
| | | // }) |
| | | // } else { |
| | | label.value = item.label |
| | | router.push({ path: item.path }) |
| | | // } |
| | | if ( |
| | | !localStorage.getItem(config.tokenKey) || |
| | | localStorage.getItem(config.tokenKey) == null |
| | | ) { |
| | | router.push({ |
| | | path: "/home", |
| | | query: { |
| | | showLogin: "1", |
| | | }, |
| | | }); |
| | | } else { |
| | | label.value = item.label; |
| | | router.push({ path: item.path }); |
| | | } |
| | | }; |
| | | </script> |
| | | <style lang="less" scoped> |
| | | .breadcrumbBox { |
| | |
| | | <script setup lang="ts"> |
| | | import { reactive, ref, onMounted, inject } from "vue"; |
| | | import { getPublicImage } from "@/assets/js/middleGround/tool"; |
| | | import { useRouter } from "vue-router"; |
| | | const MG: any = inject("MG"); |
| | | const config: any = inject("config"); |
| | | const crumbStore = inject("crumbStore"); |
| | | const router = inject("router"); |
| | | const router = useRouter(); |
| | | let listData = ref([]); |
| | | let loading = ref(false); |
| | | let paginationData = reactive({ |
| | |
| | | }); |
| | | |
| | | const toDetail = (item: any) => { |
| | | const thisCrumbs = [{ name: "书籍详情", pathName: "digitalTextbooks-textbooksDetail" }]; |
| | | MG.store.dispatch("setCrumbs", { |
| | | type: "textbooks", |
| | | data: thisCrumbs, |
| | | callback: (key: string) => { |
| | | MG.router.push({ |
| | | router.push({ |
| | | name: "digitalTextbooks-textbooksDetail", |
| | | query: { |
| | | id: item.id, |
| | | rootCmsItemId: item.rootCmsItemId, |
| | | crumbsKey: key, |
| | | }, |
| | | }); |
| | | }, |
| | | }); |
| | | }; |
| | |
| | | @click="goDetail(item)" |
| | | > |
| | | <div class="imgBox"> |
| | | <img :src="item.product.icon" alt /> |
| | | <img v-if="item.product.icon" :src="item.product.icon" /> |
| | | <img v-else :src="defaultImg" alt="" /> |
| | | </div> |
| | | <div class="details"> |
| | | <div class="text-flow" v-if="item.product.name"> |
| | | {{ item.product.name || "-" }} |
| | | </div> |
| | | <div class="text-flow" :title="item.tourism_ISBN"> |
| | | ISBN:{{ item.tourism_ISBN.length != 0 ? item.tourism_ISBN : "-" }} |
| | | <div class="text-flow" :title="item.isbn"> |
| | | ISBN:{{ item.isbn.length != 0 ? item.isbn : "-" }} |
| | | </div> |
| | | <div class="text-flow"> |
| | | 作者:{{ item.tourism_author.length != 0 ? item.tourism_author : "-" }} |
| | | 作者:{{ item.author.length != 0 ? item.author : "-" }} |
| | | </div> |
| | | <!-- <div class="text-flow" v-if="item.ExpiryDate"> |
| | | 截止日期:<span style="color: #dd0000">{{ item.ExpiryDate }}</span> |
| | | </div> --> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="myCarTopPage" v-else> |
| | | <el-empty description="您还未购买任何图书" :image-size="200" /> |
| | | </div> |
| | | </div> |
| | | <div class="pageCon"> |
| | |
| | | layout="total, prev, pager, next, slot" |
| | | :total="paginationData.totalCount" |
| | | > |
| | | <div style="display: inline-block"> |
| | | <div style="display: flex; align-items: center"> |
| | | <span class="el-pagination__jump" |
| | | >前往 |
| | | <div class="el-input el-pagination__editor is-in-pagination"> |
| | |
| | | </el-pagination> |
| | | </div> |
| | | </div> |
| | | <div class="myCarTopPage" v-else> |
| | | <el-empty description="您还未购买任何图书" :image-size="200" /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { reactive, ref, onMounted, inject, watch } from "vue"; |
| | | import { useRouter } from "vue-router"; |
| | | import { useUserStore, useBreadcrumbStore } from "@/store"; |
| | | import defaultImg from "@/assets/images/default-book-img.png"; |
| | | import { useUserStore } from "@/store"; |
| | | import tool from "@/assets/js/toolClass"; |
| | | const MG: any = inject("MG"); |
| | | const config: any = inject("config"); |
| | | const router = useRouter(); |
| | | const crumbStore = useBreadcrumbStore(); |
| | | let collectList = ref([]); |
| | | let currentCollect = ref("book"); |
| | | let isLoading = ref(false); |
| | |
| | | listData.value.forEach((item) => { |
| | | item.product.icon = tool.getPublicImage(item.product.icon); |
| | | }); |
| | | // console.log(that.collectList); |
| | | // //当前页面 |
| | | paginationData.totalCount = response.totalSize; |
| | | paginationData.totalPage = |
| | |
| | | ? response.totalSize / paginationData.limit |
| | | : Math.floor(response.totalSize / paginationData.limit) + 1; |
| | | loading.value = false; |
| | | collectList.value = response.datas; |
| | | }); |
| | | }; |
| | | onMounted(() => { |
| | |
| | | |
| | | //到图书详情 |
| | | const goDetail = (item) => { |
| | | let crumbs = [ |
| | | { |
| | | name: "教材详情", |
| | | }, |
| | | ]; |
| | | crumbStore.dispatch("setCrumbs", { |
| | | type: "textbooks", |
| | | data: crumbs, |
| | | callback: (key) => { |
| | | router.push({ |
| | | name: "digitalTextbooks-textbooksDetail", |
| | | path: "/bookdetail", |
| | | query: { |
| | | id: item.product.id, |
| | | rootCmsItemId: item.product.rootCmsItemId, |
| | | crumbsKey: key, |
| | | }, |
| | | }); |
| | | bookId: item.product.id, |
| | | }, |
| | | }); |
| | | }; |
| | |
| | | justify-content: center; |
| | | } |
| | | .myCarTopPage { |
| | | display: flex; |
| | | justify-content: flex-start; |
| | | box-sizing: border-box; |
| | | overflow: hidden; |
| | | padding-bottom: 20px; |
| | |
| | | } |
| | | .bookone { |
| | | display: flex; |
| | | width: 478px; |
| | | width: 420px; |
| | | min-height: 173px; |
| | | float: left; |
| | | cursor: pointer; |
| | |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | |
| | | <div class="breadcrumbsBox"> |
| | | <p> |
| | | 位置: <span>购物车({{ total }})</span> |
| | | </p> |
| | | </div> |
| | | <div class="selectproduct"> |
| | | <el-table |
| | | ref="multipleTableRef" |
| | |
| | | <el-table-column |
| | | property="name" |
| | | label="商品信息" |
| | | width="300" |
| | | :cell-style="{ margin: '30px' }" |
| | | width="200" |
| | | /> |
| | | <el-table-column property="productType" label="商品类型" width="300" /> |
| | | <el-table-column property="productType" label="商品类型" width="200" /> |
| | | <el-table-column label="价格"> |
| | | <template #default="scope">¥{{ scope.row.unitprice.toFixed(2) }}</template> |
| | | </el-table-column> |
| | |
| | | import { reactive } from "vue"; |
| | | import { useRouter } from "vue-router"; |
| | | import { InfoFilled } from "@element-plus/icons-vue"; |
| | | import { useUserStore, useBreadcrumbStore } from "@/store"; |
| | | import { useUserStore } from "@/store"; |
| | | import { getPublicImage } from "@/assets/js/middleGround/tool.js"; |
| | | import defaultImg from "@/assets/images/default-book-img.png"; |
| | | const dialogVisible = ref(false); |
| | | const crumbStore = useBreadcrumbStore(); |
| | | const router = useRouter(); |
| | | const userStore = useUserStore(); |
| | | const MG = inject("MG"); |
| | |
| | | orderNumber.value = createOrderResult.orderNumber; |
| | | |
| | | if (selectedIds.length) { |
| | | let crumbs = { |
| | | name: "订单支付", // 面包屑名称 |
| | | pathName: "paymentPage", // 面包屑跳转路由,可传递 pathName 或 path |
| | | isCrumbs: true, // 面包屑点击跳转时是否创建新的面包屑记录 |
| | | type: "shoppingCart", // 如果需要创建新的面包屑记录,创建的type |
| | | }; |
| | | // 在全局数据中设置面包屑 |
| | | crumbStore.setCrumbs({ |
| | | type: "shoppingCart", |
| | | data: [crumbs], |
| | | callback: (key) => { |
| | | router.push({ |
| | | name: "paymentPage", |
| | | query: { |
| | |
| | | // type: route.query.type, |
| | | type: "shoppingCart", |
| | | onNorderSaleMethod: saleMethodId, |
| | | }, |
| | | }); |
| | | }, |
| | | }); |
| | | } else { |
| | |
| | | <script setup lang="ts"> |
| | | import { reactive, ref, onMounted, inject, watch } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import { useBreadcrumbStore, useUserStore } from '@/store' |
| | | import { useUserStore } from "@/store"; |
| | | import { useRouter } from "vue-router"; |
| | | const crumbStore = useBreadcrumbStore() |
| | | const userStore = useUserStore() |
| | | const userStore = useUserStore(); |
| | | const router = useRouter(); |
| | | const MG: any = inject("MG"); |
| | | const config: any = inject("config"); |
| | |
| | | }; |
| | | // 跳转书本详情 |
| | | const goBookDetails = (id: number, name: string) => { |
| | | let crumbs = [ |
| | | { |
| | | name, |
| | | isCrumbs: true, |
| | | type: |
| | | currentCollect.value == "book" |
| | | ? "bookService" |
| | | : currentCollect.value == "textBooks" |
| | | ? "digitalTextbooks" |
| | | : "digitalCourses", |
| | | path: |
| | | currentCollect.value == "book" |
| | | ? "/bookService/details" |
| | | : "/digitalCoursesDetails", |
| | | }, |
| | | ]; |
| | | // 在全局数据中设置面包屑 |
| | | crumbStore.setCrumbs({ |
| | | type: |
| | | currentCollect.value == "book" |
| | | ? "bookService" |
| | | : currentCollect.value == "textBooks" |
| | | ? "digitalTextbooks" |
| | | : "digitalCourses", |
| | | data: crumbs, |
| | | callback: (key: any) => { |
| | | router.push({ |
| | | name: |
| | | currentCollect.value == "book" |
| | | ? "bookDetails" |
| | | : currentCollect.value == "textBooks" |
| | | ? "digitalTextbooksDetails" |
| | | : "digitalCoursesDetails", |
| | | path: "/bookdetail", |
| | | query: { |
| | | crumbsKey: key, |
| | | bookId: id, |
| | | bookName: name, |
| | | type: |
| | | currentCollect.value == "book" |
| | | ? "bookService" |
| | | : currentCollect.value == "textBooks" |
| | | ? "digitalTextbooks" |
| | | : "digitalCourses", |
| | | }, |
| | | }); |
| | | }, |
| | | }); |
| | | }; |
| | |
| | | import { ElMessage } from "element-plus"; |
| | | import { getPublicImage } from "@/assets/js/middleGround/tool.js"; |
| | | import { useRouter } from "vue-router"; |
| | | import { useBreadcrumbStore, useUserStore } from "@/store"; |
| | | import { useUserStore } from "@/store"; |
| | | import bookCover from "@/assets/images/personalCenter/book-cover.png"; |
| | | const router = useRouter(); |
| | | const crumbStore = useBreadcrumbStore(); |
| | | const userStore = useUserStore(); |
| | | const MG: any = inject("MG"); |
| | | let order = ref("all"); |
| | |
| | | let parentData = null; |
| | | let bookId = id; |
| | | if (refCode == "digitalCourses") { |
| | | let crumbs = [ |
| | | { |
| | | name, |
| | | isCrumbs: true, |
| | | type: "digitalCourses", |
| | | path: "digitalCoursesDetails", |
| | | }, |
| | | ]; |
| | | // 在全局数据中设置面包屑 |
| | | crumbStore.setCrumbs({ |
| | | type: "digitalCourses", |
| | | data: crumbs, |
| | | callback: (key: any) => { |
| | | router.push({ |
| | | name: "digitalCoursesDetails", |
| | | path: "/bookdetail", |
| | | query: { |
| | | crumbsKey: key, |
| | | bookId: bookId, |
| | | bookName: name, |
| | | type: "digitalCourses", |
| | | }, |
| | | }); |
| | | }, |
| | | }); |
| | | } else if (refCode == "digitalTextbooks") { |
| | | let crumbs = [ |
| | | { |
| | | name, |
| | | isCrumbs: true, |
| | | type: "digitalTextbooks", |
| | | path: "digitalTextbooksDetails", |
| | | }, |
| | | ]; |
| | | // 在全局数据中设置面包屑 |
| | | crumbStore.setCrumbs({ |
| | | type: "digitalTextbooks", |
| | | data: crumbs, |
| | | callback: (key: any) => { |
| | | router.push({ |
| | | name: "digitalTextbooksDetails", |
| | | path: "/bookdetail", |
| | | query: { |
| | | crumbsKey: key, |
| | | bookId: bookId, |
| | | bookName: name, |
| | | type: "digitalTextbooks", |
| | | }, |
| | | }); |
| | | }, |
| | | }); |
| | | } else { |
| | |
| | | if (parentData.parentProduct.length > 0) { |
| | | bookId = parentData.parentProduct[parentData.parentProduct.length - 1].id; |
| | | } |
| | | console.log(bookId, "bookId"); |
| | | let crumbs = [ |
| | | { |
| | | name, |
| | | isCrumbs: true, |
| | | type: "bookService", |
| | | path: "/bookService/details", |
| | | }, |
| | | ]; |
| | | // 在全局数据中设置面包屑 |
| | | crumbStore.setCrumbs({ |
| | | type: "bookService", |
| | | data: crumbs, |
| | | callback: (key: any) => { |
| | | router.push({ |
| | | name: "bookDetails", |
| | | path: "/bookdetail", |
| | | query: { |
| | | crumbsKey: key, |
| | | bookId: bookId, |
| | | bookName: name, |
| | | type: "bookService", |
| | | }, |
| | | }); |
| | | }, |
| | | }); |
| | | } |
| | | }; |
| | | //立即支付 |
| | | const toPay = (orderNo) => { |
| | | let crumbs: any[] = [ |
| | | { |
| | | name: "我的订单", // 面包屑名称 |
| | | pathName: "myOrder", // 面包屑跳转路由,可传递 pathName 或 path |
| | | isCrumbs: true, // 面包屑点击跳转时是否创建新的面包屑记录 |
| | | type: "personalCenter", // 如果需要创建新的面包屑记录,创建的type |
| | | query: { |
| | | type: "personalCenter", |
| | | }, |
| | | }, |
| | | ]; |
| | | crumbs.push({ |
| | | name: "订单详情", |
| | | }); |
| | | // 在全局数据中设置面包屑 |
| | | crumbStore.setCrumbs({ |
| | | type: "personalCenter", |
| | | data: crumbs, |
| | | callback: (key: any) => { |
| | | router.push({ |
| | | path: "/paymentPage", //要跳转的页面 |
| | | query: { |
| | | crumbsKey: key, |
| | | orderNum: orderNo, |
| | | type: "personalCenter", |
| | | }, |
| | | }); |
| | | }, |
| | | }); |
| | | }; |
| | |
| | | import { useUserStore } from "@/store"; |
| | | // import wxlogin from 'vue-wxlogin' |
| | | import teacherCertification from "./teacherCertification.vue"; |
| | | // import login from '@/layout/components/login.vue' |
| | | import login from '@/layout/components/login.vue' |
| | | const userStore = useUserStore(); |
| | | import { useRoute } from "vue-router"; |
| | | import moment from "moment"; |