965 Commits

Author SHA1 Message Date
DESKTOP-6C3NK6N\WXS 07fe167eac 反馈图片上传问题
continuous-integration/drone/push Build is running
2024-08-06 17:45:40 +08:00
DESKTOP-6C3NK6N\WXS 2a00dda5f4 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-08-06 17:45:01 +08:00
caiyiling a185f4755a Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-08-06 17:33:06 +08:00
caiyiling 0aacbf49d9 阅片反馈修改 2024-08-06 17:32:44 +08:00
DESKTOP-6C3NK6N\WXS 10e1c92e73 【意见反馈】状态修改为已解决,退出再次进入状态仍为未解决 2024-08-06 17:17:26 +08:00
DESKTOP-6C3NK6N\WXS e955f4973c 邮件管理新增系统相关分角色tab
continuous-integration/drone/push Build is passing
2024-08-06 17:12:31 +08:00
DESKTOP-6C3NK6N\WXS 0b49bd8dab 数据导出模板新增NameCN字段
continuous-integration/drone/push Build is passing
2024-08-06 17:04:48 +08:00
DESKTOP-6C3NK6N\WXS e98e826328 crc临床数据同名文件上传问题
continuous-integration/drone/push Build is passing
2024-08-06 16:31:17 +08:00
DESKTOP-6C3NK6N\WXS 86557af12f 一致性分析按钮权限
continuous-integration/drone/push Build is passing
2024-08-06 15:38:10 +08:00
caiyiling 581ed42ab6 阅片分配列表高度适配更改
continuous-integration/drone/push Build is passing
2024-08-06 10:26:15 +08:00
caiyiling ba17dd4148 阅片报告修改
continuous-integration/drone/push Build is passing
2024-08-05 17:43:34 +08:00
DESKTOP-6C3NK6N\WXS 1ce67efa9b 一致性分析临床数据
continuous-integration/drone/push Build is passing
2024-08-05 17:25:55 +08:00
caiyiling 7e21325fa1 1
continuous-integration/drone/push Build is passing
2024-08-05 16:22:21 +08:00
caiyiling 44f6b11d50 1
continuous-integration/drone/push Build is passing
2024-08-05 15:19:34 +08:00
caiyiling 6e88d2cae2 1
continuous-integration/drone/push Build is running
2024-08-05 15:15:51 +08:00
caiyiling 62f5f5ac38 上传影像页预览补充显示序列信息
continuous-integration/drone/push Build is running
2024-08-05 15:11:16 +08:00
caiyiling ddb5254716 肿瘤学阅片更改
continuous-integration/drone/push Build is passing
2024-08-05 14:28:00 +08:00
caiyiling fcc4820087 系统阅片配置更改
continuous-integration/drone/push Build is passing
2024-08-05 14:22:29 +08:00
DESKTOP-6C3NK6N\WXS a3c7e76267 1
continuous-integration/drone/push Build is passing
2024-08-02 16:20:17 +08:00
DESKTOP-6C3NK6N\WXS c6b38ea528 阅片跟踪反馈按钮调整 2024-08-02 16:19:26 +08:00
caiyiling 8b1679dfc5 项目列表行点击跳转事件添加限制
continuous-integration/drone/push Build is passing
2024-08-02 16:05:17 +08:00
caiyiling 8597e0a7e8 邮件管理样式调整
continuous-integration/drone/push Build is passing
2024-08-02 15:20:47 +08:00
caiyiling f96f8bca91 Merge remote-tracking branch 'origin/uat' into main
continuous-integration/drone/push Build is running
2024-08-02 15:18:54 +08:00
caiyiling f8837d8cef 样式调整
continuous-integration/drone/push Build is passing
2024-08-02 14:41:27 +08:00
caiyiling be3719c0d2 Merge branch 'uat' of https://gitea.frp.extimaging.com/XCKJ/irc_web into uat
continuous-integration/drone/push Build is passing
2024-08-02 14:19:27 +08:00
caiyiling 51e0322f6d 样式调整 2024-08-02 14:19:15 +08:00
DESKTOP-6C3NK6N\WXS 7c379c9566 Merge branch 'uat' of https://gitea.frp.extimaging.com/XCKJ/irc_web into uat
continuous-integration/drone/push Build is running
2024-08-02 14:17:29 +08:00
DESKTOP-6C3NK6N\WXS 38b9e092a4 国际化问题修改 2024-08-02 14:17:17 +08:00
caiyiling 23c0e4e675 Merge branch 'uat' of https://gitea.frp.extimaging.com/XCKJ/irc_web into uat
continuous-integration/drone/push Build is running
2024-08-02 14:10:11 +08:00
caiyiling 0aaa38e751 质控样式调整 2024-08-02 14:09:52 +08:00
DESKTOP-6C3NK6N\WXS ce1bd2df25 国际化问题修改
continuous-integration/drone/push Build is running
2024-08-02 14:08:42 +08:00
DESKTOP-6C3NK6N\WXS d0641cdfc9 PM项目总览反馈记录数量
continuous-integration/drone/push Build is passing
2024-08-02 14:02:44 +08:00
caiyiling ea413ffe0b 影像质控样式调整
continuous-integration/drone/push Build is passing
2024-08-02 14:00:23 +08:00
caiyiling f87935f6f5 审核通过时间查询条件更改
continuous-integration/drone/push Build is passing
2024-08-02 13:44:39 +08:00
DESKTOP-6C3NK6N\WXS 32274c4a37 阅片跟踪问题反馈
continuous-integration/drone/push Build is passing
2024-08-02 13:44:32 +08:00
caiyiling 132af31c1b Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-08-02 13:12:26 +08:00
caiyiling f8c28fc66d Merge remote-tracking branch 'origin/uat' into main 2024-08-02 13:12:11 +08:00
caiyiling 3819f5af0b 影像上传和影像指控页面添加审核完成时间
continuous-integration/drone/push Build is passing
2024-08-02 11:41:50 +08:00
DESKTOP-6C3NK6N\WXS 46bc955e76 推送记录根据项目过滤并且按时间倒序排序
continuous-integration/drone/push Build is passing
2024-08-02 11:16:54 +08:00
DESKTOP-6C3NK6N\WXS 802870f3b4 中心的AE添加时的交互缺陷
continuous-integration/drone/push Build is running
2024-08-02 11:12:06 +08:00
DESKTOP-6C3NK6N\WXS 8a46adf96f 阅片跟踪反馈弹窗添加确认取消
continuous-integration/drone/push Build is passing
2024-08-02 10:40:20 +08:00
DESKTOP-6C3NK6N\WXS 57f470e219 AE的状态测试按钮调整 2024-08-02 10:29:51 +08:00
caiyiling 14cc8ad5f5 影像重传bug修复
continuous-integration/drone/push Build is passing
2024-08-01 17:13:59 +08:00
caiyiling 43bdf0cc19 影像重传bug修复
continuous-integration/drone/push Build is passing
2024-08-01 16:34:07 +08:00
DESKTOP-6C3NK6N\WXS 049d8dc430 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web
continuous-integration/drone/push Build is passing
2024-08-01 16:15:40 +08:00
DESKTOP-6C3NK6N\WXS e0ccfe8da7 意见反馈title 2024-08-01 16:15:27 +08:00
caiyiling c5758b17df 阅片意见反馈
continuous-integration/drone/push Build is passing
2024-08-01 15:58:28 +08:00
caiyiling e485b73e1b Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-08-01 15:47:19 +08:00
caiyiling 91c78127f2 自定义阅片意见反馈 2024-08-01 15:46:36 +08:00
DESKTOP-6C3NK6N\WXS bbfd119d08 意见反馈表格修改
continuous-integration/drone/push Build is passing
2024-08-01 15:40:46 +08:00
caiyiling 32de7c4f18 阅片反馈
continuous-integration/drone/push Build is running
2024-08-01 15:36:09 +08:00
DESKTOP-6C3NK6N\WXS b76303c63d 意见反馈
continuous-integration/drone/push Build is passing
2024-08-01 15:23:58 +08:00
DESKTOP-6C3NK6N\WXS 96cb8a478c 意见反馈添加字段
continuous-integration/drone/push Build is passing
2024-08-01 10:39:54 +08:00
DESKTOP-6C3NK6N\WXS c13fe6b521 意见反馈
continuous-integration/drone/push Build is passing
2024-08-01 09:31:58 +08:00
DESKTOP-6C3NK6N\WXS fc6d0c7b35 添加中心处,数据查询以及人员列表问题修复
continuous-integration/drone/push Build is passing
2024-07-31 16:13:35 +08:00
DESKTOP-6C3NK6N\WXS 0ba8739cb5 dicom签名配置修改
continuous-integration/drone/push Build is passing
2024-07-31 15:16:50 +08:00
DESKTOP-6C3NK6N\WXS aeeb4b05f5 Merge branch 'uat'
continuous-integration/drone/push Build is passing
2024-07-31 14:04:39 +08:00
DESKTOP-6C3NK6N\WXS 8ee3847791 阅片单元表格操作栏宽度加宽
continuous-integration/drone/push Build is passing
2024-07-31 14:04:05 +08:00
DESKTOP-6C3NK6N\WXS c9e99339d5 阅片单元问题配置问题名称中英文问题
continuous-integration/drone/push Build is passing
2024-07-31 13:39:43 +08:00
DESKTOP-6C3NK6N\WXS df304d8f07 阅片单元问题配置问题名称中英文问题
continuous-integration/drone/push Build is passing
2024-07-31 13:35:47 +08:00
DESKTOP-6C3NK6N\WXS 404d18faa5 Merge branch 'uat'
continuous-integration/drone/push Build is passing
2024-07-31 13:24:22 +08:00
DESKTOP-6C3NK6N\WXS e593aedd46 阅片单元问题配置问题名称中英文问题
continuous-integration/drone/push Build is passing
2024-07-31 13:23:56 +08:00
DESKTOP-6C3NK6N\WXS c6c9142934 Merge branch 'uat'
continuous-integration/drone/push Build is passing
2024-07-31 13:11:51 +08:00
DESKTOP-6C3NK6N\WXS 65e4bf94ad 阅片单元问题配置问题名称中英文问题
continuous-integration/drone/push Build is passing
2024-07-31 13:11:13 +08:00
caiyiling 14ad1ae156 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-07-31 11:24:02 +08:00
caiyiling ddd35f4ff8 质控下载影像更改 2024-07-31 11:22:13 +08:00
DESKTOP-6C3NK6N\WXS 275501db20 Merge branch 'uat'
continuous-integration/drone/push Build is passing
2024-07-31 11:18:22 +08:00
DESKTOP-6C3NK6N\WXS e81b7897e7 mfa标题加粗
continuous-integration/drone/push Build is passing
2024-07-31 11:17:56 +08:00
DESKTOP-6C3NK6N\WXS ab65a9f1c7 阅片单元问题配置问题名称中英文问题 2024-07-31 11:17:32 +08:00
caiyiling 7f8d08032c 1
continuous-integration/drone/push Build is passing
2024-07-31 10:53:42 +08:00
DESKTOP-6C3NK6N\WXS c3955dc017 Merge branch 'uat'
continuous-integration/drone/push Build is passing
# Conflicts:
#	src/components/Dicom/DicomCanvas.vue
#	src/main.js
#	src/views/dicom-show/dicom-study.vue
#	src/views/dicom-show/dicom-visit.vue
#	src/views/login/index.vue
#	src/views/trials/trials-panel/reading/dicoms/components/StudyList.vue
#	src/views/trials/trials-panel/reading/dicoms/customize/CustomizeDicomCanvas.vue
#	src/views/trials/trials-panel/reading/dicoms/customize/CustomizeStudyList.vue
2024-07-31 10:23:17 +08:00
DESKTOP-6C3NK6N\WXS 4b6c589881 锁定MFA验证邮箱加密
continuous-integration/drone/push Build is passing
2024-07-31 10:06:54 +08:00
DESKTOP-6C3NK6N\WXS 73a6935fb8 管理后台默认访问页面修改 2024-07-31 10:06:19 +08:00
caiyiling ec96011d4b 多帧样式更改
continuous-integration/drone/push Build is passing
2024-07-30 18:57:07 +08:00
DESKTOP-6C3NK6N\WXS c01c69a9fe 意见反馈
continuous-integration/drone/push Build is passing
2024-07-30 17:47:18 +08:00
caiyiling 750c465b18 医学审核更改
continuous-integration/drone/push Build is passing
2024-07-30 17:04:16 +08:00
caiyiling d1f90a2525 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-07-30 16:59:02 +08:00
caiyiling 4212eb0f52 医学审核查看图片及多帧bug修复 2024-07-30 16:58:33 +08:00
DESKTOP-6C3NK6N\WXS d37c44a268 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web
continuous-integration/drone/push Build is passing
2024-07-30 16:35:17 +08:00
DESKTOP-6C3NK6N\WXS 4c0b219b47 意见反馈 2024-07-30 16:34:59 +08:00
caiyiling db4632fb9b 关键帧渲染问题修复
continuous-integration/drone/push Build is passing
2024-07-30 16:28:11 +08:00
caiyiling 42c1b56dda Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-07-30 15:16:32 +08:00
caiyiling d56b904141 1 2024-07-30 15:16:06 +08:00
caiyiling 1eae9eda28 多帧下载及进度条维护
continuous-integration/drone/push Build is passing
2024-07-30 14:55:59 +08:00
DESKTOP-6C3NK6N\WXS aa5f5f9bc6 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web
continuous-integration/drone/push Build is passing
2024-07-30 14:40:12 +08:00
DESKTOP-6C3NK6N\WXS 8fc6bdb437 部分页面去除中英文转换 2024-07-30 14:39:59 +08:00
caiyiling a7ce5526fd 阅片多帧进度更改
continuous-integration/drone/push Build is passing
2024-07-30 13:56:44 +08:00
DESKTOP-6C3NK6N\WXS fbb41e3fd9 1
continuous-integration/drone/push Build is passing
2024-07-30 13:42:24 +08:00
DESKTOP-6C3NK6N\WXS 7311252d3c Merge branch 'uat' into uat_us 2024-07-30 13:33:09 +08:00
DESKTOP-6C3NK6N\WXS b43202076c ip所在地暂时屏蔽
continuous-integration/drone/push Build is passing
2024-07-30 13:32:17 +08:00
DESKTOP-6C3NK6N\WXS 2e11c881f5 1 2024-07-30 10:43:24 +08:00
caiyiling 4b9118839f 多帧对齐预览
continuous-integration/drone/push Build is passing
2024-07-30 10:42:18 +08:00
DESKTOP-6C3NK6N\WXS 535d30b6df logo调整 2024-07-30 10:18:31 +08:00
caiyiling a533bb680b 切换序列更改
continuous-integration/drone/push Build is passing
2024-07-30 09:58:25 +08:00
DESKTOP-6C3NK6N\WXS be14515286 更改版本号v1.5.4
continuous-integration/drone/push Build is passing
2024-07-30 09:32:22 +08:00
DESKTOP-6C3NK6N\WXS 84a8f6ec75 操作限制相关国际化添加国际化 2024-07-30 09:32:00 +08:00
caiyiling d274c774ba Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-07-30 09:09:39 +08:00
caiyiling a7a034014d 阅片预览进度条更改 2024-07-30 09:09:20 +08:00
DESKTOP-6C3NK6N\WXS e16a02eaff 检查部位修改为文本域
continuous-integration/drone/push Build is passing
2024-07-29 17:35:12 +08:00
DESKTOP-6C3NK6N\WXS 22193bb291 检查部位输入限制提升至500
continuous-integration/drone/push Build is passing
2024-07-29 17:17:22 +08:00
DESKTOP-6C3NK6N\WXS ca98bc278c 意见反馈
continuous-integration/drone/push Build is passing
2024-07-29 17:15:41 +08:00
DESKTOP-6C3NK6N\WXS 03cf2def1b 表格高度调整
continuous-integration/drone/push Build is passing
2024-07-29 16:54:42 +08:00
caiyiling 847845a6c4 多帧对齐更改
continuous-integration/drone/push Build is passing
2024-07-29 11:06:29 +08:00
caiyiling f5ec5505d4 多帧对齐更改
continuous-integration/drone/push Build is passing
2024-07-29 10:46:51 +08:00
DESKTOP-6C3NK6N\WXS 53a9b3882d Merge commit 'fd70c3ee2c41d011a303f6c60083da98119480e5'
continuous-integration/drone/push Build is passing
# Conflicts:
#	src/utils/uploadZip.js
2024-07-26 14:55:43 +08:00
DESKTOP-6C3NK6N\WXS 671be02d13 1
continuous-integration/drone/push Build is running
2024-07-26 14:46:17 +08:00
caiyiling e1b6bec85b dicom预览更改
continuous-integration/drone/push Build is passing
2024-07-26 14:42:51 +08:00
caiyiling 8b6714806e dicom预览更改
continuous-integration/drone/push Build is passing
2024-07-26 13:21:12 +08:00
caiyiling 16581bd7b9 预览更改
continuous-integration/drone/push Build is passing
2024-07-26 11:41:30 +08:00
DESKTOP-6C3NK6N\WXS d1956e3077 系统相关邮件添加默认值修改
continuous-integration/drone/push Build is failing
2024-07-26 11:28:39 +08:00
DESKTOP-6C3NK6N\WXS 9486054a19 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web
continuous-integration/drone/push Build is failing
2024-07-26 10:58:45 +08:00
DESKTOP-6C3NK6N\WXS cd3f36756d 邮件管理新增系统相关 2024-07-26 10:58:30 +08:00
caiyiling 057d23d34b 依赖包更新
continuous-integration/drone/push Build is failing
2024-07-26 10:39:49 +08:00
caiyiling bea2d448ea Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is failing
2024-07-26 10:38:23 +08:00
caiyiling b9b62334c4 dicom预览更改 2024-07-26 10:37:48 +08:00
DESKTOP-6C3NK6N\WXS 8cf5a1a524 检查部位配置修改
continuous-integration/drone/push Build is passing
2024-07-25 17:02:47 +08:00
DESKTOP-6C3NK6N\WXS 47fc6c5ef0 mfa国际化修改 2024-07-25 14:54:41 +08:00
caiyiling fd70c3ee2c 1
continuous-integration/drone/push Build is passing
2024-07-25 14:19:56 +08:00
caiyiling de638b1436 同意重阅申请更改
continuous-integration/drone/push Build is passing
2024-07-25 14:08:50 +08:00
caiyiling ca18abe26e 重阅跟踪--审批结果新增状态
continuous-integration/drone/push Build is passing
2024-07-25 13:44:38 +08:00
DESKTOP-6C3NK6N\WXS 02a5f30224 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web
continuous-integration/drone/push Build is passing
2024-07-25 09:35:39 +08:00
DESKTOP-6C3NK6N\WXS 8933a398d7 医学审核修改 2024-07-25 09:35:23 +08:00
caiyiling a71c6e92dc 阅片配置更改及影像上传页面预览规则更改
continuous-integration/drone/push Build is passing
2024-07-25 09:06:53 +08:00
DESKTOP-6C3NK6N\WXS 80c0bfb694 医学审核查询条件修改
continuous-integration/drone/push Build is passing
2024-07-24 15:06:57 +08:00
DESKTOP-6C3NK6N\WXS 426faba24c 配置取消按钮数据重置、检查部位编辑问题
continuous-integration/drone/push Build is passing
2024-07-24 14:29:37 +08:00
DESKTOP-6C3NK6N\WXS a0eaf2f64a 美国uat发布 2024-07-24 13:10:42 +08:00
DESKTOP-6C3NK6N\WXS c6cc83aeec 意见反馈按钮
continuous-integration/drone/push Build is passing
2024-07-24 10:19:24 +08:00
DESKTOP-6C3NK6N\WXS 46f66ce2d2 独立阅片人去掉中文姓名
continuous-integration/drone/push Build is passing
2024-07-23 15:59:11 +08:00
DESKTOP-6C3NK6N\WXS 35846365a4 dicom配置修改对比标红 2024-07-23 15:58:35 +08:00
DESKTOP-6C3NK6N\WXS 90e33e1b97 pacs直连、检查查询条件新增
continuous-integration/drone/push Build is passing
2024-07-23 11:13:20 +08:00
DESKTOP-6C3NK6N\WXS 9b6f8717c3 pacs新增列表刷新
continuous-integration/drone/push Build is passing
2024-07-23 10:21:42 +08:00
DESKTOP-6C3NK6N\WXS 65da9636a2 影像检查预览影像
continuous-integration/drone/push Build is passing
2024-07-22 18:02:51 +08:00
DESKTOP-6C3NK6N\WXS 9a1b28e08c 项目配置获取部分页面排除 2024-07-22 18:02:26 +08:00
DESKTOP-6C3NK6N\WXS 94ca89db27 指控下载提示修改 2024-07-22 18:02:00 +08:00
DESKTOP-6C3NK6N\WXS b786c5e656 pacs直连
continuous-integration/drone/push Build is passing
2024-07-22 14:42:33 +08:00
DESKTOP-6C3NK6N\WXS f32abfe230 1 2024-07-19 14:34:21 +08:00
DESKTOP-6C3NK6N\WXS 3f5092bcbb 1 2024-07-19 13:28:43 +08:00
DESKTOP-6C3NK6N\WXS f0e6c5b9de Merge branch 'uat' into uat_us 2024-07-19 13:24:35 +08:00
hang 0a880af52f 修改自动打包配置
continuous-integration/drone/push Build is passing
2024-07-19 11:46:21 +08:00
hang 089d8668f2 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-07-19 11:45:03 +08:00
hang a1dab30d37 增加打包配置 2024-07-19 11:44:42 +08:00
caiyiling 32a7e42c51 阅片标准配置更改 2024-07-19 11:36:23 +08:00
DESKTOP-6C3NK6N\WXS 16b6f5f8b1 上传监控修复、非dicom上传和指控下载排除自动登出
continuous-integration/drone/push Build was killed
2024-07-19 10:14:20 +08:00
caiyiling 1a69bd9003 非dicom阅片添加跳过及国际化 2024-07-19 10:11:33 +08:00
caiyiling b37e351491 全局裁判肿瘤学阅片更改 2024-07-18 17:56:02 +08:00
caiyiling c74806a367 自定义标准更改 2024-07-18 17:16:54 +08:00
caiyiling b637fc5856 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-07-18 17:04:48 +08:00
caiyiling de18b8e6e3 阅片更改 2024-07-18 17:04:26 +08:00
wangxiaoshuang 31d3a17b80 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-07-18 15:14:14 +08:00
wangxiaoshuang a0bbb7b64c pacs添加 2024-07-18 15:14:02 +08:00
caiyiling a8bebaba49 1 2024-07-18 14:46:41 +08:00
caiyiling 403008c25f 自定义标准添加重置功能 2024-07-18 14:45:14 +08:00
caiyiling 52ed67850d 阅片报告页修改 2024-07-18 13:46:55 +08:00
caiyiling dfd0b1a767 lugano部分问题显示上一访视任务阅片信息 2024-07-18 11:44:00 +08:00
caiyiling ced87c29c9 1 2024-07-18 11:15:39 +08:00
caiyiling 5e14615176 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-07-18 11:14:36 +08:00
caiyiling 65b9cff361 Lugano标准添加重置功能 2024-07-18 11:14:01 +08:00
wangxiaoshuang 862dcb1b3d 1 2024-07-18 09:07:39 +08:00
wangxiaoshuang 3a02e9a596 Merge branch 'uat'
# Conflicts:
#	src/utils/uploadZip.js
#	src/views/login/index.vue
2024-07-18 09:05:12 +08:00
wangxiaoshuang 04bd72e90f 下载问题修复
continuous-integration/drone/push Build is passing
2024-07-17 19:30:26 +08:00
wangxiaoshuang d7fcd79cb2 下载问题修复
continuous-integration/drone/push Build is passing
2024-07-17 19:16:42 +08:00
caiyiling af586a1187 PCWG标准更改 2024-07-17 18:11:00 +08:00
caiyiling 39a0c8163f RecistBM更改 2024-07-17 17:46:19 +08:00
wangxiaoshuang bebd4c4aa0 重复下载提示
continuous-integration/drone/push Build is passing
2024-07-17 17:36:52 +08:00
caiyiling da0dabecca RecistBM标准更改 2024-07-17 17:31:27 +08:00
wangxiaoshuang 81506cc337 下载文件改名
continuous-integration/drone/push Build is passing
2024-07-17 16:49:39 +08:00
wangxiaoshuang 75efdcf0f7 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-07-17 15:58:45 +08:00
wangxiaoshuang bc674ec334 pacs 2024-07-17 15:58:41 +08:00
caiyiling 663c78ef51 iRecist和Recist阅片标准更改 2024-07-17 15:13:55 +08:00
caiyiling 13f105faa5 Merge branch 'uat' of https://gitea.frp.extimaging.com/XCKJ/irc_web into uat
continuous-integration/drone/push Build is passing
2024-07-17 14:59:51 +08:00
caiyiling 32ded49982 裁判阅片及医学审核预览图片问题修复 2024-07-17 14:59:10 +08:00
wangxiaoshuang 3ae982d422 国际化修改 2024-07-17 13:35:18 +08:00
wangxiaoshuang 05ab287e81 修改版本号
continuous-integration/drone/push Build is passing
2024-07-17 13:05:32 +08:00
wangxiaoshuang b8b876c0c9 Merge branch 'uat_us' 2024-07-17 11:16:56 +08:00
wangxiaoshuang 978aacf085 非dicom阅片国际化修改 2024-07-17 11:16:38 +08:00
wangxiaoshuang 24e7b30b7e 合并分支 2024-07-17 10:15:53 +08:00
wangxiaoshuang ba1ba68c78 Merge branch 'uat'
# Conflicts:
#	src/api/trials.js
#	src/permission.js
#	src/utils/uploadZip.js
#	src/views/login/index.vue
2024-07-17 10:14:54 +08:00
wangxiaoshuang e51e7d0e66 pacs
continuous-integration/drone/push Build is passing
2024-07-17 10:09:26 +08:00
caiyiling de16944fd6 Merge branch 'uat' of https://gitea.frp.extimaging.com/XCKJ/irc_web into uat
continuous-integration/drone/push Build is passing
2024-07-16 11:22:33 +08:00
caiyiling be96158a73 医学审核更改 2024-07-16 11:22:18 +08:00
wangxiaoshuang 5368538d52 Merge branch 'uat' of https://gitea.frp.extimaging.com/XCKJ/irc_web into uat
continuous-integration/drone/push Build is running
2024-07-16 11:17:35 +08:00
wangxiaoshuang 4a659fdde4 bug调试 2024-07-16 11:17:25 +08:00
caiyiling 198e580288 Merge branch 'uat' of https://gitea.frp.extimaging.com/XCKJ/irc_web into uat
continuous-integration/drone/push Build is passing
2024-07-16 10:41:09 +08:00
caiyiling 3ada3585e5 裁判阅片修改 2024-07-16 10:39:42 +08:00
wangxiaoshuang 38ce7c1f56 bug调试
continuous-integration/drone/push Build is passing
2024-07-16 10:25:44 +08:00
wangxiaoshuang afb1d17853 bug调试
continuous-integration/drone/push Build is passing
2024-07-16 10:14:52 +08:00
wangxiaoshuang 01c2a29085 bug调试
continuous-integration/drone/push Build is passing
2024-07-16 09:58:26 +08:00
wangxiaoshuang c94abac896 iqc下载文件
continuous-integration/drone/push Build is passing
2024-07-15 17:00:58 +08:00
wangxiaoshuang 7f36aa5a05 中心调查表链接添加二维码
continuous-integration/drone/push Build is passing
2024-07-15 15:52:47 +08:00
caiyiling fd0679dbd8 阅片添加跳过当前任务功能
continuous-integration/drone/push Build is passing
2024-07-15 14:50:50 +08:00
wangxiaoshuang 67ceadcc9c 登录日志访问ip屏蔽 2024-07-15 13:48:36 +08:00
wangxiaoshuang 6137d9deff 1
continuous-integration/drone/push Build is passing
2024-07-15 13:06:07 +08:00
wangxiaoshuang 8a4674452f 美国环境修改
continuous-integration/drone/push Build is passing
2024-07-12 18:07:31 +08:00
hang a78195fbca uat 分支自动打包测试
continuous-integration/drone/push Build is passing
2024-07-12 15:43:41 +08:00
wangxiaoshuang e45903d55e 重阅跟踪添加国际化
continuous-integration/drone/push Build is passing
2024-07-12 10:25:46 +08:00
wangxiaoshuang 1a139af448 美国环境修改 2024-07-12 10:21:03 +08:00
wangxiaoshuang 02e82bba33 1
continuous-integration/drone/push Build is passing
2024-07-10 10:55:56 +08:00
wangxiaoshuang 3d3e6a3db0 Merge branch 'uat'
continuous-integration/drone/push Build is passing
# Conflicts:
#	src/views/login/index.vue
2024-07-10 09:53:28 +08:00
wangxiaoshuang ee846d7370 usa更换logo 2024-07-10 09:52:11 +08:00
wangxiaoshuang 6e2b7cb76a usa环境logo变更
continuous-integration/drone/push Build is passing
2024-07-10 09:07:03 +08:00
wangxiaoshuang ca2ed72a6f usa更换logo
continuous-integration/drone/push Build is passing
2024-07-09 17:17:53 +08:00
wangxiaoshuang c2e2f65434 项目配置增加diicomAE配置
continuous-integration/drone/push Build is passing
2024-07-09 16:40:07 +08:00
caiyiling d2fc9ad981 提交调研表逻辑更改
continuous-integration/drone/push Build is passing
2024-07-09 16:27:33 +08:00
caiyiling c2083e9c9c Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-07-08 17:45:35 +08:00
caiyiling d118f6461f 1 2024-07-08 17:45:26 +08:00
wangxiaoshuang 13d968c5b9 中心配置中心添加dicomAE
continuous-integration/drone/push Build is passing
2024-07-08 16:56:40 +08:00
wangxiaoshuang 65f0af06ad Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web
continuous-integration/drone/push Build is passing
2024-07-08 13:55:15 +08:00
wangxiaoshuang 49a93d0188 管理后台角色添加国际化 2024-07-08 13:55:05 +08:00
caiyiling de832afac8 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-07-08 13:13:19 +08:00
caiyiling c4381a0eb2 中心调研表样式更改 2024-07-08 13:12:22 +08:00
wangxiaoshuang 17c796bd53 管理平台菜单页新增国际化
continuous-integration/drone/push Build is passing
2024-07-08 11:43:26 +08:00
caiyiling 9ce1e569eb 样式调整
continuous-integration/drone/push Build is passing
2024-07-05 16:10:55 +08:00
caiyiling 8b48f5fe2e 样式调整
continuous-integration/drone/push Build is passing
2024-07-05 16:05:59 +08:00
caiyiling 98af1e7540 1
continuous-integration/drone/push Build is passing
2024-07-05 15:57:40 +08:00
caiyiling ed027781c4 表单样式调整
continuous-integration/drone/push Build is running
2024-07-05 15:53:01 +08:00
caiyiling dd20a93523 表单样式调整
continuous-integration/drone/push Build is running
2024-07-05 15:49:50 +08:00
caiyiling ba5e9f82b7 移动端调研表操作功能添加权限控制
continuous-integration/drone/push Build is passing
2024-07-05 15:40:26 +08:00
caiyiling 5af5954f2a 表单样式调整
continuous-integration/drone/push Build is passing
2024-07-05 15:36:19 +08:00
caiyiling 9e1dbda53c 国际化补充
continuous-integration/drone/push Build is passing
2024-07-05 15:08:44 +08:00
caiyiling 3aa521229f 中心调研表登录页面优化
continuous-integration/drone/push Build is running
2024-07-05 15:07:07 +08:00
caiyiling cd1735eae8 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-07-05 15:00:06 +08:00
caiyiling 29dfe79acd 中心调研表功能完善 2024-07-05 14:59:05 +08:00
wangxiaoshuang 885af6d195 国际化修改
continuous-integration/drone/push Build is passing
2024-07-05 14:38:40 +08:00
wangxiaoshuang 98fe1f0365 下载功能暂时屏蔽
continuous-integration/drone/push Build is passing
2024-07-05 11:39:29 +08:00
wangxiaoshuang 74e86cbdbe Merge branch 'uat'
continuous-integration/drone/push Build is passing
# Conflicts:
#	src/views/login/index.vue
2024-07-05 10:21:53 +08:00
wangxiaoshuang ed0dacccbb 定时锁屏、退出问题修复 2024-07-05 10:18:16 +08:00
wangxiaoshuang 6b06d2a5f0 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web
continuous-integration/drone/push Build is failing
2024-07-05 09:09:53 +08:00
wangxiaoshuang 6250e957f0 上传方式修改 2024-07-05 09:09:40 +08:00
caiyiling 9cb9478848 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-07-04 18:01:04 +08:00
caiyiling bd9ecf13e9 调研表布局调整 2024-07-04 18:00:47 +08:00
wangxiaoshuang fe67ef0189 浏览器推荐版本更改
continuous-integration/drone/push Build is running
2024-07-04 18:00:22 +08:00
caiyiling 7283c5a5a1 中心调研登录跳转
continuous-integration/drone/push Build is passing
2024-07-04 17:33:22 +08:00
caiyiling 4d224c115d 根据用户访问设备跳转不同的中心调研表登录页面
continuous-integration/drone/push Build is running
2024-07-04 17:28:27 +08:00
caiyiling b717530ae3 中心调研表移动端页面布局调整
continuous-integration/drone/push Build is passing
2024-07-04 17:14:34 +08:00
caiyiling 66e5380fce Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-07-04 11:45:23 +08:00
wangxiaoshuang 9f73ae7e31 1
continuous-integration/drone/push Build is running
2024-07-04 11:45:10 +08:00
caiyiling 8876d24054 阅片页面功能优化 2024-07-04 11:45:03 +08:00
wangxiaoshuang d5084e411b 浏览器推荐版本弹框
continuous-integration/drone/push Build is passing
2024-07-03 14:26:34 +08:00
wangxiaoshuang cf7c7cbbc1 Merge branch 'uat'
continuous-integration/drone/push Build is passing
# Conflicts:
#	src/views/login/index.vue
#	src/views/trials/trials-layout/components/trialsNavbar.vue
#	src/views/trials/trials-panel/reading/dicoms/components/DicomCanvas.vue
#	src/views/trials/trials-panel/reading/dicoms/customize/CustomizeDicomCanvas.vue
#	src/views/trials/trials-panel/reading/dicoms/customize/CustomizeDicomViewer.vue
2024-07-03 13:29:35 +08:00
wangxiaoshuang 0dd6ace8c1 美国环境发布 2024-07-03 11:46:58 +08:00
caiyiling 4135349bfa 检查列表bug修复 2024-07-03 10:40:36 +08:00
wangxiaoshuang ac272d1e94 版本推荐列表字段修改
continuous-integration/drone/push Build is failing
2024-07-03 10:00:14 +08:00
caiyiling 98b126f630 邮件管理默认配置值更改 2024-07-02 17:23:44 +08:00
wangxiaoshuang 6a59ed80e2 1
continuous-integration/drone/push Build is failing
2024-07-02 15:57:15 +08:00
wangxiaoshuang d0cefb09df 推荐版本记录删除 2024-07-02 14:42:05 +08:00
wangxiaoshuang 4c241b9acd 管理后台新增浏览器版本推荐
continuous-integration/drone/push Build is failing
2024-07-02 14:40:24 +08:00
caiyiling 5ccaf1acc1 自定义标准阅片bug修复 2024-07-02 14:27:47 +08:00
caiyiling a9def7e6ae 阅片完成后,限制已入库的标注数据不做删除 2024-07-01 17:04:26 +08:00
caiyiling f9d81aa726 自定义阅片完成后,后续可继续在阅片页面添加临时标注 2024-07-01 16:19:55 +08:00
wangxiaoshuang e265b0c2af pm新增的部位,支持编辑
continuous-integration/drone/push Build is failing
2024-07-01 15:12:38 +08:00
wangxiaoshuang 2f549846ba 临床数据上传列表添加文件大小字段
continuous-integration/drone/push Build is passing
2024-07-01 14:07:40 +08:00
wangxiaoshuang d9f10055aa 邮箱管理发件邮箱配置清除默认值
continuous-integration/drone/push Build is passing
2024-07-01 11:06:47 +08:00
wangxiaoshuang 19c2c4eecb 影像上传不记入用户锁定和用户退出
continuous-integration/drone/push Build is passing
2024-07-01 11:01:33 +08:00
wangxiaoshuang b3bff41d35 系统标准配置全局阅片、肿瘤学阅片时,没有字段
continuous-integration/drone/push Build is passing
2024-06-28 16:05:03 +08:00
wangxiaoshuang 0eb1289cf0 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web
continuous-integration/drone/push Build is passing
2024-06-28 15:58:50 +08:00
wangxiaoshuang 5048f040cc zyss、zybs去除我的项目tab 2024-06-28 15:58:39 +08:00
caiyiling 62d7315401 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-06-28 15:40:28 +08:00
caiyiling 13b083d2df 阅片页面添加多帧影像标记渲染 2024-06-28 15:39:30 +08:00
wangxiaoshuang 712d2cc89b 自定义独立阅片人的证书pdf浏览方式修改为pdfjs
continuous-integration/drone/push Build is passing
2024-06-28 15:33:09 +08:00
wangxiaoshuang 9795f89ce9 定时锁定功能问题修复
continuous-integration/drone/push Build is passing
2024-06-28 15:21:18 +08:00
wangxiaoshuang 4eb9c2ff85 定时锁定功能问题修复
continuous-integration/drone/push Build is passing
2024-06-28 15:10:50 +08:00
wangxiaoshuang d5f1ecbb04 定时锁定功能问题修复
continuous-integration/drone/push Build is running
2024-06-28 15:08:19 +08:00
wangxiaoshuang a53fc5478b 临床数据上传流程优化 2024-06-28 15:07:57 +08:00
caiyiling 3ab5c46455 签署文档优化
continuous-integration/drone/push Build is passing
2024-06-28 11:38:23 +08:00
caiyiling c37332e8e2 CRC回复影像质疑,增加自动进入下一任务
continuous-integration/drone/push Build is passing
2024-06-28 10:31:49 +08:00
caiyiling 79cc39918e Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-06-27 16:43:32 +08:00
caiyiling ccac950bcf 医学反馈bug修复 2024-06-27 16:43:01 +08:00
wangxiaoshuang e0b095ebc9 登录页版本信息改为后端获取
continuous-integration/drone/push Build is running
2024-06-27 16:41:46 +08:00
wangxiaoshuang 898f6ed8f7 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web
continuous-integration/drone/push Build is passing
2024-06-27 16:25:23 +08:00
wangxiaoshuang ced1be74b3 国家化新增模块、迭代字段,提供批量更新 2024-06-27 16:25:18 +08:00
caiyiling e6926382fd IR医学反馈添加自动跳转下一任务
continuous-integration/drone/push Build is passing
2024-06-27 16:17:05 +08:00
wangxiaoshuang 59f27b9d35 版本记录字段顺序调整
continuous-integration/drone/push Build is passing
2024-06-27 15:22:22 +08:00
wangxiaoshuang 12449e0ca0 版本记录新增发布状态和是否当前版本字段
continuous-integration/drone/push Build is passing
2024-06-27 15:16:48 +08:00
wangxiaoshuang 3b745051eb 临床数据、IQC问题、医学问题国际化问题修改
continuous-integration/drone/push Build is passing
2024-06-27 14:02:01 +08:00
wangxiaoshuang 81c21c995d usa环境软件名称变更图片
continuous-integration/drone/push Build is passing
2024-06-27 13:21:03 +08:00
wangxiaoshuang 8f8c5d0744 Merge branch 'main' into uat
# Conflicts:
#	.env.usa
#	src/views/dicom-show/dicom-study.vue
#	src/views/login/index.vue
#	src/views/trials/trials-panel/reading/dicoms/components/ReportPage.vue
#	src/views/trials/trials-panel/reading/dicoms/customize/CustomizeDicomCanvas.vue
#	vue.config.js
2024-06-27 09:49:55 +08:00
wangxiaoshuang a2ffa87056 软件名称变更图片测试
continuous-integration/drone/push Build is passing
2024-06-27 09:44:13 +08:00
caiyiling 5133f9e3d7 dcmjs关闭长度校验
continuous-integration/drone/push Build is passing
2024-06-26 17:54:38 +08:00
wangxiaoshuang bb6bf409b7 文件上传失败检测
continuous-integration/drone/push Build is passing
2024-06-26 17:14:25 +08:00
wangxiaoshuang 64a0e68448 usa环境软件标题修改
continuous-integration/drone/push Build is passing
2024-06-26 13:37:55 +08:00
wangxiaoshuang fa6c552149 usa环境logo大小变更
continuous-integration/drone/push Build is passing
2024-06-25 13:20:49 +08:00
wangxiaoshuang 074c302077 usa环境更换logo
continuous-integration/drone/push Build is passing
2024-06-25 13:11:51 +08:00
wangxiaoshuang 8800ddb0a0 无spm/cpm时跳过审核
continuous-integration/drone/push Build is passing
2024-06-25 10:34:20 +08:00
caiyiling 2ee3ff0a7c 临床数据受试者信息根据配置控制显示
continuous-integration/drone/push Build is passing
2024-06-20 15:16:32 +08:00
caiyiling 3a09caa43b 获取非dicom文件api默认值更改
continuous-integration/drone/push Build is passing
2024-06-19 18:53:13 +08:00
caiyiling b0277d0ccf 部位信息显示异常修复
continuous-integration/drone/push Build is running
2024-06-19 18:50:01 +08:00
caiyiling 179d030f76 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-06-19 18:16:26 +08:00
caiyiling 8ebf10b373 非dicom阅片更改 2024-06-19 18:15:55 +08:00
wangxiaoshuang 3eb5094c3e zip默认图片替换
continuous-integration/drone/push Build is passing
2024-06-19 17:44:07 +08:00
wangxiaoshuang a27c6f6f18 zip默认图片替换
continuous-integration/drone/push Build is passing
2024-06-19 17:34:32 +08:00
wangxiaoshuang 03f4a7b63b 影像质控zip文件预览按钮置灰
continuous-integration/drone/push Build is passing
2024-06-19 17:27:26 +08:00
wangxiaoshuang f7b99c23aa 非dicom影像上传操作限制
continuous-integration/drone/push Build is passing
2024-06-19 17:20:25 +08:00
wangxiaoshuang 8e554bbeb8 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web
continuous-integration/drone/push Build is passing
2024-06-19 16:50:08 +08:00
wangxiaoshuang 8e5e2a0714 zip文件预览默认图像 2024-06-19 16:49:43 +08:00
wangxiaoshuang a15e908e76 时间格式处理 2024-06-19 16:49:26 +08:00
caiyiling a980f6ca58 时间选择器格式化
continuous-integration/drone/push Build is passing
2024-06-19 16:39:24 +08:00
caiyiling f89f0de740 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is running
2024-06-19 16:36:31 +08:00
caiyiling 7e54379ad3 用户列表时间格式化 2024-06-19 16:36:16 +08:00
wangxiaoshuang 5336bfd709 1
continuous-integration/drone/push Build is running
2024-06-19 16:34:25 +08:00
wangxiaoshuang c6092358d8 版本记录添加排序
continuous-integration/drone/push Build is passing
2024-06-19 15:25:22 +08:00
wangxiaoshuang da29f743cd 非DICOM影像上传 2024-06-19 15:25:00 +08:00
wangxiaoshuang 422a1cd63d 医学审核审核结论添加判断条件
continuous-integration/drone/push Build is passing
2024-06-18 17:15:13 +08:00
wangxiaoshuang 7c09594c4d 医学审核审核结论添加判断条件
continuous-integration/drone/push Build is passing
2024-06-18 14:41:35 +08:00
caiyiling ca3a6122be 列表优化
continuous-integration/drone/push Build is passing
2024-06-18 11:18:41 +08:00
caiyiling d6bb1fcb5a Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-06-18 11:07:20 +08:00
caiyiling 602f971309 中心调研扫描设备类型更改 2024-06-18 11:06:52 +08:00
wangxiaoshuang 1c21479c82 版本记录新增日期格式化
continuous-integration/drone/push Build is passing
2024-06-17 17:49:16 +08:00
caiyiling 9d81fa9251 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-06-17 17:03:58 +08:00
caiyiling b9ee682ace 多帧图像旋转异常修复 2024-06-17 17:03:32 +08:00
wangxiaoshuang 6d37838654 检查部位单表单回车提交问题
continuous-integration/drone/push Build is passing
2024-06-17 16:17:33 +08:00
wangxiaoshuang 8a5eaff5f6 国际化英文换行问题
continuous-integration/drone/push Build is passing
2024-06-17 15:02:15 +08:00
wangxiaoshuang 5967fd19b2 MFA配置
continuous-integration/drone/push Build is passing
2024-06-17 14:55:49 +08:00
wangxiaoshuang e3af442b8f 阅片规则影像筛选选项顺序调整
continuous-integration/drone/push Build is passing
2024-06-17 12:23:35 +08:00
wangxiaoshuang cfb54d9c9c mfa国际化
continuous-integration/drone/push Build is passing
2024-06-17 10:50:33 +08:00
caiyiling 43d87e612a Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-06-14 18:00:07 +08:00
caiyiling 8f1d46f113 随机阅片页面受试者编号显示 2024-06-14 17:59:39 +08:00
wangxiaoshuang 10283bbceb 上传dicom文件处理
continuous-integration/drone/push Build is passing
2024-06-14 16:26:51 +08:00
wangxiaoshuang 10a2238cba 重传临床数据取消基线限制
continuous-integration/drone/push Build is passing
2024-06-14 16:12:04 +08:00
wangxiaoshuang 6db7229cb2 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web
continuous-integration/drone/push Build is passing
2024-06-14 15:59:11 +08:00
wangxiaoshuang c80c8c0a16 重传临床数据取消基线限制 2024-06-14 15:58:59 +08:00
caiyiling 06d3026207 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is running
2024-06-14 15:56:04 +08:00
caiyiling ac37818caf 中心调研表-设备调研Modality下拉框更改 2024-06-14 15:55:25 +08:00
wangxiaoshuang 408d42f6b8 影像筛选全标准可用
continuous-integration/drone/push Build is passing
2024-06-14 15:20:20 +08:00
wangxiaoshuang ac1f5c6628 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web
continuous-integration/drone/push Build is passing
2024-06-14 15:14:14 +08:00
wangxiaoshuang e3ab23f20c 上传、下载影像 2024-06-14 15:14:03 +08:00
caiyiling 111dd526d9 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-06-14 14:44:36 +08:00
caiyiling 14238b6556 验证码发送提示 2024-06-14 14:44:20 +08:00
wangxiaoshuang 736a4eea18 检查技术中英文切换
continuous-integration/drone/push Build is passing
2024-06-14 13:26:56 +08:00
caiyiling 46b2744bc3 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is running
2024-06-14 13:23:38 +08:00
caiyiling 5738687f06 中心调研登录页面发送验证码提醒 2024-06-14 13:23:08 +08:00
wangxiaoshuang b5b0d24c97 检查部位中英文切换
continuous-integration/drone/push Build is passing
2024-06-14 13:04:20 +08:00
wangxiaoshuang 183723370a Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web
continuous-integration/drone/push Build is passing
2024-06-14 11:09:31 +08:00
wangxiaoshuang b2dc406a72 二次验证添加参数区分登录解锁 2024-06-14 11:09:27 +08:00
caiyiling 7d37fdc3c0 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-06-14 10:54:54 +08:00
caiyiling 00e44f36e2 中心调研-设备调研配置更改 2024-06-14 10:54:19 +08:00
wangxiaoshuang 4058bddd21 qc排除为空的临床数据
continuous-integration/drone/push Build is passing
2024-06-14 10:49:16 +08:00
caiyiling 16f0d72917 中心调研调整
continuous-integration/drone/push Build is passing
2024-06-14 10:42:52 +08:00
caiyiling d429f00733 列表优化
continuous-integration/drone/push Build is passing
2024-06-13 14:55:16 +08:00
caiyiling b7413c31b7 重阅列表优化
continuous-integration/drone/push Build is passing
2024-06-13 14:50:35 +08:00
caiyiling d3645a808a Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-06-13 13:20:09 +08:00
caiyiling 4b3ef5c7a5 列表优化 2024-06-13 13:19:54 +08:00
wangxiaoshuang 2ea9786626 重置密码页面修改
continuous-integration/drone/push Build is passing
2024-06-13 13:02:50 +08:00
wangxiaoshuang fcc79b0c65 重置密码页面修改
continuous-integration/drone/push Build is passing
2024-06-13 10:04:35 +08:00
wangxiaoshuang 0963441235 二次验证弹框样式更改
continuous-integration/drone/push Build is passing
2024-06-12 14:50:38 +08:00
wangxiaoshuang a6475baee9 阅片规则约束关系
continuous-integration/drone/push Build is passing
2024-06-12 14:28:48 +08:00
wangxiaoshuang be972c6fe8 裁判规则变更 2024-06-12 14:28:02 +08:00
wangxiaoshuang c2607041ff 锁定二次校验区分环境 2024-06-12 14:27:39 +08:00
wangxiaoshuang 28297aa9ba 登录及锁定添加二次验证
continuous-integration/drone/push Build is passing
2024-06-12 11:34:31 +08:00
wangxiaoshuang d4c5c517fb 下载列表添加标准id
continuous-integration/drone/push Build is passing
2024-06-12 11:04:13 +08:00
caiyiling d91a24c154 自定义阅片切换bug
continuous-integration/drone/push Build is passing
2024-06-12 10:27:52 +08:00
caiyiling a3b9cb7469 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-06-11 18:04:33 +08:00
caiyiling 134fba1e77 播放速度默认值更改 2024-06-11 18:04:11 +08:00
wangxiaoshuang fff5a0fcf5 系统新增项目中心转变为系统中心
continuous-integration/drone/push Build is passing
2024-06-07 16:05:47 +08:00
wangxiaoshuang eaba3520e9 检查部位字典变更
continuous-integration/drone/push Build is passing
2024-06-07 15:09:27 +08:00
wangxiaoshuang 4c98f91677 中心列表展示字段变更
continuous-integration/drone/push Build is passing
2024-06-07 13:42:42 +08:00
wangxiaoshuang 11b1e92488 cro、sponsor新增编辑字数限制修改
continuous-integration/drone/push Build is running
2024-06-07 13:39:46 +08:00
wangxiaoshuang c863eaac3d 检查技术选框样式变更、选项添加title 2024-06-07 13:39:03 +08:00
wangxiaoshuang 1a24217cd6 中心是否启用按钮状态变更
continuous-integration/drone/push Build is passing
2024-06-07 11:46:14 +08:00
wangxiaoshuang ac05f74980 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web
continuous-integration/drone/push Build is passing
2024-06-07 10:12:16 +08:00
wangxiaoshuang 01cb109448 cro、申办方编辑添加校验 2024-06-07 10:12:04 +08:00
caiyiling 7d2f95cba5 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is running
2024-06-07 10:11:03 +08:00
caiyiling 5975a414d2 自定义阅片bug修复 2024-06-07 10:10:31 +08:00
wangxiaoshuang e5efbf7448 检查技术搜索添加大小写转换
continuous-integration/drone/push Build is passing
2024-06-07 09:32:18 +08:00
wangxiaoshuang f9e62fe21b 人员中心管理添加中心修改
continuous-integration/drone/push Build is passing
2024-06-06 18:05:21 +08:00
wangxiaoshuang 30ff00fc84 配置检查技术添加描述
continuous-integration/drone/push Build is passing
2024-06-06 16:11:34 +08:00
wangxiaoshuang 23e55e612f 配置检查技术更改为穿梭框
continuous-integration/drone/push Build is passing
2024-06-06 15:27:26 +08:00
caiyiling ee090e995c Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-06-06 14:58:56 +08:00
caiyiling bed03a67d8 部分列表受试者编号显示更改 2024-06-06 14:58:35 +08:00
wangxiaoshuang dfbd7a7a06 预览文件全局方法注册
continuous-integration/drone/push Build is passing
2024-06-06 14:47:08 +08:00
wangxiaoshuang 17a4585a52 【项目信息】有异常的灰色背景
continuous-integration/drone/push Build is running
2024-06-06 14:45:17 +08:00
caiyiling e3e7203b1a 上传监控列表隐藏部分字段
continuous-integration/drone/push Build is passing
2024-06-06 14:17:09 +08:00
caiyiling a3f5cdb445 列表关键标识补充说明
continuous-integration/drone/push Build is passing
2024-06-06 13:56:17 +08:00
wangxiaoshuang b9163c18f1 自定义阅片页添加上传下载按钮
continuous-integration/drone/push Build is passing
2024-06-06 11:04:18 +08:00
caiyiling 5b2a3ecc54 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-06-06 09:45:03 +08:00
caiyiling 06a91499ef 稽查列表去除备注排序 2024-06-06 09:44:39 +08:00
wangxiaoshuang 28fd6a2c71 新增申办方cro接口添加字段trialId
continuous-integration/drone/push Build is running
2024-06-06 09:41:52 +08:00
wangxiaoshuang 2de65e4c1d cro获取错误问题修复
continuous-integration/drone/push Build is passing
2024-06-06 09:21:29 +08:00
wangxiaoshuang 663faba14d 新增申办方cro参数错误修改
continuous-integration/drone/push Build is passing
2024-06-06 09:13:36 +08:00
wangxiaoshuang 93b0621ba1 检查部位读取方式变更
continuous-integration/drone/push Build is passing
2024-06-05 17:52:13 +08:00
caiyiling e1dfbb5d74 添加表格问题接口修改
continuous-integration/drone/push Build is passing
2024-06-05 17:15:53 +08:00
caiyiling 23172eeed3 医学审核页面时间查询条件重置修复
continuous-integration/drone/push Build is passing
2024-06-05 16:11:05 +08:00
caiyiling 4bd286ca45 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-06-05 16:05:04 +08:00
caiyiling 873262444f 多帧图像预览页面bug修复 2024-06-05 16:04:35 +08:00
wangxiaoshuang ef6135a9e4 项目配置检查部位新建自动勾选
continuous-integration/drone/push Build is passing
2024-06-05 11:33:52 +08:00
wangxiaoshuang bc07f69687 项目配置检查部位修改
continuous-integration/drone/push Build is passing
2024-06-05 11:05:16 +08:00
caiyiling c2b9dcd277 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-06-05 09:54:02 +08:00
caiyiling 9cdc89f4df 切换序列时影像显示bug修复 2024-06-05 09:53:31 +08:00
wangxiaoshuang 1744d48889 稽查配置相关修改
continuous-integration/drone/push Build is passing
2024-06-04 14:21:54 +08:00
caiyiling 6c9e471e75 列表优化bug修复
continuous-integration/drone/push Build is passing
2024-06-04 13:36:28 +08:00
caiyiling d0bf19e3bf Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-06-04 13:16:53 +08:00
caiyiling 1a77962c42 阅片跟踪失效记录阅片结果查看 2024-06-04 13:16:23 +08:00
wangxiaoshuang e3f6204bd2 查询字段变更
continuous-integration/drone/push Build is passing
2024-06-04 13:12:17 +08:00
caiyiling 714a24040f 切换api
continuous-integration/drone/push Build is passing
2024-06-04 11:17:26 +08:00
caiyiling 76f2db5722 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is running
2024-06-04 11:15:31 +08:00
caiyiling 305433e3b1 稽查列表去除部分排序 2024-06-04 11:15:11 +08:00
wangxiaoshuang 76efc90a8b Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web
continuous-integration/drone/push Build is passing
2024-06-04 10:53:05 +08:00
wangxiaoshuang cf4b6887da oss兼容aws 2024-06-04 10:52:53 +08:00
caiyiling cd58d4d182 医学审核排序报错
continuous-integration/drone/push Build is passing
2024-06-04 10:11:45 +08:00
caiyiling 31a2b6c6fb 医学审核补充搜索条件
continuous-integration/drone/push Build is passing
2024-06-03 17:13:31 +08:00
caiyiling c6f8b8cafa 阅片跟踪重置时时间清除
continuous-integration/drone/push Build is passing
2024-06-03 16:58:38 +08:00
caiyiling 9779c028c6 阅片页面搜索条件修改
continuous-integration/drone/push Build is running
2024-06-03 16:57:58 +08:00
caiyiling d94d864b9e 审批签署、受试者、访视与中心调研表等模块项目中心字段维护
continuous-integration/drone/push Build is passing
2024-06-03 16:05:53 +08:00
wangxiaoshuang 3212f0cde2 阅片相关页面系统中心与项目中心的关联关系调整
continuous-integration/drone/push Build is passing
2024-06-03 15:34:08 +08:00
wangxiaoshuang 0592f9fc3d 人员与中心配置系统中心与项目中心的关联关系调整
continuous-integration/drone/push Build is passing
2024-06-03 15:10:20 +08:00
wangxiaoshuang 24e472d973 个人中心修改邮箱问题修复
continuous-integration/drone/push Build is passing
2024-06-03 14:45:41 +08:00
wangxiaoshuang c18364104f 申办方、cro列表新增level字段
continuous-integration/drone/push Build is passing
2024-06-03 14:34:03 +08:00
wangxiaoshuang eec16c1a2c Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web
continuous-integration/drone/push Build is passing
2024-05-31 17:45:45 +08:00
wangxiaoshuang 6737d33dcb 申办方、cro项目中新增 2024-05-31 17:45:33 +08:00
caiyiling ab242991bd 层厚信息显示bug修复 2024-05-31 15:28:07 +08:00
caiyiling a2facabb7b 层厚显示bug修复
continuous-integration/drone/push Build is passing
2024-05-31 15:25:55 +08:00
wangxiaoshuang 7e7e374e38 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web
continuous-integration/drone/push Build is passing
2024-05-31 14:09:36 +08:00
wangxiaoshuang 1b66fd6573 接口错误返回多次弹窗问题 2024-05-31 14:09:24 +08:00
caiyiling 31b1b1e3b6 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-05-31 14:03:18 +08:00
caiyiling 4b10b567e0 Lugano评估逻辑优化及全局跳转访视阅片页面bug修复 2024-05-31 14:02:47 +08:00
caiyiling dc1cd3870e Merge branch 'uat' of https://gitea.frp.extimaging.com/XCKJ/irc_web into uat 2024-05-31 14:02:40 +08:00
caiyiling 5542ad74e7 Lugano评估逻辑优化 2024-05-31 14:02:21 +08:00
wangxiaoshuang be74844410 美国环境更新 2024-05-31 13:21:51 +08:00
caiyiling fd67706269 全局阅片预览访视阅片结果bug修复 2024-05-31 11:20:21 +08:00
wangxiaoshuang e8ddecfc68 错误重传
continuous-integration/drone/push Build is passing
2024-05-31 11:07:07 +08:00
caiyiling 4ea73a455e 受试者无序阅片切换任务不切换表单
continuous-integration/drone/push Build is passing
2024-05-31 10:35:19 +08:00
caiyiling 84f5f5430c Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-05-31 09:49:16 +08:00
caiyiling 523220093f 阅片报告国际化更改 2024-05-31 09:48:55 +08:00
caiyiling 08c8d49ae1 阅片报告页国际化修改 2024-05-31 09:48:07 +08:00
wangxiaoshuang 9e4014afb0 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web
continuous-integration/drone/push Build is passing
2024-05-30 14:21:48 +08:00
wangxiaoshuang 4b1e698612 上传影像 2024-05-30 14:21:33 +08:00
wangxiaoshuang d5b4d4bbb0 crc上传影像切换tab不清除任务 2024-05-30 14:21:19 +08:00
caiyiling 8dbe02438c Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-05-30 10:58:11 +08:00
caiyiling df5a6b7fdd 融合页面结构更改 2024-05-30 10:57:43 +08:00
wangxiaoshuang 3bbe3b3fa3 新增下载影像页面
continuous-integration/drone/push Build is passing
2024-05-30 10:15:08 +08:00
wangxiaoshuang 17c3c6f6d2 用户管理添加查询条件邮箱、创建时间 2024-05-30 10:14:45 +08:00
caiyiling c653ab607f Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-05-30 09:17:07 +08:00
caiyiling 79f6e508af 项目过滤zyss,zybs用户类型 2024-05-30 09:12:44 +08:00
wangxiaoshuang d9fd181bae 美国环境更新 2024-05-29 17:34:30 +08:00
wangxiaoshuang 0ce246689b Merge commit '49dcab2a0e6e2b5a2de22a4256ec383b3b9ddb28' into uat
# Conflicts:
#	src/views/trials/trials-panel/reading/dicoms/components/DicomCanvas.vue
#	src/views/trials/trials-panel/reading/dicoms/customize/CustomizeDicomCanvas.vue
#	src/views/trials/trials-panel/visit/crc-upload/index.vue
#	vue.config.js
2024-05-29 16:19:16 +08:00
wangxiaoshuang 9102259c75 1
continuous-integration/drone/push Build is passing
2024-05-29 15:46:12 +08:00
caiyiling 11627f109d 去除阅片页面缓存影像信息 2024-05-29 15:30:21 +08:00
wangxiaoshuang 4eb202e4e7 上传影像按钮修改
continuous-integration/drone/push Build is passing
2024-05-29 09:56:04 +08:00
caiyiling d27ed741db Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-05-29 09:51:49 +08:00
caiyiling 093be87efb 医学审核失效记录添加查看功能 2024-05-29 09:51:19 +08:00
wangxiaoshuang c3e5ed0bff 上传、下载影像
continuous-integration/drone/push Build is passing
2024-05-29 08:58:03 +08:00
wangxiaoshuang ee487483d6 管理类账号增加进入管理后台的菜单
continuous-integration/drone/push Build is passing
2024-05-28 14:03:47 +08:00
caiyiling f8d921d9e5 阅片跟踪列表调整及阅片页面更改
continuous-integration/drone/push Build is passing
2024-05-28 13:54:57 +08:00
caiyiling 7758671f89 去除阅片时长排序
continuous-integration/drone/push Build is passing
2024-05-28 11:20:41 +08:00
caiyiling 59237c85c9 项目信息编辑界面更改
continuous-integration/drone/push Build is passing
2024-05-28 10:42:28 +08:00
caiyiling f505d297e9 页面优化
continuous-integration/drone/push Build is passing
2024-05-28 10:20:10 +08:00
wangxiaoshuang b34eda2139 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web
continuous-integration/drone/push Build is passing
2024-05-27 15:33:28 +08:00
wangxiaoshuang 8f354e4813 上传、下载影像 2024-05-27 15:33:04 +08:00
wangxiaoshuang 84c48adb39 仲裁问题规则修改 2024-05-27 15:32:40 +08:00
caiyiling 2892e75fd0 稽查查看表格类型的图片
continuous-integration/drone/push Build is passing
2024-05-27 14:20:46 +08:00
caiyiling ade801d323 影像预览页面更改
continuous-integration/drone/push Build is passing
2024-05-24 17:57:10 +08:00
caiyiling 29dbe52991 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-05-24 17:15:13 +08:00
caiyiling cbfe303aec 添加多帧预览进度条功能 2024-05-24 17:14:41 +08:00
wangxiaoshuang 56b94a97fd 上传、下载影像
continuous-integration/drone/push Build is passing
2024-05-24 16:47:35 +08:00
wangxiaoshuang 0baa90d86f 仲裁规则配置问题修复
continuous-integration/drone/push Build is passing
2024-05-24 15:27:32 +08:00
wangxiaoshuang 59fe18fe34 文件名包含特殊字符问题修复
continuous-integration/drone/push Build is passing
2024-05-24 14:59:16 +08:00
wangxiaoshuang b07708ebb1 仲裁规则配置问题修复 2024-05-24 14:58:52 +08:00
wangxiaoshuang d7a21af10c 上传、下载影像
continuous-integration/drone/push Build is passing
2024-05-23 17:34:29 +08:00
caiyiling 307403d897 弹窗优化
continuous-integration/drone/push Build is passing
2024-05-23 16:32:19 +08:00
caiyiling e473d03074 关于弹窗版本号更改
continuous-integration/drone/push Build is running
2024-05-23 16:28:49 +08:00
caiyiling f2f1668b05 稽查添加查看对话类型的数据
continuous-integration/drone/push Build is passing
2024-05-23 15:55:58 +08:00
caiyiling 6950883dbf 阅片检查列表优化
continuous-integration/drone/push Build is passing
2024-05-23 14:30:21 +08:00
caiyiling f767451a4e 阅片检查列表结构更改
continuous-integration/drone/push Build is passing
2024-05-23 13:49:51 +08:00
wangxiaoshuang 6d01361917 阅片单元配置修改 2024-05-21 14:14:45 +08:00
caiyiling 37521c378a 稽查bug修复 2024-05-21 13:46:48 +08:00
caiyiling ebe7c74614 稽查查看多图bug修复 2024-05-21 11:45:31 +08:00
wangxiaoshuang d50cc049ec Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web
continuous-integration/drone/push Build is passing
2024-05-20 16:25:01 +08:00
wangxiaoshuang 8d795994f6 上传、下载影像 2024-05-20 16:24:57 +08:00
caiyiling 880a0615c9 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-05-20 11:36:16 +08:00
caiyiling 77320ee132 阅片配置更改 2024-05-20 09:39:34 +08:00
wangxiaoshuang e7ccb10ba3 上传、下载影像
continuous-integration/drone/push Build is passing
2024-05-17 17:35:05 +08:00
caiyiling 456ff203bb Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-05-17 15:45:43 +08:00
caiyiling e3034e3b07 预览多帧图像处理 2024-05-17 15:45:12 +08:00
wangxiaoshuang b2700df68a 阅片单元自定义标准新增影像上传下载配置
continuous-integration/drone/push Build is passing
2024-05-17 10:52:19 +08:00
wangxiaoshuang c129d79273 阅片单元配置新增必填项影像模态
continuous-integration/drone/push Build is passing
2024-05-16 14:08:41 +08:00
caiyiling 9c5fa63b89 登录提示优化
continuous-integration/drone/push Build is running
2024-05-16 14:03:39 +08:00
caiyiling 54df1b8504 用户登录优化
continuous-integration/drone/push Build is passing
2024-05-16 13:53:48 +08:00
caiyiling a0ec36ac28 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-05-16 10:20:18 +08:00
caiyiling 416afbe84d 列表字段优化 2024-05-16 10:19:58 +08:00
wangxiaoshuang 6fd5caf8cb 仲裁规则配置项添加判断条件
continuous-integration/drone/push Build is running
2024-05-16 10:19:08 +08:00
caiyiling 90512f7967 邮件列表字段优化 2024-05-16 10:14:05 +08:00
caiyiling 71073d749b 列表字段优化
continuous-integration/drone/push Build is passing
2024-05-16 09:15:05 +08:00
caiyiling 564d6e7764 中心列表查询条件更改
continuous-integration/drone/push Build is passing
2024-05-15 17:40:00 +08:00
caiyiling 2129f7c90f Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-05-15 16:32:41 +08:00
caiyiling 960acf2007 列表优化 2024-05-15 16:32:26 +08:00
wangxiaoshuang c3be341247 问题修复
continuous-integration/drone/push Build is passing
2024-05-15 16:12:42 +08:00
caiyiling 35abb4d573 PM医学审核列表优化
continuous-integration/drone/push Build is passing
2024-05-15 14:17:05 +08:00
caiyiling 747eadb7f1 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-05-15 13:52:46 +08:00
caiyiling f26fdb82ee 列表优化 2024-05-15 13:52:14 +08:00
wangxiaoshuang 85a518d900 oss上传文件名称问题
continuous-integration/drone/push Build is passing
2024-05-15 10:16:04 +08:00
wangxiaoshuang 289230b72c 登录日志添加所在地,登录用户查询条件改为下拉框
continuous-integration/drone/push Build is passing
2024-05-14 15:10:41 +08:00
wangxiaoshuang baf2f9aa10 登录日志操作类型修改
continuous-integration/drone/push Build is passing
2024-05-14 14:10:00 +08:00
caiyiling 229bf36ce5 字段列表优化
continuous-integration/drone/push Build is passing
2024-05-14 11:20:32 +08:00
wangxiaoshuang e416429087 仲裁规则添加配置项
continuous-integration/drone/push Build is passing
2024-05-10 14:54:24 +08:00
wangxiaoshuang bd1ee8a520 个人中心更改
continuous-integration/drone/push Build is passing
2024-05-09 11:27:30 +08:00
caiyiling 5cc38ada71 影像浏览页面更改
continuous-integration/drone/push Build is passing
2024-05-09 10:13:26 +08:00
hang 75f8018fc8 修改自动打包文件
continuous-integration/drone/push Build is passing
2024-05-06 15:57:58 +08:00
wangxiaoshuang e868d50893 用户名称刷新问题
continuous-integration/drone/push Build is failing
2024-05-06 15:43:58 +08:00
caiyiling e4378d244b Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is pending
2024-05-06 14:30:21 +08:00
caiyiling 16a5f4866d 配置信息更改 2024-05-06 14:29:37 +08:00
wangxiaoshuang 115dae48c7 1
continuous-integration/drone/push Build is pending
2024-05-06 14:27:30 +08:00
caiyiling 49dcab2a0e 非淋巴结靶病灶状态自动赋值逻辑及肿瘤学阅片更改 2024-04-30 12:59:52 +08:00
caiyiling e9188115fc 退回修改用户real name
continuous-integration/drone/push Build is pending
2024-04-29 18:10:13 +08:00
caiyiling 264e0ee7c4 美国环境隐藏菜单栏切换语言功能
continuous-integration/drone/push Build is pending
2024-04-29 16:58:56 +08:00
caiyiling 434fe551b3 更改用户姓名同步更新缓存中的姓名
continuous-integration/drone/push Build is pending
2024-04-29 15:53:28 +08:00
caiyiling cd95f0b018 阅片期临床数据签名成功刷新列表
continuous-integration/drone/push Build is pending
2024-04-29 15:29:55 +08:00
caiyiling f16f5adfd6 临床数据配置更改
continuous-integration/drone/push Build is passing
2024-04-29 14:33:00 +08:00
caiyiling 26009d0626 全局阅片显示字段调整
continuous-integration/drone/push Build is passing
2024-04-29 13:09:29 +08:00
caiyiling ec41415305 随访状态为存在的淋巴结靶病灶保存验证条件更改
continuous-integration/drone/push Build is passing
2024-04-29 11:24:29 +08:00
caiyiling 3a4967e6ab Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-04-29 11:06:55 +08:00
caiyiling 384d7197a2 工作台系统文件签署刷新数据 2024-04-29 11:06:23 +08:00
wangxiaoshuang 5a98d503f8 美国环境发布
continuous-integration/drone/push Build is passing
2024-04-29 09:37:38 +08:00
caiyiling 782324b19c 系统日志列表设置默认排序 2024-04-28 17:26:14 +08:00
caiyiling 7c7573cdc4 独立阅片人列表调整 2024-04-28 17:09:17 +08:00
caiyiling ff87692f69 看检查级别的影像信息样式调整 2024-04-28 13:45:10 +08:00
caiyiling 1cbe9ce258 医生列表bug修复 2024-04-28 13:40:30 +08:00
caiyiling 3dfa1ae296 页面样式调整 2024-04-28 10:44:37 +08:00
caiyiling f5492e42d5 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-04-26 17:39:30 +08:00
caiyiling cc0b201036 自定义阅片附件下载 2024-04-26 17:39:10 +08:00
wangxiaoshuang de545a0847 一致性分析操作按钮disabled还原 2024-04-26 16:46:37 +08:00
caiyiling 8a6a7962ae mim项目列表调整 2024-04-26 14:40:56 +08:00
caiyiling 806010c6d4 表格根据列的数量动态固定列 2024-04-26 14:38:49 +08:00
caiyiling e744cbda51 全局、裁判列表展示优化 2024-04-26 14:21:15 +08:00
caiyiling 1e098c44c1 裁判任务表格样式处理 2024-04-26 14:16:45 +08:00
caiyiling 9feb906c3e 医学审核裁判任务列表优化 2024-04-26 13:44:49 +08:00
caiyiling 79a5e67b59 医学审核全局任务列表优化 2024-04-26 13:35:47 +08:00
caiyiling 6c4f022764 医学审核全局任务取消固定操作列 2024-04-26 13:12:01 +08:00
caiyiling 519e1519e2 修改用户名时登出处理 2024-04-25 17:53:46 +08:00
caiyiling 830cd1e93e 删除病灶时,更新FDG-PET评估 2024-04-25 16:09:29 +08:00
caiyiling 1e7237e7ac lugano靶病灶保存如果必填信息填写不全,将滚动条滚到顶部 2024-04-25 15:02:49 +08:00
caiyiling 13ac2e2834 未画标注是,不上传截图 2024-04-25 14:45:45 +08:00
caiyiling 04b22f5b50 自定义标准阅片单元配置优化 2024-04-25 13:15:00 +08:00
caiyiling 8d36fde03d 系统自动保存全局阅片配置时刷新再保存 2024-04-25 11:26:54 +08:00
caiyiling 0680bdf805 全局阅片配置bug修复 2024-04-25 11:25:54 +08:00
caiyiling 88f2c34db9 肝脏及pet5ps逻辑优化 2024-04-24 17:03:27 +08:00
caiyiling 612724cbea 解决未标注病灶信息则不上传截图问题 2024-04-24 16:25:19 +08:00
caiyiling afd362ba72 肝脏评估和PET5PS评估逻辑优化 2024-04-24 15:58:28 +08:00
caiyiling 1825ac34e1 脾脏评估和PET 5PS评估逻辑修改 2024-04-24 12:57:45 +08:00
caiyiling 0e33b60681 国际化处理及阅片单元配置和分配阅片人bug修复 2024-04-23 16:29:01 +08:00
caiyiling 1fdbdc4103 自定义标准获取病灶bug修复及修改用户名登出处理 2024-04-23 16:05:09 +08:00
caiyiling be6fdf2277 退出账号时调用退出接口 2024-04-23 10:11:00 +08:00
caiyiling 96c35e1736 在账号信息修改用户名后,修改前端缓存中的用户信息 2024-04-22 10:17:12 +08:00
caiyiling f3f826d60a 保存病灶只更新SUVmax所在病灶及病灶最大SUV值 2024-04-19 17:06:12 +08:00
caiyiling 300a9ad536 与基线摄取值变化数值维护 2024-04-19 15:57:17 +08:00
caiyiling 5ec96c76bf 多行文本框限制字符长度 2024-04-19 15:46:41 +08:00
caiyiling d96c4c743b 标记定位重复触发代码优化 2024-04-19 15:15:04 +08:00
caiyiling 227f583e7a pet-5ps评分为2分计算规则更改 2024-04-19 11:15:53 +08:00
caiyiling 3646acf378 与基线摄取值变化bug修复 2024-04-19 11:09:16 +08:00
caiyiling 8618b188ae 与基线摄取值变化自动计算逻辑更改 2024-04-18 16:45:45 +08:00
caiyiling 28b644a0ce 靶病灶评估列表下拉框滚动事件优化 2024-04-18 15:57:39 +08:00
caiyiling c886900005 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-04-18 15:25:09 +08:00
caiyiling 7dbe8c92e1 本地影像预览bug修复 2024-04-18 15:24:45 +08:00
wangxiaoshuang 7623264487 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-04-18 15:02:11 +08:00
wangxiaoshuang db0d5f7ff6 质控临床数据按钮图标更改 2024-04-18 15:01:48 +08:00
caiyiling 1b5c62df75 pet 5ps评分逻辑修改 2024-04-18 14:31:31 +08:00
caiyiling 0ad25e273a pet 5PS评分计算bug修复 2024-04-18 14:29:20 +08:00
caiyiling 437c571b57 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-04-18 14:26:21 +08:00
caiyiling 138ea2cfb8 提示优化及影像评估设置pet 5PS评分问题修复 2024-04-18 14:25:40 +08:00
wangxiaoshuang 08f0d76aa7 中心调研按钮显示修改 2024-04-18 11:11:03 +08:00
caiyiling 967edf7378 阅片单元同步阅片标准loading加载bug 2024-04-17 10:15:58 +08:00
caiyiling 236f07e46b 接口登出场景补充 2024-04-16 18:00:03 +08:00
caiyiling 6d4ae0a616 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-04-16 14:20:51 +08:00
caiyiling a576204ac3 lugano标准病灶评估表单滚动时下拉框触发失去焦点事件 2024-04-16 14:19:50 +08:00
wangxiaoshuang fc0ea89d74 访视详情添加检查临床数据查看按钮 2024-04-16 10:33:02 +08:00
caiyiling 7d2fdd222a 影像质量问题为不正常时刷新融合页面 2024-04-15 14:27:15 +08:00
caiyiling 56783a6f3a 非dicom文件预览及阅片结果预览bug修复 2024-04-15 14:09:55 +08:00
caiyiling df6a1cb412 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-04-15 13:50:07 +08:00
caiyiling cb24021c0d 病灶评估保存时刷新脾脏评估 2024-04-15 13:48:59 +08:00
wangxiaoshuang 917f95030b pet-ct临床数据未上传弹框判断条件更改 2024-04-15 13:47:25 +08:00
wangxiaoshuang bf131e09e4 简历采集跳转路由修改 2024-04-15 13:13:51 +08:00
wangxiaoshuang 17ed3d4dca 简历采集页tab国际化 2024-04-15 11:44:24 +08:00
caiyiling 6fa4a6349c 会话窗口字体颜色调整 2024-04-15 11:28:10 +08:00
caiyiling 2f722f8c0e 待阅和阅片跟踪去除部分排序字段 2024-04-15 11:06:35 +08:00
caiyiling 15a7b6d1ac 登录日志添加登录用户和角色搜索条件 2024-04-15 10:19:20 +08:00
caiyiling 852a794c44 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-04-15 10:07:04 +08:00
caiyiling 14d71fc3f9 自定义阅片临床数据查看及上传时基线查看访视级别临床数据 2024-04-15 09:21:12 +08:00
caiyiling 1888ec4fe5 添加备注:基线显示受试者级别和方式级别的临床数据 2024-04-13 14:41:25 +08:00
caiyiling e132f84c48 自定义阅片自动对齐bug修复 2024-04-13 14:30:15 +08:00
wangxiaoshuang c02ce4b350 PET-CT临床数据的上传与临床数据采集Tab的的显示关系 2024-04-12 17:45:42 +08:00
caiyiling 4ca0f35cad 融合页面保存状态去除病灶信息不完整判断 2024-04-12 17:30:45 +08:00
caiyiling 62dd650447 当纵隔或肝脏血池suvmax未发生改变时不计算PET 5PS评分 2024-04-12 17:24:51 +08:00
caiyiling 06761092e3 PET 5PS评分自动计算调整 2024-04-12 16:56:57 +08:00
caiyiling b4f58fddb7 病灶删除不重新获取标注 2024-04-12 15:20:03 +08:00
caiyiling 33e836cd81 脾脏状态备注显隐bug修复 2024-04-12 14:44:56 +08:00
caiyiling 790e828257 会话窗字体颜色调整 2024-04-12 14:02:28 +08:00
caiyiling e7d799ceb5 脾脏评估算法优化 2024-04-12 13:59:00 +08:00
caiyiling 3a69256a04 脾脏评估算法优化:显著增大和部分缓解均增加了当前垂直径>130 mm的条件 2024-04-12 13:58:11 +08:00
caiyiling 425782e015 稽查文件记录及路由跳转查看bug修复 2024-04-12 13:43:43 +08:00
caiyiling db1d2cc4e1 稽查查看图片功能修复 2024-04-12 11:42:42 +08:00
caiyiling 3283f7f5f2 临床数据模板配置校验更改 2024-04-12 10:37:16 +08:00
caiyiling 892b71c011 临床数据配置保存前添加校验 2024-04-11 16:51:51 +08:00
caiyiling 82b3ca055f Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-04-11 15:49:04 +08:00
caiyiling 15cc9c00be dicom上传时排除DICOMDIR文件 2024-04-11 15:48:36 +08:00
wangxiaoshuang 6740e584ae 临床数据访视者级别显示问题 2024-04-11 15:34:46 +08:00
caiyiling d8401d57f7 在阅片人选择影像质量为PET-CT影像无法融合后,保存时,弹框提示 2024-04-11 14:22:04 +08:00
caiyiling c04aaf2db6 有pet影像但无法融合/无法测量的处理 2024-04-11 13:38:42 +08:00
caiyiling c29b60cbbe 修复影像上传页面权限绑定错误问题 2024-04-10 16:45:17 +08:00
caiyiling 6f0cfb0122 修复医学审核页面配置自定义问题保存报错 2024-04-10 15:37:52 +08:00
caiyiling bfdd137cba 密码重置页面验证码验证通过添加提示 2024-04-10 15:21:32 +08:00
caiyiling 15f7e35de5 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-04-10 15:14:47 +08:00
caiyiling 0accca7ec1 修复部分列表点击重置或排序查询问题 2024-04-10 15:13:28 +08:00
wangxiaoshuang 606d637d21 admin角色去掉中心调研 2024-04-09 11:01:21 +08:00
caiyiling 94e80cbb38 全局任务类型的医学审核任务点击访视名称跳转 2024-04-08 17:11:10 +08:00
caiyiling 63a4a56feb PetCt页面viewport图像以最大的图像张数滚动 2024-04-08 16:39:44 +08:00
caiyiling 55085438aa 同步数据时只刷新病灶列表部分信息 2024-04-08 14:50:47 +08:00
caiyiling c8e7645fa5 阅片页面FDG-PET评估更改 2024-04-08 14:09:29 +08:00
caiyiling 59543a383c 阅片页面ecrf表单更改 2024-04-08 14:03:07 +08:00
caiyiling 92a92ac353 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-04-08 13:55:34 +08:00
caiyiling 91ee952707 阅片页面ecrf表单保存接口更改 2024-04-08 13:54:42 +08:00
wangxiaoshuang d5cb03209a 阅片期临床数据表格数据为空时tip展示选项内容 2024-04-08 10:39:01 +08:00
caiyiling c2aad16566 流程配置添加阅片标准国际化 2024-04-07 14:29:01 +08:00
caiyiling dd006a6269 系统级别的临床数据不允许编辑 2024-04-07 14:02:47 +08:00
caiyiling 4896aabe3d 临床数据配置更改 2024-04-07 13:55:32 +08:00
caiyiling 8164ef38eb 流程配置阅片标准变化清除临床数据配置 2024-04-07 13:37:01 +08:00
caiyiling 0401a95635 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-04-07 13:20:24 +08:00
caiyiling b461716195 脾脏状态自动计算调整 2024-04-07 13:20:02 +08:00
wangxiaoshuang ada50a7e73 crc工作台左侧菜单顺序变更 2024-04-03 16:13:46 +08:00
wangxiaoshuang 4f51946c3f 简历采集国际化 2024-04-03 16:13:17 +08:00
caiyiling edfa41291b Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-04-03 14:09:39 +08:00
caiyiling f34de6073f 历史融合弹窗添加取消事件 2024-04-03 14:09:12 +08:00
wangxiaoshuang 1d1805f8cc 自定义标准不添加默认问题 2024-04-03 13:34:03 +08:00
caiyiling 0a56880080 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-04-03 13:03:13 +08:00
caiyiling bcf69f6194 全局类型的医学审核任务去除操作列固定 2024-04-03 13:02:23 +08:00
wangxiaoshuang 72b7cdbc71 临床数据判断条件变更 2024-04-03 13:01:56 +08:00
wangxiaoshuang 90c1123113 头部名称换行问题解决 2024-04-03 10:27:47 +08:00
caiyiling 6a5f6b0da3 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-04-02 17:06:24 +08:00
caiyiling 9b601c0f9a 调整工作台一致性核查列表列头间距 2024-04-02 17:05:47 +08:00
wangxiaoshuang fa2bf66dd1 虚拟中心编号添加输入长度限制 2024-04-02 15:15:13 +08:00
caiyiling 7969db76fe 临床数据上传pdf时文件名称添加时间戳 2024-04-01 15:18:29 +08:00
caiyiling 08462786de Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-04-01 15:17:58 +08:00
caiyiling 990c152a99 临床数据上传pdf文件名称添加时间戳 2024-04-01 15:17:29 +08:00
wangxiaoshuang a00a4957fd Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-04-01 13:57:43 +08:00
wangxiaoshuang 1351a9192c 阅片人筛选,下载简历为空问题修复 2024-04-01 13:57:32 +08:00
caiyiling 51c59a7be9 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-04-01 13:18:02 +08:00
caiyiling 773aa65116 修复新增reviewer时获取文件信息报错问题 2024-04-01 13:17:20 +08:00
wangxiaoshuang 139e4ab5e2 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-04-01 11:38:02 +08:00
wangxiaoshuang e4fa9c7afd ir项目列表排序报错问题解决 2024-04-01 11:37:55 +08:00
caiyiling aa04344503 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-04-01 11:25:19 +08:00
caiyiling 7278841b0c 阅片页面重载时关闭子页签 2024-04-01 11:24:49 +08:00
wangxiaoshuang a9cbdf9b08 crc加急影像提交菜单位置变更 2024-04-01 11:14:20 +08:00
wangxiaoshuang cafd40d83e iqc项目列表加急量展示字段重复 2024-04-01 11:04:48 +08:00
wangxiaoshuang cdf26294d0 独立阅片人页面,启用按钮的字体颜色修改 2024-04-01 11:04:04 +08:00
wangxiaoshuang a8fa74b270 独立阅片人页面,启用按钮的字体颜色修改 2024-04-01 09:25:45 +08:00
wangxiaoshuang 2c97e1d441 一致性分析导出弹框大小更改 2024-03-29 17:14:42 +08:00
caiyiling d3244cee7c 融合视口显示信息格式优化 2024-03-29 16:22:58 +08:00
caiyiling cd0e62fbef 历史融合按钮调整 2024-03-29 15:02:43 +08:00
caiyiling c0519613e2 待签署系统文件添加获取下一签署文档信息 2024-03-29 14:48:57 +08:00
caiyiling 10ff7f31d8 阅片期访视级别的任务添加检查级别的临床数据 2024-03-29 13:36:50 +08:00
caiyiling 5729f2246e 删除console 2024-03-29 13:01:02 +08:00
caiyiling 7b475b4873 关闭融合页面关闭历史记录页面 2024-03-29 12:56:00 +08:00
caiyiling 12db782153 融合页面显示历史融合记录 2024-03-29 12:16:22 +08:00
caiyiling f4b2c8a6a4 lugano报告页pdd标红 2024-03-29 12:15:27 +08:00
caiyiling 9aaf2e4ad5 融合页面关闭历史记录页面同时关闭 2024-03-29 11:33:23 +08:00
caiyiling 5bcd7cfa59 阅片期临床数据是否完备为否是显示感叹号 2024-03-29 10:36:20 +08:00
caiyiling efa7c61fe4 首次渲染不更新标识优化 2024-03-29 10:20:54 +08:00
caiyiling 82e5142bac 首次渲染不更新保存标识 2024-03-29 10:17:29 +08:00
caiyiling 3083ee1e8b 肝脏血池纵隔血池保存提示 2024-03-29 09:44:16 +08:00
caiyiling c7d362e1d0 消息提示显示时间 2024-03-29 09:23:22 +08:00
caiyiling 1f3cb0284a 保存提示显示时间 2024-03-29 09:14:52 +08:00
caiyiling 431d8a0682 lugano去除提示 2024-03-28 17:53:26 +08:00
caiyiling fe40027765 逻辑配置优化 2024-03-28 17:14:06 +08:00
caiyiling 3eeefaaa2c 检查部位分割格式 2024-03-28 17:02:03 +08:00
caiyiling d4ea8bb4d5 质控提示更改 2024-03-28 16:24:37 +08:00
caiyiling 1812877f88 去除console 2024-03-28 15:38:42 +08:00
caiyiling f5ded882ee Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-28 15:37:39 +08:00
caiyiling 711373075c 脾尖、脾底标注添加限制 2024-03-28 15:37:06 +08:00
wangxiaoshuang afa835e3b9 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-03-28 14:06:06 +08:00
wangxiaoshuang 06b3632bf8 PET-CT感叹号提示及时更新 2024-03-28 14:06:02 +08:00
caiyiling 1a9f6c37b8 影像视角信息slice Location添加单位 2024-03-28 13:26:36 +08:00
caiyiling 0de0e887b4 影像保存截图文件命名添加时间戳 2024-03-28 13:15:13 +08:00
caiyiling 07a32b9b2a 去除console 2024-03-28 11:39:19 +08:00
caiyiling 7e1165888b 阅片期添加临床数据是否完备字段 2024-03-28 11:19:15 +08:00
caiyiling 0e5d1fb718 病灶历史记录同时只打开一个窗口 2024-03-28 10:53:10 +08:00
caiyiling db7498938f 列表展示信息优化 2024-03-28 10:24:31 +08:00
caiyiling fd5cce0ed9 界面展示信息格式优化 2024-03-28 09:41:42 +08:00
caiyiling 9c16e74d3e Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-28 09:31:19 +08:00
caiyiling 88cc255c56 列表展示信息格式优化 2024-03-28 09:30:23 +08:00
wangxiaoshuang 372213c7e5 预览计算问题修改 2024-03-28 08:58:33 +08:00
wangxiaoshuang 0343ba6043 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-03-28 08:55:13 +08:00
wangxiaoshuang 595da0a7de 预览计算问题修改 2024-03-27 18:06:07 +08:00
caiyiling 4fabe3fa14 影像工具下载图像功能优化 2024-03-27 16:45:09 +08:00
caiyiling c745756c8c 重阅保存表单标记渲染问题修复 2024-03-27 15:09:44 +08:00
caiyiling 6407cd8264 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-27 14:55:05 +08:00
caiyiling f4842ba34d MIP图移除VOLUME_NEW_IMAGE监听事件 2024-03-27 14:54:06 +08:00
wangxiaoshuang 1724e020f6 部分页面添加默认排序规则新增排序字段 2024-03-27 14:39:22 +08:00
wangxiaoshuang 5e2522147f 部分页面添加默认排序规则新增排序字段 2024-03-27 14:32:03 +08:00
wangxiaoshuang 05bc41f5e2 登录日志列表排序变更 2024-03-27 13:58:29 +08:00
wangxiaoshuang 9d47ae2561 提醒窗口多次弹出问题修复 2024-03-27 13:58:07 +08:00
caiyiling 2d94f07796 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-27 11:02:33 +08:00
caiyiling 3ea4617d45 阅片界面样式优化 2024-03-27 11:02:15 +08:00
wangxiaoshuang bbcb092f3e Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-03-26 17:58:41 +08:00
wangxiaoshuang 2cd92b1dcd 一致性分析导出按钮合并 2024-03-26 17:58:30 +08:00
caiyiling 81171f6486 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-26 17:53:01 +08:00
caiyiling 0df518f025 suv测量没有标注时默认激活工具 2024-03-26 17:52:30 +08:00
wangxiaoshuang 0f87682432 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-03-26 17:31:51 +08:00
wangxiaoshuang e6107ffe70 前端优化 2024-03-26 17:31:01 +08:00
caiyiling 3e24df32f0 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-26 17:11:25 +08:00
caiyiling 9233dff4ba 基线任务不显示历史融合记录 2024-03-26 17:10:51 +08:00
wangxiaoshuang 33f5bcb079 医学审核筛查阅片人排序问题解决 2024-03-26 15:59:53 +08:00
wangxiaoshuang 92d34d59f4 一致性分析操作按钮disabled放开 2024-03-26 15:59:17 +08:00
caiyiling 7db7e91468 流程配置:获取临床数据配置根据阅片标准进行过滤 2024-03-26 14:59:13 +08:00
caiyiling d74a4506c9 旋转拖拽条添加点击事件 2024-03-26 14:38:13 +08:00
caiyiling 956e3b7152 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-26 13:52:02 +08:00
caiyiling 9bc0b7b02a MIP添加旋转拖拽条 2024-03-26 13:51:24 +08:00
wangxiaoshuang 33747d1317 虚拟中心编号修改记录列表样式调整 2024-03-26 12:17:18 +08:00
wangxiaoshuang 88da86504d 未上传临床数据的pet-ct数据添加tip标识 2024-03-26 10:09:34 +08:00
wangxiaoshuang c2dc340a1d 文件水印修改 2024-03-25 16:22:45 +08:00
wangxiaoshuang f17c230267 临床资料详情tip字段替换 2024-03-25 15:43:45 +08:00
wangxiaoshuang 5e56098750 虚拟中心弹框样式优化 2024-03-25 15:12:48 +08:00
wangxiaoshuang eed3cac20e 阅片期临床数据相关功能隐藏 2024-03-25 15:03:11 +08:00
wangxiaoshuang 5df5836571 国际化问题修改 2024-03-25 13:20:50 +08:00
wangxiaoshuang 3fbc2710a3 当上传了pet序列图像时,校验提醒上传PET临床数据 2024-03-25 12:20:41 +08:00
caiyiling 16f943dd50 肿瘤学阅片的医学审核任务列表调整 2024-03-22 17:43:54 +08:00
caiyiling f960eeb445 访视级别的医学审核任务列表调整 2024-03-22 17:35:28 +08:00
caiyiling d18d61ee01 病灶保存状态提示 2024-03-22 16:58:59 +08:00
caiyiling a86c4bdd0e 病灶保存代码优化 2024-03-22 16:52:47 +08:00
caiyiling 83c441b7de 病灶保存提示语优化 2024-03-22 14:00:39 +08:00
caiyiling 49d3247f27 脾脏保存添加提示 2024-03-22 13:49:45 +08:00
caiyiling efc40de310 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-22 13:27:32 +08:00
caiyiling 0cd33687ee 保存评估结果时验证是否有标注测量为完成 2024-03-22 13:26:50 +08:00
caiyiling 994598c216 纵隔血池、肝脏血池、脾尖、脾底标记保存优化 2024-03-22 13:26:04 +08:00
wangxiaoshuang c31a92fbaa 影像质控无后续任务刷新列表 2024-03-21 14:45:59 +08:00
wangxiaoshuang 7bbf60dd7c 影像质控审核判断是否拥有下一任务逻辑变更 2024-03-21 14:15:00 +08:00
caiyiling a51d613633 历史记录融合表单优化 2024-03-20 13:44:27 +08:00
caiyiling 20480cfad6 截图无数据时点击确认关闭当前页签 2024-03-20 10:13:25 +08:00
caiyiling 9577d1d90e lugano病灶标记无截图时添加提示 2024-03-20 10:11:28 +08:00
caiyiling 9fbeb4ce04 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-20 09:53:39 +08:00
caiyiling f34f7a0656 lugano融合添加历史访视融合记录查看 2024-03-20 09:51:37 +08:00
wangxiaoshuang ee049b4017 一致性分析即首次自身/组间一致性分析时虚拟中心编号可编辑 2024-03-20 09:21:11 +08:00
wangxiaoshuang d5594e87b2 一致性分析即首次自身/组间一致性分析时虚拟中心编号可编辑 2024-03-19 17:45:32 +08:00
wangxiaoshuang 3524e7730c 中心调研审核提示信息修改 2024-03-19 12:14:53 +08:00
caiyiling 18c31112b3 lugano病灶分裂代码优化 2024-03-19 09:22:58 +08:00
caiyiling 0ae82ff145 分裂后PPD计算 2024-03-18 17:35:27 +08:00
caiyiling af9ad72798 分裂主病灶状态计算逻辑优化 2024-03-18 17:26:24 +08:00
caiyiling dc6340f65c slice location显示值根据项目标准配置的保留小数位数进行处理 2024-03-18 16:06:38 +08:00
caiyiling cd45362a07 第一个标记渲染时,不触发更新 2024-03-18 15:53:29 +08:00
caiyiling a048572403 lugano病灶截图预览路径由绝对路径改为相对路径 2024-03-18 15:05:07 +08:00
caiyiling 766a2a786f Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-18 13:57:16 +08:00
caiyiling 0cca8f71b4 lugano标准病灶列表添加既往标记截图预览 2024-03-18 13:55:56 +08:00
wangxiaoshuang 76392409f6 医院修改中英文自动带入 2024-03-18 13:12:43 +08:00
caiyiling a298048ed0 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-18 11:05:16 +08:00
caiyiling b6f46cec28 lugano标准病灶分裂,分裂病灶状态计算疾病进展逻辑更改 2024-03-18 11:04:02 +08:00
wangxiaoshuang 94b0aeb239 取消console 2024-03-18 11:01:54 +08:00
wangxiaoshuang ce5bbaaa4a 简历工作信息部分中英文切换问题修改 2024-03-18 11:01:09 +08:00
熊飞 482d37b4cf Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-03-16 14:50:05 +08:00
熊飞 531c2a5146 是否测试用户反向 2024-03-16 14:49:57 +08:00
wangxiaoshuang eb4d058c8a 分配角色去除GR,部分代码优化 2024-03-15 10:33:57 +08:00
熊飞 c09b1a2322 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-03-15 10:07:59 +08:00
熊飞 40f142e1d2 上传路径 2024-03-15 10:07:52 +08:00
wangxiaoshuang c266b9fcf1 版本日期修改 2024-03-15 08:59:20 +08:00
熊飞 586d406b4a 工作台限制我的项目进入 2024-03-14 17:58:27 +08:00
熊飞 54efc9b1ed Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-03-14 17:34:56 +08:00
熊飞 f487792d8e IQC去除语言 2024-03-14 17:34:49 +08:00
wangxiaoshuang 4290f51ce1 医学审核问题配置表格高度调整 2024-03-14 17:18:37 +08:00
wangxiaoshuang c08db443c9 医学审核问题配置按钮位置调整 2024-03-14 17:03:01 +08:00
wangxiaoshuang 9fc1628cce 中心人员列表授权时间字段变更 2024-03-14 16:42:47 +08:00
wangxiaoshuang 77e1eba8d5 pm阅片人筛选部分信息添加间隔 2024-03-14 15:43:17 +08:00
caiyiling b707c09d2d 添加获取病灶历史记录截图接口 2024-03-14 15:32:08 +08:00
caiyiling b195e6d7ce Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-14 15:31:54 +08:00
caiyiling 8c38700b51 病灶查看suv测量历史截图 2024-03-14 15:22:52 +08:00
wangxiaoshuang a675d5d79e pm阅片人筛选部分信息添加间隔 2024-03-14 15:04:15 +08:00
wangxiaoshuang 54c7bb055a 工作台中心调研数量分角色统计 2024-03-14 14:58:30 +08:00
wangxiaoshuang 9a63a206d5 项目配置检查部位和检查技术全选标识问题修复 2024-03-14 14:44:15 +08:00
熊飞 dfaa255427 IQC去除语言 2024-03-14 14:39:25 +08:00
熊飞 7f9589427f 一致性核查默认值 2024-03-14 14:11:51 +08:00
wangxiaoshuang 145655f8fc spm工作台添加中心调研入口 2024-03-14 14:09:03 +08:00
wangxiaoshuang eadd5b0223 spm阅片人筛选信息展示添加空格 2024-03-14 13:54:16 +08:00
wangxiaoshuang 46ea20a9f5 【阅片任务分配】增加筛选条件,取消筛选条件限制 2024-03-14 13:49:38 +08:00
wangxiaoshuang 37c415c0ef 【阅片任务分配】增加筛选条件 2024-03-14 11:09:48 +08:00
wangxiaoshuang 84ade87b25 【阅片任务分配】增加筛选条件 2024-03-14 10:59:42 +08:00
wangxiaoshuang 157b65c507 ea、qa权限配置 2024-03-14 10:23:26 +08:00
wangxiaoshuang 68ea60857d ea权限配置 2024-03-14 09:27:06 +08:00
熊飞 78685918a9 工作台用户名 2024-03-13 17:50:33 +08:00
熊飞 56a8e738d3 工作台用户名 2024-03-13 16:38:33 +08:00
熊飞 ccf5830fa0 工作台用户名 2024-03-13 16:21:49 +08:00
熊飞 c73c84b15d 工作台用户名 2024-03-13 15:49:48 +08:00
熊飞 d131953beb 工作台用户名 2024-03-13 14:45:43 +08:00
熊飞 6e4a674b62 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-03-13 14:28:19 +08:00
熊飞 3b7f141956 工作台用户名 2024-03-13 14:28:09 +08:00
caiyiling c114f1bb23 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-13 13:54:52 +08:00
caiyiling d9b5d76ac7 病灶标记截图更改 2024-03-13 13:54:22 +08:00
熊飞 53dc05a48c Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-03-13 13:31:06 +08:00
熊飞 e457df9325 上传进度条处理 2024-03-13 13:28:35 +08:00
caiyiling 72c6b433b6 修改长短径工具标注信息 2024-03-13 13:18:08 +08:00
caiyiling 5edd252a12 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-13 11:48:47 +08:00
caiyiling e96a4a4d7b 影像融合时,显示的访视及检查信息与当前高亮窗口一致 2024-03-13 11:47:14 +08:00
熊飞 f126d8c40b 组间一致性 原阅片人字段 2024-03-13 11:13:52 +08:00
熊飞 d15eab1a8e 1 2024-03-13 11:07:40 +08:00
熊飞 3fb2c5ca40 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-03-13 10:50:34 +08:00
熊飞 8afaf8a39e 1 2024-03-13 10:50:24 +08:00
caiyiling 9827baf122 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-13 09:31:30 +08:00
caiyiling ae77e4f048 脾尖、脾底标记命名更改 2024-03-13 09:30:49 +08:00
熊飞 0928fef04c 工作台改版 2024-03-12 18:02:48 +08:00
熊飞 d91f07bba6 工作台改版 2024-03-12 17:40:07 +08:00
熊飞 2ff15bc2b8 工作台改版 2024-03-12 17:09:37 +08:00
熊飞 f66f0da07e 工作台改版 2024-03-12 16:46:56 +08:00
熊飞 661f0e5dfb 工作台改版 2024-03-12 16:36:52 +08:00
熊飞 a4070374c6 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-03-12 16:14:00 +08:00
熊飞 9aa68bf5f4 阅片单元配置 2024-03-12 16:13:53 +08:00
caiyiling 88887e5d92 lugano表单提交按钮未更改信息时禁用 2024-03-12 16:02:50 +08:00
caiyiling 437e224f1a Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-12 15:41:34 +08:00
caiyiling 22e22c3901 脾脏垂直径测量 2024-03-12 15:41:16 +08:00
熊飞 73a054ad27 邮箱@被转%40的bug解决 2024-03-12 15:29:37 +08:00
熊飞 4fff154ad6 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-03-12 15:19:43 +08:00
熊飞 6914926567 工作台改版 2024-03-12 15:19:36 +08:00
caiyiling 998c8bc701 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-12 14:10:00 +08:00
caiyiling 058bf39c6e 添加关闭页签的请求标识 2024-03-12 14:09:26 +08:00
熊飞 727d4f8c19 工作台改版 2024-03-12 11:26:01 +08:00
熊飞 277ffa5def 工作台改版 2024-03-12 09:25:26 +08:00
熊飞 283533ff6d 工作台改版 2024-03-11 18:22:04 +08:00
熊飞 70adad29e4 工作台改版 2024-03-11 18:15:09 +08:00
熊飞 195c176c34 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-03-11 17:54:09 +08:00
熊飞 0ac75d7c44 工作台改版 2024-03-11 17:54:02 +08:00
caiyiling c23e9fb081 医学审核任务布局调整 2024-03-11 15:52:21 +08:00
caiyiling 2a4ddaf6f2 非表格问题清除病灶,添加定位及确认提示 2024-03-11 14:51:18 +08:00
caiyiling f67a5a9f43 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-11 14:06:50 +08:00
caiyiling d0e67f6937 suv测量工具默认激活 2024-03-11 14:05:28 +08:00
熊飞 c3a0d3e361 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-03-11 13:32:59 +08:00
熊飞 64691a2833 工作台待办任务换行 2024-03-11 13:32:52 +08:00
caiyiling 10fdbc427d 报告页查看历史影像 2024-03-11 11:08:31 +08:00
caiyiling 313bc28a96 bug修复 2024-03-11 10:53:16 +08:00
caiyiling ebddc9beb2 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-11 09:09:58 +08:00
caiyiling b2290ca739 脾脏状态计算更改 2024-03-11 09:09:33 +08:00
熊飞 81bc7f281d 工作台待办任务换行 2024-03-08 17:27:00 +08:00
熊飞 451fa0078d 工作台待办任务换行 2024-03-08 17:17:02 +08:00
熊飞 5d113f128f 工作台待办任务换行 2024-03-08 17:02:37 +08:00
熊飞 ad99367224 工作台待办任务换行 2024-03-08 16:42:16 +08:00
熊飞 8dedf6ee42 工作台待办任务换行 2024-03-08 15:01:06 +08:00
熊飞 f413ca60f3 工作台待办任务换行 2024-03-08 15:00:37 +08:00
熊飞 2ed3dd1376 工作台待办任务换行 2024-03-08 14:30:33 +08:00
熊飞 d5e41679c4 工作台待办任务换行 2024-03-08 13:56:52 +08:00
熊飞 0728220a2d 工作台待办任务换行 2024-03-08 13:29:52 +08:00
熊飞 15f0154b5d 工作台待办任务换行 2024-03-08 13:18:28 +08:00
熊飞 8ec94d0fa5 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-03-08 13:05:38 +08:00
熊飞 b574da9edf 国际化修改 2024-03-08 13:05:33 +08:00
caiyiling c559ff52b5 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-08 11:06:21 +08:00
caiyiling ab0744d550 基线摄取值变化 2024-03-08 11:05:59 +08:00
熊飞 80b4f123f8 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-03-08 10:07:42 +08:00
熊飞 25c14bc463 AWS 2024-03-08 10:07:35 +08:00
caiyiling cbec716a6d Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-08 09:59:20 +08:00
caiyiling 2dc2383d9d 影像融合布局调整及国际化处理 2024-03-08 09:58:45 +08:00
熊飞 c1c52f007f Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-03-07 17:45:21 +08:00
熊飞 299995dd09 中心医院关系 2024-03-07 17:45:15 +08:00
caiyiling aea1bf16bf lugano全局阅片列宽调整 2024-03-07 17:41:20 +08:00
caiyiling 6fa98f8deb Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-07 17:35:28 +08:00
caiyiling 2aef040a34 自动计算与基线相比摄取值变化 2024-03-07 17:33:39 +08:00
熊飞 2d50b6f320 临床数据PDF模版下载 2024-03-07 15:31:11 +08:00
熊飞 3fcefdb1f4 工作台 2024-03-07 15:10:04 +08:00
熊飞 f3c992bfc9 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-03-07 13:46:25 +08:00
熊飞 84ada9bc73 医学审核 2024-03-07 13:46:18 +08:00
caiyiling c34146ae76 医学审核签名保存 2024-03-07 13:37:29 +08:00
caiyiling ef4fab35b4 医学审核跳过任务 2024-03-07 13:34:00 +08:00
caiyiling 265f8771f5 国际化 2024-03-07 11:25:54 +08:00
caiyiling 48f3d4e40c Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-07 10:09:01 +08:00
caiyiling bd0f07aaed 全局阅片添加截止访视信息 2024-03-07 10:08:38 +08:00
熊飞 644cca6d0f 一致性分析 2024-03-06 17:50:50 +08:00
熊飞 0977570575 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-03-06 17:29:20 +08:00
熊飞 5acac110b1 一致性分析 2024-03-06 17:29:13 +08:00
caiyiling 7308f43f81 融合列表样式调整 2024-03-06 17:16:13 +08:00
caiyiling 22c9732382 融合界面国际化及布局调整 2024-03-06 17:12:15 +08:00
caiyiling 1154c700c3 医学审核布局调整 2024-03-06 16:53:05 +08:00
caiyiling 10a1238ab5 医学审核国际化 2024-03-06 16:09:24 +08:00
caiyiling 5782fa5f38 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-06 15:09:47 +08:00
caiyiling 8c5a364d23 医学审核优化 2024-03-06 15:09:33 +08:00
熊飞 ccb6aed115 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-03-06 14:19:08 +08:00
熊飞 a048167ab0 1 2024-03-06 14:19:03 +08:00
caiyiling d42bb57ee4 优化代码 2024-03-06 14:03:38 +08:00
caiyiling 91fee13101 优化代码 2024-03-06 13:58:19 +08:00
caiyiling d14b23761b 优化融合页面下载影像 2024-03-06 13:55:05 +08:00
caiyiling 1d3fa6a837 阅片期bug修复 2024-03-06 11:09:08 +08:00
caiyiling fb79702a65 融合病灶在后续访视添加标注 2024-03-05 17:35:52 +08:00
caiyiling d95e0958eb 融合病灶在后续访视添加标注 2024-03-05 17:20:10 +08:00
caiyiling b8384d111a 医学审核优化 2024-03-04 17:56:51 +08:00
caiyiling 2ba19fd395 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-04 17:56:22 +08:00
caiyiling 5859102225 医学审核优化 2024-03-04 17:55:47 +08:00
熊飞 19bc56bb66 国际化内容 2024-03-04 14:43:15 +08:00
熊飞 4d63318d8b 1 2024-03-01 15:14:00 +08:00
熊飞 7101276aab 工作台改版 2024-03-01 14:53:13 +08:00
熊飞 ee20254cf8 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-03-01 13:33:44 +08:00
熊飞 bd024773bd 工作台改版 2024-03-01 13:33:37 +08:00
caiyiling de40cb6ec5 医学审核样式修改 2024-03-01 09:47:55 +08:00
caiyiling c197e22f92 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-03-01 09:28:27 +08:00
caiyiling 8512b91ebd 肿瘤学bug修复 2024-03-01 09:27:49 +08:00
熊飞 0b82a73c9c Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-02-29 17:06:57 +08:00
熊飞 e7842282bf 工作台改版 2024-02-29 17:06:50 +08:00
caiyiling 9c4fc174d0 肿瘤学阅片bug修复 2024-02-29 15:22:04 +08:00
caiyiling 196dd3de92 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-02-29 14:25:09 +08:00
caiyiling f21d8871b5 阅片完成隐藏分裂融合 2024-02-29 14:24:45 +08:00
熊飞 95de39abcd Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-02-29 10:14:12 +08:00
熊飞 4f9022a18e 系统字典 2024-02-29 10:14:04 +08:00
caiyiling 62b69e8591 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-02-29 09:26:31 +08:00
caiyiling 6a4bffd8ab 非靶病灶分裂样式调整 2024-02-29 09:26:10 +08:00
熊飞 b2965e8c69 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-02-28 17:00:02 +08:00
熊飞 d3a88c0f55 配置 2024-02-28 16:59:57 +08:00
caiyiling 6cd8d2de5c Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-02-28 14:14:47 +08:00
caiyiling 74a8fa2524 lugano病灶保存验证 2024-02-28 14:14:23 +08:00
熊飞 1bbdf57fdb bug修复 2024-02-27 17:54:01 +08:00
熊飞 66c586009e Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-02-27 16:43:44 +08:00
熊飞 d224bf8700 bug修复 2024-02-27 16:43:38 +08:00
caiyiling 29e535a10a lugano病灶保存 2024-02-27 15:42:47 +08:00
caiyiling 1b905f1f9d 1 2024-02-27 15:10:41 +08:00
caiyiling 30c411d03f lugano病灶保存 2024-02-27 15:01:59 +08:00
caiyiling 6eb8957d1c lugano病灶保存提示 2024-02-27 14:05:00 +08:00
caiyiling 47288bcca0 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-02-27 14:03:48 +08:00
caiyiling 95d1207a45 lugano病灶保存提示 2024-02-27 14:02:54 +08:00
熊飞 33be113d8d 系统问题配置 2024-02-27 13:27:08 +08:00
熊飞 ad7b9054da 1 2024-02-27 13:26:14 +08:00
caiyiling f6eab06c78 suv测量工具优化 2024-02-26 17:23:16 +08:00
caiyiling ef732066f4 lugano suv测量工具更改 2024-02-26 13:25:14 +08:00
熊飞 82c80b71cc 阅片滑块在canvas外滑动 2024-02-23 17:15:42 +08:00
熊飞 ae69036777 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-02-23 17:14:46 +08:00
熊飞 c1008810d6 阅片滑块在canvas外滑动 2024-02-23 17:14:39 +08:00
caiyiling 0c4065102c lugano病灶融合 2024-02-23 14:46:54 +08:00
caiyiling c1faaf9ef0 lugano病灶融合 2024-02-23 14:35:55 +08:00
caiyiling 770df06c88 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-02-23 14:33:17 +08:00
caiyiling fcc239b54e lugano病灶融合 2024-02-23 14:33:01 +08:00
熊飞 2cc0b81c90 复制稽查记录 2024-02-23 14:27:02 +08:00
熊飞 e9a4509ced Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-02-23 13:09:57 +08:00
熊飞 ce3065d88f 切换国际化刷新 2024-02-23 13:09:50 +08:00
caiyiling f0dd5398c8 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-02-23 13:00:52 +08:00
caiyiling c1a9e848b0 lugano病灶融合 2024-02-23 12:59:42 +08:00
熊飞 89eaccf1c2 添加英文logo 2024-02-23 11:08:39 +08:00
熊飞 791746097d 添加英文logo 2024-02-23 10:50:25 +08:00
熊飞 1bf99379a8 1 2024-02-23 10:49:44 +08:00
熊飞 1cb52de265 去除MIM导表按钮 2024-02-23 10:27:40 +08:00
熊飞 0d9fabb596 修改邮箱修改按钮不能点 2024-02-23 10:07:15 +08:00
熊飞 101dd3210e 稽查二级页面空白处理 2024-02-23 09:50:37 +08:00
熊飞 6c0f148a77 稽查二级页面空白处理 2024-02-22 17:18:51 +08:00
熊飞 05cdf17282 稽查二级页面空白处理 2024-02-22 17:09:21 +08:00
熊飞 89f924d077 切换国际化刷新 2024-02-22 17:05:34 +08:00
熊飞 fa831ed6cc 1 2024-02-22 13:25:51 +08:00
熊飞 b9eaab1900 1 2024-02-22 09:58:33 +08:00
熊飞 ee15957aa7 空格问题 2024-02-22 09:47:04 +08:00
熊飞 f30e859e33 国际化问题 2024-02-22 09:44:40 +08:00
熊飞 949a09ac50 国际化问题 2024-02-21 16:52:16 +08:00
熊飞 e3ffd6d6c9 国际化问题 2024-02-21 16:44:13 +08:00
熊飞 8085585cfa 国际化问题 2024-02-21 16:41:11 +08:00
熊飞 d8cd8d336d 国际化问题 2024-02-21 16:22:13 +08:00
熊飞 8d9790f68e 国际化问题 2024-02-21 16:19:24 +08:00
熊飞 a1dc9e4031 国际化问题 2024-02-21 16:00:17 +08:00
熊飞 734e574713 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-02-21 15:43:37 +08:00
熊飞 9033119fb1 国际化问题 2024-02-21 15:43:31 +08:00
caiyiling 59b36aee8b Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-02-21 13:29:31 +08:00
caiyiling c5f86d0557 被融合的病灶在下次随访任务状态为消失且不能再操作 2024-02-21 13:28:38 +08:00
熊飞 f09901bcf6 1 2024-02-21 10:48:08 +08:00
熊飞 80597d1f98 1 2024-02-21 10:41:24 +08:00
熊飞 b56f3f1eb7 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-02-21 09:57:05 +08:00
熊飞 7e39c67fc2 1 2024-02-21 09:56:55 +08:00
caiyiling d995e1f729 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-02-21 09:11:27 +08:00
caiyiling 246e9a5bbd 弹窗布局调整 2024-02-21 09:10:41 +08:00
熊飞 dc60128cae 国际化问题 2024-02-20 17:11:51 +08:00
熊飞 052fdbcdbf 国际化问题 2024-02-20 16:49:59 +08:00
caiyiling 9929045d4b 添加融合标识 2024-02-20 16:37:11 +08:00
caiyiling 893a528bfc Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main 2024-02-20 15:54:42 +08:00
caiyiling 6e95127522 lugano病灶融合 2024-02-20 15:54:22 +08:00
熊飞 9906f44677 Go to next document?国际化 2024-02-20 11:44:34 +08:00
熊飞 4de108cd42 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2024-02-20 11:41:15 +08:00
熊飞 be96b2e93e 滑块跳动 2024-02-20 11:41:08 +08:00
caiyiling ee8b630806 lugano病灶分裂 2024-02-20 10:06:30 +08:00
熊飞 6778784111 1
continuous-integration/drone/push Build is passing
2024-02-05 09:52:06 +08:00
熊飞 6a8308fe5f 1 2024-02-05 09:51:03 +08:00
caiyiling 227009eb39 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2024-02-05 09:44:00 +08:00
caiyiling f09bf427e5 临床数据图标 2024-02-05 09:43:42 +08:00
熊飞 2a6d0faf11 1
continuous-integration/drone/push Build is passing
2024-02-05 09:25:14 +08:00
熊飞 61993e331b 1
continuous-integration/drone/push Build is passing
2024-02-04 18:01:33 +08:00
熊飞 ddd7e4638c 1 2024-02-04 18:00:34 +08:00
451 changed files with 52213 additions and 23638 deletions
+7 -1
View File
@@ -14,6 +14,9 @@ VUE_CLI_BABEL_TRANSPILE_MODULES = false
# 是否开启登陆限制 true:是 false:否
VUE_APP_LOGIN_FOR_PERMISSION = false
# 是否开启长时间无操作锁定弹框MFA验证 true:是 false:否
VUE_APP_LOCK_FOR_PERMISSION_MFA = false
# 是否开启长时间无操作锁定弹框 true:是 false:否
VUE_APP_LOCK_FOR_PERMISSION = false
@@ -27,7 +30,7 @@ VUE_APP_LOGOUT_FOR_PERMISSION = false
VUE_APP_LOGOUT_FOR_TIME = 1800
# 是否开启密码正则验证 true:是 false:否
VUE_APP_PASSWORD_FOR_PERMISSION = true
VUE_APP_PASSWORD_FOR_PERMISSION = false
# 密码校验规则
VUE_APP_PASSWORD_FOR_REGULAR = ^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[-_.@^+\$!%#*?&\$~])[A-Za-z0-9-~_.@^+\$~!%#*?&]{8,32}$
@@ -35,6 +38,9 @@ VUE_APP_PASSWORD_FOR_REGULAR = ^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[-_.@^+\$!
# 是否开启文档签署验证 true:是 false:否
VUE_APP_WORD_FOR_PERMISSION = false
# 公司名称
VUE_APP_COMPANY_NAME = "Extensive Imaging"
# dicom文件地址
VUE_APP_DICOM_PATH = 'https://zyypacs.oss-cn-shanghai.aliyuncs.com'
+6
View File
@@ -8,6 +8,9 @@ VUE_APP_BASE_PATH = '/'
# 是否开启登陆限制 true:是 false:否
VUE_APP_LOGIN_FOR_PERMISSION = true
# 是否开启长时间无操作锁定弹框MFA验证 true:是 false:否
VUE_APP_LOCK_FOR_PERMISSION_MFA = false
# 是否开启长时间无操作锁定弹框 true:是 false:否
VUE_APP_LOCK_FOR_PERMISSION = true
@@ -29,6 +32,9 @@ VUE_APP_PASSWORD_FOR_REGULAR = ^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[-_.@^+\$!
# 是否开启文档签署验证 true:是 false:否
VUE_APP_WORD_FOR_PERMISSION = true
# 公司名称
VUE_APP_COMPANY_NAME = "Extensive Imaging"
# dicom文件地址
# VUE_APP_DICOM_PATH = 'http://101.132.193.237:7080'
VUE_APP_DICOM_PATH = 'https://zyypacs-prod.oss-cn-shanghai.aliyuncs.com'
+3
View File
@@ -9,6 +9,9 @@ VUE_APP_IS_TEST = true
# 是否开启登陆限制 true:是 false:否
VUE_APP_LOGIN_FOR_PERMISSION = false
# 是否开启长时间无操作锁定弹框MFA验证 true:是 false:否
VUE_APP_LOCK_FOR_PERMISSION_MFA = false
# 是否开启长时间无操作锁定弹框 true:是 false:否
VUE_APP_LOCK_FOR_PERMISSION = false
+3
View File
@@ -5,6 +5,9 @@ NODE_ENV = 'prop'
# 是否开启登陆限制 true:是 false:否
VUE_APP_LOGIN_FOR_PERMISSION = true
# 是否开启长时间无操作锁定弹框MFA验证 true:是 false:否
VUE_APP_LOCK_FOR_PERMISSION_MFA = false
# 是否开启长时间无操作锁定弹框 true:是 false:否
VUE_APP_LOCK_FOR_PERMISSION = true
+6
View File
@@ -10,6 +10,9 @@ VUE_APP_BASE_PATH = '/'
# 是否开启登陆限制 true:是 false:否
VUE_APP_LOGIN_FOR_PERMISSION = true
# 是否开启长时间无操作锁定弹框MFA验证 true:是 false:否
VUE_APP_LOCK_FOR_PERMISSION_MFA = false
# 是否开启长时间无操作锁定弹框 true:是 false:否
VUE_APP_LOCK_FOR_PERMISSION = true
@@ -31,6 +34,9 @@ VUE_APP_PASSWORD_FOR_REGULAR = ^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[-_.@^+\$!
# 是否开启文档签署验证 true:是 false:否
VUE_APP_WORD_FOR_PERMISSION = true
# 公司名称
VUE_APP_COMPANY_NAME = "Extensive Imaging"
# dicom文件地址
VUE_APP_DICOM_PATH = 'https://zyypacs-uat.oss-cn-shanghai.aliyuncs.com'
+13 -7
View File
@@ -1,26 +1,29 @@
# just a flag
ENV = 'production'
NODE_ENV = 'production'
ENV = 'usa'
NODE_ENV = 'usa'
# base public path
VUE_APP_BASE_PATH = 'https://ei-code-prod.s3.amazonaws.com/2024-01-31/'
VUE_APP_BASE_PATH = 'https://ei-code-prod.s3.amazonaws.com/2024-07-30/'
# 是否开启登陆限制 true:是 false:否
VUE_APP_LOGIN_FOR_PERMISSION = false
VUE_APP_LOGIN_FOR_PERMISSION = true
# 是否开启长时间无操作锁定弹框MFA验证 true:是 false:否
VUE_APP_LOCK_FOR_PERMISSION_MFA = true
# 是否开启长时间无操作锁定弹框 true:是 false:否
VUE_APP_LOCK_FOR_PERMISSION = false
VUE_APP_LOCK_FOR_PERMISSION = true
# 无操作锁定弹框判断时间 单位:秒
VUE_APP_LOCK_FOR_TIME = 900
# 是否开启长时间无操作登出 true:是 false:否
VUE_APP_LOGOUT_FOR_PERMISSION = false
VUE_APP_LOGOUT_FOR_PERMISSION = true
# 无操作锁定弹框判断时间 单位:秒
VUE_APP_LOGOUT_FOR_TIME = 1800
# 是否开启密码正则验证 true:是 false:否
VUE_APP_PASSWORD_FOR_PERMISSION = 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}$
@@ -28,6 +31,9 @@ VUE_APP_PASSWORD_FOR_REGULAR = ^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[-_.@^+\$!
# 是否开启文档签署验证 true:是 false:否
VUE_APP_WORD_FOR_PERMISSION = true
# 公司名称
VUE_APP_COMPANY_NAME = "Elevate Imaging"
# dicom文件地址
VUE_APP_DICOM_PATH = 'https://zyypacs-usa.oss-us-west-1.aliyuncs.com'
+46
View File
@@ -0,0 +1,46 @@
# just a flag
ENV = 'usa'
NODE_ENV = 'usa'
# base public path
VUE_APP_BASE_PATH = 'https://ei-med-s3-code.s3.amazonaws.com/2024-07-30/'
# 是否开启登陆限制 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-usa.oss-us-west-1.aliyuncs.com'
VUE_APP_DICOM_USA_PATH = 'https://zyypacs-usa.oss-us-west-1.aliyuncs.com'
VUE_APP_OSS_CONFIG_REGION = 'oss-us-west-1'
VUE_APP_OSS_CONFIG_BUCKET = 'zyypacs-usa'
VUE_APP_OSS_PATH = '/usa/dist'
+32 -31
View File
@@ -1,3 +1,32 @@
kind: pipeline
type: ssh
name: ssh-linux-uat-irc-publish
platform:
os: Linux
arch: 386
clone:
disable: true #禁用默认克隆
server:
host: 47.117.164.182
user: root
password:
from_secret: local_pwd
steps:
- name: uat-branch-publish-irc-vue
commands:
- cd /opt/1panel/vue-devops/Uat_IRC/Uat-To-Uat
- sh uat-to-uat.sh v${DRONE_BUILD_NUMBER}
trigger:
branch:
- uat
---
kind: pipeline
type: ssh
name: ssh-linux-test-irc-publish
@@ -10,7 +39,7 @@ clone:
disable: true #禁用默认克隆
server:
host: 192.168.3.68
host: 106.14.89.110
user: root
password:
from_secret: local_pwd
@@ -19,42 +48,14 @@ steps:
- name: publish-test-irc-vue
commands:
- echo start publish test-irc-vue
- cd /opt/hang/vue/test-irc
- cd /opt/1panel/hang/vue/test-irc
- sh test-irc.sh v${DRONE_BUILD_NUMBER}
trigger:
branch:
- main
---
kind: pipeline
type: ssh
name: ssh-linux-test-study-publish
platform:
os: Linux
arch: 386
clone:
disable: true #禁用默认克隆
server:
host: 123.56.94.154
user: root
password:
from_secret: local_pwd
steps:
- name: publish-test-study
commands:
- echo start publish test-study-api
- cd /opt/1panel/hang/devops/test-study
- sh test-study.sh v${DRONE_BUILD_NUMBER}
trigger:
branch:
- Test.Study
+235 -181
View File
@@ -1,6 +1,6 @@
{
"name": "EICS",
"version": "1.0.0",
"version": "1.3.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -19,7 +19,6 @@
"version": "2.2.1",
"resolved": "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.2.1.tgz",
"integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
"dev": true,
"requires": {
"@jridgewell/gen-mapping": "^0.3.0",
"@jridgewell/trace-mapping": "^0.3.9"
@@ -29,7 +28,6 @@
"version": "7.23.5",
"resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.23.5.tgz",
"integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
"dev": true,
"requires": {
"@babel/highlight": "^7.23.4",
"chalk": "^2.4.2"
@@ -38,14 +36,12 @@
"@babel/compat-data": {
"version": "7.23.5",
"resolved": "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.23.5.tgz",
"integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==",
"dev": true
"integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw=="
},
"@babel/core": {
"version": "7.23.6",
"resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.23.6.tgz",
"integrity": "sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==",
"dev": true,
"requires": {
"@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.23.5",
@@ -67,14 +63,34 @@
"json5": {
"version": "2.2.3",
"resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="
},
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
}
}
},
"@babel/eslint-parser": {
"version": "7.24.8",
"resolved": "https://registry.npmmirror.com/@babel/eslint-parser/-/eslint-parser-7.24.8.tgz",
"integrity": "sha512-nYAikI4XTGokU2QX7Jx+v4rxZKhKivaQaREZjuW3mrJrbdWJ5yUfohnoUULge+zEEaKjPYNxhoRgUKktjXtbwA==",
"requires": {
"@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1",
"eslint-visitor-keys": "^2.1.0",
"semver": "^6.3.1"
},
"dependencies": {
"eslint-visitor-keys": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw=="
},
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
}
}
},
@@ -82,7 +98,6 @@
"version": "7.23.6",
"resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.23.6.tgz",
"integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==",
"dev": true,
"requires": {
"@babel/types": "^7.23.6",
"@jridgewell/gen-mapping": "^0.3.2",
@@ -112,7 +127,6 @@
"version": "7.23.6",
"resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz",
"integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==",
"dev": true,
"requires": {
"@babel/compat-data": "^7.23.5",
"@babel/helper-validator-option": "^7.23.5",
@@ -125,7 +139,6 @@
"version": "5.1.1",
"resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz",
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
"dev": true,
"requires": {
"yallist": "^3.0.2"
}
@@ -133,14 +146,12 @@
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
},
"yallist": {
"version": "3.1.1",
"resolved": "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz",
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
"dev": true
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
}
}
},
@@ -204,14 +215,12 @@
"@babel/helper-environment-visitor": {
"version": "7.22.20",
"resolved": "https://registry.npmmirror.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
"integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
"dev": true
"integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA=="
},
"@babel/helper-function-name": {
"version": "7.23.0",
"resolved": "https://registry.npmmirror.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
"integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
"dev": true,
"requires": {
"@babel/template": "^7.22.15",
"@babel/types": "^7.23.0"
@@ -221,7 +230,6 @@
"version": "7.22.5",
"resolved": "https://registry.npmmirror.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
"integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
"dev": true,
"requires": {
"@babel/types": "^7.22.5"
}
@@ -239,7 +247,6 @@
"version": "7.22.15",
"resolved": "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz",
"integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==",
"dev": true,
"requires": {
"@babel/types": "^7.22.15"
}
@@ -248,7 +255,6 @@
"version": "7.23.3",
"resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz",
"integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==",
"dev": true,
"requires": {
"@babel/helper-environment-visitor": "^7.22.20",
"@babel/helper-module-imports": "^7.22.15",
@@ -298,7 +304,6 @@
"version": "7.22.5",
"resolved": "https://registry.npmmirror.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz",
"integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==",
"dev": true,
"requires": {
"@babel/types": "^7.22.5"
}
@@ -316,7 +321,6 @@
"version": "7.22.6",
"resolved": "https://registry.npmmirror.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
"integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
"dev": true,
"requires": {
"@babel/types": "^7.22.5"
}
@@ -324,20 +328,17 @@
"@babel/helper-string-parser": {
"version": "7.23.4",
"resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz",
"integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==",
"dev": true
"integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ=="
},
"@babel/helper-validator-identifier": {
"version": "7.22.20",
"resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
"integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
"dev": true
"integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A=="
},
"@babel/helper-validator-option": {
"version": "7.23.5",
"resolved": "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz",
"integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==",
"dev": true
"integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw=="
},
"@babel/helper-wrap-function": {
"version": "7.22.20",
@@ -354,7 +355,6 @@
"version": "7.23.6",
"resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.23.6.tgz",
"integrity": "sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==",
"dev": true,
"requires": {
"@babel/template": "^7.22.15",
"@babel/traverse": "^7.23.6",
@@ -365,7 +365,6 @@
"version": "7.23.4",
"resolved": "https://registry.npmmirror.com/@babel/highlight/-/highlight-7.23.4.tgz",
"integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
"dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.22.20",
"chalk": "^2.4.2",
@@ -375,8 +374,7 @@
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
}
}
},
@@ -1326,7 +1324,6 @@
"version": "7.22.15",
"resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.22.15.tgz",
"integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.22.13",
"@babel/parser": "^7.22.15",
@@ -1337,7 +1334,6 @@
"version": "7.23.6",
"resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.23.6.tgz",
"integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.23.5",
"@babel/generator": "^7.23.6",
@@ -1354,8 +1350,7 @@
"globals": {
"version": "11.12.0",
"resolved": "https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz",
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
"dev": true
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
}
}
},
@@ -1363,7 +1358,6 @@
"version": "7.23.6",
"resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.23.6.tgz",
"integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==",
"dev": true,
"requires": {
"@babel/helper-string-parser": "^7.23.4",
"@babel/helper-validator-identifier": "^7.22.20",
@@ -1373,8 +1367,7 @@
"to-fast-properties": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
"integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
"dev": true
"integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog=="
}
}
},
@@ -1581,11 +1574,15 @@
}
}
},
"@istanbuljs/schema": {
"version": "0.1.3",
"resolved": "https://registry.npmmirror.com/@istanbuljs/schema/-/schema-0.1.3.tgz",
"integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA=="
},
"@jridgewell/gen-mapping": {
"version": "0.3.3",
"resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
"integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
"dev": true,
"requires": {
"@jridgewell/set-array": "^1.0.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
@@ -1595,31 +1592,61 @@
"@jridgewell/resolve-uri": {
"version": "3.1.1",
"resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
"integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
"dev": true
"integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA=="
},
"@jridgewell/set-array": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.1.2.tgz",
"integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
"dev": true
"integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw=="
},
"@jridgewell/sourcemap-codec": {
"version": "1.4.15",
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
"dev": true
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
},
"@jridgewell/trace-mapping": {
"version": "0.3.20",
"resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz",
"integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==",
"dev": true,
"requires": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"@jsdevtools/coverage-istanbul-loader": {
"version": "3.0.5",
"resolved": "https://registry.npmmirror.com/@jsdevtools/coverage-istanbul-loader/-/coverage-istanbul-loader-3.0.5.tgz",
"integrity": "sha512-EUCPEkaRPvmHjWAAZkWMT7JDzpw7FKB00WTISaiXsbNOd5hCHg77XLA8sLYLFDo1zepYLo2w7GstN8YBqRXZfA==",
"requires": {
"convert-source-map": "^1.7.0",
"istanbul-lib-instrument": "^4.0.3",
"loader-utils": "^2.0.0",
"merge-source-map": "^1.1.0",
"schema-utils": "^2.7.0"
},
"dependencies": {
"convert-source-map": {
"version": "1.9.0",
"resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-1.9.0.tgz",
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="
},
"json5": {
"version": "2.2.3",
"resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="
},
"loader-utils": {
"version": "2.0.4",
"resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz",
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
}
}
},
"@kitware/vtk.js": {
"version": "27.3.1",
"resolved": "https://registry.npmmirror.com/@kitware/vtk.js/-/vtk.js-27.3.1.tgz",
@@ -1718,6 +1745,25 @@
"glob-to-regexp": "^0.3.0"
}
},
"@nicolo-ribaudo/eslint-scope-5-internals": {
"version": "5.1.1-v1",
"resolved": "https://registry.npmmirror.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz",
"integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==",
"requires": {
"eslint-scope": "5.1.1"
},
"dependencies": {
"eslint-scope": {
"version": "5.1.1",
"resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-5.1.1.tgz",
"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
"requires": {
"esrecurse": "^4.3.0",
"estraverse": "^4.1.1"
}
}
}
},
"@node-ipc/js-queue": {
"version": "2.0.3",
"resolved": "https://registry.npmmirror.com/@node-ipc/js-queue/-/js-queue-2.0.3.tgz",
@@ -3084,7 +3130,6 @@
"dev": true,
"optional": true,
"requires": {
"bindings": "^1.5.0",
"nan": "^2.12.1"
}
},
@@ -4332,6 +4377,26 @@
"zip-stream": "^4.1.0"
},
"dependencies": {
"compress-commons": {
"version": "4.1.2",
"resolved": "https://registry.npmmirror.com/compress-commons/-/compress-commons-4.1.2.tgz",
"integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==",
"requires": {
"buffer-crc32": "^0.2.13",
"crc32-stream": "^4.0.2",
"normalize-path": "^3.0.0",
"readable-stream": "^3.6.0"
}
},
"crc32-stream": {
"version": "4.0.3",
"resolved": "https://registry.npmmirror.com/crc32-stream/-/crc32-stream-4.0.3.tgz",
"integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==",
"requires": {
"crc-32": "^1.2.0",
"readable-stream": "^3.4.0"
}
},
"readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz",
@@ -4341,6 +4406,35 @@
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
},
"zip-stream": {
"version": "4.1.1",
"resolved": "https://registry.npmmirror.com/zip-stream/-/zip-stream-4.1.1.tgz",
"integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==",
"requires": {
"archiver-utils": "^3.0.4",
"compress-commons": "^4.1.2",
"readable-stream": "^3.6.0"
},
"dependencies": {
"archiver-utils": {
"version": "3.0.4",
"resolved": "https://registry.npmmirror.com/archiver-utils/-/archiver-utils-3.0.4.tgz",
"integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==",
"requires": {
"glob": "^7.2.3",
"graceful-fs": "^4.2.0",
"lazystream": "^1.0.0",
"lodash.defaults": "^4.2.0",
"lodash.difference": "^4.5.0",
"lodash.flatten": "^4.4.0",
"lodash.isplainobject": "^4.0.6",
"lodash.union": "^4.6.0",
"normalize-path": "^3.0.0",
"readable-stream": "^3.6.0"
}
}
}
}
}
},
@@ -5086,16 +5180,6 @@
"resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz",
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA=="
},
"bindings": {
"version": "1.5.0",
"resolved": "https://registry.npmmirror.com/bindings/-/bindings-1.5.0.tgz",
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
"dev": true,
"optional": true,
"requires": {
"file-uri-to-path": "1.0.0"
}
},
"bl": {
"version": "4.1.0",
"resolved": "https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz",
@@ -5379,7 +5463,6 @@
"version": "4.22.2",
"resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.22.2.tgz",
"integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==",
"dev": true,
"requires": {
"caniuse-lite": "^1.0.30001565",
"electron-to-chromium": "^1.4.601",
@@ -5659,8 +5742,7 @@
"caniuse-lite": {
"version": "1.0.30001568",
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001568.tgz",
"integrity": "sha512-vSUkH84HontZJ88MiNrOau1EBrCqEQYgkC5gIySiDlpsm8sGVrhU7Kx4V6h0tnqaHzIHZv08HlJIwPbL4XL9+A==",
"dev": true
"integrity": "sha512-vSUkH84HontZJ88MiNrOau1EBrCqEQYgkC5gIySiDlpsm8sGVrhU7Kx4V6h0tnqaHzIHZv08HlJIwPbL4XL9+A=="
},
"case-sensitive-paths-webpack-plugin": {
"version": "2.4.0",
@@ -6252,29 +6334,6 @@
"integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==",
"dev": true
},
"compress-commons": {
"version": "4.1.2",
"resolved": "https://registry.npmmirror.com/compress-commons/-/compress-commons-4.1.2.tgz",
"integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==",
"requires": {
"buffer-crc32": "^0.2.13",
"crc32-stream": "^4.0.2",
"normalize-path": "^3.0.0",
"readable-stream": "^3.6.0"
},
"dependencies": {
"readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
}
}
},
"compressible": {
"version": "2.0.18",
"resolved": "https://registry.npmmirror.com/compressible/-/compressible-2.0.18.tgz",
@@ -6444,8 +6503,7 @@
"convert-source-map": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz",
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
"dev": true
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="
},
"cookie": {
"version": "0.5.0",
@@ -6555,12 +6613,32 @@
}
},
"cornerstone-wado-image-loader": {
"version": "3.3.2",
"resolved": "https://registry.npmmirror.com/cornerstone-wado-image-loader/-/cornerstone-wado-image-loader-3.3.2.tgz",
"integrity": "sha512-Yy0DtfSMlflMS5RMQhX9YnXiYYkZz99nnXG2qtBRvzvSdwqiElIpE13sKw0Ohi4mqNwrWRx0xt8utk0HKnAXyw==",
"version": "4.13.2",
"resolved": "https://registry.npmmirror.com/cornerstone-wado-image-loader/-/cornerstone-wado-image-loader-4.13.2.tgz",
"integrity": "sha512-NGqH44bY1VMY8OYuVykkLriNtZQrmoZU/S6f/1t1xX3rMc+WUMNN+yi4Nu3jp6nckLdH/bVGiigoJXrp0dTrAg==",
"requires": {
"dicom-parser": "^1.8.3",
"pako": "^1.0.10"
"@babel/eslint-parser": "^7.19.1",
"@cornerstonejs/codec-charls": "^1.2.3",
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.2",
"@cornerstonejs/codec-openjph": "^2.4.2",
"coverage-istanbul-loader": "^3.0.5",
"date-format": "^4.0.14",
"dicom-parser": "^1.8.9",
"pako": "^2.0.4",
"uuid": "^9.0.0"
},
"dependencies": {
"pako": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/pako/-/pako-2.1.0.tgz",
"integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug=="
},
"uuid": {
"version": "9.0.1",
"resolved": "https://registry.npmmirror.com/uuid/-/uuid-9.0.1.tgz",
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="
}
}
},
"cosmiconfig": {
@@ -6587,32 +6665,19 @@
}
}
},
"coverage-istanbul-loader": {
"version": "3.0.5",
"resolved": "https://registry.npmmirror.com/coverage-istanbul-loader/-/coverage-istanbul-loader-3.0.5.tgz",
"integrity": "sha512-xsw2phF0VNqUPk47V/vHXkdcTyl0tkMSmaZfLrTOhoPhPMXFelNju7utl5s7I93KXzipqDEK0YwofQSSflPz8A==",
"requires": {
"@jsdevtools/coverage-istanbul-loader": "3.0.5"
}
},
"crc-32": {
"version": "1.2.2",
"resolved": "https://registry.npmmirror.com/crc-32/-/crc-32-1.2.2.tgz",
"integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ=="
},
"crc32-stream": {
"version": "4.0.3",
"resolved": "https://registry.npmmirror.com/crc32-stream/-/crc32-stream-4.0.3.tgz",
"integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==",
"requires": {
"crc-32": "^1.2.0",
"readable-stream": "^3.4.0"
},
"dependencies": {
"readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
}
}
},
"create-ecdh": {
"version": "4.0.4",
"resolved": "https://registry.npmmirror.com/create-ecdh/-/create-ecdh-4.0.4.tgz",
@@ -7101,6 +7166,11 @@
"resolved": "https://registry.npmmirror.com/date-fns/-/date-fns-1.30.1.tgz",
"integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw=="
},
"date-format": {
"version": "4.0.14",
"resolved": "https://registry.npmmirror.com/date-format/-/date-format-4.0.14.tgz",
"integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg=="
},
"dateformat": {
"version": "2.2.0",
"resolved": "https://registry.npmmirror.com/dateformat/-/dateformat-2.2.0.tgz",
@@ -7613,8 +7683,7 @@
"electron-to-chromium": {
"version": "1.4.611",
"resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.611.tgz",
"integrity": "sha512-ZtRpDxrjHapOwxtv+nuth5ByB8clyn8crVynmRNGO3wG3LOp8RTcyZDqwaI6Ng6y8FCK2hVZmJoqwCskKbNMaw==",
"dev": true
"integrity": "sha512-ZtRpDxrjHapOwxtv+nuth5ByB8clyn8crVynmRNGO3wG3LOp8RTcyZDqwaI6Ng6y8FCK2hVZmJoqwCskKbNMaw=="
},
"elegant-spinner": {
"version": "1.0.1",
@@ -7821,8 +7890,7 @@
"escalade": {
"version": "3.1.1",
"resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.1.1.tgz",
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
"dev": true
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw=="
},
"escape-html": {
"version": "1.0.3",
@@ -8085,7 +8153,6 @@
"version": "4.3.0",
"resolved": "https://registry.npmmirror.com/esrecurse/-/esrecurse-4.3.0.tgz",
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
"dev": true,
"requires": {
"estraverse": "^5.2.0"
},
@@ -8093,16 +8160,14 @@
"estraverse": {
"version": "5.3.0",
"resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="
}
}
},
"estraverse": {
"version": "4.3.0",
"resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-4.3.0.tgz",
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
"dev": true
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="
},
"esutils": {
"version": "2.0.3",
@@ -8542,13 +8607,6 @@
"resolved": "https://registry.npmmirror.com/file-saver/-/file-saver-2.0.5.tgz",
"integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
},
"file-uri-to-path": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
"dev": true,
"optional": true
},
"filesize": {
"version": "3.6.1",
"resolved": "https://registry.npmmirror.com/filesize/-/filesize-3.6.1.tgz",
@@ -8878,8 +8936,7 @@
"gensync": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz",
"integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
"dev": true
"integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="
},
"get-caller-file": {
"version": "2.0.5",
@@ -10467,6 +10524,29 @@
"resolved": "https://registry.npmmirror.com/isstream/-/isstream-0.1.2.tgz",
"integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g=="
},
"istanbul-lib-coverage": {
"version": "3.2.2",
"resolved": "https://registry.npmmirror.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
"integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg=="
},
"istanbul-lib-instrument": {
"version": "4.0.3",
"resolved": "https://registry.npmmirror.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz",
"integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==",
"requires": {
"@babel/core": "^7.7.5",
"@istanbuljs/schema": "^0.1.2",
"istanbul-lib-coverage": "^3.0.0",
"semver": "^6.3.0"
},
"dependencies": {
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
}
}
},
"javascript-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/javascript-stringify/-/javascript-stringify-2.1.0.tgz",
@@ -10518,8 +10598,7 @@
"jsesc": {
"version": "2.5.2",
"resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz",
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
"dev": true
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
},
"json-parse-better-errors": {
"version": "1.0.2",
@@ -11197,7 +11276,6 @@
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/merge-source-map/-/merge-source-map-1.1.0.tgz",
"integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==",
"dev": true,
"requires": {
"source-map": "^0.6.1"
},
@@ -11205,8 +11283,7 @@
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
}
}
},
@@ -11520,6 +11597,15 @@
"resolved": "https://registry.npmmirror.com/moment/-/moment-2.29.4.tgz",
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
},
"moment-timezone": {
"version": "0.5.45",
"resolved": "https://registry.npmmirror.com/moment-timezone/-/moment-timezone-0.5.45.tgz",
"integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==",
"dev": true,
"requires": {
"moment": "^2.29.4"
}
},
"move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/move-concurrently/-/move-concurrently-1.0.1.tgz",
@@ -11913,8 +11999,7 @@
"node-releases": {
"version": "2.0.14",
"resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.14.tgz",
"integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
"dev": true
"integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw=="
},
"node-sass": {
"version": "4.14.1",
@@ -14214,6 +14299,11 @@
"integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==",
"dev": true
},
"qrcodejs2": {
"version": "0.0.2",
"resolved": "https://registry.npmmirror.com/qrcodejs2/-/qrcodejs2-0.0.2.tgz",
"integrity": "sha512-+Y4HA+cb6qUzdgvI3KML8GYpMFwB24dFwzMkS/yXq6hwtUGNUnZQdUnksrV1XGMc2mid5ROw5SAuY9XhI3ValA=="
},
"qs": {
"version": "6.11.2",
"resolved": "https://registry.npmmirror.com/qs/-/qs-6.11.2.tgz",
@@ -15832,6 +15922,11 @@
"resolved": "https://registry.npmmirror.com/stream-wormhole/-/stream-wormhole-1.1.0.tgz",
"integrity": "sha512-gHFfL3px0Kctd6Po0M8TzEvt3De/xu6cnRrjlfYNhwbhLPLwigI2t1nc6jrzNuaYg5C4YF78PPFuQPzRiqn9ew=="
},
"streamsaver": {
"version": "2.0.6",
"resolved": "https://registry.npmmirror.com/streamsaver/-/streamsaver-2.0.6.tgz",
"integrity": "sha512-LK4e7TfCV8HzuM0PKXuVUfKyCB1FtT9L0EGxsFk5Up8njj0bXK8pJM9+Wq2Nya7/jslmCQwRK39LFm55h7NBTw=="
},
"strict-uri-encode": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
@@ -17151,7 +17246,6 @@
"version": "1.0.13",
"resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
"integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
"dev": true,
"requires": {
"escalade": "^3.1.1",
"picocolors": "^1.0.0"
@@ -17758,7 +17852,6 @@
"dev": true,
"optional": true,
"requires": {
"bindings": "^1.5.0",
"nan": "^2.12.1"
}
},
@@ -18889,45 +18982,6 @@
}
}
},
"zip-stream": {
"version": "4.1.1",
"resolved": "https://registry.npmmirror.com/zip-stream/-/zip-stream-4.1.1.tgz",
"integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==",
"requires": {
"archiver-utils": "^3.0.4",
"compress-commons": "^4.1.2",
"readable-stream": "^3.6.0"
},
"dependencies": {
"archiver-utils": {
"version": "3.0.4",
"resolved": "https://registry.npmmirror.com/archiver-utils/-/archiver-utils-3.0.4.tgz",
"integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==",
"requires": {
"glob": "^7.2.3",
"graceful-fs": "^4.2.0",
"lazystream": "^1.0.0",
"lodash.defaults": "^4.2.0",
"lodash.difference": "^4.5.0",
"lodash.flatten": "^4.4.0",
"lodash.isplainobject": "^4.0.6",
"lodash.union": "^4.6.0",
"normalize-path": "^3.0.0",
"readable-stream": "^3.6.0"
}
},
"readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
}
}
},
"zrender": {
"version": "4.3.2",
"resolved": "https://registry.npmmirror.com/zrender/-/zrender-4.3.2.tgz",
+9 -5
View File
@@ -2,11 +2,12 @@
"name": "EICS",
"version": "1.3.2",
"scripts": {
"dev": "vue-cli-service serve --open",
"dev": "vue-cli-service serve --open --mode development",
"build": "vue-cli-service build",
"build:prod": "vue-cli-service build --mode prod",
"build:uat": "vue-cli-service build --mode uat",
"build:usa": "vue-cli-service build --mode usa",
"build:usa_prod": "vue-cli-service build --mode usa_prod",
"pre": "vue-cli-service build --mode pre",
"i18n": "npm run i18n:zh && npm run i18n:en",
"i18n:zh": "node i18nGenerate.js lang=zh keyCol=5 valCol=6",
@@ -27,10 +28,10 @@
"babel-eslint": "7.2.3",
"copy-webpack-plugin": "^4.5.2",
"core-js": "^3.8.3",
"cornerstone-core": "^2.3.0",
"cornerstone-math": "^0.1.8",
"cornerstone-tools": "^6.0.8",
"cornerstone-wado-image-loader": "^3.1.2",
"cornerstone-core": "^2.6.1",
"cornerstone-math": "^0.1.10",
"cornerstone-tools": "^6.0.10",
"cornerstone-wado-image-loader": "^4.13.2",
"dcmjs": "^0.29.8",
"dicom-parser": "^1.8.9",
"dicomedit": "^0.1.0",
@@ -50,9 +51,11 @@
"path-to-regexp": "2.4.0",
"pdfobject": "^2.2.8",
"popper.js": "^1.16.1",
"qrcodejs2": "0.0.2",
"sass-loader": "^8.0.0",
"screenfull": "^4.2.0",
"sortablejs": "^1.15.0",
"streamsaver": "^2.0.6",
"v-viewer": "^1.6.4",
"vcrontab": "^0.3.5",
"vue": "^2.6.11",
@@ -83,6 +86,7 @@
"eslint-plugin-vue": "^6.2.2",
"html-webpack-plugin": "3.2.0",
"minio": "^7.1.3",
"moment-timezone": "^0.5.45",
"node-xlsx": "^0.21.0",
"runjs": "^4.3.2",
"script-ext-html-webpack-plugin": "2.1.3",
+189 -103
View File
@@ -1,169 +1,241 @@
<template>
<div id="app" style="position: relative">
<router-view />
<div v-show="show" v-adaptive @click="openI18n" style="position: fixed;bottom: 50px;left: 50px;z-index: 100000;width: 50px;height: 50px;background: #409eff88;line-height: 50px;text-align: center;color:#fff;border-radius: 50%;cursor: pointer">
<div
v-show="show"
v-adaptive
@click="openI18n"
style="
position: fixed;
bottom: 50px;
left: 50px;
z-index: 100000;
width: 50px;
height: 50px;
background: #409eff88;
line-height: 50px;
text-align: center;
color: #fff;
border-radius: 50%;
cursor: pointer;
"
>
i18n
</div>
<el-drawer
title="国际化"
:visible.sync="drawer"
direction="rtl"
size="80%">
<el-drawer title="国际化" :visible.sync="drawer" direction="rtl" size="80%">
<div style="width: 320px">
<el-form
label-width="100px"
@submit.native.prevent
size="small"
>
<el-form label-width="100px" @submit.native.prevent size="small">
<el-form-item label="关键字">
<el-input v-model="key" @input="keyChange"/>
<el-input v-model="key" @input="keyChange" />
</el-form-item>
</el-form>
</div>
<el-table
:data="tableData"
v-adaptive="{bottomOffset:50}"
v-adaptive="{ bottomOffset: 50 }"
height="100"
style="width: 100%">
<el-table-column
prop="Code"
label="标签"
width="300">
style="width: 100%"
>
<el-table-column prop="Code" label="标签" width="300">
</el-table-column>
<!-- <el-table-column-->
<!-- prop="Description"-->
<!-- label="路由"-->
<!-- show-overflow-tooltip-->
<!-- width="180">-->
<!-- <template slot-scope="scope">-->
<!-- {{scope.row.Description}}-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column
prop="Value"
label="英文">
<!-- <el-table-column-->
<!-- prop="Description"-->
<!-- label="路由"-->
<!-- show-overflow-tooltip-->
<!-- width="180">-->
<!-- <template slot-scope="scope">-->
<!-- {{scope.row.Description}}-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column prop="Value" label="英文">
<template slot-scope="scope">
<el-input v-model="scope.row.Value" @input="(e) => {$set(scope.row, 'Value', e)}" size="mini"></el-input>
<el-input
v-model="scope.row.Value"
@input="
(e) => {
$set(scope.row, 'Value', e);
}
"
size="mini"
></el-input>
</template>
</el-table-column>
<el-table-column
prop="ValueCN"
label="中文">
<el-table-column prop="ValueCN" label="中文">
<template slot-scope="scope">
<el-input v-model="scope.row.ValueCN" @input="(e) => {$set(scope.row, 'ValueCN', e)}" size="mini"></el-input>
<el-input
v-model="scope.row.ValueCN"
@input="
(e) => {
$set(scope.row, 'ValueCN', e);
}
"
size="mini"
></el-input>
</template>
</el-table-column>
</el-table>
<div style="text-align: right;padding-top: 10px;padding-right: 10px;">
<el-button size="mini" @click="drawer = false">取消
</el-button>
<el-button size="mini" type="primary" @click="handleSave">保存</el-button>
<div style="text-align: right; padding-top: 10px; padding-right: 10px">
<el-button size="mini" @click="drawer = false">取消 </el-button>
<el-button size="mini" type="primary" @click="handleSave"
>保存</el-button
>
</div>
</el-drawer>
<feedBack/>
</div>
</template>
<script>
import { batchAddOrUpdateFrontInternationalization, getFrontInternationalizationList } from '@/api/dictionary/dictionary'
import {
batchAddOrUpdateFrontInternationalization,
getFrontInternationalizationList,
} from "@/api/dictionary/dictionary";
import { getTrialExtralConfig } from "@/api/trials";
import feedBack from '@/views/trials/trials-layout/components/feedBack'
import Vue from "vue";
import i18n from "./lang";
export default {
name: 'App',
data () {
name: "App",
components: {feedBack},
data() {
return {
drawer: false,
tableData: [],
show: false,
key: null,
arr: []
}
arr: [],
};
},
mounted() {
this.show = process.env.VUE_APP_OSS_PATH === '/test/dist'
this.show = process.env.VUE_APP_OSS_PATH === "/test/dist";
},
watch: {
"$route.query": {
async handler() {
if (
this.$route.query.trialId &&
this.$route.query.trialId !==
this.$store.state.trials.config.trialId &&
this.$store.state.trials.whiteList.indexOf(this.$route.path) === -1
) {
let res = await getTrialExtralConfig({
TrialId: this.$route.query.trialId,
});
if (res.IsSuccess) {
this.$store.dispatch("trials/setConfig", {
trialId: this.$route.query.trialId,
...res.Result,
});
}
}
},
immediate: true,
deep: true,
},
},
methods: {
changeValue(target, attr, e) {
this.$set(target, attr, e)
this.$set(target, attr, e);
},
keyChange(v) {
if (this.key) {
this.tableData = Object.assign([], this.arr.filter(v => ~v.Code.indexOf(this.key) || ~v.Value.indexOf(this.key) || ~v.ValueCN.indexOf(this.key)))
this.tableData = Object.assign(
[],
this.arr.filter(
(v) =>
~v.Code.indexOf(this.key) ||
~v.Value.indexOf(this.key) ||
~v.ValueCN.indexOf(this.key)
)
);
} else {
this.tableData = Object.assign([], this.arr)
this.tableData = Object.assign([], this.arr);
}
},
handleSave() {
this.$confirm('确定修改当前页面国际化内容?').then(() => {
batchAddOrUpdateFrontInternationalization(this.tableData).then(async res => {
var zhMessages = {}, enMessages = {}
var Internationalization = await getFrontInternationalizationList()
Vue.prototype.$tl = Internationalization.Result
this.tableData.forEach(v => {
// zhMessages[v.Description + '_' + v.Code] = v.ValueCN
// enMessages[v.Description + '_' + v.Code] = v.Value
zhMessages[v.Code] = v.ValueCN
enMessages[v.Code] = v.Value
})
i18n.mergeLocaleMessage('zh', zhMessages)
i18n.mergeLocaleMessage('en', enMessages)
this.drawer = false
this.$message.success('国际化修改成功')
})
})
this.$confirm("确定修改当前页面国际化内容?").then(() => {
batchAddOrUpdateFrontInternationalization(this.tableData).then(
async (res) => {
var zhMessages = {},
enMessages = {};
var Internationalization = await getFrontInternationalizationList();
Vue.prototype.$tl = Internationalization.Result;
this.tableData.forEach((v) => {
// zhMessages[v.Description + '_' + v.Code] = v.ValueCN
// enMessages[v.Description + '_' + v.Code] = v.Value
zhMessages[v.Code] = v.ValueCN;
enMessages[v.Code] = v.Value;
});
i18n.mergeLocaleMessage("zh", zhMessages);
i18n.mergeLocaleMessage("en", enMessages);
this.drawer = false;
this.$message.success("国际化修改成功");
}
);
});
},
openI18n() {
this.tableData = []
this.key = null
this.drawer = true
let arr = []
let tableData = this.$tl.map(v => {
let a = {...v}
this.tableData = [];
this.key = null;
this.drawer = true;
let arr = [];
let tableData = this.$tl.map((v) => {
let a = { ...v };
// if (!a.Description) {
// a.Description = this.$route.path
// }
return a
})
tableData = tableData.filter(v => {
return a;
});
tableData = tableData.filter((v) => {
// return ~this.$path.indexOf(v.Description + '_' + v.Code)
return ~this.$path.indexOf(v.Code)
})
this.$path.forEach(v => {
let o = tableData.find(a => {
return a.Code === v
})
return ~this.$path.indexOf(v.Code);
});
this.$path.forEach((v) => {
let o = tableData.find((a) => {
return a.Code === v;
});
if (o) {
arr.push(o)
arr.push(o);
} else {
arr.push({
Code: v,
Description: null,
Value: null,
ValueCN: null
})
ValueCN: null,
});
}
})
this.arr = arr
});
this.arr = arr;
if (this.key) {
this.tableData = Object.assign([], this.arr.filter(v => ~v.Code.indexOf(this.key) || ~v.Value.indexOf(this.key) || ~v.ValueCN.indexOf(this.key)))
this.tableData = Object.assign(
[],
this.arr.filter(
(v) =>
~v.Code.indexOf(this.key) ||
~v.Value.indexOf(this.key) ||
~v.ValueCN.indexOf(this.key)
)
);
} else {
this.tableData = Object.assign([], this.arr)
this.tableData = Object.assign([], this.arr);
}
console.log(JSON.stringify(this.$path))
console.log(JSON.stringify(this.tableData))
}
}
}
// console.log(JSON.stringify(this.$path))
// console.log(JSON.stringify(this.tableData))
},
},
};
</script>
<style lang="scss">
.el-tooltip__popper{
$light_gray: #606266;
.el-tooltip__popper {
max-width: 400px;
}
.my_multiple{
.el-input--medium .el-input__inner{
height: 36px!important;
.my_multiple {
.el-input--medium .el-input__inner {
height: 36px !important;
}
.el-select__tags{
.el-select__tags {
flex-wrap: nowrap;
overflow: hidden;
white-space: nowrap;
@@ -180,21 +252,35 @@ input[type="number"] {
-moz-appearance: textfield !important;
}
.viewer-fixed.viewer-container{
.viewer-fixed.viewer-container {
z-index: 10000;
}
textarea{
textarea {
white-space: break-spaces;
word-break: normal;
}
*{
word-break: normal!important;
* {
word-break: normal !important;
}
.box-body .el-button.is-circle:not(.is-disabled) i:before{
.box-body .el-button.is-circle:not(.is-disabled) i:before {
color: #428bca;
}
.box-body .el-button.is-circle i.el-icon-question:before{
.box-body .el-button.is-circle i.el-icon-question:before {
color: #fff;
}
.system-title {
font-size: 35px;
color: $light_gray;
text-align: center;
font-weight: bold;
font-family: "Times New Roman";
text-shadow: 1px 0.5px 1.5px #666;
}
.title-logo {
height: 40px;
}
.title-logo {
height: 40px;
}
</style>
+16
View File
@@ -277,3 +277,19 @@ export function batchAddInternationalization(param) {
data: param
})
}
// 国际化获取迭代列表
export function getPublishVersionSelect() {
return request({
url: `/PublishLog/getPublishVersionSelect`,
method: 'get',
})
}
// 国际化批量更新
export function batchUpdateInternationalInfo(data) {
return request({
url: `/Internationalization/batchUpdateInternationalInfo`,
method: 'put',
data
})
}
+40
View File
@@ -1006,3 +1006,43 @@ export function deleteCommonDocument(commonDocumentId) {
method: 'delete'
})
}
//getTrialSiteList
export function getTrialSiteList(params) {
return request({
url: `/site/getTrialSiteList`,
method: 'post',
data: params
})
}
// 获取版本记录列表
export function getExploreRecommendList(params) {
return request({
url: `/ExploreRecommend/getExploreRecommendList`,
method: 'post',
data: params
})
}
// 新增或修改推荐版本记录
export function addOrUpdateExploreRecommend(params) {
return request({
url: `/ExploreRecommend/addOrUpdateExploreRecommend`,
method: 'post',
data: params
})
}
// 删除推荐版本记录
export function deleteExploreRecommend(id) {
return request({
url: `/ExploreRecommend/deleteExploreRecommend/${id}`,
method: 'delete'
})
}
// 获取推荐版本记录详情
export function getExploreRecommentInfo(params) {
return request({
url: `/ExploreRecommend/getExploreRecommentInfo`,
method: 'get',
params
})
}
+8
View File
@@ -76,3 +76,11 @@ export function fullyReplicated(param) {
})
}
// 获取所有字典key
export function getDictionaryCodeList() {
return request({
url: `/Dictionary/getAllDictionaryKey`,
method: 'post',
})
}
+9 -3
View File
@@ -22,9 +22,9 @@ export function getBasicDataSelects(param) {
})
}
export function getBasicDataAllSelect(params) {
export function getBasicDataAllSelect(params, isSystem) {
return request({
url: params ? `/Dictionary/getBasicDataAllSelect?TrialReadingCriterionId=${params}` : `/Dictionary/getBasicDataAllSelect`,
url: params ? (isSystem ? `/Dictionary/getBasicDataAllSelect?SystemReadingCriterionId=${params}` : `/Dictionary/getBasicDataAllSelect?TrialReadingCriterionId=${params}`) : `/Dictionary/getBasicDataAllSelect`,
method: 'get'
})
}
@@ -51,4 +51,10 @@ export function batchAddOrUpdateFrontInternationalization(params) {
data: params
})
}
// 获取当前版本
export function getCurrentPublishInfo() {
return request({
url: `/PublishLog/getCurrentPublishInfo`,
method: 'get'
})
}
+6 -4
View File
@@ -14,17 +14,19 @@ export function getHospitalList() {
})
}
export function getAllSponsorList() {
export function getAllSponsorList(params) {
return request({
url: '/sponsor/getAllSponsorList',
method: 'get'
method: 'get',
params
})
}
export function getAllCROList() {
export function getAllCROList(params) {
return request({
url: '/cro/getAllCROList',
method: 'get'
method: 'get',
params
})
}
export function getAllSiteList() {
+42
View File
@@ -0,0 +1,42 @@
import request from '@/utils/request'
// 下载打包影像
export function requestPackageAndAnonymizImage(params) {
return request({
url: '/DownloadAndUpload/requestPackageAndAnonymizImage',
method: 'post',
params
})
}
// 获取影像上传列表
export function getSubjectImageUploadList(params) {
return request({
url: '/DownloadAndUpload/getSubjectImageUploadList',
method: 'get',
params
})
}
// 预上传
export function preArchiveDicomStudy(data) {
return request({
url: '/DownloadAndUpload/preArchiveDicomStudy',
method: 'post',
data
})
}
// 归档
export function addOrUpdateArchiveTaskStudy(data) {
return request({
url: '/DownloadAndUpload/addOrUpdateArchiveTaskStudy',
method: 'post',
data
})
}
// 删除上传文件
export function deleteTaskStudy(params) {
return request({
url: '/DownloadAndUpload/deleteTaskStudy',
method: 'delete',
params
})
}
+23
View File
@@ -171,3 +171,26 @@ export function getCustomTag(param) {
data: param
})
}
export function clearSkipReadingCache(param) {
return request({
url: `/ReadingImageTask/clearSkipReadingCache`,
method: 'post',
data: param
})
}
export function setSkipReadingCache(param) {
return request({
url: `/ReadingImageTask/setSkipReadingCache`,
method: 'post',
data: param
})
}
export function resetReadingTask(param) {
return request({
url: `/ReadingImageTask/resetReadingTask`,
method: 'post',
data: param
})
}
+365 -2
View File
@@ -1364,9 +1364,9 @@ export function getForwardList(param) {
})
}
export function getNoneDicomStudyList(subjectVisitId, sudyId = '') {
export function getNoneDicomStudyList(subjectVisitId, sudyId = '', isFilterZip = false) {
return request({
url: `/NoneDicomStudy/getNoneDicomStudyList?subjectVisitId=${subjectVisitId}&nonedicomStudyId=${sudyId}`,
url: `/NoneDicomStudy/getNoneDicomStudyList?subjectVisitId=${subjectVisitId}&nonedicomStudyId=${sudyId}&isFilterZip=${isFilterZip}`,
method: 'get'
})
}
@@ -1747,6 +1747,21 @@ export function deleteTrialExternalUser(id) {
method: 'delete'
})
}
export function getUserTobeDoneRecord() {
return request({
url: `/PersonalWorkstation/getUserTobeDoneRecord`,
method: 'get'
})
}
export function getNeedSignTrialDocTrialIdList() {
return request({
url: `/PersonalWorkstation/getNeedSignTrialDocTrialIdList`,
method: 'get'
})
}
export function getBasicStat() {
return request({
url: `/PersonalWorkstation/getBasicStat`,
@@ -2795,6 +2810,29 @@ export function saveImageQuality(param) {
data: param
})
}
export function getIsSuvMaxLesion(param) {
return request({
url: `/LuganoCalculate/getIsSuvMaxLesion`,
method: 'post',
data: param
})
}
export function getCanChooseNotMerge(param) {
return request({
url: `/LuganoCalculate/getCanChooseNotMerge`,
method: 'post',
data: param
})
}
export function saveTaskQuestion(saveQuestionType, param) {
return request({
url: `/SaveTaskQuestion/${saveQuestionType}`,
method: 'post',
data: param
})
}
export function deleteReadingRowAnswer(param) {
return request({
url: `/ReadingImageTask/deleteReadingRowAnswer`,
@@ -2864,6 +2902,14 @@ export function asyncTrialCriterionDictionary(param) {
})
}
export function configTrialProcessInfoVerification(param) {
return request({
url: `/TrialConfig/configTrialProcessInfoVerification`,
method: 'post',
data: param
})
}
export function getTrialEmailNoticeConfigList(param) {
return request({
url: `/TrialEmailNoticeConfig/getTrialEmailNoticeConfigList`,
@@ -3519,3 +3565,320 @@ export function getTrialSiteSurveySelectList(param) {
data: param
})
}
export function getCanMergeLesion(param) {
return request({
url: `/ReadingImageTask/getCanMergeLesion`,
method: 'post',
data: param
})
}
export function mergeLesion(param) {
return request({
url: `/ReadingImageTask/mergeLesion`,
method: 'post',
data: param
})
}
export function resetAndAsyncCriterion(param) {
return request({
url: `/Inspection/ReadingCriterion/ResetAndAsyncCriterion`,
method: 'post',
data: param
})
}
export function batchSetCriterionJoinJoinAnalysis(param) {
return request({
url: `/DoctorWorkload/batchSetCriterionJoinJoinAnalysis`,
method: 'post',
data: param
})
}
export function updateTrialVirtualSiteCode(param) {
return request({
url: `/TaskConsistentRule/updateTrialVirtualSiteCode`,
method: 'post',
data: param
})
}
export function getUpdateVirtualSiteCodeList(param) {
return request({
url: `/TaskConsistentRule/getUpdateVirtualSiteCodeList?trialId=${param.trialId}`,
method: 'get'
})
}
export function addDefaultQuestions(param) {
return request({
url: `/ReadingMedicineQuestion/addDefaultQuestions`,
method: 'post',
data: param
})
}
export function getReadingCalculationData(param) {
return request({
url: `/ReadingImageTask/getReadingCalculationData`,
method: 'post',
data: param
})
}
export function getTrialSignDocumentList(param) {
return request({
url: `/TrialDocument/getTrialSignDocumentList`,
method: 'post',
data: param
})
}
export function getPreviousOtherPicturePath(param) {
return request({
url: `/ReadingImageTask/getPreviousOtherPicturePath`,
method: 'post',
data: param
})
}
export function verifyIsCanConfirm(param) {
return request({
url: `/ReadingMedicineQuestion/verifyIsCanConfirm`,
method: 'post',
data: param
})
}
export function getPTAndCtSeries(param) {
return request({
url: `/SubjectVisit/getPTAndCtSeries`,
method: 'post',
data: param
})
}
export function getDicomSeriesInfo(param) {
return request({
url: `/SubjectVisit/getDicomSeriesInfo`,
method: 'post',
data: param
})
}
export function getTrialSiteSelectList(params) {
return request({
url: `/trialMaintenance/getTrialSiteSelectList`,
method: 'get',
params
})
}
export function getNextIRMedicalFeedback(param) {
return request({
url: `/ReadingMedicalReview/getNextIRMedicalFeedback`,
method: 'post',
data: param
})
}
export function getNextCRCChallenge(param) {
return request({
url: `/QCList/getNextCRCChallenge`,
method: 'post',
data: param
})
}
// 获取中心dicomae列表
export function getTrialSiteDicomAEList(param) {
return request({
url: `/TrialSiteDicomAE/getTrialSiteDicomAEList`,
method: 'post',
data: param
})
}
// 新增或修改中心dicomae信息
export function addOrUpdateTrialSiteDicomAE(param) {
return request({
url: `/TrialSiteDicomAE/addOrUpdateTrialSiteDicomAE`,
method: 'post',
data: param
})
}
// 删除中心dicomae信息
export function deleteTrialSiteDicomAE(id) {
return request({
url: `/TrialSiteDicomAE/deleteTrialSiteDicomAE/${id}`,
method: 'delete'
})
}
// 获取项目中dicomAE配置
export function getTrialDicomAE(params) {
return request({
url: `/TrialDicomAE/getTrialDicomAE`,
method: 'get',
params
})
}
// 获取项目配置
export function getTrialExtralConfig(params) {
return request({
url: `/TrialConfig/getTrialExtralConfig`,
method: 'get',
params
})
}
// 项目新增或修改dicomAE配置
export function addOrUpdateDicomAE(data) {
return request({
url: `/TrialDicomAE/addOrUpdateDicomAE`,
method: 'post',
data
})
}
// 测试dicomAE链接
export function testSCPServerConnect(id) {
return request({
url: `/TrialDicomAE/testSCPServerConnect/${id}`,
method: 'get'
})
}
// dicomAE配置签名
export function ConfigTrialPACSInfoConfirm(data) {
return request({
url: `/Inspection/configTrialBasicInfo/ConfigTrialPACSInfoConfirm`,
method: 'post',
data
})
}
// 获取推送记录
export function getSCPImageUploadList(data) {
return request({
url: `/Patient/getSCPImageUploadList`,
method: 'post',
data
})
}
// 获取影像检查患者列表
export function getPatientList(data) {
return request({
url: `/Patient/getPatientList`,
method: 'post',
data
})
}
// 获取影像检查患者检查列表
export function getPatientStudyList(data) {
return request({
url: `/Patient/getPatientStudyList`,
method: 'post',
data
})
}
// 获取接收方AE列表
export function getDicomCalledAEList(params) {
return request({
url: `/Patient/getDicomCalledAEList`,
method: 'get',
params
})
}
// 获取发送方AE列表
export function getDicomCallingAEList(params) {
return request({
url: `/Patient/getDicomCallingAEList`,
method: 'get',
params
})
}
// CRCpacs上传检查列表
export function getVisitPatientStudyFilterList(data) {
return request({
url: `/Patient/getVisitPatientStudyFilterList`,
method: 'post',
data
})
}
// CRCpacs上传检查
export function submitVisitStudyBinding(data) {
return request({
url: `/Patient/submitVisitStudyBinding`,
method: 'post',
data
})
}
// 获取pacs检查技术
export function getDicomModalityList(params) {
return request({
url: `/Patient/getDicomModalityList`,
method: 'get',
params
})
}
// 获取反馈列表
export function getUserFeedBackList(data) {
return request({
url: `/UserFeedBack/getUserFeedBackList`,
method: 'post',
data
})
}
// 更新反馈状态
export function batchUpdateFeedBackState(data) {
return request({
url: `/UserFeedBack/batchUpdateFeedBackState`,
method: 'put',
data
})
}
// 新增或修改意见反馈
export function addOrUpdateUserFeedBack(data) {
return request({
url: `/UserFeedBack/addOrUpdateUserFeedBack`,
method: 'post',
data
})
}
// 获取反馈详情
export function getUserFeedBackInfo(data) {
return request({
url: `/UserFeedBack/getUserFeedBackInfo`,
method: 'post',
data
})
}
// 一致性分析获取临床数据列表
export function getConsistencyAnalysisReadingClinicalDataList(data) {
return request({
url: `/ReadingClinicalData/getConsistencyAnalysisReadingClinicalDataList`,
method: 'post',
data
})
}
// 新增或修改一致性分析临床数据
export function addOrUpdateConsistencyAnalysisReadingClinicalData(data) {
return request({
url: `/ReadingClinicalData/addOrUpdateConsistencyAnalysisReadingClinicalData`,
method: 'post',
data
})
}
// 一致性分析临床数据签名
export function signConsistencyAnalysisReadingClinicalData(data) {
return request({
url: `/Inspection/ReadingClinicalData/SignConsistencyAnalysisReadingClinicalData`,
method: 'post',
data
})
}
// 一致性分析临床数据设置任务为有效
export function setTaskValid(data) {
return request({
url: `/ReadingClinicalData/setTaskValid`,
method: 'post',
data
})
}
+2 -2
View File
@@ -436,9 +436,9 @@ export function addSubjectCancelDoctorNote(params) {
})
}
export function getSubjectCancelDoctorHistoryList(SubjectId) {
export function getSubjectCancelDoctorHistoryList(SubjectId, TrialReadingCriterionId) {
return request({
url: `/TaskAllocationRule/getSubjectCancelDoctorHistoryList?SubjectId=${SubjectId}`,
url: `/TaskAllocationRule/getSubjectCancelDoctorHistoryList?SubjectId=${SubjectId}&&TrialReadingCriterionId=${TrialReadingCriterionId}`,
method: 'get'
})
}
+16
View File
@@ -94,4 +94,20 @@ export function getTrialJudgyInfo(params) {
data: params
})
}
// 获取检查部位列表
export function getTrialBodyPartList(params) {
return request({
url: `/TrialConfig/getTrialBodyPartList`,
method: 'get',
params
})
}
// 新增检查部位
export function addOrUpdateTrialBodyPart(data) {
return request({
url: `/TrialConfig/addOrUpdateTrialBodyPart`,
method: 'post',
data
})
}
+34 -1
View File
@@ -7,7 +7,13 @@ export function login(data) {
data
})
}
export function loginOut(params) {
return request({
url: `/User/loginOut`,
method: 'get',
params
})
}
export function getAllDictionary() {
return request({
url: '/dictionary/getAllDictionary',
@@ -152,3 +158,30 @@ export function getUserLogList(params) {
data: params
})
}
// 获取登录用户
export function getTrialUserList(params) {
return request({
url: `/TrialMaintenance/getTrialUserList`,
method: 'get',
params
})
}
// 验证MFA邮件
export function verifyMFACode(params) {
return request({
url: `/User/verifyMFACode`,
method: 'post',
params
})
}
// 发送MFA邮件
export function sendMFAEmail(params) {
return request({
url: `/User/sendMFAEmail`,
method: 'post',
params
})
}
+781
View File
@@ -0,0 +1,781 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 765.14 474.77">
<defs>
<style>
.cls-1 {
fill: #d1d6ff;
}
.cls-2 {
fill: #707bef;
}
.cls-3 {
fill: #3d37a6;
}
.cls-4, .cls-5, .cls-6 {
fill: #fff;
}
.cls-5 {
opacity: .5;
}
.cls-5, .cls-7, .cls-8, .cls-9, .cls-6, .cls-10, .cls-11, .cls-12, .cls-13, .cls-14 {
fill-rule: evenodd;
}
.cls-15 {
fill: #f58d7d;
}
.cls-7 {
fill: #afbee7;
}
.cls-16 {
fill: #9f2121;
}
.cls-8 {
fill: #7483a7;
}
.cls-17 {
fill: #200000;
}
.cls-18 {
fill: #ab2426;
}
.cls-19 {
fill: #00338f;
}
.cls-9 {
fill: #333d56;
}
.cls-20 {
fill: #fac6bf;
}
.cls-21 {
fill: #e8625b;
}
.cls-22 {
fill: #ffbfce;
}
.cls-23 {
fill: #ffd785;
}
.cls-10 {
fill: #90a2d0;
}
.cls-11, .cls-24 {
fill: #384a8e;
}
.cls-25 {
fill: #a1b1f5;
}
.cls-26 {
fill: #fcfdff;
}
.cls-27, .cls-28 {
fill: #4b65de;
}
.cls-29 {
fill: #1067db;
}
.cls-30 {
fill: #7fc346;
}
.cls-31 {
clip-path: url(#clippath-2);
}
.cls-12, .cls-32 {
fill: #464c5c;
}
.cls-33 {
fill: #ff768d;
}
.cls-34 {
isolation: isolate;
}
.cls-35 {
fill: #2897cc;
}
.cls-36 {
fill: #ff5722;
}
.cls-37 {
fill: #025aa4;
}
.cls-38 {
stroke-width: 8.99px;
}
.cls-38, .cls-39, .cls-40, .cls-41, .cls-42 {
fill: none;
}
.cls-38, .cls-39, .cls-40, .cls-42 {
stroke-miterlimit: 10;
}
.cls-38, .cls-39, .cls-42 {
stroke: #dae2f9;
}
.cls-43 {
clip-path: url(#clippath-1);
}
.cls-39 {
stroke-width: 22.47px;
}
.cls-44 {
fill: #002daa;
}
.cls-13 {
fill: #c1d4ff;
}
.cls-45 {
fill: #1e1c1c;
}
.cls-46 {
fill: #e3edfe;
}
.cls-40 {
stroke: #e8eef9;
}
.cls-40, .cls-42 {
stroke-width: 6.74px;
}
.cls-28 {
opacity: .4;
}
.cls-28, .cls-47 {
mix-blend-mode: multiply;
}
.cls-48 {
fill: #c54342;
}
.cls-49 {
fill: #f99595;
}
.cls-50 {
clip-path: url(#clippath);
}
.cls-51 {
fill: #eef4fc;
}
.cls-52 {
fill: #f7d5b0;
}
.cls-53 {
fill: #c1d0f2;
}
.cls-54 {
fill: #6169b3;
}
.cls-55 {
fill: #fafcff;
}
.cls-56 {
fill: #d47180;
}
.cls-14 {
fill: #2e3d6d;
}
.cls-57 {
fill: #4770e4;
}
.cls-58 {
fill: #e8eef9;
}
.cls-59 {
fill: #e56059;
}
.cls-60 {
fill: #c24434;
}
.cls-61 {
fill: #d04139;
}
.cls-62 {
fill: #f2f2f2;
}
.cls-63 {
fill: #065fa8;
}
.cls-64 {
fill: #5ad2fe;
}
.cls-65 {
fill: #aa2f27;
}
</style>
<clipPath id="clippath">
<polygon class="cls-4" points="420.66 471.75 343.93 471.75 345.03 363.22 421.77 363.22 420.66 471.75"/>
</clipPath>
<clipPath id="clippath-1">
<path class="cls-41" d="m185.09,399.5c-.01,10.38,9.49,19.78,20.01,19.78h333.01c12.07,0,20.96-8.77,20.97-20.68l.05-36.91H185.15l-.05,37.81Z"/>
</clipPath>
<clipPath id="clippath-2">
<path class="cls-41" d="m466.77,472.37h-191.24c-2.4,0-4.65-1.95-5.03-4.35l-.03-.19c-.38-2.4,1.26-4.35,3.66-4.35h191.24l1.4,8.88Z"/>
</clipPath>
</defs>
<g class="cls-34">
<g id="_图层_2" data-name="图层 2">
<g id="_图层_1-2" data-name="图层 1">
<g>
<path class="cls-51" d="m677.06,197.09c-3.8-25.04-18.99-48.95-39.61-64.35-29.98-22.39-68.97-29.39-106.39-28.8-66.18,1.04-88.53-62.47-139.47-91.25-35.63-20.13-81.65-14.74-117.31,5.35-35.65,20.1-62.42,52.89-84.63,87.27-9.81,15.19-19.17,31.14-33.03,42.75-12.48,10.45-27.85,16.72-41.72,25.25-40.79,25.09-67.77,71.28-69.59,119.13-1.82,47.85,21.59,95.96,60.36,124.07,31.42,22.78,77.46,38.95,113.74,51.18,40.37,13.6,86.38,2.08,127.83,2.24,87.87.33,175.74.67,263.61,1,.01,0,.02,0,.03,0,17.46.07,40.06,3.53,56.3-.95-6.97,1.92,9.65-39.42,10.09-42.39,2.42-16.35-1.82-32.18-10.45-46.22-12.07-19.65-29.28-38.04-30.63-61.06-1.92-32.74,28.59-57.84,38.45-89.12,3.51-11.13,4.12-22.72,2.4-34.08Z"/>
<g>
<path class="cls-63" d="m635.26,192.49s8.62,56.26-19.83,100.54c-14.36,22.34-30.95,40.22-46.12,51.01l-45.66-7.31c-2.6-19.71,7.73-52.27,28.4-84.44,28.45-44.28,83.21-59.81,83.21-59.81Z"/>
<image class="cls-47" width="113" height="148" transform="translate(523.11 192.24)" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHEAAACUCAYAAACk98bhAAAACXBIWXMAAAsSAAALEgHS3X78AAANuUlEQVR4nO2d+Y8dRxHHa3af7djxfeEc5CYmiFMIxCEQ/EAw8O/yE78hJJBAIBA3KOQgiZPY2PHtXe9Oo3lvel51dVV1z/lm5vVXsnaOntl1f963uqrneBkkTU7GGAOrn5BlGSSIE5FZyftjd3Z2ssW2d87Yled55TorijI5cYTC4RIoNLOmtruzs1xKEEckHDL9wFnsXy8vdncqdimcjkAW3vKf/XOMC9IojktO3KBosmIXqQvp+hHkQkgQh5cHzv5EpBwHkoz06GLXY5bC6UDCIRM8UHhZzkIlJSf2LMl5dsyTXMcBPMa4EBLE/mTrOxBcZ9CKoe0YgseO8AAhhdPuxcGj4x038yIlNTFKTuxIXNjkkpVQUkNV7DquuBASxPaqEhZyJmPoTItxx0DiPIMPRDp+dBFklMJpQ1l4OYqDHJAKHOdK1I7uq6PkxAZaA/SPpa70HGm3wxqypBMRLoTkxHrC7tPGO2msow71tnsrcUpOjBBOWnJhrAOmBgTkOLTLC69Uxa6Tx+JcCAmiLnpVISdxUqr/OHBcO0l1AEIKp7KKei9H7uPGLxo2pctI2HleGNXqi0glJzIqANo6z0tUYB0uM+Q8toAHl1oOMjR7vlNPHanNJEFEKmKnTVooGAzP3cZDdtY1yEinGwCEFE7XOizCZ26WbnHCIlf/2XXSTmqjBcwOomly4tJ9uSkTFwEe09M54zZyXn6fUDeeOd7MhbDtEAuAh7lNXgwfMoXrf7HgJKfhzWdbAIRtDacW3oEFmPudnwu9T2dppGuAYqHP7WyprXOiBWgTFy8sCsU7Xg9NmWm1IA3N504cbc1gqyAWAJfuMwYOcUejMEjB4cWY2wmlqTWvPQCc7wAgbEs4taVDAdC6T5vn5DqfC6+xNzex5+wwou52d6pxqijci/BZGnBVcEckKiYwJwp4nzahjTbg7Ree7saFMHcnFrXfyn2uk9azLG579qp7IEmhrlMTmp402zHx4DCvZl9y7CpuDpOOdWbdM2KSwjiVSzo5iBc7dCHMFeL+waGxIRI70Gai2q2B6tjIhVjQwyzddunksc77fHbhdK8EeGjdVfYjnnzWsstqHe2QQIvjYCAz7VqzcuLekxU6fOXdcOHSirmBt9rFuAikkBm4R8Zuu9yDC2EuEAt4xc8DMvMi3YXmrsvlgDQDY8hG1pHktJdP9QMQ5hBOHz85XCYw9LYJI8yFAlO8c/vYWRpwaUqTA8xqr5q0Ex/tH5Thc73NwotNUJzN4EPHCUqtJAhtv9KjC2HKEB/uHxgOHnDF+3JdH7eAg1IDNj3O6srpp3rv40mG0wd7K4BcR1OwVGrhDvKxYpiV2g2oyTnx/t6B/1w7mk6Dmpkld4w/DtLzKGMp0jMDuBCmNnd67/ETG8mWqmpALcUXZlykuk4ChzfH1JnPnhkGIEwpnBYAKTwjuAID4JIaobmaqEhjZExy07cmEU7vFg5kbliil4dCNWCdJIUmKFLN6OwrdmQZPDegC2EKTrzz6Ilxsk3lETEtMeFEs1gKDgSXutu9T069/2AHGrUTlwDLZfqqEK3z1fEPXPDa8bGXoOxS0ZnPnz0+eJ+O2ol0zPNuUrI/JYCCKUwN1/ljoByiNwEQxgzx9sN9oxfwpMwIOMc9NDzWSdmrs28ESQ2MtcRYAoR1wiGGO7QS04liEiPA0Ap+eo4Xzm3GhTDGMfHWg31DO7JOVgkO3AblhHK/jHQl48XzJzbaj6MLp9hlISc4qb1wHmdbg7GODdEbyEA1jSqc3nywXw50fBlhF6WO5LLSTNtfI1za30m3v7RhF8KYwunN+3sGu1BKGrQbeEExSag8sCtc6cIDBXj5wuYBwljC6Y0SoHRnGXZeLDy8mkWUISF4whA7Cm38k/TJ/T0jOcBZt8sRTnMaZ5n8Gmaa6UIYnl18ZSQuhFE4MfCmCadpRDmBHWcdSMdW6QMjwaOgXx0RQNg0xI/v7Rn6HLuaFVKFQqxQitStO8eYkWJt7BP10d3HXHQLPtenAeM2cuHS+50gwCOxtFh67eLTo6utN+LEAqAUKsEBaqo3VDhtpROTbIarJUMh0/5eoJBHfLVg8L/rOnJgqBOxGpcUHBDuAxPR9nOXxudC2IQTYx5Q4fcr+5Rf1AU8GDFAGBrih3dIGFXe0sTNmlBxHwQg20V4kWOj/VKtMWtQiFwHAu10hpyWmdr9GVrmnNQEntXrI3YhDDkmvv/pI1quVQqCazhGciHT2R5waKGrl0+O/j6kQZxoAVKKciiVnUrF1SkavDrhdSoaBKKUhQIBZ9BL79RzcSeqAU/KhKlD3/jM+F0IQ4TT924/4sxSroQfxuSgccdwLq7rPBwApgIQBnUi8OOS3FbZxx4YWVI0neIbsXr9tL1buDBiflNqED5GzzTtYsxVe9zmC1dOTeoZld7+2HduPeQrA2+B2Ue3ByafpbDJwhNewGc1NYDQdziVB8P4cS14DHNe7Qu2tHZTfVizl3ts3i5cGOk0mklK7bh99P6ZGHgA7jVG7OAvPjM9F0JfTtSiHwcNFHBa+K1e8RUTNsHNhqXEZ4rq3In/+d9Dv98jwyPt2JDawKO/5ksTdSH04UR6IbXazrWVdijHrH8PCZ3KdzW5f5sP+csTBghdQ3zr5gOxfG9c/zGOs1cV2FIBbdDcJ4X1KapTiL4Twm297REdW71wnYHng1ovc22+8uzpyb+QqbP/wL9vPFB7ny8P6jvBtIDnHJ8BfHUGAKErJ2KAbQr2GDnjWgAebWe8HfNQJxC5OqxOe65BTFLDlQv+NvcNU3b/156bhwuhi3D6z0/uxzBRd8S7MBYeCp1MmzkBhN6KfWFjkwjGlQscGEAAOXhS6TMHtfpE/kNwYUy+omdBfJ1JOaxLDNl5dOz8+vNnZve25XZOjHSXHE5NXDuh1gMEMEcNcf2IU585AoQ2EP/+8X3RcN72Glcl2HZc6FTCK/fut3kG0pUaQ4yNo9GgIvdp4x5QuAjeNz47TxdCq3Da8O4w36X+KveINgfJDZ2u+7ivT5+rGn06//rRPSkB5RXo0PBYqF+FoK+KdiEb+OYLZ2f9nVitEpuQqyJ3yccE6j1DptK4cmTuAKEJxL9cv6e9nVJVXZAiPCDuVMLqNqg2xNogGhbZJhQ6FffZ8fBbL87fhVB3TPzzdX8sbFLtR7m2hvuKlZwcty0Aoa4T61y1r6vq1BnJOkGBh5zJPRyzLYr+tP7pw7u1+6ZNtmrh4eYVQDQTY6hrjYFvv3Ruq76htfUEuPEW2p+Pug9w3YcKfXoHd7H6nS0DCHUgxuYnbVnStypyyQt1nym/4GvkD/T2piiIf/zgrvj4Uv1stRz4UIdnaJ9WNgAC6Ey/lbu30YUQC7Gpu+Qr/G524k+tyQV91c5mpOW27768nQAhBuIfPri7RtGi5otqJzzsIoXPZn/N/BR2YsvLSLHSZl0qYGVWSoF+75XzW+tCiIHYBladOxI9gEo9aBDAraZXSoX4+/fvyBiMuholeoz0xZWm/JJLYGBvuwshBLHuvb1tEyB25oUAxF8t9P0EcCkd4gB/AC0rrOit+ka4fT9JmXb73X+VUEogtBENn4aMixzAYukHryYXWolObAuHPSf7dO962f5eGlItwMMyrv7wtQsJIBIL8bfvfdqYYOhAOqUGjhv98sGCpl+zl7QWCzEujjbsReIhbvpMA5hc6IsPp8yUWGeiMy1k+oyOfwlgWM2dGCF7HrbnOfeRpAYD3KZbEOvK69/fvNt8PKye3gz5hQ2f6EIvAmiToeRCWb4TWycQ4XvmafiktSIGCAlgUB7EQaJWJMCUlcbJ+YT/+p3bvfcYvVohASzGwGL/j16/mFwYkOPEIT709ldgh3khtFgvKCZ8Uer+ZURomTKgAKvLSmSK5qBMRd9MLoyS68SOT+5damKuF9IrGHZq7c2rCWCsKoi/evu20VwEVYfLJUS4sggDpPOrSWEtUA+7HS6jEHdqTsYJDAVIZ3GSC+upglg3lDbpZRZg+dOG0R8ngLXV7ePeWnsJIAqjSc20/NT/8q1b9fsws98UKu9TAZrVzE2OACYXNlOLZ/YVN5J9Tk0ICWDXWkLsKpRpFHD4BATwyaHZ2mcoutIKInJKhpdqdi73YeBuhMLri90MriUXtpIyAd7xG3wswPIWRDs6Xrt6KQFsKTGcdtWzdMI756baklpp5URmmqRNF68fVXNrwZyY+9rnkwu70NqJAjW2l8uN1kwZ3Q7+T5yJJhd2q2YP1Bhhlbl6RAHm5UMwyYXdKVhi4O/q5bZT4Xbco9uQAHauqsTwe3X1LhJDt5GQSY+woo+iAXO2pG6kTICzVR9kLIcVXMd1eLoNjYM/SS7sXLu/+NdNg7/Ht00Ps/OlsI6jCWA/WtCa3jS84At0PKwWUhDtWwuvg2nZ4G52lfFtq4dCy+K+mBtNLuxP8qNtgV+ZoUahOdMEsF8ttJcDaZIg4/E11fTDqHQi/3Kgpch1Ijylxl3osJmoBfjTN5IL+5Y/Jpaqel67gapgX0K27fEF4ARwGC2kWwSjxkRYQ+ZmZpIGgsheNiSFYwxkeuXiZ8mFg2mBWK1FCj53jGTaM1cukgaESCFQeXaiZUWGx8PVz+TCYbWg4xe9aSl49YI4NQEcXk6H//xvN0yTO8/w5aoEcXhFdXgs3ARwoioAF/+2vR82JgD4Py3tuexQuXy8AAAAAElFTkSuQmCC"/>
<path class="cls-4" d="m635.62,191.94c-.3-.2-.71-.11-.9.2l-34.84,54.22-6.23-22.68c-.1-.35-.46-.55-.8-.46-.35.1-.55.46-.46.8l6.54,23.81-39.18,60.98-9.98-20.48c-.16-.32-.55-.46-.87-.3-.32.16-.46.55-.3.87l10.32,21.2-18.65,29.03c-.19.3-.11.71.2.9.08.05.16.08.25.1.25.04.51-.07.65-.29l39.47-61.42,25.89-1.33c.36-.02.64-.33.62-.69-.02-.36-.33-.64-.69-.62l-24.96,1.29,54.12-84.21c.2-.3.11-.71-.2-.9Z"/>
</g>
<g>
<path class="cls-63" d="m645.71,307.02s-15.11,28.68-42.62,40.29c-13.88,5.86-27.26,8.96-37.62,9.23l-17.79-17.58c5.48-9.92,21.02-21.75,41.01-30.18,27.52-11.61,57.02-1.75,57.02-1.75Z"/>
<image width="99" height="44" transform="translate(547.11 302.24)" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGMAAAAsCAYAAABxNQYsAAAACXBIWXMAAAsSAAALEgHS3X78AAABTElEQVR4nO3aiQ3CMAyF4SIxDAOwFBOxFAOwDUhIRq565LRjO+8fgDr9FHrAgux0mcXi9nx9NI/3ftyLz204DO2TXlIKKASGZYBUHMgthmeAo1xhRATgmceIDuDia2omBMocRmQEF3dTM+6CvYZiAGHdMIyoEDVP3pQ6BhCOU8MAQjpxjIgIPQF4ohjRIKQQKJEPj4QgDcDrfqAoEJoIVLcDAqG9Lgf2DjESgNc0BBD6Vj1MlF/XLFU1lEcIqwC8ogGBIFv2oN4gPCFQWQN7gfAIwEsO7wHCOwJ1ugjPfwjz2OGCrEJERKB2F2YRIjICdbUxxn4zAPA2i7WwK2ZDoFaLHg0xKwL1X/woiNkBeL8TMQICCNtUL+AAOO+isSuAkJfozgBCWd2vGQCor9vdFBDaa37OAEK/qp7AASBT0YtCIMiW9QodCAoty/IFaUmhq+RDGEYAAAAASUVORK5CYII="/>
<path class="cls-4" d="m646.02,306.89c-.07-.17-.27-.25-.45-.18l-30.53,12.88,6.58-11.71c.09-.16.03-.37-.13-.46-.16-.09-.37-.03-.46.13l-6.95,12.36s-.02.06-.03.1l-41.85,17.66,5.35-16.3c.06-.18-.04-.37-.22-.43-.18-.06-.37.04-.43.22l-5.51,16.79s0,.04,0,.07l-17.15,7.24c-.17.07-.25.27-.18.45.03.08.1.14.18.18.08.04.18.04.27,0l40.88-17.25,14.56,6.27c.17.07.37,0,.45-.18.07-.17,0-.38-.18-.45l-13.96-6.01,49.59-20.93c.17-.07.25-.27.18-.45Z"/>
</g>
<g>
<g>
<path class="cls-63" d="m132.21,302.14s9.06,30.39,33.93,45.91c12.55,7.83,25.17,12.88,35.38,14.71l21.26-14.56c-3.38-10.55-16.34-24.48-34.42-35.76-24.88-15.52-56.15-10.3-56.15-10.3Z"/>
<image class="cls-47" width="91" height="53" transform="translate(132.11 301.24)" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFsAAAA1CAYAAAAuyJezAAAACXBIWXMAAAsSAAALEgHS3X78AAAGTUlEQVR4nO2c+2/cRBDHZy/pu2nTPCilpYWW0qoIAQIhBIiXUOEH/lzevyAhkEAIhBAQgqpWpbSUJiG5vF/nRePz2rOzs2v7Hrnz3Y2UnL1evz47993Z9fiUbhqUMVO7phTgvnSdmlKsYMhNRVEUs8J/yNzCozOwPsP6tK0y8J4dNEAt2ThsjRHfbKMRpbxSbpQ88V6V0NXkANqUx1Xt5jEtiXytY5C6Y2Y92T4+5m2qSpt1U3uNSFOQGXhSUxu4WQUKntdzwWugDm2Oo1k9g/vI+NjAgBdvZGe/oTlIILCodiC4tJzruVBuHyv78ihazuqYCicOj1cavPfit/YaCaUwLKMjRHGsOsZDNTuIz+trTFJAkCa0iaOHKgc+94I3d/czToK3A8jyAAQS1ei8DjcvMOKbJ49VB3qhC13fSYAXgAUBYErQc+7BToDiOScvmzp+uO+hl7rA1e09K1hJl4UDOYB4RCOUW/uxTlPSdLt+c2nm5JG+hd7ShdW39mzn9QATAREpouGgKfRJlHMc1slymTs70X/QW76g5c1d3ueFNR0yXefrvE74GIFzEBcwS+dOHe0b6G1fyNLGrsTbCw3A9kLjlV4ZCkQwQCCnfYBQCYvOn+499I5cwOL6jtgnuq4fBgZcz8l2Gv75OmDH24WKFyaP9Qx6R0/8aG1HckjLqOeHIhvFjiHNv4AHKLBvBq9x8UxvgHflpA9Xtx0Ekpdz45tVgcbJ03IAV8/RLk0dP3DgXTvhgzoBXjA+p0br1wAgSo9lfcj75I16ybbL0wcHvesnul/f1pFPA/KdPTU+ICrk8T7pIfuiXZk5cSDAD+Qk91a2UleLQhWLPMQgk2DWKDQQtfjCQr7v1dnuQj9Q3bq7vKWlmw4iFjb6HlhACbDONST7XHvsZNeY9KRXvrO0KfIto+um8wzC9cTcIEQxdO16l4D3LOa8vbSpc8O2AkanBIp4rnQO6Vty42zngfd8VHVrcSP4vFkaXTrbWVDOB0G0HASPD3W2zz0+0TFGfTFv8OfCRqIGZQPEzFTypJ9bELDU0ZIFs/78uc4A76uZsflH6zoqwZtKiFk2cy1evRa818iPLzzE5ReeONU2q76c+537dz3Vc6+MBLIgrGyMnDg8FCZyj3+xTeB9O9H+28M17XR4nquVinnKhTR6BObBwAEL9V863zrwvn+U9Os/a14lL3TxQsoFeCB7G4SFli9fON0St0o8LP3lwWp8t/Hok2dtEUuLWYWaZ+AjhYsSZNpxmuVXniwPvFLpAD/fX9VBVQk0ApWVIvG4FIfzTvPVi5Ol+FUy6eUnhE6w85uQHkAokJ9V+kagDuC03C4pA7yyGUY//l23wkQqFZw1XTWZWk7U4Qn9uF6DUPe1S8WAVz6P7od7ddvLPV4NrBGUAM/y2bjMbgygjUD+4cfrT53JZTkQSYvf/7XiDB55DmFWnpVgKoUziBISS8UZRkH/33g6DHygUnO/u7sSDM2Rsw9+qGM05c5klqDrbwaAjxe+kwqY0c5v7yxbVAzkZgKum95Gkz+lyANE+QhHMJINZNI52jcMOAjabcCnkUoAtCQlvm/D21em5BmGtu6oAvb17f8s6DUC2AKhSE45EE32jT55yh2r944AvDbQpAHgrctTCkFgR4gvVqR/uvkXEc/F8hgiljcXrSjF6LYmDaFZPbNdsoH3bGpf3VqSvVzZZdIrLLyD5J4sDe3fuzpt8R0q2MYQejoAMp8ImYCnb0CkIIUhfmj+BD/fJ8AHXkYke/eZaRUlcoJvszSlAKVDW1JDJYF3kBGVk6QwT06G0rOpfTm/GCNBEPhGII/FsYxKRp4nS7nqN5+diQ85lJ5N7ea1JgiEsh9pwBflGsRDYw8v4cnZOqSdrLGh92xqX8wvpmMW9EJ8E1mROBwoaCe+lie1jLd/eH1WDdQIsl37IPHyj39fiBkdIqBroKwXZDOo8mSVJCkjz/bY538spJxMpAJGw4FNWOXpdrIygp1jCF1z4IrDlb3Z7lhHHWSuodYCZKFh3GnSAQ19kJCTZDTy7BL2GXp5wrPG5lJ4SMi9+qMbs6MfX2nFPp1r6nn8uylCbgoFjpDNKUawWzQErukPIThzJTZoGMFu3z6ZW9BW2rIA2dgIdgcMgRvP9oEGAPgf3OtAXqhoKN0AAAAASUVORK5CYII="/>
<path class="cls-4" d="m131.9,301.95c.11-.17.33-.22.5-.12l30.46,19.01-2.27-12.91c-.03-.2.1-.39.3-.42.2-.03.39.1.42.3l2.38,13.55,34.26,21.38.15-12.69c0-.2.17-.36.37-.36.2,0,.36.17.36.37l-.15,13.13,16.31,10.18c.17.11.22.33.12.5-.03.04-.06.08-.1.11-.12.08-.27.09-.4,0l-34.51-21.53-13.36,5.5c-.19.08-.4-.01-.47-.2-.08-.19.01-.4.2-.47l12.87-5.3-47.31-29.52c-.17-.11-.22-.33-.12-.5Z"/>
</g>
<g>
<path class="cls-63" d="m144.35,355.63s11.05,13.35,26.71,16.41c7.9,1.54,15.24,1.7,20.69.71l7.38-11.15c-3.95-4.59-13.38-9.07-24.76-11.3-15.67-3.06-30.03,5.33-30.03,5.33Z"/>
<image width="56" height="17" transform="translate(144.11 349.24)" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADgAAAARCAYAAACIJW/gAAAACXBIWXMAAAsSAAALEgHS3X78AAAAmklEQVRIidXW2w2AIAxA0bKNA7iUE7mUA7iNRj8MNiVQSkt7vxVyfAAJhC37cbWOcG6reD5u7Ak5IG4aD6A6oCao1ggwOcBMFJUE+rvRG4yKi30vjgDDtUJTRFxeDRruEy1VgrpeRXvC0K7VyTs6Rw7bWL1uLapHp9noB2l+NrRGmwNLacCnvEFOErTJP6hRKzoskAqjv20CAG4a0EKcs+XdfAAAAABJRU5ErkJggg=="/>
<path class="cls-4" d="m144.17,355.6c.02-.1.11-.16.21-.14l17.39,3.39-4.72-5.4c-.07-.08-.06-.19.02-.26.08-.07.19-.06.26.02l4.99,5.71s.02.03.03.05l23.83,4.65-4.58-7.94c-.05-.09-.02-.2.07-.25.09-.05.2-.02.25.07l4.72,8.18s0,.02.01.03l9.77,1.91c.1.02.16.11.14.21,0,.05-.04.09-.07.11-.04.03-.09.04-.14.03l-23.28-4.55-6.93,4.88c-.08.06-.2.04-.25-.04-.06-.08-.04-.2.04-.25l6.65-4.68-28.24-5.51c-.1-.02-.16-.11-.14-.21Z"/>
</g>
</g>
<g>
<g>
<polygon class="cls-4" points="420.66 471.75 343.93 471.75 345.03 363.22 421.77 363.22 420.66 471.75"/>
<g class="cls-50">
<polygon class="cls-46" points="343.93 469.46 344.29 471.75 343.93 471.75 343.93 469.46"/>
<polygon class="cls-4" points="343.93 448.1 347.67 471.75 344.29 471.75 343.93 469.46 343.93 448.1"/>
<polygon class="cls-4" points="343.93 426.74 351.05 471.75 347.67 471.75 343.93 448.1 343.93 426.74"/>
<polygon class="cls-4" points="343.93 405.37 354.43 471.75 351.05 471.75 343.93 426.74 343.93 405.37"/>
<polygon class="cls-4" points="343.93 384.01 357.81 471.75 354.43 471.75 343.93 405.37 343.93 384.01"/>
<polygon class="cls-4" points="344.02 363.22 361.19 471.75 357.81 471.75 343.93 384.01 343.93 363.22 344.02 363.22"/>
<polygon class="cls-4" points="347.4 363.22 364.57 471.75 361.19 471.75 344.02 363.22 347.4 363.22"/>
<polygon class="cls-4" points="350.78 363.22 367.95 471.75 364.57 471.75 347.4 363.22 350.78 363.22"/>
<polygon class="cls-4" points="354.16 363.22 371.33 471.75 367.95 471.75 350.78 363.22 354.16 363.22"/>
<polygon class="cls-4" points="357.54 363.22 374.71 471.75 371.33 471.75 354.16 363.22 357.54 363.22"/>
<polygon class="cls-4" points="360.92 363.22 378.09 471.75 374.71 471.75 357.54 363.22 360.92 363.22"/>
<polygon class="cls-4" points="364.3 363.22 381.47 471.75 378.09 471.75 360.92 363.22 364.3 363.22"/>
<polygon class="cls-4" points="367.68 363.22 384.85 471.75 381.47 471.75 364.3 363.22 367.68 363.22"/>
<polygon class="cls-4" points="371.06 363.22 388.23 471.75 384.85 471.75 367.68 363.22 371.06 363.22"/>
<polygon class="cls-4" points="374.44 363.22 391.61 471.75 388.23 471.75 371.06 363.22 374.44 363.22"/>
<polygon class="cls-4" points="377.82 363.22 394.99 471.75 391.61 471.75 374.44 363.22 377.82 363.22"/>
<polygon class="cls-4" points="381.2 363.22 398.37 471.75 394.99 471.75 377.82 363.22 381.2 363.22"/>
<polygon class="cls-4" points="384.58 363.22 401.75 471.75 398.37 471.75 381.2 363.22 384.58 363.22"/>
<polygon class="cls-4" points="387.96 363.22 405.13 471.75 401.75 471.75 384.58 363.22 387.96 363.22"/>
<polygon class="cls-4" points="391.34 363.22 408.51 471.75 405.13 471.75 387.96 363.22 391.34 363.22"/>
<polygon class="cls-4" points="394.72 363.22 411.9 471.75 408.51 471.75 391.34 363.22 394.72 363.22"/>
<polygon class="cls-4" points="398.1 363.22 415.28 471.75 411.9 471.75 394.72 363.22 398.1 363.22"/>
<polygon class="cls-4" points="401.48 363.22 418.66 471.75 415.28 471.75 398.1 363.22 401.48 363.22"/>
<polygon class="cls-4" points="404.86 363.22 421.77 470.04 421.77 471.75 418.66 471.75 401.48 363.22 404.86 363.22"/>
<polygon class="cls-4" points="408.24 363.22 421.77 448.68 421.77 470.04 404.86 363.22 408.24 363.22"/>
<polygon class="cls-4" points="411.62 363.22 421.77 427.31 421.77 448.68 408.24 363.22 411.62 363.22"/>
<polygon class="cls-4" points="415.01 363.22 421.77 405.95 421.77 427.31 411.62 363.22 415.01 363.22"/>
<polygon class="cls-4" points="418.39 363.22 421.77 384.59 421.77 405.95 415.01 363.22 418.39 363.22"/>
<polygon class="cls-4" points="421.77 363.22 421.77 363.22 421.77 384.59 418.39 363.22 421.77 363.22"/>
</g>
</g>
<polygon class="cls-4" points="427.04 363.22 425.08 466.33 419.8 466.33 421.77 363.22 427.04 363.22"/>
<path class="cls-37" d="m544.25,176.11H211.24c-12.07,0-20.96,8.77-20.97,20.68l-.34,207.82c0,1.89.31,3.75.89,5.52l-.56,1.72,3.76,4.32c.53.69,1.1,1.34,1.7,1.96l.02.02h0c3.71,3.78,8.81,6.23,14.18,6.23h333.01c12.07,0,20.96-8.77,20.97-20.68l.34-207.82c.01-10.38-9.49-19.78-20.01-19.78Z"/>
<path class="cls-53" d="m538.11,419.28H205.1c-10.51,0-20.02-9.4-20.01-19.78l.34-207.82c.02-11.92,8.91-20.68,20.97-20.68h333.01c10.51,0,20.02,9.4,20.01,19.78l-.34,207.82c-.02,11.92-8.91,20.68-20.97,20.68Z"/>
<g class="cls-43">
<polygon class="cls-46" points="185.08 391.65 189.45 419.28 185.08 419.28 185.08 391.65"/>
<polygon class="cls-4" points="193.87 361.69 202.98 419.28 189.45 419.28 185.08 391.65 185.08 361.69 193.87 361.69"/>
<polygon class="cls-4" points="207.4 361.69 216.51 419.28 202.98 419.28 193.87 361.69 207.4 361.69"/>
<polygon class="cls-4" points="220.92 361.69 230.04 419.28 216.51 419.28 207.4 361.69 220.92 361.69"/>
<polygon class="cls-4" points="234.45 361.69 243.57 419.28 230.04 419.28 220.92 361.69 234.45 361.69"/>
<polygon class="cls-4" points="247.98 361.69 257.1 419.28 243.57 419.28 234.45 361.69 247.98 361.69"/>
<polygon class="cls-4" points="261.51 361.69 270.62 419.28 257.1 419.28 247.98 361.69 261.51 361.69"/>
<polygon class="cls-4" points="275.04 361.69 284.15 419.28 270.62 419.28 261.51 361.69 275.04 361.69"/>
<polygon class="cls-4" points="288.57 361.69 297.68 419.28 284.15 419.28 275.04 361.69 288.57 361.69"/>
<polygon class="cls-4" points="302.09 361.69 311.21 419.28 297.68 419.28 288.57 361.69 302.09 361.69"/>
<polygon class="cls-4" points="315.62 361.69 324.74 419.28 311.21 419.28 302.09 361.69 315.62 361.69"/>
<polygon class="cls-4" points="329.15 361.69 338.27 419.28 324.74 419.28 315.62 361.69 329.15 361.69"/>
<polygon class="cls-4" points="342.68 361.69 351.79 419.28 338.27 419.28 329.15 361.69 342.68 361.69"/>
<polygon class="cls-4" points="356.21 361.69 365.32 419.28 351.79 419.28 342.68 361.69 356.21 361.69"/>
<polygon class="cls-4" points="369.74 361.69 378.85 419.28 365.32 419.28 356.21 361.69 369.74 361.69"/>
<polygon class="cls-4" points="383.27 361.69 392.38 419.28 378.85 419.28 369.74 361.69 383.27 361.69"/>
<polygon class="cls-4" points="396.79 361.69 405.91 419.28 392.38 419.28 383.27 361.69 396.79 361.69"/>
<polygon class="cls-4" points="410.32 361.69 419.44 419.28 405.91 419.28 396.79 361.69 410.32 361.69"/>
<polygon class="cls-4" points="423.85 361.69 432.96 419.28 419.44 419.28 410.32 361.69 423.85 361.69"/>
<polygon class="cls-4" points="437.38 361.69 446.49 419.28 432.96 419.28 423.85 361.69 437.38 361.69"/>
<polygon class="cls-4" points="450.91 361.69 460.02 419.28 446.49 419.28 437.38 361.69 450.91 361.69"/>
<polygon class="cls-4" points="464.44 361.69 473.55 419.28 460.02 419.28 450.91 361.69 464.44 361.69"/>
<polygon class="cls-4" points="477.96 361.69 487.08 419.28 473.55 419.28 464.44 361.69 477.96 361.69"/>
<polygon class="cls-4" points="491.49 361.69 500.61 419.28 487.08 419.28 477.96 361.69 491.49 361.69"/>
<polygon class="cls-4" points="505.02 361.69 514.13 419.28 500.61 419.28 491.49 361.69 505.02 361.69"/>
<polygon class="cls-4" points="518.55 361.69 527.66 419.28 514.13 419.28 505.02 361.69 518.55 361.69"/>
<polygon class="cls-4" points="532.08 361.69 541.19 419.28 527.66 419.28 518.55 361.69 532.08 361.69"/>
<polygon class="cls-4" points="545.61 361.69 554.72 419.28 541.19 419.28 532.08 361.69 545.61 361.69"/>
<polygon class="cls-4" points="559.13 361.69 559.13 361.69 559.13 419.28 554.72 419.28 545.61 361.69 559.13 361.69"/>
</g>
<path class="cls-44" d="m538.11,420.1H205.1c-5.27,0-10.6-2.31-14.62-6.33-3.94-3.95-6.2-9.15-6.19-14.26h.81s-.81,0-.81,0l.05-38.62h375.61l-.05,37.72c0,5.98-2.21,11.45-6.21,15.39-3.99,3.94-9.53,6.11-15.58,6.11Zm-352.15-57.6l-.05,37c0,4.69,2.08,9.47,5.72,13.11,3.72,3.72,8.63,5.86,13.47,5.86h333.01c11.67,0,20.15-8.36,20.16-19.87l.05-36.1H185.96Z"/>
<g class="cls-31">
<polygon class="cls-46" points="270.52 463.5 271.93 472.37 270.09 472.37 270.09 463.5 270.52 463.5"/>
<polygon class="cls-4" points="277.48 463.5 278.89 472.37 271.93 472.37 270.52 463.5 277.48 463.5"/>
<polygon class="cls-4" points="284.44 463.5 285.84 472.37 278.89 472.37 277.48 463.5 284.44 463.5"/>
<polygon class="cls-4" points="291.4 463.5 292.8 472.37 285.84 472.37 284.44 463.5 291.4 463.5"/>
<polygon class="cls-4" points="298.36 463.5 299.76 472.37 292.8 472.37 291.4 463.5 298.36 463.5"/>
<polygon class="cls-4" points="305.32 463.5 306.72 472.37 299.76 472.37 298.36 463.5 305.32 463.5"/>
<polygon class="cls-4" points="312.27 463.5 313.68 472.37 306.72 472.37 305.32 463.5 312.27 463.5"/>
<polygon class="cls-4" points="319.23 463.5 320.64 472.37 313.68 472.37 312.27 463.5 319.23 463.5"/>
<polygon class="cls-4" points="326.19 463.5 327.6 472.37 320.64 472.37 319.23 463.5 326.19 463.5"/>
<polygon class="cls-4" points="333.15 463.5 334.55 472.37 327.6 472.37 326.19 463.5 333.15 463.5"/>
<polygon class="cls-4" points="340.11 463.5 341.51 472.37 334.55 472.37 333.15 463.5 340.11 463.5"/>
<polygon class="cls-4" points="347.07 463.5 348.47 472.37 341.51 472.37 340.11 463.5 347.07 463.5"/>
<polygon class="cls-4" points="354.03 463.5 355.43 472.37 348.47 472.37 347.07 463.5 354.03 463.5"/>
<polygon class="cls-4" points="360.98 463.5 362.39 472.37 355.43 472.37 354.03 463.5 360.98 463.5"/>
<polygon class="cls-4" points="367.94 463.5 369.35 472.37 362.39 472.37 360.98 463.5 367.94 463.5"/>
<polygon class="cls-4" points="374.9 463.5 376.31 472.37 369.35 472.37 367.94 463.5 374.9 463.5"/>
<polygon class="cls-4" points="381.86 463.5 383.26 472.37 376.31 472.37 374.9 463.5 381.86 463.5"/>
<polygon class="cls-4" points="388.82 463.5 390.22 472.37 383.26 472.37 381.86 463.5 388.82 463.5"/>
<polygon class="cls-4" points="395.78 463.5 397.18 472.37 390.22 472.37 388.82 463.5 395.78 463.5"/>
<polygon class="cls-4" points="402.73 463.5 404.14 472.37 397.18 472.37 395.78 463.5 402.73 463.5"/>
<polygon class="cls-4" points="409.69 463.5 411.1 472.37 404.14 472.37 402.73 463.5 409.69 463.5"/>
<polygon class="cls-4" points="416.65 463.5 418.06 472.37 411.1 472.37 409.69 463.5 416.65 463.5"/>
<polygon class="cls-4" points="423.61 463.5 425.01 472.37 418.06 472.37 416.65 463.5 423.61 463.5"/>
<polygon class="cls-4" points="430.57 463.5 431.97 472.37 425.01 472.37 423.61 463.5 430.57 463.5"/>
<polygon class="cls-55" points="437.53 463.5 438.93 472.37 431.97 472.37 430.57 463.5 437.53 463.5"/>
<polygon class="cls-4" points="444.49 463.5 445.89 472.37 438.93 472.37 437.53 463.5 444.49 463.5"/>
<polygon class="cls-26" points="451.44 463.5 452.85 472.37 445.89 472.37 444.49 463.5 451.44 463.5"/>
<polygon class="cls-4" points="458.4 463.5 459.81 472.37 452.85 472.37 451.44 463.5 458.4 463.5"/>
<polygon class="cls-4" points="465.36 463.5 466.77 472.37 466.77 472.37 459.81 472.37 458.4 463.5 465.36 463.5"/>
<polygon class="cls-4" points="466.77 472.37 465.36 463.5 466.77 463.5 466.77 472.37"/>
</g>
<path class="cls-44" d="m467.72,473.18h-192.19c-2.78,0-5.4-2.26-5.83-5.03l-.03-.19c-.22-1.41.13-2.74.99-3.75.85-.99,2.08-1.54,3.47-1.54h191.93l1.66,10.5Zm-193.59-8.88c-.91,0-1.7.34-2.24.97-.55.64-.77,1.51-.62,2.44l.03.19c.32,2.02,2.22,3.66,4.23,3.66h190.29l-1.15-7.25h-190.54Z"/>
<path class="cls-4" d="m465.99,472.37h15.06c2.4,0,4.04-1.95,3.66-4.35l-.03-.19c-.38-2.4-2.63-4.35-5.03-4.35h-15.06c-2.4,0-4.04,1.95-3.66,4.35l.03.19c.38,2.4,2.63,4.35,5.03,4.35Z"/>
<path class="cls-44" d="m481.05,473.18h-15.06c-2.78,0-5.4-2.26-5.83-5.03l-.03-.18c-.22-1.41.13-2.74.99-3.75.85-.99,2.08-1.54,3.47-1.54h15.06c2.78,0,5.4,2.26,5.83,5.03l.03.18c.22,1.41-.13,2.74-.99,3.75-.85.99-2.08,1.54-3.47,1.54Zm-16.46-8.88c-.91,0-1.7.34-2.24.97-.55.64-.77,1.51-.62,2.44l.03.18c.32,2.02,2.22,3.66,4.23,3.66h15.06c.91,0,1.7-.34,2.24-.97.55-.64.77-1.51.62-2.44l-.03-.18c-.32-2.02-2.22-3.66-4.23-3.66h-15.06Z"/>
</g>
<g>
<path class="cls-63" d="m320.46,133.97h-155.48c-4.07,0-7.4-3.3-7.43-7.38l-.63-85.31c-.03-4.07,3.25-7.38,7.32-7.38h155.48c4.07,0,7.4,3.3,7.43,7.38l.63,85.31c.03,4.07-3.25,7.38-7.32,7.38Z"/>
<polygon class="cls-4" points="314.32 68.54 238.79 68.54 238.74 61.82 314.27 61.82 314.32 68.54"/>
<polygon class="cls-4" points="314.46 87.3 238.93 87.3 238.88 80.57 314.41 80.57 314.46 87.3"/>
<polygon class="cls-33" points="276.83 106.05 239.07 106.05 239.02 99.33 276.78 99.33 276.83 106.05"/>
</g>
<path class="cls-44" d="m670.62,296.46c-1.32,0-2.64,1.07-2.96,2.39-.32,1.32.5,2.39,1.81,2.39s2.64-1.07,2.96-2.39c.32-1.32-.5-2.39-1.81-2.39Z"/>
<path class="cls-44" d="m98.43,256.14c-1.33,0-2.66,1.07-2.98,2.4-.32,1.33.5,2.4,1.82,2.4s2.66-1.07,2.98-2.4c.32-1.33-.5-2.4-1.82-2.4Z"/>
<path class="cls-36" d="m725.01,299.56c-1.65,0-3.31,1.34-3.7,2.98-.4,1.65.62,2.98,2.27,2.98s3.31-1.34,3.7-2.98c.4-1.65-.62-2.98-2.27-2.98Z"/>
<path class="cls-29" d="m20.75,263.19c-1.51,0-3.03,1.23-3.39,2.74-.36,1.51.57,2.74,2.08,2.74s3.03-1.23,3.39-2.74c.36-1.51-.57-2.74-2.08-2.74Z"/>
<path class="cls-44" d="m764.33,473.18H10.82c-.45,0-.81-.36-.81-.81s.36-.81.81-.81h753.51c.45,0,.81.36.81.81s-.36.81-.81.81Z"/>
<g>
<path class="cls-30" d="m363.73,230.37h-181.35c-6,0-11.43-5.36-11.43-11.29l-.02-55.55c0-4.75,3.54-8.24,8.34-8.24h181.35c6,0,11.43,5.36,11.43,11.29l.02,55.55c0,4.75-3.54,8.24-8.34,8.24Z"/>
<g>
<path class="cls-4" d="m292.72,185.47h-40.54c-1.02,0-1.95-.91-1.95-1.92v-9.45c0-.81.6-1.4,1.42-1.4h40.54c1.02,0,1.95.91,1.95,1.92v9.45c0,.81-.6,1.4-1.42,1.4Z"/>
<path class="cls-4" d="m350.82,205.05h-98.62c-1.02,0-1.95-.91-1.95-1.92v-9.45c0-.81.6-1.4,1.42-1.4h98.62c1.02,0,1.95.91,1.95,1.92v9.45c0,.81-.6,1.4-1.42,1.4Z"/>
</g>
<path class="cls-36" d="m209.1,212.44c.71.14,1.09.18,1.09.18,0,0-.38-.06-1.08-.23-.34-.1-.78-.2-1.26-.39v.12c.48.15.9.25,1.25.32Z"/>
</g>
<g>
<g>
<path class="cls-63" d="m662.9,104.77s-7.01,9.91-1.15,15.35l7.07-13.12-5.92-2.23Z"/>
<g>
<g>
<path class="cls-63" d="m688.53,135.41s9.66-1.31,10.74-21.24c1.07-19.92-17.64-21.02-28.76-16.17,0,0-10.81,5.42-.97,19.46,9.84,14.04,18.99,17.94,18.99,17.94Z"/>
<g>
<path class="cls-22" d="m698.63,120.35c-1.04-.79-2.55-.99-3.85-.58,1.41-6.83.45-13.86-4.64-18.38-1.08-.95-2.24-1.69-3.47-2.23-5.79-2.54-15.27-1.56-20.39,2.44-5.13,4.01-4.02,11.77-5.06,18.27-1.39,8.72-.31,17.72,8.4,20.59.44.15.89.26,1.34.36l-1.15,14.34c-.53,6.06,4.46,11.18,10.53,10.81,5.26-.32,9.36-4.68,9.35-9.95,0,0,.46-21.83.58-24.8,0-.16.17-.24.31-.16,1.67.92,3.85,1.14,5.58.45,2.14-.85,3.84-2.97,4.31-5.37.41-2.15-.23-4.55-1.85-5.79Z"/>
<path class="cls-19" d="m693.87,126.85c1.27.08,2.34-.65,2.4-1.63.04-.73-.49-1.4-1.3-1.71"/>
<path class="cls-63" d="m670.51,145.74l.31-5.16s8.53,2.24,15.82-5.16c0,0-4.1,9.11-16.14,10.32Z"/>
</g>
</g>
<path class="cls-63" d="m686.03,105.28s-20.88,12.29-23.57.91c-1.04-4.4,8.64-18.29,28.58-8.78,0,0,9.19,6.7,6.13,22.27,0,0-.81-.52-2.25,0-4.27,1.52-8.85-1.52-9.36-6.02-.25-2.25-.17-5.01.48-8.38Z"/>
</g>
</g>
<g>
<path class="cls-22" d="m637.27,265.61h0c-.83,5.11-1.78,8.97-2.02,13.59-.16,3.02.48,5.77.96,5.56,1.03-.46,2.56-7.07,2.56-7.07,0,0-.9,9.43.64,6.77,1.54-2.66,2.46-8.14,2.46-8.14,0,0,.13,8.97,1.29,5.99,1.15-2.98,1.72-8.43,1.72-8.43,0,0,.59,10,1.93,5.21,1.34-4.8,4.19-13.7,4.19-13.7l-13.73.23Z"/>
<polygon class="cls-22" points="648.89 193.13 636.88 268.2 648.89 273 659.7 206.34 648.89 193.13"/>
</g>
<g>
<polygon class="cls-22" points="645.06 460.58 661.73 460.58 662.77 435.94 647.06 435.94 645.06 460.58"/>
<path class="cls-63" d="m661.73,458.19h-20.62l-15.57,6.52c-3.09,1.59-5.04,4.77-5.04,8.25h43.58l-2.36-14.77Z"/>
<path class="cls-63" d="m639.58,458.89l4.21-5.7s6.59-1.2,6.01,5.96l-10.23-.26Z"/>
</g>
<g>
<polygon class="cls-22" points="726.08 454.34 741.75 448.94 734.71 425.25 719.04 430.65 726.08 454.34"/>
<path class="cls-63" d="m740.89,446.72l-19.36,6.83-12.16,11.71c-2.31,2.6-2.97,6.27-1.71,9.51h0l40.76-15.13-7.54-12.92Z"/>
<path class="cls-63" d="m720.36,454.75l1.87-6.84s5.71-3.5,7.76,3.39l-9.63,3.46Z"/>
</g>
<path class="cls-63" d="m669.69,448.91l-37.28-.33s16.45-181.72,27.42-234.84l32.69-3.89-22.82,239.05Z"/>
<path class="cls-63" d="m748.91,437.46l-34.01,8.15s-48.29-199.38-36.06-235.7l35.95-2.85,34.12,230.39Z"/>
<path class="cls-4" d="m722.9,271.14s-.05,0-.07,0c-6.65-1.01-11.96-5.45-15.37-12.86-2.55-5.55-3.14-10.72-3.16-10.93-.03-.26.16-.5.42-.53.26-.03.5.16.53.42,0,.05.59,5.25,3.09,10.66,3.31,7.19,8.24,11.32,14.64,12.29.26.04.44.28.4.54-.04.24-.24.41-.47.41Z"/>
<path class="cls-4" d="m652.72,267.48c-.24,0-.45-.18-.47-.42-.03-.26.16-.5.42-.53,9.01-1.07,11.3-21.85,11.32-22.06.03-.26.26-.45.53-.43.26.03.45.26.43.53-.09.89-2.4,21.75-12.16,22.91-.02,0-.04,0-.06,0Z"/>
<path class="cls-4" d="m683.85,300.36c-.25,0-.47-.2-.48-.46l-1.97-44.69c-.01-.26.19-.49.46-.5.25-.01.49.19.5.46l1.97,44.69c.01.26-.19.49-.46.5,0,0-.01,0-.02,0Z"/>
<g>
<path class="cls-64" d="m690.34,145.74l-8.64,17.09-11.51-15.54s-26.14-.75-26.14,62.66l13.69,1.51-6.92,41.36,70.26-1.12-2.47-53.11,16.86-7.91s-16.33-47.02-45.14-44.92Z"/>
<path class="cls-17" d="m715.86,200.15c-.18,0-.35-.1-.43-.27l-7.08-14.65c-.12-.24-.02-.52.22-.64.24-.11.52-.02.64.22l7.08,14.65c.12.24.02.52-.22.64-.07.03-.14.05-.21.05Z"/>
<path class="cls-22" d="m735.48,190.66s16.08,44.33.46,45.53c-15.61,1.2-53.91-39.53-53.91-39.53l5.27-13.01,31.89,25.85-3.33-9.84,19.62-9.01Z"/>
<g>
<polygon class="cls-4" points="695.33 161.28 678.57 218.8 636.88 205.59 652.83 148.67 695.33 161.28"/>
<polygon class="cls-4" points="692.49 171.77 704.8 171.39 704.8 177.13 692.49 176.4 692.49 171.77"/>
<path class="cls-22" d="m695.01,189.91h0c-3.14-3.4-6.95-6.11-11.2-7.96-2.77-1.2-5.36-2.18-5.39-1.66-.06,1.13,5.14,5.49,5.14,5.49,0,0-8-5.08-6.32-2.49,1.67,2.58,6.14,5.88,6.14,5.88,0,0-8.06-3.95-5.92-1.57,2.14,2.38,6.73,6.34,6.73,6.34,0,0-9.19-4.19-5.52-.82,3.67,3.37,8.82,9.13,8.82,9.13l7.51-12.35Z"/>
</g>
</g>
<path class="cls-63" d="m696.67,104.93c-1.03-1.79-2.19-3.49-3.48-5.1-.25-.31-.52-.64-.9-.77-.45-.16-.94-.03-1.4.05-2.03.37-4.14-.16-6.01-1.03s-3.58-2.06-5.35-3.12c-2.57-1.53-5.31-2.77-8.03-4.01-4.66-2.12-7.88,1.45-11.15,4.44-1.11,1.01-2.21,2.11-2.73,3.52-.63,1.69-.33,3.57.08,5.33.27,1.17.61,2.37,1.34,3.33.88,1.17,2.24,1.88,3.63,2.36,2.74.95,5.74,1.13,8.57.51,2.63-.58,5.06-1.81,7.64-2.58,2.77-.83,5.7-1.11,8.58-.83"/>
</g>
<g>
<g>
<g>
<g>
<path class="cls-63" d="m47.43,148.01l21.34,1.18-5.52-49.52c-19.4-.19-15.97,16.61-24.22,25.96-2.72,3.08-3.91,5.99-4.17,8.64-.67,6.81,5.42,13.35,12.57,13.74Z"/>
<path class="cls-63" d="m62.21,99.68l1.21,50.45,4.46-.31c10.49-.74,18.25-10.05,17.12-20.51-1.47-13.68-6.65-29.63-22.79-29.63Z"/>
</g>
<path class="cls-22" d="m45.48,124.69c1.04-.8,2.56-1.01,3.87-.6-1.45-6.87-.52-13.95,4.59-18.52,1.08-.97,2.25-1.71,3.48-2.26,5.81-2.58,12.94-.71,18.11,3.3,5.18,4.01,4.33,10.63,5.4,17.16,1.44,8.77,2.59,18.1-6.16,21.03-.45.15-.9.27-1.35.37l1.22,14.43c.56,6.1-4.43,11.27-10.55,10.93-5.3-.3-9.44-4.67-9.46-9.97,0,0-.56-21.97-.7-24.96,0-.16-.18-.24-.32-.16-1.67.93-3.87,1.16-5.61.48-2.16-.85-3.88-2.98-4.36-5.39-.43-2.16.21-4.58,1.84-5.84Z"/>
<path class="cls-45" d="m50.1,131.67c-.63,0-1.23-.17-1.71-.5-.57-.39-.91-.94-.95-1.55-.06-.91.56-1.76,1.58-2.17.23-.09.49.02.58.25s-.02.49-.25.58c-.66.26-1.06.77-1.02,1.29.02.33.22.64.56.87.38.25.87.37,1.39.34.24-.02.46.17.47.41.02.24-.17.46-.41.47-.08,0-.15,0-.23,0Z"/>
<path class="cls-63" d="m73.91,150.13l-.34-5.19s-8.57,2.3-15.95-5.13c0,0,4.16,9.15,16.29,10.32Z"/>
<path class="cls-63" d="m76.36,112.6c2.66,1.57,3.57,3.5,4.39,6.14,0,0,2.63-10.16-5.3-14.56l-3.2-.02s-3.31,4.05,4.11,8.44Z"/>
</g>
<path class="cls-63" d="m55.19,105.57c8.27,6.46,1.38,20.05-4.89,19.28,0,0-1.28-1.64-3.05-.9,0,0,1.57-23.35,7.94-18.38Z"/>
</g>
<g>
<g>
<g>
<path class="cls-22" d="m81.86,211.36l18.67,14.84c6.99,5.07,14.18,3.25,18.18-4.41.26-.49.49-1.01.7-1.54,3.29-8.54,4.45-60.76,4.45-60.76l-11.26-.36-7.82,45.57-10.57-8.75-12.34,15.41Z"/>
<path class="cls-22" d="m111.99,164.42c.22-5.01.92-10.56,2.01-14.33.71-2.46,1.47-4.68,1.83-4.42.77.57.8,6.32.8,6.32,0,0,1.01-7.96,1.79-5.48s.52,7.19.52,7.19c0,0,1.78-7.39,2.18-4.71.4,2.68-.15,7.29-.15,7.29,0,0,2.35-8.16,2.57-3.95.32,6.27.49,6.85.14,12.37l-11.68-.29Z"/>
</g>
<path class="cls-53" d="m109.32,168.86l17.03,6.44s.32,59.86-17.92,55.09c-18.24-4.77-22.52-10.83-22.52-10.83l-2.11-42.88,22.2,16.76,3.32-24.57Z"/>
</g>
<g>
<polygon class="cls-22" points="102.86 461.97 87.38 461.97 84.63 439.07 101 439.07 102.86 461.97"/>
<path class="cls-63" d="m86.79,459.75l16.13-.79,18.38,6.85c2.87,1.48,4.68,4.44,4.68,7.67h-40.49l1.3-13.72Z"/>
</g>
<g>
<polygon class="cls-22" points="22.68 454.24 8.2 448.75 13.76 426.37 29.07 432.18 22.68 454.24"/>
<path class="cls-63" d="m8.44,446.47l15.36,4.99,14.76,12.93c2.16,2.4,2.8,5.81,1.65,8.83h0l-37.86-14.37,6.09-12.37Z"/>
</g>
<path class="cls-63" d="m75.03,449.07l38.19.58s-9.49-204.44-28.46-234.58l-30.94-.03,21.2,234.02Z"/>
<path class="cls-63" d="m3.79,435.57l36.99,9.54s37.11-196.26,25.75-230l-33.41-2.65L3.79,435.57Z"/>
<path class="cls-64" d="m55.52,152.76l10.27,16.76,9.41-16.03s10.48-1.21,10.2,36.85l3.36,69.23-60.06.52.86-55.51-15.66-7.35s14.86-46.42,41.62-44.47Z"/>
<g>
<path class="cls-53" d="m96.88,255.83l12.55,79.02h-21.34c1.42-1.42-11.51-180.98-11.51-180.98,0,0,6.9-2.72,12.04,10.84l5.13,62.68"/>
<path class="cls-57" d="m96.88,256.27c-.22,0-.41-.16-.44-.38l-6.27-46.23c-.03-.24.14-.47.38-.5.24-.03.47.14.5.38l6.27,46.23c.03.24-.14.47-.38.5-.02,0-.04,0-.06,0Z"/>
<path class="cls-17" d="m81.59,197.9s-.07,0-.1-.01c-.24-.05-.39-.29-.33-.53l5.48-24.05-5.3-4.85c-.1-.09-.15-.23-.14-.36.01-.14.08-.26.2-.34l6.15-4.1-10.41-9.13c-.18-.16-.2-.44-.04-.63.16-.18.44-.2.63-.04l10.85,9.51c.1.09.16.23.15.36,0,.14-.08.26-.2.34l-6.16,4.11,5.07,4.64c.12.11.17.27.13.43l-5.54,24.3c-.05.21-.23.35-.43.35Z"/>
</g>
<path class="cls-4" d="m62.52,309.49s-.04,0-.05,0c-.24-.03-.42-.25-.39-.49l4.7-39.43c.03-.24.25-.42.49-.39.24.03.42.25.39.49l-4.7,39.43c-.03.23-.22.39-.44.39Z"/>
<g>
<g>
<path class="cls-53" d="m50.51,152.96h0c6.48,18.24,8.03,37.86,4.5,56.88l-22.88,123.22-32.13,1.79,20.13-87,30.37-94.89Z"/>
<g>
<path class="cls-22" d="m58.66,190.71l-19.5,15.81c.02,1.55.03,3.1,0,4.65.53,4.29,1.22,8.57,1.95,12.84,11.93-10.03,22.44-21.21,22.44-21.21l-4.9-12.09Z"/>
<path class="cls-53" d="m50.51,152.96h0c-8.74-1.27-20.36,5.02-25.33,12.17-7.99,11.49-35.26,66.73-18.05,75.74,17.21,9.01,53.27-29.73,53.27-29.73l-7.52-15.74-20.75,14.97,18.38-57.42Z"/>
<path class="cls-57" d="m32.13,207.02c-.06,0-.11-.01-.17-.03-.23-.09-.34-.35-.25-.58l5.97-14.87c.09-.23.35-.34.58-.25.23.09.34.35.25.58l-5.97,14.87c-.07.17-.24.28-.41.28Z"/>
<path class="cls-57" d="m50.18,195.89c-.18,0-.35-.11-.42-.29l-8.89-23.29c-.06-.15-.03-.32.07-.44l4.37-5.3-6.67-3.21c-.13-.06-.23-.19-.25-.34-.02-.15.03-.29.14-.39l10.25-9.15c.18-.16.46-.15.63.04.16.18.15.46-.04.63l-9.75,8.71,6.58,3.16c.12.06.21.17.24.3s0,.27-.09.38l-4.57,5.54,8.8,23.05c.09.23-.03.49-.26.57-.05.02-.11.03-.16.03Z"/>
<path class="cls-57" d="m25.21,212.87c-.13,0-.25-.05-.34-.16-.16-.19-.13-.47.06-.63l15.2-12.63c.19-.16.47-.13.63.06.16.19.13.47-.06.63l-15.2,12.63c-.08.07-.18.1-.28.1Z"/>
</g>
</g>
<g>
<polygon class="cls-35" points="54.34 165.97 74.87 217.72 111.02 202.42 90.36 151.16 54.34 165.97"/>
<path class="cls-22" d="m57.14,192.43h0c3.09-3.24,6.13-5.76,9.66-8.34,2.27-1.66,4.77-2.49,4.84-2.01.16,1.04-4.28,5.53-4.28,5.53,0,0,6.95-5.39,5.63-2.86-1.32,2.53-5.17,5.98-5.17,5.98,0,0,7.11-4.36,5.34-1.97-1.77,2.39-5.76,5.54-5.76,5.54,0,0,8.15-4.51,5.05-1.07-3.1,3.44-8.75,9.43-8.75,9.43l-6.56-10.22Z"/>
</g>
</g>
</g>
<path class="cls-63" d="m75.45,106.53s-5.75,19.59-22.46,16.97l-4.18-14.89,6.27-5.22s3.13-2.09,3.92-2.35,9.4.78,9.4.78l7.05,4.7Z"/>
</g>
<g>
<polygon class="cls-4" points="199.87 211.84 199.88 217.74 235.8 217.74 235.77 175.72 229.82 175.72 229.84 211.84 199.87 211.84"/>
<path class="cls-4" d="m230.79,212.78h-37.82l-.03-43.9h37.82l.03,43.9Zm-35.92-1.88h34.03l-.03-40.15h-34.03l.03,40.15Z"/>
<rect class="cls-4" x="203.88" y="165.61" width="15.94" height="8.42"/>
<rect class="cls-4" x="200.28" y="183.6" width="23.17" height="1.88"/>
<rect class="cls-4" x="200.28" y="193.11" width="23.17" height="1.88"/>
<rect class="cls-4" x="200.29" y="202.62" width="23.17" height="1.88"/>
</g>
<g>
<path class="cls-4" d="m216.85,86.58c-2.26,1.18-5.08,2.14-8.3,2.83l-32.33-16.5c2.15-1.22,4.86-2.23,7.98-2.99l32.64,16.66Z"/>
<path class="cls-4" d="m196.92,91.76c-1.6,0-3.17-.06-4.69-.18-13.16-1.01-22.35-5.96-22.35-12.03,0-2.86,2-5.5,5.78-7.65,2.26-1.28,5.05-2.33,8.28-3.1,2.56-.62,5.35-1.05,8.29-1.27,3.02-.24,6.34-.24,9.38,0,13.16,1,22.35,5.94,22.35,12.02,0,3.07-2.27,5.87-6.57,8.07-2.36,1.23-5.25,2.21-8.58,2.93-2.29.5-4.71.84-7.2,1.03-1.51.12-3.09.18-4.69.18Zm0-22.1c-1.53,0-3.05.06-4.51.17-2.82.21-5.48.62-7.93,1.22-3.02.73-5.61,1.69-7.68,2.87-2.97,1.68-4.6,3.68-4.6,5.63,0,2.15,1.94,4.31,5.46,6.09,3.76,1.9,8.99,3.19,14.74,3.63,2.92.23,6.1.23,9.02,0,2.39-.18,4.7-.51,6.89-.99,3.13-.68,5.83-1.59,8.01-2.72,3.43-1.76,5.32-3.89,5.32-6.01s-1.94-4.31-5.46-6.09c-3.76-1.9-8.99-3.18-14.74-3.62-1.46-.12-2.98-.17-4.51-.17Z"/>
<path class="cls-4" d="m196.92,102.81c-1.59,0-3.17-.06-4.69-.18-13.16-1.01-22.35-5.95-22.35-12.03v-11.05h2.32v11.05c0,2.15,1.94,4.31,5.46,6.09,3.76,1.9,8.99,3.19,14.74,3.63,2.92.23,6.1.23,9.02,0,5.75-.44,10.99-1.73,14.75-3.63,3.52-1.78,5.46-3.94,5.46-6.09v-11.05h2.32v11.05c0,6.08-9.19,11.02-22.35,12.03-1.51.12-3.09.18-4.69.18Z"/>
</g>
<g>
<rect class="cls-4" x="398.49" y="176.57" width="137.96" height="80.72"/>
<polyline class="cls-42" points="398.49 176.57 536.45 176.57 536.45 215.41"/>
<polyline class="cls-42" points="503.26 257.29 398.49 257.29 398.49 187.62"/>
<line class="cls-42" x1="536.45" y1="229.59" x2="536.45" y2="257.29"/>
<g>
<line class="cls-39" x1="525.9" y1="188.3" x2="490.21" y2="188.3"/>
<line class="cls-38" x1="525.9" y1="196.44" x2="485.52" y2="196.44"/>
<line class="cls-38" x1="505.8" y1="202.43" x2="485.52" y2="202.43"/>
<line class="cls-38" x1="525.9" y1="202.43" x2="513.1" y2="202.43"/>
<line class="cls-38" x1="525.9" y1="208.41" x2="485.52" y2="208.41"/>
<line class="cls-38" x1="525.9" y1="214.39" x2="487.33" y2="214.39"/>
</g>
<rect class="cls-42" x="405.99" y="185.56" width="66.6" height="62.74"/>
<circle class="cls-23" cx="521.51" cy="224.85" r="4.38"/>
<circle class="cls-58" cx="505.8" cy="224.85" r="4.38"/>
<circle class="cls-58" cx="490.09" cy="224.85" r="4.38"/>
<line class="cls-40" x1="525.9" y1="238.63" x2="499.66" y2="238.63"/>
<line class="cls-40" x1="525.9" y1="243.44" x2="507.25" y2="243.44"/>
</g>
<g>
<path class="cls-52" d="m429.34,203.49s4.02-.96,6.1-.32c2.09.64,4.61,3.53,6.64,3.11,2.03-.43,4.99-1.22,6.43-.75s.96,3.05.96,3.75-3.37,15.58-4.93,16.65c-1.55,1.07-1.22,2.95-3.1,2.68-1.88-.27-2.36-1.93-2.84-2.78-.48-.86-4.55-10.76-4.61-10.92-.05-.16-4.66-11.41-4.66-11.41Z"/>
<path class="cls-25" d="m415.84,238.62s-1.77.16-1.5-4.28c.27-4.44,0-15.8,1.5-20.72,1.5-4.93,5.38-10.75,12.85-10.98,17.4-.54,12.08,24.3,11.65,25.6-.86,2.54-5.92,6.45-9.53,6.99-12.57,1.86-13.25,3.51-14.97,3.4Z"/>
<path class="cls-25" d="m443.33,211.17s.57-5.07,6.89-5.18c6.32-.11,8.15,1.91,10.31,2.24,2.44.37,4.47.16,4.69,1.79.15,1.14-2.93,4.61-3.61,5.93-.68,1.32-4,8.07-10.07,10.03-6.07,1.96-7.75.75-8.43-1-.68-1.75.04-11.46.21-13.82Z"/>
</g>
<g>
<g>
<path class="cls-4" d="m537.16,267.25v84.36c0,1.28-1,2.32-2.24,2.32h-135.16c-1.24,0-2.24-1.04-2.24-2.32v-84.36c0-1.28,1-2.32,2.24-2.32h135.16c1.24,0,2.24,1.04,2.24,2.32Z"/>
<path class="cls-54" d="m534.03,262.67h-133.21c-2.26,0-4.09,1.83-4.09,4.09v86.08c0,2.26,1.83,4.09,4.09,4.09h133.21c2.26,0,4.09-1.83,4.09-4.09v-86.08c0-2.26-1.83-4.09-4.09-4.09Zm2.66,88.97c0,1.26-1,2.29-2.22,2.29h-133.98c-1.23,0-2.22-1.02-2.22-2.29v-83.24c0-1.26.99-2.29,2.22-2.29h133.98c1.23,0,2.22,1.02,2.22,2.29v83.24Z"/>
<rect class="cls-2" x="398.26" y="346.96" width="138.43" height="6.97" rx="3.48" ry="3.48"/>
<g>
<path class="cls-4" d="m511.59,350.47h-108.39c-.27,0-.48.24-.48.53s.22.53.48.53h108.39c.27,0,.48-.24.48-.53s-.22-.53-.48-.53Z"/>
<rect class="cls-4" x="422.65" y="349.6" width=".65" height="2.79"/>
<path class="cls-4" d="m399.76,351c0-.47.38-.86.86-.86s.86.38.86.86-.38.86-.86.86-.86-.38-.86-.86Z"/>
<g>
<path class="cls-4" d="m518.69,351c0-.47.38-.86.86-.86s.86.38.86.86-.38.86-.86.86-.86-.38-.86-.86Z"/>
<circle class="cls-4" cx="523.14" cy="351" r=".86"/>
<path class="cls-4" d="m514.59,351c0-.47.38-.86.86-.86s.86.38.86.86-.38.86-.86.86-.86-.38-.86-.86Z"/>
</g>
<g>
<path class="cls-4" d="m532.55,352.84c-.16,0-.29-.13-.29-.29s.13-.29.29-.29c.59,0,1.06-.48,1.06-1.06,0-.16.13-.29.29-.29s.29.13.29.29c0,.9-.74,1.64-1.64,1.64Z"/>
<path class="cls-4" d="m533.9,350.01c-.16,0-.29-.13-.29-.29,0-.58-.48-1.06-1.06-1.06-.16,0-.29-.13-.29-.29s.13-.29.29-.29c.9,0,1.64.73,1.64,1.64,0,.16-.13.29-.29.29Z"/>
<path class="cls-4" d="m527.69,350.01c-.16,0-.29-.13-.29-.29,0-.9.74-1.64,1.64-1.64.16,0,.29.13.29.29s-.13.29-.29.29c-.59,0-1.06.48-1.06,1.06,0,.16-.13.29-.29.29Z"/>
<path class="cls-4" d="m529.04,352.84c-.9,0-1.64-.73-1.64-1.64,0-.16.13-.29.29-.29s.29.13.29.29c0,.58.48,1.06,1.06,1.06.16,0,.29.13.29.29s-.13.29-.29.29Z"/>
</g>
</g>
<path class="cls-1" d="m423.34,335.57h-21.41c-.37,0-.68-.3-.68-.68h0c0-.37.3-.68.68-.68h21.41c.37,0,.68.3.68.68h0c0,.37-.3.68-.68.68Z"/>
<path class="cls-1" d="m423.34,332.36h-21.41c-.37,0-.68-.3-.68-.68h0c0-.37.3-.68.68-.68h21.41c.37,0,.68.3.68.68h0c0,.37-.3.68-.68.68Z"/>
<path class="cls-1" d="m423.34,328.8h-21.41c-.37,0-.68-.3-.68-.68h0c0-.37.3-.68.68-.68h21.41c.37,0,.68.3.68.68h0c0,.37-.3.68-.68.68Z"/>
<path class="cls-1" d="m529.2,281.57h-21.41c-.37,0-.68-.3-.68-.68h0c0-.37.3-.68.68-.68h21.41c.37,0,.68.3.68.68h0c0,.37-.3.68-.68.68Z"/>
<path class="cls-1" d="m529.2,278.36h-21.41c-.37,0-.68-.3-.68-.68h0c0-.37.3-.68.68-.68h21.41c.37,0,.68.3.68.68h0c0,.37-.3.68-.68.68Z"/>
<path class="cls-1" d="m529.2,274.8h-21.41c-.37,0-.68-.3-.68-.68h0c0-.37.3-.68.68-.68h21.41c.37,0,.68.3.68.68h0c0,.37-.3.68-.68.68Z"/>
<g>
<path class="cls-1" d="m438.88,270.95h-34.15c-.37,0-.68-.3-.68-.68h0c0-.37.3-.68.68-.68h34.15c.37,0,.68.3.68.68h0c0,.37-.3.68-.68.68Z"/>
<path class="cls-1" d="m426.14,275.39h-21.41c-.37,0-.68-.3-.68-.68h0c0-.37.3-.68.68-.68h21.41c.37,0,.68.3.68.68h0c0,.37-.3.68-.68.68Z"/>
<path class="cls-1" d="m438.36,275.39h-6.58c-.37,0-.68-.3-.68-.68h0c0-.37.3-.68.68-.68h6.58c.37,0,.68.3.68.68h0c0,.37-.3.68-.68.68Z"/>
</g>
<g>
<path class="cls-1" d="m519.53,323.61h-21.41c-.37,0-.68-.3-.68-.68h0c0-.37.3-.68.68-.68h21.41c.37,0,.68.3.68.68h0c0,.37-.3.68-.68.68Z"/>
<path class="cls-1" d="m519.53,328.93h-12.11c-.37,0-.68-.3-.68-.68h0c0-.37.3-.68.68-.68h12.11c.37,0,.68.3.68.68h0c0,.37-.3.68-.68.68Z"/>
<rect class="cls-1" x="523.32" y="321.12" width="11.73" height="8.12" rx="1.76" ry="1.76"/>
</g>
</g>
<g>
<g>
<path class="cls-2" d="m532.29,287.14h-7.01c-.06,0-.1-.04-.1-.1s.04-.1.1-.1h7.01c.06,0,.1.04.1.1s-.04.1-.1.1Z"/>
<path class="cls-2" d="m531.84,289.3h-6.12c-.06,0-.1-.04-.1-.1s.04-.1.1-.1h6.12c.06,0,.1.04.1.1s-.04.1-.1.1Z"/>
<path class="cls-2" d="m530.56,291.08h-3.5c-.06,0-.1-.04-.1-.1s.04-.1.1-.1h3.5c.06,0,.1.04.1.1s-.04.1-.1.1Z"/>
<path class="cls-2" d="m530.56,293.92h-3.5c-.06,0-.1-.04-.1-.1s.04-.1.1-.1h3.5c.06,0,.1.04.1.1s-.04.1-.1.1Z"/>
<path class="cls-2" d="m531.84,295.7h-6.11c-.06,0-.1-.04-.1-.1s.04-.1.1-.1h6.11c.06,0,.1.04.1.1s-.04.1-.1.1Z"/>
<path class="cls-2" d="m532.29,297.86h-7.02c-.06,0-.1-.04-.1-.1s.04-.1.1-.1h7.02c.06,0,.1.04.1.1s-.04.1-.1.1Z"/>
<path class="cls-2" d="m531.83,300.02h-6.1c-.06,0-.1-.04-.1-.1s.04-.1.1-.1h6.1c.06,0,.1.04.1.1s-.04.1-.1.1Z"/>
<path class="cls-2" d="m530.5,301.8h-3.46c-.06,0-.1-.04-.1-.1s.04-.1.1-.1h3.46c.06,0,.1.04.1.1s-.04.1-.1.1Z"/>
<path class="cls-2" d="m530.49,304.64h-3.41c-.06,0-.1-.04-.1-.1s.04-.1.1-.1h3.41c.06,0,.1.04.1.1s-.04.1-.1.1Z"/>
<path class="cls-2" d="m531.84,306.41h-6.1c-.06,0-.1-.04-.1-.1s.04-.1.1-.1h6.1c.06,0,.1.04.1.1s-.04.1-.1.1Z"/>
<path class="cls-2" d="m532.27,308.6h-7c-.06,0-.1-.04-.1-.1s.04-.1.1-.1h7c.06,0,.1.04.1.1s-.04.1-.1.1Z"/>
</g>
<g>
<path class="cls-3" d="m532.29,287.49c-.12,0-.23-.05-.32-.13-.08-.08-.13-.2-.13-.32,0-.03,0-.06,0-.09,0-.03.02-.06.03-.08.01-.03.03-.05.04-.08.02-.02.04-.05.06-.07.11-.11.26-.15.41-.12.03,0,.06.01.09.03.03.01.05.03.08.04.03.02.05.04.07.06.02.02.04.04.06.07.02.03.03.05.04.08.01.03.02.06.03.08,0,.03,0,.06,0,.09,0,.12-.05.23-.13.32-.02.02-.04.04-.07.06-.02.02-.05.03-.08.04-.03.01-.06.02-.08.03-.03,0-.06,0-.09,0Z"/>
<path class="cls-3" d="m531.41,306.5c-.11-.22-.01-.49.21-.6h0c.22-.11.49-.01.6.21h0c.11.22.01.49-.21.6h0c-.06.03-.13.04-.19.04h0c-.17,0-.33-.1-.41-.26Z"/>
<path class="cls-3" d="m530.18,304.86c-.18-.17-.19-.46-.01-.64h0c.17-.18.46-.19.64-.01h0c.18.17.19.46.01.64h0c-.09.09-.21.14-.32.14h0c-.11,0-.23-.04-.31-.13Z"/>
<path class="cls-3" d="m526.73,302.02c-.18-.17-.18-.46-.01-.64h0c.17-.18.46-.18.64,0h0c.18.17.18.46.01.64h0c-.09.09-.21.14-.32.14h0c-.11,0-.23-.04-.31-.13Z"/>
<path class="cls-3" d="m525.32,300.11c-.11-.23,0-.49.22-.6h0c.23-.1.49,0,.6.22h0c.11.23,0,.49-.22.6h0c-.06.03-.13.04-.19.04h0c-.17,0-.33-.1-.41-.26Z"/>
<path class="cls-3" d="m525.27,298.21c-.25,0-.45-.2-.45-.45h0c0-.25.2-.45.45-.45h0c.25,0,.45.2.45.45h0c0,.25-.2.45-.45.45h0Z"/>
<path class="cls-3" d="m525.55,296.01c-.22-.11-.32-.38-.22-.6h0c.11-.23.37-.32.6-.22h0c.23.11.32.37.22.6h0c-.08.16-.24.26-.41.26h0c-.06,0-.13-.01-.19-.04Z"/>
<path class="cls-3" d="m526.74,294.14c-.17-.18-.17-.47.01-.64h0c.18-.17.47-.17.64.01h0c.17.18.17.47-.01.64h0c-.09.08-.2.13-.31.13h0c-.12,0-.24-.05-.32-.14Z"/>
<path class="cls-3" d="m530.18,291.3c-.17-.18-.17-.47.01-.64h0c.18-.17.47-.17.64.01h0c.17.18.17.47-.01.64h0c-.09.09-.2.13-.31.13h0c-.12,0-.24-.05-.32-.14Z"/>
<path class="cls-3" d="m531.64,289.61c-.23-.11-.32-.38-.22-.6h0c.11-.23.37-.32.6-.22h0c.23.11.32.37.22.6h0c-.08.16-.24.26-.41.26h0c-.06,0-.13-.01-.19-.04Z"/>
<path class="cls-3" d="m532.29,308.95s-.06,0-.09,0c-.03,0-.06-.01-.08-.03-.03-.01-.05-.03-.08-.04-.03-.02-.05-.04-.07-.06-.08-.08-.13-.2-.13-.32,0-.03,0-.06,0-.09,0-.03.02-.06.03-.08.01-.03.03-.05.04-.08.02-.02.04-.05.06-.07.08-.08.2-.13.32-.13s.24.05.32.13c.02.02.04.04.06.07.02.03.03.05.04.08.01.03.02.06.03.08,0,.03,0,.06,0,.09s0,.06,0,.09c0,.03-.02.06-.03.08-.01.03-.03.05-.04.08-.02.02-.04.05-.06.07-.02.02-.04.04-.07.06-.02.02-.05.03-.08.04-.03.01-.06.02-.08.03-.03,0-.06,0-.09,0Z"/>
</g>
<g>
<path class="cls-2" d="m525.27,287.49c-.12,0-.23-.05-.32-.13-.08-.08-.13-.2-.13-.32,0-.03,0-.06,0-.09,0-.03.02-.06.03-.08.01-.03.03-.05.04-.08.02-.02.04-.05.06-.07.11-.11.26-.15.41-.12.03,0,.06.01.09.03.03.01.05.03.08.04.03.02.05.04.07.06.02.02.04.04.06.07.02.03.03.05.04.08.01.03.02.06.03.08,0,.03,0,.06,0,.09,0,.12-.05.23-.13.32-.02.02-.04.04-.07.06-.02.02-.05.03-.08.04-.03.01-.06.02-.08.03-.03,0-.06,0-.09,0Z"/>
<path class="cls-2" d="m525.55,306.72c-.22-.11-.32-.38-.21-.6h0c.11-.23.38-.32.6-.21h0c.22.11.32.38.21.6h0c-.08.16-.24.26-.41.26h0c-.07,0-.13-.01-.19-.04Z"/>
<path class="cls-2" d="m526.75,304.85c-.17-.18-.17-.47.01-.64h0c.18-.17.47-.17.64.01h0c.17.18.17.47-.01.64h0c-.09.08-.2.13-.31.13h0c-.12,0-.24-.05-.33-.14Z"/>
<path class="cls-2" d="m528.44,303.39c-.15-.2-.11-.48.08-.63h0c.2-.15.48-.11.63.08h0c.15.2.11.48-.08.63h0c-.08.06-.18.09-.27.09h0c-.14,0-.27-.06-.36-.18Z"/>
<path class="cls-2" d="m530.2,302.01c-.17-.18-.17-.46.01-.64h0c.18-.17.46-.17.64,0h0c.17.18.17.46,0,.64h0c-.09.09-.2.13-.31.13h0c-.12,0-.24-.05-.32-.14Z"/>
<path class="cls-2" d="m531.65,300.33c-.23-.1-.32-.37-.22-.6h0c.1-.23.37-.32.6-.22h0c.23.11.32.37.22.6h0c-.08.16-.24.26-.41.26h0c-.06,0-.13-.01-.19-.04Z"/>
<path class="cls-2" d="m531.84,297.76c0-.25.2-.45.45-.45h0c.25,0,.45.2.45.45h0c0,.25-.2.45-.45.45h0c-.25,0-.45-.2-.45-.45Z"/>
<path class="cls-2" d="m531.42,295.79c-.11-.23,0-.49.22-.6h0c.23-.11.49-.01.6.22h0c.11.23,0,.49-.22.6h0c-.06.03-.13.04-.19.04h0c-.17,0-.33-.1-.41-.26Z"/>
<path class="cls-2" d="m530.19,294.15h0c-.18-.17-.18-.46-.01-.64h0c.17-.18.46-.18.64-.01h0c.18.17.18.46.01.64h0c-.09.09-.21.14-.32.14h0c-.11,0-.23-.04-.31-.13Z"/>
<path class="cls-2" d="m528.51,292.76h0c-.2-.15-.24-.44-.08-.63h0c.15-.2.43-.24.63-.08h0c.2.15.24.43.08.63h0c-.09.12-.22.18-.36.18h0c-.1,0-.19-.03-.27-.09Z"/>
<path class="cls-2" d="m526.75,291.31h0c-.18-.17-.18-.46-.01-.64h0c.17-.18.46-.18.64-.01h0c.18.17.18.46.01.64h0c-.09.09-.21.14-.32.14h0c-.11,0-.23-.04-.31-.13Z"/>
<path class="cls-2" d="m525.33,289.4h0c-.11-.22,0-.49.22-.6h0c.23-.11.49,0,.6.22h0c.11.23,0,.49-.22.6h0c-.06.03-.13.04-.19.04h0c-.17,0-.33-.1-.41-.26Z"/>
<path class="cls-2" d="m525.27,308.95s-.06,0-.09,0c-.03,0-.06-.01-.08-.03-.03-.01-.05-.03-.08-.04-.03-.02-.05-.04-.07-.06-.08-.08-.13-.2-.13-.32,0-.03,0-.06,0-.09s.02-.06.03-.08c.01-.03.03-.05.04-.08.02-.02.04-.05.06-.07.08-.08.2-.13.32-.13s.24.05.32.13c.02.02.04.04.06.07.02.03.03.05.04.08.01.03.02.06.03.08,0,.03,0,.06,0,.09s0,.06,0,.09c0,.03-.02.06-.03.08-.01.03-.03.05-.04.08-.02.02-.04.05-.06.07-.02.02-.04.04-.07.06-.02.02-.05.03-.08.04-.03.01-.06.02-.08.03-.03,0-.06,0-.09,0Z"/>
</g>
</g>
<circle class="cls-4" cx="499.98" cy="303.2" r="2.32"/>
<g id="head">
<path class="cls-49" d="m433.27,316.46c.61-2.67,2.46-5.21,4.14-8.01.77-1.29,2.06-2.31,2.33-3.65.56-2.75-1.55-9.59,2.01-16.72,4.85-9.72,15.76-15.23,26.3-15.2,1.53,0,16.2.28,24.18,12.16,5.92,8.82,5.16,19.47-.42,29.69-2.34,4.28-.78,20.61-.64,25.44h-28.84c-.11-1.3-.67-2.03-.95-2.33-1.39-1.49-4.23-1.2-7-.41-6.78,1.94-9.73,1-10.39.51-1.75-1.3-2.94-4.83-1.91-6.99.24-.5.71-1.17.42-1.72-.35-.68-1.41-.36-2.44-1.22-.14-.12-1.19-.99-.95-2.03.23-1.02,1.52-1.4,1.59-1.42-.06.02-1.26.37-1.95-.29-.45-.43-.45-1.07-.44-1.48,0-.69.24-.8.33-1.48.02-.19.21-1.59-.55-2.22-.4-.33-.67-.13-2.16-.37-1.13-.18-1.73-.29-2.16-.74-.46-.48-.58-1.15-.49-1.53Z"/>
</g>
<g id="brainwave">
<path class="cls-56" d="m448.45,310c-.41,0-.73-.39-.99-5.39-.16-3.07-.25-7.11-.34-11.02-.12-5.32-.26-11.27-.56-12.87-.58,2.23-1.09,13.41-1.28,20.5,0,.09-.05.18-.14.22-.08.04-.18.04-.26,0-.19-.12-1.91-1.21-2.31-1.85-.18-.29-.31-.77-.45-1.29-.19-.7-.47-1.75-.82-1.72-.24.02-.4.82-.5,1.35-.17.88-.34,1.7-.95,1.78-2.89.34-6.28.17-9.27.02l-.32-.02c-.54-.03-1.19-.41-1.87-.81-.64-.38-1.31-.77-1.75-.76-.4.01-1.03.42-1.59.77-.56.36-1.1.71-1.55.79-.42.07-1.02-.04-1.67-.15-.86-.16-1.92-.35-2.15.03-.23.39-.39,2.68-.53,4.69-.32,4.59-.48,5.74-1.06,5.74-.3,0-.35-.29-.42-1.07-.05-.51-.1-1.26-.14-2.28-.09-1.91-.17-4.57-.26-7.38-.12-3.99-.26-8.51-.45-12.08-.23-4.15-.47-5.66-.62-6.19-.26,1.17-.31,5.31-.36,8.72-.1,7.21-.21,11.63-.98,12.16-.1.07-.22.09-.34.06-.28-.08-.44-.44-.65-.9-.1-.23-.24-.54-.33-.62-.1-.08-.31-.18-.52-.27-.35-.16-.72-.32-.89-.56-.23-.31-.38-.84-.55-1.4-.21-.71-.5-1.67-.86-1.68h0c-.32,0-.59.86-.79,1.48-.22.7-.43,1.36-.81,1.65-1.16.89-5.29.14-5.76.05-.14-.03-.23-.16-.21-.3.03-.14.16-.23.3-.21,1.21.23,4.52.68,5.35.05.25-.19.45-.83.63-1.4.29-.91.59-1.85,1.3-1.84.75.01,1.05,1.05,1.35,2.05.15.49.3,1,.47,1.24.1.13.42.28.69.4.24.11.48.21.63.34.19.15.33.47.48.81.07.17.19.42.27.55.12-.22.36-1.01.51-3.88.12-2.23.16-5.06.19-7.8.11-8.14.23-9.46.86-9.46.33,0,.55.31.76,1.98.14,1.04.26,2.51.37,4.5.21,3.64.35,8.37.48,12.53.12,3.98.25,8.07.4,9.67.2-1.04.34-3.17.45-4.7.19-2.75.33-4.45.6-4.92.41-.69,1.56-.48,2.68-.28.57.1,1.16.21,1.49.15.35-.06.87-.39,1.36-.71.64-.41,1.31-.84,1.86-.86.58-.02,1.28.4,2.02.83.6.35,1.22.72,1.63.74l.32.02c2.97.15,6.33.32,9.18-.02.24-.03.4-.83.51-1.36.18-.88.34-1.71.97-1.77.78-.07,1.08,1.03,1.37,2.1.12.46.25.93.39,1.15.22.36,1.14,1.03,1.76,1.44.04-1.4.18-5.76.4-10.08.16-3.06.32-5.5.49-7.25.32-3.27.58-3.52.92-3.52.31,0,.44.32.56,1.35.08.68.15,1.67.21,3.02.12,2.5.2,5.81.28,9.32.14,6.15.34,14.46.84,15.8.15-.46.14-1.9.12-3.08-.03-2.64-.07-5.92,1.09-7.04.54-.52,1.62-.35,2.67-.19.58.09,1.12.17,1.46.12.28-.04.68-.35,1.07-.65.5-.38.98-.74,1.42-.77.54-.04,1.19.41,1.81.84.37.26.72.5.97.58.75.25,3.13.08,3.98-.01.14-.01.27.09.28.23.01.14-.09.27-.23.28-.13.01-3.19.33-4.2-.01-.32-.11-.7-.37-1.1-.65-.5-.35-1.11-.78-1.48-.75-.29.02-.75.37-1.15.67-.46.35-.9.68-1.3.74-.42.07-1-.02-1.62-.12-.84-.13-1.88-.29-2.23.05-.99.96-.96,4.25-.93,6.66.02,2.1.02,3.21-.34,3.58-.09.09-.2.14-.32.14Z"/>
</g>
<g id="brainwave-2" data-name="brainwave">
<path class="cls-56" d="m508.15,310c-.41,0-.73-.39-.99-5.39-.16-3.07-.25-7.11-.34-11.02-.12-5.32-.26-11.27-.56-12.87-.58,2.23-1.09,13.41-1.28,20.5,0,.09-.05.18-.14.22-.08.04-.18.04-.26,0-.19-.12-1.91-1.21-2.31-1.85-.18-.29-.31-.77-.45-1.29-.19-.7-.47-1.75-.82-1.72-.24.02-.4.82-.5,1.35-.17.88-.34,1.7-.95,1.78-2.89.34-6.28.17-9.27.02l-.32-.02c-.54-.03-1.19-.41-1.87-.81-.64-.38-1.31-.77-1.75-.76-.4.01-1.03.42-1.59.77-.56.36-1.1.71-1.55.79-.42.07-1.02-.04-1.67-.15-.86-.16-1.92-.35-2.15.03-.23.39-.39,2.68-.53,4.69-.32,4.59-.48,5.74-1.06,5.74-.3,0-.35-.29-.42-1.07-.05-.51-.1-1.26-.14-2.28-.09-1.91-.17-4.57-.26-7.38-.12-3.99-.26-8.51-.45-12.08-.23-4.15-.47-5.66-.62-6.19-.26,1.17-.31,5.31-.36,8.72-.1,7.21-.21,11.63-.98,12.16-.1.07-.22.09-.34.06-.28-.08-.44-.44-.65-.9-.1-.23-.24-.54-.33-.62-.1-.08-.31-.18-.52-.27-.35-.16-.72-.32-.89-.56-.23-.31-.38-.84-.55-1.4-.21-.71-.5-1.67-.86-1.68h0c-.32,0-.59.86-.79,1.48-.22.7-.43,1.36-.81,1.65-1.16.89-5.29.14-5.76.05-.14-.03-.23-.16-.21-.3.03-.14.16-.23.3-.21,1.21.23,4.52.68,5.35.05.25-.19.45-.83.63-1.4.29-.91.59-1.85,1.3-1.84.75.01,1.05,1.05,1.35,2.05.15.49.3,1,.47,1.24.1.13.42.28.69.4.24.11.48.21.63.34.19.15.33.47.48.81.07.17.19.42.27.55.12-.22.36-1.01.51-3.88.12-2.23.16-5.06.19-7.8.11-8.14.23-9.46.86-9.46.33,0,.55.31.76,1.98.14,1.04.26,2.51.37,4.5.21,3.64.35,8.37.48,12.53.12,3.98.25,8.07.4,9.67.2-1.04.34-3.17.45-4.7.19-2.75.33-4.45.6-4.92.41-.69,1.56-.48,2.68-.28.57.1,1.16.21,1.49.15.35-.06.87-.39,1.36-.71.64-.41,1.31-.84,1.86-.86.59-.02,1.28.4,2.02.83.6.35,1.22.72,1.63.74l.32.02c2.97.15,6.33.32,9.18-.02.24-.03.4-.83.51-1.36.18-.88.34-1.71.97-1.77.78-.07,1.08,1.03,1.37,2.1.12.46.25.93.39,1.15.22.36,1.14,1.03,1.76,1.44.04-1.4.18-5.76.4-10.08.16-3.06.32-5.5.49-7.25.32-3.27.58-3.52.92-3.52.31,0,.44.32.56,1.35.08.68.15,1.67.21,3.02.12,2.5.2,5.81.28,9.32.14,6.15.34,14.46.84,15.8.15-.46.14-1.9.12-3.08-.03-2.64-.07-5.92,1.09-7.04.54-.52,1.62-.35,2.67-.19.58.09,1.12.17,1.46.12.28-.04.68-.35,1.07-.65.5-.38.98-.74,1.42-.77.55-.04,1.19.41,1.81.84.37.26.72.5.97.58.75.25,3.13.08,3.98-.01.14-.01.27.09.28.23.01.14-.09.27-.23.28-.13.01-3.19.33-4.2-.01-.32-.11-.7-.37-1.1-.65-.5-.35-1.12-.78-1.48-.75-.29.02-.75.37-1.15.67-.46.35-.9.68-1.3.74-.42.07-1-.02-1.62-.12-.84-.13-1.88-.29-2.23.05-.99.96-.96,4.25-.93,6.66.02,2.1.02,3.21-.34,3.58-.09.09-.2.14-.32.14Z"/>
</g>
<g id="brain">
<g>
<path class="cls-60" d="m486.75,305.32c.32.51.95,1.67.79,3.14-.32,3.02-3.66,4.3-3.8,4.35-.97.35-1.15.12-3.73.21-4.31.16-5.01.86-6.1.14-1.66-1.1-1.71-3.82-1.72-4.77,0-.34.57-3.14.57-3.14,0,0,7.18-2.61,14,.07Z"/>
<path class="cls-65" d="m478.39,304.17c-.4.03-.78.06-1.15.11,2.18,1.44,4.1,3.19,5.71,5.22.7.87,1.33,1.79,1.91,2.75.2-.12.4-.26.62-.42-.58-.97-1.23-1.91-1.94-2.79-1.48-1.85-3.2-3.48-5.14-4.86Z"/>
<path class="cls-65" d="m484.81,308.17c.65.81,1.25,1.67,1.79,2.56.17-.21.32-.44.45-.69-.51-.81-1.06-1.59-1.66-2.33-1.02-1.28-2.15-2.45-3.4-3.5-.43-.04-.86-.07-1.27-.08,1.52,1.19,2.89,2.54,4.09,4.05Z"/>
<path class="cls-65" d="m478.7,308.11c-1.06-1.13-2.05-2.35-2.97-3.61-.28.05-.55.1-.8.16.98,1.39,2.06,2.72,3.22,3.96,1.5,1.6,3.14,3.06,4.9,4.36.21-.03.42-.08.68-.18.02,0,.1-.04.21-.09-1.9-1.36-3.66-2.9-5.25-4.6Z"/>
<path class="cls-65" d="m475.95,308.53c-1-1.07-1.95-2.21-2.82-3.41-.25.08-.38.13-.38.13,0,0-.04.19-.1.48.85,1.16,1.77,2.27,2.75,3.31,1.35,1.45,2.83,2.78,4.4,3.99.06,0,.13,0,.19,0,.38-.01.72-.02,1-.02-1.82-1.32-3.52-2.82-5.06-4.46Z"/>
<path class="cls-65" d="m474.34,310.32c-.74-.76-1.44-1.57-2.1-2.4-.04.23-.06.4-.06.46,0,.17,0,.4.02.66.51.61,1.05,1.21,1.6,1.78.84.88,1.74,1.71,2.68,2.49.3-.04.63-.08,1.02-.13-1.12-.89-2.17-1.85-3.16-2.88Z"/>
</g>
<g>
<path class="cls-18" d="m468.3,306.52c-.38,1.69-.09,2.8.22,3.49.13.28.59.88,1.51,2.07,1.67,2.16,1.77,2.16,2.01,2.71.41.93.35,1.39.93,1.92.15.13.81.74,1.58.57.8-.17,1.15-1.04,1.22-1.21.3-.79.06-1.51-.65-3.35-1.08-2.8-1.14-2.71-1.22-3.14-.2-1.05-.05-2.64,1.72-4.92-2.44.62-4.88,1.24-7.32,1.85Z"/>
<path class="cls-16" d="m474.83,315.8c-.97.06-2.32-2.37-2.65-3.62-.29-1.08-.96-3.81-.4-6.54-1.16.29-2.32.59-3.47.88-.38,1.69-.09,2.8.22,3.49.13.28.59.88,1.51,2.07,1.67,2.16,1.77,2.16,2.01,2.71.41.93.35,1.39.93,1.92.15.13.81.74,1.58.57.8-.17,1.15-1.04,1.22-1.21.15-.4.17-.78.05-1.29-.25.53-.58,1-1,1.02Z"/>
</g>
<g>
<path class="cls-15" d="m492.22,301.35c-.3,2-1.9,3.01-2.12,3.14-.14.53-.47,1.48-1.29,2.36-.4.43-1.76,1.89-3.62,1.65-1.35-.17-2.16-1.09-2.25-1.2-.02-.03-.04-.05-.06-.08-.02-.02-.03-.04-.05-.06-.02-.03-.04-.06-.07-.09-.01-.02-.03-.04-.04-.06-.02-.02-.03-.05-.05-.07-.02-.03-.03-.05-.05-.08-.01-.02-.02-.04-.04-.06-.01-.02-.03-.05-.04-.07-.02-.03-.03-.06-.04-.09,0-.02-.02-.04-.03-.05-.1-.21-.17-.41-.22-.59,0-.02-.01-.04-.02-.06-.02-.08-.04-.15-.05-.21,0,.04,0,.08,0,.12.01.32-.04.69-.26,1-.49.68-1.53.69-2.42.66-3.17-.09-4.3-.54-6-.58-1.17-.03-.91.18-5,1.03-.07.02-.14.03-.21.04-.02,0-.04,0-.05.01-.09.02-.17.04-.26.05-.09.02-.17.04-.26.05-.08.02-.16.03-.24.05-.17.03-.33.07-.48.1-.04,0-.08.02-.11.02-.23.05-.46.09-.67.14-.06.01-.11.02-.17.03-.05.01-.11.02-.16.03,0,0-.01,0-.02,0-.05,0-.09.02-.14.03-.05.01-.1.02-.15.03-.04,0-.08.01-.11.02,0,0-.02,0-.03,0-.09.02-.18.03-.27.05-.12.02-.23.04-.35.06-.08.01-.17.03-.25.04-.02,0-.03,0-.05,0-.13.02-.25.04-.37.06-.09.01-.18.02-.26.03,0,0,0,0,0,0-.03,0-.05,0-.08.01-.05,0-.09.01-.14.02-.02,0-.03,0-.05,0-.59.06-1.05.07-1.45,0-.65-.1-4.06-.68-5.96-3.73-.03-.05-.06-.1-.09-.15-.03-.05-.06-.1-.09-.15-.1-.19-.2-.37-.28-.56-.02-.04-.04-.09-.06-.13-.12-.28-.22-.56-.31-.84-.01-.04-.02-.08-.04-.12,0-.03-.02-.06-.03-.09-.02-.06-.03-.12-.05-.17-.01-.06-.03-.11-.04-.17-.01-.06-.03-.12-.04-.17-.01-.08-.03-.15-.04-.22,0-.03-.01-.06-.02-.1-.04-.26-.07-.51-.08-.74,0-.03,0-.07,0-.1-.02-.3-.02-.55,0-.75h0s-.04,0-.05,0c-.27.04-.58.07-.92.1-.11,0-.22.01-.34.02-.08,0-.16,0-.24,0-.04,0-.08,0-.12,0-.12,0-.25,0-.38,0-.05,0-.1,0-.15,0-.07,0-.15,0-.22,0-.07,0-.14,0-.21-.01-.04,0-.09,0-.13,0-.01,0-.02,0-.04,0-.04,0-.09,0-.13,0-.17-.01-.34-.03-.52-.05-1.64-.2-4.02-.48-5.8-2.32-.02-.02-.05-.05-.07-.08-.42-.45-1.71-1.83-1.75-3.97,0-.03,0-.06,0-.09,0-.03,0-.07,0-.1t0,0c0-.07,0-.13,0-.2,0-.04,0-.07,0-.11,0-.03,0-.06,0-.09,0-.04,0-.07.01-.11,0-.03,0-.06.01-.09.02-.12.03-.24.06-.35,0-.02,0-.04.01-.06.06-.27.13-.53.22-.76,0-.02.02-.05.03-.07,0,0,0,0,0,0,.01-.03.02-.05.03-.08.01-.03.02-.06.04-.09,0-.02.02-.04.03-.07.03-.08.07-.15.1-.22.01-.02.02-.05.04-.07.02-.05.05-.09.07-.14.01-.02.02-.04.04-.07.01-.02.02-.04.04-.07,0,0,0,0,0,0,.02-.03.04-.06.05-.09,0-.02.02-.03.03-.05.02-.03.04-.07.06-.1.03-.04.05-.08.08-.12.01-.02.02-.04.03-.05.04-.05.07-.11.11-.16.03-.05.06-.09.1-.13,0-.01.02-.02.03-.03.02-.02.03-.04.05-.07,0,0,0,0,0,0,0-.01.02-.02.02-.03.18-.22.33-.38.41-.46-.02-.08-.04-.2-.07-.35,0-.02,0-.04,0-.07,0-.01,0-.03,0-.04,0-.07-.02-.14-.02-.22,0-.03,0-.05,0-.08,0-.07,0-.13,0-.21,0-.03,0-.06,0-.09,0-.13,0-.28.01-.43,0-.09.02-.18.03-.27,0-.02,0-.05,0-.07,0-.05.01-.1.02-.14.01-.07.03-.15.04-.22,0-.02.01-.05.02-.07.01-.06.03-.13.05-.19.02-.06.04-.13.06-.19,0-.03.02-.05.03-.08.02-.05.04-.1.06-.16.03-.08.06-.16.1-.24.02-.05.05-.11.07-.16.03-.05.05-.11.08-.16.65-1.21,1.63-1.81,2.04-2.03.14-.6.49-1.69,1.42-2.69,1.82-1.95,4.36-1.91,4.79-1.9.48-.47,1.47-1.33,3-1.82,1.46-.47,2.72-.38,3.37-.29.57-.43,1.86-1.28,3.75-1.53.37-.05.72-.07,1.05-.07.37,0,.72.03,1.05.07.04,0,.08.01.13.02.01,0,.02,0,.04,0,.04,0,.07.01.11.02,0,0,.02,0,.03,0,.25.04.48.1.7.15.42.11.76.24.99.33.45-.13,1.38-.34,2.5-.08,1.52.34,2.42,1.31,2.71,1.65.14-.07.35-.18.63-.28.3-.11.68-.2,1.11-.23h0c.2-.01.41-.01.63,0,1.73.16,2.73,1.38,2.92,1.61.37-.06,2.37-.37,4.25.95,1.91,1.34,2.27,3.36,2.33,3.72.36.02,1.31.14,2.12.87,1.45,1.29,1.11,3.3,1.08,3.43.16.05,1.41.44,1.92,1.74.59,1.49-.36,2.78-.42,2.85.24.11,1.19.58,1.62,1.65.43,1.05.21,2.29-.54,3.23.11.16.4.59.59,1.23,0,.02.01.05.02.07,0,.02.01.05.02.07,0,0,0,0,0,0,0,.02.01.04.02.06.02.08.04.16.06.24,0,.03.01.05.02.08,0,.02,0,.05.01.07,0,.03.01.06.01.09,0,.03,0,.07.01.1,0,.02,0,.04,0,.06,0,.07.01.15.02.23,0,.02,0,.05,0,.07,0,.02,0,.04,0,.05,0,.23,0,.47-.04.72Z"/>
<path class="cls-59" d="m492.27,300.63s0-.04,0-.05c0-.02,0-.05,0-.07,0-.08-.01-.15-.02-.23,0-.02,0-.04,0-.06,0-.03,0-.07-.01-.1,0-.03,0-.06-.01-.09,0-.02,0-.05-.01-.07,0-.03-.01-.05-.02-.08-.02-.08-.04-.16-.06-.24,0-.02-.01-.04-.02-.06,0,0,0,0,0,0,0-.02-.01-.05-.02-.07,0-.02-.01-.05-.02-.07-1.06,1.69-2.72,2.91-4.64,3.32-3.43.73-6.09-1.46-6.42-1.74-.28.87-.8,2-1.83,2.4-1.36.53-2.59-.63-4.17-1.24-4.67-1.82-8.53,2.63-11.16,1.08-2.47-1.45-2.42-4.2-2.13-5.79.12-.66.29-1.13.33-1.2-.13.17-.32.39-.52.61,0,.01-.02.02-.03.03-.03.04-.06.07-.1.11-.02.03-.05.05-.07.08-.02.03-.05.05-.07.08-.03.03-.06.07-.1.1-.92,1.66-1.36,3.52-1.11,5.1.49,3.03,2.42,5.57,5.53,6.19.05,0,.1-.02.15-.03.05,0,.09-.02.14-.03,0,0,.01,0,.02,0,.05-.01.11-.02.16-.03.05-.01.11-.02.17-.03.21-.04.44-.09.67-.14.04,0,.08-.02.11-.02.16-.03.32-.07.48-.1.08-.02.16-.03.24-.05.08-.02.17-.04.26-.05.09-.02.17-.04.26-.05.02,0,.04,0,.05-.01.07-.01.14-.03.21-.04,4.09-.85,3.83-1.06,5-1.03,1.7.04,2.83.49,6,.58.89.02,1.92.02,2.42-.66.22-.31.27-.67.26-1,0-.04,0-.08,0-.12.01.07.03.14.05.21,0,.02.01.04.02.06.05.18.12.38.22.59,0,.02.02.04.03.05.01.03.03.06.04.09.01.02.03.05.04.07.01.02.02.04.04.06.02.03.03.05.05.08.01.02.03.05.05.07.01.02.03.04.04.06.02.03.04.06.07.09.02.02.03.04.05.06.02.03.04.05.06.08.09.11.9,1.03,2.25,1.2,1.87.23,3.23-1.23,3.62-1.65.82-.88,1.15-1.83,1.29-2.36.23-.14,1.83-1.14,2.12-3.14.04-.25.05-.49.04-.72Zm-10.08,5.1c-.03-.13-.04-.25-.05-.33,0,.02,0,.05.01.08,0,.03.01.07.02.11,0,.02,0,.04,0,.06,0,0,0,0,0,0,0,.02,0,.05,0,.07,0,0,0,0,0,.01t0,0Z"/>
<path class="cls-61" d="m465.59,308.56s-.08.01-.11.02c0,0-.02,0-.03,0-.09.02-.18.03-.27.05-.12.02-.23.04-.35.06-.08.01-.17.03-.25.04-.01,0-.03,0-.05,0-.13.02-.25.04-.37.06-.09.01-.18.02-.26.03,0,0,0,0,0,0-.03,0-.05,0-.08.01-.05,0-.09.01-.14.02-.02,0-.03,0-.05,0-.59.06-1.05.07-1.45,0-.65-.1-4.06-.68-5.96-3.73-.03-.05-.06-.1-.09-.15-.03-.05-.06-.1-.09-.15-.1-.19-.2-.37-.28-.56-.02-.04-.04-.09-.06-.13-.12-.28-.22-.56-.31-.84-.01-.04-.02-.08-.04-.12,0-.03-.02-.06-.03-.09-.02-.06-.03-.12-.05-.17-.01-.06-.03-.11-.04-.17-.01-.06-.03-.12-.04-.17-.01-.08-.03-.15-.04-.22,0-.03-.01-.06-.02-.1-.04-.26-.07-.51-.08-.74,0-.03,0-.07,0-.1-.02-.3-.02-.55,0-.75.57-.16,1.17-.35,1.79-.58,1.59-.58,2.83-1.46,3.75-2.29.2-.18.39-.37.56-.54-.92,1.66-1.36,3.52-1.11,5.1.49,3.03,2.42,5.57,5.53,6.19Z"/>
<path class="cls-21" d="m466.92,276.59c-1.15.23-2.42.71-3.23,1.81-.26.35-.41.67-.5.91-.73-.11-2.15-.23-3.79.29-1.4.44-2.4,1.17-3.02,1.73,0,0-.02.02-.03.02-.18.17-.33.31-.45.44-.41.04-1.95.26-3.21,1.57-1.33,1.39-1.41,3.05-1.42,3.43-.21.13-3.43,2.19-3.29,5.29.04.88.34,1.63.78,2.28.88,1.3,2.35,2.16,3.48,2.68.73.33,1.32.52,1.53.58.16.05.32.09.48.13.46.11.91.18,1.34.22.06,0,.12,0,.18.01,2.36.15,4.35-.65,5.43-1.21.14-.07.27-.14.38-.2.17-.1.31-.18.39-.23-.13.16-.27.34-.44.53,0,.01-.02.02-.03.03-.03.04-.06.07-.1.11-.02.03-.05.05-.07.08-.02.03-.05.05-.07.08-.03.03-.06.07-.1.1-.06.06-.12.12-.18.19-.03.03-.06.05-.08.08-.07.07-.14.14-.22.2-.02.01-.03.03-.05.04,0,0,0,0,0,0,0,0-.01.01-.02.02h0s-.06.05-.09.08c-.03.03-.06.05-.09.08-.03.03-.06.05-.09.08-.06.05-.12.11-.19.16-.03.03-.06.05-.1.08-.03.03-.07.05-.1.08-.1.08-.2.16-.31.23-.03.02-.07.05-.1.07-.04.03-.08.05-.11.08-.03.02-.06.04-.09.06-.02.01-.04.03-.06.04-.03.02-.05.03-.08.05-.08.05-.15.1-.23.15-.03.02-.06.04-.09.06-.01,0-.02.01-.03.02-.04.02-.07.04-.11.07-.04.02-.08.05-.12.07-.12.07-.25.14-.38.21-.03.02-.07.04-.1.05-.04.02-.08.04-.11.06-.03.02-.06.03-.09.05,0,0-.02,0-.03.01,0,0-.01,0-.02,0-.04.02-.09.04-.13.06,0,0,0,0,0,0-.06.03-.11.05-.17.08,0,0-.01,0-.02,0-.05.02-.1.05-.16.07-.04.02-.08.04-.13.05-.03.01-.05.02-.08.03,0,0-.01,0-.02,0-.02,0-.04.02-.05.02,0,0,0,0,0,0-.04.01-.07.03-.11.04-.05.02-.1.04-.15.06-.62.23-1.22.42-1.79.58h0s-.04,0-.05,0c-.27.04-.58.07-.92.1-.11,0-.22.01-.34.02-.08,0-.16,0-.24,0-.04,0-.08,0-.12,0-.12,0-.25,0-.38,0-.05,0-.1,0-.15,0-.07,0-.15,0-.22,0-.07,0-.14,0-.21-.01-.04,0-.09,0-.13,0-.01,0-.02,0-.04,0-.04,0-.09,0-.13,0-.17-.01-.34-.03-.52-.05-1.64-.2-4.02-.48-5.8-2.32-.02-.02-.05-.05-.07-.08-.42-.45-1.71-1.83-1.75-3.97,0-.03,0-.06,0-.09,0-.03,0-.07,0-.1t0,0c0-.07,0-.13,0-.2,0-.04,0-.07,0-.11,0-.03,0-.06,0-.09,0-.04,0-.07.01-.11,0-.03,0-.06.01-.09.02-.12.03-.24.06-.35,0-.02,0-.04.01-.06.06-.27.13-.53.22-.76,0-.02.02-.05.03-.07,0,0,0,0,0,0,.01-.03.02-.05.03-.08.01-.03.02-.06.04-.09,0-.02.02-.04.03-.07.03-.08.07-.15.1-.22.01-.02.02-.05.04-.07.02-.05.05-.09.07-.14.01-.02.02-.04.04-.07.01-.02.02-.04.04-.07,0,0,0,0,0,0,.02-.03.04-.06.05-.09,0-.02.02-.03.03-.05.02-.03.04-.07.06-.1.03-.04.05-.08.08-.12.01-.02.02-.04.03-.05.04-.05.07-.11.11-.16.03-.05.06-.09.1-.13,0-.01.02-.02.03-.03.02-.02.03-.04.05-.07,0,0,0,0,0,0,0-.01.02-.02.02-.03.18-.22.33-.38.41-.46-.02-.08-.04-.2-.07-.35,0-.02,0-.04,0-.07,0-.01,0-.03,0-.04,0-.07-.02-.14-.02-.22,0-.03,0-.05,0-.08,0-.07,0-.13,0-.21,0-.03,0-.06,0-.09,0-.13,0-.28.01-.43,0-.09.02-.18.03-.27,0-.02,0-.05,0-.07,0-.05.01-.1.02-.14.01-.07.03-.15.04-.22,0-.02.01-.05.02-.07.01-.06.03-.13.05-.19.02-.06.04-.13.06-.19,0-.03.02-.05.03-.08.02-.05.04-.1.06-.16.03-.08.06-.16.1-.24.02-.05.05-.11.07-.16.03-.05.05-.11.08-.16.65-1.21,1.63-1.81,2.04-2.03.14-.6.49-1.69,1.42-2.69,1.82-1.95,4.36-1.91,4.79-1.9.48-.47,1.47-1.33,3-1.82,1.46-.47,2.72-.38,3.37-.29.57-.43,1.86-1.28,3.75-1.53.37-.05.72-.07,1.05-.07.37,0,.72.03,1.05.07.04,0,.08.01.13.02.01,0,.02,0,.04,0,.04,0,.07.01.11.02,0,0,.02,0,.03,0Z"/>
</g>
<g>
<path class="cls-20" d="m476.37,291.34c-.08,0-.17-.03-.24-.08-.19-.14-.83-.68-.91-1.61-.1-1.12.71-1.83.81-1.91.17-.14.42-.12.56.05.14.17.12.42-.05.56-.02.02-.59.5-.53,1.23.05.61.5.97.59,1.04.18.13.21.38.08.55-.08.1-.2.16-.32.16Z"/>
<path class="cls-20" d="m453.83,296.43c-.99,0-1.94-.25-2.75-.72-1-.58-1.68-1.45-1.93-2.44-.43-1.69.58-3.15.9-3.56.13-.17.39-.2.56-.07.17.13.21.38.07.56-.26.34-1.1,1.55-.76,2.89.37,1.47,2.18,2.82,4.56,2.52.22-.03.42.13.45.34.03.22-.13.42-.35.44-.25.03-.5.05-.75.05Z"/>
<path class="cls-20" d="m468.62,284.64c-.2,0-.37-.15-.4-.35-.02-.22.13-.41.35-.44,1.27-.14,2.48-.52,3.61-1.11,1.24-.66,2.35-1.59,3.2-2.7.13-.17.38-.21.56-.07.17.13.21.38.07.56-.93,1.2-2.12,2.21-3.46,2.92-1.21.64-2.52,1.05-3.89,1.2-.02,0-.03,0-.05,0Z"/>
<path class="cls-20" d="m462.57,294.39c-.09,0-.18-.02-.26-.08-.17-.14-.2-.38-.07-.56.5-.63,1.1-1.18,1.77-1.61.92-.6,1.99-.99,3.1-1.13.22-.03.42.12.45.34.03.22-.13.42-.34.44-.99.13-1.94.48-2.77,1.01-.6.39-1.13.87-1.58,1.44-.08.1-.19.15-.3.15Z"/>
<path class="cls-20" d="m483.87,298.13c-.16,0-.31-.09-.37-.25-.26-.63-.91-1.82-2.25-2.62-.97-.58-1.93-.74-2.56-.77-.22-.01-.39-.2-.38-.42.01-.22.2-.39.42-.38,1.04.05,2.06.36,2.94.88,1.54.92,2.28,2.28,2.58,3,.08.2-.01.43-.22.52-.05.02-.1.03-.15.03Z"/>
<path class="cls-20" d="m477.2,301.6c-.08,0-.15-.02-.22-.06-.18-.12-.24-.37-.12-.55,1.14-1.73,1.35-3.24.51-3.85-.54-.4-1.96.25-3.11,1.82-.13.18-.38.21-.56.09-.18-.13-.22-.38-.09-.55,1.38-1.88,3.2-2.73,4.22-1.99,1.22.89,1.1,2.77-.32,4.92-.08.12-.2.18-.33.18Z"/>
<path class="cls-20" d="m484.87,292.4c-.66,0-1.23-.35-1.69-1.03-.42-.61-.78-1.52-1.16-2.92-.06-.21.07-.43.28-.49.21-.06.43.07.49.28.66,2.39,1.26,3.37,2.1,3.37.07,0,.13,0,.2-.02.8-.14,1.01-1.12.75-3.62-.02-.22.14-.41.36-.43.22-.02.42.14.44.35.1,1.02.18,2.07.02,2.88-.18.93-.66,1.47-1.43,1.6-.12.02-.23.03-.35.03Z"/>
<path class="cls-20" d="m457.87,283.24s0,0,0,0c-.22,0-.4-.18-.4-.4,0-.45.11-1.12.58-1.73.66-.84,1.79-1.25,2.96-1.06.22.04.37.24.33.46-.04.22-.24.36-.46.33-.88-.14-1.72.15-2.2.76-.34.43-.41.92-.42,1.25,0,.22-.18.39-.4.39Z"/>
<path class="cls-20" d="m472.73,279.32c-.09,0-.17-.03-.24-.08-.43-.33-1.13-.75-2.09-.89-.65-.1-1.34-.05-1.97.14-.21.06-.43-.06-.5-.27-.06-.21.06-.43.27-.49.75-.22,1.55-.28,2.32-.16,1.12.17,1.96.67,2.46,1.05.17.13.21.38.07.56-.08.1-.2.15-.32.15Z"/>
<path class="cls-20" d="m463.1,283.27c-.07,0-.14-.02-.2-.06-.19-.11-.25-.35-.14-.54.03-.05.69-1.13,1.86-1.6,1.4-.56,2.6-.01,2.65,0,.2.09.28.33.19.53-.09.2-.33.28-.53.19-.04-.02-.94-.42-2.01,0-.91.37-1.46,1.26-1.47,1.27-.07.12-.21.19-.34.19Z"/>
<path class="cls-20" d="m462.86,289.73c-.82,0-1.61-.35-2.2-.98-.15-.16-.14-.41.02-.56.16-.15.41-.14.56.02.45.49,1.08.75,1.71.72.47-.02.89-.21,1.12-.51.37-.48.34-1.47-.35-2.22-.15-.16-.14-.41.03-.56.16-.15.42-.14.56.03.89.97,1.06,2.36.4,3.24-.37.49-1,.78-1.71.82-.05,0-.09,0-.14,0Z"/>
</g>
<g>
<path class="cls-48" d="m469.63,292.23c-1.09.15-4.82.89-7.24,4.25l-.03.05c-.15.21-.38.53-.63.94-.69,1.12-1.52,2.9-1.26,4.86.23,1.78,1.35,3.5,3.15,4.85.68.51,1.45.96,2.28,1.33,0,0,0,0,0,0-.05,0-.09.02-.14.03-.05.01-.1.02-.15.03-.04,0-.08.01-.11.02,0,0-.02,0-.03,0-.09.02-.18.03-.27.05-.12.02-.23.04-.35.06-.08.01-.17.03-.25.04h0c-2.72-1.5-4.58-3.77-4.92-6.32-.24-1.79.32-3.41.94-4.61.2-.4.42-.75.61-1.04.2-.3.37-.54.49-.71l.03-.05c1.16-1.61,2.72-2.85,4.63-3.68,1.01-.44,2.13-.76,3.15-.9.22-.03.42.12.45.34.03.22-.12.42-.34.45Z"/>
<path class="cls-48" d="m475.55,278.14c-.83,1.33-1.83,2.38-3.01,3.12-1.52.96-3.12,1.31-4.67,1.65-1.99.44-3.71.82-4.84,2.4-.26.37-.48.77-.64,1.21-.06.16-.21.26-.38.26-.05,0-.09,0-.14-.02-.21-.07-.31-.3-.24-.51.18-.5.43-.97.74-1.4,1.32-1.83,3.26-2.26,5.32-2.72,1.48-.33,3.01-.66,4.41-1.55.88-.55,1.66-1.29,2.33-2.22.3-.11.68-.2,1.11-.23Z"/>
<path class="cls-48" d="m463.02,288.32c-.14,0-.28-.08-.35-.21-.2-.37-.57-.89-1.22-1.27-.66-.38-1.3-.45-1.72-.44-.22,0-.4-.17-.41-.39,0-.22.17-.4.39-.41.53-.01,1.33.07,2.15.55.82.48,1.28,1.12,1.53,1.58.1.19.03.43-.17.54-.06.03-.12.05-.19.05Z"/>
<path class="cls-48" d="m467.61,276.74c-.69.07-1.84.32-2.9,1.18-.46.38-.81.79-1.08,1.21-.15.24-.28.48-.39.71-.31.68-.42,1.29-.46,1.63-.02.2-.2.35-.4.35-.02,0-.03,0-.05,0-.22-.03-.38-.22-.35-.44.04-.37.16-1.01.47-1.74-1.76-.35-3.47.02-4.61,1.08-.22.21-.41.43-.57.66-.17.25-.31.51-.43.77-.23,0-.53,0-.87.04-.86.1-1.97.43-2.9,1.35-1.21,1.2-1.39,2.69-1.41,3.28v.22s-.2.11-.2.11c-.64.36-1.83,1.19-2.56,2.71-.22.46-.9,2.07-.5,3.63.08.31.2.61.35.89.64,1.19,1.9,2.14,3.48,2.68.9.31,1.91.48,2.97.49.22,0,.4.18.4.4,0,.01,0,.03,0,.04-.02.2-.19.35-.4.35h0c-1.83-.01-3.54-.47-4.93-1.33-1.37-.85-2.31-2.03-2.64-3.32-.45-1.76.24-3.5.55-4.16.75-1.58,1.95-2.5,2.7-2.95.06-.78.35-2.32,1.63-3.59,1.26-1.26,2.79-1.57,3.83-1.62,0,0,0,0,.01,0,0,0,0-.01.01-.02.23-.41.54-.82.94-1.19,1.39-1.29,3.45-1.71,5.53-1.23.32-.55.77-1.1,1.37-1.6.45-.37.92-.64,1.36-.84.37,0,.72.03,1.05.07.04,0,.08.01.13.02.01,0,.02,0,.04,0,.04,0,.07.01.11.02,0,0,.02,0,.03,0,.25.04.48.1.7.15Z"/>
<path class="cls-48" d="m485.78,284.44c-.45.67-.86,1.56-1,2.67-.18,1.39.16,2.54.47,3.27.09.2,0,.43-.21.52-.05.02-.1.03-.16.03-.15,0-.3-.09-.37-.24-.35-.81-.73-2.11-.53-3.68.19-1.52.85-2.68,1.46-3.47l.33.9Z"/>
<path class="cls-48" d="m448.07,288.47c-.22.48-.53.89-.9,1.24-.6.55-1.28.84-1.88.98.18-.22.33-.38.41-.46-.02-.08-.04-.2-.07-.35,0-.02,0-.04,0-.07,0-.01,0-.03,0-.04.34-.13.69-.33,1.01-.63.3-.28.54-.61.72-.99.09-.2.33-.28.53-.19.2.09.29.33.19.53Z"/>
<path class="cls-48" d="m468.51,304.69s-.09,0-.14-.03c-.21-.08-.31-.31-.23-.51.45-1.18,1.12-2,1.99-2.43.68-.34,1.28-.35,1.76-.36.1,0,.19,0,.28,0,1.36-.08,2.78-1.07,4.21-2.94.13-.17.38-.21.56-.08.18.13.21.38.08.56-1.58,2.07-3.2,3.16-4.8,3.25-.1,0-.2,0-.31,0-.42,0-.9.02-1.41.28-.69.34-1.23,1.02-1.6,2.01-.06.16-.21.26-.37.26Z"/>
<path class="cls-48" d="m473.71,301.19c-.23,0-.47-.03-.73-.1-.38-.11-.74-.31-1.04-.57-.16-.15-.18-.4-.03-.56.15-.16.4-.18.56-.03.21.19.46.33.73.4.53.15,1,.03,1.24-.06.21-.08.44.02.52.22s-.02.43-.23.51c-.22.08-.58.19-1.02.19Z"/>
<path class="cls-48" d="m473.59,295.62c-.23,0-.47-.03-.73-.1-.38-.11-.74-.31-1.04-.57-.16-.15-.18-.4-.03-.56.15-.16.4-.18.56-.03.21.19.46.33.73.4.53.15,1,.03,1.24-.06.21-.08.44.02.52.22.08.2-.02.43-.23.51-.22.08-.58.19-1.02.19Z"/>
<path class="cls-48" d="m462.63,296.01c-.11,0-.22-.05-.3-.14-.14-.17-.13-.42.04-.56.41-.35,1.53-1.16,3.12-1.07,1.29.07,2.2.7,2.62,1.06.17.14.18.39.04.56-.14.17-.4.18-.56.04-.35-.3-1.09-.81-2.14-.87-1.3-.07-2.22.59-2.55.88-.08.06-.17.1-.26.1Z"/>
<path class="cls-48" d="m485.99,303.3c-.79,0-1.58-.13-2.35-.39-.21-.07-.32-.3-.25-.5.07-.21.3-.32.51-.25.82.28,1.66.39,2.51.33,1.64-.11,2.87-.81,3.61-1.39.17-.13.42-.1.56.07.14.17.1.42-.07.56-.83.64-2.21,1.43-4.05,1.55-.16.01-.31.02-.47.02Z"/>
<path class="cls-48" d="m486.01,298.44c-.15,0-.29-.08-.36-.22-1.1-2.24-2.55-3.83-4.32-4.72-.89-.44-1.61-.6-2.37-.76-.79-.17-1.61-.34-2.58-.86-1.89-1.01-3.38-2.81-4.43-5.35-.08-.2.01-.43.22-.52.2-.08.44.01.52.22.97,2.36,2.34,4.03,4.07,4.95.87.47,1.6.62,2.37.78.78.16,1.58.33,2.56.83,1.93.97,3.51,2.68,4.68,5.08.1.2.01.43-.19.53-.06.03-.12.04-.17.04Z"/>
<path class="cls-48" d="m474.37,289.9s-.01,0-.02,0c-.22,0-.39-.19-.38-.41.01-.28.06-.56.13-.83.12-.45.33-.86.62-1.24.13-.17.38-.21.56-.08.18.13.21.38.08.56-.23.3-.39.62-.49.97-.06.21-.09.43-.1.65,0,.21-.19.38-.4.38Z"/>
<path class="cls-48" d="m482.29,293.83c-.16,0-.31-.09-.37-.25-.1-.26-.18-.53-.22-.81-.07-.46-.05-.92.06-1.38.05-.21.26-.35.48-.3.21.05.35.26.3.48-.08.36-.1.73-.05,1.09.03.22.09.43.17.63.08.2-.02.43-.22.51-.05.02-.1.03-.15.03Z"/>
<path class="cls-48" d="m467.96,301.68c-.16,0-.31-.09-.37-.25-.1-.26-.18-.53-.22-.81-.07-.46-.05-.92.06-1.38.05-.21.26-.35.48-.3.21.05.35.26.3.48-.08.36-.1.73-.05,1.09.03.22.09.43.17.63.08.2-.02.43-.22.51-.05.02-.1.03-.15.03Z"/>
<path class="cls-48" d="m474.22,291.63c-.31,0-.63-.04-.94-.12-.21-.06-.34-.27-.29-.48.06-.21.27-.34.49-.28.36.09.73.12,1.09.07.22-.03.43-.08.64-.15.21-.08.44.03.51.23.08.21-.03.43-.24.51-.26.1-.54.16-.82.2-.15.02-.3.03-.45.03Z"/>
<path class="cls-48" d="m458.7,291.29c-1.47,0-2.92-.3-4.25-.89-2.79-1.24-4.29-3.38-4.94-4.56-.11-.19-.03-.43.16-.54.19-.11.44-.03.54.16.6,1.08,1.98,3.07,4.56,4.21,1.82.8,3.53.88,4.64.79.22-.02.41.15.43.37.02.22-.15.41-.37.42-.26.02-.52.03-.78.03Z"/>
<path class="cls-48" d="m461.7,292.17s0,0,0,0c-.15,0-1.46-.04-2.17-1.18-.48-.77-.37-1.56-.3-1.87.05-.21.26-.35.48-.3.22.05.35.26.3.47-.05.21-.12.75.2,1.28.49.79,1.46.8,1.5.8.22,0,.4.18.4.4,0,.22-.18.39-.4.39Z"/>
<path class="cls-48" d="m453.45,289.28c-.17,0-.32-.11-.38-.27-.07-.21.05-.43.26-.5,1.99-.65,3.32-1.94,3.48-3.39.04-.4,0-.82-.15-1.24-.07-.21.04-.43.25-.5.21-.07.44.04.51.25.18.53.24,1.06.19,1.57-.19,1.76-1.73,3.31-4.02,4.06-.04.01-.08.02-.12.02Z"/>
<path class="cls-48" d="m461.96,296.3c-.12,0-.24-.05-.31-.15-.29-.37-.64-.67-1.04-.9-1.62-.92-3.76-.4-5.26.19-.2.08-.44-.02-.52-.22-.08-.2.02-.43.22-.51,1.67-.66,4.05-1.22,5.95-.14.48.27.91.64,1.27,1.09.14.17.11.42-.07.56-.07.06-.16.08-.25.08Z"/>
<path class="cls-48" d="m484.53,286.71c-.13,0-.26-.06-.33-.18-.01-.02-1.35-1.96-4.43-2.82-2.6-.73-5.09,0-5.12,0-.21.06-.43-.06-.5-.27-.06-.21.06-.43.27-.49.11-.03,2.74-.8,5.56,0,3.37.94,4.82,3.06,4.88,3.15.12.18.07.43-.11.55-.07.04-.14.07-.22.07Z"/>
<path class="cls-48" d="m487.63,303.12c-.08,0-.17-.03-.24-.08-.18-.13-.21-.38-.08-.55.44-.59.94-1.53.77-2.69-.09-.61-.35-1.21-.77-1.76-.13-.17-.1-.42.08-.56.18-.13.43-.1.56.08.51.66.82,1.38.92,2.13.16,1.11-.17,2.28-.92,3.28-.08.1-.2.16-.32.16Z"/>
<path class="cls-48" d="m466.12,300.19c-.18,0-.35-.12-.39-.31-.05-.21.09-.43.3-.47,2.51-.57,4.88-1.72,6.86-3.32,1.55-1.26,2.85-2.78,3.86-4.51.11-.19.35-.25.55-.14.19.11.26.35.15.54-1.06,1.82-2.42,3.41-4.04,4.73-2.07,1.68-4.55,2.88-7.18,3.48-.03,0-.06.01-.09.01Z"/>
<path class="cls-48" d="m470.52,307.92c-.16,0-.31-.09-.37-.25-.08-.2.02-.43.22-.52.84-.34,1.72-.54,2.6-.61.99-.07,1.73.05,2.52.18.15.02.3.05.46.07,1.31.2,2.69.31,4.09.32.22,0,.4.18.4.4,0,.22-.18.39-.4.39h0c-1.44,0-2.85-.12-4.21-.33-.16-.02-.32-.05-.47-.08-.77-.13-1.44-.24-2.33-.17-.8.06-1.59.25-2.36.55-.05.02-.1.03-.15.03Z"/>
<path class="cls-48" d="m455.01,300.69c-.27.04-.58.07-.92.1-.11,0-.22.01-.34.02-.08,0-.16,0-.24,0-.04,0-.08,0-.12,0-.12,0-.25,0-.38,0-.05,0-.1,0-.15,0-.07,0-.15,0-.22,0-.07,0-.14,0-.21-.01-.04,0-.09,0-.13,0-.01,0-.02,0-.04,0-.04,0-.09,0-.13,0-.17-.01-.34-.03-.52-.05-1.64-.2-4.02-.48-5.8-2.32.01-.05.03-.11.07-.16.13-.18.38-.22.56-.09.89.64,1.87,1.14,2.9,1.48,1.68.56,3.52.7,5.32.4.22-.04.42.11.46.33.02.12-.02.24-.09.32Z"/>
</g>
</g>
<g>
<circle class="cls-1" cx="450.77" cy="278.71" r="2.03"/>
<rect class="cls-1" x="444.63" y="267.03" width=".9" height="13.96" transform="translate(-47.8 447.92) rotate(-51.05)"/>
</g>
<g>
<circle class="cls-1" cx="444" cy="308.49" r="2.03" transform="translate(-87.55 209.74) rotate(-24.27)"/>
<rect class="cls-1" x="418.36" y="317.54" width="28.72" height=".9" transform="translate(-102.84 357.26) rotate(-40.5)"/>
</g>
<g>
<circle class="cls-1" cx="491.73" cy="308.34" r="2.03" transform="translate(58.7 694.81) rotate(-73.84)"/>
<rect class="cls-1" x="510.08" y="295.56" width=".9" height="39.25" transform="translate(42.44 690.51) rotate(-70.41)"/>
</g>
</g>
<g>
<g>
<g>
<path class="cls-4" d="m558.92,41.42s-.03-8.59-.03-8.59l-3.23-1.47c-7-3.18-31.95-13.5-59.34-13.5s-52.33,10.33-59.33,13.5l-3.25,1.46-.05,16.52c0,26.91,1.16,54.84,15.04,75.1,15.1,22.01,36.44,35.26,44.92,39.93l2.67,1.47,2.66-1.47c8.49-4.67,29.84-17.92,44.91-39.93,13.9-20.27,15.06-48.19,15.06-75.09l-.03-7.93Z"/>
<path class="cls-27" d="m439.26,36.38c-.01,1.91-.05,12.98-.05,12.98,0,26.01,1.08,53.01,14.08,71.94,14.63,21.36,35.72,34.2,43.01,38.24,7.29-4.03,28.38-16.88,43.01-38.24,13-18.94,14.08-45.93,14.08-71.95v-7.92s-.03-3.04-.03-5.05c-6.31-2.84-30.62-13-57.07-13s-50.76,10.16-57.05,13Z"/>
</g>
<path class="cls-28" d="m553.38,36.38c-6.31-2.84-30.62-13-57.07-13-.21,0-.42.02-.65.02v135.77c.21.11.46.25.65.37,7.29-4.03,28.38-16.88,43.01-38.24,13-18.94,14.08-45.93,14.08-71.95v-7.92s-.03-3.04-.03-5.05Z"/>
</g>
<g>
<path class="cls-62" d="m523.29,82.72c0,14.9-12.08,27-26.96,27s-26.98-12.1-26.98-27,12.07-26.97,26.98-26.97,26.96,12.1,26.96,26.97Z"/>
<polygon class="cls-27" points="512.89 78.2 500.85 78.2 500.85 66.13 491.81 66.13 491.81 78.2 479.74 78.2 479.74 87.23 491.81 87.23 491.81 99.3 500.85 99.3 500.85 87.23 512.89 87.23 512.89 78.2"/>
</g>
</g>
<g>
<path class="cls-14" d="m176.95,449.72l-8.69,20.63c-.18.42-.14.87.12,1.25.25.38.65.59,1.11.59h59.48l-11.15-19.64s-30.52-6.74-40.86-2.84Z"/>
<path class="cls-6" d="m212.52,452.94l-7.32,17.41c-.18.42-.14.87.12,1.25.25.38.65.59,1.11.59h57.2c.49,0,.9-.24,1.15-.66.24-.42.25-.9,0-1.32l-10.03-17.65s-31.88-3.52-42.23.38Z"/>
<path class="cls-24" d="m178.05,327.34h34.9c1.38,0,2.51,1.12,2.51,2.51v120.59c0,1.38-1.12,2.51-2.51,2.51h-34.9c-1.38,0-2.51-1.12-2.51-2.51v-120.59c0-1.38,1.12-2.51,2.51-2.51Z"/>
<path class="cls-11" d="m178.05,452.94h34.9c1.38,0,2.51-1.13,2.51-2.51v-58.68h-16.88v-45.67h-23.03v104.35c0,1.38,1.13,2.51,2.51,2.51Z"/>
<rect class="cls-4" x="209.6" y="327.34" width="46.65" height="125.6" rx="2.93" ry="2.93"/>
<path class="cls-9" d="m212.52,452.94h40.79c1.61,0,2.93-1.32,2.93-2.93v-58.26h-46.65v58.26c0,1.61,1.32,2.93,2.93,2.93Z"/>
<polygon class="cls-7" points="223.75 327.73 267.27 327.73 264.16 306.65 217.57 306.65 223.75 327.73"/>
<path class="cls-8" d="m227.76,327.73h.67l-.94-6.38h3.68l.94,6.38h.67l-.94-6.38h3.68l.94,6.38h.67l-.94-6.38h3.68l.94,6.38h.67l-.94-6.38h3.68l.94,6.38h.67l-.94-6.38h3.68l.94,6.38h.67l-.94-6.38h3.68l.94,6.38h.67l-.94-6.38h3.68l.94,6.38h.67l-.94-6.38h3.68l.94,6.38h.67l-.94-6.38h4.02l-.1-.66h-4.02l-.43-2.93h4.02l-.1-.66h-4.02l-.43-2.93h4.02l-.1-.66h-4.02l-.43-2.93h4.02l-.1-.66h-4.02l-.48-3.26h-.67l.48,3.26h-3.68l-.48-3.26h-.67l.48,3.26h-3.68l-.48-3.26h-.67l.48,3.26h-3.68l-.48-3.26h-.67l.48,3.26h-3.68l-.48-3.26h-.67l.48,3.26h-3.68l-.48-3.26h-.67l.48,3.26h-3.68l-.48-3.26h-.67l.48,3.26h-3.68l-.48-3.26h-.67l.48,3.26h-3.68l-.48-3.26h-.67l.48,3.26h-6.61l.19.66h6.52l.43,2.93h-6.09l.19.66h5.99l.43,2.93h-5.57l.19.66h5.47l.43,2.93h-5.04l.19.66h4.95l.94,6.38h0Zm33.78-7.05h-3.68l-.43-2.93h3.68l.43,2.93h0Zm-.53-3.59h-3.68l-.43-2.93h3.68l.43,2.93h0Zm-.53-3.59h-3.68l-.43-2.93h3.68l.43,2.93h0Zm-4.78-2.93l.43,2.93h-3.68l-.43-2.93h3.68Zm-4.35,0l.43,2.93h-3.68l-.43-2.93h3.68Zm-4.35,0l.43,2.93h-3.68l-.43-2.93h3.68Zm-4.35,0l.43,2.93h-3.68l-.43-2.93h3.68Zm-4.35,0l.43,2.93h-3.68l-.43-2.93h3.68Zm-4.35,0l.43,2.93h-3.68l-.43-2.93h3.68Zm-4.35,0l.43,2.93h-3.68l-.43-2.93h3.68Zm26.65,3.59l.43,2.93h-3.68l-.43-2.93h3.68Zm-4.35,0l.43,2.93h-3.68l-.43-2.93h3.68Zm-4.35,0l.43,2.93h-3.68l-.43-2.93h3.68Zm-4.35,0l.43,2.93h-3.68l-.43-2.93h3.68Zm-4.35,0l.43,2.93h-3.68l-.43-2.93h3.68Zm-4.35,0l.43,2.93h-3.68l-.43-2.93h3.68Zm-4.35,0l.43,2.93h-3.68l-.43-2.93h3.68Zm26.65,3.59l.43,2.93h-3.68l-.43-2.93h3.68Zm-4.35,0l.43,2.93h-3.68l-.43-2.93h3.68Zm-4.35,0l.43,2.93h-3.68l-.43-2.93h3.68Zm-4.35,0l.43,2.93h-3.68l-.43-2.93h3.68Zm-4.35,0l.43,2.93h-3.68l-.43-2.93h3.68Zm-4.35,0l.43,2.93h-3.68l-.43-2.93h3.68Zm-4.35,0l.43,2.93h-3.68l-.43-2.93h3.68Z"/>
<polygon class="cls-12" points="223.75 327.73 267.27 327.73 266.81 324.61 222.83 324.61 223.75 327.73"/>
<polygon class="cls-12" points="180.81 327.73 186.56 327.73 190.25 299.14 176.78 300.4 180.81 327.73"/>
<polygon class="cls-9" points="186.56 327.73 223.75 327.73 219.71 300.4 182.53 300.4 186.56 327.73"/>
<g>
<g>
<polygon class="cls-13" points="189.58 324.44 196.53 324.44 193.47 303.7 186.52 303.7 189.58 324.44"/>
<path class="cls-32" d="m189.58,324.77h6.94c.1,0,.19-.04.25-.11.06-.07.09-.17.08-.27l-3.06-20.74c-.02-.16-.16-.28-.33-.28h-6.94c-.1,0-.19.04-.25.11-.06.07-.09.17-.08.27l3.06,20.74c.02.16.16.28.33.28Zm6.56-.66h-6.27l-2.96-20.07h6.27l2.96,20.07Z"/>
</g>
<path class="cls-32" d="m193.06,324.77s.03,0,.05,0c.18-.03.31-.2.28-.38l-.45-3.08h3.09c.18,0,.33-.15.33-.33s-.15-.33-.33-.33h-3.19l-.41-2.79h3.09c.18,0,.33-.15.33-.33s-.15-.33-.33-.33h-3.19l-.41-2.79h3.09c.18,0,.33-.15.33-.33s-.15-.33-.33-.33h-3.19l-.41-2.79h3.09c.18,0,.33-.15.33-.33s-.15-.33-.33-.33h-3.19l-.41-2.79h3.09c.18,0,.33-.15.33-.33s-.15-.33-.33-.33h-3.19l-.47-3.17c-.03-.18-.19-.3-.38-.28-.18.03-.31.2-.28.38l.45,3.08h-3.09c-.18,0-.33.15-.33.33s.15.33.33.33h3.19l.41,2.79h-3.09c-.18,0-.33.15-.33.33s.15.33.33.33h3.19l.41,2.79h-3.09c-.18,0-.33.15-.33.33s.15.33.33.33h3.19l.41,2.79h-3.09c-.18,0-.33.15-.33.33s.15.33.33.33h3.19l.41,2.79h-3.09c-.18,0-.33.15-.33.33s.15.33.33.33h3.19l.47,3.17c.02.16.17.28.33.28Z"/>
</g>
<path class="cls-10" d="m151.14,243.34c.91,0,1.82,0,2.74,0,5.49,19.14,8.36,39.19,8.65,60.12h-2.74c-2.88-20.04-5.76-40.08-8.65-60.12Z"/>
<polygon class="cls-7" points="153.87 243.34 222.43 243.34 231.07 303.46 162.52 303.46 153.87 243.34"/>
<polygon class="cls-11" points="159.31 248.03 166.61 298.77 225.64 298.77 218.34 248.03 159.31 248.03"/>
<path class="cls-5" d="m163.61,277.93l3,20.84h19.77s-22.77-20.84-22.77-20.84h0Zm60.05,20.84l-52.8-50.74h0s6.72,0,6.72,0l47.23,44.95h0l.83,5.79h-1.98Zm-3.01-34.65l-2.31-16.09h-13.43s0,0,0,0l15.75,16.09h0Z"/>
<path class="cls-10" d="m203.58,318.41c-2.27,0-4.11-1.75-4.11-3.9s1.85-3.9,4.11-3.9,4.11,1.75,4.11,3.9-1.85,3.9-4.11,3.9Z"/>
<path class="cls-7" d="m209.69,311.19h7.27l-4.51-5.92-2.76,5.92h0Zm8.34,7.22h-7.27l4.51,5.92,2.76-5.92Z"/>
<path class="cls-12" d="m235.56,335.24c4.73,0,6.86,7.07,6.93,15.88v.84c-.07,8.81-2.2,15.88-6.93,15.88s-6.86-7.07-6.93-15.88v-.84c.07-8.81,2.2-15.88,6.93-15.88Z"/>
<path class="cls-13" d="m235.94,376.79c.1-1.46,1.36-2.57,2.82-2.47,1.46.1,2.57,1.36,2.47,2.82,0,.08-2.02,29.05,1.38,41.99,2.53,9.63,11.47,9.48,13.19,6.76.16-.22.26-.5.28-.82.23-3.18.1-6.78.16-10,7.81,5.39,6.85,17.62-4.15,17.85-6.64.14-12.56-4.65-14.61-12.44-3.63-13.8-1.55-43.61-1.55-43.69Z"/>
<path class="cls-8" d="m228.68,349.14c1.21-.88,3.56-2.14,6.68-1.75,4.68.59,7.56,2.68,7.56,11.91v17.57c0,4.73-8.69,5.95-8.69-.1s1.37-12.98-.49-15.81c-1.4-2.13-3.18-1.91-4.68-2.84-.28-1.89-.42-3.97-.44-6.16v-.84c0-.67.02-1.33.05-1.98Z"/>
<path class="cls-13" d="m242.84,356.76c.06.78.08,1.63.08,2.54v17.57c0,.93-.34,1.73-.88,2.36-2.15-.43-4.35-1.13-4.92-2.27.98,0,1.07-2.1,1.07-4.54v-13.91c0-3.06,3.01-5.17,4.65-1.76Z"/>
<path class="cls-10" d="m242.92,376.96c-.12,4.6-8.49,5.79-8.68,0h8.68Z"/>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 91 KiB

+52
View File
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="_图层_2" data-name="图层 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 454.72 126.1">
<defs>
<style>
.cls-1 {
fill: #0093dd;
}
.cls-2 {
fill: #5b5b5b;
}
</style>
</defs>
<g id="_图层_1-2" data-name="图层 1">
<g>
<path class="cls-1" d="m162.51,68.1h14.37c5.59,0,9.79,4.03,8.73,8.37l-1.38,5.61h-44.66c-2.41,0-4.3-.44-5.66-1.32-1.36-.82-1.84-2.17-1.42-4.06L148.68,6.71c.52-1.95,1.97-3.56,4.32-4.82,2.36-1.26,5.16-1.89,8.41-1.89h16.82l-15.72,68.1Z"/>
<path class="cls-1" d="m204.2,25.41c.52-1.76,1.86-3.21,4.01-4.34,2.15-1.13,4.69-1.7,7.62-1.7h15.88l-11.32,49.4c-.94,3.97-3.83,7.19-8.64,9.68-4.82,2.49-10.43,3.73-16.82,3.73h-3.61l12.89-56.77ZM219.29.38h17.6l-2.04,8.78c-.42,1.26-1.36,2.28-2.83,3.07-1.47.79-3.2,1.18-5.19,1.18h-19.02l1.89-8.12c.31-1.45,1.39-2.63,3.22-3.54,1.83-.91,3.95-1.37,6.36-1.37Z"/>
<path class="cls-1" d="m262.55,68.1h14.37c5.59,0,9.79,4.03,8.73,8.37l-1.38,5.61h-44.66c-2.41,0-4.3-.44-5.66-1.32-1.36-.82-1.84-2.17-1.42-4.06L248.72,6.71c.52-1.95,1.97-3.56,4.32-4.82,2.36-1.26,5.16-1.89,8.41-1.89h16.82l-15.72,68.1Z"/>
<path class="cls-1" d="m304.25,25.41c.52-1.76,1.86-3.21,4.01-4.34,2.15-1.13,4.69-1.7,7.62-1.7h15.88l-11.32,49.4c-.94,3.97-3.83,7.19-8.64,9.68-4.82,2.49-10.43,3.73-16.82,3.73h-3.61l12.89-56.77ZM319.33.38h17.6l-2.04,8.78c-.42,1.26-1.36,2.28-2.83,3.07-1.47.79-3.2,1.18-5.19,1.18h-19.02l1.89-8.12c.31-1.45,1.39-2.63,3.22-3.54,1.83-.91,3.95-1.37,6.36-1.37Z"/>
<g>
<path class="cls-2" d="m0,101.17h2.51v19.36H0v-19.36Z"/>
<path class="cls-2" d="m28.37,110.12v10.4h-2.4v-9.54c0-2.31-.64-3.65-2.9-3.65-1.76,0-3.26.5-3.91,2.65v10.54h-2.4v-9.54c0-2.31-.56-3.65-2.76-3.65-1.87,0-3.24.42-3.99,2.73v10.46h-2.4v-15.06h2.4v1.98c.92-1.79,2.54-2.26,4.35-2.26,2.37,0,3.74.95,4.38,2.45.89-1.95,2.84-2.45,4.69-2.45,3.51,0,4.94,2.04,4.94,4.94Z"/>
<path class="cls-2" d="m45.28,109.84v10.68h-2.04l-.36-2.29c-.86,1.65-3.12,2.57-5.38,2.57-3.6,0-5.19-1.65-5.19-4.49,0-3.57,2.37-4.8,5.97-4.8h4.6v-1.26c0-1.81-.64-3.07-3.71-3.07-1,0-2.23.11-3.32.33v-2.12c1.12-.14,2.34-.22,3.43-.22,4.74,0,6,1.95,6,4.66Zm-2.4,6.08v-2.48h-4.43c-2.48,0-3.65.5-3.65,2.85,0,1.65.81,2.51,2.93,2.51,2.51,0,4.38-1.09,5.16-2.87Z"/>
<path class="cls-2" d="m63.05,105.46v14c0,4.16-2.26,6.64-7.36,6.64-1.28,0-2.71-.17-3.65-.36v-2.04c1.14.22,2.4.33,3.68.33,3.35,0,4.94-1.37,4.94-4.83v-1.51c-.61,1.76-1.98,2.82-4.88,2.82-5.02,0-6.25-3.07-6.25-7.67,0-4.16,1.23-7.67,6.25-7.67,3.04,0,4.29,1.31,4.88,3.1v-2.82h2.4Zm-2.32,7.39c0-3.46-1-5.66-4.63-5.66s-4.02,2.73-4.02,5.66c0,3.15.47,5.66,4.02,5.66s4.63-2.06,4.63-5.66Z"/>
<path class="cls-2" d="m67.9,101.28c0-1.26.39-1.42,1.45-1.42,1,0,1.42.17,1.42,1.42s-.42,1.42-1.42,1.42c-1.06,0-1.45-.2-1.45-1.42Zm.22,4.18h2.4v15.06h-2.4v-15.06Z"/>
<path class="cls-2" d="m87.87,110.09v10.43h-2.43v-9.54c0-2.31-.47-3.65-2.87-3.65-1.9,0-3.74.36-4.57,3.01v10.18h-2.4v-15.06h2.4v2.15c.92-1.92,2.98-2.43,4.83-2.43,3.93,0,5.05,2.04,5.05,4.91Z"/>
<path class="cls-2" d="m105.5,105.46v14c0,4.16-2.26,6.64-7.36,6.64-1.28,0-2.71-.17-3.65-.36v-2.04c1.14.22,2.4.33,3.68.33,3.35,0,4.94-1.37,4.94-4.83v-1.51c-.61,1.76-1.98,2.82-4.88,2.82-5.02,0-6.25-3.07-6.25-7.67,0-4.16,1.23-7.67,6.25-7.67,3.04,0,4.29,1.31,4.88,3.1v-2.82h2.4Zm-2.32,7.39c0-3.46-1-5.66-4.63-5.66s-4.02,2.73-4.02,5.66c0,3.15.47,5.66,4.02,5.66s4.63-2.06,4.63-5.66Z"/>
<path class="cls-2" d="m129.47,103.4h-5.63v17.13h-2.51v-17.13h-5.66v-2.23h13.81v2.23Z"/>
<path class="cls-2" d="m138.31,105.18l-.08,2.18h-.33c-1.92,0-3.82.64-4.66,3.32v9.85h-2.4v-15.06h2.4v2.73c.95-2.51,2.98-3.01,4.8-3.01h.28Z"/>
<path class="cls-2" d="m141.19,101.28c0-1.26.39-1.42,1.45-1.42,1,0,1.42.17,1.42,1.42s-.42,1.42-1.42,1.42c-1.06,0-1.45-.2-1.45-1.42Zm.22,4.18h2.4v15.06h-2.4v-15.06Z"/>
<path class="cls-2" d="m160.85,109.84v10.68h-2.04l-.36-2.29c-.86,1.65-3.12,2.57-5.38,2.57-3.6,0-5.19-1.65-5.19-4.49,0-3.57,2.37-4.8,5.97-4.8h4.6v-1.26c0-1.81-.64-3.07-3.71-3.07-1,0-2.23.11-3.32.33v-2.12c1.12-.14,2.34-.22,3.43-.22,4.74,0,6,1.95,6,4.66Zm-2.4,6.08v-2.48h-4.43c-2.48,0-3.65.5-3.65,2.85,0,1.65.81,2.51,2.93,2.51,2.51,0,4.38-1.09,5.16-2.87Z"/>
<path class="cls-2" d="m165.96,117.48v-18.16h2.4v17.54c0,1.51.42,1.81,1.39,1.81.33,0,.75-.03,1.14-.14v1.98c-.45.11-.92.17-1.59.17-2.23,0-3.35-.95-3.35-3.21Z"/>
<path class="cls-2" d="m181.13,101.17h4.02l4.94,12.47h.17l4.94-12.47h3.96v19.36h-2.51v-16.82h-.17l-4.96,12.44h-2.73l-5.02-12.44h-.17v16.82h-2.45v-19.36Z"/>
<path class="cls-2" d="m216.23,109.84v10.68h-2.04l-.36-2.29c-.86,1.65-3.12,2.57-5.38,2.57-3.6,0-5.19-1.65-5.19-4.49,0-3.57,2.37-4.8,5.97-4.8h4.6v-1.26c0-1.81-.64-3.07-3.71-3.07-1,0-2.23.11-3.32.33v-2.12c1.12-.14,2.34-.22,3.43-.22,4.74,0,6,1.95,6,4.66Zm-2.4,6.08v-2.48h-4.43c-2.48,0-3.65.5-3.65,2.85,0,1.65.81,2.51,2.93,2.51,2.51,0,4.38-1.09,5.16-2.87Z"/>
<path class="cls-2" d="m233.61,110.09v10.43h-2.43v-9.54c0-2.31-.47-3.65-2.87-3.65-1.9,0-3.74.36-4.57,3.01v10.18h-2.4v-15.06h2.4v2.15c.92-1.92,2.98-2.43,4.83-2.43,3.93,0,5.05,2.04,5.05,4.91Z"/>
<path class="cls-2" d="m250.54,109.84v10.68h-2.04l-.36-2.29c-.86,1.65-3.12,2.57-5.38,2.57-3.6,0-5.19-1.65-5.19-4.49,0-3.57,2.37-4.8,5.97-4.8h4.6v-1.26c0-1.81-.64-3.07-3.71-3.07-1,0-2.23.11-3.32.33v-2.12c1.12-.14,2.34-.22,3.43-.22,4.74,0,6,1.95,6,4.66Zm-2.4,6.08v-2.48h-4.43c-2.48,0-3.65.5-3.65,2.85,0,1.65.81,2.51,2.93,2.51,2.51,0,4.38-1.09,5.16-2.87Z"/>
<path class="cls-2" d="m268.31,105.46v14c0,4.16-2.26,6.64-7.36,6.64-1.28,0-2.71-.17-3.65-.36v-2.04c1.14.22,2.4.33,3.68.33,3.35,0,4.94-1.37,4.94-4.83v-1.51c-.61,1.76-1.98,2.82-4.88,2.82-5.02,0-6.25-3.07-6.25-7.67,0-4.16,1.23-7.67,6.25-7.67,3.04,0,4.29,1.31,4.88,3.1v-2.82h2.4Zm-2.32,7.39c0-3.46-1-5.66-4.63-5.66s-4.02,2.73-4.02,5.66c0,3.15.47,5.66,4.02,5.66s4.63-2.06,4.63-5.66Z"/>
<path class="cls-2" d="m285.22,113.24l-10.21.64c.03,3.29,1.17,4.8,4.83,4.8,1.65,0,3.57-.42,4.71-.98v2.2c-.86.45-2.93.89-5.08.89-4.44,0-6.97-1.81-6.97-7.81s2.54-7.81,6.83-7.81c5.13,0,6.02,3.38,6.02,6.3,0,.42-.06,1.06-.14,1.76Zm-2.23-1.73c0-2.32-.39-4.35-3.65-4.35-3.46,0-4.24,1.87-4.32,4.94l7.98-.59Z"/>
<path class="cls-2" d="m310.27,110.12v10.4h-2.4v-9.54c0-2.31-.64-3.65-2.9-3.65-1.76,0-3.26.5-3.91,2.65v10.54h-2.4v-9.54c0-2.31-.56-3.65-2.76-3.65-1.87,0-3.24.42-3.99,2.73v10.46h-2.4v-15.06h2.4v1.98c.92-1.79,2.54-2.26,4.35-2.26,2.37,0,3.74.95,4.38,2.45.89-1.95,2.84-2.45,4.69-2.45,3.51,0,4.94,2.04,4.94,4.94Z"/>
<path class="cls-2" d="m327.03,113.24l-10.21.64c.03,3.29,1.17,4.8,4.83,4.8,1.65,0,3.57-.42,4.71-.98v2.2c-.86.45-2.93.89-5.08.89-4.44,0-6.97-1.81-6.97-7.81s2.54-7.81,6.83-7.81c5.13,0,6.03,3.38,6.03,6.3,0,.42-.06,1.06-.14,1.76Zm-2.23-1.73c0-2.32-.39-4.35-3.65-4.35-3.46,0-4.24,1.87-4.32,4.94l7.98-.59Z"/>
<path class="cls-2" d="m343.6,110.09v10.43h-2.43v-9.54c0-2.31-.47-3.65-2.87-3.65-1.9,0-3.74.36-4.57,3.01v10.18h-2.4v-15.06h2.4v2.15c.92-1.92,2.98-2.43,4.83-2.43,3.93,0,5.05,2.04,5.05,4.91Z"/>
<path class="cls-2" d="m354.9,118.52v2.04c-.59.08-1.06.14-1.7.14-3.32,0-4.52-.81-4.52-4.77v-8.45h-2.23v-2.01h2.23v-3.57h2.4v3.57h3.74v2.01h-3.74v8.31c0,2.34.33,2.9,2.18,2.9.67,0,1.12-.06,1.65-.17Z"/>
<path class="cls-2" d="m364.19,120.05v-2.32c1.14.42,3.46.86,5.75.86,2.9,0,4.41-.86,4.41-3.26s-.84-3.01-4.46-3.88c-3.96-.95-5.41-1.92-5.41-5.36s2.06-5.24,6.44-5.24c1.87,0,3.93.33,4.85.7v2.29c-1.12-.42-3.07-.78-4.83-.78-2.71,0-3.99.53-3.99,3.04,0,1.81.47,2.45,3.96,3.26,4.32,1,5.88,2.15,5.88,5.94s-2.4,5.49-6.86,5.49c-2.4,0-4.8-.42-5.75-.75Z"/>
<path class="cls-2" d="m379.71,124.04c2.62,0,3.68-1.12,4.43-3.54l-6.02-15.03h2.59l4.6,12.5h.17l4.35-12.5h2.43l-5.41,14.56c-1.42,3.77-2.71,6.08-7.14,6.08v-2.06Z"/>
<path class="cls-2" d="m394.18,120.22v-2.06c1.06.31,2.98.59,4.35.59,2.29,0,3.49-.56,3.49-2.31s-.5-2.15-3.38-2.82c-3.32-.75-4.21-1.81-4.21-4.35s1.84-4.07,5.41-4.07c1.45,0,3.07.22,3.79.5l-.17,2.04c-.86-.33-2.2-.59-3.6-.59-2.12,0-3.18.47-3.18,2.18,0,1.53.53,1.87,2.87,2.4,3.46.78,4.71,1.73,4.71,4.63s-2.04,4.35-5.72,4.35c-1.45,0-3.54-.22-4.38-.47Z"/>
<path class="cls-2" d="m414.77,118.52v2.04c-.59.08-1.06.14-1.7.14-3.32,0-4.52-.81-4.52-4.77v-8.45h-2.23v-2.01h2.23v-3.57h2.4v3.57h3.74v2.01h-3.74v8.31c0,2.34.33,2.9,2.18,2.9.67,0,1.12-.06,1.65-.17Z"/>
<path class="cls-2" d="m429.67,113.24l-10.21.64c.03,3.29,1.17,4.8,4.83,4.8,1.65,0,3.57-.42,4.71-.98v2.2c-.86.45-2.93.89-5.08.89-4.44,0-6.97-1.81-6.97-7.81s2.54-7.81,6.83-7.81c5.13,0,6.02,3.38,6.02,6.3,0,.42-.06,1.06-.14,1.76Zm-2.23-1.73c0-2.32-.39-4.35-3.65-4.35-3.46,0-4.24,1.87-4.32,4.94l7.98-.59Z"/>
<path class="cls-2" d="m454.72,110.12v10.4h-2.4v-9.54c0-2.31-.64-3.65-2.9-3.65-1.76,0-3.26.5-3.91,2.65v10.54h-2.4v-9.54c0-2.31-.56-3.65-2.76-3.65-1.87,0-3.24.42-3.99,2.73v10.46h-2.4v-15.06h2.4v1.98c.92-1.79,2.54-2.26,4.35-2.26,2.37,0,3.74.95,4.38,2.45.89-1.95,2.84-2.45,4.69-2.45,3.51,0,4.94,2.04,4.94,4.94Z"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.8 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

+124 -43
View File
@@ -2,18 +2,28 @@
<template>
<div class="base-search-form">
<el-form :size="size" :inline="true" :label-width="labelWidth">
<el-form-item v-for="item in searchForm" :key="item.prop" :label="item.label">
<el-form-item
v-for="item in searchForm"
:key="item.prop"
:label="item.label"
>
<!-- 输入框 -->
<el-input v-if="item.type==='Input'" v-model="searchData[item.prop]" :placeholder="item.placeholder" size="mini" :style="{width:item.width}" :readonly="item.readonly" />
<!-- 下拉框 -->
<el-select
v-if="item.type==='Select'"
<el-input
v-if="item.type === 'Input'"
v-model="searchData[item.prop]"
:placeholder="item.placeholder"
size="mini"
:style="{width:item.width}"
@change="item.change && item.change(that,searchData[item.prop])"
:style="{ width: item.width }"
:readonly="item.readonly"
/>
<!-- 下拉框 -->
<el-select
v-if="item.type === 'Select'"
v-model="searchData[item.prop]"
:placeholder="item.placeholder"
size="mini"
:style="{ width: item.width }"
@change="item.change && item.change(that, searchData[item.prop])"
>
<el-option
v-for="op in item.options"
@@ -23,49 +33,122 @@
/>
</el-select>
<el-select
v-if="item.type==='Select2'"
v-if="item.type === 'Select2'"
v-model="searchData[item.prop]"
:placeholder="item.placeholder"
size="mini"
:style="{width:item.width}"
@change="item.change && item.change(that,searchData[item.prop])"
:style="{ width: item.width }"
@change="item.change && item.change(that, searchData[item.prop])"
>
<el-option
v-for="(key,value) of item.options"
v-for="(key, value) of item.options"
:key="key"
:label="key"
:value="value"
/>
</el-select>
<!-- 单选 -->
<el-radio-group v-if="item.type==='Radio'" v-model="searchData[item.prop]" :style="{width:item.width}">
<el-radio v-for="ra in item.radios" :key="ra.value" :label="ra.value">{{ ra.label }}</el-radio>
<el-radio-group
v-if="item.type === 'Radio'"
v-model="searchData[item.prop]"
:style="{ width: item.width }"
>
<el-radio
v-for="ra in item.radios"
:key="ra.value"
:label="ra.value"
>{{ ra.label }}</el-radio
>
</el-radio-group>
<!-- 单选按钮 -->
<el-radio-group v-if="item.type==='RadioButton'" v-model="searchData[item.prop]" :style="{width:item.width}" @change="item.change && item.change(searchData[item.prop])">
<el-radio-button v-for="ra in item.radios" :key="ra.value" :label="ra.value">{{ ra.label }}</el-radio-button>
<el-radio-group
v-if="item.type === 'RadioButton'"
v-model="searchData[item.prop]"
:style="{ width: item.width }"
@change="item.change && item.change(searchData[item.prop])"
>
<el-radio-button
v-for="ra in item.radios"
:key="ra.value"
:label="ra.value"
>{{ ra.label }}</el-radio-button
>
</el-radio-group>
<!-- 复选框 -->
<el-checkbox-group v-if="item.type==='Checkbox'" v-model="searchData[item.prop]" :style="{width:item.width}">
<el-checkbox v-for="ch in item.checkboxs" :key="ch.value" :label="ch.value">{{ ch.label }}</el-checkbox>
<el-checkbox-group
v-if="item.type === 'Checkbox'"
v-model="searchData[item.prop]"
:style="{ width: item.width }"
>
<el-checkbox
v-for="ch in item.checkboxs"
:key="ch.value"
:label="ch.value"
>{{ ch.label }}</el-checkbox
>
</el-checkbox-group>
<!-- 日期 -->
<el-date-picker v-if="item.type==='Date'" v-model="searchData[item.prop]" :placeholder="item.placeholder" :style="{width:item.width}" value-format="yyyy-MM-dd" format="yyyy-MM-dd" :picker-options="item.pickerOption" />
<el-date-picker
v-if="item.type === 'Date'"
v-model="searchData[item.prop]"
:placeholder="item.placeholder"
:style="{ width: item.width }"
value-format="yyyy-MM-dd"
format="yyyy-MM-dd"
:picker-options="item.pickerOption"
/>
<!-- 时间 -->
<el-time-select v-if="item.type==='Time'" v-model="searchData[item.prop]" :placeholder="item.placeholder" type="" :style="{width:item.width}" />
<el-time-select
v-if="item.type === 'Time'"
v-model="searchData[item.prop]"
:placeholder="item.placeholder"
type=""
:style="{ width: item.width }"
/>
<!-- 日期时间 -->
<el-date-picker v-if="item.type==='DateTime'" v-model="searchData[item.prop]" :placeholder="item.placeholder" type="datetime" :disabled="item.disable && item.disable(searchData[item.prop])" :style="{width:item.width}" />
<el-date-picker
v-if="item.type === 'DateTime'"
v-model="searchData[item.prop]"
:placeholder="item.placeholder"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
:disabled="item.disable && item.disable(searchData[item.prop])"
:style="{ width: item.width }"
/>
<!-- 日期时间段 -->
<el-date-picker
v-if="item.type === 'Daterange'"
v-model="searchData[item.prop]"
type="datetimerange"
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
value-format="yyyy-MM-dd HH:mm:ss"
format="yyyy-MM-dd HH:mm:ss"
:style="{ width: item.width }"
clearable
/>
<!-- 滑块 -->
<!-- <el-slider v-if="item.type==='Slider'" v-model="searchData[item.prop]"></el-slider> -->
<!-- 开关 -->
<el-switch v-if="item.type==='Switch'" v-model="searchData[item.prop]" :style="{width:item.width}" />
<el-switch
v-if="item.type === 'Switch'"
v-model="searchData[item.prop]"
:style="{ width: item.width }"
/>
<!-- 具名slot -->
<slot v-if="item.type==='Custom'" :name="item.slot" />
<slot v-if="item.type === 'Custom'" :name="item.slot" />
</el-form-item>
<el-form-item v-for="item in searchHandle" :key="item.label">
<slot v-if="item.slot" :name="item.slot" />
<el-button v-else :type="item.type" :size="item.size || size" :icon="item.icon || ''" @click="handleClick(item.emitKey)">{{ item.label }}</el-button>
<el-button
v-else
:type="item.type"
:size="item.size || size"
:icon="item.icon || ''"
@click="handleClick(item.emitKey)"
>{{ item.label }}</el-button
>
</el-form-item>
</el-form>
</div>
@@ -76,47 +159,45 @@ export default {
props: {
that: {
type: Object,
default: this
default: this,
},
isHandle: {
type: Boolean,
default: true
default: true,
},
labelWidth: {
type: String,
default: ''
default: "",
},
size: {
type: String,
default: 'mini'
default: "mini",
},
searchForm: {
type: Array,
default: () => []
default: () => [],
},
searchHandle: {
type: Array,
default: () => []
default: () => [],
},
searchData: {
type: Object,
default: () => {}
}
default: () => {},
},
},
methods: {
handleClick(emitKey) {
// emit
this.$emit(`${emitKey}`)
}
}
}
this.$emit(`${emitKey}`);
},
},
};
</script>
<style lang="scss">
.base-search-form{
.el-form-item{
margin-bottom: 0px;
}
.base-search-form {
.el-form-item {
margin-bottom: 0px;
}
}
</style>
+45 -30
View File
@@ -1,6 +1,16 @@
<template>
<div class="base-model-wrapper">
<el-dialog v-if="config.visible" v-dialogDrag :title="config.title" :append-to-body="config.appendToBody" :visible.sync="config.visible" :close-on-click-modal="false" :show-close="config.showClose" :width="config.width" :fullscreen="config.fullscreen">
<el-dialog
v-if="config.visible"
v-dialogDrag
:title="config.title"
:append-to-body="config.appendToBody"
:visible.sync="config.visible"
:close-on-click-modal="false"
:show-close="config.showClose"
:width="config.width"
:fullscreen="config.fullscreen"
>
<div class="base-modal-body">
<slot name="dialog-body" />
</div>
@@ -12,46 +22,51 @@
</template>
<script>
export default {
name: 'BaseDialog',
name: "BaseDialog",
props: {
config: {
type: Object,
default: () => {
return {
visible: false,
title: '',
title: "",
closeOnClickModal: false,
showClose: true,
appendToBody: false,
width: '100px',
fullscreen: false
}
}
}
}
}
width: "100px",
fullscreen: false,
};
},
},
},
};
</script>
<style lang="scss">
.base-model-wrapper{
.el-dialog__header{
padding: 10px;
.el-dialog__headerbtn{
top: 10px;
right: 10px;
}
}
.el-dialog__body{
padding:10px 10px 10px 10px;
.base-modal-body{
min-height: 100px;
max-height:650px;
overflow-y: auto;
padding: 10px;
border: 1px solid #e0e0e0;
}
}
.el-dialog__footer{
padding: 10px;
.base-model-wrapper {
.el-dialog__header {
padding: 10px;
.el-dialog__headerbtn {
top: 10px;
right: 10px;
}
}
.el-dialog__body {
padding: 10px 10px 10px 10px;
.base-modal-body {
min-height: 100px;
max-height: 650px;
overflow-y: auto;
padding: 10px;
border: 1px solid #e0e0e0;
}
}
.el-dialog__footer {
padding: 10px;
}
}
.notFooter {
.is-fullscreen .el-dialog__footer {
display: none;
}
}
</style>
+1 -1
View File
@@ -1,7 +1,7 @@
<template>
<div class="chat-wrapper">
<div class="chat-content">
<div v-for="(record,index) in recordContent" :key="index">
<div v-for="(record,index) in recordContent" :key="`${record.chatTime}${index}`">
<div v-if="!record.mineMsg" class="word">
<!-- <img :src="record.headUrl"> -->
<img src="@/assets/CRC.png">
+251 -215
View File
@@ -8,7 +8,6 @@
style="width:100%;height:100%;position:relative;"
class="cornerstone-element"
@contextmenu.prevent="onContextmenu"
@mousemove="sliderMousemove"
@mouseup="sliderMouseup"
>
<div v-show="dicomInfo.series" class="info-series">
@@ -54,7 +53,7 @@
<!-- <div v-show="dicomInfo.acc">ACC {{ dicomInfo.acc }}</div> -->
<!-- <div>{{ dicomInfo.time }}</div> -->
</div>
<div ref="sliderBox" class="my_slider_box" style="position: absolute;right: 1px;height: calc(100% - 100px);transform: translateY(-50%);top: calc(50% - 30px);width: 10px;background: #333;cursor: pointer">
<div ref="sliderBox" class="my_slider_box" style="position: absolute;right: 1px;height: calc(100% - 100px);transform: translateY(-50%);top: calc(50% - 30px);width: 10px;background: #333;cursor: pointer" @click.stop="goViewer($event)">
<div :style="{top: height + '%'}" style="z-index:10;background: #9e9e9e;height: 20px;width: 100%;position: absolute;top: 0;cursor: move" @mousedown="sliderMousedown($event)" />
</div>
<div style="position: absolute;left: 50%;top: 15px;color: #f44336;">
@@ -163,7 +162,9 @@ export default {
isMove: false
},
mousePosition: { x: '', y: '', mo: '' },
markers: { top: '', right: '', bottom: '', left: '' }
markers: { top: '', right: '', bottom: '', left: '' },
orientationMarkers: [],
originalMarkers: []
}
},
@@ -186,6 +187,9 @@ export default {
document.addEventListener('mouseup', () => {
this.sliderMouseup()
})
document.addEventListener('mousemove', (e) => {
this.sliderMousemove(e)
})
this.canvas.addEventListener('cornerstonetoolsstackscroll', this.stackScrollCallback)
},
@@ -205,15 +209,19 @@ export default {
var instanceId = imageId.split('/')[imageId.split('/').length - 1]
instanceId = instanceId.split('.')[0]
this.stack.instanceId = instanceId
if (this.toolState.clipPlaying) this.toggleClipPlay()
this.toolState.clipPlaying = false
const element = this.$refs.canvas
cornerstone.enable(element)
cornerstoneTools.stopClip(this.canvas)
this.toolState.clipPlaying = false
this.loading = true
cornerstone.loadAndCacheImage(this.stack.imageIds[this.stack.currentImageIdIndex])
.then(image => {
this.loading = false
this.onFirstImageLoaded(image)
if (this.stack.imageIds.indexOf(image.imageId) !== -1) {
this.onFirstImageLoaded(image)
}
}).catch((error) => {
this.loading = false
if (error.error && error.error.message) {
@@ -356,6 +364,12 @@ export default {
if (this.dicomInfo.thick) {
this.dicomInfo.thick = this.dicomInfo.thick.toFixed(2)
}
let newImageIdIndex = this.stack.imageIds.findIndex(i=>i===e.detail.image.imageId)
if(newImageIdIndex === -1) return
this.stack.currentImageIdIndex = newImageIdIndex
this.stack.imageIdIndex = newImageIdIndex
this.series.imageIdIndex = newImageIdIndex
this.height = (this.stack.currentImageIdIndex) * 100 / (this.stack.imageIds.length - 1)
},
stackScrollCallback(e) {
const { detail } = e
@@ -403,6 +417,7 @@ export default {
this.dicomInfo.location = position
},
getOrientationMarker(element) {
console.log('getOrientationMarker')
const enabledElement = cornerstone.getEnabledElement(element)
const imagePlane = cornerstone.metaData.get(
'imagePlaneModule',
@@ -426,6 +441,7 @@ export default {
if (!markers) {
return
}
this.orientationMarkers = [oppositeColumn, row, column, oppositeRow]
this.originalMarkers = [oppositeColumn, row, column, oppositeRow]
this.setMarkers()
@@ -438,10 +454,10 @@ export default {
}
},
onImageLoaded(e) {
var image = e.detail.image
// var seriesIndex = -1
var seriesUid = image.data.string('x0020000e')
console.log(seriesUid)
// var image = e.detail.image
// // var seriesIndex = -1
// var seriesUid = image.data.string('x0020000e')
// console.log(seriesUid)
},
getToolForElement(toolName) {
var isExist = false
@@ -521,6 +537,9 @@ export default {
this.sliderInfo.oldB = parseInt(e.srcElement.style.top) * boxHeight / 100
this.sliderInfo.oldM = e.clientY
this.sliderInfo.isMove = true
e.stopImmediatePropagation()
e.stopPropagation()
e.preventDefault()
},
sliderMousemove(e) {
if (!this.sliderInfo.isMove) return
@@ -540,6 +559,13 @@ export default {
sliderMouseup(e) {
this.sliderInfo.isMove = false
},
goViewer(e) {
// console.log(this.$refs['sliderBox'].clientHeight)
var height = e.offsetY * 100 / this.$refs['sliderBox'].clientHeight
this.height = height
var index = Math.trunc(this.stack.imageIds.length * this.height / 100)
scroll(this.canvas, index)
},
onClipStopped() {
this.toolState.clipPlaying = false
},
@@ -610,6 +636,7 @@ export default {
enabledElement.renderingTools.renderCanvasData = renderCanvasData
},
scrollPage(offset) {
if(this.loading) return
var index = this.stack.currentImageIdIndex + offset
if (index < 0) index = 0
else if (index >= this.stack.imageIds.length) {
@@ -621,6 +648,7 @@ export default {
},
toggleClipPlay() {
if(this.loading) return
if (this.toolState.clipPlaying) {
cornerstoneTools.stopClip(this.canvas)
this.toolState.clipPlaying = false
@@ -675,8 +703,11 @@ export default {
},
resetRotate() {
this.orientationMarkers = [...this.originalMarkers]
this.setMarkers()
if (this.originalMarkers.length > 0) {
this.orientationMarkers = [...this.originalMarkers]
this.setMarkers()
}
var viewport = cornerstone.getViewport(this.canvas)
viewport.hflip = false
viewport.vflip = false
@@ -685,24 +716,26 @@ export default {
},
setRotate(hflip, vflip, angle, type) {
var markers = [...this.orientationMarkers]
if (type === 2) {
//
this.orientationMarkers[1] = markers[3]
if (this.orientationMarkers.length > 0) {
var markers = [...this.orientationMarkers]
if (type === 2) {
//
this.orientationMarkers[1] = markers[3]
this.orientationMarkers[3] = markers[1]
} else if (type === 3) {
//
this.orientationMarkers[0] = markers[2]
this.orientationMarkers[2] = markers[0]
} else if (type === 4) {
// 90
this.orientationMarkers = markers.slice(1, 4).concat(markers[0])
} else if (type === 5) {
// 90
this.orientationMarkers = [markers[3]].concat(markers.slice(0, 3))
this.orientationMarkers[3] = markers[1]
} else if (type === 3) {
//
this.orientationMarkers[0] = markers[2]
this.orientationMarkers[2] = markers[0]
} else if (type === 4) {
// 90
this.orientationMarkers = markers.slice(1, 4).concat(markers[0])
} else if (type === 5) {
// 90
this.orientationMarkers = [markers[3]].concat(markers.slice(0, 3))
}
this.setMarkers()
}
this.setMarkers()
var viewport = cornerstone.getViewport(this.canvas)
if (hflip) viewport.hflip = !viewport.hflip
if (vflip) viewport.vflip = !viewport.vflip
@@ -840,194 +873,197 @@ export default {
synchronizer.remove(this.$refs.canvas)
this.setAllToolsPassive()
},
onContextmenu(event) {
const colormapsList = cornerstone.colors.getColormapsList()
const colorItems = []
colorItems.push({
label: '默认值',
onClick: () => {
this.setColormap()
}
})
colormapsList.forEach(colormap => {
const item = {}
item.label = colormap.name
item.onClick = () => {
this.setColormap(colormap.id)
}
colorItems.push(item)
})
this.$contextmenu({
items: [
{
label: '移动',
divided: true,
onClick: () => {
this.setToolActive('Pan')
}
},
{
label: '缩放',
divided: true,
children: [
{
label: '自由缩放',
onClick: () => {
this.setToolActive('Zoom')
}
},
{
label: '适应图像',
onClick: () => {
this.fitToWindow()
}
},
{
label: '适应窗口',
onClick: () => {
this.fitToImage()
}
}
]
},
{
label: '透镜',
divided: true,
onClick: () => {
this.setToolActive('Magnify')
}
},
{
label: '旋转',
divided: true,
children: [
{
label: '默认值',
onClick: () => {
this.resetRotate()
}
},
{
label: '自由旋转',
onClick: () => {
this.setToolActive('Rotate')
}
},
{
label: '水平翻转',
onClick: () => {
this.setRotate(true, false, 0)
}
},
{
label: '垂直翻转',
onClick: () => {
this.setRotate(false, true, 0)
}
},
{
label: '左转90度',
onClick: () => {
this.setRotate(false, false, -90)
}
},
{
label: '右转90度',
onClick: () => {
this.setRotate(false, false, 90)
}
}
]
},
onContextmenu(e) {
e.stopImmediatePropagation()
e.stopPropagation()
e.preventDefault()
// const colormapsList = cornerstone.colors.getColormapsList()
// const colorItems = []
// colorItems.push({
// label: '',
// onClick: () => {
// this.setColormap()
// }
// })
// colormapsList.forEach(colormap => {
// const item = {}
// item.label = colormap.name
// item.onClick = () => {
// this.setColormap(colormap.id)
// }
// colorItems.push(item)
// })
// this.$contextmenu({
// items: [
// {
// label: '',
// divided: true,
// onClick: () => {
// this.setToolActive('Pan')
// }
// },
// {
// label: '',
// divided: true,
// children: [
// {
// label: '',
// onClick: () => {
// this.setToolActive('Zoom')
// }
// },
// {
// label: '',
// onClick: () => {
// this.fitToWindow()
// }
// },
// {
// label: '',
// onClick: () => {
// this.fitToImage()
// }
// }
// ]
// },
// {
// label: '',
// divided: true,
// onClick: () => {
// this.setToolActive('Magnify')
// }
// },
// {
// label: '',
// divided: true,
// children: [
// {
// label: '',
// onClick: () => {
// this.resetRotate()
// }
// },
// {
// label: '',
// onClick: () => {
// this.setToolActive('Rotate')
// }
// },
// {
// label: '',
// onClick: () => {
// this.setRotate(true, false, 0)
// }
// },
// {
// label: '',
// onClick: () => {
// this.setRotate(false, true, 0)
// }
// },
// {
// label: '90',
// onClick: () => {
// this.setRotate(false, false, -90)
// }
// },
// {
// label: '90',
// onClick: () => {
// this.setRotate(false, false, 90)
// }
// }
// ]
// },
{
label: '测量',
divided: true,
minWidth: 0,
children: [
{
label: '探针',
onClick: () => {
this.setToolActive('Probe')
}
},
{
label: '长度测量',
onClick: () => {
this.setToolActive('Length')
}
},
{
label: '角度测量',
onClick: () => {
this.setToolActive('Angle')
}
},
{
label: 'Cobb测量',
onClick: () => {
this.setToolActive('CobbAngle')
}
},
{
label: '椭圆测量',
onClick: () => {
this.setToolActive('EllipticalRoi')
}
},
{
label: '矩形测量',
onClick: () => {
this.setToolActive('RectangleRoi')
}
},
{
label: '多边形标记',
onClick: () => {
this.setToolActive('FreehandRoi')
}
},
{
label: '十字线',
onClick: () => {
this.setToolActive('Bidirectional')
}
},
{
label: '文字标注',
onClick: () => {
this.setToolActive('ArrowAnnotate')
}
}
]
},
{
label: '调窗',
divided: true,
onClick: () => {
this.setToolActive('Wwwc')
}
},
{
label: '反色',
divided: true,
onClick: () => {
this.toggleInvert()
}
},
{
label: '伪彩',
children: colorItems
}
],
event,
// x: event.clientX,
// y: event.clientY,
customClass: 'class-a',
zIndex: 3,
minWidth: 100
})
return false
// {
// label: '',
// divided: true,
// minWidth: 0,
// children: [
// {
// label: '',
// onClick: () => {
// this.setToolActive('Probe')
// }
// },
// {
// label: '',
// onClick: () => {
// this.setToolActive('Length')
// }
// },
// {
// label: '',
// onClick: () => {
// this.setToolActive('Angle')
// }
// },
// {
// label: 'Cobb',
// onClick: () => {
// this.setToolActive('CobbAngle')
// }
// },
// {
// label: '',
// onClick: () => {
// this.setToolActive('EllipticalRoi')
// }
// },
// {
// label: '',
// onClick: () => {
// this.setToolActive('RectangleRoi')
// }
// },
// {
// label: '',
// onClick: () => {
// this.setToolActive('FreehandRoi')
// }
// },
// {
// label: '线',
// onClick: () => {
// this.setToolActive('Bidirectional')
// }
// },
// {
// label: '',
// onClick: () => {
// this.setToolActive('ArrowAnnotate')
// }
// }
// ]
// },
// {
// label: '',
// divided: true,
// onClick: () => {
// this.setToolActive('Wwwc')
// }
// },
// {
// label: '',
// divided: true,
// onClick: () => {
// this.toggleInvert()
// }
// },
// {
// label: '',
// children: colorItems
// }
// ],
// event,
// // x: event.clientX,
// // y: event.clientY,
// customClass: 'class-a',
// zIndex: 3,
// minWidth: 100
// })
// return false
},
getToolSate() {
const toolROITypes = [
+34 -20
View File
@@ -162,6 +162,19 @@
<button :title="$t('trials:dicom-show:lens')" class="btn-link" data-tool="Magnify" @click="setToolActive($event,'Magnify')">
<svg-icon icon-class="zoom" style="font-size:20px;" />
</button>
<button :title="$t('trials:reading:button:rotate')" class="btn-link dropdown" data-tool="Rotate">
<svg-icon icon-class="rotate" style="font-size:20px;" />
<div class="dropdown-content">
<div @click.stop="setDicomCanvasRotate(1)">{{ $t('trials:reading:button:rotateDefault') }}</div>
<div @click.stop="setDicomCanvasRotate(2)">{{ $t('trials:reading:button:rotateHorizontal') }}</div>
<div @click.stop="setDicomCanvasRotate(3)">{{ $t('trials:reading:button:rotateVertical') }}</div>
<div @click.stop="setDicomCanvasRotate(4)">{{ $t('trials:reading:button:rotateTurnLeft') }}</div>
<div @click.stop="setDicomCanvasRotate(5)">{{ $t('trials:reading:button:rotateTurnRight') }}</div>
</div>
</button>
<button :title="$t('trials:reading:button:move')" class="btn-link" data-tool="Pan" @click="setToolActive($event,'Pan')">
<svg-icon icon-class="move" style="font-size:20px;" />
</button>
<button :title="$t('trials:reading:button:fitWindow')" class="btn-link" data-tool="fitToWindow" @click="fitToType($event,'fitToWindow')">
<svg-icon icon-class="fitToWindow" style="font-size:20px;" />
</button>
@@ -169,19 +182,7 @@
<svg-icon icon-class="fitToImage" style="font-size:20px;" />
</button>
<!-- <button title="旋转" class="btn-link dropdown" data-tool="Rotate" @click="setToolActive($event,'Rotate')"> -->
<button :title="$t('trials:reading:button:rotate')" class="btn-link dropdown" data-tool="Rotate">
<svg-icon icon-class="rotate" style="font-size:20px;" />
<div class="dropdown-content">
<p @click.stop="setDicomCanvasRotate(1)">{{ $t('trials:reading:button:rotateDefault') }}</p>
<p @click.stop="setDicomCanvasRotate(2)">{{ $t('trials:reading:button:rotateHorizontal') }}</p>
<p @click.stop="setDicomCanvasRotate(3)">{{ $t('trials:reading:button:rotateVertical') }}</p>
<p @click.stop="setDicomCanvasRotate(4)">{{ $t('trials:reading:button:rotateTurnLeft') }}</p>
<p @click.stop="setDicomCanvasRotate(5)">{{ $t('trials:reading:button:rotateTurnRight') }}</p>
</div>
</button>
<button :title="$t('trials:reading:button:move')" class="btn-link" data-tool="Pan" @click="setToolActive($event,'Pan')">
<svg-icon icon-class="move" style="font-size:20px;" />
</button>
</div>
</div>
<!-- 测量标注 -->
@@ -247,7 +248,7 @@
<svg-icon icon-class="previousframe" style="font-size:20px;" />
</button>
<!-- 播放 -->
<button class="btn-link" :title="$t('trials:dicom-show:play')" @click="currentDicomCanvas.toggleClipPlay()">
<button class="btn-link" :title="$t('trials:dicom-show:play')" @click="clipPlay">
<svg-icon
:icon-class="currentDicomCanvas.toolState.clipPlaying ? 'stop' : 'play'"
style="font-size:20px;"
@@ -261,9 +262,10 @@
<button class="btn-link" :title="$t('trials:dicom-show:lastframe')" @click="currentDicomCanvas.scrollPage(9999)">
<svg-icon icon-class="lastframe" style="font-size:20px;" />
</button>
<select class="sidetool-select" style="width:60px" @change="setDicomCanvasfps($event)">
<select v-model="fps" class="sidetool-select" style="width:60px" @change="setDicomCanvasfps($event)">
<!-- 默认值 -->
<option :value="10">{{ $t('trials:dicom-show:default') }}</option>
<option :value="5">5</option>
<option :value="10">10</option>
<option :value="15">15</option>
<option :value="20">20</option>
<option :value="30">30</option>
@@ -386,20 +388,22 @@ export default {
wwwcList: [],
layout: null,
seriesList: [],
customWwc: { visible: false, title: null }
customWwc: { visible: false, title: null },
fps: 15
}
},
mounted() {
this.customWwc = { visible: false, title: this.$t('DicomViewer:data:customWwc') }
this.rotateList[0] = '1'
this.colorList[0] = ''
this.wwwcList[0] = '1'
this.wwwcList[0] = '-1'
this.colormapsList = cornerstone.colors.getColormapsList()
this.currentDicomCanvas = this.$refs['dicomCanvas0']
},
methods: {
loadImageStack(dicomSeries) {
this.currentDicomCanvas.toolState.clipPlaying = false
this.$nextTick(() => {
this.currentDicomCanvas.loadImageStack(dicomSeries)
})
@@ -444,7 +448,7 @@ export default {
this.colorList[this.currentDicomCanvasIndex] = ''
}
if (!this.wwwcList[this.currentDicomCanvasIndex]) {
this.wwwcList[this.currentDicomCanvasIndex] = '1'
this.wwwcList[this.currentDicomCanvasIndex] = '-1'
}
}
},
@@ -565,6 +569,10 @@ export default {
setDicomCanvasfps(event) {
this.currentDicomCanvas.setFps(event.target.value)
},
clipPlay() {
this.currentDicomCanvas.setFps(this.fps)
this.currentDicomCanvas.toggleClipPlay()
},
fitToType(e, type) {
const toolButtons = document.querySelectorAll('[data-tool]')
Array.from(toolButtons).forEach((toolBtn) => {
@@ -879,13 +887,19 @@ export default {
background-color: #323232;
min-width: 80px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
border: 1px solid #4e4e4e;
padding: 5px;
}
.dicom-wrapper .dropdown:hover .dropdown-content {
display: block;
}
.dicom-wrapper .dropdown-content p{
.dicom-wrapper .dropdown-content div{
height: 25px;
line-height: 25px;
cursor:point;
}
.dicom-wrapper .dropdown-content div:hover{
background-color: #16477b90;
}
</style>
+26
View File
@@ -0,0 +1,26 @@
import Vue from "vue";
import MFACOMP from "./index.vue";
const MFAConstructor = Vue.extend(MFACOMP);
const MFA = options => {
const { UserId, username, EMail, callBack, cancelBack, status = 'login' } = options;
if (!UserId) throw `UserId is requred.but ${UserId}`
const id = `MFA${new Date().getTime()}`;
const instance = new MFAConstructor();
instance.id = id;
instance.vm = instance.$mount();
if (instance.vm.visible) return;
document.body.appendChild(instance.vm.$el);
instance.vm.open({ UserId, username, EMail, status });
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();
});
return instance.vm;
}
export default MFA;
+7
View File
@@ -0,0 +1,7 @@
import MFACOMP from "./index.vue";
import MFA from "./fun";
export default Vue => {
Vue.component(MFACOMP.name, MFACOMP);
Vue.prototype.$MFA = MFA;
};
+207
View File
@@ -0,0 +1,207 @@
<template>
<!--MFA-->
<el-dialog
v-if="visible"
:visible.sync="visible"
width="540px"
:close-on-click-modal="false"
append-to-body
center
:show-close="status === 'login'"
@close="cancel"
>
<div slot="title">
{{ status === "login" ? $t("mfa:title") : $t("mfa:lock:title") }}
</div>
<el-form
ref="mfaForm"
label-position="right"
:model="form"
:rules="rules"
label-width="100px"
>
<!-- 邮箱 -->
<p class="tip">
<i class="el-icon-warning" style="color: #409eff"></i>
<span>{{ tip }}</span>
</p>
<!-- 用户名 -->
<el-form-item :label="$t('mfa:form:username')" prop="username">
<span>{{ form.username }}</span>
</el-form-item>
<!-- 验证码 -->
<el-form-item :label="$t('mfa:form:MFACode')" prop="Code">
<el-input
:placeholder="$t('mfa:form:input:placeholder:Codes')"
v-model="form.Code"
style="width: 240px; margin-right: 10px"
/>
<el-button
type="primary"
size="small"
@click.stop="sendMFACode"
:disabled="flag || sendFlag"
>{{ flag ? `${second}s` : $t("mfa:form:sendMFACode") }}</el-button
>
</el-form-item>
</el-form>
<div slot="footer">
<!-- 取消 -->
<!-- <el-button size="small" @click="cancel" v-if="status === 'login'">
{{ $t("mfa:button:cancel") }}
</el-button> -->
<!-- 保存 -->
<el-button
type="primary"
size="small"
@click="save"
:loading="loading"
style="width: 80%"
>
{{
status === "login"
? $t("mfa:button:save")
: $t("mfa:lock:button:save")
}}
</el-button>
</div>
</el-dialog>
</template>
<script>
import { sendMFAEmail, verifyMFACode } from "@/api/user.js";
export default {
name: "MFA",
data() {
return {
status: "login", // lock
tip: null,
visible: false,
loading: false,
timer: null,
flag: false,
sendFlag: false,
second: 60,
form: {
Code: null,
UserId: null,
EMail: null,
username: null,
},
rules: {
Code: [
{
required: true,
message: this.$t("mfa:ruleMessage:specify"),
trigger: "blur",
},
],
EMail: [
{
required: true,
message: this.$t("mfa:ruleMessage:specify"),
trigger: "blur",
},
],
username: [
{
required: true,
message: this.$t("mfa:ruleMessage:specify"),
trigger: "blur",
},
],
},
};
},
methods: {
open(data) {
let { UserId, status, username, EMail } = data;
this.form.UserId = UserId;
this.status = status ? status : "login";
this.form.username = username;
this.form.EMail = EMail;
this.visible = true;
this.tip = this.$t("mfa:tip").replace("xx", EMail);
},
cancel() {
this.visible = false;
this.$emit("closed");
},
async save() {
try {
let validate = await this.$refs.mfaForm.validate();
if (!validate) return;
this.loading = true;
let res = await verifyMFACode(this.form);
this.loading = false;
if (res.IsSuccess) {
if (this.status === "login") {
this.$message.success(this.$t("mfa:message:verifySuccess"));
}
this.$emit("success", this.form.UserId);
this.cancel();
}
} catch (err) {
console.log(err);
this.loading = false;
}
},
async sendMFACode() {
try {
if (this.flag || this.sendFlag) return;
this.sendFlag = true;
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
let data = {
UserId: this.form.UserId,
};
if (this.status === "lock") {
data.MfaType = 1;
}
let res = await sendMFAEmail(data);
this.sendFlag = false;
if (res.IsSuccess) {
this.flag = true;
this.second = 60;
this.timer = setInterval(() => {
this.second--;
if (this.second <= 0) {
clearInterval(this.timer);
this.timer = null;
}
}, 1000);
}
} catch (err) {
console.log(err);
this.flag = false;
this.sendFlag = false;
}
},
},
destroyed() {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
},
};
</script>
<style lang="scss" scoped>
.tip {
width: 86%;
margin: auto;
margin-bottom: 20px;
text-align: left;
padding: 0 10px;
line-height: 30px;
border-radius: 5px;
background-color: #eee;
i {
margin-right: 5px;
}
}
::v-deep .el-dialog__header{
font-weight: bold;
}
</style>
+22
View File
@@ -0,0 +1,22 @@
import Vue from "vue";
import Preview from "./index.vue";
const PreviewConstructor = Vue.extend(Preview);
const preview = options => {
const { path, type, title } = options;
if (!path) throw `path is requred.but ${path}`
const id = `Preview_${new Date().getTime()}`;
const instance = new PreviewConstructor();
instance.id = id;
instance.vm = instance.$mount();
if (instance.vm.visible) return;
document.body.appendChild(instance.vm.$el);
instance.vm.open(path, type, title);
instance.vm.$on("closed", () => {
document.body.removeChild(instance.vm.$el);
instance.vm.$destroy();
});
return instance.vm;
}
export default preview;
+7
View File
@@ -0,0 +1,7 @@
import Preview from "./index.vue";
import preview from "./fun";
export default Vue => {
Vue.component(Preview.name, Preview);
Vue.prototype.$preview = preview;
};
+41
View File
@@ -0,0 +1,41 @@
<template>
<el-dialog
v-if="visible"
: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">
<PreviewFile v-if="visible" :file-path="path" :file-type="type" />
</div>
</el-dialog>
</template>
<script>
import PreviewFile from "@/components/PreviewFile";
export default {
name: "preview",
components: { PreviewFile },
data() {
return {
visible: false,
path: null,
type: null,
title: null,
};
},
methods: {
open(path, type, title) {
this.path = path;
this.type = type;
this.title = title;
this.visible = true;
},
handleClose() {
this.$emit("closed");
},
},
};
</script>
+17 -9
View File
@@ -2,16 +2,17 @@
<template>
<div class="trialsTab">
<el-tabs v-model="trialsTab" @tab-click="clickTab">
<el-tab-pane v-for="item of trialsRouter.children.find(v => {return v.name == 'TrialsPanel'}).children" :key="`tab${item.path}`" :disabled="TotalNeedSignTrialDocCount !== 0" :label="$t(item.LanguageMark)" :name="item.path">
<el-tab-pane v-for="item of trialsRouter.children.find(v => {return v.name == 'TrialsPanel'}).children" :key="`tab${item.path}`" :disabled="TotalNeedSignTrialDocCount !== 0 && item.path !== '/trials/trials-panel/attachments'" :label="$t(item.LanguageMark)" :name="item.path">
<el-tabs v-if="!item.tabHiddn" v-model="trialsTabChild" @tab-click="clickTab">
<el-tab-pane
v-for="item1 of item.children"
v-if="TrialConfig && isShow(item1.path)"
:key="`tab1${item1.path}`"
:disabled="TotalNeedSignTrialDocCount !== 0 || (TrialStatusStr === 'Initializing' && (item1.path === '/trials/trials-panel/setting/personnel-manage' || item1.path === '/trials/trials-panel/setting/qc-question' || item1.path === '/trials/trials-panel/setting/reading-unit' || item1.path === '/trials/trials-panel/setting/medical-audit' || item1.path === '/trials/trials-panel/setting/email-manage'))"
:label="$t(item1.LanguageMark)"
:name="item1.path"
/>
<template v-for="item1 of item.children">
<el-tab-pane
v-if="TrialConfig && isShow(item1.path)"
:key="`tab1${item1.path}`"
:disabled="TotalNeedSignTrialDocCount !== 0 && item1.path !== '/trials/trials-panel/attachments/self-attachment' || (TrialStatusStr === 'Initializing' && (item1.path === '/trials/trials-panel/setting/personnel-manage' || item1.path === '/trials/trials-panel/setting/qc-question' || item1.path === '/trials/trials-panel/setting/reading-unit' || item1.path === '/trials/trials-panel/setting/medical-audit' || item1.path === '/trials/trials-panel/setting/email-manage'))"
:label="$t(item1.LanguageMark)"
:name="item1.path"
/>
</template>
</el-tabs>
</el-tab-pane>
</el-tabs>
@@ -126,6 +127,10 @@ export default {
var additionalAssessmentList = [
'/trials/trials-panel/subject/brain-metastasis'
]
let dicomList = [
'/trials/trials-panel/trial-summary/image-inspect',
'/trials/trials-panel/trial-summary/push-record',
]
if (this.TrialConfig.QCProcessEnum === 0 && ~qualityList.indexOf(path)) {
isShow = false
}
@@ -135,6 +140,9 @@ export default {
if (!this.IsAdditionalAssessment && ~additionalAssessmentList.indexOf(path)) {
isShow = false
}
if ((!this.TrialConfig.IsPACSConnect || !this.TrialConfig.IsTrialPACSConfirmed) && ~dicomList.indexOf(path)) {
isShow = false
}
return isShow
},
goBack() {
+4 -3
View File
@@ -14,8 +14,8 @@
:on-exceed="handleExceed"
accept=".pdf"
>
<el-button size="small" type="primary" :disabled="btnDisabled || $route.query.ReviewStatus === '1'" >Upload</el-button>
<span slot="tip" class="el-upload__tip">(must be in pdf format. 1/2 pages, please confirm information integrity)</span>
<el-button size="small" type="primary" :disabled="btnDisabled || $route.query.ReviewStatus === '1'" >{{ $t('system:GcpCertificate:upload:Upload') }}</el-button>
<span slot="tip" class="el-upload__tip">{{$t('system:GcpCertificate:tap:must2') }}</span>
</el-upload>
</div>
</template>
@@ -45,6 +45,7 @@ export default {
},
methods: {
initFileList() {
if(!this.doctorId) return
getAttachmentByType(this.doctorId, this.type)
.then(res => {
if (res.IsSuccess) {
@@ -129,7 +130,7 @@ export default {
this.fileList = []
this.$emit('getFileList', '', '')
this.$message({
message: 'Deleted successfully!',
message: this.$t('common:message:deletedSuccessfully'),
type: 'success'
})
}
+4 -4
View File
@@ -9,7 +9,7 @@
:file-list="fileList"
:accept="accept"
>
<el-button size="small" type="primary" :disabled="isDisabled">Upload</el-button>
<el-button size="small" type="primary" :disabled="isDisabled">{{ $t('common:button:upload') }}</el-button>
</el-upload>
</div>
</template>
@@ -39,6 +39,7 @@ export default {
}
},
mounted() {
if(!this.doctorId) return
this.initFileList()
},
methods: {
@@ -143,8 +144,7 @@ export default {
this.$confirm('Sure to remove?', {
type: 'warning',
distinguishCancelAndClose: true,
confirmButtonText: 'Ok',
cancelButtonText: 'Cancel'
}).then(() => {
deleteAttachment(file.Id, file.Path)
.then(res => {
@@ -152,7 +152,7 @@ export default {
this.fileList.splice(this.fileList.findIndex(item => item.Id === file.Id), 1)
this.$emit('getFileList', this.fileList)
this.$message({
message: 'Deleted successfully!',
message: this.$t('common:message:deletedSuccessfully'),
type: 'success'
})
}
@@ -64,7 +64,7 @@
</template>
</el-table-column>
<el-table-column
v-if="hasPermi(['trials:trials-panel:visit:crc-upload:upload']) && allowAddOrEdit"
v-if="hasPermi(['trials:trials-panel:visit:crc-upload:edit']) && allowAddOrEdit"
:label="$t('common:action:action')"
min-width="120"
>
@@ -81,7 +81,6 @@
<!-- 移除 -->
<el-button
v-if="(data.SubmitState*1 < 2 || (data.SubmitState === 2 && data.IsQCConfirmedReupload))"
v-hasPermi="['trials:trials-panel:visit:crc-upload:upload']"
icon="el-icon-delete"
circle
:title="$t('common:button:delete')"
@@ -127,7 +126,7 @@
</el-table-column>
<el-table-column
v-if="hasPermi(['trials:trials-panel:visit:crc-upload:upload']) && allowAddOrEdit"
v-if="hasPermi(['trials:trials-panel:visit:crc-upload:edit']) && allowAddOrEdit"
:label="$t('common:action:action')"
min-width="200"
>
@@ -144,7 +143,6 @@
<!-- 移除 -->
<el-button
v-if="data.SubmitState*1 < 2 || (data.SubmitState === 2 && data.IsQCConfirmedReupload)"
v-hasPermi="['trials:trials-panel:visit:crc-upload:upload']"
icon="el-icon-delete"
circle
:title="$t('common:button:delete')"
@@ -200,7 +198,7 @@
</el-table-column>
<el-table-column
v-if="hasPermi(['trials:trials-panel:visit:crc-upload:upload']) && allowAddOrEdit"
v-if="hasPermi(['trials:trials-panel:visit:crc-upload:edit']) && allowAddOrEdit"
:label="$t('common:action:action')"
min-width="200"
>
@@ -237,7 +235,7 @@
icon="el-icon-download"
size="small"
:loading="downloadLoading"
@click.native.prevent="handleDownloadTpl(cd.ClinicalDataTrialSetId)"
@click.native.prevent="handleDownloadTpl(cd)"
>
{{ $t('trials:uploadClinicalData:button:downloadTemplate') }}
</el-button>
@@ -551,11 +549,8 @@ export default {
})
})
},
handleDownloadTpl(clinicalDataTrialSetId) {
this.downloadLoading = true
DownloadTrialClinicalFile(clinicalDataTrialSetId).then(data => {
this.downloadLoading = false
}).catch(() => { this.downloadLoading = false })
handleDownloadTpl(cd) {
window.open(this.OSSclientConfig.basePath + cd.Path)
}
}
+27
View File
@@ -0,0 +1,27 @@
import Vue from "vue";
import FEEDBACKCOMP from "./index.vue";
const FBConstructor = Vue.extend(FEEDBACKCOMP);
const FB = options => {
const { type, callBack, cancelBack, trialId = null, Id = null, visitTaskId = null } = options;
if (!type) throw `type is requred.but ${type}`
const id = `FB${new Date().getTime()}`;
const instance = new FBConstructor();
instance.id = id;
instance.vm = instance.$mount();
if (instance.vm.visible) return;
document.body.appendChild(instance.vm.$el);
console.log(type);
instance.vm.open({ type, trialId, Id, visitTaskId });
instance.vm.$on("success", (Id) => {
if (callBack) callBack();
});
instance.vm.$on("closed", () => {
document.body.removeChild(instance.vm.$el);
instance.vm.$destroy();
if (cancelBack) cancelBack()
});
return instance.vm;
}
export default FB;
+7
View File
@@ -0,0 +1,7 @@
import FEEDBACKCOMP from "./index.vue";
import FB from "./fun";
export default Vue => {
Vue.component(FEEDBACKCOMP.name, FEEDBACKCOMP);
Vue.prototype.$FB = FB;
};
+400
View File
@@ -0,0 +1,400 @@
<template>
<!--FEEDBACK-->
<div v-if="visible" @click.stop="() => false">
<el-dialog
:visible.sync="visible"
v-dialogDrag
width="540px"
:close-on-click-modal="false"
@close="cancel"
>
<div slot="title">
{{ title }}
</div>
<!-- 项目详情 -->
<div class="trialsBox" v-if="visitTaskId">
<el-form
label-position="right"
:model="form"
:inline="true"
class="trialsForm"
v-if="type === 'detail'"
>
<el-form-item :label="$t('feedBack:trials:code')" style="width: 40%">
<span>{{ form.TrialCode }}</span>
</el-form-item>
<el-form-item :label="$t('feedBack:trials:name')" style="width: 40%">
<span>{{ form.ExperimentName }}</span>
</el-form-item>
<el-form-item
:label="$t('feedBack:trials:siteCode')"
style="width: 40%"
>
<span>{{ form.TrialSiteCode }}</span>
</el-form-item>
<el-form-item :label="$t('feedBack:trials:visit')" style="width: 40%">
<span>{{ form.SubjectVisitName }}</span>
</el-form-item>
</el-form>
</div>
<el-form
ref="feedBackForm"
label-position="right"
:model="form"
:rules="rules"
label-width="100px"
>
<!-- 影像异常tip -->
<p class="tip" v-if="type === 'imgfail'">
<i
class="el-icon-warning-outline"
style="color: #f56c6c; font-size: 24px"
></i>
<span>{{ $t("feedBack:imgfail:tip") }}</span>
</p>
<!-- 问题反馈 -->
<el-form-item
:label="$t('feedBack:form:feedBack')"
prop="QuestionType"
v-if="type === 'feedback' && trialId"
>
<el-select v-model="form.QuestionType" style="width: 100%">
<el-option
v-for="item in QuestionTypeOptions"
:key="item.id"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<!-- 问题反馈 -->
<el-form-item
:label="$t('feedBack:form:feedBack')"
prop="QuestionType"
v-if="type === 'detail'"
>
<span>{{
QuestionTypeOptions.filter(
(item) => item.value === form.QuestionType
)[0].label
}}</span>
</el-form-item>
<!-- 问题描述 -->
<el-form-item
:label="$t('feedBack:form:description')"
prop="QuestionDescription"
>
<el-input
v-model="form.QuestionDescription"
type="textarea"
:rows="4"
:maxlength="500"
:disabled="type === 'detail'"
/>
</el-form-item>
<!-- 截图 -->
<el-form-item :label="$t('feedBack:form:screenshot')" prop="screenshot">
<uploadImage
:path.sync="form.ScreenshotList"
:disabled="type === 'detail'"
ref="uploadImage"
/>
</el-form-item>
<!-- 反馈时间 -->
<el-form-item
:label="$t('feedBack:form:time')"
prop="screenshot"
v-if="type === 'detail'"
>
<span>{{ form.CreateTime }}</span>
</el-form-item>
<!-- 状态 -->
<el-form-item
:label="$t('feedBack:form:status')"
prop="screenshot"
v-if="type === 'detail' && level > 7"
>
<el-switch
v-model="form.State"
active-color="#13ce66"
inactive-color="#ff4949"
:active-value="1"
:inactive-value="0"
:active-text="$fd('FeedBackStatus', 1)"
:inactive-text="$fd('FeedBackStatus', 0)"
:disabled="level < 8 || !isStateChange"
@change="changeState"
>
</el-switch>
</el-form-item>
</el-form>
<div slot="footer" v-if="type !== 'detail' || isImgfail">
<!-- 取消 -->
<el-button size="small" @click.stop="cancel">
{{ $t("feedBack:button:cancel") }}
</el-button>
<!-- 保存 -->
<el-button
type="primary"
size="small"
@click.stop="save"
:loading="loading"
>
{{ $t("feedBack:button:save") }}
</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import uploadImage from "./uploadImage.vue";
import {
addOrUpdateUserFeedBack,
getUserFeedBackInfo,
batchUpdateFeedBackState,
} from "@/api/trials.js";
export default {
name: "FB",
components: { uploadImage },
data() {
return {
title: null,
visible: false,
loading: false,
options: [],
type: null, // detail feedback imgfail
trialId: null, // id
Id: null, // id
visitTaskId: null, // id
isImgfail: false, //
isStateChange: true, //
form: {
Id: null,
SubjectId: null,
SubjectVisitId: null,
QuestionType: 0,
QuestionDescription: null,
State: 0,
TrialSiteId: null,
TrialId: null,
VisitTaskId: null,
ScreenshotList: [],
ScreenshotListStr: null,
},
rules: {
QuestionType: [
{
required: true,
message: this.$t("common:ruleMessage:specify"),
trigger: "blur",
},
],
QuestionDescription: [
{
required: true,
message: this.$t("common:ruleMessage:specify"),
trigger: "blur",
},
{
validator: (rule, value, callback) => {
if (value.length < 5) {
callback(
new Error(this.$t("feedBack:ruleMessage:lengthLimitMin5"))
);
}
callback();
},
trigger: "blur",
},
],
},
};
},
computed: {
level() {
if (this.hasPermi(["role:dev", "role:admin"])) {
return 9;
}
if (this.hasPermi(["role:pm"])) {
return 8;
}
if (this.hasPermi(["role:ir", "role:crc"])) {
return 7;
}
return 0;
},
QuestionTypeOptions() {
if (this.level > 7) {
return [
...this.$d.FeedBackTypeToCRC.filter((item) => item.value > 0),
...this.$d.FeedBackTypeToIR,
];
}
if (this.hasPermi(["role:ir"])) {
return this.$d.FeedBackTypeToIR;
}
if (this.hasPermi(["role:crc"])) {
return this.$d.FeedBackTypeToCRC;
}
return [];
},
},
methods: {
open(data) {
let { type, trialId, Id, visitTaskId } = data;
this.type = type;
this.trialId = trialId;
this.Id = Id;
this.visitTaskId = visitTaskId;
console.log(visitTaskId, "visitTaskId");
if (visitTaskId) {
this.isImgfail = true;
}
console.log(this.isImgfail, "isImgfail");
this.setTypeOption();
if (!Id) {
this.title = this.setTitle();
}
if (Id || visitTaskId) {
this.getInfo(Id, visitTaskId);
}
this.visible = true;
},
cancel() {
this.visible = false;
this.$emit("closed");
},
async save() {
try {
let validate = await this.$refs.feedBackForm.validate();
if (!validate) return;
if (this.trialId) {
this.form.TrialId = this.trialId;
}
if (this.visitTaskId) {
this.form.VisitTaskId = this.visitTaskId;
}
if (this.Id) {
this.form.Id = this.Id;
}
this.loading = true;
let res = await addOrUpdateUserFeedBack(this.form);
this.loading = false;
if (res.IsSuccess) {
this.$emit("success");
this.$message.success(this.$t("feedBack:save:success"));
this.cancel();
}
} catch (err) {
this.loading = false;
console.log(err);
}
},
//
async changeState() {
if (this.isImgfail) return;
try {
let data = {
IdList: [this.Id],
State: this.form.State,
};
let res = await batchUpdateFeedBackState(data);
if (res.IsSuccess) {
this.$message.success(this.$t("feedBack:changeState:success"));
this.$emit("success");
this.cancel();
}
} catch (err) {
console.log(err);
}
},
//
async getInfo(Id, visitTaskId) {
try {
let data = {
Id,
visitTaskId,
};
let res = await getUserFeedBackInfo(data);
if (res.IsSuccess && res.Result) {
this.form = res.Result;
this.Id = res.Result.Id;
if (res.Result.State > 0) {
this.isStateChange = false;
}
if (res.Result.VisitTaskId) {
this.visitTaskId = res.Result.VisitTaskId;
}
let code = this.$fd("UserType", res.Result.UserTypeEnum);
this.title = this.setTitle(code, res.Result.FeedBackFullName);
if (visitTaskId) {
code = `${res.Result.SubjectCode}-${res.Result.SubjectVisitName}`;
this.title = this.setTitle(code, res.Result.FeedBackFullName);
}
this.$refs.uploadImage.initFileList(res.Result.ScreenshotList);
}
} catch (err) {
console.log(err);
}
},
setTypeOption() {
if (!this.trialId) return (this.options = []);
if (this.hasPermi(["role:ir"]))
return (this.option = this.$d.FeedBackTypeToIR);
if (this.hasPermi(["role:crc"]))
return (this.option = this.$d.FeedBackTypeToCRC);
},
setTitle(code, name) {
console.log(code, name);
if (this.hasPermi(["role:pm"]) && this.visitTaskId) {
return `${this.$t("feedBack:form:title:pm2")}(${code}/${name})`;
}
if (this.hasPermi(["role:pm", "role:dev", "role:admin"])) {
return `${this.$t("feedBack:form:title:pm")}(${code},${name})`;
}
if (this.hasPermi(["role:ir", "role:crc"]) && this.type === "detail") {
return `${this.$t("feedBack:form:detail:title")}`;
}
if (this.hasPermi(["role:ir", "role:crc"])) {
return `${this.$t("feedBack:form:title")}`;
}
},
},
};
</script>
<style lang="scss" scoped>
.tip {
width: 86%;
margin: auto;
margin-bottom: 20px;
text-align: left;
padding: 0 10px;
display: flex;
align-items: center;
// border-radius: 5px;
// background-color: #eee;
i {
margin-right: 5px;
}
}
.trialsBox {
margin: auto;
margin-bottom: 20px;
text-align: left;
padding: 0 10px;
display: flex;
align-items: center;
border-radius: 5px;
background-color: #eee;
}
.trialsForm {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
.el-form-item {
margin-bottom: 10px;
}
}
</style>
+219
View File
@@ -0,0 +1,219 @@
<template>
<div class="upload-container">
<el-upload
class="upload-demo"
:class="{ uploadDisabled: disabled ? true : false }"
action
multiple
:http-request="uploadFile"
:before-upload="beforeUpload"
:file-list="fileList"
:on-preview="handlePreview"
:on-remove="remove"
:on-exceed="handleExceed"
accept=".png,.jpg,.jpeg"
list-type="picture-card"
>
<i slot="default" class="el-icon-plus"></i>
<div slot="file" slot-scope="{ file }">
<viewer :ref="file.url" :images="fileList">
<img
class="el-upload-list__item-thumbnail"
:src="`${file.url}`"
alt=""
crossorigin="anonymous"
/>
<span class="el-upload-list__item-actions" v-if="!isUpload">
<span
class="el-upload-list__item-preview"
@click="handlePictureCardPreview(file)"
>
<i class="el-icon-zoom-in"></i>
</span>
<span
class="el-upload-list__item-delete"
v-if="!disabled"
@click="handleRemove(file)"
>
<i class="el-icon-delete"></i>
</span>
</span>
<div class="loadingBox" v-else>
<i class="el-icon-loading" style="color: #fff; margin: auto"></i>
</div>
</viewer>
</div>
</el-upload>
</div>
</template>
<script>
const type = "Statement of Work";
export default {
name: "UploadImage",
props: {
path: {
required: true,
default: () => {
return [];
},
},
disabled: {
required: true,
default: false,
},
},
data() {
return {
fileList: [],
btnDisabled: false,
isUpload: false,
};
},
methods: {
remove(file, fileList) {
// this.$emit("update:path", null);
},
fileToBlob(file) {
// FileReader
const reader = new FileReader();
return new Promise((resolve) => {
// FileReader load
reader.addEventListener("load", (e) => {
let blob;
if (typeof e.target.result === "object") {
blob = new Blob([e.target.result]);
} else {
blob = e.target.result;
}
resolve(blob);
});
// FileReader ArrayBuffer File
reader.readAsArrayBuffer(file);
});
},
// oss
async uploadToOSS(name, file) {
try {
let res = await this.OSSclient.put(
`/System/GeneralDocuments/${name}`,
file
);
return res;
} catch (err) {
console.log(err);
return false;
}
},
initFileList(list) {
if (list && list.length > 0) {
this.fileList = [];
list.forEach((item, index) => {
let name = item.split("/");
this.fileList.push({
name: name[name.length - 1],
path: item,
fullPath: this.OSSclientConfig.basePath + item,
url: this.OSSclientConfig.basePath + item,
uid: `${name[name.length - 1]}${index}`,
});
});
console.log(this.fileList);
}
},
async uploadFile(param) {
var fileName = param.file.name;
this.isUpload = true;
this.btnDisabled = true;
let file = await this.fileToBlob(param.file);
let res = await this.uploadToOSS(fileName, file);
this.btnDisabled = false;
if (!res) return (this.isUpload = false);
this.fileList.push({
url: this.OSSclientConfig.basePath + res.name,
path: res.name,
uid: param.file.uid,
});
this.$emit("update:path", [...this.path, res.name]);
this.isUpload = false;
return false;
},
beforeUpload(file, fileList) {
const isValidFile = this.fileValid(file.name, ["png", "jpg", "jpeg"]);
if (isValidFile) {
// this.fileList = [];
} else {
this.$alert(this.$t("feedBack:uploadImg:format"));
return false;
}
},
handlePreview(file) {
file.fullPath ? window.open(file.fullPath, "_blank") : "";
},
handleExceed(files, fileList) {
this.$message.warning(`Upload is currently limited to 1 file`);
},
fileValid(fileName, typeArr) {
var extendName = fileName
.substring(fileName.lastIndexOf(".") + 1)
.toLocaleLowerCase();
if (typeArr.indexOf(extendName) > -1) {
return true;
} else {
return false;
}
},
handlePictureCardPreview(file) {
this.$refs[file.url].$viewer.show();
},
handleRemove(file) {
let index = this.fileList.findIndex((item) => item.uid === file.uid);
this.fileList.splice(index, 1);
let arr = this.fileList.map((item) => item.path);
this.$emit("update:path", arr);
},
},
};
</script>
<style>
.upload-container .el-upload--text {
border: none;
width: 80px;
height: 30px;
}
.upload-container .el-form-item__label {
font-size: 12px;
}
.upload-container .el-upload-list__item {
font-size: 12px;
}
.logoAMessage {
font-size: 12px;
cursor: pointer;
}
.upload-container .uploadDisabled .el-upload--picture-card {
display: none;
}
.upload-container .el-upload--picture-card {
width: 100px;
height: 100px;
line-height: 100px;
}
.upload-container .el-upload-list--picture-card .el-upload-list__item {
width: 100px;
height: 100px;
line-height: 100px;
}
.loadingBox {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
width: 100px;
height: 100px;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
}
</style>
+23
View File
@@ -0,0 +1,23 @@
import Vue from "vue";
import FEEDBACKCOMP from "./index.vue";
const FBConstructor = Vue.extend(FEEDBACKCOMP);
const FBT = (options = {}) => {
const { data = {} } = options;
// if (!UserId) throw `UserId is requred.but ${UserId}`
const id = `FB${new Date().getTime()}`;
const instance = new FBConstructor();
instance.id = id;
instance.vm = instance.$mount();
if (instance.vm.visible) return;
document.body.appendChild(instance.vm.$el);
instance.vm.open({ ...data });
instance.vm.$on("success", (Id) => {
});
instance.vm.$on("closed", () => {
document.body.removeChild(instance.vm.$el);
instance.vm.$destroy();
});
return instance.vm;
}
export default FBT;
+7
View File
@@ -0,0 +1,7 @@
import FEEDBACKCOMP from "./index.vue";
import FBT from "./fun";
export default Vue => {
Vue.component(FEEDBACKCOMP.name, FEEDBACKCOMP);
Vue.prototype.$FBT = FBT;
};
+57
View File
@@ -0,0 +1,57 @@
<template>
<div v-if="visible" @click.stop="() => false">
<el-dialog
:visible.sync="visible"
v-dialogDrag
width="1200px"
:close-on-click-modal="false"
@close="cancel"
>
<div slot="title">
{{ title }}
</div>
<feedBackTable :trialId="trialId" />
</el-dialog>
</div>
</template>
<script>
import feedBackTable from "@/views/feedBack/index.vue";
export default {
name: "FBT",
components: { feedBackTable },
data() {
return {
title: null,
visible: false,
trialId: null,
};
},
computed: {},
methods: {
open(data) {
let { code, name, trialId } = data;
this.title = this.setTitle(code, name);
this.trialId = trialId;
this.visible = true;
},
cancel() {
this.visible = false;
this.$emit("closed");
},
setTitle(code, name) {
if (this.hasPermi(["role:pm"])) {
return `${this.$t("feedBack:table:title:pm")}(${code},${name})`;
}
if (this.hasPermi(["role:ir", "role:crc"])) {
return `${this.$t("feedBack:table:title")}`;
}
},
},
};
</script>
<style lang="scss" scoped>
::v-deep .el-dialog__body {
padding-bottom: 0;
height: 500px;
}
</style>
@@ -0,0 +1,95 @@
<template>
<base-model :config="model_cfg">
<div slot="dialog-body">
<el-table :data="modelList" style="width: 100%" height="300">
<!--检查编号-->
<el-table-column
prop="StudyCode"
:label="$t('trials:uploadImage:table:StudyCode')"
/>
<!--检查类型-->
<el-table-column
prop="ModalityForEdit"
:label="$t('trials:uploadImage:table:ModalityForEdit')"
/>
<!--检查模态-->
<el-table-column
prop="Modalities"
:label="$t('trials:uploadImage:table:Modalities')"
/>
<!--检查部位-->
<el-table-column
prop="BodyPartForEdit"
:label="$t('trials:uploadImage:table:BodyPartForEdit')"
/>
<!--序列数量-->
<el-table-column
prop="SeriesCount"
:label="$t('trials:uploadImage:table:SeriesCount')"
/>
<!--图像数量-->
<el-table-column
prop="InstanceCount"
:label="$t('trials:uploadImage:table:InstanceCount')"
/>
<!--检查时间-->
<el-table-column
prop="StudyTime"
:label="$t('trials:uploadImage:table:StudyTime')"
min-width="130"
/>
<el-table-column
:label="$t('common:action:action')"
fixed="right"
width="80"
>
<template slot-scope="scope">
<!--预览--->
<el-button
circle
icon="el-icon-view"
:title="$t('trials:uploadImage:button:download')"
@click.stop="preview(scope.row)"
/>
</template>
</el-table-column>
</el-table>
</div>
</base-model>
</template>
<script>
import baseModel from "@/components/BaseModel";
import { getToken } from "@/utils/auth";
export default {
name: "studyView",
props: {
model_cfg: {
type: Object,
default: () => {
return {};
},
},
modelList: {
type: Array,
default: () => {
return [];
},
},
},
components: {
"base-model": baseModel,
},
methods: {
//
preview(row) {
var token = getToken();
const routeData = this.$router.resolve({
path: `/showdicom?studyId=${row.Id}&TokenKey=${token}&type=Study`,
});
window.open(routeData.href, "_blank");
},
},
};
</script>
<style lang="scss" scoped>
</style>
@@ -0,0 +1,769 @@
<template>
<div class="uploadList">
<el-divider content-position="left">{{
$t("trials:uploadImage:button:uploadTableTitle")
}}</el-divider>
<div class="top" style="margin-bottom: 10px">
<el-button
type="primary"
size="small"
v-if="!isLoad"
style="position: relative;
}"
>
<span style="opacity: 0">{{
$t("trials:uploadImage:button:selectFolder")
}}</span>
<label for="file">
{{ $t("trials:uploadImage:button:selectFolder") }}
</label>
</el-button>
<el-button
type="primary"
size="small"
class="el-icon-upload2"
@click.stop="notUp"
v-else
>
{{ $t("trials:uploadImage:button:selectFolder") }}
</el-button>
<input
type="file"
name="file"
id="file"
ref="file"
style="display: none"
webkitdirectory
multiple
@change="beginScanFiles($event)"
/>
</div>
<!--本地影像检查-->
<el-table
:data="uploadList"
style="width: 100%"
v-adaptive="{ bottomOffset: 50 }"
>
<el-table-column type="index" width="40" />
<!--检查信息-->
<el-table-column min-width="200" show-overflow-tooltip>
<template slot="header">
<el-tooltip placement="top">
<div slot="content">
{{ $t("trials:uploadImage:table:studyDetail1") }}<br />
{{ $t("trials:uploadImage:table:studyDetail2") }}<br />
{{ $t("trials:uploadedDicoms:table:studyDate") }}
</div>
<span>{{ $t("trials:uploadImage:table:studyInfo") }}</span>
</el-tooltip>
</template>
<template slot-scope="scope">
<div style="line-height: 15px">
<div>
<div>
<span>
<span style="font-weight: 500">Acc:</span>
<span
:class="{
colorOfRed: !scope.row.dicomInfo.AccessionNumber,
}"
>{{ scope.row.dicomInfo.AccessionNumber || "N/A" }}</span
>
</span>
</div>
<div style="display: inline-block; margin-right: 2px">
<span v-if="scope.row.dicomInfo.Modalities.length > 0">
{{ scope.row.dicomInfo.Modalities.join("、") }},
</span>
<span v-else style="color: #f44336">N/A,</span>
</div>
<div style="display: inline-block; margin-right: 2px">
<span v-if="scope.row.SeriesInstanceUidList.length"
>{{ scope.row.SeriesInstanceUidList.length }} Series,
</span>
<span v-else style="color: #f44336">N/A,</span>
</div>
<div style="display: inline-block">
<span v-if="scope.row.count"
>{{ scope.row.count }} Instances
</span>
<span v-else style="color: #f44336">N/A</span>
</div>
</div>
<div>
<div style="display: inline-block; margin-right: 2px">
<span v-if="scope.row.dicomInfo.seriesBodyPartExamined">
{{ scope.row.dicomInfo.seriesBodyPartExamined }},
</span>
<span v-else style="color: #f44336">N/A, </span>
</div>
<div style="display: inline-block">
<span v-if="scope.row.dicomInfo.StudyDescription">
{{ scope.row.dicomInfo.StudyDescription }}</span
>
<span v-else style="color: #f44336">N/A</span>
</div>
</div>
<div>
{{ scope.row.dicomInfo.StudyTime }}
</div>
</div>
</template>
</el-table-column>
<!--患者信息-->
<el-table-column min-width="130" show-overflow-tooltip>
<template slot="header">
<el-tooltip placement="top">
<div slot="content">
{{ $t("trials:uploadImage:table:pId") }}<br />
{{ $t("trials:uploadImage:table:patientName") }}<br />
{{ $t("trials:uploadImage:table:pInfo") }}
</div>
<span>{{ $t("trials:uploadImage:table:patientInfo") }}</span>
</el-tooltip>
</template>
<template slot-scope="scope">
<div style="line-height: 15px">
<div>
<span v-if="scope.row.dicomInfo.PatientId"
><span style="font-weight: 500">PID: </span
>{{ scope.row.dicomInfo.PatientId }}</span
>
<span v-else style="color: #f44336">N/A</span>
</div>
<div>
<span
:class="[scope.row.dicomInfo.PatientName ? '' : 'colorOfRed']"
>
{{ scope.row.dicomInfo.PatientName || "N/A" }}
</span>
</div>
<div>
<span
:class="[scope.row.dicomInfo.PatientSex ? '' : 'colorOfRed']"
>
{{ scope.row.dicomInfo.PatientSex || "N/A" }},
</span>
<span
:class="[scope.row.dicomInfo.PatientAge ? '' : 'colorOfRed']"
>
{{ scope.row.dicomInfo.PatientAge || "N/A" }},
</span>
<span
:class="[
scope.row.dicomInfo.PatientBirthDate ? '' : 'colorOfRed',
]"
>
{{ scope.row.dicomInfo.PatientBirthDate || "N/A" }}
</span>
</div>
</div>
</template>
</el-table-column>
<!--上传进度-->
<el-table-column
prop="schedule"
:label="$t('trials:uploadImage:table:schedule')"
min-width="150"
>
<template slot-scope="scope">
<el-progress
color="#409eff"
:percentage="scope.row.schedule"
v-if="scope.row.schedule || scope.row.schedule === 0"
/>
</template>
</el-table-column>
<!--上传状态-->
<el-table-column
prop="status"
:label="$t('trials:uploadImage:table:status')"
min-width="120"
>
<template slot-scope="scope">
<el-tag
:type="
['warning', 'success', 'danger', 'primary', 'success', 'danger'][
scope.row.status
]
"
v-if="scope.row.status || scope.row.status === 0"
>{{ $fd("UploadStatus", scope.row.status) }}
</el-tag>
</template>
</el-table-column>
<!--已有/成功/失败-->
<el-table-column
prop="scheduleNum"
:label="$t('trials:uploadImage:table:scheduleNum')"
min-width="140"
>
<template slot-scope="scope">
<span v-if="scope.row.count">{{
`${scope.row.count} /${scope.row.successCount} / ${scope.row.failCount}`
}}</span>
</template>
</el-table-column>
<el-table-column
:label="$t('common:action:action')"
fixed="right"
width="140"
>
<!-- <template slot-scope="scope">
</template> -->
</el-table-column>
</el-table>
</div>
</template>
<script>
import {
preArchiveDicomStudy,
addOrUpdateArchiveTaskStudy,
} from "@/api/load.js";
import { parseDicom, getThumbnail, dicomToOSS } from "@/utils/parseDicom.js";
import store from "@/store";
export default {
name: "uploadList",
props: {
SopInstanceUidList: {
type: Array,
default: () => {
return [];
},
},
StudyInstanceUidList: {
type: Array,
default: () => {
return [];
},
},
UploadStudyList: {
type: Array,
default: () => {
return [];
},
},
visible: {
type: Boolean,
default: false,
},
},
data() {
return {
isLoad: false,
uploadList: [], //
dicomList: [], //
requestNum: 6,
hasOtherStudy: false, //
isClose: false,
};
},
watch: {
isLoad() {
store.dispatch("trials/setUnLock", this.isLoad);
if (!this.isLoad) {
this.$refs.file.value = null;
if (this.dicomList.some((item) => item.isUpload === 3)) {
this.$confirm(this.$t("trials:uploadImage:confirm:failUpload"), {
type: "warning",
distinguishCancelAndClose: true,
confirmButtonText: this.$t("common:button:confirm"),
cancelButtonText: this.$t("common:button:cancel"),
})
.then(() => {
this.againUpload();
})
.catch((err) => {
console.log(err);
});
}
}
},
},
methods: {
//
againUpload() {
for (let i = 0; i < this.uploadList.length; i++) {
let item = this.uploadList[i];
if (item.status > 2) continue;
item.status = 0;
item.failCount = 0;
item.schedule = Math.floor(
((item.successCount + item.failCount) / item.count) * 100
);
let arr = this.dicomList.filter(
(dicom) =>
dicom.StudyInstanceUid === item.StudyInstanceUid &&
dicom.isUpload === 3
);
arr.forEach((item) => (item.isUpload = 0));
this.setUploadTask(arr);
}
},
async setUploadTask(arr) {
let num = arr.length > this.requestNum ? this.requestNum : arr.length;
let funArr = [];
for (let i = 0; i < num; i++) {
funArr.push(this.handleUploadTask(arr, i));
}
if (funArr.length > 0) {
let res = await Promise.all(funArr);
}
},
//
async preArchiveDicomStudy(post, index) {
try {
let res = await preArchiveDicomStudy(post);
if (res.IsSuccess) {
let item = this.uploadList[index];
item.StudyMonitorId = res.Result;
let arr = this.dicomList.filter(
(dicom) => dicom.StudyInstanceUid === item.StudyInstanceUid
);
this.setUploadTask(arr);
} else {
return false;
}
} catch (err) {
console.log(err);
return false;
}
},
//
async beginScanFiles(e) {
let files = e.target.files;
try {
this.dicomList = [];
this.hasOtherStudy = false;
for (var i = 0; i < files.length; ++i) {
if (files[i].name.indexOf("DICOMDIR") >= 0) continue;
let dicom = await parseDicom(files[i]);
if (!dicom) continue;
let has = this.dicomList.some(
(item) => item.SopInstanceUid === dicom.SopInstanceUid
);
if (has) continue;
has = this.StudyInstanceUidList.some(
(item) => item.StudyInstanceUid === dicom.StudyInstanceUid
);
if (!has) {
this.hasOtherStudy = true;
continue;
}
if (this.SopInstanceUidList.includes(dicom.SopInstanceUid)) continue;
this.isLoad = true;
dicom.file = files[i];
dicom.isUpload = 0;
this.StudyInstanceUidList.some((item) => {
if (item.StudyInstanceUid === dicom.StudyInstanceUid) {
dicom.params = {
TrialId: this.$route.query.trialId,
SubjectId: item.SubjectId,
VisitTaskId: item.VisitTaskId,
SourceSubjectVisitId: item.SourceSubjectVisitId,
};
let uploadHas = this.uploadList.some((uploadData) => {
if (uploadData.StudyInstanceUid === dicom.StudyInstanceUid) {
if (uploadData.status > 0) {
uploadData.count = 1;
uploadData.successCount = 0;
uploadData.failCount = 0;
uploadData.schedule = 0;
uploadData.status = 0;
uploadData.FileSize = dicom.file.size;
uploadData.SeriesInstanceUidList = [
dicom.SeriesInstanceUid,
];
uploadData.dicomInfo = {
AccessionNumber: dicom.AccessionNumber,
Modalities: dicom.Modalities,
seriesBodyPartExamined: dicom.seriesBodyPartExamined,
StudyDescription: dicom.StudyDescription,
StudyTime: this.getTime(dicom.StudyDate, dicom.StudyTime),
PatientName: dicom.PatientName,
PatientId: dicom.PatientId,
PatientAge: dicom.PatientAge,
PatientSex: dicom.PatientSex,
PatientBirthDate: dicom.PatientBirthDate,
};
} else {
uploadData.FileSize += dicom.file.size;
uploadData.count++;
}
if (
!uploadData.SeriesInstanceUidList.includes(
dicom.SeriesInstanceUid
)
) {
uploadData.SeriesInstanceUidList.push(
dicom.SeriesInstanceUid
);
}
}
return uploadData.StudyInstanceUid === dicom.StudyInstanceUid;
});
if (!uploadHas) {
let uploadData = {
TrialId: this.$route.query.trialId,
SubjectId: item.SubjectId,
SourceSubjectVisitId: item.SourceSubjectVisitId,
StudyId: dicom.StudyId,
StudyInstanceUid: dicom.StudyInstanceUid,
FileSize: dicom.file.size,
count: 1,
successCount: 0,
failCount: 0,
schedule: 0,
status: 0,
SeriesInstanceUidList: [dicom.SeriesInstanceUid],
IsDicomReUpload: false,
dicomInfo: {
AccessionNumber: dicom.AccessionNumber,
Modalities: dicom.Modalities,
seriesBodyPartExamined: dicom.seriesBodyPartExamined,
StudyDescription: dicom.StudyDescription,
StudyTime: this.getTime(dicom.StudyDate, dicom.StudyTime),
PatientName: dicom.PatientName,
PatientId: dicom.PatientId,
PatientAge: dicom.PatientAge,
PatientSex: dicom.PatientSex,
PatientBirthDate: dicom.PatientBirthDate,
},
};
if (
this.UploadStudyList.some(
(d) => d.StudyInstanceUid === uploadData.StudyInstanceUid
)
) {
uploadData.IsDicomReUpload = true;
}
this.uploadList.push(uploadData);
}
}
return item.StudyInstanceUid === dicom.StudyInstanceUid;
});
this.dicomList.push(dicom);
}
if (this.dicomList.length <= 0 && this.hasOtherStudy) {
let confirm = await this.$confirm(
this.$t("trials:uploadImage:confirmMessage:failSubject"),
{
type: "warning",
distinguishCancelAndClose: true,
confirmButtonText: this.$t("common:button:confirm"),
cancelButtonText: this.$t("common:button:cancel"),
}
);
if (confirm !== "confirm") return false;
this.$refs.file.click();
return false;
}
let funArr = [];
for (let i = 0; i < this.uploadList.length; i++) {
let item = this.uploadList[i];
let data = {
TrialId: item.TrialId,
SubjectId: item.SubjectId,
SubjectVisitId: item.SourceSubjectVisitId,
FileSize: item.FileSize,
IsDicomReUpload: item.IsDicomReUpload,
FileCount: item.count,
};
funArr.push(this.preArchiveDicomStudy(data, i));
}
if (funArr && funArr.length > 0) {
let res = await Promise.all(funArr);
}
} catch (err) {
console.log(err);
this.$refs.file.value = null;
}
},
//
async handleUploadTask(arr, index) {
if (this.isClose) return false;
arr[index].isUpload = 1;
let path = `/${arr[index].params.TrialId}/TaskImage/${
arr[index].params.SubjectId
}/${arr[index].params.VisitTaskId}/${
arr[index].StudyInstanceUid
}/${this.getGuid(
arr[index].StudyInstanceUid +
arr[index].SeriesInstanceUid +
arr[index].SOPInstanceUid +
arr[index].params.TrialId +
arr[index].params.VisitTaskId
)}`;
let uploadDicom = this.uploadList.filter(
(item) => item.StudyInstanceUid === arr[index].StudyInstanceUid
)[0];
let res = await dicomToOSS(arr[index].file, path);
if (res) {
arr[index].path = res;
uploadDicom.successCount++;
arr[index].isUpload = 2;
} else {
uploadDicom.status = 2;
uploadDicom.failCount++;
arr[index].isUpload = 3;
}
uploadDicom.schedule = Math.floor(
((uploadDicom.successCount + uploadDicom.failCount) /
uploadDicom.count) *
100
);
if (uploadDicom.schedule >= 100) {
if (uploadDicom.successCount === uploadDicom.count) {
uploadDicom.status = 1;
if (!uploadDicom.Study) {
let res = await this.formatDicom(arr, arr[index].StudyInstanceUid);
if (res) {
uploadDicom.Study = res[arr[index].StudyId];
uploadDicom.status = 3;
}
}
try {
res = await addOrUpdateArchiveTaskStudy(uploadDicom);
if (res.IsSuccess) {
uploadDicom.status = 4;
this.$emit("getList");
let ind = this.uploadList.findIndex(
(item) => item.StudyInstanceUid === uploadDicom.StudyInstanceUid
);
this.uploadList.splice(ind, 1);
} else {
uploadDicom.status = 5;
}
let flag = this.dicomList.every((item) => item.isUpload > 1);
if (flag) this.isLoad = false;
} catch (err) {
uploadDicom.status = 5;
let flag = this.dicomList.every((item) => item.isUpload > 1);
if (flag) this.isLoad = false;
}
} else if (
uploadDicom.count ===
uploadDicom.successCount + uploadDicom.failCount
) {
let flag = this.dicomList.every((item) => item.isUpload > 1);
if (flag) this.isLoad = false;
}
}
let ind = arr.findIndex((item) => !item.isUpload);
if (ind >= 0) {
return this.handleUploadTask(arr, ind);
} else {
return false;
}
},
//
async formatDicom(arr, StudyInstanceUid) {
let studyObj = {};
for (let i = 0; i < arr.length; i++) {
let dicom = arr[i];
if (dicom.StudyInstanceUid !== StudyInstanceUid) continue;
let thumbnailPath = `/${dicom.params.TrialId}/TaskImage/${dicom.params.SubjectId}/${dicom.params.VisitTaskId}/${dicom.StudyInstanceUid}/${dicom.SeriesInstanceUid}.png`;
if (!studyObj[dicom.StudyId]) {
studyObj[dicom.StudyId] = {
StudyId: dicom.StudyId,
StudyInstanceUid: dicom.StudyInstanceUid,
StudyTime: this.getTime(dicom.StudyDate, dicom.StudyTime),
Modalities: dicom.Modalities,
Description: dicom.StudyDescription,
SeriesCount: 1,
InstanceCount: 1,
InstitutionName: dicom.InstitutionName,
PatientId: dicom.PatientId,
PatientName: dicom.PatientName,
PatientAge: dicom.PatientAge,
PatientSex: dicom.PatientSex,
AccessionNumber: dicom.AccessionNumber,
PatientBirthDate: dicom.PatientBirthDate,
AcquisitionTime: dicom.AcquisitionTime,
AcquisitionNumber: dicom.AcquisitionNumber,
TriggerTime: dicom.TriggerTime,
BodyPartExamined: dicom.BodyPartExamined,
SeriesList: [
{
StudyInstanceUid: dicom.StudyInstanceUid,
SeriesInstanceUid: dicom.SeriesInstanceUid,
SeriesNumber: dicom.SeriesNumber,
SeriesTime: this.getTime(dicom.SeriesDate, dicom.SeriesTime),
Modality: dicom.Modality,
Description: dicom.SeriesDescription,
InstanceCount: 1,
SliceThickness: dicom.SliceThickness,
ImagePositionPatient: dicom.ImagePosition,
ImageOrientationPatient: dicom.ImageOrientation,
BodyPartExamined: dicom.seriesBodyPartExamined,
SequenceName: dicom.SequenceName,
ProtocolName: dicom.ProtocolName,
ImagerPixelSpacing: dicom.ImagePixelSpacing,
AcquisitionTime: dicom.AcquisitionTime,
AcquisitionNumber: dicom.AcquisitionNumber,
TriggerTime: dicom.TriggerTime,
ImageResizePath: await getThumbnail(
dicom.file,
thumbnailPath,
dicom
),
InstanceList: [
{
StudyInstanceUid: dicom.StudyInstanceUid,
SeriesInstanceUid: dicom.SeriesInstanceUid,
SopInstanceUid: dicom.SopInstanceUid,
InstanceNumber: dicom.ImageOrInstanceNumber,
InstanceTime: this.getTime(
dicom.ContentDate,
dicom.ContentTime
),
ImageRows: dicom.Rows || 0,
ImageColumns: dicom.Columns || 0,
SliceLocation: dicom.SliceLocation,
SliceThickness: dicom.SliceThickness,
NumberOfFrames: dicom.NumberOfFrames || 0,
PixelSpacing: dicom.PixelSpacing,
ImagerPixelSpacing: dicom.ImagePixelSpacing,
FrameOfReferenceUID: dicom.FrameOfReferenceUID,
WindowCenter: dicom.WindowCenter,
WindowWidth: dicom.WindowWidth,
Path: dicom.path,
HtmlPath: "",
},
],
},
],
};
} else {
let seriesHas = studyObj[dicom.StudyId].SeriesList.some((item) => {
if (item.SeriesInstanceUid === dicom.SeriesInstanceUid) {
item.InstanceCount++;
let instance = {
StudyInstanceUid: dicom.StudyInstanceUid,
SeriesInstanceUid: dicom.SeriesInstanceUid,
SopInstanceUid: dicom.SopInstanceUid,
InstanceNumber: dicom.ImageOrInstanceNumber,
InstanceTime: this.getTime(
dicom.ContentDate,
dicom.ContentTime
),
ImageRows: dicom.Rows || 0,
ImageColumns: dicom.Columns || 0,
SliceLocation: dicom.SliceLocation,
SliceThickness: dicom.SliceThickness,
NumberOfFrames: dicom.NumberOfFrames || 0,
PixelSpacing: dicom.PixelSpacing,
ImagerPixelSpacing: dicom.ImagePixelSpacing,
FrameOfReferenceUID: dicom.FrameOfReferenceUID,
WindowCenter: dicom.WindowCenter,
WindowWidth: dicom.WindowWidth,
Path: dicom.path,
HtmlPath: "",
};
item.InstanceList.push(instance);
}
return item.SeriesInstanceUid === dicom.SeriesInstanceUid;
});
if (!seriesHas) {
studyObj[dicom.StudyId].SeriesCount++;
let series = {
StudyInstanceUid: dicom.StudyInstanceUid,
SeriesInstanceUid: dicom.SeriesInstanceUid,
SeriesNumber: dicom.SeriesNumber,
SeriesTime: this.getTime(dicom.SeriesDate, dicom.SeriesTime),
Modality: dicom.Modality,
Description: dicom.SeriesDescription,
InstanceCount: 1,
SliceThickness: dicom.SliceThickness,
ImagePositionPatient: dicom.ImagePosition,
ImageOrientationPatient: dicom.ImageOrientation,
BodyPartExamined: dicom.seriesBodyPartExamined,
SequenceName: dicom.SequenceName,
ProtocolName: dicom.ProtocolName,
ImagerPixelSpacing: dicom.ImagePixelSpacing,
AcquisitionTime: dicom.AcquisitionTime,
AcquisitionNumber: dicom.AcquisitionNumber,
TriggerTime: dicom.TriggerTime,
ImageResizePath: await getThumbnail(
dicom.file,
thumbnailPath,
dicom
),
InstanceList: [
{
StudyInstanceUid: dicom.StudyInstanceUid,
SeriesInstanceUid: dicom.SeriesInstanceUid,
SopInstanceUid: dicom.SopInstanceUid,
InstanceNumber: dicom.ImageOrInstanceNumber,
InstanceTime: this.getTime(
dicom.ContentDate,
dicom.ContentTime
),
ImageRows: dicom.Rows || 0,
ImageColumns: dicom.Columns || 0,
SliceLocation: dicom.SliceLocation,
SliceThickness: dicom.SliceThickness,
NumberOfFrames: dicom.NumberOfFrames || 0,
PixelSpacing: dicom.PixelSpacing,
ImagerPixelSpacing: dicom.ImagePixelSpacing,
FrameOfReferenceUID: dicom.FrameOfReferenceUID,
WindowCenter: dicom.WindowCenter,
WindowWidth: dicom.WindowWidth,
Path: dicom.path,
HtmlPath: "",
},
],
};
studyObj[dicom.StudyId].SeriesList.push(series);
}
studyObj[dicom.StudyId].InstanceCount++;
}
}
return studyObj;
},
// dicom
getTime(date, time) {
let studyTime = "";
if (date) {
date = `${date.substring(0, 4)}-${date.substring(
4,
6
)}-${date.substring(6, 8)}`;
}
if (time) {
time = `${time.substring(0, 2)}:${time.substring(
2,
4
)}:${time.substring(4, 6)}`;
}
if (date) {
studyTime = time ? `${date} ${time}` : `${date} 00:00:00`;
}
return studyTime;
},
},
beforeDestroy() {
this.isClose = true;
store.dispatch("trials/setUnLock", false);
},
};
</script>
<style lang="scss" scoped>
.colorOfRed {
color: #f44336;
}
label {
cursor: pointer;
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
padding: 9px 15px;
}
</style>
+612
View File
@@ -0,0 +1,612 @@
<template>
<el-dialog
:visible.sync="visible"
:fullscreen="true"
:close-on-click-modal="false"
custom-class="upload-dialog"
:before-close="beforeClose"
class="uploadImage"
>
<span slot="title">{{ title }}</span>
<el-divider content-position="left">{{
$t("trials:uploadImage:button:uploadTableTitle1")
}}</el-divider>
<!--已上传影像检查-->
<el-table
:data="list"
style="width: 100%"
height="300"
v-adaptive="{ bottomOffset: 50, notAdaptive: isUpload }"
:loading="loading"
>
<!--受试者-->
<el-table-column
prop="SubjectCode"
:label="$t('trials:uploadImage:table:subjectCode')"
/>
<!--任务名称-->
<el-table-column
prop="TaskBlindName"
:label="$t('trials:uploadImage:table:taskBlindName')"
/>
<!--原始检查数-->
<el-table-column
prop="OrginalStudyList"
:label="$t('trials:uploadImage:table:orginalStudyListNum')"
>
<template slot-scope="scope">
<el-button
v-if="
scope.row.OrginalStudyList &&
scope.row.OrginalStudyList.length >= 1
"
type="text"
@click="handleOpenDialog(scope.row, 'OrginalStudyList')"
>
<span>{{ scope.row.OrginalStudyList.length }}</span>
</el-button>
<span v-else>0</span>
</template>
</el-table-column>
<!--后处理检查数-->
<el-table-column
prop="UploadStudyList"
:label="$t('trials:uploadImage:table:uploadStudyListNum')"
>
<template slot-scope="scope">{{
scope.row.UploadStudyList && Array.isArray(scope.row.UploadStudyList)
? scope.row.UploadStudyList.length
: 0
}}</template>
</el-table-column>
<el-table-column
:label="$t('common:action:action')"
fixed="right"
width="140"
>
<template slot-scope="scope">
<!--下载--->
<!-- <el-button
v-if="!isUpload && Criterion.ImageDownloadEnum > 0"
circle
icon="el-icon-download"
:title="$t('trials:uploadImage:button:download')"
@click.stop="downloadImage(scope.row)"
/> -->
<!--删除--->
<el-button
v-if="isUpload"
circle
icon="el-icon-delete"
:title="$t('trials:uploadImage:button:delete')"
@click.stop="remove(scope.row)"
/>
</template>
</el-table-column>
</el-table>
<upload-list
v-if="Criterion.ImageUploadEnum > 0 && isUpload"
:StudyInstanceUidList="StudyInstanceUidList"
:SopInstanceUidList="SopInstanceUidList"
:UploadStudyList="UploadStudyList"
@getList="getList"
/>
<study-view
v-if="model_cfg.visible"
:model_cfg="model_cfg"
:modelList="modelList"
/>
</el-dialog>
</template>
<script>
import uploadList from "./components/upload-list.vue";
import studyView from "./components/study-view.vue";
import { getSubjectImageUploadList, deleteTaskStudy } from "@/api/load.js";
import { downloadImage } from "@/utils/uploadZip.js";
import store from "@/store";
export default {
name: "uploadImage",
props: {
visible: {
type: Boolean,
default: false,
},
SubjectId: {
type: String,
default: "",
},
Criterion: {
type: Object,
default: () => {
return {};
},
},
status: {
type: String,
default: "upload",
},
},
components: {
"upload-list": uploadList,
"study-view": studyView,
},
data() {
return {
list: [],
StudyInstanceUidList: [],
SopInstanceUidList: [],
UploadStudyList: [],
//
model_cfg: {
visible: false,
showClose: true,
width: "1000px",
title: "",
appendToBody: true,
},
modelList: [],
};
},
computed: {
title() {
let str = this.$t("trials:uploadImage:title:uploadImages");
if (this.status === "download") {
str = this.$t("trials:uploadImage:title:uploadImagesDownLoad");
}
return str;
},
isUpload() {
return this.status === "upload";
},
},
created() {
this.getList();
},
methods: {
beforeClose() {
this.$emit("update:visible", false);
},
notUp() {
this.$confirm(this.$t("trials:uploadImage:confirmMessage:notUp"), {
type: "warning",
distinguishCancelAndClose: true,
confirmButtonText: this.$t("common:button:confirm"),
cancelButtonText: this.$t("common:button:cancel"),
});
},
//
async getList() {
try {
let params = {
SubjectId: this.SubjectId,
TrialReadingCriterionId: this.Criterion.TrialReadingCriterionId,
};
this.loading = true;
let res = await getSubjectImageUploadList(params);
this.loading = false;
if (res.IsSuccess) {
this.StudyInstanceUidList = [];
this.SopInstanceUidList = [];
this.UploadStudyList = [];
this.list = res.Result;
res.Result.forEach((item) => {
if (item.OrginalStudyList && Array.isArray(item.OrginalStudyList)) {
item.OrginalStudyList.forEach((data) => {
data.SubjectId = item.SubejctId;
data.VisitTaskId = item.VisitTaskId;
data.SourceSubjectVisitId = item.SourceSubjectVisitId;
this.StudyInstanceUidList.push(data);
});
}
if (item.UploadStudyList && Array.isArray(item.UploadStudyList)) {
item.UploadStudyList.forEach((data) => {
data.SopInstanceUidList &&
this.SopInstanceUidList.push(...data.SopInstanceUidList);
this.UploadStudyList.push(data);
});
}
});
}
} catch (err) {
console.log(err);
this.loading = false;
}
},
//
async remove(item) {
try {
let confirm = await this.$confirm(
this.$t("trials:uploadImage:confirm:delMessage"),
{
type: "warning",
distinguishCancelAndClose: true,
confirmButtonText: this.$t("common:button:confirm"),
cancelButtonText: this.$t("common:button:cancel"),
}
);
if (confirm !== "confirm") return;
let params = {
VisitTaskId: item.VisitTaskId,
};
let res = await deleteTaskStudy(params);
if (res.IsSuccess) {
this.getList();
this.$message.success(
this.$t("trials:uploadImage:message:delSuccess")
);
}
} catch (err) {
console.log(err);
}
},
//
handleOpenDialog(item, list) {
this.model_cfg.title = `${item.SubejctCode || ""}>${item.TaskBlindName}`;
this.modelList = item[list];
this.model_cfg.visible = true;
},
//
async downloadImage(item) {
let zipName = "压缩包.zip";
let InstanceInfoList = [
{
Id: "e634352c-6465-32ba-04b3-824ec8d346a8",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/e634352c-6465-32ba-04b3-824ec8d346a8",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 1,
},
{
Id: "d4ad1dd2-747b-6de7-8ad4-3e81c58943dd",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/d4ad1dd2-747b-6de7-8ad4-3e81c58943dd",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 2,
},
{
Id: "6a1d1d12-2b4a-0368-c7e1-d44f7180b280",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/6a1d1d12-2b4a-0368-c7e1-d44f7180b280",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 3,
},
{
Id: "7a8fb1b4-9ea8-1189-4ca6-b9a9b9547a39",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/7a8fb1b4-9ea8-1189-4ca6-b9a9b9547a39",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 4,
},
{
Id: "8d00be19-5ac5-c608-dbd0-41f84cfacd95",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/8d00be19-5ac5-c608-dbd0-41f84cfacd95",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 5,
},
{
Id: "729ded91-0eca-78f2-1c17-5182d4f27e3a",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/729ded91-0eca-78f2-1c17-5182d4f27e3a",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 6,
},
{
Id: "9e2fd28c-72fe-bb66-e0ce-40115cd82260",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/9e2fd28c-72fe-bb66-e0ce-40115cd82260",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 7,
},
{
Id: "9b31613f-3c9e-28ad-fd9e-7001a69e09b5",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/9b31613f-3c9e-28ad-fd9e-7001a69e09b5",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 8,
},
{
Id: "4982b453-d068-7e56-2acd-a361d8584f35",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/4982b453-d068-7e56-2acd-a361d8584f35",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 9,
},
{
Id: "8279cf5a-2551-43ea-3fe4-673e88ba7e5a",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/8279cf5a-2551-43ea-3fe4-673e88ba7e5a",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 10,
},
{
Id: "6424e9c5-d31b-9388-3b64-a56705ab6fc8",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/6424e9c5-d31b-9388-3b64-a56705ab6fc8",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 11,
},
{
Id: "a73cf3f9-defa-0c22-dfdc-8c5bfb93c9a7",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/a73cf3f9-defa-0c22-dfdc-8c5bfb93c9a7",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 12,
},
{
Id: "dbfaafea-f721-0a93-37c6-69bcc0d957c3",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/dbfaafea-f721-0a93-37c6-69bcc0d957c3",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 13,
},
{
Id: "52000ac1-6a5b-83e2-5468-4dfdf394e455",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/52000ac1-6a5b-83e2-5468-4dfdf394e455",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 14,
},
{
Id: "de34a347-41f4-1018-a710-48d81fa9aadc",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/de34a347-41f4-1018-a710-48d81fa9aadc",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 15,
},
{
Id: "251d6a13-26b7-935b-d765-0c5db1ed7dfc",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/251d6a13-26b7-935b-d765-0c5db1ed7dfc",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 16,
},
{
Id: "b22e93c8-3f6a-484a-a32b-f7626689f8da",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/b22e93c8-3f6a-484a-a32b-f7626689f8da",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 17,
},
{
Id: "6517400b-d4b5-db65-d026-8c06c40bf244",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/6517400b-d4b5-db65-d026-8c06c40bf244",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 18,
},
{
Id: "8e70df99-525a-4ecd-5cf1-6c32698eaa3f",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/8e70df99-525a-4ecd-5cf1-6c32698eaa3f",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 19,
},
{
Id: "7df907f2-b6a6-fd03-67ab-be86c497d412",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/7df907f2-b6a6-fd03-67ab-be86c497d412",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 20,
},
{
Id: "ba31ba5b-728e-8301-273d-459fd3c65a43",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/ba31ba5b-728e-8301-273d-459fd3c65a43",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 21,
},
{
Id: "7528c70c-5ba1-59c1-413c-7bfc984c0066",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/7528c70c-5ba1-59c1-413c-7bfc984c0066",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 22,
},
{
Id: "15dd574d-fc82-c5b7-fefb-497346d4abbb",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/15dd574d-fc82-c5b7-fefb-497346d4abbb",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 23,
},
{
Id: "6cd76aca-91fa-64ce-6077-af48c5e5b18b",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/6cd76aca-91fa-64ce-6077-af48c5e5b18b",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 24,
},
{
Id: "2f0f9f4e-12b8-a6a8-d3f9-f43e2055653d",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/2f0f9f4e-12b8-a6a8-d3f9-f43e2055653d",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 25,
},
{
Id: "3c49f379-8548-67cd-1333-dde28219c6e9",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/3c49f379-8548-67cd-1333-dde28219c6e9",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 26,
},
{
Id: "910f43c8-123a-0753-aaf7-11081eef4268",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/910f43c8-123a-0753-aaf7-11081eef4268",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 27,
},
{
Id: "ffad6b36-74aa-1c7d-01eb-18524da91f6e",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/ffad6b36-74aa-1c7d-01eb-18524da91f6e",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 28,
},
{
Id: "9e2bf22d-8734-62ae-881a-7404064a95ce",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/9e2bf22d-8734-62ae-881a-7404064a95ce",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 29,
},
{
Id: "eef8b291-ffdf-dbfb-244d-5e63dc5b8cc7",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/eef8b291-ffdf-dbfb-244d-5e63dc5b8cc7",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 30,
},
{
Id: "12b0de3a-243c-78b9-b006-82f2cc633a0f",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/12b0de3a-243c-78b9-b006-82f2cc633a0f",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 31,
},
{
Id: "4341ea87-7d54-2608-184e-01e5c976ce9f",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/4341ea87-7d54-2608-184e-01e5c976ce9f",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 32,
},
{
Id: "4db2bac2-18eb-0589-d520-f297b2840e1d",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/4db2bac2-18eb-0589-d520-f297b2840e1d",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 33,
},
{
Id: "9442c2a3-0972-67f7-afc3-6f1a47abefab",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/9442c2a3-0972-67f7-afc3-6f1a47abefab",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 34,
},
{
Id: "a7fb75b0-0b09-5340-70cf-a11afd84b1ec",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/a7fb75b0-0b09-5340-70cf-a11afd84b1ec",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 35,
},
{
Id: "753d7795-451a-bd32-69ea-fd58c1e89d63",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/753d7795-451a-bd32-69ea-fd58c1e89d63",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 36,
},
{
Id: "33bf7274-de0a-e8f9-f97a-c58fb2ea3aaf",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/33bf7274-de0a-e8f9-f97a-c58fb2ea3aaf",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 37,
},
{
Id: "adadae31-37a1-818d-3721-09a1d371c6a5",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/adadae31-37a1-818d-3721-09a1d371c6a5",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 38,
},
{
Id: "f64e8b0d-d2ab-b112-5705-92c23cfc5df6",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/f64e8b0d-d2ab-b112-5705-92c23cfc5df6",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 39,
},
{
Id: "781088b0-5afd-6eb3-5f87-9bfec210d490",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/781088b0-5afd-6eb3-5f87-9bfec210d490",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 40,
},
{
Id: "56df4cef-8053-bff3-21f7-1b1841a3d6e6",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/56df4cef-8053-bff3-21f7-1b1841a3d6e6",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 41,
},
{
Id: "a3e3dab9-7a61-f822-d113-42f46bc5e8ce",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/a3e3dab9-7a61-f822-d113-42f46bc5e8ce",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 42,
},
{
Id: "1cc195b9-e498-179d-b927-6d706266decb",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/1cc195b9-e498-179d-b927-6d706266decb",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 43,
},
{
Id: "7dca834f-d959-898e-a0cb-5c8244c4c4a9",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/7dca834f-d959-898e-a0cb-5c8244c4c4a9",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 44,
},
{
Id: "13eeba83-2e93-800e-e934-a56061633c64",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/13eeba83-2e93-800e-e934-a56061633c64",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 45,
},
{
Id: "971f0a62-92a3-6d04-53c5-51fa9155e28c",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/971f0a62-92a3-6d04-53c5-51fa9155e28c",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 46,
},
{
Id: "2959d06c-5ac7-f3b9-63d4-1a56e3974fc7",
Path: "/01000000-c0a8-0242-ff9a-08dc8a84633c/Image/01000000-c0a8-0242-2179-08dc8a9e55b4/01000000-c0a8-0242-7f99-08dc8abdc649/01000000-c0a8-0242-89ca-08dc8abdc65d/1.2.840.113619.2.334.3.2831181473.554.1419910103.185/2959d06c-5ac7-f3b9-63d4-1a56e3974fc7",
HtmlPath: "",
NumberOfFrames: 0,
InstanceNumber: 47,
},
];
let path = "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com";
let files = new Array();
for (let i = 0; i < InstanceInfoList.length; i++) {
let item = InstanceInfoList[i];
let obj = {
name: "file" + i,
url: path + item.Path,
};
files.push(obj);
}
store.dispatch("trials/setUnLock", true);
let res = await downloadImage(zipName, files);
store.dispatch("trials/setUnLock", false);
},
},
beforeDestroy() {
store.dispatch("trials/setUnLock", false);
},
};
</script>
<style lang="scss" scoped>
::v-deep .el-dialog {
.el-dialog__header {
padding-top: 15px;
}
}
.uploadImage {
background-color: #fff;
}
</style>
+8 -6
View File
@@ -1,6 +1,5 @@
<script>
export default
{
export default {
processSignature: {
LogicalConfigConfirmation: 101, //
ProcessConfigConfirmation: 102, //
@@ -9,6 +8,8 @@ export default
ProcessConfigUpdates: 105, //
ExpeditedConfigUpdates: 106, //
QCConfirmation: 107, //
DicomConfigConfirmation: 110, // DICOM AE
DicomConfigUpdates: 111, // DICOM AE
ClinicalDataConfirmation: 201, //
AgreeToRetransmit: 202, //
QCSingleReviewPassed: 203, //
@@ -25,8 +26,9 @@ export default
ImageAssessmentReportConfirmation: 214, //
MedicalAuditConfirmation: 109, //
ReadingUnitConfirmation: 108, //
MedicalAudit: 215,//
HeavyReadingApproval: 216,//
}
}
MedicalAudit: 215, //
HeavyReadingApproval: 216, //
ResetAndAsyncCriterion: 218, //
},
};
</script>
+3 -2
View File
@@ -4,11 +4,12 @@ import {
} from 'element-ui/src/utils/resize-event'
// 设置表格高度
const doResize = async(el, binding, vnode) => {
const doResize = async (el, binding, vnode) => {
// 获取表格Dom对象
const { componentInstance: $table } = await vnode
// 获取调用传递过来的数据
const { value } = binding
if (value && value.notAdaptive) return;
// 获取距底部距离(用于展示页码等信息)
const bottomOffset = (value && value.bottomOffset) || 40
if (!$table) return
@@ -24,7 +25,7 @@ export default {
// 初始化设置
bind(el, binding, vnode) {
// 设置resize监听方法
el.resizeListener = async() => {
el.resizeListener = async () => {
await doResize(el, binding, vnode)
}
// 绑定监听方法到addResizeListener
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 98 KiB

+52
View File
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="_图层_2" data-name="图层 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 454.72 126.1">
<defs>
<style>
.cls-1 {
fill: #0093dd;
}
.cls-2 {
fill: #5b5b5b;
}
</style>
</defs>
<g id="_图层_1-2" data-name="图层 1">
<g>
<path class="cls-1" d="m162.51,68.1h14.37c5.59,0,9.79,4.03,8.73,8.37l-1.38,5.61h-44.66c-2.41,0-4.3-.44-5.66-1.32-1.36-.82-1.84-2.17-1.42-4.06L148.68,6.71c.52-1.95,1.97-3.56,4.32-4.82,2.36-1.26,5.16-1.89,8.41-1.89h16.82l-15.72,68.1Z"/>
<path class="cls-1" d="m204.2,25.41c.52-1.76,1.86-3.21,4.01-4.34,2.15-1.13,4.69-1.7,7.62-1.7h15.88l-11.32,49.4c-.94,3.97-3.83,7.19-8.64,9.68-4.82,2.49-10.43,3.73-16.82,3.73h-3.61l12.89-56.77ZM219.29.38h17.6l-2.04,8.78c-.42,1.26-1.36,2.28-2.83,3.07-1.47.79-3.2,1.18-5.19,1.18h-19.02l1.89-8.12c.31-1.45,1.39-2.63,3.22-3.54,1.83-.91,3.95-1.37,6.36-1.37Z"/>
<path class="cls-1" d="m262.55,68.1h14.37c5.59,0,9.79,4.03,8.73,8.37l-1.38,5.61h-44.66c-2.41,0-4.3-.44-5.66-1.32-1.36-.82-1.84-2.17-1.42-4.06L248.72,6.71c.52-1.95,1.97-3.56,4.32-4.82,2.36-1.26,5.16-1.89,8.41-1.89h16.82l-15.72,68.1Z"/>
<path class="cls-1" d="m304.25,25.41c.52-1.76,1.86-3.21,4.01-4.34,2.15-1.13,4.69-1.7,7.62-1.7h15.88l-11.32,49.4c-.94,3.97-3.83,7.19-8.64,9.68-4.82,2.49-10.43,3.73-16.82,3.73h-3.61l12.89-56.77ZM319.33.38h17.6l-2.04,8.78c-.42,1.26-1.36,2.28-2.83,3.07-1.47.79-3.2,1.18-5.19,1.18h-19.02l1.89-8.12c.31-1.45,1.39-2.63,3.22-3.54,1.83-.91,3.95-1.37,6.36-1.37Z"/>
<g>
<path class="cls-2" d="m0,101.17h2.51v19.36H0v-19.36Z"/>
<path class="cls-2" d="m28.37,110.12v10.4h-2.4v-9.54c0-2.31-.64-3.65-2.9-3.65-1.76,0-3.26.5-3.91,2.65v10.54h-2.4v-9.54c0-2.31-.56-3.65-2.76-3.65-1.87,0-3.24.42-3.99,2.73v10.46h-2.4v-15.06h2.4v1.98c.92-1.79,2.54-2.26,4.35-2.26,2.37,0,3.74.95,4.38,2.45.89-1.95,2.84-2.45,4.69-2.45,3.51,0,4.94,2.04,4.94,4.94Z"/>
<path class="cls-2" d="m45.28,109.84v10.68h-2.04l-.36-2.29c-.86,1.65-3.12,2.57-5.38,2.57-3.6,0-5.19-1.65-5.19-4.49,0-3.57,2.37-4.8,5.97-4.8h4.6v-1.26c0-1.81-.64-3.07-3.71-3.07-1,0-2.23.11-3.32.33v-2.12c1.12-.14,2.34-.22,3.43-.22,4.74,0,6,1.95,6,4.66Zm-2.4,6.08v-2.48h-4.43c-2.48,0-3.65.5-3.65,2.85,0,1.65.81,2.51,2.93,2.51,2.51,0,4.38-1.09,5.16-2.87Z"/>
<path class="cls-2" d="m63.05,105.46v14c0,4.16-2.26,6.64-7.36,6.64-1.28,0-2.71-.17-3.65-.36v-2.04c1.14.22,2.4.33,3.68.33,3.35,0,4.94-1.37,4.94-4.83v-1.51c-.61,1.76-1.98,2.82-4.88,2.82-5.02,0-6.25-3.07-6.25-7.67,0-4.16,1.23-7.67,6.25-7.67,3.04,0,4.29,1.31,4.88,3.1v-2.82h2.4Zm-2.32,7.39c0-3.46-1-5.66-4.63-5.66s-4.02,2.73-4.02,5.66c0,3.15.47,5.66,4.02,5.66s4.63-2.06,4.63-5.66Z"/>
<path class="cls-2" d="m67.9,101.28c0-1.26.39-1.42,1.45-1.42,1,0,1.42.17,1.42,1.42s-.42,1.42-1.42,1.42c-1.06,0-1.45-.2-1.45-1.42Zm.22,4.18h2.4v15.06h-2.4v-15.06Z"/>
<path class="cls-2" d="m87.87,110.09v10.43h-2.43v-9.54c0-2.31-.47-3.65-2.87-3.65-1.9,0-3.74.36-4.57,3.01v10.18h-2.4v-15.06h2.4v2.15c.92-1.92,2.98-2.43,4.83-2.43,3.93,0,5.05,2.04,5.05,4.91Z"/>
<path class="cls-2" d="m105.5,105.46v14c0,4.16-2.26,6.64-7.36,6.64-1.28,0-2.71-.17-3.65-.36v-2.04c1.14.22,2.4.33,3.68.33,3.35,0,4.94-1.37,4.94-4.83v-1.51c-.61,1.76-1.98,2.82-4.88,2.82-5.02,0-6.25-3.07-6.25-7.67,0-4.16,1.23-7.67,6.25-7.67,3.04,0,4.29,1.31,4.88,3.1v-2.82h2.4Zm-2.32,7.39c0-3.46-1-5.66-4.63-5.66s-4.02,2.73-4.02,5.66c0,3.15.47,5.66,4.02,5.66s4.63-2.06,4.63-5.66Z"/>
<path class="cls-2" d="m129.47,103.4h-5.63v17.13h-2.51v-17.13h-5.66v-2.23h13.81v2.23Z"/>
<path class="cls-2" d="m138.31,105.18l-.08,2.18h-.33c-1.92,0-3.82.64-4.66,3.32v9.85h-2.4v-15.06h2.4v2.73c.95-2.51,2.98-3.01,4.8-3.01h.28Z"/>
<path class="cls-2" d="m141.19,101.28c0-1.26.39-1.42,1.45-1.42,1,0,1.42.17,1.42,1.42s-.42,1.42-1.42,1.42c-1.06,0-1.45-.2-1.45-1.42Zm.22,4.18h2.4v15.06h-2.4v-15.06Z"/>
<path class="cls-2" d="m160.85,109.84v10.68h-2.04l-.36-2.29c-.86,1.65-3.12,2.57-5.38,2.57-3.6,0-5.19-1.65-5.19-4.49,0-3.57,2.37-4.8,5.97-4.8h4.6v-1.26c0-1.81-.64-3.07-3.71-3.07-1,0-2.23.11-3.32.33v-2.12c1.12-.14,2.34-.22,3.43-.22,4.74,0,6,1.95,6,4.66Zm-2.4,6.08v-2.48h-4.43c-2.48,0-3.65.5-3.65,2.85,0,1.65.81,2.51,2.93,2.51,2.51,0,4.38-1.09,5.16-2.87Z"/>
<path class="cls-2" d="m165.96,117.48v-18.16h2.4v17.54c0,1.51.42,1.81,1.39,1.81.33,0,.75-.03,1.14-.14v1.98c-.45.11-.92.17-1.59.17-2.23,0-3.35-.95-3.35-3.21Z"/>
<path class="cls-2" d="m181.13,101.17h4.02l4.94,12.47h.17l4.94-12.47h3.96v19.36h-2.51v-16.82h-.17l-4.96,12.44h-2.73l-5.02-12.44h-.17v16.82h-2.45v-19.36Z"/>
<path class="cls-2" d="m216.23,109.84v10.68h-2.04l-.36-2.29c-.86,1.65-3.12,2.57-5.38,2.57-3.6,0-5.19-1.65-5.19-4.49,0-3.57,2.37-4.8,5.97-4.8h4.6v-1.26c0-1.81-.64-3.07-3.71-3.07-1,0-2.23.11-3.32.33v-2.12c1.12-.14,2.34-.22,3.43-.22,4.74,0,6,1.95,6,4.66Zm-2.4,6.08v-2.48h-4.43c-2.48,0-3.65.5-3.65,2.85,0,1.65.81,2.51,2.93,2.51,2.51,0,4.38-1.09,5.16-2.87Z"/>
<path class="cls-2" d="m233.61,110.09v10.43h-2.43v-9.54c0-2.31-.47-3.65-2.87-3.65-1.9,0-3.74.36-4.57,3.01v10.18h-2.4v-15.06h2.4v2.15c.92-1.92,2.98-2.43,4.83-2.43,3.93,0,5.05,2.04,5.05,4.91Z"/>
<path class="cls-2" d="m250.54,109.84v10.68h-2.04l-.36-2.29c-.86,1.65-3.12,2.57-5.38,2.57-3.6,0-5.19-1.65-5.19-4.49,0-3.57,2.37-4.8,5.97-4.8h4.6v-1.26c0-1.81-.64-3.07-3.71-3.07-1,0-2.23.11-3.32.33v-2.12c1.12-.14,2.34-.22,3.43-.22,4.74,0,6,1.95,6,4.66Zm-2.4,6.08v-2.48h-4.43c-2.48,0-3.65.5-3.65,2.85,0,1.65.81,2.51,2.93,2.51,2.51,0,4.38-1.09,5.16-2.87Z"/>
<path class="cls-2" d="m268.31,105.46v14c0,4.16-2.26,6.64-7.36,6.64-1.28,0-2.71-.17-3.65-.36v-2.04c1.14.22,2.4.33,3.68.33,3.35,0,4.94-1.37,4.94-4.83v-1.51c-.61,1.76-1.98,2.82-4.88,2.82-5.02,0-6.25-3.07-6.25-7.67,0-4.16,1.23-7.67,6.25-7.67,3.04,0,4.29,1.31,4.88,3.1v-2.82h2.4Zm-2.32,7.39c0-3.46-1-5.66-4.63-5.66s-4.02,2.73-4.02,5.66c0,3.15.47,5.66,4.02,5.66s4.63-2.06,4.63-5.66Z"/>
<path class="cls-2" d="m285.22,113.24l-10.21.64c.03,3.29,1.17,4.8,4.83,4.8,1.65,0,3.57-.42,4.71-.98v2.2c-.86.45-2.93.89-5.08.89-4.44,0-6.97-1.81-6.97-7.81s2.54-7.81,6.83-7.81c5.13,0,6.02,3.38,6.02,6.3,0,.42-.06,1.06-.14,1.76Zm-2.23-1.73c0-2.32-.39-4.35-3.65-4.35-3.46,0-4.24,1.87-4.32,4.94l7.98-.59Z"/>
<path class="cls-2" d="m310.27,110.12v10.4h-2.4v-9.54c0-2.31-.64-3.65-2.9-3.65-1.76,0-3.26.5-3.91,2.65v10.54h-2.4v-9.54c0-2.31-.56-3.65-2.76-3.65-1.87,0-3.24.42-3.99,2.73v10.46h-2.4v-15.06h2.4v1.98c.92-1.79,2.54-2.26,4.35-2.26,2.37,0,3.74.95,4.38,2.45.89-1.95,2.84-2.45,4.69-2.45,3.51,0,4.94,2.04,4.94,4.94Z"/>
<path class="cls-2" d="m327.03,113.24l-10.21.64c.03,3.29,1.17,4.8,4.83,4.8,1.65,0,3.57-.42,4.71-.98v2.2c-.86.45-2.93.89-5.08.89-4.44,0-6.97-1.81-6.97-7.81s2.54-7.81,6.83-7.81c5.13,0,6.03,3.38,6.03,6.3,0,.42-.06,1.06-.14,1.76Zm-2.23-1.73c0-2.32-.39-4.35-3.65-4.35-3.46,0-4.24,1.87-4.32,4.94l7.98-.59Z"/>
<path class="cls-2" d="m343.6,110.09v10.43h-2.43v-9.54c0-2.31-.47-3.65-2.87-3.65-1.9,0-3.74.36-4.57,3.01v10.18h-2.4v-15.06h2.4v2.15c.92-1.92,2.98-2.43,4.83-2.43,3.93,0,5.05,2.04,5.05,4.91Z"/>
<path class="cls-2" d="m354.9,118.52v2.04c-.59.08-1.06.14-1.7.14-3.32,0-4.52-.81-4.52-4.77v-8.45h-2.23v-2.01h2.23v-3.57h2.4v3.57h3.74v2.01h-3.74v8.31c0,2.34.33,2.9,2.18,2.9.67,0,1.12-.06,1.65-.17Z"/>
<path class="cls-2" d="m364.19,120.05v-2.32c1.14.42,3.46.86,5.75.86,2.9,0,4.41-.86,4.41-3.26s-.84-3.01-4.46-3.88c-3.96-.95-5.41-1.92-5.41-5.36s2.06-5.24,6.44-5.24c1.87,0,3.93.33,4.85.7v2.29c-1.12-.42-3.07-.78-4.83-.78-2.71,0-3.99.53-3.99,3.04,0,1.81.47,2.45,3.96,3.26,4.32,1,5.88,2.15,5.88,5.94s-2.4,5.49-6.86,5.49c-2.4,0-4.8-.42-5.75-.75Z"/>
<path class="cls-2" d="m379.71,124.04c2.62,0,3.68-1.12,4.43-3.54l-6.02-15.03h2.59l4.6,12.5h.17l4.35-12.5h2.43l-5.41,14.56c-1.42,3.77-2.71,6.08-7.14,6.08v-2.06Z"/>
<path class="cls-2" d="m394.18,120.22v-2.06c1.06.31,2.98.59,4.35.59,2.29,0,3.49-.56,3.49-2.31s-.5-2.15-3.38-2.82c-3.32-.75-4.21-1.81-4.21-4.35s1.84-4.07,5.41-4.07c1.45,0,3.07.22,3.79.5l-.17,2.04c-.86-.33-2.2-.59-3.6-.59-2.12,0-3.18.47-3.18,2.18,0,1.53.53,1.87,2.87,2.4,3.46.78,4.71,1.73,4.71,4.63s-2.04,4.35-5.72,4.35c-1.45,0-3.54-.22-4.38-.47Z"/>
<path class="cls-2" d="m414.77,118.52v2.04c-.59.08-1.06.14-1.7.14-3.32,0-4.52-.81-4.52-4.77v-8.45h-2.23v-2.01h2.23v-3.57h2.4v3.57h3.74v2.01h-3.74v8.31c0,2.34.33,2.9,2.18,2.9.67,0,1.12-.06,1.65-.17Z"/>
<path class="cls-2" d="m429.67,113.24l-10.21.64c.03,3.29,1.17,4.8,4.83,4.8,1.65,0,3.57-.42,4.71-.98v2.2c-.86.45-2.93.89-5.08.89-4.44,0-6.97-1.81-6.97-7.81s2.54-7.81,6.83-7.81c5.13,0,6.02,3.38,6.02,6.3,0,.42-.06,1.06-.14,1.76Zm-2.23-1.73c0-2.32-.39-4.35-3.65-4.35-3.46,0-4.24,1.87-4.32,4.94l7.98-.59Z"/>
<path class="cls-2" d="m454.72,110.12v10.4h-2.4v-9.54c0-2.31-.64-3.65-2.9-3.65-1.76,0-3.26.5-3.91,2.65v10.54h-2.4v-9.54c0-2.31-.56-3.65-2.76-3.65-1.87,0-3.24.42-3.99,2.73v10.46h-2.4v-15.06h2.4v1.98c.92-1.79,2.54-2.26,4.35-2.26,2.37,0,3.74.95,4.38,2.45.89-1.95,2.84-2.45,4.69-2.45,3.51,0,4.94,2.04,4.94,4.94Z"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.8 KiB

+1
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="1710814433132" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6202" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M509.48 9.666C232.874 9.666 8.666 233.874 8.666 510.48c0 276.618 224.206 500.818 500.814 500.818 276.618 0 500.818-224.202 500.818-500.818 0-276.606-224.2-500.814-500.818-500.814z m0 896.198c-218.384 0-395.378-176.994-395.378-395.382 0-218.384 176.996-395.378 395.378-395.378 218.388 0 395.382 176.996 395.382 395.378 0.002 218.388-176.992 395.382-395.382 395.382z m26.362-390.848v-189.042c0-29.136-23.578-52.718-52.718-52.718s-52.716 23.582-52.716 52.718v210.87c0 0.18 0.012 0.356 0.014 0.534 0.006 0.686 0.018 1.37 0.052 2.054 0.026 0.52 0.072 1.036 0.112 1.55 0.026 0.334 0.042 0.666 0.076 1 0.06 0.632 0.142 1.258 0.226 1.884 0.028 0.21 0.05 0.422 0.08 0.63 0.102 0.698 0.222 1.388 0.35 2.076 0.026 0.136 0.046 0.276 0.074 0.412 0.142 0.732 0.304 1.458 0.476 2.178 0.022 0.098 0.042 0.196 0.068 0.292 0.182 0.744 0.382 1.48 0.596 2.21l0.068 0.244c0.22 0.74 0.46 1.474 0.71 2.202l0.078 0.228c0.256 0.732 0.532 1.454 0.818 2.17 0.032 0.076 0.06 0.154 0.09 0.23 0.292 0.718 0.602 1.428 0.926 2.13l0.104 0.228c0.334 0.716 0.684 1.424 1.05 2.124 0.032 0.058 0.06 0.12 0.09 0.178 0.386 0.732 0.79 1.454 1.208 2.164l0.044 0.078a52.9 52.9 0 0 0 8.716 11.054l148.508 148.506c20.594 20.598 53.956 20.598 74.548 0 20.586-20.586 20.586-53.95 0-74.542l-133.648-133.642z" fill="#FFFFFF" p-id="6203"></path></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

+10 -11
View File
@@ -23,23 +23,22 @@
<div style="margin-left:20px;">
<el-dropdown class="dropdown-container" trigger="click">
<span class="el-dropdown-link">
{{ name }}
<span v-if="userTypeShortName">({{ userTypeShortName }})</span>
{{ `${name} (${userTypeShortName})` }}
<!-- {{ name }}
<span v-if="userTypeShortName"> ({{ userTypeShortName }}) </span> -->
<i class="el-icon-caret-bottom" />
</span>
<el-dropdown-menu slot="dropdown" class="user-dropdown">
<el-dropdown-item v-if="!isReviewer">
<span style="display:block;" @click="editInfo">Edit Info</span>
</el-dropdown-item>
<el-dropdown-item>
<span style="display:block;" @click="account">Account</span>
<span style="display:block;" @click="editInfo">{{$t('system:navbar:button:Profile')}}</span>
</el-dropdown-item>
<el-dropdown-item divided>
<span style="display:block;" @click="logout">Log Out</span>
<span style="display:block;" @click="logout">{{$t('system:navbar:button:Log Out')}}</span>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<TopLang></TopLang>
</div>
</div>
</div>
@@ -50,12 +49,15 @@ import {mapGetters, mapMutations} from 'vuex'
import Breadcrumb from '@/components/Breadcrumb'
import Hamburger from '@/components/Hamburger'
import Screenfull from '@/components/Screenfull'
import TopLang from './topLang'
export default {
components: {
Breadcrumb,
Hamburger,
Screenfull
Screenfull,
TopLang
},
data() {
return {
@@ -89,9 +91,6 @@ export default {
editInfo() {
this.$router.push({ name: 'BaiscInfo' })
},
account() {
this.$router.push({ name: 'Account' })
}
}
}
</script>
+54
View File
@@ -0,0 +1,54 @@
<template>
<el-dropdown
style="height:50px;line-height: 60px;"
@command="handleSetLanguage"
>
<span class="el-dropdown-link">
<svg-icon icon-class="language" style="font-size:25px;margin:0 10px;" />
<!-- {{ language==='zh'?'语言:中文':'Language: English' }} -->
<!-- <i class="el-icon-arrow-down el-icon--right" /> -->
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
:disabled="language==='zh'"
command="zh"
>中文
</el-dropdown-item>
<el-dropdown-item
:disabled="language==='en'"
command="en"
>English
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
<script>
import { mapGetters, mapMutations } from 'vuex'
export default {
name: 'TopLang',
data() {
return {}
},
computed: {
...mapGetters({
language: 'language'
})
},
methods: {
...mapMutations({ setLanguage: 'lang/setLanguage' }),
handleSetLanguage(lang) {
this.$i18n.locale = lang
this.setLanguage(lang)
this.$updateDictionary()
window.location.reload()
}
}
}
</script>
<style lang="scss" scoped>
</style>
+150 -74
View File
@@ -3,7 +3,8 @@ import Vue from 'vue'
import 'normalize.css/normalize.css' // A modern alternative to CSS resets
import ElementUI, { MessageBox } from 'element-ui'
import { getBasicDataAllSelect, getFrontInternationalizationList } from '@/api/dictionary/dictionary'
import { getBasicDataAllSelect, getFrontInternationalizationList, getCurrentPublishInfo } from '@/api/dictionary/dictionary'
import { sendMFAEmail } from "@/api/user.js";
import { resetReadingRestTime } from '@/api/trials/reading'
// import 'element-ui/lib/theme-chalk/index.css'
import './assets/css/theme-blue/index.css' // 浅绿色主题
@@ -24,7 +25,6 @@ Vue.use(VueClipboard)
// import htmlToPdf from './utils/htmlToPdf'
// Vue.use(htmlToPdf)
import permission from './utils/permission'
import { OSSclient } from './utils/oss'
Vue.use(permission)
import Viewer from 'v-viewer'
@@ -44,7 +44,6 @@ Viewer.setDefaults({
'rotatable': true,
'scalable': true,
'transition': true,
'fullscreen': true,
'keyboard': true,
'url': 'data-source'
}
@@ -57,14 +56,22 @@ Vue.use(hasPermi)
// Vue.use(ElementUI, { locale, size: 'medium' })
import upload from '@/components/element-ui/upload'
Vue.use(upload)
import Preview from '@/components/Preview/index'
Vue.use(Preview)
import MFA from '@/components/MFA/index'
Vue.use(MFA)
import FB from '@/components/feedBack/index'
Vue.use(FB)
import FBT from '@/components/feedBackTable/index'
Vue.use(FBT)
import adaptive from '@/directive/adaptive/index'
// 表格自适应指令
Vue.use(adaptive)
import dialogDrag from '@/directive/dialogDrag'
// 窗口拖拽
Vue.use(dialogDrag)
if(!String.prototype.replaceAll){
String.prototype.replaceAll = function(str, newStr){
if (!String.prototype.replaceAll) {
String.prototype.replaceAll = function (str, newStr) {
// 正则表达式
if (Object.prototype.toString.call(str).toLowerCase() === '[object regexp]') {
return this.replace(str, newStr)
@@ -80,6 +87,7 @@ import DictTag from '@/components/DictTag'
import DictData from '@/components/DictData'
import { getBasicDataSelect } from '@/api/dictionary/dictionary'
import { checkConfig } from '@/const/check/index'
import { getTrialBodyPartList } from "@/api/trials/setting";
// 全局方法挂载
var $q = params
Vue.prototype.checkConfig = checkConfig
@@ -96,12 +104,14 @@ Vue.prototype.selectDictLabel = selectDictLabel
// Vue.prototype.download = download
Vue.prototype.handleTree = handleTree
Vue.prototype.$getObjectName = (url) => {
// console.log(url)
var value = url
var str = value.split("//"); //https://进行分割,
var index = str[1].indexOf("/")+1; //indexOf 获取第一个斜杠的索引,
// console.log(str[1].substring(index)); //substring 截取,
return '/' + str[1].substring(index)
// console.log(url,'url')
// console.log(Vue.prototype.OSSclientConfig.viewEndpoint,'url')
var value = url;
let basePath = Vue.prototype.OSSclientConfig.viewEndpoint;
if (Vue.prototype.OSSclientConfig.ObjectStoreUse === 'AliyunOSS') {
basePath = Vue.prototype.OSSclientConfig.endPoint.split('https://').length > 1 ? Vue.prototype.OSSclientConfig.endPoint.split('https://')[1] : Vue.prototype.OSSclientConfig.endPoint;
}
return value.split(basePath)[1];
}
Vue.prototype.getGuid = (text) => {
text = md5(text)
@@ -117,14 +127,15 @@ Vue.prototype.getGuid = (text) => {
t9 = text.substr(16, 4)
t10 = text.substr(20, 12)
// console.log(`${t4+t3+t2+t1}-${t6+t5}-${t8+t7}-${t9}-${t10}`)
return `${t4+t3+t2+t1}-${t6+t5}-${t8+t7}-${t9}-${t10}`
return `${t4 + t3 + t2 + t1}-${t6 + t5}-${t8 + t7}-${t9}-${t10}`
}
Vue.prototype.$validatePassword = (rule, value, callback) => {
var lang = zzSessionStorage.getItem('lang')?zzSessionStorage.getItem('lang'):'zh'
var lang = zzSessionStorage.getItem('lang') ? zzSessionStorage.getItem('lang') : 'zh'
/* eslint-disable */
var reg1 = eval(process.env.VUE_APP_PASSWORD_FOR_PERMISSION) ? new RegExp(`${process.env.VUE_APP_PASSWORD_FOR_REGULAR}`) : /.*/g; //密码必须是8位以上、必须含有字母、数字、特殊符号
if (!reg1.test(value)) {
callback(lang==='zh' ? new Error("密码必须包含:1)8 – 32 个字符;2)至少1个数字;3) 至少1个大写字母;4)至少1个小写字母;5)至少1个特殊字符 (~!-@#$%^&*_+?)") : new Error('Passwords must have: 1) 8 - 32 characters; 2) At least 1 number; 3) At least 1 uppercase letter; 4) At least 1 lowercase letter; 5) At least 1 special character (~!-@#$%^&*_+?) '))
callback(
new Error(_vm.$t('env:regExp:formatPassword')))
} else {
callback();
}
@@ -158,12 +169,18 @@ Vue.prototype.fileToBlob = (file) => {
}
var _vm
async function VueInit () {
async function VueInit() {
var params
var res
if (~window.location.href.indexOf('/readingDicoms') || ~window.location.href.indexOf('/noneDicomReading') || ~window.location.href.indexOf('/criterionquestions') || ~window.location.href.indexOf('/petct')) {
params = $q('TrialReadingCriterionId')
res = await getBasicDataAllSelect(params)
} else if (~window.location.href.indexOf('/ecrfPreview')) {
params = $q('SystemReadingCriterionId')
res = await getBasicDataAllSelect(params, true)
} else {
res = await getBasicDataAllSelect(params)
}
var res = await getBasicDataAllSelect(params)
var Internationalization = await getFrontInternationalizationList()
Vue.prototype.$tl = Internationalization.Result
let zhMessages = {}, enMessages = {}
@@ -173,6 +190,27 @@ async function VueInit () {
zhMessages[v.Code] = v.ValueCN
enMessages[v.Code] = v.Value
})
// 获取版本信息
let PublishInfo = await getCurrentPublishInfo();
Vue.prototype.$version = PublishInfo.Result;
// 获取检查部位
Vue.prototype.$getBodyPart = (id) => {
return new Promise(async (resolve, reject) => {
try {
let params = {
TrialId: id
}
let BodyPart = await getTrialBodyPartList(params)
if (BodyPart.IsSuccess) {
resolve(BodyPart.Result);
} else {
reject(BodyPart);
}
} catch (err) {
reject(err)
}
})
}
i18n.mergeLocaleMessage('zh', zhMessages)
i18n.mergeLocaleMessage('en', enMessages)
Vue.use(ElementUI, {
@@ -181,14 +219,14 @@ async function VueInit () {
})
let d = function (code) {
var dictInfo = res.Result
var lang = zzSessionStorage.getItem('lang')?zzSessionStorage.getItem('lang'):'zh'
var lang = zzSessionStorage.getItem('lang') ? zzSessionStorage.getItem('lang') : 'zh'
try {
for (var code in dictInfo) {
var dictList = (dictInfo[code] && dictInfo[code].length > 0) ? dictInfo[code].map(dict => {
var dictList = (dictInfo[code] && dictInfo[code].length > 0) ? dictInfo[code].map(dict => {
return {
id: dict.Id,
label: lang==='zh' ? dict.ValueCN : dict.Value,
value: dict.DataTypeEnum === 3 ? eval(dict.Code) : dict.IsEnumInt ? parseInt(dict.Code): dict.Code,
label: lang === 'zh' ? dict.ValueCN : dict.Value,
value: dict.DataTypeEnum === 3 ? eval(dict.Code) : dict.IsEnumInt ? parseInt(dict.Code) : dict.Code,
raw: Object.assign({}, dict),
IsBaseLineUse: false,
IsFollowVisitUse: false
@@ -196,35 +234,36 @@ async function VueInit () {
}) : []
dictInfo[code] = dictList
}
} catch (e){
} catch (e) {
console.error(e)
}
return dictInfo
}()
Vue.prototype.$d = d
Vue.prototype.$fd = function (code, v, type) {
Vue.prototype.$fd = function (code, v, type, arr, key = 'label') {
try {
let data = arr || d;
type = type || 'value';
// code === 'YesOrNo' ? console.log(d) : ''
type = type || 'value'
return d[code].find(i => {
return data[code].find(i => {
return i[type] === v
}) ? d[code].find(i => {
}) ? data[code].find(i => {
return i[type] === v
}).label : ''
})[key] : ''
} catch (e) {
}
}
Vue.prototype.$updateDictionary = function() {
Vue.prototype.$updateDictionary = function () {
Vue.prototype.$d = function (code) {
var dictInfo = res.Result
var lang = zzSessionStorage.getItem('lang')?zzSessionStorage.getItem('lang'):'zh'
var lang = zzSessionStorage.getItem('lang') ? zzSessionStorage.getItem('lang') : 'zh'
try {
for (var code in dictInfo) {
var dictList = (dictInfo[code] && dictInfo[code].length > 0) ? dictInfo[code].map(dict => {
var dictList = (dictInfo[code] && dictInfo[code].length > 0) ? dictInfo[code].map(dict => {
return {
id: dict.raw.Id,
label: lang==='zh' ? dict.raw.ValueCN : dict.raw.Value,
value: dict.raw.DataTypeEnum === 3 ? eval(dict.raw.Code) : dict.raw.IsEnumInt ? parseInt(dict.raw.Code): dict.raw.Code,
label: lang === 'zh' ? dict.raw.ValueCN : dict.raw.Value,
value: dict.raw.DataTypeEnum === 3 ? eval(dict.raw.Code) : dict.raw.IsEnumInt ? parseInt(dict.raw.Code) : dict.raw.Code,
raw: Object.assign({}, dict.raw),
IsBaseLineUse: false,
IsFollowVisitUse: false
@@ -232,7 +271,7 @@ async function VueInit () {
}) : []
_vm.$set(dictInfo, code, dictList)
}
} catch (e){
} catch (e) {
console.error(e)
}
return dictInfo
@@ -268,14 +307,14 @@ async function VueInit () {
let count = 0;
if (eval(process.env.VUE_APP_LOGIN_FOR_PERMISSION)) {
setInterval(() => {
var lang = zzSessionStorage.getItem('lang')?zzSessionStorage.getItem('lang'):'zh'
if ( _vm.$route.path === '/ReviewersResearchForm' || _vm.$route.path === '/ReviewersResearch' || _vm.$route.path === '/login' || _vm.$route.path === '/researchForm' || _vm.$route.path === '/researchLogin' || _vm.$route.path === '/email-recompose' || _vm.$route.path === '/recompose' || _vm.$route.path === '/resetpassword' || _vm.$route.path === '/error') {
var lang = zzSessionStorage.getItem('lang') ? zzSessionStorage.getItem('lang') : 'zh'
if (_vm.$route.path === '/ReviewersResearchForm' || _vm.$route.path === '/ReviewersResearch' || _vm.$route.path === '/login' || _vm.$route.path === '/researchForm' || _vm.$route.path === '/researchLogin' || _vm.$route.path === '/email-recompose' || _vm.$route.path === '/recompose' || _vm.$route.path === '/resetpassword' || _vm.$route.path === '/error') {
return
}
if (_vm.$store.state.user.userId !== zzSessionStorage.getItem('userId')) {
window.location.href = `/login`
zzSessionStorage.removeItem('lastWorkbench')
_vm.$alert(lang === 'en'? 'The same browser only allows one user account to be logged in at a time.' : '同一浏览器只允许同时登陆一个账户', {
_vm.$alert(_vm.$t("env:sso:tip"), {
type: 'warning',
})
}
@@ -289,10 +328,10 @@ async function VueInit () {
function countTime() {
count++
localStorage.setItem('count', count)
if (count == parseInt(second2) || isLock === 'true') {
if (count == parseInt(second2) || isLock === 'true') {
callback2();
}
if (count >= second) {
if (count >= second) {
callback();
count = 0;
localStorage.removeItem('count')
@@ -326,24 +365,40 @@ async function VueInit () {
}
const h = _vm.$createElement
/* eslint-disable */
// eval(process.env.VUE_APP_LOGOUT_FOR_PERMISSION)
// process.env.VUE_APP_LOGOUT_FOR_TIME
// eval(process.env.VUE_APP_LOCK_FOR_PERMISSION)
// process.env.VUE_APP_LOCK_FOR_TIME
window.VUE_APP_COMPANY_NAME = process.env.VUE_APP_COMPANY_NAME;
waitOperate(eval(process.env.VUE_APP_LOGOUT_FOR_PERMISSION) ? () => {
var lang = zzSessionStorage.getItem('lang')?zzSessionStorage.getItem('lang'):'zh'
if ( _vm.$route.path === '/ReviewersResearchForm' || _vm.$route.path === '/ReviewersResearch' || _vm.$route.path === '/login' || _vm.$route.path === '/researchForm' || _vm.$route.path === '/researchLogin' || _vm.$route.path === '/email-recompose' || _vm.$route.path === '/recompose' || _vm.$route.path === '/resetpassword' || _vm.$route.path === '/error') {
count = 0;
localStorage.setItem('count', '0')
return
var lang = zzSessionStorage.getItem('lang') ? zzSessionStorage.getItem('lang') : 'zh'
if (_vm.$store.state.trials.unlock || _vm.$route.path === '/ReviewersResearchForm' || _vm.$route.path === '/ReviewersResearch' || _vm.$route.path === '/login' || _vm.$route.path === '/researchForm' || _vm.$route.path === '/researchLogin' || _vm.$route.path === '/email-recompose' || _vm.$route.path === '/recompose' || _vm.$route.path === '/resetpassword' || _vm.$route.path === '/error') {
count = 0;
localStorage.setItem('count', '0')
return
}
_vm.$store.dispatch('user/logout').then(res => {
// window.location.href = `/login`
if (_vm.$msgbox) {
_vm.$msgbox.close();
}
_vm.$store.dispatch('user/logout').then(res => {
window.location.href = `/login`
})
_vm.$alert(lang === 'zh' ? '由于您长时间未操作,为保护您的数据安全已强制将您下线,如果需要继续操作请重新登陆!' : 'No operation for a long time non-operation, you have been forced logout to protect data security. If continue to operate, please login again!', {
isOpen = false
isLock = null
zzSessionStorage.removeItem('isLock')
router.push("/login")
}).then(() => {
// _vm.$alert(lang === 'zh' ? '由于您长时间未操作,为保护您的数据安全已强制将您下线,如果需要继续操作请重新登陆!' : 'No operation for a long time non-operation, you have been forced logout to protect data security. If continue to operate, please login again!', {
// type: 'warning',
// })
_vm.$alert(_vm.$t("env:loginOut"), {
type: 'warning',
})
} : () => {}, process.env.VUE_APP_LOGOUT_FOR_TIME,
})
} : () => { }, process.env.VUE_APP_LOGOUT_FOR_TIME,
eval(process.env.VUE_APP_LOCK_FOR_PERMISSION) ? () => {
var lang = zzSessionStorage.getItem('lang')?zzSessionStorage.getItem('lang'):'zh'
if ( _vm.$route.path === '/ReviewersResearchForm' || _vm.$route.path === '/ReviewersResearch' || _vm.$route.path === '/login' || _vm.$route.path === '/researchForm' || _vm.$route.path === '/researchLogin' || _vm.$route.path === '/email-recompose' || _vm.$route.path === '/recompose' || _vm.$route.path === '/resetpassword' || _vm.$route.path === '/error') {
var lang = zzSessionStorage.getItem('lang') ? zzSessionStorage.getItem('lang') : 'zh'
if (_vm.$store.state.trials.unlock || _vm.$route.path === '/ReviewersResearchForm' || _vm.$route.path === '/ReviewersResearch' || _vm.$route.path === '/login' || _vm.$route.path === '/researchForm' || _vm.$route.path === '/researchLogin' || _vm.$route.path === '/email-recompose' || _vm.$route.path === '/recompose' || _vm.$route.path === '/resetpassword' || _vm.$route.path === '/error') {
count = 0;
localStorage.setItem('count', '0')
if (_vm.$route.path === '/login') {
@@ -359,53 +414,74 @@ async function VueInit () {
isOpen = true
zzSessionStorage.setItem('isLock', 'true')
_vm.$msgbox({
title: lang === 'zh' ? '已锁定' : 'Locked',
confirmButtonText: lang === 'zh' ? '解锁' : 'Unlock',
title: _vm.$t("env:lock:msgBox:title"),
confirmButtonText: _vm.$t("env:lock:msgBox:confirmButtonText"),
showClose: false,
beforeClose: (action, instance, done) => {
if (action === 'confirm') {
if (!_vm.unlock.my_username) {
_vm.$alert(lang === 'zh' ? '请输入您的用户名解锁' : 'Please enter your user name to unlock.')
_vm.$alert(_vm.$t("env:lock:msgBox:iupUser"))
return
}
if (!_vm.unlock.my_password) {
_vm.$alert(lang === 'zh' ? '请输入您的密码解锁' : 'Please enter the correct password to unlock.')
_vm.$alert(_vm.$t("env:lock:msgBox:inpPassword"))
return
}
var my_username = zzSessionStorage.getItem('my_username')
var my_password = zzSessionStorage.getItem('my_password')
let my_userid = zzSessionStorage.getItem('userId')
let my_EMail = zzSessionStorage.getItem('my_EMail')
if (md5(_vm.unlock.my_password) === my_password && my_username === _vm.unlock.my_username) {
resetReadingRestTime().then(() => {
})
_vm.$message.success(lang === 'zh' ? '解锁成功,请继续操作' : 'Unlocked successfully. Please continue operation.')
_vm.unlock = {
my_username: null,
my_password: null
const closeLock = (_vm) => {
_vm.$message.success(_vm.$t("env:lock:msgBox:lockSuccess"))
_vm.unlock = {
my_username: null,
my_password: null
}
isOpen = false
count = 0;
isLock = null
zzSessionStorage.removeItem('isLock')
localStorage.setItem('count', '0')
document.querySelector('#my_username').value = null
document.querySelector('#my_password').value = null
setTimeout(() => {
done()
}, 500)
}
isOpen = false
count = 0;
isLock = null
zzSessionStorage.removeItem('isLock')
localStorage.setItem('count', '0')
document.querySelector('#my_username').value = null
document.querySelector('#my_password').value = null
setTimeout(() => {
done()
}, 500)
if (eval(process.env.VUE_APP_LOCK_FOR_PERMISSION_MFA)) {
sendMFAEmail({ UserId: my_userid, MfaType: 1 }).then((res) => {
done();
Vue.prototype.$MFA({
status: "lock",
UserId: my_userid,
EMail: res.Result,
username: my_username,
callBack: () => {
closeLock(_vm)
},
})
})
} else {
closeLock(_vm)
}
} else {
// console.log(111)
_vm.$message.error(lang === 'zh' ? '请输入正确用户名密码' : 'Please enter the correct password.')
_vm.$message.error(_vm.$t('env:lock:msgBox:userFail'))
}
}
},
message: h('div', {} , [
message: h('div', {}, [
h('el-form', {
props: { labelWidth: "80px" }
}, [
h('el-form-item', {
props: {label: lang === 'zh' ? '用户名' : 'Username'},
props: { label: _vm.$t("env:lock:msgBox:form:username") },
}, [
h('input',{
h('input', {
props: {
value: _vm.unlock.my_username
},
@@ -425,7 +501,7 @@ async function VueInit () {
})
]),
h('el-form-item', {
props: {label: lang === 'zh' ? '密码' : 'Password'},
props: { label: _vm.$t("env:lock:msgBox:form:Password") },
}, [
h('input', {
props: {
@@ -450,7 +526,7 @@ async function VueInit () {
])
])
})
} : () => {}, process.env.VUE_APP_LOCK_FOR_TIME)
} : () => { }, process.env.VUE_APP_LOCK_FOR_TIME)
}
VueInit()
+23 -7
View File
@@ -10,9 +10,9 @@ import { OSSclient } from './utils/oss'
NProgress.configure({ showSpinner: false })
const whiteList = ['/ReviewersResearch', '/login', '/error', '/resetpassword', '/recompose', '/email-recompose', '/trialStats', '/showdicom', '/imagesShare', '/audit', '/preview', '/researchLogin', '/blindResumeInfo', '/trialsResume', '/joinVerify', '/showNoneDicoms', '/noneDicomReading', '/clinicalData', '/readingDicoms', '/readingPage', '/visitDicomReview', '/visitNondicomReview', '/globalReview', '/adReview', '/oncologyReview', '/nonedicoms']
router.beforeEach(async(to, from, next) => {
const whiteList = ['/ReviewersResearch', '/login', '/error', '/resetpassword', '/recompose', '/email-recompose', '/trialStats', '/showdicom', '/imagesShare', '/audit', '/preview', '/researchLogin', '/researchLogin_m', '/blindResumeInfo', '/trialsResume', '/joinVerify', '/showNoneDicoms', '/noneDicomReading', '/clinicalData', '/readingDicoms', '/readingPage', '/visitDicomReview', '/visitNondicomReview', '/globalReview', '/adReview', '/oncologyReview', '/nonedicoms']
store.state.trials.whiteList = whiteList;
router.beforeEach(async (to, from, next) => {
NProgress.start()
// 设置页面标题
// document.title = getPageTitle(to.meta.title)
@@ -34,7 +34,7 @@ router.beforeEach(async(to, from, next) => {
NProgress.done()
} else {
OSSclient()
const hasGetUserInfo = store.getters.name
const hasGetUserInfo = store.getters.userId
if (hasGetUserInfo) {
next()
} else {
@@ -55,17 +55,33 @@ router.beforeEach(async(to, from, next) => {
} else {
/* has no token*/
if (whiteList.indexOf(to.path) !== -1) {
// 在免登录whiteList中,直接进入
next()
if (to.path === '/researchLogin') {
console.log(to)
const flag = navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)
if (flag) {
next(`/researchLogin_m?trialId=${to.query.trialId}&lang=${to.query.lang}`)
} else {
next()
}
} else {
// 在免登录whiteList中,直接进入
if (to.path === '/readingDicoms' || to.path === '/noneDicomReading') {
OSSclient()
}
next()
}
} else {
if (to.path === '/researchForm') {
next(`/researchLogin?`)
NProgress.done()
} else if (to.path === '/researchDetail_m') {
next(`/researchLogin_m?`)
NProgress.done()
} else if (to.path === '/ReviewersResearchForm') {
next(`/ReviewersResearch?`)
NProgress.done()
} else {
// 其他无权访问的页面将重定向到登录页面。
// 其他无权访问的页面将重定向到登录页面。
next(`/login?`)
NProgress.done()
}
+24 -5
View File
@@ -139,6 +139,13 @@ export const constantRoutes = [
hidden: true,
component: () => import('@/views/trials/trials-panel/reading/dicoms/components/Fusion/PetCt')
},
{
path: '/historyScreenshot',
name: 'historyScreenshot',
hidden: true,
component: () => import('@/views/trials/trials-panel/reading/dicoms/components/Fusion/HistoryScreenshot')
},
{
path: '/visitDicomReview',
name: 'visitDicomReview',
@@ -194,6 +201,18 @@ export const constantRoutes = [
component: () => import('@/views/research/form'),
hidden: true
},
{
path: '/researchLogin_m',
name: 'researchLogin_m',
component: () => import('@/views/research-mobile/login'),
hidden: true
},
{
path: '/researchDetail_m',
name: 'researchDetail_m',
component: () => import('@/views/research-mobile/detail'),
hidden: true
},
{
path: '/trialsResume',
component: () => import('@/views/trials/trials-panel/enrolled-reviewers/resume/index'),
@@ -242,6 +261,11 @@ export const constantRoutes = [
component: () => import('@/views/404'),
hidden: true
},
{
path: '/ecrfPreview',
component: () => import('@/views/dictionary/template/components/ECRF'),
hidden: true
},
{
path: '/editUser',
component: Layout,
@@ -251,11 +275,6 @@ export const constantRoutes = [
path: 'baiscInfo',
name: 'BaiscInfo',
component: () => import('@/views/user/editInfo')
},
{
path: 'account',
name: 'Account',
component: () => import('@/views/user/account')
}
]
}
+2
View File
@@ -40,6 +40,8 @@ const getters = {
activeSeries: state => state.reading.activeSeries,
lastCanvasTaskId: state => state.reading.lastCanvasTaskId,
imageQuality: state => state.reading.imageQuality,
imageQualityIssues: state => state.reading.imageQualityIssues,
currentLoadIns: state => state.reading.currentLoadIns,
language: state => state.lang.language,
TotalNeedSignSystemDocCount: state => state.user.TotalNeedSignSystemDocCount,
TotalNeedSignTrialDocCount: state => state.user.TotalNeedSignTrialDocCount,
+284 -84
View File
@@ -20,8 +20,8 @@ const hangingAgreement = [
]
const getDefaultState = () => {
return {
// visitTaskList: [],
visitTaskList: sessionStorage.getItem('visitTaskList') ? JSON.parse(sessionStorage.getItem('visitTaskList')) : [],
visitTaskList: [],
// visitTaskList: sessionStorage.getItem('visitTaskList') ? JSON.parse(sessionStorage.getItem('visitTaskList')) : [],
organList: [],
seriesStack: [],
activeHangingAgreement: hangingAgreement[0],
@@ -29,7 +29,9 @@ const getDefaultState = () => {
currentReadingTaskState: 2,
activeSeries: {},
lastCanvasTaskId: '',
imageQuality: null
imageQuality: null,
imageQualityIssues: null,
currentLoadIns: []
}
}
function getQuestions(questions) {
@@ -138,6 +140,22 @@ function getQuestionAnswer(questions, questionMark, answers) {
return ''
}
}
// function getKeySeriesInfo(keyInstance, series) {
// const obj = {}
// const set = new Set()
// var instances = series.instanceList.concat(keyInstance).filter((item) => {
// if (set.has(item)) {
// return true
// } else {
// set.add(item)
// return false
// }
// })
// instances.map(item => {
// obj[item] = { seriesId: series.seriesId, studyIndex: series.studyIndex, seriesIndex: series.seriesIndex }
// })
// return obj
// }
const state = getDefaultState
@@ -165,7 +183,7 @@ const actions = {
item.IsInit = false
})
state.visitTaskList = res.Result
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
const currentTaskIdx = res.Result.findIndex(item => item.IsCurrentTask)
if (currentTaskIdx > -1) {
state.currentTaskId = res.Result[currentTaskIdx].VisitTaskId
@@ -177,17 +195,19 @@ const actions = {
},
resetVisitTasks({ state }) {
return new Promise(resolve => {
sessionStorage.setItem('visitTaskList', '')
// sessionStorage.setItem('visitTaskList', '')
state.visitTaskList = []
state.currentTaskId = ''
state.activeSeries = {}
state.lastCanvasTaskId = ''
state.imageQuality = null
state.imageQualityIssues = null
resolve()
})
},
getMasterSeries({ state }, obj) {
return new Promise(resolve => {
console.log('getMasterSeries')
var seriesInfo = {}
var i = state.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId)
getReadingVisitStudyList(obj.trialId, obj.visitId, obj.visitTaskId).then(res => {
@@ -207,14 +227,28 @@ const actions = {
var seriesList = []
study.SeriesList.forEach((series, index) => {
const imageIds = []
series.InstancePathList.forEach((path) => {
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${path}`)
const instanceList = []
// series.InstancePathList.forEach((path) => {
// imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${path}`)
// })
series.InstanceInfoList.forEach(instance => {
if (instance.NumberOfFrames && instance.NumberOfFrames > 1) {
for (let i = 0; i < instance.NumberOfFrames; i++) {
const imageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${instance.Path}?frame=${i}&instanceId=${instance.Id}&visitTaskId=${obj.visitTaskId}&idx=0|0`
imageIds.push(imageId)
}
} else {
const imageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${instance.Path}?instanceId=${instance.Id}&visitTaskId=${obj.visitTaskId}&idx=0|0`
imageIds.push(imageId)
}
instance.ImageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${instance.Path}?instanceId=${instance.Id}&visitTaskId=${obj.visitTaskId}&idx=0|0`
instanceList.push(instance.Id)
})
seriesList.push({
isDicom: study.IsDicom,
imageIds: imageIds,
instanceList: series.InstanceList,
instanceInfoList: series.InstanceInfoList,
instanceList: instanceList,
seriesId: series.Id,
imageIdIndex: 0,
seriesUid: series.SeriesInstanceUid,
@@ -285,7 +319,7 @@ const actions = {
}
}
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
}).catch(() => { resolve() })
})
@@ -301,7 +335,7 @@ const actions = {
})
})
}
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
})
},
@@ -320,7 +354,7 @@ const actions = {
state.visitTaskList[index].Questions = res.Result
state.visitTaskList[index].questionsInit = true
state.visitTaskList[index].QuestionMarkInfoList = res.OtherInfo.QuestionMarkInfoList
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
}).catch(() => { resolve() })
}
@@ -338,7 +372,7 @@ const actions = {
state.visitTaskList[index].Questions = res.Result
state.visitTaskList[index].questionsInit = true
state.visitTaskList[index].QuestionMarkInfoList = res.OtherInfo.QuestionMarkInfoList
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
}).catch(() => { resolve() })
})
@@ -357,7 +391,7 @@ const actions = {
var list = getQuestions(res.Result.SinglePage)
state.visitTaskList[index].ReadingQuestions = list
state.visitTaskList[index].readingQuestionsInit = true
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
}).catch(() => { resolve() })
}
@@ -374,7 +408,7 @@ const actions = {
var list = getQuestions(res.Result.SinglePage)
state.visitTaskList[index].ReadingQuestions = list
state.visitTaskList[index].readingQuestionsInit = true
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
}).catch(() => { resolve() })
})
@@ -385,7 +419,7 @@ const actions = {
if (index > -1) {
state.visitTaskList[index].ReadingQuestions = obj.questions
}
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
})
},
@@ -397,7 +431,7 @@ const actions = {
questions = findQuestionAndAddLesion(questions, obj)
state.visitTaskList[index].ReadingQuestions = questions
}
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
})
},
@@ -409,7 +443,7 @@ const actions = {
questions = findQuestionAndUpdateLesion(questions, obj)
state.visitTaskList[index].ReadingQuestions = questions
}
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
})
},
@@ -421,7 +455,7 @@ const actions = {
questions = findQuestionAndRemoveLesion(questions, obj)
state.visitTaskList[index].ReadingQuestions = questions
}
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
})
},
@@ -442,7 +476,7 @@ const actions = {
})
state.visitTaskList[index].MeasureData = arr
state.visitTaskList[index].measureDataInit = true
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
}).catch(() => { resolve() })
}
@@ -469,7 +503,7 @@ const actions = {
})
state.visitTaskList[index].MeasureData = arr
state.visitTaskList[index].measureDataInit = true
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
}).catch(() => { resolve() })
}
@@ -479,24 +513,28 @@ const actions = {
return new Promise(async resolve => {
var index = state.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId)
var measureData = state.visitTaskList[index].MeasureData
console.log('removeCustomizeMeasuredData', obj, state.visitTaskList[index].MeasureData)
// var uuid = obj.measureData.data.uuid
// var idx = measureData.findIndex(item => item.MeasureData && item.MeasureData.data && item.MeasureData.data.uuid === uuid)
console.log(obj, measureData)
var idx = measureData.findIndex(item => item.Id === obj.questionInfo.Id)
console.log('idx', idx)
if (idx > -1) {
if (measureData[idx].FristAddTaskId) {
measureData[idx].MeasureData = ''
console.log('清除标记成功', idx)
} else {
measureData.splice(idx, 1)
console.log('移除标记成功', idx)
// console.log(obj, measureData)
if (obj.questionInfo.Id) {
var idx = measureData.findIndex(item => item.Id === obj.questionInfo.Id)
console.log('idx', idx)
if (idx > -1) {
if (measureData[idx].FristAddTaskId) {
measureData[idx].MeasureData = ''
console.log('清除标记成功', idx)
} else {
measureData.splice(idx, 1)
console.log('移除标记成功', idx)
}
if (obj.questionInfo.Id && state.currentReadingTaskState < 2) {
await deleteCustomTag(obj.questionInfo.Id)
}
state.visitTaskList[index].MeasureData = measureData
}
await deleteCustomTag(obj.questionInfo.Id)
state.visitTaskList[index].MeasureData = measureData
} else if (obj.orderMarkName) {
const i = measureData.findIndex(item => item.QuestionId === obj.questionId && item.OrderMarkName === obj.orderMarkName)
const i = measureData.findIndex(item => item.MeasureData.data.remark === obj.orderMarkName)
if (i > -1) {
if (measureData[i].FristAddTaskId) {
measureData[i].MeasureData = ''
@@ -506,10 +544,12 @@ const actions = {
console.log('移除标记成功', i)
}
}
await deleteCustomTag(obj.questionInfo.Id)
if (obj.questionInfo.Id && state.currentReadingTaskState < 2) {
await deleteCustomTag(obj.questionInfo.Id)
}
state.visitTaskList[index].MeasureData = measureData
}
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
})
},
@@ -527,7 +567,7 @@ const actions = {
})
state.visitTaskList[index].MeasureData = arr
state.visitTaskList[index].measureDataInit = true
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
}).catch(() => { resolve() })
})
@@ -546,7 +586,7 @@ const actions = {
})
state.visitTaskList[index].MeasureData = arr
state.visitTaskList[index].measureDataInit = true
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
}).catch(() => { resolve() })
})
@@ -578,7 +618,7 @@ const actions = {
state.visitTaskList[index].MeasureData.push(obj.data)
console.log('新增标记成功')
}
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
console.log(state.visitTaskList)
resolve()
})
@@ -588,6 +628,7 @@ const actions = {
var index = state.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId)
var measureData = state.visitTaskList[index].MeasureData
console.log('addOrUpdateNonTargetMeasuredData')
// item.MeasureData.data.remark === obj.orderMarkName
var idx = measureData.findIndex(item => item.QuestionId === obj.data.QuestionId && item.OrderMarkName === obj.data.OrderMarkName)
if (idx > -1) {
for (const k in state.visitTaskList[index].MeasureData[idx]) {
@@ -600,7 +641,7 @@ const actions = {
state.visitTaskList[index].MeasureData.push(obj.data)
console.log('新增标记成功')
}
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
})
},
@@ -620,7 +661,7 @@ const actions = {
}
state.visitTaskList[index].MeasureData = measureData
}
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
})
},
@@ -630,32 +671,42 @@ const actions = {
var measureData = state.visitTaskList[index].MeasureData
console.log(measureData, obj)
// var idx = measureData.findIndex(item => item.MeasureData.uuid === obj.data.MeasureData.data.uuid)
if (!obj.questionInfo) {
state.visitTaskList[index].MeasureData.push({
MeasureData: obj,
SeriesId: obj.seriesId,
StudyId: obj.studyId,
InstanceId: obj.instanceId,
Id: obj.Id
})
console.log('新增标记成功')
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
}
var idx = measureData.findIndex(item => item.Id === obj.questionInfo.Id)
// if (!obj.questionInfo) {
// state.visitTaskList[index].MeasureData.push({
// MeasureData: obj,
// SeriesId: obj.seriesId,
// StudyId: obj.studyId,
// InstanceId: obj.instanceId,
// Id: obj.Id
// })
// console.log('新增标记成功')
// resolve()
// }
var idx = measureData.findIndex(item => item.MeasureData.data.remark === obj.measureData.data.remark)
if (idx > -1) {
for (const k in state.visitTaskList[index].MeasureData[idx]) {
if (k !== 'Id' && obj.MeasureData.data[k]) {
state.visitTaskList[index].MeasureData[idx][k] = obj.MeasureData.data[k]
}
}
// state.visitTaskList[index].MeasureData[idx].InstanceId = obj.instanceId
state.visitTaskList[index].MeasureData[idx].MeasureData = obj.measureData
// state.visitTaskList[index].MeasureData[idx].SeriesId = obj.seriesId
// state.visitTaskList[index].MeasureData[idx].StudyId = obj.studyId
// for (const k in state.visitTaskList[index].MeasureData[idx]) {
// if (k !== 'Id' && obj.MeasureData.data[k]) {
// state.visitTaskList[index].MeasureData[idx][k] = obj.MeasureData.data[k]
// }
// }
// state.visitTaskList[index].MeasureData[idx].MeasureData = obj.data.MeasureData
console.log('更新标记成功', idx)
} else {
state.visitTaskList[index].MeasureData.push(obj.MeasureData.data)
// state.visitTaskList[index].MeasureData.push(obj.MeasureData.data)
state.visitTaskList[index].MeasureData.push({
MeasureData: obj.measureData,
SeriesId: obj.measureData.seriesId,
StudyId: obj.measureData.studyId,
InstanceId: obj.measureData.instanceId,
Id: obj.id
})
console.log('新增标记成功')
}
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
})
},
@@ -700,7 +751,7 @@ const actions = {
// state.visitTaskList[index].MeasureData = measureData
// }
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
})
},
@@ -713,20 +764,29 @@ const actions = {
measureData[idx].MeasureData.data.status = obj.status
state.visitTaskList[index].MeasureData = measureData
}
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
})
},
getStudyInfo({ state }, obj) {
console.log('getStudyInfo')
return new Promise(resolve => {
var index = state.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId)
if (state.visitTaskList[index].studyListInit) {
resolve()
} else {
var studyList = []
// getVisitStudyList
// getReadingVisitStudyList
var keyImages = []
getReadingVisitStudyList(obj.trialId, obj.subjectVisitId, obj.visitTaskId).then(res => {
const i = res.Result.findIndex(i => i.IsCriticalSequence)
if (i > -1) {
const seriesList = res.Result[i].SeriesList && res.Result[i].SeriesList
seriesList.map(i => {
i.InstanceInfoList.map(k => {
keyImages.push({ instanceId: k.Id })
})
})
}
res.Result.forEach((study, studyIndex) => {
const data = {}
data.StudyId = study.StudyId
@@ -741,19 +801,40 @@ const actions = {
var seriesList = []
study.SeriesList.forEach((series, seriesIndex) => {
const imageIds = []
try {
// if (~window.location.href.indexOf('3c210000-3e2c-0016-4247-08dabf28e96b')) {
series.InstancePathList.forEach((path) => {
// var path = id.split('/')[id.split('/').length - 1]
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${path}`)
})
} catch (e) {
console.log(e)
}
const instanceList = []
// try {
// series.InstancePathList.forEach((path) => {
// imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${path}`)
// })
// } catch (e) {
// console.log(e)
// }
series.InstanceInfoList.forEach(instance => {
if (instance.NumberOfFrames && instance.NumberOfFrames > 1) {
for (let i = 0; i < instance.NumberOfFrames; i++) {
const imageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${instance.Path}?frame=${i}&instanceId=${instance.Id}&visitTaskId=${obj.visitTaskId}&idx=${studyIndex}|${seriesIndex}|${index}`
imageIds.push(imageId)
}
instance.ImageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${instance.Path}?frame=${0}&instanceId=${instance.Id}&visitTaskId=${obj.visitTaskId}&idx=${studyIndex}|${seriesIndex}|${index}`
} else {
const imageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${instance.Path}?instanceId=${instance.Id}&visitTaskId=${obj.visitTaskId}&idx=${studyIndex}|${seriesIndex}|${index}`
imageIds.push(imageId)
instance.ImageId = imageId
}
if (!study.IsCriticalSequence && series.IsBeMark) {
const i = keyImages.findIndex(i => i.instanceId === instance.Id)
if (i > -1) {
keyImages[i].studyIndex = studyIndex
keyImages[i].seriesIndex = seriesIndex
}
}
instanceList.push(instance.Id)
})
seriesList.push({
isDicom: study.IsDicom,
imageIds: imageIds,
instanceList: series.InstanceList,
instanceInfoList: series.InstanceInfoList,
instanceList: instanceList,
seriesId: series.Id,
imageIdIndex: 0,
seriesUid: series.SeriesInstanceUid,
@@ -780,7 +861,8 @@ const actions = {
isLoading: false,
isBeMark: series.IsBeMark,
ww: series.WindowWidth,
wc: series.WindowCenter
wc: series.WindowCenter,
isExistMutiFrames: series.IsExistMutiFrames
})
})
data.SeriesList = seriesList
@@ -788,7 +870,8 @@ const actions = {
})
state.visitTaskList[index].StudyList = studyList
state.visitTaskList[index].studyListInit = true
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
state.visitTaskList[index].KeyImages = keyImages
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
}).catch(() => { resolve() })
}
@@ -821,7 +904,7 @@ const actions = {
}
}
state.visitTaskList[index].StudyList = studyList
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
} else {
// console.log(obj)
}
@@ -841,15 +924,124 @@ const actions = {
studyList[obj.studyIndex].SeriesList[obj.seriesIndex].loadStatus = true
}
state.visitTaskList[obj.visitTaskindex].StudyList = studyList
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
}
resolve()
})
},
setImageLoadedProgress({ state }, obj) {
const studyIndex = parseInt(obj.idx.split('|')[0])
const seriesIndex = parseInt(obj.idx.split('|')[1])
const visitTaskIndex = parseInt(obj.idx.split('|')[2])
let pStudyIndex = null
let pSeriesIndex = null
let pSeries = null
try {
const study = state.visitTaskList[visitTaskIndex].StudyList[studyIndex]
const series = state.visitTaskList[visitTaskIndex].StudyList[studyIndex].SeriesList[seriesIndex]
const keyImages = state.visitTaskList[visitTaskIndex].KeyImages
if (study.IsCriticalSequence) {
const i = keyImages.findIndex(i => i.instanceId === obj.instanceId)
if (i > -1) {
pStudyIndex = keyImages[i].studyIndex
pSeriesIndex = keyImages[i].seriesIndex
}
} else if (series.isBeMark) {
if (keyImages.length > 0) {
pStudyIndex = 0
pSeriesIndex = 0
}
}
if (pStudyIndex !== null && pSeriesIndex !== null) {
pSeries = state.visitTaskList[visitTaskIndex].StudyList[pStudyIndex].SeriesList[pSeriesIndex]
}
var prefetchInstanceCount = series.prefetchInstanceCount
var instanceCount = series.instanceCount
var prefetchInstanceCount2 = pSeries ? pSeries.prefetchInstanceCount : null
var instanceCount2 = pSeries ? pSeries.instanceCount : null
if (series.imageloadedArr.indexOf(obj.instanceId) < 0) {
const i = state.currentLoadIns.findIndex(i => i.instanceId === obj.instanceId)
if (i > -1) {
prefetchInstanceCount = prefetchInstanceCount + obj.percentComplete - state.currentLoadIns[i].percentComplete
prefetchInstanceCount2 = prefetchInstanceCount2 !== null ? prefetchInstanceCount2 + obj.percentComplete - state.currentLoadIns[i].percentComplete : null
state.currentLoadIns[i].percentComplete = obj.percentComplete
if (obj.percentComplete >= 100) {
state.currentLoadIns.splice(i, 1)
}
} else {
if (obj.percentComplete !== 100) {
state.currentLoadIns.push({ instanceId: obj.instanceId, percentComplete: obj.percentComplete })
}
prefetchInstanceCount = prefetchInstanceCount + obj.percentComplete
prefetchInstanceCount2 = prefetchInstanceCount2 !== null ? prefetchInstanceCount2 + obj.percentComplete : null
}
series.prefetchInstanceCount = prefetchInstanceCount
if (pSeries) {
pSeries.prefetchInstanceCount = prefetchInstanceCount2
}
if (obj.percentComplete >= 100) {
series.imageloadedArr.push(obj.instanceId)
if (pSeries) {
pSeries.imageloadedArr.push(obj.instanceId)
}
}
}
if (prefetchInstanceCount >= instanceCount * 100) {
series.prefetchInstanceCount = instanceCount * 100
// 设置当前序列状态为已下载完成
series.loadStatus = true
}
if (prefetchInstanceCount2 !== null && instanceCount2 !== null && prefetchInstanceCount2 >= instanceCount2 * 100) {
pSeries.prefetchInstanceCount = instanceCount2 * 100
// 设置当前序列状态为已下载完成
pSeries.loadStatus = true
}
} catch (e) {
console.log('error')
}
},
setImageloadedInfo({ state }, obj) {
console.log('setImageloadedInfo', obj)
// if(obj.instance === '20dd8fc9-51b0-ec63-942b-cb3006c72650')
// var index = state.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId)
// // const prefetchInstanceCount = state.visitTaskList[index].StudyList[obj.studyIndex].SeriesList[obj.seriesIndex].prefetchInstanceCount
// const instanceList = state.visitTaskList[index].StudyList[obj.studyIndex].SeriesList[obj.seriesIndex].instanceList
// const idx = state.visitTaskList[index].StudyList.findIndex(i => i.IsCriticalSequence)
// if (!state.visitTaskList[index].StudyList[obj.studyIndex].IsCriticalSequence) {
// // 当前下载的非关键序列
// console.log('当前下载的非关键序列')
// if (idx > -1) {
// const keyInstance = state.visitTaskList[index].StudyList[idx].SeriesList[0].instanceList
// obj.markedImages = getKeySeriesInfo(keyInstance, state.visitTaskList[index].StudyList[obj.studyIndex].SeriesList[obj.seriesIndex])
// instanceList.map(i => {
// if (obj.markedImages.hasOwnProperty(i) && state.visitTaskList[index].StudyList[idx].SeriesList[0].imageloadedArr.indexOf(i) < 0) {
// state.visitTaskList[index].StudyList[idx].SeriesList[0].imageloadedArr.push(i)
// state.visitTaskList[index].StudyList[idx].SeriesList[0].prefetchInstanceCount = state.visitTaskList[index].StudyList[idx].SeriesList[0].prefetchInstanceCount + 100
// }
// })
// if (state.visitTaskList[index].StudyList[idx].SeriesList[0].imageloadedArr >= state.visitTaskList[index].StudyList[idx].SeriesList[0].instanceCount) {
// state.visitTaskList[index].StudyList[idx].SeriesList[0].loadStatus = true
// }
// }
// }
// state.visitTaskList[index].StudyList[obj.studyIndex].SeriesList[obj.seriesIndex].prefetchInstanceCount = state.visitTaskList[index].StudyList[obj.studyIndex].SeriesList[obj.seriesIndex].instanceCount * 100
// state.visitTaskList[index].StudyList[obj.studyIndex].SeriesList[obj.seriesIndex].imageloadedArr = instanceList
// state.visitTaskList[index].StudyList[obj.studyIndex].SeriesList[obj.seriesIndex].loadStatus = true
// const imageloadedArr = state.visitTaskList[index].StudyList[obj.studyIndex].SeriesList[obj.seriesIndex].imageloadedArr
// if (imageloadedArr.indexOf())
// if (state.visitTaskList[index].StudyList[0].IsCriticalSequence){
// state.visitTaskList[index].StudyList[0].SeriesList[0].prefetchInstanceCount = prefetchInstanceCount + 100
// state.visitTaskList[index].StudyList[obj.studyIndex].SeriesList[obj.seriesIndex].imageloadedArr.push(obj.imageId)
// }
},
setStatus({ state }, obj) {
var index = state.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId)
state.visitTaskList[index].IsInit = true
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
},
setActiveSeries({ state }, series) {
return new Promise(resolve => {
@@ -859,7 +1051,12 @@ const actions = {
},
setLastCanvasTaskId({ state }, taskId) {
return new Promise(resolve => {
state.lastCanvasTaskId = taskId
var isReadingTaskViewInOrder = localStorage.getItem('isReadingTaskViewInOrder')
if (parseInt(isReadingTaskViewInOrder) === 2) {
if (!state.lastCanvasTaskId) state.lastCanvasTaskId = taskId
} else {
state.lastCanvasTaskId = taskId
}
resolve()
})
},
@@ -875,6 +1072,9 @@ const actions = {
setImageQuality({ state }, imageQuality) {
state.imageQuality = isNaN(parseInt(imageQuality)) ? null : parseInt(imageQuality)
},
setImageQualityIssues({ state }, imageQualityIssues) {
state.imageQualityIssues = isNaN(parseInt(imageQualityIssues)) ? null : parseInt(imageQualityIssues)
},
addQuestionMeasuredData({ state }, obj) {
return new Promise(resolve => {
var index = state.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId)
@@ -891,7 +1091,7 @@ const actions = {
state.visitTaskList[index].QuestionMarkInfoList.push(obj.data)
console.log('新增标记成功')
}
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
})
},
@@ -907,7 +1107,7 @@ const actions = {
}
state.visitTaskList[index].QuestionMarkInfoList = measureData
}
sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
resolve()
})
}
+18 -1
View File
@@ -6,7 +6,12 @@ const getDefaultState = () => {
subjectQuery: null,
visitPlanQuery: null,
visitPointQuery: null,
studyListQuery: null
studyListQuery: null,
unlock: false,
config: {},
uploadTip: null,
timer: null,
whiteList: []
}
}
@@ -16,6 +21,12 @@ const mutations = {
RESET_TRIALS: (state) => {
Object.assign(state, getDefaultState())
},
SET_UNLOCK: (state, unlock) => {
state.unlock = unlock
},
SET_CONFIG: (state, config) => {
state.config = config
},
SET_ACTIVENAME: (state, activeName) => {
state.trialDetailActiveName = activeName
},
@@ -37,6 +48,12 @@ const mutations = {
}
const actions = {
setUnLock({ commit }, unlock) {
commit('SET_UNLOCK', unlock)
},
setConfig({ commit }, config) {
commit('SET_CONFIG', config)
},
setActiveName({ commit }, activeName) {
commit('SET_ACTIVENAME', activeName)
},
+32 -14
View File
@@ -1,5 +1,5 @@
import { getToken, setToken, removeToken, setName, removeName } from '@/utils/auth'
import { login, getUserMenuTree, getUserPermissions } from '@/api/user'
import { login, loginOut, getUserMenuTree, getUserPermissions } from '@/api/user'
import { resetRouter } from '@/router'
import md5 from 'js-md5'
@@ -78,22 +78,32 @@ const mutations = {
}
const actions = {
changeUserName({ commit }, userName) {
commit('SET_USERNAME', userName)
},
// user login
login({ commit }, userInfo) {
const { username, password } = userInfo
const { username, password, UserId } = userInfo
return new Promise((resolve, reject) => {
login({ UserName: username.trim(), Password: md5(password) }).then(async response => {
let data = {
UserName: username.trim(), Password: md5(password)
}
if (UserId) {
data.UserId = UserId;
}
login(data).then(async response => {
if (response.IsSuccess) {
zzSessionStorage.removeItem('lastWorkbench')
zzSessionStorage.setItem('my_username', username.trim())
zzSessionStorage.setItem('my_password', md5(password))
zzSessionStorage.setItem('my_EMail', response.Result.BasicInfo.EMail)
const data = response.Result
if (data.BasicInfo.IsFirstAdd) {
if (data.BasicInfo.IsFirstAdd || data.BasicInfo.LoginState === 1) {
try {
zzSessionStorage.setItem('userId', data.BasicInfo.Id)
commit('SET_TOKEN', data.JWTStr)
setToken(data.JWTStr)
resolve(false)
resolve(response.Result)
} catch (e) {
console.log(e)
}
@@ -104,6 +114,7 @@ const actions = {
zzSessionStorage.setItem('userName', data.BasicInfo.UserName)
commit('SET_TOKEN', data.JWTStr)
commit('SET_NAME', data.BasicInfo.RealName)
zzSessionStorage.setItem('realName', data.BasicInfo.RealName)
zzSessionStorage.setItem('isTestUser', data.BasicInfo.IsTestUser)
commit('SET_ISTESTUSER', data.BasicInfo.IsTestUser)
commit('SET_USERNAME', data.BasicInfo.UserName)
@@ -158,13 +169,13 @@ const actions = {
commit('SET_PERMISSIONS', JSON.parse(zzSessionStorage.getItem('permissions')))
commit('SET_ISTESTUSER', zzSessionStorage.getItem('isTestUser'))
const user = JSON.parse(userString)
commit('SET_NAME', user.realName)
commit('SET_NAME', zzSessionStorage.getItem('realName'))
commit('SET_USERID', user.id)
commit('SET_USERNAME', zzSessionStorage.getItem('userName'))
commit('SET_NEED_SIGN_SYSTEM_DOC_COUNT', parseInt(zzSessionStorage.getItem('TotalNeedSignSystemDocCount')))
commit('SET_NEED_SIGN_TRIALS_DOC_COUNT', parseInt(zzSessionStorage.getItem('TotalNeedSignTrialDocCount')))
console.log( zzSessionStorage.getItem('TotalNeedSignSystemDocCount'))
console.log( zzSessionStorage.getItem('TotalNeedSignTrialDocCount'))
console.log(zzSessionStorage.getItem('TotalNeedSignSystemDocCount'))
console.log(zzSessionStorage.getItem('TotalNeedSignTrialDocCount'))
zzSessionStorage.setItem('userName', user.name)
zzSessionStorage.setItem('userId', user.id)
zzSessionStorage.setItem('userTypeShortName', user.userTypeShortName)
@@ -175,12 +186,19 @@ const actions = {
commit('SET_NAME', zzSessionStorage.getItem('realName'))
},
// user logout
logout({ commit, state }) {
removeToken() // must remove token first
resetRouter()
removeName()
zzSessionStorage.clear()
commit('RESET_STATE')
async logout({ commit, state }) {
try {
removeToken() // must remove token first
await loginOut({
Userd: zzSessionStorage.getItem('userId')
})
resetRouter()
removeName()
zzSessionStorage.clear()
commit('RESET_STATE')
} catch (e) {
console.log(e)
}
},
setToken({ commit }, token) {
commit('SET_TOKEN', token)
+13 -7
View File
@@ -1,6 +1,5 @@
import dicomParser from "dicom-parser";
import dcmjs from './dcmjs'
import {encoder} from "./encoder";
export const anonymization = function (file, config) {
return new Promise(async (resolve, reject) => {
@@ -32,7 +31,7 @@ export const anonymization = function (file, config) {
if (AnonymizeNotFixed.Group + AnonymizeNotFixed.Element === '00100020') {
console.log(`${DicomStoreInfo.TrialCode}_${DicomStoreInfo.SubjectCode}`)
if (dataset.dict[AnonymizeNotFixed.Group + AnonymizeNotFixed.Element]) {
dataset.dict[AnonymizeNotFixed.Group + AnonymizeNotFixed.Element].Value[0] = `${DicomStoreInfo.TrialCode}-${DicomStoreInfo.SubjectCode}`
dataset.dict[AnonymizeNotFixed.Group + AnonymizeNotFixed.Element].Value[0] = `${DicomStoreInfo.TrialCode}-${DicomStoreInfo.SubjectCode}`
} else {
dataset.dict[AnonymizeNotFixed.Group + AnonymizeNotFixed.Element] = {
vr: AnonymizeNotFixed.ValueRepresentation,
@@ -54,14 +53,21 @@ export const anonymization = function (file, config) {
}
}
}
console.log(dataset)
let newDicomFile = dataset.write()
const bufferArray = new Uint8Array(newDicomFile)
const blob = new Blob([bufferArray], { type: 'application/octet-stream' })
resolve({blob, pixelDataElement})
// console.log(dataset)
try {
let newDicomFile = dataset.write()
const bufferArray = new Uint8Array(newDicomFile)
const blob = new Blob([bufferArray], { type: 'application/octet-stream' })
resolve({ blob, pixelDataElement })
} catch (err) {
console.log(file, 'warning')
console.log(err)
resolve(false);
}
};
reader.readAsArrayBuffer(file);
} catch (e) {
console.log(file, 'warning')
console.log(e)
reject(e)
}
+7 -5
View File
@@ -1,12 +1,13 @@
import Vue from 'vue'
import { encoder } from './encoder'
import { anonymization } from './anonymization'
export const dcmUpload = async function(name, file, config){
export const dcmUpload = async function (name, file, config) {
return new Promise(async resolve => {
try {
// let blob = await encoder(file, config)
// let blob = await fileToBlob(file)
let blob = await anonymization(file, config)
let blob = await fileToBlob(file)
if (config) {
blob = await anonymization(file, config)
}
let res = await Vue.prototype.OSSclient.put(name, blob.blob)
resolve({
...res,
@@ -18,6 +19,7 @@ export const dcmUpload = async function(name, file, config){
} catch (e) {
console.log(file, 'warning')
resolve(false)
console.log(e)
}
@@ -35,7 +37,7 @@ function fileToBlob(file) {
} else {
blob = e.target.result
}
resolve(blob)
resolve({ blob })
})
// FileReader 以 ArrayBuffer 格式 读取 File 对象中数据
reader.readAsArrayBuffer(file)
+1
View File
@@ -8359,6 +8359,7 @@
allowInvalidVRLength: false
};
var allowInvalidVRLength = writeOptions.allowInvalidVRLength;
allowInvalidVRLength = true
var valid = true,
valarr = Array.isArray(value) ? value : [value],
total = 0;
+17 -9
View File
@@ -2,10 +2,8 @@ const OSS = require('ali-oss')
const router = require('@/router');
const Minio = require('minio')
const stream = require('stream')
console.log(Minio)
import Vue from 'vue'
const { GenerateSTS, GetObjectStoreToken } = require('../api/user.js')
import { getToken } from '@/utils/auth'
const { GetObjectStoreToken } = require('../api/user.js')
Vue.prototype.OSSclientConfig = {
}
@@ -20,6 +18,7 @@ function blobToBuffer(blob, fileName) {
async function ossGenerateSTS() {
let res = await GetObjectStoreToken()
Vue.prototype.OSSclientConfig = { ...res.Result[res.Result.ObjectStoreUse] }
Vue.prototype.OSSclientConfig.ObjectStoreUse = res.Result.ObjectStoreUse;
Vue.prototype.OSSclientConfig.basePath = Vue.prototype.OSSclientConfig.viewEndpoint
switch (res.Result.ObjectStoreUse) {
case 'AliyunOSS':
@@ -40,7 +39,7 @@ async function ossGenerateSTS() {
if (res && res.url) {
resolve({
name: objectName,
url: Vue.prototype.OSSclientConfig.viewEndpoint + objectName
url: res.url
})
} else {
reject()
@@ -70,14 +69,14 @@ async function ossGenerateSTS() {
reader.onload = (ex) => {
const bufferStream = new stream.PassThrough()
bufferStream.end(Buffer.from(ex.target.result))
minioClient.putObject(Vue.prototype.OSSclientConfig.bucketName, objectName, bufferStream, function(err,etag) {
minioClient.putObject(Vue.prototype.OSSclientConfig.bucketName, objectName, bufferStream, function (err, etag) {
if (err) {
console.log(err)
reject()
} else {
resolve({
name: objectName,
url: 'http://www.abc.com' + objectName
url: Vue.prototype.OSSclientConfig.viewEndpoint + decodeUtf8(objectName)
})
}
})
@@ -107,14 +106,15 @@ async function ossGenerateSTS() {
reader.onload = (ex) => {
const bufferStream = new stream.PassThrough()
bufferStream.end(Buffer.from(ex.target.result))
aws.putObject(Vue.prototype.OSSclientConfig.bucketName, objectName, bufferStream, function(err,etag) {
aws.putObject(Vue.prototype.OSSclientConfig.bucketName, objectName, bufferStream, function (err, etag) {
if (err) {
console.log(err)
reject()
} else {
console.log(objectName);
resolve({
name: objectName,
url: 'http://www.abc.com' + objectName
url: Vue.prototype.OSSclientConfig.viewEndpoint + decodeUtf8(objectName)
})
}
})
@@ -129,7 +129,15 @@ async function ossGenerateSTS() {
}
return
}
function decodeUtf8(bytes) {
let str = bytes.split('?');
let str2 = str[0].split('/');
let name = str2[str2.length - 1];
name = encodeURIComponent(name);
str.shift();
str2.pop();
return str2.join("/") + '/' + name;
}
export const OSSclient = ossGenerateSTS
+202
View File
@@ -0,0 +1,202 @@
import * as dicomParser from "dicom-parser";
import * as cornerstone from "cornerstone-core";
import * as cornerstoneWADOImageLoader from "cornerstone-wado-image-loader";
cornerstoneWADOImageLoader.external.dicomParser = dicomParser;
cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
import { convertBytes } from "@/utils/dicom-character-set";
import Vue from 'vue';
import { dcmUpload } from "@/utils/dcmUpload/dcmUpload";
let dicom = {
PatientName: "x00100010", // 患者姓名
PatientId: "x00100020", // 患者ID
PatientBirthDate: "x00100030", // 患者出生日期
PatientBirthTime: "x00100032", // 患者出生时间
PatientSex: "x00100040", // 患者性别
PatientWeight: "x00101030", // 患者体重
PregnancyStatus: "x001021c0", // 怀孕状态
PatientAge: "x00101010", // 患者年龄(做检查时刻的患者年龄,而不是此刻患者的真实年龄)
AcquisitionTime: "x00080032",
AcquisitionNumber: "x00200012",
TriggerTime: "x00181060",
AccessionNumber: "x00080050", // 检查号
StudyId: "x00200010", // 检查ID
StudyInstanceUid: "x0020000d", // 检查实例号
StudyDate: "x00080020", // 检查日期
StudyTime: "x00080030", // 检查时间
Modalities: "x00080061", // 一个检查中含有的不同检查类型
BodyPartExamined: "x00080015", // 检查的部位
StudyDescription: "x00081030", // 检查的描述
InstitutionName: "x00080080",
SeriesNumber: "x00200011", // 序列号
SeriesInstanceUid: "x0020000e", // 序列实例号
Modality: "x00080060", // 检查模态
SeriesDescription: "x0008103e", // 检查描述和说明
SeriesDate: "x00080021", // 检查日期
SeriesTime: "x00080031", // 检查时间
SequenceName: "x00180024",
ProtocolName: "x00181030",
ImagePosition: "x00200032", // 图像位置
ImageOrientation: "x00200037", // 图像方位
ImagePixelSpacing: "x00181164",
SliceThickness: "x00180050", // 层厚
SpacingBetweenSlices: "x00180088", // 层间距
SliceLocation: "x00201041", // 相对位置
MRAcquisition: "x00180023",
seriesBodyPartExamined: "x00180015", // 身体部位
ImageType: "x00080008",
SopInstanceUid: "x00080018", // SOP实例UID
ContentDate: "x00080023", // 影像拍摄日期
ContentTime: "x00080033", // 影像拍摄时间
ImageOrInstanceNumber: "x00200013", // 图像码
SamplesPerPixel: "x00280002", // 图像采样率
PhotometricInterpretation: "x00280004", // 光度计(对于CT图像,用两个枚举值MONOCHROME1MONOCHROME2 用来判断图像是否是彩色的;MONOCHROME 1/2是灰度图,RGB则是真彩色图)
Rows: "x00280010", // 行数
Columns: "x00280011", // 列数
NumberOfFrames: "x00280008",
PixelSpacing: "x00280030", // 像素间距
BitsAllocated: "x00280100", // 分配的位数
BitsStored: "x00280101", // 存储的位数
HighBit: "x00280102", // 高位
PixelRepresentation: "x00280103", // 像素数据的表现类型(一个枚举值,分别为十六进制数0000和0001.0000H = 无符号整型,0001H = 2的补码)
WindowCenter: "x00281050", // 窗位
WindowWidth: "x002811051", // 窗宽
RescaleIntercept: "x00281052", // 截距
RescaleSlope: "x00281053", // 斜率
RescaleType: "x00281054", // 输出值的单位
ParsingFormat: "x00080005",
FrameOfReferenceUID: "x00200052",
};
// 需要设置默认值
let defaultKey = ['Rows', 'Columns', 'SliceLocation', 'NumberOfFrames'];
let uintKey = ['Rows', 'Columns'];
let intStringKey = ['SliceLocation', 'NumberOfFrames'];
// 需要格式解析
let pormatParseKey = ['PatientName', 'SeriesDescription', 'StudyDescription'];
// 解析dicom文件
export const parseDicom = (file, name = false) => {
return new Promise(function (resolve) {
let reader = new FileReader();
reader.onload = function (e) {
try {
let data = dicomParser.parseDicom(new Uint8Array(e.target.result));
let res = {};
if (name && Array.isArray(name)) {
name.forEach((item) => {
if (dicom[item]) {
res[item] = data.string(dicom[item]) || '';
}
});
} else if (name) {
if (dicom[name]) {
res[name] = data.string(dicom[name]) || '';
} else {
console.log("name is inexistence");
resolve(false)
}
} else {
Object.keys(dicom).forEach((key) => {
res[key] = data.string(dicom[key]) || '';
});
}
pormatParseKey.forEach(key => {
if (res[key]) {
const Element = data.elements[dicom[key]];
const Bytes = new Uint8Array(
data.byteArray.buffer,
Element ? Element.dataOffset : 0,
Element ? Element.length : 0
);
res[key] = convertBytes(
res.ParsingFormat,
Bytes
);
}
})
uintKey.forEach(key => {
res[key] = data.uint16(dicom[key])
})
intStringKey.forEach(key => {
res[key] = data.intString(dicom[key])
})
defaultKey.forEach(key => {
if (!res[key] && res.hasOwnProperty(key)) {
res[key] = 0;
}
})
resolve(res);
} catch (error) {
console.log(error)
resolve(false);
}
};
reader.onerror = function (e) {
console.log(e)
resolve(false);
};
reader.readAsArrayBuffer(file);
});
};
// 影像上传
// 影像上传
export const dicomToOSS = async (file, path) => {
try {
let res = await dcmUpload(path, file);
if (!res || !res.url) return false;
return Vue.prototype.$getObjectName(res.url);
} catch (err) {
console.log(err);
return false;
}
};
// 获取缩略图
export const getThumbnail = async (file, ossPath, dicomInfo) => {
try {
if (dicomInfo.modality !== "SR") {
let fileId = cornerstoneWADOImageLoader.wadouri.fileManager.add(file);
let blob = await dicomToPng(
fileId,
dicomInfo.Columns,
dicomInfo.Rows
);
if (!blob) return "";
let OSSclient = Vue.prototype.OSSclient;
let seriesRes = await OSSclient.put(ossPath, blob);
if (seriesRes && seriesRes.url) {
return Vue.prototype.$getObjectName(seriesRes.url);
} else {
return "";
}
} else {
return "";
}
} catch (err) {
console.log(err);
return "";
}
};
const canvasToBlob = (canvas) => {
return new Promise((resolve) => {
canvas.toBlob((blob) => {
resolve(blob);
});
});
};
const dicomToPng = (imageId, width, height) => {
return new Promise((resolve) => {
cornerstone.loadImage(imageId).then(async (image) => {
let canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
if (image) {
cornerstone.renderToCanvas(canvas, image);
// 将 Canvas 图像对象转换为 PNG 格式
let blob = await canvasToBlob(canvas);
resolve(blob);
} else {
resolve(false);
}
});
}).catch((reason) => {
reason();
});
};
+61 -36
View File
@@ -3,6 +3,8 @@ import { Message, MessageBox, Alert } from 'element-ui'
import store from '@/store'
import router from '@/router'
import Vue from 'vue'
import moment from 'moment-timezone';
console.log(moment.tz.guess())
axios.defaults.withCredentials = false
const service = axios.create({
baseURL: '/api',
@@ -18,7 +20,8 @@ service.interceptors.request.use(
path = router && router.app && router.app._route && router.app._route.path
config.headers['Content-Type'] = 'application/json;charset=UTF-8'
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()
if (store.getters.token) {
config.headers.Authorization = `Bearer ${store.getters.token}`
}
@@ -30,7 +33,7 @@ service.interceptors.request.use(
if (store.state.user.userId !== zzSessionStorage.getItem('userId')) {
window.location.href = `/login`
zzSessionStorage.removeItem('lastWorkbench')
Alert(store.state.lang.language === 'en'? 'The same browser only allows one user account to be logged in at a time.' : '同一浏览器只允许同时登陆一个账户', {
Alert(store.state.lang.language === 'en' ? 'The same browser only allows one user account to be logged in at a time.' : '同一浏览器只允许同时登陆一个账户', {
type: 'warning',
})
}
@@ -46,20 +49,24 @@ service.interceptors.request.use(
}
)
var isConfirm = true
let timer = null;
let time = 1000;
service.interceptors.response.use(
response => {
const res = response.data
if (res.IsSuccess) {
isConfirm = true
return Promise.resolve(res)
} else if (res.IsSuccess === false) {
if (res.Code !== 5) {
MessageBox.confirm(res.ErrorMessage, {
MessageBox.confirm(res.ErrorMessage, {
type: 'warning',
showCancelButton: false,
callback: action => {}
callback: action => {
if (res.Code === 6) {
window.close()
}
}
})
}
return Promise.reject(res)
@@ -71,7 +78,7 @@ service.interceptors.response.use(
var message = ''
if (error && error.response) {
const status = error.response.status
if (error.response.data && error.response.data.Code === -1) {
if (error.response.data && (error.response.data.Code === -1 || error.response.data.Code === -2)) {
store.dispatch('user/logout').then(() => {
router.push(`/login`)
this.$i18n.locale = 'zh'
@@ -80,29 +87,29 @@ service.interceptors.response.use(
})
}
switch (status) {
case 400: message = store.state.lang.language === 'en'? 'Request error' : '请求错误'; break
case 401: message = store.state.lang.language === 'en'? 'Not authorized or login timed out. Please log in again.' : '未授权或登陆超时,请重新登录'; break
case 400: message = store.state.lang.language === 'en' ? 'Request error' : '请求错误'; break
case 401: message = store.state.lang.language === 'en' ? 'Not authorized or login timed out. Please log in again.' : '未授权或登陆超时,请重新登录'; break
case 403: message = error.response.data.ErrorMessage; break
case 404: message = store.state.lang.language === 'en'? 'Request address error' : `请求地址出错`; break
case 405: message = store.state.lang.language === 'en'? 'Interface parameter error or request method inconsistency' : `接口参数传递错误,或者请求方法不一致`; break
case 408: message = store.state.lang.language === 'en'? 'Request timed out' : '请求超时'; break
case 429: message = store.state.lang.language === 'en'? 'The application service limits the traffic. Your requests are too frequent. Please try again later.' : '应用服务限流,您的请求过于频繁,请稍后再试'; break
case 500: message = store.state.lang.language === 'en'? 'Internal server error, and unable to complete the request. Software release might be in process. Please contact the administrator.' : '服务器内部错误,无法完成请求;可能正在发布中,请联系管理员处理'; break
case 501: message = store.state.lang.language === 'en'? 'Service has not been implemented.' : '服务未实现'; break
case 502: message = store.state.lang.language === 'en'? 'System is being upgraded. Please wait patiently.' : '系统正在升级,请耐心等待。'; break
case 503: message = store.state.lang.language === 'en'? 'Service is not available' : '服务不可用'; break
case 504: message = store.state.lang.language === 'en'? 'Gateway timed out' : '网关超时'; break
case 505: message = store.state.lang.language === 'en'? 'HTTP version is not supported' : 'HTTP版本不受支持'; break
case 404: message = store.state.lang.language === 'en' ? 'Request address error' : `请求地址出错`; break
case 405: message = store.state.lang.language === 'en' ? 'Interface parameter error or request method inconsistency' : `接口参数传递错误,或者请求方法不一致`; break
case 408: message = store.state.lang.language === 'en' ? 'Request timed out' : '请求超时'; break
case 429: message = store.state.lang.language === 'en' ? 'The application service limits the traffic. Your requests are too frequent. Please try again later.' : '应用服务限流,您的请求过于频繁,请稍后再试'; break
case 500: message = store.state.lang.language === 'en' ? 'Internal server error, and unable to complete the request. Software release might be in process. Please contact the administrator.' : '服务器内部错误,无法完成请求;可能正在发布中,请联系管理员处理'; break
case 501: message = store.state.lang.language === 'en' ? 'Service has not been implemented.' : '服务未实现'; break
case 502: message = store.state.lang.language === 'en' ? 'System is being upgraded. Please wait patiently.' : '系统正在升级,请耐心等待。'; break
case 503: message = store.state.lang.language === 'en' ? 'Service is not available' : '服务不可用'; break
case 504: message = store.state.lang.language === 'en' ? 'Gateway timed out' : '网关超时'; break
case 505: message = store.state.lang.language === 'en' ? 'HTTP version is not supported' : 'HTTP版本不受支持'; break
default: break
}
if (error.response.status === 401) {
if (store.getters.token) {
if(message !== ''){
Message({
if (message !== '') {
setTimer({
message: message,
type: 'warning',
showClose: true
})
}, 'message')
}
store.dispatch('user/logout').then(() => {
router.push(`/login`)
@@ -111,34 +118,52 @@ service.interceptors.response.use(
this.$updateDictionary()
})
} else {
Message({
message: store.state.lang.language === 'en'? 'You are not authorized to access the interface' : '您无权访问接口',
setTimer({
message: store.state.lang.language === 'en' ? 'You are not authorized to access the interface' : '您无权访问接口',
type: 'warning',
showClose: true
})
}, 'message')
}
} else {
if(message !== '' && isConfirm){
MessageBox.confirm(message, store.state.lang.language === 'en'? 'Warning' : '警告', {
if (message !== '') {
setTimer([message, store.state.lang.language === 'en' ? 'Warning' : '警告', {
type: 'warning',
showCancelButton: false,
callback: action => {}
})
callback: action => { }
}], 'confirm')
}
}
}
if (!window.navigator.onLine && isConfirm) {
MessageBox.confirm(store.state.lang.language === 'en'? 'Please check your networkand try again later' : '请检查网络,稍后重试!', store.state.lang.language === 'en'? 'Warning' : '警告', {
type: 'warning',
showCancelButton: false,
callback: action => {}
})
isConfirm = false
if (!window.navigator.onLine) {
setTimer(
[store.state.lang.language === 'en' ? 'Please check your networkand try again later' : '请检查网络,稍后重试!', store.state.lang.language === 'en' ? 'Warning' : '警告', {
type: 'warning',
showCancelButton: false,
callback: action => { }
}], "confirm"
)
}
return Promise.reject(new Error(message || 'Error'))
}
)
const setTimer = (obj, type) => {
if (timer) {
clearTimeout(timer);
timer = null;
}
timer = setTimeout(() => {
if (type === 'message') {
Message(obj)
}
if (type === 'confirm') {
MessageBox.confirm(...obj)
}
clearTimeout(timer);
timer = null;
}, time)
}
+168
View File
@@ -0,0 +1,168 @@
import Vue from 'vue';
import store from "@/store";
import {
requestPackageAndAnonymizImage,
} from "@/api/load.js";
import streamSaver from "streamsaver";
import "streamsaver/examples/zip-stream.js"
let flag = {};
export const resetFlag = () => {
flag = {};
store.state.trials.uploadTip = null;
if (store.state.trials.timer) {
clearInterval(store.state.trials.timer);
store.state.trials.timer = null;
}
store.dispatch("trials/setUnLock", false);
}
export const downloadImage = async (id, id2, IsDicom = true) => {
// if (flag[`${id2}_${IsDicom}`]) return Vue.prototype.$message.warning(Vue.prototype.$t('trials:upload:tip:uploading'));
if (flag[`${id2}_${IsDicom}`]) return false;
flag[`${id2}_${IsDicom}`] = true
try {
let params = {
TrialId: id,
SubjectVisitId: id2,
IsDicom: IsDicom
}
store.dispatch("trials/setUnLock", true);
let res = await requestPackageAndAnonymizImage(params);
if (res.IsSuccess) {
if (!res.Result) {
flag[`${id2}_${IsDicom}`] = false;
// Vue.prototype.$message.warning(Vue.prototype.$t("trials:upload:message:not"))
let message = Vue.prototype.$t('trials:upload:tip:uploading').replace("xxx", res.OtherInfo.FileName);
store.state.trials.uploadTip = message;
if (!store.state.trials.timer) {
store.state.trials.timer = setInterval(() => {
downloadImage(id, id2, IsDicom);
}, 2000);
}
return false;
}
if (store.state.trials.timer) {
clearInterval(store.state.trials.timer);
store.state.trials.timer = null;
}
let fileName = res.Result.split("/").pop();
let href = Vue.prototype.OSSclientConfig.basePath + res.Result;
if (fileName !== res.OtherInfo.FileName) {
let message = Vue.prototype.$t('trials:upload:tip:uploading').replace("xxx", res.OtherInfo.FileName);
store.state.trials.uploadTip = message;
// Vue.prototype.$message.success(Vue.prototype.$t("trials:upload:message:startUpload"));
return download(href, res.OtherInfo.FileName, { id2, IsDicom });
}
let a = document.createElement("a");
a.download = res.OtherInfo.FileName;
a.href = href;
a.click();
URL.revokeObjectURL(href);
let timer = setTimeout(() => {
a = null;
href = null;
timer = null;
}, 500)
store.state.trials.uploadTip = null;
return true;
} else {
flag[`${id2}_${IsDicom}`] = false;
return false;
}
} catch (err) {
flag[`${id2}_${IsDicom}`] = false;
console.log(err);
}
};
export const fileDownload = (content, filename) => {
const eleLink = document.createElement("a");
eleLink.download = filename;
eleLink.style.display = "none";
const blob = new Blob([content]);
eleLink.href = URL.createObjectURL(blob);
document.body.appendChild(eleLink);
eleLink.click();
document.body.removeChild(eleLink);
};
let download = async (downloadUrl, downloadFileName, res) => {
const blob = await getBlob(downloadUrl);
flag[`${res.id2}_${res.IsDicom}`] = false;
store.state.trials.uploadTip = null;
store.dispatch("trials/setUnLock", false);
saveAsB(blob, downloadFileName);
return true;
}
let getBlob = (url) => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onload = () => {
if (xhr.status === 200) {
resolve(xhr.response);
} else {
reject(new Error(`Request failed with status ${xhr.status}`));
}
};
xhr.onerror = () => {
reject(new Error('Request failed'));
};
xhr.send();
});
}
let saveAsB = (blob, filename) => {
const link = document.createElement('a');
const body = document.body;
link.href = window.URL.createObjectURL(blob);
link.download = filename;
// hide the link
link.style.display = 'none';
body.appendChild(link);
link.click();
body.removeChild(link);
window.URL.revokeObjectURL(link.href);
}
// 前端流式打包下载
const handleBatchDown = async (item, zip) => {
return new Promise((resolve) => {
console.log("同步下载打包开始时间:" + new Date());
// 创建压缩文件输出流
const zipFileOutputStream = streamSaver.createWriteStream(zipName);
// 创建下载文件流
const fileIterator = files.values();
const readableZipStream = new window.ZIP({
async pull(ctrl) {
const fileInfo = fileIterator.next();
if (fileInfo.done) {//迭代终止
ctrl.close();
} else {
const { name, url } = fileInfo.value;
return fetch(url).then(res => {
ctrl.enqueue({
name,
stream: () => res.body
})
})
}
}
});
if (window.WritableStream && readableZipStream.pipeTo) {
// 开始下载
readableZipStream
.pipeTo(zipFileOutputStream)
.then(() => { console.log("同步下载打包结束时间:" + new Date()); resolve(true) })
} else {
resolve(false);
}
})
};
+135 -137
View File
@@ -1,137 +1,135 @@
<template>
<div class="app-container menu">
<el-tree
:props="defaultProps"
:data="treeData"
node-key="Id"
:default-expand-all="true"
:expand-on-click-node="false"
style="width:80%;"
>
<span slot-scope="{ node, data }" class="custom-tree-node">
<span v-if="data.FunctionName">{{ node.label }} --------------------(Function)</span>
<span v-else>{{ node.label }}</span>
<span>
<el-button type="text" icon="el-icon-plus" size="small" @click="() => append(data)">Append</el-button>
<el-button
type="text"
icon="el-icon-edit"
size="small"
@click="() => edit(data)"
>Edit</el-button>
<el-button type="text" icon="el-icon-delete" size="small" @click="() => remove(data)">Delete</el-button>
</span>
</span>
</el-tree>
<menu-form v-if="model_cfg.visible" :form="currenNode" width="500px" @close="closeModel" />
</div>
</template>
<script>
import { getMenuFunction, deleteMenuFunction } from '@/api/admin'
import MenuForm from './components/MenuForm'
import { model_cfg } from './menu'
export default {
name: 'Menu',
components: { MenuForm },
data() {
return {
model_cfg,
treeData: [],
defaultProps: {
label: 'MenuName',
children: 'Children'
},
dialogVisible: false,
title: '',
currenNode: {},
nodeId: '',
parentId: ''
}
},
mounted() {
this.getlist()
},
methods: {
//
getlist() {
const loading = this.$loading({
target: document.querySelector('.menu'),
fullscreen: false,
lock: true,
text: 'Loading',
spinner: 'el-icon-loading'
})
getMenuFunction().then(res => {
loading.close()
this.treeData = res.Result
}).catch(() => { loading.close() })
},
//
append(node) {
this.currenNode = {}
this.currenNode.ParentId = node.Id
this.currenNode.Status = 1
// this.currenNode.ShowOrder = 0
this.nodeId = node.Id
this.model_cfg.title = 'Append'
this.model_cfg.visible = true
},
//
edit(node) {
// eslint-disable-next-line no-unused-vars
const { Children, CreateTime, CreateUserId, UpdateTime, UpdateUserId, ...obj } = JSON.parse(JSON.stringify(node))
obj.MetaBreadcrumb = obj.MetaBreadcrumb ? 1 : 0
obj.Hidden = obj.Hidden ? 1 : 0
this.currenNode = obj
this.nodeId = node.Id
this.model_cfg.title = 'Edit'
this.model_cfg.visible = true
},
//
remove(node) {
this.$confirm('Sure to delete?', {
type: 'warning',
distinguishCancelAndClose: true,
confirmButtonText: 'Ok',
cancelButtonText: 'Cancel'
})
.then(() => {
deleteMenuFunction(node.Id)
.then(res => {
if (res.IsSuccess) {
this.getlist()
this.$message.success('Deleted successfully!')
}
})
})
},
//
closeModel() {
this.model_cfg.visible = false
this.getlist()
}
}
}
</script>
<style lang="scss">
.menu{
.el-tree {
margin-top: 20px;
}
.el-tree-node{
margin-top: 5px;
}
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
.el-dialog__body{
padding: 10px;
}
}
</style>
<template>
<div class="app-container menu">
<el-tree
:props="defaultProps"
:data="treeData"
node-key="Id"
:default-expand-all="true"
:expand-on-click-node="false"
style="width:80%;"
>
<span slot-scope="{ node, data }" class="custom-tree-node">
<span v-if="data.FunctionName">{{ node.label }} --------------------(Function)</span>
<span v-else>{{ node.label }}</span>
<span>
<el-button type="text" icon="el-icon-plus" size="small" @click="() => append(data)">Append</el-button>
<el-button
type="text"
icon="el-icon-edit"
size="small"
@click="() => edit(data)"
>Edit</el-button>
<el-button type="text" icon="el-icon-delete" size="small" @click="() => remove(data)">Delete</el-button>
</span>
</span>
</el-tree>
<menu-form v-if="model_cfg.visible" :form="currenNode" width="500px" @close="closeModel" />
</div>
</template>
<script>
import { getMenuFunction, deleteMenuFunction } from '@/api/admin'
import MenuForm from './components/MenuForm'
import { model_cfg } from './menu'
export default {
name: 'Menu',
components: { MenuForm },
data() {
return {
model_cfg,
treeData: [],
defaultProps: {
label: 'MenuName',
children: 'Children'
},
dialogVisible: false,
title: '',
currenNode: {},
nodeId: '',
parentId: ''
}
},
mounted() {
this.getlist()
},
methods: {
//
getlist() {
const loading = this.$loading({
target: document.querySelector('.menu'),
fullscreen: false,
lock: true,
text: 'Loading',
spinner: 'el-icon-loading'
})
getMenuFunction().then(res => {
loading.close()
this.treeData = res.Result
}).catch(() => { loading.close() })
},
//
append(node) {
this.currenNode = {}
this.currenNode.ParentId = node.Id
this.currenNode.Status = 1
// this.currenNode.ShowOrder = 0
this.nodeId = node.Id
this.model_cfg.title = 'Append'
this.model_cfg.visible = true
},
//
edit(node) {
// eslint-disable-next-line no-unused-vars
const { Children, CreateTime, CreateUserId, UpdateTime, UpdateUserId, ...obj } = JSON.parse(JSON.stringify(node))
obj.MetaBreadcrumb = obj.MetaBreadcrumb ? 1 : 0
obj.Hidden = obj.Hidden ? 1 : 0
this.currenNode = obj
this.nodeId = node.Id
this.model_cfg.title = 'Edit'
this.model_cfg.visible = true
},
//
remove(node) {
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
type: 'warning',
distinguishCancelAndClose: true
})
.then(() => {
deleteMenuFunction(node.Id)
.then(res => {
if (res.IsSuccess) {
this.getlist()
this.$message.success(this.$t('common:message:deletedSuccessfully'))
}
})
})
},
//
closeModel() {
this.model_cfg.visible = false
this.getlist()
}
}
}
</script>
<style lang="scss">
.menu{
.el-tree {
margin-top: 20px;
}
.el-tree-node{
margin-top: 5px;
}
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
.el-dialog__body{
padding: 10px;
}
}
</style>
+3 -4
View File
@@ -89,16 +89,15 @@ export default {
})
},
handleDeleteRole(row) {
this.$confirm('Sure to delete?', {
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
type: 'warning',
distinguishCancelAndClose: true,
confirmButtonText: 'Ok',
cancelButtonText: 'Cancel'
}).then(() => {
deleteUserTypeRole(row.Id).then((res) => {
if (res.IsSuccess) {
this.list.splice(this.list.findIndex((item) => item.Id === row.Id), 1)
this.$message.success('Deleted successfully!')
this.$message.success(this.$t('common:message:deletedSuccessfully'))
}
})
})
+38 -39
View File
@@ -1,39 +1,38 @@
<template>
<el-card class="box-card" style="width:800px;" size="small">
<!-- <div slot="header" class="clearfix">
<span>Security</span>
</div> -->
<div>
<el-button type="danger" @click="handleReset">Reset Password</el-button>
</div>
</el-card>
</template>
<script>
import { resetPassword } from '@/api/admin'
export default {
name: 'Account',
props: {
userId: { type: String, default: '' }
},
methods: {
handleReset() {
this.$confirm('Sure to reset password?', {
type: 'warning',
distinguishCancelAndClose: true,
confirmButtonText: 'Ok',
cancelButtonText: 'Cancel'
})
.then(() => {
resetPassword(this.userId).then(res => {
if (res.IsSuccess) {
this.$message({
message: 'Reset password successfully',
type: 'success'
})
}
})
})
}
}
}
</script>
<template>
<el-card class="box-card" style="width:800px;" size="small">
<!-- <div slot="header" class="clearfix">
<span>Security</span>
</div> -->
<div>
<el-button type="danger" @click="handleReset">Reset Password</el-button>
</div>
</el-card>
</template>
<script>
import { resetPassword } from '@/api/admin'
export default {
name: 'Account',
props: {
userId: { type: String, default: '' }
},
methods: {
handleReset() {
this.$confirm('Sure to reset password?', {
type: 'warning',
distinguishCancelAndClose: true,
})
.then(() => {
resetPassword(this.userId).then(res => {
if (res.IsSuccess) {
this.$message({
message: 'Reset password successfully',
type: 'success'
})
}
})
})
}
}
}
</script>
+3 -4
View File
@@ -113,18 +113,17 @@ export default {
},
//
handleDeleteUser(data) {
this.$confirm('Sure to delete?', {
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
type: 'warning',
distinguishCancelAndClose: true,
confirmButtonText: 'Ok',
cancelButtonText: 'Cancel'
})
.then(() => {
deleteSysUser(data.Id)
.then(res => {
if (res.IsSuccess) {
this.users.splice(this.users.findIndex(item => item.Id === data.Id), 1)
this.$message.success('Deleted successfully!')
this.$message.success(this.$t('common:message:deletedSuccessfully'))
}
})
})
@@ -14,27 +14,26 @@
<span v-else>{{ employment.RankCN }}</span>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item :label="$t('resumeInfo:label:Physician')">
<span v-if="isEnglish">{{ employment.Physician }}</span>
<span v-else>{{ employment.PhysicianCN }}</span>
</el-form-item>
</el-col>
<!-- <el-col :span="6">-->
<!-- <el-form-item :label="$t('resumeInfo:label:Physician')">-->
<!-- <span v-if="isEnglish">{{ employment.Physician }}</span>-->
<!-- <span v-else>{{ employment.PhysicianCN }}</span>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<el-col :span="6">
<el-form-item :label="$t('resumeInfo:label:Position')">
<span v-if="isEnglish">{{ employment.Position }}</span>
<span v-else>{{ employment.PositionCN }}</span>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="6">
<el-form-item :label="$t('resumeInfo:label:Hospital')">
<span v-if="isEnglish">{{ employment.HospitalName }}</span>
<span v-else>{{ employment.HospitalNameCN }}</span>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="6">
<el-form-item :label="$t('resumeInfo:label:Affiliated')">
<span v-if="isEnglish">{{ employment.UniversityAffiliated }}</span>
+4 -2
View File
@@ -90,11 +90,12 @@ export default {
this.setLanguage('zh')
this.$updateDictionary()
}
this.title = this.doctorInfo.BasicInfoView?`${this.doctorInfo.BasicInfoView.FirstName} ${this.doctorInfo.BasicInfoView.LastName}${this.$t('resumeInfo:title:Details')}`:''
this.title = this.doctorInfo.BasicInfoView?`${this.doctorInfo.BasicInfoView.BlindName}${this.$t('resumeInfo:title:Details')}`:''
}
},
mounted() {
this.isEnglish = !!((this.$route.query.isEnglish === true || this.$route.query.isEnglish === 'true'))
this.isEnglish = this.$i18n.locale === 'zh' ? false : true
this.doctorId = this.$route.query.doctorId
this.initForm()
},
@@ -135,6 +136,7 @@ export default {
} else {
this.workInfo.Position = this.workInfo.Position
this.workInfo.PositionCN = this.workInfo.PositionCN
//
}
this.workInfo.PositionOther = this.workInfo.PositionOther ? 'Other - ' + this.workInfo.PositionOther : 'Other'
}
@@ -179,7 +181,7 @@ export default {
this.holiday = res.Result.InHoliday ? 'Yes' : 'No'
this.doctorInfo = res.Result
!this.doctorInfo.ResearchPublicationView ? this.doctorInfo.ResearchPublicationView = {} : '';
this.title = `${this.doctorInfo.BasicInfoView.BlindName} 's Details`
this.title = this.doctorInfo.BasicInfoView?`${this.doctorInfo.BasicInfoView.BlindName}${this.$t('resumeInfo:title:Details')}`:''
this.htmlTitle = this.title
this.initStatus()
this.initEmploymentInfo()
+1 -2
View File
@@ -126,8 +126,7 @@ export default {
this.$confirm('Sure to sign out', {
type: 'warning',
distinguishCancelAndClose: true,
confirmButtonText: 'Ok',
cancelButtonText: 'Cancel'
})
.then(() => {
this.$store.dispatch('user/logout').then(res => {
+16 -11
View File
@@ -8,10 +8,10 @@
<!-- <div class="studyDesc" style="border-bottom:1px solid #9e9e9e;" @click="closeDialog()">
<span style="font-size:14px;color:#d0d0d0;margin:5px 0px;line-height: 25px;">返回列表</span>
</div> -->
<div class="studyDesc" style="line-height: 10px;">
<div class="studyDesc">
{{ studyTitle }}
</div>
<div class="studyDesc" style="line-height: 10px">
<div class="studyDesc">
{{ seriesCount }} Series
</div>
<div class="viewerSidethumbs ps" style="position: relative;">
@@ -38,11 +38,12 @@
</span>
</span>-->
<div class="viewernavitextwrapper">
<div style="padding: 1px;">#{{ item.seriesTitle }}</div>
<div style="padding: 1px;">#{{ item.seriesNumber }}</div>
<div style="padding: 1px;">{{ item.description }}</div>
<div
v-show="item.instanceCount"
style="padding: 1px;"
>{{ item.instanceCount }} image
>{{ item.modality }} : {{ item.instanceCount }} Series
</div>
</div>
</div>
@@ -63,7 +64,7 @@
import * as dicomParser from 'dicom-parser'
import * as cornerstone from 'cornerstone-core'
import * as cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader'
import dicomStore from '@/utils/dicom-store.js'
import dicomStore from '@/utils/dicom-store'
import dicomViewer from '@/components/Dicom/DicomViewer'
import dicomPreview from '@/components/Dicom/DicomPreview'
@@ -86,6 +87,10 @@ export default {
uid: {
type: String,
default: ''
},
studyList: {
type: Array,
default: []
}
},
@@ -102,7 +107,7 @@ export default {
var totalHeight = window.innerHeight || document.body.clientHeight
var wrapper = this.$refs['preview-wrapper']
wrapper.style.height = (totalHeight - 70) + 'px'
if (!dicomStore.studyList || !this.uid) return
if (!this.studyList || !this.uid) return
this.loadStudy()
},
@@ -120,15 +125,14 @@ export default {
return newObj
},
loadStudy() {
var studyList = dicomStore.studyList
var studyList = this.studyList
var studyUid = this.uid
var studyItem = studyList.find(function(item) {
return item.dicomInfo.studyUid === studyUid
})
if (!studyItem) return
this.studyTitle =
studyItem.dicomInfo.patientName || studyItem.dicomInfo.description
this.studyTitle = studyItem.dicomInfo.description
this.seriesCount = studyItem.seriesList.length
var scope = this
@@ -151,7 +155,8 @@ export default {
scope.seriesList.push({
seriesNumber: series.seriesNumber,
seriesTitle: series.description || series.modality || '(Anonymous)',
description: series.description,
modality: series.modality,
instanceCount: series.instanceList.length,
imageIds: imageIds,
previewImageId: imageIds[0]
@@ -253,7 +258,7 @@ export default {
text-align: center;
background: rgb(88 84 83);
color: #d0d0d0;
padding: 2px;
padding: 5px;
}
.ps {
+387 -249
View File
@@ -43,45 +43,73 @@
fit="fill"
>
<div class="viewernavitextwrapper">
<div v-if="item.keySeries" style="padding: 1px;color:red">
Key Images
</div>
<div v-else style="padding: 1px;">
#{{ item.seriesNumber }}
<div style="padding: 1px 5px 1px 1px;display: flex;justify-content: space-between;">
<div v-if="item.keySeries" style="color:red">
Key Images
</div>
<div v-else>
#{{ item.seriesNumber }}
</div>
<div v-if="item.isExistMutiFrames && item.instanceCount > 1">
<el-popover
placement="right"
trigger="hover"
popper-class="instance_frame_wrapper"
>
<div class="frame_list">
<div
v-for="(instance, idx) in item.instanceInfoList"
:key="instance.Id"
class="frame_content"
:style="{'margin-bottom':idx<item.instanceInfoList.length-1? '5px':'0px'}"
@click="showMultiFrames(item, index, instance)"
>
<div>
<div>{{ instance.InstanceNumber }}</div>
<div>{{ `${instance.NumberOfFrames > 0 ? instance.NumberOfFrames : 1} frame` }}</div>
</div>
</div>
</div>
<i slot="reference" class="el-icon-connection" style="font-size: 15px;cursor: pointer;" />
</el-popover>
</div>
</div>
<div v-show="item.instanceCount" style="padding: 1px;">
{{ item.modality }}: {{ item.instanceCount }} image
</div>
<div v-show="!item.keySeries && item.sliceThickness" style="padding: 1px;">
T: {{ item.sliceThickness }}
T: {{ parseFloat(item.sliceThickness).toFixed(2) }}
</div>
<div v-show="!item.keySeries &&item.description" style="width: 120px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;padding: 1x;">
{{ item.description }}
</div>
<div v-if="!item.keySeries" style="padding: 1px;">
{{ item.prefetchInstanceCount }}/{{ item.instanceCount }}
{{ item.imageloadedArr.length }}/{{ item.instanceCount }}
</div>
</div>
</div>
<div v-if="showDelete" @click.stop="">
<div v-if="showDelete" style="display: flex;flex-direction: row;justify-content: space-between;" @click.stop="">
<span style="font-size: 12px;">{{ $t('trials:audit:table:isReading') }}</span>
<el-switch
v-model="item.isReading"
size="mini"
@change="changeReadingStatus($event, item)"
/>
<span style="font-size: 12px;">{{ $t('trials:audit:table:isDelete') }}</span>
<el-switch
v-model="item.isDeleted"
size="mini"
@change="changeDeleteStatus($event, item)"
/>
<div>
<span style="font-size: 12px;margin-right: 5px">{{ $t('trials:audit:table:isReading') }}</span>
<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 v-if="item.prefetchInstanceCount>0 && item.prefetchInstanceCount<item.instanceCount">
<el-progress :percentage="parseInt(((item.prefetchInstanceCount/item.instanceCount)*100).toFixed(2))" />
<div v-if="item.prefetchInstanceCount>0 && item.prefetchInstanceCount<item.instanceCount * 100">
<el-progress :percentage="parseInt((item.prefetchInstanceCount/item.instanceCount).toFixed(2))" />
</div>
</div>
@@ -117,7 +145,8 @@ import store from '@/store'
import { changeURLStatic } from '@/utils/history.js'
cornerstoneWADOImageLoader.external.dicomParser = dicomParser
cornerstoneWADOImageLoader.external.cornerstone = cornerstone
const maximumSizeInBytes = 1024 * 1024 * 1024 // 1 GB
const maximumSizeInBytes = 1024 * 1024 * 1024 * 6
cornerstone.imageCache.setMaximumSizeBytes(maximumSizeInBytes)
export default {
components: {
'dicom-viewer': dicomViewer
@@ -153,10 +182,13 @@ export default {
showDelete: false,
loading: false,
imageList: [],
showSeriesList: []
showSeriesList: [],
currentLoadIns: [],
isFromCRCUpload: false
}
},
created: function() {
requestPoolManager.resetRequestPool()
this.type = this.$router.currentRoute.query.type ? this.$router.currentRoute.query.type : ''
this.visitNum = this.$router.currentRoute.query.visitNum ? parseInt(this.$router.currentRoute.query.visitNum) : 0
@@ -167,6 +199,7 @@ export default {
changeURLStatic('TokenKey', '')
}
this.studyId = this.$router.currentRoute.query.studyId
this.isFromCRCUpload = !!this.$router.currentRoute.query.isFromCRCUpload
if (this.type === 'Series') {
// this.initStudy()
this.showDelete = parseInt(this.$router.currentRoute.query.showDelete)
@@ -177,49 +210,60 @@ export default {
} else if (this.type === 'Share') {
this.loadStudy()
}
cornerstone.events.addEventListener('cornerstoneimageloadprogress', this.cornerstoneimageloadprogress)
window.addEventListener('beforeunload', e => {
cornerstone.imageCache.purgeCache()
requestPoolManager.resetRequestPool()
})
},
beforeDestroy() {
requestPoolManager.stopTaskTimer()
window.removeEventListener('beforeunload', e => {
cornerstone.imageCache.purgeCache()
requestPoolManager.resetRequestPool()
})
},
methods: {
loadStudy() {
var scope = this
getStudyInfo(scope.studyId).then(data => {
if (data.IsSuccess) {
scope.studyCode = data.Result.StudyCode
scope.modality = data.Result.Modalities
scope.seriesCount = data.Result.SeriesCount
scope.description = data.Result.Description
var url = `/series/list/${scope.studyId}`
scope.getSeriesList(url)
}
})
async loadStudy() {
const data = await getStudyInfo(this.studyId)
if (data.IsSuccess) {
this.studyCode = data.Result.StudyCode
this.modality = data.Result.Modalities
this.seriesCount = data.Result.SeriesCount
this.description = data.Result.Description
const url = `/series/list/${this.studyId}`
this.getSeriesList(url)
}
},
getSeriesList(url) {
var scope = this
getSeriesList(url).then(data => {
async getSeriesList(url) {
try {
const data = await getSeriesList(url)
if (data.IsSuccess) {
const { Result } = data
var seriesList = []
Result.forEach(function(item) {
Result.forEach((item, index) => {
const imageIds = []
// item.InstanceList.forEach(function(id) {
// imageIds.push(`wadouri:/api/instance/content/${id}`)
// })
// item.InstanceList.forEach((id) => {
// imageIds.push(`wadouri:http://123.56.94.154:7000/instance/content/${id}`)
// })
item.InstancePathList.forEach((path) => {
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? scope.OSSclientConfig.basePath : scope.OSSclientConfig.basePath}${path}`)
item.InstanceInfoList.forEach(i => {
if (i.NumberOfFrames && i.NumberOfFrames > 1) {
for (let j = 0; j < i.NumberOfFrames; j++) {
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${i.Path}?frame=${j}&instanceId=${i.Id}&seriesIndex=${index}`)
}
i.ImageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${i.Path}?frame=0&instanceId=${i.Id}&seriesIndex=${index}`
} else {
const imageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${i.Path}?instanceId=${i.Id}&seriesIndex=${index}`
imageIds.push(imageId)
i.ImageId = imageId
}
})
var subjectVisitId = scope.$router.currentRoute.query.subjectVisitId
var studyId = scope.$router.currentRoute.query.studyId
var trialId = scope.$router.currentRoute.query.trialId
var subjectVisitId = this.$router.currentRoute.query.subjectVisitId
var studyId = this.$router.currentRoute.query.studyId
var trialId = this.$router.currentRoute.query.trialId
seriesList.push({
trialId,
subjectVisitId,
studyId,
imageIds: imageIds,
instanceInfoList: item.InstanceInfoList,
seriesId: item.Id,
seriesUid: item.SeriesInstanceUid,
seriesNumber: item.SeriesNumber,
@@ -228,71 +272,84 @@ export default {
description: item.Description,
isReading: item.IsReading,
isDeleted: item.IsDeleted,
previewImageUrl: item.ImageResizePath ? scope.OSSclientConfig.basePath + item.ImageResizePath : `/api/series/preview/${item.Id}`,
previewImageUrl: item.ImageResizePath ? this.OSSclientConfig.basePath + item.ImageResizePath : `/api/series/preview/${item.Id}`,
instanceCount: item.InstanceCount,
prefetchInstanceCount: 0,
hasLabel: item.HasLabel,
keySeries: item.KeySeries,
tpCode: scope.tpCode,
tpCode: this.tpCode,
loadStatus: false,
imageloadedArr: []
imageloadedArr: [],
isExistMutiFrames: item.IsExistMutiFrames
})
})
scope.seriesList = seriesList
if (scope.seriesList.length > 0) {
this.seriesList = seriesList
if (this.seriesList.length > 0) {
this.loadAllImages()
scope.$refs.dicomViewer.loadImageStack(scope.seriesList[0], scope.labels[scope.tpCode])
scope.firstInstanceId = scope.seriesList[0].imageIds[0]
this.$refs.dicomViewer.loadImageStack(this.seriesList[0], this.labels[this.tpCode])
this.firstInstanceId = this.seriesList[0].imageIds[0]
}
}
})
} catch (e) {
console.log(e)
}
},
initSeries() {
var scope = this
this.studyCode = this.$router.currentRoute.query.studyCode
this.modality = this.$router.currentRoute.query.modality
this.seriesCount = 1
this.description = this.$router.currentRoute.query.description
var seriesId = this.$router.currentRoute.query.seriesId
var seriesNumber = this.$router.currentRoute.query.seriesNumber
var subjectVisitId = this.$router.currentRoute.query.subjectVisitId
var studyId = this.$router.currentRoute.query.studyId
var trialId = this.$router.currentRoute.query.trialId
getInstanceList(seriesId).then(res => {
async initSeries() {
try {
this.studyCode = this.$router.currentRoute.query.studyCode
this.modality = this.$router.currentRoute.query.modality
this.seriesCount = 1
this.description = this.$router.currentRoute.query.description
var seriesId = this.$router.currentRoute.query.seriesId
var seriesNumber = this.$router.currentRoute.query.seriesNumber
var subjectVisitId = this.$router.currentRoute.query.subjectVisitId
var studyId = this.$router.currentRoute.query.studyId
var trialId = this.$router.currentRoute.query.trialId
const res = await getInstanceList(seriesId)
if (!res.Result || (res.Result && res.Result.length === 0)) return
var seriesInstanceUid = res.Result[0].SeriesInstanceUid
var sliceLocation = res.Result[0].SliceLocation
var sliceThickness = res.Result[0].SliceThickness
var isReading = res.Result[0].IsReading
var isDeleted = res.Result[0].IsDeleted
var seriesList = []
var imageIds = []
let isExistMutiFrames = false
const instanceInfoList = []
res.Result.forEach(instance => {
let imageId = ''
if (instance.NumberOfFrames > 1) {
for (let i = 0; i < instance.NumberOfFrames; i++) {
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instance.Path}?frame=${i}`)
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instance.Path}?frame=${i}&instanceId=${instance.Id}&seriesIndex=0`)
}
isExistMutiFrames = true
imageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instance.Path}?frame=0&instanceId=${instance.Id}&seriesIndex=0`
} else {
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instance.Path}`)
const path = `wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instance.Path}?instanceId=${instance.Id}&seriesIndex=0`
imageIds.push(path)
imageId = path
}
instanceInfoList.push({ Id: instance.Id, InstanceNumber: instance.InstanceNumber, NumberOfFrames: instance.NumberOfFrames, Path: instance.Path, ImageId: imageId })
})
seriesList.push({
trialId,
subjectVisitId,
studyId,
imageIds: imageIds,
instanceInfoList,
seriesId: seriesId,
seriesUid: seriesInstanceUid,
seriesNumber: seriesNumber,
sliceThickness: sliceLocation,
sliceThickness: sliceThickness,
modality: this.modality,
description: this.description,
isReading,
isDeleted,
previewImageUrl: res.OtherInfo.ImageResizePath ? scope.OSSclientConfig.basePath + res.OtherInfo.ImageResizePath : res.OtherInfo.ImageResizePath,
previewImageUrl: res.OtherInfo.ImageResizePath ? this.OSSclientConfig.basePath + res.OtherInfo.ImageResizePath : res.OtherInfo.ImageResizePath,
instanceCount: res.Result.length,
prefetchInstanceCount: 0,
loadStatus: false,
imageloadedArr: []
imageloadedArr: [],
isExistMutiFrames: isExistMutiFrames
})
this.seriesList = seriesList
if (this.seriesList.length > 0) {
@@ -302,7 +359,9 @@ export default {
this.firstInstanceId = this.seriesList[0].imageIds[0]
})
}
})
} catch (e) {
console.log(e)
}
},
showSeriesImage(e, seriesIndex, series) {
// if (seriesIndex === this.currentSeriesIndex) return
@@ -315,22 +374,102 @@ export default {
this.currentSeriesIndex = seriesIndex
this.$refs.dicomViewer.loadImageStack(this.seriesList[seriesIndex])
if (!series.loadStatus) {
requestPoolManager.changePriority(series.seriesId)
// var isAddToTakPool = false
// if (this.showSeriesList.includes(`${seriesIndex}`)) {
// isAddToTakPool = true
// } else {
// this.showSeriesList.push(`${seriesIndex}`)
// }
// if (!isAddToTakPool) {
// var priority = parseInt(new Date().getTime())
// series.isLoading = true
// series.imageIds.map((imageId) => {
// this.imageList.push({ imageId: imageId, seriesId: series.seriesId, priority })
// })
// } else {
// requestPoolManager.changePriority(series.seriesId)
// }
series.isLoading = true
var isAddToTakPool = false
if (this.showSeriesList.includes(`0_${seriesIndex}`)) {
isAddToTakPool = true
} else {
this.showSeriesList.push(`0_${seriesIndex}`)
}
if (!isAddToTakPool) {
var priority = parseInt(new Date().getTime())
// var images = []
// if (series.isExistMutiFrames) {
// images = series.imageIds.filter(i => i.includes('?frame=0'))
// } else {
// images = series.imageIds
// }
// images.map(imageId => {
// this.imageList.push({ imageId: imageId, seriesId: series.seriesId, studyIndex: 0, seriesIndex: seriesIndex, priority })
// })
if (series.isExistMutiFrames) {
series.instanceInfoList.map(image => {
this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, priority })
})
} else {
series.imageIds.map(imageId => {
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, priority })
})
}
if (this.imageList.length > 0) {
this.loopLoad()
}
} else {
requestPoolManager.changePriority(series.seriesId)
}
}
},
showMultiFrames(series, seriesIndex, instanceInfo) {
this.currentSeriesIndex = seriesIndex
const imageIds = []
if (instanceInfo.NumberOfFrames && instanceInfo.NumberOfFrames > 1) {
for (let j = 0; j < instanceInfo.NumberOfFrames; j++) {
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instanceInfo.Path}?frame=${j}&instanceId=${instanceInfo.Id}&seriesIndex=${seriesIndex}`)
}
} else {
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instanceInfo.Path}?instanceId=${instanceInfo.Id}&seriesIndex=${seriesIndex}`)
}
const seriesInfo = {
trialId: series.trialId,
subjectVisitId: series.subjectVisitId,
studyId: series.studyId,
imageIds: imageIds,
seriesId: series.seriesId,
seriesUid: series.seriesUid,
seriesNumber: series.seriesNumber,
sliceThickness: series.sliceThickness,
modality: series.modality,
description: series.description,
isReading: series.isReading,
isDeleted: series.isDeleted,
previewImageUrl: series.previewImageUrl,
instanceCount: series.instanceCount
}
this.$refs.dicomViewer.loadImageStack(seriesInfo)
if (!series.loadStatus) {
var isAddToTakPool = false
if (this.showSeriesList.includes(`0_${seriesIndex}`)) {
isAddToTakPool = true
} else {
this.showSeriesList.push(`0_${seriesIndex}`)
}
if (!isAddToTakPool) {
var priority = parseInt(new Date().getTime())
// if (series.isExistMutiFrames) {
// series.instanceInfoList.map(image => {
// this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, studyIndex: 0, seriesIndex: seriesIndex, priority })
// })
// } else {
// series.imageIds.map((imageId) => {
// this.imageList.push({ imageId: imageId, seriesId: series.seriesId, studyIndex: 0, seriesIndex: seriesIndex, priority })
// })
// }
if (series.isExistMutiFrames) {
series.instanceInfoList.map(image => {
this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, priority })
})
} else {
series.imageIds.map(imageId => {
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, priority })
})
}
if (this.imageList.length > 0) {
this.loopLoad()
}
} else {
requestPoolManager.changePriority(series.seriesId)
}
}
},
initStudy() {
@@ -342,13 +481,6 @@ export default {
const seriesInfo = JSON.parse(this.$router.currentRoute.query.series)
var seriesList = []
const imageIds = []
// const scope = this
// seriesInfo.InstanceList.forEach(function(item) {
// imageIds.push(`wadouri:/api/instance/content/${item}`)
// })
// seriesInfo.InstanceList.forEach((id) => {
// imageIds.push(`wadouri:http://123.56.94.154:7000/instance/content/${id}`)
// })
seriesInfo.InstancePathList.forEach((path) => {
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${path}`)
})
@@ -378,22 +510,25 @@ export default {
}
}
},
deleteSeries() {
async deleteSeries() {
this.loading = true
var subjectVisitId = this.$router.currentRoute.query.subjectVisitId
var studyId = this.$router.currentRoute.query.studyId
var seriesId = this.$router.currentRoute.query.seriesId
// trialId, subjectVisitId, studyId, seriesId, state
setSeriesStatus(this.trialId, subjectVisitId, studyId, seriesId, 5).then(res => {
try {
const res = await setSeriesStatus(this.trialId, subjectVisitId, studyId, seriesId, 5)
this.loading = false
if (res.IsSuccess) {
this.$message.success(this.$t('common:message:savedSuccessfully'))
window.opener.postMessage({ type: 'refreshSeriesList', data: '' }, window.location)
}
}).catch(() => { this.loading = false })
} catch (e) {
console.log(e)
this.loading = false
}
},
changeReadingStatus(callback, data) {
async changeReadingStatus(callback, data) {
let statusStr = ''
if (callback) {
statusStr = this.$t('trials:audit:label:setSeriesReading')
@@ -403,24 +538,31 @@ export default {
data.isReading = true
}
var message = this.$t('trials:audit:message:changeSeriesStatus').replace('xxx', statusStr)
this.$confirm(message, {
distinguishCancelAndClose: true,
type: 'warning'
}).then(() => {
const state = data.isReading ? 1 : 2
this.loading = true
setSeriesStatus(data.trialId, data.subjectVisitId, data.studyId, data.seriesId, state).then(res => {
this.loading = false
if (res.IsSuccess) {
data.isReading = !data.isReading
this.$message.success(this.$t('common:message:savedSuccessfully'))
window.opener.postMessage({ type: 'refreshSeriesList', data: '' }, window.location)
}
}).catch(() => { this.loading = false })
}).catch(() => {})
message = message.replace('yyy', this.$fd('YesOrNo', !data.isReading))
const confirm = await this.$confirm(
message,
{
type: 'warning',
distinguishCancelAndClose: true
}
)
if (confirm !== 'confirm') return
const state = data.isReading ? 1 : 2
this.loading = true
try {
const res = await setSeriesStatus(data.trialId, data.subjectVisitId, data.studyId, data.seriesId, state)
this.loading = false
if (res.IsSuccess) {
data.isReading = !data.isReading
this.$message.success(this.$t('common:message:savedSuccessfully'))
window.opener.postMessage({ type: 'refreshSeriesList', data: '' }, window.location)
}
} catch (e) {
console.log(e)
this.loading = false
}
},
changeDeleteStatus(callback, data) {
async changeDeleteStatus(callback, data) {
let statusStr = ''
if (callback) {
statusStr = this.$t('trials:audit:label:setSeriesDeleted')
@@ -430,111 +572,76 @@ export default {
data.isDeleted = true
}
var message = this.$t('trials:audit:message:changeSeriesStatus').replace('xxx', statusStr)
this.$confirm(message, {
distinguishCancelAndClose: true,
type: 'warning'
}).then(() => {
const state = data.isDeleted ? 5 : 4
this.loading = true
// var trialId = this.$router.currentRoute.query.trialId
// var subjectVisitId = this.$router.currentRoute.query.subjectVisitId
// var studyId = this.$router.currentRoute.query.studyId
// var seriesId = this.$router.currentRoute.query.seriesId
setSeriesStatus(data.trialId, data.subjectVisitId, data.studyId, data.seriesId, state).then(res => {
this.loading = false
if (res.IsSuccess) {
data.isDeleted = !data.isDeleted
this.$message.success(this.$t('common:message:savedSuccessfully'))
window.opener.postMessage({ type: 'refreshSeriesList', data: '' }, window.location)
}
}).catch(() => { this.loading = false })
}).catch(() => {})
message = message.replace('yyy', this.$fd('YesOrNo', !data.isDeleted))
const confirm = await this.$confirm(
message,
{
type: 'warning',
distinguishCancelAndClose: true
}
)
if (confirm !== 'confirm') return
const state = data.isDeleted ? 5 : 4
this.loading = true
try {
const res = await setSeriesStatus(data.trialId, data.subjectVisitId, data.studyId, data.seriesId, state)
this.loading = false
if (res.IsSuccess) {
data.isDeleted = !data.isDeleted
this.$message.success(this.$t('common:message:savedSuccessfully'))
window.opener.postMessage({ type: 'refreshSeriesList', data: '' }, window.location)
}
} catch (e) {
console.log(e)
this.loading = false
}
},
loadAllImages() {
const seriesIndex = this.seriesList.findIndex(i => i.loadStatus === false)
if (seriesIndex === -1) return
const series = this.seriesList[seriesIndex]
var priority = new Date().getTime()
this.seriesList.forEach((series, index) => {
series.imageIds.forEach(imageId => {
var p = null
if (this.firstInstanceId === imageId) {
p = priority * 100
} else {
p = priority - 1
}
// this.load(imageId, series.seriesId, priority)
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, seriesIndex: index, priority: p })
// var images = []
// if (series.isExistMutiFrames) {
// images = series.imageIds.filter(i => i.includes('?frame=0'))
// } else {
// images = series.imageIds
// }
// images.map(imageId => {
// this.imageList.push({ imageId: imageId, seriesId: series.seriesId, studyIndex: 0, seriesIndex: seriesIndex, priority })
// })
if (series.isExistMutiFrames) {
series.instanceInfoList.map(image => {
this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, priority })
})
})
} else {
series.imageIds.map(imageId => {
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, priority })
})
}
if (this.imageList.length > 0) {
this.loopLoad()
}
},
getInstanceInfo(imageId) {
const params = {}
const searchParams = new URLSearchParams(imageId.split('?')[1])
for (const [key, value] of searchParams.entries()) {
params[key] = value
}
return params
},
loopLoad() {
if (this.imageList.length > 0) {
requestPoolManager.startTaskTimer()
console.log('loopLoad')
this.imageList.map(image => {
requestPoolManager.loadAndCacheImagePlus(image.imageId, image.seriesId, image.priority).then(res => {
this.imageLoaded(image, res.data.string('x0020000e'))
})
requestPoolManager.loadAndCacheImagePlus(image.imageId, image.seriesId, image.priority)
})
requestPoolManager.sortTaskPool()
this.imageList = []
}
},
load(imageId, seriesId, priority = 999) {
return new Promise((resolve, reject) => {
requestPoolManager.loadAndCacheImagePlus(imageId, seriesId, priority).then(res => {
if (!res) return
this.imageLoaded(imageId, res.data.string('x0020000e'))
resolve(res)
}).catch(e => {
reject(e)
})
})
},
imageLoaded(image, seriesUid) {
var seriesIndex = image.seriesIndex
if (seriesIndex < 0) return
if (this.seriesList[seriesIndex].imageloadedArr.indexOf(image.imageId) < 0) {
++this.seriesList[seriesIndex].prefetchInstanceCount
this.seriesList[seriesIndex].imageloadedArr.push(image.imageId)
if (this.seriesList[seriesIndex].prefetchInstanceCount >= this.seriesList[seriesIndex].instanceCount) {
this.seriesList[seriesIndex].prefetchInstanceCount = this.seriesList[seriesIndex].instanceCount
//
this.seriesList[seriesIndex].loadStatus = true
// if (!this.isLoadedAll) {
// this.loadAllImages()
// }
}
}
},
imageLoaded2(imageId, seriesUid) {
var seriesIndex = -1
for (let i = 0; i < this.seriesList.length; ++i) {
if (this.seriesList[i].seriesUid === seriesUid) {
seriesIndex = i
break
}
}
if (seriesIndex < 0) return
const imageIdIndex = this.seriesList[seriesIndex].imageIds.indexOf(imageId)
if (imageIdIndex < 0) return
if (this.seriesList[seriesIndex].imageloadedArr.indexOf(imageId) < 0) {
++this.seriesList[seriesIndex].prefetchInstanceCount
this.seriesList[seriesIndex].imageloadedArr.push(imageId)
if (this.seriesList[seriesIndex].prefetchInstanceCount >= this.seriesList[seriesIndex].instanceCount) {
this.seriesList[seriesIndex].prefetchInstanceCount = this.seriesList[seriesIndex].instanceCount
//
this.seriesList[seriesIndex].loadStatus = true
// if (!this.isLoadedAll) {
// this.loadAllImages()
// }
}
}
},
datasetsCacheChanged(e) {
// const uri = e.detail.uri
const cacheInfo = e.detail.cacheInfo
@@ -558,48 +665,44 @@ export default {
return 0
},
cornerstoneImageLoaded(e) {
if (this.firstInstanceId === e.detail.image.imageId && !this.isStartLoad) {
//
this.loadAllImages()
this.isStartLoad = true
// requestPoolManager.executeTask()
cornerstoneimageloadprogress(e) {
const imageId = e.detail.imageId
const percentComplete = e.detail.percentComplete
const params = {}
const searchParams = new URLSearchParams(imageId.split('?')[1])
for (const [key, value] of searchParams.entries()) {
params[key] = value
}
const uri = e.detail.image.sharedCacheKey
const index = this.cachedImages.findIndex(item => item.uri === uri)
if (index === -1) {
this.cachedImages.push({ uri: uri, timestamp: new Date().getTime() })
} else {
this.cachedImages[index].timestamp = new Date().getTime()
}
// loadedDataSets[uri].dataSet.byteArray.length
// console.log(this.cachedImages.length)
// console.log(cornerstoneWADOImageLoader.wadouri.dataSetCacheManager.getInfo().cacheSizeInBytes)
// const imageId = e.detail.image.imageId
var imageId = e.detail.image.imageId
var seriesUid = e.detail.image.data.string('x0020000e')
var seriesIndex = -1
for (let i = 0; i < this.seriesList.length; ++i) {
if (this.seriesList[i].seriesUid === seriesUid) {
seriesIndex = i
break
if (this.visitTaskId === params.visitTaskId) {
const seriesIndex = params.seriesIndex
var prefetchInstanceCount = this.seriesList[seriesIndex].prefetchInstanceCount
var instanceCount = this.seriesList[seriesIndex].instanceCount
if (this.seriesList[seriesIndex].imageloadedArr.indexOf(imageId) < 0 && this.seriesList[seriesIndex].imageloadedArr.length < this.seriesList[seriesIndex].instanceCount) {
const i = this.currentLoadIns.findIndex(i => i.imageId === imageId)
if (i > -1) {
prefetchInstanceCount = prefetchInstanceCount - this.currentLoadIns[i].percentComplete + percentComplete
this.currentLoadIns[i].percentComplete = percentComplete
if (percentComplete === 100) {
this.currentLoadIns.splice(i, 1)
}
} else {
if (percentComplete !== 100) {
this.currentLoadIns.push({ imageId, percentComplete })
}
prefetchInstanceCount = prefetchInstanceCount + percentComplete
}
this.seriesList[seriesIndex].prefetchInstanceCount = prefetchInstanceCount
if (percentComplete >= 100) {
this.seriesList[seriesIndex].imageloadedArr.push(imageId)
}
}
}
if (seriesIndex < 0) return
const imageIdIndex = this.seriesList[seriesIndex].imageIds.indexOf(imageId)
if (imageIdIndex < 0) return
if (this.seriesList[seriesIndex].imageloadedArr.indexOf(imageId) < 0) {
++this.seriesList[seriesIndex].prefetchInstanceCount
this.seriesList[seriesIndex].imageloadedArr.push(imageId)
if (this.seriesList[seriesIndex].prefetchInstanceCount >= this.seriesList[seriesIndex].instanceCount) {
this.seriesList[seriesIndex].prefetchInstanceCount = this.seriesList[seriesIndex].instanceCount
if (prefetchInstanceCount >= instanceCount * 100) {
this.seriesList[seriesIndex].prefetchInstanceCount = instanceCount * 100
//
this.seriesList[seriesIndex].loadStatus = true
// if (!this.isLoadedAll) {
// this.loadAllImages()
// }
if (!this.isFromCRCUpload) {
this.loadAllImages()
}
}
}
}
@@ -751,6 +854,41 @@ export default {
color: #D0D0D0;
font-size: 13px;
}
.instance_frame_wrapper{
min-width: 120px;
background-color: #2c2c2c;
border: 1px solid #2c2c2c;
padding: 5px;
}
.frame_list{
max-height: 500px;
overflow-y: auto;
}
.instance_frame_wrapper ::-webkit-scrollbar {
width: 7px;
height: 7px;
}
.instance_frame_wrapper ::-webkit-scrollbar-thumb {
border-radius: 10px;
background: #d0d0d0;
}
.frame_content{
height: 50px;
padding: 5px;
display: flex;
justify-content: flex-start;
color: #ddd;
font-size: 12px;
border: 1px solid #404040;
}
.frame_content:hover {
/* font-weight: bold; */
/* box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); */
cursor: pointer;
/* color: #428bca; */
border-color: #213a54 !important;
background-color: #213a54;
}
/* .viewerRightSidePanel {
width: 300px;
height: 100%;
+436 -273
View File
@@ -46,13 +46,6 @@
@click="showSeriesImage($event,index,i,series)"
>
<div class="viewernavigatorwrapper">
<!-- <el-image
class="image-preview"
style="height:72px;width:72px;"
:src="series.previewImageUrl"
fit="fill"
/> -->
<img
class="image-preview"
:src="series.previewImageUrl"
@@ -62,8 +55,41 @@
fit="fill"
>
<div class="viewernavitextwrapper">
<div style="padding: 1px;">
#{{ series.seriesNumber }}
<div style="padding: 1px 5px 1px 1px;display: flex;justify-content: space-between;">
<div>#{{ series.seriesNumber }}</div>
<div v-if="series.isExistMutiFrames && series.instanceCount > 1">
<el-popover
placement="right"
trigger="hover"
popper-class="instance_frame_wrapper"
>
<div
v-for="(instance, idx) in series.instanceInfoList"
:key="instance.Id"
class="frame_content"
:style="{'margin-bottom':idx<series.instanceInfoList.length-1? '5px':'0px'}"
@click="showMultiFrames(index,series, i, instance)"
>
<!-- <div>
<img
class="image-preview"
:src="series.previewImageUrl"
crossorigin="anonymous"
alt=""
style="width: 40px;height:40px;"
fit="fill"
>
</div> -->
<div>
<div>{{ instance.InstanceNumber }}</div>
<div>{{ `${instance.NumberOfFrames > 0 ? instance.NumberOfFrames : 1} frame` }}</div>
</div>
</div>
<i slot="reference" class="el-icon-connection" style="font-size: 15px;cursor: pointer;" />
</el-popover>
</div>
</div>
<div v-show="series.InstanceCount" style="padding: 1px;">
{{ series.modality }}: {{ series.instanceCount }} image
@@ -78,32 +104,35 @@
</div>
</el-tooltip>
<div style="padding: 1px;">
{{ series.prefetchInstanceCount }}/{{ series.instanceCount }}
{{ series.imageloadedArr.length }}/{{ series.instanceCount }}
</div>
<div />
</div>
</div>
<div v-if="showDelete" @click.stop="">
<div v-if="showDelete" style="display: flex;flex-direction: row;justify-content: space-between;" @click.stop="">
<span style="font-size: 12px;">{{ $t('trials:audit:table:isReading') }}</span>
<el-switch
v-model="series.isReading"
size="mini"
@change="changeReadingStatus($event, series)"
/>
<span style="font-size: 12px;">{{ $t('trials:audit:table:isDelete') }}</span>
<el-switch
v-model="series.isDeleted"
size="mini"
@change="changeDeleteStatus($event, series)"
/>
<div>
<span style="font-size: 12px;">{{ $t('trials:audit:table:isReading') }}</span>
<el-switch
v-model="series.isReading"
size="mini"
@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 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" />
</div> -->
<div v-if="series.prefetchInstanceCount>0 && series.prefetchInstanceCount<series.instanceCount">
<el-progress :percentage="parseInt(((series.prefetchInstanceCount/series.instanceCount)*100).toFixed(2))" />
<div v-if="series.prefetchInstanceCount>0 && series.prefetchInstanceCount<series.instanceCount * 100">
<el-progress :percentage="parseInt((series.prefetchInstanceCount/series.instanceCount).toFixed(2))" />
</div>
</div>
@@ -117,7 +146,7 @@
<el-tab-pane :label="$t('trials:dicom-show:relatedVisit')" name="relation-study" class="pane-relation-wrapper">
<div class="viewerSidethumbinner">
<el-collapse v-model="relationActiveName" @change="handelRelationActiveChange">
<el-collapse-item v-for="(study) in relationStudyList" :key="`${study.StudyId}`" :name="`${study.StudyId}`">
<el-collapse-item v-for="(study,studyIndex) in relationStudyList" :key="`${study.StudyId}`" :name="`${study.StudyId}`">
<template slot="title">
<div class="text-desc">
@@ -142,7 +171,7 @@
class="viewernavigatorwrapper"
style="position: relative;border:1px solid #434343;"
series-type="relation"
@click="showRelationSeriesImage($event,seriesItem,index)"
@click="showRelationSeriesImage($event,seriesItem,studyIndex,index)"
>
<!-- <el-image
class="image-preview"
@@ -160,13 +189,38 @@
>
<div class="viewernavitextwrapper">
<div v-if="seriesItem.keySeries" style="padding: 1px;color:red">
Key Images
<div style="padding: 1px 5px 1px 1px;display: flex;justify-content: space-between;">
<div v-if="seriesItem.keySeries" style="color:red">
Key Images
</div>
<div v-else>#{{ seriesItem.seriesNumber }}</div>
<div v-if="seriesItem.isExistMutiFrames && seriesItem.instanceCount > 1">
<el-popover
placement="right"
trigger="hover"
popper-class="instance_frame_wrapper"
>
<div class="frame_list">
<div
v-for="(instance, idx) in seriesItem.instanceInfoList"
:key="instance.Id"
class="frame_content"
:style="{'margin-bottom':idx<seriesItem.instanceInfoList.length-1? '5px':'0px'}"
@click="showMultiFrames(studyIndex,seriesItem, index, instance)"
>
<div>
<div>{{ instance.InstanceNumber }}</div>
<div>{{ `${instance.NumberOfFrames > 0 ? instance.NumberOfFrames : 1} frame` }}</div>
</div>
</div>
</div>
<i slot="reference" class="el-icon-connection" style="font-size: 15px;cursor: pointer;" />
</el-popover>
</div>
</div>
<div v-else style="padding: 1px;">
#{{ seriesItem.seriesNumber }}
</div>
<div v-show=" seriesItem.instanceCount" style="padding: 1px;">
<div v-show="seriesItem.instanceCount" style="padding: 1px;">
{{ seriesItem.modality }}: {{ seriesItem.instanceCount }} image
</div>
<div v-show="seriesItem.sliceThickness" style="padding: 1px;">
@@ -177,7 +231,6 @@
{{ seriesItem.description }}
</div>
</el-tooltip>
</div>
<!-- <div style="position: absolute;bottom: -10px;left: 0;width: 100%;">
<el-progress v-if="seriesItem.prefetchInstanceCount>0 && seriesItem.prefetchInstanceCount<seriesItem.instanceCount" :percentage="Number(seriesItem.prefetchInstanceCount/seriesItem.instanceCount)*100" />
@@ -211,9 +264,11 @@ import { setSeriesStatus } from '@/api/trials'
import requestPoolManager from '@/utils/request-pool'
import store from '@/store'
import { changeURLStatic } from '@/utils/history.js'
// import * as cornerstoneTools from 'cornerstone-tools'
cornerstoneWADOImageLoader.external.dicomParser = dicomParser
cornerstoneWADOImageLoader.external.cornerstone = cornerstone
const maximumSizeInBytes = 1024 * 1024 * 1024 // 1 GB
const maximumSizeInBytes = 1024 * 1024 * 1024 * 6
cornerstone.imageCache.setMaximumSizeBytes(maximumSizeInBytes)
export default {
name: 'DicomsOfVisit',
components: {
@@ -234,10 +289,14 @@ export default {
imageList: [],
activeNames: [],
relationActiveName: [],
showSeriesList: []
showSeriesList: [],
currentLoadIns: [],
isFromCRCUpload: false
}
},
mounted() {
requestPoolManager.resetRequestPool()
document.documentElement.style.userSelect = 'none'
if (this.$router.currentRoute.query.TokenKey) {
store.dispatch('user/setToken', this.$router.currentRoute.query.TokenKey)
changeURLStatic('TokenKey', '')
@@ -248,72 +307,109 @@ export default {
this.visitInfo = this.$router.currentRoute.query.visitInfo
this.isReading = this.$router.currentRoute.query.isReading ? this.$router.currentRoute.query.isReading * 1 : 0
this.showDelete = parseInt(this.$router.currentRoute.query.showDelete)
this.isFromCRCUpload = !!this.$router.currentRoute.query.isFromCRCUpload
// cornerstone.events.addEventListener('cornerstoneimageloaded', this.cornerstoneImageLoaded)
this.getStudiesInfo()
cornerstone.events.addEventListener('cornerstoneimageloadprogress', this.cornerstoneimageloadprogress)
window.addEventListener('beforeunload', e => {
cornerstone.imageCache.purgeCache()
requestPoolManager.resetRequestPool()
})
},
beforeDestroy() {
requestPoolManager.stopTaskTimer()
window.removeEventListener('beforeunload', e => {
cornerstone.imageCache.purgeCache()
requestPoolManager.resetRequestPool()
})
},
methods: {
// 访
getStudiesInfo() {
async getStudiesInfo() {
this.studyList = []
getVisitStudyList(this.trialId, this.subjectVisitId, this.isReading).then(res => {
res.Result.forEach((study) => {
const data = {}
data.StudyId = study.StudyId
data.StudyCode = study.StudyCode
data.Modalities = study.Modalities
data.SeriesCount = study.SeriesCount
data.InstanceCount = study.InstanceCount
data.InstanceCount = study.InstanceCount
data.PreviewImageCount = 0
var seriesList = []
study.SeriesList.forEach((series) => {
const imageIds = []
// series.InstanceList.forEach((id) => {
// imageIds.push(`wadouri:/api/instance/content/${id}`)
// })
// series.InstanceList.forEach((id) => {
// imageIds.push(`wadouri:http://123.56.94.154:7000/instance/content/${id}`)
// })
series.InstancePathList.forEach((path) => {
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${path}`)
})
seriesList.push({
trialId: this.trialId,
subjectVisitId: this.subjectVisitId,
studyId: study.StudyId,
imageIds: imageIds,
seriesId: series.Id,
seriesUid: series.SeriesInstanceUid,
seriesNumber: series.SeriesNumber,
sliceThickness: series.SliceThickness,
modality: series.Modality,
description: series.Description,
isReading: series.IsReading,
isDeleted: series.IsDeleted,
previewImageUrl: series.ImageResizePath ? this.OSSclientConfig.basePath + series.ImageResizePath : `/api/series/preview/${series.Id}`,
instanceCount: series.InstanceCount,
prefetchInstanceCount: 0,
loadStatus: false,
imageloadedArr: []
try {
const res = await getVisitStudyList(this.trialId, this.subjectVisitId, this.isReading)
if (res.IsSuccess) {
res.Result.forEach((study, studyIndex) => {
const data = {}
data.StudyId = study.StudyId
data.StudyCode = study.StudyCode
data.Modalities = study.Modalities
data.SeriesCount = study.SeriesCount
data.InstanceCount = study.InstanceCount
data.InstanceCount = study.InstanceCount
data.PreviewImageCount = 0
var seriesList = []
study.SeriesList.forEach((series, seriesIndex) => {
const imageIds = []
series.InstanceInfoList.forEach(i => {
if (i.NumberOfFrames && i.NumberOfFrames > 1) {
for (let j = 0; j < i.NumberOfFrames; j++) {
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${i.Path}?frame=${j}&instanceId=${i.Id}&idx=${studyIndex}|${seriesIndex}`)
}
i.ImageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${i.Path}?frame=0&instanceId=${i.Id}&idx=${studyIndex}|${seriesIndex}`
// imageIds.push(`${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${i.Path}`)
} else {
const imageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${i.Path}?instanceId=${i.Id}&idx=${studyIndex}|${seriesIndex}`
imageIds.push(imageId)
i.ImageId = imageId
// imageIds.push(`${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${i.Path}`)
}
})
seriesList.push({
trialId: this.trialId,
subjectVisitId: this.subjectVisitId,
studyId: study.StudyId,
imageIds: imageIds,
instanceInfoList: series.InstanceInfoList,
seriesId: series.Id,
seriesUid: series.SeriesInstanceUid,
seriesNumber: series.SeriesNumber,
sliceThickness: series.SliceThickness,
modality: series.Modality,
description: series.Description,
isReading: series.IsReading,
isDeleted: series.IsDeleted,
previewImageUrl: series.ImageResizePath ? this.OSSclientConfig.basePath + series.ImageResizePath : `/api/series/preview/${series.Id}`,
instanceCount: series.InstanceCount,
prefetchInstanceCount: 0,
loadStatus: false,
imageloadedArr: [],
isExistMutiFrames: series.IsExistMutiFrames
})
})
data.SeriesList = seriesList
this.studyList.push(data)
})
data.SeriesList = seriesList
this.studyList.push(data)
})
if (this.studyList.length > 0) {
this.$refs.dicomViewer.loadImageStack(this.studyList[0].SeriesList[0])
const imageId = this.studyList[0].SeriesList[0].imageIds[0]
let instanceId = imageId.split('/')[imageId.split('/').length - 1]
instanceId = instanceId.split('.')[0]
this.firstInstanceId = instanceId
this.activeNames = [this.studyList[0].StudyId]
this.loadAllImages()
if (this.studyList.length > 0) {
this.$refs.dicomViewer.loadImageStack(this.studyList[0].SeriesList[0])
const imageId = this.studyList[0].SeriesList[0].imageIds[0]
let instanceId = imageId.split('/')[imageId.split('/').length - 1]
instanceId = instanceId.split('.')[0]
this.firstInstanceId = instanceId
this.activeNames = [this.studyList[0].StudyId]
this.loadImages(this.studyList[0].SeriesList[0], 0)
}
}
})
} catch (e) {
console.log(e)
}
},
loadImages(series, seriesIndex) {
var priority = parseInt(new Date().getTime())
if (series.isExistMutiFrames) {
series.instanceInfoList.map(image => {
this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, priority })
})
} else {
series.imageIds.map(imageId => {
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, priority })
})
}
if (this.imageList.length > 0) {
this.loopLoad()
}
},
showSeriesImage(e, studyIndex, seriesIndex, series) {
const element = e.currentTarget
@@ -324,26 +420,91 @@ export default {
element.classList.add('viewerSideActive')
this.currentSeriesIndex = seriesIndex
this.$refs.dicomViewer.loadImageStack(this.studyList[studyIndex].SeriesList[seriesIndex])
// if (!series.loadStatus) {
// requestPoolManager.changePriority(series.seriesId)
// }
if (!series.loadStatus) {
requestPoolManager.changePriority(series.seriesId)
// var isAddToTakPool = false
// if (this.showSeriesList.includes(`${studyIndex}_${seriesIndex}`)) {
// isAddToTakPool = true
// } else {
// this.showSeriesList.push(`${studyIndex}_${seriesIndex}`)
// }
// if (!isAddToTakPool) {
// var priority = parseInt(new Date().getTime())
// series.isLoading = true
// series.imageIds.map((imageId, i) => {
// this.imageList.push({ imageId: imageId, seriesId: series.seriesId, priority })
// })
// } else {
// requestPoolManager.changePriority(series.seriesId)
// }
series.isLoading = true
var isAddToTakPool = false
if (this.showSeriesList.includes(`${studyIndex}_${seriesIndex}`)) {
isAddToTakPool = true
} else {
this.showSeriesList.push(`${studyIndex}_${seriesIndex}`)
}
if (!isAddToTakPool) {
var priority = parseInt(new Date().getTime())
if (series.isExistMutiFrames) {
series.instanceInfoList.map(image => {
this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, priority })
})
} else {
series.imageIds.map(imageId => {
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, priority })
})
}
if (this.imageList.length > 0) {
this.loopLoad()
}
} else {
requestPoolManager.changePriority(series.seriesId)
}
}
},
changeReadingStatus(callback, data) {
showMultiFrames(studyIndex, series, seriesIndex, instanceInfo) {
this.currentSeriesIndex = seriesIndex
const imageIds = []
if (instanceInfo.NumberOfFrames && instanceInfo.NumberOfFrames > 1) {
for (let j = 0; j < instanceInfo.NumberOfFrames; j++) {
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instanceInfo.Path}?frame=${j}&instanceId=${instanceInfo.Id}&idx=${studyIndex}|${seriesIndex}`)
}
} else {
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instanceInfo.Path}?instanceId=${instanceInfo.Id}&idx=${studyIndex}|${seriesIndex}`)
}
const seriesInfo = {
trialId: series.trialId,
subjectVisitId: series.subjectVisitId,
studyId: series.studyId,
imageIds: imageIds,
seriesId: series.seriesId,
seriesUid: series.seriesUid,
seriesNumber: series.seriesNumber,
sliceThickness: series.sliceThickness,
modality: series.modality,
description: series.description,
isReading: series.isReading,
isDeleted: series.isDeleted,
previewImageUrl: series.previewImageUrl,
instanceCount: series.instanceCount
}
this.$refs.dicomViewer.loadImageStack(seriesInfo)
if (!series.loadStatus) {
var isAddToTakPool = false
if (this.showSeriesList.includes(`${studyIndex}_${seriesIndex}`)) {
isAddToTakPool = true
} else {
this.showSeriesList.push(`${studyIndex}_${seriesIndex}`)
}
if (!isAddToTakPool) {
var priority = parseInt(new Date().getTime())
if (series.isExistMutiFrames) {
series.instanceInfoList.map(image => {
this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, priority })
})
} else {
series.imageIds.map((imageId) => {
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, priority })
})
}
if (this.imageList.length > 0) {
this.loopLoad()
}
} else {
requestPoolManager.changePriority(series.seriesId)
}
}
},
async changeReadingStatus(callback, data) {
let statusStr = ''
if (callback) {
statusStr = this.$t('trials:audit:label:setSeriesReading')
@@ -353,24 +514,30 @@ export default {
data.isReading = true
}
var message = this.$t('trials:audit:message:changeSeriesStatus').replace('xxx', statusStr)
this.$confirm(message, {
distinguishCancelAndClose: true,
type: 'warning'
}).then(() => {
const state = data.isReading ? 1 : 2
this.loading = true
setSeriesStatus(data.trialId, data.subjectVisitId, data.studyId, data.seriesId, state).then(res => {
this.loading = false
if (res.IsSuccess) {
data.isReading = !data.isReading
this.$message.success(this.$t('common:message:savedSuccessfully'))
window.opener.postMessage({ type: 'refreshSeriesList', data: '' }, window.location)
}
}).catch(() => { this.loading = false })
}).catch(() => {})
message = message.replace('yyy', this.$fd('YesOrNo', !data.isReading))
const confirm = await this.$confirm(
message,
{
type: 'warning',
distinguishCancelAndClose: true
}
)
if (confirm !== 'confirm') return
const state = data.isReading ? 1 : 2
this.loading = true
try {
const res = await setSeriesStatus(data.trialId, data.subjectVisitId, data.studyId, data.seriesId, state)
this.loading = false
if (res.IsSuccess) {
data.isReading = !data.isReading
this.$message.success(this.$t('common:message:savedSuccessfully'))
window.opener.postMessage({ type: 'refreshSeriesList', data: '' }, window.location)
}
} catch (e) {
this.loading = false
}
},
changeDeleteStatus(callback, data) {
async changeDeleteStatus(callback, data) {
let statusStr = ''
if (callback) {
statusStr = this.$t('trials:audit:label:setSeriesDeleted')
@@ -380,24 +547,32 @@ export default {
data.isDeleted = true
}
var message = this.$t('trials:audit:message:changeSeriesStatus').replace('xxx', statusStr)
this.$confirm(message, {
distinguishCancelAndClose: true,
type: 'warning'
}).then(() => {
const state = data.isDeleted ? 5 : 4
this.loading = true
setSeriesStatus(data.trialId, data.subjectVisitId, data.studyId, data.seriesId, state).then(res => {
this.loading = false
if (res.IsSuccess) {
data.isDeleted = !data.isDeleted
this.$message.success(this.$t('common:message:savedSuccessfully'))
window.opener.postMessage({ type: 'refreshSeriesList', data: '' }, window.location)
}
}).catch(() => { this.loading = false })
}).catch(() => {})
message = message.replace('yyy', this.$fd('YesOrNo', !data.isDeleted))
const confirm = await this.$confirm(
message,
{
type: 'warning',
distinguishCancelAndClose: true
}
)
if (confirm !== 'confirm') return
const state = data.isDeleted ? 5 : 4
this.loading = true
try {
const res = await setSeriesStatus(data.trialId, data.subjectVisitId, data.studyId, data.seriesId, state)
this.loading = false
if (res.IsSuccess) {
data.isDeleted = !data.isDeleted
this.$message.success(this.$t('common:message:savedSuccessfully'))
window.opener.postMessage({ type: 'refreshSeriesList', data: '' }, window.location)
}
} catch (e) {
this.loading = false
}
},
// Tab
handleTabClick(tab, event) {
async handleTabClick(tab, event) {
if (tab.name === 'relation-study' && this.relationStudyList.length <= 0) {
const loading = this.$loading({
target: document.querySelector('.pane-relation-wrapper'),
@@ -407,11 +582,13 @@ export default {
background: 'rgb(49 49 49 / 50%)',
spinner: 'el-icon-loading'
})
getAllRelationStudyList(this.subjectVisitId).then(res => {
try {
const res = await getAllRelationStudyList(this.subjectVisitId)
loading.close()
this.relationStudyList = res.Result
console.log(this.relationStudyList)
}).catch(() => { loading.close() })
} catch (e) {
loading.close()
}
}
},
handelRelationActiveChange(v) {
@@ -423,8 +600,7 @@ export default {
}
},
//
getRelationSeriesByStudy(studyId, index) {
console.log('getRelationSeriesByStudy')
async getRelationSeriesByStudy(studyId, index) {
if (this.relationStudyList[index].seriesCount) {
this.relationStudyList[index].showSeries = !this.relationStudyList[index].showSeries
this.$forceUpdate()
@@ -438,24 +614,26 @@ export default {
background: 'rgb(49 49 49 / 50%)',
spinner: 'el-icon-loading'
})
getSeriesList(`/series/list/${studyId}`).then(data => {
try {
const data = await getSeriesList(`/series/list/${studyId}`)
loading.close()
if (data.Result != null && data.Result.length > 0) {
var seriesList = []
const res = data.Result
res.forEach(function(item) {
res.forEach((item, seriesIndex) => {
const imageIds = []
// item.InstanceList.forEach(function(id) {
// imageIds.push(`wadouri:/api/instance/content/${id}`)
// })
// item.InstanceList.forEach((id) => {
// imageIds.push(`wadouri:http://123.56.94.154:7000/instance/content/${id}`)
// })
item.InstancePathList.forEach((path) => {
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? scope.OSSclientConfig.basePath : scope.OSSclientConfig.basePath}${path}`)
item.InstanceInfoList.forEach(i => {
if (i.NumberOfFrames && i.NumberOfFrames > 1) {
for (let j = 0; j < i.NumberOfFrames; j++) {
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? scope.OSSclientConfig.basePath : scope.OSSclientConfig.basePath}${i.Path}?frame=${j}&instanceId=${i.Id}&idx=${index}|${seriesIndex}&isRelation=1`)
}
} else {
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? scope.OSSclientConfig.basePath : scope.OSSclientConfig.basePath}${i.Path}?instanceId=${i.Id}&idx=${index}|${seriesIndex}&isRelation=1`)
}
})
seriesList.push({
imageIds: imageIds,
instanceInfoList: item.InstanceInfoList,
seriesId: item.Id,
seriesUid: item.SeriesInstanceUid,
seriesNumber: item.SeriesNumber,
@@ -468,19 +646,21 @@ export default {
hasLabel: item.HasLabel,
keySeries: item.KeySeries,
loadStatus: false,
imageloadedArr: []
imageloadedArr: [],
isExistMutiFrames: item.IsExistMutiFrames
})
})
scope.relationStudyList[index].seriesCount = seriesList.length
scope.relationStudyList[index].seriesList = seriesList
scope.relationStudyList[index].showSeries = true
console.log(scope.relationStudyList)
scope.$forceUpdate()
}
}).catch(() => { loading.close() })
} catch (e) {
loading.close()
}
}
},
showRelationSeriesImage(e, series, index) {
showRelationSeriesImage(e, series, studyIndex, index) {
this.currentRelationIndex = index
const element = e.currentTarget
const elements = document.querySelectorAll('[series-type]')
@@ -491,80 +671,55 @@ export default {
this.$refs.dicomViewer.loadImageStack(series)
if (!series.loadStatus) {
var priority = parseInt(new Date().getTime())
series.imageIds.map(imageId => {
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, priority })
})
if (series.isExistMutiFrames) {
series.instanceInfoList.map(image => {
this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, priority })
})
} else {
series.imageIds.map((imageId) => {
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, priority })
})
}
}
},
loadAllImages() {
var seriesList = this.studyList.map(s => s.SeriesList).flat()
const seriesIndex = seriesList.findIndex(i => i.loadStatus === false)
if (seriesIndex === -1) return
const series = seriesList[seriesIndex]
var priority = parseInt(new Date().getTime())
this.studyList.map((study, studyIndex) => {
study.SeriesList.map((series, seriesIndex) => {
series.imageIds.map(imageId => {
var p = null
if (this.firstInstanceId === imageId) {
p = priority * 100
} else {
p = priority - 1
}
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, studyIndex, seriesIndex, priority: p })
})
// if (!series.loadStatus && series.seriesId !== this.firstSeriesId) {
// series.imageIds.map(imageId => {
// // imageIds.push({ imageId: image, seriesId: series.seriesId, priority })
// this.imageList.push({ imageId: imageId, seriesId: series.seriesId, studyIndex, seriesIndex, priority })
// })
// }
if (series.isExistMutiFrames) {
series.instanceInfoList.map(image => {
this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, priority })
})
})
} else {
series.imageIds.map((imageId) => {
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, priority })
})
}
if (this.imageList.length > 0) {
this.loopLoad()
}
// requestPoolManager.setPendingList(imageIds)
},
getInstanceInfo(imageId) {
const params = {}
const searchParams = new URLSearchParams(imageId.split('?')[1])
for (const [key, value] of searchParams.entries()) {
params[key] = value
}
return params
},
loopLoad() {
if (this.imageList.length > 0) {
requestPoolManager.startTaskTimer()
this.imageList.map(image => {
requestPoolManager.loadAndCacheImagePlus(image.imageId, image.seriesId, image.priority).then(res => {
this.imageLoaded(image, res.data.string('x0020000e'))
})
requestPoolManager.loadAndCacheImagePlus(image.imageId, image.seriesId, image.priority)
})
requestPoolManager.sortTaskPool()
this.imageList = []
}
},
load(imageId, seriesId, priority = 999) {
return new Promise((resolve, reject) => {
requestPoolManager.loadAndCacheImagePlus(imageId, seriesId, priority).then(res => {
if (!res) return
this.imageLoaded(imageId, res.data.string('x0020000e'))
resolve(res)
}).catch(e => {
reject(e)
})
})
},
// load(imageId, priority = 999) {
// return new Promise((resolve, reject) => {
// const imageTask = this.buildImageRequestTask(imageId, { priority })
// requestPoolManager.addTaskIntoPool(imageTask).then((res) => {
// resolve(res)
// }).catch(e => {
// reject(e)
// console.log(e)
// })
// })
// },
buildImageRequestTask(imageId, config = {}) {
return {
key: imageId,
...config,
execute: () => {
return cornerstone.loadAndCacheImage(imageId)
}
}
},
datasetsCacheChanged(e) {
const cacheInfo = e.detail.cacheInfo
const cacheSizeInBytes = cacheInfo.cacheSizeInBytes
@@ -572,62 +727,47 @@ export default {
//
}
},
imageLoaded(image, seriesUid) {
var studyIndex = image.studyIndex
var seriesIndex = image.seriesIndex
if (seriesIndex < 0 || studyIndex < 0) return
if (this.studyList[studyIndex].SeriesList[seriesIndex].imageloadedArr.indexOf(image.imageId) < 0) {
++this.studyList[studyIndex].SeriesList[seriesIndex].prefetchInstanceCount
this.studyList[studyIndex].SeriesList[seriesIndex].imageloadedArr.push(image.imageId)
if (this.studyList[studyIndex].SeriesList[seriesIndex].prefetchInstanceCount >= this.studyList[studyIndex].SeriesList[seriesIndex].instanceCount) {
this.studyList[studyIndex].SeriesList[seriesIndex].prefetchInstanceCount = this.studyList[studyIndex].SeriesList[seriesIndex].instanceCount
//
this.studyList[studyIndex].SeriesList[seriesIndex].loadStatus = true
}
cornerstoneimageloadprogress(e) {
const imageId = e.detail.imageId
if (!imageId) return
const percentComplete = e.detail.percentComplete
const params = {}
const searchParams = new URLSearchParams(imageId.split('?')[1])
if (!searchParams) return
for (const [key, value] of searchParams.entries()) {
params[key] = value
}
},
// instance
cornerstoneImageLoaded(e) {
if (e.detail.image.imageId.includes(this.firstInstanceId) && !this.isStartLoad) {
//
this.loadAllImages()
this.isStartLoad = true
// requestPoolManager.executeTask()
}
const uri = e.detail.image.sharedCacheKey
const index = this.cachedImages.findIndex(item => item.uri === uri)
if (index === -1) {
this.cachedImages.push({ uri: uri, timestamp: new Date().getTime() })
} else {
this.cachedImages[index].timestamp = new Date().getTime()
}
var imageId = e.detail.image.imageId
var seriesUid = e.detail.image.data.string('x0020000e')
var studyIndex = -1
var seriesIndex = -1
for (let i = 0; i < this.studyList.length; ++i) {
for (let j = 0; j < this.studyList[i].SeriesList.length; ++j) {
if (this.studyList[i].SeriesList[j].seriesUid === seriesUid) {
studyIndex = i
seriesIndex = j
break
const studyIndex = params.idx.split('|')[0]
const seriesIndex = params.idx.split('|')[1]
var series = !params.isRelation ? this.studyList[studyIndex].SeriesList[seriesIndex] : null
if (!series) return
var prefetchInstanceCount = series.prefetchInstanceCount
var instanceCount = series.instanceCount
if (series.imageloadedArr.indexOf(imageId) < 0) {
const i = this.currentLoadIns.findIndex(i => i.imageId === imageId)
if (i > -1) {
prefetchInstanceCount = prefetchInstanceCount - this.currentLoadIns[i].percentComplete + percentComplete
this.currentLoadIns[i].percentComplete = percentComplete
if (percentComplete === 100) {
this.currentLoadIns.splice(i, 1)
}
} else {
if (percentComplete !== 100) {
this.currentLoadIns.push({ imageId, percentComplete })
}
prefetchInstanceCount = prefetchInstanceCount + percentComplete
}
series.prefetchInstanceCount = prefetchInstanceCount
if (percentComplete >= 100) {
series.imageloadedArr.push(imageId)
}
if (studyIndex > 0) break
}
if (seriesIndex < 0) return
const imageIdIndex = this.studyList[studyIndex].SeriesList[seriesIndex].imageIds.indexOf(imageId)
if (imageIdIndex < 0) return
if (this.studyList[studyIndex].SeriesList[seriesIndex].imageloadedArr.indexOf(imageId) < 0) {
++this.studyList[studyIndex].SeriesList[seriesIndex].prefetchInstanceCount
this.studyList[studyIndex].SeriesList[seriesIndex].imageloadedArr.push(imageId)
if (this.studyList[studyIndex].SeriesList[seriesIndex].prefetchInstanceCount >= this.studyList[studyIndex].SeriesList[seriesIndex].instanceCount) {
this.studyList[studyIndex].SeriesList[seriesIndex].prefetchInstanceCount = this.studyList[studyIndex].SeriesList[seriesIndex].instanceCount
//
this.studyList[studyIndex].SeriesList[seriesIndex].loadStatus = true
if (prefetchInstanceCount >= instanceCount * 100) {
series.prefetchInstanceCount = instanceCount * 100
//
series.loadStatus = true
if (!this.isFromCRCUpload) {
this.loadAllImages()
}
}
}
@@ -689,16 +829,16 @@ export default {
padding: 5px;
/* height: 95%; */
height: 99%;
overflow: hidden;
text-overflow: clip;
white-space: nowrap;
/* overflow: hidden;
text-overflow: clip; */
/* white-space: nowrap; */
}
.viewerContainer .viewerContentWrapper>div {
display: inline-block;
white-space: normal;
}
.viewerContainer .viewerLeftSidePanel {
width: 215px;
width: 220px;
background-color: #323232;
box-sizing: border-box;
margin: 0;
@@ -735,7 +875,7 @@ export default {
}
.viewerContainer .viewerLeftSidePanel .viewernavigatorwrapper {
display: flex;
width: 200px;
width: 220px;
/* height: 84px; */
padding: 1px 2px 1px 2px;
margin: 2px 0 1px 1px;
@@ -808,6 +948,29 @@ export default {
height: 40px;
line-height: 20px;
}
.instance_frame_wrapper{
min-width: 120px;
background-color: #2c2c2c;
border: 1px solid #2c2c2c;
padding: 5px;
}
.frame_content{
height: 50px;
padding: 5px;
display: flex;
justify-content: flex-start;
color: #ddd;
font-size: 12px;
border: 1px solid #404040;
}
.frame_content:hover {
/* font-weight: bold; */
/* box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); */
cursor: pointer;
/* color: #428bca; */
border-color: #213a54 !important;
background-color: #213a54;
}
/* .viewerRightSidePanel {
width: 300px;
@@ -3,7 +3,7 @@
ref="sysTemplateFrom"
v-loading="loading"
:model="form"
label-width="90px"
label-width="140px"
size="small"
:rules="rules"
class="upload-temporary-file"
@@ -12,10 +12,13 @@
<el-form-item label="Code" prop="Code">
<el-input v-model="form.Code" />
</el-form-item>
<el-form-item label="业务场景: " prop="BusinessScenarioEnum">
<el-form-item
:label="$t('dictionary:attachment:export:form:business')"
prop="BusinessScenarioEnum"
>
<el-select
v-model="form.BusinessScenarioEnum"
style="width:100%;"
style="width: 100%"
size="small"
filterable
>
@@ -27,7 +30,7 @@
/>
</el-select>
</el-form-item>
<el-form-item label="文件: ">
<el-form-item :label="$t('dictionary:attachment:export:form:file')">
<div class="upload-container">
<el-upload
class="upload-demo"
@@ -43,84 +46,123 @@
:on-exceed="handleExceed"
:disabled="!form.FileTypeEnum || !form.BusinessScenarioEnum"
>
<el-button size="small" type="primary" :disabled="!form.FileTypeEnum || !form.BusinessScenarioEnum" :loading="btnLoading">Select</el-button>
<span
slot="tip"
style="margin-left:10px;"
class="el-upload__tip"
<el-button
size="small"
type="primary"
:disabled="!form.FileTypeEnum || !form.BusinessScenarioEnum"
:loading="btnLoading"
>Select</el-button
>
<span slot="tip" style="margin-left: 10px" class="el-upload__tip">
(must be in xlsx/xls/doc/docx format)
</span>
</el-upload>
</div>
</el-form-item>
<el-form-item label="文件名" prop="Name">
<el-form-item
:label="$t('dictionary:attachment:export:form:name')"
prop="Name"
>
<el-input v-model="form.Name" />
</el-form-item>
<el-form-item v-if="form.Id !== ''" label="是否废除: ">
<el-form-item
:label="$t('dictionary:attachment:export:form:nameCN')"
prop="NameCN"
>
<el-input v-model="form.NameCN" />
</el-form-item>
<el-form-item
v-if="form.Id !== ''"
:label="$t('dictionary:attachment:export:form:isDeleted')"
>
<el-radio-group v-model="form.IsDeleted">
<el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="描述">
<el-form-item
:label="$t('dictionary:attachment:export:form:description')"
>
<el-input
v-model="form.Description"
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
placeholder="请输入内容"
:autosize="{ minRows: 2, maxRows: 4 }"
placeholder=""
/>
</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" :disabled="!form.FileTypeEnum || !form.BusinessScenarioEnum" :loading="saveBtnLoading" @click="handleSave">Save</el-button>
<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"
:disabled="!form.FileTypeEnum || !form.BusinessScenarioEnum"
:loading="saveBtnLoading"
@click="handleSave"
>{{ $t("common:button:save") }}</el-button
>
</el-form-item>
</div>
</el-form>
</template>
<script>
import { addOrUpdateCommonDocument, uploadCommonDoc, Upload } from '@/api/dictionary'
import { getBasicDataSelects } from '@/api/dictionary/dictionary'
import {
addOrUpdateCommonDocument,
uploadCommonDoc,
Upload,
} from "@/api/dictionary";
import { getBasicDataSelects } from "@/api/dictionary/dictionary";
export default {
name: 'TemplateForm',
name: "TemplateForm",
props: {
data: {
type: Object,
default() { return {} }
}
default() {
return {};
},
},
},
data() {
return {
form: {
Id: '',
Code: '',
Id: "",
Code: "",
FileTypeEnum: null,
BusinessScenarioEnum: null,
Name: '',
Path: '',
Description: '',
IsDeleted: false
Name: "",
NameCN: "",
Path: "",
Description: "",
IsDeleted: false,
},
rules: {
Code: [{ required: true, message: 'Please specify', trigger: ['blur'] }],
Name: [{ required: true, message: 'Please specify', trigger: ['blur'] }],
BusinessScenarioEnum: [{ required: true, message: 'Please select', trigger: ['blur'] }]
Code: [
{ required: true, message: "Please specify", trigger: ["blur"] },
],
Name: [
{ required: true, message: "Please specify", trigger: ["blur"] },
],
NameCN: [
{ required: true, message: "Please specify", trigger: ["blur"] },
],
BusinessScenarioEnum: [
{ required: true, message: "Please select", trigger: ["blur"] },
],
},
fileList: [],
btnLoading: false,
saveBtnLoading: false,
loading: false,
dictionaryList: {}
}
dictionaryList: {},
};
},
mounted() {
this.initForm()
this.initForm();
},
methods: {
async initForm() {
await this.getDicData()
await this.getDicData();
if (Object.keys(this.data).length > 0) {
if (this.data.Path) {
this.fileList = [
@@ -128,97 +170,111 @@ export default {
name: this.data.Name,
path: this.data.Path,
url: this.data.Path,
type: this.data.Type
}
]
type: this.data.Type,
},
];
}
for (const k in this.form) {
if (this.data.hasOwnProperty(k)) {
this.form[k] = this.data[k]
this.form[k] = this.data[k];
}
}
}
},
//
getDicData() {
this.loading = true
getBasicDataSelects(['Common_File_ModuleType', 'Common_File_Type']).then(res => {
this.dictionaryList = { ...res.Result }
this.loading = false
}).catch(() => {
this.loading = false
})
this.loading = true;
getBasicDataSelects(["Common_File_ModuleType", "Common_File_Type"])
.then((res) => {
this.dictionaryList = { ...res.Result };
this.loading = false;
})
.catch(() => {
this.loading = false;
});
},
beforeUpload(file) {
//
if (this.checkFileSuffix(file.name)) {
this.fileList = []
return true
this.fileList = [];
return true;
} else {
this.$alert('必须是word/excel格式')
return false
// this.$alert("word/excel");
this.$alert(this.$t("dictionary:attachment:export:alert:formatFile"));
return false;
}
},
async handleUploadFile(param) {
this.loading = true
const formData = new FormData()
formData.append('file', param.file)
this.form.FileName = param.file.name
Upload(formData, 1).then(res => {
this.fileList.push({ name: param.file.name, path: res.Result.FilePath, fullPath: res.Result.FullFilePath, url: res.Result.FilePath })
this.form.Path = res.Result.FilePath
this.form.Name = param.file.name
this.loading = false
this.btnLoading = false
})
this.loading = true;
const formData = new FormData();
formData.append("file", param.file);
this.form.FileName = param.file.name;
Upload(formData, 1).then((res) => {
this.fileList.push({
name: param.file.name,
path: res.Result.FilePath,
fullPath: res.Result.FullFilePath,
url: res.Result.FilePath,
});
this.form.Path = res.Result.FilePath;
this.form.NameCN = param.file.name;
this.loading = false;
this.btnLoading = false;
});
},
handleSave() {
this.$refs.sysTemplateFrom.validate(valid => {
if (!valid) return
this.$refs.sysTemplateFrom.validate((valid) => {
if (!valid) return;
if (!this.form.Name) {
this.$alert('Please select file.')
return
this.$alert("Please select file.");
return;
}
this.saveBtnLoading = true
addOrUpdateCommonDocument(this.form).then(res => {
this.saveBtnLoading = false
this.$emit('closeDialog')
this.$emit('getList')
this.$message.success('Uploaded successfully')
}).catch(() => {
this.saveBtnLoading = false
})
})
this.saveBtnLoading = true;
addOrUpdateCommonDocument(this.form)
.then((res) => {
this.saveBtnLoading = false;
this.$emit("closeDialog");
this.$emit("getList");
this.$message.success(
this.$t("trials:uploadMonitor:table:uploadStatus")
);
})
.catch(() => {
this.saveBtnLoading = false;
});
});
},
handleRemoveFile() {
this.fileList = []
this.form.Path = ''
this.form.Name = ''
this.fileList = [];
this.form.Path = "";
this.form.NameCN = "";
this.form.Name = "";
},
handlePreview(file) {
if (file.fullPath) {
window.open(file.fullPath, '_blank')
window.open(file.fullPath, "_blank");
}
},
handleExceed(files, fileList) {
this.$message.warning(`Upload is currently limited to 1 file`)
this.$message.warning(`Upload is currently limited to 1 file`);
},
checkFileSuffix(fileName) {
var typeArr = ['xls', 'xlsx', 'doc', 'docx']
var extendName = fileName.substring(fileName.lastIndexOf('.') + 1).toLocaleLowerCase()
var typeArr = ["xls", "xlsx", "doc", "docx"];
var extendName = fileName
.substring(fileName.lastIndexOf(".") + 1)
.toLocaleLowerCase();
if (typeArr.indexOf(extendName) !== -1) {
return true
return true;
} else {
return false
return false;
}
}
}
}
},
},
};
</script>
<style lang="scss">
.upload-temporary-file{
.upload-temporary-file {
.upload-container .el-upload--text {
border: none;
width: 80px;
@@ -231,8 +287,8 @@ export default {
color: #428bca;
font-size: 13px;
}
.account_item_clear{
.el-tag__close{
.account_item_clear {
.el-tag__close {
display: none !important;
}
}
@@ -2,10 +2,12 @@
<BaseContainer>
<template slot="search-container">
<el-form :inline="true" size="small">
<el-form-item label="业务场景">
<el-form-item
:label="$t('dictionary:attachment:export:search:business')"
>
<el-select
v-model="searchData.BusinessScenarioEnum"
style="width:150px;"
style="width: 150px"
>
<el-option
v-for="item of $d.Common_File_BusinessScenario"
@@ -13,41 +15,42 @@
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="文件名称">
<el-input
v-model="searchData.Name"
style="width:130px;"
clearable
/>
<el-form-item
:label="$t('dictionary:attachment:export:search:fileName')"
>
<el-input v-model="searchData.Name" style="width: 130px" clearable />
</el-form-item>
<el-form-item>
<!-- 查询 -->
<el-button type="primary" icon="el-icon-search" @click="handleSearch">
{{ $t('common:button:search') }}
{{ $t("common:button:search") }}
</el-button>
<!-- 重置 -->
<el-button type="primary" icon="el-icon-refresh-left" @click="handleReset">
{{ $t('common:button:reset') }}
<el-button
type="primary"
icon="el-icon-refresh-left"
@click="handleReset"
>
{{ $t("common:button:reset") }}
</el-button>
</el-form-item>
<el-button
type="primary"
icon="el-icon-plus"
style="float: right"
size="small"
@click="handleAdd"
>
{{ $t("common:button:new") }}
</el-button>
</el-form>
<el-button
type="primary"
icon="el-icon-plus"
style="margin-left:auto;"
size="small"
@click="handleAdd"
>
{{ $t('common:button:new') }}
</el-button>
</template>
<template slot="main-container">
<el-table
v-adaptive="{bottomOffset:60}"
v-adaptive="{ bottomOffset: 60 }"
v-loading="loading"
:data="list"
stripe
@@ -64,70 +67,81 @@
<el-table-column
prop="BusinessScenarioEnum"
label="业务场景"
:label="$t('dictionary:attachment:export:table:business')"
show-overflow-tooltip
sortable="custom"
>
<template slot-scope="scope">
{{ $fd('Common_File_BusinessScenario',scope.row.BusinessScenarioEnum) }}
{{
$fd(
"Common_File_BusinessScenario",
scope.row.BusinessScenarioEnum
)
}}
</template>
</el-table-column>
<el-table-column
prop="Name"
label="文件名称"
:label="$t('dictionary:attachment:export:table:name')"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
prop="NameCN"
:label="$t('dictionary:attachment:export:table:nameCN')"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
prop="Description"
label="描述"
:label="$t('dictionary:attachment:export:table:description')"
show-overflow-tooltip
/>
<el-table-column
prop="IsDeleted"
label="是否废除"
:label="$t('dictionary:attachment:export:table:isDeleted')"
show-overflow-tooltip
sortable="custom"
>
<template slot-scope="scope">
<el-tag v-if="scope.row.IsDeleted" type="danger">{{ $fd('YesOrNo', scope.row.IsDeleted) }}</el-tag>
<el-tag v-else type="primary">{{ $fd('YesOrNo', scope.row.IsDeleted) }}</el-tag>
<el-tag v-if="scope.row.IsDeleted" type="danger">{{
$fd("YesOrNo", scope.row.IsDeleted)
}}</el-tag>
<el-tag v-else type="primary">{{
$fd("YesOrNo", scope.row.IsDeleted)
}}</el-tag>
</template>
</el-table-column>
<el-table-column
prop="UpdateTime"
label="更新时间"
:label="$t('dictionary:attachment:export:table:updateTime')"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column label="Action">
<el-table-column :label="$t('common:action:action')">
<template slot-scope="scope">
<el-button
type="text"
@click="handleDownload(scope.row)"
>
下载
<el-button type="text" @click="handleDownload(scope.row)">
{{ $t("common:button:download") }}
</el-button>
<el-button
type="text"
@click="handleEdit(scope.row)"
>
编辑
<el-button type="text" @click="handleEdit(scope.row)">
{{ $t("common:button:edit") }}
</el-button>
<el-button
type="text"
@click="handleDelete(scope.row)"
>
删除
<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" />
<pagination
class="page"
:total="total"
:page.sync="searchData.PageIndex"
:limit.sync="searchData.PageSize"
@pagination="getList"
/>
<!-- 新增/编辑 -->
<el-dialog
@@ -138,28 +152,36 @@
width="600px"
custom-class="base-dialog-wrapper"
>
<TemplateForm :data="currentRow" @closeDialog="closeDialog" @getList="getList" />
<TemplateForm
:data="currentRow"
@closeDialog="closeDialog"
@getList="getList"
/>
</el-dialog>
</template>
</BaseContainer>
</template>
<script>
import { getCommonDocumentList, DownloadCommonDoc, deleteCommonDocument } from '@/api/dictionary'
import BaseContainer from '@/components/BaseContainer'
import Pagination from '@/components/Pagination'
import TemplateForm from './TemplateForm'
const FileTypeEnum = 2
import {
getCommonDocumentList,
DownloadCommonDoc,
deleteCommonDocument,
} from "@/api/dictionary";
import BaseContainer from "@/components/BaseContainer";
import Pagination from "@/components/Pagination";
import TemplateForm from "./TemplateForm";
const FileTypeEnum = 2;
const searchDataDefault = () => {
return {
FileTypeEnum: FileTypeEnum,
BusinessScenarioEnum: null,
Name: '',
Name: "",
PageIndex: 1,
PageSize: 20
}
}
PageSize: 20,
};
};
export default {
name: 'ExportTemplate',
name: "ExportTemplate",
components: { BaseContainer, Pagination, TemplateForm },
data() {
return {
@@ -167,73 +189,86 @@ export default {
list: [],
total: 0,
currentRow: {},
editDialog: { title: '', visible: false },
loading: false
}
editDialog: { title: "", visible: false },
loading: false,
};
},
mounted() {
this.getList()
this.getList();
},
methods: {
handleDelete(row) {
this.$confirm('确定删除该模版?').then(() => {
this.$confirm(
this.$t("dictionary:attachment:export:confirm:delete")
).then(() => {
deleteCommonDocument(row.Id).then(() => {
this.$message.success('删除成功')
this.getList()
})
})
this.$message.success(this.$t("common:message:deletedSuccessfully"));
this.getList();
});
});
},
getList() {
this.loading = true
getCommonDocumentList(this.searchData).then(res => {
this.loading = false
this.list = res.Result.CurrentPageData
this.total = res.Result.TotalCount
}).catch(() => {
this.loading = false
})
this.loading = true;
getCommonDocumentList(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 = 'Add'
this.currentRow = { FileTypeEnum: FileTypeEnum }
this.editDialog.visible = true
this.editDialog.title = "Add";
this.currentRow = { FileTypeEnum: FileTypeEnum };
this.editDialog.visible = true;
},
//
handleDownload(row) {
this.loading = true
DownloadCommonDoc(row.Code).then(data => {
this.loading = false
}).catch(() => { this.loading = false })
this.loading = true;
DownloadCommonDoc(row.Code)
.then((data) => {
this.loading = false;
})
.catch(() => {
this.loading = false;
});
},
//
handleEdit(row) {
this.editDialog.title = 'Edit'
this.currentRow = { ...row }
this.editDialog.visible = true
this.editDialog.title = "Edit";
this.currentRow = { ...row };
this.editDialog.visible = true;
},
handleSearch() {
this.searchData.PageIndex = 1
this.getList()
this.searchData.PageIndex = 1;
this.getList();
},
handleReset() {
this.searchData = searchDataDefault()
this.getList()
this.searchData = searchDataDefault();
this.getList();
},
closeDialog() {
this.editDialog.visible = false
this.editDialog.visible = false;
},
//
handleSortChange(column) {
if (column.order === 'ascending') {
this.searchData.Asc = true
if (column.order === "ascending") {
this.searchData.Asc = true;
} else {
this.searchData.Asc = false
this.searchData.Asc = false;
}
this.searchData.SortField = column.prop
this.searchData.PageIndex = 1
this.getList()
}
}
}
this.searchData.SortField = column.prop;
this.searchData.PageIndex = 1;
this.getList();
},
},
};
</script>
<style lang="scss" scoped>
::v-deep .search{
display: block;
}
</style>
@@ -244,8 +244,7 @@ export default {
this.$confirm('是否确认废除此文件?', {
type: 'warning',
distinguishCancelAndClose: true,
confirmButtonText: 'Ok',
cancelButtonText: 'Cancel'
})
.then(() => {
this.loading = true
+67 -8
View File
@@ -33,7 +33,7 @@
<el-table-column prop="ModuleTypeValueCN" label="模块" show-overflow-tooltip align="left" min-width="230px" />
<el-table-column prop="Description" label="操作名称" :show-overflow-tooltip="true" min-width="200px">
<template slot-scope="scope">
<span>{{ scope.row.Description }}{{scope.row.DescriptionCN}}</span>
<span>{{ scope.row.DescriptionCN }}{{scope.row.Description}}</span>
</template>
</el-table-column>
<el-table-column prop="DescriptionCN" label="其他" :show-overflow-tooltip="true" min-width="140px">
@@ -513,12 +513,27 @@
</el-col>
<el-col v-show="form.ConfigType === 'C' && title !== '复制' && form.EnumType === 'Dictionary'" :span="12">
<el-form-item label="字典表名">
<el-input v-model="form.DictionaryCode" placeholder="请输入字典表名" />
<!-- <el-input v-model="form.DictionaryCode" placeholder="请输入字典表名" /> -->
<el-autocomplete
clearable
class="inline-input"
v-model="form.DictionaryCode"
:fetch-suggestions="querySearch"
placeholder="请输入字典表名"
></el-autocomplete>
</el-form-item>
</el-col>
<el-col v-show="form.ConfigType === 'C' && title !== '复制' && form.EnumType === 'Dictionary'" :span="12">
<el-form-item label="翻译字段">
<el-input v-model="form.DictionaryType" placeholder="请输入翻译字段" />
<!-- <el-input v-model="form.DictionaryType" placeholder="请输入翻译字段" /> -->
<el-select v-model="form.DictionaryType" clearable placeholder="请选择翻译字段">
<el-option
v-for="item in $d.DictionaryType"
:key="item.id"
:label="item.label"
:value="item.label">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col v-show="form.ConfigType === 'C' && title !== '复制' && form.EnumType === 'Date'" :span="24">
@@ -608,11 +623,11 @@
<div style="padding: 0 40px;display: flex;flex-direction: column">
<div style="text-align: right;height: 50px;">
<el-select v-model="copeParams.FromItemId" collapse-tags filterable placeholder="完全拷贝对象" clearable size="small">
<el-option v-for="item of list" v-if="drawer_cfg.drawerChild && item.ConfigType === 'M' && item.ObjectTypeId === selectRow.ObjectTypeId && item.OptTypeId && item.ChildrenTypeId " :value="item.Id" :label="item.Description" />
<el-option v-for="item of list" v-if="drawer_cfg.drawerChild && item.ConfigType === 'M' && item.ObjectTypeId === selectRow.ObjectTypeId && item.OptTypeId && item.ChildrenTypeId " :value="item.Id" :label="item.DescriptionCN" />
</el-select>
<el-button type="primary" size="mini" style="margin-right: 10px" @click="handleOverCope(selectRow)">完全拷贝</el-button>
<el-select v-model="copeParams.DataSourceGuids" multiple collapse-tags filterable placeholder="拷贝对象" clearable size="small">
<el-option v-for="item of list" v-if="drawer_cfg.drawerChild && item.ConfigType === 'M' && item.ObjectTypeId === selectRow.ObjectTypeId && item.OptTypeId && item.ChildrenTypeId " :value="item.Id" :label="item.Description" />
<el-option v-for="item of list" v-if="drawer_cfg.drawerChild && item.ConfigType === 'M' && item.ObjectTypeId === selectRow.ObjectTypeId && item.OptTypeId && item.ChildrenTypeId " :value="item.Id" :label="item.DescriptionCN" />
</el-select>
<el-button type="primary" size="mini" @click="handleCope(selectRow)">拷贝</el-button>
<el-button type="primary" size="mini" @click="handleAdd(selectRow)">新建</el-button>
@@ -668,6 +683,12 @@
<el-table-column prop="TrialConfigRelyFieldName" label="依赖字段" min-width="120px" :show-overflow-tooltip="true" />
<el-table-column label="操作" align="center" min-width="180" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleCopyData(scope.row)"
>复制</el-button>
<el-button
size="mini"
type="text"
@@ -690,7 +711,7 @@
</template>
<script>
import { fullyReplicated, changeFrontAuditSort, copyFrontAuditConfigItem, getFrontAuditConfigList, addOrUpdateFrontAuditConfig, deleteFrontAuditConfig, copyOtherToThisItem, getAuditConfigChildList, setDictionaryValue } from '@/api/dictionary/checkConfig'
import { fullyReplicated, changeFrontAuditSort, copyFrontAuditConfigItem, getFrontAuditConfigList, addOrUpdateFrontAuditConfig, deleteFrontAuditConfig, copyOtherToThisItem, getAuditConfigChildList, getDictionaryCodeList } from '@/api/dictionary/checkConfig'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import Sortable from 'sortablejs'
@@ -743,13 +764,41 @@ export default {
},
ChildGroup: null,
tableShow: false,
rowDrop2TableIsShow: true
rowDrop2TableIsShow: true,
DictionaryCodeList:[]
}
},
created() {
this.getList()
this.getList();
this.getDictionaryCodeList();
},
methods: {
querySearch(queryString, cb) {
var DictionaryCodeList = this.DictionaryCodeList;
var results = queryString ? DictionaryCodeList.filter(this.createFilter(queryString)) : DictionaryCodeList;
// callback
cb(results);
},
createFilter(queryString) {
return (DictionaryCodeList) => {
return (DictionaryCodeList.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
};
},
//
async getDictionaryCodeList(){
try{
let res = await getDictionaryCodeList();
if(res.IsSuccess){
this.DictionaryCodeList = res.Result.map(item=>{
return {
value:item
}
});
}
}catch(err){
console.log(err);
}
},
addParameter() {
this.form.UrlConfig.ParameterList.push({
UrlParameterName: null,
@@ -1146,6 +1195,16 @@ export default {
this.title = '修改'
this.rowDrop2()
},
handleCopyData (row) {
this.$confirm('确定复制该条记录到当前稽查下吗?').then(() => {
let params = {...row}
delete params.Id
addOrUpdateFrontAuditConfig(params).then(() => {
this.$message.success(this.$t('common:message:savedSuccessfully'))
this.getList()
})
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
+3 -4
View File
@@ -125,18 +125,17 @@ export default {
},
//
handleDelete(row) {
this.$confirm('Sure to delete?', {
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
type: 'warning',
distinguishCancelAndClose: true,
confirmButtonText: 'Ok',
cancelButtonText: 'Cancel'
})
.then(() => {
deleteDictionary(row.Id)
.then(res => {
if (res.IsSuccess) {
this.list.splice(this.list.findIndex(item => item.Id === row.Id), 1)
this.$message.success('Deleted successfully!')
this.$message.success(this.$t('common:message:deletedSuccessfully'))
this.$store.dispatch('global/setDictionary', {})
}
})
+3 -4
View File
@@ -239,18 +239,17 @@ export default {
},
//
handleDelete(row) {
this.$confirm('Sure to delete?', {
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
type: 'warning',
distinguishCancelAndClose: true,
confirmButtonText: 'Ok',
cancelButtonText: 'Cancel'
})
.then(() => {
deleteEmailNoticeConfig(row.Id)
.then(res => {
if (res.IsSuccess) {
this.list.splice(this.list.findIndex(item => item.Id === row.Id), 1)
this.$message.success('Deleted successfully!')
this.$message.success(this.$t('common:message:deletedSuccessfully'))
}
})
})
@@ -3,26 +3,34 @@
<div class="search">
<el-form :inline="true" size="small" class="base-search-form">
<el-form-item label="CRO Name:">
<el-input v-model="searchData.CROName" style="width:100px;" />
<el-input v-model="searchData.CROName" style="width: 100px" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleSearch">Search</el-button>
<el-button type="primary" icon="el-icon-refresh-left" @click="handleReset">Reset</el-button>
<el-button type="primary" icon="el-icon-search" @click="handleSearch"
>Search</el-button
>
<el-button
type="primary"
icon="el-icon-refresh-left"
@click="handleReset"
>Reset</el-button
>
</el-form-item>
</el-form>
<span style="margin-left:auto;">
<span style="margin-left: auto">
<el-button
size="small"
type="primary"
style="margin-left:auto;"
style="margin-left: auto"
icon="el-icon-plus"
@click="handleAddCro"
>New</el-button>
>New</el-button
>
</span>
</div>
<el-table
v-loading="loading"
v-adaptive="{bottomOffset:60}"
v-adaptive="{ bottomOffset: 60 }"
:data="list"
stripe
height="100"
@@ -50,6 +58,16 @@
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
prop="IsTrialLevel"
label="Level"
show-overflow-tooltip
sortable="custom"
>
<template slot-scope="scope">
<span>{{ $fd("IsTrialLevel", String(scope.row.IsTrialLevel)) }}</span>
</template>
</el-table-column>
<el-table-column label="Action" min-width="200">
<template slot-scope="scope">
<el-button
@@ -68,7 +86,13 @@
</el-table-column>
</el-table>
<!-- 分页组件 -->
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize" @pagination="getList" />
<pagination
class="page"
:total="total"
:page.sync="searchData.PageIndex"
:limit.sync="searchData.PageSize"
@pagination="getList"
/>
<el-dialog
v-if="editVisible"
@@ -78,26 +102,32 @@
width="600px"
custom-class="base-dialog-wrapper"
>
<CroForm v-if="editVisible" :data="rowData" @close="close" @getList="getList" />
<CroForm
v-if="editVisible"
:data="rowData"
:IsTrialLevel="rowData.IsTrialLevel"
@close="close"
@getList="getList"
/>
</el-dialog>
</box-content>
</template>
<script>
import { getCROPageList, deleteCROCompany } from '@/api/dictionary'
import BoxContent from '@/components/BoxContent'
import Pagination from '@/components/Pagination'
import CroForm from './CroForm'
import { getCROPageList, deleteCROCompany } from "@/api/dictionary";
import BoxContent from "@/components/BoxContent";
import Pagination from "@/components/Pagination";
import CroForm from "./CroForm";
const searchDataDefault = () => {
return {
CROName: '',
CROName: "",
PageIndex: 1,
PageSize: 20,
Asc: true,
SortField: ''
}
}
SortField: "",
};
};
export default {
name: 'Cros',
name: "Cros",
components: { BoxContent, Pagination, CroForm },
data() {
return {
@@ -107,88 +137,93 @@ export default {
loading: false,
rowData: {},
editVisible: false,
title: ''
}
title: "",
};
},
mounted() {
this.getList()
this.getList();
},
methods: {
// CRO
getList() {
this.loading = true
getCROPageList(this.searchData).then(res => {
this.loading = false
this.list = res.Result.CurrentPageData
this.total = res.Result.TotalCount
}).catch(() => {
this.loading = false
})
this.loading = true;
getCROPageList(this.searchData)
.then((res) => {
this.loading = false;
this.list = res.Result.CurrentPageData;
this.total = res.Result.TotalCount;
})
.catch(() => {
this.loading = false;
});
},
// CRO
handleAddCro() {
this.rowData = {}
this.title = 'Add'
this.editVisible = true
this.rowData = {};
this.title = "Add";
this.editVisible = true;
},
// CRO
handleEdit(row) {
this.rowData = row
this.title = 'Edit'
this.editVisible = true
this.rowData = row;
this.title = "Edit";
this.editVisible = true;
},
// CRO
handleDelete(row) {
this.$confirm('Sure to delete?', {
type: 'warning',
this.$confirm(this.$t("trials:uploadedDicoms:message:deleteMes"), {
type: "warning",
distinguishCancelAndClose: true,
confirmButtonText: 'Ok',
cancelButtonText: 'Cancel'
})
.then(() => {
this.loading = true
deleteCROCompany(row.Id)
.then(res => {
this.loading = false
if (res.IsSuccess) {
this.list.splice(this.list.findIndex(item => item.Id === row.Id), 1)
this.$message.success('Deleted successfully!')
}
}).catch(() => {
this.loading = false
})
})
}).then(() => {
this.loading = true;
deleteCROCompany(row.Id)
.then((res) => {
this.loading = false;
if (res.IsSuccess) {
this.list.splice(
this.list.findIndex((item) => item.Id === row.Id),
1
);
this.$message.success(
this.$t("common:message:deletedSuccessfully")
);
}
})
.catch(() => {
this.loading = false;
});
});
},
//
handleReset() {
this.searchData = searchDataDefault()
this.getList()
this.searchData = searchDataDefault();
this.getList();
},
//
handleSearch() {
this.searchData.PageIndex = 1
this.getList()
this.searchData.PageIndex = 1;
this.getList();
},
//
handleSortByColumn(column) {
if (column.order === 'ascending') {
this.searchData.Asc = true
if (column.order === "ascending") {
this.searchData.Asc = true;
} else {
this.searchData.Asc = false
this.searchData.Asc = false;
}
this.searchData.SortField = column.prop
this.searchData.PageIndex = 1
this.getList()
this.searchData.SortField = column.prop;
this.searchData.PageIndex = 1;
this.getList();
},
//
close() {
this.editVisible = false
}
}
}
this.editVisible = false;
},
},
};
</script>
<style lang="scss" scoped>
.cros{
.cros {
height: 100%;
}
</style>
@@ -17,70 +17,98 @@
<el-form-item label="CRO Code: " prop="CROCode">
<el-input v-model="form.CROCode" />
</el-form-item>
<el-form-item label="Level: ">
<el-switch
:disabled="!IsTrialLevel"
v-model="form.IsTrialLevel"
:active-text="$fd('IsTrialLevel', 'true')"
:inactive-text="$fd('IsTrialLevel', 'false')"
>
</el-switch>
</el-form-item>
</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">
<el-form-item>
<el-button :disabled="btnLoading" type="primary" @click="handleCancel">Cancel</el-button>
<el-button type="primary" :loading="btnLoading" @click="handleSave">Save</el-button>
<el-button :disabled="btnLoading" type="primary" @click="handleCancel"
>Cancel</el-button
>
<el-button type="primary" :loading="btnLoading" @click="handleSave"
>Save</el-button
>
</el-form-item>
</div>
</el-form>
</template>
<script>
import { addOrUpdateCro } from '@/api/dictionary'
import { addOrUpdateCro } from "@/api/dictionary";
export default {
name: 'CroForm',
name: "CroForm",
props: {
data: {
type: Object,
default() {
return {}
}
}
return {};
},
},
IsTrialLevel: {
type: Boolean,
default: true,
},
},
data() {
return {
btnLoading: false,
form: {
Id: '',
CROName: '',
CRONameCN: '',
CROCode: ''
Id: "",
CROName: "",
CRONameCN: "",
CROCode: "",
IsTrialLevel: true,
},
rules: {
CROName: [{ required: true, message: 'Please specify', trigger: 'blur' }, { max: 50, message: 'The maximum length is 50' }],
CRONameCN: [{ required: true, message: 'Please specify', trigger: 'blur' }, { max: 50, message: 'The maximum length is 50' }],
CROCode: [{ required: true, message: 'Please specify', trigger: 'blur' }, { max: 50, message: 'The maximum length is 50' }]
}
}
CROName: [
{ required: true, message: "Please specify", trigger: "blur" },
{ max: 500, message: "The maximum length is 500" },
],
CRONameCN: [
{ required: true, message: "Please specify", trigger: "blur" },
{ max: 500, message: "The maximum length is 500" },
],
CROCode: [
{ required: true, message: "Please specify", trigger: "blur" },
{ max: 50, message: "The maximum length is 50" },
],
},
};
},
mounted() {
if (Object.keys(this.data).length && this.data.Id) {
this.form = { ...this.data }
this.form = { ...this.data };
}
},
methods: {
handleSave() {
this.$refs.CROForm.validate(valid => {
if (!valid) return
this.btnLoading = true
addOrUpdateCro(this.form).then(res => {
this.btnLoading = false
if (res.IsSuccess) {
this.$message.success('Saved successfully')
this.$refs['CROForm'].resetFields()
this.$emit('getList')
this.$emit('close')
}
}).catch(() => {
this.btnLoading = false
})
})
this.$refs.CROForm.validate((valid) => {
if (!valid) return;
this.btnLoading = true;
addOrUpdateCro(this.form)
.then((res) => {
this.btnLoading = false;
if (res.IsSuccess) {
this.$message.success("Saved successfully");
this.$refs["CROForm"].resetFields();
this.$emit("getList");
this.$emit("close");
}
})
.catch(() => {
this.btnLoading = false;
});
});
},
handleCancel() {
this.$emit('close')
}
}
}
this.$emit("close");
},
},
};
</script>
@@ -8,12 +8,15 @@
label-width="170px"
>
<div class="base-dialog-body">
<el-form-item label="Hospital CN: " prop="SiteId">
<el-select v-model="form.SiteId" style="width: 100%" filterable @change="siteChange">
<el-form-item label="Site: ">
<el-select v-model="form.SiteId" style="width: 100%" clearable filterable @change="siteChange">
<el-option v-for="item of siteList" :value="item.Id" :key="item.Id" :label="item.SiteName">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="Hospital CN: " prop="HospitalNameCN">
<el-input v-model="form.HospitalNameCN" />
</el-form-item>
<el-form-item label="Hospital EN: " prop="HospitalName">
<el-input v-model="form.HospitalName" />
</el-form-item>
@@ -88,9 +91,7 @@ export default {
},
siteList: [],
rules: {
SiteId: [{ required: true, message: 'Please specify', trigger: 'blur' },
{ max: 50, message: 'The maximum length is 50' }],
HospitalName: [{ required: true, message: 'Please specify', trigger: 'blur' }, { max: 50, message: 'The maximum length is 50' }],
HospitalNameCN: [{ required: true, message: 'Please specify', trigger: 'blur' }, { max: 50, message: 'The maximum length is 50' }],
UniversityAffiliated: [{ max: 100, message: 'The maximum length is 100' }],
UniversityAffiliatedCN: [{ max: 100, message: 'The maximum length is 100' }],
Country: [{ required: true, message: 'Please specify', trigger: 'blur' },
@@ -116,7 +117,8 @@ export default {
this.siteList.forEach(o => {
if (o.Id === v) {
this.form.CityCN = o.City
this.form.HospitalNameCN = o.SiteName
this.form.HospitalNameCN = o.SiteNameCN
this.form.HospitalName = o.SiteName
this.form.ProvinceCN = o.Province
this.form.CountryCN = o.Country
}
@@ -1,256 +1,255 @@
<template>
<box-content>
<div class="search">
<el-form :inline="true" size="small" class="base-search-form">
<el-form-item label="Hospital:">
<el-input v-model="searchData.HospitalName" style="width:100px;" />
</el-form-item>
<el-form-item label="Province:">
<el-input v-model="searchData.Province" style="width:100px;" />
</el-form-item>
<el-form-item label="City:">
<el-input v-model="searchData.City" style="width:100px;" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleSearch">Search</el-button>
<el-button type="primary" icon="el-icon-refresh-left" @click="handleReset">Reset</el-button>
</el-form-item>
</el-form>
<span style="margin-left:auto;">
<el-button
size="small"
type="primary"
style="margin-left:auto;"
icon="el-icon-plus"
@click="handleAddHospital"
>New</el-button>
</span>
</div>
<!-- hospital列表 -->
<el-table
v-loading="loading"
v-adaptive="{bottomOffset:60}"
:data="list"
stripe
height="100"
@sort-change="handleSortByColumn"
>
<el-table-column type="index" width="40" />
<el-table-column
prop="HospitalName"
label="Hospital"
min-width="120"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
prop="HospitalNameCN"
label="Hospital CN"
min-width="120"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
prop="UniversityAffiliated"
label="University Affiliated"
min-width="170"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
prop="UniversityAffiliatedCN"
label="University Affiliated CN"
min-width="170"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
prop="Country"
label="Country"
width="120"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
prop="CountryCN"
label="Country CN"
width="140"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
prop="Province"
label="Province"
width="120"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
prop="ProvinceCN"
label="Province CN"
width="140"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
prop="City"
label="City"
width="120"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
prop="CityCN"
label="City CN"
width="120"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column label="Action" width="150">
<template slot-scope="scope">
<el-button
circle
icon="el-icon-edit-outline"
title="编辑"
@click="handleEdit(scope.row)"
/>
<el-button
circle
icon="el-icon-delete"
title="删除"
@click="handleDelete(scope.row)"
/>
</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"
width="600px"
custom-class="base-dialog-wrapper"
>
<hospital-form v-if="editDialog.visible" :data="rowData" @close="close" @getList="getList" />
</el-dialog>
</box-content>
</template>
<script>
import { getHospitalPageList, deleteHospital } from '@/api/dictionary'
import BoxContent from '@/components/BoxContent'
import Pagination from '@/components/Pagination'
import HospitalForm from './HospitalForm'
const searchDataDefault = () => {
return {
HospitalName: '',
Province: '',
City: '',
PageIndex: 1,
PageSize: 20,
Asc: true,
SortField: ''
}
}
export default {
name: 'Hospitals',
components: { BoxContent, Pagination, HospitalForm },
data() {
return {
searchData: searchDataDefault(),
editDialog: { visible: false, title: '' },
list: [],
total: 0,
loading: false,
rowData: {}
}
},
mounted() {
this.getList()
},
methods: {
//
getList() {
this.loading = true
getHospitalPageList(this.searchData).then(res => {
this.loading = false
this.list = res.Result.CurrentPageData
this.total = res.Result.TotalCount
}).catch(() => {
this.loading = false
})
},
//
handleAddHospital() {
this.rowData = {}
this.editDialog.title = 'Add'
this.editDialog.visible = true
},
//
handleEdit(row) {
this.rowData = row
this.editDialog.title = 'Edit'
this.editDialog.visible = true
},
//
handleDelete(row) {
this.$confirm('Sure to delete?', {
type: 'warning',
distinguishCancelAndClose: true,
confirmButtonText: 'Ok',
cancelButtonText: 'Cancel'
})
.then(() => {
this.loading = true
deleteHospital(row.Id)
.then(res => {
if (res.IsSuccess) {
this.list.splice(this.list.findIndex(item => item.Id === row.Id), 1)
this.$message.success('Deleted successfully!')
}
this.loading = false
}).catch(() => {
this.loading = false
})
})
},
//
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()
},
//
close() {
this.editDialog.visible = false
}
}
}
</script>
<style lang="scss" scoped>
.hospitals{
height: 100%;
}
</style>
<template>
<box-content>
<div class="search">
<el-form :inline="true" size="small" class="base-search-form">
<el-form-item label="Hospital:">
<el-input v-model="searchData.HospitalName" style="width:100px;" />
</el-form-item>
<el-form-item label="Province:">
<el-input v-model="searchData.Province" style="width:100px;" />
</el-form-item>
<el-form-item label="City:">
<el-input v-model="searchData.City" style="width:100px;" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleSearch">Search</el-button>
<el-button type="primary" icon="el-icon-refresh-left" @click="handleReset">Reset</el-button>
</el-form-item>
</el-form>
<span style="margin-left:auto;">
<el-button
size="small"
type="primary"
style="margin-left:auto;"
icon="el-icon-plus"
@click="handleAddHospital"
>New</el-button>
</span>
</div>
<!-- hospital列表 -->
<el-table
v-loading="loading"
v-adaptive="{bottomOffset:60}"
:data="list"
stripe
height="100"
@sort-change="handleSortByColumn"
>
<el-table-column type="index" width="40" />
<el-table-column
prop="HospitalName"
label="Hospital"
min-width="120"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
prop="HospitalNameCN"
label="Hospital CN"
min-width="120"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
prop="UniversityAffiliated"
label="University Affiliated"
min-width="170"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
prop="UniversityAffiliatedCN"
label="University Affiliated CN"
min-width="170"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
prop="Country"
label="Country"
width="120"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
prop="CountryCN"
label="Country CN"
width="140"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
prop="Province"
label="Province"
width="120"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
prop="ProvinceCN"
label="Province CN"
width="140"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
prop="City"
label="City"
width="120"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
prop="CityCN"
label="City CN"
width="120"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column label="Action" width="150">
<template slot-scope="scope">
<el-button
circle
icon="el-icon-edit-outline"
title="编辑"
@click="handleEdit(scope.row)"
/>
<el-button
circle
icon="el-icon-delete"
title="删除"
@click="handleDelete(scope.row)"
/>
</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"
width="600px"
custom-class="base-dialog-wrapper"
>
<hospital-form v-if="editDialog.visible" :data="rowData" @close="close" @getList="getList" />
</el-dialog>
</box-content>
</template>
<script>
import { getHospitalPageList, deleteHospital } from '@/api/dictionary'
import BoxContent from '@/components/BoxContent'
import Pagination from '@/components/Pagination'
import HospitalForm from './HospitalForm'
const searchDataDefault = () => {
return {
HospitalName: '',
Province: '',
City: '',
PageIndex: 1,
PageSize: 20,
Asc: true,
SortField: ''
}
}
export default {
name: 'Hospitals',
components: { BoxContent, Pagination, HospitalForm },
data() {
return {
searchData: searchDataDefault(),
editDialog: { visible: false, title: '' },
list: [],
total: 0,
loading: false,
rowData: {}
}
},
mounted() {
this.getList()
},
methods: {
//
getList() {
this.loading = true
getHospitalPageList(this.searchData).then(res => {
this.loading = false
this.list = res.Result.CurrentPageData
this.total = res.Result.TotalCount
}).catch(() => {
this.loading = false
})
},
//
handleAddHospital() {
this.rowData = {}
this.editDialog.title = 'Add'
this.editDialog.visible = true
},
//
handleEdit(row) {
this.rowData = row
this.editDialog.title = 'Edit'
this.editDialog.visible = true
},
//
handleDelete(row) {
this.$confirm(this.$t('trials:uploadedDicoms:message:deleteMes'), {
type: 'warning',
distinguishCancelAndClose: true,
})
.then(() => {
this.loading = true
deleteHospital(row.Id)
.then(res => {
if (res.IsSuccess) {
this.list.splice(this.list.findIndex(item => item.Id === row.Id), 1)
this.$message.success(this.$t('common:message:deletedSuccessfully'))
}
this.loading = false
}).catch(() => {
this.loading = false
})
})
},
//
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()
},
//
close() {
this.editDialog.visible = false
}
}
}
</script>
<style lang="scss" scoped>
.hospitals{
height: 100%;
}
</style>

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