init
This commit is contained in:
commit
6a8e5e1929
|
@ -0,0 +1,24 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
|
@ -0,0 +1,7 @@
|
|||
# Vue 3 + Vite
|
||||
|
||||
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar)
|
|
@ -0,0 +1 @@
|
|||
# Vue 3 + Vite
|
|
@ -0,0 +1 @@
|
|||
# Vue 3 + Vite + pinia
|
|
@ -0,0 +1,13 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
export function getShopCarList(){
|
||||
return request({
|
||||
url:'/shopcar/getShopCarList'
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteShopCar(){
|
||||
return request({
|
||||
url:'/shopcar/deleteShopCar'
|
||||
})
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
export function getShopCarList(){
|
||||
return request({
|
||||
url:'/shopcar/getShopCarList'
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteShopCar(){
|
||||
return request({
|
||||
url:'/shopcar/deleteShopCar'
|
||||
})
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
export function getShopCarList(){
|
||||
return request({
|
||||
url:'/shopcar/getShopCarList'
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteShopCar(){
|
||||
return request({
|
||||
url:'/shopcar/deleteShopCar'
|
||||
})
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
export function getFirstCategorys(){
|
||||
return request({
|
||||
url:'/course/category/getFirstCategorys'
|
||||
})
|
||||
}
|
||||
|
||||
export function getSecondCategorys(data){
|
||||
return request({
|
||||
url:'/course/category/getSecondCategorys',
|
||||
params:data
|
||||
})
|
||||
}
|
||||
|
||||
export function searchCourse(data){
|
||||
return request({
|
||||
url:'/course/search',
|
||||
method:'POST',
|
||||
data
|
||||
})
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
import request from '@/utils/request`'
|
||||
|
||||
export function getFirstCategorys(){
|
||||
return request({
|
||||
url:'/course/category/getFirstCategorys'
|
||||
})
|
||||
}
|
||||
|
||||
export function getSecondCategorys(data){
|
||||
return request({
|
||||
url:'/course/category/getSecondCategorys',
|
||||
params:data
|
||||
})
|
||||
}
|
||||
|
||||
export function searchCourse(data){
|
||||
return request({
|
||||
url:'/course/search',
|
||||
method:'POST',
|
||||
data
|
||||
})
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import request from '@/utils/request`'
|
||||
import $http from '@/utils/request';
|
||||
export function getFirstCategorys(){
|
||||
return request({
|
||||
url:'/course/category/getFirstCategorys'
|
||||
})
|
||||
}
|
||||
|
||||
// export function getSecondCategorys(data){
|
||||
// return request({
|
||||
// url:'/course/category/getSecondCategorys',
|
||||
// params:data
|
||||
// })
|
||||
// }
|
||||
|
||||
export function searchCourse(data){
|
||||
return request({
|
||||
url:'/course/search',
|
||||
method:'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
export function getSecondCategorys(){
|
||||
return $http.get('/api/course/category/getSecondCategorys')
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
export function getFirstCategorys(){
|
||||
return request({
|
||||
url:'/course/category/getFirstCategorys'
|
||||
})
|
||||
}
|
||||
|
||||
export function getSecondCategorys( data ){
|
||||
return request({
|
||||
url:'/course/category/getSecondCategorys',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
export function tagsList(data){
|
||||
return request({
|
||||
url:'/course/tags/list',
|
||||
method:'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function search(data){
|
||||
return request({
|
||||
url:'/course/search',
|
||||
method:'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function getSliders(){
|
||||
return request({
|
||||
url:'/slider/getSliders'
|
||||
})
|
||||
}
|
||||
|
||||
export function mostNewCourse( data ){
|
||||
return request({
|
||||
url:'/course/mostNew',
|
||||
method:'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function getSetting(){
|
||||
return request({
|
||||
url:'/setting/get'
|
||||
})
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import $http from '@/utils/request';
|
||||
const API = {
|
||||
getdemo(arg) {
|
||||
return $http.get(`/smart/getdemo?currentPage=${arg.currentPage}&pageSize=${arg.pageSize}`);
|
||||
},
|
||||
get() {
|
||||
return $http.get(`/smart/getinfo?pageNo=1&pageSize=100`)
|
||||
},
|
||||
add(params) {
|
||||
return $http.post('/smart/send', params);
|
||||
},
|
||||
uploadfile(arg) {
|
||||
return $http.post(`/smart/upload`, arg)
|
||||
},
|
||||
downloadfile(params) {
|
||||
return $http.get(`/smart/download?fileId=${params.fileId}`, { responseType: 'blob', })
|
||||
},
|
||||
};
|
||||
export default API;
|
|
@ -0,0 +1,19 @@
|
|||
import $http from '@/utils/request';
|
||||
const API = {
|
||||
getdemo(arg) {
|
||||
return $http.get(`/api/getdemo?currentPage=${arg.currentPage}&pageSize=${arg.pageSize}`);
|
||||
},
|
||||
get() {
|
||||
return $http.get(`/api/getinfo?pageNo=1&pageSize=100`)
|
||||
},
|
||||
add(params) {
|
||||
return $http.post('/api/send', params);
|
||||
},
|
||||
uploadfile(arg) {
|
||||
return $http.post(`/api/upload`, arg)
|
||||
},
|
||||
downloadfile(params) {
|
||||
return $http.get(`/api/download?fileId=${params.fileId}`, { responseType: 'blob', })
|
||||
},
|
||||
};
|
||||
export default API;
|
|
@ -0,0 +1,22 @@
|
|||
import $http from '@/utils/request';
|
||||
const API = {
|
||||
getdemo(arg) {
|
||||
return $http.get(`/api/getdemo?currentPage=${arg.currentPage}&pageSize=${arg.pageSize}`);
|
||||
},
|
||||
get() {
|
||||
return $http.get(`/api/getinfo?pageNo=1&pageSize=100`)
|
||||
},
|
||||
add(params) {
|
||||
return $http.post('/api/send', params);
|
||||
},
|
||||
uploadfile(arg) {
|
||||
return $http.post(`/api/upload`, arg)
|
||||
},
|
||||
downloadfile(params) {
|
||||
return $http.get(`/api/download?fileId=${params.fileId}`, { responseType: 'blob', })
|
||||
},
|
||||
getShopCarList(){
|
||||
return $http.get('/api/shopcar/getShopCarList')
|
||||
}
|
||||
};
|
||||
export default API;
|
|
@ -0,0 +1,27 @@
|
|||
import $http from '@/utils/request';
|
||||
// const API = {
|
||||
// getdemo(arg) {
|
||||
// return $http.get(`/api/getdemo?currentPage=${arg.currentPage}&pageSize=${arg.pageSize}`);
|
||||
// },
|
||||
// get() {
|
||||
// return $http.get(`/api/getinfo?pageNo=1&pageSize=100`)
|
||||
// },
|
||||
// add(params) {
|
||||
// return $http.post('/api/send', params);
|
||||
// },
|
||||
// uploadfile(arg) {
|
||||
// return $http.post(`/api/upload`, arg)
|
||||
// },
|
||||
// downloadfile(params) {
|
||||
// return $http.get(`/api/download?fileId=${params.fileId}`, { responseType: 'blob', })
|
||||
// },
|
||||
// getShopCarList(){
|
||||
// return $http.get('/api/shopcar/getShopCarList')
|
||||
// }
|
||||
// };
|
||||
// export default API;
|
||||
export function getShopCarList(){
|
||||
return request({
|
||||
url:'/api/shopcar/getShopCarList'
|
||||
})
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import $http from '@/utils/request';
|
||||
// const API = {
|
||||
// getdemo(arg) {
|
||||
// return $http.get(`/api/getdemo?currentPage=${arg.currentPage}&pageSize=${arg.pageSize}`);
|
||||
// },
|
||||
// get() {
|
||||
// return $http.get(`/api/getinfo?pageNo=1&pageSize=100`)
|
||||
// },
|
||||
// add(params) {
|
||||
// return $http.post('/api/send', params);
|
||||
// },
|
||||
// uploadfile(arg) {
|
||||
// return $http.post(`/api/upload`, arg)
|
||||
// },
|
||||
// downloadfile(params) {
|
||||
// return $http.get(`/api/download?fileId=${params.fileId}`, { responseType: 'blob', })
|
||||
// },
|
||||
// getShopCarList(){
|
||||
// return $http.get('/api/shopcar/getShopCarList')
|
||||
// }
|
||||
// };
|
||||
// export default API;
|
||||
export function getShopCarList(){
|
||||
return $http.get('/api/shopcar/getShopCarList')
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import $http from '@/utils/request';
|
||||
// const API = {
|
||||
// getdemo(arg) {
|
||||
// return $http.get(`/api/getdemo?currentPage=${arg.currentPage}&pageSize=${arg.pageSize}`);
|
||||
// },
|
||||
// get() {
|
||||
// return $http.get(`/api/getinfo?pageNo=1&pageSize=100`)
|
||||
// },
|
||||
// add(params) {
|
||||
// return $http.post('/api/send', params);
|
||||
// },
|
||||
// uploadfile(arg) {
|
||||
// return $http.post(`/api/upload`, arg)
|
||||
// },
|
||||
// downloadfile(params) {
|
||||
// return $http.get(`/api/download?fileId=${params.fileId}`, { responseType: 'blob', })
|
||||
// },
|
||||
// getShopCarList(){
|
||||
// return $http.get('/api/shopcar/getShopCarList')
|
||||
// }
|
||||
// };
|
||||
// export default API;
|
||||
export function getShopCarList(){
|
||||
return $http.get('/api/shopcar/getShopCarList')
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import $http from '@/utils/request';
|
||||
// const API = {
|
||||
// getdemo(arg) {
|
||||
// return $http.get(`/api/getdemo?currentPage=${arg.currentPage}&pageSize=${arg.pageSize}`);
|
||||
// },
|
||||
// get() {
|
||||
// return $http.get(`/api/getinfo?pageNo=1&pageSize=100`)
|
||||
// },
|
||||
// add(params) {
|
||||
// return $http.post('/api/send', params);
|
||||
// },
|
||||
// uploadfile(arg) {
|
||||
// return $http.post(`/api/upload`, arg)
|
||||
// },
|
||||
// downloadfile(params) {
|
||||
// return $http.get(`/api/download?fileId=${params.fileId}`, { responseType: 'blob', })
|
||||
// },
|
||||
// getShopCarList(){
|
||||
// return $http.get('/api/shopcar/getShopCarList')
|
||||
// }
|
||||
// };
|
||||
// export default API;
|
||||
export function getShopCarList(){
|
||||
return $http.get('/api/shopcar/getShopCarList')
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
export function loginByJson(data){
|
||||
return request({
|
||||
url:'/u/loginByJson',
|
||||
method:'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function sendRegisterOrLoginCaptcha(params){
|
||||
return request({
|
||||
url:'/sms/sendRegisterOrLoginCaptcha',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function loginByMobile(data){
|
||||
return request({
|
||||
url:'/u/loginByMobile',
|
||||
method:'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function createToken(data){
|
||||
return request({
|
||||
url:'/token/createToken'
|
||||
})
|
||||
}
|
||||
|
||||
export function getInfo(params){
|
||||
return request({
|
||||
url:'/member/getInfo',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function logout(){
|
||||
return request({
|
||||
url:'/u/logout',
|
||||
})
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
import $http from '@/utils/request';
|
|
@ -0,0 +1,39 @@
|
|||
import $http from '@/utils/request';
|
||||
|
||||
export function loginByJson(data){
|
||||
return $http.get(`/api/getdemo?currentPage=${arg.currentPage}&pageSize=${arg.pageSize}`);
|
||||
}
|
||||
|
||||
export function sendRegisterOrLoginCaptcha(params){
|
||||
return request({
|
||||
url:'/sms/sendRegisterOrLoginCaptcha',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function loginByMobile(data){
|
||||
return request({
|
||||
url:'/u/loginByMobile',
|
||||
method:'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function createToken(data){
|
||||
return request({
|
||||
url:'/token/createToken'
|
||||
})
|
||||
}
|
||||
|
||||
export function getInfo(params){
|
||||
return request({
|
||||
url:'/member/getInfo',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function logout(){
|
||||
return request({
|
||||
url:'/u/logout',
|
||||
})
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
import $http from '@/utils/request';
|
||||
|
||||
export function loginByJson(arg){
|
||||
return $http.get(`/api/getdemo?currentPage=${arg.currentPage}&pageSize=${arg.pageSize}`);
|
||||
}
|
||||
|
||||
export function sendRegisterOrLoginCaptcha(params){
|
||||
return request({
|
||||
url:'/sms/sendRegisterOrLoginCaptcha',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function loginByMobile(data){
|
||||
return request({
|
||||
url:'/u/loginByMobile',
|
||||
method:'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function createToken(data){
|
||||
return request({
|
||||
url:'/token/createToken'
|
||||
})
|
||||
}
|
||||
|
||||
export function getInfo(params){
|
||||
return request({
|
||||
url:'/member/getInfo',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function logout(){
|
||||
return request({
|
||||
url:'/u/logout',
|
||||
})
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
import $http from '@/utils/request';
|
||||
|
||||
export function loginByJson(arg){
|
||||
return $http.get(`/api/getdemo?currentPage=${arg.currentPage}&pageSize=${arg.pageSize}`);
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function loginByMobile(params){
|
||||
return $http.post('/api/send', params);
|
||||
}
|
||||
|
||||
export function createToken(data){
|
||||
return request({
|
||||
url:'/token/createToken'
|
||||
})
|
||||
}
|
||||
|
||||
export function getInfo(params){
|
||||
return request({
|
||||
url:'/member/getInfo',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function logout(){
|
||||
return request({
|
||||
url:'/u/logout',
|
||||
})
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
import $http from '@/utils/request';
|
||||
|
||||
export function loginByJson(arg){
|
||||
return $http.get(`/api/getdemo?currentPage=${arg.currentPage}&pageSize=${arg.pageSize}`);
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function loginByMobile(params){
|
||||
return $http.post('/api/send', params);
|
||||
}
|
||||
|
||||
export function createToken(data){
|
||||
return $http.get(`/api/download?fileId=${params.fileId}`, { responseType: 'blob', })
|
||||
}
|
||||
|
||||
export function getInfo(params){
|
||||
return request({
|
||||
url:'/member/getInfo',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function logout(){
|
||||
return request({
|
||||
url:'/u/logout',
|
||||
})
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
import $http from '@/utils/request';
|
||||
|
||||
export function loginByJson(arg){
|
||||
return $http.get(`/api/getdemo?currentPage=${arg.currentPage}&pageSize=${arg.pageSize}`);
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function loginByMobile(params){
|
||||
return $http.post('/api/send', params);
|
||||
}
|
||||
|
||||
export function createToken(params){
|
||||
return $http.get(`/api/download?fileId=${params.fileId}`, { responseType: 'blob', })
|
||||
}
|
||||
|
||||
export function getInfo(params){
|
||||
return request({
|
||||
url:'/member/getInfo',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function logout(){
|
||||
return request({
|
||||
url:'/u/logout',
|
||||
})
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
import $http from '@/utils/request';
|
||||
|
||||
export function loginByJson(arg){
|
||||
return $http.get(`/api/getdemo?currentPage=${arg.currentPage}&pageSize=${arg.pageSize}`);
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function loginByMobile(params){
|
||||
return $http.post('/api/send', params);
|
||||
}
|
||||
|
||||
export function createToken(params){
|
||||
return $http.get(`/api/download?fileId=${params.fileId}`, { responseType: 'blob', })
|
||||
}
|
||||
|
||||
|
||||
export function logout(){
|
||||
return request({
|
||||
url:'/u/logout',
|
||||
})
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import $http from '@/utils/request';
|
||||
|
||||
export function loginByJson(arg){
|
||||
return $http.get(`/api/getdemo?currentPage=${arg.currentPage}&pageSize=${arg.pageSize}`);
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function loginByMobile(params){
|
||||
return $http.post('/api/send', params);
|
||||
}
|
||||
|
||||
export function createToken(params){
|
||||
return $http.get(`/api/download?fileId=${params.fileId}`, { responseType: 'blob', })
|
||||
}
|
||||
|
|
@ -0,0 +1,623 @@
|
|||
<template>
|
||||
<div class="coursemain">
|
||||
<div class="course-main">
|
||||
<section class="search-container">
|
||||
<div class="search-item">
|
||||
<div class="title-name">课程方向:</div>
|
||||
<div class="all-items">
|
||||
<el-tag
|
||||
:class="
|
||||
curryType['1'].id ? 'category-poniter-item' : 'category-poniter'
|
||||
"
|
||||
effect="plain"
|
||||
type="info"
|
||||
@click="handleAllData"
|
||||
>全部</el-tag
|
||||
>
|
||||
<el-tag
|
||||
:class="
|
||||
curryType['1'].id == item.id
|
||||
? 'category-poniter'
|
||||
: 'category-poniter-item'
|
||||
"
|
||||
effect="plain"
|
||||
type="info"
|
||||
v-for="item in courseFirstList"
|
||||
:key="item.id"
|
||||
@click="handleFirstItem('1', item.id)"
|
||||
>
|
||||
{{ item.categoryName }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-item search-item-transition" style="top: 45px">
|
||||
<div class="title-name">课程分类:</div>
|
||||
<div class="all-items">
|
||||
<el-tag
|
||||
:class="
|
||||
curryType['2'].id ? 'category-poniter-item' : 'category-poniter'
|
||||
"
|
||||
effect="plain"
|
||||
type="info"
|
||||
>全部</el-tag
|
||||
>
|
||||
<el-tag
|
||||
:class="
|
||||
curryType['2'].id == item.id
|
||||
? 'category-poniter'
|
||||
: 'category-poniter-item'
|
||||
"
|
||||
effect="plain"
|
||||
type="info"
|
||||
v-for="item in courseSecondList"
|
||||
:key="item.id"
|
||||
@click="handleFirstItem('2', item.id)"
|
||||
>
|
||||
{{ item.categoryName }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-item" style="top: 90px">
|
||||
<div class="title-name">课程难度:</div>
|
||||
<div class="all-items">
|
||||
<el-tag
|
||||
:class="
|
||||
curryType['3'].id ? 'category-poniter-item' : 'category-poniter'
|
||||
"
|
||||
effect="plain"
|
||||
type="info"
|
||||
>全部</el-tag
|
||||
>
|
||||
<el-tag
|
||||
:class="
|
||||
curryType['3'].id == item.code
|
||||
? 'category-poniter'
|
||||
: 'category-poniter-item'
|
||||
"
|
||||
effect="plain"
|
||||
type="info"
|
||||
v-for="item in courseThirdList"
|
||||
:key="item.code"
|
||||
@click="handleFirstItem('3', item.code)"
|
||||
>
|
||||
{{ item.name }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="main-container">
|
||||
<div class="container-top">
|
||||
<ul class="all">
|
||||
<li class="item">综合</li>
|
||||
<li class="item split">|</li>
|
||||
<li class="item">最新课程</li>
|
||||
<li class="item split">|</li>
|
||||
<li class="item">最多购买</li>
|
||||
<li class="item split">|</li>
|
||||
<li class="item-price">
|
||||
<span>价格</span>
|
||||
<span class="arrow">
|
||||
<el-icon><CaretTop /></el-icon>
|
||||
<el-icon><CaretBottom /></el-icon>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="right">
|
||||
<li class="right-item">
|
||||
<el-radio-group v-model="radio">
|
||||
<el-radio label="1">免费课程</el-radio>
|
||||
<el-radio label="2">会员课程</el-radio>
|
||||
</el-radio-group>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="container-body">
|
||||
<div class="newCourseContent">
|
||||
<ul class="courseUl">
|
||||
<li
|
||||
class="courseItem"
|
||||
v-for="item in courseSearchList"
|
||||
:key="item.id"
|
||||
>
|
||||
<router-link :to="'/CourseInfo/' + item.id">
|
||||
<div class="courseInfo">
|
||||
<div class="courseBg">
|
||||
<img :src="item.courseCover" />
|
||||
</div>
|
||||
<div class="courseName">{{ item.courseName }}</div>
|
||||
<div class="courseDegree">
|
||||
{{ courseTypeFn(item.courseLevel) }} ·
|
||||
{{ item.purchaseCounter + item.purchaseCnt }}人报名
|
||||
</div>
|
||||
<div class="coursePriceZero" v-if="item.discountPrice == 0">
|
||||
<div class="pricefree">免费学习</div>
|
||||
<img src="@/assets/img/logo1.jpg" alt="" />
|
||||
</div>
|
||||
<div class="coursePrice" v-else-if="item.isMember == 1">
|
||||
<div class="courseMemberbg">
|
||||
<span class="courseMember">会员免费</span>
|
||||
</div>
|
||||
<div class="price">¥ {{ item.discountPrice }}</div>
|
||||
</div>
|
||||
<div class="coursePricePri" v-else>
|
||||
<div class="pricePri">¥ {{ item.discountPrice }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="pages">
|
||||
<el-pagination
|
||||
background
|
||||
layout="prev, pager, next"
|
||||
:total="courseSearchListTotal"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
getFirstCategorys,
|
||||
getSecondCategorys,
|
||||
searchCourse,
|
||||
} from "@/api/Course/index";
|
||||
import mixins from "@/mixins/E2C.js";
|
||||
import { reactive } from "@vue/reactivity";
|
||||
import { computed, watch, watchEffect } from "@vue/runtime-core";
|
||||
import { CaretTop , CaretBottom} from "@element-plus/icons-vue";
|
||||
let { courseTypeFn } = mixins();
|
||||
|
||||
let CourseList = reactive({
|
||||
courseFirstList: [],
|
||||
courseSecondList: [],
|
||||
courseSearchList: [],
|
||||
courseThirdList: [
|
||||
{ name: "初级", code: "1" },
|
||||
{ name: "中级", code: "2" },
|
||||
{ name: "高级", code: "3" },
|
||||
],
|
||||
pageNum: 1,
|
||||
pageSize: 8,
|
||||
courseSearchListTotal: 0,
|
||||
entity: {
|
||||
firstCategory: "",
|
||||
secondCategory: "",
|
||||
courseLevel: "",
|
||||
isMember:"",
|
||||
isFree:'',
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
// entity:{
|
||||
// firstCategory:'', string 一级分类ID
|
||||
// secondCategory:'', string 二级分类ID
|
||||
// tags:'', string 知识点
|
||||
// isMember:'', string 会员课程(传1)
|
||||
// isFree:'', string 免费课程(传1)
|
||||
// courseLevel:'', string 课程等级(1:初级;2:中级;3:高级)
|
||||
// sortBy:'', string 排序方式(1:点击量倒序:clicks-desc;2:点击量正序:clicks-asc;3:时间倒序:time-desc;4:时间正序:time-asc;5:售价倒序:price-desc;6:售价正序:price-asc;7:购买数倒序:purchase-desc;6:购买数正序:purchase-asc)
|
||||
// }
|
||||
|
||||
let {
|
||||
courseFirstList,
|
||||
courseSecondList,
|
||||
courseThirdList,
|
||||
pageNum,
|
||||
pageSize,
|
||||
courseSearchList,
|
||||
courseSearchListTotal,
|
||||
entity,
|
||||
} = toRefs(CourseList);
|
||||
|
||||
// 封装多次调用接口的方法
|
||||
const querySearchCourse = async (pageNum, pageSize, entity) => {
|
||||
const res = await searchCourse({
|
||||
pageNum,
|
||||
pageSize,
|
||||
entity,
|
||||
});
|
||||
courseSearchList.value = res.data.pageInfo.list;
|
||||
courseSearchListTotal.value = res.data.pageInfo.total;
|
||||
};
|
||||
|
||||
let secondCategorysParams = reactive({
|
||||
categoryId: -1,
|
||||
});
|
||||
|
||||
const getSecondCategorysFn = async (params) => {
|
||||
const res = await getSecondCategorys(params);
|
||||
courseSecondList.value = res.data.list;
|
||||
};
|
||||
|
||||
onBeforeMount(async () => {
|
||||
const res = await getFirstCategorys();
|
||||
courseFirstList.value = res.data.list;
|
||||
getSecondCategorysFn(secondCategorysParams);
|
||||
querySearchCourse(pageNum.value, pageSize.value);
|
||||
});
|
||||
|
||||
let curryType = reactive({
|
||||
1: {
|
||||
id: "",
|
||||
},
|
||||
2: {
|
||||
id: "",
|
||||
},
|
||||
3: {
|
||||
id: "",
|
||||
},
|
||||
});
|
||||
|
||||
const handleAllData = async () => {
|
||||
const res = await getFirstCategorys();
|
||||
courseFirstList.value = res.data.list;
|
||||
getSecondCategorysFn(secondCategorysParams);
|
||||
querySearchCourse(pageNum.value, pageSize.value);
|
||||
curryType['1'].id = ''
|
||||
}
|
||||
|
||||
const handleFirstItem = async (type, id) => {
|
||||
if (type == 1) {
|
||||
entity.value.isFree = ''
|
||||
entity.value.isMember = ''
|
||||
radio.value = '0'
|
||||
curryType[type].id = id;
|
||||
curryType["2"].id = "";
|
||||
curryType["3"].id = "";
|
||||
entity.value.secondCategory = "";
|
||||
entity.value.courseLevel = "";
|
||||
secondCategorysParams.categoryId = id;
|
||||
getSecondCategorysFn(secondCategorysParams);
|
||||
entity.value.firstCategory = id;
|
||||
querySearchCourse(pageNum.value, pageSize.value, entity.value);
|
||||
return;
|
||||
}
|
||||
if (type == 2) {
|
||||
entity.value.isFree = ''
|
||||
entity.value.isMember = ''
|
||||
radio.value = '0'
|
||||
curryType["3"].id = "";
|
||||
curryType[type].id = id;
|
||||
entity.value.courseLevel = "";
|
||||
entity.value.secondCategory = id;
|
||||
querySearchCourse(pageNum.value, pageSize.value, entity.value);
|
||||
return;
|
||||
}
|
||||
if (type == 3) {
|
||||
entity.value.isFree = ''
|
||||
entity.value.isMember = ''
|
||||
radio.value = '0'
|
||||
curryType[type].id = id;
|
||||
entity.value.courseLevel = id;
|
||||
querySearchCourse(pageNum.value, pageSize.value, entity.value);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
const handleCurrentChange = (e) => {
|
||||
pageNum.value = e;
|
||||
querySearchCourse(pageNum.value, pageSize.value);
|
||||
};
|
||||
|
||||
let radio = ref('0')
|
||||
|
||||
watch(radio, (n,o)=>{
|
||||
console.log(n);
|
||||
console.log(o);
|
||||
})
|
||||
|
||||
watchEffect(()=>{
|
||||
if(radio.value == '1'){
|
||||
entity.value.isFree = 1
|
||||
entity.value.isMember = ''
|
||||
}else if(radio.value == '2'){
|
||||
entity.value.isFree = ''
|
||||
entity.value.isMember = 1
|
||||
}
|
||||
querySearchCourse(pageNum.value, pageSize.value,entity.value)
|
||||
})
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.course-main {
|
||||
padding: 20px 0;
|
||||
width: 100%;
|
||||
height: 130px;
|
||||
background: #f3f5f9;
|
||||
}
|
||||
.search-container {
|
||||
width: 1200px;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
.search-item {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
height: 45px;
|
||||
transition: all 0.5s;
|
||||
}
|
||||
.search-item-transition:hover {
|
||||
z-index: 777;
|
||||
height: auto;
|
||||
box-shadow: rgb(95 101 105 / 10%) 0px 12px 20px 0px;
|
||||
border-radius: 8px;
|
||||
background: rgba(255, 255, 255);
|
||||
}
|
||||
.search-item .title-name {
|
||||
width: 100px;
|
||||
font-size: 16px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: bold;
|
||||
line-height: 25px;
|
||||
text-align: justify;
|
||||
color: #333333;
|
||||
padding: 10px;
|
||||
opacity: 1;
|
||||
}
|
||||
.search-item .title-name:after {
|
||||
content: ".";
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.search-item .all-items {
|
||||
width: calc(100% - 120px);
|
||||
min-height: 25px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.title .all-list {
|
||||
width: 40px;
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
border-radius: 4px;
|
||||
padding: 0 10px;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title .all {
|
||||
opacity: 1;
|
||||
color: #2c80ff;
|
||||
}
|
||||
|
||||
.title .item {
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
margin: 0 15px;
|
||||
font-size: 16px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
line-height: 21px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.title .item .active {
|
||||
color: #2c80ff;
|
||||
}
|
||||
|
||||
.category-poniter {
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
margin: 10px 5px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
background: rgba(44, 128, 255, 0.1);
|
||||
color: #2c80ff;
|
||||
}
|
||||
.category-poniter-item {
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
margin: 10px 5px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
background: none;
|
||||
color: rgba(81, 87, 89, 1);
|
||||
}
|
||||
|
||||
.main-container {
|
||||
width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.container-top {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.all {
|
||||
display: flex;
|
||||
padding-top: 20px;
|
||||
font-size: 16px;
|
||||
color: #515759;
|
||||
}
|
||||
|
||||
.all .item:first-child {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.all .item {
|
||||
margin: 0 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
padding-top: 20px;
|
||||
font-size: 16px;
|
||||
color: #515759;
|
||||
}
|
||||
|
||||
.right .right-item {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.right .right-items {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.arrow i:first-child {
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
.arrow i:last-child {
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
}
|
||||
|
||||
.check {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.up {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 2px;
|
||||
}
|
||||
|
||||
.down {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
left: 2px;
|
||||
transform: rotate(180deg);
|
||||
-ms-transform: rotate(180deg); /* IE 9 */
|
||||
-moz-transform: rotate(180deg); /* Firefox */
|
||||
-webkit-transform: rotate(180deg); /* Safari 和 Chrome */
|
||||
-o-transform: rotate(180deg); /* Opera */
|
||||
}
|
||||
.newCourseContent {
|
||||
width: 1200px;
|
||||
margin: 30px auto 0px auto;
|
||||
}
|
||||
|
||||
.newCourseContent .courseUl {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.courseItem {
|
||||
width: 285px;
|
||||
height: 280px;
|
||||
margin: 0 20px 20px 0;
|
||||
transition: margin-top 0.2s;
|
||||
}
|
||||
.courseItem:hover {
|
||||
margin-top: -10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.courseItem:nth-child(4n + 0) {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
.courseInfo {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 270px;
|
||||
background: #ffffff;
|
||||
box-shadow: 1px 1px 10px rgb(27 39 94 / 40%);
|
||||
opacity: 1;
|
||||
border-bottom-left-radius: 6px;
|
||||
border-bottom-right-radius: 6px;
|
||||
overflow: hidden;
|
||||
text-decoration: none;
|
||||
}
|
||||
.courseBg {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 160px;
|
||||
}
|
||||
.courseBg img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.courseName {
|
||||
margin: 10px;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
color: #333333;
|
||||
display: -webkit-box;
|
||||
overflow: hidden;
|
||||
}
|
||||
.courseDegree {
|
||||
margin-left: 10px;
|
||||
font-size: 12px;
|
||||
color: #808080;
|
||||
}
|
||||
.coursePrice {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
width: 130px;
|
||||
font-size: 14px;
|
||||
margin-top: 15px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
.coursePricePri {
|
||||
width: 75px;
|
||||
font-size: 14px;
|
||||
margin-top: 18px;
|
||||
padding: 0 13px;
|
||||
color: rgba(255, 114, 127, 1);
|
||||
font-weight: 700;
|
||||
}
|
||||
.coursePriceZero {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 75px;
|
||||
font-size: 14px;
|
||||
margin-top: 15px;
|
||||
padding: 0 10px;
|
||||
color: rgba(53, 134, 255, 1);
|
||||
}
|
||||
.courseMemberbg {
|
||||
position: relative;
|
||||
width: 80px;
|
||||
height: 20px;
|
||||
color: #ffffff;
|
||||
background: linear-gradient(90deg, #ff928e 0%, #fe7062 99%);
|
||||
border-radius: 24px 0px 24px 0px;
|
||||
}
|
||||
.courseMember {
|
||||
position: absolute;
|
||||
line-height: 20px;
|
||||
left: 13px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.price {
|
||||
line-height: 25px;
|
||||
left: 100px;
|
||||
color: #ff727f;
|
||||
font-weight: 700;
|
||||
}
|
||||
.pages {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 50px auto !important;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,624 @@
|
|||
<template>
|
||||
<div class="coursemain">
|
||||
<div class="course-main">
|
||||
<section class="search-container">
|
||||
<div class="search-item">
|
||||
<div class="title-name">课程方向:</div>
|
||||
<div class="all-items">
|
||||
<el-tag
|
||||
:class="
|
||||
curryType['1'].id ? 'category-poniter-item' : 'category-poniter'
|
||||
"
|
||||
effect="plain"
|
||||
type="info"
|
||||
@click="handleAllData"
|
||||
>全部</el-tag
|
||||
>
|
||||
<el-tag
|
||||
:class="
|
||||
curryType['1'].id == item.id
|
||||
? 'category-poniter'
|
||||
: 'category-poniter-item'
|
||||
"
|
||||
effect="plain"
|
||||
type="info"
|
||||
v-for="item in courseFirstList"
|
||||
:key="item.id"
|
||||
@click="handleFirstItem('1', item.id)"
|
||||
>
|
||||
{{ item.categoryName }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-item search-item-transition" style="top: 45px">
|
||||
<div class="title-name">课程分类:</div>
|
||||
<div class="all-items">
|
||||
<el-tag
|
||||
:class="
|
||||
curryType['2'].id ? 'category-poniter-item' : 'category-poniter'
|
||||
"
|
||||
effect="plain"
|
||||
type="info"
|
||||
>全部</el-tag
|
||||
>
|
||||
<el-tag
|
||||
:class="
|
||||
curryType['2'].id == item.id
|
||||
? 'category-poniter'
|
||||
: 'category-poniter-item'
|
||||
"
|
||||
effect="plain"
|
||||
type="info"
|
||||
v-for="item in courseSecondList"
|
||||
:key="item.id"
|
||||
@click="handleFirstItem('2', item.id)"
|
||||
>
|
||||
{{ item.categoryName }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-item" style="top: 90px">
|
||||
<div class="title-name">课程难度:</div>
|
||||
<div class="all-items">
|
||||
<el-tag
|
||||
:class="
|
||||
curryType['3'].id ? 'category-poniter-item' : 'category-poniter'
|
||||
"
|
||||
effect="plain"
|
||||
type="info"
|
||||
>全部</el-tag
|
||||
>
|
||||
<el-tag
|
||||
:class="
|
||||
curryType['3'].id == item.code
|
||||
? 'category-poniter'
|
||||
: 'category-poniter-item'
|
||||
"
|
||||
effect="plain"
|
||||
type="info"
|
||||
v-for="item in courseThirdList"
|
||||
:key="item.code"
|
||||
@click="handleFirstItem('3', item.code)"
|
||||
>
|
||||
{{ item.name }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="main-container">
|
||||
<div class="container-top">
|
||||
<ul class="all">
|
||||
<li class="item">综合</li>
|
||||
<li class="item split">|</li>
|
||||
<li class="item">最新课程</li>
|
||||
<li class="item split">|</li>
|
||||
<li class="item">最多购买</li>
|
||||
<li class="item split">|</li>
|
||||
<li class="item-price">
|
||||
<span>价格</span>
|
||||
<span class="arrow">
|
||||
<el-icon><CaretTop /></el-icon>
|
||||
<el-icon><CaretBottom /></el-icon>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="right">
|
||||
<li class="right-item">
|
||||
<el-radio-group v-model="radio">
|
||||
<el-radio label="1">免费课程</el-radio>
|
||||
<el-radio label="2">会员课程</el-radio>
|
||||
</el-radio-group>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="container-body">
|
||||
<div class="newCourseContent">
|
||||
<ul class="courseUl">
|
||||
<li
|
||||
class="courseItem"
|
||||
v-for="item in courseSearchList"
|
||||
:key="item.id"
|
||||
>
|
||||
<router-link :to="'/CourseInfo/' + item.id">
|
||||
<div class="courseInfo">
|
||||
<div class="courseBg">
|
||||
<img :src="item.courseCover" />
|
||||
</div>
|
||||
<div class="courseName">{{ item.courseName }}</div>
|
||||
<div class="courseDegree">
|
||||
{{ courseTypeFn(item.courseLevel) }} ·
|
||||
{{ item.purchaseCounter + item.purchaseCnt }}人报名
|
||||
</div>
|
||||
<div class="coursePriceZero" v-if="item.discountPrice == 0">
|
||||
<div class="pricefree">免费学习</div>
|
||||
<img src="@/assets/img/logo1.jpg" alt="" />
|
||||
</div>
|
||||
<div class="coursePrice" v-else-if="item.isMember == 1">
|
||||
<div class="courseMemberbg">
|
||||
<span class="courseMember">会员免费</span>
|
||||
</div>
|
||||
<div class="price">¥ {{ item.discountPrice }}</div>
|
||||
</div>
|
||||
<div class="coursePricePri" v-else>
|
||||
<div class="pricePri">¥ {{ item.discountPrice }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="pages">
|
||||
<el-pagination
|
||||
background
|
||||
layout="prev, pager, next"
|
||||
:total="courseSearchListTotal"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
getFirstCategorys,
|
||||
getSecondCategorys,
|
||||
searchCourse,
|
||||
} from "@/api/Course/index";
|
||||
import mixins from "@/mixins/E2C.js";
|
||||
import { reactive } from "@vue/reactivity";
|
||||
import { computed, watch, watchEffect } from "@vue/runtime-core";
|
||||
import { CaretTop , CaretBottom} from "@element-plus/icons-vue";
|
||||
let { courseTypeFn } = mixins();
|
||||
|
||||
let CourseList = reactive({
|
||||
courseFirstList: [],
|
||||
courseSecondList: [],
|
||||
courseSearchList: [],
|
||||
courseThirdList: [
|
||||
{ name: "初级", code: "1" },
|
||||
{ name: "中级", code: "2" },
|
||||
{ name: "高级", code: "3" },
|
||||
],
|
||||
pageNum: 1,
|
||||
pageSize: 8,
|
||||
courseSearchListTotal: 0,
|
||||
entity: {
|
||||
firstCategory: "",
|
||||
secondCategory: "",
|
||||
courseLevel: "",
|
||||
isMember:"",
|
||||
isFree:'',
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
// entity:{
|
||||
// firstCategory:'', string 一级分类ID
|
||||
// secondCategory:'', string 二级分类ID
|
||||
// tags:'', string 知识点
|
||||
// isMember:'', string 会员课程(传1)
|
||||
// isFree:'', string 免费课程(传1)
|
||||
// courseLevel:'', string 课程等级(1:初级;2:中级;3:高级)
|
||||
// sortBy:'', string 排序方式(1:点击量倒序:clicks-desc;2:点击量正序:clicks-asc;3:时间倒序:time-desc;4:时间正序:time-asc;5:售价倒序:price-desc;6:售价正序:price-asc;7:购买数倒序:purchase-desc;6:购买数正序:purchase-asc)
|
||||
// }
|
||||
|
||||
let {
|
||||
courseFirstList,
|
||||
courseSecondList,
|
||||
courseThirdList,
|
||||
pageNum,
|
||||
pageSize,
|
||||
courseSearchList,
|
||||
courseSearchListTotal,
|
||||
entity,
|
||||
} = toRefs(CourseList);
|
||||
|
||||
// 封装多次调用接口的方法
|
||||
const querySearchCourse = async (pageNum, pageSize, entity) => {
|
||||
const res = await searchCourse({
|
||||
pageNum,
|
||||
pageSize,
|
||||
entity,
|
||||
});
|
||||
courseSearchList.value = res.data.pageInfo.list;
|
||||
courseSearchListTotal.value = res.data.pageInfo.total;
|
||||
};
|
||||
|
||||
let secondCategorysParams = reactive({
|
||||
categoryId: -1,
|
||||
});
|
||||
|
||||
const getSecondCategorysFn = async (params) => {
|
||||
const res = await getSecondCategorys(params);
|
||||
courseSecondList.value = res.data.list;
|
||||
};
|
||||
|
||||
onBeforeMount(async () => {
|
||||
const res = await getFirstCategorys();
|
||||
console.log(res,"res")
|
||||
courseFirstList.value = res.data.list;
|
||||
getSecondCategorysFn(secondCategorysParams);
|
||||
querySearchCourse(pageNum.value, pageSize.value);
|
||||
});
|
||||
|
||||
let curryType = reactive({
|
||||
1: {
|
||||
id: "",
|
||||
},
|
||||
2: {
|
||||
id: "",
|
||||
},
|
||||
3: {
|
||||
id: "",
|
||||
},
|
||||
});
|
||||
|
||||
const handleAllData = async () => {
|
||||
const res = await getFirstCategorys();
|
||||
courseFirstList.value = res.data.list;
|
||||
getSecondCategorysFn(secondCategorysParams);
|
||||
querySearchCourse(pageNum.value, pageSize.value);
|
||||
curryType['1'].id = ''
|
||||
}
|
||||
|
||||
const handleFirstItem = async (type, id) => {
|
||||
if (type == 1) {
|
||||
entity.value.isFree = ''
|
||||
entity.value.isMember = ''
|
||||
radio.value = '0'
|
||||
curryType[type].id = id;
|
||||
curryType["2"].id = "";
|
||||
curryType["3"].id = "";
|
||||
entity.value.secondCategory = "";
|
||||
entity.value.courseLevel = "";
|
||||
secondCategorysParams.categoryId = id;
|
||||
getSecondCategorysFn(secondCategorysParams);
|
||||
entity.value.firstCategory = id;
|
||||
querySearchCourse(pageNum.value, pageSize.value, entity.value);
|
||||
return;
|
||||
}
|
||||
if (type == 2) {
|
||||
entity.value.isFree = ''
|
||||
entity.value.isMember = ''
|
||||
radio.value = '0'
|
||||
curryType["3"].id = "";
|
||||
curryType[type].id = id;
|
||||
entity.value.courseLevel = "";
|
||||
entity.value.secondCategory = id;
|
||||
querySearchCourse(pageNum.value, pageSize.value, entity.value);
|
||||
return;
|
||||
}
|
||||
if (type == 3) {
|
||||
entity.value.isFree = ''
|
||||
entity.value.isMember = ''
|
||||
radio.value = '0'
|
||||
curryType[type].id = id;
|
||||
entity.value.courseLevel = id;
|
||||
querySearchCourse(pageNum.value, pageSize.value, entity.value);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
const handleCurrentChange = (e) => {
|
||||
pageNum.value = e;
|
||||
querySearchCourse(pageNum.value, pageSize.value);
|
||||
};
|
||||
|
||||
let radio = ref('0')
|
||||
|
||||
watch(radio, (n,o)=>{
|
||||
console.log(n);
|
||||
console.log(o);
|
||||
})
|
||||
|
||||
watchEffect(()=>{
|
||||
if(radio.value == '1'){
|
||||
entity.value.isFree = 1
|
||||
entity.value.isMember = ''
|
||||
}else if(radio.value == '2'){
|
||||
entity.value.isFree = ''
|
||||
entity.value.isMember = 1
|
||||
}
|
||||
querySearchCourse(pageNum.value, pageSize.value,entity.value)
|
||||
})
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.course-main {
|
||||
padding: 20px 0;
|
||||
width: 100%;
|
||||
height: 130px;
|
||||
background: #f3f5f9;
|
||||
}
|
||||
.search-container {
|
||||
width: 1200px;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
.search-item {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
height: 45px;
|
||||
transition: all 0.5s;
|
||||
}
|
||||
.search-item-transition:hover {
|
||||
z-index: 777;
|
||||
height: auto;
|
||||
box-shadow: rgb(95 101 105 / 10%) 0px 12px 20px 0px;
|
||||
border-radius: 8px;
|
||||
background: rgba(255, 255, 255);
|
||||
}
|
||||
.search-item .title-name {
|
||||
width: 100px;
|
||||
font-size: 16px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: bold;
|
||||
line-height: 25px;
|
||||
text-align: justify;
|
||||
color: #333333;
|
||||
padding: 10px;
|
||||
opacity: 1;
|
||||
}
|
||||
.search-item .title-name:after {
|
||||
content: ".";
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.search-item .all-items {
|
||||
width: calc(100% - 120px);
|
||||
min-height: 25px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.title .all-list {
|
||||
width: 40px;
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
border-radius: 4px;
|
||||
padding: 0 10px;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title .all {
|
||||
opacity: 1;
|
||||
color: #2c80ff;
|
||||
}
|
||||
|
||||
.title .item {
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
margin: 0 15px;
|
||||
font-size: 16px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
line-height: 21px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.title .item .active {
|
||||
color: #2c80ff;
|
||||
}
|
||||
|
||||
.category-poniter {
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
margin: 10px 5px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
background: rgba(44, 128, 255, 0.1);
|
||||
color: #2c80ff;
|
||||
}
|
||||
.category-poniter-item {
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
margin: 10px 5px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
background: none;
|
||||
color: rgba(81, 87, 89, 1);
|
||||
}
|
||||
|
||||
.main-container {
|
||||
width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.container-top {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.all {
|
||||
display: flex;
|
||||
padding-top: 20px;
|
||||
font-size: 16px;
|
||||
color: #515759;
|
||||
}
|
||||
|
||||
.all .item:first-child {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.all .item {
|
||||
margin: 0 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
padding-top: 20px;
|
||||
font-size: 16px;
|
||||
color: #515759;
|
||||
}
|
||||
|
||||
.right .right-item {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.right .right-items {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.arrow i:first-child {
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
.arrow i:last-child {
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
}
|
||||
|
||||
.check {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.up {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 2px;
|
||||
}
|
||||
|
||||
.down {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
left: 2px;
|
||||
transform: rotate(180deg);
|
||||
-ms-transform: rotate(180deg); /* IE 9 */
|
||||
-moz-transform: rotate(180deg); /* Firefox */
|
||||
-webkit-transform: rotate(180deg); /* Safari 和 Chrome */
|
||||
-o-transform: rotate(180deg); /* Opera */
|
||||
}
|
||||
.newCourseContent {
|
||||
width: 1200px;
|
||||
margin: 30px auto 0px auto;
|
||||
}
|
||||
|
||||
.newCourseContent .courseUl {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.courseItem {
|
||||
width: 285px;
|
||||
height: 280px;
|
||||
margin: 0 20px 20px 0;
|
||||
transition: margin-top 0.2s;
|
||||
}
|
||||
.courseItem:hover {
|
||||
margin-top: -10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.courseItem:nth-child(4n + 0) {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
.courseInfo {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 270px;
|
||||
background: #ffffff;
|
||||
box-shadow: 1px 1px 10px rgb(27 39 94 / 40%);
|
||||
opacity: 1;
|
||||
border-bottom-left-radius: 6px;
|
||||
border-bottom-right-radius: 6px;
|
||||
overflow: hidden;
|
||||
text-decoration: none;
|
||||
}
|
||||
.courseBg {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 160px;
|
||||
}
|
||||
.courseBg img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.courseName {
|
||||
margin: 10px;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
color: #333333;
|
||||
display: -webkit-box;
|
||||
overflow: hidden;
|
||||
}
|
||||
.courseDegree {
|
||||
margin-left: 10px;
|
||||
font-size: 12px;
|
||||
color: #808080;
|
||||
}
|
||||
.coursePrice {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
width: 130px;
|
||||
font-size: 14px;
|
||||
margin-top: 15px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
.coursePricePri {
|
||||
width: 75px;
|
||||
font-size: 14px;
|
||||
margin-top: 18px;
|
||||
padding: 0 13px;
|
||||
color: rgba(255, 114, 127, 1);
|
||||
font-weight: 700;
|
||||
}
|
||||
.coursePriceZero {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 75px;
|
||||
font-size: 14px;
|
||||
margin-top: 15px;
|
||||
padding: 0 10px;
|
||||
color: rgba(53, 134, 255, 1);
|
||||
}
|
||||
.courseMemberbg {
|
||||
position: relative;
|
||||
width: 80px;
|
||||
height: 20px;
|
||||
color: #ffffff;
|
||||
background: linear-gradient(90deg, #ff928e 0%, #fe7062 99%);
|
||||
border-radius: 24px 0px 24px 0px;
|
||||
}
|
||||
.courseMember {
|
||||
position: absolute;
|
||||
line-height: 20px;
|
||||
left: 13px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.price {
|
||||
line-height: 25px;
|
||||
left: 100px;
|
||||
color: #ff727f;
|
||||
font-weight: 700;
|
||||
}
|
||||
.pages {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 50px auto !important;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,55 @@
|
|||
import { createRouter, createWebHistory } from "vue-router";
|
||||
import { useUserStore } from '@/store/user'
|
||||
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: "/",
|
||||
name: "Home",
|
||||
component: () =>import(/* webpackChunkName: "home" */ "../views/Home.vue"),
|
||||
},
|
||||
{
|
||||
path: "/Course",
|
||||
name: "Course",
|
||||
component: () =>import(/* webpackChunkName: "about" */ "../views/Course.vue"),
|
||||
},
|
||||
{
|
||||
path: "/CourseInfo/:id",
|
||||
name: "CourseInfo",
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "CourseInfo" */ "../views/CourseInfo.vue"),
|
||||
},
|
||||
{
|
||||
path: "/Login",
|
||||
name: "Login",
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "Login" */ "../views/Login.vue"),
|
||||
},
|
||||
{
|
||||
path:'/course-play',
|
||||
name:'course-play',
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "CoursePlay" */ "../views/CoursePlay.vue"),
|
||||
},
|
||||
{
|
||||
path:'/cart',
|
||||
name:'Cart',
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "CoursePlay" */ "../views/Cart.vue"),
|
||||
beforeEnter: (to, from, next) => {
|
||||
if( useUserStore().token ){
|
||||
next()
|
||||
}else {
|
||||
next('/login')
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
});
|
||||
|
||||
export default router;
|
|
@ -0,0 +1,33 @@
|
|||
import { createRouter, createWebHistory } from "vue-router";
|
||||
import { useUserStore } from '@/store/user'
|
||||
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: "/",
|
||||
name: "Home",
|
||||
component: () =>import(/* webpackChunkName: "home" */ "../views/Home.vue"),
|
||||
},
|
||||
|
||||
// {
|
||||
// path:'/cart',
|
||||
// name:'Cart',
|
||||
// component: () =>
|
||||
// import(/* webpackChunkName: "CoursePlay" */ "../views/Cart.vue"),
|
||||
// beforeEnter: (to, from, next) => {
|
||||
// if( useUserStore().token ){
|
||||
// next()
|
||||
// }else {
|
||||
// next('/login')
|
||||
// }
|
||||
|
||||
// }
|
||||
// },
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
});
|
||||
|
||||
export default router;
|
|
@ -0,0 +1,7 @@
|
|||
import { createPinia } from 'pinia'
|
||||
import piniaPluginPersist from 'pinia-plugin-persist'
|
||||
|
||||
const store = createPinia()
|
||||
store.use(piniaPluginPersist)
|
||||
|
||||
export default store
|
|
@ -0,0 +1,8 @@
|
|||
import { createPinia } from 'pinia'
|
||||
import piniaPluginPersist from 'pinia-plugin-persist'
|
||||
|
||||
const store = createPinia()
|
||||
// 使用持久化插件
|
||||
store.use(piniaPluginPersist)
|
||||
|
||||
export default store
|
|
@ -0,0 +1,42 @@
|
|||
import Vue from 'vue';
|
||||
import axios from 'axios';
|
||||
|
||||
Vue.prototype.axios = axios;
|
||||
// 创建axios实例
|
||||
const $axios = axios.create();
|
||||
$axios.defaults.timeout = 1000 * 50; // 请求超时时间
|
||||
|
||||
// request拦截器
|
||||
$axios.interceptors.request.use(config => {
|
||||
if (sessionStorage.getItem('token')) {
|
||||
config.headers.Authorization = sessionStorage.getItem('token')
|
||||
}
|
||||
if (navigator.userAgent.indexOf('Trident') != -1) {
|
||||
if (config.method == 'post') {
|
||||
config.data = {
|
||||
...config.data,
|
||||
t: Date.now()
|
||||
};
|
||||
} else if (config.method == 'get') {
|
||||
config.params = {
|
||||
...config.params,
|
||||
t: Date.now()
|
||||
};
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}, error => {
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
// respone 拦截器
|
||||
$axios.interceptors.response.use(
|
||||
response => {
|
||||
return response;
|
||||
},
|
||||
error => {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default $axios;
|
|
@ -0,0 +1,41 @@
|
|||
import Vue from 'vue';
|
||||
import axios from 'axios';
|
||||
Vue.prototype.axios = axios;
|
||||
// 创建axios实例
|
||||
const $axios = axios.create();
|
||||
$axios.defaults.timeout = 1000 * 50; // 请求超时时间
|
||||
|
||||
// request拦截器
|
||||
$axios.interceptors.request.use(config => {
|
||||
if (sessionStorage.getItem('token')) {
|
||||
config.headers.Authorization = sessionStorage.getItem('token')
|
||||
}
|
||||
if (navigator.userAgent.indexOf('Trident') != -1) {
|
||||
if (config.method == 'post') {
|
||||
config.data = {
|
||||
...config.data,
|
||||
t: Date.now()
|
||||
};
|
||||
} else if (config.method == 'get') {
|
||||
config.params = {
|
||||
...config.params,
|
||||
t: Date.now()
|
||||
};
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}, error => {
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
// respone 拦截器
|
||||
$axios.interceptors.response.use(
|
||||
response => {
|
||||
return response;
|
||||
},
|
||||
error => {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default $axios;
|
|
@ -0,0 +1,41 @@
|
|||
// import Vue from 'vue';
|
||||
import axios from 'axios';
|
||||
Vue.prototype.axios = axios;
|
||||
// 创建axios实例
|
||||
const $axios = axios.create();
|
||||
$axios.defaults.timeout = 1000 * 50; // 请求超时时间
|
||||
|
||||
// request拦截器
|
||||
$axios.interceptors.request.use(config => {
|
||||
if (sessionStorage.getItem('token')) {
|
||||
config.headers.Authorization = sessionStorage.getItem('token')
|
||||
}
|
||||
if (navigator.userAgent.indexOf('Trident') != -1) {
|
||||
if (config.method == 'post') {
|
||||
config.data = {
|
||||
...config.data,
|
||||
t: Date.now()
|
||||
};
|
||||
} else if (config.method == 'get') {
|
||||
config.params = {
|
||||
...config.params,
|
||||
t: Date.now()
|
||||
};
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}, error => {
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
// respone 拦截器
|
||||
$axios.interceptors.response.use(
|
||||
response => {
|
||||
return response;
|
||||
},
|
||||
error => {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default $axios;
|
|
@ -0,0 +1,41 @@
|
|||
// import Vue from 'vue';
|
||||
import axios from 'axios';
|
||||
// Vue.prototype.axios = axios;
|
||||
// 创建axios实例
|
||||
const $axios = axios.create();
|
||||
$axios.defaults.timeout = 1000 * 50; // 请求超时时间
|
||||
|
||||
// request拦截器
|
||||
$axios.interceptors.request.use(config => {
|
||||
if (sessionStorage.getItem('token')) {
|
||||
config.headers.Authorization = sessionStorage.getItem('token')
|
||||
}
|
||||
if (navigator.userAgent.indexOf('Trident') != -1) {
|
||||
if (config.method == 'post') {
|
||||
config.data = {
|
||||
...config.data,
|
||||
t: Date.now()
|
||||
};
|
||||
} else if (config.method == 'get') {
|
||||
config.params = {
|
||||
...config.params,
|
||||
t: Date.now()
|
||||
};
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}, error => {
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
// respone 拦截器
|
||||
$axios.interceptors.response.use(
|
||||
response => {
|
||||
return response;
|
||||
},
|
||||
error => {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default $axios;
|
|
@ -0,0 +1,96 @@
|
|||
import $axios from '@/utils/axios';
|
||||
// import server from './server.config';
|
||||
import Qs from 'qs';
|
||||
import {
|
||||
Message
|
||||
} from 'element-ui';
|
||||
import router from '@/router/index';
|
||||
/**
|
||||
* code为非1000是抛错 可结合自己业务进行修改
|
||||
*
|
||||
* **/
|
||||
const dealResponse = function (response, resolve) {
|
||||
let res = response.data;
|
||||
if (res.code) {
|
||||
if (res.code === 1000 || res.code === 200) {
|
||||
resolve(res);
|
||||
} else if (res.code === 401) {
|
||||
Message({
|
||||
type: 'error',
|
||||
message: `['尚未登录授权或授权过期,请登录']`
|
||||
});
|
||||
router.replace({
|
||||
path: '/login'
|
||||
});
|
||||
resolve(res);
|
||||
} else {
|
||||
Message({
|
||||
type: 'error',
|
||||
message: `[${res.code},${res.message}]`
|
||||
});
|
||||
resolve(res);
|
||||
}
|
||||
} else {
|
||||
// 二进制无res.code
|
||||
resolve(response);
|
||||
}
|
||||
};
|
||||
|
||||
// 封装GET方法
|
||||
const get = function (url, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.get(url, Object.assign({}, ...args)).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装POST方法
|
||||
const post = function (url, data = {}, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.post(url, data, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装get请求方法,自动添加参数
|
||||
const addArrayParamsByGet = function (url, [params, ...args]) {
|
||||
let search = Qs.stringify(params, {
|
||||
arrayFormat: 'repeat'
|
||||
});
|
||||
url = url + '?' + search;
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.get(url, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装post请求方法,自动添加参数
|
||||
const addFormDataParamsByPost = (url, [params, ...args]) => {
|
||||
let search = Qs.stringify(params, {
|
||||
arrayFormat: 'repeat'
|
||||
});
|
||||
url = url + '?' + search;
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.post(url, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
get,
|
||||
post,
|
||||
addArrayParamsByGet,
|
||||
addFormDataParamsByPost
|
||||
};
|
|
@ -0,0 +1,96 @@
|
|||
import $axios from '@/utils/axios';
|
||||
// import server from './server.config';
|
||||
import Qs from 'qs';
|
||||
import {
|
||||
Message
|
||||
} from 'element-ui';
|
||||
import router from '@/router/index';
|
||||
/**
|
||||
* code为非1000是抛错 可结合自己业务进行修改
|
||||
*
|
||||
* **/
|
||||
const dealResponse = function (response, resolve) {
|
||||
let res = response.data;
|
||||
if (res.code) {
|
||||
if (res.code === 1000 || res.code === 200) {
|
||||
resolve(res);
|
||||
} else if (res.code === 401) {
|
||||
Message({
|
||||
type: 'error',
|
||||
message: `['尚未登录授权或授权过期,请登录']`
|
||||
});
|
||||
router.replace({
|
||||
path: '/login'
|
||||
});
|
||||
resolve(res);
|
||||
} else {
|
||||
Message({
|
||||
type: 'error',
|
||||
message: `[${res.code},${res.message}]`
|
||||
});
|
||||
resolve(res);
|
||||
}
|
||||
} else {
|
||||
// 二进制无res.code
|
||||
resolve(response);
|
||||
}
|
||||
};
|
||||
|
||||
// 封装GET方法
|
||||
const get = function (url, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.get(url, Object.assign({}, ...args)).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装POST方法
|
||||
const post = function (url, data = {}, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.post(url, data, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装get请求方法,自动添加参数
|
||||
const addArrayParamsByGet = function (url, [params, ...args]) {
|
||||
let search = Qs.stringify(params, {
|
||||
arrayFormat: 'repeat'
|
||||
});
|
||||
url = url + '?' + search;
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.get(url, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装post请求方法,自动添加参数
|
||||
const addFormDataParamsByPost = (url, [params, ...args]) => {
|
||||
let search = Qs.stringify(params, {
|
||||
arrayFormat: 'repeat'
|
||||
});
|
||||
url = url + '?' + search;
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.post(url, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
get,
|
||||
post,
|
||||
addArrayParamsByGet,
|
||||
addFormDataParamsByPost
|
||||
};
|
|
@ -0,0 +1,96 @@
|
|||
import $axios from '@/utils/axios';
|
||||
// import server from './server.config';
|
||||
import Qs from 'qs';
|
||||
// import {
|
||||
// Message
|
||||
// } from 'element-ui';
|
||||
import router from '@/router/index';
|
||||
/**
|
||||
* code为非1000是抛错 可结合自己业务进行修改
|
||||
*
|
||||
* **/
|
||||
const dealResponse = function (response, resolve) {
|
||||
let res = response.data;
|
||||
if (res.code) {
|
||||
if (res.code === 1000 || res.code === 200) {
|
||||
resolve(res);
|
||||
} else if (res.code === 401) {
|
||||
Message({
|
||||
type: 'error',
|
||||
message: `['尚未登录授权或授权过期,请登录']`
|
||||
});
|
||||
router.replace({
|
||||
path: '/login'
|
||||
});
|
||||
resolve(res);
|
||||
} else {
|
||||
// Message({
|
||||
// type: 'error',
|
||||
// message: `[${res.code},${res.message}]`
|
||||
// });
|
||||
resolve(res);
|
||||
}
|
||||
} else {
|
||||
// 二进制无res.code
|
||||
resolve(response);
|
||||
}
|
||||
};
|
||||
|
||||
// 封装GET方法
|
||||
const get = function (url, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.get(url, Object.assign({}, ...args)).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装POST方法
|
||||
const post = function (url, data = {}, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.post(url, data, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装get请求方法,自动添加参数
|
||||
const addArrayParamsByGet = function (url, [params, ...args]) {
|
||||
let search = Qs.stringify(params, {
|
||||
arrayFormat: 'repeat'
|
||||
});
|
||||
url = url + '?' + search;
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.get(url, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装post请求方法,自动添加参数
|
||||
const addFormDataParamsByPost = (url, [params, ...args]) => {
|
||||
let search = Qs.stringify(params, {
|
||||
arrayFormat: 'repeat'
|
||||
});
|
||||
url = url + '?' + search;
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.post(url, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
get,
|
||||
post,
|
||||
addArrayParamsByGet,
|
||||
addFormDataParamsByPost
|
||||
};
|
|
@ -0,0 +1,97 @@
|
|||
import $axios from '@/utils/axios';
|
||||
// import server from './server.config';
|
||||
import Qs from 'qs';
|
||||
// import {
|
||||
// Message
|
||||
// } from 'element-ui';
|
||||
import router from '@/router/index';
|
||||
/**
|
||||
* code为非1000是抛错 可结合自己业务进行修改
|
||||
*
|
||||
* **/
|
||||
const dealResponse = function (response, resolve) {
|
||||
let res = response.data;
|
||||
if (res.code) {
|
||||
if (res.code === 1000 || res.code === 200) {
|
||||
resolve(res);
|
||||
} else if (res.code === 401) {
|
||||
Message({
|
||||
type: 'error',
|
||||
message: `['尚未登录授权或授权过期,请登录']`
|
||||
});
|
||||
router.replace({
|
||||
path: '/login'
|
||||
});
|
||||
resolve(res);
|
||||
} else {
|
||||
// Message({
|
||||
// type: 'error',
|
||||
// message: `[${res.code},${res.message}]`
|
||||
// });
|
||||
console.log("社事件")
|
||||
resolve(res);
|
||||
}
|
||||
} else {
|
||||
// 二进制无res.code
|
||||
resolve(response);
|
||||
}
|
||||
};
|
||||
|
||||
// 封装GET方法
|
||||
const get = function (url, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.get(url, Object.assign({}, ...args)).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装POST方法
|
||||
const post = function (url, data = {}, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.post(url, data, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装get请求方法,自动添加参数
|
||||
const addArrayParamsByGet = function (url, [params, ...args]) {
|
||||
let search = Qs.stringify(params, {
|
||||
arrayFormat: 'repeat'
|
||||
});
|
||||
url = url + '?' + search;
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.get(url, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装post请求方法,自动添加参数
|
||||
const addFormDataParamsByPost = (url, [params, ...args]) => {
|
||||
let search = Qs.stringify(params, {
|
||||
arrayFormat: 'repeat'
|
||||
});
|
||||
url = url + '?' + search;
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.post(url, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
get,
|
||||
post,
|
||||
addArrayParamsByGet,
|
||||
addFormDataParamsByPost
|
||||
};
|
|
@ -0,0 +1,97 @@
|
|||
import $axios from '@/utils/axios';
|
||||
// import server from './server.config';
|
||||
import Qs from 'qs';
|
||||
import {
|
||||
Message
|
||||
} from 'element-plus';
|
||||
import router from '@/router/index';
|
||||
/**
|
||||
* code为非1000是抛错 可结合自己业务进行修改
|
||||
*
|
||||
* **/
|
||||
const dealResponse = function (response, resolve) {
|
||||
let res = response.data;
|
||||
if (res.code) {
|
||||
if (res.code === 1000 || res.code === 200) {
|
||||
resolve(res);
|
||||
} else if (res.code === 401) {
|
||||
Message({
|
||||
type: 'error',
|
||||
message: `['尚未登录授权或授权过期,请登录']`
|
||||
});
|
||||
router.replace({
|
||||
path: '/login'
|
||||
});
|
||||
resolve(res);
|
||||
} else {
|
||||
Message({
|
||||
type: 'error',
|
||||
message: `[${res.code},${res.message}]`
|
||||
});
|
||||
console.log("社事件")
|
||||
resolve(res);
|
||||
}
|
||||
} else {
|
||||
// 二进制无res.code
|
||||
resolve(response);
|
||||
}
|
||||
};
|
||||
|
||||
// 封装GET方法
|
||||
const get = function (url, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.get(url, Object.assign({}, ...args)).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装POST方法
|
||||
const post = function (url, data = {}, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.post(url, data, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装get请求方法,自动添加参数
|
||||
const addArrayParamsByGet = function (url, [params, ...args]) {
|
||||
let search = Qs.stringify(params, {
|
||||
arrayFormat: 'repeat'
|
||||
});
|
||||
url = url + '?' + search;
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.get(url, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装post请求方法,自动添加参数
|
||||
const addFormDataParamsByPost = (url, [params, ...args]) => {
|
||||
let search = Qs.stringify(params, {
|
||||
arrayFormat: 'repeat'
|
||||
});
|
||||
url = url + '?' + search;
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.post(url, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
get,
|
||||
post,
|
||||
addArrayParamsByGet,
|
||||
addFormDataParamsByPost
|
||||
};
|
|
@ -0,0 +1,95 @@
|
|||
import $axios from '@/utils/axios';
|
||||
// import server from './server.config';
|
||||
import Qs from 'qs';
|
||||
|
||||
import router from '@/router/index';
|
||||
/**
|
||||
* code为非1000是抛错 可结合自己业务进行修改
|
||||
*
|
||||
* **/
|
||||
const dealResponse = function (response, resolve) {
|
||||
let res = response.data;
|
||||
if (res.code) {
|
||||
if (res.code === 1000 || res.code === 200) {
|
||||
resolve(res);
|
||||
} else if (res.code === 401) {
|
||||
Message({
|
||||
type: 'error',
|
||||
message: `['尚未登录授权或授权过期,请登录']`
|
||||
});
|
||||
router.replace({
|
||||
path: '/login'
|
||||
});
|
||||
resolve(res);
|
||||
} else {
|
||||
Message({
|
||||
type: 'error',
|
||||
message: `[${res.code},${res.message}]`
|
||||
});
|
||||
console.log("社事件")
|
||||
resolve(res);
|
||||
}
|
||||
} else {
|
||||
// 二进制无res.code
|
||||
resolve(response);
|
||||
}
|
||||
};
|
||||
|
||||
// 封装GET方法
|
||||
const get = function (url, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.get(url, Object.assign({}, ...args)).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装POST方法
|
||||
const post = function (url, data = {}, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.post(url, data, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装get请求方法,自动添加参数
|
||||
const addArrayParamsByGet = function (url, [params, ...args]) {
|
||||
let search = Qs.stringify(params, {
|
||||
arrayFormat: 'repeat'
|
||||
});
|
||||
url = url + '?' + search;
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.get(url, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装post请求方法,自动添加参数
|
||||
const addFormDataParamsByPost = (url, [params, ...args]) => {
|
||||
let search = Qs.stringify(params, {
|
||||
arrayFormat: 'repeat'
|
||||
});
|
||||
url = url + '?' + search;
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.post(url, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
get,
|
||||
post,
|
||||
addArrayParamsByGet,
|
||||
addFormDataParamsByPost
|
||||
};
|
|
@ -0,0 +1,97 @@
|
|||
import $axios from '@/utils/axios';
|
||||
// import server from './server.config';
|
||||
import Qs from 'qs';
|
||||
import {
|
||||
Message
|
||||
} from 'element-plus';
|
||||
import router from '@/router/index';
|
||||
/**
|
||||
* code为非1000是抛错 可结合自己业务进行修改
|
||||
*
|
||||
* **/
|
||||
const dealResponse = function (response, resolve) {
|
||||
let res = response.data;
|
||||
if (res.code) {
|
||||
if (res.code === 1000 || res.code === 200) {
|
||||
resolve(res);
|
||||
} else if (res.code === 401) {
|
||||
Message({
|
||||
type: 'error',
|
||||
message: `['尚未登录授权或授权过期,请登录']`
|
||||
});
|
||||
router.replace({
|
||||
path: '/login'
|
||||
});
|
||||
resolve(res);
|
||||
} else {
|
||||
Message({
|
||||
type: 'error',
|
||||
message: `[${res.code},${res.message}]`
|
||||
});
|
||||
console.log("社事件")
|
||||
resolve(res);
|
||||
}
|
||||
} else {
|
||||
// 二进制无res.code
|
||||
resolve(response);
|
||||
}
|
||||
};
|
||||
|
||||
// 封装GET方法
|
||||
const get = function (url, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.get(url, Object.assign({}, ...args)).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装POST方法
|
||||
const post = function (url, data = {}, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.post(url, data, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装get请求方法,自动添加参数
|
||||
const addArrayParamsByGet = function (url, [params, ...args]) {
|
||||
let search = Qs.stringify(params, {
|
||||
arrayFormat: 'repeat'
|
||||
});
|
||||
url = url + '?' + search;
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.get(url, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装post请求方法,自动添加参数
|
||||
const addFormDataParamsByPost = (url, [params, ...args]) => {
|
||||
let search = Qs.stringify(params, {
|
||||
arrayFormat: 'repeat'
|
||||
});
|
||||
url = url + '?' + search;
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.post(url, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
get,
|
||||
post,
|
||||
addArrayParamsByGet,
|
||||
addFormDataParamsByPost
|
||||
};
|
|
@ -0,0 +1,97 @@
|
|||
import $axios from '@/utils/axios';
|
||||
// import server from './server.config';
|
||||
import Qs from 'qs';
|
||||
import {
|
||||
ElMessage
|
||||
} from 'element-plus';
|
||||
import router from '@/router/index';
|
||||
/**
|
||||
* code为非1000是抛错 可结合自己业务进行修改
|
||||
*
|
||||
* **/
|
||||
const dealResponse = function (response, resolve) {
|
||||
let res = response.data;
|
||||
if (res.code) {
|
||||
if (res.code === 1000 || res.code === 200) {
|
||||
resolve(res);
|
||||
} else if (res.code === 401) {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: `['尚未登录授权或授权过期,请登录']`
|
||||
});
|
||||
router.replace({
|
||||
path: '/login'
|
||||
});
|
||||
resolve(res);
|
||||
} else {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: `[${res.code},${res.message}]`
|
||||
});
|
||||
console.log("社事件")
|
||||
resolve(res);
|
||||
}
|
||||
} else {
|
||||
// 二进制无res.code
|
||||
resolve(response);
|
||||
}
|
||||
};
|
||||
|
||||
// 封装GET方法
|
||||
const get = function (url, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.get(url, Object.assign({}, ...args)).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装POST方法
|
||||
const post = function (url, data = {}, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.post(url, data, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装get请求方法,自动添加参数
|
||||
const addArrayParamsByGet = function (url, [params, ...args]) {
|
||||
let search = Qs.stringify(params, {
|
||||
arrayFormat: 'repeat'
|
||||
});
|
||||
url = url + '?' + search;
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.get(url, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装post请求方法,自动添加参数
|
||||
const addFormDataParamsByPost = (url, [params, ...args]) => {
|
||||
let search = Qs.stringify(params, {
|
||||
arrayFormat: 'repeat'
|
||||
});
|
||||
url = url + '?' + search;
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.post(url, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
get,
|
||||
post,
|
||||
addArrayParamsByGet,
|
||||
addFormDataParamsByPost
|
||||
};
|
|
@ -0,0 +1,361 @@
|
|||
<template>
|
||||
<Header></Header>
|
||||
<div class="fixed">
|
||||
<div class="bgColor">
|
||||
<h1 class="main-shopcart">购物车</h1>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="main">
|
||||
<div class="nav">
|
||||
<span class="left">全部课程</span>
|
||||
</div>
|
||||
<ul class="head">
|
||||
<li class="item check">
|
||||
<el-checkbox
|
||||
v-model='checkAll'
|
||||
@change='fnCheckAll'
|
||||
>全选</el-checkbox>
|
||||
</li>
|
||||
<li class="item classInfo">课程信息</li>
|
||||
<li class="item price">单价</li>
|
||||
<li class="item count">数量</li>
|
||||
<li class="item total">金额</li>
|
||||
<li class="item function">操作</li>
|
||||
</ul>
|
||||
<div v-if="true">
|
||||
<ul
|
||||
class="haveorder"
|
||||
v-for='(item,index) in cartList'
|
||||
:key='item.id'
|
||||
>
|
||||
<li class="order-item">
|
||||
<el-checkbox
|
||||
v-model='item.check'
|
||||
@change='cartStore.checkItem(index)'
|
||||
></el-checkbox>
|
||||
</li>
|
||||
<li class="order-item info" >
|
||||
<div class="courseimg" >
|
||||
<img :src="item.courseCover" alt="">
|
||||
</div>
|
||||
<div class="course-name">{{item.courseName}}</div>
|
||||
</li>
|
||||
<li class="order-item">¥{{ item.discountPrice }}</li>
|
||||
<li class="order-item num">1</li>
|
||||
<li class="order-item totoalprice">¥{{ item.discountPrice }}</li>
|
||||
<li class="order-item delete" >
|
||||
<a href="javascript:;">
|
||||
<i class="el-icon-delete"></i>
|
||||
<span class="deletd-text" @click="deleteCart(item.id)">删除</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="noOrder" v-else>
|
||||
<img src="/image/norder365.png" alt="">
|
||||
<div class="order-alert">哎呦!暂无订单</div>
|
||||
</div>
|
||||
<el-divider class="line"></el-divider>
|
||||
<ul class="foot">
|
||||
<li class="foot-item">已选课程<span class="unique">{{ total.number }}</span></li>
|
||||
<li class="foot-item">合计<span class="unique">{{ total.price }}</span></li>
|
||||
<li >
|
||||
<button class="btn">去结算</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Foot></Foot>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
//组件
|
||||
import Header from '../components/common/Header.vue'
|
||||
import Foot from '../components/common/Foot.vue'
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useCartStore } from '@/store/cart.js'
|
||||
import { getShopCarList,deleteShopCar } from '@/api/Cart/index.js'
|
||||
import { onBeforeMount } from 'vue'
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
let cartStore = useCartStore();
|
||||
|
||||
let { cartList , checkAll , total , select } = storeToRefs(cartStore);
|
||||
|
||||
//生命周期
|
||||
onBeforeMount(async ()=>{
|
||||
const res = await getShopCarList()
|
||||
cartStore.getCartList( res.data.list )
|
||||
})
|
||||
|
||||
|
||||
//点击全选
|
||||
const fnCheckAll = ()=>{
|
||||
if( checkAll.value ){
|
||||
cartStore.unAll();
|
||||
}else{
|
||||
cartStore.all();
|
||||
}
|
||||
}
|
||||
|
||||
const deleteCart = async (id) => {
|
||||
ElMessageBox.confirm('确定删除该课程吗?', '删除', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
createToken().then(res=>{
|
||||
let token = res.data.token;
|
||||
deleteShopCar({
|
||||
id
|
||||
},token)
|
||||
})
|
||||
ElMessage.success({
|
||||
message: '删除成功!'
|
||||
});
|
||||
}).catch(() => {
|
||||
ElMessage.info({
|
||||
message: '已取消删除'
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
.fixed{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #FFFFFF;
|
||||
}
|
||||
.bgColor{
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
background-color: red;
|
||||
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
|
||||
background-size: 400% 400%;
|
||||
animation: gradient 15s ease infinite;
|
||||
}
|
||||
@keyframes gradient {
|
||||
0% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
50% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
100% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
}
|
||||
.container{
|
||||
width: 1200px;
|
||||
margin: -100px auto 50px auto;
|
||||
background: #EBEDF2;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0px 2px 5px #888888;
|
||||
}
|
||||
.main{
|
||||
padding:20px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.main-shop{
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-content: center;
|
||||
}
|
||||
.main-shop i{
|
||||
font-size: 35px;
|
||||
padding: 20px 10px 0 0;
|
||||
color: #FF4400;
|
||||
font-weight: bold;
|
||||
}
|
||||
.main-shopcart{
|
||||
width: 1200px;
|
||||
margin: 0 auto;
|
||||
height: 42px;
|
||||
font-size: 24px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: bold;
|
||||
line-height: 35px;
|
||||
color: #FFFFFF;
|
||||
padding: 30px 0;
|
||||
opacity: 1;
|
||||
}
|
||||
.nav{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
border-bottom: 2px solid #E6E6E6;
|
||||
|
||||
}
|
||||
.nav .left{
|
||||
width: 80px;
|
||||
height: 26px;
|
||||
font-size: 18px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: bold;
|
||||
line-height: 0px;
|
||||
color: #FF4400;
|
||||
opacity: 1;
|
||||
border-bottom: 2px solid #FF4400;
|
||||
}
|
||||
.nav .right{
|
||||
width: 108px;
|
||||
height: 24px;
|
||||
font-size: 14px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
line-height: 0px;
|
||||
color: #333333;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/* 头部开始 */
|
||||
.head{
|
||||
display: flex;
|
||||
padding: 0 10px;
|
||||
margin: 20px 0;
|
||||
width: 100%;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
background: #FCFCFC;
|
||||
opacity: 1;
|
||||
border-radius: 0px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 2px 5px 2px #cccccc;
|
||||
}
|
||||
.head .item{
|
||||
width: 150px;
|
||||
font-size: 14px;
|
||||
color: #333333;
|
||||
}
|
||||
.check .all{
|
||||
margin-right: 10px;
|
||||
}
|
||||
.check .text{
|
||||
width: 1487px;
|
||||
height: 40px;
|
||||
|
||||
}
|
||||
.classInfo{
|
||||
width: 400px!important;
|
||||
color: #333333;
|
||||
}
|
||||
/* 头部结束 */
|
||||
|
||||
/* 订单开始 */
|
||||
.haveorder{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
background: #FCFCFC;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 2px 5px 2px #cccccc;
|
||||
}
|
||||
.haveorder .order-item{
|
||||
height: 200px;
|
||||
line-height: 200px;
|
||||
margin: 5px;
|
||||
}
|
||||
.order-item:first-child{
|
||||
width: 30px;
|
||||
}
|
||||
.order-item{
|
||||
width: 150px;
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
}
|
||||
.totoalprice{
|
||||
color: #E2231A;
|
||||
}
|
||||
.num{
|
||||
width: 120px !important;
|
||||
padding-left: 15px;
|
||||
}
|
||||
.info{
|
||||
display: flex;
|
||||
width: 470px !important;
|
||||
height: 200px;
|
||||
line-height: 200px;
|
||||
}
|
||||
.courseimg{
|
||||
margin:40px 20px 40px 0;
|
||||
width: 200px;
|
||||
height: 120px;
|
||||
}
|
||||
.courseimg img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.info .course-name{
|
||||
width: 300px;
|
||||
word-break: keep-all;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.delete{
|
||||
cursor: pointer;
|
||||
}
|
||||
.deletd-text{
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
/* 订单结束 */
|
||||
|
||||
/* 暂无订单开始 */
|
||||
.noOrder{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
margin:200px 0;
|
||||
}
|
||||
.order-alert{
|
||||
height: 31px;
|
||||
font-size: 20px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
line-height: 0px;
|
||||
color: #B5B9BC;
|
||||
opacity: 1;
|
||||
margin:20px 120px;
|
||||
|
||||
}
|
||||
/* 暂无订单结束 */
|
||||
.foot{
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
color: #333333;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.foot-item{
|
||||
width: 120px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #333333;
|
||||
}
|
||||
.unique{
|
||||
margin-left: 5px;
|
||||
font-size: 24px;
|
||||
color: #FF4400;
|
||||
}
|
||||
.btn{
|
||||
width: 120px;
|
||||
height: 40px;
|
||||
margin-left: 20px;
|
||||
border: none;
|
||||
color: #FFFFFF;
|
||||
font-size: 22px;
|
||||
border-radius: 5px;
|
||||
background: #FF4400;
|
||||
cursor: pointer;
|
||||
box-shadow: 0px 3px 5px 2px #ff727f;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,361 @@
|
|||
<template>
|
||||
<Header></Header>
|
||||
<div class="fixed">
|
||||
<div class="bgColor">
|
||||
<h1 class="main-shopcart">购物车</h1>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="main">
|
||||
<div class="nav">
|
||||
<span class="left">全部课程</span>
|
||||
</div>
|
||||
<ul class="head">
|
||||
<li class="item check">
|
||||
<el-checkbox
|
||||
v-model='checkAll'
|
||||
@change='fnCheckAll'
|
||||
>全选</el-checkbox>
|
||||
</li>
|
||||
<li class="item classInfo">课程信息</li>
|
||||
<li class="item price">单价</li>
|
||||
<li class="item count">数量</li>
|
||||
<li class="item total">金额</li>
|
||||
<li class="item function">操作</li>
|
||||
</ul>
|
||||
<div v-if="true">
|
||||
<ul
|
||||
class="haveorder"
|
||||
v-for='(item,index) in cartList'
|
||||
:key='item.id'
|
||||
>
|
||||
<li class="order-item">
|
||||
<el-checkbox
|
||||
v-model='item.check'
|
||||
@change='cartStore.checkItem(index)'
|
||||
></el-checkbox>
|
||||
</li>
|
||||
<li class="order-item info" >
|
||||
<div class="courseimg" >
|
||||
<img :src="item.courseCover" alt="">
|
||||
</div>
|
||||
<div class="course-name">{{item.courseName}}</div>
|
||||
</li>
|
||||
<li class="order-item">¥{{ item.discountPrice }}</li>
|
||||
<li class="order-item num">1</li>
|
||||
<li class="order-item totoalprice">¥{{ item.discountPrice }}</li>
|
||||
<li class="order-item delete" >
|
||||
<a href="javascript:;">
|
||||
<i class="el-icon-delete"></i>
|
||||
<span class="deletd-text" @click="deleteCart(item.id)">删除</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="noOrder" v-else>
|
||||
<img src="/image/norder365.png" alt="">
|
||||
<div class="order-alert">哎呦!暂无订单</div>
|
||||
</div>
|
||||
<el-divider class="line"></el-divider>
|
||||
<ul class="foot">
|
||||
<li class="foot-item">已选课程<span class="unique">{{ total.number }}</span></li>
|
||||
<li class="foot-item">合计<span class="unique">{{ total.price }}</span></li>
|
||||
<li >
|
||||
<button class="btn">去结算</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Foot></Foot>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
//组件
|
||||
import Header from '../components/common/Header.vue'
|
||||
import Foot from '../components/common/Foot.vue'
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useCartStore } from '@/store/cart.js'
|
||||
import { getShopCarList,deleteShopCar } from '@/api/index.js'
|
||||
import { onBeforeMount } from 'vue'
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
let cartStore = useCartStore();
|
||||
|
||||
let { cartList , checkAll , total , select } = storeToRefs(cartStore);
|
||||
|
||||
//生命周期
|
||||
onBeforeMount(async ()=>{
|
||||
const res = await getShopCarList()
|
||||
cartStore.getCartList( res.data.list )
|
||||
})
|
||||
|
||||
|
||||
//点击全选
|
||||
const fnCheckAll = ()=>{
|
||||
if( checkAll.value ){
|
||||
cartStore.unAll();
|
||||
}else{
|
||||
cartStore.all();
|
||||
}
|
||||
}
|
||||
|
||||
const deleteCart = async (id) => {
|
||||
ElMessageBox.confirm('确定删除该课程吗?', '删除', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
createToken().then(res=>{
|
||||
let token = res.data.token;
|
||||
deleteShopCar({
|
||||
id
|
||||
},token)
|
||||
})
|
||||
ElMessage.success({
|
||||
message: '删除成功!'
|
||||
});
|
||||
}).catch(() => {
|
||||
ElMessage.info({
|
||||
message: '已取消删除'
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
.fixed{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #FFFFFF;
|
||||
}
|
||||
.bgColor{
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
background-color: red;
|
||||
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
|
||||
background-size: 400% 400%;
|
||||
animation: gradient 15s ease infinite;
|
||||
}
|
||||
@keyframes gradient {
|
||||
0% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
50% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
100% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
}
|
||||
.container{
|
||||
width: 1200px;
|
||||
margin: -100px auto 50px auto;
|
||||
background: #EBEDF2;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0px 2px 5px #888888;
|
||||
}
|
||||
.main{
|
||||
padding:20px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.main-shop{
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-content: center;
|
||||
}
|
||||
.main-shop i{
|
||||
font-size: 35px;
|
||||
padding: 20px 10px 0 0;
|
||||
color: #FF4400;
|
||||
font-weight: bold;
|
||||
}
|
||||
.main-shopcart{
|
||||
width: 1200px;
|
||||
margin: 0 auto;
|
||||
height: 42px;
|
||||
font-size: 24px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: bold;
|
||||
line-height: 35px;
|
||||
color: #FFFFFF;
|
||||
padding: 30px 0;
|
||||
opacity: 1;
|
||||
}
|
||||
.nav{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
border-bottom: 2px solid #E6E6E6;
|
||||
|
||||
}
|
||||
.nav .left{
|
||||
width: 80px;
|
||||
height: 26px;
|
||||
font-size: 18px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: bold;
|
||||
line-height: 0px;
|
||||
color: #FF4400;
|
||||
opacity: 1;
|
||||
border-bottom: 2px solid #FF4400;
|
||||
}
|
||||
.nav .right{
|
||||
width: 108px;
|
||||
height: 24px;
|
||||
font-size: 14px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
line-height: 0px;
|
||||
color: #333333;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/* 头部开始 */
|
||||
.head{
|
||||
display: flex;
|
||||
padding: 0 10px;
|
||||
margin: 20px 0;
|
||||
width: 100%;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
background: #FCFCFC;
|
||||
opacity: 1;
|
||||
border-radius: 0px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 2px 5px 2px #cccccc;
|
||||
}
|
||||
.head .item{
|
||||
width: 150px;
|
||||
font-size: 14px;
|
||||
color: #333333;
|
||||
}
|
||||
.check .all{
|
||||
margin-right: 10px;
|
||||
}
|
||||
.check .text{
|
||||
width: 1487px;
|
||||
height: 40px;
|
||||
|
||||
}
|
||||
.classInfo{
|
||||
width: 400px!important;
|
||||
color: #333333;
|
||||
}
|
||||
/* 头部结束 */
|
||||
|
||||
/* 订单开始 */
|
||||
.haveorder{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
background: #FCFCFC;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 2px 5px 2px #cccccc;
|
||||
}
|
||||
.haveorder .order-item{
|
||||
height: 200px;
|
||||
line-height: 200px;
|
||||
margin: 5px;
|
||||
}
|
||||
.order-item:first-child{
|
||||
width: 30px;
|
||||
}
|
||||
.order-item{
|
||||
width: 150px;
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
}
|
||||
.totoalprice{
|
||||
color: #E2231A;
|
||||
}
|
||||
.num{
|
||||
width: 120px !important;
|
||||
padding-left: 15px;
|
||||
}
|
||||
.info{
|
||||
display: flex;
|
||||
width: 470px !important;
|
||||
height: 200px;
|
||||
line-height: 200px;
|
||||
}
|
||||
.courseimg{
|
||||
margin:40px 20px 40px 0;
|
||||
width: 200px;
|
||||
height: 120px;
|
||||
}
|
||||
.courseimg img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.info .course-name{
|
||||
width: 300px;
|
||||
word-break: keep-all;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.delete{
|
||||
cursor: pointer;
|
||||
}
|
||||
.deletd-text{
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
/* 订单结束 */
|
||||
|
||||
/* 暂无订单开始 */
|
||||
.noOrder{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
margin:200px 0;
|
||||
}
|
||||
.order-alert{
|
||||
height: 31px;
|
||||
font-size: 20px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
line-height: 0px;
|
||||
color: #B5B9BC;
|
||||
opacity: 1;
|
||||
margin:20px 120px;
|
||||
|
||||
}
|
||||
/* 暂无订单结束 */
|
||||
.foot{
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
color: #333333;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.foot-item{
|
||||
width: 120px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #333333;
|
||||
}
|
||||
.unique{
|
||||
margin-left: 5px;
|
||||
font-size: 24px;
|
||||
color: #FF4400;
|
||||
}
|
||||
.btn{
|
||||
width: 120px;
|
||||
height: 40px;
|
||||
margin-left: 20px;
|
||||
border: none;
|
||||
color: #FFFFFF;
|
||||
font-size: 22px;
|
||||
border-radius: 5px;
|
||||
background: #FF4400;
|
||||
cursor: pointer;
|
||||
box-shadow: 0px 3px 5px 2px #ff727f;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,361 @@
|
|||
<template>
|
||||
<Header></Header>
|
||||
<div class="fixed">
|
||||
<div class="bgColor">
|
||||
<h1 class="main-shopcart">购物车</h1>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="main">
|
||||
<div class="nav">
|
||||
<span class="left">全部课程</span>
|
||||
</div>
|
||||
<ul class="head">
|
||||
<li class="item check">
|
||||
<el-checkbox
|
||||
v-model='checkAll'
|
||||
@change='fnCheckAll'
|
||||
>全选</el-checkbox>
|
||||
</li>
|
||||
<li class="item classInfo">课程信息</li>
|
||||
<li class="item price">单价</li>
|
||||
<li class="item count">数量</li>
|
||||
<li class="item total">金额</li>
|
||||
<li class="item function">操作</li>
|
||||
</ul>
|
||||
<div v-if="true">
|
||||
<ul
|
||||
class="haveorder"
|
||||
v-for='(item,index) in cartList'
|
||||
:key='item.id'
|
||||
>
|
||||
<li class="order-item">
|
||||
<el-checkbox
|
||||
v-model='item.check'
|
||||
@change='cartStore.checkItem(index)'
|
||||
></el-checkbox>
|
||||
</li>
|
||||
<li class="order-item info" >
|
||||
<div class="courseimg" >
|
||||
<img :src="item.courseCover" alt="">
|
||||
</div>
|
||||
<div class="course-name">{{item.courseName}}</div>
|
||||
</li>
|
||||
<li class="order-item">¥{{ item.discountPrice }}</li>
|
||||
<li class="order-item num">1</li>
|
||||
<li class="order-item totoalprice">¥{{ item.discountPrice }}</li>
|
||||
<li class="order-item delete" >
|
||||
<a href="javascript:;">
|
||||
<i class="el-icon-delete"></i>
|
||||
<span class="deletd-text" @click="deleteCart(item.id)">删除</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="noOrder" v-else>
|
||||
<img src="/image/norder365.png" alt="">
|
||||
<div class="order-alert">哎呦!暂无订单</div>
|
||||
</div>
|
||||
<el-divider class="line"></el-divider>
|
||||
<ul class="foot">
|
||||
<li class="foot-item">已选课程<span class="unique">{{ total.number }}</span></li>
|
||||
<li class="foot-item">合计<span class="unique">{{ total.price }}</span></li>
|
||||
<li >
|
||||
<button class="btn">去结算</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Foot></Foot>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
//组件
|
||||
import Header from '../components/common/Header.vue'
|
||||
import Foot from '../components/common/Foot.vue'
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useCartStore } from '@/store/cart.js'
|
||||
import { getShopCarList } from '@/api/index.js'
|
||||
import { onBeforeMount } from 'vue'
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
let cartStore = useCartStore();
|
||||
|
||||
let { cartList , checkAll , total , select } = storeToRefs(cartStore);
|
||||
|
||||
//生命周期
|
||||
onBeforeMount(async ()=>{
|
||||
const res = await getShopCarList()
|
||||
cartStore.getCartList( res.data.list )
|
||||
})
|
||||
|
||||
|
||||
//点击全选
|
||||
const fnCheckAll = ()=>{
|
||||
if( checkAll.value ){
|
||||
cartStore.unAll();
|
||||
}else{
|
||||
cartStore.all();
|
||||
}
|
||||
}
|
||||
|
||||
const deleteCart = async (id) => {
|
||||
ElMessageBox.confirm('确定删除该课程吗?', '删除', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
createToken().then(res=>{
|
||||
let token = res.data.token;
|
||||
deleteShopCar({
|
||||
id
|
||||
},token)
|
||||
})
|
||||
ElMessage.success({
|
||||
message: '删除成功!'
|
||||
});
|
||||
}).catch(() => {
|
||||
ElMessage.info({
|
||||
message: '已取消删除'
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
.fixed{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #FFFFFF;
|
||||
}
|
||||
.bgColor{
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
background-color: red;
|
||||
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
|
||||
background-size: 400% 400%;
|
||||
animation: gradient 15s ease infinite;
|
||||
}
|
||||
@keyframes gradient {
|
||||
0% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
50% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
100% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
}
|
||||
.container{
|
||||
width: 1200px;
|
||||
margin: -100px auto 50px auto;
|
||||
background: #EBEDF2;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0px 2px 5px #888888;
|
||||
}
|
||||
.main{
|
||||
padding:20px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.main-shop{
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-content: center;
|
||||
}
|
||||
.main-shop i{
|
||||
font-size: 35px;
|
||||
padding: 20px 10px 0 0;
|
||||
color: #FF4400;
|
||||
font-weight: bold;
|
||||
}
|
||||
.main-shopcart{
|
||||
width: 1200px;
|
||||
margin: 0 auto;
|
||||
height: 42px;
|
||||
font-size: 24px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: bold;
|
||||
line-height: 35px;
|
||||
color: #FFFFFF;
|
||||
padding: 30px 0;
|
||||
opacity: 1;
|
||||
}
|
||||
.nav{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
border-bottom: 2px solid #E6E6E6;
|
||||
|
||||
}
|
||||
.nav .left{
|
||||
width: 80px;
|
||||
height: 26px;
|
||||
font-size: 18px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: bold;
|
||||
line-height: 0px;
|
||||
color: #FF4400;
|
||||
opacity: 1;
|
||||
border-bottom: 2px solid #FF4400;
|
||||
}
|
||||
.nav .right{
|
||||
width: 108px;
|
||||
height: 24px;
|
||||
font-size: 14px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
line-height: 0px;
|
||||
color: #333333;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/* 头部开始 */
|
||||
.head{
|
||||
display: flex;
|
||||
padding: 0 10px;
|
||||
margin: 20px 0;
|
||||
width: 100%;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
background: #FCFCFC;
|
||||
opacity: 1;
|
||||
border-radius: 0px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 2px 5px 2px #cccccc;
|
||||
}
|
||||
.head .item{
|
||||
width: 150px;
|
||||
font-size: 14px;
|
||||
color: #333333;
|
||||
}
|
||||
.check .all{
|
||||
margin-right: 10px;
|
||||
}
|
||||
.check .text{
|
||||
width: 1487px;
|
||||
height: 40px;
|
||||
|
||||
}
|
||||
.classInfo{
|
||||
width: 400px!important;
|
||||
color: #333333;
|
||||
}
|
||||
/* 头部结束 */
|
||||
|
||||
/* 订单开始 */
|
||||
.haveorder{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
background: #FCFCFC;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 2px 5px 2px #cccccc;
|
||||
}
|
||||
.haveorder .order-item{
|
||||
height: 200px;
|
||||
line-height: 200px;
|
||||
margin: 5px;
|
||||
}
|
||||
.order-item:first-child{
|
||||
width: 30px;
|
||||
}
|
||||
.order-item{
|
||||
width: 150px;
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
}
|
||||
.totoalprice{
|
||||
color: #E2231A;
|
||||
}
|
||||
.num{
|
||||
width: 120px !important;
|
||||
padding-left: 15px;
|
||||
}
|
||||
.info{
|
||||
display: flex;
|
||||
width: 470px !important;
|
||||
height: 200px;
|
||||
line-height: 200px;
|
||||
}
|
||||
.courseimg{
|
||||
margin:40px 20px 40px 0;
|
||||
width: 200px;
|
||||
height: 120px;
|
||||
}
|
||||
.courseimg img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.info .course-name{
|
||||
width: 300px;
|
||||
word-break: keep-all;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.delete{
|
||||
cursor: pointer;
|
||||
}
|
||||
.deletd-text{
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
/* 订单结束 */
|
||||
|
||||
/* 暂无订单开始 */
|
||||
.noOrder{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
margin:200px 0;
|
||||
}
|
||||
.order-alert{
|
||||
height: 31px;
|
||||
font-size: 20px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
line-height: 0px;
|
||||
color: #B5B9BC;
|
||||
opacity: 1;
|
||||
margin:20px 120px;
|
||||
|
||||
}
|
||||
/* 暂无订单结束 */
|
||||
.foot{
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
color: #333333;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.foot-item{
|
||||
width: 120px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #333333;
|
||||
}
|
||||
.unique{
|
||||
margin-left: 5px;
|
||||
font-size: 24px;
|
||||
color: #FF4400;
|
||||
}
|
||||
.btn{
|
||||
width: 120px;
|
||||
height: 40px;
|
||||
margin-left: 20px;
|
||||
border: none;
|
||||
color: #FFFFFF;
|
||||
font-size: 22px;
|
||||
border-radius: 5px;
|
||||
background: #FF4400;
|
||||
cursor: pointer;
|
||||
box-shadow: 0px 3px 5px 2px #ff727f;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,362 @@
|
|||
<template>
|
||||
<Header></Header>
|
||||
<div class="fixed">
|
||||
<div class="bgColor">
|
||||
<h1 class="main-shopcart">购物车</h1>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="main">
|
||||
<div class="nav">
|
||||
<span class="left">全部课程</span>
|
||||
</div>
|
||||
<ul class="head">
|
||||
<li class="item check">
|
||||
<el-checkbox
|
||||
v-model='checkAll'
|
||||
@change='fnCheckAll'
|
||||
>全选</el-checkbox>
|
||||
</li>
|
||||
<li class="item classInfo">课程信息</li>
|
||||
<li class="item price">单价</li>
|
||||
<li class="item count">数量</li>
|
||||
<li class="item total">金额</li>
|
||||
<li class="item function">操作</li>
|
||||
</ul>
|
||||
<div v-if="true">
|
||||
<ul
|
||||
class="haveorder"
|
||||
v-for='(item,index) in cartList'
|
||||
:key='item.id'
|
||||
>
|
||||
<li class="order-item">
|
||||
<el-checkbox
|
||||
v-model='item.check'
|
||||
@change='cartStore.checkItem(index)'
|
||||
></el-checkbox>
|
||||
</li>
|
||||
<li class="order-item info" >
|
||||
<div class="courseimg" >
|
||||
<img :src="item.courseCover" alt="">
|
||||
</div>
|
||||
<div class="course-name">{{item.courseName}}</div>
|
||||
</li>
|
||||
<li class="order-item">¥{{ item.discountPrice }}</li>
|
||||
<li class="order-item num">1</li>
|
||||
<li class="order-item totoalprice">¥{{ item.discountPrice }}</li>
|
||||
<li class="order-item delete" >
|
||||
<a href="javascript:;">
|
||||
<i class="el-icon-delete"></i>
|
||||
<span class="deletd-text" @click="deleteCart(item.id)">删除</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="noOrder" v-else>
|
||||
<img src="/image/norder365.png" alt="">
|
||||
<div class="order-alert">哎呦!暂无订单</div>
|
||||
</div>
|
||||
<el-divider class="line"></el-divider>
|
||||
<ul class="foot">
|
||||
<li class="foot-item">已选课程<span class="unique">{{ total.number }}</span></li>
|
||||
<li class="foot-item">合计<span class="unique">{{ total.price }}</span></li>
|
||||
<li >
|
||||
<button class="btn">去结算</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Foot></Foot>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
//组件
|
||||
import Header from '../components/common/Header.vue'
|
||||
import Foot from '../components/common/Foot.vue'
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useCartStore } from '@/store/cart.js'
|
||||
import { getShopCarList } from '@/api/index.js'
|
||||
import { onBeforeMount } from 'vue'
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
let cartStore = useCartStore();
|
||||
|
||||
let { cartList , checkAll , total , select } = storeToRefs(cartStore);
|
||||
|
||||
//生命周期
|
||||
onBeforeMount(async ()=>{
|
||||
const res = await getShopCarList()
|
||||
console.log(res,"res")
|
||||
cartStore.getCartList( res.data.list )
|
||||
})
|
||||
|
||||
|
||||
//点击全选
|
||||
const fnCheckAll = ()=>{
|
||||
if( checkAll.value ){
|
||||
cartStore.unAll();
|
||||
}else{
|
||||
cartStore.all();
|
||||
}
|
||||
}
|
||||
|
||||
const deleteCart = async (id) => {
|
||||
ElMessageBox.confirm('确定删除该课程吗?', '删除', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
createToken().then(res=>{
|
||||
let token = res.data.token;
|
||||
deleteShopCar({
|
||||
id
|
||||
},token)
|
||||
})
|
||||
ElMessage.success({
|
||||
message: '删除成功!'
|
||||
});
|
||||
}).catch(() => {
|
||||
ElMessage.info({
|
||||
message: '已取消删除'
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
.fixed{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #FFFFFF;
|
||||
}
|
||||
.bgColor{
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
background-color: red;
|
||||
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
|
||||
background-size: 400% 400%;
|
||||
animation: gradient 15s ease infinite;
|
||||
}
|
||||
@keyframes gradient {
|
||||
0% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
50% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
100% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
}
|
||||
.container{
|
||||
width: 1200px;
|
||||
margin: -100px auto 50px auto;
|
||||
background: #EBEDF2;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0px 2px 5px #888888;
|
||||
}
|
||||
.main{
|
||||
padding:20px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.main-shop{
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-content: center;
|
||||
}
|
||||
.main-shop i{
|
||||
font-size: 35px;
|
||||
padding: 20px 10px 0 0;
|
||||
color: #FF4400;
|
||||
font-weight: bold;
|
||||
}
|
||||
.main-shopcart{
|
||||
width: 1200px;
|
||||
margin: 0 auto;
|
||||
height: 42px;
|
||||
font-size: 24px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: bold;
|
||||
line-height: 35px;
|
||||
color: #FFFFFF;
|
||||
padding: 30px 0;
|
||||
opacity: 1;
|
||||
}
|
||||
.nav{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
border-bottom: 2px solid #E6E6E6;
|
||||
|
||||
}
|
||||
.nav .left{
|
||||
width: 80px;
|
||||
height: 26px;
|
||||
font-size: 18px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: bold;
|
||||
line-height: 0px;
|
||||
color: #FF4400;
|
||||
opacity: 1;
|
||||
border-bottom: 2px solid #FF4400;
|
||||
}
|
||||
.nav .right{
|
||||
width: 108px;
|
||||
height: 24px;
|
||||
font-size: 14px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
line-height: 0px;
|
||||
color: #333333;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/* 头部开始 */
|
||||
.head{
|
||||
display: flex;
|
||||
padding: 0 10px;
|
||||
margin: 20px 0;
|
||||
width: 100%;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
background: #FCFCFC;
|
||||
opacity: 1;
|
||||
border-radius: 0px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 2px 5px 2px #cccccc;
|
||||
}
|
||||
.head .item{
|
||||
width: 150px;
|
||||
font-size: 14px;
|
||||
color: #333333;
|
||||
}
|
||||
.check .all{
|
||||
margin-right: 10px;
|
||||
}
|
||||
.check .text{
|
||||
width: 1487px;
|
||||
height: 40px;
|
||||
|
||||
}
|
||||
.classInfo{
|
||||
width: 400px!important;
|
||||
color: #333333;
|
||||
}
|
||||
/* 头部结束 */
|
||||
|
||||
/* 订单开始 */
|
||||
.haveorder{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
background: #FCFCFC;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 2px 5px 2px #cccccc;
|
||||
}
|
||||
.haveorder .order-item{
|
||||
height: 200px;
|
||||
line-height: 200px;
|
||||
margin: 5px;
|
||||
}
|
||||
.order-item:first-child{
|
||||
width: 30px;
|
||||
}
|
||||
.order-item{
|
||||
width: 150px;
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
}
|
||||
.totoalprice{
|
||||
color: #E2231A;
|
||||
}
|
||||
.num{
|
||||
width: 120px !important;
|
||||
padding-left: 15px;
|
||||
}
|
||||
.info{
|
||||
display: flex;
|
||||
width: 470px !important;
|
||||
height: 200px;
|
||||
line-height: 200px;
|
||||
}
|
||||
.courseimg{
|
||||
margin:40px 20px 40px 0;
|
||||
width: 200px;
|
||||
height: 120px;
|
||||
}
|
||||
.courseimg img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.info .course-name{
|
||||
width: 300px;
|
||||
word-break: keep-all;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.delete{
|
||||
cursor: pointer;
|
||||
}
|
||||
.deletd-text{
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
/* 订单结束 */
|
||||
|
||||
/* 暂无订单开始 */
|
||||
.noOrder{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
margin:200px 0;
|
||||
}
|
||||
.order-alert{
|
||||
height: 31px;
|
||||
font-size: 20px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
line-height: 0px;
|
||||
color: #B5B9BC;
|
||||
opacity: 1;
|
||||
margin:20px 120px;
|
||||
|
||||
}
|
||||
/* 暂无订单结束 */
|
||||
.foot{
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
color: #333333;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.foot-item{
|
||||
width: 120px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #333333;
|
||||
}
|
||||
.unique{
|
||||
margin-left: 5px;
|
||||
font-size: 24px;
|
||||
color: #FF4400;
|
||||
}
|
||||
.btn{
|
||||
width: 120px;
|
||||
height: 40px;
|
||||
margin-left: 20px;
|
||||
border: none;
|
||||
color: #FFFFFF;
|
||||
font-size: 22px;
|
||||
border-radius: 5px;
|
||||
background: #FF4400;
|
||||
cursor: pointer;
|
||||
box-shadow: 0px 3px 5px 2px #ff727f;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,46 @@
|
|||
<template>
|
||||
<Header></Header>
|
||||
<NavSwiper></NavSwiper>
|
||||
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
|
||||
<div ref="target">
|
||||
<NewGoodCourse v-if='targetIsVisible'></NewGoodCourse>
|
||||
</div>
|
||||
<Foot></Foot>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useIntersectionObserver } from '@vueuse/core'
|
||||
import Header from '../components/common/Header.vue'
|
||||
import NavSwiper from '../components/home/NavSwiper.vue'
|
||||
import Foot from '../components/common/Foot.vue'
|
||||
|
||||
const NewGoodCourse = defineAsyncComponent(() =>
|
||||
import('../components/home/NewGoodCourse.vue')
|
||||
)
|
||||
|
||||
const target = ref(null);
|
||||
const targetIsVisible = ref(false);
|
||||
|
||||
|
||||
const { stop } = useIntersectionObserver(
|
||||
target,
|
||||
([{ isIntersecting }]) => {
|
||||
if( isIntersecting ) {
|
||||
targetIsVisible.value = isIntersecting
|
||||
}
|
||||
}
|
||||
)
|
||||
</script>
|
|
@ -0,0 +1,46 @@
|
|||
<template>
|
||||
<Header></Header>
|
||||
<NavSwiper></NavSwiper>
|
||||
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
|
||||
<div ref="target">
|
||||
<NewGoodCourse v-if='targetIsVisible'></NewGoodCourse>
|
||||
</div>
|
||||
<Foot></Foot>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useIntersectionObserver } from '@vueuse/core'
|
||||
import Header from '../components/common/Header.vue'
|
||||
import NavSwiper from '../components/home/NavSwiper.vue'
|
||||
import Foot from '../components/common/Foot.vue'
|
||||
|
||||
const NewGoodCourse = defineAsyncComponent(() =>
|
||||
import('../components/home/NewGoodCourse.vue')
|
||||
)
|
||||
|
||||
const target = ref(null);
|
||||
const targetIsVisible = ref(false);
|
||||
|
||||
|
||||
const { stop } = useIntersectionObserver(
|
||||
target,
|
||||
([{ isIntersecting }]) => {
|
||||
if( isIntersecting ) {
|
||||
targetIsVisible.value = isIntersecting
|
||||
}
|
||||
}
|
||||
)
|
||||
</script>
|
|
@ -0,0 +1,38 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div>首页啊</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useIntersectionObserver } from '@vueuse/core'
|
||||
import NavSwiper from '../components/home/NavSwiper.vue'
|
||||
|
||||
|
||||
const NewGoodCourse = defineAsyncComponent(() =>
|
||||
import('../components/home/NewGoodCourse.vue')
|
||||
)
|
||||
|
||||
const target = ref(null);
|
||||
const targetIsVisible = ref(false);
|
||||
|
||||
|
||||
const { stop } = useIntersectionObserver(
|
||||
target,
|
||||
([{ isIntersecting }]) => {
|
||||
if( isIntersecting ) {
|
||||
targetIsVisible.value = isIntersecting
|
||||
}
|
||||
}
|
||||
)
|
||||
</script>
|
|
@ -0,0 +1,19 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div>首页啊</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
</script>
|
|
@ -0,0 +1,20 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div>首页啊</div>
|
||||
<el-button>按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
</script>
|
|
@ -0,0 +1,20 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div>首页啊</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
</script>
|
|
@ -0,0 +1,23 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div>首页啊</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
Message({
|
||||
type: 'error',
|
||||
message: `测得的和`
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,26 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div>首页啊</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
Message
|
||||
} from 'element-plus';
|
||||
Message({
|
||||
type: 'error',
|
||||
message: `测得的和`
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,26 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div>首页啊</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// import {
|
||||
// Message
|
||||
// } from 'element-plus';
|
||||
// Message({
|
||||
// type: 'error',
|
||||
// message: `测得的和`
|
||||
// });
|
||||
</script>
|
|
@ -0,0 +1,26 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div>首页啊</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
Message
|
||||
} from 'element-plus';
|
||||
Message({
|
||||
type: 'error',
|
||||
message: `测得的和`
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,21 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div>首页啊</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
|
||||
</script>
|
|
@ -0,0 +1,29 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div>首页啊</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
const openVn = () => {
|
||||
ElMessage({
|
||||
message: h('p', null, [
|
||||
h('span', null, 'Message can be '),
|
||||
h('i', { style: 'color: teal' }, 'VNode'),
|
||||
]),
|
||||
})
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,30 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div>首页啊</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
const openVn = () => {
|
||||
ElMessage({
|
||||
message: h('p', null, [
|
||||
h('span', null, 'Message can be '),
|
||||
h('i', { style: 'color: teal' }, 'VNode'),
|
||||
]),
|
||||
})
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,34 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div>首页啊</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { onBeforeMount } from 'vue'
|
||||
//生命周期
|
||||
onBeforeMount(async ()=>{
|
||||
openVn
|
||||
})
|
||||
const openVn = () => {
|
||||
ElMessage({
|
||||
message: h('p', null, [
|
||||
h('span', null, 'Message can be '),
|
||||
h('i', { style: 'color: teal' }, 'VNode'),
|
||||
]),
|
||||
})
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,34 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div>首页啊</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { onBeforeMount } from 'vue'
|
||||
//生命周期
|
||||
onBeforeMount(async ()=>{
|
||||
openVn()
|
||||
})
|
||||
const openVn = () => {
|
||||
ElMessage({
|
||||
message: h('p', null, [
|
||||
h('span', null, 'Message can be '),
|
||||
h('i', { style: 'color: teal' }, 'VNode'),
|
||||
]),
|
||||
})
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,34 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div>首页啊</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
// import { onBeforeMount } from 'vue'
|
||||
//生命周期
|
||||
onBeforeMount(async ()=>{
|
||||
openVn()
|
||||
})
|
||||
const openVn = () => {
|
||||
ElMessage({
|
||||
message: h('p', null, [
|
||||
h('span', null, 'Message can be '),
|
||||
h('i', { style: 'color: teal' }, 'VNode'),
|
||||
]),
|
||||
})
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,33 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div>首页啊</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
//生命周期
|
||||
onBeforeMount(async ()=>{
|
||||
openVn()
|
||||
})
|
||||
const openVn = () => {
|
||||
ElMessage({
|
||||
message: h('p', null, [
|
||||
h('span', null, 'Message can be '),
|
||||
h('i', { style: 'color: teal' }, 'VNode'),
|
||||
]),
|
||||
})
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,36 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div>首页啊</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
//生命周期
|
||||
onBeforeMount(async ()=>{
|
||||
// openVn()
|
||||
})
|
||||
watchEffect(()=>{
|
||||
openVn()
|
||||
})
|
||||
const openVn = () => {
|
||||
ElMessage({
|
||||
message: h('p', null, [
|
||||
h('span', null, 'Message can be '),
|
||||
h('i', { style: 'color: teal' }, 'VNode'),
|
||||
]),
|
||||
})
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,37 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div>首页啊</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
//生命周期
|
||||
onBeforeMount(async ()=>{
|
||||
// openVn()
|
||||
})
|
||||
const openVn = () => {
|
||||
ElMessage({
|
||||
message: h('p', null, [
|
||||
h('span', null, 'Message can be '),
|
||||
h('i', { style: 'color: teal' }, 'VNode'),
|
||||
]),
|
||||
})
|
||||
}
|
||||
watchEffect(()=>{
|
||||
openVn()
|
||||
})
|
||||
|
||||
</script>
|
|
@ -0,0 +1,39 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div>首页啊</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
import {onBeforeMount} from 'vue'
|
||||
|
||||
//生命周期
|
||||
onBeforeMount(async ()=>{
|
||||
// openVn()
|
||||
})
|
||||
const openVn = () => {
|
||||
ElMessage({
|
||||
message: h('p', null, [
|
||||
h('span', null, 'Message can be '),
|
||||
h('i', { style: 'color: teal' }, 'VNode'),
|
||||
]),
|
||||
})
|
||||
}
|
||||
watchEffect(()=>{
|
||||
openVn()
|
||||
})
|
||||
|
||||
</script>
|
|
@ -0,0 +1,39 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div>首页啊</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
import {onBeforeMount,onMount} from 'vue'
|
||||
|
||||
//生命周期
|
||||
onMount(async ()=>{
|
||||
// openVn()
|
||||
})
|
||||
const openVn = () => {
|
||||
ElMessage({
|
||||
message: h('p', null, [
|
||||
h('span', null, 'Message can be '),
|
||||
h('i', { style: 'color: teal' }, 'VNode'),
|
||||
]),
|
||||
})
|
||||
}
|
||||
watchEffect(()=>{
|
||||
openVn()
|
||||
})
|
||||
|
||||
</script>
|
|
@ -0,0 +1,39 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div>首页啊</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
import {onBeforeMount,onMount} from 'vue'
|
||||
|
||||
//生命周期
|
||||
onMount(async ()=>{
|
||||
// openVn()
|
||||
})
|
||||
const openVn = () => {
|
||||
ElMessage({
|
||||
message: h('p', null, [
|
||||
h('span', null, 'Message can be '),
|
||||
h('i', { style: 'color: teal' }, 'VNode'),
|
||||
]),
|
||||
})
|
||||
}
|
||||
// watchEffect(()=>{
|
||||
// openVn()
|
||||
// })
|
||||
|
||||
</script>
|
|
@ -0,0 +1,39 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div>首页啊</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
import {onBeforeMount,onMount} from 'vue'
|
||||
|
||||
//生命周期
|
||||
onMount(async ()=>{
|
||||
openVn()
|
||||
})
|
||||
const openVn = () => {
|
||||
ElMessage({
|
||||
message: h('p', null, [
|
||||
h('span', null, 'Message can be '),
|
||||
h('i', { style: 'color: teal' }, 'VNode'),
|
||||
]),
|
||||
})
|
||||
}
|
||||
// watchEffect(()=>{
|
||||
// openVn()
|
||||
// })
|
||||
|
||||
</script>
|
|
@ -0,0 +1,39 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div>首页啊</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
import {onBeforeMount,onMount} from 'vue'
|
||||
|
||||
//生命周期
|
||||
onMount(()=>{
|
||||
openVn()
|
||||
})
|
||||
const openVn = () => {
|
||||
ElMessage({
|
||||
message: h('p', null, [
|
||||
h('span', null, 'Message can be '),
|
||||
h('i', { style: 'color: teal' }, 'VNode'),
|
||||
]),
|
||||
})
|
||||
}
|
||||
// watchEffect(()=>{
|
||||
// openVn()
|
||||
// })
|
||||
|
||||
</script>
|
|
@ -0,0 +1,39 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div>首页啊</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
import {onBeforeMount,onMounted} from 'vue'
|
||||
|
||||
//生命周期
|
||||
onMounted(()=>{
|
||||
openVn()
|
||||
})
|
||||
const openVn = () => {
|
||||
ElMessage({
|
||||
message: h('p', null, [
|
||||
h('span', null, 'Message can be '),
|
||||
h('i', { style: 'color: teal' }, 'VNode'),
|
||||
]),
|
||||
})
|
||||
}
|
||||
// watchEffect(()=>{
|
||||
// openVn()
|
||||
// })
|
||||
|
||||
</script>
|
|
@ -0,0 +1,51 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div class="home">
|
||||
<span>首页啊</span>
|
||||
</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
import {onBeforeMount,onMounted} from 'vue'
|
||||
|
||||
//生命周期
|
||||
onMounted(()=>{
|
||||
openVn()
|
||||
})
|
||||
const openVn = () => {
|
||||
ElMessage({
|
||||
message: h('p', null, [
|
||||
h('span', null, 'Message can be '),
|
||||
h('i', { style: 'color: teal' }, 'VNode'),
|
||||
]),
|
||||
})
|
||||
}
|
||||
// watchEffect(()=>{
|
||||
// openVn()
|
||||
// })
|
||||
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.home{
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
span{
|
||||
color: aqua;
|
||||
}
|
||||
}
|
||||
</style>>
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div class="home">
|
||||
<span>首页啊</span>
|
||||
</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
import {onBeforeMount,onMounted} from 'vue'
|
||||
|
||||
//生命周期
|
||||
onMounted(()=>{
|
||||
openVn()
|
||||
})
|
||||
const openVn = () => {
|
||||
ElMessage({
|
||||
message: h('p', null, [
|
||||
h('span', null, 'Message can be '),
|
||||
h('i', { style: 'color: teal' }, 'VNode'),
|
||||
]),
|
||||
})
|
||||
}
|
||||
// watchEffect(()=>{
|
||||
// openVn()
|
||||
// })
|
||||
|
||||
</script>
|
||||
<style lang="sass" scoped>
|
||||
.home{
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
span{
|
||||
color: aqua;
|
||||
}
|
||||
}
|
||||
</style>>
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div class="home">
|
||||
<span>首页啊</span>
|
||||
</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
import {onBeforeMount,onMounted} from 'vue'
|
||||
|
||||
//生命周期
|
||||
onMounted(()=>{
|
||||
openVn()
|
||||
})
|
||||
const openVn = () => {
|
||||
ElMessage({
|
||||
message: h('p', null, [
|
||||
h('span', null, 'Message can be '),
|
||||
h('i', { style: 'color: teal' }, 'VNode'),
|
||||
]),
|
||||
})
|
||||
}
|
||||
// watchEffect(()=>{
|
||||
// openVn()
|
||||
// })
|
||||
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.home{
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
span{
|
||||
color: aqua;
|
||||
}
|
||||
}
|
||||
</style>>
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div class="home">
|
||||
<span class="btn">首页啊</span>
|
||||
</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
import {onBeforeMount,onMounted} from 'vue'
|
||||
|
||||
//生命周期
|
||||
onMounted(()=>{
|
||||
openVn()
|
||||
})
|
||||
const openVn = () => {
|
||||
ElMessage({
|
||||
message: h('p', null, [
|
||||
h('span', null, 'Message can be '),
|
||||
h('i', { style: 'color: teal' }, 'VNode'),
|
||||
]),
|
||||
})
|
||||
}
|
||||
// watchEffect(()=>{
|
||||
// openVn()
|
||||
// })
|
||||
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.home{
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
span{
|
||||
}
|
||||
.btn{
|
||||
color: aquamarine;
|
||||
}
|
||||
}
|
||||
</style>>
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<template>
|
||||
<!-- 两种异步加载的方法,
|
||||
第一个是用Suspense
|
||||
第二个是用vueuse的插件
|
||||
-->
|
||||
<!-- <Suspense>
|
||||
<template #default>
|
||||
<NewGoodCourse></NewGoodCourse>
|
||||
</template>
|
||||
<template #fallback>
|
||||
Loading······
|
||||
</template>
|
||||
</Suspense> -->
|
||||
<div class="home">
|
||||
<span class="btn">首页啊</span>
|
||||
</div>
|
||||
<el-button type="primary">按钮</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
import {onBeforeMount,onMounted} from 'vue'
|
||||
|
||||
//生命周期
|
||||
onMounted(()=>{
|
||||
openVn()
|
||||
})
|
||||
const openVn = () => {
|
||||
ElMessage({
|
||||
message: h('p', null, [
|
||||
h('span', null, 'Message can be '),
|
||||
h('i', { style: 'color: teal' }, 'VNode'),
|
||||
]),
|
||||
})
|
||||
}
|
||||
// watchEffect(()=>{
|
||||
// openVn()
|
||||
// })
|
||||
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.home{
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
.btn{
|
||||
color: aquamarine;
|
||||
}
|
||||
}
|
||||
</style>>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"recommendations": ["Vue.volar"]
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite App</title>
|
||||
<link rel="stylesheet" href="//at.alicdn.com/t/font_3438590_p85idk0acv.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"name": "saas",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vueuse/core": "^8.5.0",
|
||||
"axios": "^0.27.2",
|
||||
"crypto-js": "^4.1.1",
|
||||
"element-plus": "^2.2.2",
|
||||
"pinia": "^2.0.14",
|
||||
"pinia-plugin-persist": "^1.0.0",
|
||||
"qs": "^6.11.0",
|
||||
"vue": "^3.2.25",
|
||||
"vue-router": "^4.0.15",
|
||||
"vue3-video-play": "^1.3.1-beta.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^2.3.3",
|
||||
"less": "^4.1.3",
|
||||
"less-loader": "^11.1.0",
|
||||
"unplugin-auto-import": "^0.8.5",
|
||||
"vite": "^2.9.9",
|
||||
"vite-plugin-require-transform": "^1.0.3"
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
|
@ -0,0 +1,8 @@
|
|||
<template>
|
||||
<router-view></router-view>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
@import './assets/css/reset.css';
|
||||
|
||||
</style>
|
|
@ -0,0 +1,25 @@
|
|||
import $http from '@/utils/request';
|
||||
// const API = {
|
||||
// getdemo(arg) {
|
||||
// return $http.get(`/api/getdemo?currentPage=${arg.currentPage}&pageSize=${arg.pageSize}`);
|
||||
// },
|
||||
// get() {
|
||||
// return $http.get(`/api/getinfo?pageNo=1&pageSize=100`)
|
||||
// },
|
||||
// add(params) {
|
||||
// return $http.post('/api/send', params);
|
||||
// },
|
||||
// uploadfile(arg) {
|
||||
// return $http.post(`/api/upload`, arg)
|
||||
// },
|
||||
// downloadfile(params) {
|
||||
// return $http.get(`/api/download?fileId=${params.fileId}`, { responseType: 'blob', })
|
||||
// },
|
||||
// getShopCarList(){
|
||||
// return $http.get('/api/shopcar/getShopCarList')
|
||||
// }
|
||||
// };
|
||||
// export default API;
|
||||
export function getShopCarList(){
|
||||
return $http.get('/api/shopcar/getShopCarList')
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import $http from '@/utils/request';
|
||||
|
||||
export function loginByJson(arg){
|
||||
return $http.get(`/api/getdemo?currentPage=${arg.currentPage}&pageSize=${arg.pageSize}`);
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function loginByMobile(params){
|
||||
return $http.post('/api/send', params);
|
||||
}
|
||||
|
||||
export function createToken(params){
|
||||
return $http.get(`/api/download?fileId=${params.fileId}`, { responseType: 'blob', })
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/* http://meyerweb.com/eric/tools/css/reset/ */
|
||||
/* v1.0 | 20080212 */
|
||||
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, font, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
font-size: 100%;
|
||||
vertical-align: baseline;
|
||||
background: transparent;
|
||||
}
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
ol, ul {
|
||||
list-style: none;
|
||||
}
|
||||
blockquote, q {
|
||||
quotes: none;
|
||||
}
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
|
||||
/* remember to define focus styles! */
|
||||
:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
/* remember to highlight inserts somehow! */
|
||||
ins {
|
||||
text-decoration: none;
|
||||
}
|
||||
del {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
/* tables still need 'cellspacing="0"' in the markup */
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 63 KiB |
|
@ -0,0 +1,10 @@
|
|||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from "./router";
|
||||
|
||||
import ElementPlus from 'element-plus'
|
||||
import 'element-plus/dist/index.css'
|
||||
|
||||
import store from "./store";
|
||||
|
||||
createApp(App).use(router).use(store).use(ElementPlus).mount('#app')
|
|
@ -0,0 +1,22 @@
|
|||
export default function(){
|
||||
let courseTypeFn = ( type )=>{
|
||||
let val = '';
|
||||
switch (type) {
|
||||
case 1:
|
||||
val = '初级';
|
||||
break;
|
||||
case 2:
|
||||
val = '中级';
|
||||
break;
|
||||
case 3:
|
||||
val = '高级';
|
||||
break;
|
||||
default:
|
||||
val = '';
|
||||
}
|
||||
return val;
|
||||
}
|
||||
return {
|
||||
courseTypeFn
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
import { createRouter, createWebHistory } from "vue-router";
|
||||
import { useUserStore } from '@/store/user'
|
||||
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: "/",
|
||||
name: "Home",
|
||||
component: () =>import(/* webpackChunkName: "home" */ "../views/Home.vue"),
|
||||
},
|
||||
|
||||
// {
|
||||
// path:'/cart',
|
||||
// name:'Cart',
|
||||
// component: () =>
|
||||
// import(/* webpackChunkName: "CoursePlay" */ "../views/Cart.vue"),
|
||||
// beforeEnter: (to, from, next) => {
|
||||
// if( useUserStore().token ){
|
||||
// next()
|
||||
// }else {
|
||||
// next('/login')
|
||||
// }
|
||||
|
||||
// }
|
||||
// },
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
});
|
||||
|
||||
export default router;
|
|
@ -0,0 +1,8 @@
|
|||
import { createPinia } from 'pinia'
|
||||
import piniaPluginPersist from 'pinia-plugin-persist'
|
||||
|
||||
const store = createPinia()
|
||||
// 使用持久化插件
|
||||
store.use(piniaPluginPersist)
|
||||
|
||||
export default store
|
|
@ -0,0 +1,34 @@
|
|||
// user模块,类似于 vuex 中的moduel
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
// defineStore 类等于 中的 moduel
|
||||
// useUserStore ,类等于 中的 moduel :{ useUserStore }
|
||||
export const useUserStore = defineStore({
|
||||
// 模块ID
|
||||
id: 'user',
|
||||
state: () => {
|
||||
return {
|
||||
token: '',
|
||||
userInfo:{}
|
||||
}
|
||||
},
|
||||
actions:{
|
||||
setToken( token ){
|
||||
this.token = token;
|
||||
} ,
|
||||
removeToken(){
|
||||
this.token = '';
|
||||
}
|
||||
},
|
||||
// 开启数据缓存
|
||||
persist: {
|
||||
enabled: true,
|
||||
strategies: [{
|
||||
// localStorage 的数据 相当于 setLocalStorage
|
||||
key: 'xiaoluxian_user',
|
||||
// 模式
|
||||
storage: localStorage,
|
||||
//paths: ['token']
|
||||
}]
|
||||
}
|
||||
})
|
|
@ -0,0 +1,41 @@
|
|||
// import Vue from 'vue';
|
||||
import axios from 'axios';
|
||||
// Vue.prototype.axios = axios;
|
||||
// 创建axios实例
|
||||
const $axios = axios.create();
|
||||
$axios.defaults.timeout = 1000 * 50; // 请求超时时间
|
||||
|
||||
// request拦截器
|
||||
$axios.interceptors.request.use(config => {
|
||||
if (sessionStorage.getItem('token')) {
|
||||
config.headers.Authorization = sessionStorage.getItem('token')
|
||||
}
|
||||
if (navigator.userAgent.indexOf('Trident') != -1) {
|
||||
if (config.method == 'post') {
|
||||
config.data = {
|
||||
...config.data,
|
||||
t: Date.now()
|
||||
};
|
||||
} else if (config.method == 'get') {
|
||||
config.params = {
|
||||
...config.params,
|
||||
t: Date.now()
|
||||
};
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}, error => {
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
// respone 拦截器
|
||||
$axios.interceptors.response.use(
|
||||
response => {
|
||||
return response;
|
||||
},
|
||||
error => {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default $axios;
|
|
@ -0,0 +1,20 @@
|
|||
import CryptoJS from "crypto-js";
|
||||
|
||||
const key = CryptoJS.enc.Utf8.parse("AOWQ4P0YEC4YXUKS"); //十六位十六进制数作为密钥
|
||||
const iv = CryptoJS.enc.Utf8.parse('O3V2GCL1K2HNZ9Y7'); //十六位十六进制数作为密钥偏移量
|
||||
|
||||
//解密方法
|
||||
export function Decrypt(word) {
|
||||
let encryptedHexStr = CryptoJS.enc.Hex.parse(word);
|
||||
let srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr);
|
||||
let decrypt = CryptoJS.AES.decrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
|
||||
let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
|
||||
return decryptedStr.toString();
|
||||
}
|
||||
|
||||
//加密方法
|
||||
export function Encrypt(word) {
|
||||
let srcs = CryptoJS.enc.Utf8.parse(word);
|
||||
let encrypted = CryptoJS.AES.encrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
|
||||
return encrypted.ciphertext.toString().toUpperCase();
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
import $axios from '@/utils/axios';
|
||||
// import server from './server.config';
|
||||
import Qs from 'qs';
|
||||
import {
|
||||
ElMessage
|
||||
} from 'element-plus';
|
||||
import router from '@/router/index';
|
||||
/**
|
||||
* code为非1000是抛错 可结合自己业务进行修改
|
||||
*
|
||||
* **/
|
||||
const dealResponse = function (response, resolve) {
|
||||
let res = response.data;
|
||||
if (res.code) {
|
||||
if (res.code === 1000 || res.code === 200) {
|
||||
resolve(res);
|
||||
} else if (res.code === 401) {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: `['尚未登录授权或授权过期,请登录']`
|
||||
});
|
||||
router.replace({
|
||||
path: '/login'
|
||||
});
|
||||
resolve(res);
|
||||
} else {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: `[${res.code},${res.message}]`
|
||||
});
|
||||
console.log("社事件")
|
||||
resolve(res);
|
||||
}
|
||||
} else {
|
||||
// 二进制无res.code
|
||||
resolve(response);
|
||||
}
|
||||
};
|
||||
|
||||
// 封装GET方法
|
||||
const get = function (url, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.get(url, Object.assign({}, ...args)).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装POST方法
|
||||
const post = function (url, data = {}, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.post(url, data, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装get请求方法,自动添加参数
|
||||
const addArrayParamsByGet = function (url, [params, ...args]) {
|
||||
let search = Qs.stringify(params, {
|
||||
arrayFormat: 'repeat'
|
||||
});
|
||||
url = url + '?' + search;
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.get(url, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装post请求方法,自动添加参数
|
||||
const addFormDataParamsByPost = (url, [params, ...args]) => {
|
||||
let search = Qs.stringify(params, {
|
||||
arrayFormat: 'repeat'
|
||||
});
|
||||
url = url + '?' + search;
|
||||
return new Promise((resolve, reject) => {
|
||||
$axios.post(url, ...args).then(res => {
|
||||
dealResponse(res, resolve);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
get,
|
||||
post,
|
||||
addArrayParamsByGet,
|
||||
addFormDataParamsByPost
|
||||
};
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue