Browse Source

api stash

master
kola-web 1 week ago
parent
commit
bbd0d87f54
  1. 18
      src/components/popup/index.scss
  2. 76
      src/components/popup/index.ts
  3. 25
      src/components/popup/index.wxml
  4. 14
      src/doctor/pages/article/index.ts
  5. 3
      src/doctor/pages/articleList/index.scss
  6. 35
      src/doctor/pages/articleList/index.ts
  7. 6
      src/doctor/pages/articleList/index.wxml
  8. 28
      src/doctor/pages/home/index.ts
  9. 2
      src/doctor/pages/invite/index.wxml
  10. 5
      src/doctor/pages/my/index.ts
  11. 12
      src/doctor/pages/patientList/index.scss
  12. 258
      src/doctor/pages/patientList/index.ts
  13. 101
      src/doctor/pages/patientList/index.wxml
  14. 3
      src/doctor/pages/stat/index.json
  15. 24
      src/doctor/pages/stat/index.ts
  16. 65
      src/doctor/pages/stat/index.wxml
  17. 2
      src/ground/pages/invite/index.wxml
  18. 2
      src/ground/pages/my/index.ts
  19. 12
      src/pages/index/index.ts
  20. 7
      src/pages/start/index.ts
  21. 22
      src/pages/tourists/index.ts

18
src/components/popup/index.scss

@ -45,6 +45,21 @@
} }
} }
} }
.upload-preview {
margin-top: 16rpx;
position: relative;
.preview-img {
width: 100%;
height: 300rpx;
border-radius: 12rpx;
}
.reupload {
margin-top: 16rpx;
font-size: 28rpx;
color: #ff8a4c;
text-align: center;
}
}
.btn { .btn {
margin-top: 32rpx; margin-top: 32rpx;
font-size: 36rpx; font-size: 36rpx;
@ -54,6 +69,9 @@
line-height: 92rpx; line-height: 92rpx;
background: linear-gradient(90deg, #fece55 0%, #ff8a4c 100%); background: linear-gradient(90deg, #fece55 0%, #ff8a4c 100%);
border-radius: 72rpx 72rpx 72rpx 72rpx; border-radius: 72rpx 72rpx 72rpx 72rpx;
&.disabled {
opacity: 0.5;
}
} }
} }

76
src/components/popup/index.ts

@ -36,6 +36,13 @@ Component({
if (this.data.type === 'publicCard') { if (this.data.type === 'publicCard') {
this.getCodeImg() this.getCodeImg()
} }
if (this.data.type === 'uploadMaterial') {
// 重置上传状态
this.setData({
materialImageUrl: '',
materialUploading: false,
})
}
} }
}, },
}, },
@ -53,6 +60,10 @@ Component({
codeImg: '', codeImg: '',
// 上传材料相关
materialImageUrl: '',
materialUploading: false,
imageUrl: app.globalData.imageUrl, imageUrl: app.globalData.imageUrl,
Timestamp: app.globalData.Timestamp, Timestamp: app.globalData.Timestamp,
}, },
@ -120,8 +131,7 @@ Component({
url, url,
}) })
}, },
handlePopup1Check1() { handlePopup1Check1() {},
},
handleSelectStatus(e) { handleSelectStatus(e) {
const { status } = e.currentTarget.dataset const { status } = e.currentTarget.dataset
this.triggerEvent('ok', { type: 'selectStatusComplete', status }) this.triggerEvent('ok', { type: 'selectStatusComplete', status })
@ -158,5 +168,67 @@ Component({
}) })
}) })
}, },
// 选择图片
handleChooseImage() {
wx.chooseMedia({
count: 1,
mediaType: ['image'],
sizeType: ['compressed'],
sourceType: ['camera', 'album'],
success: (res) => {
const tempFilePath = res.tempFiles[0].tempFilePath
this.uploadImage(tempFilePath)
},
})
},
// 上传图片
uploadImage(filePath: string) {
this.setData({ materialUploading: true })
wx.uploadFile({
url: `${app.globalData.url}/app/common/common/upload`,
filePath,
name: 'file',
success: (res) => {
const data = JSON.parse(res.data)
if (data.code === 0) {
// 更新头像
this.setData({
materialImageUrl: data.data.url,
})
} else {
wx.showToast({
title: data.msg || '上传失败',
icon: 'none',
})
}
},
fail: () => {
wx.showToast({
title: '上传失败',
icon: 'none',
})
},
complete: () => {
this.setData({ materialUploading: false })
},
})
},
// 提交材料
handleSubmitMaterial() {
const { materialImageUrl, params } = this.data
if (!materialImageUrl) {
wx.showToast({
title: '请先上传证明材料',
icon: 'none',
})
return
}
this.triggerEvent('ok', {
type: 'uploadMaterialComplete',
patientId: params.patientId,
auditType: params.auditType,
imageUrl: materialImageUrl,
})
},
}, },
}) })

25
src/components/popup/index.wxml

@ -9,33 +9,38 @@
safe-area-inset-bottom="{{false}}" safe-area-inset-bottom="{{false}}"
root-portal root-portal
> >
<view class="popup1" wx:if="{{type==='popup1'}}"> <!-- 上传患者材料弹窗 -->
<view class="title">新患者注册通知</view> <view class="popup1" wx:if="{{type==='uploadMaterial'}}">
<view class="title">{{params.title || '上传证明材料'}}</view>
<view class="row"> <view class="row">
<view class="label">患者姓名</view> <view class="label">患者姓名</view>
<view class="content">钱多多</view> <view class="content">{{params.patientName}}</view>
</view> </view>
<view class="row"> <view class="row">
<view class="label">手机号</view> <view class="label">手机号</view>
<view class="content">13800138000</view> <view class="content">{{params.phone}}</view>
</view> </view>
<view class="row"> <view class="row">
<view class="label">项目</view> <view class="label">项目</view>
<view class="content">特诺雅<text style="font-size:0.5em;vertical-align: top;">®</text>项目</view> <view class="content">{{params.projectName}}<text style="font-size:0.5em;vertical-align: top;">®</text>项目</view>
</view> </view>
<view class="row"> <view class="row">
<view class="label">适应症</view> <view class="label">适应症</view>
<view class="content">IBD</view> <view class="content">{{params.indicationName}}</view>
</view> </view>
<uploadFile class="upload-file"> <view class="upload-file">
<view class="upload"> <view class="upload" bind:tap="handleChooseImage" wx:if="{{!materialImageUrl}}">
<view class="place"> <view class="place">
<image class="icon" src="{{imageUrl}}icon21.png?t={{Timestamp}}"></image> <image class="icon" src="{{imageUrl}}icon21.png?t={{Timestamp}}"></image>
<view class="tip">拍照/从相册选择</view> <view class="tip">拍照/从相册选择</view>
</view> </view>
</view> </view>
</uploadFile> <view class="upload-preview" wx:if="{{materialImageUrl}}" bind:tap="handleChooseImage">
<view class="btn">确定并提交审核</view> <image class="preview-img" src="{{materialImageUrl}}" mode="aspectFill"></image>
<view class="reupload">点击重新选择</view>
</view>
</view>
<view class="btn {{materialImageUrl ? '' : 'disabled'}}" bind:tap="handleSubmitMaterial">确定并提交审核</view>
</view> </view>
<image <image

14
src/doctor/pages/article/index.ts

@ -47,9 +47,9 @@ Page({
}) })
}) })
}, },
// 点赞/取消点赞 // 点赞(多次点赞只增加点赞数)
handleLike() { handleLike() {
const { articleId, isLiked, articleDetail } = this.data const { articleId, articleDetail } = this.data
if (!articleId) return if (!articleId) return
wx.ajax({ wx.ajax({
@ -60,24 +60,22 @@ Page({
}, },
}) })
.then(() => { .then(() => {
const newLikeCount = isLiked ? (articleDetail.likeCount || 0) - 1 : (articleDetail.likeCount || 0) + 1
this.setData({ this.setData({
isLiked: !isLiked,
articleDetail: { articleDetail: {
...articleDetail, ...articleDetail,
likeCount: newLikeCount, likeCount: (articleDetail.likeCount || 0) + 1,
}, },
isLiked: true,
}) })
wx.showToast({ wx.showToast({
title: isLiked ? '取消点赞' : '点赞成功', title: '点赞成功',
icon: 'none', icon: 'none',
}) })
}) })
.catch(() => { .catch(() => {
wx.showToast({ wx.showToast({
title: '操作失败', title: '点赞失败',
icon: 'none', icon: 'none',
}) })
}) })

3
src/doctor/pages/articleList/index.scss

@ -71,6 +71,9 @@ page {
.wrap { .wrap {
flex: 1; flex: 1;
overflow: hidden; overflow: hidden;
display: flex;
flex-direction: column;
justify-content: space-between;
.title { .title {
font-size: 32rpx; font-size: 32rpx;
color: #342317; color: #342317;

35
src/doctor/pages/articleList/index.ts

@ -80,12 +80,13 @@ Page({
.then((res: any) => { .then((res: any) => {
const list = (res.list || []).map((item: any) => ({ const list = (res.list || []).map((item: any) => ({
...item, ...item,
isLiked: item.isLiked || false,
})) }))
const total = res.total || 0 const total = res.total || 0
const currentPage = this.data.page const currentPage = this.data.page
this.setData({ this.setData({
articleList: [...this.data.articleList, ...list], articleList: this.data.page === 1 ? list : [...this.data.articleList, ...list],
page: currentPage + 1, page: currentPage + 1,
hasMore: list.length >= this.data.pageSize, hasMore: list.length >= this.data.pageSize,
loading: false, loading: false,
@ -126,6 +127,38 @@ Page({
url: `/doctor/pages/article/index?id=${id}`, url: `/doctor/pages/article/index?id=${id}`,
}) })
}, },
// 点赞(多次点赞只增加点赞数)
handleLike(e: WechatMiniprogram.CustomEvent) {
const { id, index } = e.currentTarget.dataset
const article = this.data.articleList[index]
wx.ajax({
method: 'POST',
url: '/app/pharmacist/pharmacist/edu-article-like',
data: {
articleId: id,
},
})
.then(() => {
// 更新本地数据
const likedKey = `articleList[${index}].isLiked`
const countKey = `articleList[${index}].likeCount`
this.setData({
[likedKey]: true,
[countKey]: article.likeCount + 1,
})
wx.showToast({
title: '点赞成功',
icon: 'none',
})
})
.catch(() => {
wx.showToast({
title: '点赞失败',
icon: 'none',
})
})
},
}) })
export {} export {}

6
src/doctor/pages/articleList/index.wxml

@ -31,9 +31,9 @@
<image class="icon" src="{{imageUrl}}icon22.png?t={{Timestamp}}"></image> <image class="icon" src="{{imageUrl}}icon22.png?t={{Timestamp}}"></image>
<text class="num">{{item.viewCount || 0}}</text> <text class="num">{{item.viewCount || 0}}</text>
</view> </view>
<view class="o-item"> <view class="o-item" catch:tap="handleLike" data-id="{{item.id}}" data-index="{{index}}">
<image class="icon" src="{{imageUrl}}icon23.png?t={{Timestamp}}"></image> <image class="icon" src="{{item.isLiked ? imageUrl + 'icon25.png' : imageUrl + 'icon23.png'}}?t={{Timestamp}}"></image>
<text class="num">{{item.likeCount || 0}}</text> <text class="num {{item.isLiked ? 'liked' : ''}}">{{item.likeCount || 0}}</text>
</view> </view>
</view> </view>
</view> </view>

28
src/doctor/pages/home/index.ts

@ -213,11 +213,11 @@ Page({
// 根据统计类型格式化日期 // 根据统计类型格式化日期
const startDate = const startDate =
this.data.statType === 'month' this.data.statType === 'month'
? this.data.chartStartDate.substring(0, 7) // YYYY-MM ? this.data.chartStartMonth // YYYY-MM
: this.data.chartStartDate // YYYY-MM-DD : this.data.chartStartDate // YYYY-MM-DD
const endDate = const endDate =
this.data.statType === 'month' this.data.statType === 'month'
? this.data.chartEndDate.substring(0, 7) // YYYY-MM ? this.data.chartEndMonth // YYYY-MM
: this.data.chartEndDate // YYYY-MM-DD : this.data.chartEndDate // YYYY-MM-DD
wx.ajax({ wx.ajax({
@ -229,7 +229,7 @@ Page({
endDate, endDate,
}, },
}).then((res: any) => { }).then((res: any) => {
const list = res.list || [] const list = res || []
// 转换为图表需要的格式 // 转换为图表需要的格式
const chartData = list.map((item: any) => ({ const chartData = list.map((item: any) => ({
date: item.statDate || item.date, date: item.statDate || item.date,
@ -241,28 +241,6 @@ Page({
this.initChartBar(chartData) this.initChartBar(chartData)
}) })
}, },
// 生成模拟图表数据
generateMockChartData() {
const list: any[] = []
const days = this.data.statType === 'day' ? 30 : 12
for (let i = 0; i < days; i++) {
const date = new Date()
if (this.data.statType === 'day') {
date.setDate(date.getDate() - (days - 1 - i))
list.push({
date: this.formatDate(date),
count: Math.floor(Math.random() * 30) + 5,
})
} else {
date.setMonth(date.getMonth() - (days - 1 - i))
list.push({
date: `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`,
count: Math.floor(Math.random() * 300) + 50,
})
}
}
return list
},
// 切换统计类型 // 切换统计类型
switchStatType(e: WechatMiniprogram.CustomEvent) { switchStatType(e: WechatMiniprogram.CustomEvent) {

2
src/doctor/pages/invite/index.wxml

@ -23,7 +23,7 @@
<view class="title">邀请您加入健康管理项目</view> <view class="title">邀请您加入健康管理项目</view>
<view class="brand"> <view class="brand">
<view class="name"> <view class="name">
特诺雅 {{projectName || '特诺雅'}}
<text style="font-size: 0.5em; vertical-align: top">®</text> <text style="font-size: 0.5em; vertical-align: top">®</text>
</view> </view>
<view class="bg"></view> <view class="bg"></view>

5
src/doctor/pages/my/index.ts

@ -81,9 +81,6 @@ Page({
url: `${app.globalData.url}/app/common/common/upload`, url: `${app.globalData.url}/app/common/common/upload`,
filePath, filePath,
name: 'file', name: 'file',
header: {
loginState: app.globalData.loginState || '',
},
success: (res) => { success: (res) => {
wx.hideLoading() wx.hideLoading()
const data = JSON.parse(res.data) const data = JSON.parse(res.data)
@ -156,7 +153,7 @@ Page({
wx.ajax({ wx.ajax({
method: 'POST', method: 'POST',
url: '/app/pharmacist/pharmacist/logout', url: '/app/pharmacist/pharmacist/logout',
}).finally(() => { }).then(() => {
app.startLogin(() => { app.startLogin(() => {
wx.reLaunch({ wx.reLaunch({
url: '/pages/work/index', url: '/pages/work/index',

12
src/doctor/pages/patientList/index.scss

@ -163,6 +163,7 @@ page {
} }
.container { .container {
margin-top: 32rpx; margin-top: 32rpx;
padding-top: 12rpx;
padding-bottom: 32rpx; padding-bottom: 32rpx;
border-radius: 12rpx; border-radius: 12rpx;
background-color: rgba(247, 247, 247, 0.6); background-color: rgba(247, 247, 247, 0.6);
@ -215,18 +216,18 @@ page {
.wrap { .wrap {
flex: 1; flex: 1;
margin: 0 16rpx; margin: 0 16rpx;
padding-top: 24rpx;
padding-bottom: 32rpx; padding-bottom: 32rpx;
border-bottom: 1px solid #efefef; border-bottom: 1px solid #efefef;
.none { .none {
color: #b7b7b7; color: #b7b7b7;
} }
.date { .date {
padding-top: 24rpx;
font-size: 32rpx; font-size: 32rpx;
color: #342317; color: #342317;
} }
.status { .status {
margin-top: 28rpx; margin-top: 18rpx;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 32rpx; gap: 32rpx;
@ -259,6 +260,11 @@ page {
color: #e86854; color: #e86854;
} }
} }
.none {
padding: 20rpx 0 0 16rpx;
font-size: 32rpx;
color: rgba(183, 183, 183, 0.8);
}
&.active { &.active {
.aside { .aside {
.line-top, .line-top,
@ -287,7 +293,7 @@ page {
&:last-of-type { &:last-of-type {
.aside { .aside {
.line-bottom { .line-bottom {
border: none; // border: none;
} }
} }
.wrap { .wrap {

258
src/doctor/pages/patientList/index.ts

@ -1,41 +1,43 @@
import dayjs from 'dayjs'
const app = getApp<IAppOption>() const app = getApp<IAppOption>()
Page({ Page({
data: { data: {
// 项目列表
projectList: [] as Array<{ projectId: number; projectName: string; projectDescription: string }>,
currentProjectId: 0,
currentProjectName: '特诺雅',
projectIndex: 0,
// 搜索关键词 // 搜索关键词
keyword: '', keyword: '',
// 筛选条件 // 筛选条件
jumpStatus: 0, // 0-全部,1-已跳转 jumpStatus: '', // ''-全部,0-未跳转,1-已跳转
enrollStatus: 0, // 0-全部,1-已入组 jumpStatusIndex: 0, // picker 选中索引
jumpStatusLabel: '全部',
jumpStatusOptions: [
{ value: '', label: '全部' },
{ value: 0, label: '未跳转' },
{ value: 1, label: '已跳转' },
] as Array<{ value: string | number; label: string }>,
enrollStatus: '', // ''-全部,0-未入组,1-已入组
enrollStatusIndex: 0, // picker 选中索引
enrollStatusLabel: '全部',
enrollStatusOptions: [
{ value: '', label: '全部' },
{ value: 0, label: '未入组' },
{ value: 1, label: '已入组' },
] as Array<{ value: string | number; label: string }>,
timeType: 0, // 0-跳转时间,1-入组时间 timeType: 0, // 0-跳转时间,1-入组时间
jumpStartTime: '', jumpStartTime: '',
jumpEndTime: '', jumpEndTime: '',
enrollStartTime: '', enrollStartTime: '',
enrollEndTime: '', enrollEndTime: '',
// 患者列表(模拟数据,接口上线后删除) // 患者列表
patientList: [ patientList: [] as any[],
{ totalCount: 0,
id: 100,
patientId: 10,
patientName: '患者A',
patientAvatar: '',
phone: '138****8888',
indicationName: '银屑病',
pharmacyName: '国大药房(XX店)',
bindTime: 1700000000,
bindTimeFormatted: '2023/11/14 22:13:20',
jumpStatus: 1,
jumpTime: 1700000100,
jumpTimeFormatted: '2023/11/14 22:15:00',
enrollStatus: 1,
enrollTime: 1700000200,
enrollTimeFormatted: '2023/11/14 22:16:40',
materialStatus: 2,
},
] as any[],
totalCount: 1,
// 分页 // 分页
page: 1, page: 1,
@ -43,9 +45,9 @@ Page({
loading: false, loading: false,
hasMore: true, hasMore: true,
pagination: { pagination: {
count: 1, count: 0,
page: 1, page: 0,
pages: 1, pages: 0,
}, },
// 弹窗 // 弹窗
@ -56,8 +58,67 @@ Page({
onLoad() { onLoad() {
// 药店端患者列表页面,仅允许药店人员访问 // 药店端患者列表页面,仅允许药店人员访问
app.waitLogin({ types: [4] }).then(() => { app.waitLogin({ types: [4] }).then(() => {
// TODO: 接口上线后取消注释 this.getProjectList()
// this.getPatientList() })
},
// 获取项目列表
getProjectList() {
wx.ajax({
method: 'GET',
url: '/app/pharmacist/pharmacist/project-list',
})
.then((res: any) => {
const list = res.list || []
const currentProjectId = res.currentProjectId || (list.length > 0 ? list[0].projectId : 0)
const currentProject = list.find((p: any) => p.projectId === currentProjectId)
this.setData({
projectList: list,
currentProjectId,
currentProjectName: currentProject?.projectName || '特诺雅',
projectIndex: list.findIndex((p: any) => p.projectId === currentProjectId),
})
// 获取患者列表
this.getPatientList()
})
.catch(() => {
// 接口失败,使用默认数据
this.getPatientList()
})
},
// 切换项目
onProjectChange(e: WechatMiniprogram.CustomEvent) {
const index = e.detail.value
const project = this.data.projectList[index]
if (!project || project.projectId === this.data.currentProjectId) return
// 调用切换项目接口
wx.ajax({
method: 'POST',
url: '/app/pharmacist/pharmacist/switch-project',
data: {
projectId: project.projectId,
},
})
.then(() => {
this.setData({
currentProjectId: project.projectId,
currentProjectName: project.projectName,
projectIndex: index,
// 重置患者列表
patientList: [],
page: 1,
hasMore: true,
})
// 刷新患者列表
this.getPatientList()
})
.catch(() => {
wx.showToast({
title: '切换项目失败',
icon: 'none',
})
}) })
}, },
// 获取患者列表 // 获取患者列表
@ -67,15 +128,23 @@ Page({
this.setData({ loading: true }) this.setData({ loading: true })
// 根据时间类型判断传递哪个时间参数 // 根据时间类型判断传递哪个时间参数
const { timeType, jumpStartTime, jumpEndTime, enrollStartTime, enrollEndTime } = this.data const { timeType, jumpStartTime, jumpEndTime, enrollStartTime, enrollEndTime, jumpStatus, enrollStatus } = this.data
const params: any = { const params: any = {
keyword: this.data.keyword, keyword: this.data.keyword,
jumpStatus: this.data.jumpStatus,
enrollStatus: this.data.enrollStatus,
page: this.data.page, page: this.data.page,
pageSize: this.data.pageSize, pageSize: this.data.pageSize,
} }
// 跳转状态:空字符串表示全部,不传递参数
if (jumpStatus !== '') {
params.jumpStatus = jumpStatus
}
// 入组状态:空字符串表示全部,不传递参数
if (enrollStatus !== '') {
params.enrollStatus = enrollStatus
}
// 时间类型:0-跳转时间,1-入组时间 // 时间类型:0-跳转时间,1-入组时间
if (timeType === 0) { if (timeType === 0) {
// 跳转时间 // 跳转时间
@ -91,18 +160,31 @@ Page({
method: 'GET', method: 'GET',
url: '/app/pharmacist/pharmacist/patient-list', url: '/app/pharmacist/pharmacist/patient-list',
data: params, data: params,
}).then((res: any) => { })
.then((res: any) => {
const list = (res.list || []).map((item: any) => ({ const list = (res.list || []).map((item: any) => ({
...item, ...item,
bindTimeFormatted: item.bindTime ? this.formatDate(item.bindTime) : '-', bindTimeFormatted: item.bindTime || '-',
jumpTimeFormatted: item.jumpTime ? this.formatDate(item.jumpTime) : '', jumpTimeFormatted: item.jumpMaterial.updateTime
enrollTimeFormatted: item.enrollTime ? this.formatDate(item.enrollTime) : '', ? dayjs(item.jumpMaterial.updateTime).format('YYYY-MM-DD HH:mm')
: '',
enrollTimeFormatted: item.enrollMaterial.updateTime
? dayjs(item.enrollMaterial.updateTime).format('YYYY-MM-DD HH:mm')
: '',
// 跳转材料审核状态
jumpAuditStatus: item.jumpMaterial?.auditStatus ?? -1,
jumpAuditStatusText: item.jumpMaterial?.auditStatusText || '',
jumpRejectReason: item.jumpMaterial?.rejectReason || '',
// 入组材料审核状态
enrollAuditStatus: item.enrollMaterial?.auditStatus ?? -1,
enrollAuditStatusText: item.enrollMaterial?.auditStatusText || '',
enrollRejectReason: item.enrollMaterial?.rejectReason || '',
})) }))
const total = res.total || 0 const total = res.total || 0
const currentPage = this.data.page const currentPage = this.data.page
this.setData({ this.setData({
patientList: [...this.data.patientList, ...list], patientList: this.data.page === 1 ? list : [...this.data.patientList, ...list],
totalCount: total, totalCount: total,
page: currentPage + 1, page: currentPage + 1,
hasMore: list.length >= this.data.pageSize, hasMore: list.length >= this.data.pageSize,
@ -113,7 +195,8 @@ Page({
pages: Math.ceil(total / this.data.pageSize) || 1, pages: Math.ceil(total / this.data.pageSize) || 1,
}, },
}) })
}).catch(() => { })
.catch(() => {
this.setData({ loading: false }) this.setData({ loading: false })
}) })
}, },
@ -140,9 +223,12 @@ Page({
}, },
// 跳转状态筛选 // 跳转状态筛选
handleJumpStatusChange(e: WechatMiniprogram.CustomEvent) { handleJumpStatusChange(e: WechatMiniprogram.CustomEvent) {
const jumpStatus = e.detail.value === '1' ? 1 : 0 const index = e.detail.value
const option = this.data.jumpStatusOptions[index]
this.setData({ this.setData({
jumpStatus, jumpStatus: option.value,
jumpStatusIndex: index,
jumpStatusLabel: option.label,
page: 1, page: 1,
patientList: [], patientList: [],
hasMore: true, hasMore: true,
@ -151,9 +237,12 @@ Page({
}, },
// 入组状态筛选 // 入组状态筛选
handleEnrollStatusChange(e: WechatMiniprogram.CustomEvent) { handleEnrollStatusChange(e: WechatMiniprogram.CustomEvent) {
const enrollStatus = e.detail.value === '1' ? 1 : 0 const index = e.detail.value
const option = this.data.enrollStatusOptions[index]
this.setData({ this.setData({
enrollStatus, enrollStatus: option.value,
enrollStatusIndex: index,
enrollStatusLabel: option.label,
page: 1, page: 1,
patientList: [], patientList: [],
hasMore: true, hasMore: true,
@ -250,24 +339,93 @@ Page({
} }
this.getPatientList() this.getPatientList()
}, },
// 查看详情 // 预览提交的材料图片
handleInfo(e: WechatMiniprogram.CustomEvent) { handlePreviewMaterial(e: WechatMiniprogram.CustomEvent) {
const { id } = e.currentTarget.dataset const { url } = e.currentTarget.dataset
wx.navigateTo({ if (!url) {
url: `/doctor/pages/stat/index?id=${id}`, wx.showToast({
title: '暂无图片',
icon: 'none',
})
return
}
wx.previewImage({
urls: [url],
current: url,
}) })
}, },
// 上传材料 // 上传材料
handleUpload(e: WechatMiniprogram.CustomEvent) { handleUpload(e: WechatMiniprogram.CustomEvent) {
const { id } = e.currentTarget.dataset const { id } = e.currentTarget.dataset
// 查找患者信息
const patient = this.data.patientList.find((p: any) => p.id === id)
if (!patient) return
// 判断是跳转材料还是入组材料
const isJumpMaterial = patient.jumpAuditStatus === 0 || patient.jumpAuditStatus === 3
const auditType = isJumpMaterial ? 1 : 2
const title = isJumpMaterial ? '上传跳转证明材料' : '上传入组证明材料'
this.setData({ this.setData({
popupShow: true, popupShow: true,
popupType: 'upload', popupType: 'uploadMaterial',
popupParams: { patientId: id }, popupParams: {
patientId: patient.patientId,
patientName: patient.patientName,
phone: patient.phone,
projectName: this.data.currentProjectName,
indicationName: patient.indicationName,
auditType,
title,
},
}) })
}, },
// 弹窗确认 // 弹窗确认
handlePopupOk() { handlePopupOk(e: WechatMiniprogram.CustomEvent) {
const { detail } = e
// 处理上传材料完成
if (detail && detail.type === 'uploadMaterialComplete') {
const { patientId, auditType, imageUrl } = detail
wx.showLoading({ title: '提交中...' })
wx.ajax({
method: 'POST',
url: '/app/pharmacist/pharmacist/submit-material',
data: {
patientId,
imageUrl,
auditType,
},
})
.then(() => {
wx.hideLoading()
wx.showToast({
title: '提交成功',
icon: 'success',
})
this.setData({
popupShow: false,
})
// 刷新列表
this.setData({
page: 1,
patientList: [],
hasMore: true,
})
this.getPatientList()
})
.catch(() => {
wx.hideLoading()
wx.showToast({
title: '提交失败',
icon: 'none',
})
})
return
}
// 其他弹窗类型处理
this.setData({ this.setData({
popupShow: false, popupShow: false,
}) })

101
src/doctor/pages/patientList/index.wxml

@ -1,9 +1,17 @@
<navbar fixed custom-style="background: transparent;"> <navbar fixed custom-style="background: transparent;">
<view class="page-switch" slot="left"> <picker
特诺雅 slot="left"
bindchange="onProjectChange"
value="{{projectIndex}}"
range="{{projectList}}"
range-key="projectName"
>
<view class="page-switch">
{{currentProjectName}}
<text style="font-size: 0.5em; vertical-align: super">®</text> <text style="font-size: 0.5em; vertical-align: super">®</text>
<van-icon class="arrow" name="arrow-down" /> <van-icon class="arrow" name="arrow-down" />
</view> </view>
</picker>
</navbar> </navbar>
<view class="page"> <view class="page">
@ -20,17 +28,17 @@
/> />
</view> </view>
<view class="row"> <view class="row">
<picker bindchange="handleJumpStatusChange" value="{{jumpStatus}}" range="{{['全部', '已跳转']}}"> <picker bindchange="handleJumpStatusChange" value="{{jumpStatusIndex}}" range="{{jumpStatusOptions}}" range-key="label">
<view class="col"> <view class="col">
<view class="label">跳转:</view> <view class="label">跳转:</view>
<view class="content">{{jumpStatus === 0 ? '全部' : '已跳转'}}</view> <view class="content">{{jumpStatusLabel}}</view>
<image class="icon" src="{{imageUrl}}icon2.png?t={{Timestamp}}"></image> <image class="icon" src="{{imageUrl}}icon2.png?t={{Timestamp}}"></image>
</view> </view>
</picker> </picker>
<picker bindchange="handleEnrollStatusChange" value="{{enrollStatus}}" range="{{['全部', '已入组']}}"> <picker bindchange="handleEnrollStatusChange" value="{{enrollStatusIndex}}" range="{{enrollStatusOptions}}" range-key="label">
<view class="col"> <view class="col">
<view class="label">入组:</view> <view class="label">入组:</view>
<view class="content">{{enrollStatus === 0 ? '全部' : '已入组'}}</view> <view class="content">{{enrollStatusLabel}}</view>
<image class="icon" src="{{imageUrl}}icon2.png?t={{Timestamp}}"></image> <image class="icon" src="{{imageUrl}}icon2.png?t={{Timestamp}}"></image>
</view> </view>
</picker> </picker>
@ -71,13 +79,9 @@
</view> </view>
</view> </view>
<view class="page-container"> <view class="page-container">
<view class="card" wx:for="{{patientList}}" wx:key="id" data-id="{{item.id}}" bind:tap="handleInfo"> <view class="card" wx:for="{{patientList}}" wx:key="id">
<view class="user"> <view class="user">
<image <image class="avatar" src="{{item.patientAvatar}}" mode="aspectFill"></image>
class="avatar"
src="{{item.patientAvatar || imageUrl + 'cache/a2.png'}}?t={{Timestamp}}"
mode="aspectFill"
></image>
<view class="wrap"> <view class="wrap">
<view class="info"> <view class="info">
<text class="name">{{item.patientName}}</text> <text class="name">{{item.patientName}}</text>
@ -99,23 +103,36 @@
<view class="line-bottom"></view> <view class="line-bottom"></view>
</view> </view>
<view class="wrap"> <view class="wrap">
<view class="date" wx:if="{{item.jumpTime}}">{{item.jumpTimeFormatted}}</view> <view class="date" wx:if="{{item.jumpTimeFormatted}}">{{item.jumpTimeFormatted}}</view>
<view class="status" wx:if="{{item.jumpStatus === 1}}"> <view class="status">
<view <!-- 审核状态文本 -->
class="s{{item.materialStatus === 0 ? '1' : (item.materialStatus === 1 ? '1' : (item.materialStatus === 2 ? '1' : '2'))}}" <view class="s1" wx:if="{{item.jumpAuditStatus === 3 || item.jumpAuditStatus === 2}}">
> {{item.jumpAuditStatusText}}
{{item.materialStatus === 0 ? '未提交' : (item.materialStatus === 1 ? '审核中' : (item.materialStatus
=== 2 ? '已通过' : '已驳回'))}}
</view> </view>
<view class="s2" wx:if="{{item.jumpAuditStatus === 0 || item.jumpAuditStatus === 1}}">
{{item.jumpAuditStatusText}}
</view>
<!-- 未审核:提交 -->
<view class="btn2" wx:if="{{item.jumpAuditStatus === 0}}" catch:tap="handleUpload" data-id="{{item.id}}">
提交
</view>
<!-- 审核中/已通过:查看提交材料(预览图片) -->
<view <view
class="btn{{item.materialStatus === 3 ? '2' : '1'}}" class="btn1"
catch:tap="{{item.materialStatus === 3 ? 'handleUpload' : 'handleInfo'}}" wx:if="{{item.jumpAuditStatus === 1 || item.jumpAuditStatus === 2}}"
data-id="{{item.id}}" catch:tap="handlePreviewMaterial"
data-url="{{item.jumpMaterial.imageUrl}}"
> >
{{item.materialStatus === 3 ? '重新提交' : '查看提交材料'}} 查看提交材料
</view>
<!-- 已驳回:重新提交 -->
<view class="btn2" wx:if="{{item.jumpAuditStatus === 3}}" catch:tap="handleUpload" data-id="{{item.id}}">
重新提交
</view>
</view> </view>
<view class="remark" wx:if="{{item.jumpAuditStatus === 3 && item.jumpRejectReason}}">
{{item.jumpRejectReason}}
</view> </view>
<view class="remark" wx:if="{{item.materialStatus === 3}}">材料信息不全</view>
</view> </view>
</view> </view>
<!-- 入组状态 --> <!-- 入组状态 -->
@ -128,13 +145,39 @@
</view> </view>
<view class="line-bottom"></view> <view class="line-bottom"></view>
</view> </view>
<view class="wrap"> <view class="wrap" wx:if="{{item.jumpAuditStatus === 2}}">
<view class="date" wx:if="{{item.enrollTime}}">{{item.enrollTimeFormatted}}</view> <view class="date" wx:if="{{item.enrollTimeFormatted}}">{{item.enrollTimeFormatted}}</view>
<view class="status" wx:if="{{item.enrollStatus === 1}}"> <view class="status">
<view class="s1">审核通过</view> <!-- 审核状态文本 -->
<view class="btn1" catch:tap="handleInfo" data-id="{{item.id}}">查看提交材料</view> <view class="s1" wx:if="{{item.enrollAuditStatus === 3 || item.enrollAuditStatus === 2}}">
{{item.enrollAuditStatusText}}
</view>
<view class="s2" wx:if="{{item.enrollAuditStatus === 0 || item.enrollAuditStatus === 1}}">
{{item.enrollAuditStatusText}}
</view>
<!-- 未审核:提交 -->
<view class="btn2" wx:if="{{item.enrollAuditStatus === 0}}" catch:tap="handleUpload" data-id="{{item.id}}">
提交
</view>
<!-- 审核中/已通过:查看提交材料(预览图片) -->
<view
class="btn1"
wx:if="{{item.enrollAuditStatus === 1 || item.enrollAuditStatus === 2}}"
catch:tap="handlePreviewMaterial"
data-url="{{item.enrollMaterial.imageUrl}}"
>
查看提交材料
</view>
<!-- 已驳回:重新提交 -->
<view class="btn2" wx:if="{{item.enrollAuditStatus === 3}}" catch:tap="handleUpload" data-id="{{item.id}}">
重新提交
</view>
</view>
<view class="remark" wx:if="{{item.enrollAuditStatus === 3 && item.enrollRejectReason}}">
{{item.enrollRejectReason}}
</view> </view>
</view> </view>
<view class="none">---</view>
</view> </view>
</view> </view>
</view> </view>

3
src/doctor/pages/stat/index.json

@ -2,6 +2,7 @@
"navigationStyle": "custom", "navigationStyle": "custom",
"usingComponents": { "usingComponents": {
"popup": "/components/popup/index", "popup": "/components/popup/index",
"navbar": "/components/navbar/index" "navbar": "/components/navbar/index",
"pagination": "/components/pagination/index"
} }
} }

24
src/doctor/pages/stat/index.ts

@ -29,13 +29,18 @@ Page({
total: 0, total: 0,
loading: false, loading: false,
hasMore: true, hasMore: true,
// 分页组件数据
pagination: {
count: 0,
page: 0,
pages: 0,
},
}, },
onLoad() { onLoad() {
// 药店端统计页面,仅允许药店人员访问 // 药店端统计页面,仅允许药店人员访问
app.waitLogin({ types: [4] }).then(() => { app.waitLogin({ types: [4] }).then(() => {
this.initDate() this.initDate()
this.getStatisticsList()
}) })
}, },
@ -49,6 +54,7 @@ Page({
endDate: today, endDate: today,
today, today,
}) })
this.getStatisticsList()
}, },
// 格式化日期 // 格式化日期
@ -75,7 +81,8 @@ Page({
page: this.data.page, page: this.data.page,
pageSize: this.data.pageSize, pageSize: this.data.pageSize,
}, },
}).then((res: any) => { })
.then((res: any) => {
const list = res.list || [] const list = res.list || []
const summary = res.summary || { const summary = res.summary || {
invitePatientCount: 0, invitePatientCount: 0,
@ -83,15 +90,24 @@ Page({
enrollPatientCount: 0, enrollPatientCount: 0,
} }
const total = res.total || 0
const pages = Math.ceil(total / this.data.pageSize)
this.setData({ this.setData({
summary, summary,
statList: this.data.page === 1 ? list : [...this.data.statList, ...list], statList: this.data.page === 1 ? list : [...this.data.statList, ...list],
total: res.total || 0, total,
page: this.data.page + 1, page: this.data.page + 1,
hasMore: list.length >= this.data.pageSize, hasMore: list.length >= this.data.pageSize,
loading: false, loading: false,
pagination: {
count: total,
page: this.data.page,
pages,
},
})
}) })
}).catch(() => { .catch(() => {
this.setData({ loading: false }) this.setData({ loading: false })
}) })
}, },

65
src/doctor/pages/stat/index.wxml

@ -26,100 +26,55 @@
<view class="stat-card"> <view class="stat-card">
<view class="col"> <view class="col">
<view class="num"> <view class="num">
1893 {{summary.invitePatientCount}}
<text class="sub">人</text> <text class="sub">人</text>
</view> </view>
<view class="title">邀约患者总数</view> <view class="title">邀约患者总数</view>
</view> </view>
<view class="col"> <view class="col">
<view class="num"> <view class="num">
1893 {{summary.jumpPatientCount}}
<text class="sub">人</text> <text class="sub">人</text>
</view> </view>
<view class="title">跳转患者数</view> <view class="title">跳转患者数</view>
</view> </view>
<view class="col"> <view class="col">
<view class="num"> <view class="num">
1893 {{summary.enrollPatientCount}}
<text class="sub">人</text> <text class="sub">人</text>
</view> </view>
<view class="title">跳转患者数</view> <view class="title">入组患者数</view>
</view> </view>
</view> </view>
<view class="stat-list"> <view class="stat-list">
<view class="module"> <view class="module" wx:for="{{statList}}" wx:key="statDate">
<view class="aside"> <view class="aside">
<view class="line-top"></view> <view class="line-top"></view>
<view class="dot"></view> <view class="dot"></view>
<view class="line-bottom"></view> <view class="line-bottom"></view>
</view> </view>
<view class="m-container"> <view class="m-container">
<view class="date">2025/02/26</view> <view class="date">{{item.statDate}}</view>
<view class="card"> <view class="card">
<view class="row2"> <view class="row2">
<view class="col"> <view class="col">
<view class="name">邀约患者数</view> <view class="name">邀约患者数</view>
<view class="num">750</view> <view class="num">{{item.invitePatientCount}}</view>
</view> </view>
<view class="line"></view> <view class="line"></view>
<view class="col"> <view class="col">
<view class="name">跳转患者数</view> <view class="name">跳转患者数</view>
<view class="num">750</view> <view class="num">{{item.jumpPatientCount}}</view>
</view> </view>
<view class="line"></view> <view class="line"></view>
<view class="col"> <view class="col">
<view class="name">入组患者数</view> <view class="name">入组患者数</view>
<view class="num">750</view> <view class="num">{{item.enrollPatientCount}}</view>
</view>
</view>
<view class="row3">
<view class="col">
<view class="name">入组患者数</view>
<view class="num">300</view>
<view class="line"></view>
</view>
<view class="col">
<view class="name">斑块状银屑病</view>
<view class="num">280</view>
</view>
<view class="col">
<view class="name">斑块状银屑病</view>
<view class="num">280</view>
<view class="line"></view>
</view>
</view>
<view class="row3">
<view class="col">
<view class="name">溃疡性结肠炎</view>
<view class="num">300</view>
<view class="line"></view>
</view>
<view class="col">
<view class="name">溃疡性结肠炎</view>
<view class="num">280</view>
</view>
<view class="col">
<view class="name">溃疡性结肠炎</view>
<view class="num">280</view>
<view class="line"></view>
</view>
</view>
<view class="row3">
<view class="col">
<view class="name">克罗恩病</view>
<view class="num">300</view>
</view>
<view class="col">
<view class="name">克罗恩病</view>
<view class="num">280</view>
</view>
<view class="col">
<view class="name">克罗恩病</view>
<view class="num">280</view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
<pagination pagination="{{pagination}}" />
</view> </view>
</view> </view>

2
src/ground/pages/invite/index.wxml

@ -27,7 +27,7 @@
<view class="title">邀请您加入健康管理项目</view> <view class="title">邀请您加入健康管理项目</view>
<view class="brand"> <view class="brand">
<view class="name"> <view class="name">
特诺雅 {{projectName || '特诺雅'}}
<text style="font-size: 0.5em; vertical-align: top">®</text> <text style="font-size: 0.5em; vertical-align: top">®</text>
</view> </view>
<view class="bg"></view> <view class="bg"></view>

2
src/ground/pages/my/index.ts

@ -129,7 +129,7 @@ Page({
wx.ajax({ wx.ajax({
method: 'POST', method: 'POST',
url: '/app/promoter/promoter/logout', url: '/app/promoter/promoter/logout',
}).finally(() => { }).then(() => {
app.startLogin(() => { app.startLogin(() => {
wx.reLaunch({ wx.reLaunch({
url: '/pages/work/index', url: '/pages/work/index',

12
src/pages/index/index.ts

@ -121,7 +121,16 @@ Page({
}) })
.then((res: any) => { .then((res: any) => {
if (res && res.projectId) { if (res && res.projectId) {
// 已有项目,显示已参加项目状态 // 检查扫码的项目是否与当前项目一致
const scanProjectId = this.data.projectId
if (scanProjectId && String(scanProjectId) !== String(res.projectId)) {
// 扫码的是新项目,进入选择流程
this.setData({
hasProject: false,
})
this.getProjectInfo()
} else {
// 已有项目且与扫码项目一致,显示已参加项目状态
this.setData({ this.setData({
isLogin: 1, isLogin: 1,
isPatient: 1, isPatient: 1,
@ -130,6 +139,7 @@ Page({
hasProject: true, hasProject: true,
selectedIndicationName: res.indicationName, selectedIndicationName: res.indicationName,
}) })
}
} else { } else {
// 没有项目,获取项目列表供选择 // 没有项目,获取项目列表供选择
this.setData({ this.setData({

7
src/pages/start/index.ts

@ -71,6 +71,13 @@ Page({
return return
} }
if (loginIdentity === 4 && isRegister === 0) {
wx.reLaunch({
url: '/doctor/pages/login/index',
})
return
}
// 已注册,根据身份跳转到对应首页 // 已注册,根据身份跳转到对应首页
const homePageUrl = { const homePageUrl = {
2: '/pages/index/index', 2: '/pages/index/index',

22
src/pages/tourists/index.ts

@ -3,27 +3,7 @@ const app = getApp<IAppOption>()
Page({ Page({
data: {}, data: {},
onLoad() { onLoad() {
app.waitLogin().then(() => { app.waitLogin().then(() => {})
// 检查用户是否已有绑定的项目
this.checkProjectStatus()
})
},
// 检查用户项目状态
checkProjectStatus() {
wx.ajax({
method: 'GET',
url: '/app/patient/patient/recent-project',
}).then((res: any) => {
if (res && res.projectId) {
// 已有绑定的项目,跳转到患者首页
wx.reLaunch({
url: '/pages/index/index',
})
}
// 没有项目,停留在当前页面
}).catch(() => {
// 接口失败,停留在当前页面
})
}, },
// 跳转到药店工作人员登录页 // 跳转到药店工作人员登录页
goToPharmacist() { goToPharmacist() {

Loading…
Cancel
Save