Browse Source

复诊记录联调

dev
kola-web 3 days ago
parent
commit
90eae5c44c
  1. 2
      project.config.json
  2. 69
      src/app.ts
  3. 20
      src/components/uploadFile/index.js
  4. 8
      src/components/uploadFile/index.wxml
  5. 24
      src/custom-tab-bar/index.ts
  6. 4
      src/pages/articleDetail/index.ts
  7. 4
      src/pages/articleVideoDetail/index.ts
  8. 1
      src/pages/followDetail/index.scss
  9. 77
      src/pages/followDetail/index.ts
  10. 30
      src/pages/followDetail/index.wxml
  11. 1
      src/pages/followForm/index.scss
  12. 135
      src/pages/followForm/index.ts
  13. 55
      src/pages/followForm/index.wxml
  14. 3
      src/pages/health/index.json
  15. 134
      src/pages/health/index.ts
  16. 36
      src/pages/health/index.wxml
  17. 10
      src/pages/index/index.scss
  18. 8
      src/pages/index/index.ts
  19. 8
      src/pages/index/index.wxml
  20. 1
      src/pages/login/index.ts
  21. 40
      src/pages/my/index.wxml
  22. 4
      src/pages/videoDetail/index.ts
  23. 2
      typings/index.d.ts

2
project.config.json

