Browse Source

2.0 联调&bug处理

dev
kola-web 2 weeks ago
parent
commit
afb0623190
  1. 173
      doc/api.md
  2. 47
      src/api/request.ts
  3. 1
      src/app.ts
  4. 4
      src/doctor/pages/d_caseReport/index.wxml
  5. 4
      src/doctor/pages/d_createTask/index.scss
  6. 48
      src/doctor/pages/d_createTask/index.ts
  7. 3
      src/doctor/pages/d_createTask/index.wxml
  8. 19
      src/doctor/pages/d_patientDetail/index.scss
  9. 65
      src/doctor/pages/d_patientDetail/index.ts
  10. 7
      src/doctor/pages/d_patientDetail/index.wxml
  11. 2
      src/doctor/pages/d_taskDetail/index.ts
  12. 26
      src/gift/pages/record/index.scss
  13. 147
      src/gift/pages/record/index.ts
  14. 27
      src/gift/pages/record/index.wxml
  15. 7
      src/gift/pages/recordDetail/index.scss
  16. 83
      src/gift/pages/recordDetail/index.ts
  17. 17
      src/gift/pages/recordDetail/index.wxml
  18. 20
      src/gift/pages/recordList/index.scss
  19. 76
      src/gift/pages/recordList/index.ts
  20. 9
      src/gift/pages/recordList/index.wxml
  21. BIN
      src/images/icon117.png
  22. BIN
      src/images/icon136.png
  23. 21
      src/pages/caseReport/index.scss
  24. 5
      src/pages/caseReport/index.ts
  25. 11
      src/pages/caseReport/index.wxml
  26. 14
      src/pages/index/index.scss
  27. 8
      src/pages/index/index.ts
  28. 17
      src/pages/index/index.wxml
  29. 3
      src/pages/login/index.ts
  30. 4
      src/pages/qaFormDetail/index.wxml
  31. 8
      src/utils/tools.wxs

173
doc/api.md

