Initial commit

This commit is contained in:
jackyu66git
2026-03-23 11:52:05 +08:00
commit c3c9db3151
267 changed files with 24984 additions and 0 deletions
+937
View File
@@ -0,0 +1,937 @@
<template>
<view class="content" :style="{height:bgHeight}">
<myNav title="立即预约" bgColor="#fff" titleColor="#614D49" :backIcon="true" :backHome="false" :flex="true"></myNav>
<view style=" display: flex; flex-direction: column; align-items: center;overflow-y: auto;"
v-if="psychicShowDetail">
<view class="card" style="margin-top: 40rpx;">
<view class="psychic-top"></view>
<view class="psychic-card">
<view style="display: flex;justify-content: space-between;width: 100%;">
<view style="display: flex;align-items:last baseline;">
<image v-if="psychicShowDetail.avatar" :src="psychicShowDetail.avatar"
style="width: 120rpx;height: 120rpx;border-radius: 10rpx;">
</image>
<text class="psychic-name">{{psychicShowDetail.name}}</text>
</view>
<view>
<text class="psychic-price">¥{{advancedFormat(psychicShowDetail.price)}}</text>
<text class="psychic-unit"
v-if="appointmentTime">/{{calculateTimeDifference(appointmentTime.startTime,appointmentTime.endTime)}}分钟</text>
</view>
</view>
<view class="line"></view>
<view class="psychic-detail-row">
<text class="psychic-detail-text">咨询时段</text>
<view @click="showChoiceDateTimePop">
<text class="psychic-detail-show-text"
v-if="appointmentDate&&appointmentTime">{{appointmentDate.scheduleDate}}({{appointmentDate.weekStr}}){{appointmentTime.startTime.substring(0,5)}}-{{appointmentTime.endTime.substring(0,5)}}</text>
<image src="/static/n-zx/right-icon.png" class="right-icon" >
</image>
</view>
</view>
<view class="psychic-detail-row">
<text class="psychic-detail-text">咨询方式</text>
<view style="display: flex; align-items: center;">
<view v-if="psychicOrder.consultationMethod == 'video' && showVideo" style="width: 124rpx;height: 48rpx;border-radius: 80rpx;
box-sizing: border-box;border: 1px solid #F97559;display: flex;justify-content: center;align-items: center;"
@click="choiceConsultationMethod('video')">
<image src="/static/n-zx/video.png" style="width: 25.6rpx;height: 19.2rpx;"></image>
<text style="font-size: 24rpx;color: #F97559;margin-left: 8rpx;">视频</text>
</view>
<view v-if="psychicOrder.consultationMethod == 'video'&& showFaceToFace" style="width: 124rpx;height: 48rpx;border-radius: 80rpx;margin-left: 20rpx;
box-sizing: border-box;border: 1px solid #909099;display: flex;justify-content: center;align-items: center;"
@click="choiceConsultationMethod('face_to_face')">
<image src="/static/n-zx/face-to-face.png" style="width: 26rpx;height: 28.66rpx;">
</image>
<text style="font-size: 24rpx;color: #909099;margin-left: 8rpx;">面对面</text>
</view>
<view v-if="psychicOrder.consultationMethod == 'face_to_face'&& showVideo" style="width: 124rpx;height: 48rpx;border-radius: 80rpx;
box-sizing: border-box;border: 1px solid #909099;display: flex;justify-content: center;align-items: center;"
@click="choiceConsultationMethod('video')">
<image src="/static/n-zx/video-camera.png" style="width: 26rpx;height: 28.66rpx;">
</image>
<text style="font-size: 24rpx;color: #909099;margin-left: 8rpx;">视频</text>
</view>
<view v-if="psychicOrder.consultationMethod == 'face_to_face'&& showFaceToFace" style="width: 124rpx;height: 48rpx;border-radius: 80rpx;margin-left: 20rpx;
box-sizing: border-box;border: 1px solid #F97559;display: flex;justify-content: center;align-items: center;"
@click="choiceConsultationMethod('face_to_face')">
<image src="/static/n-zx/face-to-face-c.png" style="width: 26rpx;height: 28.66rpx;">
</image>
<text style="font-size: 24rpx;color: #F97559;margin-left: 8rpx;">面对面</text>
</view>
</view>
</view>
<view class="psychic-detail-row" v-if="psychicOrder.consultationMethod == 'face_to_face'">
<text class="psychic-detail-text">面询地址</text>
<view style="width: 70%;text-align: right;">
<text class="psychic-detail-show-text">{{psychicShowDetail.address}}(下单后展示详细)</text>
</view>
</view>
</view>
</view>
<view class="card" style="margin-top: 20rpx;box-sizing: border-box;" v-if="!showDetailFlag">
<view style="padding-left: 40rpx;padding-right: 40rpx;width: 100%;box-sizing: border-box;">
<view class="psychic-detail-row">
<text class="psychic-detail-text">预约人信息</text>
<view>
<text class="psychic-detail-show-text"
v-if="psychicShowDetail.appointmentInfoAppRespVO&&psychicShowDetail.appointmentInfoAppRespVO.phone">{{psychicShowDetail.appointmentInfoAppRespVO.phone}}</text>
<text class="psychic-detail-show-text" @click="changeDetailFlag" v-else>去填写</text>
<image v-if="!psychicShowDetail.appointmentInfoAppRespVO||!psychicShowDetail.appointmentInfoAppRespVO.phone" src="/static/n-zx/right-icon.png" class="right-icon" style="margin-left: 10rpx;"
@click="changeDetailFlag" >
</image>
</view>
</view>
</view>
<view class="expand-bottom">
<view @click="changeDetailFlag"
style="display: flex;justify-content: center;flex-direction: column;align-items: center;justify-content: center;">
<text class="expand-text">展开更多</text>
<image src="/static/n-zx/down-icon.png" style="width: 16rpx;height: 11.82rpx;"></image>
</view>
</view>
</view>
<view class="card" style="margin-top: 20rpx;box-sizing: border-box;" v-if="showDetailFlag">
<view
style="padding-left: 40rpx;padding-right: 40rpx;width: 100%;box-sizing: border-box;padding-bottom: 40rpx;">
<view class="psychic-detail-row">
<text class="psychic-detail-text">预约人信息</text>
<view>
<text class="psychic-detail-show-text" style="color: #909099;">必填信息将严格保密请放心如实填写</text>
</view>
</view>
<view class="psychic-detail-row">
<text class="psychic-detail-title-text">预约人称呼</text>
<view style="text-align: right;">
<input type="text" class="input-text" v-model="psychicOrder.appointmentName" :maxlength="10"
placeholder="请输入预约人称呼" />
</view>
</view>
<view class="psychic-detail-row">
<text class="psychic-detail-title-text">出生年月</text>
<view style="display: flex;justify-content: flex-end; align-items: center;">
<picker mode="date" value="date" fields="month" @change="bindDateChange">
<view class="input-text">{{psychicOrder.birthday}}</view>
</picker>
<image src="/static/n-zx/right-icon.png" class="right-icon" style="margin-left: 20rpx;">
</image>
</view>
</view>
<view class="psychic-detail-row">
<text class="psychic-detail-title-text">联系方式</text>
<view style="text-align: right;">
<input class="input-text" type="number" :maxlength="11" v-model="psychicOrder.phone"
placeholder="请输入预约人联系电话" />
</view>
</view>
<view class="psychic-detail-row">
<text class="psychic-detail-title-text">性别</text>
<view style="display: flex;align-items: center;" v-if="psychicOrder.sex == 1">
<view style="margin-right: 44.44rpx;display: flex;align-items: center;">
<image src="/static/n-zx/choice.png" style="width: 40rpx;height: 40rpx;"></image>
<text class="input-text" style="margin-left:10rpx ;"></text>
</view>
<view style="display: flex;align-items: center;" @click="choiceSex(2)">
<image src="/static/n-zx/nochoice.png" style="width: 31rpx;height: 31rpx;"></image>
<text class="input-text" style="margin-left:10rpx ;"></text>
</view>
</view>
<view style="display: flex;align-items: center;" v-if="psychicOrder.sex == 2">
<view style="margin-right: 44.44rpx;display: flex;align-items: center;"
@click="choiceSex(1)">
<image src="/static/n-zx/nochoice.png" style="width: 31rpx;height: 31rpx;"></image>
<text class="input-text" style="margin-left:10rpx ;"></text>
</view>
<view style="display: flex;align-items: center;">
<image src="/static/n-zx/choice.png" style="width: 40rpx;height: 40rpx;"></image>
<text class="input-text" style="margin-left:10rpx ;"></text>
</view>
</view>
</view>
</view>
</view>
<view class="card" style="margin-top: 20rpx;box-sizing: border-box;" v-if="showDetailFlag">
<view
style="padding-left: 40rpx;padding-right: 40rpx;width: 100%;box-sizing: border-box;padding-bottom: 40rpx;">
<view class="psychic-detail-row" style="justify-content: flex-start;">
<text class="psychic-detail-text">紧急联系人</text>
<view style="margin-left: 20rpx;">
<text class="psychic-detail-show-text" style="color: #909099;">必填</text>
</view>
</view>
<view class="psychic-detail-row" style="justify-content: flex-start;margin-top: 20rpx;">
<view>
<text class="psychic-detail-show-text"
style="color: #909099;">我们承诺对您的信息严格保密仅在紧急情况时联系您全力保障您的生命安全与生活福祉</text>
</view>
</view>
<view class="psychic-detail-row">
<text class="psychic-detail-title-text">联系方式</text>
<view style="text-align: right;">
<input class="input-text" v-model="psychicOrder.emergencyContactPhone" type="number"
:maxlength="11" placeholder="请输入紧急联系人电话" />
</view>
</view>
<view class="psychic-detail-row">
<text class="psychic-detail-title-text">与你的关系</text>
<view style="display: flex;align-items: center;flex: 1;justify-content: flex-end;">
<!-- <input class="input-text" type="number" :maxlength="10" placeholder="请输入预约人联系电话" />
<image src="/static/n-zx/right-icon.png" class="right-icon" style="margin-left: 20rpx;">
</image> -->
<uni-data-select style="width: 80%;outline: none;border: none;text-align: right"
v-model="psychicOrder.emergencyContactType"
:localdata="range"
@change="changeEmergencyContactType"
:clear="false"
placeholder="请选择"
>
</uni-data-select>
</view>
</view>
</view>
</view>
<view class="card" style="margin-top: 20rpx;box-sizing: border-box;">
<view
style="padding-left: 40rpx;padding-right: 40rpx;width: 100%;box-sizing: border-box;padding-bottom: 40rpx;">
<view class="psychic-detail-row" style="justify-content: flex-start;">
<text class="psychic-detail-text">支付方式</text>
</view>
<view class="psychic-detail-row" style="margin-top: 20rpx;align-items: center;">
<view style="display: flex;align-items: center;">
<image src="/static/n-zx/wx-pay-icon.png" style="width:88rpx;height: 88rpx;"></image>
<text class="input-text">微信支付</text>
</view>
<image src="/static/n-zx/choice-pay-icon.png" style="width: 48rpx;height: 48rpx;"></image>
</view>
</view>
</view>
<view style="width: 670rpx;display: flex;align-items: center; margin-top: 22rpx">
<image v-if="!agreeFlag" src="/static/n-zx/nochoice.png" style="width: 26rpx;height:26rpx;" @click="agree"></image>
<image v-else src="/static/n-zx/choice.png" style="width: 40rpx;height: 40rpx;" @click="agree"></image>
<!-- @click="expandPopSlot" -->
<view
style="white-space: nowrap; text-overflow: ellipsis;overflow: hidden;width: 630rpx;margin-left: 10rpx;">
<text class="psychic-detail-title-text1"> 同意</text>
<text class="psychic-detail-title-text1" style="color:#F37155 ;">
<text @click="toShowProtocol('informed_consent')">知情同意书</text><text @click="toShowProtocol('psychological_counseling')">心理咨询服务协议</text></text>
<text class="psychic-detail-title-text1"></text>
<text class="psychic-detail-title-text1" style="color:#F37155 ;" @click="toShowProtocol('exclusive_assistant')">专属助理服务须知</text>
<text class="psychic-detail-title-text1">点击同意"开始接受服务。</text>
</view>
</view>
<view class="bottom-btn" @click="toPay">
<text class="btn-text">立即预约¥{{advancedFormat(psychicShowDetail.price)}}</text>
</view>
</view>
</view>
<uni-popup ref="timeSlot" type="bottom" :animation="true" :safe-area="false">
<view style="width: 750rpx;height: 940rpx;padding: 40rpx 40rpx 64rpx 40rpx;background: #fff;box-sizing: border-box;
flex-direction: column;display: flex;align-items: center;border-radius: 10rpx 10rpx 0px 0px;">
<text style="color: #614D49;font-size: 40rpx;font-family: SourceHanSansBold; ">选择咨询时段</text>
<text style="color: #9B918C;font-size: 24rpx;font-family: SourceHanSans;margin-top: 8rpx; ">(北京时间)</text>
<view style="display: flex; justify-content: space-between;width: 100%;margin-top: 40rpx;">
<text
style="color: #614D49;font-size: 28rpx;font-family: SourceHanSansBold;">共{{choiceSlotNum}}个时段可选择</text>
<text style="color: #9B918C;font-size: 28rpx;font-family: SourceHanSans;">已为你隐藏不可约时段</text>
</view>
<view style="display: flex;width: 100%;flex-direction: column;overflow-y: auto;">
<view style="display: flex;width: 100%;align-items: flex-start"
v-for="(item,index) in appointmentDateDetailList" :key="index">
<view class="date-card" :style="{'color':choiceDateIndex == index?'#F37155':'#9B918C'}">
<text style="font-size: 10rpx;font-family: SourceHanSansBold;">{{item.weekStr}}</text>
<text
style="font-size: 20rpx;font-family: SourceHanSans;">{{item.scheduleDate.slice(-5)}}</text>
</view>
<view style="display: flex;flex-wrap: wrap;width: 550rpx;">
<view class="time-card" :style="{'color':choiceTimeIndex == index1&&choiceDateIndex == index?'#fff':'#9B918C',
'background':choiceTimeIndex == index1&&choiceDateIndex == index?'#F37155':'#fff'
,'border':choiceTimeIndex == index1&&choiceDateIndex == index?'none':'1px solid #909099'}"
v-for="(ele,index1) in item.slotVOList" :key="index1"
@click="choiceDate(ele,index1,item,index)">
<text
style="font-size: 20rpx;font-family: SourceHanSans;width: 50rpx;height: 28rpx;">{{ele.startTime.substring(0,5)}}</text>
<text
style="font-size: 20rpx;font-family: SourceHanSans;;width: 8rpx;height: 28rpx;">-</text>
<text
style="font-size: 20rpx;font-family: SourceHanSans;width: 50rpx;height: 28rpx;">{{ele.endTime.substring(0,5)}}</text>
</view>
</view>
</view>
</view>
<view class="bottom-btn" style="margin-bottom: 64rpx;" @click="sureTime">
<text class="btn-text">确认时段</text>
</view>
</view>
</uni-popup>
<uni-popup ref="popSlot" type="center" :animation="true" :safe-area="false">
<view
style="width: 590rpx;height: 768rpx;border-radius: 10rpx;background-color: #fff;display: flex;flex-direction: column;align-items: center;">
<image src="/static/n-zx/header.png" style="width: 590rpx;height: 536.3rpx;margin-top: -282rpx;"></image>
<view style="width: 464rpx;margin-top: 80rpx;">
<text style="font-size: 28rpx;font-family: SourceHanSansBold">
请阅读<text style="color:#EA4E2D;" @click="toShowProtocol('informed_consent')">《知情同意书》</text>、
<text style="color:#EA4E2D;" @click="toShowProtocol('psychological_counseling')">《心理咨询服务协议》</text>与
<text style="color:#EA4E2D;" @click="toShowProtocol('exclusive_assistant')">《专属助理服务须知》</text>,点击“同意"开始接受服务
</text>
</view>
<view style="width: 430rpx;height: 96rpx;border-radius: 2002rpx;background: linear-gradient(180deg, #E84B2A 0%, #FF846A 100%);
display: flex;justify-content: center;align-items: center;margin-top: 70rpx;" @click="sureAgree">
<text style="font-size: 36rpx;font-family: SourceHanSansBold;color: #fff;" >同意并支付</text>
</view>
<text style="font-size: 36rpx;color: #606271;font-family: SourceHanSansBold;margin-top: 40rpx;" @click="notAgree">取消</text>
</view>
</uni-popup>
<ShowPop v-if="showPopFlag" :code="showPopCode" @closeProcotolPop="closeProcotolPop"></ShowPop>
</template>
<script setup>
import {
ref
} from 'vue'
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
import ShowPop from "@/components/show-pop/show-pop.vue";
const psychicShowDetail = ref()
const showDetailFlag = ref(false)
const timeSlot = ref()
const popSlot = ref()
const showPopFlag= ref(false)
const showPopCode= ref("")
const toShowProtocol = (code) => {
showPopFlag.value = true
showPopCode.value = code
}
const closeProcotolPop=()=>{
showPopFlag.value = false
showPopCode.value = ""
}
onLoad((option) => {
if (option && option.id) {
psychicOrder.value.doctorId = option.id
getDetail(option.id)
getDateDetailList()
} else {
uni.showModal({
title: '数据异常',
content: '页面数据发生异常,即将返回主页',
showCancel: false,
success: function(res) {
if (res.confirm) {
uni.reLaunch({
url: "/pages/index/index"
})
}
}
})
}
if (option && option.choiceDayFlag == 2) {
setTimeout(() => {
showChoiceDateTimePop()
}, 500)
}
})
const agreeFlag=ref(false)
const agree=()=>{
agreeFlag.value = !agreeFlag.value
}
const changeEmergencyContactType=(e)=>{
psychicOrder.value.emergencyContactType = e
}
const showChoiceDateTimePop = () => {
timeSlot.value.open("bottom")
}
const choiceDateIndex = ref()
const choiceTimeIndex = ref()
const appointmentDate = ref()
const appointmentTime = ref()
const choiceDate = (ele, index1, item, index) => {
choiceDateIndex.value = index
choiceTimeIndex.value = index1
appointmentDate.value = item
appointmentTime.value = ele
psychicOrder.value.slotId = ele.slotId
if (ele.consultationMethod){
showVideo.value = ele.consultationMethod.indexOf('video') >= 0
showFaceToFace.value = ele.consultationMethod.indexOf(
'face_to_face') >= 0
}
}
// 将时间字符串转换为总分钟数
const timeToMinutes = (timeStr) => {
const [hours, minutes] = timeStr.split(':').map(Number);
return hours * 60 + minutes;
}
// 计算时间差(处理跨天情况)
const calculateTimeDifference = (startTime, endTime) => {
const startMinutes = timeToMinutes(startTime);
const endMinutes = timeToMinutes(endTime);
let diff = endMinutes - startMinutes;
// 如果跨天(结束时间早于开始时间),补上24小时
if (diff < 0) diff += 24 * 60;
return diff;
}
const onShareAppMessage = () => {
return {
title: '快来体验一下吧~',
path: '/pages/index/index', // 分享的路径
};
};
const onShareTimeline = () => {
return {
title: '快来体验一下吧~',
query: 'id=12', // 分享路径的参数
};
};
const appointmentDateDetailList = ref([])
const choiceSlotNum = ref(0)
const getDateDetailList = () => {
let queryData = {
doctorId: psychicOrder.value.doctorId
}
dohttp.post(urls.dateDetailList, queryData).then((result) => {
console.log("resultresult", result)
if (result && result.length > 0) {
appointmentDateDetailList.value = result.reverse()
appointmentDateDetailList.value.forEach(ele => {
choiceSlotNum.value += ele.slotVOList.length
})
} else {
uni.showModal({
title: '数据异常',
content: '该咨询师暂无排班信息,请选择其他咨询师',
showCancel: false,
success: function(res) {
if (res.confirm) {
uni.reLaunch({
url: "/pages/consult/consult"
})
}
}
})
}
})
}
const showVideo = ref(false)
const showFaceToFace = ref(false)
const getDetail = (id) => {
dohttp.get(urls.getShowInfo + "?id=" + id).then((result) => {
if (result) {
psychicShowDetail.value = result
psychicOrder.value.totalAmount = psychicShowDetail.value.price
if (psychicShowDetail.value.consultationMethod) {
showVideo.value = psychicShowDetail.value.consultationMethod.indexOf('video') >= 0
showFaceToFace.value = psychicShowDetail.value.consultationMethod.indexOf(
'face_to_face') >= 0
// psychicShowDetail.value.consultationMethodList = psychicShowDetail.value.consultationMethod
// .split(",")
if (psychicShowDetail.value.consultationMethod.indexOf('video') >= 0) {
psychicOrder.value.consultationMethod = 'video' //默认 咨询方式为未视频
} else {
psychicOrder.value.consultationMethod = 'face_to_face' //默认 咨询方式为未视频
}
}
if (psychicShowDetail.value.appointmentInfoAppRespVO) {
psychicOrder.value.appointmentName = psychicShowDetail.value.appointmentInfoAppRespVO
.appointmentName
if (psychicShowDetail.value.appointmentInfoAppRespVO.birthday) {
psychicOrder.value.birthday = psychicShowDetail.value.appointmentInfoAppRespVO.birthday.slice(0, 7)
}
psychicOrder.value.phone = psychicShowDetail.value.appointmentInfoAppRespVO.phone
if (psychicShowDetail.value.appointmentInfoAppRespVO.sex) {
psychicOrder.value.sex = psychicShowDetail.value.appointmentInfoAppRespVO.sex
}
if (psychicShowDetail.value.appointmentInfoAppRespVO.emergencyContactType) {
psychicOrder.value.emergencyContactType = Number(psychicShowDetail.value
.appointmentInfoAppRespVO
.emergencyContactType)
}
if (psychicShowDetail.value.appointmentInfoAppRespVO.emergencyContactPhone) {
psychicOrder.value.emergencyContactPhone = psychicShowDetail.value
.appointmentInfoAppRespVO
.emergencyContactPhone
}
}
}
})
}
const choiceSex = (sex) => {
psychicOrder.value.sex = sex
}
const advancedFormat = (num) => {
const divided = Number(num) / 100;
// 转换为字符串处理科学计数法(如1e-7)
const str = divided.toLocaleString('en-US', {
maximumFractionDigits: 2,
useGrouping: false
});
return str.replace(/(\.\d*?[1-9])0+$/, '$1').replace(/\.$/, '');
}
const bindDateChange = (event) => {
psychicOrder.value.birthday = event.detail.value
}
const bgHeight = ref("100vh")
const changeDetailFlag = () => {
showDetailFlag.value = true
bgHeight.value = "fit-content"
}
const sureTime = () => {
if (!appointmentDate.value || !appointmentTime.value) {
uni.showToast({
title: '未选择咨询时段',
icon: 'error',
duration: 2000
});
return
}
timeSlot.value.close()
}
const psychicOrder = ref({
slotId: null,
doctorId: null,
appointmentName: null,
birthday: "1990-01",
phone: null,
sex: 1,
emergencyContactInfo: null,
consultationMethod: null,
emergencyContactPhone: "",
emergencyContactType: 1,
totalAmount: 0,
})
const range = ref([{
value: 1,
text: "朋友"
},
{
value: 2,
text: "子女"
},
{
value: 3,
text: "夫妻"
},
{
value: 4,
text: "父母"
},
])
const choiceConsultationMethod = (consultationMethod) => {
psychicOrder.value.consultationMethod = consultationMethod
}
const provider = ref("")
const createOrder = () => {
psychicOrder.value.emergencyContactInfo = JSON.stringify({
phone: psychicOrder.value.emergencyContactPhone,
type: psychicOrder.value.emergencyContactType
})
const deepCopy = JSON.parse(JSON.stringify(psychicOrder.value));
deepCopy.birthday =deepCopy.birthday+"-01"
return dohttp.post(urls.createZxOrder,deepCopy)
}
const sureAgree=()=>{
agreeFlag.value = true
popSlot.value.close()
toPay()
}
const notAgree=()=>{
popSlot.value.close()
}
const validatePhone = (phone)=> {
const regex = /^1[3-9]\d{9}$/;
return regex.test(phone);
}
const validData=()=>{
if(!psychicOrder.value.slotId){
uni.showModal({
title: '提示',
content: '请选择预约时段',
showCancel: false,
})
return false
}
if(!psychicOrder.value.appointmentName){
uni.showModal({
title: '提示',
content: '请填写预约人称呼',
showCancel: false,
})
return false
}
if(!psychicOrder.value.phone){
uni.showModal({
title: '提示',
content: '请填写预约人联系方式',
showCancel: false,
})
return false
}
if (!psychicOrder.value.birthday){
uni.showModal({
title: '提示',
content: '请选择预约人出生年月',
showCancel: false,
})
return false
}
if (!psychicOrder.value.sex){
uni.showModal({
title: '提示',
content: '请选择预约人性别',
showCancel: false,
})
return false
}
if (!psychicOrder.value.emergencyContactPhone){
uni.showModal({
title: '提示',
content: '请填写紧急联系人电话',
showCancel: false,
})
return false
}
if (!psychicOrder.value.emergencyContactType){
uni.showModal({
title: '提示',
content: '请选择紧急联系人与你的关系',
showCancel: false,
})
return false
}
if(!validatePhone(psychicOrder.value.phone)){
uni.showModal({
title: '提示',
content: '请填写正确的预约人手机号码',
showCancel: false,
})
return false
}
if(!validatePhone(psychicOrder.value.emergencyContactPhone)){
uni.showModal({
title: '提示',
content: '请填写正确的紧急联系人手机号码',
showCancel: false,
})
return false
}
return true
}
const expandPopSlot=()=>{
popSlot.value.open("center")
}
const toPay = async () => {
if(!validData()){
return
}
if(!agreeFlag.value){
popSlot.value.open("center")
return
}
const result = await createOrder()
console.log("toPay------------", result)
uni.requestPayment({
provider: 'wxpay',
timeStamp: result.timeStamp,
nonceStr: result.nonceStr,
package: result.packageStr,
signType: result.signType,
paySign: result.paySign,
success: function(res) {
dohttp.navigateTo("/pages/order/order?backHome="+1)
},
fail: function(err) {
dohttp.navigateTo("/pages/order/order")
}
})
}
</script>
<style scoped>
.content {
width: 100vw;
background-color: #F9F6F5;
font-family: 'SourceHanSans';
}
.psychic-top {
border-radius: 10rpx 10rpx 0rpx 0rpx;
opacity: 1;
/* 自动布局 */
width: 670rpx;
height: 60rpx;
background: linear-gradient(180deg, #FFE7D9 0%, rgba(255, 255, 255, 0) 98%);
}
.card {
width: 670rpx;
background-color: #ffffff;
display: flex;
flex-direction: column;
box-sizing: border-box;
align-items: flex-start;
border-radius: 10rpx;
}
.psychic-card {
padding-left: 40rpx;
padding-right: 40rpx;
padding-bottom: 54rpx;
border-radius: 10rpx;
margin-top: -20rpx;
width: 670rpx;
box-sizing: border-box;
}
.psychic-name {
font-family: SourceHanSansBold;
font-size: 40rpx;
line-height: normal;
text-align: center;
letter-spacing: 0rpx;
font-variation-settings: "opsz" auto;
color: #614D49;
margin-left: 20rpx;
}
.psychic-price {
/* 标题/标题二加粗 */
font-family: SourceHanSans;
font-weight: 700;
font-size: 36rpx;
font-variation-settings: "opsz" auto;
color: #EA4E2D;
}
.psychic-unit {
/* 标题/标题二加粗 */
font-family: SourceHanSans;
font-weight: 700;
font-size: 20rpx;
font-variation-settings: "opsz" auto;
color: #EA4E2D;
}
.psychic-detail-text {
font-family: SourceHanSansBold;
font-size: 28rpx;
line-height: normal;
text-align: center;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
/* 背景色/浅色背景2 */
color: #614D49;
}
.psychic-detail-title-text {
font-family: SourceHanSans;
font-size: 28rpx;
font-weight: normal;
line-height: normal;
text-align: center;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
/* 背景色/浅色背景2 */
color: #614D49;
}
.psychic-detail-title-text1 {
font-family: SourceHanSans;
font-size: 24rpx;
font-weight: normal;
line-height: normal;
text-align: center;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
/* 背景色/浅色背景2 */
color: #614D49;
}
.psychic-detail-show-text {
font-family: SourceHanSans;
font-size: 24rpx;
font-weight: normal;
line-height: normal;
text-align: center;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
/* 背景色/浅色背景2 */
color: #909099;
}
.line {
margin-top: 41rpx;
width: 100%;
border: 1rpx dashed #DFD6D3;
}
.psychic-detail-row {
display: flex;
justify-content: space-between;
width: 100%;
margin-top: 39rpx;
}
.right-icon {
width: 15rpx;
height: 25rpx;
margin-left: 20rpx;
}
.expand-text {
font-family: SourceHanSansBold;
font-size: 24rpx;
line-height: normal;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
color: #EA4E2D;
}
.expand-bottom {
width: 670rpx;
margin-top: 40rpx;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
justify-content: center;
height: 62rpx;
border-radius: 0px 0px 10rpx 10rpx;
background: linear-gradient(180deg, #FFFFFF 10%, #FFF3EF 80%);
}
.input-text {
font-family: SourceHanSans;
font-size: 28rpx;
font-weight: normal;
line-height: normal;
text-align: right;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
/* 正文色/正文辅助4 */
color: #606271;
}
.bottom-btn {
width: 550rpx;
height: 96rpx;
border-radius: 2002rpx;
/* 自动布局 */
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 8rpx 40rpx;
background: linear-gradient(180deg, #FF9079 0%, #F37155 100%);
margin-bottom: 82rpx;
margin-top: 68rpx;
}
.btn-text {
font-family: SourceHanSansBold;
font-size: 36rpx;
line-height: normal;
letter-spacing: 0rpx;
/* 正文色/正文色 */
color: #FFFFFF;
}
.time-card {
width: 116rpx;
height: 108rpx;
border-radius: 10rpx;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
margin-left: 40rpx;
border: 1rpx solid #909099;
box-sizing: border-box;
margin-top: 40rpx;
color: #606271;
}
.date-card {
width: 116rpx;
height: 108rpx;
border-radius: 10rpx;
background-color: #F7F4F3;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
margin-top: 40rpx;
color: #606271;
}
</style>
@@ -0,0 +1,53 @@
<template>
<view class="content">
<myNav title="协议内容" bgColor="#fff" titleColor="#614D49" :backIcon="true" :backHome="false" :flex="false">
</myNav>
<view style="width: 100%;height: 100%;display: flex;flex-direction: column;align-items: center;overflow-y: auto;padding-bottom: 40rpx;">
<view style="margin: 40rpx;display: flex;width: 670rpx;flex-direction: column;align-items: center;background-color: #fff;box-sizing: border-box;
border-radius: 10rpx;padding: 40rpx;">
<text class="title">{{procotol.title}}</text>
<rich-text style="margin-top: 40rpx;" :nodes="procotol.context"></rich-text>
</view>
</view>
</view>
</template>
<script setup>
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
onLoad((option) => {
getProcotol()
})
const procotol=ref()
const getProcotol = () => {
dohttp.post(urls.getByCode + "?code=consultation_appointment_agreement").then((result) => {
procotol.value = result
})
}
</script>
<style scoped>
.content {
width: 100vw;
height: 100vh;
background-color: #f9f8f8;
display: flex;
flex-direction: column;
font-family: SourceHanSans;
background-image: url('https://miniapp.yuxingu.com.cn/yxg-mp/pic/bg-all.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
font-family: SourceHanSans;
}
.title{
font-size: 36rpx;
font-family: SourceHanSansBold;
}
</style>
+855
View File
@@ -0,0 +1,855 @@
<template>
<view class="content">
<!-- <myNav title="" bgColor="nonoe" titleColor="#000" :backIcon="true" :backHome="false" :flex="false"></myNav> -->
<view class="back-btn" :style="{'height':backBtnHeight+'px','width':backBtnHeight+'px'}" @click="toBack">
<image src="/static/back/n-back-mini.png" mode="widthFix" :style="{'width':backBtnImgWidth+'px'}"></image>
</view>
<view style="display: flex;flex-direction: column;justify-content: center;">
<image :src="showDetail.coverUrl" style="width: 750rpx;height:600rpx;"></image>
<view style="position: relative;display: flex;justify-content: center;height: 402rpx;">
<view class="header-detail">
<view class="header-detail-top">
</view>
<view class="header-detail-show">
<view style="display: flex;justify-content: space-between;align-items: first baseline;">
<view>
<text class="name-class">{{ showDetail.name }}</text>
<!-- <text class="school-class">{{ showDetail.education }}</text> -->
</view>
<view>
<text class="momey-text">¥{{ advancedFormat(showDetail.price) }}</text>
<text class="unit-text">/</text>
</view>
</view>
<view style="display: flex;flex-wrap: wrap;margin-top: 15rpx;">
<view class="tag" :key="index" v-for="(item,index) in showDetail.tagList">
<text class="tag-text">{{ item }}</text>
</view>
</view>
<view style="margin-left: 5rpx;margin-top: 15rpx;">
<text class="showjj">{{showDetail.introduction}}</text>
</view>
</view>
<view style="position: absolute; bottom: 20rpx; left: 0; right: 0;">
<view style="display: flex;justify-content: space-evenly;align-items: center;">
<view style="display: flex;flex-direction: column;">
<view>
<text class="service-time-text-big">{{ showDetail.workExperience }}+</text>
<text class="service-time-text-mini">小时</text>
</view>
<view
style="margin-top: 10rpx;display: flex;justify-content: center;align-items: center;">
<image src="/static/n-zx/l-icon.png" style="width: 25rpx;height: 36rpx;"></image>
<text class="service-text" style="margin-left: 6rpx;">咨询经验</text>
</view>
</view>
<view style="height: 92rpx;width: 2rpx;background: #DFD6D3;">
</view>
<view style="display: flex;flex-direction: column;">
<view>
<text
class="service-time-text-big">{{ preciseYearDiff(showDetail.workStartTime) }}+</text>
<text class="service-time-text-mini"></text>
</view>
<view
style="margin-top: 10rpx;display: flex;justify-content: center;align-items: center;">
<image src="/static/n-zx/r-icon.png" style="width: 25rpx;height: 36rpx;"></image>
<text class="service-text" style="margin-left: 6rpx;">从业年限</text>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 简介 可约时间 预约须知 -->
<view id="section1" style="display: flex;align-items: center;margin-top: 20rpx;flex-direction: column;">
<view
style="background-color:#FFFFFF;border-radius: 10rpx;width: 670rpx;display:flex;flex-direction: column;">
<view style="display: flex;align-items: center;justify-content: space-around;margin-top: 29rpx;">
<view v-for="(item,index) in types" :key="index"
style="display: flex;flex-direction: column;justify-content: center;align-items: center;"
@click="choice(item)">
<text :class="{ 'choice-text': choiceTypeCode==item.code,
'no-choice-text': choiceTypeCode!=item.code }">{{ item.name }}
</text>
<view :class="{'choice-icon':choiceTypeCode==item.code}"></view>
</view>
</view>
<view style="padding: 28rpx;">
<rich-text :nodes="showDetail.resume"></rich-text>
</view>
</view>
<view id="section2" style="width: 670rpx;border-radius: 10rpx;background-color: #FFFFFF;display: flex;flex-direction: column;
margin-top: 20rpx;padding-top: 28rpx;padding-bottom: 40rpx;">
<view style="display: flex;padding-left: 40rpx;align-items: baseline;">
<text class="reservation-title-text-large">可预约时间</text>
<text class="reservation-title-text-mini" style="margin-left: 10rpx;">(北京时间)</text>
</view>
<text class="reservation-title-text-mini"
style="padding-left: 40rpx;padding-right: 40rpx;">如果暂时无法确定具体的咨询时间可以在预约成功后再与咨询师协商
</text>
<view style="background: #F37155;width: 100%;height: 64rpx;border-top-right-radius:10rpx ;
border-top-left-radius:10rpx ;margin-top: 20rpx;display: flex;align-items: center;">
<text class="reservation-time-month" style="margin-left:54rpx ;">
{{ yearMonth }}
</text>
</view>
<view
style="padding-left: 10rpx;padding-right: 10rpx;display:flex;flex-direction: column;align-items: center;">
<view class="row">
<view class="row-unit">
<text class="reservation-time-week"></text>
</view>
<view class="row-unit">
<text class="reservation-time-week"></text>
</view>
<view class="row-unit">
<text class="reservation-time-week"></text>
</view>
<view class="row-unit">
<text class="reservation-time-week"></text>
</view>
<view class="row-unit">
<text class="reservation-time-week"></text>
</view>
<view class="row-unit">
<text class="reservation-time-week"></text>
</view>
<view class="row-unit">
<text class="reservation-time-week"></text>
</view>
</view>
<view class="line"></view>
<view style="display: flex;flex-wrap: wrap;width: 630rpx;">
<view style="height: 104rpx;width: 90rpx;" :key="idx" v-for="(item,idx) in allDates">
<view class="day-unit" v-if="item.dateStr"
:style="{'backgroundColor': idx == choiceIdx?'#F37155':'transparent' }"
@click="choiceDay(idx,item)">
<text class="reservation-time-day"
:style="{'color': idx == choiceIdx?'#FFFFFF':'#000' }">{{ item.nextMonth? item.nextMonth:item.day }}
</text>
<text class="reservation-time-day-text" v-if="item.remainNum"
:style="{'color': idx == choiceIdx?'#FFFFFF':'#F37155' }">
{{ item.remainNum }}
</text>
<text class="reservation-time-day-text" v-else
:style="{'color': idx == choiceIdx?'#FFFFFF':'#9B918C' }">-
</text>
</view>
</view>
</view>
</view>
</view>
<view id="section3"
style="width: 670rpx;border-radius: 10rpx;background-color: #FFFFFF;display: flex;flex-direction: column;box-sizing: border-box;
align-items: center;justify-content: center;
margin-top: 20rpx;padding-top: 20rpx;padding-bottom: 14rpx;padding-left: 34rpx;padding-right: 34rpx;margin-bottom: 196rpx;">
<text class="reservation-notice-text">预约须知</text>
<rich-text :nodes="procotol.context" style="margin-top: 34rpx;"></rich-text>
</view>
</view>
</view>
<view
style="width: 750rpx;position: fixed;height:176rpx ;background-color: #FFFFFF;display: flex;align-items: center;bottom: 0;left: 0;">
<view style="margin-left: 50rpx;width: 100rpx;display: flex;flex-direction: column;align-items: center;"
@click="focusDoctor">
<image v-if="!showDetail.focus" src="/static/n-zx/gz.png" style="width: 43.4rpx;height: 40.02rpx;">
</image>
<image v-if="showDetail.focus" src="/static/n-menu/wd-c.png" style="width: 46rpx;height: 48rpx;">
</image>
<text v-if="!showDetail.focus" class="operate-text" style="margin-top: 6rpx;">关注</text>
<text v-if="showDetail.focus" class="operate-text" style="margin-top: 6rpx;">取消关注</text>
</view>
<view
style="width: 50rpx;display: flex;flex-direction: column;align-items: center;margin-left: 84rpx;">
<button plain class="contact-btn" open-type="contact">
<image src="/static/n-zx/kf.png" style="width: 40rpx;height: 40rpx;"></image>
</button>
<text class="operate-text" style="margin-top: 6rpx;">客服</text>
</view>
<view style="margin-left: 100rpx;width: 250rpx;height: 86rpx;border-radius: 2002rpx;
background: linear-gradient(180deg, #E84B2A 0%, #FF846A 100%);display: flex; flex-direction: column;
justify-content: center; align-items: center; padding: 8rpx 40rpx;" @click="toAppoint">
<text class="button-text">立即预约</text>
</view>
</view>
</view>
</template>
<script setup>
import {
ref
} from 'vue'
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
const choiceTypeCode = ref("code1")
const choiceIdx = ref()
const backBtnHeight = ref()
const backBtnImgWidth = ref()
const types = ref([{
code: "code1",
name: '个人简介'
},
{
code: "code2",
name: '可约时间'
},
{
code: "code3",
name: '预约须知'
},
])
const doctorId = ref()
const choiceDayFlag = ref(1)
const procotol=ref()
const getProcotol = () => {
dohttp.post(urls.getByCode + "?code=psychological_show_appointment_agreement").then((result) => {
procotol.value = result
})
}
const choiceDay = (idx, item) => {
choiceIdx.value = idx
if (item.remainNum) {
choiceDayFlag.value = 2
} else {
choiceDayFlag.value = 1
}
}
const onShareAppMessage = () => {
return {
title: '快来体验一下吧~',
path: '/pages/index/index', // 分享的路径
};
};
const onShareTimeline = () => {
return {
title: '快来体验一下吧~',
query: 'id=21', // 分享路径的参数
};
};
const choice = (item) => {
let sectionId = null
if (item.code == 'code1') {
sectionId = "#section1"
}
if (item.code == 'code2') {
sectionId = "#section2"
}
if (item.code == 'code3') {
sectionId = "#section3"
}
choiceTypeCode.value = item.code
if (sectionId) {
uni.pageScrollTo({
selector: sectionId, // 目标元素选择器
duration: 300, // 滚动动画时长
success: () => {
console.log('滚动成功')
}
})
}
}
const toBack = () => {
uni.navigateBack({
delta: 1
})
}
onMounted(() => {
const systemInfo = uni.getSystemInfoSync()
// 胶囊位置信息
let rect = uni.getMenuButtonBoundingClientRect();
let navBarHeight = (rect.top - systemInfo.statusBarHeight) * 2 + rect.height;
backBtnHeight.value = navBarHeight
backBtnImgWidth.value = navBarHeight * 0.3
getProcotol()
})
const todayWeekdayIndex = ref(0)
onLoad((option) => {
const currentDate = new Date();
todayWeekdayIndex.value = currentDate.getDay()
// 必须根据今天星期几先插入相关数据 构建数据 让日历对齐
for (var i = 0; i < todayWeekdayIndex.value; i++) {
allDates.value.push({
dateStr: "",
day: ""
})
}
getYearAndMonth()
getOneMonth()
if (option && option.id) {
doctorId.value = option.id
getDetail(option.id)
getAppointDate()
} else {
uni.showModal({
title: '数据异常',
content: '页面数据发生异常,即将返回主页',
showCancel: false,
success: function (res) {
if (res.confirm) {
uni.reLaunch({
url: "/pages/index/index"
})
}
}
})
}
})
const getDateRange = (start, end) => {
const dates = [];
let current = new Date(start);
while (current <= end) {
let dateStr = formatDate(new Date(current))
dates.push(dateStr);
current.setDate(current.getDate() + 1);
}
return dates;
}
const formatDate = (date) => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
let obj = {
dateStr: `${year}-${month}-${day}`,
day: `${day}`
}
if(day=="01"&&currentMonth.value!=month){
obj.nextMonth = Number(month)+"月";
}
return obj;
}
const allDates = ref([])
const getOneMonth = () => {
const startDate = new Date();
const endDate = new Date(startDate);
endDate.setMonth(startDate.getMonth() + 1);
allDates.value.push(...getDateRange(startDate, endDate));
allDates.value.length = allDates.value.length - todayWeekdayIndex.value
}
const havingTime = ref(true)
const getAppointDate = () => {
let queryData = {
doctorId: doctorId.value
}
dohttp.post(urls.appointTotalList, queryData).then((result) => {
if (result&&result.length>0) {
const map = new Map(result.map(item => [item.scheduleDate, item]));
allDates.value.forEach(ele => {
if (ele.dateStr && map.get(ele.dateStr)) {
ele.remainNum = map.get(ele.dateStr).remainNum
}
})
}else{
havingTime.value = false
}
})
}
const yearMonth = ref()
const currentMonth=ref("")
const getYearAndMonth = () => {
// 创建Date对象
const currentDate = new Date();
// 获取年份(四位数)
const year = currentDate.getFullYear(); // 例如2025[1,2,3](@ref)
// 获取月份(0-11),需+1并补零
const month = String(currentDate.getMonth() + 1).padStart(2, '0'); // 例如04[1,4,7](@ref)
// 拼接为“YYYY-MM”格式
yearMonth.value = `${year}${month}`;
currentMonth.value = month
}
const showDetail = ref({})
const getDetail = (id) => {
dohttp.get(urls.getDoctorInfo + "?id=" + id).then((result) => {
if (result) {
if (result.tags) {
let tags = result.tags.split(",")
result.tagList = tags
}
showDetail.value = result
} else {
uni.showModal({
title: '数据异常',
content: '未获取到该咨询师信息,请选择其他咨询师',
showCancel: false,
success: function (res) {
if (res.confirm) {
uni.reLaunch({
url: "/pages/consult/consult"
})
}
}
})
}
})
}
const advancedFormat = (num) => {
const divided = Number(num) / 100;
// 转换为字符串处理科学计数法(如1e-7)
const str = divided.toLocaleString('en-US', {
maximumFractionDigits: 2,
useGrouping: false
});
return str.replace(/(\.\d*?[1-9])0+$/, '$1').replace(/\.$/, '');
}
const preciseYearDiff = (dateStr) => {
const target = new Date(dateStr);
const now = new Date();
// 计算完整年数
let years = now.getFullYear() - target.getFullYear();
// 检查月份和日期是否已超过
const monthDiff = now.getMonth() - target.getMonth();
if (monthDiff < 0 || (monthDiff === 0 && now.getDate() < target.getDate())) {
years--;
}
// 极端情况处理:闰年2月29日
if (target.getMonth() === 1 && target.getDate() === 29) {
const isLeapYear = (year) => (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
if (!isLeapYear(now.getFullYear()) && now.getMonth() === 1 && now.getDate() === 28) {
years++; // 闰日未到但当年非闰年时特殊处理
}
}
return years;
}
const focusDoctor = () => {
if (!showDetail.value.focus) {
dohttp.post(urls.focus + "?id=" + doctorId.value).then((result) => {
getDetail(doctorId.value)
})
} else {
dohttp.post(urls.cancelFocus + "?id=" + doctorId.value).then((result) => {
getDetail(doctorId.value)
})
}
}
const toAppoint = () => {
if(!havingTime.value){
uni.showModal({
title: '暂无排班',
content: '该咨询师暂无排班信息,请选择其他咨询师',
showCancel: false,
success: function (res) {
if (res.confirm) {
uni.reLaunch({
url: "/pages/consult/consult"
})
}
}
})
return
}
dohttp.navigateTo("/pages/appoint/appoint?id=" + doctorId.value + "&choiceDayFlag=" + choiceDayFlag.value)
}
</script>
<style scoped>
.content {
width: 100vw;
height: fit-content;
background-color: #F9F6F5;
display: flex;
flex-direction: column;
font-family: SourceHanSans;
box-sizing: border-box;
}
.header-detail {
width: 670rpx;
min-height: 378rpx;
border-radius: 10rpx;
opacity: 1;
/* 自动布局 */
display: flex;
flex-direction: column;
background: #FFFFFF;
margin-top: -26rpx;
}
.header-detail-top {
height: 60rpx;
border-radius: 10rpx 10rpx 0px 0px;
background: linear-gradient(180deg, #FFE7D9 0%, rgba(255, 255, 255, 0) 98%);
}
.header-detail-show {
display: flex;
flex-direction: column;
padding-left: 40rpx;
padding-right: 40rpx;
padding-bottom: 26rpx;
margin-top: -26rpx;
}
.name-class {
font-family: SourceHanSansBold;
font-size: 40rpx;
line-height: normal;
text-align: center;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
color: #614D49;
}
.school-class {
font-family: SourceHanSans;
font-size: 24rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
/* 正文色/正文辅助4 */
color: #9B918C;
margin-left: 18rpx;
}
.momey-text {
color: #F37155;
/* 标题/标题二加粗 */
font-family: SourceHanSansBold;
font-size: 38rpx;
font-weight: 700;
font-variation-settings: "opsz" auto;
}
.unit-text {
/* 正文/正文文本小号加粗 */
font-family: SourceHanSans;
font-weight: 700;
font-size: 22rpx;
font-variation-settings: "opsz" auto;
color: #F37155;
}
.tag {
border-radius: 80rpx;
opacity: 1;
/* 自动布局 */
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 4rpx 14rpx;
background: linear-gradient(270deg, #FFF0E7 0%, #FFCEC4 97%);
margin-left: 5rpx;
}
.tag-text {
/* 正文/正文文本超小 */
/* 样式描述:辅助信息 */
font-family: SourceHanSans;
font-size: 16rpx;
font-weight: normal;
line-height: normal;
text-align: center;
letter-spacing: 0px;
/* 背景色/浅色背景2 */
color: #303044;
}
.service-time-text-big {
color: #303044;
font-family: SourceHanSansBold;
font-size: 40rpx;
font-variation-settings: "opsz" auto;
}
.service-time-text-mini {
color: #303044;
font-family: SourceHanSansBold;
font-size: 22rpx;
font-variation-settings: "opsz" auto;
}
.service-text {
font-family: SourceHanSans;
font-size: 24rpx;
font-weight: normal;
line-height: normal;
text-align: center;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
/* 背景色/浅色背景2 */
color: #303044;
}
.no-choice-text {
/* 按钮/按钮文本中号 */
font-family: SourceHanSans;
font-size: 28rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
/* 背景色/浅色背景2 */
color: #9B918C;
}
.choice-text {
/* 样式描述:常规大按钮 */
font-family: SourceHanSansBold;
font-size: 28rpx;
line-height: normal;
letter-spacing: 0px;
/* 背景色/深色大背景 */
color: #614D49;
z-index: 0;
}
.choice-icon {
width: 60%;
height: 10rpx;
border-radius: 424rpx;
background: #F37155;
}
.reservation-title-text-large {
font-family: SourceHanSansBold;
font-size: 36rpx;
line-height: normal;
text-align: center;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
/* 背景色/浅色背景2 */
color: #614D49;
}
.reservation-title-text-mini {
font-family: SourceHanSans;
font-size: 20rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
/* 正文色/正文辅助4 */
color: #9B918C;
}
.reservation-time-month {
font-family: SourceHanSansBold;
font-size: 28rpx;
line-height: normal;
text-align: center;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
color: #FFFFFF;
}
.reservation-time-week {
font-family: SourceHanSans;
font-size: 30rpx;
font-weight: normal;
line-height: 36rpx;
letter-spacing: 0px;
color: #000000;
}
.line {
width: 670rpx;
height: 0px;
opacity: 1;
border: 2rpx solid #EDEDED;
}
.row-unit {
width: 90rpx;
display: flex;
justify-content: center;
align-items: center;
}
.row {
width: 630rpx;
display: flex;
height: 76rpx;
}
.reservation-time-day {
font-family: SourceHanSans;
font-size: 30rpx;
font-weight: normal;
line-height: 36rpx;
letter-spacing: 0px;
color: #000000;
}
.reservation-time-day-text {
font-family: SourceHanSans;
font-size: 20rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
/* 正文色/正文色辅助3 */
color: #9B918C;
}
.reservation-time-today {
font-family: SourceHanSans;
font-size: 30rpx;
font-weight: normal;
line-height: 36rpx;
letter-spacing: 0rpx;
/* 今天 */
color: #186BF9
}
.day-unit {
border-radius: 10rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100%;
}
.reservation-notice-text {
font-family: SourceHanSansBold;
font-size: 28rpx;
line-height: normal;
text-align: center;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
color: #614D49;
}
.operate-text {
font-family: SourceHanSans;
font-size: 24rpx;
font-weight: 500;
line-height: 36rpx;
letter-spacing: 0rpx;
/* 正文色/正文色辅助3 */
color: #9B918C;
}
.button-text {
font-family: SourceHanSansBold;
font-size: 36rpx;
line-height: normal;
letter-spacing: 0px;
/* 正文色/正文色 */
color: #FFFFFF;
}
.back-btn {
width: 750rpx;
position: absolute;
background-color: rgba(255, 255, 255, 0.3);
display: flex;
align-items: center;
top: 0;
left: 0;
margin-top: 54px;
width: 40px;
border-radius: 50%;
margin-left: 24rpx;
display: flex;
justify-content: center;
align-items: center;
}
.contact-btn {
border: none;
outline: none;
width: 40rpx;
height: 40rpx;
padding: 0rpx;
margin: 0rpx;
background-color: transparent;
display: flex;
align-items: center;
background-color: #fff;
}
.showjj{
font-family: SourceHanSans;
font-size: 24rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
color: #9B918C;
display: -webkit-box; /* 使用 flex 布局 */
-webkit-box-orient: vertical; /* 垂直排列 */
-webkit-line-clamp: 3; /* 限制显示行数 */
overflow: hidden; /* 超出部分隐藏 */
text-overflow: ellipsis; /* 超出部分显示省略号 */
}
</style>
+351
View File
@@ -0,0 +1,351 @@
<template>
<view class="content">
<image src="/static/n-main/overlap-bg.png" style="width: 750rpx;height: 660rpx;position: absolute;z-index: 1;">
</image>
<view
style="display: flex;justify-content: center;flex-direction: column;position: absolute;z-index: 2;width: 750rpx;">
<myNav title="心理咨询" bgColor="nonoe" titleColor="#614D49" :backIcon="false" :backHome="false" :flex="false">
</myNav>
<scroll-view v-if="list.length>0" :scroll-y="enableScroll" @scrolltolower="scrolltolower" class="scroll-style"
:style="{ height: `${showHight}rpx` }">
<view id="contentContainer"
style="display: flex;flex-direction: column;align-items: center;margin-top: 10rpx;">
<view class="show-card" v-for="(item,index) in list" :key="index" @click="toDetail(item)">
<view style="position: relative;156rpx;height: 204rpx;">
<image :src="item.avatar" style="width: 156rpx;height: 204rpx;border-radius: 10rpx;"></image>
</view>
<view style="position: relative; display: flex;flex-direction: column;margin-left: 20rpx;width: 452rpx;
justify-content: space-between">
<view style="display: flex;flex-direction: column; gap: 4rpx;">
<text class="show-name">
{{item.name}}
</text>
<view style="display: flex;height: 28rpx;" v-if="item.tags&&item.tags.length==1">
<view class="tag">
<text class="tag-text">{{item.tags[0]}}</text>
</view>
</view>
<view style="display: flex;height: 28rpx;" v-if="item.tags&&item.tags.length==2">
<view class="tag">
<text class="tag-text">{{item.tags[0]}}</text>
</view>
<view class="tag" style="margin-left:20rpx;">
<text class="tag-text">{{item.tags[1]}}</text>
</view>
</view>
<view style="display: flex;height: 28rpx;" v-if="item.tags&&item.tags.length==3">
<view class="tag">
<text class="tag-text">{{item.tags[0]}}</text>
</view>
<view class="tag" style="margin-left:20rpx;">
<text class="tag-text">{{item.tags[1]}}</text>
</view>
<view class="tag" style="margin-left:20rpx;">
<text class="tag-text">{{item.tags[2]}}</text>
</view>
</view>
<view style="display: flex;height: 28rpx;" v-if="item.tags&&item.tags.length>=4">
<view class="tag">
<text class="tag-text">{{item.tags[0]}}</text>
</view>
<view class="tag" style="margin-left:20rpx;">
<text class="tag-text">{{item.tags[1]}}</text>
</view>
<view class="tag" style="margin-left:20rpx;">
<text class="tag-text">{{item.tags[2]}}</text>
</view>
<view class="tag" style="margin-left:20rpx;">
<text class="tag-text">{{item.tags[3]}}</text>
</view>
</view>
<text class="show-introduce" >
{{item.introduction}}
</text>
<!-- <text class="show-introduce">
擅长:婚姻家庭/情绪管理/个人成长从业15年·咨询经验3300+小小时
</text> -->
</view>
<view style="position: absolute; right: 10rpx; bottom: -10rpx; display: flex;justify-content: flex-end;align-items: baseline;">
<view>
<text class="momey-text">
¥ {{item.price/100}}
</text>
<text class="unit-text">
/
</text>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
<view v-else style="width: 750rpx;height: 60vh;display: flex;justify-content: center;align-items: center;">
<text style="font-size: 30rpx;font-family: SourceHanSansBold;color: #EA4E2D">暂无咨询师数据</text>
</view>
</view>
</view>
</template>
<script setup>
import {
ref
} from 'vue'
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
const choiceTypeCode = ref()
const types = ref([])
const choice = (item) => {
if (item) {
choiceTypeCode.value = item.code
} else {
choiceTypeCode.value = ""
}
param.value.businessScope = choiceTypeCode.value
param.value.pageNo = 1
list.value=[]
getPage()
}
onMounted(() => {
getType()
getPage()
const systemInfo = uni.getSystemInfoSync()
showHight.value = (systemInfo.windowHeight * (750 / systemInfo.screenWidth)) - 180
})
const getType = () => {
dohttp.get(urls.businessScopeList).then((result) => {
types.value = result
let zxcode = uni.getStorageSync("zxcode")
if(zxcode){
choiceTypeCode.value = zxcode
uni.removeStorageSync("zxcode")
}
})
}
const param = ref({
businessScope: "",
pageNo: 1,
pageSize: 10
})
const totalNum = ref(0)
const list = ref([])
const getPage = () => {
dohttp.get(urls.doctorInfopage, param.value).then((result) => {
for (let i = 0; i < result.list.length; i++) {
if (result.list[i].consultationMethod) {
result.list[i].tags = result.list[i].tags.split(",")
}
}
list.value = result.list
totalNum.value = result.total
// 数据更新后检查高度
nextTick(() => {
checkContentHeight()
})
})
}
const onShareAppMessage = () => {
return {
title: '快来体验一下吧~',
path: '/pages/index/index', // 分享的路径
};
};
const onShareTimeline = () => {
return {
title: '快来体验一下吧~',
query: 'id=2', // 分享路径的参数
};
};
const showHight = ref(0)
// 新增代码
import {
onMounted,
nextTick,
getCurrentInstance
} from 'vue'
const instance = getCurrentInstance()
const enableScroll = ref(false) // 新增动态滚动控制
// 新增高度检查方法
const checkContentHeight = () => {
const query = uni.createSelectorQuery().in(instance.proxy)
query.select('#contentContainer').boundingClientRect(rect => {
if (rect) {
// 转换为rpx比较
const contentHeightRpx = rect.height * (750 / uni.getSystemInfoSync().screenWidth)
enableScroll.value = contentHeightRpx > showHight.value
console.log('内容高度:', contentHeightRpx, '容器高度:', showHight.value)
}
}).exec()
}
const toDetail=(item)=>{
dohttp.navigateTo("/pages/consult-detail/consult-detail?id=" + item.id)
}
</script>
<style scoped>
/* 新增关键样式 */
#contentContainer {
width: 100%;
min-height: 100%;
/* 确保内容容器撑开 */
}
.content {
width: 100vw;
height: 100vh;
background-image: url('https://miniapp.yuxingu.com.cn/yxg-mp/pic/test-list-bg.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
display: flex;
flex-direction: column;
position: relative;
}
.no-choice-text {
/* 按钮/按钮文本中号 */
font-family: SourceHanSans;
font-size: 32rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
/* 背景色/浅色背景2 */
color: #303044;
}
.choice-text {
/* 样式描述:常规大按钮 */
font-family: SourceHanSansBold;
font-size: 36rpx;
line-height: normal;
letter-spacing: 0px;
/* 背景色/深色大背景 */
color: #0F141B;
z-index: 0;
}
.choice-icon {
width: 80%;
height: 10rpx;
border-radius: 424rpx;
background: #EA4E2D;
}
.show-card {
margin-bottom: 20rpx;
width: 670rpx;
height: 244rpx;
border-radius: 10rpx;
background: #FFFFFF;
display: flex;
padding: 20rpx;
box-sizing: border-box;
justify-content: center;
}
.show-name {
/* 标题/标题三加粗 */
/* 样式描述:正文标题 */
font-family: SourceHanSansBold;
font-size: 28rpx;
line-height: normal;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
/* 背景色/浅色背景2 */
color: #614D49;
}
.show-introduce {
font-family: SourceHanSans;
font-size: 20rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
/* 正文色/正文辅助4 */
color: #9B918C;
display: -webkit-box; /* 使用 flex 布局 */
-webkit-box-orient: vertical; /* 垂直排列 */
-webkit-line-clamp: 3; /* 限制显示行数 */
overflow: hidden; /* 超出部分隐藏 */
text-overflow: ellipsis; /* 超出部分显示省略号 */
}
.tag {
border-radius: 60rpx;
opacity: 1;
/* 自动布局 */
display: flex;
padding: 2rpx 10rpx;
box-sizing: border-box;
border: 2rpx solid #EA8D7A;
justify-content: center;
align-items: center;
}
.tag-text {
/* 样式描述:辅助信息 */
font-family: SourceHanSans;
font-size: 16rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0rpx;
/* 正文色/正文色辅助3 */
color: #F37155;
}
.momey-text {
color: #F37155;
/* 标题/标题二加粗 */
font-family: SourceHanSansBold;
font-size: 36rpx;
font-variation-settings: "opsz" auto;
}
.unit-text {
/* 正文/正文文本小号加粗 */
font-family: SourceHanSans;
font-weight: 700;
font-size: 20rpx;
font-variation-settings: "opsz" auto;
color: #F37155;
}
</style>
@@ -0,0 +1,69 @@
<template>
<view class="content">
<myNav title="联系客服" bgColor="#fff" titleColor="#614D49" :backIcon="true" :backHome="false" :flex="false"></myNav>
<view style="display: flex;flex-direction: column;align-items: center;width: 100%;height: 100%;">
<view style="margin-top: 176rpx;width: 590rpx;border-radius: 10px;height: 748rpx;display: flex;flex-direction: column;
background: linear-gradient(180deg, #ED5B3C -5%, rgba(242, 118, 91, 0.27) 53%, rgba(232, 86, 54, 0) 83%), #FFFFFF;
position: relative;">
<image src="/static/n-pc/show-word.png" style="width: 308rpx;height: 100rpx;margin-left: 40rpx;margin-top: 40rpx;"></image>
<text class="p-menu" style="font-family: SourceHanSans; color: #FFFFFF; font-weight: 400; font-size: 28rpx; margin-left: 40rpx;margin-top: 10rpx;">合作联系19308074417</text>
<image src="/static/n-pc/kt-icon.png" style="width: 368rpx;height: 500rpx;
position: absolute;top: -246.96rpx ;right: -60rpx;"></image>
<view style="position: absolute;top: 198rpx;left: 40rpx;height: 510rpx;width: 510rpx;background: rgba(255, 226, 218, 0.7);border-radius: 10px;
display: flex;flex-direction: column; align-items: center;justify-content: center;">
<!-- <view style="width: 272rpx;height: 269.98rpx;background: #FFFFFF;">
</view> -->
<image src="/static/n-pc/kf_code.png" style="width: 272rpx;height: 269.98rpx;background: #FFFFFF;" ></image>
<text class="p-menu" style="font-family: SourceHanSansBold;color: #614D49; font-size: 28rpx; margin-top: 20rpx;">扫码添加咨询顾问</text>
</view>
</view>
</view>
</view>
</template>
<script setup>
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
const onShareAppMessage = () => {
return {
title: '快来体验一下吧~',
path: '/pages/index/index', // 分享的路径
};
};
const onShareTimeline = () => {
return {
title: '快来体验一下吧~',
query: 'id=11', // 分享路径的参数
};
};
</script>
<style scoped>
.content {
width: 100vw;
height: 100vh;
background-color: #f9f8f8;
display: flex;
flex-direction: column;
font-family: SourceHanSans;
background-image: url('https://miniapp.yuxingu.com.cn/yxg-mp/pic/bg-all.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
</style>
+178
View File
@@ -0,0 +1,178 @@
<template>
<view class="content">
<myNav title="编辑资料" bgColor="#fff" titleColor="#614D49" :backIcon="true" :backHome="false" :flex="false"></myNav>
<view style="display: flex;flex-direction: column;align-items: center;padding: 40rpx;box-sizing: border-box;width: 100%;">
<view style="display: flex;justify-content: space-between;width: 100%;flex-direction: column;padding:58rpx 40rpx 80rpx 40rpx;
border-radius: 10rpx; box-sizing: border-box;background-color: #fff;">
<view style="display: flex;align-items: center;justify-content: space-between;">
<text class="p-title">头像</text>
<view style="display: flex;align-items: center;">
<button type="default" open-type="chooseAvatar"
style="width: 100%;background-color: #fff;text-align: right;border: none;margin-right: 0;padding-right: 10rpx;height: 95rpx;"
@chooseavatar="chooseavatar" plain>
<image v-if="showObj.avatarUrl" :src="showObj.avatarUrl" style="width: 80rpx;height: 80rpx;border-radius: 80rpx;"></image>
<image v-else src="/static/n-pc/head.png" style="width: 80rpx;height: 80rpx;"></image>
</button>
<image src="/static/n-pc/p-left.png" style="width: 12rpx;height: 22rpx;margin-left: 22rpx;"></image>
</view>
</view>
<view style="display: flex;align-items: center;justify-content: space-between;margin-top: 40rpx;">
<text class="p-title">昵称</text>
<view style="display: flex;align-items: center;">
<!-- <text class="p-name">微信用户</text> -->
<input type="nickname" style="width: 100%;background-color: #fff;text-align: right;border: none;padding-right: 10rpx;
font-family: 'SourceHanSans';font-size: 28rpx;color: rgba(0, 0, 0, 0.7);" v-model="showObj.nickName"
placeholder-class="user-input-placeholder" @change="getNickname"></input>
<image src="/static/n-pc/p-left.png" style="width: 12rpx;height: 22rpx;margin-left: 22rpx;"></image>
</view>
</view>
</view>
<view style="display: flex;justify-content:center;width: 90%;flex-direction: column;height:96rpx;align-items: center;margin-top: 100rpx;
border-radius: 2002rpx; box-sizing: border-box;background: linear-gradient(180deg, #E84B2A 0%, #FF846A 100%);" @click="saveUserinfo">
<text class="btn-text">保存</text>
</view>
</view>
</view>
</template>
<script setup>
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
const showObj=ref({
avatarUrl: null,
nickName: null
})
onLoad((option) => {
const userinfo = uni.getStorageSync('userinfo')
if(userinfo){
showObj.value.avatarUrl= userinfo.avatarUrl
showObj.value.nickName = userinfo.nickName
if(!showObj.value.nickName){
showObj.value.nickName = "微信用户"
}
}else{
getUserInfo()
}
})
const getUserInfo = () => {
dohttp.get(urls.getSelfInfo).then((result) => {
const userinfo = {
avatarUrl: result.avatarUrl,
nickName: result.nickName
}
uni.setStorageSync('userinfo', userinfo)
showObj.value.avatarUrl= result.avatarUrl
showObj.value.nickName = result.nickName
if(!showObj.value.nickName){
showObj.value.nickName = "微信用户"
}
})
}
const chooseavatar = (result) => {
console.log("chooseavatarchooseavatar",result,dohttp.baseUrl + urls.upload)
if (result.detail.avatarUrl) {
uni.uploadFile({
url: dohttp.baseUrl + urls.upload,
filePath: result.detail.avatarUrl,
name: "file",
success: (res) => {
if (res.statusCode == 200) {
let data = JSON.parse(res.data)
showObj.value.avatarUrl = data.data
}
},
})
}
}
const getNickname = (event) => {
if (event.detail.value) {
showObj.value.nickName = event.detail.value
}
}
const saveUserinfo = ()=>{
if (!showObj.value.avatarUrl) {
uni.showToast({
title: '请上传头像',
duration: 2000,
icon: "error"
});
return
}
if (!showObj.value.nickName) {
uni.showToast({
title: '请输入昵称',
duration: 2000,
icon: "error"
});
return
}
const params = {
nickName:showObj.value.nickName,
avatarUrl:showObj.value.avatarUrl
}
uni.setStorageSync('userinfo', showObj.value)
dohttp.post(urls.updateUserInfo,params).then((result) => {
uni.showToast({
title: '更新成功',
duration: 2000,
icon: "success",
success: () => {
setTimeout(() => {
uni.navigateBack({
delta: 1
});
}, 2000);
}
});
})
// uni.reLaunch({
// url:"/pages/index/index"
// })
}
</script>
<style scoped>
.content {
width: 100vw;
height: 100vh;
background-color: #f9f8f8;
display: flex;
flex-direction: column;
font-family: SourceHanSans;
background-image: url('https://miniapp.yuxingu.com.cn/yxg-mp/pic/bg-all.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.p-title{
font-size: 28rpx;
font-family: SourceHanSansBold;
color: #614D49;
}
.p-name{
font-size: 28rpx;
color: #9B918C;
}
.btn-text{
font-size: 36rpx;
font-family: SourceHanSansBold;
color: #FFFFFF;
}
</style>
+92
View File
@@ -0,0 +1,92 @@
<template>
<view class="content">
<myNav title="意见反馈" bgColor="#fff" titleColor="#614D49" :backIcon="true" :backHome="false" :flex="false"
style="width: 100%;"></myNav>
<view style="margin-top: 40rpx;width: 670rpx;background-color: #fff;border-radius: 10rpx;padding: 20rpx;">
<textarea placeholder="请输入您的宝贵意见、优化建议等,可输入160字" :maxlength="160" style="width: 100%;height: 640rpx;"
v-model="text" />
</view>
<view @click="save" class="btn" style="margin-top: 80rpx">
<text class="btn-text">提交</text>
</view>
</view>
</template>
<script setup>
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
const text = ref()
const save = async() => {
if (text.value) {
const result = await getFlag()
if(result){
let params = {
contentText: text.value
}
dohttp.post(urls.userFeedback, params).then((result) => {
uni.showToast({
title: '提交成功',
duration: 1500
});
})
}else{
uni.showToast({
title: '提交太频繁啦,请稍后再试',
icon:'none',
duration: 1500
});
}
}else{
uni.showToast({
title: '请输入意见反馈',
icon:'none',
duration: 1500
});
}
}
const getFlag = () => {
return dohttp.post(urls.feedbackFlag)
}
</script>
<style scoped>
.content {
width: 100vw;
height: 100vh;
background-color: #f9f8f8;
display: flex;
flex-direction: column;
align-items: center;
font-family: SourceHanSans;
background-image: url('https://miniapp.yuxingu.com.cn/yxg-mp/pic/bg-all.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.btn {
width: 550rpx;
height: 96rpx;
border-radius: 2002rpx;
/* 自动布局 */
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background: linear-gradient(180deg, #E84B2A 0%, #FF846A 100%);
}
.btn-text {
font-size: 36rpx;
font-family: SourceHanSansBold;
color: #FFFFFF;
}
</style>
+68
View File
@@ -0,0 +1,68 @@
<template>
<view class="content">
<myNav title="活动详情" bgColor="#fff" titleColor="#614D49" :backIcon="true" :backHome="false" :flex="false">
</myNav>
<view style="width: 100%;height: 100%;display: flex;flex-direction: column;align-items: center;overflow-y: auto;padding-bottom: 40rpx;">
<view style="margin: 40rpx;display: flex;width: 670rpx;flex-direction: column;align-items: center;background-color: #fff;box-sizing: border-box;
border-radius: 10rpx;padding: 40rpx;">
<text class="title">{{detail.title}}</text>
<rich-text style="margin-top: 40rpx; max-width: 630rpx; overflow-x: hidden;" :nodes="detail.content"></rich-text>
</view>
</view>
</view>
</template>
<script setup>
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
const detail=ref()
onLoad((option) => {
if (option && option.id) {
dohttp.get(urls.newDetailUrl + "?id=" + option.id).then((result) => {
detail.value = result
})
}
})
const onShareAppMessage = () => {
return {
title: '快来体验一下吧~',
path: '/pages/index/index', // 分享的路径
};
};
const onShareTimeline = () => {
return {
title: '快来体验一下吧~',
query: 'id=91', // 分享路径的参数
};
};
</script>
<style scoped>
.content {
width: 100vw;
height: 100vh;
background-color: #f9f8f8;
display: flex;
flex-direction: column;
font-family: SourceHanSans;
background-image: url('https://miniapp.yuxingu.com.cn/yxg-mp/pic/bg-all.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
font-family: SourceHanSans;
}
.title{
font-size: 36rpx;
font-family: SourceHanSansBold;
}
</style>
+68
View File
@@ -0,0 +1,68 @@
<template>
<view class="content">
<myNav title="疗愈详情" bgColor="#fff" titleColor="#614D49" :backIcon="true" :backHome="false" :flex="false">
</myNav>
<view style="width: 100%;height: 100%;display: flex;flex-direction: column;align-items: center;overflow-y: auto;padding-bottom: 40rpx;">
<view style="margin: 40rpx;display: flex;width: 670rpx;flex-direction: column;align-items: center;background-color: #fff;box-sizing: border-box;
border-radius: 10rpx;padding: 40rpx;">
<text class="title">{{detail.title}}</text>
<rich-text style="margin-top: 40rpx; max-width: 630rpx; overflow-x: hidden;" :nodes="detail.content"></rich-text>
</view>
</view>
</view>
</template>
<script setup>
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
const detail =ref()
onLoad((option) => {
if (option && option.id) {
dohttp.get(urls.newDetailUrl + "?id=" + option.id).then((result) => {
detail.value = result
})
}
})
const onShareAppMessage = () => {
return {
title: '快来体验一下吧~',
path: '/pages/index/index', // 分享的路径
};
};
const onShareTimeline = () => {
return {
title: '快来体验一下吧~',
query: 'id=101', // 分享路径的参数
};
};
</script>
<style scoped>
.content {
width: 100vw;
height: 100vh;
background-color: #f9f8f8;
display: flex;
flex-direction: column;
font-family: SourceHanSans;
background-image: url('https://miniapp.yuxingu.com.cn/yxg-mp/pic/bg-all.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
font-family: SourceHanSans;
}
.title{
font-size: 36rpx;
font-family: SourceHanSansBold;
}
</style>
+204
View File
@@ -0,0 +1,204 @@
<template>
<view class="content">
<view class="banner"></view>
<view class="page">
<myNav title="活动中心" bgColor="nonoe" titleColor="#614D49" :backIcon="true" :backHome="false" :flex="false">
</myNav>
<scroll-view :scroll-y="enableScroll" @scrolltolower="scrolltolower" class="scroll-style"
:style="{ height: `${showHight}rpx` }">
<view ref="contentRef" id="contentContainer" style="display:flex;align-items:center;flex-direction:column;margin-top: 40rpx">
<view v-for="(item,index) in newActiveList" :key="index"
style="width: 670rpx;height: 300rpx;border-radius: 10rpx; background-color: #fff;margin-top: 20rpx;display: flex;flex-direction: column; align-items: flex-start;justify-content: flex-start;">
<view style="width: 670rpx;display: flex;flex-direction: column; align-items: flex-start;justify-content:center;" @click="toActiveDetail(item)">
<image :src="item.showImage" style="width: 670rpx;height: 220rpx;border-top-left-radius: 10rpx;border-top-right-radius: 10rpx;"></image>
<text style="color: #614D49;
margin-left: 10rpx;
margin-top: 14rpx;
width: 650rpx;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
font-family: SourceHanSansBold;ont-variation-settings: 'opsz' auto;
font-size: 28rpx;
line-height: normal;
letter-spacing: 0px;">
{{item.title}}
</text>
</view>
</view>
<view v-if="newActiveList.length==0" style="margin-top: 50%;">
<text style="color: #614D49;
font-family: SourceHanSansBold;ont-variation-settings: 'opsz' auto;
font-size: 28rpx;
line-height: normal;
letter-spacing: 0px;">
暂无活动内容
</text>
</view>
</view>
</scroll-view>
</view>
</view>
</template>
<script setup>
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
const newActiveList = ref([])
onMounted(() => {
getPsychicTest()
})
const getPsychicTest = () => {
const param = ref({
type: 2,
pageNo: 1,
pageSize: 10
})
dohttp.get(urls.newPageUrl, param.value).then((result) => {
newActiveList.value = result.list
// 确保图片加载完成
nextTick(() => {
setTimeout(() => {
checkContentHeight()
// 添加重试机制
if (!enableScroll.value) setTimeout(checkContentHeight, 500)
}, 300)
})
})
}
const toActiveDetail = (item) => {
dohttp.navigateTo("/pages/healing-detail/active-detail?id=" + item.id)
}
// 新增代码
import {
ref,
onMounted,
nextTick,
getCurrentInstance
} from 'vue'
const showHight = ref(0)
const instance = getCurrentInstance()
const enableScroll = ref(false) // 新增动态滚动控制
onLoad(() => {
const systemInfo = uni.getSystemInfoSync()
// 更精准的高度计算
showHight.value = (systemInfo.windowHeight * (750 / systemInfo.screenWidth)) - 200
})
// 新增高度检查方法
const checkContentHeight = () => {
const query = uni.createSelectorQuery().in(instance.proxy)
query.select('#contentContainer').boundingClientRect(rect => {
if (rect) {
const systemInfo = uni.getSystemInfoSync()
// 转换为rpx比较
// 计算容器实际像素高度
const containerHeightPx = (showHight.value * systemInfo.screenWidth) / 750
const threshold = 5 // 容错阈值
enableScroll.value = rect.height > (containerHeightPx + threshold)
console.log('[Layout Debug]', {
contentHeight: rect.height,
containerPx: containerHeightPx,
containerRpx: showHight.value,
shouldScroll: enableScroll.value
})
}
}).exec()
}
const onShareAppMessage = () => {
return {
title: '快来体验一下吧~',
path: '/pages/index/index', // 分享的路径
};
};
const onShareTimeline = () => {
return {
title: '快来体验一下吧~',
query: 'id=9', // 分享路径的参数
};
};
// 初始加载检查
onMounted(() => {
nextTick(checkContentHeight)
})
</script>
<style scoped>
.content {
width: 100vw;
height: 100vh;
background-image: url('https://miniapp.yuxingu.com.cn/yxg-mp/pic/test-list-bg.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
display: flex;
flex-direction: column;
position: relative;
}
.page {
position: absolute;
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
}
.banner {
background-image: url('https://miniapp.yuxingu.com.cn/yxg-mp/pic/botton.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
width: 750rpx;
height: 660rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: absolute;
z-index: 0;
}
/* 修改 #contentContainer 样式 */
#contentContainer {
width: 100%;
min-height: 100%;
/* 新增关键属性 */
flex-shrink: 0;
/* 禁止收缩 */
overflow: visible;
/* 确保子元素不被裁剪 */
}
.scroll-style {
box-sizing: border-box;
padding: 0 !important;
/* 清除可能的内边距 */
}
</style>
+201
View File
@@ -0,0 +1,201 @@
<template>
<view class="content">
<view class="banner"></view>
<view class="page">
<myNav title="艺术疗愈" bgColor="nonoe" titleColor="#614D49" :backIcon="true" :backHome="false" :flex="false">
</myNav>
<scroll-view :scroll-y="enableScroll" @scrolltolower="scrolltolower" class="scroll-style"
:style="{ height: `${showHight}rpx` }">
<view ref="contentRef" id="contentContainer" style="display:flex;align-items:center; flex-direction:column;margin-top: 40rpx">
<view v-for="(item,index) in newHealingList" :key="index"
style="width: 670rpx;height: 196rpx;background-color: #fff;margin-top: 14rpx;display: flex;flex-direction: column; align-items: center;justify-content: center;border-radius: 10rpx;">
<view style="width: 630rpx;display: flex;flex-direction: row; align-items: center;justify-content:space-between;" @click="toHealingDetail(item)">
<text style="color: #614D49;
width: 350rpx;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
font-family: SourceHanSansBold;ont-variation-settings: 'opsz' auto;
font-size: 28rpx;
line-height: normal;
letter-spacing: 0px;">
{{item.title}}
</text>
<image :src="item.showImage" style="width: 200rpx;height: 156rpx;border-radius: 10rpx;"></image>
</view>
</view>
<view v-if="newHealingList.length==0" style="">
<text style="color: #614D49;
font-family: SourceHanSansBold;ont-variation-settings: 'opsz' auto;
font-size: 28rpx;
line-height: normal;
letter-spacing: 0px;">
暂无疗愈内容
</text>
</view>
</view>
</scroll-view>
</view>
</view>
</template>
<script setup>
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
const newHealingList = ref([])
onMounted(() => {
getPsychicTest()
})
const getPsychicTest = () => {
const param = ref({
type: 1,
pageNo: 1,
pageSize: 10
})
dohttp.get(urls.newPageUrl, param.value).then((result) => {
newHealingList.value = result.list
// 确保图片加载完成
nextTick(() => {
setTimeout(() => {
checkContentHeight()
// 添加重试机制
if (!enableScroll.value) setTimeout(checkContentHeight, 500)
}, 300)
})
})
}
const toHealingDetail = (item) => {
dohttp.navigateTo("/pages/healing-detail/healing-detail?id=" + item.id)
}
// 新增代码
import {
ref,
onMounted,
nextTick,
getCurrentInstance
} from 'vue'
const showHight = ref(0)
const instance = getCurrentInstance()
const enableScroll = ref(false) // 新增动态滚动控制
onLoad(() => {
const systemInfo = uni.getSystemInfoSync()
// 更精准的高度计算
showHight.value = (systemInfo.windowHeight * (750 / systemInfo.screenWidth)) - 200
})
// 新增高度检查方法
const checkContentHeight = () => {
const query = uni.createSelectorQuery().in(instance.proxy)
query.select('#contentContainer').boundingClientRect(rect => {
if (rect) {
const systemInfo = uni.getSystemInfoSync()
// 转换为rpx比较
// 计算容器实际像素高度
const containerHeightPx = (showHight.value * systemInfo.screenWidth) / 750
const threshold = 5 // 容错阈值
enableScroll.value = rect.height > (containerHeightPx + threshold)
console.log('[Layout Debug]', {
contentHeight: rect.height,
containerPx: containerHeightPx,
containerRpx: showHight.value,
shouldScroll: enableScroll.value
})
}
}).exec()
}
const onShareAppMessage = () => {
return {
title: '快来体验一下吧~',
path: '/pages/index/index', // 分享的路径
};
};
const onShareTimeline = () => {
return {
title: '快来体验一下吧~',
query: 'id=10', // 分享路径的参数
};
};
// 初始加载检查
onMounted(() => {
nextTick(checkContentHeight)
})
</script>
<style scoped>
.content {
width: 100vw;
height: 100vh;
background-image: url('https://miniapp.yuxingu.com.cn/yxg-mp/pic/test-list-bg.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
display: flex;
flex-direction: column;
position: relative;
}
.page {
position: absolute;
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
}
.banner {
background-image: url('https://miniapp.yuxingu.com.cn/yxg-mp/pic/botton.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
width: 750rpx;
height: 660rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: absolute;
z-index: 0;
}
/* 修改 #contentContainer 样式 */
#contentContainer {
width: 100%;
min-height: 100%;
/* 新增关键属性 */
flex-shrink: 0;
/* 禁止收缩 */
overflow: visible;
/* 确保子元素不被裁剪 */
}
.scroll-style {
box-sizing: border-box;
padding: 0 !important;
/* 清除可能的内边距 */
}
</style>
+789
View File
@@ -0,0 +1,789 @@
<template>
<view class="content">
<view class="banner">
<view style="width: 750rpx;margin-top: 18px;"></view>
<myNav title="愈心谷" bgColor="nonoe" titleColor="#D1502B" :isJcenter="true" :backIcon="false" :backHome="false"
:flex="false"></myNav>
<view style="width: 670rpx;height: 296rpx;margin-top: 20px;">
<uni-swiper-dot :info="banners" mode="default" :current="current" :dots-styles="dotsStyles">
<swiper class="swiper" @change="change" next-margin="-90rpx" style="width: 670rpx;height: 296rpx;">
<swiper-item v-for="(item,index) in banners" :key="index">
<view class="swiper-item uni-bg-red" style="width: 670rpx;height: 256rpx;">
<image :src="item.bannerImage" mode="widthFix"
style="width: 670rpx;border-radius: 10rpx;"
@click="showBanner(item)">
</image>
</view>
</swiper-item>
</swiper>
</uni-swiper-dot>
</view>
<view
style="width: 670rpx;display: flex;justify-content: space-between;align-items: center;margin-top: 20rpx;">
<!-- 左边部分 -->
<view style="width: 324rpx;height: 168rpx;border-radius: 10rpx;
background: linear-gradient(180deg, #FFE6DF 2%, #FCF3EA 100%);
box-sizing: border-box;
display: flex;
" @click="toTestList">
<view style="display: flex;flex-direction: column;margin-top: 26rpx;">
<text style="margin-left: 26rpx;color: #614D49;
font-family: SourceHanSansBold;font-variation-settings: 'opsz' auto;
font-size: 30rpx;
line-height: normal;
letter-spacing: 0px;">
心理测评
</text>
<text style="margin-left: 26rpx;color: #B88973;
font-family: SourceHanSans;ont-variation-settings: 'opsz' auto;
font-size: 24rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0px;">
探寻自我
</text>
</view>
<image src="/static/n-main/left.png"
style="margin-top:50rpx;width: 90rpx;margin-left: 70rpx;height: 90rpx;"></image>
</view>
<!-- 右边部分 -->
<view style="width: 324rpx;height: 168rpx;border-radius: 10rpx;
background: linear-gradient(180deg, #FFE6DF 2%, #FCF3EA 100%);
box-sizing: border-box;
display: flex;
" @click="toZxList">
<view style="display: flex;flex-direction: column;margin-top: 26rpx;">
<text style="margin-left: 26rpx;color: #614D49;
font-family: SourceHanSansBold;font-variation-settings: 'opsz' auto;
font-size: 30rpx;
line-height: normal;
letter-spacing: 0px;">
心理咨询
</text>
<text style="margin-left: 26rpx;color: #B88973;
font-family: SourceHanSans;ont-variation-settings: 'opsz' auto;
font-size: 24rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0px;">
严选咨询师
</text>
</view>
<image src="/static/n-main/right.png"
style="margin-top:58rpx;width: 82rpx;margin-left: 70rpx;height: 82rpx;"></image>
</view>
</view>
</view>
<view
style="width: 750rpx;border-radius: 32rpx 32rpx 0rpx 0rpx;margin-top: 60rpx;
opacity: 1;<!-- background: linear-gradient(270deg, rgba(255, 255, 255, 0) 0%, #FFF4C7 100%); -->display: flex;flex-direction: column;">
<view style="display: flex;margin-top: 16rpx;margin-left: 40rpx; align-items: center;">
<text style="margin-left: 8rpx;color: #614D49;
font-family: SourceHanSansBold;ont-variation-settings: 'opsz' auto;
font-size: 32rpx;
line-height: normal;
letter-spacing: 0px;">
艺术疗愈
</text>
<view style="display: flex;margin-left: 442rpx;align-items: center;" @click="toHealingView">
<text style="color: #9B918C;
font-family: SourceHanSans;ont-variation-settings: 'opsz' auto;
font-size: 24rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0px;">
更多
</text>
<image src="/static/n-main/to-right.png" style="width: 12rpx;height: 20rpx; margin-left: 10rpx;"></image>
</view>
</view>
</view>
<view style="width: 750rpx;display: flex;flex-direction: column;align-items: center;
display: flex; border-radius: 32rpx;">
<view style="width: 670rpx;margin-top: 6rpx;display: flex;align-items: center;justify-content: space-between;">
</view>
<view v-for="(item,index) in newHealingList" :key="index"
style="width: 750rpx;height: 196rpx;background-color: #fff;margin-top: 14rpx;display: flex;flex-direction: column; align-items: center;justify-content: center;">
<view style="width: 670rpx;display: flex;flex-direction: row; align-items: center;justify-content:space-between;" @click="toHealingDetail(item)">
<text style="color: #614D49;
width: 350rpx;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
font-family: SourceHanSansBold;ont-variation-settings: 'opsz' auto;
font-size: 28rpx;
line-height: normal;
letter-spacing: 0px;">
{{item.title}}
</text>
<image :src="item.showImage" style="width: 200rpx;height: 156rpx;border-radius: 10rpx;"></image>
</view>
</view>
<view v-if="newHealingList.length==0" >
<text style="color: #9B918C;
font-family: SourceHanSansBold;ont-variation-settings: 'opsz' auto;
font-size: 28rpx;
line-height: normal;
letter-spacing: 0px;">暂无疗愈内容</text>
</view>
</view>
<view
style="width: 750rpx;border-radius: 32rpx 32rpx 0rpx 0rpx;margin-top: 20rpx;
opacity: 1;<!-- background: linear-gradient(270deg, rgba(255, 255, 255, 0) 0%, #FFF4C7 100%); -->display: flex;flex-direction: column;">
<view style="display: flex;margin-top: 16rpx;margin-left: 40rpx; align-items: center;">
<text style="margin-left: 8rpx;color: #614D49;
font-family: SourceHanSansBold;ont-variation-settings: 'opsz' auto;
font-size: 32rpx;
line-height: normal;
letter-spacing: 0px;">
活动中心
</text>
<view style="display: flex;margin-left: 442rpx;align-items: center;" @click="toActiveView">
<text style="color: #9B918C;
font-family: SourceHanSans;ont-variation-settings: 'opsz' auto;
font-size: 24rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0px;">
更多
</text>
<image src="/static/n-main/to-right.png" style="width: 12rpx;height: 20rpx; margin-left: 10rpx;"></image>
</view>
</view>
</view>
<view style="width: 750rpx;display: flex;flex-direction: column;align-items: center;
display: flex;background-color: transparent;border-radius: 32rpx;">
<view style="width: 670rpx;margin-top: 10rpx;display: flex;align-items: center;justify-content: space-between;">
</view>
<view v-for="(item,index) in newActivityList" :key="index"
style="width: 670rpx; height: 300rpx;background-color: #fff;border-radius: 10rpx; margin-top: 14rpx;display: flex;flex-direction: column; align-items: flex-start;justify-content: flex-start;">
<image :src="item.showImage" style="width: 670rpx;height: 220rpx;border-top-right-radius: 10rpx;border-top-left-radius: 10rpx;" @click="toActiveDetail(item)"></image>
<view style="display: flex;flex-direction: column;margin-left: 20rpx;">
<text style="color: #614D49;
width: 670rpx;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
font-family: SourceHanSansBold;ont-variation-settings: 'opsz' auto;
margin-top: 20rpx;
font-size: 28rpx;
font-weight: 400;
line-height: normal;
letter-spacing: 0px;">
{{item.title}}
</text>
</view>
</view>
<view v-if="newActivityList.length==0" >
<text style="color: #9B918C;
font-family: SourceHanSansBold;ont-variation-settings: 'opsz' auto;
font-size: 28rpx;
line-height: normal;
letter-spacing: 0px;">暂无活动内容</text>
</view>
</view>
<view
style="width: 750rpx;border-radius: 32rpx 32rpx 0rpx 0rpx;margin-top: 20rpx;
opacity: 1;<!-- background: linear-gradient(270deg, rgba(255, 255, 255, 0) 0%, #FFF4C7 100%); -->display: flex;flex-direction: column;">
<view style="display: flex;margin-top: 16rpx;margin-left: 40rpx;align-items: center;">
<text style="margin-left: 8rpx;color: #614D49;
font-family: SourceHanSansBold;ont-variation-settings: 'opsz' auto;
font-size: 32rpx;
line-height: normal;
letter-spacing: 0px;">
经典必测
</text>
<view style="display: flex;margin-left: 442rpx;align-items: center;" @click="toTestList">
<text style="color: #9B918C;
font-family: SourceHanSans;ont-variation-settings: 'opsz' auto;
font-size: 24rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0px;">
更多
</text>
<image src="/static/n-main/to-right.png" style="width: 12rpx;height: 20rpx; margin-left: 10rpx;"></image>
</view>
</view>
</view>
<view style="width: 670rpx;margin-left: 40rpx; display: flex;flex-direction: column;align-items: center;
display: flex;background-color: transparent;border-radius: 32rpx;">
<view style="width: 670rpx;margin-top: 6rpx;display: flex;align-items: center;justify-content: space-between;">
</view>
<!-- 个人测评 -->
<view v-for="(item,index) in testList" :key="index"
style="width: 650rpx;background-color: #fff;border-radius: 10rpx; padding: 20rpx; margin-top: 14rpx;display: flex;align-items: center;justify-content: space-between;">
<view style="display: flex;">
<image :src="item.testPic" style="width: 140rpx;height: 140rpx;border-radius: 10rpx;"></image>
<view style="display: flex;flex-direction: column;margin-left: 20rpx;">
<text style="color: #614D49;
font-family: SourceHanSansBold;ont-variation-settings: 'opsz' auto;
font-size: 28rpx;
line-height: normal;
letter-spacing: 0px;">
{{item.testName}}
</text>
<view style="margin-top: 8rpx;display: flex;align-items: center;">
<view style="width: fit-content;margin-left: 10rpx;
border-radius: 32rpx;
display: flex;
text-align: center;
justify-content: center;
padding-top: 4rpx;
padding-bottom: 4rpx;
padding-left: 10rpx;
padding-right: 10rpx;
border: 1px solid #EA8D7A;">
<text style="color: #F37155;
font-family: SourceHanSans;ont-variation-settings: 'opsz' auto;
font-size: 20rpx;
font-weight: normal;
letter-spacing: 0px;">
{{item.showNum}}人已测
</text>
</view>
</view>
<text style="color: #9B918C;margin-top: 26rpx;
font-family: SourceHanSans;ont-variation-settings: 'opsz' auto;
font-size: 20rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0px;">
{{item.subTitle}}
</text>
</view>
</view>
<view @click="goTest(item)" style="width:fit-content;
height: fit-content;
border-radius: 2002rpx;
opacity: 1;
display: flex;
padding: 8rpx 40rpx;justify-content: center;align-items: center;
background: linear-gradient(180deg, #E84B2A 0%, #FF846A 100%);">
<text style="color: #FFFFFF;
font-family: SourceHanSansBold;ont-variation-settings: 'opsz' auto;
font-size: 28rpx;
line-height: normal;
letter-spacing: 0px;">
测评
</text>
</view>
</view>
<view v-if="testList.length==0" >
<text style="color: #9B918C;
font-family: SourceHanSansBold;ont-variation-settings: 'opsz' auto;
font-size: 28rpx;
line-height: normal;
letter-spacing: 0px;">
暂无测评信息
</text>
</view>
</view>
<view
style="width: 750rpx;border-radius: 32rpx 32rpx 0rpx 0rpx;margin-top: 20rpx;
opacity: 1;<!-- background: linear-gradient(270deg, rgba(255, 255, 255, 0) 0%, #FFF4C7 100%); -->display: flex;flex-direction: column;">
<view style="display: flex;margin-top: 16rpx;margin-left: 40rpx; align-items: center;">
<text style="margin-left: 8rpx;color: #614D49;
font-family: SourceHanSansBold;ont-variation-settings: 'opsz' auto;
font-size: 32rpx;
line-height: normal;
letter-spacing: 0px;">
咨询推荐
</text>
<view style="display: flex;margin-left: 442rpx;align-items: center;" @click="toZxList">
<text style="color: #9B918C;
font-family: SourceHanSans;ont-variation-settings: 'opsz' auto;
font-size: 24rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0px;">
更多
</text>
<image src="/static/n-main/to-right.png" style="width: 12rpx;height: 20rpx; margin-left: 10rpx;"></image>
</view>
</view>
</view>
<view style="width: 750rpx;display: flex;flex-direction: column;align-items: center;
display: flex;background-color: transparent;
padding-bottom: 15rpx;border-radius: 10rpx;">
<view style="width: 670rpx;margin-top: 6rpx;display: flex;align-items: center;justify-content: space-between;">
</view>
<view class="show-card" v-for="(item,index) in consultList" :key="index" @click="toDetail(item)">
<view style="position: relative;height: 204rpx;">
<image :src="item.avatar" style="width: 156rpx;height: 204rpx;border-radius: 10rpx;"></image>
</view>
<view style="position: relative; display: flex;flex-direction: column;margin-left: 20rpx;width: 452rpx;
justify-content: space-between">
<view style="display: flex;flex-direction: column; gap: 4rpx;">
<text class="show-name">
{{item.name}}
</text>
<view style="display: flex;height: 28rpx;" v-if="item.tags&&item.tags.length==1">
<view class="tag">
<text class="tag-text">{{item.tags[0]}}</text>
</view>
</view>
<view style="display: flex;height: 28rpx;" v-if="item.tags&&item.tags.length==2">
<view class="tag">
<text class="tag-text">{{item.tags[0]}}</text>
</view>
<view class="tag" style="margin-left:20rpx;">
<text class="tag-text">{{item.tags[1]}}</text>
</view>
</view>
<view style="display: flex;height: 28rpx;" v-if="item.tags&&item.tags.length==3">
<view class="tag">
<text class="tag-text">{{item.tags[0]}}</text>
</view>
<view class="tag" style="margin-left:20rpx;">
<text class="tag-text">{{item.tags[1]}}</text>
</view>
<view class="tag" style="margin-left:20rpx;">
<text class="tag-text">{{item.tags[2]}}</text>
</view>
</view>
<view style="display: flex;height: 28rpx;" v-if="item.tags&&item.tags.length>=4">
<view class="tag">
<text class="tag-text">{{item.tags[0]}}</text>
</view>
<view class="tag" style="margin-left:20rpx;">
<text class="tag-text">{{item.tags[1]}}</text>
</view>
<view class="tag" style="margin-left:20rpx;">
<text class="tag-text">{{item.tags[2]}}</text>
</view>
<view class="tag" style="margin-left:20rpx;">
<text class="tag-text">{{item.tags[3]}}</text>
</view>
</view>
<text class="show-introduce" >
{{item.introduction}}
</text>
<!-- <text class="show-introduce">
擅长:婚姻家庭/情绪管理/个人成长从业15年·咨询经验3300+小小时
</text> -->
</view>
<view style="position: absolute; right: 10rpx; bottom: -10rpx; display: flex;justify-content: flex-end;align-items: baseline;">
<view>
<text class="momey-text">
¥ {{item.price/100}}
</text>
<text class="unit-text">
/
</text>
</view>
</view>
</view>
</view>
<view v-if="consultList.length==0" >
<text style="color: #9B918C;
font-family: SourceHanSansBold;ont-variation-settings: 'opsz' auto;
font-size: 28rpx;
line-height: normal;
letter-spacing: 0px;">
暂无推荐信息
</text>
</view>
</view>
<web-view v-if="showWebView" :src="externalUrl"></web-view>
</view>
</template>
<script setup>
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
const banners = ref([])
const testList = ref([])
const consultList = ref([])
const newHealingList = ref([])
const newActivityList = ref([])
const showWebView = ref(false)
const externalUrl = ref()
const dotsStyles = ref({
backgroundColor: 'rgba(96, 98, 113, 1)',
border: '1px rgba(96, 98, 113, 1) solid',
color: '#fff',
selectedBackgroundColor: 'rgba(231, 86, 55, 1)',
selectedBorder: '1px rgba(231, 86, 55, 1) solid'
})
const current = ref(0)
const change = (e) => {
current.value = e.detail.current
}
const showBanner = (item) => {
if (item.jumpType == 1) {
uni.navigateTo({
"url": "/pages/show-banner/show-banner?url=" + item.clickUrl,
"animationType": "pop-in"
})
} else {
uni.showModal({
title: '跳转异常',
content: '该banner跳转方式不正确,请稍后再试',
showCancel: false,
success: function(res) {
if (res.confirm) {
}
}
})
}
}
const onShareAppMessage = () => {
return {
title: '快来体验一下吧~',
path: '/pages/index/index', // 分享的路径
};
};
const onShareTimeline = () => {
return {
title: '快来体验一下吧~',
query: 'id=1', // 分享路径的参数
};
};
onLoad(() => {
})
onMounted(() => {
getBanner()
getPsychicTest()
getConsult()
getNewsHealingPage()
getNewActivityPage()
})
const getNewsHealingPage = ()=> {
const param = ref({
type: 1,
pageNo: 1,
pageSize: 100,
showMain: 1
})
dohttp.get(urls.newPageUrl, param.value).then((result) => {
newHealingList.value = result.list
})
}
const getNewActivityPage = ()=> {
const param = ref({
type: 2,
pageNo: 1,
pageSize: 100,
showMain: 1
})
dohttp.get(urls.newPageUrl, param.value).then((result) => {
newActivityList.value = result.list
})
}
const toTuTest=()=>{
const externalUrl = 'https://cps.jsbr.org.cn/login.html';
uni.navigateTo({
url: `/pages/webview-page/webview-page?url=${encodeURIComponent(externalUrl)}`
});
}
const toHealingDetail=(item)=>{
dohttp.navigateTo("/pages/healing-detail/healing-detail?id=" + item.id)
}
const toActiveDetail=(item)=>{
dohttp.navigateTo("/pages/healing-detail/active-detail?id=" + item.id)
}
const goTest = (item) => {
dohttp.navigateTo("/pages/test-detail/test-detail?id=" + item.id)
}
const toDetail=(item)=>{
dohttp.navigateTo("/pages/consult-detail/consult-detail?id=" + item.id)
}
const getConsult = ()=> {
const param = ref({
businessScope: "",
pageNo: 1,
pageSize: 100,
isTop: 1
})
dohttp.get(urls.doctorInfopage, param.value).then((result) => {
for (let i = 0; i < result.list.length; i++) {
if (result.list[i].consultationMethod) {
result.list[i].tags = result.list[i].tags.split(",")
}
}
consultList.value = result.list
})
}
const getBanner = () => {
dohttp.post(urls.getBanner).then((result) => {
banners.value = result
})
}
const getPsychicTest = () => {
dohttp.post(urls.getPsychicListTest +'?showMain=1').then((result) => {
console.log("getPsychicTestgetPsychicTestgetPsychicTest", result)
if (result) {
result.forEach((ele) => {
if (ele.totalNum && Number(ele.totalNum) >= 10000) {
ele.showNum = (Number(ele.totalNum) / 10000).toFixed(1) + "W"
} else {
ele.showNum = ele.totalNum
}
})
}
testList.value = result
})
}
const toTestList = () => {
uni.switchTab({
"url": "/pages/test-list/test-list",
"animationType": "pop-in"
})
}
const toActiveView = ()=> {
uni.navigateTo({
"url": "/pages/healing/active-list",
"animationType": "pop-in"
})
}
const toHealingView = ()=> {
uni.navigateTo({
"url": "/pages/healing/healing-list",
"animationType": "pop-in"
})
}
const toZxList = (params) => {
if (params) {
uni.setStorageSync("zxcode", params)
}
uni.switchTab({
"url": "/pages/consult/consult",
"animationType": "pop-in"
})
}
</script>
<style scoped>
.content {
width: 100vw;
background-color: #F9F6F5;
display: flex;
flex-direction: column;
overflow-y: auto;
}
.banner {
background-image: url('https://miniapp.yuxingu.com.cn/yxg-mp/pic/botton.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
width: 750rpx;
height: 660rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.choce-view {
display: flex;
justify-content: center;
margin-top: 20rpx;
}
.choce-view-inner {
display: flex;
justify-content: center;
width: 696rpx;
justify-content: space-between;
}
.choice-inner-left {
width: 340rpx;
height: 190rpx;
background-image: url('https://miniapp.yuxingu.com.cn/yxg-mp/pic/main_left.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
display: flex;
}
.choice-inner-right {
width: 340rpx;
height: 190rpx;
background-image: url('https://miniapp.yuxingu.com.cn/yxg-mp/pic/main_right.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
display: flex;
}
.choice-inner-text {
font-family: SourceHanSansBold;
font-size: 44rpx;
margin-left: 28rpx;
margin-top: 35rpx;
letter-spacing: 2rpx;
}
.bottom-view {
display: flex;
justify-content: center;
width: 100%;
margin-top: 40rpx;
}
.show-card {
margin-top: 14rpx;
width: 670rpx;
height: 244rpx;
border-radius: 10rpx;
background: #FFFFFF;
display: flex;
padding: 20rpx;
box-sizing: border-box;
justify-content: center;
}
.show-name {
/* 标题/标题三加粗 */
/* 样式描述:正文标题 */
font-family: SourceHanSansBold;
font-size: 28rpx;
line-height: normal;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
/* 背景色/浅色背景2 */
color: #614D49;
}
.show-introduce {
font-family: SourceHanSans;
font-size: 20rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
/* 正文色/正文辅助4 */
color: #9B918C;
display: -webkit-box; /* 使用 flex 布局 */
-webkit-box-orient: vertical; /* 垂直排列 */
-webkit-line-clamp: 3; /* 限制显示行数 */
overflow: hidden; /* 超出部分隐藏 */
text-overflow: ellipsis; /* 超出部分显示省略号 */
}
.momey-text {
color: #F37155;
/* 标题/标题二加粗 */
font-family: SourceHanSansBold;
font-size: 36rpx;
font-variation-settings: "opsz" auto;
}
.unit-text {
/* 正文/正文文本小号加粗 */
font-family: SourceHanSans;
font-weight: 700;
font-size: 20rpx;
font-variation-settings: "opsz" auto;
color: #F37155;
}
.tag {
border-radius: 60rpx;
opacity: 1;
/* 自动布局 */
display: flex;
padding: 2rpx 10rpx;
box-sizing: border-box;
border: 2rpx solid #EA8D7A;
justify-content: center;
align-items: center;
}
.tag-text {
/* 样式描述:辅助信息 */
font-family: SourceHanSans;
font-size: 16rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0rpx;
/* 正文色/正文色辅助3 */
color: #F37155;
}
</style>
File diff suppressed because one or more lines are too long
+169
View File
@@ -0,0 +1,169 @@
<template>
<view class="content">
<myNav title="我关注的咨询师" bgColor="#fff" titleColor="#614D49" :backIcon="true" :backHome="false" :flex="false">
</myNav>
<view style="margin: 40rpx;display: flex;flex-direction: column;align-items: center;overflow-y: auto;" v-if="focusList.length>0">
<view style="width: 100%;padding: 40rpx;box-sizing: border-box;background-color: #fff;
display: flex;flex-direction: column;border-radius: 10rpx;margin-top: auto;" >
<text style="font-size: 28rpx;color: #9B918C;">已关注{{focusList.length}}</text>
<view v-for="(item,index) in focusList" :key="index" >
<view style="margin-top: 40rpx;display: flex; justify-content: space-between;">
<image src="/static/n-main/child.png"
style="width: 100rpx;height: 100rpx;border-radius: 10rpx;">
</image>
<view style="display: flex;flex-direction: column; width: 294rpx;">
<view style="display: flex;align-items: baseline;justify-content: flex-start;">
<text style="font-size: 28rpx;font-family: SourceHanSansBold;color: #614D49;">{{item.name}}</text>
<text style="font-size: 20rpx;;color: #614D49;margin-left: 20rpx;">{{item.showServiceNum}}+咨询*从业{{item.workNum}}+</text>
</view>
<view style="display: flex;">
<text class="text-ellipsis"
style="font-size: 20rpx;;color: #9B918C;line-height: normal;letter-spacing: 0px;">{{item.introduction}}</text>
</view>
</view>
<view style="display: flex;flex-direction: column;align-items: center;">
<view style="width: 136rpx;height: 56rpx;border-radius: 2002rpx;display: flex;justify-content: center;align-items: center;
background: linear-gradient(180deg, #FF9079 0%, #F37155 100%);" @click="toConsult(item)">
<text class="btn-text">预约</text>
</view>
<view>
<text class="rmb-text">¥{{advancedFormat(item.price)}}</text><text class="rmb-text-mini">/</text>
</view>
</view>
</view>
<view class="line" v-if="index<focusList.length-1"></view>
</view>
</view>
</view>
<view style="display:flex;align-items:center;flex-direction:column;width: 100%;height: 100%;
display: flex;align-items: center;justify-content: center"
v-if="focusList.length==0">
<text style="font-size: 30rpx;font-family: SourceHanSansBold;color: #EA4E2D">暂无关注信息</text>
</view>
</view>
</template>
<script setup>
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
onLoad((option) => {
if (option.num && option.num > 0) {
toFocusRead()
}
focusAll()
})
const toFocusRead = () => {
dohttp.post(urls.focusToRead).then((result) => {})
}
const focusList = ref([])
const focusAll = () => {
dohttp.post(urls.focusAll).then((result) => {
focusList.value = result
})
}
const advancedFormat = (num) => {
const divided = Number(num) / 100;
// 转换为字符串处理科学计数法(如1e-7)
const str = divided.toLocaleString('en-US', {
maximumFractionDigits: 2,
useGrouping: false
});
return str.replace(/(\.\d*?[1-9])0+$/, '$1').replace(/\.$/, '');
}
const toConsult = (item)=>{
dohttp.navigateTo("/pages/consult-detail/consult-detail?id=" + item.id)
}
const onShareAppMessage = () => {
return {
title: '快来体验一下吧~',
path: '/pages/index/index', // 分享的路径
};
};
const onShareTimeline = () => {
return {
title: '快来体验一下吧~',
query: 'id=7', // 分享路径的参数
};
};
</script>
<style scoped>
.content {
width: 100vw;
height: 100vh;
background-color: #F9F6F5;
display: flex;
flex-direction: column;
font-family: SourceHanSans;
}
.btn-text {
/* 按钮/按钮文本中号加粗 */
font-family: SourceHanSansBold;
font-size: 28rpx;
line-height: normal;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
/* 正文色/正文色 */
color: #FFFFFF;
}
.rmb-text {
font-family: SourceHanSans;
font-size: 24rpx;
font-weight: 700;
line-height: normal;
letter-spacing: 0px;
color: #F37155;
}
.rmb-text-mini {
font-family: SourceHanSans;
font-size: 16rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0px;
color: #F37155;
}
.text-ellipsis {
overflow: hidden;
/* 溢出内容隐藏 */
text-overflow: ellipsis;
/* 显示省略号 */
display: -webkit-box;
/* 使用WebKit弹性盒子模型 */
-webkit-line-clamp: 2;
/* 限制显示行数(此处为2行) */
-webkit-box-orient: vertical;
/* 文本垂直排列 */
}
.line {
width: 100%;
height: 2rpx;
border-radius: 36rpx;
background: #DFD6D3;
margin-top: 30rpx;
}
</style>
+235
View File
@@ -0,0 +1,235 @@
<template>
<view class="content">
<view class="banner"></view>
<view class="page">
<myNav title="我的测评" bgColor="nonoe" titleColor="#614D49" :backIcon="true" :backHome="false" :flex="false">
</myNav>
<scroll-view :scroll-y="enableScroll" v-if="testList.length>0" @scrolltolower="scrolltolower" class="scroll-style" :style="{ height: `${showHight}rpx` }"
>
<view ref="contentRef" id="contentContainer"
style="display: flex;align-items: center;flex-direction: column;margin-top: 30rpx">
<view v-for="(item,index) in testList" :key="index"
style="width: 670rpx;margin-top: 20rpx;display: flex;height: 180rpx;
align-items: center;justify-content: space-between;background:#FFFFFF;border-radius: 10rpx;padding-left: 20rpx;padding-right: 20rpx;">
<view style="display: flex;">
<image :src="item.testPic" style="width: 140rpx;height: 140rpx;border-radius: 10rpx;">
</image>
<view style="display: flex;flex-direction: column;margin-left: 20rpx;">
<text style="color: #303044;
font-family: SourceHanSansBold;ont-variation-settings: 'opsz' auto;
font-size: 28rpx;
line-height: normal;
letter-spacing: 0px;">
{{item.testName}}
</text>
<view style="margin-top: 2rpx;display: flex;align-items: center;">
<rich-text style="color: #606271;
font-family: SourceHanSans;ont-variation-settings: 'opsz' auto;
font-size: 20rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0px;" class="test-desc" :nodes="item.subTitle"></rich-text>
</view>
<text style="color: #EA4E2D;margin-top: 26rpx;
font-family: SourceHanSans;ont-variation-settings: 'opsz' auto;
font-size: 20rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0px;">
测试于{{ item.startTime }}
</text>
</view>
</view>
<view style="width:fit-content;
height: fit-content;
border-radius: 2002rpx;
opacity: 1;
display: flex;
padding: 8rpx 40rpx;justify-content: center;align-items: center;
background: linear-gradient(180deg, #E84B2A 0%, #FF846A 100%);" @click="toTestResult(item)">
<text style="color: #FFFFFF;
font-family: SourceHanSansBold;ont-variation-settings: 'opsz' auto;
font-size: 28rpx;
line-height: normal;
letter-spacing: 0px;">
查看
</text>
</view>
</view>
</view>
</scroll-view>
<view v-if="testList.length==0" style="margin-top: 50%; width: 100%; text-align: center;">
<text style="color: #614D49;
font-family: SourceHanSansBold;ont-variation-settings: 'opsz' auto;
font-size: 28rpx;
line-height: normal;
letter-spacing: 0px;">暂无测评信息</text>
</view>
</view>
</view>
</template>
<script setup>
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
const testList = ref([])
const params = ref({
pageNo: 1,
pageSize: 20
})
onMounted(() => {
testList.value = []
getMyTest()
})
const getMyTest = () => {
dohttp.post(urls.myTest, params.value).then((result) => {
if (result.list) {
testList.value.push(...result.list)
// 数据更新后检查高度
nextTick(() => {
checkContentHeight()
})
}
})
}
const toTestResult = (item) => {
uni.navigateTo({
url: "/pages/test-result/test-result?resultId=" + item.testResultId,
animationType: "pop-in"
})
}
const scrolltolower = () => {
params.value.pageNo += 1
getMyTest()
}
const showHight = ref(0)
onLoad(() => {
const systemInfo = uni.getSystemInfoSync()
// 更精准的高度计算
showHight.value = (systemInfo.windowHeight * (750 / systemInfo.screenWidth)) - 200
})
// 新增代码
import { ref, onMounted, nextTick, getCurrentInstance } from 'vue'
const instance = getCurrentInstance()
const enableScroll = ref(false) // 新增动态滚动控制
// 新增高度检查方法
const checkContentHeight = () => {
const query = uni.createSelectorQuery().in(instance.proxy)
query.select('#contentContainer').boundingClientRect(rect => {
if (rect) {
// 转换为rpx比较
const contentHeightRpx = rect.height * (750 / uni.getSystemInfoSync().screenWidth)
enableScroll.value = contentHeightRpx > showHight.value
console.log('内容高度:', contentHeightRpx, '容器高度:', showHight.value)
}
}).exec()
}
// 初始加载检查
onMounted(() => {
nextTick(checkContentHeight)
})
const onShareAppMessage = () => {
return {
title: '快来体验一下吧~',
path: '/pages/index/index', // 分享的路径
};
};
const onShareTimeline = () => {
return {
title: '快来体验一下吧~',
query: 'id=6', // 分享路径的参数
};
};
</script>
<style scoped>
.content {
width: 100vw;
height: 100vh;
background-image: url('https://miniapp.yuxingu.com.cn/yxg-mp/pic/test-list-bg.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
display: flex;
flex-direction: column;
}
/* 新增关键样式 */
#contentContainer {
width: 100%;
min-height: 100%; /* 确保内容容器撑开 */
}
.page {
position: absolute;
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
}
.banner {
background-image: url('https://miniapp.yuxingu.com.cn/yxg-mp/pic/botton.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
width: 750rpx;
height: 660rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: absolute;
z-index: 0;
}
.test-desc {
font-size: 24rpx;
color: #888;
}
/* .scroll-style {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
} */
.scroll-style {
box-sizing: border-box;
padding: 0 !important; /* 清除可能的内边距 */
}
</style>
+738
View File
@@ -0,0 +1,738 @@
<template>
<view class="content">
<myNav title="订单详情" bgColor="#fff" titleColor="#614D49" :backIcon="true" :backHome="false" :flex="false"></myNav>
<view
style="width: 100%;display: flex;flex-direction: column;align-items: center;overflow-y: auto;padding-bottom: 80rpx;">
<view class="card" style="margin-top: 40rpx;">
<view
style="width: 670rpx;height: 60rpx;border-radius: 10rpx 32rpx 0rpx 0rpx;background: linear-gradient(180deg, #FFE7D9 0%, rgba(255, 255, 255, 0) 98%);">
</view>
<image src="/static/n-zx/order-status-icon.png" style="width: 60rpx;height: 60rpx;align-self: center;"
v-if="orderDetail.status==0">
</image>
<text style="font-size: 36rpx;color:#F37155 ;font-family: SourceHanSansBold;align-self: center;"
v-if="orderDetail.status==0">待支付
</text>
<text style="font-size: 36rpx;color:#F37155 ;font-family: SourceHanSansBold;align-self: center;"
v-if="orderDetail.status== 1 ">待咨询
</text>
<text style="font-size: 36rpx;color:#F37155 ;font-family: SourceHanSansBold;align-self: center;"
v-if="orderDetail.status== 4 ">待确认
</text>
<text style="font-size: 36rpx;color:#F37155 ;font-family: SourceHanSansBold;align-self: center;"
v-if="orderDetail.status== 5 ">已完成
</text>
<text style="font-size: 36rpx;color:#00B637 ;font-family: SourceHanSansBold;align-self: center;"
v-if="orderDetail.status== 6 ">申请退款中
</text>
<text style="font-size: 36rpx;color:#00B637 ;font-family: SourceHanSansBold;align-self: center;"
v-if="orderDetail.status== 7 ">退款中
</text>
<text style="font-size: 36rpx;color:#00B637 ;font-family: SourceHanSansBold;align-self: center;"
v-if="orderDetail.status== 8 ">已退款
</text>
<text style="font-size: 36rpx;color:#00B637 ;font-family: SourceHanSansBold;align-self: center;"
v-if="orderDetail.status== 9 ">交易关闭
</text>
<view style="align-self: center;margin-top: 20rpx;" v-if="orderDetail.status==0">
<text class="order-text" style="color: #186BF9;">
{{ orderDetail.validTime.split('T').join(' ') }}</text>
<text class="order-text">前未支付订单将自动取消</text>
</view>
<view style="align-self: center;margin-top: 20rpx;" v-if="orderDetail.status==1">
<text class="order-text" @click="toConsultAppointment">支付成功等待执行相关详情请查看
<text style="color: #186BF9;">预约须知</text>
</text>
</view>
<view style="align-self: center;margin-top: 20rpx;" v-if="orderDetail.status==4">
<text class="order-text">等待客服确认本次咨询</text>
</view>
<view style="align-self: center;margin-top: 20rpx;" v-if="orderDetail.status==5">
<text class="order-text">订单已完成</text>
</view>
<view style="align-self: center;margin-top: 20rpx;" v-if="orderDetail.status==6">
<text class="order-text">申请退款中请耐心等待</text>
</view>
<view style="align-self: center;margin-top: 20rpx;" v-if="orderDetail.status==7">
<text class="order-text">退款已受理将会在1个工作日内返回到支付账户</text>
</view>
<view style="align-self: center;margin-top: 20rpx;" v-if="orderDetail.status==8">
<text class="order-text">退款金额已成功返回到支付账户</text>
</view>
<view style="align-self: center;margin-top: 20rpx;" v-if="orderDetail.status==9">
<text class="order-text" v-if="orderDetail.cancelFlag == 1">支付超时,已关闭交易</text>
<text class="order-text" v-if="orderDetail.cancelFlag == 2">订单已取消</text>
</view>
<view style="padding-left: 40rpx;padding-right: 40rpx;padding-bottom: 40rpx;
width: 670rpx;box-sizing: border-box;
margin-top: 98rpx; display: flex;flex-direction: column;">
<view class="psychic-detail-row">
<text class="psychic-detail-text">咨询方式</text>
<view style="display: flex; align-items: center;">
<view v-if="orderDetail.consultationMethod == 'video' " style="width: 124rpx;height: 48rpx;border-radius: 80rpx;
box-sizing: border-box;border: 1px solid #F97559;display: flex;justify-content: center;align-items: center;">
<image src="/static/n-zx/video.png" style="width: 25.6rpx;height: 19.2rpx;"></image>
<text style="font-size: 24rpx;color: #F97559;margin-left: 8rpx;">视频</text>
</view>
<view v-if="orderDetail.consultationMethod == 'face_to_face'" style="width: 124rpx;height: 48rpx;border-radius: 80rpx;margin-left: 20rpx;
box-sizing: border-box;border: 1px solid #F97559;display: flex;justify-content: center;align-items: center;">
<image src="/static/n-zx/face-to-face-c.png" style="width: 26rpx;height: 28.66rpx;">
</image>
<text style="font-size: 24rpx;color: #F97559;margin-left: 8rpx;">面对面</text>
</view>
</view>
</view>
<view class="psychic-detail-row">
<text class="psychic-detail-text">咨询时段</text>
<view>
<text class="psychic-detail-show-text" v-if="orderDetail.appointmentDate">
{{ orderDetail.appointmentDate.substring(0, 10) }}({{
getWeekDay(orderDetail.appointmentDate)
}}){{ orderDetail.startTime.substring(0, 5) }}-{{ orderDetail.endTime.substring(0, 5) }}
</text>
<image src="/static/n-zx/right-icon.png" class="right-icon" @click="showChoiceDateTimePop">
</image>
</view>
</view>
<view class="psychic-detail-row" v-if="orderDetail.consultationMethod == 'face_to_face'">
<text class="psychic-detail-text">面询地址</text>
<view style="width: 70%;text-align: right;">
<text class="psychic-detail-show-text">{{ orderDetail.addressDetail }}</text>
</view>
</view>
</view>
</view>
<view class="card" style="margin-top: 20rpx;box-sizing: border-box;" v-if="!showDetailFlag">
<view style="padding-left: 40rpx;padding-right: 40rpx;width: 100%;box-sizing: border-box;">
<view class="psychic-detail-row">
<text class="psychic-detail-text">预约人信息</text>
<view>
<text class="psychic-detail-show-text" v-if="orderDetail.phone">{{ orderDetail.phone }}
</text>
<!-- <text class="psychic-detail-show-text" v-else>去填写</text>-->
<image src="/static/n-zx/right-icon.png" class="right-icon" style="margin-left: 10rpx;"
@click="changeDetailFlag">
</image>
</view>
</view>
</view>
<view class="expand-bottom">
<view @click="changeDetailFlag"
style="display: flex;justify-content: center;flex-direction: column;align-items: center;justify-content: center;">
<text class="expand-text">展开更多</text>
<image src="/static/n-zx/down-icon.png" style="width: 16rpx;height: 11.82rpx;"></image>
</view>
</view>
</view>
<view class="card" style="margin-top: 20rpx;box-sizing: border-box;" v-if="showDetailFlag">
<view
style="padding-left: 40rpx;padding-right: 40rpx;width: 100%;box-sizing: border-box;padding-bottom: 40rpx;">
<view class="psychic-detail-row">
<text class="psychic-detail-text">预约人信息</text>
</view>
<view class="psychic-detail-row">
<text class="psychic-detail-title-text">预约人称呼</text>
<view style="text-align: right;">
<input type="text" class="input-text" disabled :maxlength="10"
v-model="orderDetail.appointmentName" placeholder="请输入预约人称呼" />
</view>
</view>
<view class="psychic-detail-row">
<text class="psychic-detail-title-text">出生年月</text>
<view style="display: flex;justify-content: flex-end; align-items: center;">
<picker mode="date" value="date" :disabled="true" fields="month" @change="bindDateChange">
<view class="input-text">{{ orderDetail.birthday.slice(0, 7) }}</view>
</picker>
<image src="/static/n-zx/right-icon.png" class="right-icon" style="margin-left: 20rpx;">
</image>
</view>
</view>
<view class="psychic-detail-row">
<text class="psychic-detail-title-text">联系方式</text>
<view style="text-align: right;">
<input class="input-text" type="number" v-model="orderDetail.phone" :disabled="true"
:maxlength="10" placeholder="请输入预约人联系电话" />
</view>
</view>
<view class="psychic-detail-row">
<text class="psychic-detail-title-text">性别</text>
<view style="display: flex;align-items: center;" v-if="orderDetail.sex == 1">
<view style="margin-right: 44.44rpx;display: flex;align-items: center;">
<image src="/static/n-zx/choice.png" style="width: 40rpx;height: 40rpx;"></image>
<text class="input-text" style="margin-left:10rpx ;"></text>
</view>
<view style="display: flex;align-items: center;">
<image src="/static/n-zx/nochoice.png" style="width: 31rpx;height: 31rpx;"></image>
<text class="input-text" style="margin-left:10rpx ;"></text>
</view>
</view>
<view style="display: flex;align-items: center;" v-if="orderDetail.sex == 2">
<view style="margin-right: 44.44rpx;display: flex;align-items: center;">
<image src="/static/n-zx/nochoice.png" style="width: 31rpx;height: 31rpx;"></image>
<text class="input-text" style="margin-left:10rpx ;"></text>
</view>
<view style="display: flex;align-items: center;">
<image src="/static/n-zx/choice.png" style="width: 40rpx;height: 40rpx;"></image>
<text class="input-text" style="margin-left:10rpx ;"></text>
</view>
</view>
</view>
</view>
</view>
<view class="card" style="margin-top: 20rpx;box-sizing: border-box;" v-if="showDetailFlag">
<view
style="padding-left: 40rpx;padding-right: 40rpx;width: 100%;box-sizing: border-box;padding-bottom: 40rpx;">
<view class="psychic-detail-row" style="justify-content: flex-start;">
<text class="psychic-detail-text">紧急联系人</text>
</view>
<!-- <view class="psychic-detail-row" style="justify-content: flex-start;margin-top: 20rpx;">-->
<!-- <view>-->
<!-- <text class="psychic-detail-show-text"-->
<!-- style="color: #909099;">信息严格保密仅常机状况时联系以保障您的生命安全和福社-->
<!-- </text>-->
<!-- </view>-->
<!-- </view>-->
<view class="psychic-detail-row">
<text class="psychic-detail-title-text">联系方式</text>
<view style="text-align: right;">
<input class="input-text" type="number" :maxlength="10" disabled
v-model="orderDetail.emergencyContactPhone" placeholder="请输入预约人联系电话" />
</view>
</view>
<view class="psychic-detail-row">
<text class="psychic-detail-title-text">与你的关系</text>
<view style="text-align: right;display: flex;align-items: center;">
<input class="input-text" type="number" disabled
v-model="orderDetail.emergencyContactTypeText" :maxlength="10"
placeholder="请输入预约人联系电话" />
<!-- <image src="/static/n-zx/right-icon.png" class="right-icon" style="margin-left: 20rpx;">-->
<!-- </image>-->
<!-- <uni-data-select style="width: 80%;outline: none;border: none;text-align: right"-->
<!-- v-model="orderDetail.emergencyContactType"-->
<!-- :localdata="range"-->
<!-- disabled-->
<!-- @change="changeEmergencyContactType"-->
<!-- :clear="false"-->
<!-- placeholder="请选择"-->
<!-- >-->
<!-- </uni-data-select>-->
</view>
</view>
</view>
</view>
<view class="card" style="margin-top: 20rpx;box-sizing: border-box;">
<view
style="padding-left: 40rpx;padding-right: 40rpx;width: 100%;box-sizing: border-box;padding-bottom: 40rpx;">
<view class="psychic-detail-row" style="justify-content: flex-start;">
<text class="psychic-detail-text">订单信息</text>
</view>
<view class="psychic-detail-row">
<text class="psychic-detail-title-text">订单编号</text>
<view style="text-align: right;">
<uni-tag text="复制" type="primary" @click="copyContent(orderDetail.orderSn)" :inverted="true"
style="margin-right: 10rpx;" />
<text class="psychic-detail-show-text">{{orderDetail.orderSn}} </text>
</view>
</view>
<view class="psychic-detail-row">
<text class="psychic-detail-title-text">创建时间</text>
<view style="text-align: right;" v-if=" orderDetail.createTime">
<text
class="psychic-detail-show-text">{{ orderDetail.createTime.split('T').join(' ') }}</text>
</view>
</view>
<view class="psychic-detail-row">
<text class="psychic-detail-title-text">订单原价</text>
<view style="text-align: right;">
<text class="psychic-detail-show-text">¥{{advancedFormat(orderDetail.totalAmount)}} </text>
</view>
</view>
<view class="psychic-detail-row">
<text class="psychic-detail-title-text">实付金额</text>
<view style="text-align: right;">
<text class="psychic-detail-show-text">¥{{advancedFormat(orderDetail.totalAmount)}} </text>
</view>
</view>
<!-- <view class="psychic-detail-row" style="margin-top: 20rpx;align-items: center;">
<view style="display: flex;align-items: center;">
<image src="/static/n-zx/wx-pay-icon.png" style="width:88rpx;height: 88rpx;"></image>
<text class="input-text">微信支付</text>
</view>
<image src="/static/n-zx/choice-pay-icon.png" style="width: 48rpx;height: 48rpx;"></image>
</view> -->
</view>
</view>
<!-- <view style="width: 670rpx;display: flex;align-items: center; margin-top: 22rpx">-->
<!-- <image src="/static/n-zx/choice.png" style="width: 36rpx;height: 36rpx;"></image>-->
<!-- <view-->
<!-- style="white-space: nowrap; text-overflow: ellipsis;overflow: hidden;width: 630rpx;margin-left: 10rpx;">-->
<!-- <text class="psychic-detail-title-text"> 同意</text>-->
<!-- <text class="psychic-detail-title-text" style="color:#F97559 ;">知情同意书心理咨询服务协议</text>-->
<!-- <text class="psychic-detail-title-text"></text>-->
<!-- <text class="psychic-detail-title-text" style="color:#F97559 ;">专属助理服务须知</text>-->
<!-- <text class="psychic-detail-title-text">点击同意"开始接受服务。</text>-->
<!-- </view>-->
<!-- </view>-->
<!-- <view class="bottom-btn" style="box-sizing: border-box;">-->
<!-- <text class="btn-text">立即预约¥600</text>-->
<!-- </view>-->
<view v-if="orderDetail.status==0||orderDetail.status==8||orderDetail.status==9"
style="margin-top: 40rpx;display: flex;justify-content: space-around;align-items: center;width: 100%">
<view v-if="orderDetail.status==0" class="btn1" @click.stop="cancelOrder(orderDetail)">
<text class="btn-text1">取消订单</text>
</view>
<view v-if="orderDetail.status==0" class="btn" @click.stop="toPay(orderDetail)">
<text class="btn-text">立即支付</text>
</view>
<view class="btn1" v-if="orderDetail.status==8||orderDetail.status==9"
@click.stop="deleteOrder(orderDetail)">
<text class="btn-text1">删除订单</text>
</view>
<view class="btn" v-if="orderDetail.status==9||orderDetail.status==8"
@click.stop="consultAgain(orderDetail)">
<text class="btn-text">再次咨询</text>
</view>
<!-- <view class="btn" v-if="orderDetail.status==8" @click.stop="findOtherDoctor">
<text class="btn-text">预约其他咨询师</text>
</view> -->
</view>
<view v-if="orderDetail.status==1||orderDetail.status==4||orderDetail.status==5"
style="margin-top: 40rpx;display: flex;justify-content: center;align-items: center;width: 100%">
<view class="btn2" v-if="orderDetail.status==1">
<button plain class="contact-btn" open-type="contact">
<text class="btn-text">联系助理</text>
</button>
</view>
<view class="btn2" v-if="orderDetail.status==4||orderDetail.status==5"
@click.stop="consultAgain(orderDetail)">
<text class="btn-text">再次咨询</text>
</view>
</view>
</view>
</view>
</template>
<script setup>
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
const advancedFormat = (num) => {
const divided = Number(num) / 100;
// 转换为字符串处理科学计数法(如1e-7)
const str = divided.toLocaleString('en-US', {
maximumFractionDigits: 2,
useGrouping: false
});
return str.replace(/(\.\d*?[1-9])0+$/, '$1').replace(/\.$/, '');
}
const copyContent = (content) => {
uni.setClipboardData({
data: content,
success: () => {
uni.showToast({
title: '复制成功',
duration: 1500
});
}
});
}
const cancelOrder = (item) => {
uni.showModal({
content: '确定取消该订单吗?',
success: function(res) {
if (res.confirm) {
dohttp.post(urls.cancelOrder + "?orderId=" + item.id).then((result) => {
if (result) {
item.status = 9
item.cancelFlag = 2
uni.showToast({
title: '取消成功',
duration: 1500
});
}
})
}
}
})
}
const consultAgain = (item) => {
dohttp.navigateTo("/pages/consult-detail/consult-detail?id=" + item.doctorId)
}
const onShareAppMessage = () => {
return {
title: '快来体验一下吧~',
path: '/pages/index/index', // 分享的路径
};
};
const onShareTimeline = () => {
return {
title: '快来体验一下吧~',
query: 'id=51', // 分享路径的参数
};
};
const deleteOrder = (item) => {
uni.showModal({
content: '是否删除该订单信息,删除后将不能恢复',
success: function(res) {
if (res.confirm) {
dohttp.post(urls.deleteOrder + "?orderId=" + item.id).then((result) => {
if (result) {
uni.showToast({
title: '删除成功',
duration: 1500
});
uni.navigateTo("/pages/order/order")
}
})
}
}
})
}
const findOtherDoctor = () => {
uni.switchTab({
"url": "/pages/consult/consult",
"animationType": "pop-in"
})
}
const toPay = (item) => {
let params = {
orderSn: item.orderSn
}
dohttp.get(urls.getPayParam, params).then((result) => {
console.log("urls.getPayParam", result)
uni.requestPayment({
provider: 'wxpay',
timeStamp: result.timeStamp,
nonceStr: result.nonceStr,
package: result.packageStr,
signType: result.signType,
paySign: result.paySign,
success: function(res) {
console.log('success:' + JSON.stringify(res));
},
fail: function(err) {
console.log('fail:' + JSON.stringify(err));
}
})
})
}
const getWeekDay = (dateString) => {
const date = new Date(dateString);
if (isNaN(date.getTime())) {
return '无效日期'; // 校验日期合法性[3](@ref)
}
const weekDays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
return weekDays[date.getDay()];
}
const range = ref([{
value: 1,
text: "朋友"
},
{
value: 2,
text: "子女"
},
{
value: 3,
text: "夫妻"
},
{
value: 4,
text: "父母"
},
])
const showDetailFlag = ref(false)
const toConsultAppointment = () => {
dohttp.navigateTo("/pages/consult-appointment/consult-appointment")
}
const changeDetailFlag = () => {
showDetailFlag.value = true
bgHeight.value = "fit-content"
}
const orderDetail = ref({})
onLoad((option) => {
if (option.id) {
getOrderDetail(option.id)
} else {
uni.showModal({
title: '数据异常',
content: '页面数据发生异常,即将返回主页',
showCancel: false,
success: function(res) {
if (res.confirm) {
uni.reLaunch({
url: "/pages/index/index"
})
}
}
})
}
})
const getOrderDetail = async (id) => {
dohttp.post(urls.orderDetail + "?orderId=" + id).then(res => {
orderDetail.value = res
if (orderDetail.value.emergencyContactType) {
range.value.forEach(item => {
if (item.value == orderDetail.value.emergencyContactType) {
orderDetail.value.emergencyContactTypeText = item.text
}
})
}
})
}
</script>
<style scoped>
.content {
width: 100vw;
height: 100vh;
background-color: #F9F6F5;
display: flex;
flex-direction: column;
font-family: SourceHanSans;
background-image: url('https://miniapp.yuxingu.com.cn/yxg-mp/pic/bg-all.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.order-text {
font-size: 20rpx;
font-variation-settings: "opsz" auto;
color: #606271
}
.card {
width: 670rpx;
background-color: #ffffff;
display: flex;
flex-direction: column;
box-sizing: border-box;
align-items: flex-start;
border-radius: 32rpx;
}
.psychic-detail-row {
display: flex;
justify-content: space-between;
width: 100%;
margin-top: 39rpx;
}
.psychic-detail-text {
font-family: SourceHanSansBold;
font-size: 28rpx;
line-height: normal;
text-align: center;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
/* 背景色/浅色背景2 */
color: #614D49;
}
.psychic-detail-show-text {
font-family: SourceHanSans;
font-size: 24rpx;
font-weight: normal;
line-height: normal;
text-align: center;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
/* 背景色/浅色背景2 */
color: #614D49;
}
.input-text {
font-family: SourceHanSans;
font-size: 28rpx;
font-weight: normal;
line-height: normal;
text-align: right;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
/* 正文色/正文辅助4 */
color: #909099;
}
.psychic-detail-title-text {
font-family: SourceHanSans;
font-size: 28rpx;
font-weight: normal;
line-height: normal;
text-align: center;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
/* 背景色/浅色背景2 */
color: #614D49;
}
.right-icon {
width: 12rpx;
height: 22rpx;
margin-left: 10rpx;
}
.bottom-btn {
width: 550rpx;
height: 96rpx;
border-radius: 2002rpx;
/* 自动布局 */
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 22rpx 40rpx;
background: linear-gradient(180deg, #E84B2A 0%, #FF846A 100%);
margin-top: 68rpx;
}
.btn-text {
font-family: SourceHanSansBold;
font-size: 36rpx;
line-height: normal;
letter-spacing: 0rpx;
/* 正文色/正文色 */
color: #FFFFFF;
}
.expand-bottom {
width: 670rpx;
margin-top: 40rpx;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
justify-content: center;
height: 62rpx;
border-radius: 0px 0px 10rpx 10rpx;
background: linear-gradient(180deg, #FF9079 0%, #F37155 100%);
}
.btn {
width: 282rpx;
height: 96rpx;
border-radius: 2002rpx;
/* 自动布局 */
display: flex;
justify-content: center;
align-items: center;
background: linear-gradient(180deg, #E84B2A 0%, #FF846A 100%);
}
.btn-text {
font-size: 28rpx;
font-family: SourceHanSansBold;
color: #FFFFFF;
}
.btn1 {
width: 282rpx;
height: 76rpx;
border-radius: 2002rpx;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
border: 2rpx solid #F36749;
}
.btn2 {
width: 650rpx;
height: 96rpx;
border-radius: 2002rpx;
/* 自动布局 */
display: flex;
justify-content: center;
align-items: center;
background: linear-gradient(180deg, #E84B2A 0%, #FF846A 100%);
}
.btn-text1 {
font-size: 28rpx;
font-family: SourceHanSansBold;
color: #F36749;
}
.contact-btn {
border: none;
outline: none;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
padding: 0rpx;
margin: 0rpx;
background-color: transparent;
display: flex;
align-items: center;
}
</style>
+484
View File
@@ -0,0 +1,484 @@
<template>
<view class="content">
<myNav title="咨询订单" bgColor="#fff" titleColor="#614D49" :backIcon="true" :backHome="backHomeFlag" :flex="false"></myNav>
<scroll-view :scroll-y="enableScroll" @scrolltolower="scrolltolower" class="scroll-style"
:style="{ height: `${showHight}rpx` }">
<view ref="contentRef" id="contentContainer" style="display:flex;align-items:center;flex-direction:column;"
v-if="orderList.length>0">
<view v-for="(item,index) in orderList" :key="index" @click="toDetail(item)"
style="width: 670rpx;background-color: #fff;padding: 40rpx;display: flex;flex-direction: column;margin-top: 40rpx; box-sizing: border-box;border-radius: 10rpx;">
<view style="display: flex;">
<image :src="item.avatar" style="width: 120rpx;height: 120rpx;border-radius: 10rpx;">
</image>
<view style="display: flex;flex-direction: column;margin-left: 20rpx;">
<text class="show-name">{{ item.name }}</text>
<view style="display: flex; align-items: last baseline;" v-if="item.consultationMethod == 'face_to_face'">
<image src="/static/n-zx/face-to-face.png" style="width: 26rpx;height: 28.66rpx;"></image>
<text class="consult-method-text" style="margin-left: 10rpx;">面对面咨询·1</text>
</view>
<view style="display: flex; align-items: last baseline;" v-if="item.consultationMethod == 'video'">
<image src="/static/n-zx/video-camera.png" style="width: 26rpx;height: 28.66rpx;"></image>
<text class="consult-method-text" style="margin-left: 10rpx;">视频咨询·1</text>
</view>
</view>
<view style="flex: 1;text-align: right;display: flex;flex-direction: column;">
<text class="order-status-text1" v-if="item.status== 0 ">待支付</text>
<text class="order-status-text1" v-if="item.status== 1 ">待咨询</text>
<text class="order-status-text1" v-if="item.status== 4 ">待确认</text>
<text class="order-status-text1" v-if="item.status== 5 ">已完成</text>
<text class="order-status-text1" style="color: #00B637" v-if="item.status== 6 ">申请退款中</text>
<text class="order-status-text1" style="color: #00B637" v-if="item.status== 7 ">退款中</text>
<text class="order-status-text1" style="color: #00B637" v-if="item.status== 8 ">已退款</text>
<text class="order-status-text1" style="color: #00B637" v-if="item.status== 9 ">交易关闭</text>
<view style="">
<text class="rmb-text">¥{{ advancedFormat(item.totalAmount) }}</text>
<!-- <text class="effect-time-text">/{{ calculateTimeDifference(item.startTime, item.endTime) }}分钟</text> -->
</view>
</view>
</view>
<view
style="border-radius: 10rpx;background-color: #F7F4F3;padding: 20rpx;display: flex;margin-top: 20rpx;align-items: first baseline;">
<image src="/static/n-zx/notice-icon.png" style="width:21rpx ;height:18.48rpx;"></image>
<view style="line-height: 24rpx;" v-if="item.status==0">
<text class="order-text"
style="margin-left: 10rpx;color: #186BF9;flex-wrap: nowrap;">
{{ item.validTime.split('T').join(' ') }}
</text>
<text class="order-text">前未支付订单将自动取消请及时完成支付</text>
</view>
<view style="line-height: 24rpx;margin-left: 5rpx" v-if="item.status==1">
<text class="order-text" @click="toConsultAppointment">支付成功等待执行相关详情请查看
<text style="color: #186BF9;">预约须知</text>
</text>
</view>
<view style="line-height: 24rpx;margin-left: 5rpx" v-if="item.status==4">
<text class="order-text">等待客服确认本次咨询</text>
</view>
<view style="line-height: 24rpx;margin-left: 5rpx" v-if="item.status==5">
<text class="order-text">订单已完成</text>
</view>
<view style="line-height: 24rpx;margin-left: 5rpx" v-if="item.status==6">
<text class="order-text">申请退款中请耐心等待</text>
</view>
<view style="line-height: 24rpx;margin-left: 5rpx" v-if="item.status==7">
<text class="order-text">退款已受理将会在1个工作日内返回到支付账户</text>
</view>
<view style="line-height: 24rpx;margin-left: 5rpx" v-if="item.status==8">
<text class="order-text">退款金额已成功返回到支付账户</text>
</view>
<view style="line-height: 24rpx;margin-left: 5rpx" v-if="item.status==9">
<text class="order-text" v-if="item.cancelFlag == 1">支付超时,已关闭交易</text>
<text class="order-text" v-if="item.cancelFlag == 2">订单已取消</text>
</view>
</view>
<view style="margin-top: 20rpx;display: flex;justify-content: space-between;align-items: center;">
<view style="display: flex;flex-direction: column;">
<!-- <view style="display: flex;align-items: baseline">
<text class="rmb-text">¥{{ advancedFormat(item.totalAmount) }}</text>
<text class="effect-time-text">/{{ calculateTimeDifference(item.startTime, item.endTime) }}分钟</text>
</view> -->
<text class="time-text">{{ item.createTime.split('T').join(' ') }}</text>
</view>
<view class="btn1" v-if="item.status==0" @click.stop="cancelOrder(item)">
<text class="btn-text1">取消订单</text>
</view>
<view class="btn" v-if="item.status==0" @click.stop="toPay(item)">
<text class="btn-text">立即支付</text>
</view>
<view class="btn" v-if="item.status==1">
<button plain class="contact-btn" open-type="contact">
<text class="btn-text">联系助理</text>
</button>
</view>
<view class="btn1" v-if="item.status==8||item.status==9" @click.stop="deleteOrder(item)">
<text class="btn-text1">删除订单</text>
</view>
<!-- <view class="btn" v-if="item.status==8" style="width: 40%;margin-left: 5%" @click.stop="findOtherDoctor">
<text class="btn-text">预约其他咨询师</text>
</view> -->
<view class="btn" v-if="item.status==4||item.status==5||item.status==9||item.status==8" @click.stop="consultAgain(item)">
<text class="btn-text">再次咨询</text>
</view>
</view>
</view>
</view>
<view ref="contentRef" id="contentContainer" style="display:flex;align-items:center;flex-direction:column;width: 100%;height: 100%;
display: flex;align-items: center;justify-content: center"
v-if="orderList.length==0">
<text style="font-size: 30rpx;font-family: SourceHanSansBold;color: #EA4E2D">暂无订单数据</text>
</view>
</scroll-view>
</view>
</template>
<script setup>
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
const backHomeFlag = ref(false)
onLoad((option) => {
if(option.backHome && option.backHome == 1){
backHomeFlag.value=true
}
if (option.num && option.num > 0) {
toOrderRead()
}
requestParam.value.pageNo = 1
orderList.value = []
const systemInfo = uni.getSystemInfoSync()
// 更精准的高度计算
showHight.value = (systemInfo.windowHeight * (750 / systemInfo.screenWidth)) - 200
getOrderList()
})
const timeToMinutes = (timeStr) => {
const [hours, minutes] = timeStr.split(':').map(Number);
return hours * 60 + minutes;
}
// 计算时间差(处理跨天情况)
const calculateTimeDifference = (startTime, endTime) => {
const startMinutes = timeToMinutes(startTime);
const endMinutes = timeToMinutes(endTime);
let diff = endMinutes - startMinutes;
// 如果跨天(结束时间早于开始时间),补上24小时
if (diff < 0) diff += 24 * 60;
return diff;
}
const advancedFormat = (num) => {
const divided = Number(num) / 100;
// 转换为字符串处理科学计数法(如1e-7)
const str = divided.toLocaleString('en-US', {
maximumFractionDigits: 2,
useGrouping: false
});
return str.replace(/(\.\d*?[1-9])0+$/, '$1').replace(/\.$/, '');
}
import {
ref,
onMounted,
nextTick,
getCurrentInstance
} from 'vue'
const showHight = ref(0)
const instance = getCurrentInstance()
const enableScroll = ref(false) // 新增动态滚动控制
// 新增高度检查方法
const checkContentHeight = () => {
const query = uni.createSelectorQuery().in(instance.proxy)
query.select('#contentContainer').boundingClientRect(rect => {
if (rect) {
const systemInfo = uni.getSystemInfoSync()
// 转换为rpx比较
// 计算容器实际像素高度
const containerHeightPx = (showHight.value * systemInfo.screenWidth) / 750
const threshold = 5 // 容错阈值
enableScroll.value = rect.height > (containerHeightPx + threshold)
// console.log('[Layout Debug]', {
// contentHeight: rect.height,
// containerPx: containerHeightPx,
// containerRpx: showHight.value,
// shouldScroll: enableScroll.value
// })
}
}).exec()
}
// 初始加载检查
onMounted(() => {
nextTick(checkContentHeight)
})
const orderList = ref([])
const toOrderRead = () => {
dohttp.post(urls.orderToRead).then((result) => {
})
}
const onShareAppMessage = () => {
return {
title: '快来体验一下吧~',
path: '/pages/index/index', // 分享的路径
};
};
const onShareTimeline = () => {
return {
title: '快来体验一下吧~',
query: 'id=5', // 分享路径的参数
};
};
const requestParam = ref({
pageNo: 1,
pageSize: 10
})
const totalNum = ref(0)
const getOrderList = () => {
dohttp.post(urls.orderList, requestParam.value).then((result) => {
orderList.value = [...orderList.value, ...result.list]
totalNum.value = result.totalNum
// 确保图片加载完成
nextTick(() => {
setTimeout(() => {
checkContentHeight()
// 添加重试机制
if (!enableScroll.value) setTimeout(checkContentHeight, 500)
}, 300)
})
})
}
const findOtherDoctor = () => {
uni.switchTab({
"url": "/pages/consult/consult",
"animationType": "pop-in"
})
}
const deleteOrder = (item) => {
uni.showModal({
content: '是否删除该订单信息,删除后将不能恢复',
success: function(res) {
if (res.confirm) {
dohttp.post(urls.deleteOrder + "?orderId=" + item.id).then((result) => {
if (result) {
orderList.value = orderList.value.filter(order => order.id !== item.id);
// getOrderList()
uni.showToast({
title: '删除成功',
duration: 1500
});
}
})
}
}
})
}
const consultAgain = (item) => {
dohttp.navigateTo("/pages/consult-detail/consult-detail?id=" + item.doctorId)
}
const toPay = (item) => {
let params = {
orderSn: item.orderSn
}
dohttp.get(urls.getPayParam, params).then((result) => {
console.log("urls.getPayParam", result)
uni.requestPayment({
provider: 'wxpay',
timeStamp: result.timeStamp,
nonceStr: result.nonceStr,
package: result.packageStr,
signType: result.signType,
paySign: result.paySign,
success: function (res) {
console.log('success:' + JSON.stringify(res));
},
fail: function (err) {
console.log('fail:' + JSON.stringify(err));
}
})
})
}
const toDetail = (item) => {
dohttp.navigateTo("/pages/order-detail/order-detail?id=" + item.id)
}
const cancelOrder = (item) => {
uni.showModal({
content: '确定取消该订单吗?',
success: function(res) {
if (res.confirm) {
dohttp.post(urls.cancelOrder + "?orderId=" + item.id).then((result) => {
if (result) {
item.status = 9
item.cancelFlag = 2
uni.showToast({
title: '取消成功',
duration: 1500
});
}
})
}
}
})
}
const toConsultAppointment = () => {
dohttp.navigateTo("/pages/consult-appointment/consult-appointment")
}
const scrolltolower = () => {
if (totalNum.value > requestParam.value.pageNo * requestParam.value.pageSize) {
requestParam.value.pageNo += 1
getOrderList()
} else {
uni.showToast({
title: '没有更多数据了',
duration: 1500
});
}
}
</script>
<style scoped>
.content {
width: 100vw;
height: 100vh;
background-color: #F9F6F5;
display: flex;
flex-direction: column;
font-family: SourceHanSans;
background-image: url('https://miniapp.yuxingu.com.cn/yxg-mp/pic/bg-all.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.scroll-style {
box-sizing: border-box;
padding: 0 !important;
/* 清除可能的内边距 */
}
.show-name {
font-family: SourceHanSansBold;
font-size: 40rpx;
font-variation-settings: "opsz" auto;
color: #614D49;
}
.consult-method-text {
font-size: 24rpx;
font-variation-settings: "opsz" auto;
/* 正文色/正文辅助4 */
color: #9B918C;
}
.order-text {
font-size: 20rpx;
font-variation-settings: "opsz" auto;
color: #9B918C
}
.rmb-text {
color: #F37155;
font-family: SourceHanSansBold;
font-size: 36rpx;
}
.effect-time-text {
color: #EA4E2D;
font-weight: 700;
font-size: 20rpx;
}
.time-text {
font-size: 24rpx;
font-variation-settings: "opsz" auto;
/* 正文色/正文色辅助3 */
color: #909099;
}
.order-status-text1 {
font-size: 28rpx;
font-family: SourceHanSansBold;
font-variation-settings: "opsz" auto;
color: #DB0000;
}
.order-status-text2 {
font-size: 28rpx;
font-family: SourceHanSansBold;
font-variation-settings: "opsz" auto;
color: #00B637;
}
.btn {
width: 152rpx;
height: 56rpx;
border-radius: 2002rpx;
/* 自动布局 */
display: flex;
justify-content: center;
align-items: center;
background: linear-gradient(180deg, #FF9079 0%, #F37155 100%);
}
.btn-text {
font-size: 28rpx;
font-family: SourceHanSansBold;
color: #FFFFFF;
}
.btn1 {
width: 152rpx;
height: 56rpx;
border-radius: 2002rpx;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
border: 2rpx solid #F36749;
}
.btn-text1 {
font-size: 28rpx;
font-family: SourceHanSansBold;
color: #F36749;
}
.contact-btn {
border: none;
outline: none;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
padding: 0rpx;
margin: 0rpx;
background-color: transparent;
display: flex;
align-items: center;
}
</style>
+101
View File
@@ -0,0 +1,101 @@
<template>
<view class="content">
<myNav title="支付demo" bgColor="nonoe" titleColor="#614D49" :backIcon="false" :backHome="false" :flex="false">
</myNav>
<view class="button-container">
<button class="start-btn" @click="toPay">立即支付</button>
</view>
<view class="button-container">
<button class="start-btn" @click="refund">立即退款</button>
</view>
</view>
</template>
<script setup>
import {
onMounted,
ref
} from 'vue'
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
const provider = ref("")
const toPay = async() => {
const result = await createOrder()
console.log("toPay------------",result)
uni.requestPayment({
provider:'wxpay',
timeStamp:result.timeStamp,
nonceStr:result.nonceStr,
package:result.packageStr,
signType:result.signType,
paySign:result.paySign,
success: function (res) {
console.log('success:' + JSON.stringify(res));
},
fail: function (err) {
console.log('fail:' + JSON.stringify(err));
}
})
}
const createOrder=()=>{
return dohttp.post(urls.createOrder)
}
const refund=()=>{
dohttp.post(urls.refund).then((result)=>{
console.log("urls.refundurls.refund",result)
})
}
onMounted(() => {
uni.getProvider({
"service": "payment",
success(data) {
if (data.provider && data.provider.length > 0) {
provider.value = data.provider[0]
}
}
})
})
</script>
<style scoped>
.content {
width: 100vw;
height: 100vh;
background-color: #f9f8f8;
display: flex;
flex-direction: column;
font-family: SourceHanSansBold;
}
/* 按钮 */
.button-container {
text-align: center;
margin-top: 40rpx;
}
.start-btn {
width: 50%;
background: linear-gradient(to right, #7c5afe, #6253e5);
color: white;
font-size: 24rpx;
border-radius: 50rpx;
text-align: center;
}
</style>
+236
View File
@@ -0,0 +1,236 @@
<template>
<view class="content">
<myNav title="我的" bgColor="#fff" titleColor="#614D49" :backIcon="false" :backHome="false" :flex="false"></myNav>
<view
style="display: flex;margin-top: 20rpx; flex-direction: column;align-items: center;padding: 40rpx;box-sizing: border-box;width: 100%;">
<view style="display: flex;align-items: center;justify-content: space-between;width: 100%;">
<view style="display: flex;align-items: center;">
<image v-if="showObj.avatarUrl" :src="showObj.avatarUrl" style="width: 120rpx;height: 120rpx;border-radius: 120rpx;"></image>
<image v-else src="/static/n-pc/head.png" style="width: 120rpx;height: 120rpx;"></image>
<text v-if="showObj.nickName" class="p-name" style="margin-left: 48rpx;">{{showObj.nickName}}</text>
<text v-else class="p-name" style="margin-left: 48rpx;">未登录</text>
</view>
<view style="display: flex;justify-content: flex-end;align-items: center;height: 50%;width: 80rpx;" @click="editUserInfo">
<image src="/static/n-pc/p-left.png" style="width: 12rpx;height: 22rpx" ></image>
</view>
</view>
<view
style="display: flex;align-items: center;justify-content: space-between;width: 100%;margin-top: 40rpx;">
<view style="position: relative;width: 316rpx;height: 138rpx;" @click="myOrder">
<image src="/static/n-pc/order-bg.png"
style="position: absolute;width: 100%;height: 100%;z-index: 0;"></image>
<view style="display: flex;position: absolute;z-index: 1;width: 316rpx;height: 138rpx;">
<image src="/static/n-pc/wd-dd.png" mode="heightFix"
style="height: 74rpx;width: 66rpx;margin-left: 40rpx;margin-top: 28rpx;"></image>
<view
style="display: flex;flex-direction: column;margin-top: 26rpx;margin-left:20rpx;align-items: center;">
<text class="p-title">我的订单</text>
<text v-if="notReadNumObj?.orderNum&&notReadNumObj?.orderNum>0" class="p-num" style="margin-top: -10rpx;color: #B6640B;">{{notReadNumObj?.orderNum ? notReadNumObj?.orderNum : 0}}</text>
</view>
</view>
</view>
<view style="position: relative;width: 316rpx;height: 138rpx;" @click="myFocus">
<image src="/static/n-pc/focus-bg.png"
style="position: absolute;width: 100%;height: 100%;z-index: 0;"></image>
<view style="display: flex;position: absolute;z-index: 1;width: 316rpx;height: 138rpx;">
<image src="/static/n-pc/wd-gz.png" mode="heightFix"
style="height: 74rpx;width: 66rpx;margin-left: 40rpx;margin-top: 28rpx;"></image>
<view
style="display: flex;flex-direction: column;margin-top: 26rpx;margin-left:20rpx;align-items: center;">
<text class="p-title">我的关注</text>
<text v-if="notReadNumObj?.focusNum&&notReadNumObj?.focusNum>0" class="p-num" style="margin-top: -10rpx;color: #DC2602;">{{notReadNumObj?.focusNum ? notReadNumObj?.focusNum : 0}}</text>
</view>
</view>
</view>
</view>
<view style="display: flex;justify-content: space-between;width: 100%;margin-top: 40rpx;flex-direction: column;padding: 40rpx 40rpx;
border-radius: 32rpx; box-sizing: border-box;background-color: #fff;">
<view style="display: flex;align-items: center;" @click="toMyTest">
<image src="/static/n-pc/wd-wdpc.png" style="width:38rpx ;height: 38rpx;"></image>
<text class="p-menu" style="margin-left:42rpx; ">我的评测</text>
<view style="flex: 1;text-align: right;">
<image src="/static/n-pc/p-left.png" style="width: 12rpx;height: 22rpx;"></image>
</view>
</view>
<view style="display: flex;align-items: center;margin-top: 62rpx" @click="toConsultAppointment">
<image src="/static/n-pc/wd-zxyx.png" style="width:38rpx ;height: 38rpx;"></image>
<text class="p-menu" style="margin-left:42rpx; ">咨询预约协议</text>
<view style="flex: 1;text-align: right;">
<image src="/static/n-pc/p-left.png" style="width: 12rpx;height: 22rpx;"></image>
</view>
</view>
<view style="display: flex;align-items: center;margin-top: 62rpx" @click="toKefu">
<image src="/static/n-pc/wd-kf.png" style="width:38rpx ;height: 38rpx;"></image>
<text class="p-menu" style="margin-left:42rpx; ">联系客服</text>
<view style="flex: 1;text-align: right;">
<image src="/static/n-pc/p-left.png" style="width: 12rpx;height: 22rpx;"></image>
</view>
</view>
<view style="display: flex;align-items: center;margin-top: 62rpx" @click="toFeedback">
<image src="/static/n-pc/wd-yj.png" style="width:38rpx ;height: 38rpx;"></image>
<text class="p-menu" style="margin-left:42rpx; ">意见反馈</text>
<view style="flex: 1;text-align: right;">
<image src="/static/n-pc/p-left.png" style="width: 12rpx;height: 22rpx;"></image>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
const onShareAppMessage = () => {
return {
title: '快来体验一下吧~',
path: '/pages/index/index', // 分享的路径
};
};
const onShareTimeline = () => {
return {
title: '快来体验一下吧~',
query: 'id=4', // 分享路径的参数
};
};
const editUserInfo = () => {
dohttp.navigateTo("/pages/edit-userinfo/edit-userinfo")
}
const toKefu = () => {
dohttp.navigateTo("/pages/customer-service/customer-service")
}
const toFeedback = () => {
dohttp.navigateTo("/pages/feedback/feedback")
}
const myFocus=()=>{
dohttp.navigateTo("/pages/my-focus/my-focus?num="+notReadNumObj.value?.focusNum)
}
const myOrder=()=>{
dohttp.navigateTo("/pages/order/order?num="+notReadNumObj.value?.orderNum)
}
const showObj=ref({
id: null,
avatarUrl: null,
nickName: null
})
const notReadNumObj=ref({})
const notReadNum=()=>{
dohttp.get(urls.notReadNum).then((result) => {
notReadNumObj.value.id= result.id
notReadNumObj.value.focusNum = result.focusNum
notReadNumObj.value.orderNum = result.orderNum
})
}
onLoad((option) => {
const isLoggedIn = uni.getStorageSync('token'); // 假设 token 保存在本地存储
if (!isLoggedIn) {
// uni.navigateTo({
// "url": "/pages/login-pop/login-pop?type=3&path=/pages/personal-center/personal-center",
// "animationType": "pop-in"
// })
return
}
const userinfo = uni.getStorageSync('userinfo')
if(userinfo){
showObj.value.avatarUrl= userinfo.avatarUrl
showObj.value.nickName = userinfo.nickName
if(!showObj.value.nickName){
showObj.value.nickName = "微信用户"
}
}else{
getUserInfo()
}
notReadNum()
})
const getUserInfo = () => {
dohttp.get(urls.getSelfInfo).then((result) => {
const userinfo = {
avatarUrl: result.avatarUrl,
nickName: result.nickName
}
uni.setStorageSync('userinfo', userinfo)
showObj.value.avatarUrl= result.avatarUrl
showObj.value.nickName = result.nickName
if(!showObj.value.nickName){
showObj.value.nickName = "微信用户"
}
})
}
onShow(() => {
const userinfo = uni.getStorageSync('userinfo')
if(userinfo){
showObj.value.avatarUrl= userinfo.avatarUrl
showObj.value.nickName = userinfo.nickName
if(!showObj.value.nickName){
showObj.value.nickName = "微信用户"
}
}else{
getUserInfo()
}
notReadNum()
})
const toConsultAppointment=()=>{
dohttp.navigateTo("/pages/consult-appointment/consult-appointment")
}
const toMyTest=()=> {
dohttp.navigateTo("/pages/my-test/my-test")
}
</script>
<style scoped>
.content {
width: 100vw;
height: 100vh;
background-color: #F9F6F5;
display: flex;
flex-direction: column;
font-family: SourceHanSans;
background-image: url('https://miniapp.yuxingu.com.cn/yxg-mp/pic/botton.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.p-name {
font-size: 40rpx;
font-family: SourceHanSansBold;
color: #3D3D3D;
}
.p-title {
font-size: 28rpx;
font-family: SourceHanSansBold;
color: #614D49;
}
.p-num {
font-size: 40rpx;
font-family: SourceHanSansBold;
}
.p-menu {
font-size: 28rpx;
color: #3D3D3D;
}
</style>
+42
View File
@@ -0,0 +1,42 @@
<template>
<view class="content">
<myNav title="" bgColor="#fff" titleColor="#614D49" :backIcon="true" :backHome="false" :flex="false" ></myNav>
<view style="box-sizing: border-box;overflow-y: auto;margin-top: 5rpx;">
<image :src="showUrl" style="width: 100%;"
mode="widthFix"></image>
</view>
</view>
</template>
<script setup>
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
const showUrl=ref()
onLoad((option) => {
if(option.url){
showUrl.value = option.url
}else{
//TODO 报错 返回首页
}
})
</script>
<style scoped>
.content {
width: 100vw;
height: 100vh;
background-color: #f9f8f8;
display: flex;
flex-direction: column;
font-family: 'pingfang';
}
image {
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
}
</style>
+34
View File
@@ -0,0 +1,34 @@
<template>
<view class="content">
<myNav title="" bgColor="#fff" titleColor="#614D49" :backIcon="true" :backHome="false" :flex="false"></myNav>
</view>
</template>
<script setup>
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
</script>
<style scoped>
.content {
width: 100vw;
height: 100vh;
background-color: #f9f8f8;
display: flex;
flex-direction: column;
font-family: SourceHanSansBold;
}
</style>
+388
View File
@@ -0,0 +1,388 @@
<template>
<view class="content">
<myNav :title="showTitle" bgColor="nonoe" titleColor="#614D49" :backIcon="true" :backHome="false" :flex="false">
</myNav>
<view class="flex-justify-center">
<view class="choice-process">
<text class="chice-show-num" style="margin-left: 36rpx;">
{{ answerList.length }}/{{ showListData.length }}
</text>
<view style="width: 416rpx;margin-left: 15rpx;margin-right: 16rpx;height: 18rpx;">
<uv-line-progress :percentage="percentage" :showText="false" activeColor="#F37155"
style=""></uv-line-progress>
</view>
<text class="chice-show-title" style="margin-left: 10rpx;">
单选题
</text>
</view>
</view>
<view class="flex-justify-center">
<view class="question-show">
<image v-if="showData.questionImgae" style="width:100%;margin-top: 40rpx;" :src="showData.questionImgae"
mode="aspectFill"></image>
<text class="question-content">
{{ showData.seq + 1 }}{{ showData.questionText }}
</text>
<view class="option-show" v-for="(item, index) in showData.questionOptionVOList"
@click="toChoice(item,index)" :key="index">
<view :style="{color:showData.choiceindex&&showData.choiceindex==(index+1)?'#EA4E2D':'#303044'}">
<text>{{ getLabel(index) }}</text>
<text style="margin-left: 10rpx;">{{ item.optionText }}</text>
</view>
<view v-if="showData.choiceindex&&showData.choiceindex==(index+1)" class="no-choice">
<view class="choice-selected"></view>
</view>
<view v-else class="no-choice"></view>
</view>
</view>
</view>
<view class="button-container" style="display: flex;" v-if="showData.seq==(showListData.length-1)">
<button class="start-btn1" style="margin-left: 120rpx;" @click="toPre">
<text class="button-text">
上一题
</text>
</button>
<button class="start-btn1" style="margin-right: 120rpx;" @click="complete">
<text class="button-text">
完成
</text>
</button>
</view>
<view v-if="showData.seq>0&&showData.seq!=(showListData.length-1)" class="button-container">
<button class="start-btn" @click="toPre">
<text class="button-text">
上一题
</text>
</button>
</view>
</view>
</template>
<script setup>
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
const showListData = ref([])
const showTitle = ref("")
const answerList = ref([])
const percentage = ref(0)
const showData = ref({})
const testId = ref(null)
const costTime = ref(0)
const testPic = ref("")
onLoad((option) => {
const instance = getCurrentInstance().proxy
const eventChannel = instance.getOpenerEventChannel();
eventChannel.on('acceptDataFromOpenerPage', function(data) {
showListData.value = data.data
showTitle.value = data.showTitle
testPic.value = data.testPic
testId.value = data.testId
let index = 0
showData.value = showListData.value[index]
showData.value.seq = index
percentage.value = (answerList.value.length / showListData.value.length).toFixed(2) * 100
setInterval(() => {
costTime.value = costTime.value + 1
}, 1000)
})
})
onMounted(() => {
// showListData.value = uni.getStorageSync("data")
// showTitle.value = uni.getStorageSync("showTitle")
})
const getLabel = (index) => {
return String.fromCharCode(65 + index) + "" // A. B. C. D.
}
const toChoice = (item, index) => {
for (let i = 0; i < answerList.value.length; i++) {
if (answerList.value[i].questionId == showData.value.id) {
answerList.value[i].optionId = item.id
showData.value.choiceindex = index + 1
toNext()
return
}
}
answerList.value.push({
optionId: item.id,
questionId: showData.value.id
})
percentage.value = (answerList.value.length / showListData.value.length).toFixed(2) * 100
showData.value.choiceindex = index + 1
toNext()
}
const toNext = () => {
let currentIndex = showData.value.seq + 1
if (showListData.value[currentIndex]) {
showData.value = showListData.value[currentIndex]
showData.value.seq = currentIndex
}
}
const toPre = () => {
let currentIndex = showData.value.seq - 1
if (showListData.value[currentIndex]) {
showData.value = showListData.value[currentIndex]
showData.value.seq = currentIndex
}
}
const complete = () => {
let params = {
id: testId.value,
totalTime: costTime.value,
userChoiceOptionVOList: answerList.value
}
if (answerList.value.length != showListData.value.length) {
// const uniqueIds = showListData.value
// .filter(item => !answerList.value.some(sItem => sItem.questionId === item.id))
// .map(item => item.id);
console.log("ssssssssssss",answerList.value,showListData.value)
const map = answerList.value.reduce((acc, item) => {
acc.set(item.questionId, item);
return acc;
}, new Map());
for (let i = 0; i < showListData.value.length; i++) {
let ele= map.get(showListData.value[i].id)
if(!ele){
let req = showListData.value[i].seq+1
uni.showModal({
title: '提示',
content: '序号为'+req+"的题目还未选择,请选择后再提交",
showCancel: false,
success: function (res) {
if (res.confirm) {
}
}
})
}
}
return
}
dohttp.post(urls.userChoiceSave, params).then((result) => {
dohttp.navigateTo("/pages/test-result/test-result?resultId=" + result)
})
}
const onShareAppMessage = () => {
return {
title: '快来体验一下吧~',
path: '/pages/index/index', // 分享的路径
};
};
const onShareTimeline = () => {
return {
title: '快来体验一下吧~',
query: 'id=32', // 分享路径的参数
};
};
</script>
<style scoped>
.content {
width: 100vw;
height: 100vh;
background-color: #f9f8f8;
display: flex;
flex-direction: column;
font-family: SourceHanSans;
}
.section {
background: white;
margin: 20rpx 30rpx;
padding: 27rpx 20rpx;
border-radius: 10rpx;
box-shadow: 0rpx 4rpx 8rpx rgba(0, 0, 0, 0.01);
height: fit-content;
display: flex;
align-items: center;
}
/* 顶部图片 */
.banner {
width: 690rpx;
height: 440rpx;
object-fit: cover;
margin-top: 20rpx;
}
/* 按钮 */
.button-container {
text-align: center;
margin-top: auto;
margin-bottom: 60rpx;
}
.start-btn {
width: 550rpx;
height: 96rpx;
border-radius: 2002rpx;
opacity: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 8rpx 40rpx;
background: linear-gradient(180deg, #FF9079 0%, #F37155 100%);
}
.start-btn1 {
width: 250rpx;
height: 96rpx;
border-radius: 2002rpx;
opacity: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 8rpx 40rpx;
background: linear-gradient(180deg, #FF9079 0%, #F37155 100%);
}
.flex-justify-center {
display: flex;
justify-content: center;
}
.choice-process {
/* 正文色/正文色 */
background: #FFFFFF;
width: 670rpx;
height: 128rpx;
border-radius: 10rpx;
display: flex;
align-items: center;
}
.chice-show-num {
width: 70rpx;
height: 46rpx;
opacity: 1;
/* 按钮/按钮文本中号加粗 */
font-family: SourceHanSansBold;
font-size: 32rpx;
line-height: normal;
text-align: center;
letter-spacing: 0rpx;
font-variation-settings: "opsz" auto;
color: #9B918C;
}
.chice-show-title {
/* 正文/正文文本1 */
font-family: SourceHanSans;
font-size: 28rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0rpx;
font-variation-settings: "opsz" auto;
color: #9B918C;
}
.question-show {
display: flex;
flex-direction: column;
box-sizing: border-box;
width: 670rpx;
margin-top: 20rpx;
border-radius: 10rpx;
background: #FFFFFF;
padding-left: 40rpx;
padding-right: 40rpx;
padding-bottom: 40rpx;
}
.question-content {
font-family: SourceHanSansBold;
font-size: 36rpx;
line-height: normal;
letter-spacing: 0rpx;
font-variation-settings: "opsz" auto;
/* 背景色/浅色背景2 */
color: #614D49;
margin-top: 40rpx;
}
.option-show {
display: flex;
margin-top: 40rpx;
align-items: center;
font-family: SourceHanSans;
justify-content: space-between;
font-size: 32rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
/* 背景色/浅色背景2 */
color: #614D49;
}
.no-choice {
width: 40rpx;
height: 40rpx;
box-sizing: border-box;
border: 1px solid #606271;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
}
.choice-selected {
width: 28rpx;
height: 28rpx;
border-radius: 50%;
background: #EA4E2D;
}
.button-text {
/* 按钮/按钮文本大号 */
/* 样式描述:常规大按钮 */
font-family: SourceHanSansBold;
font-size: 36rpx;
line-height: normal;
letter-spacing: 0px;
/* 正文色/正文色 */
color: #FFFFFF;
}
</style>
+360
View File
@@ -0,0 +1,360 @@
<template>
<view class="content">
<myNav :title="title" bgColor="nonoe" titleColor="#614D49" :backIcon="true" :backHome="false" :flex="false">
</myNav>
<view style="display: flex;flex-direction: column;align-items: center;overflow-y: auto; ">
<view style="height: 100%;padding-bottom: 220rpx;display: flex;flex-direction: column;align-items: center;">
<image src="/static/n-test/test-bg-n.png" style="width: 750rpx;height: 420rpx;"></image>
<!-- 评测卡片 -->
<view class="card">
<view style="border-radius: 10px 10px 0px 0px;background: linear-gradient(180deg, #FFE7D9 0%, rgba(255, 255, 255, 0) 98%);
height: 60rpx;width: 670rpx;opacity: 1;">
<image :src="showData.testPic" style="width: 88rpx;height: 88rpx;border-radius: 558rpx;
border: 8rpx solid #FFFFFF;margin-left: 92rpx;margin-top: -48rpx;"></image>
</view>
<view style="padding-left: 40rpx;padding-right: 40rpx;display: flex;flex-direction: column;">
<text class="card-title">{{showData.testName}}</text>
<view style="display: flex;align-items: center;">
<image src="/static/n-test/hz-icon.png" style="width: 48rpx;height: 48rpx;"></image>
<text class="card-subtitle">{{showData.subTitle}}</text>
</view>
</view>
<view class="stats">
<!-- <image src="@/static/fire-icon.png" class="fire-icon"></image> -->
<image src="/static/n-test/icon1.png" style="width: 14rpx;height: 18rpx;margin-right: 10rpx;">
</image>
<text v-if="showData.questionDetailVOList&&showData.questionDetailVOList.length>0"
class="stats-text"
style="margin-right: 50rpx;">{{showData.questionDetailVOList.length}}道精选题</text>
<image src="/static/n-test/icon2.png" style="width: 16.54rpx;height: 17.5rpx;margin-right: 10rpx;">
</image>
<text class="stats-text">{{showData.showNum}}人已测</text>
</view>
</view>
<view style="display: flex;justify-content: center;height: 284rpx;">
<view class="introduce-card" style="">
<view style="width: 670rpx;height: 60rpx;
border-radius: 10rpx 10rpx 0rpx 0rpx;opacity: 1;
background: linear-gradient(180deg, #DEE8FF 0%, rgba(255, 255, 255, 0) 98%);">
</view>
<view style="display: flex;flex-direction: column;overflow-y: auto;margin-top: -28rpx;">
<view style="display: flex;padding-left: 40rpx;padding-right: 40rpx;flex-direction: column;">
<view style="display: flex;align-items: center;">
<view style="width: 12rpx;height: 38rpx;background: #99B1FF;border-radius: 180rpx;">
</view>
<text style="color: #614D49;margin-left: 6rpx;
font-family: SourceHanSansBold;ont-variation-settings: 'opsz' auto;
font-size: 40rpx;
line-height: normal;
text-align: center;
letter-spacing: 0px;">
测评介绍
</text>
</view>
<rich-text class="rich-text" :nodes="showData.testIntroduction"></rich-text>
</view>
</view>
</view>
</view>
<view style="display: flex;justify-content: center;margin-top: 20rpx;height: 284rpx;">
<view class="introduce-card" style="">
<view style="width: 670rpx;height: 60rpx;
border-radius: 10rpx 10rpx 0rpx 0rpx;opacity: 1;
background: linear-gradient(180deg, #DEE8FF 0%, rgba(255, 255, 255, 0) 98%);">
</view>
<view style="display: flex;flex-direction: column;overflow-y: auto;margin-top: -28rpx;">
<view style="display: flex;padding-left: 40rpx;padding-right: 40rpx;flex-direction: column;">
<view style="display: flex;align-items: center;">
<view style="width: 12rpx;height: 38rpx;background: #99B1FF;border-radius: 180rpx;">
</view>
<text style="color: #614D49;margin-left: 6rpx;
font-family: SourceHanSansBold;ont-variation-settings: 'opsz' auto;
font-size: 40rpx;
line-height: normal;
text-align: center;
letter-spacing: 0px;">
测评须知
</text>
</view>
<rich-text class="rich-text" :nodes="showData.testNotice"></rich-text>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 立即测评按钮 -->
<view class="button-container">
<button class="start-btn" @click="startTest"><text class="btn-text">立即测评</text></button>
</view>
</view>
</template>
<script setup>
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
const title = ref("")
const showData = ref({})
onLoad((option) => {
if (option && option.id) {
dohttp.post(urls.getSingleDetail + "?studyId=" + option.id).then((result) => {
if (result) {
if (result.totalNum && Number(result.totalNum) >= 10000) {
result.showNum = (Number(result.totalNum) / 10000).toFixed(1) + "W"
} else {
result.showNum = result.totalNum
}
title.value = result.testName
showData.value = result
}
})
}
//计算滑动块的高度
let sysInfo = uni.getSystemInfoSync(); //状态栏的高度
// 胶囊位置信息
let rect = uni.getMenuButtonBoundingClientRect();
// 导航栏高度
let navBarHeight = (rect.top - sysInfo.statusBarHeight) * 2 + rect.height;
// 自定义导航栏的高度
let topHeight = sysInfo.statusBarHeight + navBarHeight;
const windowWidth = sysInfo.windowWidth; // 可用窗口宽度(px
const bottomPx = 184 / (750 / windowWidth)
let contextHeight = sysInfo.screenHeight - topHeight - bottomPx
console.log("contextHeightcontextHeightcontextHeightcontextHeight", contextHeight)
})
const onShareAppMessage = () => {
return {
title: '快来体验一下吧~',
path: '/pages/index/index', // 分享的路径
};
};
const onShareTimeline = () => {
return {
title: '快来体验一下吧~',
query: 'id=31', // 分享路径的参数
};
};
const startTest = () => {
let data = {
data: showData.value.questionDetailVOList,
showTitle: showData.value.testName,
testPic: showData.value.testPic,
testId: showData.value.id
}
dohttp.navigateTo("/pages/show-question/show-question", data)
}
</script>
<style>
.content {
width: 100vw;
height: 100vh;
background-color: #f9f8f8;
display: flex;
flex-direction: column;
font-family: SourceHanSans;
}
/* 评测卡片 */
.card {
background: #FFFFFF;
margin: -26rpx 40rpx 20rpx 40rpx;
border-radius: 10rpx;
height: 284rpx;
width: 670rpx;
display: flex;
flex-direction: column;
/* padding-left: 40rpx;
padding-right: 40rpx; */
}
.card-title {
font-size: 40rpx;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
color: #614D49;
margin-top: 12rpx;
font-family: SourceHanSansBold;
}
.card-subtitle {
font-family: SourceHanSans;
font-size: 28rpx;
font-weight: normal;
line-height: normal;
text-align: center;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
/* 正文色/正文辅助4 */
color: #9B918C;
}
.stats {
display: flex;
align-items: center;
justify-content: flex-end;
padding-bottom: 40rpx;
color: #909099;
margin-top: auto;
font-family: SourceHanSansBold;
font-size: 20rpx;
line-height: normal;
text-align: center;
letter-spacing: 0px;
font-variation-settings: "opsz" auto;
padding-left: 40rpx;
padding-right: 40rpx;
}
.fire-icon {
width: 36rpx;
height: 36rpx;
margin-right: 10rpx;
}
.stats-text {
font-size: 22rpx;
color: #909099;
}
/* 评测介绍 & 评测须知 */
.section {
background: white;
margin: 20rpx 30rpx;
padding: 20rpx 40rpx;
margin-top: 5rpx;
border-radius: 10rpx;
box-shadow: 0rpx 8rpx 16rpx rgba(0, 0, 0, 0.05);
height: 210rpx;
overflow-y: auto;
}
.section-header {
display: flex;
align-items: center;
margin-bottom: 20rpx;
}
.blue-bar {
width: 12rpx;
height: 34rpx;
background-color: #7f75ff;
margin-right: 5rpx;
}
.section-title {
font-size: 36rpx;
font-family: SourceHanSansBold;
color: #333;
}
.bold {
font-family: SourceHanSansBold;
}
.description {
font-size: 28rpx;
color: #666;
line-height: 1.6;
margin-top: 10rpx;
}
/* 按钮 */
.button-container {
bottom: 0;
position: fixed;
height: 184rpx;
width: 100%;
text-align: center;
background: #FFFFFF;
box-shadow: 0px 4rpx 12rpx 0px rgba(67, 33, 26, 0.3);
}
.start-btn {
margin-top: 24rpx;
width: 550rpx;
height: 96rpx;
border-radius: 2002rpx;
opacity: 1;
/* 自动布局 */
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 4rpx 20rpx;
background: linear-gradient(180deg, #FF9079 0%, #F37155 100%);
}
.btn-text {
/* 按钮/按钮文本大号 */
/* 样式描述:常规大按钮 */
font-family: SourceHanSansBold;
font-size: 36rpx;
line-height: normal;
letter-spacing: 0px;
/* 正文色/正文色 */
color: #FFFFFF;
}
/* 评测卡片 */
.introduce-card {
width: 670rpx;
height: 284rpx;
border-radius: 32rpx;
background: #FFFFFF;
display: flex;
flex-direction: column;
}
.rich-text {
margin-top: 20rpx;
font-family: Source Han Sans;
font-size: 24rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0rpx;
font-variation-settings: "opsz" auto;
/* 正文色/正文辅助4 */
color: #606271;
}
</style>
+251
View File
@@ -0,0 +1,251 @@
<template>
<view class="content">
<view class="banner"></view>
<view class="page">
<myNav title="心理测评" bgColor="nonoe" titleColor="#614D49" :backIcon="false" :backHome="false" :flex="false">
</myNav>
<scroll-view :scroll-y="enableScroll" @scrolltolower="scrolltolower" class="scroll-style">
<view ref="contentRef" id="contentContainer" style="display:flex;align-items:center;flex-direction:column;margin-top: 10rpx;">
<view v-for="(item,index) in testList" :key="index" style="width: 630rpx;display: flex;
align-items: center;justify-content: space-between;background:#FFFFFF;padding: 20rpx;border-radius: 10rpx;">
<view style="display: flex;">
<image :src="item.testPic" style="width: 140rpx;height: 140rpx;border-radius: 10rpx;">
</image>
<view style="display: flex;flex-direction: column;margin-left: 20rpx;">
<text style="color: #614D49;
font-family: SourceHanSansBold;ont-variation-settings: 'opsz' auto;
font-size: 28rpx;
line-height: normal;
letter-spacing: 0px;">
{{item.testName}}
</text>
<view style="margin-top: 8rpx;display: flex;align-items: center;">
<!-- <image src="/static/n-main/fire-icon.png" style="width:19.04rpx ;height:26.28rpx ;"> -->
<!-- </image> -->
<view style="width: fit-content;margin-left: 10rpx;
border-radius: 32rpx;
display: flex;
text-align: center;
justify-content: center;
padding-top: 4rpx;
padding-bottom: 4rpx;
padding-left: 10rpx;
padding-right: 10rpx;
border: 1px solid #EA8D7A;">
<text style="color: #F37155;
font-family: SourceHanSans;ont-variation-settings: 'opsz' auto;
font-size: 20rpx;
font-weight: normal;
letter-spacing: 0px;">
{{item.showNum}}人已测
</text>
</view>
</view>
<text style="color: #9B918C;margin-top: 26rpx;
font-family: SourceHanSans;ont-variation-settings: 'opsz' auto;
font-size: 20rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0px;">
{{item.subTitle}}
</text>
</view>
</view>
<view style="width:fit-content;
height: fit-content;
border-radius: 2002rpx;
opacity: 1;
display: flex;
padding: 8rpx 40rpx;justify-content: center;align-items: center;
background: linear-gradient(180deg, #FF9079 0%, #F37155 100%);" @click="goTest(item)">
<text style="color: #FFFFFF;
font-family: SourceHanSans;ont-variation-settings: 'opsz' auto;
font-size: 28rpx;
font-weight: normal;
line-height: normal;
letter-spacing: 0px;">
测评
</text>
</view>
</view>
<view v-if="testList.length==0" style="margin-top: 50%;">
<text style="color: #303044;
font-family: SourceHanSansBold;ont-variation-settings: 'opsz' auto;
font-size: 28rpx;
line-height: normal;
letter-spacing: 0px;">
暂无测评信息
</text>
</view>
</view>
</scroll-view>
</view>
</view>
</template>
<script setup>
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
const testList = ref([])
onMounted(() => {
getPsychicTest()
})
const getPsychicTest = () => {
dohttp.post(urls.getPsychicListTest).then((result) => {
console.log("getPsychicTestgetPsychicTestgetPsychicTest", result)
if (result) {
result.forEach((ele) => {
if (ele.totalNum && Number(ele.totalNum) >= 10000) {
ele.showNum = (Number(ele.totalNum) / 10000).toFixed(1) + "W"
} else {
ele.showNum = ele.totalNum
}
})
}
testList.value = result
// 确保图片加载完成
nextTick(() => {
setTimeout(() => {
checkContentHeight()
// 添加重试机制
if (!enableScroll.value) setTimeout(checkContentHeight, 500)
}, 300)
})
})
}
const goTest = (item) => {
dohttp.navigateTo("/pages/test-detail/test-detail?id=" + item.id)
}
// 新增代码
import {
ref,
onMounted,
nextTick,
getCurrentInstance
} from 'vue'
const showHight = ref(0)
const instance = getCurrentInstance()
const enableScroll = ref(false) // 新增动态滚动控制
onLoad(() => {
const systemInfo = uni.getSystemInfoSync()
// 更精准的高度计算
showHight.value = (systemInfo.windowHeight * (750 / systemInfo.screenWidth)) - 180
})
// 新增高度检查方法
const checkContentHeight = () => {
const query = uni.createSelectorQuery().in(instance.proxy)
query.select('#contentContainer').boundingClientRect(rect => {
if (rect) {
const systemInfo = uni.getSystemInfoSync()
// 转换为rpx比较
// 计算容器实际像素高度
const containerHeightPx = (showHight.value * systemInfo.screenWidth) / 750
const threshold = 5 // 容错阈值
enableScroll.value = rect.height > (containerHeightPx + threshold)
console.log('[Layout Debug]', {
contentHeight: rect.height,
containerPx: containerHeightPx,
containerRpx: showHight.value,
shouldScroll: enableScroll.value
})
}
}).exec()
}
const onShareAppMessage = () => {
return {
title: '快来体验一下吧~',
path: '/pages/index/index', // 分享的路径
};
};
const onShareTimeline = () => {
return {
title: '快来体验一下吧~',
query: 'id=3', // 分享路径的参数
};
};
// 初始加载检查
onMounted(() => {
nextTick(checkContentHeight)
})
</script>
<style scoped>
.content {
width: 100vw;
height: 100vh;
background-image: url('https://miniapp.yuxingu.com.cn/yxg-mp/pic/test-list-bg.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
display: flex;
flex-direction: column;
position: relative;
}
.page {
position: absolute;
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
}
.banner {
background-image: url('https://miniapp.yuxingu.com.cn/yxg-mp/pic/botton.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
width: 750rpx;
height: 660rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: absolute;
z-index: 0;
}
/* 修改 #contentContainer 样式 */
#contentContainer {
width: 100%;
min-height: 100%;
/* 新增关键属性 */
flex-shrink: 0;
/* 禁止收缩 */
overflow: visible;
/* 确保子元素不被裁剪 */
}
.scroll-style {
box-sizing: border-box;
padding: 0 !important;
/* 清除可能的内边距 */
}
</style>
+203
View File
@@ -0,0 +1,203 @@
<template>
<view class="content">
<myNav :title="showData.testName" bgColor="nonoe" titleColor="#614D49" :backIcon="backIcon" :backHome="false"
:flex="false">
</myNav>
<image class="show-header-bg" src="/static/n-test/test-result-bg.png" mode="aspectFill"></image>
<view class="flex-justify-center">
<view class="show-content">
<view class="content-top">
</view>
<view style="display: flex;justify-content: center;margin-top: 45rpx;">
<image src="/static/n-test/result-icon.png" style="width: 160rpx;height:188rpx"></image>
</view>
<view style="margin-top: 60rpx;padding-left: 40rpx;margin-right: 38rpx;">
<view class="section-content" v-if="showData.resultDesc">
<text style="font-size: 38rpx;font-family: 'SourceHanSansBold';">结果描述</text>
<rich-text style="margin-top: 20rpx;" :nodes="showData.resultDesc"></rich-text>
</view>
<view class="section-content" style="margin-top: 40rpx;" v-if="showData.resultAnalysis">
<text style="font-size: 38rpx;font-family: 'SourceHanSansBold';">结果分析</text>
<rich-text style="margin-top: 20rpx;" :nodes="showData.resultAnalysis"></rich-text>
</view>
<view class="section-content" style="margin-top: 40rpx;" v-if="showData.treatPlan">
<text style="font-size: 38rpx;font-family: 'SourceHanSansBold';">治疗方案</text>
<rich-text style="margin-top: 20rpx;" :nodes="showData.treatPlan"></rich-text>
</view>
</view>
</view>
</view>
<view class="button-container" style="margin-top: 60rpx;">
<button class="start-btn" @click="goMainPage"><text class="btn-text">返回主页</text></button>
</view>
</view>
</template>
<script setup>
import myNav from '@/components/my-nav.vue'
import {
urls
} from '@/util/apiUrl.js'
import dohttp from '@/util/requestConfig.js'
const showData = ref({})
const backIcon = ref(false)
onLoad((option) => {
dohttp.post(urls.getResult + "?resultId=" + option.resultId).then((result) => {
showData.value = result
})
let pages = getCurrentPages()
let prePage = pages[pages.length - 2]
if (prePage && prePage.route) {
if (prePage.route == "pages/my-test/my-test") {
backIcon.value = true
}
}
})
const onShareAppMessage = () => {
return {
title: '快来体验一下吧~',
path: '/pages/index/index', // 分享的路径
};
};
const onShareTimeline = () => {
return {
title: '快来体验一下吧~',
query: 'id=33', // 分享路径的参数
};
};
const goMainPage = () => {
uni.switchTab({
url: "/pages/index/index",
animationType: "pop-in"
})
}
</script>
<style scoped>
.content {
width: 100vw;
height: 100vh;
background-color: #f9f8f8;
display: flex;
flex-direction: column;
font-family: 'pingfang';
box-sizing: border-box;
}
/* 顶部图片 */
.show-header-bg {
width: 750rpx;
height: 420rpx;
}
.show-content {
width: 670rpx;
border-radius: 10rpx;
opacity: 1;
/* 自动布局 */
display: flex;
flex-direction: column;
background: #FFFFFF;
margin-top: -20rpx;
height: 844rpx;
overflow-y: auto;
}
.content-top {
width: 670rpx;
height: 60rpx;
border-radius: 10rpx 10rpx 0rpx 0rpx;
opacity: 1;
background: linear-gradient(180deg, #FFE7D9 0%, rgba(255, 255, 255, 0) 98%);
}
.blue-bar {
width: 12rpx;
height: 42rpx;
background-color: #7f75ff;
margin-right: 5rpx;
}
.section-title {
font-size: 45rpx;
font-family: SourceHanSansBold;
color: #333;
}
.description {
font-size: 28rpx;
color: #666;
line-height: 1.6;
margin-top: 10rpx;
}
.section {
background: white;
margin: 20rpx 30rpx;
padding: 20rpx 40rpx;
margin-top: 5rpx;
border-radius: 10rpx;
box-shadow: 0rpx 8rpx 16rpx rgba(0, 0, 0, 0.05);
flex-grow: 1;
overflow-y: auto;
}
.section-content {
display: flex;
flex-direction: column;
}
.button-container {
text-align: center;
margin-top: auto;
margin-bottom: 60rpx;
}
.start-btn {
width: 550rpx;
height: 96rpx;
border-radius: 2002rpx;
opacity: 1;
/* 自动布局 */
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 8rpx 40rpx;
background: linear-gradient(180deg, #E84B2A 0%, #FF846A 100%);
}
.flex-justify-center {
display: flex;
justify-content: center;
}
.btn-text{
/* 按钮/按钮文本大号 */
/* 样式描述:常规大按钮 */
font-family: SourceHanSansBold;
font-size: 36rpx;
font-weight: bold;
line-height: normal;
letter-spacing: 0px;
/* 正文色/正文色 */
color: #FFFFFF;
}
</style>