Sfoglia il codice sorgente

Merge branch 'feat' into test

test
chenJinxu 9 mesi fa
parent
commit
ad1267e90c
11 ha cambiato i file con 970 aggiunte e 237 eliminazioni
  1. +29
    -40
      src/api/optimize.js
  2. +17
    -2
      src/components/TabBar.vue
  3. +7
    -0
      src/router/router.config.js
  4. +10
    -1
      src/store/index.js
  5. +2
    -0
      src/views/insight/index.vue
  6. +236
    -0
      src/views/optimize/expertChat.vue
  7. +42
    -32
      src/views/optimize/index.vue
  8. +223
    -0
      src/views/optimize/scss/expertChat.scss
  9. +97
    -19
      src/views/optimize/scss/index.scss
  10. +164
    -82
      src/views/optimize/scss/trainingcamp.scss
  11. +143
    -61
      src/views/optimize/trainingcamp.vue

+ 29
- 40
src/api/optimize.js Vedi File

@@ -1,54 +1,43 @@
import request from '@/config/request_java';
import request from '@/config/request';

export const APIOptimize = {
getExpertList, // 获取专家列表
getTalkList, // 获取养育话题列表
addTalkLabels, // 新增养育话题标签
getCampList, // 获取训练营列表
getCampRecommendList // 获取训练营推荐列表
getCampList, // 获取训练营列表
getTrainingCampDetail, //获取训练营-详情-简介+内容
getTrainingCampDetailComment, //获取训练营-详情-评论
comment //评论课程
};
export default APIOptimize;

