20个文件已删除
17个文件已添加
11个文件已修改
| | |
| | | "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-router": "^4.5.1" |
| | | }, |
| | | "devDependencies": { |
| | |
| | | "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": ">=16" |
| | | } |
| | | }, |
| | | "node_modules/tiny-emitter": { |
| | | "version": "2.1.0", |
| | | "resolved": "https://registry.npmmirror.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz", |
| | | "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/tinyglobby": { |
| | | "version": "0.2.14", |
| | | "resolved": "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.14.tgz", |
| | |
| | | } |
| | | } |
| | | }, |
| | | "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-router": { |
| | | "version": "4.5.1", |
| | | "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.5.1.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", |
| | |
| | | "copy-anything": "^3.0.2" |
| | | } |
| | | }, |
| | | "tiny-emitter": { |
| | | "version": "2.1.0", |
| | | "resolved": "https://registry.npmmirror.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz", |
| | | "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" |
| | | }, |
| | | "tinyglobby": { |
| | | "version": "0.2.14", |
| | | "resolved": "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.14.tgz", |
| | |
| | | "@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-router": { |
| | | "version": "4.5.1", |
| | | "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.5.1.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", |
| | |
| | | "pinia": "^3.0.3", |
| | | "spark-md5": "^3.0.2", |
| | | "vue": "^3.5.18", |
| | | "vue-baidu-map-3x": "^1.0.40", |
| | | "vue-router": "^4.5.1" |
| | | }, |
| | | "devDependencies": { |
| | |
| | | export const requestCtx = 'http://182.92.203.7:5001' // 请求地址 |
| | | // export const requestCtx = 'http://182.92.203.7:5001' // 请求地址 |
| | | export const requestCtx = 'http://39.96.166.67' // 请求地址 |
| | | // export const appId = 1051; |
| | | |
| | | // export const requestCtx = 'http://172.31.31.145' // 请求地址 |
| | |
| | | export const appId = 1 |
| | | |
| | | export const requestTimeOut = 300000 // 请求超时时间 |
| | | export const tokenKey = 'jilin-token' |
| | | export const userInfoKey = 'jilin-userInfo' // 用户信息key |
| | | export const appRefCode = 'jilinWebsite' |
| | | export const tokenKey = 'jsek-token' |
| | | export const userInfoKey = 'jsek-isUserInfo' // 用户信息key |
| | | export const appRefCode = 'PUMC' |
| | | export const goodsStore = `defaultGoodsStore${appId}` // 默认商品库(书城) |
| | | export const publicStore = `defaultPublicStore${appId}` // 默认资源开放仓储 |
| | | export const publicRepository = `defaultPublicRepository${appId}` // 默认资源开放库 |
| | |
| | | newVideosStore: 'jilin_videosLibrary\\jilin_newVideosStore', |
| | | newModelsStore: 'jilin_modelsLibrary\\jilin_newModelsStore', |
| | | // 首页推荐资源 |
| | | recommendImgStore:'jilin_imgLibrary\\jilin_recommendedImage', |
| | | recommendAudioStore:'jilin_audiosLibrary\\jilin_recommendedAudio', |
| | | recommendVideoStore:'jilin_videosLibrary\\jilin_recommendedVideo', |
| | | recommendModelStore:'jilin_modelsLibrary\\jilin_recommendedModel', |
| | | recommendImgStore: 'jilin_imgLibrary\\jilin_recommendedImage', |
| | | recommendAudioStore: 'jilin_audiosLibrary\\jilin_recommendedAudio', |
| | | recommendVideoStore: 'jilin_videosLibrary\\jilin_recommendedVideo', |
| | | recommendModelStore: 'jilin_modelsLibrary\\jilin_recommendedModel', |
| | | } |
| | | |
| | | const wxLogin = { |
| | | appid: 'wx2b9d4a6308fd03d6', |
| | | scope: 'snsapi_login', |
| | | logInRedirectURL: encodeURIComponent(requestCtx + '/website'), |
| | | authenRedirectURL:encodeURIComponent(requestCtx + '/website/#/userInfo') |
| | | authenRedirectURL: encodeURIComponent(requestCtx + '/website/#/userInfo'), |
| | | } |
| | | |
| | | const config = { |
| | |
| | | reg_tel, |
| | | appId, |
| | | refCode, |
| | | wxLogin |
| | | wxLogin, |
| | | } |
| | | export default config |
| | |
| | | import request from "@/plugin/axios/index.ts"; |
| | | import request from '@/plugin/axios/index.ts' |
| | | const identityApi = { |
| | | // 获取图形验证码 |
| | | getImgCode() { |
| | | return request({ |
| | | url: "/identity/NewCaptcha", |
| | | method: "post", |
| | | }); |
| | | url: '/identity/NewCaptcha', |
| | | method: 'post', |
| | | }) |
| | | }, |
| | | |
| | | // 验证图形验证码 |
| | | verificationImgCode(data) { |
| | | return request({ |
| | | url: "/identity/ValidCaptcha", |
| | | method: "post", |
| | | url: '/identity/ValidCaptcha', |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }) |
| | | }, |
| | | |
| | | // 获取短信验证码 |
| | | getPhoneCode(data) { |
| | | return request({ |
| | | url: "/identity/NewSms", |
| | | method: "post", |
| | | url: '/identity/NewSms', |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }) |
| | | }, |
| | | // 验证短信验证码 |
| | | verificationPhoneCode(data) { |
| | | return request({ |
| | | url: "/identity/api/ApiValidMobilePhone", |
| | | method: "post", |
| | | url: '/identity/api/ApiValidMobilePhone', |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }) |
| | | }, |
| | | |
| | | getSlideCaptchaImage(options) { |
| | | return request('/identity/GetSlideCaptchaImage', { |
| | | method: 'POST', |
| | | data: options || {}, |
| | | }) |
| | | }, |
| | | // 验证滑动验证码 |
| | | validSlideCaptcha(options) { |
| | | return request('/identity/ValidSlideCaptcha', { |
| | | method: 'POST', |
| | | data: options || {}, |
| | | }) |
| | | }, |
| | | |
| | | // 通过手机号注册用户 |
| | | registerAppUserWithPhone(data) { |
| | | return request({ |
| | | url: "/identity/api/RegisterAppUserWithPhone", |
| | | method: "post", |
| | | url: '/identity/api/RegisterAppUserWithPhone', |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }) |
| | | }, |
| | | |
| | | // 账号密码登录 |
| | | loginByPassword(data) { |
| | | return request({ |
| | | url: "/identity/api/LoginByPassword", |
| | | method: "post", |
| | | url: '/identity/api/LoginByPassword', |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }) |
| | | }, |
| | | |
| | | // 短信验证码登录 |
| | | loginByMobilePhone(data) { |
| | | return request({ |
| | | url: "/identity/api/LoginByMobilePhone", |
| | | method: "post", |
| | | url: '/identity/api/LoginByMobilePhone', |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }) |
| | | }, |
| | | |
| | | // 设置用户key |
| | | setUserKey(data) { |
| | | return request({ |
| | | url: "/identity/api/ApiAppUserSetKey", |
| | | method: "post", |
| | | url: '/identity/api/ApiAppUserSetKey', |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }) |
| | | }, |
| | | |
| | | // 获取用户key |
| | | getUserKey(data) { |
| | | return request({ |
| | | url: "/identity/api/ApiGetAppUserKey", |
| | | method: "post", |
| | | url: '/identity/api/ApiGetAppUserKey', |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }) |
| | | }, |
| | | |
| | | // 删除用户key |
| | | delUserKey(data) { |
| | | return request({ |
| | | url: "/identity/api/ApiDelAppUserKey", |
| | | method: "post", |
| | | url: '/identity/api/ApiDelAppUserKey', |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }) |
| | | }, |
| | | |
| | | // 获取去当前用户信息 |
| | | getCurrentAppUser() { |
| | | return request({ |
| | | url: "/identity/api/GetCurrentAppUser", |
| | | method: "post", |
| | | }); |
| | | url: '/identity/api/GetCurrentAppUser', |
| | | method: 'post', |
| | | }) |
| | | }, |
| | | |
| | | // 添加用户信息 |
| | | setAppUserInfo(data) { |
| | | return request({ |
| | | url: "/identity/api/SetAppUserInfoRequest", |
| | | method: "post", |
| | | url: '/identity/api/SetAppUserInfoRequest', |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }) |
| | | }, |
| | | |
| | | // 用户更换绑定手机号,如没有绑定手机则自动创建 |
| | | userSetPhoneNumber(data) { |
| | | return request({ |
| | | url: "/identity/api/ApiUserSetPhoneNumber", |
| | | method: "post", |
| | | url: '/identity/api/ApiUserSetPhoneNumber', |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }) |
| | | }, |
| | | |
| | | // 检测用户是否绑定微信 |
| | | checkBuildingWeChat(data) { |
| | | return request({ |
| | | url: "/identity/api/ApiCheckBuildingWeChat", |
| | | method: "post", |
| | | url: '/identity/api/ApiCheckBuildingWeChat', |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }) |
| | | }, |
| | | |
| | | |
| | | // 通过手机号重置密码 |
| | | changePasswordByMobilePhone(data) { |
| | | return request({ |
| | | url: "/identity/api/ChangePasswordByMobilePhone", |
| | | method: "post", |
| | | url: '/identity/api/ChangePasswordByMobilePhone', |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }) |
| | | }, |
| | | |
| | | // 微信开放平台扫码登录 |
| | | loginByWeChatOpenCode(data) { |
| | | return request({ |
| | | url: "/identity/api/LoginByWeChatOpenCode", |
| | | method: "post", |
| | | url: '/identity/api/LoginByWeChatOpenCode', |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }) |
| | | }, |
| | | |
| | | // 用户绑定微信号 |
| | | bindingWeChat(data) { |
| | | return request({ |
| | | url: "/identity/api/ApiBindingWeChat", |
| | | method: "post", |
| | | url: '/identity/api/ApiBindingWeChat', |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }) |
| | | }, |
| | | |
| | | // 设置登录的用户名和密码,用户名和密码至少6位 |
| | | setLoginNameAndPassword(data) { |
| | | return request({ |
| | | url: "/identity/api/ApiUserSetLoginNameAndPassword", |
| | | method: "post", |
| | | url: '/identity/api/ApiUserSetLoginNameAndPassword', |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }) |
| | | }, |
| | | |
| | | // 获取邮箱验证码 |
| | | getEmailCode(data) { |
| | | return request({ |
| | | url: "/identity/api/SendVerifyEMail", |
| | | method: "post", |
| | | url: '/identity/api/SendVerifyEMail', |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }) |
| | | }, |
| | | // 用户绑定邮箱 |
| | | bindingEmail(data) { |
| | | return request({ |
| | | url: "/identity/api/ApiBindEMail", |
| | | method: "post", |
| | | url: '/identity/api/ApiBindEMail', |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }) |
| | | }, |
| | | }; |
| | | } |
| | | |
| | | export default identityApi; |
| | | export default identityApi |
| | |
| | | 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 == 'tourism_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 == 'tourism_accompanyingResources', |
| | | ).saleMethod |
| | | if (saleMethod && saleMethod.length > 0) { |
| | | Object.keys(saleMethod[0]).map((key) => { |
| | |
| | | if (md5) { |
| | | src = requestCtx + `/file/GetPreViewImage?md5=${md5}` |
| | | } else { |
| | | if(storeInfo == `defaultGoodsStore${appId}`){ |
| | | return bookCover; |
| | | }else{ |
| | | return "" |
| | | if (storeInfo == `defaultGoodsStore${appId}`) { |
| | | return bookCover |
| | | } else { |
| | | 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?.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]; |
| | | if (values ?.length > 1) { |
| | | const isFile = values.find((citem) => citem.FileList ?.length > 0); |
| | | const dataItems = deduplicateArray(values, 'FieldId'); |
| | | item.datas[fieldKey] = values[0] |
| | | if (values?.length > 1) { |
| | | 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({ |
| | |
| | | linkInfo: item.datas.LinkInfo ? JSON.parse(item.datas.LinkInfo) : [], |
| | | linkPath: item.datas.LinkPath ?? null, |
| | | linkOrg: item.datas.LinkOrg ? JSON.parse(item.datas.LinkOrg) : [], |
| | | linkDepartment: item.datas.LinkDepartment? JSON.parse(item.datas.LinkDepartment) : [], |
| | | linkDepartment: item.datas.LinkDepartment ? JSON.parse(item.datas.LinkDepartment) : [], |
| | | ..._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, |
| | |
| | | handleTypeList, |
| | | handleTreeData, |
| | | // parseHtml, |
| | | } |
| | | } |
| | |
| | | } */ |
| | | |
| | | .el-input-group__append, .el-input-group__prepend { |
| | | vertical-align: initial !important; |
| | | /* vertical-align: initial !important; */ |
| | | /* align-items: stretch !important; */ |
| | | } |
| | | .el-checkbox__inner{ |
| | | border: 1px solid #000 !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); |
| | |
| | | <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> |
| | | <span style="cursor: pointer">欢迎您,{{ userStore?.userInfo.name }}!</span> |
| | | <el-dropdown-menu slot="dropdown"> |
| | | <el-dropdown-item icon="el-icon-user" command="gotoPersonalCenter" |
| | | >个人中心</el-dropdown-item |
| | |
| | | </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 login from './login.vue' |
| | | import { onMounted, ref } from 'vue' |
| | | import { Search } from '@element-plus/icons-vue' |
| | | import { useUserStore } from '@/stores' |
| | | import { useRouter } from 'vue-router' |
| | | const userStore = useUserStore() |
| | | const router = useRouter() |
| | | |
| | | const loginRef = ref() |
| | | const props = defineProps({ |
| | | hideSerch: { |
| | | type: Boolean, |
| | |
| | | }, |
| | | ]) |
| | | |
| | | onMounted(() => { |
| | | userInfo.value = userStore.userInfo |
| | | console.log(userInfo.value, 'userInfo') |
| | | }) |
| | | |
| | | const gotoSearch = () => {} |
| | | const handleCommand = () => {} |
| | | const gotoPage = () => {} |
| | | const gotoPage = (item) => { |
| | | router.push(item.path) |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
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 '@/stores' |
| | | 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('jsek-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('jesk-userInfo') |
| | | localStorage.removeItem('jsek-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, |
| | | }, |
| | | ], |
| | | }, |
| | | ], |
New file |
| | |
| | | import { createPinia } from 'pinia' |
| | | |
| | | // 创建pinia实例 |
| | | const pinia = createPinia() |
| | | |
| | | export default pinia |
| | | |
| | | // export * from './modules/breadcrumb' |
| | | export * from './modules/user' |
New file |
| | |
| | | import { defineStore } from 'pinia' |
| | | import { ref } from 'vue' |
| | | |
| | | export const useUserStore = defineStore('user', () => { |
| | | const token = localStorage.getItem('jsek-token') ? ref(localStorage.getItem('jsek-token')) : ref() |
| | | const userInfo = localStorage.getItem('jesk-userInfo') |
| | | ? ref(JSON.parse(localStorage.getItem('jesk-userInfo'))) |
| | | : ref() |
| | | const setToken = (value) => { |
| | | token.value = value |
| | | localStorage.setItem('jsek-token', value) |
| | | } |
| | | const setUserInfo = (value) => { |
| | | userInfo.value = value |
| | | localStorage.setItem('jesk-userInfo', JSON.stringify(value)) |
| | | } |
| | | // 退出登录 |
| | | const delteUserInfo = () => { |
| | | ;((token.vlaue = ''), (userInfo.value = { userName: '', userType: '' })) |
| | | localStorage.removeItem('jsek-token') |
| | | localStorage.removeItem('jesk-userInfo') |
| | | localStorage.removeItem('jsek-isUserInfo') |
| | | } |
| | | // 购物车数量 |
| | | let cartNum = ref(1) |
| | | // 更新右侧弹出框购物车的数量 |
| | | const updateRightPop = () => { |
| | | cartNum.value += 1 |
| | | } |
| | | |
| | | // 购物车商品id |
| | | const shoppingIds = ref([]) |
| | | const updateShoppingIds = (ids) => { |
| | | shoppingIds.value = ids |
| | | } |
| | | |
| | | // 已购买的商品id |
| | | const buyIds = ref([]) |
| | | const updateBuyIds = (ids) => { |
| | | buyIds.value = ids |
| | | } |
| | | |
| | | return { |
| | | token, |
| | | setToken, |
| | | userInfo, |
| | | setUserInfo, |
| | | delteUserInfo, |
| | | cartNum, |
| | | updateRightPop, |
| | | shoppingIds, |
| | | updateShoppingIds, |
| | | buyIds, |
| | | updateBuyIds, |
| | | } |
| | | }) |
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> |
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> |