1.删除不需要的内容,修改部分样式
This commit is contained in:
2025-07-03 09:39:26 +08:00
parent 534e759350
commit 9cb6a0ad7a
1719 changed files with 38 additions and 347285 deletions
+2 -2
View File
@@ -11,12 +11,12 @@ VITE_PUBLIC_PATH = /
VITE_DROP_CONSOLE = false
#后台接口父地址(必填)
VITE_GLOB_API_URL=http://cqyt.dev.yg.dt.io
VITE_GLOB_API_URL=https://xjgateway.mcrm.vip:8888
#VITE_GLOB_API_URL=http://192.168.1.20
#VITE_GLOB_API_URL=http://cqyt.test.yg.dt.io
#后台接口全路径地址(必填)
VITE_GLOB_DOMAIN_URL=http://cqyt.dev.yg.dt.io
VITE_GLOB_DOMAIN_URL=https://xjgateway.mcrm.vip:8888
#VITE_GLOB_DOMAIN_URL=http://192.168.1.20
#VITE_GLOB_DOMAIN_URL=http://cqyt.test.yg.dt.io
# 接口前缀
+2 -2
View File
@@ -16,10 +16,10 @@ VITE_BUILD_COMPRESS = 'gzip'
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
#后台接口父地址(必填)
VITE_GLOB_API_URL=https://api.cqygjk.com
VITE_GLOB_API_URL=https://xjgateway.mcrm.vip:8888
#后台接口全路径地址(必填)
VITE_GLOB_DOMAIN_URL=https://api.cqygjk.com
VITE_GLOB_DOMAIN_URL=https://xjgateway.mcrm.vip:8888
#食堂接口前缀
VITE_GLOB_ST_DOMAIN_URL=https://yyjk.cqygjk.com/gateway
#西安、银川应急大屏
+1 -10
View File
@@ -3,14 +3,6 @@ MAINTAINER jeecgos@163.com
VOLUME /tmp
ENV LANG en_US.UTF-8
RUN echo "server { \
listen 80; \
location /jeecgboot/ { \
proxy_pass http://jeecg-boot-system:8080/jeecg-boot/; \
proxy_redirect off; \
proxy_set_header Host jeecg-boot-system; \
proxy_set_header X-Real-IP \$remote_addr; \
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; \
} \
#解决Router(mode: 'history')模式下,刷新路由地址不能找到页面的问题 \
location / { \
root /var/www/html/; \
@@ -26,5 +18,4 @@ RUN echo "server { \
&& mkdir -p /var/www/html
ADD dist/ /var/www/html/
EXPOSE 80
EXPOSE 443
EXPOSE 3100
+5 -5
View File
@@ -42,12 +42,12 @@
<h3 class="title-one">软件使用许可协议(健康长庆)</h3>
<h3 class="title-one">软件使用许可协议</h3>
<div>欢迎使用我们的服务</div>
<div>本软件许可使用协议《健康长庆平台服务协议》(以下称"本协议")由您与中国石油天然气股份有限公司长庆油田分公司行政事务管理处(以下称“长庆油田”)共同签署。</div>
<div>本软件许可使用协议《健康长庆平台服务协议》(以下称"本协议")由您与中国石油天然气股份有限公司新疆油田分公司行政事务管理处(以下称“新疆油田”)共同签署。</div>
<div>在使用“健康长庆”软件(以下称许可软件)之前,请仔细阅读本协议。一旦您下载安装使用许可软件,即表示您同意接受本协议所有条款和条件的约束。如您不同意本协议条款和条件,请勿使用许可软件,并请销毁所有许可软件副本。</div>
<div>健康长庆有权根据实际运营的情况对本协议不时进行调整,并以平台公告或电子邮件等书面形式通知您。修改后的协议于公示或邮件送达时生效。协议条款修改后,您继续使用许可软件的,即视为您已阅读并接受修改后的协议。</div>
<div>一、定义</div>
<div>1. 健康长庆APP:是指由长庆油田开发的,供您从应用下载平台(以下称下载平台)下载,并仅限在手机等手持移动终端(以下称移动终端)中安装、使用的软件系统。</div>
<div>2. 健康长庆服务:由长庆油田为您提供的服务。您可以通过许可软件在手持移动终端使用健康长庆服务。</div>
<div>1. 健康长庆APP:是指由新疆油田开发的,供您从应用下载平台(以下称下载平台)下载,并仅限在手机等手持移动终端(以下称移动终端)中安装、使用的软件系统。</div>
<div>2. 健康长庆服务:由新疆油田为您提供的服务。您可以通过许可软件在手持移动终端使用健康长庆服务。</div>
<div>3. 用户:指阅读并同意本协议内容,经过健康长庆在线注册程序成为健康长庆在线各项服务使用者。(以下更多称为“您”)</div>
<div>二、服务说明</div>
<div>1. 本平台是一个集健康咨询、应急就医、健康档案、体检服务等功能的综合个人健康管理平台,为确保您能正常地使用平台的各项服务,您应当阅读并遵守本协议。请您务必审慎阅读、充分理解各条款内容,以及开通或使用某项服务的单独协议,并选择接受或不接受。</div>
@@ -58,7 +58,7 @@
<div>6. 本协议的条款适用于平台提供的各种服务,但当您使用平台某特定服务时,如该服务另有单独的服务条款、指引或规则,您应遵守本协议及平台随时公布的与该服务相关的服务条款、指引或规则等。前述所有的指引和规则,均构成本协议的一部分。除非本协议另有其他明示规定,新推出的服务、增加或强化目前本服务的新功能,均受到本协议之规范。</div>
<div>7. 如对本协议内容有任何疑问、意见或建议,您可与我们联系。</div>
<div>三、本协议的确认和接纳</div>
<div>1、平台的各项服务的所有权和运作权归长庆油田所有。您同意所有注册协议条款,才能成为平台平台的正式用户。您确认:本协议条款是处理双方权利义务的契约,始终有效,法律另有强制性规定或双方另有特别约定的,依其规定。</div>
<div>1、平台的各项服务的所有权和运作权归新疆油田所有。您同意所有注册协议条款,才能成为平台平台的正式用户。您确认:本协议条款是处理双方权利义务的契约,始终有效,法律另有强制性规定或双方另有特别约定的,依其规定。</div>
<div>2、您点击注册登录,即视为您确认自己具有享受平台服务相应的权利能力和行为能力,能够独立承担法律责任。</div>
<div>3、平台通过互联网为您提供各项服务,并承担本协议和其它服务协议中对您的责任和义务。为使用本服务,您必须能够自行通过有法律资格的第三方对您提供互联网接入服务,并自行承担以下内容:</div>
<div>(1)自行配备上网所需的设备,包括手机、个人电脑、调制解调器及其他必要的设备装置。</div>
@@ -114,7 +114,7 @@
<div>1、 您一旦接受本协议,即表明您在任何时间在平台发表的任何形式的信息内容(包括但不限于员工评价、员工咨询、各类话题文章等信息内容)产生的权利,如著作权财产权(包括并不限于:复制权、发行权、出租权、展览权、表演权、放映权、广播权、信息网络传播权、摄制权、改编权、翻译权、汇编权以及应当由著作权人享有的其他可转让权利), 全部独家且不可撤销地转让给平台所有,您同意平台有权就任何主体侵权而单独提起诉讼。</div>
<div>2、本协议已经构成《中华人民共和国著作权法》第二十五条(条文序号依照2011年版著作权法确定)及相关法律规定的著作财产权等权利转让书面协议,其效力及于您在平台上发布的任何受著作权法保护的作品内容,无论该等内容形成于本协议订立前还是本协议订立后。</div>
<div>3、您同意并已充分了解本协议的条款,承诺不将已发表于平台的信息,以任何形式发布或授权其它主体以任何方式使用(包括但限于在各类网站、媒体上使用)、</div>
<div>4、长庆油田是平台的制作者,拥有平台内容及资源的著作权等合法权利,受国家法律保护,有权不时地对本协议及平台的内容进行修改,并在平台张贴,无须另行通知您。在法律允许的最大限度范围内,平台对本协议及的内容拥有解释权。</div>
<div>4、新疆油田是平台的制作者,拥有平台内容及资源的著作权等合法权利,受国家法律保护,有权不时地对本协议及平台的内容进行修改,并在平台张贴,无须另行通知您。在法律允许的最大限度范围内,平台对本协议及的内容拥有解释权。</div>
<div>5、除法律另有强制性规定外,未经平台明确的特别书面许可,任何单位或个人不得以任何方式非法地全部或部分复制、转载、引用、链接、抓取或以其他方式使用平台的信息内容,否则,平台有权追究其法律责任。</div>
<div>6、平台所刊登的资料信息(诸如文字、图表、标识、按钮图标、图像、声音文件片段、数字下载、数据编辑和软件),均是平台或其内容提供者的财产,受中国和国际版权法的保护。平台上所有内容的汇编是平台的排他财产,受中国和国际版权法的保护。平台上的所有软件都是平台的财产,受中国和国际版权法的保护。</div>
<div>十二、特别授权</div>
-300
View File
@@ -1,300 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>隐私权政策</title>
</head>
<style>
html,body {
padding: 0;
margin: 0;
}
html,body,#zwb{
box-sizing: border-box;
overflow: hidden auto;
font-size: 22px;
}
html::-webkit-scrollbar {
width: 0;
}
body::-webkit-scrollbar {
width: 0;
}
#zwb {
padding: 25px;
width: 100%;
height: 100%;
overflow: hidden auto;
}
div {
margin: 0 0 10px;
}
.title-one {
text-align: center;
margin: 5px 0
}
</style>
<body>
<div id="zwb">
<h3 class="title-one">隐私权政策</h3>
<div>本平台由西安恒烨通企业管理咨询有限公司开发和运维,平台深知个人信息对您的重要性,并会尽全力保护您的个人信息安全可靠。我们致力于维持您对我们的信任,恪守以下原则,保护您的个人信息:权责一致原则、目的明确原则、选择同意原则、最少够用原则、确保安全原则、主体参与原则、公开透明原则等。同时,我们承诺将采取相应的安全保护措施来保护您的个人信息。请在使用平台服务前,仔细阅读并了解本隐私权政策,我们将按照本政策收集、处理及披露您的信息。</div>
<div>本政策将帮助您了解以下内容:</div>
<div>1、定义</div>
<div>2、我们可能收集的信息</div>
<div>3、我们如何收集和使用您的个人信息</div>
<div>4、我们如何使用 Cookie 和同类技术</div>
<div>5、我们如何共享、转让、公开披露您的个人信息</div>
<div>6、员工业务数据和公开信息</div>
<div>7、我们如何保护您的个人信息</div>
<div>8、您如何管理您的个人信息</div>
<div>9、我们如何处理未成年人的个人信息</div>
<div>10、本声明和政策如何更新</div>
<div>11、如何联系我们</div>
<div>一、定义</div>
<div>1. 个人信息:</div>
<div>指以电子或者其他方式记录的与已识别或者可识别的自然人有关的各种信息,不包括匿名化处理后的信息</div>
<div>2. 个人健康信息</div>
<div>指以电子或者其他方式记录的能够单独或者与其他信息结合识别特定自然人身份或者反映特定自然人活动情况的各种健康信息,一旦泄露或者非法使用,可能导致个人受到歧视或者人身、财产受到严重危害的个人信息,包括如姓名、出生日期、身份证件号码、体检信息、就医信息、住址、通讯联系方式、通信记录和内容、账号密码、行踪轨迹、民族、个人生物特征、医疗健康、金融账户、个人行踪、不满十四周岁未成年人信息等。</div>
<div>3. 未成年人:指不满18周岁的自然人。</div>
<div>4. 儿童:指不满14周岁的自然人。</div>
<div>5. 设备信息</div>
<div>包括设备标识符 (IMEI、IDFA、Android1D、MAC、OAID、IMSI、SIM 卡序列号 (ICCID) 、设备序列号及其他设备相关信息),应用信息 (应用崩溃信息、通知开关状态、运行中进程、应用安装列表及其他应用相关信息) ,设备参数及系统信息(设备类型、设备型号、操作系统及硬件相关信息),设备网络环境信息 (IP地址,WiFi信息,基站信息及其他网络相关信息),蓝牙信息,广播组件通讯信息,运营商信息,传感器 (陀螺仪、重力传感器、加速度传感器、环境传感器、光学心率传感器),剪切板。以产品实际采集情况为准。</div>
<div>6. 业务数据</div>
<div>不同于个人信息,是指平台员工利用平台的服务上传、下载、分发等通过平台的技术服务处理的数据。</div>
<div>二、我们可能收集的信息</div>
<div>我们提供服务时,可能会收集、储存和使用下列与个人有关的信息。如果您不提供相关信息,可能无法注册成为平台员工或无法享受平台的某些服务,或者无法达到相关服务拟达到的效果。</div>
<div>2.1 与个人身份无关</div>
<div>当您使用平台的服务时,我们可能收集和汇总诸如员工的来源途径、访问顺序、停留时间等信息,例如记录使用平台服务的每个员工的来源途径、浏览器软件等。</div>
<div>2.2 与个人身份有关</div>
<div>当您使用平台的服务时,我们可能收集和汇总或要求您提供有关个人身份的信息,例如:</div>
<div>(1) 个人身份证明(包括身份证图片和身份证号、手机号、邮箱等);</div>
<div>(2) 个人补充信息(姓名、生日、籍贯、性别、兴趣爱好、学历、个人联系电话、住址、工作信息、婚姻状况、健康状况、;</div>
<div>(3) 网络身份标识信息(包括系统账号、IP地址、电子邮箱地址及与前述有关的密码、口令、口令保护答案、个人数字证书等);</div>
<div>(4) 个人健康信息(包括:姓名、性别、出生日期、身高体重、就诊卡、所在城市,所患病症、患病时长、体检报告、住院记录、诊治情况、检验报告、体检报告、用药记录、以往病史、过敏信息、家族史、患病史等,和历史咨询记录。</div>
<div>(5) 相机、相册(设备的相机功能,以拍摄照片或录制视频);</div>
<div>(6) 麦克风(通话、发送录音文件);</div>
<div>(7) 悬浮窗(在其他程序页面仍能保持应用内通话);</div>
<div>(8) 日历(访问用户的日历,以便将预约信息添加到日历中);</div>
<div>(9) 存储(访问设备存储器中的文件、照片和视频);</div>
<div>(10) 个人上网记录和日志信息(包括网站浏览记录、软件使用记录、点击记录、操作日志等);</div>
<div>(11) 设备信息(包括设备型号、设备MAC地址、操作系统类型、设备设置);</div>
<div>(12) 软件列表唯一设备识别码(如IMEI/android ID/IDFA/OPENUDID/GUID、SIM卡IMSI信息等在内的描述个人常用设备基本情况的信息);</div>
<div>(13) 拨打电话(唤起手机拨号界面并自动填充电话)</div>
<div>(14) 个人位置信息(包括精准定位信息、经纬度等);</div>
<div>(15) 其他平台基于为您提供服务需要而收集或汇总的您的信息。</div>
<div>三、我们如何收集和使用您的个人信息</div>
<div>1. 您直接提供的信息:我们可能会收集您在健康咨询员工端注册账号、申请或使用我们的服务时填写,通过现场交谈、电话、视频或其他联系方式与我们联系时所提供的信息,以及您在使用我们服务过程中产生的与您的交易和活动有关的信息。</div>
<div>(1) 帮助您成为我们的一员</div>
<div>您需要向平台提供真实姓名、邮箱、有效身份证件(包括但不限于身份证)的号码,以便于我们进行实名认证。您可以修改和补充您的昵称、性别、生日、职级、职称、学历、亲属、紧急联系人、工作信息(单位部门)、婚姻状况、健康类型、兴趣爱好以及您的实名认证等一系列相关信息相关信息,这些信息均属于您的“账号信息”。您补充的账户信息将有助于我们为您提供与您信息更匹配的相关业务服务(急救协助、医院体检、健康知识推送等)。如果您不提供这些信息,可能会影响您对平台部分核心业务功能的正常使用,如咨询专家等,但不会影响您进行基本的浏览、搜索。如果您不提供这些信息,将会影响您使用平台的部分功能,如咨询专家,但不会影响您使用平台服务的基本浏览、搜索功能。在您主动注销账号时,我们将根据相关法律法规的要求尽快使其匿名或删除您的个人信息。</div>
<div>(2) 咨询专家</div>
<div>为便于您能够咨询专家,您需提供真实姓名、手机号、身份证号码、性别、出生日期、身高体重等信息。为更好地向您提供咨询服务解决您的问题,更加精准、快速地向您推荐医生,我们可能需要您在健康咨询时提供个人健康信息,例如:病症、患病时长、检验报告、体检报告、医院就诊信息、诊治情况、用药记录、以往病史、过敏信息、家族史、患病史等。如您不提供上述信息,将会影响您使用部分健康咨询等功能,但不影响您使用平台产品或服务的基本浏览、搜索功能。应急救援</div>
<div>(1) 您实名成为健康咨询员工端的用户后,若您或您的朋友发生了意外事件,你可以通过查看系统内的相关医疗资源,并向平台发起帮助请求。在此过程中,我们可能会通过您的基本信息和聊天功能获取您的手机号、您的紧急联系人姓名和联系 电话,位置、姓名、性别、年龄、健康状况、事故详情介绍的图文、音视频沟通的信息。搜索</div>
<div>(2) 搜索</div>
<div>为了让您快速地找到您所需要的专家、知识文章、软件功能、医院等,我们可能会收集您使用我们的产品记录为您提供这些信息展示的最优方式。我们也会为了不断改进和优化上述的功能来使用您的上述个人信息。</div>
<div>您也可以通过搜索来精准地找到您所需要的专家、医院、系统功能。我们会保留您的搜索内容以方便您重复输入或为您展示与您搜索内容相关联的产品或服务。</div>
<div>2. 我们在您使用服务过程中收集的信息</div>
<div>为向您提供更契合您需求的页面展示和搜索结果、了解服务适配性、识别账号异常状态,我们会收集关于您使用的服务以及使用方式的信息并将这些信息进行关联,这些信息包括:</div>
<div>设备信息:我们会根据您在软件安装及使用中授予的具体权限,接收并记录您所使用的设备相关信息(例如设备型号、操作系统版本、设备设置、唯一设备标识符等软硬件特征信息)、设备所在位置相关信息(例如IP 地址、GPS位置以及能够提供相关信息的Wi-Fi 接入点、蓝牙和基站等传感器信息)。</div>
<div>日志信息:当您使用我们的网站或用户端提供的服务时,我们会自动收集您对我们服务的详细使用情况,作为有关网络日志保存。例如您的搜索查询内容、IP地址、浏览器的类型、电信运营商、使用的语言、访问日期和时间及您访问的网页记录等。</div>
<div>请注意,单独的设备信息、日志信息等是无法识别特定自然人身份的信息。如果我们将这类非个人信息与其他信息结合用于识别特定自然人身份,或者将其与个人信息结合使用,则在结合使用期间,这类非个人信息将被视为个人信息,除取得您授权或法律法规另有规定外,我们会将该类个人信息做匿名化、去标识化处理。</div>
<div>为展示您的健康信息,我们会收集您在使用我们服务过程中产生的健康咨询详情(包括但不限于图片、文字、视频、语音)、预约挂号记录、咨询记录、个人健康信息、检查检验、医生诊断结果等用于向您展示及便于您对信息进行管理。</div>
<div>当您与我们联系时,我们可能会保存您的通信/通话记录和内容或您留下的联系方式等信息,以便与您联系或帮助您解决问题,或记录相关问题的处理方案及结果。</div>
<div>3. 我们通过间接获得方式收集到的您的个人信息</div>
<div>我们可能从第三方获取您授权共享的账户信息(头像、昵称、联系方式),并在您同意声明和政策后将您的第三方账户与您的账户绑定,使您可以通过第三方账户直接登录并使用平台服务。我们会将依据与第三方的约定、对个人信息来源的合法性进行确认后,在符合相关法律和法规规定的前提下,使用您的这些个人信息。</div>
<div>如您拒绝提供上述信息或拒绝授权,可能无法使用我们的相应服务,或者无法展示相关信息,但不影响使用平台的健康咨询等核心服务。</div>
<div>为您提供安全保障</div>
<div>请注意,为向您提供更好的安全保障,您可以向我们提供姓名、身份证、就诊卡、邮箱等身份信息完成实名认证。如您拒绝提供上述信息,可能无法预约或咨询特定专家、继续可能存在风险的操作等,但不会影响您使用浏览、搜索等服务。</div>
<div>为提高您使用我们提供服务的安全性,更好地预防钓鱼网站、欺诈、网络漏洞、计算机病毒、网络攻击、网络侵入等安全风险,更准确地识别违反法律法规或平台相关协议规则的情况,我们可能使用或整合您的账户信息、交易信息、设备信息、有关网络日志以及我们取得您授权或依据法律共享的信息,来进行身份验证、检测及防范安全事件,并依法采取必要的记录、审计、分析、处置措施。</div>
<div>4. 其他用途</div>
<div>我们将信息用于本声明和政策未载明的其他用途,或者将基于特定目的收集而来的信息用于其他目的时,会事先征求您的同意。</div>
<div>5. 征得授权同意的例外</div>
<div>根据相关法律法规规定,以下情形中收集您的个人信息无需征得您的授权同意:</div>
<div>1、与国家安全、国防安全有关的;</div>
<div>2、与公共安全、公共卫生、重大公共利益有关的;</div>
<div>3、与犯罪侦查、起诉、审判和判决执行等有关的;</div>
<div>4、出于维护个人信息主体或其他个人的生命、财产等重大合法权益但又很难得到您本人同意的;</div>
<div>5、所收集的个人信息是您自行向社会公众公开的;</div>
<div>6、从合法公开披露的信息中收集个人信息的,如合法的新闻报道、政府信息公开等渠道;</div>
<div>7、根据您的要求签订合同所必需的;</div>
<div>8、用于维护所提供的产品或服务的安全稳定运行所必需的,例如发现、处置产品或服务的故障;</div>
<div>9、为合法的新闻报道所必需的;</div>
<div>10、学术研究机构基于公共利益开展统计或学术研究所必要,且对外提供学术研究或描述的结果时,对结果中所包含的个人信息进行去标识化处理的;</div>
<div>11、法律法规规定的其他情形。</div>
<div>如我们停止平台的产品或服务,我们将及时停止继续收集您个人信息的活动,对所持有的个人信息进行删除或匿名化处理。</div>
<div>6. 设备权限调用:在向您提供服务的过程中,为了实现特定的产品功能,我们会向您的设备系统申请调用以下设备权限,申请前我们会征询您的同意,您可以选择“允许”或者“禁止”权限申请。申请成功后,您可以随时进入手机“设置-权限管理”中关闭相应权限,不过权限关闭后有关产品功能可能无法正常使用,请您理解:</div>
<div>(1) 位置</div>
<div>您需要授权我们使用位置权限,以便于我们基于位置向您展示、推送急救资源,显示医院位置等信息。您在首次打开移动平台和使用相关业务时会看到弹窗提醒,询问您是否授权。</div>
<div>(2) 通讯录</div>
<div>在视话咨询时为保护医生和员工双方个人信息安全,我们提供中转电话服务。您需要授权我们使用通讯录权限,以便于我们对此电话进行标识。您在使用相应功能时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常在视话咨询中使用电话进行沟通。</div>
<div>(3) 相机、相册</div>
<div>您需要授权我们使用相机权限,以便于使用我们的核心业务功能,如在咨询中发送图片或视频通话。您在使用相应功能时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常在咨询中进行视频通话。</div>
<div>(4) 通知栏</div>
<div>您需要授权我们使用通知权限,以便于使用所有基于此权限实现的功能,如咨询状态、体检报告等各类消息提醒。您在首次打开移动平台时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常获取各类消息提醒。</div>
<div>(5) 存储</div>
<div>您需要授权我们使用存储权限,以便于在急救和咨询时候使用发送文件、图片、照片等功能,同时我们的移动平台可以写入、存储员工信息和日志等。您在首次打开移动平台和使用相应功能时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常使用使用移动平台。</div>
<div>(6) 麦克风</div>
<div>您需要授权我们使用麦克风权限,以便于使用我们的核心业务功能,如在咨询咨询中发送语音消息或视频通话。您在使用相应功能时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常在咨询中进行视频通话。</div>
<div>(7) 悬浮窗</div>
<div>您需要授权我们使用悬浮窗权限,当您在咨询/应急业务时正在进行语音/音视频通话时候您可切换APP继续使用手机其他功能。您在使用相应功能时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常在咨询中进行视频通话。</div>
<div>设备权限 使用目的</div>
<div>存储 聊天过程中发送和接收相关文件</div>
<div>相机 应急请求和咨询专家业务聊天过程中发送图片</div>
<div>相册 应急请求和咨询专家业务聊天过程中发送图片</div>
<div>位置 用于向用户提供地图上的资源数据,聊天发送位置</div>
<div>麦克风(音频) 与专家音视频交流、聊天语音输入,拍摄视频</div>
<div>悬浮窗 在其他程序页面仍能保持应用内通话</div>
<div>短信 获取验证码修改密码</div>
<div>通知栏 对您在系统内使用的业务(如预约体检、专家咨询),及时进行通知</div>
<div>拨打电话 在查看地图资源发起急救时候,跳转手机拨打电话</div>
<div>日历 找专家进行咨询、预约专家,大病就医挂号医院,预约去医院体检的日期需访问日历</div>
<div>请您注意,您开启以上权限即代表您授权我们可以收集和使用这些个人信息来实现上述的功能,您关闭权限即代表您取消了这些授权,则我们将不再继续收集和使用您的这些个人信息,也无法为您提供上述与这些授权所对应的功能。您关闭权限的决定不会影响此前基于您的授权所进行的个人信息的处理。除此以外,我们在相关业务功能中可能还需要您开启设备的其他访问权限,详细权限和使用目的如下:</div>
<div>1android.permission.INTERNET(访问网络权限):实现应用程序联网</div>
<div>2android.permission.ACCESS_WIFI_STATE(获取WiFi状态权限):监控网络变化,提示用户当前网络环境</div>
<div>3android.permission.ACCESS_NETWORK_STATE(获取网络状态权限):监控网络变化,提示用户当前网络环境</div>
<div>4android.permission.VIBRATE(使用振动权限):允许手机振动</div>
<div>5android.permission.WAKE_LOCK(唤醒锁定权限):允许程序在手机屏幕关闭后后台进程仍然运行,保持屏幕唤醒</div>
<div>6android.permission.RESTART_PACKAGES(结束系统任务权限):重新启动应用</div>
<div>7android.permission.MODIFY_AUDIO_SETTINGS(修改声音设置权限):修改全局音频设置,例如调节音量和用于输出的扬声器</div>
<div>8android.permission.BLUETOOTH(使用蓝牙权限):小程序蓝牙功能模块使用</div>
<div>9(android.permission.BLUETOOTH_ADMIN)(蓝牙管理权限):小程序蓝牙功能模块使用</div>
<div>10android.permission.SYSTEM_ALERT_WINDOW(悬浮窗权限):观看直播、短视频悬浮窗播放</div>
<div>11 android.permission.ACCESS_BACKGROUND_LOCATION(支持后台访问位置权限):保持持续定位能力</div>
<div>12android.permission.WRITE SYSTEM(读写系统设置权限):允许应用读写系统设置项</div>
<div>13android.permission.GET_TASKS(获取任务信息权限):允许应用获取当前或最近运行的应用</div>
<div>14android.permission.CHANGE_WIFI_STATE(改变WiFi状态权限):允许应用改变WiFi状态</div>
<div>15android.permission.CHANGE_NETWORK_STATE(改变网络连接状态):允许应用改变网络连接状态</div>
<div>四、我们如何使用 Cookie 和同类技术</div>
<div>1. 4.1 Cookie</div>
<div>为确保网站正常运转、为您获得更轻松的访问体验、向您推荐您可能感兴趣的内容,我们会在您的计算机或移动设备上存储名为 Cookie 的小数据文件。Cookie 通常包含标识符、站点名称以及一些号码和字符。借助于 Cookie,网站能够记住您的选择,提供个性化增强服务等。</div>
<div>您可根据自己的偏好管理或删除Cookie。有关详情,请参见 AboutCookies.org。您可以清除计算机上保存的所有 Cookie,大部分网络浏览器都设有阻止 Cookie 的功能。但如果您这么做,则需要在每一次访问平台时更改员工设置。如需详细了解如何更改浏览器设置,请访问您使用的浏览器的相关设置页面。</div>
<div>2. 4.2 网站信标和像素标签</div>
<div>除 Cookie 外,我们还会在网站上使用网站信标和像素标签等其他同类技术。例如,我们向您发送的电子邮件可能含有链接至我们网站内容的地址链接,如果您点击该链接,我们则会跟踪此次点击,帮助我们了解您的服务偏好以便于我们主动改善服务体验。网站信标通常是一种嵌入到网站或电子邮件中的透明图像。借助于电子邮件中的像素标签,我们能够获知电子邮件是否被打开。</div>
<div>五、我们如何共享、转让、公开披露您的个人信息</div>
<div>1. 共享</div>
<div>我们不会与平台服务提供者以外的任何公司、组织和个人分享您的个人信息,但以下情况除外:</div>
<div>1、在获取明确同意的情况下共享:获得您的明确同意后,我们会与其他方共享您的个人信息。</div>
<div>2、我们可能会根据法律法规规定,或按政府主管部门的强制性要求,对外共享您的个人信息。</div>
<div>3、与授权合作机构共享:仅为实现本声明和政策中声明的目的,我们的某些服务将由授权合作机构提供。我们可能会与合作机构共享您的某些个人信息,以提供更好的服务和员工体验。我们仅会出于合法、正当、必要、特定、明确的目的共享您的个人信息,并且只会共享提供服务所必要的个人信息。我们的合作机构无权将共享的个人信息用于任何其他用途。</div>
<div>目前,我们的授权合作机构包括以下类型:</div>
<div>(1)分析服务类的授权合作机构。除非得到您的许可,否则我们不会将您的个人身份信息(指可以识别您身份的信息,例如姓名或电子邮箱,通过这些信息可以联系到您或识别您的身份)与提供分析服务的合作机构分享。我们会向这些合作机构提供有关其服务覆盖面和有效性的信息,而不会提供您的个人身份信息,或者我们将这些信息进行汇总,以便它不会识别您。</div>
<div>(2)服务提供方和其他合作机构。我们将信息发送给支持我们业务的服务提供方和其他合作机构,这些支持包括提供技术基础设施服务、分析我们服务的使用方式、衡量服务的有效性、提供员工服务、支付便利或进行学术研究和调查。</div>
<div>对我们与之共享个人信息的机构,我们会与其签署严格的保密协定,要求他们按照我们的说明、声明和政策以及其他任何相关的保密和安全措施来处理个人信息。</div>
<div>2. .转让</div>
<div>除以下情形外,我们不会将您的个人信息转让给任何公司、组织或个人:</div>
<div>1)事先获得您的明确同意的;</div>
<div>(2)根据法律法规规定,或者政府主管部门、司法机关的强制要求必须对外转让的;</div>
<div>(3)涉及公司合并、分立、解散、资产或业务转让、破产清算或类似的交易时,若涉及到您的个人信息转让,我们会要求新持有您个人信息的公司、组织或个人继续受本政策的约束,否则我们将要求该等公司、组织或个人重新取得您的授权同意。</div>
<div>3. 公开披露</div>
<div>除以下情形外,我们不会公开披露您的个人信息:</div>
<div>1)事先获得您的明确同意的;</div>
<div>(2)根据法律法规规定,或者政府主管部门、司法机关的强制要求必须公开披露的。在符合法律法规的前提下,当我们收到上述披露信息的请求时,我们会要求必须出具与之相应的法律文件,如传票或调查函。我们坚信,对于要求我们提供的信息,应该在法律允许的范围内尽可能保持透明。我们对所有的请求都将进行慎重的审查,以确保其具备合法依据,且仅限于执法部门因特定调查目的且有合法权利获取的数据。</div>
<div>4. 共享、转让、公开披露个人信息授权同意的例外</div>
<div>根据相关法律法规的规定,在以下情形中,我们可以在不征得您的授权同意的情况下共享、转让、公开披露您的个人信息:</div>
<div>A.与国家安全、国防安全有关的;</div>
<div>B.与公共安全、公共卫生、重大公共利益有关的;C.与犯罪侦查、起诉、审判和判决执行等有关的;</div>
<div>D.出于维护您或其他个人的生命、财产等重大合法权益但又很难得到本人同意的;</div>
<div>E.您自行向社会公众公开的个人信息;</div>
<div>F.从合法公开披露的信息中收集到的个人信息的,如合法的新闻报道、政府信息公开等渠道。</div>
<div>G.法律法规规定的其他情形。</div>
<div>根据法律规定,共享、转让经去标识化处理的个人信息,且确保数据接收方无法复原并重新识别个人信息主体的,不属于个人信息的对外共享、转让及公开披露行为,对此类数据的保存及处理将无需另行向您通知并征得您的同意。</div>
<div>六、员工业务数据和公开信息</div>
<div>不同于您的个人信息,对于员工业务数据和公开信息,平台将按如下方式处理:</div>
<div>1. 员工业务数据</div>
<div>1、您通过平台提供的服务,加工、存储、上传、下载、分发以及通过其他方式处理的数据,均为您的员工业务数据。平台作为服务提供者,只会严格执行您的指示处理您的业务数据,除按与您协商一致或执行明确的法律法规要求外,不对您的业务数据进行任何非授权的使用或披露。</div>
<div>2、您应对您的员工业务数据来源及内容负责,平台提示您谨慎判断数据来源及内容的合法性。因您的员工业务数据内容违反法律法规、部门规章或国家政策而造成的全部结果及责任均由您自行承担。</div>
<div>3、根据您与平台协商一致,平台在您选定的数据中心存储员工业务数据。我们恪守对员工的安全承诺,根据适用的法律保护员工存储在平台数据中心的数据。</div>
<div>2. 公开信息</div>
<div>1、公开信息是指您公开分享的任何信息,任何人都可以在使用和未使用平台服务期间查看或访问这些信息。例如您在社区、论坛发布的信息。</div>
<div>2、为使用平台的服务,可能存在您必须公开分享的信息。</div>
<div>七、我们如何保护您的个人信息</div>
<div>1.我们已使用符合业界标准的安全防护措施保护您提供的个人信息,防止您的个人信息遭到未经授权访问、使用、修改、公开披露、损坏或丢失。我们会采取一切合理可行的措施,保护您的个人信息,比如:</div>
<div>(1)我们设立了网络安全和个人信息保护机构,专门负责网络安全和个人信息保护事务;</div>
<div>(2)我们的网络服务采取了传输层安全协议等加密技术,通过https等方式提供浏览服务,确保用户数据在传输过程中的安全;</div>
<div>(3)我们采取MD5、SHA256等加密技术对您的个人信息进行加密存储,增强个人信息在使用中的安全性;</div>
<div>(4)我们采用严格的数据访问权限控制和多重身份认证技术保护个人信息,避免数据被违规使用;</div>
<div>(5)我们采用代码安全检查、数据访问日志分析技术进行个人信息安全审计;</div>
<div>(6)我们建立了客户信息保护管理规定、客户信息分级分类管理规定、日常操作规程等一系列管理制度来规范个人信息的存储和使用;</div>
<div>(7)我们定期举办信息安全和个人信息保护培训课程,加强员工对于个人信息保护重要性的认识;</div>
<div>(8)我们与所有可能接触个人信息的员工签订了保密协议,对关键岗位人员进行背景审查,并建立了严格的访问权限控制、权限审批流程和监控、审计机制;</div>
<div>(9)我们与所有可能接触用户个人信息的合作伙伴均签署了严格的保密协议或数据保护专用条款,并要求可能接触到您个人信息的所有人员履行相应的保密和数据保护义务。如果第三方合作伙伴未履行保密和数据保护义务,可能会被我们追究法律责任并被我们终止合作;</div>
<div>2.我们已经通过了国家信息安全等级保护测评和备案,最高备案等级为二级。</div>
<div>3.我们会采取一切合理可行的措施,确保未收集无关的个人信息。我们只会在达成本政策所述目的所需的期限内保留您的个人信息,除非需要延长保留期或者受到法律允许。</div>
<div>4.互联网并非绝对安全的环境,而且电子邮件、即时通讯、社交软件等与其他用户的交流方式无法确定是否完全加密,我们强烈建议您不用通过此类方式发送个人信息。若确需使用,在使用此类工具时请使用复杂密码,并注意保护您的个人信息安全。我们将尽力保障您个人信息的安全性。如果我们的物理、技术、或管理防护设施遭到破坏,导致信息被非授权访问、公开披露、篡改、或毁坏,导致您的合法权益受损,我们将全力配合保护您的权益,并依法承担我们应承担的赔偿责任。</div>
<div>5.在不幸发生个人信息安全事件后,我们将按照法律法规的要求及时向您告知安全事件的基本情况和可能的影响、我们已采取或将采取的处置措施、您可自主防范和降低风险的建议、对您的补救措施等。我们将及时将事件相关情况以邮件、信函、电话、推送通知等方式告知您,难以逐一告知时,我们会采取合理、有效的方式发布公告。同时,我们还将按照监管部门要求,主动上报个人信息安全事件的处置情况。</div>
<div>八、您如何管理您的个人信息(您的权力)</div>
<div>您可以通过以下方式访问及管理您的个人信息:</div>
<div>8.1 访问您的个人信息</div>
<div>您的账号信息:您可在“我的”中查询您的账户、姓名、性别、手机、身份证号、工作信息、健康类型、学历、工号、工种、住址,紧急联系人的姓名、电话等。</div>
<div>您和您亲属的健康信息:您可在“咨询人管理”中查询您和您亲属手机号码、患者姓名、性别、出生日期、与患者的关系、身高体重、所在城市;健康信息:病症、患病时长、体检报告、住院记录、诊治情况、用药记录、以往病史、过敏信息、家族史、患病史等健康信息。</div>
<div>您的订单、工单信息:您可在“我的-我的咨询”、“我的-我的应急工单”、“我的-大病就医工单”、“健康体检-体检预约”等各个业务的对应入口查看、评价订单和工单信息。</div>
<div>您的体检报告:你可在“健康体检-体检报告”和“健康档案-健康现状”、“健康档案-体检数据分析”查看个人的体检报告详情和重点指标的分析。</div>
<div>对于您在使用我们的产品或服务过程中向我们提供或产生的其他信息,只要我们不需要过多投入,我们会向您提供。您可以通过拨打我们的客服电话提出访问申请,我们将在30天内回复您的访问请求。</div>
<div>对于您在使用我们服务过程中产生的其他个人信息,我们将根据本条“8.9 响应您的上述请求”中的相关安排向您提供。</div>
<div>8.2 更正或补充您的个人信息</div>
<div>当您发现我们处理的您的个人信息有误或者您需要更正该等信息时,您可以通过内设置的自动更正功能、电子邮件或者拨打客服电话等方式进行修改或更正。您如果需要更正其他个人信息,可通过联系人工客服向我们提出更正申请。</div>
<div>可自主更正的信息:</div>
<div>账号信息:您可在“我的”中更新您的头像,紧急联系人的姓名、电话等。</div>
<div>您和您亲属的健康信息:您可在“咨询人管理”中更正您和您亲属手机号码、患者姓名、性别、出生日期、与患者的关系、身高体重、所在城市;健康信息:病症、患病时长、体检报告、住院记录、诊治情况、用药记录、以往病史、过敏信息、家族史、患病史等健康信息。</div>
<div>8.3 如何注销</div>
<div>您在我们的产品与/或服务页面中可以直接清除或删除的信息,包括浏览信息、紧急联系人信息、咨询人信息。</div>
<div>在以下情形中,您可以向我们提出删除个人信息的请求:</div>
<div>(1)如果我们处理个人信息的行为违反了法律法规的强制性规定;</div>
<div>(2)如果我们收集、使用您的个人信息,却未征得您的同意(依法无需征得同意的情况除外);</div>
<div>(3)如果我们处理个人信息的行为违反了与您的约定;</div>
<div>(4)如果您不再使用我们的产品或服务,或您注销了账号;</div>
<div>5)如果我们不再为您提供产品或服务。</div>
<div>如果您想删除或注册账号:</div>
<div>(1)拨打客服热线电话029-86618899</div>
<div>2)发送电子邮件至40115111@qq.com</div>
<div>(3)邮寄地址:陕西省西安市未央区欧亚大道丝路国际创意梦工场5号楼,收件人:许策</div>
<div>收到您的删除请求后,我们会根据您及相关法律法规的要求进行后续删除处理并向您反馈结果。若我们决定响应您的删除请求,我们还将同时通知从我们获得您的个人信息的实体,要求其及时删除,除非法律法规另有规定,或这些实体获得您的独立授权。</div>
<div>当您从我们的服务中删除信息后,我们可能不会立即备份系统中删除相应的信息,但会在备份更新时删除这些信息。</div>
<div>8.4 改变您授权同意的范围</div>
<div>您可以通过删除信息、关闭设备功能、在平台中进行隐私设置等方式改变您授权我们继续收集个人信息的范围或撤回您的授权。</div>
<div>请您理解,每个业务功能需要一些基本的个人信息才能得以完成(见本隐私权政策“我们如何收集和使用您的信息”)。当您收回同意后,我们将不再处理相应的个人信息。但您收回同意的决定,不会影响此前基于您的授权而开展的个人信息处理。</div>
<div>8.5 个人信息主体注销账户</div>
<div>在符合平台单项服务的服务协议约定条件及国家相关法律法规规定的情况下,您的该项平台服务帐号可能被注销或删除。当帐号注销或被删除后,与该帐号相关的、该单项服务项下的全部服务资料和数据将依照单项服务的服务协议约定删除或匿名化处理。</div>
<div>8.6 约束信息系统自动决策</div>
<div>在某些业务功能中,我们可能仅依据信息系统、算法等在内的非人工自动决策机制做出决定。如果这些决定显著影响您的合法权益,您有权要求我们做出解释,我们也将在不侵害平台保密或其他员工权益、社会公共利益的前提下提供申诉方法。</div>
<div>8.7约束信息系统自动决策</div>
<div>在某些业务功能中,我们可能仅依据信息系统、算法在内的非人工自动决策机制作出决定。如果这些决定显著影响您的合法权益,您有权要求我们作出解释,我们也将提供适当的救济方式。</div>
<div>8.8举报和投诉</div>
<div>如果您发现您的个人信息可能被泄露,或者我们的工作人员或合作伙伴在处理您的个人信息时有任何违法违规行为,您可以通过拨打客服热线或者发送电子邮件的方式向我们进行举报和投诉。</div>
<div>8.9 响应您的上述请求</div>
<div>为保障安全,您可能需要提供书面请求,或以其他方式证明您的身份。我们可能会先要求您验证自己的身份,然后再处理您的请求。我们将在15个工作日内做出答复。</div>
<div>对于那些无端重复、需要过多技术手段(例如,需要开发新系统或从根本上改变现行惯例)、给他人合法权益带来风险或者非常不切实际的请求,我们可能会予以拒绝。</div>
<div>在以下情形中,按照法律法规要求,我们将无法响应您的请求:</div>
<div>(1) 与国家安全、国防安全有关的;</div>
<div>(2) 与公共安全、公共卫生、重大公共利益有关的;</div>
<div>(3) 与犯罪侦查、起诉、审判和执行判决等有关的;</div>
<div>(4) 有充分证据表明个人信息主体存在主观恶意或滥用权利的;</div>
<div>(5) 响应您的请求将导致您或其他个人、组织的合法权益受到严重损害的;</div>
<div>(6) 涉及商业秘密的。</div>
<div>九、我们如何处理未成年人的个人信息</div>
<div>1.健康咨询员工端非常重视对未成年人个人信息的保护。若您是18周岁以下的未成年人,在使用我们的产品与/或服务前,应事先取得您监护人的同意。健康咨询员工端根据国家相关法律法规的规定保护未成年人的个人信息。</div>
<div>2.我们不会主动直接向未成年人收集其个人信息。对于经监护人同意而收集未成年人个人信息的情况,我们只会在受到法律允许、监护人同意或者保护未成年人所必要的情况下使用、共享、转让或披露此信息。</div>
<div>3.如果有事实证明未成年人在未取得监护人同意的情况下注册使用了我们的产品与/或服务,我们会与相关监护人协商,并设法尽快删除相关个人信息。</div>
<div>十、本声明和政策如何更新</div>
<div>我们的隐私政策可能变更。未经您明确同意,我们不会削减您按照声明和政策所应享有的权利。 我们会在本页面上发布对本声明和政策所做的任何变更。</div>
<div>对于重大变更,我们还会提供更为显著的通知(包括我们会通过网站公示的方式进行通知甚至向您提供弹窗提示)。</div>
<div>本声明和隐私所指的重大变更包括但不限于:</div>
<div>1、 我们的服务模式发生重大变化。如处理个人信息的目的、处理的个人信息类型、个人信息的使用方式等;</div>
<div>2、 我们在所有权结构、组织架构等方面发生重大变化。如业务调整等引起的所有者变更等;</div>
<div>3、 个人信息共享或公开披露的主要对象发生变化;</div>
<div>4、 您参与个人信息处理方面的权利及其行使方式发生重大变化;</div>
<div>5、 我们负责处理个人信息安全的责任部门、联络方式等发生变化时;</div>
<div>6、 个人信息安全影响评估报告表明存在高风险时。</div>
<div>7、 我们还会将本声明和隐私的旧版本存档,供您查阅。</div>
<div>十一、如何联系我们</div>
<div>1.如果您对本政策有任何疑问、意见或建议,可通过以下方式与我们联系:</div>
<div>(1)拨打客服热线电话029-86618899</div>
<div>2)发送电子邮件至40115111@qq.com</div>
<div>(3)邮寄地址:陕西省西安市未央区欧亚大道丝路国际创意梦工场5号楼,收件人:许策</div>
<div>我们的客服部门将会同个人信息保护部门30天内进行回复,并协助解决您的问题。</div>
<div>2.如果您对我们的回复不满意,特别是我们的个人信息处理行为损害了您的合法权益,您还可以通过以下外部途径寻求解决方式:向网信、工商、公安等监管部门进行投诉或举报。</div>
</div>
</body>
</html>
-300
View File
@@ -1,300 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>隐私权政策</title>
</head>
<style>
html,body {
padding: 0;
margin: 0;
}
html,body,#zwb{
box-sizing: border-box;
overflow: hidden auto;
font-size: 22px;
}
html::-webkit-scrollbar {
width: 0;
}
body::-webkit-scrollbar {
width: 0;
}
#zwb {
padding: 25px;
width: 100%;
height: 100%;
overflow: hidden auto;
}
div {
margin: 0 0 10px;
}
.title-one {
text-align: center;
margin: 5px 0
}
</style>
<body>
<div id="zwb">
<h3 class="title-one">隐私权政策</h3>
<div>本平台由西安恒烨通企业管理咨询有限公司开发和运维,平台深知个人信息对您的重要性,并会尽全力保护您的个人信息安全可靠。我们致力于维持您对我们的信任,恪守以下原则,保护您的个人信息:权责一致原则、目的明确原则、选择同意原则、最少够用原则、确保安全原则、主体参与原则、公开透明原则等。同时,我们承诺将采取相应的安全保护措施来保护您的个人信息。请在使用平台服务前,仔细阅读并了解本隐私权政策,我们将按照本政策收集、处理及披露您的信息。</div>
<div>本政策将帮助您了解以下内容:</div>
<div>1、定义</div>
<div>2、我们可能收集的信息</div>
<div>3、我们如何收集和使用您的个人信息</div>
<div>4、我们如何使用 Cookie 和同类技术</div>
<div>5、我们如何共享、转让、公开披露您的个人信息</div>
<div>6、员工业务数据和公开信息</div>
<div>7、我们如何保护您的个人信息</div>
<div>8、您如何管理您的个人信息</div>
<div>9、我们如何处理未成年人的个人信息</div>
<div>10、本声明和政策如何更新</div>
<div>11、如何联系我们</div>
<div>一、定义</div>
<div>1. 个人信息:</div>
<div>指以电子或者其他方式记录的与已识别或者可识别的自然人有关的各种信息,不包括匿名化处理后的信息</div>
<div>2. 个人健康信息</div>
<div>指以电子或者其他方式记录的能够单独或者与其他信息结合识别特定自然人身份或者反映特定自然人活动情况的各种健康信息,一旦泄露或者非法使用,可能导致个人受到歧视或者人身、财产受到严重危害的个人信息,包括如姓名、出生日期、身份证件号码、体检信息、就医信息、住址、通讯联系方式、通信记录和内容、账号密码、行踪轨迹、民族、个人生物特征、医疗健康、金融账户、个人行踪、不满十四周岁未成年人信息等。</div>
<div>3. 未成年人:指不满18周岁的自然人。</div>
<div>4. 儿童:指不满14周岁的自然人。</div>
<div>5. 设备信息</div>
<div>包括设备标识符 (IMEI、IDFA、MAC、OAID、IMSI、SIM 卡序列号 (ICCID) 、设备序列号及其他设备相关信息),应用信息 (应用崩溃信息、通知开关状态、运行中进程、应用安装列表及其他应用相关信息) ,设备参数及系统信息(设备类型、设备型号、操作系统及硬件相关信息),设备网络环境信息 (IP地址,WiFi信息,基站信息及其他网络相关信息),蓝牙信息,广播组件通讯信息,运营商信息,传感器 (陀螺仪、重力传感器、加速度传感器、环境传感器、光学心率传感器),剪切板。以产品实际采集情况为准。</div>
<div>6. 业务数据</div>
<div>不同于个人信息,是指平台员工利用平台的服务上传、下载、分发等通过平台的技术服务处理的数据。</div>
<div>二、我们可能收集的信息</div>
<div>我们提供服务时,可能会收集、储存和使用下列与个人有关的信息。如果您不提供相关信息,可能无法注册成为平台员工或无法享受平台的某些服务,或者无法达到相关服务拟达到的效果。</div>
<div>2.1 与个人身份无关</div>
<div>当您使用平台的服务时,我们可能收集和汇总诸如员工的来源途径、访问顺序、停留时间等信息,例如记录使用平台服务的每个员工的来源途径、浏览器软件等。</div>
<div>2.2 与个人身份有关</div>
<div>当您使用平台的服务时,我们可能收集和汇总或要求您提供有关个人身份的信息,例如:</div>
<div>(1) 个人身份证明(包括身份证图片和身份证号、手机号、邮箱等);</div>
<div>(2) 个人补充信息(姓名、生日、籍贯、性别、兴趣爱好、学历、个人联系电话、住址、工作信息、婚姻状况、健康状况、;</div>
<div>(3) 网络身份标识信息(包括系统账号、IP地址、电子邮箱地址及与前述有关的密码、口令、口令保护答案、个人数字证书等);</div>
<div>(4) 个人健康信息(包括:姓名、性别、出生日期、身高体重、就诊卡、所在城市,所患病症、患病时长、体检报告、住院记录、诊治情况、检验报告、体检报告、用药记录、以往病史、过敏信息、家族史、患病史等,和历史咨询记录。</div>
<div>(5) 相机、相册(设备的相机功能,以拍摄照片或录制视频);</div>
<div>(6) 麦克风(通话、发送录音文件);</div>
<div>(7) 悬浮窗(在其他程序页面仍能保持应用内通话);</div>
<div>(8) 日历(访问用户的日历,以便将预约信息添加到日历中);</div>
<div>(9) 存储(访问设备存储器中的文件、照片和视频);</div>
<div>(10) 个人上网记录和日志信息(包括网站浏览记录、软件使用记录、点击记录、操作日志等);</div>
<div>(11) 设备信息(包括设备型号、设备MAC地址、操作系统类型、设备设置);</div>
<div>(12) 软件列表唯一设备识别码(如IMEI ID/IDFA/OPENUDID/GUID、SIM卡IMSI信息等在内的描述个人常用设备基本情况的信息);</div>
<div>(13) 拨打电话(唤起手机拨号界面并自动填充电话)</div>
<div>(14) 个人位置信息(包括精准定位信息、经纬度等);</div>
<div>(15) 其他平台基于为您提供服务需要而收集或汇总的您的信息。</div>
<div>三、我们如何收集和使用您的个人信息</div>
<div>1. 您直接提供的信息:我们可能会收集您在健康咨询员工端注册账号、申请或使用我们的服务时填写,通过现场交谈、电话、视频或其他联系方式与我们联系时所提供的信息,以及您在使用我们服务过程中产生的与您的交易和活动有关的信息。</div>
<div>(1) 帮助您成为我们的一员</div>
<div>您需要向平台提供真实姓名、邮箱、有效身份证件(包括但不限于身份证)的号码,以便于我们进行实名认证。您可以修改和补充您的昵称、性别、生日、职级、职称、学历、亲属、紧急联系人、工作信息(单位部门)、婚姻状况、健康类型、兴趣爱好以及您的实名认证等一系列相关信息相关信息,这些信息均属于您的“账号信息”。您补充的账户信息将有助于我们为您提供与您信息更匹配的相关业务服务(急救协助、医院体检、健康知识推送等)。如果您不提供这些信息,可能会影响您对平台部分核心业务功能的正常使用,如咨询专家等,但不会影响您进行基本的浏览、搜索。如果您不提供这些信息,将会影响您使用平台的部分功能,如咨询专家,但不会影响您使用平台服务的基本浏览、搜索功能。在您主动注销账号时,我们将根据相关法律法规的要求尽快使其匿名或删除您的个人信息。</div>
<div>(2) 咨询专家</div>
<div>为便于您能够咨询专家,您需提供真实姓名、手机号、身份证号码、性别、出生日期、身高体重等信息。为更好地向您提供咨询服务解决您的问题,更加精准、快速地向您推荐医生,我们可能需要您在健康咨询时提供个人健康信息,例如:病症、患病时长、检验报告、体检报告、医院就诊信息、诊治情况、用药记录、以往病史、过敏信息、家族史、患病史等。如您不提供上述信息,将会影响您使用部分健康咨询等功能,但不影响您使用平台产品或服务的基本浏览、搜索功能。应急救援</div>
<div>(1) 您实名成为健康咨询员工端的用户后,若您或您的朋友发生了意外事件,你可以通过查看系统内的相关医疗资源,并向平台发起帮助请求。在此过程中,我们可能会通过您的基本信息和聊天功能获取您的手机号、您的紧急联系人姓名和联系 电话,位置、姓名、性别、年龄、健康状况、事故详情介绍的图文、音视频沟通的信息。搜索</div>
<div>(2) 搜索</div>
<div>为了让您快速地找到您所需要的专家、知识文章、软件功能、医院等,我们可能会收集您使用我们的产品记录为您提供这些信息展示的最优方式。我们也会为了不断改进和优化上述的功能来使用您的上述个人信息。</div>
<div>您也可以通过搜索来精准地找到您所需要的专家、医院、系统功能。我们会保留您的搜索内容以方便您重复输入或为您展示与您搜索内容相关联的产品或服务。</div>
<div>2. 我们在您使用服务过程中收集的信息</div>
<div>为向您提供更契合您需求的页面展示和搜索结果、了解服务适配性、识别账号异常状态,我们会收集关于您使用的服务以及使用方式的信息并将这些信息进行关联,这些信息包括:</div>
<div>设备信息:我们会根据您在软件安装及使用中授予的具体权限,接收并记录您所使用的设备相关信息(例如设备型号、操作系统版本、设备设置、唯一设备标识符等软硬件特征信息)、设备所在位置相关信息(例如IP 地址、GPS位置以及能够提供相关信息的Wi-Fi 接入点、蓝牙和基站等传感器信息)。</div>
<div>日志信息:当您使用我们的网站或用户端提供的服务时,我们会自动收集您对我们服务的详细使用情况,作为有关网络日志保存。例如您的搜索查询内容、IP地址、浏览器的类型、电信运营商、使用的语言、访问日期和时间及您访问的网页记录等。</div>
<div>请注意,单独的设备信息、日志信息等是无法识别特定自然人身份的信息。如果我们将这类非个人信息与其他信息结合用于识别特定自然人身份,或者将其与个人信息结合使用,则在结合使用期间,这类非个人信息将被视为个人信息,除取得您授权或法律法规另有规定外,我们会将该类个人信息做匿名化、去标识化处理。</div>
<div>为展示您的健康信息,我们会收集您在使用我们服务过程中产生的健康咨询详情(包括但不限于图片、文字、视频、语音)、预约挂号记录、咨询记录、个人健康信息、检查检验、医生诊断结果等用于向您展示及便于您对信息进行管理。</div>
<div>当您与我们联系时,我们可能会保存您的通信/通话记录和内容或您留下的联系方式等信息,以便与您联系或帮助您解决问题,或记录相关问题的处理方案及结果。</div>
<div>3. 我们通过间接获得方式收集到的您的个人信息</div>
<div>我们可能从第三方获取您授权共享的账户信息(头像、昵称、联系方式),并在您同意声明和政策后将您的第三方账户与您的账户绑定,使您可以通过第三方账户直接登录并使用平台服务。我们会将依据与第三方的约定、对个人信息来源的合法性进行确认后,在符合相关法律和法规规定的前提下,使用您的这些个人信息。</div>
<div>如您拒绝提供上述信息或拒绝授权,可能无法使用我们的相应服务,或者无法展示相关信息,但不影响使用平台的健康咨询等核心服务。</div>
<div>为您提供安全保障</div>
<div>请注意,为向您提供更好的安全保障,您可以向我们提供姓名、身份证、就诊卡、邮箱等身份信息完成实名认证。如您拒绝提供上述信息,可能无法预约或咨询特定专家、继续可能存在风险的操作等,但不会影响您使用浏览、搜索等服务。</div>
<div>为提高您使用我们提供服务的安全性,更好地预防钓鱼网站、欺诈、网络漏洞、计算机病毒、网络攻击、网络侵入等安全风险,更准确地识别违反法律法规或平台相关协议规则的情况,我们可能使用或整合您的账户信息、交易信息、设备信息、有关网络日志以及我们取得您授权或依据法律共享的信息,来进行身份验证、检测及防范安全事件,并依法采取必要的记录、审计、分析、处置措施。</div>
<div>4. 其他用途</div>
<div>我们将信息用于本声明和政策未载明的其他用途,或者将基于特定目的收集而来的信息用于其他目的时,会事先征求您的同意。</div>
<div>5. 征得授权同意的例外</div>
<div>根据相关法律法规规定,以下情形中收集您的个人信息无需征得您的授权同意:</div>
<div>1、与国家安全、国防安全有关的;</div>
<div>2、与公共安全、公共卫生、重大公共利益有关的;</div>
<div>3、与犯罪侦查、起诉、审判和判决执行等有关的;</div>
<div>4、出于维护个人信息主体或其他个人的生命、财产等重大合法权益但又很难得到您本人同意的;</div>
<div>5、所收集的个人信息是您自行向社会公众公开的;</div>
<div>6、从合法公开披露的信息中收集个人信息的,如合法的新闻报道、政府信息公开等渠道;</div>
<div>7、根据您的要求签订合同所必需的;</div>
<div>8、用于维护所提供的产品或服务的安全稳定运行所必需的,例如发现、处置产品或服务的故障;</div>
<div>9、为合法的新闻报道所必需的;</div>
<div>10、学术研究机构基于公共利益开展统计或学术研究所必要,且对外提供学术研究或描述的结果时,对结果中所包含的个人信息进行去标识化处理的;</div>
<div>11、法律法规规定的其他情形。</div>
<div>如我们停止平台的产品或服务,我们将及时停止继续收集您个人信息的活动,对所持有的个人信息进行删除或匿名化处理。</div>
<div>6. 设备权限调用:在向您提供服务的过程中,为了实现特定的产品功能,我们会向您的设备系统申请调用以下设备权限,申请前我们会征询您的同意,您可以选择“允许”或者“禁止”权限申请。申请成功后,您可以随时进入手机“设置-权限管理”中关闭相应权限,不过权限关闭后有关产品功能可能无法正常使用,请您理解:</div>
<div>(1) 位置</div>
<div>您需要授权我们使用位置权限,以便于我们基于位置向您展示、推送急救资源,显示医院位置等信息。您在首次打开移动平台和使用相关业务时会看到弹窗提醒,询问您是否授权。</div>
<div>(2) 通讯录</div>
<div>在视话咨询时为保护医生和员工双方个人信息安全,我们提供中转电话服务。您需要授权我们使用通讯录权限,以便于我们对此电话进行标识。您在使用相应功能时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常在视话咨询中使用电话进行沟通。</div>
<div>(3) 相机、相册</div>
<div>您需要授权我们使用相机权限,以便于使用我们的核心业务功能,如在咨询中发送图片或视频通话。您在使用相应功能时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常在咨询中进行视频通话。</div>
<div>(4) 通知栏</div>
<div>您需要授权我们使用通知权限,以便于使用所有基于此权限实现的功能,如咨询状态、体检报告等各类消息提醒。您在首次打开移动平台时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常获取各类消息提醒。</div>
<div>(5) 存储</div>
<div>您需要授权我们使用存储权限,以便于在急救和咨询时候使用发送文件、图片、照片等功能,同时我们的移动平台可以写入、存储员工信息和日志等。您在首次打开移动平台和使用相应功能时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常使用使用移动平台。</div>
<div>(6) 麦克风</div>
<div>您需要授权我们使用麦克风权限,以便于使用我们的核心业务功能,如在咨询咨询中发送语音消息或视频通话。您在使用相应功能时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常在咨询中进行视频通话。</div>
<div>(7) 悬浮窗</div>
<div>您需要授权我们使用悬浮窗权限,当您在咨询/应急业务时正在进行语音/音视频通话时候您可切换APP继续使用手机其他功能。您在使用相应功能时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常在咨询中进行视频通话。</div>
<div>设备权限 使用目的</div>
<div>存储 聊天过程中发送和接收相关文件</div>
<div>相机 应急请求和咨询专家业务聊天过程中发送图片</div>
<div>相册 应急请求和咨询专家业务聊天过程中发送图片</div>
<div>位置 用于向用户提供地图上的资源数据,聊天发送位置</div>
<div>麦克风(音频) 与专家音视频交流、聊天语音输入,拍摄视频</div>
<div>悬浮窗 在其他程序页面仍能保持应用内通话</div>
<div>短信 获取验证码修改密码</div>
<div>通知栏 对您在系统内使用的业务(如预约体检、专家咨询),及时进行通知</div>
<div>拨打电话 在查看地图资源发起急救时候,跳转手机拨打电话</div>
<div>日历 找专家进行咨询、预约专家,大病就医挂号医院,预约去医院体检的日期需访问日历</div>
<div>请您注意,您开启以上权限即代表您授权我们可以收集和使用这些个人信息来实现上述的功能,您关闭权限即代表您取消了这些授权,则我们将不再继续收集和使用您的这些个人信息,也无法为您提供上述与这些授权所对应的功能。您关闭权限的决定不会影响此前基于您的授权所进行的个人信息的处理。除此以外,我们在相关业务功能中可能还需要您开启设备的其他访问权限,详细权限和使用目的如下:</div>
<div>1)访问网络权限:实现应用程序联网</div>
<div>(2)获取WiFi状态权限:监控网络变化,提示用户当前网络环境</div>
<div>(3)获取网络状态权限:监控网络变化,提示用户当前网络环境</div>
<div>4)使用振动权限:允许手机振动</div>
<div>(5)唤醒锁定权限:允许程序在手机屏幕关闭后后台进程仍然运行,保持屏幕唤醒</div>
<div>6)结束系统任务权限:重新启动应用</div>
<div>(7)修改声音设置权限:修改全局音频设置,例如调节音量和用于输出的扬声器</div>
<div>(8)使用蓝牙权限:小程序蓝牙功能模块使用</div>
<div>(9)蓝牙管理权限:小程序蓝牙功能模块使用</div>
<div>(10)悬浮窗权限:观看直播、短视频悬浮窗播放</div>
<div>(11)支持后台访问位置权限:保持持续定位能力</div>
<div>(12)读写系统设置权限:允许应用读写系统设置项</div>
<div>(13)获取任务信息权限:允许应用获取当前或最近运行的应用</div>
<div>(14)改变WiFi状态权限:允许应用改变WiFi状态</div>
<div>(15)改变网络连接状态:允许应用改变网络连接状态</div>
<div>四、我们如何使用 Cookie 和同类技术</div>
<div>1. 4.1 Cookie</div>
<div>为确保网站正常运转、为您获得更轻松的访问体验、向您推荐您可能感兴趣的内容,我们会在您的计算机或移动设备上存储名为 Cookie 的小数据文件。Cookie 通常包含标识符、站点名称以及一些号码和字符。借助于 Cookie,网站能够记住您的选择,提供个性化增强服务等。</div>
<div>您可根据自己的偏好管理或删除Cookie。有关详情,请参见 AboutCookies.org。您可以清除计算机上保存的所有 Cookie,大部分网络浏览器都设有阻止 Cookie 的功能。但如果您这么做,则需要在每一次访问平台时更改员工设置。如需详细了解如何更改浏览器设置,请访问您使用的浏览器的相关设置页面。</div>
<div>2. 4.2 网站信标和像素标签</div>
<div>除 Cookie 外,我们还会在网站上使用网站信标和像素标签等其他同类技术。例如,我们向您发送的电子邮件可能含有链接至我们网站内容的地址链接,如果您点击该链接,我们则会跟踪此次点击,帮助我们了解您的服务偏好以便于我们主动改善服务体验。网站信标通常是一种嵌入到网站或电子邮件中的透明图像。借助于电子邮件中的像素标签,我们能够获知电子邮件是否被打开。</div>
<div>五、我们如何共享、转让、公开披露您的个人信息</div>
<div>1. 共享</div>
<div>我们不会与平台服务提供者以外的任何公司、组织和个人分享您的个人信息,但以下情况除外:</div>
<div>1、在获取明确同意的情况下共享:获得您的明确同意后,我们会与其他方共享您的个人信息。</div>
<div>2、我们可能会根据法律法规规定,或按政府主管部门的强制性要求,对外共享您的个人信息。</div>
<div>3、与授权合作机构共享:仅为实现本声明和政策中声明的目的,我们的某些服务将由授权合作机构提供。我们可能会与合作机构共享您的某些个人信息,以提供更好的服务和员工体验。我们仅会出于合法、正当、必要、特定、明确的目的共享您的个人信息,并且只会共享提供服务所必要的个人信息。我们的合作机构无权将共享的个人信息用于任何其他用途。</div>
<div>目前,我们的授权合作机构包括以下类型:</div>
<div>(1)分析服务类的授权合作机构。除非得到您的许可,否则我们不会将您的个人身份信息(指可以识别您身份的信息,例如姓名或电子邮箱,通过这些信息可以联系到您或识别您的身份)与提供分析服务的合作机构分享。我们会向这些合作机构提供有关其服务覆盖面和有效性的信息,而不会提供您的个人身份信息,或者我们将这些信息进行汇总,以便它不会识别您。</div>
<div>(2)服务提供方和其他合作机构。我们将信息发送给支持我们业务的服务提供方和其他合作机构,这些支持包括提供技术基础设施服务、分析我们服务的使用方式、衡量服务的有效性、提供员工服务、支付便利或进行学术研究和调查。</div>
<div>对我们与之共享个人信息的机构,我们会与其签署严格的保密协定,要求他们按照我们的说明、声明和政策以及其他任何相关的保密和安全措施来处理个人信息。</div>
<div>2. .转让</div>
<div>除以下情形外,我们不会将您的个人信息转让给任何公司、组织或个人:</div>
<div>1)事先获得您的明确同意的;</div>
<div>(2)根据法律法规规定,或者政府主管部门、司法机关的强制要求必须对外转让的;</div>
<div>(3)涉及公司合并、分立、解散、资产或业务转让、破产清算或类似的交易时,若涉及到您的个人信息转让,我们会要求新持有您个人信息的公司、组织或个人继续受本政策的约束,否则我们将要求该等公司、组织或个人重新取得您的授权同意。</div>
<div>3. 公开披露</div>
<div>除以下情形外,我们不会公开披露您的个人信息:</div>
<div>1)事先获得您的明确同意的;</div>
<div>(2)根据法律法规规定,或者政府主管部门、司法机关的强制要求必须公开披露的。在符合法律法规的前提下,当我们收到上述披露信息的请求时,我们会要求必须出具与之相应的法律文件,如传票或调查函。我们坚信,对于要求我们提供的信息,应该在法律允许的范围内尽可能保持透明。我们对所有的请求都将进行慎重的审查,以确保其具备合法依据,且仅限于执法部门因特定调查目的且有合法权利获取的数据。</div>
<div>4. 共享、转让、公开披露个人信息授权同意的例外</div>
<div>根据相关法律法规的规定,在以下情形中,我们可以在不征得您的授权同意的情况下共享、转让、公开披露您的个人信息:</div>
<div>A.与国家安全、国防安全有关的;</div>
<div>B.与公共安全、公共卫生、重大公共利益有关的;C.与犯罪侦查、起诉、审判和判决执行等有关的;</div>
<div>D.出于维护您或其他个人的生命、财产等重大合法权益但又很难得到本人同意的;</div>
<div>E.您自行向社会公众公开的个人信息;</div>
<div>F.从合法公开披露的信息中收集到的个人信息的,如合法的新闻报道、政府信息公开等渠道。</div>
<div>G.法律法规规定的其他情形。</div>
<div>根据法律规定,共享、转让经去标识化处理的个人信息,且确保数据接收方无法复原并重新识别个人信息主体的,不属于个人信息的对外共享、转让及公开披露行为,对此类数据的保存及处理将无需另行向您通知并征得您的同意。</div>
<div>六、员工业务数据和公开信息</div>
<div>不同于您的个人信息,对于员工业务数据和公开信息,平台将按如下方式处理:</div>
<div>1. 员工业务数据</div>
<div>1、您通过平台提供的服务,加工、存储、上传、下载、分发以及通过其他方式处理的数据,均为您的员工业务数据。平台作为服务提供者,只会严格执行您的指示处理您的业务数据,除按与您协商一致或执行明确的法律法规要求外,不对您的业务数据进行任何非授权的使用或披露。</div>
<div>2、您应对您的员工业务数据来源及内容负责,平台提示您谨慎判断数据来源及内容的合法性。因您的员工业务数据内容违反法律法规、部门规章或国家政策而造成的全部结果及责任均由您自行承担。</div>
<div>3、根据您与平台协商一致,平台在您选定的数据中心存储员工业务数据。我们恪守对员工的安全承诺,根据适用的法律保护员工存储在平台数据中心的数据。</div>
<div>2. 公开信息</div>
<div>1、公开信息是指您公开分享的任何信息,任何人都可以在使用和未使用平台服务期间查看或访问这些信息。例如您在社区、论坛发布的信息。</div>
<div>2、为使用平台的服务,可能存在您必须公开分享的信息。</div>
<div>七、我们如何保护您的个人信息</div>
<div>1.我们已使用符合业界标准的安全防护措施保护您提供的个人信息,防止您的个人信息遭到未经授权访问、使用、修改、公开披露、损坏或丢失。我们会采取一切合理可行的措施,保护您的个人信息,比如:</div>
<div>(1)我们设立了网络安全和个人信息保护机构,专门负责网络安全和个人信息保护事务;</div>
<div>(2)我们的网络服务采取了传输层安全协议等加密技术,通过https等方式提供浏览服务,确保用户数据在传输过程中的安全;</div>
<div>(3)我们采取MD5、SHA256等加密技术对您的个人信息进行加密存储,增强个人信息在使用中的安全性;</div>
<div>(4)我们采用严格的数据访问权限控制和多重身份认证技术保护个人信息,避免数据被违规使用;</div>
<div>(5)我们采用代码安全检查、数据访问日志分析技术进行个人信息安全审计;</div>
<div>(6)我们建立了客户信息保护管理规定、客户信息分级分类管理规定、日常操作规程等一系列管理制度来规范个人信息的存储和使用;</div>
<div>(7)我们定期举办信息安全和个人信息保护培训课程,加强员工对于个人信息保护重要性的认识;</div>
<div>(8)我们与所有可能接触个人信息的员工签订了保密协议,对关键岗位人员进行背景审查,并建立了严格的访问权限控制、权限审批流程和监控、审计机制;</div>
<div>(9)我们与所有可能接触用户个人信息的合作伙伴均签署了严格的保密协议或数据保护专用条款,并要求可能接触到您个人信息的所有人员履行相应的保密和数据保护义务。如果第三方合作伙伴未履行保密和数据保护义务,可能会被我们追究法律责任并被我们终止合作;</div>
<div>2.我们已经通过了国家信息安全等级保护测评和备案,最高备案等级为二级。</div>
<div>3.我们会采取一切合理可行的措施,确保未收集无关的个人信息。我们只会在达成本政策所述目的所需的期限内保留您的个人信息,除非需要延长保留期或者受到法律允许。</div>
<div>4.互联网并非绝对安全的环境,而且电子邮件、即时通讯、社交软件等与其他用户的交流方式无法确定是否完全加密,我们强烈建议您不用通过此类方式发送个人信息。若确需使用,在使用此类工具时请使用复杂密码,并注意保护您的个人信息安全。我们将尽力保障您个人信息的安全性。如果我们的物理、技术、或管理防护设施遭到破坏,导致信息被非授权访问、公开披露、篡改、或毁坏,导致您的合法权益受损,我们将全力配合保护您的权益,并依法承担我们应承担的赔偿责任。</div>
<div>5.在不幸发生个人信息安全事件后,我们将按照法律法规的要求及时向您告知安全事件的基本情况和可能的影响、我们已采取或将采取的处置措施、您可自主防范和降低风险的建议、对您的补救措施等。我们将及时将事件相关情况以邮件、信函、电话、推送通知等方式告知您,难以逐一告知时,我们会采取合理、有效的方式发布公告。同时,我们还将按照监管部门要求,主动上报个人信息安全事件的处置情况。</div>
<div>八、您如何管理您的个人信息(您的权力)</div>
<div>您可以通过以下方式访问及管理您的个人信息:</div>
<div>8.1 访问您的个人信息</div>
<div>您的账号信息:您可在“我的”中查询您的账户、姓名、性别、手机、身份证号、工作信息、健康类型、学历、工号、工种、住址,紧急联系人的姓名、电话等。</div>
<div>您和您亲属的健康信息:您可在“咨询人管理”中查询您和您亲属手机号码、患者姓名、性别、出生日期、与患者的关系、身高体重、所在城市;健康信息:病症、患病时长、体检报告、住院记录、诊治情况、用药记录、以往病史、过敏信息、家族史、患病史等健康信息。</div>
<div>您的订单、工单信息:您可在“我的-我的咨询”、“我的-我的应急工单”、“我的-大病就医工单”、“健康体检-体检预约”等各个业务的对应入口查看、评价订单和工单信息。</div>
<div>您的体检报告:你可在“健康体检-体检报告”和“健康档案-健康现状”、“健康档案-体检数据分析”查看个人的体检报告详情和重点指标的分析。</div>
<div>对于您在使用我们的产品或服务过程中向我们提供或产生的其他信息,只要我们不需要过多投入,我们会向您提供。您可以通过拨打我们的客服电话提出访问申请,我们将在30天内回复您的访问请求。</div>
<div>对于您在使用我们服务过程中产生的其他个人信息,我们将根据本条“8.9 响应您的上述请求”中的相关安排向您提供。</div>
<div>8.2 更正或补充您的个人信息</div>
<div>当您发现我们处理的您的个人信息有误或者您需要更正该等信息时,您可以通过内设置的自动更正功能、电子邮件或者拨打客服电话等方式进行修改或更正。您如果需要更正其他个人信息,可通过联系人工客服向我们提出更正申请。</div>
<div>可自主更正的信息:</div>
<div>账号信息:您可在“我的”中更新您的头像,紧急联系人的姓名、电话等。</div>
<div>您和您亲属的健康信息:您可在“咨询人管理”中更正您和您亲属手机号码、患者姓名、性别、出生日期、与患者的关系、身高体重、所在城市;健康信息:病症、患病时长、体检报告、住院记录、诊治情况、用药记录、以往病史、过敏信息、家族史、患病史等健康信息。</div>
<div>8.3 如何注销</div>
<div>您在我们的产品与/或服务页面中可以直接清除或删除的信息,包括浏览信息、紧急联系人信息、咨询人信息。</div>
<div>在以下情形中,您可以向我们提出删除个人信息的请求:</div>
<div>(1)如果我们处理个人信息的行为违反了法律法规的强制性规定;</div>
<div>(2)如果我们收集、使用您的个人信息,却未征得您的同意(依法无需征得同意的情况除外);</div>
<div>(3)如果我们处理个人信息的行为违反了与您的约定;</div>
<div>(4)如果您不再使用我们的产品或服务,或您注销了账号;</div>
<div>5)如果我们不再为您提供产品或服务。</div>
<div>如果您想删除或注册账号:</div>
<div>(1)拨打客服热线电话029-86618899</div>
<div>2)发送电子邮件至40115111@qq.com</div>
<div>(3)邮寄地址:陕西省西安市未央区欧亚大道丝路国际创意梦工场5号楼,收件人:许策</div>
<div>收到您的删除请求后,我们会根据您及相关法律法规的要求进行后续删除处理并向您反馈结果。若我们决定响应您的删除请求,我们还将同时通知从我们获得您的个人信息的实体,要求其及时删除,除非法律法规另有规定,或这些实体获得您的独立授权。</div>
<div>当您从我们的服务中删除信息后,我们可能不会立即备份系统中删除相应的信息,但会在备份更新时删除这些信息。</div>
<div>8.4 改变您授权同意的范围</div>
<div>您可以通过删除信息、关闭设备功能、在平台中进行隐私设置等方式改变您授权我们继续收集个人信息的范围或撤回您的授权。</div>
<div>请您理解,每个业务功能需要一些基本的个人信息才能得以完成(见本隐私权政策“我们如何收集和使用您的信息”)。当您收回同意后,我们将不再处理相应的个人信息。但您收回同意的决定,不会影响此前基于您的授权而开展的个人信息处理。</div>
<div>8.5 个人信息主体注销账户</div>
<div>在符合平台单项服务的服务协议约定条件及国家相关法律法规规定的情况下,您的该项平台服务帐号可能被注销或删除。当帐号注销或被删除后,与该帐号相关的、该单项服务项下的全部服务资料和数据将依照单项服务的服务协议约定删除或匿名化处理。</div>
<div>8.6 约束信息系统自动决策</div>
<div>在某些业务功能中,我们可能仅依据信息系统、算法等在内的非人工自动决策机制做出决定。如果这些决定显著影响您的合法权益,您有权要求我们做出解释,我们也将在不侵害平台保密或其他员工权益、社会公共利益的前提下提供申诉方法。</div>
<div>8.7约束信息系统自动决策</div>
<div>在某些业务功能中,我们可能仅依据信息系统、算法在内的非人工自动决策机制作出决定。如果这些决定显著影响您的合法权益,您有权要求我们作出解释,我们也将提供适当的救济方式。</div>
<div>8.8举报和投诉</div>
<div>如果您发现您的个人信息可能被泄露,或者我们的工作人员或合作伙伴在处理您的个人信息时有任何违法违规行为,您可以通过拨打客服热线或者发送电子邮件的方式向我们进行举报和投诉。</div>
<div>8.9 响应您的上述请求</div>
<div>为保障安全,您可能需要提供书面请求,或以其他方式证明您的身份。我们可能会先要求您验证自己的身份,然后再处理您的请求。我们将在15个工作日内做出答复。</div>
<div>对于那些无端重复、需要过多技术手段(例如,需要开发新系统或从根本上改变现行惯例)、给他人合法权益带来风险或者非常不切实际的请求,我们可能会予以拒绝。</div>
<div>在以下情形中,按照法律法规要求,我们将无法响应您的请求:</div>
<div>(1) 与国家安全、国防安全有关的;</div>
<div>(2) 与公共安全、公共卫生、重大公共利益有关的;</div>
<div>(3) 与犯罪侦查、起诉、审判和执行判决等有关的;</div>
<div>(4) 有充分证据表明个人信息主体存在主观恶意或滥用权利的;</div>
<div>(5) 响应您的请求将导致您或其他个人、组织的合法权益受到严重损害的;</div>
<div>(6) 涉及商业秘密的。</div>
<div>九、我们如何处理未成年人的个人信息</div>
<div>1.健康咨询员工端非常重视对未成年人个人信息的保护。若您是18周岁以下的未成年人,在使用我们的产品与/或服务前,应事先取得您监护人的同意。健康咨询员工端根据国家相关法律法规的规定保护未成年人的个人信息。</div>
<div>2.我们不会主动直接向未成年人收集其个人信息。对于经监护人同意而收集未成年人个人信息的情况,我们只会在受到法律允许、监护人同意或者保护未成年人所必要的情况下使用、共享、转让或披露此信息。</div>
<div>3.如果有事实证明未成年人在未取得监护人同意的情况下注册使用了我们的产品与/或服务,我们会与相关监护人协商,并设法尽快删除相关个人信息。</div>
<div>十、本声明和政策如何更新</div>
<div>我们的隐私政策可能变更。未经您明确同意,我们不会削减您按照声明和政策所应享有的权利。 我们会在本页面上发布对本声明和政策所做的任何变更。</div>
<div>对于重大变更,我们还会提供更为显著的通知(包括我们会通过网站公示的方式进行通知甚至向您提供弹窗提示)。</div>
<div>本声明和隐私所指的重大变更包括但不限于:</div>
<div>1、 我们的服务模式发生重大变化。如处理个人信息的目的、处理的个人信息类型、个人信息的使用方式等;</div>
<div>2、 我们在所有权结构、组织架构等方面发生重大变化。如业务调整等引起的所有者变更等;</div>
<div>3、 个人信息共享或公开披露的主要对象发生变化;</div>
<div>4、 您参与个人信息处理方面的权利及其行使方式发生重大变化;</div>
<div>5、 我们负责处理个人信息安全的责任部门、联络方式等发生变化时;</div>
<div>6、 个人信息安全影响评估报告表明存在高风险时。</div>
<div>7、 我们还会将本声明和隐私的旧版本存档,供您查阅。</div>
<div>十一、如何联系我们</div>
<div>1.如果您对本政策有任何疑问、意见或建议,可通过以下方式与我们联系:</div>
<div>(1)拨打客服热线电话029-86618899</div>
<div>2)发送电子邮件至40115111@qq.com</div>
<div>(3)邮寄地址:陕西省西安市未央区欧亚大道丝路国际创意梦工场5号楼,收件人:许策</div>
<div>我们的客服部门将会同个人信息保护部门30天内进行回复,并协助解决您的问题。</div>
<div>2.如果您对我们的回复不满意,特别是我们的个人信息处理行为损害了您的合法权益,您还可以通过以下外部途径寻求解决方式:向网信、工商、公安等监管部门进行投诉或举报。</div>
</div>
</body>
</html>
-152
View File
@@ -1,152 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>健康咨询员工端用户协议</title>
</head>
<style>
html,body {
padding: 0;
margin: 0;
}
html,body,#zwb{
box-sizing: border-box;
overflow: hidden auto;
font-size: 22px;
}
html::-webkit-scrollbar {
width: 0;
}
body::-webkit-scrollbar {
width: 0;
}
#zwb {
padding: 25px;
width: 100%;
height: 100%;
overflow: hidden auto;
}
div {
margin: 0 0 10px;
}
.title-one {
text-align: center;
margin: 5px 0
}
</style>
<body>
<div id="zwb">
<h3 class="title-one">健康咨询员工端用户协议</h3>
<h3 class="title-one">软件使用许可协议(健康咨询员工端)</h3>
<h3 class="title-one">软件使用许可协议</h3>
<div>欢迎使用我们的服务</div>
<div>本软件许可使用协议《健康咨询员工端平台服务协议》(以下称"本协议")由您与西安恒烨通企业管理咨询有限公司(以下称“西安恒烨通”)共同签署。</div>
<div>在使用“健康咨询员工端”软件(以下称许可软件)之前,请仔细阅读本协议。一旦您下载安装使用许可软件,即表示您同意接受本协议所有条款和条件的约束。如您不同意本协议条款和条件,请勿使用许可软件,并请销毁所有许可软件副本。</div>
<div>健康咨询员工端有权根据实际运营的情况对本协议不时进行调整,并以平台公告或电子邮件等书面形式通知您。修改后的协议于公示或邮件送达时生效。协议条款修改后,您继续使用许可软件的,即视为您已阅读并接受修改后的协议。</div>
<div>一、定义</div>
<div>1. 健康咨询员工端APP:是指由西安恒烨通开发的,供您从应用下载平台(以下称下载平台)下载,并仅限在手机等手持移动终端(以下称移动终端)中安装、使用的软件系统。</div>
<div>2. 健康咨询员工端服务:由西安恒烨通为您提供的服务。您可以通过许可软件在手持移动终端使用健康咨询员工端服务。</div>
<div>3. 用户:指阅读并同意本协议内容,经过健康咨询员工端在线注册程序成为健康咨询员工端在线各项服务使用者。(以下更多称为“您”)</div>
<div>二、服务说明</div>
<div>1. 本平台是一个集健康咨询功能的综合个人健康管理平台,为确保您能正常地使用平台的各项服务,您应当阅读并遵守本协议。请您务必审慎阅读、充分理解各条款内容,以及开通或使用某项服务的单独协议,并选择接受或不接受。</div>
<div>2. 除非您已阅读并接受本协议所有条款,否则您无权使用平台的各项服务(以下简称"本服务”)。您在平台的登录、查看、发布信息等行为即视为您已阅读并同意本协议的约束,包括接受更新后的本协议条款。当您与平台发生争议时,应以最新的服务协议为准。</div>
<div>3. 平台为您提供集健康咨询功能服务,为充分保护您对于平台提供的各项服务的知情权,平台就其提供的服务相关性、有效性以及限制性提供以下注册条款。平台在此特别提醒您,在您使用前已确实仔细阅读了本协议,如果您对本协议的任何条款或者将来随时可能修改、补充的条款有异议,您可选择不注册。</div>
<div>4. 您在使用服务过程中,根据声音、文字或图形等提示可以选择表示“同意”的操作,当您点选“同意”按钮时即视为您已仔细阅读本协议,同意接受本协议项下的所有条款,包括接受平台对本协议条款随时所做的任何修改,并愿意受其约束。之后方能按系统提示完成全部注册程序、问答程序、享受相关的各项电子服务。</div>
<div>5. 您在平台提问、搜索、提供各项电子信息、与其它员工交流及其他服务,即代表您已经同意本协议。</div>
<div>6. 本协议的条款适用于平台提供的各种服务,但当您使用平台某特定服务时,如该服务另有单独的服务条款、指引或规则,您应遵守本协议及平台随时公布的与该服务相关的服务条款、指引或规则等。前述所有的指引和规则,均构成本协议的一部分。除非本协议另有其他明示规定,新推出的服务、增加或强化目前本服务的新功能,均受到本协议之规范。</div>
<div>7. 如对本协议内容有任何疑问、意见或建议,您可与我们联系。</div>
<div>三、本协议的确认和接纳</div>
<div>1、平台的各项服务的所有权和运作权归西安恒烨通所有。您同意所有注册协议条款,才能成为平台平台的正式用户。您确认:本协议条款是处理双方权利义务的契约,始终有效,法律另有强制性规定或双方另有特别约定的,依其规定。</div>
<div>2、您点击注册登录,即视为您确认自己具有享受平台服务相应的权利能力和行为能力,能够独立承担法律责任。</div>
<div>3、平台通过互联网为您提供各项服务,并承担本协议和其它服务协议中对您的责任和义务。为使用本服务,您必须能够自行通过有法律资格的第三方对您提供互联网接入服务,并自行承担以下内容:</div>
<div>(1)自行配备上网所需的设备,包括手机、个人电脑、调制解调器及其他必要的设备装置。</div>
<div>(2)自行承担上网所需的相关必要费用,如:电话费用、网络费用等。</div>
<div>(3)本协议中规定的您的其他责任和义务。</div>
<div>4、您应保证:提供详尽、真实、准确和完整的个人资料以符合实名认证的要求。如果资料发生变动,您应及时更改。若您提供任何错误、不实、过时或不完整的资料,并为平台所确知,或者平台有合理理由怀疑前述资料为错误、不实、过时或不完整的资料,平台有权暂停或终止您的帐号,并拒绝现在或将来申请使用本服务的全部或一部分的请求。在此情况下,您可通过平台的申诉途径与平台取得联系并修正个人资料,经平台核实后恢复账号使用。</div>
<div>5、本务不会提供给被暂时中止或永久终止资格的平台员工。</div>
<div>6、平台会尽最大努力为员工提供服务,确保服务的连贯性和安全性;但平台不能随时预见和防范法律、技术以及其他风险,包括但不限于不可抗力、病毒、木马、黑客攻击、系统不稳定、第三方服务瑕疵、政府行为等原因可能导致的服务中断、数据丢失以及其他的损失和风险。</div>
<div>7、本协议依据国家相关法律法规规章制定,员工同意并遵守相关法律法规:</div>
<div>(1)不得传输或发表:煽动抗拒、破坏宪法和法律、行政法规实施的言论,煽动颠覆国家政权,推翻社会主义制度的言论,煽动分裂国家、破坏国家统一的的言论,煽动民族仇恨、民族歧视、破坏民族团结的言论;</div>
<div>(2)不得利用平台从事洗钱、窃取商业秘密、 窃取个人信息等违法犯罪活动;</div>
<div>(3)不得干扰平台的正常运转,不得侵入平台及国家计算机信息系统;</div>
<div>(5)不得传输或发表任何违法犯罪的、骚扰性的、中伤他人的、 辱骂性的、恐吓性的、伤害性的、庸俗的、 淫秽的、不文明的等信息资料;</div>
<div>(6)不得传输或发表损害国家社会公共利益和涉及国家安全的信息资料或言论;</div>
<div>(7)不得教唆他人从事本条所禁止的行为;</div>
<div>(8)不得发布任何侵犯他人著作权、商标权等知识产权或合法权利的内容。您应关注并遵守平台不时公布或修改的各类合法规则规定。平台保有删除各类不符合法律政策或不真实的信息内容而无须通知员工的权利。若您未遵守以上规定的,平台有权作出独立判断并采取暂停或关闭员工帐号等措施。您须对自己在网上的言论和行为承担法律责任。</div>
<div></div>
<div>四、员工管理</div>
<div>1、您使用本平台服务时,在平台上不得发表违法言论、不得违反公序良俗、不得使用攻击性语言恶意中伤他人,或作出虚假性陈述。您保证您在平台上提供的信息的真实性、合法性和有效性。您单独承担在平台上发布内容的一切相关责任。您使用或提供的服务应有适用于平台的地方法律、国家法律和国际法律标准。</div>
<div>2、您不得干扰或扰乱本平台提供的服务,不得盗用他人帐号,如有上述行为,您需对此行为造成的后果负责。</div>
<div>3、您应遵守所有使用本服务的各项协议、 规定、程序和惯。您须承诺不传输任何非法的、骚扰性的、中伤他人的、辱骂性的、恐吓性的、伤害性的、庸俗的,淫秽等信息内容。另外,您也不能传输任何教唆他人构成犯罪行为的内容;不能传输助长国内不利条件和涉及国家安全的内容;不能传输任何不符合当地法规、国家法律和国际法律的内容。</div>
<div>4、您不得发布任何不基于事实、虚构、夸大、引人误解的信息;不得发布涉及政治、性别、种族歧视或攻击他人的文字、图片、视频或语言等信息;不得发布有广告性质的内容;不得有其它涉及违反当地法规、国家法律和国际法律的行为。</div>
<div>5、您发布的文章、视频、资讯不得侵犯任何第三方的合法知识产权。</div>
<div>6、若您的行为不符合本协议的规定,平台有权做出独立判断,并立即停止向该您帐号提供服务。您需对自己在网上的行为承担法律责任。您若在平台上散布和传播反动、色情或其他违反国家法律的信息,平台的系统记录有可能作为您违反法律的证据。</div>
<div>7、您的授权行为:对平台而言,您帐号和密码是唯一验证您真实性的依据,只要使用了正确的您帐号和密码,无论是谁登录均视为已经得到您本人的授权。</div>
<div>五、员工保障</div>
<div>您同意保障和维护平台的利益,如果因为您违反有关法律、法规或本协议的任何规定而给平台或其他第三方造成任何损失,您统一承担由此产生的损害赔偿责任,其中包括平台为此而支付的律师费用。</div>
<div></div>
<div>六、您的帐号、密码和安全性</div>
<div>1、您一旦注册成功,成为平台的合法用户,将得到一个您的帐号和密码。您的帐号和密码由您负责保管。您要对任何以您帐号进行的活动和事件负全责,且您有权随时根据指示更改您的密码。若发现您的帐号有任何风险、非法使用或存在安全漏洞的情况,请立即通知平台。</div>
<div>2、 因黑客行为或您的保管疏忽等情况导致帐号、密码遭他人非法使用,平台不承担责任。平台将根据法律法规的要求,履行其作为移动互联网信息服务提供者应当履行的义务。</div>
<div>七、收费服务</div>
<div>1、如您使用平台的收费服务,请遵守相关的协议。</div>
<div>2、 请您在支付费用时,仔细阅读收费服务的相关协议,除协议约定的情况外,否则,平台将不予退费。退费的方式视支付方式的不同而不同。员工应严格依据退费方式及退费周期收回退款。</div>
<div>3、平台可能根据实际需要对收费服务的收费标准、方式进行修改和变更,平台也可能会对部分免费服务变更收费。如果您不同意上述修改、变更或付费内容,则应停止使用该服务。</div>
<div>八、服务暂停、变更与中止条款</div>
<div>1、鉴于移动互联网服务的特殊性,健康咨询员工端平台有权随时变更、中止或终上部分或全部的服务。如变更、中止或终止的服务属于免费服务,平台无需通知您,也无需对您或任何第三方承担任何责任。</div>
<div>2、您理解,因不可抗力、网络状况、通讯线路、用户自身过错等技术原因,或平台需要进行定期或不定期地对所提供的服务进行维护升级、对相关的设备进行检修或者维护,如因此类情况而造成本服务在合理时间内的中断,健康咨询员工端平台无需为此承担任何责任。</div>
<div>3、 如发生下列任何一种情形,平台有权随时中断或终止向您提供本协议项下的服务而无需对您或任何第三方承担任何责任:</div>
<div>(1)您违反国家有关法律法规或平台规定,侵害他人合法权益的;</div>
<div>(2)您提供的个人资料不真实;</div>
<div>(3)您违反本协议中的规定;</div>
<div>(4)您违反平台发布的政策;</div>
<div>(5)平台认为其他不适宜的地方。</div>
<div>九、结束服务</div>
<div>您或平台可随时根据员工管理的规范中断一项或多项本服务,平台无需对您或任何其他第三方负责。您对本协议的修改有异议,或对平台的服务不满,可以行使如下权利:</div>
<div>1、停止使用平台提供的服务。</div>
<div>2、通知平台停止对您帐号提供服务。停止为您提供服务后,您使用本服务的权利即刻终止,,平台不对您承担任何义务和责任。</div>
<div>十、隐私及个人信息的保护</div>
<div>1、保护您的隐私是平台的一项基本政策。</div>
<div>2、您的信任对平台非常重要,平台深知个人信息安全的重要性,平台将按照法律法规要求,采取安全保护措施,保护您的个人信息安全。</div>
<div>十一、知识产权条款</div>
<div>1、 您一旦接受本协议,即表明您在任何时间在平台发表的任何形式的信息内容(包括但不限于员工评价、员工咨询、各类话题文章等信息内容)产生的权利,如著作权财产权(包括并不限于:复制权、发行权、出租权、展览权、表演权、放映权、广播权、信息网络传播权、摄制权、改编权、翻译权、汇编权以及应当由著作权人享有的其他可转让权利), 全部独家且不可撤销地转让给平台所有,您同意平台有权就任何主体侵权而单独提起诉讼。</div>
<div>2、本协议已经构成《中华人民共和国著作权法》第二十五条(条文序号依照2011年版著作权法确定)及相关法律规定的著作财产权等权利转让书面协议,其效力及于您在平台上发布的任何受著作权法保护的作品内容,无论该等内容形成于本协议订立前还是本协议订立后。</div>
<div>3、您同意并已充分了解本协议的条款,承诺不将已发表于平台的信息,以任何形式发布或授权其它主体以任何方式使用(包括但限于在各类网站、媒体上使用)、</div>
<div>4、西安恒烨通是平台的制作者,拥有平台内容及资源的著作权等合法权利,受国家法律保护,有权不时地对本协议及平台的内容进行修改,并在平台张贴,无须另行通知您。在法律允许的最大限度范围内,平台对本协议及的内容拥有解释权。</div>
<div>5、除法律另有强制性规定外,未经平台明确的特别书面许可,任何单位或个人不得以任何方式非法地全部或部分复制、转载、引用、链接、抓取或以其他方式使用平台的信息内容,否则,平台有权追究其法律责任。</div>
<div>6、平台所刊登的资料信息(诸如文字、图表、标识、按钮图标、图像、声音文件片段、数字下载、数据编辑和软件),均是平台或其内容提供者的财产,受中国和国际版权法的保护。平台上所有内容的汇编是平台的排他财产,受中国和国际版权法的保护。平台上的所有软件都是平台的财产,受中国和国际版权法的保护。</div>
<div>十二、特别授权</div>
<div>您完全理解并不可撤销地授予平台下列权利:</div>
<div>1、一旦您向平台作出任何形式的承诺,且相关机构已确认您违反了该承诺,则平台有权依据您的承诺或协议约定的方式对您的账户采取限制措施,包括中止或终止向您提供服务,并向相关机构确认的您的违约情况。您了解并同意,平台无须就相关违约事项与您核对事实,或另行征得您的同意,且平台无须就此限制措施或公示行为向您或任何第三方承担任何的责任。</div>
<div>2、一旦您违反本协议、或与平台签订其他协议的约定,平台有权或以任何方式通知其他相关平台服务,要求其对您的权益采取限制措施,包括但不限于要求中止、终止对您提供的部分或全部服务。</div>
<div>3、您授权平台使用您注册、使用本平台服务过程中产生的信息,并允许平台通过短信、邮件、电话或其他形式向您传送平台提供的服务。您同意接受平台通过短信、邮件、电话或其他形式向您发送活动、服务等信息。如果您不需要平台提供的部分或全部服务的活动、服务,您可向平台提出申请中止、终止对您提供的该部分或全部服务。</div>
<div>十三、平台拒绝提供担保</div>
<div>1、您对移动网络服务的使用承担风险,并承担因为使用移动网络服务而产生的一切后果。平台对此不作任何类型的担保,不论是明确的或隐含的,但是不对商业性的隐含担保、特定目的和不违反规定的适当担保作限制。</div>
<div>2、平台不担保提供的服务一定能完全满足您的要求,也不担保本服务不会受网络、通信等原因而中断,对服务的及时性、安全性、错误程序的发生都不作担保。</div>
<div>3、平台因受合作医疗机构等资源限制,就您所提的请求不担保服务一定能够成功。</div>
<div>4、您不能从平台得到口头或书面的意见或信息(增加除外条款,而并非全部),平台也不会在此做明确担保。</div>
<div>5、除非另有明确的书面说明,平台不对平台上的信息、内容、材料、包括软件或服务作任何形式的、明示或联示的声明或担保(根据中华人民共和国法律另有规定的以外)</div>
<div>6、如因不可抗力或其它无法控制的原因使平台系统崩溃或无法正常使用导致无法完成或丢失有关的服务信息、记录等,平台会合理地尽力协助处理。</div>
<div>十四、责任限制</div>
<div>1、平台会尽最大努力为您提供服务,确保服务的连贯性和安全性;但平台不能随时预见和防范法律、技术以及其他风险,包括但不限于不可抗力病毒、木马、黑客攻击、系统不稳定第三方服务瑕疵、政府行为等原因可能导致的服务中断数据丢失以及其他的损失和风险。因平台所不能控制的事件而影响提供服务,平台无须承担任何责任。</div>
<div>2、因不正当使用网络服务,私自在网上进行交易,非法使用网络服务或您传送的信息有所变动等这些行为都有可能会导致平台的形象受损,所以平台事先提出这种损害的可能性。</div>
<div>3、平台所有信息仅供参考。平台不对因信息的不正确或遗漏导致的任何损失或损害承担责任。平台所提供的任何健康资讯,仅供参考,不能替代医生和其他医务人员的建议,如自行使用平台资料发生偏差,平台不承担任何法律责任。</div>
<div>4、平台拒绝回复的问题,包括但不限于如下情况:</div>
<div>(1)动物疾病问题、社会意识形态问题等;</div>
<div>(2)医疗司法举证或询证问题;</div>
<div>(3)胎儿性别鉴定问题;</div>
<div>(4)有危害他人/自己可能的问题;</div>
<div>(5) 追问医生个人信息的问题;</div>
<div>(6) 故意挑逗、侮辱医生的提问。</div>
<div>5、平台保留对本声明作出不定时修改的权利。</div>
<div>十五、协议修改</div>
<div>根据国家法律法规变化及网络运营需要,本协议即时生效,并对条款不时地进行修改。您可随时登陆查阅最新协议;您有义务不时关注并阅读最新版的协议及平台公告;如您使用平台提供服务,即视为同意更新后的协议。建议您在使用平台之前阅读本协议。</div>
<div>十六、其他</div>
<div>1、平台尊重您的合法权利,本协议及平台上发布的各类规则、声明等其他内容,均是为了更好地、更加便利地为您提供服务。平台欢迎您和社会各界提出意见和建议,平台将虚心接受并适时修改本协议及平台的各类规则。</div>
<div>2、您使用平台服务即视为您完全接受本协议,在“登录"之前请您再次确认已知悉并完全理解本协议的全部内容。</div>
</div>
</body>
</html>
-300
View File
@@ -1,300 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>隐私权政策</title>
</head>
<style>
html,body {
padding: 0;
margin: 0;
}
html,body,#zwb{
box-sizing: border-box;
overflow: hidden auto;
font-size: 22px;
}
html::-webkit-scrollbar {
width: 0;
}
body::-webkit-scrollbar {
width: 0;
}
#zwb {
padding: 25px;
width: 100%;
height: 100%;
overflow: hidden auto;
}
div {
margin: 0 0 10px;
}
.title-one {
text-align: center;
margin: 5px 0
}
</style>
<body>
<div id="zwb">
<h3 class="title-one">隐私权政策</h3>
<div>本平台由西安仁康信息科技有限公司开发和运维,平台深知个人信息对您的重要性,并会尽全力保护您的个人信息安全可靠。我们致力于维持您对我们的信任,恪守以下原则,保护您的个人信息:权责一致原则、目的明确原则、选择同意原则、最少够用原则、确保安全原则、主体参与原则、公开透明原则等。同时,我们承诺将采取相应的安全保护措施来保护您的个人信息。请在使用平台服务前,仔细阅读并了解本隐私权政策,我们将按照本政策收集、处理及披露您的信息。</div>
<div>本政策将帮助您了解以下内容:</div>
<div>1、定义</div>
<div>2、我们可能收集的信息</div>
<div>3、我们如何收集和使用您的个人信息</div>
<div>4、我们如何使用 Cookie 和同类技术</div>
<div>5、我们如何共享、转让、公开披露您的个人信息</div>
<div>6、员工业务数据和公开信息</div>
<div>7、我们如何保护您的个人信息</div>
<div>8、您如何管理您的个人信息</div>
<div>9、我们如何处理未成年人的个人信息</div>
<div>10、本声明和政策如何更新</div>
<div>11、如何联系我们</div>
<div>一、定义</div>
<div>1. 个人信息:</div>
<div>指以电子或者其他方式记录的与已识别或者可识别的自然人有关的各种信息,不包括匿名化处理后的信息</div>
<div>2. 个人健康信息</div>
<div>指以电子或者其他方式记录的能够单独或者与其他信息结合识别特定自然人身份或者反映特定自然人活动情况的各种健康信息,一旦泄露或者非法使用,可能导致个人受到歧视或者人身、财产受到严重危害的个人信息,包括如姓名、出生日期、身份证件号码、体检信息、就医信息、住址、通讯联系方式、通信记录和内容、账号密码、行踪轨迹、民族、个人生物特征、医疗健康、金融账户、个人行踪、不满十四周岁未成年人信息等。</div>
<div>3. 未成年人:指不满18周岁的自然人。</div>
<div>4. 儿童:指不满14周岁的自然人。</div>
<div>5. 设备信息</div>
<div>包括设备标识符 (IMEI、IDFA、Android1D、MAC、OAID、IMSI、SIM 卡序列号 (ICCID) 、设备序列号及其他设备相关信息),应用信息 (应用崩溃信息、通知开关状态、运行中进程、应用安装列表及其他应用相关信息) ,设备参数及系统信息(设备类型、设备型号、操作系统及硬件相关信息),设备网络环境信息 (IP地址,WiFi信息,基站信息及其他网络相关信息),蓝牙信息,广播组件通讯信息,运营商信息,传感器 (陀螺仪、重力传感器、加速度传感器、环境传感器、光学心率传感器),剪切板。以产品实际采集情况为准。</div>
<div>6. 业务数据</div>
<div>不同于个人信息,是指平台员工利用平台的服务上传、下载、分发等通过平台的技术服务处理的数据。</div>
<div>二、我们可能收集的信息</div>
<div>我们提供服务时,可能会收集、储存和使用下列与个人有关的信息。如果您不提供相关信息,可能无法注册成为平台员工或无法享受平台的某些服务,或者无法达到相关服务拟达到的效果。</div>
<div>2.1 与个人身份无关</div>
<div>当您使用平台的服务时,我们可能收集和汇总诸如员工的来源途径、访问顺序、停留时间等信息,例如记录使用平台服务的每个员工的来源途径、浏览器软件等。</div>
<div>2.2 与个人身份有关</div>
<div>当您使用平台的服务时,我们可能收集和汇总或要求您提供有关个人身份的信息,例如:</div>
<div>(1) 个人身份证明(包括身份证图片和身份证号、手机号、邮箱等);</div>
<div>(2) 个人补充信息(姓名、生日、籍贯、性别、兴趣爱好、学历、个人联系电话、住址、工作信息、婚姻状况、健康状况、;</div>
<div>(3) 网络身份标识信息(包括系统账号、IP地址、电子邮箱地址及与前述有关的密码、口令、口令保护答案、个人数字证书等);</div>
<div>(4) 个人健康信息(包括:姓名、性别、出生日期、身高体重、就诊卡、所在城市,所患病症、患病时长、体检报告、住院记录、诊治情况、检验报告、体检报告、用药记录、以往病史、过敏信息、家族史、患病史等,和历史咨询记录。</div>
<div>(5) 相机、相册(设备的相机功能,以拍摄照片或录制视频);</div>
<div>(6) 麦克风(通话、发送录音文件);</div>
<div>(7) 悬浮窗(在其他程序页面仍能保持应用内通话);</div>
<div>(8) 日历(访问用户的日历,以便将预约信息添加到日历中);</div>
<div>(9) 存储(访问设备存储器中的文件、照片和视频);</div>
<div>(10) 个人上网记录和日志信息(包括网站浏览记录、软件使用记录、点击记录、操作日志等);</div>
<div>(11) 设备信息(包括设备型号、设备MAC地址、操作系统类型、设备设置);</div>
<div>(12) 软件列表唯一设备识别码(如IMEI/android ID/IDFA/OPENUDID/GUID、SIM卡IMSI信息等在内的描述个人常用设备基本情况的信息);</div>
<div>(13) 拨打电话(唤起手机拨号界面并自动填充电话)</div>
<div>(14) 个人位置信息(包括精准定位信息、经纬度等);</div>
<div>(15) 其他平台基于为您提供服务需要而收集或汇总的您的信息。</div>
<div>三、我们如何收集和使用您的个人信息</div>
<div>1. 您直接提供的信息:我们可能会收集您在健康咨询专家端注册账号、申请或使用我们的服务时填写,通过现场交谈、电话、视频或其他联系方式与我们联系时所提供的信息,以及您在使用我们服务过程中产生的与您的交易和活动有关的信息。</div>
<div>(1) 帮助您成为我们的一员</div>
<div>您需要向平台提供真实姓名、邮箱、有效身份证件(包括但不限于身份证)的号码,以便于我们进行实名认证。您可以修改和补充您的昵称、性别、生日、职级、职称、学历、亲属、紧急联系人、工作信息(单位部门)、婚姻状况、健康类型、兴趣爱好以及您的实名认证等一系列相关信息相关信息,这些信息均属于您的“账号信息”。您补充的账户信息将有助于我们为您提供与您信息更匹配的相关业务服务(急救协助、医院体检、健康知识推送等)。如果您不提供这些信息,可能会影响您对平台部分核心业务功能的正常使用,如咨询专家等,但不会影响您进行基本的浏览、搜索。如果您不提供这些信息,将会影响您使用平台的部分功能,如咨询专家,但不会影响您使用平台服务的基本浏览、搜索功能。在您主动注销账号时,我们将根据相关法律法规的要求尽快使其匿名或删除您的个人信息。</div>
<div>(2) 咨询专家</div>
<div>为便于您能够咨询专家,您需提供真实姓名、手机号、身份证号码、性别、出生日期、身高体重等信息。为更好地向您提供咨询服务解决您的问题,更加精准、快速地向您推荐医生,我们可能需要您在健康咨询时提供个人健康信息,例如:病症、患病时长、检验报告、体检报告、医院就诊信息、诊治情况、用药记录、以往病史、过敏信息、家族史、患病史等。如您不提供上述信息,将会影响您使用部分健康咨询等功能,但不影响您使用平台产品或服务的基本浏览、搜索功能。应急救援</div>
<div>(1) 您实名成为健康咨询专家端的用户后,若您或您的朋友发生了意外事件,你可以通过查看系统内的相关医疗资源,并向平台发起帮助请求。在此过程中,我们可能会通过您的基本信息和聊天功能获取您的手机号、您的紧急联系人姓名和联系 电话,位置、姓名、性别、年龄、健康状况、事故详情介绍的图文、音视频沟通的信息。搜索</div>
<div>(2) 搜索</div>
<div>为了让您快速地找到您所需要的专家、知识文章、软件功能、医院等,我们可能会收集您使用我们的产品记录为您提供这些信息展示的最优方式。我们也会为了不断改进和优化上述的功能来使用您的上述个人信息。</div>
<div>您也可以通过搜索来精准地找到您所需要的专家、医院、系统功能。我们会保留您的搜索内容以方便您重复输入或为您展示与您搜索内容相关联的产品或服务。</div>
<div>2. 我们在您使用服务过程中收集的信息</div>
<div>为向您提供更契合您需求的页面展示和搜索结果、了解服务适配性、识别账号异常状态,我们会收集关于您使用的服务以及使用方式的信息并将这些信息进行关联,这些信息包括:</div>
<div>设备信息:我们会根据您在软件安装及使用中授予的具体权限,接收并记录您所使用的设备相关信息(例如设备型号、操作系统版本、设备设置、唯一设备标识符等软硬件特征信息)、设备所在位置相关信息(例如IP 地址、GPS位置以及能够提供相关信息的Wi-Fi 接入点、蓝牙和基站等传感器信息)。</div>
<div>日志信息:当您使用我们的网站或用户端提供的服务时,我们会自动收集您对我们服务的详细使用情况,作为有关网络日志保存。例如您的搜索查询内容、IP地址、浏览器的类型、电信运营商、使用的语言、访问日期和时间及您访问的网页记录等。</div>
<div>请注意,单独的设备信息、日志信息等是无法识别特定自然人身份的信息。如果我们将这类非个人信息与其他信息结合用于识别特定自然人身份,或者将其与个人信息结合使用,则在结合使用期间,这类非个人信息将被视为个人信息,除取得您授权或法律法规另有规定外,我们会将该类个人信息做匿名化、去标识化处理。</div>
<div>为展示您的健康信息,我们会收集您在使用我们服务过程中产生的健康咨询详情(包括但不限于图片、文字、视频、语音)、预约挂号记录、咨询记录、个人健康信息、检查检验、医生诊断结果等用于向您展示及便于您对信息进行管理。</div>
<div>当您与我们联系时,我们可能会保存您的通信/通话记录和内容或您留下的联系方式等信息,以便与您联系或帮助您解决问题,或记录相关问题的处理方案及结果。</div>
<div>3. 我们通过间接获得方式收集到的您的个人信息</div>
<div>我们可能从第三方获取您授权共享的账户信息(头像、昵称、联系方式),并在您同意声明和政策后将您的第三方账户与您的账户绑定,使您可以通过第三方账户直接登录并使用平台服务。我们会将依据与第三方的约定、对个人信息来源的合法性进行确认后,在符合相关法律和法规规定的前提下,使用您的这些个人信息。</div>
<div>如您拒绝提供上述信息或拒绝授权,可能无法使用我们的相应服务,或者无法展示相关信息,但不影响使用平台的健康咨询等核心服务。</div>
<div>为您提供安全保障</div>
<div>请注意,为向您提供更好的安全保障,您可以向我们提供姓名、身份证、就诊卡、邮箱等身份信息完成实名认证。如您拒绝提供上述信息,可能无法预约或咨询特定专家、继续可能存在风险的操作等,但不会影响您使用浏览、搜索等服务。</div>
<div>为提高您使用我们提供服务的安全性,更好地预防钓鱼网站、欺诈、网络漏洞、计算机病毒、网络攻击、网络侵入等安全风险,更准确地识别违反法律法规或平台相关协议规则的情况,我们可能使用或整合您的账户信息、交易信息、设备信息、有关网络日志以及我们取得您授权或依据法律共享的信息,来进行身份验证、检测及防范安全事件,并依法采取必要的记录、审计、分析、处置措施。</div>
<div>4. 其他用途</div>
<div>我们将信息用于本声明和政策未载明的其他用途,或者将基于特定目的收集而来的信息用于其他目的时,会事先征求您的同意。</div>
<div>5. 征得授权同意的例外</div>
<div>根据相关法律法规规定,以下情形中收集您的个人信息无需征得您的授权同意:</div>
<div>1、与国家安全、国防安全有关的;</div>
<div>2、与公共安全、公共卫生、重大公共利益有关的;</div>
<div>3、与犯罪侦查、起诉、审判和判决执行等有关的;</div>
<div>4、出于维护个人信息主体或其他个人的生命、财产等重大合法权益但又很难得到您本人同意的;</div>
<div>5、所收集的个人信息是您自行向社会公众公开的;</div>
<div>6、从合法公开披露的信息中收集个人信息的,如合法的新闻报道、政府信息公开等渠道;</div>
<div>7、根据您的要求签订合同所必需的;</div>
<div>8、用于维护所提供的产品或服务的安全稳定运行所必需的,例如发现、处置产品或服务的故障;</div>
<div>9、为合法的新闻报道所必需的;</div>
<div>10、学术研究机构基于公共利益开展统计或学术研究所必要,且对外提供学术研究或描述的结果时,对结果中所包含的个人信息进行去标识化处理的;</div>
<div>11、法律法规规定的其他情形。</div>
<div>如我们停止平台的产品或服务,我们将及时停止继续收集您个人信息的活动,对所持有的个人信息进行删除或匿名化处理。</div>
<div>6. 设备权限调用:在向您提供服务的过程中,为了实现特定的产品功能,我们会向您的设备系统申请调用以下设备权限,申请前我们会征询您的同意,您可以选择“允许”或者“禁止”权限申请。申请成功后,您可以随时进入手机“设置-权限管理”中关闭相应权限,不过权限关闭后有关产品功能可能无法正常使用,请您理解:</div>
<div>(1) 位置</div>
<div>您需要授权我们使用位置权限,以便于我们基于位置向您展示、推送急救资源,显示医院位置等信息。您在首次打开移动平台和使用相关业务时会看到弹窗提醒,询问您是否授权。</div>
<div>(2) 通讯录</div>
<div>在视话咨询时为保护医生和员工双方个人信息安全,我们提供中转电话服务。您需要授权我们使用通讯录权限,以便于我们对此电话进行标识。您在使用相应功能时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常在视话咨询中使用电话进行沟通。</div>
<div>(3) 相机、相册</div>
<div>您需要授权我们使用相机权限,以便于使用我们的核心业务功能,如在咨询中发送图片或视频通话。您在使用相应功能时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常在咨询中进行视频通话。</div>
<div>(4) 通知栏</div>
<div>您需要授权我们使用通知权限,以便于使用所有基于此权限实现的功能,如咨询状态、体检报告等各类消息提醒。您在首次打开移动平台时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常获取各类消息提醒。</div>
<div>(5) 存储</div>
<div>您需要授权我们使用存储权限,以便于在急救和咨询时候使用发送文件、图片、照片等功能,同时我们的移动平台可以写入、存储员工信息和日志等。您在首次打开移动平台和使用相应功能时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常使用使用移动平台。</div>
<div>(6) 麦克风</div>
<div>您需要授权我们使用麦克风权限,以便于使用我们的核心业务功能,如在咨询咨询中发送语音消息或视频通话。您在使用相应功能时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常在咨询中进行视频通话。</div>
<div>(7) 悬浮窗</div>
<div>您需要授权我们使用悬浮窗权限,当您在咨询/应急业务时正在进行语音/音视频通话时候您可切换APP继续使用手机其他功能。您在使用相应功能时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常在咨询中进行视频通话。</div>
<div>设备权限 使用目的</div>
<div>存储 聊天过程中发送和接收相关文件</div>
<div>相机 应急请求和咨询专家业务聊天过程中发送图片</div>
<div>相册 应急请求和咨询专家业务聊天过程中发送图片</div>
<div>位置 用于向用户提供地图上的资源数据,聊天发送位置</div>
<div>麦克风(音频) 与专家音视频交流、聊天语音输入,拍摄视频</div>
<div>悬浮窗 在其他程序页面仍能保持应用内通话</div>
<div>短信 获取验证码修改密码</div>
<div>通知栏 对您在系统内使用的业务(如预约体检、专家咨询),及时进行通知</div>
<div>拨打电话 在查看地图资源发起急救时候,跳转手机拨打电话</div>
<div>日历 找专家进行咨询、预约专家,大病就医挂号医院,预约去医院体检的日期需访问日历</div>
<div>请您注意,您开启以上权限即代表您授权我们可以收集和使用这些个人信息来实现上述的功能,您关闭权限即代表您取消了这些授权,则我们将不再继续收集和使用您的这些个人信息,也无法为您提供上述与这些授权所对应的功能。您关闭权限的决定不会影响此前基于您的授权所进行的个人信息的处理。除此以外,我们在相关业务功能中可能还需要您开启设备的其他访问权限,详细权限和使用目的如下:</div>
<div>1android.permission.INTERNET(访问网络权限):实现应用程序联网</div>
<div>2android.permission.ACCESS_WIFI_STATE(获取WiFi状态权限):监控网络变化,提示用户当前网络环境</div>
<div>3android.permission.ACCESS_NETWORK_STATE(获取网络状态权限):监控网络变化,提示用户当前网络环境</div>
<div>4android.permission.VIBRATE(使用振动权限):允许手机振动</div>
<div>5android.permission.WAKE_LOCK(唤醒锁定权限):允许程序在手机屏幕关闭后后台进程仍然运行,保持屏幕唤醒</div>
<div>6android.permission.RESTART_PACKAGES(结束系统任务权限):重新启动应用</div>
<div>7android.permission.MODIFY_AUDIO_SETTINGS(修改声音设置权限):修改全局音频设置,例如调节音量和用于输出的扬声器</div>
<div>8android.permission.BLUETOOTH(使用蓝牙权限):小程序蓝牙功能模块使用</div>
<div>9(android.permission.BLUETOOTH_ADMIN)(蓝牙管理权限):小程序蓝牙功能模块使用</div>
<div>10android.permission.SYSTEM_ALERT_WINDOW(悬浮窗权限):观看直播、短视频悬浮窗播放</div>
<div>11 android.permission.ACCESS_BACKGROUND_LOCATION(支持后台访问位置权限):保持持续定位能力</div>
<div>12android.permission.WRITE SYSTEM(读写系统设置权限):允许应用读写系统设置项</div>
<div>13android.permission.GET_TASKS(获取任务信息权限):允许应用获取当前或最近运行的应用</div>
<div>14android.permission.CHANGE_WIFI_STATE(改变WiFi状态权限):允许应用改变WiFi状态</div>
<div>15android.permission.CHANGE_NETWORK_STATE(改变网络连接状态):允许应用改变网络连接状态</div>
<div>四、我们如何使用 Cookie 和同类技术</div>
<div>1. 4.1 Cookie</div>
<div>为确保网站正常运转、为您获得更轻松的访问体验、向您推荐您可能感兴趣的内容,我们会在您的计算机或移动设备上存储名为 Cookie 的小数据文件。Cookie 通常包含标识符、站点名称以及一些号码和字符。借助于 Cookie,网站能够记住您的选择,提供个性化增强服务等。</div>
<div>您可根据自己的偏好管理或删除Cookie。有关详情,请参见 AboutCookies.org。您可以清除计算机上保存的所有 Cookie,大部分网络浏览器都设有阻止 Cookie 的功能。但如果您这么做,则需要在每一次访问平台时更改员工设置。如需详细了解如何更改浏览器设置,请访问您使用的浏览器的相关设置页面。</div>
<div>2. 4.2 网站信标和像素标签</div>
<div>除 Cookie 外,我们还会在网站上使用网站信标和像素标签等其他同类技术。例如,我们向您发送的电子邮件可能含有链接至我们网站内容的地址链接,如果您点击该链接,我们则会跟踪此次点击,帮助我们了解您的服务偏好以便于我们主动改善服务体验。网站信标通常是一种嵌入到网站或电子邮件中的透明图像。借助于电子邮件中的像素标签,我们能够获知电子邮件是否被打开。</div>
<div>五、我们如何共享、转让、公开披露您的个人信息</div>
<div>1. 共享</div>
<div>我们不会与平台服务提供者以外的任何公司、组织和个人分享您的个人信息,但以下情况除外:</div>
<div>1、在获取明确同意的情况下共享:获得您的明确同意后,我们会与其他方共享您的个人信息。</div>
<div>2、我们可能会根据法律法规规定,或按政府主管部门的强制性要求,对外共享您的个人信息。</div>
<div>3、与授权合作机构共享:仅为实现本声明和政策中声明的目的,我们的某些服务将由授权合作机构提供。我们可能会与合作机构共享您的某些个人信息,以提供更好的服务和员工体验。我们仅会出于合法、正当、必要、特定、明确的目的共享您的个人信息,并且只会共享提供服务所必要的个人信息。我们的合作机构无权将共享的个人信息用于任何其他用途。</div>
<div>目前,我们的授权合作机构包括以下类型:</div>
<div>(1)分析服务类的授权合作机构。除非得到您的许可,否则我们不会将您的个人身份信息(指可以识别您身份的信息,例如姓名或电子邮箱,通过这些信息可以联系到您或识别您的身份)与提供分析服务的合作机构分享。我们会向这些合作机构提供有关其服务覆盖面和有效性的信息,而不会提供您的个人身份信息,或者我们将这些信息进行汇总,以便它不会识别您。</div>
<div>(2)服务提供方和其他合作机构。我们将信息发送给支持我们业务的服务提供方和其他合作机构,这些支持包括提供技术基础设施服务、分析我们服务的使用方式、衡量服务的有效性、提供员工服务、支付便利或进行学术研究和调查。</div>
<div>对我们与之共享个人信息的机构,我们会与其签署严格的保密协定,要求他们按照我们的说明、声明和政策以及其他任何相关的保密和安全措施来处理个人信息。</div>
<div>2. .转让</div>
<div>除以下情形外,我们不会将您的个人信息转让给任何公司、组织或个人:</div>
<div>1)事先获得您的明确同意的;</div>
<div>(2)根据法律法规规定,或者政府主管部门、司法机关的强制要求必须对外转让的;</div>
<div>(3)涉及公司合并、分立、解散、资产或业务转让、破产清算或类似的交易时,若涉及到您的个人信息转让,我们会要求新持有您个人信息的公司、组织或个人继续受本政策的约束,否则我们将要求该等公司、组织或个人重新取得您的授权同意。</div>
<div>3. 公开披露</div>
<div>除以下情形外,我们不会公开披露您的个人信息:</div>
<div>1)事先获得您的明确同意的;</div>
<div>(2)根据法律法规规定,或者政府主管部门、司法机关的强制要求必须公开披露的。在符合法律法规的前提下,当我们收到上述披露信息的请求时,我们会要求必须出具与之相应的法律文件,如传票或调查函。我们坚信,对于要求我们提供的信息,应该在法律允许的范围内尽可能保持透明。我们对所有的请求都将进行慎重的审查,以确保其具备合法依据,且仅限于执法部门因特定调查目的且有合法权利获取的数据。</div>
<div>4. 共享、转让、公开披露个人信息授权同意的例外</div>
<div>根据相关法律法规的规定,在以下情形中,我们可以在不征得您的授权同意的情况下共享、转让、公开披露您的个人信息:</div>
<div>A.与国家安全、国防安全有关的;</div>
<div>B.与公共安全、公共卫生、重大公共利益有关的;C.与犯罪侦查、起诉、审判和判决执行等有关的;</div>
<div>D.出于维护您或其他个人的生命、财产等重大合法权益但又很难得到本人同意的;</div>
<div>E.您自行向社会公众公开的个人信息;</div>
<div>F.从合法公开披露的信息中收集到的个人信息的,如合法的新闻报道、政府信息公开等渠道。</div>
<div>G.法律法规规定的其他情形。</div>
<div>根据法律规定,共享、转让经去标识化处理的个人信息,且确保数据接收方无法复原并重新识别个人信息主体的,不属于个人信息的对外共享、转让及公开披露行为,对此类数据的保存及处理将无需另行向您通知并征得您的同意。</div>
<div>六、员工业务数据和公开信息</div>
<div>不同于您的个人信息,对于员工业务数据和公开信息,平台将按如下方式处理:</div>
<div>1. 员工业务数据</div>
<div>1、您通过平台提供的服务,加工、存储、上传、下载、分发以及通过其他方式处理的数据,均为您的员工业务数据。平台作为服务提供者,只会严格执行您的指示处理您的业务数据,除按与您协商一致或执行明确的法律法规要求外,不对您的业务数据进行任何非授权的使用或披露。</div>
<div>2、您应对您的员工业务数据来源及内容负责,平台提示您谨慎判断数据来源及内容的合法性。因您的员工业务数据内容违反法律法规、部门规章或国家政策而造成的全部结果及责任均由您自行承担。</div>
<div>3、根据您与平台协商一致,平台在您选定的数据中心存储员工业务数据。我们恪守对员工的安全承诺,根据适用的法律保护员工存储在平台数据中心的数据。</div>
<div>2. 公开信息</div>
<div>1、公开信息是指您公开分享的任何信息,任何人都可以在使用和未使用平台服务期间查看或访问这些信息。例如您在社区、论坛发布的信息。</div>
<div>2、为使用平台的服务,可能存在您必须公开分享的信息。</div>
<div>七、我们如何保护您的个人信息</div>
<div>1.我们已使用符合业界标准的安全防护措施保护您提供的个人信息,防止您的个人信息遭到未经授权访问、使用、修改、公开披露、损坏或丢失。我们会采取一切合理可行的措施,保护您的个人信息,比如:</div>
<div>(1)我们设立了网络安全和个人信息保护机构,专门负责网络安全和个人信息保护事务;</div>
<div>(2)我们的网络服务采取了传输层安全协议等加密技术,通过https等方式提供浏览服务,确保用户数据在传输过程中的安全;</div>
<div>(3)我们采取MD5、SHA256等加密技术对您的个人信息进行加密存储,增强个人信息在使用中的安全性;</div>
<div>(4)我们采用严格的数据访问权限控制和多重身份认证技术保护个人信息,避免数据被违规使用;</div>
<div>(5)我们采用代码安全检查、数据访问日志分析技术进行个人信息安全审计;</div>
<div>(6)我们建立了客户信息保护管理规定、客户信息分级分类管理规定、日常操作规程等一系列管理制度来规范个人信息的存储和使用;</div>
<div>(7)我们定期举办信息安全和个人信息保护培训课程,加强员工对于个人信息保护重要性的认识;</div>
<div>(8)我们与所有可能接触个人信息的员工签订了保密协议,对关键岗位人员进行背景审查,并建立了严格的访问权限控制、权限审批流程和监控、审计机制;</div>
<div>(9)我们与所有可能接触用户个人信息的合作伙伴均签署了严格的保密协议或数据保护专用条款,并要求可能接触到您个人信息的所有人员履行相应的保密和数据保护义务。如果第三方合作伙伴未履行保密和数据保护义务,可能会被我们追究法律责任并被我们终止合作;</div>
<div>2.我们已经通过了国家信息安全等级保护测评和备案,最高备案等级为二级。</div>
<div>3.我们会采取一切合理可行的措施,确保未收集无关的个人信息。我们只会在达成本政策所述目的所需的期限内保留您的个人信息,除非需要延长保留期或者受到法律允许。</div>
<div>4.互联网并非绝对安全的环境,而且电子邮件、即时通讯、社交软件等与其他用户的交流方式无法确定是否完全加密,我们强烈建议您不用通过此类方式发送个人信息。若确需使用,在使用此类工具时请使用复杂密码,并注意保护您的个人信息安全。我们将尽力保障您个人信息的安全性。如果我们的物理、技术、或管理防护设施遭到破坏,导致信息被非授权访问、公开披露、篡改、或毁坏,导致您的合法权益受损,我们将全力配合保护您的权益,并依法承担我们应承担的赔偿责任。</div>
<div>5.在不幸发生个人信息安全事件后,我们将按照法律法规的要求及时向您告知安全事件的基本情况和可能的影响、我们已采取或将采取的处置措施、您可自主防范和降低风险的建议、对您的补救措施等。我们将及时将事件相关情况以邮件、信函、电话、推送通知等方式告知您,难以逐一告知时,我们会采取合理、有效的方式发布公告。同时,我们还将按照监管部门要求,主动上报个人信息安全事件的处置情况。</div>
<div>八、您如何管理您的个人信息(您的权力)</div>
<div>您可以通过以下方式访问及管理您的个人信息:</div>
<div>8.1 访问您的个人信息</div>
<div>您的账号信息:您可在“我的”中查询您的账户、姓名、性别、手机、身份证号、工作信息、健康类型、学历、工号、工种、住址,紧急联系人的姓名、电话等。</div>
<div>您和您亲属的健康信息:您可在“咨询人管理”中查询您和您亲属手机号码、患者姓名、性别、出生日期、与患者的关系、身高体重、所在城市;健康信息:病症、患病时长、体检报告、住院记录、诊治情况、用药记录、以往病史、过敏信息、家族史、患病史等健康信息。</div>
<div>您的订单、工单信息:您可在“我的-我的咨询”、“我的-我的应急工单”、“我的-大病就医工单”、“健康体检-体检预约”等各个业务的对应入口查看、评价订单和工单信息。</div>
<div>您的体检报告:你可在“健康体检-体检报告”和“健康档案-健康现状”、“健康档案-体检数据分析”查看个人的体检报告详情和重点指标的分析。</div>
<div>对于您在使用我们的产品或服务过程中向我们提供或产生的其他信息,只要我们不需要过多投入,我们会向您提供。您可以通过拨打我们的客服电话提出访问申请,我们将在30天内回复您的访问请求。</div>
<div>对于您在使用我们服务过程中产生的其他个人信息,我们将根据本条“8.9 响应您的上述请求”中的相关安排向您提供。</div>
<div>8.2 更正或补充您的个人信息</div>
<div>当您发现我们处理的您的个人信息有误或者您需要更正该等信息时,您可以通过内设置的自动更正功能、电子邮件或者拨打客服电话等方式进行修改或更正。您如果需要更正其他个人信息,可通过联系人工客服向我们提出更正申请。</div>
<div>可自主更正的信息:</div>
<div>账号信息:您可在“我的”中更新您的头像,紧急联系人的姓名、电话等。</div>
<div>您和您亲属的健康信息:您可在“咨询人管理”中更正您和您亲属手机号码、患者姓名、性别、出生日期、与患者的关系、身高体重、所在城市;健康信息:病症、患病时长、体检报告、住院记录、诊治情况、用药记录、以往病史、过敏信息、家族史、患病史等健康信息。</div>
<div>8.3 如何注销</div>
<div>您在我们的产品与/或服务页面中可以直接清除或删除的信息,包括浏览信息、紧急联系人信息、咨询人信息。</div>
<div>在以下情形中,您可以向我们提出删除个人信息的请求:</div>
<div>(1)如果我们处理个人信息的行为违反了法律法规的强制性规定;</div>
<div>(2)如果我们收集、使用您的个人信息,却未征得您的同意(依法无需征得同意的情况除外);</div>
<div>(3)如果我们处理个人信息的行为违反了与您的约定;</div>
<div>(4)如果您不再使用我们的产品或服务,或您注销了账号;</div>
<div>5)如果我们不再为您提供产品或服务。</div>
<div>如果您想删除或注册账号:</div>
<div>(1)拨打客服热线电话029-86618899</div>
<div>2)发送电子邮件至40115111@qq.com</div>
<div>(3)邮寄地址:陕西省西安市未央区欧亚大道丝路国际创意梦工场5号楼,收件人:许策</div>
<div>收到您的删除请求后,我们会根据您及相关法律法规的要求进行后续删除处理并向您反馈结果。若我们决定响应您的删除请求,我们还将同时通知从我们获得您的个人信息的实体,要求其及时删除,除非法律法规另有规定,或这些实体获得您的独立授权。</div>
<div>当您从我们的服务中删除信息后,我们可能不会立即备份系统中删除相应的信息,但会在备份更新时删除这些信息。</div>
<div>8.4 改变您授权同意的范围</div>
<div>您可以通过删除信息、关闭设备功能、在平台中进行隐私设置等方式改变您授权我们继续收集个人信息的范围或撤回您的授权。</div>
<div>请您理解,每个业务功能需要一些基本的个人信息才能得以完成(见本隐私权政策“我们如何收集和使用您的信息”)。当您收回同意后,我们将不再处理相应的个人信息。但您收回同意的决定,不会影响此前基于您的授权而开展的个人信息处理。</div>
<div>8.5 个人信息主体注销账户</div>
<div>在符合平台单项服务的服务协议约定条件及国家相关法律法规规定的情况下,您的该项平台服务帐号可能被注销或删除。当帐号注销或被删除后,与该帐号相关的、该单项服务项下的全部服务资料和数据将依照单项服务的服务协议约定删除或匿名化处理。</div>
<div>8.6 约束信息系统自动决策</div>
<div>在某些业务功能中,我们可能仅依据信息系统、算法等在内的非人工自动决策机制做出决定。如果这些决定显著影响您的合法权益,您有权要求我们做出解释,我们也将在不侵害平台保密或其他员工权益、社会公共利益的前提下提供申诉方法。</div>
<div>8.7约束信息系统自动决策</div>
<div>在某些业务功能中,我们可能仅依据信息系统、算法在内的非人工自动决策机制作出决定。如果这些决定显著影响您的合法权益,您有权要求我们作出解释,我们也将提供适当的救济方式。</div>
<div>8.8举报和投诉</div>
<div>如果您发现您的个人信息可能被泄露,或者我们的工作人员或合作伙伴在处理您的个人信息时有任何违法违规行为,您可以通过拨打客服热线或者发送电子邮件的方式向我们进行举报和投诉。</div>
<div>8.9 响应您的上述请求</div>
<div>为保障安全,您可能需要提供书面请求,或以其他方式证明您的身份。我们可能会先要求您验证自己的身份,然后再处理您的请求。我们将在15个工作日内做出答复。</div>
<div>对于那些无端重复、需要过多技术手段(例如,需要开发新系统或从根本上改变现行惯例)、给他人合法权益带来风险或者非常不切实际的请求,我们可能会予以拒绝。</div>
<div>在以下情形中,按照法律法规要求,我们将无法响应您的请求:</div>
<div>(1) 与国家安全、国防安全有关的;</div>
<div>(2) 与公共安全、公共卫生、重大公共利益有关的;</div>
<div>(3) 与犯罪侦查、起诉、审判和执行判决等有关的;</div>
<div>(4) 有充分证据表明个人信息主体存在主观恶意或滥用权利的;</div>
<div>(5) 响应您的请求将导致您或其他个人、组织的合法权益受到严重损害的;</div>
<div>(6) 涉及商业秘密的。</div>
<div>九、我们如何处理未成年人的个人信息</div>
<div>1.健康咨询专家端非常重视对未成年人个人信息的保护。若您是18周岁以下的未成年人,在使用我们的产品与/或服务前,应事先取得您监护人的同意。健康咨询专家端根据国家相关法律法规的规定保护未成年人的个人信息。</div>
<div>2.我们不会主动直接向未成年人收集其个人信息。对于经监护人同意而收集未成年人个人信息的情况,我们只会在受到法律允许、监护人同意或者保护未成年人所必要的情况下使用、共享、转让或披露此信息。</div>
<div>3.如果有事实证明未成年人在未取得监护人同意的情况下注册使用了我们的产品与/或服务,我们会与相关监护人协商,并设法尽快删除相关个人信息。</div>
<div>十、本声明和政策如何更新</div>
<div>我们的隐私政策可能变更。未经您明确同意,我们不会削减您按照声明和政策所应享有的权利。 我们会在本页面上发布对本声明和政策所做的任何变更。</div>
<div>对于重大变更,我们还会提供更为显著的通知(包括我们会通过网站公示的方式进行通知甚至向您提供弹窗提示)。</div>
<div>本声明和隐私所指的重大变更包括但不限于:</div>
<div>1、 我们的服务模式发生重大变化。如处理个人信息的目的、处理的个人信息类型、个人信息的使用方式等;</div>
<div>2、 我们在所有权结构、组织架构等方面发生重大变化。如业务调整等引起的所有者变更等;</div>
<div>3、 个人信息共享或公开披露的主要对象发生变化;</div>
<div>4、 您参与个人信息处理方面的权利及其行使方式发生重大变化;</div>
<div>5、 我们负责处理个人信息安全的责任部门、联络方式等发生变化时;</div>
<div>6、 个人信息安全影响评估报告表明存在高风险时。</div>
<div>7、 我们还会将本声明和隐私的旧版本存档,供您查阅。</div>
<div>十一、如何联系我们</div>
<div>1.如果您对本政策有任何疑问、意见或建议,可通过以下方式与我们联系:</div>
<div>(1)拨打客服热线电话029-86618899</div>
<div>2)发送电子邮件至chentianyu_cq@petrochina.com.cn</div>
<div>(3)邮寄地址:陕西省西安市未央区未央路151号,收件人:员工健康服务部</div>
<!-- <div>我们的客服部门将会同个人信息保护部门30天内进行回复,并协助解决您的问题。</div>-->
<div>2.如果您对我们的回复不满意,特别是我们的个人信息处理行为损害了您的合法权益,您还可以通过以下外部途径寻求解决方式:向网信、工商、公安等监管部门进行投诉或举报。</div>
</div>
</body>
</html>
-300
View File
@@ -1,300 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>隐私权政策</title>
</head>
<style>
html,body {
padding: 0;
margin: 0;
}
html,body,#zwb{
box-sizing: border-box;
overflow: hidden auto;
font-size: 22px;
}
html::-webkit-scrollbar {
width: 0;
}
body::-webkit-scrollbar {
width: 0;
}
#zwb {
padding: 25px;
width: 100%;
height: 100%;
overflow: hidden auto;
}
div {
margin: 0 0 10px;
}
.title-one {
text-align: center;
margin: 5px 0
}
</style>
<body>
<div id="zwb">
<h3 class="title-one">隐私权政策</h3>
<div>本平台由西安仁康信息科技有限公司开发和运维,平台深知个人信息对您的重要性,并会尽全力保护您的个人信息安全可靠。我们致力于维持您对我们的信任,恪守以下原则,保护您的个人信息:权责一致原则、目的明确原则、选择同意原则、最少够用原则、确保安全原则、主体参与原则、公开透明原则等。同时,我们承诺将采取相应的安全保护措施来保护您的个人信息。请在使用平台服务前,仔细阅读并了解本隐私权政策,我们将按照本政策收集、处理及披露您的信息。</div>
<div>本政策将帮助您了解以下内容:</div>
<div>1、定义</div>
<div>2、我们可能收集的信息</div>
<div>3、我们如何收集和使用您的个人信息</div>
<div>4、我们如何使用 Cookie 和同类技术</div>
<div>5、我们如何共享、转让、公开披露您的个人信息</div>
<div>6、员工业务数据和公开信息</div>
<div>7、我们如何保护您的个人信息</div>
<div>8、您如何管理您的个人信息</div>
<div>9、我们如何处理未成年人的个人信息</div>
<div>10、本声明和政策如何更新</div>
<div>11、如何联系我们</div>
<div>一、定义</div>
<div>1. 个人信息:</div>
<div>指以电子或者其他方式记录的与已识别或者可识别的自然人有关的各种信息,不包括匿名化处理后的信息</div>
<div>2. 个人健康信息</div>
<div>指以电子或者其他方式记录的能够单独或者与其他信息结合识别特定自然人身份或者反映特定自然人活动情况的各种健康信息,一旦泄露或者非法使用,可能导致个人受到歧视或者人身、财产受到严重危害的个人信息,包括如姓名、出生日期、身份证件号码、体检信息、就医信息、住址、通讯联系方式、通信记录和内容、账号密码、行踪轨迹、民族、个人生物特征、医疗健康、金融账户、个人行踪、不满十四周岁未成年人信息等。</div>
<div>3. 未成年人:指不满18周岁的自然人。</div>
<div>4. 儿童:指不满14周岁的自然人。</div>
<div>5. 设备信息</div>
<div>包括设备标识符 (IMEI、IDFA、MAC、OAID、IMSI、SIM 卡序列号 (ICCID) 、设备序列号及其他设备相关信息),应用信息 (应用崩溃信息、通知开关状态、运行中进程、应用安装列表及其他应用相关信息) ,设备参数及系统信息(设备类型、设备型号、操作系统及硬件相关信息),设备网络环境信息 (IP地址,WiFi信息,基站信息及其他网络相关信息),蓝牙信息,广播组件通讯信息,运营商信息,传感器 (陀螺仪、重力传感器、加速度传感器、环境传感器、光学心率传感器),剪切板。以产品实际采集情况为准。</div>
<div>6. 业务数据</div>
<div>不同于个人信息,是指平台员工利用平台的服务上传、下载、分发等通过平台的技术服务处理的数据。</div>
<div>二、我们可能收集的信息</div>
<div>我们提供服务时,可能会收集、储存和使用下列与个人有关的信息。如果您不提供相关信息,可能无法注册成为平台员工或无法享受平台的某些服务,或者无法达到相关服务拟达到的效果。</div>
<div>2.1 与个人身份无关</div>
<div>当您使用平台的服务时,我们可能收集和汇总诸如员工的来源途径、访问顺序、停留时间等信息,例如记录使用平台服务的每个员工的来源途径、浏览器软件等。</div>
<div>2.2 与个人身份有关</div>
<div>当您使用平台的服务时,我们可能收集和汇总或要求您提供有关个人身份的信息,例如:</div>
<div>(1) 个人身份证明(包括身份证图片和身份证号、手机号、邮箱等);</div>
<div>(2) 个人补充信息(姓名、生日、籍贯、性别、兴趣爱好、学历、个人联系电话、住址、工作信息、婚姻状况、健康状况、;</div>
<div>(3) 网络身份标识信息(包括系统账号、IP地址、电子邮箱地址及与前述有关的密码、口令、口令保护答案、个人数字证书等);</div>
<div>(4) 个人健康信息(包括:姓名、性别、出生日期、身高体重、就诊卡、所在城市,所患病症、患病时长、体检报告、住院记录、诊治情况、检验报告、体检报告、用药记录、以往病史、过敏信息、家族史、患病史等,和历史咨询记录。</div>
<div>(5) 相机、相册(设备的相机功能,以拍摄照片或录制视频);</div>
<div>(6) 麦克风(通话、发送录音文件);</div>
<div>(7) 悬浮窗(在其他程序页面仍能保持应用内通话);</div>
<div>(8) 日历(访问用户的日历,以便将预约信息添加到日历中);</div>
<div>(9) 存储(访问设备存储器中的文件、照片和视频);</div>
<div>(10) 个人上网记录和日志信息(包括网站浏览记录、软件使用记录、点击记录、操作日志等);</div>
<div>(11) 设备信息(包括设备型号、设备MAC地址、操作系统类型、设备设置);</div>
<div>(12) 软件列表唯一设备识别码(如IMEI ID/IDFA/OPENUDID/GUID、SIM卡IMSI信息等在内的描述个人常用设备基本情况的信息);</div>
<div>(13) 拨打电话(唤起手机拨号界面并自动填充电话)</div>
<div>(14) 个人位置信息(包括精准定位信息、经纬度等);</div>
<div>(15) 其他平台基于为您提供服务需要而收集或汇总的您的信息。</div>
<div>三、我们如何收集和使用您的个人信息</div>
<div>1. 您直接提供的信息:我们可能会收集您在健康咨询专家端注册账号、申请或使用我们的服务时填写,通过现场交谈、电话、视频或其他联系方式与我们联系时所提供的信息,以及您在使用我们服务过程中产生的与您的交易和活动有关的信息。</div>
<div>(1) 帮助您成为我们的一员</div>
<div>您需要向平台提供真实姓名、邮箱、有效身份证件(包括但不限于身份证)的号码,以便于我们进行实名认证。您可以修改和补充您的昵称、性别、生日、职级、职称、学历、亲属、紧急联系人、工作信息(单位部门)、婚姻状况、健康类型、兴趣爱好以及您的实名认证等一系列相关信息相关信息,这些信息均属于您的“账号信息”。您补充的账户信息将有助于我们为您提供与您信息更匹配的相关业务服务(急救协助、医院体检、健康知识推送等)。如果您不提供这些信息,可能会影响您对平台部分核心业务功能的正常使用,如咨询专家等,但不会影响您进行基本的浏览、搜索。如果您不提供这些信息,将会影响您使用平台的部分功能,如咨询专家,但不会影响您使用平台服务的基本浏览、搜索功能。在您主动注销账号时,我们将根据相关法律法规的要求尽快使其匿名或删除您的个人信息。</div>
<div>(2) 咨询专家</div>
<div>为便于您能够咨询专家,您需提供真实姓名、手机号、身份证号码、性别、出生日期、身高体重等信息。为更好地向您提供咨询服务解决您的问题,更加精准、快速地向您推荐医生,我们可能需要您在健康咨询时提供个人健康信息,例如:病症、患病时长、检验报告、体检报告、医院就诊信息、诊治情况、用药记录、以往病史、过敏信息、家族史、患病史等。如您不提供上述信息,将会影响您使用部分健康咨询等功能,但不影响您使用平台产品或服务的基本浏览、搜索功能。应急救援</div>
<div>(1) 您实名成为健康咨询专家端的用户后,若您或您的朋友发生了意外事件,你可以通过查看系统内的相关医疗资源,并向平台发起帮助请求。在此过程中,我们可能会通过您的基本信息和聊天功能获取您的手机号、您的紧急联系人姓名和联系 电话,位置、姓名、性别、年龄、健康状况、事故详情介绍的图文、音视频沟通的信息。搜索</div>
<div>(2) 搜索</div>
<div>为了让您快速地找到您所需要的专家、知识文章、软件功能、医院等,我们可能会收集您使用我们的产品记录为您提供这些信息展示的最优方式。我们也会为了不断改进和优化上述的功能来使用您的上述个人信息。</div>
<div>您也可以通过搜索来精准地找到您所需要的专家、医院、系统功能。我们会保留您的搜索内容以方便您重复输入或为您展示与您搜索内容相关联的产品或服务。</div>
<div>2. 我们在您使用服务过程中收集的信息</div>
<div>为向您提供更契合您需求的页面展示和搜索结果、了解服务适配性、识别账号异常状态,我们会收集关于您使用的服务以及使用方式的信息并将这些信息进行关联,这些信息包括:</div>
<div>设备信息:我们会根据您在软件安装及使用中授予的具体权限,接收并记录您所使用的设备相关信息(例如设备型号、操作系统版本、设备设置、唯一设备标识符等软硬件特征信息)、设备所在位置相关信息(例如IP 地址、GPS位置以及能够提供相关信息的Wi-Fi 接入点、蓝牙和基站等传感器信息)。</div>
<div>日志信息:当您使用我们的网站或用户端提供的服务时,我们会自动收集您对我们服务的详细使用情况,作为有关网络日志保存。例如您的搜索查询内容、IP地址、浏览器的类型、电信运营商、使用的语言、访问日期和时间及您访问的网页记录等。</div>
<div>请注意,单独的设备信息、日志信息等是无法识别特定自然人身份的信息。如果我们将这类非个人信息与其他信息结合用于识别特定自然人身份,或者将其与个人信息结合使用,则在结合使用期间,这类非个人信息将被视为个人信息,除取得您授权或法律法规另有规定外,我们会将该类个人信息做匿名化、去标识化处理。</div>
<div>为展示您的健康信息,我们会收集您在使用我们服务过程中产生的健康咨询详情(包括但不限于图片、文字、视频、语音)、预约挂号记录、咨询记录、个人健康信息、检查检验、医生诊断结果等用于向您展示及便于您对信息进行管理。</div>
<div>当您与我们联系时,我们可能会保存您的通信/通话记录和内容或您留下的联系方式等信息,以便与您联系或帮助您解决问题,或记录相关问题的处理方案及结果。</div>
<div>3. 我们通过间接获得方式收集到的您的个人信息</div>
<div>我们可能从第三方获取您授权共享的账户信息(头像、昵称、联系方式),并在您同意声明和政策后将您的第三方账户与您的账户绑定,使您可以通过第三方账户直接登录并使用平台服务。我们会将依据与第三方的约定、对个人信息来源的合法性进行确认后,在符合相关法律和法规规定的前提下,使用您的这些个人信息。</div>
<div>如您拒绝提供上述信息或拒绝授权,可能无法使用我们的相应服务,或者无法展示相关信息,但不影响使用平台的健康咨询等核心服务。</div>
<div>为您提供安全保障</div>
<div>请注意,为向您提供更好的安全保障,您可以向我们提供姓名、身份证、就诊卡、邮箱等身份信息完成实名认证。如您拒绝提供上述信息,可能无法预约或咨询特定专家、继续可能存在风险的操作等,但不会影响您使用浏览、搜索等服务。</div>
<div>为提高您使用我们提供服务的安全性,更好地预防钓鱼网站、欺诈、网络漏洞、计算机病毒、网络攻击、网络侵入等安全风险,更准确地识别违反法律法规或平台相关协议规则的情况,我们可能使用或整合您的账户信息、交易信息、设备信息、有关网络日志以及我们取得您授权或依据法律共享的信息,来进行身份验证、检测及防范安全事件,并依法采取必要的记录、审计、分析、处置措施。</div>
<div>4. 其他用途</div>
<div>我们将信息用于本声明和政策未载明的其他用途,或者将基于特定目的收集而来的信息用于其他目的时,会事先征求您的同意。</div>
<div>5. 征得授权同意的例外</div>
<div>根据相关法律法规规定,以下情形中收集您的个人信息无需征得您的授权同意:</div>
<div>1、与国家安全、国防安全有关的;</div>
<div>2、与公共安全、公共卫生、重大公共利益有关的;</div>
<div>3、与犯罪侦查、起诉、审判和判决执行等有关的;</div>
<div>4、出于维护个人信息主体或其他个人的生命、财产等重大合法权益但又很难得到您本人同意的;</div>
<div>5、所收集的个人信息是您自行向社会公众公开的;</div>
<div>6、从合法公开披露的信息中收集个人信息的,如合法的新闻报道、政府信息公开等渠道;</div>
<div>7、根据您的要求签订合同所必需的;</div>
<div>8、用于维护所提供的产品或服务的安全稳定运行所必需的,例如发现、处置产品或服务的故障;</div>
<div>9、为合法的新闻报道所必需的;</div>
<div>10、学术研究机构基于公共利益开展统计或学术研究所必要,且对外提供学术研究或描述的结果时,对结果中所包含的个人信息进行去标识化处理的;</div>
<div>11、法律法规规定的其他情形。</div>
<div>如我们停止平台的产品或服务,我们将及时停止继续收集您个人信息的活动,对所持有的个人信息进行删除或匿名化处理。</div>
<div>6. 设备权限调用:在向您提供服务的过程中,为了实现特定的产品功能,我们会向您的设备系统申请调用以下设备权限,申请前我们会征询您的同意,您可以选择“允许”或者“禁止”权限申请。申请成功后,您可以随时进入手机“设置-权限管理”中关闭相应权限,不过权限关闭后有关产品功能可能无法正常使用,请您理解:</div>
<div>(1) 位置</div>
<div>您需要授权我们使用位置权限,以便于我们基于位置向您展示、推送急救资源,显示医院位置等信息。您在首次打开移动平台和使用相关业务时会看到弹窗提醒,询问您是否授权。</div>
<div>(2) 通讯录</div>
<div>在视话咨询时为保护医生和员工双方个人信息安全,我们提供中转电话服务。您需要授权我们使用通讯录权限,以便于我们对此电话进行标识。您在使用相应功能时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常在视话咨询中使用电话进行沟通。</div>
<div>(3) 相机、相册</div>
<div>您需要授权我们使用相机权限,以便于使用我们的核心业务功能,如在咨询中发送图片或视频通话。您在使用相应功能时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常在咨询中进行视频通话。</div>
<div>(4) 通知栏</div>
<div>您需要授权我们使用通知权限,以便于使用所有基于此权限实现的功能,如咨询状态、体检报告等各类消息提醒。您在首次打开移动平台时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常获取各类消息提醒。</div>
<div>(5) 存储</div>
<div>您需要授权我们使用存储权限,以便于在急救和咨询时候使用发送文件、图片、照片等功能,同时我们的移动平台可以写入、存储员工信息和日志等。您在首次打开移动平台和使用相应功能时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常使用使用移动平台。</div>
<div>(6) 麦克风</div>
<div>您需要授权我们使用麦克风权限,以便于使用我们的核心业务功能,如在咨询咨询中发送语音消息或视频通话。您在使用相应功能时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常在咨询中进行视频通话。</div>
<div>(7) 悬浮窗</div>
<div>您需要授权我们使用悬浮窗权限,当您在咨询/应急业务时正在进行语音/音视频通话时候您可切换APP继续使用手机其他功能。您在使用相应功能时会看到弹窗提醒,询问您是否授权。如您拒绝授权,可能无法正常在咨询中进行视频通话。</div>
<div>设备权限 使用目的</div>
<div>存储 聊天过程中发送和接收相关文件</div>
<div>相机 应急请求和咨询专家业务聊天过程中发送图片</div>
<div>相册 应急请求和咨询专家业务聊天过程中发送图片</div>
<div>位置 用于向用户提供地图上的资源数据,聊天发送位置</div>
<div>麦克风(音频) 与专家音视频交流、聊天语音输入,拍摄视频</div>
<div>悬浮窗 在其他程序页面仍能保持应用内通话</div>
<div>短信 获取验证码修改密码</div>
<div>通知栏 对您在系统内使用的业务(如预约体检、专家咨询),及时进行通知</div>
<div>拨打电话 在查看地图资源发起急救时候,跳转手机拨打电话</div>
<div>日历 找专家进行咨询、预约专家,大病就医挂号医院,预约去医院体检的日期需访问日历</div>
<div>请您注意,您开启以上权限即代表您授权我们可以收集和使用这些个人信息来实现上述的功能,您关闭权限即代表您取消了这些授权,则我们将不再继续收集和使用您的这些个人信息,也无法为您提供上述与这些授权所对应的功能。您关闭权限的决定不会影响此前基于您的授权所进行的个人信息的处理。除此以外,我们在相关业务功能中可能还需要您开启设备的其他访问权限,详细权限和使用目的如下:</div>
<div>1)访问网络权限:实现应用程序联网</div>
<div>(2)获取WiFi状态权限:监控网络变化,提示用户当前网络环境</div>
<div>(3)获取网络状态权限:监控网络变化,提示用户当前网络环境</div>
<div>4)使用振动权限:允许手机振动</div>
<div>(5)唤醒锁定权限:允许程序在手机屏幕关闭后后台进程仍然运行,保持屏幕唤醒</div>
<div>6)结束系统任务权限:重新启动应用</div>
<div>(7)修改声音设置权限:修改全局音频设置,例如调节音量和用于输出的扬声器</div>
<div>(8)使用蓝牙权限:小程序蓝牙功能模块使用</div>
<div>(9)蓝牙管理权限:小程序蓝牙功能模块使用</div>
<div>(10)悬浮窗权限:观看直播、短视频悬浮窗播放</div>
<div>(11)支持后台访问位置权限:保持持续定位能力</div>
<div>(12)读写系统设置权限:允许应用读写系统设置项</div>
<div>(13)获取任务信息权限:允许应用获取当前或最近运行的应用</div>
<div>(14)改变WiFi状态权限:允许应用改变WiFi状态</div>
<div>(15)改变网络连接状态:允许应用改变网络连接状态</div>
<div>四、我们如何使用 Cookie 和同类技术</div>
<div>1. 4.1 Cookie</div>
<div>为确保网站正常运转、为您获得更轻松的访问体验、向您推荐您可能感兴趣的内容,我们会在您的计算机或移动设备上存储名为 Cookie 的小数据文件。Cookie 通常包含标识符、站点名称以及一些号码和字符。借助于 Cookie,网站能够记住您的选择,提供个性化增强服务等。</div>
<div>您可根据自己的偏好管理或删除Cookie。有关详情,请参见 AboutCookies.org。您可以清除计算机上保存的所有 Cookie,大部分网络浏览器都设有阻止 Cookie 的功能。但如果您这么做,则需要在每一次访问平台时更改员工设置。如需详细了解如何更改浏览器设置,请访问您使用的浏览器的相关设置页面。</div>
<div>2. 4.2 网站信标和像素标签</div>
<div>除 Cookie 外,我们还会在网站上使用网站信标和像素标签等其他同类技术。例如,我们向您发送的电子邮件可能含有链接至我们网站内容的地址链接,如果您点击该链接,我们则会跟踪此次点击,帮助我们了解您的服务偏好以便于我们主动改善服务体验。网站信标通常是一种嵌入到网站或电子邮件中的透明图像。借助于电子邮件中的像素标签,我们能够获知电子邮件是否被打开。</div>
<div>五、我们如何共享、转让、公开披露您的个人信息</div>
<div>1. 共享</div>
<div>我们不会与平台服务提供者以外的任何公司、组织和个人分享您的个人信息,但以下情况除外:</div>
<div>1、在获取明确同意的情况下共享:获得您的明确同意后,我们会与其他方共享您的个人信息。</div>
<div>2、我们可能会根据法律法规规定,或按政府主管部门的强制性要求,对外共享您的个人信息。</div>
<div>3、与授权合作机构共享:仅为实现本声明和政策中声明的目的,我们的某些服务将由授权合作机构提供。我们可能会与合作机构共享您的某些个人信息,以提供更好的服务和员工体验。我们仅会出于合法、正当、必要、特定、明确的目的共享您的个人信息,并且只会共享提供服务所必要的个人信息。我们的合作机构无权将共享的个人信息用于任何其他用途。</div>
<div>目前,我们的授权合作机构包括以下类型:</div>
<div>(1)分析服务类的授权合作机构。除非得到您的许可,否则我们不会将您的个人身份信息(指可以识别您身份的信息,例如姓名或电子邮箱,通过这些信息可以联系到您或识别您的身份)与提供分析服务的合作机构分享。我们会向这些合作机构提供有关其服务覆盖面和有效性的信息,而不会提供您的个人身份信息,或者我们将这些信息进行汇总,以便它不会识别您。</div>
<div>(2)服务提供方和其他合作机构。我们将信息发送给支持我们业务的服务提供方和其他合作机构,这些支持包括提供技术基础设施服务、分析我们服务的使用方式、衡量服务的有效性、提供员工服务、支付便利或进行学术研究和调查。</div>
<div>对我们与之共享个人信息的机构,我们会与其签署严格的保密协定,要求他们按照我们的说明、声明和政策以及其他任何相关的保密和安全措施来处理个人信息。</div>
<div>2. .转让</div>
<div>除以下情形外,我们不会将您的个人信息转让给任何公司、组织或个人:</div>
<div>1)事先获得您的明确同意的;</div>
<div>(2)根据法律法规规定,或者政府主管部门、司法机关的强制要求必须对外转让的;</div>
<div>(3)涉及公司合并、分立、解散、资产或业务转让、破产清算或类似的交易时,若涉及到您的个人信息转让,我们会要求新持有您个人信息的公司、组织或个人继续受本政策的约束,否则我们将要求该等公司、组织或个人重新取得您的授权同意。</div>
<div>3. 公开披露</div>
<div>除以下情形外,我们不会公开披露您的个人信息:</div>
<div>1)事先获得您的明确同意的;</div>
<div>(2)根据法律法规规定,或者政府主管部门、司法机关的强制要求必须公开披露的。在符合法律法规的前提下,当我们收到上述披露信息的请求时,我们会要求必须出具与之相应的法律文件,如传票或调查函。我们坚信,对于要求我们提供的信息,应该在法律允许的范围内尽可能保持透明。我们对所有的请求都将进行慎重的审查,以确保其具备合法依据,且仅限于执法部门因特定调查目的且有合法权利获取的数据。</div>
<div>4. 共享、转让、公开披露个人信息授权同意的例外</div>
<div>根据相关法律法规的规定,在以下情形中,我们可以在不征得您的授权同意的情况下共享、转让、公开披露您的个人信息:</div>
<div>A.与国家安全、国防安全有关的;</div>
<div>B.与公共安全、公共卫生、重大公共利益有关的;C.与犯罪侦查、起诉、审判和判决执行等有关的;</div>
<div>D.出于维护您或其他个人的生命、财产等重大合法权益但又很难得到本人同意的;</div>
<div>E.您自行向社会公众公开的个人信息;</div>
<div>F.从合法公开披露的信息中收集到的个人信息的,如合法的新闻报道、政府信息公开等渠道。</div>
<div>G.法律法规规定的其他情形。</div>
<div>根据法律规定,共享、转让经去标识化处理的个人信息,且确保数据接收方无法复原并重新识别个人信息主体的,不属于个人信息的对外共享、转让及公开披露行为,对此类数据的保存及处理将无需另行向您通知并征得您的同意。</div>
<div>六、员工业务数据和公开信息</div>
<div>不同于您的个人信息,对于员工业务数据和公开信息,平台将按如下方式处理:</div>
<div>1. 员工业务数据</div>
<div>1、您通过平台提供的服务,加工、存储、上传、下载、分发以及通过其他方式处理的数据,均为您的员工业务数据。平台作为服务提供者,只会严格执行您的指示处理您的业务数据,除按与您协商一致或执行明确的法律法规要求外,不对您的业务数据进行任何非授权的使用或披露。</div>
<div>2、您应对您的员工业务数据来源及内容负责,平台提示您谨慎判断数据来源及内容的合法性。因您的员工业务数据内容违反法律法规、部门规章或国家政策而造成的全部结果及责任均由您自行承担。</div>
<div>3、根据您与平台协商一致,平台在您选定的数据中心存储员工业务数据。我们恪守对员工的安全承诺,根据适用的法律保护员工存储在平台数据中心的数据。</div>
<div>2. 公开信息</div>
<div>1、公开信息是指您公开分享的任何信息,任何人都可以在使用和未使用平台服务期间查看或访问这些信息。例如您在社区、论坛发布的信息。</div>
<div>2、为使用平台的服务,可能存在您必须公开分享的信息。</div>
<div>七、我们如何保护您的个人信息</div>
<div>1.我们已使用符合业界标准的安全防护措施保护您提供的个人信息,防止您的个人信息遭到未经授权访问、使用、修改、公开披露、损坏或丢失。我们会采取一切合理可行的措施,保护您的个人信息,比如:</div>
<div>(1)我们设立了网络安全和个人信息保护机构,专门负责网络安全和个人信息保护事务;</div>
<div>(2)我们的网络服务采取了传输层安全协议等加密技术,通过https等方式提供浏览服务,确保用户数据在传输过程中的安全;</div>
<div>(3)我们采取MD5、SHA256等加密技术对您的个人信息进行加密存储,增强个人信息在使用中的安全性;</div>
<div>(4)我们采用严格的数据访问权限控制和多重身份认证技术保护个人信息,避免数据被违规使用;</div>
<div>(5)我们采用代码安全检查、数据访问日志分析技术进行个人信息安全审计;</div>
<div>(6)我们建立了客户信息保护管理规定、客户信息分级分类管理规定、日常操作规程等一系列管理制度来规范个人信息的存储和使用;</div>
<div>(7)我们定期举办信息安全和个人信息保护培训课程,加强员工对于个人信息保护重要性的认识;</div>
<div>(8)我们与所有可能接触个人信息的员工签订了保密协议,对关键岗位人员进行背景审查,并建立了严格的访问权限控制、权限审批流程和监控、审计机制;</div>
<div>(9)我们与所有可能接触用户个人信息的合作伙伴均签署了严格的保密协议或数据保护专用条款,并要求可能接触到您个人信息的所有人员履行相应的保密和数据保护义务。如果第三方合作伙伴未履行保密和数据保护义务,可能会被我们追究法律责任并被我们终止合作;</div>
<div>2.我们已经通过了国家信息安全等级保护测评和备案,最高备案等级为二级。</div>
<div>3.我们会采取一切合理可行的措施,确保未收集无关的个人信息。我们只会在达成本政策所述目的所需的期限内保留您的个人信息,除非需要延长保留期或者受到法律允许。</div>
<div>4.互联网并非绝对安全的环境,而且电子邮件、即时通讯、社交软件等与其他用户的交流方式无法确定是否完全加密,我们强烈建议您不用通过此类方式发送个人信息。若确需使用,在使用此类工具时请使用复杂密码,并注意保护您的个人信息安全。我们将尽力保障您个人信息的安全性。如果我们的物理、技术、或管理防护设施遭到破坏,导致信息被非授权访问、公开披露、篡改、或毁坏,导致您的合法权益受损,我们将全力配合保护您的权益,并依法承担我们应承担的赔偿责任。</div>
<div>5.在不幸发生个人信息安全事件后,我们将按照法律法规的要求及时向您告知安全事件的基本情况和可能的影响、我们已采取或将采取的处置措施、您可自主防范和降低风险的建议、对您的补救措施等。我们将及时将事件相关情况以邮件、信函、电话、推送通知等方式告知您,难以逐一告知时,我们会采取合理、有效的方式发布公告。同时,我们还将按照监管部门要求,主动上报个人信息安全事件的处置情况。</div>
<div>八、您如何管理您的个人信息(您的权力)</div>
<div>您可以通过以下方式访问及管理您的个人信息:</div>
<div>8.1 访问您的个人信息</div>
<div>您的账号信息:您可在“我的”中查询您的账户、姓名、性别、手机、身份证号、工作信息、健康类型、学历、工号、工种、住址,紧急联系人的姓名、电话等。</div>
<div>您和您亲属的健康信息:您可在“咨询人管理”中查询您和您亲属手机号码、患者姓名、性别、出生日期、与患者的关系、身高体重、所在城市;健康信息:病症、患病时长、体检报告、住院记录、诊治情况、用药记录、以往病史、过敏信息、家族史、患病史等健康信息。</div>
<div>您的订单、工单信息:您可在“我的-我的咨询”、“我的-我的应急工单”、“我的-大病就医工单”、“健康体检-体检预约”等各个业务的对应入口查看、评价订单和工单信息。</div>
<div>您的体检报告:你可在“健康体检-体检报告”和“健康档案-健康现状”、“健康档案-体检数据分析”查看个人的体检报告详情和重点指标的分析。</div>
<div>对于您在使用我们的产品或服务过程中向我们提供或产生的其他信息,只要我们不需要过多投入,我们会向您提供。您可以通过拨打我们的客服电话提出访问申请,我们将在30天内回复您的访问请求。</div>
<div>对于您在使用我们服务过程中产生的其他个人信息,我们将根据本条“8.9 响应您的上述请求”中的相关安排向您提供。</div>
<div>8.2 更正或补充您的个人信息</div>
<div>当您发现我们处理的您的个人信息有误或者您需要更正该等信息时,您可以通过内设置的自动更正功能、电子邮件或者拨打客服电话等方式进行修改或更正。您如果需要更正其他个人信息,可通过联系人工客服向我们提出更正申请。</div>
<div>可自主更正的信息:</div>
<div>账号信息:您可在“我的”中更新您的头像,紧急联系人的姓名、电话等。</div>
<div>您和您亲属的健康信息:您可在“咨询人管理”中更正您和您亲属手机号码、患者姓名、性别、出生日期、与患者的关系、身高体重、所在城市;健康信息:病症、患病时长、体检报告、住院记录、诊治情况、用药记录、以往病史、过敏信息、家族史、患病史等健康信息。</div>
<div>8.3 如何注销</div>
<div>您在我们的产品与/或服务页面中可以直接清除或删除的信息,包括浏览信息、紧急联系人信息、咨询人信息。</div>
<div>在以下情形中,您可以向我们提出删除个人信息的请求:</div>
<div>(1)如果我们处理个人信息的行为违反了法律法规的强制性规定;</div>
<div>(2)如果我们收集、使用您的个人信息,却未征得您的同意(依法无需征得同意的情况除外);</div>
<div>(3)如果我们处理个人信息的行为违反了与您的约定;</div>
<div>(4)如果您不再使用我们的产品或服务,或您注销了账号;</div>
<div>5)如果我们不再为您提供产品或服务。</div>
<div>如果您想删除或注册账号:</div>
<div>(1)拨打客服热线电话029-86618899</div>
<div>2)发送电子邮件至40115111@qq.com</div>
<div>(3)邮寄地址:陕西省西安市未央区欧亚大道丝路国际创意梦工场5号楼,收件人:许策</div>
<div>收到您的删除请求后,我们会根据您及相关法律法规的要求进行后续删除处理并向您反馈结果。若我们决定响应您的删除请求,我们还将同时通知从我们获得您的个人信息的实体,要求其及时删除,除非法律法规另有规定,或这些实体获得您的独立授权。</div>
<div>当您从我们的服务中删除信息后,我们可能不会立即备份系统中删除相应的信息,但会在备份更新时删除这些信息。</div>
<div>8.4 改变您授权同意的范围</div>
<div>您可以通过删除信息、关闭设备功能、在平台中进行隐私设置等方式改变您授权我们继续收集个人信息的范围或撤回您的授权。</div>
<div>请您理解,每个业务功能需要一些基本的个人信息才能得以完成(见本隐私权政策“我们如何收集和使用您的信息”)。当您收回同意后,我们将不再处理相应的个人信息。但您收回同意的决定,不会影响此前基于您的授权而开展的个人信息处理。</div>
<div>8.5 个人信息主体注销账户</div>
<div>在符合平台单项服务的服务协议约定条件及国家相关法律法规规定的情况下,您的该项平台服务帐号可能被注销或删除。当帐号注销或被删除后,与该帐号相关的、该单项服务项下的全部服务资料和数据将依照单项服务的服务协议约定删除或匿名化处理。</div>
<div>8.6 约束信息系统自动决策</div>
<div>在某些业务功能中,我们可能仅依据信息系统、算法等在内的非人工自动决策机制做出决定。如果这些决定显著影响您的合法权益,您有权要求我们做出解释,我们也将在不侵害平台保密或其他员工权益、社会公共利益的前提下提供申诉方法。</div>
<div>8.7约束信息系统自动决策</div>
<div>在某些业务功能中,我们可能仅依据信息系统、算法在内的非人工自动决策机制作出决定。如果这些决定显著影响您的合法权益,您有权要求我们作出解释,我们也将提供适当的救济方式。</div>
<div>8.8举报和投诉</div>
<div>如果您发现您的个人信息可能被泄露,或者我们的工作人员或合作伙伴在处理您的个人信息时有任何违法违规行为,您可以通过拨打客服热线或者发送电子邮件的方式向我们进行举报和投诉。</div>
<div>8.9 响应您的上述请求</div>
<div>为保障安全,您可能需要提供书面请求,或以其他方式证明您的身份。我们可能会先要求您验证自己的身份,然后再处理您的请求。我们将在15个工作日内做出答复。</div>
<div>对于那些无端重复、需要过多技术手段(例如,需要开发新系统或从根本上改变现行惯例)、给他人合法权益带来风险或者非常不切实际的请求,我们可能会予以拒绝。</div>
<div>在以下情形中,按照法律法规要求,我们将无法响应您的请求:</div>
<div>(1) 与国家安全、国防安全有关的;</div>
<div>(2) 与公共安全、公共卫生、重大公共利益有关的;</div>
<div>(3) 与犯罪侦查、起诉、审判和执行判决等有关的;</div>
<div>(4) 有充分证据表明个人信息主体存在主观恶意或滥用权利的;</div>
<div>(5) 响应您的请求将导致您或其他个人、组织的合法权益受到严重损害的;</div>
<div>(6) 涉及商业秘密的。</div>
<div>九、我们如何处理未成年人的个人信息</div>
<div>1.健康咨询专家端非常重视对未成年人个人信息的保护。若您是18周岁以下的未成年人,在使用我们的产品与/或服务前,应事先取得您监护人的同意。健康咨询专家端根据国家相关法律法规的规定保护未成年人的个人信息。</div>
<div>2.我们不会主动直接向未成年人收集其个人信息。对于经监护人同意而收集未成年人个人信息的情况,我们只会在受到法律允许、监护人同意或者保护未成年人所必要的情况下使用、共享、转让或披露此信息。</div>
<div>3.如果有事实证明未成年人在未取得监护人同意的情况下注册使用了我们的产品与/或服务,我们会与相关监护人协商,并设法尽快删除相关个人信息。</div>
<div>十、本声明和政策如何更新</div>
<div>我们的隐私政策可能变更。未经您明确同意,我们不会削减您按照声明和政策所应享有的权利。 我们会在本页面上发布对本声明和政策所做的任何变更。</div>
<div>对于重大变更,我们还会提供更为显著的通知(包括我们会通过网站公示的方式进行通知甚至向您提供弹窗提示)。</div>
<div>本声明和隐私所指的重大变更包括但不限于:</div>
<div>1、 我们的服务模式发生重大变化。如处理个人信息的目的、处理的个人信息类型、个人信息的使用方式等;</div>
<div>2、 我们在所有权结构、组织架构等方面发生重大变化。如业务调整等引起的所有者变更等;</div>
<div>3、 个人信息共享或公开披露的主要对象发生变化;</div>
<div>4、 您参与个人信息处理方面的权利及其行使方式发生重大变化;</div>
<div>5、 我们负责处理个人信息安全的责任部门、联络方式等发生变化时;</div>
<div>6、 个人信息安全影响评估报告表明存在高风险时。</div>
<div>7、 我们还会将本声明和隐私的旧版本存档,供您查阅。</div>
<div>十一、如何联系我们</div>
<div>1.如果您对本政策有任何疑问、意见或建议,可通过以下方式与我们联系:</div>
<div>(1)拨打客服热线电话029-86618899</div>
<div>2)发送电子邮件至chentianyu_cq@petrochina.com.cn</div>
<div>(3)邮寄地址:陕西省西安市未央区未央路151号,收件人:员工健康服务部</div>
<!-- <div>我们的客服部门将会同个人信息保护部门30天内进行回复,并协助解决您的问题。</div>-->
<div>2.如果您对我们的回复不满意,特别是我们的个人信息处理行为损害了您的合法权益,您还可以通过以下外部途径寻求解决方式:向网信、工商、公安等监管部门进行投诉或举报。</div>
</div>
</body>
</html>
-152
View File
@@ -1,152 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>健康咨询专家端用户协议</title>
</head>
<style>
html,body {
padding: 0;
margin: 0;
}
html,body,#zwb{
box-sizing: border-box;
overflow: hidden auto;
font-size: 22px;
}
html::-webkit-scrollbar {
width: 0;
}
body::-webkit-scrollbar {
width: 0;
}
#zwb {
padding: 25px;
width: 100%;
height: 100%;
overflow: hidden auto;
}
div {
margin: 0 0 10px;
}
.title-one {
text-align: center;
margin: 5px 0
}
</style>
<body>
<div id="zwb">
<h3 class="title-one">健康咨询专家端用户协议</h3>
<h3 class="title-one">软件使用许可协议(健康咨询专家端)</h3>
<h3 class="title-one">软件使用许可协议</h3>
<div>欢迎使用我们的服务</div>
<div>本软件许可使用协议《健康咨询专家端平台服务协议》(以下称"本协议")由您与西安仁康信息科技有限公司(以下称“西安仁康”)共同签署。</div>
<div>在使用“健康咨询专家端”软件(以下称许可软件)之前,请仔细阅读本协议。一旦您下载安装使用许可软件,即表示您同意接受本协议所有条款和条件的约束。如您不同意本协议条款和条件,请勿使用许可软件,并请销毁所有许可软件副本。</div>
<div>健康咨询专家端有权根据实际运营的情况对本协议不时进行调整,并以平台公告或电子邮件等书面形式通知您。修改后的协议于公示或邮件送达时生效。协议条款修改后,您继续使用许可软件的,即视为您已阅读并接受修改后的协议。</div>
<div>一、定义</div>
<div>1. 健康咨询专家端APP:是指由西安仁康开发的,供您从应用下载平台(以下称下载平台)下载,并仅限在手机等手持移动终端(以下称移动终端)中安装、使用的软件系统。</div>
<div>2. 健康咨询专家端服务:由西安仁康为您提供的服务。您可以通过许可软件在手持移动终端使用健康咨询专家端服务。</div>
<div>3. 用户:指阅读并同意本协议内容,经过健康咨询专家端在线注册程序成为健康咨询专家端在线各项服务使用者。(以下更多称为“您”)</div>
<div>二、服务说明</div>
<div>1. 本平台是一个集健康咨询功能的综合个人健康管理平台,为确保您能正常地使用平台的各项服务,您应当阅读并遵守本协议。请您务必审慎阅读、充分理解各条款内容,以及开通或使用某项服务的单独协议,并选择接受或不接受。</div>
<div>2. 除非您已阅读并接受本协议所有条款,否则您无权使用平台的各项服务(以下简称"本服务”)。您在平台的登录、查看、发布信息等行为即视为您已阅读并同意本协议的约束,包括接受更新后的本协议条款。当您与平台发生争议时,应以最新的服务协议为准。</div>
<div>3. 平台为您提供集健康咨询功能服务,为充分保护您对于平台提供的各项服务的知情权,平台就其提供的服务相关性、有效性以及限制性提供以下注册条款。平台在此特别提醒您,在您使用前已确实仔细阅读了本协议,如果您对本协议的任何条款或者将来随时可能修改、补充的条款有异议,您可选择不注册。</div>
<div>4. 您在使用服务过程中,根据声音、文字或图形等提示可以选择表示“同意”的操作,当您点选“同意”按钮时即视为您已仔细阅读本协议,同意接受本协议项下的所有条款,包括接受平台对本协议条款随时所做的任何修改,并愿意受其约束。之后方能按系统提示完成全部注册程序、问答程序、享受相关的各项电子服务。</div>
<div>5. 您在平台提问、搜索、提供各项电子信息、与其它员工交流及其他服务,即代表您已经同意本协议。</div>
<div>6. 本协议的条款适用于平台提供的各种服务,但当您使用平台某特定服务时,如该服务另有单独的服务条款、指引或规则,您应遵守本协议及平台随时公布的与该服务相关的服务条款、指引或规则等。前述所有的指引和规则,均构成本协议的一部分。除非本协议另有其他明示规定,新推出的服务、增加或强化目前本服务的新功能,均受到本协议之规范。</div>
<div>7. 如对本协议内容有任何疑问、意见或建议,您可与我们联系。</div>
<div>三、本协议的确认和接纳</div>
<div>1、平台的各项服务的所有权和运作权归西安仁康所有。您同意所有注册协议条款,才能成为平台平台的正式用户。您确认:本协议条款是处理双方权利义务的契约,始终有效,法律另有强制性规定或双方另有特别约定的,依其规定。</div>
<div>2、您点击注册登录,即视为您确认自己具有享受平台服务相应的权利能力和行为能力,能够独立承担法律责任。</div>
<div>3、平台通过互联网为您提供各项服务,并承担本协议和其它服务协议中对您的责任和义务。为使用本服务,您必须能够自行通过有法律资格的第三方对您提供互联网接入服务,并自行承担以下内容:</div>
<div>(1)自行配备上网所需的设备,包括手机、个人电脑、调制解调器及其他必要的设备装置。</div>
<div>(2)自行承担上网所需的相关必要费用,如:电话费用、网络费用等。</div>
<div>(3)本协议中规定的您的其他责任和义务。</div>
<div>4、您应保证:提供详尽、真实、准确和完整的个人资料以符合实名认证的要求。如果资料发生变动,您应及时更改。若您提供任何错误、不实、过时或不完整的资料,并为平台所确知,或者平台有合理理由怀疑前述资料为错误、不实、过时或不完整的资料,平台有权暂停或终止您的帐号,并拒绝现在或将来申请使用本服务的全部或一部分的请求。在此情况下,您可通过平台的申诉途径与平台取得联系并修正个人资料,经平台核实后恢复账号使用。</div>
<div>5、本务不会提供给被暂时中止或永久终止资格的平台员工。</div>
<div>6、平台会尽最大努力为员工提供服务,确保服务的连贯性和安全性;但平台不能随时预见和防范法律、技术以及其他风险,包括但不限于不可抗力、病毒、木马、黑客攻击、系统不稳定、第三方服务瑕疵、政府行为等原因可能导致的服务中断、数据丢失以及其他的损失和风险。</div>
<div>7、本协议依据国家相关法律法规规章制定,员工同意并遵守相关法律法规:</div>
<div>(1)不得传输或发表:煽动抗拒、破坏宪法和法律、行政法规实施的言论,煽动颠覆国家政权,推翻社会主义制度的言论,煽动分裂国家、破坏国家统一的的言论,煽动民族仇恨、民族歧视、破坏民族团结的言论;</div>
<div>(2)不得利用平台从事洗钱、窃取商业秘密、 窃取个人信息等违法犯罪活动;</div>
<div>(3)不得干扰平台的正常运转,不得侵入平台及国家计算机信息系统;</div>
<div>(5)不得传输或发表任何违法犯罪的、骚扰性的、中伤他人的、 辱骂性的、恐吓性的、伤害性的、庸俗的、 淫秽的、不文明的等信息资料;</div>
<div>(6)不得传输或发表损害国家社会公共利益和涉及国家安全的信息资料或言论;</div>
<div>(7)不得教唆他人从事本条所禁止的行为;</div>
<div>(8)不得发布任何侵犯他人著作权、商标权等知识产权或合法权利的内容。您应关注并遵守平台不时公布或修改的各类合法规则规定。平台保有删除各类不符合法律政策或不真实的信息内容而无须通知员工的权利。若您未遵守以上规定的,平台有权作出独立判断并采取暂停或关闭员工帐号等措施。您须对自己在网上的言论和行为承担法律责任。</div>
<div></div>
<div>四、员工管理</div>
<div>1、您使用本平台服务时,在平台上不得发表违法言论、不得违反公序良俗、不得使用攻击性语言恶意中伤他人,或作出虚假性陈述。您保证您在平台上提供的信息的真实性、合法性和有效性。您单独承担在平台上发布内容的一切相关责任。您使用或提供的服务应有适用于平台的地方法律、国家法律和国际法律标准。</div>
<div>2、您不得干扰或扰乱本平台提供的服务,不得盗用他人帐号,如有上述行为,您需对此行为造成的后果负责。</div>
<div>3、您应遵守所有使用本服务的各项协议、 规定、程序和惯。您须承诺不传输任何非法的、骚扰性的、中伤他人的、辱骂性的、恐吓性的、伤害性的、庸俗的,淫秽等信息内容。另外,您也不能传输任何教唆他人构成犯罪行为的内容;不能传输助长国内不利条件和涉及国家安全的内容;不能传输任何不符合当地法规、国家法律和国际法律的内容。</div>
<div>4、您不得发布任何不基于事实、虚构、夸大、引人误解的信息;不得发布涉及政治、性别、种族歧视或攻击他人的文字、图片、视频或语言等信息;不得发布有广告性质的内容;不得有其它涉及违反当地法规、国家法律和国际法律的行为。</div>
<div>5、您发布的文章、视频、资讯不得侵犯任何第三方的合法知识产权。</div>
<div>6、若您的行为不符合本协议的规定,平台有权做出独立判断,并立即停止向该您帐号提供服务。您需对自己在网上的行为承担法律责任。您若在平台上散布和传播反动、色情或其他违反国家法律的信息,平台的系统记录有可能作为您违反法律的证据。</div>
<div>7、您的授权行为:对平台而言,您帐号和密码是唯一验证您真实性的依据,只要使用了正确的您帐号和密码,无论是谁登录均视为已经得到您本人的授权。</div>
<div>五、员工保障</div>
<div>您同意保障和维护平台的利益,如果因为您违反有关法律、法规或本协议的任何规定而给平台或其他第三方造成任何损失,您统一承担由此产生的损害赔偿责任,其中包括平台为此而支付的律师费用。</div>
<div></div>
<div>六、您的帐号、密码和安全性</div>
<div>1、您一旦注册成功,成为平台的合法用户,将得到一个您的帐号和密码。您的帐号和密码由您负责保管。您要对任何以您帐号进行的活动和事件负全责,且您有权随时根据指示更改您的密码。若发现您的帐号有任何风险、非法使用或存在安全漏洞的情况,请立即通知平台。</div>
<div>2、 因黑客行为或您的保管疏忽等情况导致帐号、密码遭他人非法使用,平台不承担责任。平台将根据法律法规的要求,履行其作为移动互联网信息服务提供者应当履行的义务。</div>
<div>七、收费服务</div>
<div>1、如您使用平台的收费服务,请遵守相关的协议。</div>
<div>2、 请您在支付费用时,仔细阅读收费服务的相关协议,除协议约定的情况外,否则,平台将不予退费。退费的方式视支付方式的不同而不同。员工应严格依据退费方式及退费周期收回退款。</div>
<div>3、平台可能根据实际需要对收费服务的收费标准、方式进行修改和变更,平台也可能会对部分免费服务变更收费。如果您不同意上述修改、变更或付费内容,则应停止使用该服务。</div>
<div>八、服务暂停、变更与中止条款</div>
<div>1、鉴于移动互联网服务的特殊性,健康咨询专家端平台有权随时变更、中止或终上部分或全部的服务。如变更、中止或终止的服务属于免费服务,平台无需通知您,也无需对您或任何第三方承担任何责任。</div>
<div>2、您理解,因不可抗力、网络状况、通讯线路、用户自身过错等技术原因,或平台需要进行定期或不定期地对所提供的服务进行维护升级、对相关的设备进行检修或者维护,如因此类情况而造成本服务在合理时间内的中断,健康咨询专家端平台无需为此承担任何责任。</div>
<div>3、 如发生下列任何一种情形,平台有权随时中断或终止向您提供本协议项下的服务而无需对您或任何第三方承担任何责任:</div>
<div>(1)您违反国家有关法律法规或平台规定,侵害他人合法权益的;</div>
<div>(2)您提供的个人资料不真实;</div>
<div>(3)您违反本协议中的规定;</div>
<div>(4)您违反平台发布的政策;</div>
<div>(5)平台认为其他不适宜的地方。</div>
<div>九、结束服务</div>
<div>您或平台可随时根据员工管理的规范中断一项或多项本服务,平台无需对您或任何其他第三方负责。您对本协议的修改有异议,或对平台的服务不满,可以行使如下权利:</div>
<div>1、停止使用平台提供的服务。</div>
<div>2、通知平台停止对您帐号提供服务。停止为您提供服务后,您使用本服务的权利即刻终止,,平台不对您承担任何义务和责任。</div>
<div>十、隐私及个人信息的保护</div>
<div>1、保护您的隐私是平台的一项基本政策。</div>
<div>2、您的信任对平台非常重要,平台深知个人信息安全的重要性,平台将按照法律法规要求,采取安全保护措施,保护您的个人信息安全。</div>
<div>十一、知识产权条款</div>
<div>1、 您一旦接受本协议,即表明您在任何时间在平台发表的任何形式的信息内容(包括但不限于员工评价、员工咨询、各类话题文章等信息内容)产生的权利,如著作权财产权(包括并不限于:复制权、发行权、出租权、展览权、表演权、放映权、广播权、信息网络传播权、摄制权、改编权、翻译权、汇编权以及应当由著作权人享有的其他可转让权利), 全部独家且不可撤销地转让给平台所有,您同意平台有权就任何主体侵权而单独提起诉讼。</div>
<div>2、本协议已经构成《中华人民共和国著作权法》第二十五条(条文序号依照2011年版著作权法确定)及相关法律规定的著作财产权等权利转让书面协议,其效力及于您在平台上发布的任何受著作权法保护的作品内容,无论该等内容形成于本协议订立前还是本协议订立后。</div>
<div>3、您同意并已充分了解本协议的条款,承诺不将已发表于平台的信息,以任何形式发布或授权其它主体以任何方式使用(包括但限于在各类网站、媒体上使用)、</div>
<div>4、西安仁康是平台的制作者,拥有平台内容及资源的著作权等合法权利,受国家法律保护,有权不时地对本协议及平台的内容进行修改,并在平台张贴,无须另行通知您。在法律允许的最大限度范围内,平台对本协议及的内容拥有解释权。</div>
<div>5、除法律另有强制性规定外,未经平台明确的特别书面许可,任何单位或个人不得以任何方式非法地全部或部分复制、转载、引用、链接、抓取或以其他方式使用平台的信息内容,否则,平台有权追究其法律责任。</div>
<div>6、平台所刊登的资料信息(诸如文字、图表、标识、按钮图标、图像、声音文件片段、数字下载、数据编辑和软件),均是平台或其内容提供者的财产,受中国和国际版权法的保护。平台上所有内容的汇编是平台的排他财产,受中国和国际版权法的保护。平台上的所有软件都是平台的财产,受中国和国际版权法的保护。</div>
<div>十二、特别授权</div>
<div>您完全理解并不可撤销地授予平台下列权利:</div>
<div>1、一旦您向平台作出任何形式的承诺,且相关机构已确认您违反了该承诺,则平台有权依据您的承诺或协议约定的方式对您的账户采取限制措施,包括中止或终止向您提供服务,并向相关机构确认的您的违约情况。您了解并同意,平台无须就相关违约事项与您核对事实,或另行征得您的同意,且平台无须就此限制措施或公示行为向您或任何第三方承担任何的责任。</div>
<div>2、一旦您违反本协议、或与平台签订其他协议的约定,平台有权或以任何方式通知其他相关平台服务,要求其对您的权益采取限制措施,包括但不限于要求中止、终止对您提供的部分或全部服务。</div>
<div>3、您授权平台使用您注册、使用本平台服务过程中产生的信息,并允许平台通过短信、邮件、电话或其他形式向您传送平台提供的服务。您同意接受平台通过短信、邮件、电话或其他形式向您发送活动、服务等信息。如果您不需要平台提供的部分或全部服务的活动、服务,您可向平台提出申请中止、终止对您提供的该部分或全部服务。</div>
<div>十三、平台拒绝提供担保</div>
<div>1、您对移动网络服务的使用承担风险,并承担因为使用移动网络服务而产生的一切后果。平台对此不作任何类型的担保,不论是明确的或隐含的,但是不对商业性的隐含担保、特定目的和不违反规定的适当担保作限制。</div>
<div>2、平台不担保提供的服务一定能完全满足您的要求,也不担保本服务不会受网络、通信等原因而中断,对服务的及时性、安全性、错误程序的发生都不作担保。</div>
<div>3、平台因受合作医疗机构等资源限制,就您所提的请求不担保服务一定能够成功。</div>
<div>4、您不能从平台得到口头或书面的意见或信息(增加除外条款,而并非全部),平台也不会在此做明确担保。</div>
<div>5、除非另有明确的书面说明,平台不对平台上的信息、内容、材料、包括软件或服务作任何形式的、明示或联示的声明或担保(根据中华人民共和国法律另有规定的以外)</div>
<div>6、如因不可抗力或其它无法控制的原因使平台系统崩溃或无法正常使用导致无法完成或丢失有关的服务信息、记录等,平台会合理地尽力协助处理。</div>
<div>十四、责任限制</div>
<div>1、平台会尽最大努力为您提供服务,确保服务的连贯性和安全性;但平台不能随时预见和防范法律、技术以及其他风险,包括但不限于不可抗力病毒、木马、黑客攻击、系统不稳定第三方服务瑕疵、政府行为等原因可能导致的服务中断数据丢失以及其他的损失和风险。因平台所不能控制的事件而影响提供服务,平台无须承担任何责任。</div>
<div>2、因不正当使用网络服务,私自在网上进行交易,非法使用网络服务或您传送的信息有所变动等这些行为都有可能会导致平台的形象受损,所以平台事先提出这种损害的可能性。</div>
<div>3、平台所有信息仅供参考。平台不对因信息的不正确或遗漏导致的任何损失或损害承担责任。平台所提供的任何健康资讯,仅供参考,不能替代医生和其他医务人员的建议,如自行使用平台资料发生偏差,平台不承担任何法律责任。</div>
<div>4、平台拒绝回复的问题,包括但不限于如下情况:</div>
<div>(1)动物疾病问题、社会意识形态问题等;</div>
<div>(2)医疗司法举证或询证问题;</div>
<div>(3)胎儿性别鉴定问题;</div>
<div>(4)有危害他人/自己可能的问题;</div>
<div>(5) 追问医生个人信息的问题;</div>
<div>(6) 故意挑逗、侮辱医生的提问。</div>
<div>5、平台保留对本声明作出不定时修改的权利。</div>
<div>十五、协议修改</div>
<div>根据国家法律法规变化及网络运营需要,本协议即时生效,并对条款不时地进行修改。您可随时登陆查阅最新协议;您有义务不时关注并阅读最新版的协议及平台公告;如您使用平台提供服务,即视为同意更新后的协议。建议您在使用平台之前阅读本协议。</div>
<div>十六、其他</div>
<div>1、平台尊重您的合法权利,本协议及平台上发布的各类规则、声明等其他内容,均是为了更好地、更加便利地为您提供服务。平台欢迎您和社会各界提出意见和建议,平台将虚心接受并适时修改本协议及平台的各类规则。</div>
<div>2、您使用平台服务即视为您完全接受本协议,在“登录"之前请您再次确认已知悉并完全理解本协议的全部内容。</div>
</div>
</body>
</html>
+1 -7
View File
@@ -4,7 +4,7 @@
-->
<template>
<div class="anticon" :class="getAppLogoClass" @click="goHome">
<div class="ml-2 truncate md:opacity-100" :class="[getTitleClass, getEnvInfo().VITE_PLATFORM === 'YT' ? 'new-class' : '']" v-show="showTitle">
<div class="ml-2 truncate md:opacity-100" v-show="showTitle">
<!-- <div class="logo-left" v-if="getEnvInfo().VITE_PLATFORM === 'YT'">-->
<!-- <div>长庆</div>-->
<!-- <div>油田</div>-->
@@ -107,12 +107,6 @@
line-height: normal;
}
}
.new-class {
color: #000000 !important;
display: flex;
justify-content: center;
align-items: center;
}
.logo-left {
font-size: 15px;
@@ -1,6 +1,6 @@
<template>
<div :class="`${prefixCls}- flex items-center `">
<!-- <Icon v-if="getIcon" :icon="getIcon" :size="18" :class="`${prefixCls}-wrapper__icon mr-2`" />-->
<Icon v-if="getIcon" :icon="getIcon" :size="18" :class="`${prefixCls}-wrapper__icon mr-2`" />
{{ getI18nName }}
</div>
</template>
@@ -3,7 +3,7 @@
<span :class="[prefixCls, `${prefixCls}--${theme}`]" class="flex">
<img :class="`${prefixCls}__header`" :src="getAvatarUrl" />
<span :class="`${prefixCls}__info hidden md:block`">
<span :class="`${prefixCls}__name `" class="truncate" :style="{ color: getEnvInfo().VITE_PLATFORM === 'YT' ? '#000000' : '' }">
<span :class="`${prefixCls}__name `" class="truncate">
{{ getUserInfo.realname }}
</span>
</span>
+1 -2
View File
@@ -22,7 +22,7 @@
</Sider>
</template>
<script lang="ts">
import { computed, CSSProperties, defineComponent, h, ref, unref, watch } from 'vue';
import { computed, CSSProperties, defineComponent, h, ref, unref } from 'vue';
import { Layout } from 'ant-design-vue';
import LayoutMenu from '../menu/index.vue';
@@ -124,7 +124,6 @@
getSplitType,
getShowTrigger,
toggleCollapsed,
isSpecialPath,
count,
};
},
@@ -1,14 +0,0 @@
<template>
<BasicDrawer v-bind="$attrs" :showFooter="false" @register="registerDrawer" destroyOnClose title="查看报告" :width="700" :maskClosable="true">
<iframe style="width: 100%; height: 100%" :src="pdfUrl" />
</BasicDrawer>
</template>
<script setup lang="ts">
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
import { ref } from 'vue';
const pdfUrl = ref('');
const [registerDrawer, {}] = useDrawerInner(async (data) => {
pdfUrl.value = data.url;
});
</script>
<style scoped lang="less"></style>
@@ -1,38 +0,0 @@
<template>
<BasicDrawer v-bind="$attrs" :showFooter="false" @register="registerDrawer" destroyOnClose title="查看问卷详情" :width="700" :maskClosable="true">
<a-descriptions v-if="Object.keys(descriptions).length > 0" title="HMS评估报告" bordered>
<a-descriptions-item v-for="(item, k) in descriptions" :key="k" :label="k" :span="4">{{ item }}</a-descriptions-item>
</a-descriptions>
<a-empty v-else style="margin-top: 150px" />
</BasicDrawer>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
import { getQsDetail, QsDetail } from '/@/views/archive/comprehensiveStatistics/comprehensiveStatistics.api';
const descriptions = ref({});
//表单赋值
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
setDrawerProps({
confirmLoading: false,
showCancelBtn: !!data?.showFooter,
showOkBtn: !!data?.showFooter,
});
descriptions.value = {};
await getDetail(data.record);
});
async function getDetail(record: QsDetail) {
try {
const params = <QsDetail>{ logId: record.logId, realName: record.realName, time: record.saveDate };
let res = await getQsDetail(params);
if (res) {
descriptions.value = res;
}
} catch (e) {
console.log(e);
}
}
</script>
<style scoped lang="less"></style>
@@ -1,38 +0,0 @@
<template>
<BasicDrawer v-bind="$attrs" :showFooter="false" @register="registerDrawer" destroyOnClose title="查看问卷详情" :width="700" :maskClosable="true">
<a-descriptions v-if="Object.keys(descriptions).length > 0" title="HMS评估报告" bordered>
<a-descriptions-item v-for="(item, k) in descriptions" :key="k" :label="k" :span="4">{{ item }}</a-descriptions-item>
</a-descriptions>
<a-empty v-else style="margin-top: 150px" />
</BasicDrawer>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
import { getQsDetail, QsDetail } from '/@/views/archive/psychologicalAssessmentStatistics/psychologicalAssessmentStatistics.api';
const descriptions = ref({});
//表单赋值
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
setDrawerProps({
confirmLoading: false,
showCancelBtn: !!data?.showFooter,
showOkBtn: !!data?.showFooter,
});
descriptions.value = {};
await getDetail(data.record);
});
async function getDetail(record: QsDetail) {
try {
const params = <QsDetail>{ evaluationId: record?.id, realName: record.realName, time: record.saveDate };
let res = await getQsDetail(params);
if (res) {
descriptions.value = res;
}
} catch (e) {
console.log(e);
}
}
</script>
<style scoped lang="less"></style>
@@ -1,17 +0,0 @@
import { defHttp } from '/@/utils/http/axios';
export enum Api {
list = '/archives/hmsEvaluation/allEvaluationResultPage',
getQsDetail = '/archives/hmsEvaluation/getQsDetail',
getQsDetail1 = '/archives/hmsEvaluationPhyStat/getQsDetail',
exportPDF = '/archives/hmsEvaluation/getPdfFilePath',
}
export interface QsDetail {
realName: string;
time: string;
logId: string;
createTime?: string;
userName?: string;
}
export const listApi = (params: any) => defHttp.get({ url: Api.list, params });
export const getQsDetail = (params: QsDetail) => defHttp.get({ url: Api.getQsDetail, params });
export const exportPDF = (params: any) => defHttp.get({ url: Api.exportPDF, params }, { isTransformResponse: false });
@@ -1,71 +0,0 @@
import { BasicColumn, FormSchema } from '/@/components/Table';
import { orgSearchInfo } from '/@/utils/orgSearchInfo';
import { render } from '/@/utils/common/renderUtils';
//姓名 身份证号 性别 单位 部门 评估日期 评估类型 评估状态 错误提示 (操作框添加两个(查看问卷 查看报告))
export const columns: BasicColumn[] = [
{
title: '姓名',
dataIndex: 'realName',
},
{
title: '身份证号',
dataIndex: 'idCard',
},
{
title: '性别',
dataIndex: 'sex_dictText',
width: 60,
},
{
title: '单位',
dataIndex: 'secondDepart',
},
{
title: '部门',
dataIndex: 'thirdDepart',
},
{
title: '评估日期',
dataIndex: 'saveDate',
},
{
title: '评估类型',
dataIndex: 'questionnairesType_dictText',
},
{
title: '评估状态',
dataIndex: 'generationStatus_dictText',
},
{
title: '错误提示',
dataIndex: 'exceptionCatch',
width: 80,
},
];
// 风险评估统计筛选条件 新加评估类型 评估状态 条件
export const schema: FormSchema[] = [
{
label: '姓名',
field: 'realName',
component: 'Input',
},
...orgSearchInfo({ orgField: 'orgCode1', orgName: '单位', deptFiled: 'orgCode2', deptName: '部门' }),
{
label: '评估时间',
field: 'saveDate',
component: 'RangeDate',
},
{
label: '评估状态',
field: 'generationStatus',
component: 'JDictSelectTag',
componentProps: () => ({ dictCode: 'hms_gene_status' }),
},
{
label: '评估类型',
field: 'questionnairesType',
component: 'JDictSelectTag',
componentProps: () => ({ dictCode: 'evaluation_type' }),
},
];
@@ -1,127 +0,0 @@
<template>
<div ref="innerRef">
<BasicTable @register="registerTable">
<template #bodyCell="{ column, record }">
<a-button
v-if="column.dataIndex === 'exceptionCatch'"
:disabled="!record.exceptionCatch"
style="color: #1890ff"
type="text"
@click="look(record?.exceptionCatch)"
>
查看
</a-button>
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
<QuestionDrawer @register="registerDrawer" />
<question-drawer1 @register="registerDrawer1" />
<a-modal v-model:visible="visible" title="错误提示" @ok="okButton">
<div style="padding: 10px">
<p>{{ info }}</p>
</div>
</a-modal>
<!-- <pdf-drawer @register="registerPdfDrawer" :getContainer="innerRef" />-->
</div>
</template>
<script setup lang="ts">
import { useListPage } from '/@/hooks/system/useListPage';
import { BasicTable, TableAction } from '/@/components/Table';
import { listApi, exportPDF } from '/@/views/archive/comprehensiveStatistics/comprehensiveStatistics.api';
import { columns, schema } from '/@/views/archive/comprehensiveStatistics/comprehensiveStatistics.data';
import { useDrawer } from '/@/components/Drawer';
import QuestionDrawer from '/@/views/archive/comprehensiveStatistics/components/questionDrawer.vue';
import { message } from 'ant-design-vue';
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
// import PdfDrawer from '/@/views/archive/comprehensiveStatistics/components/pdfDrawer.vue';
import { ref } from 'vue';
import QuestionDrawer1 from '/@/views/archive/comprehensiveStatistics/components/questionDrawer1.vue';
const [registerDrawer, { openDrawer }] = useDrawer();
const [registerDrawer1, { openDrawer: openDrawer1 }] = useDrawer();
// const [registerPdfDrawer, { openDrawer: openPdfDrawer }] = useDrawer();
const innerRef = ref();
const visible = ref(false);
const info = ref('');
function look(text) {
info.value = text;
visible.value = true;
}
function okButton() {
info.value = '';
visible.value = false;
}
//注册table数据
const { tableContext } = useListPage({
tableProps: {
title: '风险评估统计',
api: listApi,
columns,
canResize: false,
formConfig: {
labelWidth: 120,
schemas: schema,
autoSubmitOnEnter: true,
showAdvancedButton: false,
fieldMapToTime: [['saveDate', ['startTime', 'endTime']]],
actionColOptions: {
style: {
marginLeft: '120px',
},
},
},
actionColumn: {
width: 180,
fixed: 'right',
},
},
});
function getTableAction(record: Recordable) {
return [
{
label: '查看报告',
onClick: checkReport.bind(null, record),
},
{
label: '查看问卷',
onClick: checkQuestion.bind(null, record),
},
];
}
async function checkReport(record: Recordable) {
let url = record?.pdfUrl;
if (url) {
if (url.charAt(url.length - 1) === ',' || url.charAt(url.length - 1) === '') {
url = url.substring(0, url.length - 1);
}
window.open(getFileAccessHttpUrl(url));
} else {
message.warn('获取文件地址失败');
}
}
function checkQuestion(record: Recordable) {
if (record?.questionnairesType == 1) {
openDrawer(true, {
record,
isUpdate: true,
showFooter: false,
});
} else {
openDrawer1(true, {
record,
isUpdate: true,
showFooter: false,
});
}
}
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
</script>
<style scoped lang="less"></style>
@@ -1,18 +0,0 @@
import { defHttp } from '/@/utils/http/axios';
export enum Api {
left = '/health-archives/archives/hmsEvaluation/selectMedicalUniItemClassList',
right = '/health-archives/archives/hmsEvaluation/selectMedicalUniItemByClassId',
downloadUrl = '/archives/hmsEvaluation/reportDownload',
}
export const getLeft = (params: any) => defHttp.get({ url: Api.left, params: params });
export const getRight = (params: any) => defHttp.get({ url: Api.right, params: params });
export const downloadPDF = (params: any) =>
defHttp.get(
{
url: Api.downloadUrl,
params: params,
},
{ isTransformResponse: false }
);
@@ -1,300 +0,0 @@
<!--体检分析报告-->
<template>
<div class="analysisReport">
<div class="left-menu">
<div class="sub-tit tree-tit">检查类别</div>
<div class="tree-box">
<BasicTree
ref="tree"
v-model:selectedKeys="selectedKeys"
:expanded-keys="expandedKeys"
:tree-data="treeData"
:fieldNames="fieldNames"
@select="select"
>
<template #name="data"></template>
</BasicTree>
</div>
</div>
<div class="right-content">
<div class="sub-tit content-tit">
<div>{{ parentName ? (contentName ? parentName + '/' : parentName) : '' }}{{ contentName }} </div>
<div class="report-info">
<div style="margin-right: 10px" v-if="btnDisable">
<span>报告最新年份:{{ reportData?.reportLastYear ? reportData?.reportLastYear : '--' }}</span>
<span>生成时间{{ reportData?.generateTime }}</span>
</div>
<a-button type="primary" preIcon="ant-design:sync-outlined" @click="getReportStatus">刷新报告信息</a-button>
<a-button type="primary" preIcon="ant-design:form-outlined" @click="reportGenerateFun" style="margin: 0 10px">生成报告</a-button>
<a-button type="primary" :disabled="!btnDisable" preIcon="ant-design:download-outlined" @click="downloadFile">报告下载 </a-button>
</div>
</div>
<div v-show="rightList.length == 0 && spinning == false" class="empty-con">
<a-empty :image="Empty.PRESENTED_IMAGE_SIMPLE" />
</div>
<div class="spin-content">
<a-spin tip="Loading..." :spinning="spinning" />
</div>
<div class="chart-list">
<div class="chart-list-left">
<template v-for="(item, i) in rightList" :key="i">
<AnalysisContent v-if="i % 2 == 0" :item="item" :key="item" :isConclusion="isConclusion" />
</template>
</div>
<div class="chart-list-right">
<template v-for="(item, i) in rightList" :key="i">
<AnalysisContent v-if="i % 2 != 0" :item="item" :key="item" :isConclusion="isConclusion" />
</template>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { Empty, message } from 'ant-design-vue';
import AnalysisContent from '/@/views/archive/employeeFile/components/analysisReport/components/analysisContent.vue';
import { downloadPDF, getLeft, getRight } from '/@/views/archive/employeeFile/components/analysisReport/analysisReport.api';
import { fieldNames, useContentName } from '/@/views/archive/employeeFile/components/analysisReport/analysisReportHooks';
import { BasicTree } from '/@/components/Tree/index';
import { useRoute } from 'vue-router';
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
import { reportStatus, reportGenerate } from '/@/views/archive/employeeFile/employeeFileList.api';
const route = useRoute();
const treeData = ref([]);
const rightList = ref([]);
const expandedKeys = ref<string[]>([]);
const selectedKeys = ref<string[]>();
const isConclusion = ref(false); //判断是否为结论建议
const { contentName, setContentName } = useContentName();
const { contentName: parentName, setContentName: setParentName } = useContentName();
const tree = ref();
let btnDisable = ref(false);
let reportData = ref();
async function select(selectedKeys, e) {
if (Array.isArray(e.node.childList) && e.node.childList.length > 0) {
//判断当前项 是否在已经展开keys数组 如果不在则展开 否则关闭
let index = expandedKeys.value.indexOf(e.node.id);
if (index === -1) {
expandedKeys.value.push(e.node.id);
} else {
expandedKeys.value = expandedKeys.value.filter((item) => item !== e.node.id);
}
} else {
isConclusion.value = false;
let { id, name, parentName } = e.node;
setParentName(parentName);
//第一层节点name不是string类型
if (typeof name !== 'string') {
name = name.el.innerText;
}
// 防止重复点击
if (contentName.value == name) return;
setContentName(name);
// 选中结论建议
if (id == '11') {
isConclusion.value = true;
await getRightData(id, true);
return;
}
await getRightData(id);
}
}
onMounted(() => {
getReportStatus();
getMenu();
});
async function getReportStatus() {
try {
spinning.value = true;
let data = await reportStatus({ userId: route.query.id });
console.log(data);
reportData.value = data;
btnDisable.value = data?.generateStatus == 2;
spinning.value = false;
} catch {
spinning.value = false;
}
}
async function reportGenerateFun() {
try {
spinning.value = true;
await reportGenerate({ userId: route.query.id });
spinning.value = false;
} catch {
spinning.value = false;
}
}
async function getMenu() {
try {
let data = await getLeft({ sex: route.query.sex });
treeData.value = data;
if (Array.isArray(data) && data[0]) {
const { id, name } = data[0]?.childList[0] || data[0];
setContentName(name);
// 第一个菜单没有子级
if (!data[0]?.childList[0]?.name) {
setContentName('');
}
// 默认展开一级选中第一个节点
expandedKeys.value.push(data[0].id);
parentName.value = data[0].name;
selectedKeys.value = [id];
await getRightData(id);
} else {
spinning.value = false;
}
} catch {
rightList.value = [];
spinning.value = false;
}
}
const spinning = ref<boolean>(true);
const changeSpinning = () => {
spinning.value = !spinning.value;
};
async function getRightData(id: string, isConclusion = false) {
spinning.value = true;
if (!id) {
changeSpinning();
console.error('该数据没有id');
return;
}
try {
let res = await getRight({
medicalUniItemClassId: id,
isConclusion,
userId: route.query.id,
});
setTimeout(() => {
if (res && res.length > 0) {
rightList.value = res;
} else {
rightList.value = [];
}
spinning.value = false;
}, 1000);
} catch {
rightList.value = [];
spinning.value = false;
}
}
async function downloadFile() {
const { code, result, message: info } = await downloadPDF({ userId: route.query.id });
if (code !== 200) {
return message.warn(info);
}
const url = getFileAccessHttpUrl(result);
if (url) {
window.open(url);
} else {
message.warn(info);
}
}
</script>
<style scoped lang="less">
.analysisReport {
width: 100%;
height: calc(100% - 63px);
display: flex;
margin: 10px;
background-color: #fff;
.sub-tit {
font-size: 16px;
color: #333;
font-weight: bold;
}
.left-menu {
min-width: 240px;
display: flex;
flex-direction: column;
border-right: 1px solid #ccc;
position: relative;
overflow-y: hidden;
.tree-tit {
padding: 10px 20px;
}
.tree-box {
flex: 1;
overflow-y: auto;
}
:deep(.ant-tree) {
.ant-tree-node-content-wrapper.ant-tree-node-selected {
background-color: #eaf3fc;
color: #4095e5;
}
}
}
.right-content {
flex: 1;
margin: 0 16px 16px 16px;
overflow: hidden;
position: relative;
.spin-content {
position: absolute;
width: 200px;
height: 200px;
//border: 1px solid red;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
//background: #fff;
//opacity: 0;
transition: all 0.3s;
}
.content-tit {
height: 45px;
line-height: 45px;
box-shadow: 0 2px 8px #f0f1f2;
display: flex;
justify-content: space-between;
.report-info {
display: flex;
align-items: center;
font-size: 14px;
font-weight: 500;
}
}
.empty-con {
height: 415px;
display: flex;
justify-content: center;
align-items: center;
}
.chart-list {
display: flex;
gap: 20px;
height: calc(100% - 35px);
overflow-x: hidden;
overflow-y: auto;
}
.chart-list-left {
width: calc(50% - 10px);
display: flex;
flex-direction: column;
gap: 10px;
}
.chart-list-right {
width: calc(50% - 10px);
display: flex;
flex-direction: column;
gap: 10px;
}
}
}
</style>
File diff suppressed because it is too large Load Diff
@@ -1,332 +0,0 @@
<template>
<div class="chart-item">
<!--图表-->
<div v-show="firstChild.type === '0'">
<div class="chart-title">
<div class="t1">{{ item?.peItemName }}</div>
<div class="t2" v-show="showReference(firstChild?.printContext)">
<span>参考值</span>
<span>
<span style="color: #333">{{ firstChild?.printContext }}</span>
<span>{{ firstChild?.unit }}</span>
</span>
</div>
</div>
<div class="panel-table">
<div class="label-list">
<div class="label-item">时间</div>
<div class="label-item">数值</div>
</div>
<div class="value-list">
<a-row class="value-data">
<div class="value-data-inner" v-for="val in timeList" :key="val">
{{ val ? val : '' }}
</div>
</a-row>
<a-row class="value-data">
<div class="value-data-inner" v-for="val in valueList" :key="val">
{{ val ? val : '' }}
</div>
</a-row>
</div>
</div>
<div class="chart-box" ref="chartBox"></div>
</div>
<!--数值-短文本-->
<!-- <div v-show="firstChild.type == '1'">-->
<!-- <div class="chart-title">-->
<!-- <div class="t1">{{ item?.peItemName }}</div>-->
<!-- </div>-->
<!-- <div class="panel-table">-->
<!-- <div class="label-list">-->
<!-- <div class="label-item">时间</div>-->
<!-- <div class="label-item">数值</div>-->
<!-- </div>-->
<!-- <div class="value-list">-->
<!-- <a-row class="value-data">-->
<!-- <div-->
<!-- class="value-data-inner"-->
<!-- v-for="val in timeList"-->
<!-- :key="val"-->
<!-- style="width: 200px"-->
<!-- v-html="val ? val.substring(0, 14) : ''"-->
<!-- ></div>-->
<!-- </a-row>-->
<!-- <a-row class="value-data">-->
<!-- <div-->
<!-- class="value-data-inner"-->
<!-- v-for="val in valueList"-->
<!-- :key="val"-->
<!-- style="width: 200px"-->
<!-- v-html="val && val.length > 14 ? val.substring(0, 14) + '...' : val"-->
<!-- >-->
<!-- </div>-->
<!-- </a-row>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!--数值-长文本-->
<!-- <div v-show="firstChild.type == '2'">-->
<!-- <div class="chart-title">-->
<!-- <div class="t1">{{ item?.peItemName }}</div>-->
<!-- </div>-->
<!-- <div class="panel-table">-->
<!-- <div class="label-list">-->
<!-- <div class="label-item">时间</div>-->
<!-- <div class="label-item">数值</div>-->
<!-- </div>-->
<!-- <div class="value-list">-->
<!-- <a-row class="value-data">-->
<!-- <a-tooltip v-for="val in timeList" :key="val">-->
<!-- <template #title>{{ val }}</template>-->
<!-- <div class="value-data-inner" style="width: 200px" v-html="val ? val.substring(0, 14) : ''"></div>-->
<!-- </a-tooltip>-->
<!-- </a-row>-->
<!-- <a-row class="value-data">-->
<!-- <a-tooltip v-for="val in valueList" :key="val">-->
<!-- <template #title>{{ val }}</template>-->
<!-- <div-->
<!-- class="value-data-inner"-->
<!-- style="width: 200px"-->
<!-- v-html="val && val.length > 14 ? val.substring(0, 14) + '...' : val"-->
<!-- ></div>-->
<!-- </a-tooltip>-->
<!-- </a-row>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<div v-if="firstChild.type == '2' || firstChild.type == '1'">
<div class="chart-title">
<div class="t1">{{ item?.peItemName }}</div>
</div>
<a-descriptions style="padding: 0 16px" layout="vertical" bordered :column="timeList.length + 1" size="small">
<a-descriptions-item style="white-space: nowrap; width: 220px" class="ellipsis" label="时间">数值</a-descriptions-item>
<a-descriptions-item style="width: 220px" class="ellipsis" v-for="(val, i) in timeList" :key="val" :label="val">
<a-tooltip trigger="click" placement="topLeft">
<template #title>{{ valueList[i] }}</template>
{{ valueList[i] }}
</a-tooltip>
</a-descriptions-item>
</a-descriptions>
</div>
<!--文本-->
<div v-show="isConclusion">
<div class="desc-box">
<a-descriptions :title="firstChild?.peYear" bordered>
<a-descriptions-item label="结论" :span="3" :labelStyle="{ whiteSpace: 'nowrap', width: '70px' }">
<div v-html="firstChild?.conclusion || ''"></div>
</a-descriptions-item>
<a-descriptions-item label="建议" :span="3" :labelStyle="{ whiteSpace: 'nowrap', width: '70px' }">
<div v-html="firstChild?.suggest || ''"></div>
</a-descriptions-item>
</a-descriptions>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import echarts from '/@/utils/lib/echarts';
import { ref, unref, onMounted, nextTick, computed } from 'vue';
import { chartOptions } from '/@/views/archive/employeeFile/components/analysisReport/analysisReportHooks';
const props = defineProps({
item: {
type: Object,
},
isConclusion: {
type: Boolean,
},
});
const timeList = ref([]);
const valueList = ref([]);
const firstChild = ref({});
const chartBox = ref();
const showReference = computed(() => showValue);
function showValue(val: string) {
if (!val) {
return false;
}
let result = '';
for (let i = val.length - 1; i > 0; i--) {
if (!isNaN(val[i]) || (val[i] === '.' && !result.includes('.'))) {
result += val[i];
} else {
break;
}
}
const count = parseFloat(result.split('').reverse().join(''));
return count > 0;
}
function initChart() {
const myChart = echarts.init(chartBox.value);
const options = chartOptions({
timeList: JSON.parse(JSON.stringify(unref(timeList))),
firstChild,
valueList: JSON.parse(JSON.stringify(unref(valueList))),
});
myChart.setOption(options);
window.addEventListener('resize', () => {
myChart.resize();
});
}
function useMinWidth() {
const minWidth = ref(120);
const useWidth = ref(false);
function setMinWidth(width: number, fontSize = 14) {
minWidth.value = width * fontSize;
useWidth.value = true;
}
return {
useWidth,
setMinWidth,
minWidth,
};
}
const { useWidth, minWidth, setMinWidth } = useMinWidth();
function computedStyle() {
return useWidth.value
? {
minWidth: minWidth.value + 'px',
}
: {};
}
onMounted(() => {
timeList.value = props.item.list.map((item) => item.peYear);
valueList.value = props.item.list.map((item) => item.peResult);
const length = valueList.value.map((item) => (item && item.length) || 0);
let max = Math.max(...length);
if (max > 4) {
setMinWidth(max, 14);
}
firstChild.value = props.item.list[0];
nextTick(() => {
initChart();
});
});
</script>
<style scoped lang="less">
.chart-item {
display: flex;
flex-direction: column;
border: 1px solid #f0f0f0;
padding: 10px 0;
.chart-title {
margin-left: 16px;
.t1 {
font-size: 16px;
color: #333;
font-weight: bold;
height: 26px;
display: flex;
align-items: center;
margin: 5px 0;
}
.t1:before {
content: '';
width: 4px;
height: 15px;
margin-right: 5px;
border-radius: 2px;
background-color: #1890ff;
}
.t2 {
margin: 4px 0;
}
}
.panel-table {
display: flex;
padding: 0 16px;
overflow-y: hidden;
.label-list {
display: flex;
flex-direction: column;
.label-item {
min-width: 80px;
height: 40px;
line-height: 40px;
text-align: center;
white-space: nowrap;
background-color: #f9f9f9;
border-bottom: 1px solid #f0f0f0;
}
}
.value-list {
flex: 1;
display: flex;
flex-direction: column;
overflow-y: hidden;
.value-data:first-child {
.value-data-inner {
border-top: 1px solid #f0f0f0;
}
}
.value-data {
flex: 1;
display: flex;
flex-wrap: nowrap;
.value-data-inner {
min-width: 120px;
padding: 0 5px;
height: 40px;
line-height: 40px;
text-align: center;
white-space: nowrap;
border-right: 1px solid #f0f0f0;
border-bottom: 1px solid #f0f0f0;
}
}
}
}
.chart-box {
flex: 1;
width: 100%;
min-height: 250px;
//border: 1px solid red;
}
// 文字描述
.desc-box {
padding: 0 16px;
}
:deep(.ellipsis) {
width: fit-content;
max-width: calc(100% / 9);
span {
min-height: 26px;
display: flex;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3; /* 定义文本的行数 */
-webkit-box-orient: vertical;
white-space: normal; /* 保证文本换行 */
font-family: MyCustomFont, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif,
'Apple Color Emoji', 'Segoe UI Emoji', Segoe UI Symbol, 'Noto Color Emoji';
}
}
}
</style>
@@ -1,681 +0,0 @@
import { FormSchema } from '/@/components/Form';
import { getSecondaryDepartmentList, getThirdDepartmentList } from '/@/views/system/user/user.api';
import { message } from 'ant-design-vue';
import { ColEx } from '/@/components/Form/src/types';
import { checkPassword } from '/@/hooks/checkPassword/checkPassword';
// 自适应列配置
export const adaptiveColProps: Partial<ColEx> = {
span: 6,
xs: 12, // <576px
sm: 12, // ≥576px
md: 12, // ≥768px
lg: 12, // ≥992px
xl: 12, // ≥1200px
xxl: 8, // ≥1600px
};
export function getPopupContainer() {
return document.body;
}
/**
* @Description:form校验关系
* @date `2023/8/17`
*/
export function checkRelation(_, value) {
if (!value) {
return Promise.reject('请选择与员工的关系');
}
return Promise.resolve();
}
/**
* @Description:校验值重复的个数
* @date 2023/8/17
* @param val
* @param list
* @return 出现的个数
*/
export function repeatCount(val, list) {
let i = 0;
list.map((item) => {
if (item == val && item !== '') {
i++;
}
});
return i;
}
export interface FormItem {
name: string;
phone: number | string;
familyRelation: string;
idCard: string;
id?: string;
[key: string]: any;
}
export interface TableState {
data: FormItem[];
selectedRowKeys: any[];
}
type FunForm = (isUpdate: boolean) => FormSchema[];
/**
* @Description:基础信息
* @date 2023/8/2
* @param isUpdate
*/
// @ts-ignore
export const formSchema: FunForm = (isUpdate = false) => [
{
label: '用户账号',
field: 'username',
component: 'Input',
componentProps: ({ formModel }) => {
return {
onInput: () => {
formModel.username = formModel.username.replace(/[^a-zA-Z0-9_]/g, '');
},
autocomplete: 'off',
};
},
required: true,
},
{
label: '密码',
field: 'password',
component: 'StrengthMeter',
componentProps: {
// @ts-ignore
autocomplete: 'new-password',
},
dynamicRules: () => {
return [
{
required: true,
validator: (_, value) => {
let { message } = checkPassword(value);
if (message === 'ok') {
return Promise.resolve();
} else {
return Promise.reject(message);
}
},
trigger: 'blur',
},
];
},
required: true,
ifShow: isUpdate,
},
{
label: '姓名',
field: 'realname',
component: 'Input',
required: true,
},
{
label: '性别',
field: 'sex',
component: 'JDictSelectTag',
componentProps: {
// @ts-ignore
dictCode: 'sex2',
},
required: true,
},
{
label: '手机号码',
field: 'phone',
component: 'Input',
componentProps: ({ formModel }) => {
return {
onInput: () => {
formModel.phone = formModel.phone.replace(/[^0-9]/g, '');
},
};
},
rules: [
{
required: true,
},
{
pattern: /^1[3456789][0-9]{9}$/,
message: '${label}格式有误',
},
],
},
{
label: '身份证号',
field: 'idCard',
component: 'Input',
componentProps: ({ formModel }) => {
return {
onInput: () => {
formModel.idCard = formModel.idCard.replace(/[^Xx0-9]/g, '');
},
};
},
rules: [
{
required: true,
},
{
pattern: /^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|[xX])$/,
message: '${label}格式有误',
},
],
},
{
label: '邮箱',
field: 'email',
component: 'Input',
rules: [
{
pattern: /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/,
message: '${label}格式有误',
required: true,
},
],
},
{
label: '编号',
field: 'empSysno',
component: 'Input',
required: true,
componentProps: ({ formModel }) => {
return {
onInput: () => {
formModel.empSysno = formModel.empSysno.replace(/[^0-9]/g, '');
},
};
},
},
{
label: '单位',
field: 'secondDepart',
component: 'ApiSelect',
required: true,
componentProps: ({ formModel }) => {
return {
api: getSecondaryDepartmentList,
resultField: 'result',
labelField: 'departName',
valueField: 'id',
immediate: true,
onChange: (_value) => {
formModel.orgCode = '';
},
onDeselect: () => {
formModel.secondDepart = '';
formModel.orgCode = '';
},
getPopupContainer: () => document.body,
};
},
},
{
label: '部门',
field: 'orgCode',
component: 'ApiSelect',
required: true,
componentProps: ({ formModel }) => {
return {
api: getThirdDepartmentList,
resultField: 'list',
labelField: 'departName',
params: {
secondDepartId: formModel?.secondDepart || '12313',
},
valueField: 'id',
immediate: true,
onFocus: () => {
if (!formModel.secondDepart) {
return message.warn('请先选择单位!');
}
},
getPopupContainer: () => document.body,
};
},
},
{
label: '职务',
field: 'empJob',
component: 'JDictSelectTag',
componentProps: {
// @ts-ignore
dictCode: 'e_job',
getPopupContainer: () => document.body,
},
},
{
label: '职称',
field: 'empTitle',
component: 'JDictSelectTag',
componentProps: {
// @ts-ignore
dictCode: 'e_title',
getPopupContainer: () => document.body,
},
},
{
label: '职位',
field: 'empPosition',
component: 'JDictSelectTag',
componentProps: {
// @ts-ignore
dictCode: 'emp_position',
getPopupContainer: () => document.body,
},
},
{
label: '行政级别',
field: 'empLevel',
component: 'JDictSelectTag',
componentProps: {
// @ts-ignore
dictCode: 'emp_level',
getPopupContainer: () => document.body,
},
},
{
label: '子组',
field: 'empGroup',
component: 'JDictSelectTag',
componentProps: {
// @ts-ignore
dictCode: 'emp_group',
getPopupContainer: () => document.body,
},
},
{
label: '工作状态',
field: 'empStatus',
component: 'JDictSelectTag',
componentProps: {
// @ts-ignore
dictCode: 'emp_status',
getPopupContainer: () => document.body,
},
},
{
label: '工种',
field: 'medicalWorkTypeCode',
component: 'JDictSelectTag',
componentProps: {
// @ts-ignore
dictCode: 'medical_worktype',
showSearch: true,
getPopupContainer: () => document.body,
},
},
{
label: '体检形式',
field: 'medicalOnJob',
component: 'JDictSelectTag',
componentProps: {
// @ts-ignore
dictCode: 'medical_on_job',
getPopupContainer: () => document.body,
},
},
{
label: '接害时间',
field: 'medicalHazardDate',
component: 'DatePicker',
componentProps: {
// @ts-ignore
showTime: false,
valueFormat: 'YYYY-MM-DD HH:mm:ss',
getPopupContainer: () => document.body,
},
},
{
label: '危害因素',
field: 'medicalHazardFactorCode',
component: 'JDictSelectTag',
componentProps: {
// @ts-ignore
dictCode: 'medical_hazard',
showSearch: true,
mode: 'multiple',
getPopupContainer: () => document.body,
},
},
{
label: '隐藏id',
field: 'id',
component: 'Input',
show: false,
},
];
/**
* @Description:set基本信息
* @date 2023/8/15
* @param form1Obj
* @param res
*/
export function setBasicInfo(form1Obj, res) {
// 危害因素
let medicalHazardFactorCode = null;
if (res?.extension?.medicalHazardFactorCode) {
medicalHazardFactorCode = res.extension.medicalHazardFactorCode?.split(',');
}
return {
...form1Obj,
email: res?.email || '',
empSysno: res?.extension?.empSysno,
empJob: res?.extension?.empJob,
empTitle: res?.extension?.empTitle,
empPosition: res?.extension?.empPosition,
empLevel: res?.extension?.empLevel,
empGroup: res?.extension?.empGroup,
empStatus: res?.extension?.empStatus,
medicalWorkTypeCode: res?.extension?.medicalWorkTypeCode,
medicalOnJob: res?.extension?.medicalOnJob,
medicalHazardFactorCode: medicalHazardFactorCode,
medicalHazardDate: res?.extension?.medicalHazardDate,
secondDepart: res?.secondDepart?.id, //单位
orgCode: res?.depart?.id, //部门
};
}
/**
* @Description:扩展信息
* @date 2023/7/24
* @param isUpdate
*/
// @ts-ignore
export const extendedInfoForm: FunForm = (isUpdate = false) => [
{
label: '头像',
field: 'avatar',
component: 'JImageUpload',
componentProps: {
// @ts-ignore
maxCount: 1,
},
},
{
label: '身份证正面',
field: 'empIdcardFace',
component: 'JImageUpload',
componentProps: {
// @ts-ignore
maxCount: 1,
},
},
{
label: '身份证反面',
field: 'empIdcardBack',
component: 'JImageUpload',
componentProps: {
// @ts-ignore
maxCount: 1,
},
},
{
label: '身高',
field: 'height',
component: 'Input',
componentProps: ({ formModel }) => {
return {
suffix: 'cm',
style: {
width: '100%',
},
onInput: () => {
formModel.height = formModel.height.match(/\d+\.?\d{0,2}/);
// formModel.height = formModel.height.replace(/[^0-9.]/g, '');
},
};
},
},
{
label: '体重',
field: 'weight',
component: 'Input',
componentProps: ({ formModel }) => {
return {
suffix: 'kg',
style: {
width: '100%',
},
onInput: () => {
formModel.weight = formModel.weight.match(/\d+\.?\d{0,2}/);
},
};
},
},
{
label: '出生日期',
field: 'birthday',
component: 'DatePicker',
componentProps: {
// @ts-ignore
showTime: false,
valueFormat: 'YYYY-MM-DD',
getPopupContainer: () => document.body,
disabledDate: (current) => current > new Date(),
},
ifShow: !isUpdate,
},
{
label: '年龄',
field: 'age',
component: 'InputNumber',
componentProps: {
//@ts-ignore
style: {
width: '100%',
},
},
ifShow: !isUpdate,
},
{
label: '血型',
field: 'bloodType',
component: 'JDictSelectTag',
componentProps: {
//@ts-ignore
dictCode: 'blood_type',
getPopupContainer: () => document.body,
},
},
{
label: '民族',
field: 'empNation',
component: 'JDictSelectTag',
componentProps: {
//@ts-ignore
dictCode: 'nation',
getPopupContainer: () => document.body,
},
},
{
label: '婚姻状况',
field: 'empMarriage',
component: 'JDictSelectTag',
componentProps: {
//@ts-ignore
dictCode: 'mr_state',
getPopupContainer: () => document.body,
},
},
{
label: '政治面貌',
field: 'empPolitical',
component: 'JDictSelectTag',
componentProps: {
//@ts-ignore
dictCode: 'emp_political',
getPopupContainer: () => document.body,
},
},
{
label: '学历',
field: 'empDegree',
component: 'JDictSelectTag',
componentProps: {
//@ts-ignore
dictCode: 'emp_education',
getPopupContainer: () => document.body,
},
},
{
label: '籍贯',
field: 'empNativeplace',
component: 'Input',
},
{
label: '入职时间',
field: 'empWorktime',
component: 'DatePicker',
componentProps: {
//@ts-ignore
showTime: false,
valueFormat: 'YYYY-MM-DD',
getPopupContainer: () => document.body,
disabledDate: (current) => current > new Date(),
},
},
{
label: '用工形式',
field: 'empType',
component: 'JDictSelectTag',
componentProps: {
//@ts-ignore
dictCode: 'contract',
getPopupContainer: () => document.body,
},
},
{
label: '是否上市员工',
field: 'listedFlag',
component: 'JDictSelectTag',
componentProps: {
//@ts-ignore
dictCode: 'sf_10',
getPopupContainer: () => document.body,
},
},
{
label: '工作地点',
field: 'workSpace',
component: 'Input',
},
{
label: '居住地点',
field: 'liveSpace',
component: 'Input',
},
{
label: '健康类型',
field: 'healthType',
component: 'JDictSelectTag',
componentProps: {
// @ts-ignore
dictCode: 'health_type',
getPopupContainer: () => document.body,
},
},
{
label: '健康状态',
field: 'empJkState',
component: 'JDictSelectTag',
componentProps: {
// @ts-ignore
dictCode: 'jk_status',
getPopupContainer: () => document.body,
},
},
];
/**
* @Description:set扩展信息
* @date 2023/8/15
* @param res
*/
export function setExtendedForm(res) {
return {
height: res?.extension?.height,
weight: res?.extension?.weight,
birthday: res?.birthday || '',
age: res?.age,
bloodType: res?.extension?.bloodType,
empNation: res?.extension?.empNation,
empMarriage: res?.extension?.empMarriage,
empPolitical: res?.extension?.empPolitical,
empDegree: res?.extension?.empDegree,
empNativeplace: res?.extension?.empNativeplace,
empWorktime: res?.extension?.empWorktime,
empType: res?.extension?.empType,
listedFlag: res?.extension?.listedFlag,
workSpace: res?.extension?.workSpace,
liveSpace: res?.extension?.liveSpace,
empJkState: res?.extension?.empJkState,
healthType: res?.extension?.healthType,
avatar: res?.avatar,
empIdcardFace: res?.extension?.empIdcardFace,
empIdcardBack: res?.extension?.empIdcardBack,
};
}
/**
* @Description:身份证截取生日
* @date 2023/8/15
* @param cardId
*/
export function getBirth(cardId: string) {
if (!cardId) return '';
return cardId.substring(6, 10) + '-' + cardId.substring(10, 12) + '-' + cardId.substring(12, 14);
}
/**
* @Description:处理请求参数
* @param basicInfo
* @param extendForm
*/
export function dealParams(basicInfo = {}, extendForm: any) {
// 危害因素
const medicalHazardFactorCode = basicInfo?.['medicalHazardFactorCode'] || null;
const idCard = basicInfo?.['idCard'] || null;
return {
...basicInfo,
...extendForm,
birthday: getBirth(idCard),
secondDepart: null,
extension: {
...basicInfo,
...extendForm,
birthday: getBirth(idCard),
secondDepart: null,
medicalHazardFactorCode: medicalHazardFactorCode,
},
};
}
/**
* @Description:表单字段验证
* @date 2023/8/18
* @param type
* @param value
* @param list 校验数据
*/
export function formValidate(type, value, list) {
const messageType = {
phone: '输入的手机号有重复',
idCard: '输入的身份证号有重复',
};
const emptyType = {
phone: '请输入手机号',
idCard: '请输入身份证号',
};
if (!value) {
return Promise.reject(emptyType[type]);
}
if (repeatCount(value, list) > 1) {
return Promise.reject(messageType[type]);
} else {
return Promise.resolve();
}
}
@@ -1,410 +0,0 @@
<template>
<a-spin :spinning="spinning" :delay="500">
<div class="bg-color pd-10 basic-container">
<a-tabs v-model:activeKey="activeKey" tab-position="left">
<a-tab-pane key="1" tab="基本信息">
<BasicForm @register="registerForm" />
</a-tab-pane>
<a-tab-pane key="2" tab="扩展信息" v-if="showTab2" force-render>
<BasicForm @register="registerExtendForm" />
</a-tab-pane>
<a-tab-pane key="3" tab="紧急联系人" v-if="showTab3">
<a-form ref="relationForm" :model="tableState.data" :rules="rules">
<a-list :data-source="tableState.data" :bordered="true">
<template #header>
<a-row>
<a-col flex="4" class="align-center">姓名</a-col>
<a-col flex="4" class="align-center">与员工关系</a-col>
<a-col flex="4" class="align-center">联系电话</a-col>
<a-col flex="4" class="align-center">身份证号</a-col>
<a-col flex="1" class="align-center">
<a-button
size="small"
title="添加"
type="primary"
preIcon="ant-design:plus-outlined"
@click="handleAdd"
:disabled="inputDisabled"
/>
</a-col>
</a-row>
</template>
<template #renderItem="{ item, index }">
<a-row class="row-self">
<a-col flex="4">
<div class="flex-jc">
<a-form-item style="width: 60%" class="self-form-item" :name="[index, 'name']" :rules="rules.name">
<a-input v-model:value="item.name" placeholder="请输入姓名" allow-clear :disabled="inputDisabled" />
</a-form-item>
</div>
</a-col>
<a-col flex="4">
<div class="flex-jc">
<a-form-item style="width: 60%" :name="[index, 'familyRelation']" :rules="rules.familyRelation">
<JDictSelectTag
allowClear
placeholder="请选择与员工的关系"
v-model:value="item.familyRelation"
:getPopupContainer="getPopupContainer"
dict-code="family_member_relation"
:disabled="inputDisabled"
/>
</a-form-item>
</div>
</a-col>
<a-col flex="4">
<div class="flex-jc">
<a-form-item style="width: 60%" class="self-form-item" :name="[index, 'phone']" :rules="rules.phone">
<a-input
v-model:value="item.phone"
placeholder="请输入手机号"
allow-clear
:disabled="inputDisabled"
@blur="phoneBlur($event, index)"
/>
</a-form-item>
</div>
</a-col>
<a-col flex="4">
<div class="flex-jc">
<a-form-item style="width: 60%" class="self-form-item" :name="[index, 'idCard']" :rules="rules.idCard">
<a-input
v-model:value="item.idCard"
placeholder="请输入身份证号"
allow-clear
:disabled="inputDisabled"
/>
</a-form-item>
</div>
</a-col>
<a-col flex="1" class="align-center">
<a-button
size="small"
title="删除"
preIcon="ant-design:delete-outlined"
@click="handleDelete(index, item)"
:disabled="inputDisabled"
/>
</a-col>
</a-row>
</template>
</a-list>
</a-form>
</a-tab-pane>
</a-tabs>
<div class="footer-action" v-show="!inputDisabled">
<a-button @click="cancel">重置</a-button>
<a-button class="m10" type="primary" @click="submit" :loading="loading" :disabled="loading">保存 </a-button>
</div>
</div>
</a-spin>
</template>
<script setup lang="ts" name="BasicInfo">
import { BasicForm, useForm } from '/@/components/Form';
import { computed, nextTick, onMounted, reactive, ref } from 'vue';
import { cloneDeep } from 'lodash-es';
import {
extendedInfoForm,
formSchema,
adaptiveColProps,
getPopupContainer,
FormItem,
TableState,
dealParams,
setExtendedForm,
setBasicInfo,
checkRelation,
formValidate,
} from '/@/views/archive/employeeFile/components/basicInfo/basicInfo.data';
import { getEmergency, queryById, removeEmergency, saveOrUpdate, updateEmergency } from '/@/views/archive/employeeFile/employeeFileList.api';
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
import { FormInstance } from 'ant-design-vue';
import { useRoute, useRouter } from 'vue-router';
import { useMultipleTabStore } from '/@/store/modules/multipleTab';
const route = useRoute();
let showTab2 = ref(true); //显示扩展信息
let showTab3 = ref(true); //显示紧急联系人
function init() {
let { notShowTab } = route.query;
showTab2.value = true;
showTab3.value = true;
if (notShowTab) {
nextTick(() => {
if (notShowTab.includes('2')) {
showTab2.value = false;
}
if (notShowTab.includes('3')) {
showTab3.value = false;
}
});
}
}
const rules = {
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
phone: [
{ pattern: /^1[3456789]\d{9}$/, message: '手机号码格式有误', trigger: 'blur' },
{ required: true, trigger: 'blur', validator: phoneBlur },
],
familyRelation: [{ required: true, trigger: 'blur', validator: checkRelation }],
idCard: [
{
trigger: 'blur',
pattern: /^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|[xX])$/,
message: '身份证号码格式有误',
},
{ required: true, trigger: 'blur', validator: idCardBlur },
],
};
function phoneBlur(_, value) {
return formValidate('phone', value, tableState.data?.map((item) => item.phone) || []);
}
function idCardBlur(_, value) {
return formValidate('idCard', value, tableState.data?.map((item) => item.idCard) || []);
}
const spinning = ref<boolean>(true);
const changeSpinning = () => {
spinning.value = !spinning.value;
};
const activeKey = ref<string>('1');
const tableState: TableState = reactive({
data: [],
selectedRowKeys: [],
});
const initInfo = ref();
const router = useRouter();
// 查看时禁用输入框
const inputDisabled = computed(() => route.query.type == 'detail');
const isAdd = computed(() => route.query.type == 'add');
const relationForm = ref<FormInstance>();
const loading = ref(false);
//表单配置
const [registerForm, { setProps, setFieldsValue, validate, clearValidate }] = useForm({
labelWidth: 90,
schemas: formSchema(isAdd.value),
showActionButtonGroup: false,
baseColProps: adaptiveColProps,
});
const [
registerExtendForm,
{ setProps: ExtendSetProps, validate: extendFormValidate, setFieldsValue: extendFormSetValue, clearValidate: clearExtendFormValidate },
] = useForm({
labelWidth: 90,
schemas: extendedInfoForm(!inputDisabled.value),
showActionButtonGroup: false,
baseColProps: adaptiveColProps,
});
onMounted(async () => {
spinning.value = true;
if (route.query.type == 'edit') {
await getInfo();
} else if (route.query.type == 'detail') {
await setProps({ disabled: true });
await ExtendSetProps({ disabled: true });
await getInfo();
init();
} else {
changeSpinning();
}
});
/**
* @Description:获取基础信息
* @date 2023/8/3
*/
async function getInfo() {
try {
let res = await queryById({ id: route.query.id });
initInfo.value = cloneDeep(res);
await setValue(res?.userEmployee || {});
tableState.data = res.sysUserEmergencyContactList;
} catch {
spinning.value = false;
}
}
/**
* @Description:form赋值
* @date 2023/7/24
*/
async function setValue(res) {
spinning.value = false;
const form1 = formSchema(isAdd.value).map((item) => item.field);
const form1Obj = {};
form1.forEach((item) => (form1Obj[item] = res[item]));
await setFieldsValue(setBasicInfo(form1Obj, res));
await extendFormSetValue(setExtendedForm(res));
await clearValidate();
await clearExtendFormValidate();
}
/**
* @Description:获取紧急联系人
*/
async function getEmergencyList() {
try {
let list = await getEmergency({ userId: route.query.id });
tableState.data = list.records;
} catch {}
}
function handleAdd() {
let formItem: FormItem = { name: '', familyRelation: '', phone: '', idCard: '' };
tableState.data.unshift(formItem);
}
/**
* @Description:删除紧急联系人
* @date 2023/8/3
* @param index
* @param item
*/
async function handleDelete(index, item) {
// 新增数据没添加到数据库
if (!item?.id) {
return tableState.data.splice(index, 1);
}
try {
await removeEmergency({ id: item.id });
tableState.data.splice(index, 1);
} catch {}
}
/**
* @Description:添加或者修改紧急联系人
* @date 2023/8/8
*/
async function editEmergency() {
try {
let values = tableState.data;
let params = values?.map((item) => ({ ...item, userId: route.query.id, id: item.id || '' }));
return updateEmergency(params);
} catch {}
}
function submitSend(params, isUpdate) {
saveOrUpdate(params, isUpdate, () => {
closeTab();
}).catch(() => {
loading.value = false;
});
}
/**
* @Description:提交
* @date 2023/8/8
*/
async function submit() {
await nextTick(() => {
loading.value = true;
});
try {
const basicInfo = await validate();
const extendForm = await extendFormValidate();
let res = await relationForm.value?.validate();
// 请求参数
const params = dealParams(basicInfo, extendForm);
// 编辑或新增
const isUpdate = route.query.type == 'edit';
// 提交联系人
if (res && Object.keys(res).length > 0) {
return editEmergency()
.then(() => {
// 提交表单
submitSend(params, isUpdate);
})
.catch(() => {
loading.value = false;
});
} else {
submitSend(params, isUpdate);
}
} catch (e: any) {
console.log(e, 'e');
// 处理未填字段
const [item] = e?.errorFields || {};
const obj = {
'1': formSchema(isAdd.value).map((item) => item.field),
'2': extendedInfoForm(!inputDisabled.value).map((item) => item.field),
};
for (const key in obj) {
if (obj[key].includes(item.name[0])) {
activeKey.value = key;
break;
} else {
activeKey.value = '3';
}
}
loading.value = false;
} finally {
// loading.value = false;
}
}
function closeTab() {
const tabStore = useMultipleTabStore();
let timer = setTimeout(() => {
clearTimeout(timer);
router.push({ path: '/archive/employeeFileList' });
}, 200);
tabStore.closeTabByKey(route.fullPath, router);
}
async function cancel() {
if (initInfo.value?.userEmployee) {
await setValue(initInfo.value.userEmployee);
}
await getEmergencyList();
}
</script>
<style scoped lang="less">
.basic-container {
margin: 10px;
}
.row-self {
margin-top: 8px;
padding: 0 24px;
}
.footer-action {
margin-top: 8px;
display: flex;
justify-content: center;
}
.flex-jc {
display: flex;
justify-content: center;
}
.self-form-item {
.ant-form-item-explain {
text-align: left !important;
}
}
.m10 {
margin: 0 10px;
}
.pd-10 {
padding: 10px;
}
.bg-color {
background-color: #fff;
}
.align-center {
text-align: center;
}
</style>
@@ -1,93 +0,0 @@
<template>
<div style="position: relative; height: 100%; width: 100%">
<div class="emp-detail-container">
<div class="detail-header">
<a-radio-group v-model:value="activeKey" button-style="solid" class="top-selector" @change="changeType">
<a-radio-button v-for="t in showList" :key="t.key" :value="t.key">{{ t.title }}</a-radio-button>
</a-radio-group>
<div class="detail-header-right">{{ decrypt(route.query.name) }}</div>
</div>
<keep-alive>
<component :is="currentComp" />
</keep-alive>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, shallowRef, unref } from 'vue';
import { useRoute } from 'vue-router';
import { usePermission } from '/@/hooks/web/usePermission';
import { componentsList, ComponentsType, encryption } from '/@/views/archive/employeeFile/employeeFileList.data';
const route = useRoute();
const { decrypt } = encryption();
const { hasPermission } = usePermission();
const activeKey = ref(1);
const showList = ref<ComponentsType[]>([]);
// type: detail、edit; currentTab:activeKey
const { type, currentTab, showKey } = route.query;
if (type === 'detail') {
showList.value = filterComponent(componentsList);
activeKey.value = Number(currentTab) || 1;
} else {
showList.value = filterComponent([componentsList[0]]);
}
function filterComponent(list: ComponentsType[]) {
/*
* 增加筛选出需要显示的组件 2024/08/16
*/
let arr = list;
if (showKey && showKey.length) {
const numericShowKey = showKey.map((key) => parseInt(key, 10));
arr = list.filter((item) => numericShowKey.includes(item.key));
}
return arr.filter((t) => {
if (t.auth) {
return hasPermission(t.auth);
} else {
return true;
}
});
}
function changeType() {
currentComp.value = getCurrentComp();
}
function getCurrentComp() {
return unref(showList).find((t) => t.key === unref(activeKey))?.component || '';
}
let currentComp = shallowRef<any>(getCurrentComp());
</script>
<style scoped lang="less">
.emp-detail-container {
height: 100%;
width: 100%;
overflow-y: auto;
overflow-x: hidden;
position: absolute;
top: 0;
left: 0;
display: flex;
flex-direction: column;
}
.top-selector {
padding: 10px 10px 0;
}
.detail-header {
display: flex;
justify-content: space-between;
.detail-header-right {
display: flex;
align-items: center;
font-weight: 600;
color: #333;
margin-right: 50px;
padding-top: 10px;
}
}
</style>
@@ -1,22 +0,0 @@
import { defHttp } from '/@/utils/http/axios';
export enum Api {
list = '/archives/employeeArchives/queryByUserId',
queryById = '',
save = '/health-consultation/consultation/conHealthInfo/add',
edit = '/health-consultation/consultation/conHealthInfo/edit',
deleteOne = '/health-consultation/consultation/conHealthInfo/delete',
// report = '/historyReport/getHistoryReportById',
report = '/health-archives/historyReport/selectHealthReportResult',
}
/**
* @Description: 获取列表数据
* @date 2023/7/25
* @param params
*/
export const list = (params) => defHttp.get({ url: Api.list, params });
/**
* @Description:体检报告详情
* @date 2023/8/16
* @param:
*/
export const report = (params) => defHttp.get({ url: Api.report, params });
@@ -1,145 +0,0 @@
import { BasicColumn, FormSchema } from '/@/components/Table';
export const columns: BasicColumn[] = [
{
title: '体检日期',
align: 'center',
dataIndex: 'peQueueDate',
},
{
title: '体检年度',
align: 'center',
dataIndex: 'medicalYear',
},
{
title: '体检医院',
align: 'center',
dataIndex: 'hospitalName',
},
{
title: '审核时间',
align: 'center',
dataIndex: 'auditDate',
},
{
title: '报告上传时间',
align: 'center',
dataIndex: 'createDate',
},
// {
// title: '体检检出',
// align: 'center',
// dataIndex: 'sicksDetailsToString',
// },
// {
// title: '正常/异常项',
// align: 'center',
// dataIndex: 'statusListToString',
// },
];
export const searchFormSchema: FormSchema[] = [
{
label: '体检日期',
field: 'date',
component: 'RangePicker',
componentProps: ({ formModel }) => {
return {
showTime: false,
valueFormat: 'YYYY-MM-DD',
getPopupContainer: () => document.body,
'onUpdate:value': (value) => {
if (value) {
formModel.startTime = value[0];
formModel.endTime = value[1];
} else {
formModel.startTime = null;
formModel.endTime = null;
}
},
};
},
},
{
label: '开始时间',
field: 'startTime',
component: 'Input',
show: false,
},
{
label: '结束时间',
field: 'endTime',
component: 'Input',
show: false,
},
];
const one = {
analysisName: 'cqmc',
senResultRes: 'childlist',
};
const two = {
thirdResultRes: 'childlist',
uniItemClassName: 'cqmc',
};
const three = {
peItemName: 'cqmc',
peResult: 'xmz',
unit: 'xmdw',
printContext: 'cqckz',
};
//循序键值对,依次更改
let index = 0;
const arr = [one, two, three];
export function changeKey(json) {
function getData(list, one) {
if (one && typeof one == 'object') {
const oneKeys = Object.keys(one);
oneKeys.forEach((key) => {
list.forEach((item) => {
if (item[key] && Array.isArray(item[key]) && item[key].length) {
index++;
item[one[key]] = item[key];
getData(item[key], arr[index]);
delete item[key];
} else {
item[one[key]] = item[key];
item['show'] = true;
delete item[key];
}
});
});
}
return list;
}
getData(json, one);
return json;
}
export function replaceProperties(json) {
return json.map((item) => {
return {
...item,
show: true,
cqmc: item?.analysisName,
childlist:
item?.senResultRes?.map((result) => {
return {
...result,
cqmc: result?.uniItemClassName,
show: true,
childlist:
result?.thirdResultRes?.map((thirdResult) => {
return {
...thirdResult,
cqmc: thirdResult?.peItemName,
xmz: thirdResult?.peResult,
xmdw: thirdResult?.unit,
cqckz: thirdResult?.printContext,
show: true,
};
}) || [],
};
}) || [],
};
});
}
@@ -1,75 +0,0 @@
<template>
<BasicTable @register="registerTable">
<!--操作栏-->
<template #action="{ record }">
<table-action :actions="getTableAction(record)" />
</template>
</BasicTable>
<UserReport ref="reportRefs" @register="lookRecordModal" />
</template>
<script setup lang="ts">
import { BasicTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import { columns, replaceProperties, searchFormSchema } from '/@/views/archive/employeeFile/components/examinationReport/examinationReport.data';
import { list, report } from '/@/views/archive/employeeFile/components/examinationReport/examinationReport.api';
import UserReport from '/@/views/medical/report/userResult/components/UserReport.vue';
import { useModal } from '/@/components/Modal';
import { ref } from 'vue';
import { useRoute } from 'vue-router';
const reportRefs = ref('');
const route = useRoute();
// 注册modal
const [lookRecordModal, { openModal }] = useModal();
// 注册table数据
const { tableContext } = useListPage({
tableProps: {
title: '体检报告',
columns,
api: list,
canResize: false,
searchInfo: {
userId: route.query.id,
},
formConfig: {
schemas: searchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: false,
},
actionColumn: {
width: 120,
fixed: 'right',
},
},
});
const [registerTable] = tableContext;
async function handleDetail(record: Recordable) {
let { medicalYear } = record;
try {
// let res = await report({ id: medicalId });
let res = await report({ userId: route.query.id, medicalYear: medicalYear });
// let classVoList = replaceProperties(res?.resultItemResList || []);
// const result = {
// conclusion: res?.conclusion,
// recommendation: res?.suggest,
// classVoList: classVoList,
// };
reportRefs.value['handlePhysical'](res);
} catch {
reportRefs.value['handlePhysical']({});
}
openModal(true, {
isUpdate: true,
showFooter: false,
});
}
function getTableAction(record: Recordable) {
return [
{
label: '查看报告',
onClick: handleDetail.bind(null, record),
},
];
}
</script>
<style scoped lang="less"></style>
@@ -1,49 +0,0 @@
<template>
<BasicDrawer v-bind="$attrs" :showFooter="false" @register="registerDrawer" destroyOnClose :title="title" :width="500">
<QuestionType :list="list" />
</BasicDrawer>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
import QuestionType from '/@/views/archive/employeeFile/components/questionType/index.vue';
import { queryById } from '/@/views/archive/employeeFile/components/healthAssessment/healthAssessment.api';
const title = '问卷详情';
const list = ref({});
const [registerDrawer] = useDrawerInner(async (data) => {
if (data.record?.logId) {
await getQuestionList(data.record.logId);
}
});
async function getQuestionList(logId) {
try {
let res = await queryById({ logId });
list.value = dealQuestion(res, true);
} catch {}
}
/**
* @Description:处理第8题的选中项对后面题的结果
* @date 2023/8/12
* @param isDeal
* @param json
*/
function dealQuestion(json, isDeal = false) {
if (json && typeof json === 'string') {
let res = JSON.parse(json);
if (!isDeal) return res;
let valueT = [9, 10, 11];
let valueTh = [11];
return res.filter((item) => {
if (res[7].answer == '1') {
return !valueT.includes(item.orderNo);
} else if (res[7].answer == '2') {
return !valueTh.includes(item.orderNo);
} else {
return item;
}
});
}
return [];
}
</script>
@@ -1,25 +0,0 @@
import { defHttp } from '/@/utils/http/axios';
export enum Api {
list = '/health-archives/archives/hmsEvaluationStatistics/pageCustom',
queryById = '/health-archives/archives/hmsEvaluation/questionByLogId',
exportReport = '/health-archives/archives/hmsEvaluation/pdfByLogId',
}
/**
* @Description:列表接口
* @date 2023/7/18
* @param params
*/
export const list = (params) => defHttp.get({ url: Api.list, params });
/**
* @Description:获取答题问卷详情
* @date 2023/8/12
* @param params
*/
export const queryById = (params) => defHttp.get({ url: Api.queryById, params });
/**
* @Description:获取pdf下载地址byLogId
* @date 2023/8/16
* @param params
*/
export const exportReport = (params) => defHttp.get({ url: Api.exportReport, params });
export const downloadReport = (url: string) => defHttp.get({ ...{ url: url }, ...{ responseType: 'blob' } });
@@ -1,80 +0,0 @@
import { BasicColumn, FormSchema } from '/@/components/Table';
export const columns: BasicColumn[] = [
{
title: '评估日期',
align: 'center',
dataIndex: 'createTime',
},
{
title: '体重指数',
align: 'center',
dataIndex: 'bmiDesc',
},
{
title: '缺血性心血管病',
align: 'center',
dataIndex: 'ischemicCardiovascular_dictText',
},
{
title: '糖尿病',
align: 'center',
dataIndex: 'diabetes_dictText',
},
{
title: '肺癌',
align: 'center',
dataIndex: 'lungCancer_dictText',
},
{
title: '高血压',
align: 'center',
dataIndex: 'hypertension_dictText',
},
{
title: '代谢综合征',
align: 'center',
dataIndex: 'metabolicSyndrome_dictText',
},
{
title: '详情id',
align: 'center',
dataIndex: 'logId',
ifShow: false,
},
];
export const searchFormSchema: FormSchema[] = [
{
label: '体检日期',
field: 'date',
component: 'RangePicker',
componentProps: ({ formModel }) => {
return {
showTime: false,
valueFormat: 'YYYY-MM-DD',
getPopupContainer: () => document.body,
'onUpdate:value': (value) => {
if (value) {
formModel.startDate = value[0];
formModel.endDate = value[1];
} else {
formModel.startDate = null;
formModel.endDate = null;
}
},
};
},
},
{
label: '开始时间',
field: 'startDate',
component: 'Input',
show: false,
},
{
label: '结束时间',
field: 'endDate',
component: 'Input',
show: false,
},
];
@@ -1,116 +0,0 @@
<template>
<BasicTable @register="registerTable">
<!--插槽:table标题-->
<template #tableTitle>
<div class="total-text">累计评估{{ total }}</div>
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
<HealthQuestionDrawer @register="registerDrawer" />
</template>
<script setup lang="ts" name="HealthAssessment">
import { BasicTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import { columns, searchFormSchema } from '/@/views/archive/employeeFile/components/healthAssessment/healthAssessment.data';
import { exportReport, list } from '/@/views/archive/employeeFile/components/healthAssessment/healthAssessment.api';
import { useRoute } from 'vue-router';
import HealthQuestionDrawer from '/@/views/archive/employeeFile/components/healthAssessment/components/healthQuestionDrawer.vue';
import { useDrawer } from '/@/components/Drawer';
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
import { ref } from 'vue';
import { defHttp } from '/@/utils/http/axios';
import { message } from 'ant-design-vue';
const route = useRoute();
const [registerDrawer, { openDrawer }] = useDrawer();
const total = ref();
//注册table数据
const { tableContext } = useListPage({
tableProps: {
title: '健康评估',
api: list,
columns,
canResize: false,
formConfig: { schemas: searchFormSchema },
beforeFetch: (params) => {
params['userId'] = route.query.id;
return params;
},
actionColumn: {
width: 160,
fixed: 'right',
},
afterFetch: () => {
setTotal();
},
},
});
const [registerTable, { getRawDataSource }] = tableContext;
function setTotal() {
try {
const data = getRawDataSource();
total.value = data.total;
} catch {}
}
async function exportExcel(record: Recordable) {
try {
if (!record.logId) return false;
let res = await exportReport({ logId: record.logId });
if (res) {
let urlList = res?.split(',');
if (!urlList) {
message.info('暂无PDF文件');
return;
}
urlList.map((item) => {
item && Download(item);
});
}
} catch {}
}
async function Download(url) {
const downloadReport = (url: string) =>
defHttp.get({ url: '/file/show/' + url, ...{ responseType: 'blob' } }, { isTransformResponse: false });
try {
let res: any = await downloadReport(url);
let blob = new Blob([res], { type: 'application/vnd.ms-pdf;charset=utf-8' });
let link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = `${url.substring(url.lastIndexOf('/') + 1)}`;
link.click();
} catch (e) {
throw new Error(e);
}
}
function handleDetail(record: Recordable) {
openDrawer(true, {
showFooter: false,
record,
isUpdate: false,
});
}
function getTableAction(record: Recordable) {
return [
{
label: '导出报告',
onClick: exportExcel.bind(null, record),
},
{
label: '问卷详情',
onClick: handleDetail.bind(null, record),
},
];
}
</script>
<style scoped lang="less">
.m-10 {
margin: 10px;
}
.total-text {
color: #000;
}
</style>
@@ -1,25 +0,0 @@
<template>
<BasicDrawer v-bind="$attrs" :showFooter="false" @register="registerDrawer" destroyOnClose :title="title" :width="500">
<QuestionType :list="list" />
</BasicDrawer>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
import QuestionType from '/@/views/archive/employeeFile/components/questionType/index.vue';
import { queryById } from '/@/views/archive/employeeFile/components/psychologicalAssessment/psychologicalAssessment.api';
const title = '问卷详情';
const list = ref({});
const [registerDrawer] = useDrawerInner(async (data) => {
if (data.record?.id) {
await getQuestionList(data.record.id);
}
});
async function getQuestionList(id) {
try {
let res = await queryById({ id });
list.value = JSON.parse(res);
} catch {}
}
</script>
@@ -1,11 +0,0 @@
import { defHttp } from '/@/utils/http/axios';
export enum Api {
list = '/archives/hmsEvaluation/pageCustom',
queryById = '/archives/hmsEvaluation/question',
}
/**
* @Description:列表接口
* @date 2023/7/18
*/
export const list = (params) => defHttp.get({ url: Api.list, params });
export const queryById = (params) => defHttp.get({ url: Api.queryById, params });
@@ -1,55 +0,0 @@
import { BasicColumn, FormSchema } from '/@/components/Table';
export const columns: BasicColumn[] = [
{
title: '评估日期',
align: 'center',
dataIndex: 'saveDate',
},
{
title: '健康评分',
align: 'center',
dataIndex: 'grade',
},
{
title: '评分等级',
align: 'center',
dataIndex: 'level',
},
{
title: '累计评估',
align: 'center',
dataIndex: 'fromName',
ifShow: false,
},
];
export const searchFormSchema: FormSchema[] = [
{
label: '体检日期',
field: 'date',
component: 'RangePicker',
componentProps: ({ formModel }) => {
return {
showTime: false,
valueFormat: 'YYYY-MM-DD',
getPopupContainer: () => document.body,
onChange: ([start, end]) => {
formModel.startDate = start;
formModel.endDate = end;
},
};
},
},
{
label: '开始时间',
field: 'startDate',
component: 'Input',
show: false,
},
{
label: '结束时间',
field: 'endDate',
component: 'Input',
show: false,
},
];
@@ -1,113 +0,0 @@
<template>
<BasicTable @register="registerTable">
<!--插槽:table标题-->
<template #tableTitle>
<div class="total-text">累计评估{{ total }}</div>
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
<QuestionDetailDrawer @register="registerDrawer" />
</template>
<script setup lang="ts" name="PsychologicalAssessment">
import { BasicTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import { columns } from '/@/views/archive/employeeFile/components/psychologicalAssessment/psychologicalAssessment.data';
import { list } from '/@/views/archive/employeeFile/components/psychologicalAssessment/psychologicalAssessment.api';
import QuestionDetailDrawer from '/@/views/archive/employeeFile/components/psychologicalAssessment/components/questionDetailDrawer.vue';
import { useDrawer } from '/@/components/Drawer';
import { useRoute } from 'vue-router';
import { ref } from 'vue';
import { searchFormSchema } from '/@/views/archive/employeeFile/components/healthAssessment/healthAssessment.data';
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
import { defHttp } from '/@/utils/http/axios';
import { message } from 'ant-design-vue';
const route = useRoute();
const total = ref();
//注册table数据
const { tableContext } = useListPage({
tableProps: {
title: '心理评估',
api: list,
columns,
canResize: false,
formConfig: { schemas: searchFormSchema },
actionColumn: {
width: 160,
fixed: 'right',
},
beforeFetch: (params) => {
params['userId'] = route.query.id;
params['hmsType'] = '2';
return params;
},
afterFetch: () => {
setTotal();
},
},
});
const [registerTable, { getRawDataSource }, {}] = tableContext;
const [registerDrawer, { openDrawer }] = useDrawer();
function setTotal() {
try {
const data = getRawDataSource();
total.value = data.total;
} catch {}
}
async function exportExcel(record: Recordable) {
if (!record.pdfUrl) {
message.info('暂无PDF文件');
return;
}
let urlList = record.pdfUrl?.split(',') || '';
urlList?.map((item) => {
item && Download(item);
});
}
async function Download(url) {
const downloadReport = (url: string) =>
defHttp.get({ url: '/file/show/' + url, ...{ responseType: 'blob' } }, { isTransformResponse: false });
try {
let res: any = await downloadReport(url);
let blob = new Blob([res], { type: 'application/vnd.ms-pdf;charset=utf-8' });
let link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = `${url.substring(url.lastIndexOf('/') + 1)}`;
link.click();
document.body.removeChild(link);
} catch (e) {
throw new Error(e);
}
}
function handleDetail(record: Recordable) {
openDrawer(true, {
isUpdate: false,
record,
showFooter: false,
});
}
function getTableAction(record: Recordable) {
return [
{
label: '导出报告',
onClick: exportExcel.bind(null, record),
},
{
label: '问卷详情',
onClick: handleDetail.bind(null, record),
},
];
}
</script>
<style scoped lang="less">
.m-10 {
margin: 10px;
}
.total-text {
color: #000;
}
</style>
@@ -1,36 +0,0 @@
<script setup lang="ts">
import { toRefs } from 'vue';
const props = defineProps(['item']);
const { orderNo, questionName, questionDict } = toRefs(props.item);
</script>
<template>
<div>
<div class="q-title">{{ orderNo }}.{{ questionName }}(多选)</div>
<div class="q-list">
<div class="q-item" v-for="(val, i) in questionDict" :key="i" :class="[val.value == '1' ? 'active' : '']">{{ val.title }}</div>
</div>
</div>
</template>
<style scoped lang="less">
.q-title {
line-height: 28px;
font-size: 14px;
font-weight: bold;
color: #333333;
}
.q-item {
padding: 4px 10px;
border: 1px solid #f4f4f4;
background-color: #f4f4f4;
border-radius: 6px;
margin-bottom: 8px;
&.active {
border: 1px solid #40a9ff;
background: rgba(24, 144, 255, 0.2);
}
}
</style>
@@ -1,30 +0,0 @@
<template>
<div v-for="(item, k) in list" :key="k" class="question-container">
<component :is="typeList(item.quesType)" :key="k" :item="item" />
</div>
</template>
<script setup lang="ts">
import InputTopic from '/@/views/archive/employeeFile/components/questionType/inputTopic.vue';
import RadioTopic from '/@/views/archive/employeeFile/components/questionType/radioTopic.vue';
import CheckTopic from '/@/views/archive/employeeFile/components/questionType/checkTopic.vue';
import MultipleTopic from '/@/views/archive/employeeFile/components/questionType/multipleTopic.vue';
const props = defineProps({
list: {
type: Array,
},
});
const typeList = (type) => {
const typeObj = {
5: CheckTopic,
2: MultipleTopic,
3: InputTopic,
1: RadioTopic,
};
return typeObj[type];
};
</script>
<style scoped lang="less">
.question-container {
padding: 0 10px;
}
</style>
@@ -1,25 +0,0 @@
<script setup lang="ts">
import { toRefs } from 'vue';
const props = defineProps(['item']);
const { orderNo, questionName, answer } = toRefs(props.item);
</script>
<template>
<div>
<div class="q-title">{{ orderNo }}.{{ questionName }}(填空)</div>
<div>
<a-input :value="answer" allow-clear readonly />
</div>
</div>
</template>
<style scoped lang="less">
.q-title {
line-height: 28px;
font-size: 14px;
font-weight: bold;
color: #333333;
}
</style>
@@ -1,38 +0,0 @@
<script setup lang="ts">
import { toRefs } from 'vue';
const props = defineProps(['item']);
const { orderNo, questionName, questionDict, answerCode } = toRefs(props.item);
</script>
<template>
<div>
<div class="q-title">{{ orderNo }}.{{ questionName }}(多选)</div>
<div class="q-list">
<div class="q-item" v-for="(val, i) in questionDict" :key="i" :class="[answerCode.includes(val.code) ? 'active' : '']">{{
val.title
}}</div>
</div>
</div>
</template>
<style scoped lang="less">
.q-title {
line-height: 28px;
font-size: 14px;
font-weight: bold;
color: #333333;
}
.q-item {
padding: 4px 10px;
border: 1px solid #f4f4f4;
background-color: #f4f4f4;
border-radius: 6px;
margin-bottom: 8px;
&.active {
border: 1px solid #40a9ff;
background: rgba(24, 144, 255, 0.2);
}
}
</style>
@@ -1,34 +0,0 @@
<template>
<div>
<div class="q-title">{{ orderNo }}.{{ questionName }}(单选)</div>
<div class="q-list">
<div class="q-item" v-for="(val, i) in questionDict" :key="i" :class="[val.code == answerCode ? 'active' : '']">{{ val.title }}</div>
</div>
</div>
</template>
<script setup lang="ts">
import { toRefs } from 'vue';
const props = defineProps(['item']);
const { orderNo, questionName, questionDict, answerCode } = toRefs(props.item);
</script>
<style scoped lang="less">
.q-title {
line-height: 28px;
font-size: 14px;
font-weight: bold;
color: #333333;
}
.q-item {
padding: 4px 10px;
border: 1px solid #f4f4f4;
background-color: #f4f4f4;
border-radius: 6px;
margin-bottom: 8px;
&.active {
border: 1px solid #40a9ff;
background: rgba(24, 144, 255, 0.2);
}
}
</style>
@@ -1,7 +0,0 @@
<script setup lang="ts" name="StressAssessment">
console.log(2);
</script>
<template><div></div> </template>
<style scoped lang="less"></style>
@@ -1,81 +0,0 @@
import { defHttp } from '/@/utils/http/axios';
export enum Api {
list = '/sys/healthUserEmployeeEx/list',
queryById = '/archives/employeeArchives/queryById',
// queryById = '/sys/healthUserEmployeeEx/queryById',
save = '/sys/healthUserEmployeeEx/add',
edit = '/sys/healthUserEmployeeEx/edit',
deleteOne = '/health-consultation/consultation/conHealthInfo/delete',
thirdByCode = '/sys/sysDepart/getThirdDepartListByOrgCode',
updateEmergency = '/sys/sysUserEmergencyContact/add',
getEmergency = '/sys/sysUserEmergencyContact/list',
removeEmergency = '/sys/sysUserEmergencyContact/delete',
reportStatus = '/health-archives/archives/hmsEvaluation/analysisReport/status',
reportGenerate = '/health-archives/archives/hmsEvaluation/analysisReport/generate',
}
/**
* @Description:列表接口
* @date 2023/7/17
*/
export const list = (params) => defHttp.get({ url: Api.list, params: { ...params, selectFamily: true } });
/**
* @Description:获取详情信息
* @date 2023/7/17
*/
export const queryById = (params) => defHttp.get({ url: Api.queryById, params });
/**
* 保存或者更新
* @param params
* @param isUpdate
* @param handleSuccess
*/
export const saveOrUpdate = (params, isUpdate, handleSuccess) => {
const url = isUpdate ? Api.edit : Api.save;
return defHttp.post({ url: url, params }).then(() => {
handleSuccess();
});
};
/**
* @Description:通过code查三级部门
* @date 2023/8/3
* @param params
*/
export const getThirdDepartListByOrgCode = (params) => defHttp.get({ url: Api.thirdByCode, params });
/**.
* @Description:添加或者修改紧急联系人
* @date 2023/8/3
* @param params
*/
export const updateEmergency = (params) => defHttp.post({ url: Api.updateEmergency, params }, { successNeedMessage: false });
/**
* @Description:查询紧急联系人列表
* @date 2023/8/3
* @param data
*/
export const getEmergency = (data) => {
const params = {
...data,
pageNo: 1,
pageSize: 50,
};
return defHttp.get({ url: Api.getEmergency, params });
};
/**
* @Description:删除紧急联系人
* @date 2023/8/3
* @param:
*/
export const removeEmergency = (params) => defHttp.delete({ url: Api.removeEmergency, params }, { joinParamsToUrl: true });
/**
* 获取分析报告详情状态
*
*/
export const reportStatus = (params) => defHttp.get({ url: Api.reportStatus, params });
/**
* 生成报告
* */
export const reportGenerate = (params) => defHttp.get({ url: Api.reportGenerate, params });
@@ -1,238 +0,0 @@
import { BasicColumn, FormSchema } from '/@/components/Table';
import { Component, h } from 'vue';
import { Image, message } from 'ant-design-vue';
import { getFamaleDefaultImage, getFileAccessHttpUrl } from '/@/utils/common/compUtils';
import { EyeOutlined } from '@ant-design/icons-vue';
import { render } from '/@/utils/common/renderUtils';
import BasicInfo from '/@/views/archive/employeeFile/components/basicInfo/basicInfo.vue';
import ExaminationReport from '/@/views/archive/employeeFile/components/examinationReport/examinationReport.vue';
import HealthAssessment from '/src/views/archive/employeeFile/components/healthAssessment/healthAssessment.vue';
import PsychologicalAssessment from '/@/views/archive/employeeFile/components/psychologicalAssessment/psychologicalAssessment.vue';
import AnalysisReport from '/@/views/archive/employeeFile/components/analysisReport/analysisReport.vue';
import { getSecondaryDepartmentList } from '/@/views/system/user/user.api';
import { getThirdDepartListByOrgCode } from '/@/views/archive/employeeFile/employeeFileList.api';
import { useDepartment } from '/@/utils/auth/formAuth';
import { AesEncryption } from '/@/utils/cipher';
import { cacheCipher } from '/@/settings/encryptionSetting';
export const columns: BasicColumn[] = [
{
title: '用户账号',
align: 'center',
dataIndex: 'username',
width: 100,
fixed: 'left',
},
{
title: '姓名',
align: 'center',
dataIndex: 'realname',
fixed: 'left',
width: 100,
},
{
title: '头像',
align: 'center',
dataIndex: 'avatar',
width: 100,
customRender: ({ text, record }) => {
const t = text ? text.replace(',', '') : null;
return h(Image, {
placeholder: true,
src: getFileAccessHttpUrl(t),
height: 50,
width: 50,
fallback: getFamaleDefaultImage(record.sex),
previewMask: () => {
return h(EyeOutlined, {
style: {
color: 'white',
},
});
},
});
},
},
{
title: '性别',
align: 'center',
dataIndex: 'sex',
width: 60,
customRender: ({ text }) => {
return render.renderDict(text, 'gender');
},
},
{
title: '年龄',
align: 'center',
dataIndex: 'age',
width: 60,
},
{
title: '单位',
align: 'center',
dataIndex: ['secondDepart', 'departName'],
},
{
title: '部门',
align: 'center',
dataIndex: ['depart', 'departName'],
},
{
title: '身份证',
align: 'center',
dataIndex: 'idCard',
width: 200,
},
{
title: '手机号',
align: 'center',
dataIndex: 'phone',
},
{
title: '职务',
align: 'center',
dataIndex: ['extension', 'empJob_dictText'],
},
{
title: '编号',
align: 'center',
dataIndex: ['extension', 'empNo'],
},
{
title: '家庭成员',
align: 'center',
dataIndex: 'familyNum',
},
];
export const searchFormSchema: FormSchema[] = [
{
label: '姓名',
field: 'realname',
component: 'Input',
},
{
label: '手机号',
field: 'phone',
component: 'Input',
},
{
label: '身份证号',
field: 'idCord',
component: 'Input',
},
{
label: '单位',
field: 'orgCode',
component: 'ApiSelect',
componentProps: ({ formModel, schema }) => {
const { secondSelectValue, secondSelectDisabled } = useDepartment({ schema, key: 'orgCode' });
secondSelectValue();
return {
api: getSecondaryDepartmentList,
resultField: 'result',
labelField: 'departName',
valueField: 'orgCode',
immediate: true,
onChange: () => {
formModel.orgCode2 = '';
},
onDeselect: () => {
formModel.orgCode = '';
formModel.orgCode2 = '';
},
showSearch: true,
filterOption: (input: string, option: any): boolean => {
const str: string = input.toLowerCase();
return option.label.toLowerCase().indexOf(str) >= 0;
},
disabled: secondSelectDisabled,
};
},
},
{
label: '部门',
field: 'orgCode2',
component: 'ApiSelect',
componentProps: ({ formModel, schema }) => {
const { thirdSelectValue, thirdSelectDisabled } = useDepartment({ schema, key: 'orgCode' });
thirdSelectValue();
return {
api: getThirdDepartListByOrgCode,
resultField: 'list',
labelField: 'departName',
params: {
orgCode: formModel?.orgCode || '12313',
},
valueField: 'orgCode',
immediate: true,
onFocus: () => {
if (!formModel.orgCode) {
return message.warn('请先选择单位!');
}
},
showSearch: true,
filterOption: (input: string, option: any): boolean => {
const str: string = input.toLowerCase();
return option.label.toLowerCase().indexOf(str) >= 0;
},
disabled: thirdSelectDisabled,
};
},
},
];
export interface ComponentsType {
key: number;
title: string;
component: Component;
auth?: string;
}
export const componentsList: ComponentsType[] = [
{
key: 1,
title: '健康档案',
component: BasicInfo,
},
// {
// key: 2,
// title: '压力评估',
// component: StressAssessment,
// },
{
key: 2,
title: '体检报告',
component: ExaminationReport,
},
{
key: 3,
title: '心理评估',
component: PsychologicalAssessment,
},
{
key: 4,
title: '健康评估',
component: HealthAssessment,
},
{
key: 5,
title: '体检分析报告',
component: AnalysisReport,
},
];
export function encryption() {
const aes = new AesEncryption(cacheCipher);
function encrypt(word: string) {
if (!word) return;
return aes.encryptByAES(word);
}
function decrypt(word: string) {
if (!word) return;
return aes.decryptByAES(word);
}
return { encrypt, decrypt };
}
@@ -1,89 +0,0 @@
<template>
<BasicTable @register="registerTable">
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined" v-auth="'archives:arc_assess_value:add'"> 新增 </a-button>
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
</template>
<script setup lang="ts">
import { BasicTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import { columns, encryption, searchFormSchema } from '/@/views/archive/employeeFile/employeeFileList.data';
import { list } from '/@/views/archive/employeeFile/employeeFileList.api';
import { useRouter } from 'vue-router';
import { useUserStore } from '/@/store/modules/user';
const router = useRouter();
const userStore = useUserStore();
console.log(userStore.getUserInfo?.roleCodes);
const { encrypt } = encryption();
//注册table数据
const { tableContext } = useListPage({
tableProps: {
title: '健康信息',
api: list,
columns,
canResize: false,
formConfig: {
schemas: searchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: false,
},
beforeFetch: (params) => {
if (params.orgCode2) {
params.orgCode = params.orgCode2;
}
},
actionColumn: {
width: 120,
fixed: 'right',
},
},
});
const [registerTable] = tableContext;
function userInfo(record: Recordable) {
const second = record?.secondDepart?.departName ? `-${record?.secondDepart?.departName}` : '';
const third = record?.depart?.departName ? `-${record?.depart?.departName}` : '';
const unit = second == third ? second : second + third;
return encrypt(record.realname + unit);
}
/**
* @Description:查看详情
* @date 2023/7/17
*/
function handleDetail(record: Recordable) {
router.replace({
path: '/archive/employeeFile/employeeFileDetail',
query: { id: record.id, type: 'detail', name: userInfo(record), sex: record.sex },
});
}
/**
* @Description:编辑
* @date 2023/7/17
*/
function handleEdit(record: Recordable) {
router.replace({ path: '/archive/employeeFile/employeeFileEdit', query: { id: record.id, type: 'edit', name: userInfo(record) } });
}
function handleAdd() {
router.push({ path: '/archive/employeeFile/employeeFileAdd', query: { type: 'add' } });
}
function getTableAction(record: Recordable) {
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'archives:arc_assess_value:edit',
},
{
label: '详情',
onClick: handleDetail.bind(null, record),
},
];
}
</script>
@@ -1,742 +0,0 @@
<template>
<BasicDrawer @register="registerDrawer" :title="props.title" width="70%" :showFooter="true" @ok="handleSubmit">
<div style="position: absolute; left: 50%; top: 50%; transform: translate3d(-50%, -50%, 0); z-index: 99" v-if="spining">
<a-spin tip="加载中..." />
</div>
<BasicForm @register="registerForm" class="jeecg-form">
<template #first>
<div class="sub">基本信息</div>
</template>
<template #second>
<div class="sub">住院信息</div>
</template>
<template #third>
<div class="sub">分类信息</div>
</template>
<template #A>
<div>
<div class="label-class">A类大病信息</div>
</div>
<div style="flex: 1">
<a-form :model="data1" class="option-form" ref="optionForm">
<a-form-item-rest>
<div class="table-d">
<div class="table-td-d d1">大病名称</div>
<div class="table-td-d d1">确诊年份</div>
<div class="table-td-d d1">确诊医院</div>
<div class="table-td-d d1">大病状态</div>
<div class="table-td-d d1">治疗情况</div>
<div class="table-td-d d1">
<span style="color: #1890ff; cursor: pointer" @click="addItem('a')"> 添加 </span>
</div>
</div>
<template v-for="(item, index) in data1.option" :key="`temp${index}`">
<div class="table-d table-d-d">
<div class="table-td-d tabled-td-d-d d1">
<a-form-item
:name="['option', index, 'name']"
:rules="{
required: true,
// message: `请输入第${index}个大病名称`,
message: '',
}"
>
<JDictSelectTag
style="max-width: 100%"
v-model:value="item.name"
placeholder="请选择大病名称"
dictCode="ill_type"
/>
</a-form-item>
</div>
<div class="table-td-d tabled-td-d-d d1">
<a-form-item :name="['option', index, 'time']">
<a-date-picker v-model:value="item.time" picker="year" value-format="YYYY" />
</a-form-item>
</div>
<div class="table-td-d tabled-td-d-d d1">
<a-form-item :name="['option', index, 'hospital']">
<a-input v-model:value="item.hospital" placeholder="请输入确诊医院" />
</a-form-item>
</div>
<div class="table-td-d tabled-td-d-d d1 user-group">
<a-form-item
:name="['option', index, 'status']"
:rules="{
required: true,
// message: `请选择第${index}个大病状态`,
message: '',
}"
>
<JDictSelectTag
style="max-width: 100%"
v-model:value="item.status"
placeholder="请选择大病状态"
dictCode="archives_ill_status"
/>
</a-form-item>
</div>
<div class="table-td-d tabled-td-d-d d1">
<a-form-item :name="['option', index, 'cure']">
<a-input v-model:value="item.cure" placeholder="请输入治疗情况" />
</a-form-item>
</div>
<div class="table-td-d tabled-td-d-d d1">
<span style="color: #1890ff; cursor: pointer" @click="delItem('a', index)"> 删除 </span>
</div>
</div>
</template>
</a-form-item-rest> </a-form
><div style="display: flex"> </div>
</div>
</template>
<template #B>
<div style="display: flex">
<div>
<div class="label-class">B类慢病信息</div>
</div>
<div style="flex: 1">
<a-form :model="data2" class="option-form" ref="optionForm">
<a-form-item-rest>
<div class="table-d">
<div class="table-td-d d2">慢病名称</div>
<div class="table-td-d d2">确诊年份</div>
<div class="table-td-d d2">确诊医院</div>
<div class="table-td-d d2">治疗情况</div>
<div class="table-td-d d2">
<span style="color: #1890ff; cursor: pointer" @click="addItem('b')"> 添加 </span>
</div>
</div>
<template v-for="(item, index) in data2.option" :key="`temp${index}`">
<div class="table-d table-d-d">
<div class="table-td-d tabled-td-d-d d2">
<a-form-item
:name="['option', index, 'name']"
:rules="{
required: true,
// message: `请输入第${index}个大病名称`,
message: '',
}"
>
<JDictSelectTag
style="max-width: 100%"
v-model:value="item.name"
placeholder="请选择慢病名称"
dictCode="hms_disease_type"
/>
</a-form-item>
</div>
<div class="table-td-d tabled-td-d-d d2">
<a-form-item :name="['option', index, 'time']">
<a-date-picker v-model:value="item.time" picker="year" value-format="YYYY" />
</a-form-item>
</div>
<div class="table-td-d tabled-td-d-d d2">
<a-form-item :name="['option', index, 'hospital']">
<a-input v-model:value="item.hospital" placeholder="请输入确诊医院" />
</a-form-item>
</div>
<div class="table-td-d tabled-td-d-d d2">
<a-form-item :name="['option', index, 'cure']">
<a-input v-model:value="item.cure" placeholder="请输入治疗情况" />
</a-form-item>
</div>
<div class="table-td-d tabled-td-d-d d2">
<span style="color: #1890ff; cursor: pointer" @click="delItem('b', index)"> 删除 </span>
</div>
</div>
</template>
</a-form-item-rest>
</a-form>
</div>
</div>
</template>
<template #C>
<div style="display: flex">
<div>
<div class="label-class">C类重点指标异常</div>
</div>
<div style="flex: 1">
<a-form :model="data3" class="option-form" ref="optionForm">
<a-form-item-rest>
<div class="table-d">
<div class="table-td-d d3">指标名称</div>
<div class="table-td-d d3">指标值</div>
<div class="table-td-d d3">参考范围</div>
<div class="table-td-d d3">确诊年份</div>
<div class="table-td-d d3">确诊医院</div>
<div class="table-td-d d3">
<span style="color: #1890ff; cursor: pointer" @click="addItem('c')"> 添加 </span>
</div>
</div>
<template v-for="(item, index) in data3.option" :key="`temp${index}`">
<div class="table-d table-d-d">
<div class="table-td-d tabled-td-d-d d3">
<a-input v-model:value="item.name" readonly />
</div>
<div class="table-td-d tabled-td-d-d d3">
<a-input v-model:value="item.value" readonly />
</div>
<div class="table-td-d tabled-td-d-d d3">
<a-input v-model:value="item.scope" readonly />
</div>
<div class="table-td-d tabled-td-d-d d3">
<a-form-item :name="['option', index, 'hospital']">
<a-input v-model:value="item.time" readonly />
</a-form-item>
</div>
<div class="table-td-d tabled-td-d-d d3">
<a-form-item :name="['option', index, 'hospital']">
<a-input v-model:value="item.hospital" readonly />
</a-form-item>
</div>
<div class="table-td-d tabled-td-d-d d3">
<span style="color: #1890ff; cursor: pointer" @click="delItem('c', index)"> 删除 </span>
</div>
</div>
</template>
</a-form-item-rest>
</a-form>
</div>
</div>
</template>
<template #D>
<div style="display: flex">
<div>
<div class="label-class">D类健康风险评估</div>
</div>
<div style="flex: 1">
<a-form :model="data4" class="option-form" ref="optionForm">
<a-form-item-rest>
<div class="table-d">
<div class="table-td-d d4">疾病名称</div>
<div class="table-td-d d4">风险等级</div>
<div class="table-td-d d4">评估年份</div>
<div class="table-td-d d4">
<span style="color: #1890ff; cursor: pointer" @click="addItem('d')"> 添加 </span>
</div>
</div>
<template v-for="(item, index) in data4.option" :key="`temp${index}`">
<div class="table-d table-d-d">
<div class="table-td-d tabled-td-d-d d4">
<a-input v-model:value="item.name" readonly />
</div>
<div class="table-td-d tabled-td-d-d d4">
<a-input v-model:value="item.levelDesc" readonly />
</div>
<div class="table-td-d tabled-td-d-d d4">
<a-input v-model:value="item.time" readonly />
</div>
<div class="table-td-d tabled-td-d-d d4">
<span style="color: #1890ff; cursor: pointer" @click="delItem('d', index)"> 删除 </span>
</div>
</div>
</template>
</a-form-item-rest>
</a-form>
</div>
</div>
</template>
</BasicForm>
<ChooseSome
class="choose-some"
:width="1000"
@register="examinationModal"
@select-some="onSelectUserOk"
title="体检报告"
zIndex="1001"
:tableprops="tableProps"
selection-type="checkbox"
/>
<ChooseSome
class="choose-some"
:width="1000"
@register="examinationModal1"
@select-some="onSelectUserOk1"
title="评估结果"
zIndex="1001"
:tableprops="tableProps1"
selection-type="checkbox"
/>
</BasicDrawer>
</template>
<script setup lang="ts">
import BasicDrawer from '/@/components/Drawer/src/BasicDrawer.vue';
import BasicForm from '/@/components/Form/src/BasicForm.vue';
import { useDrawer, useDrawerInner } from '/@/components/Drawer';
import { useForm } from '/@/components/Form';
import { mSearchSchema, schemas, mColumns, mSearchSchema1, mColumns1 } from '/@/views/archive/fiveClassPeople/index.data';
import { ref } from 'vue';
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
import {
groupUserAApi,
groupUserBApi,
groupUserCApi,
groupUserDApi,
groupUserEApi,
groupUserCLatestReportApi,
groupUserDLatestReportApi,
detailAApi,
detailBApi,
detailCApi,
detailDApi,
groupUserExtByUserIdApi,
editByUserIdApi,
} from '/@/views/archive/fiveClassPeople/index.api';
import ChooseSome from '/@/views/compoents/chooseSome/index.vue';
import { message } from 'ant-design-vue';
const props = defineProps({
title: {
type: String,
default: () => '编辑',
},
});
const spining = ref(false);
const data1 = ref<object>({
option: [],
});
const itemA = ref<object>({
name: '',
time: '',
hospital: '',
status: '',
});
const data2 = ref<object>({
option: [],
});
const itemB = ref<object>({
name: '',
time: '',
hospital: '',
});
const data3 = ref<object>({
option: [],
});
const data4 = ref<object>({
option: [],
});
const [examinationModal, { openDrawer }] = useDrawer();
const [examinationModal1, { openDrawer: openDrawer1 }] = useDrawer();
const tableProps = ref({
tableProps: {
api: groupUserCLatestReportApi,
columns: mColumns,
canResize: false,
immediate: false,
clearSelectOnPageChange: false,
rowKey: (record: Recordable) => {
return JSON.stringify({
peItemName: record?.peItemName,
peResult: record?.peResult,
printContext: record?.printContext,
medicalYear: record?.medicalYear,
hospitalName: record?.hospitalName,
uniItemId: record?.uniItemId,
});
},
beforeFetch: (params) => {
params['userId'] = getFieldsValue()?.userId;
return params;
},
afterFetch: (data) => {
let result: any[] = [];
data.length > 0 &&
data.map((item) => {
if (item?.senResultRes && item?.senResultRes.length > 0) {
item?.senResultRes.map((it) => {
if (it?.thirdResultRes && it?.thirdResultRes.length > 0) {
result = result.concat(it?.thirdResultRes);
}
});
}
});
return result;
},
formConfig: {
schemas: mSearchSchema,
autoSubmitOnEnter: true,
showAdvancedButton: false,
fieldMapToNumber: [],
fieldMapToTime: [],
labelWidth: 140,
baseColProps: {
xs: 12,
sm: 12,
md: 12,
lg: 12,
xl: 12,
xxl: 12,
},
actionColOptions: {
style: {
paddingLeft: '144px',
},
span: 24,
offset: 0,
xs: 12,
sm: 12,
md: 12,
lg: 12,
xl: 12,
xxl: 12,
},
},
showActionColumn: false,
},
});
const tableProps1 = ref({
tableProps: {
api: groupUserDLatestReportApi,
columns: mColumns1,
canResize: false,
immediate: false,
clearSelectOnPageChange: false,
rowKey: (record: Recordable) => {
return JSON.stringify({
name: record?.name,
levelDesc: record?.levelDesc,
level: record?.level,
year: record?.year + '',
});
},
beforeFetch: (params) => {
params['userId'] = getFieldsValue()?.userId;
return params;
},
showTableSetting: true,
tableSetting: {
redo: true,
setting: false,
},
// afterFetch: (data) => {
// let result: any[] = [];
//
// data.length > 0 &&
// data.map((item) => {
// if (item?.senResultRes && item?.senResultRes.length > 0) {
// item?.senResultRes.map((it) => {
// if (it?.thirdResultRes && it?.thirdResultRes.length > 0) {
// result = result.concat(it?.thirdResultRes);
// }
// });
// }
// });
//
// return result;
// },
useSearchForm: false,
formConfig: {
schemas: mSearchSchema1,
autoSubmitOnEnter: true,
showAdvancedButton: false,
fieldMapToNumber: [],
fieldMapToTime: [],
labelWidth: 120,
baseColProps: {
xs: 12,
sm: 12,
md: 12,
lg: 12,
xl: 12,
xxl: 12,
},
actionColOptions: {
style: {
paddingLeft: '122px',
},
span: 24,
offset: 0,
xs: 12,
sm: 12,
md: 12,
lg: 12,
xl: 12,
xxl: 12,
},
},
showActionColumn: false,
},
});
const emit = defineEmits(['success']);
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
spining.value = true;
await resetFields();
data1.value.option = [];
data2.value.option = [];
data3.value.option = [];
data4.value.option = [];
let res = {};
try {
switch (data.record.userGroup) {
case 'a':
const { records: r1 } = await detailAApi({ pageNo: 1, pageSize: 9999, userId: data.record.userId });
res = await groupUserExtByUserIdApi({ pageNo: 1, pageSize: 9999, userId: data.record.userId });
data1.value.option = r1;
break;
case 'b':
const { records: r2 } = await detailBApi({ pageNo: 1, pageSize: 9999, userId: data.record.userId });
res = await groupUserExtByUserIdApi({ pageNo: 1, pageSize: 9999, userId: data.record.userId });
data2.value.option = r2;
break;
case 'c':
const { records: r3 } = await detailCApi({ pageNo: 1, pageSize: 9999, userId: data.record.userId });
data3.value.option = r3;
break;
case 'd':
const { records: r4 } = await detailDApi({ pageNo: 1, pageSize: 9999, userId: data.record.userId });
data4.value.option = r4.map((item: any) => ({
name: item?.name,
levelDesc: item?.levelDesc,
level: item?.level,
time: item?.time,
}));
console.log(data4.value.option);
break;
case 'e':
break;
}
await setFieldsValue({
...data.record,
...res,
});
setDrawerProps({
confirmLoading: false,
});
} finally {
spining.value = false;
}
});
function addItem(type) {
switch (type) {
case 'a':
data1.value?.option.push(JSON.parse(JSON.stringify(itemA.value)));
break;
case 'b':
data2.value?.option.push(JSON.parse(JSON.stringify(itemB.value)));
break;
case 'c':
const list = data3.value.option.map((item: any) => {
return JSON.stringify({
peItemName: item?.name,
peResult: item?.value,
printContext: item?.scope,
medicalYear: item?.time,
hospitalName: item?.hospital,
uniItemId: item?.uniItemId,
});
});
openDrawer(true, {
selectedRowKeys: list,
});
break;
case 'd':
const list1 = data4.value.option.map((item: any) => {
return JSON.stringify({
name: item?.name,
levelDesc: item?.levelDesc,
level: item?.level,
year: item?.time + '',
});
});
console.log(list1);
openDrawer1(true, {
selectedRowKeys: list1,
});
break;
}
}
function delItem(type, index) {
switch (type) {
case 'a':
data1.value?.option.splice(index, 1);
break;
case 'b':
data2.value?.option.splice(index, 1);
break;
case 'c':
data3.value?.option.splice(index, 1);
break;
case 'd':
data4.value?.option.splice(index, 1);
break;
}
}
const [registerForm, { setFieldsValue, resetFields, validate, getFieldsValue }] = useForm({
schemas,
showAdvancedButton: false,
showActionButtonGroup: false,
labelWidth: 130,
});
const optionForm = ref();
async function handleSubmit() {
try {
const values = await validate();
let values1;
// if (values['userGroup'] != 'e') {
if (!['c', 'd', 'e'].includes(values['userGroup'])) {
values1 = await optionForm.value.validate();
}
let params =
values['userGroup'] == 'e'
? { userId: values.userId }
: {
userId: values.userId,
userGroup: values.userGroup,
list: values['userGroup'] === 'c' ? data3.value.option : values['userGroup'] === 'd' ? data4.value.option : values1?.option,
};
console.log(params);
if (values['userGroup'] !== 'e' && (!params?.list || params?.list.length === 0)) return message.warn('请填写分类信息');
setDrawerProps({
confirmLoading: true,
});
switch (values['userGroup']) {
case 'a':
await editByUserIdApi(values);
await groupUserAApi(params);
break;
case 'b':
await editByUserIdApi(values);
await groupUserBApi(params);
break;
case 'c':
await groupUserCApi(params);
break;
case 'd':
await groupUserDApi(params);
break;
case 'e':
await groupUserEApi(params);
break;
}
closeDrawer();
emit('success', values['userGroup']);
} finally {
setDrawerProps({
confirmLoading: false,
});
}
}
function onSelectUserOk(e) {
data3.value.option =
e.length > 0
? e.map((item) => {
return {
name: JSON.parse(item)?.peItemName,
value: JSON.parse(item)?.peResult,
scope: JSON.parse(item)?.printContext,
time: JSON.parse(item)?.medicalYear,
hospital: JSON.parse(item)?.hospitalName,
uniItemId: JSON.parse(item)?.uniItemId,
};
})
: [];
}
function onSelectUserOk1(e) {
console.log(e);
data4.value.option =
e.length > 0
? e.map((item) => {
return {
name: JSON.parse(item)?.name,
levelDesc: JSON.parse(item)?.levelDesc,
level: JSON.parse(item)?.level,
time: JSON.parse(item)?.year,
};
})
: [];
}
</script>
<style scoped lang="less">
.table-d {
width: 100%;
display: flex;
border-top: 1px solid #f0f0f0;
border-right: 1px solid #f0f0f0;
.table-td-d {
border-left: 1px solid #f0f0f0;
border-bottom: 1px solid #f0f0f0;
background-color: #fafafa;
height: 50px;
line-height: 50px !important;
text-align: center;
}
.d1 {
width: calc(100% / 6);
}
.d2 {
width: 20%;
}
.d4 {
width: 25%;
}
.d3 {
width: calc(100% / 6);
}
.table-d-d {
background-color: #ffffff;
display: flex;
align-items: center;
justify-content: center;
}
}
.option-form {
.ant-form-item {
line-height: 50px !important;
}
}
:deep(.user-group .ant-select-selector) {
padding: 0 !important;
}
.sub {
font-size: 16px;
font-weight: bold;
padding-left: 10px;
}
:deep(.ant-form-item-label .form_item_b-class) {
background-color: red;
position: relative;
}
.label-class {
padding-left: 20px;
position: relative;
&::before {
position: absolute;
font-size: 14px;
top: 1px;
left: 10px;
color: #ff4d4f;
content: '*';
font-family: SimSun, sans-serif;
}
}
</style>
@@ -1,45 +0,0 @@
import { defHttp } from '/@/utils/http/axios';
export enum Api {
list = '/health-system/sys/user/listGroupUser',
groupUserCLatestReport = '/health-archives/archives/groupUserC/latestReport',
groupUserDLatestReport = '/health-archives/archives/groupUserD/latestReport',
groupUserA = '/health-archives/archives/groupUserA/addBatch',
groupUserB = '/health-archives/archives/groupUserB/addBatch',
groupUserC = '/health-archives/archives/groupUserC/addBatch',
groupUserD = '/health-archives/archives/groupUserD/addBatch',
groupUserE = '/health-archives/archives/groupUserA/updateUserToE',
groupUserAImportExcel = '/health-archives/archives/groupUserA/importExcel',
groupUserBImportExcel = '/health-archives/archives/groupUserB/importExcel',
groupImportExcel = '/health-archives/archives/groupUserC/importExcelBatchUpdateUserGroup',
autoAddC = '/health-archives/archives/groupUserC/autoAddC',
autoAddD = '/health-archives/archives/groupUserD/autoAddD',
detailA = '/health-archives/archives/groupUserA/list',
groupUserExtByUserId = '/archives/groupUserExt/groupUserExtByUserId',
detailB = '/health-archives/archives/groupUserB/list',
detailC = '/health-archives/archives/groupUserC/list',
detailD = '/health-archives/archives/groupUserD/list',
editByUserId = '/health-archives/archives/groupUserExt/editByUserId',
excelImportTemplate = '/health-archives/archives/groupUserA/excelImportTemplate',
listGroupUserExport = '/health-system/sys/user/listGroupUserExport', // 五类人群导出
}
export const listApi = (params) => defHttp.get({ url: Api.list, params });
export const groupUserCLatestReportApi = (params) => defHttp.get({ url: Api.groupUserCLatestReport, params });
export const groupUserDLatestReportApi = (params) => defHttp.get({ url: Api.groupUserDLatestReport, params });
export const groupUserAApi = (params) => defHttp.post({ url: Api.groupUserA, params });
export const groupUserBApi = (params) => defHttp.post({ url: Api.groupUserB, params });
export const groupUserCApi = (params) => defHttp.post({ url: Api.groupUserC, params });
export const groupUserDApi = (params) => defHttp.post({ url: Api.groupUserD, params });
export const groupUserEApi = (params) => defHttp.post({ url: Api.groupUserE, params }, { joinParamsToUrl: true });
export const autoAddCApi = () => defHttp.post({ url: Api.autoAddC });
export const autoAddDApi = () => defHttp.post({ url: Api.autoAddD });
export const groupUserExtByUserIdApi = (params) => defHttp.get({ url: Api.groupUserExtByUserId, params }, { joinParamsToUrl: true });
export const detailAApi = (params) => defHttp.get({ url: Api.detailA, params }, { joinParamsToUrl: true });
export const detailBApi = (params) => defHttp.get({ url: Api.detailB, params }, { joinParamsToUrl: true });
export const detailCApi = (params) => defHttp.get({ url: Api.detailC, params }, { joinParamsToUrl: true });
export const detailDApi = (params) => defHttp.get({ url: Api.detailD, params }, { joinParamsToUrl: true });
export const editByUserIdApi = (params) => defHttp.post({ url: Api.editByUserId, params }, { successNeedMessage: false });
export const excelImportTemplateUrl = Api.excelImportTemplate;
export const listGroupUserExportApi = (params) => defHttp.get({ url: Api.listGroupUserExport, params }, { joinParamsToUrl: true });
@@ -1,274 +0,0 @@
import { BasicColumn, FormSchema } from '/@/components/Table';
import dayjs from 'dayjs';
import { orgSearchInfo } from '/@/utils/orgSearchInfo';
export const searchFormSchema: FormSchema[] = [
...orgSearchInfo(),
{
label: '身份证号',
field: 'idCard',
component: 'Input',
},
{
label: '健康分类',
field: 'userGroup',
component: 'JDictSelectTag',
componentProps: () => ({ dictCode: 'user_group' }),
},
];
export const mSearchSchema: FormSchema[] = [
{
label: '重点指标项',
field: 'peItemName',
component: 'Input',
},
{
label: '是否异常项',
field: 'colour',
component: 'Select',
componentProps: () => ({
options: [
{ label: '否', value: '0' },
{ label: '是', value: '1' },
],
}),
},
];
export const mSearchSchema1: FormSchema[] = [
{
label: '疾病名称',
field: 'name',
component: 'Input',
},
{
label: '风险等级',
field: 'illName',
component: 'Input',
show: false,
defaultValue: '体重',
},
];
export const columns: BasicColumn[] = [
{
title: '单位',
dataIndex: 'secondDepart',
align: 'center',
},
{
title: '部门',
dataIndex: 'depart',
align: 'center',
},
{
title: '姓名',
dataIndex: 'realName',
align: 'center',
},
{
title: '身份证号',
dataIndex: 'idCard',
align: 'center',
},
{
title: '健康分类',
dataIndex: 'userGroup_dictText',
align: 'center',
width: 100,
},
{
title: '更新时间',
dataIndex: 'userGroupUpdateTime',
align: 'center',
customRender: ({ text }) => {
return text ? dayjs(text).format('YYYY-MM-DD HH:mm:ss') : '';
},
},
];
export const mColumns: BasicColumn[] = [
{
title: '重点指标项',
dataIndex: 'peItemName',
align: 'center',
},
{
title: '指标值',
dataIndex: 'peResult',
align: 'center',
},
{
title: '参考范围',
dataIndex: 'printContext',
align: 'center',
},
{
title: '检查年份',
dataIndex: 'medicalYear',
align: 'center',
},
{
title: '检查医院',
dataIndex: 'hospitalName',
align: 'center',
},
{
title: '是否异常项',
dataIndex: 'colour',
customRender: ({ text }) => (text == '0' ? '否' : '是'),
align: 'center',
},
];
export const mColumns1: BasicColumn[] = [
{
title: '疾病名称',
dataIndex: 'name',
align: 'center',
},
{
title: '风险等级',
dataIndex: 'levelDesc',
align: 'center',
},
{
title: '评估年份',
dataIndex: 'year',
align: 'center',
},
];
export const schemas: FormSchema[] = [
{
label: '',
field: 'first',
component: 'Input',
slot: 'first',
},
{
label: '',
field: 'id',
component: 'Input',
show: false,
},
{
label: '',
field: 'userId',
component: 'Input',
show: false,
},
{
label: '单位',
field: 'secondDepart',
component: 'Input',
componentProps: () => ({ disabled: true }),
},
{
label: '部门',
field: 'depart',
component: 'Input',
componentProps: () => ({ disabled: true }),
},
{
label: '姓名',
field: 'realName',
component: 'Input',
componentProps: () => ({ disabled: true }),
},
{
label: '身份证号',
field: 'idCard',
component: 'Input',
componentProps: () => ({ disabled: true }),
},
{
label: '健康分类',
field: 'userGroup',
component: 'JDictSelectTag',
required: true,
componentProps: () => ({ dictCode: 'user_group' }),
},
{
label: '',
field: 'second',
component: 'Input',
slot: 'second',
ifShow: ({ values }) => ['a', 'b'].includes(values.userGroup),
},
{
label: '住院状态',
field: 'status',
component: 'JDictSelectTag',
componentProps: () => ({ dictCode: 'group_user_status' }),
ifShow: ({ values }) => ['a', 'b'].includes(values.userGroup),
},
{
label: '所在医院',
field: 'hospital',
component: 'Input',
ifShow: ({ values }) => ['a', 'b'].includes(values.userGroup),
},
{
label: '住院时间',
field: 'hospitalTime',
component: 'DatePicker',
componentProps: () => ({ format: 'YYYY-MM-DD', valueFormat: 'YYYY-MM-DD', style: { width: '100%' } }),
ifShow: ({ values }) => ['a', 'b'].includes(values.userGroup),
},
{
label: '住院次数',
field: 'hospitalNum',
component: 'InputNumber',
componentProps: () => ({ dictCode: 'user_group', style: { width: '100%' } }),
ifShow: ({ values }) => ['a', 'b'].includes(values.userGroup),
},
{
label: '联系人',
field: 'contact',
component: 'Input',
componentProps: () => ({ dictCode: 'user_group' }),
ifShow: ({ values }) => ['a', 'b'].includes(values.userGroup),
},
{
label: '联系电话',
field: 'contactMobile',
component: 'Input',
componentProps: () => ({ dictCode: 'user_group' }),
rules: [
// { required: true, message: '请输入联系电话', trigger: 'blur' },
{ pattern: /^1[3456789]\d{9}$/, message: '手机号码格式有误' },
],
ifShow: ({ values }) => ['a', 'b'].includes(values.userGroup),
},
{
label: '',
field: 'third',
component: 'Input',
slot: 'third',
ifShow: ({ values }) => ['a', 'b', 'c', 'd'].includes(values.userGroup),
},
{
label: '',
field: 'idCard',
component: 'Input',
slot: 'A',
ifShow: ({ values }) => values.userGroup == 'a',
},
{
label: '',
field: 'idCard',
component: 'Input',
slot: 'B',
ifShow: ({ values }) => values.userGroup == 'b',
},
{
label: '',
field: 'idCard',
component: 'Input',
slot: 'C',
ifShow: ({ values }) => values.userGroup == 'c',
},
{
label: '',
field: 'idCard',
component: 'Input',
slot: 'D',
ifShow: ({ values }) => values.userGroup == 'd',
},
];
-254
View File
@@ -1,254 +0,0 @@
<template>
<BasicTable @register="registerTable">
<template #tableTitle>
<a-button v-auth="'archives:group_user_batch:big'" type="primary" preIcon="ant-design:import-outlined" @click="downloadTemplate1">
下载大病人员模板</a-button
>
<a-upload
v-auth="'archives:group_user_batch:big'"
name="file"
:showUploadList="false"
:customRequest="onImportXls1"
accept=".xlsx, .xls, application/vnd.ms-excel-=='"
>
<a-button type="primary" preIcon="ant-design:import-outlined" :loading="bigLoading">导入大病人员</a-button>
</a-upload>
<a-button v-auth="'archives:group_user_batch:slow'" type="primary" preIcon="ant-design:import-outlined" @click="downloadTemplate2">
下载慢病人员模板</a-button
>
<a-upload
v-auth="'archives:group_user_batch:slow'"
name="file"
:showUploadList="false"
:customRequest="onImportXls2"
accept=".xlsx, .xls, application/vnd.ms-excel-=='"
>
<a-button type="primary" preIcon="ant-design:import-outlined" :loading="slowLoading">导入慢病人员</a-button>
</a-upload>
<a-button type="primary" preIcon="ant-design:plus-outlined" v-auth="'archives:group_user_batch:automaticAbnormal'" @click="automatic1">
自动添加最新体检异常项
</a-button>
<a-button type="primary" preIcon="ant-design:plus-outlined" v-auth="'archives:group_user_batch:automaticResult'" @click="automatic2">
自动添加评估结果
</a-button>
<a-button v-auth="'archives:group_user_batch:importExcel'" type="primary" preIcon="ant-design:import-outlined" @click="downloadTemplate3">
下载批量修改导入模板
</a-button>
<a-upload
v-auth="'archives:group_user_batch:importExcel'"
name="file"
:showUploadList="false"
:customRequest="onImportXls3"
accept=".xlsx, .xls, application/vnd.ms-excel-=='"
>
<a-button type="primary">批量修改导入</a-button>
</a-upload>
<a-button v-auth="'archives:group_user_batch:exportFivePeople'" type="primary" preIcon="ant-design:export-outlined" @click="exportReport">
导出
</a-button>
<a-button
v-auth="'archives:group_user_batch:exportFivePeopleRecord'"
preIcon="ant-design:search-outlined"
@click="handleLookRecord"
type="primary"
>查看导出记录
</a-button>
<!-- <a-button v-auth="'archives:group_user_batch:importExcel'" @click="handleLookRecord" type="primary"> 查看批量修改导入记录 </a-button>-->
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
<index-drawer @register="registerDrawer" @success="handleSuccess" />
<!-- <ExportUtil task-code="batchUpdateUserGroup" :params="{ handleType: '2' }" @register="registerExport" />-->
<ExportUtil task-code="groupUserTaskCode" @register="registerExport" />
</template>
<script setup lang="ts">
import BasicTable from '/@/components/Table/src/BasicTable.vue';
import { TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import {
listApi,
Api,
autoAddCApi,
autoAddDApi,
excelImportTemplateUrl,
listGroupUserExportApi,
} from '/@/views/archive/fiveClassPeople/index.api';
import { columns, searchFormSchema } from '/@/views/archive/fiveClassPeople/index.data';
import IndexDrawer from '/@/views/archive/fiveClassPeople/components/indexDrawer.vue';
import { useDrawer } from '/@/components/Drawer';
import { useMethods } from '/@/hooks/system/useMethods';
import { downloadExcel } from '/@/views/healthMonitor/healMonitorManage/monitorToll/toolManagement/toolHooks';
import { ref } from 'vue';
import ExportUtil from '/@/utils/export/exportUtil.vue';
import { message } from 'ant-design-vue';
const [registerDrawer, { openDrawer }] = useDrawer();
const [registerExport, { openDrawer: openExportDrawer }] = useDrawer();
function exportReport() {
const val = getForm().getFieldsValue();
listGroupUserExportApi(val);
}
function handleLookRecord() {
openExportDrawer(true, {});
}
const { hasParamsImportXls, handleExportXlsx } = useMethods();
const bigLoading = ref(false);
const slowLoading = ref(false);
function getTableAction(record: Recordable) {
return [
{
label: '编辑',
onclick: handleEdit.bind(null, record),
auth: 'archives:edit-button',
},
];
}
function handleEdit(record: Recordable) {
openDrawer(true, {
record,
});
}
const { tableContext } = useListPage({
tableProps: {
api: listApi,
columns,
canResize: false,
beforeFetch: (params) => {
if (params['orgCode2']) {
params['orgCode'] = params['orgCode2'];
} else {
params['orgCode'] = params['orgCode1'];
}
return params;
},
formConfig: {
schemas: searchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: false,
fieldMapToNumber: [],
},
showIndexColumn: true,
indexColumnProps: {
width: 80,
},
actionColumn: {
width: 80,
fixed: 'right',
},
},
});
const [registerTable, { reload, getForm }] = tableContext;
function handleSuccess() {
reload();
}
function onImportXls1(d) {
const size = d.file.size;
const m10 = 1024 * 1024 * 10;
if (size > m10) {
console.log('文件过大');
}
bigLoading.value = true;
console.log(d, 'dddddd');
hasParamsImportXls(d, Api.groupUserAImportExcel, { noMessage: true }, (res) => {
if (res?.code != 200) {
alert(
res?.result
? res?.result
.map((item: any) => {
return item.substring(0, item.length) + ';';
})
.join('\n')
: res?.message
);
}
reload();
}).finally(() => {
bigLoading.value = false;
});
}
function onImportXls2(d) {
const size = d.file.size;
const m10 = 1024 * 1024 * 10;
if (size > m10) {
console.log('文件过大');
}
slowLoading.value = true;
hasParamsImportXls(d, Api.groupUserBImportExcel, { noMessage: true }, (res) => {
alert(
res?.result
? res?.result
.map((item: any) => {
return item.substring(0, item.length) + ';';
})
.join('\n')
: res?.message
);
reload();
}).finally(() => {
slowLoading.value = false;
});
}
function onImportXls3(file) {
hasParamsImportXls(file, Api.groupImportExcel, {}, (res) => {
alert(
res?.result
? res?.result
.map((item: any) => {
return item.substring(0, item.length) + ';';
})
.join('\n')
: res?.message
);
reload();
}).finally(() => {
slowLoading.value = false;
});
}
function downloadTemplate1() {
// downloadExcel('/static/fiveClass/big.xlsx', '大病人员导入模板');
downLoadFile('1');
}
function downloadTemplate2() {
// downloadExcel('/static/fiveClass/slow.xlsx', '慢病人员导入模板');
downLoadFile('2');
}
function downloadTemplate3() {
downloadExcel('/static/fiveClass/large.xlsx', '批量修改导入模板');
}
async function downLoadFile(type) {
await handleExportXlsx(type === '1' ? '大病人员导入模板' : '慢病人员导入模板', excelImportTemplateUrl, { type: type });
// try {
// let res: any = await excelImportTemplateApi({ type: type });
// let blob = new Blob([res], { type: 'application/octet-stream' });
// let link = document.createElement('a');
// link.href = window.URL.createObjectURL(blob);
// link.download = (type === 1 ? '大病人员导入模板' : '慢病人员导入模板') + '.xlsx';
// link.click();
// } catch {}
}
function automatic1() {
autoAddCApi();
}
function automatic2() {
autoAddDApi();
}
</script>
<style scoped lang="less"></style>
@@ -1,41 +0,0 @@
// noinspection Eslint
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
const { createConfirm } = useMessage();
enum Api {
list = '/health-archives/housenew/healthHouseOrderReservationNew/list',
deleteBatch = '/health-archives/housenew/healthHouseOrderReservationNew/deleteBatch',
allHouseList = '/health-archives/housenew/healthHouseNew/allHouse',
}
/**
* 列表接口
* @param params
*/
export const list = (params) => defHttp.get({ url: Api.list, params });
/**
*健康室列表
*
*/
export const allHouseList = (params) => defHttp.get({ url: Api.allHouseList, params });
/**
* 批量删除
* @param params
*/
export const batchDelete = (params, handleSuccess) => {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
return defHttp.post({ url: Api.deleteBatch, data: params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
},
});
};
@@ -1,199 +0,0 @@
import { BasicColumn, FormSchema } from '/@/components/Table';
import { render } from '/@/utils/common/renderUtils';
import { allHouseList } from '/@/views/archive/healthCabin/bespeakManage/bespeakManage.api';
import { orgSearchInfo } from '/@/utils/orgSearchInfo';
export const columns: BasicColumn[] = [
{
title: '预约单号',
align: 'center',
dataIndex: 'reservationNo',
},
{
title: '用户姓名 ',
align: 'center',
dataIndex: 'realName',
},
{
title: '用户性别',
align: 'center',
dataIndex: 'sex_dictText',
},
{
title: '用户所属部门',
align: 'center',
dataIndex: 'thirdDepart',
},
{
title: '用户联系方式',
align: 'center',
dataIndex: 'mobile',
},
{
title: '预约状态',
align: 'center',
dataIndex: 'reservationStatus',
customRender: ({ text }) => {
return render.renderDict(text, 'health_reservation');
},
},
{
title: '预约健康室',
align: 'center',
dataIndex: 'houseName',
},
{
title: '设备名称',
align: 'center',
dataIndex: 'deviceName',
},
{
title: '预约日期',
align: 'center',
dataIndex: 'reservationDate',
},
{
title: '开始时间',
align: 'center',
dataIndex: 'startTime',
},
{
title: '完成时间',
align: 'center',
dataIndex: 'endTime',
},
{
title: '创建时间',
align: 'center',
dataIndex: 'createDate',
},
];
export const searchFormSchema: FormSchema[] = [
{
label: '用户姓名',
field: 'realName',
component: 'Input',
},
{
label: '预约状态',
field: 'status',
component: 'JDictSelectTag',
componentProps: {
// @ts-ignore//@ts-ignore
dictCode: 'health_reservation',
},
},
{
label: '预约健康室',
field: 'houseCode',
component: 'ApiSelect',
componentProps: {
api: allHouseList,
resultField: 'list',
labelField: 'houseName',
valueField: 'houseCode',
immediate: false,
placeholder: '请选择预约健康室',
},
},
{
label: '预约日期',
field: 'time',
component: 'DatePicker',
componentProps: () => ({ format: 'YYYY-MM-DD', valueFormat: 'YYYY-MM-DD', style: { width: '100%' } }),
},
...orgSearchInfo({ orgName: '二级部门', deptName: '三级部门' }),
{
label: '设备名称',
field: 'deviceName',
component: 'Input',
},
];
export const schemas: FormSchema[] = [
{
label: '预约单号',
field: 'reservationNo',
component: 'Input',
},
{
label: '用户姓名',
field: 'realName',
component: 'Input',
},
{
label: '预约健康室',
field: 'houseName',
component: 'Input',
},
{
label: '用户部门',
field: 'thirdDepart',
component: 'Input',
},
{
label: '设备名称',
field: 'deviceName',
component: 'Input',
},
{
label: '用户性别',
field: 'sex_dictText',
component: 'Input',
},
{
label: '设备编号',
field: 'deviceCode',
component: 'Input',
},
{
label: '用户联系方式',
field: 'mobile',
component: 'Input',
},
{
label: '创建时间',
field: 'createDate',
component: 'Input',
},
{
label: '预约时间',
field: 'reservationDate',
component: 'Input',
},
{
label: '取消时间',
field: 'cancelDate',
component: 'Input',
show: ({ values }) => {
return values.reservationStatus === '4' || values.reservationStatus === '5';
},
},
{
label: '使用时间',
field: 'useDate',
component: 'Input',
show: ({ values }) => {
return values.reservationStatus === '2';
},
},
{
label: '归还时间',
field: 'giveBackDate',
component: 'Input',
show: ({ values }) => {
return values.reservationStatus === '2';
},
},
{
label: '预约状态',
field: 'reservationStatus',
component: 'JDictSelectTag',
componentProps: {
// @ts-ignore//@ts-ignore
dictCode: 'health_reservation',
},
},
];
@@ -1,88 +0,0 @@
<template>
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<template #tableTitle>
<a-button type="primary" :icon="h(DeleteOutlined)" @click="deteleAll"> 批量删除 </a-button>
</template>
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
<add-modal @register="registerModal" />
</template>
<script lang="ts" setup>
import { h } from 'vue';
import { DeleteOutlined } from '@ant-design/icons-vue';
import BasicTable from '/@/components/Table/src/BasicTable.vue';
import { useListPage } from '/@/hooks/system/useListPage';
import { TableAction } from '/@/components/Table';
import { columns, searchFormSchema } from '/@/views/archive/healthCabin/bespeakManage/bespeakManage.data';
import { useModal } from '/@/components/Modal';
import AddModal from '/@/views/archive/healthCabin/bespeakManage/components/addDespeakManageModal.vue';
import { useMessage } from '/@/hooks/web/useMessage';
import { list, batchDelete } from '/@/views/archive/healthCabin/bespeakManage/bespeakManage.api';
const { createMessage } = useMessage();
const { tableContext } = useListPage({
tableProps: {
api: list,
// dataSource: list,
columns,
// canResize: false,
orderFlag: false,
showIndexColumn: true,
formConfig: {
schemas: searchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: false,
fieldMapToNumber: [],
fieldMapToTime: [],
},
beforeFetch: (params) => {
return params;
},
actionColumn: {
width: 100,
fixed: 'right',
},
},
});
const [registerTable, { reload, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
//注册弹窗
const [registerModal, { openModal }] = useModal();
function getTableAction(record: any) {
return [
{
label: '删除',
onClick: handleDelete.bind(null, record),
},
{
label: '详情',
onClick: onlyread.bind(null, record),
},
];
}
function onlyread(record) {
openModal(true, {
record,
isUpdate: false,
title: '查看',
onlyRead: true,
});
}
function deteleAll() {
if (!selectedRowKeys.value.length) {
createMessage.warning('请选择需要删除的数据');
} else {
batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
}
}
function handleSuccess() {
reload();
}
function handleDelete(record) {
batchDelete({ ids: record.id }, handleSuccess);
}
</script>
<style lang="less" scoped></style>
@@ -1,35 +0,0 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" width="40%" @ok="handleSubmit">
<BasicForm @register="registerForm" :disabled="onlyRead" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import BasicForm from '/@/components/Form/src/BasicForm.vue';
import { useForm } from '/@/components/Form';
import { schemas } from '/@/views/archive/healthCabin/bespeakManage/bespeakManage.data';
const title = ref('新增');
const isUpdate = ref();
const onlyRead = ref(true);
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
console.log(data);
await resetFields();
title.value = data.title;
isUpdate.value = data.isUpdate;
await setFieldsValue(data.record);
});
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
//labelWidth: 150,
schemas,
showActionButtonGroup: false,
baseColProps: { span: 12 },
});
function handleSubmit() {
closeModal();
}
</script>
<style lang="less" scoped></style>
@@ -1,67 +0,0 @@
// noinspection Eslint
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
const { createConfirm } = useMessage();
enum Api {
list = '/archives/medicalDataAnalysis/list',
save = '/archives/medicalDataAnalysis/add',
edit = '/archives/medicalDataAnalysis/edit',
deleteOne = '/archives/medicalDataAnalysis/delete',
deleteBatch = '/archives/medicalDataAnalysis/deleteBatch',
importExcel = '/archives/medicalDataAnalysis/importExcel',
exportXls = '/archives/medicalDataAnalysis/exportXls',
}
/**
* 导出api
* @param params
*/
export const getExportUrl = Api.exportXls;
/**
* 导入api
*/
export const getImportUrl = Api.importExcel;
/**
* 列表接口
* @param params
*/
export const list = (params) => defHttp.get({ url: Api.list, params });
/**
* 删除单个
*/
export const deleteOne = (params, handleSuccess) => {
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
};
/**
* 批量删除
* @param params
*/
export const batchDelete = (params, handleSuccess) => {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
return defHttp.delete({ url: Api.deleteBatch, data: params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
},
});
};
/**
* 保存或者更新
* @param params
* @param isUpdate
*/
export const saveOrUpdate = (params: any, isUpdate: boolean) => {
const url = isUpdate ? Api.edit : Api.save;
return defHttp.post({ url: url, params });
};
@@ -1,47 +0,0 @@
import { BasicColumn, FormSchema } from '/@/components/Table';
export const columns: BasicColumn[] = [
{
title: '今日就诊人数',
align: 'center',
dataIndex: 'todayCheck',
},
{
title: '总计就诊人数',
align: 'center',
dataIndex: 'totalCheck',
},
{
title: '今日救护车出动次数',
align: 'center',
dataIndex: 'todayAmbulance',
},
{
title: '总计救护车出动次数',
align: 'center',
dataIndex: 'totalAmbulance',
},
];
export const schemas: FormSchema[] = [
{
label: '今日就诊人数',
field: 'todayCheck',
component: 'InputNumber',
},
{
label: '总计就诊人数',
field: 'totalCheck',
component: 'InputNumber',
},
{
label: '今日救护车出动次数',
field: 'todayAmbulance',
component: 'InputNumber',
},
{
label: '总计救护车出动次数',
field: 'totalAmbulance',
component: 'InputNumber',
rules: [{ required: true, trigger: 'blur' }],
},
];
@@ -1,104 +0,0 @@
<template>
<BasicTable @register="registerTable" :rowSelection="rowSelection" style="margin: 10px 5px">
<template #tableTitle>
<a-button type="primary" :icon="h(PlusOutlined)" @click="handleAdd"> 录入 </a-button>
<a-button type="primary" :icon="h(EditOutlined)" @click="handleEdit"> 编辑 </a-button>
</template>
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
<add-modal @register="registerModal" @success="handleSuccess" />
</template>
<script lang="ts" setup>
import { h } from 'vue';
import { PlusOutlined, EditOutlined } from '@ant-design/icons-vue';
import BasicTable from '/@/components/Table/src/BasicTable.vue';
import { useListPage } from '/@/hooks/system/useListPage';
import { TableAction } from '/@/components/Table';
import { columns } from '/@/views/archive/healthCabin/bigDataShow/bigDataShow.data';
import { useModal } from '/@/components/Modal';
import AddModal from '/@/views/archive/healthCabin/bigDataShow/components/addDigDataShowModal.vue';
import { useMessage } from '/@/hooks/web/useMessage';
import { deleteOne } from '/@/views/archive/healthCabin/bigDataShow/bigDataShow.api';
const { createMessage } = useMessage();
import { usePermission } from '/@/hooks/web/usePermission';
const { hasPermission } = usePermission();
const list = [{}];
const { tableContext } = useListPage({
tableProps: {
// api: listApi,
dataSource: list,
columns,
canResize: false,
orderFlag: false,
showIndexColumn: true,
useSearchForm: false,
beforeFetch: (params) => {
return params;
},
actionColumn: {
width: 100,
fixed: 'right',
},
},
});
const [registerTable, { reload, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
//注册弹窗
const [registerModal, { openModal }] = useModal();
function getTableAction(record: any) {
return [
{
label: '删除',
onClick: handleDelete.bind(null, record),
ifShow: () => hasPermission('housenew:health_house_banner:delete'),
},
];
}
/**
* 新增事件
*/
function handleAdd() {
openModal(true, {
record: { sort: getDataSource().length + 1 },
isUpdate: false,
showFooter: true,
type: '新增',
});
}
/**
* 编辑事件
*/
function handleEdit() {
if (!selectedRowKeys.value.length || selectedRowKeys.value.length > 1) {
return createMessage.warning('请选择一条数据!');
}
let id = selectedRowKeys.value[0];
let dataSource = getDataSource();
let record = dataSource.filter((item) => item.id === id)[0];
openModal(true, {
record,
isUpdate: true,
showFooter: true,
title: '编辑',
});
}
/**
* 删除事件
*/
async function handleDelete(record) {
await deleteOne({ id: record.id }, handleSuccess);
}
/**
* 成功回调
*/
function handleSuccess() {
(selectedRowKeys.value = []) && reload();
}
</script>
<style lang="less" scoped></style>
@@ -1,57 +0,0 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" width="40%" @ok="handleSubmit">
<BasicForm @register="registerForm" :disabled="onlyRead" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import BasicForm from '/@/components/Form/src/BasicForm.vue';
import { useForm } from '/@/components/Form';
import { schemas } from '/@/views/archive/healthCabin/bigDataShow/bigDataShow.data';
import { saveOrUpdate } from '/@/views/archive/healthCabin/bigDataShow/bigDataShow.api';
// Emits声明
const emit = defineEmits(['register', 'success']);
const isUpdate = ref(true);
//设置标题
const title = ref(String);
const onlyRead = ref('false');
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
//重置表单
await resetFields();
setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
isUpdate.value = !!data?.isUpdate;
title.value = data.type;
//表单赋值
await setFieldsValue({
...data.record,
});
// 隐藏底部时禁用整个表单
setProps({ disabled: !data?.showFooter });
});
const [registerForm, { resetFields, setFieldsValue, validate, setProps }] = useForm({
labelWidth: 150,
schemas,
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
async function handleSubmit() {
try {
let values = await validate();
setModalProps({ confirmLoading: true });
//提交表单
await saveOrUpdate(values, isUpdate.value);
//关闭弹窗
closeModal();
//刷新列表
emit('success');
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
<style lang="less" scoped></style>
@@ -1,30 +0,0 @@
import { defHttp } from '/@/utils/http/axios';
enum Api {
list = '/health-archives/housenew/fakerData/getFakerData,' +
'/health-archives/housenew/fakerData/getFakerData,' +
'/health-archives/housenew/fakerData/getFakerData,' +
'/health-archives/housenew/fakerData/getFakerData,' +
'/health-archives/housenew/fakerData/getFakerData,' +
'/health-archives/housenew/fakerData/getFakerData,' +
'/health-archives/housenew/fakerData/getFakerData', // 查询: 1: 五类人群 2:医疗点 3:员工营养监控 4:总体健康水平 5: 干预效果 6: 手表
save = '/health-archives/housenew/fakerData/createGroupUserFakerData,' +
'/health-archives/housenew/fakerData/createMedicalCenterFakerData,' +
'/health-archives/housenew/fakerData/createNutritionFakerData,' +
'/health-archives/housenew/fakerData/createHealthLevelFakerData,' +
'/health-archives/housenew/fakerData/createInterveneFakerData,' +
'/health-archives/housenew/fakerData/createWatchFakerData,' +
'/health-archives/housenew/fakerData/createWatchStressFakerData', // 查询: 1: 五类人群 2:医疗点 3:员工营养监控 4:总体健康水平 5: 干预效果 6: 手表
status = '/health-archives/housenew/fakerData/getFakerDataEnable',
changeStatus = '/health-archives/housenew/fakerData/fakerDataEnable',
}
console.log(Api.list.split(','));
export const listApi = (params: any) =>
defHttp.post(
{ url: Api.list.split(',')[(params['module'] === 20 ? 5 : params['module'] === 21 ? 6 : params['module']) - 1], params },
{ joinParamsToUrl: true, isTransformResponse: false }
);
export const saveApi = (params: any) =>
defHttp.post({ url: Api.save.split(',')[(params['module'] === 20 ? 6 : params['module'] === 21 ? 7 : params['module']) - 1], params });
export const statusApi = (params: any) => defHttp.post({ url: Api.status, params });
export const changeStatusApi = (params: any) => defHttp.post({ url: Api.changeStatus, params });
@@ -1,447 +0,0 @@
import { BasicColumn } from '/@/components/Table';
const fiveColumns: BasicColumn[] = [
{
title: '总人数',
dataIndex: 'totalUser',
},
{
title: '大病',
dataIndex: 'illnessNum',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '慢病',
dataIndex: 'slowVirusNum',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '异常',
dataIndex: 'failNum',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '风险',
dataIndex: 'riskNum',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '健康',
dataIndex: 'healthNum',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '状态',
dataIndex: 'status',
},
];
const medicalColumns: BasicColumn[] = [
{
title: '近一周就诊人数',
dataIndex: 'weekNum',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '累计就诊人数',
dataIndex: 'totalNum',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '近一周救护车',
dataIndex: 'weekAmbulanceNum',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '累计救护车',
dataIndex: 'totalAmbulanceNum',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '状态',
dataIndex: 'status',
},
];
const nutritionColumns: BasicColumn[] = [
{
title: '早餐人数',
dataIndex: 'breakfastHeadCount',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '早餐超标人数',
dataIndex: 'breakfastOutOfLimits',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '午餐人数',
dataIndex: 'lunchHeadCount',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '午餐超标人数',
dataIndex: 'lunchOutOfLimits',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '晚餐人数',
dataIndex: 'dinnerHeadCount',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '晚餐超标人数',
dataIndex: 'dinnerOutOfLimits',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '状态',
dataIndex: 'status',
},
];
const healthColumns: BasicColumn[] = [
{
title: '健康值',
dataIndex: 'health',
},
{
title: '亚健康值',
dataIndex: 'sub',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '轻度心理问题',
dataIndex: 'mild',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '中度心理问题',
dataIndex: 'moderate',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '高度心理问题',
dataIndex: 'serious',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '状态',
dataIndex: 'status',
},
];
const interveneColumns: BasicColumn[] = [
{
title: '训练前睡眠质量',
dataIndex: 'sleepAgo',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '训练后睡眠质量',
dataIndex: 'sleepLater',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '训练前冥想情绪',
dataIndex: 'meditationAgo',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '训练后冥想情绪',
dataIndex: 'meditationLater',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '训练前骑行放松度',
dataIndex: 'cyclingAgo',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '训练后骑行放松度',
dataIndex: 'cyclingLater',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '总体改善度',
dataIndex: 'total',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '状态',
dataIndex: 'status',
},
];
const watchColumns: BasicColumn[] = [
{
title: '血氧监测-正常',
dataIndex: 'bloodOxygenNormal',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '血氧监测-警戒',
dataIndex: 'bloodOxygenWarn',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '血氧监测-危险',
dataIndex: 'bloodOxygenDanger',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '心率监测-正常',
dataIndex: 'heartRateNormal',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '心率监测-警戒',
dataIndex: 'heartRateWarn',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '心率监测--危险',
dataIndex: 'heartRateDanger',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '状态',
dataIndex: 'status',
},
];
const sportColumns: BasicColumn[] = [
{
title: '小于两公里1',
dataIndex: 'ltOne',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '小于两公里2',
dataIndex: 'ltTwo',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '小于两公里3',
dataIndex: 'ltThree',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '小于两公里4',
dataIndex: 'ltFour',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '3-5公里1',
dataIndex: 'middleOne',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '3-5公里2',
dataIndex: 'middleTwo',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '3-5公里3',
dataIndex: 'middleThree',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '3-5公里4',
dataIndex: 'middleFour',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '五公里以上1',
dataIndex: 'gtOne',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '五公里以上2',
dataIndex: 'gtTwo',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '五公里以上3',
dataIndex: 'gtThree',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '五公里以上4',
dataIndex: 'gtFour',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '压力-放松',
dataIndex: 'stressRelax',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '压力-正常',
dataIndex: 'stressNormal',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '压力-中等',
dataIndex: 'stressMedium',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '压力-偏高',
dataIndex: 'stressHigh',
rewriting: true,
rewroteCell: {
type: 'inputNumber',
},
},
{
title: '状态',
dataIndex: 'status',
},
];
export const columns: Array<BasicColumn[]> = [
fiveColumns,
medicalColumns,
nutritionColumns,
healthColumns,
interveneColumns,
watchColumns,
sportColumns,
];
@@ -1,171 +0,0 @@
<template>
<div style="padding: 10px">
<BasicTable @register="registerTable">
<template #tableTitle>
<div style="width: 100%">
<div>
<a-tabs v-model:activeKey="activeKey" @change="handleChange" style="padding-left: 5px">
<a-tab-pane v-for="item in tabList" :key="item.id" :tab="item.name" />
</a-tabs>
</div>
<div>
<a-button type="primary" @click="changeCalculateStatus" :loading="saveLoading">{{ isCalculate ? `保存` : `录入` }}</a-button>
<a-button style="margin-left: 5px" v-if="isCalculate" @click="changeCalculateStatusFalse">取消</a-button>
</div>
</div>
</template>
<template v-if="isCalculate" #bodyCell="{ column, record }">
<div v-if="column?.rewriting">
<a-input-number v-model:value="record[column.dataIndex]" />
</div>
<div v-if="column.dataIndex == 'status'">
<a-switch
v-model:checked="checked1"
checked-children=""
un-checked-children=""
@change="changeSwitch"
:loading="switchLoading"
/>
</div>
</template>
<template v-else #bodyCell="{ column, record }">
<div v-if="column.dataIndex == 'status'">
<a-switch
v-model:checked="checked1"
checked-children=""
un-checked-children=""
@change="changeSwitch"
:loading="switchLoading"
/>
</div>
</template>
</BasicTable>
</div>
</template>
<script setup lang="ts">
import BasicTable from '/@/components/Table/src/BasicTable.vue';
import { useListPage } from '/@/hooks/system/useListPage';
import { onMounted, ref } from 'vue';
import { listApi, saveApi, statusApi, changeStatusApi } from '/@/views/archive/healthCabin/bigScreen/currency.api';
import { columns } from '/@/views/archive/healthCabin/bigScreen/currency.data';
import { message } from 'ant-design-vue';
const activeKey = ref(1);
const checked1 = ref(false);
const isCalculate = ref(false);
const saveLoading = ref(false);
const switchLoading = ref(false);
const tabList = ref([
{
id: 1,
name: '五类人群',
},
{
id: 2,
name: '一线医疗点',
},
{
id: 3,
name: '员工营养监控',
},
{
id: 4,
name: '总体健康水平',
},
{
id: 5,
name: '干预效果',
},
{
id: 6,
name: '手表',
},
{
id: 7,
name: '运动压力',
},
]);
const { tableContext } = useListPage({
tableProps: {
api: listApi,
// columns: props.columns,
beforeFetch: (params) => {
const redisKey = ['house:fakerData:groupUser'];
params['module'] = activeKey.value === 6 ? 20 : activeKey.value === 7 ? 21 : activeKey.value;
params['redisKey'] = redisKey[activeKey.value - 1];
return params;
},
afterFetch: async () => {
let { code, result, message: msg } = getRawDataSource();
const res = await statusApi({});
checked1.value = res[activeKey.value] ? res[activeKey.value] : false;
if (code == 200) {
return [result];
} else {
message.warn(msg);
}
},
showTableSetting: false,
tableSetting: {
setting: false,
},
pagination: false,
canResize: false,
immediate: false,
useSearchForm: false,
showActionColumn: false,
},
});
async function changeCalculateStatus() {
if (!isCalculate.value) return (isCalculate.value = true);
try {
saveLoading.value = true;
switchLoading.value = false;
await saveApi({ ...getDataSource()[0], module: activeKey.value });
saveLoading.value = false;
await reload();
} catch (e) {
saveLoading.value = false;
switchLoading.value = false;
}
}
function changeCalculateStatusFalse() {
isCalculate.value = false;
saveLoading.value = false;
switchLoading.value = false;
reload();
}
async function changeSwitch() {
try {
switchLoading.value = true;
checked1.value = !checked1.value;
await changeStatusApi({ module: activeKey.value === 6 ? 20 : activeKey.value === 7 ? 21 : activeKey.value, enable: !checked1.value });
checked1.value = !checked1.value;
switchLoading.value = false;
} catch (e) {
switchLoading.value = false;
}
}
function handleChange() {
saveLoading.value = false;
switchLoading.value = false;
isCalculate.value = false;
setProps({
columns: columns[activeKey.value - 1],
});
reload();
}
onMounted(() => {
setProps({
columns: columns[activeKey.value - 1],
});
reload();
});
const [registerTable, { reload, setProps, getRawDataSource, getDataSource }, {}] = tableContext;
</script>
<style scoped lang="less"></style>
@@ -1,47 +0,0 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" width="50%" @ok="handleSubmit">
<BasicForm @register="registerForm" :disabled="onlyRead" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import BasicForm from '/@/components/Form/src/BasicForm.vue';
import { useForm } from '/@/components/Form';
import { schemas } from '/@/views/archive/healthCabin/healthEquipment/healthEquipment.data';
const title = ref('新增');
const isUpdate = ref();
const onlyRead = ref('false');
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
console.log(data);
await resetFields();
title.value = data.title;
isUpdate.value = data.isUpdate;
onlyRead.value = data.onlyRead;
});
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
labelWidth: 120,
schemas,
showActionButtonGroup: false,
baseColProps: { span: 12 },
});
async function handleSubmit() {
if (onlyRead.value) {
closeModal();
return;
}
try {
let values = await validate();
setModalProps({ confirmLoading: true });
console.log(values, 1233333);
closeModal();
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
<style lang="less" scoped></style>
@@ -1,67 +0,0 @@
// noinspection Eslint
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
const { createConfirm } = useMessage();
enum Api {
list = '/health-archives/health-house/device/list',
save = '/archives/medicalDataAnalysis/add',
edit = '/archives/medicalDataAnalysis/edit',
deleteOne = '/archives/medicalDataAnalysis/delete',
deleteBatch = '/archives/medicalDataAnalysis/deleteBatch',
importExcel = '/archives/medicalDataAnalysis/importExcel',
exportXls = '/archives/medicalDataAnalysis/exportXls',
}
/**
* 导出api
* @param params
*/
export const getExportUrl = Api.exportXls;
/**
* 导入api
*/
export const getImportUrl = Api.importExcel;
/**
* 列表接口
* @param params
*/
export const list = (params) => defHttp.get({ url: Api.list, params });
/**
* 删除单个
*/
export const deleteOne = (params, handleSuccess) => {
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
};
/**
* 批量删除
* @param params
*/
export const batchDelete = (params, handleSuccess) => {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
return defHttp.delete({ url: Api.deleteBatch, data: params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
},
});
};
/**
* 保存或者更新
* @param params
* @param isUpdate
*/
export const saveOrUpdate = (params: any, isUpdate: boolean) => {
const url = isUpdate ? Api.edit : Api.save;
return defHttp.post({ url: url, params });
};
@@ -1,124 +0,0 @@
import { BasicColumn, FormSchema } from '/@/components/Table';
export const columns: BasicColumn[] = [
{
title: '设备编号',
align: 'center',
dataIndex: 'pic',
},
{
title: '设备名称',
align: 'center',
dataIndex: 'qq',
},
{
title: '设备状态',
align: 'center',
dataIndex: 'name',
},
{
title: '所属健康室',
align: 'center',
dataIndex: 'pic',
},
{
title: '设备图片',
align: 'center',
dataIndex: 'pic',
},
{
title: '设备类型',
align: 'center',
dataIndex: 'pic',
},
{
title: '单位预约时间(/分钟)',
align: 'center',
dataIndex: 'pic',
},
{
title: '可预约人数(/人)',
align: 'center',
dataIndex: 'pic',
},
];
export const searchFormSchema: FormSchema[] = [
{
label: '所属健康室',
field: 'name1',
component: 'Select',
},
{
label: '设备类型',
field: 'name',
component: 'Select',
},
];
export const schemas: FormSchema[] = [
{
label: '设备编号',
field: 'name',
component: 'Input',
rules: [{ required: true }],
},
{
label: '设备名称',
field: 'name',
component: 'Input',
rules: [{ required: true }],
},
{
label: '设备状态',
field: 'name',
component: 'Select',
rules: [{ required: true }],
},
{
label: '设备类型',
field: 'name',
component: 'Select',
rules: [{ required: true }],
},
{
label: '所属健康室',
field: 'name',
component: 'Input',
rules: [{ required: true }],
},
{
label: '添加图片',
field: 'uploadImage',
component: 'JImageUpload',
componentProps: {
//按钮显示文字
text: '图片上传',
//支持两种基本样式picture和picture-card
listType: 'picture-card',
//用于控制文件上传的业务路径,默认temp
bizPath: 'temp',
//是否禁用
disabled: false,
//最大上传数量
fileMax: 1,
},
},
{
label: '设备介绍',
field: 'editor',
component: 'JEditor',
// componentProps: {
//是否禁用
// disabled: false
// },
},
{
label: '预约须知',
field: 'editor',
component: 'JEditor',
// componentProps: {
//是否禁用
// disabled: false
// },
},
];
@@ -1,106 +0,0 @@
<template>
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<template #tableTitle>
<a-button type="primary" :icon="h(PlusOutlined)" @click="add"> 添加设备 </a-button>
<a-button type="primary" :icon="h(EditOutlined)" @click="edit"> 修改设备信息 </a-button>
</template>
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
<add-modal @register="registerModal" />
</template>
<script lang="ts" setup>
import { h } from 'vue';
import { PlusOutlined, EditOutlined } from '@ant-design/icons-vue';
import BasicTable from '/@/components/Table/src/BasicTable.vue';
import { useListPage } from '/@/hooks/system/useListPage';
import { TableAction } from '/@/components/Table';
import { list } from '/@/views/archive/healthCabin/healthEquipment/healthEquipment.api';
import { columns, searchFormSchema } from '/@/views/archive/healthCabin/healthEquipment/healthEquipment.data';
import { useModal } from '/@/components/Modal';
import AddModal from '/@/views/archive/healthCabin/healthEquipment/components/addHealthEquipmentModal.vue';
import { useMessage } from '/@/hooks/web/useMessage';
const { createMessage } = useMessage();
const { tableContext } = useListPage({
tableProps: {
api: list,
columns,
canResize: false,
orderFlag: false,
showIndexColumn: true,
formConfig: {
schemas: searchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: false,
fieldMapToNumber: [],
fieldMapToTime: [],
},
// beforeFetch: (params) => {
// return params;
// },
actionColumn: {
width: 100,
fixed: 'right',
},
},
});
const [registerTable, { reload, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
//注册弹窗
const [registerModal, { openModal }] = useModal();
function getTableAction(record: any) {
return [
{
label: '删除',
onClick: handleDelete.bind(null, record),
},
];
}
function edit() {
if (!selectedRowKeys.value.length || selectedRowKeys.value.length > 1) {
return createMessage.warning('请选择一条数据!');
}
let id = selectedRowKeys.value[0];
let dataSource = getDataSource();
let record = dataSource.filter((item) => item.id === id)[0];
openModal(true, {
record,
isUpdate: true,
title: '编辑',
});
}
function add() {
openModal(true, {
isUpdate: false,
title: '新增',
onlyRead: false,
});
}
function onlyread() {
if (!selectedRowKeys.value.length || selectedRowKeys.value.length > 1) {
return createMessage.warning('请选择一条数据!');
}
let id = selectedRowKeys.value[0];
let dataSource = getDataSource();
let record = dataSource.filter((item) => item.id === id)[0];
openModal(true, {
record,
isUpdate: false,
title: '查看',
onlyRead: true,
});
}
function deteleAll() {
if (!selectedRowKeys.value.length) {
createMessage.warning('请选择需要删除的格言');
}
}
function handleDelete(e) {
console.log(e);
}
</script>
<style lang="less" scoped></style>
@@ -1,71 +0,0 @@
<template>
<BasicModal v-bind="$attrs" @register="registerAdministratorModal" :title="title" :width="800" @ok="handleSubmit">
<BasicForm @register="registerAdministratorForm" />
</BasicModal>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form';
import { administratorFormSchema } from '/@/views/archive/healthCabin/healthRoom/index.data';
import { addAdmin } from '/@/views/archive/healthCabin/healthRoom/index.api';
import { encipher } from '/@/utils/jsencrypt';
const emit = defineEmits(['register', 'success']);
const isUpdate = ref(true);
const title = ref('医院管理员');
const record = ref();
//表单配置
const [registerAdministratorForm, { setProps, resetFields, setFieldsValue, validate, clearValidate }] = useForm({
schemas: administratorFormSchema,
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
//表单赋值
const [registerAdministratorModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
//重置表单
await resetFields();
setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
isUpdate.value = !!data?.isUpdate;
title.value = data.title;
record.value = data.record;
if (isUpdate.value) {
await setFieldsValue(data.record);
}
await clearValidate();
// 隐藏底部时禁用整个表单
await setProps({ disabled: !data?.showFooter });
});
async function handleSubmit() {
try {
setModalProps({ confirmLoading: true });
const values = await validate();
const params = {
...values,
pwd: encipher(values.password),
confirmPwd: encipher(values.confirmPassword),
// pwd: values.password,
// confirmPwd: values.confirmPassword,
houseCode: record.value.houseCode,
};
delete params.confirmPassword;
delete params.password;
await addAdmin(params);
setModalProps({ confirmLoading: false });
// 关闭弹窗
closeModal();
//刷新列表
emit('success');
} catch {
setModalProps({ confirmLoading: false });
}
}
</script>
<style scoped lang="less">
.title-info {
margin-left: 16px;
font-weight: bold;
}
</style>
@@ -1,125 +0,0 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" width="40%" @ok="handleSubmit">
<BasicForm @register="registerForm" :disabled="onlyRead">
<template #address="{ model }">
<a-input style="width: calc(100% - 100px)" v-model:value="model['housePlace']" :disabled="true" />
<a-button style="margin-left: 10px; width: 80px" @click="viewMap" :disabled="onlyRead">查看地图</a-button>
</template>
<template #defaultHouseNumber="{ model }" v-if="!isUpdate">
<a-checkbox-group v-model:value="model['defaultHouseNumber']" :options="plainOptions" />
</template>
</BasicForm>
<Map @register="registerMap" :state="state" ref="map" @get-position="getPosition" />
</BasicModal>
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import { BasicModal, useModal, useModalInner } from '/@/components/Modal';
import BasicForm from '/@/components/Form/src/BasicForm.vue';
import { useForm } from '/@/components/Form';
import { schemas } from '/@/views/archive/healthCabin/healthRoom/index.data';
import Map from '/@/views/consult/resource/components/Map.vue';
import { addRoom, editRoom } from '/@/views/archive/healthCabin/healthRoom/index.api';
import { getDictCache } from '/@/utils/dict';
const emit = defineEmits(['register', 'success']);
const title = ref('新增');
const isUpdate = ref();
const state = ref();
const roomId = ref();
const onlyRead = ref('false');
let plainOptions = ref();
// console.log(plainOptions)
onMounted(async () => {
plainOptions.value = getDictCache('week');
console.log(plainOptions.value);
});
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
console.log(data.record);
setModalProps({ confirmLoading: false });
await resetFields();
await updateSchema([
{
field: 'defaultHouseNumber',
show: true,
},
]);
if (data.isUpdate) {
await setFieldsValue({ ...data.record });
await setFieldsValue({ useDeparts: data.record.useDeparts.split(',') });
roomId.value = data.record.id;
await updateSchema([
{
field: 'defaultHouseNumber',
show: false,
},
]);
}
title.value = data.title;
isUpdate.value = data.isUpdate;
onlyRead.value = data.onlyRead;
});
const [registerMap, { openModal: openMapModal }] = useModal();
const [registerForm, { updateSchema, resetFields, setFieldsValue, validate, getFieldsValue }] = useForm({
//labelWidth: 150,
schemas,
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
async function handleSubmit() {
if (onlyRead.value) {
closeModal();
return;
}
try {
let values = await validate();
setModalProps({ confirmLoading: true });
values = {
...values,
...state.value,
};
if (isUpdate.value) {
values.id = roomId.value;
await editRoom(values);
} else {
await addRoom(values);
}
closeModal();
//刷新列表
emit('success');
} catch (e) {
setModalProps({ confirmLoading: false });
}
}
function viewMap() {
openMapModal(true, {
record: { ...getFieldsValue() },
});
}
async function getPosition(val) {
let { pname, cityname, adname, address, name } = val.handleItem || '';
let nameList = [pname, cityname, adname, address, name];
let str = '';
nameList.map((item) => {
if (item !== undefined) {
str += item;
}
});
await setFieldsValue({
latitude: val.lat,
longitude: val.lng,
customAddress: `${val.lng}${val.lat}`,
housePlace: str,
});
state.value = {
...state.value,
latitude: val.lat,
longitude: val.lng,
};
}
</script>
<style lang="less" scoped></style>
@@ -1,60 +0,0 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" width="40%" @ok="handleSubmit">
<BasicTable @register="TerEquiTable" :rowSelection="rowSelection" class="device-table"></BasicTable>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import BasicTable from '/@/components/Table/src/BasicTable.vue';
import { useListPage } from '/@/hooks/system/useListPage';
import { deviceList, bindDevices } from '/@/views/archive/healthCabin/healthRoom/index.api';
import { terEquiChangeColums } from '/@/views/archive/healthCabin/healthRoom/index.data';
const title = ref('选择');
const emit = defineEmits(['register', 'success']);
const isUpdate = ref(false);
const terminalCode = ref();
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
console.log(data.record);
setModalProps({ confirmLoading: false });
terminalCode.value = data.terminalCode;
});
const { tableContext } = useListPage({
tableProps: {
title: '终端设备表',
api: deviceList,
columns: terEquiChangeColums,
canResize: false,
orderFlag: false,
showIndexColumn: false,
useSearchForm: false,
actionColumn: {
width: 100,
fixed: 'right',
},
},
});
const [TerEquiTable, { reload, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
async function handleSubmit() {
try {
const allData = getDataSource();
const filteredData = allData.filter((item) => selectedRowKeys.value.includes(item.id));
const deviceCodes = filteredData.map((item) => {
return item.deviceCode;
});
const params = {
deviceCodes,
terminalCode: terminalCode.value,
};
// closeModal();
await bindDevices(params);
closeModal();
emit('success');
} catch (e) {
setModalProps({ confirmLoading: false });
}
}
</script>
<style lang="less" scoped></style>
@@ -1,59 +0,0 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" width="40%" @ok="handleSubmit">
<BasicForm @register="registerForm"></BasicForm>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { useForm } from '/@/components/Form';
import BasicForm from '/@/components/Form/src/BasicForm.vue';
import { terminalFormSchema } from '/@/views/archive/healthCabin/healthRoom/index.data';
import { terminalAdd, terminalEdit } from '/@/views/archive/healthCabin/healthRoom/index.api';
const emit = defineEmits(['register', 'success']);
let title = ref('新增设备');
let isUpdate = ref(false);
const onlyRead = ref('false');
const houseCode = ref();
const terminalId = ref();
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
console.log(data);
setModalProps({ confirmLoading: false });
await resetFields();
title.value = data.title + 1;
houseCode.value = data.houseCode;
isUpdate.value = data.isUpdate;
if (data.isUpdate) {
terminalId.value = data.record.id;
data.record.terminalStatus = data.record.terminalStatus.toString();
await setFieldsValue({ ...data.record });
}
});
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
//labelWidth: 150,
schemas: terminalFormSchema,
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
async function handleSubmit() {
console.log(123);
try {
let values = await validate();
setModalProps({ confirmLoading: true });
closeModal();
values.houseCode = houseCode.value;
if (isUpdate.value) {
values.id = terminalId.value;
await terminalEdit(values);
} else {
await terminalAdd(values);
}
emit('success');
} catch (e) {
setModalProps({ confirmLoading: false });
}
}
</script>
<style lang="less" scoped></style>
@@ -1,186 +0,0 @@
<template>
<BasicDrawer v-bind="$attrs" @register="registerModal" title="医院管理员" :width="1000">
<div class="administrator-container">
<!-- <div class="title-info">-->
<!-- <div>医院名称{{ record?.resourceName }}</div>-->
<!-- <div class="level">医院等级{{ record?.resourceLevel_dictText }}</div>-->
<!-- </div>-->
<div>
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--插槽:table标题-->
<template #tableTitle>
<a-button
type="primary"
@click="handleAdd"
preIcon="ant-design:plus-outlined"
v-auth="'medicalCenter:medical_hospital_manager:add'"
>
新增管理员
</a-button>
<!-- <a-button-->
<!-- type="primary"-->
<!-- @click="batchHandleDelete"-->
<!-- preIcon="ant-design:delete-outlined"-->
<!-- v-auth="'medicalCenter:medical_hospital_manager:deleteBatch'"-->
<!-- >-->
<!-- 批量删除-->
<!-- </a-button>-->
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
</div>
</div>
<!--新增管理员-->
<AddAdminModal @register="registerAdminModal" @success="handleSuccess" />
<!--重置密码-->
<RestPass @register="resetPassModal" />
</BasicDrawer>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { BasicModal, useModal, useModalInner } from '/@/components/Modal';
import { BasicTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
// import { administratorDeleteBatch, administratorDeleteOne, administratorList } from '/@/views/medicalCenter/partnerHospital/partnerHospital.api';
import { adminList } from '/@/views/archive/healthCabin/healthRoom/index.api';
import AddAdminModal from '/@/views/archive/healthCabin/healthRoom/components/addAdminModal.vue';
import { administratorColumns, administratorSearchForm } from '/@/views/archive/healthCabin/healthRoom/index.data';
import RestPass from '/@/views/system/user/restPass/RestPass.vue';
import { message } from 'ant-design-vue';
import BasicDrawer from '/@/components/Drawer/src/BasicDrawer.vue';
import { useDrawerInner } from '/@/components/Drawer';
const record = ref();
//表单赋值
const [registerModal, { setDrawerProps }] = useDrawerInner(async (data) => {
record.value = data.record;
await reload();
});
//注册Modal
const [registerAdminModal, { openModal }] = useModal();
const [resetPassModal, { openModal: openResetModal }] = useModal();
//注册table数据
const { tableContext } = useListPage({
tableProps: {
title: '健康室管理员',
api: adminList,
columns: administratorColumns,
canResize: false,
showIndexColumn: false,
formConfig: {
labelWidth: 40,
// schemas: administratorSearchForm,
showActionButtonGroup: false,
showAdvancedButton: false,
showSubmitButton: false,
showResetButton: false,
fieldMapToNumber: [],
fieldMapToTime: [],
// baseColProps: {
// offset: 0,
// xs: 12,
// sm: 12,
// md: 8,
// lg: 8,
// xl: 8,
// xxl: 8,
// },
// actionColOptions: {
// span: 8,
// offset: 0,
// xs: 12,
// sm: 12,
// md: 8,
// lg: 8,
// xl: 8,
// xxl: 8,
// },
},
beforeFetch: (params) => {
params['houseCode'] = record.value?.houseCode;
return params;
},
actionColumn: {
width: 100,
fixed: 'right',
},
},
});
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
function resetPassword(record: Recordable) {
openResetModal(true, {
record: record.userId,
isUpdate: true,
showFooter: false,
});
}
function handleAdd() {
openModal(true, {
record: { ...record.value, hospitalId: record.value.id },
isUpdate: false,
title: '新增管理员',
showFooter: true,
});
}
function handleEdit(row: Recordable) {
openModal(true, {
record: { ...row, hospitalId: record.value.id },
isUpdate: true,
title: '编辑医院管理员',
showFooter: true,
});
}
// function handleDelete(record: Recordable) {
// administratorDeleteOne({ id: record.id }, handleSuccess);
// }
// function batchHandleDelete() {
// if (selectedRowKeys.value.length === 0) {
// message.warning('未选中任何数据');
// return;
// }
// administratorDeleteBatch({ ids: selectedRowKeys.value }, handleSuccess);
// }
function handleSuccess() {
(selectedRowKeys.value = []) && reload();
}
function getTableAction(record: Recordable) {
return [
{
label: '重置密码',
onClick: resetPassword.bind(null, record),
auth: 'system:reset:password',
},
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'medicalCenter:medical_hospital_manager:edit',
ifShow: false,
},
// {
// label: '删除',
// onClick: handleDelete.bind(null, record),
// auth: 'medicalCenter:medical_hospital_manager:delete',
// ifShow: false,
// },
];
}
</script>
<style scoped lang="less">
.administrator-container {
height: 65vh;
overflow: auto;
}
.title-info {
margin-left: 20px;
font-weight: bold;
display: flex;
gap: 20px;
}
</style>
@@ -1,196 +0,0 @@
<template>
<BasicDrawer @register="registerDrawer" title="设备管理" :width="drawerWidth" :maskClosable="false" :show-footer="false">
<BasicTable @register="deviceTable" :rowSelection="rowSelection" class="device-table">
<template #tableTitle>
<a-button type="primary" :icon="h(PlusOutlined)" @click="addDevice"> 新增 </a-button>
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
</template>
</BasicTable>
<DeviceModal @register="deviceModal" @success="deviceSuccess"></DeviceModal>
<ProjectDrawer @register="projectDrawer"></ProjectDrawer>
</BasicDrawer>
</template>
<script lang="ts" setup>
import BasicDrawer from '/@/components/Drawer/src/BasicDrawer.vue';
import { ref, unref, h } from 'vue';
import { PlusOutlined, EditOutlined, SearchOutlined } from '@ant-design/icons-vue';
import { useDrawer, useDrawerInner } from '/@/components/Drawer';
import BasicTable from '/@/components/Table/src/BasicTable.vue';
import { useListPage } from '/@/hooks/system/useListPage';
import { TableAction } from '/@/components/Table';
import { deviceColumns, deviceSearchFormSchema } from '/@/views/archive/healthCabin/healthRoom/index.data';
import DeviceModal from '/@/views/archive/healthCabin/healthRoom/components/deviceModal.vue';
import ProjectDrawer from '/@/views/archive/healthCabin/healthRoom/components/projectDrawer.vue';
import { useMessage } from '/@/hooks/web/useMessage';
import { deviceList, deviceDelete, deviceChangeStatus } from '/@/views/archive/healthCabin/healthRoom/index.api';
import { useModal } from '/@/components/Modal';
const { createMessage } = useMessage();
let records = ref();
const [registerDrawer, { setDrawerProps }] = useDrawerInner(async (data) => {
console.log(data);
records.value = data.record;
});
const [projectDrawer, { openDrawer: openProjectDrawer }] = useDrawer();
const drawerWidth = '80%';
const list = [{}];
const { tableContext } = useListPage({
tableProps: {
title: '设备管理表',
api: deviceList,
// dataSource: list,
columns: deviceColumns,
canResize: false,
orderFlag: false,
showIndexColumn: false,
formConfig: {
// layout: 'inline',
schemas: deviceSearchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: false,
fieldMapToNumber: [],
fieldMapToTime: [],
baseColProps: {
offset: 0,
xs: 8,
sm: 8,
md: 8,
lg: 8,
xl: 8,
xxl: 5,
},
},
// beforeFetch: (params) => {
// params['id'] = record.value.houseCode;
// return params;
// },
actionColumn: {
width: 200,
fixed: 'right',
},
},
});
const [deviceTable, { reload, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
const [deviceModal, { openModal }] = useModal();
function getTableAction(record: any) {
return [
{
label: '启用',
onClick: handleEnable.bind(null, record),
ifShow: record.deviceStatus == 0,
},
{
label: '禁用',
// label: '删除',
popConfirm: {
title: '请确认禁用类型',
okText: '禁用并取消',
cancelText: '禁用',
confirm: handleDisabled.bind(null, record),
cancel: handleOlnyDisabled.bind(null, record),
},
// onClick: handleDisabled.bind(null, record),
// confirm: {
// ok: 'qqq',
// },
ifShow: record.deviceStatus != 0,
},
{
label: '设备项目',
onClick: projectBtn.bind(null, record),
ifShow: record.childStatus == 1,
},
];
}
function projectBtn(record) {
openProjectDrawer(true, {
record,
});
}
function deviceSuccess() {
reload();
}
function getDropDownAction(record: any) {
return [
{
label: '编辑',
onClick: edit.bind(null, record),
},
{
label: '详情',
onClick: onlyread.bind(null, record),
},
{
label: '删除',
onClick: deviceDeleteBtn.bind(null, record),
},
];
}
async function handleEnable(record) {
console.log(record);
const params = {
deviceId: record.id,
status: 1,
};
await deviceChangeStatus(params);
reload();
}
async function handleDisabled(record) {
console.log(record);
const params = {
deviceId: record.id,
status: 0,
force: true,
};
await deviceChangeStatus(params);
reload();
}
async function handleOlnyDisabled(record) {
const params = {
deviceId: record.id,
status: 4,
force: false,
};
await deviceChangeStatus(params);
reload();
}
function addDevice() {
openModal(true, {
title: '新增设备',
isUpdate: false,
houseCode: records.value.houseCode,
});
}
function edit(record) {
openModal(true, {
record,
isUpdate: true,
houseCode: records.value.houseCode,
title: '编辑',
});
}
function onlyread(record) {
openModal(true, {
record,
isUpdate: true,
onlyRead: true,
title: '详情',
});
}
function deviceDeleteBtn(record) {
deviceDelete({ id: record.id }, reload);
}
</script>
<style lang="less" scoped>
.device-table {
/deep/ .ant-form-item-control-input-content {
display: flex;
}
}
</style>
@@ -1,67 +0,0 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" width="40%" @ok="handleSubmit">
<BasicForm @register="registerForm" :disabled="onlyRead">
<template #startTime="{ model }">
<a-time-picker v-model:value="model['startTime']" format="HH:mm" value-format="HH:mm" />
</template>
<template #endTime="{ model }">
<a-time-picker v-model:value="model['endTime']" format="HH:mm" value-format="HH:mm" />
</template>
</BasicForm>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { useForm } from '/@/components/Form';
import BasicForm from '/@/components/Form/src/BasicForm.vue';
import { deviceSchemas } from '/@/views/archive/healthCabin/healthRoom/index.data';
import { deviceAdd, deviceEdit } from '/@/views/archive/healthCabin/healthRoom/index.api';
const emit = defineEmits(['register', 'success']);
let title = ref('新增设备');
let houseCode = ref();
let deviceId = ref();
let isUpdate = ref(false);
const onlyRead = ref('false');
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
console.log(data);
setModalProps({ confirmLoading: false });
await resetFields();
title.value = data.title;
houseCode.value = data.houseCode;
isUpdate.value = data.isUpdate;
onlyRead.value = data.onlyRead;
if (data.isUpdate) {
setFieldsValue({ ...data.record });
deviceId.value = data.record.id;
}
});
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
//labelWidth: 150,
schemas: deviceSchemas,
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
async function handleSubmit() {
console.log(123);
try {
let values = await validate();
setModalProps({ confirmLoading: true });
values.houseCode = houseCode.value;
if (isUpdate.value) {
values.id = deviceId.value;
await deviceEdit(values);
} else {
console.log(values);
await deviceAdd(values);
}
closeModal();
emit('success');
} catch (e) {
setModalProps({ confirmLoading: false });
}
}
</script>
<style lang="less" scoped></style>
@@ -1,49 +0,0 @@
<template>
<template>
<BasicModal :title="title" v-bind="$attrs" width="40%" @ok="handleSubmit" @register="registerModal">
<BasicForm @register="registerForm">
<template #defaultLayout="{ model }">
<a-checkbox-group v-model:value="model['defaultLayout']" :options="plainOptions" />
</template>
</BasicForm>
</BasicModal>
</template>
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { useForm } from '/@/components/Form';
import BasicForm from '/@/components/Form/src/BasicForm.vue';
import { defaultLayoutSchemas } from '/@/views/archive/healthCabin/healthRoom/index.data';
import { getDictCache } from '/@/utils/dict';
const title = ref('新增');
const isUpdate = ref();
const state = ref();
let plainOptions = ref();
// console.log(plainOptions)
onMounted(async () => {
plainOptions.value = getDictCache('week');
});
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
console.log(data);
// await resetFields();
title.value = data.title;
isUpdate.value = data.isUpdate;
});
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
//labelWidth: 150,
schemas: defaultLayoutSchemas,
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
async function handleSubmit() {
let values = await validate();
console.log(values);
}
</script>
<style lang="less" scoped></style>
@@ -1,58 +0,0 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" width="40%" @ok="handleSubmit">
<BasicForm @register="registerForm">
<template #openTime="{ model }">
<a-time-picker v-model:value="model['openTime']" format="HH:mm" value-format="HH:mm" />
</template>
<template #closeTime="{ model }">
<a-time-picker v-model:value="model['closeTime']" format="HH:mm" value-format="HH:mm" />
</template>
</BasicForm>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { useForm } from '/@/components/Form';
import BasicForm from '/@/components/Form/src/BasicForm.vue';
import { layoutSchemas } from '/@/views/archive/healthCabin/healthRoom/index.data';
import { defaultEdit } from '/@/views/archive/healthCabin/healthRoom/index.api';
const title = ref('新增');
const emit = defineEmits(['register', 'success']);
const isUpdate = ref();
const state = ref();
const houseCode = ref();
const layoutId = ref();
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
await resetFields();
setModalProps({ confirmLoading: false });
console.log(data);
data.record.wokrStatus = data.record.wokrStatus.toString();
await setFieldsValue({ ...data.record });
title.value = data.title;
isUpdate.value = data.isUpdate;
houseCode.value = data.record.houseCode;
layoutId.value = data.record.id;
});
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
//labelWidth: 150,
schemas: layoutSchemas,
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
async function handleSubmit() {
setModalProps({ confirmLoading: true });
let values = await validate();
values.id = layoutId.value;
values.houseCode = houseCode.value;
console.log(values);
// defaultEdit
await defaultEdit(values);
closeModal();
emit('success');
setModalProps({ confirmLoading: false });
}
</script>
<style lang="less" scoped></style>
@@ -1,102 +0,0 @@
<template>
<BasicDrawer @register="registerDrawer" title="默认模板" :width="900" :show-footer="false">
<BasicTable @register="deviceTable" :pagination="false" size="small" :rowSelection="rowSelection" class="layout-table">
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'openTime'">
<div>{{ record.openTime }}--{{ record.closeTime }}</div>
</template>
</template>
<template #tableTitle>
<a-button type="primary" :icon="h(EditOutlined)" @click="edit"> 编辑 </a-button>
<!-- <a-button type="primary" :icon="h(PlusOutlined)" @click="editLayout"> 修改默认模板 </a-button>-->
</template>
</BasicTable>
<EditLayoutModal @register="layoutModal" @success="layoutSuccess"></EditLayoutModal>
<EditDefaultLayoutModal @register="defaultLayoutModal"></EditDefaultLayoutModal>
</BasicDrawer>
</template>
<script lang="ts" setup>
import { ref, unref, h } from 'vue';
import { PlusOutlined, EditOutlined } from '@ant-design/icons-vue';
import BasicDrawer from '/@/components/Drawer/src/BasicDrawer.vue';
import { useDrawer, useDrawerInner } from '/@/components/Drawer';
import BasicTable from '/@/components/Table/src/BasicTable.vue';
import { layoutColumns } from '/@/views/archive/healthCabin/healthRoom/index.data';
import { useListPage } from '/@/hooks/system/useListPage';
import { useMessage } from '/@/hooks/web/useMessage';
import EditLayoutModal from '/@/views/archive/healthCabin/healthRoom/components/editLayoutModal.vue';
import EditDefaultLayoutModal from '/@/views/archive/healthCabin/healthRoom/components/editDefaultLayoutModal.vue';
import { useModal } from '/@/components/Modal';
import { defaultList } from '/@/views/archive/healthCabin/healthRoom/index.api';
const { createMessage } = useMessage();
const houseCode = ref();
const [registerDrawer, { setDrawerProps }] = useDrawerInner(async (data) => {
houseCode.value = data.record.houseCode;
});
const [layoutModal, { openModal: openLayoutModal }] = useModal();
const [defaultLayoutModal, { openModal: openDefaultLayoutModal }] = useModal();
const { tableContext } = useListPage({
tableProps: {
title: '设备管理表',
api: defaultList,
// dataSource: dataSource,
columns: layoutColumns,
canResize: false,
orderFlag: false,
defSort: {
column: 'houseWorkDay',
order: 'asc',
},
rowSelection: { type: 'radio' },
showActionColumn: false,
formConfig: {
showSubmitButton: false,
showResetButton: false,
},
beforeFetch: (params) => {
params['houseCode'] = houseCode.value;
return params;
},
showIndexColumn: false,
// actionColumn: {
// width: 450,
// fixed: 'right',
// },
},
});
const [deviceTable, { reload, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
function edit() {
if (!selectedRowKeys.value.length || selectedRowKeys.value.length > 1) {
return createMessage.warning('请选择一条数据!');
}
let id = selectedRowKeys.value[0];
let dataSource = getDataSource();
let record = dataSource.filter((item) => item.id === id)[0];
openLayoutModal(true, {
record,
isUpdate: true,
title: '编辑',
});
}
function editLayout() {
openDefaultLayoutModal(true, {
isUpdate: true,
title: '编辑',
});
}
function layoutSuccess() {
reload();
}
</script>
<style lang="less" scoped>
.layout-table {
/deep/ .ant-form {
display: none;
}
}
</style>
@@ -1,86 +0,0 @@
<template>
<BasicDrawer @register="projectDrawer" title="设备项目" :width="900" :show-footer="false" :maskClosable="false">
<BasicTable @register="projectTable" :rowSelection="rowSelection" class="device-table">
<template #tableTitle>
<a-button type="primary" :icon="h(PlusOutlined)" @click="addProject"> 新增 </a-button>
</template>
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
<ProjectModal @register="projectModal" @success="handleSuccess"></ProjectModal>
</BasicDrawer>
</template>
<script lang="ts" setup>
import BasicDrawer from '/@/components/Drawer/src/BasicDrawer.vue';
import { useDrawerInner } from '/@/components/Drawer';
import ProjectModal from '/@/views/archive/healthCabin/healthRoom/components/projectModal.vue';
import BasicTable from '/@/components/Table/src/BasicTable.vue';
import { useListPage } from '/@/hooks/system/useListPage';
import { projectList, projectDetele } from '/@/views/archive/healthCabin/healthRoom/index.api';
import { projectColums } from '/@/views/archive/healthCabin/healthRoom/index.data';
import { ref, h } from 'vue';
import { PlusOutlined } from '@ant-design/icons-vue';
import { TableAction } from '/@/components/Table';
import { useModal } from '/@/components/Modal';
let deviceCode = ref();
let deviceName = ref();
const [projectDrawer, { setDrawerProps }] = useDrawerInner(async (data) => {
console.log(data.record, 1111111);
deviceCode.value = data.record.deviceCode;
deviceName.value = data.record.deviceName;
});
const [projectModal, { openModal }] = useModal();
const { tableContext } = useListPage({
tableProps: {
title: '设备项目表',
api: projectList,
columns: projectColums,
canResize: false,
orderFlag: false,
showIndexColumn: false,
useSearchForm: false,
actionColumn: {
width: 100,
fixed: 'right',
},
},
});
const [projectTable, { reload, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
function getTableAction(record: any) {
return [
{
label: '编辑',
onClick: projectEdit.bind(null, record),
},
{
label: '删除',
onClick: projectDelete.bind(null, record),
},
];
}
function addProject() {
openModal(true, {
title: '新增',
isUpdate: false,
deviceCode: deviceCode.value,
deviceName: deviceName.value,
});
}
function projectEdit(record) {
openModal(true, {
title: '编辑',
record,
isUpdate: true,
deviceCode: deviceCode.value,
deviceName: deviceName.value,
});
}
function handleSuccess() {
reload();
}
function projectDelete(record) {
projectDetele({ id: record.id }, reload);
}
</script>
<style lang="less" scoped></style>
@@ -1,56 +0,0 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" width="40%" @ok="handleSubmit">
<BasicForm @register="registerForm"> </BasicForm>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { useForm } from '/@/components/Form';
import BasicForm from '/@/components/Form/src/BasicForm.vue';
import { projectSchemas } from '/@/views/archive/healthCabin/healthRoom/index.data';
import { projectAdd, projectEdit } from '/@/views/archive/healthCabin/healthRoom/index.api';
const title = ref('新增');
const emit = defineEmits(['register', 'success']);
const deviceCode = ref();
const isUpdate = ref(false);
const projectId = ref();
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
console.log(data.record);
setModalProps({ confirmLoading: false });
await resetFields();
title.value = `设备名称:${data.deviceName},设备编号:${data.deviceCode}`;
deviceCode.value = data.deviceCode;
isUpdate.value = data.isUpdate;
if (data.isUpdate) {
projectId.value = data.record.id;
await setFieldsValue({ ...data.record });
}
});
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
//labelWidth: 150,
schemas: projectSchemas,
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
async function handleSubmit() {
try {
const values = await validate();
console.log(values);
values.deviceCode = deviceCode.value;
if (isUpdate.value) {
values.id = projectId.value;
await projectEdit(values);
} else {
await projectAdd(values);
}
closeModal();
emit('success');
} catch (e) {
setModalProps({ confirmLoading: false });
}
}
</script>
<style lang="less" scoped></style>
@@ -1,112 +0,0 @@
<template>
<BasicDrawer @register="registerDrawer" title="默认模板" :width="900" :show-footer="false">
<BasicTable @register="deviceTable" :pagination="true" size="small" :rowSelection="rowSelection" class="layout-table">
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'openTime'">
<div>{{ record.openTime }}--{{ record.closeTime }}</div>
</template>
</template>
<template #tableTitle>
<a-button type="primary" :icon="h(PlusOutlined)" @click="add"> 新增 </a-button>
</template>
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
<SelfLayoutModal @register="selfModal" @success="selfSuccess"></SelfLayoutModal>
</BasicDrawer>
</template>
<script lang="ts" setup>
import { ref, unref, h } from 'vue';
import { PlusOutlined, EditOutlined } from '@ant-design/icons-vue';
import BasicDrawer from '/@/components/Drawer/src/BasicDrawer.vue';
import { useDrawer, useDrawerInner } from '/@/components/Drawer';
import BasicTable from '/@/components/Table/src/BasicTable.vue';
import { selfLayoutColumns } from '/@/views/archive/healthCabin/healthRoom/index.data';
import { useListPage } from '/@/hooks/system/useListPage';
import { useMessage } from '/@/hooks/web/useMessage';
import SelfLayoutModal from '/@/views/archive/healthCabin/healthRoom/components/selfLayoutModal.vue';
import { useModal } from '/@/components/Modal';
import { selfLayoutList, selfLayoutDelete } from '/@/views/archive/healthCabin/healthRoom/index.api';
import { TableAction } from '/@/components/Table';
const { createMessage } = useMessage();
const houseCode = ref();
const [registerDrawer, { setDrawerProps }] = useDrawerInner(async (data) => {
houseCode.value = data.record.houseCode;
console.log(data);
});
const [selfModal, { openModal }] = useModal();
const { tableContext } = useListPage({
tableProps: {
title: '设备管理表',
api: selfLayoutList,
// dataSource: dataSource,
columns: selfLayoutColumns,
canResize: false,
orderFlag: false,
showActionColumn: true,
formConfig: {
showSubmitButton: false,
showResetButton: false,
},
defSort: {
column: 'defineDate',
order: 'asc',
},
beforeFetch: (params) => {
params['houseCode'] = houseCode.value;
return params;
},
showIndexColumn: false,
// actionColumn: {
// width: 450,
// fixed: 'right',
// },
},
});
const [deviceTable, { reload, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
function add() {
openModal(true, {
houseCode: houseCode.value,
title: '新增',
});
}
function getTableAction(record: any) {
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
},
{
label: '删除',
onClick: handleDetele.bind(null, record),
},
];
}
function handleEdit(record) {
openModal(true, {
houseCode: houseCode.value,
isUpdate: true,
title: '编辑',
record,
});
}
function handleDetele(record) {
selfLayoutDelete({ id: record.id }, reload);
}
function selfSuccess() {
reload();
}
</script>
<style lang="less" scoped>
.layout-table {
/deep/ .ant-form {
display: none;
}
}
</style>
@@ -1,170 +0,0 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" width="40%" @ok="handleSubmit">
<BasicForm @register="register" class="self">
<template #add="{ field }">
<Button v-if="Number(field) === 0 && !isUpdate" @click="add">+</Button>
<Button v-if="field > 0" @click="del(field)">-</Button>
</template>
</BasicForm>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { Button } from '/@/components/Button';
import { selfLayoutSchemas } from '/@/views/archive/healthCabin/healthRoom/index.data';
import { selfLayoutAdd, selfLayoutEdit } from '/@/views/archive/healthCabin/healthRoom/index.api';
const title = ref('新增');
const emit = defineEmits(['register', 'success']);
const isUpdate = ref(false);
const state = ref();
const houseCode = ref();
const selfLayoutId = ref();
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
console.log(data);
houseCode.value = data.houseCode;
await resetFields();
// addSchema(0);
// await removeSchemaByFiled()
title.value = data.title;
isUpdate.value = data.isUpdate;
await removeSchemaByFiled(['wokrStatus']);
if (data.isUpdate) {
await appendSchemaByField(
{
field: `wokrStatus`,
component: 'JDictSelectTag',
label: '是否启用',
colProps: {
span: 8,
},
componentProps: {
dictCode: 'yes_no',
},
},
''
);
selfLayoutId.value = data.record.id;
const DateTime = data.record.defineDate + ' 00:00:00';
await setFieldsValue({ defineDate: DateTime });
await setFieldsValue({ 'houseOpenTime[0].openTime': data.record.openTime });
await setFieldsValue({ 'houseOpenTime[0].closeTime': data.record.closeTime });
}
});
const [register, { resetFields, setFieldsValue, appendSchemaByField, removeSchemaByFiled, validate }] = useForm({
labelWidth: 100,
actionColOptions: { span: 24 },
schemas: selfLayoutSchemas,
showSubmitButton: false,
showResetButton: false,
});
async function handleSubmit() {
try {
const data = await validate();
const result = Object.keys(data).reduce(
(acc, key) => {
const parts = key.match(/houseOpenTime\[(\d+)\]\.(\w+)/);
if (parts) {
const index = parseInt(parts[1], 10);
const prop = parts[2];
if (!acc.houseOpenTime[index]) {
acc.houseOpenTime[index] = {};
}
acc.houseOpenTime[index][prop] = data[key];
}
return acc;
},
{ houseOpenTime: [] }
);
console.log(result);
console.log(data);
const params = {
houseCode: houseCode.value,
defineDate: data.defineDate,
houseOpenTime: result.houseOpenTime,
};
if (isUpdate.value) {
params.wokrStatus = data.wokrStatus;
params.id = selfLayoutId.value;
await selfLayoutEdit(params);
} else {
await selfLayoutAdd(params);
}
result.houseOpenTime.forEach((item, index) => {
if (index == 0) return;
if (index != 0) del(index);
});
closeModal();
emit('success');
} catch (e) {
console.log(e);
}
}
const n = ref(1);
function add() {
addSchema(n.value);
n.value++;
}
function addSchema(num) {
appendSchemaByField(
{
field: `houseOpenTime[${num}].openTime`,
component: 'TimePicker',
label: '开始时间',
colProps: {
span: 8,
},
componentProps: {
//日期格式化
format: 'HH:mm',
valueFormat: 'HH:mm',
},
},
''
);
appendSchemaByField(
{
field: `houseOpenTime[${num}].closeTime`,
component: 'TimePicker',
label: '结束时间',
colProps: {
span: 8,
},
componentProps: {
//日期格式化
format: 'HH:mm',
valueFormat: 'HH:mm',
},
},
''
);
appendSchemaByField(
{
field: `${num}`,
component: 'Input',
label: '',
colProps: {
span: 8,
},
slot: 'add',
},
''
);
}
function del(field) {
removeSchemaByFiled([`houseOpenTime[${field}].closeTime`, `houseOpenTime[${field}].openTime`, `${field}`]);
n.value--;
}
</script>
<style lang="less" scoped>
.self {
/deep/ .ant-picker-panel-container {
position: fixed !important;
}
}
</style>
@@ -1,104 +0,0 @@
<template>
<BasicDrawer @register="terminalDrawer" title="终端管理" :width="1200" :maskClosable="false" :show-footer="false">
<BasicTable @register="terminalTable" :rowSelection="rowSelection">
<template #tableTitle>
<a-button type="primary" :icon="h(PlusOutlined)" @click="addTerminal"> 新增 </a-button>
</template>
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
<AddTerminalModal @register="terminalRegister" @success="addTerminalSuccess"></AddTerminalModal>
<TermEquipDrawer @register="termEquipRegister"></TermEquipDrawer>
</BasicDrawer>
</template>
<script lang="ts" setup>
import BasicDrawer from '/@/components/Drawer/src/BasicDrawer.vue';
import { useDrawer, useDrawerInner } from '/@/components/Drawer';
import { ref, h } from 'vue';
import { PlusOutlined } from '@ant-design/icons-vue';
import BasicTable from '/@/components/Table/src/BasicTable.vue';
import { useListPage } from '/@/hooks/system/useListPage';
import { terminalList, terminalDetele } from '/@/views/archive/healthCabin/healthRoom/index.api';
import { terminalColumns, terminalSearchFormSchema } from '/@/views/archive/healthCabin/healthRoom/index.data';
import { TableAction } from '/@/components/Table';
import { useModal } from '/@/components/Modal';
import AddTerminalModal from '/@/views/archive/healthCabin/healthRoom/components/addTerminalModal.vue';
import TermEquipDrawer from '/@/views/archive/healthCabin/healthRoom/components/terminalEquipmentDrawer.vue';
let houseCode = ref();
const [terminalDrawer, { setDrawerProps }] = useDrawerInner(async (data) => {
console.log(data);
houseCode.value = data.record.houseCode;
});
const { tableContext } = useListPage({
tableProps: {
title: '健康室表',
api: terminalList,
columns: terminalColumns,
canResize: false,
orderFlag: false,
showIndexColumn: false,
formConfig: {
schemas: terminalSearchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: false,
fieldMapToNumber: [],
fieldMapToTime: [],
},
// beforeFetch: (params) => {
// params['orgCode'] = 'A01A11'
// return params;
// },
actionColumn: {
width: 200,
fixed: 'right',
},
},
});
const [terminalTable, { reload, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
const [terminalRegister, { openModal }] = useModal();
// termEquipRegister
const [termEquipRegister, { openDrawer: openTermEquipDrawer }] = useDrawer();
function addTerminal() {
openModal(true, {
title: '新增',
houseCode: houseCode.value,
});
}
function getTableAction(record: any) {
return [
{
label: '终端设备',
onClick: terminalEqui.bind(null, record),
},
{
label: '编辑',
onClick: editTerminal.bind(null, record),
},
{
label: '删除',
onClick: deteleTerminal.bind(null, record),
},
];
}
function editTerminal(record) {
openModal(true, {
title: '编辑',
isUpdate: true,
record,
houseCode: houseCode.value,
});
}
function deteleTerminal(record) {
terminalDetele({ id: record.id }, reload);
}
function addTerminalSuccess() {
reload();
}
function terminalEqui(record) {
openTermEquipDrawer(true, {
record,
});
}
</script>
<style lang="less" scoped></style>
@@ -1,75 +0,0 @@
<template>
<BasicDrawer @register="projectDrawer" title="终端设备" :width="900" :show-footer="false" :maskClosable="false">
<BasicTable @register="projectTable" :rowSelection="rowSelection" class="device-table">
<template #tableTitle>
<a-button type="primary" :icon="h(PlusOutlined)" @click="addTerEqui"> 新增 </a-button>
</template>
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
<AddTerEquiModal @register="TerEquiModal" @success="handleSuccess"></AddTerEquiModal>
</BasicDrawer>
</template>
<script lang="ts" setup>
import BasicDrawer from '/@/components/Drawer/src/BasicDrawer.vue';
import { useDrawerInner } from '/@/components/Drawer';
import AddTerEquiModal from '/@/views/archive/healthCabin/healthRoom/components/addTerEquipmentModal.vue';
import BasicTable from '/@/components/Table/src/BasicTable.vue';
import { useListPage } from '/@/hooks/system/useListPage';
import { terEquiColums } from '/@/views/archive/healthCabin/healthRoom/index.data';
import { ref, h } from 'vue';
import { listByTerminal, terEquiDelete } from '/@/views/archive/healthCabin/healthRoom/index.api';
import { PlusOutlined } from '@ant-design/icons-vue';
import { TableAction } from '/@/components/Table';
import { useModal } from '/@/components/Modal';
const terminalCode = ref();
const [projectDrawer, { setDrawerProps }] = useDrawerInner(async (data) => {
console.log(data.record, 1111111);
terminalCode.value = data.record.terminalCode;
});
const [TerEquiModal, { openModal }] = useModal();
const { tableContext } = useListPage({
tableProps: {
title: '设备项目表',
api: listByTerminal,
columns: terEquiColums,
canResize: false,
orderFlag: false,
showIndexColumn: false,
useSearchForm: false,
actionColumn: {
width: 100,
fixed: 'right',
},
beforeFetch: (params) => {
params['terminalCode'] = terminalCode.value;
return params;
},
},
});
const [projectTable, { reload, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
function getTableAction(record: any) {
return [
{
label: '删除',
onClick: projectDelete.bind(null, record),
},
];
}
function addTerEqui() {
openModal(true, {
title: '新增',
terminalCode: terminalCode.value,
isUpdate: false,
});
}
function handleSuccess() {
reload();
}
function projectDelete(record) {
terEquiDelete({ id: record.id }, reload);
// projectDetele({ id: record.id }, reload);
}
</script>
<style lang="less" scoped></style>
@@ -1,201 +0,0 @@
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
const { createConfirm } = useMessage();
enum Api {
list = '/health-archives/housenew/healthHouseNew/list',
addRoom = '/health-archives/housenew/healthHouseNew/add',
deleteRoom = '/health-archives/housenew/healthHouseNew/delete',
deleteBatchRoom = '/health-archives/housenew/healthHouseNew/deleteBatch',
getRoomById = '/health-archives/housenew/healthHouseNew/queryById',
editRoom = '/health-archives/housenew/healthHouseNew/edit',
//设备
deviceList = '/health-archives/housenew/healthHouseDeviceNew/list',
deviceAdd = '/health-archives/housenew/healthHouseDeviceNew/add',
deviceEdit = '/health-archives/housenew/healthHouseDeviceNew/edit',
deviceDelete = '/health-archives/housenew/healthHouseDeviceNew/delete',
deviceChangeStatus = '/health-archives/housenew/healthHouseDeviceNew/changeStatus',
//设备项目
projectList = '/health-archives/housenew/healthHouseDeviceProjectNew/list',
projectAdd = '/health-archives/housenew/healthHouseDeviceProjectNew/add',
projectEdit = '/health-archives/housenew/healthHouseDeviceProjectNew/edit',
projectDetele = '/health-archives/housenew/healthHouseDeviceProjectNew/delete',
//默认排班
defaultList = '/health-archives//housenew/healthHouseNumberNew/list',
defaultEdit = '/health-archives/housenew/healthHouseNumberNew/edit',
//终端
terminalList = '/health-archives/housenew/healthHouseTerminalNew/list',
terminalAdd = '/health-archives/housenew/healthHouseTerminalNew/add',
terminalEdit = '/health-archives/housenew/healthHouseTerminalNew/edit',
terminalDetele = '/health-archives/housenew/healthHouseTerminalNew/delete',
listByTerminal = '/health-archives/housenew/healthHouseDeviceNew/listByTerminal',
bindDevices = '/health-archives/housenew/healthHouseTerminalNew/bindDevices',
terEquiDelete = '/health-archives/housenew/healthHouseTerminalRelationNew/delete',
//自定义排班
selfLayoutList = '/health-archives/housenew/healthHouseDefineNew/list',
selfLayoutAdd = '/health-archives/housenew/healthHouseDefineNew/add',
selfLayoutDelete = '/health-archives/housenew/healthHouseDefineNew/delete',
selfLayoutEdit = '/health-archives/housenew/healthHouseDefineNew/edit',
// 管理员列表
adminList = '/health-archives/housenew/healthHouseManagerNew/houseManagers',
addAdmin = '/health-archives/housenew/healthHouseManagerNew/addHouseManagers',
}
// 健康室列表
export const listApi = (params: any) => defHttp.get({ url: Api.list, params });
// 通过id获取健康室信息
export const getRoomById = (params: any) => defHttp.get({ url: Api.getRoomById, params });
// 健康室新增
export const addRoom = (params: any) => defHttp.post({ url: Api.addRoom, params });
// 健康室编辑
export const editRoom = (params: any) => defHttp.put({ url: Api.editRoom, params });
//小屋删除
// export const deleteRoom =
export const deleteRoom = (params, handleSuccess) => {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
return defHttp.delete({ url: Api.deleteRoom + `?id=${params.id}`, params }).then(() => {
handleSuccess();
});
},
});
};
//健康室批量删除
export const deleteBatchRoom = (params, handleSuccess) => {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
return defHttp.delete({ url: Api.deleteBatchRoom, data: params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
},
});
};
//设备列表
export const deviceList = (params: any) => defHttp.get({ url: Api.deviceList, params });
//设备新增
export const deviceAdd = (params: any) => defHttp.post({ url: Api.deviceAdd, params });
//设备编辑
export const deviceEdit = (params: any) => defHttp.put({ url: Api.deviceEdit, params });
//设备删除
export const deviceDelete = (params, handleSuccess) => {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
return defHttp.delete({ url: Api.deviceDelete + `?id=${params.id}`, params }).then(() => {
handleSuccess();
});
},
});
};
//设备状态
export const deviceChangeStatus = (params: any) => defHttp.post({ url: Api.deviceChangeStatus, params });
//设备项目列表
export const projectList = (params: any) => defHttp.get({ url: Api.projectList, params });
//项目新增
export const projectAdd = (params: any) => defHttp.post({ url: Api.projectAdd, params });
//项目编辑
export const projectEdit = (params: any) => defHttp.put({ url: Api.projectEdit, params });
//项目删除
export const projectDetele = (params, handleSuccess) => {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
return defHttp.delete({ url: Api.projectDetele + `?id=${params.id}`, params }).then(() => {
handleSuccess();
});
},
});
};
//默认排班列表
export const defaultList = (params: any) => defHttp.get({ url: Api.defaultList, params });
//默认排班编辑
export const defaultEdit = (params: any) => defHttp.put({ url: Api.defaultEdit, params });
//终端列表
export const terminalList = (params: any) => defHttp.get({ url: Api.terminalList, params });
//终端新增
export const terminalAdd = (params: any) => defHttp.post({ url: Api.terminalAdd, params });
//终端编辑
export const terminalEdit = (params: any) => defHttp.put({ url: Api.terminalEdit, params });
//终端删除 terminalDetele
export const terminalDetele = (params, handleSuccess) => {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
return defHttp.delete({ url: Api.terminalDetele + `?id=${params.id}`, params }).then(() => {
handleSuccess();
});
},
});
};
//通过终端查询设备
export const listByTerminal = (params: any) => defHttp.get({ url: Api.listByTerminal, params });
//绑定终端设备
export const bindDevices = (params: any) => defHttp.post({ url: Api.bindDevices, params });
//终端设备删除
export const terEquiDelete = (params, handleSuccess) => {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
return defHttp.delete({ url: Api.terEquiDelete + `?id=${params.id}`, params }).then(() => {
handleSuccess();
});
},
});
};
//自定义排班列表
export const selfLayoutList = (params: any) => defHttp.get({ url: Api.selfLayoutList, params });
//自定义排班新增
export const selfLayoutAdd = (params: any) => defHttp.post({ url: Api.selfLayoutAdd, params });
//自定义排班删除
export const selfLayoutDelete = (params, handleSuccess) => {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
return defHttp.delete({ url: Api.selfLayoutDelete + `?id=${params.id}`, params }).then(() => {
handleSuccess();
});
},
});
};
//自定义排班编辑
export const selfLayoutEdit = (params: any) => defHttp.put({ url: Api.selfLayoutEdit, params });
// 管理员列表
export const adminList = (params: any) => defHttp.get({ url: Api.adminList, params });
// 管理员新增
export const addAdmin = (params: any) => defHttp.post({ url: Api.addAdmin, params });
@@ -1,745 +0,0 @@
import { BasicColumn, FormSchema } from '/@/components/Table';
import { h } from 'vue';
import { Image } from 'ant-design-vue';
import { getDefaultImage, getFileAccessHttpUrl } from '/@/utils/common/compUtils';
import { EyeOutlined } from '@ant-design/icons-vue';
import { getThirdDepartListByOrgCode } from '/@/views/archive/employeeFile/employeeFileList.api';
import { useUserStore } from '/@/store/modules/user';
import { ref } from 'vue';
import { checkPassword } from '/@/hooks/checkPassword/checkPassword';
import { rules } from '/@/utils/helper/validator';
export const columns: BasicColumn[] = [
{
title: '名称',
align: 'center',
dataIndex: 'houseName',
},
{
title: '地点',
align: 'center',
dataIndex: 'housePlace',
},
{
title: '图片',
align: 'center',
dataIndex: 'houseImage',
customRender: ({ text }) => {
const t = text ? text.replace(',', '') : null;
return h(Image, {
placeholder: true,
src: getFileAccessHttpUrl(t),
height: 50,
width: 50,
fallback: getDefaultImage(),
previewMask: () => {
return h(EyeOutlined, {
style: {
color: 'white',
},
});
},
});
},
},
{
title: '所属部门',
align: 'center',
dataIndex: 'departName',
},
{
title: '启用',
align: 'center',
dataIndex: 'houseStatus_dictText',
// customRender: ({ text }) => {
// if (!text) return '';
// return text == '1' ? '是' : '否';
// },
},
{
title: '法定排班',
align: 'center',
dataIndex: 'legalStatus_dictText',
},
];
export const searchFormSchema: FormSchema[] = [
{
label: '所属部门',
field: 'orgCode',
component: 'ApiSelect',
componentProps: () => {
const userOrgCode = user?.userInfo?.orgCode?.substring(0, 6);
return {
api: getThirdDepartListByOrgCode,
resultField: 'list',
labelField: 'departName',
params: {
orgCode: userOrgCode || '12313',
},
valueField: 'orgCode',
immediate: true,
};
},
},
{
label: '启用状态',
field: 'houseStatus',
component: 'JDictSelectTag',
componentProps: {
dictCode: 'yes_no',
},
},
];
const user = useUserStore();
export const schemas: FormSchema[] = [
{
label: '健康室名称',
field: 'houseName',
component: 'Input',
required: true,
},
{
label: '健康室地址',
field: 'housePlace',
component: 'Input',
slot: 'address',
required: true,
},
{
label: '所属部门',
field: 'orgCode',
component: 'ApiSelect',
required: true,
componentProps: () => {
const userOrgCode = user?.userInfo?.orgCode?.substring(0, 6);
return {
api: getThirdDepartListByOrgCode,
resultField: 'list',
labelField: 'departName',
params: {
orgCode: userOrgCode || '12313',
},
valueField: 'orgCode',
immediate: true,
};
},
},
{
label: '使用部门',
field: 'useDeparts',
component: 'ApiSelect',
required: true,
componentProps: () => {
const userOrgCode = user?.userInfo?.orgCode?.substring(0, 6);
return {
api: getThirdDepartListByOrgCode,
resultField: 'list',
mode: 'multiple',
labelField: 'departName',
params: {
orgCode: userOrgCode || '12313',
},
valueField: 'orgCode',
immediate: true,
};
},
},
{
label: '默认排班',
field: 'defaultHouseNumber',
component: 'Input',
defaultValue: '5,4,3,2,1',
slot: 'defaultHouseNumber',
},
{
label: '使用法定排班',
field: 'legalStatus',
component: 'JDictSelectTag',
componentProps: {
dictCode: 'yes_no',
},
required: true,
},
{
label: '启用状态',
field: 'houseStatus',
component: 'JDictSelectTag',
componentProps: {
dictCode: 'yes_no',
},
required: true,
},
{
label: '健康室图片',
field: 'houseImage',
component: 'JImageUpload',
componentProps: {
maxCount: 1,
},
rules: [{ required: true, trigger: 'blur', message: '请上传健康室图片' }],
},
];
export const deviceColumns: BasicColumn[] = [
{
title: '设备编号',
align: 'center',
dataIndex: 'deviceCode',
},
{
title: '设备名称',
align: 'center',
dataIndex: 'deviceName',
},
{
title: '设备状态',
align: 'center',
dataIndex: 'deviceStatus',
customRender: ({ text }) => {
if (!text) return '';
switch (text) {
case 1:
return '有效';
}
},
},
{
title: '设备图片',
align: 'center',
dataIndex: 'deviceImage',
customRender: ({ text }) => {
const t = text ? text.replace(',', '') : null;
return h(Image, {
placeholder: true,
src: getFileAccessHttpUrl(t),
height: 50,
width: 50,
fallback: getDefaultImage(),
previewMask: () => {
return h(EyeOutlined, {
style: {
color: 'white',
},
});
},
});
},
},
{
title: '设备类型',
align: 'center',
dataIndex: 'categoryCode', //
customRender: ({ text }) => {
if (!text) return '';
if (text == 1) return '测量设备';
if (text == 2) return '心理检测';
if (text == 3) return '治疗设备';
if (text == 4) return '监测设备';
},
},
{
title: '单位预约时间(分钟)',
align: 'center',
dataIndex: 'lengthOfTime',
},
{
title: '可预约人数(人)',
align: 'center',
dataIndex: 'useNum',
},
];
export const deviceSearchFormSchema: FormSchema[] = [
{
label: '设备类型',
field: 'categoryCode',
component: 'JDictSelectTag',
componentProps: {
dictCode: 'house_category',
},
},
];
export const deviceSchemas: FormSchema[] = [
{
label: '设备编号',
field: 'deviceCode',
component: 'Input',
},
{
label: '设备名称',
field: 'deviceName',
component: 'Input',
},
{
label: '设备类型',
field: 'categoryCode',
component: 'JDictSelectTag',
componentProps: {
dictCode: 'house_category',
},
required: true,
},
{
label: '单位预约时间',
field: 'lengthOfTime',
component: 'Select',
ifShow: ({ values }) => {
if (!values.categoryCode) return false;
if (values.categoryCode != 4) {
return true;
} else {
values.lengthOfTime = '';
return false;
}
},
componentProps: {
options: [
{
label: '10分钟',
value: '10',
},
{
label: '20分钟',
value: '20',
},
{
label: '30分钟',
value: '30',
},
{
label: '40分钟',
value: '40',
},
{
label: '50分钟',
value: '50',
},
{
label: '60分钟',
value: '60',
},
],
placeholder: '请选择时长',
},
},
{
label: '可预约人数',
field: 'useNum',
component: 'Input',
ifShow: ({ values }) => {
if (!values.categoryCode) return false;
if (values.categoryCode != 4) {
return true;
} else {
values.useNum = '';
return false;
}
},
},
{
label: '添加图片',
field: 'deviceImage',
component: 'JImageUpload',
componentProps: {
maxCount: 1,
},
rules: [{ required: true, trigger: 'blur', message: '请上传健康室图片' }],
},
{
label: '设备介绍',
field: 'deviceRemark',
component: 'JEditor',
componentProps: () => {
return {
height: 200,
};
},
},
{
label: '预约须知',
field: 'deviceNotice',
component: 'JEditor',
componentProps: () => {
return {
height: 200,
};
},
},
];
export const layoutColumns: BasicColumn[] = [
{
title: '工作日',
dataIndex: 'houseWorkDay',
customCell: (_, index) => {
if (index % 2 === 0) {
return {
rowSpan: 2,
};
} else {
return {
rowSpan: 0,
};
}
},
customRender: ({ text }) => {
if (text == 1) return '星期一';
if (text == 2) return '星期二';
if (text == 3) return '星期三';
if (text == 4) return '星期四';
if (text == 5) return '星期五';
if (text == 6) return '星期六';
if (text == 7) return '星期日';
},
},
{
title: '开放时间',
dataIndex: 'openTime',
},
{
title: '启用',
dataIndex: 'wokrStatus',
customRender: ({ text }) => {
if (text == 1) return '是';
if (text == 0) return '否';
},
},
];
export const layoutSchemas: FormSchema[] = [
{
field: 'houseWorkDay',
label: '工作日',
component: 'JDictSelectTag',
componentProps: {
dictCode: 'week',
},
required: true,
},
{
field: 'openTime',
label: '开始时间',
component: 'Input',
slot: 'openTime',
required: true,
},
{
field: 'closeTime',
label: '结束时间',
component: 'Input',
slot: 'closeTime',
required: true,
},
{
field: 'wokrStatus',
label: '排班状态:启用',
component: 'JDictSelectTag',
componentProps: {
dictCode: 'yes_no',
},
required: true,
},
];
export const defaultLayoutSchemas: FormSchema[] = [
{
field: 'defaultLayout',
label: '默认排班',
component: 'Input',
slot: 'defaultLayout',
},
{
field: 'use',
label: '使用法定排班',
component: 'JDictSelectTag',
componentProps: {
dictCode: 'yes_no',
},
},
];
export const projectColums: BasicColumn[] = [
{
title: '项目编号',
dataIndex: 'projectCode',
},
{
title: '项目名称',
dataIndex: 'projectName',
},
{
title: '项目是否有效',
dataIndex: 'projectStatus',
customRender: ({ text }) => {
if (!text) return '';
if (text == 0) return '无效';
if (text == 1) return '有效';
},
},
];
export const projectSchemas: FormSchema[] = [
{
field: 'projectCode',
label: '项目编号',
component: 'Input',
required: true,
},
{
field: 'projectName',
label: '项目名称',
component: 'Input',
required: true,
},
{
field: 'projectStatus',
label: '项目是否有效',
component: 'JDictSelectTag',
componentProps: {
dictCode: 'yes_no',
},
required: true,
},
{
field: 'projectNotice',
label: '项目须知',
component: 'InputTextArea',
},
];
// 终端
export const terminalColumns: BasicColumn[] = [
{
title: '终端编号',
dataIndex: 'terminalCode',
},
{
title: '终端名称',
dataIndex: 'terminalName',
},
{
title: '终端状态',
dataIndex: 'terminalStatus',
customRender: ({ text }) => {
if (!text) return '';
if (text == 0) return '无效';
if (text == 1) return '有效';
},
},
];
export const terminalSearchFormSchema: FormSchema[] = [
{
field: 'terminalName',
label: '终端名称',
component: 'JInput',
},
];
export const terminalFormSchema: FormSchema[] = [
{
field: 'terminalCode',
label: '终端编号',
component: 'Input',
required: true,
},
{
field: 'terminalName',
label: '终端名称',
component: 'Input',
required: true,
},
{
field: 'terminalStatus',
label: '是否有效',
component: 'JDictSelectTag',
componentProps: {
dictCode: 'yes_no',
},
required: true,
},
];
//终端设备
export const terEquiColums: BasicColumn[] = [
{
title: '设备编号',
dataIndex: 'deviceCode',
},
{
title: '设备名称',
dataIndex: 'deviceName',
},
{
title: '设备类型',
dataIndex: 'categoryCode_dictText',
},
];
export const terEquiChangeColums: BasicColumn[] = [
{
title: '设备编号',
dataIndex: 'deviceCode',
},
{
title: '设备名称',
dataIndex: 'deviceName',
},
];
export const selfLayoutColumns: BasicColumn[] = [
{
title: '自定义日期',
dataIndex: 'defineDate',
},
{
title: '开放时间',
dataIndex: 'openTime',
slots: 'openTime',
},
{
title: '启用',
dataIndex: 'wokrStatus',
customRender: ({ text }) => {
if (!text) return '';
if (text == 0) return '否';
if (text == 1) return '是';
},
},
];
export const selfLayoutSchemas: FormSchema[] = [
{
field: 'defineDate',
component: 'DatePicker',
label: '选择日期',
componentProps: {
//日期格式化
format: 'YYYY-MM-DD',
valueFormat: 'YYYY-MM-DD HH:mm:ss',
},
required: true,
},
{
field: 'houseOpenTime[0].openTime',
component: 'TimePicker',
label: '开始时间',
colProps: {
span: 8,
},
componentProps: {
//日期格式化
format: 'HH:mm',
valueFormat: 'HH:mm',
},
},
{
field: 'houseOpenTime[0].closeTime',
component: 'TimePicker',
label: '结束时间',
colProps: {
span: 8,
},
componentProps: {
//日期格式化
format: 'HH:mm',
valueFormat: 'HH:mm',
},
},
{
field: '0',
component: 'Input',
label: '',
colProps: {
span: 8,
},
slot: 'add',
},
];
// 管理员列表
export const administratorColumns: BasicColumn[] = [
{
title: '账号',
dataIndex: 'userName',
},
{
title: '姓名',
dataIndex: 'realName',
},
];
export const administratorSearchForm: FormSchema[] = [
{
field: 'realName',
label: '姓名',
component: 'Input',
},
];
export const administratorFormSchema: FormSchema[] = [
{
field: 'userName',
label: '账号',
component: 'Input',
componentProps: ({ formModel }) => {
return {
onInput: () => {
formModel.username = formModel.username.replace(/[^a-zA-Z0-9_]/g, '');
},
autocomplete: 'off',
};
},
dynamicDisabled: ({ values }) => {
return !!values.id;
},
required: true,
},
{
field: 'realName',
label: '姓名',
component: 'Input',
componentProps: () => {
return {
autocomplete: 'off',
};
},
required: true,
},
{
label: '密码',
field: 'password',
component: 'StrengthMeter',
componentProps: () => {
return {
autocomplete: 'new-password',
};
},
dynamicRules: () => {
return [
{
required: true,
validator: (_, value) => {
if (!value) {
return Promise.reject('请输入登录密码');
}
let { message } = checkPassword(value);
if (message === 'ok') {
return Promise.resolve();
} else {
return Promise.reject(message);
}
},
trigger: 'blur',
},
];
},
ifShow: ({ values }) => {
return !values.id;
},
},
{
label: '确认密码',
field: 'confirmPassword',
component: 'InputPassword',
componentProps: () => {
return {
autocomplete: 'off',
};
},
dynamicRules: ({ values }) => rules.confirmPassword(values, true),
ifShow: ({ values }) => {
return !values.id;
},
},
];
@@ -1,177 +0,0 @@
<template>
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<template #tableTitle>
<a-button type="primary" :icon="h(PlusOutlined)" @click="addRoom"> 新增 </a-button>
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
</template>
</BasicTable>
<AddRoom @register="addModal" @success="handleSuccess" />
<DeviceDrawer @register="registerDrawer" />
<LayoutDrawer @register="layoutDrawer" />
<TerminalDrawer @register="terminalDrawer" />
<AdminModal @register="adminModal" @success="handleSuccess" />
<SelfLayoutDrawer @register="selfLayoutDrawer" />
</template>
<script lang="ts" setup>
import { ref, onMounted, h } from 'vue';
import BasicTable from '/@/components/Table/src/BasicTable.vue';
import { useListPage } from '/@/hooks/system/useListPage';
import { TableAction } from '/@/components/Table';
import { columns, searchFormSchema } from '/@/views/archive/healthCabin/healthRoom/index.data';
import { listApi, deleteRoom } from '/@/views/archive/healthCabin/healthRoom/index.api';
import { useModal } from '/@/components/Modal';
import { PlusOutlined, EditOutlined, SearchOutlined, DeleteOutlined } from '@ant-design/icons-vue';
//抽屉
import DeviceDrawer from '/@/views/archive/healthCabin/healthRoom/components/deviceDrawer.vue';
import LayoutDrawer from '/@/views/archive/healthCabin/healthRoom/components/layoutDrawer.vue';
import TerminalDrawer from '/@/views/archive/healthCabin/healthRoom/components/terminalDrawer.vue';
//新增健康室弹窗
import AddRoom from '/@/views/archive/healthCabin/healthRoom/components/addRoomModal.vue';
import AdminModal from '/@/views/archive/healthCabin/healthRoom/components/adminModal.vue';
import SelfLayoutDrawer from '/@/views/archive/healthCabin/healthRoom/components/selfLayoutDrawer.vue';
import { useDrawer } from '/@/components/Drawer';
import { useMessage } from '/@/hooks/web/useMessage';
const { createMessage } = useMessage();
const { tableContext } = useListPage({
tableProps: {
title: '健康室表',
api: listApi,
columns,
canResize: false,
orderFlag: false,
showIndexColumn: false,
formConfig: {
schemas: searchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: false,
fieldMapToNumber: [],
fieldMapToTime: [],
},
// beforeFetch: (params) => {
// params['orgCode'] = 'A01A11'
// return params;
// },
actionColumn: {
width: 200,
fixed: 'right',
},
},
});
const [registerTable, { reload, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
const [registerDrawer, { openDrawer }] = useDrawer();
const [layoutDrawer, { openDrawer: openLayoutDrawer }] = useDrawer();
const [terminalDrawer, { openDrawer: openTerminalDrawer }] = useDrawer();
const [selfLayoutDrawer, { openDrawer: openSelfDrawer }] = useDrawer();
const [addModal, { openModal }] = useModal();
const [adminModal, { openDrawer: openAdminModal }] = useDrawer();
function getTableAction(record: any) {
return [
{
label: '设备管理',
onClick: handleDevice.bind(null, record),
},
{
label: '终端',
onClick: handleTerminal.bind(null, record),
},
];
}
function getDropDownAction(record: any) {
return [
{
label: '编辑',
onClick: edit.bind(null, record),
},
{
label: '详情',
onClick: onlyread.bind(null, record),
},
{
label: '默认排班',
onClick: handleLayout.bind(null, record),
},
{
label: '自定义排班',
onClick: handleCustom.bind(null, record),
},
{
label: '管理员',
onClick: handleAdmin.bind(null, record),
},
{
label: '删除',
onClick: handleDelete.bind(null, record),
},
];
}
// 设备管理
function handleDevice(record) {
openDrawer(true, {
record,
});
}
// 默认排版
function handleLayout(record) {
openLayoutDrawer(true, {
record,
});
}
// 自定义排版
function handleCustom(record) {
openSelfDrawer(true, {
record,
});
}
// 管理员
function handleAdmin(record) {
console.log(record);
openAdminModal(true, {
record,
});
}
// 终端
function handleTerminal(record) {
console.log(record);
openTerminalDrawer(true, {
record,
});
}
// 删除
function handleDelete(record) {
console.log(record);
deleteRoom({ id: record.id }, reload);
// deleteRoom
}
function edit(record) {
openModal(true, {
record,
isUpdate: true,
title: '编辑',
});
}
function onlyread(record) {
openModal(true, {
record,
isUpdate: true,
onlyRead: true,
title: '详情',
});
}
function addRoom() {
openModal(true, {
isUpdate: false,
title: '录入',
});
}
function handleSuccess() {
reload();
}
</script>
<style lang="less" scoped></style>
@@ -1,60 +0,0 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" width="40%" @ok="handleSubmit">
<BasicForm @register="registerForm" :disabled="onlyRead" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, unref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import BasicForm from '/@/components/Form/src/BasicForm.vue';
import { useForm } from '/@/components/Form';
import { schemas } from '/@/views/archive/healthCabin/planWork/planWork.data';
import { saveOrUpdate } from '/@/views/archive/healthCabin/planWork/planWork.api';
//设置标题
const title = ref(String);
// Emits声明
const emit = defineEmits(['register', 'success']);
const isUpdate = ref(true);
const onlyRead = ref('false');
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
//重置表单
await resetFields();
setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
isUpdate.value = !!data?.isUpdate;
title.value = data.type;
if (unref(isUpdate)) {
data.record['rangeTime'] = `${data.record.openTime},${data.record.closeTime}`;
}
//表单赋值
await setFieldsValue({
...data.record,
});
// 隐藏底部时禁用整个表单
setProps({ disabled: !data?.showFooter });
});
const [registerForm, { resetFields, setFieldsValue, validate, setProps }] = useForm({
//labelWidth: 150,
schemas,
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
async function handleSubmit() {
try {
let values = await validate();
setModalProps({ confirmLoading: true });
//提交表单
await saveOrUpdate(values, isUpdate.value);
//关闭弹窗
closeModal();
//刷新列表
emit('success');
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
<style lang="less" scoped></style>
@@ -1,67 +0,0 @@
// noinspection Eslint
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
const { createConfirm } = useMessage();
enum Api {
list = '/health-archives/housenew/healthHouseDefaultNumberConfigNew/list',
save = '/health-archives/housenew/healthHouseDefaultNumberConfigNew/add',
edit = '/health-archives/housenew/healthHouseDefaultNumberConfigNew/edit',
deleteOne = '/health-archives/housenew/healthHouseDefaultNumberConfigNew/delete',
deleteBatch = '/health-archives/housenew/healthHouseDefaultNumberConfigNew/deleteBatch',
importExcel = '/health-archives/housenew/healthHouseDefaultNumberConfigNew/exportXls',
exportXls = '/health-archives/housenew/healthHouseDefaultNumberConfigNew/importExcel',
}
/**
* 导出api
* @param params
*/
export const getExportUrl = Api.exportXls;
/**
* 导入api
*/
export const getImportUrl = Api.importExcel;
/**
* 列表接口
* @param params
*/
export const list = (params) => defHttp.get({ url: Api.list, params });
/**
* 删除单个
*/
export const deleteOne = (params, handleSuccess) => {
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
};
/**
* 批量删除
* @param params
*/
export const batchDelete = (params, handleSuccess) => {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
return defHttp.delete({ url: Api.deleteBatch, data: params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
},
});
};
/**
* 保存或者更新
* @param params
* @param isUpdate
*/
export const saveOrUpdate = (params: any, isUpdate: boolean) => {
const url = isUpdate ? Api.edit : Api.save;
return defHttp.post({ url: url, params });
};
@@ -1,94 +0,0 @@
import { BasicColumn, FormSchema } from '/@/components/Table';
import { BODY_CONTAINER } from '/@/utils/domUtils';
export const columns: BasicColumn[] = [
{
title: '工作日',
align: 'center',
dataIndex: 'workDay',
},
{
title: '开始时间',
align: 'center',
dataIndex: 'openTime',
},
{
title: '结束时间',
align: 'center',
dataIndex: 'closeTime',
},
];
export const searchFormSchema: FormSchema[] = [
{
label: '工作日',
field: 'workDay',
component: 'Input',
},
];
export const schemas: FormSchema[] = [
{
label: '工作日',
field: 'workDay',
component: 'Input',
rules: [{ required: true }],
},
// {
// label: '开始时间',
// field: 'openTime',
// component: 'TimePicker',
// //日期格式化
// componentProps: {
// //日期格式化
// format: 'HH/mm',
// },
// },
// {
// label: '结束时间',
// field: 'closeTime',
// component: 'TimePicker',
// //日期格式化
// componentProps: {
// //日期格式化
// format: 'HH/mm',
// },
// },
{
label: '有效期时间',
field: 'rangeTime',
component: 'RangeDate',
rules: [{ required: true }],
componentProps: ({ formModel }) => {
return {
picker: 'time',
format: 'HH:mm',
valueFormat: 'HH:mm',
getPopupContainer: () => BODY_CONTAINER,
onChange: (v) => {
const time = v ? v.split(',') : ['', ''];
formModel.openTime = time[0];
formModel.closeTime = time[1];
},
};
},
},
{
label: '',
field: 'openTime',
component: 'Input',
show: false,
},
{
label: '',
field: 'closeTime',
component: 'Input',
show: false,
},
// TODO 主键隐藏字段,目前写死为ID
{
label: '',
field: 'id',
component: 'Input',
show: false,
},
];
@@ -1,140 +0,0 @@
<template>
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<template #tableTitle>
<a-button type="primary" :icon="h(PlusOutlined)" @click="handleAdd" v-auth="'housenew:health_house_device_project:add'"> 新增 </a-button>
<!-- <a-button type="primary" :icon="h(EditOutlined)" @click="handleEdit" v-auth="'housenew:health_house_banner:edit'"> 编辑 </a-button>-->
<!-- <a-button type="primary" :icon="h(DeleteOutlined)" @click="batchHandleDelete" v-auth="'housenew:health_house_banner:deleteBatch'">-->
<!-- 批量删除-->
<!-- </a-button>-->
<!-- <a-button type="primary" :icon="h(SearchOutlined)" @click="onlyread"> 查看 </a-button>-->
</template>
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
<add-modal @register="registerModal" @success="handleSuccess" />
</template>
<script lang="ts" setup>
import { h } from 'vue';
import { PlusOutlined, EditOutlined, DeleteOutlined, SearchOutlined } from '@ant-design/icons-vue';
import BasicTable from '/@/components/Table/src/BasicTable.vue';
import { useListPage } from '/@/hooks/system/useListPage';
import { TableAction } from '/@/components/Table';
import { columns, searchFormSchema } from '/@/views/archive/healthCabin/planWork/planWork.data';
import { batchDelete, deleteOne, list } from '/@/views/archive/healthCabin/planWork/planWork.api';
import { useModal } from '/@/components/Modal';
import AddModal from '/@/views/archive/healthCabin/planWork/components/addPlanWorkModal.vue';
import { useMessage } from '/@/hooks/web/useMessage';
const { createConfirm } = useMessage();
import { usePermission } from '/@/hooks/web/usePermission';
const { hasPermission } = usePermission();
const { tableContext } = useListPage({
tableProps: {
api: list,
columns,
canResize: false,
orderFlag: false,
showIndexColumn: true,
formConfig: {
schemas: searchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: false,
fieldMapToNumber: [],
fieldMapToTime: [],
},
beforeFetch: (params) => {
return params;
},
actionColumn: {
width: 150,
fixed: 'right',
},
},
});
const [registerTable, { reload, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
//注册弹窗
const [registerModal, { openModal }] = useModal();
function getTableAction(record: any) {
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
// ifShow: () => hasPermission('housenew:health_house_device_project:edit'),
},
{
label: '详情',
onClick: onlyread.bind(null, record),
// ifShow: () => hasPermission('housenew:health_house_banner:delete'),
},
{
label: '删除',
onClick: handleDelete.bind(null, record),
// ifShow: () => hasPermission('housenew:health_house_device_project:delete'),
},
];
}
/**
* 新增事件
*/
function handleAdd() {
openModal(true, {
record: { sort: getDataSource().length + 1 },
isUpdate: false,
showFooter: true,
type: '新增',
});
}
/**
* 编辑事件
*/
function handleEdit(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
showFooter: true,
type: '编辑',
});
}
/**
* 删除事件
*/
async function handleDelete(record) {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
deleteOne({ id: record.id }, handleSuccess);
},
});
}
/**
* 批量删除事件
*/
// async function batchHandleDelete() {
// if (selectedRowKeys.value.length === 0) return message.info('请至少选择一条');
// await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
// }
/**
* 成功回调
*/
function handleSuccess() {
(selectedRowKeys.value = []) && reload();
}
function onlyread(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
title: '查看',
onlyRead: true,
});
}
</script>
<style lang="less" scoped></style>
@@ -1,59 +0,0 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" width="40%" @ok="handleSubmit">
<BasicForm @register="registerForm" :disabled="onlyRead" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import BasicForm from '/@/components/Form/src/BasicForm.vue';
import { useForm } from '/@/components/Form';
import { schemas } from '/@/views/archive/healthCabin/slideshow/slideshow.data';
import { saveOrUpdate } from '/@/views/archive/healthCabin/slideshow/slideshow.api';
// Emits声明
const emit = defineEmits(['register', 'success']);
const isUpdate = ref(true);
//设置标题
const title = ref(String);
const onlyRead = ref('false');
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
//重置表单
await resetFields();
setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
isUpdate.value = !!data?.isUpdate;
title.value = data.type;
console.log(data, '传进来的值');
//表单赋值
await setFieldsValue({
...data.record,
});
// 隐藏底部时禁用整个表单
setProps({ disabled: !data?.showFooter });
});
const [registerForm, { resetFields, setFieldsValue, validate, setProps }] = useForm({
//labelWidth: 150,
schemas,
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
async function handleSubmit() {
try {
let values = await validate();
console.log(values, '要穿走的值');
setModalProps({ confirmLoading: true });
//提交表单
await saveOrUpdate(values, isUpdate.value);
//关闭弹窗
closeModal();
//刷新列表
emit('success');
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
<style lang="less" scoped></style>
@@ -1,67 +0,0 @@
// noinspection Eslint
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
const { createConfirm } = useMessage();
enum Api {
list = '/health-archives/housenew/healthHouseBannerNew/list',
save = '/health-archives/housenew/healthHouseBannerNew/add',
edit = '/health-archives/housenew/healthHouseBannerNew/edit',
deleteOne = '/health-archives/housenew/healthHouseBannerNew/delete',
deleteBatch = '/health-archives/housenew/healthHouseBannerNew/deleteBatch',
importExcel = '/health-archives/archives/medicalDataAnalysis/importExcel',
exportXls = '/health-archives/archives/medicalDataAnalysis/exportXls',
}
/**
* 导出api
* @param params
*/
export const getExportUrl = Api.exportXls;
/**
* 导入api
*/
export const getImportUrl = Api.importExcel;
/**
* 列表接口
* @param params
*/
export const list = (params) => defHttp.get({ url: Api.list, params });
/**
* 删除单个
*/
export const deleteOne = (params, handleSuccess) => {
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
};
/**
* 批量删除
* @param params
*/
export const batchDelete = (params, handleSuccess) => {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
return defHttp.delete({ url: Api.deleteBatch, data: params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
},
});
};
/**
* 保存或者更新
* @param params
* @param isUpdate
*/
export const saveOrUpdate = (params: any, isUpdate: boolean) => {
const url = isUpdate ? Api.edit : Api.save;
return defHttp.post({ url: url, params });
};
@@ -1,94 +0,0 @@
import { BasicColumn, FormSchema } from '/@/components/Table';
import { getDefaultImage, getFileAccessHttpUrl } from '/@/utils/common/compUtils';
import { h } from 'vue';
import { Image } from 'ant-design-vue';
export const columns: BasicColumn[] = [
{
title: '标题',
align: 'center',
dataIndex: 'bannerTitle',
},
{
title: '编号',
align: 'center',
dataIndex: 'bannerNo',
},
{
title: '轮播图',
align: 'center',
dataIndex: 'bannerUrl',
minWidth: 230,
customRender: ({ text }) => {
return h(Image, {
placeholder: true,
src: getFileAccessHttpUrl(text),
height: 80,
width: 200,
fallback: getDefaultImage(),
});
},
},
{
title: '是否有效',
align: 'center',
dataIndex: 'bannerValid_dictText',
},
{
title: '所属模块',
align: 'center',
dataIndex: 'bannerType_dictText',
},
{
title: '创建时间',
align: 'center',
dataIndex: 'createDate',
},
];
export const schemas: FormSchema[] = [
{
label: '序号',
field: 'bannerNo',
component: 'InputNumber',
rules: [{ required: true }],
},
{
label: '轮播图标题',
field: 'bannerTitle',
component: 'Input',
rules: [{ required: true }],
},
{
label: '是否有效',
field: 'bannerValid',
component: 'JDictSelectTag',
defaultValue: '1',
componentProps: {
type: 'radio',
dictCode: 'yes_no',
},
rules: [{ required: true }],
},
{
label: '类型',
field: 'bannerType',
component: 'JDictSelectTag',
componentProps: {
dictCode: 'house_banner_type',
},
rules: [{ required: true }],
},
{
label: '轮播图',
field: 'bannerUrl',
component: 'JImageUpload',
rules: [{ required: true, message: '请上传图片' }],
},
// TODO 主键隐藏字段,目前写死为ID
{
label: 'id',
field: 'id',
component: 'Input',
show: false,
},
];
@@ -1,132 +0,0 @@
<template>
<BasicTable @register="registerTable" :rowSelection="rowSelection" style="margin: 10px 5px">
<template #tableTitle>
<a-button type="primary" :icon="h(PlusOutlined)" @click="handleAdd" v-auth="'housenew:health_house_banner:add'"> 新增 </a-button>
<!-- <a-button type="primary" :icon="h(EditOutlined)" @click="handleEdit" v-auth="'housenew:health_house_banner:edit'"> 编辑 </a-button>-->
<!-- <a-button type="primary" :icon="h(DeleteOutlined)" @click="batchHandleDelete" v-auth="'housenew:health_house_banner:deleteBatch'">-->
<!-- 批量删除-->
<!-- </a-button>-->
<!-- <a-button type="primary" :icon="h(SearchOutlined)" @click="onlyread"> 详情 </a-button>-->
</template>
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
<add-modal @register="registerModal" @success="handleSuccess" />
</template>
<script lang="ts" setup>
import { h } from 'vue';
import { PlusOutlined } from '@ant-design/icons-vue';
import { useListPage } from '/@/hooks/system/useListPage';
import { BasicTable, TableAction } from '/@/components/Table';
import { list, deleteOne } from '/@/views/archive/healthCabin/slideshow/slideshow.api';
import { columns } from '/@/views/archive/healthCabin/slideshow/slideshow.data';
import { useModal } from '/@/components/Modal';
import AddModal from '/@/views/archive/healthCabin/slideshow/components/addSlideshowModal.vue';
import { useMessage } from '/@/hooks/web/useMessage';
const { createConfirm } = useMessage();
import { usePermission } from '/@/hooks/web/usePermission';
const { hasPermission } = usePermission();
const { tableContext } = useListPage({
tableProps: {
api: list,
columns,
canResize: false,
orderFlag: false,
showIndexColumn: true,
useSearchForm: false,
beforeFetch: (params) => {
return params;
},
actionColumn: {
width: 150,
fixed: 'right',
},
},
});
const [registerTable, { reload, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
//注册弹窗
const [registerModal, { openModal }] = useModal();
function getTableAction(record: any) {
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
ifShow: () => hasPermission('housenew:health_house_banner:edit'),
},
{
label: '详情',
onClick: onlyread.bind(null, record),
// ifShow: () => hasPermission('housenew:health_house_banner:delete'),
},
{
label: '删除',
onClick: handleDelete.bind(null, record),
ifShow: () => hasPermission('housenew:health_house_banner:delete'),
},
];
}
/**
* 新增事件
*/
function handleAdd() {
openModal(true, {
record: { sort: getDataSource().length + 1 },
isUpdate: false,
showFooter: true,
type: '新增',
});
}
/**
* 编辑事件
*/
function handleEdit(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
showFooter: true,
type: '编辑',
});
}
/**
* 删除事件
*/
async function handleDelete(record) {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
deleteOne({ id: record.id }, handleSuccess);
},
});
}
/**
* 批量删除事件
*/
// async function batchHandleDelete() {
// if (selectedRowKeys.value.length === 0) return message.info('请至少选择一条');
// await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
// }
/**
* 成功回调
*/
function handleSuccess() {
(selectedRowKeys.value = []) && reload();
}
function onlyread(record: Recordable) {
openModal(true, {
record,
isUpdate: false,
title: '查看',
onlyRead: true,
});
}
</script>
<style lang="less" scoped></style>
@@ -1,47 +0,0 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" width="40%" @ok="handleSubmit">
<BasicForm @register="registerForm" :disabled="onlyRead" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import BasicForm from '/@/components/Form/src/BasicForm.vue';
import { useForm } from '/@/components/Form';
import { schemas } from '/@/views/archive/healthCabin/terminalManagement/terminalManagement.data';
const title = ref('新增');
const isUpdate = ref();
const onlyRead = ref('false');
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
console.log(data);
await resetFields();
title.value = data.title;
isUpdate.value = data.isUpdate;
onlyRead.value = data.onlyRead;
});
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
//labelWidth: 150,
schemas,
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
async function handleSubmit() {
if (onlyRead.value) {
closeModal();
return;
}
try {
let values = await validate();
setModalProps({ confirmLoading: true });
console.log(values, 1233333);
closeModal();
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
<style lang="less" scoped></style>
@@ -1,67 +0,0 @@
// noinspection Eslint
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
const { createConfirm } = useMessage();
enum Api {
list = '/archives/medicalDataAnalysis/list',
save = '/archives/medicalDataAnalysis/add',
edit = '/archives/medicalDataAnalysis/edit',
deleteOne = '/archives/medicalDataAnalysis/delete',
deleteBatch = '/archives/medicalDataAnalysis/deleteBatch',
importExcel = '/archives/medicalDataAnalysis/importExcel',
exportXls = '/archives/medicalDataAnalysis/exportXls',
}
/**
* 导出api
* @param params
*/
export const getExportUrl = Api.exportXls;
/**
* 导入api
*/
export const getImportUrl = Api.importExcel;
/**
* 列表接口
* @param params
*/
export const list = (params) => defHttp.get({ url: Api.list, params });
/**
* 删除单个
*/
export const deleteOne = (params, handleSuccess) => {
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
};
/**
* 批量删除
* @param params
*/
export const batchDelete = (params, handleSuccess) => {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
return defHttp.delete({ url: Api.deleteBatch, data: params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
},
});
};
/**
* 保存或者更新
* @param params
* @param isUpdate
*/
export const saveOrUpdate = (params: any, isUpdate: boolean) => {
const url = isUpdate ? Api.edit : Api.save;
return defHttp.post({ url: url, params });
};
@@ -1,58 +0,0 @@
import { BasicColumn, FormSchema } from '/@/components/Table';
export const columns: BasicColumn[] = [
{
title: '健康室 ',
align: 'center',
dataIndex: 'pic',
},
{
title: '终端编号 ',
align: 'center',
dataIndex: 'qq',
},
{
title: '终端名称',
align: 'center',
dataIndex: 'name',
},
{
title: '启用',
align: 'center',
dataIndex: 'pic',
},
];
export const searchFormSchema: FormSchema[] = [
{
label: '健康室',
field: 'name1',
component: 'Select',
},
];
export const schemas: FormSchema[] = [
{
label: '健康室',
field: 'name',
component: 'Select',
rules: [{ required: true, trigger: 'blur' }],
},
{
label: '终端编号',
field: 'name',
component: 'Input',
rules: [{ required: true, trigger: 'blur' }],
},
{
label: '终端名称',
field: 'name',
component: 'Input',
rules: [{ required: true, trigger: 'blur' }],
},
{
label: '启用',
field: 'name',
component: 'Select',
rules: [{ required: true, trigger: 'blur' }],
},
];
@@ -1,114 +0,0 @@
<template>
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<template #tableTitle>
<a-button type="primary" :icon="h(PlusOutlined)" @click="handleAdd"> 新增终端 </a-button>
<a-button type="primary" :icon="h(EditOutlined)" @click="handleEdit"> 编辑 </a-button>
</template>
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
<add-modal @register="registerModal" @success="handleSuccess" />
</template>
<script lang="ts" setup>
import { h } from 'vue';
import { PlusOutlined, EditOutlined } from '@ant-design/icons-vue';
import BasicTable from '/@/components/Table/src/BasicTable.vue';
import { useListPage } from '/@/hooks/system/useListPage';
import { TableAction } from '/@/components/Table';
import { columns, searchFormSchema } from '/@/views/archive/healthCabin/terminalManagement/terminalManagement.data';
import { useModal } from '/@/components/Modal';
import AddModal from '/@/views/archive/healthCabin/terminalManagement/components/addTerminalManagementModal.vue';
import { useMessage } from '/@/hooks/web/useMessage';
const { createMessage } = useMessage();
import { deleteOne } from '/@/views/archive/healthCabin/bigDataShow/bigDataShow.api';
import { usePermission } from '/@/hooks/web/usePermission';
const { hasPermission } = usePermission();
const list = [{}];
const { tableContext } = useListPage({
tableProps: {
// api: listApi,
dataSource: list,
columns,
canResize: false,
orderFlag: false,
showIndexColumn: true,
formConfig: {
schemas: searchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: false,
fieldMapToNumber: [],
fieldMapToTime: [],
},
beforeFetch: (params) => {
return params;
},
actionColumn: {
width: 150,
fixed: 'right',
},
},
});
const [registerTable, { reload, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
//注册弹窗
const [registerModal, { openModal }] = useModal();
function getTableAction(record: any) {
return [
{
label: '删除',
onClick: handleDelete.bind(null, record),
ifShow: () => hasPermission('housenew:health_house_banner:delete'),
},
{
label: '终端设备',
onClick: handleDelete.bind(null, record),
},
];
}
/**
* 新增事件
*/
function handleAdd() {
openModal(true, {
record: { sort: getDataSource().length + 1 },
isUpdate: false,
showFooter: true,
type: '新增',
});
}
/**
* 编辑事件
*/
function handleEdit() {
if (!selectedRowKeys.value.length || selectedRowKeys.value.length > 1) {
return createMessage.warning('请选择一条数据!');
}
let id = selectedRowKeys.value[0];
let dataSource = getDataSource();
let record = dataSource.filter((item) => item.id === id)[0];
openModal(true, {
record,
isUpdate: true,
showFooter: true,
title: '编辑',
});
}
/**
* 删除事件
*/
async function handleDelete(record) {
await deleteOne({ id: record.id }, handleSuccess);
}
/**
* 成功回调
*/
function handleSuccess() {
(selectedRowKeys.value = []) && reload();
}
</script>
<style lang="less" scoped></style>
@@ -1,54 +0,0 @@
<template>
<BasicModal @register="registerModal" :title="title" :width="900" @ok="handleOk">
<BasicForm @register="registerForm"></BasicForm>
</BasicModal>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { useForm, BasicForm } from '/@/components/Form';
import { formSchema } from '/@/views/archive/healthClock/clockQuestionnaire/integralRule/integralRule.data';
import { ruleAdd, ruleEdit } from '/@/views/archive/healthClock/clockQuestionnaire/integralRule/integralRule.api';
const title = ref('录入');
const emit = defineEmits(['register', 'success']);
const isUpdate = ref(false);
const ruleId = ref();
const showFooter = ref(true);
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
setModalProps({ confirmLoading: false });
await resetFields();
title.value = data.title;
isUpdate.value = data.isUpdate;
showFooter.value = data.showFooter;
console.log(data.record);
if (data.isUpdate) {
await setFieldsValue(data.record);
ruleId.value = data.record.id;
}
});
const [registerForm, { setProps, resetFields, setFieldsValue, validate, updateSchema }] = useForm({
//labelWidth: 150,
schemas: formSchema,
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
async function handleOk() {
if (!showFooter.value) {
closeModal();
return;
}
try {
const values = await validate();
if (isUpdate.value) {
values.id = ruleId.value;
await ruleEdit(values);
} else {
await ruleAdd(values);
}
closeModal();
emit('success');
} catch (e) {
setModalProps({ confirmLoading: false });
}
}
</script>
@@ -1,32 +0,0 @@
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
const { createConfirm } = useMessage();
export enum Api {
list = '/health-archives/punchnew/healthScoreSettingNew/list',
ruleAdd = '/health-archives/punchnew/healthScoreSettingNew/add',
ruleEdit = '/health-archives//punchnew/healthScoreSettingNew/edit',
ruleDelete = '/health-archives/punchnew/healthScoreSettingNew/delete',
}
// 列表接口
export const listApi = (params) => defHttp.get({ url: Api.list, params });
// 分类新增
export const ruleAdd = (params) => defHttp.post({ url: Api.ruleAdd, params });
// 分类编辑
export const ruleEdit = (params) => defHttp.put({ url: Api.ruleEdit, params });
// 分类删除
export const ruleDelete = (params, handleSuccess) => {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
return defHttp.delete({ url: Api.ruleDelete + `?id=${params.id}`, params }).then(() => {
handleSuccess();
});
},
});
};
@@ -1,72 +0,0 @@
import { BasicColumn, FormSchema } from '/@/components/Table';
export const columns: BasicColumn[] = [
{
title: '积分奖励起始值',
dataIndex: 'scoreStart',
},
{
title: '积分奖励递增值',
dataIndex: 'scoreStep',
},
{
title: '积分奖励最大值',
dataIndex: 'scoreMax',
},
{
title: '规则状态',
dataIndex: 'scoreStatus',
customRender: ({ text }) => {
if (text == 0) return '无效';
if (text == 1) return '有效';
},
},
];
export const formSchema: FormSchema[] = [
{
label: '积分奖励起始值',
field: 'scoreStart',
component: 'Input',
componentProps: () => {
return {
type: 'number',
};
},
required: true,
},
{
label: '积分奖励递增值',
field: 'scoreStep',
component: 'Input',
componentProps: () => {
return {
type: 'number',
};
},
required: true,
},
{
label: '积分奖励最大值',
field: 'scoreMax',
component: 'Input',
componentProps: () => {
return {
type: 'number',
};
},
required: true,
},
{
label: '规则状态',
field: 'scoreStatus',
component: 'RadioGroup',
defaultValue: 1,
componentProps: {
options: [
{ label: '有效', value: 1 },
{ label: '无效', value: 0 },
],
},
required: true,
},
];

Some files were not shown because too many files have changed in this diff Show More