Commit c50e0a88 authored by gengchunlei's avatar gengchunlei

Merge branch 'chronic-dev' into chronic-master

parents 1485572f 616fb46f
...@@ -7,6 +7,7 @@ module.exports = { ...@@ -7,6 +7,7 @@ module.exports = {
'postcss-pxtorem': { 'postcss-pxtorem': {
rootValue: 100, rootValue: 100,
propList: ['*'], propList: ['*'],
minPixelValue: 2,
} }
} }
} }
\ No newline at end of file
...@@ -6,6 +6,7 @@ export function getDict() { ...@@ -6,6 +6,7 @@ export function getDict() {
return fetchBase({ url: `/tumour-admin/v1/h5-app/dict`, loading: true }) return fetchBase({ url: `/tumour-admin/v1/h5-app/dict`, loading: true })
} }
// 区划编码查询下级 // 区划编码查询下级
export function getAreaChild(parentCode, loading = true) { export function getAreaChild(parentCode, loading = true) {
const key = 'chronic-area-cache' const key = 'chronic-area-cache'
...@@ -33,4 +34,21 @@ export function getResidentInfo(idCard) { ...@@ -33,4 +34,21 @@ export function getResidentInfo(idCard) {
// 居民idCard或者tel查询居民信息 // 居民idCard或者tel查询居民信息
export function getResidentByInfo(params) { export function getResidentByInfo(params) {
return fetchBase({ url: `/chronic-resident/v1/chronic-residents-record/query-resident-info-by-id-card`, body: params, loading: true }) return fetchBase({ url: `/chronic-resident/v1/chronic-residents-record/query-resident-info-by-id-card`, body: params, loading: true })
} }
\ No newline at end of file
// 文件上传
export function fileUpload(params) {
return fetchBase({ url: `/chronic-admin/v1/pictures-info/qiniu`, body: params, contentType: 'file' })
}
// 获取字典管理数据
export function getTemplateList() {
return fetchBase({ url: `/tumour-admin/v1/h5-app/dict`, loading: true })
}
//字典数据主键查询
export function getTemplateById() {
return fetchBase({ url: `/tumour-admin/v1/h5-app/dict`, loading: true })
}
import {fetchBase} from '@/api/doctor/doctorFetch'
//列表查询 疾病信息相关 诊断列表、治疗方案、随访方案
export function fetchDiseaseTypeList(params, loading) {
return fetchBase({ url: `/chronic-admin/v1/chronic-diagnose-record/manage-record`, body: params, loading })
}
// 查询随访列表
export function getVisitManageList(params, loading) {
return fetchBase({ url: `/chronic-admin/v1/chronic-visit-record/page`, body: params, loading })
}
\ No newline at end of file
...@@ -13,27 +13,27 @@ export function getChronicResidentsId(residentInfoId) { ...@@ -13,27 +13,27 @@ export function getChronicResidentsId(residentInfoId) {
loading: true loading: true
}) })
} }
//获取居民是否存在微信电话
export function getResidentWX(params) {
return fetchBase({ url: `/chronic-admin/v1/chronic-residents-record/query-resident-is-wx`, body: params, loading: true})
}
// 主键查询 // 主键查询
export function fetchCurrencyById(params) { export function fetchCurrencyById(params) {
return fetchBase({ url: `/chronic-admin/v1/chronic-visit-currency/record`, body: params, loading: true }) return fetchBase({ url: `/chronic-admin/v1/chronic-visit-currency/record`, body: params, loading: true })
} }
// 慢性病管理列表查询
export function getResidentByPage(params) {
return fetchBase({ url: `/chronic-admin/v1/chronic-residents-record/page`, body: params, loading: true })
}
// 查询待随访列表
export function getVisitAll(params, loading = true) {
return fetchBase({ url: `/chronic-admin/v1/chronic-visit-task/query-all-list`, body: params, loading })
}
// 根据单位名称模糊查询单位信息 // 根据单位名称模糊查询单位信息
export function getUnitByName(orgName) { export function getUnitByName(orgName) {
return fetchBase({ url: `/tumour-admin/v1/sys-user/org-by-name/${orgName}` }) return fetchBase({ url: `/tumour-admin/v1/sys-user/org-by-name/${orgName}` })
} }
// 拼音码查询药品信息
export function getDrug(code) {
return fetchBase({ url: `/tumour-admin/v1/remote-system/drugs/${code}` })
}
// 根据单位id查询科室 // 根据单位id查询科室
export function getOfficeList(unitId) { export function getOfficeList(unitId) {
return fetchBase({ url: `/tumour-admin/v1/sys-user/org-office/${unitId}` }) return fetchBase({ url: `/tumour-admin/v1/sys-user/org-office/${unitId}` })
...@@ -54,14 +54,14 @@ export function updateCurrency(params) { ...@@ -54,14 +54,14 @@ export function updateCurrency(params) {
return fetchBase({ url: `/chronic-admin/v1/chronic-visit-currency/update`, body: params, loading: true }) return fetchBase({ url: `/chronic-admin/v1/chronic-visit-currency/update`, body: params, loading: true })
} }
// 删除随访 // 列表查询
export function deleteVisit(params) { export function fetchCurrencyList(params, loading) {
return fetchBase({ url: `/chronic-admin/v1/chronic-visit-record/delete`, body:params, loading: true }) return fetchBase({ url: `/chronic-admin/v1/chronic-visit-currency/page`, body: params, loading })
} }
// 查询随访列表 //删除通用随访
export function queryVisitByPage(params, loading) { export function delCurrencyById(params) {
return fetchBase({ url: `/chronic-admin/v1/chronic-visit-record/page`, body: params, loading }) return fetchBase({ url: `/chronic-admin/v1/chronic-visit-currency/delete`, body: params, loading: true })
} }
...@@ -73,4 +73,9 @@ export function upLoadMultifile(params) { ...@@ -73,4 +73,9 @@ export function upLoadMultifile(params) {
loading: false, loading: false,
contentType: 'file' contentType: 'file'
}) })
}
//短信重发
export function messageResend(params) {
return fetchBase({ url: `/chronic-admin/v1/chronic-visit-currency/resend-sms`, body: params, loading: true })
} }
\ No newline at end of file
...@@ -8,4 +8,34 @@ export function queryResidentInfo(params) { ...@@ -8,4 +8,34 @@ export function queryResidentInfo(params) {
//更新居民基本信息 //更新居民基本信息
export function updateResident(params) { export function updateResident(params) {
return fetchBase({ url: `/chronic-admin/v1/chronic-residents-record/update`, body: params, loading: true }) return fetchBase({ url: `/chronic-admin/v1/chronic-residents-record/update`, body: params, loading: true })
}
// 慢性病管理列表查询
export function getResidentByPage(params) {
return fetchBase({ url: `/chronic-admin/v1/chronic-residents-record/page`, body: params, loading: true })
}
//转诊列表查询
export function getReferralList(params, loading) {
return fetchBase({ url: `/chronic-admin/v1/base-info/referral-list`, body: params, loading })
}
// 会诊列表查询
export function getConsultationList(params, loading) {
return fetchBase({ url: `/chronic-admin/v1/base-info/consultation-list`, body: params, loading })
}
// 获取用户配置
export function getUserConfig() {
return fetchBase({ url: `/tumour-admin/v1/sys-user-config/query-by-user`, loading: true })
}
// 添加个性化配置
export function addUserConfig(params, loading = true) {
return fetchBase({ url: `/tumour-admin/v1/sys-user-config/add-config`, body: params, loading })
}
// 修改个性化配置
export function updateUserConfig(params, loading = true) {
return fetchBase({ url: `/tumour-admin/v1/sys-user-config/update-config`, body: params, loading })
} }
\ No newline at end of file
import {fetchBase} from '@/api/doctor/doctorFetch'
//查初筛和复筛列表
export function getScreenAllList(residentInfoId, loading) {
return fetchBase({ url: `/chronic-admin/v1/chronic-screening-record/screen-list`,body:{residentInfoId},loading})
}
// 慢病高危筛查详情
export function firstScreenDetail(params) {
return fetchBase({ url: `/chronic-resident/v1/chronic-screening-record/screening-detail`, body: params, loading: true })
}
// 慢病专病筛查详情
export function secondScreenDetail(params) {
return fetchBase({ url: `/chronic-resident/v1/chronic-screening-record/rescreen-detail`, body: params, loading: true })
}
\ No newline at end of file
import {fetchBase} from '@/api/doctor/doctorFetch'
//获取高危随访列表v1.2
export function getHighVisitList(params, loading) {
return fetchBase({ url: `/chronic-admin/v1/chronic-high-visit-collect/page`, body: params, loading})
}
\ No newline at end of file
import {fetchBase} from '@/api/doctor/doctorFetch'
// 查询最近工作记录
export function getWorkByPage(params, loading) {
return fetchBase({ url: `/chronic-admin/v1/chronic-workbench/lately-service`, body: params, loading })
}
// 查询待随访列表
export function getVisitByPage(params, loading) {
return fetchBase({ url: `/chronic-admin/v1/chronic-visit-task/page`, body: params, loading })
}
// 待随访列表忽略
export function delVisit(params) {
return fetchBase({ url: `/chronic-admin/v1/chronic-visit-task/delete`, body: params, loading: true })
}
// 模板 分页查询
export function getTemplateByPage(params) {
return fetchBase({ url: `/tumour-admin/v1/template/page`, body: params, loading: true })
}
// 模板 主键查询
export function getTemplateDetail(params, loading = true) {
return fetchBase({ url: `/tumour-admin/v1/template/query-id/${params.id}`, loading })
}
// 待接诊列表
export function getReceiveByPage(params) {
return fetchBase({ url: `/chronic-admin/v1/chronic-referral-task/page`, body: params })
}
// 待接诊列表 忽略
export function ignoreReceive(params) {
return fetchBase({ url: `/chronic-admin/v1/chronic-referral-task/update`, body: params, loading: true })
}
// 筛查高危记录表 初筛高危待复筛1 复筛高危待诊断2
export function getBeSecondScreenByPage(params) {
return fetchBase({ url: `/chronic-admin/v1/chronic-workbench/be-second-page`, body: params })
}
// 筛查高危记录表 初筛高危待复筛1 复筛高危待诊断2
export function getDiagnoseByPage(params) {
return fetchBase({ url: `/chronic-admin/v1/chronic-workbench/be-diagnose-page`, body: params })
}
// 待复筛和高危待诊断忽略
export function addIgnoreRecord(params) {
return fetchBase({ url: `/chronic-admin/v1/chronic-ignore-record/save`, body: params, loading: true })
}
...@@ -11,7 +11,7 @@ export function queryMajorFUDetail(params) { ...@@ -11,7 +11,7 @@ export function queryMajorFUDetail(params) {
//查询专病高危随访详情 //查询专病高危随访详情
export function querySpecificFUDetail(params) { export function querySpecificFUDetail(params) {
return fetchBase({ url: `/chronic-resident/v1/chronic-visit-record/high-major-detail`, body: params, loading: true }) return fetchBase({ url: `/chronic-resident/v1/chronic-visit-record/high-specific-detail`, body: params, loading: true })
} }
// 查询通用随访详情 // 查询通用随访详情
......
...@@ -75,6 +75,7 @@ ...@@ -75,6 +75,7 @@
.w-1\/3 { width: 33.3%; } .w-1\/3 { width: 33.3%; }
.w-1\/2 { width: 50%; } .w-1\/2 { width: 50%; }
.h-full { height: 100%; } .h-full { height: 100%; }
.min-h-0 { min-height: 0px; }
// 字体大小 // 字体大小
.text-16 { font-size: 16px; } .text-16 { font-size: 16px; }
......
...@@ -27,6 +27,34 @@ body { ...@@ -27,6 +27,34 @@ body {
opacity: 0; opacity: 0;
} }
// 下拉框 消失隐藏动画
.viewer-fade-enter-active {
animation: viewer-fade-in .3s;
}
.viewer-fade-leave-active {
animation: viewer-fade-out .2s;
}
@keyframes viewer-fade-in {
0% {
transform: translate3d(0, -20px, 0);
opacity: 0;
}
100% {
transform: translate3d(0, 0, 0);
opacity: 1;
}
}
@keyframes viewer-fade-out {
0% {
transform: translate3d(0, 0, 0);
opacity: 1;
}
100% {
transform: translate3d(0, -20px, 0);
opacity: 0;
}
}
*, :after, :before { *, :after, :before {
box-sizing: border-box; box-sizing: border-box;
} }
......
<svg width="19" height="19" viewBox="0 0 19 19" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.6675 9.27291C11.6675 10.5326 10.6465 11.5536 9.38677 11.5536C8.12707 11.5536 7.10571 10.5326 7.10571 9.27291C7.10571 8.01321 8.12707 6.99219 9.38677 6.99219C10.6465 6.99219 11.6675 8.01321 11.6675 9.27291Z" stroke="currentColor" stroke-width="1.2"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.7508 8.14H14.9998C14.9913 8.14 14.9835 8.09478 14.975 8.09512C14.8285 7.42362 14.5629 6.77388 14.2032 6.21356C14.21 6.2071 14.2175 6.19112 14.2243 6.18466L15.4622 4.94026C15.8264 4.57612 15.8264 3.98282 15.4622 3.61868L15.0444 3.19912C14.6802 2.83498 14.0897 2.8343 13.7255 3.19844L12.4872 4.43604C12.4808 4.44284 12.4764 4.45032 12.4702 4.45678C11.9096 4.0974 11.2364 3.83152 10.5649 3.68498C10.5652 3.67648 10.52 3.66866 10.52 3.66016V1.90916C10.52 1.39406 10.1973 1 9.68224 1H9.09098C8.57588 1 8.14 1.39406 8.14 1.90916V3.66016C8.14 3.66866 8.15156 3.67648 8.1519 3.68498C7.4804 3.83152 6.85888 4.09706 6.29856 4.45678C6.2921 4.44998 6.29006 4.4425 6.2836 4.4357L5.04668 3.19776C4.68254 2.83362 4.09264 2.83362 3.7285 3.19776L3.31064 3.61562C2.9465 3.97976 2.9465 4.57034 3.31098 4.93448L4.54892 6.17276C4.55572 6.17922 4.56354 6.1833 4.57 6.18976C4.21028 6.75042 3.94474 7.42362 3.7982 8.09512C3.7897 8.09478 3.78188 8.14 3.77338 8.14H2.02238C1.50728 8.14 1 8.46266 1 8.97776V9.56902C1 10.0838 1.50728 10.52 2.02238 10.52H3.77338C3.78188 10.52 3.7897 10.5084 3.7982 10.5081C3.94474 11.1796 4.21028 11.8011 4.57 12.3614C4.56354 12.3679 4.55572 12.3699 4.54926 12.3764L3.31098 13.6133C2.94684 13.9775 2.94684 14.5674 3.31098 14.9315L3.72884 15.3494C4.09332 15.7135 4.68356 15.7135 5.0477 15.349L6.28598 14.1107C6.29244 14.1043 6.29686 14.0965 6.30298 14.09C6.86364 14.4497 7.4804 14.7153 8.1519 14.8618C8.15156 14.8703 8.14 14.8781 8.14 14.8866V16.6376C8.14 17.1527 8.57588 17.66 9.09098 17.66H9.68224C10.1973 17.66 10.52 17.1527 10.52 16.6376V14.8866C10.52 14.8781 10.5652 14.8703 10.5649 14.8618C11.2364 14.7153 11.8858 14.4497 12.4464 14.09C12.4529 14.0965 12.4689 14.1043 12.4753 14.1107L13.7197 15.349C14.0839 15.7132 14.6772 15.7132 15.0413 15.349L15.4609 14.9312C15.825 14.5667 15.8257 13.9764 15.4616 13.6123L14.224 12.374C14.2172 12.3676 14.2097 12.3631 14.2029 12.357C14.5626 11.7964 14.8285 11.1796 14.975 10.5081C14.9835 10.5084 14.9913 10.52 14.9998 10.52H16.7508C17.2659 10.52 17.66 10.0838 17.66 9.56902V8.97776C17.66 8.46266 17.2659 8.14 16.7508 8.14Z" stroke="currentColor" stroke-width="1.2"/>
</svg>
<svg width="14" height="15" viewBox="0 0 14 15" xmlns="http://www.w3.org/2000/svg">
<path d="M1.75 12.7496H2.8105L9.796 5.76407L8.7355 4.70357L1.75 11.6891V12.7496ZM13.75 14.2496H0.25V11.0673L10.3263 0.991074C10.4669 0.850471 10.6576 0.771484 10.8565 0.771484C11.0554 0.771484 11.2461 0.850471 11.3868 0.991074L13.5085 3.11282C13.6491 3.25347 13.7281 3.4442 13.7281 3.64307C13.7281 3.84195 13.6491 4.03268 13.5085 4.17332L4.93225 12.7496H13.75V14.2496ZM9.796 3.64307L10.8565 4.70357L11.917 3.64307L10.8565 2.58257L9.796 3.64307Z"/>
</svg>
<svg width="9" height="15" viewBox="0 0 9 15" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="9" height="15" viewBox="0 0 9 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.5 13.689L1.5 7.68896L7.5 1.68896" stroke="#262626" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/> <path d="M7.5 13.689L1.5 7.68896L7.5 1.68896" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
</svg> </svg>
<svg width="18" height="16" viewBox="0 0 18 16" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0H18V2H0V0ZM0 7H18V9H0V7ZM0 14H18V16H0V14Z"/>
</svg>
<svg width="18" height="18" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
<path d="M12 0H18V5H16V2H12V0ZM6 0V2H2V5H0V0H6ZM12 18V16H16V13H18V18H12ZM6 18H0V13H2V16H6V18ZM0 8H18V10H0V8Z"/>
</svg>
<svg width="8" height="9" viewBox="0 0 8 9" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="8" height="9" viewBox="0 0 8 9" xmlns="http://www.w3.org/2000/svg">
<path d="M6.6432 3.90404C7.26987 4.29571 7.26987 5.20837 6.6432 5.60004L1.53 8.79579C0.863951 9.21207 0 8.73323 0 7.94779V1.55629C0 0.770851 0.863951 0.292008 1.53 0.708288L6.6432 3.90404Z" fill="#5FC3B7"/> <path d="M6.6432 3.90404C7.26987 4.29571 7.26987 5.20837 6.6432 5.60004L1.53 8.79579C0.863951 9.21207 0 8.73323 0 7.94779V1.55629C0 0.770851 0.863951 0.292008 1.53 0.708288L6.6432 3.90404Z"/>
</svg> </svg>
<template> <template>
<van-config-provider :theme-vars='themeVars' class="h-full"> <van-config-provider :theme-vars='themeVars' style="height: 100vh">
<div class='h-full resident-home'> <div class='h-full resident-home'>
<router-view v-slot='{ Component }'> <router-view v-slot='{ Component, route }'>
<Transition name='route' mode='out-in'> <Transition name='route' mode='out-in'>
<component :is='Component' v-if='visible' /> <KeepAlive :include="['Workbench', 'PatientDetail']">
<component :is='Component' :key="route.name" v-if='visible' />
</KeepAlive>
</Transition> </Transition>
</router-view> </router-view>
</div> </div>
...@@ -35,7 +37,8 @@ export default { ...@@ -35,7 +37,8 @@ export default {
cellVerticalPadding: '.15rem', cellVerticalPadding: '.15rem',
cellTextColor: '#262626', cellTextColor: '#262626',
cellBorderColor: '#d9d9d9', cellBorderColor: '#d9d9d9',
navBarIconColor: '#262626' navBarIconColor: '#262626',
} }
} }
}, },
...@@ -45,6 +48,8 @@ export default { ...@@ -45,6 +48,8 @@ export default {
}, },
created() { created() {
this.init() this.init()
// 监听页面是否隐藏
document.addEventListener('visibilitychange', this.visibilitychange)
}, },
methods: { methods: {
async init() { async init() {
...@@ -52,7 +57,7 @@ export default { ...@@ -52,7 +57,7 @@ export default {
if (!token) { if (!token) {
token = sessionStorage.getItem('token') token = sessionStorage.getItem('token')
if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV !== 'production') {
token = '4ef7a32e-c217-44b6-ac5d-8ad9a91d38a0' token = '80fa0d29-73b2-4593-87b8-fc46b53bf49e'
} }
} }
if (token) { if (token) {
...@@ -61,17 +66,128 @@ export default { ...@@ -61,17 +66,128 @@ export default {
this.store.$patch({ dict: res.data || {} }) this.store.$patch({ dict: res.data || {} })
const user = await getAuthInfo() const user = await getAuthInfo()
this.store.$patch({authInfo: user.data || {}}) this.store.$patch({authInfo: user.data || {}})
this.visible = true this.visible = true
} else { } else {
backHome() backHome()
} }
},
visibilitychange() {
if (document.hidden) {
this.store.onDocumentHidden(true)
} else {
this.store.onDocumentHidden(false)
}
} }
},
beforeUnmount() {
document.removeEventListener('visibilitychange', this.visibilitychange)
} }
} }
</script> </script>
<style lang='less' scoped> <style lang='less'>
// 按钮样式
.doc-btn {
border: 0;
padding: 4px 12px;
height: 26px;
}
.doc-btn-primary {
.doc-btn();
color: var(--van-primary-color);
background: #F0F3FF;
}
.doc-btn-red {
.doc-btn();
color: #FF4D4F;
background: #FFF3F0;
}
// tab 样式
.doc-tab-round {
.van-tabs__nav--card {
column-gap: 10px;
border: 0;
margin: 0;
background: transparent;
}
.van-tab--card {
border: 0;
border-radius: 40px;
background: #fff;
color: #262626;
font-size: 14px;
line-height: 28px;
padding: 0 10px;
transition: all .2s;
}
.van-tab--card.van-tab--active {
color: #fff;
background: var(--van-primary-color);
font-weight: 500;
}
}
.doc-tab-round[line] {
.van-tab--card {
border: 1px solid #fff;
line-height: 1;
}
.van-tab--card.van-tab--active {
color: var(--van-primary-color);
border: 1px solid var(--van-primary-color);
background: #E6F0FF;
font-weight: 500;
}
}
// 底部细线
.bottom-small-line {
height: 1px;
box-shadow: 0 0.5Px #D7DADE;
}
// list列表中的card
.doc-list-card {
border-radius: 12px;
background-color: #fff;
.name {
font-size: 16px;
font-weight: 600;
}
.tag {
background: #F0F3FF;
padding: 4px 8px;
border-radius: 8px;
font-size: 12px;
line-height: 1;
}
.label {
display: inline-block;
color: #8C8C8C;
min-width: 104px;
}
.divider {
.bottom-small-line()
// border-bottom: 1px solid #D7DADE;
// transform: scaleY(.5);
// height: 1px;
// box-shadow: 0 0 0.5Px #e5e5e5;
}
.bt-group {
display: flex;
justify-content: flex-end;
column-gap: 10px;
}
}
// 输入框
.doc-input {
border-radius: 50px;
background-color: #FAFAFA !important;
padding: 5px 0 5px 12px !important;
&::after {
display: none;
}
}
</style> </style>
<template> <template>
<div> <div>
<van-nav-bar title='修改居民信息' left-text='' left-arrow <!-- <van-nav-bar title='修改居民信息' left-text='' left-arrow
@click-left='toBack'></van-nav-bar> @click-left='toBack'></van-nav-bar> -->
<DocNavBar title="修改居民信息" class="shrink-0"></DocNavBar>
<div class='p-4 h-overflow'> <div class='p-4 h-overflow'>
<van-form ref='form'> <van-form ref='form'>
<div class='title'>居民信息</div> <div class='title'>居民信息</div>
...@@ -14,14 +15,14 @@ ...@@ -14,14 +15,14 @@
class='input-back mt-2 form-input' class='input-back mt-2 form-input'
:rules='rules.certificateTypeName' :rules='rules.certificateTypeName'
/>--> />-->
<!-- <div class='label-title mt-5'>证件号码</div> <div class='label-title mt-5'>证件号码</div>
<van-field <van-field
v-model='form.idCard' v-model='form.idCard'
readonly readonly
placeholder='证件号码' placeholder='证件号码'
class='input-back mt-2 form-input' class='input-back mt-2 form-input'
:rules='rules.idCard' :rules='rules.idCard'
/>--> />
<div class='label-title mt-5'>姓名</div> <div class='label-title mt-5'>姓名</div>
<van-field <van-field
v-model='form.residentName' v-model='form.residentName'
...@@ -30,7 +31,7 @@ ...@@ -30,7 +31,7 @@
class='input-back mt-2 form-input' class='input-back mt-2 form-input'
:rules='rules.residentName' :rules='rules.residentName'
/> />
<!-- <div class='label-title mt-5'>性别</div> <div class='label-title mt-5'>性别</div>
<van-field <van-field
v-model='form.genderName' v-model='form.genderName'
is-link is-link
...@@ -38,8 +39,8 @@ ...@@ -38,8 +39,8 @@
placeholder='性别' placeholder='性别'
class='input-back mt-2 form-input' class='input-back mt-2 form-input'
:rules='rules.genderName' :rules='rules.genderName'
/>--> />
<!-- <div class='label-title mt-5'>出生日期</div> <div class='label-title mt-5'>出生日期</div>
<van-field <van-field
v-model='form.dataBirth' v-model='form.dataBirth'
is-link is-link
...@@ -47,7 +48,7 @@ ...@@ -47,7 +48,7 @@
placeholder='出生日期' placeholder='出生日期'
class='input-back mt-2 form-input' class='input-back mt-2 form-input'
:rules='rules.dataBirth' :rules='rules.dataBirth'
/>--> />
<div class='label-title mt-5'>本人电话</div> <div class='label-title mt-5'>本人电话</div>
<van-field <van-field
v-model='form.telephone' v-model='form.telephone'
...@@ -74,15 +75,14 @@ ...@@ -74,15 +75,14 @@
@cancel='showNational = false' @cancel='showNational = false'
/> />
</van-popup> </van-popup>
<!-- <div class='label-title mt-5'>年龄</div> <div class='label-title mt-5'>年龄</div>
<van-field <van-field
v-model='form.currentAge' v-model='form.currentAge'
readonly readonly
placeholder='年龄' placeholder='年龄'
class='input-back mt-2 form-input' class='input-back mt-2 form-input'
:rules='rules.currentAge' :rules='rules.currentAge'
/>--> />
<div class='label-title mt-5'>现住址</div> <div class='label-title mt-5'>现住址</div>
<van-field <van-field
...@@ -196,10 +196,10 @@ ...@@ -196,10 +196,10 @@
</template> </template>
<script> <script>
import { addToArr, fetchDataHandle } from '@/utils/common' import { addToArr } from '@/utils/common'
import { useStore } from '@/doctor/store' import { useStore } from '@/doctor/store'
import DocAddress from '@/components/docAddress/DocAddress' import DocAddress from '@/components/docAddress/DocAddress'
import dayjs from 'dayjs' import DocNavBar from '@/doctor/components/docNavBar/DocNavBar.vue'
import { getChronicResidentsId } from '@/api/doctor/generalFU' import { getChronicResidentsId } from '@/api/doctor/generalFU'
import { updateResident } from '@/api/doctor/resident' import { updateResident } from '@/api/doctor/resident'
...@@ -262,8 +262,27 @@ const defaultForm = (info = {}) => { ...@@ -262,8 +262,27 @@ const defaultForm = (info = {}) => {
// 与居民关系 // 与居民关系
relation: undefined, relation: undefined,
relationName: undefined, relationName: undefined,
relationOther: undefined relationOther: undefined,
// 人群 // 人群
chronicCrowd: undefined,
chronicTagsArray: undefined,
firstScreenDate: undefined,
firstScreenResult: undefined,
highTagsArray: undefined,
highTags: undefined,
latelyDiagnoseDate: undefined,
latelyScreenDate:undefined,
// 建档单位、科室、医生
createDoctorId: undefined,
createDoctorName: undefined,
createOfficeId: undefined,
createOfficeName: undefined,
createUnitId: undefined,
createUnitName: undefined,
// 当前人群-显示type=CP00181
groupsArrays: undefined,
// 当前人群-查询
groups: undefined,
} }
Reflect.ownKeys(form).forEach(key => { Reflect.ownKeys(form).forEach(key => {
if (info[key] != undefined) { if (info[key] != undefined) {
...@@ -274,7 +293,7 @@ const defaultForm = (info = {}) => { ...@@ -274,7 +293,7 @@ const defaultForm = (info = {}) => {
} }
export default { export default {
name: 'BaseInfo', name: 'BaseInfo',
components: { DocAddress }, components: { DocAddress, DocNavBar },
props: { props: {
info: { info: {
default: () => { default: () => {
...@@ -315,8 +334,8 @@ export default { ...@@ -315,8 +334,8 @@ export default {
authInfo() { authInfo() {
return this.store.$state.authInfo return this.store.$state.authInfo
}, },
routerDetail() { residentInfoId() {
return this.$route.query return this.$route.query.residentInfoId
} }
}, },
created() { created() {
...@@ -324,7 +343,7 @@ export default { ...@@ -324,7 +343,7 @@ export default {
}, },
methods: { methods: {
async load() { async load() {
const res = await getChronicResidentsId(this.routerDetail.residentInfoId) const res = await getChronicResidentsId(this.residentInfoId)
this.form = defaultForm(res.data) this.form = defaultForm(res.data)
if (this.form.presentCode) { if (this.form.presentCode) {
this.addressRecord.presentCode = addToArr(this.form.presentCode) this.addressRecord.presentCode = addToArr(this.form.presentCode)
...@@ -461,6 +480,7 @@ export default { ...@@ -461,6 +480,7 @@ export default {
:deep(.van-field__error-message) { :deep(.van-field__error-message) {
position: absolute; position: absolute;
margin-top: 3px;
} }
:deep(.van-cell:after) { :deep(.van-cell:after) {
......
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
@click="onClick(item)" @click="onClick(item)"
:class="['py-2 px-3 shrink-0 check-btn-item', :class="['py-2 px-3 shrink-0 check-btn-item',
{ 'check-btn-item-active': isSelect(item) }, { 'check-btn-item-active': isSelect(item) },
{ 'check-btn-item-disabled': isDisabled(item) }]"> { 'check-btn-item-disabled': isDisabled(item) },
`text-align-${textAlign}`]"
>
{{ item[fieldNames.text] }} {{ item[fieldNames.text] }}
</div> </div>
</div> </div>
...@@ -20,11 +22,16 @@ export default { ...@@ -20,11 +22,16 @@ export default {
fieldNames: { fieldNames: {
type: Object, type: Object,
default: () => { default: () => {
return {text: 'name', value: 'code'} return {text: 'name', value: 'value'}
} }
}, },
// 点击取消选中 单选
clearable: { default: true },
// 是否多选 // 是否多选
multiple: Boolean multiple: Boolean,
textAlign: { default: 'center' },
// 关闭选中样式
activeStyleNone: Boolean
}, },
emits: ['update:value', 'change'], emits: ['update:value', 'change'],
data() { data() {
...@@ -49,20 +56,28 @@ export default { ...@@ -49,20 +56,28 @@ export default {
if (this.isDisabled(item)) { if (this.isDisabled(item)) {
return return
} }
const val = item[this.fieldNames.value]
if (this.multiple) { if (this.multiple) {
if (this.innerValue.includes(item[this.fieldNames.value])) { if (this.innerValue.includes(val)) {
this.innerValue = this.innerValue.filter(e => e !== item[this.fieldNames.value]) this.innerValue = this.innerValue.filter(e => e !== val)
} else { } else {
this.innerValue.push(item[this.fieldNames.value]) this.innerValue.push(val)
} }
} else { } else {
this.innerValue = item[this.fieldNames.value] if (this.clearable && this.innerValue === val) {
this.innerValue = undefined
} else {
this.innerValue = val
}
} }
this.$emit('update:value', this.innerValue) this.$emit('update:value', this.innerValue)
this.$emit('change', this.innerValue, item) this.$emit('change', this.innerValue, item)
}, },
// 是否选中 // 是否选中
isSelect(item){ isSelect(item){
if (this.activeStyleNone) {
return false
}
if (this.multiple) { if (this.multiple) {
return this.innerValue.includes(item[this.fieldNames.value]) return this.innerValue.includes(item[this.fieldNames.value])
} else { } else {
...@@ -86,25 +101,64 @@ export default { ...@@ -86,25 +101,64 @@ export default {
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.check-btn { .check-btn {
row-gap: 10px; row-gap: 10px;
column-gap: 10px; column-gap: 10px;
.check-btn-item {
border: 1px solid transparent;
background-color: #FAFAFA;
border-radius: 8px;
text-align: center;
transition: all .2s;
}
.check-btn-item-active {
border: 1px solid var(--van-primary-color);
background-color: #F0F6FF;
color: var(--van-primary-color);
}
.check-btn-item-disabled {
background-color: #F0F6FF;
color: var(--van-primary-color);
// opacity: 0.5;
filter: grayscale(1);
}
.text-align-left {
text-align: left;
}
.text-align-center {
text-align: center;
}
.text-align-right {
text-align: right;
}
} }
.check-btn-item {
border: 1px solid transparent; .check-btn.check-btn-workbench {
background-color: #FAFAFA; .check-btn-item {
border-radius: 8px; border-radius: 30px;
transition: all .2s; padding-top: 4px;
padding-bottom: 4px;
color: #595959;
}
.check-btn-item-active {
color: var(--van-primary-color);
}
} }
.check-btn-item-active {
border: 1px solid var(--van-primary-color); .check-btn[column-3] {
background-color: #F0F6FF; .check-btn-item {
color: var(--van-primary-color); width: calc(33.3% - 6.6px);
}
}
.check-btn[column-2] {
.check-btn-item {
width: calc(50% - 5px);
}
} }
.check-btn-item-disabled { .check-btn[column-1] {
background-color: #F0F6FF; .check-btn-item {
color: var(--van-primary-color); width: 100%;
// opacity: 0.5; }
filter: grayscale(1);
} }
</style> </style>
<template>
<!-- 弹出层 -->
<van-popup v-model:show='data.isPicker' position='bottom' round @close='confirmOn'>
<van-picker ref='picker'
title='请选择时间'
:columns='data.columns'
@cancel='cancelOn'
@confirm='onConfirm'
v-model='data.selectedValues'
:min-date='data.minDate'
:max-date='data.maxDate'
@change='changeTime'
/>
</van-popup>
</template>
<script setup>
import { reactive, watch, getCurrentInstance } from 'vue'
import dayjs from 'dayjs'
const customFieldName = {
text: 'value',
value: 'values',
children: ''
}
const data = reactive({
isPicker: false, //是否显示弹出层
columns: [], //所有时间列
selectedValues: [], //控件选择的时间值
showType: [], //控制显示时间格式 年月日时分秒
minDate: null,
maxDate: null,
})
const props = defineProps({
// 传入的显影状态
showPicker: {
type: Boolean
},
// 传入的值
values: {
type: String
},
showType: {
type: Array,
default: () => {
return ['year', 'month', 'day', 'hour', 'minute', 'second']
}
},
minDate: {
type: Date
},
maxDate: {
type: Date
}
})
//定义要向父组件传递的事件
const emit = defineEmits(['changeValue', 'confirm'])
watch(
() => props.showPicker,
val => {
data.isPicker = val
data.showType = props.showType
data.minDate = props.minDate
data.maxDate = props.maxDate
data.columns = []
getcolumns()
},
{
immediate: true//立即监听--进入就会执行一次 监听显影状态
}
)
function getcolumns() {
let strtime = props.values //传入的时间
//console.log(strtime); 2023-09-05 19:28:00
let date = new Date(strtime.replace(/-/g, '/'))
// console.log(date); Wed Aug 09 2023 14:53:15 GMT+0800 (中国标准时间)
let timeVaules = date.getTime()
let dateVaules
if (props.values != '') {
dateVaules = new Date(timeVaules)
} else {
dateVaules = new Date() //没有传入时间则默认当前时刻
}
let Y = dateVaules.getFullYear()
let M = dateVaules.getMonth()
let D = dateVaules.getDate()
let h = dateVaules.getHours()
let m = dateVaules.getMinutes()
let s = dateVaules.getSeconds()
let minYear = data.minDate ? new Date(data.minDate).getFullYear() : null
if (data.showType.includes('year')) {
let year = [] //获取前后十年数组
year.values = []
let Currentday = new Date().getFullYear()
let minYear = props.minDate ? props.minDate.getFullYear() : Currentday - 10
let maxYear = props.maxDate ? props.maxDate.getFullYear() : Currentday + 10
for (let i = minYear; i < maxYear; i++) {
year.push({ text: i.toString(), value: i })
}
year.defaultIndex = year.values.indexOf(Y) //设置默认选项当前年
// 个位数补0
const _M = M < 10 ? `0${M + 1}` : `${M + 1}`.toString() //月份比实际获取的少1,所以要加1
const _D = D < 10 ? `0${D}` : D.toString()
const _h = h < 10 ? `0${h}` : h.toString()
const _m = m < 10 ? `0${m}` : m.toString()
const _s = s < 10 ? `0${s}` : s.toString()
// 生成年月日时分秒时间值
data.selectedValues.push(Y)
data.selectedValues.push(_M)
data.selectedValues.push(_D)
data.selectedValues.push(_h)
data.selectedValues.push(_m)
data.selectedValues.push(_s)
data.columns.push(year) //生成年列
}
if (data.showType.includes('month')) {
let month = [] //获取12月数组
let allMon = []
if (data.minDate && minYear == Y) {
let minMon = new Date(data.minDate).getMonth()
let allM = Object.keys(Array.apply(null, { length: 13 }))
allMon = allM.filter(item => item >= minMon)
} else {
allMon = Object.keys(Array.apply(null, { length: 13 }))
}
month = allMon.map(function(item) {
if (+item + 1 <= 10) {
return { text: '0' + item, value: '0' + item }
} else if (+item + 1 == 11) {
return { text: +item, value: +item }
} else {
return {
text: (+item + 0).toString(),
value: (+item + 0).toString()
}
}
})
month.splice(0, 1)
data.columns.push(month) //生成月列
}
if (data.showType.includes('day')) {
//获取当月的天数
let days = getCountDays(Y, M + 1)
let day = [] //创建当月天数数组
let allDays = []
if (data.minDate && minYear == Y) {
let minDay = new Date(data.minDate).getDate()
let allD = Object.keys(Array.apply(null, { length: days + 1 }))
allDays = allD.filter(item => item >= minDay)
} else {
allDays = Object.keys(Array.apply(null, { length: days + 1 }))
}
day = allDays.map(function(item) {
if (+item + 1 <= 10) {
return { text: '0' + item, value: '0' + item }
} else if (+item + 1 == 11) {
return { text: +item, value: +item }
} else {
return {
text: (+item + 0).toString(),
value: (+item + 0).toString()
}
}
})
day.splice(0, 1)
data.columns.push(day) //生成日列
}
if (data.showType.includes('hour')) {
let hour = [] //创建小时数组
let allHour = []
if (data.minDate && minYear == Y) {
let minHour = new Date(data.minDate).getHours() ? new Date(data.minDate).getHours(): new Date().getHours()
let allH = Object.keys(Array.apply(null, { length: 24 }))
allHour = allH.filter(item => item >= minHour)
} else {
allHour = Object.keys(Array.apply(null, { length: 24 }))
}
hour = allHour.map(function(item) {
if (+item + 1 <= 10) {
return { text: '0' + item, value: '0' + item }
} else if (+item + 1 == 11) {
return { text: +item, value: +item }
} else {
return {
text: (+item + 0).toString(),
value: (+item + 0).toString()
}
}
})
data.columns.push(hour) //生成小时列
}
if (data.showType.includes('minute')) {
let mi = [] //创建分钟数组
let allMi = []
if (data.minDate && minYear == Y) {
let minMi = new Date(data.minDate).getMinutes() ? new Date(data.minDate).getMinutes() : new Date().getMinutes()
let allM = Object.keys(Array.apply(null, { length: 60 }))
allMi = allM.filter(item => item >= minMi)
} else {
allMi = Object.keys(Array.apply(null, { length: 60 }))
}
mi = allMi.map(function(item) {
if (+item + 1 <= 10) {
return { text: '0' + item, value: '0' + item }
} else if (+item + 1 == 11) {
return { text: +item, value: +item }
} else {
return {
text: (+item + 0).toString(),
value: (+item + 0).toString()
}
}
})
data.columns.push(mi)//生成分钟列
}
if (data.showType.includes('second')) {
let ss = [] //创建秒数数组
let allSS = []
if (data.minDate && minYear == Y) {
let minSS = new Date(data.minDate).getSeconds() ? new Date(data.minDate).getSeconds() : new Date().getSeconds()
let allS = Object.keys(Array.apply(null, { length: 60 }))
allSS = allS.filter(item => item >= minSS)
} else {
allSS = Object.keys(Array.apply(null, { length: 60 }))
}
ss = allSS.map(function(item) {
if (+item + 1 <= 10) {
return { text: '0' + item, value: '0' + item }
} else if (+item + 1 == 11) {
return { text: +item, value: +item }
} else {
return {
text: (+item + 0).toString(),
value: (+item + 0).toString()
}
}
})
data.columns.push(ss)//生成秒钟列
}
}
function getCountDays(year, month) {
//获取某年某月多少天
let day = new Date(year, month, 0)
return day.getDate()
}
// 关闭弹框
function confirmOn() {
emit('changeValue')
}
function changeTime() {
if (data.selectedValues && data.selectedValues.length) {
//存在最小时间时触发
if (props.minDate) {
let endval =
data.selectedValues[0] +
'-' +
data.selectedValues[1] +
'-' +
data.selectedValues[2] +
' ' +
data.selectedValues[3] +
':' +
data.selectedValues[4] +
':' +
data.selectedValues[5]
let selectAll = dayjs(endval).format('YYYY-MM-DD HH:mm:ss')
changeColumns(selectAll)
}
}
}
function changeColumns(val) {
data.columns = []
let strtime = val //传入的时间
let date = new Date(strtime.replace(/-/g, '/'))
let timeVaules = date.getTime()
let dateVaules = new Date(timeVaules)
let Y = dateVaules.getFullYear()
let M = dateVaules.getMonth()
let D = dateVaules.getDate()
let h = dateVaules.getHours()
let m = dateVaules.getMinutes()
let s = dateVaules.getSeconds()
let minYear = data.minDate ? new Date(data.minDate).getFullYear() : null
if (data.showType.includes('year')) {
let year = [] //获取前后十年数组
year.values = []
let Currentday = new Date().getFullYear()
let minYear = props.minDate ? props.minDate.getFullYear() : Currentday - 10
let maxYear = props.maxDate ? props.maxDate.getFullYear() : Currentday + 10
for (let i = minYear; i < maxYear; i++) {
year.push({ text: i.toString(), value: i })
}
year.defaultIndex = year.values.indexOf(Y) //设置默认选项当前年
// 个位数补0
const _M = M < 10 ? `0${M + 1}` : `${M + 1}`.toString() //月份比实际获取的少1,所以要加1
const _D = D < 10 ? `0${D}` : D.toString()
const _h = h < 10 ? `0${h}` : h.toString()
const _m = m < 10 ? `0${m}` : m.toString()
const _s = s < 10 ? `0${s}` : s.toString()
// 生成年月日时分秒时间值
data.selectedValues.push(Y)
data.selectedValues.push(_M)
data.selectedValues.push(_D)
data.selectedValues.push(_h)
data.selectedValues.push(_m)
data.selectedValues.push(_s)
data.columns.push(year) //生成年列
}
if (data.showType.includes('month')) {
let month = [] //获取12月数组
let allMon = []
if (data.minDate && minYear == Y) {
let minMon = new Date(data.minDate).getMonth()
let allM = Object.keys(Array.apply(null, { length: 13 }))
allMon = allM.filter(item => item >= minMon)
} else {
allMon = Object.keys(Array.apply(null, { length: 13 }))
}
month = allMon.map(function(item) {
if (+item + 1 <= 10) {
return { text: '0' + item, value: '0' + item }
} else if (+item + 1 == 11) {
return { text: +item, value: +item }
} else {
return {
text: (+item + 0).toString(),
value: (+item + 0).toString()
}
}
})
month.splice(0, 1)
data.columns.push(month) //生成月列
}
if (data.showType.includes('day')) {
//获取当月的天数
let days = getCountDays(Y, M + 1)
let day = [] //创建当月天数数组
let allDays = []
if (data.minDate && minYear == Y) {
let minDay = new Date(data.minDate).getDate()
let allD = Object.keys(Array.apply(null, { length: days + 1 }))
allDays = allD.filter(item => item >= minDay)
} else {
allDays = Object.keys(Array.apply(null, { length: days + 1 }))
}
day = allDays.map(function(item) {
if (+item + 1 <= 10) {
return { text: '0' + item, value: '0' + item }
} else if (+item + 1 == 11) {
return { text: +item, value: +item }
} else {
return {
text: (+item + 0).toString(),
value: (+item + 0).toString()
}
}
})
day.splice(0, 1)
data.columns.push(day) //生成日列
}
if (data.showType.includes('hour')) {
let hour = [] //创建小时数组
let allHour = []
if (data.minDate && minYear == Y) {
let minHour = new Date(data.minDate).getHours() ? new Date(data.minDate).getHours(): new Date().getHours()
let allH = Object.keys(Array.apply(null, { length: 24 }))
allHour = allH.filter(item => item >= minHour)
} else {
allHour = Object.keys(Array.apply(null, { length: 24 }))
}
hour = allHour.map(function(item) {
if (+item + 1 <= 10) {
return { text: '0' + item, value: '0' + item }
} else if (+item + 1 == 11) {
return { text: +item, value: +item }
} else {
return {
text: (+item + 0).toString(),
value: (+item + 0).toString()
}
}
})
data.columns.push(hour) //生成小时列
}
if (data.showType.includes('minute')) {
let mi = [] //创建分钟数组
let allMi = []
if (data.minDate && minYear == Y) {
let minMi = new Date(data.minDate).getMinutes() ? new Date(data.minDate).getMinutes() : new Date().getMinutes()
let allM = Object.keys(Array.apply(null, { length: 60 }))
allMi = allM.filter(item => item >= minMi)
} else {
allMi = Object.keys(Array.apply(null, { length: 60 }))
}
mi = allMi.map(function(item) {
if (+item + 1 <= 10) {
return { text: '0' + item, value: '0' + item }
} else if (+item + 1 == 11) {
return { text: +item, value: +item }
} else {
return {
text: (+item + 0).toString(),
value: (+item + 0).toString()
}
}
})
data.columns.push(mi)//生成分钟列
}
if (data.showType.includes('second')) {
let ss = [] //创建秒数数组
let allSS = []
if (data.minDate && minYear == Y) {
let minSS = new Date(data.minDate).getSeconds() ? new Date(data.minDate).getSeconds() : new Date().getSeconds()
let allS = Object.keys(Array.apply(null, { length: 60 }))
allSS = allS.filter(item => item >= minSS)
} else {
allSS = Object.keys(Array.apply(null, { length: 60 }))
}
ss = allSS.map(function(item) {
if (+item + 1 <= 10) {
return { text: '0' + item, value: '0' + item }
} else if (+item + 1 == 11) {
return { text: +item, value: +item }
} else {
return {
text: (+item + 0).toString(),
value: (+item + 0).toString()
}
}
})
data.columns.push(ss)//生成秒钟列
}
}
//时间选择器关闭 值不改变并关闭弹框
function cancelOn({ selectedValues }) {
confirmOn()
}
// 时间选择器确定 值改变
function onConfirm({ selectedValues }) {
let endval =
selectedValues[0] +
'-' +
selectedValues[1] +
'-' +
selectedValues[2] +
' ' +
selectedValues[3] +
':' +
selectedValues[4] +
':' +
selectedValues[5]
confirmOn()
emit('confirm', endval)
}
</script>
<template>
<div>
<van-field
v-model='innerValueName'
readonly
is-link
label='药品名称:'
placeholder='请选择'
class='input-back mt-2 form-input w-full'
:rules="[{required: true, message:'请选择'}]"
@click='showDrug= true'
/>
<van-popup v-model:show='showDrug' position='bottom'>
<div class='pb-4 pr-4 pl-4'>
<van-picker
:columns='array'
:columns-field-names='fieldNames'
@confirm='drugConfirm'
@cancel='showDrug = false'
>
<template #columns-top>
<van-search v-model="searchStr" :placeholder='placeholder' @search='onSearch' clearable/>
</template>
</van-picker>
</div>
</van-popup>
</div>
</template>
<script>
import { getDrug } from '@/api/doctor/generalFU'
import { debounce } from '@/utils/common'
export default {
name: 'DocDrug',
props: {
value: [String, Number],
valueName: String,
placeholder: String,
fieldNames: {
type: Object,
default: () => {
return { text: 'chemicalName', value: 'id' }
}
}
},
emits: ['update:value', 'change'],
data() {
return {
innerValue: null,
innerValueName: undefined,
array: [],
loading: false,
showDrug: false,
searchStr: ''
}
},
created() {
this.onSearch = debounce(this.onSearch, 500)
this.onSearch('')
},
methods: {
onSearch(value) {
if (this.loading) return
this.array = []
if (!value) {
return
}
if (!value.trim()) return
this.loading = true
getDrug(value).then(res => {
this.array = res.data || []
if (this.array.length && this.innerValue) {
let list = this.array.filter(item => item.id == this.innerValue)
if (list && list.length) {
this.innerValueName = list[0].chemicalName
}
}
}).finally(() => {
this.loading = false
})
},
drugConfirm({ selectedOptions }) {
this.innerValueName = selectedOptions[0].chemicalName
this.$emit('update:value', selectedOptions[0].id)
this.$emit('change', selectedOptions[0])
this.searchStr = ''
this.showDrug = false
}
},
watch: {
value: {
handler(value) {
this.innerValue = value
},
immediate: true
},
valueName: {
handler(value) {
if (!value) {
return
}
this.onSearch(value)
},
immediate: true
},
searchStr: {
handler(val) {
if (!val) return
this.onSearch(val)
}
}
}
}
</script>
<style lang='less' scoped>
.form-input {
padding: 8px 12px;
border-radius: 8px;
}
.input-back {
background: #FAFAFA;
}
//灰色
.greyColor {
color: var(--van-text-color-2);
}
//确认按钮颜色
.blueColor {
color: var(--van-primary-color)
}
</style>
<template>
<div class="doc-image">
<div v-if="isPdf" class="p-2 flex items-center view-pdf">
<doc-icon type="doc-PDF" style="font-size: .48rem" class="shrink-0"/>
<span class="grow px-4 text-ellipsis">{{name}}</span>
<span class="close-btn" @click.stop="removeBtn" v-if="remove">
<doc-icon type="close-circle" />
</span>
</div>
<div class="view-img" v-if="status==='success' && !isPdf">
<img :src="src" :alt="name"
:loading="loading" >
</div>
<template v-if="!isPdf">
<div class="doc-image-wrapper" v-if="status==='loading'">
<slot name="placeholder">
<div class="doc-image-default">加载中...</div>
</slot>
</div>
<div class="doc-image-wrapper" v-if="status==='fail'">
<slot name="fail">
<div class="doc-image-default">加载失败</div>
</slot>
</div>
<span class="close-btn" @click.stop="removeBtn" v-if="remove">
<doc-icon type="close-circle" />
</span>
</template>
</div>
</template>
<script>
export default {
name: 'doc-image',
props: {
src: String,
// 浏览器应当如何加载该图像
// img标签中的属性 需要浏览器支持
// https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/img
// eager 立即加载图像
// lazy 延迟加载图像,直到它和视口接近到一个计算得到的距离
loading: String,
// 开启删除功能
remove: Boolean,
// 处理pdf预览
isPdf: Boolean,
name: String
},
emits: ['removeBtn'],
data() {
return {
// 图片加载状态 loading | fail | success
status: 'loading',
imgStyle: {},
// viewer显示
visible: false,
// 按键界面显示
btVisible: false
}
},
methods: {
loadImage() {
if (this.isPdf) {
this.status = 'success'
return
}
const image = new Image()
image.onload = () => {
this.show = true
this.status = 'success'
}
image.onerror = (err) => {
console.warn('doc-image', err)
this.show = false
this.status = 'fail'
}
this.status = 'loading'
image.src = this.src
},
removeBtn() {
this.btVisible = false
this.$emit('onRemove', this.src)
}
},
watch: {
src: {
handler(val) {
if (val) {
this.loadImage()
}
},
immediate: true
}
}
}
</script>
<style lang="less" scoped>
.doc-image {
display: inline-block;
width: 100%;
height: 100%;
position: relative;
.view-img {
width: 100%;
height: 100%;
min-height: 90px;
border: 1px dashed #d9d9d9;
background: #fafafa;
img {
width: 100%;
height: 90px;
object-fit: contain;
}
}
.view-pdf {
width: 100%;
min-height: 48px;
overflow-y: hidden;
border-radius: 8px;
border: 1px solid #EEEEEE;
.close-btn {
top: 50%;
right: 8px;
transform: translateY(-50%);
}
}
.close-btn {
position: absolute;
font-size: 16px;
top: -8px;
right: -8px;
}
}
.doc-image-wrapper {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.doc-image-default {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
background: #f5faf7;
color: #a8abb2;
vertical-align: middle;
user-select: none;
}
</style>
<template> <template>
<div class="doc-image-upload"> <div class='doc-image-upload'>
<div class="text-12 description">{{ description }}</div> <div class='text-12 description'>{{ description }}</div>
<div class="mt-2 py-3 text-center upload-btn" @click="fileSelect"> <div class='mt-2 py-3 text-center upload-btn' @click='fileSelect'>
<doc-icon type="doc-upload" class="mr-2 text-16"/> <doc-icon type='doc-upload' class='mr-2 text-16' />
<span>{{ btText }}</span> <span>{{ btText }}</span>
</div> </div>
<div class="flex flex-wrap justify-between mt-4 image-box"> <div class='flex flex-wrap mt-4 image-box'>
<div v-for="item in innerImage" :key="item.id"> <div v-for="item in innerImage.filter(e => e.fileType != 'pdf')" :key='item.id'
<div v-if="item.fileType === 'pdf'" class=""> class='item-img' @click.stop='toPreview(item)'>
<doc-icon type="doc-PDF" /> <DocImage :src='item.trueDownloadUrl' remove @onRemove='removeImage(item)' />
</div> </div>
<div v-else> <div v-for="item in innerImage.filter(e => e.fileType == 'pdf')" :key='item.id'
<img src="@/assets/image/doctor/empty.png" style="width: 100%"/> class='item-pdf'>
</div> <DocImage isPdf :src='item.trueDownloadUrl' name='pdf文件名称' remove @onRemove='removeImage(item)' />
<span class="close-btn" @click="removeImage(item)">
<doc-icon type="close-circle" />
</span>
</div> </div>
</div> </div>
<input type="file" <!-- accept='.jpg,.jpeg,.png,.pdf' -->
accept=".jpg,.jpeg,.png,.pdf" <input type='file'
ref="fileElem" accept="image/*"
style="display: none;" ref='fileElem'
@change="handleFiles" style='display: none;'
:key="inputKey"> @change='handleFiles'
:key='inputKey'>
<van-overlay :show='imgShow' @click='imgShow = false'>
<div class='wrapper'>
<van-swipe class='block' :initial-swipe='initSwipe'>
<van-swipe-item v-for="image in innerImage.filter(e => e.fileType != 'pdf')" :key='image'>
<img :src='image.trueDownloadUrl' style='width: 100%;height: 100%' />
</van-swipe-item>
</van-swipe>
</div>
</van-overlay>
</div> </div>
</template> </template>
<script> <script>
import DocImage from './DocImage.vue'
import { showToast } from 'vant' import { showToast } from 'vant'
import { fileUpload } from '@/api/base'
export default { export default {
name: 'DocImageUpload', name: 'DocImageUpload',
components: {
DocImage
},
props: { props: {
// 上传描述 // 上传描述
description: { default: '温馨提示:请上传JPG、PNG格式图片,文件大小不超过5M' }, description: { default: '温馨提示:请上传JPG、PNG格式图片,文件大小不超过10M' },
// 传入的img数据 { id, trueDownloadUrl } // 传入的img数据 { id, trueDownloadUrl }
imageData: { default: () => [] }, imageData: { default: () => [] },
// 上传按键的文字 // 上传按键的文字
...@@ -53,7 +66,10 @@ export default { ...@@ -53,7 +66,10 @@ export default {
spinning: false, spinning: false,
inputKey: '1', inputKey: '1',
// viewer显示 // viewer显示
visible: false visible: false,
//显示图片所在位置
initSwipe: 0,
imgShow: false
} }
}, },
computed: { computed: {
...@@ -64,15 +80,16 @@ export default { ...@@ -64,15 +80,16 @@ export default {
return this.innerImage.map(e => e.id).join(',') return this.innerImage.map(e => e.id).join(',')
} }
}, },
methods:{ methods: {
init() { init() {
if (this.imageData?.length) { if (this.imageData?.length) {
this.innerImage = [...this.imageData] this.innerImage = [...this.imageData]
} else { } else {
this.innerImage = [ this.innerImage = [
{ fileType: 'pdf', id: 1 }, // { fileType: 'pdf', id: 1, trueDownloadUrl: testUrl },
{ fileType: 'png', id: 2 }, // { fileType: 'png', id: 2, trueDownloadUrl: testUrl },
{ fileType: 'png', id: 3 } // { fileType: 'png', id: 3, trueDownloadUrl: testUrl },
// { fileType: 'png', id: 4, trueDownloadUrl: testUrl }
] ]
} }
}, },
...@@ -98,7 +115,6 @@ export default { ...@@ -98,7 +115,6 @@ export default {
this.addImage(result) this.addImage(result)
this.inputKey = Math.random().toString(16).substring(2, 6) this.inputKey = Math.random().toString(16).substring(2, 6)
this.$emit('change', this.ids, this.innerImage) this.$emit('change', this.ids, this.innerImage)
this.formItemContext.onFieldChange()
}).finally(() => { }).finally(() => {
this.spinning = false this.spinning = false
}) })
...@@ -109,8 +125,8 @@ export default { ...@@ -109,8 +125,8 @@ export default {
showToast('未选中文件,请尝试重新选择') showToast('未选中文件,请尝试重新选择')
return return
} }
if (files[0].size / 1024 / 1024 > 5) { if (files[0].size / 1024 / 1024 > 10) {
showToast('图片大小不能超过5M') showToast('图片大小不能超过10M')
return return
} }
this.file = files[0] this.file = files[0]
...@@ -129,6 +145,13 @@ export default { ...@@ -129,6 +145,13 @@ export default {
if (!item) return if (!item) return
this.innerImage = this.innerImage.filter(e => e.id != item.id) this.innerImage = this.innerImage.filter(e => e.id != item.id)
this.$emit('change', this.ids, this.innerImage) this.$emit('change', this.ids, this.innerImage)
},
//图片预览
toPreview(val) {
let res = this.innerImage.filter(e => e.fileType != 'pdf')
let index = res.findIndex(e => val.id == e.id)
this.initSwipe = index
this.imgShow = true
} }
}, },
watch: { watch: {
...@@ -142,31 +165,49 @@ export default { ...@@ -142,31 +165,49 @@ export default {
} }
</script> </script>
<style lang="less" scoped> <style lang='less' scoped>
.description { .description {
color: #A5AEBE; color: #A5AEBE;
} }
.upload-btn { .upload-btn {
color: var(--van-primary-color); color: var(--van-primary-color);
border: 1px solid #eee; border: 1px solid #eee;
background-color: #FAFAFA; background-color: #FAFAFA;
border-radius: 8px; border-radius: 8px;
} }
.image-box { .image-box {
>div { row-gap: 8px;
width: calc(33.3vw - 8px); column-gap: 12px;
.item-img {
width: calc(33.3% - 8px);
}
.item-pdf {
width: 100%;
}
> div {
width: calc(33.3% - 8px);
position: relative; position: relative;
border: 1px solid #999;
border-radius: 2px; border-radius: 2px;
img { img {
object-fit: contain; object-fit: contain;
} }
} }
.close-btn { }
position: absolute;
font-size: 16px; .wrapper {
top: -8px; display: flex;
right: -8px; align-items: center;
justify-content: center;
height: 100%;
.block {
width: 100%;
} }
} }
</style> </style>
<template>
<div class="px-3 py-3 flex items-center doc-nav-bar">
<div class="shrink-0 left">
<slot name="left">
<span class="back-btn" @click="goBack">
<doc-icon type="doc-left-1" style="color: #262626"/>
</span>
</slot>
</div>
<div class="grow text-center font-semibold title">
<slot>
{{title}}
</slot>
</div>
<div class="shrink-0 right">
<slot name="right"></slot>
</div>
</div>
</template>
<script>
import { backHome } from '@/utils/common.js'
export default {
name: 'DocNavBar',
props: {
title: String,
// 是否首页
home: Boolean
},
methods: {
goBack() {
if (this.home) {
backHome()
return
}
this.$router.back()
}
}
}
</script>
<style lang="less" scoped>
.doc-nav-bar {
background: transparent;
border-bottom: 1px solid #00000019;
.left {
min-width: 24px;
}
.title {
font-size: 16px;
}
}
</style>
<template> <template>
<van-popup :show="innerShow" position="bottom" <van-popup :show="innerShow" position="bottom"
:teleport="teleport"
class="doc-unit"> class="doc-unit">
<van-picker :loading="loading" <van-picker :loading="loading"
title="机构选择" title="机构选择"
...@@ -32,7 +33,8 @@ export default { ...@@ -32,7 +33,8 @@ export default {
default: () => { default: () => {
return {text: 'unitName', value: 'id'} return {text: 'unitName', value: 'id'}
} }
} },
teleport: [String, Element]
}, },
emits: ['update:show', 'update:value', 'change'], emits: ['update:show', 'update:value', 'change'],
data() { data() {
......
<template>
<van-uploader :max-size="5 * 1024 * 1024" :after-read="afterRead" max-count="1"
class="id-card-scan">
<slot>
<doc-icon type="doc-scan" class="shrink-0 mr-3 text-primary"/>
</slot>
</van-uploader>
</template>
<script>
import { showNotify } from 'vant'
export default {
name: 'IdCardScan',
emits: ['change'],
methods: {
// 证件上传后
afterRead(file) {
console.log(file)
showNotify({ type: 'primary', message: '文件上传' })
this.$emit('change', file)
}
}
}
</script>
<style lang="less" scoped>
</style>
<template>
<div>
<div class='list gap-x-2.5 gap-y-1 flex items-center flex-wrap'>
<div v-for="(url, index) in imgList" :key="index" @click='toPreview(index)'>
<img style='width: 1.47rem;height: 2.04rem' :src="url.trueDownloadUrl" />
</div>
</div>
<van-overlay :show='imgShow' @click='imgShow = false'>
<div class='wrapper'>
<van-swipe class='block' :initial-swipe='initSwipe'>
<van-swipe-item v-for='image in imgList' :key='image'>
<img :src='image.trueDownloadUrl' style='width: 100%;height: 100%'/>
</van-swipe-item>
</van-swipe>
</div>
</van-overlay>
</div>
</template>
<script>
export default {
name: 'imagePreview',
props: {
imgList: Array,
},
data() {
return {
imgShow: false,
initSwipe: 0
}
},
methods: {
//图片预览
toPreview(index) {
this.initSwipe = index
this.imgShow = true
},
}
}
</script>
<style scoped lang='less'>
.wrapper {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
.block {
width: 100%;
}
}
</style>
\ No newline at end of file
<template>
<div class="p-1 flex flex-col mp3">
<div v-if="file.annexFileName" class="text-12 mb-1 text-ellipsis">{{ file.annexFileName }}</div>
<div class="flex items-center justify-between gap-x-2.5">
<div class="shrink-0 play-bt" @click.stop="start(file)">
<doc-icon type="doc-play" v-if="!player.playing"/>
<doc-icon type="doc-pause" v-else/>
</div>
<span class="shrink-0 time">{{timeFormat(player.duration)}}</span>
<div class="grow progress">
<van-slider v-model="player.currentTime" :max="sliderMax" :bar-height="6" :button-size="0"
@change="onProgress" />
<!-- <div :style="`width: ${progress}%`"></div> -->
</div>
<span class="shrink-0 time" :style="`opacity: ${player.currentTime ? 1 : 0}`">
{{ timeFormat(player.currentTime) }}</span>
<span class="text-16 shrink-0 close-btn" @click.stop="removeBtn" v-if="remove">
<doc-icon type="close-circle" />
</span>
</div>
<audio ref="audio" type="audio/mpeg" crossOrigin="anonymous" preload="metadata" style="display: none"></audio>
</div>
</template>
<script>
import { musicPlayer } from './mp3.js'
import { showToast } from 'vant'
import { useStore } from '@/doctor/store/index.js'
export default {
props: {
file: { default: () => ({}) },
activeMediaUrl: { default: '' },
remove: Boolean
},
emits: ['play', 'onRemove'],
data() {
return {
store: useStore(),
player: {},
// 正在播放的items
activeAudio: {},
}
},
computed: {
sliderMax() {
return this.player.duration ? Math.floor(this.player.duration) : 100
},
progress() {
if (!this.player.currentTime) return 0
const temp = this.player.currentTime / this.player.duration
return Math.round(temp * 1000) / 10
}
},
mounted() {
this.init()
},
methods: {
init() {
this.player = new musicPlayer(this.$refs.audio)
this.player.init()
this.player.setSrc(this.file.annexUrl)
this.player.audioEl.onended = () => {
console.log('播放结束')
this.stop()
}
},
start(item) {
if (!item || !item.annexUrl) {
showToast('文件获取失败')
return
}
if (!this.player.audioCtx) {
this.player.init()
this.player.setSrc(item.annexUrl)
}
if (this.player.playing) {
this.stop()
} else {
this.player.audioEl.play()
this.activeAudio = item
this.player.playing = true
this.$emit('play', item)
console.log('this.player.duration', this.player.audioEl.duration)
}
console.log('this.player', this.player)
},
stop() {
this.player.audioEl.pause()
this.player.playing = false
},
timeFormat(value) {
if (!value || value == Infinity) {
return '00:00'
}
let date = Math.ceil(parseFloat(value))
let minutes = Math.floor(date / 60)
let seconds = date % 60
let format = `${minutes >= 10 ? minutes : '0' + minutes.toString()}:${seconds >= 10 ? seconds : '0' + seconds.toString()}`
return format
},
onProgress(value) {
this.player.progressChange(value)
this.player.playing = true
},
removeBtn() {
this.$emit('onRemove', this.file)
}
},
watch: {
activeMediaUrl(val) {
if (val !== this.file.annexUrl) {
this.stop()
}
},
'store.documentHidden': {
handler(val) {
if (val && this.activeMediaUrl == this.file.annexUrl) {
this.stop()
}
}
}
}
}
</script>
<style lang="less" scoped>
.mp3 {
background-color: #fff;
.play-bt {
display: inline-flex;
width: 24px;
height: 24px;
align-items: center;
justify-content: center;
border-radius: 50%;
background-color: #E4F2F0;
font-size: 10px;
padding-left: 2px;
color: var(--van-primary-color);
}
.progress {
// height: 6px;
// border-radius: 4px;
// background: #EFF2F7;
// overflow: hidden;
// text-align: left;
// >div {
// height: 100%;
// background: #54CCBD;
// }
}
}
</style>
<template>
<div class="mp4">
<div class="flex flex-wrap justify-between video-list">
<div v-for="item in files" :key="item.annexId" @click.stop="start(item)">
<div class="item">
<div class="shrink-0 play-bt" >
<doc-icon type="doc-play" />
</div>
<span class="close-btn" @click.stop="removeBtn(item)" v-if="remove">
<doc-icon type="close-circle" />
</span>
</div>
<div v-if="item.annexFileName" class="text-12 my-1 text-ellipsis">{{ item.annexFileName }}</div>
</div>
</div>
<!-- <van-popup v-model:show="visible" :close-on-click-overlay="false" closeable
close-icon-position="top-right"
close-icon="clear">
<video controls v-if="visible" style="width: calc(100vw - var(--van-padding-md) * 2)">
<source :src="activeVideo.annexUrl" type="video/mp4" />
播放失败!
</video>
</van-popup> -->
<van-overlay :show="visible">
<div class="h-full flex items-center justify-center wrapper" @click.stop>
<video controls v-if="visible" ref="video">
<source :src="activeVideo.annexUrl" type="video/mp4" />
播放失败!
</video>
<van-icon name="close" class="close-icon" @click="visible = false"/>
</div>
</van-overlay>
</div>
</template>
<script>
import { useStore } from '@/doctor/store/index.js'
export default {
props: {
files: { default: () => [] },
activeMediaUrl: { default: '' },
remove: Boolean
},
emits: ['play', 'onRemove'],
data() {
return {
visible: false,
activeVideo: {},
store: useStore()
}
},
methods: {
start(item) {
this.activeVideo = item
this.visible = true
this.$emit('play', item)
},
removeBtn(item) {
this.$emit('onRemove', item)
}
},
watch: {
activeMediaUrl(val) {
if (val !== this.activeVideo.annexUrl) {
const dom = this.$refs.video
dom && dom.pause()
}
},
'store.documentHidden': {
handler(val) {
if (val && this.activeMediaUrl == this.activeVideo.annexUrl) {
const dom = this.$refs.video
dom && dom.pause()
}
}
}
}
}
</script>
<style lang="less" scoped>
.video-list {
>div {
width: calc(50% - 5px);
.item {
position: relative;
background: url('@/assets/image/residentWX/video-default.png') no-repeat;
background-size: 100%;
height: .84rem;
display: flex;
align-items: center;
justify-content: center;
}
}
.play-bt {
display: inline-flex;
width: 36px;
height: 36px;
align-items: center;
justify-content: center;
border-radius: 50%;
background-color: #E4F2F0;
font-size: 15px;
padding-left: 2px;
color: var(--van-primary-color);
}
.close-btn {
position: absolute;
font-size: 16px;
top: -8px;
right: -8px;
}
}
.wrapper {
position: relative;
.close-icon {
position: absolute;
top: 16px;
right: 16px;
color: #ccc;
font-size: 24px;
}
video {
width: calc(100vw - var(--van-padding-md) * 2);
background-color: #fff;
}
}
</style>
export class musicPlayer {
constructor(audioEl) {
this.audioEl = audioEl
// 音频上下文
this.audioCtx = null
// 音源
this.audioSource = null
// 时长
this.duration = 0
// 当前播放时间
this.currentTime = 0
// 播放进度
this.progress = 0
// 声音
this.volume = 20
// AnalyserNode 接口表示了一个可以提供实时频域和时域分析信息的节点
this.analyser = null
// 音量节点
this.gainNode = null
// 缓冲进度
this.timeRange = null
// 是否播放中
this.playing = false
}
init() {
// 音频上下文
this.audioCtx = new (window.AudioContext || window.webkitAudioContext)()
if (!this.audioCtx) {
throw new Error('audioCtx is null')
}
// 获取音频数据的节点
this.analyser = this.audioCtx.createAnalyser()
// 音量节点
this.gainNode = this.audioCtx.createGain()
this.gainNode.gain.value = 1
this.audioEl.volume = this.volume / 100
// 从<audio>或<video>元素生成的音频源
this.audioSource = this.audioCtx.createMediaElementSource(this.audioEl)
this.audioEl.ontimeupdate = () => {
this.currentTime = this.audioEl.currentTime
if (this.progress >= this.duration) return
this.progress = this.currentTime
}
this.audioEl.onloadedmetadata = () => {
// 时长
this.duration = this.audioEl.duration
console.log('onloadedmetadata', this.duration)
}
this.audioEl.onprogress = () => {
// 当浏览器正在下载音频/视频时
this.timeRange = this.audioEl.buffered
if (this.timeRange && this.timeRange.length > 0) {
console.log(
'buffered',
this.audioEl.buffered.start(0),
this.audioEl.buffered.end(0)
)
}
}
this.audioEl.oncanplay = () => {
console.log('可播放')
setTimeout(() => {
this.getAudioSource()
}, 100)
}
this.audioEl.onerror = (e) => {
console.error('加载出现错误', e)
this.onerror(e)
}
}
onerror() {}
onended() {}
setSrc(src) {
this.progress = 0
this.audioEl.src = src
this.audioEl.load()
}
// 调整进度
progressChange(value) {
this.audioEl.currentTime = value
}
// 调整音量
volumeChange(value) {
this.volume = value
this.audioEl.volume = this.volume / 100
}
// 音频波形处理
getAudioSource() {
// 节点链接到音源
this.audioSource.connect(this.analyser)
// 链接音量节点
this.analyser.connect(this.gainNode)
this.gainNode.connect(this.audioCtx.destination)
return
// 使用快速傅立叶变换(Fast Fourier Transform (FFT) )来捕获音频数据
// this.analyser.fftSize = 2048
this.analyser.fftSize = 256
let bufferLength = this.analyser.frequencyBinCount
let dataArray = new Uint8Array(bufferLength)
let c = this.boardEl
let canvasWidth = c.width
let canvasHeight = c.height
let ctx = c.getContext('2d')
let left = this
ctx.strokeStyle = 'rgba(81,167,255, .5)'
drawBar()
function drawBar() {
// 波形绘制
ctx.clearRect(0, 0, canvasWidth, canvasHeight)
let barWidth = (canvasWidth / bufferLength) * 1
let barHeight = 0
let x = 0
left.analyser.getByteFrequencyData(dataArray)
for (let i = 0; i < bufferLength; i++) {
barHeight = dataArray[i] / 2
let tempColor = barHeight * 3 > 255 ? 255 : barHeight * 3
ctx.fillStyle = 'rgba(' + tempColor + ', 160, 255, .5)'
ctx.fillRect(x, canvasHeight - barHeight / 2, barWidth, barHeight)
x += barWidth + 0.1
}
requestAnimationFrame(drawBar)
}
}
}
<template>
<van-popup v-if='innerShow' v-model:show='innerShow' position='right' :style="{ height: '100%', width: '100%' }">
<div class='flex flex-col' style='height: 100vh'>
<div class='p-3 text-black text-center shrink-0 doc-nav-bar'>
<span @click='onBack' class='text-12 back-bt'>
<doc-icon type='doc-left2' />
</span>
<span>查看内容</span>
</div>
<div class='grow overflow-y-auto pl-4 pr-4 pt-3 pb-3'>
<!-- {{fileType}}-->
<div>
<div class='flex flex-col '>
<!-- 文本 -->
<div class='card' v-if='contentList?.length' @click.stop='selectFiletype(1)'>
<div class='flex justify-between items-center'>
<div class='font-semibold mb-1'>文本</div>
<van-checkbox-group v-model="fileType" shape="square" icon-size="16px" >
<van-checkbox :name="1" @click.stop='()=> {}'></van-checkbox>
</van-checkbox-group>
</div>
<div class='conten-bg'>
<div v-for='item in contentList' :key='item.templateMode' class='mb-1 flex'
:style='`order: ${item.templateMode}`'>
<span class='shrink-0 mr-1'
v-if="item.templateModeTrans != '无'">{{ item.templateModeTrans }} :</span>
<span> {{ item.templateContent }}</span>
</div>
</div>
</div>
</div>
<div class='card mt-4' v-if='mp4List?.length' @click='selectFiletype(3)'>
<div class='flex justify-between items-center'>
<div class='font-semibold mb-1'>视频</div>
<van-checkbox-group v-model="fileType" shape="square" icon-size="16px">
<van-checkbox :name="3" @click.stop='()=> {}'></van-checkbox>
</van-checkbox-group>
</div>
<div class='conten-bg'>
<Mp4 :files='mp4List' :activeMediaUrl='activeMediaUrl'
@play='e => activeMediaUrl = e.annexUrl' />
</div>
</div>
<div class='card flex flex-col mt-4' style='row-gap: .06rem;' v-if='mp3List?.length' @click='selectFiletype(2)'>
<div class='flex justify-between items-center'>
<div class='font-semibold mb-1'>音频</div>
<van-checkbox-group v-model="fileType" shape="square" icon-size="16px">
<van-checkbox :name="2" @click.stop='()=> {}'></van-checkbox>
</van-checkbox-group>
</div>
<div class='conten-bg'>
<Mp3 :file='item' v-for='item in mp3List' :key='item.annexId'
:activeMediaUrl='activeMediaUrl'
@play='e => activeMediaUrl = e.annexUrl' />
</div>
</div>
</div>
</div>
<div class='bbtn'>
<van-button type='primary' @click='toUse'>引用</van-button>
</div>
</div>
</van-popup>
</template>
<script>
import { showToast } from 'vant'
import { getTemplateDetail } from '@/api/doctor/workbench'
import Mp3 from '@/doctor/components/mediaPlay/Mp3.vue'
import Mp4 from '@/doctor/components/mediaPlay/Mp4.vue'
export default {
name: 'temDetail',
components: { Mp4, Mp3 },
props: {
show: { default: false },
id: String
},
data() {
return {
info: {},
activeMediaUrl: '',
fileType: [1, 2, 3],
}
},
computed: {
innerShow() {
return this.show
},
contentList() {
return this.info.contentList
},
// 文件内容
annexList() {
return this.info?.annexList || []
},
mp3List() {
return this.annexList.filter(e => e.type == 2)
},
mp4List() {
return this.annexList.filter(e => e.type == 3)
}
},
created() {
this.load()
},
methods: {
async load() {
if (!this.id) {
showToast('未获取到信息')
return
}
let par = {
id: this.id
}
getTemplateDetail(par).then(res => {
let result = res.data || {}
this.info = result
}).finally(() => {
})
},
selectFiletype(val) {
let index = this.fileType.findIndex(item => item == val)
if (index >= 0) {
this.fileType = this.fileType.filter(item => item != val)
} else {
this.fileType.push(val)
}
},
toUse() {
this.$emit('selectedInfo', this.id, this.fileType)
this.onBack()
},
onBack() {
this.$emit('closeDetail', false)
}
}
}
</script>
<style scoped lang='less'>
@import url('../../utils/common.less');
.bbtn {
padding: 8px 12px;
border-top: 1px solid #D7D8DA;
button {
width: 100%;
border-radius: 100px
}
}
.card {
border: 1px solid #CFD5DE;
padding: 8px;
border-radius: 8px;
color: #262626;
}
.conten-bg {
background: #F8FAFC;
padding: 6px 10px;
border-radius: 4px;
}
</style>
\ No newline at end of file
<template>
<van-popup v-model:show='innerShow' position='right' :style="{ height: '100%', width: '100%' }" :overlay='false' >
<div class='bg flex flex-col'>
<div class='p-3 flex items-center shrink-0 justify-between title bg-white'>
<div @click='onBack' class='text-12 back-bt'>
<doc-icon type='doc-left2' />
</div>
<div>选择内容</div>
<div class='text-primary left-btn' @click='openSearch'>筛查</div>
</div>
<div class='grow p-10 overflow-y-auto' ref='list'>
<van-pull-refresh v-model='loadingRefresh' @refresh='onRefresh'
:disabled='isRefreshDisable' style='min-height: 100%'>
<van-list
v-model:loading='loading'
:finished='finished'
:finished-text="list.length ? '没有更多了' : ''"
:immediate-check='false'
@load='onMore'
>
<div class='flex flex-col gap-y-2.5'>
<div class='py-3 px-4 doc-list-card' v-for='item in list' :key='item.id'>
<div class='flex flex-col gap-y-2.5'>
<div>
<span class='label'>模板分类</span>
<span>{{ item.templateClassifyTrans }}</span>
</div>
<div>
<span class='label'>模板名称</span>
<span>{{ item.templateName }}</span>
</div>
</div>
<div class='divider my-3'></div>
<div class='bt-group'>
<van-button round size='small' class='doc-btn-primary mr-3'
@click='toDetail(item)'>查看
</van-button>
<van-button round size='small' class='doc-btn-primary' @click='toUse(item)'>
引用
</van-button>
</div>
</div>
</div>
</van-list>
<div class='text-center shrink-0 empty' v-if='!list.length'>
<img src='@/assets/image/doctor/empty.png' alt='' style='width: 1.2rem;'>
<p>暂无数据</p>
</div>
</van-pull-refresh>
<van-popup v-model:show='searchVisible' position='top' :style="{ height: '60%' }"
style='position: absolute;transition: none'
:overlay-style="{ position: 'absolute' }"
transition='viewer-fade'
:teleport='listDom'>
<div class='h-full flex flex-col workbench-search-box'>
<div class='px-4 py-3 grow overflow-y-auto' style=''>
<van-field v-model='form.templateName' placeholder='请输入要查询的模板名称' maxlength='100'
class='doc-input' />
<div class='my-3'>模板分类(仅单选)</div>
<CheckBtn :options="store.getDict('DC00082')" v-model:value='form.templateClassify' column-3
class='check-btn-workbench' />
<div class='my-3'>文件类型(可多选)</div>
<CheckBtn multiple :options="store.getDict('DC00093')" v-model:value='form.fileType' column-3
class='check-btn-workbench' />
<div class='my-3'>共享类型(仅单选)</div>
<CheckBtn :options="store.getDict('DC00053')" v-model:value='form.templateType' column-3
class='check-btn-workbench' />
</div>
<div class='text-16 flex shrink-0 text-center bt-group'>
<div class='grow py-3' @click='reset'>重置</div>
<div class='grow py-3 submit-btn' @click='search'>确定</div>
</div>
</div>
</van-popup>
<!-- 查看详情组件-->
<temDetail v-if='detailShow && innerShow'
:show='detailShow'
:id='selectRecord.id'
@closeDetail='detailClosed'
@selectedInfo='detailToUse'
:overlay='false'
></temDetail>
</div>
</div>
</van-popup>
</template>
<script>
import { showToast } from 'vant'
import CheckBtn from '@/doctor/components/checkBtn/CheckBtn'
import { getTemplateByPage } from '@/api/doctor/workbench'
import { useStore } from '@/doctor/store'
import TemDetail from '@/doctor/components/template/temDetail'
const DefaultForm = () => {
return {
templateName: undefined,
templateClassify: undefined,
//慢病
businessType: 1,
//文件类型
fileType: [],
//共享类型
templateType: 1
}
}
export default {
name: 'temList',
components: { TemDetail, CheckBtn },
props: {
show: { default: false },
templateClassify: Number,
},
data() {
return {
store: useStore(),
list: [],
pagination: {
total: 0,
pageIndex: 1,
pageSize: 8
},
loading: false,
finished: false,
loadingRefresh: false,
isRefreshDisable: false,
// 搜索弹出框
searchVisible: false,
form: DefaultForm(),
//是否展示详情弹窗
detailShow: false,
//选中项
selectRecord: {}
}
},
computed: {
innerShow() {
return this.show
},
listDom() {
return this.$refs.list
}
},
created() {
this.form.templateClassify = this.templateClassify
this.load()
},
mounted() {
const list = this.$refs.list
if (list) {
list.addEventListener('scroll', () => {
if (list.scrollTop > 0) {
this.isRefreshDisable = true
} else {
this.isRefreshDisable = false
}
})
}
},
methods: {
load(loading = true) {
const {fileType = [], ...others} = this.form
const query = {
pageIndex: this.pagination.pageIndex,
pageSize: this.pagination.pageSize,
fileType: fileType&&fileType.length ? fileType.join(): '',
...others
}
getTemplateByPage(query, loading).then(res => {
if (this.pagination.pageIndex === 1) {
this.list = []
}
this.list = this.list.concat(res.data.dataList || [])
this.pagination.total = res.data.total || 0
this.finished = this.list.length >= this.pagination.total
}).finally(() => {
this.loading = false
this.loadingRefresh = false
})
},
search() {
this.pagination.pageIndex = 1
this.load()
this.searchVisible = false
},
reset() {
this.form = DefaultForm()
this.form.templateClassify = this.templateClassify
this.search()
},
onMore() {
this.pagination.pageIndex++
this.load(false)
},
onRefresh() {
this.pagination.pageIndex = 1
this.load()
},
openSearch() {
this.searchVisible = true
},
toDetail(record) {
this.selectRecord = record
this.detailShow = true
},
detailClosed(val) {
this.detailShow = val
},
//列表引用
toUse(record, typeList = [1, 2, 3]) {
this.$emit('selectRecord', record.id, typeList)
this.onBack()
},
//详情选中引用
detailToUse(val, typeList = []) {
this.$emit('selectRecord', val, typeList)
this.onBack()
},
onBack() {
this.$emit('closed', false)
}
}
}
</script>
<style scoped lang='less'>
.title {
font-size: 18px;
font-weight: 600;
}
.bg-white {
background: #FFFFFF;
}
.left-btn {
font-size: 14px;
font-weight: 400;
}
.bg {
background: rgb(245, 245, 245);
height: 100vh;
}
.p-10 {
padding: 10px;
}
:deep(.workbench-search-box) {
color: #595959;
.bt-group {
border-top: 1px solid #EBEBEC;
color: #262626;
.submit-btn {
color: #fff;
background-color: var(--van-primary-color);
}
}
}
</style>
\ No newline at end of file
<template>
<div class='all-back'>
<van-nav-bar title='慢病管理' left-text='' left-arrow
@click-right="toSearch" @click-left='toBack'>
<template #right>
<doc-icon type="doc-search" style="color: #262626"/>
</template>
</van-nav-bar>
<van-pull-refresh v-model="loading" @refresh="onRefresh"
:disabled='isRefreshDisable'>
<div class='top-title'>
我的待随访({{ total }})
</div>
<van-tabs v-model:active='active'>
<van-tab :name='item.name' v-for='item in tabList' :key="item.name">
<template #title>
<span>{{ item.title }}({{ item.num }})</span>
</template>
</van-tab>
</van-tabs>
<div class='list-data' ref='list'>
<div class='mt-10 white-back p-16' v-for='item in activeData' :key="item.id">
<div class='flex items-center'>
<div class='base-title'>{{ item.residentName }}</div>
<div class='second-title plr-8'>{{ getInfoByIdCard(item.idCard).age }}岁</div>
<div class='second-title plr-6'>{{ item.genderName }}</div>
</div>
<div class='mt-3 flex items-center'>
<div class='detail-left'>
身份证号
</div>
<div class='detail-right'>
{{ $idCardHide(item.idCard) }}
</div>
</div>
<div class='mt-3 flex items-center'>
<div class='detail-left'>
是否逾期
</div>
<div class='detail-right'>
{{ item.isOverdueName }}
</div>
</div>
<div class='mt-3 flex items-center'>
<div class='detail-left'>
逾期天数
</div>
<div class='detail-right'>
{{ item.overdueDay }} 天
</div>
</div>
<div class='flex mt-3' style='align-items: baseline'>
<div class='detail-left'>
慢病标签
</div>
<div class='detail-right' style='flex: 1'>
<ChronicTag :list="item.chronicTagsArray"/>
</div>
</div>
<van-divider class='mt-3' />
<div class='mt-3 flex word-right'>
<div></div>
<div>
<van-button round size='small' class='btn' @click='toGeneralDetail(item)'>详情</van-button>
<van-button round size='small' class='btn' style='margin-left: 16px' @click='toAddGeneral(item)'>通用随访
</van-button>
</div>
</div>
</div>
<div class="text-center empty" v-if="!activeData.length">
<img src="@/assets/image/doctor/empty.png" alt="" style="width: 1.2rem;">
<p>暂无数据</p>
</div>
</div>
</van-pull-refresh>
</div>
</template>
<script>
import dayjs from 'dayjs'
import { getVisitAll } from '@/api/doctor/generalFU.js'
import ChronicTag from '@/doctor/components/chronicTag/ChronicTag.vue'
import { backHome, getInfoByIdCard } from '@/utils/common'
export default {
name: 'List',
components: {
ChronicTag
},
data() {
return {
active: 1,
tabList: [
{ title: '高血压', name: 1, num: 0 },
{ title: '糖尿病', name: 2, num: 0 },
{ title: '冠心病', name: 3, num: 0 },
{ title: '脑卒中', name: 4, num: 0 },
{ title: '慢阻肺', name: 5, num: 0 },
{ title: '慢性肾病', name: 6, num: 0 },
{ title: '血脂异常', name: 7, num: 0 }
],
detailInfo: [],
total: 0,
// 下拉刷新
loading: false,
isRefreshDisable: false
}
},
computed: {
activeData() {
return this.detailInfo.filter(e => e.diseaseType === this.active)
}
},
created() {
this.init()
},
mounted() {
const list = this.$refs.list
list.addEventListener('scroll', () => {
if (list.scrollTop > 0) {
this.isRefreshDisable = true
} else {
this.isRefreshDisable = false
}
})
},
methods: {
getInfoByIdCard,
init() {
this.load()
},
load(loading = true) {
// const nextVisitDateStart = dayjs().format('YYYY-MM-DD')
// const nextVisitDateEnd = dayjs().add(6, 'day').format('YYYY-MM-DD')
const query = {
// nextVisitDateStart,
// nextVisitDateEnd
}
getVisitAll(query, loading).then(res => {
console.log('getVisitAll', res)
this.detailInfo = res.data || []
this.total = this.detailInfo.length
this.tabList.forEach(e => {
e.num = this.detailInfo.filter(i => i.diseaseType === e.name).length
})
}).finally(() => {
this.loading = false
})
},
scrollHandle(dom) {
if (!dom) return
if (dom.scrollTop > 0) {
this.isRefreshDisable = true
} else {
this.isRefreshDisable = false
}
},
onRefresh() {
this.load(false)
},
toGeneralDetail(item) {
this.$router.push({
path: `/doctor/resident/base`,
query: {
residentId: item.residentInfoId
}
})
},
toAddGeneral(val) {
const {id, ...others} = val
this.$router.push({
path: `/doctor/followUp/generalFU/add`,
query: {...others}
})
},
toSearch() {
this.$router.push({
path: `/doctor/followUp/search`
})
},
toBack() {
backHome()
}
}
}
</script>
<style scoped lang='less'>
.all-back {
background: #F5F5F5;
.top-title {
padding: 10px 12px;
}
.white-back {
background: #FFFFFF;
}
.mt-10 {
margin-top: 10px;
}
.p-16 {
padding: 16px;
}
.plr-8 {
padding: 0px 8px;
}
.plr-6 {
padding: 0px 6px;
}
.base-title {
font-weight: bold;
font-size: 16px;
}
.second-title {
background: #F0F3FF;
line-height: 24px;
margin-left: 10px;
}
.detail-left {
width: 104px;
font-size: 14px;
color: #8C8C8C;
}
.detail-right {
font-size: 14px;
}
.word-right {
justify-content: space-between;
align-items: center;
}
.btn {
background: #F0F3FF;
color: #607FF0;
border: 0px;
line-height: 26px;
height: 26px;
//padding: 4px 8px 4px 8px;
padding: 0px 8px;
}
.list-data {
height: calc(100vh - 140px);
overflow-y: auto;
}
}
</style>
\ No newline at end of file
<template>
<div class='all-back'>
<van-nav-bar title='慢病管理' left-text='' left-arrow
@click-right='toSearch' @click-left='toBack'>
<template #right>
<doc-icon type='doc-search' style='color: #262626' />
</template>
</van-nav-bar>
<div class='top-title'>
我的待随访({{ total }})
</div>
<van-tabs v-model:active='active' @change='changeTab'>
<van-tab :name='item.name' v-for='item in tabList' :key='item.name'>
<template #title>
<span>{{ item.title }}({{ item.num }})</span>
</template>
</van-tab>
</van-tabs>
<van-pull-refresh v-model='loading' @refresh='onRefresh'
:disabled='isRefreshDisable'>
<div class='list-data' ref='list'>
<van-list
v-model:loading='loadingTable'
:finished='finished'
:finished-text="detailInfo.length ? '没有更多了' : ''"
@load='onMore'
>
<div class='mt-10 white-back p-16' v-for='item in detailInfo' :key='item.id'>
<div class='flex items-center'>
<div class='base-title'>{{ item.residentName }}</div>
<div class='second-title plr-8'>{{ getInfoByIdCard(item.idCard).age }}岁</div>
<div class='second-title plr-6'>{{ item.genderName }}</div>
</div>
<div class='mt-3 flex items-center'>
<div class='detail-left'>
身份证号
</div>
<div class='detail-right'>
{{ $idCardHide(item.idCard) }}
</div>
</div>
<div class='mt-3 flex items-center'>
<div class='detail-left'>
是否逾期
</div>
<div class='detail-right'>
{{ item.isOverdueName }}
</div>
</div>
<div class='mt-3 flex items-center'>
<div class='detail-left'>
逾期天数
</div>
<div class='detail-right'>
{{ item.overdueDay }} 天
</div>
</div>
<div class='flex mt-3' style='align-items: baseline'>
<div class='detail-left'>
慢病标签
</div>
<div class='detail-right' style='flex: 1'>
<ChronicTag :list='item.chronicTagsArray' />
</div>
</div>
<van-divider class='mt-3' />
<div class='mt-3 flex word-right'>
<div></div>
<div>
<van-button round size='small' class='btn' @click='toGeneralDetail(item)'>详情
</van-button>
<van-button round size='small' class='btn' style='margin-left: 16px'
@click='toAddGeneral(item)'>通用随访
</van-button>
</div>
</div>
</div>
</van-list>
<div class='text-center empty' v-if='!detailInfo.length'>
<img src='@/assets/image/doctor/empty.png' alt='' style='width: 1.2rem;'>
<p>暂无数据</p>
</div>
</div>
</van-pull-refresh>
</div>
</template>
<script>
import dayjs from 'dayjs'
import { getVisitAll, queryVisitByPage } from '@/api/doctor/generalFU.js'
import ChronicTag from '@/doctor/components/chronicTag/ChronicTag.vue'
import { backHome, getInfoByIdCard } from '@/utils/common'
export default {
name: 'List',
components: {
ChronicTag
},
data() {
return {
active: 1,
tabList: [
{ title: '高血压', name: 1, num: 0 },
{ title: '糖尿病', name: 2, num: 0 },
{ title: '冠心病', name: 3, num: 0 },
{ title: '脑卒中', name: 4, num: 0 },
{ title: '慢阻肺', name: 5, num: 0 },
{ title: '慢性肾病', name: 6, num: 0 },
{ title: '血脂异常', name: 7, num: 0 }
],
detailInfo: [],
total: 0,
// 下拉刷新
loading: false,
isRefreshDisable: false,
//列表刷新
loadingTable: false,
pagination: {
total: 0,
pageIndex: 1,
pageSize: 5
},
finished: false
}
},
mounted() {
const list = this.$refs.list
list.addEventListener('scroll', () => {
if (list.scrollTop > 0) {
this.isRefreshDisable = true
} else {
this.isRefreshDisable = false
}
})
},
methods: {
getInfoByIdCard,
changeTab() {
this.detailInfo = []
this.pagination.pageIndex = 1
this.load()
},
onMore() {
this.pagination.pageIndex++
this.load()
},
load(loading = true) {
const query = {
diseaseType: this.active,
pageIndex: this.pagination.pageIndex,
pageSize: this.pagination.pageSize
}
getVisitAll(query, loading).then(res => {
console.log('getVisitAll', res)
this.detailInfo = this.detailInfo.concat(res.data || [])
this.total = this.detailInfo.length
this.finished = this.detailInfo.length >= this.pagination.total
}).finally(() => {
this.loading = false
this.loadingTable = false
})
},
scrollHandle(dom) {
if (!dom) return
if (dom.scrollTop > 0) {
this.isRefreshDisable = true
} else {
this.isRefreshDisable = false
}
},
onRefresh() {
this.detailInfo = []
this.pagination.pageIndex = 1
this.load(false)
},
toGeneralDetail(item) {
this.$router.push({
path: `/doctor/resident/base`,
query: {
residentId: item.residentInfoId
}
})
},
toAddGeneral(val) {
const { id, ...others } = val
this.$router.push({
path: `/doctor/followUp/generalFU/add`,
query: { ...others }
})
},
toSearch() {
this.$router.push({
path: `/doctor/followUp/search`
})
},
toBack() {
backHome()
}
}
}
</script>
<style scoped lang='less'>
.all-back {
background: #F5F5F5;
.top-title {
padding: 10px 12px;
}
.white-back {
background: #FFFFFF;
}
.mt-10 {
margin-top: 10px;
}
.p-16 {
padding: 16px;
}
.plr-8 {
padding: 0px 8px;
}
.plr-6 {
padding: 0px 6px;
}
.base-title {
font-weight: bold;
font-size: 16px;
}
.second-title {
background: #F0F3FF;
line-height: 24px;
margin-left: 10px;
}
.detail-left {
width: 104px;
font-size: 14px;
color: #8C8C8C;
}
.detail-right {
font-size: 14px;
}
.word-right {
justify-content: space-between;
align-items: center;
}
.btn {
background: #F0F3FF;
color: #607FF0;
border: 0px;
line-height: 26px;
height: 26px;
//padding: 4px 8px 4px 8px;
padding: 0px 8px;
}
.list-data {
height: calc(100vh - 140px);
overflow-y: auto;
}
}
</style>
\ No newline at end of file
<!--通用随访详情-->
<template> <template>
<div> <div class='flex flex-col' style='height: 100vh'>
<van-nav-bar title='随访详情' left-text='' left-arrow @click-left='toBack'></van-nav-bar> <div class='p-3 text-black text-center shrink-0 doc-nav-bar'>
<div class='p-4 detail-info'> <span @click='onBack' class='text-12 back-bt'>
<div class='title'>居民信息</div> <doc-icon type='doc-left2' />
<div class='detail-div mt-3'> </span>
<!-- <div class='flex items-center justify-between'> <span>随访详情</span>
<div class='label'>证件类型</div> </div>
<div>{{ residentInfo.certificateTypeName || '-' }}</div> <div class='px-4 py-3 flex shrink-0 base-info'>
</div> <div class='flex w-full'>
<div class='flex items-center justify-between mt-2'> <div class='grow flex flex-col justify-between'>
<div class='label'>证件号码</div> <div class='flex justify-between'>
<div>{{ residentInfo.idCard || '-' }}</div> <span class='name'>{{ residentInfo.residentName }}</span>
</div>-->
<div class='flex items-center justify-between mt-2'>
<div class='label'>姓名</div>
<div>{{ residentInfo.residentName || '-' }}</div>
</div>
<!-- <div class='flex items-center justify-between mt-2'>
<div class='label'>性别</div>
<div>{{ residentInfo.genderName || '-' }}</div>
</div>
<div class='flex items-center justify-between mt-2'>
<div class='label'>出生日期</div>
<div>{{ residentInfo.dataBirth || '-' }}</div>
</div>-->
<div class='flex items-center justify-between mt-2'>
<div class='label'>本人电话</div>
<div>{{ residentInfo.telephone || '-' }}</div>
</div>
<div class='flex items-center justify-between mt-2'>
<div class='label'>民族</div>
<div>{{ residentInfo.nationalName || '-' }}</div>
</div>
<!-- <div class='flex items-center justify-between mt-2'>
<div class='label'>年龄</div>
<div>{{ residentInfo.currentAge || '-' }}</div>
</div>-->
<div class='flex flex-wrap justify-between mt-2'>
<div class='label'>现住址</div>
<div style='flex: 1'>{{ residentInfo.fullNowAddress || '-' }}</div>
</div>
<div class='flex flex-wrap justify-between mt-2'>
<div class='label'>户籍地址</div>
<div style='flex: 1'>{{ residentInfo.fullPermanentAddress || '-' }}</div>
</div>
</div>
<div class='title mt-3'>联系人信息</div>
<div class='detail-div mt-3'>
<div class='flex items-center justify-between'>
<div class='label'>联系人姓名</div>
<div>{{ residentInfo.contactName || '-' }}</div>
</div>
<div class='flex items-center justify-between mt-2'>
<div class='label'>与居民关系</div>
<div>{{ residentInfo.relationName || '-' }}</div>
</div>
<div class='flex items-center justify-between mt-2'>
<div class='label'>联系电话</div>
<div>{{ residentInfo.contactPhone || '-' }}</div>
</div>
</div>
<div class='title mt-3'>随访信息</div>
<div class='detail-div mt-3'>
<div class='flex items-center justify-between'>
<div>本次随访情况</div>
<div>{{ info.visitSituationName }}</div>
</div>
<div class='flex items-center justify-between mt-2' v-if='info.visitSituation == 2'>
<div>失访原因</div>
<div>
<span v-if='info.lossReason != 9'>{{ info.lossReasonName || '-' }}</span>
<span v-if='info.lossReason == 9'>{{ info.lossReasonOther || '-' }}</span>
</div> </div>
</div> <div class='top-label'>
<div class='flex items-center justify-between mt-2' v-if='info.lossReason == 3'> <div class='mt-3 flex'>
<div>死亡原因</div> <div><span>随访方式:</span><span class='color-b'>{{ info.visitWayName }}</span></div>
<div>{{ info.deathReason }}</div> <div class='ml-4'>随访日期:<span class='color-b'>{{ info.visitDate }}</span></div>
</div> </div>
<div class='flex items-center justify-between mt-2' v-if='info.visitSituation == 1'> <div><span>下次随访日期:</span><span class='color-b'>{{ info.nextVisitDate }}</span></div>
<div>随访方式</div>
<div>{{ info.visitWayName }}</div>
</div>
<div class='white-b mt-2' v-if='showOne && info.visitSituation == 1'>
<span>居民电话: </span><span>{{ residentInfo.telephone || '-' }}</span>
</div>
<div class='white-b mt-2' v-if='showThree && info.visitSituation == 1'>
<div>催检内容:</div>
<div>{{ info.urgentInsContent }}</div>
</div>
<div class='mt-2' v-if='showOne && info.visitSituation == 1'>
<div>随访内容</div>
<div class='white-b mt-2' style='min-height: 60px'>
<div>{{ info.visitContent }}</div>
</div> </div>
</div> </div>
<div class='mt-2' v-if='showOne && info.visitSituation == 1'> </div>
<div>处置意见</div> </div>
<div class='white-b mt-2' style='min-height: 60px'> <div class='p-3 grow cont-box'>
<div>{{ info.disposalOpinion }}</div> <div class='p-3 h-full cont-inner'>
</div> <div class='flex justify-between collapse-head mt-2'>
<span class='text-16 font-semibold'>全部内容</span>
<span @click='toggleAll'>
<span v-if='!collapseAll'>展开全部</span>
<span v-else>收起全部</span>
<span :class="['ml-2 icon-down', { 'icon-down-expanded': collapseAll }]">
<doc-icon type='doc-down' />
</span>
</span>
</div> </div>
<div class='mt-2' v-if='(showOne || showTwo) && info.visitSituation == 1 && info.isHealthGuide == 1'> <van-collapse :model-value='activeCollapse' ref='collapse' class='doc-collapse'
<div>健康指导</div> @change='collapseChange'>
<div class='white-b mt-2'> <van-collapse-item key='1' title='居民信息' name='1'>
<div class='flex flex-wrap mt-2' <template #right-icon>
v-for='(item, index) in healthInterventionsInfo.visitHealthGuideList'> <doc-icon type='doc-down' />
<div v-if="item.name != '无'" class='label'>{{ item.name }}</div> </template>
<div style='flex: 1'>{{ item.templateContent }}</div> <div class='list'>
<div v-for='item in columnsBase' :key='item.key'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>{{ item.title }}</span>
<span v-if="item.key === 'idCard'">{{ $idCardHide(residentInfo.idCard) || '-'
}}</span>
<span class='text-end' v-else>
<span>{{ residentInfo[item.key] || '-' }}</span>
<span v-if='item.unit' class='ml-1'>{{ item.unit }}</span>
</span>
</div>
</div>
</div> </div>
</div> </van-collapse-item>
</div> <van-collapse-item key='2' title='随访人群' name='2'>
<template #right-icon>
<div class='mt-2' v-if='imgList1.length'> <doc-icon type='doc-down' />
<div>随访记录</div> </template>
<div class='flex items-center' style='flex-wrap: wrap'> <div class='list'>
<div v-for='(item, index) in imgList1'> <div class='flex justify-between py-1 border-bottom item'>
<!-- 图片--> <span class='shrink-0 mr-2 label'>随访人群</span>
<div v-if="item.imgFlag == 'img'" class='mt-2'> <span class='text-end'>
<img :src='item.trueDownloadUrl' class='ml-2' style='width: 95px;height: 95px;'> <span>{{ info.groupsArraysName || '-' }}</span>
</span>
</div> </div>
</div> </div>
</div> </van-collapse-item>
<!-- pdf--> <van-collapse-item key='3' title='随访方式' name='3'>
<div> <template #right-icon>
<div v-for='item in imgList1'> <doc-icon type='doc-down' />
<div class='mt-2 pdf' v-if="item.imgFlag == 'pdf'"> </template>
<div class='flex items-center justify-between'> <div class='list'>
<div class='flex items-center' @click.stop='toPdf(item)'> <div class='flex justify-between py-1 border-bottom item'>
<div> <span class='shrink-0 mr-2 label'>随访方式</span>
<doc-icon type='doc-PDF' style='font-size: .48rem'></doc-icon> <span class='text-end'>
</div> <span>{{ info.visitWayName || '-' }}</span>
<div class='ml-1'>{{ item.name }}</div> </span>
</div> </div>
</div>
</van-collapse-item>
<van-collapse-item key='4' title='随访类型' name='4'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>随访类型</span>
<span class='text-end'>
<span>{{ info.visitWayRulesName || '-' }}</span>
</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='5' title='随访内容' name='5' v-if='showOne'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='py-1 border-bottom item card'
:style="{textIndent: info.visitContent ? '2em' : '0'}">
<span>{{ info.visitContent || '-' }}</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='6' title='处置意见' name='6' v-if='showOne'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='py-1 border-bottom item card'
:style="{textIndent: info.disposalOpinion ? '2em' : '0'}">
<span>{{ info.disposalOpinion || '-' }}</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='7' title='健康指导' name='7' v-if='showTwo'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div>
<div v-if='guideContentList.length' class='flex flex-col card'>
<!-- 文本 -->
<div v-for='item in guideContentList' :key='item.templateMode' class='mb-1 flex'
:style='`order: ${item.templateMode}`'>
<span class='shrink-0 mr-1'
v-if="item.templateModeTrans != '无'">{{ item.templateModeTrans }} :</span>
<span> {{ item.templateContent }}</span>
</div> </div>
</div> </div>
</div> </div>
</div> </van-collapse-item>
</div> <van-collapse-item key='8' title='宣教内容' name='8' v-if='showThree'>
<template #right-icon>
<div class='mt-2' v-if='imgList2.length'> <doc-icon type='doc-down' />
<div>现场随访照片</div> </template>
<div class='flex items-center' style='flex-wrap: wrap'> <div>
<div v-for='(item, index) in imgList2'> <div class='flex flex-col card' v-if='detailInfo?.publicizeType?.includes(1)'>
<!-- 图片--> <!-- 文本 -->
<div v-if="item.imgFlag == 'img'" class='mt-2'> <div v-for='item in contentList' :key='item.templateMode' class='mb-1 flex'
<img :src='item.trueDownloadUrl' class='ml-2' style='width: 95px;height: 95px;'> :style='`order: ${item.templateMode}`'>
<span class='shrink-0 mr-1'
v-if="item.templateModeTrans != '无'">{{ item.templateModeTrans }} :</span>
<span> {{ item.templateContent }}</span>
</div>
</div>
<div class='card mt-2' v-if='detailInfo?.publicizeType?.includes(3)'>
<Mp4 :files='mp4List' :activeMediaUrl="activeMediaUrl"
@play='e => activeMediaUrl = e.annexUrl' />
</div>
<div class='card flex flex-col mt-2' style='row-gap: .06rem;'
v-if='detailInfo?.publicizeType?.includes(2)'>
<Mp3 :file='item' v-for='item in mp3List' :key='item.annexId'
:activeMediaUrl='activeMediaUrl'
@play='e => activeMediaUrl = e.annexUrl' />
</div> </div>
</div> </div>
</div> </van-collapse-item>
<!-- pdf--> <van-collapse-item key='9' title='催检内容' name='9' v-if='showFour'>
<div> <template #right-icon>
<div v-for='item in imgList2'> <doc-icon type='doc-down' />
<div class='mt-2 pdf' v-if="item.imgFlag == 'pdf'"> </template>
<div class='flex items-center justify-between'> <div class='list'>
<div class='flex items-center' @click.stop='toPdf(item)'> <div class='py-1 border-bottom item card'
<div> :style="{textIndent: info.urgentInsContent ? '2em' : '0'}">
<doc-icon type='doc-PDF' style='font-size: .48rem'></doc-icon> <span>{{ info.urgentInsContent || '-' }}</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='10' title='上传随访记录' name='10' v-if='showOne'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div>
<image-preview :img-list='info.uploadVisitRecordImageList'></image-preview>
</div>
</van-collapse-item>
<van-collapse-item key='11' title='现场随访照片' name='11'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<!-- <div class='list gap-x-2.5 gap-y-1 flex items-center flex-wrap'>
<div v-for="(url, index) in info.sceneVisitImageList" :key="index" >
<img style='width: 1.47rem;height: 2.04rem' :src="url.trueDownloadUrl" />
</div>
</div>-->
<div>
<image-preview :img-list='info.sceneVisitImageList'></image-preview>
</div>
</van-collapse-item>
<van-collapse-item key='12' title='推送渠道' name='12'
v-if='info?.visitWayRules?.includes(2) || info?.visitWayRules?.includes(3) || info?.visitWayRules?.includes(4)'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>推送渠道</span>
<span class='text-end'>
<span v-if='info.isSms == 1'>短信</span><span
v-if='info.isSms == 1 && info.isWx == 1'></span>
<span v-if='info.isWx == 1'>微信</span>
<span v-if='info.isSms != 1 && info.isWx != 1'>-</span>
</span>
</div>
<div class='flex justify-between py-1 border-bottom item'
v-if='info.isSms == 1 && (info?.visitWayRules?.includes(2) || info?.visitWayRules?.includes(3) || info?.visitWayRules?.includes(4))'>
<span class='shrink-0 mr-2 label'>短信推送情况</span>
<span class='text-end'>
<div class='flex items-center'>
<span>{{ info?.serviceResidents?.messageStateName || '-' }}</span>
<span class='ml-4' v-if='info?.serviceResidents?.messageState == 4' style='font-size: 12px'>
<van-button plain type='primary' size='small' @click='toReSend'>重新发送</van-button>
</span>
</div> </div>
<div class='ml-1'>{{ item.name }}</div> </span>
</div> </div>
</div>
</van-collapse-item>
<van-collapse-item key='13' title='随访机构' name='13'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div v-for='item in columnsOrg' :key='item.key'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>{{ item.title }}</span>
<span class='text-end'>
<span>{{ info[item.key] || '-' }}</span>
</span>
</div> </div>
</div> </div>
</div> </div>
</div> </van-collapse-item>
</div> </van-collapse>
<div class='flex items-center justify-between mt-2' v-if='info.visitSituation == 1'>
<div>下次随访日期</div>
<div>{{ info.nextVisitDate || '-' }}</div>
</div>
<div class='flex items-center justify-between mt-2'>
<div>随访单位</div>
<div>{{ info.visitUnitName || '-' }}</div>
</div>
<div class='flex items-center justify-between mt-2'>
<div>随访科室</div>
<div>{{ info.visitOfficeName || '-' }}</div>
</div>
<div class='flex items-center justify-between mt-2'>
<div>随访医生</div>
<div>{{ info.visitDoctorName || '-' }}</div>
</div>
</div> </div>
</div> </div>
<div class='px-5 flex align-center justify-around pt-2 pb-2'>
<van-button type='primary' round plain style='width: 70%;background: #F0F3FF;border: 0px'
@click='toBack'>返回
</van-button>
</div>
</div> </div>
</template> </template>
<script> <script>
import { fetchCurrencyById } from '@/api/doctor/generalFU'
import { showToast } from 'vant' import { showToast } from 'vant'
import { useStore } from '@/doctor/store' import Mp3 from '@/doctor/components/mediaPlay/Mp3.vue'
import Mp4 from '@/doctor/components/mediaPlay/Mp4.vue'
import ImagePreview from '@/residentWX/components/imagePreview/imagePreview'
import { fetchCurrencyById, messageResend } from '@/api/doctor/generalFU'
import { getTemplateDetail } from '@/api/doctor/workbench'
export default { export default {
name: 'Detail', name: 'CurrencyFUDetail.vue',
props: { components: { ImagePreview, Mp4, Mp3 },
id: [String, Number]
},
data() { data() {
return { return {
store: useStore(), activeCollapse: [],
detailInfo: {
publicizeType: [],
visitWayRules: []
},
collapseList: [
{ title: '居民信息', name: '1' },
{ title: '随访人群', name: '2' },
{ title: '随访方式', name: '3' },
{ title: '随访类型', name: '4' },
{ title: '随访内容', name: '5' },
{ title: '处置意见', name: '6' },
{ title: '健康指导', name: '7' },
{ title: '宣教内容', name: '8' },
{ title: '催检内容', name: '9' },
{ title: '上传随访记录', name: '10' },
{ title: '现场随访照片', name: '11' },
{ title: '推送渠道', name: '12' },
{ title: '下次随访日期', name: '13' },
{ title: '随访机构', name: '14' }
],
// 全部展开、收起
collapseAll: false,
info: {}, info: {},
residentInfo: {} columnsBase: [
{ title: '姓名', key: 'residentName' },
{ title: '证件号码', key: 'idCard' },
{ title: '性别', key: 'genderName' },
{ title: '出生日期', key: 'dataBirth' },
{ title: '年龄', key: 'currentAge' },
{ title: '民族', key: 'nationalName' },
{ title: '本人电话', key: 'telephone' },
{ title: '现住址', key: 'presentCodeName' },
{ title: '详细地址', key: 'nowAddress' },
{ title: '户籍地址', key: 'registeredCodeName' },
{ title: '详细地址', key: 'permanentAddress' }
],
columnsOrg: [
{ title: '随访单位', key: 'visitUnitName' },
{ title: '随访科室', key: 'visitOfficeName' },
{ title: '随访医生', key: 'visitDoctorName' }
],
// 控制音频同一时间只播放一个
activeMediaUrl: '',
hideActiveMediaUrl: '',
} }
}, },
computed: { computed: {
routerDetail() { routerDetail() {
return this.$route.query return this.$route.query
}, },
//复检指导 residentInfo() {
return this.info.residentsRecord || {}
},
//复检
showOne() { showOne() {
const { visitWay } = this.info const { visitWayRules = [] } = this.info
let res = false let res = false
if (visitWay == 5 || visitWay == 6 || visitWay == 7 || visitWay == 8) { if (visitWayRules.includes(1)) {
res = true res = true
} }
return res return res
}, },
//微信、短信指导 //指导
showTwo() { showTwo() {
const { visitWay } = this.info const { visitWayRules = [] } = this.info
let res = false let res = false
if (visitWay == 9 || visitWay == 11) { if (visitWayRules.includes(2)) {
res = true res = true
} }
return res return res
}, },
//催检 //宣教
showThree() { showThree() {
const { visitWay } = this.info const { visitWayRules = [] } = this.info
let res = false let res = false
if (visitWay == 10 || visitWay == 12) { if (visitWayRules.includes(3)) {
res = true res = true
} }
return res return res
}, },
//健康指导 //催检
healthInterventionsInfo() { showFour() {
const modeArray = this.store.getDict('DC00084') const { visitWayRules = [] } = this.info
let visitHealthGuideList = [] let res = false
if (this.info.healthGuideContent) { if (visitWayRules.includes(4)) {
visitHealthGuideList = JSON.parse(this.info.healthGuideContent) res = true
}
const res = {
visitHealthGuideList: modeArray.map(e => {
const item = visitHealthGuideList.find(i => i.templateMode === e.value)
return {
templateMode: e.value,
name: e.name,
templateContent: item ? item.templateContent : '',
id: item ? item.visitId : ''
}
})
} }
return res return res
}, },
imgList1() { // 文本内容
const { uploadVisitRecordImageList = [] } = this.info guideContentList() {
uploadVisitRecordImageList.forEach(item => { return this.info?.guide?.contentList || []
item['imgFlag'] = ''
if (item.fileType == 'pdf') {
item['imgFlag'] = 'pdf'
}
if (item.fileType == 'img') {
item['imgFlag'] = 'img'
}
})
return uploadVisitRecordImageList
}, },
imgList2() { // 文本内容
const { sceneVisitImageList = [] } = this.info contentList() {
sceneVisitImageList.forEach(item => { return this.info?.publicize?.contentList || []
item['imgFlag'] = '' },
if (item.fileType == 'pdf') { // 文件内容
item['imgFlag'] = 'pdf' annexList() {
} return this.info?.publicize?.annexList || []
if (item.fileType == 'img') { },
item['imgFlag'] = 'img' mp3List() {
} return this.annexList.filter(e => e.type == 2)
}) },
return sceneVisitImageList mp4List() {
return this.annexList.filter(e => e.type == 3)
} }
}, },
created() { created() {
document.title = '通用随访详情'
this.load() this.load()
}, },
methods: { methods: {
...@@ -305,50 +378,141 @@ export default { ...@@ -305,50 +378,141 @@ export default {
fetchCurrencyById(par).then(res => { fetchCurrencyById(par).then(res => {
let result = res.data || {} let result = res.data || {}
this.info = result this.info = result
this.residentInfo = result.residentsRecord || {} this.dataHandle()
}).finally(() => { }).finally(() => {
}) })
}, },
toBack() { //数据处理
dataHandle() {
const { visitWayRules, publicizeType } = this.info
if (publicizeType) {
this.detailInfo.publicizeType = publicizeType.split(',').map(item => Number(item))
}
if (visitWayRules) {
this.detailInfo.visitWayRules = visitWayRules.split(',').map(item => Number(item))
}
},
//重新发送
toReSend() {
let par = {
id: this.routerDetail.relationId
}
messageResend(par).then(() => {
this.load()
})
},
// 折叠面板切换
collapseChange(val) {
if (val && val.length <= 2) {
this.activeCollapse = val.slice(val.length - 1)
} else {
if (this.activeCollapse.length > val.length) {
this.activeCollapse = val
}
if (this.activeCollapse.length < val.length) {
this.activeCollapse = val.slice(val.length - 1)
}
}
if (val && val.length === this.collapseList.length) {
this.collapseAll = true
} else {
this.collapseAll = false
}
},
// 全部展开、收起
toggleAll() {
if (this.collapseAll) {
this.activeCollapse = []
} else {
this.activeCollapse = this.collapseList.map(e => e.name)
}
this.collapseAll = !this.collapseAll
},
onBack() {
this.$router.back() this.$router.back()
} }
} }
} }
</script> </script>
<style scoped lang='less'> <style lang='less' scoped>
.title { @import url('../../../utils/common.less');
font-weight: bold;
}
.mt-4 { .base-info {
margin-top: 24px; background: linear-gradient(to bottom, #F0F6FF, #fff 50%);
color: #8c8c8c;
.name {
font-weight: 600;
color: #000;
font-size: 18px;
}
.top-label {
font-size: 13px;
line-height: 22px;
}
.color-b {
color: #262626;
}
} }
.detail-info { .cont-box {
height: calc(100vh - 110px); background-color: #f9f9f9;
overflow-y: auto;
.cont-inner {
background: linear-gradient(to bottom, #F0F6FF, #fff .6rem);
border-top-left-radius: .08rem;
border-top-right-radius: .08rem;
}
} }
.detail-div { .collapse-head {
padding: 12px; .icon-down {
border: 1px solid #EEEEEE; vertical-align: middle;
background: #F8FAFC; font-size: .12rem;
border-radius: 8px;
.svg-icon {
transition: all .2s;
}
}
.icon-down-expanded {
.svg-icon {
transform: rotate(-180deg);
}
}
} }
.white-b {
background: #FFFFFF; table {
padding: 12px; text-align: left;
border: 1px solid #EEEEEE; border-bottom: 1px solid var(--van-cell-border-color);
border-radius: 8px;
> tr {
> td {
padding-left: 14px;
padding-bottom: 12px;
&:first-child {
text-align: right;
padding-left: 0;
}
}
}
} }
.label { .list {
width: 104px; .label {
min-width: 5em;
}
} }
:deep(.van-nav-bar .van-icon) { .card {
color: #000000; background-color: #F8FAFC;
padding: 4px 10px;
border-radius: 4px;
color: #4D5665;
} }
</style> </style>
\ No newline at end of file
...@@ -2,23 +2,23 @@ ...@@ -2,23 +2,23 @@
<div> <div>
<van-form ref='form'> <van-form ref='form'>
<div class='title'>居民信息</div> <div class='title'>居民信息</div>
<!-- <div class='label-title'>证件类型</div> <!-- <div class='label-title'>证件类型</div>
<van-field <van-field
v-model='form.certificateTypeName' v-model='form.certificateTypeName'
is-link is-link
readonly readonly
placeholder='证件类型' placeholder='证件类型'
class='input-back mt-2 form-input' class='input-back mt-2 form-input'
:rules='rules.certificateTypeName' :rules='rules.certificateTypeName'
/>--> />-->
<!-- <div class='label-title mt-5'>证件号码</div> <!-- <div class='label-title mt-5'>证件号码</div>
<van-field <van-field
v-model='form.idCard' v-model='form.idCard'
readonly readonly
placeholder='证件号码' placeholder='证件号码'
class='input-back mt-2 form-input' class='input-back mt-2 form-input'
:rules='rules.idCard' :rules='rules.idCard'
/>--> />-->
<div class='label-title mt-5'>姓名</div> <div class='label-title mt-5'>姓名</div>
<van-field <van-field
v-model='form.residentName' v-model='form.residentName'
...@@ -27,24 +27,24 @@ ...@@ -27,24 +27,24 @@
class='input-back mt-2 form-input' class='input-back mt-2 form-input'
:rules='rules.residentName' :rules='rules.residentName'
/> />
<!-- <div class='label-title mt-5'>性别</div> <!-- <div class='label-title mt-5'>性别</div>
<van-field <van-field
v-model='form.genderName' v-model='form.genderName'
is-link is-link
readonly readonly
placeholder='性别' placeholder='性别'
class='input-back mt-2 form-input' class='input-back mt-2 form-input'
:rules='rules.genderName' :rules='rules.genderName'
/>--> />-->
<!-- <div class='label-title mt-5'>出生日期</div> <!-- <div class='label-title mt-5'>出生日期</div>
<van-field <van-field
v-model='form.dataBirth' v-model='form.dataBirth'
is-link is-link
readonly readonly
placeholder='出生日期' placeholder='出生日期'
class='input-back mt-2 form-input' class='input-back mt-2 form-input'
:rules='rules.dataBirth' :rules='rules.dataBirth'
/>--> />-->
<div class='label-title mt-5'>本人电话</div> <div class='label-title mt-5'>本人电话</div>
<van-field <van-field
v-model='form.telephone' v-model='form.telephone'
...@@ -71,14 +71,14 @@ ...@@ -71,14 +71,14 @@
@cancel='showNational = false' @cancel='showNational = false'
/> />
</van-popup> </van-popup>
<!-- <div class='label-title mt-5'>年龄</div> <!-- <div class='label-title mt-5'>年龄</div>
<van-field <van-field
v-model='form.currentAge' v-model='form.currentAge'
readonly readonly
placeholder='年龄' placeholder='年龄'
class='input-back mt-2 form-input' class='input-back mt-2 form-input'
:rules='rules.currentAge' :rules='rules.currentAge'
/>--> />-->
<div class='label-title mt-5'>现住址</div> <div class='label-title mt-5'>现住址</div>
<van-field <van-field
v-model='form.presentCodeName' v-model='form.presentCodeName'
...@@ -182,305 +182,99 @@ ...@@ -182,305 +182,99 @@
:rules='rules.contactPhone' :rules='rules.contactPhone'
/> />
<div class='title mt-5'>随访信息</div> <div class='title mt-5'>随访信息</div>
<div class='label-title mt-5'>本次随访情况</div> <div class='label-title mt-5'>随访人群</div>
<van-field name='radio' :rules='rules.visitSituation' class='p-12-0'> <van-field
<template #input> v-model='form.groupsArraysName'
<van-radio-group v-model='form.visitSituation' class='w-full' shape='dot'> readonly
is-link
<van-cell title='在访' clickable @click='form.visitSituation = 1' placeholder='请选择'
class='input-back form-input'> class='input-back mt-2 form-input'
<template #right-icon> :rules='rules.groupsArraysName'
<van-radio :name='1' /> @click='showGroupsArrays= true'
</template> >
</van-cell>
<van-cell title='失访' clickable @click='form.visitSituation = 2'
class='input-back mt-2 form-input'>
<template #right-icon>
<van-radio :name='2' />
</template>
</van-cell>
</van-radio-group>
</template>
</van-field>
<div class='label-title mt-5' v-if='form.visitSituation == 2'>失访原因</div>
<van-field name='radio' :rules='rules.lossReason' class='p-12-0'
v-if='form.visitSituation == 2'>
<template #input> <template #input>
<van-radio-group v-model='form.lossReason' class='w-full' shape='dot'> <span class='text-end' v-if='form.groupsArraysName'>{{form.groupsArraysName}}</span>
<span class='text-end' v-if='!form.groupsArraysName' style='color: #dfdfe1'>请选择</span>
<van-cell title='无法联系' clickable @click='form.lossReason = 1'
class='input-back form-input'>
<template #right-icon>
<van-radio :name='1' />
</template>
</van-cell>
<van-cell title='患者拒绝随访' clickable @click='form.lossReason = 2'
class='input-back mt-2 form-input'>
<template #right-icon>
<van-radio :name='2' />
</template>
</van-cell>
<van-cell title='死亡' clickable @click='form.lossReason = 3'
class='input-back mt-2 form-input'
:style="{borderRadius: form.lossReason == 3 ? '8px 8px 0px 0px ': '8px'}"
>
<template #right-icon>
<van-radio :name='3' />
</template>
</van-cell>
<div class='death-r' v-if='form.lossReason == 3'>
<van-field
v-model='form.deathReason'
clearable
placeholder='死亡原因'
class='input-white form-input'
/>
</div>
<van-cell title='其他' clickable @click='form.lossReason = 9'
class='input-back mt-2 form-input'
:style="{borderRadius: form.lossReason == 9 ? '8px 8px 0px 0px ': '8px'}"
>
<template #right-icon>
<van-radio :name='9' />
</template>
</van-cell>
<div class='death-r' v-if='form.lossReason == 9'>
<van-field
v-if='form.lossReason == 9'
v-model='form.lossReasonOther'
clearable
placeholder='其他原因'
class='input-white form-input'
/>
</div>
</van-radio-group>
</template> </template>
</van-field> </van-field>
<van-popup v-model:show='showGroupsArrays' position='bottom'>
<div class='p-4'>
<div class='flex justify-between items-center mb-4 pop-title'>
<div class='greyColor' @click='showGroupsArrays = false' style='font-weight: 400'>取消</div>
<div>随访人群(可多选)</div>
<div class='blueColor' @click='groupsArraysConfirm'>确定</div>
</div>
<CheckBtn multiple :options='groupArrList' v-model:value='checkGroupsArrays' :fieldNames="{text: 'name', value: 'value'}"/>
</div>
</van-popup>
<div class='label-title mt-5' v-if='form.visitSituation == 1'>随访方式</div> <div class='label-title mt-5'>随访方式</div>
<van-field name='radio' :rules='rules.visitWay' class='p-12-0' v-if='form.visitSituation == 1'> <van-field
<template #input> v-model='form.visitWayName'
<van-radio-group v-model='form.visitWay' class='w-full' shape='dot'> readonly
is-link
<van-cell title='门诊' clickable @click='form.visitWay = 5' placeholder='请选择'
class='input-back form-input' class='input-back mt-2 form-input'
:style="{borderRadius: form.visitWay == 5 ? '8px 8px 0px 0px ': '8px'}" :style="{borderRadius: form.visitWayName ? '8px 8px 0px 0px ': '8px'}"
> :rules='rules.visitWay'
<template #right-icon> @click='showVisitWay= true'
<van-radio :name='5' /> />
</template> <div class='tel-back' v-if='form.visitWayName'>
<div class='tel flex items-center justify-between'>
</van-cell> <div>
<div class='tel-back' v-if='form.visitWay == 5'> <span>居民电话: </span><span>{{ form.telephone }}</span>
<div class='tel flex items-center justify-between'> </div>
<div> <div @click='toTel' class='tel-label'>点击拨打</div>
<span>居民电话: </span><span>{{ form.telephone }}</span> </div>
</div> </div>
<div @click='toTel' class='tel-label'>点击拨打</div> <van-popup v-model:show='showVisitWay' position='bottom'>
</div> <div class='p-4'>
</div> <div class='flex justify-between mb-4 items-center pop-title'>
<van-cell title='住院' clickable @click='form.visitWay = 6' <div class='greyColor' @click='showVisitWay = false' style='font-weight: 400'>取消</div>
class='input-back mt-2 form-input' <div>随访方式(仅单选)</div>
:style="{borderRadius: form.visitWay == 6 ? '8px 8px 0px 0px ': '8px'}" <!-- <div class='blueColor' @click='visitWayConfirm'>确定</div>-->
> <div></div>
<template #right-icon> </div>
<van-radio :name='6' /> <CheckBtn column-1
</template> @change="visitWayConfirm"
</van-cell> :options="store.getDict('CP00179')"
<div class='tel-back' v-if='form.visitWay == 6'> v-model:value='checkVisitWay'
<div class='tel flex items-center justify-between'> :fieldNames="{text: 'name', value: 'value'}"
<div> />
<span>居民电话: </span><span>{{ form.telephone }}</span> </div>
</div> </van-popup>
<div @click='toTel' class='tel-label'>点击拨打</div>
</div>
</div>
<van-cell title='入户' clickable @click='form.visitWay = 7'
class='input-back mt-2 form-input'
:style="{borderRadius: form.visitWay == 7 ? '8px 8px 0px 0px ': '8px'}"
>
<template #right-icon>
<van-radio :name='7' />
</template>
</van-cell>
<div class='tel-back' v-if='form.visitWay == 7'>
<div class='tel flex items-center justify-between'>
<div>
<span>居民电话: </span><span>{{ form.telephone }}</span>
</div>
<div @click='toTel' class='tel-label'>点击拨打</div>
</div>
</div>
<van-cell title='电话' clickable @click='form.visitWay = 8'
class='input-back mt-2 form-input'
:style="{borderRadius: form.visitWay == 8 ? '8px 8px 0px 0px ': '8px'}"
>
<template #right-icon>
<van-radio :name='8' />
</template>
</van-cell>
<div class='tel-back' v-if='form.visitWay == 8'>
<div class='tel flex items-center justify-between'>
<div>
<span>居民电话: </span><span>{{ form.telephone }}</span>
</div>
<div @click='toTel' class='tel-label'>点击拨打</div>
</div>
</div>
<!-- @click='form.visitWay = 9'-->
<van-cell title='短信(指导)' clickable
class='input-back mt-2 form-input'
:style="{borderRadius: form.visitWay == 9 ? '8px 8px 0px 0px ': '8px'}"
>
<template #right-icon>
<van-radio-group disabled>
<van-radio :name='9' />
</van-radio-group>
</template>
</van-cell>
<div class='tel-back' v-if='form.visitWay == 9'>
<div class='tel'>
<div>
是否指导?
</div>
<van-radio-group v-model='form.isHealthGuide' direction='horizontal'
shape='dot'>
<div class='flex items-center w-full'>
<van-cell title='是' clickable
@click='form.isHealthGuide = 1'
style='flex: 1'
class='input-back form-input'
>
<template #right-icon>
<van-radio :name='1' />
</template>
</van-cell>
<van-cell title='否' clickable
@click='form.isHealthGuide = 2'
style='flex: 1'
class='input-back form-input ml-2'
>
<template #right-icon>
<van-radio :name='2' />
</template>
</van-cell>
</div>
</van-radio-group>
</div>
</div>
<!-- @click='form.visitWay = 11'-->
<van-cell title='微信(指导)' clickable
class='input-back mt-2 form-input'
:style="{borderRadius: form.visitWay == 11 ? '8px 8px 0px 0px ': '8px'}"
>
<template #right-icon>
<van-radio-group disabled>
<van-radio :name='11' />
</van-radio-group>
</template>
</van-cell>
<div class='tel-back' v-if='form.visitWay == 11'>
<div class='tel'>
<div>
是否指导?
</div>
<van-radio-group v-model='form.isHealthGuide' direction='horizontal'
shape='dot'>
<div class='flex items-center w-full'>
<van-cell title='是' clickable
@click='form.isHealthGuide = 1'
style='flex: 1'
class='input-back form-input'
>
<template #right-icon>
<van-radio :name='1' />
</template>
</van-cell>
<van-cell title='否' clickable
@click='form.isHealthGuide = 2'
style='flex: 1'
class='input-back form-input ml-2'
>
<template #right-icon>
<van-radio :name='2' />
</template>
</van-cell>
</div>
</van-radio-group>
</div>
</div>
<!-- @click='form.visitWay = 10'-->
<van-cell title='短信(催检)' clickable
class='input-back mt-2 form-input'
:style="{borderRadius: form.visitWay == 10 ? '8px 8px 0px 0px ': '8px'}"
>
<template #right-icon>
<van-radio-group disabled>
<van-radio :name='10' />
</van-radio-group>
</template>
</van-cell>
<div class='tel-back' v-if='form.visitWay == 10'>
<div class='tel'>
<div>
催检内容:
</div>
<div>
请您于{{ form.screenTime }}到{{ authInfo.unitName }}进行复查,祝早日 恢复健康!
</div>
<div class='mt-2' style='text-align: center'>
<span style='color: #607FF0' @click='showTime1 = true'>修改日期</span>
</div>
</div>
</div>
<van-popup v-model:show='showTime1' position='bottom'>
<van-date-picker @confirm='timeConfirm1' @cancel='showBirth = false' />
</van-popup>
<!-- @click='form.visitWay = 12'-->
<van-cell title='微信(催检)' clickable
class='input-back mt-2 form-input'
:style="{borderRadius: form.visitWay == 12 ? '8px 8px 0px 0px ': '8px'}"
>
<template #right-icon>
<van-radio-group disabled>
<van-radio :name='12' />
</van-radio-group>
</template>
</van-cell>
<div class='tel-back' v-if='form.visitWay == 12'>
<div class='tel'>
<div>
催检内容:
</div>
<div>
请您于{{ form.screenTime }}到{{ authInfo.unitName }}进行复查,祝早日 恢复健康!
</div>
<div class='mt-2' style='text-align: center'>
<span style='color: #607FF0' @click='showTime2 = true'>修改日期</span>
</div>
</div>
</div>
<van-popup v-model:show='showTime2' position='bottom'>
<van-date-picker @confirm='timeConfirm2' @cancel='showBirth = false' />
</van-popup>
</van-radio-group> <div class='label-title mt-5'>随访类型</div>
</template> <van-field
</van-field> v-model='form.visitWayRulesName'
readonly
is-link
placeholder='请选择'
class='input-back mt-2 form-input'
:rules='rules.visitWayRulesName'
@click='showVisitWayRules= true'
/>
<van-popup v-model:show='showVisitWayRules' position='bottom'>
<div class='p-4'>
<div class='flex justify-between mb-4 items-center pop-title'>
<div class='greyColor' @click='showVisitWayRules = false' style='font-weight: 400'>取消</div>
<div>随访类型(可多选)</div>
<div class='blueColor' @click='visitWayRulesConfirm'>确定</div>
</div>
<CheckBtn multiple column-2 :options='visitWayRulesList' v-model:value='checkVisitWayRules' :fieldNames="{text: 'name', value: 'value'}"/>
</div>
</van-popup>
</van-form> </van-form>
</div> </div>
</template> </template>
<script> <script>
import { addToArr, fetchDataHandle } from '@/utils/common' import { addToArr, callMobile, fetchDataHandle, isIOSWebKit } from '@/utils/common'
import { useStore } from '@/doctor/store' import { useStore } from '@/doctor/store'
import DocAddress from '@/components/docAddress/DocAddress' import DocAddress from '@/components/docAddress/DocAddress'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import CheckBtn from '@/doctor/components/checkBtn/CheckBtn'
const defaultForm = (info = {}) => { const defaultForm = (info = {}) => {
const form = { const form = {
...@@ -489,40 +283,20 @@ const defaultForm = (info = {}) => { ...@@ -489,40 +283,20 @@ const defaultForm = (info = {}) => {
residentInfoId: undefined, residentInfoId: undefined,
// 年龄 // 年龄
currentAge: undefined, currentAge: undefined,
// 出生地详细地址
birthAddress: undefined,
// 出生地编码
birthCode: undefined,
// 证件类型,[DC00004] // 证件类型,[DC00004]
certificateType: 1, certificateType: 1,
certificateTypeName: '身份证', certificateTypeName: '身份证',
// 联系人姓名 // 联系人姓名
contactName: undefined, contactName: undefined,
contactName2: undefined,
// 联系人电话 // 联系人电话
contactPhone: undefined, contactPhone: undefined,
// 与居民关系,[DC00023]
contactRelation: undefined,
contactRelationName: undefined,
// 创建单位id
// createdUnitId: undefined,
// createdUnitName: undefined,
// 创建医生
// createdUserName: undefined,
// 出生日期 // 出生日期
dataBirth: undefined, dataBirth: undefined,
// 职业,[DC00010]
duty: undefined,
dutyName: undefined,
// 文化程度(学历),[DC00007]
education: undefined,
educationName: undefined,
// 性别,[DC00005] // 性别,[DC00005]
gender: undefined, gender: undefined,
genderName: undefined, genderName: undefined,
// 身份证号 // 身份证号
idCard: undefined, idCard: undefined,
// innerMarital: undefined,
// 民族,[DC00006] // 民族,[DC00006]
national: undefined, national: undefined,
nationalName: undefined, nationalName: undefined,
...@@ -542,39 +316,20 @@ const defaultForm = (info = {}) => { ...@@ -542,39 +316,20 @@ const defaultForm = (info = {}) => {
residentName: undefined, residentName: undefined,
// 本人电话 // 本人电话
telephone: undefined, telephone: undefined,
// 工作单位
workUnit: undefined,
// diseaseId: undefined,
// 与居民关系 // 与居民关系
relation: undefined, relation: undefined,
relationName: undefined, relationName: undefined,
relationOther: undefined, relationOther: undefined,
// 人群 //随访人群
// chronicTagsArray: undefined, groupsArrays: undefined,
// 建档单位、科室、医生 groupsArraysName: undefined,
// createDoctorId: undefined, //随访方式
// createDoctorName: undefined, visitWay: undefined,
// createOfficeId: undefined, visitWayName: undefined,
// createOfficeName: undefined, //随访类型
// createUnitId: undefined, visitWayRules: undefined,
// createUnitName: undefined visitWayRulesName: undefined,
//本次随访情况 sendNumber: undefined,
visitSituation: 1,
lossReason: undefined,
deathReason: undefined,
lossReasonOther: undefined,
visitWay: 5,
isHealthGuide: 1,
screenTime: new dayjs().add(1, 'day').format('YYYY-MM-DD'),
chronicCrowd: undefined,
chronicTagsArray: undefined,
firstScreenDate: undefined,
firstScreenResult: undefined,
highTagsArray: undefined,
highTags: undefined,
latelyDiagnoseDate: undefined,
latelyScreenDate:undefined,
} }
Reflect.ownKeys(form).forEach(key => { Reflect.ownKeys(form).forEach(key => {
if (info[key] != undefined) { if (info[key] != undefined) {
...@@ -585,13 +340,18 @@ const defaultForm = (info = {}) => { ...@@ -585,13 +340,18 @@ const defaultForm = (info = {}) => {
} }
export default { export default {
name: 'BaseInfo', name: 'BaseInfo',
components: { DocAddress }, components: { CheckBtn, DocAddress },
props: { props: {
info: { info: {
default: () => { default: () => {
return {} return {}
} }
} },
modeEnumList: {
default: () => {
return {}
}
},
}, },
data() { data() {
return { return {
...@@ -607,6 +367,15 @@ export default { ...@@ -607,6 +367,15 @@ export default {
addressRecord: {}, addressRecord: {},
showTime1: false, showTime1: false,
showTime2: false, showTime2: false,
showGroupsArrays: false,
showVisitWay: false,
showVisitWayRules: false,
//随访人群组件双向绑定变量
checkGroupsArrays: [],
//随访方式组件双向绑定变量
checkVisitWay: [],
//随访类型组件双向绑定变量
checkVisitWayRules: [],
form: {}, form: {},
rules: { rules: {
certificateTypeName: [{ required: true, message: '请选择证件类型' }], certificateTypeName: [{ required: true, message: '请选择证件类型' }],
...@@ -621,16 +390,44 @@ export default { ...@@ -621,16 +390,44 @@ export default {
contactPhone: [{ required: false, message: '请填写联系电话' }], contactPhone: [{ required: false, message: '请填写联系电话' }],
presentCodeName: [{ required: true, message: '请选择所在地区' }], presentCodeName: [{ required: true, message: '请选择所在地区' }],
registeredCode: [{ required: true, message: '请选择所在地区' }], registeredCode: [{ required: true, message: '请选择所在地区' }],
visitSituation: [{ required: true, message: '请选择' }], groupsArraysName: [{ required: true, message: '请选择' }],
lossReason: [{ required: true, message: '请选择' }], visitWay: [{ required: true, message: '请选择' }],
visitWay: [{ required: true, message: '请选择' }] visitWayRulesName: [{ required: true, message: '请选择' }],
} }
} }
}, },
computed: { computed: {
authInfo() { authInfo() {
return this.store.$state.authInfo return this.store.$state.authInfo
} },
//随访人群
groupArrList() {
let res = []
res = this.store.getDict('CP00181')
if (this.info?.groupsArrays) {
let list = this.info.groupsArrays.split(',').map(item => Number(item))
res.forEach(item => {
item.disabled = true
if (list.includes(item.value)) {
item.disabled = false
}
})
} else {
res.forEach(item => {
item.disabled = true
})
}
return res
},
//随访类型
visitWayRulesList() {
let res = []
const {visitWay} = this.form
if (visitWay) {
res = this.modeEnumList.mode1.filter(item => item.value == visitWay)[0].children
}
return res
},
}, },
watch: { watch: {
'info': { 'info': {
...@@ -642,13 +439,14 @@ export default { ...@@ -642,13 +439,14 @@ export default {
if (this.form.registeredCode) { if (this.form.registeredCode) {
this.addressRecord.registeredCode = addToArr(this.form.registeredCode) this.addressRecord.registeredCode = addToArr(this.form.registeredCode)
} }
}, },
immediate: true immediate: true
}, },
'form.visitSituation': { 'form.visitWay': {
handler() { handler() {
this.$emit('changeVisitSituation', this.form.visitSituation) this.form.visitWayRulesName = ''
this.form.visitWayRules = ''
this.checkVisitWayRules = []
} }
} }
}, },
...@@ -691,55 +489,97 @@ export default { ...@@ -691,55 +489,97 @@ export default {
toTel() { toTel() {
// 创建一个电话号码的URL // 创建一个电话号码的URL
let phoneNumber = this.form.telephone // 替换为需要拨打的号码 let phoneNumber = this.form.telephone // 替换为需要拨打的号码
let url = 'tel:' + encodeURIComponent(phoneNumber) //判断是否是iOS环境
// 创建一个a标签 if (isIOSWebKit) {
let a = document.createElement('a') console.log('tel:', phoneNumber)
a.href = url callMobile('startCallUpActivity', phoneNumber)
// 触发a标签的点击事件 } else {
a.click() let url = 'tel://' + encodeURIComponent(phoneNumber)
// 创建一个a标签
let a = document.createElement('a')
a.href = url
// 触发a标签的点击事件
a.click()
}
}, },
timeConfirm1({ selectedValues }) { //随访人群
this.form.screenTime = selectedValues.join('-') groupsArraysConfirm() {
this.showTime1 = false let res = []
this.groupArrList.forEach(item => {
let selected = this.checkGroupsArrays.filter(i => i == item.value)
if (selected && selected.length) {
res.push(item.name)
}
})
if (this.checkGroupsArrays && this.checkGroupsArrays.length) {
this.form.groupsArrays = this.checkGroupsArrays.join()
this.form.groupsArraysName = res.join()
} else {
this.form.groupsArrays = ''
this.form.groupsArraysName = ''
}
this.showGroupsArrays = false
}, },
timeConfirm2({ selectedValues }) { //随访方式
this.form.screenTime = selectedValues.join('-') visitWayConfirm() {
this.showTime2 = false if (this.checkVisitWay) {
this.store.getDict('CP00179').forEach(item => {
if (item.value == this.checkVisitWay) {
this.form.visitWay = item.value
this.form.visitWayName = item.name
}
})
} else {
this.form.visitWay = ''
this.form.visitWayName = ''
}
this.showVisitWay = false
},
//随访类型
visitWayRulesConfirm() {
let res = []
this.visitWayRulesList.forEach(item => {
let selected = this.checkVisitWayRules.filter(i => i == item.value)
if (selected && selected.length) {
res.push(item.name)
}
})
if (this.checkVisitWayRules && this.checkVisitWayRules.length) {
this.form.visitWayRules = this.checkVisitWayRules.join()
this.form.visitWayRulesName = res.join()
} else {
this.form.visitWayRules = ''
this.form.visitWayRulesName = ''
}
this.showVisitWayRules = false
}, },
onSubmit() { onSubmit() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.$refs.form.validate().then(() => { this.$refs.form.validate().then(() => {
const { const {
personId, personId,
visitSituation,
lossReason,
deathReason,
lossReasonOther,
visitWay, visitWay,
isHealthGuide, visitWayRules ,
screenTime, groupsArrays,
sendNumber,
...others ...others
} = this.form } = this.form
let time = dayjs(screenTime).format('YYYY-MM-DD')
let content = `请您于${time}${this.authInfo.unitName}进行复查,祝早日恢复健康!`
let par = { let par = {
visitSituation,
lossReason,
deathReason,
lossReasonOther,
visitWay, visitWay,
isHealthGuide, visitWayRules,
screenTime, groupsArrays,
sendNumber,
residentInfoId: this.form.residentInfoId, residentInfoId: this.form.residentInfoId,
urgentInsContent: content,
residentsRecord: { residentsRecord: {
...others, ...others,
groupsArrays: this.info.groupsArrays,
id: this.form.personId id: this.form.personId
} }
} }
resolve(par) resolve(par)
}).catch((e) => { }).catch((e) => {
console.warn('ArchiveCommon error', e) console.warn('baseInfo error', e)
}) })
}) })
} }
...@@ -812,6 +652,22 @@ export default { ...@@ -812,6 +652,22 @@ export default {
padding: 12px 0px; padding: 12px 0px;
} }
//灰色
.greyColor {
color: var(--van-text-color-2);
}
//确定按钮颜色
.blueColor {
color: var(--van-primary-color)
}
.pop-title {
color: #262626;
font-size: 16px;
line-height: 24px;
font-weight: bold;
}
:deep(.van-cell-group--inset) { :deep(.van-cell-group--inset) {
overflow: visible; overflow: visible;
} }
...@@ -820,9 +676,10 @@ export default { ...@@ -820,9 +676,10 @@ export default {
overflow: visible; overflow: visible;
} }
:deep(.van-field__error-message) { /*:deep(.van-field__error-message) {
position: absolute; position: absolute;
} margin-top: 3px;
}*/
:deep(.van-cell:after) { :deep(.van-cell:after) {
border-bottom: 0px; border-bottom: 0px;
...@@ -835,4 +692,9 @@ export default { ...@@ -835,4 +692,9 @@ export default {
:deep(.van-radio__icon--checked.van-radio__icon--dot) { :deep(.van-radio__icon--checked.van-radio__icon--dot) {
background: var(--van-button-primary-background) background: var(--van-button-primary-background)
} }
:deep(.van-popup) {
min-height: 30%!important;
}
</style> </style>
\ No newline at end of file
<template> <template>
<div> <div>
<van-form ref='form'> <van-form ref='form'>
<div class='no-req-label'>随访单位</div> <div class='no-req-label' v-if='showPush'>请选择推送渠道</div>
<van-field <van-field
v-model='form.visitUnitName' v-model='form.isSmsIsWxStr'
is-link style='padding: 0px'
readonly :rules='rules.isSmsIsWxStr'
placeholder='随访单位' >
class='input-back mt-2 form-input' <template #input>
@click="show1 = true" <div class='w-full'>
/> <div>
<DocUnit v-model:show="show1" v-model:value="form.visitUnitId" @change="changeUnit"/> <checkBtn class='mt-3'
column-1
<div class='no-req-label mt-5'>随访科室</div> text-align='left'
<van-field :options='vxList'
v-model='form.visitOfficeName' v-model:value='checkVx'
is-link :fieldNames="{text: 'name', value: 'value'}"
readonly >
placeholder='随访科室'
class='input-back mt-2 form-input' </checkBtn>
@click='show2 = true' <div class='vx-cb'>
/> <van-checkbox-group v-model='checkVxCb' shape='square' icon-size='18px'>
<DocOffice v-model:show="show2" v-model:value="form.visitOfficeId" @change="changeOffice" :unitId="form.visitUnitId"/> <van-checkbox :name='1' />
</van-checkbox-group>
<div class='no-req-label mt-5'>随访医生</div> </div>
<van-field </div>
v-model='form.visitDoctorName' <div class='push-lab'>随访信息将通过小程序消息推送给居民</div>
is-link <checkBtn class='mt-3'
readonly column-1
placeholder='随访医生' text-align='left'
class='input-back mt-2 form-input' :options='messageList'
@click='show3 = true' v-model:value='checkMessage'
/> :fieldNames="{text: 'name', value: 'value'}"
></checkBtn>
<DocOfficeDoctor v-model:show="show3" v-model:value="form.visitDoctorId" @change="changeDoctor" :unitId="form.visitUnitId" :officeId="form.visitOfficeId"/> <div class='ms-cb'>
<van-checkbox-group v-model='checkMessageCb' shape='square' icon-size='18px'>
<van-checkbox :name='1' />
</van-checkbox-group>
</div>
<div class='push-lab'>随访信息将通过短信方式发送给居民</div>
</div>
</template>
</van-field>
<div :class="['label-title', {'mt-5': showPush}]">随访单位</div>
<van-field
v-model='form.visitUnitName'
is-link
readonly
placeholder='随访单位'
class='input-back mt-2 form-input'
:rules='rules.visitUnitName'
@click='show1 = true'
/>
<DocUnit v-model:show='show1' v-model:value='form.visitUnitId' @change='changeUnit' />
<div class='label-title mt-5'>随访科室</div>
<van-field
v-model='form.visitOfficeName'
is-link
readonly
placeholder='随访科室'
class='input-back mt-2 form-input'
:rules='rules.visitOfficeName'
@click='show2 = true'
/>
<DocOffice v-model:show='show2' v-model:value='form.visitOfficeId' @change='changeOffice'
:unitId='form.visitUnitId' />
<div class='label-title mt-5'>随访医生</div>
<van-field
v-model='form.visitDoctorName'
is-link
readonly
placeholder='随访医生'
class='input-back mt-2 form-input'
:rules='rules.visitDoctorName'
@click='show3 = true'
/>
<DocOfficeDoctor v-model:show='show3' v-model:value='form.visitDoctorId' @change='changeDoctor'
:unitId='form.visitUnitId' :officeId='form.visitOfficeId' />
</van-form> </van-form>
</div> </div>
</template> </template>
...@@ -44,15 +91,27 @@ import { useStore } from '@/doctor/store' ...@@ -44,15 +91,27 @@ import { useStore } from '@/doctor/store'
import DocUnit from '@/doctor/components/docUnit/DocUnit' import DocUnit from '@/doctor/components/docUnit/DocUnit'
import DocOffice from '@/doctor/components/docOffice/DocOffice' import DocOffice from '@/doctor/components/docOffice/DocOffice'
import DocOfficeDoctor from '@/doctor/components/docOfficeDoctor/DocOfficeDoctor' import DocOfficeDoctor from '@/doctor/components/docOfficeDoctor/DocOfficeDoctor'
import CheckBtn from '@/doctor/components/checkBtn/CheckBtn'
export default { export default {
name: 'CommonBottom', name: 'CommonBottom',
components: { DocOfficeDoctor, DocOffice, DocUnit }, components: { CheckBtn, DocOfficeDoctor, DocOffice, DocUnit },
props: { props: {
info: { info: {
default: () => { default: () => {
return {} return {}
} }
},
firstForm: {
default: () => {
return {}
}
},
modeEnumList: {
default: () => {
return {}
}
} }
}, },
data() { data() {
...@@ -61,8 +120,21 @@ export default { ...@@ -61,8 +120,21 @@ export default {
show1: false, show1: false,
show2: false, show2: false,
show3: false, show3: false,
form: {}, vxList: [],
rules: {} checkVx: 1,
checkVxCb: [1],
messageList: [],
checkMessage: undefined,
checkMessageCb: [],
form: {
isSmsIsWx: [1]
},
rules: {
isSmsIsWxStr: [{ required: false, message: '请选择' }],
visitUnitName: [{ required: true, message: '请选择' }],
visitOfficeName: [{ required: true, message: '请选择' }],
visitDoctorName: [{ required: true, message: '请选择' }]
}
} }
}, },
watch: { watch: {
...@@ -71,14 +143,101 @@ export default { ...@@ -71,14 +143,101 @@ export default {
this.form = this.setForm(this.info) this.form = this.setForm(this.info)
}, },
immediate: true immediate: true
},
'firstForm.residentsRecord': {
handler() {
this.vxList = this.getVxEnum(this.firstForm)
this.messageList = this.getMessageEnum(this.firstForm.residentsRecord)
},
immediate: true,
deep: true
},
'checkMessage': {
handler() {
this.form.isSms = 2
if (this.checkMessage) {
this.form.isSms = 1
this.form.isSmsIsWx.push(2)
this.form.isSmsIsWxStr = 2
this.checkMessageCb = [1]
} else {
this.form.isSmsIsWx = this.form.isSmsIsWx.filter(item => item != 2)
this.checkMessageCb = []
//判断推送渠道是否存在值
if (!this.checkVx) {
this.form.isSmsIsWxStr = ''
}
}
}
},
'checkVx': {
handler() {
this.form.isWx = 2
if (this.checkVx) {
this.form.isWx = 1
this.form.isSmsIsWx.push(1)
this.form.isSmsIsWxStr = 1
this.checkVxCb = [1]
} else {
this.form.isSmsIsWx = this.form.isSmsIsWx.filter(item => item != 1)
this.checkVxCb = []
//判断推送渠道是否存在值
if (!this.checkMessage) {
this.form.isSmsIsWxStr = ''
}
}
}
},
'checkVxCb': {
handler() {
if (this.checkVxCb && this.checkVxCb.length) {
this.checkVx = 1
} else {
this.checkVx = undefined
}
}
},
'checkMessageCb': {
handler() {
if (this.checkMessageCb && this.checkMessageCb.length) {
this.checkMessage = 2
} else {
this.checkMessage = undefined
}
}
} }
}, },
computed: { computed: {
authInfo() { authInfo() {
return this.store.$state.authInfo return this.store.$state.authInfo
},
//是否显示推送渠道
showPush() {
let res = false
let list = []
if (this.firstForm.visitWayRules) {
list = this.firstForm.visitWayRules.split(',').map(item => Number(item))
}
if (list && list.length && (list.includes(2) || list.includes(3) || list.includes(4))) {
res = true
}
return res
} }
}, },
methods: { methods: {
//微信
getVxEnum(patientInfo = {}) {
return [{
name: `微信 ${patientInfo.sendNumber ? `(${this.$phoneHide(patientInfo.sendNumber)}已注册小程序)` : `(未注册小程序)`}`,
value: 1
}]
},
getMessageEnum(patientInfo = {}) {
return [{
name: `短信 ${patientInfo.telephone ? `(手机号 ${this.$phoneHide(patientInfo.telephone)})` : `(手机号 不存在)`}`,
value: 2
}]
},
setForm(info) { setForm(info) {
const form = { const form = {
visitDate: new dayjs(), visitDate: new dayjs(),
...@@ -100,7 +259,10 @@ export default { ...@@ -100,7 +259,10 @@ export default {
createOfficeName: this.authInfo.officeName, createOfficeName: this.authInfo.officeName,
// 录入医生 // 录入医生
createDoctorId: this.authInfo.relationId, createDoctorId: this.authInfo.relationId,
createDoctorName: this.authInfo.nickName createDoctorName: this.authInfo.nickName,
isSms: 2,
isWx: 1,
isSmsIsWx: [1]
} }
Reflect.ownKeys(form).forEach(key => { Reflect.ownKeys(form).forEach(key => {
if (info[key] != undefined) { if (info[key] != undefined) {
...@@ -133,13 +295,29 @@ export default { ...@@ -133,13 +295,29 @@ export default {
onSubmit() { onSubmit() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.$refs.form.validate().then(() => { this.$refs.form.validate().then(() => {
const { isSmsIsWx = [], ...others } = this.form
let isSms = 2
let isWx = 2
let wxTel = ''
if (isSmsIsWx.length && this.showPush) {
if (isSmsIsWx.includes(1)) {
isWx = 1
wxTel = this.modeEnumList.weixinTel
}
if (isSmsIsWx.includes(2)) {
isSms = 1
}
}
let par = { let par = {
...this.form, ...others,
isSms,
isWx,
isSmsIsWx,
sendNumber: wxTel
} }
resolve(par) resolve(par)
}).catch((e) => { }).catch((e) => {
console.warn('ArchiveCommon error', e) console.warn('ArchiveCommon error', e)
reject(e)
}) })
}) })
} }
...@@ -166,6 +344,12 @@ export default { ...@@ -166,6 +344,12 @@ export default {
} }
} }
.push-lab {
line-height: 20px;
color: #8C8C8C;
font-size: 12px
}
.no-req-label { .no-req-label {
font-size: 13px; font-size: 13px;
color: #595959; color: #595959;
...@@ -202,6 +386,18 @@ export default { ...@@ -202,6 +386,18 @@ export default {
padding: 12px 0px; padding: 12px 0px;
} }
.vx-cb {
position: absolute;
right: 10px;
top: 23px;
}
.ms-cb {
position: absolute;
right: 10px;
top: 97px;
}
:deep(.van-cell-group--inset) { :deep(.van-cell-group--inset) {
overflow: visible; overflow: visible;
} }
...@@ -210,11 +406,13 @@ export default { ...@@ -210,11 +406,13 @@ export default {
overflow: visible; overflow: visible;
} }
:deep(.van-field__error-message) { /*:deep(.van-field__error-message) {
position: absolute; position: absolute;
} margin-top: 3px;
}*/
:deep(.van-cell:after) { :deep(.van-cell:after) {
border-bottom: 0px; border-bottom: 0px;
} }
</style> </style>
\ No newline at end of file
...@@ -2,176 +2,190 @@ ...@@ -2,176 +2,190 @@
<div> <div>
<van-form ref='form'> <van-form ref='form'>
<div class='title'>随访信息</div> <div class='title'>随访信息</div>
<div v-if='showOne && firstForm.visitSituation == 1'> <div v-if='showOne'>
<div class='no-req-label'>随访内容</div> <div class='label-title'>随访内容</div>
<van-field <van-field
v-model='form.visitContent' v-model='form.visitContent'
placeholder='随访内容' name='visitContent'
class='input-back mt-2 form-input' placeholder='随访内容'
rows='2' class='input-back mt-2 form-input'
autosize rows='2'
type='textarea' autosize
/> type='textarea'
:rules='rules.visitContent'
/>
</div>
<div v-if='showOne'>
<div class='no-req-label mt-5'>处置意见</div>
<van-field
v-model='form.disposalOpinion'
rows='2'
autosize
type='textarea'
placeholder='处置意见'
class='input-back mt-2 form-input'
/>
</div>
<!-- 健康指导-->
<div v-if='showTwo'>
<div class='flex justify-between items-center mt-5'>
<div class='label-title '>健康指导</div>
<!-- <van-button class='doc-btn-p' @click='toShowTem(1)'>选择内容</van-button>-->
</div> </div>
<div v-if='showOne && firstForm.visitSituation == 1'> <div class='health mt-2'>
<div class='no-req-label mt-5'>处置意见</div> <GuideTextVideo :file-type='[1]'
<van-field :info='form.guide'
v-model='form.disposalOpinion' :content-title="'指导内容'"
rows='2' :classify='1'
autosize @changeSelect='toShowTem'
type='textarea' ref='guideRef'
placeholder='处置意见' ></GuideTextVideo>
class='input-back mt-2 form-input'
/>
</div> </div>
<div v-if='(showOne || showTwo) && firstForm.visitSituation == 1 && firstForm.isHealthGuide == 1'> </div>
<div class='no-req-label mt-5'>健康指导</div> <!-- 宣教内容-->
<div class='health mt-2'> <div v-if='showThree'>
<div class='health-cell mt-2' v-for='item in form.visitHealthGuideList'> <div class='flex justify-between items-center mt-5'>
<div class='no-req-label' v-if="item.name != '无'">{{ item.name }}</div> <div class='label-title '>宣教内容</div>
<van-field <!-- <van-button class='doc-btn-p' @click='toShowTem(2)'>选择内容</van-button>-->
v-model='item.templateContent'
rows='1'
autosize
type='textarea'
placeholder='请输入'
class='input-back mt-2 form-input'
/>
</div>
</div>
</div> </div>
<div class='health mt-2'>
<div v-if='showOne && firstForm.visitSituation == 1'> <div class='health-cell mt-2'>
<div class='no-req-label mt-5'>上传随访记录</div> <div class='no-req-label'>健康宣教</div>
<div class='tips'> <van-field
支持上传jpg、png、jpeg文件,大小请在10M以内 v-model='form.publicizeTypeName'
</div> readonly
<div class='img-btn mt-2' @click="toUpload('imgId')"> is-link
<input type='file' id='imgId' multiple @change='choiceImg' style='display: none' placeholder='请选择'
:key='new Date().getTime()' accept="image/*,.pdf"> class='input-back mt-2 form-input'
<div class='flex items-center justify-center'> @click='showPublicizeType= true'
<div> >
<doc-icon type='doc-upload' class='doc-up' /> <template #input>
</div> <span class='text-end' v-if='form.publicizeTypeName'>{{ form.publicizeTypeName }}</span>
<div class='ml-2'>上传图片</div> <span class='text-end' v-if='!form.publicizeTypeName' style='color: #dfdfe1'>请选择</span>
</div> </template>
</div> </van-field>
<van-popup v-model:show='showPublicizeType' position='bottom'>
<div class='flex items-center' style='flex-wrap: wrap'> <div class='p-4'>
<div v-for='(item, index) in imgList'> <div class='flex justify-between mb-4 items-center pop-title'>
<!-- 图片--> <div class='greyColor' @click='showPublicizeType = false' style='font-weight: 400'>
<div v-if="item.imgFlag == 'img'" class='mt-2' style='position: relative'> 取消
<div>
<doc-icon type='doc-remove' class='remove' @click='delImg(item.indexF)'></doc-icon>
</div>
<img :src='item.trueDownloadUrl' class='ml-2' style='width: 95px;height: 95px;'
@click='toPreview(imgList,index)'>
</div>
</div>
</div>
<!-- pdf-->
<div>
<div v-for='item in imgList'>
<div class='mt-2 pdf' v-if="item.imgFlag == 'pdf'">
<div class='flex items-center justify-between'>
<div class='flex items-center' @click.stop='toPdf(item)'>
<div>
<doc-icon type='doc-PDF' style='font-size: .48rem'></doc-icon>
</div>
<div class='ml-1'>{{ item.name }}</div>
</div>
<div>
<span><doc-icon type='doc-remove' style='font-size: .24rem'
@click='delImg(item.indexF)'></doc-icon></span>
</div> </div>
<div>健康宣教(可多选)</div>
<div class='blueColor' @click='publicizeTypeConfirm'>确定</div>
</div> </div>
<CheckBtn multiple column-3 :options="store.getDict('DC00091')"
v-model:value='checkPublicizeType'
:fieldNames="{text: 'name', value: 'value'}"
/>
</div> </div>
</div> </van-popup>
</div> </div>
<div class='mt-2' v-if='form.publicizeTypeName &&!form?.publicizeType?.includes(1)'>
<div v-if='imgList.length > 6' class='warn mt-2'>最多允许上传6张!</div> <van-button type='primary' plain class='w-full' @click='toShowTem(2)' size='small'>选择内容</van-button>
</div> </div>
<div v-if='form?.publicizeType?.includes(1)'>
<div v-if='showOne && firstForm.visitSituation == 1'> <GuideTextVideo :file-type='[1]'
<div class='no-req-label mt-5'>现场随访照片</div> :info='form.publicize'
<div class='tips'> :content-title="'文本内容'"
支持上传jpg、png、jpeg文件,大小请在10M以内 :classify='2'
@changeSelect='toShowTem'
ref='contentOne'></GuideTextVideo>
</div> </div>
<div class='img-btn mt-2' @click="toUpload('imgId2')"> <div v-if='form?.publicizeType?.includes(2)'>
<input type='file' id='imgId2' multiple @change='choiceImg2' style='display: none' <GuideTextVideo :file-type='[2]'
:key='new Date().getTime()-10000' accept="image/*,.pdf"> :info='form.publicize'
<div class='flex items-center justify-center'> :classify='2'
<div> ref='contentTwo'></GuideTextVideo>
<doc-icon type='doc-upload' class='doc-up' /> </div>
</div> <div v-if='form?.publicizeType?.includes(3)'>
<div class='ml-2'>上传图片</div> <GuideTextVideo :file-type='[3]'
</div> :info='form.publicize'
:classify='2'
ref='contentThree'></GuideTextVideo>
</div> </div>
<div class='flex items-center' style='flex-wrap: wrap'> </div>
<div v-for='(item, index) in imgList2'> </div>
<!-- 图片-->
<div v-if="item.imgFlag == 'img'" class='mt-2' style='position: relative'> <!-- 催检-->
<div> <div v-if='showFour'>
<doc-icon type='doc-remove' class='remove' @click='delImg2(item.indexF)'></doc-icon> <div class='no-req-label mt-5'>催检内容</div>
</div> <div class='tel-back mt-2'>
<img :src='item.trueDownloadUrl' class='ml-2' style='width: 95px;height: 95px;' <div class='tel'>
@click='toPreview(imgList2 ,index)'> <div style='text-indent: 2em;line-height: .2rem'>
</div> <span v-if='modeEnumList.urgeResidentShow'>{{ firstForm.residentsRecord.residentName
}}先生/女士,</span>
<span v-else>您好,</span>
<span>请您于{{ form.screenTime }}</span>
<span>到{{ authInfo.unitName }}</span>
<span>进行专病高危筛查/慢病复查,</span>
<span>祝早日康复!</span>
</div> </div>
</div> <div class='mt-2' style='text-align: center' @click='showTime1 = true'>
<!-- pdf--> <span style='color: #607FF0'>修改日期</span>
<div>
<div v-for='item in imgList2'>
<div class='mt-2 pdf' v-if="item.imgFlag == 'pdf'">
<div class='flex items-center justify-between'>
<div class='flex items-center' @click.stop='toPdf(item)'>
<div>
<doc-icon type='doc-PDF' style='font-size: .48rem'></doc-icon>
</div>
<div class='ml-1'>{{ item.name }}</div>
</div>
<div>
<span><doc-icon type='doc-remove' style='font-size: .24rem'
@click='delImg2(item.indexF)'></doc-icon></span>
</div>
</div>
</div>
</div> </div>
</div> </div>
<div v-if='imgList2.length > 8' class='warn mt-2'>最多允许上传8张!</div>
</div>
<!-- 图片预览-->
<van-overlay :show='imgShow' @click='imgShow = false'>
<div class='wrapper'>
<van-swipe class='block' :initial-swipe='initSwipe'>
<van-swipe-item v-for='image in showImgList' :key='image'>
<img :src='image' style='width: 100%;height: 100%'/>
</van-swipe-item>
</van-swipe>
</div>
</van-overlay>
<div v-if='firstForm.visitSituation == 1'>
<div class='label-title mt-5'>下次随访日期</div>
<van-field
v-model='form.nextVisitDate'
is-link
readonly
name='nextVisitDate'
placeholder='下次随访日期'
class='input-back mt-2 form-input'
:rules='rules.nextVisitDate'
@click='showDate = true' />
<van-popup v-model:show='showDate' position='bottom'>
<van-date-picker v-model="form._nextVisitDate"
:min-date="nextVisitDateRange.min"
:max-date="nextVisitDateRange.max"
@confirm='dataConfirm' @cancel='showDate = false' />
</van-popup>
</div> </div>
<DataTime
:values='startTime'
:showType="['year', 'month', 'day', 'hour']"
@changeValue='showTime1 = false'
:showPicker='showTime1'
@confirm='timeConfirm1'
:min-date='startDateRange.min'
:max-date='startDateRange.max'
/>
</div>
<!-- 上传随访照片-->
<div v-if='showOne'>
<div class='no-req-label mt-5'>上传随访记录</div>
<DocImageUpload
description='支持上传jpg、png、jpeg文件,大小请在10M以内'
lengthMessage='抱歉,最多可上传6个文件。'
:imageData='[]'
@change='(ids, option) => form.uploadVisitRecord = ids'
:maxLength='6'
class='mt-2'
/>
</div>
<!-- 现场随访照片-->
<div>
<div class='no-req-label mt-5'>现场随访照片</div>
<DocImageUpload
description='支持上传jpg、png、jpeg文件,大小请在10M以内'
lengthMessage='抱歉,最多可上传6个文件。'
:imageData='[]'
@change='(ids, option) => form.sceneVisitImage = ids'
:maxLength='6'
class='mt-2'
/>
</div>
<div>
<div class='label-title mt-5'>下次随访日期</div>
<van-field
v-model='form.nextVisitDate'
is-link
readonly
name='nextVisitDate'
placeholder='下次随访日期'
class='input-back mt-2 form-input'
:rules='rules.nextVisitDate'
@click='showDate = true' />
<van-popup v-model:show='showDate' position='bottom'>
<van-date-picker v-model='form._nextVisitDate'
:min-date='nextVisitDateRange.min'
:max-date='nextVisitDateRange.max'
@confirm='dataConfirm' @cancel='showDate = false' />
</van-popup>
</div>
</van-form> </van-form>
<div v-if='showTem'>
<temList :show='showTem' @closed='closedTem' @selectRecord='getSelectTem' :templateClassify='citeInfo'></temList>
</div>
</div> </div>
</template> </template>
...@@ -179,12 +193,18 @@ ...@@ -179,12 +193,18 @@
import { useStore } from '@/resident/store' import { useStore } from '@/resident/store'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import DocIcon from '@/components/docIcon/DocIcon' import DocIcon from '@/components/docIcon/DocIcon'
import { showToast } from 'vant' import { showFailToast, showToast } from 'vant'
import { fetchDataHandle } from '@/utils/common' import { fetchDataHandle, uniqueArr } from '@/utils/common'
import DocImageUpload from '@/doctor/components/docImageUpload/DocImageUpload'
import TemList from '@/doctor/components/template/temList'
import { getTemplateDetail } from '@/api/doctor/workbench'
import GuideTextVideo from '@/doctor/followUp/generalFU/form/GuideTextVideo'
import CheckBtn from '@/doctor/components/checkBtn/CheckBtn'
import DataTime from '@/doctor/components/dataTime/dataTime'
export default { export default {
name: 'GeneralFUForm', name: 'GeneralFUForm',
components: { DocIcon }, components: { DataTime, CheckBtn, GuideTextVideo, TemList, DocImageUpload, DocIcon },
props: { props: {
info: { info: {
default: () => { default: () => {
...@@ -195,23 +215,26 @@ export default { ...@@ -195,23 +215,26 @@ export default {
default: () => { default: () => {
return {} return {}
} }
},
modeEnumList: {
default: () => {
return {}
}
} }
}, },
data() { data() {
return { return {
store: useStore(), store: useStore(),
form: {}, form: {},
//展示用
imgList: [],
imgList2: [],
//input图片值
imgInputList1: [],
imgInputList2: [],
showDate: false, showDate: false,
imgShow: false, showTime1: false,
showImgList: [], showTem: false,
initSwipe: 0, showPublicizeType: false,
checkPublicizeType: [],
currentTime1: null,
citeInfo: 1,
rules: { rules: {
visitContent: [{ required: true, message: '请输入' }],
nextVisitDate: [{ required: true, message: '请选择' }] nextVisitDate: [{ required: true, message: '请选择' }]
}, },
// 筛查日期可选范围 // 筛查日期可选范围
...@@ -219,75 +242,65 @@ export default { ...@@ -219,75 +242,65 @@ export default {
min: undefined, min: undefined,
max: undefined max: undefined
}, },
startTime: '',
// 催检时间范围
startDateRange: {
min: undefined,
max: undefined
},
} }
}, },
watch: { watch: {
'info': { 'info': {
handler() { handler() {
this.form = this.setForm(this.info) this.form = this.setForm(this.info)
if (this.info.id) {
this.imgList = this.imgListInfo1
this.imgList2 = this.imgListInfo2
}
}, },
immediate: true immediate: true
}, }
}, },
computed: { computed: {
//复检指导 authInfo() {
return this.store.$state.authInfo
},
//复检
showOne() { showOne() {
const { visitWay } = this.firstForm const { visitWayRules } = this.firstForm
let res = false let res = false
if (visitWay == 5 || visitWay == 6 || visitWay == 7 || visitWay == 8) { let list = visitWayRules && visitWayRules.split(',').map(item => Number(item))
if (list && list.includes(1)) {
res = true res = true
} }
return res return res
}, },
//微信、短信指导 //指导
showTwo() { showTwo() {
const { visitWay } = this.firstForm const { visitWayRules } = this.firstForm
let res = false let res = false
if (visitWay == 9 || visitWay == 11) { let list = visitWayRules && visitWayRules.split(',').map(item => Number(item))
if (list && list.includes(2)) {
res = true res = true
} }
return res return res
}, },
//催检 //宣教
showThree() { showThree() {
const { visitWay } = this.firstForm const { visitWayRules } = this.firstForm
let res = false let res = false
if (visitWay == 10 || visitWay == 12) { let list = visitWayRules && visitWayRules.split(',').map(item => Number(item))
if (list && list.includes(3)) {
res = true res = true
} }
return res return res
}, },
imgListInfo1() { //催检
const { uploadVisitRecordImageList = [] } = this.info showFour() {
uploadVisitRecordImageList.forEach((item, index) => { const { visitWayRules } = this.firstForm
item['imgFlag'] = '' let res = false
item['indexF'] = index + 1 let list = visitWayRules && visitWayRules.split(',').map(item => Number(item))
if (item.fileType == 'pdf') { if (list && list.includes(4)) {
item['imgFlag'] = 'pdf' res = true
} }
if (item.fileType == 'img') { return res
item['imgFlag'] = 'img'
}
})
return uploadVisitRecordImageList
},
imgListInfo2() {
const { sceneVisitImageList = [] } = this.info
sceneVisitImageList.forEach((item, index) => {
item['imgFlag'] = ''
item['indexF'] = index + 1
if (item.fileType == 'pdf') {
item['imgFlag'] = 'pdf'
}
if (item.fileType == 'img') {
item['imgFlag'] = 'img'
}
})
return sceneVisitImageList
} }
}, },
created() { created() {
...@@ -295,150 +308,436 @@ export default { ...@@ -295,150 +308,436 @@ export default {
this.nextVisitDateRange.max = new Date(date.year() + 10, date.month(), date.date()) this.nextVisitDateRange.max = new Date(date.year() + 10, date.month(), date.date())
this.nextVisitDateRange.min = new Date(date.year(), date.month(), date.date() + 1) this.nextVisitDateRange.min = new Date(date.year(), date.month(), date.date() + 1)
this.form._nextVisitDate = [date.year(), date.month(), date.date() + 1] this.form._nextVisitDate = [date.year(), date.month(), date.date() + 1]
let time = new dayjs().add(1, 'day').format('YYYY-MM-DD')
this.currentTime1 = time.split('-')
this.startTime = new dayjs().add(1, 'day').format('YYYY-MM-DD HH:mm:ss')
this.startDateRange.max = new Date(date.year() + 10, date.month(), date.date())
this.startDateRange.min = new Date(date.year(), date.month(), date.date())
}, },
methods: { methods: {
setForm(info = {}) { setForm(data = {}) {
const modeArray = this.store.getDict('DC00084') let info = fetchDataHandle(data, {
let visitHealthGuideList = [] visitWayRules: 'strToArrNum',
if (info.healthGuideContent) { groupsArrays: 'strToArrNum',
visitHealthGuideList = JSON.parse(info.healthGuideContent) publicizeType: 'strToArrNum'
})
let isSmsIsWx = []
if (info.id) {
const { isSms, isWx } = info
if (isSms == 1) {
isSmsIsWx = [1]
}
if (isWx == 1) {
isSmsIsWx = [2]
}
if (isSms == 1 && isWx == 1) {
isSmsIsWx = [1, 2]
}
} else {
isSmsIsWx = [1]
} }
const form = { const form = {
id: info.id, id: info.id,
diseaseType: info.diseaseType, groupsArrays: info.groupsArrays,
visitDate: info.visitDate || new dayjs(), visitDate: info.visitDate || new dayjs(),
nextVisitDate: info.nextVisitDate, nextVisitDate: info.nextVisitDate,
visitWay: info.visitWay || 1,
isSms: info.isSms, isSms: info.isSms,
isWx: info.isWx, isWx: info.isWx,
isSmsIsWx: isSmsIsWx,
visitContent: info.visitContent, visitContent: info.visitContent,
disposalOpinion: info.disposalOpinion, disposalOpinion: info.disposalOpinion,
uploadVisitRecord: info.uploadVisitRecord, uploadVisitRecord: info.uploadVisitRecord,
sceneVisitImage: info.sceneVisitImage, sceneVisitImage: info.sceneVisitImage,
screenTime: info.screenTime || new dayjs().add(1, 'day').format('YYYY-MM-DD HH:00:00'),
sendInfo: info.sendInfo, sendInfo: info.sendInfo,
visitHealthGuideList: modeArray.map(e => { publicizeType: info.publicizeType,
const item = visitHealthGuideList.find(i => i.templateMode === e.value) guide: info.guide || {},
return { publicize: info.publicize || {}
templateMode: e.value,
name: e.name,
templateContent: item ? item.templateContent : '',
id: item ? item.visitId : ''
}
})
} }
return form return form
}, },
setTemForm(info) { dataConfirm({ selectedValues }) {
const modeArray = this.store.getDict('DC00084') this.form.nextVisitDate = selectedValues.join('-')
const visitHealthGuideList = info.contentList || [] this.showDate = false
const form = {
visitHealthGuideList: modeArray.map(e => {
const item = visitHealthGuideList.find(i => i.templateMode === e.value)
return {
templateMode: e.value,
name: e.name,
templateContent: item ? item.templateContent : '',
id: item ? item.visitId : ''
}
})
}
return form.visitHealthGuideList
}, },
toUpload(id) { //催检日期选择
if (id === 'imgId' && this.imgList.length > 6) { timeConfirm1(selectedValues) {
showToast('最多允许上传6张') this.form.screenTime = dayjs(selectedValues).format('YYYY-MM-DD HH:00:00')
return this.startTime = dayjs(selectedValues).format('YYYY-MM-DD HH:00:00')
} this.showTime1 = false
if (id === 'imgId2' && this.imgList2.length > 8) { },
showToast('最多允许上传8张') toShowTem(val) {
return this.citeInfo = val
} this.showTem = true
let input = document.getElementById(id) },
input.click() closedTem(val) {
this.showTem = val
}, },
choiceImg() { //获取选中的模板
let input = document.getElementById('imgId') async getSelectTem(val, selectType = []) {
let file = input.files if (val && selectType && selectType.length) {
let newFile = Array.from(file) let par = { id: val }
let maxIndexF = this.imgList.length ? Math.max(...this.imgList.map(item => item.indexF)) : 0 let result = await getTemplateDetail(par)
newFile.forEach((item, index) => { const { data } = result
item['indexF'] = maxIndexF + index + 1 let obj = {
item['trueDownloadUrl'] = window.URL.createObjectURL(item) annexList: [],
item['imgFlag'] = '' contentList: [],
if (item.type == 'application/pdf') { drugsList: []
item['imgFlag'] = 'pdf'
} }
if (item.type == 'image/jpeg' || item.type == 'image/png' || item.type == 'image/gif' || item.type == 'image/webp') { let mp3List = data.annexList && data.annexList.filter(item => item.type == 2)
item['imgFlag'] = 'img' let mp4List = data.annexList && data.annexList.filter(item => item.type == 3)
if (selectType.includes(1)) { //是否返回文本选中
obj.contentList = data.contentList
obj.drugsList = data.drugsList
} }
}) if (selectType.includes(2)) {//是否返回音频选中
this.imgList = this.imgList.concat(newFile) obj.annexList = [...obj.annexList, ...mp3List]
this.imgInputList1 = this.imgInputList1.concat(newFile)
},
choiceImg2() {
let input = document.getElementById('imgId2')
let file = input.files
let newFile = Array.from(file)
let maxIndexF = this.imgList2.length ? Math.max(...this.imgList2.map(item => item.indexF)) : 0
newFile.forEach((item, index) => {
item['indexF'] = maxIndexF + index + 1
item['trueDownloadUrl'] = window.URL.createObjectURL(item)
item['imgFlag'] = ''
if (item.type == 'application/pdf') {
item['imgFlag'] = 'pdf'
} }
if (item.type == 'image/jpeg' || item.type == 'image/png' || item.type == 'image/gif' || item.type == 'image/webp') { if (selectType.includes(3)) {//是否返回视频选中
item['imgFlag'] = 'img' obj.annexList = [...obj.annexList, ...mp4List]
} }
}) //健康指导
this.imgList2 = this.imgList2.concat(newFile) if (this.showTwo && this.citeInfo == 1) {
console.log(this.imgList2) this.setGuide(obj)
this.imgInputList2 = this.imgInputList2.concat(newFile) }
//宣教内容
if (this.showThree && this.citeInfo == 2) {
this.setPublicize(obj)
}
}
}, },
//图片预览 publicizeTypeConfirm() {
toPreview(list = [], index) {
let res = [] let res = []
this.showImgList = [] this.store.getDict('DC00091').forEach(item => {
list.forEach(item => { let selected = this.checkPublicizeType.filter(i => i == item.value)
res.push(item.trueDownloadUrl) if (selected && selected.length) {
res.push(item.name)
}
}) })
this.showImgList = res if (this.checkPublicizeType && this.checkPublicizeType.length) {
this.initSwipe = index this.form.publicizeType = this.checkPublicizeType.join()
this.imgShow = true this.form.publicizeTypeName = res.join()
}, } else {
//pdf预览 this.form.publicizeType = ''
toPdf(item) { this.form.publicizeTypeName = ''
// window.open(item.trueDownloadUrl) }
}, this.showPublicizeType = false
delImg(index) {
this.imgList = this.imgList.filter(item => item.indexF != index)
this.imgInputList1 = this.imgInputList1.filter(item => item.indexF != index)
}, },
delImg2(index) { //健康指导模板赋值
this.imgList2 = this.imgList2.filter(item => item.indexF != index) async setGuide(val = {}) {
this.imgInputList2 = this.imgInputList2.filter(item => item.indexF != index) //获取上一次的值
let lastObj = {
contentList: [],
drugsList: []
}
let obj = await this.$refs.guideRef.getForm()
lastObj = {
contentList: obj.contentList,
drugsList: obj.drugsList
}
//重新赋值
let resObj = {
contentList: [],
drugsList: []
}
if (lastObj.contentList && lastObj.contentList.length) {
resObj.contentList = [...lastObj.contentList]
}
if (lastObj.drugsList && lastObj.drugsList.length) {
resObj.drugsList = [...lastObj.drugsList]
}
//判断模板文本是否选中 并赋值
if (val.contentList) {
//文本内容区域存在 初始值 后面选中的模板内容需要拼接在初始值后面
if (lastObj.contentList && lastObj.contentList.length) {
//合并相同的文本选项内容
resObj.contentList.forEach(item => {
val.contentList.forEach(vitem => {
if (item.templateMode != 5 && item.templateMode == vitem.templateMode) {
item.templateContent = item.templateContent ? item.templateContent + `\n` + vitem.templateContent : vitem.templateContent
}
})
})
//去掉 返回的val中与合并后相同的文本
resObj.contentList.forEach(item => {
let reIndex = val.contentList.findIndex(vitem => vitem.templateMode == item.templateMode)
if (reIndex != -1) {
val.contentList.splice(reIndex, 1)
}
})
//合并剩余的val.contentList到 resObj.contentList中
resObj.contentList = [...resObj.contentList, ...val.contentList]
//合并药物指导
//判断之前是否存在药物指导
if (lastObj.drugsList && lastObj.drugsList.length) {
//获取之前药物指导的最大_id的值
let rowId = 0
rowId = Math.max.apply(null, lastObj.drugsList.map(item => Number(item._id)))
val.drugsList.forEach((item, index) => {
item.id = ''
item._id = rowId + index + 1
})
//合并
resObj.drugsList = [...resObj.drugsList, ...val.drugsList]
} else {
resObj.drugsList = [...val.drugsList]
}
} else {
if (val.contentList) {
resObj.contentList = [...val.contentList]
resObj.drugsList = [...val.drugsList]
}
}
} else {
//模板未选中文本 赋初始值
if (lastObj.contentList && lastObj.contentList.length) {
resObj.contentList = [...lastObj.contentList]
}
}
console.log('resObj', resObj)
this.form.guide = resObj
}, },
dataConfirm({ selectedValues }) { //宣教内容模板赋值
this.form.nextVisitDate = selectedValues.join('-') async setPublicize(val = {}) {
this.showDate = false //获取上一次的值
let lastObj = {
annexList: [],
contentList: [],
drugsList: []
}
//文本
if (this.form?.publicizeType?.includes(1)) {
let obj1 = await this.$refs.contentOne.getForm()
lastObj = {
annexList: [],
contentList: obj1.contentList,
drugsList: obj1.drugsList
}
}
//音频
if (this.form?.publicizeType?.includes(2)) {
let obj2 = await this.$refs.contentTwo.getForm()
let list = obj2.annexList.filter(item => item.type == 2)
lastObj = {
...lastObj,
annexList: list
}
}
//视频
if (this.form?.publicizeType?.includes(3)) {
let obj3 = await this.$refs.contentThree.getForm()
let list = obj3.annexList.filter(item => item.type == 3)
lastObj = {
...lastObj,
annexList: [...lastObj.annexList, ...list]
}
}
//重新赋值
console.log('json', val)
let resObj = {
annexList: [],
contentList: [],
drugsList: []
}
const { publicizeType = [], publicize = {} } = this.form
if (lastObj.annexList && lastObj.annexList.length) {
resObj.annexList = [...lastObj.annexList]
}
if (lastObj.contentList && lastObj.contentList.length) {
resObj.contentList = [...lastObj.contentList]
}
if (lastObj.drugsList && lastObj.drugsList.length) {
resObj.drugsList = [...lastObj.drugsList]
}
//文本
if (publicizeType.includes(1)) {
//判断模板文本是否选中 并赋值
if (val.contentList) {
//文本内容区域存在 初始值 后面选中的模板内容需要拼接在初始值后面
if (lastObj.contentList && lastObj.contentList.length) {
//合并相同的文本选项内容
resObj.contentList.forEach(item => {
val.contentList.forEach(vitem => {
if (item.templateMode != 5 && item.templateMode == vitem.templateMode) {
item.templateContent = item.templateContent ? item.templateContent + `\n` + vitem.templateContent : vitem.templateContent
}
})
})
//去掉 返回的val中与合并后相同的文本
resObj.contentList.forEach(item => {
let reIndex = val.contentList.findIndex(vitem => vitem.templateMode == item.templateMode)
if (reIndex != -1) {
val.contentList.splice(reIndex, 1)
}
})
//合并剩余的val.contentList到 resObj.contentList中
resObj.contentList = [...resObj.contentList, ...val.contentList]
//合并药物指导
//判断之前是否存在药物指导
if (lastObj.drugsList && lastObj.drugsList.length) {
//获取之前药物指导的最大_id的值
let rowId = 0
rowId = Math.max.apply(null, lastObj.drugsList.map(item => Number(item._id)))
val.drugsList.forEach((item, index) => {
item.id = ''
item._id = rowId + index + 1
})
//合并
resObj.drugsList = [...resObj.drugsList, ...val.drugsList]
} else {
resObj.drugsList = [...val.drugsList]
}
} else {
if (val.contentList) {
resObj.contentList = [...val.contentList]
resObj.drugsList = [...val.drugsList]
}
}
} else {
//模板未选中文本 赋初始值
if (lastObj.contentList && lastObj.contentList.length) {
resObj.contentList = [...lastObj.contentList]
}
}
}
//音频
if (publicizeType.includes(2)) {
//判断模板音频是否选中 并赋值
let mp3List = val.annexList.filter(item => item.type == 2) || []
if (mp3List && mp3List.length) {
if (resObj.annexList && resObj.annexList.length) {
let rowId = 0
rowId = Math.max.apply(null, resObj.annexList.map(item => Number(item.annexId)))
mp3List.forEach((item, index) => {
item['annexId'] = rowId + index + 1
resObj.annexList.push(item)
})
} else {
resObj.annexList = [...mp3List]
}
}
}
//视频
if (publicizeType.includes(3)) {
//判断模板视频是否选中 并赋值
let mp4List = val.annexList.filter(item => item.type == 3) || []
if (mp4List && mp4List.length) {
if (resObj.annexList && resObj.annexList.length) {
let rowId = 0
rowId = Math.max.apply(null, resObj.annexList.map(item => Number(item.annexId)))
mp4List.forEach((item, index) => {
item['annexId'] = rowId + index + 1
resObj.annexList.push(item)
})
} else {
resObj.annexList = [...mp4List]
}
}
}
//对视频音频去重
resObj.annexList = uniqueArr(resObj.annexList, 'relativeUrl')
this.form.publicize = resObj
}, },
onSubmit() { async onSubmit() {
try {
if (this.showTwo) {
await this.$refs.guideRef.submit()
}
if (this.showThree) {
//文本
if (this.form?.publicizeType?.includes(1)) {
await this.$refs.contentOne.submit()
}
//音频
if (this.form?.publicizeType?.includes(2)) {
await this.$refs.contentTwo.submit()
}
//视频
if (this.form?.publicizeType?.includes(3)) {
await this.$refs.contentThree.submit()
}
}
}catch (e) {}
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.$refs.form.validate().then(() => { this.$refs.form.validate().then(async () => {
if (this.imgList.length > 6 || this.imgList2.length > 8) { let time = dayjs(this.form.screenTime).format('YYYY-MM-DD HH:00:00')
return let content = `${this.modeEnumList?.urgeResidentShow ? `${this.firstForm?.residentsRecord?.residentName}先生/女士,` : `您好,`}请您于${time}${this.authInfo.unitName}进行专病高危筛查/慢病复查,祝早日恢复健康!`
const { publicizeType, ...others } = this.form
let publicizeTypeInfo = ''
if (publicizeType && publicizeType instanceof Array) {
publicizeTypeInfo = publicizeType.join()
}
if (publicizeType && typeof publicizeType === 'string') {
publicizeTypeInfo = publicizeType
}
let res = {
...others,
publicizeType: publicizeTypeInfo,
urgentInsContent: content
}
//健康指导
if (this.showTwo) {
let obj = await this.$refs.guideRef.submit()
res.guide = {
contentList: obj.contentList,
drugsList: obj.drugsList
}
} }
let par = { //宣教内容
img1: this.imgList || [], if (this.showThree) {
img2: this.imgList2 || [], let resObj = {
imgInput1: this.imgInputList1, annexList: [],
imgInput2: this.imgInputList2, contentList: [],
...this.form, drugsList: []
healthGuideContent: JSON.stringify(this.form.visitHealthGuideList) }
//文本
if (this.form?.publicizeType?.includes(1)) {
let obj1 = await this.$refs.contentOne.submit()
resObj = {
annexList: [],
contentList: obj1.contentList,
drugsList: obj1.drugsList
}
}
//音频
if (this.form?.publicizeType?.includes(2)) {
let obj2 = await this.$refs.contentTwo.submit()
let list = obj2.annexList.filter(item => item.type == 2)
if (!list.length) {
showFailToast('请上传音频')
return
}
resObj = {
...resObj,
annexList: list
}
}
//视频
if (this.form?.publicizeType?.includes(3)) {
let obj3 = await this.$refs.contentThree.submit()
let list = obj3.annexList.filter(item => item.type == 3)
if (!list.length) {
showFailToast('请上传视频')
return
}
resObj = {
...resObj,
annexList: [...resObj.annexList, ...list]
}
}
res.publicize = {
...resObj
}
} }
resolve(par) resolve(res)
}).catch((e) => { }).catch((e) => {
console.warn('ArchiveCommon error', e) console.warn('generaFu error', e)
// reject(e) // reject(e)
}) })
}) })
...@@ -448,6 +747,21 @@ export default { ...@@ -448,6 +747,21 @@ export default {
</script> </script>
<style scoped lang='less'> <style scoped lang='less'>
// 按钮样式
.doc-btn {
border: 0;
padding: 4px 8px;
height: 26px;
border-radius: 38px;
}
.doc-btn-p {
.doc-btn();
color: var(--van-primary-color);
background: #F0F3FF;
font-size: 13px;
}
.title { .title {
font-weight: bold; font-weight: bold;
margin-bottom: 20px; margin-bottom: 20px;
...@@ -546,11 +860,13 @@ export default { ...@@ -546,11 +860,13 @@ export default {
top: -9px; top: -9px;
z-index: 1; z-index: 1;
} }
.wrapper { .wrapper {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
height: 100%; height: 100%;
.block { .block {
width: 100%; width: 100%;
height: 300px; height: 300px;
...@@ -565,19 +881,40 @@ export default { ...@@ -565,19 +881,40 @@ export default {
overflow: visible; overflow: visible;
} }
:deep(.van-field__error-message) { //:deep(.van-field__error-message) {
position: absolute; // position: absolute;
} // margin-top: 3px;
//}
:deep(.van-cell:after) { :deep(.van-cell:after) {
border-bottom: 0px; border-bottom: 0px;
} }
.warn { .warn {
color: #ee0a24; color: #ee0a24;
text-align: left; text-align: left;
} }
//灰色
.greyColor {
color: var(--van-text-color-2);
}
//确定按钮颜色
.blueColor {
color: var(--van-primary-color)
}
.pop-title {
color: #262626;
font-size: 16px;
line-height: 24px;
font-weight: bold;
}
:deep(.van-popup) {
min-height: 30% !important;
}
</style> </style>
<style lang='less'> <style lang='less'>
...@@ -596,4 +933,5 @@ export default { ...@@ -596,4 +933,5 @@ export default {
.van-swipe-item { .van-swipe-item {
width: 100% !important; width: 100% !important;
} }
</style> </style>
\ No newline at end of file
<template>
<van-form ref='form'
class='grow flex flex-col' style='min-height: 1px;flex-wrap: nowrap;'>
<div class='flex flex-col' v-if='fileType?.includes(1)'>
<div>
<!-- 无选项-->
<div class='health-cell mt-2' v-for="item in form.contentList.filter(e => e.templateModeTrans == '无')">
<div class='no-req-label'>{{ contentTitle }}</div>
<van-field
v-model='item.templateContent'
rows='1'
autosize
type='textarea'
placeholder='请输入'
class='input-back mt-2 form-input'
:rules='rules.templateContent'
/>
</div>
<!-- 更多选项-->
<div class='health-cell mt-2'>
<div class='no-req-label'>更多{{ contentTitle }}</div>
<van-field
v-model='form.contentSelectName'
readonly
is-link
placeholder='请选择'
class='input-back mt-2 form-input'
name='contentSelectName'
:rules='rules.contentSelectName'
@click='showContentSelect= true'
>
<template #input>
<span class='text-end' v-if='form.contentSelectName'>{{ form.contentSelectName }}</span>
<span class='text-end' v-if='!form.contentSelectName' style='color: #dfdfe1'>请选择</span>
</template>
</van-field>
<van-popup v-model:show='showContentSelect' position='bottom'>
<div class='p-4'>
<div class='flex justify-between mb-4 items-center pop-title'>
<div class='greyColor' @click='showContentSelect = false' style='font-weight: 400'>取消
</div>
<div>{{ contentTitle }}(可多选)</div>
<div class='blueColor' @click='contentSelectConfirm'>确定</div>
</div>
<CheckBtn multiple column-2 :options='contentArray' v-model:value='checkContentSelect'
:fieldNames="{text: 'name', value: 'value'}" />
</div>
</van-popup>
</div>
<div v-if='form.contentSelectName' class='mt-2'>
<van-button type='primary' plain class='w-full' @click='choiceTel' size='small'>选择内容</van-button>
</div>
<div class='health-cell mt-2' v-for="item in form.contentList.filter(e => e.templateModeTrans != '无')">
<template v-if='item.templateMode === 5'>
<div class='no-req-label'>药物指导</div>
<div v-for='(item, index) in form.drugsList' :key='item._id'
:style="{marginTop: index == 0 ? '0': '.16rem'}">
<div class='text-driver' v-if='index'></div>
<DocDrug v-model:value='item.drugsCode' placeholder='拼音码查询药品'
:valueName="selectData.drugsList ? selectData.drugsList[index]?.helpCode : ''"
@change='drugChange($event, item)'
/>
<div class='flex items-center justify-between w-full mt-2'>
<van-field
v-model='item.dose'
placeholder='输入'
label='剂量:'
type='digit'
class='input-back form-input'
style='flex: 1'
:rules='rules.dose'
/>
<van-field
v-model='item.doseUnitName'
readonly
placeholder='请选择'
class='input-back ml-2 form-input'
style='width: .8rem'
@click='showDoseUnit= true'
:rules='rules.doseUnitName'
/>
</div>
<van-popup v-model:show='showDoseUnit' position='bottom'>
<div class='p-4'>
<van-picker
:columns-field-names="{ text: 'name', value: 'value' }"
:columns="store.getDict('CP00081')"
@confirm='doseUnitConfirm($event, item)'
@cancel='showDoseUnit = false'
/>
</div>
</van-popup>
<van-field
v-model='item.frequencyName'
readonly
is-link
label='频次:'
placeholder='请选择'
class='input-back mt-2 form-input'
@click='showFrequency= true'
:rules='rules.frequencyName'
/>
<van-popup v-model:show='showFrequency' position='bottom'>
<div class='p-4'>
<van-picker
:columns-field-names="{ text: 'name', value: 'value' }"
:columns="store.getDict('CP00084')"
@confirm='frequencyConfirm($event, item)'
@cancel='showFrequency = false'
/>
</div>
</van-popup>
<van-field
v-model='item.usageMethodName'
readonly
is-link
label='用法:'
placeholder='请选择'
class='input-back mt-2 form-input'
@click='showUsageMethod= true'
:rules='rules.usageMethodName'
/>
<van-popup v-model:show='showUsageMethod' position='bottom'>
<div class='p-4'>
<van-picker
:columns-field-names="{ text: 'name', value: 'value' }"
:columns="store.getDict('CP00083')"
@confirm='usageMethodConfirm($event, item)'
@cancel='showUsageMethod = false'
/>
</div>
</van-popup>
<div class='mt-2 text-center'>
<van-button type='primary' plain class='btn-br' @click='addDrug'>增加</van-button>
<van-button plain class='btn-br'
@click='minusDrug(item, index)'
v-if='form?.drugsList?.length > 1'
style='margin-left: .16rem'
>删除
</van-button>
</div>
</div>
</template>
<div class='no-req-label' v-if='item.templateMode != 5'>{{ item.templateModeTrans }}</div>
<van-field
v-model='item.templateContent'
v-if='item.templateMode != 5'
rows='1'
autosize
type='textarea'
placeholder='请输入'
:name='item.templateContent'
:rules="[{ required: true, message: '请输入' }]"
class='input-back mt-2 form-input'
/>
</div>
</div>
</div>
<div v-if='fileType.includes(2)' class='w-full'>
<div class='health-cell mt-2'>
<div class='no-req-label'>音频</div>
<Mp3 :file='item' v-for='item in _audio' :key='item.annexId'
:activeMediaUrl='activeMediaUrl'
@play='e => activeMediaUrl = e.annexUrl'
remove
@onRemove='getMP3RemoveInfo'
class='mt-2'
/>
</div>
</div>
<div v-if='fileType.includes(3)' class='w-full'>
<div class='health-cell mt-2'>
<div class='no-req-label'>视频</div>
<Mp4 :files='_video' :activeMediaUrl='activeMediaUrl'
@play='e => activeMediaUrl = e.annexUrl'
remove
@onRemove='getMP4RemoveInfo'
class='mt-2'
/>
</div>
</div>
</van-form>
</template>
<script>
import { fetchDataHandle } from '@/utils/common'
import { useStore } from '@/doctor/store'
import DocDrug from '@/doctor/components/docDrug/DocDrug'
import Mp3 from '@/doctor/components/mediaPlay/Mp3.vue'
import Mp4 from '@/doctor/components/mediaPlay/Mp4.vue'
import CheckBtn from '@/doctor/components/checkBtn/CheckBtn'
export default {
name: 'GuideTextVideo',
components: { CheckBtn, Mp4, Mp3, DocDrug },
props: {
info: {
default: () => {
return {}
}
},
//内容标题
contentTitle: {
default: () => {
return '宣教内容'
}
},
// 文件类型 1:文本 2、文字播报 3、视频
fileType: Array,
// 分类
classify: Number
},
data() {
return {
store: useStore(),
//更多指导内容
showContentSelect: false,
checkContentSelect: [],
//药物剂量
showDoseUnit: false,
//药物频次
showFrequency: false,
//药物用法
showUsageMethod: false,
form: {},
selectData: {},
// 控制音频同一时间只播放一个
activeMediaUrl: '',
hideActiveMediaUrl: '',
rules: {
templateContent: [{ required: true, message: '请输入' }],
dose: [{ required: true, message: '请输入' }],
doseUnitName: [{ required: true, message: '请选择' }],
frequencyName: [{ required: true, message: '请选择' }],
usageMethodName: [{ required: true, message: '请选择' }]
}
}
},
computed: {
contentArray() {
let res = []
res = this.store.getDict('DC00084').filter(item => item.value != 1)
return res
},
// 音频、视频 回显使用
_video() {
const annexList = this.selectData.annexList || []
return annexList.filter(e => e.type === 3).map(e => {
return {
annexFileName: e.annexFileName,
trueDownloadUrl: e.annexUrl,
annexUrl: e.annexUrl,
relativeUrl: e.relativeUrl,
fileType: 'mp4',
md5Hash: e.annexMd5,
id: e.annexId
}
})
},
_audio() {
const annexList = this.selectData.annexList || []
return annexList.filter(e => e.type === 2).map(e => {
return {
annexFileName: e.annexFileName,
trueDownloadUrl: e.annexUrl,
annexUrl: e.annexUrl,
relativeUrl: e.relativeUrl,
fileType: 'mp3',
md5Hash: e.annexMd5,
id: e.annexId
}
})
}
},
watch: {
'info': {
handler() {
if (this.info) {
this.selectData = fetchDataHandle(this.info || {}, {
templateType: 'strToArrNum',
fileType: 'strToArrNum'
})
const annexList = this.selectData.annexList || []
this.selectData._video = annexList.filter(e => e.type === 3)
this.selectData._audio = annexList.filter(e => e.type === 2)
this.form = this.setTemForm(this.selectData)
} else {
this.form = this.setTemForm({})
}
},
immediate: true
},
'form.contentSelectName': {
handler() {
this.contentSelectChange()
}
}
},
methods: {
//指导和宣教赋值
setTemForm(info = {}) {
let contentList = []
let initC = [
{
templateContent: '',
templateId: '',
templateMode: 1,
templateModeTrans: '无'
}
]
let infoC = info.contentList || []
//判断父组件的数据里是否存在 无 的选项
let resList = infoC.filter(item => item.templateMode == 1)
if (!resList.length) { //不存在无选项
contentList = [...initC, ...infoC]
} else {
contentList = [...infoC]
}
const drugsList = info?.drugsList?.length ? info.drugsList.map(e => {
if (e.id) {
e._id = e.id
e.doseUnitName = this.store.getDictValue(this.store.getDict('CP00081'), e.doseUnit)
e.frequencyName = this.store.getDictValue(this.store.getDict('CP00084'), e.frequency)
e.usageMethodName = this.store.getDictValue(this.store.getDict('CP00083'), e.usageMethod)
}
return e
}) : []
//给更多内容赋值
let contentSelectName = ''
let contentSelectNameList = []
this.checkContentSelect = []
contentList.forEach(item => {
if (item.templateMode != 1) {
this.checkContentSelect.push(item.templateMode)
contentSelectNameList.push(item.templateModeTrans)
}
if (contentSelectNameList && contentSelectNameList.length) {
contentSelectName = contentSelectNameList.join()
}
})
const form = {
id: info.id,
templateType: info.templateType,
templateName: info.templateName,
templateMode: info.templateMode || 1,
fileType: info.fileType || [1],
templateClassify: info.templateClassify || 1,
businessType: info.businessType || 1,
contentList: JSON.parse(JSON.stringify(contentList)),
contentSelect: contentList.map(e => e.templateMode),
drugsList: JSON.parse(JSON.stringify(drugsList)),
annexList: info.annexList || [],
// 存放上传后返回的id
_video: JSON.parse(JSON.stringify(info._video || [])),
_audio: JSON.parse(JSON.stringify(info._audio || [])),
drugSelect: 1,
contentSelectName: contentSelectName
}
return form
},
// 选择的模板内容变化
contentSelectChange() {
const cont = this.form.contentList || []
let val = this.checkContentSelect
let delValue = []
cont.forEach(i => {
if (!val.includes(i.templateMode) && i.templateMode != 1) {
delValue.push(i.templateMode)
}
})
if (delValue.length) {
this.form.contentList = this.form.contentList.filter(e => !delValue.includes(e.templateMode))
// 药物指导处理
if (delValue.includes(5)) {
this.form.drugsList = []
}
}
const addValue = this.checkContentSelect.filter(e => !cont.find(i => i.templateMode === e))
if (addValue.length) {
addValue.forEach(e => {
this.form.contentList.push({
templateMode: e,
templateModeTrans: this.store.getDictValue('DC00084', e),
templateContent: undefined,
id: undefined
})
})
// 药物指导处理
if (addValue.includes(5)) {
this.addDrug()
}
}
},
// 添加药品
addDrug() {
this.form.drugsList.push(this.drugItem())
},
drugItem() {
let rowId = 0
if (this.form.drugsList.length > 0) {
rowId = Math.max.apply(null, this.form.drugsList.map(item => Number(item._id)))
}
return {
_id: rowId + 1,
// 药品名称
drugsName: undefined,
drugsCode: undefined,
// 剂量单位,[CP00081]
doseUnit: 1,
// 每次剂量
dose: undefined,
// 频次,[CP00084]
frequency: undefined,
// 用法,[CP00083]
usageMethod: undefined,
// 每日几次
// dayTime: undefined,
helpCode: undefined
}
},
drugChange(option, item) {
item.drugsName = option.chemicalName
item.helpCode = option.helpCode
},
minusDrug(item, index) {
this.form.drugsList = this.form.drugsList.filter(e => e._id !== item._id)
},
getRef() {
return this.$refs.form
},
choiceTel() {
this.$emit('changeSelect', this.classify)
},
contentSelectConfirm() {
let res = []
this.contentArray.forEach(item => {
let selected = this.checkContentSelect.filter(i => i == item.value)
if (selected && selected.length) {
res.push(item.name)
}
})
if (this.checkContentSelect && this.checkContentSelect.length) {
this.form.contentSelect = this.checkContentSelect.join()
this.form.contentSelectName = res.join()
} else {
this.form.contentSelect = ''
this.form.contentSelectName = ''
}
this.showContentSelect = false
},
doseUnitConfirm({ selectedValues, selectedOptions }, item) {
item.doseUnit = selectedValues[0]
item.doseUnitName = selectedOptions[0].name
this.showDoseUnit = false
},
frequencyConfirm({ selectedValues, selectedOptions }, item) {
item.frequency = selectedValues[0]
item.frequencyName = selectedOptions[0].name
this.showFrequency = false
},
usageMethodConfirm({ selectedValues, selectedOptions }, item) {
item.usageMethod = selectedValues[0]
item.usageMethodName = selectedOptions[0].name
this.showUsageMethod = false
},
//删除MP3
getMP3RemoveInfo(val) {
this.selectData.annexList.forEach((item, index) => {
if (item.relativeUrl == val.relativeUrl) {
this.selectData.annexList.splice(index, 1)
}
})
},
//删除MP4
getMP4RemoveInfo(val) {
this.selectData.annexList.forEach((item, index) => {
if (item.relativeUrl == val.relativeUrl) {
this.selectData.annexList.splice(index, 1)
}
})
},
submit() {
return new Promise((resolve, reject) => {
console.log(this.form)
if (this.form.contentList && this.form.contentList.length > 1 ) {
this.rules.templateContent[0].required = false
} else {
this.rules.templateContent[0].required = true
}
this.$refs.form.validate().then(valid => {
/* if (this.form.fileType.includes(3) && !this.form._video.length) {
this.$message.info('请上传视频')
return
}
if (this.form.fileType.includes(2) && !this.form._audio.length) {
this.$message.info('请上传音频')
return
}*/
const query = fetchDataHandle({ ...this.form }, {
templateType: 'arrToStr',
fileType: 'arrToStr'
})
const annexList = []
this._video.forEach(e => {
annexList.push({
type: 3,
annexId: e.annexId,
relativeUrl: e.relativeUrl,
annexFileName: e.annexFileName
})
})
this._audio.forEach(e => {
annexList.push({
type: 2,
annexId: e.annexId,
relativeUrl: e.relativeUrl,
annexFileName: e.annexFileName
})
})
query.annexList = annexList
const contentList = query.contentList
const item = contentList.find(e => e.templateMode == 5)
if (item) {
const drugsList = query.drugsList
let str = ''
drugsList.forEach(e => {
str = `药品名:${e.drugsName} 剂量:${e.dose} ${this.store.getDictValue('CP00081', e.doseUnit)} 频次:${this.store.getDictValue('CP00084', e.frequency)} 用法:${this.store.getDictValue('CP00083', e.usageMethod)}\n` + str
})
item.templateContent = str
}
resolve(query)
}).catch(e => {
reject(e)
})
})
},
getForm() {
return new Promise((resolve, reject) => {
const query = fetchDataHandle({ ...this.form }, {
templateType: 'arrToStr',
fileType: 'arrToStr'
})
const annexList = []
this._video.forEach(e => {
annexList.push({
type: 3,
annexId: e.annexId,
annexUrl: e.annexUrl,
relativeUrl: e.relativeUrl,
annexFileName: e.annexFileName
})
})
this._audio.forEach(e => {
annexList.push({
type: 2,
annexId: e.annexId,
annexUrl: e.annexUrl,
relativeUrl: e.relativeUrl,
annexFileName: e.annexFileName
})
})
query.annexList = annexList
const contentList = query.contentList
const item = contentList.find(e => e.templateMode == 5)
if (item) {
const drugsList = query.drugsList
let str = ''
drugsList.forEach(e => {
str = `药品名:${e.drugsName} 剂量:${e.dose} ${this.store.getDictValue('CP00081', e.doseUnit)} 频次:${this.store.getDictValue('CP00084', e.frequency)} 用法:${this.store.getDictValue('CP00083', e.usageMethod)}\n` + str
})
item.templateContent = str
}
resolve(query)
}).catch(e => {
console.log( 'GuideTextVideo',e)
})
}
}
}
</script>
<style lang='less' scoped>
.action-box {
width: 56px;
font-size: 20px;
.svg-icon {
vertical-align: baseline;
}
}
.drug-list {
background-color: #F5F5F5;
}
.health {
padding: 1px 8px 8px 8px;
background: #FAFAFA;
border-radius: 8px;
.health-cell {
padding: 8px;
background: #FFFFFF;
border-radius: 8px;
}
}
.no-req-label {
font-size: 13px;
color: #595959;
font-weight: 500;
}
.form-input {
padding: 8px 12px;
border-radius: 8px;
}
.input-back {
background: #FAFAFA;
}
.text-driver {
border: 1px solid #EEEEEE;
margin-bottom: 8px;
margin-top: 8px;
}
.btn-br {
border-radius: 38px;
width: 112px;
padding: 4px 8px;
height: 26px;
font-size: 13px;
}
//灰色
.greyColor {
color: var(--van-text-color-2);
}
//确定按钮颜色
.blueColor {
color: var(--van-primary-color)
}
.pop-title {
color: #262626;
font-size: 16px;
line-height: 24px;
font-weight: bold;
}
//:deep(.van-field__error-message) {
// position: relative!important;
//}
</style>
\ No newline at end of file
<template> <template>
<div> <div>
<van-nav-bar :title="routerDetail.id ? '修改通用随访': '新增通用随访'" left-text='' left-arrow @click-left='toBack'></van-nav-bar> <van-nav-bar :title="routerDetail.id ? '修改通用随访': '新增通用随访'" left-text='' left-arrow
<div class='p-4 h-overflow'> @click-left='toBack'></van-nav-bar>
<base-info :info='info' v-show='step == 1' ref='baseInfo' <div class='p-4 h-overflow' ref='all'>
@changeVisitSituation='changeVisitSituation'></base-info> <base-info :info='info'
<general-f-u-form :info='info' :first-form='firstForm' v-show='step == 2' :modeEnumList='modeEnumList'
ref='generalFUForm'></general-f-u-form> v-show='step == 1'
<common-bottom :info='info' v-show='step == 3' ref='commonBottom'></common-bottom> ref='baseInfo'
></base-info>
<general-f-u-form :info='info'
:first-form='firstForm'
:modeEnumList='modeEnumList'
v-show='step == 2'
ref='generalFUForm'
></general-f-u-form>
<common-bottom :info='info'
:first-form='firstForm'
:modeEnumList='modeEnumList'
v-show='step == 3'
ref='commonBottom'
></common-bottom>
</div> </div>
<div class='bottom-small-line'></div>
<div class='pt-2 pb-2'> <div class='pt-2 pb-2'>
<div class='px-5 grow flex flex-col justify-end' v-if='step == 1'> <div class='px-5 grow flex flex-col justify-end' v-if='step == 1'>
<van-button type='primary' block round v-if='visitSituation == 1' <van-button type='primary' block round
@click='toNext(2)'>下一步 @click='toNext(2)'>下一步
</van-button> </van-button>
<van-button type='primary' block round v-if='visitSituation == 2'
@click='toNext(3)'>下一步
</van-button>
</div> </div>
<div class='px-5 flex align-center justify-around' v-if='step == 2'> <div class='px-5 flex align-center justify-around' v-if='step == 2'>
...@@ -41,26 +52,95 @@ import BaseInfo from '@/doctor/followUp/generalFU/form/BaseInfo' ...@@ -41,26 +52,95 @@ import BaseInfo from '@/doctor/followUp/generalFU/form/BaseInfo'
import { import {
addCurrency, addCurrency,
fetchCurrencyById, fetchCurrencyById,
getChronicResidentsId, getChronicResidentsId, getResidentWX,
updateCurrency, updateCurrency,
upLoadMultifile upLoadMultifile
} from '@/api/doctor/generalFU' } from '@/api/doctor/generalFU'
import GeneralFUForm from '@/doctor/followUp/generalFU/form/GeneralFUForm' import GeneralFUForm from '@/doctor/followUp/generalFU/form/GeneralFUForm'
import CommonBottom from '@/doctor/followUp/generalFU/form/CommonBottom' import CommonBottom from '@/doctor/followUp/generalFU/form/CommonBottom'
import { useStore } from '@/doctor/store'
const getModeEnum = (patientInfo = {}) => {
return {
mode1: [
{
value: '1', name: `门诊`,
children: [
{ value: 1, name: `复检`, disabled: false },
{ value: 2, name: `指导`, disabled: false },
{ value: 3, name: `宣教`, disabled: false },
{ value: 4, name: `催检`, disabled: true }
]
},
{
value: '2', name: `住院`,
children: [
{ value: 1, name: `复检`, disabled: false },
{ value: 2, name: `指导`, disabled: false },
{ value: 3, name: `宣教`, disabled: false },
{ value: 4, name: `催检`, disabled: true }
]
},
{
value: '3', name: `入户`,
children: [
{ value: 1, name: `复检`, disabled: false },
{ value: 2, name: `指导`, disabled: false },
{ value: 3, name: `宣教`, disabled: false },
{ value: 4, name: `催检`, disabled: true }
]
},
{
value: '4', name: `电话`,
children: [
{ value: 1, name: `复检`, disabled: false },
{ value: 2, name: `指导`, disabled: false },
{ value: 3, name: `宣教`, disabled: true },
{ value: 4, name: `催检`, disabled: false }
]
},
{
value: '5', name: `短信`,
children: [
{ value: 1, name: `复检`, disabled: true },
{ value: 2, name: `指导`, disabled: false },
{ value: 3, name: `宣教`, disabled: false },
{ value: 4, name: `催检`, disabled: false }
]
},
{
value: '6', name: `微信`,
children: [
{ value: 1, name: `复检`, disabled: true },
{ value: 2, name: `指导`, disabled: false },
{ value: 3, name: `宣教`, disabled: false },
{ value: 4, name: `催检`, disabled: false }
]
}
],
tel: `(本人电话:${patientInfo.telephone || ''})`,
weixi: `(绑定电话:${patientInfo.weixin || '未绑定'})`,
telephone: patientInfo.telephone,
weixinTel: patientInfo.weixin,
//是否下次随访日期必填
nextVisitDateReq: true,
//催检内容是否显示患者姓名
urgeResidentShow: true
}
}
export default { export default {
name: 'Index', name: 'Index',
components: { CommonBottom, GeneralFUForm, BaseInfo }, components: { CommonBottom, GeneralFUForm, BaseInfo },
data() { data() {
return { return {
store: useStore(),
info: {}, info: {},
resident: {}, resident: {},
visitSituation: 1,
step: 1, step: 1,
//第一步提交的表单 //第一步提交的表单
firstForm: {}, firstForm: {},
//居民信息 //居民信息
residentInfo: {} residentInfo: {},
modeEnumList: getModeEnum({})
} }
}, },
created() { created() {
...@@ -77,8 +157,8 @@ export default { ...@@ -77,8 +157,8 @@ export default {
if (this.routerDetail.id) { if (this.routerDetail.id) {
const res = await fetchCurrencyById({ id: this.routerDetail.id }) const res = await fetchCurrencyById({ id: this.routerDetail.id })
let result = res.data || {} let result = res.data || {}
const {residentsRecord = {}} = result const { residentsRecord = {} } = result
const {id, ...others} = residentsRecord const { id, ...others } = residentsRecord
this.info = { this.info = {
...others, ...others,
personId: id, personId: id,
...@@ -86,6 +166,7 @@ export default { ...@@ -86,6 +166,7 @@ export default {
} }
} else { } else {
const res = await getChronicResidentsId(this.routerDetail.residentInfoId) const res = await getChronicResidentsId(this.routerDetail.residentInfoId)
const weixinInfo = await getResidentWX({residentInfoId: this.routerDetail.residentInfoId})
const { const {
id, id,
createDate, createDate,
...@@ -100,13 +181,15 @@ export default { ...@@ -100,13 +181,15 @@ export default {
} = res.data } = res.data
this.info = { this.info = {
personId: id, personId: id,
...others ...others,
sendNumber: weixinInfo?.data?.isWx ? weixinInfo?.data?.telephone : ''
} }
this.info.diseaseType = this.routerDetail.diseaseType this.info.diseaseType = this.routerDetail.diseaseType
} }
this.modeEnumList = getModeEnum(this.info)
}, },
async toNext(val) { async toNext(val) {
this.$refs.all.scrollTo(0, 0)
if (val == 2) { if (val == 2) {
this.firstForm = await this.$refs.baseInfo.onSubmit() this.firstForm = await this.$refs.baseInfo.onSubmit()
} }
...@@ -115,9 +198,6 @@ export default { ...@@ -115,9 +198,6 @@ export default {
} }
this.step = val this.step = val
}, },
changeVisitSituation(val) {
this.visitSituation = val
},
//图片上传 //图片上传
async upload(imgList = []) { async upload(imgList = []) {
let list = [] let list = []
...@@ -148,60 +228,27 @@ export default { ...@@ -148,60 +228,27 @@ export default {
let baseInfo = await this.$refs.baseInfo.onSubmit() let baseInfo = await this.$refs.baseInfo.onSubmit()
let generalFUForm = await this.$refs.generalFUForm.onSubmit() let generalFUForm = await this.$refs.generalFUForm.onSubmit()
let commonBottom = await this.$refs.commonBottom.onSubmit() let commonBottom = await this.$refs.commonBottom.onSubmit()
let imgInput1List = []
let imgInput2List = []
let uploadVisitRecord = ''
let sceneVisitImage = ''
//图片上传
if (generalFUForm.imgInput1.length) {
imgInput1List = await this.upload(generalFUForm.imgInput1)
}
if (generalFUForm.imgInput2.length) {
imgInput2List = await this.upload(generalFUForm.imgInput2)
}
if (generalFUForm.img1.length) {
let img1List = this.baseImgHandle(generalFUForm.img1)
let lsit1 = [...imgInput1List, ...img1List]
uploadVisitRecord = Array.from(new Set(lsit1)).join()
}
if (generalFUForm.img2.length) {
let img2List = this.baseImgHandle(generalFUForm.img2)
let lsit2 = [...imgInput2List, ...img2List]
sceneVisitImage = Array.from(new Set(lsit2)).join()
}
let params = { let params = {
...baseInfo,
...generalFUForm, ...generalFUForm,
...commonBottom, ...commonBottom,
uploadVisitRecord, ...baseInfo,
sceneVisitImage,
source: 2 source: 2
} }
if (this.info.id) { if (this.info.id) {
params.visitRecordId = this.info.visitRecordId params.visitRecordId = this.info.visitRecordId
} }
if (params.visitSituation == 2) {
params.visitWay = 14
}
let fun = this.info.id ? updateCurrency : addCurrency let fun = this.info.id ? updateCurrency : addCurrency
fun(params, true).then(({ code }) => { fun(params, true).then(({ code }) => {
if (code == 'SUCCESS') { if (code == 'SUCCESS') {
this.store.onRefreshMark()
this.$router.back() this.$router.back()
} }
}) })
}, },
toBack() { toBack() {
if (this.visitSituation == 1) { if (this.step != 1) {
if (this.step != 1) { this.step--
this.step-- return
return
}
}
if (this.visitSituation == 2) {
if (this.step != 1) {
this.step = 1
return
}
} }
this.$router.back() this.$router.back()
} }
......
<template>
<div class="h-full flex flex-col patient-detail">
<DocNavBar title="居民详情" class="shrink-0">
<template #right>
<span class="text-primary" @click="() => addVisible = true">新增</span>
</template>
</DocNavBar>
<div class="grow flex flex-col" style="background: #f5f5f5;min-height: 0px;">
<div :class="['px-4 pt-4 doc-list-card resident-info shrink-0',
{'resident-info-collapsed': collapsed}]">
<div class="mb-4">
<span class="name mr-2">{{ residentInfo.residentName || '-' }}</span>
<span class="tag mr-2">{{ residentInfo.currentAge || '-' }}岁</span>
<span class="tag mr-2">{{ residentInfo.genderName || '-' }}</span>
<doc-icon type="doc-edit" class="text-primary" @click="toArchivesEdit"/>
</div>
<div class="flex flex-col" style="row-gap: .04rem;line-height: 1.5;">
<div>
<span class="label">身份证号</span>
<span>{{ $idCardHide(residentInfo.idCard) || '-' }}</span>
</div>
<div class="flex">
<span class="label shrink-0">人群标签</span>
<span class="grow text-wrap">{{ residentInfo.groupsArraysName || '-' }}</span>
</div>
<div>
<span class="label">联系电话</span>
<span>{{ $phoneHide(residentInfo.telephone) || '-' }}</span>
</div>
<!-- <div>
<span class="label">人群分类</span>
<span>{{ residentInfo.chronicCrowdName || '-' }}</span>
</div>
<div class="flex">
<span class="label">慢病标签</span>
<span>
<ChronicTag :list='residentInfo.chronicTagsArray' />
</span>
</div> -->
<div>
<span class="label">建档状态</span>
<span v-if="residentInfo.id">
<span v-if="!!residentInfo.residentsBaseDTO">已建档</span>
<span v-else style="color: #8C8C8C">未建档</span>
</span>
</div>
<div>
<span class="label">签约状态</span>
<span v-if="residentInfo.id">
<span v-if="!!residentInfo.signedInfoDTO">已签约</span>
<span v-else style="color: #8C8C8C">未签约</span>
</span>
</div>
</div>
<div :class="['text-center py-1 fold-btn', { 'fold-btn-collapsed': collapsed }]"
@click="() => collapsed = !collapsed">
<doc-icon type="doc-left-1" />
</div>
</div>
<van-tabs shrink v-model:active="activeTab" class="shrink-0 patient-detail-tabs">
<van-tab v-for="item in tabList" :key="item.id"
:title="item.name"></van-tab>
</van-tabs>
<div class="grow py-3 px-2" style="min-height: 0px;" v-if="residentInfo.id">
<ScreeningList v-if="activeTabItem.id === 'SCREENING'"/>
<GeneralList v-else-if="activeTabItem.id === 'CURRENCY'"/>
<ReferralList v-else-if="activeTabItem.id === 'REFERRAL'"/>
<ConsultationList v-else-if="activeTabItem.id === 'CONSULTATION'"/>
<DiseaseList v-else :diseaseName="activeTabItem.name" :diseaseType="activeTabItem.value"/>
</div>
<van-popup
v-model:show="addVisible"
position="bottom"
:style="{ height: '30%' }"
>
<div class="popup-bottom-panel">
<div class="p-4 text-16 flex items-center justify-between"
style="border-bottom: 1px solid #00000019;">
<span class="left" @click="addVisible = false">取消</span>
<span class="font-semibold">请选择</span>
<span class="right" style="width: .32rem;"></span>
</div>
<div class="p-4">
<CheckBtn :options="addOptions" activeStyleNone
@change="onAddChange" column-1 />
<div class="pb-4"></div>
</div>
</div>
</van-popup>
</div>
</div>
</template>
<script>
import { queryResidentInfo } from '@/api/doctor/resident.js'
import { showNotify, showToast } from 'vant'
import DocNavBar from '@/doctor/components/docNavBar/DocNavBar.vue'
import ChronicTag from '@/doctor/components/chronicTag/ChronicTag.vue'
import CheckBtn from '@/doctor/components/checkBtn/CheckBtn.vue'
import ScreeningList from './components/screening/Index.vue'
import GeneralList from './components/generalFU/List.vue'
import ReferralList from './components/referral/List.vue'
import ConsultationList from './components/consultation/List.vue'
import DiseaseList from './components/disease/Index.vue'
export default {
name: 'PatientDetail',
components: {
DocNavBar,
ChronicTag,
ScreeningList,
GeneralList,
ReferralList,
ConsultationList,
DiseaseList,
CheckBtn
},
data() {
return {
residentInfoId: null,
residentInfo: {},
// 折叠
collapsed: true,
// 标签页index
activeTab: 0,
// 新增弹窗
addVisible: false,
addOptions: [
{ name: '新增通用随访', value: 1, path: '/doctor/followUp/generalFU/add' }
]
}
},
provide() {
return {
residentInfo: () => this.residentInfo
}
},
computed: {
chronicTagsArray() {
const chronicTagsArray = this.residentInfo.chronicTagsArray || ''
return chronicTagsArray.split(',')
},
groupsArrays() {
const groupsArrays = this.residentInfo.groupsArrays || ''
return groupsArrays.split(',')
},
// 死亡状态
deathStatus() {
return this.residentInfo.chronicStatus
},
tabList() {
const diseaseList = [
{ name: '高血压', value: 1, code: '512', id: 'HYPERTENSION' },
{ name: '糖尿病', value: 2, code: '1024', id: 'DIABETE' },
{ name: '冠心病', value: 3, code: '2048', id: 'COPD' },
{ name: '脑卒中', value: 4, code: '4096', id: 'STROKE' },
{ name: '慢性阻塞性疾病', value: 5, code: '8192', id: 'NEPHROPATHY' },
{ name: '慢性肾脏病', value: 6, code: '16384', id: 'KIDNEY' },
{ name: '血脂异常', value: 7, code: '32768', id: 'DYSLIPEMIA' }
]
const result = [
{ name: '筛查管理', id: 'SCREENING' },
...diseaseList.filter(e => this.groupsArrays.includes(e.code)),
{ name: '通用随访', id: 'CURRENCY' },
// { name: '转诊记录', id: 'REFERRAL' },
// { name: '会诊记录', id: 'CONSULTATION' }
]
return result
},
activeTabItem() {
return this.tabList[this.activeTab] || {}
},
},
activated() {
this.residentInfoId = this.$route.query.residentInfoId
},
methods: {
load() {
if (!this.residentInfoId) {
showNotify({ type: 'warning', message: '未获取到患者信息' })
return
}
queryResidentInfo({ residentInfoId: this.residentInfoId }).then(res => {
this.residentInfo = res.data || {}
})
},
onAddChange(val, option) {
console.log(val, option)
if (this.deathStatus === 9) {
showToast('该患者已死亡')
return
}
this.addVisible = false
this.$router.push({
path: option.path,
query: { residentInfoId: this.residentInfoId }
})
},
toArchivesEdit() {
this.$router.push({
path: '/doctor/archives-form',
query: { residentInfoId: this.residentInfoId }
})
}
},
watch: {
residentInfoId(val) {
if (!val) return
this.residentInfo = {}
this.load()
}
}
}
</script>
<style lang="less" scoped>
.resident-info {
position: relative;
overflow: hidden;
border-radius: 0;
height: auto;
// transition: height .2s;
padding-bottom: 28px;
}
.resident-info-collapsed {
height: 100px;
}
.fold-btn {
color: #BFBFBF;
background: #fff;
position: absolute;
bottom: 0;
left: 16px;
right: 16px;
border-bottom: 1px solid #00000019;
.svg-icon {
transform: rotate(90deg);
}
}
.fold-btn-collapsed {
.svg-icon {
transform: rotate(-90deg);
}
}
:deep(.patient-detail-tabs) {
.van-tab {
color: #262626;
}
.van-tab--active {
color: var(--van-tab-active-text-color);
font-weight: 500;
}
.van-tabs__line {
width: 28px;
height: 2px;
bottom: 22px;
}
}
</style>
<template>
<div class="h-full overflow-y-auto general-list" ref='list'>
<van-pull-refresh v-model='loadingRefresh' @refresh='onRefresh'
:disabled='isRefreshDisable'>
<div class="flex flex-col">
<div v-for='item in list' :key="item.id"
class="flex flex-col gap-y-2.5 py-3 px-4 mb-3 doc-list-card">
<div>
<span class="label">创建时间</span>
<span>{{ item.addTime || '-' }}</span>
</div>
<div>
<span class="label">期望会诊日期</span>
<span>{{ item.booksDate || '-' }}</span>
</div>
<div>
<span class="label">会诊方式</span>
<span>{{ item.rcWayName || '-' }}</span>
</div>
<div class="text-ellipsis">
<span class="label">申请单位</span>
<span>{{ item.applyHosName || '-' }}</span>
</div>
<div>
<span class="label">申请医生</span>
<span>{{ item.applyDoctName || '-' }}</span>
</div>
<div>
<span class="label">来源</span>
<span>{{ item.systemName || '-' }}</span>
</div>
<div>
<span class="label">状态</span>
<span>{{ item.applyStatusName || '-' }}</span>
</div>
<div class="divider"></div>
<div class="bt-group">
<van-button round size="small" class="doc-btn-primary" @click="toDetail(item)">详情</van-button>
</div>
</div>
</div>
</van-pull-refresh>
<div class='text-center shrink-0 empty' v-if='!list.length'>
<img src='@/assets/image/doctor/empty.png' alt='' style='width: 1.2rem;'>
<p>暂无数据</p>
</div>
</div>
</template>
<script>
import { getConsultationList } from '@/api/doctor/resident.js'
export default {
inject: ['residentInfo'],
data() {
return {
list: [],
loadingRefresh: false,
isRefreshDisable: false
}
},
computed: {
idCard() {
return this.residentInfo().idCard
}
},
created() {
this.load()
},
mounted() {
const list = this.$refs.list
list.addEventListener('scroll', () => {
if (list.scrollTop > 0) {
this.isRefreshDisable = true
} else {
this.isRefreshDisable = false
}
})
},
methods: {
load(loading = true) {
const query = {
idCard: this.idCard
}
getConsultationList(query, loading).then(res => {
this.list = res.data || []
}).finally(() => {
this.loadingRefresh = false
})
},
onRefresh() {
this.load(false)
},
toDetail(record) {
if (!record) return
if (record.id == null) {
showToast('暂时无法查看 详情信息')
return
}
}
}
}
</script>
<style lang="less" scoped>
</style>
<template>
<div class="h-full flex flex-col disease-index">
<van-tabs shrink type="card" class="shrink-0 doc-tab-round"
v-model:active="activeTab">
<van-tab :title="`${diseaseName}信息`"></van-tab>
<van-tab :title="`${diseaseName}管理`"></van-tab>
</van-tabs>
<div class="pt-3"></div>
<div class="grow pb-3 overflow-y-auto">
<DiseaseList :diseaseType="diseaseType" v-if="activeTab == 0"/>
<DiseaseVisit :diseaseType="diseaseType" v-if="activeTab == 1"/>
</div>
</div>
</template>
<script>
import DiseaseList from './List.vue'
import DiseaseVisit from './Visit.vue'
export default {
components: {
DiseaseList,
DiseaseVisit
},
inject: ['residentInfo'],
props: {
diseaseName: String,
diseaseType: Number
},
data() {
return {
activeTab: 0
}
}
}
</script>
<style lang="less" scoped>
:deep(.card-back-1) {
border-radius: 12px;
background: linear-gradient(to bottom, #FFC9D3, #FFE9E9);
.title {
color: #8E2A4A;
}
}
:deep(.card-back-2) {
border-radius: 12px;
background: linear-gradient(to bottom, #FFD8BC, #FFF0E9);
.title {
color: #8E562A;
}
}
:deep(.card-back-3) {
border-radius: 12px;
background: linear-gradient(to bottom, #B3F5F7, #FFFFE9);
.title {
color: #2A8E75;
}
}
</style>
<template>
<div class="disease-list" ref="list">
<van-pull-refresh v-model='loadingRefresh' @refresh='onRefresh'
:disabled='isRefreshDisable'>
<div v-for="item in diagnoseRecord" :key="item.id"
class="card-back-1 mb-3">
<div class="title px-4 py-1">诊断列表</div>
<div class="flex flex-col py-3 px-4 doc-list-card" style="row-gap: .04rem;line-height: 1.5;">
<div class="flex">
<span class="label shrink-0">诊断名称</span>
<span class="grow text-wrap">{{ item.diseaseName }}({{item.icdCode}})</span>
</div>
<div class="flex">
<span class="label shrink-0">诊断评估</span>
<span class="grow" >{{ item.diagnoseResultValue || '-' }}</span>
</div>
<div>
<span class="label">诊断单位</span>
<span>{{ item.diseaseUnitName }}</span>
</div>
<div>
<span class="label">诊断科室</span>
<span>{{ item.diseaseOfficeName }}</span>
</div>
<div>
<span class="label">诊断医生</span>
<span>{{ item.diseaseDoctorName }}</span>
</div>
<div>
<span class="label">数据来源</span>
<span>{{ item.sourceName || '-' }}</span>
</div>
<div>
<span class="label">诊断日期</span>
<span>{{ item.diseaseDate }}</span>
</div>
<div>
<span class="label">纳入管理日期</span>
<span>{{ item.manageDate }}</span>
</div>
<!-- <div class="divider"></div>
<div class="bt-group">
<van-button round size="small" class="doc-btn-primary" @click="toDetail(item)">详情</van-button>
<van-button round size="small" class="doc-btn-primary" @click='editBtn(item)'
v-if="item.allowUpdate == 1">修改</van-button>
<van-button round size="small" class="doc-btn-red" @click="delBtn(item)"
v-if="item.allowDelete ==1">删除</van-button>
</div> -->
</div>
</div>
<div v-for="item in treatmentRecord" :key="item.id"
class="card-back-2 mb-3">
<div class="title px-4 py-1">治疗方案</div>
<div class="flex flex-col py-3 px-4 doc-list-card" style="row-gap: .04rem;line-height: 1.5;">
<div class="text-ellipsis">
<span class="label">慢病标签</span>
<span>{{ item.diseaseTypeName }}</span>
</div>
<div class="text-ellipsis">
<span class="label">治疗方式</span>
<span>{{ item.therapyMethodName || '-' }}</span>
</div>
<div>
<span class="label">创建单位</span>
<span>{{ item.createUnitName }}</span>
</div>
<div>
<span class="label">创建科室</span>
<span>{{ item.createOfficeName }}</span>
</div>
<div>
<span class="label">创建医生</span>
<span>{{ item.createDoctorName }}</span>
</div>
<!-- <div class="divider"></div>
<div class="bt-group">
<van-button round size="small" class="doc-btn-primary" @click="toDetail(item)">详情</van-button>
<van-button round size="small" class="doc-btn-primary" @click='editBtn(item)'
v-if="item.allowUpdate == 1">修改</van-button>
<van-button round size="small" class="doc-btn-red" @click="delBtn(item)"
v-if="item.allowDelete ==1">删除</van-button>
</div> -->
</div>
</div>
<div v-for="item in followUpRecord" :key="item.id"
class="card-back-3 mb-3">
<div class="title px-4 py-1">随访方案</div>
<div class="flex flex-col py-3 px-4 doc-list-card" style="row-gap: .04rem;line-height: 1.5;">
<div class="text-ellipsis">
<span class="label">随访方案</span>
<span>
<span v-if="item.visitScheme">{{item.visitSchemeOther}}</span>
<span>{{item.visitSchemeName}}</span>
</span>
</div>
<div class="text-ellipsis">
<span class="label">预计随访地点</span>
<span>{{ item.visitPlace || '-' }}</span>
</div>
<div>
<span class="label">创建单位</span>
<span>{{ item.createUnitName }}</span>
</div>
<div>
<span class="label">创建科室</span>
<span>{{ item.createOfficeName }}</span>
</div>
<div>
<span class="label">创建医生</span>
<span>{{ item.createDoctorName }}</span>
</div>
<div>
<span class="label">下次随访日期</span>
<span>{{ item.nextVisitDate || '-' }}</span>
</div>
<!-- <div class="divider"></div>
<div class="bt-group">
<van-button round size="small" class="doc-btn-primary" @click="toDetail(item)">详情</van-button>
<van-button round size="small" class="doc-btn-primary" @click='editBtn(item)'
v-if="item.allowUpdate == 1">修改</van-button>
<van-button round size="small" class="doc-btn-red" @click="delBtn(item)"
v-if="item.allowDelete ==1">删除</van-button>
</div> -->
</div>
</div>
</van-pull-refresh>
<div class='text-center shrink-0 empty'
v-if='!diagnoseRecord.length && !treatmentRecord.length && !followUpRecord.length'>
<img src='@/assets/image/doctor/empty.png' alt='' style='width: 1.2rem;'>
<p>暂无数据</p>
</div>
</div>
</template>
<script>
import { fetchDiseaseTypeList } from '@/api/doctor/disease.js'
import { useStore } from '@/doctor/store'
export default {
inject: ['residentInfo'],
props: {
diseaseType: Number
},
data() {
return {
store: useStore(),
loadingRefresh: false,
isRefreshDisable: false,
diagnoseRecord: [],
treatmentRecord: [],
followUpRecord: []
}
},
computed: {
residentInfoId() {
return this.residentInfo().residentInfoId
}
},
created() {
this.load()
},
mounted() {
const list = this.$refs.list
list.addEventListener('scroll', () => {
if (list.scrollTop > 0) {
this.isRefreshDisable = true
} else {
this.isRefreshDisable = false
}
})
},
methods: {
load(loading = true) {
const query = {
residentInfoId: this.residentInfoId,
diseaseType: this.diseaseType
}
fetchDiseaseTypeList(query, loading).then(res => {
const result = res.data || {}
this.diagnoseRecord = result.chronicDiagnoseList || []
this.treatmentRecord = result.chronicTreatmentRecordList || []
this.followUpRecord = result.chronicVisitSchemeRecordList || []
}).finally(() => {
this.loadingRefresh = false
})
},
onRefresh() {
this.load()
},
toDetail() {
},
editBtn() {
},
delBtn() {
}
},
watch: {
diseaseType() {
this.load()
},
'store.refreshMark'() {
this.onRefresh()
}
}
}
</script>
<style lang="less" scoped>
</style>
<template>
<div class="h-full disease-visit" ref="list">
<van-pull-refresh v-model='loadingRefresh' @refresh='onRefresh'
:disabled='isRefreshDisable' style="min-height: 100%">
<van-list
v-model:loading='loading'
:finished='finished'
:finished-text="list.length ? '没有更多了' : ''"
:immediate-check='false'
@load='onMore'
>
<div class="flex flex-col">
<div class="flex flex-col gap-y-2.5 py-3 px-4 mb-3 doc-list-card"
v-for='item in list' :key="item.id" @click="toDetail(item)">
<div>
<span class="label">服务类型</span>
<span>{{ item.serveTypeName || '-' }}</span>
</div>
<div>
<span class="label">随访日期</span>
<span>{{ item.serveDate }}</span>
</div>
<div>
<span class="label">随访分类</span>
<span>{{ item.visitTypeName || '-' }}</span>
</div>
<div v-if="item.patientNo">
<span class="label">就诊号</span>
<span>{{ item.patientNo || '-' }}</span>
</div>
<div class="text-ellipsis" v-if="item.diagnose">
<span class="label">诊断</span>
<span>{{ item.diagnose || '-' }}</span>
</div>
<div v-if="item.bloodPressure">
<span class="label">血压</span>
<span>{{ item.bloodPressure || '-' }}</span>
</div>
<div>
<span class="label">数据来源</span>
<span>{{ item.sourceName || '-' }}</span>
</div>
<div>
<span class="label">随访医生</span>
<span>{{ item.serveDoctorName || '-' }}</span>
</div>
<div class="text-ellipsis">
<span class="label">随访机构</span>
<span>{{ item.serveUnitName || '-' }}</span>
</div>
<div class="divider" v-if="item.serveType == 5"></div>
<div class="bt-group" v-if="item.serveType == 5">
<van-button round size="small" class="doc-btn-primary" @click="toDetail(item)">详情</van-button>
<!-- <van-button round size="small" class="doc-btn-primary" v-if="item.allowUpdate == 1">转诊</van-button>
<van-button round size="small" class="doc-btn-primary" @click='editBtn(item)'
v-if="!(item.allowUpdate !==1 || item.serveType == 5)">修改</van-button>
<van-button round size="small" class="doc-btn-red" @click="delBtn(item)"
v-if="!(item.allowUpdate !==1 || item.serveType == 5)">删除</van-button> -->
</div>
</div>
</div>
</van-list>
<div class='text-center shrink-0 empty' v-if='!list.length'>
<img src='@/assets/image/doctor/empty.png' alt='' style='width: 1.2rem;'>
<p>暂无数据</p>
</div>
</van-pull-refresh>
</div>
</template>
<script>
import { getVisitManageList } from '@/api/doctor/disease.js'
import { useStore } from '@/doctor/store'
export default {
inject: ['residentInfo'],
props: {
diseaseType: Number
},
data() {
return {
store: useStore(),
list: [],
pagination: {
total: 0,
pageIndex: 1,
pageSize: 8
},
loading: false,
finished: false,
loadingRefresh: false,
isRefreshDisable: false
}
},
computed: {
residentInfoId() {
return this.residentInfo().residentInfoId
}
},
created() {
this.load()
},
mounted() {
const list = this.$refs.list
list.addEventListener('scroll', () => {
if (list.scrollTop > 0) {
this.isRefreshDisable = true
} else {
this.isRefreshDisable = false
}
})
},
methods: {
load(loading = true) {
const query = {
pageIndex: this.pagination.pageIndex,
pageSize: this.pagination.pageSize,
residentInfoId: this.residentInfoId,
diseaseType: this.diseaseType,
}
getVisitManageList(query, loading).then(res => {
if (this.pagination.pageIndex === 1) {
this.list = []
}
this.list = this.list.concat(res.data.dataList || [])
this.pagination.total = res.data.total || 0
this.finished = this.list.length >= this.pagination.total
}).finally(() => {
this.loading = false
this.loadingRefresh = false
})
},
onMore() {
this.pagination.pageIndex++
this.load(false)
},
onRefresh() {
this.pagination.pageIndex = 1
this.load()
},
toDetail(record) {
if (!record) return
if (record.id == null) {
showToast('暂时无法查看 详情信息')
return
}
if (record.serveType === 5) {
// 通用随访
this.$router.push({
path: '/doctor/followUp/generalFU/detail',
query: {
relationId: record.id
}
})
}
},
editBtn() {
},
delBtn() {
}
},
watch: {
diseaseType() {
this.list = []
this.load()
},
'store.refreshMark'() {
this.onRefresh()
}
}
}
</script>
<style lang="less" scoped>
</style>
<template>
<div class="h-full overflow-y-auto general-list" ref='list'>
<van-pull-refresh v-model='loadingRefresh' @refresh='onRefresh'
:disabled='isRefreshDisable' style="min-height: 100%">
<van-list
v-model:loading='loading'
:finished='finished'
:finished-text="list.length ? '没有更多了' : ''"
:immediate-check='false'
@load='onMore'
>
<div class="flex flex-col">
<div v-for='item in list' :key="item.id" @click="toDetail(item)"
class="flex flex-col py-3 px-4 mb-3 doc-list-card" style="row-gap: .04rem;line-height: 1.5;">
<div>
<span class="label">随访日期</span>
<span>{{ item.visitDate }}</span>
</div>
<div class="flex">
<span class="label shrink-0">服务人群</span>
<span class="grow text-wrap">{{ item.groupsArraysName || '-' }}</span>
</div>
<div>
<span class="label">随访方式</span>
<span>{{ item.visitWayName || '-' }}</span>
</div>
<div>
<span class="label">随访类型</span>
<span>{{ item.visitWayRulesName || '-' }}</span>
</div>
<div>
<span class="label">随访医生</span>
<span>{{ item.visitDoctorName || '-' }}</span>
</div>
<div>
<span class="label">随访科室</span>
<span>{{ item.visitOfficeName || '-' }}</span>
</div>
<div class="text-ellipsis">
<span class="label">随访机构</span>
<span>{{ item.visitUnitName || '-' }}</span>
</div>
<div class="divider"></div>
<div class="bt-group">
<van-button round size="small" class="doc-btn-primary" @click="toDetail(item)">详情</van-button>
</div>
</div>
</div>
</van-list>
<div class='text-center shrink-0 empty' v-if='!list.length'>
<img src='@/assets/image/doctor/empty.png' alt='' style='width: 1.2rem;'>
<p>暂无数据</p>
</div>
</van-pull-refresh>
</div>
</template>
<script>
import { fetchCurrencyList, delCurrencyById } from '@/api/doctor/generalFU.js'
import { showToast } from 'vant'
import { useStore } from '@/doctor/store'
export default {
inject: ['residentInfo'],
data() {
return {
store: useStore(),
list: [],
pagination: {
total: 0,
pageIndex: 1,
pageSize: 8
},
loading: false,
finished: false,
loadingRefresh: false,
isRefreshDisable: false
}
},
computed: {
residentInfoId() {
return this.residentInfo().residentInfoId
}
},
created() {
this.load()
},
mounted() {
const list = this.$refs.list
list.addEventListener('scroll', () => {
if (list.scrollTop > 0) {
this.isRefreshDisable = true
} else {
this.isRefreshDisable = false
}
})
},
methods: {
load(loading = true) {
const query = {
pageIndex: this.pagination.pageIndex,
pageSize: this.pagination.pageSize,
residentInfoId: this.residentInfoId
}
fetchCurrencyList(query, loading).then(res => {
if (this.pagination.pageIndex === 1) {
this.list = []
}
this.list = this.list.concat(res.data.dataList || [])
this.pagination.total = res.data.total || 0
this.finished = this.list.length >= this.pagination.total
}).finally(() => {
this.loading = false
this.loadingRefresh = false
})
},
onMore() {
this.pagination.pageIndex++
this.load(false)
},
onRefresh() {
this.pagination.pageIndex = 1
this.load(false)
},
toDetail(record) {
if (!record) return
if (record.id == null) {
showToast('暂时无法查看 详情信息')
return
}
this.$router.push({
path: '/doctor/followUp/generalFU/detail',
query: {
relationId: record.id
}
})
},
editBtn() {
},
delBtn() {
}
},
watch: {
'store.refreshMark'() {
this.onRefresh()
}
}
}
</script>
<style lang="less" scoped>
</style>
<template>
<div class="h-full overflow-y-auto general-list" ref='list'>
<van-pull-refresh v-model='loadingRefresh' @refresh='onRefresh'
:disabled='isRefreshDisable'>
<div class="flex flex-col">
<div v-for='item in list' :key="item.id"
class="flex flex-col gap-y-2.5 py-3 px-4 mb-3 doc-list-card">
<div>
<span class="label">状态</span>
<span>{{ item.statusName }}</span>
</div>
<div class="text-ellipsis">
<span class="label">转出单位</span>
<span>{{ item.unitName || '-' }}</span>
</div>
<div>
<span class="label">转出医生</span>
<span>{{ item.doctorName || '-' }}</span>
</div>
<div>
<span class="label">转诊类型</span>
<span>{{ item.referralTypeDesc || '-' }}</span>
</div>
<div>
<span class="label">来源</span>
<span>{{ item.source || '-' }}</span>
</div>
<div class="text-ellipsis">
<span class="label">接诊单位</span>
<span>{{ item.transferUnitName || '-' }}</span>
</div>
<div>
<span class="label">接诊医生</span>
<span>{{ item.attendingDoctorName || '-' }}</span>
</div>
<div>
<span class="label">发起时间</span>
<span>{{ item.startDate || '-' }}</span>
</div>
<div class="divider"></div>
<div class="bt-group">
<van-button round size="small" class="doc-btn-primary" @click="toDetail(item)">详情</van-button>
</div>
</div>
</div>
</van-pull-refresh>
<div class='text-center shrink-0 empty' v-if='!list.length'>
<img src='@/assets/image/doctor/empty.png' alt='' style='width: 1.2rem;'>
<p>暂无数据</p>
</div>
</div>
</template>
<script>
import { getReferralList } from '@/api/doctor/resident.js'
export default {
inject: ['residentInfo'],
data() {
return {
list: [],
loadingRefresh: false,
isRefreshDisable: false
}
},
computed: {
residentInfoId() {
return this.residentInfo().residentInfoId
}
},
created() {
this.load()
},
mounted() {
const list = this.$refs.list
list.addEventListener('scroll', () => {
if (list.scrollTop > 0) {
this.isRefreshDisable = true
} else {
this.isRefreshDisable = false
}
})
},
methods: {
load(loading = true) {
const query = {
residentInfoId: this.residentInfoId
}
getReferralList(query, loading).then(res => {
this.list = res.data || []
}).finally(() => {
this.loadingRefresh = false
})
},
onRefresh() {
this.load(false)
},
toDetail(record) {
if (!record) return
if (record.id == null) {
showToast('暂时无法查看 详情信息')
return
}
}
}
}
</script>
<style lang="less" scoped>
</style>
<template>
<div class="h-full flex flex-col screening-index">
<van-tabs shrink type="card" class="shrink-0 doc-tab-round"
v-model:active="activeTab">
<van-tab title="筛查记录"></van-tab>
<van-tab title="随访记录"></van-tab>
</van-tabs>
<div class="pt-3"></div>
<div class="grow pb-3 overflow-y-auto">
<ScreenRecordList v-if="activeTab == 0"/>
<VisitList v-else-if="activeTab == 1"/>
</div>
</div>
</template>
<script>
import ScreenRecordList from './Record.vue'
import VisitList from './Visit.vue'
export default {
components: {
ScreenRecordList,
VisitList
},
data() {
return {
activeTab: 0
}
}
}
</script>
<style lang="less" scoped>
// 通用随访card
:deep(.general-card) {
border-radius: 12px;
background: linear-gradient(to bottom, #FFC9D3, #FFE9E9);
.title {
color: #8E2A4A;
}
}
// 初筛 主要慢病
:deep(.first-card) {
border-radius: 12px;
background: linear-gradient(to bottom, #FFD8BC, #FFF0E9);
.title {
color: #8E562A;
}
}
// 复筛 专病高危
:deep(.second-card) {
border-radius: 12px;
background: linear-gradient(to bottom, #B3F5F7, #FFFFE9);
.title {
color: #2A8E75;
}
}
</style>
<template>
<div class="record-list" ref="list">
<van-pull-refresh v-model='loadingRefresh' @refresh='onRefresh'
:disabled='isRefreshDisable'>
<div v-for="item in firstScreenList" :key="item.id"
class="first-card mb-3">
<div class="title px-4 py-1">主要慢病筛查记录</div>
<div class="py-3 px-4 doc-list-card">
<div class="flex flex-col" style="row-gap: .04rem;line-height: 1.5;">
<div class="flex">
<span class="label shrink-0">高危评估</span>
<span class="grow">{{ item.screenResultName }}</span>
</div>
<div>
<span class="label">筛查日期</span>
<span>{{ item.screenDate }}</span>
</div>
<div class="text-ellipsis">
<span class="label">筛查单位</span>
<span>{{ item.screenUnitName }}</span>
</div>
<div class="text-ellipsis">
<span class="label">筛查科室</span>
<span>{{ item.screenOfficeName }}</span>
</div>
<div>
<span class="label">筛查医生</span>
<span>{{ item.screenDoctorName }}</span>
</div>
<div>
<span class="label">数据来源</span>
<span>{{ item.sourceName }}</span>
</div>
<div>
<span class="label">创建时间</span>
<span>{{ item.created }}</span>
</div>
</div>
<!-- <div class="divider"></div>
<div class="bt-group">
<van-button round size="small" class="doc-btn-primary" @click="toFirstDetail(item)">详情</van-button>
<van-button round size="small" class="doc-btn-primary" @click='editBtn(item)'
v-if="item.allowUpdate == 1">修改</van-button>
<van-button round size="small" class="doc-btn-red" @click="delBtn(item)"
v-if="item.allowDelete ==1">删除</van-button>
</div> -->
</div>
</div>
<div v-for="item in secondScreenList" :key="item.id"
class="second-card mb-3">
<div class="title px-4 py-1">专病筛查记录</div>
<div class=" py-3 px-4 doc-list-card">
<div class="flex flex-col" style="row-gap: .04rem;line-height: 1.5;">
<div class="flex">
<span class="label shrink-0">高危评估</span>
<span class="grow" >{{ item.specialScreenResultName }}</span>
</div>
<div>
<span class="label">筛查日期</span>
<span>{{ item.screenDate }}</span>
</div>
<div>
<span class="label">筛查单位</span>
<span>{{ item.screenUnitName }}</span>
</div>
<div>
<span class="label">筛查科室</span>
<span>{{ item.screenOfficeName }}</span>
</div>
<div>
<span class="label">筛查医生</span>
<span>{{ item.screenDoctorName }}</span>
</div>
<div>
<span class="label">数据来源</span>
<span>{{ item.sourceName }}</span>
</div>
<div>
<span class="label">创建时间</span>
<span>{{ item.created }}</span>
</div>
</div>
<!-- <div class="divider"></div>
<div class="bt-group">
<van-button round size="small" class="doc-btn-primary" @click="toSecondDetail(item)">详情</van-button>
<van-button round size="small" class="doc-btn-primary" @click='editBtn(item)'
v-if="item.allowUpdate == 1">修改</van-button>
<van-button round size="small" class="doc-btn-red" @click="delBtn(item)"
v-if="item.allowUpdate == 1">删除</van-button>
</div> -->
</div>
</div>
</van-pull-refresh>
<div class='text-center shrink-0 empty' v-if='!firstScreenList.length && !secondScreenList.length'>
<img src='@/assets/image/doctor/empty.png' alt='' style='width: 1.2rem;'>
<p>暂无数据</p>
</div>
</div>
</template>
<script>
import { useStore } from '@/doctor/store'
import { getScreenAllList } from '@/api/doctor/screening.js'
import { showToast } from 'vant'
export default {
inject: ['residentInfo'],
data() {
return {
store: useStore(),
loadingRefresh: false,
isRefreshDisable: false,
firstScreenList: [],
secondScreenList: []
}
},
computed: {
residentInfoId() {
return this.residentInfo().residentInfoId
}
},
created() {
this.load()
},
mounted() {
const list = this.$refs.list
list.addEventListener('scroll', () => {
if (list.scrollTop > 0) {
this.isRefreshDisable = true
} else {
this.isRefreshDisable = false
}
})
},
methods: {
load(loading = true) {
getScreenAllList(this.residentInfoId, loading).then(res => {
const result = res.data || {}
this.firstScreenList = result.firstScreenList || []
this.secondScreenList = result.secondScreenList || []
}).finally(() => {
this.loadingRefresh = false
})
},
onRefresh() {
this.load(false)
},
//主要慢病筛查
toFirstDetail(record) {
if (!record) return
if (record.id == null) {
showToast('暂时无法查看 详情信息')
return
}
this.$router.push({
path: '/doctor/screening/FirstDetail',
query: {
id: record.id
}
})
},
//专病筛查
toSecondDetail(record) {
if (!record) return
if (record.id == null) {
showToast('暂时无法查看 详情信息')
return
}
this.$router.push({
path: '/doctor/screening/secondDetail',
query: {
id: record.id
}
})
},
editBtn() {
},
delBtn() {
}
},
watch: {
'store.refreshMark'() {
this.onRefresh()
}
}
}
</script>
<style lang="less" scoped>
</style>
<template>
<div class="h-full visit-list" ref='list'>
<van-pull-refresh v-model='loadingRefresh' @refresh='onRefresh'
:disabled='isRefreshDisable' style="min-height: 100%">
<van-list
v-model:loading='loading'
:finished='finished'
:finished-text="list.length ? '没有更多了' : ''"
:immediate-check='false'
@load='onMore'
>
<div class="flex flex-col">
<div v-for='item in list' :key="item.id"
:class="['mb-3', {'first-card': item.serveType == 1},
{'second-card': item.serveType == 2},
{'general-card': item.serveType == 3}]">
<div class="title px-4 py-1">{{item.serveTypeName}}</div>
<div class="flex flex-col gap-y-2.5 py-3 px-4 doc-list-card" @click="toDetail(item)">
<div>
<span class="label">随访日期</span>
<span>{{ item.visitDate }}</span>
</div>
<div>
<span class="label">随访类型</span>
<span>{{ item.visitTypeName || '-' }}</span>
</div>
<div>
<span class="label">随访方式</span>
<span>{{ item.visitWayName || '-' }}</span>
</div>
<div class="text-ellipsis">
<span class="label">随访医生</span>
<span>{{ item.visitDoctorName || '-' }}</span>
</div>
<div class="text-ellipsis">
<span class="label">随访机构</span>
<span>{{ item.visitUnitName || '-' }}</span>
</div>
<div class="divider" v-if="item.serveType == 3"></div>
<div class="bt-group" v-if="item.serveType == 3">
<van-button round size="small" class="doc-btn-primary" @click="toDetail(item)">详情</van-button>
<!-- <van-button round size="small" class="doc-btn-primary" @click='editBtn(item)'
v-if="!(item.allowUpdate !==1 || item.serveType == 3)">修改</van-button>
<van-button round size="small" class="doc-btn-red" @click="delBtn(item)"
v-if="!(item.allowUpdate !==1 || item.serveType == 3)">删除</van-button> -->
</div>
</div>
</div>
</div>
</van-list>
<div class='text-center shrink-0 empty' v-if='!list.length'>
<img src='@/assets/image/doctor/empty.png' alt='' style='width: 1.2rem;'>
<p>暂无数据</p>
</div>
</van-pull-refresh>
</div>
</template>
<script>
import { getHighVisitList } from '@/api/doctor/visit.js'
import { useStore } from '@/doctor/store'
export default {
inject: ['residentInfo'],
data() {
return {
store: useStore(),
list: [],
pagination: {
total: 0,
pageIndex: 1,
pageSize: 8
},
loading: false,
finished: false,
loadingRefresh: false,
isRefreshDisable: false
}
},
computed: {
residentInfoId() {
return this.residentInfo().residentInfoId
}
},
created() {
this.load()
},
mounted() {
const list = this.$refs.list
list.addEventListener('scroll', () => {
if (list.scrollTop > 0) {
this.isRefreshDisable = true
} else {
this.isRefreshDisable = false
}
})
},
methods: {
load(loading = true) {
const query = {
pageIndex: this.pagination.pageIndex,
pageSize: this.pagination.pageSize,
residentInfoId: this.residentInfoId
}
getHighVisitList(query, loading).then(res => {
if (this.pagination.pageIndex === 1) {
this.list = []
}
this.list = this.list.concat(res.data.dataList || [])
this.pagination.total = res.data.total || 0
this.finished = this.list.length >= this.pagination.total
}).finally(() => {
this.loading = false
this.loadingRefresh = false
})
},
onMore() {
this.pagination.pageIndex++
this.load(false)
},
onRefresh() {
this.pagination.pageIndex = 1
this.load(false)
},
toDetail(record) {
if (!record) return
if (record.id == null) {
showToast('暂时无法查看 详情信息')
return
}
if (record.serveType == 3) {
this.$router.push({
path: '/doctor/followUp/generalFU/detail',
query: {
relationId: record.relationId
}
})
}
// this.$router.push({
// path: '/doctor/patient-detail',
// query: {
// residentInfoId: record.residentInfoId
// }
// })
},
editBtn() {
},
delBtn() {
}
},
watch: {
'store.refreshMark'() {
this.onRefresh()
}
}
}
</script>
<style lang="less" scoped>
</style>
<template>
<div class="h-full base">
<div class='mt-3 p-4 card' v-if="info.id">
<div class='flex items-center'>
<div class='text-16 font-semibold base-title'>{{ info.residentName }}</div>
<div class='second-title px-2'>{{ info.currentAge }}</div>
<div class='second-title px-2'>{{ info.genderName }}</div>
<div class="second-title px-2" v-if="info.chronicStatus === 9" >死亡</div>
</div>
<div class='mt-3 flex items-center'>
<div class='detail-left'>
身份证号
</div>
<div class='detail-right'>
{{ $idCardHide(info.idCard) }}
</div>
</div>
<div class='mt-3 flex items-center'>
<div class='detail-left'>
建档状态
</div>
<div class='detail-right'>
<span v-if="!!info.residentsBaseDTO">已建档</span>
<span v-else>未建档</span>
</div>
</div>
<div class='mt-3 flex items-center'>
<div class='detail-left'>
签约状态
</div>
<div class='detail-right'>
<span v-if="!!info.signedInfoDTO">已签约</span>
<span v-else>未签约</span>
</div>
</div>
<div class='mt-3 flex items-center'>
<div class='detail-left'>
高危评估
</div>
<div class='detail-right'>
<span>{{ info.firstScreenResultName || '-' }}</span>
</div>
</div>
<div class='mt-3 flex items-center'>
<div class='detail-left'>
专病高危评估
</div>
<div class='detail-right'>
<span>{{ info.highTagsArrayName || '-' }}</span>
</div>
</div>
<div class='flex mt-3'>
<div class='detail-left'>
慢病标签
</div>
<div class='detail-right' style='flex: 1'>
<ChronicTag :list="info.chronicTagsArray"/>
</div>
</div>
<div class="text-center mt-5">
<van-button round type="primary" class="detail-bt" @click="toEdit">修改基本信息</van-button>
</div>
</div>
<div class="text-center empty" v-else>
<img src="@/assets/image/doctor/empty.png" alt="" style="width: 1.2rem;">
<p>暂无数据</p>
</div>
</div>
</template>
<script>
import ChronicTag from '@/doctor/components/chronicTag/ChronicTag.vue'
export default {
components: {
ChronicTag
},
inject: ['getBaseInfo'],
data() {
return {}
},
computed: {
info() {
return this.getBaseInfo() || {}
}
},
methods: {
toEdit() {
let par = {
residentInfoId: this.info.residentInfoId
}
this.$router.push({path: `/doctor/resident/base/update`, query: par})
}
}
}
</script>
<style lang="less" scoped>
.card {
background-color: #fff;
.second-title {
background: #F0F3FF;
line-height: 24px;
margin-left: 10px;
}
.detail-left {
width: 8em;
color: #8C8C8C;
flex-shrink: 0;
}
.detail-bt {
color: #607FF0;
background-color: #F0F3FF;
border: 0;
width: 80%;
height: 40px;
}
}
</style>
<template>
<div class="h-full flex flex-col">
<van-nav-bar title='居民详情' left-text='' left-arrow class="shrink-0"
@click-left="toBack"></van-nav-bar>
<div class="flex shrink-0 justify-center pb-1">
<van-tabs v-model:active='activeTab' class="w-1/2 top-tabs"
@change="tabChange">
<van-tab v-for='item in tabList' :key="item.name"
:title='item.title' :name='item.name'></van-tab>
</van-tabs>
</div>
<div class="grow" style="background-color: #f5f5f5;min-height: 0;">
<router-view v-slot='{ Component }'>
<Transition name='route' mode='out-in'>
<component :is='Component' />
</Transition>
</router-view>
</div>
</div>
</template>
<script>
import { showNotify } from 'vant'
import { queryResidentInfo } from '@/api/doctor/resident'
export default {
data() {
return {
tabList: [
{ title: '基本信息', name: 'base', path: '/doctor/resident/base' },
{ title: '随访记录', name: 'visit', path: '/doctor/resident/visit' }
],
activeTab: 'base',
residentId: null,
// 基础信息
baseInfo: null
}
},
computed: {
routeQuery() {
return this.$route.query
}
},
provide() {
return {
getBaseInfo: () => this.baseInfo
}
},
created() {
this.residentId = this.routeQuery.residentId
this.init()
if (!this.residentId) {
showNotify({ type: 'warning', message: '未获取到医生信息', duration: 0 })
return
}
this.load()
},
methods: {
init() {
if (this.$route.name === 'doctor-resident-visit') {
this.activeTab = 'visit'
} else if (this.$route.name === 'doctor-resident-base') {
this.activeTab = 'base'
}
},
tabChange() {
console.log(this.activeTab)
const item = this.tabList.find(e => e.name === this.activeTab)
if (!item) return
this.$router.replace({
path: item.path,
query: { residentId: this.residentId }
})
},
load() {
const query = {
residentInfoId: this.residentId
}
queryResidentInfo(query).then(res => {
this.baseInfo = res.data || {}
})
},
toBack() {
this.$router.go(-1)
}
}
}
</script>
<style lang="less" scoped>
.top-tabs {
:deep(.van-tab) {
color: #262626;
}
:deep(.van-tab--active) {
color: var(--van-tab-active-text-color);
}
:deep(.van-tabs__line) {
height: 2px;
width: 28px;
bottom: 20px;
}
}
</style>
<template>
<div class='h-full flex flex-col visit'>
<van-tabs v-model:active='activeTab' class='shrink-0' v-if='tabList.length'
@change='tabChange'
shrink>
<van-tab v-for='item in tabList' :key='item.name'
:title='item.title' :name='item.name'></van-tab>
</van-tabs>
<div class='grow overflow-y-auto card-list' ref='list'>
<van-pull-refresh v-model='loadingRefresh' @refresh='onRefresh'
:disabled='isRefreshDisable'>
<van-list
v-model:loading='loading'
:finished='finished'
:finished-text="list.length ? '没有更多了' : ''"
:immediate-check='false'
@load='onMore'
>
<div v-for='item in list' :key='item.id' class='p-4 mt-3 card' @click.stop='toDetail(item)'>
<div class='flex items-center'>
<div class='detail-left'>
随访情况
</div>
<div class='detail-right'>
{{ item.visitSituationName }}
</div>
</div>
<div class='mt-3 flex items-center'>
<div class='detail-left'>
随访日期
</div>
<div class='detail-right'>
{{ item.serveDate }}
</div>
</div>
<div class='mt-3 flex items-center'>
<div class='detail-left'>
随访医生
</div>
<div class='detail-right'>
{{ item.serveDoctorName }}
</div>
</div>
<div class='mt-3 flex items-center'>
<div class='detail-left'>
服务类型
</div>
<div class='detail-right'>
{{ item.serveTypeName }}
</div>
</div>
<div class='mt-3 flex items-center'>
<div class='detail-left'>
随访机构
</div>
<div class='detail-right'>
{{ item.serveUnitName }}
</div>
</div>
<div class='mt-3 flex items-center'>
<div class='detail-left'>
下次随访日期
</div>
<div class='detail-right'>
{{ item.nextVisitDate || '-' }}
</div>
</div>
<div class='mt-3 flex items-center'>
<div class='detail-left'>
数据来源
</div>
<div class='detail-right'>
{{ item.sourceName || '-' }}
</div>
</div>
<van-divider class='mt-3' />
<div class='flex justify-end'>
<van-button round type='primary' class='card-bt' style='margin-right: .12rem'
@click.stop='editBtn(item)' v-show='item.allowUpdate ==1'>修改
</van-button>
<van-button round type='primary' class='card-bt' @click.stop='delBtn(item)'
v-show='item.allowUpdate ==1'>删除
</van-button>
</div>
<span class='px-3 float-bt'>
通用随访
</span>
</div>
</van-list>
<div class='text-center shrink-0 empty' v-if='!list.length'>
<img src='@/assets/image/doctor/empty.png' alt='' style='width: 1.2rem;'>
<p>暂无数据</p>
</div>
</van-pull-refresh>
</div>
<div class='p-3 floor' v-if='activeTab'>
<van-button round block type='primary' class='card-bt' @click='addBtn'>新增通用随访</van-button>
</div>
</div>
</template>
<script>
import { queryVisitByPage, deleteVisit } from '@/api/doctor/generalFU.js'
import { showConfirmDialog, showToast } from 'vant'
export default {
data() {
return {
activeTab: undefined,
list: [],
pagination: {
total: 0,
pageIndex: 1,
pageSize: 4
},
loading: false,
finished: false,
loadingRefresh: false,
isRefreshDisable: false
}
},
inject: ['getBaseInfo'],
computed: {
baseInfo() {
return this.getBaseInfo() || {}
},
chronicTagsArray() {
let chronicTagsArray = this.baseInfo.chronicTagsArray || ''
return chronicTagsArray.split(',')
},
tabList() {
const list = [
{ title: '高血压', name: 1, code: '1' },
{ title: '糖尿病', name: 2, code: '2' },
{ title: '冠心病', name: 3, code: '4' },
{ title: '脑卒中', name: 4, code: '8' },
{ title: '慢性阻塞性疾病', name: 5, code: '16' },
{ title: '慢性肾病', name: 6, code: '32' },
{ title: '血脂异常', name: 7, code: '64' }
]
return list.filter(e => this.chronicTagsArray.includes(e.code))
}
},
mounted() {
const list = this.$refs.list
list.addEventListener('scroll', () => {
if (list.scrollTop > 0) {
this.isRefreshDisable = true
} else {
this.isRefreshDisable = false
}
})
},
methods: {
load(loading = true) {
const query = {
residentInfoId: this.baseInfo.residentInfoId,
serveTypeList: [5, 6, 7, 8, 9, 10, 11, 12, 14],
diseaseType: this.activeTab,
pageIndex: this.pagination.pageIndex,
pageSize: this.pagination.pageSize
}
queryVisitByPage(query, loading).then(res => {
this.list = this.list.concat(res.data.dataList || [])
this.pagination.total = res.data.total || 0
this.finished = this.list.length >= this.pagination.total
}).finally(() => {
this.loading = false
this.loadingRefresh = false
})
},
onMore() {
this.pagination.pageIndex++
this.load()
},
init() {
if (this.chronicTagsArray.length) {
const item = this.tabList.find(e => e.code === this.chronicTagsArray[0]) || {}
this.activeTab = item.name
}
},
tabChange() {
this.list = []
this.pagination.pageIndex = 1
this.load()
},
onRefresh() {
this.list = []
this.pagination.pageIndex = 1
this.load(false)
},
addBtn() {
if (this.baseInfo.chronicStatus === 9) {
showToast('该居民已标记为死亡,无法新增随访')
return
}
let par = {
residentInfoId: this.baseInfo.residentInfoId,
diseaseType: this.activeTab
}
this.$router.push({
path: `/doctor/followUp/generalFU/add`,
query: par
})
},
toDetail(item) {
let par = {
relationId: item.relationId
}
this.$router.push({
path: `/doctor/followUp/generalFU/detail`,
query: par
})
},
editBtn(item) {
let par = {
id: item.relationId,
residentInfoId: this.baseInfo.residentInfoId
}
this.$router.push({
path: `/doctor/followUp/generalFU/add`,
query: par
})
},
delBtn(item) {
showConfirmDialog({
title: '提示',
message: '确认删除该随访记录吗?\n确认后将无法查看该随访信息'
}).then(() => {
// on confirm
// console.log(item.id)
deleteVisit({ id: item.id }).then(res => {
this.load()
})
})
.catch(() => {
// on cancel
})
}
}
}
</script>
<style lang='less' scoped>
.card-list {
padding-bottom: 76px;
}
.card {
position: relative;
background-color: #fff;
.detail-left {
width: 8em;
color: #8C8C8C;
flex-shrink: 0;
}
.card-bt {
font-size: 14px;
color: #607FF0;
background-color: #F0F3FF;
border: 0;
height: 26px;
}
.float-bt {
position: absolute;
top: 10px;
right: 0;
background-color: var(--van-primary-color);
color: #fff;
border-top-left-radius: 40px;
border-bottom-left-radius: 40px;
height: 26px;
line-height: 26px;
}
}
.floor {
position: fixed;
bottom: 0;
left: 0;
right: 0;
}
</style>
<template>
<div class="flex flex-col" style="height: 100vh">
<div class="p-3 text-black text-center shrink-0 doc-nav-bar" >
<span @click="onBack" class="text-12 back-bt">
<doc-icon type="doc-left2" />
</span>
<span>高危筛查详情</span>
</div>
<div class="px-4 py-3 flex shrink-0 base-info">
<div class="flex w-full">
<div class="grow flex flex-col justify-between">
<div class="flex justify-between">
<span class="name">{{ collapseList[0].info.residentName }}</span>
</div>
<div class='lh-22'>
<div class='mt-3'>筛查日期:<span class='color-26'>{{ info.screenDate || '-' }}</span></div>
<span>慢病高危评估结果:</span>
<span :class="{'text-red': info.screenResult !== 1, 'color-26': info.screenResult === 1 }">{{ info.screenResultName }}</span>
</div>
</div>
</div>
</div>
<div class="p-3 grow cont-box">
<div class="p-3 h-full cont-inner">
<div class="flex justify-between collapse-head mt-2">
<span class="text-16 font-semibold">全部内容</span>
<span @click="toggleAll">
<span v-if="!collapseAll">展开全部</span>
<span v-else>展开收起</span>
<span :class="['ml-2 icon-down', { 'icon-down-expanded': collapseAll }]">
<doc-icon type="doc-down" />
</span>
</span>
</div>
<van-collapse :model-value="activeCollapse" ref="collapse" class="doc-collapse"
@change="collapseChange">
<van-collapse-item v-for="collapse in collapseList" :key="collapse.name"
:title="collapse.title" :name="collapse.name">
<template #right-icon>
<doc-icon type="doc-down" />
</template>
<div class="list">
<div v-for="item in collapse.columns" :key="item.key" >
<div v-if="item.key == 'pressure'" class="pt-3">
<table class="w-full">
<tr>
<td style="width: 7.1em">血压值(mmHg)</td>
<td>收缩压(高压)</td>
<td></td>
<td>舒张压(低压)</td>
</tr>
<tr>
<td>
第1次测量
</td>
<td>
{{ info.pressureOneSbp || '-' }}
</td>
<td>/</td>
<td>
{{ info.pressureOneDbp || '-' }}
</td>
</tr>
<tr>
<td>
第2次测量
</td>
<td class="flex">
{{ info.pressureTwoSbp || '-' }}
</td>
<td>/</td>
<td>
{{ info.pressureTwoDbp || '-' }}
</td>
</tr>
</table>
</div>
<div v-else class="flex justify-between py-1 border-bottom item">
<span class="shrink-0 mr-2 label">{{ item.title }}</span>
<span v-if="item.key === 'idCard'">{{ $idCardHide(collapse.info.idCard) || '-' }}</span>
<span class="text-end" v-else>
<span>{{ collapse.info[item.key] || '-' }}</span>
<span v-if="item.unit" class="ml-1">{{ item.unit }}</span>
</span>
</div>
</div>
</div>
</van-collapse-item>
</van-collapse>
</div>
</div>
</div>
</template>
<script>
import { showNotify } from 'vant'
import { firstScreenDetail } from '@/api/doctor/screening.js'
import { useStore } from '@/doctor/store'
export default {
data() {
return {
store: useStore(),
activeCollapse: [],
collapseList: [
{ title: '居民信息', name: '1', columns: [
{ title: '姓名', key: 'residentName' },
{ title: '证件号码', key: 'idCard'},
{ title: '性别', key: 'genderName' },
{ title: '出生日期', key: 'dataBirth' },
{ title: '年龄', key: 'currentAge' },
{ title: '民族', key: 'nationalName' },
{ title: '本人电话', key: 'telephone' },
{ title: '现住址', key: 'presentCodeName' },
{ title: '详细地址', key: 'nowAddress' },
{ title: '户籍地址', key: 'registeredCodeName' },
{ title: '详细地址', key: 'permanentAddress' }
], info: {} },
{ title: '筛查信息', name: '2', columns: [
{ title: '年龄', key: 'currentAge', unit: '岁' },
{ title: '既往史', key: 'medicalHistoryName' },
{ title: '身高', key: 'height', unit: 'cm' },
{ title: '体重', key: 'weight', unit: 'kg' },
{ title: 'BMI', key: 'bmi', unit: 'kg/m²' },
{ title: '腰围', key: 'waistline', unit: 'cm' },
{ title: '是否吸烟', key: 'isSmokingName' },
{ title: '家族史', key: 'familyHistoryName' },
{ title: '血压值', key: 'pressure' },
{ title: '空腹血糖', key: 'fastingGlucose', unit: 'mmol/L' },
{ title: '低密度脂蛋白胆固醇', key: 'ldlCholesterin', unit: 'mmol/L' },
{ title: '血清总胆固醇', key: 'serumCholesterin', unit: 'mmol/L' },
{ title: '高密度脂蛋白胆固醇', key: 'hdlCholesterin', unit: 'mmol/L' },
{ title: '运动', key: 'exerciseIntensityName' },
{ title: '慢病高危评估结果', key: 'screenResultName' }
], info: {} },
{ title: '筛查机构', name: '3', columns: [
{ title: '筛查机构', key: 'screenUnitName' },
{ title: '筛查科室', key: 'screenOfficeName' },
{ title: '筛查医生', key: 'screenDoctorName' },
{ title: '筛查日期', key: 'screenDate' }
], info: {} }
],
// 全部展开、收起
collapseAll: false,
info: {}
}
},
computed: {
id() {
return this.$route.query.id
}
},
created() {
document.title = '筛查详情'
if (!this.id) {
showNotify({ type: 'warning', message: '未获取到查询信息'})
return
}
this.init()
},
methods: {
init() {
firstScreenDetail({ id: this.id }).then(res => {
this.info = res.data || {}
this.collapseList[0].info = this.info?.residentsRecord
this.collapseList[1].info = this.info
this.collapseList[2].info = this.info
})
},
onBack() {
this.$router.back()
},
// 折叠面板切换
collapseChange(val) {
// console.log(val, this.activeCollapse)
if (val && val.length <= 2) {
this.activeCollapse = val.slice(val.length - 1)
} else {
if (this.activeCollapse.length > val.length) {
this.activeCollapse = val
}
if (this.activeCollapse.length < val.length) {
this.activeCollapse = val.slice(val.length - 1)
}
}
if (val && val.length === this.collapseList.length) {
this.collapseAll = true
} else {
this.collapseAll = false
}
},
// 全部展开、收起
toggleAll() {
if (this.collapseAll) {
this.activeCollapse = []
} else {
this.activeCollapse = this.collapseList.map(e => e.name)
}
this.collapseAll = !this.collapseAll
}
}
}
</script>
<style lang="less" scoped>
@import url('../../utils/common.less');
.base-info {
background: linear-gradient(to bottom, #F0F6FF , #fff 50%);
color: #8c8c8c;
.name {
font-weight: 600;
color: #000;
font-size: 18px;
}
}
.cont-box {
background-color: #f9f9f9;
.cont-inner {
background: linear-gradient(to bottom, #F0F6FF , #fff .6rem);
border-top-left-radius: .08rem;
border-top-right-radius: .08rem;
}
}
.collapse-head {
.icon-down {
vertical-align: middle;
font-size: .12rem;
.svg-icon {
transition: all .2s;
}
}
.icon-down-expanded {
.svg-icon {
transform: rotate(-180deg);
}
}
}
table {
text-align: left;
// border-bottom: 1px solid var(--van-cell-border-color);
>tr {
>td {
padding-left: 14px;
padding-bottom: 12px;
&:first-child {
text-align: right;
padding-left: 0;
}
}
}
}
.list {
color: #262626;
.label {
min-width: 5em;
}
}
.lh-22 {
line-height: 22px;
}
.color-26 {
color: #262626;
}
</style>
<template>
<div class='flex flex-col' style='height: 100vh'>
<div class='p-3 text-black text-center shrink-0 doc-nav-bar'>
<span @click='onBack' class='text-12 back-bt'>
<doc-icon type='doc-left2' />
</span>
<span>专病筛查详情</span>
</div>
<div class='px-4 py-3 flex shrink-0 base-info'>
<div class='flex w-full'>
<div class='grow flex flex-col justify-between'>
<div class='flex justify-between'>
<span class='name'>{{ residentInfo.residentName }}</span>
</div>
<div class='top-label mt-3'>
<span >报告日期:<span class='color-b'>{{ info.screenDate || '-' }}</span></span>
</div>
<div class='top-label'>
<span>慢病高危评估结果:</span>
</div>
<div class='top-label color-b'>
<span v-if='info.specialScreenResult && info.specialScreenResult !=9'>您存在<span
class='color-red'>{{ info.specialScreenResultName }}</span>风险,请及时前往医院诊断确认。</span>
<span v-if='info.specialScreenResult ==9'>您并未存在高危风险。</span>
</div>
<div v-if='info.specialScreenResult && info.specialScreenResult !=9'
class='flex items-center flex-wrap gap-x-2.5 gap-y-1 mt-2'>
<div v-for='(item, index) in highRiskList' :key='index' class='tag tag-red'>
<span>{{ item.name }}</span><span class='color-red'>{{ item.num || 0 }}</span>
</div>
</div>
</div>
</div>
</div>
<div class='p-3 grow cont-box'>
<div class='p-3 h-full cont-inner'>
<div class='flex justify-between collapse-head mt-2'>
<span class='text-16 font-semibold'>全部内容</span>
<span @click='toggleAll'>
<span v-if='!collapseAll'>展开全部</span>
<span v-else>展开收起</span>
<span :class="['ml-2 icon-down', { 'icon-down-expanded': collapseAll }]">
<doc-icon type='doc-down' />
</span>
</span>
</div>
<van-collapse :model-value='activeCollapse' ref='collapse' class='doc-collapse'
@change='collapseChange'>
<van-collapse-item key='1' title='居民信息' name='1'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div v-for='item in columnsBase' :key='item.key'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>{{ item.title }}</span>
<span
v-if="item.key === 'idCard'">{{ $idCardHide(residentInfo.idCard) || '-'
}}</span>
<span class='text-end' v-else>
<span>{{ residentInfo[item.key] || '-' }}</span>
<span v-if='item.unit' class='ml-1'>{{ item.unit }}</span>
</span>
</div>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='2' title='筛查病种' name='2'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>筛查病种</span>
<span class='text-end'>
<span>{{ info.diseaseArraysName || '-' }}</span>
</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='3' title='病史' name='3' v-if='medicalHistoryShow'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>病史</span>
<span class='text-end'>
<span>{{ info.medicalHistoryName || '-' }}</span>
</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='4' title='家族史' name='4' v-if='familyHistoryShow'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>家族史</span>
<span class='text-end'>
<span>{{ info.familyHistoryName || '-' }}</span>
</span>
</div>
<div>
<div class='flex items-center' v-for='item in info.diseaseRelativeList'>
<template v-if='item.relativeAgeList.filter(e => e.age).length'>
<div class='mt-2'>{{ item.diseaseTypeName }}</div>
<div class='mt-2'>
<span v-for='item1 in item.relativeAgeList'>
<span v-if='item1.age'>{{ item1.relativeTypeName }}</span>
<span v-if='item1.age'>{{ item1.age || '-' }} 岁;</span>
</span>
</div>
</template>
</div>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='5' title='身高' name='5' v-if='highShow'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>身高</span>
<span class='text-end'>
<span>{{ info.height || '-' }} cm</span>
</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='6' title='体重' name='6' v-if='highShow'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>体重</span>
<span class='text-end'>
<span>{{ info.weight || '-' }} kg</span>
</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='7' title='BMI(体质指数)' name='7' v-if='highShow'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>BMI(体质指数)</span>
<span class='text-end'>
<span>{{ info.bmi || '-'}} kg/m²</span>
</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='8' title='腰围' name='8' v-if='waistShow'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>腰围</span>
<span class='text-end'>
<span>{{ info.waistline || '-'}} cm</span>
</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='9' title='锻炼频率' name='9' v-if='exerciseShow'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>锻炼频率</span>
<span class='text-end'>
<span>{{info.exerciseFrequencyName || '-'}}</span>
<span v-if="info.exerciseFrequency == 2 && info.isExerciseFiveName">({{info.isExerciseFiveName}})</span>
</span>
</div>
<div class='flex justify-between py-1 border-bottom item' v-if="[1,2,3].includes(info.exerciseFrequency) && exerciseShow">
<span class='shrink-0 mr-2 label'>每次锻炼时间</span>
<span class='text-end'>
<span>{{info.everyExercise || '-'}} 分钟</span>
</span>
</div>
<div class='flex justify-between py-1 border-bottom item' v-if="[1,2,3].includes(info.exerciseFrequency) && exerciseShow">
<span class='shrink-0 mr-2 label'>可达到中等及以上运动强度</span>
<span class='text-end'>
<span>{{info.mediumStrengthName}}</span>
</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='10' title='女性病史' name='10' v-if='womanMHShow'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>女性病史</span>
<span class='text-end'>
<span>{{ info.femaleMedicalHistoryName || '-'}}</span>
</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='11' title='用药史' name='11' v-if='medicationHShow'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>用药史</span>
<span class='text-end'>
<span>{{ info.medicineHistoryName || '-'}}</span>
</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='12' title='高密度脂蛋白胆固醇' name='12' v-if='triglycerideShow'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>高密度脂蛋白胆固醇</span>
<span class='text-end'>
<span>{{ info.hdlCholesterin || '-'}} mmol/L</span>
</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='13' title='甘油三酯' name='13' v-if='triglycerideShow'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>甘油三酯</span>
<span class='text-end'>
<span>{{ info.triglyceride || '-'}} mmol/L</span>
</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='14' title='总胆固醇' name='14' v-if='triglycerideShow'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>总胆固醇</span>
<span class='text-end'>
<span>{{ info.serumCholesterin || '-'}} mmol/L</span>
</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='15' title='有害物质接触或婴幼儿时期病史' name='15' v-if='babyMHShow'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span>
<span>{{ info.touchHarmfulName || '-'}}</span>
</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='16' title='血压(左侧右侧)值(SBP/DBP)' name='16' v-if='bloodPressureShow'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<div>
<div>第一次:{{ info.pressureOneSbp }}-{{ info.pressureOneDbp }} mmHg;</div>
<div class='mt-2'>第二次:{{ info.pressureTwoSbp }}-{{ info.pressureTwoDbp }} mmHg</div>
</div>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='17' title='饮食习惯' name='17' v-if='eatHabitShow'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>饮食习惯</span>
<span class='text-end'>
<span>{{ info.dietaryHabitName || '-'}}</span>
</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='18' title='饮酒情况' name='18' v-if='drinkShow'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>饮酒频率</span>
<span class='text-end'>
<span>{{ info.drinkFrequencyName || '-'}}</span>
</span>
</div>
<div v-if="[2,3,4].includes(info.drinkFrequency)">
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>饮酒种类</span>
<span class='text-end'>
<span>{{ $addrJoin(info.drinkKindName, info.drinkKindOther) || '-'}}</span>
</span>
</div>
<div class='flex justify-between py-1 border-bottom item'>
<div class='shrink-0 mr-2 label'>日饮酒量</div>
<div class='text-end'>
<div v-for="item in (info.drinkKindCapacityList || [])" :key="item.drinkKind"
>
<span>{{item.drinkKindName}}:</span> <span>{{item.drinkCapacity || '-'}} mL</span>
</div>
<div>
<span>平均: </span><span>{{info.dayDrink || '-'}} mL</span>
</div>
</div>
</div>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>开始饮酒年龄</span>
<span class='text-end'>
<span>{{ info.startDrinkAge || '-'}} 岁</span>
</span>
</div>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>是否戒酒</span>
<span class='text-end'>
<span>{{ info.giveDrinkName || '-'}}</span>
</span>
</div>
<div class='flex justify-between py-1 border-bottom item' v-if="info.giveDrink == 1">
<span class='shrink-0 mr-2 label'>戒酒年龄</span>
<span class='text-end'>
<span>{{ info.giveDrinkStart || '-'}} 岁</span>
</span>
</div>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='19' title='吸烟情况' name='19' v-if='smokeShow'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>吸烟情况</span>
<span class='text-end'>
<span>{{ info.isSmokingName || '-'}}</span>
</span>
</div>
<div class='flex justify-between py-1 border-bottom item' v-if="info.isSmoking == 3 && smokeShow">
<span class='shrink-0 mr-2 label'>日吸烟量</span>
<span class='text-end'>
<span>{{ info.daySmoking || '-'}} 支</span>
</span>
</div>
<div class='flex justify-between py-1 border-bottom item' v-if="info.isSmoking == 3 && smokeShow">
<span class='shrink-0 mr-2 label'>开始吸烟年龄</span>
<span class='text-end'>
<span>{{ info.startSmoking || '-'}} 岁</span>
</span>
</div>
<div class='flex justify-between py-1 border-bottom item' v-if="info.isSmoking == 2 && smokeShow">
<span class='shrink-0 mr-2 label'>戒烟年龄</span>
<span class='text-end'>
<span>{{ info.giveSmokingAge || '-'}} 岁</span>
</span>
</div>
<div class='flex justify-between py-1 border-bottom item' v-if="smokeShow && info?.diseaseArrays?.includes(1)">
<span class='shrink-0 mr-2 label'>经常吸入二手烟</span>
<span class='text-end'>
<span>{{ info.secondSmokingName || '-'}} </span>
</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='20' title='黑棘皮病' name='20' v-if='blackSpinySkinShow'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>黑棘皮病</span>
<span class='text-end'>
<span>{{ info.blackSpinySkinName || '-'}}</span>
</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='21' title='长期精神紧张' name='21' v-if='mentalTensionShow'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>长期精神紧张</span>
<span class='text-end'>
<span>{{ info.mentalTensionName || '-'}}</span>
</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='22' title='皮肤或肌腱黄色瘤' name='22' v-if='xanthomaShow'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>皮肤或肌腱黄色瘤</span>
<span class='text-end'>
<span>{{ info.xanthomaName || '-'}}</span>
</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='23' title='跟腱增厚' name='23' v-if='tendoIncrassationShow'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>跟腱增厚</span>
<span class='text-end'>
<span>{{ info.tendoIncrassationName || '-'}}</span>
</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='24' title='中国糖尿病风险评分' name='24' v-if='riskScoreShow'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>中国糖尿病风险评分</span>
<span class='text-end'>
<span>{{ info.riskScoreName || '-'}}</span>
</span>
</div>
</div>
</van-collapse-item>
<van-collapse-item key='25' title='知情同意书' name='25'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div>
<image-preview :img-list='info.informedConsentUrl'></image-preview>
</div>
</van-collapse-item>
<van-collapse-item key='26' title='筛查机构' name='26'>
<template #right-icon>
<doc-icon type='doc-down' />
</template>
<div class='list'>
<div v-for='item in columnsOrg' :key='item.key'>
<div class='flex justify-between py-1 border-bottom item'>
<span class='shrink-0 mr-2 label'>{{ item.title }}</span>
<span class='text-end'>
<span>{{ info[item.key] || '-' }}</span>
</span>
</div>
</div>
</div>
</van-collapse-item>
</van-collapse>
</div>
</div>
</div>
</template>
<script>
import { showNotify } from 'vant'
import { secondScreenDetail } from '@/api/doctor/screening.js'
import { useStore } from '@/doctor/store'
import { fetchDataHandle } from '@/utils/common'
import ImagePreview from '@/doctor/components/imagePreview/imagePreview'
export default {
components: { ImagePreview },
data() {
return {
store: useStore(),
activeCollapse: [],
collapseList: [
{ title: '居民信息', name: '1' },
{ title: '筛查病种', name: '2' },
{ title: '病史', name: '3' },
{ title: '家族史', name: '4' },
{ title: '身高', name: '5' },
{ title: '体重', name: '6' },
{ title: 'BMI', name: '7' },
{ title: '腰围', name: '8' },
{ title: '锻炼频率', name: '9' },
{ title: '女性病史', name: '10' },
{ title: '用药史', name: '11' },
{ title: '高密度脂蛋白胆固醇', name: '12' },
{ title: '甘油三酯', name: '13' },
{ title: '总胆固醇', name: '14' },
{ title: '有害物质接触或婴幼儿时期病史', name: '15' },
{ title: '现测血压(左侧右侧)值(SBP/DBP)', name: '16' },
{ title: '饮食习惯', name: '17' },
{ title: '饮酒情况', name: '18' },
{ title: '吸烟情况', name: '19' },
{ title: '黑棘皮病', name: '20' },
{ title: '长期精神紧张', name: '21' },
{ title: '皮肤或肌腱黄色瘤', name: '22' },
{ title: '跟腱增厚', name: '23' },
{ title: '中国糖尿病风险评分', name: '24' },
{ title: '知情同意书', name: '25' },
{ title: '筛查机构', name: '26' }
],
// 全部展开、收起
collapseAll: false,
info: {},
columnsBase: [
{ title: '姓名', key: 'residentName' },
{ title: '证件号码', key: 'idCard' },
{ title: '性别', key: 'genderName' },
{ title: '出生日期', key: 'dataBirth' },
{ title: '年龄', key: 'currentAge' },
{ title: '民族', key: 'nationalName' },
{ title: '本人电话', key: 'telephone' },
{ title: '现住址', key: 'presentCodeName' },
{ title: '详细地址', key: 'nowAddress' },
{ title: '户籍地址', key: 'registeredCodeName' },
{ title: '详细地址', key: 'permanentAddress' }
],
columnsOrg: [
{ title: '筛查单位', key: 'screenUnitName' },
{ title: '筛查科室', key: 'screenOfficeName' },
{ title: '筛查医生', key: 'screenDoctorName' }
],
highRiskList: []
}
},
computed: {
id() {
return this.$route.query.id
},
residentInfo() {
return this.info.residentsRecord || {}
},
//判断病史显示隐藏
medicalHistoryShow() {
let res = false
const { diseaseArrays = [] } = this.info
if (diseaseArrays.includes(1) || diseaseArrays.includes(2) || diseaseArrays.includes(3) || diseaseArrays.includes(4)
|| diseaseArrays.includes(5) || diseaseArrays.includes(6) || diseaseArrays.includes(7)) {
res = true
}
return res
},
//判断家族史显示隐藏
familyHistoryShow() {
let res = false
const { diseaseArrays = [] } = this.info
if (diseaseArrays.includes(1) || diseaseArrays.includes(2) || diseaseArrays.includes(3) || diseaseArrays.includes(4)
|| diseaseArrays.includes(5) || diseaseArrays.includes(6) || diseaseArrays.includes(7)) {
res = true
}
return res
},
//判断身高、体重、BMI显示隐藏
highShow() {
let res = false
const { diseaseArrays = [] } = this.info
if (diseaseArrays.includes(1) || diseaseArrays.includes(2) || diseaseArrays.includes(4)
|| diseaseArrays.includes(6) || diseaseArrays.includes(7)) {
res = true
}
return res
},
//判断腰围显示隐藏
waistShow() {
let res = false
const { diseaseArrays = [] } = this.info
if (diseaseArrays.includes(1) || diseaseArrays.includes(2)) {
res = true
}
return res
},
//判断锻炼频率显示隐藏
exerciseShow() {
let res = false
const { diseaseArrays = [] } = this.info
if (diseaseArrays.includes(1) || diseaseArrays.includes(2) || diseaseArrays.includes(4)) {
res = true
}
return res
},
//判断女性病史显示隐藏
womanMHShow() {
let res = false
const { diseaseArrays = [] } = this.info
if (diseaseArrays.includes(2)) {
res = true
}
return res
},
//判断用药史显示隐藏
medicationHShow() {
let res = false
const { diseaseArrays = [] } = this.info
if (diseaseArrays.includes(2) || diseaseArrays.includes(4) || diseaseArrays.includes(6)) {
res = true
}
return res
},
//判断高密度脂蛋白胆固醇、甘油三酯、总胆固醇显示隐藏
triglycerideShow() {
let res = false
const { diseaseArrays = [] } = this.info
if (diseaseArrays.includes(2)) {
res = true
}
return res
},
//判断有害物质接触或婴幼儿时期病史显示隐藏
babyMHShow() {
let res = false
const { diseaseArrays = [] } = this.info
if (diseaseArrays.includes(5)) {
res = true
}
return res
},
//判断血压显示隐藏
bloodPressureShow() {
let res = false
const { diseaseArrays = [] } = this.info
if (diseaseArrays.includes(1)) {
res = true
}
return res
},
//判断饮食习惯显示隐藏
eatHabitShow() {
let res = false
const { diseaseArrays = [] } = this.info
if (diseaseArrays.includes(1)) {
res = true
}
return res
},
//判断饮酒情况显示隐藏
drinkShow() {
let res = false
const { diseaseArrays = [] } = this.info
if (diseaseArrays.includes(1)) {
res = true
}
return res
},
//判断吸烟情况显示隐藏
smokeShow() {
let res = false
const { diseaseArrays = [] } = this.info
if (diseaseArrays.includes(1) || diseaseArrays.includes(3) || diseaseArrays.includes(4) || diseaseArrays.includes(5) || diseaseArrays.includes(7)) {
res = true
}
return res
},
//判断黑棘皮病显示隐藏
blackSpinySkinShow() {
let res = false
const { diseaseArrays = [] } = this.info
if (diseaseArrays.includes(2)) {
res = true
}
return res
},
//判断长期精神紧张显示隐藏
mentalTensionShow() {
let res = false
const { diseaseArrays = [] } = this.info
if (diseaseArrays.includes(1)) {
res = true
}
return res
},
//判断皮肤或肌腱黄色瘤显示隐藏
xanthomaShow() {
let res = false
const { diseaseArrays = [] } = this.info
if (diseaseArrays.includes(7)) {
res = true
}
return res
},
//判断跟腱增厚显示隐藏
tendoIncrassationShow() {
let res = false
const { diseaseArrays = [] } = this.info
if (diseaseArrays.includes(7)) {
res = true
}
return res
},
//判断中国糖尿病风险评分显示隐藏
riskScoreShow() {
let res = false
const { diseaseArrays = [] } = this.info
if (diseaseArrays.includes(2)) {
res = true
}
return res
}
},
created() {
document.title = '筛查详情'
if (!this.id) {
showNotify({ type: 'warning', message: '未获取到查询信息' })
return
}
this.init()
},
methods: {
init() {
secondScreenDetail({ id: this.id }).then(res => {
let result = res.data || {}
this.info = result
this.highRiskListHandle(result)
})
},
highRiskListHandle(result) {
this.highRiskList = []
let obj = fetchDataHandle(result, {
diseaseArrays: 'strToArrNum',
hypertensionHighItem: 'strToArrNum',
diabetesHighItem: 'strToArrNum',
coronaryHighItem: 'strToArrNum',
strokeHighItem: 'strToArrNum',
pulmonaryHighItem: 'strToArrNum',
nephrosisHighItem: 'strToArrNum',
dyslipemiaHighItem: 'strToArrNum'
})
const {
hypertensionHighItem = [],
diabetesHighItem = [],
coronaryHighItem = [],
strokeHighItem = [],
pulmonaryHighItem = [],
nephrosisHighItem = [],
dyslipemiaHighItem = []
} = obj
let list = []
let o = { name: '', num: 0 }
if (hypertensionHighItem.length) {
o = { name: '高血压风险因素', num: hypertensionHighItem.length }
list.push(o)
}
if (diabetesHighItem.length) {
o = { name: '糖尿病风险因素', num: diabetesHighItem.length }
list.push(o)
}
if (coronaryHighItem.length) {
o = { name: '冠心病风险因素', num: coronaryHighItem.length }
list.push(o)
}
if (strokeHighItem.length) {
o = { name: '脑卒中风险因素', num: strokeHighItem.length }
list.push(o)
}
if (pulmonaryHighItem.length) {
o = { name: '慢阻肺风险因素', num: pulmonaryHighItem.length }
list.push(o)
}
if (nephrosisHighItem.length) {
o = { name: '慢性肾脏病风险因素', num: nephrosisHighItem.length }
list.push(o)
}
if (dyslipemiaHighItem.length) {
o = { name: '血脂异常风险因素', num: dyslipemiaHighItem.length }
list.push(o)
}
this.highRiskList = list
},
onBack() {
this.$router.back()
},
// 折叠面板切换
collapseChange(val) {
if (val && val.length <= 2) {
this.activeCollapse = val.slice(val.length - 1)
} else {
if (this.activeCollapse.length > val.length) {
this.activeCollapse = val
}
if (this.activeCollapse.length < val.length) {
this.activeCollapse = val.slice(val.length - 1)
}
}
if (val && val.length === this.collapseList.length) {
this.collapseAll = true
} else {
this.collapseAll = false
}
},
// 全部展开、收起
toggleAll() {
if (this.collapseAll) {
this.activeCollapse = []
} else {
this.activeCollapse = this.collapseList.map(e => e.name)
}
this.collapseAll = !this.collapseAll
}
}
}
</script>
<style lang='less' scoped>
@import url('../../utils/common.less');
.base-info {
background: linear-gradient(to bottom, #F0F6FF, #fff 50%);
color: #8c8c8c;
.name {
font-weight: 600;
color: #000;
font-size: 18px;
}
.top-label {
font-size: 13px;
line-height: 22px;
}
.color-b {
color: #262626;
}
.color-red {
color: #F5222D;
}
.tag {
border-radius: 2px;
padding: 3px 8px;
font-size: 12px;
line-height: 18px;
}
.tag-red {
border: 1px solid #EFF2F7;
color: #262626;
background-color: #EFF2F7;
}
}
.cont-box {
background-color: #f9f9f9;
.cont-inner {
background: linear-gradient(to bottom, #F0F6FF, #fff .6rem);
border-top-left-radius: .08rem;
border-top-right-radius: .08rem;
}
}
.collapse-head {
.icon-down {
vertical-align: middle;
font-size: .12rem;
.svg-icon {
transition: all .2s;
}
}
.icon-down-expanded {
.svg-icon {
transform: rotate(-180deg);
}
}
}
table {
text-align: left;
// border-bottom: 1px solid var(--van-cell-border-color);
> tr {
> td {
padding-left: 14px;
padding-bottom: 12px;
&:first-child {
text-align: right;
padding-left: 0;
}
}
}
}
.list {
color: #262626;
.label {
min-width: 5em;
}
}
.gap-y-1 {
row-gap: 4px;
}
</style>
...@@ -4,17 +4,17 @@ ...@@ -4,17 +4,17 @@
<span class="shrink-0 pr-2 back-bt" @click="toBack"> <span class="shrink-0 pr-2 back-bt" @click="toBack">
<doc-icon type="doc-left-1" style="color: #262626"/> <doc-icon type="doc-left-1" style="color: #262626"/>
</span> </span>
<div class="grow flex items-center px-2 mr-2 input-box"> <div class="grow flex items-center mr-2 input-box">
<doc-icon type="doc-search" class="shrink-0" style="color: #595959"/> <!-- <doc-icon type="doc-search" class="shrink-0" style="color: #595959"/> -->
<van-field v-model="idCard" placeholder="请输入身份证号查询" <van-field v-model="idCard" placeholder="请输入身份证号查询"
autocomplete="off" autocomplete="off"
clearable clearable
:formatter="formatter" :formatter="formatter"
@clear="idCardClear" @clear="idCardClear"
ref="idCardField"/> ref="idCardField"/>
<!-- <van-uploader :max-size="5 * 1024 * 1024" :after-read="afterRead" max-count="1"> <IdCardScan>
<doc-icon type="doc-camera" class="shrink-0 mr-3" style="color: #575B66"/> <doc-icon type="doc-camera" class="shrink-0 mr-3" style="color: #575B66"/>
</van-uploader>--> </IdCardScan>
</div> </div>
<span class="text-16 shrink-0 text-primary" @click="search"> <span class="text-16 shrink-0 text-primary" @click="search">
搜索 搜索
...@@ -40,8 +40,8 @@ ...@@ -40,8 +40,8 @@
<div class="pt-2" v-if="state === 2"> <div class="pt-2" v-if="state === 2">
<div class="text-12" style="color: #8c8c8c">查找结果:</div> <div class="text-12" style="color: #8c8c8c">查找结果:</div>
<div class="card" <div class="card" v-if="result.id">
v-if="result.chronicTagsArrayName || result.firstScreenResult || result.highTagsArray"> <!-- v-if="result.chronicTagsArrayName || result.firstScreenResult || result.highTagsArray" -->
<div class="py-3"> <div class="py-3">
<span class="text-16 font-semibold mr-3">{{ result.residentName }}</span> <span class="text-16 font-semibold mr-3">{{ result.residentName }}</span>
<span class="text-12 mr-3">{{ result.currentAge || '-' }}</span> <span class="text-12 mr-3">{{ result.currentAge || '-' }}</span>
...@@ -53,17 +53,17 @@ ...@@ -53,17 +53,17 @@
<span>{{ $idCardHide(result.idCard) }}</span> <span>{{ $idCardHide(result.idCard) }}</span>
</div> </div>
<div class="mb-2"> <div class="mb-2">
<span class="label">高危评估</span> <span class="label">人群分类</span>
<span>{{ result.firstScreenResultName || '-' }}</span> <span>{{ result.chronicCrowdName || '-' }}</span>
</div> </div>
<div class="flex mb-2"> <!-- <div class="flex mb-2">
<span class="shrink-0 label">专病高危评估</span> <span class="shrink-0 label">专病高危评估</span>
<span>{{ result.highTagsArrayName || '-' }}</span> <span>{{ result.highTagsArrayName || '-' }}</span>
</div> </div> -->
<div class="flex mb-2"> <div class="flex mb-2">
<span class="shrink-0 label">慢病标签</span> <span class="shrink-0 label">人群标签</span>
<ChronicTag :list="result.chronicTagsArray"/> <!-- <chronic-tag :list="result.chronicTagsArray" /> -->
<!-- <span>{{ result.chronicTagsArrayName }}</span> --> <span class="grow text-wrap">{{ result.groupsArraysName }}</span>
</div> </div>
<div class="text-12 tip"> <div class="text-12 tip">
<div style="color: #A5AEBE;" >提示:</div> <div style="color: #A5AEBE;" >提示:</div>
...@@ -75,7 +75,7 @@ ...@@ -75,7 +75,7 @@
</div> </div>
</div> </div>
<div class="card" v-else-if="!!result.id"> <!-- <div class="card" v-else-if="!!result.id">
<div class="py-3"> <div class="py-3">
<span class="text-16 font-semibold mr-3">{{ result.residentName }}</span> <span class="text-16 font-semibold mr-3">{{ result.residentName }}</span>
<span class="text-12 mr-3">{{ result.currentAge || '-' }}</span> <span class="text-12 mr-3">{{ result.currentAge || '-' }}</span>
...@@ -89,9 +89,9 @@ ...@@ -89,9 +89,9 @@
<div style="color: #A5AEBE;" >提示:</div> <div style="color: #A5AEBE;" >提示:</div>
<div style="color: #768092;">如需为居民进行 慢病诊断筛查 ,请在医生PC端进行操作</div> <div style="color: #768092;">如需为居民进行 慢病诊断筛查 ,请在医生PC端进行操作</div>
</div> </div>
</div> </div> -->
<div class="text-center empty" v-else> <div class="text-center empty" v-if="!total">
<img src="@/assets/image/doctor/empty.png" alt="" style="width: 1.2rem;"> <img src="@/assets/image/doctor/empty.png" alt="" style="width: 1.2rem;">
<p>暂无数据</p> <p>暂无数据</p>
</div> </div>
...@@ -101,15 +101,16 @@ ...@@ -101,15 +101,16 @@
</template> </template>
<script> <script>
import { getResidentByPage } from '@/api/doctor/generalFU.js' import { getResidentByPage } from '@/api/doctor/resident.js'
import { validateIdCard } from '@/utils/commonReg.js' import { validateIdCard } from '@/utils/commonReg.js'
import { setLocalStorage, getLocalStorage } from '@/utils/common.js' import { setLocalStorage, getLocalStorage } from '@/utils/common.js'
import { showFailToast } from 'vant' import { showFailToast } from 'vant'
import ChronicTag from '@/doctor/components/chronicTag/ChronicTag.vue' // import ChronicTag from '@/doctor/components/chronicTag/ChronicTag.vue'
import IdCardScan from '@/doctor/components/idCardScan/IdCardScan.vue'
export default { export default {
components: { components: {
ChronicTag IdCardScan
}, },
data() { data() {
return { return {
...@@ -118,7 +119,9 @@ export default { ...@@ -118,7 +119,9 @@ export default {
// 历史记录 // 历史记录
history: [], history: [],
result: {}, result: {},
// 显示切换
state: 1, state: 1,
total: 0,
show: false, show: false,
value1: undefined, value1: undefined,
value2: undefined value2: undefined
...@@ -150,6 +153,7 @@ export default { ...@@ -150,6 +153,7 @@ export default {
getResidentByPage(query).then(res => { getResidentByPage(query).then(res => {
const result = res?.data?.dataList || [] const result = res?.data?.dataList || []
this.result = result[0] || {} this.result = result[0] || {}
this.total = res.data.total || 0
this.setHistory() this.setHistory()
}).finally(() => { }).finally(() => {
this.state = 2 this.state = 2
...@@ -161,9 +165,9 @@ export default { ...@@ -161,9 +165,9 @@ export default {
}, },
toDetail() { toDetail() {
this.$router.push({ this.$router.push({
path: `/doctor/resident/base`, path: `/doctor/patient-detail`,
query: { query: {
residentId: this.result.residentInfoId residentInfoId: this.result.residentInfoId
} }
}) })
}, },
...@@ -189,11 +193,6 @@ export default { ...@@ -189,11 +193,6 @@ export default {
clearHistory() { clearHistory() {
setLocalStorage(this.historyKey, []) setLocalStorage(this.historyKey, [])
this.history = [] this.history = []
},
// 证件上传后
afterRead(file) {
console.log(file)
showNotify({ type: 'primary', message: '文件上传' })
} }
} }
} }
......
...@@ -6,7 +6,11 @@ export const useStore = defineStore('chronic', { ...@@ -6,7 +6,11 @@ export const useStore = defineStore('chronic', {
// 字典 // 字典
dict: [], dict: [],
//登录医生相关基本信息 //登录医生相关基本信息
authInfo: {} authInfo: {},
// 刷新标记
refreshMark: 1,
// 页面是否处于隐藏状态
documentHidden: false
} }
}, },
getters: {}, getters: {},
...@@ -27,6 +31,12 @@ export const useStore = defineStore('chronic', { ...@@ -27,6 +31,12 @@ export const useStore = defineStore('chronic', {
} }
let temp = array.find(e => e.value == value) || {} let temp = array.find(e => e.value == value) || {}
return temp.name || '' return temp.name || ''
},
onRefreshMark() {
this.refreshMark++
},
onDocumentHidden(value) {
this.documentHidden = value
} }
} }
}) })
:deep(.doc-tabs) {
border-bottom: 1px solid #EBEBEC;
.van-tab {
font-weight: 500;
}
.van-tabs__line {
border-radius: 0;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
}
// 顶部导航栏
.doc-nav-bar {
position: relative;
border-bottom: 1px solid #3C3C435C;
font-size: 18px;
font-weight: 600;
.back-bt {
position: absolute;
left: .16rem;
top: 50%;
transform: translateY(-50%);
}
}
// 折叠面板
:deep(.doc-collapse) {
margin-top: .1rem;
&::after {
display: none;
}
.van-cell {
padding: .1rem 0;
color: #8C8C8C;
font-weight: 600;
background: transparent;
&::after {
display: none;
}
.svg-icon {
font-size: .12rem;
transition: all .2s;
}
}
.van-collapse-item {
.van-collapse-item__content {
padding: 0;
color: #262626;
}
&::after {
display: none;
}
}
// 展开
.van-collapse-item__title--expanded {
.svg-icon {
transform: rotate(-180deg);
}
}
}
\ No newline at end of file
<template>
<div class="h-full flex flex-col workbench">
<DocNavBar title="慢病管理" class="shrink-0" home>
<template #right>
<doc-icon type="doc-config" style="color: #262626" class="mr-3 text-16"
@click="toConfig"/>
<doc-icon type="doc-search" style="color: #262626" class="text-16"
@click="toSearch"/>
</template>
</DocNavBar>
<div class="grow flex flex-col" style="min-height: 0;position: relative;" ref="list">
<div class="shrink-0 workbench-tab">
<div class="back"></div>
<div class="flex workbench-tab-inner" ref="tab-inner">
<div v-for="(item, index) in configTab" :key="item.key" @click="tabSelect(item, index)"
:class="['item', { 'item-active': item.key == tabActive.key }]">{{item.name}}</div>
</div>
</div>
<div class="grow" style="background: #F8FAFC;min-height: 0;">
<component :is="tabActive.component"
:ref="tabActive.key"
:searchType="configRange"/>
<van-popup v-model:show="configVisible" position="top" :style="{ height: '20%' }"
style="position: absolute;transition: none"
:overlay-style="{ position: 'absolute' }"
transition="viewer-fade"
:teleport="(() => $refs.list)()">
<div class="h-full flex flex-col workbench-search-box">
<div class="px-4 py-3 grow">
<div class="mb-3">查询范围</div>
<van-radio-group v-model="configValue.range" direction="horizontal">
<van-radio :name="1">本科室</van-radio>
<van-radio :name="2">本人</van-radio>
</van-radio-group>
</div>
<div class="text-16 flex shrink-0 text-center bt-group">
<div class="grow py-3 submit-btn" @click="saveConfig">确定</div>
</div>
</div>
</van-popup>
</div>
</div>
</div>
</template>
<script>
import { getUserConfig, addUserConfig, updateUserConfig } from '@/api/doctor/resident.js'
import DocNavBar from '@/doctor/components/docNavBar/DocNavBar.vue'
import TableWork from './tables/Work.vue'
import TableVisit from './tables/Visit.vue'
import TableReceive from './tables/Receive.vue'
import TableFirstScreen from './tables/FirstScreen.vue'
import TableHighRisk from './tables/HighRisk.vue'
export default {
name: 'Workbench',
components: {
DocNavBar,
TableWork,
TableVisit,
TableReceive,
TableFirstScreen,
TableHighRisk
},
data() {
return {
configTab: [
{ key: 'work', component: 'TableWork', name: '工作记录' },
{ key: 'visit', component: 'TableVisit', name: '慢病待随访' },
// { key: 'receive', component: 'TableReceive', name: '待接诊居民' },
// { key: 'screenRecord', component: 'TableScreenRecord', name: '当年待筛查记录' },
// { key: 'firstScreen', component: 'TableFirstScreen', name: '初筛高危待筛查' },
// { key: 'highRisk', component: 'TableHighRisk', name: '高危待诊断' }
],
tabActive:{},
configName: '慢病APP个性化配置',
configVisible: false,
// 工作台查询范围 1:本科室 2:本人
configRange: 1,
configValue: { range: 1 },
configOption: null
}
},
created() {
this.init()
},
methods: {
init() {
this.tabActive = this.configTab[0]
// 加载配置
getUserConfig().then(res => {
const result = res.data || {}
const config = result.find(e => e.configName === this.configName)
this.configOption = config
if (config) {
this.configValue = JSON.parse(config.configValue)
this.configRange = this.configValue.range
}
})
},
toSearch() {
this.$router.push({
path: '/doctor/search'
})
},
toConfig() {
this.configVisible = true
},
saveConfig() {
const func = this.configOption ? updateUserConfig : addUserConfig
const configValue = this.configValue
let query = [{
configName: this.configName,
configValue: JSON.stringify(configValue),
id: this.configOption?.id
}]
func(query).then(res => {
this.configVisible = false
this.configRange = configValue.range
})
},
tabSelect(item, index) {
this.tabActive = item
const dom = this.$refs['tab-inner']
if (!dom) return
// console.log(dom.children[index].offsetLeft, dom.scrollLeft, dom.clientWidth, dom.scrollWidth, scrollNum)
// dom.children[index].scrollIntoView({ behavior: 'smooth', inline: 'start' })
const scrollNum = dom.children[index].offsetLeft - (dom.clientWidth - dom.children[index].clientWidth) / 2
dom.scrollTo({ left: scrollNum > 0 ? scrollNum : 0, behavior: 'smooth' })
}
}
}
</script>
<style lang="less" scoped>
.workbench {
background: linear-gradient(to bottom, #C6DBF9, #EFF2F7);
}
.workbench-tab {
color: #4D5665;
background: #C6DBF9;
padding-top: 10px;
position: relative;
.workbench-tab-inner {
align-items: flex-end;
position: relative;
overflow-x: auto;
overflow-y: hidden;
&::-webkit-scrollbar {
display: none;
}
}
.back {
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: 42px;
background-color: #E7F1FF;
border-top-left-radius: 12px;
border-top-right-radius: 12px;
}
.item {
flex: 1 0 auto;
position: relative;
padding: 0 16px;
height: 42px;
line-height: 42px;
text-align: center;
&:first-child {
border-top-left-radius: 12px;
}
&:last-child {
border-top-right-radius: 12px;
}
}
.item-active:first-child {
border-top-left-radius: 12px;
&::before {
display: none;
}
}
.item-active:last-child {
border-top-right-radius: 12px;
&::after {
display: none;
}
}
.item-active {
background-color: #F8FAFC;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
font-size: 16px;
height: 46px;
line-height: 46px;
font-weight: 600;
&::after {
content: '';
display: inline-block;
position: absolute;
right: -26px;
bottom: 0;
background: url('@/assets/image/doctor/tab-bg.png') no-repeat;
background-size: auto 100%;
background-position-x: -20px;
height: 100%;
width: 34px;
z-index: 1;
}
&::before {
content: '';
display: inline-block;
position: absolute;
left: -26px;
bottom: 0;
background: url('@/assets/image/doctor/tab-bg.png') no-repeat;
background-size: auto 100%;
background-position-x: -20px;
height: 100%;
width: 34px;
z-index: 1;
transform: rotateY(180deg);
}
}
}
:deep(.workbench-search-box) {
color: #595959;
.bt-group {
border-top: 1px solid #EBEBEC;
color: #262626;
.submit-btn {
color: #fff;
background-color: var(--van-primary-color);
}
}
}
</style>
<template>
<div class="h-full flex flex-col first-screen">
<div class="shrink-0 flex pb-2 px-2 pt-3 items-center">
<van-tabs shrink type="card" class="grow doc-tab-round" line>
<van-tab title="全部" title-style="padding: 0 .2rem"></van-tab>
</van-tabs>
<doc-icon type="doc-menu" style="font-size:.2rem;color:#03053D"
@click='openSearch' />
</div>
<div class='grow pt-1 relative min-h-0'>
<div class='h-full overflow-y-auto px-2 pb-3' ref='list'>
<van-pull-refresh v-model='loadingRefresh' @refresh='onRefresh'
:disabled='isRefreshDisable' style="min-height: 100%">
<van-list
v-model:loading='loading'
:finished='finished'
:finished-text="list.length ? '没有更多了' : ''"
:immediate-check='false'
@load='onMore'
>
<div class="flex flex-col gap-y-2.5">
<div class="py-3 px-4 doc-list-card" v-for='item in list' :key="item.id">
<div class="mb-4" @click="toDetail(item)">
<span class="name mr-2">{{ item.residentName }}</span>
<span class="tag mr-2">{{ item.currentAge }}</span>
<span class="tag mr-2">{{ item.genderName }}</span>
</div>
<div class="flex flex-col gap-y-2.5" @click="toDetail(item)">
<div>
<span class="label">身份证号</span>
<span>{{ item.idCard }}</span>
</div>
<div>
<span class="label">筛查医生</span>
<span>{{ item.screenDoctorName }}</span>
</div>
<div>
<span class="label">初筛日期</span>
<span>{{ item.screenDate }}</span>
</div>
</div>
<div class="divider my-3"></div>
<div class="bt-group">
<van-button round size="small" class="doc-btn-primary" @click="toDetail(item)">详情</van-button>
<!-- <van-button round size="small" class="doc-btn-primary" @click="toDetail(item)">复筛</van-button> -->
<van-button round size="small" class="doc-btn-primary" @click="onIgnore(item)">忽略</van-button>
</div>
</div>
</div>
</van-list>
<div class='text-center shrink-0 empty' v-if='!list.length'>
<img src='@/assets/image/doctor/empty.png' alt='' style='width: 1.2rem;'>
<p>暂无数据</p>
</div>
</van-pull-refresh>
</div>
<van-popup v-model:show="searchVisible" position="top" :style="{ height: '70%' }"
style="position: absolute;transition: none"
:overlay-style="{ position: 'absolute' }"
transition="viewer-fade"
:teleport="$refs.list">
<div class="h-full flex flex-col workbench-search-box">
<div class="px-4 py-3 grow overflow-y-auto">
<div class="mb-3">身份证号</div>
<van-field v-model="form.idCard" placeholder="请输入身份证号" maxlength="20"
class="doc-input">
<template #right-icon>
<IdCardScan />
</template>
</van-field>
<div class="my-3">居民姓名</div>
<van-field v-model="form.residentName" placeholder="输入居民姓名" maxlength="100"
class="doc-input"/>
<div class="my-3">初筛日期</div>
<div class="flex items-center">
<van-field v-model="form.startDate" placeholder="开始日期" readonly
class="doc-input"
@click="() => { dateShow = true, dateMark = 1 }"/>
<span class="px-2">~</span>
<van-field v-model="form.endDate" placeholder="结束日期" readonly
class="doc-input"
@click="() => { dateShow = true, dateMark = 2 }"/>
</div>
<van-popup v-model:show="dateShow" position="bottom" :teleport="$refs.list">
<van-date-picker @confirm="onDateConfirm" @cancel="dateShow = false" />
</van-popup>
<div class="my-3">数据来源</div>
<CheckBtn :options="store.getDict('CP00124')" v-model:value="form.source" column-2
class="check-btn-workbench"/>
</div>
<div class="text-16 flex shrink-0 text-center bt-group">
<div class="grow py-3" @click="reset">重置</div>
<div class="grow py-3 submit-btn" @click="search">确定</div>
</div>
</div>
</van-popup>
</div>
</div>
</template>
<script>
import { getBeSecondScreenByPage, addIgnoreRecord } from '@/api/doctor/workbench.js'
import { useStore } from '@/doctor/store'
import CheckBtn from '@/doctor/components/checkBtn/CheckBtn.vue'
import IdCardScan from '@/doctor/components/idCardScan/IdCardScan.vue'
import { showToast } from 'vant'
const DefaultForm = {
// 数据来源,[DC00051]
source: undefined,
// 状态
status: undefined,
// 初筛日期-截止日期
startDate: undefined,
// 初筛日期-开始日期
endDate: undefined,
// 姓名
residentName: undefined,
// 身份证号
idCard: undefined
}
export default {
name: 'TableFirstScreen',
components: {
CheckBtn,
IdCardScan
},
props: {
searchType: { default: 1 }
},
data() {
return {
store: useStore(),
list: [],
pagination: {
total: 0,
pageIndex: 1,
pageSize: 8
},
loading: false,
finished: false,
loadingRefresh: false,
isRefreshDisable: false,
// 搜索弹出框
searchVisible: false,
// 时间选择
dateShow: false,
// 判断对哪一个日期赋值
dateMark: 0,
form: { ...DefaultForm },
}
},
created() {
this.load()
},
mounted() {
const list = this.$refs.list
list.addEventListener('scroll', () => {
if (list.scrollTop > 0) {
this.isRefreshDisable = true
} else {
this.isRefreshDisable = false
}
})
},
methods: {
load(loading = true) {
const query = {
pageIndex: this.pagination.pageIndex,
pageSize: this.pagination.pageSize,
searchType: this.searchType,
serveType: 2,
...this.form
}
getBeSecondScreenByPage(query, loading).then(res => {
if (this.pagination.pageIndex === 1) {
this.list = []
}
this.list = this.list.concat(res.data.dataList || [])
this.pagination.total = res.data.total || 0
this.finished = this.list.length >= this.pagination.total
}).finally(() => {
this.loading = false
this.loadingRefresh = false
})
},
search() {
this.pagination.pageIndex = 1
this.load()
this.searchVisible = false
},
reset() {
this.form = { ...DefaultForm }
this.rangeDate = []
this.search()
},
onMore() {
this.pagination.pageIndex++
this.load(false)
},
onRefresh() {
this.pagination.pageIndex = 1
this.load()
},
openSearch() {
this.searchVisible = !this.searchVisible
},
onDateConfirm({ selectedValues }) {
const result = selectedValues.join('-')
if (this.dateMark === 1) {
this.form.startDate = result
} else if (this.dateMark === 2) {
this.form.endDate = result
}
this.dateShow = false
this.dateMark = 0
},
toDetail(record) {
if (!record) return
if (record.residentInfoId == null) {
showToast('暂时无法查看 详情信息')
return
}
this.$router.push({
path: '/doctor/patient-detail',
query: {
residentInfoId: record.residentInfoId
}
})
},
onIgnore(record) {
let params={
relationId:record.screenId,
ignoreType:2,
}
addIgnoreRecord(params).then(() => {
this.list = this.list.filter(e => e.screenId !== record.screenId)
setTimeout(() => {
showToast('操作成功')
}, 800);
})
}
},
watch: {
searchType() {
this.onRefresh()
},
'store.refreshMark'() {
this.onRefresh()
}
}
}
</script>
<style lang="less" scoped>
</style>
<template>
<div class="h-full flex flex-col heigh-risk">
<div class="shrink-0 flex pb-2 px-2 pt-3 items-center">
<van-tabs shrink type="card" class="grow doc-tab-round" line
v-model:active="activeTab"
@change="tabChange">
<van-tab v-for="item in tabList" :key="item.value"
:title="item.name"></van-tab>
</van-tabs>
<div class="shrink-0 pl-3" style="border-left: 1px solid #A5AEBE;" @click='openSearch'>
<doc-icon type="doc-menu" style="font-size:.2rem;color:#03053D"/>
</div>
</div>
<div class='grow pt-1 relative min-h-0'>
<div class='h-full overflow-y-auto px-2 pb-3' ref='list'>
<van-pull-refresh v-model='loadingRefresh' @refresh='onRefresh'
:disabled='isRefreshDisable' style="min-height: 100%">
<van-list
v-model:loading='loading'
:finished='finished'
:finished-text="list.length ? '没有更多了' : ''"
:immediate-check='false'
@load='onMore'
>
<div class="flex flex-col gap-y-2.5">
<div class="py-3 px-4 doc-list-card" v-for='item in list' :key="item.id">
<div class="mb-4" @click="toDetail(item)">
<span class="name mr-2">{{ item.residentName }}</span>
<span class="tag mr-2">{{ item.currentAge }}</span>
<span class="tag mr-2">{{ item.genderName || '-' }}</span>
</div>
<div class="flex flex-col gap-y-2.5" @click="toDetail(item)">
<div>
<span class="label">身份证号</span>
<span>{{ item.idCard }}</span>
</div>
<div>
<span class="label">筛查医生</span>
<span>{{ item.screenDoctorName }}</span>
</div>
<div>
<span class="label">复筛日期</span>
<span>{{ item.screenDate }}</span>
</div>
</div>
<div class="divider my-3"></div>
<div class="bt-group">
<van-button round size="small" class="doc-btn-primary" @click="toDetail(item)">详情</van-button>
<!-- <van-button round size="small" class="doc-btn-primary" @click='toDetail(item)'>诊断</van-button> -->
<van-button round size="small" class="doc-btn-primary" @click="onIgnore(item)">忽略</van-button>
</div>
</div>
</div>
</van-list>
<div class='text-center shrink-0 empty' v-if='!list.length'>
<img src='@/assets/image/doctor/empty.png' alt='' style='width: 1.2rem;'>
<p>暂无数据</p>
</div>
</van-pull-refresh>
</div>
<van-popup v-model:show="searchVisible" position="top" :style="{ height: '70%' }"
style="position: absolute;transition: none"
:overlay-style="{ position: 'absolute' }"
transition="viewer-fade"
:teleport="$refs.list">
<div class="h-full flex flex-col workbench-search-box">
<div class="px-4 py-3 grow overflow-y-auto">
<div class="mb-3">身份证号</div>
<van-field v-model="form.idCard" placeholder="请输入身份证号" maxlength="20"
class="doc-input">
<template #right-icon>
<IdCardScan />
</template>
</van-field>
<div class="my-3">居民姓名</div>
<van-field v-model="form.residentName" placeholder="输入居民姓名" maxlength="100"
class="doc-input"/>
<div class="my-3">复筛日期</div>
<div class="flex items-center">
<van-field v-model="form.startDate" placeholder="开始日期" readonly
class="doc-input"
@click="() => { dateShow = true, dateMark = 1 }"/>
<span class="px-2">~</span>
<van-field v-model="form.endDate" placeholder="结束日期" readonly
class="doc-input"
@click="() => { dateShow = true, dateMark = 2 }"/>
</div>
<van-popup v-model:show="dateShow" position="bottom" :teleport="$refs.list">
<van-date-picker @confirm="onDateConfirm" @cancel="dateShow = false" />
</van-popup>
<div class="my-3">数据来源</div>
<CheckBtn :options="store.getDict('CP00124')" v-model:value="form.source" column-2
class="check-btn-workbench"/>
</div>
<div class="text-16 flex shrink-0 text-center bt-group">
<div class="grow py-3" @click="reset">重置</div>
<div class="grow py-3 submit-btn" @click="search">确定</div>
</div>
</div>
</van-popup>
</div>
</div>
</template>
<script>
import { useStore } from '@/doctor/store'
import { getDiagnoseByPage, addIgnoreRecord } from '@/api/doctor/workbench.js'
import CheckBtn from '@/doctor/components/checkBtn/CheckBtn.vue'
import IdCardScan from '@/doctor/components/idCardScan/IdCardScan.vue'
import { showToast } from 'vant'
const DefaultForm = {
// 数据来源,[DC00051]
source: undefined,
// 状态
status: undefined,
// 复筛日期-截止日期
startDate: undefined,
// 复筛日期-开始日期
endDate: undefined,
// 姓名
residentName: undefined,
// 身份证号
idCard: undefined
}
export default {
name: 'TableHighRisk',
components: {
CheckBtn,
IdCardScan
},
props: {
searchType: { default: 1 }
},
data() {
return {
store: useStore(),
list: [],
pagination: {
total: 0,
pageIndex: 1,
pageSize: 8
},
loading: false,
finished: false,
loadingRefresh: false,
isRefreshDisable: false,
// 慢病tab列表
tabList: [
{ name: '高血压', value: 1 },
{ name: '糖尿病', value: 2 },
{ name: '冠心病', value: 3 },
{ name: '脑卒中', value: 4 },
{ name: '慢阻肺', value: 5 },
{ name: '慢性肾脏病', value: 6 },
{ name: '血脂异常', value: 7 }
],
activeTab: 0,
// 搜索弹出框
searchVisible: false,
// 时间选择
dateShow: false,
// 判断对哪一个日期赋值
dateMark: 0,
form: { ...DefaultForm },
}
},
computed: {
activeTabItem() {
return this.tabList[this.activeTab] || {}
},
isValidArray() {
return [
{ name: '是', value: 1 },
{ name: '否', value: 2 }
]
}
},
created() {
this.load()
},
mounted() {
const list = this.$refs.list
list.addEventListener('scroll', () => {
if (list.scrollTop > 0) {
this.isRefreshDisable = true
} else {
this.isRefreshDisable = false
}
})
},
methods: {
load(loading = true) {
const query = {
pageIndex: this.pagination.pageIndex,
pageSize: this.pagination.pageSize,
serveType: 3,
searchType: this.searchType,
diseaseType: this.activeTabItem.value,
...this.form
}
getDiagnoseByPage(query, loading).then(res => {
if (this.pagination.pageIndex === 1) {
this.list = []
}
this.list = this.list.concat(res.data.dataList || [])
this.pagination.total = res.data.total || 0
this.finished = this.list.length >= this.pagination.total
}).finally(() => {
this.loading = false
this.loadingRefresh = false
})
},
search() {
this.pagination.pageIndex = 1
this.load()
this.searchVisible = false
},
reset() {
this.form = { ...DefaultForm }
this.search()
},
onMore() {
this.pagination.pageIndex++
this.load(false)
},
onRefresh() {
this.pagination.pageIndex = 1
this.load()
},
tabChange() {
this.pagination.pageIndex = 1
this.load()
},
openSearch() {
this.searchVisible = !this.searchVisible
},
onDateConfirm({ selectedValues }) {
const result = selectedValues.join('-')
if (this.dateMark === 1) {
this.form.startDate = result
} else if (this.dateMark === 2) {
this.form.endDate = result
}
this.dateShow = false
this.dateMark = 0
},
toDetail(record) {
if (!record) return
if (record.residentInfoId == null) {
showToast('暂时无法查看 详情信息')
return
}
this.$router.push({
path: '/doctor/patient-detail',
query: {
residentInfoId: record.residentInfoId
}
})
},
onIgnore(record) {
let params={
relationId: record.screenId,
ignoreType: 3,
diseaseType: this.activeTabItem.value
}
addIgnoreRecord(params).then(() => {
this.list = this.list.filter(e => e.id !== record.id)
setTimeout(() => {
showToast('操作成功')
}, 800);
})
},
},
watch: {
searchType() {
this.onRefresh()
},
'store.refreshMark'() {
this.onRefresh()
}
}
}
</script>
<style lang="less" scoped>
</style>
<template>
<div class="h-full flex flex-col receive">
<div class="shrink-0 flex pb-2 px-2 pt-3 items-center">
<van-tabs shrink type="card" class="grow doc-tab-round" line>
<van-tab title="全部" title-style="padding: 0 .2rem"></van-tab>
</van-tabs>
<doc-icon type="doc-menu" style="font-size:.2rem;color:#03053D"
@click='openSearch' />
</div>
<div class='grow pt-1 relative min-h-0'>
<div class='h-full overflow-y-auto px-2 pb-3' ref='list'>
<van-pull-refresh v-model='loadingRefresh' @refresh='onRefresh'
:disabled='isRefreshDisable' style="min-height: 100%">
<van-list
v-model:loading='loading'
:finished='finished'
:finished-text="list.length ? '没有更多了' : ''"
:immediate-check='false'
@load='onMore'
>
<div class="flex flex-col gap-y-2.5">
<div class="py-3 px-4 doc-list-card" v-for='item in list' :key="item.id">
<div class="mb-4" @click="toDetail(item)">
<span class="name mr-2">{{ item.residentName }}</span>
<span class="tag mr-2">{{ item.age }}</span>
<span class="tag mr-2">{{ item.genderName }}</span>
</div>
<div class="flex flex-col gap-y-2.5" @click="toDetail(item)">
<div>
<span class="label">转出单位</span>
<span>{{ item.outUnitName }}</span>
</div>
<div>
<span class="label">转出医生</span>
<span>{{ item.outDoctorName }}</span>
</div>
<div>
<span class="label">转诊类型</span>
<span>{{ item.referralTypeName }}</span>
</div>
<div>
<span class="label">创建日期</span>
<span>{{ item.created }}</span>
</div>
</div>
<div class="divider my-3"></div>
<div class="bt-group">
<van-button round size="small" class="doc-btn-primary" @click="toDetail(item)">详情</van-button>
<!-- <van-button round size="small" class="doc-btn-primary" @click="toDetail(item)">接诊</van-button> -->
<van-button round size="small" class="doc-btn-primary" @click="onIgnore(item)">忽略</van-button>
</div>
</div>
</div>
</van-list>
<div class='text-center shrink-0 empty' v-if='!list.length'>
<img src='@/assets/image/doctor/empty.png' alt='' style='width: 1.2rem;'>
<p>暂无数据</p>
</div>
</van-pull-refresh>
</div>
<van-popup v-model:show="searchVisible" position="top" :style="{ height: '70%' }"
style="position: absolute;transition: none"
:overlay-style="{ position: 'absolute' }"
transition="viewer-fade"
:teleport="$refs.list">
<div class="h-full flex flex-col workbench-search-box">
<div class="px-4 py-3 grow overflow-y-auto" style="">
<div class="mb-3">身份证号</div>
<van-field v-model="form.idCard" placeholder="请输入身份证号" maxlength="20"
class="doc-input">
<template #right-icon>
<IdCardScan />
</template>
</van-field>
<div class="my-3">居民姓名</div>
<van-field v-model="form.residentName" placeholder="输入居民姓名" maxlength="100"
class="doc-input"/>
<div class="my-3">转出单位</div>
<van-field v-model="form._unitName" placeholder="请选择" readonly
@click="() => unitShow = true"
class="doc-input">
</van-field>
<DocUnit v-model:show='unitShow' v-model:value='form.outUnitId' @change='e => form._unitName = e.unitName'
:teleport="$refs.list"/>
<div class="my-3">创建日期</div>
<div class="flex items-center">
<van-field v-model="form.startDate" placeholder="开始日期" readonly
class="doc-input"
@click="() => { dateShow = true, dateMark = 1 }"/>
<span class="px-2">~</span>
<van-field v-model="form.endDate" placeholder="结束日期" readonly
class="doc-input"
@click="() => { dateShow = true, dateMark = 2 }"/>
</div>
<van-popup v-model:show="dateShow" position="bottom" :teleport="$refs.list">
<van-date-picker @confirm="onDateConfirm" @cancel="dateShow = false" />
</van-popup>
<div class="my-3">转诊类型</div>
<CheckBtn :options="store.getDict('CP00184')" v-model:value="form.referralType" column-2
class="check-btn-workbench"/>
</div>
<div class="text-16 flex shrink-0 text-center bt-group">
<div class="grow py-3" @click="reset">重置</div>
<div class="grow py-3 submit-btn" @click="search">确定</div>
</div>
</div>
</van-popup>
</div>
</div>
</template>
<script>
import { getReceiveByPage, ignoreReceive } from '@/api/doctor/workbench.js'
import { useStore } from '@/doctor/store'
import CheckBtn from '@/doctor/components/checkBtn/CheckBtn.vue'
import IdCardScan from '@/doctor/components/idCardScan/IdCardScan.vue'
import DocUnit from '@/doctor/components/docUnit/DocUnit.vue'
import { showToast } from 'vant'
const DefaultForm = {
// 转出单位id
outUnitId: undefined,
_unitName: undefined,
// 转诊类型,[DC00001]
referralType: undefined,
// 日期-截止日期
startDate: undefined,
// 日期-开始日期
endDate: undefined,
// 姓名
screenResidentName: undefined,
// 身份证号
idCard: undefined
}
export default {
name: 'TableReceive',
components: {
CheckBtn,
IdCardScan,
DocUnit
},
props: {
searchType: { default: 1 }
},
data() {
return {
store: useStore(),
list: [],
pagination: {
total: 0,
pageIndex: 1,
pageSize: 8
},
loading: false,
finished: false,
loadingRefresh: false,
isRefreshDisable: false,
// 搜索弹出框
searchVisible: false,
// 单位选择
unitShow: false,
// 时间选择
dateShow: false,
// 判断对哪一个日期赋值
dateMark: 0,
form: { ...DefaultForm },
}
},
created() {
this.load()
},
mounted() {
const list = this.$refs.list
list.addEventListener('scroll', () => {
if (list.scrollTop > 0) {
this.isRefreshDisable = true
} else {
this.isRefreshDisable = false
}
})
},
methods: {
load(loading = true) {
const query = {
pageIndex: this.pagination.pageIndex,
pageSize: this.pagination.pageSize,
searchType: this.searchType,
...this.form
}
getReceiveByPage(query, loading).then(res => {
if (this.pagination.pageIndex === 1) {
this.list = []
}
this.list = this.list.concat(res.data.dataList || [])
this.pagination.total = res.data.total || 0
this.finished = this.list.length >= this.pagination.total
}).finally(() => {
this.loading = false
this.loadingRefresh = false
})
},
search() {
this.pagination.pageIndex = 1
this.load()
this.searchVisible = false
},
reset() {
this.form = { ...DefaultForm }
this.rangeDate = []
this.search()
},
onMore() {
this.pagination.pageIndex++
this.load(false)
},
onRefresh() {
this.pagination.pageIndex = 1
this.load()
},
openSearch() {
this.searchVisible = !this.searchVisible
},
onDateConfirm({ selectedValues }) {
const result = selectedValues.join('-')
if (this.dateMark === 1) {
this.form.startDate = result
} else if (this.dateMark === 2) {
this.form.endDate = result
}
this.dateShow = false
this.dateMark = 0
},
toDetail(record) {
if (!record) return
if (record.residentInfoId == null) {
showToast('暂时无法查看 详情信息')
return
}
this.$router.push({
path: '/doctor/patient-detail',
query: {
residentInfoId: record.residentInfoId
}
})
},
onIgnore(record) {
let params={
id: record.id,
state: 3,
}
ignoreReceive(params).then(() => {
this.list = this.list.filter(e => e.id !== record.id)
setTimeout(() => {
showToast('操作成功')
}, 800);
})
}
},
watch: {
searchType() {
this.onRefresh()
},
'store.refreshMark'() {
this.onRefresh()
}
}
}
</script>
<style lang="less" scoped>
</style>
<template>
<div class="h-full flex flex-col visit">
<div class="shrink-0 flex pb-2 px-2 pt-3 items-center">
<van-tabs shrink type="card" class="grow doc-tab-round" line
v-model:active="activeTab"
@change="tabChange">
<van-tab v-for="item in tabList" :key="item.value"
:title="item.name"></van-tab>
</van-tabs>
<div class="shrink-0 pl-3" style="border-left: 1px solid #A5AEBE;" @click='openSearch'>
<doc-icon type="doc-menu" style="font-size:.2rem;color:#03053D"/>
</div>
</div>
<div class='grow pt-1 relative min-h-0'>
<div class='h-full overflow-y-auto px-2 pb-3' ref='list'>
<van-pull-refresh v-model='loadingRefresh' @refresh='onRefresh'
:disabled='isRefreshDisable' style="min-height: 100%">
<van-list
v-model:loading='loading'
:finished='finished'
:finished-text="list.length ? '没有更多了' : ''"
:immediate-check='false'
@load='onMore'
>
<div class="flex flex-col gap-y-2.5">
<div class="py-3 px-4 doc-list-card" v-for='item in list' :key="item.id">
<div class="mb-4" @click="toDetail(item)">
<span class="name mr-2">{{ item.residentName }}</span>
<span class="tag mr-2">{{ item.age }}</span>
<span class="tag mr-2">{{ item.genderName || '-' }}</span>
</div>
<div class="flex flex-col gap-y-2.5" @click="toDetail(item)">
<div>
<span class="label">身份证号</span>
<span>{{ $idCardHide(item.idCard) }}</span>
</div>
<div>
<span class="label">是否逾期</span>
<span>{{ item.isOverdue == 1 ? '是' : '否' }}</span>
</div>
<div>
<span class="label">逾期天数</span>
<span>
<span :class="{'text-red': item.overdueDay > 0}">{{ item.overdueDay }}</span>
<span></span>
</span>
</div>
<div class="flex">
<span class="label">慢病标签</span>
<span>
<ChronicTag :list='item.chronicTagsArray' />
</span>
</div>
<div>
<span class="label">数据来源</span>
<span>{{ item.sourceName || '-' }}</span>
</div>
</div>
<div class="divider my-3"></div>
<div class="bt-group">
<van-button round size="small" class="doc-btn-primary" @click="toDetail(item)">详情</van-button>
<van-button round size="small" class="doc-btn-primary" @click='toAddGeneral(item)'>通用随访</van-button>
<van-button round size="small" class="doc-btn-primary" @click="onIgnore(item)">忽略</van-button>
</div>
</div>
</div>
</van-list>
<div class='text-center shrink-0 empty' v-if='!list.length'>
<img src='@/assets/image/doctor/empty.png' alt='' style='width: 1.2rem;'>
<p>暂无数据</p>
</div>
</van-pull-refresh>
</div>
<van-popup v-model:show="searchVisible" position="top" :style="{ height: '80%' }"
style="position: absolute;transition: none"
:overlay-style="{ position: 'absolute' }"
transition="viewer-fade"
:teleport="$refs.list">
<div class="h-full flex flex-col workbench-search-box">
<div class="px-4 py-3 grow overflow-y-auto" style="">
<div class="mb-3">身份证号</div>
<van-field v-model="form.idCard" placeholder="请输入身份证号" maxlength="20"
class="doc-input">
<template #right-icon>
<IdCardScan />
</template>
</van-field>
<div class="my-3">居民姓名</div>
<van-field v-model="form.residentName" placeholder="输入居民姓名" maxlength="100"
class="doc-input"/>
<div class="my-3">下次随访日期</div>
<div class="flex items-center">
<van-field v-model="form.nextVisitDateStart" placeholder="开始日期" readonly
class="doc-input"
@click="() => { dateShow = true, dateMark = 1 }"/>
<span class="px-2">~</span>
<van-field v-model="form.nextVisitDateEnd" placeholder="结束日期" readonly
class="doc-input"
@click="() => { dateShow = true, dateMark = 2 }"/>
</div>
<van-popup v-model:show="dateShow" position="bottom" :teleport="$refs.list">
<van-date-picker @confirm="onDateConfirm" @cancel="dateShow = false"/>
</van-popup>
<div class="my-3">数据来源</div>
<CheckBtn :options="store.getDict('CP00124')" v-model:value="form.source" column-3
class="check-btn-workbench"/>
<div class="my-3">是否逾期</div>
<CheckBtn :options="isOverdueArray" v-model:value="form.isOverdue"
class="check-btn-workbench"/>
</div>
<div class="text-16 flex shrink-0 text-center bt-group">
<div class="grow py-3" @click="reset">重置</div>
<div class="grow py-3 submit-btn" @click="search">确定</div>
</div>
</div>
</van-popup>
</div>
</div>
</template>
<script>
import { useStore } from '@/doctor/store'
import { getVisitByPage, delVisit } from '@/api/doctor/workbench.js'
import ChronicTag from '@/doctor/components/chronicTag/ChronicTag.vue'
import CheckBtn from '@/doctor/components/checkBtn/CheckBtn.vue'
import IdCardScan from '@/doctor/components/idCardScan/IdCardScan.vue'
import { showToast } from 'vant'
const DefaultForm = {
// 数据来源,[CP00124]
source: undefined,
// 是否逾期
isOverdue: '',
// 下次随访日期-开始日期
nextVisitDateStart: undefined,
// 下次随访日期-截止日期
nextVisitDateEnd: undefined,
// 姓名
residentName: undefined,
// 身份证号
idCard: undefined
}
export default {
name: 'TableVisit',
components: {
ChronicTag,
CheckBtn,
IdCardScan
},
props: {
searchType: { default: 1 }
},
data() {
return {
store: useStore(),
list: [],
pagination: {
total: 0,
pageIndex: 1,
pageSize: 8
},
loading: false,
finished: false,
loadingRefresh: false,
isRefreshDisable: false,
// 慢病tab列表
tabList: [
{ name: '高血压', value: 1 },
{ name: '糖尿病', value: 2 },
{ name: '冠心病', value: 3 },
{ name: '脑卒中', value: 4 },
{ name: '慢阻肺', value: 5 },
{ name: '慢性肾脏病', value: 6 },
{ name: '血脂异常', value: 7 }
],
activeTab: 0,
// 搜索弹出框
searchVisible: false,
// 时间选择
dateShow: false,
// 判断对哪一个日期赋值
dateMark: 0,
form: { ...DefaultForm }
}
},
computed: {
activeTabItem() {
return this.tabList[this.activeTab] || {}
},
isOverdueArray() {
return [
{ name: '是', value: 1 },
{ name: '否', value: 2 }
]
}
},
created() {
this.load()
},
mounted() {
const list = this.$refs.list
list.addEventListener('scroll', () => {
if (list.scrollTop > 0) {
this.isRefreshDisable = true
} else {
this.isRefreshDisable = false
}
})
},
methods: {
load(loading = true) {
const query = {
pageIndex: this.pagination.pageIndex,
pageSize: this.pagination.pageSize,
searchType: this.searchType,
diseaseType: this.activeTabItem.value,
...this.form
}
getVisitByPage(query, loading).then(res => {
if (this.pagination.pageIndex === 1) {
this.list = []
}
this.list = this.list.concat(res.data.dataList || [])
this.pagination.total = res.data.total || 0
this.finished = this.list.length >= this.pagination.total
}).finally(() => {
this.loading = false
this.loadingRefresh = false
})
},
search() {
this.pagination.pageIndex = 1
this.load()
this.searchVisible = false
},
reset() {
this.form = { ...DefaultForm }
this.search()
},
onMore() {
this.pagination.pageIndex++
this.load(false)
},
onRefresh() {
this.pagination.pageIndex = 1
this.load()
},
tabChange() {
this.pagination.pageIndex = 1
this.load()
},
openSearch() {
this.searchVisible = !this.searchVisible
},
onDateConfirm({ selectedValues }) {
const result = selectedValues.join('-')
if (this.dateMark === 1) {
this.form.nextVisitDateStart = result
} else if (this.dateMark === 2) {
this.form.nextVisitDateEnd = result
}
this.dateShow = false
this.dateMark = 0
},
toDetail(record) {
if (!record) return
if (record.residentInfoId == null) {
showToast('暂时无法查看 详情信息')
return
}
this.$router.push({
path: '/doctor/patient-detail',
query: {
residentInfoId: record.residentInfoId
}
})
},
onIgnore(record) {
delVisit({ id: record.id }).then(() => {
this.list = this.list.filter(e => e.id !== record.id)
setTimeout(() => {
showToast('操作成功')
}, 800);
})
},
//新增通用随访
toAddGeneral(val) {
const {id, ...others} = val
this.$router.push({
path: `/doctor/followUp/generalFU/add`,
query: {...others}
})
}
},
watch: {
searchType() {
this.onRefresh()
},
'store.refreshMark'() {
this.onRefresh()
}
}
}
</script>
<style lang="less" scoped>
</style>
<template>
<div class="h-full flex flex-col work">
<div class="shrink-0 flex px-2 pb-2 pt-3 items-center">
<van-tabs shrink type="card" class="grow doc-tab-round" line>
<van-tab title="全部" title-style="padding: 0 .2rem"></van-tab>
</van-tabs>
<doc-icon type="doc-menu" style="font-size:.2rem;color:#03053D"
@click='openSearch' />
</div>
<div class='grow pt-1 relative min-h-0'>
<div class='h-full px-2 pb-3 overflow-y-auto' ref='list'>
<van-pull-refresh v-model='loadingRefresh' @refresh='onRefresh'
:disabled='isRefreshDisable' style="min-height: 100%">
<van-list
v-model:loading='loading'
:finished='finished'
:finished-text="list.length ? '没有更多了' : ''"
:immediate-check='false'
@load='onMore'
>
<div class="flex flex-col gap-y-2.5">
<div class="py-3 px-4 doc-list-card" v-for='item in list' :key="item.id">
<div class="mb-4" @click="toDetail(item)">
<span class="name mr-2">{{ item.residentName }}</span>
<span class="tag mr-2">{{ item.currentAge }}</span>
<span class="tag mr-2">{{ item.genderName }}</span>
</div>
<div class="flex flex-col gap-y-2.5" @click="toDetail(item)">
<div>
<span class="label">身份证号</span>
<span>{{ $idCardHide(item.idCard) || '-' }}</span>
</div>
<div>
<span class="label">服务类型</span>
<span>{{ item.serviceTypeName }}</span>
</div>
<div>
<span class="label">服务日期</span>
<span>{{ item.serviceDate }}</span>
</div>
<div>
<span class="label">服务医生</span>
<span>{{ item.serviceDoctorName }}</span>
</div>
</div>
<div class="divider my-3"></div>
<div class="bt-group">
<van-button round size="small" class="doc-btn-primary" @click="toDetail(item)">详情</van-button>
</div>
</div>
</div>
</van-list>
<div class='text-center shrink-0 empty' v-if='!list.length'>
<img src='@/assets/image/doctor/empty.png' alt='' style='width: 1.2rem;'>
<p>暂无数据</p>
</div>
</van-pull-refresh>
</div>
<van-popup v-model:show="searchVisible" position="top" :style="{ height: '80%' }"
style="position: absolute;transition: none"
:overlay-style="{ position: 'absolute' }"
transition="viewer-fade"
:teleport="$refs.list">
<div class="h-full flex flex-col workbench-search-box">
<div class="px-4 py-3 grow overflow-y-auto" style="">
<div class="mb-3">身份证号</div>
<van-field v-model="form.idCard" placeholder="请输入身份证号" maxlength="20"
clearable
class="doc-input">
<template #right-icon>
<IdCardScan />
</template>
</van-field>
<div class="my-3">居民姓名</div>
<van-field v-model="form.residentName" placeholder="输入居民姓名" maxlength="100" clearable
class="doc-input"/>
<div class="my-3">服务日期</div>
<div class="flex items-center">
<van-field v-model="form.startDate" placeholder="开始日期" readonly
class="doc-input"
@click="() => { dateShow = true, dateMark = 1 }"/>
<span class="px-2">~</span>
<van-field v-model="form.endDate" placeholder="结束日期" readonly
class="doc-input"
@click="() => { dateShow = true, dateMark = 2 }"/>
</div>
<van-popup v-model:show="dateShow" position="bottom" :teleport="$refs.list">
<van-date-picker @confirm="onDateConfirm" @cancel="dateShow = false"/>
</van-popup>
<div class="my-3">数据来源</div>
<CheckBtn :options="store.getDict('CP00124')" v-model:value="form.source" column-3
class="check-btn-workbench"/>
<div class="my-3">服务类型</div>
<CheckBtn :options="store.getDict('CP00150')" v-model:value="form.serviceType" column-2
class="check-btn-workbench"/>
</div>
<div class="text-16 flex shrink-0 text-center bt-group">
<div class="grow py-3" @click="reset">重置</div>
<div class="grow py-3 submit-btn" @click="search">确定</div>
</div>
</div>
</van-popup>
</div>
</div>
</template>
<script>
import { getWorkByPage } from '@/api/doctor/workbench.js'
import { useStore } from '@/doctor/store'
import CheckBtn from '@/doctor/components/checkBtn/CheckBtn.vue'
import IdCardScan from '@/doctor/components/idCardScan/IdCardScan.vue'
import { showToast } from 'vant'
const DefaultForm = {
// 数据来源,[DC00051]
source: undefined,
// 服务类型
serviceType: undefined,
// 服务日期-截止日期
startDate: undefined,
// 服务日期-开始日期
endDate: undefined,
// 姓名
residentName: undefined,
// 身份证号
idCard: undefined
}
export default {
name: 'TableWork',
props: {
searchType: { default: 1 }
},
components: {
CheckBtn,
IdCardScan
},
data() {
return {
store: useStore(),
list: [],
pagination: {
total: 0,
pageIndex: 1,
pageSize: 8
},
loading: false,
finished: false,
loadingRefresh: false,
isRefreshDisable: false,
// 搜索弹出框
searchVisible: false,
// 时间选择
dateShow: false,
// 判断对哪一个日期赋值
dateMark: 0,
form: { ...DefaultForm }
}
},
created() {
this.load()
},
mounted() {
const list = this.$refs.list
list.addEventListener('scroll', () => {
if (list.scrollTop > 0) {
this.isRefreshDisable = true
} else {
this.isRefreshDisable = false
}
})
},
methods: {
load(loading = true) {
const query = {
pageIndex: this.pagination.pageIndex,
pageSize: this.pagination.pageSize,
searchType: this.searchType,
...this.form
}
getWorkByPage(query, loading).then(res => {
if (this.pagination.pageIndex === 1) {
this.list = []
}
this.list = this.list.concat(res.data.dataList || [])
this.pagination.total = res.data.total || 0
this.finished = this.list.length >= this.pagination.total
}).finally(() => {
this.loading = false
this.loadingRefresh = false
})
},
search() {
this.pagination.pageIndex = 1
this.load()
this.searchVisible = false
},
reset() {
this.form = { ...DefaultForm }
this.search()
},
onMore() {
this.pagination.pageIndex++
this.load(false)
},
onRefresh() {
this.pagination.pageIndex = 1
this.load()
},
openSearch() {
this.searchVisible = !this.searchVisible
},
onDateConfirm({ selectedValues }) {
const result = selectedValues.join('-')
if (this.dateMark === 1) {
this.form.startDate = result
} else if (this.dateMark === 2) {
this.form.endDate = result
}
this.dateShow = false
this.dateMark = 0
},
toDetail(record) {
if (!record) return
if (record.residentInfoId == null) {
showToast('暂时无法查看 详情信息')
return
}
this.$router.push({
path: '/doctor/patient-detail',
query: {
residentInfoId: record.residentInfoId
}
})
}
},
watch: {
searchType() {
this.onRefresh()
},
'store.refreshMark'() {
this.onRefresh()
}
}
}
</script>
<style lang="less" scoped>
</style>
...@@ -3,6 +3,7 @@ import 'vant/es/toast/style/index' ...@@ -3,6 +3,7 @@ import 'vant/es/toast/style/index'
import 'vant/es/notify/style/index' import 'vant/es/notify/style/index'
import 'vant/es/dialog/style/index' import 'vant/es/dialog/style/index'
import 'vant/es/image-preview/style/index' import 'vant/es/image-preview/style/index'
import { DatePicker } from 'vant'
// 自定义svg 图标组件 // 自定义svg 图标组件
import DocIcon from '@/components/docIcon/index' import DocIcon from '@/components/docIcon/index'
...@@ -20,6 +21,12 @@ export function registe(app) { ...@@ -20,6 +21,12 @@ export function registe(app) {
app.config.globalProperties.$idCardHide = idCardHide app.config.globalProperties.$idCardHide = idCardHide
app.config.globalProperties.$phoneHide = phoneHide app.config.globalProperties.$phoneHide = phoneHide
app.config.globalProperties.$addrJoin = addrJoin app.config.globalProperties.$addrJoin = addrJoin
// 日期选择框默认选中当前日期
DatePicker.props.modelValue.default = () => {
const now = dayjs()
return [now.year(), now.month() + 1, now.date()]
}
} }
// idCard 脱敏 // idCard 脱敏
......
...@@ -125,7 +125,7 @@ export default { ...@@ -125,7 +125,7 @@ export default {
}, },
created() { created() {
if (!this.id) { if (!this.id) {
showNotify({ type: 'warning', message: '未获取到查询信息', duration: 0 }) showNotify({ type: 'warning', message: '未获取到查询信息'})
return return
} }
this.init() this.init()
......
...@@ -53,7 +53,7 @@ export default { ...@@ -53,7 +53,7 @@ export default {
}, },
created() { created() {
if (!this.idCard) { if (!this.idCard) {
showNotify({ type: 'warning', message: '未获取到用户信息', duration: 0 }) showNotify({ type: 'warning', message: '未获取到用户信息'})
return return
} }
this.init() this.init()
......
...@@ -70,7 +70,7 @@ export default { ...@@ -70,7 +70,7 @@ export default {
}, },
created() { created() {
if (!this.doctorId) { if (!this.doctorId) {
showNotify({ type: 'warning', message: '未获取到医生信息', duration: 0 }) showNotify({ type: 'warning', message: '未获取到医生信息' })
return return
} }
this.recordForm.doctorId = this.doctorId this.recordForm.doctorId = this.doctorId
......
...@@ -524,15 +524,15 @@ export default { ...@@ -524,15 +524,15 @@ export default {
}, },
resultHandle() { resultHandle() {
const {currentAge, height = 0, weight = 0, waistline, familyHistory = [], isSmoking, gender, const {currentAge, height = 0, weight = 0, waistline, familyHistory = [], isSmoking, gender,
pressureOneSbp, pressureOneDbp, pressureTwoSbp, pressureTwoDbp, fastingGlucose, ldlCholesterin} = this.form pressureOneSbp, pressureOneDbp, pressureTwoSbp, pressureTwoDbp, fastingGlucose, ldlCholesterin, serumCholesterin} = this.form
let list = [] let list = []
if (currentAge >= 50) { if (currentAge >= 50) {
list.push(1) list.push(1)
} }
let bmi = parseFloat(this.bmi) let bmi = parseFloat(this.bmi)
if ((bmi >= 24)|| if ((bmi >= 24)||
(gender == 2 && waistline >=85) || (gender == 2 && waistline >=80) ||
(gender == 1 && waistline >=90) ){ (gender == 1 && waistline >=85) ){
list.push(2) list.push(2)
} }
if (isSmoking == 1) { if (isSmoking == 1) {
...@@ -550,7 +550,10 @@ export default { ...@@ -550,7 +550,10 @@ export default {
if (fastingGlucose >= 6.1) { if (fastingGlucose >= 6.1) {
list.push(6) list.push(6)
} }
if (ldlCholesterin >= 3.4) { // if (ldlCholesterin >= 3.4) {
// list.push(7)
// }
if (serumCholesterin >= 5.2) {
list.push(7) list.push(7)
} }
list = Array.from(new Set(list)) list = Array.from(new Set(list))
......
...@@ -74,6 +74,7 @@ export default { ...@@ -74,6 +74,7 @@ export default {
background-color: #E4F2F0; background-color: #E4F2F0;
font-size: 15px; font-size: 15px;
padding-left: 2px; padding-left: 2px;
color: var(--van-primary-color);
} }
} }
.wrapper { .wrapper {
......
...@@ -118,7 +118,7 @@ export default { ...@@ -118,7 +118,7 @@ export default {
created() { created() {
document.title = '指导详情' document.title = '指导详情'
if (!this.id) { if (!this.id) {
showNotify({ type: 'warning', message: '未获取到查询信息', duration: 0 }) showNotify({ type: 'warning', message: '未获取到查询信息' })
return return
} }
this.init() this.init()
......
...@@ -149,7 +149,7 @@ export default { ...@@ -149,7 +149,7 @@ export default {
// 连接到im服务 // 连接到im服务
connect() { connect() {
if (!this.accountId || !this.token) { if (!this.accountId || !this.token) {
showNotify({ type: 'warning', message: '聊天服务连接失败', duration: 0 }) showNotify({ type: 'warning', message: '聊天服务连接失败' })
return return
} }
this.isConnect = false this.isConnect = false
...@@ -162,7 +162,8 @@ export default { ...@@ -162,7 +162,8 @@ export default {
onconnect: () => { onconnect: () => {
console.log('连接成功 ================>') console.log('连接成功 ================>')
this.isConnect = true this.isConnect = true
this.getLocalMsgs() // this.getLocalMsgs()
this.getHistoryMsgs()
this.toBottom('instant') this.toBottom('instant')
setTimeout(() => { setTimeout(() => {
// 开启滚动加载 // 开启滚动加载
...@@ -245,8 +246,34 @@ export default { ...@@ -245,8 +246,34 @@ export default {
} }
}) })
}, },
// 加载云端消息
getHistoryMsgs() {
const msg = this.msgs[0] || {}
this.loading = true
this.nim.getHistoryMsgs({
// sessionId: `p2p-${this.targetId}`,
scene: 'p2p',
to: this.targetId,
limit: 40,
end: msg.time,
done: (error, obj) => {
console.log('获取p2p历史消息' + (!error?'成功':'失败'), obj);
const msgs = obj.msgs || []
this.loading = false
if (!msgs.length) {
this.finished = true
return
}
msgs.sort((a, b) => {
return a.time - b.time
})
this.msgs = msgs.concat(this.msgs)
}
})
},
loadHistory() { loadHistory() {
this.getLocalMsgs() // this.getLocalMsgs()
this.getHistoryMsgs()
}, },
handleFiles() { handleFiles() {
let files = this.$refs['fileElem'].files let files = this.$refs['fileElem'].files
......
...@@ -40,7 +40,7 @@ export default { ...@@ -40,7 +40,7 @@ export default {
console.log(obj.duration) console.log(obj.duration)
}, },
ondisconnect: function(error) { ondisconnect: function(error) {
showNotify({ type: 'warning', message: '连接失败', duration: 0 }) showNotify({ type: 'warning', message: '连接失败' })
// if (error) { // if (error) {
// switch (error.code) { // switch (error.code) {
// case 302: // case 302:
......
...@@ -159,7 +159,7 @@ export default { ...@@ -159,7 +159,7 @@ export default {
created() { created() {
document.title = '筛查详情' document.title = '筛查详情'
if (!this.id) { if (!this.id) {
showNotify({ type: 'warning', message: '未获取到查询信息', duration: 0 }) showNotify({ type: 'warning', message: '未获取到查询信息' })
return return
} }
this.init() this.init()
......
...@@ -345,7 +345,7 @@ ...@@ -345,7 +345,7 @@
<span>{{ info.giveDrinkName || '-'}}</span> <span>{{ info.giveDrinkName || '-'}}</span>
</span> </span>
</div> </div>
<div class='flex justify-between py-1 border-bottom item'> <div class='flex justify-between py-1 border-bottom item' v-if="info.giveDrink == 1">
<span class='shrink-0 mr-2 label'>戒酒年龄</span> <span class='shrink-0 mr-2 label'>戒酒年龄</span>
<span class='text-end'> <span class='text-end'>
<span>{{ info.giveDrinkStart || '-'}} 岁</span> <span>{{ info.giveDrinkStart || '-'}} 岁</span>
...@@ -383,7 +383,7 @@ ...@@ -383,7 +383,7 @@
<span>{{ info.giveSmokingAge || '-'}} 岁</span> <span>{{ info.giveSmokingAge || '-'}} 岁</span>
</span> </span>
</div> </div>
<div class='flex justify-between py-1 border-bottom item' v-if="smokeShow && record?.diseaseArrays?.includes(1)"> <div class='flex justify-between py-1 border-bottom item' v-if="smokeShow && info?.diseaseArrays?.includes(1)">
<span class='shrink-0 mr-2 label'>经常吸入二手烟</span> <span class='shrink-0 mr-2 label'>经常吸入二手烟</span>
<span class='text-end'> <span class='text-end'>
<span>{{ info.secondSmokingName || '-'}} </span> <span>{{ info.secondSmokingName || '-'}} </span>
...@@ -728,7 +728,7 @@ export default { ...@@ -728,7 +728,7 @@ export default {
created() { created() {
document.title = '筛查详情' document.title = '筛查详情'
if (!this.id) { if (!this.id) {
showNotify({ type: 'warning', message: '未获取到查询信息', duration: 0 }) showNotify({ type: 'warning', message: '未获取到查询信息' })
return return
} }
this.init() this.init()
......
...@@ -13,9 +13,9 @@ ...@@ -13,9 +13,9 @@
<span class="name">{{ userInfo.residentName }}</span> <span class="name">{{ userInfo.residentName }}</span>
</div> </div>
<div class='lh-22'> <div class='lh-22'>
<div class='mt-3'>随访日期:<span class='color-26'>{{ info.screenDate || '-' }}</span></div> <div class='mt-3'>随访日期:<span class='color-26'>{{ info.visitDate || '-' }}</span></div>
<span>慢病高危评估结果:</span> <span>慢病高危评估结果:</span>
<span :class="{'text-red': info.screenResult !== 1, 'color-26': info.screenResult === 1 }">{{ info.screenResultName }}</span> <span :class="{'text-red': info.visitResult !== 1, 'color-26': info.visitResult === 1 }">{{ info.visitResultName }}</span>
</div> </div>
</div> </div>
</div> </div>
...@@ -96,7 +96,6 @@ ...@@ -96,7 +96,6 @@
<script> <script>
import { showNotify } from 'vant' import { showNotify } from 'vant'
import { firstScreenDetail } from '@/api/residentWX/screening.js'
import { useStore } from '@/residentWX/store' import { useStore } from '@/residentWX/store'
import { queryMajorFUDetail } from '@/api/residentWX/visit' import { queryMajorFUDetail } from '@/api/residentWX/visit'
...@@ -135,7 +134,7 @@ export default { ...@@ -135,7 +134,7 @@ export default {
{ title: '血清总胆固醇', key: 'serumCholesterin', unit: 'mmol/L' }, { title: '血清总胆固醇', key: 'serumCholesterin', unit: 'mmol/L' },
{ title: '高密度脂蛋白胆固醇', key: 'hdlCholesterin', unit: 'mmol/L' }, { title: '高密度脂蛋白胆固醇', key: 'hdlCholesterin', unit: 'mmol/L' },
{ title: '运动', key: 'exerciseIntensityName' }, { title: '运动', key: 'exerciseIntensityName' },
{ title: '慢病高危评估结果', key: 'screenResultName' } { title: '慢病高危评估结果', key: 'visitResultName' }
], info: {} }, ], info: {} },
{ title: '随访机构', name: '3', columns: [ { title: '随访机构', name: '3', columns: [
{ title: '随访机构', key: 'visitUnitName' }, { title: '随访机构', key: 'visitUnitName' },
...@@ -160,7 +159,7 @@ export default { ...@@ -160,7 +159,7 @@ export default {
created() { created() {
document.title = '主要慢病高危随访详情' document.title = '主要慢病高危随访详情'
if (!this.id) { if (!this.id) {
showNotify({ type: 'warning', message: '未获取到查询信息', duration: 0 }) showNotify({ type: 'warning', message: '未获取到查询信息' })
return return
} }
this.init() this.init()
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
</div> </div>
<div class='top-label mt-3'> <div class='top-label mt-3'>
<span >报告日期:<span class='color-b'>{{ info.screenDate || '-' }}</span></span> <span >报告日期:<span class='color-b'>{{ info.visitDate || '-' }}</span></span>
</div> </div>
<div class='top-label'> <div class='top-label'>
<span>慢病高危评估结果:</span> <span>慢病高危评估结果:</span>
...@@ -383,7 +383,7 @@ ...@@ -383,7 +383,7 @@
<span>{{ info.giveSmokingAge || '-'}} 岁</span> <span>{{ info.giveSmokingAge || '-'}} 岁</span>
</span> </span>
</div> </div>
<div class='flex justify-between py-1 border-bottom item' v-if="smokeShow && record?.diseaseArrays?.includes(1)"> <div class='flex justify-between py-1 border-bottom item' v-if="smokeShow && info?.diseaseArrays?.includes(1)">
<span class='shrink-0 mr-2 label'>经常吸入二手烟</span> <span class='shrink-0 mr-2 label'>经常吸入二手烟</span>
<span class='text-end'> <span class='text-end'>
<span>{{ info.secondSmokingName || '-'}} </span> <span>{{ info.secondSmokingName || '-'}} </span>
...@@ -488,7 +488,6 @@ ...@@ -488,7 +488,6 @@
<script> <script>
import { showNotify } from 'vant' import { showNotify } from 'vant'
import { secondScreenDetail } from '@/api/residentWX/screening.js'
import { useStore } from '@/residentWX/store' import { useStore } from '@/residentWX/store'
import { fetchDataHandle } from '@/utils/common' import { fetchDataHandle } from '@/utils/common'
import ImagePreview from '@/residentWX/components/imagePreview/imagePreview' import ImagePreview from '@/residentWX/components/imagePreview/imagePreview'
...@@ -729,7 +728,7 @@ export default { ...@@ -729,7 +728,7 @@ export default {
created() { created() {
document.title = '专病高危随访详情' document.title = '专病高危随访详情'
if (!this.id) { if (!this.id) {
showNotify({ type: 'warning', message: '未获取到查询信息', duration: 0 }) showNotify({ type: 'warning', message: '未获取到查询信息' })
return return
} }
this.init() this.init()
......
...@@ -4,7 +4,7 @@ const routes = [ ...@@ -4,7 +4,7 @@ const routes = [
{ {
path: '/doctor', path: '/doctor',
name: 'Home', name: 'Home',
redirect: '/doctor/followUp/list' redirect: '/doctor/workbench'
}, },
{ {
path: '/resident', path: '/resident',
...@@ -41,14 +41,34 @@ const routes = [ ...@@ -41,14 +41,34 @@ const routes = [
component: () => import(/* webpackChunkName: "doctor" */ '@/doctor/Doctor'), component: () => import(/* webpackChunkName: "doctor" */ '@/doctor/Doctor'),
children: [ children: [
{ {
path: 'followUp/list', path: 'workbench',
name: 'followUp-list', name: 'doctor-workbench',
component: () => import(/* webpackChunkName: "doctor" */ '@/doctor/followUp/List') component: () => import(/* webpackChunkName: "doctor" */ '@/doctor/workbench/Workbench.vue')
}, },
{ {
path: 'followUp/search', path: 'search',
name: 'followUp-search', name: 'doctor-search',
component: () => import(/* webpackChunkName: "doctor" */ '@/doctor/followUp/search/Search.vue') component: () => import(/* webpackChunkName: "doctor" */ '@/doctor/search/Search.vue')
},
{
path: 'patient-detail',
name: 'doctor-patient-detail',
component: () => import(/* webpackChunkName: "doctor" */ '@/doctor/patientDetail/PatientDetail.vue')
},
{
path: 'archives-form',
name: 'doctor-archives-form',
component: () => import(/* webpackChunkName: "doctor" */ '@/doctor/archives/form/BaseInfo.vue')
},
{
path: 'screening/firstDetail',
name: 'screening-firstDetail',
component: () => import(/* webpackChunkName: "doctor" */ '@/doctor/screening/detail/FirstDetail.vue')
},
{
path: 'screening/secondDetail',
name: 'screening-secondDetail',
component: () => import(/* webpackChunkName: "doctor" */ '@/doctor/screening/detail/SecondDetail.vue')
}, },
{ {
path: 'followUp/generalFU/detail', path: 'followUp/generalFU/detail',
...@@ -60,32 +80,6 @@ const routes = [ ...@@ -60,32 +80,6 @@ const routes = [
name: 'followUp-generalFU-add', name: 'followUp-generalFU-add',
component: () => import(/* webpackChunkName: "doctor" */ '@/doctor/followUp/generalFU/form/Index') component: () => import(/* webpackChunkName: "doctor" */ '@/doctor/followUp/generalFU/form/Index')
}, },
{
path: 'resident',
name: 'doctor-resident',
redirect: '/doctor/resident/base',
component: () => import(/* webpackChunkName: "doctor" */ '@/doctor/resident/Index.vue'),
children: [
// 基本信息
{
path: 'base',
name: 'doctor-resident-base',
component: () => import(/* webpackChunkName: "doctor" */ '@/doctor/resident/Base.vue')
},
// 随访记录
{
path: 'visit',
name: 'doctor-resident-visit',
component: () => import(/* webpackChunkName: "doctor" */ '@/doctor/resident/Visit.vue')
}
]
},
//修改基本信息
{
path: 'resident/base/update',
name: 'doctor-resident-base-update',
component: () => import(/* webpackChunkName: "page-doctor" */ '@/doctor/resident/form/BaseInfo.vue')
}
] ]
}, },
{ {
......
...@@ -10,10 +10,35 @@ ...@@ -10,10 +10,35 @@
<h4>多选/单选按键</h4> <h4>多选/单选按键</h4>
<span>{{ checkData }}</span> <span>{{ checkData }}</span>
</div> </div>
<CheckBtn :options="checkOptions" v-model:value="checkData"/> <CheckBtn :options="checkOptions" v-model:value="checkData" column-1 text-align="center"/>
<h4>upload</h4> <h4>upload</h4>
<DocImageUpload /> <DocImageUpload />
<h4>work-tab</h4>
<div class="work-tab">
<div class="back"></div>
<div class="flex work-tab-inner">
<div class="item">工作记录</div>
<div class="item" active>待筛查记录</div>
<div class="item" >慢病待随访</div>
</div>
</div>
<h4>tab</h4>
<van-tabs shrink type="card" class="doc-tab-round">
<van-tab v-for="index in 4" :title="'标签 ' + index" :key="index"></van-tab>
</van-tabs>
<h4>button</h4>
<van-button round size="small" class="doc-btn-primary">修改</van-button>
<van-button round size="small" class="doc-btn-red">删除</van-button>
<h4>MP4</h4>
<Mp4 :files="mp4Data" remove/>
<h4 @click="mp3Show">MP3</h4>
<Mp3 v-for="item in mp3Data" :file="item" :key="item.annexId" remove/>
</div> </div>
</template> </template>
...@@ -21,12 +46,16 @@ ...@@ -21,12 +46,16 @@
import DocUnit from '@/doctor/components/docUnit/DocUnit.vue' import DocUnit from '@/doctor/components/docUnit/DocUnit.vue'
import CheckBtn from '@/doctor/components/checkBtn/CheckBtn.vue' import CheckBtn from '@/doctor/components/checkBtn/CheckBtn.vue'
import DocImageUpload from '@/doctor/components/docImageUpload/DocImageUpload.vue' import DocImageUpload from '@/doctor/components/docImageUpload/DocImageUpload.vue'
import Mp4 from '@/doctor/components/mediaPlay/Mp4.vue'
import Mp3 from '@/doctor/components/mediaPlay/Mp3.vue'
export default { export default {
components:{ components:{
DocUnit, DocUnit,
CheckBtn, CheckBtn,
DocImageUpload DocImageUpload,
Mp4,
Mp3
}, },
data(){ data(){
return { return {
...@@ -36,20 +65,145 @@ export default { ...@@ -36,20 +65,145 @@ export default {
}, },
checkData: undefined, checkData: undefined,
checkOptions: [ checkOptions: [
{ name: '血常规', code: 1, disabled: true }, { name: '血常规', value: 1, disabled: true },
{ name: '尿常规', code: 2 }, { name: '尿常规', value: 2 },
{ name: '肝功能', code: 3 }, { name: '肝功能', value: 3 },
{ name: '肾功能', code: 4 }, { name: '肾功能', value: 4 },
{ name: '电解质', code: 5 } { name: '电解质', value: 5 }
] ],
mp4Data: [{ annexId: 1, annexUrl: 'https://beta-tumour.zmnyjk.com/chronic-admin/file-proxy/tumour/20241025/1729847263522306995.mp4?e=1733300684&token=yrkyCAltqk1WVrw1ZNWUl5F5gLxE0O8LJ0Vq4hzi:xukYHUsfX6OuAXIagBuHMCJ8XNg=', annexFileName: 'kanna.mp4' }],
mp3Data: []
} }
}, },
created() { created() {
sessionStorage.setItem('token', 'dd16fd27-4cfc-492e-a772-c817033133bb') sessionStorage.setItem('token', 'dd16fd27-4cfc-492e-a772-c817033133bb')
},
methods: {
mp3Show() {
this.mp3Data = [{ annexId: 2, annexUrl: 'https://beta-tumour.zmnyjk.com/chronic-admin/file-proxy/tumour/20241025/1729847336798585370.mp3?e=1733300684&token=yrkyCAltqk1WVrw1ZNWUl5F5gLxE0O8LJ0Vq4hzi:RTqkJZsScil9rGf9kdA0Lq1TEOs=', annexFileName: 'Never Gonna Give You Up-Rick Astley.mp3'}]
}
} }
} }
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
:deep(.doc-tab-round) {
.van-tabs__nav--card {
column-gap: 10px;
border: 0;
margin: 0;
}
.van-tab--card {
border: 0;
border-radius: 40px;
background: #fff;
color: #262626;
font-size: 14px;
line-height: 28px;
padding: 0 10px;
transition: all .2s;
}
.van-tab--card.van-tab--active {
color: #fff;
background: var(--van-primary-color);
font-weight: 500;
}
}
.doc-btn {
border: 0;
padding: 4px 12px;
height: 26px;
}
.doc-btn-primary {
.doc-btn();
color: var(--van-primary-color);
background: #F0F3FF;
}
.doc-btn-red {
.doc-btn();
color: #FF4D4F;
background: #FFF3F0;
}
.work-tab {
background: #C6DBF9;
padding-top: 10px;
position: relative;
.work-tab-inner {
align-items: flex-end;
position: relative;
}
.back {
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: 42px;
background-color: #E7F1FF;
border-top-left-radius: 12px;
border-top-right-radius: 12px;
}
.item {
// flex-grow: 1;
position: relative;
padding: 0 16px;
height: 42px;
line-height: 42px;
text-align: center;
&:first-child {
border-top-left-radius: 12px;
}
&:last-child {
border-top-right-radius: 12px;
}
}
.item:first-child[active] {
border-top-left-radius: 12px;
&::before {
display: none;
}
}
.item:last-child[active] {
border-top-right-radius: 12px;
&::after {
display: none;
}
}
.item[active] {
background-color: #F8FAFC;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
font-size: 16px;
height: 46px;
line-height: 46px;
&::after {
content: '';
display: inline-block;
position: absolute;
right: -26px;
bottom: 0;
background: url('@/assets/image/doctor/tab-bg.png') no-repeat;
background-size: auto 100%;
background-position-x: -20px;
height: 100%;
width: 34px;
z-index: 1;
}
&::before {
content: '';
display: inline-block;
position: absolute;
left: -26px;
bottom: 0;
background: url('@/assets/image/doctor/tab-bg.png') no-repeat;
background-size: auto 100%;
background-position-x: -20px;
height: 100%;
width: 34px;
z-index: 1;
transform: rotateY(180deg);
}
}
}
</style> </style>
...@@ -286,4 +286,18 @@ export function isResidentInfo() { ...@@ -286,4 +286,18 @@ export function isResidentInfo() {
res = true res = true
} }
return res return res
}
//一维数组去重
export function uniqueArr(arr =[], key= '') {
let res = []
if (key) {
arr.forEach(item => {
let tmp = res.filter(i => i[key] == item[key])
if (!tmp.length) {
res.push(item)
}
})
}
return res
} }
\ No newline at end of file
...@@ -31,7 +31,7 @@ module.exports = defineConfig({ ...@@ -31,7 +31,7 @@ module.exports = defineConfig({
}, },
'/chronic-admin': { '/chronic-admin': {
target: 'https://beta-tumour.zmnyjk.com', target: 'https://beta-tumour.zmnyjk.com',
// target: 'http://192.168.1.125:8900', // target: 'http://192.168.1.163:8900',
changOrigin: true, changOrigin: true,
pathRewrite: { pathRewrite: {
// '^/chronic-admin': '/' // '^/chronic-admin': '/'
...@@ -39,12 +39,12 @@ module.exports = defineConfig({ ...@@ -39,12 +39,12 @@ module.exports = defineConfig({
} }
}, },
'/chronic-resident': { '/chronic-resident': {
target: 'http://192.168.1.142:8903', // target: 'http://192.168.1.142:8903',
// target: 'https://beta-tumour.zmnyjk.com', target: 'https://beta-tumour.zmnyjk.com',
changOrigin: true, changOrigin: true,
pathRewrite: { pathRewrite: {
'^/chronic-resident': '/', // '^/chronic-resident': '/',
// '^/chronic-resident': '/chronic-resident' '^/chronic-resident': '/chronic-resident'
} }
} }
}, },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment