Files
soulspace/pages/curriculum/list/index.vue
liuyuan e04e7953a1 111
2025-08-19 10:24:28 +08:00

688 lines
16 KiB
Vue

<template>
<view class="commonPageBox">
<z-nav-bar :title="title">
<view class="curseSet" slot="right" v-if="statusXLCP&&XL_id==77">
<uni-icons type="location" size="18"></uni-icons>
<picker class="picker" mode="multiSelector" :range="multiArray" @change="bindMultiPickerChange" @columnchange="bindMultiPickerColumnChange">
<text @click="changeCountry">{{countryText}}</text>
</picker>
</view>
</z-nav-bar>
<view class="cateList">
<view class="labels_block" v-if="labelsList.length>0" :style="`top: ${45 + statusBarHeight}px;`">
<view class="labels_item"
:style="{ width: labelsList.length > 0 ? `${100 / labelsList.length}%` : '100%' }"
v-for="(tabData,tabIndex) in labelsList" :key="tabIndex"
:class="activeTab==tabIndex?'active_tab':''" @click.stop="clickTab(tabData,tabIndex)">
{{tabData.title}}<text class="line-item"></text>
</view>
</view>
<view class="children_block" v-if="childrenList.length>0">
<view class="children_item"
:style="{ width: childrenList.length > 0 ? `${100 / childrenList.length}%` : '100%' }"
v-for="(childrenData,childrenIndex) in childrenList" :key="childrenIndex"
:class="childrenTab==childrenIndex?'active_children':''" @click.stop="clickChildren(childrenData,childrenIndex)">
{{childrenData.title}}
</view>
</view>
<view class="list_block" v-if="!statusXLCP" :style="labelsList.length>0&&childrenList.length==0?`marginTop: ${45 + statusBarHeight}px;`:''">
<view class="list_item" v-if="list.length>0" v-for="(item,index) in list" :key="index" @click.stop="goToDetail(item)">
<view class="list_item_image">
<image v-if="item.squareImage" :src="item.squareImage"></image>
<text class="image_null" v-else>暂无封面图</text>
</view>
<view class="list_item_right">
<view class="list_item_title">{{item.title}}</view>
<view class="list_item_content" v-html="item.content"></view>
<view class="list_item_bt">
<view class="list_item_price" v-if="item.courseCatalogueEntityList.length==1">
<text v-if="item.courseCatalogueEntityList[0].halfFee==0">免费</text>
<text v-else>¥{{item.courseCatalogueEntityList[0].halfFee}}/{{item.courseCatalogueEntityList[0].fee}}</text>
</view>
<view class="list_item_price" v-if="item.courseCatalogueEntityList.length>1">
<text v-for="(v,i) in item.courseCatalogueEntityList" :key="i">
{{formatContent(v.title)}}<text v-if="i !== item.courseCatalogueEntityList.length - 1">/</text>
</text>
<text v-if="item.courseCatalogueEntityList[0].halfFee==0" style="padding-left: 20rpx;">免费</text>
<text v-else style="margin-left: 20rpx;">{{item.courseCatalogueEntityList[0].halfFee}}/{{item.courseCatalogueEntityList[0].fee}}</text>
</view>
<text class="list_item_study">了解课程</text>
</view>
</view>
</view>
<text v-if="statusNull" class="text_null">暂无数据</text>
</view>
<view class="xlcp_block" :class="XL_id==78?'xlcp_block_2':''" v-if="statusXLCP">
<view class="form_block" v-if="XL_id==77">
<view class="form_item" v-for="(item,index) in formList" :key="index">
<text class="form_title">{{item.title}}</text>
<view class="form_solid">
<view class="form_des">{{item.des}}</view>
<picker mode="multiSelector" :range="multiArray" @change="bindMultiPickerChange" @columnchange="bindMultiPickerColumnChange" v-show="countryText=='城市'">
<u-button class="form_btn">进入测试</u-button>
</picker>
<u-button v-show="countryText!='城市'" class="form_btn" @click="test(item)">进入测试</u-button>
</view>
</view>
</view>
<view class="level_block" v-if="XL_id==78">
<view class="level_item" @click="clickLevel">自恋型人格障碍诊断标准</view>
</view>
</view>
</view>
</view>
</template>
<script>
import $http from "@/config/requestConfig.js";
export default {
data() {
return {
title: '',
id: null,
ordersTabs: [],
page: {
current: 1,
limit: 10
},
labelsList: [], //二级数据
childrenList: [], //子级目录
childrenId: null,
list: [], //列表数据
statusNull: null,
statusXLCP: null,
activeTab: 0, //默认选中tab
childrenTab: 0,
XL_id: null, //心理测评tab的id绑定
//心身量表
formList: [],
//选择城市弹窗
cityList: [],
isPicker: false,
countries: [],
multiArray: [[], []],
value: [0, 0],
selectedData: {}, //城市
countryIndex: 0, //抑郁症文字区分国家展示
countryText: '',
}
},
onShow(){
},
onLoad(options) {
//清除缓存
uni.removeStorageSync('fixed');
this.title = options.title;
this.id = options.id;
//如果是心理评测
if(this.id==75){
this.statusXLCP = true;
this.getFormList();
}
//显示城市数据
this.getCityList();
let countryData = uni.getStorageSync('countryData');
let text= '';
if(countryData&&countryData.country){
text = countryData.country
if(countryData.city){
text = text + countryData.city
}
}else{
text= '城市';
}
this.countryText = text;
// let fixed = uni.getStorageSync('fixed');
// //如果是诊断标准子页面返回的
// if(fixed){
// this.activeTab = 1;
// }else{
this.activeTab = 0;
this.getPsycheTree();
// }
this.childrenTab = 0;
},
methods: {
//判断显示‘上/中/下’
formatContent(content) {
const keywords = ["上部", "中部", "下部"];
let result = [];
// 判断是否包含关键字
keywords.forEach((keyword) => {
if (content.includes(keyword)) {
result.push(keyword.substring(0, 1));
}
});
return result.join("");
},
//获取数据
getData(id){
uni.showLoading({
title: '加载中'
})
this.$http.request({
url: 'psyche/home/getPsycheCourseList',
method: "POST",
data: {
id: id,
limit: this.page.limit,
page: this.page.current,
},
header: {
"Content-Type": "application/json",
},
})
.then(res => {
uni.hideLoading();
if(res.courses.records&&res.courses.records.length>0){
this.list = res.courses.records;
}else{
this.list = [];
this.statusNull = true;
}
});
},
//二级列表数据
getPsycheTree() {
this.$http.request({
url: 'psyche/home/getChildCoursePsycheTree',
method: "POST",
data: {
id: this.id
},
header: {
"Content-Type": "application/json",
},
})
.then(res => {
if(res.labels&&res.labels.length>0){
this.labelsList = res.labels;
//如果是心理测评
if(this.id == 75){
this.XL_id = this.labelsList[0].id;
}
//判断是否有子级
if(this.labelsList[0].isLast == 1) {
this.childrenList = [];
this.childrenId = this.labelsList[0].id;
}else{
if(this.labelsList[0].children.length > 0){
this.childrenList = this.labelsList[0].children;
this.childrenId = this.childrenList[0].id;
}else{
this.childrenList = [];
this.childrenId = null;
}
}
//请求课程列表数据
if(this.childrenId){
this.getData(this.childrenId);
}else{
this.getData(this.id);
}
}else{
this.labelsList = [];
this.getData(this.id);
}
});
},
//切换tab
clickTab(item, index){
this.statusNull = null;
this.activeTab = index;
//如果是心理测评
if(this.id == 75){
this.XL_id = item.id;
}
if(item.isLast == 1) {
this.childrenList = [];
this.childrenId = item.id;
}else{
if(item.children.length > 0){
this.childrenList = item.children;
this.childrenId = item.children[0].id;
//点击tab默认显示第一个children
this.childrenTab = 0;
}else{
this.childrenList = [];
this.childrenId = null;
}
}
//请求课程列表数据
if(this.childrenId){
this.getData(this.childrenId);
}else{
this.getData(this.id);
}
},
//点击children
clickChildren(item, index){
this.statusNull = null;
this.childrenTab = index;
this.childrenId = item.id;
//请求课程列表数据
if(this.childrenId){
this.getData(this.childrenId);
}else{
this.getData(this.id);
}
},
//心身量表
getFormList() {
$http.request({
url: "common/selfEvaluationForm/formList",
method: "POST",
data: {},
header: {
'Content-Type': 'application/json'
},
})
.then(res => {
if (res.code == 0) {
this.formList = res.formList;
}
}).catch(e => {
});
},
//获取国家-一级
getCountryList() {
$http.request({
url: "common/baseArea/getAllBaseArea",
method: "POST",
data: {},
header: {
'Content-Type': 'application/json'
},
})
.then(res => {
if (res.code == 0) {
this.countries = res.baseAreas;
this.countries.forEach((country, index)=>{
if(country.code=='86'){
this.countries[index].cities = this.cityList;
}
})
//初始化 picker 数据
this.initPickerData();
}
}).catch(e => {
});
},
//获取城市-二级
getCityList() {
$http.request({
url: "common/province/getProvinceList",
method: "POST",
data: {},
header: {
'Content-Type': 'application/json'
},
})
.then(res => {
if (res.code == 0) {
const newCityList = res.provinceList.map( city => {
return city.provName;
});
this.cityList = newCityList;
this.getCountryList();
}
}).catch(e => {
});
},
//展示城市数据
initPickerData() {
//第一列是国家名
const countryNames = this.countries.map(item => item.title);
this.multiArray[0] = countryNames;
//默认选择中国,并加载其省份
if (this.countries[0].cities) { //如果默认显示的是第一个-中国,则显示城市列
this.multiArray[1] = Object.keys(this.countries[0].cities).map(key => this.countries[0].cities[key]);
} else {
this.multiArray[1] = [];
}
//强制更新视图
this.$set(this, 'multiArray', [...this.multiArray]);
},
//picker修改值
bindMultiPickerChange(e) {
this.value = e.detail.value;
this.updateCurrentSelection();
},
//修改动作
bindMultiPickerColumnChange(e) {
let data = {
multiArray: this.multiArray,
value: this.value
};
if (e.detail.column === 0) {
// 如果是第一列(国家)改变了,则需要更新第二列(城市)
const selectedCountry = this.countries[e.detail.value];
if (selectedCountry.cities) {
// 如果选择了中国,加载省份
data.multiArray[1] = Object.keys(selectedCountry.cities).map(key => selectedCountry.cities[key]);
data.value = [e.detail.value, 0];
} else {
// 否则清空第二列
data.multiArray[1] = [];
data.value = [e.detail.value, 0];
}
}
this.$set(this, 'multiArray', [...data.multiArray]);
this.value = data.value;
},
updateCurrentSelection() {
const countryIndex = this.value[0];
this.countryIndex = countryIndex; //判断抑郁结果 标准的定义文字显示
const cityIndex = this.value[1];
const selectedCountry = this.multiArray[0][countryIndex];
const selectedCity = this.multiArray[1][cityIndex];
this.selectedData = {
country: selectedCountry
}
this.countryText = selectedCountry;
if(selectedCity){
this.selectedData.city = selectedCity;
this.countryText = selectedCountry + selectedCity;
}else{
this.selectedData.city = ''
}
uni.setStorageSync('countryData', this.selectedData)
},
//点击地理位置修改城市
changeCountry(){
this.initPickerData();
},
//进入测试
test(item){
uni.setStorageSync('data',JSON.stringify(item))
uni.navigateTo({
url: '/pages/curriculum/list/scale'
})
},
//跳转课程详情
goToDetail(item) {
uni.navigateTo({
url: `/pages/curriculum/order/index?navTitle=${item.title}&title=${item.title}&id=${item.id}`,
});
},
//诊断标准
clickLevel(){
uni.navigateTo({
url: '/pages/curriculum/list/level'
})
}
}
};
</script>
<style lang="scss" scoped>
.commonPageBox{
background: #eff5f8;
height: 100vh;
}
.list_block{
padding: 20rpx 20rpx 0;
}
.list_item{
position: relative;
background: #fff;
box-shadow: 0px 0px 10px 0px #a7bbe4;
padding: 30rpx 20rpx 70rpx;
margin-bottom: 20rpx;
display: flex;
border-radius: 10rpx;
}
.list_item_image,.image_null{
width: 250rpx;
height: 250rpx;
background-color: rgba(125, 193, 240, 0.1);
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
.list_item_image image{
width: 100%;
height: 250rpx;
}
.list_item_right{
margin-left: 30rpx;
width: calc(100% - 250rpx);
}
.list_item_title{
font-size: 30rpx;
line-height: 36rpx;
font-weight: bold;
color: #333;
}
.list_item_content{
margin-top: 15rpx;
font-size: 26rpx;
line-height: 36rpx;
color: #999;
max-height: 108rpx;
overflow: hidden;
}
.list_item_study{
line-height: 48rpx;
background: #7dc1f0;
color: #fff;
border-radius: 40rpx;
font-size: 24rpx;
padding: 0 20rpx;
}
.list_item_bt{
display: flex;
align-items: center;
position: absolute;
right: 20rpx;
bottom: 30rpx;
}
.list_item_price{
font-size: 30rpx;
font-weight: 500;
margin-right: 30rpx;
color: red;
line-height: 54rpx;
}
.text_null{
display: block;
width: 100%;
text-align: center;
font-size: 26rpx;
color: #999;
margin: 150rpx 0;
}
.image_null{
color: #999;
font-size: 22rpx;
}
.labels_block{
width: 100%;
display: flex;
align-items: center;
background: #fff;
position: fixed;
left: 0;
z-index: 99;
height: 40px;
}
.labels_item{
line-height: 76rpx;
text-align: center;
font-size: 32rpx;
color: #333;
}
.active_tab{
font-size: 36rpx;
font-weight: bold;
}
.line-item{
display: none;
margin: 0 auto;
width: 55rpx;
height: 6rpx;
background: #7dc1f0;
overflow: hidden;
}
.active_tab .line-item{
display: block;
}
.children_block{
display: flex;
align-items: center;
margin: 50px 10rpx 0;
position: relative;
z-index: 99;
}
.children_item{
margin: 0 10rpx;
line-height: 80rpx;
text-align: center;
font-size: 28rpx;
color: #333;
background: #fff;
border: 1rpx solid #999;
border-radius: 10rpx;
}
.active_children{
color: #fff;
background: #7dc1f0;
border: 1rpx solid #7dc1f0;
}
.xlcp_block{
padding: 0 20rpx;
margin-top: 90rpx;
}
.xlcp_block_2{
margin-top: 110rpx;
}
.form_item{
margin-bottom: 50rpx;
}
.form_solid{
border-radius: 10rpx;
background-color: #fff;
padding: 20rpx 20rpx 50rpx;
box-shadow: 0px 0px 10px 0px #a7bbe4;
}
.form_title{
display: inline-block;
width: 100%;
font-size: 42rpx;
color: #333;
text-align: center;
padding: 30rpx 0 20rpx;
}
.form_des{
font-size: 30rpx;
line-height: 48rpx;
color: #666;
}
.form_btn{
width: 300rpx;
height: 70rpx;
margin: 40rpx auto 0;
color: #fff;
font-size: 28rpx;
background: #7dc1f0;
border-radius: 10rpx;
}
.popup_mark{
width: 100%;
height: 100%;
background: #000;
opacity: 0.5;
position: fixed;
top: 0;
left: 0;
z-index: 99;
}
.popup_block{
width: 580rpx;
height: 360rpx;
position: fixed;
top: 50%;
left: 50%;
margin-top: -180rpx;
margin-left: -290rpx;
background: #fff;
z-index: 99;
border-radius: 5px;
}
.popup_title{
display: block;
height: 90rpx;
line-height: 90rpx;
font-size: 32rpx;
color: #333;
text-align: center;
border-bottom: 1rpx solid #f0f0f0;
}
.popup_con{
font-size: 28rpx;
padding-top: 50rpx;
text-align: center;
}
.popup_picker{
position: absolute;
bottom: 0;
width: 100%;
}
.scale_btn{
width: 100%;
height: 80rpx;
line-height: 80rpx;
color: #fff;
font-size: 28rpx;
background: #294a97;
border: none;
border-radius: 0 0 5px 5px;
}
.curseSet{
margin-right: 18rpx;
font-size: 28rpx;
display: flex;
align-items: center;
}
.level_block{
border-radius: 10rpx;
background-color: #fff;
padding: 20rpx;
box-shadow: 0px 0px 10px 0px #a7bbe4;
}
.level_item{
display: inline-block;
color: #333;
width: 100%;
font-size: 32rpx;
padding: 20rpx 0;
border-bottom: 1rpx solid #f0f0f0;
}
.level_item:last-child{
border-bottom: 0;
}
</style>