Compare commits

..

159 Commits
uat_us ... main

Author SHA1 Message Date
wangxiaoshuang 7328ea55df 阅片临床数据弹框修改
continuous-integration/drone/push Build is running Details
2025-12-24 11:47:23 +08:00
wangxiaoshuang 5773a93df3 部分问题修复
continuous-integration/drone/push Build is passing Details
2025-12-24 11:18:17 +08:00
wangxiaoshuang e6e9ab03a3 1
continuous-integration/drone/push Build is passing Details
2025-12-24 11:10:08 +08:00
wangxiaoshuang a663f6fa4e 1
continuous-integration/drone/push Build is passing Details
2025-12-24 10:54:57 +08:00
wangxiaoshuang 80fe969fe1 1
continuous-integration/drone/push Build is passing Details
2025-12-24 10:36:32 +08:00
wangxiaoshuang bdbca21550 邮件日志收件人、抄送人显示修改
continuous-integration/drone/push Build is passing Details
2025-12-24 10:17:45 +08:00
wangxiaoshuang 3901ceec45 中心调研模板设备字段修改
continuous-integration/drone/push Build is passing Details
2025-12-24 10:06:09 +08:00
wangxiaoshuang 2f8b88b51f 1
continuous-integration/drone/push Build is passing Details
2025-12-23 17:43:53 +08:00
wangxiaoshuang bed842ec88 1
continuous-integration/drone/push Build is passing Details
2025-12-23 17:28:27 +08:00
wangxiaoshuang 72d9872b20 申请重阅添加保留后续访视数据的选项
continuous-integration/drone/push Build is passing Details
2025-12-23 17:13:15 +08:00
wangxiaoshuang bdca45a505 影像汇总文件下载
continuous-integration/drone/push Build is passing Details
2025-12-23 16:36:22 +08:00
wangxiaoshuang 68fa0edfe5 申请重阅添加保留后续访视数据的选项
continuous-integration/drone/push Build is running Details
2025-12-23 16:19:54 +08:00
wangxiaoshuang 17ad103c34 【邮件日志】邮件日志页面相关问题
continuous-integration/drone/push Build is passing Details
2025-12-23 14:55:12 +08:00
wangxiaoshuang 7bebb8900e 1
continuous-integration/drone/push Build is passing Details
2025-12-22 17:10:52 +08:00
wangxiaoshuang fc72e141bf 1
continuous-integration/drone/push Build is passing Details
2025-12-22 16:29:54 +08:00
wangxiaoshuang 3eb28d2baa dicom预览问题
continuous-integration/drone/push Build is passing Details
2025-12-22 15:52:50 +08:00
wangxiaoshuang 7892b8cf01 发件人在新建项目时需要自动生成
continuous-integration/drone/push Build is passing Details
2025-12-22 14:15:45 +08:00
wangxiaoshuang 9f5fc1dc9d 同步邮件添加参数
continuous-integration/drone/push Build is passing Details
2025-12-18 17:15:46 +08:00
wangxiaoshuang 4b5fee5739 mpr添加十字准星
continuous-integration/drone/push Build is running Details
2025-12-18 17:13:13 +08:00
wangxiaoshuang f5143fe11c PET-CT融合页面,测量值默认显示SUV
continuous-integration/drone/push Build is passing Details
2025-12-18 14:35:20 +08:00
wangxiaoshuang 363ffa58b3 影像质控风险管理
continuous-integration/drone/push Build is passing Details
2025-12-18 13:38:02 +08:00
wangxiaoshuang 4e46bbac84 项目自定义标准-NM DICOM工具可配置测量标注工具,影像标记可以与CRF问题关联
continuous-integration/drone/push Build is passing Details
2025-12-18 11:36:50 +08:00
wangxiaoshuang fb8135d985 【LiLi】中心人员定期管理
continuous-integration/drone/push Build is passing Details
2025-12-18 11:28:54 +08:00
wangxiaoshuang e5233c8894 PET-CT融合页面,测量值和问题没有关联
continuous-integration/drone/push Build is passing Details
2025-12-15 17:13:34 +08:00
wangxiaoshuang 4143eb6279 部分问题修复
continuous-integration/drone/push Build is passing Details
2025-12-15 14:34:42 +08:00
wangxiaoshuang f3d9b31313 病灶融合
continuous-integration/drone/push Build is passing Details
2025-12-12 17:24:39 +08:00
wangxiaoshuang 726f6499f9 项目报表
continuous-integration/drone/push Build is passing Details
2025-12-12 16:58:50 +08:00
wangxiaoshuang aab9c4576c 病灶融合功能
continuous-integration/drone/push Build is passing Details
2025-12-11 16:33:31 +08:00
wangxiaoshuang b661a51ec2 下载进度提示 2025-12-11 16:24:37 +08:00
wangxiaoshuang edb03fef23 隐私政策和用户协议更新日期和生效日期格式修改
continuous-integration/drone/push Build is passing Details
2025-12-11 11:36:54 +08:00
wangxiaoshuang 7ca31d8a5e 自动计算可以配置高亮显示值
continuous-integration/drone/push Build is passing Details
2025-12-11 11:18:59 +08:00
wangxiaoshuang 5ec5eda344 【lugano2014】消失状态可使用的工具调整
continuous-integration/drone/push Build is passing Details
2025-12-08 16:43:25 +08:00
wangxiaoshuang 61a1b1b1c2 【国际化】一致性核查和人员中心管理的上传页面的上传文件文字的国际化需要相互独立
continuous-integration/drone/push Build is passing Details
2025-12-08 16:26:25 +08:00
wangxiaoshuang f93274080a 邮件日志重发记录
continuous-integration/drone/push Build is passing Details
2025-12-08 16:21:53 +08:00
wangxiaoshuang fbb9899b55 系统标准报告高亮显示修改
continuous-integration/drone/push Build is passing Details
2025-12-08 15:39:26 +08:00
wangxiaoshuang f7af9999e4 邮件日志接口添加项目Id 2025-12-08 15:39:03 +08:00
wangxiaoshuang d64bea0d27 1
continuous-integration/drone/push Build is passing Details
2025-12-05 09:12:30 +08:00
wangxiaoshuang 3a7eadb41c mpr图标修改
continuous-integration/drone/push Build is passing Details
2025-12-04 14:57:44 +08:00
wangxiaoshuang 1b25f6538e MPR调窗同步
continuous-integration/drone/push Build is passing Details
2025-12-04 14:43:35 +08:00
wangxiaoshuang dbc84b2f58 1
continuous-integration/drone/push Build is passing Details
2025-12-04 13:43:23 +08:00
wangxiaoshuang 9d601b4a46 工作台时间显示问题
continuous-integration/drone/push Build is running Details
2025-12-04 13:40:44 +08:00
wangxiaoshuang 09e5bcb3b7 mpr查看标记和标记截图问题 2025-12-04 13:40:23 +08:00
wangxiaoshuang ae536a7fc4 mpr阅片
continuous-integration/drone/push Build is passing Details
2025-12-03 16:52:52 +08:00
wangxiaoshuang 1b6f48a5a5 1
continuous-integration/drone/push Build is passing Details
2025-12-03 11:13:02 +08:00
wangxiaoshuang d57c080916 部分问题修复
continuous-integration/drone/push Build is passing Details
2025-12-02 17:52:47 +08:00
wangxiaoshuang c2cb5b1999 部分问题修复
continuous-integration/drone/push Build is passing Details
2025-12-02 17:12:49 +08:00
wangxiaoshuang cc5ac4c2a9 自定义dicom阅片添加mpr
continuous-integration/drone/push Build is passing Details
2025-12-02 16:28:42 +08:00
wangxiaoshuang 653d3c6228 拖拽上传文件夹未读取全部文件修复
continuous-integration/drone/push Build is passing Details
2025-12-02 13:31:29 +08:00
wangxiaoshuang eefb42c3f6 阅片图像修改
continuous-integration/drone/push Build is passing Details
2025-12-02 09:12:53 +08:00
wangxiaoshuang ba6cb87648 阅片融合分组区分颜色
continuous-integration/drone/push Build is passing Details
2025-11-28 16:30:29 +08:00
wangxiaoshuang 17f738aa5d 1
continuous-integration/drone/push Build is passing Details
2025-11-28 14:34:09 +08:00
wangxiaoshuang 7a91ccac80 淋巴结非靶病灶和淋巴结新病灶在状态为消失时且长短径不符合标准的不允许保存
continuous-integration/drone/push Build is passing Details
2025-11-28 10:50:43 +08:00
wangxiaoshuang b57076d41d 阅片问题配置修改
continuous-integration/drone/push Build is passing Details
2025-11-26 16:20:22 +08:00
wangxiaoshuang 633a169467 中心调研编辑注意事项添加默认值
continuous-integration/drone/push Build is passing Details
2025-11-25 14:28:58 +08:00
wangxiaoshuang f2d50e7465 【邮件日志】邮件日志中收件人、抄送人未显示,发送时间错误
continuous-integration/drone/push Build is passing Details
2025-11-25 14:23:15 +08:00
wangxiaoshuang e65e6e2208 淋巴结非靶病灶和淋巴结新病灶在状态为消失时,允许测量
continuous-integration/drone/push Build is passing Details
2025-11-25 14:15:47 +08:00
wangxiaoshuang 196a20cbc0 【培训管理】新建培训文档,未发布直接下线,发布按钮仍可以点击,需要禁用
continuous-integration/drone/push Build is passing Details
2025-11-25 10:36:20 +08:00
wangxiaoshuang f002fed9e2 在查看多帧文件时,序列的图像数字出现了:31/1了。
continuous-integration/drone/push Build is passing Details
2025-11-25 10:30:52 +08:00
wangxiaoshuang 423b71c702 鼠标滚动时,切换图像,图像可以循环的从头到尾
continuous-integration/drone/push Build is passing Details
2025-11-24 17:12:10 +08:00
wangxiaoshuang f79084b599 阅片图表修改
continuous-integration/drone/push Build is passing Details
2025-11-24 15:27:15 +08:00
wangxiaoshuang ca99572f19 工作台的时间格式
continuous-integration/drone/push Build is passing Details
2025-11-24 13:29:59 +08:00
wangxiaoshuang 0d9db63f88 阅片图表显示修改
continuous-integration/drone/push Build is passing Details
2025-11-21 14:55:13 +08:00
wangxiaoshuang 3f9beb6dee 1
continuous-integration/drone/push Build is passing Details
2025-11-20 18:00:01 +08:00
wangxiaoshuang 3243b33b33 阅片报告中数值的统计与可视化
continuous-integration/drone/push Build is passing Details
2025-11-20 15:48:40 +08:00
wangxiaoshuang ca44352b9e 阅片图表展示配置
continuous-integration/drone/push Build is passing Details
2025-11-20 10:49:22 +08:00
wangxiaoshuang e5d86abf92 阅片报告中数值的统计与可视化(未完成)
continuous-integration/drone/push Build is passing Details
2025-11-19 13:13:29 +08:00
wangxiaoshuang 8dedd1068a 阅片关键点添加查看全部
continuous-integration/drone/push Build is passing Details
2025-11-17 13:28:51 +08:00
wangxiaoshuang f58e52585f 阅片人简历采集验证码按钮样式修改
continuous-integration/drone/push Build is passing Details
2025-11-17 13:21:48 +08:00
wangxiaoshuang 1dd153448c 1
continuous-integration/drone/push Build is passing Details
2025-11-17 11:26:39 +08:00
wangxiaoshuang b60b0f8de7 1
continuous-integration/drone/push Build is passing Details
2025-11-17 11:07:10 +08:00
wangxiaoshuang 9de73b9d44 【验证码优化】等待时按钮需要置为灰色
continuous-integration/drone/push Build is passing Details
2025-11-14 17:17:16 +08:00
wangxiaoshuang b55245a83a 项目阅片关键点添加、首次进入阅片弹框提示阅片关键点
continuous-integration/drone/push Build is passing Details
2025-11-14 16:03:32 +08:00
wangxiaoshuang cf1af92c2f 阅片关键点系统添加
continuous-integration/drone/push Build is passing Details
2025-11-14 11:43:12 +08:00
wangxiaoshuang c7740493f8 1
continuous-integration/drone/push Build is passing Details
2025-11-13 15:26:45 +08:00
wangxiaoshuang cca8a0df9d 验证码发送与确认页面优化
continuous-integration/drone/push Build is passing Details
2025-11-12 15:31:00 +08:00
wangxiaoshuang a75f4a38f6 登录进行勾选
continuous-integration/drone/push Build is passing Details
2025-11-11 16:00:01 +08:00
wangxiaoshuang 49b3b056e3 中心调研与中心影像手册的逻辑关系
continuous-integration/drone/push Build is passing Details
2025-11-11 15:56:26 +08:00
wangxiaoshuang 937ab0899e 影像归档时,增加影像信息
continuous-integration/drone/push Build is passing Details
2025-11-10 15:56:20 +08:00
wangxiaoshuang f7d7d2b742 1
continuous-integration/drone/push Build is passing Details
2025-11-10 14:22:26 +08:00
wangxiaoshuang 7c9cde00a9 1
continuous-integration/drone/push Build is passing Details
2025-11-10 13:45:01 +08:00
wangxiaoshuang b56834e8ed 人员核对提醒按钮只需要pm显示
continuous-integration/drone/push Build is passing Details
2025-11-10 11:36:26 +08:00
wangxiaoshuang 29e785243e 阅片页面增加章程和阅片手册的入口
continuous-integration/drone/push Build is passing Details
2025-11-07 14:38:18 +08:00
wangxiaoshuang 7d57f6b5f6 阅片比例尺工具问题修复
continuous-integration/drone/push Build is passing Details
2025-11-07 13:23:18 +08:00
wangxiaoshuang ecb146bd67 1
continuous-integration/drone/push Build is passing Details
2025-11-06 16:10:26 +08:00
wangxiaoshuang 795423182d 邮件日志及状态管理
continuous-integration/drone/push Build is passing Details
2025-11-06 16:07:07 +08:00
wangxiaoshuang 5dd13b58c5 1
continuous-integration/drone/push Build is passing Details
2025-11-06 13:43:11 +08:00
wangxiaoshuang bbd8e8b510 1
continuous-integration/drone/push Build is passing Details
2025-11-06 10:04:14 +08:00
wangxiaoshuang 6c02793d2f 【LiLi】支持影像拖拽上传
continuous-integration/drone/push Build is passing Details
2025-11-05 16:33:03 +08:00
wangxiaoshuang 4f5fb17bb8 已有阅片期修改左侧条件时,右侧查询结果需要清空或刷新
continuous-integration/drone/push Build is passing Details
2025-11-05 14:45:42 +08:00
wangxiaoshuang 5f89d7d10c 影像阅片时,支持双屏、竖屏
continuous-integration/drone/push Build is passing Details
2025-11-05 14:21:23 +08:00
wangxiaoshuang 0002bd0165 去除列表项指定中心
continuous-integration/drone/push Build is passing Details
2025-11-05 13:58:12 +08:00
wangxiaoshuang 5cd5e3c34d 1
continuous-integration/drone/push Build is passing Details
2025-11-05 13:18:12 +08:00
wangxiaoshuang 9c0ca0a831 非dicom阅片配置矩形标记可绑定项修改
continuous-integration/drone/push Build is passing Details
2025-11-04 16:46:07 +08:00
wangxiaoshuang 181eaed3f5 批量设置阅片期
continuous-integration/drone/push Build is passing Details
2025-11-04 16:17:39 +08:00
wangxiaoshuang b88657fda0 1
continuous-integration/drone/push Build is passing Details
2025-11-04 09:14:52 +08:00
wangxiaoshuang d4aa02e0e5 系统标准阅片页面竖屏适配
continuous-integration/drone/push Build is passing Details
2025-11-03 15:59:50 +08:00
wangxiaoshuang d13a5edfda 全屏显示按钮,没有作用
continuous-integration/drone/push Build is passing Details
2025-11-03 14:39:51 +08:00
wangxiaoshuang b6ee9d5f62 【LiLi】工作台的时间格式
continuous-integration/drone/push Build is passing Details
2025-11-03 14:10:05 +08:00
wangxiaoshuang 134f2471a6 【自定义非dicom】增加比例尺后,表格中的数据没有刷新
continuous-integration/drone/push Build is passing Details
2025-10-31 17:12:13 +08:00
wangxiaoshuang 746278681d 1
continuous-integration/drone/push Build is passing Details
2025-10-31 09:16:47 +08:00
wangxiaoshuang 081263d34f 1
continuous-integration/drone/push Build is passing Details
2025-10-30 15:28:48 +08:00
wangxiaoshuang 199fe6aed3 【自定义非dicom】标记已与问题绑定,删除比例尺后,问题中的值应该恢复为px
continuous-integration/drone/push Build is passing Details
2025-10-30 15:04:28 +08:00
wangxiaoshuang 273932f9cc 【自定义dicom】表格数值问题移除标记后保存报错
continuous-integration/drone/push Build is passing Details
2025-10-30 14:32:33 +08:00
wangxiaoshuang 3832312041 标记值不正确
continuous-integration/drone/push Build is passing Details
2025-10-30 14:24:59 +08:00
wangxiaoshuang b6500c62c5 非dicom标记保存修改
continuous-integration/drone/push Build is passing Details
2025-10-30 13:20:21 +08:00
wangxiaoshuang 42839a925d 【阅片单元】数值问题配置测量工具,选项中不应该有箭头问题
continuous-integration/drone/push Build is passing Details
2025-10-30 11:09:44 +08:00
wangxiaoshuang 342f135d23 【自定义非dicom】绑定问题显示的小数取值与标记显示的值有差异
continuous-integration/drone/push Build is passing Details
2025-10-30 10:58:29 +08:00
wangxiaoshuang 7f47936f8a 【自定义dicom】数值问题中多边形工具的测量值,不应该有radius和max,缺少perimeter
continuous-integration/drone/push Build is passing Details
2025-10-30 10:55:09 +08:00
wangxiaoshuang a7b9218952 dicom阅片比例尺修改
continuous-integration/drone/push Build is passing Details
2025-10-30 10:48:54 +08:00
wangxiaoshuang 8590808cb9 1
continuous-integration/drone/push Build is passing Details
2025-10-29 16:20:48 +08:00
wangxiaoshuang 5394a2cde5 非dicom角度工具添加注释
continuous-integration/drone/push Build is passing Details
2025-10-29 16:04:08 +08:00
wangxiaoshuang fe0ba42736 【非dicom】重置crf时,需要清除所有标记,包括标尺
continuous-integration/drone/push Build is passing Details
2025-10-29 14:05:55 +08:00
wangxiaoshuang b6bc22af72 非dicom阅片问题修改
continuous-integration/drone/push Build is passing Details
2025-10-28 17:55:48 +08:00
wangxiaoshuang 9b67760ffd 中心人员定期管理
continuous-integration/drone/push Build is passing Details
2025-10-28 15:35:54 +08:00
wangxiaoshuang aee12347dc 非dicom阅片标记绑定问题
continuous-integration/drone/push Build is passing Details
2025-10-27 15:25:13 +08:00
wangxiaoshuang 7426be2e50 非dicom阅片问题绑定标记
continuous-integration/drone/push Build is passing Details
2025-10-24 17:58:10 +08:00
wangxiaoshuang 5565b1389d 隐私政策样式调整
continuous-integration/drone/push Build is passing Details
2025-10-24 15:53:10 +08:00
wangxiaoshuang 0e029369a3 隐私政策修改
continuous-integration/drone/push Build is passing Details
2025-10-24 11:23:19 +08:00
wangxiaoshuang 5d09bd2159 全量核查文件下载问题修改
continuous-integration/drone/push Build is passing Details
2025-10-24 09:49:16 +08:00
wangxiaoshuang 98757b6c06 1
continuous-integration/drone/push Build is passing Details
2025-10-23 16:28:39 +08:00
wangxiaoshuang c197c077a7 非dicom阅片工具配置修改
continuous-integration/drone/push Build is passing Details
2025-10-23 15:49:59 +08:00
wangxiaoshuang 2ce7fa7552 一致性核查结果,在做全量核查时,对于已经核查过的数据也进行校验
continuous-integration/drone/push Build is passing Details
2025-10-21 17:35:17 +08:00
wangxiaoshuang 5456d7a40b 阅片重置窗宽窗位不重置反色
continuous-integration/drone/push Build is passing Details
2025-10-21 16:46:01 +08:00
wangxiaoshuang 8299fd8958 隐私政策去除删除功能 2025-10-21 16:45:31 +08:00
wangxiaoshuang 06b505544b 1
continuous-integration/drone/push Build is passing Details
2025-10-21 16:09:39 +08:00
wangxiaoshuang 19d472bfb3 用户协议和数据隐私采集说明
continuous-integration/drone/push Build is passing Details
2025-10-21 16:04:23 +08:00
wangxiaoshuang 62f601a7be 接口变更
continuous-integration/drone/push Build is passing Details
2025-10-21 13:36:59 +08:00
wangxiaoshuang 689527b61e 错误字段修改
continuous-integration/drone/push Build is passing Details
2025-10-21 13:26:13 +08:00
wangxiaoshuang 7478472e33 1
continuous-integration/drone/push Build is passing Details
2025-10-21 13:09:58 +08:00
wangxiaoshuang 7f48e37779 1
continuous-integration/drone/push Build is passing Details
2025-10-21 11:48:41 +08:00
wangxiaoshuang 2a27e1fbae 【Lugano2014 无pet】报告页的整体肿瘤评估结果需要可以修改结果,为下拉框
continuous-integration/drone/push Build is passing Details
2025-10-21 11:38:35 +08:00
wangxiaoshuang 02a5e2fdc2 MFA登录状态持久管理和页面优化
continuous-integration/drone/push Build is passing Details
2025-10-20 14:59:58 +08:00
wangxiaoshuang 0f6da34395 1
continuous-integration/drone/push Build is passing Details
2025-10-17 15:14:15 +08:00
wangxiaoshuang 2c567e3530 培训记录受训人查询条件修改
continuous-integration/drone/push Build is passing Details
2025-10-17 13:58:58 +08:00
wangxiaoshuang b7f113c109 【Lugano2014 no pet】阅片报告整体肿瘤评估结果在全局阅片时有修改,鼠标悬浮在结果上时需要显示全局修改的结果
continuous-integration/drone/push Build is passing Details
2025-10-17 10:03:48 +08:00
wangxiaoshuang 7c79e4b1f3 项目信息编辑,申办方和CRO选择后无法清空,增加删除按钮
continuous-integration/drone/push Build is passing Details
2025-10-17 10:00:11 +08:00
wangxiaoshuang 5528188a8b 非dicom阅片问题标记绑定(待完成)
continuous-integration/drone/push Build is passing Details
2025-10-16 18:41:01 +08:00
wangxiaoshuang c0aa89c6ca 调窗开启后,无法进行调窗
continuous-integration/drone/push Build is passing Details
2025-10-16 15:41:24 +08:00
wangxiaoshuang 5bbbdb0a97 Merge branch 'uat'
continuous-integration/drone/push Build is passing Details
2025-10-16 14:55:03 +08:00
wangxiaoshuang cbcc11fe97 非dicom阅片单元配置
continuous-integration/drone/push Build is running Details
2025-10-15 17:10:18 +08:00
wangxiaoshuang 7f20bfecdc 新标准全局阅片修改
continuous-integration/drone/push Build is passing Details
2025-10-15 15:37:46 +08:00
wangxiaoshuang f58c116382 阅片期列表数量选择添加100、500、1000
continuous-integration/drone/push Build is passing Details
2025-10-15 14:47:41 +08:00
wangxiaoshuang b44d832241 1
continuous-integration/drone/push Build is passing Details
2025-10-15 14:32:15 +08:00
wangxiaoshuang bf2a2818ce Merge branch 'uat'
continuous-integration/drone/push Build is passing Details
2025-10-15 09:54:33 +08:00
wangxiaoshuang 58c33bc008 是否预设添加限制下拉框、单选框
continuous-integration/drone/push Build is passing Details
2025-10-14 14:48:17 +08:00
wangxiaoshuang 1e49dedd23 Lugano 2014 without FDG-PET
continuous-integration/drone/push Build is passing Details
2025-10-14 13:33:15 +08:00
wangxiaoshuang 3c661ae86a 1
continuous-integration/drone/push Build is passing Details
2025-10-14 11:13:48 +08:00
wangxiaoshuang 7238b12424 Lugano 2014全局更新类型,配置时数据被清空
continuous-integration/drone/push Build is passing Details
2025-10-13 16:17:48 +08:00
wangxiaoshuang 341a707c80 独立阅片人简历查看修改
continuous-integration/drone/push Build is passing Details
2025-10-13 14:01:46 +08:00
wangxiaoshuang 877535f579 1
continuous-integration/drone/push Build is passing Details
2025-10-13 10:20:09 +08:00
wangxiaoshuang 602f942e9e 附加评估问题修改
continuous-integration/drone/push Build is passing Details
2025-10-13 10:01:22 +08:00
wangxiaoshuang a804ba40f0 阅片单元新增配置是否预设
continuous-integration/drone/push Build is passing Details
2025-10-10 17:26:04 +08:00
wangxiaoshuang 38eef44d79 表单固定列
continuous-integration/drone/push Build is passing Details
2025-10-10 16:47:44 +08:00
wangxiaoshuang ff1b4f6f21 阅片比例尺 2025-10-10 16:47:25 +08:00
wangxiaoshuang ef336eafe6 登录隐私政策 2025-10-10 16:46:50 +08:00
wangxiaoshuang 553014be79 稽查记录的子项,增加属性:指定标准显示
continuous-integration/drone/push Build is passing Details
2025-10-10 15:19:17 +08:00
wangxiaoshuang e7491501cf 阅片人筛选-选择,编辑阅片人简历时,需要可以修改自动生成的临床试验经历
continuous-integration/drone/push Build is passing Details
2025-10-10 15:12:27 +08:00
wangxiaoshuang d64d5a523d 在报告页面增加附件评估结果评估和查看入口
continuous-integration/drone/push Build is passing Details
2025-10-10 11:26:18 +08:00
wangxiaoshuang b2e7eeaeb4 增加受试者中止状态筛选项
continuous-integration/drone/push Build is passing Details
2025-10-10 11:05:29 +08:00
178 changed files with 20950 additions and 12396 deletions

View File

@ -2,11 +2,7 @@
ENV = 'usa' ENV = 'usa'
NODE_ENV = 'usa' NODE_ENV = 'usa'
# base public path # base public path
# VUE_APP_BASE_PATH = 'https://d3taa4kz0xxv95.cloudfront.net/2025-10-31/' VUE_APP_BASE_PATH = 'https://ei-code-prod.s3.amazonaws.com/2024-07-30/'
VUE_APP_BASE_PATH = '/'
# onlyoffice地址
VUE_APP_ONLYOFFICE_URL = "https://onlyoffice.uat.elevateimaging.ai"
# 是否开启登陆限制 true:是 false:否 # 是否开启登陆限制 true:是 false:否
VUE_APP_LOGIN_FOR_PERMISSION = true VUE_APP_LOGIN_FOR_PERMISSION = true

View File

@ -2,7 +2,7 @@
ENV = 'usa' ENV = 'usa'
NODE_ENV = 'usa' NODE_ENV = 'usa'
# base public path # base public path
VUE_APP_BASE_PATH = 'https://ei-med-s3-code.s3.amazonaws.com/2025-01-24/' VUE_APP_BASE_PATH = 'https://ei-med-s3-code.s3.amazonaws.com/2024-07-30/'
# 是否开启登陆限制 true:是 false:否 # 是否开启登陆限制 true:是 false:否
VUE_APP_LOGIN_FOR_PERMISSION = true VUE_APP_LOGIN_FOR_PERMISSION = true

View File

@ -1,44 +0,0 @@
# just a flag
ENV = 'usa'
NODE_ENV = 'usa'
# base public path
VUE_APP_BASE_PATH = 'https://ei-code-prod.s3.amazonaws.com/2024-08-12/'
# 是否开启登陆限制 true:是 false:否
VUE_APP_LOGIN_FOR_PERMISSION = true
# 是否开启长时间无操作锁定弹框MFA验证 true:是 false:否
VUE_APP_LOCK_FOR_PERMISSION_MFA = true
# 是否开启长时间无操作锁定弹框 true:是 false:否
VUE_APP_LOCK_FOR_PERMISSION = true
# 无操作锁定弹框判断时间 单位:秒
VUE_APP_LOCK_FOR_TIME = 900
# 是否开启长时间无操作登出 true:是 false:否
VUE_APP_LOGOUT_FOR_PERMISSION = true
# 无操作锁定弹框判断时间 单位:秒
VUE_APP_LOGOUT_FOR_TIME = 1800
# 是否开启密码正则验证 true:是 false:否
VUE_APP_PASSWORD_FOR_PERMISSION = true
# 是否开启密码正则验证 true:是 false:否
VUE_APP_PASSWORD_FOR_REGULAR = ^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[-_.@^+\$!%#*?&\$~])[A-Za-z0-9-~_.@^+\$~!%#*?&]{8,32}$
# 是否开启文档签署验证 true:是 false:否
VUE_APP_WORD_FOR_PERMISSION = true
# 公司名称
VUE_APP_COMPANY_NAME = "Elevate Imaging"
# dicom文件地址
VUE_APP_DICOM_PATH = 'https://zyypacs-uat.oss-cn-shanghai.aliyuncs.com'
VUE_APP_OSS_CONFIG_REGION = 'oss-cn-shanghai'
VUE_APP_OSS_CONFIG_BUCKET = 'zyypacs-uat'
VUE_APP_OSS_PATH = '/usa/dist'

View File

@ -6,7 +6,6 @@
"build": "vue-cli-service build", "build": "vue-cli-service build",
"build:prod": "vue-cli-service build --mode prod", "build:prod": "vue-cli-service build --mode prod",
"build:uat": "vue-cli-service build --mode uat", "build:uat": "vue-cli-service build --mode uat",
"build:usa_test": "vue-cli-service build --mode usa_test",
"build:usa": "vue-cli-service build --mode usa", "build:usa": "vue-cli-service build --mode usa",
"build:usa_prod": "vue-cli-service build --mode usa_prod", "build:usa_prod": "vue-cli-service build --mode usa_prod",
"pre": "vue-cli-service build --mode pre", "pre": "vue-cli-service build --mode pre",
@ -21,6 +20,7 @@
"@cornerstonejs/core": "^2.19.7", "@cornerstonejs/core": "^2.19.7",
"@cornerstonejs/dicom-image-loader": "^2.19.7", "@cornerstonejs/dicom-image-loader": "^2.19.7",
"@cornerstonejs/tools": "^2.19.7", "@cornerstonejs/tools": "^2.19.7",
"@fingerprintjs/fingerprintjs": "^4.6.2",
"@icr/polyseg-wasm": "^0.4.0", "@icr/polyseg-wasm": "^0.4.0",
"@microsoft/signalr": "^8.0.7", "@microsoft/signalr": "^8.0.7",
"@riophae/vue-treeselect": "^0.4.0", "@riophae/vue-treeselect": "^0.4.0",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

BIN
public/screen.pdf Normal file

Binary file not shown.

View File

@ -350,3 +350,43 @@ export function getUserJoinedTrialList(data) {
data data
}) })
} }
// 邮件日志-日志列表
export function getEmailLogList(data) {
return request({
url: `/EmailLog/getEmailLogList`,
method: 'post',
data
})
}
// 邮件日志-日志详情
export function getEmailInfo(data) {
return request({
url: `/EmailLog/getEmailInfo`,
method: 'post',
data
})
}
// 邮件日志-重发邮件
export function resendEmail(data) {
return request({
url: `/EmailLog/resendEmail`,
method: 'post',
data
})
}
// 邮件日志-同步邮件
export function synchronizationEmail(data) {
return request({
url: `/EmailLog/synchronizationEmail`,
method: 'post',
data
})
}
// 邮件日志-重发列表
export function getReSendEmail(data) {
return request({
url: `/EmailLog/getReSendEmail`,
method: 'post',
data
})
}

View File

@ -1403,3 +1403,74 @@ export function batchUpdateEmail(data) {
data data
}) })
} }
// 隐私政策和用户协议-获取列表
export function getUserAgreementList(data) {
return request({
url: `/UserAgreement/getUserAgreementList`,
method: 'post',
data
})
}
// 隐私政策和用户协议-设置当前版本
export function setCurrentVersion(data) {
return request({
url: `/UserAgreement/setCurrentVersion`,
method: 'post',
data
})
}
// 隐私政策和用户协议-新增或修改
export function addOrUpdateUserAgreement(data) {
return request({
url: `/UserAgreement/addOrUpdateUserAgreement`,
method: 'post',
data
})
}
// 隐私政策和用户协议-删除
export function deleteUserAgreement(id) {
return request({
url: `/UserAgreement/deleteUserAgreement/${id}`,
method: 'delete',
})
}
// 隐私政策和用户协议-详情
export function getUserAgreementById(data) {
return request({
url: `/UserAgreement/getUserAgreementById`,
method: 'post',
data
})
}
// 隐私政策和用户协议-当前版本
export function getCurrentVersionUserAgreements(data) {
return request({
url: `/UserAgreement/getCurrentVersionUserAgreements`,
method: 'post',
data
})
}
// 获取系统阅片关键点文件列表
export function getSystemCriterionKeyFileList(data) {
return request({
url: `/SystemCriterionKeyFile/getSystemCriterionKeyFileList`,
method: 'post',
data
})
}
// 新增/修改系统阅片关键点文件
export function addOrUpdateSystemCriterionKeyFile(data) {
return request({
url: `/SystemCriterionKeyFile/addOrUpdateSystemCriterionKeyFile`,
method: 'post',
data
})
}
// 删除系统阅片关键点文件
export function deleteSystemCriterionKeyFile(systemCriterionKeyFileId) {
return request({
url: `/SystemCriterionKeyFile/deleteSystemCriterionKeyFile/${systemCriterionKeyFileId}`,
method: 'delete'
})
}

View File

@ -255,6 +255,14 @@ export function getCommonJudgeRatioList_Export(data) {
data data
}) })
} }
export function getTumor_CDISC_Export(data) {
return requestDownload({
url: `/Tumor_CDISC_Export/getTumor_CDISC_Export`,
responseType: 'blob',
method: 'post',
data
})
}
// 导出国际化列表 // 导出国际化列表
export function GetInternationalizationList_Export(data) { export function GetInternationalizationList_Export(data) {
return requestDownload({ return requestDownload({

View File

@ -294,3 +294,28 @@ export function readingImport(param) {
data: param data: param
}) })
} }
// 非dicom阅片保存标记
export function saveAnswerAndBindingNoneDicomMark(param) {
return request({
url: `/ReadingImageTask/saveAnswerAndBindingNoneDicomMark`,
method: 'post',
data: param
})
}
// 非dicom按比例修改答案
export function changePlottingScaleChangeAnswer(param) {
return request({
url: `/ReadingImageTask/changePlottingScaleChangeAnswer`,
method: 'post',
data: param
})
}
// 阅片获取图表数据
export function getReportsChartData(param) {
return request({
url: `/ReadingImageTask/getReportsChartData`,
method: 'post',
data: param
})
}

View File

@ -26,8 +26,11 @@ export function getTrialSurveyInitInfo(trialId) {
export function getSiteSurveyInfo(trialId, id) { export function getSiteSurveyInfo(trialId, id) {
return request({ return request({
url: `/TrialSiteSurvey/getSiteSurveyInfo/${trialId}/${id}`, url: `/TrialSiteSurvey/getSiteSurveyInfo/${trialId}`,
method: 'get' method: 'get',
params: {
TrialsiteSurveyId: id
}
}) })
} }

View File

@ -1203,7 +1203,13 @@ export function getConsistencyVerificationList(param) {
data: param data: param
}) })
} }
export function getConsistencyCheckFileList(param) {
return request({
url: `/QCList/getConsistencyCheckFileList`,
method: 'post',
data: param
})
}
export function getCheckChallengeDialogList(subjectVisitId) { export function getCheckChallengeDialogList(subjectVisitId) {
return request({ return request({
url: `/QCList/getCheckChallengeDialogList/${subjectVisitId}`, url: `/QCList/getCheckChallengeDialogList/${subjectVisitId}`,
@ -1256,11 +1262,11 @@ export function getCRCVisitChallengeAndDialog(subjectVisitId, trialQCProcess) {
}) })
} }
export function uploadVisitCheckExcel(trialId, file) { export function uploadVisitCheckExcel(trialId, file, isFullCheck = false) {
const formData = new FormData() const formData = new FormData()
formData.append('file', file) formData.append('file', file)
return request({ return request({
url: `/QCOperation/UploadVisitCheckExcel/${trialId}`, url: `/QCOperation/UploadVisitCheckExcel/${trialId}?isFullCheck=${isFullCheck}`,
method: 'post', method: 'post',
data: formData data: formData
}) })
@ -2833,7 +2839,13 @@ export function getSplitPPdSum(param) {
data: param data: param
}) })
} }
export function getSplitPPdSumNoPet(param) {
return request({
url: `/LuganoWithoutPETCalculate/getSplitPPdSum`,
method: 'post',
data: param
})
}
export function submitDicomVisitTask(param) { export function submitDicomVisitTask(param) {
return request({ return request({
url: `/Inspection/ReadingImageTask/SubmitDicomVisitTask`, url: `/Inspection/ReadingImageTask/SubmitDicomVisitTask`,
@ -2872,7 +2884,13 @@ export function getIsSuvMaxLesion(param) {
data: param data: param
}) })
} }
export function getIsSuvMaxLesionNoPet(param) {
return request({
url: `/LuganoWithoutPETCalculate/getIsSuvMaxLesion`,
method: 'post',
data: param
})
}
export function getCanChooseNotMerge(param) { export function getCanChooseNotMerge(param) {
return request({ return request({
url: `/LuganoCalculate/getCanChooseNotMerge`, url: `/LuganoCalculate/getCanChooseNotMerge`,
@ -2880,6 +2898,13 @@ export function getCanChooseNotMerge(param) {
data: param data: param
}) })
} }
export function getCanChooseNotMergeNoPet(param) {
return request({
url: `/LuganoWithoutPETCalculate/getCanChooseNotMerge`,
method: 'post',
data: param
})
}
export function saveTaskQuestion(saveQuestionType, param) { export function saveTaskQuestion(saveQuestionType, param) {
return request({ return request({
url: `/SaveTaskQuestion/${saveQuestionType}`, url: `/SaveTaskQuestion/${saveQuestionType}`,
@ -3603,13 +3628,24 @@ export function getSplenicState(visitTaskId, spleenLength) {
method: 'post' method: 'post'
}) })
} }
export function getSplenicStateNoPet(visitTaskId, spleenLength) {
return request({
url: `/LuganoWithoutPETCalculate/getSplenicState?visitTaskId=${visitTaskId}&spleenLength=${spleenLength}`,
method: 'post'
})
}
export function getSplenicVerify(visitTaskId) { export function getSplenicVerify(visitTaskId) {
return request({ return request({
url: `/LuganoCalculate/getSplenicVerify?visitTaskId=${visitTaskId}`, url: `/LuganoCalculate/getSplenicVerify?visitTaskId=${visitTaskId}`,
method: 'post' method: 'post'
}) })
} }
export function getSplenicVerifyNoPet(visitTaskId) {
return request({
url: `/LuganoWithoutPETCalculate/getSplenicVerify?visitTaskId=${visitTaskId}`,
method: 'post'
})
}
export function uploadTrialSiteSurveyUser(trialId, baseUrl, routeUrl, param) { export function uploadTrialSiteSurveyUser(trialId, baseUrl, routeUrl, param) {
return request({ return request({
url: `/TrialSiteSurvey/UploadTrialSiteSurveyUser?trialId=${trialId}&baseUrl=${baseUrl}&routeUrl=${routeUrl}`, url: `/TrialSiteSurvey/UploadTrialSiteSurveyUser?trialId=${trialId}&baseUrl=${baseUrl}&routeUrl=${routeUrl}`,
@ -4281,4 +4317,93 @@ export function deleteAuditRecord(auditRecordId) {
url: `/AuditDocument/deleteAuditRecord/${auditRecordId}`, url: `/AuditDocument/deleteAuditRecord/${auditRecordId}`,
method: 'delete' method: 'delete'
}) })
}
// 核对中心人员发送邮件
export function sendCheckSiteSurveyUserEmail(data) {
return request({
url: `/TrialSiteSurvey/sendCheckSiteSurveyUserEmail`,
method: 'post',
data
})
}
// 更新中心人员发送邮件
export function sendUpdateSiteSurveyUserEmail(data) {
return request({
url: `/TrialSiteSurvey/sendUpdateSiteSurveyUserEmail`,
method: 'post',
data
})
}
// 更新中心人员发送邮件
export function getTrialSiteLatestSurvey(params) {
return request({
url: `/TrialSiteSurvey/getTrialSiteLatestSurvey`,
method: 'get',
params
})
}
// 阅片期计划列表
export function getReadModulePageList(data) {
return request({
url: `/ReadModule/getReadModulePageList`,
method: 'post',
data
})
}
// 移除阅片期
export function setBatchRemoveReadingPlan(data) {
return request({
url: `/ReadingPeriodSet/setBatchRemoveReadingPlan`,
method: 'post',
data
})
}
// 更新项目额外json配置
export function updateTrialExtralConfig(params, data) {
return request({
url: `/TrialConfig/updateTrialExtralConfig`,
method: 'put',
params,
data
})
}
// 获取项目标准阅片关键点列表
export function getTrialCriterionKeyFileList(data) {
return request({
url: `/TrialCriterionKeyFile/getTrialCriterionKeyFileList`,
method: 'post',
data
})
}
// 设置已阅读关键文件
export function setReadKeyFile(data) {
return request({
url: `/ReadingImageTask/setReadKeyFile`,
method: 'post',
data
})
}
// 项目报表-访视完成度
export function getTrialVisitFinishedStatList(data) {
return request({
url: `/TrialStat/getTrialVisitFinishedStatList`,
method: 'post',
data
})
}
// 项目报表-质疑统计表
export function getTrialQuestionStatList(data) {
return request({
url: `/TrialStat/getTrialQuestionStatList`,
method: 'post',
data
})
}
// 项目报表-疗效统计表
export function getTrialEfficacyEvaluationStatList(data) {
return request({
url: `/TrialStat/getTrialEfficacyEvaluationStatList`,
method: 'post',
data
})
} }

37
src/components/AGR/fun.js Normal file
View File

@ -0,0 +1,37 @@
import Vue from "vue";
import AGRCOMP from "./index.vue";
const MFAConstructor = Vue.extend(AGRCOMP);
let MFAINSTANCELIST = [];
const AGR = options => {
const { Id, IsEn_Us, callBack, cancelBack } = options;
if (!Id) throw `Id is requred.but ${Id}`
const id = `AGR${new Date().getTime()}`;
const instance = new MFAConstructor();
MFAINSTANCELIST.push(instance)
instance.id = id;
instance.vm = instance.$mount();
if (instance.vm.visible) return;
document.body.appendChild(instance.vm.$el);
instance.vm.open({ Id, IsEn_Us });
instance.vm.$on("success", (Id) => {
if (callBack) callBack(Id)
});
instance.vm.$on("closed", () => {
if (cancelBack) cancelBack();
document.body.removeChild(instance.vm.$el);
instance.vm.$destroy();
let index = MFAINSTANCELIST.findIndex(item => item.id === id);
MFAINSTANCELIST.splice(index, 1)
});
return instance.vm;
}
AGR.close = () => {
if (MFAINSTANCELIST.length <= 0) return;
MFAINSTANCELIST.forEach(item => {
document.body.removeChild(item.vm.$el);
item.vm.$destroy();
})
MFAINSTANCELIST = [];
}
export default AGR;

View File

@ -0,0 +1,7 @@
import AGRCOMP from "./index.vue";
import AGR from "./fun";
export default Vue => {
Vue.component(AGRCOMP.name, AGRCOMP);
Vue.prototype.$AGR = AGR;
};

View File

@ -0,0 +1,65 @@
<template>
<!--AGR-->
<el-dialog v-if="visible" :visible.sync="visible" width="60%" :close-on-click-modal="false" append-to-body center
:show-close="true" @close="cancel">
<!-- <div slot="title">
{{ agreement.FileName }}
</div> -->
<div v-html="agreement.FileEnContent" class="content" v-if="IsEn_Us"></div>
<div v-html="agreement.FileContent" class="content" v-else></div>
</el-dialog>
</template>
<script>
import {
getUserAgreementById
} from '@/api/dictionary'
export default {
name: "AGR",
data() {
return {
visible: false,
agreement: {},
IsEn_Us: false
}
},
mounted() {
},
methods: {
async getAgreement(Id) {
try {
let data = {
Id
}
let res = await getUserAgreementById(data)
if (res.IsSuccess) {
this.agreement = res.Result
}
} catch (err) {
console.log(err)
}
},
open(data) {
let { Id, IsEn_Us } = data;
this.IsEn_Us = IsEn_Us
this.getAgreement(Id)
this.visible = true
},
cancel() {
this.visible = false;
this.$emit("closed");
},
},
};
</script>
<style lang="scss" scoped>
::v-deep .el-dialog__body {
height: 500px;
}
.content {
height: 100%;
overflow-y: auto;
}
</style>

View File

@ -1,25 +1,11 @@
<template> <template>
<!--MFA--> <!--MFA-->
<el-dialog <el-dialog v-if="visible" :visible.sync="visible" width="540px" :close-on-click-modal="false" append-to-body center
v-if="visible" :show-close="status === 'login'" @close="cancel">
:visible.sync="visible"
width="540px"
:close-on-click-modal="false"
append-to-body
center
:show-close="status === 'login'"
@close="cancel"
>
<div slot="title"> <div slot="title">
{{ status === "login" ? $t("mfa:title") : $t("mfa:lock:title") }} {{ status === "login" ? $t("mfa:title") : $t("mfa:lock:title") }}
</div> </div>
<el-form <el-form ref="mfaForm" label-position="right" :model="form" :rules="rules" label-width="100px">
ref="mfaForm"
label-position="right"
:model="form"
:rules="rules"
label-width="100px"
>
<!-- 邮箱 --> <!-- 邮箱 -->
<p class="tip_mfa"> <p class="tip_mfa">
<i class="el-icon-warning" style="color: #409eff"></i> <i class="el-icon-warning" style="color: #409eff"></i>
@ -31,18 +17,13 @@
</el-form-item> </el-form-item>
<!-- 验证码 --> <!-- 验证码 -->
<el-form-item :label="$t('mfa:form:MFACode')" prop="Code"> <el-form-item :label="$t('mfa:form:MFACode')" prop="Code">
<el-input <div style="display: flex;justify-content: space-between;width: 90%;">
:placeholder="$t('mfa:form:input:placeholder:Codes')" <el-input :placeholder="$t('mfa:form:input:placeholder:Codes')" v-model="form.Code" />
v-model="form.Code" <el-button size="small" @click.stop="sendMFACode" :disabled="flag || sendFlag" style="margin-left: 10px;"
style="width: 240px; margin-right: 10px" class="codeBtn">{{
/> flag ?
<el-button `${$t("mfa:form:sendMFACodeCountDown")} (${second}s)` : $t("mfa:form:sendMFACode") }}</el-button>
type="primary" </div>
size="small"
@click.stop="sendMFACode"
:disabled="flag || sendFlag"
>{{ flag ? `${second}s` : $t("mfa:form:sendMFACode") }}</el-button
>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div slot="footer"> <div slot="footer">
@ -51,19 +32,16 @@
{{ $t("mfa:button:cancel") }} {{ $t("mfa:button:cancel") }}
</el-button> --> </el-button> -->
<!-- 保存 --> <!-- 保存 -->
<el-button <el-button type="primary" size="small" @click="save" :loading="loading" style="width: 80%">
type="primary"
size="small"
@click="save"
:loading="loading"
style="width: 80%"
>
{{ {{
status === "login" status === "login"
? $t("mfa:button:save") ? $t("mfa:button:save")
: $t("mfa:lock:button:save") : $t("mfa:lock:button:save")
}} }}
</el-button> </el-button>
<p style="text-align: left;font-size: 14px;margin:10px auto;width: 80%;">
<el-checkbox v-model="form.isRemember" /><span style="margin-left: 10px;">{{ $t("mfa:tip:noLogin") }}</span>
</p>
</div> </div>
</el-dialog> </el-dialog>
</template> </template>
@ -86,6 +64,7 @@ export default {
IdentityUserId: null, IdentityUserId: null,
EMail: null, EMail: null,
username: null, username: null,
isRemember: true
}, },
rules: { rules: {
Code: [ Code: [
@ -112,6 +91,18 @@ export default {
}, },
}; };
}, },
mounted() {
this.flag = true;
this.second = 60;
this.timer = setInterval(() => {
this.second--;
if (this.second <= 0) {
this.flag = false;
clearInterval(this.timer);
this.timer = null;
}
}, 1000);
},
methods: { methods: {
open(data) { open(data) {
let { UserId, status, username, EMail } = data; let { UserId, status, username, EMail } = data;
@ -189,6 +180,21 @@ export default {
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.codeBtn {
color: #409EFF;
border-color: #409EFF;
}
.codeBtn.is-disabled,
.codeBtn.is-disabled:focus,
.codeBtn.is-disabled:hover {
color: #c0c4cc;
cursor: not-allowed;
background-image: none;
background-color: #fff;
border-color: #ebeef5;
}
.tip_mfa { .tip_mfa {
width: 86%; width: 86%;
margin: auto; margin: auto;
@ -198,10 +204,12 @@ export default {
line-height: 30px; line-height: 30px;
border-radius: 5px; border-radius: 5px;
background-color: #eee; background-color: #eee;
i { i {
margin-right: 5px; margin-right: 5px;
} }
} }
::v-deep .el-dialog__header { ::v-deep .el-dialog__header {
font-weight: bold; font-weight: bold;
} }

View File

@ -4,7 +4,7 @@ import Preview from "./index.vue";
const PreviewConstructor = Vue.extend(Preview); const PreviewConstructor = Vue.extend(Preview);
const preview = options => { const preview = options => {
const { path, type, title } = options; const { path, type, title, isLocal = false } = options;
if (!path) throw `path is requred.but ${path}` if (!path) throw `path is requred.but ${path}`
const id = `Preview_${new Date().getTime()}`; const id = `Preview_${new Date().getTime()}`;
const instance = new PreviewConstructor(); const instance = new PreviewConstructor();
@ -12,7 +12,7 @@ const preview = options => {
instance.vm = instance.$mount(); instance.vm = instance.$mount();
if (instance.vm.visible) return; if (instance.vm.visible) return;
document.body.appendChild(instance.vm.$el); document.body.appendChild(instance.vm.$el);
instance.vm.open(path, type, title); instance.vm.open(path, type, title, isLocal);
instance.vm.$on("closed", () => { instance.vm.$on("closed", () => {
document.body.removeChild(instance.vm.$el); document.body.removeChild(instance.vm.$el);
instance.vm.$destroy(); instance.vm.$destroy();

View File

@ -1,15 +1,8 @@
<template> <template>
<el-dialog <el-dialog v-if="visible" :visible.sync="visible" :title="title" :fullscreen="true" append-to-body
v-if="visible" custom-class="base-dialog-wrapper" @close="handleClose">
:visible.sync="visible"
:title="title"
:fullscreen="true"
append-to-body
custom-class="base-dialog-wrapper"
@close="handleClose"
>
<div class="base-modal-body" style="border: 2px solid #ccc; padding: 10px"> <div class="base-modal-body" style="border: 2px solid #ccc; padding: 10px">
<PreviewFile v-if="visible" :file-path="path" :file-type="type" /> <PreviewFile v-if="visible" :file-path="path" :file-type="type" :is-local="isLocal" />
</div> </div>
</el-dialog> </el-dialog>
</template> </template>
@ -24,13 +17,15 @@ export default {
path: null, path: null,
type: null, type: null,
title: null, title: null,
isLocal: false
}; };
}, },
methods: { methods: {
open(path, type, title) { open(path, type, title, isLocal) {
this.path = path; this.path = path;
this.type = type; this.type = type;
this.title = title; this.title = title;
this.isLocal = isLocal;
this.visible = true; this.visible = true;
}, },
handleClose() { handleClose() {

View File

@ -5,16 +5,17 @@
<!-- <embed v-else-if="fileType.indexOf('pdf') !== -1" :src="filePath+'#toolbar=0'" style="width: 100%; height: 100%"> --> <!-- <embed v-else-if="fileType.indexOf('pdf') !== -1" :src="filePath+'#toolbar=0'" style="width: 100%; height: 100%"> -->
<!-- <iframe v-else-if="fileType.indexOf('pdf') !== -1" :src="filePath+'#toolbar=0'" width="100%" height="100%" frameborder="0" /> --> <!-- <iframe v-else-if="fileType.indexOf('pdf') !== -1" :src="filePath+'#toolbar=0'" width="100%" height="100%" frameborder="0" /> -->
<iframe v-else-if="fileType.indexOf('pdf') !== -1" <iframe v-else-if="fileType.indexOf('pdf') !== -1"
:src="`/static/pdfjs/web/viewer.html?file=${OSSclientConfig.basePath}${filePath}?userName=${currentUser}&COMPANY=${COMPANY}`" :src="`/static/pdfjs/web/viewer.html?file=${isLocal ? window.location.origin : OSSclientConfig.basePath}${filePath}?userName=${currentUser}&COMPANY=${COMPANY}`"
width="100%" height="100%" frameborder="0" crossorigin="anonymous" /> width="100%" height="100%" frameborder="0" crossorigin="anonymous" />
<!-- <pdf--> <!-- <pdf-->
<!-- v-else-if="fileType.indexOf('pdf') !== -1"--> <!-- v-else-if="fileType.indexOf('pdf') !== -1"-->
<!-- :src="`/static/pdfjs/web/viewer.html?file=${filePath}`">--> <!-- :src="`/static/pdfjs/web/viewer.html?file=${filePath}`">-->
<!-- </pdf>--> <!-- </pdf>-->
<video :src="`${OSSclientConfig.basePath}${filePath}`" style="width: 100%;height: 99%;" autoplay controls <video :src="`${isLocal ? window.location.origin : OSSclientConfig.basePath}${filePath}`"
controlsList="nodownload" v-else-if="fileType.indexOf('mp4') !== -1"></video> style="width: 100%;height: 99%;" autoplay controls controlsList="nodownload"
v-else-if="fileType.indexOf('mp4') !== -1"></video>
<iframe v-else <iframe v-else
:src="`/static/onlyOffice/viewer.html?url=${OSSclientConfig.basePath}${filePath}?onlyOffice_url=${onlyOffice_url}&type=${fileType}&title=${title}&documentType=${documentType}&userName=${currentUser}`" :src="`/static/onlyOffice/viewer.html?url=${isLocal ? window.location.origin : OSSclientConfig.basePath}${filePath}?onlyOffice_url=${onlyOffice_url}&type=${fileType}&title=${title}&documentType=${documentType}&userName=${currentUser}`"
width="100%" height="100%" frameborder="0" crossorigin="anonymous" /> width="100%" height="100%" frameborder="0" crossorigin="anonymous" />
<!-- <div v-else> <!-- <div v-else>
{{ $t('common:message:downloadFile') }} {{ $t('common:message:downloadFile') }}
@ -43,12 +44,17 @@ export default {
type: String, type: String,
default: '' default: ''
}, },
isLocal: {
type: Boolean,
default: false
}
}, },
data() { data() {
return { return {
currentUser: zzSessionStorage.getItem('userName'), currentUser: zzSessionStorage.getItem('userName'),
COMPANY: process.env.VUE_APP_COMPANY_NAME, COMPANY: process.env.VUE_APP_COMPANY_NAME,
onlyOffice_url: process.env.VUE_APP_ONLYOFFICE_URL onlyOffice_url: process.env.VUE_APP_ONLYOFFICE_URL,
window,
} }
}, },
computed: { computed: {

View File

@ -22,7 +22,7 @@ export default {
}, },
methods: { methods: {
click() { click() {
if (!screenfull.enabled) { if (!screenfull.isEnabled) {
this.$message({ this.$message({
message: 'you browser can not work', message: 'you browser can not work',
type: 'warning' type: 'warning'
@ -35,12 +35,12 @@ export default {
this.isFullscreen = screenfull.isFullscreen this.isFullscreen = screenfull.isFullscreen
}, },
init() { init() {
if (screenfull.enabled) { if (screenfull.isEnabled) {
screenfull.on('change', this.change) screenfull.on('change', this.change)
} }
}, },
destroy() { destroy() {
if (screenfull.enabled) { if (screenfull.isEnabled) {
screenfull.off('change', this.change) screenfull.off('change', this.change)
} }
} }

View File

@ -0,0 +1,240 @@
<template>
<div :id="key" class="readingChart" v-show="visible" :style="{
'z-index': zIndex
}">
<div ref="chartContainer" style="width: 490px; height: 290px;" v-loading="loading"></div>
</div>
</template>
<script>
import { getReportsChartData } from "@/api/reading"
import moment from "moment"
let echarts = require('echarts/lib/echarts');
//
// require('echarts/lib/chart/bar');
require('echarts/lib/chart/line');
// require('echarts/lib/chart/pie');
// require('echarts/lib/chart/scatter');
//
require('echarts/lib/component/tooltip');
require('echarts/lib/component/title');
require('echarts/lib/component/legend');
require('echarts/lib/component/grid');
require('echarts/lib/component/dataZoom');
export default {
name: "readingChart",
props: {
},
data() {
return {
visible: false,
zIndex: 9,
chart: null,
loading: false,
key: 'readingChart'
};
},
methods: {
init(event, obj, zIndex = 9) {
this.loading = true
this.zIndex = zIndex
let { key } = obj
if (key) {
this.key = key
}
this.$nextTick(() => {
this.visible = true
let readingChart = document.querySelector(`#${this.key}`);
let chaY = document.body.clientHeight - event.clientY;
let chaX = document.body.clientWidth - event.clientX;
if (chaY < 250) {
readingChart.style.top = event.clientY - 220 + "px";
} else {
readingChart.style.top = event.clientY + "px";
}
if (chaX < 500) {
readingChart.style.left = event.clientX - 520 + "px";
} else {
readingChart.style.left = event.clientX + 15 + "px";
}
this.getInfo(obj)
})
},
async getInfo(data) {
try {
let { VisitTaskId = null, TrialId = null, QuestionId = null, QuestionName = null, TableQuestionId = null, RowIndex = null, ReportChartTypeEnum = null } = data
let params = {
VisitTaskId, TrialId, QuestionId, TableQuestionId, RowIndex, ReportChartTypeEnum
}
this.loading = true
let res = await getReportsChartData(params)
this.loading = false
if (res.IsSuccess) {
let LatestScanDateList = res.Result.LatestScanDateList.map(item => item.split(" ")[0])
let obj = {
title: QuestionName,
xAxisData: LatestScanDateList || [],
series: [],
unit: this.$fd("ValueUnit", res.Result.Unit),
visitName: res.Result.VisitTaskNameList,
min: null,
max: null
}
res.Result.ChartDataList.forEach((item) => {
let arr = []
item.Value.forEach((d, index) => {
// arr.push([LatestScanDateList[index], d])
arr.push(d)
})
obj.series.push({
name: item.Name,
data: arr,
type: 'line'
})
});
// if (Array.isArray(res.Result.LatestScanDateList) && res.Result.LatestScanDateList.length >= 2) {
// let hours = moment(res.Result.LatestScanDateList[res.Result.LatestScanDateList.length - 1]).diff(moment(res.Result.LatestScanDateList[0]), 'hours');
// let days = moment(res.Result.LatestScanDateList[res.Result.LatestScanDateList.length - 1]).diff(moment(res.Result.LatestScanDateList[0]), 'days');
// let months = moment(res.Result.LatestScanDateList[res.Result.LatestScanDateList.length - 1]).diff(moment(res.Result.LatestScanDateList[0]), 'months');
// console.log(hours, 'hours')
// console.log(days, 'days')
// console.log(months, 'months')
// if (hours < 24) {
// obj.min = moment(res.Result.LatestScanDateList[0]).format('YYYY-MM-DD') + ' 00:00:00'
// obj.max = moment(res.Result.LatestScanDateList[0]).format('YYYY-MM-DD') + ' 23:59:59'
// }
// if (days >= 1 && days <= 7) {
// obj.min = moment(res.Result.LatestScanDateList[0]).format('YYYY-MM-DD') + ' 00:00:00'
// obj.max = moment(res.Result.LatestScanDateList[0]).add(7, 'days').format('YYYY-MM-DD') + ' 23:59:59'
// }
// if (days > 7 && days < 30) {
// obj.min = moment(res.Result.LatestScanDateList[0]).startOf('month').format('YYYY-MM-DD') + ' 00:00:00'
// obj.max = moment(res.Result.LatestScanDateList[0]).endOf('month').format('YYYY-MM-DD') + ' 23:59:59'
// }
// if (months >= 1 && months <= 3) {
// obj.min = moment(res.Result.LatestScanDateList[0]).startOf('month').format('YYYY-MM-DD') + ' 00:00:00'
// obj.max = moment(res.Result.LatestScanDateList[0]).add(4, 'months').startOf('month').format('YYYY-MM-DD') + ' 23:59:59'
// }
// if (months > 3 && months <= 6) {
// obj.min = moment(res.Result.LatestScanDateList[0]).startOf('month').format('YYYY-MM-DD') + ' 00:00:00'
// obj.max = moment(res.Result.LatestScanDateList[0]).add(7, 'months').startOf('month').format('YYYY-MM-DD') + ' 23:59:59'
// }
// if (months > 6 && months <= 12) {
// obj.min = moment(res.Result.LatestScanDateList[0]).startOf('month').format('YYYY-MM-DD') + ' 00:00:00'
// obj.max = moment(res.Result.LatestScanDateList[0]).add(13, 'months').startOf('month').format('YYYY-MM-DD') + ' 23:59:59'
// }
// if (months > 12) {
// obj.min = moment(res.Result.LatestScanDateList[0]).startOf('month').format('YYYY-MM-DD') + ' 00:00:00'
// obj.max = moment(res.Result.LatestScanDateList[res.Result.LatestScanDateList.length - 1]).add(1, 'months').startOf('month').format('YYYY-MM-DD') + ' 23:59:59'
// }
// }
// console.log(obj)
this.initChart(obj)
}
} catch (err) {
this.loading = false
console.log(err)
}
},
foo() {
this.visible = false
this.$emit("foo");
this.dispose()
},
initChart(obj) {
this.chart = echarts.init(this.$refs.chartContainer);
// ...
const option = {
title: {
text: obj.title,
textStyle: {
color: "#fff"
}
},
tooltip: {
trigger: 'axis',
// formatter: function (params) {
// let index = obj.xAxisData.findIndex(item => item === params[0].value[0])
// let result = obj.visitName[index] + ' ' + params[0].value[0] + '<br>'; //
// params.forEach(function (item) {
// result += item.marker + ' ' + item.seriesName + ': ' + item.value[1] + '<br>'; //
// });
// return result;
// }
},
xAxis: {
// type: 'time',
// data: obj.xAxisData,
data: obj.visitName,
axisLine: { // x 线
lineStyle: {
color: '#fff',
}
},
axisLabel: { // x
textStyle: {
color: '#fff'
}
},
// splitLine: {
// show: false // 线
// },
// min: obj.min,
// max: obj.max
},
yAxis: {
name: obj.unit,
type: 'value',
axisLabel: {
textStyle: {
color: '#fff',
}
},
axisLine: {
lineStyle: {
color: '#fff',
}
},
},
series: obj.series
};
// 4. 使
this.chart.setOption(option);
},
resize() {
if (this.chart) {
this.chart.resize()
}
},
dispose() {
if (this.chart) {
this.chart.dispose()
this.chart = null
}
}
},
};
</script>
<style lang="scss" scoped>
.readingChart {
min-width: 500px;
max-width: 500px;
font-size: 14px;
display: inline-block;
background: #000;
border: 1px solid #ebeef5;
border-radius: 4px;
position: fixed;
padding: 10px 6px;
list-style-type: none;
min-height: 300px;
max-height: 80vh;
// overflow: hidden;
// overflow-y: auto;
box-sizing: border-box;
}
</style>

View File

@ -730,6 +730,13 @@ export default {
fileList: [], fileList: [],
dicomInfo: { dicomInfo: {
studyId: data.string('x00200010'), studyId: data.string('x00200010'),
Manufacturer: data.string('x00080070') || '',
ManufacturerModelName: data.string('x000801090') || '',
DeviceSerialNumber: data.string('x00181000') || '',
DeviceUID: data.string('x00181002') || '',
SoftwareVersions: data.string('x00181020') || '',
PatientWeight: data.string('x00101030') || '',
DicomStudyDate: data.string('x00080020'), DicomStudyDate: data.string('x00080020'),
DicomStudyTime: data.string('x00080030'), DicomStudyTime: data.string('x00080030'),
studyUid: studyUid, studyUid: studyUid,
@ -842,6 +849,9 @@ export default {
) )
seriesItem = { seriesItem = {
seriesUid: seriesUid, seriesUid: seriesUid,
RadiopharmaceuticalInformationSequence: data.string('x00540016') || "",
AcquisitionDate: data.string('x00080022') || "",
DicomSeriesDate: data.string('x00080021'), DicomSeriesDate: data.string('x00080021'),
DicomSeriesTime: data.string('x00080031'), DicomSeriesTime: data.string('x00080031'),
seriesNumber: data.intString('x00200011') || 1, seriesNumber: data.intString('x00200011') || 1,
@ -882,6 +892,20 @@ export default {
instanceTime = time ? `${date} ${time}` : `${date} 00:00:00` instanceTime = time ? `${date} ${time}` : `${date} 00:00:00`
} }
instanceItem = { instanceItem = {
PhotometricInterpretation: data.string('x00280004') || '',
BitsAllocated: data.uint16('x00280100') || '',
PixelRepresentation: data.uint16('x00280103') || '',
RescaleIntercept: data.string('x00281052') || '',
RescaleSlope: data.string('x00281053') || '',
ImagePositionPatient: data.string('x00200032') || '',
ImageOrientationPatient: data.string('x00200037') || '',
SequenceOfUltrasoundRegions: data.string('x00186011') || '',
FrameTime: data.string('x00181063') || '',
CorrectedImage: data.string('x00280051') || '',
Units: data.string('x00541001') || '',
DecayCorrection: data.string('x00541102') || '',
EncapsulatedDocument: data.string('x00420011') || '',
instanceUid: instanceUid, instanceUid: instanceUid,
SOPClassUID: data.string('x00080016'), SOPClassUID: data.string('x00080016'),
TransferSytaxUID: data.string('x00020010'), TransferSytaxUID: data.string('x00020010'),
@ -1098,6 +1122,13 @@ export default {
DicomStudyDate: dicomInfo.DicomStudyDate, DicomStudyDate: dicomInfo.DicomStudyDate,
DicomStudyTime: dicomInfo.DicomStudyTime, DicomStudyTime: dicomInfo.DicomStudyTime,
seriesList: [], seriesList: [],
Manufacturer: dicomInfo.Manufacturer,
ManufacturerModelName: dicomInfo.ManufacturerModelName,
DeviceSerialNumber: dicomInfo.DeviceSerialNumber,
DeviceUID: dicomInfo.DeviceUID,
SoftwareVersions: dicomInfo.SoftwareVersions,
PatientWeight: dicomInfo.PatientWeight,
}, },
} }
let arr = [] let arr = []
@ -1140,6 +1171,20 @@ export default {
windowWidth: o.windowWidth, windowWidth: o.windowWidth,
path: o.myPath, path: o.myPath,
FileSize: o.FileSize, FileSize: o.FileSize,
PhotometricInterpretation: o.PhotometricInterpretation,
BitsAllocated: o.BitsAllocated,
PixelRepresentation: o.PixelRepresentation,
RescaleIntercept: o.RescaleIntercept,
RescaleSlope: o.RescaleSlope,
ImagePositionPatient: o.ImagePositionPatient,
ImageOrientationPatient: o.ImageOrientationPatient,
SequenceOfUltrasoundRegions: o.SequenceOfUltrasoundRegions,
FrameTime: o.FrameTime,
CorrectedImage: o.CorrectedImage,
Units: o.Units,
DecayCorrection: o.DecayCorrection,
EncapsulatedDocument: o.EncapsulatedDocument,
}) })
Record.Uploaded.push(name) Record.Uploaded.push(name)
dicomInfo.failedFileCount++ dicomInfo.failedFileCount++
@ -1224,6 +1269,20 @@ export default {
windowWidth: o.windowWidth, windowWidth: o.windowWidth,
path: scope.$getObjectName(res.url), path: scope.$getObjectName(res.url),
FileSize: o.FileSize, FileSize: o.FileSize,
PhotometricInterpretation: o.PhotometricInterpretation,
BitsAllocated: o.BitsAllocated,
PixelRepresentation: o.PixelRepresentation,
RescaleIntercept: o.RescaleIntercept,
RescaleSlope: o.RescaleSlope,
ImagePositionPatient: o.ImagePositionPatient,
ImageOrientationPatient: o.ImageOrientationPatient,
SequenceOfUltrasoundRegions: o.SequenceOfUltrasoundRegions,
FrameTime: o.FrameTime,
CorrectedImage: o.CorrectedImage,
Units: o.Units,
DecayCorrection: o.DecayCorrection,
EncapsulatedDocument: o.EncapsulatedDocument,
}) })
o.myPath = scope.$getObjectName(res.url) o.myPath = scope.$getObjectName(res.url)
Record.Uploaded.push(name) Record.Uploaded.push(name)
@ -1272,6 +1331,9 @@ export default {
bodyPartExamined: dicomInfo.bodyPart, bodyPartExamined: dicomInfo.bodyPart,
instanceList: instanceList, instanceList: instanceList,
ImageResizePath: ImageResizePath, ImageResizePath: ImageResizePath,
RadiopharmaceuticalInformationSequence: v.RadiopharmaceuticalInformationSequence,
AcquisitionDate: v.AcquisitionDate,
}) })
} }
let text = JSON.stringify(Record) let text = JSON.stringify(Record)

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1762494352859" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="22987" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M896 832a128 128 0 0 1-128 128H256a128 128 0 0 1-128-128V192a128 128 0 0 1 128-128h512a128 128 0 0 1 128 128v640zM192 768v64a64 64 0 0 0 56.512 63.552L256 896h512a64 64 0 0 0 63.552-56.512L832 832v-64H192z m448-640H512v206.912l64-38.4 64 38.464V128z m-448 576h640V192a64 64 0 0 0-56.512-63.552L768 128h-64v263.488a32 32 0 0 1-48.448 27.456L576 371.2l-79.552 47.744A32 32 0 0 1 448 391.424V128H256a64 64 0 0 0-63.552 56.512L192 192v512z" fill="#e6e6e6" p-id="22988"></path></svg>

After

Width:  |  Height:  |  Size: 812 B

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1766048712120" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6026" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M924.520311 484.074997c7.439436 0 13.884218 2.726088 19.336394 8.16496 5.437849 5.452175 8.16496 11.897981 8.16496 19.336394 0 7.452739-2.726088 13.898545-8.16496 19.336394-5.452175 5.452175-11.897981 8.16496-19.336394 8.16496l-83.363639 0c-3.437286 40.110533-13.617136 77.777411-30.508851 113.012913-16.906042 35.236526-38.673811 66.175165-65.315588 92.816942s-57.58144 48.422849-92.816942 65.315588c-35.236526 16.906042-72.915683 26.790156-113.012913 29.650297l0 84.223217c0 7.439436-2.726088 13.884218-8.16496 19.336394-5.451152 5.437849-11.896958 8.16496-19.336394 8.16496-7.452739 0-13.898545-2.726088-19.336394-8.16496-5.452175-5.452175-8.16496-11.897981-8.16496-19.336394l0-84.223217c-40.110533-2.860141-77.777411-12.743232-113.012913-29.650297-35.236526-16.892739-66.175165-38.673811-92.816942-65.315588s-48.422849-57.58144-65.315588-92.816942c-16.906042-35.236526-27.071565-72.90238-30.508851-113.012913L99.479689 539.077705c-7.452739 0-13.898545-2.711761-19.336394-8.16496-5.452175-5.437849-8.16496-11.883655-8.16496-19.336394 0-7.439436 2.712785-13.884218 8.16496-19.336394 5.437849-5.437849 11.883655-8.16496 19.336394-8.16496l83.363639 0c3.437286-40.09723 13.602809-77.777411 30.508851-113.012913 16.892739-35.236526 38.673811-66.175165 65.315588-92.816942s57.58144-48.409546 92.816942-65.315588c35.236526-16.892739 72.90238-26.77583 113.012913-29.650297L484.497623 99.05604c0-7.439436 2.712785-13.885242 8.16496-19.336394 5.437849-5.437849 11.883655-8.16496 19.336394-8.16496 7.440459 0 13.885242 2.726088 19.336394 8.16496 5.437849 5.452175 8.16496 11.896958 8.16496 19.336394l0 84.223217c40.098253 2.874467 77.777411 12.757558 113.012913 29.650297 35.236526 16.906042 66.175165 38.673811 92.816942 65.315588s48.409546 57.58144 65.315588 92.816942c16.892739 35.236526 27.071565 72.916706 30.508851 113.012913L924.520311 484.074997zM484.498646 238.281965c-32.657794 2.874467-63.167668 11.320836-91.527576 25.352411-28.360931 14.046924-53.431933 31.946596-75.198679 53.713342-21.781072 21.781072-39.680744 46.837748-53.713342 75.198679-14.045901 28.360931-22.49227 58.869782-25.352411 91.527576L484.498646 484.073974 484.498646 238.281965zM238.70459 539.077705c2.860141 32.657794 11.30651 63.166645 25.352411 91.527576 14.032598 28.360931 31.933293 53.431933 53.713342 75.198679 21.766746 21.781072 46.837748 39.680744 75.198679 53.713342 28.360931 14.046924 58.869782 22.49227 91.527576 25.352411L484.496599 539.077705 238.70459 539.077705zM539.501354 484.074997l245.793032 0c-2.874467-32.657794-11.320836-63.167668-25.352411-91.527576-14.046924-28.360931-31.946596-53.417607-53.713342-75.198679-21.780049-21.766746-46.837748-39.667441-75.198679-53.713342-28.360931-14.032598-58.869782-22.478967-91.527576-25.352411L539.502377 484.074997zM539.501354 784.870738c32.657794-2.860141 63.167668-11.30651 91.527576-25.352411 28.360931-14.032598 53.41863-31.93227 75.198679-53.713342 21.766746-21.766746 39.667441-46.837748 53.713342-75.198679 14.032598-28.360931 22.478967-58.869782 25.352411-91.527576L539.501354 539.078729 539.501354 784.870738z" p-id="6027" fill="#ffffff"></path></svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 418 B

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1762485648235" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10985" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M543.378286 515.949714V104.521143a31.451429 31.451429 0 0 0-62.976 0v411.501714a125.44 125.44 0 0 0 0.292571 242.834286 31.670857 31.670857 0 0 0-0.292571 3.949714v156.745143a31.451429 31.451429 0 0 0 62.902857 0v-156.745143a31.597714 31.597714 0 0 0-0.219429-3.876571 125.513143 125.513143 0 0 0 0.292572-242.980572z m12.946285 165.814857a62.683429 62.683429 0 1 1-88.649142-88.722285 62.683429 62.683429 0 0 1 88.649142 88.722285zM229.522286 202.459429a31.597714 31.597714 0 0 0 0.292571-3.949715V104.594286a31.305143 31.305143 0 1 0-62.610286 0v93.988571c0 1.389714 0 2.706286 0.146286 4.022857a125.44 125.44 0 0 0 0 242.907429 31.670857 31.670857 0 0 0-0.146286 3.876571v470.235429a31.305143 31.305143 0 1 0 62.610286 0V449.316571a31.597714 31.597714 0 0 0-0.292571-3.803428 125.44 125.44 0 0 0 0-243.053714z m13.312 165.888a62.683429 62.683429 0 1 1-88.649143-88.722286 62.683429 62.683429 0 0 1 88.649143 88.722286zM950.857143 324.022857c0-58.587429-40.228571-107.739429-94.500572-121.563428a31.670857 31.670857 0 0 0 0.146286-3.949715V104.594286a31.305143 31.305143 0 0 0-62.610286 0v93.988571c0 1.389714 0.146286 2.706286 0.292572 4.022857a125.44 125.44 0 0 0 0 242.907429 31.670857 31.670857 0 0 0-0.292572 3.949714v470.162286a31.305143 31.305143 0 1 0 62.610286 0V449.389714c0-1.316571 0-2.56-0.146286-3.876571A125.513143 125.513143 0 0 0 950.857143 324.022857z m-81.042286 44.324572a62.683429 62.683429 0 1 1-88.649143-88.722286 62.683429 62.683429 0 0 1 88.649143 88.722286z" p-id="10986" fill="#e6e6e6"></path></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

1
src/icons/svg/mpr.svg Normal file
View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1764830990216" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5566" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M192 170.666667a21.333333 21.333333 0 0 0-21.333333 21.333333v640a21.333333 21.333333 0 0 0 21.333333 21.333333h640a21.333333 21.333333 0 0 0 21.333333-21.333333v-640a21.333333 21.333333 0 0 0-21.333333-21.333333h-640zM85.333333 192A106.666667 106.666667 0 0 1 192 85.333333h640A106.666667 106.666667 0 0 1 938.666667 192v640a106.666667 106.666667 0 0 1-106.666667 106.666667h-640A106.666667 106.666667 0 0 1 85.333333 832v-640z" fill="#ffffff" p-id="5567"></path><path d="M173.653333 170.666667c-1.621333 5.034667-2.986667 12.373333-2.986666 21.333333v640c0 8.96 1.365333 16.298667 2.986666 21.333333h292.693334c1.621333-5.034667 2.986667-12.373333 2.986666-21.333333v-640c0-8.96-1.365333-16.298667-2.986666-21.333333H173.653333zM99.157333 127.658667C107.306667 111.530667 126.293333 85.333333 160 85.333333h320c33.706667 0 52.736 26.197333 60.8 42.325334 9.301333 18.688 13.866667 41.472 13.866667 64.341333v640c0 22.869333-4.565333 45.653333-13.866667 64.341333-8.106667 16.128-27.093333 42.325333-60.8 42.325334h-320c-33.706667 0-52.736-26.197333-60.8-42.325334C89.856 877.653333 85.333333 854.869333 85.333333 832v-640c0-22.869333 4.522667-45.653333 13.866667-64.341333z" fill="#ffffff" p-id="5568"></path><path d="M170.666667 170.666667v298.666666h298.666666V170.666667H170.666667z m-85.333334-10.666667C85.333333 118.784 118.784 85.333333 160 85.333333h320c41.216 0 74.666667 33.450667 74.666667 74.666667v320A74.666667 74.666667 0 0 1 480 554.666667h-320A74.666667 74.666667 0 0 1 85.333333 480v-320z" fill="#ffffff" p-id="5569"></path></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1763446648844" class="icon" viewBox="0 0 1321 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3570" xmlns:xlink="http://www.w3.org/1999/xlink" width="258.0078125" height="200"><path d="M1187.981 845.871H200.885V120.065C200.885 91.032 177.659 62 142.82 62s-58.064 23.226-58.064 58.065v783.87c0 29.033 23.225 58.065 58.064 58.065h1045.161c29.033 0 58.065-23.226 58.065-58.065s-29.032-58.064-58.065-58.064z" fill="#1296db" p-id="3571"></path><path d="M287.981 317.484L555.078 485.87c11.613 5.806 17.42 5.806 29.032 5.806 17.42 0 34.84-5.806 46.452-23.225l185.806-255.484 191.613 145.161c23.226 17.42 58.065 11.613 75.484-11.613 17.42-23.226 11.613-58.064-11.613-75.484L839.594 96.84c-23.226-17.42-58.064-11.613-75.484 11.613L572.497 363.935 346.046 224.581c-23.226-17.42-58.065-5.807-75.484 17.419s-5.806 58.065 17.42 75.484z m29.033 505.161c29.032 0 58.064-23.226 58.064-58.064V532.323c0-29.033-23.226-58.065-58.064-58.065s-58.065 23.226-58.065 58.065v238.064c5.807 29.032 29.032 52.258 58.065 52.258zM502.82 619.42v150.968c0 29.032 23.226 58.065 58.065 58.065s58.064-23.226 58.064-58.065V619.42c0-29.032-23.226-58.064-58.064-58.064s-58.065 29.032-58.065 58.064z" fill="#1296db" p-id="3572"></path><path d="M740.885 416.194v354.193c0 29.032 23.225 58.065 58.064 58.065s58.065-23.226 58.065-58.065V416.194c0-29.033-23.226-58.065-58.065-58.065s-58.064 29.032-58.064 58.065z m296.129 92.903c-29.033 0-58.065 23.226-58.065 58.064v203.226c0 29.032 23.226 58.065 58.065 58.065s58.064-23.226 58.064-58.065V567.161c0-29.032-29.032-58.064-58.064-58.064z" fill="#1296db" p-id="3573"></path></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -26,8 +26,9 @@ Vue.use(VueClipboard)
import permission from './utils/permission' import permission from './utils/permission'
Vue.use(permission) Vue.use(permission)
import { formatSize } from "./utils" import { formatSize, guidToColor } from "./utils"
Vue.prototype.$FormatSize = formatSize Vue.prototype.$FormatSize = formatSize
Vue.prototype.$GuidToColor = guidToColor
import Viewer from 'v-viewer' import Viewer from 'v-viewer'
import './assets/css/viewer.css' import './assets/css/viewer.css'
@ -61,6 +62,8 @@ import Onlyoffice from '@/components/Preview_onlyoffice/index'
Vue.use(Onlyoffice) Vue.use(Onlyoffice)
import Video from '@/components/Preview_video/index' import Video from '@/components/Preview_video/index'
Vue.use(Video) Vue.use(Video)
import AGR from '@/components/AGR/index'
Vue.use(AGR)
import MFA from '@/components/MFA/index' import MFA from '@/components/MFA/index'
Vue.use(MFA) Vue.use(MFA)
import FB from '@/components/feedBack/index' import FB from '@/components/feedBack/index'

View File

@ -357,4 +357,18 @@ body .el-table th.gutter {
.el-message-box__wrapper { .el-message-box__wrapper {
z-index: 9999 !important; z-index: 9999 !important;
}
.svg-readingChart {
width: 28px !important;
height: 30px !important;
margin-left: 10px;
cursor: pointer;
}
.svg-readingChart-mini {
width: 18px !important;
height: 20px !important;
vertical-align: -0.4em !important;
cursor: pointer;
} }

32
src/utils/fingerprint.js Normal file
View File

@ -0,0 +1,32 @@
import FingerprintJS from '@fingerprintjs/fingerprintjs';
export const customAgent = () => {
return new Promise(async resolve => {
const fpPromise = await FingerprintJS.load({
monitoring: false
});
const result = await fpPromise.get({
products: ['fonts', 'screen', 'canvas'],
extendedData: true,
debug: false
})
// const filteredComponents = Object.fromEntries(
// Object.entries(result.components)
// .filter(([key, value]) => value.confidence > 0.5)
// );
resolve({
...result,
});
// fpPromise
// .then(fp => fp.get({
// products: ['fonts', 'screen', 'canvas'],
// extendedData: true,
// debug: true
// }))
// .then(result => {
// // 自定义数据转换
// });
});
}

View File

@ -196,4 +196,110 @@ export function workSpeedclose(isForce = false) {
lastPercentage = 0; lastPercentage = 0;
imageId = null; imageId = null;
percentageById = {}; percentageById = {};
}
function readDirectoryEntries(directoryReader) {
return new Promise((resolve, reject) => {
let entries = [];
function readBatch() {
directoryReader.readEntries(
(results) => {
if (results.length) {
entries = entries.concat(results);
readBatch();
} else {
resolve(entries);
}
},
(error) => reject(error)
);
}
readBatch();
});
}
export async function readEntry(entry) {
const files = [];
// 如果是文件夹,创建读取器并递归读取其内容
if (entry.isDirectory) {
const directoryReader = entry.createReader();
const entries = await readDirectoryEntries(directoryReader)
// 递归读取文件夹内的每一项
for (const subEntry of entries) {
const subFiles = await readEntry(subEntry);
files.push(...subFiles);
}
}
// 如果是文件则将其转换为File对象
else if (entry.isFile) {
const file = await new Promise((resolve, reject) => {
entry.file(resolve, reject); // entry.file()是异步的
});
files.push(file);
}
return files;
}
// 使用FNV-1a哈希算法确保相同GUID产生相同结果
function fnv1aHash(str) {
const FNV_OFFSET_BASIS = 2166136261;
const FNV_PRIME = 16777619;
let hash = FNV_OFFSET_BASIS;
for (let i = 0; i < str.length; i++) {
hash ^= str.charCodeAt(i);
hash = (hash * FNV_PRIME) >>> 0; // 使用无符号右移确保结果为无符号32位整数
}
return hash;
}
// RGB转十六进制
function rgbToHex(r, g, b) {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1).toUpperCase();
}
// HSL转RGB函数
function hslToRgb(h, s, l) {
let r, g, b;
if (s === 0) {
r = g = b = l; // 灰色
} else {
const hue2rgb = (p, q, t) => {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p + (q - p) * 6 * t;
if (t < 1 / 2) return q;
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
};
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
return { r, g, b };
}
export function guidToColor(guid) {
// 移除GUID中的连字符和花括号如果有
let cleanGuid = guid.replace(/[{}()-]/g, '');
// 计算GUID的哈希值
const hash = fnv1aHash(cleanGuid);
// 使用哈希值生成HLS颜色确保高区分度
// 将哈希值映射到0-1之间
const h = (hash & 0xFFFF) / 0xFFFF; // 使用前16位作为色相
const s = ((hash >> 16) & 0xFF) / 0xFF * 0.6 + 0.4; // 饱和度在0.4-1.0之间
const l = ((hash >> 24) & 0xFF) / 0xFF * 0.4 + 0.4; // 亮度在0.3-0.7之间,避免太暗或太亮
// 返回RGB对象
let rgb = hslToRgb(h, s, l);
let obj = {
r: Math.round(rgb.r * 255),
g: Math.round(rgb.g * 255),
b: Math.round(rgb.b * 255)
}
let str = rgbToHex(obj.r, obj.g, obj.b)
return str;
} }

View File

@ -5,6 +5,7 @@ import router from '@/router'
import WHITELIST from "./whiteList" import WHITELIST from "./whiteList"
import moment from 'moment-timezone'; import moment from 'moment-timezone';
import { encryptConfig } from "@/utils/encrypt" import { encryptConfig } from "@/utils/encrypt"
import { customAgent } from './fingerprint'
const ROUTER = require('@/router'); const ROUTER = require('@/router');
axios.defaults.withCredentials = false axios.defaults.withCredentials = false
const service = axios.create({ const service = axios.create({
@ -26,6 +27,8 @@ service.interceptors.request.use(
var language = zzSessionStorage.getItem('lang') var language = zzSessionStorage.getItem('lang')
config.headers['Accept-Language'] = language === 'en' ? 'en-US,en;q=0.5' : 'zh-CN,zh;q=0.9' config.headers['Accept-Language'] = language === 'en' ? 'en-US,en;q=0.5' : 'zh-CN,zh;q=0.9'
config.headers['TimeZoneId'] = moment.tz.guess() config.headers['TimeZoneId'] = moment.tz.guess()
let fingerprint = await customAgent()
config.headers['BrowserFingerprint'] = fingerprint.visitorId
if (config.ENCRYPT) { if (config.ENCRYPT) {
try { try {
config = await encryptConfig(config) config = await encryptConfig(config)

88
src/utils/splitScreen.js Normal file
View File

@ -0,0 +1,88 @@
async function queryWindowManagement() {
return await navigator.permissions.query({ name: 'window-management' });;
}
async function getPermission() {
const permission = await queryWindowManagement();
console.log(permission.state, 'permission.state')
if (permission.state === "granted") { // 已经授权
return true
} else if (permission.state === "prompt") { // 询问是否授权
// 请求授权
if (navigator.permissions.request) {
navigator.permissions.request({ name: 'window-management' })
}
return false
} else if (permission.state === "denied") {
// 权限被拒绝
return false
}
}
function getScreen() {
return new Promise((resolve, reject) => {
let multiScreen = []
if (window.getScreenDetails) {
let getScreensProsime1 = window.getScreenDetails();
getScreensProsime1.then((c) => {
if (c instanceof Array) {
multiScreen = c
} else if (c instanceof Object) {
multiScreen = c.screens
} else {
multiScreen = []
}
resolve(multiScreen)
}).catch((err) => {
reject(err)
});
} else if (window.getScreens) {
let getScreensProsime = window.getScreens();
getScreensProsime.then((c) => {
if (c instanceof Array) {
multiScreen = c
} else if (c instanceof Object) {
multiScreen = c.screens
} else {
multiScreen = []
}
resolve(multiScreen)
}).catch((err) => {
reject(err)
})
}
})
}
export async function openWindow(url, name, Skip = false) {
// 判断浏览器是否兼容
// 高版本的谷歌edge不支持跨屏需要降低浏览器版本86.0版
if (!window.getScreens && !window.getScreenDetails) {
console.log('你的浏览器版本不支持多屏展示功能!');
return window.open(url, name);
}
let permission = await getPermission()
if (!permission) {
// alert('使用多屏功能请先进行授权')
if (Skip) {
return window.open(url, name);
}
return false
}
let multiScreen = await getScreen()
console.log(multiScreen, 'multiScreen')
// 判断是否2个屏幕
if (multiScreen.length < 2) {
console.log('请接入多个显示屏!');
return window.open(url, name);
}
console.log(screen, 'screen')
// 获取当前屏幕availLeft信息和所有信息比对取另一个屏幕数据
let currentAvailLeft = screen.availLeft ? screen.availLeft : '0'
let newCurr = multiScreen.find((t) => t.availLeft != currentAvailLeft)
console.log(newCurr, 'newCurr')
let fulls = ''
for (let key in newCurr) {
fulls += `${key}=${(newCurr[key] || newCurr[key] === 0) ? newCurr[key] : 0},`
}
console.log(fulls, 'fulls')
return window.open(url, name, fulls);
}

View File

@ -112,7 +112,7 @@ export default {
this.currentTime = moment().format('YYYY-MM-DD HH:mm:ss') this.currentTime = moment().format('YYYY-MM-DD HH:mm:ss')
}, },
handleTitleClick() { handleTitleClick() {
if (!screenfull.enabled) { if (!screenfull.isEnabled) {
this.$message({ this.$message({
message: 'Your browser can not work', message: 'Your browser can not work',
type: 'warning' type: 'warning'

View File

@ -83,33 +83,36 @@
{{ item.description }} {{ item.description }}
</div> </div>
<div v-if="!item.keySeries" style="padding: 1px;"> <div v-if="!item.keySeries" style="padding: 1px;">
{{ item.imageloadedArr.length }}/{{ item.instanceCount }} {{ item.imageloadedArr.length <= item.instanceCount ? item.imageloadedArr.length :
item.instanceCount }}/{{ item.instanceCount }} </div>
</div> </div>
</div> </div>
</div> <div v-if="showDelete" style="display: flex;flex-direction: row;justify-content: space-between;"
<div v-if="showDelete" style="display: flex;flex-direction: row;justify-content: space-between;" @click.stop="">
@click.stop="">
<div> <div>
<span style="font-size: 12px;margin-right: 5px">{{ $t('trials:audit:table:isReading') <span style="font-size: 12px;margin-right: 5px">{{ $t('trials:audit:table:isReading')
}}</span> }}</span>
<el-switch v-model="item.isReading" size="mini" @change="changeReadingStatus($event, item)" /> <el-switch v-model="item.isReading" size="mini"
@change="changeReadingStatus($event, item)" />
</div>
<div>
<span style="font-size: 12px;margin-right: 5px">{{ $t('trials:audit:table:isDelete')
}}</span>
<el-switch v-model="item.isDeleted" size="mini"
@change="changeDeleteStatus($event, item)" />
</div>
</div> </div>
<div> <div
<span style="font-size: 12px;margin-right: 5px">{{ $t('trials:audit:table:isDelete') }}</span> v-if="item.prefetchInstanceCount > 0 && item.prefetchInstanceCount < item.instanceCount * 100">
<el-switch v-model="item.isDeleted" size="mini" @change="changeDeleteStatus($event, item)" /> <el-progress
:percentage="parseInt((item.prefetchInstanceCount / item.instanceCount).toFixed(2))" />
</div> </div>
</div>
<div
v-if="item.prefetchInstanceCount > 0 && item.prefetchInstanceCount < item.instanceCount * 100">
<el-progress
:percentage="parseInt((item.prefetchInstanceCount / item.instanceCount).toFixed(2))" />
</div>
</div>
</div> </div>
</div> </div>
</div>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
@ -891,6 +894,7 @@ export default {
// //
this.seriesList[seriesIndex].loadStatus = true this.seriesList[seriesIndex].loadStatus = true
workSpeedclose() workSpeedclose()
localStorage.setItem("QCRiskControl", 1)
if (!this.isFromCRCUpload) { if (!this.isFromCRCUpload) {
this.loadAllImages() this.loadAllImages()
} }

View File

@ -113,35 +113,35 @@
</div> </div>
</el-tooltip> </el-tooltip>
<div style="padding: 1px;"> <div style="padding: 1px;">
{{ series.imageloadedArr.length }}/{{ series.instanceCount }} {{ series.imageloadedArr.length <= series.instanceCount ? series.imageloadedArr.length :
series.instanceCount }}/{{ series.instanceCount }} </div>
<div />
</div> </div>
<div />
</div> </div>
</div> <div v-if="showDelete"
<div v-if="showDelete" style="display: flex;flex-direction: row;justify-content: space-between;" @click.stop="">
style="display: flex;flex-direction: row;justify-content: space-between;" @click.stop="">
<div> <div>
<span style="font-size: 12px;">{{ $t('trials:audit:table:isReading') }}</span> <span style="font-size: 12px;">{{ $t('trials:audit:table:isReading') }}</span>
<el-switch v-model="series.isReading" size="mini" <el-switch v-model="series.isReading" size="mini"
@change="changeReadingStatus($event, series)" /> @change="changeReadingStatus($event, series)" />
</div>
<div>
<span style="font-size: 12px;">{{ $t('trials:audit:table:isDelete') }}</span>
<el-switch v-model="series.isDeleted" size="mini"
@change="changeDeleteStatus($event, series)" />
</div>
</div> </div>
<div> <!-- <div style="position: absolute;bottom: -10px;left: 0;width: 100%;">
<span style="font-size: 12px;">{{ $t('trials:audit:table:isDelete') }}</span>
<el-switch v-model="series.isDeleted" size="mini"
@change="changeDeleteStatus($event, series)" />
</div>
</div>
<!-- <div style="position: absolute;bottom: -10px;left: 0;width: 100%;">
<el-progress v-if="series.prefetchInstanceCount>0 && series.prefetchInstanceCount<series.instanceCount" :percentage="Number(series.prefetchInstanceCount/series.instanceCount)*100" /> <el-progress v-if="series.prefetchInstanceCount>0 && series.prefetchInstanceCount<series.instanceCount" :percentage="Number(series.prefetchInstanceCount/series.instanceCount)*100" />
</div> --> </div> -->
<div <div
v-if="series.prefetchInstanceCount > 0 && series.prefetchInstanceCount < series.instanceCount * 100"> v-if="series.prefetchInstanceCount > 0 && series.prefetchInstanceCount < series.instanceCount * 100">
<el-progress <el-progress
:percentage="parseInt((series.prefetchInstanceCount / series.instanceCount).toFixed(2))" /> :percentage="parseInt((series.prefetchInstanceCount / series.instanceCount).toFixed(2))" />
</div> </div>
</div> </div>
</el-collapse-item> </el-collapse-item>
</el-collapse> </el-collapse>
@ -937,6 +937,7 @@ export default {
this.loadAllImages() this.loadAllImages()
} }
workSpeedclose() workSpeedclose()
localStorage.setItem("QCRiskControl", 1)
} }
} }
} }

View File

@ -106,6 +106,16 @@ export default {
isTrial: { isTrial: {
type: Boolean, type: Boolean,
default: false default: false
},
isExternal: {
type: Boolean,
default: false
},
ExternalList: {
type: Array,
default: () => {
return []
}
} }
}, },
data() { data() {
@ -122,7 +132,8 @@ export default {
rowData: {}, rowData: {},
list: [], list: [],
searchData: defaultSearchData(), searchData: defaultSearchData(),
title: this.$t('dictionary:signature:fileList') title: this.$t('dictionary:signature:fileList'),
loading: false
} }
}, },
watch: { watch: {
@ -131,6 +142,16 @@ export default {
this.getList() this.getList()
}, },
immediate: true, immediate: true,
},
isExternal: {
handler() {
if (this.isExternal) {
this.list = this.ExternalList
this.rowData = this.list[0] || {}
this.title = this.$t('dictionary:signature:view')
}
},
immediate: true
} }
}, },
methods: { methods: {
@ -145,6 +166,7 @@ export default {
}, },
async getList() { async getList() {
try { try {
if (this.isExternal) return
if (!this.SystemDocumentId) return false if (!this.SystemDocumentId) return false
this.loading = true this.loading = true
if (!this.isTrial) { if (!this.isTrial) {

View File

@ -191,6 +191,17 @@
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="24">
<el-form-item>
<span slot="label">
适用的标准
</span>
<el-select v-model="form.ApplyCriterionList" placeholder="" clearable multiple>
<el-option v-for="item in $d.CriterionType" :key="item.id" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col v-show="form.ConfigType === 'C' && title !== '复制'" :span="12"> <el-col v-show="form.ConfigType === 'C' && title !== '复制'" :span="12">
<el-form-item> <el-form-item>
<span slot="label"> <span slot="label">
@ -1008,6 +1019,7 @@ export default {
ValueCN: null, ValueCN: null,
EnumType: '', EnumType: '',
IsShowByTrialConfig: false, IsShowByTrialConfig: false,
ApplyCriterionList: [],
TrialConfigRelyFieldName: null, TrialConfigRelyFieldName: null,
Identification: null, Identification: null,
IsForwardPosition: false, IsForwardPosition: false,

View File

@ -0,0 +1,194 @@
<template>
<el-form ref="sysAgreementFrom" v-loading="loading" :model="form" label-width="140px" size="small" :rules="rules"
class="upload-temporary-file">
<div class="base-dialog-body">
<el-row>
<el-col :span="12">
<el-form-item :label="$t('dictionary:agreement:table:UserAgreementTypeEnum')" prop="UserAgreementTypeEnum"
style="width: 48%">
<el-select v-model="form.UserAgreementTypeEnum" style="width: 100%" size="small" filterable>
<el-option v-for="item of $d.UserAgreementType" :key="item.id" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('dictionary:agreement:table:FileName')" prop="FileName" style="width: 48%">
<el-input v-model="form.FileName" clearable style="width: 100%" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item :label="$t('dictionary:agreement:table:FileVersion')" prop="FileVersion" style="width: 48%">
<el-input v-model="form.FileVersion" clearable style="width: 100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('dictionary:agreement:table:UpdateDate')" prop="UpdateDate" style="width: 48%">
<el-date-picker v-model="form.UpdateDate" type="date"
:placeholder="$t('trials:seletctedReviews:table:selectionTime')" value-format="yyyy-MM-dd"
format="yyyy-MM-dd" clearable style="width: 100%;">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item :label="$t('dictionary:agreement:table:EffectiveDate')" prop="EffectiveDate" style="width: 48%">
<el-date-picker v-model="form.EffectiveDate" type="date"
:placeholder="$t('trials:seletctedReviews:table:selectionTime')" value-format="yyyy-MM-dd"
format="yyyy-MM-dd" clearable style="width: 100%;">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-form-item :label="$t('dictionary:agreement:table:FileContent')" prop="FileContent">
<div class="html_temp">
<prism-editor class="my-editor" v-model="form.FileContent" :highlight="highlighter" :line-numbers="true"
style="width: 50%;max-height: 350px;"></prism-editor>
<div v-html="form.FileContent" style="width: 45%;" class="content"></div>
</div>
</el-form-item>
<el-form-item :label="$t('dictionary:agreement:table:FileContentEn')" prop="FileEnContent">
<div class="html_temp">
<prism-editor class="my-editor" v-model="form.FileEnContent" :highlight="highlighter" :line-numbers="true"
style="width: 50%;max-height: 350px;"></prism-editor>
<div v-html="form.FileEnContent" style="width: 45%;" class="content"></div>
</div>
</el-form-item>
</div>
<div class="base-dialog-footer" style="text-align: right; margin-top: 10px">
<el-form-item style="text-align: right">
<el-button size="small" type="primary" :loading="saveBtnLoading" @click="handleSave">{{ $t('common:button:save')
}}</el-button>
</el-form-item>
</div>
</el-form>
</template>
<script>
import {
addOrUpdateUserAgreement,
} from '@/api/dictionary'
import { PrismEditor } from 'vue-prism-editor';
import 'vue-prism-editor/dist/prismeditor.min.css';
import { highlight, languages } from 'prismjs/components/prism-core';
import 'prismjs/components/prism-clike';
import 'prismjs/components/prism-javascript';
import 'prismjs/themes/prism.css';
export default {
name: 'TemplateForm',
props: {
data: {
type: Object,
default() {
return {}
},
},
},
components: { PrismEditor },
data() {
return {
form: {
Id: '',
UserAgreementTypeEnum: '',
FileName: '',
FileVersion: null,
FileContent: '\n\n\n\n',
FileEnContent: `\n\n\n\n`,
UpdateDate: '',
EffectiveDate: '',
IsCurrentVersion: false
},
rules: {
UserAgreementTypeEnum: [
{ required: true, message: this.$t('common:ruleMessage:select'), trigger: ['blur'] },
],
FileName: [
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: ['blur'] },
],
FileVersion: [
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: ['blur'] },
],
FileContent: [
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: ['blur'] },
],
FileEnContent: [
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: ['blur'] },
],
UpdateDate: [
{ required: true, message: this.$t('common:ruleMessage:select'), trigger: ['blur'] },
],
EffectiveDate: [
{ required: true, message: this.$t('common:ruleMessage:select'), trigger: ['blur'] },
],
},
saveBtnLoading: false,
loading: false,
dictionaryList: {},
}
},
mounted() {
this.initForm()
},
methods: {
highlighter(code) {
return highlight(code, languages.js);
},
async initForm() {
if (Object.keys(this.data).length > 0) {
for (const k in this.form) {
if (this.data.hasOwnProperty(k)) {
this.form[k] = this.data[k]
}
}
}
},
handleSave() {
this.$refs.sysAgreementFrom.validate((valid) => {
if (!valid) return
this.saveBtnLoading = true
addOrUpdateUserAgreement(this.form)
.then((res) => {
this.saveBtnLoading = false
this.$emit('closeDialog')
this.$emit('getList')
this.$message.success(this.$t('common:message:savedSuccessfully'))
})
.catch(() => {
this.saveBtnLoading = false
})
})
},
},
}
</script>
<style lang="scss" scoped>
.html_temp {
display: flex;
justify-content: space-between;
width: 100%;
.my-editor {
border: 1px solid #333;
}
}
.base-dialog-body {
max-height: calc(100% - 60px);
}
.upload-temporary-file {
overflow-y: auto;
height: 100%;
}
.content {
max-height: 350px;
overflow-y: auto;
}
</style>

View File

@ -0,0 +1,313 @@
<template>
<BaseContainer>
<template slot="search-container">
<el-form :inline="true" size="small">
<!-- 文件类型 -->
<el-form-item :label="$t('dictionary:agreement:table:UserAgreementTypeEnum')">
<el-select v-model="searchData.UserAgreementTypeEnum" style="width: 150px">
<el-option v-for="item of $d.UserAgreementType" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<!-- 文件名称 -->
<el-form-item :label="$t('dictionary:agreement:table:FileName')">
<el-input v-model="searchData.FileName" style="width: 130px" clearable />
</el-form-item>
<!-- 版本 -->
<el-form-item :label="$t('dictionary:agreement:table:FileVersion')">
<el-input v-model="searchData.FileVersion" style="width: 130px" clearable />
</el-form-item>
<!--更新日期-->
<el-form-item :label="$t('dictionary:agreement:table:UpdateDate')">
<el-date-picker v-model="UpdateDate" @change="changeTimeList('UpdateDate')" value-format="yyyy-MM-dd"
type="daterange">
</el-date-picker>
</el-form-item>
<!--生效日期-->
<el-form-item :label="$t('dictionary:agreement:table:EffectiveDate')">
<el-date-picker v-model="EffectiveDate" @change="changeTimeList('EffectiveDate')" value-format="yyyy-MM-dd"
type="daterange">
</el-date-picker>
</el-form-item>
<!-- 当前版本 -->
<el-form-item :label="$t('dictionary:agreement:table:IsCurrentVersion')">
<el-select v-model="searchData.IsCurrentVersion" style="width: 150px">
<el-option v-for="item of $d.YesOrNo" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item>
<!-- 查询 -->
<el-button type="primary" icon="el-icon-search" @click="handleSearch">
{{ $t('common:button:search') }}
</el-button>
<!-- 重置 -->
<el-button type="primary" icon="el-icon-refresh-left" @click="handleReset">
{{ $t('common:button:reset') }}
</el-button>
</el-form-item>
<el-button type="primary" style="float: right" size="small" @click="handleAdd">
{{ $t('common:button:new') }}
</el-button>
</el-form>
</template>
<template slot="main-container">
<el-table v-adaptive="{ bottomOffset: 60 }" v-loading="loading" :data="list" stripe height="100"
@sort-change="handleSortChange">
<el-table-column type="index" width="40" />
<!-- 文件类型 -->
<el-table-column prop="UserAgreementTypeEnum" :label="$t('dictionary:agreement:table:UserAgreementTypeEnum')"
show-overflow-tooltip sortable="custom">
<template slot-scope="scope">
{{
$fd(
'UserAgreementType',
scope.row.UserAgreementTypeEnum
)
}}
</template>
</el-table-column>
<!-- 文件名称 -->
<el-table-column prop="FileName" :label="$t('dictionary:agreement:table:FileName')" show-overflow-tooltip
sortable="custom" />
<!-- 版本 -->
<el-table-column prop="FileVersion" :label="$t('dictionary:agreement:table:FileVersion')" show-overflow-tooltip
sortable="custom" />
<!--内容-->
<el-table-column prop="FileContent" :label="$t('dictionary:agreement:table:FileContent')">
<template slot-scope="scope">
<el-button type="text" size="small" @click.stop="view(scope.row)">{{ $t('dictionary:agreement:button:view')
}}</el-button>
</template>
</el-table-column>
<!-- 更新日期 -->
<el-table-column prop="UpdateDate" :label="$t('dictionary:agreement:table:UpdateDate')" show-overflow-tooltip
sortable="custom">
<template slot-scope="scope">
<span>{{ scope.row.UpdateDate ? scope.row.UpdateDate.split(' ')[0] : '' }}</span>
</template>
</el-table-column>
<!-- 生效日期 -->
<el-table-column prop="EffectiveDate" :label="$t('dictionary:agreement:table:EffectiveDate')"
show-overflow-tooltip sortable="custom">
<template slot-scope="scope">
<span>{{ scope.row.EffectiveDate ? scope.row.EffectiveDate.split(' ')[0] : '' }}</span>
</template>
</el-table-column>
<!-- 当前版本 -->
<el-table-column prop="IsCurrentVersion" :label="$t('dictionary:agreement:table:IsCurrentVersion')"
show-overflow-tooltip sortable="custom">
<template slot-scope="scope">
{{
$fd(
'YesOrNo',
scope.row.IsCurrentVersion
)
}}
</template>
</el-table-column>
<!-- 创建日期 -->
<el-table-column prop="CreateTime" :label="$t('dictionary:agreement:table:CreateTime')" show-overflow-tooltip
sortable="custom" />
<!-- 修改日期 -->
<el-table-column prop="UpdateTime" :label="$t('dictionary:agreement:table:UpdateTime')" show-overflow-tooltip
sortable="custom" />
<el-table-column :label="$t('common:action:action')" width="300">
<template slot-scope="scope">
<el-button type="text" :disabled="scope.row.IsCurrentVersion" @click="setCurrentVersion(scope.row)">
{{ $t('dictionary:agreement:button:setCurrentVersion') }}
</el-button>
<el-button type="text" @click="handleEdit(scope.row)">
{{ $t('common:button:edit') }}
</el-button>
<!-- <el-button type="text" @click="handleDelete(scope.row)">
{{ $t('common:button:delete') }}
</el-button> -->
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
@pagination="getList" />
<!-- 新增/编辑 -->
<el-dialog v-if="editDialog.visible" :visible.sync="editDialog.visible" :close-on-click-modal="false"
:title="editDialog.title" custom-class="base-dialog-wrapper" :fullscreen="true">
<TemplateForm :data="currentRow" @closeDialog="closeDialog" @getList="getList" />
</el-dialog>
</template>
</BaseContainer>
</template>
<script>
import {
getUserAgreementList,
deleteUserAgreement,
setCurrentVersion
} from '@/api/dictionary'
import BaseContainer from '@/components/BaseContainer'
import Pagination from '@/components/Pagination'
import TemplateForm from './TemplateForm'
const searchDataDefault = () => {
return {
StartEffectiveDate: null,
EndEffectiveDate: null,
FileName: null,
FileVersion: null,
IsCurrentVersion: null,
StartUpdateDate: null,
EndUpdateDate: null,
UserAgreementTypeEnum: null,
Asc: false,
SortField: "",
PageIndex: 1,
PageSize: 20,
}
}
export default {
name: 'Agreement',
components: { BaseContainer, Pagination, TemplateForm },
data() {
return {
searchData: searchDataDefault(),
list: [],
total: 0,
currentRow: {},
editDialog: { title: '', visible: false },
loading: false,
UpdateDate: [],
EffectiveDate: []
}
},
mounted() {
this.getList()
},
computed: {
isEN() {
return this.$i18n.locale !== 'zh'
},
},
methods: {
async setCurrentVersion(row) {
try {
let data = {
Id: row.Id
}
this.loading = true
let res = await setCurrentVersion(data)
this.loading = false
if (res.IsSuccess) {
this.getList()
}
} catch (err) {
this.loading = false
console.log(err)
}
},
view(row) {
this.$AGR({
Id: row.Id,
IsEn_Us: this.isEN
})
},
changeTimeList(key) {
if (this[key]) {
this.searchData[`Start${key}`] = this[key][0]
this.searchData[`End${key}`] = this[key][1]
} else {
this.searchData.BeginCreateTime = null
this.searchData.EndCreateTime = null
}
},
handleDelete(row) {
//
this.$confirm(this.$t('dictionary:agreement:message:msg1')).then(() => {
deleteUserAgreement(row.Id).then(() => {
this.$message.success(this.$t('common:message:deletedSuccessfully'))
this.getList()
})
}).catch(() => { })
},
PreviewFile(row) {
let basePath = window.location.origin
if (window.location.protocol !== 'https:') {
basePath = 'https://irc.test.extimaging.com'
}
let data = {
name: row.NameCN,
path: basePath + row.Path,
}
this.$emit('PreviewFile', data)
},
getList() {
this.loading = true
getUserAgreementList(this.searchData)
.then((res) => {
this.loading = false
this.list = res.Result.CurrentPageData
this.total = res.Result.TotalCount
})
.catch(() => {
this.loading = false
})
},
//
handleAdd() {
this.editDialog.title = this.$t('common:button:new')
this.currentRow = {}
this.editDialog.visible = true
},
//
async handleDownload(row) {
try {
this.loading = true
let fileName = this.isEN ? row.Name : row.NameCN;
let type = fileName
.substring(fileName.lastIndexOf('.'))
.toLocaleLowerCase()
if (!type) {
let extendName = row.Path
.substring(row.Path.lastIndexOf('.'))
.toLocaleLowerCase()
fileName += extendName
}
let res = await downLoadFile(this.OSSclientConfig.basePath + row.Path, fileName)
this.loading = false
} catch (err) {
this.loading = false
}
},
//
handleEdit(row) {
this.editDialog.title = this.$t('common:button:edit')
this.currentRow = { ...row }
this.editDialog.visible = true
},
handleSearch() {
this.searchData.PageIndex = 1
this.getList()
},
handleReset() {
this.searchData = searchDataDefault()
this.getList()
},
closeDialog() {
this.editDialog.visible = false
},
//
handleSortChange(column) {
if (column.order === 'ascending') {
this.searchData.Asc = true
} else {
this.searchData.Asc = false
}
this.searchData.SortField = column.prop
this.searchData.PageIndex = 1
this.getList()
},
},
}
</script>
<style lang="scss" scoped>
::v-deep .search {
display: block;
}
</style>

View File

@ -3,27 +3,22 @@
<!-- 器官 --> <!-- 器官 -->
<el-tab-pane :label="$t('dictionary:template:basicData:organs')" name="organs"> <el-tab-pane :label="$t('dictionary:template:basicData:organs')" name="organs">
<OrgansTbl <OrgansTbl :criterion-id="criterionId" :is-complete-config="isCompleteConfig" />
:criterion-id="criterionId"
:is-complete-config="isCompleteConfig"
/>
</el-tab-pane> </el-tab-pane>
<!-- 疗效评估 --> <!-- 疗效评估 -->
<el-tab-pane :label="$t('dictionary:template:basicData:efficacyAssessment')" name="efficacyAssessment"> <el-tab-pane :label="$t('dictionary:template:basicData:efficacyAssessment')" name="efficacyAssessment">
<EfficacyAssessment <EfficacyAssessment v-if="tabs.includes('efficacyAssessment')" :criterion-id="criterionId"
v-if="tabs.includes('efficacyAssessment')" :criterion-type="criterionType" :is-complete-config="isCompleteConfig" />
:criterion-id="criterionId"
:criterion-type="criterionType"
:is-complete-config="isCompleteConfig"
/>
</el-tab-pane> </el-tab-pane>
<!-- 标准字典 --> <!-- 标准字典 -->
<el-tab-pane :label="$t('dictionary:template:basicData:criterionDictionary')" name="criterionDictionary"> <el-tab-pane :label="$t('dictionary:template:basicData:criterionDictionary')" name="criterionDictionary">
<CriterionDictionary <CriterionDictionary v-if="tabs.includes('criterionDictionary')" :criterion-id="criterionId"
v-if="tabs.includes('criterionDictionary')" :is-complete-config="isCompleteConfig" />
:criterion-id="criterionId" </el-tab-pane>
:is-complete-config="isCompleteConfig" <!-- 关键文件 -->
/> <el-tab-pane :label="$t('dictionary:template:basicData:keyDocument')" name="keyDocument">
<KeyDocument v-if="tabs.includes('keyDocument')" :criterion-id="criterionId"
:is-complete-config="isCompleteConfig" />
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</template> </template>
@ -31,9 +26,10 @@
import OrgansTbl from './OrgansTbl' import OrgansTbl from './OrgansTbl'
import EfficacyAssessment from './EfficacyAssessment' import EfficacyAssessment from './EfficacyAssessment'
import CriterionDictionary from './CriterionDictionary' import CriterionDictionary from './CriterionDictionary'
import KeyDocument from './KeyDocument'
export default { export default {
name: 'CriterionsBaseData', name: 'CriterionsBaseData',
components: { OrgansTbl, EfficacyAssessment, CriterionDictionary }, components: { OrgansTbl, EfficacyAssessment, CriterionDictionary, KeyDocument },
props: { props: {
criterionId: { criterionId: {
type: String, type: String,

View File

@ -1,6 +1,6 @@
<template> <template>
<div style="position: relative"> <div style="position: relative">
<el-form size="small" :inline="true" style="position: relative;"> <el-form size="small" :inline="true" style="position: relative;">
<!-- 阅片规则 --> <!-- 阅片规则 -->
<el-divider content-position="left">{{ $t('dictionary:template:globalConfig:readingRules') }}</el-divider> <el-divider content-position="left">{{ $t('dictionary:template:globalConfig:readingRules') }}</el-divider>
<!-- 是否必须全局阅片 --> <!-- 是否必须全局阅片 -->
@ -8,68 +8,38 @@
{{ $fd('YesOrNo', IsMustGlobalReading) }} {{ $fd('YesOrNo', IsMustGlobalReading) }}
</el-form-item> </el-form-item>
<!-- 配置 --> <!-- 配置 -->
<el-button <el-button size="mini" type="primary" style="position: absolute;right: 10px;top: 15px"
size="mini" v-if="Object.keys(data).length > 0 && !(data.IsCompleteConfig || data.IsBeUsed)" @click="handleAdd(1)">
type="primary"
style="position: absolute;right: 10px;top: 15px"
v-if="Object.keys(data).length > 0 && !(data.IsCompleteConfig || data.IsBeUsed)"
@click="handleAdd(1)"
>
{{ $t('dictionary:template:globalConfig:config') }} {{ $t('dictionary:template:globalConfig:config') }}
</el-button> </el-button>
</el-form> </el-form>
<el-form size="small" :inline="true" style="position: relative"> <el-form size="small" :inline="true" style="position: relative">
<!-- 名称 --> <!-- 名称 -->
<el-divider content-position="left">{{ $t('dictionary:template:globalConfig:name') }}</el-divider> <el-divider content-position="left">{{ $t('dictionary:template:globalConfig:name') }}</el-divider>
<!-- 配置 --> <!-- 配置 -->
<el-button <el-button size="mini" type="primary" style="position: absolute;right: 10px;top: 15px"
size="mini" v-if="Object.keys(data).length > 0 && !(data.IsCompleteConfig || data.IsBeUsed)" @click="handleAdd(2)">
type="primary"
style="position: absolute;right: 10px;top: 15px"
v-if="Object.keys(data).length > 0 && !(data.IsCompleteConfig || data.IsBeUsed)"
@click="handleAdd(2)"
>
{{ $t('dictionary:template:globalConfig:config') }} {{ $t('dictionary:template:globalConfig:config') }}
</el-button> </el-button>
<!-- 评估更新类型 --> <!-- 评估更新类型 -->
<el-form-item :label="$t('dictionary:template:globalConfig:updateType')" style="width: 100%"> <el-form-item :label="$t('dictionary:template:globalConfig:updateType')" style="width: 100%">
</el-form-item> </el-form-item>
<el-table <el-table v-loading="loading" style="width: 100%" :data="list" stripe>
v-loading="loading"
style="width: 100%"
:data="list"
stripe
>
<!-- 序号 --> <!-- 序号 -->
<el-table-column <el-table-column prop="" :label="$t('dictionary:template:globalConfig:order')" width="80">
prop=""
:label="$t('dictionary:template:globalConfig:order')"
width="80"
>
<template slot-scope="scope"> <template slot-scope="scope">
{{scope.$index + 1}} {{ scope.$index + 1 }}
</template> </template>
</el-table-column> </el-table-column>
<!-- 中文值 --> <!-- 中文值 -->
<el-table-column <el-table-column prop="ValueCN" :label="$t('dictionary:template:globalConfig:valueCN')" show-overflow-tooltip>
prop="ValueCN"
:label="$t('dictionary:template:globalConfig:valueCN')"
show-overflow-tooltip
>
</el-table-column> </el-table-column>
<!-- 英文值 --> <!-- 英文值 -->
<el-table-column <el-table-column prop="Value" :label="$t('dictionary:template:globalConfig:value')" show-overflow-tooltip>
prop="Value"
:label="$t('dictionary:template:globalConfig:value')"
show-overflow-tooltip
>
</el-table-column> </el-table-column>
<!-- 是否基线评估 --> <!-- 是否基线评估 -->
<el-table-column <el-table-column prop="IsBaseLineUse" :label="$t('dictionary:template:globalConfig:isBaseLineUse')"
prop="IsBaseLineUse" show-overflow-tooltip>
:label="$t('dictionary:template:globalConfig:isBaseLineUse')"
show-overflow-tooltip
>
<template slot-scope="scope"> <template slot-scope="scope">
<!-- <el-switch--> <!-- <el-switch-->
<!-- @change="(v) => {BaseLineUseChange(v, scope.row)}"--> <!-- @change="(v) => {BaseLineUseChange(v, scope.row)}"-->
@ -81,92 +51,64 @@
</template> </template>
</el-table-column> </el-table-column>
<!-- 是否随访评估 --> <!-- 是否随访评估 -->
<el-table-column <el-table-column prop="IsFollowVisitUse" :label="$t('dictionary:template:globalConfig:isFollowVisitUse')"
prop="IsFollowVisitUse" show-overflow-tooltip>
:label="$t('dictionary:template:globalConfig:isFollowVisitUse')"
show-overflow-tooltip
>
<template slot-scope="scope"> <template slot-scope="scope">
<!-- <el-switch--> <!-- <el-switch-->
<!-- @change="(v) => {FollowVisitUseChange(v, scope.row)}"--> <!-- @change="(v) => {FollowVisitUseChange(v, scope.row)}"-->
<!-- v-model="scope.row.IsFollowVisitUse"--> <!-- v-model="scope.row.IsFollowVisitUse"-->
<!-- >--> <!-- >-->
<!-- </el-switch>--> <!-- </el-switch>-->
<el-tag v-if="scope.row.IsFollowVisitUse" type="primary">{{ $fd('YesOrNo', scope.row.IsFollowVisitUse) }}</el-tag> <el-tag v-if="scope.row.IsFollowVisitUse" type="primary">{{ $fd('YesOrNo', scope.row.IsFollowVisitUse)
}}</el-tag>
<el-tag v-else type="danger">{{ $fd('YesOrNo', scope.row.IsFollowVisitUse) }}</el-tag> <el-tag v-else type="danger">{{ $fd('YesOrNo', scope.row.IsFollowVisitUse) }}</el-tag>
<!-- <span>{{$fd('YesOrNo', scope.row.IsFollowVisitUse)}}</span>--> <!-- <span>{{$fd('YesOrNo', scope.row.IsFollowVisitUse)}}</span>-->
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-form> </el-form>
<base-model <base-model :config="config">
:config="config"
>
<template slot="dialog-body"> <template slot="dialog-body">
<el-form size="small" :inline="true" label-width="130px"> <el-form size="small" :inline="true" label-width="130px">
<!-- 是否必须全局阅片 --> <!-- 是否必须全局阅片 -->
<el-form-item :label="$t('dictionary:template:globalConfig:isMustGlobalReading')" v-if="config.configType === 1"> <el-form-item :label="$t('dictionary:template:globalConfig:isMustGlobalReading')"
v-if="config.configType === 1">
<el-radio-group v-model="form.IsMustGlobalReading"> <el-radio-group v-model="form.IsMustGlobalReading">
<el-radio v-for="item of $d.YesOrNo" :key="'form.IsMustGlobalReading' + item.value" :label="item.value">{{ item.label }}</el-radio> <el-radio v-for="item of $d.YesOrNo" :key="'form.IsMustGlobalReading' + item.value" :label="item.value">{{
item.label }}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<!-- 评估更新类型 --> <!-- 评估更新类型 @selection-change="handleSelectionChange"-->
<el-form-item v-if="config.configType === 2" :label="$t('dictionary:template:globalConfig:updateType')" style="width: 100%"> <el-form-item v-if="config.configType === 2" :label="$t('dictionary:template:globalConfig:updateType')"
style="width: 100%">
</el-form-item> </el-form-item>
<el-table <el-table v-if="config.configType === 2" v-loading="loading" ref="multipleTable" :data="GlobalAssessType"
v-if="config.configType === 2" stripe>
v-loading="loading" <!-- <el-table-column type="selection" width="55">
ref="multipleTable" </el-table-column> -->
:data="GlobalAssessType"
stripe
@selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
width="55">
</el-table-column>
<!-- 中文值 --> <!-- 中文值 -->
<el-table-column <el-table-column prop="ValueCN" :label="$t('dictionary:template:globalConfig:valueCN')"
prop="ValueCN" show-overflow-tooltip>
:label="$t('dictionary:template:globalConfig:valueCN')"
show-overflow-tooltip
>
</el-table-column> </el-table-column>
<!-- 英文值 --> <!-- 英文值 -->
<el-table-column <el-table-column prop="Value" :label="$t('dictionary:template:globalConfig:value')" show-overflow-tooltip>
prop="Value"
:label="$t('dictionary:template:globalConfig:value')"
show-overflow-tooltip
>
</el-table-column> </el-table-column>
<!-- 是否基线评估 --> <!-- 是否基线评估 -->
<el-table-column <el-table-column prop="IsBaseLineUse" :label="$t('dictionary:template:globalConfig:isBaseLineUse')"
prop="IsBaseLineUse" show-overflow-tooltip>
:label="$t('dictionary:template:globalConfig:isBaseLineUse')"
show-overflow-tooltip
>
<template slot-scope="scope"> <template slot-scope="scope">
<el-switch <el-switch v-model="scope.row.IsBaseLineUse" @change="() => $forceUpdate()">
v-model="scope.row.IsBaseLineUse"
@change="() => $forceUpdate()"
>
</el-switch> </el-switch>
<span>{{$fd('YesOrNo', scope.row.IsBaseLineUse)}}</span> <span>{{ $fd('YesOrNo', scope.row.IsBaseLineUse) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<!-- 是否随访评估 --> <!-- 是否随访评估 -->
<el-table-column <el-table-column prop="IsFollowVisitUse" :label="$t('dictionary:template:globalConfig:isFollowVisitUse')"
prop="IsFollowVisitUse" show-overflow-tooltip>
:label="$t('dictionary:template:globalConfig:isFollowVisitUse')"
show-overflow-tooltip
>
<template slot-scope="scope"> <template slot-scope="scope">
<el-switch <el-switch v-model="scope.row.IsFollowVisitUse" @change="() => $forceUpdate()">
v-model="scope.row.IsFollowVisitUse"
@change="() => $forceUpdate()"
>
</el-switch> </el-switch>
<span>{{$fd('YesOrNo', scope.row.IsFollowVisitUse)}}</span> <span>{{ $fd('YesOrNo', scope.row.IsFollowVisitUse) }}</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -226,7 +168,7 @@ export default {
mounted() { mounted() {
this.getList() this.getList()
this.getSystemGlobalInfo() this.getSystemGlobalInfo()
this.getCriterionDictionary() // this.getCriterionDictionary()
}, },
methods: { methods: {
getCriterionDictionary() { getCriterionDictionary() {
@ -241,12 +183,12 @@ export default {
getSystemGlobalInfo({ getSystemGlobalInfo({
SystemCriterionId: this.criterionId SystemCriterionId: this.criterionId
}).then(res => { }).then(res => {
this.GlobalAssessType = res.Result.DictionaryList
}) })
}, },
FollowVisitUseChange(v, row) { FollowVisitUseChange(v, row) {
this.loading = true this.loading = true
setDictionaryFollowVisitUse({Id:row.Id, IsFollowVisitUse: v}).then(res => { setDictionaryFollowVisitUse({ Id: row.Id, IsFollowVisitUse: v }).then(res => {
this.$message.success(this.$t('common:message:savedSuccessfully')) this.$message.success(this.$t('common:message:savedSuccessfully'))
this.loading = false this.loading = false
}).catch(() => { }).catch(() => {
@ -255,7 +197,7 @@ export default {
}, },
BaseLineUseChange(v, row) { BaseLineUseChange(v, row) {
this.loading = true this.loading = true
setDictionaryBaseLineUse({Id:row.Id, isBaseLineUse: v}).then(res => { setDictionaryBaseLineUse({ Id: row.Id, isBaseLineUse: v }).then(res => {
this.$message.success(this.$t('common:message:savedSuccessfully')) this.$message.success(this.$t('common:message:savedSuccessfully'))
this.loading = false this.loading = false
}).catch(() => { }).catch(() => {
@ -273,6 +215,7 @@ export default {
} }
}, },
handleSelectionChange(val) { handleSelectionChange(val) {
console.log(this.selectedList, 'this.selectedList')
this.selectedList = val this.selectedList = val
}, },
getList() { getList() {
@ -295,18 +238,6 @@ export default {
} else { } else {
this.config.title = this.$t('dictionary:template:globalConfig:updateType') this.config.title = this.$t('dictionary:template:globalConfig:updateType')
this.config.visible = true this.config.visible = true
this.$nextTick(() => {
var a = this.$d.GlobalAssessType.filter(v => {
return !!this.list.find(v1 => {
if (v.id === v1.DictionaryId) {
v.IsBaseLineUse = v1.IsBaseLineUse
v.IsFollowVisitUse = v1.IsFollowVisitUse
}
return v1.DictionaryId === v.id
})
})
this.toggleSelection(a)
})
} }
}, },
handleSave() { handleSave() {
@ -319,11 +250,11 @@ export default {
var params = { var params = {
SystemCriterionId: this.criterionId, SystemCriterionId: this.criterionId,
IsMustGlobalReading: this.form.IsMustGlobalReading, IsMustGlobalReading: this.form.IsMustGlobalReading,
DictionaryList: this.config.configType === 1 ? this.list : this.selectedList.map(v => { DictionaryList: this.config.configType === 1 ? this.list : this.GlobalAssessType.map(v => {
return { return {
DictionaryId: v.id, DictionaryId: v.DictionaryId,
IsBaseLineUse: v.IsBaseLineUse, IsBaseLineUse: v.IsBaseLineUse ? v.IsBaseLineUse : false,
IsFollowVisitUse: v.IsFollowVisitUse, IsFollowVisitUse: v.IsFollowVisitUse ? v.IsFollowVisitUse : false,
} }
}), }),
} }
@ -342,5 +273,3 @@ export default {
} }
} }
</script> </script>

View File

@ -0,0 +1,286 @@
<template>
<BaseContainer>
<!-- 搜索框 -->
<template slot="search-container">
<el-form :inline="true" size="mini">
<el-form-item :label="$t('dictionary:template:keyDocList:FileName')">
<el-input clearable v-model="searchData.FileName"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleSearch">
{{ $t('common:button:search') }}
</el-button>
<el-button type="primary" icon="el-icon-refresh-left" size="mini" @click="handleReset">
{{ $t('common:button:reset') }}
</el-button>
</el-form-item>
<el-form-item>
<div class="upload">
<input directory accept=".pdf" type="file" name="uploadFolder" class="select-file" title=""
@change="beginScanFiles($event)" />
<div class="btn-select">
{{ $t('dictionary:template:basicData:button:selectFile') }}
</div>
</div>
</el-form-item>
</el-form>
</template>
<template slot="main-container">
<div class="drag" ref="drag" @dragover="handleDragover" @drop="handleDrop">
<el-table ref="keyDocList" v-loading="loading" v-adaptive="{ bottomOffset: 80 }" :data="list"
width="100%" style="width: 100%;min-width: 300px" stripe height="100"
@sort-change="handleSortByColumn">
<el-table-column type="index" min-width="90" />
<el-table-column prop="FileName" :label="$t('dictionary:template:keyDocList:FileName')"
show-overflow-tooltip />
<el-table-column prop="CreateTime" :label="$t('dictionary:template:keyDocList:CreateTime')"
show-overflow-tooltip />
<el-table-column :label="$t('common:action:action')" align="left" fixed="right">
<template slot-scope="scope">
<el-button circle icon="el-icon-view"
:title="$t('dictionary:template:keyDocList:button:view')"
@click.stop="view(scope.row)" />
<el-button circle icon="el-icon-delete"
:title="$t('dictionary:template:keyDocList:button:del')" @click.stop="del(scope.row)" />
</template>
</el-table-column>
</el-table>
</div>
<!-- 分页组件 -->
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
@pagination="getList" />
</template>
</BaseContainer>
</template>
<script>
import { Upload } from '@/api/dictionary'
import BaseContainer from '@/components/BaseContainer'
import Pagination from '@/components/Pagination'
import { getSystemCriterionKeyFileList, addOrUpdateSystemCriterionKeyFile, deleteSystemCriterionKeyFile } from '@/api/dictionary'
import { readEntry } from '@/utils/index'
const searchDataDefault = () => {
return {
FileName: '',
PageIndex: 1,
PageSize: 20,
Asc: false,
SortField: ''
}
}
export default {
name: "KeyDocument",
components: { BaseContainer, Pagination },
props: {
criterionId: {
type: String,
required: true
},
isCompleteConfig: {
type: Boolean,
required: true
},
},
data() {
return {
searchData: searchDataDefault(),
loading: false,
list: [],
total: 0,
}
},
mounted() {
this.getList()
},
methods: {
handleDragover(e) {
e.stopPropagation();
e.preventDefault();
},
handleDrop(e) {
e.stopPropagation();
e.preventDefault();
this.beginScanFiles(e, true)
},
beforeUpload(file) {
//
if (this.checkFileSuffix(file.name)) {
this.fileList = [];
return true;
} else {
// this.$alert("word/excel");
this.$alert(this.$t("dictionary:attachment:export:alert:formatFile"));
return false;
}
},
async beginScanFiles(e, isDrop = false) {
try {
this.loading = true;
let files = []
if (isDrop) {
const items = e.dataTransfer.items;
const allFiles = []; //
//
for (const item of items) {
const entry = item.webkitGetAsEntry(); //
if (entry) {
const files = await readEntry(entry); //
allFiles.push(...files);
}
}
files = allFiles
} else {
files = [...e.target.files]
}
for (let i = 0; i < files.length; i++) {
let file = files[i]
if (!this.checkFileSuffix(file.name)) continue
const formData = new FormData();
formData.append("file", file);
let res = await Upload(formData, 5)
let data = {
FilePath: res.Result.FilePath,
FileName: file.name
}
await this.addKeyDoc(data)
}
} catch (err) {
console.log(err)
this.loading = false;
}
},
checkFileSuffix(fileName) {
var index = fileName.lastIndexOf('.')
var suffix = fileName.substring(index + 1, fileName.length)
if ('.pdf'.toLocaleLowerCase().search(suffix.toLocaleLowerCase()) === -1) {
return false
} else {
return true
}
},
async getList() {
try {
this.searchData.SystemCriterionId = this.criterionId
this.loading = true
let res = await getSystemCriterionKeyFileList(this.searchData)
this.loading = false
if (res.IsSuccess) {
this.list = res.Result.CurrentPageData
this.total = res.Result.TotalCount
}
} catch (err) {
this.loading = false
console.log(err)
}
},
async addKeyDoc(row) {
try {
let { FileName, FilePath } = row
let data = {
FileName,
FilePath,
SystemCriterionId: this.criterionId
}
this.loading = true
let res = await addOrUpdateSystemCriterionKeyFile(data)
this.loading = false
if (res.IsSuccess) {
this.getList()
}
} catch (err) {
this.loading = false
console.log(err)
}
},
async del(row) {
try {
this.loading = true
let res = await deleteSystemCriterionKeyFile(row.Id)
this.loading = false
if (res.IsSuccess) {
this.getList()
}
} catch (err) {
console.log(err)
this.loading = false
}
},
view(row) {
this.$preview({
path: row.FilePath,
type: 'pdf',
isLocal: true,
title: row.FileName,
})
},
//
handleSearch() {
this.searchData.PageIndex = 1
this.getList()
},
//
handleReset() {
this.searchData = searchDataDefault()
this.getList()
},
//
handleSortByColumn(column) {
if (column.order === 'ascending') {
this.searchData.Asc = true
} else {
this.searchData.Asc = false
}
this.searchData.SortField = column.prop
this.searchData.PageIndex = 1
this.getList()
}
}
}
</script>
<style lang="scss" scoped>
.upload {
display: inline-block;
height: 30px;
width: 90px;
padding: 2px 10px;
line-height: 23px;
position: relative;
text-decoration: none;
border-radius: 3px;
overflow: hidden;
text-align: center;
background: #428bca;
border-color: #428bca;
color: #fff;
.select-file {
height: 30px;
width: 90px;
position: absolute;
overflow: hidden;
left: 0;
top: 0;
opacity: 0;
font-size: 0;
}
.btn-select {
//
width: 90px;
height: 30px;
line-height: 30px;
text-align: center;
cursor: pointer;
border-radius: 24px;
overflow: hidden;
position: absolute;
top: 0;
left: 0;
pointer-events: none; //pointer-events:none穿
}
}
</style>

View File

@ -1,155 +1,86 @@
<template> <template>
<el-form <el-form ref="tableQsForm" v-loading="loading" :model="form" size="small" :disabled="type === 'look'" :rules="rules"
ref="tableQsForm" label-width="130px">
v-loading="loading"
:model="form"
size="small"
:disabled="type === 'look'"
:rules="rules"
label-width="130px"
>
<div class="base-dialog-body" style="height: 550px; display:flex;flex-direction: column;"> <div class="base-dialog-body" style="height: 550px; display:flex;flex-direction: column;">
<div style="height: 150px;"> <div style="height: 150px;">
<!-- 类型 --> <!-- 类型 -->
<el-form-item :label="$t('trials:readingUnit:qsList:title:type')" prop="Type"> <el-form-item :label="$t('trials:readingUnit:qsList:title:type')" prop="Type">
<el-select <el-select v-model="form.Type" @change="((val) => { qsTypeChange(val, form) })">
v-model="form.Type" <el-option v-for="item of $d.Criterion_Question_Type"
@change="((val)=>{qsTypeChange(val, form)})"
>
<el-option
v-for="item of $d.Criterion_Question_Type"
v-show="item.value !== 'class' && item.value !== 'group' && item.value !== 'table' && item.value !== 'basicTable'" v-show="item.value !== 'class' && item.value !== 'group' && item.value !== 'table' && item.value !== 'basicTable'"
:key="item.value" :key="item.value" :value="item.value" :label="item.label" />
:value="item.value"
:label="item.label"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 问题名称 --> <!-- 问题名称 -->
<el-form-item <el-form-item v-if="form.Type !== 'group'" :label="$t('trials:readingUnit:qsList:title:qsNameEn')"
v-if="form.Type !== 'group'" prop="QuestionName" :rules="[
:label="$t('trials:readingUnit:qsList:title:qsNameEn')"
prop="QuestionName"
:rules="[
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' }, { required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' },
{ max: form.Type === 'summary' ? 300 : 100, message: `${this.$t('common:ruleMessage:maxLength')} ${form.Type === 'summary' ? 300 : 100}` } { max: form.Type === 'summary' ? 300 : 100, message: `${this.$t('common:ruleMessage:maxLength')} ${form.Type === 'summary' ? 300 : 100}` }
]" ]">
> <el-input v-model="form.QuestionName" />
<el-input
v-model="form.QuestionName"
/>
</el-form-item> </el-form-item>
<!-- 问题名称EN --> <!-- 问题名称EN -->
<el-form-item <el-form-item v-if="form.Type !== 'group'" :label="$t('trials:readingUnit:qsList:title:qsNameEn')"
v-if="form.Type !== 'group'" prop="QuestionEnName" :rules="[
:label="$t('trials:readingUnit:qsList:title:qsNameEn')"
prop="QuestionEnName"
:rules="[
{ max: form.Type === 'summary' ? 300 : 100, message: `${this.$t('common:ruleMessage:maxLength')} ${form.Type === 'summary' ? 300 : 100}` } { max: form.Type === 'summary' ? 300 : 100, message: `${this.$t('common:ruleMessage:maxLength')} ${form.Type === 'summary' ? 300 : 100}` }
]" ]">
> <el-input v-model="form.QuestionEnName" />
<el-input
v-model="form.QuestionEnName"
/>
</el-form-item> </el-form-item>
</div> </div>
<div style="flex: 1;overflow-y:auto;"> <div style="flex: 1;overflow-y:auto;">
<!-- 公有属性 --> <!-- 公有属性 -->
<el-divider content-position="left">{{$t('trials:readingUnit:title:publicProperties')}}</el-divider> <el-divider content-position="left">{{ $t('trials:readingUnit:title:publicProperties') }}</el-divider>
<!-- 是否显示 --> <!-- 是否显示 -->
<el-form-item v-if="form.Type !== 'group'" :label="$t('trials:readingUnit:qsList:title:isShow')" prop="ShowQuestion"> <el-form-item v-if="form.Type !== 'group'" :label="$t('trials:readingUnit:qsList:title:isShow')"
<el-radio-group prop="ShowQuestion">
v-model="form.ShowQuestion" <el-radio-group v-model="form.ShowQuestion" @change="((val) => { isShowQuestionChange(val, form) })">
@change="((val)=>{isShowQuestionChange(val, form)})" <el-radio v-for="item of $d.ShowQuestion" :key="`ShowQuestion${item.value}`" :label="item.value">
>
<el-radio
v-for="item of $d.ShowQuestion"
:key="`ShowQuestion${item.value}`"
:label="item.value"
>
{{ item.label }} {{ item.label }}
</el-radio> </el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<!-- 显示时依赖父问题 --> <!-- 显示时依赖父问题 -->
<el-form-item <el-form-item v-if="form.Type !== 'group' && form.ShowQuestion === 1"
v-if="form.Type !== 'group' && form.ShowQuestion===1" :label="$t('trials:readingUnit:qsList:title:parentId')" prop="ParentId">
:label="$t('trials:readingUnit:qsList:title:parentId')" <el-select v-model="form.ParentId" clearable @change="((val) => { parentQuestionChange(val, form) })">
prop="ParentId" <el-option v-for="item of parentOptions" :key="`ParentId${item.QuestionId}`" :label="item.QuestionName"
> :value="item.QuestionId" />
<el-select
v-model="form.ParentId"
clearable
@change="((val)=>{parentQuestionChange(val, form)})"
>
<el-option
v-for="item of parentOptions"
:key="`ParentId${item.QuestionId}`"
:label="item.QuestionName"
:value="item.QuestionId"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 显示时依赖父问题触发值 --> <!-- 显示时依赖父问题触发值 -->
<el-form-item v-if="form.ParentId && form.ShowQuestion===1" :label="$t('trials:readingUnit:qsList:title:parentTriggerValueList')" prop="ParentTriggerValueList"> <el-form-item v-if="form.ParentId && form.ShowQuestion === 1"
:label="$t('trials:readingUnit:qsList:title:parentTriggerValueList')" prop="ParentTriggerValueList">
<el-select v-model="form.ParentTriggerValueList" clearable multiple> <el-select v-model="form.ParentTriggerValueList" clearable multiple>
<el-option <el-option v-for="item of parentTriggerValOptions" :key="item.id" :label="item.label"
v-for="item of parentTriggerValOptions" :value="String(item.value)" />
:key="item.id"
:label="item.label"
:value="String(item.value)"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 是否必填 --> <!-- 是否必填 -->
<el-form-item v-if="form.Type !== 'group' && form.Type !== 'table' && form.Type !== 'basicTable' && form.Type !== 'summary'" :label="$t('trials:readingUnit:qsList:title:isRequired')" prop="IsRequired"> <el-form-item
<el-radio-group v-if="form.Type !== 'group' && form.Type !== 'table' && form.Type !== 'basicTable' && form.Type !== 'summary'"
v-model="form.IsRequired" :label="$t('trials:readingUnit:qsList:title:isRequired')" prop="IsRequired">
:disabled="form.IsJudgeQuestion===true || form.ShowQuestion===2" <el-radio-group v-model="form.IsRequired" :disabled="form.IsJudgeQuestion === true || form.ShowQuestion === 2"
@change="((val)=>{isRequiredChange(val, form)})" @change="((val) => { isRequiredChange(val, form) })">
> <el-radio v-for="item of $d.QuestionRequired" :key="`QuestionRequired${item.value}`" :label="item.value">
<el-radio
v-for="item of $d.QuestionRequired"
:key="`QuestionRequired${item.value}`"
:label="item.value"
>
{{ item.label }} {{ item.label }}
</el-radio> </el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<!-- 必填依赖父问题 --> <!-- 必填依赖父问题 -->
<el-form-item <el-form-item v-if="form.Type !== 'group' && form.IsRequired === 1"
v-if="form.Type !== 'group' && form.IsRequired === 1" :label="$t('trials:readingUnit:qsList:title:relevanceId')" prop="RelevanceId">
:label="$t('trials:readingUnit:qsList:title:relevanceId')" <el-select v-model="form.RelevanceId" clearable @change="((val) => { relevanceQuestionChange(val, form) })">
prop="RelevanceId" <el-option v-for="item of parentOptions" :key="`RelevanceId${item.QuestionId}`" :label="item.QuestionName"
> :value="item.QuestionId" />
<el-select
v-model="form.RelevanceId"
clearable
@change="((val)=>{relevanceQuestionChange(val, form)})"
>
<el-option
v-for="item of parentOptions"
:key="`RelevanceId${item.QuestionId}`"
:label="item.QuestionName"
:value="item.QuestionId"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 必填触发值 --> <!-- 必填触发值 -->
<el-form-item <el-form-item v-if="form.RelevanceId && form.IsRequired === 1"
v-if="form.RelevanceId && form.IsRequired === 1" :label="$t('trials:readingUnit:qsList:title:relevanceValueList')" prop="RelevanceValueList">
:label="$t('trials:readingUnit:qsList:title:relevanceValueList')"
prop="RelevanceValueList"
>
<el-select v-model="form.RelevanceValueList" clearable multiple> <el-select v-model="form.RelevanceValueList" clearable multiple>
<el-option <el-option v-for="item of reParentTriggerValOptions" :key="item.id" :label="item.label"
v-for="item of reParentTriggerValOptions" :value="String(item.value)" />
:key="item.id"
:label="item.label"
:value="String(item.value)"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 导出标识 --> <!-- 导出标识 -->
@ -174,175 +105,95 @@
</el-radio-group> </el-radio-group>
</el-form-item> --> </el-form-item> -->
<!-- 导出结果 --> <!-- 导出结果 -->
<el-form-item <el-form-item :label="$t('trials:readingUnit:qsList:title:ExportResult')"
:label="$t('trials:readingUnit:qsList:title:ExportResult')" v-if="form.Type === 'radio' || form.Type === 'select' || form.Type === 'input' || form.Type === 'textarea' || form.Type === 'number' || form.Type === 'class' || form.Type === 'calculation'">
v-if="form.Type === 'radio' || form.Type === 'select' || form.Type === 'input' || form.Type === 'textarea' || form.Type === 'number' || form.Type === 'class' || form.Type === 'calculation'"
>
<el-select v-model="form.ExportResult" multiple> <el-select v-model="form.ExportResult" multiple>
<el-option <el-option v-for="item in CriterionDictionaryList.ExportResult" :key="`ExportResult${item.value}`"
v-for="item in CriterionDictionaryList.ExportResult" :value="parseInt(item.Code)" :label="$i18n.locale === 'zh' ? item.ValueCN : item.Value">
:key="`ExportResult${item.value}`"
:value="parseInt(item.Code)"
:label="$i18n.locale === 'zh' ? item.ValueCN : item.Value"
>
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 限制编辑 --> <!-- 限制编辑 -->
<el-form-item <el-form-item :label="$t('trials:readingUnit:qsList:title:limitEdit')" v-if="form.Type !== 'summary'"
:label="$t('trials:readingUnit:qsList:title:limitEdit')" prop="LimitEdit" :rules="[
v-if="form.Type !== 'summary'"
prop="LimitEdit"
:rules="[
{ required: true, message: this.$t('common:ruleMessage:select'), trigger: 'blur' } { required: true, message: this.$t('common:ruleMessage:select'), trigger: 'blur' }
]" ]">
>
<el-radio-group v-model="form.LimitEdit"> <el-radio-group v-model="form.LimitEdit">
<el-radio v-for="item of $d.LimitEdit" :key="item.value" :label="item.value">{{ item.label }}</el-radio> <el-radio v-for="item of $d.LimitEdit" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<!-- 问题标识 --> <!-- 问题标识 -->
<el-form-item <el-form-item v-if="form.Type !== 'group' && form.Type !== 'summary'"
v-if="form.Type !== 'group' && form.Type !== 'summary'" :label="$t('dictionary:template:criterionConfig:table:questionMark')" prop="QuestionMark">
:label="$t('dictionary:template:criterionConfig:table:questionMark')" <el-select v-model="form.QuestionMark" clearable>
prop="QuestionMark" <el-option v-for="item of CriterionDictionaryList.QuestionMark" :key="item.Id" :value="parseInt(item.Code)"
> :label="$i18n.locale === 'zh' ? item.ValueCN : item.Value" />
<el-select
v-model="form.QuestionMark"
clearable
>
<el-option
v-for="item of CriterionDictionaryList.QuestionMark"
:key="item.Id"
:value="parseInt(item.Code)"
:label="$i18n.locale === 'zh' ? item.ValueCN : item.Value"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 注释 --> <!-- 注释 -->
<el-form-item <el-form-item :label="$t('trials:readingUnit:qsList:title:Remark')" prop="Remark">
:label="$t('trials:readingUnit:qsList:title:Remark')"
prop="Remark"
>
<el-input v-model="form.Remark" /> <el-input v-model="form.Remark" />
</el-form-item> </el-form-item>
<!-- 序号 --> <!-- 序号 -->
<el-form-item <el-form-item :label="$t('trials:readingUnit:qsList:title:order')" prop="ShowOrder" :rules="[
:label="$t('trials:readingUnit:qsList:title:order')" { required: true, message: this.$t('common:ruleMessage:select'), trigger: 'blur' }
prop="ShowOrder" ]">
:rules="[ <el-input-number v-model="form.ShowOrder" controls-position="right" :min="0" />
{ required: true, message: this.$t('common:ruleMessage:select'), trigger: 'blur' }
]"
>
<el-input-number
v-model="form.ShowOrder"
controls-position="right"
:min="0"
/>
</el-form-item> </el-form-item>
<!-- 重复出现最大次数 --> <!-- 重复出现最大次数 -->
<el-form-item :label="$t('dictionary:template:criterionConfig:table:maxRowCount')" v-if="form.Type !== 'summary' && form.Type !== 'screenshot' && form.Type !== 'upload'"> <el-form-item :label="$t('dictionary:template:criterionConfig:table:maxRowCount')"
<el-input-number v-if="form.Type !== 'summary' && form.Type !== 'screenshot' && form.Type !== 'upload'">
v-model="form.MaxRowCount" <el-input-number v-model="form.MaxRowCount" controls-position="right" :min="0" :max="10" />
controls-position="right"
:min="0"
:max="10"
/>
</el-form-item> </el-form-item>
<!-- 问题分类 --> <!-- 问题分类 -->
<el-form-item :label="$t('dictionary:template:criterionConfig:table:questionClassify')" v-if="criterionType === 2"> <el-form-item :label="$t('dictionary:template:criterionConfig:table:questionClassify')"
v-if="criterionType === 2">
<el-select v-model="form.QuestionClassify" clearable> <el-select v-model="form.QuestionClassify" clearable>
<el-option <el-option v-for="item of $d.QuestionClassify" :key="item.id" :label="item.label" :value="item.value" />
v-for="item of $d.QuestionClassify"
:key="item.id"
:label="item.label"
:value="item.value"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 私有属性 --> <!-- 私有属性 -->
<el-divider content-position="left">{{$t('trials:readingUnit:title:privateProperties')}}</el-divider> <el-divider content-position="left">{{ $t('trials:readingUnit:title:privateProperties') }}</el-divider>
<!-- 选项类型 --> <!-- 选项类型 -->
<el-form-item <el-form-item v-if="form.Type === 'select' || form.Type === 'radio' || form.Type === 'input'"
v-if="form.Type === 'select' || form.Type === 'radio' || form.Type === 'input'" :label="$t('trials:readingUnit:label:QuestionGenre')" prop="TableQuestionType" :rules="[
:label="$t('trials:readingUnit:label:QuestionGenre')" { required: form.Type !== 'input', message: this.$t('common:ruleMessage:select') }
prop="TableQuestionType" ]">
:rules="[ <el-radio-group v-model="form.TableQuestionType" @change="((val) => { tableQuestionTypeChange(val, form) })">
{ required: form.Type !== 'input', message: this.$t('common:ruleMessage:select')} <el-radio v-for="item of $d.TableQuestionType" :key="item.id" :label="item.value"
]" :disabled="(form.Type === 'radio' && (item.value === 1 || item.value === 2)) || (form.Type === 'input' && (item.value === 0 || item.value === 3))">
>
<el-radio-group
v-model="form.TableQuestionType"
@change="((val)=>{tableQuestionTypeChange(val, form)})"
>
<el-radio
v-for="item of $d.TableQuestionType"
:key="item.id"
:label="item.value"
:disabled="(form.Type === 'radio' && (item.value===1 || item.value===2)) || (form.Type === 'input' && (item.value===0 || item.value===3))"
>
{{ item.label }} {{ item.label }}
</el-radio> </el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<!-- 选项 --> <!-- 选项 -->
<el-form-item <el-form-item v-if="form.TableQuestionType === 0 || form.Type === 'class'"
v-if="form.TableQuestionType === 0 || form.Type === 'class'" :label="$t('trials:qcCfg:table:typeValue')" prop="TypeValue">
:label="$t('trials:qcCfg:table:typeValue')" <el-input v-model="form.TypeValue" :placeholder="$t('trials:qcCfg:message:typeValue')"
prop="TypeValue" @change="typeValueChange" />
>
<el-input
v-model="form.TypeValue"
:placeholder="$t('trials:qcCfg:message:typeValue')"
@change="typeValueChange"
/>
</el-form-item> </el-form-item>
<!-- 关联问题 --> <!-- 关联问题 -->
<el-form-item <el-form-item v-if="form.TableQuestionType === 2"
v-if="form.TableQuestionType === 2" :label="$t('dictionary:template:criterionConfig:table:dependParentId')" prop="DependParentId">
:label="$t('dictionary:template:criterionConfig:table:dependParentId')" <el-select v-model="form.DependParentId">
prop="DependParentId" <el-option v-for="item of parentOptions" :key="`DependParentId${item.QuestionId}`"
> :label="item.QuestionName" :value="item.QuestionId" />
<el-select
v-model="form.DependParentId"
>
<el-option
v-for="item of parentOptions"
:key="`DependParentId${item.QuestionId}`"
:label="item.QuestionName"
:value="item.QuestionId"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 关联字段 --> <!-- 关联字段 -->
<el-form-item <el-form-item v-if="form.TableQuestionType === 1 || !!form.DependParentId"
v-if="form.TableQuestionType === 1 || !!form.DependParentId" :label="$t('dictionary:template:criterionConfig:table:dataTableColumn')" prop="DataTableColumn">
:label="$t('dictionary:template:criterionConfig:table:dataTableColumn')"
prop="DataTableColumn"
>
<el-select v-model="form.DataTableColumn"> <el-select v-model="form.DataTableColumn">
<el-option <el-option v-for="item of CriterionDictionaryList.OrganColumn" :key="item.Id"
v-for="item of CriterionDictionaryList.OrganColumn" :label="$i18n.locale === 'zh' ? item.ValueCN : item.Value" :value="item.Code" />
:key="item.Id"
:label="$i18n.locale === 'zh' ? item.ValueCN : item.Value"
:value="item.Code"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 关联字典 --> <!-- 关联字典 -->
<el-form-item <el-form-item v-if="form.TableQuestionType === 3 || form.TableQuestionType === 2"
v-if="form.TableQuestionType === 3 || form.TableQuestionType === 2" :label="$t('dictionary:template:criterionConfig:table:relatedDictionaryCode')" prop="DictionaryCode"
:label="$t('dictionary:template:criterionConfig:table:relatedDictionaryCode')" :rules="[{ required: form.TableQuestionType === 3, message: '请选择', trigger: 'blur' }]">
prop="DictionaryCode"
:rules="[{ required: form.TableQuestionType === 3, message: '请选择', trigger: 'blur' }]"
>
<el-select v-model="form.DictionaryCode"> <el-select v-model="form.DictionaryCode">
<el-option <el-option v-for="item of dicList" :key="item.Id" :label="item.Code" :value="item.Code" />
v-for="item of dicList"
:key="item.Id"
:label="item.Code"
:value="item.Code"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 默认值 --> <!-- 默认值 -->
@ -354,35 +205,23 @@
:label="item.label" :label="item.label"
:value="item.value.toString()" :value="item.value.toString()"
/> --> /> -->
<el-option <el-option v-for="item of highlightAnswers" :key="item.Id"
v-for="item of highlightAnswers" :label="$i18n.locale === 'zh' ? item.ValueCN : item.Value" :value="item.Code" />
:key="item.Id"
:label="$i18n.locale === 'zh' ? item.ValueCN : item.Value"
:value="item.Code"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 默认值 --> <!-- 默认值 -->
<el-form-item v-if="form.TableQuestionType === 0" :label="$t('trials:readingUnit:qsList:title:defaultValue')"> <el-form-item v-if="form.TableQuestionType === 0" :label="$t('trials:readingUnit:qsList:title:defaultValue')">
<el-select v-model="form.DefaultValue" clearable> <el-select v-model="form.DefaultValue" clearable>
<el-option <el-option v-for="item of form.TypeValue ? form.TypeValue.split('|') : []" :key="item" :label="item"
v-for="item of form.TypeValue ? form.TypeValue.split('|') : []" :value="item" />
:key="item"
:label="item"
:value="item"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 高亮标记值 --> <!-- 高亮标记值 -->
<el-form-item v-if="form.Type === 'select' || form.Type === 'radio'" :label="$t('trials:readingUnit:qsList:title:highlightAnswers')" prop="HighlightAnswerList"> <el-form-item v-if="form.Type === 'select' || form.Type === 'radio' || form.Type === 'calculation'"
:label="$t('trials:readingUnit:qsList:title:highlightAnswers')" prop="HighlightAnswerList">
<el-select v-model="form.HighlightAnswerList" clearable multiple> <el-select v-model="form.HighlightAnswerList" clearable multiple>
<template v-if="form.TypeValue"> <template v-if="form.TypeValue">
<el-option <el-option v-for="item of form.TypeValue.split('|')" :key="item" :label="item" :value="item" />
v-for="item of form.TypeValue.split('|')"
:key="item"
:label="item"
:value="item"
/>
</template> </template>
<template v-else-if="form.DictionaryCode"> <template v-else-if="form.DictionaryCode">
<!-- <el-option <!-- <el-option
@ -391,24 +230,16 @@
:label="item.label" :label="item.label"
:value="item.value.toString()" :value="item.value.toString()"
/> --> /> -->
<el-option <el-option v-for="item of highlightAnswers" :key="item.Id"
v-for="item of highlightAnswers" :label="$i18n.locale === 'zh' ? item.ValueCN : item.Value" :value="item.Code" />
:key="item.Id"
:label="$i18n.locale === 'zh' ? item.ValueCN : item.Value"
:value="item.Code"
/>
</template> </template>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 最大长度 --> <!-- 最大长度 -->
<el-form-item <el-form-item v-if="form.Type === 'input' || form.Type === 'textarea'"
v-if="form.Type === 'input' || form.Type === 'textarea'" :label="$t('trials:readingUnit:qsList:title:MaxAnswerLength')" prop="MaxAnswerLength" :rules="[
:label="$t('trials:readingUnit:qsList:title:MaxAnswerLength')"
prop="MaxAnswerLength"
:rules="[
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' } { required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' }
]" ]">
>
<el-input-number v-model="form.MaxAnswerLength" :min="0"></el-input-number> <el-input-number v-model="form.MaxAnswerLength" :min="0"></el-input-number>
</el-form-item> </el-form-item>
<!-- 是否复制前值 --> <!-- 是否复制前值 -->
@ -425,138 +256,82 @@
/> />
</el-form-item> --> </el-form-item> -->
<!-- 数值类型 --> <!-- 数值类型 -->
<el-form-item <el-form-item v-if="form.Type === 'number' || form.Type === 'calculation'"
v-if="form.Type === 'number' || form.Type === 'calculation'" :label="$t('trials:readingUnit:qsList:title:valueType')" prop="ValueType" :rules="[
:label="$t('trials:readingUnit:qsList:title:valueType')"
prop="ValueType"
:rules="[
{ required: true, message: this.$t('common:ruleMessage:select') } { required: true, message: this.$t('common:ruleMessage:select') }
]" ]">
> <el-radio-group v-model="form.ValueType">
<el-radio-group <el-radio v-for="item of $d.ValueType" :key="item.id" :label="item.value">
v-model="form.ValueType"
>
<el-radio
v-for="item of $d.ValueType"
:key="item.id"
:label="item.value"
>
{{ item.label }} {{ item.label }}
</el-radio> </el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<!-- 单位 --> <!-- 单位 -->
<el-form-item <el-form-item v-if="form.Type === 'number' || form.Type === 'calculation'"
v-if="form.Type === 'number' || form.Type === 'calculation'" :label="$t('trials:readingUnit:qsList:title:unit')" prop="Unit" :rules="[
:label="$t('trials:readingUnit:qsList:title:unit')"
prop="Unit"
:rules="[
{ required: true, message: this.$t('common:ruleMessage:select'), trigger: 'blur' } { required: true, message: this.$t('common:ruleMessage:select'), trigger: 'blur' }
]" ]">
> <el-radio-group v-model="form.Unit">
<el-radio-group <el-radio v-for="item of $d.ValueUnit" :key="item.id" :label="item.value">
v-model="form.Unit"
>
<el-radio
v-for="item of $d.ValueUnit"
:key="item.id"
:label="item.value"
>
{{ item.label }} {{ item.label }}
</el-radio> </el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<!-- 图表展示-->
<el-form-item v-if="form.Type === 'number' || form.Type === 'calculation'"
:label="$t('trials:readingUnit:qsList:title:ShowChartTypeEnum')" prop="ShowChartTypeEnum">
<el-radio-group v-model="form.ShowChartTypeEnum">
<el-radio v-for="item of $d.ShowChartType" :key="item.id" :label="item.value">{{ item.label }}</el-radio>
</el-radio-group>
</el-form-item>
<!-- 最大上传个数 --> <!-- 最大上传个数 -->
<el-form-item <el-form-item v-if="form.Type === 'upload'" :label="$t('trials:readingUnit:qsList:title:imageCount')"
v-if="form.Type === 'upload'" prop="ImageCount">
:label="$t('trials:readingUnit:qsList:title:imageCount')" <el-input-number v-model="form.ImageCount" controls-position="right" :min="0" :max="10" />
prop="ImageCount"
>
<el-input-number
v-model="form.ImageCount"
controls-position="right"
:min="0"
:max="10"
/>
</el-form-item> </el-form-item>
<!-- 文件类型 --> <!-- 文件类型 -->
<el-form-item <el-form-item v-if="form.Type === 'upload'" :label="$t('trials:readingUnit:qsList:title:FileType')"
v-if="form.Type === 'upload'"
:label="$t('trials:readingUnit:qsList:title:FileType')"
prop="FileType" prop="FileType"
:rules="[{ type: 'array', required: true, message: this.$t('common:ruleMessage:specify'), trigger: [ 'change'] }]" :rules="[{ type: 'array', required: true, message: this.$t('common:ruleMessage:specify'), trigger: ['change'] }]">
> <el-checkbox-group v-model="form.FileType" @change="(v) => {
<el-checkbox-group if (v && v.includes('-1')) {
v-model="form.FileType" form.FileType = ['-1']
@change="(v) => { }
if (v && v.includes('-1')) { }">
form.FileType = ['-1'] <el-checkbox v-for="item of $d.fileType" :key="`fileType${item.value}`" :value="item.value + ''"
} :label="item.value" :disabled="form.FileType && form.FileType.includes('-1') && item.value !== '-1'">
}"
>
<el-checkbox
v-for="item of $d.fileType"
:key="`fileType${item.value}`"
:value="item.value + ''"
:label="item.value"
:disabled="form.FileType && form.FileType.includes('-1') && item.value !== '-1'"
>
{{ item.label }} {{ item.label }}
</el-checkbox> </el-checkbox>
</el-checkbox-group> </el-checkbox-group>
</el-form-item> </el-form-item>
<!-- 分类 --> <!-- 分类 -->
<!-- 分类数据来源 --> <!-- 分类数据来源 -->
<el-form-item <el-form-item v-if="form.Type === 'class'"
v-if="form.Type === 'class'" :label="$t('dictionary:template:criterionConfig:table:classifyQuestion')" prop="ClassifyTableQuestionId">
:label="$t('dictionary:template:criterionConfig:table:classifyQuestion')"
prop="ClassifyTableQuestionId"
>
<el-select v-model="form.ClassifyTableQuestionId" clearable> <el-select v-model="form.ClassifyTableQuestionId" clearable>
<el-option v-for="item of Questions" :key="item.Id" :label="item.QuestionName" <el-option v-for="item of Questions" :key="item.Id" :label="item.QuestionName" :value="item.Id" />
:value="item.Id"/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 分类算法 --> <!-- 分类算法 -->
<el-form-item <el-form-item v-if="form.Type === 'class'"
v-if="form.Type === 'class'" :label="$t('dictionary:template:criterionConfig:table:classifyAlgorithms')" prop="ClassifyAlgorithms">
:label="$t('dictionary:template:criterionConfig:table:classifyAlgorithms')"
prop="ClassifyAlgorithms"
>
<div> <div>
<el-table <el-table ref="CalculateTable" :data="ClassifyAlgorithmsList" style="margin: 10px;width: 100%" size="small">
ref="CalculateTable"
:data="ClassifyAlgorithmsList"
style="margin: 10px;width: 100%"
size="small"
>
<!-- 运算类型 --> <!-- 运算类型 -->
<el-table-column <el-table-column :label="$t('trials:readingUnit:label:label')" show-overflow-tooltip min-width="70">
:label="$t('trials:readingUnit:label:label')"
show-overflow-tooltip
min-width="70"
>
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.label }} {{ scope.row.label }}
</template> </template>
</el-table-column> </el-table-column>
<!-- 运算类型 --> <!-- 运算类型 -->
<el-table-column <el-table-column :label="$t('trials:readingUnit:label:gt')" show-overflow-tooltip min-width="128">
:label="$t('trials:readingUnit:label:gt')"
show-overflow-tooltip
min-width="128"
>
<template slot-scope="scope"> <template slot-scope="scope">
<el-input-number v-model="scope.row.gt"></el-input-number> <el-input-number v-model="scope.row.gt"></el-input-number>
</template> </template>
</el-table-column> </el-table-column>
<!-- 运算类型 --> <!-- 运算类型 -->
<el-table-column <el-table-column :label="$t('trials:readingUnit:label:lt')" show-overflow-tooltip min-width="128">
:label="$t('trials:readingUnit:label:lt')"
show-overflow-tooltip
min-width="128"
>
<template slot-scope="scope"> <template slot-scope="scope">
<el-input-number v-model="scope.row.lt"></el-input-number> <el-input-number v-model="scope.row.lt"></el-input-number>
</template> </template>
@ -569,11 +344,7 @@
<div class="base-dialog-footer" style="text-align:right;margin-top:10px;"> <div class="base-dialog-footer" style="text-align:right;margin-top:10px;">
<el-form-item> <el-form-item>
<!-- 取消 --> <!-- 取消 -->
<el-button <el-button size="small" type="primary" @click="close">
size="small"
type="primary"
@click="close"
>
{{ $t('common:button:cancel') }} {{ $t('common:button:cancel') }}
</el-button> </el-button>
<!-- 保存 --> <!-- 保存 -->
@ -666,7 +437,8 @@ export default {
ClassifyAlgorithms: null, ClassifyAlgorithms: null,
// ExportIdentification: 0, // ExportIdentification: 0,
ExportResult: [], ExportResult: [],
DefaultValue:null DefaultValue: null,
ShowChartTypeEnum: 0
// IsEnable: true // IsEnable: true
}, },
rules: { rules: {
@ -677,8 +449,8 @@ export default {
// { max: 300, message: ' 300' }], // { max: 300, message: ' 300' }],
TypeValue: [{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' }, TypeValue: [{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' },
{ validator: validateTypeVal, trigger: 'blur' }, { validator: validateTypeVal, trigger: 'blur' },
{ max: 200, message: `${this.$t('common:ruleMessage:maxLength')} 200` }], { max: 200, message: `${this.$t('common:ruleMessage:maxLength')} 200` }],
ShowQuestion: [{ required: true, message: this.$t('common:ruleMessage:select'), trigger: 'blur' }], ShowQuestion: [{ required: true, message: this.$t('common:ruleMessage:select'), trigger: 'blur' }],
IsRequired: [{ required: true, message: this.$t('common:ruleMessage:select'), trigger: 'blur' }], IsRequired: [{ required: true, message: this.$t('common:ruleMessage:select'), trigger: 'blur' }],
ParentId: [{ required: true, message: this.$t('common:ruleMessage:select'), trigger: 'blur' }], ParentId: [{ required: true, message: this.$t('common:ruleMessage:select'), trigger: 'blur' }],
@ -776,7 +548,7 @@ export default {
if (this.data.hasOwnProperty(k)) { if (this.data.hasOwnProperty(k)) {
if (k === 'ClassifyAlgorithms' && this.data[k] !== undefined && this.data[k] !== '') { if (k === 'ClassifyAlgorithms' && this.data[k] !== undefined && this.data[k] !== '') {
this.ClassifyAlgorithmsList = JSON.parse(this.data[k]) this.ClassifyAlgorithmsList = JSON.parse(this.data[k])
} else if(k === 'FileType'){ } else if (k === 'FileType') {
this.form[k] = this.data[k].split(',') this.form[k] = this.data[k].split(',')
} else { } else {
this.form[k] = this.data[k] this.form[k] = this.data[k]
@ -792,10 +564,10 @@ export default {
if (this.parentOptions[index].QuestionGenre === 3) { if (this.parentOptions[index].QuestionGenre === 3) {
// this.parentTriggerValOptions = this.$d[this.parentOptions[index].DictionaryCode] // this.parentTriggerValOptions = this.$d[this.parentOptions[index].DictionaryCode]
let dicCode = this.parentOptions[index].DictionaryCode let dicCode = this.parentOptions[index].DictionaryCode
let res = await getCriterionDictionary({ReadingCriterionId: this.criterionId, DictionaryCode: dicCode}) let res = await getCriterionDictionary({ ReadingCriterionId: this.criterionId, DictionaryCode: dicCode })
this.parentTriggerValOptions = res.Result[dicCode].map(i=>{ this.parentTriggerValOptions = res.Result[dicCode].map(i => {
return {id: i.Id, label: this.$i18n.locale === 'zh' ? i.ValueCN : i.Value, value: i.Code} return { id: i.Id, label: this.$i18n.locale === 'zh' ? i.ValueCN : i.Value, value: i.Code }
}) })
} else { } else {
const options = [] const options = []
@ -814,9 +586,9 @@ export default {
if (this.parentOptions[i].QuestionGenre === 3) { if (this.parentOptions[i].QuestionGenre === 3) {
// this.reParentTriggerValOptions = this.$d[this.parentOptions[i].DictionaryCode] // this.reParentTriggerValOptions = this.$d[this.parentOptions[i].DictionaryCode]
let dicCode = this.parentOptions[i].DictionaryCode let dicCode = this.parentOptions[i].DictionaryCode
let res = await getCriterionDictionary({ReadingCriterionId: this.criterionId, DictionaryCode: dicCode}) let res = await getCriterionDictionary({ ReadingCriterionId: this.criterionId, DictionaryCode: dicCode })
this.reParentTriggerValOptions = res.Result[dicCode].map(i=>{ this.reParentTriggerValOptions = res.Result[dicCode].map(i => {
return {id: i.Id, label: this.$i18n.locale === 'zh' ? i.ValueCN : i.Value, value: i.Code} return { id: i.Id, label: this.$i18n.locale === 'zh' ? i.ValueCN : i.Value, value: i.Code }
}) })
} else { } else {
const options = [] const options = []
@ -903,12 +675,12 @@ export default {
if (index !== -1) { if (index !== -1) {
if (this.parentOptions[index].QuestionGenre === 3) { if (this.parentOptions[index].QuestionGenre === 3) {
// this.parentTriggerValOptions = this.$d[this.parentOptions[index].DictionaryCode] // this.parentTriggerValOptions = this.$d[this.parentOptions[index].DictionaryCode]
let dicCode = this.parentOptions[index].DictionaryCode let dicCode = this.parentOptions[index].DictionaryCode
let res = await getCriterionDictionary({ReadingCriterionId: this.criterionId, DictionaryCode: dicCode}) let res = await getCriterionDictionary({ ReadingCriterionId: this.criterionId, DictionaryCode: dicCode })
this.parentTriggerValOptions = res.Result[dicCode].map(i=>{ this.parentTriggerValOptions = res.Result[dicCode].map(i => {
return {id: i.Id, label: this.$i18n.locale === 'zh' ? i.ValueCN : i.Value, value: i.Code} return { id: i.Id, label: this.$i18n.locale === 'zh' ? i.ValueCN : i.Value, value: i.Code }
}) })
} else { } else {
const options = [] const options = []
this.parentOptions[index].TypeValue.split('|').forEach((item, index) => { this.parentOptions[index].TypeValue.split('|').forEach((item, index) => {
@ -929,10 +701,10 @@ export default {
if (this.parentOptions[index].QuestionGenre === 3) { if (this.parentOptions[index].QuestionGenre === 3) {
// this.reParentTriggerValOptions = this.$d[this.parentOptions[index].DictionaryCode] // this.reParentTriggerValOptions = this.$d[this.parentOptions[index].DictionaryCode]
let dicCode = this.parentOptions[index].DictionaryCode let dicCode = this.parentOptions[index].DictionaryCode
let res = await getCriterionDictionary({ReadingCriterionId: this.criterionId, DictionaryCode: dicCode}) let res = await getCriterionDictionary({ ReadingCriterionId: this.criterionId, DictionaryCode: dicCode })
this.reParentTriggerValOptions = res.Result[dicCode].map(i=>{ this.reParentTriggerValOptions = res.Result[dicCode].map(i => {
return {id: i.Id, label: this.$i18n.locale === 'zh' ? i.ValueCN : i.Value, value: i.Code} return { id: i.Id, label: this.$i18n.locale === 'zh' ? i.ValueCN : i.Value, value: i.Code }
}) })
} else { } else {
const options = [] const options = []
@ -993,6 +765,7 @@ export default {
// form.ExportIdentification = 0 // form.ExportIdentification = 0
form.ExportResult = [] form.ExportResult = []
form.DefaultValue = null form.DefaultValue = null
form.ShowChartTypeEnum = 0
}, },
close() { close() {
this.$emit('close') this.$emit('close')
@ -1001,5 +774,4 @@ export default {
} }
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped></style>
</style>

View File

@ -6,68 +6,45 @@
<qc-questions v-if="activeTab == 'qc'" /> <qc-questions v-if="activeTab == 'qc'" />
</el-tab-pane> </el-tab-pane>
<!-- 阅片标准配置 --> <!-- 阅片标准配置 -->
<el-tab-pane <el-tab-pane :label="$t('dictionary:template:tab:criterionsConfig')" name="criterions">
:label="$t('dictionary:template:tab:criterionsConfig')"
name="criterions"
>
<criterions-tmp v-if="activeTab == 'criterions'" /> <criterions-tmp v-if="activeTab == 'criterions'" />
</el-tab-pane> </el-tab-pane>
<!-- 临床数据配置 --> <!-- 临床数据配置 -->
<el-tab-pane <el-tab-pane :label="$t('dictionary:template:tab:clinicalDataConfig')" name="clinicalData">
:label="$t('dictionary:template:tab:clinicalDataConfig')"
name="clinicalData"
>
<clinical-data v-if="activeTab == 'clinicalData'" /> <clinical-data v-if="activeTab == 'clinicalData'" />
</el-tab-pane> </el-tab-pane>
<!-- 医学审核问题配置 --> <!-- 医学审核问题配置 -->
<el-tab-pane <el-tab-pane :label="$t('dictionary:template:tab:medicalConfig')" name="medicalAudit">
:label="$t('dictionary:template:tab:medicalConfig')"
name="medicalAudit"
>
<medical-audit v-if="activeTab == 'medicalAudit'" /> <medical-audit v-if="activeTab == 'medicalAudit'" />
</el-tab-pane> </el-tab-pane>
<!-- DICOM字段匿名化配置 --> <!-- DICOM字段匿名化配置 -->
<el-tab-pane <el-tab-pane :label="$t('dictionary:template:tab:dicomTagConfig')" name="anonymization">
:label="$t('dictionary:template:tab:dicomTagConfig')"
name="anonymization"
>
<Anonymization v-if="activeTab == 'anonymization'" /> <Anonymization v-if="activeTab == 'anonymization'" />
</el-tab-pane> </el-tab-pane>
<!-- DICOM字段新增配置 --> <!-- DICOM字段新增配置 -->
<el-tab-pane <el-tab-pane :label="$t('dictionary:template:tab:dicomTagAddConfig')" name="increasefields">
:label="$t('dictionary:template:tab:dicomTagAddConfig')"
name="increasefields"
>
<IncreaseFields v-if="activeTab == 'increasefields'" /> <IncreaseFields v-if="activeTab == 'increasefields'" />
</el-tab-pane> </el-tab-pane>
<!-- 邮件管理 --> <!-- 邮件管理 -->
<el-tab-pane <el-tab-pane :label="$t('dictionary:template:tab:emailConfig')" name="email">
:label="$t('dictionary:template:tab:emailConfig')"
name="email"
>
<Email v-if="activeTab == 'email'" /> <Email v-if="activeTab == 'email'" />
</el-tab-pane> </el-tab-pane>
<!-- 签名管理 --> <!-- 签名管理 -->
<el-tab-pane <el-tab-pane :label="$t('dictionary:template:tab:signConfig')" name="sign">
:label="$t('dictionary:template:tab:signConfig')"
name="sign"
>
<Sign v-if="activeTab == 'sign'" /> <Sign v-if="activeTab == 'sign'" />
</el-tab-pane> </el-tab-pane>
<!-- 浏览器推荐 --> <!-- 浏览器推荐 -->
<el-tab-pane <el-tab-pane :label="$t('dictionary:template:tab:browserConfig')" name="browser">
:label="$t('dictionary:template:tab:browserConfig')"
name="browser"
>
<Browser v-if="activeTab == 'browser'" /> <Browser v-if="activeTab == 'browser'" />
</el-tab-pane> </el-tab-pane>
<!-- 文件记录 --> <!-- 文件记录 -->
<el-tab-pane <el-tab-pane :label="$t('dictionary:template:tab:fileConfig')" name="file">
:label="$t('dictionary:template:tab:fileConfig')"
name="file"
>
<File v-if="activeTab == 'file'" /> <File v-if="activeTab == 'file'" />
</el-tab-pane> </el-tab-pane>
<!-- 用户协议 -->
<el-tab-pane :label="$t('dictionary:template:tab:agreement')" name="agreement">
<Agreement v-if="activeTab == 'agreement'" />
</el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
</template> </template>
@ -82,6 +59,7 @@ import Email from './email/index.vue'
import Sign from './sign/index.vue' import Sign from './sign/index.vue'
import Browser from './browser/index.vue' import Browser from './browser/index.vue'
import File from './file/index.vue' import File from './file/index.vue'
import Agreement from './agreement/index.vue'
export default { export default {
name: 'Questions', name: 'Questions',
components: { components: {
@ -95,6 +73,7 @@ export default {
MedicalAudit, MedicalAudit,
Browser, Browser,
File, File,
Agreement
}, },
data() { data() {
return { return {
@ -122,16 +101,18 @@ export default {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.el-tabs__header { .el-tabs__header {
height: 40px; height: 40px;
margin-bottom: 5px; margin-bottom: 5px;
} }
.el-tabs__content { .el-tabs__content {
flex: 1; flex: 1;
.el-tab-pane { .el-tab-pane {
height: 100%; height: 100%;
} }
} }
} }
</style> </style>

View File

@ -21,13 +21,19 @@
<el-form-item :label="$t('trials:researchForm:form:verifyCode')" required> <el-form-item :label="$t('trials:researchForm:form:verifyCode')" required>
<el-col :span="18"> <el-col :span="18">
<el-form-item prop="VerificationCode"> <el-form-item prop="VerificationCode">
<el-input v-model="form.VerificationCode" autocomplete="off" /> <div style="display: flex;justify-content: space-between;">
<el-input v-model="form.VerificationCode" autocomplete="off" />
<el-button size="small" class="codeBtn" :disabled="sendDisabled" @click="handleSendCode"
style="width: 30%;margin-left: 10px;">
{{ sendTitle }}
</el-button>
</div>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6" style="text-align: right"> <!-- <el-col :span="6" style="text-align: right">
<el-button size="small" type="primary" style="width: 80%" :disabled="sendDisabled"
@click="handleSendCode">{{ sendTitle }}</el-button> </el-col> -->
</el-col>
</el-form-item> </el-form-item>
</el-form> </el-form>
<!-- 校验 --> <!-- 校验 -->
@ -381,6 +387,21 @@ export default {
/*::v-deep .is-error{*/ /*::v-deep .is-error{*/
/* margin-bottom: 40px;*/ /* margin-bottom: 40px;*/
/*}*/ /*}*/
.codeBtn {
color: #409EFF;
border-color: #409EFF;
}
.codeBtn.is-disabled,
.codeBtn.is-disabled:focus,
.codeBtn.is-disabled:hover {
color: #c0c4cc;
cursor: not-allowed;
background-image: none;
background-color: #fff;
border-color: #ebeef5;
}
.is-error.my_new_pwd { .is-error.my_new_pwd {
margin-bottom: 45px; margin-bottom: 45px;
} }

View File

@ -6,7 +6,9 @@
<div class="login-body"> <div class="login-body">
<div class="login-l"> <div class="login-l">
<div class="login-logo"> <div class="login-logo">
<img src="@/assets/zzlogo-usa.png" alt="" class="usa-logo" /> <img v-if="language === 'zh'" src="@/assets/zzlogo2.png" alt="" />
<img v-else-if="NODE_ENV === 'usa'" src="@/assets/zzlogo-usa.png" alt="" class="usa-logo" />
<img v-else src="@/assets/zzlogo4.png" alt="" />
</div> </div>
<div :class="{ <div :class="{
'login-image': true, 'login-image': true,
@ -75,13 +77,22 @@
</span> --> </span> -->
</el-form-item> </el-form-item>
<!-- Login --> <!-- Login -->
<el-button :loading="loading" type="primary" style=" <el-button :loading="loading" type="primary" :disabled="!checked" style="
width: 100%; width: 100%;
margin-bottom: 10px; margin-bottom: 10px;
background-color: rgb(0, 147, 221); background-color: rgb(0, 147, 221);
" size="medium" @click.native.prevent="handleLogin"> " size="medium" @click.native.prevent="handleLogin">
{{ $t('login:button:login') }} {{ $t('login:button:login') }}
</el-button> </el-button>
<div class="PrivacyPolicy" style="font-size: 14px;">
<el-checkbox v-model="checked" style="margin-right: 5px;" />
<span>{{ $t('login:message:PrivacyPolicy') }}</span>
<span style="cursor: pointer;color:#428bca" @click="viewAgreement(0)">{{ $t('login:message:UserAgreement')
}}</span>
<span>{{ $t('login:message:and') }}</span>
<span style="cursor: pointer;color:#428bca" @click="viewAgreement(1)">{{
$t('login:message:PrivacyPolicyName') }}</span>
</div>
<div style="text-align: right"> <div style="text-align: right">
<TopLang v-if=" <TopLang v-if="
VUE_APP_OSS_CONFIG_REGION !== 'oss-us-west-1' && VUE_APP_OSS_CONFIG_REGION !== 'oss-us-west-1' &&
@ -179,6 +190,9 @@ import Vcode from 'vue-puzzle-vcode'
import browserTip from '@/views/dictionary/template/browser/tip.vue' import browserTip from '@/views/dictionary/template/browser/tip.vue'
import Img1 from '@/assets/pic-2.png' import Img1 from '@/assets/pic-2.png'
import toggleRole from '@/components/toggleRole' import toggleRole from '@/components/toggleRole'
import {
getCurrentVersionUserAgreements,
} from '@/api/dictionary'
export default { export default {
name: 'Login', name: 'Login',
components: { TopLang, Vcode, browserTip, toggleRole }, components: { TopLang, Vcode, browserTip, toggleRole },
@ -226,6 +240,8 @@ export default {
Img1, Img1,
toggleRoleVisible: false, toggleRoleVisible: false,
toggleRoleLoading: false, toggleRoleLoading: false,
Agreement: [],
checked: true
} }
}, },
computed: { computed: {
@ -254,7 +270,6 @@ export default {
zzSessionStorage.setItem('loginType', this.loginType) zzSessionStorage.setItem('loginType', this.loginType)
localStorage.setItem('location', this.location) localStorage.setItem('location', this.location)
// zh-CN navigator.language // zh-CN navigator.language
console.log(navigator.language, 'navigator.language')
if (navigator.language !== 'zh-CN' && navigator.language !== 'zh-TW') { if (navigator.language !== 'zh-CN' && navigator.language !== 'zh-TW') {
this.$i18n.locale = 'en' this.$i18n.locale = 'en'
this.setLanguage('en') this.setLanguage('en')
@ -276,9 +291,30 @@ export default {
} }
} }
this.$refs.browserTip.open() this.$refs.browserTip.open()
this.getAgreementList()
}, },
methods: { methods: {
...mapMutations({ setLanguage: 'lang/setLanguage' }), ...mapMutations({ setLanguage: 'lang/setLanguage' }),
viewAgreement(type) {
let find = this.Agreement.find(item => item.IsCurrentVersion && item.UserAgreementTypeEnum === type)
if (!find) return this.$confirm(this.$t('login:message:noAgreement').replace('xxx', this.$fd('UserAgreementType', type)))
this.$AGR({
Id: find.Id,
IsEn_Us: this.$i18n.locale !== 'zh'
})
},
getAgreementList() {
getCurrentVersionUserAgreements({
PageIndex: 1,
PageSize: 20,
IsCurrentVersion: true
})
.then((res) => {
this.Agreement = res.Result
})
.catch(() => {
})
},
openAbout() { openAbout() {
this.aboutVisible = true this.aboutVisible = true
}, },

View File

@ -18,19 +18,10 @@
</el-form-item> </el-form-item>
<!-- 中心名称 --> <!-- 中心名称 -->
<el-form-item :label="$t('trials:researchForm:form:siteName')" prop="TrialSiteId"> <el-form-item :label="$t('trials:researchForm:form:siteName')" prop="TrialSiteId">
<el-select <el-select v-model="form.TrialSiteId" filterable style="width:100%;"
v-model="form.TrialSiteId" :disabled="!(state === 0 && userTypeEnumInt === 0) || isHistory" @change="handleSiteChange">
filterable <el-option v-for="(item, index) of siteOptions" :key="index" :label="item.TrialSiteAliasName"
style="width:100%;" :value="item.TrialSiteId" />
:disabled="!(state === 0 && userTypeEnumInt === 0) || isHistory"
@change="handleSiteChange"
>
<el-option
v-for="(item,index) of siteOptions"
:key="index"
:label="item.TrialSiteAliasName"
:value="item.TrialSiteId"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 中心编号 --> <!-- 中心编号 -->
@ -42,10 +33,7 @@
<el-input v-model="form.UserName" :disabled="!(state === 0 && userTypeEnumInt === 0) || isHistory" /> <el-input v-model="form.UserName" :disabled="!(state === 0 && userTypeEnumInt === 0) || isHistory" />
</el-form-item> </el-form-item>
<!-- 联系电话 --> <!-- 联系电话 -->
<el-form-item <el-form-item :label="$t('trials:researchForm:form:contactorPhone')" prop="Phone">
:label="$t('trials:researchForm:form:contactorPhone')"
prop="Phone"
>
<el-input v-model="form.Phone" :disabled="!(state === 0 && userTypeEnumInt === 0) || isHistory" /> <el-input v-model="form.Phone" :disabled="!(state === 0 && userTypeEnumInt === 0) || isHistory" />
</el-form-item> </el-form-item>
<!-- 联系邮箱 --> <!-- 联系邮箱 -->
@ -55,75 +43,71 @@
<!-- <el-divider /> --> <!-- <el-divider /> -->
<!-- 平均刻盘周期 --> <!-- 平均刻盘周期 -->
<el-form-item v-if="!notShowFieldList.includes('AverageEngravingCycle')" :label="$t('trials:researchForm:form:engravingCycle')"> <el-form-item v-if="!notShowFieldList.includes('AverageEngravingCycle')"
<el-input-number v-model="form.AverageEngravingCycle" :disabled="!(state === 0 && userTypeEnumInt === 0) || isHistory" controls-position="right" :min="0" /> :label="$t('trials:researchForm:form:engravingCycle')">
<el-input-number v-model="form.AverageEngravingCycle"
:disabled="!(state === 0 && userTypeEnumInt === 0) || isHistory" controls-position="right" :min="0" />
</el-form-item> </el-form-item>
<!-- 请确认参与本项目影像采集的影像技师具备对应的资质技师证对应设备的大型设备上岗证 --> <!-- 请确认参与本项目影像采集的影像技师具备对应的资质技师证对应设备的大型设备上岗证 -->
<el-form-item v-if="!notShowFieldList.includes('IsConfirmImagingTechnologist')" :label="$t('trials:researchForm:form:isQualified')"> <el-form-item v-if="!notShowFieldList.includes('IsConfirmImagingTechnologist')"
<el-radio-group v-model="form.IsConfirmImagingTechnologist" :disabled="!(state === 0 && userTypeEnumInt === 0) || isHistory"> :label="$t('trials:researchForm:form:isQualified')">
<el-radio <el-radio-group v-model="form.IsConfirmImagingTechnologist"
v-for="item of $d.YesOrNo" :disabled="!(state === 0 && userTypeEnumInt === 0) || isHistory">
:key="`IsConfirmImagingTechnologist${item.value}`" <el-radio v-for="item of $d.YesOrNo" :key="`IsConfirmImagingTechnologist${item.value}`" :label="item.value">{{
:label="item.value" item.label }}</el-radio>
>{{ item.label }}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<!-- 原因 --> <!-- 原因 -->
<el-form-item <el-form-item v-if="!notShowFieldList.includes('NotConfirmReson') && form.IsConfirmImagingTechnologist === false"
v-if="!notShowFieldList.includes('NotConfirmReson') && form.IsConfirmImagingTechnologist === false" :label="$t('trials:researchForm:form:notQualifiedReason')">
:label="$t('trials:researchForm:form:notQualifiedReason')" <el-input v-model="form.NotConfirmReson" type="textarea" :autosize="{ minRows: 2, maxRows: 4 }"
> :disabled="!(state === 0 && userTypeEnumInt === 0) || isHistory" />
<el-input
v-model="form.NotConfirmReson"
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
:disabled="!(state === 0 && userTypeEnumInt === 0) || isHistory"
/>
</el-form-item> </el-form-item>
<!-- 研究单位疗效评估人员类型 --> <!-- 研究单位疗效评估人员类型 -->
<el-form-item v-if="!notShowFieldList.includes('EfficacyEvaluatorType')" :label="$t('trials:researchForm:form:staffType')"> <el-form-item v-if="!notShowFieldList.includes('EfficacyEvaluatorType')"
<el-radio-group v-model="form.EfficacyEvaluatorType" :disabled="!(state === 0 && userTypeEnumInt === 0)|| isHistory"> :label="$t('trials:researchForm:form:staffType')">
<el-radio v-for="item of $d.EfficacyEvaluatorType" :key="`EfficacyEvaluatorType${item.value}`" :label="item.value">{{ item.label }}</el-radio> <el-radio-group v-model="form.EfficacyEvaluatorType"
:disabled="!(state === 0 && userTypeEnumInt === 0) || isHistory">
<el-radio v-for="item of $d.EfficacyEvaluatorType" :key="`EfficacyEvaluatorType${item.value}`"
:label="item.value">{{ item.label }}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<!-- 是否严格按照研究单位影像手册参数完成图像采集 --> <!-- 是否严格按照研究单位影像手册参数完成图像采集 -->
<el-form-item v-if="!notShowFieldList.includes('IsFollowStudyParameters')"> <el-form-item v-if="!notShowFieldList.includes('IsFollowStudyParameters')">
<span slot="label" v-html="$t('trials:researchForm:form:isFollowStudyParam')" /> <span slot="label" v-html="$t('trials:researchForm:form:isFollowStudyParam')" />
<el-radio-group v-model="form.IsFollowStudyParameters" :disabled="!(state === 0 && userTypeEnumInt === 0) || isHistory"> <el-radio-group v-model="form.IsFollowStudyParameters"
<el-radio v-for="item of $d.YesOrNo" :key="`IsFollowStudyParameters${item.value}`" :label="item.value">{{ item.label }}</el-radio> :disabled="!(state === 0 && userTypeEnumInt === 0) || isHistory" style="margin-right: 10px;">
<el-radio v-for="item of $d.YesOrNo" :key="`IsFollowStudyParameters${item.value}`" :label="item.value">{{
item.label }}</el-radio>
</el-radio-group> </el-radio-group>
<el-button type="primary" size="small" @click="viewManual">
{{ $t('trials:researchForm:button:viewManual') }}
</el-button>
</el-form-item> </el-form-item>
<!-- 不能严格按照研究单位影像手册参数采集图像原因 --> <!-- 不能严格按照研究单位影像手册参数采集图像原因 -->
<el-form-item <el-form-item v-if="!notShowFieldList.includes('NotFollowReson') && !form.IsFollowStudyParameters">
v-if="!notShowFieldList.includes('NotFollowReson') && !form.IsFollowStudyParameters"
>
<span slot="label" v-html="$t('trials:researchForm:form:notFollowStudyParam')" /> <span slot="label" v-html="$t('trials:researchForm:form:notFollowStudyParam')" />
<el-input <el-input v-model="form.NotFollowReson" type="textarea" :autosize="{ minRows: 2, maxRows: 4 }"
v-model="form.NotFollowReson" :disabled="!(state === 0 && userTypeEnumInt === 0) || isHistory" />
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
:disabled="!(state === 0 && userTypeEnumInt === 0) || isHistory"
/>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<!-- 保存 --> <!-- 保存 -->
<el-button <el-button v-if="state === 0 && userTypeEnumInt === 0 && !isHistory" type="primary" :loading="btnLoading"
v-if="state === 0 && userTypeEnumInt === 0 && !isHistory" size="small" @click="handleSave(false)">
type="primary"
:loading="btnLoading"
size="small"
@click="handleSave(false)"
>
{{ $t('common:button:save') }} {{ $t('common:button:save') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
<attachmentPreview :visible.sync="perview_visible" :isView="true" :isExternal="true" :ExternalList="ExternalList"
v-if="perview_visible" />
</el-form> </el-form>
</template> </template>
<script> <script>
import { getTrialSiteSelect } from '@/api/trials' import { getTrialSiteSelect, getTrialDocumentList } from '@/api/trials'
import { addOrUpdateTrialSiteSurvey } from '@/api/research' import { addOrUpdateTrialSiteSurvey } from '@/api/research'
import attachmentPreview from '@/views/dictionary/attachment/components/SignatureTemplate/attachmentPreview'
export default { export default {
name: 'QuestionForm', name: 'QuestionForm',
components: { attachmentPreview },
props: { props: {
isHistory: { isHistory: {
type: Boolean, type: Boolean,
@ -197,10 +181,41 @@ export default {
state: null, state: null,
userTypeEnumInt: zzSessionStorage.getItem('userTypeEnumInt') * 1, userTypeEnumInt: zzSessionStorage.getItem('userTypeEnumInt') * 1,
isShow: false, isShow: false,
notShowFieldList: [] notShowFieldList: [],
perview_visible: false,
ExternalList: []
} }
}, },
methods: { methods: {
async viewManual() {
try {
let data = {
PageIndex: 1,
PageSize: 20,
TrialId: this.$route.query.trialId,
IsPublish: true,
FileTypeCode: 4,
IsDeleted: false
}
let res = await getTrialDocumentList(data)
if (res.IsSuccess) {
const { CurrentPageData } = res.Result
if (CurrentPageData.length <= 0) return this.$message.warning(this.$t("trials:researchRecord:ImageManual:message:noImageManual"))
this.ExternalList = []
CurrentPageData.forEach(item => {
let obj = {
FilePath: item.Path,
FileFormat: 'pdf',
Name: item.Name
}
this.ExternalList.push(obj)
});
this.perview_visible = true
}
} catch (err) {
console.log(err)
}
},
// //
handleSave(isAutoCommit) { handleSave(isAutoCommit) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {

View File

@ -21,14 +21,15 @@
<!-- <h4>{{ $t('trials:staffResearch:title:staff') }}</h4>--> <!-- <h4>{{ $t('trials:staffResearch:title:staff') }}</h4>-->
<!-- 历史人员 --> <!-- 历史人员 -->
<h4>{{ $t('trials:staffResearch:title:historicalStaff') }}</h4> <h4>{{ $t('trials:staffResearch:title:historicalStaff') }}</h4>
<HistoricalParticipant ref="historicalParticipant" :is-history="true" @refreshPage="refreshPage" @getList="initPage" /> <HistoricalParticipant ref="historicalParticipant" :is-history="true" @refreshPage="refreshPage"
@getList="initPage" />
<!-- 新增人员 --> <!-- 新增人员 -->
<h4>{{ $t('trials:staffResearch:title:newStaff') }}</h4> <h4>{{ $t('trials:staffResearch:title:newStaff') }}</h4>
<ParticipantList ref="researchParticipants" :is-history="true" @refreshPage="refreshPage" @getList="initPage" /> <ParticipantList ref="researchParticipants" :is-history="true" @refreshPage="refreshPage" @getList="initPage" />
</el-card> </el-card>
<!-- 设备调研 --> <!-- 设备调研 -->
<el-card shadow="hover" class="mt10"> <el-card shadow="hover" class="mt10" v-if="!siteSurveyNoteInfo.IsCloseEquipmentSurvey">
<h4>{{ $t('trials:equiptResearch:title:equiptResearch') }}</h4> <h4>{{ $t('trials:equiptResearch:title:equiptResearch') }}</h4>
<EquipmentList ref="researchEquipments" :is-history="true" /> <EquipmentList ref="researchEquipments" :is-history="true" />
</el-card> </el-card>
@ -53,31 +54,17 @@
</el-card> </el-card>
</div> </div>
<el-dialog <el-dialog v-if="rejectVisible" :visible.sync="rejectVisible" :close-on-click-modal="false"
v-if="rejectVisible" :title="$t('trials:researchForm:dialogTitle:reject')" width="600px" custom-class="base-dialog-wrapper"
:visible.sync="rejectVisible" :append-to-body="userTypeEnumInt !== 0">
:close-on-click-modal="false"
:title="$t('trials:researchForm:dialogTitle:reject')"
width="600px"
custom-class="base-dialog-wrapper"
:append-to-body="userTypeEnumInt !== 0"
>
<el-form ref="rejectForm" :model="rejectForm" label-width="100px"> <el-form ref="rejectForm" :model="rejectForm" label-width="100px">
<div class="base-dialog-body"> <div class="base-dialog-body">
<!-- 驳回原因 --> <!-- 驳回原因 -->
<el-form-item <el-form-item :label="$t('trials:researchForm:form:rejectReson')" prop="reason" :rules="[
:label="$t('trials:researchForm:form:rejectReson')" { required: true, message: $t('trials:researchForm:formRule:specify') }
prop="reason" ]">
:rules="[ <el-input v-model="rejectForm.reason" type="textarea" :autosize="{ minRows: 2, maxRows: 4 }"
{ required: true, message: $t('trials:researchForm:formRule:specify')} style="width:100%;" />
]"
>
<el-input
v-model="rejectForm.reason"
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
style="width:100%;"
/>
</el-form-item> </el-form-item>
</div> </div>
<div class="base-dialog-footer" style="text-align:right;margin-top:10px;"> <div class="base-dialog-footer" style="text-align:right;margin-top:10px;">
@ -136,7 +123,7 @@ export default {
props: { props: {
trialSiteSurveyId: { trialSiteSurveyId: {
type: String, type: String,
required: true default: ''
} }
}, },
data() { data() {
@ -152,7 +139,7 @@ export default {
btnLoading: false, btnLoading: false,
isFullscreen: false, isFullscreen: false,
historyVisible: false, historyVisible: false,
siteSurveyNoteInfo: null siteSurveyNoteInfo: {}
} }
}, },
mounted() { mounted() {
@ -172,6 +159,7 @@ export default {
if (res.Result.SiteSurveyFiledConfig && res.Result.SiteSurveyFiledConfig.ModifyFiledList.length > 0) { if (res.Result.SiteSurveyFiledConfig && res.Result.SiteSurveyFiledConfig.ModifyFiledList.length > 0) {
this.siteSurveyNoteInfo = res.Result.SiteSurveyFiledConfig.ModifyFiledList.find(i => i.NeedModifyFiled === 'SiteSurveyNote') this.siteSurveyNoteInfo = res.Result.SiteSurveyFiledConfig.ModifyFiledList.find(i => i.NeedModifyFiled === 'SiteSurveyNote')
} }
this.siteSurveyNoteInfo.IsCloseEquipmentSurvey = res.Result.SiteSurveyFiledConfig.IsCloseEquipmentSurvey
var historicalArr = [] var historicalArr = []
var newArr = [] var newArr = []
res.Result.TrialSiteUserSurveyList.map(i => { res.Result.TrialSiteUserSurveyList.map(i => {
@ -241,7 +229,7 @@ export default {
this.$message.success(this.$t('common:message:savedSuccessfully')) this.$message.success(this.$t('common:message:savedSuccessfully'))
} }
}).catch(() => { this.loading = false }) }).catch(() => { this.loading = false })
}).catch(() => {}) }).catch(() => { })
}, },
// //
generateAccount() { generateAccount() {
@ -276,7 +264,7 @@ export default {
}).catch(() => { }).catch(() => {
this.loading = false this.loading = false
}) })
}).catch(() => {}) }).catch(() => { })
}, },
// //
handleReject() { handleReject() {
@ -324,37 +312,44 @@ export default {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
.mt10{
.mt10 {
margin-top: 10px; margin-top: 10px;
} }
.header-wrapper{
.header-wrapper {
width: 70%; width: 70%;
margin: 20px auto; margin: 20px auto;
} }
.center-wrapper{
.center-wrapper {
flex: 1; flex: 1;
width: 70%; width: 70%;
margin: 0px auto; margin: 0px auto;
padding-bottom: 20px; padding-bottom: 20px;
overflow-y: auto; overflow-y: auto;
} }
::v-deep .el-card__body{
::v-deep .el-card__body {
padding: 10px; padding: 10px;
} }
// >>>.el-dialog__body{ // >>>.el-dialog__body{
// padding: 10px 20px 20px 20px; // padding: 10px 20px 20px 20px;
// } // }
::v-deep .full-dialog-container{ ::v-deep .full-dialog-container {
.el-dialog__body{ .el-dialog__body {
height: calc(100% - 80px); height: calc(100% - 80px);
} }
} }
::v-deep .dialog-container{
::v-deep .dialog-container {
// margin-top: 50px !important; // margin-top: 50px !important;
width:75%; width: 75%;
height:80%; height: 80%;
.el-dialog__body{
.el-dialog__body {
padding: 10px; padding: 10px;
height: calc(100% - 80px); height: calc(100% - 80px);
} }

View File

@ -6,61 +6,37 @@
{{ $t('trials:researchForm:title:question') }} {{ $t('trials:researchForm:title:question') }}
</h2> </h2>
<!-- <TopLang style="position: fixed;top: 40px;right: 40px" /> --> <!-- <TopLang style="position: fixed;top: 40px;right: 40px" /> -->
<div style="display: flex;justify-content: space-between;"> <div style="display: flex;justify-content: space-between;" v-if="!isPreview">
<div>{{ $t('trials:researchForm:title:researchSurveyStatus') }} <el-tag>{{ $fd('ResearchRecord', state) }}</el-tag></div> <div>{{ $t('trials:researchForm:title:researchSurveyStatus') }} <el-tag>{{ $fd('ResearchRecord', state)
}}</el-tag></div>
<div> <div>
<!-- 提交 --> <!-- 提交 -->
<el-button <el-button v-if="(state === 0 && userTypeEnumInt === 0)" type="primary" size="small"
v-if="(state === 0 && userTypeEnumInt === 0)" @click="handleSubmit('submit')">
type="primary"
size="small"
@click="handleSubmit('submit')"
>
{{ $t('trials:researchForm:button:submit') }} {{ $t('trials:researchForm:button:submit') }}
</el-button> </el-button>
<!-- 审核通过 --> <!-- 审核通过 -->
<el-button <el-button v-if="(state === 1 && hasPermi(['role:spm', 'role:cpm']))" type="primary" size="small"
v-if="(state === 1 && hasPermi(['role:spm','role:cpm']))" @click="handleSubmit('approve')">
type="primary"
size="small"
@click="handleSubmit('approve')"
>
{{ $t('trials:researchForm:button:auditPasses') }} {{ $t('trials:researchForm:button:auditPasses') }}
</el-button> </el-button>
<!-- 审核通过 --> <!-- 审核通过 -->
<el-button <el-button v-if="(state === 2 && hasPermi(['role:pm', 'role:apm']))" type="primary" size="small"
v-if="(state === 2 && hasPermi(['role:pm','role:apm']))" @click="generateAccount">
type="primary"
size="small"
@click="generateAccount"
>
{{ $t('trials:researchForm:button:auditPasses') }} {{ $t('trials:researchForm:button:auditPasses') }}
</el-button> </el-button>
<!-- 驳回 --> <!-- 驳回 -->
<el-button <el-button
v-if="((state === 1 && hasPermi(['role:spm','role:cpm'])) || (state === 2 && hasPermi(['role:pm','role:apm'])))" v-if="((state === 1 && hasPermi(['role:spm', 'role:cpm'])) || (state === 2 && hasPermi(['role:pm', 'role:apm'])))"
type="primary" type="primary" size="small" @click="handleReject">
size="small"
@click="handleReject"
>
{{ $t('trials:researchForm:button:auditRejected') }} {{ $t('trials:researchForm:button:auditRejected') }}
</el-button> </el-button>
<!-- 历史记录 --> <!-- 历史记录 -->
<el-button <el-button v-if="userTypeEnumInt === 0" type="primary" size="small" @click="handleHistory">
v-if="userTypeEnumInt === 0"
type="primary"
size="small"
@click="handleHistory"
>
{{ $t('trials:researchForm:button:historicalRecord') }} {{ $t('trials:researchForm:button:historicalRecord') }}
</el-button> </el-button>
<!-- 退出 --> <!-- 退出 -->
<el-button <el-button v-if="userTypeEnumInt === 0" type="primary" size="small" @click="handleBack">
v-if="userTypeEnumInt === 0"
type="primary"
size="small"
@click="handleBack"
>
{{ $t('trials:researchForm:button:loginOut') }} {{ $t('trials:researchForm:button:loginOut') }}
</el-button> </el-button>
</div> </div>
@ -69,24 +45,26 @@
<div class="center-wrapper"> <div class="center-wrapper">
<!-- 基本信息 --> <!-- 基本信息 -->
<el-card shadow="hover"> <el-card shadow="hover">
<BaseInfo ref="baseResearchInfo" /> <BaseInfo ref="baseResearchInfo" :isPreview="isPreview" />
</el-card> </el-card>
<!-- 人员调查 --> <!-- 人员调查 -->
<el-card shadow="hover" class="mt10"> <el-card shadow="hover" class="mt10">
<!-- 历史人员 --> <!-- 历史人员 -->
<h4>{{ $t('trials:staffResearch:title:historicalStaff') }}</h4> <h4>{{ $t('trials:staffResearch:title:historicalStaff') }}</h4>
<HistoricalParticipant ref="historicalParticipant" @refreshPage="refreshPage" @getList="initPage" /> <HistoricalParticipant ref="historicalParticipant" :isPreview="isPreview" @refreshPage="refreshPage"
@getList="initPage" />
<!-- <h4>{{ $t('trials:staffResearch:title:staff') }}</h4> --> <!-- <h4>{{ $t('trials:staffResearch:title:staff') }}</h4> -->
<!-- 新增人员 --> <!-- 新增人员 -->
<h4>{{ $t('trials:staffResearch:title:newStaff') }}</h4> <h4>{{ $t('trials:staffResearch:title:newStaff') }}</h4>
<ParticipantList ref="researchParticipants" @refreshPage="refreshPage" @getList="initPage" /> <ParticipantList ref="researchParticipants" :isPreview="isPreview" @refreshPage="refreshPage"
@getList="initPage" />
</el-card> </el-card>
<!-- 设备调研 --> <!-- 设备调研 -->
<el-card shadow="hover" class="mt10"> <el-card shadow="hover" class="mt10" v-if="!siteSurveyNoteInfo.IsCloseEquipmentSurvey">
<h4>{{ $t('trials:equiptResearch:title:equiptResearch') }}</h4> <h4>{{ $t('trials:equiptResearch:title:equiptResearch') }}</h4>
<EquipmentList ref="researchEquipments" /> <EquipmentList ref="researchEquipments" :isPreview="isPreview" />
</el-card> </el-card>
<!-- 其他信息调研 --> <!-- 其他信息调研 -->
@ -110,31 +88,17 @@
</el-card> </el-card>
</div> </div>
<el-dialog <el-dialog v-if="rejectVisible" :visible.sync="rejectVisible" :close-on-click-modal="false"
v-if="rejectVisible" :title="$t('trials:researchForm:dialogTitle:reject')" width="600px" custom-class="base-dialog-wrapper"
:visible.sync="rejectVisible" append-to-body>
:close-on-click-modal="false"
:title="$t('trials:researchForm:dialogTitle:reject')"
width="600px"
custom-class="base-dialog-wrapper"
append-to-body
>
<el-form ref="rejectForm" :model="rejectForm" label-width="100px"> <el-form ref="rejectForm" :model="rejectForm" label-width="100px">
<div class="base-dialog-body"> <div class="base-dialog-body">
<!-- 驳回原因 --> <!-- 驳回原因 -->
<el-form-item <el-form-item :label="$t('trials:researchForm:form:rejectReson')" prop="reason" :rules="[
:label="$t('trials:researchForm:form:rejectReson')" { required: true, message: $t('trials:researchForm:formRule:specify') }
prop="reason" ]">
:rules="[ <el-input v-model="rejectForm.reason" type="textarea" :autosize="{ minRows: 2, maxRows: 4 }"
{ required: true, message: $t('trials:researchForm:formRule:specify')} style="width:100%;" />
]"
>
<el-input
v-model="rejectForm.reason"
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
style="width:100%;"
/>
</el-form-item> </el-form-item>
</div> </div>
<div class="base-dialog-footer" style="text-align:right;margin-top:10px;"> <div class="base-dialog-footer" style="text-align:right;margin-top:10px;">
@ -152,30 +116,24 @@
</el-form> </el-form>
</el-dialog> </el-dialog>
<el-dialog <el-dialog :visible.sync="historyVisible"
:visible.sync="historyVisible" :custom-class="isFullscreen ? 'full-dialog-container' : 'dialog-container'" :close-on-click-modal="false"
:custom-class="isFullscreen?'full-dialog-container':'dialog-container'" :fullscreen="isFullscreen" :show-close="false">
:close-on-click-modal="false"
:fullscreen="isFullscreen"
:show-close="false"
>
<span slot="title" class="dialog-footer"> <span slot="title" class="dialog-footer">
<div style="display: flex;flex-direction: row;justify-content: space-between;"> <div style="display: flex;flex-direction: row;justify-content: space-between;">
<div> <div>
{{ $t('trials:researchForm:button:historicalRecord') }} {{ $t('trials:researchForm:button:historicalRecord') }}
</div> </div>
<div> <div>
<svg-icon :icon-class="isFullscreen?'exit-fullscreen':'fullscreen'" style="vertical-align: baseline;cursor: pointer;font-size: 20px;" @click="isFullscreen=!isFullscreen" /> <svg-icon :icon-class="isFullscreen ? 'exit-fullscreen' : 'fullscreen'"
<svg-icon icon-class="dClose" style="cursor: pointer;font-size: 25px;margin-left: 10px;" @click="historyVisible = false" /> style="vertical-align: baseline;cursor: pointer;font-size: 20px;" @click="isFullscreen = !isFullscreen" />
<svg-icon icon-class="dClose" style="cursor: pointer;font-size: 25px;margin-left: 10px;"
@click="historyVisible = false" />
</div> </div>
</div> </div>
</span> </span>
<div style="height:100%;margin:0;"> <div style="height:100%;margin:0;">
<HistoricalRecord <HistoricalRecord :trial-id="trialId" :site-id="siteId" :trial-site-survey-id="trialSiteSurveyId" />
:trial-id="trialId"
:site-id="siteId"
:trial-site-survey-id="trialSiteSurveyId"
/>
</div> </div>
</el-dialog> </el-dialog>
@ -194,6 +152,12 @@ import HistoricalRecord from './components/HistoricalRecord'
export default { export default {
name: 'QuestionForm', name: 'QuestionForm',
components: { BaseInfo, HistoricalParticipant, ParticipantList, EquipmentList, TopLang, HistoricalRecord }, components: { BaseInfo, HistoricalParticipant, ParticipantList, EquipmentList, TopLang, HistoricalRecord },
props: {
isPreview: {
type: Boolean,
default: false
}
},
data() { data() {
return { return {
trialId: this.$route.query.trialId, trialId: this.$route.query.trialId,
@ -208,7 +172,7 @@ export default {
btnLoading: false, btnLoading: false,
isFullscreen: false, isFullscreen: false,
historyVisible: false, historyVisible: false,
siteSurveyNoteInfo: null siteSurveyNoteInfo: {}
} }
}, },
mounted() { mounted() {
@ -229,6 +193,7 @@ export default {
if (res.Result.SiteSurveyFiledConfig && res.Result.SiteSurveyFiledConfig.ModifyFiledList.length > 0) { if (res.Result.SiteSurveyFiledConfig && res.Result.SiteSurveyFiledConfig.ModifyFiledList.length > 0) {
this.siteSurveyNoteInfo = res.Result.SiteSurveyFiledConfig.ModifyFiledList.find(i => i.NeedModifyFiled === 'SiteSurveyNote') this.siteSurveyNoteInfo = res.Result.SiteSurveyFiledConfig.ModifyFiledList.find(i => i.NeedModifyFiled === 'SiteSurveyNote')
} }
this.siteSurveyNoteInfo.IsCloseEquipmentSurvey = res.Result.SiteSurveyFiledConfig.IsCloseEquipmentSurvey
this.state = res.Result.TrialSiteSurvey.State this.state = res.Result.TrialSiteSurvey.State
this.siteId = res.Result.TrialSiteSurvey.TrialSiteId this.siteId = res.Result.TrialSiteSurvey.TrialSiteId
this.$refs['baseResearchInfo'].initForm(res.Result.TrialInfo, res.Result.TrialSiteSurvey, res.Result.SiteSurveyFiledConfig ? res.Result.SiteSurveyFiledConfig.NotShowFieldList : null) this.$refs['baseResearchInfo'].initForm(res.Result.TrialInfo, res.Result.TrialSiteSurvey, res.Result.SiteSurveyFiledConfig ? res.Result.SiteSurveyFiledConfig.NotShowFieldList : null)
@ -290,7 +255,7 @@ export default {
} }
} }
}).catch(() => { this.loading = false }) }).catch(() => { this.loading = false })
}).catch(() => {}) }).catch(() => { })
}, },
// //
generateAccount() { generateAccount() {
@ -325,7 +290,7 @@ export default {
}).catch(() => { }).catch(() => {
this.loading = false this.loading = false
}) })
}).catch(() => {}) }).catch(() => { })
}, },
// //
handleReject() { handleReject() {
@ -373,37 +338,44 @@ export default {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
.mt10{
.mt10 {
margin-top: 10px; margin-top: 10px;
} }
.header-wrapper{
.header-wrapper {
width: 70%; width: 70%;
margin: 20px auto; margin: 20px auto;
} }
.center-wrapper{
.center-wrapper {
flex: 1; flex: 1;
width: 70%; width: 70%;
margin: 0px auto; margin: 0px auto;
padding-bottom: 20px; padding-bottom: 20px;
overflow-y: auto; overflow-y: auto;
} }
::v-deep.el-card__body{
::v-deep.el-card__body {
padding: 10px; padding: 10px;
} }
// >>>.el-dialog__body{ // >>>.el-dialog__body{
// padding: 10px 20px 20px 20px; // padding: 10px 20px 20px 20px;
// } // }
::v-deep.full-dialog-container{ ::v-deep.full-dialog-container {
.el-dialog__body{ .el-dialog__body {
height: calc(100% - 80px); height: calc(100% - 80px);
} }
} }
::v-deep.dialog-container{
::v-deep.dialog-container {
// margin-top: 50px !important; // margin-top: 50px !important;
width:75%; width: 75%;
height:80%; height: 80%;
.el-dialog__body{
.el-dialog__body {
padding: 10px; padding: 10px;
height: calc(100% - 80px); height: calc(100% - 80px);
} }

View File

@ -7,16 +7,8 @@
<!-- <TopLang style="position: fixed;top: 40px;right: 40px" /> --> <!-- <TopLang style="position: fixed;top: 40px;right: 40px" /> -->
</h2> </h2>
<el-card shadow="hover"> <el-card shadow="hover">
<el-form <el-form ref="resetForm" v-loading="loading" :model="form" label-width="150px" style="width:80%;margin:0 auto;"
ref="resetForm" :rules="rules" class="demo-ruleForm" size="small">
v-loading="loading"
:model="form"
label-width="150px"
style="width:80%;margin:0 auto;"
:rules="rules"
class="demo-ruleForm"
size="small"
>
<!-- 项目编号 --> <!-- 项目编号 -->
<el-form-item :label="$t('trials:researchForm:form:trialId')"> <el-form-item :label="$t('trials:researchForm:form:trialId')">
<el-input v-model="form.TrialCode" disabled /> <el-input v-model="form.TrialCode" disabled />
@ -35,13 +27,10 @@
</el-form-item> </el-form-item>
<!-- 中心名称 --> <!-- 中心名称 -->
<el-form-item :label="$t('trials:researchForm:form:siteName')" prop="TrialSiteId"> <el-form-item :label="$t('trials:researchForm:form:siteName')" prop="TrialSiteId">
<el-select v-model="form.TrialSiteId" filterable style="width:100%;" @change="handleSiteChange"> <el-select v-model="form.TrialSiteId" filterable style="width:100%;" @change="handleSiteChange"
<el-option :disabled="isUpload">
v-for="(item,index) of siteOptions" <el-option v-for="(item, index) of siteOptions" :key="index" :label="item.TrialSiteAliasName"
:key="index" :value="item.TrialSiteId" />
:label="item.TrialSiteAliasName"
:value="item.TrialSiteId"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 中心编号 --> <!-- 中心编号 -->
@ -54,13 +43,14 @@
{{ $t('trials:researchForm:button:updateQsForm') }} {{ $t('trials:researchForm:button:updateQsForm') }}
</el-link> </el-link>
<!-- 取消更新调研表 --> <!-- 取消更新调研表 -->
<el-link v-else type="primary" @click="form.IsUpdate = false;form.ReplaceUserEmailOrPhone=''"> <el-link v-else type="primary" @click="form.IsUpdate = false; form.ReplaceUserEmailOrPhone = ''">
{{ $t('trials:researchForm:button:cancelUpdateQsForm') }} {{ $t('trials:researchForm:button:cancelUpdateQsForm') }}
</el-link> </el-link>
</el-form-item> </el-form-item>
<!-- 原调研表填写人邮箱 --> <!-- 原调研表填写人邮箱 -->
<el-form-item v-if="form.IsUpdate" :label="$t('trials:researchForm:form:originalEmail')" prop="ReplaceUserEmailOrPhone"> <el-form-item v-if="form.IsUpdate" :label="$t('trials:researchForm:form:originalEmail')"
<el-input v-model="form.ReplaceUserEmailOrPhone" autocomplete="new-password" /> prop="ReplaceUserEmailOrPhone">
<el-input v-model="form.ReplaceUserEmailOrPhone" autocomplete="new-password" :disabled="isUpload" />
</el-form-item> </el-form-item>
<!-- 联系邮箱 --> <!-- 联系邮箱 -->
<el-form-item :label="$t('trials:researchForm:form:contactorEmail')" prop="EmailOrPhone"> <el-form-item :label="$t('trials:researchForm:form:contactorEmail')" prop="EmailOrPhone">
@ -74,13 +64,9 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col style="width: 120px;margin-left: 10px"> <el-col style="width: 120px;margin-left: 10px">
<el-button <el-button size="small" class="codeBtn" style="width:100%;"
size="small" :disabled="sendDisabled || !form.EmailOrPhone || count > 0" @click="handleSendCode">{{
type="primary" this.$t('trials:researchForm:button:send') }} {{ sendTitle ? `${sendTitle}` : null }}</el-button>
style="width:100%;"
:disabled="sendDisabled || !form.EmailOrPhone || count > 0"
@click="handleSendCode"
>{{ this.$t('trials:researchForm:button:send') }} {{ sendTitle ? `${sendTitle}` : null }}</el-button>
</el-col> </el-col>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
@ -203,7 +189,8 @@ export default {
timer: null, timer: null,
msg: '', msg: '',
lang: 'zh', lang: 'zh',
isHaveSiteSurveyRecord: false isHaveSiteSurveyRecord: false,
isUpload: false
} }
}, },
computed: { computed: {
@ -221,6 +208,14 @@ export default {
this.trialId = this.$route.query.trialId this.trialId = this.$route.query.trialId
this.initPage() this.initPage()
} }
if (this.$route.query.isUpload) {
this.isUpload = true
this.form.IsUpdate = true
let { email, oldEMail, trialSiteId } = this.$route.query
if (trialSiteId) this.form.TrialSiteId = trialSiteId
if (oldEMail) this.form.ReplaceUserEmailOrPhone = oldEMail
if (email) this.form.EmailOrPhone = email
}
}, },
methods: { methods: {
...mapMutations({ setLanguage: 'lang/setLanguage' }), ...mapMutations({ setLanguage: 'lang/setLanguage' }),
@ -235,6 +230,9 @@ export default {
this.form[key] = Result[key] this.form[key] = Result[key]
} }
}) })
if (this.isUpload) {
this.handleSiteChange(this.form.TrialSiteId)
}
this.loading = false this.loading = false
}).catch(() => { this.loading = false }) }).catch(() => { this.loading = false })
}, },
@ -345,8 +343,24 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.codeBtn {
color: #409EFF;
border-color: #409EFF;
}
.codeBtn.is-disabled,
.codeBtn.is-disabled:focus,
.codeBtn.is-disabled:hover {
color: #c0c4cc;
cursor: not-allowed;
background-image: none;
background-color: #fff;
border-color: #ebeef5;
}
.question-login-wrapper { .question-login-wrapper {
padding: 20px; padding: 20px;
.box-wrapper { .box-wrapper {
width: 50%; width: 50%;
margin: 20px auto; margin: 20px auto;

View File

@ -7,51 +7,20 @@
{{ $t('trials:researchForm:form:title') }} {{ $t('trials:researchForm:form:title') }}
</h2> </h2>
<el-card shadow="hover" style="padding-top: 40px"> <el-card shadow="hover" style="padding-top: 40px">
<el-form <el-form ref="resetForm" v-loading="loading" :model="form" label-width="150px"
ref="resetForm" style="width: 80%; margin: 0 auto" :rules="rules" class="demo-ruleForm" size="small">
v-loading="loading"
:model="form"
label-width="150px"
style="width: 80%; margin: 0 auto"
:rules="rules"
class="demo-ruleForm"
size="small"
>
<!-- 联系邮箱 --> <!-- 联系邮箱 -->
<el-form-item <el-form-item :label="$t('trials:researchForm:form:contactorEmail')" prop="EmailOrPhone">
:label="$t('trials:researchForm:form:contactorEmail')" <el-input v-model="form.EmailOrPhone" autocomplete="new-password" @change="handleEmailChange" />
prop="EmailOrPhone"
>
<el-input
v-model="form.EmailOrPhone"
autocomplete="new-password"
@change="handleEmailChange"
/>
</el-form-item> </el-form-item>
<!-- 验证码 --> <!-- 验证码 -->
<el-form-item <el-form-item :label="$t('trials:researchForm:form:verifyCode')" prop="VerificationCode">
:label="$t('trials:researchForm:form:verifyCode')" <div style="display: flex;;justify-content: space-between;">
required <el-input v-model="form.VerificationCode" autocomplete="new-password" />
> <el-button size="small" style="margin-left: 10px;" :disabled="sendDisabled" class="codeBtn"
<el-col :span="20"> @click="handleSendCode">{{ this.$t('trials:researchForm:button:send')
<el-form-item prop="VerificationCode"> }}{{ count || count === 0 ? `(${count}s)` : '' }}</el-button>
<el-input </div>
v-model="form.VerificationCode"
autocomplete="new-password"
/>
</el-form-item>
</el-col>
<el-col :span="4">
<el-button
size="small"
type="primary"
style="width: 100%"
:disabled="sendDisabled"
@click="handleSendCode"
>{{ this.$t('trials:researchForm:button:send')
}}{{ count || count === 0 ? `(${count}s)` : '' }}</el-button
>
</el-col>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<!-- 取消 --> <!-- 取消 -->
@ -59,12 +28,7 @@
{{ $t('common:button:cancel') }} {{ $t('common:button:cancel') }}
</el-button> </el-button>
<!-- 提交 --> <!-- 提交 -->
<el-button <el-button size="small" type="primary" :loading="btnLoading" @click="onSubmit">
size="small"
type="primary"
:loading="btnLoading"
@click="onSubmit"
>
{{ $t('common:button:submit') }} {{ $t('common:button:submit') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
@ -216,7 +180,7 @@ export default {
this.$i18n.locale = this.$route.query.lang this.$i18n.locale = this.$route.query.lang
this.setLanguage(this.$route.query.lang) this.setLanguage(this.$route.query.lang)
}, },
mounted() {}, mounted() { },
methods: { methods: {
...mapMutations({ setLanguage: 'lang/setLanguage' }), ...mapMutations({ setLanguage: 'lang/setLanguage' }),
// //
@ -249,21 +213,16 @@ export default {
// this.$router.push({ path: `/researchForm?trialId=${this.trialId}&trialSiteSurveyId=${res.Result.TrialSiteSurveyId}` }) // this.$router.push({ path: `/researchForm?trialId=${this.trialId}&trialSiteSurveyId=${res.Result.TrialSiteSurveyId}` })
if (this.$route.query.trialId) { if (this.$route.query.trialId) {
this.$router.push({ this.$router.push({
path: `/curriculumVitae?Id=${ path: `/curriculumVitae?Id=${res.Result.DoctorId ? res.Result.DoctorId : ''
res.Result.DoctorId ? res.Result.DoctorId : '' }&tabActive=BasicInfo&ReviewStatus=${res.Result.ReviewStatus
}&tabActive=BasicInfo&ReviewStatus=${ }&trialId=${this.$route.query.trialId}&lang=${this.$route.query.lang
res.Result.ReviewStatus }`,
}&trialId=${this.$route.query.trialId}&lang=${
this.$route.query.lang
}`,
}) })
} else { } else {
this.$router.push({ this.$router.push({
path: `/curriculumVitae?Id=${ path: `/curriculumVitae?Id=${res.Result.DoctorId ? res.Result.DoctorId : ''
res.Result.DoctorId ? res.Result.DoctorId : '' }&tabActive=BasicInfo&ReviewStatus=${res.Result.ReviewStatus
}&tabActive=BasicInfo&ReviewStatus=${ }&lang=${this.$route.query.lang}`,
res.Result.ReviewStatus
}&lang=${this.$route.query.lang}`,
}) })
} }
}) })
@ -312,9 +271,8 @@ export default {
this.timer = setInterval(() => { this.timer = setInterval(() => {
if (this.count > 0 && this.count <= TIME_COUNT) { if (this.count > 0 && this.count <= TIME_COUNT) {
this.count-- this.count--
this.sendTitle = `${this.$t('trials:researchForm:button:send')}(${ this.sendTitle = `${this.$t('trials:researchForm:button:send')}(${this.count
this.count }s)`
}s)`
this.sendDisabled = true this.sendDisabled = true
} else { } else {
this.sendDisabled = false this.sendDisabled = false
@ -335,6 +293,7 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.question-login-wrapper { .question-login-wrapper {
padding: 20px; padding: 20px;
.box-wrapper { .box-wrapper {
width: 50%; width: 50%;
margin: 20px auto; margin: 20px auto;
@ -342,4 +301,19 @@ export default {
color: #303133; color: #303133;
} }
} }
.codeBtn {
color: #409EFF;
border-color: #409EFF;
}
.codeBtn.is-disabled,
.codeBtn.is-disabled:focus,
.codeBtn.is-disabled:hover {
color: #c0c4cc;
cursor: not-allowed;
background-image: none;
background-color: #fff;
border-color: #ebeef5;
}
</style> </style>

View File

@ -155,6 +155,17 @@ export default {
}, },
], ],
IdCard: [ IdCard: [
{
validator: (rule, value, callback) => {
let reg = new RegExp(/(^\d{15}$)|(^\d{17}([0-9]|X)$)/, 'ig')
if (value && !reg.test(value)) {
callback(new Error(this.$t('common:ruleMessage:pattern')))
} else {
callback()
}
},
trigger: 'blur',
},
{ {
max: 400, max: 400,
message: this.$t('form:rules:maxLength:400'), message: this.$t('form:rules:maxLength:400'),
@ -162,6 +173,17 @@ export default {
}, },
], ],
BankPhoneNum: [ BankPhoneNum: [
{
validator: (rule, value, callback) => {
let reg = new RegExp(/^\d{11}$/, 'i')
if (value && !reg.test(value)) {
callback(new Error(this.$t('common:ruleMessage:pattern')))
} else {
callback()
}
},
trigger: 'blur',
},
{ {
max: 400, max: 400,
message: this.$t('form:rules:maxLength:400'), message: this.$t('form:rules:maxLength:400'),

View File

@ -21,7 +21,7 @@
:maxlength="400" :maxlength="400"
/> />
</el-form-item> </el-form-item>
<!-- <el-form-item <el-form-item
:label="$t('system:Setting:label:Blind NameCN')" :label="$t('system:Setting:label:Blind NameCN')"
prop="BlindNameCN" prop="BlindNameCN"
> >
@ -30,7 +30,7 @@
style="width: 300px" style="width: 300px"
:maxlength="400" :maxlength="400"
/> />
</el-form-item> --> </el-form-item>
<el-form-item <el-form-item
:label="$t('system:Setting:label:Blind Publications')" :label="$t('system:Setting:label:Blind Publications')"
prop="BlindPublications" prop="BlindPublications"

View File

@ -79,10 +79,7 @@
<el-table-column prop="date" :label="$t('common:action:action')"> <el-table-column prop="date" :label="$t('common:action:action')">
<template <template
slot-scope="scope" slot-scope="scope"
v-if=" v-if="scope.row.ExperienceDataType != 3"
scope.row.ExperienceDataType != 2 &&
scope.row.ExperienceDataType != 3
"
> >
<el-button <el-button
type="text" type="text"

View File

@ -211,6 +211,17 @@ export default {
}, },
], ],
IdCard: [ IdCard: [
{
validator: (rule, value, callback) => {
let reg = new RegExp(/(^\d{15}$)|(^\d{17}([0-9]|X)$)/, 'ig')
if (value && !reg.test(value)) {
callback(new Error(this.$t('common:ruleMessage:pattern')))
} else {
callback()
}
},
trigger: 'blur',
},
{ {
max: 400, max: 400,
message: this.$t('form:rules:maxLength:400'), message: this.$t('form:rules:maxLength:400'),
@ -218,6 +229,17 @@ export default {
}, },
], ],
BankPhoneNum: [ BankPhoneNum: [
{
validator: (rule, value, callback) => {
let reg = new RegExp(/^\d{11}$/, 'i')
if (value && !reg.test(value)) {
callback(new Error(this.$t('common:ruleMessage:pattern')))
} else {
callback()
}
},
trigger: 'blur',
},
{ {
max: 400, max: 400,
message: this.$t('form:rules:maxLength:400'), message: this.$t('form:rules:maxLength:400'),

View File

@ -19,12 +19,12 @@
> >
{{ DATA.BlindName }} {{ DATA.BlindName }}
</el-form-item> </el-form-item>
<!-- <el-form-item <el-form-item
:label="$t('system:Setting:label:Blind NameCN')" :label="$t('system:Setting:label:Blind NameCN')"
style="width: 45%" style="width: 45%"
> >
{{ DATA.BlindNameCN }} {{ DATA.BlindNameCN }}
</el-form-item> --> </el-form-item>
<div style="display: flex; font-size: 14px; margin-bottom: 22px"> <div style="display: flex; font-size: 14px; margin-bottom: 22px">
<span style="display: inline-block; width: 120px; color: #000">{{ <span style="display: inline-block; width: 120px; color: #000">{{
$t('system:Setting:label:Blind Publications') $t('system:Setting:label:Blind Publications')
@ -109,19 +109,19 @@
<div class="form_title"> <div class="form_title">
{{ $t('system:Setting:title:Blinded information') }} {{ $t('system:Setting:title:Blinded information') }}
</div> </div>
<!-- <el-row> <el-row>
<el-col :span="12"> --> <el-col :span="12">
<el-form-item <el-form-item
:label="$t('system:Setting:label:Blind Name')" :label="$t('system:Setting:label:Blind Name')"
prop="BlindName" prop="BlindName"
> >
<el-input <el-input
v-model="form.BlindName" v-model="form.BlindName"
clearable clearable
:maxlength="400" :maxlength="400"
></el-input> ></el-input>
</el-form-item> </el-form-item>
<!-- </el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item
:label="$t('system:Setting:label:Blind NameCN')" :label="$t('system:Setting:label:Blind NameCN')"
@ -134,7 +134,7 @@
></el-input> ></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> --> </el-row>
<el-form-item <el-form-item
:label="$t('system:Setting:label:Blind Publications')" :label="$t('system:Setting:label:Blind Publications')"
prop="BlindPublications" prop="BlindPublications"

View File

@ -2,14 +2,8 @@
<div class="curriculumVitae" v-loading="loading"> <div class="curriculumVitae" v-loading="loading">
<div class="leftMenu"> <div class="leftMenu">
<div class="title">{{ $t('curriculumVitae:menu:title') }}</div> <div class="title">{{ $t('curriculumVitae:menu:title') }}</div>
<el-menu <el-menu :default-active="activeIndex" class="el-menu-demo" mode="vertical" @select="handleSelect"
:default-active="activeIndex" background-color="#eee" active-text-color="#000">
class="el-menu-demo"
mode="vertical"
@select="handleSelect"
background-color="#eee"
active-text-color="#000"
>
<el-menu-item index="info"> <el-menu-item index="info">
{{ $t('curriculumVitae:menu:info') }} {{ $t('curriculumVitae:menu:info') }}
</el-menu-item> </el-menu-item>
@ -70,94 +64,58 @@
</el-button> </el-button>
</div> </div>
</div> </div>
<!--个人信息-->
<div class="box" id="info"> <div class="box" id="info">
<info <info :DATA="{
:DATA="{ ...reviewerData.BasicInfoView,
...reviewerData.BasicInfoView, ...reviewerData.EmploymentView,
...reviewerData.EmploymentView, }" :reviewerId.sync="reviewerId" :isEN="isEN" @getInfo="getDetail" />
}"
:reviewerId.sync="reviewerId"
:isEN="isEN"
@getInfo="getDetail"
/>
</div> </div>
<!--概述-->
<div class="box" id="summarize"> <div class="box" id="summarize">
<summarize <summarize :DATA="{
:DATA="{ ...reviewerData.SummarizeInfo,
...reviewerData.SummarizeInfo, }" :reviewerId.sync="reviewerId" :trialId="trialId" :isEN="isEN" @getInfo="getDetail" />
}"
:reviewerId.sync="reviewerId"
:trialId="trialId"
:isEN="isEN"
@getInfo="getDetail"
/>
</div> </div>
<!--专业-->
<div class="box" id="specialty"> <div class="box" id="specialty">
<specialty <specialty :DATA="{
:DATA="{ ...reviewerData.SpecialtyView,
...reviewerData.SpecialtyView, }" :isEN="isEN" :reviewerId.sync="reviewerId" @getInfo="getDetail" />
}"
:isEN="isEN"
:reviewerId.sync="reviewerId"
@getInfo="getDetail"
/>
</div> </div>
<!--教育经历-->
<div class="box" id="educationalExperience"> <div class="box" id="educationalExperience">
<educationalExperience <educationalExperience :DATA="reviewerData.EducationList" :isEN="isEN" :reviewerId.sync="reviewerId"
:DATA="reviewerData.EducationList" @getInfo="getDetail" />
:isEN="isEN"
:reviewerId.sync="reviewerId"
@getInfo="getDetail"
/>
</div> </div>
<!--进修培训-->
<div class="box" id="continuingTraining"> <div class="box" id="continuingTraining">
<continuingTraining <continuingTraining :DATA="reviewerData.PostgraduateList" :isEN="isEN" :reviewerId.sync="reviewerId"
:DATA="reviewerData.PostgraduateList" @getInfo="getDetail" />
:isEN="isEN"
:reviewerId.sync="reviewerId"
@getInfo="getDetail"
/>
</div> </div>
<!--科研课题-->
<div class="box" id="scientificResearchProject"> <div class="box" id="scientificResearchProject">
<scientificResearchProject <scientificResearchProject :DATA="{ ...reviewerData.ResearchPublicationView }" :isEN="isEN"
:DATA="{ ...reviewerData.ResearchPublicationView }" :reviewerId.sync="reviewerId" @getInfo="getDetail" />
:isEN="isEN"
:reviewerId.sync="reviewerId"
@getInfo="getDetail"
/>
</div> </div>
<!--临床试验-->
<div class="box" id="clinicalTrials"> <div class="box" id="clinicalTrials">
<clinicalTrials <clinicalTrials :DATA="{ ...reviewerData.TrialExperienceView }" :isEN="isEN" :reviewerId.sync="reviewerId"
:DATA="{ ...reviewerData.TrialExperienceView }" :trialId="trialId" @getInfo="getDetail" />
:isEN="isEN"
:reviewerId.sync="reviewerId"
:trialId="trialId"
@getInfo="getDetail"
/>
</div> </div>
<!--gcp证书-->
<div class="box" id="treatise"> <div class="box" id="treatise">
<treatise <treatise :DATA="{ ...reviewerData.ResearchPublicationView }" :isEN="isEN" :reviewerId.sync="reviewerId"
:DATA="{ ...reviewerData.ResearchPublicationView }" @getInfo="getDetail" />
:isEN="isEN"
:reviewerId.sync="reviewerId"
@getInfo="getDetail"
/>
</div> </div>
<!--其他相关经历-->
<div class="box" id="other"> <div class="box" id="other">
<other <other :DATA="{ ...reviewerData.ResearchPublicationView }" :isEN="isEN" :reviewerId.sync="reviewerId"
:DATA="{ ...reviewerData.ResearchPublicationView }" @getInfo="getDetail" />
:isEN="isEN"
:reviewerId.sync="reviewerId"
@getInfo="getDetail"
/>
</div> </div>
<div class="box" id="pay"> <div class="box" id="pay">
<pay <pay :DATA="{ ...reviewerData.PaymentModeInfo }" :isEN="isEN" :reviewerId.sync="reviewerId"
:DATA="{ ...reviewerData.PaymentModeInfo }" @getInfo="getDetail" />
:isEN="isEN"
:reviewerId.sync="reviewerId"
@getInfo="getDetail"
/>
</div> </div>
<div class="box" id="setting" v-if="isPM"> <div class="box" id="setting" v-if="isPM">
<setting :isEN="isEN" :reviewerId.sync="reviewerId" /> <setting :isEN="isEN" :reviewerId.sync="reviewerId" />
@ -167,38 +125,19 @@
<!--简历附件--> <!--简历附件-->
<curriculum :isEN="isEN" :reviewerId.sync="reviewerId" /> <curriculum :isEN="isEN" :reviewerId.sync="reviewerId" />
<!--资历证书--> <!--资历证书-->
<certificate <certificate :DATA="reviewerData.AttachmentList" :isEN="isEN" :reviewerId.sync="reviewerId"
:DATA="reviewerData.AttachmentList" @getInfo="getDetail" />
:isEN="isEN"
:reviewerId.sync="reviewerId"
@getInfo="getDetail"
/>
<!--协议--> <!--协议-->
<agreement <agreement :DATA="reviewerData.AttachmentList" :isEN="isEN" :isPM="isPM" :reviewerId.sync="reviewerId"
:DATA="reviewerData.AttachmentList" @getInfo="getDetail" />
:isEN="isEN"
:isPM="isPM"
:reviewerId.sync="reviewerId"
@getInfo="getDetail"
/>
</div> </div>
</div> </div>
<el-dialog :visible.sync="visible" fullscreen append-to-body> <el-dialog :visible.sync="visible" fullscreen append-to-body>
<div style="height: 100%; overflow: auto"> <div style="height: 100%; overflow: auto">
<preview <preview :isEN="isEN" :reviewerId.sync="reviewerId" :trialId="trialId" :isAll="isAll" v-if="visible" />
:isEN="isEN"
:reviewerId.sync="reviewerId"
:trialId="trialId"
:isAll="isAll"
v-if="visible"
/>
</div> </div>
</el-dialog> </el-dialog>
<holiday <holiday v-if="holidayVisible" :reviewerId.sync="reviewerId" :visible.sync="holidayVisible" />
v-if="holidayVisible"
:reviewerId.sync="reviewerId"
:visible.sync="holidayVisible"
/>
<!-- <setting <!-- <setting
v-if="settingVisible" v-if="settingVisible"
:reviewerId.sync="reviewerId" :reviewerId.sync="reviewerId"
@ -383,12 +322,14 @@ export default {
position: relative; position: relative;
height: 100%; height: 100%;
} }
.title { .title {
line-height: 50px; line-height: 50px;
background-color: #fff; background-color: #fff;
text-align: center; text-align: center;
font-weight: bold; font-weight: bold;
} }
.leftMenu { .leftMenu {
position: absolute; position: absolute;
left: 0; left: 0;
@ -397,12 +338,15 @@ export default {
height: 100%; height: 100%;
background-color: #eee; background-color: #eee;
border-right: 1px solid #eee; border-right: 1px solid #eee;
::v-deep .el-menu { ::v-deep .el-menu {
padding: 5px 5px 0; padding: 5px 5px 0;
} }
::v-deep .is-active { ::v-deep .is-active {
background-color: #fff !important; background-color: #fff !important;
position: relative; position: relative;
&::before { &::before {
display: block; display: block;
content: ''; content: '';
@ -415,6 +359,7 @@ export default {
} }
} }
} }
.main { .main {
width: calc(100% - 300px); width: calc(100% - 300px);
height: 100%; height: 100%;
@ -423,9 +368,11 @@ export default {
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
} }
.content { .content {
width: calc(100% - 300px); width: calc(100% - 300px);
padding: 0 50px 0 20px; padding: 0 50px 0 20px;
.title { .title {
line-height: 50px; line-height: 50px;
background-color: #fff; background-color: #fff;
@ -434,35 +381,42 @@ export default {
justify-content: space-between; justify-content: space-between;
} }
} }
.box { .box {
border: 1px solid #ddd; border: 1px solid #ddd;
border-radius: 3px; border-radius: 3px;
padding: 15px; padding: 15px;
margin-bottom: 20px; margin-bottom: 20px;
} }
::v-deep .noData { ::v-deep .noData {
color: #909399; color: #909399;
text-align: center; text-align: center;
} }
.rightFile { .rightFile {
width: 300px; width: 300px;
padding-right: 10px; padding-right: 10px;
::v-deep .title { ::v-deep .title {
line-height: 50px; line-height: 50px;
background-color: #fff; background-color: #fff;
text-align: left; text-align: left;
font-weight: bold; font-weight: bold;
} }
::v-deep .fileBox { ::v-deep .fileBox {
background-color: #eee; background-color: #eee;
padding: 10px; padding: 10px;
font-size: 14px; font-size: 14px;
border-radius: 3px; border-radius: 3px;
} }
::v-deep .file_title { ::v-deep .file_title {
line-height: 40px; line-height: 40px;
font-weight: bold; font-weight: bold;
} }
::v-deep .btnBox { ::v-deep .btnBox {
display: flex; display: flex;
align-items: center; align-items: center;
@ -474,17 +428,23 @@ export default {
width: 100%; width: 100%;
display: flex; display: flex;
margin-bottom: 10px; margin-bottom: 10px;
.name { .name {
width: 70%; width: 70%;
white-space: nowrap; /* 文本不会换行,会在同一行内继续,直到遇到<br>标签为止 */ white-space: nowrap;
text-overflow: ellipsis; /* 当文本溢出包含它的容器时,显示省略号(...)来表示被截断的文本 */ /* 文本不会换行,会在同一行内继续,直到遇到<br>标签为止 */
overflow: hidden; /* 隐藏溢出容器的文本 */ text-overflow: ellipsis;
/* 当文本溢出包含它的容器时,显示省略号(...)来表示被截断的文本 */
overflow: hidden;
/* 隐藏溢出容器的文本 */
} }
i { i {
cursor: pointer; cursor: pointer;
margin: 3px; margin: 3px;
color: #409eff; color: #409eff;
} }
.disable { .disable {
cursor: not-allowed; cursor: not-allowed;
color: #909399; color: #909399;

View File

@ -591,9 +591,32 @@
</div> </div>
</div> </div>
<div class="file" v-if="isAll && hasFile"> <div class="file" v-if="isAll && hasFile">
<div class="curriculum" v-if="resumeListEN && resumeListEN.length > 0"> <div
class="curriculum"
v-if="
(resumeListCN && resumeListCN.length > 0) ||
(resumeListEN && resumeListEN.length > 0)
"
>
<div class="title">{{ $t('curriculumVitae:curriculum:title') }}</div> <div class="title">{{ $t('curriculumVitae:curriculum:title') }}</div>
<div class="fileBox"> <div class="fileBox">
<div
class="file_title"
v-if="resumeListCN && resumeListCN.length > 0"
>
{{ $t('curriculumVitae:curriculum:fileTitle:CN') }}
</div>
<template v-if="true">
<div class="file" v-for="item in resumeListCN" :key="item.Id">
<div class="name" :title="item.FileName">{{ item.FileName }}</div>
<i
class="el-icon-download"
:title="$t('common:button:download')"
@click.stop="handlePreview(item)"
/>
</div>
</template>
<div class="noData" v-else>{{ $t('curriculumVitae:noData') }}</div>
<div <div
class="file_title" class="file_title"
v-if="resumeListEN && resumeListEN.length > 0" v-if="resumeListEN && resumeListEN.length > 0"

View File

@ -0,0 +1,228 @@
<template>
<div class="detail">
<div class="attachment" v-if="Array.isArray(info.AttachmentList) && info.AttachmentList.length > 0">
<div class="box" v-for="item of info.AttachmentList" :key="item.AttachmentPath" @click="perview(item)">
<i :class="`icon icon_file icon_${item.type}`" />
<span>{{ item.AttachmentName }}</span>
</div>
<span class="downLoadTip" @click="downloadFile">{{ $t('system:email:tip:allDownLoad') }}</span>
</div>
<div class="content" v-html="info.Content"></div>
<viewer ref="picture_perview" style="margin: 0 10px"
v-if="rowData.type && ['png', 'jpg', 'jpeg'].includes(rowData.type.toLowerCase())"
:images="[`${OSSclientConfig.basePath}${rowData.AttachmentPath}`]" :options="viewerOptions">
<img v-show="false" :src="`${OSSclientConfig.basePath}${rowData.AttachmentPath}`" alt="Image" />
</viewer>
</div>
</template>
<script>
import { downLoadFile } from '@/utils/stream.js'
export default {
name: "emailDetail",
props: {
info: {
type: Object,
default: () => {
return {}
}
}
},
data() {
return {
rowData: {},
viewerOptions: {
toolbar: {
zoomIn: true,
zoomOut: true,
reset: true,
prev: false,
next: false,
rotateLeft: true,
rotateRight: true,
flipHorizontal: true,
flipVertical: true,
}
}
}
},
methods: {
//
perview(data) {
this.rowData = data
if (['.ppt',
'.pptx',
'.doc',
'.docx',
'.xls',
'.xlsx'].includes(`.${data.type.toLowerCase()}`)) {
this.$onlyOffice({
path: data.AttachmentPath,
type: data.type,
title: data.AttachmentName
})
}
if (['.jpg',
'.jpeg',
'.png'].includes(`.${data.type.toLowerCase()}`)) {
this.$refs['picture_perview'].$viewer.show()
}
if (['.pdf'].includes(`.${data.type.toLowerCase()}`)) {
this.$preview({
path: data.Path || data.AttachmentPath,
type: 'pdf',
title: data.AttachmentName,
})
}
},
async downloadFile() {
try {
let { files, name } = this.formatDownloadFile(this.info.AttachmentList)
let res = await downLoadFile(files, name, 'zip')
} catch (err) {
console.log(err)
}
},
//
formatDownloadFile(list) {
let files = [],
name = `Attachment_${new Date().getTime()}.zip`
list.forEach(item => {
let obj = {
name: item.AttachmentName,
url: this.OSSclientConfig.basePath + item.AttachmentPath,
}
files.push(obj)
})
return { files, name }
},
}
}
</script>
<style lang="scss" scoped>
.attachment {
border-bottom: 1px solid #EBEEF5;
padding: 10px 0 0 0;
display: flex;
.box {
padding: 5px 10px;
display: flex;
align-items: center;
max-width: 400px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
border-radius: 5px;
background-color: #E4E7ED;
cursor: pointer;
margin-right: 10px;
margin-bottom: 10px;
i {
margin-right: 5px;
}
}
.downLoadTip {
cursor: pointer;
font-size: 14px;
color: #409EFF;
}
}
.content {
width: 100%;
overflow: hidden;
}
.icon {
height: 20px;
width: 20px;
padding: 0px;
line-height: 20px;
margin-right: 6px;
margin-top: 6px;
}
/*文件*/
.icon_file {
width: 16px !important;
height: 16px !important;
margin-right: 6px;
background-size: inherit;
background-image: url(@/assets/0.file-16.png);
background-position: 0 0;
margin-top: -2px;
background-repeat: no-repeat;
font-style: normal;
display: inline-block;
pointer-events: none;
font-size: 85%;
}
/*文件夹*/
.icon_folder {
background-image: url(@/assets/folder_win11_small.png);
margin-top: -6px;
margin-left: 2px;
margin-right: 6px;
background-repeat: no-repeat;
}
/*docx*/
.icon_docx {
background-position: -81px -560px !important;
margin-top: 0;
margin-left: 2px;
}
/*doc*/
.icon_doc {
background-position: -81px -592px !important;
margin-top: 0;
margin-left: 2px;
}
/*xlsx*/
.icon_xlsx {
background-position: -81px -48px !important;
margin-top: 0;
margin-left: 2px;
}
/*pdf*/
.icon_pdf {
background-position: -81px -352px !important;
margin-top: 0;
margin-left: 2px;
}
/*pptx*/
.icon_pptx {
background-position: -81px -288px !important;
margin-top: 0;
margin-left: 2px;
}
/*zip*/
.icon_zip {
background-position: 0 0 !important;
margin-top: -2px;
margin-left: 2px;
}
/*ppt*/
.icon_ppt {
background-position: -81px -304px !important;
margin-top: 0;
margin-left: 2px;
}
/*xls*/
.icon_xls {
background-position: -81px -96px !important;
margin-top: 0;
margin-left: 2px;
}
</style>

View File

@ -0,0 +1,264 @@
<template>
<div class="event">
<div ref="leftContainer" class="left">
<el-form :inline="true">
<el-form-item :label="$t('system:email:search:ToRecipientName')">
<el-input v-model="searchData.ToRecipientName" clearable />
</el-form-item>
<el-form-item :label="$t('system:email:search:CcRecipientName')">
<el-input v-model="searchData.CcRecipientName" clearable />
</el-form-item>
<el-form-item :label="$t('system:email:search:EmailStateEnum')">
<el-select v-model="searchData.EmailStateEnum" clearable filterable placeholder="">
<el-option v-for="item in $d.EmailState" :key="item.id" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<!-- <el-form-item :label="$t('system:email:search:EmailStateEnum')">
<el-select v-model="searchData.EmailStateEnum" clearable filterable placeholder="">
<el-option v-for="item in $d.EmailState" :key="item.id" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item> -->
<el-form-item :label="$t('system:email:search:emailDate')">
<el-date-picker v-model="datetimerange" type="datetimerange"
:default-time="['00:00:00', '23:59:59']" :start-placeholder="$t('feedBack:search:beginTime')"
:end-placeholder="$t('feedBack:search:endTime')" value-format="yyyy-MM-dd HH:mm:ss"
@change="handleDatetimeChange" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="small" @click="getList">
{{ $t('common:button:search') }}
</el-button>
<el-button icon="el-icon-refresh-left" size="small" @click="handleReset">
{{ $t('common:button:reset') }}
</el-button>
<!-- <el-button type="primary" size="small" @click="synchronizationEmail">
{{ $t('system:email:button:sync') }}
</el-button> -->
</el-form-item>
</el-form>
<el-table v-loading="loading" v-adaptive="{ bottomOffset: 45 }" height="100" :data="list" class="table"
@sort-change="handleSortByColumn">
<el-table-column type="index" width="50" />
<el-table-column :label="$t('system:email:table:messageId')" prop="MessageId" show-overflow-tooltip
sortable="custom" />
<el-table-column :label="$t('system:email:table:emailSubject')" prop="EmailSubject"
show-overflow-tooltip />
<el-table-column :label="$t('system:email:table:ToRecipientName')" prop="ToRecipientName"
show-overflow-tooltip>
<template slot-scope="scope">
<el-tooltip class="item" effect="dark" :content="scope.row.RecipientList.filter(item => item.RecipientTypeEnum === 0).map(item =>
`${item.RecipientName}: ${item.RecipientAddress}`).join('<br/>')" placement="top-start"
v-if="Array.isArray(scope.row.RecipientList) && scope.row.RecipientList.length > 0">
<span>{{Array.isArray(scope.row.RecipientList) && scope.row.RecipientList.length > 0
? scope.row.RecipientList.filter(item => item.RecipientTypeEnum === 0).map(item =>
item.RecipientName).join(", ") : ''
}}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column :label="$t('system:email:table:CcRecipientName')" prop="CcRecipientName"
show-overflow-tooltip>
<template slot-scope="scope">
<el-tooltip class="item" effect="dark" :content="scope.row.RecipientList.filter(item => item.RecipientTypeEnum === 1).map(item =>
`${item.RecipientName}: ${item.RecipientAddress}`).join('<br/>')" placement="top-start"
v-if="Array.isArray(scope.row.RecipientList) && scope.row.RecipientList.length > 0">
<span>{{Array.isArray(scope.row.RecipientList) && scope.row.RecipientList.length > 0
? scope.row.RecipientList.filter(item => item.RecipientTypeEnum === 1).map(item =>
item.RecipientName).join(", ") : ''
}}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column :label="$t('system:email:table:emailDate')" prop="EmailDate" show-overflow-tooltip
sortable="custom" />
<el-table-column :label="$t('system:email:table:emailStateEnum')" prop="EmailStateEnum"
show-overflow-tooltip sortable="custom">
<template slot-scope="scope">
<el-tag :type="scope.row.EmailStateEnum === 1 ? 'danger' : ''">{{ $fd("EmailState",
scope.row.EmailStateEnum) }}</el-tag>
</template>
</el-table-column>
<el-table-column :label="$t('system:email:table:errorInfo')" prop="ErrorInfo" show-overflow-tooltip />
<el-table-column :label="$t('common:action:action')" prop="" show-overflow-tooltip>
<template slot-scope="scope">
<el-button type="text" @click="view(scope.row)">
{{ $t('common:button:view') }}
</el-button>
<!-- <el-button type="text" @click="resendEmail(scope.row)">
{{ $t('system:email:button:resendEmail') }}
</el-button> -->
</template>
</el-table-column>
</el-table>
<div class="pagination" style="text-align: right; margin-top: 5px">
<pagination :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
@pagination="getList" />
</div>
</div>
<base-model v-if="model_cfg.visible" :config="model_cfg">
<template slot="dialog-body">
<emailDetail :info="info" />
</template>
</base-model>
</div>
</template>
<script>
import { getReSendEmail, getEmailInfo } from '@/api/admin'
import Pagination from '@/components/Pagination'
import BaseModel from '@/components/BaseModel'
import emailDetail from "./detail"
const searchDataDefault = () => {
return {
// TrialId: null,
// EmailStartDate: null,
// EmailEndDate: null,
// EmailStateEnum: null,
// ToRecipientName: null,
// CcRecipientName: null,
Id: null,
Asc: false,
SortField: 'CreateTime',
PageIndex: 1,
PageSize: 20,
}
}
export default {
name: 'emailLog',
components: { Pagination, BaseModel, emailDetail },
props: {
isSystem: {
type: Boolean,
default: true
},
rowData: {
type: Object,
default: () => {
return {}
}
}
},
data() {
return {
searchData: searchDataDefault(),
list: [],
total: 0,
loading: false,
datetimerange: [],
model_cfg: { visible: false, title: '', width: '500px', fullscreen: true, appendToBody: true },
info: null,
}
},
watch: {
"rowData.Id": {
handler() {
this.getList()
}
}
},
mounted() {
this.getList()
},
methods: {
getList() {
this.loading = true
if (!this.rowData.Id) return false
this.searchData.Id = this.rowData.Id
if (!this.isSystem) this.searchData.TrialId = this.$route.query.trialId
getReSendEmail(this.searchData)
.then((res) => {
this.loading = false
this.list = res.Result.CurrentPageData
this.total = res.Result.TotalCount
})
.catch(() => {
this.loading = false
})
},
//
async view(row) {
try {
let data = {
Id: row.Id,
TrialId: this.$route.query.trialId
// Id: "EC660000-BA37-5C60-8680-08DE1CD6931B"
}
let res = await getEmailInfo(data)
if (res.IsSuccess) {
this.info = res.Result
if (Array.isArray(this.info.AttachmentList) && this.info.AttachmentList.length > 0) {
this.info.AttachmentList.forEach(item => {
var type = item.AttachmentName
.substring(item.AttachmentName.lastIndexOf('.'))
.toLocaleLowerCase().split('.')[1];
item.type = type
})
}
this.model_cfg.visible = true
}
} catch (err) {
console.log(err)
}
},
//
handleReset() {
this.searchData = searchDataDefault()
this.datetimerange = []
this.getList()
},
//
handleSortByColumn(column) {
if (column.order === 'ascending') {
this.searchData.Asc = true
} else {
this.searchData.Asc = false
}
this.searchData.SortField = column.prop
this.searchData.PageIndex = 1
this.getList()
},
handleDatetimeChange(val) {
if (val) {
this.searchData.EmailStartDate = val[0]
this.searchData.EmailEndDate = val[1]
} else {
this.searchData.EmailStartDate = ''
this.searchData.EmailEndDate = ''
}
},
},
}
</script>
<style lang="scss" scoped>
.event {
height: 100%;
box-sizing: border-box;
display: flex;
padding: 10px;
border-radius: 5px;
.left {
display: flex;
flex-direction: column;
width: 0;
flex-grow: 4;
// border-right: 1px solid #ccc;
.filter-container {
display: flex;
align-items: center;
margin: 5px;
}
.data-table {
flex: 1;
padding: 5px 0px;
}
.pagination-container {
text-align: right;
}
}
}
</style>

View File

@ -0,0 +1,298 @@
<template>
<div class="event">
<div ref="leftContainer" class="left">
<el-form :inline="true">
<el-form-item :label="$t('system:email:search:ToRecipientName')">
<el-input v-model="searchData.ToRecipientName" clearable />
</el-form-item>
<el-form-item :label="$t('system:email:search:CcRecipientName')">
<el-input v-model="searchData.CcRecipientName" clearable />
</el-form-item>
<el-form-item :label="$t('system:email:search:EmailStateEnum')">
<el-select v-model="searchData.EmailStateEnum" clearable filterable placeholder="">
<el-option v-for="item in $d.EmailState" :key="item.id" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<!-- <el-form-item :label="$t('system:email:search:EmailStateEnum')">
<el-select v-model="searchData.EmailStateEnum" clearable filterable placeholder="">
<el-option v-for="item in $d.EmailState" :key="item.id" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item> -->
<el-form-item :label="$t('system:email:search:emailDate')">
<el-date-picker v-model="datetimerange" type="datetimerange"
:default-time="['00:00:00', '23:59:59']" :start-placeholder="$t('feedBack:search:beginTime')"
:end-placeholder="$t('feedBack:search:endTime')" value-format="yyyy-MM-dd HH:mm:ss"
@change="handleDatetimeChange" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="small" @click="getList">
{{ $t('common:button:search') }}
</el-button>
<el-button icon="el-icon-refresh-left" size="small" @click="handleReset">
{{ $t('common:button:reset') }}
</el-button>
<el-button type="primary" size="small" @click="synchronizationEmail">
{{ $t('system:email:button:sync') }}
</el-button>
</el-form-item>
</el-form>
<el-table v-loading="loading" v-adaptive="{ bottomOffset: 45 }" height="100" :data="list" class="table"
@sort-change="handleSortByColumn">
<el-table-column type="index" width="50" />
<el-table-column :label="$t('system:email:table:messageId')" prop="MessageId" show-overflow-tooltip
sortable="custom" />
<el-table-column :label="$t('system:email:table:emailSubject')" prop="EmailSubject"
show-overflow-tooltip />
<el-table-column :label="$t('system:email:table:ToRecipientName')" prop="ToRecipientName"
show-overflow-tooltip>
<template slot-scope="scope">
<el-tooltip class="item" effect="dark" :content="scope.row.RecipientList.filter(item => item.RecipientTypeEnum === 0).map(item =>
`${item.RecipientName}: ${item.RecipientAddress}`).join('<br/>')" placement="top-start"
v-if="Array.isArray(scope.row.RecipientList) && scope.row.RecipientList.length > 0">
<span>{{Array.isArray(scope.row.RecipientList) && scope.row.RecipientList.length > 0
? scope.row.RecipientList.filter(item => item.RecipientTypeEnum === 0).map(item =>
item.RecipientName).join(", ") : ''
}}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column :label="$t('system:email:table:CcRecipientName')" prop="CcRecipientName"
show-overflow-tooltip>
<template slot-scope="scope">
<el-tooltip class="item" effect="dark" :content="scope.row.RecipientList.filter(item => item.RecipientTypeEnum === 1).map(item =>
`${item.RecipientName}: ${item.RecipientAddress}`).join('<br/>')" placement="top-start"
v-if="Array.isArray(scope.row.RecipientList) && scope.row.RecipientList.length > 0">
<span>{{Array.isArray(scope.row.RecipientList) && scope.row.RecipientList.length > 0
? scope.row.RecipientList.filter(item => item.RecipientTypeEnum === 1).map(item =>
item.RecipientName).join(", ") : ''
}}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column :label="$t('system:email:table:emailDate')" prop="EmailDate" show-overflow-tooltip
sortable="custom" />
<el-table-column :label="$t('system:email:table:emailStateEnum')" prop="EmailStateEnum"
show-overflow-tooltip sortable="custom">
<template slot-scope="scope">
<el-tag :type="scope.row.EmailStateEnum === 1 ? 'danger' : ''">{{ $fd("EmailState",
scope.row.EmailStateEnum) }}</el-tag>
</template>
</el-table-column>
<el-table-column :label="$t('system:email:table:errorInfo')" prop="ErrorInfo" show-overflow-tooltip />
<el-table-column :label="$t('common:action:action')" fixed="right" prop="" show-overflow-tooltip
min-width="120px">
<template slot-scope="scope">
<el-button type="text" @click="view(scope.row)">
{{ $t('common:button:view') }}
</el-button>
<el-button type="text" @click="resendEmail(scope.row)">
{{ $t('system:email:button:resendEmail') }}
</el-button>
<el-button type="text" @click="openResendEmailList(scope.row)">
{{ $t('system:email:button:resendEmailList') }}
</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination" style="text-align: right; margin-top: 5px">
<pagination :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
@pagination="getList" />
</div>
</div>
<base-model v-if="model_cfg.visible" :config="model_cfg">
<template slot="dialog-body">
<emailDetail :info="info" />
</template>
</base-model>
<el-dialog title="" :visible.sync="resendVisible" width="30%" :fullscreen='true'>
<resendList :rowData="info" :isSystem="isSystem" />
</el-dialog>
</div>
</template>
<script>
import { getEmailLogList, resendEmail, getEmailInfo, synchronizationEmail } from '@/api/admin'
import Pagination from '@/components/Pagination'
import BaseModel from '@/components/BaseModel'
import emailDetail from "./components/detail"
import resendList from "./components/resendList"
const searchDataDefault = () => {
return {
TrialId: null,
EmailStartDate: null,
EmailEndDate: null,
EmailStateEnum: null,
ToRecipientName: null,
CcRecipientName: null,
Asc: false,
SortField: 'CreateTime',
PageIndex: 1,
PageSize: 20,
}
}
export default {
name: 'emailLog',
components: { Pagination, BaseModel, emailDetail, resendList },
props: {
isSystem: {
type: Boolean,
default: true
}
},
data() {
return {
searchData: searchDataDefault(),
list: [],
total: 0,
loading: false,
datetimerange: [],
model_cfg: { visible: false, title: '', width: '500px', fullscreen: true },
info: null,
resendVisible: false
}
},
mounted() {
this.getList()
},
methods: {
openResendEmailList(row) {
this.info = row
this.resendVisible = true
},
getList() {
this.loading = true
if (!this.isSystem) this.searchData.TrialId = this.$route.query.trialId
getEmailLogList(this.searchData)
.then((res) => {
this.loading = false
this.list = res.Result.CurrentPageData
this.total = res.Result.TotalCount
})
.catch(() => {
this.loading = false
})
},
//
async view(row) {
try {
let data = {
Id: row.Id,
TrialId: this.$route.query.trialId
// Id: "EC660000-BA37-5C60-8680-08DE1CD6931B"
}
let res = await getEmailInfo(data)
if (res.IsSuccess) {
this.info = res.Result
if (Array.isArray(this.info.AttachmentList) && this.info.AttachmentList.length > 0) {
this.info.AttachmentList.forEach(item => {
var type = item.AttachmentName
.substring(item.AttachmentName.lastIndexOf('.'))
.toLocaleLowerCase().split('.')[1];
item.type = type
})
}
this.model_cfg.visible = true
}
} catch (err) {
console.log(err)
}
},
//
async synchronizationEmail() {
try {
let data = {
TrialId: this.$route.query.trialId
}
this.loading = true
let res = await synchronizationEmail(data)
this.loading = false
if (res.IsSuccess) {
this.getList()
this.$message.success(this.$t("system:email:message:syncSuccessfully"))
}
} catch (err) {
this.loading = false
console.log(err)
}
},
//
async resendEmail(row) {
try {
let data = {
Id: row.Id,
TrialId: this.$route.query.trialId
}
this.loading = true
let res = await resendEmail(data)
this.loading = false
if (res.IsSuccess) {
this.getList()
this.$message.success(this.$t("system:email:message:resendSuccessfully"))
}
} catch (err) {
this.loading = false
console.log(err)
}
},
//
handleReset() {
this.searchData = searchDataDefault()
this.datetimerange = []
this.getList()
},
//
handleSortByColumn(column) {
if (column.order === 'ascending') {
this.searchData.Asc = true
} else {
this.searchData.Asc = false
}
this.searchData.SortField = column.prop
this.searchData.PageIndex = 1
this.getList()
},
handleDatetimeChange(val) {
if (val) {
this.searchData.EmailStartDate = val[0]
this.searchData.EmailEndDate = val[1]
} else {
this.searchData.EmailStartDate = ''
this.searchData.EmailEndDate = ''
}
},
},
}
</script>
<style lang="scss" scoped>
.event {
height: 100%;
box-sizing: border-box;
display: flex;
padding: 10px;
border-radius: 5px;
.left {
display: flex;
flex-direction: column;
width: 0;
flex-grow: 4;
// border-right: 1px solid #ccc;
.filter-container {
display: flex;
align-items: center;
margin: 5px;
}
.data-table {
flex: 1;
padding: 5px 0px;
}
.pagination-container {
text-align: right;
}
}
}
</style>

View File

@ -2,26 +2,18 @@
<base-model v-if="config.visible" :config="config"> <base-model v-if="config.visible" :config="config">
<template slot="dialog-body"> <template slot="dialog-body">
<el-table :data="curData" border style="width: 100%" size="small"> <el-table :data="curData" border style="width: 100%" size="small">
<el-table-column <el-table-column prop="key" :label="$t('system:loginLog:table:cfgItem')" show-overflow-tooltip />
prop="key" <el-table-column prop="value" :label="$t('system:loginLog:table:cfgVal')" show-overflow-tooltip>
:label="$t('system:loginLog:table:cfgItem')"
show-overflow-tooltip
/>
<el-table-column
prop="value"
:label="$t('system:loginLog:table:cfgVal')"
show-overflow-tooltip
>
<template slot-scope="scope"> <template slot-scope="scope">
<span v-if="scope.row.prop !== 'UserRoleList'">{{ <el-button v-if="scope.row.prop === 'UserAgreementId'" type="text" size="small"
@click.stop="view(scope.row)">{{
$t('dictionary:agreement:button:view')
}}</el-button>
<span v-else-if="scope.row.prop !== 'UserRoleList'">{{
scope.row.value scope.row.value
}}</span> }}</span>
<template v-else> <template v-else>
<div <div v-for="item in scope.row.value" :key="item.UserTypeEnum" style="margin: 0">
v-for="item in scope.row.value"
:key="item.UserTypeEnum"
style="margin: 0"
>
{{ item.UserTypeShortName {{ item.UserTypeShortName
}}{{ $t('system:loginLog:form:symbol') }}{{ $t('system:loginLog:form:symbol')
}}{{ $fd('IsEnable', !item.IsUserRoleDisabled) }} }}{{ $fd('IsEnable', !item.IsUserRoleDisabled) }}
@ -74,7 +66,11 @@ export default {
'PositionName', 'PositionName',
'DepartmentName', 'DepartmentName',
'UserRoleList', 'UserRoleList',
'UserAgreementTypeEnum',
'FileVersion',
'UserAgreementId',
], ],
IsEn_Us: false
} }
}, },
computed: { computed: {
@ -87,6 +83,7 @@ export default {
let obj = JSON.parse(this.JsonObj) let obj = JSON.parse(this.JsonObj)
let curData = [] let curData = []
Object.keys(obj).forEach((key) => { Object.keys(obj).forEach((key) => {
if (key === 'IsEn_Us') this.IsEn_Us = obj[key]
if (this.curKeys.includes(key)) { if (this.curKeys.includes(key)) {
let o = { let o = {
key: this.$t(`system:loginLog:form:${key}`), key: this.$t(`system:loginLog:form:${key}`),
@ -96,12 +93,23 @@ export default {
if (key === 'Status') { if (key === 'Status') {
o.value = this.$fd('IsUserEnable', obj[key]) o.value = this.$fd('IsUserEnable', obj[key])
} }
if (key === 'UserAgreementTypeEnum') {
o.value = this.$fd('UserAgreementType', obj[key])
}
curData.push(o) curData.push(o)
} }
}) })
return curData return curData
}, },
}, },
methods: {
view(row) {
this.$AGR({
Id: row.value,
IsEn_Us: this.IsEn_Us
})
},
}
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -1,7 +1,14 @@
<template> <template>
<div class="trials-navbar" style="position: relative"> <div class="trials-navbar" style="position: relative">
<div class="leftMenu"> <div class="leftMenu">
<img src="@/assets/title-logo.png" alt="" class="title-logo" /> <img v-if="language === 'zh'" src="@/assets/zzlogo2.png" alt="" />
<img
v-else-if="NODE_ENV === 'usa'"
src="@/assets/title-logo.png"
alt=""
class="title-logo"
/>
<img v-else src="@/assets/zzlogo4.png" alt="" />
<span style="white-space: nowrap" v-if="NODE_ENV !== 'usa'"> <span style="white-space: nowrap" v-if="NODE_ENV !== 'usa'">
<!-- 中心影像系统EICS --> <!-- 中心影像系统EICS -->
{{ $t('trials:trials:title:eics') }} {{ $t('trials:trials:title:eics') }}

View File

@ -1,72 +1,33 @@
<!-- eslint-disable --> <!-- eslint-disable -->
<template> <template>
<el-form <el-form ref="trialForm" v-loading="loading" label-width="250px" :rules="trialFormRules"
ref="trialForm" class="demo-ruleForm trial-Form" :model="trialForm" label-position="right" :inline="true">
v-loading="loading"
label-width="250px"
:rules="trialFormRules"
class="demo-ruleForm trial-Form"
:model="trialForm"
label-position="right"
:inline="true"
>
<el-row> <el-row>
<!-- 项目编号 --> <!-- 项目编号 -->
<el-form-item <el-form-item v-if="trialForm.Id !== ''" :label="$t('trials:trials-list:form:trialId')" prop="TrialCode">
v-if="trialForm.Id !== ''" <el-input v-model="trialForm.TrialCode" @keyup.native="trialCodekeyUp" />
:label="$t('trials:trials-list:form:trialId')"
prop="TrialCode"
>
<el-input
v-model="trialForm.TrialCode"
@keyup.native="trialCodekeyUp"
/>
</el-form-item> </el-form-item>
<!-- 项目类型 --> <!-- 项目类型 -->
<el-form-item <el-form-item :label="$t('trials:trials-list:form:trialType')" prop="TrialType">
:label="$t('trials:trials-list:form:trialType')" <el-radio-group v-model="trialForm.TrialType" :disabled="trialForm.Id !== ''">
prop="TrialType" <el-radio v-for="item of $d.TrialType" :disabled="isTestUser && (item.value === 1 || item.value === 2)"
> :key="item.id" :label="item.value">{{ item.label }}</el-radio>
<el-radio-group
v-model="trialForm.TrialType"
:disabled="trialForm.Id !== ''"
>
<el-radio
v-for="item of $d.TrialType"
:disabled="isTestUser && (item.value === 1 || item.value === 2)"
:key="item.id"
:label="item.value"
>{{ item.label }}</el-radio
>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-row> </el-row>
<el-row> <el-row>
<!-- 试验名称 --> <!-- 试验名称 -->
<el-form-item <el-form-item :label="$t('trials:trials-list:form:experimentName')" prop="ExperimentName">
:label="$t('trials:trials-list:form:experimentName')" <el-input v-model="trialForm.ExperimentName" type="textarea" :autosize="{ minRows: 1, maxRows: 4 }" />
prop="ExperimentName"
>
<el-input
v-model="trialForm.ExperimentName"
type="textarea"
:autosize="{ minRows: 1, maxRows: 4 }"
/>
</el-form-item> </el-form-item>
<!-- 研究方案号 --> <!-- 研究方案号 -->
<el-form-item <el-form-item :label="$t('trials:trials-list:form:researchNumber')" prop="ResearchProgramNo">
:label="$t('trials:trials-list:form:researchNumber')"
prop="ResearchProgramNo"
>
<el-input v-model="trialForm.ResearchProgramNo" /> <el-input v-model="trialForm.ResearchProgramNo" />
</el-form-item> </el-form-item>
</el-row> </el-row>
<el-row> <el-row>
<!-- 主研单位 --> <!-- 主研单位 -->
<el-form-item <el-form-item :label="$t('trials:trials-list:form:researchUnit')" prop="MainResearchUnit">
:label="$t('trials:trials-list:form:researchUnit')"
prop="MainResearchUnit"
>
<el-input v-model="trialForm.MainResearchUnit" /> <el-input v-model="trialForm.MainResearchUnit" />
</el-form-item> </el-form-item>
<!-- 负责人PI --> <!-- 负责人PI -->
@ -77,63 +38,28 @@
<el-row> <el-row>
<!-- 申办方 --> <!-- 申办方 -->
<el-form-item :label="$t('trials:trials-list:form:sponsor')"> <el-form-item :label="$t('trials:trials-list:form:sponsor')">
<el-select <el-select v-model="trialForm.SponsorId" filterable allow-create default-first-option clearable
v-model="trialForm.SponsorId" @change="(value) => handleSelectChange(value, 'sponsor')" @visible-change="
filterable
allow-create
default-first-option
@change="(value) => handleSelectChange(value, 'sponsor')"
@visible-change="
(flag) => handleSelectVisibbleChange(flag, 'sponsor') (flag) => handleSelectVisibbleChange(flag, 'sponsor')
" ">
> <el-option v-for="item in sponsorList" :key="item.Id" :label="item.SponsorName" :value="item.Id" />
<el-option
v-for="item in sponsorList"
:key="item.Id"
:label="item.SponsorName"
:value="item.Id"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- CRO --> <!-- CRO -->
<el-form-item :label="$t('trials:trials-list:form:cro')"> <el-form-item :label="$t('trials:trials-list:form:cro')">
<el-select <el-select v-model="trialForm.CROId" filterable allow-create default-first-option clearable
v-model="trialForm.CROId"
filterable
allow-create
default-first-option
@change="(value) => handleSelectChange(value, 'cro')" @change="(value) => handleSelectChange(value, 'cro')"
@visible-change="(flag) => handleSelectVisibbleChange(flag, 'cro')" @visible-change="(flag) => handleSelectVisibbleChange(flag, 'cro')">
> <el-option v-for="item of croList" :key="item.Id" :label="item.CROName" :value="item.Id" />
<el-option
v-for="item of croList"
:key="item.Id"
:label="item.CROName"
:value="item.Id"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-row> </el-row>
<el-row> <el-row>
<!-- DeclarationType --> <!-- DeclarationType -->
<el-form-item <el-form-item :label="$t('trials:trials-list:form:declarationType')" prop="DeclarationTypeEnumList">
:label="$t('trials:trials-list:form:declarationType')" <el-select v-model="trialForm.DeclarationTypeEnumList" size="small" multiple clearable
prop="DeclarationTypeEnumList" @change="handleDeclarationTypeChange" style="width: 100%">
> <el-option v-for="item of $d.DeclarationType" :key="item.value" :value="item.value" :label="item.label" />
<el-select
v-model="trialForm.DeclarationTypeEnumList"
size="small"
multiple
clearable
@change="handleDeclarationTypeChange"
style="width: 100%"
>
<el-option
v-for="item of $d.DeclarationType"
:key="item.value"
:value="item.value"
:label="item.label"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- Phase --> <!-- Phase -->
@ -145,79 +71,41 @@
:label="item.Value" :label="item.Value"
:value="item.Id" :value="item.Id"
/> --> /> -->
<el-option <el-option v-for="item of $d.Trial_Phase" :key="item.id" :label="item.label" :value="item.id" />
v-for="item of $d.Trial_Phase"
:key="item.id"
:label="item.label"
:value="item.id"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-row> </el-row>
<el-row> <el-row>
<!-- 适应症类型 IndicationType --> <!-- 适应症类型 IndicationType -->
<el-form-item <el-form-item :label="$t('trials:trials-list:form:indicationType')" prop="IndicationTypeId">
:label="$t('trials:trials-list:form:indicationType')" <el-select v-model="trialForm.IndicationTypeId" @change="handleIndicationTypeChange">
prop="IndicationTypeId"
>
<el-select
v-model="trialForm.IndicationTypeId"
@change="handleIndicationTypeChange"
>
<!-- <el-option <!-- <el-option
v-for="item of dictionaryList.IndicationType" v-for="item of dictionaryList.IndicationType"
:key="item.Id" :key="item.Id"
:label="item.Value" :label="item.Value"
:value="item.Id" :value="item.Id"
/> --> /> -->
<el-option <el-option v-for="item of $d.IndicationType" :key="item.id" :label="item.label" :value="item.id" />
v-for="item of $d.IndicationType"
:key="item.id"
:label="item.label"
:value="item.id"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- Indication --> <!-- Indication -->
<el-form-item <el-form-item :label="$t('trials:trials-list:form:indication')" prop="IndicationEnum">
:label="$t('trials:trials-list:form:indication')"
prop="IndicationEnum"
>
<!-- <el-input v-model="trialForm.Indication" />--> <!-- <el-input v-model="trialForm.Indication" />-->
<el-select <el-select :disabled="!trialForm.IndicationTypeId" v-if="![37, 38, 39].includes(trialForm.IndicationEnum)"
:disabled="!trialForm.IndicationTypeId" v-model="trialForm.IndicationEnum">
v-if="![37, 38, 39].includes(trialForm.IndicationEnum)" <el-option v-for="item of $d.Indication" v-show="indicationGrouping === item.raw.ChildGroup" :key="item.id"
v-model="trialForm.IndicationEnum" :label="item.label" :value="item.value" />
>
<el-option
v-for="item of $d.Indication"
v-show="indicationGrouping === item.raw.ChildGroup"
:key="item.id"
:label="item.label"
:value="item.value"
/>
</el-select> </el-select>
<el-row v-if="[37, 38, 39].includes(trialForm.IndicationEnum)"> <el-row v-if="[37, 38, 39].includes(trialForm.IndicationEnum)">
<el-col :span="12"> <el-col :span="12">
<el-select <el-select :disabled="!trialForm.IndicationTypeId" v-model="trialForm.IndicationEnum"
:disabled="!trialForm.IndicationTypeId" style="width: 100%; margin-right: 10px">
v-model="trialForm.IndicationEnum" <el-option v-for="item of $d.Indication" v-show="indicationGrouping === item.raw.ChildGroup"
style="width: 100%; margin-right: 10px" :key="item.id" :label="item.label" :value="item.value" />
>
<el-option
v-for="item of $d.Indication"
v-show="indicationGrouping === item.raw.ChildGroup"
:key="item.id"
:label="item.label"
:value="item.value"
/>
</el-select> </el-select>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-input <el-input :disabled="!trialForm.IndicationTypeId" v-model="trialForm.Indication" />
:disabled="!trialForm.IndicationTypeId"
v-model="trialForm.Indication"
/>
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
@ -232,99 +120,54 @@
:label="item.Value" :label="item.Value"
:value="item.Id" :value="item.Id"
/> --> /> -->
<el-option <el-option v-for="item of $d.Modality" :key="item.id" :label="item.label" :value="item.id" />
v-for="item of $d.Modality"
:key="item.id"
:label="item.label"
:value="item.id"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- Sites --> <!-- Sites -->
<el-form-item :label="$t('trials:trials-list:form:siteCount')"> <el-form-item :label="$t('trials:trials-list:form:siteCount')">
<el-input-number <el-input-number v-model="trialForm.PlanSiteCount" controls-position="right" :min="0" />
v-model="trialForm.PlanSiteCount"
controls-position="right"
:min="0"
/>
</el-form-item> </el-form-item>
</el-row> </el-row>
<el-row> <el-row>
<!-- Expected Patients Num --> <!-- Expected Patients Num -->
<el-form-item :label="$t('trials:trials-list:form:patientsNum')"> <el-form-item :label="$t('trials:trials-list:form:patientsNum')">
<el-input-number <el-input-number v-model="trialForm.ExpectedPatients" controls-position="right" :min="0"
v-model="trialForm.ExpectedPatients" @change="handleExpectedPatientsChange" />
controls-position="right"
:min="0"
@change="handleExpectedPatientsChange"
/>
</el-form-item> </el-form-item>
<!-- Timepoints Per Patient --> <!-- Timepoints Per Patient -->
<el-form-item :label="$t('trials:trials-list:form:timePointsPerPatient')"> <el-form-item :label="$t('trials:trials-list:form:timePointsPerPatient')">
<el-input-number <el-input-number v-model="trialForm.TimePointsPerPatient" controls-position="right" :min="0"
v-model="trialForm.TimePointsPerPatient" @change="handleTpPerPatientChange" />
controls-position="right"
:min="0"
@change="handleTpPerPatientChange"
/>
</el-form-item> </el-form-item>
</el-row> </el-row>
<el-row> <el-row>
<!-- Visits --> <!-- Visits -->
<el-form-item :label="$t('trials:trials-list:form:visitCount')"> <el-form-item :label="$t('trials:trials-list:form:visitCount')">
<el-input-number <el-input-number v-model="trialForm.PlanVisitCount" controls-position="right" :min="0" />
v-model="trialForm.PlanVisitCount"
controls-position="right"
:min="0"
/>
</el-form-item> </el-form-item>
</el-row> </el-row>
<el-row> <el-row>
<!-- Expedited --> <!-- Expedited -->
<el-form-item <el-form-item :label="$t('trials:trials-list:form:expedited')" prop="Expedited">
:label="$t('trials:trials-list:form:expedited')"
prop="Expedited"
>
<el-select v-model="trialForm.Expedited"> <el-select v-model="trialForm.Expedited">
<el-option <el-option v-for="item in expeditedOption" :key="item.value" :label="item.label" :value="item.value" />
v-for="item in expeditedOption"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- Turnaround Time --> <!-- Turnaround Time -->
<el-form-item <el-form-item :label="$t('trials:trials-list:form:projectCycle')" prop="ProjectCycle">
:label="$t('trials:trials-list:form:projectCycle')"
prop="ProjectCycle"
>
<el-input v-model="trialForm.ProjectCycle" /> <el-input v-model="trialForm.ProjectCycle" />
</el-form-item> </el-form-item>
</el-row> </el-row>
<el-row> <el-row>
<!-- Total Reviewers --> <!-- Total Reviewers -->
<el-form-item :label="$t('trials:trials-list:form:totalReviewers')"> <el-form-item :label="$t('trials:trials-list:form:totalReviewers')">
<el-input-number <el-input-number v-model="trialForm.TotalReviewers" controls-position="right" :min="0" />
v-model="trialForm.TotalReviewers"
controls-position="right"
:min="0"
/>
</el-form-item> </el-form-item>
<!-- Type of Reviewers --> <!-- Type of Reviewers -->
<el-form-item :label="$t('trials:trials-list:form:typeofReviewers')"> <el-form-item :label="$t('trials:trials-list:form:typeofReviewers')">
<el-select <el-select v-model="trialForm.AttendedReviewerTypeEnumList" size="small" multiple clearable>
v-model="trialForm.AttendedReviewerTypeEnumList" <el-option v-for="item of $d.AttendedReviewerType" :key="item.value" :value="item.value"
size="small" :label="item.label" />
multiple
clearable
>
<el-option
v-for="item of $d.AttendedReviewerType"
:key="item.value"
:value="item.value"
:label="item.label"
/>
</el-select> </el-select>
<!-- <el-row v-if="trialForm.AttendedReviewerTypeEnumList.includes(2)">--> <!-- <el-row v-if="trialForm.AttendedReviewerTypeEnumList.includes(2)">-->
<!-- <el-col :span="12">--> <!-- <el-col :span="12">-->
@ -557,6 +400,7 @@ export default {
}, },
// CRO // CRO
async handleSelectChange(value, key) { async handleSelectChange(value, key) {
if (!value) return false
let arr = key == "sponsor" ? this.sponsorList : this.croList; let arr = key == "sponsor" ? this.sponsorList : this.croList;
let has = arr.some((item) => item.Id === value); let has = arr.some((item) => item.Id === value);
if (!has) { if (!has) {
@ -788,6 +632,7 @@ export default {
.trial-Form .el-textarea { .trial-Form .el-textarea {
width: 340px; width: 340px;
} }
.trial-Form .el-col .el-input { .trial-Form .el-col .el-input {
width: 165px; width: 165px;
margin-right: 10px; margin-right: 10px;

View File

@ -5,135 +5,61 @@
<!-- 账号信息 --> <!-- 账号信息 -->
{{ $t('trials:trials-myinfo:title:accountInfo') }} {{ $t('trials:trials-myinfo:title:accountInfo') }}
</div> </div>
<el-form <el-form label-position="right" label-width="100px" :rules="rule" :model="userForm" ref="userFormRef">
label-position="right"
label-width="100px"
:rules="rule"
:model="userForm"
ref="userFormRef"
>
<!-- 用户名 --> <!-- 用户名 -->
<el-form-item <el-form-item :label="$t('trials:trials-myinfo:form:userName')" style="margin-bottom: 5px">
:label="$t('trials:trials-myinfo:form:userName')"
style="margin-bottom: 5px"
>
<span>{{ user.UserName }}</span> <span>{{ user.UserName }}</span>
</el-form-item> </el-form-item>
<el-form-item label="" style="position: relative" prop="UserName"> <el-form-item label="" style="position: relative" prop="UserName">
<el-input <el-input v-model="userForm.UserName" :placeholder="$t('trials:trials-myinfo:form:userName')" />
v-model="userForm.UserName"
:placeholder="$t('trials:trials-myinfo:form:userName')"
/>
<!-- 修改 --> <!-- 修改 -->
<el-button <el-button :disabled="!userForm.UserName" class="saveBtn" type="primary" size="small" @click="setNewUserName">
:disabled="!userForm.UserName"
class="saveBtn"
type="primary"
size="small"
@click="setNewUserName"
>
{{ $t('trials:trials-myinfo:button:update') }} {{ $t('trials:trials-myinfo:button:update') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
<!-- 电话 --> <!-- 电话 -->
<el-form-item <el-form-item :label="$t('trials:trials-myinfo:form:phone')" style="margin-bottom: 5px" prop="Phone">
:label="$t('trials:trials-myinfo:form:phone')"
style="margin-bottom: 5px"
prop="Phone"
>
<span>{{ user.Phone }}</span> <span>{{ user.Phone }}</span>
</el-form-item> </el-form-item>
<el-form-item label="" style="position: relative" prop="Phone"> <el-form-item label="" style="position: relative" prop="Phone">
<el-input <el-input v-model="userForm.Phone" :placeholder="$t('trials:trials-myinfo:form:phone')" />
v-model="userForm.Phone"
:placeholder="$t('trials:trials-myinfo:form:phone')"
/>
<!-- 修改 --> <!-- 修改 -->
<el-button <el-button :disabled="!userForm.Phone" class="saveBtn" type="primary" size="small" @click="setNewPhone">
:disabled="!userForm.Phone"
class="saveBtn"
type="primary"
size="small"
@click="setNewPhone"
>
{{ $t('trials:trials-myinfo:button:update') }} {{ $t('trials:trials-myinfo:button:update') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
<!-- 邮箱 --> <!-- 邮箱 -->
<el-form-item <el-form-item :label="$t('trials:trials-myinfo:form:email')" style="margin-bottom: 5px" prop="EMail">
:label="$t('trials:trials-myinfo:form:email')"
style="margin-bottom: 5px"
prop="EMail"
>
<span>{{ user.EMail }}</span> <span>{{ user.EMail }}</span>
</el-form-item> </el-form-item>
<el-form-item <el-form-item label="" style="margin-bottom: 10px; position: relative" prop="EMail" v-if="IsCanConnectInternet">
label="" <el-input v-model="userForm.EMail" @input="handleEmailChange"
style="margin-bottom: 10px; position: relative" :placeholder="$t('trials:trials-myinfo:form:email')" />
prop="EMail"
v-if="IsCanConnectInternet"
>
<el-input
v-model="userForm.EMail"
@input="handleEmailChange"
:placeholder="$t('trials:trials-myinfo:form:email')"
/>
<el-button
class="sendCode"
:disabled="sendDisabled"
type="primary"
size="mini"
@click="sendVerificationCode"
>{{ sendTitle }}</el-button
>
</el-form-item> </el-form-item>
<el-form-item <el-form-item label="" style="position: relative" prop="VerificationCode" v-if="IsCanConnectInternet">
label="" <div style="display: flex;justify-content: space-between;width: 100%;">
style="position: relative" <el-input v-model="userForm.VerificationCode" :placeholder="$t('trials:researchForm:form:verifyCode')" />
prop="VerificationCode" <el-button class="codeBtn" :disabled="sendDisabled" size="mini" @click="sendVerificationCode">{{
v-if="IsCanConnectInternet" sendTitle
> }}</el-button>
<el-input </div>
v-model="userForm.VerificationCode"
:placeholder="$t('trials:researchForm:form:verifyCode')"
/>
<!-- 修改 --> <!-- 修改 -->
<el-button <el-button :disabled="!userForm.EMail || !userForm.VerificationCode" class="saveBtn" type="primary"
:disabled="!userForm.EMail || !userForm.VerificationCode" size="small" @click="setNewEmail">
class="saveBtn"
type="primary"
size="small"
@click="setNewEmail"
>
{{ $t('trials:trials-myinfo:button:update') }} {{ $t('trials:trials-myinfo:button:update') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
<el-form-item <el-form-item :label="$t('trials:trials-myinfo:form:toggleRole')" style="position: relative"
:label="$t('trials:trials-myinfo:form:toggleRole')" prop="VerificationCode" v-if="hasRole">
style="position: relative"
prop="VerificationCode"
v-if="hasRole"
>
<el-radio-group v-model="userRoleId" class="roles" v-if="hasRole"> <el-radio-group v-model="userRoleId" class="roles" v-if="hasRole">
<el-radio <el-radio v-for="item in roles" :key="item.Id" :label="item.Id" :disabled="item.IsUserRoleDisabled"
v-for="item in roles" style="margin-bottom: 10px">
:key="item.Id"
:label="item.Id"
:disabled="item.IsUserRoleDisabled"
style="margin-bottom: 10px"
>
{{ item.UserTypeShortName }} {{ item.UserTypeShortName }}
</el-radio> </el-radio>
</el-radio-group> </el-radio-group>
<!-- 修改 --> <!-- 修改 -->
<el-button <el-button :disabled="!userRoleId || saveDisabled" class="saveBtn" :loading="toggleRoleLoading" type="primary"
:disabled="!userRoleId || saveDisabled" size="small" @click="toggleRole">
class="saveBtn"
:loading="toggleRoleLoading"
type="primary"
size="small"
@click="toggleRole"
>
{{ $t('trials:trials-myinfo:button:toggleRole') }} {{ $t('trials:trials-myinfo:button:toggleRole') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
@ -189,11 +115,11 @@ export default {
callback( callback(
lang === 'zh' lang === 'zh'
? new Error( ? new Error(
'1用户名字符长度最小为4个字符最大为16个字符只可使用字母、数字、下划线' '1用户名字符长度最小为4个字符最大为16个字符只可使用字母、数字、下划线'
) )
: new Error( : new Error(
'the username must have:1) At least 4 characters;2) At most 16 characters;3)Only letters, numbers, and underscores are allowed.' 'the username must have:1) At least 4 characters;2) At most 16 characters;3)Only letters, numbers, and underscores are allowed.'
) )
) )
} else { } else {
callback() callback()
@ -345,9 +271,26 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.codeBtn {
color: #409EFF;
border-color: #409EFF;
margin-left: 10px;
}
.codeBtn.is-disabled,
.codeBtn.is-disabled:focus,
.codeBtn.is-disabled:hover {
color: #c0c4cc;
cursor: not-allowed;
background-image: none;
background-color: #fff;
border-color: #ebeef5;
}
.el-radio-group { .el-radio-group {
margin-top: 12px; margin-top: 12px;
} }
.el-radio { .el-radio {
width: 60px; width: 60px;
} }

View File

@ -39,7 +39,22 @@
<el-input v-model="searchData.Name" clearable style="width: 120px" /> <el-input v-model="searchData.Name" clearable style="width: 120px" />
</el-form-item> </el-form-item>
<!-- 签署人 --> <!-- 签署人 -->
<el-form-item :label="$t('trials:signRecords:table:user')" v-if="!isDoc"> <el-form-item :label="$t('trials:signRecords:table:user')" v-if="!isSystem">
<el-select v-model="searchData.UserId" clearable filterable style="width: 140px">
<el-option v-for="item of userOptions" :key="item.UserId" :label="item.RealName" :value="item.UserId">
<span style="float: left">{{ item.RealName || item.FullName }}</span>
<span style="
float: right;
color: #8492a6;
font-size: 13px;
margin-left: 5px;
">
{{ item.UserName }}
</span>
</el-option>
</el-select>
</el-form-item>
<el-form-item :label="$t('trials:signRecords:table:user')" v-else-if="!isDoc">
<el-select v-model="searchData.UserId" clearable filterable style="width: 140px"> <el-select v-model="searchData.UserId" clearable filterable style="width: 140px">
<el-option v-for="item of userOptions" :key="item.ConfirmUserId" :label="item.FullName" <el-option v-for="item of userOptions" :key="item.ConfirmUserId" :label="item.FullName"
:value="item.ConfirmUserId"> :value="item.ConfirmUserId">

View File

@ -0,0 +1,220 @@
<template>
<div class="ImageManual">
<div class="config">
<div style="margin-bottom: 20px;font-weight: bold;">
{{ $t("trials:researchRecord:ImageManual:BasicQuestion") }}
</div>
<el-form size="small" :model="form" style="width:80%">
<el-form-item>
<el-checkbox v-model="form.AverageEngravingCycle">
{{ $t('trials:researchForm:form:engravingCycle') }}
</el-checkbox>
</el-form-item>
<el-form-item>
<el-checkbox v-model="form.IsConfirmImagingTechnologist"
@change="(val) => handleChange(val, 'IsConfirmImagingTechnologist')">
{{ $t('trials:researchForm:form:isQualified') }}
</el-checkbox>
</el-form-item>
<el-form-item>
<el-checkbox v-model="form.EfficacyEvaluatorType">
{{ $t('trials:researchForm:form:staffType') }}
</el-checkbox>
</el-form-item>
<el-form-item>
<el-checkbox v-model="form.IsFollowStudyParameters"
@change="(val) => handleChange(val, 'IsFollowStudyParameters')">
{{ $t('trials:researchForm:form:isFollowStudyParam') }}
</el-checkbox>
</el-form-item>
</el-form>
<div style="margin-bottom: 20px;font-weight: bold;">
{{ $t("trials:researchRecord:ImageManual:TableConfiguration") }}
</div>
<el-form size="small" :model="form" style="width:80%">
<el-form-item :label="$t('trials:researchRecord:ImageManual:Equipment')">
<el-radio-group v-model="form.IsCloseEquipmentSurvey">
<el-radio :label="item.value" v-for="item in $d.YesOrNo" :key="item.id">{{ item.label
}}</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<div style="margin-bottom: 20px;font-weight: bold;">
{{ $t("trials:researchRecord:ImageManual:Precautions") }}
</div>
<el-input type="textarea" :autosize="{ minRows: 4, maxRows: 99 }" placeholder=""
v-model="form.ReplaceContent" @input="handleInput" style="width: 70%;" />
<div style="text-align: right;margin: 20px;">
<el-button type="primary" :loading="loading" size="small" @click="handleSave">
{{ $t('common:button:save') }}
</el-button>
</div>
</div>
<div class="preview">
<researchForm ref="ResearchForm" :trialSiteSurveyId="trialSiteSurveyId" />
</div>
</div>
</template>
<script>
import researchForm from '@/views/research/components/ResearchForm'
import { updateTrialExtralConfig, getTrialExtralConfig, getTrialDocumentList } from "@/api/trials"
export default {
name: "ImageManual",
components: { researchForm },
props: {
trialSiteSurveyId: {
type: String,
default: ''
}
},
data() {
return {
form: {
AverageEngravingCycle: false,
IsConfirmImagingTechnologist: false,
NotConfirmReson: false,
EfficacyEvaluatorType: false,
IsFollowStudyParameters: false,
NotFollowReson: false,
ReplaceContent: '',
ReplaceContentCN: '',
IsOpenLostVistRead: false,
IsSupportQCDownloadImage: false,
IsCloseEquipmentSurvey: true
},
obj: {
AverageEngravingCycle: false,
IsConfirmImagingTechnologist: false,
NotConfirmReson: false,
EfficacyEvaluatorType: false,
IsFollowStudyParameters: false,
NotFollowReson: false,
},
loading: false
}
},
mounted() {
this.getInfo()
},
methods: {
handleChange(val, key) {
if (key === 'IsConfirmImagingTechnologist') this.form.NotConfirmReson = val
if (key === 'IsFollowStudyParameters') this.form.NotFollowReson = val
},
handleInput(val) {
this.form.ReplaceContentCN = val
},
async getInfo() {
try {
let param = {
TrialId: this.$route.query.trialId
}
let res = await getTrialExtralConfig(param)
if (res.IsSuccess) {
Object.keys(this.form).forEach(key => {
this.form[key] = true
if (key === 'ReplaceContent' || key === 'ReplaceContentCN') this.form[key] = ''
})
this.form.IsOpenLostVistRead = res.Result.IsOpenLostVistRead
this.form.IsSupportQCDownloadImage = res.Result.IsSupportQCDownloadImage
this.form.IsCloseEquipmentSurvey = !res.Result.IsCloseEquipmentSurvey
if (Array.isArray(res.Result.NotShowFieldList) && res.Result.NotShowFieldList.length > 0) {
res.Result.NotShowFieldList.forEach(key => {
this.form[key] = false
})
}
if (Array.isArray(res.Result.ModifyFiledList) && res.Result.ModifyFiledList.length > 0) {
this.form.ReplaceContent = res.Result.ModifyFiledList[0].ReplaceContent.split('<p>').join('').split('</p>').filter(item => isNaN(item)).join("\n")
this.form.ReplaceContentCN = res.Result.ModifyFiledList[0].ReplaceContentCN.split('<p>').join('').split('</p>').filter(item => isNaN(item)).join("\n")
} else {
let arr = [this.$t('trials:equiptResearch:form:item1'), this.$t('trials:equiptResearch:form:item2'), this.$t('trials:equiptResearch:form:item3'), this.$t('trials:equiptResearch:form:item4')]
this.form.ReplaceContent = arr.join("\n")
this.form.ReplaceContentCN = arr.join("\n")
}
}
} catch (err) {
console.log(err)
}
},
async getTrialDocumentList() {
try {
let data = {
PageIndex: 1,
PageSize: 20,
TrialId: this.$route.query.trialId,
IsPublish: true,
FileTypeCode: 4,
IsDeleted: false
}
let res = await getTrialDocumentList(data)
if (res.IsSuccess) {
const { CurrentPageData } = res.Result
if (CurrentPageData.length <= 0) this.$message.warning(this.$t("trials:researchRecord:ImageManual:message:noImageManual"))
}
} catch (err) {
console.log(err)
}
},
async handleSave() {
try {
let param = {
TrialId: this.$route.query.trialId
}
let data = {
IsOpenLostVistRead: this.form.IsOpenLostVistRead,
IsSupportQCDownloadImage: this.form.IsSupportQCDownloadImage,
IsCloseEquipmentSurvey: !this.form.IsCloseEquipmentSurvey,
ModifyFiledList: [],
NotShowFieldList: []
}
Object.keys(this.obj).forEach(key => {
if (!this.form[key]) data.NotShowFieldList.push(key)
})
let ReplaceContent = ''
this.form.ReplaceContent.split("\n").forEach(item => {
ReplaceContent += `<p>${item}</p>`
})
let ReplaceContentCN = ''
this.form.ReplaceContentCN.split("\n").forEach(item => {
ReplaceContentCN += `<p>${item}</p>`
})
let obj = {
NeedModifyFiled: 'SiteSurveyNote',
ReplaceContent: ReplaceContent,
ReplaceContentCN: ReplaceContentCN,
}
data.ModifyFiledList.push(obj)
this.loading = true
let res = await updateTrialExtralConfig(param, data)
this.loading = false
if (res.IsSuccess) {
this.$refs.ResearchForm.initPage()
if (!data.NotShowFieldList.includes('IsFollowStudyParameters')) this.getTrialDocumentList()
}
} catch (err) {
this.loading = false
console.log(err)
}
}
}
}
</script>
<style lang="scss" scoped>
.ImageManual {
width: 100%;
height: 100%;
display: flex;
.config,
.preview {
width: 50%;
height: 100%;
overflow-y: auto;
}
.config {
border-right: 1px solid #EBEEF5;
}
}
</style>

View File

@ -5,127 +5,62 @@
<el-form :inline="true"> <el-form :inline="true">
<!-- 中心 --> <!-- 中心 -->
<el-form-item :label="$t('trials:researchRecord:table:siteId')"> <el-form-item :label="$t('trials:researchRecord:table:siteId')">
<el-select <el-select v-model="searchData.TrialSiteId" clearable filterable style="width: 120px">
v-model="searchData.TrialSiteId" <el-option v-for="(item, index) of siteOptions" :key="index" :label="item.TrialSiteCode"
clearable :value="item.TrialSiteId" />
filterable
style="width: 120px"
>
<el-option
v-for="(item, index) of siteOptions"
:key="index"
:label="item.TrialSiteCode"
:value="item.TrialSiteId"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 联系人 --> <!-- 联系人 -->
<el-form-item :label="$t('trials:researchRecord:table:contactor')"> <el-form-item :label="$t('trials:researchRecord:table:contactor')">
<el-input <el-input v-model="searchData.UserKeyInfo" class="mr" clearable :placeholder="`${$t(
v-model="searchData.UserKeyInfo" 'trials:researchRecord:placeholder:contactorInfo'
class="mr" )}`" style="width: 140px" />
clearable
:placeholder="`${$t(
'trials:researchRecord:placeholder:contactorInfo'
)}`"
style="width: 140px"
/>
</el-form-item> </el-form-item>
<!-- 初审人 --> <!-- 初审人 -->
<el-form-item <el-form-item :label="$t('trials:researchRecord:table:preliminaryUser')">
:label="$t('trials:researchRecord:table:preliminaryUser')" <el-input v-model="searchData.PreliminaryUserName" class="mr" clearable style="width: 140px" />
>
<el-input
v-model="searchData.PreliminaryUserName"
class="mr"
clearable
style="width: 140px"
/>
</el-form-item> </el-form-item>
<!-- 审核人 --> <!-- 审核人 -->
<el-form-item :label="$t('trials:researchRecord:table:ReviewerUser')"> <el-form-item :label="$t('trials:researchRecord:table:ReviewerUser')">
<el-input <el-input v-model="searchData.ReviewerUserName" class="mr" clearable style="width: 140px" />
v-model="searchData.ReviewerUserName"
class="mr"
clearable
style="width: 140px"
/>
</el-form-item> </el-form-item>
<!-- 状态 --> <!-- 状态 -->
<el-form-item :label="$t('trials:researchRecord:table:status')"> <el-form-item :label="$t('trials:researchRecord:table:status')">
<el-select <el-select v-model="searchData.State" clearable filterable style="width: 120px">
v-model="searchData.State" <el-option v-for="(item, index) of $d.ResearchRecord" :key="index" :label="item.label"
clearable :value="item.value" />
filterable
style="width: 120px"
>
<el-option
v-for="(item, index) of $d.ResearchRecord"
:key="index"
:label="item.label"
:value="item.value"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 是否废除 --> <!-- 是否废除 -->
<el-form-item :label="$t('trials:researchRecord:table:isDeleted')"> <el-form-item :label="$t('trials:researchRecord:table:isDeleted')">
<el-select <el-select v-model="searchData.IsDeleted" clearable filterable style="width: 120px">
v-model="searchData.IsDeleted" <el-option v-for="item of $d.YesOrNo" v-show="item.raw.ValueCN !== ''" :key="`IsDeleted${item.value}`"
clearable :label="item.label" :value="item.value" />
filterable
style="width: 120px"
>
<el-option
v-for="item of $d.YesOrNo"
v-show="item.raw.ValueCN !== '无'"
:key="`IsDeleted${item.value}`"
:label="item.label"
:value="item.value"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 更新时间 --> <!-- 更新时间 -->
<el-form-item :label="$t('trials:researchRecord:table:updateTime')"> <el-form-item :label="$t('trials:researchRecord:table:updateTime')">
<el-date-picker <el-date-picker v-model="searchData.DateRange" type="daterange" value-format="yyyy-MM-dd" format="yyyy-MM-dd"
v-model="searchData.DateRange" style="width: 250px" />
type="daterange"
value-format="yyyy-MM-dd"
format="yyyy-MM-dd"
style="width: 250px"
/>
</el-form-item> </el-form-item>
<!-- 查询 --> <!-- 查询 -->
<el-button type="primary" icon="el-icon-search" @click="handleSearch"> <el-button type="primary" icon="el-icon-search" @click="handleSearch">
{{ $t('common:button:search') }} {{ $t('common:button:search') }}
</el-button> </el-button>
<!-- 重置 --> <!-- 重置 -->
<el-button <el-button type="primary" icon="el-icon-refresh-left" @click="handleReset">
type="primary"
icon="el-icon-refresh-left"
@click="handleReset"
>
{{ $t('common:button:reset') }} {{ $t('common:button:reset') }}
</el-button> </el-button>
<!-- 中心人员 --> <!-- 中心人员 -->
<el-button <el-button v-hasPermi="[
v-hasPermi="[ 'trials:trials-panel:attachments:site-research:summary-record',
'trials:trials-panel:attachments:site-research:summary-record', ]" type="primary" icon="el-icon-info" @click="showResearchUser">
]"
type="primary"
icon="el-icon-info"
@click="showResearchUser"
>
{{ $t('trials:researchRecord:button:questionStaffs') }} {{ $t('trials:researchRecord:button:questionStaffs') }}
</el-button> </el-button>
<!-- 调查表链接 --> <!-- 调查表链接 -->
<el-button <el-button v-hasPermi="[
v-hasPermi="[ 'trials:trials-panel:attachments:site-research:questionnaire-link',
'trials:trials-panel:attachments:site-research:questionnaire-link', ]" type="primary" icon="el-icon-link" @click="showResearchLink">
]"
type="primary"
icon="el-icon-link"
@click="showResearchLink"
>
{{ $t('trials:researchRecord:button:questionLink') }} {{ $t('trials:researchRecord:button:questionLink') }}
</el-button> </el-button>
</el-form> </el-form>
@ -133,61 +68,27 @@
<template slot="main-container"> <template slot="main-container">
<!-- 系统文件列表 --> <!-- 系统文件列表 -->
<el-table <el-table ref="siteResearchList" v-loading="loading" v-adaptive="{ bottomOffset: 60 }" :data="list" stripe
ref="siteResearchList" height="100" @sort-change="handleSortByColumn">
v-loading="loading"
v-adaptive="{ bottomOffset: 60 }"
:data="list"
stripe
height="100"
@sort-change="handleSortByColumn"
>
<el-table-column type="index" width="50" /> <el-table-column type="index" width="50" />
<!-- 中心编号 --> <!-- 中心编号 -->
<el-table-column <el-table-column prop="TrialSiteCode" :label="$t('trials:researchRecord:table:siteId')" min-width="100"
prop="TrialSiteCode" sortable="custom" show-overflow-tooltip />
:label="$t('trials:researchRecord:table:siteId')"
min-width="100"
sortable="custom"
show-overflow-tooltip
/>
<!-- 中心名称 --> <!-- 中心名称 -->
<el-table-column <el-table-column prop="SiteName" :label="$t('trials:researchRecord:table:siteName')" min-width="100"
prop="SiteName" sortable="custom" show-overflow-tooltip />
:label="$t('trials:researchRecord:table:siteName')"
min-width="100"
sortable="custom"
show-overflow-tooltip
/>
<!-- 联系人 --> <!-- 联系人 -->
<el-table-column <el-table-column prop="UserName" :label="$t('trials:researchRecord:table:contactor')" min-width="100"
prop="UserName" sortable="custom" show-overflow-tooltip />
:label="$t('trials:researchRecord:table:contactor')"
min-width="100"
sortable="custom"
show-overflow-tooltip
/>
<!-- 联系电话 --> <!-- 联系电话 -->
<el-table-column <el-table-column prop="Phone" :label="$t('trials:researchRecord:table:contactorPhone')" min-width="100"
prop="Phone" show-overflow-tooltip />
:label="$t('trials:researchRecord:table:contactorPhone')"
min-width="100"
show-overflow-tooltip
/>
<!-- 联系邮箱 --> <!-- 联系邮箱 -->
<el-table-column <el-table-column prop="Email" :label="$t('trials:researchRecord:table:contactorEmail')" min-width="150"
prop="Email" show-overflow-tooltip />
:label="$t('trials:researchRecord:table:contactorEmail')"
min-width="150"
show-overflow-tooltip
/>
<!-- 初审人 --> <!-- 初审人 -->
<el-table-column <el-table-column prop="preliminaryUser" :label="$t('trials:researchRecord:table:preliminaryUser')"
prop="preliminaryUser" min-width="150" show-overflow-tooltip>
:label="$t('trials:researchRecord:table:preliminaryUser')"
min-width="150"
show-overflow-tooltip
>
<template slot-scope="scope"> <template slot-scope="scope">
{{ {{
scope.row.PreliminaryUser scope.row.PreliminaryUser
@ -197,24 +98,15 @@
</template> </template>
</el-table-column> </el-table-column>
<!-- 审核人 --> <!-- 审核人 -->
<el-table-column <el-table-column prop="ReviewerUser" :label="$t('trials:researchRecord:table:ReviewerUser')" min-width="150"
prop="ReviewerUser" show-overflow-tooltip>
:label="$t('trials:researchRecord:table:ReviewerUser')"
min-width="150"
show-overflow-tooltip
>
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.ReviewerUser ? scope.row.ReviewerUser.RealName : '' }} {{ scope.row.ReviewerUser ? scope.row.ReviewerUser.RealName : '' }}
</template> </template>
</el-table-column> </el-table-column>
<!-- 状态 --> <!-- 状态 -->
<el-table-column <el-table-column prop="State" :label="$t('trials:researchRecord:table:status')" min-width="150"
prop="State" sortable="custom" show-overflow-tooltip>
:label="$t('trials:researchRecord:table:status')"
min-width="150"
sortable="custom"
show-overflow-tooltip
>
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag v-if="scope.row.State === 0" type="primary">{{ <el-tag v-if="scope.row.State === 0" type="primary">{{
$fd('ResearchRecord', scope.row.State) $fd('ResearchRecord', scope.row.State)
@ -231,13 +123,8 @@
</template> </template>
</el-table-column> </el-table-column>
<!-- 是否废除 --> <!-- 是否废除 -->
<el-table-column <el-table-column prop="IsDeleted" :label="$t('trials:researchRecord:table:isDeleted')" min-width="100"
prop="IsDeleted" sortable="custom" show-overflow-tooltip>
:label="$t('trials:researchRecord:table:isDeleted')"
min-width="100"
sortable="custom"
show-overflow-tooltip
>
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag v-if="scope.row.IsDeleted" type="danger">{{ <el-tag v-if="scope.row.IsDeleted" type="danger">{{
$fd('YesOrNo', scope.row.IsDeleted) $fd('YesOrNo', scope.row.IsDeleted)
@ -248,88 +135,59 @@
</template> </template>
</el-table-column> </el-table-column>
<!-- 更新时间 --> <!-- 更新时间 -->
<el-table-column <el-table-column prop="UpdateTime" :label="$t('trials:researchRecord:table:updateTime')" min-width="150"
prop="UpdateTime" show-overflow-tooltip sortable="custom" />
:label="$t('trials:researchRecord:table:updateTime')"
min-width="150"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column width="150"> <el-table-column width="150">
<template slot-scope="scope"> <template slot-scope="scope">
<!-- 查看 --> <!-- 查看 -->
<el-button <el-button :disabled="scope.row.State !== 3" circle :title="$t('common:button:view')" icon="el-icon-view"
:disabled="scope.row.State !== 3" @click="handleViewResearchList(scope.row)" />
circle
:title="$t('common:button:view')"
icon="el-icon-view"
@click="handleViewResearchList(scope.row)"
/>
<!-- 审批 --> <!-- 审批 -->
<el-button <el-button v-hasPermi="[
v-hasPermi="[ 'trials:trials-panel:attachments:site-research:auidt',
'trials:trials-panel:attachments:site-research:auidt', ]" :disabled="scope.row.State === 0 || scope.row.State === 3 || scope.row.IsDeleted" circle
]" :title="$t('trials:researchRecord:action:view')" icon="el-icon-s-check"
:disabled="scope.row.State === 0 || scope.row.State === 3 || scope.row.IsDeleted" @click="handleViewResearchList(scope.row)" />
circle
:title="$t('trials:researchRecord:action:view')"
icon="el-icon-s-check"
@click="handleViewResearchList(scope.row)"
/>
<!-- 废除 --> <!-- 废除 -->
<el-button <el-button v-hasPermi="[
v-hasPermi="[ 'trials:trials-panel:attachments:site-research:abolish',
'trials:trials-panel:attachments:site-research:abolish', ]" :disabled="scope.row.State !== 0 || scope.row.IsDeleted" circle
]" :title="$t('trials:researchRecord:action:abolish')" icon="el-icon-delete"
:disabled="scope.row.State !== 0 || scope.row.IsDeleted" @click="handleRepealResearch(scope.row)" />
circle
:title="$t('trials:researchRecord:action:abolish')"
icon="el-icon-delete"
@click="handleRepealResearch(scope.row)"
/>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!-- 分页组件 --> <!-- 分页组件 -->
<pagination <pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
class="page" @pagination="getList" />
:total="total"
:page.sync="searchData.PageIndex"
:limit.sync="searchData.PageSize"
@pagination="getList"
/>
</template> </template>
<!-- 中心人员 --> <!-- 中心人员 -->
<el-dialog <el-dialog v-if="researchUserVisible" :visible.sync="researchUserVisible"
v-if="researchUserVisible" :title="$t('trials:researchRecord:dialogTitle:questionStaff')" custom-class="base-dialog-wrapper"
:visible.sync="researchUserVisible" :fullscreen="true">
:title="$t('trials:researchRecord:dialogTitle:questionStaff')" <div class="base-modal-body" style="border: 1px solid #ccc; padding: 10px">
custom-class="base-dialog-wrapper"
:fullscreen="true"
>
<div
class="base-modal-body"
style="border: 1px solid #ccc; padding: 10px"
>
<Users v-if="researchUserVisible" /> <Users v-if="researchUserVisible" />
</div> </div>
</el-dialog> </el-dialog>
<!-- 调查表 --> <!-- 调查表 -->
<el-dialog <el-dialog v-if="researchInfoVisible" :visible.sync="researchInfoVisible" :fullscreen="true"
v-if="researchInfoVisible" :close-on-click-modal="false">
:visible.sync="researchInfoVisible"
:fullscreen="true"
:close-on-click-modal="false"
>
<research-form v-if="researchInfoVisible" @refreshPage="getList" /> <research-form v-if="researchInfoVisible" @refreshPage="getList" />
</el-dialog> </el-dialog>
<!-- 调查表编辑 -->
<el-dialog v-if="ImageManualVisible" :visible.sync="ImageManualVisible" :fullscreen="true"
:close-on-click-modal="false" :title="$t('trials:researchRecord:dialogTitle:ImageManualEdit')">
<ImageManual v-if="ImageManualVisible" :trialSiteSurveyId="trialSiteSurveyId" @getList="getList" />
</el-dialog>
<!-- 调查表链接 --> <!-- 调查表链接 -->
<base-model :config="share_model"> <base-model :config="share_model">
<template slot="dialog-body"> <template slot="dialog-body">
<el-button size="small" type="primary" style="margin-bottom: 10px;" @click.stop="openImageManual">{{
$t('trials:researchRecord:label:edit')
}}</el-button>
<div style="width: 100%; display: flex"> <div style="width: 100%; display: flex">
<div class="shareLink"> <div class="shareLink">
<!-- <div> <!-- <div>
@ -341,22 +199,11 @@
<div style="margin: 10px 0"> <div style="margin: 10px 0">
<!-- 链接 --> <!-- 链接 -->
{{ $t('trials:researchRecord:label:link') }} {{ $t('trials:researchRecord:label:link') }}
<el-input <el-input ref="shareLink" v-model="shareLink" readonly type="textarea" autosize />
ref="shareLink"
v-model="shareLink"
readonly
type="textarea"
autosize
/>
</div> </div>
<div> <div>
<!-- 复制链接 --> <!-- 复制链接 -->
<el-button <el-button type="primary" round @click="copyLink" class="shareLinkBtn">
type="primary"
round
@click="copyLink"
class="shareLinkBtn"
>
{{ $t('trials:researchRecord:button:copyLink') }} {{ $t('trials:researchRecord:button:copyLink') }}
</el-button> </el-button>
</div> </div>
@ -391,6 +238,7 @@ import Pagination from '@/components/Pagination'
import Users from './components/users' import Users from './components/users'
import ResearchForm from '@/views/research/form' import ResearchForm from '@/views/research/form'
import BaseModel from '@/components/BaseModel' import BaseModel from '@/components/BaseModel'
import ImageManual from './components/ImageManual'
import QRCode from 'qrcodejs2' import QRCode from 'qrcodejs2'
const searchDataDefault = () => { const searchDataDefault = () => {
@ -410,7 +258,7 @@ const searchDataDefault = () => {
} }
export default { export default {
name: 'SiteResearchList', name: 'SiteResearchList',
components: { BaseContainer, Pagination, Users, ResearchForm, BaseModel }, components: { BaseContainer, Pagination, Users, ResearchForm, BaseModel, ImageManual },
data() { data() {
return { return {
searchData: searchDataDefault(), searchData: searchDataDefault(),
@ -429,6 +277,9 @@ export default {
shareLink: '', shareLink: '',
researchState: this.$d.ResearchRecord, researchState: this.$d.ResearchRecord,
qrcode: null, qrcode: null,
ImageManualVisible: false,
trialSiteSurveyId: null
} }
}, },
mounted() { mounted() {
@ -436,6 +287,10 @@ export default {
this.getSite() this.getSite()
}, },
methods: { methods: {
openImageManual() {
// if (!this.trialSiteSurveyId) return false
this.ImageManualVisible = true
},
// //
getList() { getList() {
this.loading = true this.loading = true
@ -488,8 +343,7 @@ export default {
copyLink() { copyLink() {
// //
this.$copyText( this.$copyText(
`${this.$t('trials:researchRecord:message:researchFormLink')}: ${ `${this.$t('trials:researchRecord:message:researchFormLink')}: ${this.shareLink
this.shareLink
}` }`
) )
.then((res) => { .then((res) => {
@ -564,6 +418,7 @@ export default {
const trialId = this.trialId const trialId = this.trialId
this.shareLink = `${location.protocol}//${location.host}/researchLogin?trialId=${trialId}&lang=${this.$i18n.locale}` this.shareLink = `${location.protocol}//${location.host}/researchLogin?trialId=${trialId}&lang=${this.$i18n.locale}`
this.share_model.visible = true this.share_model.visible = true
// this.trialSiteSurveyId = this.list[0].Id
this.$nextTick(() => { this.$nextTick(() => {
this.creatQrCode() this.creatQrCode()
}) })
@ -611,18 +466,21 @@ export default {
padding-right: 20px; padding-right: 20px;
width: 50%; width: 50%;
position: relative; position: relative;
.shareLinkBtn { .shareLinkBtn {
position: absolute; position: absolute;
bottom: 0px; bottom: 0px;
left: 0px; left: 0px;
} }
} }
.shareCode { .shareCode {
width: 50%; width: 50%;
border-left: 1px solid #eee; border-left: 1px solid #eee;
display: flex; display: flex;
justify-content: center; justify-content: center;
flex-wrap: wrap; flex-wrap: wrap;
.qrCode { .qrCode {
width: 220px; width: 220px;
height: 220px; height: 220px;
@ -633,6 +491,7 @@ export default {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.codeBtnBox { .codeBtnBox {
margin-top: 20px; margin-top: 20px;
width: 100%; width: 100%;

View File

@ -21,7 +21,7 @@
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" @click=" <el-button type="text" @click="
go( go(
`/trialsResume?doctorId=${scope.row.DoctorId}&token=${token}` `/trialsResume?doctorId=${scope.row.DoctorId}&token=${token}&trialId=${$route.query.trialId}`
) )
">{{ scope.row.LastName }} / {{ scope.row.FirstName }}</el-button> ">{{ scope.row.LastName }} / {{ scope.row.FirstName }}</el-button>
</template> </template>

View File

@ -1,10 +1,5 @@
<template> <template>
<el-form <el-form v-if="isRender" ref="assessmentForm" :model="form" size="small">
v-if="isRender"
ref="assessmentForm"
:model="form"
size="small"
>
<div class="base-dialog-body"> <div class="base-dialog-body">
<!-- <div v-for="qs in questions" :key="qs.Id"> <!-- <div v-for="qs in questions" :key="qs.Id">
<h4 v-if="qs.Type === 'group'">{{ qs.GroupName }}</h4> <h4 v-if="qs.Type === 'group'">{{ qs.GroupName }}</h4>
@ -42,14 +37,9 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</div> --> </div> -->
<AssessmentFormItem <AssessmentFormItem v-for="question of questions" :key="question.Id" :question="question" :question-form="form"
v-for="question of questions" :readingTaskState="readingTaskState" @setFormItemData="setFormItemData"
:key="question.Id" @resetFormItemData="resetFormItemData" />
:question="question"
:question-form="form"
@setFormItemData="setFormItemData"
@resetFormItemData="resetFormItemData"
/>
</div> </div>
<div class="base-dialog-footer" style="text-align:right;margin-top:10px;"> <div class="base-dialog-footer" style="text-align:right;margin-top:10px;">
@ -57,11 +47,7 @@
<el-button size="small" @click="handleCancel"> <el-button size="small" @click="handleCancel">
{{ $t('common:button:cancel') }} {{ $t('common:button:cancel') }}
</el-button> </el-button>
<el-button <el-button size="small" type="primary" v-if="readingTaskState < 2" @click="handleSave">
size="small"
type="primary"
@click="handleSave"
>
{{ $t('common:button:save') }} {{ $t('common:button:save') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
@ -85,6 +71,14 @@ export default {
default() { default() {
return [] return []
} }
},
readingTaskState: {
type: Number,
default: 0
},
additionalAssessmentsType: {
type: String,
default: 'edit'
} }
}, },
data() { data() {
@ -126,7 +120,7 @@ export default {
} }
const res = await submitTaskAdditionalQuestion(params) const res = await submitTaskAdditionalQuestion(params)
if (res.IsSuccess) { if (res.IsSuccess) {
this.$emit('sign') this.$emit('sign', this.additionalAssessmentsType)
} }
loading.close() loading.close()
} catch (e) { } catch (e) {

View File

@ -1,67 +1,39 @@
<template> <template>
<div> <div>
<div <div v-if="!!question.GroupName && question.Type === 'group'">
v-if="!!question.GroupName && question.Type==='group'"
>
<h4 style="color: #ddd;padding: 5px 0px;margin: 0;font-size: 15px;"> <h4 style="color: #ddd;padding: 5px 0px;margin: 0;font-size: 15px;">
{{ language==='en'?question.GroupEnName:question.GroupName }} {{ language === 'en' ? question.GroupEnName : question.GroupName }}
</h4> </h4>
</div> </div>
<template v-else> <template v-else>
<el-form-item <el-form-item :label="`${language === 'en' ? question.QuestionEnName : question.QuestionName}`"
:label="`${language==='en'?question.QuestionEnName:question.QuestionName}`" :prop="question.Id" :rules="[
:prop="question.Id" {
:rules="[ required: true,
{ required: true, message: $t('common:ruleMessage:select'), trigger: ['blur', 'change']
message: $t('common:ruleMessage:select'), trigger: ['blur', 'change']}, },
]" ]" :class="[question.Type === 'group' ? 'mb' : '']">
:class="[question.Type==='group'?'mb':'']"
>
<!-- 下拉框 --> <!-- 下拉框 -->
<el-select <el-select v-if="question.Type === 'select'" v-model="questionForm[question.Id]" clearable
v-if="question.Type==='select'" @change="((val) => { formItemChange(val, question) })" :disabled="readingTaskState >= 2">
v-model="questionForm[question.Id]"
clearable
@change="((val)=>{formItemChange(val, question)})"
>
<template v-if="question.DictionaryCode"> <template v-if="question.DictionaryCode">
<el-option <el-option v-for="item of $d[question.DictionaryCode]" :key="item.id" :value="String(item.value)"
v-for="item of $d[question.DictionaryCode]" :label="item.label" />
:key="item.id"
:value="String(item.value)"
:label="item.label"
/>
</template> </template>
<template v-else> <template v-else>
<el-option <el-option v-for="val in question.TypeValue.split('|')" :key="val" :label="val" :value="val" />
v-for="val in question.TypeValue.split('|')"
:key="val"
:label="val"
:value="val"
/>
</template> </template>
</el-select> </el-select>
<!-- 单选 --> <!-- 单选 -->
<el-radio-group <el-radio-group v-if="question.Type === 'radio'" v-model="questionForm[question.Id]"
v-if="question.Type==='radio'" @change="((val) => { formItemChange(val, question) })" :disabled="readingTaskState >= 2">
v-model="questionForm[question.Id]"
@change="((val)=>{formItemChange(val, question)})"
>
<template v-if="question.DictionaryCode"> <template v-if="question.DictionaryCode">
<el-radio <el-radio v-for="item of $d[question.DictionaryCode]" :key="item.id" :label="String(item.value)">
v-for="item of $d[question.DictionaryCode]"
:key="item.id"
:label="String(item.value)"
>
{{ item.label }} {{ item.label }}
</el-radio> </el-radio>
</template> </template>
<template v-else-if="question.TypeValue"> <template v-else-if="question.TypeValue">
<el-radio <el-radio v-for="val in question.TypeValue.split('|')" :key="val" :label="val">
v-for="val in question.TypeValue.split('|')"
:key="val"
:label="val"
>
{{ val }} {{ val }}
</el-radio> </el-radio>
</template> </template>
@ -69,14 +41,9 @@
</el-form-item> </el-form-item>
</template> </template>
<AssessmentFormItem <AssessmentFormItem v-for="(item) in question.Childrens" :key="item.Id" :question="item"
v-for="(item) in question.Childrens" :readingTaskState="readingTaskState" :question-form="questionForm" @setFormItemData="setFormItemData"
:key="item.Id" @resetFormItemData="resetFormItemData" />
:question="item"
:question-form="questionForm"
@setFormItemData="setFormItemData"
@resetFormItemData="resetFormItemData"
/>
</div> </div>
</template> </template>
<script> <script>
@ -95,6 +62,10 @@ export default {
default() { default() {
return [] return []
} }
},
readingTaskState: {
type: Number,
default: 0
} }
}, },
data() { data() {
@ -139,7 +110,7 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.mb{ .mb {
margin-bottom: 0px; margin-bottom: 0px;
} }
</style> </style>

View File

@ -1194,7 +1194,7 @@ export default {
cornerstoneTools.addToolForElement(element, cornerstoneTools.WwwcRegionTool) cornerstoneTools.addToolForElement(element, cornerstoneTools.WwwcRegionTool)
} }
if (!cornerstoneTools.getToolForElement(element, cornerstoneTools.StackScrollMouseWheelTool)) { if (!cornerstoneTools.getToolForElement(element, cornerstoneTools.StackScrollMouseWheelTool)) {
cornerstoneTools.addToolForElement(element, cornerstoneTools.StackScrollMouseWheelTool) cornerstoneTools.addToolForElement(element, cornerstoneTools.StackScrollMouseWheelTool, { configuration: { loop: true, } })
} }
cornerstoneTools.setToolActiveForElement(element, 'StackScrollMouseWheel', {}) cornerstoneTools.setToolActiveForElement(element, 'StackScrollMouseWheel', {})
@ -1307,6 +1307,9 @@ export default {
this.isFirstLoadIns = false this.isFirstLoadIns = false
// this.initWwc() // this.initWwc()
this.imageId = instanceId this.imageId = instanceId
if (this.isInitWwwc) {
this.resetWwwc()
}
} }
this.stack.instanceId = instanceId this.stack.instanceId = instanceId
@ -1326,9 +1329,6 @@ export default {
this.scrollSyncInfo.offset = 0 this.scrollSyncInfo.offset = 0
} }
this.renderMeasuredData(e) this.renderMeasuredData(e)
if (this.isInitWwwc) {
this.resetWwwc()
}
}, },
getOrientationMarker(element) { getOrientationMarker(element) {
const enabledElement = cornerstone.getEnabledElement(element) const enabledElement = cornerstone.getEnabledElement(element)
@ -1708,7 +1708,7 @@ export default {
resetWwwc() { resetWwwc() {
// console.log('resetWwwc') // console.log('resetWwwc')
this.isInitWwwc = true this.isInitWwwc = true
this.toolState.viewportInvert = false // this.toolState.viewportInvert = false
var viewport = cornerstone.getViewport(this.canvas) var viewport = cornerstone.getViewport(this.canvas)
// viewport.invert = false // viewport.invert = false
var image = cornerstone.getImage(this.canvas) var image = cornerstone.getImage(this.canvas)
@ -1839,6 +1839,9 @@ export default {
// console.log(toolName) // console.log(toolName)
// cornerstoneTools.setToolPassiveForElement(this.canvas, toolName) // cornerstoneTools.setToolPassiveForElement(this.canvas, toolName)
// }) // })
if (toolName === 'Wwwc') {
this.isInitWwwc = false
}
this.activeToolName = toolName this.activeToolName = toolName
this.$nextTick(() => { this.$nextTick(() => {
// console.log(cornerstoneTools.isToolActiveForElement(this.canvas, 'Bidirectional')) // console.log(cornerstoneTools.isToolActiveForElement(this.canvas, 'Bidirectional'))

View File

@ -214,56 +214,25 @@
<!-- @dblclick.native="reloadViewport('CT_AXIAL')" --> <!-- @dblclick.native="reloadViewport('CT_AXIAL')" -->
<div ref="dicomContainer" class="dicom-container box box_2_2" style="position: relative;" <div ref="dicomContainer" class="dicom-container box box_2_2" style="position: relative;"
@dblclick="reloadViewport"> @dblclick="reloadViewport">
<Viewport <Viewport ref="CT_AXIAL" :index="1" :active-index="activeIndex"
ref="CT_AXIAL" :is-reading-show-subject-info="isReadingShowSubjectInfo" :series-info="ctSeries"
:index="1" :rendering-engine-id="renderingEngineId" viewport-id="CT_AXIAL" :volume="ctVolume"
:active-index="activeIndex" :measure-datas="measureDatas" :style="1 === activeIndex ? viewportStyle : {}"
:is-reading-show-subject-info="isReadingShowSubjectInfo" @upperRangeChange="upperRangeChange" />
:series-info="ctSeries" <Viewport ref="PT_AXIAL" :index="2" :active-index="activeIndex"
:rendering-engine-id="renderingEngineId" :is-reading-show-subject-info="isReadingShowSubjectInfo" :series-info="petSeries"
viewport-id="CT_AXIAL" :volume="ctVolume" :rendering-engine-id="renderingEngineId" viewport-id="PT_AXIAL" :volume="ptVolume"
:measure-datas="measureDatas" :measure-datas="measureDatas" :style="2 === activeIndex ? viewportStyle : {}"
:style="1 === activeIndex ? viewportStyle : {}" @upperRangeChange="upperRangeChange" />
@upperRangeChange="upperRangeChange" <Viewport ref="FUSION_AXIAL" :index="3" :active-index="activeIndex"
/> :is-reading-show-subject-info="isReadingShowSubjectInfo" :series-info="petSeries"
<Viewport :rendering-engine-id="renderingEngineId" viewport-id="FUSION_AXIAL" :volume="ptVolume"
ref="PT_AXIAL" :measure-datas="measureDatas" :rgb-preset-name="rgbPresetName" :style="3 === activeIndex ? viewportStyle : {}"
:index="2" @upperRangeChange="upperRangeChange" />
:active-index="activeIndex" <Viewport ref="PET_MIP_CORONAL" :index="4" :active-index="activeIndex"
:is-reading-show-subject-info="isReadingShowSubjectInfo" :is-reading-show-subject-info="isReadingShowSubjectInfo" :series-info="petSeries"
:series-info="petSeries" :rendering-engine-id="renderingEngineId" viewport-id="PET_MIP_CORONAL" :measure-datas="measureDatas"
:rendering-engine-id="renderingEngineId" :style="4 === activeIndex ? viewportStyle : {}" @upperRangeChange="upperRangeChange" />
viewport-id="PT_AXIAL"
:volume="ptVolume"
:measure-datas="measureDatas"
:style="2 === activeIndex ? viewportStyle : {}"
@upperRangeChange="upperRangeChange"
/>
<Viewport
ref="FUSION_AXIAL"
:index="3"
:active-index="activeIndex"
:is-reading-show-subject-info="isReadingShowSubjectInfo"
:series-info="petSeries"
:rendering-engine-id="renderingEngineId"
viewport-id="FUSION_AXIAL"
:volume="ptVolume"
:measure-datas="measureDatas"
:rgb-preset-name="rgbPresetName"
:style="3 === activeIndex ? viewportStyle : {}"
@upperRangeChange="upperRangeChange"
/>
<Viewport
ref="PET_MIP_CORONAL"
:index="4"
:active-index="activeIndex"
:is-reading-show-subject-info="isReadingShowSubjectInfo"
:series-info="petSeries"
:rendering-engine-id="renderingEngineId"
viewport-id="PET_MIP_CORONAL" :measure-datas="measureDatas"
:style="4 === activeIndex ? viewportStyle : {}"
@upperRangeChange="upperRangeChange"
/>
</div> </div>
<!-- 表单 --> <!-- 表单 -->
<div class="form-container" style="overflow-y: auto;"> <div class="form-container" style="overflow-y: auto;">
@ -273,19 +242,22 @@
<span style="margin-left:5px;">{{ taskBlindName }}</span> <span style="margin-left:5px;">{{ taskBlindName }}</span>
</h3> </h3>
<TableQuestions ref="tableQuestions" /> <TableQuestions ref="tableQuestions" @handleReadingChart="handleReadingChart" />
<Questions ref="questions" @setNonTargetMeasurementStatus="setNonTargetMeasurementStatus" /> <Questions ref="questions" @setNonTargetMeasurementStatus="setNonTargetMeasurementStatus"
@handleReadingChart="handleReadingChart" />
</div> </div>
</div> </div>
</div> </div>
<el-dialog v-if="customWwc.visible" :visible.sync="customWwc.visible" :close-on-click-modal="false" <el-dialog v-if="customWwc.visible" :visible.sync="customWwc.visible" :close-on-click-modal="false"
:title="customWwc.title" width="400px" custom-class="base-dialog-wrapper"> :title="customWwc.title" width="400px" custom-class="base-dialog-wrapper">
<custom-wwwc-form :ww="activeCanvasWW" :wc="activeCanvasWC" @close="customWwc.visible = false" @setWwwc="setWwwc" /> <custom-wwwc-form :ww="activeCanvasWW" :wc="activeCanvasWC" @close="customWwc.visible = false"
@setWwwc="setWwwc" />
</el-dialog> </el-dialog>
<el-dialog :visible.sync="fusion.visible" :close-on-click-modal="false" :title="$t('trials:lugano:button:record')" <el-dialog :visible.sync="fusion.visible" :close-on-click-modal="false" :title="$t('trials:lugano:button:record')"
width="850px"> width="850px">
<fusion-form @close="fusion.visible = false" /> <fusion-form @close="fusion.visible = false" />
</el-dialog> </el-dialog>
<readingChart ref="readingChart" />
</div> </div>
</template> </template>
<script> <script>
@ -333,6 +305,7 @@ import vtkPiecewiseFunction from '@kitware/vtk.js/Common/DataModel/PiecewiseFunc
// import vtkOrientationMarkerWidget from '@kitware/vtk.js/Interaction/Widgets/OrientationMarkerWidget' // import vtkOrientationMarkerWidget from '@kitware/vtk.js/Interaction/Widgets/OrientationMarkerWidget'
import { mat4, vec3 } from 'gl-matrix' import { mat4, vec3 } from 'gl-matrix'
import html2canvas from 'html2canvas' import html2canvas from 'html2canvas'
import readingChart from '@/components/readingChart'
// import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction' // import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction'
// import vtkMath from '@kitware/vtk.js/Common/Core/Math' // import vtkMath from '@kitware/vtk.js/Common/Core/Math'
// import CircleROITool from './tools/CircleROITool' // import CircleROITool from './tools/CircleROITool'
@ -420,7 +393,8 @@ export default {
Questions, Questions,
TableQuestions, TableQuestions,
CustomWwwcForm, CustomWwwcForm,
FusionForm FusionForm,
readingChart
}, },
data() { data() {
return { return {
@ -582,6 +556,7 @@ export default {
this.screenshotWindow = window.open(routeData.href, '_blank') this.screenshotWindow = window.open(routeData.href, '_blank')
}) })
window.addEventListener('beforeunload', e => { this.beforeUnloadHandler(e) }) window.addEventListener('beforeunload', e => { this.beforeUnloadHandler(e) })
document.addEventListener("click", this.foo);
}, },
beforeDestroy() { beforeDestroy() {
if (this.screenshotWindow) { if (this.screenshotWindow) {
@ -604,7 +579,21 @@ export default {
window.removeEventListener('beforeunload', e => { this.beforeUnloadHandler(e) }) window.removeEventListener('beforeunload', e => { this.beforeUnloadHandler(e) })
}, },
methods: { methods: {
handleReadingChart(row) {
let { e, data } = row
let obj = Object.assign({}, data)
obj.TrialId = this.$route.query.trialId
obj.VisitTaskId = this.$route.query.visitTaskId
let zIndex = 9
if (obj.RowIndex) {
zIndex = 9999
}
this.$refs.readingChart.init(e, obj, zIndex)
},
foo() {
if (!this.$refs.readingChart) return false
this.$refs.readingChart.foo()
},
initPage() { initPage() {
const resizeObserver = new ResizeObserver(() => { const resizeObserver = new ResizeObserver(() => {
if (element_ct.style.width) { if (element_ct.style.width) {
@ -1505,6 +1494,10 @@ export default {
await setVolumesForViewports( await setVolumesForViewports(
renderingEngine, renderingEngine,
[ [
{
volumeId: ptVolumeId,
callback: setPetColorMapTransferFunctionForVolumeActor
},
{ {
volumeId: ctVolumeId, volumeId: ctVolumeId,
callback: setCtTransferFunctionForVolumeActor callback: setCtTransferFunctionForVolumeActor
@ -1715,7 +1708,7 @@ export default {
}, },
voiChange(v) { voiChange(v) {
let viewportIds = ['FUSION_AXIAL', 'PT_AXIAL', 'PET_MIP_CORONAL'] let viewportIds = ['FUSION_AXIAL', 'PT_AXIAL', 'PET_MIP_CORONAL']
viewportIds.map(viewportId=>{ viewportIds.map(viewportId => {
// const volumeId = viewportId === 'viewportId' ? ptVolumeId : ctVolumeId // const volumeId = viewportId === 'viewportId' ? ptVolumeId : ctVolumeId
const volumeId = ptVolumeId const volumeId = ptVolumeId
const voiRange = { lower: 0, upper: v } const voiRange = { lower: 0, upper: v }
@ -1738,14 +1731,14 @@ export default {
// console.log(vp.id) // console.log(vp.id)
// }) // })
}) })
}, },
async setColorMap(rgbPresetName) { async setColorMap(rgbPresetName) {
this.rgbPresetName = rgbPresetName this.rgbPresetName = rgbPresetName
let viewports = ['FUSION_AXIAL', 'PT_AXIAL', 'PET_MIP_CORONAL'] let viewports = ['FUSION_AXIAL', 'PT_AXIAL', 'PET_MIP_CORONAL']
viewports.map(v=>{ viewports.map(v => {
this.$refs[v].setPreset(this.rgbPresetName) this.$refs[v].setPreset(this.rgbPresetName)
this.$refs[v].renderColorBar(this.rgbPresetName) this.$refs[v].renderColorBar(this.rgbPresetName)
this.createColorBar(this.rgbPresetName, 'colorBarCanvas', 256, 15) this.createColorBar(this.rgbPresetName, 'colorBarCanvas', 256, 15)
const renderingEngine = getRenderingEngine(renderingEngineId) const renderingEngine = getRenderingEngine(renderingEngineId)
@ -1862,8 +1855,8 @@ export default {
const renderingEngine = getRenderingEngine(renderingEngineId) const renderingEngine = getRenderingEngine(renderingEngineId)
const viewport = renderingEngine.getViewport(viewporId) const viewport = renderingEngine.getViewport(viewporId)
const { invert } = viewport.getProperties() const { invert } = viewport.getProperties()
if ( this.isFusion ) { if (this.isFusion) {
viewport.setProperties({ invert: !invert }, volumeId ) viewport.setProperties({ invert: !invert }, volumeId)
} }
viewport.setProperties({ invert: !invert }) viewport.setProperties({ invert: !invert })
viewport.render() viewport.render()
@ -1987,7 +1980,7 @@ export default {
const viewport = renderingEngine.getViewport(viewportId) const viewport = renderingEngine.getViewport(viewportId)
const lower = v.wc - v.ww / 2 const lower = v.wc - v.ww / 2
const upper = v.wc + v.ww / 2 - 1 const upper = v.wc + v.ww / 2 - 1
viewport.setProperties({ voiRange: { upper: upper, lower: lower }}) viewport.setProperties({ voiRange: { upper: upper, lower: lower } })
viewport.render() viewport.render()
this.customWwc.visible = false this.customWwc.visible = false
}, },

View File

@ -1,305 +1,219 @@
<template> <template>
<div> <div>
<div <div v-if="!!question.GroupName && question.Type === 'group'">
v-if="!!question.GroupName && question.Type==='group'"
>
<h4 style="color: #ddd;padding: 5px 0px;margin: 0;"> <h4 style="color: #ddd;padding: 5px 0px;margin: 0;">
{{ language==='en'?question.GroupEnName:question.GroupName }} {{ language === 'en' ? question.GroupEnName : question.GroupName }}
</h4> </h4>
</div> </div>
<template v-else-if="((question.QuestionType === 56) && question.IsBaseLineTask)" /> <template v-else-if="((question.QuestionType === 56) && question.IsBaseLineTask)" />
<template v-else> <template v-else>
<el-form-item <el-form-item
v-if="(question.ShowQuestion===1 && question.ParentTriggerValueList.includes(String(questionForm[question.ParentId]))) || question.ShowQuestion===0" v-if="(question.ShowQuestion === 1 && question.ParentTriggerValueList.includes(String(questionForm[question.ParentId]))) || question.ShowQuestion === 0"
:label="`${question.QuestionName}`" :label="`${question.QuestionName}`" :prop="question.Id" :rules="[
:prop="question.Id" {
:rules="[ required: (question.IsRequired === 0 || (question.IsRequired === 1 && question.RelevanceId && (questionForm[question.RelevanceId] === question.RelevanceValue))) && question.Type !== 'group' && question.Type !== 'summary',
{ required: (question.IsRequired === 0 || (question.IsRequired ===1 && question.RelevanceId && (questionForm[question.RelevanceId] === question.RelevanceValue))) && question.Type!=='group' && question.Type!=='summary', message: ['radio', 'select', 'checkbox'].includes(question.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']
message: ['radio', 'select', 'checkbox'].includes(question.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']}, },
]" ]" :class="[question.Type === 'group' ? 'mb' : question.Type === 'upload' ? 'uploadWrapper' : '']">
:class="[question.Type==='group'?'mb':question.Type==='upload'?'uploadWrapper':'']"
>
<template v-if="question.QuestionType === 51 || question.QuestionType === 52"> <template v-if="question.QuestionType === 51 || question.QuestionType === 52">
<!-- question.QuestionType === 51 || question.QuestionType === 52 --> <!-- question.QuestionType === 51 || question.QuestionType === 52 -->
<div style="display: flex;flex-direction: row;justify-content: flex-start;"> <div style="display: flex;flex-direction: row;justify-content: flex-start;">
<el-input <div style="display: flex;justify-content: space-between;" v-if="question.Type === 'calculation'">
v-if="question.Type==='calculation'" <el-input v-model="questionForm[question.Id]" disabled style="width: 120px;">
v-model="questionForm[question.Id]" <template v-if="question.Unit" slot="append">
disabled {{ $fd('ValueUnit', parseInt(question.Unit)) }}
style="width: 120px;" </template>
> <svg-icon v-if="question.ShowChartTypeEnum > 0" icon-class="readingChart"
<template v-if="question.Unit" slot="append"> class="svg-icon svg-readingChart" @click.stop="(e) => handleReadingChart({
{{ $fd('ValueUnit', parseInt(question.Unit)) }} e,
</template> data: {
</el-input> QuestionId: question.Id,
RowIndex: questionForm.RowIndex,
QuestionName: question.QuestionName
}
})" />
</el-input>
</div>
<!-- 测量 --> <!-- 测量 -->
<el-button v-if="(!questionForm[question.Id] && ((question.QuestionType === 51 && liverIsInsideVolume) || (question.QuestionType === 52 && lungIsInsideVolume)) && readingTaskState!== 2)" size="mini" type="text" @click="addAnnotation(question)">{{ $t('trials:lugano:button:addAnnotation') }}</el-button> <el-button
v-if="(!questionForm[question.Id] && ((question.QuestionType === 51 && liverIsInsideVolume) || (question.QuestionType === 52 && lungIsInsideVolume)) && readingTaskState !== 2)"
size="mini" type="text" @click="addAnnotation(question)">{{ $t('trials:lugano:button:addAnnotation')
}}</el-button>
<!-- 清除标记 --> <!-- 清除标记 -->
<el-button v-if="(questionForm[question.Id] || (question.QuestionType === 51 && !liverIsInsideVolume) || (question.QuestionType === 52 && !lungIsInsideVolume)) && readingTaskState!== 2" size="mini" type="text" style="padding: 7px 5px;margin-left:5px;" @click="removeAnnotation(question)">{{ $t('trials:lugano:button:clearAnnotation') }}</el-button> <el-button
v-if="(questionForm[question.Id] || (question.QuestionType === 51 && !liverIsInsideVolume) || (question.QuestionType === 52 && !lungIsInsideVolume)) && readingTaskState !== 2"
size="mini" type="text" style="padding: 7px 5px;margin-left:5px;" @click="removeAnnotation(question)">{{
$t('trials:lugano:button:clearAnnotation') }}</el-button>
<!-- 定位 --> <!-- 定位 -->
<el-button <el-button
v-if="(questionForm[question.Id] || (question.QuestionType === 51 && !liverIsInsideVolume) || (question.QuestionType === 52 && !lungIsInsideVolume))" v-if="(questionForm[question.Id] || (question.QuestionType === 51 && !liverIsInsideVolume) || (question.QuestionType === 52 && !lungIsInsideVolume))"
size="mini" size="mini" type="text" style="padding: '7px 5px';margin-left:-5px;"
type="text" @click="locateAnnotation(question)">{{
style="padding: '7px 5px';margin-left:-5px;" $t('trials:lugano:button:locateAnnotation') }}</el-button>
@click="locateAnnotation(question)"
>{{ $t('trials:lugano:button:locateAnnotation') }}</el-button>
<!-- 保存 --> <!-- 保存 -->
<el-button v-if="readingTaskState!== 2 && question.SaveEnum === 1" size="mini" type="text" style="padding: '7px 5px';margin-left:-5px;" @click="saveAnnotation(question)"> <el-button v-if="readingTaskState !== 2 && question.SaveEnum === 1" size="mini" type="text"
style="padding: '7px 5px';margin-left:-5px;" @click="saveAnnotation(question)">
<!-- 未保存 --> <!-- 未保存 -->
<el-tooltip class="item" effect="dark" :content="$t('trials:reading:button:unsaved')" placement="bottom"> <el-tooltip class="item" effect="dark" :content="$t('trials:reading:button:unsaved')" placement="bottom">
<i class="el-icon-warning" style="color:red" /> <i class="el-icon-warning" style="color:red" />
</el-tooltip> </el-tooltip>
{{ $t('common:button:save') }} {{ $t('common:button:save') }}
</el-button> </el-button>
<el-button v-if="!question.IsBaseLineTask" size="mini" type="text" style="padding: '7px 5px';margin-left:-5px;" @click="viewAnnotations(question)">{{ $t('trials:lugano:button:suvscreenshot') }}</el-button> <el-button v-if="!question.IsBaseLineTask" size="mini" type="text"
style="padding: '7px 5px';margin-left:-5px;" @click="viewAnnotations(question)">{{
$t('trials:lugano:button:suvscreenshot') }}</el-button>
</div> </div>
</template> </template>
<template v-else-if="question.QuestionType === 53"> <template v-else-if="question.QuestionType === 53">
<el-input <div style="display: flex;justify-content: space-between;" v-if="question.Type === 'calculation'">
v-if="question.Type==='calculation'" <el-input v-model="questionForm[question.Id]" disabled>
v-model="questionForm[question.Id]" <template v-if="question.Unit" slot="append">
disabled {{ $fd('ValueUnit', parseInt(question.Unit)) }}
> </template>
<template v-if="question.Unit" slot="append"> </el-input>
{{ $fd('ValueUnit', parseInt(question.Unit)) }} <svg-icon v-if="question.ShowChartTypeEnum > 0" icon-class="readingChart" class="svg-icon svg-readingChart"
</template> @click.stop="(e) => handleReadingChart({
</el-input> e,
data: {
QuestionId: question.Id,
RowIndex: questionForm.RowIndex,
QuestionName: question.QuestionName
}
})" />
</div>
</template> </template>
<template v-else-if="question.QuestionType === 55"> <template v-else-if="question.QuestionType === 55">
<el-select <el-select v-model="questionForm[question.Id]" :disabled="readingTaskState >= 2" clearable
v-model="questionForm[question.Id]" @change="((val) => { formItemChange(val, question) })">
:disabled="readingTaskState >= 2 "
clearable
@change="((val)=>{formItemChange(val, question)})"
>
<el-option-group <el-option-group
:label="!isNaN(parseFloat(question.LastTaskAnswer)) ? `${$t('trials:dicomReading:tip:lastVisitStatus')} ${$fd(question.DictionaryCode,parseFloat(question.LastTaskAnswer))}` : ''" :label="!isNaN(parseFloat(question.LastTaskAnswer)) ? `${$t('trials:dicomReading:tip:lastVisitStatus')} ${$fd(question.DictionaryCode, parseFloat(question.LastTaskAnswer))}` : ''">
>
<template> <template>
<el-option <el-option v-for="item of $d[question.DictionaryCode]" :key="item.id" :value="String(item.value)"
v-for="item of $d[question.DictionaryCode]" :label="item.label" />
:key="item.id"
:value="String(item.value)"
:label="item.label"
/>
</template> </template>
</el-option-group> </el-option-group>
</el-select> </el-select>
</template> </template>
<template v-else-if="question.QuestionType === 56"> <template v-else-if="question.QuestionType === 56">
<el-select <el-select v-model="questionForm[question.Id]" :disabled="readingTaskState >= 2" clearable
v-model="questionForm[question.Id]" @change="((val) => { formItemChange(val, question) })">
:disabled="readingTaskState >= 2 "
clearable
@change="((val)=>{formItemChange(val, question)})"
>
<el-option-group <el-option-group
:label="!isNaN(parseFloat(question.LastTaskAnswer)) ? `${$t('trials:dicomReading:tip:lastVisitStatus')} ${parseFloat(question.LastTaskAnswer) === 5 ? 'NA' : $fd(question.DictionaryCode,parseFloat(question.LastTaskAnswer))}` : ''" :label="!isNaN(parseFloat(question.LastTaskAnswer)) ? `${$t('trials:dicomReading:tip:lastVisitStatus')} ${parseFloat(question.LastTaskAnswer) === 5 ? 'NA' : $fd(question.DictionaryCode, parseFloat(question.LastTaskAnswer))}` : ''">
> <template v-if="pet5PS * 1 === -1">
<template v-if="pet5PS*1=== -1"> <el-option v-for="item of $d[question.DictionaryCode]" v-show="item.value !== 4" :key="item.id"
<el-option :value="String(item.value)" :label="item.label" />
v-for="item of $d[question.DictionaryCode]"
v-show="item.value !== 4"
:key="item.id"
:value="String(item.value)"
:label="item.label"
/>
</template> </template>
<template v-else> <template v-else>
<el-option <el-option v-for="item of $d[question.DictionaryCode]" :key="item.id" :value="String(item.value)"
v-for="item of $d[question.DictionaryCode]" :label="item.label" />
:key="item.id"
:value="String(item.value)"
:label="item.label"
/>
</template> </template>
</el-option-group> </el-option-group>
</el-select> </el-select>
</template> </template>
<template v-else-if="question.QuestionType === 57"> <template v-else-if="question.QuestionType === 57">
<el-select <el-select v-model="questionForm[question.Id]" :disabled="readingTaskState >= 2" clearable
v-model="questionForm[question.Id]" @change="((val) => { formItemChange(val, question) })">
:disabled="readingTaskState >= 2 "
clearable
@change="((val)=>{formItemChange(val, question)})"
>
<el-option-group <el-option-group
:label="!isNaN(parseFloat(question.LastTaskAnswer)) ? `${$t('trials:dicomReading:tip:lastVisitStatus')} ${$fd(question.DictionaryCode,parseFloat(question.LastTaskAnswer))}` : ''" :label="!isNaN(parseFloat(question.LastTaskAnswer)) ? `${$t('trials:dicomReading:tip:lastVisitStatus')} ${$fd(question.DictionaryCode, parseFloat(question.LastTaskAnswer))}` : ''">
> <template v-if="pet5PS * 1 === -1">
<template v-if="pet5PS*1=== -1"> <el-option v-for="item of $d[question.DictionaryCode]" v-show="item.value !== 1" :key="item.id"
<el-option :value="String(item.value)" :label="item.label" />
v-for="item of $d[question.DictionaryCode]"
v-show="item.value !== 1"
:key="item.id"
:value="String(item.value)"
:label="item.label"
/>
</template> </template>
<template v-else> <template v-else>
<el-option <el-option v-for="item of $d[question.DictionaryCode]" :key="item.id" :value="String(item.value)"
v-for="item of $d[question.DictionaryCode]" :label="item.label" />
:key="item.id"
:value="String(item.value)"
:label="item.label"
/>
</template> </template>
</el-option-group> </el-option-group>
</el-select> </el-select>
</template> </template>
<!-- 输入框 --> <!-- 输入框 -->
<el-input <el-input v-else-if="question.Type === 'input'" v-model="questionForm[question.Id]"
v-else-if="question.Type==='input'" :disabled="readingTaskState >= 2" />
v-model="questionForm[question.Id]"
:disabled="readingTaskState >= 2"
/>
<!-- 多行文本输入框 --> <!-- 多行文本输入框 -->
<el-input <el-input v-else-if="question.Type === 'textarea'" v-model="questionForm[question.Id]" type="textarea"
v-else-if="question.Type==='textarea'" :autosize="{ minRows: 2, maxRows: 4 }" maxlength="500" :disabled="readingTaskState >= 2" />
v-model="questionForm[question.Id]"
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
maxlength="500"
:disabled="readingTaskState >= 2"
/>
<!-- 下拉框 --> <!-- 下拉框 -->
<el-select <el-select v-else-if="question.Type === 'select'" v-model="questionForm[question.Id]"
v-else-if="question.Type==='select'"
v-model="questionForm[question.Id]"
:disabled="readingTaskState >= 2 || ((question.TableQuestionType === 2 || question.QuestionGenre === 2) && !!question.DictionaryCode) || question.QuestionType === 50" :disabled="readingTaskState >= 2 || ((question.TableQuestionType === 2 || question.QuestionGenre === 2) && !!question.DictionaryCode) || question.QuestionType === 50"
clearable clearable @change="((val) => { formItemChange(val, question) })">
@change="((val)=>{formItemChange(val, question)})"
>
<template v-if="question.TableQuestionType === 1"> <template v-if="question.TableQuestionType === 1">
<el-option <el-option v-for="item in organList" :key="item.Id" :label="item[question.DataTableColumn]"
v-for="item in organList" :value="item[question.DataTableColumn]" />
:key="item.Id"
:label="item[question.DataTableColumn]"
:value="item[question.DataTableColumn]"
/>
</template> </template>
<template v-else-if="question.TableQuestionType === 3 || question.QuestionGenre === 3"> <template v-else-if="question.TableQuestionType === 3 || question.QuestionGenre === 3">
<el-option <el-option v-for="item of $d[question.DictionaryCode]" :key="item.id" :value="String(item.value)"
v-for="item of $d[question.DictionaryCode]" :label="item.label" />
:key="item.id"
:value="String(item.value)"
:label="item.label"
/>
</template> </template>
<template v-else-if="(question.TableQuestionType === 2 || question.QuestionGenre === 2) && question.DictionaryCode"> <template
<el-option v-else-if="(question.TableQuestionType === 2 || question.QuestionGenre === 2) && question.DictionaryCode">
v-for="item of $d[question.DictionaryCode]" <el-option v-for="item of $d[question.DictionaryCode]" :key="item.id" :value="String(item.value)"
:key="item.id" :label="item.label" />
:value="String(item.value)"
:label="item.label"
/>
</template> </template>
<template v-else> <template v-else>
<el-option <el-option v-for="val in question.TypeValue.split('|')" :key="val" :label="val" :value="val" />
v-for="val in question.TypeValue.split('|')"
:key="val"
:label="val"
:value="val"
/>
</template> </template>
</el-select> </el-select>
<!-- 单选 --> <!-- 单选 -->
<el-radio-group <el-radio-group v-else-if="question.Type === 'radio'" v-model="questionForm[question.Id]"
v-else-if="question.Type==='radio'" :disabled="readingTaskState >= 2" @change="((val) => { formItemChange(val, question) })">
v-model="questionForm[question.Id]"
:disabled="readingTaskState >= 2"
@change="((val)=>{formItemChange(val, question)})"
>
<template v-if="question.DictionaryCode"> <template v-if="question.DictionaryCode">
<el-radio <el-radio v-for="item of $d[question.DictionaryCode]" :key="item.id" :label="String(item.value)">
v-for="item of $d[question.DictionaryCode]"
:key="item.id"
:label="String(item.value)"
>
{{ item.label }} {{ item.label }}
</el-radio> </el-radio>
</template> </template>
<template v-else-if="question.TypeValue"> <template v-else-if="question.TypeValue">
<el-radio <el-radio v-for="val in question.TypeValue.split('|')" :key="val" :label="val">
v-for="val in question.TypeValue.split('|')"
:key="val"
:label="val"
>
{{ val }} {{ val }}
</el-radio> </el-radio>
</template> </template>
</el-radio-group> </el-radio-group>
<!-- 复选框 --> <!-- 复选框 -->
<el-checkbox-group <el-checkbox-group v-else-if="question.Type === 'checkbox'" v-model="questionForm[question.Id]"
v-else-if="question.Type==='checkbox'" :disabled="readingTaskState >= 2">
v-model="questionForm[question.Id]" <el-checkbox v-for="val in question.TypeValue.split('|')" :key="val" :label="val">
:disabled="readingTaskState >= 2"
>
<el-checkbox
v-for="val in question.TypeValue.split('|')"
:key="val"
:label="val"
>
{{ val }} {{ val }}
</el-checkbox> </el-checkbox>
</el-checkbox-group> </el-checkbox-group>
<!-- 数值 --> <!-- 数值 -->
<el-input-number
v-else-if="question.Type==='number'" <div style="display: flex;justify-content: space-between;"
v-model="questionForm[question.Id]" v-else-if="question.Type === 'calculation' || question.Type === 'number'">
:disabled="readingTaskState >= 2" <el-input-number v-if="question.Type === 'number'" v-model="questionForm[question.Id]"
/> :disabled="readingTaskState >= 2" />
<el-input <el-input v-model="questionForm[question.Id]" disabled v-else />
v-else-if="question.Type==='calculation'" <svg-icon v-if="question.ShowChartTypeEnum > 0" icon-class="readingChart" class="svg-icon svg-readingChart"
v-model="questionForm[question.Id]" @click.stop="(e) => handleReadingChart({
disabled e,
/> data: {
QuestionId: question.Id,
RowIndex: questionForm.RowIndex,
QuestionName: question.QuestionName
}
})" />
</div>
<!-- 上传图像 --> <!-- 上传图像 -->
<el-upload <el-upload v-if="question.Type === 'upload'" action :accept="accept" :limit="question.ImageCount"
v-if="question.Type==='upload'" :on-preview="handlePictureCardPreview" :before-upload="handleBeforeUpload" :http-request="uploadScreenshot"
action list-type="picture-card" :on-remove="handleRemove" :file-list="fileList"
:accept="accept" :class="{ disabled: fileList.length >= question.ImageCount }" :disabled="readingTaskState >= 2">
:limit="question.ImageCount"
:on-preview="handlePictureCardPreview"
:before-upload="handleBeforeUpload"
:http-request="uploadScreenshot"
list-type="picture-card"
:on-remove="handleRemove"
:file-list="fileList"
:class="{disabled:fileList.length >= question.ImageCount}"
:disabled="readingTaskState >= 2"
>
<i slot="default" class="el-icon-plus" /> <i slot="default" class="el-icon-plus" />
<div slot="file" slot-scope="{file}"> <div slot="file" slot-scope="{file}">
<img <img class="el-upload-list__item-thumbnail" :src="OSSclientConfig.basePath + file.url" alt="">
class="el-upload-list__item-thumbnail"
:src="OSSclientConfig.basePath + file.url"
alt=""
>
<span class="el-upload-list__item-actions"> <span class="el-upload-list__item-actions">
<span <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
class="el-upload-list__item-preview"
@click="handlePictureCardPreview(file)"
>
<i class="el-icon-zoom-in" /> <i class="el-icon-zoom-in" />
</span> </span>
<span <span v-if="readingTaskState < 2" class="el-upload-list__item-delete" @click="handleRemove(file)">
v-if="readingTaskState < 2"
class="el-upload-list__item-delete"
@click="handleRemove(file)"
>
<i class="el-icon-delete" /> <i class="el-icon-delete" />
</span> </span>
</span> </span>
</div> </div>
</el-upload> </el-upload>
<el-dialog <el-dialog v-if="question.Type === 'upload'" append-to-body :visible.sync="imgVisible" width="600px">
v-if="question.Type==='upload'"
append-to-body
:visible.sync="imgVisible"
width="600px"
>
<el-image :src="imageUrl" width="100%"> <el-image :src="imageUrl" width="100%">
<div slot="placeholder" class="image-slot"> <div slot="placeholder" class="image-slot">
加载中<span class="dot">...</span> 加载中<span class="dot">...</span>
@ -309,19 +223,11 @@
</el-form-item> </el-form-item>
</template> </template>
<template v-for="item of question.Childrens"> <template v-for="item of question.Childrens">
<QuestionItem <QuestionItem v-if="item.QuestionClassify === 0" :key="item.Id" :question="item"
v-if="item.QuestionClassify === 0" :reading-task-state="readingTaskState" :question-form="questionForm" :visit-task-id="visitTaskId"
:key="item.Id" :pet5p-s="pet5PS" :lung-is-inside-volume="lungIsInsideVolume" :liver-is-inside-volume="liverIsInsideVolume"
:question="item" @setFormItemData="setFormItemData" @resetFormItemData="resetFormItemData"
:reading-task-state="readingTaskState" @handleReadingChart="handleReadingChart" />
:question-form="questionForm"
:visit-task-id="visitTaskId"
:pet5p-s="pet5PS"
:lung-is-inside-volume="lungIsInsideVolume"
:liver-is-inside-volume="liverIsInsideVolume"
@setFormItemData="setFormItemData"
@resetFormItemData="resetFormItemData"
/>
</template> </template>
</div> </div>
</template> </template>
@ -406,6 +312,9 @@ export default {
} }
}, },
methods: { methods: {
handleReadingChart(e) {
this.$emit('handleReadingChart', e)
},
formItemChange(v, question) { formItemChange(v, question) {
if (question.QuestionType === 55) { if (question.QuestionType === 55) {
this.$emit('setFormItemData', { key: question.Id, val: v }) this.$emit('setFormItemData', { key: question.Id, val: v })
@ -441,7 +350,7 @@ export default {
.then(() => { .then(() => {
FusionEvent.$emit('removeAnnotation', question) FusionEvent.$emit('removeAnnotation', question)
}) })
.catch(() => {}) .catch(() => { })
}, },
locateAnnotation(question) { locateAnnotation(question) {
FusionEvent.$emit('locateAnnotation', question) FusionEvent.$emit('locateAnnotation', question)
@ -503,26 +412,32 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.mb{ .mb {
margin-bottom: 0px; margin-bottom: 0px;
} }
.disabled{
.disabled {
::v-deep .el-upload--picture-card { ::v-deep .el-upload--picture-card {
display: none; display: none;
} }
} }
.uploadWrapper{
.uploadWrapper {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: flex-start; align-items: flex-start;
} }
::v-deep .el-input.is-disabled .el-input__inner{
background-color: #646464a1; ::v-deep .el-input.is-disabled .el-input__inner {
} background-color: #646464a1;
::v-deep .el-input-group__append, .el-input-group__prepend{ }
padding: 0 5px;
} ::v-deep .el-input-group__append,
::v-deep .el-select.is-disabled .el-input__inner{ .el-input-group__prepend {
background-color: #646464a1; padding: 0 5px;
} }
::v-deep .el-select.is-disabled .el-input__inner {
background-color: #646464a1;
}
</style> </style>

View File

@ -1,29 +1,17 @@
<template> <template>
<div v-loading="loading" class="ecrf-wrapper"> <div v-loading="loading" class="ecrf-wrapper">
<el-form <el-form v-if="questions.length > 0" ref="questions" size="small" :model="questionForm">
v-if="questions.length > 0"
ref="questions"
size="small"
:model="questionForm"
>
<template v-for="question of questions"> <template v-for="question of questions">
<QuestionItem <QuestionItem v-if="question.QuestionClassify === 0" :key="question.Id" :question="question"
v-if="question.QuestionClassify === 0" :question-form="questionForm" :reading-task-state="readingTaskState" :visit-task-id="visitTaskId"
:key="question.Id" :pet5p-s="questionForm[pet5PSId]" :lung-is-inside-volume="lungIsInsideVolume"
:question="question" :liver-is-inside-volume="liverIsInsideVolume" @setFormItemData="setFormItemData"
:question-form="questionForm" @resetFormItemData="resetFormItemData" @handleReadingChart="handleReadingChart" />
:reading-task-state="readingTaskState"
:visit-task-id="visitTaskId"
:pet5p-s="questionForm[pet5PSId]"
:lung-is-inside-volume="lungIsInsideVolume"
:liver-is-inside-volume="liverIsInsideVolume"
@setFormItemData="setFormItemData"
@resetFormItemData="resetFormItemData"
/>
</template> </template>
<el-form-item v-if="readingTaskState < 2"> <el-form-item v-if="readingTaskState < 2">
<div style="text-align:right"> <div style="text-align:right">
<el-button :disabled="!questionFormChangeState" :type="questionFormChangeState ? 'primary' : null" size="mini" @click="handleSave">{{ $t('common:button:save') }}</el-button> <el-button :disabled="!questionFormChangeState" :type="questionFormChangeState ? 'primary' : null" size="mini"
@click="handleSave">{{ $t('common:button:save') }}</el-button>
</div> </div>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -132,6 +120,9 @@ export default {
FusionEvent.$off('locateAnnotation') FusionEvent.$off('locateAnnotation')
}, },
methods: { methods: {
handleReadingChart(e) {
this.$emit('handleReadingChart', e)
},
getQuestions1() { getQuestions1() {
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId) var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
@ -139,17 +130,17 @@ export default {
this.readingTaskState = this.visitTaskList[idx].ReadingTaskState this.readingTaskState = this.visitTaskList[idx].ReadingTaskState
var questions = this.visitTaskList[idx].Questions var questions = this.visitTaskList[idx].Questions
this.questions = this.questions =
questions.map((v) => { questions.map((v) => {
if (v.QuestionClassify === 0) { if (v.QuestionClassify === 0) {
if (v.Type === 'group' && v.Childrens.length === 0) return if (v.Type === 'group' && v.Childrens.length === 0) return
if (!v.IsPage && v.Type !== 'group' && v.Type !== 'summary') { if (!v.IsPage && v.Type !== 'group' && v.Type !== 'summary') {
this.$set(this.questionForm, v.Id, v.Answer ? v.Answer : null) this.$set(this.questionForm, v.Id, v.Answer ? v.Answer : null)
}
if (v.Childrens.length > 0) {
this.setChild(v.Childrens)
}
} }
if (v.Childrens.length > 0) { })
this.setChild(v.Childrens)
}
}
})
this.questions = questions this.questions = questions
} }
}, },
@ -185,7 +176,7 @@ export default {
this.setChild(v.Childrens) this.setChild(v.Childrens)
} }
}) })
console.log(this.questionForm,questions) console.log(this.questionForm, questions)
this.questions = questions this.questions = questions
this.setPet5PSCommentDisplay() this.setPet5PSCommentDisplay()
this.measurements = [] this.measurements = []
@ -759,39 +750,43 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.ecrf-wrapper{ .ecrf-wrapper {
::v-deep .el-form-item__label{ ::v-deep .el-form-item__label {
color: #c3c3c3; color: #c3c3c3;
text-align: left; text-align: left;
} }
::v-deep .el-input__inner{
background-color: transparent; ::v-deep .el-input__inner {
color: #ddd; background-color: transparent;
border: 1px solid #5e5e5e; color: #ddd;
} border: 1px solid #5e5e5e;
::v-deep .el-textarea__inner{ }
background-color: transparent;
color: #ddd; ::v-deep .el-textarea__inner {
border: 1px solid #5e5e5e; background-color: transparent;
} color: #ddd;
::v-deep .el-form-item{ border: 1px solid #5e5e5e;
display: flex; }
flex-direction: row;
justify-content: flex-start; ::v-deep .el-form-item {
flex-wrap: wrap; display: flex;
} flex-direction: row;
::v-deep .el-form-item__content{ justify-content: flex-start;
flex: 1; flex-wrap: wrap;
} }
::v-deep .el-button--mini, .el-button--mini.is-round {
::v-deep .el-form-item__content {
flex: 1;
}
::v-deep .el-button--mini,
.el-button--mini.is-round {
padding: 7px 10px; padding: 7px 10px;
} }
.el-form-item__content
.el-select{ .el-form-item__content .el-select {
width: 100%; width: 100%;
}
} }
}
</style> </style>

View File

@ -1,12 +1,6 @@
<template> <template>
<el-form <el-form v-if="isRender" ref="measurementForm" v-loading="loading" :model="questionForm" size="mini"
v-if="isRender" class="measurement-form">
ref="measurementForm"
v-loading="loading"
:model="questionForm"
size="mini"
class="measurement-form"
>
<div class="base-dialog-body"> <div class="base-dialog-body">
<div style="display: flex;justify-content: space-between;"> <div style="display: flex;justify-content: space-between;">
<h3 v-if="lesionName" style="color: #ddd;padding: 5px 0px;margin: 0;"> <h3 v-if="lesionName" style="color: #ddd;padding: 5px 0px;margin: 0;">
@ -19,184 +13,151 @@
</div> </div>
</div> </div>
<el-form-item <el-form-item :label="$t('trials:reading:title:lesionType')" prop="LesionType" :rules="[
:label="$t('trials:reading:title:lesionType')" { required: true, message: $t('common:ruleMessage:select'), trigger: ['blur'] },
prop="LesionType" ]">
:rules="[
{ required:true,message: $t('common:ruleMessage:select'), trigger: ['blur']},
]"
>
<!-- 下拉框 --> <!-- 下拉框 -->
<el-select <el-select v-model="questionForm.LesionType" filterable
v-model="questionForm.LesionType" :disabled="!isCurrentTask || readingTaskState >= 2 || !isBaseLineTask"
filterable @change="((val) => { lesionTypeChange(val) })">
:disabled="!isCurrentTask || readingTaskState>=2 || !isBaseLineTask"
@change="((val)=>{lesionTypeChange(val)})"
>
<el-option <el-option v-for="item of $d.LesionType" v-show="!(isBaseLineTask && item.value === 2)" :key="item.id"
v-for="item of $d.LesionType" :value="item.value" :label="item.label" />
v-show="!(isBaseLineTask && item.value === 2)"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<template v-for="qs in questions"> <template v-for="qs in questions">
<el-form-item <el-form-item v-if="qs.ShowQuestion !== 2 && qs.QuestionClassify === 0" :key="qs.Id"
v-if="qs.ShowQuestion!==2 && qs.QuestionClassify === 0" :label="`${qs.QuestionName}`" :prop="qs.Id" :rules="[
:key="qs.Id" {
:label="`${qs.QuestionName}`" required: (qs.IsRequired === 0 || (qs.IsRequired === 1 && qs.RelevanceId && (questionForm[qs.RelevanceId] === qs.RelevanceValue)) || (qs.QuestionMark === 6 && questionForm.IsCanEditPosition === true) || (questionForm.IsCanEditPosition && qs.QuestionMark === 10)) && qs.Type !== 'group' && qs.Type !== 'summary',
:prop="qs.Id" message: ['radio', 'select', 'checkbox'].includes(qs.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']
:rules="[ },
{ required: (qs.IsRequired === 0 || (qs.IsRequired ===1 && qs.RelevanceId && (questionForm[qs.RelevanceId] === qs.RelevanceValue)) || (qs.QuestionMark === 6 && questionForm.IsCanEditPosition === true) || (questionForm.IsCanEditPosition && qs.QuestionMark === 10)) && qs.Type!=='group' && qs.Type!=='summary', ]">
message:['radio', 'select', 'checkbox'].includes(qs.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur','change']},
]"
>
<!-- {{ isCurrentTaskAdd }} <!-- {{ isCurrentTaskAdd }}
{{ questionForm.IsCanEditPosition }} --> {{ questionForm.IsCanEditPosition }} -->
<!-- 输入框 --> <!-- 输入框 -->
<template v-if="qs.Type==='input' || qs.Type==='number'"> <template v-if="qs.Type === 'input' || qs.Type === 'number'">
<!-- {{ ((qs.QuestionMark === 6 && isCurrentTaskAdd === 'False') || (qs.QuestionMark === 6 && isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition)) }} --> <div style="display: flex;justify-content: space-between;">
<el-input <!-- {{ ((qs.QuestionMark === 6 && isCurrentTaskAdd === 'False') || (qs.QuestionMark === 6 && isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition)) }} -->
v-if="qs.Type==='input' || qs.Type==='number'" <el-input v-if="qs.Type === 'input' || qs.Type === 'number'" v-model="questionForm[qs.Id]"
v-model="questionForm[qs.Id]" :disabled="!isCurrentTask || readingTaskState >= 2 || qs.QuestionMark === 0 || qs.QuestionMark === 1 || qs.QuestionMark === 2 || qs.QuestionMark === 5 || (qs.QuestionMark === 6 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answers.SplitOrMergeLesionName)) || (qs.QuestionMark === 8 && (isCurrentTaskAdd === 'False' || !!answers.SplitOrMergeLesionName) && lesionType !== 2) || (qs.QuestionMark === 10 && (isCurrentTaskAdd === 'False' || !!answers.SplitOrMergeLesionName))"
:disabled="!isCurrentTask || readingTaskState>=2 || qs.QuestionMark === 0 || qs.QuestionMark === 1 || qs.QuestionMark === 2 || qs.QuestionMark === 5 || (qs.QuestionMark === 6 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answers.SplitOrMergeLesionName))|| (qs.QuestionMark === 8 && (isCurrentTaskAdd === 'False' || !!answers.SplitOrMergeLesionName) && lesionType !== 2) || (qs.QuestionMark === 10 && (isCurrentTaskAdd === 'False' || !!answers.SplitOrMergeLesionName))" @change="((val) => { formItemChange(val, qs) })">
@change="((val)=>{formItemChange(val, qs)})" <template v-if="(qs.QuestionMark === 0 || qs.QuestionMark === 1) && qs.Unit" slot="append">
> {{ $fd('ValueUnit', parseInt(qs.Unit)) }}
<template v-if="(qs.QuestionMark===0 || qs.QuestionMark===1) && qs.Unit" slot="append"> </template>
{{ $fd('ValueUnit', parseInt(qs.Unit)) }} <svg-icon v-if="qs.ShowChartTypeEnum > 0" icon-class="readingChart" class="svg-icon svg-readingChart"
</template> @click.stop="(e) => handleReadingChart({
</el-input> e,
data: {
TableQuestionId: qs.Id,
RowIndex: questionForm.RowIndex,
QuestionName: qs.QuestionName
}
})" />
</el-input>
</div>
</template> </template>
<!-- 多行文本输入框 --> <!-- 多行文本输入框 -->
<el-input <el-input v-if="qs.Type === 'textarea'" v-model="questionForm[qs.Id]" type="textarea"
v-if="qs.Type==='textarea'" :autosize="{ minRows: 2, maxRows: 4 }" maxlength="500" :disabled="!isCurrentTask || readingTaskState >= 2"
v-model="questionForm[qs.Id]" @change="((val) => { formItemChange(val, qs) })" />
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
maxlength="500"
:disabled="!isCurrentTask || readingTaskState>=2"
@change="((val)=>{formItemChange(val, qs)})"
/>
<!-- 下拉框 --> <!-- 下拉框 -->
<el-select <el-select v-if="qs.Type === 'select'" v-model="questionForm[qs.Id]" filterable
v-if="qs.Type==='select'"
v-model="questionForm[qs.Id]"
filterable
:placeholder="qs.QuestionMark === 8 ? $t('common:placeholder:selectorsearch') : $t('common:placeholder:select')" :placeholder="qs.QuestionMark === 8 ? $t('common:placeholder:selectorsearch') : $t('common:placeholder:select')"
:disabled="!isCurrentTask || readingTaskState>=2 || qs.QuestionMark === 0 || qs.QuestionMark === 1 || qs.QuestionMark === 2 || qs.QuestionMark === 5 || (qs.QuestionMark === 6 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answers.SplitOrMergeLesionName))|| (qs.QuestionMark === 8 && (isCurrentTaskAdd === 'False'|| !!answers.SplitOrMergeLesionName)) || (qs.QuestionMark === 10 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answers.SplitOrMergeLesionName))" :disabled="!isCurrentTask || readingTaskState >= 2 || qs.QuestionMark === 0 || qs.QuestionMark === 1 || qs.QuestionMark === 2 || qs.QuestionMark === 5 || (qs.QuestionMark === 6 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answers.SplitOrMergeLesionName)) || (qs.QuestionMark === 8 && (isCurrentTaskAdd === 'False' || !!answers.SplitOrMergeLesionName)) || (qs.QuestionMark === 10 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answers.SplitOrMergeLesionName))"
@change="((val)=>{formItemChange(val, qs)})" @change="((val) => { formItemChange(val, qs) })">
>
<template v-if="qs.QuestionMark === 8" #prefix> <template v-if="qs.QuestionMark === 8" #prefix>
<span style="padding-left: 5px;"> <span style="padding-left: 5px;">
<i class="el-icon-search" /> <i class="el-icon-search" />
</span> </span>
</template> </template>
<template v-if="qs.TableQuestionType === 1"> <template v-if="qs.TableQuestionType === 1">
<el-option <el-option v-for="item in organList" :key="item.Id" :label="item[qs.DataTableColumn]"
v-for="item in organList" :value="item[qs.DataTableColumn]" />
:key="item.Id"
:label="item[qs.DataTableColumn]"
:value="item[qs.DataTableColumn]"
/>
</template> </template>
<template v-else-if="qs.DictionaryCode && qs.QuestionMark !== 7"> <template v-else-if="qs.DictionaryCode && qs.QuestionMark !== 7">
<el-option <el-option v-for="item of $d[qs.DictionaryCode]" :key="item.id" :value="item.value" :label="item.label" />
v-for="item of $d[qs.DictionaryCode]"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template> </template>
<template v-else> <template v-else>
<el-option <el-option v-for="val in qs.TypeValue.split('|')" :key="val" :label="val" :value="val" />
v-for="val in qs.TypeValue.split('|')"
:key="val"
:label="val"
:value="val"
/>
</template> </template>
</el-select> </el-select>
<!-- 单选 --> <!-- 单选 -->
<el-radio-group <el-radio-group v-if="qs.Type === 'radio'" v-model="questionForm[qs.id]"
v-if="qs.Type==='radio'" :disabled="!isCurrentTask || readingTaskState >= 2">
v-model="questionForm[qs.id]" <el-radio v-for="val in qs.options.split('|')" :key="val" :label="val">
:disabled="!isCurrentTask || readingTaskState>=2"
>
<el-radio
v-for="val in qs.options.split('|')"
:key="val"
:label="val"
>
{{ val }} {{ val }}
</el-radio> </el-radio>
</el-radio-group> </el-radio-group>
<template v-if="qs.QuestionMark === 20 && qs.Type==='calculation'"> <template v-if="qs.QuestionMark === 20 && qs.Type === 'calculation'">
<div style="display: flex;flex-direction: row;justify-content: flex-start;"> <div style="display: flex;flex-direction: row;justify-content: flex-start;">
<el-input <div style="display: flex;justify-content: space-between;">
v-if="qs.Type==='calculation'" <el-input v-if="qs.Type === 'calculation'" v-model="questionForm[qs.Id]" disabled style="width:120px;">
v-model="questionForm[qs.Id]" <template v-if="qs.Unit" slot="append">
disabled {{ $fd('ValueUnit', parseInt(qs.Unit)) }}
style="width:120px;" </template>
> </el-input>
<template v-if="qs.Unit" slot="append"> <svg-icon v-if="qs.ShowChartTypeEnum > 0" icon-class="readingChart" class="svg-icon svg-readingChart"
{{ $fd('ValueUnit', parseInt(qs.Unit)) }} @click.stop="(e) => handleReadingChart({
</template> e,
</el-input> data: {
TableQuestionId: qs.Id,
RowIndex: questionForm.RowIndex,
QuestionName: qs.QuestionName
}
})" />
</div>
<!-- <span style="color:#409eff;cursor: pointer" @click="previewImages(answers.RowId)"> <!-- <span style="color:#409eff;cursor: pointer" @click="previewImages(answers.RowId)">
{{ $t('trials:lugano:button:suvscreenshot') }} {{ $t('trials:lugano:button:suvscreenshot') }}
</span> --> </span> -->
<el-button v-if="!isBaseLineTask" type="text" @click="previewImages(answers.RowId)">{{ $t('trials:lugano:button:suvscreenshot') }}</el-button> <el-button v-if="!isBaseLineTask" type="text" @click="previewImages(answers.RowId)">{{
$t('trials:lugano:button:suvscreenshot') }}</el-button>
</div> </div>
</template> </template>
<el-input <div style="display: flex;justify-content: space-between;"
v-else-if="qs.Type==='calculation' && qs.QuestionMark !== 20" v-else-if="qs.Type === 'calculation' && qs.QuestionMark !== 20">
v-model="questionForm[qs.Id]" <el-input v-model="questionForm[qs.Id]" disabled>
disabled <template v-if="qs.Unit" slot="append">
> {{ $fd('ValueUnit', parseInt(qs.Unit)) }}
<template v-if="qs.Unit" slot="append"> </template>
{{ $fd('ValueUnit', parseInt(qs.Unit)) }} </el-input>
</template> <svg-icon v-if="qs.ShowChartTypeEnum > 0" icon-class="readingChart" class="svg-icon svg-readingChart"
</el-input> @click.stop="(e) => handleReadingChart({
e,
data: {
TableQuestionId: qs.Id,
RowIndex: questionForm.RowIndex,
QuestionName: qs.QuestionName
}
})" />
</div>
</el-form-item> </el-form-item>
</template> </template>
</div> </div>
<div <div v-if="isCurrentTask && readingTaskState < 2" class="base-dialog-footer"
v-if="isCurrentTask && readingTaskState<2" style="text-align:right;margin-top:10px;">
class="base-dialog-footer"
style="text-align:right;margin-top:10px;"
>
<!-- 清除标记 --> <!-- 清除标记 -->
<el-button <el-button v-if="questionForm.OtherMeasureData" size="mini" @click="handleDeleteMeasureData">
v-if="questionForm.OtherMeasureData"
size="mini"
@click="handleDeleteMeasureData"
>
{{ $t('trials:reading:button:removeMark') }} {{ $t('trials:reading:button:removeMark') }}
</el-button> </el-button>
<!-- 删除 --> <!-- 删除 -->
<el-button <el-button v-if="isCurrentTaskAdd !== 'False'" size="mini" @click="handleDelete">
v-if="isCurrentTaskAdd !== 'False'"
size="mini"
@click="handleDelete"
>
{{ $t('common:button:delete') }} {{ $t('common:button:delete') }}
</el-button> </el-button>
<!-- 保存 --> <!-- 保存 -->
<el-button <el-button size="mini" @click="handleSave">
size="mini"
@click="handleSave"
>
{{ $t('common:button:save') }} {{ $t('common:button:save') }}
</el-button> </el-button>
</div> </div>
@ -288,6 +249,9 @@ export default {
}, },
methods: { methods: {
handleReadingChart(e) {
this.$emit('handleReadingChart', e)
},
async initForm(isRerender = false) { async initForm(isRerender = false) {
const loading = this.$loading({ fullscreen: true }) const loading = this.$loading({ fullscreen: true })
this.questions.forEach(item => { this.questions.forEach(item => {
@ -341,7 +305,7 @@ export default {
await this.setMeasureData(this.answers.measureObj, true) await this.setMeasureData(this.answers.measureObj, true)
} else { } else {
if (this.questionForm.MeasureData) { if (this.questionForm.MeasureData) {
// 线 // 线
// if (this.answers.MarkTool === 'Bidirectional') { // if (this.answers.MarkTool === 'Bidirectional') {
// this.organList = [] // this.organList = []
// await this.getOrganInfoList(1) // await this.getOrganInfoList(1)
@ -446,8 +410,8 @@ export default {
type: 'warning', type: 'warning',
distinguishCancelAndClose: true distinguishCancelAndClose: true
}) })
.then(() => {}) .then(() => { })
.catch(() => {}) .catch(() => { })
this.$set(this.questionForm, 'LesionType', this.originalQuestionForm.LesionType) this.$set(this.questionForm, 'LesionType', this.originalQuestionForm.LesionType)
return return
} }
@ -459,7 +423,7 @@ export default {
this.$confirm(msg, { this.$confirm(msg, {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
this.$set(this.questionForm, 'LesionType', this.originalQuestionForm.LesionType) this.$set(this.questionForm, 'LesionType', this.originalQuestionForm.LesionType)
return return
@ -786,7 +750,7 @@ export default {
this.$confirm(this.$t('trials:reading:lugano:warnning:outsideVolume'), { this.$confirm(this.$t('trials:reading:lugano:warnning:outsideVolume'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
return return
@ -800,7 +764,7 @@ export default {
this.$confirm(this.$t('trials:reading:lugano:warnning:cannotMeasuredSUV'), { this.$confirm(this.$t('trials:reading:lugano:warnning:cannotMeasuredSUV'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
return return
} }
@ -813,7 +777,7 @@ export default {
this.$confirm(this.$t('trials:reading:lugano:warnning:suvis0'), { this.$confirm(this.$t('trials:reading:lugano:warnning:suvis0'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
return return
} }
@ -1054,47 +1018,57 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.measurement-form{ .measurement-form {
::v-deep .el-form-item__label{ ::v-deep .el-form-item__label {
color: #c3c3c3; color: #c3c3c3;
// text-align: left; // text-align: left;
} }
::v-deep .el-input .el-input__inner{
::v-deep .el-input .el-input__inner {
background-color: transparent; background-color: transparent;
color: #ddd; color: #ddd;
border: 1px solid #5e5e5e; border: 1px solid #5e5e5e;
} }
::v-deep .el-form-item{
::v-deep .el-form-item {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: flex-start; justify-content: flex-start;
flex-wrap: wrap; flex-wrap: wrap;
} }
::v-deep .el-form-item__content{
::v-deep .el-form-item__content {
flex: 1; flex: 1;
} }
::v-deep .el-input.is-disabled .el-input__inner{
::v-deep .el-input.is-disabled .el-input__inner {
background-color: #646464a1; background-color: #646464a1;
} }
::v-deep .el-input-group__append, .el-input-group__prepend{
::v-deep .el-input-group__append,
.el-input-group__prepend {
padding: 0 10px; padding: 0 10px;
} }
::v-deep .el-select.is-disabled .el-input__inner{
::v-deep .el-select.is-disabled .el-input__inner {
background-color: #646464a1; background-color: #646464a1;
} }
::v-deep .el-button--mini, .el-button--mini.is-round {
::v-deep .el-button--mini,
.el-button--mini.is-round {
padding: 7px 10px; padding: 7px 10px;
} }
.el-form-item__content
.el-select{ .el-form-item__content .el-select {
width: 100%; width: 100%;
} }
.input-width1{
width: calc(100% - 60px)!important; .input-width1 {
width: calc(100% - 60px) !important;
} }
.input-width2{
.input-width2 {
width: 100% !important; width: 100% !important;
} }
} }
</style> </style>

View File

@ -3,75 +3,88 @@
<div class="container"> <div class="container">
<!-- 测量问题 --> <!-- 测量问题 -->
<template v-for="(qs,index) in questions"> <template v-for="(qs, index) in questions">
<div v-if="qs.QuestionClassify === 0" :key="index" v-loading="loading" class="lesions lesions_wrapper"> <div v-if="qs.QuestionClassify === 0" :key="index" v-loading="loading" class="lesions lesions_wrapper">
<h4 v-if="qs.Type === 'group'" style="color: #ddd;padding: 5px 0px;margin: 0;"> <h4 v-if="qs.Type === 'group'" style="color: #ddd;padding: 5px 0px;margin: 0;">
{{ language==='en'?qs.GroupEnName:qs.GroupName }} {{ language === 'en' ? qs.GroupEnName : qs.GroupName }}
</h4> </h4>
<div class="lesion_list"> <div class="lesion_list">
<template v-for="item in qs.Childrens"> <template v-for="item in qs.Childrens">
<div v-if="item.QuestionClassify === 0 && !(isBaseLineTask && item.LesionType === 2)" :key="item.Id"> <div v-if="item.QuestionClassify === 0 && !(isBaseLineTask && item.LesionType === 2)" :key="item.Id">
<div v-if="item.Type === 'table'" class="flex-row" style="margin:3px 0;"> <div v-if="item.Type === 'table'" class="flex-row" style="margin:3px 0;">
<div class="title">{{ item.QuestionName }}</div> <div class="title">{{ item.QuestionName }}
<div v-if="readingTaskState<2 && (isBaseLineTask || item.LesionType === 2)" class="add-icon" @click.prevent="handleAdd(item)"> <svg-icon v-if="item.LesionType === 0" icon-class="readingChart"
class="svg-icon svg-readingChart-mini" @click.stop="(e) => handleReadingChart({
e,
data: {
ReportChartTypeEnum: 0,
QuestionName: item.QuestionName
},
})" />
</div>
<div v-if="readingTaskState < 2 && (isBaseLineTask || item.LesionType === 2)" class="add-icon"
@click.prevent="handleAdd(item)">
<i class="el-icon-plus" /> <i class="el-icon-plus" />
</div> </div>
</div> </div>
<!-- @change="handleCollapseChange(qs.Childrens,item)" --> <!-- @change="handleCollapseChange(qs.Childrens,item)" -->
<el-collapse <el-collapse v-if="item.Type === 'table' && item.TableQuestions" v-model="activeName" accordion
v-if="item.Type === 'table' && item.TableQuestions" @change="handleCollapseChange">
v-model="activeName" <el-collapse-item v-for="(q, i) in item.TableQuestions.Answers" :key="`${item.Id}_${q.RowIndex}`"
accordion
@change="handleCollapseChange"
>
<el-collapse-item
v-for="(q,i) in item.TableQuestions.Answers"
:key="`${item.Id}_${q.RowIndex}`"
:name="`${item.Id}_${q.RowIndex}`" :name="`${item.Id}_${q.RowIndex}`"
@contextmenu.prevent.native="collapseRightClick($event,q,item.Id,q.RowIndex)" @contextmenu.prevent.native="collapseRightClick($event, q, item.Id, q.RowIndex)">
>
<template slot="title"> <template slot="title">
<div style="width:300px;position: relative;" :style="{color:(activeName===item.Id+q.RowIndex?'#ffeb3b':'#fff')}"> <div style="width:300px;position: relative;"
:style="{ color: (activeName === item.Id + q.RowIndex ? '#ffeb3b' : '#fff') }">
{{ getLesionName(item.OrderMark,q.RowIndex) }} {{ getLesionName(item.OrderMark, q.RowIndex) }}
<!-- 未保存 --> <!-- 未保存 -->
<el-tooltip v-if="readingTaskState<2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) === 0" class="item" effect="dark" :content="$t('trials:reading:button:unsaved')" placement="bottom"> <el-tooltip
v-if="readingTaskState < 2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) === 0"
class="item" effect="dark" :content="$t('trials:reading:button:unsaved')" placement="bottom">
<i class="el-icon-warning" style="color:red" /> <i class="el-icon-warning" style="color:red" />
</el-tooltip> </el-tooltip>
<!-- 信息不完整 --> <!-- 信息不完整 -->
<el-tooltip v-if="readingTaskState<2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) ===1" class="item" effect="dark" :content="$t('trials:reading:button:incompleteInfor')" placement="bottom"> <el-tooltip
v-if="readingTaskState < 2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) === 1"
class="item" effect="dark" :content="$t('trials:reading:button:incompleteInfor')"
placement="bottom">
<i class="el-icon-warning" style="color:#ff9800" /> <i class="el-icon-warning" style="color:#ff9800" />
</el-tooltip> </el-tooltip>
<div style="position: absolute;left: 50px;top: 2px;"> <div style="position: absolute;left: 50px;top: 2px;">
<!-- white-space: nowrap;overflow: hidden;text-overflow: ellipsis; --> <!-- white-space: nowrap;overflow: hidden;text-overflow: ellipsis; -->
<div style="font-size: 11px;width:220px;height: 30px;"> <div style="font-size: 11px;width:220px;height: 30px;">
<div <div v-if="item.TableQuestions.Answers[i].lesionPart"
v-if="item.TableQuestions.Answers[i].lesionPart" style="margin-left:10px;display: inline-block; white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width:90px">
style="margin-left:10px;display: inline-block; white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width:90px" <el-tooltip v-if="!!item.TableQuestions.Answers[i].lesionPart" class="item" effect="dark"
> :content="item.TableQuestions.Answers[i].lesionPart" placement="bottom">
<el-tooltip v-if="!!item.TableQuestions.Answers[i].lesionPart" class="item" effect="dark" :content="item.TableQuestions.Answers[i].lesionPart" placement="bottom">
<span>{{ item.TableQuestions.Answers[i].lesionPart }}</span> <span>{{ item.TableQuestions.Answers[i].lesionPart }}</span>
</el-tooltip> </el-tooltip>
</div> </div>
<div style="display: inline-block;margin-left:5px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width:50px"> <div
style="display: inline-block;margin-left:5px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width:50px">
<span v-if="item.LesionType === 0"> <span v-if="item.LesionType === 0">
{{ $fd('TargetState',parseInt(item.TableQuestions.Answers[i].lesionState)) }} {{ $fd('TargetState', parseInt(item.TableQuestions.Answers[i].lesionState)) }}
</span> </span>
<span v-else-if="item.LesionType === 1"> <span v-else-if="item.LesionType === 1">
{{ $fd('NoTargetState',parseInt(item.TableQuestions.Answers[i].lesionState)) }} {{ $fd('NoTargetState', parseInt(item.TableQuestions.Answers[i].lesionState)) }}
</span> </span>
<span v-else> <span v-else>
{{ $fd('NewLesionState',parseInt(item.TableQuestions.Answers[i].lesionState)) }} {{ $fd('NewLesionState', parseInt(item.TableQuestions.Answers[i].lesionState)) }}
</span> </span>
</div> </div>
<div style="display: inline-block;margin-left:5px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width:60px;color:red;"> <div
<template v-if="item.TableQuestions.Answers[i].suvMax && !isNaN(parseFloat(item.TableQuestions.Answers[i].suvMax))"> style="display: inline-block;margin-left:5px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width:60px;color:red;">
<template
v-if="item.TableQuestions.Answers[i].suvMax && !isNaN(parseFloat(item.TableQuestions.Answers[i].suvMax))">
{{ item.TableQuestions.Answers[i].suvMax }} SUV {{ item.TableQuestions.Answers[i].suvMax }} SUV
</template> </template>
</div> </div>
</div> </div>
</div> </div>
<div v-if="((item.LesionType === 0 && parseInt(item.TableQuestions.Answers[i].lesionState) === 0) || (item.LesionType === 1 && [0,1].includes(parseInt(item.TableQuestions.Answers[i].lesionState))) || (item.LesionType === 2 && parseInt(item.TableQuestions.Answers[i].lesionState) === 0)) && item.TableQuestions.Answers[i].IsCurrentTaskAdd === 'False'" style="position: absolute;right: 5px;top: 2px;transform: rotateY(180deg);"> <div
v-if="((item.LesionType === 0 && parseInt(item.TableQuestions.Answers[i].lesionState) === 0) || (item.LesionType === 1 && [0, 1].includes(parseInt(item.TableQuestions.Answers[i].lesionState))) || (item.LesionType === 2 && parseInt(item.TableQuestions.Answers[i].lesionState) === 0)) && item.TableQuestions.Answers[i].IsCurrentTaskAdd === 'False'"
style="position: absolute;right: 5px;top: 2px;transform: rotateY(180deg);">
<!-- 分裂 --> <!-- 分裂 -->
<!-- <el-tooltip v-show="readingTaskState<2 && !!item.TableQuestions.Answers[i].RowId && !isBaseLineTask" class="item" :content="$t('trials:reading:button:split')" placement="left"> <!-- <el-tooltip v-show="readingTaskState<2 && !!item.TableQuestions.Answers[i].RowId && !isBaseLineTask" class="item" :content="$t('trials:reading:button:split')" placement="left">
<i class="iconfont icon-24gl-split" style="color:#fff;font-size: 16px;" @click.stop="handleSplit(item.TableQuestions.Answers[i].RowId,item.Id)" /> <i class="iconfont icon-24gl-split" style="color:#fff;font-size: 16px;" @click.stop="handleSplit(item.TableQuestions.Answers[i].RowId,item.Id)" />
@ -81,25 +94,14 @@
</div> </div>
</template> </template>
<QuestionForm <QuestionForm :ref="`${item.Id}_${q.RowIndex}`" :questions="item.TableQuestions.Questions"
:ref="`${item.Id}_${q.RowIndex}`" :answers="item.TableQuestions.Answers[i]" :lesion-type="item.LesionType"
:questions="item.TableQuestions.Questions" :order-mark="item.OrderMark" :table-questions="tableQuestions" :row-index="String(q.RowIndex)"
:answers="item.TableQuestions.Answers[i]" :question-name="item.QuestionName" :parent-qs-id="item.Id" :visit-task-id="visitTaskId"
:lesion-type="item.LesionType" :is-current-task="isCurrentTask" :reading-task-state="readingTaskState"
:order-mark="item.OrderMark" :is-base-line-task="isBaseLineTask" @changeLesionType="changeLesionType"
:table-questions="tableQuestions" @resetQuestions="resetQuestions" @determineExistsUnsavedLession="determineExistsUnsavedLession"
:row-index="String(q.RowIndex)" @close="close" @handleReadingChart="handleReadingChart" />
:question-name="item.QuestionName"
:parent-qs-id="item.Id"
:visit-task-id="visitTaskId"
:is-current-task="isCurrentTask"
:reading-task-state="readingTaskState"
:is-base-line-task="isBaseLineTask"
@changeLesionType="changeLesionType"
@resetQuestions="resetQuestions"
@determineExistsUnsavedLession="determineExistsUnsavedLession"
@close="close"
/>
</el-collapse-item> </el-collapse-item>
</el-collapse> </el-collapse>
@ -170,6 +172,9 @@ export default {
beforeDestroy() { beforeDestroy() {
}, },
methods: { methods: {
handleReadingChart(e) {
this.$emit('handleReadingChart', e)
},
initList(isRerender = false) { initList(isRerender = false) {
this.loading = true this.loading = true
this.activeName = '' this.activeName = ''
@ -345,7 +350,7 @@ export default {
.then(() => { .then(() => {
this.split(rowId, questionId) this.split(rowId, questionId)
}) })
.catch(() => {}) .catch(() => { })
} else { } else {
// //
this.$confirm(this.$t('trials:reading:warnning:msg4'), { this.$confirm(this.$t('trials:reading:warnning:msg4'), {
@ -355,7 +360,7 @@ export default {
.then(() => { .then(() => {
this.split(rowId, questionId) this.split(rowId, questionId)
}) })
.catch(() => {}) .catch(() => { })
} }
} }
} }
@ -429,7 +434,7 @@ export default {
this.$confirm(msg, { this.$confirm(msg, {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
return return
} }
@ -439,7 +444,7 @@ export default {
this.$confirm(msg, { this.$confirm(msg, {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
} else { } else {
// saveTypeEnum: 0 // saveTypeEnum: 0
@ -582,7 +587,7 @@ export default {
// await store.dispatch('reading/removeReadingQuestionAndAnswer', { lesionType: questionsObj.oldLesionType, rowIndex: questionsObj.rowIndex, visitTaskId: this.visitTaskId }) // await store.dispatch('reading/removeReadingQuestionAndAnswer', { lesionType: questionsObj.oldLesionType, rowIndex: questionsObj.rowIndex, visitTaskId: this.visitTaskId })
this.questions = this.findQuestionAndRemoveLesion(this.questions, { lesionType: questionsObj.oldLesionType, rowIndex: questionsObj.rowIndex }) this.questions = this.findQuestionAndRemoveLesion(this.questions, { lesionType: questionsObj.oldLesionType, rowIndex: questionsObj.rowIndex })
// saveTypeEnum: 0 // saveTypeEnum: 0
var lesionObj = { } var lesionObj = {}
var questionObj = questionsObj.questionForm var questionObj = questionsObj.questionForm
// //
var targetObj = this.tableQuestions.find(item => item.LesionType === questionsObj.newLesionType) var targetObj = this.tableQuestions.find(item => item.LesionType === questionsObj.newLesionType)
@ -817,19 +822,20 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.measurement-wrapper{ .measurement-wrapper {
// .container{ // .container{
// padding: 10px; // padding: 10px;
// } // }
.title{ .title {
padding: 5px; padding: 5px;
font-weight: bold; font-weight: bold;
color: #ddd; color: #ddd;
font-size: 15px; font-size: 15px;
} }
.add-icon{
.add-icon {
padding: 5px; padding: 5px;
font-weight: bold; font-weight: bold;
color: #ddd; color: #ddd;
@ -838,42 +844,49 @@ export default {
margin-bottom: 2px; margin-bottom: 2px;
cursor: pointer; cursor: pointer;
} }
.add-icon:hover{
.add-icon:hover {
background-color: #607d8b; background-color: #607d8b;
} }
.flex-row{ .flex-row {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
background-color: #424242; background-color: #424242;
} }
.lesion_list{
.lesion_list {
position: relative; position: relative;
} }
.el-collapse{
border-bottom:none; .el-collapse {
border-top:none; border-bottom: none;
::v-deep .el-collapse-item{ border-top: none;
background-color: #000!important;
::v-deep .el-collapse-item {
background-color: #000 !important;
color: #ddd; color: #ddd;
} }
::v-deep .el-collapse-item__header{
background-color: #000!important; ::v-deep .el-collapse-item__header {
background-color: #000 !important;
color: #ddd; color: #ddd;
border-bottom-color:#5a5a5a; border-bottom-color: #5a5a5a;
padding-left: 5px; padding-left: 5px;
height: 35px; height: 35px;
line-height: 35px; line-height: 35px;
} }
::v-deep .el-collapse-item__wrap{
background-color: #000!important; ::v-deep .el-collapse-item__wrap {
background-color: #000 !important;
color: #ddd; color: #ddd;
} }
::v-deep .el-collapse-item__content{
width:260px; ::v-deep .el-collapse-item__content {
width: 260px;
position: absolute; position: absolute;
top: 0px; top: 0px;
right: 0px; right: 0px;
@ -882,7 +895,7 @@ export default {
z-index: 1; z-index: 1;
color: #ddd; color: #ddd;
padding: 5px; padding: 5px;
background-color:#1e1e1e; background-color: #1e1e1e;
} }
} }

View File

@ -1,12 +1,6 @@
<template> <template>
<el-form <el-form v-if="isRender" ref="measurementForm" v-loading="loading" :model="questionForm" size="mini"
v-if="isRender" class="measurement-form">
ref="measurementForm"
v-loading="loading"
:model="questionForm"
size="mini"
class="measurement-form"
>
<div class="base-dialog-body"> <div class="base-dialog-body">
<div style="display: flex;justify-content: space-between;"> <div style="display: flex;justify-content: space-between;">
<h3 v-if="questionName" style="color: #ddd;padding: 5px 0px;margin: 0;"> <h3 v-if="questionName" style="color: #ddd;padding: 5px 0px;margin: 0;">
@ -19,179 +13,119 @@
</div> </div>
</div> </div>
<el-form-item <el-form-item :label="$t('trials:reading:title:lesionType')" prop="LesionType" :rules="[
:label="$t('trials:reading:title:lesionType')" { required: true, message: $t('common:ruleMessage:select'), trigger: ['blur'] },
prop="LesionType" ]">
:rules="[
{ required:true,message: $t('common:ruleMessage:select'), trigger: ['blur']},
]"
>
<!-- 下拉框 --> <!-- 下拉框 -->
<el-select <el-select v-model="questionForm.LesionType" filterable
v-model="questionForm.LesionType" :disabled="!isCurrentTask || readingTaskState >= 2 || (!isBaseLineTask && !(isFirstChangeTask && (lesionType === 2 || lesionType === 5 || lesionType === 6)))"
filterable @change="((val) => { lesionTypeChange(val) })">
:disabled="!isCurrentTask || readingTaskState>=2 || (!isBaseLineTask && !(isFirstChangeTask && (lesionType === 2 || lesionType === 5 || lesionType === 6)))"
@change="((val)=>{lesionTypeChange(val)})"
>
<el-option <el-option v-for="item of $d.LesionType"
v-for="item of $d.LesionType"
v-show="(isBaseLineTask && (item.value === 0 || item.value === 1)) || (!isBaseLineTask && ((isFirstChangeTask && (item.value === 5 || item.value === 6)) || !isFirstChangeTask))" v-show="(isBaseLineTask && (item.value === 0 || item.value === 1)) || (!isBaseLineTask && ((isFirstChangeTask && (item.value === 5 || item.value === 6)) || !isFirstChangeTask))"
:key="item.id" :key="item.id" :value="item.value" :label="item.label" />
:value="item.value"
:label="item.label"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item <el-form-item v-for="qs in questions" v-show="qs.ShowQuestion !== 2" :key="qs.Id" :label="`${qs.QuestionName}`"
v-for="qs in questions" :prop="qs.Id" :rules="[
v-show="qs.ShowQuestion!==2" {
:key="qs.Id" required: (qs.IsRequired === 0 || (qs.IsRequired === 1 && qs.RelevanceId && (questionForm[qs.RelevanceId] === qs.RelevanceValue)) || (qs.QuestionMark === 6 && questionForm.IsCanEditPosition === true) || (questionForm.IsCanEditPosition && qs.QuestionMark === 10)) && qs.Type !== 'group' && qs.Type !== 'summary',
:label="`${qs.QuestionName}`" message: ['radio', 'select', 'checkbox'].includes(qs.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']
:prop="qs.Id" },
:rules="[ ]">
{ required: (qs.IsRequired === 0 || (qs.IsRequired ===1 && qs.RelevanceId && (questionForm[qs.RelevanceId] === qs.RelevanceValue)) || (qs.QuestionMark === 6 && questionForm.IsCanEditPosition === true) || (questionForm.IsCanEditPosition && qs.QuestionMark === 10)) && qs.Type!=='group' && qs.Type!=='summary',
message:['radio', 'select', 'checkbox'].includes(qs.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur','change']},
]"
>
<!-- 输入框 --> <!-- 输入框 -->
<template v-if="qs.Type==='input' || qs.Type==='number'"> <template v-if="qs.Type === 'input' || qs.Type === 'number'">
<el-input <div style="display: flex;justify-content: space-between;">
v-if="qs.Type==='input' || qs.Type==='number'" <el-input v-if="qs.Type === 'input' || qs.Type === 'number'" v-model="questionForm[qs.Id]"
v-model="questionForm[qs.Id]" :disabled="!isCurrentTask || readingTaskState >= 2 || qs.QuestionMark === 0 || qs.QuestionMark === 1 || qs.QuestionMark === 2 || qs.QuestionMark === 5 || (qs.QuestionMark === 6 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answers.SplitOrMergeLesionName)) || (qs.QuestionMark === 8 && (isCurrentTaskAdd === 'False' || !!answers.SplitOrMergeLesionName) && lesionType !== 2) || (qs.QuestionMark === 10 && (isCurrentTaskAdd === 'False' || !!answers.SplitOrMergeLesionName)) || (isFirstChangeTask && (lesionType === 5 || lesionType === 6) && (qs.QuestionMark === 8 || qs.QuestionMark === 10))"
:disabled="!isCurrentTask || readingTaskState>=2 || qs.QuestionMark === 0 || qs.QuestionMark === 1 || qs.QuestionMark === 2 || qs.QuestionMark === 5 || (qs.QuestionMark === 6 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answers.SplitOrMergeLesionName))|| (qs.QuestionMark === 8 && (isCurrentTaskAdd === 'False' || !!answers.SplitOrMergeLesionName) && lesionType !== 2 ) || (qs.QuestionMark === 10 && (isCurrentTaskAdd === 'False' || !!answers.SplitOrMergeLesionName)) || (isFirstChangeTask && (lesionType === 5 || lesionType === 6) && (qs.QuestionMark === 8 || qs.QuestionMark === 10 ))" @change="((val) => { formItemChange(val, qs) })">
@change="((val)=>{formItemChange(val, qs)})" <template v-if="(qs.QuestionMark === 0 || qs.QuestionMark === 1) && qs.Unit" slot="append">
> {{ $fd('ValueUnit', parseInt(qs.Unit)) }}
<template v-if="(qs.QuestionMark===0 || qs.QuestionMark===1) && qs.Unit" slot="append"> </template>
{{ $fd('ValueUnit', parseInt(qs.Unit)) }} </el-input>
</template> <svg-icon v-if="qs.ShowChartTypeEnum > 0" icon-class="readingChart" class="svg-icon svg-readingChart"
</el-input> @click.stop="(e) => handleReadingChart({
e,
data: {
TableQuestionId: qs.Id,
RowIndex: questionForm.RowIndex,
QuestionName: qs.QuestionName
}
})" />
</div>
</template> </template>
<!-- 多行文本输入框 --> <!-- 多行文本输入框 -->
<el-input <el-input v-if="qs.Type === 'textarea'" v-model="questionForm[qs.Id]" type="textarea"
v-if="qs.Type==='textarea'" :autosize="{ minRows: 2, maxRows: 4 }" :disabled="!isCurrentTask || readingTaskState >= 2"
v-model="questionForm[qs.Id]" @change="((val) => { formItemChange(val, qs) })" />
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
:disabled="!isCurrentTask || readingTaskState>=2 "
@change="((val)=>{formItemChange(val, qs)})"
/>
<!-- 下拉框 --> <!-- 下拉框 -->
<el-select <el-select v-if="qs.Type === 'select'" v-model="questionForm[qs.Id]" filterable
v-if="qs.Type==='select'"
v-model="questionForm[qs.Id]"
filterable
:placeholder="qs.QuestionMark === 8 ? $t('common:placeholder:selectorsearch') : $t('common:placeholder:select')" :placeholder="qs.QuestionMark === 8 ? $t('common:placeholder:selectorsearch') : $t('common:placeholder:select')"
:disabled="!isCurrentTask || readingTaskState>=2 || qs.QuestionMark === 0 || qs.QuestionMark === 1 || qs.QuestionMark === 2 || qs.QuestionMark === 5 || (qs.QuestionMark === 6 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answers.SplitOrMergeLesionName))|| (qs.QuestionMark === 8 && (isCurrentTaskAdd === 'False'|| !!answers.SplitOrMergeLesionName)) || (qs.QuestionMark === 10 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answers.SplitOrMergeLesionName)) || (qs.QuestionMark === 7 && isFirstChangeTask ) || (qs.QuestionMark === 8 && isFirstChangeTask)" :disabled="!isCurrentTask || readingTaskState >= 2 || qs.QuestionMark === 0 || qs.QuestionMark === 1 || qs.QuestionMark === 2 || qs.QuestionMark === 5 || (qs.QuestionMark === 6 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answers.SplitOrMergeLesionName)) || (qs.QuestionMark === 8 && (isCurrentTaskAdd === 'False' || !!answers.SplitOrMergeLesionName)) || (qs.QuestionMark === 10 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answers.SplitOrMergeLesionName)) || (qs.QuestionMark === 7 && isFirstChangeTask) || (qs.QuestionMark === 8 && isFirstChangeTask)"
@change="((val)=>{formItemChange(val, qs)})" @change="((val) => { formItemChange(val, qs) })">
>
<template v-if="qs.QuestionMark === 8" #prefix> <template v-if="qs.QuestionMark === 8" #prefix>
<span style="padding-left: 5px;"> <span style="padding-left: 5px;">
<i class="el-icon-search" /> <i class="el-icon-search" />
</span> </span>
</template> </template>
<template v-if="qs.TableQuestionType === 1"> <template v-if="qs.TableQuestionType === 1">
<el-option <el-option v-for="item in organList" :key="item.Id" :label="item[qs.DataTableColumn]"
v-for="item in organList" :value="item[qs.DataTableColumn]" />
:key="item.Id"
:label="item[qs.DataTableColumn]"
:value="item[qs.DataTableColumn]"
/>
</template> </template>
<template v-else-if="qs.DictionaryCode && qs.QuestionMark === 7 && isBaseLineTask"> <template v-else-if="qs.DictionaryCode && qs.QuestionMark === 7 && isBaseLineTask">
<el-option <el-option v-for="item of $d[qs.DictionaryCode]"
v-for="item of $d[qs.DictionaryCode]" v-show="((lesionType === 0 && item.value === 0) || (lesionType === 1 && (item.value === 0))) && (crterionDictionaryGroup.indexOf(item.raw.CrterionDictionaryGroup) > -1)"
v-show="((lesionType === 0 && item.value ===0) || (lesionType === 1 && (item.value ===0))) && (crterionDictionaryGroup.indexOf(item.raw.CrterionDictionaryGroup) > -1)" :key="item.id" :value="item.value" :label="item.label" />
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template> </template>
<template v-else-if="qs.DictionaryCode && qs.QuestionMark === 7 && isFirstChangeTask && (lesionType === 5 || lesionType ===6)"> <template
<el-option v-else-if="qs.DictionaryCode && qs.QuestionMark === 7 && isFirstChangeTask && (lesionType === 5 || lesionType === 6)">
v-for="item of $d[qs.DictionaryCode]" <el-option v-for="item of $d[qs.DictionaryCode]"
v-show="((lesionType === 5 && item.value ===1) || (lesionType === 6 && (item.value ===0))) && (crterionDictionaryGroup.indexOf(item.raw.CrterionDictionaryGroup) > -1)" v-show="((lesionType === 5 && item.value === 1) || (lesionType === 6 && (item.value === 0))) && (crterionDictionaryGroup.indexOf(item.raw.CrterionDictionaryGroup) > -1)"
:key="item.id" :key="item.id" :value="item.value" :label="item.label" />
:value="item.value"
:label="item.label"
/>
</template> </template>
<template v-else-if="qs.DictionaryCode && qs.QuestionMark === 7 && !isBaseLineTask"> <template v-else-if="qs.DictionaryCode && qs.QuestionMark === 7 && !isBaseLineTask">
<el-option-group <el-option-group
:label="!isNaN(parseFloat(answers.LastTaskState)) ? `${$t('trials:dicomReading:tip:lastVisitStatus')} ${$fd(qs.DictionaryCode,parseFloat(answers.LastTaskState))}` : ''" :label="!isNaN(parseFloat(answers.LastTaskState)) ? `${$t('trials:dicomReading:tip:lastVisitStatus')} ${$fd(qs.DictionaryCode, parseFloat(answers.LastTaskState))}` : ''">
>
<!-- 首次分裂的病灶只能选择存在 --> <!-- 首次分裂的病灶只能选择存在 -->
<template v-if="answers.IsFristAdd=== 'True' && answers.SplitOrMergeType === '0'"> <template v-if="answers.IsFristAdd === 'True' && answers.SplitOrMergeType === '0'">
<el-option <el-option v-for="item of $d[qs.DictionaryCode]"
v-for="item of $d[qs.DictionaryCode]" v-show="((lesionType === 0 && item.value === 0) || (lesionType === 1 && item.value === 0) || (lesionType === 2 && item.value === 0) || (lesionType === 5 && item.value === 1) || (lesionType === 6 && item.value === 0) || (lesionType === 7 && item.value === 0) || (lesionType === 8 && item.value === 1)) && (crterionDictionaryGroup.indexOf(item.raw.CrterionDictionaryGroup) > -1)"
v-show="((lesionType === 0 && item.value === 0) || (lesionType === 1 && item.value === 0 ) || (lesionType === 2 && item.value === 0 )|| (lesionType === 5 && item.value === 1 )|| (lesionType === 6 && item.value === 0 )|| (lesionType === 7 && item.value === 0 )|| (lesionType === 8 && item.value === 1 )) && (crterionDictionaryGroup.indexOf(item.raw.CrterionDictionaryGroup) > -1)" :key="item.id" :value="item.value" :label="item.label" />
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template> </template>
<template v-else-if="isCurrentTaskAdd=== 'True' && (lesionType === 2 || lesionType === 8)"> <template v-else-if="isCurrentTaskAdd === 'True' && (lesionType === 2 || lesionType === 8)">
<!-- 首次添加的新病灶不能为无法评估和消失 --> <!-- 首次添加的新病灶不能为无法评估和消失 -->
<el-option <el-option v-for="item of $d[qs.DictionaryCode]"
v-for="item of $d[qs.DictionaryCode]"
v-show="(((item.value === 0 || item.value === 1) && lesionType === 2) || ((item.value === 1 || item.value === 2) && lesionType === 8)) && (crterionDictionaryGroup.indexOf(item.raw.CrterionDictionaryGroup) > -1)" v-show="(((item.value === 0 || item.value === 1) && lesionType === 2) || ((item.value === 1 || item.value === 2) && lesionType === 8)) && (crterionDictionaryGroup.indexOf(item.raw.CrterionDictionaryGroup) > -1)"
:key="item.id" :key="item.id" :value="item.value" :label="item.label" />
:value="item.value"
:label="item.label"
/>
</template> </template>
<template v-else-if="isCurrentTaskAdd=== 'False' && lesionType === 1 && answers.LastTaskState !== '4'"> <template v-else-if="isCurrentTaskAdd === 'False' && lesionType === 1 && answers.LastTaskState !== '4'">
<el-option <el-option v-for="item of filterState($d[qs.DictionaryCode])"
v-for="item of filterState($d[qs.DictionaryCode])"
v-show="(item.value !== 5) && (crterionDictionaryGroup.indexOf(item.raw.CrterionDictionaryGroup) > -1)" v-show="(item.value !== 5) && (crterionDictionaryGroup.indexOf(item.raw.CrterionDictionaryGroup) > -1)"
:key="item.id" :key="item.id" :value="item.value" :label="item.label" />
:value="item.value"
:label="item.label"
/>
</template> </template>
<template v-else> <template v-else>
<el-option <el-option v-for="item of filterState($d[qs.DictionaryCode])"
v-for="item of filterState($d[qs.DictionaryCode])" v-show="crterionDictionaryGroup.indexOf(item.raw.CrterionDictionaryGroup) > -1" :key="item.id"
v-show="crterionDictionaryGroup.indexOf(item.raw.CrterionDictionaryGroup) > -1" :value="item.value" :label="item.label" />
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template> </template>
</el-option-group> </el-option-group>
</template> </template>
<template v-else-if="qs.DictionaryCode && qs.QuestionMark !== 7"> <template v-else-if="qs.DictionaryCode && qs.QuestionMark !== 7">
<el-option <el-option v-for="item of $d[qs.DictionaryCode]"
v-for="item of $d[qs.DictionaryCode]" v-show="crterionDictionaryGroup.indexOf(item.raw.CrterionDictionaryGroup) > -1" :key="item.id"
v-show="crterionDictionaryGroup.indexOf(item.raw.CrterionDictionaryGroup) > -1" :value="item.value" :label="item.label" />
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template> </template>
<template v-else-if="qs.TypeValue"> <template v-else-if="qs.TypeValue">
<el-option <el-option v-for="val in qs.TypeValue.split('|')" :key="val" :label="val" :value="val" />
v-for="val in qs.TypeValue.split('|')"
:key="val"
:label="val"
:value="val"
/>
</template> </template>
</el-select> </el-select>
<!-- 单选 --> <!-- 单选 -->
<el-radio-group <el-radio-group v-if="qs.Type === 'radio'" v-model="questionForm[qs.id]"
v-if="qs.Type==='radio'" :disabled="!isCurrentTask || readingTaskState >= 2">
v-model="questionForm[qs.id]" <el-radio v-for="val in qs.options.split('|')" :key="val" :label="val">
:disabled="!isCurrentTask || readingTaskState>=2"
>
<el-radio
v-for="val in qs.options.split('|')"
:key="val"
:label="val"
>
{{ val }} {{ val }}
</el-radio> </el-radio>
</el-radio-group> </el-radio-group>
@ -199,33 +133,21 @@
</div> </div>
<div <div v-if="isCurrentTask && readingTaskState < 2" class="base-dialog-footer"
v-if="isCurrentTask && readingTaskState<2" style="text-align:right;margin-top:10px;">
class="base-dialog-footer"
style="text-align:right;margin-top:10px;"
>
<!-- 清除标记 --> <!-- 清除标记 -->
<el-button <el-button
v-if="questionForm.MeasureData && (!isFirstChangeTask || (isFirstChangeTask && (lesionType === 5 || lesionType === 6)))" v-if="questionForm.MeasureData && (!isFirstChangeTask || (isFirstChangeTask && (lesionType === 5 || lesionType === 6)))"
size="mini" size="mini" @click="handleDeleteMeasureData">
@click="handleDeleteMeasureData"
>
{{ $t('trials:reading:button:removeMark') }} {{ $t('trials:reading:button:removeMark') }}
</el-button> </el-button>
<!-- 删除 --> <!-- 删除 -->
<el-button <el-button v-if="!isFirstChangeTask && isCurrentTaskAdd !== 'False'" size="mini" @click="handleDelete">
v-if="!isFirstChangeTask && isCurrentTaskAdd !== 'False'"
size="mini"
@click="handleDelete"
>
{{ $t('common:button:delete') }} {{ $t('common:button:delete') }}
</el-button> </el-button>
<!-- 保存 --> <!-- 保存 -->
<el-button <el-button v-if="(isFirstChangeTask && (lesionType === 5 || lesionType === 6)) || !isFirstChangeTask" size="mini"
v-if="(isFirstChangeTask && (lesionType === 5 || lesionType === 6)) || !isFirstChangeTask" @click="handleSave">
size="mini"
@click="handleSave"
>
{{ $t('common:button:save') }} {{ $t('common:button:save') }}
</el-button> </el-button>
</div> </div>
@ -330,6 +252,9 @@ export default {
DicomEvent.$off('handleImageQualityAbnormal') DicomEvent.$off('handleImageQualityAbnormal')
}, },
methods: { methods: {
handleReadingChart(e) {
this.$emit('handleReadingChart', e)
},
async initForm() { async initForm() {
const loading = this.$loading({ fullscreen: true }) const loading = this.$loading({ fullscreen: true })
this.questions.forEach(item => { this.questions.forEach(item => {
@ -375,12 +300,12 @@ export default {
await this.setMeasureData(this.answers.measureObj, true) await this.setMeasureData(this.answers.measureObj, true)
} else { } else {
if (this.questionForm.MeasureData) { if (this.questionForm.MeasureData) {
// 线 // 线
if (this.questionForm.MeasureData.type === 'Bidirectional') { if (this.questionForm.MeasureData.type === 'Bidirectional') {
this.organList = [] this.organList = []
await this.getOrganInfoList(1) await this.getOrganInfoList(1)
} else if (this.questionForm.MeasureData.type === 'Length') { } else if (this.questionForm.MeasureData.type === 'Length') {
// //
this.organList = [] this.organList = []
await this.getOrganInfoList(0) await this.getOrganInfoList(0)
} else { } else {
@ -486,8 +411,8 @@ export default {
type: 'warning', type: 'warning',
distinguishCancelAndClose: true distinguishCancelAndClose: true
}) })
.then(() => {}) .then(() => { })
.catch(() => {}) .catch(() => { })
this.$set(this.questionForm, 'LesionType', this.originalQuestionForm.LesionType) this.$set(this.questionForm, 'LesionType', this.originalQuestionForm.LesionType)
return return
} }
@ -500,7 +425,7 @@ export default {
this.$confirm(msg, { this.$confirm(msg, {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
this.$set(this.questionForm, 'LesionType', this.originalQuestionForm.LesionType) this.$set(this.questionForm, 'LesionType', this.originalQuestionForm.LesionType)
return return
@ -735,7 +660,7 @@ export default {
} }
} }
} }
var status = '' var status = ''
if (lesionState) { if (lesionState) {
if (this.lesionType === 0 && lesionState === 1) { if (this.lesionType === 0 && lesionState === 1) {
@ -926,7 +851,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg19'), { this.$confirm(this.$t('trials:reading:warnning:msg19'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -938,7 +863,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg20'), { this.$confirm(this.$t('trials:reading:warnning:msg20'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -955,7 +880,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg21'), { this.$confirm(this.$t('trials:reading:warnning:msg21'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -967,7 +892,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg22'), { this.$confirm(this.$t('trials:reading:warnning:msg22'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -985,7 +910,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg23'), { this.$confirm(this.$t('trials:reading:warnning:msg23'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -997,7 +922,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg24'), { this.$confirm(this.$t('trials:reading:warnning:msg24'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1013,7 +938,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg25'), { this.$confirm(this.$t('trials:reading:warnning:msg25'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1029,7 +954,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg26'), { this.$confirm(this.$t('trials:reading:warnning:msg26'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1050,7 +975,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg27'), { this.$confirm(this.$t('trials:reading:warnning:msg27'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1062,7 +987,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg28'), { this.$confirm(this.$t('trials:reading:warnning:msg28'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1078,7 +1003,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg29'), { this.$confirm(this.$t('trials:reading:warnning:msg29'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1090,7 +1015,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg30'), { this.$confirm(this.$t('trials:reading:warnning:msg30'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1111,7 +1036,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg31'), { this.$confirm(this.$t('trials:reading:warnning:msg31'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1123,7 +1048,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg32'), { this.$confirm(this.$t('trials:reading:warnning:msg32'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1140,7 +1065,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg33'), { this.$confirm(this.$t('trials:reading:warnning:msg33'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1152,7 +1077,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg34'), { this.$confirm(this.$t('trials:reading:warnning:msg34'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1169,7 +1094,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg35'), { this.$confirm(this.$t('trials:reading:warnning:msg35'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1181,7 +1106,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg36'), { this.$confirm(this.$t('trials:reading:warnning:msg36'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1193,12 +1118,12 @@ export default {
if (this.lesionType === 1 && lesionState === 3) { if (this.lesionType === 1 && lesionState === 3) {
if (lymphNodes === 1) { if (lymphNodes === 1) {
// 使 // 使
if (!(measureData && (measureData.type === 'ArrowAnnotate'))) { if (!(measureData && (measureData.type === 'ArrowAnnotate' || (measureData.type === 'Bidirectional' && lesionShort < 10)))) {
// 使 // 使
this.$confirm(this.$t('trials:reading:warnning:msg37'), { this.$confirm(this.$t('trials:reading:warnning:msg37'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1210,7 +1135,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg38'), { this.$confirm(this.$t('trials:reading:warnning:msg38'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1227,7 +1152,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg33'), { this.$confirm(this.$t('trials:reading:warnning:msg33'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1239,7 +1164,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg34'), { this.$confirm(this.$t('trials:reading:warnning:msg34'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1256,7 +1181,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg50'), { this.$confirm(this.$t('trials:iRecist:warnning:msg50'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1268,7 +1193,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg51'), { this.$confirm(this.$t('trials:iRecist:warnning:msg51'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1285,7 +1210,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg39'), { this.$confirm(this.$t('trials:reading:warnning:msg39'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1297,7 +1222,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg40'), { this.$confirm(this.$t('trials:reading:warnning:msg40'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1314,7 +1239,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg41'), { this.$confirm(this.$t('trials:reading:warnning:msg41'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1326,7 +1251,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg42'), { this.$confirm(this.$t('trials:reading:warnning:msg42'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1343,7 +1268,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg43'), { this.$confirm(this.$t('trials:reading:warnning:msg43'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1355,7 +1280,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg44'), { this.$confirm(this.$t('trials:reading:warnning:msg44'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1367,12 +1292,12 @@ export default {
if (this.lesionType === 2 && lesionState === 3) { if (this.lesionType === 2 && lesionState === 3) {
if (lymphNodes === 1) { if (lymphNodes === 1) {
// 使 // 使
if (!(measureData && (measureData.type === 'ArrowAnnotate'))) { if (!(measureData && (measureData.type === 'ArrowAnnotate' || (measureData.type === 'Bidirectional' && lesionShort < 10)))) {
// 使 // 使
this.$confirm(this.$t('trials:reading:warnning:msg45'), { this.$confirm(this.$t('trials:reading:warnning:msg45'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1384,7 +1309,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg46'), { this.$confirm(this.$t('trials:reading:warnning:msg46'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1404,7 +1329,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg31'), { this.$confirm(this.$t('trials:iRecist:warnning:msg31'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1416,7 +1341,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg32'), { this.$confirm(this.$t('trials:iRecist:warnning:msg32'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1433,7 +1358,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg1'), { this.$confirm(this.$t('trials:iRecist:warnning:msg1'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1445,7 +1370,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg2'), { this.$confirm(this.$t('trials:iRecist:warnning:msg2'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1460,7 +1385,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg3'), { this.$confirm(this.$t('trials:iRecist:warnning:msg3'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1472,7 +1397,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg4'), { this.$confirm(this.$t('trials:iRecist:warnning:msg4'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1493,7 +1418,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg5'), { this.$confirm(this.$t('trials:iRecist:warnning:msg5'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1505,7 +1430,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg6'), { this.$confirm(this.$t('trials:iRecist:warnning:msg6'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1522,7 +1447,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg33'), { this.$confirm(this.$t('trials:iRecist:warnning:msg33'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1538,7 +1463,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg34'), { this.$confirm(this.$t('trials:iRecist:warnning:msg34'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1595,7 +1520,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg7'), { this.$confirm(this.$t('trials:iRecist:warnning:msg7'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1607,7 +1532,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg8'), { this.$confirm(this.$t('trials:iRecist:warnning:msg8'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1623,7 +1548,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg9'), { this.$confirm(this.$t('trials:iRecist:warnning:msg9'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1635,7 +1560,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg10'), { this.$confirm(this.$t('trials:iRecist:warnning:msg10'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1651,7 +1576,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg11'), { this.$confirm(this.$t('trials:iRecist:warnning:msg11'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1663,7 +1588,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg12'), { this.$confirm(this.$t('trials:iRecist:warnning:msg12'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1679,7 +1604,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg13'), { this.$confirm(this.$t('trials:iRecist:warnning:msg13'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1691,7 +1616,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg14'), { this.$confirm(this.$t('trials:iRecist:warnning:msg14'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1711,7 +1636,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg15'), { this.$confirm(this.$t('trials:iRecist:warnning:msg15'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1723,7 +1648,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg16'), { this.$confirm(this.$t('trials:iRecist:warnning:msg16'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1740,7 +1665,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg17'), { this.$confirm(this.$t('trials:iRecist:warnning:msg17'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1752,7 +1677,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg18'), { this.$confirm(this.$t('trials:iRecist:warnning:msg18'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1769,7 +1694,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg19'), { this.$confirm(this.$t('trials:iRecist:warnning:msg19'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1781,7 +1706,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg20'), { this.$confirm(this.$t('trials:iRecist:warnning:msg20'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1798,7 +1723,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg21'), { this.$confirm(this.$t('trials:iRecist:warnning:msg21'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1810,7 +1735,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg22'), { this.$confirm(this.$t('trials:iRecist:warnning:msg22'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1829,7 +1754,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg23'), { this.$confirm(this.$t('trials:iRecist:warnning:msg23'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1841,7 +1766,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg24'), { this.$confirm(this.$t('trials:iRecist:warnning:msg24'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1858,7 +1783,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg25'), { this.$confirm(this.$t('trials:iRecist:warnning:msg25'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1870,7 +1795,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg26'), { this.$confirm(this.$t('trials:iRecist:warnning:msg26'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1886,7 +1811,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg27'), { this.$confirm(this.$t('trials:iRecist:warnning:msg27'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1898,7 +1823,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg28'), { this.$confirm(this.$t('trials:iRecist:warnning:msg28'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1914,7 +1839,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg29'), { this.$confirm(this.$t('trials:iRecist:warnning:msg29'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1926,7 +1851,7 @@ export default {
this.$confirm(this.$t('trials:iRecist:warnning:msg30'), { this.$confirm(this.$t('trials:iRecist:warnning:msg30'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -2167,42 +2092,50 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.measurement-form{ .measurement-form {
::v-deep .el-form-item__label{ ::v-deep .el-form-item__label {
color: #c3c3c3; color: #c3c3c3;
} }
::v-deep .el-input .el-input__inner{
::v-deep .el-input .el-input__inner {
background-color: transparent; background-color: transparent;
color: #ddd; color: #ddd;
border: 1px solid #5e5e5e; border: 1px solid #5e5e5e;
} }
::v-deep .el-form-item{
::v-deep .el-form-item {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: flex-start; justify-content: flex-start;
} }
::v-deep .el-form-item__content{
::v-deep .el-form-item__content {
flex: 1; flex: 1;
} }
::v-deep .el-input.is-disabled .el-input__inner{
::v-deep .el-input.is-disabled .el-input__inner {
background-color: #646464a1; background-color: #646464a1;
} }
::v-deep .el-select.is-disabled .el-input__inner{
::v-deep .el-select.is-disabled .el-input__inner {
background-color: #646464a1; background-color: #646464a1;
} }
::v-deep .el-button--mini, .el-button--mini.is-round {
::v-deep .el-button--mini,
.el-button--mini.is-round {
padding: 7px 10px; padding: 7px 10px;
} }
.el-form-item__content
.el-select{ .el-form-item__content .el-select {
width: 100%; width: 100%;
} }
.input-width1{
width: calc(100% - 60px)!important; .input-width1 {
width: calc(100% - 60px) !important;
} }
.input-width2{
.input-width2 {
width: 100% !important; width: 100% !important;
} }
} }
</style> </style>

View File

@ -8,43 +8,48 @@
<span style="margin-left:5px;">{{ taskBlindName }}</span> <span style="margin-left:5px;">{{ taskBlindName }}</span>
</h3> </h3>
<div v-if="readingTaskState < 2"> <div v-if="readingTaskState < 2">
<el-tooltip class="item" effect="dark" :content="$t('trials:dicomReading:message:confirmReset')" placement="bottom"> <el-tooltip class="item" effect="dark" :content="$t('trials:dicomReading:message:confirmReset')"
<i placement="bottom">
class="el-icon-refresh-left" <i class="el-icon-refresh-left" @click="resetMeasuredData" />
@click="resetMeasuredData"
/>
</el-tooltip> </el-tooltip>
</div> </div>
</div> </div>
<!-- 非测量问题 --> <!-- 非测量问题 -->
<div class="lesions"> <div class="lesions">
<Questions <Questions ref="ecrf" :question-form-change-state="questionFormChangeState"
ref="ecrf" :question-form-change-num="questionFormChangeNum" :is-first-change-task="isFirstChangeTask"
:question-form-change-state="questionFormChangeState" @handleReadingChart="handleReadingChart" />
:question-form-change-num="questionFormChangeNum"
:is-first-change-task="isFirstChangeTask"
/>
</div> </div>
<!-- 测量问题 --> <!-- 测量问题 -->
<template v-if="questions.length > 0"> <template v-if="questions.length > 0">
<div v-for="(qs,index) in questions" :key="index" v-loading="loading" class="lesions lesions_wrapper"> <div v-for="(qs, index) in questions" :key="index" v-loading="loading" class="lesions lesions_wrapper">
<h4 v-if="qs.Type === 'group'" style="color: #ddd;padding: 5px 0px;margin: 0;"> <h4 v-if="qs.Type === 'group'" style="color: #ddd;padding: 5px 0px;margin: 0;">
{{ language==='en'?qs.GroupEnName:qs.GroupName }} {{ language === 'en' ? qs.GroupEnName : qs.GroupName }}
</h4> </h4>
<div class="lesion_list"> <div class="lesion_list">
<div v-for="item in qs.Childrens" v-show="(!isConvertedTask && !(isBaseLineTask && item.LesionType === 2)) || (isConvertedTask && (isFirstChangeTask && item.LesionType !== 8) || (!isFirstChangeTask && item.LesionType !== 2))" :key="item.Id"> <div v-for="item in qs.Childrens"
v-show="(!isConvertedTask && !(isBaseLineTask && item.LesionType === 2)) || (isConvertedTask && (isFirstChangeTask && item.LesionType !== 8) || (!isFirstChangeTask && item.LesionType !== 2))"
:key="item.Id">
<div v-if="item.Type === 'table'" class="flex-row" style="margin:3px 0;"> <div v-if="item.Type === 'table'" class="flex-row" style="margin:3px 0;">
<div <div v-if="isFirstChangeTask && item.LesionType === 2 && readingTaskState < 2" class="title">
v-if="isFirstChangeTask && item.LesionType === 2 && readingTaskState<2"
class="title"
>
{{ item.QuestionName }} {{ item.QuestionName }}
<span v-if="isFirstChangeTask && item.TableQuestions.Answers.length > 0" style="color:red;font-size: 12px;">{{ $t("trials:reading:dicom:IRecist:reevaluate") }}</span> <span v-if="isFirstChangeTask && item.TableQuestions.Answers.length > 0"
style="color:red;font-size: 12px;">{{ $t("trials:reading:dicom:IRecist:reevaluate") }}</span>
</div> </div>
<div v-else class="title"> <div v-else class="title">
{{ item.QuestionName }} {{ item.QuestionName }}
<svg-icon v-if="item.LesionType === 0" icon-class="readingChart"
class="svg-icon svg-readingChart-mini" @click.stop="(e) => handleReadingChart({
e,
data: {
ReportChartTypeEnum: 0,
QuestionName: item.QuestionName
},
})" />
</div> </div>
<div v-if="readingTaskState<2 && ((!isConvertedTask && (isBaseLineTask || item.LesionType === 2)) || (isConvertedTask && !isFirstChangeTask && item.LesionType === 8))" class="add-icon" @click.prevent="handleAdd(item)"> <div
v-if="readingTaskState < 2 && ((!isConvertedTask && (isBaseLineTask || item.LesionType === 2)) || (isConvertedTask && !isFirstChangeTask && item.LesionType === 8))"
class="add-icon" @click.prevent="handleAdd(item)">
<i class="el-icon-plus" /> <i class="el-icon-plus" />
</div> </div>
@ -52,109 +57,134 @@
111 111
</div> --> </div> -->
</div> </div>
<el-collapse <el-collapse v-if="item.Type === 'table' && item.TableQuestions" v-model="activeName" accordion
v-if="item.Type === 'table' && item.TableQuestions" @change="handleCollapseChange">
v-model="activeName" <el-collapse-item v-for="(q, i) in item.TableQuestions.Answers" :key="`${item.Id}_${q.RowIndex}`"
accordion
@change="handleCollapseChange"
>
<el-collapse-item
v-for="(q,i) in item.TableQuestions.Answers"
:key="`${item.Id}_${q.RowIndex}`"
:name="`${item.Id}_${q.RowIndex}`" :name="`${item.Id}_${q.RowIndex}`"
@contextmenu.prevent.native="collapseRightClick($event,q,item.Id,q.RowIndex)" @contextmenu.prevent.native="collapseRightClick($event, q, item.Id, q.RowIndex)">
>
<template slot="title"> <template slot="title">
<div <div style="width:300px;position: relative;"
style="width:300px;position: relative;" :style="{ color: (activeName === item.Id + q.RowIndex ? '#ffeb3b' : '#fff') }">
:style="{color:(activeName===item.Id+q.RowIndex?'#ffeb3b':'#fff')}"
>
{{ getLesionName(item.OrderMark,q.RowIndex) }} {{ getLesionName(item.OrderMark, q.RowIndex) }}
<!-- 未保存 --> <!-- 未保存 -->
<el-tooltip v-if="readingTaskState<2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) === 0" class="item" effect="dark" :content="$t('trials:reading:button:unsaved')" placement="bottom"> <el-tooltip
v-if="readingTaskState < 2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) === 0"
class="item" effect="dark" :content="$t('trials:reading:button:unsaved')" placement="bottom">
<i class="el-icon-warning" style="color:red" /> <i class="el-icon-warning" style="color:red" />
</el-tooltip> </el-tooltip>
<!-- 信息不完整 --> <!-- 信息不完整 -->
<el-tooltip v-if="readingTaskState<2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) ===1" class="item" effect="dark" :content="$t('trials:reading:button:incompleteInfor')" placement="bottom"> <el-tooltip
v-if="readingTaskState < 2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) === 1"
class="item" effect="dark" :content="$t('trials:reading:button:incompleteInfor')"
placement="bottom">
<i class="el-icon-warning" style="color:#ff9800" /> <i class="el-icon-warning" style="color:#ff9800" />
</el-tooltip> </el-tooltip>
<div style="position: absolute;left: 62px;top: 2px;"> <div
<!-- white-space: nowrap;overflow: hidden;text-overflow: ellipsis; --> :style="{ position: 'absolute', left: item.LesionType === 1 && readingTaskState < 2 ? '58px' : '50px', top: '2px' }">
<div style="font-size: 11px;width:220px;height: 30px;"> <div
<div style="font-size: 11px;width:210px;height: 30px;display: flex;justify-content: flex-start;flex-wrap: nowrap;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;">
v-if="item.TableQuestions.Answers[i].lesionPart" <el-tooltip
style="margin-left:10px;display: inline-block; white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width:90px" v-if="item.TableQuestions.Answers[i].SplitOrMergeType === '1' || item.TableQuestions.Answers[i].SplitOrMergeType === '3'"
> class="item" effect="dark"
<el-tooltip v-if="!!item.TableQuestions.Answers[i].lesionPart" class="item" effect="dark" :content="item.TableQuestions.Answers[i].lesionPart" placement="bottom"> :content="`${$t('trials:reading:message:fused')}${item.TableQuestions.Answers[i].SplitOrMergeLesionName}`"
<span>{{ item.TableQuestions.Answers[i].lesionPart }}</span> placement="bottom">
</el-tooltip> <div
v-if="item.TableQuestions.Answers[i].SplitOrMergeType === '1' || item.TableQuestions.Answers[i].SplitOrMergeType === '3'">
<span class="login-cycle"
:style="`background-color:${$GuidToColor(item.TableQuestions.Answers[i].MergeRowId)}`" />
</div>
</el-tooltip>
<div v-if="item.TableQuestions.Answers[i].SplitOrMergeType === '4'">
<span class="login-cycle"
:style="`background-color:${$GuidToColor(item.TableQuestions.Answers[i].RowId)}`" />
</div> </div>
<div style="display: inline-block;margin-left:5px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width:50px"> <!-- white-space: nowrap;overflow: hidden;text-overflow: ellipsis; -->
<span v-if="item.LesionType === 0"> <div style="font-size: 11px;width:220px;height: 30px;">
{{ $fd('TargetState',parseInt(item.TableQuestions.Answers[i].lesionState)) }} <div v-if="item.TableQuestions.Answers[i].lesionPart"
</span> style="margin-left:10px;display: inline-block; white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width:90px">
<span v-else-if="item.LesionType === 1"> <el-tooltip v-if="!!item.TableQuestions.Answers[i].lesionPart" class="item" effect="dark"
{{ $fd('NoTargetState',parseInt(item.TableQuestions.Answers[i].lesionState)) }} :content="item.TableQuestions.Answers[i].lesionPart" placement="bottom">
</span> <span>{{ item.TableQuestions.Answers[i].lesionPart }}</span>
<span v-else-if="item.LesionType === 2"> </el-tooltip>
{{ $fd('NewLesionState',parseInt(item.TableQuestions.Answers[i].lesionState)) }} </div>
</span> <div
<span v-else-if="item.LesionType === 5"> style="display: inline-block;margin-left:5px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width:50px">
{{ $fd('NewTargetLesionState',parseInt(item.TableQuestions.Answers[i].lesionState)) }} <span v-if="item.LesionType === 0">
</span> {{ $fd('TargetState', parseInt(item.TableQuestions.Answers[i].lesionState)) }}
<span v-else-if="item.LesionType === 6"> </span>
{{ $fd('NewNoTargetLesionState',parseInt(item.TableQuestions.Answers[i].lesionState)) }} <span v-else-if="item.LesionType === 1">
</span> {{ $fd('NoTargetState', parseInt(item.TableQuestions.Answers[i].lesionState)) }}
<span v-else-if="item.LesionType === 7"> </span>
{{ $fd('OtherPreviousNewLesionState',parseInt(item.TableQuestions.Answers[i].lesionState)) }} <span v-else-if="item.LesionType === 2">
</span> {{ $fd('NewLesionState', parseInt(item.TableQuestions.Answers[i].lesionState)) }}
<span v-else-if="item.LesionType === 8"> </span>
{{ $fd('NewLesionAfterTriggeringiRECSITState',parseInt(item.TableQuestions.Answers[i].lesionState)) }} <span v-else-if="item.LesionType === 5">
</span> {{ $fd('NewTargetLesionState', parseInt(item.TableQuestions.Answers[i].lesionState)) }}
</div> </span>
<div style="display: inline-block;margin-left:5px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width:60px"> <span v-else-if="item.LesionType === 6">
<template v-if="item.TableQuestions.Answers[i].isLymphLesion && !isNaN(parseInt(item.TableQuestions.Answers[i].lesionShort))"> {{ $fd('NewNoTargetLesionState', parseInt(item.TableQuestions.Answers[i].lesionState))
{{ item.TableQuestions.Answers[i].lesionShort }}mm }}
</template> </span>
<template v-else-if="!item.TableQuestions.Answers[i].isLymphLesion && !isNaN(parseInt(item.TableQuestions.Answers[i].lesionLength))"> <span v-else-if="item.LesionType === 7">
{{ item.TableQuestions.Answers[i].lesionLength }}mm {{ $fd('OtherPreviousNewLesionState',
</template> parseInt(item.TableQuestions.Answers[i].lesionState))
}}
</span>
<span v-else-if="item.LesionType === 8">
{{
$fd('NewLesionAfterTriggeringiRECSITState',
parseInt(item.TableQuestions.Answers[i].lesionState))
}}
</span>
</div>
<div
style="display: inline-block;margin-left:5px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width:60px">
<template
v-if="item.TableQuestions.Answers[i].isLymphLesion && !isNaN(parseInt(item.TableQuestions.Answers[i].lesionShort))">
{{ item.TableQuestions.Answers[i].lesionShort }}mm
</template>
<template
v-else-if="!item.TableQuestions.Answers[i].isLymphLesion && !isNaN(parseInt(item.TableQuestions.Answers[i].lesionLength))">
{{ item.TableQuestions.Answers[i].lesionLength }}mm
</template>
</div>
</div> </div>
</div> </div>
</div> </div>
<div v-if="((item.LesionType === 0 && parseInt(item.TableQuestions.Answers[i].lesionState) === 0) || (item.LesionType === 1 && [0,1,4,5].includes(parseInt(item.TableQuestions.Answers[i].lesionState))) || (item.LesionType === 2 && parseInt(item.TableQuestions.Answers[i].lesionState) === 0) || (item.LesionType === 5 && parseInt(item.TableQuestions.Answers[i].lesionState) === 1) || (item.LesionType === 6 && [0,1].includes(parseInt(item.TableQuestions.Answers[i].lesionState))) || (item.LesionType === 7 && parseInt(item.TableQuestions.Answers[i].lesionState) === 0) || (item.LesionType === 8 && parseInt(item.TableQuestions.Answers[i].lesionState) === 1)) && item.TableQuestions.Answers[i].IsCurrentTaskAdd === 'False'" style="position: absolute;right: 5px;top: 2px;transform: rotateY(180deg);"> <div
v-if="((item.LesionType === 0 && [0, 1, 4].includes(parseInt(item.TableQuestions.Answers[i].lesionState))) || (item.LesionType === 0 && parseInt(item.TableQuestions.Answers[i].lesionState) === 0) || (item.LesionType === 1 && [0, 1, 4, 5].includes(parseInt(item.TableQuestions.Answers[i].lesionState))) || (item.LesionType === 2 && parseInt(item.TableQuestions.Answers[i].lesionState) === 0) || (item.LesionType === 5 && parseInt(item.TableQuestions.Answers[i].lesionState) === 1) || (item.LesionType === 6 && [0, 1].includes(parseInt(item.TableQuestions.Answers[i].lesionState))) || (item.LesionType === 7 && parseInt(item.TableQuestions.Answers[i].lesionState) === 0) || (item.LesionType === 8 && parseInt(item.TableQuestions.Answers[i].lesionState) === 1)) && item.TableQuestions.Answers[i].IsCurrentTaskAdd === 'False'"
style="position: absolute;right: 5px;top: 2px;transform: rotateY(180deg);">
<!-- 分裂 --> <!-- 分裂 -->
<el-tooltip v-show="readingTaskState<2 && !!item.TableQuestions.Answers[i].RowId && (!isBaseLineTask && !isFirstChangeTask ) && item.TableQuestions.Answers[i].isDicomReading !== false" class="item" :content="$t('trials:reading:button:split')" placement="left"> <el-tooltip
<i class="iconfont icon-24gl-split" style="color:#fff;font-size: 16px;" @click.stop="handleSplit(item.TableQuestions.Answers[i].RowId,item.Id)" /> v-show="readingTaskState < 2 && !!item.TableQuestions.Answers[i].RowId && (!isBaseLineTask && !isFirstChangeTask) && item.TableQuestions.Answers[i].isDicomReading !== false"
class="item" :content="$t('trials:reading:button:split')" placement="left">
<i class="iconfont icon-24gl-split" style="color:#fff;font-size: 16px;"
@click.stop="handleSplit(item.TableQuestions.Answers[i].RowId, item.Id)" />
</el-tooltip>
<!-- 融合 -->
<el-tooltip
v-show="!!item.TableQuestions.Answers[i].RowId && item.TableQuestions.Answers[i].SplitOrMergeType !== '2' && ((item.LesionType === 0 && [0, 1, 4].includes(parseInt(item.TableQuestions.Answers[i].lesionState))))"
class="item" :content="$t('trials:reading:button:merge')" placement="bottom">
<i class="iconfont icon-24gl-merge" style="color:#fff;font-size: 16px;"
@click.stop="handleMerge(item.TableQuestions.Answers[i], item.Id, item.OrderMark)" />
</el-tooltip> </el-tooltip>
</div> </div>
</div> </div>
</template> </template>
<QuestionForm <QuestionForm :ref="`${item.Id}_${q.RowIndex}`" :questions="item.TableQuestions.Questions"
:ref="`${item.Id}_${q.RowIndex}`" :answers="item.TableQuestions.Answers[i]" :lesion-type="item.LesionType"
:questions="item.TableQuestions.Questions" :order-mark="item.OrderMark" :table-questions="tableQuestions" :row-index="String(q.RowIndex)"
:answers="item.TableQuestions.Answers[i]" :question-name="item.QuestionName" :parent-qs-id="item.Id"
:lesion-type="item.LesionType" :crterion-dictionary-group="item.CrterionDictionaryGroup" :visit-task-id="visitTaskId"
:order-mark="item.OrderMark" :is-current-task="isCurrentTask" :is-first-change-task="isFirstChangeTask"
:table-questions="tableQuestions" :is-converted-task="isConvertedTask" :reading-task-state="readingTaskState"
:row-index="String(q.RowIndex)" :is-base-line-task="isBaseLineTask" @getReadingQuestionAndAnswer="getReadingQuestionAndAnswer"
:question-name="item.QuestionName" @determineExistsUnsavedLession="determineExistsUnsavedLession" @resetQuestions="resetQuestions"
:parent-qs-id="item.Id" @close="close" @handleReadingChart="handleReadingChart" />
:crterion-dictionary-group="item.CrterionDictionaryGroup"
:visit-task-id="visitTaskId"
:is-current-task="isCurrentTask"
:is-first-change-task="isFirstChangeTask"
:is-converted-task="isConvertedTask"
:reading-task-state="readingTaskState"
:is-base-line-task="isBaseLineTask"
@getReadingQuestionAndAnswer="getReadingQuestionAndAnswer"
@determineExistsUnsavedLession="determineExistsUnsavedLession"
@resetQuestions="resetQuestions"
@close="close"
/>
</el-collapse-item> </el-collapse-item>
</el-collapse> </el-collapse>
@ -163,10 +193,35 @@
</div> </div>
</template> </template>
</div> </div>
<el-dialog v-if="merge.visible" v-loading="merge.loading" :visible.sync="merge.visible"
:close-on-click-modal="false" :title="$t('trials:reading:lugano:message:merge')" width="500px">
<div class="merge-table">
<div class="merge-label">
<label>{{ $t('trials:reading:lugano:label:currentLesion') }}</label>
<span>{{ mergeInfo.lesionName }}</span>
<span style="margin-left:10px">{{ mergeInfo.lesionPart }}</span>
</div>
<div class="merge-label"><label>{{ $t('trials:reading:lugano:label:selectLesion') }}</label></div>
<el-table :data="lesionData" style="width: 450px" size="small" height="200"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="45" />
<el-table-column prop="OrderMarkName" :label="$t('trials:reading:lugano:label:lesionNumber')" width="100" />
<el-table-column prop="Part" :label="$t('trials:reading:lugano:label:lesionLocation')" min-width="120"
show-overflow-tooltip />
</el-table>
</div>
<div slot="footer" style="text-align:right;">
<!-- 取消 -->
<el-button size="mini" @click="merge.visible = false">{{ $t('common:button:cancel') }}</el-button>
<!-- 确认 -->
<el-button type="primary" size="mini" :disabled="mergeList.length === 0" @click="confirmMerge">
{{ $t('common:button:confirm') }}</el-button>
</div>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
import { splitLesion } from '@/api/trials' import { splitLesion, getCanMergeLesion, mergeLesion } from '@/api/trials'
import { resetReadingTask } from '@/api/reading' import { resetReadingTask } from '@/api/reading'
import DicomEvent from './../DicomEvent' import DicomEvent from './../DicomEvent'
import store from '@/store' import store from '@/store'
@ -222,7 +277,12 @@ export default {
criterionType: null, criterionType: null,
subjectCode: '', subjectCode: '',
isConvertedTask: null, isConvertedTask: null,
isFirstChangeTask: null isFirstChangeTask: null,
merge: { visible: false, loading: false },
lesionData: [],
mergeInfo: {},
mergeList: []
} }
}, },
computed: { computed: {
@ -275,6 +335,69 @@ export default {
DicomEvent.$off('getUnSaveTarget') DicomEvent.$off('getUnSaveTarget')
}, },
methods: { methods: {
handleReadingChart(e) {
this.$emit('handleReadingChart', e)
},
//
async handleMerge(answers, questionId, orderMark) {
this.lesionData = []
this.mergeList = []
this.merge.visible = true
this.mergeInfo.questionId = questionId
this.mergeInfo.mergeRowId = answers.RowId
this.mergeInfo.lesionName = this.getLesionName(orderMark, answers.RowIndex)
this.mergeInfo.lesionPart = answers.lesionPart
this.merge.loading = true
try {
const res = await getCanMergeLesion({ rowId: answers.RowId })
if (res.IsSuccess) {
this.lesionData = res.Result
}
this.merge.loading = false
} catch (e) {
console.log(e)
this.merge.loading = false
}
},
handleSelectionChange(val) {
this.mergeList = []
val.map(i => {
this.mergeList.push(i.RowId)
})
},
confirmMerge() {
// ', ?'
this.$confirm(this.$t('trials:reading:lugano:warnning:fuse'), {
type: 'warning'
}).then(() => {
this.lesionMerge()
}).catch(() => {
})
},
async lesionMerge() {
this.merge.loading = true
try {
var params = {
visitTaskId: this.visitTaskId,
questionId: this.mergeInfo.questionId,
mergeMainRowId: this.mergeInfo.mergeRowId,
mergeRowIdList: this.mergeList
}
const res = await mergeLesion(params)
if (res.IsSuccess) {
this.merge.visible = false
DicomEvent.$emit('readingPageUpdate', {})
DicomEvent.$emit('getReportInfo', true)
DicomEvent.$emit('setMeasuredToolsPassive')
this.getReadingQuestionAndAnswer()
}
this.merge.loading = false
} catch (e) {
this.merge.loading = false
console.log(e)
}
},
async initList() { async initList() {
var i = this.visitTaskList.findIndex(i => i.VisitTaskId === this.lastCanvasTaskId) var i = this.visitTaskList.findIndex(i => i.VisitTaskId === this.lastCanvasTaskId)
if (i > -1) { if (i > -1) {
@ -568,7 +691,7 @@ export default {
.then(() => { .then(() => {
this.split(rowId, questionId) this.split(rowId, questionId)
}) })
.catch(() => {}) .catch(() => { })
} else { } else {
// //
this.$confirm(this.$t('trials:reading:warnning:msg4'), { this.$confirm(this.$t('trials:reading:warnning:msg4'), {
@ -578,7 +701,7 @@ export default {
.then(() => { .then(() => {
this.split(rowId, questionId) this.split(rowId, questionId)
}) })
.catch(() => {}) .catch(() => { })
} }
} }
} }
@ -736,7 +859,7 @@ export default {
this.$confirm(msg, { this.$confirm(msg, {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
return return
} }
@ -747,7 +870,7 @@ export default {
this.$confirm(msg, { this.$confirm(msg, {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
} else { } else {
// saveTypeEnum: 0 // saveTypeEnum: 0
@ -898,7 +1021,7 @@ export default {
async changeLesionType(questionsObj) { async changeLesionType(questionsObj) {
await store.dispatch('reading/removeReadingQuestionAndAnswer', { lesionType: questionsObj.oldLesionType, rowIndex: questionsObj.rowIndex, visitTaskId: this.visitTaskId }) await store.dispatch('reading/removeReadingQuestionAndAnswer', { lesionType: questionsObj.oldLesionType, rowIndex: questionsObj.rowIndex, visitTaskId: this.visitTaskId })
// saveTypeEnum: 0 // saveTypeEnum: 0
var lesionObj = { } var lesionObj = {}
var questionObj = questionsObj.questionForm var questionObj = questionsObj.questionForm
// //
var targetObj = this.tableQuestions.find(item => item.LesionType === questionsObj.newLesionType) var targetObj = this.tableQuestions.find(item => item.LesionType === questionsObj.newLesionType)
@ -1176,23 +1299,90 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.measurement-wrapper{ .login-cycle {
width: 5px;
height: 5px;
display: inline-block;
background-color: #428bca;
border-radius: 50%;
margin-right: 2px;
margin-bottom: 2px;
}
.merge-table {
padding: 0 10px;
::v-deep.el-table {
background-color: #1e1e1e !important;
color: #383838;
}
::v-deep.el-table td.el-table__cell,
.el-table th.el-table__cell.is-leaf {
border-bottom: 1px solid #383838;
}
.el-table--border::after,
.el-table--group::after,
.el-table::before {
background-color: #1e1e1e;
}
::v-deep.el-table__header-wrapper {
th {
background-color: #1e1e1e !important;
color: #dfdfdf;
border-bottom: 1px solid #383838;
}
}
::v-deep.el-table__body-wrapper {
tr {
background-color: #1e1e1e !important;
color: #dfdfdf;
}
tr:hover>td {
background-color: #1e1e1e !important;
}
}
::v-deep.el-table__empty-block {
background-color: #1e1e1e !important;
}
.merge-label {
color: #ddd;
font-size: 13px;
margin-bottom: 10px;
span {
font-size: 15px;
color: red;
}
}
}
.measurement-wrapper {
height: 100%; height: 100%;
overflow-y: auto; overflow-y: auto;
// overflow: hidden; // overflow: hidden;
.container{ .container {
padding: 10px; padding: 10px;
.basic-info{
.basic-info {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
h3{
h3 {
color: #ddd; color: #ddd;
padding: 5px 0px; padding: 5px 0px;
margin: 0; margin: 0;
} }
i{
i {
color: #fff; color: #fff;
font-size: 22px; font-size: 22px;
font-weight: bold; font-weight: bold;
@ -1200,14 +1390,16 @@ export default {
} }
} }
} }
.title{
.title {
padding: 5px; padding: 5px;
font-weight: bold; font-weight: bold;
color: #ddd; color: #ddd;
font-size: 15px; font-size: 15px;
} }
.add-icon{
.add-icon {
padding: 5px; padding: 5px;
font-weight: bold; font-weight: bold;
color: #ddd; color: #ddd;
@ -1216,42 +1408,49 @@ export default {
margin-bottom: 2px; margin-bottom: 2px;
cursor: pointer; cursor: pointer;
} }
.add-icon:hover{
.add-icon:hover {
background-color: #607d8b; background-color: #607d8b;
} }
.flex-row{ .flex-row {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
background-color: #424242; background-color: #424242;
} }
.lesion_list{
.lesion_list {
position: relative; position: relative;
} }
.el-collapse{
border-bottom:none; .el-collapse {
border-top:none; border-bottom: none;
::v-deep .el-collapse-item{ border-top: none;
background-color: #000!important;
::v-deep .el-collapse-item {
background-color: #000 !important;
color: #ddd; color: #ddd;
} }
::v-deep .el-collapse-item__header{
background-color: #000!important; ::v-deep .el-collapse-item__header {
background-color: #000 !important;
color: #ddd; color: #ddd;
border-bottom-color:#5a5a5a; border-bottom-color: #5a5a5a;
padding-left: 5px; padding-left: 5px;
height: 35px; height: 35px;
line-height: 35px; line-height: 35px;
} }
::v-deep .el-collapse-item__wrap{
background-color: #000!important; ::v-deep .el-collapse-item__wrap {
background-color: #000 !important;
color: #ddd; color: #ddd;
} }
::v-deep .el-collapse-item__content{
width:260px; ::v-deep .el-collapse-item__content {
width: 260px;
position: absolute; position: absolute;
top: 0px; top: 0px;
right: 0px; right: 0px;
@ -1260,7 +1459,7 @@ export default {
z-index: 1; z-index: 1;
color: #ddd; color: #ddd;
padding: 5px; padding: 5px;
background-color:#1e1e1e; background-color: #1e1e1e;
} }
} }

View File

@ -18,7 +18,7 @@
<!-- 影像质量问题 --> <!-- 影像质量问题 -->
<div class="lesions"> <div class="lesions">
<Questions ref="ecrf" :question-form-change-state="true" :question-form-change-num="0" :is-qulity-issues="false" <Questions ref="ecrf" :question-form-change-state="true" :question-form-change-num="0" :is-qulity-issues="false"
:group-classify="1" /> :group-classify="1" @handleReadingChart="handleReadingChart" />
</div> </div>
<!-- 测量问题 --> <!-- 测量问题 -->
<template v-if="questions.length > 0"> <template v-if="questions.length > 0">
@ -37,7 +37,8 @@
<div class="add-icon" @click.prevent="downloadTpl"> <div class="add-icon" @click.prevent="downloadTpl">
<i class="el-icon-download" /> <i class="el-icon-download" />
</div> </div>
<div class="add-icon" style="margin: 0 5px;" @click.prevent="uploadTpl(item.LesionType, item.QuestionName)"> <div class="add-icon" style="margin: 0 5px;"
@click.prevent="uploadTpl(item.LesionType, item.QuestionName)">
<i class="el-icon-upload2" /> <i class="el-icon-upload2" />
</div> </div>
<div class="add-icon" @click.prevent="handleAddOrEdit('add', item)"> <div class="add-icon" @click.prevent="handleAddOrEdit('add', item)">
@ -100,9 +101,19 @@
@change="((val) => { formItemChange(val, item) })" /> @change="((val) => { formItemChange(val, item) })" />
</template> </template>
<template v-if="item.Type === 'number'"> <template v-if="item.Type === 'number'">
<el-input-number v-model="questionForm[item.Id]" <div style="display: flex;justify-content: space-between;">
:disabled="!isCurrentTask || readingTaskState >= 2" :precision="0" <el-input-number v-model="questionForm[item.Id]"
@change="((val) => { formItemChange(val, item) })" /> :disabled="!isCurrentTask || readingTaskState >= 2" :precision="0"
@change="((val) => { formItemChange(val, item) })" />
<svg-icon v-if="item.ShowChartTypeEnum > 0" icon-class="readingChart"
class="svg-icon svg-readingChart" @click.stop="(e) => handleReadingChart({
e,
data: {
QuestionId: item.Id,
QuestionName: item.QuestionName
}
})" />
</div>
</template> </template>
<template v-if="item.Type === 'select'"> <template v-if="item.Type === 'select'">
<el-select v-model="questionForm[item.Id]" :disabled="!isCurrentTask || readingTaskState >= 2" <el-select v-model="questionForm[item.Id]" :disabled="!isCurrentTask || readingTaskState >= 2"
@ -159,7 +170,7 @@
<el-form ref="tableQsForm" v-loading="loading" :model="qsForm" size="small"> <el-form ref="tableQsForm" v-loading="loading" :model="qsForm" size="small">
<QuestionTableFormItem v-for="item in qsList" :key="item.Id" :question="item" :question-form="qsForm" <QuestionTableFormItem v-for="item in qsList" :key="item.Id" :question="item" :question-form="qsForm"
:reading-task-state="readingTaskState" @setFormItemData="setFormItemData" :reading-task-state="readingTaskState" @setFormItemData="setFormItemData"
@resetFormItemData="resetFormItemData" /> @resetFormItemData="resetFormItemData" @handleReadingChart="handleReadingChart" />
<el-form-item style="text-align: right"> <el-form-item style="text-align: right">
<el-button size="small" @click="addOrEdit.visible = false"> <el-button size="small" @click="addOrEdit.visible = false">
{{ $t('common:button:cancel') }} {{ $t('common:button:cancel') }}
@ -286,6 +297,9 @@ export default {
DicomEvent.$off('refreshQuestions') DicomEvent.$off('refreshQuestions')
}, },
methods: { methods: {
handleReadingChart(e) {
this.$emit('handleReadingChart', e)
},
async initList() { async initList() {
var i = this.visitTaskList.findIndex(i => i.VisitTaskId === this.lastCanvasTaskId) var i = this.visitTaskList.findIndex(i => i.VisitTaskId === this.lastCanvasTaskId)
if (i > -1) { if (i > -1) {

View File

@ -1,119 +1,66 @@
<template> <template>
<div> <div>
<div <div v-if="!!question.GroupName && question.Type === 'group'">
v-if="!!question.GroupName && question.Type==='group'"
>
<h4 style="color: #ddd;padding: 5px 0px;margin: 0;"> <h4 style="color: #ddd;padding: 5px 0px;margin: 0;">
{{ language==='en'?question.GroupEnName:question.GroupName }} {{ language === 'en' ? question.GroupEnName : question.GroupName }}
</h4> </h4>
</div> </div>
<template v-else> <template v-else>
<el-form-item <el-form-item
v-if="(question.ShowQuestion===1 && question.ParentTriggerValueList.includes(String(questionForm[question.ParentId]))) || question.ShowQuestion===0 " v-if="(question.ShowQuestion === 1 && question.ParentTriggerValueList.includes(String(questionForm[question.ParentId]))) || question.ShowQuestion === 0"
:label="`${question.QuestionName}`" :label="`${question.QuestionName}`" :prop="question.Id" :rules="[
:prop="question.Id" {
:rules="[ required: (question.IsRequired === 0 || (question.IsRequired === 1 && question.RelevanceId && (questionForm[question.RelevanceId] === question.RelevanceValue))) && question.Type !== 'group' && question.Type !== 'summary',
{ required: (question.IsRequired === 0 || (question.IsRequired ===1 && question.RelevanceId && (questionForm[question.RelevanceId] === question.RelevanceValue))) && question.Type!=='group' && question.Type!=='summary', message: ['radio', 'select', 'checkbox'].includes(question.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']
message: ['radio', 'select', 'checkbox'].includes(question.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']}, },
]" ]"
:class="[question.Type==='group' ? 'mb' : (question.Type==='upload' || question.QuestionName.length > 15) ?'uploadWrapper' : '']" :class="[question.Type === 'group' ? 'mb' : (question.Type === 'upload' || question.QuestionName.length > 15) ? 'uploadWrapper' : '']">
>
<!-- 输入框 --> <!-- 输入框 -->
<el-input <el-input v-if="question.Type === 'input'" v-model="questionForm[question.Id]" :disabled="readingTaskState >= 2"
v-if="question.Type==='input'" @change="((val) => { formItemChange(val, question) })" />
v-model="questionForm[question.Id]"
:disabled="readingTaskState >= 2"
@change="((val)=>{formItemChange(val, question)})"
/>
<!-- 多行文本输入框 --> <!-- 多行文本输入框 -->
<el-input <el-input v-else-if="question.Type === 'textarea'" v-model="questionForm[question.Id]" type="textarea"
v-else-if="question.Type==='textarea'" :autosize="{ minRows: 2, maxRows: 4 }" maxlength="500" :disabled="readingTaskState >= 2"
v-model="questionForm[question.Id]" @change="((val) => { formItemChange(val, question) })" />
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
maxlength="500"
:disabled="readingTaskState >= 2"
@change="((val)=>{formItemChange(val, question)})"
/>
<!-- 下拉框 --> <!-- 下拉框 -->
<el-select <el-select v-else-if="question.Type === 'select'" v-model="questionForm[question.Id]"
v-else-if="question.Type==='select'"
v-model="questionForm[question.Id]"
:disabled="readingTaskState >= 2 || ((question.TableQuestionType === 2 || question.QuestionGenre === 2) && !!question.DictionaryCode)" :disabled="readingTaskState >= 2 || ((question.TableQuestionType === 2 || question.QuestionGenre === 2) && !!question.DictionaryCode)"
clearable clearable @change="((val) => { formItemChange(val, question) })">
@change="((val)=>{formItemChange(val, question)})"
>
<template v-if="question.TableQuestionType === 1"> <template v-if="question.TableQuestionType === 1">
<el-option <el-option v-for="item in organList" :key="item.Id" :label="item[question.DataTableColumn]"
v-for="item in organList" :value="item[question.DataTableColumn]" />
:key="item.Id"
:label="item[question.DataTableColumn]"
:value="item[question.DataTableColumn]"
/>
</template> </template>
<template v-else-if="question.TableQuestionType === 3 || question.QuestionGenre === 3"> <template v-else-if="question.TableQuestionType === 3 || question.QuestionGenre === 3">
<el-option <el-option v-for="item of $d[question.DictionaryCode]" :key="item.id" :value="String(item.value)"
v-for="item of $d[question.DictionaryCode]" :label="item.label" />
:key="item.id"
:value="String(item.value)"
:label="item.label"
/>
</template> </template>
<template v-else-if="(question.TableQuestionType === 2 || question.QuestionGenre === 2) && question.DictionaryCode"> <template
<el-option v-else-if="(question.TableQuestionType === 2 || question.QuestionGenre === 2) && question.DictionaryCode">
v-for="item of $d[question.DictionaryCode]" <el-option v-for="item of $d[question.DictionaryCode]" :key="item.id" :value="String(item.value)"
:key="item.id" :label="item.label" />
:value="String(item.value)"
:label="item.label"
/>
</template> </template>
<template v-else> <template v-else>
<el-option <el-option v-for="val in question.TypeValue.split('|')" :key="val" :label="val" :value="val" />
v-for="val in question.TypeValue.split('|')"
:key="val"
:label="val"
:value="val"
/>
</template> </template>
</el-select> </el-select>
<!-- 单选 --> <!-- 单选 -->
<el-radio-group <el-radio-group v-else-if="question.Type === 'radio'" v-model="questionForm[question.Id]"
v-else-if="question.Type==='radio'" :disabled="readingTaskState >= 2" @change="((val) => { formItemChange(val, question) })">
v-model="questionForm[question.Id]"
:disabled="readingTaskState >= 2"
@change="((val)=>{formItemChange(val, question)})"
>
<template v-if="question.DictionaryCode"> <template v-if="question.DictionaryCode">
<el-radio <el-radio v-for="item of $d[question.DictionaryCode]" :key="item.id" :label="String(item.value)">
v-for="item of $d[question.DictionaryCode]"
:key="item.id"
:label="String(item.value)"
>
{{ item.label }} {{ item.label }}
</el-radio> </el-radio>
</template> </template>
<template v-else-if="question.TypeValue"> <template v-else-if="question.TypeValue">
<el-radio <el-radio v-for="val in question.TypeValue.split('|')" :key="val" :label="val">
v-for="val in question.TypeValue.split('|')"
:key="val"
:label="val"
>
{{ val }} {{ val }}
</el-radio> </el-radio>
</template> </template>
</el-radio-group> </el-radio-group>
<!-- 复选框 --> <!-- 复选框 -->
<el-checkbox-group <el-checkbox-group v-else-if="question.Type === 'checkbox'" v-model="questionForm[question.Id]"
v-else-if="question.Type==='checkbox'" :disabled="readingTaskState >= 2" @change="((val) => { formItemChange(val, question) })">
v-model="questionForm[question.Id]" <el-checkbox v-for="val in question.TypeValue.split('|')" :key="val" :label="val">
:disabled="readingTaskState >= 2"
@change="((val)=>{formItemChange(val, question)})"
>
<el-checkbox
v-for="val in question.TypeValue.split('|')"
:key="val"
:label="val"
>
{{ val }} {{ val }}
</el-checkbox> </el-checkbox>
</el-checkbox-group> </el-checkbox-group>
@ -144,40 +91,38 @@
/> />
</template> --> </template> -->
<!-- 数值类型 --> <!-- 数值类型 -->
<el-input <div style="display: flex;justify-content: space-between;"
v-else-if="question.Type==='number'" v-else-if="question.Type === 'number' || question.Type === 'calculation'">
v-model="questionForm[question.Id]" <el-input v-if="question.Type === 'number'" v-model="questionForm[question.Id]"
:disabled="readingTaskState>=2 " :disabled="readingTaskState >= 2" type="number" @change="((val) => { formItemChange(val, question) })">
type="number" <template v-if="question.Unit" slot="append">
@change="((val)=>{formItemChange(val, question)})" {{ $fd('ValueUnit', parseInt(question.Unit)) }}
> </template>
<template v-if="question.Unit" slot="append"> </el-input>
{{ $fd('ValueUnit', parseInt(question.Unit)) }}
</template> <el-input v-else-if="question.Type === 'calculation'" v-model="questionForm[question.Id]" disabled
</el-input> @change="((val) => { formItemChange(val, question) })">
<template v-if="question.Unit" slot="append">
{{ $fd('ValueUnit', parseInt(question.Unit)) }}
</template>
</el-input>
<svg-icon v-if="question.ShowChartTypeEnum > 0" icon-class="readingChart" class="svg-icon svg-readingChart"
@click.stop="(e) => handleReadingChart({
e,
data: {
TableQuestionId: question.Id,
RowIndex: questionForm.RowIndex,
QuestionName: question.QuestionName
}
})" />
</div>
<el-input
v-else-if="question.Type==='calculation'"
v-model="questionForm[question.Id]"
disabled
@change="((val)=>{formItemChange(val, question)})"
>
<template v-if="question.Unit" slot="append">
{{ $fd('ValueUnit', parseInt(question.Unit)) }}
</template>
</el-input>
</el-form-item> </el-form-item>
</template> </template>
<QuestionTableFormItem <QuestionTableFormItem v-for="item in question.Childrens" :key="item.Id" :question="item"
v-for="item in question.Childrens" :question-form="questionForm" :reading-task-state="readingTaskState" @setFormItemData="setFormItemData"
:key="item.Id" @resetFormItemData="resetFormItemData" />
:question="item"
:question-form="questionForm"
:reading-task-state="readingTaskState"
@setFormItemData="setFormItemData"
@resetFormItemData="resetFormItemData"
/>
</div> </div>
</template> </template>
<script> <script>
@ -214,6 +159,9 @@ export default {
this.digitPlaces = Number(localStorage.getItem('digitPlaces')) this.digitPlaces = Number(localStorage.getItem('digitPlaces'))
}, },
methods: { methods: {
handleReadingChart(e) {
this.$emit('handleReadingChart', e)
},
formItemChange(v, question) { formItemChange(v, question) {
if (question.Childrens && question.Childrens.length > 0) { if (question.Childrens && question.Childrens.length > 0) {
this.resetChild(question.Childrens) this.resetChild(question.Childrens)
@ -269,29 +217,36 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.mb{ .mb {
margin-bottom: 0px; margin-bottom: 0px;
} }
.disabled{
.disabled {
::v-deep .el-upload--picture-card { ::v-deep .el-upload--picture-card {
display: none; display: none;
} }
} }
.uploadWrapper{
.uploadWrapper {
display: flex; display: flex;
flex-direction: column !important; flex-direction: column !important;
align-items: flex-start; align-items: flex-start;
} }
::v-deep .el-input.is-disabled .el-input__inner{
background-color: #646464a1; ::v-deep .el-input.is-disabled .el-input__inner {
} background-color: #646464a1;
::v-deep .el-input-group__append, .el-input-group__prepend{ }
padding: 0 10px;
} ::v-deep .el-input-group__append,
::v-deep .el-form-item__content { .el-input-group__prepend {
width: 100%; padding: 0 10px;
} }
::v-deep .el-select.is-disabled .el-input__inner{
background-color: #646464a1; ::v-deep .el-form-item__content {
} width: 100%;
}
::v-deep .el-select.is-disabled .el-input__inner {
background-color: #646464a1;
}
</style> </style>

View File

@ -4,7 +4,7 @@
class="upload-excel-file" class="upload-excel-file"
> >
<!-- 文件 --> <!-- 文件 -->
<el-form-item :label="$t('trials:consistencyCheck:label:file')"> <el-form-item :label="$t('trials:consistencyCheck:label:file2')">
<div class="upload-container"> <div class="upload-container">
<el-upload <el-upload
class="upload-demo" class="upload-demo"

View File

@ -1,12 +1,6 @@
<template> <template>
<el-form <el-form v-if="isRender" ref="measurementForm" v-loading="loading" :model="questionForm" size="mini"
v-if="isRender" class="measurement-form">
ref="measurementForm"
v-loading="loading"
:model="questionForm"
size="mini"
class="measurement-form"
>
<div class="base-dialog-body"> <div class="base-dialog-body">
<div style="display: flex;justify-content: space-between;"> <div style="display: flex;justify-content: space-between;">
<h3 v-if="lesionName" style="color: #ddd;padding: 5px 0px;margin: 0;"> <h3 v-if="lesionName" style="color: #ddd;padding: 5px 0px;margin: 0;">
@ -19,198 +13,137 @@
</div> </div>
</div> </div>
<div ref="scrollPanel" style="height: 420px;overflow-y: auto;overflow-x: hidden;" @scroll.stop="scrollHandle"> <div ref="scrollPanel" style="height: 420px;overflow-y: auto;overflow-x: hidden;" @scroll.stop="scrollHandle">
<el-form-item <el-form-item :label="$t('trials:reading:title:lesionType')" prop="LesionType" :rules="[
:label="$t('trials:reading:title:lesionType')" { required: true, message: $t('common:ruleMessage:select'), trigger: ['blur'] },
prop="LesionType" ]">
:rules="[
{ required:true,message: $t('common:ruleMessage:select'), trigger: ['blur']},
]"
>
<!-- 下拉框 --> <!-- 下拉框 -->
<el-select <el-select :ref="`select_LesionType`" v-model="questionForm.LesionType" filterable
:ref="`select_LesionType`" :disabled="!isCurrentTask || readingTaskState >= 2 || !isBaseLineTask || answers.SplitOrMergeType === '1'"
v-model="questionForm.LesionType" @change="((val) => { lesionTypeChange(val) })">
filterable
:disabled="!isCurrentTask || readingTaskState>=2 || !isBaseLineTask || answers.SplitOrMergeType === '1'"
@change="((val)=>{lesionTypeChange(val)})"
>
<el-option <el-option v-for="item of $d.LesionType" v-show="!(isBaseLineTask && item.value === 2)" :key="item.id"
v-for="item of $d.LesionType" :value="item.value" :label="item.label" />
v-show="!(isBaseLineTask && item.value === 2)"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item <el-form-item v-for="qs in questions" v-show="qs.ShowQuestion !== 2" :key="qs.Id" :label="`${qs.QuestionName}`"
v-for="qs in questions" :prop="qs.Id" :rules="[
v-show="qs.ShowQuestion!==2" {
:key="qs.Id" required: (qs.IsRequired === 0 || (qs.IsRequired === 1 && qs.RelevanceId && (qs.RelevanceValue.includes(questionForm[qs.RelevanceId]))) || (qs.QuestionMark === 6 && questionForm.IsCanEditPosition === true) || (questionForm.IsCanEditPosition && qs.QuestionMark === 10)) && qs.Type !== 'group' && qs.Type !== 'summary',
:label="`${qs.QuestionName}`" message: ['radio', 'select', 'checkbox'].includes(qs.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']
:prop="qs.Id" },
:rules="[ ]">
{ required: (qs.IsRequired === 0 || (qs.IsRequired ===1 && qs.RelevanceId && (qs.RelevanceValue.includes(questionForm[qs.RelevanceId]))) || (qs.QuestionMark === 6 && questionForm.IsCanEditPosition === true) || (questionForm.IsCanEditPosition && qs.QuestionMark === 10)) && qs.Type!=='group' && qs.Type!=='summary',
message:['radio', 'select', 'checkbox'].includes(qs.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur','change']},
]"
>
<!-- 输入框 --> <!-- 输入框 -->
<template v-if="qs.Type==='input' || qs.Type==='number'"> <template v-if="qs.Type === 'input' || qs.Type === 'number'">
<div style="display: flex;justify-content: space-between;">
<el-input v-if="qs.Type === 'input' || qs.Type === 'number'" v-model="questionForm[qs.Id]"
:disabled="!isCurrentTask || readingTaskState >= 2 || qs.QuestionMark === 0 || qs.QuestionMark === 1 || qs.QuestionMark === 2 || qs.QuestionMark === 5 || (qs.QuestionMark === 6 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answers.SplitOrMergeLesionName)) || (qs.QuestionMark === 8 && (isCurrentTaskAdd === 'False' || !!answers.SplitOrMergeLesionName) && lesionType !== 2) || (qs.QuestionMark === 10 && (isCurrentTaskAdd === 'False' || !!answers.SplitOrMergeLesionName)) || answers.SplitOrMergeType === '1'"
@change="((val) => { formItemChange(val, qs) })">
<template v-if="(qs.QuestionMark === 0 || qs.QuestionMark === 1) && qs.Unit" slot="append">
{{ $fd('ValueUnit', parseInt(qs.Unit)) }}
</template>
</el-input>
<svg-icon v-if="qs.ShowChartTypeEnum > 0" icon-class="readingChart" class="svg-icon svg-readingChart"
@click.stop="(e) => handleReadingChart({
e,
data: {
TableQuestionId: qs.Id,
RowIndex: questionForm.RowIndex,
QuestionName: qs.QuestionName
}
})" />
</div>
<!-- {{ ((qs.QuestionMark === 6 && isCurrentTaskAdd === 'False') || (qs.QuestionMark === 6 && isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition)) }} --> <!-- {{ ((qs.QuestionMark === 6 && isCurrentTaskAdd === 'False') || (qs.QuestionMark === 6 && isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition)) }} -->
<el-input
v-if="qs.Type==='input' || qs.Type==='number'"
v-model="questionForm[qs.Id]"
:disabled="!isCurrentTask || readingTaskState>=2 || qs.QuestionMark === 0 || qs.QuestionMark === 1 || qs.QuestionMark === 2 || qs.QuestionMark === 5 || (qs.QuestionMark === 6 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answers.SplitOrMergeLesionName))|| (qs.QuestionMark === 8 && (isCurrentTaskAdd === 'False' || !!answers.SplitOrMergeLesionName) && lesionType !== 2) || (qs.QuestionMark === 10 && (isCurrentTaskAdd === 'False' || !!answers.SplitOrMergeLesionName)) || answers.SplitOrMergeType === '1'"
@change="((val)=>{formItemChange(val, qs)})"
>
<template v-if="(qs.QuestionMark===0 || qs.QuestionMark===1) && qs.Unit" slot="append">
{{ $fd('ValueUnit', parseInt(qs.Unit)) }}
</template>
</el-input>
</template> </template>
<!-- 多行文本输入框 --> <!-- 多行文本输入框 -->
<el-input <el-input v-if="qs.Type === 'textarea'" v-model="questionForm[qs.Id]" type="textarea"
v-if="qs.Type==='textarea'" :autosize="{ minRows: 2, maxRows: 4 }" maxlength="500"
v-model="questionForm[qs.Id]" :disabled="!isCurrentTask || readingTaskState >= 2 || answers.SplitOrMergeType === '1'"
type="textarea" @change="((val) => { formItemChange(val, qs) })" />
:autosize="{ minRows: 2, maxRows: 4}"
maxlength="500"
:disabled="!isCurrentTask || readingTaskState>=2 || answers.SplitOrMergeType === '1'"
@change="((val)=>{formItemChange(val, qs)})"
/>
<!-- 下拉框 --> <!-- 下拉框 -->
<!-- :disabled="!isCurrentTask || readingTaskState>=2 || (!isBaseLineTask && qs.QuestionMark === 5 && isCurrentTaskAdd === 'False') || qs.QuestionMark === 2 || (qs.QuestionMark === 8 && !isBaseLineTask && isCurrentTaskAdd === 'False')" --> <!-- :disabled="!isCurrentTask || readingTaskState>=2 || (!isBaseLineTask && qs.QuestionMark === 5 && isCurrentTaskAdd === 'False') || qs.QuestionMark === 2 || (qs.QuestionMark === 8 && !isBaseLineTask && isCurrentTaskAdd === 'False')" -->
<el-select <el-select v-if="qs.Type === 'select'" :ref="`select_${qs.Id}`" v-model="questionForm[qs.Id]" filterable
v-if="qs.Type==='select'"
:ref="`select_${qs.Id}`"
v-model="questionForm[qs.Id]"
filterable
:placeholder="qs.QuestionMark === 8 ? $t('common:placeholder:selectorsearch') : $t('common:placeholder:select')" :placeholder="qs.QuestionMark === 8 ? $t('common:placeholder:selectorsearch') : $t('common:placeholder:select')"
:disabled="!isCurrentTask || readingTaskState>=2 || qs.QuestionMark === 0 || qs.QuestionMark === 1 || qs.QuestionMark === 2 || qs.QuestionMark === 5 || (qs.QuestionMark === 6 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answers.SplitOrMergeLesionName))|| (qs.QuestionMark === 8 && (isCurrentTaskAdd === 'False'|| !!answers.SplitOrMergeLesionName)) || (qs.QuestionMark === 10 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answers.SplitOrMergeLesionName)) || (qs.QuestionMark === 7 && stateDisabled) || answers.SplitOrMergeType === '1' || (qs.QuestionMark === 7 && answers.SplitOrMergeType === '3')" :disabled="!isCurrentTask || readingTaskState >= 2 || qs.QuestionMark === 0 || qs.QuestionMark === 1 || qs.QuestionMark === 2 || qs.QuestionMark === 5 || (qs.QuestionMark === 6 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answers.SplitOrMergeLesionName)) || (qs.QuestionMark === 8 && (isCurrentTaskAdd === 'False' || !!answers.SplitOrMergeLesionName)) || (qs.QuestionMark === 10 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answers.SplitOrMergeLesionName)) || (qs.QuestionMark === 7 && stateDisabled) || answers.SplitOrMergeType === '1' || (qs.QuestionMark === 7 && answers.SplitOrMergeType === '3')"
@change="((val)=>{formItemChange(val, qs)})" @change="((val) => { formItemChange(val, qs) })">
>
<template v-if="qs.QuestionMark === 8" #prefix> <template v-if="qs.QuestionMark === 8" #prefix>
<span style="padding-left: 5px;"> <span style="padding-left: 5px;">
<i class="el-icon-search" /> <i class="el-icon-search" />
</span> </span>
</template> </template>
<template v-if="qs.TableQuestionType === 1"> <template v-if="qs.TableQuestionType === 1">
<el-option <el-option v-for="item in organList" :key="item.Id" :label="item[qs.DataTableColumn]"
v-for="item in organList" :value="item[qs.DataTableColumn]" />
:key="item.Id"
:label="item[qs.DataTableColumn]"
:value="item[qs.DataTableColumn]"
/>
</template> </template>
<template v-else-if="qs.DictionaryCode && qs.QuestionMark === 7 && isBaseLineTask"> <template v-else-if="qs.DictionaryCode && qs.QuestionMark === 7 && isBaseLineTask">
<el-option <el-option v-for="item of $d[qs.DictionaryCode]"
v-for="item of $d[qs.DictionaryCode]" v-show="(lesionType === 0 && item.value === 0) || (lesionType === 1 && (item.value === 0))"
v-show="(lesionType === 0 && item.value ===0) || (lesionType === 1 && (item.value ===0))" :key="item.id" :value="item.value" :label="item.label" />
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template> </template>
<template v-else-if="qs.DictionaryCode && qs.QuestionMark === 7 && !isBaseLineTask"> <template v-else-if="qs.DictionaryCode && qs.QuestionMark === 7 && !isBaseLineTask">
<el-option-group <el-option-group
:label="!isNaN(parseFloat(answers.LastTaskState)) ? `${$t('trials:dicomReading:tip:lastVisitStatus')} ${$fd(qs.DictionaryCode,parseFloat(answers.LastTaskState))}` : ''" :label="!isNaN(parseFloat(answers.LastTaskState)) ? `${$t('trials:dicomReading:tip:lastVisitStatus')} ${$fd(qs.DictionaryCode, parseFloat(answers.LastTaskState))}` : ''">
>
<!-- 首次分裂的病灶只能选择存在 --> <!-- 首次分裂的病灶只能选择存在 -->
<template v-if="answers.IsFristAdd=== 'True' && answers.SplitOrMergeType === '0'"> <template v-if="answers.IsFristAdd === 'True' && answers.SplitOrMergeType === '0'">
<el-option <el-option v-for="item of $d[qs.DictionaryCode]" v-show="item.value === 0" :key="item.id"
v-for="item of $d[qs.DictionaryCode]" :value="item.value" :label="item.label" />
v-show="item.value === 0"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template> </template>
<!-- 首次添加的新病灶不能为无法评估和消失 --> <!-- 首次添加的新病灶不能为无法评估和消失 -->
<template v-else-if="isCurrentTaskAdd=== 'True' && lesionType === 2"> <template v-else-if="isCurrentTaskAdd === 'True' && lesionType === 2">
<el-option <el-option v-for="item of $d[qs.DictionaryCode]" v-show="item.value === 0 || item.value === 1"
v-for="item of $d[qs.DictionaryCode]" :key="item.id" :value="item.value" :label="item.label" />
v-show="item.value === 0 || item.value === 1"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template> </template>
<template v-else> <template v-else>
<el-option <el-option v-for="item of filterState($d[qs.DictionaryCode])" :key="item.id" :value="item.value"
v-for="item of filterState($d[qs.DictionaryCode])" :label="item.label" />
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template> </template>
</el-option-group> </el-option-group>
</template> </template>
<template v-else-if="qs.DictionaryCode && qs.QuestionMark !== 7"> <template v-else-if="qs.DictionaryCode && qs.QuestionMark !== 7">
<el-option <el-option v-for="item of $d[qs.DictionaryCode]" :key="item.id" :value="item.value" :label="item.label" />
v-for="item of $d[qs.DictionaryCode]"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template> </template>
<template v-else> <template v-else>
<el-option <el-option v-for="val in qs.TypeValue.split('|')" :key="val" :label="val" :value="val" />
v-for="val in qs.TypeValue.split('|')"
:key="val"
:label="val"
:value="val"
/>
</template> </template>
</el-select> </el-select>
<!-- 单选 --> <!-- 单选 -->
<el-radio-group <el-radio-group v-if="qs.Type === 'radio'" v-model="questionForm[qs.id]"
v-if="qs.Type==='radio'" :disabled="!isCurrentTask || readingTaskState >= 2 || answers.SplitOrMergeType === '1'">
v-model="questionForm[qs.id]" <el-radio v-for="val in qs.options.split('|')" :key="val" :label="val"
:disabled="!isCurrentTask || readingTaskState>=2 || answers.SplitOrMergeType === '1'" @change="((val) => { formItemChange(val, qs) })">
>
<el-radio
v-for="val in qs.options.split('|')"
:key="val"
:label="val"
@change="((val)=>{formItemChange(val, qs)})"
>
{{ val }} {{ val }}
</el-radio> </el-radio>
</el-radio-group> </el-radio-group>
<template v-if="qs.QuestionMark === 20"> <template v-if="qs.QuestionMark === 20">
<div style="display: flex;flex-direction: row;justify-content: flex-start;"> <div style="display: flex;flex-direction: row;justify-content: flex-start;">
<div style="display: flex;justify-content: space-between;" v-if="qs.Type === 'calculation'">
<el-input <el-input v-if="qs.Type === 'calculation'" v-model="questionForm[qs.Id]" disabled style="width:120px;"
v-if="qs.Type==='calculation'" @change="((val) => { formItemChange(val, qs) })">
v-model="questionForm[qs.Id]" <template v-if="qs.Unit" slot="append">
disabled {{ $fd('ValueUnit', parseInt(qs.Unit)) }}
style="width:120px;" </template>
@change="((val)=>{formItemChange(val, qs)})" </el-input>
> <svg-icon v-if="qs.ShowChartTypeEnum > 0" icon-class="readingChart" class="svg-icon svg-readingChart"
<template v-if="qs.Unit" slot="append"> @click.stop="(e) => handleReadingChart({
{{ $fd('ValueUnit', parseInt(qs.Unit)) }} e,
</template> data: {
</el-input> TableQuestionId: qs.Id,
<viewer RowIndex: questionForm.RowIndex,
v-if="answers.OtherPicturePath" QuestionName: qs.QuestionName
ref="viewer" }
style="margin:0 10px;" })" />
:images="[`${OSSclientConfig.basePath}${answers.OtherPicturePath}`]" </div>
> <viewer v-if="answers.OtherPicturePath" ref="viewer" style="margin:0 10px;"
:images="[`${OSSclientConfig.basePath}${answers.OtherPicturePath}`]">
<span style="color:#409eff;cursor: pointer" @click="previewImage()"> <span style="color:#409eff;cursor: pointer" @click="previewImage()">
{{ $t('trials:lugano:button:suvscreenshot1') }} {{ $t('trials:lugano:button:suvscreenshot1') }}
</span> </span>
<img <img v-show="false" crossorigin="anonymous"
v-show="false" :src="`${OSSclientConfig.basePath}${answers.OtherPicturePath}`" alt="Image">
crossorigin="anonymous"
:src="`${OSSclientConfig.basePath}${answers.OtherPicturePath}`"
alt="Image"
>
</viewer> </viewer>
<!-- <img <!-- <img
v-if="answers.OtherPicturePath" v-if="answers.OtherPicturePath"
@ -226,45 +159,40 @@
</div> </div>
</template> </template>
<template v-else> <template v-else>
<el-input <div style="display: flex;justify-content: space-between;" v-if="qs.Type === 'calculation'">
v-if="qs.Type==='calculation'" <el-input v-if="qs.Type === 'calculation'" v-model="questionForm[qs.Id]" disabled
v-model="questionForm[qs.Id]" @change="((val) => { formItemChange(val, qs) })">
disabled <template v-if="qs.Unit" slot="append">
@change="((val)=>{formItemChange(val, qs)})" {{ $fd('ValueUnit', parseInt(qs.Unit)) }}
> </template>
<template v-if="qs.Unit" slot="append"> </el-input>
{{ $fd('ValueUnit', parseInt(qs.Unit)) }} <svg-icon v-if="qs.ShowChartTypeEnum > 0" icon-class="readingChart" class="svg-icon svg-readingChart"
</template> @click.stop="(e) => handleReadingChart({
</el-input> e,
data: {
TableQuestionId: qs.Id,
RowIndex: questionForm.RowIndex,
QuestionName: qs.QuestionName
}
})" />
</div>
</template> </template>
</el-form-item> </el-form-item>
</div> </div>
<div <div
v-if="isCurrentTask && readingTaskState<2 && (answers.SplitOrMergeType !== '1' && answers.SplitOrMergeType !== '3')" v-if="isCurrentTask && readingTaskState < 2 && (answers.SplitOrMergeType !== '1' && answers.SplitOrMergeType !== '3')"
class="base-dialog-footer" class="base-dialog-footer" style="text-align:right;margin-top:10px;">
style="text-align:right;margin-top:10px;"
>
<!-- 清除标记 --> <!-- 清除标记 -->
<el-button <el-button v-if="questionForm.MeasureData" size="mini" @click="handleDeleteMeasureData">
v-if="questionForm.MeasureData"
size="mini"
@click="handleDeleteMeasureData"
>
{{ $t('trials:reading:button:removeMark') }} {{ $t('trials:reading:button:removeMark') }}
</el-button> </el-button>
<!-- 删除 --> <!-- 删除 -->
<el-button <el-button v-if="isCurrentTaskAdd !== 'False'" size="mini" @click="handleDelete">
v-if="isCurrentTaskAdd !== 'False'"
size="mini"
@click="handleDelete"
>
{{ $t('common:button:delete') }} {{ $t('common:button:delete') }}
</el-button> </el-button>
<!-- 保存 --> <!-- 保存 -->
<el-button <el-button size="mini" @click="handleSave">
size="mini"
@click="handleSave"
>
{{ $t('common:button:save') }} {{ $t('common:button:save') }}
</el-button> </el-button>
</div> </div>
@ -368,6 +296,9 @@ export default {
// container.removeEventListener('scroll', this.scrollHandle , true) // container.removeEventListener('scroll', this.scrollHandle , true)
}, },
methods: { methods: {
handleReadingChart(e) {
this.$emit('handleReadingChart', e)
},
scrollHandle() { scrollHandle() {
for (const k in this.$refs) { for (const k in this.$refs) {
if (k.indexOf('select_') === -1) continue if (k.indexOf('select_') === -1) continue
@ -505,11 +436,11 @@ export default {
if ((ldi > 15 && ldi <= 20) && (pddIncrease >= 50) && (ldiIncrease >= 5 || sdiIncrease >= 5)) { if ((ldi > 15 && ldi <= 20) && (pddIncrease >= 50) && (ldiIncrease >= 5 || sdiIncrease >= 5)) {
this.stateDisabled = true this.stateDisabled = true
} else if ((ldi > 20) && (pddIncrease >= 50) && (ldiIncrease >= 10 || sdiIncrease >= 10)) { } else if ((ldi > 20) && (pddIncrease >= 50) && (ldiIncrease >= 10 || sdiIncrease >= 10)) {
/** /**
* 当前靶病灶LDi>20 mm * 当前靶病灶LDi>20 mm
* 相比最低点PPD增加百分比 50 * 相比最低点PPD增加百分比 50
* 相比PPD最低点LDi增加值 10 mm 或者 相比PPD最低点SDi增加值Sdi 10 mm * 相比PPD最低点LDi增加值 10 mm 或者 相比PPD最低点SDi增加值Sdi 10 mm
**/ **/
this.stateDisabled = true this.stateDisabled = true
} else { } else {
this.stateDisabled = false this.stateDisabled = false
@ -607,8 +538,8 @@ export default {
type: 'warning', type: 'warning',
distinguishCancelAndClose: true distinguishCancelAndClose: true
}) })
.then(() => {}) .then(() => { })
.catch(() => {}) .catch(() => { })
this.$set(this.questionForm, 'LesionType', this.originalQuestionForm.LesionType) this.$set(this.questionForm, 'LesionType', this.originalQuestionForm.LesionType)
return return
} }
@ -621,7 +552,7 @@ export default {
this.$confirm(msg, { this.$confirm(msg, {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
this.$set(this.questionForm, 'LesionType', this.originalQuestionForm.LesionType) this.$set(this.questionForm, 'LesionType', this.originalQuestionForm.LesionType)
return return
@ -653,7 +584,7 @@ export default {
}) })
}, },
deleteLesionInfo() { deleteLesionInfo() {
return new Promise(async(resolve, reject) => { return new Promise(async (resolve, reject) => {
const loading = this.$loading({ fullscreen: true }) const loading = this.$loading({ fullscreen: true })
var param = { var param = {
visitTaskId: this.visitTaskId, visitTaskId: this.visitTaskId,
@ -782,8 +713,8 @@ export default {
this.$set(this.questionForm, stateId, 0) this.$set(this.questionForm, stateId, 0)
} }
var lesionLength = this.getQuestionVal(0) var lesionLength = this.getQuestionVal(0)
// // && this.lesionType === 0
if (!(this.isCurrentTaskAdd === 'True') && this.lesionType === 0 && !this.isBaseLineTask && measureData.type === 'Bidirectional') { if (!(this.isCurrentTaskAdd === 'True') && !this.isBaseLineTask && measureData.type === 'Bidirectional') {
if (isLymphLesion) { if (isLymphLesion) {
// //
if (lesionLength > 15) { if (lesionLength > 15) {
@ -810,7 +741,7 @@ export default {
if (this.lesionType === 0) { if (this.lesionType === 0) {
this.calculatePPD() this.calculatePPD()
} }
var status = '' var status = ''
if (lesionState) { if (lesionState) {
if (this.lesionType === 0 && lesionState === 1) { if (this.lesionType === 0 && lesionState === 1) {
@ -965,31 +896,31 @@ export default {
this.stateDisabled = false this.stateDisabled = false
} }
} else { } else {
/** /**
* 15mm<当前靶病灶LDi20mm * 15mm<当前靶病灶LDi20mm
* 相比最低点PPD增加百分比 50 * 相比最低点PPD增加百分比 50
* 相比PPD最低点LDi增加值 5 mm 或者 相比PPD最低点SDi增加值5 mm * 相比PPD最低点LDi增加值 5 mm 或者 相比PPD最低点SDi增加值5 mm
**/ **/
if ((ldi > 15 && ldi <= 20) && (pddIncreaseNum >= 50) && (ldiIncrease >= 5 || sdiIncrease >= 5)) { if ((ldi > 15 && ldi <= 20) && (pddIncreaseNum >= 50) && (ldiIncrease >= 5 || sdiIncrease >= 5)) {
const stateId = this.getQuestionId(7) const stateId = this.getQuestionId(7)
this.$set(this.questionForm, stateId, 4) this.$set(this.questionForm, stateId, 4)
this.stateDisabled = true this.stateDisabled = true
} else if ((ldi > 20) && (pddIncreaseNum >= 50) && (ldiIncrease >= 10 || sdiIncrease >= 10)) { } else if ((ldi > 20) && (pddIncreaseNum >= 50) && (ldiIncrease >= 10 || sdiIncrease >= 10)) {
/** /**
* 当前靶病灶LDi>20 mm * 当前靶病灶LDi>20 mm
* 相比最低点PPD增加百分比 50 * 相比最低点PPD增加百分比 50
* 相比PPD最低点LDi增加值 10 mm 或者 相比PPD最低点SDi增加值Sdi 10 mm * 相比PPD最低点LDi增加值 10 mm 或者 相比PPD最低点SDi增加值Sdi 10 mm
**/ **/
const stateId = this.getQuestionId(7) const stateId = this.getQuestionId(7)
this.$set(this.questionForm, stateId, 4) this.$set(this.questionForm, stateId, 4)
this.stateDisabled = true this.stateDisabled = true
} else { } else {
// //
// const lesionState = !isNaN(parseInt(this.getQuestionVal(7))) ? parseInt(this.getQuestionVal(7)) : '' // const lesionState = !isNaN(parseInt(this.getQuestionVal(7))) ? parseInt(this.getQuestionVal(7)) : ''
// if (lesionState === 4) { // if (lesionState === 4) {
// const stateId = this.getQuestionId(7) // const stateId = this.getQuestionId(7)
// this.$set(this.questionForm, stateId, null) // this.$set(this.questionForm, stateId, null)
// } // }
this.stateDisabled = false this.stateDisabled = false
} }
} }
@ -1132,7 +1063,7 @@ export default {
this.$confirm(this.$t('trials:lugano:message:validState1'), { this.$confirm(this.$t('trials:lugano:message:validState1'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1143,7 +1074,7 @@ export default {
this.$confirm(this.$t('trials:lugano:message:validState2'), { this.$confirm(this.$t('trials:lugano:message:validState2'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1159,7 +1090,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg21'), { this.$confirm(this.$t('trials:reading:warnning:msg21'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1170,7 +1101,7 @@ export default {
this.$confirm(this.$t('trials:lugano:message:validState12'), { this.$confirm(this.$t('trials:lugano:message:validState12'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1187,7 +1118,7 @@ export default {
this.$confirm(this.$t('trials:lugano:message:validState3'), { this.$confirm(this.$t('trials:lugano:message:validState3'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1199,7 +1130,7 @@ export default {
this.$confirm(this.$t('trials:lugano:message:validState4'), { this.$confirm(this.$t('trials:lugano:message:validState4'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1215,7 +1146,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg25'), { this.$confirm(this.$t('trials:reading:warnning:msg25'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1234,7 +1165,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg26'), { this.$confirm(this.$t('trials:reading:warnning:msg26'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1258,7 +1189,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg27'), { this.$confirm(this.$t('trials:reading:warnning:msg27'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1270,7 +1201,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg28'), { this.$confirm(this.$t('trials:reading:warnning:msg28'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1281,13 +1212,13 @@ export default {
// 3 // 3
if (this.lesionType === 0 && lesionState === 3) { if (this.lesionType === 0 && lesionState === 3) {
if (lymphNodes === 1) { if (lymphNodes === 1) {
// 使 // 使 measureData.type === 'ArrowAnnotate' ||
if (!(measureData && (measureData.type === 'ArrowAnnotate' || measureData.type === 'Bidirectional'))) { if (!(measureData && (measureData.type === 'Bidirectional'))) {
// 使 // 使
this.$confirm(this.$t('trials:lugano:message:validState5'), { this.$confirm(this.$t('trials:lugano:message:validState5'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1296,7 +1227,7 @@ export default {
this.$confirm(this.$t('trials:lugano:message:validState6'), { this.$confirm(this.$t('trials:lugano:message:validState6'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1313,12 +1244,12 @@ export default {
// } // }
} else { } else {
// //
if (!(measureData && measureData.type === 'ArrowAnnotate')) { if (!(measureData && (measureData.type === 'ArrowAnnotate'))) {
// 使 // 使
this.$confirm(this.$t('trials:reading:warnning:msg30'), { this.$confirm(this.$t('trials:lugano:warnning:validState7'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1347,7 +1278,7 @@ export default {
this.$confirm(this.$t('trials:lugano:message:validState7'), { this.$confirm(this.$t('trials:lugano:message:validState7'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1359,7 +1290,7 @@ export default {
this.$confirm(this.$t('trials:lugano:message:validState8'), { this.$confirm(this.$t('trials:lugano:message:validState8'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1376,7 +1307,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg31'), { this.$confirm(this.$t('trials:reading:warnning:msg31'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1388,7 +1319,7 @@ export default {
this.$confirm(this.$t('trials:lugano:message:validState9'), { this.$confirm(this.$t('trials:lugano:message:validState9'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1405,7 +1336,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg33'), { this.$confirm(this.$t('trials:reading:warnning:msg33'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1417,7 +1348,7 @@ export default {
this.$confirm(this.$t('trials:lugano:message:validState10'), { this.$confirm(this.$t('trials:lugano:message:validState10'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1434,7 +1365,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg35'), { this.$confirm(this.$t('trials:reading:warnning:msg35'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1446,7 +1377,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg36'), { this.$confirm(this.$t('trials:reading:warnning:msg36'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1458,12 +1389,12 @@ export default {
if (this.lesionType === 1 && lesionState === 3) { if (this.lesionType === 1 && lesionState === 3) {
if (lymphNodes === 1) { if (lymphNodes === 1) {
// 使 // 使
if (!(measureData && (measureData.type === 'ArrowAnnotate'))) { if (!(measureData && (measureData.type === 'ArrowAnnotate' || (measureData.type === 'Bidirectional' && lesionLength < 15)))) {
// 使 // 使
this.$confirm(this.$t('trials:reading:warnning:msg37'), { this.$confirm(this.$t('trials:reading:warnning:lgmsg37'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1475,7 +1406,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg38'), { this.$confirm(this.$t('trials:reading:warnning:msg38'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1492,7 +1423,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg39'), { this.$confirm(this.$t('trials:reading:warnning:msg39'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1504,7 +1435,7 @@ export default {
this.$confirm(this.$t('trials:lugano:message:validState11'), { this.$confirm(this.$t('trials:lugano:message:validState11'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1550,7 +1481,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg43'), { this.$confirm(this.$t('trials:reading:warnning:msg43'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1562,7 +1493,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg44'), { this.$confirm(this.$t('trials:reading:warnning:msg44'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1574,12 +1505,12 @@ export default {
if (this.lesionType === 2 && lesionState === 3) { if (this.lesionType === 2 && lesionState === 3) {
if (lymphNodes === 1) { if (lymphNodes === 1) {
// 使 // 使
if (!(measureData && (measureData.type === 'ArrowAnnotate'))) { if (!(measureData && (measureData.type === 'ArrowAnnotate' || (measureData.type === 'Bidirectional' && lesionLength < 15)))) {
// 使 // 使
this.$confirm(this.$t('trials:reading:warnning:msg45'), { this.$confirm(this.$t('trials:reading:warnning:lgmsg45'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1591,7 +1522,7 @@ export default {
this.$confirm(this.$t('trials:reading:warnning:msg46'), { this.$confirm(this.$t('trials:reading:warnning:msg46'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -1837,51 +1768,62 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.measurement-form{ .measurement-form {
::v-deep .el-form-item__label{ ::v-deep .el-form-item__label {
color: #c3c3c3; color: #c3c3c3;
} }
::v-deep .el-input .el-input__inner{
::v-deep .el-input .el-input__inner {
background-color: transparent; background-color: transparent;
color: #ddd; color: #ddd;
border: 1px solid #5e5e5e; border: 1px solid #5e5e5e;
} }
::v-deep .el-form-item{
::v-deep .el-form-item {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: flex-start; justify-content: flex-start;
flex-wrap: wrap; flex-wrap: wrap;
} }
::v-deep .el-form-item__content{
::v-deep .el-form-item__content {
flex: 1; flex: 1;
} }
::v-deep .el-input.is-disabled .el-input__inner{
::v-deep .el-input.is-disabled .el-input__inner {
background-color: #646464a1; background-color: #646464a1;
} }
::v-deep .el-input-group__append, .el-input-group__prepend{
::v-deep .el-input-group__append,
.el-input-group__prepend {
padding: 0 10px; padding: 0 10px;
} }
::v-deep .el-select.is-disabled .el-input__inner{
::v-deep .el-select.is-disabled .el-input__inner {
background-color: #646464a1; background-color: #646464a1;
} }
::v-deep .el-button--mini, .el-button--mini.is-round {
::v-deep .el-button--mini,
.el-button--mini.is-round {
padding: 7px 10px; padding: 7px 10px;
} }
.el-form-item__content
.el-select{ .el-form-item__content .el-select {
width: 100%; width: 100%;
} }
.input-width1{
width: calc(100% - 60px)!important; .input-width1 {
width: calc(100% - 60px) !important;
} }
.input-width2{
.input-width2 {
width: 100% !important; width: 100% !important;
} }
.suv_viewer{
.suv_viewer {
::v-deep .viewer-play { ::v-deep .viewer-play {
display: none; display: none;
} }
} }
} }
</style> </style>

View File

@ -8,11 +8,9 @@
<span style="margin-left:5px;">{{ taskBlindName }}</span> <span style="margin-left:5px;">{{ taskBlindName }}</span>
</h3> </h3>
<div v-if="readingTaskState < 2"> <div v-if="readingTaskState < 2">
<el-tooltip class="item" effect="dark" :content="$t('trials:dicomReading:message:confirmReset')" placement="bottom"> <el-tooltip class="item" effect="dark" :content="$t('trials:dicomReading:message:confirmReset')"
<i placement="bottom">
class="el-icon-refresh-left" <i class="el-icon-refresh-left" @click="resetMeasuredData" />
@click="resetMeasuredData"
/>
</el-tooltip> </el-tooltip>
</div> </div>
</div> </div>
@ -25,121 +23,135 @@
:question-form-change-num="questionFormChangeNum" :question-form-change-num="questionFormChangeNum"
:group-classify="1" :group-classify="1"
/> --> /> -->
<Questions <Questions ref="ecrf" :question-form-change-state="true" :question-form-change-num="0" :is-qulity-issues="false"
ref="ecrf" :group-classify="1" @handleReadingChart="handleReadingChart" />
:question-form-change-state="true"
:question-form-change-num="0"
:is-qulity-issues="false"
:group-classify="1"
/>
</div> </div>
<!-- 测量问题 --> <!-- 测量问题 -->
<template v-if="questions.length > 0 && CriterionType !== 10"> <template v-if="questions.length > 0 && CriterionType !== 10">
<div v-for="(qs,index) in questions" :key="index" v-loading="loading" class="lesions lesions_wrapper"> <div v-for="(qs, index) in questions" :key="index" v-loading="loading" class="lesions lesions_wrapper">
<h4 v-if="qs.Type === 'group'" style="color: #ddd;padding: 5px 0px;margin: 0;"> <h4 v-if="qs.Type === 'group'" style="color: #ddd;padding: 5px 0px;margin: 0;">
{{ language==='en'?qs.GroupEnName:qs.GroupName }} {{ language === 'en' ? qs.GroupEnName : qs.GroupName }}
</h4> </h4>
<div class="lesion_list"> <div class="lesion_list">
<div v-for="item in qs.Childrens" v-show="!(isBaseLineTask && item.LesionType === 2)" :key="item.Id"> <div v-for="item in qs.Childrens" v-show="!(isBaseLineTask && item.LesionType === 2)" :key="item.Id">
<div v-if="item.Type === 'table'" class="flex-row" style="margin:3px 0;"> <div v-if="item.Type === 'table'" class="flex-row" style="margin:3px 0;">
<div class="title">{{ item.QuestionName }}</div> <div class="title">{{ item.QuestionName }}
<div v-if="readingTaskState<2 && (isBaseLineTask || item.LesionType === 2)" class="add-icon" @click.prevent="handleAdd(item)"> <svg-icon v-if="item.LesionType === 0" icon-class="readingChart"
class="svg-icon svg-readingChart-mini" @click.stop="(e) => handleReadingChart({
e,
data: {
ReportChartTypeEnum: 0,
QuestionName: item.QuestionName
},
})" />
</div>
<div v-if="readingTaskState < 2 && (isBaseLineTask || item.LesionType === 2)" class="add-icon"
@click.prevent="handleAdd(item)">
<i class="el-icon-plus" /> <i class="el-icon-plus" />
</div> </div>
</div> </div>
<!-- @change="handleCollapseChange(qs.Childrens,item)" --> <!-- @change="handleCollapseChange(qs.Childrens,item)" -->
<el-collapse <el-collapse v-if="item.Type === 'table' && item.TableQuestions" v-model="activeName" accordion
v-if="item.Type === 'table' && item.TableQuestions" @change="handleCollapseChange">
v-model="activeName" <el-collapse-item v-for="(q, i) in item.TableQuestions.Answers" :key="`${item.Id}_${q.RowIndex}`"
accordion
@change="handleCollapseChange"
>
<el-collapse-item
v-for="(q,i) in item.TableQuestions.Answers"
:key="`${item.Id}_${q.RowIndex}`"
:name="`${item.Id}_${q.RowIndex}`" :name="`${item.Id}_${q.RowIndex}`"
@contextmenu.prevent.native="collapseRightClick($event,q,item.Id,q.RowIndex)" @contextmenu.prevent.native="collapseRightClick($event, q, item.Id, q.RowIndex)">
>
<template slot="title"> <template slot="title">
<div style="width:300px;position: relative;" :style="{color:(activeName===item.Id+q.RowIndex?'#ffeb3b':'#fff')}"> <div style="width:300px;position: relative;"
:style="{ color: (activeName === item.Id + q.RowIndex ? '#ffeb3b' : '#fff') }">
{{ getLesionName(item.OrderMark,q.RowIndex) }} {{ getLesionName(item.OrderMark, q.RowIndex) }}
<!-- 未保存 --> <!-- 未保存 -->
<el-tooltip v-if="readingTaskState<2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) === 0" class="item" effect="dark" :content="$t('trials:reading:button:unsaved')" placement="bottom"> <el-tooltip
v-if="readingTaskState < 2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) === 0"
class="item" effect="dark" :content="$t('trials:reading:button:unsaved')" placement="bottom">
<i class="el-icon-warning" style="color:red" /> <i class="el-icon-warning" style="color:red" />
</el-tooltip> </el-tooltip>
<!-- 信息不完整 --> <!-- 信息不完整 -->
<el-tooltip v-if="readingTaskState<2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) ===1" class="item" effect="dark" :content="$t('trials:reading:button:incompleteInfor')" placement="bottom"> <el-tooltip
v-if="readingTaskState < 2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) === 1"
class="item" effect="dark" :content="$t('trials:reading:button:incompleteInfor')"
placement="bottom">
<i class="el-icon-warning" style="color:#ff9800" /> <i class="el-icon-warning" style="color:#ff9800" />
</el-tooltip> </el-tooltip>
<div :style="{position: 'absolute',left: item.LesionType === 1 && readingTaskState < 2?'58px':'50px',top: '2px'}"> <div
:style="{ position: 'absolute', left: item.LesionType === 1 && readingTaskState < 2 ? '58px' : '50px', top: '2px' }">
<!-- white-space: nowrap;overflow: hidden;text-overflow: ellipsis; --> <!-- white-space: nowrap;overflow: hidden;text-overflow: ellipsis; -->
<div style="font-size: 11px;width:210px;height: 30px;display: flex;justify-content: flex-start;flex-wrap: nowrap;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;"> <div
<el-tooltip v-if="item.TableQuestions.Answers[i].SplitOrMergeType === '1' || item.TableQuestions.Answers[i].SplitOrMergeType === '3'" class="item" effect="dark" :content="`${$t('trials:reading:message:fused')}${item.TableQuestions.Answers[i].SplitOrMergeLesionName}`" placement="bottom"> style="font-size: 11px;width:210px;height: 30px;display: flex;justify-content: flex-start;flex-wrap: nowrap;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;">
<div v-if="item.TableQuestions.Answers[i].SplitOrMergeType === '1' || item.TableQuestions.Answers[i].SplitOrMergeType === '3'"> <el-tooltip
<span class="login-cycle" /> v-if="item.TableQuestions.Answers[i].SplitOrMergeType === '1' || item.TableQuestions.Answers[i].SplitOrMergeType === '3'"
class="item" effect="dark"
:content="`${$t('trials:reading:message:fused')}${item.TableQuestions.Answers[i].SplitOrMergeLesionName}`"
placement="bottom">
<div
v-if="item.TableQuestions.Answers[i].SplitOrMergeType === '1' || item.TableQuestions.Answers[i].SplitOrMergeType === '3'">
<span class="login-cycle"
:style="`background-color:${$GuidToColor(item.TableQuestions.Answers[i].MergeRowId)}`" />
</div> </div>
</el-tooltip> </el-tooltip>
<div v-if="item.TableQuestions.Answers[i].SplitOrMergeType === '4'"> <div v-if="item.TableQuestions.Answers[i].SplitOrMergeType === '4'">
<span class="login-cycle" /> <span class="login-cycle"
:style="`background-color:${$GuidToColor(item.TableQuestions.Answers[i].RowId)}`" />
</div> </div>
<el-tooltip v-if="!!item.TableQuestions.Answers[i].lesionPart" class="item" effect="dark" :content="item.TableQuestions.Answers[i].lesionPart" placement="bottom"> <el-tooltip v-if="!!item.TableQuestions.Answers[i].lesionPart" class="item" effect="dark"
<div v-if="item.TableQuestions.Answers[i].lesionPart" style="max-width: 100px;overflow: hidden;"> :content="item.TableQuestions.Answers[i].lesionPart" placement="bottom">
<div v-if="item.TableQuestions.Answers[i].lesionPart"
style="max-width: 100px;overflow: hidden;">
{{ item.TableQuestions.Answers[i].lesionPart }} {{ item.TableQuestions.Answers[i].lesionPart }}
</div> </div>
</el-tooltip> </el-tooltip>
<div v-if="item.LesionType === 0" style="margin:0 5px;"> <div v-if="item.LesionType === 0" style="margin:0 5px;">
{{ $fd('TargetState',parseInt(item.TableQuestions.Answers[i].lesionState)) }} {{ $fd('TargetState', parseInt(item.TableQuestions.Answers[i].lesionState)) }}
</div> </div>
<div v-else-if="item.LesionType === 1" style="margin:0 5px;"> <div v-else-if="item.LesionType === 1" style="margin:0 5px;">
{{ $fd('NoTargetState',parseInt(item.TableQuestions.Answers[i].lesionState)) }} {{ $fd('NoTargetState', parseInt(item.TableQuestions.Answers[i].lesionState)) }}
</div> </div>
<div v-else style="margin:0 5px;"> <div v-else style="margin:0 5px;">
{{ $fd('NewLesionState',parseInt(item.TableQuestions.Answers[i].lesionState)) }} {{ $fd('NewLesionState', parseInt(item.TableQuestions.Answers[i].lesionState)) }}
</div> </div>
<div v-if="!isNaN(parseInt(item.TableQuestions.Answers[i].lesionLength))"> <div v-if="!isNaN(parseInt(item.TableQuestions.Answers[i].lesionLength))">
<el-tooltip class="item" effect="dark" :content="`${item.TableQuestions.Answers[i].lesionLength}*${item.TableQuestions.Answers[i].lesionShort}m㎡`" placement="bottom"> <el-tooltip class="item" effect="dark"
<span>{{ item.TableQuestions.Answers[i].lesionLength }}*{{ item.TableQuestions.Answers[i].lesionShort }}m</span> :content="`${item.TableQuestions.Answers[i].lesionLength}*${item.TableQuestions.Answers[i].lesionShort}m㎡`"
placement="bottom">
<span>{{ item.TableQuestions.Answers[i].lesionLength }}*{{
item.TableQuestions.Answers[i].lesionShort }}m</span>
</el-tooltip> </el-tooltip>
</div> </div>
</div> </div>
</div> </div>
<div v-if="item.TableQuestions.Answers[i].IsCurrentTaskAdd === 'False' && readingTaskState < 2" style="position: absolute;right: 5px;top: 2px;"> <div v-if="item.TableQuestions.Answers[i].IsCurrentTaskAdd === 'False' && readingTaskState < 2"
style="position: absolute;right: 5px;top: 2px;">
<!-- 分裂 --> <!-- 分裂 -->
<el-tooltip v-show="!!item.TableQuestions.Answers[i].RowId && item.TableQuestions.Answers[i].SplitOrMergeType !== '4' && ((item.LesionType === 0 && [0,4].includes(parseInt(item.TableQuestions.Answers[i].lesionState))) || (item.LesionType === 1 && [0,1].includes(parseInt(item.TableQuestions.Answers[i].lesionState))) || (item.LesionType === 2 && parseInt(item.TableQuestions.Answers[i].lesionState) === 0))" class="item" :content="$t('trials:reading:button:split')" placement="bottom"> <el-tooltip
<i class="iconfont icon-24gl-split" style="color:#fff;font-size: 16px;" @click.stop="handleSplit(item.TableQuestions.Answers[i].RowId,item.Id)" /> v-show="!!item.TableQuestions.Answers[i].RowId && item.TableQuestions.Answers[i].SplitOrMergeType !== '4' && ((item.LesionType === 0 && [0, 4].includes(parseInt(item.TableQuestions.Answers[i].lesionState))) || (item.LesionType === 1 && [0, 1].includes(parseInt(item.TableQuestions.Answers[i].lesionState))) || (item.LesionType === 2 && parseInt(item.TableQuestions.Answers[i].lesionState) === 0))"
class="item" :content="$t('trials:reading:button:split')" placement="bottom">
<i class="iconfont icon-24gl-split" style="color:#fff;font-size: 16px;"
@click.stop="handleSplit(item.TableQuestions.Answers[i].RowId, item.Id)" />
</el-tooltip> </el-tooltip>
<!-- 融合 --> <!-- 融合 -->
<el-tooltip v-show="!!item.TableQuestions.Answers[i].RowId && item.TableQuestions.Answers[i].SplitOrMergeType !== '2' && ((item.LesionType === 0 && [0,1,4].includes(parseInt(item.TableQuestions.Answers[i].lesionState))))" class="item" :content="$t('trials:reading:button:merge')" placement="bottom"> <el-tooltip
<i class="iconfont icon-24gl-merge" style="color:#fff;font-size: 16px;" @click.stop="handleMerge(item.TableQuestions.Answers[i],item.Id,item.OrderMark)" /> v-show="!!item.TableQuestions.Answers[i].RowId && item.TableQuestions.Answers[i].SplitOrMergeType !== '2' && ((item.LesionType === 0 && [0, 1, 4].includes(parseInt(item.TableQuestions.Answers[i].lesionState))))"
class="item" :content="$t('trials:reading:button:merge')" placement="bottom">
<i class="iconfont icon-24gl-merge" style="color:#fff;font-size: 16px;"
@click.stop="handleMerge(item.TableQuestions.Answers[i], item.Id, item.OrderMark)" />
</el-tooltip> </el-tooltip>
</div> </div>
</div> </div>
</template> </template>
<QuestionForm <QuestionForm :ref="`${item.Id}_${q.RowIndex}`" :questions="item.TableQuestions.Questions"
:ref="`${item.Id}_${q.RowIndex}`" :answers="item.TableQuestions.Answers[i]" :lesion-type="item.LesionType"
:questions="item.TableQuestions.Questions" :order-mark="item.OrderMark" :table-questions="tableQuestions" :row-index="String(q.RowIndex)"
:answers="item.TableQuestions.Answers[i]" :question-name="item.QuestionName" :parent-qs-id="item.Id" :visit-task-id="visitTaskId"
:lesion-type="item.LesionType" :is-current-task="isCurrentTask" :reading-task-state="readingTaskState"
:order-mark="item.OrderMark" :is-base-line-task="isBaseLineTask" @getReadingQuestionAndAnswer="getReadingQuestionAndAnswer"
:table-questions="tableQuestions" @determineExistsUnsavedLession="determineExistsUnsavedLession" @resetQuestions="resetQuestions"
:row-index="String(q.RowIndex)" @close="close" @handleReadingChart="handleReadingChart" />
:question-name="item.QuestionName"
:parent-qs-id="item.Id"
:visit-task-id="visitTaskId"
:is-current-task="isCurrentTask"
:reading-task-state="readingTaskState"
:is-base-line-task="isBaseLineTask"
@getReadingQuestionAndAnswer="getReadingQuestionAndAnswer"
@determineExistsUnsavedLession="determineExistsUnsavedLession"
@resetQuestions="resetQuestions"
@close="close"
/>
</el-collapse-item> </el-collapse-item>
</el-collapse> </el-collapse>
@ -149,35 +161,15 @@
</template> </template>
<!-- <el-divider /> --> <!-- <el-divider /> -->
<!-- 肝脏评估 --> <!-- 肝脏评估 -->
<Questions <Questions ref="ecrf2" :question-form-change-state="true" :question-form-change-num="0" :group-classify="2"
ref="ecrf2" :is-qulity-issues="false" style="margin-top:20px" :question-type="6"
:question-form-change-state="true" @setNonTargetMeasurementStatus="setNonTargetMeasurementStatus" />
:question-form-change-num="0"
:group-classify="2"
:is-qulity-issues="false"
style="margin-top:20px"
:question-type="6"
@setNonTargetMeasurementStatus="setNonTargetMeasurementStatus"
/>
<!-- 脾脏评估 --> <!-- 脾脏评估 -->
<Questions <Questions ref="ecrf3" :question-form-change-state="true" :question-form-change-num="0" :group-classify="3"
ref="ecrf3" :is-qulity-issues="false" :question-type="7" @setNonTargetMeasurementStatus="setNonTargetMeasurementStatus" />
:question-form-change-state="true"
:question-form-change-num="0"
:group-classify="3"
:is-qulity-issues="false"
:question-type="7"
@setNonTargetMeasurementStatus="setNonTargetMeasurementStatus"
/>
</div> </div>
<el-dialog <el-dialog v-if="merge.visible" v-loading="merge.loading" :visible.sync="merge.visible"
v-if="merge.visible" :close-on-click-modal="false" :title="$t('trials:reading:lugano:message:merge')" width="500px">
v-loading="merge.loading"
:visible.sync="merge.visible"
:close-on-click-modal="false"
:title="$t('trials:reading:lugano:message:merge')"
width="500px"
>
<div class="merge-table"> <div class="merge-table">
<div class="merge-label"> <div class="merge-label">
<label>{{ $t('trials:reading:lugano:label:currentLesion') }}</label> <label>{{ $t('trials:reading:lugano:label:currentLesion') }}</label>
@ -185,40 +177,19 @@
<span style="margin-left:10px">{{ mergeInfo.lesionPart }}</span> <span style="margin-left:10px">{{ mergeInfo.lesionPart }}</span>
</div> </div>
<div class="merge-label"><label>{{ $t('trials:reading:lugano:label:selectLesion') }}</label></div> <div class="merge-label"><label>{{ $t('trials:reading:lugano:label:selectLesion') }}</label></div>
<el-table <el-table :data="lesionData" style="width: 450px" size="small" height="200"
:data="lesionData" @selection-change="handleSelectionChange">
style="width: 450px" <el-table-column type="selection" width="45" />
size="small" <el-table-column prop="OrderMarkName" :label="$t('trials:reading:lugano:label:lesionNumber')" width="100" />
height="200" <el-table-column prop="Part" :label="$t('trials:reading:lugano:label:lesionLocation')" min-width="120"
@selection-change="handleSelectionChange" show-overflow-tooltip />
>
<el-table-column
type="selection"
width="45"
/>
<el-table-column
prop="OrderMarkName"
:label="$t('trials:reading:lugano:label:lesionNumber')"
width="100"
/>
<el-table-column
prop="Part"
:label="$t('trials:reading:lugano:label:lesionLocation')"
min-width="120"
show-overflow-tooltip
/>
</el-table> </el-table>
</div> </div>
<div slot="footer" style="text-align:right;"> <div slot="footer" style="text-align:right;">
<!-- 取消 --> <!-- 取消 -->
<el-button size="mini" @click="merge.visible = false">{{ $t('common:button:cancel') }}</el-button> <el-button size="mini" @click="merge.visible = false">{{ $t('common:button:cancel') }}</el-button>
<!-- 确认 --> <!-- 确认 -->
<el-button <el-button type="primary" size="mini" :disabled="mergeList.length === 0" @click="confirmMerge">
type="primary"
size="mini"
:disabled="mergeList.length === 0"
@click="confirmMerge"
>
{{ $t('common:button:confirm') }}</el-button> {{ $t('common:button:confirm') }}</el-button>
</div> </div>
</el-dialog> </el-dialog>
@ -333,7 +304,7 @@ export default {
DicomEvent.$on('split', measureData => { DicomEvent.$on('split', measureData => {
this.handleSplit(measureData.RowId, measureData.QuestionId) this.handleSplit(measureData.RowId, measureData.QuestionId)
}) })
DicomEvent.$on('refreshQuestions', async(obj) => { DicomEvent.$on('refreshQuestions', async (obj) => {
var triald = this.$router.currentRoute.query.trialId var triald = this.$router.currentRoute.query.trialId
await store.dispatch('reading/refreshDicomReadingQuestionAnswer', { trialId: triald, visitTaskId: this.visitTaskId }) await store.dispatch('reading/refreshDicomReadingQuestionAnswer', { trialId: triald, visitTaskId: this.visitTaskId })
this.$nextTick(() => { this.$nextTick(() => {
@ -342,7 +313,7 @@ export default {
this.$refs['ecrf3'].getQuestions(this.visitTaskId) this.$refs['ecrf3'].getQuestions(this.visitTaskId)
}) })
}) })
DicomEvent.$on('refreshSplitTargetLesionPDD', async(callback) => { DicomEvent.$on('refreshSplitTargetLesionPDD', async (callback) => {
const res = await getSplitPPdSum({ visitTaskId: this.visitTaskId }) const res = await getSplitPPdSum({ visitTaskId: this.visitTaskId })
this.splitTargetLesions = res.Result this.splitTargetLesions = res.Result
if (this.splitTargetLesions && this.splitTargetLesions.length > 0) { if (this.splitTargetLesions && this.splitTargetLesions.length > 0) {
@ -366,6 +337,9 @@ export default {
DicomEvent.$off('refreshQuestions') DicomEvent.$off('refreshQuestions')
}, },
methods: { methods: {
handleReadingChart(e) {
this.$emit('handleReadingChart', e)
},
async initList() { async initList() {
var i = this.visitTaskList.findIndex(i => i.VisitTaskId === this.lastCanvasTaskId) var i = this.visitTaskList.findIndex(i => i.VisitTaskId === this.lastCanvasTaskId)
if (i > -1) { if (i > -1) {
@ -529,7 +503,7 @@ export default {
try { try {
const loading = this.$loading({ fullscreen: true }) const loading = this.$loading({ fullscreen: true })
await store.dispatch('reading/refreshReadingQuestionAndAnswer', { trialId: this.$router.currentRoute.query.trialId, visitTaskId: this.visitTaskId }).then(async() => { await store.dispatch('reading/refreshReadingQuestionAndAnswer', { trialId: this.$router.currentRoute.query.trialId, visitTaskId: this.visitTaskId }).then(async () => {
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId) var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
if (idx > -1) { if (idx > -1) {
if (this.visitTaskList[idx].ReadingQuestions.length > 0) { if (this.visitTaskList[idx].ReadingQuestions.length > 0) {
@ -561,7 +535,7 @@ export default {
}) })
}) })
}) })
}) })
await store.dispatch('reading/refreshMeasuredData', this.visitTaskId) await store.dispatch('reading/refreshMeasuredData', this.visitTaskId)
DicomEvent.$emit('getMeasureData') DicomEvent.$emit('getMeasureData')
await store.dispatch('reading/refreshDicomReadingQuestionAnswer', { trialId: this.$route.query.trialId, visitTaskId: this.visitTaskId }) await store.dispatch('reading/refreshDicomReadingQuestionAnswer', { trialId: this.$route.query.trialId, visitTaskId: this.visitTaskId })
@ -655,7 +629,7 @@ export default {
.then(() => { .then(() => {
this.split(rowId, questionId) this.split(rowId, questionId)
}) })
.catch(() => {}) .catch(() => { })
} else { } else {
// //
this.$confirm(this.$t('trials:reading:warnning:msg4'), { this.$confirm(this.$t('trials:reading:warnning:msg4'), {
@ -665,7 +639,7 @@ export default {
.then(() => { .then(() => {
this.split(rowId, questionId) this.split(rowId, questionId)
}) })
.catch(() => {}) .catch(() => { })
} }
} }
} }
@ -722,7 +696,7 @@ export default {
}) })
}, },
confirmMerge() { confirmMerge() {
// ', ?' // ', ?'
this.$confirm(this.$t('trials:reading:lugano:warnning:fuse'), { this.$confirm(this.$t('trials:reading:lugano:warnning:fuse'), {
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
@ -875,7 +849,7 @@ export default {
this.$confirm(msg, { this.$confirm(msg, {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
return return
} }
@ -886,7 +860,7 @@ export default {
this.$confirm(msg, { this.$confirm(msg, {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
} else { } else {
// saveTypeEnum: 0 // saveTypeEnum: 0
@ -1026,7 +1000,7 @@ export default {
async changeLesionType(questionsObj) { async changeLesionType(questionsObj) {
await store.dispatch('reading/removeReadingQuestionAndAnswer', { lesionType: questionsObj.oldLesionType, rowIndex: questionsObj.rowIndex, visitTaskId: this.visitTaskId }) await store.dispatch('reading/removeReadingQuestionAndAnswer', { lesionType: questionsObj.oldLesionType, rowIndex: questionsObj.rowIndex, visitTaskId: this.visitTaskId })
// saveTypeEnum: 0 // saveTypeEnum: 0
var lesionObj = { } var lesionObj = {}
var questionObj = questionsObj.questionForm var questionObj = questionsObj.questionForm
// //
var targetObj = this.tableQuestions.find(item => item.LesionType === questionsObj.newLesionType) var targetObj = this.tableQuestions.find(item => item.LesionType === questionsObj.newLesionType)
@ -1343,21 +1317,25 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.measurement-wrapper{ .measurement-wrapper {
height: 100%; height: 100%;
overflow-y: auto; overflow-y: auto;
.container{
.container {
padding: 10px; padding: 10px;
.basic-info{
.basic-info {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
h3{
h3 {
color: #ddd; color: #ddd;
padding: 5px 0px; padding: 5px 0px;
margin: 0; margin: 0;
} }
i{
i {
color: #fff; color: #fff;
font-size: 22px; font-size: 22px;
font-weight: bold; font-weight: bold;
@ -1365,14 +1343,16 @@ export default {
} }
} }
} }
.title{
.title {
padding: 5px; padding: 5px;
font-weight: bold; font-weight: bold;
color: #ddd; color: #ddd;
font-size: 15px; font-size: 15px;
} }
.add-icon{
.add-icon {
padding: 5px; padding: 5px;
font-weight: bold; font-weight: bold;
color: #ddd; color: #ddd;
@ -1381,21 +1361,24 @@ export default {
margin-bottom: 2px; margin-bottom: 2px;
cursor: pointer; cursor: pointer;
} }
.add-icon:hover{
.add-icon:hover {
background-color: #607d8b; background-color: #607d8b;
} }
.flex-row{ .flex-row {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
background-color: #424242; background-color: #424242;
} }
.lesion_list{
.lesion_list {
position: relative; position: relative;
} }
.login-cycle{
.login-cycle {
width: 5px; width: 5px;
height: 5px; height: 5px;
display: inline-block; display: inline-block;
@ -1404,28 +1387,33 @@ export default {
margin-right: 2px; margin-right: 2px;
margin-bottom: 2px; margin-bottom: 2px;
} }
.el-collapse{
border-bottom:none; .el-collapse {
border-top:none; border-bottom: none;
::v-deep .el-collapse-item{ border-top: none;
background-color: #000!important;
::v-deep .el-collapse-item {
background-color: #000 !important;
color: #ddd; color: #ddd;
} }
::v-deep .el-collapse-item__header{
background-color: #000!important; ::v-deep .el-collapse-item__header {
background-color: #000 !important;
color: #ddd; color: #ddd;
border-bottom-color:#5a5a5a; border-bottom-color: #5a5a5a;
padding-left: 5px; padding-left: 5px;
height: 35px; height: 35px;
line-height: 35px; line-height: 35px;
} }
::v-deep .el-collapse-item__wrap{
background-color: #000!important; ::v-deep .el-collapse-item__wrap {
background-color: #000 !important;
color: #ddd; color: #ddd;
} }
::v-deep .el-collapse-item__content{
width:260px; ::v-deep .el-collapse-item__content {
width: 260px;
position: absolute; position: absolute;
top: 0px; top: 0px;
right: 0px; right: 0px;
@ -1434,46 +1422,59 @@ export default {
z-index: 1; z-index: 1;
color: #ddd; color: #ddd;
padding: 5px; padding: 5px;
background-color:#1e1e1e; background-color: #1e1e1e;
} }
} }
.merge-table{
padding:0 10px; .merge-table {
::v-deep.el-table{ padding: 0 10px;
background-color: #1e1e1e !important;
::v-deep.el-table {
background-color: #1e1e1e !important;
color: #383838; color: #383838;
} }
::v-deep.el-table td.el-table__cell, .el-table th.el-table__cell.is-leaf{
::v-deep.el-table td.el-table__cell,
.el-table th.el-table__cell.is-leaf {
border-bottom: 1px solid #383838; border-bottom: 1px solid #383838;
} }
.el-table--border::after, .el-table--group::after, .el-table::before{
.el-table--border::after,
.el-table--group::after,
.el-table::before {
background-color: #1e1e1e; background-color: #1e1e1e;
} }
::v-deep.el-table__header-wrapper{
th{ ::v-deep.el-table__header-wrapper {
background-color: #1e1e1e !important; th {
color: #dfdfdf; background-color: #1e1e1e !important;
border-bottom: 1px solid #383838; color: #dfdfdf;
} border-bottom: 1px solid #383838;
} }
::v-deep.el-table__body-wrapper{ }
tr{
background-color: #1e1e1e !important; ::v-deep.el-table__body-wrapper {
tr {
background-color: #1e1e1e !important;
color: #dfdfdf; color: #dfdfdf;
} }
tr:hover > td{
background-color: #1e1e1e !important; tr:hover>td {
background-color: #1e1e1e !important;
} }
} }
::v-deep.el-table__empty-block{
background-color: #1e1e1e !important; ::v-deep.el-table__empty-block {
background-color: #1e1e1e !important;
} }
.merge-label{
color:#ddd; .merge-label {
color: #ddd;
font-size: 13px; font-size: 13px;
margin-bottom: 10px; margin-bottom: 10px;
span{
span {
font-size: 15px; font-size: 15px;
color: red; color: red;
} }

View File

@ -1,12 +1,6 @@
<template> <template>
<el-form <el-form v-if="isRender" ref="measurementForm" v-loading="loading" :model="questionForm" size="mini"
v-if="isRender" class="measurement-form">
ref="measurementForm"
v-loading="loading"
:model="questionForm"
size="mini"
class="measurement-form"
>
<div class="base-dialog-body"> <div class="base-dialog-body">
<div style="display: flex;justify-content: space-between;"> <div style="display: flex;justify-content: space-between;">
<h3 v-if="questionName" style="color: #ddd;padding: 5px 0px;margin: 0;"> <h3 v-if="questionName" style="color: #ddd;padding: 5px 0px;margin: 0;">
@ -18,183 +12,134 @@
</div> </div>
</div> </div>
<el-form-item <el-form-item v-for="qs in questions" v-show="qs.ShowQuestion !== 2" :key="qs.Id" :label="`${qs.QuestionName}`"
v-for="qs in questions" :prop="qs.Id" :rules="[
v-show="qs.ShowQuestion!==2" {
:key="qs.Id" required: (qs.IsRequired === 0 || (qs.IsRequired === 1 && qs.RelevanceId && (String(questionForm[qs.RelevanceId]) === qs.RelevanceValue)) || (qs.QuestionMark === 6 && questionForm.IsCanEditPosition === true) || (questionForm.IsCanEditPosition && qs.QuestionMark === 10)) && qs.Type !== 'group' && qs.Type !== 'summary',
:label="`${qs.QuestionName}`" message: ['radio', 'select', 'checkbox'].includes(qs.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']
:prop="qs.Id" },
:rules="[ ]" style="flex-wrap: wrap">
{ required: (qs.IsRequired === 0 || (qs.IsRequired ===1 && qs.RelevanceId && (String(questionForm[qs.RelevanceId]) === qs.RelevanceValue)) || (qs.QuestionMark === 6 && questionForm.IsCanEditPosition === true) || (questionForm.IsCanEditPosition && qs.QuestionMark === 10)) && qs.Type!=='group' && qs.Type!=='summary',
message:['radio', 'select', 'checkbox'].includes(qs.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur','change']},
]"
style="flex-wrap: wrap"
>
<!-- 输入框 --> <!-- 输入框 -->
<template v-if="(qs.Type==='input' || qs.Type==='number') && (qs.QuestionMark === 1101 || qs.QuestionMark === 1102 || qs.QuestionMark === 1103)"> <template
v-if="(qs.Type === 'input' || qs.Type === 'number') && (qs.QuestionMark === 1101 || qs.QuestionMark === 1102 || qs.QuestionMark === 1103)">
<div style="display: flex;flex-direction: row;justify-content: flex-start;align-items: center;"> <div style="display: flex;flex-direction: row;justify-content: flex-start;align-items: center;">
<el-input <el-input v-model="questionForm[qs.Id]" disabled style="width: 100px;">
v-model="questionForm[qs.Id]"
disabled
style="width: 100px;"
>
<template v-if="qs.Unit" slot="append"> <template v-if="qs.Unit" slot="append">
{{ $fd('ValueUnit', parseInt(qs.Unit)) }} {{ $fd('ValueUnit', parseInt(qs.Unit)) }}
</template> </template>
</el-input> </el-input>
<!-- 测量 --> <!-- 测量 -->
<el-button <el-button
v-if="questionForm[isMeasurableId] && parseInt(questionForm[isMeasurableId]) === 1 && !questionForm[qs.Id] && readingTaskState!== 2" v-if="questionForm[isMeasurableId] && parseInt(questionForm[isMeasurableId]) === 1 && !questionForm[qs.Id] && readingTaskState !== 2"
size="mini" size="mini" type="text" @click="addAnnotation(qs)">
type="text"
@click="addAnnotation(qs)"
>
{{ $t('trials:MRIPDFF:button:measure') }} {{ $t('trials:MRIPDFF:button:measure') }}
</el-button> </el-button>
<!-- 清除标记 --> <!-- 清除标记 -->
<el-button <el-button v-if="getAnnotationStatus(qs) && readingTaskState !== 2" size="mini" type="text"
v-if="getAnnotationStatus(qs) && readingTaskState!== 2" style="margin-left: 0px" @click="removeAnnotation(qs)">
size="mini"
type="text"
style="margin-left: 0px"
@click="removeAnnotation(qs)"
>
{{ $t('trials:MRIPDFF:button:clear') }} {{ $t('trials:MRIPDFF:button:clear') }}
</el-button> </el-button>
<!-- 返回 --> <!-- 返回 -->
<el-button <el-button v-if="questionForm[qs.Id]" size="mini" type="text" style="margin-left: 0px"
v-if="questionForm[qs.Id]" @click="locateAnnotation(qs)">
size="mini"
type="text"
style="margin-left: 0px"
@click="locateAnnotation(qs)"
>
{{ $t('trials:MRIPDFF:button:return') }} {{ $t('trials:MRIPDFF:button:return') }}
</el-button> </el-button>
<!-- 保存 --> <!-- 保存 -->
<el-button <el-button
v-if="questionForm[isMeasurableId] && parseInt(questionForm[isMeasurableId]) === 1 && questionForm[qs.Id] && readingTaskState!== 2" v-if="questionForm[isMeasurableId] && parseInt(questionForm[isMeasurableId]) === 1 && questionForm[qs.Id] && readingTaskState !== 2"
size="mini" size="mini" type="text" style="margin-left: 0px" @click="saveAnnotation(qs)">
type="text"
style="margin-left: 0px"
@click="saveAnnotation(qs)"
>
<!-- 未保存 --> <!-- 未保存 -->
<el-tooltip v-if="getAnnotationSaveEnum(qs) === 0" class="item" effect="dark" :content="$t('trials:reading:button:unsaved')" placement="bottom"> <el-tooltip v-if="getAnnotationSaveEnum(qs) === 0" class="item" effect="dark"
:content="$t('trials:reading:button:unsaved')" placement="bottom">
<i class="el-icon-warning" style="color:red" /> <i class="el-icon-warning" style="color:red" />
</el-tooltip> </el-tooltip>
{{ $t('common:button:save') }} {{ $t('common:button:save') }}
</el-button> </el-button>
</div> </div>
</template> </template>
<template v-else-if="qs.Type==='input' || qs.Type==='number'"> <template v-else-if="qs.Type === 'input' || qs.Type === 'number'">
<el-input <div style="display: flex;justify-content: space-between;">
v-model="questionForm[qs.Id]" <el-input v-model="questionForm[qs.Id]" :disabled="!isCurrentTask || readingTaskState >= 2"
:disabled="!isCurrentTask || readingTaskState>=2" @change="((val) => { formItemChange(val, qs) })">
@change="((val)=>{formItemChange(val, qs)})" <template v-if="(qs.QuestionMark === 0 || qs.QuestionMark === 1) && qs.Unit" slot="append">
> {{ $fd('ValueUnit', parseInt(qs.Unit)) }}
<template v-if="(qs.QuestionMark===0 || qs.QuestionMark===1) && qs.Unit" slot="append"> </template>
{{ $fd('ValueUnit', parseInt(qs.Unit)) }} </el-input>
</template> <svg-icon v-if="qs.ShowChartTypeEnum > 0" icon-class="readingChart" class="svg-icon svg-readingChart"
</el-input> @click.stop="(e) => handleReadingChart({
e,
data: {
TableQuestionId: qs.Id,
RowIndex: questionForm.RowIndex,
QuestionName: qs.QuestionName
}
})" />
</div>
</template> </template>
<!-- 多行文本输入框 --> <!-- 多行文本输入框 -->
<el-input <el-input v-else-if="qs.Type === 'textarea'" v-model="questionForm[qs.Id]" type="textarea"
v-else-if="qs.Type==='textarea'" :autosize="{ minRows: 2, maxRows: 4 }" :disabled="!isCurrentTask || readingTaskState >= 2"
v-model="questionForm[qs.Id]" @change="((val) => { formItemChange(val, qs) })" />
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
:disabled="!isCurrentTask || readingTaskState>=2"
@change="((val)=>{formItemChange(val, qs)})"
/>
<!-- 下拉框 --> <!-- 下拉框 -->
<el-select <el-select v-else-if="qs.Type === 'select'" v-model="questionForm[qs.Id]" filterable
v-else-if="qs.Type==='select'"
v-model="questionForm[qs.Id]"
filterable
:placeholder="$t('common:placeholder:select')" :placeholder="$t('common:placeholder:select')"
:disabled="!isCurrentTask || readingTaskState>=2 || qs.QuestionMark === 1106" :disabled="!isCurrentTask || readingTaskState >= 2 || qs.QuestionMark === 1106"
@change="((val)=>{formItemChange(val, qs)})" @change="((val) => { formItemChange(val, qs) })">
>
<template v-if="qs.TableQuestionType === 1"> <template v-if="qs.TableQuestionType === 1">
<el-option <el-option v-for="item in organList" :key="item.Id" :label="item[qs.DataTableColumn]"
v-for="item in organList" :value="item[qs.DataTableColumn]" />
:key="item.Id"
:label="item[qs.DataTableColumn]"
:value="item[qs.DataTableColumn]"
/>
</template> </template>
<template v-else-if="qs.DictionaryCode"> <template v-else-if="qs.DictionaryCode">
<el-option <el-option v-for="item of $d[qs.DictionaryCode]" :key="item.id" :value="item.value" :label="item.label" />
v-for="item of $d[qs.DictionaryCode]"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template> </template>
<template v-else> <template v-else>
<el-option <el-option v-for="val in qs.TypeValue.split('|')" :key="val" :label="val" :value="val" />
v-for="val in qs.TypeValue.split('|')"
:key="val"
:label="val"
:value="val"
/>
</template> </template>
</el-select> </el-select>
<!-- 单选 --> <!-- 单选 -->
<el-radio-group <el-radio-group v-else-if="qs.Type === 'radio'" v-model="questionForm[qs.Id]"
v-else-if="qs.Type==='radio'" :disabled="!isCurrentTask || readingTaskState >= 2 || (qs.QuestionMark === 1105 && isDisabledMeasurableRadio)"
v-model="questionForm[qs.Id]" @change="((val) => { formItemChange(val, qs) })">
:disabled="!isCurrentTask || readingTaskState>=2 || (qs.QuestionMark === 1105 && isDisabledMeasurableRadio)"
@change="((val)=>{formItemChange(val, qs)})"
>
<template v-if="qs.DictionaryCode.length > 0"> <template v-if="qs.DictionaryCode.length > 0">
<el-radio <el-radio v-for="item in $d[qs.DictionaryCode]" :key="item.id" :label="item.value">
v-for="item in $d[qs.DictionaryCode]"
:key="item.id"
:label="item.value"
>
{{ item.label }} {{ item.label }}
</el-radio> </el-radio>
</template> </template>
<template v-else-if="qs.options.length > 0"> <template v-else-if="qs.options.length > 0">
<el-radio <el-radio v-for="val in qs.options.split('|')" :key="val" :label="val">
v-for="val in qs.options.split('|')"
:key="val"
:label="val"
>
{{ val }} {{ val }}
</el-radio> </el-radio>
</template> </template>
</el-radio-group> </el-radio-group>
<!-- 自动计算 --> <div style="display: flex;justify-content: space-between;" v-else-if="qs.Type === 'calculation'">
<el-input <!-- 自动计算 -->
v-else-if="qs.Type==='calculation'" <el-input v-model="questionForm[qs.Id]" disabled @change="((val) => { formItemChange(val, qs) })">
v-model="questionForm[qs.Id]" <template v-if="qs.Unit" slot="append">
disabled {{ $fd('ValueUnit', parseInt(qs.Unit)) }}
@change="((val)=>{formItemChange(val, qs)})" </template>
> </el-input>
<template v-if="qs.Unit" slot="append"> <svg-icon v-if="qs.ShowChartTypeEnum > 0" icon-class="readingChart" class="svg-icon svg-readingChart"
{{ $fd('ValueUnit', parseInt(qs.Unit)) }} @click.stop="(e) => handleReadingChart({
</template> e,
</el-input> data: {
TableQuestionId: qs.Id,
RowIndex: questionForm.RowIndex,
QuestionName: qs.QuestionName
}
})" />
</div>
</el-form-item> </el-form-item>
</div> </div>
<div <div v-if="isCurrentTask && readingTaskState < 2" class="base-dialog-footer"
v-if="isCurrentTask && readingTaskState<2" style="text-align:right;margin-top:10px;">
class="base-dialog-footer"
style="text-align:right;margin-top:10px;"
>
<!-- 保存 --> <!-- 保存 -->
<el-button <el-button size="mini" @click="handleSave">
size="mini"
@click="handleSave"
>
{{ $t('common:button:save') }} {{ $t('common:button:save') }}
</el-button> </el-button>
</div> </div>
@ -290,6 +235,9 @@ export default {
DicomEvent.$off('handleImageQualityAbnormal') DicomEvent.$off('handleImageQualityAbnormal')
}, },
methods: { methods: {
handleReadingChart(e) {
this.$emit('handleReadingChart', e)
},
async initForm() { async initForm() {
this.isRender = false this.isRender = false
this.isMeasurableId = this.getQuestionId(1105) this.isMeasurableId = this.getQuestionId(1105)
@ -503,7 +451,7 @@ export default {
const orderMarkName = this.getLesionName(this.orderMark, qs.QuestionMark) const orderMarkName = this.getLesionName(this.orderMark, qs.QuestionMark)
this.activeQuestionId = qs.Id this.activeQuestionId = qs.Id
this.activeQuestionMark = qs.QuestionMark this.activeQuestionMark = qs.QuestionMark
DicomEvent.$emit('addAnnotation', { question: qs, locateInfo: { questionId: this.parentQsId, rowIndex: this.questionForm.RowIndex, visitTaskId: this.visitTaskId, lesionName: orderMarkName, lesionType: null, markTool: 'Probe', readingTaskState: this.readingTaskState, isMarked: true }}) DicomEvent.$emit('addAnnotation', { question: qs, locateInfo: { questionId: this.parentQsId, rowIndex: this.questionForm.RowIndex, visitTaskId: this.visitTaskId, lesionName: orderMarkName, lesionType: null, markTool: 'Probe', readingTaskState: this.readingTaskState, isMarked: true } })
}, },
getAnnotationSaveEnum(qs) { getAnnotationSaveEnum(qs) {
const i = this.markList.findIndex(i => i.tableQuestionId === qs.Id) const i = this.markList.findIndex(i => i.tableQuestionId === qs.Id)
@ -592,14 +540,14 @@ export default {
if (confirm !== 'confirm') return if (confirm !== 'confirm') return
} }
// //
DicomEvent.$emit('getScreenshots', { questionId: this.parentQsId, rowIndex: this.questionForm.RowIndex, visitTaskId: this.visitTaskId, lesionName: measureData.OrderMarkName, lesionType: null, isMarked: !!measureData }, async val => { DicomEvent.$emit('getScreenshots', { questionId: this.parentQsId, rowIndex: this.questionForm.RowIndex, visitTaskId: this.visitTaskId, lesionName: measureData.OrderMarkName, lesionType: null, isMarked: !!measureData }, async val => {
params = Object.assign({}, this.markList[i].measureData) params = Object.assign({}, this.markList[i].measureData)
if (val) { if (val) {
const pictureObj = await this.uploadScreenshots(`${new Date().getTime()}`, val) const pictureObj = await this.uploadScreenshots(`${new Date().getTime()}`, val)
params.PicturePath = pictureObj.isSuccess ? this.$getObjectName(pictureObj.result.url) : '' params.PicturePath = pictureObj.isSuccess ? this.$getObjectName(pictureObj.result.url) : ''
} }
params.Answer = this.questionForm[tableQuestionId] params.Answer = this.questionForm[tableQuestionId]
params.MeasureData = JSON.stringify(this.markList[i].measureData.MeasureData) params.MeasureData = JSON.stringify(this.markList[i].measureData.MeasureData)
loading.close() loading.close()
@ -754,17 +702,17 @@ export default {
const valid = await this.$refs.measurementForm.validate() const valid = await this.$refs.measurementForm.validate()
if (!valid) return if (!valid) return
if (parseInt(this.questionForm[this.isMeasurableId]) === 1) { if (parseInt(this.questionForm[this.isMeasurableId]) === 1) {
// //
const i = this.markList.findIndex(i => i.saveEnum === 0) const i = this.markList.findIndex(i => i.saveEnum === 0)
if (i > -1) { if (i > -1) {
// //
this.$alert(this.$t('trials:MRIPDFF:message:message1')) this.$alert(this.$t('trials:MRIPDFF:message:message1'))
// this.$message.warning(this.$t('trials:MRIPDFF:message:message1')) // this.$message.warning(this.$t('trials:MRIPDFF:message:message1'))
return return
} }
} else { } else {
// //
// '' // ''
const confirm = await this.$confirm( const confirm = await this.$confirm(
this.$t('trials:MRIPDFF:message:message2'), this.$t('trials:MRIPDFF:message:message2'),
{ {
@ -817,7 +765,7 @@ export default {
} }
const res = await submitTaskRowInfo(params, 11) const res = await submitTaskRowInfo(params, 11)
if (res.IsSuccess) { if (res.IsSuccess) {
// //
this.$message.success(this.$t('common:message:savedSuccessfully')) this.$message.success(this.$t('common:message:savedSuccessfully'))
this.$set(this.questionForm, 'saveTypeEnum', 2) this.$set(this.questionForm, 'saveTypeEnum', 2)
this.originalQuestionForm = { ...this.questionForm } this.originalQuestionForm = { ...this.questionForm }
@ -853,45 +801,55 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.measurement-form{ .measurement-form {
::v-deep .el-form-item__label{ ::v-deep .el-form-item__label {
color: #c3c3c3; color: #c3c3c3;
} }
::v-deep .el-input .el-input__inner{
::v-deep .el-input .el-input__inner {
background-color: transparent; background-color: transparent;
color: #ddd; color: #ddd;
border: 1px solid #5e5e5e; border: 1px solid #5e5e5e;
} }
::v-deep .el-form-item{
::v-deep .el-form-item {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: flex-start; justify-content: flex-start;
} }
::v-deep .el-form-item__content{
::v-deep .el-form-item__content {
flex: 1; flex: 1;
} }
::v-deep .el-input.is-disabled .el-input__inner{
::v-deep .el-input.is-disabled .el-input__inner {
background-color: #646464a1; background-color: #646464a1;
} }
::v-deep .el-select.is-disabled .el-input__inner{
::v-deep .el-select.is-disabled .el-input__inner {
background-color: #646464a1; background-color: #646464a1;
} }
::v-deep .el-button--mini, .el-button--mini.is-round {
::v-deep .el-button--mini,
.el-button--mini.is-round {
padding: 7px 10px; padding: 7px 10px;
} }
::v-deep .el-input-group__append, .el-input-group__prepend {
::v-deep .el-input-group__append,
.el-input-group__prepend {
padding: 0 10px; padding: 0 10px;
} }
.el-form-item__content
.el-select{ .el-form-item__content .el-select {
width: 100%; width: 100%;
} }
.input-width1{
width: calc(100% - 60px)!important; .input-width1 {
width: calc(100% - 60px) !important;
} }
.input-width2{
.input-width2 {
width: 100% !important; width: 100% !important;
} }
} }
</style> </style>

View File

@ -8,63 +8,62 @@
<span style="margin-left:5px;">{{ taskBlindName }}</span> <span style="margin-left:5px;">{{ taskBlindName }}</span>
</h3> </h3>
<div v-if="readingTaskState < 2"> <div v-if="readingTaskState < 2">
<el-tooltip class="item" effect="dark" :content="$t('trials:dicomReading:message:confirmReset')" placement="bottom"> <el-tooltip class="item" effect="dark" :content="$t('trials:dicomReading:message:confirmReset')"
<i placement="bottom">
class="el-icon-refresh-left" <i class="el-icon-refresh-left" @click="resetMeasuredData" />
@click="resetMeasuredData"
/>
</el-tooltip> </el-tooltip>
</div> </div>
</div> </div>
<!-- 非测量问题 --> <!-- 非测量问题 -->
<div class="lesions"> <div class="lesions">
<Questions ref="ecrf" :groupClassify="1" :question-form-change-state="questionFormChangeState" :question-form-change-num="questionFormChangeNum" /> <Questions ref="ecrf" :groupClassify="1" :question-form-change-state="questionFormChangeState"
:question-form-change-num="questionFormChangeNum" @handleReadingChart="handleReadingChart" />
</div> </div>
<!-- 测量问题 --> <!-- 测量问题 -->
<template > <template>
<div v-for="(qs,index) in questions" :key="index" v-loading="loading" class="lesions lesions_wrapper"> <div v-for="(qs, index) in questions" :key="index" v-loading="loading" class="lesions lesions_wrapper">
<h4 v-if="qs.Type === 'group'" style="color: #ddd;padding: 5px 0px;margin: 0;"> <h4 v-if="qs.Type === 'group'" style="color: #ddd;padding: 5px 0px;margin: 0;">
{{ language==='en'?qs.GroupEnName:qs.GroupName }} {{ language === 'en' ? qs.GroupEnName : qs.GroupName }}
</h4> </h4>
<div class="lesion_list"> <div class="lesion_list">
<div v-for="item in qs.Childrens" v-show="!(isBaseLineTask && item.LesionType === 2)" :key="item.Id"> <div v-for="item in qs.Childrens" v-show="!(isBaseLineTask && item.LesionType === 2)" :key="item.Id">
<div v-if="item.Type === 'table'" class="flex-row" style="margin:3px 0;"> <div v-if="item.Type === 'table'" class="flex-row" style="margin:3px 0;">
<div class="title">{{ item.QuestionName }}</div> <div class="title">{{ item.QuestionName }}</div>
</div> </div>
<div style="color: #ddd;text-align: left;padding: 5px 10px;border-bottom: 1px solid #5a5a5a; font-size: 15px;"> <div
<el-row > style="color: #ddd;text-align: left;padding: 5px 10px;border-bottom: 1px solid #5a5a5a; font-size: 15px;">
<el-row>
<!-- 分段 --> <!-- 分段 -->
<el-col :span="14">{{$t('trials:MRIPDFF:label:col1')}}</el-col> <el-col :span="14">{{ $t('trials:MRIPDFF:label:col1') }}</el-col>
<!-- 是否可测量 --> <!-- 是否可测量 -->
<!-- <el-col :span="7">{{$t('trials:MRIPDFF:label:col2')}}</el-col> --> <!-- <el-col :span="7">{{$t('trials:MRIPDFF:label:col2')}}</el-col> -->
<!-- 平均值 --> <!-- 平均值 -->
<el-col :span="7">{{$t('trials:MRIPDFF:label:col3')}}</el-col> <el-col :span="7">{{ $t('trials:MRIPDFF:label:col3') }}</el-col>
</el-row> </el-row>
</div> </div>
<el-collapse <el-collapse v-if="item.Type === 'table' && item.TableQuestions" v-model="activeName" accordion
v-if="item.Type === 'table' && item.TableQuestions" @change="handleCollapseChange">
v-model="activeName" <el-collapse-item v-for="(q, i) in item.TableQuestions.Answers" :key="`${item.Id}_${q.RowIndex}`"
accordion
@change="handleCollapseChange"
>
<el-collapse-item
v-for="(q,i) in item.TableQuestions.Answers"
:key="`${item.Id}_${q.RowIndex}`"
:name="`${item.Id}_${q.RowIndex}`" :name="`${item.Id}_${q.RowIndex}`"
@contextmenu.prevent.native="collapseRightClick($event,q,item.Id,q.RowIndex)" @contextmenu.prevent.native="collapseRightClick($event, q, item.Id, q.RowIndex)">
>
<template slot="title"> <template slot="title">
<div style="width:300px;position: relative;" :style="{color:(activeName===item.Id+q.RowIndex?'#ffeb3b':'#fff')}"> <div style="width:300px;position: relative;"
:style="{ color: (activeName === item.Id + q.RowIndex ? '#ffeb3b' : '#fff') }">
{{ getLesionName(item.TableQuestions.Questions, q) }} {{ getLesionName(item.TableQuestions.Questions, q) }}
<!-- 未保存 --> <!-- 未保存 -->
<el-tooltip v-if="readingTaskState<2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) === 0" class="item" effect="dark" :content="$t('trials:reading:button:unsaved')" placement="bottom"> <el-tooltip
v-if="readingTaskState < 2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) === 0"
class="item" effect="dark" :content="$t('trials:reading:button:unsaved')" placement="bottom">
<i class="el-icon-warning" style="color:red" /> <i class="el-icon-warning" style="color:red" />
</el-tooltip> </el-tooltip>
<!-- 信息不完整 --> <!-- 信息不完整 -->
<el-tooltip v-if="readingTaskState<2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) ===1" class="item" effect="dark" :content="$t('trials:reading:button:incompleteInfor')" placement="bottom"> <el-tooltip
v-if="readingTaskState < 2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) === 1"
class="item" effect="dark" :content="$t('trials:reading:button:incompleteInfor')"
placement="bottom">
<i class="el-icon-warning" style="color:#ff9800" /> <i class="el-icon-warning" style="color:#ff9800" />
</el-tooltip> </el-tooltip>
<div style="position: absolute;right: 0px;top: 2px;"> <div style="position: absolute;right: 0px;top: 2px;">
@ -73,32 +72,23 @@
<!-- <div style="display: inline-block;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;width:95px"> <!-- <div style="display: inline-block;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;width:95px">
{{ $fd('ReadingYesOrNo', parseInt(item.TableQuestions.Answers[i].isMeasurable)) }} {{ $fd('ReadingYesOrNo', parseInt(item.TableQuestions.Answers[i].isMeasurable)) }}
</div> --> </div> -->
<div style="display: inline-block;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;width:50px"> <div
{{ isNaN(parseFloat(item.TableQuestions.Answers[i].mean)) ? item.TableQuestions.Answers[i].mean : `${item.TableQuestions.Answers[i].mean}%` }} style="display: inline-block;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;width:50px">
{{ isNaN(parseFloat(item.TableQuestions.Answers[i].mean)) ?
item.TableQuestions.Answers[i].mean : `${item.TableQuestions.Answers[i].mean}%` }}
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<QuestionForm <QuestionForm :ref="`${item.Id}_${q.RowIndex}`" :questions="item.TableQuestions.Questions"
:ref="`${item.Id}_${q.RowIndex}`" :answers="item.TableQuestions.Answers[i]" :lesion-type="item.LesionType"
:questions="item.TableQuestions.Questions" :order-mark="item.OrderMark" :table-questions="tableQuestions" :row-index="String(q.RowIndex)"
:answers="item.TableQuestions.Answers[i]" :question-name="item.QuestionName" :parent-qs-id="item.Id" :visit-task-id="visitTaskId"
:lesion-type="item.LesionType" :is-current-task="isCurrentTask" :reading-task-state="readingTaskState"
:order-mark="item.OrderMark" :is-base-line-task="isBaseLineTask" @getReadingQuestionAndAnswer="getReadingQuestionAndAnswer"
:table-questions="tableQuestions" @resetQuestions="resetQuestions" @close="close" @handleReadingChart="handleReadingChart" />
:row-index="String(q.RowIndex)"
:question-name="item.QuestionName"
:parent-qs-id="item.Id"
:visit-task-id="visitTaskId"
:is-current-task="isCurrentTask"
:reading-task-state="readingTaskState"
:is-base-line-task="isBaseLineTask"
@getReadingQuestionAndAnswer="getReadingQuestionAndAnswer"
@resetQuestions="resetQuestions"
@close="close"
/>
</el-collapse-item> </el-collapse-item>
</el-collapse> </el-collapse>
@ -210,6 +200,9 @@ export default {
DicomEvent.$off('getAllUnSaveLesions') DicomEvent.$off('getAllUnSaveLesions')
}, },
methods: { methods: {
handleReadingChart(e) {
this.$emit('handleReadingChart', e)
},
async initList() { async initList() {
var i = this.visitTaskList.findIndex(i => i.VisitTaskId === this.lastCanvasTaskId) var i = this.visitTaskList.findIndex(i => i.VisitTaskId === this.lastCanvasTaskId)
if (i > -1) { if (i > -1) {
@ -269,7 +262,7 @@ export default {
for (const i in obj.anwsers) { for (const i in obj.anwsers) {
if (i === 'MeasureData' && obj.anwsers[i]) { if (i === 'MeasureData' && obj.anwsers[i]) {
} else { } else {
item.TableQuestions.Answers[idx][i] = String(obj.anwsers[i]) item.TableQuestions.Answers[idx][i] = String(obj.anwsers[i])
} }
@ -360,11 +353,11 @@ export default {
}) })
await store.dispatch('reading/refreshMeasuredData', this.visitTaskId) await store.dispatch('reading/refreshMeasuredData', this.visitTaskId)
DicomEvent.$emit('getMeasureData') DicomEvent.$emit('getMeasureData')
loading ? loading.close() : '' loading ? loading.close() : ''
resolve() resolve()
} catch (e) { } catch (e) {
console.log(e) console.log(e)
loading ? loading.close() : '' loading ? loading.close() : ''
} }
}) })
@ -383,13 +376,13 @@ export default {
}, },
checkToolCanActive(toolName) { checkToolCanActive(toolName) {
return { isCanActiveTool: true, reason: '' } return { isCanActiveTool: true, reason: '' }
}, },
getLesionName(questions, q) { getLesionName(questions, q) {
let liverSegmentStr = '' let liverSegmentStr = ''
if (!this.liverSegmentId) { if (!this.liverSegmentId) {
let i = questions.findIndex(i=>i.QuestionMark === 1106) let i = questions.findIndex(i => i.QuestionMark === 1106)
if (i === -1) return if (i === -1) return
this.liverSegmentId = questions[i].Id this.liverSegmentId = questions[i].Id
this.liverSegmentDicCode = questions[i].DictionaryCode this.liverSegmentDicCode = questions[i].DictionaryCode
@ -458,7 +451,7 @@ export default {
} }
}) })
} else { } else {
} }
}, },
async close(questionsObj) { async close(questionsObj) {
@ -525,23 +518,26 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.measurement-wrapper{ .measurement-wrapper {
height: 100%; height: 100%;
overflow-y: auto; overflow-y: auto;
// overflow: hidden; // overflow: hidden;
.container{ .container {
padding: 10px; padding: 10px;
.basic-info{
.basic-info {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
h3{
h3 {
color: #ddd; color: #ddd;
padding: 5px 0px; padding: 5px 0px;
margin: 0; margin: 0;
} }
i{
i {
color: #fff; color: #fff;
font-size: 22px; font-size: 22px;
font-weight: bold; font-weight: bold;
@ -549,14 +545,16 @@ export default {
} }
} }
} }
.title{
.title {
padding: 5px; padding: 5px;
font-weight: bold; font-weight: bold;
color: #ddd; color: #ddd;
font-size: 15px; font-size: 15px;
} }
.add-icon{
.add-icon {
padding: 5px; padding: 5px;
font-weight: bold; font-weight: bold;
color: #ddd; color: #ddd;
@ -565,42 +563,49 @@ export default {
margin-bottom: 2px; margin-bottom: 2px;
cursor: pointer; cursor: pointer;
} }
.add-icon:hover{
.add-icon:hover {
background-color: #607d8b; background-color: #607d8b;
} }
.flex-row{ .flex-row {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
background-color: #424242; background-color: #424242;
} }
.lesion_list{
.lesion_list {
position: relative; position: relative;
} }
.el-collapse{
border-bottom:none; .el-collapse {
border-top:none; border-bottom: none;
::v-deep .el-collapse-item{ border-top: none;
background-color: #000!important;
::v-deep .el-collapse-item {
background-color: #000 !important;
color: #ddd; color: #ddd;
} }
::v-deep .el-collapse-item__header{
background-color: #000!important; ::v-deep .el-collapse-item__header {
background-color: #000 !important;
color: #ddd; color: #ddd;
border-bottom-color:#5a5a5a; border-bottom-color: #5a5a5a;
padding-left: 5px; padding-left: 5px;
height: 35px; height: 35px;
line-height: 35px; line-height: 35px;
} }
::v-deep .el-collapse-item__wrap{
background-color: #000!important; ::v-deep .el-collapse-item__wrap {
background-color: #000 !important;
color: #ddd; color: #ddd;
} }
::v-deep .el-collapse-item__content{
width:260px; ::v-deep .el-collapse-item__content {
width: 260px;
position: absolute; position: absolute;
top: 0px; top: 0px;
right: 0px; right: 0px;
@ -609,7 +614,7 @@ export default {
z-index: 1; z-index: 1;
color: #ddd; color: #ddd;
padding: 5px; padding: 5px;
background-color:#1e1e1e; background-color: #1e1e1e;
} }
} }

View File

@ -1,14 +1,9 @@
<template> <template>
<div v-loading="loading" class="manuals-wrapper"> <div v-loading="loading" class="manuals-wrapper">
<div class="left-wrapper"> <div class="left-wrapper">
<div v-if="fileList.length>0" class="basic-content"> <div v-if="fileList.length > 0" class="basic-content">
<div <div v-for="file in fileList" :key="file.Id" class="file-item" :class="{ activeItem: file.Id === selected.id }"
v-for="file in fileList" @click.prevent="preview(file)">
:key="file.Id"
class="file-item"
:class="{activeItem:file.Id === selected.id}"
@click.prevent="preview(file)"
>
<!-- {{ file.Name }} --> <!-- {{ file.Name }} -->
<el-tooltip class="item" :content="file.Name" placement="bottom"> <el-tooltip class="item" :content="file.Name" placement="bottom">
<span>{{ file.Name }} </span> <span>{{ file.Name }} </span>
@ -21,19 +16,25 @@
</div> </div>
<div class="right-wrapper"> <div class="right-wrapper">
<div class="right-content"> <div class="right-content">
<iframe v-if="selected.filePath" :src="`/static/pdfjs/web/viewer.html?file=${OSSclientConfig.basePath}${selected.filePath}?userName=${currentUser}&COMPANY=${COMPANY}`" width="100%" height="100%" frameborder="0" /> <iframe v-if="selected.filePath"
:src="`/static/pdfjs/web/viewer.html?file=${OSSclientConfig.basePath}${selected.filePath}?userName=${currentUser}&COMPANY=${COMPANY}`"
width="100%" height="100%" frameborder="0" />
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { getManualList } from '@/api/trials' import { getManualList, getTrialCriterionKeyFileList } from '@/api/trials'
export default { export default {
name: 'Manuals', name: 'Manuals',
props: { props: {
trialId: { trialId: {
type: String, type: String,
required: true required: true
},
justKeyDoc: {
type: Boolean,
default: false
} }
}, },
data() { data() {
@ -45,7 +46,7 @@ export default {
fileList: [], fileList: [],
loading: false, loading: false,
currentUser: zzSessionStorage.getItem('userName'), currentUser: zzSessionStorage.getItem('userName'),
COMPANY:process.env.VUE_APP_COMPANY_NAME COMPANY: process.env.VUE_APP_COMPANY_NAME
} }
}, },
mounted() { mounted() {
@ -54,16 +55,35 @@ export default {
methods: { methods: {
async getList() { async getList() {
this.loading = true this.loading = true
this.fileList = []
try { try {
var param = { var param = {
trialId: this.trialId TrialCriterionId: this.$router.currentRoute.query.TrialReadingCriterionId,
PageIndex: 1,
PageSize: 1000
} }
const res = await getManualList(param) const res = await getTrialCriterionKeyFileList(param)
if (res.IsSuccess) { if (res.IsSuccess) {
this.fileList = res.Result let list = res.Result.CurrentPageData.map(item => {
if (this.fileList.length > 0) { return {
this.preview(this.fileList[0]) Id: item.Id,
Name: item.FileName,
Path: item.FilePath
}
})
this.fileList = [...this.fileList, ...list]
}
if (!this.justKeyDoc) {
var param = {
trialId: this.trialId
} }
const res = await getManualList(param)
if (res.IsSuccess) {
this.fileList = [...this.fileList, ...res.Result]
}
}
if (this.fileList.length > 0) {
this.preview(this.fileList[0])
} }
this.loading = false this.loading = false
} catch (e) { } catch (e) {
@ -77,38 +97,43 @@ export default {
} }
} }
</script> </script>
<style lang="scss"> <style lang="scss" scoped>
.manuals-wrapper{ .manuals-wrapper {
display: flex; display: flex;
flex-direction: row !important; flex-direction: row !important;
width: 100%; width: 100%;
height: 100%; height: 95%;
padding: 5px; padding: 5px;
overflow: hidden; overflow: hidden;
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 7px; width: 7px;
height: 7px; height: 7px;
} }
::-webkit-scrollbar-thumb { ::-webkit-scrollbar-thumb {
border-radius: 10px; border-radius: 10px;
background: #d0d0d0; background: #d0d0d0;
} }
.left-wrapper{
.left-wrapper {
box-sizing: border-box; box-sizing: border-box;
margin-right: 10px; margin-right: 10px;
height: 100%; height: 100%;
width: 300px; width: 300px;
border: 1px solid #ddd; border: 1px solid #ddd;
.basic-content{ .basic-content {
height: 100%; height: 100%;
overflow: auto; overflow: auto;
} }
.basic-content-empty{
.basic-content-empty {
padding: 5px; padding: 5px;
font-size: 16px; font-size: 16px;
} }
.file-item{
.file-item {
box-sizing: border-box; box-sizing: border-box;
border-bottom: 1px solid #f3f3f3; border-bottom: 1px solid #f3f3f3;
height: 50px; height: 50px;
@ -121,18 +146,21 @@ export default {
text-overflow: ellipsis; text-overflow: ellipsis;
width: 100%; width: 100%;
} }
.activeItem{
.activeItem {
color: #428bca !important; color: #428bca !important;
border-bottom: 1px solid #f3f3f3 !important; border-bottom: 1px solid #f3f3f3 !important;
} }
} }
.right-wrapper{
.right-wrapper {
flex: 1; flex: 1;
height: 100%; height: 100%;
border: 1px solid #ddd; border: 1px solid #ddd;
} }
.right-content{
height:100%; .right-content {
height: 100%;
} }
} }

View File

@ -17,7 +17,7 @@
<!-- 影像质量问题 --> <!-- 影像质量问题 -->
<div class="lesions"> <div class="lesions">
<Questions ref="ecrf" :question-form-change-state="true" :question-form-change-num="0" :is-qulity-issues="false" <Questions ref="ecrf" :question-form-change-state="true" :question-form-change-num="0" :is-qulity-issues="false"
:group-classify="1" /> :group-classify="1" @handleReadingChart="handleReadingChart" />
</div> </div>
<!-- 测量问题 --> <!-- 测量问题 -->
@ -37,7 +37,8 @@
<div class="add-icon" @click.prevent="downloadTpl(item.LesionType)"> <div class="add-icon" @click.prevent="downloadTpl(item.LesionType)">
<i class="el-icon-download" /> <i class="el-icon-download" />
</div> </div>
<div class="add-icon" style="margin: 0 5px;" @click.prevent="uploadTpl(item.LesionType, item.QuestionName)"> <div class="add-icon" style="margin: 0 5px;"
@click.prevent="uploadTpl(item.LesionType, item.QuestionName)">
<i class="el-icon-upload2" /> <i class="el-icon-upload2" />
</div> </div>
<div class="add-icon" @click.prevent="handleAddOrEdit('add', item)"> <div class="add-icon" @click.prevent="handleAddOrEdit('add', item)">
@ -154,7 +155,7 @@
<el-form ref="tableQsForm" v-loading="loading" :model="qsForm" size="small"> <el-form ref="tableQsForm" v-loading="loading" :model="qsForm" size="small">
<QuestionTableFormItem v-for="item in qsList" :key="item.Id" :question="item" :question-form="qsForm" <QuestionTableFormItem v-for="item in qsList" :key="item.Id" :question="item" :question-form="qsForm"
:reading-task-state="readingTaskState" @setFormItemData="setFormItemData" :reading-task-state="readingTaskState" @setFormItemData="setFormItemData"
@resetFormItemData="resetFormItemData" /> @resetFormItemData="resetFormItemData" @handleReadingChart="handleReadingChart" />
<el-form-item style="text-align: right"> <el-form-item style="text-align: right">
<el-button size="small" @click="addOrEdit.visible = false"> <el-button size="small" @click="addOrEdit.visible = false">
{{ $t('common:button:cancel') }} {{ $t('common:button:cancel') }}
@ -169,7 +170,8 @@
<!-- 导入 --> <!-- 导入 -->
<el-dialog v-if="upload.visible" :visible.sync="upload.visible" :close-on-click-modal="false" <el-dialog v-if="upload.visible" :visible.sync="upload.visible" :close-on-click-modal="false"
:title="upload.title" width="500px"> :title="upload.title" width="500px">
<UploadExcel :visit-task-id="visitTaskId" :lesion-type="upload.lesionType" :TableName="upload.TableName" @close="uploadDlgClose" /> <UploadExcel :visit-task-id="visitTaskId" :lesion-type="upload.lesionType" :TableName="upload.TableName"
@close="uploadDlgClose" />
</el-dialog> </el-dialog>
</div> </div>
</div> </div>
@ -282,6 +284,9 @@ export default {
DicomEvent.$off('refreshQuestions') DicomEvent.$off('refreshQuestions')
}, },
methods: { methods: {
handleReadingChart(e) {
this.$emit('handleReadingChart', e)
},
async initList() { async initList() {
var i = this.visitTaskList.findIndex(i => i.VisitTaskId === this.lastCanvasTaskId) var i = this.visitTaskList.findIndex(i => i.VisitTaskId === this.lastCanvasTaskId)
if (i > -1) { if (i > -1) {

View File

@ -1,119 +1,66 @@
<template> <template>
<div> <div>
<div <div v-if="!!question.GroupName && question.Type === 'group'">
v-if="!!question.GroupName && question.Type==='group'"
>
<h4 style="color: #ddd;padding: 5px 0px;margin: 0;"> <h4 style="color: #ddd;padding: 5px 0px;margin: 0;">
{{ language==='en'?question.GroupEnName:question.GroupName }} {{ language === 'en' ? question.GroupEnName : question.GroupName }}
</h4> </h4>
</div> </div>
<template v-else> <template v-else>
<el-form-item <el-form-item
v-if="(question.ShowQuestion===1 && question.ParentTriggerValueList.includes(String(questionForm[question.ParentId]))) || question.ShowQuestion===0 " v-if="(question.ShowQuestion === 1 && question.ParentTriggerValueList.includes(String(questionForm[question.ParentId]))) || question.ShowQuestion === 0"
:label="`${question.QuestionName}`" :label="`${question.QuestionName}`" :prop="question.Id" :rules="[
:prop="question.Id" {
:rules="[ required: (question.IsRequired === 0 || (question.IsRequired === 1 && question.RelevanceId && (questionForm[question.RelevanceId] === question.RelevanceValue))) && question.Type !== 'group' && question.Type !== 'summary',
{ required: (question.IsRequired === 0 || (question.IsRequired ===1 && question.RelevanceId && (questionForm[question.RelevanceId] === question.RelevanceValue))) && question.Type!=='group' && question.Type!=='summary', message: ['radio', 'select', 'checkbox'].includes(question.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']
message: ['radio', 'select', 'checkbox'].includes(question.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']}, },
]" ]"
:class="[question.Type==='group' ? 'mb' : (question.Type==='upload' || question.QuestionName.length > 15) ?'uploadWrapper' : '']" :class="[question.Type === 'group' ? 'mb' : (question.Type === 'upload' || question.QuestionName.length > 15) ? 'uploadWrapper' : '']">
>
<!-- 输入框 --> <!-- 输入框 -->
<el-input <el-input v-if="question.Type === 'input'" v-model="questionForm[question.Id]" :disabled="readingTaskState >= 2"
v-if="question.Type==='input'" @change="((val) => { formItemChange(val, question) })" />
v-model="questionForm[question.Id]"
:disabled="readingTaskState >= 2"
@change="((val)=>{formItemChange(val, question)})"
/>
<!-- 多行文本输入框 --> <!-- 多行文本输入框 -->
<el-input <el-input v-else-if="question.Type === 'textarea'" v-model="questionForm[question.Id]" type="textarea"
v-else-if="question.Type==='textarea'" :autosize="{ minRows: 2, maxRows: 4 }" maxlength="500" :disabled="readingTaskState >= 2"
v-model="questionForm[question.Id]" @change="((val) => { formItemChange(val, question) })" />
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
maxlength="500"
:disabled="readingTaskState >= 2"
@change="((val)=>{formItemChange(val, question)})"
/>
<!-- 下拉框 --> <!-- 下拉框 -->
<el-select <el-select v-else-if="question.Type === 'select'" v-model="questionForm[question.Id]"
v-else-if="question.Type==='select'"
v-model="questionForm[question.Id]"
:disabled="readingTaskState >= 2 || ((question.TableQuestionType === 2 || question.QuestionGenre === 2) && !!question.DictionaryCode)" :disabled="readingTaskState >= 2 || ((question.TableQuestionType === 2 || question.QuestionGenre === 2) && !!question.DictionaryCode)"
clearable clearable @change="((val) => { formItemChange(val, question) })">
@change="((val)=>{formItemChange(val, question)})"
>
<template v-if="question.TableQuestionType === 1"> <template v-if="question.TableQuestionType === 1">
<el-option <el-option v-for="item in organList" :key="item.Id" :label="item[question.DataTableColumn]"
v-for="item in organList" :value="item[question.DataTableColumn]" />
:key="item.Id"
:label="item[question.DataTableColumn]"
:value="item[question.DataTableColumn]"
/>
</template> </template>
<template v-else-if="question.TableQuestionType === 3 || question.QuestionGenre === 3"> <template v-else-if="question.TableQuestionType === 3 || question.QuestionGenre === 3">
<el-option <el-option v-for="item of $d[question.DictionaryCode]" :key="item.id" :value="String(item.value)"
v-for="item of $d[question.DictionaryCode]" :label="item.label" />
:key="item.id"
:value="String(item.value)"
:label="item.label"
/>
</template> </template>
<template v-else-if="(question.TableQuestionType === 2 || question.QuestionGenre === 2) && question.DictionaryCode"> <template
<el-option v-else-if="(question.TableQuestionType === 2 || question.QuestionGenre === 2) && question.DictionaryCode">
v-for="item of $d[question.DictionaryCode]" <el-option v-for="item of $d[question.DictionaryCode]" :key="item.id" :value="String(item.value)"
:key="item.id" :label="item.label" />
:value="String(item.value)"
:label="item.label"
/>
</template> </template>
<template v-else> <template v-else>
<el-option <el-option v-for="val in question.TypeValue.split('|')" :key="val" :label="val" :value="val" />
v-for="val in question.TypeValue.split('|')"
:key="val"
:label="val"
:value="val"
/>
</template> </template>
</el-select> </el-select>
<!-- 单选 --> <!-- 单选 -->
<el-radio-group <el-radio-group v-else-if="question.Type === 'radio'" v-model="questionForm[question.Id]"
v-else-if="question.Type==='radio'" :disabled="readingTaskState >= 2" @change="((val) => { formItemChange(val, question) })">
v-model="questionForm[question.Id]"
:disabled="readingTaskState >= 2"
@change="((val)=>{formItemChange(val, question)})"
>
<template v-if="question.DictionaryCode"> <template v-if="question.DictionaryCode">
<el-radio <el-radio v-for="item of $d[question.DictionaryCode]" :key="item.id" :label="String(item.value)">
v-for="item of $d[question.DictionaryCode]"
:key="item.id"
:label="String(item.value)"
>
{{ item.label }} {{ item.label }}
</el-radio> </el-radio>
</template> </template>
<template v-else-if="question.TypeValue"> <template v-else-if="question.TypeValue">
<el-radio <el-radio v-for="val in question.TypeValue.split('|')" :key="val" :label="val">
v-for="val in question.TypeValue.split('|')"
:key="val"
:label="val"
>
{{ val }} {{ val }}
</el-radio> </el-radio>
</template> </template>
</el-radio-group> </el-radio-group>
<!-- 复选框 --> <!-- 复选框 -->
<el-checkbox-group <el-checkbox-group v-else-if="question.Type === 'checkbox'" v-model="questionForm[question.Id]"
v-else-if="question.Type==='checkbox'" :disabled="readingTaskState >= 2" @change="((val) => { formItemChange(val, question) })">
v-model="questionForm[question.Id]" <el-checkbox v-for="val in question.TypeValue.split('|')" :key="val" :label="val">
:disabled="readingTaskState >= 2"
@change="((val)=>{formItemChange(val, question)})"
>
<el-checkbox
v-for="val in question.TypeValue.split('|')"
:key="val"
:label="val"
>
{{ val }} {{ val }}
</el-checkbox> </el-checkbox>
</el-checkbox-group> </el-checkbox-group>
@ -143,41 +90,39 @@
@change="((val)=>{formItemChange(val, question)})" @change="((val)=>{formItemChange(val, question)})"
/> />
</template> --> </template> -->
<!-- 数值类型 --> <div style="display: flex;justify-content: space-between;"
<el-input v-else-if="question.Type === 'calculation' || question.Type === 'number'">
v-else-if="question.Type==='number'" <!-- 数值类型 -->
v-model="questionForm[question.Id]" <el-input v-if="question.Type === 'number'" v-model="questionForm[question.Id]"
:disabled="readingTaskState>=2 " :disabled="readingTaskState >= 2" type="number" @change="((val) => { formItemChange(val, question) })">
type="number" <template v-if="question.Unit" slot="append">
@change="((val)=>{formItemChange(val, question)})" {{ $fd('ValueUnit', parseInt(question.Unit)) }}
> </template>
<template v-if="question.Unit" slot="append"> </el-input>
{{ $fd('ValueUnit', parseInt(question.Unit)) }}
</template> <el-input v-else-if="question.Type === 'calculation'" v-model="questionForm[question.Id]" disabled
</el-input> @change="((val) => { formItemChange(val, question) })">
<template v-if="question.Unit" slot="append">
{{ $fd('ValueUnit', parseInt(question.Unit)) }}
</template>
</el-input>
<svg-icon v-if="question.ShowChartTypeEnum > 0" icon-class="readingChart" class="svg-icon svg-readingChart"
@click.stop="(e) => handleReadingChart({
e,
data: {
TableQuestionId: question.Id,
RowIndex: questionForm.RowIndex,
QuestionName: question.QuestionName
}
})" />
</div>
<el-input
v-else-if="question.Type==='calculation'"
v-model="questionForm[question.Id]"
disabled
@change="((val)=>{formItemChange(val, question)})"
>
<template v-if="question.Unit" slot="append">
{{ $fd('ValueUnit', parseInt(question.Unit)) }}
</template>
</el-input>
</el-form-item> </el-form-item>
</template> </template>
<QuestionTableFormItem <QuestionTableFormItem v-for="item in question.Childrens" :key="item.Id" :question="item"
v-for="item in question.Childrens" :question-form="questionForm" :reading-task-state="readingTaskState" @setFormItemData="setFormItemData"
:key="item.Id" @resetFormItemData="resetFormItemData" @handleReadingChart="handleReadingChart" />
:question="item"
:question-form="questionForm"
:reading-task-state="readingTaskState"
@setFormItemData="setFormItemData"
@resetFormItemData="resetFormItemData"
/>
</div> </div>
</template> </template>
<script> <script>
@ -214,6 +159,9 @@ export default {
this.digitPlaces = Number(localStorage.getItem('digitPlaces')) this.digitPlaces = Number(localStorage.getItem('digitPlaces'))
}, },
methods: { methods: {
handleReadingChart(e) {
this.$emit('handleReadingChart', e)
},
formItemChange(v, question) { formItemChange(v, question) {
if (question.Childrens && question.Childrens.length > 0) { if (question.Childrens && question.Childrens.length > 0) {
this.resetChild(question.Childrens) this.resetChild(question.Childrens)
@ -269,29 +217,36 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.mb{ .mb {
margin-bottom: 0px; margin-bottom: 0px;
} }
.disabled{
.disabled {
::v-deep .el-upload--picture-card { ::v-deep .el-upload--picture-card {
display: none; display: none;
} }
} }
.uploadWrapper{
.uploadWrapper {
display: flex; display: flex;
flex-direction: column !important; flex-direction: column !important;
align-items: flex-start; align-items: flex-start;
} }
::v-deep .el-input.is-disabled .el-input__inner{
background-color: #646464a1; ::v-deep .el-input.is-disabled .el-input__inner {
} background-color: #646464a1;
::v-deep .el-input-group__append, .el-input-group__prepend{ }
padding: 0 10px;
} ::v-deep .el-input-group__append,
::v-deep .el-form-item__content { .el-input-group__prepend {
width: 100%; padding: 0 10px;
} }
::v-deep .el-select.is-disabled .el-input__inner{
background-color: #646464a1; ::v-deep .el-form-item__content {
} width: 100%;
}
::v-deep .el-select.is-disabled .el-input__inner {
background-color: #646464a1;
}
</style> </style>

View File

@ -4,7 +4,7 @@
class="upload-excel-file" class="upload-excel-file"
> >
<!-- 文件 --> <!-- 文件 -->
<el-form-item :label="$t('trials:consistencyCheck:label:file')"> <el-form-item :label="$t('trials:consistencyCheck:label:file3')">
<div class="upload-container"> <div class="upload-container">
<el-upload <el-upload
class="upload-demo" class="upload-demo"

View File

@ -3,15 +3,22 @@
<div class="base-dialog-body" style="height:380px;overflow-y: auto;"> <div class="base-dialog-body" style="height:380px;overflow-y: auto;">
<el-form ref="otherForm" :model="form"> <el-form ref="otherForm" :model="form">
<!-- 自动切换下一个任务不必提示 --> <!-- 自动切换下一个任务不必提示 -->
<el-form-item <el-form-item :label="$t('trials:reading:label:autoSwitch')" prop="AutoCutNextTask" :rules="[
:label="$t('trials:reading:label:autoSwitch')" { required: true, message: $t('common:ruleMessage:select') }
prop="AutoCutNextTask" ]">
:rules="[
{ required: true, message: $t('common:ruleMessage:select')}
]"
>
<el-switch v-model="form.AutoCutNextTask" /> <el-switch v-model="form.AutoCutNextTask" />
</el-form-item> </el-form-item>
<el-form-item :label="$t('trials:reading:label:MultiScreen')" prop="IsDoubleScreen" :rules="[
{ required: true, message: $t('common:ruleMessage:select') }
]">
<el-switch v-model="form.IsDoubleScreen" />
</el-form-item>
<el-form-item>
<div><span>{{ $t("trials:reading:tip:MultiScreen") }}</span><a style="color:#409EFF" href="/screen.pdf"
target="blank">{{
$t("trials:reading:tip:openFile")
}}</a></div>
</el-form-item>
</el-form> </el-form>
</div> </div>
<div class="base-dialog-footer" style="text-align:right;margin-top:10px;"> <div class="base-dialog-footer" style="text-align:right;margin-top:10px;">
@ -27,7 +34,8 @@ export default {
data() { data() {
return { return {
form: { form: {
AutoCutNextTask: false AutoCutNextTask: false,
IsDoubleScreen: false
}, },
loading: false loading: false
} }
@ -42,6 +50,7 @@ export default {
const res = await getAutoCutNextTask() const res = await getAutoCutNextTask()
if (res.IsSuccess) { if (res.IsSuccess) {
this.form.AutoCutNextTask = res.Result.AutoCutNextTask this.form.AutoCutNextTask = res.Result.AutoCutNextTask
this.form.IsDoubleScreen = res.Result.IsDoubleScreen
} }
this.loading = false this.loading = false
} catch (e) { } catch (e) {
@ -66,6 +75,4 @@ export default {
} }
</script> </script>
<style lang="scss"> <style lang="scss"></style>
</style>

View File

@ -1,12 +1,6 @@
<template> <template>
<el-form <el-form v-if="isRender" ref="measurementForm" v-loading="loading" :model="questionForm" size="mini"
v-if="isRender" class="measurement-form">
ref="measurementForm"
v-loading="loading"
:model="questionForm"
size="mini"
class="measurement-form"
>
<div class="base-dialog-body"> <div class="base-dialog-body">
<div style="display: flex;justify-content: space-between;"> <div style="display: flex;justify-content: space-between;">
<h3 v-if="questionName" style="color: #ddd;padding: 5px 0px;margin: 0;"> <h3 v-if="questionName" style="color: #ddd;padding: 5px 0px;margin: 0;">
@ -20,177 +14,109 @@
</div> </div>
</div> </div>
<el-form-item <el-form-item :label="$t('trials:reading:title:lesionType')" prop="LesionType" :rules="[
:label="$t('trials:reading:title:lesionType')" { required: true, message: $t('common:ruleMessage:select'), trigger: ['blur'] },
prop="LesionType" ]">
:rules="[ <el-select v-model="questionForm.LesionType" filterable :disabled="true">
{ required:true,message: $t('common:ruleMessage:select'), trigger: ['blur']}, <el-option v-for="item of $d.LesionType" v-show="!(isBaseLineTask && item.value === 2)" :key="item.id"
]" :value="item.value" :label="item.label" />
>
<el-select
v-model="questionForm.LesionType"
filterable
:disabled="true"
>
<el-option
v-for="item of $d.LesionType"
v-show="!(isBaseLineTask && item.value === 2)"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item <el-form-item v-for="qs in questions" v-show="qs.ShowQuestion !== 2" :key="qs.Id" :label="`${qs.QuestionName}`"
v-for="qs in questions" :prop="qs.Id" :rules="qs.QuestionMark === 11 ? [
v-show="qs.ShowQuestion!==2" {
:key="qs.Id" required: (qs.IsRequired === 0 || (qs.IsRequired === 1 && qs.RelevanceId && (questionForm[qs.RelevanceId] === qs.RelevanceValue))) && qs.Type !== 'group' && qs.Type !== 'summary',
:label="`${qs.QuestionName}`" message: ['radio', 'select', 'checkbox'].includes(qs.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']
:prop="qs.Id" }, { validator: validateLesionCount, trigger: ['blur', 'change'] }] : [
:rules="qs.QuestionMark===11?[ {
{ required: (qs.IsRequired === 0 || (qs.IsRequired ===1 && qs.RelevanceId && (questionForm[qs.RelevanceId] === qs.RelevanceValue))) && qs.Type!=='group' && qs.Type!=='summary', required: (qs.IsRequired === 0 || (qs.IsRequired === 1 && qs.RelevanceId && (questionForm[qs.RelevanceId] === qs.RelevanceValue)) || (qs.QuestionMark === 6 && questionForm.IsCanEditPosition === true) || (questionForm.IsCanEditPosition && qs.QuestionMark === 10)) && qs.Type !== 'group' && qs.Type !== 'summary',
message: ['radio', 'select', 'checkbox'].includes(qs.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']},{validator:validateLesionCount, trigger: ['blur', 'change']}]:[ message: ['radio', 'select', 'checkbox'].includes(qs.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']
{ required: (qs.IsRequired === 0 || (qs.IsRequired ===1 && qs.RelevanceId && (questionForm[qs.RelevanceId] === qs.RelevanceValue)) || (qs.QuestionMark === 6 && questionForm.IsCanEditPosition === true) || (questionForm.IsCanEditPosition && qs.QuestionMark === 10)) && qs.Type!=='group' && qs.Type!=='summary', }]">
message: ['radio', 'select', 'checkbox'].includes(qs.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']}]"
>
<!-- {{ isCurrentTaskAdd }} <!-- {{ isCurrentTaskAdd }}
{{ questionForm.IsCanEditPosition }} --> {{ questionForm.IsCanEditPosition }} -->
<!-- 输入框 min="1" <!-- 输入框 min="1"
@input="questionForm[qs.Id]=questionForm[qs.Id].replace(/^(0+)|[^\d]+/g,'')"--> @input="questionForm[qs.Id]=questionForm[qs.Id].replace(/^(0+)|[^\d]+/g,'')"-->
<template v-if="qs.Type==='input' || qs.Type==='number'"> <template v-if="qs.Type === 'input' || qs.Type === 'number'">
<template v-if="qs.QuestionMark===11"> <template v-if="qs.QuestionMark === 11">
<el-input <div style="display: flex;justify-content: space-between;">
v-model="questionForm[qs.Id]" <el-input v-model="questionForm[qs.Id]" :disabled="!isCurrentTask || readingTaskState >= 2" type="number"
:disabled="!isCurrentTask || readingTaskState>=2 " @focus="focusQs = { ...qs }" @change="((val) => { formItemChange(val, qs) })">
type="number" <template v-if="(qs.QuestionMark === 0 || qs.QuestionMark === 1) && qs.Unit" slot="append">
{{ $fd('ValueUnit', parseInt(qs.Unit)) }}
</template>
</el-input>
<svg-icon v-if="qs.ShowChartTypeEnum > 0" icon-class="readingChart" class="svg-icon svg-readingChart"
@click.stop="(e) => handleReadingChart({
e,
data: {
TableQuestionId: qs.Id,
RowIndex: questionForm.RowIndex,
QuestionName: qs.QuestionName
}
})" />
</div>
@focus="focusQs = {...qs}"
@change="((val)=>{formItemChange(val, qs)})"
>
<template v-if="(qs.QuestionMark===0 || qs.QuestionMark===1) && qs.Unit" slot="append">
{{ $fd('ValueUnit', parseInt(qs.Unit)) }}
</template>
</el-input>
</template> </template>
<template v-else> <template v-else>
<el-input <el-input v-model="questionForm[qs.Id]"
v-model="questionForm[qs.Id]" :disabled="!isCurrentTask || readingTaskState >= 2 || qs.QuestionMark === 0 || qs.QuestionMark === 1 || qs.QuestionMark === 2 || qs.QuestionMark === 5 || (qs.QuestionMark === 6 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answers.SplitOrMergeLesionName)) || (qs.QuestionMark === 8 && (isCurrentTaskAdd === 'False') && lesionType !== 2) || qs.QuestionMark === 9 || (qs.QuestionMark === 10 && isCurrentTaskAdd === 'False')"
:disabled="!isCurrentTask || readingTaskState>=2 || qs.QuestionMark === 0 || qs.QuestionMark === 1 || qs.QuestionMark === 2 || qs.QuestionMark === 5 || (qs.QuestionMark === 6 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answers.SplitOrMergeLesionName))|| (qs.QuestionMark === 8 && (isCurrentTaskAdd === 'False') && lesionType !== 2) || qs.QuestionMark === 9 || (qs.QuestionMark === 10 && isCurrentTaskAdd === 'False')" @focus="focusQs = { ...qs }" @change="((val) => { formItemChange(val, qs) })">
@focus="focusQs = {...qs}" <template v-if="(qs.QuestionMark === 0 || qs.QuestionMark === 1) && qs.Unit" slot="append">
@change="((val)=>{formItemChange(val, qs)})"
>
<template v-if="(qs.QuestionMark===0 || qs.QuestionMark===1) && qs.Unit" slot="append">
{{ $fd('ValueUnit', parseInt(qs.Unit)) }} {{ $fd('ValueUnit', parseInt(qs.Unit)) }}
</template> </template>
</el-input> </el-input>
</template> </template>
</template> </template>
<!-- 多行文本输入框 --> <!-- 多行文本输入框 -->
<el-input <el-input v-if="qs.Type === 'textarea'" v-model="questionForm[qs.Id]" type="textarea"
v-if="qs.Type==='textarea'" :autosize="{ minRows: 2, maxRows: 4 }" :disabled="!isCurrentTask || readingTaskState >= 2"
v-model="questionForm[qs.Id]" @change="((val) => { formItemChange(val, qs) })" />
type="textarea" <el-select v-if="qs.Type === 'select'" v-model="questionForm[qs.Id]" filterable
:autosize="{ minRows: 2, maxRows: 4}" :disabled="((!isBaseLineTask && qs.QuestionMark === 11) || (isBaseLineTask || lesionType === 2) && qs.QuestionMark === 7) || !isCurrentTask || readingTaskState >= 2 || qs.QuestionMark === 0 || qs.QuestionMark === 1 || qs.QuestionMark === 2 || qs.QuestionMark === 5 || (qs.QuestionMark === 6 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answers.SplitOrMergeLesionName)) || (qs.QuestionMark === 8 && (isCurrentTaskAdd === 'False' || !!answers.SplitOrMergeLesionName) && lesionType !== 2)"
:disabled="!isCurrentTask || readingTaskState>=2" @change="((val) => { formItemChange(val, qs) })">
@change="((val)=>{formItemChange(val, qs)})"
/>
<el-select
v-if="qs.Type==='select'"
v-model="questionForm[qs.Id]"
filterable
:disabled="((!isBaseLineTask && qs.QuestionMark === 11) || (isBaseLineTask || lesionType === 2) && qs.QuestionMark === 7) || !isCurrentTask || readingTaskState>=2 || qs.QuestionMark === 0 || qs.QuestionMark === 1 || qs.QuestionMark === 2 || qs.QuestionMark === 5 || (qs.QuestionMark === 6 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answers.SplitOrMergeLesionName))|| (qs.QuestionMark === 8 && (isCurrentTaskAdd === 'False'|| !!answers.SplitOrMergeLesionName) && lesionType !== 2)"
@change="((val)=>{formItemChange(val, qs)})"
>
<template v-if="qs.TableQuestionType === 1"> <template v-if="qs.TableQuestionType === 1">
<el-option <el-option v-for="item in organList" :key="item.Id" :label="item[qs.DataTableColumn]"
v-for="item in organList" :value="item[qs.DataTableColumn]" />
:key="item.Id"
:label="item[qs.DataTableColumn]"
:value="item[qs.DataTableColumn]"
/>
</template> </template>
<template v-else-if="qs.DictionaryCode && qs.QuestionMark === 7 && isBaseLineTask"> <template v-else-if="qs.DictionaryCode && qs.QuestionMark === 7 && isBaseLineTask">
<el-option <el-option v-for="item of $d[qs.DictionaryCode]" :key="item.id" :value="item.value" :label="item.label" />
v-for="item of $d[qs.DictionaryCode]"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template> </template>
<template v-else-if="qs.DictionaryCode && qs.QuestionMark === 7 && !isBaseLineTask"> <template v-else-if="qs.DictionaryCode && qs.QuestionMark === 7 && !isBaseLineTask">
<el-option <el-option v-for="item of $d[qs.DictionaryCode]" :key="item.id" :value="item.value" :label="item.label" />
v-for="item of $d[qs.DictionaryCode]"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template> </template>
<template v-else-if="qs.DictionaryCode && qs.QuestionMark !== 7"> <template v-else-if="qs.DictionaryCode && qs.QuestionMark !== 7">
<el-option <el-option v-for="item of $d[qs.DictionaryCode]" :key="item.id" :value="item.value" :label="item.label" />
v-for="item of $d[qs.DictionaryCode]"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template> </template>
<template v-else> <template v-else>
<el-option <el-option v-for="val in qs.TypeValue.split('|')" :key="val" :label="val" :value="val" />
v-for="val in qs.TypeValue.split('|')"
:key="val"
:label="val"
:value="val"
/>
</template> </template>
</el-select> </el-select>
<!-- 单选 --> <!-- 单选 -->
<el-radio-group <el-radio-group v-if="qs.Type === 'radio'" v-model="questionForm[qs.id]"
v-if="qs.Type==='radio'" :disabled="!isCurrentTask || readingTaskState >= 2">
v-model="questionForm[qs.id]" <el-radio v-for="val in qs.options.split('|')" :key="val" :label="val">
:disabled="!isCurrentTask || readingTaskState>=2"
>
<el-radio
v-for="val in qs.options.split('|')"
:key="val"
:label="val"
>
{{ val }} {{ val }}
</el-radio> </el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</div> </div>
<div <div v-if="isCurrentTask && readingTaskState < 2" class="base-dialog-footer"
v-if="isCurrentTask && readingTaskState<2" style="text-align:right;margin-top:10px;">
class="base-dialog-footer"
style="text-align:right;margin-top:10px;"
>
<!-- 清除标记 --> <!-- 清除标记 -->
<el-button <el-button v-if="questionForm.MeasureData" size="mini" style="padding:7px 10px" @click="handleDeleteMeasureData">
v-if="questionForm.MeasureData"
size="mini"
style="padding:7px 10px"
@click="handleDeleteMeasureData"
>
{{ $t('trials:reading:button:removeMark') }} {{ $t('trials:reading:button:removeMark') }}
</el-button> </el-button>
<!-- 删除 --> <!-- 删除 -->
<el-button <el-button v-if="isCurrentTaskAdd !== 'False'" size="mini" style="margin-left: 5px;padding:7px 10px"
v-if="isCurrentTaskAdd !== 'False'" @click="handleDelete">
size="mini"
style="margin-left: 5px;padding:7px 10px"
@click="handleDelete"
>
{{ $t('common:button:delete') }} {{ $t('common:button:delete') }}
</el-button> </el-button>
<!-- 保存 --> <!-- 保存 -->
<el-button <el-button size="mini" style="margin-left: 5px;padding:7px 10px" @click="handleSave">
size="mini"
style="margin-left: 5px;padding:7px 10px"
@click="handleSave"
>
{{ $t('common:button:save') }} {{ $t('common:button:save') }}
</el-button> </el-button>
</div> </div>
@ -287,6 +213,9 @@ export default {
DicomEvent.$off('handleImageQualityAbnormal') DicomEvent.$off('handleImageQualityAbnormal')
}, },
methods: { methods: {
handleReadingChart(e) {
this.$emit('handleReadingChart', e)
},
validateLesionCount(rule, value, callback) { validateLesionCount(rule, value, callback) {
// const reg = /^[1-9][0-9]?$|^100$/ // const reg = /^[1-9][0-9]?$|^100$/
// const reg = /^(0+)|[^\d]+/g // const reg = /^(0+)|[^\d]+/g
@ -647,7 +576,7 @@ export default {
this.$confirm(this.$t('trials:readingPGWC:warnning:msg2'), { this.$confirm(this.$t('trials:readingPGWC:warnning:msg2'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -660,7 +589,7 @@ export default {
this.$confirm(this.$t('trials:readingPGWC:warnning:msg3'), { this.$confirm(this.$t('trials:readingPGWC:warnning:msg3'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -672,7 +601,7 @@ export default {
this.$confirm(this.$t('trials:readingPGWC:warnning:msg4'), { this.$confirm(this.$t('trials:readingPGWC:warnning:msg4'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -684,7 +613,7 @@ export default {
this.$confirm(this.$t('trials:readingPGWC:warnning:msg5'), { this.$confirm(this.$t('trials:readingPGWC:warnning:msg5'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -696,7 +625,7 @@ export default {
this.$confirm(this.$t('trials:readingPGWC:warnning:msg6'), { this.$confirm(this.$t('trials:readingPGWC:warnning:msg6'), {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
loading.close() loading.close()
return return
@ -855,7 +784,7 @@ export default {
type: 'warning', type: 'warning',
distinguishCancelAndClose: true distinguishCancelAndClose: true
}) })
.then(async() => { .then(async () => {
// //
if (this.questionForm.MeasureData) { if (this.questionForm.MeasureData) {
var remark = this.getLesionName(this.orderMark, this.questionForm.RowIndex) var remark = this.getLesionName(this.orderMark, this.questionForm.RowIndex)
@ -864,7 +793,7 @@ export default {
DicomEvent.$emit('getMeasureData') DicomEvent.$emit('getMeasureData')
this.$emit('close', { lesionType: this.lesionType, rowIndex: this.rowIndex, visitTaskId: this.visitTaskId }) this.$emit('close', { lesionType: this.lesionType, rowIndex: this.rowIndex, visitTaskId: this.visitTaskId })
}) })
.catch(() => {}) .catch(() => { })
} else { } else {
if (this.questionForm.isSave === false) { if (this.questionForm.isSave === false) {
// '' // ''
@ -875,7 +804,7 @@ export default {
.then(() => { .then(() => {
this.$emit('close') this.$emit('close')
}) })
.catch(() => {}) .catch(() => { })
} else { } else {
this.$emit('close') this.$emit('close')
} }
@ -900,39 +829,45 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.measurement-form{ .measurement-form {
::v-deep .el-form-item__label{ ::v-deep .el-form-item__label {
color: #c3c3c3; color: #c3c3c3;
} }
::v-deep .el-input .el-input__inner{
::v-deep .el-input .el-input__inner {
background-color: transparent; background-color: transparent;
color: #ddd; color: #ddd;
border: 1px solid #5e5e5e; border: 1px solid #5e5e5e;
} }
::v-deep .el-form-item{
::v-deep .el-form-item {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: flex-start; justify-content: flex-start;
} }
::v-deep .el-form-item__content{
::v-deep .el-form-item__content {
flex: 1; flex: 1;
} }
::v-deep .el-input.is-disabled .el-input__inner{
::v-deep .el-input.is-disabled .el-input__inner {
background-color: #646464a1; background-color: #646464a1;
} }
::v-deep .el-select.is-disabled .el-input__inner{
::v-deep .el-select.is-disabled .el-input__inner {
background-color: #646464a1; background-color: #646464a1;
} }
.el-form-item__content
.el-select{ .el-form-item__content .el-select {
width: 100%; width: 100%;
} }
.input-width1{
width: calc(100% - 60px)!important; .input-width1 {
width: calc(100% - 60px) !important;
} }
.input-width2{
.input-width2 {
width: 100% !important; width: 100% !important;
} }
} }
</style> </style>

View File

@ -8,58 +8,64 @@
<span style="margin-left:5px;">{{ taskBlindName }}</span> <span style="margin-left:5px;">{{ taskBlindName }}</span>
</h3> </h3>
<div v-if="readingTaskState < 2"> <div v-if="readingTaskState < 2">
<el-tooltip class="item" effect="dark" :content="$t('trials:dicomReading:message:confirmReset')" placement="bottom"> <el-tooltip class="item" effect="dark" :content="$t('trials:dicomReading:message:confirmReset')"
<i placement="bottom">
class="el-icon-refresh-left" <i class="el-icon-refresh-left" @click="resetMeasuredData" />
@click="resetMeasuredData"
/>
</el-tooltip> </el-tooltip>
</div> </div>
</div> </div>
<!-- 非测量问题 --> <!-- 非测量问题 -->
<div class="lesions"> <div class="lesions">
<Questions <Questions ref="ecrf" :question-form-change-state="questionFormChangeState"
ref="ecrf" :question-form-change-num="questionFormChangeNum" :is-first-change-task="isFirstChangeTask"
:question-form-change-state="questionFormChangeState" @handleReadingChart="handleReadingChart" />
:question-form-change-num="questionFormChangeNum"
:is-first-change-task="isFirstChangeTask"
/>
</div> </div>
<!-- 测量问题 --> <!-- 测量问题 -->
<template v-if="questions.length > 0"> <template v-if="questions.length > 0">
<div v-for="(qs,index) in questions" :key="index" v-loading="loading" class="lesions lesions_wrapper"> <div v-for="(qs, index) in questions" :key="index" v-loading="loading" class="lesions lesions_wrapper">
<h4 v-if="qs.Type === 'group'" style="color: #ddd;padding: 5px 0px;margin: 0;"> <h4 v-if="qs.Type === 'group'" style="color: #ddd;padding: 5px 0px;margin: 0;">
{{ language==='en'?qs.GroupEnName:qs.GroupName }} {{ language === 'en' ? qs.GroupEnName : qs.GroupName }}
</h4> </h4>
<div class="lesion_list"> <div class="lesion_list">
<div v-for="item in qs.Childrens" v-show="!(isBaseLineTask && item.LesionType === 2) && !(isBaseLineTask && item.LesionType === 3)" :key="item.Id"> <div v-for="item in qs.Childrens"
v-show="!(isBaseLineTask && item.LesionType === 2) && !(isBaseLineTask && item.LesionType === 3)"
:key="item.Id">
<div v-if="item.Type === 'table'" class="flex-row" style="margin:3px 0;"> <div v-if="item.Type === 'table'" class="flex-row" style="margin:3px 0;">
<div class="title">{{ item.QuestionName }}</div> <div class="title">{{ item.QuestionName }}
<div v-if="readingTaskState<2 && (isBaseLineTask || item.LesionType === 2)" class="add-icon" @click.prevent="handleAdd(item)"> <svg-icon v-if="item.LesionType === 4" icon-class="readingChart"
class="svg-icon svg-readingChart-mini" @click.stop="(e) => handleReadingChart({
e,
data: {
ReportChartTypeEnum: 1,
QuestionName: item.QuestionName
},
})" />
</div>
<div v-if="readingTaskState < 2 && (isBaseLineTask || item.LesionType === 2)" class="add-icon"
@click.prevent="handleAdd(item)">
<i class="el-icon-plus" /> <i class="el-icon-plus" />
</div> </div>
</div> </div>
<el-collapse <el-collapse v-if="item.Type === 'table' && item.TableQuestions" v-model="activeName" accordion
v-if="item.Type === 'table' && item.TableQuestions" @change="handleCollapseChange">
v-model="activeName" <el-collapse-item v-for="(q, i) in item.TableQuestions.Answers" :key="`${item.Id}_${q.RowIndex}`"
accordion
@change="handleCollapseChange"
>
<el-collapse-item
v-for="(q,i) in item.TableQuestions.Answers"
:key="`${item.Id}_${q.RowIndex}`"
:name="`${item.Id}_${q.RowIndex}`" :name="`${item.Id}_${q.RowIndex}`"
@contextmenu.prevent.native="collapseRightClick($event,q,item.Id,q.RowIndex)" @contextmenu.prevent.native="collapseRightClick($event, q, item.Id, q.RowIndex)">
>
<template slot="title"> <template slot="title">
<div style="width:300px;position: relative;" :style="{color:(activeName===item.Id+q.RowIndex?'#ffeb3b':'#fff')}"> <div style="width:300px;position: relative;"
{{ getLesionName(item.OrderMark,q.RowIndex, qs.Childrens) }} :style="{ color: (activeName === item.Id + q.RowIndex ? '#ffeb3b' : '#fff') }">
{{ getLesionName(item.OrderMark, q.RowIndex, qs.Childrens) }}
<!-- 未保存 --> <!-- 未保存 -->
<el-tooltip v-if="readingTaskState<2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) === 0" class="item" effect="dark" :content="$t('trials:reading:button:unsaved')" placement="bottom"> <el-tooltip
v-if="readingTaskState < 2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) === 0"
class="item" effect="dark" :content="$t('trials:reading:button:unsaved')" placement="bottom">
<i class="el-icon-warning" style="color:red" /> <i class="el-icon-warning" style="color:red" />
</el-tooltip> </el-tooltip>
<!-- 已更新未保存 --> <!-- 已更新未保存 -->
<el-tooltip v-if="readingTaskState<2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) ===1" class="item" effect="dark" :content="$t('trials:reading:button:incompleteInfor')" placement="bottom"> <el-tooltip
v-if="readingTaskState < 2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) === 1"
class="item" effect="dark" :content="$t('trials:reading:button:incompleteInfor')"
placement="bottom">
<i class="el-icon-warning" style="color:#ff9800" /> <i class="el-icon-warning" style="color:#ff9800" />
</el-tooltip> </el-tooltip>
<div style="position: absolute;left: 60px;top: 2px;"> <div style="position: absolute;left: 60px;top: 2px;">
@ -68,37 +74,29 @@
{{ item.TableQuestions.Answers[i].lesionPart }} {{ item.TableQuestions.Answers[i].lesionPart }}
</div> </div>
<div v-if="item.TableQuestions.Answers[i].lesionState" style="margin-left:10px;"> <div v-if="item.TableQuestions.Answers[i].lesionState" style="margin-left:10px;">
{{ $fd('EvaluationOfState',parseInt(item.TableQuestions.Answers[i].lesionState)) }} {{ $fd('EvaluationOfState', parseInt(item.TableQuestions.Answers[i].lesionState)) }}
</div> </div>
<div v-if="item.TableQuestions.Answers[i].lesionType" style="margin-left:10px;margin-bottom:5px;"> <div v-if="item.TableQuestions.Answers[i].lesionType"
style="margin-left:10px;margin-bottom:5px;">
{{ item.TableQuestions.Answers[i].lesionType }} {{ item.TableQuestions.Answers[i].lesionType }}
</div> </div>
<div v-if="!isNaN(parseInt(item.TableQuestions.Answers[i].lesionNum)) && item.LesionType === 4" style="margin-left:10px;"> <div
v-if="!isNaN(parseInt(item.TableQuestions.Answers[i].lesionNum)) && item.LesionType === 4"
style="margin-left:10px;">
{{ item.TableQuestions.Answers[i].lesionNum }} {{ item.TableQuestions.Answers[i].lesionNum }}
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<QuestionForm <QuestionForm :ref="`${item.Id}_${q.RowIndex}`" :questions="item.TableQuestions.Questions"
:ref="`${item.Id}_${q.RowIndex}`" :answers="item.TableQuestions.Answers[i]" :lesion-type="item.LesionType"
:questions="item.TableQuestions.Questions" :order-mark="item.OrderMark" :table-questions="tableQuestions" :row-index="String(q.RowIndex)"
:answers="item.TableQuestions.Answers[i]" :question-name="item.QuestionName" :parent-qs-id="item.Id" :visit-task-id="visitTaskId"
:lesion-type="item.LesionType" :is-current-task="isCurrentTask" :reading-task-state="readingTaskState"
:order-mark="item.OrderMark" :is-base-line-task="isBaseLineTask" @getReadingQuestionAndAnswer="getReadingQuestionAndAnswer"
:table-questions="tableQuestions" @determineExistsUnsavedLession="determineExistsUnsavedLession" @resetQuestions="resetQuestions"
:row-index="String(q.RowIndex)" @close="close" @handleReadingChart="handleReadingChart" />
:question-name="item.QuestionName"
:parent-qs-id="item.Id"
:visit-task-id="visitTaskId"
:is-current-task="isCurrentTask"
:reading-task-state="readingTaskState"
:is-base-line-task="isBaseLineTask"
@getReadingQuestionAndAnswer="getReadingQuestionAndAnswer"
@determineExistsUnsavedLession="determineExistsUnsavedLession"
@resetQuestions="resetQuestions"
@close="close"
/>
</el-collapse-item> </el-collapse-item>
</el-collapse> </el-collapse>
@ -218,6 +216,9 @@ export default {
DicomEvent.$off('getUnSaveTarget') DicomEvent.$off('getUnSaveTarget')
}, },
methods: { methods: {
handleReadingChart(e) {
this.$emit('handleReadingChart', e)
},
async initList() { async initList() {
var i = this.visitTaskList.findIndex(i => i.VisitTaskId === this.lastCanvasTaskId) var i = this.visitTaskList.findIndex(i => i.VisitTaskId === this.lastCanvasTaskId)
if (i > -1) { if (i > -1) {
@ -519,7 +520,7 @@ export default {
this.$confirm(msg, { this.$confirm(msg, {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
return return
} }
@ -530,7 +531,7 @@ export default {
this.$confirm(msg, { this.$confirm(msg, {
type: 'warning', type: 'warning',
showCancelButton: false, showCancelButton: false,
callback: action => {} callback: action => { }
}) })
} else { } else {
var obj = { saveTypeEnum: 0 } var obj = { saveTypeEnum: 0 }
@ -798,23 +799,26 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.measurement-wrapper{ .measurement-wrapper {
height: 100%; height: 100%;
overflow-y: auto; overflow-y: auto;
// overflow: hidden; // overflow: hidden;
.container{ .container {
padding: 10px; padding: 10px;
.basic-info{
.basic-info {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
h3{
h3 {
color: #ddd; color: #ddd;
padding: 5px 0px; padding: 5px 0px;
margin: 0; margin: 0;
} }
i{
i {
color: #fff; color: #fff;
font-size: 22px; font-size: 22px;
font-weight: bold; font-weight: bold;
@ -822,14 +826,16 @@ export default {
} }
} }
} }
.title{
.title {
padding: 5px; padding: 5px;
font-weight: bold; font-weight: bold;
color: #ddd; color: #ddd;
font-size: 15px; font-size: 15px;
} }
.add-icon{
.add-icon {
padding: 5px; padding: 5px;
font-weight: bold; font-weight: bold;
color: #ddd; color: #ddd;
@ -838,42 +844,49 @@ export default {
margin-bottom: 2px; margin-bottom: 2px;
cursor: pointer; cursor: pointer;
} }
.add-icon:hover{
.add-icon:hover {
background-color: #607d8b; background-color: #607d8b;
} }
.flex-row{ .flex-row {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
background-color: #424242; background-color: #424242;
} }
.lesion_list{
.lesion_list {
position: relative; position: relative;
} }
.el-collapse{
border-bottom:none; .el-collapse {
border-top:none; border-bottom: none;
::v-deep .el-collapse-item{ border-top: none;
background-color: #000!important;
::v-deep .el-collapse-item {
background-color: #000 !important;
color: #ddd; color: #ddd;
} }
::v-deep .el-collapse-item__header{
background-color: #000!important; ::v-deep .el-collapse-item__header {
background-color: #000 !important;
color: #ddd; color: #ddd;
border-bottom-color:#5a5a5a; border-bottom-color: #5a5a5a;
padding-left: 5px; padding-left: 5px;
height: 35px; height: 35px;
line-height: 35px; line-height: 35px;
} }
::v-deep .el-collapse-item__wrap{
background-color: #000!important; ::v-deep .el-collapse-item__wrap {
background-color: #000 !important;
color: #ddd; color: #ddd;
} }
::v-deep .el-collapse-item__content{
width:260px; ::v-deep .el-collapse-item__content {
width: 260px;
position: absolute; position: absolute;
top: 0px; top: 0px;
right: 0px; right: 0px;
@ -882,10 +895,9 @@ export default {
z-index: 1; z-index: 1;
color: #ddd; color: #ddd;
padding: 5px; padding: 5px;
background-color:#1e1e1e; background-color: #1e1e1e;
} }
} }
} }
</style> </style>

View File

@ -6,47 +6,54 @@
> >
{{ question.GroupName }} {{ question.GroupName }}
</div> --> </div> -->
<div <div v-if="!!question.GroupName && question.Type === 'group'">
v-if="!!question.GroupName && question.Type==='group'"
>
<h4 style="color: #ddd;padding: 5px 0px;margin: 0;"> <h4 style="color: #ddd;padding: 5px 0px;margin: 0;">
{{ language==='en'?question.GroupEnName:question.GroupName }} {{ language === 'en' ? question.GroupEnName : question.GroupName }}
</h4> </h4>
</div> </div>
<template v-else-if="((question.QuestionType === 56 || question.QuestionType === 57) && question.IsBaseLineTask)" /> <template v-else-if="((question.QuestionType === 56 || question.QuestionType === 57) && question.IsBaseLineTask)" />
<template v-else> <template v-else>
<el-form-item <el-form-item
v-if="(question.ShowQuestion===1 && question.ParentTriggerValueList.includes(String(questionForm[question.ParentId]))) || question.ShowQuestion===0 " v-if="(question.ShowQuestion === 1 && question.ParentTriggerValueList.includes(String(questionForm[question.ParentId]))) || question.ShowQuestion === 0"
:label="`${question.QuestionName}`" :label="`${question.QuestionName}`" :prop="question.Id" :rules="[
:prop="question.Id" {
:rules="[ required: (question.IsRequired === 0 || (question.IsRequired === 1 && question.RelevanceId && (questionForm[question.RelevanceId] === question.RelevanceValue))) && question.Type !== 'group' && question.Type !== 'summary',
{ required: (question.IsRequired === 0 || (question.IsRequired ===1 && question.RelevanceId && (questionForm[question.RelevanceId] === question.RelevanceValue))) && question.Type!=='group' && question.Type!=='summary', message: ['radio', 'select', 'checkbox'].includes(question.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']
message: ['radio', 'select', 'checkbox'].includes(question.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']}, },
]" ]"
:class="[question.Type==='group' ? 'mb' : (question.Type==='upload' || question.QuestionName.length > 15) ?'uploadWrapper' : '']" :class="[question.Type === 'group' ? 'mb' : (question.Type === 'upload' || question.QuestionName.length > 15) ? 'uploadWrapper' : '']">
>
<template v-if="question.QuestionType === 60 || question.QuestionType === 61"> <template v-if="question.QuestionType === 60 || question.QuestionType === 61">
<div style="display: flex;flex-direction: row;justify-content: flex-start;align-items: center;"> <div style="display: flex;flex-direction: row;justify-content: flex-start;align-items: center;">
<div style="display: flex;justify-content: space-between;" v-if="question.Type === 'calculation'">
<el-input v-if="question.Type === 'calculation'" v-model="questionForm[question.Id]" disabled
style="width: 130px;">
<template v-if="question.Unit" slot="append">
{{ $fd('ValueUnit', parseInt(question.Unit)) }}
</template>
</el-input>
<svg-icon v-if="question.ShowChartTypeEnum > 0" icon-class="readingChart"
class="svg-icon svg-readingChart" @click.stop="(e) => handleReadingChart({
e,
data: {
QuestionId: question.Id,
QuestionName: question.QuestionName
}
})" />
</div>
<el-input
v-if="question.Type==='calculation'"
v-model="questionForm[question.Id]"
disabled
style="width: 130px;"
>
<template v-if="question.Unit" slot="append">
{{ $fd('ValueUnit', parseInt(question.Unit)) }}
</template>
</el-input>
<!-- 测量 --> <!-- 测量 -->
<el-button v-if="!questionForm[question.Id] && readingTaskState!== 2" size="mini" type="text" @click="addAnnotation(question)">{{ $t('trials:lugano:button:addAnnotation') }}</el-button> <el-button v-if="!questionForm[question.Id] && readingTaskState !== 2" size="mini" type="text"
@click="addAnnotation(question)">{{ $t('trials:lugano:button:addAnnotation') }}</el-button>
<!-- 清除标记 --> <!-- 清除标记 -->
<el-button v-if="questionForm[question.Id]&& readingTaskState!== 2" size="mini" type="text" @click="removeAnnotation(question)">{{ $t('trials:lugano:button:clearAnnotation') }}</el-button> <el-button v-if="questionForm[question.Id] && readingTaskState !== 2" size="mini" type="text"
@click="removeAnnotation(question)">{{ $t('trials:lugano:button:clearAnnotation') }}</el-button>
<!-- 定位 --> <!-- 定位 -->
<el-button v-if="questionForm[question.Id]" size="mini" type="text" @click="locateAnnotation(question)">{{ $t('trials:lugano:button:locateAnnotation') }}</el-button> <el-button v-if="questionForm[question.Id]" size="mini" type="text" @click="locateAnnotation(question)">{{
$t('trials:lugano:button:locateAnnotation') }}</el-button>
<!-- 保存 --> <!-- 保存 -->
<el-button v-if="readingTaskState!== 2 && question.SaveEnum === 1" size="mini" type="text" @click="saveAnnotation(question)"> <el-button v-if="readingTaskState !== 2 && question.SaveEnum === 1" size="mini" type="text"
@click="saveAnnotation(question)">
<!-- 未保存 --> <!-- 未保存 -->
<el-tooltip class="item" effect="dark" :content="$t('trials:reading:button:unsaved')" placement="bottom"> <el-tooltip class="item" effect="dark" :content="$t('trials:reading:button:unsaved')" placement="bottom">
<i class="el-icon-warning" style="color:red" /> <i class="el-icon-warning" style="color:red" />
@ -56,157 +63,101 @@
</div> </div>
</template> </template>
<template v-else-if="question.QuestionType === 48 || question.QuestionType === 51 || question.QuestionType === 52 || question.QuestionType === 53"> <template
<el-input v-else-if="question.QuestionType === 48 || question.QuestionType === 51 || question.QuestionType === 52 || question.QuestionType === 53">
v-if="question.Type==='calculation'" <div style="display: flex;justify-content: space-between;" v-if="question.Type === 'calculation'">
v-model="questionForm[question.Id]" <el-input v-if="question.Type === 'calculation'" v-model="questionForm[question.Id]" disabled>
disabled <template v-if="question.Unit" slot="append">
> {{ $fd('ValueUnit', parseInt(question.Unit)) }}
<template v-if="question.Unit" slot="append"> </template>
{{ $fd('ValueUnit', parseInt(question.Unit)) }} </el-input>
</template> <svg-icon v-if="question.ShowChartTypeEnum > 0" icon-class="readingChart" class="svg-icon svg-readingChart"
</el-input> @click.stop="(e) => handleReadingChart({
e,
data: {
QuestionId: question.Id,
QuestionName: question.QuestionName
}
})" />
</div>
</template> </template>
<!-- 输入框 --> <!-- 输入框 -->
<el-input <el-input v-else-if="question.Type === 'input'" v-model="questionForm[question.Id]"
v-else-if="question.Type==='input'"
v-model="questionForm[question.Id]"
:disabled="readingTaskState >= 2 || isFirstChangeTask" :disabled="readingTaskState >= 2 || isFirstChangeTask"
@change="((val)=>{formItemChange(val, question)})" @change="((val) => { formItemChange(val, question) })" />
/>
<!-- 多行文本输入框 --> <!-- 多行文本输入框 -->
<el-input <el-input v-else-if="question.Type === 'textarea'" v-model="questionForm[question.Id]" type="textarea"
v-else-if="question.Type==='textarea'" :autosize="{ minRows: 2, maxRows: 4 }" maxlength="500" :disabled="readingTaskState >= 2 || isFirstChangeTask"
v-model="questionForm[question.Id]" @change="((val) => { formItemChange(val, question) })" />
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
maxlength="500"
:disabled="readingTaskState >= 2 || isFirstChangeTask"
@change="((val)=>{formItemChange(val, question)})"
/>
<!-- 下拉框 --> <!-- 下拉框 -->
<el-select <el-select v-else-if="question.Type === 'select'" v-model="questionForm[question.Id]"
v-else-if="question.Type==='select'"
v-model="questionForm[question.Id]"
:disabled="readingTaskState >= 2 || ((question.TableQuestionType === 2 || question.QuestionGenre === 2) && !!question.DictionaryCode) || isFirstChangeTask || question.QuestionType === 50 || question.QuestionType === 55" :disabled="readingTaskState >= 2 || ((question.TableQuestionType === 2 || question.QuestionGenre === 2) && !!question.DictionaryCode) || isFirstChangeTask || question.QuestionType === 50 || question.QuestionType === 55"
clearable clearable @change="((val) => { formItemChange(val, question) })">
@change="((val)=>{formItemChange(val, question)})"
>
<template v-if="question.TableQuestionType === 1"> <template v-if="question.TableQuestionType === 1">
<el-option <el-option v-for="item in organList" :key="item.Id" :label="item[question.DataTableColumn]"
v-for="item in organList" :value="item[question.DataTableColumn]" />
:key="item.Id"
:label="item[question.DataTableColumn]"
:value="item[question.DataTableColumn]"
/>
</template> </template>
<template v-else-if="question.QuestionGenre === 3 && question.QuestionType === 47 && question.IsBaseLineTask"> <template v-else-if="question.QuestionGenre === 3 && question.QuestionType === 47 && question.IsBaseLineTask">
<el-option <el-option v-for="item of $d[question.DictionaryCode]"
v-for="item of $d[question.DictionaryCode]" v-show="item.value === 1 || item.value === 2 || item.value === 5" :key="item.id"
v-show="item.value === 1 ||item.value === 2 || item.value === 5 " :value="String(item.value)" :label="item.label" />
:key="item.id"
:value="String(item.value)"
:label="item.label"
/>
</template> </template>
<template v-else-if="question.QuestionGenre === 3 && question.QuestionType === 47 && !question.IsBaseLineTask"> <template
v-else-if="question.QuestionGenre === 3 && question.QuestionType === 47 && !question.IsBaseLineTask">
<el-option-group <el-option-group
:label="!isNaN(parseFloat(question.LastTaskAnswer)) ? `${$t('trials:dicomReading:tip:lastVisitStatus')} ${$fd(question.DictionaryCode,parseFloat(question.LastTaskAnswer))}` : ''" :label="!isNaN(parseFloat(question.LastTaskAnswer)) ? `${$t('trials:dicomReading:tip:lastVisitStatus')} ${$fd(question.DictionaryCode, parseFloat(question.LastTaskAnswer))}` : ''">
> <el-option v-for="item of $d[question.DictionaryCode]"
<el-option v-show="item.value === 1 || item.value === 3 || item.value === 4 || item.value === 5" :key="item.id"
v-for="item of $d[question.DictionaryCode]" :value="String(item.value)" :label="item.label" />
v-show="item.value === 1 ||item.value === 3|| item.value === 4 || item.value === 5"
:key="item.id"
:value="String(item.value)"
:label="item.label"
/>
</el-option-group> </el-option-group>
</template> </template>
<template v-else-if="question.QuestionGenre === 3 && question.QuestionType === 49 && question.IsBaseLineTask"> <template v-else-if="question.QuestionGenre === 3 && question.QuestionType === 49 && question.IsBaseLineTask">
<el-option <el-option v-for="item of $d[question.DictionaryCode]"
v-for="item of $d[question.DictionaryCode]" v-show="item.value === 1 || item.value === 5 || item.value === 6" :key="item.id"
v-show="item.value === 1 ||item.value === 5 || item.value === 6 " :value="String(item.value)" :label="item.label" />
:key="item.id"
:value="String(item.value)"
:label="item.label"
/>
</template> </template>
<template v-else-if="question.QuestionGenre === 3 && question.QuestionType === 49 && !question.IsBaseLineTask"> <template
v-else-if="question.QuestionGenre === 3 && question.QuestionType === 49 && !question.IsBaseLineTask">
<el-option-group <el-option-group
:label="!isNaN(parseFloat(question.LastTaskAnswer)) ? `${$t('trials:dicomReading:tip:lastVisitStatus')} ${$fd(question.DictionaryCode,parseFloat(question.LastTaskAnswer))}` : ''" :label="!isNaN(parseFloat(question.LastTaskAnswer)) ? `${$t('trials:dicomReading:tip:lastVisitStatus')} ${$fd(question.DictionaryCode, parseFloat(question.LastTaskAnswer))}` : ''">
> <el-option v-for="item of $d[question.DictionaryCode]"
<el-option v-show="item.value === 1 || item.value === 2 || item.value === 3 || item.value === 4 || item.value === 5"
v-for="item of $d[question.DictionaryCode]" :key="item.id" :value="String(item.value)" :label="item.label" />
v-show="item.value === 1 ||item.value === 2 || item.value === 3 || item.value === 4 || item.value === 5"
:key="item.id"
:value="String(item.value)"
:label="item.label"
/>
</el-option-group> </el-option-group>
</template> </template>
<template v-else-if="question.TableQuestionType === 3 || question.QuestionGenre === 3"> <template v-else-if="question.TableQuestionType === 3 || question.QuestionGenre === 3">
<el-option <el-option v-for="item of $d[question.DictionaryCode]" :key="item.id" :value="String(item.value)"
v-for="item of $d[question.DictionaryCode]" :label="item.label" />
:key="item.id"
:value="String(item.value)"
:label="item.label"
/>
</template> </template>
<template v-else-if="(question.TableQuestionType === 2 || question.QuestionGenre === 2) && question.DictionaryCode"> <template
<el-option v-else-if="(question.TableQuestionType === 2 || question.QuestionGenre === 2) && question.DictionaryCode">
v-for="item of $d[question.DictionaryCode]" <el-option v-for="item of $d[question.DictionaryCode]" :key="item.id" :value="String(item.value)"
:key="item.id" :label="item.label" />
:value="String(item.value)"
:label="item.label"
/>
</template> </template>
<template v-else> <template v-else>
<el-option <el-option v-for="val in question.TypeValue.split('|')" :key="val" :label="val" :value="val" />
v-for="val in question.TypeValue.split('|')"
:key="val"
:label="val"
:value="val"
/>
</template> </template>
</el-select> </el-select>
<!-- 单选 --> <!-- 单选 -->
<el-radio-group <el-radio-group v-else-if="question.Type === 'radio'" v-model="questionForm[question.Id]"
v-else-if="question.Type==='radio'" :disabled="readingTaskState >= 2 || isFirstChangeTask" @change="((val) => { formItemChange(val, question) })">
v-model="questionForm[question.Id]"
:disabled="readingTaskState >= 2 || isFirstChangeTask"
@change="((val)=>{formItemChange(val, question)})"
>
<template v-if="question.DictionaryCode"> <template v-if="question.DictionaryCode">
<el-radio <el-radio v-for="item of $d[question.DictionaryCode]" :key="item.id" :label="String(item.value)">
v-for="item of $d[question.DictionaryCode]"
:key="item.id"
:label="String(item.value)"
>
{{ item.label }} {{ item.label }}
</el-radio> </el-radio>
</template> </template>
<template v-else-if="question.TypeValue"> <template v-else-if="question.TypeValue">
<el-radio <el-radio v-for="val in question.TypeValue.split('|')" :key="val" :label="val">
v-for="val in question.TypeValue.split('|')"
:key="val"
:label="val"
>
{{ val }} {{ val }}
</el-radio> </el-radio>
</template> </template>
</el-radio-group> </el-radio-group>
<!-- 复选框 --> <!-- 复选框 -->
<el-checkbox-group <el-checkbox-group v-else-if="question.Type === 'checkbox'" v-model="questionForm[question.Id]"
v-else-if="question.Type==='checkbox'" :disabled="readingTaskState >= 2 || isFirstChangeTask">
v-model="questionForm[question.Id]" <el-checkbox v-for="val in question.TypeValue.split('|')" :key="val" :label="val">
:disabled="readingTaskState >= 2 || isFirstChangeTask"
>
<el-checkbox
v-for="val in question.TypeValue.split('|')"
:key="val"
:label="val"
>
{{ val }} {{ val }}
</el-checkbox> </el-checkbox>
</el-checkbox-group> </el-checkbox-group>
@ -217,80 +168,53 @@
:disabled="readingTaskState >= 2 || isFirstChangeTask" :disabled="readingTaskState >= 2 || isFirstChangeTask"
:precision="2" :precision="2"
/> --> /> -->
<template v-else-if="question.Type==='number'"> <div style="display: flex;justify-content: space-between;"
<el-input-number v-else-if="question.Type === 'number' || question.Type === 'calculation'">
v-if="question.ValueType === 0" <template v-if="question.Type === 'number'">
v-model="questionForm[question.Id]" <el-input-number v-if="question.ValueType === 0" v-model="questionForm[question.Id]" :precision="0"
:precision="0" :disabled="readingTaskState >= 2 || isFirstChangeTask" />
:disabled="readingTaskState >= 2 || isFirstChangeTask" <el-input-number v-else-if="question.ValueType === 3" v-model="questionForm[question.Id]"
/> :disabled="readingTaskState >= 2 || isFirstChangeTask" />
<el-input-number <el-input-number v-else-if="question.ValueType === 1 || question.ValueType === 2"
v-else-if="question.ValueType === 3" v-model="questionForm[question.Id]" :precision="digitPlaces"
v-model="questionForm[question.Id]" :disabled="readingTaskState >= 2 || isFirstChangeTask" />
:disabled="readingTaskState >= 2 || isFirstChangeTask"
/>
<el-input-number
v-else-if="question.ValueType === 1 || question.ValueType === 2"
v-model="questionForm[question.Id]"
:precision="digitPlaces"
:disabled="readingTaskState >= 2 || isFirstChangeTask"
/>
</template>
<el-input
v-else-if="question.Type==='calculation'"
v-model="questionForm[question.Id]"
disabled
>
<template v-if="question.Unit" slot="append">
{{ $fd('ValueUnit', parseInt(question.Unit)) }}
</template> </template>
</el-input> <el-input v-else-if="question.Type === 'calculation'" v-model="questionForm[question.Id]" disabled>
<template v-if="question.Unit" slot="append">
{{ $fd('ValueUnit', parseInt(question.Unit)) }}
</template>
</el-input>
<svg-icon v-if="question.ShowChartTypeEnum > 0" icon-class="readingChart" class="svg-icon svg-readingChart"
@click.stop="(e) => handleReadingChart({
e,
data: {
QuestionId: question.Id,
QuestionName: question.QuestionName
}
})" />
</div>
<!-- 上传图像 --> <!-- 上传图像 -->
<el-upload <el-upload v-else-if="question.Type === 'upload'" action :accept="accept" :limit="question.ImageCount"
v-else-if="question.Type==='upload'" :on-preview="handlePictureCardPreview" :before-upload="handleBeforeUpload" :http-request="uploadScreenshot"
action list-type="picture-card" :on-remove="handleRemove" :file-list="fileList"
:accept="accept" :class="{ disabled: fileList.length >= question.ImageCount }"
:limit="question.ImageCount" :disabled="readingTaskState >= 2 || isFirstChangeTask">
:on-preview="handlePictureCardPreview"
:before-upload="handleBeforeUpload"
:http-request="uploadScreenshot"
list-type="picture-card"
:on-remove="handleRemove"
:file-list="fileList"
:class="{disabled:fileList.length >= question.ImageCount}"
:disabled="readingTaskState >= 2 || isFirstChangeTask"
>
<i slot="default" class="el-icon-plus" /> <i slot="default" class="el-icon-plus" />
<div slot="file" slot-scope="{file}"> <div slot="file" slot-scope="{file}">
<img <img class="el-upload-list__item-thumbnail" :src="OSSclientConfig.basePath + file.url" alt="">
class="el-upload-list__item-thumbnail"
:src="OSSclientConfig.basePath + file.url"
alt=""
>
<span class="el-upload-list__item-actions"> <span class="el-upload-list__item-actions">
<span <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
class="el-upload-list__item-preview"
@click="handlePictureCardPreview(file)"
>
<i class="el-icon-zoom-in" /> <i class="el-icon-zoom-in" />
</span> </span>
<span <span v-if="readingTaskState < 2" class="el-upload-list__item-delete" @click="handleRemove(file)">
v-if="readingTaskState < 2"
class="el-upload-list__item-delete"
@click="handleRemove(file)"
>
<i class="el-icon-delete" /> <i class="el-icon-delete" />
</span> </span>
</span> </span>
</div> </div>
</el-upload> </el-upload>
<el-dialog <el-dialog v-if="question.Type === 'upload'" append-to-body :visible.sync="imgVisible" width="600px">
v-if="question.Type==='upload'"
append-to-body
:visible.sync="imgVisible"
width="600px"
>
<el-image :src="imageUrl" width="100%"> <el-image :src="imageUrl" width="100%">
<div slot="placeholder" class="image-slot"> <div slot="placeholder" class="image-slot">
加载中<span class="dot">...</span> 加载中<span class="dot">...</span>
@ -300,17 +224,9 @@
</el-form-item> </el-form-item>
</template> </template>
<QuestionItem <QuestionItem v-for="(item) in question.Childrens" :key="item.Id" :question="item"
v-for="(item) in question.Childrens" :reading-task-state="readingTaskState" :is-first-change-task="isFirstChangeTask" :question-form="questionForm"
:key="item.Id" :visit-task-id="visitTaskId" @setFormItemData="setFormItemData" @resetFormItemData="resetFormItemData" />
:question="item"
:reading-task-state="readingTaskState"
:is-first-change-task="isFirstChangeTask"
:question-form="questionForm"
:visit-task-id="visitTaskId"
@setFormItemData="setFormItemData"
@resetFormItemData="resetFormItemData"
/>
</div> </div>
</template> </template>
<script> <script>
@ -423,7 +339,7 @@ export default {
.then(() => { .then(() => {
DicomEvent.$emit('removeAnnotation', question) DicomEvent.$emit('removeAnnotation', question)
}) })
.catch(() => {}) .catch(() => { })
}, },
locateAnnotation(question) { locateAnnotation(question) {
DicomEvent.$emit('locateAnnotation', question) DicomEvent.$emit('locateAnnotation', question)
@ -479,29 +395,36 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.mb{ .mb {
margin-bottom: 0px; margin-bottom: 0px;
} }
.disabled{
.disabled {
::v-deep .el-upload--picture-card { ::v-deep .el-upload--picture-card {
display: none; display: none;
} }
} }
.uploadWrapper{
.uploadWrapper {
display: flex; display: flex;
flex-direction: column !important; flex-direction: column !important;
align-items: flex-start; align-items: flex-start;
} }
::v-deep .el-input.is-disabled .el-input__inner{
background-color: #646464a1; ::v-deep .el-input.is-disabled .el-input__inner {
} background-color: #646464a1;
::v-deep .el-input-group__append, .el-input-group__prepend{ }
padding: 0 10px;
} ::v-deep .el-input-group__append,
::v-deep .el-form-item__content { .el-input-group__prepend {
width: 100%; padding: 0 10px;
} }
::v-deep .el-select.is-disabled .el-input__inner{
background-color: #646464a1; ::v-deep .el-form-item__content {
} width: 100%;
}
::v-deep .el-select.is-disabled .el-input__inner {
background-color: #646464a1;
}
</style> </style>

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