@ -296,12 +296,15 @@ @@ -296,12 +296,15 @@
"igG4Value": 135.0,
"manualIgG4Value": 135.0,
"displayIgG4Value": 135.0,
"lastIgG4Value": 120.0,
"change": 15.0,
"totalIgGValue": 1200.0,
"igEValue": 50.0,
"eosCount": 0.3,
"esrValue": 20.0,
"crpValue": 5.0,
"oralHormoneDosage": 4.0,
"oralHormoneDosageMg": 16.0,
"medicationsUsed": [2, 3],
"immunosuppressantName": [1, 7],
"medicationsUsedOtherText": null,
@ -427,6 +430,8 @@ @@ -427,6 +430,8 @@
"immunosuppressantNameOtherText": null,
"lastIgG4Value": 120.0,
"change": 15.0,
"oralHormoneDosage": 10.0,
"oralHormoneDosageMg": 50.0,
"medicalRecordTime": "2026-06-29 09:30:00",
"prescriptionTime": "2026-06-29 10:15:00",
"reportTime": "2026-06-28 14:20:00"
@ -442,6 +447,8 @@ @@ -442,6 +447,8 @@
- 同时传入 `year``count` 时,先按年份筛选再取最近 N 条
- `lastIgG4Value`:上一次就诊的 IgG4 值,float 类型;无上一次记录时为 null
- `change`:本次与上一次 IgG4 值的差值(本次 - 上次),float 类型;任一值为 null 时为 null
- `oralHormoneDosage`:本次就诊的口服激素剂量(片),未录入时为 null
- `oralHormoneDosageMg`:本次就诊的口服激素剂量(float 类型),未录入时为 null
- `manualIgG4Value`:患者手动录入的 IgG4 数值(冗余字段),未录入时为 null
- `displayIgG4Value`:展示用 IgG4 数值,优先取 manualIgG4Value,为空则取 igG4Value;均为空时为 null
- `medicalRecordTime`:病历时间(从门诊病历图片聚合),格式 YYYY-MM-DD 或 YYYY-MM-DD HH:mm:ss,无数据时为 null
@ -796,6 +803,84 @@ @@ -796,6 +803,84 @@
---
### 1.12 获取枚举选项
- **路由**:`?r=igg4/medical-visit/get-enums`
- **请求方式**:GET
- **说明**:获取前端所需的全部枚举选项数据,统一返回。无请求参数。
#### 响应示例
```json
{
"code": 0,
"message": "success",
"data": {
"recordStatus": [
{"value": 1, "label": "草稿"},
{"value": 2, "label": "已提交"}
],
"oralHormoneDosage": [
{"value": 1, "label": "1片"},
{"value": 2, "label": "2片"},
{"value": 4, "label": "4片"},
{"value": 6, "label": "6片"},
{"value": 8, "label": "8片"}
],
"medicationsUsed": [
{"value": 1, "label": "没有使用激素"},
{"value": 2, "label": "激素"},
{"value": 3, "label": "免疫抑制剂"},
{"value": 4, "label": "靶向CD19生物制剂(伊奈利珠单抗)"},
{"value": 5, "label": "靶向CD20生物制剂(利妥昔单抗等)"},
{"value": 99, "label": "其他"}
],
"immunosuppressantName": [
{"value": 1, "label": "吗替麦考酚酯(骁悉、麦考芬)"},
{"value": 2, "label": "替唑嘌呤"},
{"value": 3, "label": "环磷酰胺"},
{"value": 4, "label": "来氟米特"},
{"value": 5, "label": "甲氨蝶呤"},
{"value": 6, "label": "环孢素 A"},
{"value": 7, "label": "他克莫司"},
{"value": 8, "label": "艾拉莫德"},
{"value": 99, "label": "其他"}
],
"imageType": [
{"value": "outpatientRecord", "label": "门诊病历及处方"},
{"value": "labReport", "label": "检验报告"},
{"value": "imagingExam", "label": "影像学检查"},
{"value": "pathology", "label": "病理诊断及活检"},
{"value": "immuneFunction", "label": "外周血免疫功能评估"}
],
"ocrStatus": [
{"value": 0, "label": "待解析"},
{"value": 1, "label": "解析中"},
{"value": 2, "label": "解析完成"},
{"value": 3, "label": "解析失败"}
],
"reminder": [
{"value": 1, "label": "开启复诊提醒"},
{"value": 2, "label": "关闭复诊提醒"}
]
}
}
```
#### 字段说明
| 字段 | 类型 | 说明 |
|------|------|------|
| recordStatus | array | 记录状态枚举,value=状态值,label=中文描述 |
| oralHormoneDosage | array | 口服激素用量预设选项,value=片数,label=中文描述 |
| medicationsUsed | array | 本次就诊已使用药物,value=常量ID,label=中文描述,99=其他需补充文本 |
| immunosuppressantName | array | 免疫抑制剂名称,value=常量ID,label=中文描述,99=其他需补充文本 |
| imageType | array | 图片类型,value=小驼峰标识(用于接口参数),label=中文描述 |
| ocrStatus | array | OCR解析状态,value=状态值,label=中文描述 |
| reminder | array | 复诊提醒开关,value=状态值,label=中文描述 |
---
## 二、医生端接口
模块路由前缀:`igg4/doctor/medical-visit`
@ -1295,94 +1380,6 @@ @@ -1295,94 +1380,6 @@
| ESR | — | mm/h | 不换算 |
| CRP | — | mg/L | 不换算 |
### E. 数据库表结构
#### t_iggfour_medical_visit_record 就诊记录主表
| 字段名 | 类型 | 说明 |
|--------|------|------|
| Id | int AUTO_INCREMENT PK | 主键 |
| UserId | varchar(40) NOT NULL | 用户 ID |
| PatientId | int NOT NULL | 患者 ID |
| VisitDate | date NOT NULL | 就诊日期 |
| NextVisitDate | date DEFAULT NULL | 下次复诊日期 |
| IgG4Value | decimal(10,2) DEFAULT NULL | IgG4 数值(OCR 解析) |
| ManualIgG4Value | decimal(10,2) DEFAULT NULL | IgG4 数值(患者手动录入,冗余字段) |
| TotalIgGValue | decimal(10,2) DEFAULT NULL | 总 IgG 数值 |
| IgEValue | decimal(10,2) DEFAULT NULL | IgE 数值 |
| EosCount | decimal(10,2) DEFAULT NULL | EOS# 计数 |
| ESRValue | decimal(10,2) DEFAULT NULL | ESR 数值 |
| CRPValue | decimal(10,2) DEFAULT NULL | CRP 数值 |
| OralHormoneDosage | decimal(10,2) DEFAULT NULL | 口服激素每日用量(片) |
| MedicationsUsed | varchar(255) DEFAULT NULL | 本次就诊已使用的药物(JSON数组,多选),见附录G |
| ImmunosuppressantName | varchar(255) DEFAULT NULL | 正在使用的免疫抑制剂名称(JSON数组,多选),见附录G |
| MedicationsUsedOtherText | varchar(500) DEFAULT NULL | 本次就诊已使用药物-其他-补充文本 |
| ImmunosuppressantNameOtherText | varchar(500) DEFAULT NULL | 正在使用的免疫抑制剂名称-其他-补充文本 |
| MedicalRecordTime | varchar(30) DEFAULT NULL | 门诊病历时间 |
| PrescriptionTime | varchar(30) DEFAULT NULL | 处方时间 |
| ReportTime | varchar(30) DEFAULT NULL | 检查报告时间 |
| ChiefComplaint | text DEFAULT NULL | 主诉 |
| MedicalHistory | text DEFAULT NULL | 病史 |
| Diagnosis | text DEFAULT NULL | 诊断 |
| TreatmentPlan | text DEFAULT NULL | 处理意见 |
| Prescription | text DEFAULT NULL | 处方内容 |
| ClinicalDiagnosis | varchar(500) DEFAULT NULL | 临床诊断(从处方图片解析) |
| RecordStatus | tinyint NOT NULL DEFAULT 1 | 记录状态:1-草稿,2-已提交 |
| LastRecordId | int DEFAULT NULL | 上一条记录 ID |
| Status | tinyint NOT NULL DEFAULT 1 | 数据状态:1-有效,100-删除 |
| CreateWorkerId | int NOT NULL DEFAULT 0 | 创建人 |
| CreateTime | datetime NOT NULL | 创建时间 |
| UpdateWorkerId | int NOT NULL DEFAULT 0 | 更新人 |
| UpdateTime | datetime NOT NULL | 更新时间 |
#### t_iggfour_medical_visit_record_image 就诊记录图片表
| 字段名 | 类型 | 说明 |
|--------|------|------|
| Id | int AUTO_INCREMENT PK | 主键 |
| RecordId | int NOT NULL | 关联就诊记录 ID |
| ImageType | tinyint NOT NULL | 图片类型:1-门诊病历,2-检验报告,3-影像检查,4-其他 |
| ImageUrl | varchar(500) NOT NULL | 原始图片 URL |
| MaskedImageUrl | varchar(500) DEFAULT NULL | 涂抹后图片 URL |
| OcrStatus | tinyint NOT NULL DEFAULT 0 | OCR 状态:0-未解析,1-解析中,2-解析完成,3-解析失败 |
| OcrText | text DEFAULT NULL | OCR 原始文本 |
| OcrParsedData | text DEFAULT NULL | OCR 解析结果(JSON) |
| IgG4Value | decimal(10,2) DEFAULT NULL | IgG4 数值 |
| TotalIgGValue | decimal(10,2) DEFAULT NULL | 总 IgG 数值 |
| IgEValue | decimal(10,2) DEFAULT NULL | IgE 数值 |
| EosCount | decimal(10,2) DEFAULT NULL | EOS# 计数 |
| ESRValue | decimal(10,2) DEFAULT NULL | ESR 数值 |
| CRPValue | decimal(10,2) DEFAULT NULL | CRP 数值 |
| ChiefComplaint | text DEFAULT NULL | 主诉(从门诊病历图片解析) |
| MedicalHistory | text DEFAULT NULL | 病史(从门诊病历图片解析) |
| Diagnosis | text DEFAULT NULL | 诊断(从门诊病历图片解析) |
| TreatmentPlan | text DEFAULT NULL | 处理意见(从门诊病历图片解析) |
| Prescription | text DEFAULT NULL | 从本图OCR解析的处方内容,仅图片类型=1时有值 |
| ClinicalDiagnosis | varchar(500) DEFAULT NULL | 临床诊断(从处方图片解析) |
| MedicalRecordTime | varchar(30) DEFAULT NULL | 门诊病历时间 |
| PrescriptionTime | varchar(30) DEFAULT NULL | 处方时间 |
| ReportTime | varchar(30) DEFAULT NULL | 检查报告时间 |
| SortOrder | int NOT NULL DEFAULT 0 | 排序序号 |
| Status | tinyint NOT NULL DEFAULT 1 | 数据状态:1-有效,100-删除 |
| CreateWorkerId | int NOT NULL DEFAULT 0 | 创建人 |
| CreateTime | datetime NOT NULL | 创建时间 |
| UpdateWorkerId | int NOT NULL DEFAULT 0 | 更新人 |
| UpdateTime | datetime NOT NULL | 更新时间 |
#### t_medical_visit_reminder_config 复诊提醒配置表
| 字段名 | 类型 | 说明 |
|--------|------|------|
| Id | int AUTO_INCREMENT PK | 主键 |
| PatientId | int NOT NULL | 患者 ID(唯一索引) |
| ReminderEnabled | tinyint NOT NULL DEFAULT 2 | 是否开启复诊提醒:1-开启,2-关闭 |
| Status | tinyint NOT NULL DEFAULT 1 | 数据状态:1-有效,100-删除 |
| CreateWorkerId | int DEFAULT NULL | 创建人 |
| CreateTime | datetime DEFAULT NULL | 创建时间 |
| UpdateWorkerId | int DEFAULT NULL | 更新人 |
| UpdateTime | datetime DEFAULT NULL | 更新时间 |
### G. 药物选项枚举
#### MedicationsUsed 本次就诊已使用的药物(多选)

