feat: 修复部分功能(健康信息、VIP、医生端健康信息导入)

This commit is contained in:
李琦
2026-08-08 10:33:59 +08:00
parent 874d1e7731
commit 74272d61d2
16 changed files with 1799 additions and 781 deletions

View File

@@ -0,0 +1,49 @@
---
description: Yii 与 xk-api 接口响应取值规范(按后端固定写死,禁止混取)
alwaysApply: true
---
# 接口响应取值Yii vs xk-api
写请求代码时**先确认该接口走哪个后端**,再按对应字段固定取值。
**禁止**运行时猜测(如「有 code 就取 result」**禁止** `result || data` / `code ?? errcode` 混写兼容。
## 形态对照
| | YiioldApi | xk-apiLaravel jok |
|---|---|---|
| 成功码 | `errcode: 0` | `code: 0` |
| 业务数据 | `data` | `result` |
| 提示文案 | `msg` | `message` |
## 强制用法
统一用 `@/utils/api-response.js`,按后端选方法:
```js
// 该接口是 xk-api
import { unwrapXkApi } from '@/utils/api-response.js'
const { ok, payload, message } = unwrapXkApi(res)
// 该接口是 Yii
import { unwrapYiiApi } from '@/utils/api-response.js'
const { ok, payload, message } = unwrapYiiApi(res)
```
也可直接写死(患者端完整响应在 `res.data`
```js
// xk-api
if (res.data.code == 0) { const data = res.data.result }
// Yii
if (res.data.errcode == 0) { const data = res.data.data }
```
API 封装文件注释里标明后端,例如:`// xk-api POST /patient/list`。
## 禁止
- 禁止 `unwrapApi` 一类「自动识别后端再取值」
- 禁止 `res.data.result || res.data.data`
- 禁止把 xk-api 再 `normalize` 成 errcode/data 后按 Yii 读

View File

@@ -10,3 +10,4 @@ alwaysApply: true
5. 数据库的created_at、updated_at、deleted_at统一使用时间戳不要使用字符串并且我在查询器中一级格式化成字符串了无需再次格式化
6. 微信小程序 `.vue` 模板(会编译成 WXML禁止使用 `??`、`?.` 等现代运算符,否则会报 `unexpected token '?'`;模板里用 `||` / 显式判断,脚本里可用 `??`/`?.`
7. 微信小程序模板里 `:class` / `:style` 禁止写 `fn(arg)` 方法调用(如 `:class="sexClass(p)"` 会编译失败);用对象/数组字面量(如 `:class="{ male: p.sex == 1 }"`),或把结果先算进 data/computed 再绑定
8. 接口取值:写代码时先确认接口是 xk-api 还是 Yii再固定用 `code/result/message` 或 `errcode/data/msg`(可用 `unwrapXkApi` / `unwrapYiiApi`);禁止运行时猜测、禁止 `result || data`(详见 Api-Response.mdc

181
mixins/patientTabList.js Normal file
View File

@@ -0,0 +1,181 @@
/**
* 就诊人 Tab + swiper 列表公共逻辑(处方/挂号/病历复用)
* 页面需实现fetchPatientList(patientId, page) → Promise 返回完整接口 res
*/
import { getPatientListApi } from '@/request/api/patient.js'
import { unwrapXkApi } from '@/utils/api-response.js'
export default {
data() {
return {
patientList: [],
patientTabs: [],
current: 0,
tabChanging: false,
infoList: [],
page: 1,
totalPage: 1,
total: 0,
loadMoreStatus: 'nomore',
isRefreshing: false,
scrollTop: 0,
emptyPatient: false,
}
},
computed: {
currentPatientId() {
const p = this.patientList[this.current]
return p ? Number(p.id) : 0
},
},
methods: {
/**
* 拉取就诊人并加载当前 Tab 列表
*/
async bootstrapPatientTabs() {
try {
const res = await getPatientListApi({})
// getPatientListApi → xk-api
const { ok, payload } = unwrapXkApi(res)
if (!ok) {
this.patientList = []
this.patientTabs = []
this.emptyPatient = true
this.infoList = []
return
}
// xk-api{ list, latest_register_user_patient_id };兼容旧版纯数组
const list = Array.isArray(payload) ? payload : (payload && payload.list) || []
const latestId = Array.isArray(payload)
? 0
: Number((payload && payload.latest_register_user_patient_id) || 0)
this.patientList = list
this.patientTabs = list.map((p) => ({ name: p.name || '就诊人' }))
this.emptyPatient = list.length === 0
if (list.length === 0) {
this.infoList = []
return
}
// 优先最近挂号就诊人,其次默认就诊人,否则第一个
let idx = -1
if (latestId > 0) {
idx = list.findIndex((p) => Number(p.id) === latestId)
}
if (idx < 0) {
idx = list.findIndex((p) => Number(p.is_default) === 1)
}
if (idx < 0) {
idx = 0
}
if (this.current >= list.length) {
this.current = idx
} else if (!this._tabsBootstrapped) {
this.current = idx
}
this._tabsBootstrapped = true
this.reloadCurrentTab()
} catch (e) {
console.error('bootstrapPatientTabs', e)
this.emptyPatient = true
}
},
onTabChange(index) {
if (this.tabChanging) {
return
}
this.tabChanging = true
this.changePatientTab(index)
this.$nextTick(() => {
this.tabChanging = false
})
},
onSwiperChange(e) {
if (this.tabChanging) {
return
}
this.tabChanging = true
this.changePatientTab(e.detail.current)
this.$nextTick(() => {
this.tabChanging = false
})
},
changePatientTab(index) {
const tabIndex = Number(index) || 0
this.current = tabIndex
this.reloadCurrentTab()
},
reloadCurrentTab() {
this.page = 1
this.infoList = []
this.loadMoreStatus = 'loading'
this.fetchCurrentList()
},
/**
* 页面实现return getXxxListApi({...})
*/
fetchPatientList() {
return Promise.reject(new Error('请实现 fetchPatientList'))
},
fetchCurrentList(callback) {
const patientId = this.currentPatientId
if (!patientId) {
this.infoList = []
this.loadMoreStatus = 'nomore'
if (typeof callback === 'function') {
callback()
}
return
}
this.fetchPatientList(patientId, this.page)
.then((res) => {
// fetchPatientList 约定走 xk-api处方/挂号/病历)
const { ok, payload } = unwrapXkApi(res)
if (!ok || !payload) {
this.loadMoreStatus = 'nomore'
return
}
const list = payload.list || []
const pagination = payload.pagination || {}
this.totalPage = Number(pagination.totalPage) || 1
this.total = Number(pagination.total) || 0
if (this.page > 1) {
this.infoList = this.infoList.concat(list)
} else {
this.infoList = list
}
this.loadMoreStatus = this.page >= this.totalPage ? 'nomore' : 'loadmore'
})
.catch((e) => {
console.error('fetchCurrentList', e)
this.loadMoreStatus = 'nomore'
})
.finally(() => {
if (typeof callback === 'function') {
callback()
}
})
},
onRefresherRefresh() {
this.isRefreshing = true
this.page = 1
this.infoList = []
this.fetchCurrentList(() => {
this.isRefreshing = false
})
},
onOrderScrollToLower() {
if (this.page >= this.totalPage) {
this.loadMoreStatus = 'nomore'
return
}
this.page += 1
this.loadMoreStatus = 'loading'
this.fetchCurrentList()
},
goAddPatient() {
uni.navigateTo({
url: '/subPackages/my/myinfo-add',
})
},
},
}

View File

@@ -313,18 +313,32 @@
"enablePullDownRefresh": false
}
},
{
"path": "my/mymedical",
"style": {
"navigationBarTitleText": "我的病历",
"enablePullDownRefresh": false
}
},
{
"path": "my/mymedical-detail",
"style": {
"navigationBarTitleText": "病历详情",
"enablePullDownRefresh": false
}
},
{
"path": "my/myrecord",
"style": {
"navigationBarTitleText": "处方记录",
"enablePullDownRefresh": true
"navigationBarTitleText": "我的处方",
"enablePullDownRefresh": false
}
},
{
"path": "my/myappiont",
"style": {
"navigationBarTitleText": "挂号记录",
"enablePullDownRefresh": true
"navigationBarTitleText": "我的挂号",
"enablePullDownRefresh": false
}
},
{

View File

@@ -63,17 +63,17 @@
<!-- 列表 -->
<view class="list">
<!-- <navigator url="../../subPackages/my/myorder" class="infos">
<navigator url="../../subPackages/my/mymedical" class="infos">
<image src="https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk-client-wx/static/mine/01.png" mode=""></image>
<text>问诊记录</text>
</navigator> -->
<text>我的病历</text>
</navigator>
<navigator url="../../subPackages/my/myrecord" class="infos">
<image src="https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk-client-wx/static/mine/02.png" mode=""></image>
<text>处方记录</text>
<text>我的处方</text>
</navigator>
<navigator url="../../subPackages/my/myappiont" class="infos">
<image src="https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk-client-wx/static/mine/03.png" mode=""></image>
<text>挂号记录</text>
<text>我的挂号</text>
</navigator>
</view>
</view>
@@ -108,6 +108,7 @@
import {
getUserInfoApi
} from '../../request/api/user'
import { unwrapXkApi } from '@/utils/api-response.js'
export default {
data() {
return {
@@ -140,9 +141,10 @@
getUserInfoApi({
store_id: uni.getStorageSync('store_id') || 11001
}).then((res) => {
// console.log(res, 'ingo');
if (res.data.code == 0) {
this.infoList = res.data.result
// getUserInfoApi → xk-api
const { ok, payload } = unwrapXkApi(res)
if (ok) {
this.infoList = payload
}
})
},

View File

@@ -0,0 +1,19 @@
import { post, get } from './http'
/**
* 我的病历列表xk-api POST /medical-record/list
* 取值unwrapXkApi → code/result/message
* @param {{ user_patient_id: number, page?: number, pageSize?: number }} params
*/
export async function getMedicalRecordListApi(params) {
return await post('/medical-record/list', params, 3)
}
/**
* 我的病历详情xk-api GET /medical-record/detail
* 取值unwrapXkApi → code/result/message
* @param {{ id: number }} params
*/
export async function getMedicalRecordDetailApi(params) {
return await get('/medical-record/detail', params, 3)
}

41
request/api/patient.js Normal file
View File

@@ -0,0 +1,41 @@
import { post, get } from './http'
/**
* 就诊人相关接口统一走 xk-apitype=3
* 取值unwrapXkApi → code / result / message
*/
/** 就诊人列表 POST /patient/list → { list, latest_register_user_patient_id } */
export async function getPatientListApi(params = {}) {
return await post('/patient/list', params, 3)
}
/** 就诊人保存(新增/编辑POST /patient/save */
export async function savePatientApi(params = {}) {
return await post('/patient/save', params, 3)
}
/** 删除就诊人 POST /patient/delete */
export async function deletePatientApi(params = {}) {
return await post('/patient/delete', params, 3)
}
/** 监护人信息 GET /patient/guardian-info */
export async function getPatientGuardianInfoApi(params = {}) {
return await get('/patient/guardian-info', params, 3)
}
/** 关系枚举 GET /patient/relation */
export async function getPatientRelationApi(params = {}) {
return await get('/patient/relation', params, 3)
}
/** 设为默认就诊人 POST /patient/change-default传 up_id */
export async function changePatientDefaultApi(params = {}) {
return await post('/patient/change-default', params, 3)
}
/** 健康问诊详情 POST /patient/health-info传 user_patient_id */
export async function getPatientHealthInfoApi(params = {}) {
return await post('/patient/health-info', params, 3)
}

View File

@@ -1,4 +1,5 @@
import {post} from './http'
import { unwrapXkApi } from '@/utils/api-response.js'
/**
* 获取挂号记录列表
@@ -21,9 +22,11 @@ export async function fetchUnpaidRegisterListApi(params = {}) {
page: 1,
...params,
}, 3);
if (res.data?.code !== 0 && res.data?.code !== '0') {
// /register/list → xk-api
const { ok, payload } = unwrapXkApi(res)
if (!ok) {
return [];
}
const list = res.data?.result?.list || [];
const list = (payload && payload.list) || [];
return list.filter((item) => item.status === 0 && item.is_cancel !== 1);
}

View File

@@ -1,432 +1,241 @@
<template>
<!-- 我的挂号就诊人 Tab + 左右滑动切换 -->
<view class="container safe-area-inset-bottom">
<MessageNotification />
<view class="head" @click="toChoose">
<view class="head_name">{{infoUserList[0].name || '请选择就诊人'}}</view>
<view class="head_qh">
切换就诊人
<text class="iconfont icon-jiantou1"></text>
</view>
<view class="head" v-if="patientTabs.length > 0">
<u-tabs :list="patientTabs" :is-scroll="true" :current="current" @change="onTabChange"></u-tabs>
</view>
<!-- 空页 -->
<view class="empty" v-if="infoList.length==0">
<view class="empty-patient" v-if="emptyPatient">
<image src="https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk-client-wx/static/empty/orders.png" mode="aspectFit"></image>
<view class="word">暂无挂号记录~</view>
<view class="word">暂无就诊人请先添加</view>
<view class="add-btn" @click="goAddPatient">添加就诊人</view>
</view>
<!-- 挂号记录 -->
<view class="list" v-for="(item,index) in infoList" :key="item.id">
<view class="li_title">
<text>{{item.created_at}}</text>
<text class="text"
v-if="item.status<4">{{item.status==0&&'待支付'||item.status==1&&'待接诊' || item.status==2&&'接诊中' || item.status==3&&'已结束'}}</text>
<text class="txt" v-if="item.status>=4">{{item.status==4&&'已取消' || item.status==7&&'已拒诊'}}</text>
</view>
<view class="info">
<view class="list_name">
患者姓名
</view>
<text>{{item.patient}}</text>
</view>
<view class="info">
<view class="list_name">
预约诊所
</view>
<text>{{item.store}}</text>
</view>
<view class="info">
<view class="list_name">
预约科室
</view>
<text>{{item.depart}}</text>
</view>
<view class="info">
<view class="list_name">
预约医生
</view>
<text>{{item.doctor}}</text>
</view>
<view class="info">
<view class="list_name">
预约序号
</view>
<text>{{item.order_number}}</text>
</view>
<view class="info">
<view class="list_name">
挂号金额
</view>
<text>{{item.store}}</text>
</view>
<!-- 转诊卡片 -->
<TransferPrescriptionCard
v-if="item.is_from_transfer == 1 && item.transfer_prescription"
:transfer-data="item.transfer_prescription"
@agree="handleTransferAgree"
@reject="handleTransferReject"
/>
<!-- 查看详情 -->
<view class="detail" @click="getInfo(item.id)"><text>查看详情</text></view>
</view>
<u-loadmore :status="status" />
<u-back-top :scroll-top="scrollTop"></u-back-top>
<swiper v-else class="list-swiper" :current="current" @change="onSwiperChange">
<swiper-item v-for="(tab, tabIdx) in patientTabs" :key="tabIdx">
<scroll-view
scroll-y
class="list-scroll"
@scrolltolower="onOrderScrollToLower"
refresher-enabled="true"
:refresher-triggered="isRefreshing"
@refresherrefresh="onRefresherRefresh"
>
<block v-if="Number(current) === tabIdx">
<view class="empty" v-if="infoList.length==0">
<image src="https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk-client-wx/static/empty/orders.png" mode="aspectFit"></image>
<view class="word">暂无挂号记录~</view>
</view>
<view class="list" v-for="(item,index) in infoList" :key="item.id">
<view class="li_title">
<text>{{item.created_at}}</text>
<text class="text" v-if="item.status<4">{{ statusText(item.status) }}</text>
<text class="txt" v-if="item.status>=4">{{ statusText(item.status) }}</text>
</view>
<view class="info">
<view class="list_name">患者姓名</view>
<text>{{item.patient}}</text>
</view>
<view class="info">
<view class="list_name">预约诊所</view>
<text>{{item.store}}</text>
</view>
<view class="info">
<view class="list_name">预约科室</view>
<text>{{item.depart}}</text>
</view>
<view class="info">
<view class="list_name">预约医生</view>
<text>{{item.doctor}}</text>
</view>
<view class="info">
<view class="list_name">预约序号</view>
<text>{{item.order_number}}</text>
</view>
<TransferPrescriptionCard
v-if="item.is_from_transfer == 1 && item.transfer_prescription"
:transfer-data="item.transfer_prescription"
@agree="handleTransferAgree"
@reject="handleTransferReject"
/>
<view class="detail" @click="getInfo(item.id)"><text>查看详情</text></view>
</view>
<u-loadmore :status="loadMoreStatus" v-if="infoList.length!=0" margin-top="30" margin-bottom="30" />
</block>
</scroll-view>
</swiper-item>
</swiper>
<u-toast ref="uToast" />
</view>
</template>
<script>
import {
userList
} from '../../request/api/api'
import {
getRegisterListApi
} from '../../request/api/register'
import { getRegisterListApi } from '../../request/api/register'
import {
agreeTransferPrescriptionApi,
rejectTransferPrescriptionApi
} from '../../request/api/transferPrescription'
import TransferPrescriptionCard from './components/TransferPrescriptionCard.vue'
export default {
components: {
TransferPrescriptionCard
},
data() {
return {
status: 'nomore',
infoList: [],
infoUserList: [],
myinfo: [],
id: "",
page: 1, // 当前页数
total: "", // 总条数
totalPage: "", // 总页数
pageSize: 20, // 每页条数
scrollTop: 0
}
},
onLoad() {
import patientTabList from '@/mixins/patientTabList.js'
import { unwrapXkApi } from '@/utils/api-response.js'
},
created() {
this.getInfolist()
},
export default {
components: { TransferPrescriptionCard },
mixins: [patientTabList],
methods: {
// 切换
toChoose() {
uni.navigateTo({
url: "/subPackages/my/myinfo?id="
})
statusText(status) {
if (status == 0) return '待支付'
if (status == 1) return '待接诊'
if (status == 2) return '接诊中'
if (status == 3) return '已结束'
if (status == 4) return '已取消'
if (status == 7) return '已拒诊'
return ''
},
// 详情
getInfo(id) {
uni.navigateTo({
url: "/subPackages/register/register-info?id=" + id + '&type=' + 1
url: '/subPackages/register/register-info?id=' + id + '&type=' + 1
})
},
fetchPatientList(patientId, page) {
return getRegisterListApi({
store_id: uni.getStorageSync('store_id') || 11001,
patient_id: patientId,
page: page
})
},
// 同意转诊
handleTransferAgree(transferData) {
uni.showModal({
title: '确认转诊',
content: '确定同意转诊吗?',
success: (res) => {
if (res.confirm) {
agreeTransferPrescriptionApi({ id: transferData.id }).then((result) => {
if (result.data.code == 0) {
uni.showToast({
title: '同意转诊成功',
icon: 'success'
if (!res.confirm) return
agreeTransferPrescriptionApi({ id: transferData.id }).then((result) => {
// transfer-prescription → xk-api
const { ok, message } = unwrapXkApi(result)
if (ok) {
uni.showToast({ title: '同意转诊成功', icon: 'success' })
setTimeout(() => {
uni.redirectTo({
url: '/subPackages/transfer/transfer-consultation?transfer_id=' + transferData.id
})
// 跳转到咨询页面
setTimeout(() => {
uni.redirectTo({
url: `/subPackages/transfer/transfer-consultation?transfer_id=${transferData.id}`,
fail: (err) => {
console.error('跳转失败:', err)
uni.showToast({ title: '跳转失败,请重试', icon: 'none' })
}
})
}, 1000)
} else {
uni.showToast({
title: result.data.message || '操作失败',
icon: 'none'
})
}
}).catch((error) => {
console.error('同意转诊失败:', error)
uni.showToast({
title: '操作失败,请重试',
icon: 'none'
})
})
}
}, 1000)
} else {
uni.showToast({ title: message || '操作失败', icon: 'none' })
}
})
}
})
},
// 拒绝转诊
handleTransferReject(transferData) {
uni.showModal({
title: '拒绝转诊',
content: '确定拒绝转诊吗?',
success: (res) => {
if (res.confirm) {
rejectTransferPrescriptionApi({ id: transferData.id }).then((result) => {
if (result.data.code == 0) {
uni.showToast({
title: '已拒绝转诊',
icon: 'success'
})
// 刷新列表
this.page = 1
this.infoList = []
this.getInfos()
} else {
uni.showToast({
title: result.data.message || '操作失败',
icon: 'none'
})
}
}).catch((error) => {
console.error('拒绝转诊失败:', error)
uni.showToast({
title: '操作失败,请重试',
icon: 'none'
})
})
}
if (!res.confirm) return
rejectTransferPrescriptionApi({ id: transferData.id }).then((result) => {
const { ok, message } = unwrapXkApi(result)
if (ok) {
uni.showToast({ title: '已拒绝转诊', icon: 'success' })
this.reloadCurrentTab()
} else {
uni.showToast({ title: message || '操作失败', icon: 'none' })
}
})
}
})
},
// 就诊人列表
getInfolist() {
userList({
method: "post",
data: {
store_id: uni.getStorageSync('store_id') || 11001,
}
}).then((res) => {
if (res.data.errcode == 0) {
this.infoUserList = res.data.data.filter((item) => item.is_default == 1)
// console.log(this.infoUserList, 'info');
if (this.infoUserList != '') {
this.id = this.infoUserList[0].id
}
}
this.getInfos()
})
},
// 列表
getInfos() {
getRegisterListApi({
store_id: uni.getStorageSync('store_id') || 11001,
patient_id: this.id || '',
page: this.page
}).then((res) => {
// console.log(res, 'info');
if (res.data.code == 0) {
const data = res.data.result
// this.infoList = (data.list).reverse()
this.totalPage = data.pagination.totalPage
this.total = data.pagination.total
if (this.page > 1) {
this.infoList = [...this.infoList, ...data.list]
} else {
this.infoList = data.list
}
}
})
},
},
onPageScroll(e) {
this.scrollTop = e.scrollTop;
},
// 触底触发
onReachBottom() {
if (this.page < this.totalPage) {
this.page += 1
uni.showToast({
title: "加载中",
duration: 700,
mask: false,
icon: 'loading'
})
setTimeout(() => {
this.getInfos();
}, 700)
}
},
onPullDownRefresh() {
// console.log("触发了下拉刷新")
// if (this.page <= 1) return
if (this.page <= 1) {
this.getInfos();
setTimeout(() => {
uni.stopPullDownRefresh()
}, 300)
}
// if (this.page <= 1) return
this.page = 1
this.infoList = []
this.getInfos(() => uni.stopPullDownRefresh())
//重置一下数据
// this.page = 1
// //重新发起请求
// this.getOrder(() => uni.stopPullDownRefresh())
},
mounted() {
},
onShow() {
this.getInfolist();
}
this.bootstrapPatientTabs()
},
}
</script>
<style lang="scss" scoped>
.container {
width: 750rpx;
min-height: 100vh;
max-height: 100%;
height: 100vh;
background-color: #F9FAFB;
padding-top: 32rpx;
display: flex;
flex-direction: column;
padding-bottom: env(safe-area-inset-bottom);
.head {
width: 750rpx;
height: 80rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 42rpx;
position: -webkit-sticky;
background: #F9FAFB;
position: sticky;
top: var(--window-top);
top: 0;
z-index: 99;
margin-bottom: 10rpx;
background-color: #F9FAFB;
font-size: 28rpx;
font-family: PingFang SC-Medium, PingFang SC;
font-weight: 500;
.iconfont {
font-size: 28rpx;
margin-left: 10rpx;
}
}
.empty {
.empty-patient, .empty {
width: 440rpx;
height: 393rpx;
margin: 200rpx auto;
text-align: center;
image {
width: 100%;
height: 100%;
z-index: 10;
}
.word {
margin-top: 10rpx;
image { width: 100%; height: 393rpx; }
.word { color: #94A3B8; margin-top: 20rpx; font-size: 28rpx; }
.add-btn {
margin: 32rpx auto 0;
width: 240rpx;
height: 64rpx;
line-height: 64rpx;
background: #2979FF;
color: #fff;
border-radius: 32rpx;
font-size: 28rpx;
}
}
.list-swiper { flex: 1; height: 0; }
.list-scroll { height: 100%; }
.list {
margin: 0rpx auto 30rpx;
margin: 0 auto 30rpx;
width: 710rpx;
background: #FFFFFF;
border-radius: 8rpx;
padding: 32rpx;
.detail {
width: 648rpx;
display: flex;
justify-content: flex-end;
align-items: center;
text {
width: 160rpx;
height: 58rpx;
line-height: 52rpx;
line-height: 58rpx;
text-align: center;
border-radius: 64rpx;
border: 1rpx solid #999999;
border: 1rpx solid #94A3B8;
font-size: 28rpx;
font-family: PingFang SC-Medium, PingFang SC;
font-weight: 500;
color: #999999;
color: #94A3B8;
}
}
.li_title {
width: 648rpx;
height: 76rpx;
line-height: 66rpx;
font-size: 28rpx;
margin: 0 auto;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #475569;
justify-content: space-between;
border-bottom: 2rpx solid #E2E8F0;
display: flex;
.text {
font-size: 28rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #4175EE;
}
.txt {
font-size: 28rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #FC3636;
}
.text { color: #4175EE; }
.txt { color: #94A3B8; }
}
.info {
width: 628rpx;
width: 648rpx;
display: flex;
align-items: center;
margin: 40rpx auto;
.list_name {
width: 170rpx;
line-height: 40rpx;
font-size: 28rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #94A3B8;
}
text {
width: 466rpx;
font-size: 28rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #1E293B;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
text-overflow: ellipsis;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
}
</style>
</style>

View File

@@ -155,10 +155,29 @@
<text @click="addAller">+添加</text>
</view>
</view>
<!-- 个人病史 -->
<!-- 现病史与病历 present_illness 对齐 -->
<view class="cards_history">
<view class="name">
<text>个人病史</text>
<text>病史</text>
<u-radio-group v-model="present" @change="radioGroupChange" size="44rpx">
<u-radio @change="radioChange" v-for="(item, index) in list" :key="index" :name="item.name"
:disabled="item.disabled" label-size="30rpx">
{{item.name}}
</u-radio>
</u-radio-group>
</view>
<view class="tabs" v-if="present=='有'">
<u-tag :bg-color="rSelectPresent.indexOf(index)!=-1?'#2979FF' :'rgba(41,121,255,0.08)'"
:color="rSelectPresent.indexOf(index)!=-1? '#FFFFFF':'#475569'"
v-for="(item,index) in presentList" :key="index" @tap="tapPresent(index,item)"
:text="item.name" mode="dark" />
<text @click="addPresent">+添加</text>
</view>
</view>
<!-- 既往史个人病史与病历 past_history 对齐 -->
<view class="cards_history">
<view class="name">
<text>既往史</text>
<u-radio-group v-model="person" @change="radioGroupChange" size="44rpx">
<u-radio @change="radioChange" v-for="(item, index) in list" :key="index" :name="item.name"
:disabled="item.disabled" label-size="30rpx">
@@ -173,15 +192,15 @@
<text @click="addPer">+添加</text>
</view>
</view>
<!-- 家族 -->
<!-- 家族史 -->
<view class="cards_history">
<view class="name">
<text>家族</text>
<text>家族史</text>
<u-radio-group v-model="family" @change="radioGroupChange" size="44rpx">
<d-radio @change="radioChange" v-for="(item, index) in list" :key="index" :name="item.name"
<u-radio @change="radioChange" v-for="(item, index) in list" :key="index" :name="item.name"
:disabled="item.disabled" label-size="30rpx">
{{item.name}}
</d-radio>
</u-radio>
</u-radio-group>
</view>
<view class="tabs" v-if="family=='有'">
@@ -191,6 +210,82 @@
<text @click="addFmaily">+添加</text>
</view>
</view>
<!-- 流行病学史 -->
<view class="cards_history">
<view class="name">
<text>流行病学史</text>
<u-radio-group v-model="epidemic" @change="radioGroupChange" size="44rpx">
<u-radio @change="radioChange" v-for="(item, index) in list" :key="index" :name="item.name"
:disabled="item.disabled" label-size="30rpx">
{{item.name}}
</u-radio>
</u-radio-group>
</view>
<view class="tabs" v-if="epidemic=='有'">
<u-tag :bg-color="rSelectEpidemic.indexOf(index)!=-1?'#2979FF' :'rgba(41,121,255,0.08)'"
:color="rSelectEpidemic.indexOf(index)!=-1? '#FFFFFF':'#475569'"
v-for="(item,index) in epidemicList" :key="index" @tap="tapEpidemic(index,item)"
:text="item.name" mode="dark" />
<text @click="addEpidemic">+添加</text>
</view>
</view>
<!-- 个人史 -->
<view class="cards_history">
<view class="name">
<text>个人史</text>
<u-radio-group v-model="personal" @change="radioGroupChange" size="44rpx">
<u-radio @change="radioChange" v-for="(item, index) in list" :key="index" :name="item.name"
:disabled="item.disabled" label-size="30rpx">
{{item.name}}
</u-radio>
</u-radio-group>
</view>
<view class="tabs" v-if="personal=='有'">
<u-tag :bg-color="rSelectPersonal.indexOf(index)!=-1?'#2979FF' :'rgba(41,121,255,0.08)'"
:color="rSelectPersonal.indexOf(index)!=-1? '#FFFFFF':'#475569'"
v-for="(item,index) in personalList" :key="index" @tap="tapPersonal(index,item)"
:text="item.name" mode="dark" />
<text @click="addPersonal">+添加</text>
</view>
</view>
<!-- 月经史仅女性 -->
<view class="cards_history" v-if="showMenstrualHistory">
<view class="name">
<text>月经史</text>
<u-radio-group v-model="menstrual" @change="radioGroupChange" size="44rpx">
<u-radio @change="radioChange" v-for="(item, index) in list" :key="index" :name="item.name"
:disabled="item.disabled" label-size="30rpx">
{{item.name}}
</u-radio>
</u-radio-group>
</view>
<view class="tabs" v-if="menstrual=='有'">
<u-tag :bg-color="rSelectMenstrual.indexOf(index)!=-1?'#2979FF' :'rgba(41,121,255,0.08)'"
:color="rSelectMenstrual.indexOf(index)!=-1? '#FFFFFF':'#475569'"
v-for="(item,index) in menstrualList" :key="index" @tap="tapMenstrual(index,item)"
:text="item.name" mode="dark" />
<text @click="addMenstrual">+添加</text>
</view>
</view>
<!-- 婚育史>22 >20 -->
<view class="cards_history" v-if="showMaritalHistory">
<view class="name">
<text>婚育史</text>
<u-radio-group v-model="marital" @change="radioGroupChange" size="44rpx">
<u-radio @change="radioChange" v-for="(item, index) in list" :key="index" :name="item.name"
:disabled="item.disabled" label-size="30rpx">
{{item.name}}
</u-radio>
</u-radio-group>
</view>
<view class="tabs" v-if="marital=='有'">
<u-tag :bg-color="rSelectMarital.indexOf(index)!=-1?'#2979FF' :'rgba(41,121,255,0.08)'"
:color="rSelectMarital.indexOf(index)!=-1? '#FFFFFF':'#475569'"
v-for="(item,index) in maritalList" :key="index" @tap="tapMarital(index,item)"
:text="item.name" mode="dark" />
<text @click="addMarital">+添加</text>
</view>
</view>
</view>
<view class="floors">
@@ -356,7 +451,7 @@
name: '阿司匹林'
}
],
person: "无", // 个人病
person: "无", // 既往
personList: [{
name: '先天性心脏病'
},
@@ -379,7 +474,7 @@
name: '哮喘'
}
],
family: "无", // 家庭病
family: "无", // 家
familyList: [{
name: '高血压'
},
@@ -411,12 +506,84 @@
name: '结核病'
}
],
// 以下与病历字段对齐,默认「无」,挂号时写入病历
present: "无",
presentList: [{
name: '起病急'
},
{
name: '病程迁延'
},
{
name: '反复发作'
},
{
name: '自行用药'
},
{
name: '症状加重'
}
],
epidemic: "无",
epidemicList: [{
name: '疫区旅居'
},
{
name: '确诊病例接触'
},
{
name: '发热病例接触'
}
],
personal: "无",
personalList: [{
name: '吸烟'
},
{
name: '饮酒'
},
{
name: '熬夜'
}
],
menstrual: "无",
menstrualList: [{
name: '月经规律'
},
{
name: '痛经'
},
{
name: '月经不调'
}
],
marital: "无",
maritalList: [{
name: '未婚'
},
{
name: '已婚'
},
{
name: '已育'
}
],
rSelect: [],
rSelects: [],
rSelec: [],
rSelectPresent: [],
rSelectEpidemic: [],
rSelectPersonal: [],
rSelectMenstrual: [],
rSelectMarital: [],
allergic_history: [],
person_history: [],
family_history: [],
present_history: [],
epidemic_history: [],
personal_history: [],
menstrual_history: [],
marital_history: [],
// 内容安全 baseline新增页为空对象仅提交变动字段
_securityBaseline: {},
is_default: 0,
@@ -440,6 +607,17 @@
const age = Number(this.form.age);
return this.form.age !== '' && !isNaN(age) && age <= 6;
},
// 月经史仅女性展示(与病历面板规则一致)
showMenstrualHistory() {
return this.form.sex == '女' || this.form.sex == '2' || this.form.sex == 2;
},
// 婚育史:男>22 或 女>20
showMaritalHistory() {
const age = Number(this.form.age) || 0;
const isMale = this.form.sex == '男' || this.form.sex == '1' || this.form.sex == 1;
const isFemale = this.form.sex == '女' || this.form.sex == '2' || this.form.sex == 2;
return (isMale && age > 22) || (isFemale && age > 20);
},
guardianPickerList() {
const currentId = Number(this.addid) || 0;
return this.patientList
@@ -689,8 +867,13 @@
name: this.names,
visitDesc: this.visitDesc,
allergic_history: this.allergic_history,
present_history: this.present_history,
person_history: this.person_history,
family_history: this.family_history,
epidemic_history: this.epidemic_history,
personal_history: this.personal_history,
menstrual_history: this.menstrual_history,
marital_history: this.marital_history,
}, this._securityBaseline, SCENE_PROFILE);
} catch (e) {
handleSecurityError(e);
@@ -710,11 +893,21 @@
liver_function: this.liver == '正常' ? '0' : '1',
renal_function: this.renal == '正常' ? '0' : '1',
allergic_status: this.allergic == '无' ? '0' : '1',
present_status: this.present == '无' ? '0' : '1',
person_status: this.person == '无' ? '0' : '1',
family_status: this.family == '无' ? '0' : '1',
epidemic_status: this.epidemic == '无' ? '0' : '1',
personal_status: this.personal == '无' ? '0' : '1',
menstrual_status: (!this.showMenstrualHistory || this.menstrual == '无') ? '0' : '1',
marital_status: (!this.showMaritalHistory || this.marital == '无') ? '0' : '1',
allergic_history: this.allergic_history,
present_history: this.present_history,
person_history: this.person_history,
family_history: this.family_history,
epidemic_history: this.epidemic_history,
personal_history: this.personal_history,
menstrual_history: this.showMenstrualHistory ? this.menstrual_history : [],
marital_history: this.showMaritalHistory ? this.marital_history : [],
});
userAdd({
method: "post",
@@ -751,76 +944,96 @@
this.show = true
this.addNum = 1
},
// 个人病
// 既往
addPer() {
this.show = true
this.addNum = 2
},
// 家庭病
// 家
addFmaily() {
this.show = true
this.addNum = 3
},
// 添加病情
addEpidemic() {
this.show = true
this.addNum = 4
},
addPersonal() {
this.show = true
this.addNum = 5
},
addMenstrual() {
this.show = true
this.addNum = 6
},
addMarital() {
this.show = true
this.addNum = 7
},
// 现病史自定义标签
addPresent() {
this.show = true
this.addNum = 8
},
// 添加自定义史标签
addTag() {
this.show = false
if (this.addNum == 3 && this.addtext != "") {
let obj = {
name: this.addtext
}
this.$set(this.familyList.push(obj))
this.addtext = ""
} else if (this.addNum == 1 && this.addtext != "") {
let obj = {
name: this.addtext
}
this.$set(this.allergicList.push(obj))
this.addtext = ""
} else if (this.addNum == 2 && this.addtext != "") {
let obj = {
name: this.addtext
}
this.$set(this.personList.push(obj))
this.addtext = ""
if (this.addtext == "") {
return
}
const obj = { name: this.addtext }
if (this.addNum == 3) {
this.familyList.push(obj)
} else if (this.addNum == 1) {
this.allergicList.push(obj)
} else if (this.addNum == 2) {
this.personList.push(obj)
} else if (this.addNum == 4) {
this.epidemicList.push(obj)
} else if (this.addNum == 5) {
this.personalList.push(obj)
} else if (this.addNum == 6) {
this.menstrualList.push(obj)
} else if (this.addNum == 7) {
this.maritalList.push(obj)
} else if (this.addNum == 8) {
this.presentList.push(obj)
}
this.addtext = ""
},
// 过敏史
// 切换史标签选中(通用)
toggleHistoryTag(selectKey, historyKey, index, item) {
if (this[selectKey].indexOf(index) == -1) {
this[selectKey].push(index)
this[historyKey].push(item.name)
} else {
this[selectKey].splice(this[selectKey].indexOf(index), 1)
this[historyKey].splice(this[historyKey].indexOf(item.name), 1)
}
},
tapInfo(e, item) {
// console.log(item);
if (this.rSelect.indexOf(e) == -1) {
// console.log(e) //打印下标
this.rSelect.push(e); //选中添加到数组里
this.allergic_history.push(item.name)
} else {
this.rSelect.splice(this.rSelect.indexOf(e), 1); //取消
this.allergic_history.splice(this.allergic_history.indexOf(item.name), 1)
}
this.toggleHistoryTag('rSelect', 'allergic_history', e, item)
},
// 个人病史
tapInfos(e, item) {
if (this.rSelects.indexOf(e) == -1) {
// console.log(e) //打印下标
this.rSelects.push(e); //选中添加到数组里
this.person_history.push(item.name)
} else {
this.rSelects.splice(this.rSelects.indexOf(e), 1); //取消
this.person_history.splice(this.person_history.indexOf(item.name), 1)
}
this.toggleHistoryTag('rSelects', 'person_history', e, item)
},
// 家庭病史
taps(e, item) {
if (this.rSelec.indexOf(e) == -1) {
// console.log(e) //打印下标
this.rSelec.push(e); //选中添加到数组里
this.family_history.push(item.name)
} else {
this.rSelec.splice(this.rSelec.indexOf(e), 1); //取消
this.family_history.splice(this.family_history.indexOf(item.name), 1)
}
this.toggleHistoryTag('rSelec', 'family_history', e, item)
},
tapEpidemic(e, item) {
this.toggleHistoryTag('rSelectEpidemic', 'epidemic_history', e, item)
},
tapPersonal(e, item) {
this.toggleHistoryTag('rSelectPersonal', 'personal_history', e, item)
},
tapMenstrual(e, item) {
this.toggleHistoryTag('rSelectMenstrual', 'menstrual_history', e, item)
},
tapMarital(e, item) {
this.toggleHistoryTag('rSelectMarital', 'marital_history', e, item)
},
tapPresent(e, item) {
this.toggleHistoryTag('rSelectPresent', 'present_history', e, item)
},
// 身份证号码

View File

@@ -144,10 +144,29 @@
<text @click="addAller">+添加</text>
</view>
</view>
<!-- 个人病史 -->
<!-- 现病史与病历 present_illness 对齐 -->
<view class="cards_history">
<view class="name">
<text>个人病史</text>
<text>病史</text>
<u-radio-group v-model="present" @change="radioGroupChange" size="44rpx">
<u-radio @change="radioChange" v-for="(item, index) in list" :key="index" :name="item.name"
:disabled="item.disabled" label-size="30rpx">
{{item.name}}
</u-radio>
</u-radio-group>
</view>
<view class="tabs" v-if="present=='有'">
<u-tag :bg-color="rSelectPresent.indexOf(index)!=-1?'#2979FF' :'rgba(41,121,255,0.08)'"
:color="rSelectPresent.indexOf(index)!=-1? '#FFFFFF':'#475569'"
v-for="(item,index) in presentList" :key="index" @tap="tapPresent(index,item)"
:text="item.name" mode="dark" />
<text @click="addPresent">+添加</text>
</view>
</view>
<!-- 既往史 -->
<view class="cards_history">
<view class="name">
<text>既往史</text>
<u-radio-group v-model="person" @change="radioGroupChange" size="44rpx">
<u-radio @change="radioChange" v-for="(item, index) in list" :key="index" :name="item.name"
:disabled="item.disabled" label-size="30rpx">
@@ -162,15 +181,15 @@
<text @click="addPer">+添加</text>
</view>
</view>
<!-- 家族 -->
<!-- 家族史 -->
<view class="cards_history">
<view class="name">
<text>家族</text>
<text>家族史</text>
<u-radio-group v-model="family" @change="radioGroupChange" size="44rpx">
<d-radio @change="radioChange" v-for="(item, index) in list" :key="index" :name="item.name"
<u-radio @change="radioChange" v-for="(item, index) in list" :key="index" :name="item.name"
:disabled="item.disabled" label-size="30rpx">
{{item.name}}
</d-radio>
</u-radio>
</u-radio-group>
</view>
<view class="tabs" v-if="family=='有'">
@@ -180,6 +199,82 @@
<text @click="addFmaily">+添加</text>
</view>
</view>
<!-- 流行病学史 -->
<view class="cards_history">
<view class="name">
<text>流行病学史</text>
<u-radio-group v-model="epidemic" @change="radioGroupChange" size="44rpx">
<u-radio @change="radioChange" v-for="(item, index) in list" :key="index" :name="item.name"
:disabled="item.disabled" label-size="30rpx">
{{item.name}}
</u-radio>
</u-radio-group>
</view>
<view class="tabs" v-if="epidemic=='有'">
<u-tag :bg-color="rSelectEpidemic.indexOf(index)!=-1?'#2979FF' :'rgba(41,121,255,0.08)'"
:color="rSelectEpidemic.indexOf(index)!=-1? '#FFFFFF':'#475569'"
v-for="(item,index) in epidemicList" :key="index" @tap="tapEpidemic(index,item)"
:text="item.name" mode="dark" />
<text @click="addEpidemic">+添加</text>
</view>
</view>
<!-- 个人史 -->
<view class="cards_history">
<view class="name">
<text>个人史</text>
<u-radio-group v-model="personal" @change="radioGroupChange" size="44rpx">
<u-radio @change="radioChange" v-for="(item, index) in list" :key="index" :name="item.name"
:disabled="item.disabled" label-size="30rpx">
{{item.name}}
</u-radio>
</u-radio-group>
</view>
<view class="tabs" v-if="personal=='有'">
<u-tag :bg-color="rSelectPersonal.indexOf(index)!=-1?'#2979FF' :'rgba(41,121,255,0.08)'"
:color="rSelectPersonal.indexOf(index)!=-1? '#FFFFFF':'#475569'"
v-for="(item,index) in personalList" :key="index" @tap="tapPersonal(index,item)"
:text="item.name" mode="dark" />
<text @click="addPersonal">+添加</text>
</view>
</view>
<!-- 月经史仅女性 -->
<view class="cards_history" v-if="showMenstrualHistory">
<view class="name">
<text>月经史</text>
<u-radio-group v-model="menstrual" @change="radioGroupChange" size="44rpx">
<u-radio @change="radioChange" v-for="(item, index) in list" :key="index" :name="item.name"
:disabled="item.disabled" label-size="30rpx">
{{item.name}}
</u-radio>
</u-radio-group>
</view>
<view class="tabs" v-if="menstrual=='有'">
<u-tag :bg-color="rSelectMenstrual.indexOf(index)!=-1?'#2979FF' :'rgba(41,121,255,0.08)'"
:color="rSelectMenstrual.indexOf(index)!=-1? '#FFFFFF':'#475569'"
v-for="(item,index) in menstrualList" :key="index" @tap="tapMenstrual(index,item)"
:text="item.name" mode="dark" />
<text @click="addMenstrual">+添加</text>
</view>
</view>
<!-- 婚育史 -->
<view class="cards_history" v-if="showMaritalHistory">
<view class="name">
<text>婚育史</text>
<u-radio-group v-model="marital" @change="radioGroupChange" size="44rpx">
<u-radio @change="radioChange" v-for="(item, index) in list" :key="index" :name="item.name"
:disabled="item.disabled" label-size="30rpx">
{{item.name}}
</u-radio>
</u-radio-group>
</view>
<view class="tabs" v-if="marital=='有'">
<u-tag :bg-color="rSelectMarital.indexOf(index)!=-1?'#2979FF' :'rgba(41,121,255,0.08)'"
:color="rSelectMarital.indexOf(index)!=-1? '#FFFFFF':'#475569'"
v-for="(item,index) in maritalList" :key="index" @tap="tapMarital(index,item)"
:text="item.name" mode="dark" />
<text @click="addMarital">+添加</text>
</view>
</view>
</view>
<view class="floors">
@@ -334,7 +429,7 @@
name: '阿司匹林'
}
],
person: "无", // 个人病
person: "无", // 既往
personList: [{
name: '先天性心脏病'
},
@@ -357,7 +452,7 @@
name: '哮喘'
}
],
family: "无", // 家庭病
family: "无", // 家
familyList: [{
name: '高血压'
},
@@ -389,12 +484,83 @@
name: '结核病'
}
],
present: "无",
presentList: [{
name: '起病急'
},
{
name: '病程迁延'
},
{
name: '反复发作'
},
{
name: '自行用药'
},
{
name: '症状加重'
}
],
epidemic: "无",
epidemicList: [{
name: '疫区旅居'
},
{
name: '确诊病例接触'
},
{
name: '发热病例接触'
}
],
personal: "无",
personalList: [{
name: '吸烟'
},
{
name: '饮酒'
},
{
name: '熬夜'
}
],
menstrual: "无",
menstrualList: [{
name: '月经规律'
},
{
name: '痛经'
},
{
name: '月经不调'
}
],
marital: "无",
maritalList: [{
name: '未婚'
},
{
name: '已婚'
},
{
name: '已育'
}
],
rSelect: [],
rSelects: [],
rSelec: [],
rSelectPresent: [],
rSelectEpidemic: [],
rSelectPersonal: [],
rSelectMenstrual: [],
rSelectMarital: [],
allergic_history: [],
person_history: [],
family_history: [],
present_history: [],
epidemic_history: [],
personal_history: [],
menstrual_history: [],
marital_history: [],
// 内容安全 baseline详情加载完成后快照
_securityBaseline: {},
heathList: [], // 健康信息
@@ -418,6 +584,15 @@
const age = Number(this.form.age);
return this.form.age !== '' && !isNaN(age) && age <= 6;
},
showMenstrualHistory() {
return this.form.sex == '女' || this.form.sex == '2' || this.form.sex == 2;
},
showMaritalHistory() {
const age = Number(this.form.age) || 0;
const isMale = this.form.sex == '男' || this.form.sex == '1' || this.form.sex == 1;
const isFemale = this.form.sex == '女' || this.form.sex == '2' || this.form.sex == 2;
return (isMale && age > 22) || (isFemale && age > 20);
},
guardianPickerList() {
const currentId = Number(this.addid) || 0;
return this.allPatientList
@@ -480,83 +655,131 @@
// console.log(this.family, 'is');
},
// 过敏史
addAller() {
this.addtext = ''
this.addtext = ''
this.show = true
this.addNum = 1
},
// 个人病史
addPer() {
this.addtext = ''
this.addtext = ''
this.show = true
this.addNum = 2
},
// 家庭病史
addFmaily() {
this.addtext = ''
this.addtext = ''
this.show = true
this.addNum = 3
},
// 添加病情
addEpidemic() {
this.addtext = ''
this.show = true
this.addNum = 4
},
addPersonal() {
this.addtext = ''
this.show = true
this.addNum = 5
},
addMenstrual() {
this.addtext = ''
this.show = true
this.addNum = 6
},
addMarital() {
this.addtext = ''
this.show = true
this.addNum = 7
},
addPresent() {
this.addtext = ''
this.show = true
this.addNum = 8
},
// 添加自定义史标签
addTag() {
this.show = false
if (this.addNum == 3 && this.addtext != "") {
let obj = {
name: this.addtext
}
this.$set(this.familyList.push(obj))
} else if (this.addNum == 1 && this.addtext != "") {
let obj = {
name: this.addtext
}
this.$set(this.allergicList.push(obj))
} else if (this.addNum == 2 && this.addtext != "") {
let obj = {
name: this.addtext
}
this.$set(this.personList.push(obj))
if (this.addtext == "") {
return
}
const obj = { name: this.addtext }
if (this.addNum == 3) {
this.familyList.push(obj)
} else if (this.addNum == 1) {
this.allergicList.push(obj)
} else if (this.addNum == 2) {
this.personList.push(obj)
} else if (this.addNum == 4) {
this.epidemicList.push(obj)
} else if (this.addNum == 5) {
this.personalList.push(obj)
} else if (this.addNum == 6) {
this.menstrualList.push(obj)
} else if (this.addNum == 7) {
this.maritalList.push(obj)
} else if (this.addNum == 8) {
this.presentList.push(obj)
}
this.addtext = ""
},
toggleHistoryTag(selectKey, historyKey, index, item) {
if (this[selectKey].indexOf(index) == -1) {
this[selectKey].push(index)
this[historyKey].push(item.name)
} else {
this[selectKey].splice(this[selectKey].indexOf(index), 1)
this[historyKey].splice(this[historyKey].indexOf(item.name), 1)
}
this.addtext = ""
},
// 过敏史
tapInfo(e, item) {
if (this.rSelect.indexOf(e) == -1) {
// console.log(e) //打印下标
this.rSelect.push(e); //选中添加到数组里
this.allergic_history.push(item.name)
} else {
this.rSelect.splice(this.rSelect.indexOf(e), 1); //取消
this.allergic_history.splice(this.allergic_history.indexOf(item.name), 1)
}
this.toggleHistoryTag('rSelect', 'allergic_history', e, item)
},
// 个人病史
tapInfos(e, item) {
console.log(e, item, 'daaaaaaaaaaaaaaaaaaa')
// 如果当前选项不在已选中项的数组中
if (this.rSelects.indexOf(e) == -1) {
// console.log(e) // 打印当前选项的下标
this.rSelects.push(e); // 将选中的选项添加到数组中
this.person_history.push(item.name); // 同时将选项的名称添加到历史记录中
} else {
// 如果当前选项已经在已选中项的数组中,则移除它
this.rSelects.splice(this.rSelects.indexOf(e), 1); // 取消选中
// 同时从历史记录中移除该选项的名称
this.person_history.splice(this.person_history.indexOf(item.name), 1);
}
this.toggleHistoryTag('rSelects', 'person_history', e, item)
},
// 家庭病史
taps(e, item) {
if (this.rSelec.indexOf(e) == -1) {
// console.log(e) //打印下标
this.rSelec.push(e); //选中添加到数组里
this.family_history.push(item.name)
} else {
this.rSelec.splice(this.rSelec.indexOf(e), 1); //取消
this.family_history.splice(this.family_history.indexOf(item.name), 1)
}
this.toggleHistoryTag('rSelec', 'family_history', e, item)
},
tapEpidemic(e, item) {
this.toggleHistoryTag('rSelectEpidemic', 'epidemic_history', e, item)
},
tapPersonal(e, item) {
this.toggleHistoryTag('rSelectPersonal', 'personal_history', e, item)
},
tapMenstrual(e, item) {
this.toggleHistoryTag('rSelectMenstrual', 'menstrual_history', e, item)
},
tapMarital(e, item) {
this.toggleHistoryTag('rSelectMarital', 'marital_history', e, item)
},
tapPresent(e, item) {
this.toggleHistoryTag('rSelectPresent', 'present_history', e, item)
},
/**
* 回显史标签:已有选项勾选;自定义项追加到列表并勾选
*/
applyHistoryEcho(listKey, selectKey, historyKey, names) {
const that = this
const arr = Array.isArray(names) ? names : []
arr.forEach(function (name) {
if (!name) {
return
}
let idx = that[listKey].findIndex(function (it) {
return it.name == name
})
if (idx < 0) {
that[listKey].push({ name: name, checked: true })
idx = that[listKey].length - 1
} else {
that.$set(that[listKey][idx], 'checked', true)
}
if (that[selectKey].indexOf(idx) == -1) {
that[selectKey].push(idx)
}
if (that[historyKey].indexOf(name) == -1) {
that[historyKey].push(name)
}
})
},
// 身份证号码
@@ -829,8 +1052,13 @@
name: this.names,
visitDesc: this.visitDesc,
allergic_history: this.allergic_history,
present_history: this.present_history,
person_history: this.person_history,
family_history: this.family_history,
epidemic_history: this.epidemic_history,
personal_history: this.personal_history,
menstrual_history: this.menstrual_history,
marital_history: this.marital_history,
}, this._securityBaseline, SCENE_PROFILE);
} catch (e) {
handleSecurityError(e);
@@ -849,11 +1077,21 @@
liver_function: this.liver == '正常' ? '0' : '1',
renal_function: this.renal == '正常' ? '0' : '1',
allergic_status: this.allergic == '无' ? '0' : '1',
present_status: this.present == '无' ? '0' : '1',
person_status: this.person == '无' ? '0' : '1',
family_status: this.family == '无' ? '0' : '1',
epidemic_status: this.epidemic == '无' ? '0' : '1',
personal_status: this.personal == '无' ? '0' : '1',
menstrual_status: (!this.showMenstrualHistory || this.menstrual == '无') ? '0' : '1',
marital_status: (!this.showMaritalHistory || this.marital == '无') ? '0' : '1',
allergic_history: this.allergic_history,
present_history: this.present_history,
person_history: this.person_history,
family_history: this.family_history,
epidemic_history: this.epidemic_history,
personal_history: this.personal_history,
menstrual_history: this.showMenstrualHistory ? this.menstrual_history : [],
marital_history: this.showMaritalHistory ? this.marital_history : [],
});
userAdd({
method: "post",
@@ -898,49 +1136,40 @@
// console.log(res, 'heath');
if (res.data.errcode == 0) {
this.heathList = res.data.data
this.liver = (this.heathList.liver_function) % 2 == 0 ? '正常' : '异常'
this.renal = (this.heathList.renal_function) % 2 == 0 ? '正常' : '异常'
this.allergic = (this.heathList.allergic_status) % 2 == 0 ? '无' : '有'
this.allergicList = (this.heathList.allergic_history) == 'Array' ? [] : (this.heathList
.allergic_history).map(function (item, index) {
console.log(index, 'sssssssssssssssssssssssssss')
that.tapInfo(index, {
name: item,
checked: true
})
return {
name: item,
checked: true
}
})
this.person = (this.heathList.person_status) % 2 == 0 ? '无' : '有'
this.personList = (this.heathList.person_history != '') == 'Array' ? [] : (this.heathList
.person_history).map(function (item, index) {
that.tapInfos(index, {
name: item,
checked: true
})
return {
name: item,
checked: true
}
})
this.family = (this.heathList.family_status) % 2 == 0 ? '无' : '有'
this.familyList = (this.heathList.family_history != '') == 'Array' ? [] : (this.heathList
.family_history).map(function (item, index) {
that.taps(index, {
name: item,
checked: true
})
return {
name: item,
checked: true
}
})
this.present = (this.heathList.present_status || 0) % 2 == 0 ? '无' : '有'
this.epidemic = (this.heathList.epidemic_status || 0) % 2 == 0 ? '无' : '有'
this.personal = (this.heathList.personal_status || 0) % 2 == 0 ? '无' : '有'
this.menstrual = (this.heathList.menstrual_status || 0) % 2 == 0 ? '无' : '有'
this.marital = (this.heathList.marital_status || 0) % 2 == 0 ? '无' : '有'
this.rSelect = []
this.rSelects = []
this.rSelec = []
this.rSelectPresent = []
this.rSelectEpidemic = []
this.rSelectPersonal = []
this.rSelectMenstrual = []
this.rSelectMarital = []
this.allergic_history = []
this.present_history = []
this.person_history = []
this.family_history = []
this.epidemic_history = []
this.personal_history = []
this.menstrual_history = []
this.marital_history = []
that.applyHistoryEcho('allergicList', 'rSelect', 'allergic_history', this.heathList.allergic_history)
that.applyHistoryEcho('presentList', 'rSelectPresent', 'present_history', this.heathList.present_history)
that.applyHistoryEcho('personList', 'rSelects', 'person_history', this.heathList.person_history)
that.applyHistoryEcho('familyList', 'rSelec', 'family_history', this.heathList.family_history)
that.applyHistoryEcho('epidemicList', 'rSelectEpidemic', 'epidemic_history', this.heathList.epidemic_history)
that.applyHistoryEcho('personalList', 'rSelectPersonal', 'personal_history', this.heathList.personal_history)
that.applyHistoryEcho('menstrualList', 'rSelectMenstrual', 'menstrual_history', this.heathList.menstrual_history)
that.applyHistoryEcho('maritalList', 'rSelectMarital', 'marital_history', this.heathList.marital_history)
}
this.updateSecurityBaseline()
})
@@ -951,8 +1180,13 @@
name: this.names,
visitDesc: this.visitDesc,
allergic_history: [...(this.allergic_history || [])],
present_history: [...(this.present_history || [])],
person_history: [...(this.person_history || [])],
family_history: [...(this.family_history || [])],
epidemic_history: [...(this.epidemic_history || [])],
personal_history: [...(this.personal_history || [])],
menstrual_history: [...(this.menstrual_history || [])],
marital_history: [...(this.marital_history || [])],
};
}
},

View File

@@ -0,0 +1,188 @@
<template>
<!-- 我的病历详情双列预览网格对齐 AI 病历预览 -->
<view class="container safe-area-inset-bottom">
<view class="wrap" v-if="detail.id">
<view class="meta">
<text>{{detail.created_at || ''}}</text>
<text class="store">{{detail.store_name || ''}}</text>
</view>
<view class="patient-box">
<text class="mr-lab">患者</text>
<text class="mr-val">{{detail.patient_name}} {{ sexText }} {{ ageText }}</text>
</view>
<view class="patient-box">
<text class="mr-lab">医生</text>
<text class="mr-val">{{detail.doctor_name || '—'}}</text>
</view>
<view v-if="detail.chief_complaint" class="patient-box">
<text class="mr-lab">主诉</text>
<text class="mr-val">{{detail.chief_complaint}}</text>
</view>
<view class="ai-preview-grid">
<view
v-for="row in previewRows"
:key="row.key"
class="ai-preview-card"
:class="{ 'ai-preview-card--full': row.full }"
>
<text class="mr-lab">{{row.label}}</text>
<text class="mr-val">{{row.value}}</text>
</view>
</view>
</view>
<view class="empty" v-else>
<text>{{loading ? '加载中…' : '暂无病历'}}</text>
</view>
</view>
</template>
<script>
import { getMedicalRecordDetailApi } from '../../request/api/medicalRecord'
import { unwrapXkApi } from '@/utils/api-response.js'
const PREVIEW_DEFS = [
{ key: 'present_illness', label: '现病史', full: true },
{ key: 'tongue', label: '舌象', full: false },
{ key: 'pulse', label: '脉象', full: false },
{ key: 'tcm_case', label: '中医病案', full: true },
{ key: 'tcm_syndrome', label: '中医证候', full: false },
{ key: 'tcm_disease', label: '中医疾病', full: false },
{ key: 'tcm_method', label: '中医治法', full: false },
{ key: 'diagnosis', label: '临床诊断', full: true },
{ key: 'treatment_advice', label: '治疗意见', full: true },
{ key: 'doctor_order', label: '医嘱', full: true },
{ key: 'past_history', label: '既往史', full: false },
{ key: 'allergy_history', label: '过敏史', full: false },
{ key: 'family_history', label: '家族史', full: false },
{ key: 'epidemic_history', label: '流行病学史', full: false },
{ key: 'personal_history', label: '个人史', full: false },
{ key: 'menstrual_history', label: '月经史', full: false },
{ key: 'marital_history', label: '婚育史', full: false },
{ key: 'physical_exam', label: '体征检查', full: false },
{ key: 'auxiliary_exam', label: '辅助检查', full: true },
]
export default {
data() {
return {
id: 0,
detail: {},
loading: true,
}
},
computed: {
sexText() {
const s = Number(this.detail.patient_sex)
if (s === 1) return '男'
if (s === 2) return '女'
return ''
},
ageText() {
const a = Number(this.detail.patient_age) || 0
return a > 0 ? (a + '岁') : ''
},
previewRows() {
const d = this.detail || {}
const rows = []
for (let i = 0; i < PREVIEW_DEFS.length; i++) {
const def = PREVIEW_DEFS[i]
const v = d[def.key] != null ? String(d[def.key]).trim() : ''
if (!v) {
continue
}
rows.push({ key: def.key, label: def.label, value: v, full: def.full })
}
return rows
},
},
onLoad(e) {
this.id = Number(e.id) || 0
this.loadDetail()
},
methods: {
loadDetail() {
if (!this.id) {
this.loading = false
return
}
this.loading = true
getMedicalRecordDetailApi({ id: this.id }).then((res) => {
const { ok, payload, message } = unwrapXkApi(res)
this.loading = false
if (ok && payload) {
this.detail = payload
} else {
uni.showToast({ title: message || '加载失败', icon: 'none' })
}
}).catch(() => {
this.loading = false
})
},
},
}
</script>
<style lang="scss" scoped>
.container {
min-height: 100vh;
background: #F1F5F9;
padding: 20rpx;
padding-bottom: env(safe-area-inset-bottom);
}
.wrap {
background: #F8FAFC;
border-radius: 16rpx;
padding: 24rpx;
}
.meta {
display: flex;
justify-content: space-between;
color: #64748B;
font-size: 24rpx;
margin-bottom: 16rpx;
.store { color: #2979FF; }
}
.patient-box {
padding: 12rpx 16rpx;
background: #fff;
border-radius: 10rpx;
margin-bottom: 12rpx;
display: flex;
flex-direction: column;
}
.ai-preview-grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: 0 -6rpx;
}
.ai-preview-card {
width: calc(50% - 12rpx);
margin: 0 6rpx 12rpx;
padding: 12rpx 16rpx;
background: #fff;
border-radius: 10rpx;
display: flex;
flex-direction: column;
box-sizing: border-box;
}
.ai-preview-card--full {
width: calc(100% - 12rpx);
}
.mr-lab {
font-size: 20rpx;
color: #94A3B8;
}
.mr-val {
font-size: 26rpx;
color: #0F172A;
margin-top: 4rpx;
white-space: pre-wrap;
word-break: break-all;
}
.empty {
text-align: center;
margin-top: 200rpx;
color: #94A3B8;
}
</style>

