33 changed files with 2422 additions and 30 deletions
@ -0,0 +1,250 @@
@@ -0,0 +1,250 @@
|
||||
# PSVT协议模块接口文档 |
||||
|
||||
## 概述 |
||||
协议模块支持4种协议类型:隐私协议、用户协议、法律声明、健康敏感信息处理与AI服务授权告知书。初始4条数据,无创建接口,仅支持修改更新文案。 |
||||
|
||||
所有接口返回格式统一为: |
||||
```json |
||||
{ |
||||
"code": 0, |
||||
"message": "success", |
||||
"data": {} |
||||
} |
||||
``` |
||||
|
||||
协议类型常量值: |
||||
| 常量值 | 含义 | |
||||
|--------|------| |
||||
| 1 | 隐私协议 | |
||||
| 2 | 用户协议 | |
||||
| 3 | 法律声明 | |
||||
| 4 | 健康敏感信息处理与AI服务授权告知书 | |
||||
|
||||
--- |
||||
|
||||
## 一、小程序端接口 |
||||
|
||||
### 1. 按类型获取协议详情 |
||||
|
||||
- **路由**: `?r=psvt/agreement/get-by-type` |
||||
- **请求方式**: GET |
||||
- **是否需要登录**: 否(白名单路由) |
||||
|
||||
#### 请求参数 |
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 | |
||||
|--------|------|------|------| |
||||
| type | int | 是 | 协议类型:1-隐私协议,2-用户协议,3-法律声明,4-健康敏感信息处理与AI服务授权告知书 | |
||||
|
||||
#### 响应示例 |
||||
|
||||
```json |
||||
{ |
||||
"code": 0, |
||||
"message": "success", |
||||
"data": { |
||||
"id": 1, |
||||
"type": 1, |
||||
"title": "隐私协议", |
||||
"content": "隐私协议内容...", |
||||
"version": "V1.0", |
||||
"updateTime": "2026-07-17 10:00:00" |
||||
} |
||||
} |
||||
``` |
||||
|
||||
#### data字段说明 |
||||
|
||||
| 字段名 | 类型 | 说明 | |
||||
|--------|------|------| |
||||
| id | int | 协议ID | |
||||
| type | int | 协议类型 | |
||||
| title | string | 协议标题 | |
||||
| content | string | 协议内容(富文本) | |
||||
| version | string | 版本号 | |
||||
| updateTime | string | 最后更新时间 | |
||||
|
||||
#### 错误码 |
||||
|
||||
| code | 说明 | |
||||
|------|------| |
||||
| 1 | 协议类型参数无效 | |
||||
| 1 | 协议不存在 | |
||||
|
||||
--- |
||||
|
||||
### 2. 获取协议列表 |
||||
|
||||
- **路由**: `?r=psvt/agreement/get-list` |
||||
- **请求方式**: GET |
||||
- **是否需要登录**: 否(白名单路由) |
||||
|
||||
#### 请求参数 |
||||
|
||||
无 |
||||
|
||||
#### 响应示例 |
||||
|
||||
```json |
||||
{ |
||||
"code": 0, |
||||
"message": "success", |
||||
"data": [ |
||||
{ |
||||
"id": 1, |
||||
"type": 1, |
||||
"title": "隐私协议", |
||||
"content": "隐私协议内容...", |
||||
"version": "V1.0", |
||||
"updateTime": "2026-07-17 10:00:00" |
||||
}, |
||||
{ |
||||
"id": 2, |
||||
"type": 2, |
||||
"title": "用户协议", |
||||
"content": "用户协议内容...", |
||||
"version": "V1.0", |
||||
"updateTime": "2026-07-17 10:00:00" |
||||
}, |
||||
{ |
||||
"id": 3, |
||||
"type": 3, |
||||
"title": "法律声明", |
||||
"content": "法律声明内容...", |
||||
"version": "V1.0", |
||||
"updateTime": "2026-07-17 10:00:00" |
||||
}, |
||||
{ |
||||
"id": 4, |
||||
"type": 4, |
||||
"title": "健康敏感信息处理与AI服务授权告知书", |
||||
"content": "健康敏感信息处理与AI服务授权告知书内容...", |
||||
"version": "V1.0", |
||||
"updateTime": "2026-07-17 10:00:00" |
||||
} |
||||
] |
||||
} |
||||
``` |
||||
|
||||
#### data字段说明 |
||||
|
||||
data为数组类型,每个元素字段同"按类型获取协议详情"接口的data字段。 |
||||
|
||||
--- |
||||
|
||||
## 二、PC后台管理端接口 |
||||
|
||||
### 1. 获取协议列表 |
||||
|
||||
- **路由**: `?r=psvtw/agreement/get-list` |
||||
- **请求方式**: GET |
||||
- **是否需要登录**: 是 |
||||
|
||||
#### 请求参数 |
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 | |
||||
|--------|------|------|------| |
||||
| search | string | 否 | 搜索关键词(按标题模糊搜索) | |
||||
| page | int | 否 | 页码,默认1 | |
||||
| count | int | 否 | 每页条数,默认10 | |
||||
|
||||
#### 响应示例 |
||||
|
||||
```json |
||||
{ |
||||
"code": 0, |
||||
"message": "success", |
||||
"data": { |
||||
"total": 4, |
||||
"pages": 1, |
||||
"list": [ |
||||
{ |
||||
"id": 1, |
||||
"type": 1, |
||||
"title": "隐私协议", |
||||
"content": "隐私协议内容...", |
||||
"version": "V1.0", |
||||
"updateTime": "2026-07-17 10:00:00" |
||||
}, |
||||
{ |
||||
"id": 2, |
||||
"type": 2, |
||||
"title": "用户协议", |
||||
"content": "用户协议内容...", |
||||
"version": "V1.0", |
||||
"updateTime": "2026-07-17 10:00:00" |
||||
}, |
||||
{ |
||||
"id": 3, |
||||
"type": 3, |
||||
"title": "法律声明", |
||||
"content": "法律声明内容...", |
||||
"version": "V1.0", |
||||
"updateTime": "2026-07-17 10:00:00" |
||||
}, |
||||
{ |
||||
"id": 4, |
||||
"type": 4, |
||||
"title": "健康敏感信息处理与AI服务授权告知书", |
||||
"content": "健康敏感信息处理与AI服务授权告知书内容...", |
||||
"version": "V1.0", |
||||
"updateTime": "2026-07-17 10:00:00" |
||||
} |
||||
] |
||||
} |
||||
} |
||||
``` |
||||
|
||||
#### data字段说明 |
||||
|
||||
| 字段名 | 类型 | 说明 | |
||||
|--------|------|------| |
||||
| total | int | 总记录数 | |
||||
| pages | int | 总页数 | |
||||
| list | array | 协议列表,每个元素字段同小程序端 | |
||||
|
||||
--- |
||||
|
||||
### 2. 更新协议文案 |
||||
|
||||
- **路由**: `?r=psvtw/agreement/update` |
||||
- **请求方式**: POST |
||||
- **是否需要登录**: 是 |
||||
- **事务**: 是 |
||||
|
||||
#### 请求参数 |
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 | |
||||
|--------|------|------|------| |
||||
| id | int | 是 | 协议ID | |
||||
| title | string | 否 | 协议标题 | |
||||
| content | string | 否 | 协议内容(富文本) | |
||||
|
||||
> 注:title和content至少传一个,传入的字段才会更新 |
||||
|
||||
#### 响应示例 |
||||
|
||||
```json |
||||
{ |
||||
"code": 0, |
||||
"message": "更新成功", |
||||
"data": { |
||||
"id": 1 |
||||
} |
||||
} |
||||
``` |
||||
|
||||
#### data字段说明 |
||||
|
||||
| 字段名 | 类型 | 说明 | |
||||
|--------|------|------| |
||||
| id | int | 更新的协议ID | |
||||
|
||||
#### 错误码 |
||||
|
||||
| code | 说明 | |
||||
|------|------| |
||||
| 1 | 用户未登录 | |
||||
| 1 | 协议ID不能为空 | |
||||
| 1 | 协议不存在 | |
||||
| 1 | 更新协议失败 | |
||||
@ -0,0 +1,848 @@
@@ -0,0 +1,848 @@
|
||||
# PSVT患者模块接口文档 |
||||
|
||||
## 一、小程序端接口 |
||||
|
||||
### 1.1 初始化登录 `GET ?r=psvt/user/init-login` |
||||
|
||||
**说明**: 小程序端通过wx.login获取code,发送到服务端完成登录初始化,返回登录态及用户状态信息。 |
||||
|
||||
**请求参数**: |
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 | |
||||
|---|---|---|---| |
||||
| code | string | 是 | wx.login获取的登录凭证 | |
||||
| channelId | int | 否 | 扫码渠道ID | |
||||
|
||||
**响应示例**: |
||||
```json |
||||
{ |
||||
"code": 0, |
||||
"data": { |
||||
"loginState": "xxx", |
||||
"isLogin": true, |
||||
"isReg": true, |
||||
"userId": "xxx", |
||||
"openId": "xxx", |
||||
} |
||||
} |
||||
``` |
||||
|
||||
**响应字段说明**: |
||||
|
||||
| 字段名 | 类型 | 说明 | |
||||
|---|---|---| |
||||
| loginState | string | 登录态凭证,后续接口需携带 | |
||||
| isLogin | bool | 是否已登录 | |
||||
| userId | string | 用户ID | |
||||
| openId | string | 小程序OpenId | |
||||
| isPhoneRegistered | bool | 是否已手机号注册 | |
||||
| isInfoSubmitted | bool | 是否已提交信息 | |
||||
|
||||
**业务逻辑**: |
||||
1. 调用微信接口获取openid和session_key |
||||
2. 创建/更新PSVT用户记录(t_psvt_user_info) |
||||
3. 若有channelId参数,更新ScanChannelId(最终渠道,每次扫码都更新) |
||||
4. 首次打开时记录FirstOpenTime |
||||
5. 返回用户状态信息(isPhoneRegistered、isInfoSubmitted) |
||||
|
||||
--- |
||||
|
||||
### 1.2 手机号授权注册 `POST ?r=psvt/patient/phone-register` |
||||
|
||||
**说明**: 解密微信加密数据获取手机号,完成手机号注册。事务操作。 |
||||
|
||||
**请求参数**: |
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 | |
||||
|---|---|---|---| |
||||
| encryptedData | string | 是 | 微信加密手机号数据 | |
||||
| iv | string | 是 | 微信加密iv | |
||||
| channelId | int | 否 | 手机号注册时的渠道ID | |
||||
|
||||
**响应示例**: |
||||
```json |
||||
{ |
||||
"code": 0, |
||||
"message": "success", |
||||
"data": { |
||||
"telephone": "138xxxx1234", |
||||
"isPhoneRegistered": true |
||||
} |
||||
} |
||||
``` |
||||
|
||||
**响应字段说明**: |
||||
|
||||
| 字段名 | 类型 | 说明 | |
||||
|---|---|---| |
||||
| telephone | string | 注册的手机号 | |
||||
| isPhoneRegistered | bool | 是否已手机号注册 | |
||||
|
||||
**业务逻辑**: |
||||
1. 解密微信加密数据获取手机号 |
||||
2. 更新t_psvt_user_info的Telephone、IsPhoneRegistered=1、PhoneRegisterTime |
||||
3. 若有channelId,记录TelChannelId(首次手机号注册渠道,仅记录首次,不更新) |
||||
4. 若有channelId,记录邀约记录(InviteType=2手机号注册)并更新统计表 |
||||
5. 更新IsFirstOpenPhoneRegistered(首次打开时间和手机号注册时间是同一天时为1) |
||||
6. 更新IsPhoneRegisteredNotLost(手机号注册时间和提交信息时间是同一天时为1) |
||||
7. 使用事务 |
||||
|
||||
--- |
||||
|
||||
### 1.3 患者信息提交注册 `POST ?r=psvt/patient/register` |
||||
|
||||
**说明**: 提交年龄段、性别、确诊状态、手术状态等信息完成注册。事务操作。 |
||||
|
||||
**请求参数**: |
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 | |
||||
|---|---|---|---| |
||||
| ageRange | int | 是 | 年龄段:1-18~28岁,2-29~40岁,3-41~50岁,4-50岁以上 | |
||||
| gender | int | 是 | 性别:1-男,2-女 | |
||||
| provinceId | int | 否 | 省份ID | |
||||
| provinceName | string | 否 | 省份名称 | |
||||
| cityId | int | 否 | 市ID | |
||||
| cityName | string | 否 | 市名称 | |
||||
| diagnosisStatus | int | 是 | 确诊状态:1-疑似PSVT正在了解中,2-已确诊PSVT,3-心悸/心跳过快 尚未就诊,4-亲友相关 想了解更多 | |
||||
| diagnosisTime | string | 否 | 确诊时间(YYYY-MM格式) | |
||||
| surgeryStatus | int | 是 | 手术状态:1-已接收射频消融/相关手术,2-尚未接收手术,3-正在评估 | |
||||
| channelId | int | 否 | 提交信息渠道ID | |
||||
|
||||
**响应示例**: |
||||
```json |
||||
{ |
||||
"code": 0, |
||||
"message": "success", |
||||
"data": { |
||||
"userId": "xxx", |
||||
"nickName": "abcd12345678", |
||||
"avatar": "https://psvt.example.com/avatar/3.png", |
||||
"isRegistered": true |
||||
} |
||||
} |
||||
``` |
||||
|
||||
**响应字段说明**: |
||||
|
||||
| 字段名 | 类型 | 说明 | |
||||
|---|---|---| |
||||
| userId | string | 用户ID | |
||||
| nickName | string | 随机生成的昵称(4字母+8数字) | |
||||
| avatar | string | 随机分配的头像URL | |
||||
| isRegistered | bool | 是否已注册 | |
||||
|
||||
**业务逻辑**: |
||||
1. 生成随机昵称(4随机字母+8随机数字) |
||||
2. 随机分配头像(10张图片池中随机选1) |
||||
3. 创建t_psvt_patient_info记录(患者属性) |
||||
4. 更新t_psvt_user_info的PatientId、IsInfoSubmitted=1、InfoSubmitTime、SubmitChannelId |
||||
5. 更新IsFirstOpenInfoSubmitted(首次打开时间和信息提交时间是同一天时为1) |
||||
6. 更新IsPhoneRegisteredNotLost(手机号注册时间和信息提交时间是同一天时为1) |
||||
7. 若有channelId,记录邀约记录(InviteType=3信息提交)并更新统计表 |
||||
8. 使用事务 |
||||
|
||||
--- |
||||
|
||||
### 1.4 获取我的信息 `GET ?r=psvt/patient/my-info` |
||||
|
||||
**说明**: 返回当前登录用户的完整信息(用户信息+患者属性),小驼峰格式。 |
||||
|
||||
**请求参数**: 无(通过loginState获取userId) |
||||
|
||||
**响应示例**: |
||||
```json |
||||
{ |
||||
"code": 0, |
||||
"message": "success", |
||||
"data": { |
||||
"userId": "xxx", |
||||
"openId": "xxx", |
||||
"telephone": "138xxxx1234", |
||||
"isPhoneRegistered": true, |
||||
"isInfoSubmitted": true, |
||||
"isHeartRateTips": true, |
||||
"firstOpenTime": "2023-01-01 10:00:00", |
||||
"phoneRegisterTime": "2023-01-01 10:05:00", |
||||
"infoSubmitTime": "2023-01-01 10:10:00", |
||||
"nickName": "abcd12345678", |
||||
"avatar": "https://psvt.example.com/avatar/3.png", |
||||
"ageRange": 1, |
||||
"gender": 1, |
||||
"provinceName": "北京", |
||||
"cityName": "北京", |
||||
"diagnosisStatus": 2, |
||||
"diagnosisTime": "2023-06", |
||||
"surgeryStatus": 1 |
||||
} |
||||
} |
||||
``` |
||||
|
||||
**响应字段说明**: |
||||
|
||||
| 字段名 | 类型 | 说明 | |
||||
|---|---|---| |
||||
| userId | string | 用户ID | |
||||
| openId | string | 小程序OpenId | |
||||
| telephone | string | 手机号 | |
||||
| isPhoneRegistered | bool | 是否已手机号注册 | |
||||
| isInfoSubmitted | bool | 是否已提交信息 | |
||||
| isHeartRateTips | bool | 是否开启心率提醒 | |
||||
| firstOpenTime | string | 首次打开时间 | |
||||
| phoneRegisterTime | string | 手机号注册时间 | |
||||
| infoSubmitTime | string | 信息提交时间 | |
||||
| nickName | string | 昵称(未提交信息时为null) | |
||||
| avatar | string | 头像URL(未提交信息时为null) | |
||||
| ageRange | int | 年龄段(未提交信息时为null) | |
||||
| gender | int | 性别(未提交信息时为null) | |
||||
| provinceName | string | 省份名称(未提交信息时为null) | |
||||
| cityName | string | 市名称(未提交信息时为null) | |
||||
| diagnosisStatus | int | 确诊状态(未提交信息时为null) | |
||||
| diagnosisTime | string | 确诊时间(未提交信息时为null) | |
||||
| surgeryStatus | int | 手术状态(未提交信息时为null) | |
||||
|
||||
--- |
||||
|
||||
### 1.5 更新我的信息 `POST ?r=psvt/patient/update-my-info` |
||||
|
||||
**说明**: 更新当前登录用户的个人信息。若已确诊PSVT(DiagnosisStatus=2),确诊状态和手术状态不可修改。事务操作。 |
||||
|
||||
**请求参数**: |
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 | |
||||
|---|---|---|---| |
||||
| avatar | string | 否 | 头像URL | |
||||
| nickName | string | 否 | 昵称 | |
||||
| telephone | string | 否 | 手机号 | |
||||
| ageRange | int | 否 | 年龄段 | |
||||
| gender | int | 否 | 性别 | |
||||
| provinceId | int | 否 | 省份ID | |
||||
| provinceName | string | 否 | 省份名称 | |
||||
| cityId | int | 否 | 市ID | |
||||
| cityName | string | 否 | 市名称 | |
||||
| diagnosisStatus | int | 否 | 确诊状态(已确诊PSVT后不可修改) | |
||||
| diagnosisTime | string | 否 | 确诊时间 | |
||||
| surgeryStatus | int | 否 | 手术状态(已确诊PSVT后不可修改) | |
||||
|
||||
**响应示例**: |
||||
```json |
||||
{ |
||||
"code": 0, |
||||
"message": "success", |
||||
"data": { |
||||
"userId": "xxx", |
||||
"openId": "xxx", |
||||
"telephone": "138xxxx1234", |
||||
"isPhoneRegistered": true, |
||||
"isInfoSubmitted": true, |
||||
"isHeartRateTips": true, |
||||
"firstOpenTime": "2023-01-01 10:00:00", |
||||
"phoneRegisterTime": "2023-01-01 10:05:00", |
||||
"infoSubmitTime": "2023-01-01 10:10:00", |
||||
"nickName": "newNickname", |
||||
"avatar": "https://...", |
||||
"ageRange": 2, |
||||
"gender": 1, |
||||
"provinceName": "上海", |
||||
"cityName": "上海", |
||||
"diagnosisStatus": 2, |
||||
"diagnosisTime": "2023-06", |
||||
"surgeryStatus": 1 |
||||
} |
||||
} |
||||
``` |
||||
|
||||
**响应字段说明**: 同1.4获取我的信息 |
||||
|
||||
**业务逻辑**: |
||||
1. 若已确诊PSVT(DiagnosisStatus=2),则diagnosisStatus和surgeryStatus不可修改 |
||||
2. 更新t_psvt_patient_info患者属性 |
||||
3. 若更新了手机号,同步更新t_psvt_user_info的Telephone |
||||
4. 使用事务 |
||||
|
||||
--- |
||||
|
||||
### 1.6 渠道码扫码记录 `POST ?r=psvt/?r=channel/scan-channel` |
||||
|
||||
**说明**: 记录扫码渠道信息,更新用户的ScanChannelId。事务操作。 |
||||
|
||||
**请求参数**: |
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 | |
||||
|---|---|---|---| |
||||
| channelId | int | 是 | 渠道码ID | |
||||
|
||||
**响应示例**: |
||||
```json |
||||
{ |
||||
"code": 0, |
||||
"message": "success", |
||||
"data": { |
||||
"recorded": true |
||||
} |
||||
} |
||||
``` |
||||
|
||||
**响应字段说明**: |
||||
|
||||
| 字段名 | 类型 | 说明 | |
||||
|---|---|---| |
||||
| recorded | bool | 是否记录成功 | |
||||
|
||||
**业务逻辑**: |
||||
1. 验证渠道码存在 |
||||
2. 更新用户ScanChannelId(最终渠道,每次扫码都更新) |
||||
3. 记录邀约记录(InviteType=1用户打开) |
||||
4. 更新统计表 |
||||
5. 使用事务 |
||||
|
||||
--- |
||||
|
||||
### 1.7 获取基础数据列表 `GET ?r=psvt/patient/base-data` |
||||
|
||||
**说明**: 返回性别、年龄段、确诊状态、手术状态等枚举数据,供前端渲染下拉选项。 |
||||
|
||||
**请求参数**: 无 |
||||
|
||||
**响应示例**: |
||||
```json |
||||
{ |
||||
"code": 0, |
||||
"message": "success", |
||||
"data": { |
||||
"genderList": [{"1": "男"}, {"2": "女"}], |
||||
"ageRangeList": [{"1": "18~28岁"}, {"2": "29~40岁"}, {"3": "41~50岁"}, {"4": "50岁以上"}], |
||||
"diagnosisStatusList": [{"1": "疑似PSVT正在了解中"}, {"2": "已确诊PSVT"}, {"3": "心悸/心跳过快 尚未就诊"}, {"4": "亲友相关 想了解更多"}], |
||||
"surgeryStatusList": [{"1": "已接收射频消融/相关手术"}, {"2": "尚未接收手术"}, {"3": "正在评估"}] |
||||
} |
||||
} |
||||
``` |
||||
|
||||
**响应字段说明**: |
||||
|
||||
| 字段名 | 类型 | 说明 | |
||||
|---|---|---| |
||||
| genderList | array | 性别列表,每项为 {value: "label"} | |
||||
| ageRangeList | array | 年龄段列表,每项为 {value: "label"} | |
||||
| diagnosisStatusList | array | 确诊状态列表,每项为 {value: "label"} | |
||||
| surgeryStatusList | array | 手术状态列表,每项为 {value: "label"} | |
||||
|
||||
**genderList值说明**: |
||||
|
||||
| 值 | 说明 | |
||||
|---|---| |
||||
| 1 | 男 | |
||||
| 2 | 女 | |
||||
|
||||
**ageRangeList值说明**: |
||||
|
||||
| 值 | 说明 | |
||||
|---|---| |
||||
| 1 | 18~28岁 | |
||||
| 2 | 29~40岁 | |
||||
| 3 | 41~50岁 | |
||||
| 4 | 50岁以上 | |
||||
|
||||
**diagnosisStatusList值说明**: |
||||
|
||||
| 值 | 说明 | |
||||
|---|---| |
||||
| 1 | 疑似PSVT正在了解中 | |
||||
| 2 | 已确诊PSVT | |
||||
| 3 | 心悸/心跳过快 尚未就诊 | |
||||
| 4 | 亲友相关 想了解更多 | |
||||
|
||||
**surgeryStatusList值说明**: |
||||
|
||||
| 值 | 说明 | |
||||
|---|---| |
||||
| 1 | 已接收射频消融/相关手术 | |
||||
| 2 | 尚未接收手术 | |
||||
| 3 | 正在评估 | |
||||
|
||||
--- |
||||
|
||||
## 二、后台管理端接口 |
||||
|
||||
### 2.1 患者列表 `GET ?r=patient/list` |
||||
|
||||
**说明**: 获取PSVT患者列表,含分页、搜索、渠道筛选及汇总统计。 |
||||
|
||||
**请求参数**: |
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 | |
||||
|---|---|---|---| |
||||
| search | string | 否 | 搜索关键字(手机号/UserId/省市) | |
||||
| channelId | int | 否 | 渠道ID筛选 | |
||||
| page | int | 否 | 页码,默认1 | |
||||
| count | int | 否 | 每页数量,默认10 | |
||||
|
||||
**响应示例**: |
||||
```json |
||||
{ |
||||
"code": 0, |
||||
"message": "success", |
||||
"data": { |
||||
"page": 1, |
||||
"pages": 10, |
||||
"count": 100, |
||||
"summary": { |
||||
"totalOpenCount": 1920, |
||||
"phoneRegisteredCount": 1900, |
||||
"phoneRegisteredRate": "19.9%", |
||||
"infoSubmittedCount": 1082, |
||||
"infoSubmittedRate": "56.3%", |
||||
"diagnosedPsvtCount": 980, |
||||
"diagnosedPsvtRate": "90.2%", |
||||
"firstOpenPhoneRegisteredCount": 800, |
||||
"firstOpenInfoSubmittedCount": 800, |
||||
"phoneRegisteredNotLostCount": 700 |
||||
}, |
||||
"list": [ |
||||
{ |
||||
"userId": "xxx", |
||||
"telephone": "138xxxx1234", |
||||
"nickName": "abcd12345678", |
||||
"avatar": "https://...", |
||||
"ageRange": 1, |
||||
"gender": 1, |
||||
"provinceName": "北京", |
||||
"cityName": "北京", |
||||
"diagnosisStatus": 2, |
||||
"diagnosisTime": "2023-06", |
||||
"surgeryStatus": 1, |
||||
"firstOpenTime": "2023-01-01 10:00:00", |
||||
"phoneRegisterTime": "2023-01-01 10:05:00", |
||||
"infoSubmitTime": "2023-01-01 10:10:00", |
||||
"isFirstOpenPhoneRegistered": true, |
||||
"isFirstOpenInfoSubmitted": true, |
||||
"isPhoneRegisteredNotLost": true, |
||||
"scanChannelId": 1, |
||||
"scanChannelName": "渠道A", |
||||
"telChannelId": 2, |
||||
"telChannelName": "渠道B", |
||||
"submitChannelId": 3, |
||||
"submitChannelName": "渠道C" |
||||
} |
||||
] |
||||
} |
||||
} |
||||
``` |
||||
|
||||
**响应字段说明(data层级)**: |
||||
|
||||
| 字段名 | 类型 | 说明 | |
||||
|---|---|---| |
||||
| page | int | 当前页码 | |
||||
| pages | int | 总页数 | |
||||
| count | int | 总记录数 | |
||||
| summary | object | 汇合统计数据 | |
||||
| list | array | 患者列表 | |
||||
|
||||
**summary字段说明**: |
||||
|
||||
| 字段名 | 类型 | 说明 | |
||||
|---|---|---| |
||||
| totalOpenCount | int | 总打开数 | |
||||
| phoneRegisteredCount | int | 手机号注册数 | |
||||
| phoneRegisteredRate | string | 手机号注册率(百分比) | |
||||
| infoSubmittedCount | int | 信息提交数 | |
||||
| infoSubmittedRate | string | 信息提交率(百分比) | |
||||
| diagnosedPsvtCount | int | 确诊PSVT数 | |
||||
| diagnosedPsvtRate | string | 确诊PSVT率(百分比) | |
||||
| firstOpenPhoneRegisteredCount | int | 首次打开完成手机号注册数 | |
||||
| firstOpenInfoSubmittedCount | int | 首次打开完成信息填写数 | |
||||
| phoneRegisteredNotLostCount | int | 手机号注册后未流失数 | |
||||
|
||||
**list行字段说明**: |
||||
|
||||
| 字段名 | 类型 | 说明 | |
||||
|---|---|---| |
||||
| userId | string | 用户ID | |
||||
| telephone | string | 手机号 | |
||||
| nickName | string | 昵称 | |
||||
| avatar | string | 头像URL | |
||||
| ageRange | int | 年龄段 | |
||||
| gender | int | 性别 | |
||||
| provinceName | string | 省份名称 | |
||||
| cityName | string | 市名称 | |
||||
| diagnosisStatus | int | 确诊状态 | |
||||
| diagnosisTime | string | 确诊时间 | |
||||
| surgeryStatus | int | 手术状态 | |
||||
| firstOpenTime | string | 首次打开时间 | |
||||
| phoneRegisterTime | string | 手机号注册时间 | |
||||
| infoSubmitTime | string | 信息提交时间 | |
||||
| isFirstOpenPhoneRegistered | bool | 首次打开完成手机号注册 | |
||||
| isFirstOpenInfoSubmitted | bool | 首次打开完成信息填写 | |
||||
| isPhoneRegisteredNotLost | bool | 手机号注册后未流失 | |
||||
| scanChannelId | int | 扫码渠道ID | |
||||
| scanChannelName | string | 扫码渠道名称 | |
||||
| telChannelId | int | 手机号注册渠道ID | |
||||
| telChannelName | string | 手机号注册渠道名称 | |
||||
| submitChannelId | int | 提交信息渠道ID | |
||||
| submitChannelName | string | 提交信息渠道名称 | |
||||
|
||||
--- |
||||
|
||||
### 2.2 患者详情 `GET ?r=patient/detail` |
||||
|
||||
**说明**: 根据用户信息表ID获取完整的用户+患者详情数据。 |
||||
|
||||
**请求参数**: |
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 | |
||||
|---|---|---|---| |
||||
| id | int | 是 | 用户信息表ID | |
||||
|
||||
**响应示例**: |
||||
```json |
||||
{ |
||||
"code": 0, |
||||
"message": "success", |
||||
"data": { |
||||
"userId": "xxx", |
||||
"openId": "xxx", |
||||
"telephone": "138xxxx1234", |
||||
"isPhoneRegistered": true, |
||||
"isInfoSubmitted": true, |
||||
"isHeartRateTips": true, |
||||
"firstOpenTime": "2023-01-01 10:00:00", |
||||
"phoneRegisterTime": "2023-01-01 10:05:00", |
||||
"infoSubmitTime": "2023-01-01 10:10:00", |
||||
"nickName": "abcd12345678", |
||||
"avatar": "https://...", |
||||
"ageRange": 1, |
||||
"gender": 1, |
||||
"provinceName": "北京", |
||||
"cityName": "北京", |
||||
"diagnosisStatus": 2, |
||||
"diagnosisTime": "2023-06", |
||||
"surgeryStatus": 1, |
||||
"scanChannelId": 1, |
||||
"scanChannelName": "渠道A", |
||||
"telChannelId": 2, |
||||
"telChannelName": "渠道B", |
||||
"submitChannelId": 3, |
||||
"submitChannelName": "渠道C" |
||||
} |
||||
} |
||||
``` |
||||
|
||||
**响应字段说明**: 同1.4获取我的信息,额外包含渠道信息字段(scanChannelId/scanChannelName、telChannelId/telChannelName、submitChannelId/submitChannelName) |
||||
|
||||
--- |
||||
|
||||
### 2.3 渠道码列表 `GET ?r=?r=channel/list` |
||||
|
||||
**说明**: 获取所有有效渠道码列表。 |
||||
|
||||
**请求参数**: 无 |
||||
|
||||
**响应示例**: |
||||
```json |
||||
{ |
||||
"code": 0, |
||||
"message": "success", |
||||
"data": [ |
||||
{ |
||||
"channelId": 1, |
||||
"channelName": "渠道A", |
||||
"channelDesc": "渠道A说明", |
||||
"miniCodeUrl": "https://xxx/minicode_1.png" |
||||
} |
||||
] |
||||
} |
||||
``` |
||||
|
||||
**响应字段说明(每行)**: |
||||
|
||||
| 字段名 | 类型 | 说明 | |
||||
|---|---|---| |
||||
| channelId | int | 渠道ID | |
||||
| channelName | string | 渠道名称 | |
||||
| channelDesc | string | 渠道码说明 | |
||||
| miniCodeUrl | string | 小程序码图片URL | |
||||
|
||||
--- |
||||
|
||||
### 2.4 创建渠道码 `POST ?r=channel/create` |
||||
|
||||
**说明**: 创建新的渠道码。事务操作。 |
||||
|
||||
**请求参数**: |
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 | |
||||
|---|---|---|---| |
||||
| channelName | string | 是 | 渠道名称 | |
||||
| channelDesc | string | 否 | 渠道码说明 | |
||||
|
||||
**响应示例**: |
||||
```json |
||||
{ |
||||
"code": 0, |
||||
"message": "success", |
||||
"data": { |
||||
"channelId": 1, |
||||
"channelName": "渠道A" |
||||
} |
||||
} |
||||
``` |
||||
|
||||
**响应字段说明**: |
||||
|
||||
| 字段名 | 类型 | 说明 | |
||||
|---|---|---| |
||||
| channelId | int | 新创建的渠道ID | |
||||
| channelName | string | 渠道名称 | |
||||
|
||||
--- |
||||
|
||||
### 2.5 更新渠道码 `POST ?r=channel/update` |
||||
|
||||
**说明**: 更新渠道码信息。事务操作。 |
||||
|
||||
**请求参数**: |
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 | |
||||
|---|---|---|---| |
||||
| channelId | int | 是 | 渠道ID | |
||||
| channelName | string | 否 | 渠道名称 | |
||||
| channelDesc | string | 否 | 渠道码说明 | |
||||
|
||||
**响应示例**: |
||||
```json |
||||
{ |
||||
"code": 0, |
||||
"message": "success", |
||||
"data": { |
||||
"channelId": 1, |
||||
"channelName": "渠道A(已更新)" |
||||
} |
||||
} |
||||
``` |
||||
|
||||
**响应字段说明**: |
||||
|
||||
| 字段名 | 类型 | 说明 | |
||||
|---|---|---| |
||||
| channelId | int | 渠道ID | |
||||
| channelName | string | 更新后的渠道名称 | |
||||
|
||||
--- |
||||
|
||||
### 2.6 获取小程序渠道码 `GET ?r=channel/get-minicode` |
||||
|
||||
**说明**: 根据渠道ID获取或生成小程序码图片URL。 |
||||
|
||||
**请求参数**: |
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 | |
||||
|---|---|---|---| |
||||
| channelId | int | 是 | 渠道ID | |
||||
|
||||
**响应示例**: |
||||
```json |
||||
{ |
||||
"code": 0, |
||||
"message": "success", |
||||
"data": { |
||||
"channelId": 1, |
||||
"channelName": "渠道A", |
||||
"miniCodeUrl": "https://xxx/minicode_1.png" |
||||
} |
||||
} |
||||
``` |
||||
|
||||
**响应字段说明**: |
||||
|
||||
| 字段名 | 类型 | 说明 | |
||||
|---|---|---| |
||||
| channelId | int | 渠道ID | |
||||
| channelName | string | 渠道名称 | |
||||
| miniCodeUrl | string | 小程序码图片URL | |
||||
|
||||
**业务逻辑**: |
||||
1. 若渠道已有小程序码URL(MiniCodeUrl),直接返回 |
||||
2. 若没有,调用微信接口生成小程序码(scene参数包含渠道ID) |
||||
3. 保存生成的MiniCodeUrl到渠道记录 |
||||
|
||||
--- |
||||
|
||||
### 2.7 渠道码统计 `GET ?r=channel/stat` |
||||
|
||||
**说明**: 根据日期范围和渠道ID获取渠道统计数据,从统计表获取。 |
||||
|
||||
**请求参数**: |
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 | |
||||
|---|---|---|---| |
||||
| inviteDateBegin | string | 否 | 邀约日期开始(YYYY-MM-DD) | |
||||
| inviteDateEnd | string | 否 | 邀约日期结束(YYYY-MM-DD) | |
||||
| channelIds | string | 否 | 渠道ID筛选,逗号分隔(如"1,2,3") | |
||||
|
||||
**响应示例**: |
||||
```json |
||||
{ |
||||
"code": 0, |
||||
"message": "success", |
||||
"data": [ |
||||
{ |
||||
"statDate": "2023-01-01", |
||||
"channelId": 1, |
||||
"channelName": "渠道A", |
||||
"openPatientCount": 100, |
||||
"phoneRegisteredCount": 80, |
||||
"infoSubmittedCount": 50, |
||||
"diagnosedPsvtCount": 30 |
||||
} |
||||
] |
||||
} |
||||
``` |
||||
|
||||
**响应字段说明(每行)**: |
||||
|
||||
| 字段名 | 类型 | 说明 | |
||||
|---|---|---| |
||||
| statDate | string | 统计日期 | |
||||
| channelId | int | 渠道ID | |
||||
| channelName | string | 渠道名称 | |
||||
| openPatientCount | int | 邀约打开患者数 | |
||||
| phoneRegisteredCount | int | 邀约注册手机号患者数 | |
||||
| infoSubmittedCount | int | 邀约提交信息患者数 | |
||||
| diagnosedPsvtCount | int | 确诊PSVT患者数 | |
||||
|
||||
--- |
||||
|
||||
### 2.8 渠道码原始数据列表 `GET ?r=channel/raw-list` |
||||
|
||||
**说明**: 获取渠道邀约的原始记录列表,支持分页。通过JOIN t_psvt_user_info和t_psvt_patient_info获取用户属性和患者属性,不冗余存储。 |
||||
|
||||
**请求参数**: |
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 | |
||||
|---|---|---|---| |
||||
| inviteDateBegin | string | 否 | 邀约日期开始(YYYY-MM-DD) | |
||||
| inviteDateEnd | string | 否 | 邀约日期结束(YYYY-MM-DD) | |
||||
| channelId | int | 否 | 渠道ID筛选 | |
||||
| inviteType | int | 否 | 邀约类型筛选:1-用户打开,2-手机号注册,3-信息提交 | |
||||
| page | int | 否 | 页码,默认1 | |
||||
| count | int | 否 | 每页数量,默认10 | |
||||
|
||||
**响应示例**: |
||||
```json |
||||
{ |
||||
"code": 0, |
||||
"message": "success", |
||||
"data": { |
||||
"page": 1, |
||||
"pages": 10, |
||||
"count": 100, |
||||
"list": [ |
||||
{ |
||||
"id": 1, |
||||
"inviteTime": "2023-01-01 10:00:00", |
||||
"channelId": 1, |
||||
"channelName": "渠道A", |
||||
"inviteType": 1, |
||||
"userId": "xxx", |
||||
"patientId": 5, |
||||
"nickName": "abcd12345678", |
||||
"gender": 1, |
||||
"ageRange": 1, |
||||
"provinceName": "北京", |
||||
"cityName": "北京", |
||||
"diagnosisStatus": 2, |
||||
"diagnosisTime": "2023-06", |
||||
"surgeryStatus": 1, |
||||
"telephone": "138xxxx1234", |
||||
"firstOpenTime": "2023-01-01 10:00:00", |
||||
"phoneRegisterTime": "2023-01-01 10:05:00", |
||||
"infoSubmitTime": "2023-01-01 10:10:00", |
||||
"isFirstOpenPhoneRegistered": true, |
||||
"isFirstOpenInfoSubmitted": true, |
||||
"isPhoneRegisteredNotLost": true, |
||||
"scanChannelId": 1, |
||||
"scanChannelName": "渠道A", |
||||
"telChannelId": 2, |
||||
"telChannelName": "渠道B", |
||||
"submitChannelId": 3, |
||||
"submitChannelName": "渠道C" |
||||
} |
||||
] |
||||
} |
||||
} |
||||
``` |
||||
|
||||
**响应字段说明(data层级)**: |
||||
|
||||
| 字段名 | 类型 | 说明 | |
||||
|---|---|---| |
||||
| page | int | 当前页码 | |
||||
| pages | int | 总页数 | |
||||
| count | int | 总记录数 | |
||||
| list | array | 原始数据列表 | |
||||
|
||||
**list行字段说明**: |
||||
|
||||
| 字段名 | 类型 | 说明 | |
||||
|---|---|---| |
||||
| id | int | 记录ID | |
||||
| inviteTime | string | 邀约时间 | |
||||
| channelId | int | 渠道ID | |
||||
| channelName | string | 渠道名称 | |
||||
| inviteType | int | 邀约类型 | |
||||
| userId | string | 用户ID | |
||||
| patientId | int | 患者ID | |
||||
| nickName | string | 昵称 | |
||||
| gender | int | 性别 | |
||||
| ageRange | int | 年龄段 | |
||||
| provinceName | string | 省份名称 | |
||||
| cityName | string | 市名称 | |
||||
| diagnosisStatus | int | 确诊状态 | |
||||
| diagnosisTime | string | 确诊时间 | |
||||
| surgeryStatus | int | 手术状态 | |
||||
| telephone | string | 手机号 | |
||||
| firstOpenTime | string | 首次打开时间 | |
||||
| phoneRegisterTime | string | 手机号注册时间 | |
||||
| infoSubmitTime | string | 信息提交时间 | |
||||
| isFirstOpenPhoneRegistered | bool | 首次打开完成手机号注册 | |
||||
| isFirstOpenInfoSubmitted | bool | 首次打开完成信息填写 | |
||||
| isPhoneRegisteredNotLost | bool | 手机号注册后未流失 | |
||||
| scanChannelId | int | 扫码渠道ID | |
||||
| scanChannelName | string | 扫码渠道名称 | |
||||
| telChannelId | int | 手机号注册渠道ID | |
||||
| telChannelName | string | 手机号注册渠道名称 | |
||||
| submitChannelId | int | 提交信息渠道ID | |
||||
| submitChannelName | string | 提交信息渠道名称 | |
||||
|
||||
--- |
||||
|
||||
### 2.9 获取基础数据列表 `GET ?r=patient/base-data` |
||||
|
||||
**说明**: 返回性别、年龄段、确诊状态、手术状态等枚举数据,供后台管理端渲染下拉选项。 |
||||
|
||||
**请求参数**: 无 |
||||
|
||||
**响应示例**: |
||||
```json |
||||
{ |
||||
"code": 0, |
||||
"message": "success", |
||||
"data": { |
||||
"genderList": [{"1": "男"}, {"2": "女"}], |
||||
"ageRangeList": [{"1": "18~28岁"}, {"2": "29~40岁"}, {"3": "41~50岁"}, {"4": "50岁以上"}], |
||||
"diagnosisStatusList": [{"1": "疑似PSVT正在了解中"}, {"2": "已确诊PSVT"}, {"3": "心悸/心跳过快 尚未就诊"}, {"4": "亲友相关 想了解更多"}], |
||||
"surgeryStatusList": [{"1": "已接收射频消融/相关手术"}, {"2": "尚未接收手术"}, {"3": "正在评估"}] |
||||
} |
||||
} |
||||
``` |
||||
|
||||
**响应字段说明**: |
||||
|
||||
| 字段名 | 类型 | 说明 | |
||||
|---|---|---| |
||||
| genderList | array | 性别列表,每项为 {value: "label"} | |
||||
| ageRangeList | array | 年龄段列表,每项为 {value: "label"} | |
||||
| diagnosisStatusList | array | 确诊状态列表,每项为 {value: "label"} | |
||||
| surgeryStatusList | array | 手术状态列表,每项为 {value: "label"} | |
||||
|
||||
--- |
||||
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
{ |
||||
"navigationStyle": "custom", |
||||
"navigationBarTitleText": "隐私协议", |
||||
"usingComponents": { |
||||
"popup": "/components/popup/index", |
||||
"navbar": "/components/navbar/index", |
||||
"uploadFile": "/components/uploadFile/index", |
||||
"van-popup": "@vant/weapp/popup/index" |
||||
} |
||||
} |
||||
@ -0,0 +1,46 @@
@@ -0,0 +1,46 @@
|
||||
page { |
||||
background-color: #f7fafc; |
||||
} |
||||
|
||||
.page-title { |
||||
font-size: 36rpx; |
||||
color: rgba(51, 51, 51, 1); |
||||
} |
||||
|
||||
.page { |
||||
padding-bottom: 260rpx; |
||||
.list { |
||||
padding: 40rpx; |
||||
|
||||
.info-card { |
||||
padding: 32rpx; |
||||
background: rgba(255, 255, 255, 0.7); |
||||
border: 1rpx solid #fff; |
||||
border-radius: 32rpx; |
||||
} |
||||
|
||||
.info-row { |
||||
display: flex; |
||||
align-items: start; |
||||
justify-content: space-between; |
||||
padding: 24rpx 0; |
||||
border-bottom: 1rpx solid #f1f5f9; |
||||
|
||||
&:last-child { |
||||
border-bottom: none; |
||||
} |
||||
|
||||
.info-label { |
||||
font-size: 32rpx; |
||||
line-height: 48rpx; |
||||
color: #1e293b; |
||||
} |
||||
|
||||
.info-arrow { |
||||
margin-top: 8rpx; |
||||
color: #64748b; |
||||
margin-left: 8rpx; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,103 @@
@@ -0,0 +1,103 @@
|
||||
const app = getApp<IAppOption>() |
||||
|
||||
Page({ |
||||
data: { |
||||
popupShow: false, |
||||
popupType: '', |
||||
popupParams: { |
||||
position: 'bottom', |
||||
} as any, |
||||
|
||||
topicShow: false, |
||||
replayShow: true, |
||||
|
||||
fileList: [] as any[], |
||||
}, |
||||
onLoad() { |
||||
app.waitLogin({ type: 0 }).then(() => {}) |
||||
}, |
||||
handlePopupOk() { |
||||
const { popupType } = this.data |
||||
if (popupType === 'argument') { |
||||
app.mpBehavior({ PageName: 'BTN_PATIENTLOG' }) |
||||
wx.ajax({ |
||||
method: 'POST', |
||||
url: '?r=wtx/user/agree-guest-privacy', |
||||
data: { |
||||
WorkerId: app.globalData.scene?.workerId || '', |
||||
}, |
||||
}).then(() => { |
||||
this.setData({ |
||||
popupShow: false, |
||||
popupType: '', |
||||
popupParams: {}, |
||||
}) |
||||
const waitBindDoctorId = app.globalData.waitBindDoctorId |
||||
if (waitBindDoctorId) { |
||||
this.handleBindDoctor(waitBindDoctorId) |
||||
} |
||||
}) |
||||
} |
||||
if (popupType === 'conformBindDoctorConform') { |
||||
this.setData({ |
||||
popupShow: false, |
||||
}) |
||||
wx.ajax({ |
||||
method: 'POST', |
||||
url: '?r=wtx/account/wait-bind-doctor', |
||||
data: { |
||||
doctorId: app.globalData.waitBindDoctorId, |
||||
}, |
||||
}).then(() => { |
||||
wx.navigateTo({ |
||||
url: `/patient/pages/login/index`, |
||||
}) |
||||
}) |
||||
} |
||||
}, |
||||
handlePopupCancel() { |
||||
const { popupType } = this.data |
||||
if (popupType === 'argument') { |
||||
wx.exitMiniProgram() |
||||
} |
||||
if (popupType === 'conformBindDoctorConform') { |
||||
this.setData({ |
||||
popupShow: false, |
||||
}) |
||||
wx.ajax({ |
||||
method: 'POST', |
||||
url: '?r=wtx/account/wait-bind-doctor', |
||||
data: { |
||||
doctorId: app.globalData.waitBindDoctorId, |
||||
}, |
||||
}).then(() => { |
||||
app.globalData.waitBindDoctorId = '' |
||||
}) |
||||
} |
||||
}, |
||||
handleWechatWork() { |
||||
wx.navigateTo({ |
||||
url: '/pages/wechatWork/index', |
||||
}) |
||||
}, |
||||
handleSetData(e) { |
||||
const { fileList } = this.data |
||||
this.setData({ |
||||
fileList: [...fileList, ...e.detail], |
||||
}) |
||||
}, |
||||
handleDeleteFile(e) { |
||||
const { index } = e.detail |
||||
const { fileList } = this.data |
||||
this.setData({ |
||||
fileList: fileList.filter((_, i) => i !== index), |
||||
}) |
||||
}, |
||||
topicClose() { |
||||
this.setData({ |
||||
topicShow: false, |
||||
}) |
||||
}, |
||||
}) |
||||
|
||||
export {} |
||||
@ -0,0 +1,32 @@
@@ -0,0 +1,32 @@
|
||||
<navbar fixed custom-style="background:{{background}}" back> |
||||
<view class="page-title" slot="left"> |
||||
<van-icon name="arrow-left" /> |
||||
个人信息 |
||||
</view> |
||||
</navbar> |
||||
|
||||
<view |
||||
class="page" |
||||
style="background: url('/images/bg6.png') no-repeat top center/100% 478rpx;padding-top: {{pageTop}}px;" |
||||
> |
||||
<view class="list"> |
||||
<view class="info-card"> |
||||
<view class="info-row"> |
||||
<text class="info-label">《隐私政策》</text> |
||||
<van-icon name="arrow" class="info-arrow" /> |
||||
</view> |
||||
<view class="info-row"> |
||||
<text class="info-label">《用户协议》</text> |
||||
<van-icon name="arrow" class="info-arrow" /> |
||||
</view> |
||||
<view class="info-row"> |
||||
<text class="info-label">《法律声明》</text> |
||||
<van-icon name="arrow" class="info-arrow" /> |
||||
</view> |
||||
<view class="info-row"> |
||||
<text class="info-label">《健康敏感信息处理与AI服务授权告知书》</text> |
||||
<van-icon name="arrow" class="info-arrow" /> |
||||
</view> |
||||
</view> |
||||
</view> |
||||
</view> |
||||
|
After Width: | Height: | Size: 668 B |
|
After Width: | Height: | Size: 599 B |
|
After Width: | Height: | Size: 626 B |
|
After Width: | Height: | Size: 1.0 KiB |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
{ |
||||
"navigationStyle": "custom", |
||||
"navigationBarTitleText": "我的评论", |
||||
"usingComponents": { |
||||
"popup": "/components/popup/index", |
||||
"navbar": "/components/navbar/index", |
||||
"uploadFile": "/components/uploadFile/index", |
||||
"van-popup": "@vant/weapp/popup/index", |
||||
"van-tab": "@vant/weapp/tab/index", |
||||
"van-tabs": "@vant/weapp/tabs/index" |
||||
} |
||||
} |
||||
@ -0,0 +1,209 @@
@@ -0,0 +1,209 @@
|
||||
page { |
||||
background-color: #f7fafc; |
||||
} |
||||
|
||||
.page-title { |
||||
font-size: 36rpx; |
||||
color: rgba(51, 51, 51, 1); |
||||
} |
||||
|
||||
.page { |
||||
padding-bottom: 260rpx; |
||||
position: relative; |
||||
.page-header { |
||||
padding: 42rpx 30rpx 0; |
||||
.search { |
||||
display: flex; |
||||
align-items: center; |
||||
gap: 16rpx; |
||||
background-color: #fff; |
||||
border-radius: 180rpx; |
||||
padding: 0 32rpx; |
||||
.icon { |
||||
width: 40rpx; |
||||
height: 40rpx; |
||||
} |
||||
.input { |
||||
flex: 1; |
||||
padding: 18rpx 0; |
||||
line-height: 40rpx; |
||||
font-size: 28rpx; |
||||
color: rgba(30, 41, 59, 1); |
||||
} |
||||
.place-input { |
||||
color: rgba(148, 163, 184, 1); |
||||
} |
||||
} |
||||
} |
||||
.tabs { |
||||
.van-tabs__line { |
||||
width: 32rpx !important; |
||||
height: 6rpx; |
||||
border-radius: 1998rpx; |
||||
background: #2f82a9; |
||||
box-sizing: border-box; |
||||
} |
||||
.tab-active-class { |
||||
font-size: 32rpx; |
||||
font-weight: bold; |
||||
} |
||||
.tab-class { |
||||
font-size: 28rpx; |
||||
padding: 26rpx; |
||||
line-height: 44rpx; |
||||
} |
||||
.wrap-class { |
||||
height: 96rpx; |
||||
} |
||||
.nav-calss { |
||||
background-color: transparent; |
||||
height: 96rpx; |
||||
border: none; |
||||
} |
||||
} |
||||
|
||||
.body1 { |
||||
padding: 24rpx 30rpx; |
||||
display: grid; |
||||
grid-template-columns: repeat(2, 1fr); |
||||
gap: 48rpx 30rpx; |
||||
.card { |
||||
display: block; |
||||
width: 100%; |
||||
overflow: hidden; |
||||
.photo { |
||||
position: relative; |
||||
width: 100%; |
||||
height: 442rpx; |
||||
border-radius: 32rpx; |
||||
overflow: hidden; |
||||
.p-img { |
||||
display: block; |
||||
width: 100%; |
||||
height: 100%; |
||||
} |
||||
.stat { |
||||
position: absolute; |
||||
bottom: 0; |
||||
left: 0; |
||||
width: 100%; |
||||
padding: 0 12rpx; |
||||
height: 104rpx; |
||||
box-sizing: border-box; |
||||
background: linear-gradient(180deg, rgba(2, 2, 2, 0) 0%, rgba(3, 3, 3, 0.11) 20.97%, #090909 100%); |
||||
backdrop-filter: opacity(67%); |
||||
display: flex; |
||||
align-items: center; |
||||
justify-content: flex-end; |
||||
gap: 8rpx; |
||||
.s-item { |
||||
padding: 48rpx 12rpx 24rpx; |
||||
display: flex; |
||||
align-items: center; |
||||
gap: 8rpx; |
||||
font-size: 28rpx; |
||||
color: rgba(255, 255, 255, 1); |
||||
.icon { |
||||
width: 32rpx; |
||||
height: 32rpx; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.title { |
||||
margin-top: 24rpx; |
||||
height: 80rpx; |
||||
padding: 0 12rpx; |
||||
color: #2a3544; |
||||
font-size: 28rpx; |
||||
line-height: 40rpx; |
||||
overflow: hidden; |
||||
text-overflow: ellipsis; |
||||
display: -webkit-box; |
||||
-webkit-line-clamp: 2; |
||||
-webkit-box-orient: vertical; |
||||
} |
||||
} |
||||
} |
||||
.body2 { |
||||
margin: 32rpx 30rpx 0; |
||||
.list-card { |
||||
padding: 32rpx; |
||||
background-color: #fff; |
||||
border-radius: 32rpx; |
||||
display: flex; |
||||
gap: 32rpx; |
||||
.photo-wrap { |
||||
position: relative; |
||||
flex-shrink: 0; |
||||
width: 224rpx; |
||||
height: 160rpx; |
||||
border-radius: 16rpx; |
||||
overflow: hidden; |
||||
.photo { |
||||
display: block; |
||||
width: 100%; |
||||
height: 100%; |
||||
} |
||||
.type1 { |
||||
position: absolute; |
||||
bottom: 8rpx; |
||||
left: 8rpx; |
||||
padding: 4rpx 12rpx; |
||||
border-radius: 102rpx; |
||||
background-color: rgba(0, 0, 0, 0.4); |
||||
font-size: 18rpx; |
||||
color: #fff; |
||||
line-height: 27rpx; |
||||
} |
||||
.type2 { |
||||
position: absolute; |
||||
bottom: 8rpx; |
||||
left: 8rpx; |
||||
padding: 4rpx 12rpx; |
||||
border-radius: 102rpx; |
||||
background-color: rgba(0, 0, 0, 0.4); |
||||
font-size: 18rpx; |
||||
color: #fff; |
||||
line-height: 27rpx; |
||||
display: flex; |
||||
align-items: center; |
||||
gap: 4rpx; |
||||
background: linear-gradient(270deg, #439fc7 0%, #2f82a9 100%); |
||||
.icon { |
||||
width: 16rpx; |
||||
height: 16rpx; |
||||
} |
||||
} |
||||
} |
||||
.wrap { |
||||
.title { |
||||
font-size: 28rpx; |
||||
color: rgba(30, 41, 59, 1); |
||||
line-height: 40rpx; |
||||
font-weight: bold; |
||||
height: 80rpx; |
||||
overflow: hidden; |
||||
text-overflow: ellipsis; |
||||
display: -webkit-box; |
||||
-webkit-line-clamp: 2; |
||||
-webkit-box-orient: vertical; |
||||
} |
||||
.op-wrap { |
||||
margin-top: 48rpx; |
||||
.op { |
||||
display: flex; |
||||
align-items: center; |
||||
gap: 8rpx; |
||||
font-size: 24rpx; |
||||
color: rgba(234, 88, 26, 1); |
||||
.icon { |
||||
width: 28rpx; |
||||
height: 28rpx; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,111 @@
@@ -0,0 +1,111 @@
|
||||
const app = getApp<IAppOption>() |
||||
|
||||
Page({ |
||||
data: { |
||||
popupShow: false, |
||||
popupType: '', |
||||
popupParams: { |
||||
position: 'bottom', |
||||
} as any, |
||||
|
||||
topicShow: false, |
||||
replayShow: true, |
||||
|
||||
fileList: [] as any[], |
||||
|
||||
tab: 1, |
||||
offsetTop: 0, |
||||
}, |
||||
onLoad() { |
||||
app.waitLogin({ type: 0 }).then(() => {}) |
||||
}, |
||||
onReady() { |
||||
const { statusBarHeight } = wx.getSystemInfoSync() |
||||
const navBarHeight = 44 |
||||
this.setData({ offsetTop: statusBarHeight + navBarHeight }) |
||||
}, |
||||
handlePopupOk() { |
||||
const { popupType } = this.data |
||||
if (popupType === 'argument') { |
||||
app.mpBehavior({ PageName: 'BTN_PATIENTLOG' }) |
||||
wx.ajax({ |
||||
method: 'POST', |
||||
url: '?r=wtx/user/agree-guest-privacy', |
||||
data: { |
||||
WorkerId: app.globalData.scene?.workerId || '', |
||||
}, |
||||
}).then(() => { |
||||
this.setData({ |
||||
popupShow: false, |
||||
popupType: '', |
||||
popupParams: {}, |
||||
}) |
||||
const waitBindDoctorId = app.globalData.waitBindDoctorId |
||||
if (waitBindDoctorId) { |
||||
this.handleBindDoctor(waitBindDoctorId) |
||||
} |
||||
}) |
||||
} |
||||
if (popupType === 'conformBindDoctorConform') { |
||||
this.setData({ |
||||
popupShow: false, |
||||
}) |
||||
wx.ajax({ |
||||
method: 'POST', |
||||
url: '?r=wtx/account/wait-bind-doctor', |
||||
data: { |
||||
doctorId: app.globalData.waitBindDoctorId, |
||||
}, |
||||
}).then(() => { |
||||
wx.navigateTo({ |
||||
url: `/patient/pages/login/index`, |
||||
}) |
||||
}) |
||||
} |
||||
}, |
||||
handlePopupCancel() { |
||||
const { popupType } = this.data |
||||
if (popupType === 'argument') { |
||||
wx.exitMiniProgram() |
||||
} |
||||
if (popupType === 'conformBindDoctorConform') { |
||||
this.setData({ |
||||
popupShow: false, |
||||
}) |
||||
wx.ajax({ |
||||
method: 'POST', |
||||
url: '?r=wtx/account/wait-bind-doctor', |
||||
data: { |
||||
doctorId: app.globalData.waitBindDoctorId, |
||||
}, |
||||
}).then(() => { |
||||
app.globalData.waitBindDoctorId = '' |
||||
}) |
||||
} |
||||
}, |
||||
handleWechatWork() { |
||||
wx.navigateTo({ |
||||
url: '/pages/wechatWork/index', |
||||
}) |
||||
}, |
||||
handleSetData(e) { |
||||
const { fileList } = this.data |
||||
this.setData({ |
||||
fileList: [...fileList, ...e.detail], |
||||
}) |
||||
}, |
||||
handleDeleteFile(e) { |
||||
const { index } = e.detail |
||||
const { fileList } = this.data |
||||
this.setData({ |
||||
fileList: fileList.filter((_, i) => i !== index), |
||||
}) |
||||
}, |
||||
topicClose() { |
||||
this.setData({ |
||||
topicShow: false, |
||||
}) |
||||
}, |
||||
}) |
||||
|
||||
export {} |
||||
@ -0,0 +1,74 @@
@@ -0,0 +1,74 @@
|
||||
<navbar fixed custom-style="background:{{background}}" back> |
||||
<view class="page-title" slot="left"> |
||||
<van-icon name="arrow-left" /> |
||||
我的收藏 |
||||
</view> |
||||
</navbar> |
||||
|
||||
<view class="page" style="background: url('/images/bg6.png') no-repeat top center/100% 478rpx"> |
||||
<view class="page-header" id="page-header" style="" style="padding-top: {{pageTop + 21}}px;"> |
||||
<view class="search"> |
||||
<image class="icon" src="/images/icon14.png"></image> |
||||
<input class="input" placeholder-class="place-input" type="text" placeholder="搜索视频" /> |
||||
</view> |
||||
</view> |
||||
<van-tabs |
||||
class="tabs" |
||||
active="{{ tab }}" |
||||
sticky |
||||
style="--tabs-nav-background-color: {{background}}" |
||||
color="rgba(47, 130, 169, 1)" |
||||
title-active-color="rgba(47, 130, 169, 1)" |
||||
title-inactive-color="rgba(100, 116, 139, 1)" |
||||
bind:change="onChange" |
||||
tab-active-class="tab-active-class" |
||||
tab-class="tab-class" |
||||
wrap-class="wrap-class" |
||||
nav-class="nav-calss" |
||||
offset-top="{{offsetTop}}" |
||||
> |
||||
<van-tab title="大咖说"> |
||||
<view class="body1"> |
||||
<view class="card" wx:for="{{10}}" wx:key="index"> |
||||
<view class="photo"> |
||||
<image class="p-img" mode="aspectFill" src="/images/bg1.png"></image> |
||||
<view class="stat"> |
||||
<view class="s-item"> |
||||
<image class="icon" src="/images/icon8-1.png"></image> |
||||
12 |
||||
</view> |
||||
<view class="s-item"> |
||||
<image class="icon" src="/images/icon9-1.png"></image> |
||||
12 |
||||
</view> |
||||
</view> |
||||
</view> |
||||
<view class="title">PSVT长期管理专家分享:日常忌口、 PSVT长期管理专家分享:日常忌口、</view> |
||||
</view> |
||||
</view> |
||||
</van-tab> |
||||
<van-tab title="科普教育"> |
||||
<view class="body2"> |
||||
<view class="list-card"> |
||||
<view class="photo-wrap"> |
||||
<image class="photo" mode="aspectFill" src="/images/bg1.png"></image> |
||||
<!-- <view class="type1">图文</view> --> |
||||
<view class="type2"> |
||||
<image class="icon" src="/images/icon10.png"></image> |
||||
视频 |
||||
</view> |
||||
</view> |
||||
<view class="wrap"> |
||||
<view class="title">什么是 PSVT?3 分钟带您了 解阵发性室上性心动过速</view> |
||||
<view class="op-wrap"> |
||||
<view class="op"> |
||||
<image class="icon" src="/images/icon9-active.png"></image> |
||||
取消收藏 |
||||
</view> |
||||
</view> |
||||
</view> |
||||
</view> |
||||
</view> |
||||
</van-tab> |
||||
</van-tabs> |
||||
</view> |
||||
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
{ |
||||
"navigationStyle": "custom", |
||||
"navigationBarTitleText": "我的评论", |
||||
"usingComponents": { |
||||
"popup": "/components/popup/index", |
||||
"navbar": "/components/navbar/index", |
||||
"uploadFile": "/components/uploadFile/index", |
||||
"van-popup": "@vant/weapp/popup/index" |
||||
} |
||||
} |
||||
@ -0,0 +1,155 @@
@@ -0,0 +1,155 @@
|
||||
page { |
||||
background-color: #f7fafc; |
||||
} |
||||
|
||||
.page-title { |
||||
font-size: 36rpx; |
||||
color: rgba(51, 51, 51, 1); |
||||
} |
||||
|
||||
.page { |
||||
padding-bottom: 260rpx; |
||||
.list { |
||||
padding: 0 30rpx; |
||||
.list-card { |
||||
margin-top: 32rpx; |
||||
padding: 32rpx; |
||||
background: #fff; |
||||
border-radius: 32rpx; |
||||
display: flex; |
||||
flex-direction: column; |
||||
gap: 24rpx; |
||||
|
||||
.card-header { |
||||
display: flex; |
||||
justify-content: space-between; |
||||
align-items: center; |
||||
|
||||
.status-tag { |
||||
padding: 8rpx 16rpx; |
||||
border-radius: 12rpx; |
||||
font-size: 28rpx; |
||||
line-height: 36rpx; |
||||
text-align: center; |
||||
&.status1 { |
||||
color: #2f82a9; |
||||
background: rgba(47, 130, 169, 0.08); |
||||
} |
||||
&.status2 { |
||||
color: rgba(45, 190, 141, 1); |
||||
background: rgba(45, 190, 141, 0.08); |
||||
} |
||||
&.status3 { |
||||
color: rgba(186, 26, 26, 1); |
||||
background: rgba(186, 26, 26, 0.08); |
||||
} |
||||
} |
||||
|
||||
.time { |
||||
font-size: 24rpx; |
||||
line-height: 32rpx; |
||||
color: #94a3b8; |
||||
} |
||||
} |
||||
|
||||
.card-content { |
||||
font-size: 32rpx; |
||||
line-height: 52rpx; |
||||
font-weight: 500; |
||||
color: #1e293b; |
||||
} |
||||
|
||||
.card-reference { |
||||
padding: 24rpx; |
||||
background: #f7fafc; |
||||
border-radius: 24rpx; |
||||
display: flex; |
||||
flex-direction: column; |
||||
gap: 16rpx; |
||||
|
||||
.reference-tags { |
||||
display: flex; |
||||
gap: 16rpx; |
||||
|
||||
.tag { |
||||
font-size: 24rpx; |
||||
line-height: 32rpx; |
||||
color: #2f82a9; |
||||
} |
||||
} |
||||
|
||||
.reference-post { |
||||
display: flex; |
||||
gap: 24rpx; |
||||
|
||||
.post-thumbnail { |
||||
width: 96rpx; |
||||
height: 96rpx; |
||||
background: #e2e8f0; |
||||
border-radius: 16rpx; |
||||
} |
||||
|
||||
.post-desc { |
||||
width: 458rpx; |
||||
font-size: 28rpx; |
||||
line-height: 40rpx; |
||||
color: #64748b; |
||||
} |
||||
} |
||||
} |
||||
|
||||
.card-overlay { |
||||
padding: 16rpx 24rpx; |
||||
background: rgba(47, 130, 169, 0.08); |
||||
border-radius: 16rpx; |
||||
line-height: 32rpx; |
||||
|
||||
.icon { |
||||
margin-right: 16rpx; |
||||
width: 32rpx; |
||||
height: 32rpx; |
||||
vertical-align: -4rpx; |
||||
} |
||||
|
||||
.overlay-text { |
||||
display: inline; |
||||
font-size: 28rpx; |
||||
color: #2f82a9; |
||||
} |
||||
} |
||||
|
||||
.rejected { |
||||
padding: 16rpx 24rpx; |
||||
border-radius: 16rpx; |
||||
background: rgba(186, 26, 26, 0.08); |
||||
box-sizing: border-box; |
||||
font-size: 28rpx; |
||||
color: rgba(186, 26, 26, 1); |
||||
line-height: 32rpx; |
||||
.icon { |
||||
display: inline-block; |
||||
flex-shrink: 0; |
||||
margin-right: 16rpx; |
||||
width: 32rpx; |
||||
height: 32rpx; |
||||
vertical-align: -4rpx; |
||||
} |
||||
.blod { |
||||
display: inline-block; |
||||
font-weight: bold; |
||||
} |
||||
} |
||||
|
||||
.card-footer { |
||||
display: flex; |
||||
justify-content: flex-end; |
||||
|
||||
.delete-btn { |
||||
font-size: 28rpx; |
||||
line-height: 40rpx; |
||||
color: #94a3b8; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,103 @@
@@ -0,0 +1,103 @@
|
||||
const app = getApp<IAppOption>() |
||||
|
||||
Page({ |
||||
data: { |
||||
popupShow: false, |
||||
popupType: '', |
||||
popupParams: { |
||||
position: 'bottom', |
||||
} as any, |
||||
|
||||
topicShow: false, |
||||
replayShow: true, |
||||
|
||||
fileList: [] as any[], |
||||
}, |
||||
onLoad() { |
||||
app.waitLogin({ type: 0 }).then(() => {}) |
||||
}, |
||||
handlePopupOk() { |
||||
const { popupType } = this.data |
||||
if (popupType === 'argument') { |
||||
app.mpBehavior({ PageName: 'BTN_PATIENTLOG' }) |
||||
wx.ajax({ |
||||
method: 'POST', |
||||
url: '?r=wtx/user/agree-guest-privacy', |
||||
data: { |
||||
WorkerId: app.globalData.scene?.workerId || '', |
||||
}, |
||||
}).then(() => { |
||||
this.setData({ |
||||
popupShow: false, |
||||
popupType: '', |
||||
popupParams: {}, |
||||
}) |
||||
const waitBindDoctorId = app.globalData.waitBindDoctorId |
||||
if (waitBindDoctorId) { |
||||
this.handleBindDoctor(waitBindDoctorId) |
||||
} |
||||
}) |
||||
} |
||||
if (popupType === 'conformBindDoctorConform') { |
||||
this.setData({ |
||||
popupShow: false, |
||||
}) |
||||
wx.ajax({ |
||||
method: 'POST', |
||||
url: '?r=wtx/account/wait-bind-doctor', |
||||
data: { |
||||
doctorId: app.globalData.waitBindDoctorId, |
||||
}, |
||||
}).then(() => { |
||||
wx.navigateTo({ |
||||
url: `/patient/pages/login/index`, |
||||
}) |
||||
}) |
||||
} |
||||
}, |
||||
handlePopupCancel() { |
||||
const { popupType } = this.data |
||||
if (popupType === 'argument') { |
||||
wx.exitMiniProgram() |
||||
} |
||||
if (popupType === 'conformBindDoctorConform') { |
||||
this.setData({ |
||||
popupShow: false, |
||||
}) |
||||
wx.ajax({ |
||||
method: 'POST', |
||||
url: '?r=wtx/account/wait-bind-doctor', |
||||
data: { |
||||
doctorId: app.globalData.waitBindDoctorId, |
||||
}, |
||||
}).then(() => { |
||||
app.globalData.waitBindDoctorId = '' |
||||
}) |
||||
} |
||||
}, |
||||
handleWechatWork() { |
||||
wx.navigateTo({ |
||||
url: '/pages/wechatWork/index', |
||||
}) |
||||
}, |
||||
handleSetData(e) { |
||||
const { fileList } = this.data |
||||
this.setData({ |
||||
fileList: [...fileList, ...e.detail], |
||||
}) |
||||
}, |
||||
handleDeleteFile(e) { |
||||
const { index } = e.detail |
||||
const { fileList } = this.data |
||||
this.setData({ |
||||
fileList: fileList.filter((_, i) => i !== index), |
||||
}) |
||||
}, |
||||
topicClose() { |
||||
this.setData({ |
||||
topicShow: false, |
||||
}) |
||||
}, |
||||
}) |
||||
|
||||
export {} |
||||
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
<navbar fixed custom-style="background:{{background}}" back> |
||||
<view class="page-title" slot="left"> |
||||
<van-icon name="arrow-left" /> |
||||
我的评论 |
||||
</view> |
||||
</navbar> |
||||
|
||||
<view |
||||
class="page" |
||||
style="background: url('/images/bg6.png') no-repeat top center/100% 478rpx;padding-top: {{pageTop}}px;" |
||||
> |
||||
<view class="list"> |
||||
<view class="list-card" bind:tap="handleDetail"> |
||||
<view class="card-header"> |
||||
<!-- status1:待审核,status2:已通过,status3:已驳回 --> |
||||
<view class="status-tag status1">待审核</view> |
||||
<view class="time">2026-01-01 13:00:09</view> |
||||
</view> |
||||
<view class="card-content">记录发作时间真的很重要,尤其是频率和持续时长</view> |
||||
<view class="card-reference"> |
||||
<view class="reference-tags"> |
||||
<view class="tag"># 我的心悸经历</view> |
||||
<view class="tag"># PSVT急救常识</view> |
||||
</view> |
||||
<view class="reference-post"> |
||||
<view class="post-thumbnail"></view> |
||||
<view class="post-desc">今天把近期的状态、复诊资料和生活节奏整理了一下,也想记录一下最</view> |
||||
</view> |
||||
</view> |
||||
<view class="card-overlay"> |
||||
<image class="icon" src="/images/icon40.png"></image> |
||||
<view class="overlay-text">评论正在审核中,预计1-2个工作日内完成审核。</view> |
||||
</view> |
||||
<view class="rejected"> |
||||
<image class="icon" src="/images/icon39.png"></image> |
||||
<view class="blod">驳回原因:</view> |
||||
语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 |
||||
语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 |
||||
</view> |
||||
<view class="card-footer"> |
||||
<view class="delete-btn">删除</view> |
||||
</view> |
||||
</view> |
||||
</view> |
||||
</view> |
||||
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
{ |
||||
"navigationStyle": "custom", |
||||
"navigationBarTitleText": "我的评论", |
||||
"usingComponents": { |
||||
"popup": "/components/popup/index", |
||||
"navbar": "/components/navbar/index", |
||||
"uploadFile": "/components/uploadFile/index", |
||||
"van-popup": "@vant/weapp/popup/index" |
||||
} |
||||
} |
||||
@ -0,0 +1,92 @@
@@ -0,0 +1,92 @@
|
||||
page { |
||||
background-color: #f7fafc; |
||||
} |
||||
|
||||
.page-title { |
||||
font-size: 36rpx; |
||||
color: rgba(51, 51, 51, 1); |
||||
} |
||||
|
||||
.page { |
||||
padding-bottom: 260rpx; |
||||
.list { |
||||
padding: 40rpx; |
||||
|
||||
.info-card { |
||||
padding: 32rpx; |
||||
background: rgba(255, 255, 255, 0.7); |
||||
border: 1rpx solid #fff; |
||||
border-radius: 32rpx; |
||||
} |
||||
|
||||
.info-row { |
||||
display: flex; |
||||
align-items: center; |
||||
justify-content: space-between; |
||||
padding: 24rpx 0; |
||||
border-bottom: 1rpx solid #f1f5f9; |
||||
|
||||
&:last-child { |
||||
border-bottom: none; |
||||
} |
||||
|
||||
.info-label { |
||||
font-size: 32rpx; |
||||
line-height: 48rpx; |
||||
color: #1e293b; |
||||
} |
||||
|
||||
.info-value { |
||||
flex: 1; |
||||
font-size: 32rpx; |
||||
line-height: 48rpx; |
||||
color: #64748b; |
||||
text-align: right; |
||||
} |
||||
|
||||
.info-arrow { |
||||
color: #64748b; |
||||
margin-left: 8rpx; |
||||
} |
||||
|
||||
.avatar-wrap { |
||||
width: 112rpx; |
||||
height: 112rpx; |
||||
border-radius: 50%; |
||||
background: #d9d9d9; |
||||
overflow: hidden; |
||||
|
||||
.avatar { |
||||
width: 100%; |
||||
height: 100%; |
||||
} |
||||
} |
||||
} |
||||
|
||||
.btn-logout { |
||||
margin-top: 32rpx; |
||||
height: 96rpx; |
||||
display: flex; |
||||
align-items: center; |
||||
justify-content: center; |
||||
background: #fff; |
||||
border-radius: 54rpx; |
||||
font-size: 32rpx; |
||||
line-height: 48rpx; |
||||
color: #1e293b; |
||||
} |
||||
|
||||
.btn-cancel { |
||||
margin-top: 24rpx; |
||||
height: 96rpx; |
||||
display: flex; |
||||
align-items: center; |
||||
justify-content: center; |
||||
background: #fff; |
||||
border-radius: 54rpx; |
||||
font-size: 32rpx; |
||||
line-height: 48rpx; |
||||
color: #1e293b; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,103 @@
@@ -0,0 +1,103 @@
|
||||
const app = getApp<IAppOption>() |
||||
|
||||
Page({ |
||||
data: { |
||||
popupShow: false, |
||||
popupType: '', |
||||
popupParams: { |
||||
position: 'bottom', |
||||
} as any, |
||||
|
||||
topicShow: false, |
||||
replayShow: true, |
||||
|
||||
fileList: [] as any[], |
||||
}, |
||||
onLoad() { |
||||
app.waitLogin({ type: 0 }).then(() => {}) |
||||
}, |
||||
handlePopupOk() { |
||||
const { popupType } = this.data |
||||
if (popupType === 'argument') { |
||||
app.mpBehavior({ PageName: 'BTN_PATIENTLOG' }) |
||||
wx.ajax({ |
||||
method: 'POST', |
||||
url: '?r=wtx/user/agree-guest-privacy', |
||||
data: { |
||||
WorkerId: app.globalData.scene?.workerId || '', |
||||
}, |
||||
}).then(() => { |
||||
this.setData({ |
||||
popupShow: false, |
||||
popupType: '', |
||||
popupParams: {}, |
||||
}) |
||||
const waitBindDoctorId = app.globalData.waitBindDoctorId |
||||
if (waitBindDoctorId) { |
||||
this.handleBindDoctor(waitBindDoctorId) |
||||
} |
||||
}) |
||||
} |
||||
if (popupType === 'conformBindDoctorConform') { |
||||
this.setData({ |
||||
popupShow: false, |
||||
}) |
||||
wx.ajax({ |
||||
method: 'POST', |
||||
url: '?r=wtx/account/wait-bind-doctor', |
||||
data: { |
||||
doctorId: app.globalData.waitBindDoctorId, |
||||
}, |
||||
}).then(() => { |
||||
wx.navigateTo({ |
||||
url: `/patient/pages/login/index`, |
||||
}) |
||||
}) |
||||
} |
||||
}, |
||||
handlePopupCancel() { |
||||
const { popupType } = this.data |
||||
if (popupType === 'argument') { |
||||
wx.exitMiniProgram() |
||||
} |
||||
if (popupType === 'conformBindDoctorConform') { |
||||
this.setData({ |
||||
popupShow: false, |
||||
}) |
||||
wx.ajax({ |
||||
method: 'POST', |
||||
url: '?r=wtx/account/wait-bind-doctor', |
||||
data: { |
||||
doctorId: app.globalData.waitBindDoctorId, |
||||
}, |
||||
}).then(() => { |
||||
app.globalData.waitBindDoctorId = '' |
||||
}) |
||||
} |
||||
}, |
||||
handleWechatWork() { |
||||
wx.navigateTo({ |
||||
url: '/pages/wechatWork/index', |
||||
}) |
||||
}, |
||||
handleSetData(e) { |
||||
const { fileList } = this.data |
||||
this.setData({ |
||||
fileList: [...fileList, ...e.detail], |
||||
}) |
||||
}, |
||||
handleDeleteFile(e) { |
||||
const { index } = e.detail |
||||
const { fileList } = this.data |
||||
this.setData({ |
||||
fileList: fileList.filter((_, i) => i !== index), |
||||
}) |
||||
}, |
||||
topicClose() { |
||||
this.setData({ |
||||
topicShow: false, |
||||
}) |
||||
}, |
||||
}) |
||||
|
||||
export {} |
||||
@ -0,0 +1,60 @@
@@ -0,0 +1,60 @@
|
||||
<navbar fixed custom-style="background:{{background}}" back> |
||||
<view class="page-title" slot="left"> |
||||
<van-icon name="arrow-left" /> |
||||
个人信息 |
||||
</view> |
||||
</navbar> |
||||
|
||||
<view |
||||
class="page" |
||||
style="background: url('/images/bg6.png') no-repeat top center/100% 478rpx;padding-top: {{pageTop}}px;" |
||||
> |
||||
<view class="list"> |
||||
<view class="info-card"> |
||||
<view class="info-row"> |
||||
<text class="info-label">头像</text> |
||||
<view class="avatar-wrap"> |
||||
<image class="avatar" src="" mode="aspectFill" /> |
||||
</view> |
||||
</view> |
||||
<view class="info-row"> |
||||
<text class="info-label">昵称</text> |
||||
<text class="info-value">ZSX0092</text> |
||||
</view> |
||||
<view class="info-row" bind:tap="handlePhone"> |
||||
<text class="info-label">手机号</text> |
||||
<text class="info-value">153****0000</text> |
||||
<van-icon name="arrow" class="info-arrow" /> |
||||
</view> |
||||
<view class="info-row" bind:tap="handleAge"> |
||||
<text class="info-label">年龄段</text> |
||||
<text class="info-value">18-35岁</text> |
||||
<van-icon name="arrow" class="info-arrow" /> |
||||
</view> |
||||
<view class="info-row" bind:tap="handleGender"> |
||||
<text class="info-label">性别</text> |
||||
<text class="info-value">女</text> |
||||
<van-icon name="arrow" class="info-arrow" /> |
||||
</view> |
||||
<view class="info-row" bind:tap="handleRegion"> |
||||
<text class="info-label">所在地区</text> |
||||
<text class="info-value">北京/北京市</text> |
||||
<van-icon name="arrow" class="info-arrow" /> |
||||
</view> |
||||
<view class="info-row" bind:tap="handleHealth"> |
||||
<text class="info-label">我的健康状态</text> |
||||
<text class="info-value">已确诊</text> |
||||
</view> |
||||
<view class="info-row"> |
||||
<text class="info-label">确诊时间</text> |
||||
<text class="info-value">2024-08-01</text> |
||||
</view> |
||||
<view class="info-row"> |
||||
<text class="info-label">是否接受过手术治疗</text> |
||||
<text class="info-value">正在评估</text> |
||||
</view> |
||||
</view> |
||||
<view class="btn-logout">退出登录</view> |
||||
<view class="btn-cancel">注销</view> |
||||
</view> |
||||
</view> |
||||
Loading…
Reference in new issue