Compare commits
No commits in common. 'main' and 'main1' have entirely different histories.
@ -0,0 +1,3 @@
|
||||
> 1%
|
||||
last 2 versions
|
||||
not dead
|
||||
@ -0,0 +1,23 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "doubao_community_frontend",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.21.1",
|
||||
"buefy": "^0.9.4",
|
||||
"core-js": "^3.6.5",
|
||||
"darkreader": "^4.9.27",
|
||||
"date-fns": "^2.17.0",
|
||||
"dayjs": "^1.10.4",
|
||||
"element-ui": "^2.15.14",
|
||||
"js-cookie": "^2.2.1",
|
||||
"nprogress": "^0.2.0",
|
||||
"vditor": "^3.8.1",
|
||||
"vue": "^2.6.11",
|
||||
"vue-lazyload": "^3.0.0",
|
||||
"vue-router": "^3.2.0",
|
||||
"vuedraggable": "^2.24.3",
|
||||
"vuex": "^3.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "~4.5.0",
|
||||
"@vue/cli-plugin-router": "~4.5.0",
|
||||
"@vue/cli-plugin-vuex": "~4.5.0",
|
||||
"@vue/cli-service": "~4.5.0",
|
||||
"@vue/compiler-sfc": "^3.3.10",
|
||||
"vue-template-compiler": "^2.6.11"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="mb-5">
|
||||
<Header></Header>
|
||||
</div>
|
||||
|
||||
<div class="container context">
|
||||
<router-view :key="this.$route.fullPath"></router-view>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Footer></Footer>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Header from "@/components/Layout/Header";
|
||||
import Footer from "@/components/Layout/Footer";
|
||||
|
||||
|
||||
export default {
|
||||
name: "App",
|
||||
components: { Header, Footer },
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
min-height: 500px;
|
||||
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,32 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 注册
|
||||
export function userRegister(userDTO) {
|
||||
return request({
|
||||
url: '/ums/user/register',
|
||||
method: 'post',
|
||||
data: userDTO
|
||||
})
|
||||
}
|
||||
|
||||
// 前台用户登录
|
||||
export function login(data) {
|
||||
return request({
|
||||
url: '/ums/user/login',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 登录后获取前台用户信息
|
||||
export function getUserInfo() {
|
||||
return request({
|
||||
url: '/ums/user/info',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
// 前台用户注销
|
||||
export function logout() {
|
||||
return request({
|
||||
url: '/ums/user/logout'
|
||||
})
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
//获得一级分类
|
||||
export function getBillboard() {
|
||||
return request({
|
||||
url: '/billboard/show',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
|
||||
//品牌获取申请需求的模特详情
|
||||
export function getApplyModel(){
|
||||
return request({
|
||||
url:'/model/getApplyModel',
|
||||
method:'get',
|
||||
})
|
||||
}
|
||||
|
||||
//品牌同意或者拒绝模特申请的需求
|
||||
export function isAgree(isAgree){
|
||||
return request({
|
||||
url:'/model/refuseModel',
|
||||
method:'post',
|
||||
data:isAgree
|
||||
})
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
// 封装购物车相关接口
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 加入购物车
|
||||
export const insertCartAPI = ({ skuId, count }) => {
|
||||
return request({
|
||||
url: '/member/cart',
|
||||
method: 'POST',
|
||||
data: {
|
||||
skuId,
|
||||
count
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取最新的购物车列表
|
||||
export const findNewCartListAPI = () => {
|
||||
return request({
|
||||
url: '/member/cart'
|
||||
})
|
||||
}
|
||||
|
||||
// 删除购物车
|
||||
export const delCartAPI = (ids) => {
|
||||
return request({
|
||||
url: '/member/cart',
|
||||
method: 'DELETE',
|
||||
data: {
|
||||
ids
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 合并购物车
|
||||
|
||||
export const mergeCartAPI = (data) => {
|
||||
return request({
|
||||
url: '/member/cart/merge',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
|
||||
export function getCategoryAPI () {
|
||||
return request({
|
||||
url: '/shopping/category',
|
||||
method:'get',
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @description: 获取导航数据
|
||||
* @data {
|
||||
categoryId: 1005000 ,
|
||||
page: 1,
|
||||
pageSize: 20,
|
||||
sortField: 'publishTime' | 'orderNum' | 'evaluateNum'
|
||||
}
|
||||
* @return {*}
|
||||
*/
|
||||
export function getSubCategoryAPI (data) {
|
||||
return request({
|
||||
url: '/shopping/category/goods',
|
||||
method: 'get',
|
||||
data
|
||||
})
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function fetchCommentsByTopicId(topic_Id) {
|
||||
return request({
|
||||
url: '/comment/get_comments',
|
||||
method: 'get',
|
||||
params: {
|
||||
topicid: topic_Id
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function pushComment(data) {
|
||||
return request({
|
||||
url: '/comment/add_comment',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
@ -0,0 +1,83 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
export function getCourseDirection() {
|
||||
return request({
|
||||
url: "/course/direction/show",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
//获取二级分类
|
||||
export function getCourseCategory() {
|
||||
return request({
|
||||
url: "/course/category/show",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
//查询课程标签
|
||||
export function tagsList(data) {
|
||||
return request({
|
||||
url: "/course/tags/list",
|
||||
method: "get",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
//查询课程
|
||||
export function searchCourse(pageNo, page, entity) {
|
||||
return request({
|
||||
url: "/course/search",
|
||||
method: "post",
|
||||
params: {
|
||||
pageNo: pageNo,
|
||||
page: page,
|
||||
},
|
||||
data: entity,
|
||||
});
|
||||
}
|
||||
|
||||
//课程详情
|
||||
export function getCourseDetail(courseId) {
|
||||
return request({
|
||||
url: "/course/getDetail",
|
||||
method: "get",
|
||||
params: { courseId },
|
||||
});
|
||||
}
|
||||
//课程视频详情
|
||||
export function getVideoDetail(courseId, videoId) {
|
||||
return request({
|
||||
url: "/course/getVideo",
|
||||
method: "get",
|
||||
params: {
|
||||
courseId,
|
||||
videoId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
//检查是否有权限
|
||||
export function courseCheckAuth() {
|
||||
return request({
|
||||
url: "/course/checkAuth",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
//下载课程资料
|
||||
export function downloadAttachment(user) {
|
||||
return request({
|
||||
url: "/course/downloadAttachment",
|
||||
params,
|
||||
responseType: "blob",
|
||||
});
|
||||
}
|
||||
|
||||
//打卡课程
|
||||
export function clockIn(courseId) {
|
||||
return request({
|
||||
url: "/course/clock",
|
||||
method: "post",
|
||||
params: { courseId },
|
||||
});
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 关注
|
||||
export function follow(id) {
|
||||
return request(({
|
||||
url: `/relationship/subscribe/${id}`,
|
||||
method: 'get'
|
||||
}))
|
||||
}
|
||||
|
||||
// 关注
|
||||
export function unFollow(id) {
|
||||
return request(({
|
||||
url: `/relationship/unsubscribe/${id}`,
|
||||
method: 'get'
|
||||
}))
|
||||
}
|
||||
|
||||
// 验证是否关注
|
||||
export function hasFollow(topicUserId) {
|
||||
return request(({
|
||||
url: `/relationship/validate/${topicUserId}`,
|
||||
method: 'get'
|
||||
}))
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
//模特详情
|
||||
export function getModelDetail(id) {
|
||||
return request({
|
||||
url: "/model/getDetail",
|
||||
method: "get",
|
||||
params: { id },
|
||||
});
|
||||
}
|
||||
|
||||
//审核模特数据
|
||||
export function checkModel(data) {
|
||||
return request({
|
||||
url: "/model/check",
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
//获取申请需求数据
|
||||
export function applyPost() {
|
||||
return request({
|
||||
url: "/model/applyPost",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
//提交模特数据
|
||||
export function submitModel(form) {
|
||||
return request({
|
||||
method: "post",
|
||||
url: "/model/submitModel",
|
||||
data: form,
|
||||
});
|
||||
}
|
||||
|
||||
//获取模特认证要求
|
||||
export function getModelRequest() {
|
||||
return request({
|
||||
method: "get",
|
||||
url: "/model/identify",
|
||||
});
|
||||
}
|
||||
@ -0,0 +1,193 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 列表
|
||||
export function getList(pageNo, size, tab) {
|
||||
return request(({
|
||||
url: '/post/list',
|
||||
method: 'get',
|
||||
params: { pageNo: pageNo, size: size, tab: tab }
|
||||
}))
|
||||
}
|
||||
|
||||
// 发布
|
||||
export function post(topic) {
|
||||
return request({
|
||||
url: '/post/create',
|
||||
method: 'post',
|
||||
data: topic
|
||||
})
|
||||
}
|
||||
|
||||
// 浏览
|
||||
export function getTopic(id) {
|
||||
return request({
|
||||
url: '/post',
|
||||
method: 'get',
|
||||
params: {
|
||||
id: id
|
||||
}
|
||||
})
|
||||
}
|
||||
// 获取详情页推荐
|
||||
export function getRecommendTopics(id) {
|
||||
return request({
|
||||
url: '/post/recommend',
|
||||
method: 'get',
|
||||
params: {
|
||||
topicId: id
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function update(topic) {
|
||||
return request({
|
||||
url: '/post/update',
|
||||
method: 'put',
|
||||
data: topic
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteTopic(id) {
|
||||
return request({
|
||||
url: `/post/delete/${id}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
//需求申请
|
||||
export function postApply(modelPost){
|
||||
return request({
|
||||
url: '/post/require',
|
||||
method: 'post',
|
||||
data:modelPost
|
||||
})
|
||||
}
|
||||
//发布签到数字
|
||||
export function sendSecretKey(postId,secretKey){
|
||||
return request({
|
||||
url: '/post/sendSecretKey',
|
||||
method: 'put',
|
||||
params:{
|
||||
postId,
|
||||
secretKey
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//获取星星名单
|
||||
export function getStar(id){
|
||||
return request({
|
||||
url: '/modelPost/getStar',
|
||||
method: 'get',
|
||||
params:{id}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新星星名单
|
||||
* @param {*}
|
||||
* data:{
|
||||
* modelId:'',
|
||||
* postId:''
|
||||
* }
|
||||
* @returns
|
||||
*/
|
||||
export function updateStar(postId,data){
|
||||
return request({
|
||||
url: '/modelPost/updateStar',
|
||||
method: 'put',
|
||||
data,
|
||||
params:{postId}
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 删除星星名单
|
||||
* @param {*}
|
||||
* data:{
|
||||
* modelId:'',
|
||||
* postId:''
|
||||
* }
|
||||
* @returns
|
||||
*/
|
||||
export function deleteStar(data){
|
||||
return request({
|
||||
url: '/modelPost/deleteStar',
|
||||
method: 'delete',
|
||||
data
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 增加星星名单
|
||||
* @param {*}
|
||||
* data:{
|
||||
* modelId:'',
|
||||
* postId:''
|
||||
* }
|
||||
* @returns
|
||||
*/
|
||||
export function addStar(data){
|
||||
return request({
|
||||
url: '/modelPost/addStar',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 主页获取模特需求
|
||||
export function getModelRequire(id, page, size) {
|
||||
return request({
|
||||
url: '/modelPost/modelRequire/' + id,
|
||||
method: 'get',
|
||||
params: {
|
||||
pageNo: page,
|
||||
size: size
|
||||
}
|
||||
})
|
||||
}
|
||||
export function addModelComment(data) {
|
||||
return request({
|
||||
url: '/modelComment/add',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
//品牌主页点击评价,获取参与活动的模特名单
|
||||
export function getPostWithModel(data) {
|
||||
return request({
|
||||
url: '/modelPost/get',
|
||||
method: 'get',
|
||||
data
|
||||
})
|
||||
}
|
||||
//模特取消申请活动
|
||||
export function modelRevoke(data) {
|
||||
return request({
|
||||
url: '/modelPost/revoke',
|
||||
method: 'delete',
|
||||
data
|
||||
})
|
||||
}
|
||||
//模特签到
|
||||
export function modelSignIn(userId,postId,secretKey) {
|
||||
return request({
|
||||
url: '/modelPost/signIn',
|
||||
method: 'put',
|
||||
params:{
|
||||
userId,
|
||||
postId,
|
||||
secretKey,
|
||||
|
||||
},
|
||||
})
|
||||
}
|
||||
export function modelPost(postId) {
|
||||
return request({
|
||||
url: '/modelComment/get',
|
||||
method: 'get',
|
||||
params:{
|
||||
postId,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 获取推广
|
||||
export function getList() {
|
||||
return request(({
|
||||
url: '/promotion/all',
|
||||
method: 'get'
|
||||
}))
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 关键词检索
|
||||
export function searchByKeyword(query) {
|
||||
return request({
|
||||
url: `/search`,
|
||||
method: 'get',
|
||||
params: {
|
||||
keyword: query.keyword,
|
||||
pageNum: query.pageNum,
|
||||
pageSize: query.pageSize
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function getTopicsByTag(paramMap) {
|
||||
return request({
|
||||
url: '/tag/' + paramMap.name,
|
||||
method: 'get',
|
||||
params: {
|
||||
page: paramMap.page,
|
||||
size: paramMap.size
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function getTodayTip() {
|
||||
return request({
|
||||
url: '/tip/today',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 用户主页
|
||||
export function getInfoByName(username, page, size) {
|
||||
return request({
|
||||
url: '/ums/user/' + username,
|
||||
method: 'get',
|
||||
params: {
|
||||
pageNo: page,
|
||||
size: size
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export function getInfo() {
|
||||
return request({
|
||||
url: '/ums/user/info',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
export function getUser(id) {
|
||||
return request({
|
||||
url: '/ums/user/getUser',
|
||||
method: 'get',
|
||||
params:{
|
||||
id
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 更新
|
||||
export function update(user) {
|
||||
return request({
|
||||
url: '/ums/user/update',
|
||||
method: 'post',
|
||||
data: user
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,153 @@
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body,
|
||||
html {
|
||||
background-color: #ffc0cb0d;
|
||||
|
||||
color: black;
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
letter-spacing: 0.03em;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC,
|
||||
Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, WenQuanYi Micro Hei,
|
||||
sans-serif, Apple Color Emoji, Segoe UI Emoji, Noto Color Emoji,
|
||||
Segoe UI Symbol, Android Emoji, EmojiSymbols;
|
||||
}
|
||||
|
||||
/*背景图*/
|
||||
/*body {*/
|
||||
/* background-image: url('https://api.mz-moe.cn/img.php');*/
|
||||
/* background-repeat: round;*/
|
||||
/*}*/
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.container {
|
||||
width: 760px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 992px) {
|
||||
.container {
|
||||
width: 980px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.container {
|
||||
width: 1280px;
|
||||
}
|
||||
}
|
||||
|
||||
/*滚动条*/
|
||||
::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
/**/
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: rgb(239, 239, 239);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #bfbfbf;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-corner {
|
||||
background: #179a16;
|
||||
}
|
||||
|
||||
/* 头部 */
|
||||
.header {
|
||||
position: fixed;
|
||||
z-index: 89;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
min-width: 1032px;
|
||||
background: #fff;
|
||||
box-shadow: 0 3px 4px rgba(26, 26, 26, 0.1);
|
||||
height: 54px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #1d1d1d;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #f60;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
.shadow-1 {
|
||||
box-shadow: 0 0.5em 1em -0.125em rgba(10, 10, 10, 0.1),
|
||||
0 0 0 1px rgba(10, 10, 10, 0.02);
|
||||
}
|
||||
|
||||
.navbar-dropdown {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
|
||||
/*统一卡片样式*/
|
||||
.el-card {
|
||||
/*border-radius: 3px !important;*/
|
||||
margin-bottom: 16px;
|
||||
/*border: none;*/
|
||||
}
|
||||
|
||||
.my-card {
|
||||
cursor: pointer;
|
||||
transition: all 0.1s ease-in-out;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.my-card:hover {
|
||||
transform: scale(1.03);
|
||||
}
|
||||
|
||||
::selection {
|
||||
text-shadow: none;
|
||||
background: rgba(67, 135, 244, 0.56);
|
||||
}
|
||||
|
||||
/* 搜索框 */
|
||||
.search-bar input {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/*按钮居中*/
|
||||
.button-center {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.ellipsis {
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
margin: 0 auto;
|
||||
line-height: 1.4;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.is-ellipsis-1 {
|
||||
-webkit-line-clamp: 1;
|
||||
}
|
||||
|
||||
.is-ellipsis-2 {
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
|
||||
.is-ellipsis-3 {
|
||||
-webkit-line-clamp: 3;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 2.8 MiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 379 B |
|
After Width: | Height: | Size: 118 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 280 B |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 2.3 MiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 207 KiB |
|
After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 427 B |
|
After Width: | Height: | Size: 436 B |
|
After Width: | Height: | Size: 123 KiB |
|
After Width: | Height: | Size: 726 B |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 442 B |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 860 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 434 KiB |
@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<el-backtop :bottom="60" :right="60">
|
||||
<div title="回到顶部"
|
||||
style="{
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: #f2f5f6;
|
||||
box-shadow: 0 1px 0 0;
|
||||
border-radius: 12px;
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
color: #167df0;
|
||||
}"
|
||||
>
|
||||
<i class="fa fa-arrow-up"></i>
|
||||
</div>
|
||||
</el-backtop>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "BackTop"
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<section class="box comments">
|
||||
<hr />
|
||||
<h3 class="title is-5">Comments</h3>
|
||||
<lv-comments-form :slug="slug" v-if="token" @loadComments="fetchComments"/>
|
||||
|
||||
<lv-comments-item
|
||||
v-for="comment in comments"
|
||||
:key="`comment-${comment.id}`"
|
||||
:comment="comment"
|
||||
/>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import { fetchCommentsByTopicId } from '@/api/comment'
|
||||
import LvCommentsForm from './CommentsForm'
|
||||
import LvCommentsItem from './CommentsItem'
|
||||
|
||||
export default {
|
||||
name: 'LvComments',
|
||||
components: {
|
||||
LvCommentsForm,
|
||||
LvCommentsItem
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
comments: []
|
||||
}
|
||||
},
|
||||
props: {
|
||||
slug: {
|
||||
type: String,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'token'
|
||||
])
|
||||
},
|
||||
async mounted() {
|
||||
await this.fetchComments(this.slug)
|
||||
},
|
||||
methods: {
|
||||
// 初始化
|
||||
async fetchComments(topic_id) {
|
||||
console.log(topic_id)
|
||||
fetchCommentsByTopicId(topic_id).then(response => {
|
||||
const { data } = response
|
||||
this.comments = data
|
||||
console.log(this.comments)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<article class="media">
|
||||
<div class="media-content">
|
||||
<form @submit.prevent="onSubmit">
|
||||
<b-field>
|
||||
<b-input
|
||||
v-model.lazy="commentText"
|
||||
type="textarea"
|
||||
maxlength="400"
|
||||
placeholder="Add a comment..."
|
||||
:disabled="isLoading"
|
||||
></b-input>
|
||||
</b-field>
|
||||
<nav class="level">
|
||||
<div class="level-left">
|
||||
<b-button
|
||||
type="is-primary"
|
||||
native-type="submit"
|
||||
class="level-item"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Comment
|
||||
</b-button>
|
||||
</div>
|
||||
</nav>
|
||||
</form>
|
||||
</div>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { pushComment } from '@/api/comment'
|
||||
|
||||
export default {
|
||||
name: 'LvCommentsForm',
|
||||
data() {
|
||||
return {
|
||||
commentText: '',
|
||||
isLoading: false
|
||||
}
|
||||
},
|
||||
props: {
|
||||
slug: {
|
||||
type: String,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onSubmit() {
|
||||
this.isLoading = true
|
||||
try {
|
||||
let postData = {}
|
||||
console.log(this.commentText)
|
||||
postData['content'] = this.commentText
|
||||
postData['topic_id'] = this.slug
|
||||
await pushComment(postData)
|
||||
this.$emit('loadComments', this.slug)
|
||||
this.$message.success('留言成功')
|
||||
} catch (e) {
|
||||
this.$buefy.toast.open({
|
||||
message: `Cannot comment this story. ${e}`,
|
||||
type: 'is-danger'
|
||||
})
|
||||
} finally {
|
||||
this.isLoading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<article class="media">
|
||||
<figure class="media-left image is-48x48">
|
||||
<img :src=comment.avatar>
|
||||
</figure>
|
||||
<div class="media-content">
|
||||
<div class="content">
|
||||
<p>
|
||||
<strong>{{ comment.username }}</strong>
|
||||
<small class="ml-2">{{ comment.createTime | date }}</small>
|
||||
<br />
|
||||
{{ comment.content }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'LvCommentsItem',
|
||||
props: {
|
||||
comment: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@ -0,0 +1,103 @@
|
||||
<template>
|
||||
<div :class="{ hidden: hidden }" class="pagination-container">
|
||||
<el-pagination
|
||||
:background="background"
|
||||
:current-page.sync="currentPage"
|
||||
:page-size.sync="pageSize"
|
||||
:layout="layout"
|
||||
:page-sizes="pageSizes"
|
||||
:total="total"
|
||||
v-bind="$attrs"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {scrollTo} from "@/utils/scroll-to";
|
||||
|
||||
export default {
|
||||
name: "Pagination",
|
||||
props: {
|
||||
total: {
|
||||
required: true,
|
||||
type: Number,
|
||||
},
|
||||
page: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
limit: {
|
||||
type: Number,
|
||||
default: 10,
|
||||
},
|
||||
pageSizes: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [5, 10, 20, 30, 50];
|
||||
},
|
||||
},
|
||||
layout: {
|
||||
type: String,
|
||||
default: "total, sizes, prev, pager, next, jumper",
|
||||
// default: 'sizes, prev, pager, next, jumper'
|
||||
},
|
||||
background: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
autoScroll: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
hidden: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
currentPage: {
|
||||
get() {
|
||||
return this.page;
|
||||
},
|
||||
set(val) {
|
||||
this.$emit("update:page", val);
|
||||
},
|
||||
},
|
||||
pageSize: {
|
||||
get() {
|
||||
return this.limit;
|
||||
},
|
||||
set(val) {
|
||||
this.$emit("update:limit", val);
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleSizeChange(val) {
|
||||
this.$emit("pagination", { page: this.currentPage, limit: val });
|
||||
if (this.autoScroll) {
|
||||
scrollTo(0, 800);
|
||||
}
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.$emit("pagination", { page: val, limit: this.pageSize });
|
||||
if (this.autoScroll) {
|
||||
scrollTo(0, 800);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.pagination-container {
|
||||
/* background: #fff; */
|
||||
padding: 5px 0px;
|
||||
}
|
||||
|
||||
.pagination-container.hidden {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<div class="comment">
|
||||
<div class="comment-info">
|
||||
<span class="comment-user">{{ comment.name }}</span>
|
||||
<span class="comment-time">{{ comment.time }}</span>
|
||||
</div>
|
||||
<p class="comment-content">{{ comment.content }}</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
comment: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 样式可以根据需要进行调整 */
|
||||
.comment {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.comment-info {
|
||||
color: #888;
|
||||
font-size: 12px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.comment-user {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.comment-content {
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,25 @@
|
||||
// 定义懒加载指令
|
||||
const lazyLoadDirective = {
|
||||
// 指令的定义
|
||||
bind(el, binding) {
|
||||
// 使用 Intersection Observer 监听元素是否进入视口
|
||||
const observer = new IntersectionObserver(entries => {
|
||||
const { isIntersecting } = entries[0];
|
||||
if (isIntersecting) {
|
||||
// 当元素进入视口时,加载图片
|
||||
el.src = binding.value;
|
||||
observer.disconnect(); // 停止监听
|
||||
}
|
||||
});
|
||||
|
||||
// 将元素添加到 Intersection Observer 中进行监听
|
||||
observer.observe(el);
|
||||
},
|
||||
};
|
||||
|
||||
// 在 Vue 2 中注册懒加载指令
|
||||
export default {
|
||||
install(Vue) {
|
||||
Vue.directive('lazy', lazyLoadDirective);
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,44 @@
|
||||
import Vue from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import store from './store'
|
||||
// Buefy
|
||||
import Buefy from 'buefy'
|
||||
import 'buefy/dist/buefy.css'
|
||||
// ElementUI
|
||||
import ElementUI from 'element-ui';
|
||||
import 'element-ui/lib/theme-chalk/index.css';
|
||||
import '@/assets/app.css'
|
||||
import './assets/plugins/font-awesome-4.7.0/css/font-awesome.min.css'
|
||||
import format from 'date-fns/format'
|
||||
import '@/permission'
|
||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||
import LazyLoadDirective from '@/directives'
|
||||
|
||||
// 国际化
|
||||
import 'dayjs/locale/zh-cn'
|
||||
const dayjs = require('dayjs');
|
||||
|
||||
// 相对时间插件
|
||||
dayjs.extend(relativeTime)
|
||||
|
||||
dayjs.locale('zh-cn') // use locale globally
|
||||
dayjs().locale('zh-cn').format() // use locale in a specific instance
|
||||
|
||||
Vue.prototype.dayjs = dayjs;//可以全局使用dayjs
|
||||
|
||||
Vue.filter('date', (date) => {
|
||||
return format(new Date(date), 'yyyy-MM-dd')
|
||||
})
|
||||
|
||||
Vue.use(Buefy)
|
||||
Vue.use(ElementUI);
|
||||
Vue.use(LazyLoadDirective)
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
new Vue({
|
||||
router,
|
||||
store,
|
||||
render: h => h(App)
|
||||
}).$mount('#app')
|
||||
@ -0,0 +1,41 @@
|
||||
import router from './router'
|
||||
import store from './store'
|
||||
import getPageTitle from '@/utils/get-page-title'
|
||||
|
||||
import NProgress from 'nprogress' // progress bar
|
||||
import 'nprogress/nprogress.css'
|
||||
import {getToken} from "@/utils/auth"; // progress bar style
|
||||
|
||||
NProgress.configure({showSpinner: false}) // NProgress Configuration
|
||||
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
// start progress bar
|
||||
NProgress.start()
|
||||
// set page title
|
||||
document.title = getPageTitle(to.meta.title)
|
||||
// determine whether the user has logged in
|
||||
const hasToken = getToken();
|
||||
|
||||
if (hasToken) {
|
||||
if (to.path === '/login') {
|
||||
// 登录,跳转首页
|
||||
next({path: '/'})
|
||||
NProgress.done()
|
||||
} else {
|
||||
// 获取用户信息
|
||||
await store.dispatch('user/getInfo')
|
||||
next()
|
||||
}
|
||||
} else if (!to.meta.requireAuth)
|
||||
{
|
||||
next()
|
||||
}
|
||||
else {
|
||||
next('/login')
|
||||
}
|
||||
})
|
||||
|
||||
router.afterEach(() => {
|
||||
// finish progress bar
|
||||
NProgress.done()
|
||||
})
|
||||
@ -0,0 +1,140 @@
|
||||
import Vue from "vue";
|
||||
import VueRouter from "vue-router";
|
||||
|
||||
Vue.use(VueRouter);
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: "/",
|
||||
name: "Home",
|
||||
component: () => import("@/views/Home"),
|
||||
},
|
||||
{
|
||||
path: "/course",
|
||||
component: () => import("@/views/Course"),
|
||||
meta: { title: "课程" },
|
||||
},
|
||||
{
|
||||
path: "/course/:id",
|
||||
component: () => import("@/views/CourseInfo"),
|
||||
meta: { title: "课程详情" },
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
path: "/courseStudy/:courseId/:itemId",
|
||||
component: () => import("@/views/CourseStudy"),
|
||||
meta: { title: "课程章节学习",requireAuth: true },
|
||||
},
|
||||
{
|
||||
path: "/certification",
|
||||
component: () => import("@/views/Certification"),
|
||||
meta: { title: "童星认证",requireAuth: true },
|
||||
},
|
||||
{
|
||||
path: "/member",
|
||||
component: () => import("@/views/Member"),
|
||||
meta: { title: "我的会员",requireAuth: true },
|
||||
},
|
||||
{
|
||||
path: "/shopping",
|
||||
component: () => import("@/views/shop/Category/Clothes"),
|
||||
meta: { title: "童星服饰"},
|
||||
},
|
||||
{
|
||||
path: "/shopping/category/:id",
|
||||
component: () => import("@/views/shop/SubCategory/SubCategory"),
|
||||
meta: { title: "服饰分类" },
|
||||
},
|
||||
{
|
||||
path: "/clothesDetail/:id",
|
||||
component: () => import("@/views/shop/Detail/index"),
|
||||
meta: { title: "服饰详情" },
|
||||
},
|
||||
{
|
||||
path: "/register",
|
||||
name: "register",
|
||||
component: () => import("@/views/auth/Register"),
|
||||
meta: { title: "注册" },
|
||||
},
|
||||
// 登录
|
||||
{
|
||||
name: "login",
|
||||
path: "/login",
|
||||
component: () => import("@/views/auth/Login"),
|
||||
meta: { title: "登录" },
|
||||
},
|
||||
// 发布
|
||||
{
|
||||
name: "post-create",
|
||||
path: "/post/create",
|
||||
component: () => import("@/views/post/Create"),
|
||||
meta: { title: "信息发布", requireAuth: true },
|
||||
},
|
||||
// 编辑
|
||||
{
|
||||
name: 'topic-edit',
|
||||
path: '/topic/edit/:id',
|
||||
component: () => import('@/views/post/Edit'),
|
||||
meta: {
|
||||
title: '编辑',
|
||||
requireAuth: true
|
||||
}
|
||||
},
|
||||
// 详情
|
||||
{
|
||||
name: "post-detail",
|
||||
path: "/post/:id",
|
||||
component: () => import("@/views/post/Detail"),
|
||||
meta: { title: "详情" },
|
||||
},
|
||||
{
|
||||
name: 'tag',
|
||||
path: '/tag/:name',
|
||||
component: () => import('@/views/tag/Tag'),
|
||||
meta: { title: '主题列表' }
|
||||
},
|
||||
// 检索
|
||||
{
|
||||
name: 'search',
|
||||
path: '/search',
|
||||
component: () => import('@/views/Search'),
|
||||
meta: { title: '检索' }
|
||||
},
|
||||
// 用户主页
|
||||
{
|
||||
name: 'user',
|
||||
path: '/member/:username/home',
|
||||
component: () => import('@/views/user/Profile'),
|
||||
meta: { title: '用户主页' }
|
||||
},
|
||||
// 用户设置
|
||||
{
|
||||
name: 'user-setting',
|
||||
path: '/member/:username/setting',
|
||||
component: () => import('@/views/user/Setting'),
|
||||
meta: { title: '设置', requireAuth: true }
|
||||
},
|
||||
{
|
||||
path: "/404",
|
||||
name: "404",
|
||||
component: () => import("@/views/error/404"),
|
||||
meta: { title: "404-NotFound" },
|
||||
},
|
||||
// {
|
||||
// path: "*",
|
||||
// redirect: "/404",
|
||||
// hidden: true,
|
||||
// },
|
||||
];
|
||||
|
||||
const originalPush = VueRouter.prototype.push;
|
||||
VueRouter.prototype.push = function push(location) {
|
||||
return originalPush.call(this, location).catch((err) => err);
|
||||
};
|
||||
|
||||
const router = new VueRouter({
|
||||
routes,
|
||||
});
|
||||
|
||||
export default router;
|
||||
@ -0,0 +1,32 @@
|
||||
// store/cart.js
|
||||
|
||||
export default {
|
||||
state: {
|
||||
cartList: [],
|
||||
},
|
||||
mutations: {
|
||||
updateCartList(state, newList) {
|
||||
state.cartList = newList;
|
||||
},
|
||||
addCartItem(state,cartItem){
|
||||
state.cartList=cartItem;
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
actions: {
|
||||
// 如果需要异步加载购物车数据,可以在此处调用 API
|
||||
// 然后提交 mutation 更新购物车数据
|
||||
// updateCartListAction(context) {
|
||||
// const res = await fetchCartData();
|
||||
// context.commit('updateCartList', res.data);
|
||||
// },
|
||||
},
|
||||
getters : {
|
||||
allCount: (state) => state.cartList.reduce((a, c) => a + c.count, 0),
|
||||
allPrice: (state) => state.cartList.reduce((a, c) => a + c.count * c.price, 0),
|
||||
selectedCount: (state) => state.cartList.filter(item => item.selected).reduce((a, c) => a + c.count, 0),
|
||||
selectedPrice: (state) => state.cartList.filter(item => item.selected).reduce((a, c) => a + c.count * c.price, 0),
|
||||
isAll: (state) => state.cartList.every((item) => item.selected),
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,5 @@
|
||||
const getters = {
|
||||
token: state => state.user.token, // token
|
||||
user: state => state.user.user, // 用户对象
|
||||
}
|
||||
export default getters
|
||||
@ -0,0 +1,18 @@
|
||||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
import getters from './getters'
|
||||
import cartList from './cartStore'
|
||||
import user from './modules/user'
|
||||
|
||||
|
||||
Vue.use(Vuex)
|
||||
|
||||
const store = new Vuex.Store({
|
||||
modules: {
|
||||
user,
|
||||
cartList
|
||||
},
|
||||
getters
|
||||
})
|
||||
|
||||
export default store
|
||||
@ -0,0 +1,87 @@
|
||||
import { getUserInfo, login, logout } from "@/api/auth/auth";
|
||||
import { getToken, setToken, removeToken } from "@/utils/auth";
|
||||
|
||||
const state = {
|
||||
token: getToken(), // token
|
||||
user: "", // 用户对象
|
||||
};
|
||||
|
||||
const mutations = {
|
||||
SET_TOKEN_STATE: (state, token) => {
|
||||
state.token = token;
|
||||
},
|
||||
SET_USER_STATE: (state, user) => {
|
||||
state.user = user;
|
||||
},
|
||||
};
|
||||
|
||||
const actions = {
|
||||
// 用户登录
|
||||
login({ commit }, userInfo) {
|
||||
console.log(userInfo);
|
||||
const { name, pass, rememberMe } = userInfo;
|
||||
return new Promise((resolve, reject) => {
|
||||
login({ username: name.trim(), password: pass, rememberMe: rememberMe })
|
||||
.then((response) => {
|
||||
const { data } = response;
|
||||
commit("SET_TOKEN_STATE", data.token);
|
||||
setToken(data.token);
|
||||
resolve();
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 500);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
},
|
||||
// 获取用户信息
|
||||
getInfo({ commit, state }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
getUserInfo()
|
||||
.then((response) => {
|
||||
const { data } = response;
|
||||
if (!data) {
|
||||
commit("SET_TOKEN_STATE", "");
|
||||
commit("SET_USER_STATE", "");
|
||||
removeToken();
|
||||
resolve();
|
||||
reject("Verification failed, please Login again.");
|
||||
}
|
||||
commit("SET_USER_STATE", data);
|
||||
resolve(data);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
},
|
||||
// 注销
|
||||
async logout({ commit, state }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
logout(state.token)
|
||||
.then((response) => {
|
||||
console.log(response);
|
||||
commit("SET_TOKEN_STATE", "");
|
||||
commit("SET_USER_STATE", "");
|
||||
removeToken();
|
||||
resolve();
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 500);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
mutations,
|
||||
actions,
|
||||
};
|
||||
@ -0,0 +1,30 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 用户主页
|
||||
export function getInfoByName(username, page, size) {
|
||||
return request({
|
||||
url: '/ums/user/' + username,
|
||||
method: 'get',
|
||||
params: {
|
||||
pageNo: page,
|
||||
size: size
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 用户主页
|
||||
export function getInfo() {
|
||||
return request({
|
||||
url: '/ums/user/info',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 更新
|
||||
export function update(user) {
|
||||
return request({
|
||||
url: '/ums/user/update',
|
||||
method: 'post',
|
||||
data: user
|
||||
})
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
import request from './request'
|
||||
|
||||
//获取购物车商品
|
||||
export function getShopCarList(){
|
||||
return request({
|
||||
url:'/api/shopcar/getShopCarList',
|
||||
})
|
||||
}
|
||||
|
||||
//删除购物车
|
||||
export function deleteShopCar( params , token ){
|
||||
return request({
|
||||
url:'/api/shopcar/deleteShopCar',
|
||||
params,
|
||||
headers:{
|
||||
token
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//删除购物车[批量]
|
||||
export function deleteShopCars( ids, token ){
|
||||
return request({
|
||||
url:'/api/shopcar/deleteShopCars',
|
||||
method: 'POST',
|
||||
data:ids,
|
||||
headers:{
|
||||
token
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//加入购物车
|
||||
export function addShopCar( data , token ){
|
||||
return request({
|
||||
url:'/api/shopcar/addShopCar',
|
||||
method:'post',
|
||||
data,
|
||||
headers:{
|
||||
token
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
import request from './request'
|
||||
|
||||
//创建Token
|
||||
export function createToken(){
|
||||
return request({
|
||||
url:'/api/token/createToken',
|
||||
})
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
import request from './request'
|
||||
|
||||
|
||||
//用户名密码登录
|
||||
export function loginByJson( data ){
|
||||
return request({
|
||||
url:'/api/u/loginByJson',
|
||||
method:'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//发送注册或登录验证码
|
||||
export function sendCaptcha( params ){
|
||||
return request({
|
||||
url:'/api/sms/sendRegisterOrLoginCaptcha',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
//手机验证码登录
|
||||
export function loginByMobile( data ){
|
||||
return request({
|
||||
url:'/api/u/loginByMobile',
|
||||
method:'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//获取个人信息
|
||||
export function getInfo( params ){
|
||||
return request({
|
||||
url:'/api/member/getInfo',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//退出登录
|
||||
export function logout(){
|
||||
return request({
|
||||
url:'/api/u/logout'
|
||||
})
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
import request from './request'
|
||||
|
||||
//去结算
|
||||
export function settlement( data ){
|
||||
return request({
|
||||
url:'/api/order/settlement',
|
||||
method:"post",
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//支付宝结算
|
||||
export function alipayOrder( data ){
|
||||
return request({
|
||||
url:'/api/pay/alipay/createOrder',
|
||||
method:"post",
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//查询支付宝,支付订单状态
|
||||
export function queryAlipay( params ){
|
||||
return request({
|
||||
url:'/api/pay/alipay/queryOrder',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//微信结算
|
||||
export function wxpayOrder( data ){
|
||||
return request({
|
||||
url:'/api/pay/wxpay/createOrder',
|
||||
method:"post",
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//查询微信,支付订单状态
|
||||
export function queryWxpay( params ){
|
||||
return request({
|
||||
url:'/api/pay/wxpay/queryOrder',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
const title = '童星闪耀'
|
||||
|
||||
export default function getPageTitle(pageTitle) {
|
||||
if (pageTitle) {
|
||||
return `${pageTitle} - ${title}`
|
||||
}
|
||||
return `${title}`
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
Math.easeInOutQuad = function(t, b, c, d) {
|
||||
t /= d / 2
|
||||
if (t < 1) {
|
||||
return c / 2 * t * t + b
|
||||
}
|
||||
t--
|
||||
return -c / 2 * (t * (t - 2) - 1) + b
|
||||
}
|
||||
|
||||
// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
|
||||
var requestAnimFrame = (function() {
|
||||
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) }
|
||||
})()
|
||||
|
||||
/**
|
||||
* Because it's so fucking difficult to detect the scrolling element, just move them all
|
||||
* @param {number} amount
|
||||
*/
|
||||
function move(amount) {
|
||||
document.documentElement.scrollTop = amount
|
||||
document.body.parentNode.scrollTop = amount
|
||||
document.body.scrollTop = amount
|
||||
}
|
||||
|
||||
function position() {
|
||||
return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} to
|
||||
* @param {number} duration
|
||||
* @param {Function} callback
|
||||
*/
|
||||
export function scrollTo(to, duration, callback) {
|
||||
const start = position()
|
||||
const change = to - start
|
||||
const increment = 20
|
||||
let currentTime = 0
|
||||
duration = (typeof (duration) === 'undefined') ? 500 : duration
|
||||
var animateScroll = function() {
|
||||
// increment the time
|
||||
currentTime += increment
|
||||
// find the value with the quadratic in-out easing function
|
||||
var val = Math.easeInOutQuad(currentTime, start, change, duration)
|
||||
// move the document.body
|
||||
move(val)
|
||||
// do the animation unless its over
|
||||
if (currentTime < duration) {
|
||||
requestAnimFrame(animateScroll)
|
||||
} else {
|
||||
if (callback && typeof (callback) === 'function') {
|
||||
// the animation is done so lets callback
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
animateScroll()
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
<template>
|
||||
<div class="course-study">
|
||||
<h1>{{ courseVideos.name }}</h1>
|
||||
<div class="video-container">
|
||||
<iframe class="bilibili-video" :src="'//player.bilibili.com/player.html?bvid=' + courseVideos.bvdid" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"></iframe> </div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getVideoDetail} from '../api/courseManage'
|
||||
|
||||
export default {
|
||||
data(){
|
||||
return{
|
||||
courseId:this.$route.params.courseId,
|
||||
videoId:this.$route.params.itemId,
|
||||
courseVideos:{}
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
getVideoDetail(this.courseId,this.videoId).then((res) => {
|
||||
this.courseVideos=res.data;
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
h1{
|
||||
width: 300px;
|
||||
height: 200px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
margin-left: -150px;
|
||||
background-image: -webkit-linear-gradient(left,blue,#66ffff 10%,#cc00ff 20%,#CC00CC 30%, #CCCCFF 40%, #00FFFF 50%,#CCCCFF 60%,#CC00CC 70%,#CC00FF 80%,#66FFFF 90%,blue 100%);
|
||||
-webkit-text-fill-color: transparent;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-background-size: 200% 100%;
|
||||
-webkit-animation: masked-animation 4s linear infinite;
|
||||
font-size: 35px;
|
||||
}
|
||||
.course-study {
|
||||
max-width: 1340px; /* 设置最大宽度为div的宽度 */
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
|
||||
}
|
||||
|
||||
.video-container {
|
||||
margin-top: 70px;
|
||||
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
width: 100%; /* 宽度占满父容器 */
|
||||
position: relative;
|
||||
padding-bottom: 42.91%; /* 设置为16:9的宽高比例 */
|
||||
}
|
||||
|
||||
.bilibili-video {
|
||||
width: 100%;
|
||||
height: 100%; /* 100% 的高度 */
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="box">🔔 {{ billboard.content }}</div>
|
||||
<div class="columns">
|
||||
<div class="column is-three-quarters">
|
||||
<TopicList></TopicList>
|
||||
</div>
|
||||
<div class="column">
|
||||
<CardBar></CardBar>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getBillboard } from "@/api/billboard";
|
||||
import CardBar from "@/views/card/CardBar"
|
||||
import PostList from '@/views/post/Index'
|
||||
|
||||
export default {
|
||||
name: "Home",
|
||||
components: {CardBar, TopicList: PostList},
|
||||
data() {
|
||||
return {
|
||||
billboard: {
|
||||
content: "",
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.fetchBillboard();
|
||||
},
|
||||
methods: {
|
||||
async fetchBillboard() {
|
||||
getBillboard().then((value) => {
|
||||
const { data } = value;
|
||||
this.billboard = data;
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-card shadow="never">
|
||||
<div slot="header" class="clearfix">
|
||||
检索到 <code>{{ list.length }}</code>
|
||||
条关于 <code class="has-text-info">{{ query.keyword }}</code> 的记录
|
||||
</div>
|
||||
<div>
|
||||
<article v-for="(item, index) in list" :key="index" class="media">
|
||||
<div class="media-left">
|
||||
<figure class="image is-48x48">
|
||||
<img :src=item.avatar>
|
||||
</figure>
|
||||
</div>
|
||||
<div class="media-content">
|
||||
<div class="">
|
||||
<p class="ellipsis is-ellipsis-1">
|
||||
<el-tooltip class="item" effect="dark" :content="item.title" placement="top">
|
||||
<router-link :to="{name:'post-detail',params:{id:item.id}}">
|
||||
<span class="is-size-6">{{ item.title }}</span>
|
||||
</router-link>
|
||||
</el-tooltip>
|
||||
</p>
|
||||
</div>
|
||||
<nav class="level has-text-grey is-mobile is-size-7 mt-2">
|
||||
<div class="level-left">
|
||||
<div class="level-left">
|
||||
<router-link class="level-item" :to="{ path: `/member/${item.username}/home` }">
|
||||
{{ item.alias }}
|
||||
</router-link>
|
||||
|
||||
<span class="mr-1">
|
||||
发布于:{{ dayjs(item.createTime).format("YYYY/MM/DD") }}
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-for="(tag, index) in item.tags"
|
||||
:key="index"
|
||||
class="tag is-hidden-mobile is-success is-light mr-1"
|
||||
>
|
||||
<router-link :to="{ name: 'tag', params: { name: tag.name } }">
|
||||
{{ "#" + tag.name }}
|
||||
</router-link>
|
||||
</span>
|
||||
|
||||
<span class="is-hidden-mobile">浏览:{{ item.view }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="media-right" />
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<!--分页-->
|
||||
<pagination
|
||||
v-show="query.total > 0"
|
||||
:total="query.total"
|
||||
:page.sync="query.pageNum"
|
||||
:limit.sync="query.pageSize"
|
||||
@pagination="fetchList"
|
||||
/>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { searchByKeyword } from '@/api/search'
|
||||
import Pagination from '@/components/Pagination'
|
||||
|
||||
export default {
|
||||
name: 'Search',
|
||||
components: { Pagination },
|
||||
data() {
|
||||
return {
|
||||
list: [],
|
||||
query: {
|
||||
keyword: this.$route.query.key,
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
total: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchList()
|
||||
},
|
||||
methods: {
|
||||
fetchList() {
|
||||
searchByKeyword(this.query).then(value => {
|
||||
const { data } = value
|
||||
this.list = data.records
|
||||
this.query.total = data.total
|
||||
this.query.pageSize = data.size
|
||||
this.query.pageNum = data.current
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||