View File

@@ -0,0 +1,218 @@
<template>
<!-- 我的病历就诊人 Tab + 预览网格卡片对齐 AI 病历预览 -->
<view class="container safe-area-inset-bottom">
<MessageNotification />
<view class="head" v-if="patientTabs.length > 0">
<u-tabs :list="patientTabs" :is-scroll="true" :current="current" @change="onTabChange"></u-tabs>
</view>
<view class="empty-patient" v-if="emptyPatient">
<image src="https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk-client-wx/static/empty/orders.png" mode="aspectFit"></image>
<view class="word">暂无就诊人请先添加</view>
<view class="add-btn" @click="goAddPatient">添加就诊人</view>
</view>
<swiper v-else class="list-swiper" :current="current" @change="onSwiperChange">
<swiper-item v-for="(tab, tabIdx) in patientTabs" :key="tabIdx">
<scroll-view
scroll-y
class="list-scroll"
@scrolltolower="onOrderScrollToLower"
refresher-enabled="true"
:refresher-triggered="isRefreshing"
@refresherrefresh="onRefresherRefresh"
>
<block v-if="Number(current) === tabIdx">
<view class="empty" v-if="infoList.length==0">
<image src="https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk-client-wx/static/empty/orders.png" mode="aspectFit"></image>
<view class="word">暂无病历记录~</view>
</view>
<view class="mr-card" v-for="(item,index) in infoList" :key="item.id" @click="goDetail(item.id)">
<view class="mr-card-hd">
<text class="mr-time">{{item.created_at || ''}}</text>
<text class="mr-store">{{item.store_name || '病历'}}</text>
</view>
<view class="mr-patient-line">
<text>{{item.doctor_name || '医生未填'}}</text>
</view>
<view v-if="item.chief_complaint" class="mr-chief">
<text class="mr-lab">主诉</text>
<text class="mr-val">{{item.chief_complaint}}</text>
</view>
<view class="ai-preview-grid">
<view
v-for="row in cardPreviewRows(item)"
:key="row.key"
class="ai-preview-card"
:class="{ 'ai-preview-card--full': row.full }"
>
<text class="mr-lab">{{row.label}}</text>
<text class="mr-val">{{row.value}}</text>
</view>
</view>
<view class="mr-foot">
<text>查看详情</text>
</view>
</view>
<u-loadmore :status="loadMoreStatus" v-if="infoList.length!=0" margin-top="30" margin-bottom="30" />
</block>
</scroll-view>
</swiper-item>
</swiper>
<u-toast ref="uToast" />
</view>
</template>
<script>
import { getMedicalRecordListApi } from '../../request/api/medicalRecord'
import patientTabList from '@/mixins/patientTabList.js'
/** 列表卡片预览字段(与 AI 病历预览一致,有内容才展示) */
const CARD_PREVIEW_DEFS = [
{ key: 'diagnosis', label: '临床诊断', full: true },
{ key: 'present_illness', label: '现病史', full: true },
{ key: 'tongue', label: '舌象', full: false },
{ key: 'pulse', label: '脉象', full: false },
{ key: 'tcm_syndrome', label: '中医证候', full: false },
{ key: 'tcm_disease', label: '中医疾病', full: false },
{ key: 'tcm_method', label: '中医治法', full: false },
{ key: 'past_history', label: '既往史', full: false },
{ key: 'allergy_history', label: '过敏史', full: false },
{ key: 'family_history', label: '家族史', full: false },
{ key: 'doctor_order', label: '医嘱', full: true },
]
export default {
mixins: [patientTabList],
methods: {
cardPreviewRows(item) {
const rows = []
for (let i = 0; i < CARD_PREVIEW_DEFS.length; i++) {
const d = CARD_PREVIEW_DEFS[i]
const v = item && item[d.key] != null ? String(item[d.key]).trim() : ''
if (!v || v === '无') {
continue
}
rows.push({ key: d.key, label: d.label, value: v, full: d.full })
}
return rows
},
goDetail(id) {
uni.navigateTo({
url: '/subPackages/my/mymedical-detail?id=' + id
})
},
fetchPatientList(patientId, page) {
return getMedicalRecordListApi({
user_patient_id: patientId,
page: page
})
},
},
onShow() {
this.bootstrapPatientTabs()
},
}
</script>
<style lang="scss" scoped>
.container {
width: 750rpx;
height: 100vh;
background-color: #F1F5F9;
display: flex;
flex-direction: column;
padding-bottom: env(safe-area-inset-bottom);
.head {
background: #F1F5F9;
position: sticky;
top: 0;
z-index: 99;
}
.empty-patient, .empty {
width: 440rpx;
margin: 200rpx auto;
text-align: center;
image { width: 100%; height: 393rpx; }
.word { color: #94A3B8; margin-top: 20rpx; font-size: 28rpx; }
.add-btn {
margin: 32rpx auto 0;
width: 240rpx;
height: 64rpx;
line-height: 64rpx;
background: #2979FF;
color: #fff;
border-radius: 32rpx;
font-size: 28rpx;
}
}
.list-swiper { flex: 1; height: 0; }
.list-scroll { height: 100%; }
.mr-card {
margin: 16rpx 20rpx;
padding: 24rpx;
background: #F8FAFC;
border-radius: 16rpx;
}
.mr-card-hd {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12rpx;
}
.mr-time { font-size: 24rpx; color: #64748B; }
.mr-store { font-size: 24rpx; color: #2979FF; }
.mr-patient-line {
font-size: 26rpx;
color: #334155;
margin-bottom: 12rpx;
}
.mr-chief {
padding: 12rpx 16rpx;
background: #fff;
border-radius: 10rpx;
margin-bottom: 12rpx;
display: flex;
flex-direction: column;
}
.ai-preview-grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: 0 -6rpx;
}
.ai-preview-card {
width: calc(50% - 12rpx);
margin: 0 6rpx 12rpx;
padding: 12rpx 16rpx;
background: #fff;
border-radius: 10rpx;
display: flex;
flex-direction: column;
box-sizing: border-box;
}
.ai-preview-card--full {
width: calc(100% - 12rpx);
}
.mr-lab {
font-size: 20rpx;
color: #94A3B8;
}
.mr-val {
font-size: 24rpx;
color: #0F172A;
margin-top: 4rpx;
word-break: break-all;
}
.mr-foot {
display: flex;
justify-content: flex-end;
margin-top: 8rpx;
text {
font-size: 24rpx;
color: #64748B;
padding: 8rpx 20rpx;
border: 1rpx solid #CBD5E1;
border-radius: 28rpx;
}
}
}
</style>

View File

@@ -1,366 +1,237 @@
<template>
<!-- 我的处方就诊人 Tab + 左右滑动切换 -->
<view class="container safe-area-inset-bottom">
<MessageNotification />
<view class="head" @click="toChoose">
<view class="head_name">{{infoUserList[0].name || '请选择就诊人'}}</view>
<view class="head_qh">
切换就诊人
<text class="iconfont icon-jiantou1"></text>
</view>
<view class="head" v-if="patientTabs.length > 0">
<u-tabs :list="patientTabs" :is-scroll="true" :current="current" @change="onTabChange"></u-tabs>
</view>
<!-- 空页 -->
<view class="empty" v-if="infoList.length==0">
<view class="empty-patient" v-if="emptyPatient">
<image src="https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk-client-wx/static/empty/orders.png" mode="aspectFit"></image>
<view class="word">暂无处方记录~</view>
<view class="word">暂无就诊人请先添加</view>
<view class="add-btn" @click="goAddPatient">添加就诊人</view>
</view>
<!-- 处方记录 -->
<view class="list" v-for="(item,index) in infoList" :key="item.id">
<view class="li_title">
<text>{{item.created_at}}</text>
<text class="text" v-if="item.status==1">已通过</text>
<text class="text" v-if="item.status==4">无需审核</text>
<text class="txt"
v-if="item.status!=1&& item.status!==4">{{item.status==0&&'待审核'||item.status==2&&'未通过'|| item.status==3&&'已失效'}}</text>
</view>
<view class="info">
<view class="list_name">
医生
</view>
<text>{{item.doctor_name}}</text>
</view>
<view class="info">
<view class="list_name">
患者
</view>
<text>{{item.patient_name}}</text>
</view>
<view class="info">
<view class="list_name">
诊断
</view>
<text>{{item.clinical_diagnose}}</text>
</view>
<view class="info">
<view class="lists_name">
药品
</view>
<view style="display: flex; align-items: center; flex-wrap: wrap;">
<text style="margin-right: 10rpx;">{{(item.drug_name).map(it=>it)}}</text>
<u-tag v-if="item.prescription_type"
:text="item.prescription_type==1?'中药饮片':item.prescription_type==2?'西(中成)药':item.prescription_type==3?'保健食品':item.prescription_type==5?'产品服务包':item.prescription_type==7?'医疗器械':''"
:type="item.prescription_type==1?'success':item.prescription_type==3?'warning':'primary'"
size="mini" />
</view>
</view>
<view class="info">
<view class="list_names">
处方详情
</view>
<text class="text" @click="getInfo(item.id,item.prescription_no)">点击查看</text>
</view>
<!-- 查看详情 -->
<view class="detail" @click="getInfo(item.id,item.prescription_no)"><text>查看详情</text></view>
</view>
<u-back-top :scroll-top="scrollTop"></u-back-top>
<swiper v-else class="list-swiper" :current="current" @change="onSwiperChange">
<swiper-item v-for="(tab, tabIdx) in patientTabs" :key="tabIdx">
<scroll-view
scroll-y
class="list-scroll"
@scrolltolower="onOrderScrollToLower"
refresher-enabled="true"
:refresher-triggered="isRefreshing"
@refresherrefresh="onRefresherRefresh"
>
<block v-if="Number(current) === tabIdx">
<view class="empty" v-if="infoList.length==0">
<image src="https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk-client-wx/static/empty/orders.png" mode="aspectFit"></image>
<view class="word">暂无处方记录~</view>
</view>
<view class="list" v-for="(item,index) in infoList" :key="item.id">
<view class="li_title">
<text>{{item.created_at}}</text>
<view class="li_title_right">
<text
class="pay-tag"
:class="{ 'pay-tag--paid': item.is_pay == 1 }"
>{{ item.is_pay == 1 ? '已支付' : '未支付' }}</text>
<text class="text" v-if="item.status==1">已通过</text>
<text class="text" v-if="item.status==4">无需审核</text>
<text class="txt" v-if="item.status!=1 && item.status!=4">{{ statusText(item.status) }}</text>
</view>
</view>
<view class="info">
<view class="list_name">医生</view>
<text>{{item.doctor_name}}</text>
</view>
<view class="info">
<view class="list_name">患者</view>
<text>{{item.patient_name}}</text>
</view>
<view class="info">
<view class="list_name">诊断</view>
<text>{{item.clinical_diagnose}}</text>
</view>
<view class="info">
<view class="lists_name">药品</view>
<view class="drug-wrap">
<text class="drug-text">{{ drugNamesText(item.drug_name) }}</text>
<u-tag
v-if="item.prescription_type"
:text="typeText(item.prescription_type)"
:type="item.prescription_type==1?'success':item.prescription_type==3?'warning':'primary'"
size="mini"
/>
</view>
</view>
<view class="detail" @click="getInfo(item.id,item.prescription_no)"><text>查看详情</text></view>
</view>
<u-loadmore :status="loadMoreStatus" v-if="infoList.length!=0" margin-top="30" margin-bottom="30" />
</block>
</scroll-view>
</swiper-item>
</swiper>
<u-toast ref="uToast" />
</view>
</template>
<script>
import {
userList
} from '../../request/api/api'
import {
getPrescriptionListApi
} from '../../request/api/prescription'
export default {
data() {
return {
infoList: [],
userList: [],
myinfo: [],
infoUserList: {},
id: " ",
page: 1, // 当前页数
total: "", // 总条数
totalPage: "", // 总页数
pageSize: 20, // 每页条数
scrollTop: 0
}
},
onLoad() {
import { getPrescriptionListApi } from '../../request/api/prescription'
import patientTabList from '@/mixins/patientTabList.js'
},
created() {
this.getInfolist();
},
export default {
mixins: [patientTabList],
methods: {
// 详情
statusText(status) {
if (status == 0) return '待审核'
if (status == 2) return '未通过'
if (status == 3) return '已失效'
return ''
},
typeText(t) {
if (t == 1) return '中药饮片'
if (t == 2) return '西(中成)药'
if (t == 3) return '保健食品'
if (t == 5) return '产品服务包'
if (t == 7) return '医疗器械'
return ''
},
drugNamesText(names) {
if (!names || !names.length) return ''
return names.join('、')
},
getInfo(id, no) {
uni.navigateTo({
url: "/subPackages/my/myrecord-detail?id=" + id + '&no=' + no
url: '/subPackages/my/myrecord-detail?id=' + id + '&no=' + no
})
},
// 切换
toChoose() {
uni.navigateTo({
url: "/subPackages/my/myinfo?id="
})
},
// 就诊人列表
getInfolist() {
userList({
method: "post",
data: {
store_id: uni.getStorageSync('store_id') || 11001,
}
}).then((res) => {
if (res.data.errcode == 0) {
this.infoUserList = res.data.data.filter((item) => item.is_default == 1)
// console.log(this.infoUserList, 'info');
if (this.infoUserList != '') {
this.id = this.infoUserList[0].id
}
}
this.getInfos()
})
},
// 列表
getInfos() {
getPrescriptionListApi({
up_id: this.id,
fetchPatientList(patientId, page) {
return getPrescriptionListApi({
up_id: patientId,
store_id: uni.getStorageSync('store_id') || 11001,
page: this.page
}).then((res) => {
if (res.data.code == 0) {
const data = res.data.result
// this.infoList = data.list
this.totalPage = data.pagination.totalPage
this.total = data.pagination.total
if (this.page > 1) {
this.infoList = [...this.infoList, ...data.list]
} else {
this.infoList = data.list
}
}
page: page
})
},
},
onPageScroll(e) {
this.scrollTop = e.scrollTop;
},
// 触底触发
onReachBottom() {
if (this.page >= this.totalPage) return
this.page += 1
uni.showToast({
title: "加载中",
duration: 700,
mask: false,
icon: 'loading'
})
setTimeout(() => {
this.getInfos();
}, 700)
},
onPullDownRefresh() {
// console.log("触发了下拉刷新")
if (this.page <= 1) {
this.getInfos();
setTimeout(() => {
uni.stopPullDownRefresh()
}, 300)
}
// if (this.page <= 1) return
this.page = 1
this.infoList=[]
this.getInfos();
//重置一下数据
// this.page = 1
// //重新发起请求
// this.getOrder(() => uni.stopPullDownRefresh())
},
mounted() {
},
onShow() {
this.getInfolist()
}
this.bootstrapPatientTabs()
},
}
</script>
<style lang="scss" scoped>
.container {
width: 750rpx;
min-height: 100vh;
max-height: 100%;
height: 100vh;
background-color: #F9FAFB;
padding-top: 12rpx;
display: flex;
flex-direction: column;
padding-bottom: env(safe-area-inset-bottom);
.head {
width: 750rpx;
height: 80rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 42rpx;
position: -webkit-sticky;
background: #F9FAFB;
position: sticky;
top: var(--window-top);
top: 0;
z-index: 99;
margin-bottom: 10rpx;
background-color: #F9FAFB;
font-size: 28rpx;
font-family: PingFang SC-Medium, PingFang SC;
font-weight: 500;
.iconfont {
font-size: 28rpx;
margin-left: 10rpx;
}
}
.empty {
.empty-patient, .empty {
width: 440rpx;
height: 393rpx;
margin: 200rpx auto;
text-align: center;
image {
width: 100%;
height: 100%;
z-index: 10;
image { width: 100%; height: 393rpx; }
.word { color: #94A3B8; margin-top: 20rpx; font-size: 28rpx; }
.add-btn {
margin: 32rpx auto 0;
width: 240rpx;
height: 64rpx;
line-height: 64rpx;
background: #2979FF;
color: #fff;
border-radius: 32rpx;
font-size: 28rpx;
}
}
.list-swiper {
flex: 1;
height: 0;
}
.list-scroll {
height: 100%;
}
.list {
margin: 0rpx auto 30rpx;
margin: 0 auto 30rpx;
width: 710rpx;
background: #FFFFFF;
border-radius: 8rpx;
padding: 32rpx;
.detail {
width: 648rpx;
display: flex;
justify-content: flex-end;
align-items: center;
text {
width: 160rpx;
height: 58rpx;
line-height: 58rpx;
text-align: center;
background: #FFFFFF rgba(41, 121, 255, 0);
border-radius: 64rpx;
border: 1rpx solid #94A3B8;
font-size: 28rpx;
font-family: PingFang SC-Medium, PingFang SC;
font-weight: 500;
color: #94A3B8;
}
}
.li_title {
width: 648rpx;
height: 76rpx;
min-height: 76rpx;
line-height: 66rpx;
font-size: 28rpx;
margin: 0 auto;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #475569;
justify-content: space-between;
align-items: center;
border-bottom: 2rpx solid #E2E8F0;
display: flex;
.text {
font-size: 28rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #4175EE;
.li_title_right {
display: flex;
align-items: center;
}
.txt {
font-size: 28rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #94A3B8;
.pay-tag {
margin-right: 16rpx;
font-size: 24rpx;
color: #F59E0B;
}
.pay-tag--paid {
color: #10B981;
}
.text { color: #4175EE; }
.txt { color: #94A3B8; }
}
.info {
width: 648rpx;
display: flex;
align-items: center;
margin: 40rpx auto;
.list_name {
.list_name, .lists_name {
width: 170rpx;
line-height: 40rpx;
letter-spacing: 50rpx;
font-size: 28rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #94A3B8;
letter-spacing: 50rpx;
}
.lists_name {
width: 170rpx;
line-height: 40rpx;
letter-spacing: 50rpx;
font-size: 28rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #94A3B8;
.drug-wrap {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
}
.list_names {
width: 160rpx;
.drug-text {
margin-right: 10rpx;
font-size: 28rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #94A3B8;
margin-right: 40rpx;
color: #1E293B;
}
text {
width: 466rpx;
font-size: 28rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #1E293B;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
text-overflow: ellipsis;
overflow: hidden;
margin-right: 20rpx;
}
.text {
font-size: 28rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #4175EE;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
}
</style>

View File

@@ -87,7 +87,19 @@
</view>
<view class="card_history">
<view class="name">
<text class="health-label">个人病史</text>
<text class="health-label">病史</text>
<u-radio-group v-model="present" size="44rpx">
<u-radio :name="present">{{present}}</u-radio>
</u-radio-group>
</view>
<view class="tabs" v-if="presentList[0]!='' && present === '有'">
<u-tag bg-color="#2979FF" color="#FFFFFF" v-for="(item,index) in presentList" :key="index"
:text="item" mode="dark" />
</view>
</view>
<view class="card_history">
<view class="name">
<text class="health-label">既往史</text>
<u-radio-group v-model="person" size="44rpx">
<u-radio :name="person">{{person}}</u-radio>
</u-radio-group>
@@ -99,7 +111,7 @@
</view>
<view class="card_history">
<view class="name">
<text class="health-label">家族</text>
<text class="health-label">家族史</text>
<u-radio-group v-model="family" size="44rpx">
<u-radio :name="family">{{family}}</u-radio>
</u-radio-group>
@@ -109,6 +121,54 @@
:text="item" mode="dark" />
</view>
</view>
<view class="card_history">
<view class="name">
<text class="health-label">流行病学史</text>
<u-radio-group v-model="epidemic" size="44rpx">
<u-radio :name="epidemic">{{epidemic}}</u-radio>
</u-radio-group>
</view>
<view class="tabs" v-if="epidemicList[0]!='' && epidemic === '有'">
<u-tag bg-color="#2979FF" color="#FFFFFF" v-for="(item,index) in epidemicList" :key="index"
:text="item" mode="dark" />
</view>
</view>
<view class="card_history">
<view class="name">
<text class="health-label">个人史</text>
<u-radio-group v-model="personal" size="44rpx">
<u-radio :name="personal">{{personal}}</u-radio>
</u-radio-group>
</view>
<view class="tabs" v-if="personalList[0]!='' && personal === '有'">
<u-tag bg-color="#2979FF" color="#FFFFFF" v-for="(item,index) in personalList" :key="index"
:text="item" mode="dark" />
</view>
</view>
<view class="card_history" v-if="showMenstrualHistory">
<view class="name">
<text class="health-label">月经史</text>
<u-radio-group v-model="menstrual" size="44rpx">
<u-radio :name="menstrual">{{menstrual}}</u-radio>
</u-radio-group>
</view>
<view class="tabs" v-if="menstrualList[0]!='' && menstrual === '有'">
<u-tag bg-color="#2979FF" color="#FFFFFF" v-for="(item,index) in menstrualList" :key="index"
:text="item" mode="dark" />
</view>
</view>
<view class="card_history" v-if="showMaritalHistory">
<view class="name">
<text class="health-label">婚育史</text>
<u-radio-group v-model="marital" size="44rpx">
<u-radio :name="marital">{{marital}}</u-radio>
</u-radio-group>
</view>
<view class="tabs" v-if="maritalList[0]!='' && marital === '有'">
<u-tag bg-color="#2979FF" color="#FFFFFF" v-for="(item,index) in maritalList" :key="index"
:text="item" mode="dark" />
</view>
</view>
</view>
<view class="footer">
@@ -160,10 +220,20 @@ export default {
renal: '',
allergic: '',
allergicList: [],
present: '无',
presentList: [],
person: '',
personList: [],
family: '',
familyList: [],
epidemic: '无',
epidemicList: [],
personal: '无',
personalList: [],
menstrual: '无',
menstrualList: [],
marital: '无',
maritalList: [],
heathList: [],
rInfo: {},
registerType: '0',
@@ -204,6 +274,23 @@ export default {
&& !!this.actived
&& this.infoList.some((p) => p.id === this.actived);
},
// 当前选中就诊人(用于月经史/婚育史展示规则)
activePatient() {
return this.infoList.find((p) => p.id === this.actived) || null;
},
showMenstrualHistory() {
const p = this.activePatient;
return !!(p && Number(p.sex) === 2);
},
showMaritalHistory() {
const p = this.activePatient;
if (!p) {
return false;
}
const sex = Number(p.sex);
const age = Number(p.age) || 0;
return (sex === 1 && age > 22) || (sex === 2 && age > 20);
},
},
watch: {
doctorId: {
@@ -500,11 +587,21 @@ export default {
this.liver = (this.heathList.liver_function) % 2 == 0 ? '正常' : '异常';
this.renal = (this.heathList.renal_function) % 2 == 0 ? '正常' : '异常';
this.allergic = (this.heathList.allergic_status) % 2 == 0 ? '无' : '有';
this.allergicList = (this.heathList.allergic_history) == 'Array' ? [] : (this.heathList.allergic_history);
this.allergicList = (this.heathList.allergic_history) == 'Array' ? [] : (this.heathList.allergic_history || []);
this.present = (this.heathList.present_status || 0) % 2 == 0 ? '无' : '有';
this.presentList = this.heathList.present_history || [];
this.person = (this.heathList.person_status) % 2 == 0 ? '无' : '有';
this.personList = (this.heathList.person_history) == 'Array' ? [] : (this.heathList.person_history);
this.personList = (this.heathList.person_history) == 'Array' ? [] : (this.heathList.person_history || []);
this.family = (this.heathList.family_status) % 2 == 0 ? '无' : '有';
this.familyList = (this.heathList.family_history) == 'Array' ? [] : (this.heathList.family_history);
this.familyList = (this.heathList.family_history) == 'Array' ? [] : (this.heathList.family_history || []);
this.epidemic = (this.heathList.epidemic_status || 0) % 2 == 0 ? '无' : '有';
this.epidemicList = this.heathList.epidemic_history || [];
this.personal = (this.heathList.personal_status || 0) % 2 == 0 ? '无' : '有';
this.personalList = this.heathList.personal_history || [];
this.menstrual = (this.heathList.menstrual_status || 0) % 2 == 0 ? '无' : '有';
this.menstrualList = this.heathList.menstrual_history || [];
this.marital = (this.heathList.marital_status || 0) % 2 == 0 ? '无' : '有';
this.maritalList = this.heathList.marital_history || [];
}
});
},

78
utils/api-response.js Normal file
View File

@@ -0,0 +1,78 @@
/**
* 按「接口所属后端」固定取值,禁止运行时猜测 / result||data 混取
*
* 写代码时先确认该请求打的是 xk-api 还是 Yii再选用对应方法
* - xk-apiunwrapXkApi / xkOk / xkPayload / xkMessage → code / result / message
* - Yii unwrapYiiApi / yiiOk / yiiPayload / yiiMessage → errcode / data / msg
*
* 患者端 request 返回完整 uni 响应,业务包在 res.data
*/
/** 取出业务 bodyuni 完整响应 → res.data已是 body 则原样) */
export function getApiBody(res) {
if (res == null || typeof res !== 'object') {
return res
}
if ('statusCode' in res || 'errMsg' in res) {
return res.data
}
return res
}
/** xk-api 是否成功code === 0 */
export function xkOk(res) {
const body = getApiBody(res)
return !!(body && Number(body.code) === 0)
}
/** xk-api 业务数据(固定取 result */
export function xkPayload(res) {
const body = getApiBody(res)
return body ? body.result : undefined
}
/** xk-api 提示文案(固定取 message */
export function xkMessage(res) {
const body = getApiBody(res)
return (body && body.message) || ''
}
/** xk-api 一次解包 */
export function unwrapXkApi(res) {
const body = getApiBody(res)
return {
ok: xkOk(res),
payload: xkPayload(res),
message: xkMessage(res),
body: body,
}
}
/** Yii 是否成功errcode === 0 */
export function yiiOk(res) {
const body = getApiBody(res)
return !!(body && Number(body.errcode) === 0)
}
/** Yii 业务数据(固定取 data */
export function yiiPayload(res) {
const body = getApiBody(res)
return body ? body.data : undefined
}
/** Yii 提示文案(固定取 msg */
export function yiiMessage(res) {
const body = getApiBody(res)
return (body && body.msg) || ''
}
/** Yii 一次解包 */
export function unwrapYiiApi(res) {
const body = getApiBody(res)
return {
ok: yiiOk(res),
payload: yiiPayload(res),
message: yiiMessage(res),
body: body,
}
}