Commit 3c380543 authored by weishengfei's avatar weishengfei

refactor: 删除旧的产检详情页面代码

- 移除了 productionDetailsOld.vue 文件的全部内容
- 这个文件可能已经过时或被新版本替换,因此删除了所有代码
parent 51b33414
<template>
<view class="production-details">
<!-- tab 切换 -->
<view class="production-details-tabs" :class="{ 'fixed-tabs': isFixedTabs, 'hidden-tabs': !showTabs }" ref="tabsRef">
<view class="custom-tabs">
<view v-for="(tab, index) in tabInfo" :key="index" class="tab-item"
:class="{ active: activeIndex === index }" @click="scrollToSection(index)">
<view class="tab-line1">{{ tab?.line1 }}</view>
<view class="tab-line2" v-if="activeIndex === index"></view>
</view>
</view>
</view>
<!-- 内容区域 -->
<!-- <scroll-view class="content-scroll" scroll-y :scroll-top="scrollTop" @scroll="handleScroll"
scroll-with-animation> -->
<view class="production-details-container" id="content-container">
<view class="container-1 pad">
{{ infoData.index }}次检查
</view>
<view class="container-2 pad">
<view class="container-2-l">
孕期{{ infoData.pregnancyWeek }}
</view>
<view class="container-2-r">
<view class="r-complete" @click="onComplete">
<image v-if="!isCompleted" src="/static/chanjianTool/icon24.png"></image>
<image v-else src="/static/chanjianTool/icon25.png"></image>
完成检查
</view>
<view class="r-remind" @click="onRemind">
<image src="/static/chanjianTool/icon26.png"></image>
</view>
</view>
</view>
<view class="container-line pad">
</view>
<view class="container-3 pad">
<view class="container-3-l">
产检时间
</view>
<view class="container-3-r" @click="onChangeTime(infoData.checkupDate)">
{{ infoData.checkupDate ? infoData.checkupDate : '选择时间' }}
<image src="/static/chanjianTool/edit.png"></image>
</view>
</view>
<view class="container-4 pad">
建议时间:{{ infoData.suggestionCheckup}}
</view>
<!-- 产检须知 -->
<view class="project-box" id="section-0">
<view class="project-info">
<view class="time-l">
<image src="/static/chanjianTool/icon19.png" />
产检须知
</view>
</view>
<view class="project-content">
<rich-text class="desc" :nodes="infoData.content"></rich-text>
</view>
</view>
<!-- 产检项目 -->
<view class="project-box" id="section-1">
<view class="project-info">
<view class="time-l">
<image src="/static/chanjianTool/icon19.png" />
产检项目
</view>
<view class="style1" @click="onModify(infoData)">
修改项目
</view>
</view>
<view class="project-content">
<view class="project-list" v-for="(item, index) in infoData.examinationItems" :key="index">
<view class="list-itemName">
{{ numberToChinese(index + 1) }}{{ item.itemName }}
</view>
<view class="list-introduction">
<rich-text :nodes="item.introduction"></rich-text>
</view>
</view>
</view>
</view>
<!-- 本次报告单 -->
<view class="project-box" id="section-2">
<view class="project-info">
<view class="time-l">
<image src="/static/chanjianTool/icon19.png" />
本次报告单
</view>
<view class="time-r style2" @click="onSeeBtn">
查看全部
<image src="/static/chanjianTool/icon13.png" />
</view>
</view>
<view class="img-list">
<view class="upload-image" @click="onUpload">
<image src="/static/chanjianTool/icon11.png"></image>
</view>
<view class="img-list-item" v-for="(item, index) in bgdImgList" :key="index">
<view class="item-image" @click="onPreviewImage(item)">
<image class="img1" :src="item" mode="widthFix"></image>
</view>
<image @click="onImageDel(item)" class="img" src="/static/chanjianTool/icon14.png"></image>
</view>
</view>
</view>
<!-- 选择提醒弹窗 -->
<view>
<!-- 底部弹窗遮罩层 -->
<view v-if="showPicker" class="picker-layer-mask" @click="close"></view>
<!-- 弹窗内容区 -->
<view v-if="showPicker" class="picker-layer-popup">
<view class="picker-layer-panel">
<view class="picker-layer-title">
设置提醒时间
</view>
<view class="picker-layer-content">
<view class="content-item"
v-for="(item, index) in options"
:key="index"
:class="{'item-active': pickerValue === index}"
@click="handleChange(index)"
>
{{ item.name }}
</view>
</view>
<view class="picker-layer-bottom">
<text class="bottom-close btn" @click="close">取消</text>
<text class="bottom-confirm btn" @click="handleConfirm">确定</text>
</view>
</view>
</view>
</view>
</view>
<!-- </scroll-view> -->
<!-- 产检选择时间 -->
<!-- 使用封装后的日期选择器组件 -->
<DatePicker v-model:visible="visible" :default-date="time" @confirm="handleDateConfirm" />
</view>
</template>
<script setup>
import {
ref,
onMounted
} from 'vue'
import {
onLoad,
onPageScroll
} from '@dcloudio/uni-app'
import {
throttleTap,
showLoading,
hideLoading
} from '@/utils/index.js';
// 时间组件
import DatePicker from '@/components/DatePicker.vue'
import { uploadImage } from '../../api/common.js'
import {
getDetail,
getUpdate,
getWxNotification
} from '../../api/obstetric.js';
// 提醒选择器相关状态
const showPicker = ref(false)
const options = [
{
name: '当天',
id: 0
},
{
name: '前一天',
id: 1
},
{
name: '前三天',
id: 3
}
] // 提醒时间选项
const pickerValue = ref(0) // 当前选中的索引
const selectedValue = ref(0) // 选中的值
const tabInfo = [{
"line1": "产检须知",
},
{
"line1": "产检项目",
},
{
"line1": "本次报告单",
}
]
// 存储id
const editId = ref('')
// 详情
const infoData = ref({})
// 临时储存报告单
const bgdImgList = ref([])
// 时间组件参数
const time = ref('')
// 新增完成状态
const isCompleted = ref(false)
// 日期选择器
const visible = ref(false)
// 新增ref
const tabsRef = ref(null)
const tabsHeight = ref(50) // 默认值,实际会在mounted中获取
// 滚动相关状态
const isFixedTabs = ref(false)
const showTabs = ref(false)
const activeIndex = ref(0)
const sectionPositions = ref([])
// 获取各section和tabs的高度信息
const getPositions = () => {
return new Promise((resolve) => {
const query = uni.createSelectorQuery()
// 获取tabs高度
query.select('.production-details-tabs').boundingClientRect()
// 获取各section位置
query.select('#content-container').boundingClientRect()
query.select('#section-0').boundingClientRect()
query.select('#section-1').boundingClientRect()
query.select('#section-2').boundingClientRect()
query.exec((res) => {
if (res[0] && res[1] && res[2] && res[3] && res[4]) {
// 获取tabs实际高度
tabsHeight.value = res[0].height
const containerTop = res[1].top
sectionPositions.value = [
res[2].top - containerTop - tabsHeight.value + 5, // 加5px微调,使内容更靠近tabs
res[3].top - containerTop - tabsHeight.value + 5,
res[4].top - containerTop - tabsHeight.value + 5
]
resolve()
}
})
})
}
// 页面滚动处理
onPageScroll(throttleTap((e) => {
const scrollTop = e.scrollTop
// 控制tabs显示/隐藏
if (scrollTop <= 10) { // 更小的阈值
showTabs.value = false
isFixedTabs.value = false
} else {
showTabs.value = true
isFixedTabs.value = true
}
// 更新当前激活的tab
updateActiveTab(scrollTop)
}, 100)) // 添加节流
// 更新当前激活的tab
const updateActiveTab = (scrollTop) => {
if (sectionPositions.value.length === 0) return
// 调整阈值,使切换更精准
const offset = tabsHeight.value + 10
if (scrollTop >= sectionPositions.value[2] - offset) {
activeIndex.value = 2
} else if (scrollTop >= sectionPositions.value[1] - offset) {
activeIndex.value = 1
} else if (scrollTop >= sectionPositions.value[0] - offset) {
activeIndex.value = 0
}
}
// 点击tab滚动到对应区域
const scrollToSection = (index) => {
if (sectionPositions.value.length === 0) return
// 更精确的滚动位置计算
let targetPosition = sectionPositions.value[index]
// 如果是第一个section,滚动到顶部
if (index === 0) {
targetPosition = 0
}
// 平滑滚动到目标位置
uni.pageScrollTo({
scrollTop: targetPosition,
duration: 300,
success: () => {
activeIndex.value = index
}
})
}
onMounted(() => {
// 获取各section和tabs位置信息
setTimeout(() => {
getPositions().then(() => {
// 初始显示第一个tab
activeIndex.value = 0
})
}, 500) // 稍长延时确保DOM渲染完成
})
// 滚动处理函数
const handleScroll = (e) => {
const scrollTop = e.detail.scrollTop;
const scrollDirection = scrollTop > lastScrollTop.value ? 'down' : 'up';
// 优化:更灵敏的 tabs 显示/隐藏逻辑
if (scrollTop <= 0) {
// 滚动到顶部时立即隐藏 tabs
showTabs.value = false;
isFixedTabs.value = false;
} else if (scrollDirection === 'down' && scrollTop > 50) {
// 向下滚动超过阈值时显示固定 tabs
showTabs.value = true;
isFixedTabs.value = true;
} else if (scrollDirection === 'up') {
// 向上滚动时保持显示 tabs
showTabs.value = true;
isFixedTabs.value = true;
}
lastScrollTop.value = scrollTop;
// 优化:只在滚动停止时更新 activeIndex
if (scrolling.value) return;
updateActiveTab(scrollTop);
}
// 更新当前激活的tab
const updateActiveTab = (scrollTop) => {
const query = uni.createSelectorQuery()
query.select('#section-0').boundingClientRect()
query.select('#section-1').boundingClientRect()
query.select('#section-2').boundingClientRect()
query.exec((res) => {
const [section0, section1, section2] = res
// 优化:使用更精确的阈值计算
const threshold = 50 // 距离顶部的阈值
if (scrollTop >= section2.top - threshold) {
activeIndex.value = 2
} else if (scrollTop >= section1.top - threshold) {
activeIndex.value = 1
} else {
activeIndex.value = 0
}
})
}
// 点击tab滚动到对应区域
const scrollToSection = (index) => {
activeIndex.value = index;
scrolling.value = true;
const query = uni.createSelectorQuery();
query.select(`#section-${index}`).boundingClientRect();
query.select('.content-scroll').scrollOffset(); // 获取 scroll-view 当前的滚动位置
query.exec((res) => {
if (res[0] && res[1]) {
const sectionTop = res[0].top; // 目标区域距离视口顶部的距离
const currentScrollTop = res[1].scrollTop; // scroll-view 当前的滚动位置
const fixedTabsHeight = 120; // 固定 tabs 的高度(根据实际样式调整)
// 计算新的滚动位置
scrollTop.value = currentScrollTop + sectionTop - fixedTabsHeight;
}
setTimeout(() => {
scrolling.value = false;
}, 300);
});
}
// 更完整的转换函数(支持0-99)
const numberToChinese = (num) => {
const chineseNumbers = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
const units = ['', '十'];
if (num === 0) return chineseNumbers[0];
if (num <= 10) return num === 10 ? '十' : chineseNumbers[num];
let str = '';
if (num > 10 && num < 20) {
str = '十' + chineseNumbers[num % 10];
} else if (num >= 20 && num < 100) {
str = chineseNumbers[Math.floor(num / 10)] + '十' + chineseNumbers[num % 10];
} else {
return num.toString(); // 超过范围返回原数字
}
return str.replace(/零$/, ''); // 去掉末尾的零
}
// 图片预览
const onPreviewImage = (url) => {
console.log(url)
uni.previewImage({
current: '1',
urls: [url]
})
}
// 删除上传图片
const onImageDel = (id) => {
bgdImgList.value.filter((item, index) => {
if (item === id) {
bgdImgList.value.splice(index, 1)
}
})
console.log("🚀 ~ bgdImgList.value.filter ~ bgdImgList:", bgdImgList)
// 直接保存
const params = {
id: editId.value,
reportImages: bgdImgList.value
}
onEditTime(params)
}
// 上传图片
const onUpload = throttleTap(() => {
if (bgdImgList.value.length == 15) {
uni.showToast({
title: "最多上传15张图片",
icon: "none",
});
return;
}
// 唤起图片选择器
uni.chooseImage({
count: 15,
sizeType: ["original", "compressed"],
sourceType: ["album", "camera"],
success: async (res) => {
showLoading();
const tempFilePath = res.tempFilePaths[0];
console.log(tempFilePath)
const fs = uni.getFileSystemManager();
console.log(fs)
const base64 =
"data:image/jpeg;base64," + fs.readFileSync(tempFilePath, "base64");
const uploadRes = await uploadImage(base64);
hideLoading();
if (uploadRes.success) {
console.log(uploadRes)
bgdImgList.value.push(uploadRes.data.url)
console.log("🚀 ~ success: ~ bgdImgList:", bgdImgList)
// 直接保存
const params = {
id: editId.value,
reportImages: bgdImgList.value
}
onEditTime(params)
} else {
uni.showToast({
title: uploadRes.message,
icon: "none",
});
}
},
});
})
// 查看更多
const onSeeBtn = () => {
uni.navigateTo({
url: '/pages/myReportCard/myReportCard'
})
}
// 打开提醒弹窗
const onRemind = () => {
showPicker.value = true;
}
// 提醒关闭
const close = () => {
showPicker.value = false;
}
// 选择提醒事件
const handleChange = (e) => {
pickerValue.value = e;
}
// 确认选择
const handleConfirm = () => {
selectedValue.value = options[pickerValue.value].id;
close();
// 订阅提醒
uni.requestSubscribeMessage({
tmplIds: [infoData.wxTemplateId],
success(res) {
console.log(res)
getWxNotificationFn(selectedValue.value, infoData.wxTemplateId, infoData.value.id)
},
fail(res) {
console.log(res)
}
})
}
// 保存订阅消息
const getWxNotificationFn = async (notificationTimeType, wxTemplateId, examinationRecordId)=>{
const params = {
type: 1,
notificationTimeType,
wxTemplateId,
examinationRecordId,
}
const { code, message, data, success } = await getWxNotification(params)
if(success){
uni.showToast({
title: '保存成功',
icon: 'success',
duration: 2000
})
} else {
uni.showToast({
title: message,
icon: 'none'
})
}
}
// 完成检查
const onComplete = () => {
if(infoData.value.checkupDate == ''){
uni.showToast({
title: '请选择产检日期',
icon: 'none',
duration: 2000
})
return
}
// 切换状态
isCompleted.value = !isCompleted.value
console.log(isCompleted.value)
const params = {
id: editId.value,
status: isCompleted.value ? 'completed' : 'pending'
}
onEditTime(params)
}
// 修改时间
const onChangeTime = throttleTap((date) => {
visible.value = true
time.value = date
})
// 选择时间
const handleDateConfirm = (date) => {
visible.value = false
time.value = date
const params = {
id: editId.value,
checkupDate: time.value
}
onEditTime(params)
}
// 修改项目
const onModify = (item) => {
console.log(item)
const items = JSON.stringify(item)
uni.navigateTo({
url: `/pages/editPostnatal/editPostnatal?item=${items}`
})
}
// 修改产检接口
const onEditTime = async (params) => {
console.log(params)
const { code, success, message } = await getUpdate(params)
if (success) {
// 重新获取信息
getDetailFn(editId.value)
} else {
uni.showToast({
title: message,
icon: 'none'
})
}
}
// 获取详情接口
const getDetailFn = async (id) => {
console.log('获取信息', id)
// 获取信息
const {code, success, message, data } = await getDetail({id})
if (success) {
infoData.value = data
bgdImgList.value = data.reportImages
isCompleted.value = data.status === 'completed'
} else {
uni.showToast({
title: message,
icon: "none",
});
}
}
// 获取传过来的参数
onLoad((options) => {
console.log(options)
editId.value = options.id
getDetailFn(options.id)
})
</script>
<style lang="less" scoped>
.production-details {
position: relative;
height: 100vh;
overflow: hidden;
background: #fef7f2;
&-tabs {
width: 100%;
height: auto;
margin-top: 22rpx;
background: #ffffff;
transition: all 0.3s;
z-index: 100;
&.fixed-tabs {
position: fixed;
top: 0;
left: 0;
right: 0;
margin-top: 0;
background: #fff;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
height: 120rpx;
}
.custom-tabs {
display: flex;
justify-content: space-between;
padding: 55rpx 42rpx 32rpx 48rpx;
box-sizing: border-box;
.tab-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
position: relative;
&.active {
.tab-line1 {
color: #000000;
}
}
.tab-line1 {
font-size: 28rpx;
font-weight: bold;
color: #6f6d67;
line-height: 35rpx;
}
.tab-line2 {
position: absolute;
bottom: -8rpx;
left: 50%;
transform: translateX(-50%);
width: 28rpx;
height: 4rpx;
background: #d3a358;
border-radius: 6rpx;
}
}
}
}
.content-scroll {
height: 100vh;
box-sizing: border-box;
/* 给固定tabs留出空间 */
// padding-top: 120rpx;
}
&-container {
padding: 50rpx 35rpx;
box-sizing: border-box;
color: #000000;
.pad {
padding-left: 13rpx;
box-sizing: border-box;
}
.container-1 {
font-size: 24rpx;
font-weight: bold;
}
.container-2 {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 20rpx;
.container-2-l {
font-size: 38rpx;
color: #b27c1e;
font-weight: bold;
}
.container-2-r {
font-size: 24rpx;
color: #a68dbb;
display: flex;
align-items: center;
.r-complete {
display: flex;
align-items: center;
image {
width: 21rpx;
height: 22rpx;
margin-right: 7rpx;
}
}
.r-remind {
width: 121rpx;
height: 35rpx;
margin-left: 22rpx;
image {
width: 100%;
height: 100%;
}
}
}
}
.container-line {
width: 100%;
height: 1rpx;
background: #f7e4cd;
margin: 30rpx 0;
}
.container-3 {
display: flex;
align-items: center;
justify-content: space-between;
.container-3-l {
font-size: 28rpx;
color: #000000;
font-weight: bold;
}
.container-3-r {
display: flex;
align-items: center;
font-size: 28rpx;
line-height: 26rpx;
image {
width: 21rpx;
height: 21rpx;
margin-left: 15rpx;
margin-top: 1rpx;
}
}
}
.container-4 {
font-size: 24rpx;
color: #6f6d67;
margin: 20rpx 0 45rpx 0;
}
.project-box {
background: #ffffff;
border-radius: 24rpx;
padding: 0 27rpx 35rpx 27rpx;
box-sizing: border-box;
// width: 682rpx;
box-shadow: 0 4rpx 12rpx rgba(253, 240, 223, 0.8);
margin-bottom: 35rpx;
}
.project-info {
// width: 682rpx;
height: 105rpx;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 32rpx;
border-bottom: 1rpx solid #f7e4cd;
margin-bottom: 25rpx;
.time-l,
.time-r {
display: flex;
align-items: center;
}
.time-l {
color: #000000;
font-weight: 600;
image {
width: 32rpx;
height: 32rpx;
margin-right: 10rpx;
}
}
.style1 {
width: 121rpx;
height: 35rpx;
text-align: center;
line-height: 35rpx;
border-radius: 17.5rpx;
border: 1px solid #b27c1e;
font-size: 24rpx;
color: #b27c1e;
}
.style2 {
font-size: 24rpx;
color: #1d1e26;
image {
width: 8rpx;
height: 16rpx;
margin-left: 12rpx;
}
}
}
.project-content {
.project-list {
.list-itemName {
font-size: 28rpx;
font-weight: bold
}
.list-introduction {
font-size: 26rpx;
}
.list-itemName,
.list-introduction {
margin-bottom: 15rpx;
}
}
}
.img-list {
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
justify-content: flex-start;
.upload-image {
width: 200rpx;
height: 200rpx;
border-radius: 10rpx;
overflow: hidden;
margin-right: 10rpx;
image {
width: 200rpx;
height: 200rpx;
}
}
.img-list-item {
// margin-right: 10rpx;
margin-bottom: 15rpx;
position: relative;
.item-image {
width: 200rpx;
height: 200rpx;
border-radius: 10rpx;
overflow: hidden;
.img1 {
width: 200rpx;
height: 200rpx;
}
}
.img {
position: absolute;
right: -12rpx;
top: -12rpx;
width: 25rpx;
height: 25rpx;
}
}
}
}
/* 遮罩层样式 */
.picker-layer-mask {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 3999;
}
.picker-layer-popup {
position: fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 4000;
display: flex;
flex-direction: column;
align-items: center;
animation: picker-layer-up 0.3s;
}
@keyframes picker-layer-up {
from {
transform: translateY(100%);
}
to {
transform: translateY(0);
}
}
/* 弹窗容器样式 */
.picker-layer-panel {
width: 100vw;
height: 52vh;
background: #f6f8fa;
border-top-left-radius: 24rpx;
border-top-right-radius: 24rpx;
overflow: hidden;
padding: 32rpx;
box-sizing: border-box;
}
.picker-layer-title{
font-size: 34rpx;
color: #000000;
font-weight: bold;
}
.picker-layer-content{
margin-top: 40rpx;
margin-bottom: 50rpx;
.content-item{
width: 100%;
height: 126rpx;
border-radius: 16rpx;
font-size: 28rpx;
display: flex;
align-items: center;
justify-content: center;
border: 2rpx solid #fff;
box-sizing: border-box;
margin-bottom: 20rpx;
background: #ffffff;
}
.item-active{
background: #fffbed;
border-color: #d3a358;
}
}
.picker-layer-bottom {
display: flex;
justify-content: space-between;
align-items: center;
.btn{
width: 334rpx;
height: 97rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: 48.5rpx;
font-size: 38rpx;
}
.bottom-close {
color: #d3a358;
background: #ffffff;
}
.bottom-confirm {
color: #ffffff;
background: #d3a358;
}
}
}
</style>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment