Browse Source

2.0联调

dev2.0
kola-web 2 weeks ago
parent
commit
4e8a13fc31
  1. 39
      api.md
  2. 3
      src/app.json
  3. 8
      src/doctor/pages/d_caseReport/index.json
  4. 72
      src/doctor/pages/d_caseReport/index.scss
  5. 73
      src/doctor/pages/d_caseReport/index.ts
  6. 30
      src/doctor/pages/d_caseReport/index.wxml
  7. 2
      src/doctor/pages/d_createTask/index.ts
  8. 20
      src/doctor/pages/d_interactive/index.scss
  9. 5
      src/doctor/pages/d_interactive/index.ts
  10. 17
      src/doctor/pages/d_interactive/index.wxml
  11. 1
      src/doctor/pages/d_patientDetail/index.scss
  12. 466
      src/doctor/pages/d_patientDetail/index.ts
  13. 215
      src/doctor/pages/d_patientDetail/index.wxml
  14. 2
      src/doctor/pages/d_taskList/index.ts
  15. 12
      src/doctor/pages/d_taskList/index.wxml

39
api.md

@ -398,8 +398,9 @@ @@ -398,8 +398,9 @@
|------|------|------|------|
| page | int | 否 | 页码,默认 1 |
| pageSize | int | 否 | 每页条数,默认 10 |
| year | int | 否 | 按就诊年份筛选 |
| count | int | 否 | 取最近 N 次就诊记录 |
| year | int | 否 | 按就诊年份筛选(快捷方式,等同于yearStart=year&yearEnd=year) |
| yearStart | int | 否 | 按就诊年份范围筛选-起始年份,优先级高于year |
| yearEnd | int | 否 | 按就诊年份范围筛选-结束年份,优先级高于year |
#### 响应示例
@ -451,6 +452,8 @@ @@ -451,6 +452,8 @@
- `medicationsUsedOtherText`:本次就诊已使用药物选择"其他"(99)时的补充文本,未选择"其他"时为 null
- `immunosuppressantNameOtherText`:正在使用的免疫抑制剂名称选择"其他"(99)时的补充文本,未选择"其他"时为 null
- 年份筛选优先级:传入 `yearStart`+`yearEnd` 时优先按范围筛选,忽略 `year` 参数;仅传 `yearStart` 取 >= 起始年份;仅传 `yearEnd`<= 结束年份;仅传 `year` 则按单年份筛选
---
### 1.5 删除就诊记录
@ -494,8 +497,11 @@ @@ -494,8 +497,11 @@
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| imageField | string | 是 | 图片类型标识 |
| year | int | 否 | 按就诊年份筛选 |
| count | int | 否 | 取最近 N 次就诊记录 |
| year | int | 否 | 按就诊年份筛选(快捷方式,等同于yearStart=year&yearEnd=year) |
| yearStart | int | 否 | 按就诊年份范围筛选-起始年份,优先级高于year |
| yearEnd | int | 否 | 按就诊年份范围筛选-结束年份,优先级高于year |
| page | int | 否 | 页码,默认 1 |
| pageSize | int | 否 | 每页条数,默认 10 |
#### imageField 枚举
@ -514,6 +520,9 @@ @@ -514,6 +520,9 @@
"code": 0,
"message": "success",
"data": {
"page": 1,
"pages": 5,
"totalCount": 50,
"list": [
{
"visitDate": "2026-06-29",
@ -530,6 +539,8 @@ @@ -530,6 +539,8 @@
}
```
- 分页按就诊记录维度,每页包含对应就诊记录中该类型的所有图片
---
### 1.7 指标字段历史列表
@ -543,8 +554,9 @@ @@ -543,8 +554,9 @@
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| indicatorField | string | 是 | 指标字段标识 |
| year | int | 否 | 按就诊年份筛选 |
| count | int | 否 | 取最近 N 次就诊记录 |
| year | int | 否 | 按就诊年份筛选(快捷方式,等同于yearStart=year&yearEnd=year) |
| yearStart | int | 否 | 按就诊年份范围筛选-起始年份,优先级高于year |
| yearEnd | int | 否 | 按就诊年份范围筛选-结束年份,优先级高于year |
#### indicatorField 枚举
@ -799,8 +811,9 @@ @@ -799,8 +811,9 @@
| patientId | int | 是 | 患者 ID |
| page | int | 否 | 页码,默认 1 |
| pageSize | int | 否 | 每页条数,默认 10 |
| year | int | 否 | 按就诊年份筛选 |
| count | int | 否 | 取最近 N 次就诊记录 |
| year | int | 否 | 按就诊年份筛选(快捷方式,等同于yearStart=year&yearEnd=year) |
| yearStart | int | 否 | 按就诊年份范围筛选-起始年份,优先级高于year |
| yearEnd | int | 否 | 按就诊年份范围筛选-结束年份,优先级高于year |
#### 响应示例
@ -839,8 +852,9 @@ @@ -839,8 +852,9 @@
|------|------|------|------|
| patientId | int | 是 | 患者 ID |
| imageField | string | 是 | 图片类型标识 |
| year | int | 否 | 按就诊年份筛选 |
| count | int | 否 | 取最近 N 次就诊记录 |
| year | int | 否 | 按就诊年份筛选(快捷方式,等同于yearStart=year&yearEnd=year) |
| yearStart | int | 否 | 按就诊年份范围筛选-起始年份,优先级高于year |
| yearEnd | int | 否 | 按就诊年份范围筛选-结束年份,优先级高于year |
#### imageField 枚举
@ -864,8 +878,9 @@ @@ -864,8 +878,9 @@
|------|------|------|------|
| patientId | int | 是 | 患者 ID |
| indicatorField | string | 是 | 指标字段标识 |
| year | int | 否 | 按就诊年份筛选 |
| count | int | 否 | 取最近 N 次就诊记录 |
| year | int | 否 | 按就诊年份筛选(快捷方式,等同于yearStart=year&yearEnd=year) |
| yearStart | int | 否 | 按就诊年份范围筛选-起始年份,优先级高于year |
| yearEnd | int | 否 | 按就诊年份范围筛选-结束年份,优先级高于year |
#### indicatorField 枚举

3
src/app.json

@ -94,7 +94,8 @@ @@ -94,7 +94,8 @@
"pages/d_patientList/index",
"pages/d_transfer/index",
"pages/d_transferLog/index",
"pages/d_transferDetail/index"
"pages/d_transferDetail/index",
"pages/d_caseReport/index"
]
},
{

8
src/doctor/pages/d_caseReport/index.json

@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
{
"navigationBarTitleText": "病例报告",
"usingComponents": {
"pagination": "/components/pagination/index",
"van-divider": "@vant/weapp/divider/index",
"van-loading": "@vant/weapp/loading/index"
}
}

72
src/doctor/pages/d_caseReport/index.scss

@ -0,0 +1,72 @@ @@ -0,0 +1,72 @@
page {
background-color: rgba(246, 246, 246, 1);
}
.page {
padding: 32rpx 32rpx 300rpx;
.list {
.card {
display: flex;
gap: 20rpx;
.aside {
display: flex;
flex-direction: column;
align-items: center;
flex-shrink: 0;
.line-top,
.line-bottom {
border-right: 1px dashed rgba(34, 34, 34, 0.2);
}
.line-top {
flex-shrink: 0;
}
.line-bottom {
flex: 1;
}
.circle {
flex-shrink: 0;
width: 20rpx;
height: 20rpx;
border-radius: 50%;
background-color: rgba(22, 121, 203, 1);
background-clip: content-box;
border: 6rpx solid rgba(22, 121, 203, 0.10);
}
}
.wrap {
flex: 1;
min-width: 0;
padding-bottom: 48rpx;
.date {
font-size: 36rpx;
color: rgba(34, 34, 34, 1);
line-height: 1;
}
.container {
margin-top: 20rpx;
padding: 32rpx;
background-color: #fff;
border-radius: 12rpx;
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 24rpx;
.photo {
display: block;
width: 100%;
height: 154rpx;
border-radius: 12rpx;
}
}
}
}
}
.empty {
padding: 200rpx 0;
text-align: center;
.text {
font-size: 28rpx;
color: rgba(34, 34, 34, 0.4);
}
}
}

73
src/doctor/pages/d_caseReport/index.ts

@ -0,0 +1,73 @@ @@ -0,0 +1,73 @@
Page({
data: {
imageField: '',
patientId: '',
list: [] as { visitDate: string; images: string[] }[],
pagination: { count: 0, page: 1, pages: 1 },
},
onLoad(options: any) {
if (options.name) {
wx.setNavigationBarTitle({ title: options.name })
}
if (options.imageField) {
this.setData({ imageField: options.imageField, patientId: options.patientId || '' })
this.getImageHistory(true)
}
},
onReachBottom() {
const { page, pages } = this.data.pagination
if (page < pages) {
this.setData({ 'pagination.page': page + 1 })
this.getImageHistory()
}
},
getImageHistory(reset = false) {
const page = reset ? 1 : this.data.pagination.page
const data: Record<string, any> = { imageField: this.data.imageField, page, pageSize: 10 }
data.patientId = this.data.patientId
wx.ajax({
method: 'GET',
url: '?r=igg4/doctor/medical-visit/image-history',
data,
}).then((res: any) => {
if (!res || !res.list) return
// 按就诊日期分组
const groupMap: Record<string, string[]> = {}
for (const item of res.list) {
if (!groupMap[item.visitDate]) {
groupMap[item.visitDate] = []
}
groupMap[item.visitDate].push(item.imageUrl)
}
const newList = Object.keys(groupMap)
.sort((a, b) => b.localeCompare(a))
.map((visitDate) => ({
visitDate,
images: groupMap[visitDate],
}))
this.setData({
list: reset ? newList : [...this.data.list, ...newList],
pagination: {
count: res.totalCount || 0,
page: res.page || 1,
pages: res.pages || 1,
},
})
})
},
handlePreviewImage(e: WechatMiniprogram.CustomEvent) {
const { url, date } = e.currentTarget.dataset
const group = this.data.list.find((item) => item.visitDate === date)
if (!group) return
wx.previewImage({
current: url,
urls: group.images,
})
},
})
export {}

30
src/doctor/pages/d_caseReport/index.wxml

@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
<view class="page" id="{{theme === 'DRUG' && 'drug-page'}}">
<view class="list">
<view class="card" wx:for="{{list}}" wx:key="visitDate">
<view class="aside">
<view class="line-top"></view>
<view class="circle"></view>
<view class="line-bottom"></view>
</view>
<view class="wrap">
<view class="date">{{item.visitDate}}</view>
<view class="container">
<image
class="photo"
wx:for="{{item.images}}"
wx:key="*this"
wx:for-item="imgUrl"
src="{{imgUrl}}"
mode="aspectFill"
bind:tap="handlePreviewImage"
data-url="{{imgUrl}}"
data-date="{{item.visitDate}}"
></image>
</view>
</view>
</view>
</view>
<pagination pagination="{{pagination}}" customEmpty emptyTitle="暂无记录">
<view class="empty-text" slot>暂无记录</view>
</pagination>
</view>

2
src/doctor/pages/d_createTask/index.ts

@ -101,8 +101,6 @@ Page({ @@ -101,8 +101,6 @@ Page({
if (typeof e === 'object') {
btn = e?.currentTarget?.dataset?.btn
}
if (btn == 1) {
}
return wx
.ajax({

20
src/doctor/pages/d_interactive/index.scss

@ -13,9 +13,12 @@ page { @@ -13,9 +13,12 @@ page {
.wrap {
display: flex;
align-items: center;
gap: 16rpx;
.search {
flex: 1;
padding: 16rpx 32rpx;
height: 76rpx;
box-sizing: border-box;
display: flex;
align-items: center;
gap: 16rpx;
@ -34,6 +37,23 @@ page { @@ -34,6 +37,23 @@ page {
color: rgba(173, 179, 180, 1);
}
}
.send {
flex-shrink: 0;
padding: 16rpx 28rpx;
background: linear-gradient(96deg, #293b9f 0%, #1679cb 100%);
border-radius: 48rpx;
font-size: 32rpx;
color: #ffffff;
display: flex;
align-items: center;
gap: 12rpx;
height: 76rpx;
box-sizing: border-box;
.icon {
width: 40rpx;
height: 40rpx;
}
}
.clear {
margin-left: 32rpx;
width: 56rpx;

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

@ -107,4 +107,9 @@ Page({ @@ -107,4 +107,9 @@ Page({
},
})
},
handleSendGroup() {
wx.navigateTo({
url: '/doctor/pages/d_taskList/index',
})
},
})

17
src/doctor/pages/d_interactive/index.wxml

@ -7,26 +7,19 @@ @@ -7,26 +7,19 @@
type="text"
class="input"
placeholder-class="input-place"
placeholder="可根据姓名、手机号搜索患者"
placeholder="搜索姓名、手机号"
model:value="{{search}}"
confirm-type="search"
bindconfirm="handleSearch"
bind:tap="handleTapSearch"
/>
</view>
<view class="send" bind:tap="handleSendGroup">
<image class="icon" src="{{imageUrl}}icon108.png?t={{Timestamp}}"></image>
群发
</view>
<!-- <image class="clear" src="{{imageUrl}}icon47.png?t={{Timestamp}}" bind:tap="hancleClaer"></image> -->
</view>
<!-- <view class="navbar"> -->
<!-- <view class="nav {{!active && 'active'}}" bind:tap="handleNav" data-active=""> -->
<!-- 全部 -->
<!-- <view class="dot" wx:if="{{unReadCount>0}}">{{unReadCount}}</view> -->
<!-- </view> -->
<!-- <view class="nav {{active===1 && 'active'}}" bind:tap="handleNav" data-active="{{1}}">已读</view> -->
<!-- <view class="nav {{active===2 && 'active'}}" bind:tap="handleNav" data-active="{{2}}"> -->
<!-- 未读 -->
<!-- <view class="dot" wx:if="{{unReadCount>0}}">{{unReadCount}}</view> -->
<!-- </view> -->
<!-- </view> -->
</view>
<view class="list">

1
src/doctor/pages/d_patientDetail/index.scss

@ -376,6 +376,7 @@ page { @@ -376,6 +376,7 @@ page {
position: fixed;
bottom: 0;
left: 0;
z-index: 10;
width: 100%;
box-sizing: border-box;
display: flex;

466
src/doctor/pages/d_patientDetail/index.ts

@ -4,6 +4,27 @@ const app = getApp<IAppOption>() @@ -4,6 +4,27 @@ const app = getApp<IAppOption>()
let echarts: any = null
const MEDICATIONS_MAP: Record<number, string> = {
1: '没有使用激素',
2: '激素',
3: '免疫抑制剂',
4: '靶向CD19生物制剂',
5: '靶向CD20生物制剂',
99: '其他',
}
const IMMUNOSUPPRESSANT_MAP: Record<number, string> = {
1: '吗替麦考酚酯',
2: '替唑嘌呤',
3: '环磷酰胺',
4: '来氟米特',
5: '甲氨蝶呤',
6: '环孢素A',
7: '他克莫司',
8: '艾拉莫德',
99: '其他',
}
Page({
data: {
toastShow: false,
@ -109,17 +130,56 @@ Page({ @@ -109,17 +130,56 @@ Page({
3: '3年以上',
},
// 图表筛选
yearOptions: [
{ label: '按年', value: 1 },
{ label: '按次', value: 2 },
] as { label: string; value: number }[],
selected: 1,
selectedLabel: '按年',
BeginMonth: dayjs().subtract(1, 'year').add(1, 'month').format('YYYY-MM'),
EndMonth: dayjs().format('YYYY-MM'),
chartUnit: '',
chartList: [] as any[],
// 病历报告
caseReportList: [
{
icon: 'icon142.png',
name: '门诊病历及处方',
content: '医生手写或电脑打印的病历、处方',
imageField: 'outpatientRecord',
},
{ icon: 'icon127.png', name: '检验报告', content: '抽血检测的IgG4、IgG、ESR等', imageField: 'labReport' },
{
icon: 'icon128.png',
name: '影像学检查',
content: '超声/CT/MRI的描述结论、电子胶片',
imageField: 'imagingExam',
},
{
icon: 'icon129.png',
name: '病理诊断及活检',
content: '受累组织穿刺或切除免疫组化报告',
imageField: 'pathology',
},
{
icon: 'icon130.png',
name: '外周血免疫功能评估',
content: '免疫细胞亚群、淋巴细胞比例测定',
imageField: 'immuneFunction',
},
{ icon: 'icon127.png', name: '检验报告', content: '抽血检测的IgG4、IgG、ESR等' },
{ icon: 'icon128.png', name: '影像学检查', content: '超声/CT/MRI的描述结论、电子胶片' },
{ icon: 'icon129.png', name: '病理诊断及活检', content: '受累组织穿刺或切除免疫组化报告' },
{ icon: 'icon130.png', name: '外周血免疫功能评估', content: '免疫细胞亚群、淋巴细胞比例测定' },
],
// Tab 切换
currentTab: 0,
// 就诊记录列表
recordList: [] as any[],
recordPagination: { count: 0, page: 1, pages: 1 },
// 导出PPT
pptGenerating: false,
},
ecDataTrendComponent: null as any,
async onLoad(option) {
@ -128,150 +188,246 @@ Page({ @@ -128,150 +188,246 @@ Page({
})
echarts = await require.async('../../../resource/components/echart/echarts.js')
this.ecDataTrendComponent = this.selectComponent('#chart1')
this.initChart()
app.waitLogin().then(async (_res) => {
this.getDoctorDetail()
await this.getDetail()
this.getIndicatorHistory()
this.getRecordList(true)
})
},
initChart(defaultList = []) {
const list: any = [
...defaultList,
{ Date: '2026-7-7', TotalScore: 100, InjectionBottles: false },
{ Date: '2026-7-8', TotalScore: 1000, InjectionBottles: false },
]
return new Promise((reslove) => {
this.ecDataTrendComponent.init((canvas, width, height, dpr) => {
const chart = echarts.init(canvas, null, {
width,
height,
devicePixelRatio: dpr, // new
})
canvas.setChart(chart)
const option: any = {
tooltip: {
show: false,
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
confine: true,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
textStyle: {
color: '#fff',
fontSize: 10,
// ========== Tab 切换 ==========
handleTabChange(e: any) {
const { index } = e.currentTarget.dataset
const tab = Number(index)
if (tab === this.data.currentTab) return
this.setData({ currentTab: tab })
wx.pageScrollTo({ scrollTop: 0, duration: 200 })
// 切换到就诊记录时如果列表为空则请求
if (tab === 1 && !this.data.recordList.length) {
this.getRecordList(true)
}
// 切换到基本信息时重新获取图表组件并渲染
if (tab === 0 && this.data.chartList.length) {
setTimeout(() => {
this.ecDataTrendComponent = this.selectComponent('#chart1')
this.initChart(this.data.chartList)
}, 100)
}
},
// ========== 图表筛选 ==========
handleChange(e: any) {
const idx = Number(e.detail.value)
const selected = this.data.yearOptions[idx]
if (!selected) return
const isByYear = selected.value === 1
this.setData({
selected: selected.value,
selectedLabel: selected.label,
BeginMonth: isByYear ? dayjs().subtract(1, 'year').add(1, 'month').format('YYYY-MM') : '',
EndMonth: isByYear ? dayjs().format('YYYY-MM') : '',
})
this.getIndicatorHistory()
},
handleBeginDateChange(e: any) {
const BeginMonth = e.detail.value
this.setData({ BeginMonth })
if (this.data.EndMonth) {
this.getIndicatorHistory()
}
},
handleEndDateChange(e: any) {
const EndMonth = e.detail.value
this.setData({ EndMonth })
if (this.data.BeginMonth) {
this.getIndicatorHistory()
}
},
// ========== 指标趋势图表 ==========
initChart(defaultList: any[] = []) {
if (!defaultList.length) return
if (!echarts || !this.ecDataTrendComponent) {
this.ecDataTrendComponent = this.selectComponent('#chart1')
if (!echarts || !this.ecDataTrendComponent) return
}
const list = defaultList
this.ecDataTrendComponent.init((canvas: any, width: number, height: number, dpr: number) => {
const chart = echarts.init(canvas, null, {
width,
height,
devicePixelRatio: dpr,
})
canvas.setChart(chart)
const color = 'rgba(22, 121, 203, 1)'
const option: any = {
tooltip: {
show: false,
trigger: 'axis',
axisPointer: { type: 'shadow' },
confine: true,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
textStyle: { color: '#fff', fontSize: 10 },
order: 'seriesDesc',
},
grid: {
top: '30',
left: '0',
right: '0',
bottom: '10',
containLabel: true,
},
xAxis: [
{
type: 'category',
axisTick: { alignWithLabel: true },
axisLine: {
lineStyle: { color: 'rgba(34, 34, 34, 0.20)', type: 'dashed' },
},
order: 'seriesDesc',
data: list.map((item: any) => dayjs(item.visitDate).format('MM-DD')),
},
grid: {
top: '30',
left: '0',
right: '0',
bottom: '10',
containLabel: true,
],
yAxis: [
{
type: 'value',
minInterval: 1,
axisLabel: { color: 'rgba(34, 34, 34, 0.40)' },
splitLine: {
lineStyle: { color: 'rgba(34, 34, 34, 0.20)', type: 'dashed' },
},
},
xAxis: [
{
type: 'category',
axisTick: {
alignWithLabel: true,
},
axisLine: {
lineStyle: {
color: 'rgba(34, 34, 34, 0.20)',
type: 'dashed',
},
},
data: list.map((item) => dayjs(item.Date).format('MM-DD')),
],
series: [
{
name: 'IgG4',
data: list.length ? list.map((item: any) => item.value) : [0],
barWidth: '16',
label: {
show: true,
position: 'top',
color,
},
],
yAxis: [
{
type: 'value',
minInterval: 1,
axisLabel: {
color: 'rgba(34, 34, 34, 0.40)',
},
splitLine: {
lineStyle: {
color: 'rgba(34, 34, 34, 0.20)',
type: 'dashed',
},
},
type: 'line',
symbol: 'circle',
symbolSize: 8,
showSymbol: list.length >= 1,
connectNulls: true,
z: 10,
itemStyle: {
color,
},
],
series: [
{
name: '总分',
data: list.length ? list.map((item) => item.TotalScore) : [25],
barWidth: '16',
label: {
show: true,
position: 'top',
color: 'rgba(22, 121, 203, 1)',
},
type: 'line',
symbol: 'circle',
symbolSize: 8,
showSymbol: list.length >= 1,
connectNulls: true,
z: 10,
itemStyle: {
color: 'rgba(22, 121, 203, 1)',
},
markLine: {
symbol: ['none', 'none'],
data: [
{
name: '135 安全区',
yAxis: 135,
label: {
formatter: '{b}',
position: 'insideMiddle',
color: 'rgba(22, 121, 203, 1)',
fontSize: '10',
},
lineStyle: {
cap: '',
color: 'rgba(22, 121, 203, 1)',
type: 'dashed',
},
markLine: {
symbol: ['none', 'none'],
data: [
{
name: '135 安全区',
yAxis: 135,
label: {
formatter: '{b}',
position: 'insideMiddle',
color,
fontSize: '10',
},
lineStyle: {
cap: '',
color,
type: 'dashed',
},
],
},
markArea: {
itemStyle: {
color: 'rgba(22, 121, 203, 0.16)',
},
data: [
[
{
yAxis: 0,
},
{
yAxis: 135,
},
],
],
],
},
markArea: {
itemStyle: {
color: 'rgba(22, 121, 203, 0.16)',
},
data: [[{ yAxis: 0 }, { yAxis: 135 }]],
},
],
dataZoom: {
type: 'inside', // 有type这个属性,滚动条在最下面,也可以不行,写y:36,这表示距离顶端36px,一般就是在图上面。
startValue: 0,
endValue: 4,
filterMode: 'none',
},
}
],
dataZoom: {
type: 'inside',
startValue: 0,
endValue: 4,
filterMode: 'none',
},
}
chart.setOption(option)
return chart
})
},
getIndicatorHistory() {
const data: Record<string, any> = {
patientId: this.data.id,
indicatorField: 'igG4',
}
const { BeginMonth, EndMonth, selected } = this.data
if (BeginMonth && EndMonth && selected === 1) {
data.yearStart = Number(BeginMonth.substring(0, 4))
data.yearEnd = Number(EndMonth.substring(0, 4))
}
chart.setOption(option)
reslove(chart)
return chart
wx.ajax({
method: 'GET',
url: '?r=igg4/doctor/medical-visit/indicator-history',
data,
}).then((res: any) => {
if (!res) return
this.setData({
chartUnit: res.unit || 'mg/dL',
chartList: res.list || [],
})
this.initChart(res.list || [])
})
},
// ========== 就诊记录列表 ==========
getRecordList(reset = false) {
const page = reset ? 1 : this.data.recordPagination.page
wx.ajax({
method: 'GET',
url: '?r=igg4/doctor/medical-visit/list',
data: {
patientId: this.data.id,
page,
pageSize: 10,
},
}).then((res: any) => {
if (!res) return
const list = (res.list || []).map((item: any) => ({
...item,
medicationLabels: (item.medicationsUsed || []).map((id: number) => MEDICATIONS_MAP[id]).filter(Boolean),
immunosuppressantLabels: (item.immunosuppressantName || [])
.map((id: number) => IMMUNOSUPPRESSANT_MAP[id])
.filter(Boolean),
}))
this.setData({
recordList: reset ? list : [...this.data.recordList, ...list],
recordPagination: {
count: res.totalCount || 0,
page: res.page || 1,
pages: res.pages || 1,
},
})
})
},
// ========== 患者详情 ==========
getDoctorDetail() {
wx.ajax({
method: 'GET',
@ -434,4 +590,58 @@ Page({ @@ -434,4 +590,58 @@ Page({
handleToastCancel() {
wx.navigateBack()
},
// ========== 病历报告导航 ==========
handleDetail(e: any) {
const { name, imagefield } = e.currentTarget.dataset
wx.navigateTo({
url: `/doctor/pages/d_caseReport/index?name=${name}&imageField=${imagefield}&patientId=${this.data.id}`,
})
},
// ========== 导出PPT ==========
handleGeneratePdf() {
if (this.data.pptGenerating) return
this.setData({ pptGenerating: true })
const patientId = this.data.id
const downloadUrl = `${app.globalData.url}?r=igg4/doctor/medical-visit/export-ppt&loginState=${app.globalData.loginState}&patientId=${patientId}`
wx.downloadFile({
url: downloadUrl,
success: (res) => {
if (res.statusCode === 200) {
wx.shareFileMessage({
filePath: res.tempFilePath,
fileName: 'medical-visit.pptx',
success: () => {
wx.showToast({ title: '分享成功', icon: 'success' })
this.setData({ pptGenerating: false })
},
fail: () => {
wx.showToast({ title: '分享失败', icon: 'none' })
this.setData({ pptGenerating: false })
},
})
} else {
wx.showToast({ title: '下载失败', icon: 'none' })
this.setData({ pptGenerating: false })
}
},
fail: () => {
wx.showToast({ title: '下载失败', icon: 'none' })
this.setData({ pptGenerating: false })
},
})
},
// ========== 分页加载 ==========
onReachBottom() {
const { page, pages } = this.data.recordPagination
if (page < pages) {
this.setData({ 'recordPagination.page': page + 1 })
this.getRecordList()
}
},
})

215
src/doctor/pages/d_patientDetail/index.wxml

@ -1,9 +1,9 @@ @@ -1,9 +1,9 @@
<wxs src="../../../utils/tools.wxs" module="tools" />
<view class="page">
<view class="banner">
<view class="generate-pdf">
一键生成病历
<image class="icon" src="{{imageUrl}}icon144.png?t={{Timestamp}}"></image>
<view class="generate-pdf" bind:tap="handleGeneratePdf">
{{pptGenerating ? '生成中...' : '一键生成病历'}}
<image class="icon" src="{{imageUrl}}icon144.png?t={{Timestamp}}" wx:if="{{!pptGenerating}}"></image>
</view>
<view class="avatar">
<image class="avatar-img" src="{{detail.UserImg}}"></image>
@ -24,123 +24,142 @@ @@ -24,123 +24,142 @@
<van-sticky>
<view class="nav">
<view class="nav-wrap">
<view class="nav-item active">基本信息</view>
<view class="nav-item">就诊记录</view>
<view class="nav-item {{currentTab === 0 && 'active'}}" data-index="0" bind:tap="handleTabChange">
基本信息
</view>
<view class="nav-item {{currentTab === 1 && 'active'}}" data-index="1" bind:tap="handleTabChange">
就诊记录
</view>
</view>
</view>
</van-sticky>
<view class="container">
<block wx:if="{{detail.HealthQA && detail.HealthQA.hasSubmitted && detail.HealthQA.questions.length > 0}}">
<view class="row" wx:for="{{detail.HealthQA.questions}}" wx:key="QuestionNo">
<view class="label">{{item.DoctorTitle}}</view>
<view class="content" wx:if="{{item.AnswerTextStr}}">
<text wx:if="{{!item.isAnswerArray}}">{{item.AnswerTextStr}}</text>
<block wx:else>
<view wx:for="{{item.AnswerTextArr}}" wx:for-item="ans" wx:key="index">
{{ans}}
<text wx:if="{{item.OtherText && index === item.AnswerTextArr.length - 1}}">({{item.OtherText}})</text>
</view>
</block>
<!-- 基本信息 -->
<block wx:if="{{currentTab === 0}}">
<view class="container">
<block wx:if="{{detail.HealthQA && detail.HealthQA.hasSubmitted && detail.HealthQA.questions.length > 0}}">
<view class="row" wx:for="{{detail.HealthQA.questions}}" wx:key="QuestionNo">
<view class="label">{{item.DoctorTitle}}</view>
<view class="content" wx:if="{{item.AnswerTextStr}}">
<text wx:if="{{!item.isAnswerArray}}">{{item.AnswerTextStr}}</text>
<block wx:else>
<view wx:for="{{item.AnswerTextArr}}" wx:for-item="ans" wx:key="index">
{{ans}}
<text wx:if="{{item.OtherText && index === item.AnswerTextArr.length - 1}}">
({{item.OtherText}})
</text>
</view>
</block>
</view>
<view class="content" wx:else>无</view>
</view>
<view class="content" wx:else>无</view>
</block>
<view class="row">
<view class="label">备注</view>
<view class="content">{{detail.DoctorRemark || '无'}}</view>
</view>
</block>
<view class="row">
<view class="label">备注</view>
<view class="content">{{detail.DoctorRemark || '无'}}</view>
</view>
</view>
<view class="chart">
<view class="chart-header">
<picker>
<view class="type">
按年
<view class="chart">
<view class="chart-header">
<picker range="{{yearOptions}}" range-key="label" bindchange="handleChange">
<view class="type">
{{selectedLabel}}
<van-icon class="icon" name="play" />
</view>
</picker>
<view class="date" wx:if="{{selected === 1}}">
<picker
mode="date"
fields="month"
bindchange="handleBeginDateChange"
value="{{BeginMonth}}"
end="{{EndMonth}}"
>
<view class="start {{BeginMonth && 'active'}}">{{BeginMonth ? BeginMonth : '开始时间'}}</view>
</picker>
<view class="line">-</view>
<picker
mode="date"
fields="month"
bindchange="handleEndDateChange"
value="{{EndMonth}}"
start="{{BeginMonth}}"
>
<view class="end {{EndMonth && 'active'}}">{{EndMonth ? EndMonth : '结束时间'}}</view>
</picker>
<van-icon class="icon" name="play" />
</view>
</picker>
<view class="date">
<picker
bindchange="handleChange"
class="start"
end="{{EndMonth}}"
fields="day"
mode="date"
model:value="{{BeginMonth}}"
>
2025.08
</picker>
<view class="line">-</view>
<picker
bindchange="handleChange"
class="end"
fields="day"
mode="date"
model:value="{{EndMonth}}"
start="{{BeginMonth}}"
>
2025.09
</picker>
<van-icon class="icon" name="play" />
</view>
<view class="chart-container">
<view class="c-header">
<view class="title">血清IgG4趋势监测</view>
<view class="sub">单位{{chartUnit}}</view>
</view>
<view class="w-chart">
<ec-canvas id="chart1" ec="{{ ec }}"></ec-canvas>
</view>
</view>
</view>
<view class="chart-container">
<view class="case-report">
<view class="c-header">
<view class="title">血清IgG4趋势监测</view>
<view class="sub">单位mg/dL</view>
<view class="name">我的病历报告</view>
</view>
<view class="w-chart">
<ec-canvas id="chart1" ec="{{ ec }}"></ec-canvas>
</view>
</view>
</view>
<view class="case-report">
<view class="c-header">
<view class="name">我的病历报告</view>
</view>
<view class="list">
<view class="row" wx:for="{{caseReportList}}" wx:key="icon" bind:tap="handleDetail" data-name="{{item.name}}">
<image class="icon" src="{{imageUrl}}{{item.icon}}?t={{Timestamp}}"></image>
<view class="col">
<view class="name">{{item.name}}</view>
<view class="content">{{item.content}}</view>
<view class="list">
<view
class="row"
wx:for="{{caseReportList}}"
wx:key="icon"
bind:tap="handleDetail"
data-name="{{item.name}}"
data-imagefield="{{item.imageField}}"
>
<image class="icon" src="{{imageUrl}}{{item.icon}}?t={{Timestamp}}"></image>
<view class="col">
<view class="name">{{item.name}}</view>
<view class="content">{{item.content}}</view>
</view>
</view>
</view>
</view>
</view>
</block>
<view class="record-list">
<view class="card" wx:for="{{10}}" wx:key="index" bind:tap="handleDetail">
<view class="aside">
<view class="line-top"></view>
<view class="circle"></view>
<view class="line-bottom"></view>
</view>
<view class="wrap">
<view class="date">2025-06-11</view>
<view class="w-container">
<view class="name">lgG4值</view>
<view class="content">
<view class="c-left">
<view class="num">385</view>
<view class="sub">mg/dL</view>
<image class="icon" src="{{imageUrl}}icon143.png?t={{Timestamp}}"></image>
<image class="icon" src="{{imageUrl}}icon120.png?t={{Timestamp}}"></image>
</view>
</view>
<view class="row">
<view class="col">
<view class="c-name">激素用量</view>
<view class="c-content">10mg/天</view>
<!-- 就诊记录 -->
<block wx:if="{{currentTab === 1}}">
<view class="record-list">
<view class="card" wx:for="{{recordList}}" wx:key="id">
<view class="aside">
<view class="line-top"></view>
<view class="circle"></view>
<view class="line-bottom"></view>
</view>
<view class="wrap">
<view class="date">{{item.visitDate}}</view>
<view class="w-container">
<view class="name">IgG4值</view>
<view class="content">
<view class="c-left">
<view class="num">{{item.displayIgG4Value || '--'}}</view>
<view class="sub">mg/dL</view>
<image class="icon" wx:if="{{item.change > 0}}" src="{{imageUrl}}icon120.png?t={{Timestamp}}"></image>
<image class="icon" wx:elif="{{item.change < 0}}" src="{{imageUrl}}icon143.png?t={{Timestamp}}"></image>
</view>
</view>
<view class="col">
<view class="c-name">下次复诊时间</view>
<view class="c-content">2025.06.11</view>
<view class="row">
<view class="col" wx:if="{{item.oralHormoneDosage}}">
<view class="c-name">激素用量</view>
<view class="c-content">{{item.oralHormoneDosage}}mg/天</view>
</view>
<view class="col" wx:if="{{item.nextVisitDate}}">
<view class="c-name">下次复诊时间</view>
<view class="c-content">{{item.nextVisitDate}}</view>
</view>
</view>
</view>
</view>
</view>
<view class="empty-text" wx:if="{{!recordList.length}}">暂无就诊记录</view>
</view>
</view>
</block>
<view class="footer">
<view class="remark" bind:tap="handleRemark">备注</view>

2
src/doctor/pages/d_taskList/index.ts

@ -119,7 +119,7 @@ Page({ @@ -119,7 +119,7 @@ Page({
BindStartDate: FilterCondition.BindStartDate,
BindEndDate: FilterCondition.BindEndDate,
ConfirmedIgg4: FilterCondition.ConfirmedIgg4,
MedicationType: FilterCondition.MedicationType,
MedicationType: FilterCondition.MedicationType.split(',').map(Number),
})
},
})

12
src/doctor/pages/d_taskList/index.wxml

@ -12,14 +12,7 @@ @@ -12,14 +12,7 @@
</view>
<view class="row">
<view class="label">发布时间</view>
<view class="content">
{{item.SendTime}}
<image
wx:if="{{item.Status==='1'}}"
class="icon"
src="{{imageUrl}}/doctor/icon-date.png?t={{Timestamp}}"
></image>
</view>
<view class="content">{{item.SendTime}}</view>
</view>
<view class="row">
<view class="label">筛选条件</view>
@ -42,7 +35,8 @@ @@ -42,7 +35,8 @@
<view class="f-label">正在使用的药物:</view>
<view class="f-content">
<block wx:for="{{item.FilterCondition.MedicationTypeArr}}" wx:for-item="subItem" wx:key="subItem">
{{MedicationTypeObj[subItem]}}{{index < item.FilterCondition.MedicationTypeArr.length - 1 ? '、' : ''}}
{{MedicationTypeObj[subItem]}}{{index < item.FilterCondition.MedicationTypeArr.length - 1 ? '、' :
''}}
</block>
</view>
</view>

Loading…
Cancel
Save