// 获取专家列表
function getExpertList(id) {
// 获取训练营列表
function getCampList(params) {
return request({
url: `/java_api/optimize/getExpertList`,
method: 'get',
params: { id }
url: `/api/HealthyCMS/GetTrainingCamp`,
method: 'post',
data: params
});
}

// 获取养育话题列表
function getTalkList(id) {
return request({
url: `/java_api/optimize/getTalkList`,
method: 'get',
params: { id }
});
}

// 新增养育话题标签
function addTalkLabels(params) {
return request({
url: `/java_api/optimize/addTalkLabels`,
method: 'post',
data: params
});
}

// 获取训练营列表
function getCampList(id) {
// 获取训练营-详情-简介+内容
function getTrainingCampDetail(data) {
return request({
url: `/java_api/optimize/getCampList`,
method: 'get',
params: { id }
url: `/api/HealthyCMS/GetTrainingCampDetail`,
method: 'post',
params: data
});
}
// 获取训练营-详情-评论
function getTrainingCampDetailComment(params) {
return request({
url: `/api/HealthyCMS/GetTrainingCampDetailComment`,
method: 'post',
data: params
});
}

// 获取训练营推荐列表
function getCampRecommendList() {
//评论课程
function comment(params) {
return request({
url: `/java_api/optimize/getCampRecommendList`,
method: 'get'
url: `/api/HealthyCMS/Comment`,
method: 'post',
data: params
});
}
}

+ 17
- 2
src/components/TabBar.vue Vedi File

@@ -1,6 +1,6 @@
<template>
<div>
<van-tabbar fixed route v-model="active" @change="handleChange">
<van-tabbar fixed route v-model="active" @change="handleChange" v-if="isShow">
<van-tabbar-item v-for="(item, index) in tabbars" :to="item.to" :key="index">
{{ item.title }}
<template #icon="props">
@@ -19,6 +19,11 @@ export default {
default: 0
}
},
computed: {
isShow() {
return this.showList.indexOf(this.$route.name) > -1
}
},
data() {
return {
active: this.defaultActive,
@@ -73,7 +78,14 @@ export default {
inactive: require('../assets/com-imges/55_14.png')
}
}
]
],
showList: [
'Optimize',
'Myself',
'Insight',
'Today',
'Development'
],
};
},
methods: {
@@ -89,14 +101,17 @@ export default {
h3 {
margin: 40px 0 0;
}

ul {
list-style-type: none;
padding: 0;
}

li {
display: inline-block;
margin: 0 10px;
}

a {
color: #42b983;
}


+ 7
- 0
src/router/router.config.js Vedi File

@@ -320,6 +320,13 @@ export const constantRouterMap = [
component: () => import('@/views/optimize/talk'),
meta: { title: '养育话题', keepAlive: false }
},
{
path: '/expertChat',
name: 'expertChat',
component: () => import('@/views/optimize/expertChat'),
meta: { title: '专家对话', keepAlive: false }
},

{
path: '/personList',
name: 'personList',


+ 10
- 1
src/store/index.js Vedi File

@@ -52,7 +52,8 @@ export default new Vuex.Store({
ssjlToken: '', //b端接口token
tabClick: '', //心理监测点击tab
personId: '', //设备列表的personId
uid: '' //心理相关用户的uid
uid: '', //心理相关用户的uid
campId: '' //训练营Id
},
mutations: {
authToken(state, token) {
@@ -188,6 +189,10 @@ export default new Vuex.Store({
uid(state, uid) {
state.uid = uid;
window.localStorage[prefix + 'uid'] = uid;
},
campId(state, campId) {
state.campId = campId;
window.localStorage[prefix + 'campId'] = campId;
}
},
getters: {
@@ -339,6 +344,10 @@ export default new Vuex.Store({
uid: state => {
if (state.uid != '') return state.uid;
return window.localStorage[prefix + 'uid'] == null ? '' : window.localStorage[prefix + 'uid'];
},
campId: state => {
if (state.campId != '') return state.campId;
return window.localStorage[prefix + 'campId'] == null ? '' : window.localStorage[prefix + 'campId'];
}
},
actions: {},


+ 2
- 0
src/views/insight/index.vue Vedi File

@@ -285,6 +285,7 @@ export default {
},
created() {
this.getAuth();

this.emoName = this.psyList[this.emotionActive].name;
this.initEchartText();

@@ -293,6 +294,7 @@ export default {
mounted() {
this.initData();
this.getPsychologiclData();

},
watch: {
active(val) {


+ 236
- 0
src/views/optimize/expertChat.vue Vedi File

@@ -0,0 +1,236 @@
<!-- -->
<template>
<div class="expert-chat">
<NavBar :title="title" @on-click-left="onNavBack"> </NavBar>
<div class="chat-container" ref="chatBox">
<van-pull-refresh v-model="refreshing" @refresh="onRefresh" v-if="false">
<van-list v-model="loading" :finished="finished" finished-text="没有更多了" @load="onLoad">
<!-- <van-cell v-for="item in list" :key="item" :title="item" /> -->
<div v-for="(item, index) in chatList" :key="index" :class="item.class">
<!-- 左边 -->

<div :class="item.leftClass">
<!-- 专家部分 -->
<div class="avatar" v-if="item.class !== 'mine'">
<img :src="defaultImg" alt="">
</div>
<!-- 用户部分 -->
<div class="mine-con" v-else>
<p>{{ item.time }}</p>

<div class="text">
<span>{{ item.text }}</span>
</div>
</div>


</div>
<div :class="item.rightClass">
<!-- 用户部分 -->
<div class="avatar" v-if="item.class === 'mine'">
<img :src="defaultImg" alt="">
</div>
<!-- 专家部分 -->
<div class="mine-con" v-else>
<p>{{ item.time }}</p>

<div class="text">
<span>{{ item.text }}</span>
</div>
</div>

</div>




</div>
</van-list>
</van-pull-refresh>

<!-- 短语 -->
<div class="short-text">
<div class="btn" v-for="(item, index) in shortList" :key="index" :style="{ backgroundColor: item.bgColor }"
@click="onAddChat(item)">
<p>{{ item.name }}</p>
</div>
</div>
</div>
<div class="send">
<div class="left">
<van-cell-group>
<van-field v-model="chat" placeholder="说点什么" />
</van-cell-group>
</div>
<div class="right" @click="onSend">
<div class="circle">发送</div>
</div>
</div>
</div>
</template>

<script>
import NavBar from '@/components/NavBar';
export default {
components: {
NavBar,
},
data() {
return {
chat: '',
list: [],
loading: false,
finished: false,
refreshing: false,
defaultImg: require('../../assets/myself/4_62.png'),
chatList: [
{
time: '2024-02-24',
text: '也可以与 CellGroup 搭配使用,CellGroup 可以为 Cell 提供上下外边框。',
class: 'cell-chat',
leftClass: 'left',
rightClass: 'right'

}, {
time: '2024-02-24',
text: '也可以与 CellGroup 搭配使用,CellGroup 可以为 Cell 提供上下外边框。',
class: 'cell-chat',
leftClass: 'left',
rightClass: 'right'

},
{
time: '2024-02-24',
text: '也可以与 CellGroup 搭配使用,CellGroup 可以为 Cell 提供上下外边框。',
class: 'mine',
leftClass: 'left',
rightClass: 'right'

},
{
time: '2024-02-24',
text: '也可以与 CellGroup 搭配使用,CellGroup 可以为 Cell 提供上下外边框。',
class: 'cell-chat',
leftClass: 'left',
rightClass: 'right'

},
/* {
time: '2024-02-24',
text: '也可以与 CellGroup 搭配使用,CellGroup 可以为 Cell 提供上下外边框。',
class: 'mine',
leftClass: 'left',
rightClass: 'right'

},
{
time: '2024-02-24',
text: '也可以与 CellGroup 搭配使用,CellGroup 可以为 Cell 提供上下外边框。',
class: 'cell-chat',
leftClass: 'left',
rightClass: 'right'

},
{
time: '2024-02-24',
text: '也可以与 CellGroup 搭配使用,CellGroup 可以为 Cell 提供上下外边框。',
class: 'cell-chat',
leftClass: 'left',
rightClass: 'right'

},
{
time: '2024-02-24',
text: '也可以与 CellGroup 搭配使用,CellGroup 可以为 Cell 提供上下外边框。',
class: 'mine',
leftClass: 'left',
rightClass: 'right'

},
{
time: '2024-02-24',
text: '也可以与 CellGroup 搭配使用,CellGroup 可以为 Cell 提供上下外边框。',
class: 'mine',
leftClass: 'left',
rightClass: 'right'

}, */
],
shortList: [
{ name: '赞', bgColor: 'red' },
{ name: '有道理', bgColor: 'green' },
{ name: '说的透彻', bgColor: 'red' },
{ name: '是这样的', bgColor: 'green' },
{ name: '有道理', bgColor: 'green' },
{ name: '有道理', bgColor: 'red' },
{ name: '学习了', bgColor: 'green' },
]
}
},
created() {

},
computed: {
title() {
return this.$route.query.title || ''
}
},
mounted() {
this.scrollToBottom(); // 页面加载时也滚动到底部
},
methods: {
scrollToBottom() {
this.$refs.chatBox.scrollTop = this.$refs.chatBox.scrollHeight;
},
onNavBack() {
this.$router.push({
name: 'trainingcamp'
})
},
onLoad() {
setTimeout(() => {
if (this.refreshing) {
this.list = [];
this.refreshing = false;
}

for (let i = 0; i < 10; i++) {
this.list.push(this.list.length + 1);
}
this.loading = false;

if (this.list.length >= 40) {
this.finished = true;
}
}, 1000);
},
onRefresh() {
// 清空列表数据
this.finished = false;

// 重新加载数据
// 将 loading 设置为 true,表示处于加载状态
this.loading = true;
this.onLoad();
},
onAddChat(item) {
this.chat = item.name;
},
onSend() {
/* let message = {
time: '2024-02-24',
text: this.chat,
class: 'mine',
leftClass: 'left',
rightClass: 'right'
};
this.chatList.push(message); */
// TODO,调取接口
}
},
}
</script>
<style scoped lang="scss">
@import './scss/expertChat.scss';
/* @import url(); 引入css类 */
</style>

+ 42
- 32
src/views/optimize/index.vue Vedi File

@@ -10,10 +10,10 @@
</van-swipe-item>
</van-swipe>
</div>
<!-- 养育话题 -->
<!-- 心理急救包 -->
<div class="parenting">
<div class="title">
<p>养育话题</p>
<p>心理急救包</p>
<a>查看更多</a>
</div>
<ul>
@@ -41,24 +41,13 @@
</div>
<div class="main">
<ul>
<li @click="goTrainingcamp(1)">
<li v-for="(item, index) in campList" :key="index" @click="goTrainingcamp(item)">
<div class="left">
<p>情绪管理控制</p>
<span>入门易学</span>
<p>{{ item.name }}</p>
<span>{{ item.summary }}</span>
<div>
<h5>会员价 ¥998</h5>
<s>¥1288</s>
</div>
</div>
<img src="@/assets/today/images/2_42.png" />
</li>
<li @click="goTrainingcamp(2)">
<div class="left">
<p>情绪管理控制</p>
<span>入门易学</span>
<div>
<h5>会员价 ¥998</h5>
<s>¥1288</s>
<h5>会员价 ¥{{ item.vipPrice }}</h5>
<s>¥{{ item.price }}</s>
</div>
</div>
<img src="@/assets/today/images/2_42.png" />
@@ -66,10 +55,10 @@
</ul>
</div>
</div>
<!-- 心理咨询 -->
<!-- 专家咨询 -->
<div class="psychology">
<div class="title">
<p>心理咨询</p>
<p>专家咨询</p>
</div>
<div class="select">
<ul>
@@ -103,7 +92,10 @@
<div class="top">
<p>黛建松</p>
<span>清华大学心理学教授</span>
<img src="@/assets/optimize/images/3_48.png" alt="" />
<div class="avatar">
<img src="@/assets/optimize/images/3_48.png" alt="" />
</div>

</div>
<div class="bottom">
<h4>700人次<span>咨询</span>,<span>从业</span>8年</h4>
@@ -116,12 +108,14 @@
<li>家庭关系</li>
<li>压力管理</li>
</ul>
<div>
<h5>
<img src="@/assets/optimize/icons/location.png" alt="" />
<span>郴州市苏仙区</span>
</h5>
<p>¥2480</p>
<div class="vip-tips">
<div class="vip-text">
<!-- <img src="@/assets/optimize/icons/location.png" alt="" /> -->
<span>会员免费</span>
</div>
<div class="price-strike">
<span>¥2480</span>
</div>
</div>
</div>
</div>
@@ -136,6 +130,7 @@ import Vue from 'vue';
import TabBar from '@/components/TabBar';
import expertImage from '@/assets/optimize/images/3_08.png';
import { Swipe, SwipeItem, Lazyload } from 'vant';
import APIOptimize from '@/api/optimize';
Vue.use(Lazyload);
Vue.use(Lazyload, {
lazyComponent: true
@@ -158,12 +153,26 @@ export default {
id: 2,
image: expertImage
}
]
],
campList: []
};
},
created() {},
mounted() {},
created() { },
mounted() {
this.$nextTick(() => {
this.getCampList();
})
},
methods: {
getCampList() {

APIOptimize.getCampList().then(res => {
console.log("训练营列表", res);
let data = res.data.data;
this.campList = data;
console.log("this.campList", this.campList);
})
},
goExperts(id) {
this.$router.push({
name: 'experts',
@@ -172,11 +181,12 @@ export default {
}
});
},
goTrainingcamp(id) {
goTrainingcamp(item) {
this.$store.commit('campId', item.id);
this.$router.push({
name: 'trainingcamp',
query: {
id: id
id: item.id
}
});
}


+ 223
- 0
src/views/optimize/scss/expertChat.scss Vedi File

@@ -0,0 +1,223 @@
.expert-chat {
height: 100vh;
overflow: hidden;

.chat-container {
/* position: relative; */
height: calc(100vh - 230px);
overflow: scroll;
margin-top: 100px;
padding: 0 20px;
@include center();

.van-list {
/* height: 100% !important; */

.cell-chat {
height: 100%;
padding: 5px 0;
margin: 10px 0;
display: flex;
justify-content: flex-start;
align-items: flex-end;

.left {
position: relative;
height: 100%;
width: 15%;
font-size: 14px;
display: flex;
justify-content: flex-start;
align-items: center;

.avatar {
height: 45px;
width: 45px;
@include center();
border-radius: 50%;

img {
height: 100%;
width: 100%;
}
}
}

.right {
width: 60%;

font-size: 14px;
margin-left: 15px;


p {
text-align: left;
font-size: 12px;
padding-left: 10px;
}

.text {
position: relative;
min-height: 50px;
border: .5px;
background-color: rgb(223, 218, 218);
border-radius: 10px;
padding: 10px 8px;
line-height: 20px;
margin-top: 5px;
z-index: 98;
}

.text :before {
content: '';
position: absolute;
bottom: 15%;
left: -20px;
width: 0;
height: 0;
border-style: solid;
border-width: 6px 25px 6px 0;
/* 调整这些值以改变三角形大小 */
border-color: transparent rgb(223, 218, 218) transparent transparent;
z-index: 90;
/* 左边是三角形可见部分的颜色 */
}


}


}

.mine {
height: 100%;
padding: 5px 0;
margin: 10px 0;
display: flex;
justify-content: flex-end;
align-items: flex-end;

.right {
position: relative;
height: 100%;
width: 15%;
font-size: 14px;
display: flex;
justify-content: flex-end;
align-items: flex-end;

.avatar {
height: 45px;
width: 45px;
display: flex;
justify-content: flex-end;
align-items: flex-end;
border-radius: 50%;

img {
height: 100%;
width: 100%;
}
}
}

.left {
width: 60%;

font-size: 14px;
margin-right: 15px;

p {
text-align: right;
font-size: 12px;
padding-right: 10px;
}

.text {
position: relative;
text-align: left;
min-height: 50px;
border: .5px;
background-color: rgb(223, 218, 218);
border-radius: 10px;
padding: 10px 8px;
line-height: 20px;
margin-top: 5px;
}

.text :before {
content: '';
position: absolute;
/* 让三角形居中对齐 */
bottom: 15%;
right: -20px;
width: 0;
height: 0;
border-style: solid;
border-width: 6px 25px 6px 0;
transform: rotate(180deg);
/* 调整这些值以改变三角形大小 */
border-color: transparent rgb(223, 218, 218) transparent transparent;
/* 左边是三角形可见部分的颜色 */
}


}
}
}

.short-text {
/* height: 100%; */
display: grid;
grid-template-columns: repeat(4, 1fr);
/* 或者固定宽度,例如:repeat(4, 1fr) */
gap: 10px;
/* 可选,用于设置列与列之间的间距 */

.btn {
height: 40px;
padding: 15px 20px;
font-size: 28px;
border-radius: 70px;
color: #fff;
@include center();
}
}
}

.send {
position: relative;
height: 90px;
padding-left: 20px;
padding-right: 40px;
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 20px;

.left {
height: 70px;
width: 70%;
border: 1px solid #000;
border-radius: 70px;
padding: 10px 40px;
display: flex;
justify-content: flex-start;
align-items: center;

.van-cell {
padding: 0 !important;
}
}

.right {
height: 90px;
width: 90px;
@include center();
background-color: $green;
border-radius: 50%;
font-size: 32px;
color: #fff;
}
}
}

+ 97
- 19
src/views/optimize/scss/index.scss Vedi File

@@ -1,25 +1,31 @@
.optimize {
min-height: 100vh;

.expert-box {
padding: 40px 32px;
height: 400px;

.van-swipe {
height: 100%;
}

img {
width: 100%;
height: 100%;
object-fit: contain;
}

.summary {
position: absolute;
top: 30%;
left: 20px;

h4 {
font-size: 52px;
color: #fff;
font-weight: bold;
}

p {
font-size: 24px;
color: #fff;
@@ -28,6 +34,7 @@
max-width: 300px;
}
}

.van-swipe-item {
position: relative;
// p {
@@ -42,12 +49,14 @@
// }
}
}

.title {
display: flex;
flex-wrap: wrap;
align-items: center;
align-content: space-between;
justify-content: space-between;

p {
font-size: 26px;
color: #fff;
@@ -56,6 +65,7 @@
border-radius: 40px;
font-weight: bold;
}

a {
font-size: 20px;
color: #000;
@@ -65,8 +75,10 @@
font-weight: bold;
}
}

.parenting {
padding: 0 32px;

ul {
width: 100%;
margin-top: 24px;
@@ -74,25 +86,31 @@
flex-wrap: wrap;
align-items: center;
justify-content: flex-start;

li {
width: 32%;

&:nth-of-type(n+4) {
display: none;
}
& + li {

&+li {
margin-left: 2%;
}

img {
width: 100%;
height: 200px;
object-fit: contain;
}

p {
text-align: center;
font-size: 30px;
color: #000;
font-weight: bold;
}

span {
text-align: center;
font-size: 20px;
@@ -103,11 +121,14 @@
}
}
}

.train {
padding: 52px 32px;

.main {
width: 100%;
overflow-x: scroll;

ul {
width: max-content;
margin-top: 30px;
@@ -115,6 +136,7 @@
flex-wrap: wrap;
align-items: center;
justify-content: flex-start;

li {
width: 480px;
background-color: #2ea7e0;
@@ -124,9 +146,11 @@
align-items: center;
align-content: space-between;
justify-content: space-between;
& + li {

&+li {
margin-left: 30px;
}

.left {
p {
font-size: 38px;
@@ -134,17 +158,20 @@
font-weight: bold;
min-height: 96px;
}

span {
display: block;
font-size: 30px;
color: #000;
}

div {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: flex-start;
margin-top: 10px;

h5 {
padding: 8px 16px;
background-color: #000;
@@ -152,6 +179,7 @@
color: #c2813f;
border-radius: 20px;
}

s {
font-style: normal;
font-size: 24px;
@@ -161,6 +189,7 @@
}
}
}

img {
height: 140px;
object-fit: contain;
@@ -169,59 +198,84 @@
}
}
}

.psychology {
padding-bottom: 40px;

.title {
padding: 0 32px;
}

.select {
margin: 30px 0 0 32px;
overflow-x: scroll;

ul {
width: max-content;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: flex-start;

li {
img {
width: 100px;
height: 100px;
object-fit: contain;
}
& + li {

&+li {
margin-left: 25px;
}
}
}
}

.main {
padding: 0 32px;
margin-top: 30px;

.top {
background-color: #179b3b;
border-radius: 60px;
padding: 40px;
position: relative;
height: 280px;

p {
color: #fff;
font-size: 54px;
font-weight: bold;
}

span {
color: #fff;
font-size: 26px;
font-weight: normal;
}
img {

.avatar {
height: 240px;
width: 240px;
position: absolute;
bottom: 0;
right: 0;
object-fit: contain;
width: 55%;
bottom: 20%;
right: 5%;
border: 10px solid $com_light_green;
border-radius: 50%;
@include center();

img {
/* position: absolute;
bottom: 0;
right: 0; */
height: 65%;
object-fit: contain;
width: 55%;
}
}

}

.bottom {
padding: 40px 30px;
border-radius: 60px;
@@ -230,15 +284,18 @@
z-index: 2;
position: relative;
background-color: #fff;

h4 {
padding: 0 20px;
font-size: 32px;
color: #000;

span {
color: #a3a3a3;
margin: 0 6px;
}
}

ul {
width: 100%;
display: flex;
@@ -246,6 +303,7 @@
align-items: center;
justify-content: flex-start;
margin-top: 20px;

li {
margin: 10px;
color: #000;
@@ -256,35 +314,55 @@
font-weight: bold;
}
}
div {

.vip-tips {
position: relative;
display: flex;
flex-wrap: wrap;
align-items: center;
align-content: space-between;
justify-content: space-between;

justify-content: flex-end;
align-items: flex-end;
margin-top: 40px;
h5 {

.vip-text {
height: 100px;
display: flex;
flex-wrap: wrap;
align-items: flex-end;
justify-content: flex-start;
justify-content: flex-end;
margin-right: 20px;
padding-bottom: 10px;

img {
width: 50px;
object-fit: contain;
}

span {
color: #000;
color: $com_light_green;
font-size: 28px;
margin-left: 10px;
}
}
p {

.price-strike {
font-size: 54px;
color: #179b3b;
font-weight: bold;
position: relative;

}

.price-strike::before {
content: "";
position: absolute;
top: 50%;
transform: translateY(-50%) rotate(-10deg); //角度可调整以适应需求
width: 110%;
height: 4px;
background-color: black;
left: 0;
}
}
}
}
}
}
}

+ 164
- 82
src/views/optimize/scss/trainingcamp.scss Vedi File

@@ -1,9 +1,13 @@
.trainingcamp {
padding-bottom:100.06px;
background-color: #fff;
min-height: 100vh;
height: 100vh;
overflow: hidden;

.main {
height: calc(100vh - 100px);
padding: 40px 32px;
overflow: hidden;

>ul {
display: flex;
flex-wrap: wrap;
@@ -11,6 +15,7 @@
align-content: space-between;
justify-content: space-between;
margin-bottom: 40px;

li {
background-color: #f1f1f1;
color: #434144;
@@ -21,84 +26,142 @@
text-align: center;
font-weight: bold;
transition: .4s all;

&.active {
background-color: #179b3b;
}
}
}

.brief-box {
img{


.con {
height: calc(100vh - 350px);
overflow: scroll;

.banner {
img {
height: 100%;
width: 100%;
object-fit: contain;
}
}

.article {}
}

.bottom {
height: 80px;
width: 100%;
object-fit: contain;
display: flex;
justify-content: flex-end;
align-items: flex-end;
padding: 20px 0;
padding-bottom: 40px;

.customer {
height: 100%;
padding: 0 20px;
@include center();
font-size: 28px;
color: #000;
}

.price {
display: flex;
justify-content: flex-start;
align-items: flex-start;
padding: 20px 60px;
border-radius: 70px;
background-color: #000;
font-size: 30px;

.left {
font-size: 32px;
color: #179b3b;
font-weight: bold;
position: relative;
}

.left::before {
content: "";
position: absolute;
top: 50%;
transform: translateY(-50%) rotate(-8deg); //角度可调整以适应需求
width: 110%;
height: 3px;
background-color: #fff;
left: 0;
}

.right {
padding: 0 15px;

span {
color: #fff;
}
}
}
}

}

.content-box {
background-color: #f1f1f1;
padding: 30px;
border-radius: 20px;
ul {
li {
padding: 24px 0;
border-bottom: 1px solid #8a8a8a;
&:first-child {
padding-top: 0;
}
/* background-color: #f1f1f1; */

/* border-radius: 20px; */
height: calc(100vh - 250px);
overflow: scroll;

.list {
height: 100%;
overflow: scroll;

.list-item {
border-radius: 50px;
border: 3px solid #179b3b;
padding: 20px;
margin: 30px 0;
display: flex;
justify-content: flex-start;
align-items: center;

p {
color: #333;
font-size: 30px;
}
div {
display: flex;
flex-wrap: wrap;
align-items: center;
align-content: space-between;
justify-content: space-between;
margin-top: 4px;
span {
color: grey;
font-size: 26px;
margin-top: 10px;
i {
display: inline-block;
font-style: normal;
border-radius: 15px;
padding: 5px 15px;
color: #cbae46;
background-color: #fcf4ce;
margin-right: 10px;
font-size: 20px;
}
}
img {
width: 35px;
height: 35px;
object-fit: contain;
}
color: #179b3b;
}
}
}
}

.recommend-box {
overflow: scroll;

ul {
li {
border-radius: 40px;
background-color: #179b3b;
padding: 60px 40px;
position: relative;
& + li {

&+li {
margin-top: 30px;
}

h4 {
color: #000;
width: 40%;
font-size: 40px;
font-weight: bold;
}

p {
font-size: 40px;
color: #000;
margin-top: 20px;
}

span {
display: inline-block;
color: #fff;
@@ -109,6 +172,7 @@
border-radius: 40px;
margin-top: 20px;
}

img {
position: absolute;
bottom: 0;
@@ -121,48 +185,66 @@
}
}
}

.evaluate-box {
li {
.top {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: flex-start;
img {
width: 80px;
height: 80px;
object-fit: contain;
}
div {
margin-left: 20px;
p {
font-size: 28px;
color: #000;
font-weight: bold;
height: calc(100vh - 250px);
overflow: scroll;

.list {
height: 100%;
overflow: scroll;

.list-item {


.top {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: flex-start;

img {
width: 80px;
height: 80px;
object-fit: contain;
}
span {
display: block;
font-size: 28px;
color: grey;
margin-top: 10px;

div {
margin-left: 20px;

p {
font-size: 28px;
color: #000;
font-weight: bold;
}

span {
display: block;
font-size: 28px;
color: grey;
margin-top: 10px;
}
}
}
}
> p{
font-size: 30px;
color: #000;
margin: 20px 0;
}
> span {
display: block;
font-size: 30px;
color: grey;
margin: 20px 0;
padding-bottom: 20px;
border-bottom: 1px solid grey;
}
& + li {
margin-top: 40px;

>p {
font-size: 30px;
color: #000;
margin: 20px 0;
}

>span {
display: block;
font-size: 30px;
color: grey;
margin: 20px 0;
padding-bottom: 20px;
border-bottom: 1px solid grey;
}

&+li {
margin-top: 40px;
}
}
}
}


+ 143
- 61
src/views/optimize/trainingcamp.vue Vedi File

@@ -2,7 +2,7 @@
<template>
<div class="trainingcamp">
<!-- 训练营 -->
<van-nav-bar title="情绪管理控制" :border="true" :left-arrow="true" @click-left="onNavBack" left-text="返回">
<van-nav-bar title="52场专家课" :border="true" :left-arrow="true" @click-left="onNavBack" left-text="返回">
<template #left>
<van-icon name="arrow-left" size="24" style="padding: 0" />
<span>返回</span>
@@ -13,44 +13,66 @@
<li :class="active == 'brief' ? 'active' : ''" @click="switchNav('brief')">简介</li>
<li :class="active == 'content' ? 'active' : ''" @click="switchNav('content')">内容</li>
<li :class="active == 'evaluate' ? 'active' : ''" @click="switchNav('evaluate')">评价</li>
<li :class="active == 'recommend' ? 'active' : ''" @click="switchNav('recommend')">推荐</li>
<!-- <li :class="active == 'recommend' ? 'active' : ''" @click="switchNav('recommend')">推荐</li> -->
</ul>
<!-- 简介 -->
<div class="brief-box" v-show="active == 'brief'">
<img :src="info.introduce" alt="" />
<!-- <img :src="info.introduce" alt="" /> -->
<div class="con">
<!-- banner -->
<div class="banner">
<img :src="camp.introductionImg" alt="">
</div>
<div class="article"></div>
</div>
<div class="bottom">
<div class="customer">
<p>客服</p>
</div>
<div class="price">
<div class="left">
<span>¥{{ camp.vipPrice }}</span>
</div>
<div class="right">
<span>会员免费</span>
</div>
</div>
</div>


</div>
<!-- 内容 -->
<div class="content-box" v-show="active == 'content'">
<ul>
<li v-for="(item, index) in info.videoList" :key="index">
<!-- <p>{{index + 1 <= 9 ? '0' + (index + 1) : index + 1}} {{item.title}}</p> -->
<p>{{item.title}}</p>
<div>
<span><i v-if="item.isFree == 0">免费</i>{{item.duration}} | {{item.playBack}}次播放</span>

<div class="list">
<div class="list-item" v-for="(item, index) in info.videoList" :key="index" @click="onRoterTo(item)">
<p>{{ item.title }}</p>
<!-- <span><i v-if="item.isFree == 0">免费</i>{{ item.duration }} | {{ item.playBack }}次播放</span>
<img v-if="item.isFree == 0" src="@/assets/optimize/icons/play.png" alt="" />
<img v-else src="@/assets/optimize/icons/lock.png" alt="" />
</div>
</li>
</ul>
<img v-else src="@/assets/optimize/icons/lock.png" alt="" /> -->
</div>
</div>
</div>
<div class="evaluate-box" v-show="active == 'evaluate'">
<ul>
<li v-for="(item, index) in info.evaluate" :key="index">
<div class="list">
<div class="list-item" v-for="(item, index) in info.evaluate" :key="index">
<div class="top">
<img src="@/assets/optimize/icons/3_55.png" alt="" />
<div>
<p>{{item.name}}</p>
<span>{{item.date}} {{item.address}}</span>
<p>{{ item.nickName }}</p>
<span>{{ item.createdAt }} {{ item.address }}</span>
</div>
</div>
<p>{{item.content}}</p>
<span>{{item.videoName}}</span>
</li>
</ul>
<p>{{ item.content }}</p>
<span>{{ item.videoName }}</span>
</div>
</div>
</div>
<div class="recommend-box" v-show="active == 'recommend'">
<ul>
<li v-for="(item, index) in campList" :key="index">
<h4>{{item.name}}</h4>
<p>{{item.summary}}</p>
<h4>{{ item.name }}</h4>
<p>{{ item.summary }}</p>
<span>播放</span>
<img src="@/assets/optimize/images/3_48.png" alt="" />
</li>
@@ -73,14 +95,97 @@ export default {
return {
active: 'brief',
campList: [],
info: {}
info: {
videoList: [
/* {
"lessonId": 1,
"title": "《心理健康—依靠爱的支撑》",
"isFree": false,
"createdAt": "2024-01-26 18:14:19",
"readCount": null
},
{
"lessonId": 2,
"title": "《心理健康—亲和力》",
"isFree": false,
"createdAt": "2024-02-21 15:16:58",
"readCount": null
},
{
"lessonId": 3,
"title": "《心理健康—推动内驱力、树立人格美》",
"isFree": false,
"createdAt": "2024-02-21 15:16:58",
"readCount": null
} */
],
evaluate: [
{
"commentId": 1,
"avatar": "https://ai.ssjlai.com/fastdfs/group1/M00/00/89/rBMqKGWiUrmAJUReAAMG6aq1a-4091.png",
"nickName": '张杰妈妈',
"content": "买了好多课,这个是最值得的!!",
"createdAt": "2024-01-29 16:34:27",
"address": "佛山",
"title": "心理健康—依靠爱的支撑》"
},
{
"commentId": 1,
"avatar": "https://ai.ssjlai.com/fastdfs/group1/M00/00/89/rBMqKGWiUrmAJUReAAMG6aq1a-4091.png",
"nickName": '张杰妈妈',
"content": "买了好多课,这个是最值得的!!",
"createdAt": "2024-01-29 16:34:27",
"address": "佛山",
"title": "心理健康—依靠爱的支撑》"
},
]
},
bannerImg: '',
camp: {}
};
},
watch: {
active(val) {
if (val == 'content') {
this.getTrainingCampDetail();
} else if (val == 'evaluate') {
this.getTrainingCampDetailComment()
}
}
},
created() {
this.init(this.$route.query.id);


},
mounted() {
this.$nextTick(() => {
this.getCampList();
})

},
mounted() {},
methods: {
getCampList() {

APIOptimize.getCampList().then(res => {
let data = res.data.data;
const campObj = data.filter(f => {
return this.$store.getters.campId == f.id
})[0];
this.camp = { ...campObj }
})
},
getTrainingCampDetail() {
let reqParams = {
courseId: Number(this.$store.getters.campId)
};
APIOptimize.getTrainingCampDetail(reqParams).then(res => {
let data = res.data.data;
this.info.videoList = data.lessonList
})
},
getTrainingCampDetailComment() {

},
// 返回
onNavBack() {
this.$router.push({
@@ -91,44 +196,21 @@ export default {
switchNav(e) {
this.active = e;
},
// 初始化
init(id) {
// 训练营详情
APIOptimize.getCampList(id)
.then(res => {
if ( res.data.data.length != 0 ) {
this.info = res.data.data[0]
if ( this.info.evaluate.length != 0 ) {
this.info.evaluate.forEach(element => {
if ( this.info.videoList.length != 0 ) {
this.info.videoList.forEach(e => {
if ( element['videoId'] == e['id'] ) {
element['videoName'] = e['title'];
}
})
} else {
element['videoName'] = "暂无消息";
}
})
}
}
})
.catch(e => {
console.log(e);
})
// 训练营推荐列表
APIOptimize.getCampRecommendList()
.then(res => {
this.campList = res.data.data
})
.catch(e => {
console.log(e);
})
onRoterTo(item) {
console.log(item);
this.$router.push({
name: 'expertChat',
query: {
title: item.title.replace("《", '').replace("》", ''),
lessonId: item.lessonId
}
})
}
}
},

};
</script>

<style scoped lang="scss">
@import './scss/trainingcamp.scss';
@import './scss/trainingcamp.scss';
</style>

Loading…
Annulla
Salva