47
src/api/request.ts

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
interface IGlobalParams {
gUrl: string;
version: string;
gUrl: string
version: string
}
export const request = function (
@ -10,9 +10,9 @@ export const request = function ( @@ -10,9 +10,9 @@ export const request = function (
return new Promise((resolve, reject) => {
if (loading) {
wx.showLoading({
title: "加载中...",
title: '加载中...',
mask: true,
});
})
}
wx.request({
header: {
@ -27,46 +27,47 @@ export const request = function ( @@ -27,46 +27,47 @@ export const request = function (
},
...options,
success(res: any) {
const { code, data } = res.data;
const { code, data } = res.data
if (isJSON) {
resolve(res.data);
resolve(res.data)
} else if (code === 0) {
resolve(data);
resolve(data)
} else if (showMsg) {
const msg = errPicker(res.data);
const msg = errPicker(res.data)
if (loading) {
setTimeout(() => {
wx.showToast({
title: msg,
icon: "none",
});
}, 30);
icon: 'none',
})
}, 30)
reject(res)
} else {
wx.showToast({
title: msg,
icon: "none",
});
reject(res);
icon: 'none',
})
reject(res)
}
} else {
reject(res);
reject(res)
}
},
fail(err) {
reject(err);
reject(err)
},
complete() {
if (loading) {
wx.hideLoading();
wx.hideLoading()
}
},
});
});
};
})
})
}
function errPicker(err) {
if (typeof err === "string") {
return err;
if (typeof err === 'string') {
return err
}
return err.data || err.msg || err.errMsg || (err.detail && err.detail.errMsg) || "未知错误";
return err.data || err.msg || err.message || err.errMsg || (err.detail && err.detail.errMsg) || '未知错误'
}

1
src/app.ts

@ -248,7 +248,6 @@ App<IAppOption>({ @@ -248,7 +248,6 @@ App<IAppOption>({
verifySys(pub = false) {
// 1:患者 2:医生
const { loginType, isLogin, anyWhere } = this.globalData
console.log('DEBUGPRINT[229]: app.ts:246: loginType=', loginType)
const pages = getCurrentPages()
const currentPage = pages[pages.length - 1]
const url = currentPage.route

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

@ -25,7 +25,5 @@ @@ -25,7 +25,5 @@
</view>
</view>
</view>
<pagination pagination="{{pagination}}" customEmpty emptyTitle="暂无记录">
<view class="empty-text" slot>暂无记录</view>
</pagination>
<pagination pagination="{{pagination}}"></pagination>
</view>

4
src/doctor/pages/d_createTask/index.scss

@ -119,7 +119,9 @@ page { @@ -119,7 +119,9 @@ page {
border-color: rgba(22, 121, 203, 1);
}
&:nth-of-type(4),
&:nth-of-type(5) {
&:nth-of-type(5),
&:nth-of-type(6),
&:nth-of-type(7) {
width: 100%;
}
}

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

@ -14,8 +14,8 @@ Page({ @@ -14,8 +14,8 @@ Page({
start: dayjs().format('HH:mm'),
end: '19:00',
disabledTime: Number(dayjs().format('HH')) * 1 > 19,
sendDay: 0, // 0 今天 1 明天
disabledTime: dayjs().format('HH:mm') >= '19:00',
sendDay: dayjs().format('HH:mm') >= '19:00' ? 1 : 0, // 0 今天 1 明天
PushTemplateId: 0, //推送模板
IsSendNow: 0, //是否立即发送 0-定时,1-立即
@ -37,10 +37,12 @@ Page({ @@ -37,10 +37,12 @@ Page({
],
MedicationTypeColumn: [
{ id: 0, value: '全部' },
{ id: 2, value: '激素' },
{ id: 3, value: '免疫抑制剂' },
{ id: 4, value: '靶向CD19生物制剂(伊奈利珠单抗)' },
{ id: 5, value: '靶向CD20生物制剂(利妥昔单抗等)' },
{"id": 99, "value": "其他"},
{"id": 2, "value": "激素"},
{"id": 1, "value": "没有使用激素"},
{"id": 3, "value": "免疫抑制剂"},
{"id": 4, "value": "靶向CD19生物制剂(伊奈利珠单抗)"},
{"id": 5, "value": "靶向CD20生物制剂(利妥昔单抗等)"},
],
},
onLoad() {
@ -71,8 +73,12 @@ Page({ @@ -71,8 +73,12 @@ Page({
},
onShow() {
this.handleViewMp()
const isAfter19 = dayjs().format('HH:mm') >= '19:00'
this.setData({
time: Number(dayjs().format('HH')) * 1 >= 12 ? dayjs().format('HH:mm') : '12:00',
disabledTime: isAfter19,
sendDay: isAfter19 ? 1 : 0,
start: isAfter19 ? '08:00' : dayjs().format('HH:mm'),
time: isAfter19 ? '12:00' : (Number(dayjs().format('HH')) * 1 >= 12 ? dayjs().format('HH:mm') : '12:00'),
})
},
getTemplate() {
@ -171,14 +177,30 @@ Page({ @@ -171,14 +177,30 @@ Page({
},
handleDay(e) {
const { value } = e.currentTarget.dataset
const isAfter19 = dayjs().format('HH:mm') >= '19:00'
if (value === 0 && isAfter19) {
wx.showToast({ title: '已超过今天发送时间', icon: 'none' })
return
}
const currentTime = Number(dayjs().format('HH')) * 1 >= 12 ? dayjs().format('HH:mm') : '12:00'
this.setData({
time: value === 0 ? currentTime : '12:00',
sendDay: value,
start: value === 0 ? dayjs().format('HH:mm') : '08:00',
disabledTime: value === 0 ? Number(dayjs().format('HH')) * 1 > 19 : false,
disabledTime: false,
})
},
handleTimeChange(e) {
const value = e.detail.value as string
const { start, end } = this.data
if (value < start) {
wx.showToast({ title: `发送时间为 ${start}-${end}`, icon: 'none' })
this.setData({ time: start })
} else if (value > end) {
wx.showToast({ title: `发送时间为 ${start}-${end}`, icon: 'none' })
this.setData({ time: end })
}
},
handleDateToast() {
const { disabledTime } = this.data
if (disabledTime) {
@ -275,6 +297,16 @@ Page({ @@ -275,6 +297,16 @@ Page({
})
return
}
if (IsSendNow === 0 && time) {
const { start, end } = this.data
if (time < start || time > end) {
wx.showToast({
icon: 'none',
title: `发送时间为 ${start}-${end}`,
})
return
}
}
if (!PushTemplateId) {
wx.showToast({
icon: 'none',

3
src/doctor/pages/d_createTask/index.wxml

@ -103,7 +103,7 @@ @@ -103,7 +103,7 @@
</view>
<block wx:if="{{IsSendNow===0}}">
<view class="date-btns">
<view class="btn {{sendDay===0 && 'active'}}" bind:tap="handleDay" data-value="{{0}}">今天</view>
<view class="btn {{sendDay===0 && 'active'}}" wx:if="{{!disabledTime}}" bind:tap="handleDay" data-value="{{0}}">今天</view>
<view class="btn {{sendDay===1 && 'active'}}" bind:tap="handleDay" data-value="{{1}}">明天</view>
</view>
<view class="date-range" bind:tap="handleDateToast">
@ -114,6 +114,7 @@ @@ -114,6 +114,7 @@
mode="time"
start="{{start}}"
end="{{end}}"
bindchange="handleTimeChange"
>
<view class="content" data-place="请选择发送时间">{{time}}</view>
</picker>

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

@ -199,6 +199,25 @@ page { @@ -199,6 +199,25 @@ page {
}
.w-chart {
height: 460rpx;
.w-empty {
padding-top: 86rpx;
text-align: center;
.icon {
width: 152rpx;
height: 139rpx;
}
.e-title {
margin-top: 24rpx;
font-size: 32rpx;
color: rgba(34, 34, 34, 0.2);
font-weight: bold;
}
.e-content {
margin-top: 10rpx;
font-size: 28rpx;
color: rgba(34, 34, 34, 0.2);
}
}
}
}
}

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

@ -4,27 +4,6 @@ const app = getApp<IAppOption>() @@ -4,27 +4,6 @@ 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,
@ -140,7 +119,8 @@ Page({ @@ -140,7 +119,8 @@ Page({
BeginMonth: dayjs().subtract(1, 'year').add(1, 'month').format('YYYY-MM'),
EndMonth: dayjs().format('YYYY-MM'),
chartUnit: '',
chartList: [] as any[],
chartList: [],
chartEmpty: true,
// 病历报告
caseReportList: [
@ -178,6 +158,10 @@ Page({ @@ -178,6 +158,10 @@ Page({
recordList: [] as any[],
recordPagination: { count: 0, page: 1, pages: 1 },
// 枚举
medicationsMap: {} as Record<number, string>,
immunosuppressantMap: {} as Record<number, string>,
// 导出PPT
pptGenerating: false,
},
@ -192,8 +176,8 @@ Page({ @@ -192,8 +176,8 @@ Page({
app.mpBehavior({ doctor: true, PageName: 'PG_DoctorPatientDetail', detailId: this.data.id })
this.getDoctorDetail()
await this.getDetail()
this.getEnums()
this.getIndicatorHistory()
this.getRecordList(true)
})
},
@ -386,16 +370,43 @@ Page({ @@ -386,16 +370,43 @@ Page({
data,
}).then((res: any) => {
if (!res) return
const chartList = res.list || []
const chartEmpty = !chartList.length
this.setData({
chartUnit: res.unit || 'mg/dL',
chartList: res.list || [],
chartList,
chartEmpty,
}, () => {
if (!chartEmpty) {
this.ecDataTrendComponent = null
this.initChart(chartList.reverse() || [])
}
})
this.initChart(res.list || [])
})
},
// ========== 就诊记录列表 ==========
getEnums() {
wx.ajax({
method: 'GET',
url: '?r=igg4/medical-visit/get-enums',
}).then((res: any) => {
if (!res) return
const medicationsMap: Record<number, string> = {}
for (const item of res.medicationsUsed || []) {
medicationsMap[item.value] = item.label
}
const immunosuppressantMap: Record<number, string> = {}
for (const item of res.immunosuppressantName || []) {
immunosuppressantMap[item.value] = item.label
}
this.setData({ medicationsMap, immunosuppressantMap })
// 枚举加载后刷新列表以应用新映射
this.getRecordList(true)
})
},
getRecordList(reset = false) {
const page = reset ? 1 : this.data.recordPagination.page
wx.ajax({
@ -410,9 +421,9 @@ Page({ @@ -410,9 +421,9 @@ Page({
if (!res) return
const list = (res.list || []).map((item: any) => ({
...item,
medicationLabels: (item.medicationsUsed || []).map((id: number) => MEDICATIONS_MAP[id]).filter(Boolean),
medicationLabels: (item.medicationsUsed || []).map((id: number) => this.data.medicationsMap[id]).filter(Boolean),
immunosuppressantLabels: (item.immunosuppressantName || [])
.map((id: number) => IMMUNOSUPPRESSANT_MAP[id])
.map((id: number) => this.data.immunosuppressantMap[id])
.filter(Boolean),
}))

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

@ -96,7 +96,12 @@ @@ -96,7 +96,12 @@
<view class="sub">单位{{chartUnit}}</view>
</view>
<view class="w-chart">
<ec-canvas id="chart1" ec="{{ ec }}"></ec-canvas>
<ec-canvas wx:if="{{!chartEmpty}}" id="chart1" ec="{{ ec }}"></ec-canvas>
<view wx:if="{{chartEmpty}}" class="w-empty">
<image class="icon" src="/images/empty2.png"></image>
<view class="e-title">暂无数据</view>
<view class="e-content">还没有您的记录信息哦~</view>
</view>
</view>
</view>
</view>

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

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

26
src/gift/pages/record/index.scss

@ -195,6 +195,7 @@ page { @@ -195,6 +195,7 @@ page {
background: transparent;
}
&::after {
margin-left: 12rpx;
padding: 0 16rpx;
line-height: 40rpx;
content: '选填';
@ -369,7 +370,7 @@ page { @@ -369,7 +370,7 @@ page {
color: rgba(0, 0, 0, 1);
}
.place-input {
color: rgba(0, 0, 0, 0.4);
color: rgba(34, 34, 34, 0.4);
}
.icon {
position: absolute;
@ -381,19 +382,18 @@ page { @@ -381,19 +382,18 @@ page {
.sub {
flex-shrink: 0;
font-size: 36rpx;
color: rgba(34, 34, 34, 0.3);
color: rgba(34, 34, 34, 0.4);
}
}
.num-tip {
margin-top: 24rpx;
font-size: 32rpx;
color: rgba(34, 34, 34, 0.4);
}
.check-group {
margin-top: 32rpx;
display: grid;
gap: 24rpx;
&.col1 {
grid-template-columns: repeat(auto-fill, minmax(300rpx, 1fr));
}
&.col2 {
grid-template-columns: repeat(2, 1fr);
}
.check-item {
display: flex;
gap: 24rpx;
@ -431,6 +431,9 @@ page { @@ -431,6 +431,9 @@ page {
display: block;
}
}
.content {
color: rgba(34, 34, 34, 0.7);
}
}
}
}
@ -449,10 +452,7 @@ page { @@ -449,10 +452,7 @@ page {
background-color: rgba(248, 248, 248, 1);
border: 1px solid rgba(248, 248, 248, 1);
box-sizing: border-box;
.content {
font-size: 36rpx;
color: rgba(34, 34, 34, 0.7);
}
&.active {
border-color: rgba(14, 182, 109, 1);
background-color: rgba(14, 182, 109, 0.08);
@ -475,11 +475,11 @@ page { @@ -475,11 +475,11 @@ page {
color: rgba(0, 0, 0, 1);
}
.place-input {
color: rgba(0, 0, 0, 0.4);
color: rgba(34, 34, 34, 0.4);
}
.sub {
font-size: 36rpx;
color: rgba(0, 0, 0, 0.8);
color: rgba(34, 34, 34, 0.4);
}
}
}

147
src/gift/pages/record/index.ts

@ -1,29 +1,7 @@ @@ -1,29 +1,7 @@
import { debounce } from 'miniprogram-licia'
const dayjs = require('dayjs')
const _app = getApp<IAppOption>()
const MEDICATIONS_OPTIONS = [
{ id: 1, label: '没有使用激素', active: false },
{ id: 2, label: '激素', active: false },
{ id: 3, label: '免疫抑制剂', active: false },
{ id: 4, label: '靶向CD19生物制剂(伊奈利珠单抗)', active: false },
{ id: 5, label: '靶向CD20生物制剂(利妥昔单抗等)', active: false },
{ id: 99, label: '其他', active: false },
]
const IMMUNOSUPPRESSANT_OPTIONS = [
{ id: 1, label: '吗替麦考酚酯(骁悉、麦考芬)', active: false },
{ id: 2, label: '替唑嘌呤', active: false },
{ id: 3, label: '环磷酰胺', active: false },
{ id: 4, label: '来氟米特', active: false },
{ id: 5, label: '甲氨蝶呤', active: false },
{ id: 6, label: '环孢素 A', active: false },
{ id: 7, label: '他克莫司', active: false },
{ id: 8, label: '艾拉莫德', active: false },
{ id: 99, label: '其他', active: false },
]
const HORMONE_DOSAGE_OPTIONS = [1, 2, 4, 6, 8, 0.5]
const IMAGE_TYPE_MAP: Record<string, string> = {
outpatientRecord: 'outpatientRecord',
labReport: 'labReport',
@ -55,9 +33,9 @@ Page({ @@ -55,9 +33,9 @@ Page({
immunosuppressantName: [] as number[],
oralHormoneDosage: 0,
customDosage: '',
medicationsOptions: MEDICATIONS_OPTIONS,
immunosuppressantOptions: IMMUNOSUPPRESSANT_OPTIONS,
hormoneDosageOptions: HORMONE_DOSAGE_OPTIONS,
medicationsOptions: [] as { id: number; label: string; active: boolean }[],
immunosuppressantOptions: [] as { id: number; label: string; active: boolean }[],
hormoneDosageOptions: [] as number[],
// 其他输入
medicationsUsedOtherText: '',
@ -71,23 +49,30 @@ Page({ @@ -71,23 +49,30 @@ Page({
toastParams: {} as any,
saving: false,
submitted: false,
today: dayjs().format('YYYY-MM-DD'),
tomorrow: dayjs().add(1, 'day').format('YYYY-MM-DD'),
focus: false,
},
_saveDraftDebounced: null as any,
onLoad(options: any) {
_app.waitLogin().then(() => {
_app.permissionVerification(3, 0, '/gift/pages/record/index').then(() => {
_app.mpBehavior({ PageName: 'PG_PatientRecordAdd' })
})
this.getEnums().then(() => {
if (options.id) {
this.setData({ draftId: Number(options.id) })
_app.waitLogin().then(() => {
this.getDetail()
})
}
})
})
})
this._saveDraftDebounced = debounce(() => {
this.saveDraft()
this.saveDraft().catch(() => {})
}, 800)
},
@ -99,7 +84,7 @@ Page({ @@ -99,7 +84,7 @@ Page({
if (this.data.submitted || !this._hasFilledData()) {
wx.disableAlertBeforeUnload()
} else {
wx.enableAlertBeforeUnload({ message: '您有填写信息还未提交' })
wx.enableAlertBeforeUnload({ message: '已填写信息将被保存为草稿', })
}
},
@ -114,6 +99,30 @@ Page({ @@ -114,6 +99,30 @@ Page({
// ========== API ==========
getEnums(): Promise<void> {
return wx
.ajax({
method: 'GET',
url: '?r=igg4/medical-visit/get-enums',
})
.then((res: any) => {
if (!res) return
this.setData({
medicationsOptions: (res.medicationsUsed || []).map((item: any) => ({
id: item.value,
label: item.label,
active: false,
})),
immunosuppressantOptions: (res.immunosuppressantName || []).map((item: any) => ({
id: item.value,
label: item.label,
active: false,
})),
hormoneDosageOptions: (res.oralHormoneDosage || []).map((item: any) => item.value),
})
})
},
getDetail() {
wx.ajax({
method: 'GET',
@ -128,18 +137,18 @@ Page({ @@ -128,18 +137,18 @@ Page({
igG4Value: res.manualIgG4Value != null ? String(res.manualIgG4Value) : '',
medicationsUsed: res.medicationsUsed || [],
immunosuppressantName: res.immunosuppressantName || [],
medicationsOptions: MEDICATIONS_OPTIONS.map((item) => ({
medicationsOptions: this.data.medicationsOptions.map((item) => ({
...item,
active: (res.medicationsUsed || []).includes(item.id),
})),
immunosuppressantOptions: IMMUNOSUPPRESSANT_OPTIONS.map((item) => ({
immunosuppressantOptions: this.data.immunosuppressantOptions.map((item) => ({
...item,
active: (res.immunosuppressantName || []).includes(item.id),
})),
oralHormoneDosage: res.oralHormoneDosage || 0,
oralHormoneDosage: res.oralHormoneDosage ? Number(res.oralHormoneDosage) : 0,
recordStatus: res.recordStatus,
customDosage:
res.oralHormoneDosage && !HORMONE_DOSAGE_OPTIONS.includes(res.oralHormoneDosage)
res.oralHormoneDosage && !this.data.hormoneDosageOptions.includes(Number(res.oralHormoneDosage))
? String(res.oralHormoneDosage)
: '',
medicationsUsedOtherText: res.medicationsUsedOtherText || '',
@ -165,8 +174,8 @@ Page({ @@ -165,8 +174,8 @@ Page({
},
saveDraft(): Promise<any> {
if (this.data.saving) return Promise.resolve()
if (!this.data.visitDate) return Promise.resolve()
if (this.data.saving) return Promise.reject(new Error('saving'))
if (!this.data.visitDate) return Promise.reject(new Error('no visitDate'))
this.setData({ saving: true })
@ -218,7 +227,6 @@ Page({ @@ -218,7 +227,6 @@ Page({
this.setData({ recordStatus: res.recordStatus })
}
})
.catch(() => {})
.finally(() => {
this.setData({ saving: false })
})
@ -226,6 +234,8 @@ Page({ @@ -226,6 +234,8 @@ Page({
autoSave() {
this._updateAlertBeforeUnload()
// 编辑已提交的记录时不在实时保存,提交时统一保存
if (this.data.recordStatus === 2) return
if (this._saveDraftDebounced) {
this._saveDraftDebounced()
}
@ -255,12 +265,22 @@ Page({ @@ -255,12 +265,22 @@ Page({
// ========== Step1 事件 ==========
handleVisitDateChange(e: WechatMiniprogram.PickerChange) {
this.setData({ visitDate: e.detail.value as string })
const value = e.detail.value as string
if (value > dayjs().format('YYYY-MM-DD')) {
wx.showToast({ title: '就诊时间不能超过今天', icon: 'none' })
return
}
this.setData({ visitDate: value })
this.autoSave()
},
handleNextVisitDateChange(e: WechatMiniprogram.PickerChange) {
this.setData({ nextVisitDate: e.detail.value as string })
const value = e.detail.value as string
if (value <= dayjs().format('YYYY-MM-DD')) {
wx.showToast({ title: '复诊时间必须在今天之后', icon: 'none' })
return
}
this.setData({ nextVisitDate: value })
this.autoSave()
},
@ -269,6 +289,10 @@ Page({ @@ -269,6 +289,10 @@ Page({
this.setData({ toastShow: true, toastType: 'oneWrite', toastParams: {} })
return
}
if (this.data.recordStatus === 2) {
this.setData({ step: 2 })
return
}
this.saveDraft().then(() => {
this.setData({ step: 2 })
})
@ -278,17 +302,22 @@ Page({ @@ -278,17 +302,22 @@ Page({
handleSetData(e: WechatMiniprogram.CustomEvent) {
const imageType = e.currentTarget.dataset.type as string
const file = e.detail[0]
const filesKey = `${imageType}Files`
const currentFiles = (this.data[filesKey as any] as any[]) || []
const newFile = {
const maxNum = 10
const remaining = maxNum - currentFiles.length
if (remaining <= 0) {
wx.showToast({ title: '最多上传10张图片', icon: 'none' })
return
}
const newFiles = (e.detail as any[]).slice(0, remaining).map((file) => ({
imgUrl: file.imgUrl,
fileUrl: file.imgUrl,
type: 'image',
imageType,
}
}))
this.setData({
[filesKey]: [...currentFiles, newFile],
[filesKey]: [...currentFiles, ...newFiles],
})
this.autoSave()
},
@ -330,6 +359,10 @@ Page({ @@ -330,6 +359,10 @@ Page({
},
handleStep2Prev() {
if (this.data.recordStatus === 2) {
this.setData({ step: 1 })
return
}
this.saveDraft().then(() => {
this.setData({ step: 1 })
})
@ -341,6 +374,10 @@ Page({ @@ -341,6 +374,10 @@ Page({
this.setData({ toastShow: true, toastType: 'oneWrite', toastParams: {} })
return
}
if (this.data.recordStatus === 2) {
this.setData({ step: 3 })
return
}
this.saveDraft().then(() => {
this.setData({ step: 3 })
})
@ -349,7 +386,10 @@ Page({ @@ -349,7 +386,10 @@ Page({
// ========== Step3 事件 ==========
handleIgG4Input(e: WechatMiniprogram.Input) {
this.setData({ igG4Value: e.detail.value })
const value = e.detail.value
// 限制小数点后一位
const formatted = value.replace(/^(\d+\.\d).*/, '$1').replace(/^\.$/, '0.')
this.setData({ igG4Value: formatted })
this.autoSave()
},
@ -361,11 +401,14 @@ Page({ @@ -361,11 +401,14 @@ Page({
})
const usedIds = options.filter((item) => item.active).map((item) => item.id)
const isOtherActive = usedIds.includes(99)
const isHormoneActive = usedIds.includes(2)
this.setData({
medicationsOptions: options,
medicationsUsed: usedIds,
medicationsOtherShow: isOtherActive,
medicationsUsedOtherText: isOtherActive ? this.data.medicationsUsedOtherText : '',
oralHormoneDosage: isHormoneActive ? this.data.oralHormoneDosage : 0,
customDosage: isHormoneActive ? this.data.customDosage : '',
})
this.autoSave()
},
@ -415,6 +458,10 @@ Page({ @@ -415,6 +458,10 @@ Page({
},
handleStep3Prev() {
if (this.data.recordStatus === 2) {
this.setData({ step: 2 })
return
}
this.saveDraft().then(() => {
this.setData({ step: 2 })
})
@ -443,6 +490,16 @@ Page({ @@ -443,6 +490,16 @@ Page({
this.submit()
})
},
handleFocus() {
this.setData({
focus: true,
})
},
handleBlur() {
this.setData({
focus: false,
})
},
// ========== Toast 事件 ==========

27
src/gift/pages/record/index.wxml

@ -1,3 +1,4 @@ @@ -1,3 +1,4 @@
<wxs src="../../../utils/tools.wxs" module="tools" />
<view class="page" id="{{theme === 'DRUG' && 'drug-page'}}">
<view class="page-header">
<view class="item active">
@ -45,7 +46,7 @@ @@ -45,7 +46,7 @@
</view>
<view class="form-item">
<view class="label">我的下次就诊时间</view>
<picker mode="date" value="{{nextVisitDate}}" start="{{visitDate}}" bind:change="handleNextVisitDateChange">
<picker mode="date" value="{{nextVisitDate}}" start="{{tomorrow}}" bind:change="handleNextVisitDateChange">
<view class="date">
<image
class="icon1"
@ -93,10 +94,11 @@ @@ -93,10 +94,11 @@
</view>
</view>
<uploadFile
wx:if="{{outpatientRecordFiles.length < 10}}"
fileTypes="{{['image']}}"
bind:setData="handleSetData"
data-type="outpatientRecord"
maxNum="{{10}}"
count="{{10 - outpatientRecordFiles.length}}"
isSlot="{{true}}"
>
<view class="upload-container">
@ -138,10 +140,11 @@ @@ -138,10 +140,11 @@
</view>
</view>
<uploadFile
wx:if="{{labReportFiles.length < 10}}"
fileTypes="{{['image']}}"
bind:setData="handleSetData"
data-type="labReport"
maxNum="{{10}}"
count="{{10 - labReportFiles.length}}"
isSlot="{{true}}"
>
<view class="upload-container">
@ -176,10 +179,11 @@ @@ -176,10 +179,11 @@
</view>
</view>
<uploadFile
wx:if="{{imagingExamFiles.length < 10}}"
fileTypes="{{['image']}}"
bind:setData="handleSetData"
data-type="imagingExam"
maxNum="{{10}}"
count="{{10 - imagingExamFiles.length}}"
isSlot="{{true}}"
>
<view class="upload-container">
@ -214,10 +218,11 @@ @@ -214,10 +218,11 @@
</view>
</view>
<uploadFile
wx:if="{{pathologyFiles.length < 10}}"
fileTypes="{{['image']}}"
bind:setData="handleSetData"
data-type="pathology"
maxNum="{{10}}"
count="{{10 - pathologyFiles.length}}"
isSlot="{{true}}"
>
<view class="upload-container">
@ -252,10 +257,11 @@ @@ -252,10 +257,11 @@
</view>
</view>
<uploadFile
wx:if="{{immuneFunctionFiles.length < 10}}"
fileTypes="{{['image']}}"
bind:setData="handleSetData"
data-type="immuneFunction"
maxNum="{{10}}"
count="{{10 - immuneFunctionFiles.length}}"
isSlot="{{true}}"
>
<view class="upload-container">
@ -300,14 +306,18 @@ @@ -300,14 +306,18 @@
maxlength="{{8}}"
value="{{igG4Value}}"
bindinput="handleIgG4Input"
focus="{{focus}}"
bind:blur="handleBlur"
/>
<image
class="icon"
src="{{imageUrl}}{{theme === 'DRUG' ? 'icon136' : 'icon117'}}.png?t={{Timestamp}}"
bind:tap="handleFocus"
></image>
</view>
<view class="sub">mg/dL</view>
</view>
<view class="num-tip">单位换算:1 g/L = 100 mg/dL</view>
</view>
<!-- 本次就诊已使用的药物 -->
@ -342,7 +352,7 @@ @@ -342,7 +352,7 @@
</view>
<!-- 口服激素每日用量 -->
<view class="form-card">
<view class="form-card" wx:if="{{tools.include(2, medicationsUsed)}}">
<view class="f-header">
<view class="label">最近一周,口服激素的每日用量</view>
</view>
@ -369,10 +379,11 @@ @@ -369,10 +379,11 @@
/>
<view class="sub">片</view>
</view>
<view class="num-tip">醋酸泼尼松,每片为5mg;甲泼尼龙,每片为4mg;临床可等效替换。</view>
</view>
<!-- 免疫抑制剂名称 -->
<view class="form-card">
<view class="form-card" wx:if="{{tools.include(3, medicationsUsed)}}">
<view class="f-header">
<view class="label">正在使用的免疫抑制剂名称</view>
</view>

7
src/gift/pages/recordDetail/index.scss

@ -131,6 +131,13 @@ page { @@ -131,6 +131,13 @@ page {
padding-bottom: 28rpx;
font-size: 36rpx;
color: rgba(34, 34, 34, 1);
display: flex;
align-items: center;
gap: 16rpx;
.icon {
width: 32rpx;
height: 37rpx;
}
}
}
}

83
src/gift/pages/recordDetail/index.ts

@ -1,32 +1,3 @@ @@ -1,32 +1,3 @@
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: '其他',
}
const IMAGE_TYPE_LABELS: Record<string, string> = {
outpatientRecord: '门诊病历及处方',
labReport: '检验报告',
imagingExam: '影像学检查',
pathology: '病理诊断及活检',
immuneFunction: '外周血免疫功能评估',
}
const app = getApp<IAppOption>()
Page({
@ -40,21 +11,61 @@ Page({ @@ -40,21 +11,61 @@ Page({
immunosuppressantLabel: '',
reminderEnabled: 2,
imageGroups: [] as { type: string; label: string; list: string[] }[],
change: 0,
// 枚举
medicationsMap: {} as Record<number, string>,
immunosuppressantMap: {} as Record<number, string>,
imageTypeLabels: {} as Record<string, string>,
},
onLoad(options: any) {
app.waitLogin().then(() => {
app.mpBehavior({ PageName: 'PG_PatientRecordDetail', detailId: String(options.id) })
})
this.getEnums().then(() => {
if (options.id) {
this.setData({ id: Number(options.id) })
this.getDetail()
this.getReminderConfig()
}
})
})
},
onShow() {
if (typeof this.__loaded === 'undefined') {
this.__loaded = true
return
}
this.getDetail()
this.getReminderConfig()
},
// ========== API ==========
getEnums(): Promise<void> {
return wx
.ajax({
method: 'GET',
url: '?r=igg4/medical-visit/get-enums',
})
.then((res: any) => {
if (!res) return
const medicationsMap: Record<number, string> = {}
for (const item of res.medicationsUsed || []) {
medicationsMap[item.value] = item.label
}
const immunosuppressantMap: Record<number, string> = {}
for (const item of res.immunosuppressantName || []) {
immunosuppressantMap[item.value] = item.label
}
const imageTypeLabels: Record<string, string> = {}
for (const item of res.imageType || []) {
imageTypeLabels[item.value] = item.label
}
this.setData({ medicationsMap, immunosuppressantMap, imageTypeLabels })
})
},
getDetail() {
wx.ajax({
method: 'GET',
@ -62,27 +73,30 @@ Page({ @@ -62,27 +73,30 @@ Page({
data: { id: this.data.id },
}).then((res: any) => {
if (!res) return
const { medicationsMap, immunosuppressantMap, imageTypeLabels } = this.data
const medicationsLabel = (res.medicationsUsed || [])
.map((id: number) => {
if (id === 99 && res.medicationsUsedOtherText) return `其他:${res.medicationsUsedOtherText}`
return MEDICATIONS_MAP[id]
if (id === 99) return ''
return medicationsMap[id]
})
.filter(Boolean)
.join('、')
const immunosuppressantLabel = (res.immunosuppressantName || [])
.map((id: number) => {
if (id === 99 && res.immunosuppressantNameOtherText) return `其他:${res.immunosuppressantNameOtherText}`
return IMMUNOSUPPRESSANT_MAP[id]
if (id === 99) return ''
return immunosuppressantMap[id]
})
.filter(Boolean)
.join('、')
const imageGroups: { type: string; label: string; list: string[] }[] = []
const images = res.images || {}
for (const type of Object.keys(IMAGE_TYPE_LABELS)) {
for (const type of Object.keys(imageTypeLabels)) {
const list = (images[type] || []).map((img: any) => img.maskedImageUrl || img.imageUrl)
if (list.length) {
imageGroups.push({ type, label: IMAGE_TYPE_LABELS[type], list })
imageGroups.push({ type, label: imageTypeLabels[type], list })
}
}
@ -94,6 +108,7 @@ Page({ @@ -94,6 +108,7 @@ Page({
oralHormoneDosageMg: res.oralHormoneDosageMg,
immunosuppressantLabel,
imageGroups,
change: res.change,
})
})
},

17
src/gift/pages/recordDetail/index.wxml

@ -18,7 +18,12 @@ @@ -18,7 +18,12 @@
</view>
<view class="switch-wrap">
<view class="name">复诊提醒</view>
<switch class="switch" checked="{{reminderEnabled === 1}}" bind:change="saveReminderConfig" color="{{theme === 'DRUG' ? 'rgba(89, 86, 233, 1)' : 'rgba(14, 182, 109, 1)'}}" />
<switch
class="switch"
checked="{{reminderEnabled === 1}}"
bind:change="saveReminderConfig"
color="{{theme === 'DRUG' ? 'rgba(89, 86, 233, 1)' : 'rgba(14, 182, 109, 1)'}}"
/>
</view>
<view class="photos" wx:for="{{imageGroups}}" wx:key="type">
<view class="p-header">{{item.label}}</view>
@ -39,7 +44,15 @@ @@ -39,7 +44,15 @@
<view class="container">
<view class="row" wx:if="{{displayIgG4Value !== null && displayIgG4Value !== ''}}">
<view class="name">IgG4值</view>
<view class="content">{{displayIgG4Value}} mg/dL</view>
<view class="content">
{{displayIgG4Value}} mg/dL
<image class="icon" wx:if="{{change > 0}}" src="{{imageUrl}}icon120.png?t={{Timestamp}}"></image>
<image
class="icon"
wx:elif="{{change < 0}}"
src="{{imageUrl}}{{theme === 'DRUG' ? 'icon132' : 'icon118'}}.png?t={{Timestamp}}"
></image>
</view>
</view>
<view class="row" wx:if="{{medicationsLabel}}">
<view class="name">本次就诊已使用的药物</view>

20
src/gift/pages/recordList/index.scss

@ -23,6 +23,7 @@ page { @@ -23,6 +23,7 @@ page {
color: rgba(34, 34, 34, 1);
.high {
color: rgba(14, 182, 109, 1);
font-weight: bold;
}
}
}
@ -105,6 +106,25 @@ page { @@ -105,6 +106,25 @@ page {
}
.w-chart {
height: 380rpx;
.w-empty {
padding-top: 86rpx;
text-align: center;
.icon {
width: 152rpx;
height: 139rpx;
}
.e-title {
margin-top: 24rpx;
font-size: 32rpx;
color: rgba(34, 34, 34, 0.2);
font-weight: bold;
}
.e-content {
margin-top: 10rpx;
font-size: 28rpx;
color: rgba(34, 34, 34, 0.2);
}
}
}
}
}

76
src/gift/pages/recordList/index.ts

@ -2,31 +2,14 @@ import dayjs from 'dayjs' @@ -2,31 +2,14 @@ import dayjs from 'dayjs'
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: {
list: [] as any[],
pagination: { count: 0, page: 1, pages: 1 },
// 枚举
medicationsMap: {} as Record<number, string>,
immunosuppressantMap: {} as Record<number, string>,
year: 0 as number,
yearOptions: [
{
@ -47,6 +30,7 @@ Page({ @@ -47,6 +30,7 @@ Page({
// 图表
chartUnit: '',
chartList: [] as any[],
chartEmpty: true,
selected: 1,
selectedLabel: '按年',
@ -59,22 +43,49 @@ Page({ @@ -59,22 +43,49 @@ Page({
echarts = mod
})
_app.waitLogin().then(() => {
_app.permissionVerification(3, 0, '/gift/pages/recordList/index').then(() => {
_app.mpBehavior({ PageName: 'PG_PatientRecordList' })
this.getEnums().then(() => {
this.getLatestRecord()
this.getList()
this.getIndicatorHistory()
})
})
})
},
onShow() {
if (this.data.list.length) {
if (typeof this.__loaded === 'undefined') {
this.__loaded = true
return
}
this.getLatestRecord()
this.getList(true)
}
this.getIndicatorHistory()
},
// ========== API ==========
getEnums(): Promise<void> {
return wx
.ajax({
method: 'GET',
url: '?r=igg4/medical-visit/get-enums',
})
.then((res: any) => {
if (!res) return
const medicationsMap: Record<number, string> = {}
for (const item of res.medicationsUsed || []) {
medicationsMap[item.value] = item.label
}
const immunosuppressantMap: Record<number, string> = {}
for (const item of res.immunosuppressantName || []) {
immunosuppressantMap[item.value] = item.label
}
this.setData({ medicationsMap, immunosuppressantMap })
})
},
getList(reset = false) {
const page = reset ? 1 : this.data.pagination.page
const data: Record<string, any> = { page, pageSize: 10 }
@ -87,9 +98,11 @@ Page({ @@ -87,9 +98,11 @@ Page({
if (!res) return
const list = (res.list || []).map((item: any) => ({
...item,
medicationLabels: (item.medicationsUsed || []).map((id: number) => MEDICATIONS_MAP[id]).filter(Boolean),
medicationLabels: (item.medicationsUsed || [])
.map((id: number) => this.data.medicationsMap[id])
.filter(Boolean),
immunosuppressantLabels: (item.immunosuppressantName || [])
.map((id: number) => IMMUNOSUPPRESSANT_MAP[id])
.map((id: number) => this.data.immunosuppressantMap[id])
.filter(Boolean),
statusText: item.recordStatus === 1 ? '草稿' : '已提交',
}))
@ -139,11 +152,18 @@ Page({ @@ -139,11 +152,18 @@ Page({
data,
}).then((res: any) => {
if (!res) return
const chartList = res.list || []
const chartEmpty = !chartList.length
this.setData({
chartUnit: res.unit || 'mg/dL',
chartList: res.list || [],
chartList,
chartEmpty,
}, () => {
if (!chartEmpty) {
this.ecDataTrendComponent = null
this.initChart((chartList as []).reverse() || [])
}
})
this.initChart(res.list || [])
})
},
@ -223,7 +243,7 @@ Page({ @@ -223,7 +243,7 @@ Page({
minInterval: 1,
axisLabel: { color: 'rgba(34, 34, 34, 0.40)' },
splitLine: {
show:false,
show: false,
lineStyle: { color: 'rgba(34, 34, 34, 0.20)', type: 'dashed' },
},
},

9
src/gift/pages/recordList/index.wxml

@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
<text class="high">{{latestIgG4}} mg/dL</text>
</view>
</view>
<view class="chart" wx:if="{{chartList.length}}">
<view class="chart">
<view class="c-header">
<view class="title">血清IgG4趋势监测</view>
<view class="sub">单位{{chartUnit}}</view>
@ -34,7 +34,12 @@ @@ -34,7 +34,12 @@
</view>
</view>
<view class="w-chart">
<ec-canvas id="chart1" ec="{{ ec }}"></ec-canvas>
<ec-canvas wx:if="{{!chartEmpty}}" id="chart1" ec="{{ ec }}"></ec-canvas>
<view wx:if="{{chartEmpty}}" class="w-empty">
<image class="icon" src="/images/empty2.png"></image>
<view class="e-title">暂无数据</view>
<view class="e-content">还没有您的记录信息哦~</view>
</view>
</view>
</view>
</view>

BIN
src/images/icon117.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
src/images/icon136.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

21
src/pages/caseReport/index.scss

@ -63,9 +63,24 @@ page { @@ -63,9 +63,24 @@ page {
.empty {
padding: 200rpx 0;
text-align: center;
.text {
font-size: 28rpx;
color: rgba(34, 34, 34, 0.4);
.e-content {
font-size: 32rpx;
color: rgba(34, 34, 34, 1);
line-height: 48rpx;
.high {
color: rgba(14, 182, 109, 1);
}
}
.btn {
margin-top: 76rpx;
height: 96rpx;
font-size: 36rpx;
color: rgba(255, 255, 255, 1);
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(86deg, #0eb66d 0%, #00d277 100%);
border-radius: 16rpx 16rpx 16rpx 16rpx;
}
}
}

5
src/pages/caseReport/index.ts

@ -56,6 +56,11 @@ Page({ @@ -56,6 +56,11 @@ Page({
urls,
})
},
handleRecord() {
wx.navigateTo({
url: '/gift/pages/record/index',
})
},
})
export {}

11
src/pages/caseReport/index.wxml

@ -25,7 +25,14 @@ @@ -25,7 +25,14 @@
</view>
</view>
</view>
<pagination pagination="{{pagination}}" customEmpty emptyTitle="暂无记录">
<view class="empty-text" slot>暂无记录</view>
<pagination pagination="{{pagination}}" customEmpty>
<view class="empty">
<view class="e-content">
您在
<text class="high">“就诊记录”</text>
里上传的病历、处方、检查单、检验单、病理、超声等报告,将帮您智能分类、整理和保存在这里
</view>
<view class="btn" bind:tap="handleRecord">去记录</view>
</view>
</pagination>
</view>

14
src/pages/index/index.scss

@ -72,6 +72,7 @@ page { @@ -72,6 +72,7 @@ page {
align-items: center;
gap: 18rpx;
.aside {
position: relative;
padding-top: 20rpx;
width: 176rpx;
height: 188rpx;
@ -87,6 +88,17 @@ page { @@ -87,6 +88,17 @@ page {
color: rgba(14, 182, 109, 1);
font-weight: bold;
}
.pos {
font-size: 32rpx;
color: rgba(33, 29, 46, 0.36);
}
.icon {
position: absolute;
bottom: 24rpx;
right: 16rpx;
width: 36rpx;
height: 36rpx;
}
}
.wrap {
.title {
@ -525,7 +537,7 @@ page { @@ -525,7 +537,7 @@ page {
bottom: calc(env(safe-area-inset-bottom) + 180rpx);
width: 690rpx;
height: 152rpx;
box-shadow: 0rpx 4rpx 32rpx 0rpx rgba(0,0,0,0.08);
box-shadow: 0rpx 4rpx 32rpx 0rpx rgba(0, 0, 0, 0.08);
border-radius: 24rpx;
background: linear-gradient(358deg, #ffffff 0%, #e1f4ec 100%);
border: 2rpx solid #ffffff;

8
src/pages/index/index.ts

@ -129,11 +129,11 @@ Page({ @@ -129,11 +129,11 @@ Page({
updateNextVisitDays(userInfo: any) {
if (userInfo.NextVisitDate) {
const date = dayjs(userInfo.NextVisitDate)
const diffMs = Math.ceil(date.diff(dayjs()) / (24 * 60 * 60 * 1000))
let diffMs = Math.ceil(date.diff(dayjs()) / (24 * 60 * 60 * 1000))
const weekNames = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
let nextVisitDays = ''
if (diffMs < 0) {
nextVisitDays = '延期'
nextVisitDays = String(diffMs)
} else if (diffMs === 0) {
nextVisitDays = '0'
} else if (diffMs > 999) {
@ -367,10 +367,8 @@ Page({ @@ -367,10 +367,8 @@ Page({
handleNextVisit() {
app.mpBehavior({ PageName: 'BTN_PatientHomeNextVisit' })
const nextVisitDays = this.data.nextVisitDays
app.permissionVerification(3, 0, '').then(() => {
wx.navigateTo({
url: nextVisitDays == '---' ? '/gift/pages/record/index' : '/gift/pages/recordList/index',
})
url: nextVisitDays == '--' ? '/gift/pages/record/index' : '/gift/pages/recordList/index',
})
},
handleReg() {

17
src/pages/index/index.wxml

@ -21,8 +21,17 @@ @@ -21,8 +21,17 @@
class="aside"
style="background: url('{{imageUrl}}{{theme === 'DRUG' ? 'bg22' : 'bg15'}}.png?t={{Timestamp}}') no-repeat top center/100%"
>
<view class="a-num">{{nextVisitDays == 0 ? '今天' : nextVisitDays}}</view>
<block wx:if="{{nextVisitDays == 0}}">
<view class="a-num">今天</view>
</block>
<block wx:elif="{{nextVisitDays < 0 }}">
<view class="pos">待更新</view>
<image class="icon" src="{{imageUrl}}icon148.png?t={{Timestamp}}"></image>
</block>
<block wx:else>
<view class="a-num">{{nextVisitDays}}</view>
<text wx:if="{{nextVisitDays > 0}}">天</text>
</block>
</view>
<view class="wrap">
<view class="title">
@ -231,7 +240,11 @@ @@ -231,7 +240,11 @@
<view class="content">重要提醒不丢失~</view>
</view>
<view class="btn">去关注</view>
<image catch:tap="handlePublicClose" class="close" src="{{imageUrl}}{{theme === 'DRUG' ? 'icon146' : 'icon145'}}.png?t={{Timestamp}}"></image>
<image
catch:tap="handlePublicClose"
class="close"
src="{{imageUrl}}{{theme === 'DRUG' ? 'icon146' : 'icon145'}}.png?t={{Timestamp}}"
></image>
</view>
</view>

3
src/pages/login/index.ts

@ -25,8 +25,7 @@ Page({ @@ -25,8 +25,7 @@ Page({
this.setData({
page: options.page,
})
app.waitLogin({ isReg: false, loginPage: true }).then(() => {
})
app.waitLogin({ isReg: false, loginPage: true }).then(() => {})
},
onUnload() {
if (timer) {

4
src/pages/qaFormDetail/index.wxml

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
<wxs src="../../utils/tools.wxs" module="tools" />
<view class="page" id="{{theme === 'DRUG' && 'drug-page'}}">
<view class="page-container" wx:if="{{showPage}}">
<view class="page" id="{{theme === 'DRUG' && 'drug-page'}}" wx:if="{{showPage}}">
<view class="page-container">
<block wx:for="{{questions}}" wx:for-index="qIndex" wx:key="QuestionNo">
<view class="card" wx:if="{{item.visible}}">
<view class="c-title">

8
src/utils/tools.wxs

@ -1,11 +1,5 @@ @@ -1,11 +1,5 @@
function include(value, arr) {
var numValue = parseInt(value)
for (var i = 0; i < arr.length; i++) {
if (arr[i] === numValue) {
return true
}
}
return false
return arr.indexOf(parseInt(value)) > -1
}
function eq(a, b) {

Loading…
Cancel
Save