@ -66,7 +66,7 @@
], ],
"include": [] "include": []
}, },
"appid": "wxd9e68fd8ad8cc3f6", "appid": "wx903aa29742dad363",
"scripts": { "scripts": {
"beforeCompile": "pnpm run beforeCompile", "beforeCompile": "pnpm run beforeCompile",
"beforePreview": "pnpm run beforeCompile", "beforePreview": "pnpm run beforeCompile",

69
src/app.ts

@ -25,15 +25,15 @@ App<IAppOption>({
globalData: { globalData: {
// dev // dev
// appid:wx903aa29742dad363 // appid:wx903aa29742dad363
// url: 'https://m.psvt.hbraas.com', url: 'https://m.psvt.hbraas.com',
// upFileUrl: 'https://m.psvt.hbraas.com/', upFileUrl: 'https://m.psvt.hbraas.com/',
// imageUrl: 'https://m.psvt.hbraas.com/psvt/', imageUrl: 'https://m.psvt.hbraas.com/psvt/',
// pro // pro
// appid:wxd9e68fd8ad8cc3f6 // appid:wxd9e68fd8ad8cc3f6
url: 'https://m.psvt.hbsaas.com', // url: 'https://m.psvt.hbsaas.com',
upFileUrl: 'https://m.psvt.hbsaas.com/', // upFileUrl: 'https://m.psvt.hbsaas.com/',
imageUrl: 'https://m.psvt.hbsaas.com/psvt/', // imageUrl: 'https://m.psvt.hbsaas.com/psvt/',
Timestamp: new Date().getTime(), Timestamp: new Date().getTime(),
@ -61,10 +61,34 @@ App<IAppOption>({
}) })
}, },
onShow(options) { onShow(options) {
console.log('DEBUGPRINT[316]: app.ts:63: options=', JSON.stringify(options))
// {"path":"pages/start/index","query":{"scene":"cid%3D3"},"scene":1047,"referrerInfo":{},"mode":"default","apiCategory":"default"}
let sceneData: any = {}
if (options.query.scene) { if (options.query.scene) {
this.globalData.scene = parseScene(options.query.scene) as { workerId: string } sceneData = parseScene(options.query.scene) || {}
} }
this.startLogin() // 渠道码:优先取 scene 中解析的 cid,其次取 query 中直接传入的 cid
const channelId = sceneData.cid || sceneData.channelId || options.query.cid || ''
if (channelId) {
sceneData.channelId = channelId
}
this.globalData.scene = sceneData
this.startLogin(() => {
// 已登录用户扫码,调用渠道码扫码记录接口
if (channelId) {
const { isLogin, isReg } = this.globalData.initLoginInfo
if (isLogin && isReg) {
wx.ajax({
method: 'POST',
url: '?r=psvt/channel/scan-channel',
data: { channelId: Number(channelId) },
loading: false,
showMsg: false,
})
}
}
})
}, },
startLogin(callback?: () => void) { startLogin(callback?: () => void) {
wx.login({ wx.login({
@ -103,7 +127,7 @@ App<IAppOption>({
checkLogin() checkLogin()
}) })
}, },
checkLoginType(type = 'any') { checkLoginType(type = 'any', confirm = false) {
const { isLogin, isReg } = this.globalData.initLoginInfo const { isLogin, isReg } = this.globalData.initLoginInfo
if (type === 'any') { if (type === 'any') {
@ -111,18 +135,18 @@ App<IAppOption>({
} }
if (!isLogin) { if (!isLogin) {
this.redirectToLogin('/pages/login/index') this.redirectToLogin('/pages/login/index', confirm)
return false return false
} }
if (!isReg) { if (!isReg) {
this.redirectToLogin('/pages/confirmInfo/index') this.redirectToLogin('/pages/confirmInfo/index', confirm)
return false return false
} }
return true return true
}, },
redirectToLogin(path) { redirectToLogin(path, confirm) {
// 获取当前页面路径 // 获取当前页面路径
const pages = getCurrentPages() const pages = getCurrentPages()
const currentPage = pages[pages.length - 1] const currentPage = pages[pages.length - 1]
@ -137,15 +161,18 @@ App<IAppOption>({
this.globalData.loginRedirectUrl = query ? `${currentUrl}?${query}` : currentUrl this.globalData.loginRedirectUrl = query ? `${currentUrl}?${query}` : currentUrl
} }
if (currentUrl.includes('login/index')) return if (currentUrl.includes('login/index')) return
wx.reLaunch({ if (confirm) {
url: path, wx.showModal({
}) title: '提示',
// wx.showModal({ content: '授权登录后,可体验更好的服务',
// title: '提示', success: () => {
// content: '授权登录后,可体验更好的服务', wx.reLaunch({
// success: () => { url: path,
// }, })
// }) },
})
return
}
}, },
mpBehavior(data: { PageName: string }) { mpBehavior(data: { PageName: string }) {
const url = '?r=wtx/mp-behavior/add' const url = '?r=wtx/mp-behavior/add'

20
src/components/uploadFile/index.js

@ -15,6 +15,10 @@ Component({
type: Boolean, type: Boolean,
value: true, value: true,
}, },
fileType: {
type: String,
value: 'image',
},
// 附件data // 附件data
fileList: { fileList: {
type: Array, type: Array,
@ -222,9 +226,15 @@ Component({
}) })
}, },
handleAction() { handleAction() {
this.setData({ // this.setData({
show: true, // show: true,
}) // })
if (this.data.fileType === 'file') {
this.selectFiles()
} else {
this.selectMedia()
}
}, },
onSelect(e) { onSelect(e) {
const { id } = e.currentTarget.dataset const { id } = e.currentTarget.dataset
@ -247,8 +257,8 @@ Component({
count = maxNum - fileList.length count = maxNum - fileList.length
} }
wx.chooseMedia({ wx.chooseMedia({
mediaType: ['image', 'video'], mediaType: this.data.fileType,
count: count, count,
sourceType: ['album', 'camera'], sourceType: ['album', 'camera'],
sizeType: ['original'], sizeType: ['original'],
success: (res) => { success: (res) => {

8
src/components/uploadFile/index.wxml

@ -10,7 +10,11 @@
></image> ></image>
<image wx:else class="sub-image" mode="aspectFill" src="{{imageUrl}}{{item.fileType}}.png?t={{Timestamp}}"></image> <image wx:else class="sub-image" mode="aspectFill" src="{{imageUrl}}{{item.fileType}}.png?t={{Timestamp}}"></image>
<view class="item_mask"> <view class="item_mask">
<image class="item_mask_icon" wx:if="{{item.fileType === 'video'}}" src="{{imageUrl}}icon17.png?t={{Timestamp}}"></image> <image
class="item_mask_icon"
wx:if="{{item.fileType === 'video'}}"
src="{{imageUrl}}icon17.png?t={{Timestamp}}"
></image>
<view class="clear" wx:if="{{delete}}" catchtap="deleteFile" data-item="{{item}}" data-index="{{index}}"> <view class="clear" wx:if="{{delete}}" catchtap="deleteFile" data-item="{{item}}" data-index="{{index}}">
<van-icon name="cross" /> <van-icon name="cross" />
</view> </view>
@ -26,8 +30,6 @@
</view> </view>
</view> </view>
<!-- <van-action-sheet title=" " show="{{ show }}" actions="{{ actions }}" bind:close="onClose" bind:select="onSelect" /> -->
<van-popup <van-popup
show="{{ show }}" show="{{ show }}"
custom-styple="background-color: rgba(247, 247, 250, 1);" custom-styple="background-color: rgba(247, 247, 250, 1);"

24
src/custom-tab-bar/index.ts

@ -16,22 +16,22 @@ Component({
icon: 'tabbar1-1', icon: 'tabbar1-1',
iconActive: 'tabbar1-1-active', iconActive: 'tabbar1-1-active',
}, },
// { {
// pagePath: '/pages/wall/index', pagePath: '/pages/wall/index',
// text: '交流墙', text: '交流墙',
// icon: 'tabbar1-2', icon: 'tabbar1-2',
// iconActive: 'tabbar1-2-active', iconActive: 'tabbar1-2-active',
// }, },
{ {
pagePath: '', pagePath: '',
custom: true, custom: true,
}, },
// { {
// pagePath: '/pages/health/index', pagePath: '/pages/health/index',
// text: '健康管理', text: '健康管理',
// icon: 'tabbar1-2', icon: 'tabbar1-2',
// iconActive: 'tabbar1-2-active', iconActive: 'tabbar1-2-active',
// }, },
{ {
pagePath: '/pages/my/index', pagePath: '/pages/my/index',
text: '我的', text: '我的',

4
src/pages/articleDetail/index.ts

@ -37,7 +37,7 @@ Page({
}) })
}, },
handleCompliment() { handleCompliment() {
if (!app.checkLoginType(1)) return if (!app.checkLoginType(1, true)) return
const { detail, id } = this.data const { detail, id } = this.data
if (detail.IsCompliment) return if (detail.IsCompliment) return
wx.ajax({ wx.ajax({
@ -52,7 +52,7 @@ Page({
}) })
}, },
handleCollect() { handleCollect() {
if (!app.checkLoginType(1)) return if (!app.checkLoginType(1, true)) return
const { detail, id } = this.data const { detail, id } = this.data
if (detail.IsCollect) { if (detail.IsCollect) {
wx.ajax({ wx.ajax({

4
src/pages/articleVideoDetail/index.ts

@ -182,7 +182,7 @@ Page({
this.setData({ [`videoList[${index}].drag`]: false }) this.setData({ [`videoList[${index}].drag`]: false })
}, },
handleCompliment() { handleCompliment() {
if (!app.checkLoginType(1)) return if (!app.checkLoginType(1, true)) return
const { current, videoList } = this.data const { current, videoList } = this.data
const video = videoList[current] const video = videoList[current]
if (video.IsCompliment) return if (video.IsCompliment) return
@ -198,7 +198,7 @@ Page({
}) })
}, },
handleCollect() { handleCollect() {
if (!app.checkLoginType(1)) return if (!app.checkLoginType(1, true)) return
const { current, videoList } = this.data const { current, videoList } = this.data
const video = videoList[current] const video = videoList[current]
const isCollect = video.IsCollect const isCollect = video.IsCollect

1
src/pages/followDetail/index.scss

@ -5,6 +5,7 @@ page {
.page-title { .page-title {
font-size: 36rpx; font-size: 36rpx;
color: rgba(51, 51, 51, 1); color: rgba(51, 51, 51, 1);
padding-right: 100rpx;
} }
.page { .page {

77
src/pages/followDetail/index.ts

@ -8,13 +8,59 @@ Page({
position: 'bottom', position: 'bottom',
} as any, } as any,
topicShow: false, id: '',
replayShow: true, detail: {} as any,
},
fileList: [] as any[], onLoad(options: any) {
if (options.id) {
this.setData({ id: options.id })
app.waitLogin({ type: 'any' }).then(() => {
this.getDetail(options.id)
})
}
},
getDetail(id: string) {
wx.ajax({
method: 'GET',
url: '?r=psvt/revisit-record/detail',
data: { id },
}).then((res: any) => {
this.setData({ detail: res || {} })
})
},
handleDelete() {
const { id } = this.data
wx.showModal({
title: '提示',
content: '确定删除该复诊记录吗?',
success: (res) => {
if (!res.confirm) return
wx.ajax({
method: 'POST',
url: '?r=psvt/revisit-record/delete',
data: { id: Number(id) },
}).then(() => {
wx.showToast({ title: '删除成功', icon: 'success' })
setTimeout(() => {
wx.navigateBack()
}, 1000)
})
},
})
}, },
onLoad() { handleEdit() {
app.waitLogin({ type: 0 }).then(() => {}) const { id } = this.data
wx.navigateTo({
url: `/pages/followForm/index?id=${id}`,
})
},
handlePreviewImage(e: any) {
const { url } = e.currentTarget.dataset
const { detail } = this.data
wx.previewImage({
current: url,
urls: detail.images || [],
})
}, },
handlePopupOk() { handlePopupOk() {
const { popupType } = this.data const { popupType } = this.data
@ -79,23 +125,8 @@ Page({
url: '/pages/wechatWork/index', url: '/pages/wechatWork/index',
}) })
}, },
handleSetData(e) { handleBack() {
const { fileList } = this.data wx.navigateBack()
this.setData({
fileList: [...fileList, ...e.detail],
})
},
handleDeleteFile(e) {
const { index } = e.detail
const { fileList } = this.data
this.setData({
fileList: fileList.filter((_, i) => i !== index),
})
},
topicClose() {
this.setData({
topicShow: false,
})
}, },
}) })

30
src/pages/followDetail/index.wxml

@ -1,5 +1,5 @@
<navbar fixed custom-style="background:{{background}}" back> <navbar fixed custom-style="background:{{background}}" back>
<view class="page-title" slot="left"> <view class="page-title" slot="left" bind:tap="handleBack">
<van-icon name="arrow-left" /> <van-icon name="arrow-left" />
复诊记录详情 复诊记录详情
</view> </view>
@ -13,7 +13,7 @@
<view class="form-item"> <view class="form-item">
<view class="form-label">日期</view> <view class="form-label">日期</view>
<view class="date"> <view class="date">
<view class="content" data-place="请选择日期">2026.07.06 21:30</view> <view class="content">{{detail.visitDate || ''}}</view>
</view> </view>
</view> </view>
<view class="form-item"> <view class="form-item">
@ -21,35 +21,33 @@
上传图片 上传图片
<view class="sub">可上传复诊病历、处方单或检查结果</view> <view class="sub">可上传复诊病历、处方单或检查结果</view>
</view> </view>
<view class="photo9"> <view class="photo9" wx:if="{{detail.images && detail.images.length}}">
<view class="p-item" wx:for="{{3}}" wx:key="index"> <view class="p-item" wx:for="{{detail.images}}" wx:key="*this" data-url="{{item}}" bind:tap="handlePreviewImage">
<image class="p-img" mode="aspectFill" src="{{imageUrl}}bg1.png?t={{Timestamp}}"></image> <image class="p-img" mode="aspectFill" src="{{item}}"></image>
</view> </view>
</view> </view>
</view> </view>
<view class="form-item"> <view class="form-item">
<view class="form-label">发作时感受</view> <view class="form-label">是否更新处方</view>
<view class="select1"> <view class="select1">
<view class="s-item active">是</view> <view class="s-item {{detail.isUpdatePrescription === 1 ? 'active' : ''}}">是</view>
<view class="s-item">否</view> <view class="s-item {{detail.isUpdatePrescription === 0 ? 'active' : ''}}">否</view>
</view> </view>
</view> </view>
<view class="form-item"> <view class="form-item">
<view class="form-label">发作时处理方式</view> <view class="form-label">是否更新手术</view>
<view class="select1"> <view class="select1">
<view class="s-item active">是</view> <view class="s-item {{detail.isUpdateSurgery === 1 ? 'active' : ''}}">是</view>
<view class="s-item">否</view> <view class="s-item {{detail.isUpdateSurgery === 0 ? 'active' : ''}}">否</view>
</view> </view>
</view> </view>
<view class="form-item"> <view class="form-item">
<view class="form-label">其他备注</view> <view class="form-label">其他备注</view>
<view class="remark"> <view class="remark">{{detail.remark || ''}}</view>
本次复诊心悸发作频率较上次减少,发作持续时间约5–10分钟,含服药物后可自行缓解。医生建议继续规律服药,避免剧烈运动及情绪激动,定期复查心电图。
</view>
</view> </view>
</view> </view>
<view class="page-footer"> <view class="page-footer">
<view class="cancel">删除</view> <view class="cancel" bind:tap="handleDelete">删除</view>
<view class="send">编辑</view> <view class="send" bind:tap="handleEdit">编辑</view>
</view> </view>
</view> </view>

1
src/pages/followForm/index.scss

@ -5,6 +5,7 @@ page {
.page-title { .page-title {
font-size: 36rpx; font-size: 36rpx;
color: rgba(51, 51, 51, 1); color: rgba(51, 51, 51, 1);
padding-right: 100rpx;
} }
.page { .page {

135
src/pages/followForm/index.ts

@ -8,10 +8,128 @@ Page({
position: 'bottom', position: 'bottom',
} as any, } as any,
topicShow: false,
replayShow: true,
id: '',
visitDate: '',
fileList: [] as any[], fileList: [] as any[],
isUpdatePrescription: 0,
isUpdateSurgery: 0,
remark: '',
isEdit: false,
},
onLoad(options: any) {
if (options.id) {
this.setData({ id: options.id, isEdit: true })
app.waitLogin({ type: 'any' }).then(() => {
this.getDetail(options.id)
})
} else {
app.waitLogin({ type: 'any' }).then(() => {})
}
},
getDetail(id: string) {
wx.ajax({
method: 'GET',
url: '?r=psvt/revisit-record/detail',
data: { id },
}).then((res: any) => {
if (!res) return
const fileList = (res.images || []).map((url: string) => ({
url,
fileType: 'image',
name: url,
}))
this.setData({
visitDate: res.visitDate || '',
fileList,
isUpdatePrescription: res.isUpdatePrescription ?? 0,
isUpdateSurgery: res.isUpdateSurgery ?? 0,
remark: res.remark || '',
})
})
},
onDateChange(e: any) {
this.setData({ visitDate: e.detail.value })
},
handleSetData(e: any) {
const { fileList } = this.data
this.setData({
fileList: [...fileList, ...e.detail],
})
},
handleDeleteFile(e: any) {
const { index } = e.detail
const { fileList } = this.data
this.setData({
fileList: fileList.filter((_, i) => i !== index),
})
},
handlePrescriptionChange(e: any) {
const { value } = e.currentTarget.dataset
this.setData({ isUpdatePrescription: value })
}, },
onLoad() { handleSurgeryChange(e: any) {
app.waitLogin({ type: 0 }).then(() => {}) const { value } = e.currentTarget.dataset
this.setData({ isUpdateSurgery: value })
},
onRemarkInput(e: any) {
this.setData({ remark: e.detail.value })
},
handleSubmit() {
const { id, visitDate, fileList, isUpdatePrescription, isUpdateSurgery, remark, isEdit } = this.data
if (!visitDate) {
wx.showToast({ title: '请选择复诊日期', icon: 'none' })
return
}
const images = fileList.map((item: any) => item.url)
const data = {
visitDate,
images,
isUpdatePrescription,
isUpdateSurgery,
remark,
}
wx.showLoading({ title: '保存中' })
if (isEdit) {
wx.ajax({
method: 'POST',
url: '?r=psvt/revisit-record/update',
data: { id: Number(id), ...data },
})
.then(() => {
wx.hideLoading()
wx.showToast({ title: '保存成功', icon: 'success' })
setTimeout(() => {
wx.navigateBack()
}, 1000)
})
.catch(() => {
wx.hideLoading()
})
} else {
wx.ajax({
method: 'POST',
url: '?r=psvt/revisit-record/create',
data,
})
.then(() => {
wx.hideLoading()
wx.showToast({ title: '保存成功', icon: 'success' })
setTimeout(() => {
wx.navigateBack()
}, 1000)
})
.catch(() => {
wx.hideLoading()
})
}
}, },
handlePopupOk() { handlePopupOk() {
const { popupType } = this.data const { popupType } = this.data
@ -76,18 +194,13 @@ Page({
url: '/pages/wechatWork/index', url: '/pages/wechatWork/index',
}) })
}, },
handleSetData(e) { topicClose() {
const { fileList } = this.data
this.setData({ this.setData({
fileList: [...fileList, ...e.detail], topicShow: false,
}) })
}, },
handleDeleteFile(e) { handleBack() {
const { index } = e.detail wx.navigateBack()
const { fileList } = this.data
this.setData({
fileList: fileList.filter((_, i) => i !== index),
})
}, },
}) })

55
src/pages/followForm/index.wxml

@ -1,5 +1,5 @@
<navbar fixed custom-style="background:{{background}}" back> <navbar fixed custom-style="background:{{background}}" back>
<view class="page-title" slot="left"> <view class="page-title" slot="left" bind:tap="handleBack">
<van-icon name="arrow-left" /> <van-icon name="arrow-left" />
复诊记录 复诊记录
</view> </view>
@ -12,9 +12,9 @@
<view class="form"> <view class="form">
<view class="form-item"> <view class="form-item">
<view class="form-label">日期</view> <view class="form-label">日期</view>
<picker mode="date"> <picker mode="date" value="{{visitDate}}" bind:change="onDateChange">
<view class="date"> <view class="date">
<view class="content" data-place="请选择日期"></view> <view class="content" data-place="请选择日期">{{visitDate}}</view>
<van-icon class="icon" name="arrow-down" /> <van-icon class="icon" name="arrow-down" />
</view> </view>
</picker> </picker>
@ -34,26 +34,57 @@
</view> </view>
</view> </view>
<view class="form-item"> <view class="form-item">
<view class="form-label">发作时感受</view> <view class="form-label">是否更新处方</view>
<view class="select1"> <view class="select1">
<view class="s-item active">是</view> <view
<view class="s-item">否</view> class="s-item {{isUpdatePrescription === 1 ? 'active' : ''}}"
data-value="{{1}}"
bind:tap="handlePrescriptionChange"
>
</view>
<view
class="s-item {{isUpdatePrescription === 0 ? 'active' : ''}}"
data-value="{{0}}"
bind:tap="handlePrescriptionChange"
>
</view>
</view> </view>
</view> </view>
<view class="form-item"> <view class="form-item">
<view class="form-label">发作时处理方式</view> <view class="form-label">是否更新手术</view>
<view class="select1"> <view class="select1">
<view class="s-item active">是</view> <view
<view class="s-item">否</view> class="s-item {{isUpdateSurgery === 1 ? 'active' : ''}}"
data-value="{{1}}"
bind:tap="handleSurgeryChange"
>
</view>
<view
class="s-item {{isUpdateSurgery === 0 ? 'active' : ''}}"
data-value="{{0}}"
bind:tap="handleSurgeryChange"
>
</view>
</view> </view>
</view> </view>
<view class="form-item"> <view class="form-item">
<view class="form-label">其他备注</view> <view class="form-label">其他备注</view>
<textarea class="txa" placeholder-class="txa-place" placeholder="我要评论" maxlength="{{500}}"></textarea> <textarea
class="txa"
placeholder-class="txa-place"
placeholder="请输入备注"
value="{{remark}}"
bindinput="onRemarkInput"
maxlength="{{500}}"
></textarea>
</view> </view>
</view> </view>
<view class="page-footer"> <view class="page-footer">
<view class="cancel">取消</view> <view class="cancel" bind:tap="handleBack">取消</view>
<view class="send">保存记录</view> <view class="send" bind:tap="handleSubmit">保存记录</view>
</view> </view>
</view> </view>

3
src/pages/health/index.json

@ -5,6 +5,7 @@
"navbar": "/components/navbar/index", "navbar": "/components/navbar/index",
"van-tab": "@vant/weapp/tab/index", "van-tab": "@vant/weapp/tab/index",
"van-tabs": "@vant/weapp/tabs/index", "van-tabs": "@vant/weapp/tabs/index",
"ec-canvas": "/components/ec-canvas/ec-canvas" "ec-canvas": "/components/ec-canvas/ec-canvas",
"pagination": "/components/pagination/index"
} }
} }

134
src/pages/health/index.ts

@ -1,6 +1,8 @@
const app = getApp<IAppOption>() const app = getApp<IAppOption>()
const echarts = require('@/components/ec-canvas/echarts.js') const echarts = require('@/components/ec-canvas/echarts.js')
const PAGE_SIZE = 10
Page({ Page({
data: { data: {
popupShow: false, popupShow: false,
@ -9,36 +11,142 @@ Page({
position: 'bottom', position: 'bottom',
} as any, } as any,
tab: 1, tab: 2,
offsetTop: 0, offsetTop: 0,
// 复诊记录
revisitList: [] as any[],
revisitPagination: {
page: 1,
pages: 1,
count: 0,
},
startMonth: '',
endMonth: '',
daysSinceLastRevisit: 0,
totalRevisits: 0,
}, },
ecDataTrendComponent: null as any, ecDataTrendComponent: null as any,
_loaded: false,
onLoad() { onLoad() {
const now = new Date()
const endMonth = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`
const startDate = new Date(now.getFullYear(), now.getMonth() - 6, 1)
const startMonth = `${startDate.getFullYear()}-${String(startDate.getMonth() + 1).padStart(2, '0')}`
this.setData({ startMonth, endMonth })
this.ecDataTrendComponent = this.selectComponent('#chart1') this.ecDataTrendComponent = this.selectComponent('#chart1')
this.initChart() this.initChart()
app.waitLogin({ type: 0 }).then(() => {})
app.waitLogin({ type: 0 }).then(() => {
this._loaded = true
this.getRevisitList()
this.getLastRevisit()
})
}, },
onReady() { onReady() {
const { statusBarHeight } = wx.getSystemInfoSync() const { statusBarHeight } = wx.getSystemInfoSync()
const navBarHeight = 44 const navBarHeight = 44
this.setData({ offsetTop: statusBarHeight + navBarHeight }) this.setData({ offsetTop: statusBarHeight + navBarHeight })
}, },
onShow() {
if (this._loaded && this.data.tab === 2) {
this.getRevisitList()
this.getLastRevisit()
}
},
onReachBottom() {
if (this.data.tab === 2) {
const { revisitPagination } = this.data
if (revisitPagination.page < revisitPagination.pages) {
this.getRevisitList(revisitPagination.page + 1, true)
}
}
},
onChange(e: any) {
const { index } = e.detail
this.setData({ tab: index })
if (index === 2) {
this.getRevisitList()
this.getLastRevisit()
}
},
getRevisitList(page = 1, append = false) {
const { startMonth, endMonth } = this.data
wx.ajax({
method: 'GET',
url: '?r=psvt/revisit-record/list',
data: {
page,
count: PAGE_SIZE,
startMonth,
endMonth,
},
}).then((res: any) => {
const totalCount = Number(res.count) || 0
const list = (res.list || []).map((item: any, index: number) => {
const globalIndex = (page - 1) * PAGE_SIZE + index
return {
...item,
seqNum: globalIndex + 1,
}
})
this.setData({
revisitList: append ? this.data.revisitList.concat(list) : list,
revisitPagination: {
page: res.page || 1,
pages: res.pages || 1,
count: totalCount,
},
totalRevisits: totalCount,
})
})
},
getLastRevisit() {
wx.ajax({
method: 'GET',
url: '?r=psvt/revisit-record/last-revisit',
}).then((res: any) => {
this.setData({
daysSinceLastRevisit: res?.daysSinceLastRevisit ?? 0,
})
})
},
onStartMonthChange(e: any) {
this.setData({ startMonth: e.detail.value })
this.getRevisitList()
},
onEndMonthChange(e: any) {
this.setData({ endMonth: e.detail.value })
this.getRevisitList()
},
handleRevisitTap(e: any) {
const { id } = e.currentTarget.dataset
wx.navigateTo({
url: `/pages/followDetail/index?id=${id}`,
})
},
handleAddRevisit() {
wx.navigateTo({
url: '/pages/followForm/index',
})
},
initChart() { initChart() {
const arr = ['2026-06-01', '2026-06-02', '2026-06-03', '2026-06-04', '2026-06-05', '2026-06-06', '2026-06-07'] const arr = ['2026-06-01', '2026-06-02', '2026-06-03', '2026-06-04', '2026-06-05', '2026-06-06', '2026-06-07']
this.ecDataTrendComponent.init((canvas, width, height, dpr) => { this.ecDataTrendComponent.init((canvas, width, height, dpr) => {
let chart = echarts.init(canvas, null, { const chart = echarts.init(canvas, null, {
width: width, width,
height: height, height,
devicePixelRatio: dpr, devicePixelRatio: dpr,
}) })
canvas.setChart(chart) canvas.setChart(chart)
var option = { const option = {
dataZoom: [ dataZoom: [
{ {
type: 'inside', type: 'inside',
startValue: 0, startValue: 0,
endValue: 6, // 修正:数组下标0~6,原来7会越界 endValue: 6,
xAxisIndex: [0], xAxisIndex: [0],
}, },
], ],
@ -55,7 +163,6 @@ Page({
}, },
order: 'seriesDesc', order: 'seriesDesc',
}, },
// 双图例自定义样式,匹配原图空心绿圈+实心红点
legend: { legend: {
bottom: 0, bottom: 0,
padding: 0, padding: 0,
@ -133,20 +240,18 @@ Page({
], ],
series: [ series: [
{ {
// 单条主线,所有点位都有数值,折线完整连续无断点
name: '心率', name: '心率',
type: 'line', type: 'line',
symbol: 'circle', symbol: 'circle',
symbolSize: 8, symbolSize: 8,
lineStyle: { color: '#46bc70', width: 2 }, lineStyle: { color: '#46bc70', width: 2 },
// 每个点位单独配置样式,发作点红色实心,其余白色空心绿边框
data: [ data: [
{ value: 62, itemStyle: { color: '#fff', borderColor: '#46bc70', borderWidth: 2 } }, { value: 62, itemStyle: { color: '#fff', borderColor: '#46bc70', borderWidth: 2 } },
{ value: 60, itemStyle: { color: '#fff', borderColor: '#46bc70', borderWidth: 2 } }, { value: 60, itemStyle: { color: '#fff', borderColor: '#46bc70', borderWidth: 2 } },
{ value: 61, itemStyle: { color: '#fff', borderColor: '#46bc70', borderWidth: 2 } }, { value: 61, itemStyle: { color: '#fff', borderColor: '#46bc70', borderWidth: 2 } },
{ value: 66, itemStyle: { color: '#d62828', borderColor: '#fff' } }, // 发作红点 { value: 66, itemStyle: { color: '#d62828', borderColor: '#fff' } },
{ value: 63, itemStyle: { color: '#fff', borderColor: '#46bc70', borderWidth: 2 } }, { value: 63, itemStyle: { color: '#fff', borderColor: '#46bc70', borderWidth: 2 } },
{ value: 69, itemStyle: { color: '#d62828', borderColor: '#fff' } }, // 发作红点 { value: 69, itemStyle: { color: '#d62828', borderColor: '#fff' } },
{ value: 64, itemStyle: { color: '#fff', borderColor: '#46bc70', borderWidth: 2 } }, { value: 64, itemStyle: { color: '#fff', borderColor: '#46bc70', borderWidth: 2 } },
], ],
}, },
@ -215,11 +320,6 @@ Page({
}) })
} }
}, },
handleDetail() {
wx.navigateTo({
url: '/pages/wallDetail/index',
})
},
}) })
export {} export {}

36
src/pages/health/index.wxml

@ -6,11 +6,6 @@
class="page" class="page"
style="background: url('{{imageUrl}}bg6.png?t={{Timestamp}}') no-repeat top center/100% 478rpx;padding-top: {{pageTop}}px;" style="background: url('{{imageUrl}}bg6.png?t={{Timestamp}}') no-repeat top center/100% 478rpx;padding-top: {{pageTop}}px;"
> >
<!-- <swiper class="banner"> -->
<!-- <swiper-item> -->
<!-- <image class="b-img" mode="aspectFill" src="{{imageUrl}}bg1.png?t={{Timestamp}}"></image> -->
<!-- </swiper-item> -->
<!-- </swiper> -->
<van-tabs <van-tabs
class="tabs" class="tabs"
active="{{ tab }}" active="{{ tab }}"
@ -83,43 +78,44 @@
<view class="body3"> <view class="body3">
<view class="body-op"> <view class="body-op">
<view class="date-range"> <view class="date-range">
<picker mode="date"> <picker mode="date" fields="month" value="{{startMonth}}" bind:change="onStartMonthChange">
<view class="date">2026.01</view> <view class="date">{{startMonth}}</view>
</picker> </picker>
- -
<picker mode="date"> <picker mode="date" fields="month" value="{{endMonth}}" bind:change="onEndMonthChange">
<view class="date">2026.01</view> <view class="date">{{endMonth}}</view>
</picker> </picker>
<image class="icon" src="{{imageUrl}}icon25.png?t={{Timestamp}}"></image> <image class="icon" src="{{imageUrl}}icon25.png?t={{Timestamp}}"></image>
</view> </view>
<view class="total"> <view class="total">
共复诊 共复诊
<view class="high">3</view> <view class="high">{{totalRevisits}}</view>
次 距上次复诊 次 距上次复诊
<view class="high">12</view> <view class="high">{{daysSinceLastRevisit}}</view>
</view> </view>
</view> </view>
<view class="list"> <view class="list">
<view class="card" wx:for="{{10}}" wx:key="index"> <view class="card" wx:for="{{revisitList}}" wx:key="id" data-id="{{item.id}}" bind:tap="handleRevisitTap">
<view class="c-header"> <view class="c-header">
<view class="label">第4次复诊</view> <view class="label">第{{item.seqNum}}次复诊</view>
<view class="date">2026.7.12</view> <view class="date">{{item.visitDate}}</view>
</view> </view>
<view class="photo9"> <view class="photo9" wx:if="{{item.images && item.images.length}}">
<view class="p-item" wx:for="{{3}}" wx:key="index"> <view class="p-item" wx:for="{{item.images}}" wx:for-item="img" wx:key="*this">
<image class="p-img" mode="aspectFill" src="{{imageUrl}}bg1.png?t={{Timestamp}}"></image> <image class="p-img" mode="aspectFill" src="{{img}}"></image>
</view> </view>
</view> </view>
<view class="title">未更新处方</view> <view class="title">{{item.isUpdatePrescription ? '已更新处方' : '未更新处方'}}</view>
<view class="content">医生建议持续监测心律指标、评估药物疗效与不良反应,动态调整治…</view> <view class="content" wx:if="{{item.remark}}">{{item.remark}}</view>
</view> </view>
</view> </view>
<pagination pagination="{{revisitPagination}}" />
</view> </view>
</van-tab> </van-tab>
</van-tabs> </van-tabs>
</view> </view>
<view class="fixed-add"> <view class="fixed-add" bind:tap="handleAddRevisit">
<image class="icon" src="{{imageUrl}}icon24.png?t={{Timestamp}}"></image> <image class="icon" src="{{imageUrl}}icon24.png?t={{Timestamp}}"></image>
</view> </view>

10
src/pages/index/index.scss

@ -58,6 +58,16 @@ page {
margin: 32rpx 30rpx 0; margin: 32rpx 30rpx 0;
height: 176rpx; height: 176rpx;
} }
.swiper2 {
margin: 32rpx 30rpx 0;
height: 160rpx;
.s-img{
display: block;
width: 100%;
height: 160rpx;
border-radius: 32rpx;
}
}
.video-list { .video-list {
margin: 32rpx 0 0; margin: 32rpx 0 0;
.v-header { .v-header {

8
src/pages/index/index.ts

@ -19,7 +19,7 @@ Page({
}, },
videoList: [] as Array<any>, videoList: [] as Array<any>,
configList: [] as Array<any>, configList: [] as Array<any>,
sectionList: [] as Array<{ code: string; visible: boolean }>, sectionList: [] as Array<{ code: string; visible: boolean; subList: any[] }>,
moduleVisible: { moduleVisible: {
health: true, health: true,
'spread1': true, 'spread1': true,
@ -68,7 +68,11 @@ Page({
const sectionList = sectionCodes const sectionList = sectionCodes
.map((code) => { .map((code) => {
const conf = list.find((item: any) => item.code === code) const conf = list.find((item: any) => item.code === code)
return { code, visible: conf ? conf.showStatus == 1 : false } return {
code,
visible: conf ? conf.showStatus == 1 : false,
subList: conf?.subList || [],
}
}) })
.sort((a, b) => { .sort((a, b) => {
const aSeq = list.find((item: any) => item.code === a.code)?.sequence || 0 const aSeq = list.find((item: any) => item.code === a.code)?.sequence || 0

8
src/pages/index/index.wxml

@ -42,7 +42,13 @@
</view> </view>
</view> </view>
<!-- code: spread2 banner2模块 --> <!-- code: spread2 banner2模块 -->
<view class="banner" wx:if="{{item.code==='spread2' && item.visible}}"></view> <view class="banner" wx:if="{{item.code==='spread2' && item.visible}}">
<swiper class="swiper2">
<swiper-item wx:for="{{item.subList}}" wx:key="subIndex" wx:for-item="subItem" wx:for-index="subIndex">
<image class="s-img" mode="aspectFill" src="{{subItem.img}}"></image>
</swiper-item>
</swiper>
</view>
</block> </block>
<!-- code: education 用户教育最底部 --> <!-- code: education 用户教育最底部 -->
<view class="info-list" wx:if="{{moduleVisible.education}}"> <view class="info-list" wx:if="{{moduleVisible.education}}">

1
src/pages/login/index.ts

@ -114,6 +114,7 @@ Page({
data: { data: {
mobile, mobile,
code, code,
channelId: app.globalData.scene?.channelId || '',
}, },
showMsg: false, showMsg: false,
}) })

40
src/pages/my/index.wxml

@ -17,27 +17,27 @@
</view> </view>
</view> </view>
</view> </view>
<!-- <view class="kkd"> --> <view class="kkd">
<!-- <view class="k-item" bind:tap="handlePDev"> --> <view class="k-item" bind:tap="handlePDev">
<!-- 我的帖子 --> 我的帖子
<!-- <image class="icon" src="{{imageUrl}}icon30.png?t={{Timestamp}}"></image> --> <image class="icon" src="{{imageUrl}}icon30.png?t={{Timestamp}}"></image>
<!-- </view> --> </view>
<!-- <view class="k-item" bind:tap="handlePDev"> --> <view class="k-item" bind:tap="handlePDev">
<!-- 健康档案 --> 健康档案
<!-- <image class="icon" src="{{imageUrl}}icon31.png?t={{Timestamp}}"></image> --> <image class="icon" src="{{imageUrl}}icon31.png?t={{Timestamp}}"></image>
<!-- </view> --> </view>
<!-- </view> --> </view>
<view class="list"> <view class="list">
<!-- <view class="list-item" bind:tap="handlePDev"> --> <view class="list-item" bind:tap="handlePDev">
<!-- <image class="icon" src="{{imageUrl}}icon32.png?t={{Timestamp}}"></image> --> <image class="icon" src="{{imageUrl}}icon32.png?t={{Timestamp}}"></image>
<!-- <view class="content">我的评论</view> --> <view class="content">我的评论</view>
<!-- <van-icon class="arrow" name="arrow" /> --> <van-icon class="arrow" name="arrow" />
<!-- </view> --> </view>
<!-- <view class="list-item" bind:tap="routerTo" data-url="/pages/myCollection/index"> --> <view class="list-item" bind:tap="routerTo" data-url="/pages/myCollection/index">
<!-- <image class="icon" src="{{imageUrl}}icon33.png?t={{Timestamp}}"></image> --> <image class="icon" src="{{imageUrl}}icon33.png?t={{Timestamp}}"></image>
<!-- <view class="content">我的收藏</view> --> <view class="content">我的收藏</view>
<!-- <van-icon class="arrow" name="arrow" /> --> <van-icon class="arrow" name="arrow" />
<!-- </view> --> </view>
<view class="list-item" bind:tap="routerTo" data-url="/pages/userInfo/index"> <view class="list-item" bind:tap="routerTo" data-url="/pages/userInfo/index">
<image class="icon" src="{{imageUrl}}icon34.png?t={{Timestamp}}"></image> <image class="icon" src="{{imageUrl}}icon34.png?t={{Timestamp}}"></image>
<view class="content">个人信息</view> <view class="content">个人信息</view>

4
src/pages/videoDetail/index.ts

@ -164,7 +164,7 @@ Page({
this.setData({ [`videoList[${index}].drag`]: false }) this.setData({ [`videoList[${index}].drag`]: false })
}, },
handleCompliment() { handleCompliment() {
if (!app.checkLoginType(1)) return if (!app.checkLoginType(1, true)) return
const { current, videoList } = this.data const { current, videoList } = this.data
const video = videoList[current] const video = videoList[current]
if (video.IsCompliment) return if (video.IsCompliment) return
@ -180,7 +180,7 @@ Page({
}) })
}, },
handleCollect() { handleCollect() {
if (!app.checkLoginType(1)) return if (!app.checkLoginType(1, true)) return
const { current, videoList } = this.data const { current, videoList } = this.data
const video = videoList[current] const video = videoList[current]
const isCollect = video.IsCollect const isCollect = video.IsCollect

2
typings/index.d.ts vendored

@ -46,7 +46,7 @@ interface IAppOption {
getUserInfo: (type?: 0 | 1 | 2) => Promise<any> getUserInfo: (type?: 0 | 1 | 2) => Promise<any>
startLogin: (callback?: () => void) => void startLogin: (callback?: () => void) => void
waitLogin: (params?: { type?: 0 | 1 | 2 | 'any' }) => Promise<void> waitLogin: (params?: { type?: 0 | 1 | 2 | 'any' }) => Promise<void>
checkLoginType: (type: 0 | 1 | 2 | 'any') => boolean checkLoginType: (type: 1 | 'any', confirm: boolean) => boolean
mpBehavior: (data: { PageName: string; type?: 0 | 1 | 2 | 3 }) => void mpBehavior: (data: { PageName: string; type?: 0 | 1 | 2 | 3 }) => void
globalSystemInfo?: globalSystemInfo globalSystemInfo?: globalSystemInfo
[propName: string]: any [propName: string]: any

Loading…
Cancel
Save