Browse Source

feat: 新增图片预览组件与笔记图片查看功能,优化多个页面样式与交互

1.  新增noteImagePreview图片预览组件,支持分组标注与操作栏控制
2.  在笔记详情、历史记录页面集成图片预览组件,替换原生预览实现
3.  优化拍照裁切比例为4:3,修复前置摄像头镜像翻转问题
4.  调整新增记录页面样式,优化表单布局与按钮样式
5.  为首页新增首次使用笔记引导弹窗
6.  优化图片合并组件的文字绘制逻辑,适配不同像素密度
7.  修复toast组件位置与安全区适配问题
master
kola-web 3 weeks ago
parent
commit
497b53317b
  1. 35
      src/components/image-merge/index.ts
  2. 25
      src/components/noteImagePreview/index.scss
  3. 8
      src/components/noteImagePreview/index.ts
  4. 7
      src/components/noteImagePreview/index.wxml
  5. 9
      src/components/patient-tab-bar/index.scss
  6. 11
      src/components/toast/index.scss
  7. 7
      src/components/toast/index.wxml
  8. 3
      src/pages/d_noteDetail/index.json
  9. 56
      src/pages/d_noteDetail/index.ts
  10. 12
      src/pages/d_noteDetail/index.wxml
  11. 7
      src/patient/components/camera/index.ts
  12. 37
      src/patient/components/image-merge/index.ts
  13. 13
      src/patient/pages/index/index.ts
  14. 12
      src/patient/pages/note/index.scss
  15. 3
      src/patient/pages/note/index.wxml
  16. 23
      src/patient/pages/noteAdd/index.scss
  17. 61
      src/patient/pages/noteAdd/index.ts
  18. 3
      src/patient/pages/noteAdd/index.wxml
  19. 3
      src/patient/pages/noteHistory/index.json
  20. 56
      src/patient/pages/noteHistory/index.ts
  21. 12
      src/patient/pages/noteHistory/index.wxml

35
src/components/image-merge/index.ts

@ -96,11 +96,12 @@ Component({ @@ -96,11 +96,12 @@ Component({
const canvas = res[0].node
const ctx = canvas.getContext('2d')
Promise.all(imageList.map((item) => this.getImageInfo(item.src)))
Promise.all(imageList.map(item => this.getImageInfo(item.src)))
.then((imageInfos) => {
const targetWidth = 750
const pixelRatio = wx.getWindowInfo().pixelRatio
const canvasWidth = Math.floor((targetWidth * pixelRatio) / 2)
const fontScale = pixelRatio / 2
let totalHeight = 0
const scaledHeights: number[] = []
@ -135,29 +136,33 @@ Component({ @@ -135,29 +136,33 @@ Component({
ctx.drawImage(img, 0, yPositions[index], canvasWidth, scaledHeights[index])
const timeText = imageList[index].time || this.formatTime(new Date())
const padding = 20
const textY = yPositions[index] + 40
const padding = 20 * fontScale
const fontSize = Math.round(28 * fontScale)
const textY = yPositions[index] + 40 * fontScale
ctx.font = `bold ${fontSize}px sans-serif`
ctx.textBaseline = 'middle'
const textMetrics = ctx.measureText(timeText)
const bgPaddingH = 16 * fontScale
const bgPaddingV = 10 * fontScale
const bgH = fontSize + bgPaddingV * 2
const bgX = padding - bgPaddingH
const bgY = textY - bgH / 2
const bgW = textMetrics.width + bgPaddingH * 2
ctx.fillStyle = 'rgba(0, 0, 0, 0.45)'
ctx.fillRect(bgX, bgY, bgW, bgH)
ctx.fillStyle = '#ffffff'
ctx.font = 'bold 38px sans-serif'
ctx.textAlign = 'left'
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)'
ctx.shadowBlur = 4
ctx.shadowOffsetX = 1
ctx.shadowOffsetY = 1
ctx.fillText(timeText, padding, textY)
ctx.shadowColor = 'transparent'
ctx.shadowBlur = 0
ctx.shadowOffsetX = 0
ctx.shadowOffsetY = 0
if (index === imageInfos.length - 1) {
const lastImageBottom = yPositions[index] + scaledHeights[index]
ctx.fillStyle = 'rgba(255, 255, 255, 0.8)'
ctx.font = '32px sans-serif'
ctx.font = `${Math.round(24 * fontScale)}px sans-serif`
ctx.textAlign = 'right'
ctx.fillText('由-TED关爱小助手-小程序生成', canvasWidth - 20, lastImageBottom - 20)
ctx.fillText('由-TED关爱小助手-小程序生成', canvasWidth - 20 * fontScale, lastImageBottom - 20 * fontScale)
}
loadedCount++

25
src/components/noteImagePreview/index.scss

@ -29,6 +29,31 @@ @@ -29,6 +29,31 @@
overflow: hidden;
position: relative;
.order {
position: absolute;
left: 50%;
transform: translate(-50%, 0 );
padding: 18rpx 32rpx;
font-size: 40rpx;
font-weight: bold;
text-align: center;
color: #211d2e;
border-radius: 94rpx;
display: inline-flex;
align-items: baseline;
background-color: #fff;
z-index: 10;
white-space: nowrap;
.num {
margin-left: 20rpx;
}
.m-num {
font-size: 28rpx;
}
}
.preview-image {
display: block;
width: 100%;

8
src/components/noteImagePreview/index.ts

@ -19,6 +19,14 @@ Component({ @@ -19,6 +19,14 @@ Component({
type: Number,
value: 0,
},
photoLabels: {
type: Array,
value: [] as { name: string; index: number; total: number }[],
},
showActions: {
type: Boolean,
value: true,
},
},
data: {

7
src/components/noteImagePreview/index.wxml

@ -4,6 +4,11 @@ @@ -4,6 +4,11 @@
</navbar>
<view class="image-wrapper" style="padding-top:{{navHeight}}px;" bindtouchstart="handleTouchStart" bindtouchend="handleTouchEnd">
<view class="order" wx:if="{{photoLabels[currentIndex]}}" style="top:{{navHeight * 0.5}}px;">
{{photoLabels[currentIndex].name}}
<!-- <view class="num">{{photoLabels[currentIndex].index}}</view> -->
<!-- <view class="m-num">/{{photoLabels[currentIndex].total}}</view> -->
</view>
<view class="nav-btn nav-prev {{currentIndex <= 0 ? 'disabled' : ''}}" wx:if="{{images.length > 1}}" bindtap="handlePrev">
<van-icon name="arrow-left" size="20px" color="{{currentIndex <= 0 ? '#666' : '#fff'}}" />
</view>
@ -19,7 +24,7 @@ @@ -19,7 +24,7 @@
<text class="total">{{images.length}}</text>
</view>
<view class="action-bar">
<view class="action-bar" wx:if="{{showActions}}">
<view class="btn btn-delete" bindtap="handleDelete">删除</view>
<view class="btn btn-retake" bindtap="handleRetake">重拍</view>
</view>

9
src/components/patient-tab-bar/index.scss

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
/* custom-tab-bar/index.wxss */
.tab-custom-item {
position: relative;
flex: 1;
z-index: 1;
.circle {
@ -28,6 +29,14 @@ @@ -28,6 +29,14 @@
color: rgba(33, 29, 46, 1);
}
}
.tip-card {
position: absolute;
top: -30rpx;
left: 50%;
width: 390rpx;
height: 230rpx;
transform: translate(-50%, -100%);
}
}
.tab-item {

11
src/components/toast/index.scss

@ -2761,3 +2761,14 @@ @@ -2761,3 +2761,14 @@
}
}
}
.popup-note-guide {
.popup-container {
.guide {
margin: 0 auto 62rpx;
display: block;
width: 660rpx;
height: 673rpx;
}
}
}

7
src/components/toast/index.wxml

@ -4,6 +4,8 @@ @@ -4,6 +4,8 @@
round
z-index="{{100000}}"
show="{{ show }}"
position="{{params.position || 'center'}}"
safe-area-inset-bottom="{{false}}"
>
<view class="popup-class" wx:if="{{type=='videoComplate'}}">
<image class="bg" src="{{imageUrl}}za-images/popup-class-bg.png?t={{Timestamp}}"></image>
@ -846,6 +848,11 @@ @@ -846,6 +848,11 @@
<image class="code" src="{{params.ConsultQwImg}}" show-menu-by-longpress></image>
</view>
</view>
<view class="popup-note-guide" wx:if="{{type==='noteGuide'}}">
<view class="popup-container" bind:tap="handleCancel">
<image class="guide" src="{{imageUrl}}bg59.png?t={{Timestamp}}"></image>
</view>
</view>
<van-icon wx:if="{{params.close}}" class="popup-close" bind:tap="handleCancel" name="close" />
</van-popup>

3
src/pages/d_noteDetail/index.json

@ -1,7 +1,8 @@ @@ -1,7 +1,8 @@
{
"usingComponents": {
"navbar": "/components/navbar/index",
"van-icon": "@vant/weapp/icon/index"
"van-icon": "@vant/weapp/icon/index",
"noteImagePreview": "/components/noteImagePreview/index"
},
"navigationBarTitleText": "记录"
}

56
src/pages/d_noteDetail/index.ts

@ -35,6 +35,12 @@ Page({ @@ -35,6 +35,12 @@ Page({
hasBackend: false,
hasOther: false,
imagePreview: false,
previewImageSrc: '',
previewImages: [] as string[],
previewCurrentIndex: 0,
previewPhotoLabels: [] as { name: string; index: number; total: number }[],
// 角度分组
angleGroups: {
frontend: ['front_open', 'front_closed', 'front_looking_up'],
@ -138,13 +144,57 @@ Page({ @@ -138,13 +144,57 @@ Page({
const { angle } = e.currentTarget.dataset
const photo = this.data.photoMap[angle]
if (photo) {
wx.previewImage({
urls: [photo.photoUrl],
current: photo.photoUrl,
const { frontend, backend, other } = this.data.angleGroups
const allAngles = [
...frontend.map((a: string) => ({ angle: a, group: 'frontend' })),
...backend.map((a: string) => ({ angle: a, group: 'backend' })),
...other.map((a: string) => ({ angle: a, group: 'other' })),
]
const groupCounts: Record<string, number> = {}
const groupOffsets: Record<string, number> = {}
allAngles.forEach((item) => {
if (!groupCounts[item.group]) groupCounts[item.group] = 0
groupCounts[item.group]++
})
const previewAngles: string[] = []
const previewImages: string[] = []
const previewPhotoLabels: { name: string; index: number; total: number }[] = []
allAngles.forEach((item) => {
const p = this.data.photoMap[item.angle]
if (p) {
previewAngles.push(item.angle)
previewImages.push(p.photoUrl)
if (!groupOffsets[item.group]) groupOffsets[item.group] = 0
groupOffsets[item.group]++
previewPhotoLabels.push({
name: this.data.angleNameMap[item.angle],
index: groupOffsets[item.group],
total: groupCounts[item.group],
})
}
})
const currentIndex = previewAngles.indexOf(angle)
this.setData({
imagePreview: true,
previewImageSrc: photo.photoUrl,
previewImages,
previewCurrentIndex: currentIndex >= 0 ? currentIndex : 0,
previewPhotoLabels,
})
}
},
handleImagePreviewClose() {
this.setData({ imagePreview: false })
},
handleImageChange(e: any) {
const { index } = e.detail
this.setData({ previewCurrentIndex: index })
},
// 眼突度对比
handleDiffData() {
wx.navigateTo({

12
src/pages/d_noteDetail/index.wxml

@ -72,3 +72,15 @@ @@ -72,3 +72,15 @@
<view class="btn2" bind:tap="handlePhotoCompare">照片 对比</view>
</view>
</view>
<noteImagePreview
id="note-image-preview"
visible="{{imagePreview}}"
src="{{previewImageSrc}}"
images="{{previewImages}}"
currentIndex="{{previewCurrentIndex}}"
photoLabels="{{previewPhotoLabels}}"
showActions="{{false}}"
bind:close="handleImagePreviewClose"
bind:change="handleImageChange"
></noteImagePreview>

7
src/patient/components/camera/index.ts

@ -313,8 +313,11 @@ Component({ @@ -313,8 +313,11 @@ Component({
switchCamera() {
const newPosition = this.data.devicePosition === 'back' ? 'front' : 'back'
// 前置摄像头镜像,左侧45度和右侧45度需要互换 frame 图片
// 前置摄像头镜像,左侧和右侧需要互换 frame 图片
const frame = { ...this.data.frame }
const temp4 = { ...frame[4] }
frame[4] = { ...frame[5] }
frame[5] = temp4
const temp6 = { ...frame[6] }
frame[6] = { ...frame[7] }
frame[7] = temp6
@ -346,7 +349,7 @@ Component({ @@ -346,7 +349,7 @@ Component({
})
wx.cropImage({
src: res.tempImagePath,
cropScale: '16:9',
cropScale: '4:3',
success: (cropRes) => {
// 裁剪成功后上传图片
this.uploadImage(cropRes.tempFilePath || res.tempImagePath)

37
src/patient/components/image-merge/index.ts

@ -96,11 +96,12 @@ Component({ @@ -96,11 +96,12 @@ Component({
const canvas = res[0].node
const ctx = canvas.getContext('2d')
Promise.all(imageList.map((item) => this.getImageInfo(item.src)))
Promise.all(imageList.map(item => this.getImageInfo(item.src)))
.then((imageInfos) => {
const targetWidth = 750
const pixelRatio = wx.getWindowInfo().pixelRatio
const canvasWidth = Math.floor((targetWidth * pixelRatio) / 2)
const fontScale = pixelRatio / 2
let totalHeight = 0
const scaledHeights: number[] = []
@ -135,32 +136,34 @@ Component({ @@ -135,32 +136,34 @@ Component({
// 在每张图片左上角绘制时间,白色字体
const timeText = imageList[index].time || this.formatTime(new Date())
const padding = 20
const textY = yPositions[index] + 40
const padding = 20 * fontScale
const fontSize = Math.round(28 * fontScale)
const textY = yPositions[index] + 40 * fontScale
ctx.font = `bold ${fontSize}px sans-serif`
ctx.textBaseline = 'middle'
const textMetrics = ctx.measureText(timeText)
const bgPaddingH = 16 * fontScale
const bgPaddingV = 10 * fontScale
const bgH = fontSize + bgPaddingV * 2
const bgX = padding - bgPaddingH
const bgY = textY - bgH / 2
const bgW = textMetrics.width + bgPaddingH * 2
ctx.fillStyle = 'rgba(0, 0, 0, 0.45)'
ctx.fillRect(bgX, bgY, bgW, bgH)
// 设置白色字体和阴影以增强可读性
ctx.fillStyle = '#ffffff'
ctx.font = 'bold 28px sans-serif'
ctx.textAlign = 'left'
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)'
ctx.shadowBlur = 4
ctx.shadowOffsetX = 1
ctx.shadowOffsetY = 1
ctx.fillText(timeText, padding, textY)
// 重置阴影
ctx.shadowColor = 'transparent'
ctx.shadowBlur = 0
ctx.shadowOffsetX = 0
ctx.shadowOffsetY = 0
// 如果是最后一张图片,在其右下角绘制水印
if (index === imageInfos.length - 1) {
const lastImageBottom = yPositions[index] + scaledHeights[index]
ctx.fillStyle = 'rgba(255, 255, 255, 0.8)'
ctx.font = '24px sans-serif'
ctx.font = `${Math.round(24 * fontScale)}px sans-serif`
ctx.textAlign = 'right'
ctx.fillText('由-TED关爱小助手-小程序生成', canvasWidth - 20, lastImageBottom - 20)
ctx.fillText('由-TED关爱小助手-小程序生成', canvasWidth - 20 * fontScale, lastImageBottom - 20 * fontScale)
}
loadedCount++

13
src/patient/pages/index/index.ts

@ -43,6 +43,7 @@ Page({ @@ -43,6 +43,7 @@ Page({
// toastType: 'question-toast',
// toastType: 'guideEnterInfo',
// toastType: 'guideEnterInfoJump',
// toastType: 'noteGuide',
toastShow: false,
toastType: '',
@ -116,6 +117,18 @@ Page({ @@ -116,6 +117,18 @@ Page({
async getPopup() {
if (this.data.toastShow)
return
const noteGuideShown = wx.getStorageSync('noteGuideShown')
if (!noteGuideShown) {
this.setData({
toastShow: true,
toastType: 'noteGuide',
toastParams: { position: 'bottom', close: false },
})
wx.setStorageSync('noteGuideShown', true)
return
}
const data1 = await wx.ajax({
method: 'GET',
url: '?r=zd/popup/info',

12
src/patient/pages/note/index.scss

@ -117,7 +117,7 @@ page { @@ -117,7 +117,7 @@ page {
.action-btn {
flex: 1;
height: 320rpx;
border-radius: 20rpx;
border-radius: 32rpx;
display: flex;
flex-direction: column;
align-items: center;
@ -127,21 +127,11 @@ page { @@ -127,21 +127,11 @@ page {
overflow: hidden;
&.primary {
background: linear-gradient(180deg, #e98ff8 0%, #b073ff 100%);
.btn-text {
color: #fff;
}
.corner-fold {
position: absolute;
top: 0;
right: 0;
width: 60rpx;
height: 60rpx;
background: linear-gradient(45deg, #f6edff 0%, #f6edff 50%, #f6f8f9 50%, #f6f8f9 100%);
border-radius: 0 0 0 18rpx;
}
}
&.secondary {

3
src/patient/pages/note/index.wxml

@ -35,8 +35,7 @@ @@ -35,8 +35,7 @@
<!-- 功能按钮区 -->
<view class="action-buttons">
<view class="action-btn primary" bindtap="addRecord">
<view class="corner-fold"></view>
<view class="action-btn primary" bindtap="addRecord" style="background: url('{{imageUrl}}bg57.png?t={{Timestamp}}') no-repeat top center/100%;">
<image class="btn-icon" src="{{imageUrl}}icon147.png?t={{Timestamp}}"></image>
<text class="btn-text">新增记录</text>
</view>

23
src/patient/pages/noteAdd/index.scss

@ -26,7 +26,7 @@ page { @@ -26,7 +26,7 @@ page {
}
.form {
margin: 0 40rpx 24rpx;
padding: 32rpx;
padding: 24rpx 32rpx;
background: #ffffff;
border-radius: 32rpx 32rpx 32rpx 32rpx;
.form-title {
@ -45,10 +45,10 @@ page { @@ -45,10 +45,10 @@ page {
}
}
.form-title-gap {
margin-top: 48rpx;
margin-top: 28rpx;
}
.select {
margin-top: 24rpx;
margin-top: 12rpx;
display: flex;
justify-content: space-between;
padding: 26rpx 32rpx;
@ -64,7 +64,7 @@ page { @@ -64,7 +64,7 @@ page {
}
}
.dobule {
margin-top: 44rpx;
margin-top: 24rpx;
border-radius: 24rpx 24rpx 24rpx 24rpx;
display: flex;
gap: 26rpx;
@ -74,13 +74,13 @@ page { @@ -74,13 +74,13 @@ page {
color: #211d2e;
}
.i-content {
margin-top: 24rpx;
padding: 26rpx 14rpx;
margin-top: 12rpx;
padding: 26rpx 18rpx;
display: flex;
align-items: center;
background: #f6f8f9;
border-radius: 24rpx 24rpx 24rpx 24rpx;
font-size: 32rpx;
font-size: 24rpx;
color: #211d2e;
.num {
font-size: 32rpx;
@ -91,7 +91,7 @@ page { @@ -91,7 +91,7 @@ page {
}
}
.container {
margin-top: 32rpx;
// margin-top: 24rpx;
padding: 32rpx 40rpx 0;
background-color: #fff;
border-radius: 32rpx 32rpx 0 0;
@ -120,15 +120,16 @@ page { @@ -120,15 +120,16 @@ page {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
gap: 16rpx;
padding: 26rpx;
padding: 12rpx 26rpx;
border-radius: 18rpx;
.icon {
flex-shrink: 0;
width: 36rpx;
height: 36rpx;
}
font-size: 32rpx;
font-size: 28rpx;
&.btn1 {
color: #b982ff;
background: rgba(185, 130, 255, 0.12);
@ -136,6 +137,8 @@ page { @@ -136,6 +137,8 @@ page {
&.btn2 {
color: #ffffff;
background: linear-gradient(180deg, #e98ff8 0%, #b073ff 100%);
// color: #b982ff;
// background: rgba(185, 130, 255, 0.12);
}
}
}

61
src/patient/pages/noteAdd/index.ts

@ -44,6 +44,7 @@ Page({ @@ -44,6 +44,7 @@ Page({
previewImages: [] as string[],
previewAngles: [] as string[],
previewCurrentIndex: 0,
previewPhotoLabels: [] as { name: string, index: number, total: number }[],
recordId: '',
// 表单数据
@ -59,7 +60,7 @@ Page({ @@ -59,7 +60,7 @@ Page({
// 顺序拍摄模式
sequentialShootMode: false,
sequentialShootList: [] as { name: string; type: string; angle: string }[],
sequentialShootList: [] as { name: string, type: string, angle: string }[],
sequentialShootIndex: 0,
// 替妥尤单抗使用次数选项 (0-9, 9表示大于8)
@ -210,7 +211,8 @@ Page({ @@ -210,7 +211,8 @@ Page({
// 左眼度数输入
onLeftEyeInput(e: any) {
let val = e.detail.value
if (Number(val) > 999.9) val = '999.9'
if (Number(val) > 999.9)
val = '999.9'
this.setData({
leftEye: val,
})
@ -218,7 +220,8 @@ Page({ @@ -218,7 +220,8 @@ Page({
onRightEyeInput(e: any) {
let val = e.detail.value
if (Number(val) > 999.9) val = '999.9'
if (Number(val) > 999.9)
val = '999.9'
this.setData({
rightEye: val,
})
@ -226,7 +229,8 @@ Page({ @@ -226,7 +229,8 @@ Page({
onInterorbitalDistanceInput(e: any) {
let val = e.detail.value
if (Number(val) > 999.9) val = '999.9'
if (Number(val) > 999.9)
val = '999.9'
this.setData({
interorbitalDistance: val,
})
@ -382,17 +386,33 @@ Page({ @@ -382,17 +386,33 @@ Page({
if (photo) {
// 构建已上传图片列表(按 cameraList 顺序)
const allAngles = [
...this.data.cameraList.frontend,
...this.data.cameraList.backend,
...this.data.cameraList.other,
...this.data.cameraList.frontend.map(item => ({ ...item, group: 'frontend' })),
...this.data.cameraList.backend.map(item => ({ ...item, group: 'backend' })),
...this.data.cameraList.other.map(item => ({ ...item, group: 'other' })),
]
const previewAngles: string[] = []
const previewImages: string[] = []
const previewPhotoLabels: { name: string, index: number, total: number }[] = []
const groupCounts: Record<string, number> = {}
const groupOffsets: Record<string, number> = {}
allAngles.forEach((item) => {
if (!groupCounts[item.group])
groupCounts[item.group] = 0
groupCounts[item.group]++
})
allAngles.forEach((item) => {
const p = this.data.photoMap[item.angle]
if (p) {
previewAngles.push(item.angle)
previewImages.push(p.photoUrl)
if (!groupOffsets[item.group])
groupOffsets[item.group] = 0
groupOffsets[item.group]++
previewPhotoLabels.push({
name: item.name,
index: groupOffsets[item.group],
total: groupCounts[item.group],
})
}
})
const currentIndex = previewAngles.indexOf(angle)
@ -404,6 +424,7 @@ Page({ @@ -404,6 +424,7 @@ Page({
previewImages,
previewAngles,
previewCurrentIndex: currentIndex >= 0 ? currentIndex : 0,
previewPhotoLabels,
})
}
},
@ -448,8 +469,8 @@ Page({ @@ -448,8 +469,8 @@ Page({
// 保存记录
handleSave() {
const { recordId, recordDate, treatmentCount, isBaseline, leftEye, rightEye, interorbitalDistance, photoMap } =
this.data
const { recordId, recordDate, treatmentCount, isBaseline, leftEye, rightEye, interorbitalDistance, photoMap }
= this.data
// 表单验证
if (!recordDate) {
@ -465,13 +486,13 @@ Page({ @@ -465,13 +486,13 @@ Page({
}
// 所有照片全不合规才不允许保存
const hasCompliantPhoto = photos.some((photo) => photo.checkStatus === 1)
const hasCompliantPhoto = photos.some(photo => photo.checkStatus === 1)
if (!hasCompliantPhoto) {
wx.showToast({ title: '所有照片不合规,请重新上传', icon: 'none' })
return
}
const photoIds = photos.map((photo) => photo.photoId).join(',')
const photoIds = photos.map(photo => photo.photoId).join(',')
const data: any = {
...(recordId ? { recordId } : {}),
@ -482,9 +503,12 @@ Page({ @@ -482,9 +503,12 @@ Page({
}
// 可选字段
if (leftEye) data.leftEye = leftEye
if (rightEye) data.rightEye = rightEye
if (interorbitalDistance) data.interorbitalDistance = interorbitalDistance
if (leftEye)
data.leftEye = leftEye
if (rightEye)
data.rightEye = rightEye
if (interorbitalDistance)
data.interorbitalDistance = interorbitalDistance
wx.showLoading({ title: '保存中...' })
@ -524,7 +548,8 @@ Page({ @@ -524,7 +548,8 @@ Page({
})
if (popupType === 'popup18') {
this.setData({ isBaseline: 1 })
} else {
}
else {
this.handleSave()
}
},
@ -536,7 +561,8 @@ Page({ @@ -536,7 +561,8 @@ Page({
})
if (popupType === 'popup18') {
this.setData({ isBaseline: 0 })
} else {
}
else {
wx.navigateBack()
}
},
@ -547,7 +573,8 @@ Page({ @@ -547,7 +573,8 @@ Page({
popupShow: true,
popupType: 'popup16',
})
} else {
}
else {
wx.navigateBack()
}
},

3
src/patient/pages/noteAdd/index.wxml

@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
<van-icon name="arrow-left" slot="left" size="18px" color="#000" bind:tap="handleBack" />
</navbar>
<view class="page" style="padding-top:{{pageTop+20}}px;">
<view class="page" style="padding-top:{{pageTop+10}}px;">
<view class="benchmark">
<checkbox-group bindchange="onBaselineChange">
<checkbox class="checkbox" color="#fff" value="1" checked="{{isBaseline === 1}}">设置为基准记录,用于对比</checkbox>
@ -145,6 +145,7 @@ @@ -145,6 +145,7 @@
src="{{previewImageSrc}}"
images="{{previewImages}}"
currentIndex="{{previewCurrentIndex}}"
photoLabels="{{previewPhotoLabels}}"
bind:close="handleImagePreviewClose"
bind:delete="handleImageDel"
bind:retake="handleImageRetake"

3
src/patient/pages/noteHistory/index.json

@ -2,7 +2,8 @@ @@ -2,7 +2,8 @@
"usingComponents": {
"navbar": "/components/navbar/index",
"van-icon": "@vant/weapp/icon/index",
"popup": "/components/popup/index"
"popup": "/components/popup/index",
"noteImagePreview": "/components/noteImagePreview/index"
},
"navigationBarTitleText": "记录"
}

56
src/patient/pages/noteHistory/index.ts

@ -46,6 +46,12 @@ Page({ @@ -46,6 +46,12 @@ Page({
// 已上传照片数量
uploadedCount: 0,
imagePreview: false,
previewImageSrc: '',
previewImages: [] as string[],
previewCurrentIndex: 0,
previewPhotoLabels: [] as { name: string; index: number; total: number }[],
// 角度分组
angleGroups: {
frontend: ['front_open', 'front_closed', 'front_looking_up'],
@ -215,13 +221,57 @@ Page({ @@ -215,13 +221,57 @@ Page({
const { angle } = e.currentTarget.dataset
const photo = this.data.photoMap[angle]
if (photo) {
wx.previewImage({
urls: [photo.photoUrl],
current: photo.photoUrl,
const { frontend, backend, other } = this.data.angleGroups
const allAngles = [
...frontend.map((a: string) => ({ angle: a, group: 'frontend' })),
...backend.map((a: string) => ({ angle: a, group: 'backend' })),
...other.map((a: string) => ({ angle: a, group: 'other' })),
]
const groupCounts: Record<string, number> = {}
const groupOffsets: Record<string, number> = {}
allAngles.forEach((item) => {
if (!groupCounts[item.group]) groupCounts[item.group] = 0
groupCounts[item.group]++
})
const previewAngles: string[] = []
const previewImages: string[] = []
const previewPhotoLabels: { name: string; index: number; total: number }[] = []
allAngles.forEach((item) => {
const p = this.data.photoMap[item.angle]
if (p) {
previewAngles.push(item.angle)
previewImages.push(p.photoUrl)
if (!groupOffsets[item.group]) groupOffsets[item.group] = 0
groupOffsets[item.group]++
previewPhotoLabels.push({
name: this.data.angleNameMap[item.angle],
index: groupOffsets[item.group],
total: groupCounts[item.group],
})
}
})
const currentIndex = previewAngles.indexOf(angle)
this.setData({
imagePreview: true,
previewImageSrc: photo.photoUrl,
previewImages,
previewCurrentIndex: currentIndex >= 0 ? currentIndex : 0,
previewPhotoLabels,
})
}
},
handleImagePreviewClose() {
this.setData({ imagePreview: false })
},
handleImageChange(e: any) {
const { index } = e.detail
this.setData({ previewCurrentIndex: index })
},
// 去补充照片
handleSupplement() {
wx.navigateTo({

12
src/patient/pages/noteHistory/index.wxml

@ -105,3 +105,15 @@ @@ -105,3 +105,15 @@
bind:ok="handlePopupOk"
bind:cancel="handlePopupCancel"
></popup>
<noteImagePreview
id="note-image-preview"
visible="{{imagePreview}}"
src="{{previewImageSrc}}"
images="{{previewImages}}"
currentIndex="{{previewCurrentIndex}}"
photoLabels="{{previewPhotoLabels}}"
showActions="{{false}}"
bind:close="handleImagePreviewClose"
bind:change="handleImageChange"
></noteImagePreview>

Loading…
Cancel
Save