51 Commits

Author SHA1 Message Date
wangxiaoshuang 67a75188e5 双屏教程更改 2026-07-29 16:43:40 +08:00
wangxiaoshuang 0266f1266c 生产0nlyoffice地址配置 2026-07-20 10:16:21 +08:00
caiyiling c010522112 Merge commit '6ecc0e58e9f79518d1c129ccb982581d3bf4acdb' into rj 2026-07-16 16:22:11 +08:00
caiyiling 6ecc0e58e9 重置标记更改;标记定位更改
continuous-integration/drone/push Build is passing
2026-07-16 15:40:28 +08:00
wangxiaoshuang aad6242114 Merge branch 'main' into rj 2026-07-16 14:12:21 +08:00
wangxiaoshuang 84a81e1851 临床数据输入框禁用样式修改
continuous-integration/drone/push Build is passing
2026-07-16 14:12:04 +08:00
wangxiaoshuang 6405a07e70 Merge branch 'main' into rj 2026-07-16 13:31:11 +08:00
wangxiaoshuang b09209af31 完全随机分割问题绑定弹框不显示检查编号显示检查模态
continuous-integration/drone/push Build is passing
2026-07-16 13:30:48 +08:00
caiyiling 9892070ccc 播放功能修改
continuous-integration/drone/push Build is passing
2026-07-16 11:43:10 +08:00
wangxiaoshuang eec575d210 Merge branch 'main' into rj 2026-07-16 10:55:53 +08:00
wangxiaoshuang 63cbc8746f 完全随机融合弹框不显示检查号显示检查模态
continuous-integration/drone/push Build is passing
2026-07-16 10:54:55 +08:00
wangxiaoshuang b568b40f95 Merge branch 'main' into rj 2026-07-15 14:50:08 +08:00
wangxiaoshuang fe64feac80 路由守卫判断条件修改
continuous-integration/drone/push Build was killed
2026-07-15 14:49:51 +08:00
wangxiaoshuang 767be63feb Merge branch 'main' into rj 2026-07-14 17:54:32 +08:00
wangxiaoshuang dce7fd9737 Merge branch 'uat'
continuous-integration/drone/push Build is passing
2026-07-14 17:54:02 +08:00
wangxiaoshuang 6187c585ad 接口频繁请求不提示
continuous-integration/drone/push Build is passing
2026-07-14 17:53:39 +08:00
wangxiaoshuang b0fcf37835 Merge branch 'main' into rj 2026-07-14 11:51:01 +08:00
wangxiaoshuang 22ac496d7b 用户编辑页添加国际化
continuous-integration/drone/push Build is passing
2026-07-14 11:50:46 +08:00
wangxiaoshuang 303fb22e11 版权登记信息修改 2026-07-14 09:22:26 +08:00
wangxiaoshuang dadf1de9ed 初始化 2026-07-13 13:00:00 +08:00
caiyiling 45c0e5030b Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2026-07-10 17:54:12 +08:00
caiyiling 36e23b8135 通知列表添加默认排序 2026-07-10 17:53:50 +08:00
wangxiaoshuang b530f68446 1
continuous-integration/drone/push Build is passing
2026-07-10 17:11:39 +08:00
wangxiaoshuang 383bfabae8 1
continuous-integration/drone/push Build is passing
2026-07-10 16:59:18 +08:00
wangxiaoshuang 196ed7f993 完全随机ir上传下载页面及预览页屏蔽受试者编号和项目编号
continuous-integration/drone/push Build is passing
2026-07-10 16:53:41 +08:00
caiyiling 70cc0027cd 受试者状态更改弹窗移除结束访视日期
continuous-integration/drone/push Build is passing
2026-07-10 16:21:44 +08:00
caiyiling 975b7d39a7 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2026-07-10 15:06:24 +08:00
caiyiling 21bcd1fddb 只有顺序阅片的时显示是否复制后续任务阅片表单 2026-07-10 15:05:39 +08:00
wangxiaoshuang 04bbde8583 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web 2026-07-10 13:55:06 +08:00
wangxiaoshuang f3c4bedbfd 趋势图提示红色改为蓝色 2026-07-10 13:54:54 +08:00
caiyiling 835aedc800 1
continuous-integration/drone/push Build is passing
2026-07-10 13:40:57 +08:00
caiyiling 9026b1d7fd 自定义标准完全随机阅片更改
continuous-integration/drone/push Build is passing
2026-07-10 13:12:44 +08:00
caiyiling b8f96efa66 列表调整
continuous-integration/drone/push Build is passing
2026-07-10 11:18:05 +08:00
caiyiling 4c4f68dbd0 完全随机阅片规则更改
continuous-integration/drone/push Build is passing
2026-07-10 11:12:55 +08:00
caiyiling 11c56d2f7a 1
continuous-integration/drone/push Build is passing
2026-07-09 16:52:58 +08:00
caiyiling a72521304e Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2026-07-09 16:33:50 +08:00
caiyiling 8baf6cb88f IR阅片模块相关页面添加任务名称搜索条件 2026-07-09 16:33:14 +08:00
wangxiaoshuang 71e04c3bf1 中心调研移动端确认弹框样式修改
continuous-integration/drone/push Build is passing
2026-07-09 15:17:44 +08:00
caiyiling 1af9b48622 完全随机IR阅片列表及阅片页面更改
continuous-integration/drone/push Build is pending
2026-07-09 14:17:02 +08:00
wangxiaoshuang 447b74fa55 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web
continuous-integration/drone/push Build is passing
2026-07-09 13:29:51 +08:00
wangxiaoshuang c633fbcf87 外层问题配置为表格问题不显示时阅片时不展示表格 2026-07-09 13:29:45 +08:00
caiyiling 1cc57ad1d6 修复保存申请重阅表单异常问题
continuous-integration/drone/push Build is passing
2026-07-09 09:30:19 +08:00
caiyiling f282fdfabc 是否复制后续表单去除标准限制
continuous-integration/drone/push Build is passing
2026-07-08 16:46:50 +08:00
caiyiling d77c6ecf03 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2026-07-08 16:04:27 +08:00
caiyiling 1db75cf4f7 MRI-PDFF报告页数据更改 2026-07-08 16:03:55 +08:00
wangxiaoshuang 7bc70bfd6c 【中心调研】中心调研表手机扫描二维码进入时,同pc一样也需要增加验证。上传文件功能也要能正常使用
continuous-integration/drone/push Build is passing
2026-07-07 17:35:33 +08:00
wangxiaoshuang 69ba30e5a9 【趋势图】趋势图访视结果后增加查看按钮,可以查看已阅结果
continuous-integration/drone/push Build is passing
2026-07-07 10:25:32 +08:00
wangxiaoshuang 18482ddaa9 【中心调研】选择项目方案号生成验证码,项目方案号中有特殊符号,生成的验证码中未显示特殊符号
continuous-integration/drone/push Build is passing
2026-07-07 09:38:14 +08:00
caiyiling 14e2afcfee Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is pending
2026-07-06 17:22:30 +08:00
caiyiling 39dadbbf47 受试者任务状态变更原因更改 2026-07-06 17:20:59 +08:00
wangxiaoshuang d0ba340fea 去除分割上传文件按钮
continuous-integration/drone/push Build is passing
2026-07-06 11:44:37 +08:00
31 changed files with 1606 additions and 892 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ NODE_ENV = 'prod'
VUE_APP_BASE_PATH = '/' VUE_APP_BASE_PATH = '/'
# onlyoffice地址 # onlyoffice地址
VUE_APP_ONLYOFFICE_URL = "https://office.extimaging.com" VUE_APP_ONLYOFFICE_URL = "https://office.rayplus.net"
# 是否开启登陆限制 true:是 false:否 # 是否开启登陆限制 true:是 false:否
VUE_APP_LOGIN_FOR_PERMISSION = true VUE_APP_LOGIN_FOR_PERMISSION = true
+1 -1
View File
@@ -10,7 +10,7 @@
<meta http-equiv="Pragma" content="no-cache"> <meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-control" content="no-store,no-cache,must-revalidate"> <meta http-equiv="Cache-control" content="no-store,no-cache,must-revalidate">
<meta http-equiv="Cache" content="no-cache"> <meta http-equiv="Cache" content="no-cache">
<title>EIC lmaging Trial Management System</title> <title>RPC lmaging Trial Management System</title>
</head> </head>
<body> <body>
+2 -2
View File
@@ -31,7 +31,7 @@
<div class="title-container" style="display: flex;padding-top:180px;justify-content: flex-start;height: 100%;box-sizing: border-box"> <div class="title-container" style="display: flex;padding-top:180px;justify-content: flex-start;height: 100%;box-sizing: border-box">
<!-- IRC Management System --> <!-- IRC Management System -->
<!-- <div class="title" style="text-align: center;font-size: 28px;margin-top: 100px;padding-right: 120px"></div>--> <!-- <div class="title" style="text-align: center;font-size: 28px;margin-top: 100px;padding-right: 120px"></div>-->
<!-- <div class="title" v-show="false">EIC lmaging Trial Management System</div>--> <!-- <div class="title" v-show="false">RPC lmaging Trial Management System</div>-->
<div style="color: #0a84ff;text-align: left;font-size: 28px"> <div style="color: #0a84ff;text-align: left;font-size: 28px">
{{message}} {{message}}
</div> </div>
@@ -63,7 +63,7 @@
<div style="margin: 0 auto;width: 600px;line-height: 28px;text-align: center" > <div style="margin: 0 auto;width: 600px;line-height: 28px;text-align: center" >
<h1 style="text-align: center;margin-bottom: 20px">关于</h1> <h1 style="text-align: center;margin-bottom: 20px">关于</h1>
<p style="margin-bottom: 20px"> <p style="margin-bottom: 20px">
EIC lmaging Trial Management System RPC lmaging Trial Management System
</p> </p>
<p style="margin-bottom: 20px"> <p style="margin-bottom: 20px">
V1.3.0.001 V1.3.0.001
+1 -1
View File
@@ -31,7 +31,7 @@
<div class="title-container" style="display: flex;padding-top:180px;justify-content: flex-start;height: 100%;box-sizing: border-box"> <div class="title-container" style="display: flex;padding-top:180px;justify-content: flex-start;height: 100%;box-sizing: border-box">
<!-- IRC Management System --> <!-- IRC Management System -->
<!-- <div class="title" style="text-align: center;font-size: 28px;margin-top: 100px;padding-right: 120px"></div>--> <!-- <div class="title" style="text-align: center;font-size: 28px;margin-top: 100px;padding-right: 120px"></div>-->
<!-- <div class="title" v-show="false">EIC lmaging Trial Management System</div>--> <!-- <div class="title" v-show="false">RPC lmaging Trial Management System</div>-->
<div style="color: #0a84ff;text-align: left;font-size: 28px"> <div style="color: #0a84ff;text-align: left;font-size: 28px">
{{message}} {{message}}
</div> </div>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
View File
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 225 KiB

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 353 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 65 KiB

+1315 -792
View File
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 99 KiB

+2 -2
View File
@@ -1608,7 +1608,7 @@ Enroll: Enrolled Confirmation`,
'trials:notice:table:appendix': `Attachment`, 'trials:notice:table:appendix': `Attachment`,
'trials:notice:table:isRead': `Readed`, 'trials:notice:table:isRead': `Readed`,
'trials:notice:action:detail': `Details`, 'trials:notice:action:detail': `Details`,
'login:title:system': `EIC lmaging Trial Management System`, 'login:title:system': `RPC lmaging Trial Management System`,
'login:form:userName': `User ID`, 'login:form:userName': `User ID`,
'login:form:password': `Password`, 'login:form:password': `Password`,
'login:button:login': `Login`, 'login:button:login': `Login`,
@@ -1672,7 +1672,7 @@ Enroll: Enrolled Confirmation`,
'trials:tab:trials': `My Trials`, 'trials:tab:trials': `My Trials`,
'trials:trials:title:back': `Return`, 'trials:trials:title:back': `Return`,
'trials:trials:title:backTrialList': `Return to trial list`, 'trials:trials:title:backTrialList': `Return to trial list`,
'trials:trials:title:eics': `EIC lmaging Trial Management System`, 'trials:trials:title:eics': `RPC lmaging Trial Management System`,
'trials:tab:reading': `Reads`, 'trials:tab:reading': `Reads`,
'trials:tab:pendingReadingTasks': `Pending`, 'trials:tab:pendingReadingTasks': `Pending`,
'trials:pendingReadingTasks:table:subjectCode': `Subject ID`, 'trials:pendingReadingTasks:table:subjectCode': `Subject ID`,
+7 -2
View File
@@ -92,8 +92,13 @@ router.beforeEach(async (to, from, next) => {
await store.dispatch('user/getUserInfo') await store.dispatch('user/getUserInfo')
const accessRoutes = await store.dispatch('permission/generateRoutes') const accessRoutes = await store.dispatch('permission/generateRoutes')
resetRouter() resetRouter()
router.addRoutes(accessRoutes) if (accessRoutes.length > 0) {
next({ ...to, replace: true }) router.addRoutes(accessRoutes)
next({ ...to, replace: true })
} else {
next()
}
} catch (error) { } catch (error) {
console.log(error) console.log(error)
// 删除token并进入登录页面以重新登录 // 删除token并进入登录页面以重新登录
+1 -1
View File
@@ -1,7 +1,7 @@
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
module.exports = { module.exports = {
title: 'HASC lmaging Trial Management System', title: 'RPC lmaging Trial Management System',
/** /**
* @type {boolean} true | false * @type {boolean} true | false
+1 -1
View File
@@ -1,6 +1,6 @@
import defaultSettings from '@/settings' import defaultSettings from '@/settings'
const title = defaultSettings.title || 'HASC lmaging Trial Management System' const title = defaultSettings.title || 'RPC lmaging Trial Management System'
export default function getPageTitle(pageTitle) { export default function getPageTitle(pageTitle) {
if (pageTitle) { if (pageTitle) {
+3
View File
@@ -118,6 +118,9 @@ service.interceptors.response.use(
if (res.IsSuccess) { if (res.IsSuccess) {
return Promise.resolve(res) return Promise.resolve(res)
} else if (res.IsSuccess === false) { } else if (res.IsSuccess === false) {
if (res.Code === -4) {
return Promise.resolve(res)
}
if (res.Code !== 5) { if (res.Code !== 5) {
MessageBox.confirm(res.ErrorMessage, { MessageBox.confirm(res.ErrorMessage, {
type: 'warning', type: 'warning',
+1 -1
View File
@@ -2,7 +2,7 @@
<div class="dashboard"> <div class="dashboard">
<div class="dashboard-header"> <div class="dashboard-header">
<h1> <h1>
<a href="#" @click="handleTitleClick">GRR Real-Time HASC Information</a> <a href="#" @click="handleTitleClick">GRR Real-Time IRC Information</a>
</h1> </h1>
<div> <div>
+1 -1
View File
@@ -1,7 +1,7 @@
<template> <template>
<div class="dashboard"> <div class="dashboard">
<div class="dashboard-header"> <div class="dashboard-header">
<!-- <h1>Extimaging Real-Time HASC Information</h1> --> <!-- <h1>Extimaging Real-Time IRC Information</h1> -->
<div> <div>
<span>{{ currentTime }}</span> <span>{{ currentTime }}</span>
</div> </div>
+16 -15
View File
@@ -5,27 +5,28 @@
</div> </div>
<div class="login-body"> <div class="login-body">
<div class="login-l"> <div class="login-l">
<!-- <div class="login-logo"> <div class="login-logo">
<img v-if="language === 'zh'" src="@/assets/zzlogo2.png" alt="" /> <img v-if="language === 'zh'" src="@/assets/zzlogo2.png" alt="" />
<img v-else-if="NODE_ENV === 'usa'" src="@/assets/zzlogo-usa.png" alt="" class="usa-logo" /> <img v-else-if="NODE_ENV === 'usa'" src="@/assets/zzlogo-usa.png" alt="" class="usa-logo" />
<img v-else src="@/assets/zzlogo2.png" alt="" /> <img v-else src="@/assets/zzlogo2.png" alt="" />
</div> --> </div>
<div :class="{ <div :class="{
'login-image': true, 'login-image': true,
'login-image-usa': true, 'login-image-usa': true,
}"> }">
<!-- <svg-icon icon-class="login-bg" style="width: 90%; height: 90%" /> --> <svg-icon icon-class="login-bg" style="width: 90%; height: 90%" />
<img src="@/assets/login-bg.png" style=" height: 80%" /> <!-- <img src="@/assets/login-bg.png" v-else /> -->
</div> </div>
</div> </div>
<div class="login-r"> <div class="login-r">
<div class="title-container"> <div class="title-container">
<!-- HASC Management System --> <!-- IRC Management System -->
<div v-if="NODE_ENV === 'usa'"> <div v-if="NODE_ENV === 'usa'">
<svg-icon icon-class="login-logo" style="width: 300px; height: 94px" /> <svg-icon icon-class="login-logo" style="width: 300px; height: 94px" />
</div> </div>
<div class="title" v-else> <div class="title" v-else>
<img src="@/assets/system.png" alt="" :style="{ height: isEN ? '50px' : '55px' }" /> <img src="@/assets/system.png" alt=""
:style="{ width: isEN ? '180px' : '200px', height: isEN ? '60px' : '65px' }" />
<div :style="`font-size:${isEN ? '28px' : '35px'}`">{{ $t('login:title:system') }}</div> <div :style="`font-size:${isEN ? '28px' : '35px'}`">{{ $t('login:title:system') }}</div>
</div> </div>
</div> </div>
@@ -110,14 +111,14 @@
</div> </div>
</div> </div>
<div v-if="language === 'zh'" class="login-footer"> <div v-if="language === 'zh'" class="login-footer">
<span>Copyright © {{ new Date().getFullYear() }} 上海禾安枢信息科技有限公司 <span>Copyright © {{ new Date().getFullYear() }} 睿佳(武汉)软件科技有限公司
版权所有</span> 版权所有</span>
<span> | </span> <span> | </span>
<!-- <a target="_blank" href="https://beian.miit.gov.cn/"> <a target="_blank" href="https://beian.miit.gov.cn/">
<span> ICP备2021037850-2 </span> <span> ICP备16002609号 </span>
</a> </a>
<span> | </span> <!-- <span> | </span> -->
<a target="_blank" href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=31011002005859"> <!-- <a target="_blank" href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=31011002005859">
<img src="@/assets/filing.png" /> <img src="@/assets/filing.png" />
<span>沪公网安备 31011002005859号</span> <span>沪公网安备 31011002005859号</span>
</a> --> </a> -->
@@ -161,16 +162,16 @@
V{{ $version.IsEnv_US ? $version.Version_US : $version.Version }} V{{ $version.IsEnv_US ? $version.Version_US : $version.Version }}
</p> </p>
<p style="margin-bottom: 20px" v-if="language === 'zh'"> <p style="margin-bottom: 20px" v-if="language === 'zh'">
Copyright © {{ new Date().getFullYear() }} 上海禾安枢信息科技有限公司 Copyright © {{ new Date().getFullYear() }} 睿佳(武汉)软件科技有限公司
版权所有 版权所有
</p> </p>
<p style="margin-bottom: 20px" v-else-if="NODE_ENV === 'usa'"> <p style="margin-bottom: 20px" v-else-if="NODE_ENV === 'usa'">
© {{ new Date().getFullYear() }} Elevate Imaging Inc. © {{ new Date().getFullYear() }} Elevate Imaging Inc.
</p> </p>
<!-- <p style="margin-bottom: 20px" v-else> <p style="margin-bottom: 20px" v-else>
Copyright © {{ new Date().getFullYear() }} Shanghai Extensive Imaging Copyright © {{ new Date().getFullYear() }} Shanghai Extensive Imaging
Inc. Inc.
</p> --> </p>
<!-- <div style="margin-bottom: 20px" v-if="NODE_ENV === 'usa'"> <!-- <div style="margin-bottom: 20px" v-if="NODE_ENV === 'usa'">
<img style="width: 180px" src="@/assets/zzlogo-usa.png" alt="" /> <img style="width: 180px" src="@/assets/zzlogo-usa.png" alt="" />
</div> </div>
@@ -681,7 +682,7 @@ $light_gray: #606266;
left: 50px; left: 50px;
img { img {
height: 40px; height: 70px;
} }
.usa-logo { .usa-logo {
+1 -1
View File
@@ -1,7 +1,7 @@
<template> <template>
<div class="share-image-container"> <div class="share-image-container">
<div class="share-image-banner"> <div class="share-image-banner">
<h2 style="text-align:center;">HASC Management System</h2> <h2 style="text-align:center;">IRC Management System</h2>
<el-card shadow="hover"> <el-card shadow="hover">
<h4>请输入提取码</h4> <h4>请输入提取码</h4>
<el-form ref="validateForm" :inline="true" :rules="rules" :model="form"> <el-form ref="validateForm" :inline="true" :rules="rules" :model="form">
+2 -2
View File
@@ -302,13 +302,13 @@ export default {
// 发件人邮箱地址 // 发件人邮箱地址
"FromEmail": "test@extimaging.com", "FromEmail": "test@extimaging.com",
// 发件人显示名称 // 发件人显示名称
"FromName": "Test HASC Imaging System", "FromName": "Test IRC Imaging System",
//SMTP授权码 //SMTP授权码
"AuthorizationCode": "SHzyyl2021", "AuthorizationCode": "SHzyyl2021",
//系统对外访问地址 //系统对外访问地址
"SiteUrl": "http://irc.test.extimaging.com/login", "SiteUrl": "http://irc.test.extimaging.com/login",
//系统简称-致性核查使用 //系统简称-致性核查使用
"SystemShortName": "HASC", "SystemShortName": "IRC",
// 组织英文名称-添加用户默认值 // 组织英文名称-添加用户默认值
"OrganizationName": "ExtImaging", "OrganizationName": "ExtImaging",
// 组织中文名称 // 组织中文名称
+18 -18
View File
@@ -178,7 +178,7 @@ export default {
updateUser(this.user) updateUser(this.user)
.then((res) => { .then((res) => {
this.isDisabled = false this.isDisabled = false
this.$message.success('Updated successfully') this.$message.success(this.$t("common:message:updatedSuccessfully"))
}) })
.catch(() => { .catch(() => {
this.isDisabled = false this.isDisabled = false
@@ -190,7 +190,7 @@ export default {
this.user.Id = res.Result.Id this.user.Id = res.Result.Id
this.user.UserCode = res.Result.UserCode this.user.UserCode = res.Result.UserCode
this.$emit('getUserId', res.Result.Id) this.$emit('getUserId', res.Result.Id)
this.$message.success('Added successfully') this.$message.success(this.$t("common:message:addedSuccessfully"))
this.$router.push({ path: '/system/user/list' }) this.$router.push({ path: '/system/user/list' })
}) })
.catch(() => { .catch(() => {
@@ -308,63 +308,63 @@ export default {
UserWorkLanguage: [ UserWorkLanguage: [
{ {
required: true, required: true,
message: 'Please Select', message: this.$t("common:ruleMessage:select"),
trigger: ['blur', 'change'], trigger: ['blur', 'change'],
}, },
], ],
Roles: [ Roles: [
{ {
required: true, required: true,
message: 'Please Select', message: this.$t("common:ruleMessage:select"),
trigger: ['blur', 'change'], trigger: ['blur', 'change'],
}, },
], ],
IsZhiZhun: [ IsZhiZhun: [
{ {
required: true, required: true,
message: 'Please Select', message: this.$t("common:ruleMessage:select"),
trigger: ['blur', 'change'], trigger: ['blur', 'change'],
}, },
], ],
OrganizationName: [ OrganizationName: [
{ required: true, message: 'Please specify', trigger: 'blur' }, { required: true, message: this.$t("common:ruleMessage:specify"), trigger: 'blur' },
], ],
LastName: [ LastName: [
{ required: true, message: 'Please specify', trigger: 'blur' }, { required: true, message: this.$t("common:ruleMessage:specify"), trigger: 'blur' },
{ max: 50, message: 'The maximum length is 50' }, { max: 50, message: this.$t("trials:researchForm:formRule:maxLength") },
], ],
FirstName: [ FirstName: [
{ required: true, message: 'Please specify', trigger: 'blur' }, { required: true, message: this.$t("common:ruleMessage:specify"), trigger: 'blur' },
{ max: 50, message: 'The maximum length is 50' }, { max: 50, message: this.$t("trials:researchForm:formRule:maxLength") },
], ],
Phone: [ Phone: [
{ {
max: 20, max: 20,
min: 7, min: 7,
message: 'The length is 7 to 20', message: this.$t("system:userInfo:ruleMessage:length7to20"),
trigger: ['blur'], trigger: ['blur'],
}, },
], ],
EMail: [ EMail: [
{ {
required: true, required: true,
message: 'Please input the email address', message: this.$t("common:ruleMessage:specify"),
trigger: 'blur', trigger: 'blur',
}, },
{ {
// type: 'email', // type: 'email',
pattern: new RegExp(this.$reg().EmailRegexStr), pattern: new RegExp(this.$reg().EmailRegexStr),
message: 'Please input the correct email address', message: this.$t("trials:site:ruleMessage:correctEmail"),
trigger: ['blur'], trigger: ['blur'],
}, },
{ max: 50, message: 'The maximum length is 50' }, { max: 50, message: this.$t("trials:researchForm:formRule:maxLength") },
], ],
Sex: [{ required: true, message: 'Please specify', trigger: 'blur' }], Sex: [{ required: true, message: this.$t("common:ruleMessage:specify"), trigger: 'blur' }],
Status: [ Status: [
{ required: true, message: 'Please specify', trigger: 'blur' }, { required: true, message: this.$t("common:ruleMessage:specify"), trigger: 'blur' },
], ],
DepartmentName: [{ max: 50, message: 'The maximum length is 50' }], DepartmentName: [{ max: 50, message: this.$t("trials:researchForm:formRule:maxLength") }],
PositionName: [{ max: 50, message: 'The maximum length is 50' }], PositionName: [{ max: 50, message: this.$t("trials:researchForm:formRule:maxLength") }],
}, },
userTypeOptions: [], userTypeOptions: [],
isDisabled: false, isDisabled: false,
@@ -619,6 +619,14 @@ export default {
} }
} }
::v-deep .el-dialog.cd-dialog-container {
.el-input.is-disabled .el-input__inner {
background-color: rgb(245, 247, 250);
color: #666;
border: 1px solid #dcdfe6;
}
}
} }
::v-deep .dialog-container { ::v-deep .dialog-container {
@@ -12,7 +12,9 @@
{ required: true, message: $t('common:ruleMessage:select'), trigger: 'blur' } { required: true, message: $t('common:ruleMessage:select'), trigger: 'blur' }
]"> ]">
<el-select v-model="fusionForm.studyId" clearable @change="handleStudyIdChange"> <el-select v-model="fusionForm.studyId" clearable @change="handleStudyIdChange">
<el-option v-for="item in studyList" :key="item.StudyId" :label="item.StudyCode" :value="item.StudyId" /> <el-option v-for="item in studyList" :key="item.StudyId"
:label="taskInfo.IsReadingTaskViewInOrder !== 0 ? item.StudyCode : `${item.Modalities}(${item.SeriesCount})`"
:value="item.StudyId" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 融合图像 --> <!-- 融合图像 -->
@@ -111,10 +113,12 @@ export default {
ctSeries: [], ctSeries: [],
petSeries: [], petSeries: [],
petctWindow: null, petctWindow: null,
digitPlaces: 2 digitPlaces: 2,
taskInfo: {}
} }
}, },
mounted() { mounted() {
this.taskInfo = JSON.parse(sessionStorage.getItem('taskInfo'))
var digitPlaces = Number(localStorage.getItem('digitPlaces')) var digitPlaces = Number(localStorage.getItem('digitPlaces'))
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
this.initForm() this.initForm()
@@ -187,6 +187,7 @@ export default {
originalMarkers: [], originalMarkers: [],
markers: { top: '', right: '', bottom: '', left: '' }, markers: { top: '', right: '', bottom: '', left: '' },
playClipState: false, playClipState: false,
clipFramesPerSecond: null,
wwwcIdx: 2, wwwcIdx: 2,
presetName: '', presetName: '',
volumeId: null, volumeId: null,
@@ -625,6 +626,22 @@ export default {
} }
}, },
syncViewportStaticState() {
const renderingEngine = getRenderingEngine(this.renderingEngineId)
if (!renderingEngine) return
const viewport = renderingEngine.getViewport(this.viewportId)
if (!viewport) return
this.getOrientationMarker()
const toolGroup =
cornerstoneTools.ToolGroupManager.getToolGroupForViewport(
this.viewportId,
this.renderingEngineId
) || cornerstoneTools.ToolGroupManager.getToolGroup(this.viewportId)
if (toolGroup) {
toolGroup.setToolEnabled('ScaleOverlay')
}
},
setFullScreen(index) { setFullScreen(index) {
setTimeout(() => { setTimeout(() => {
const renderingEngine = getRenderingEngine(this.renderingEngineId) const renderingEngine = getRenderingEngine(this.renderingEngineId)
@@ -727,14 +744,33 @@ export default {
} }
}, },
toggleClipPlay(isPlay, framesPerSecond) { toggleClipPlay(isPlay, framesPerSecond) {
this.playClipState = isPlay
const renderingEngine = getRenderingEngine(this.renderingEngineId) const renderingEngine = getRenderingEngine(this.renderingEngineId)
if (!renderingEngine) return
const viewport = renderingEngine.getViewport(this.viewportId) const viewport = renderingEngine.getViewport(this.viewportId)
if (!viewport?.element) return
const parsedFramesPerSecond = Number(framesPerSecond)
const nextFramesPerSecond = Number.isFinite(parsedFramesPerSecond)
? parsedFramesPerSecond
: (this.clipFramesPerSecond || 15)
const isSameSpeedWhilePlaying = this.playClipState &&
isPlay &&
this.clipFramesPerSecond === nextFramesPerSecond
if (isPlay) { if (isPlay) {
cornerstoneTools.utilities.cine.playClip(viewport.element, { framesPerSecond, loop: true }) if (isSameSpeedWhilePlaying) return
cornerstoneTools.utilities.cine.playClip(viewport.element, {
framesPerSecond: nextFramesPerSecond,
loop: true,
waitForRendered: 1
})
this.clipFramesPerSecond = nextFramesPerSecond
this.playClipState = true
} else { } else {
cornerstoneTools.utilities.cine.stopClip(viewport.element) cornerstoneTools.utilities.cine.stopClip(viewport.element)
this.clipFramesPerSecond = null
this.playClipState = false
} }
}, },
scrollPage(type) { scrollPage(type) {
@@ -1125,6 +1161,7 @@ export default {
} }
viewport.render() viewport.render()
this.syncViewportStaticState()
if (this.currentVoiUpper > 0) { if (this.currentVoiUpper > 0) {
this.voiChange(this.currentVoiUpper) this.voiChange(this.currentVoiUpper)
} }
@@ -284,7 +284,7 @@
<svg-icon icon-class="lastframe" class="svg-icon" /> <svg-icon icon-class="lastframe" class="svg-icon" />
</div> </div>
<select v-model="fps" :title="$t('trials:dicom-show:speed')" class="select-wrapper" <select v-model="fps" :title="$t('trials:dicom-show:speed')" class="select-wrapper"
:disabled="clipPlaying"> @change="handleClipFpsChange">
<!-- 默认值 --> <!-- 默认值 -->
<option :value="5">5</option> <option :value="5">5</option>
<option :value="10">10</option> <option :value="10">10</option>
@@ -1221,12 +1221,7 @@ export default {
this.selectArr.push(item.VisitTaskId) this.selectArr.push(item.VisitTaskId)
} }
if (item.IsCurrentTask) { if (item.IsCurrentTask) {
this.markedSeriesIds = [] this.syncMarkedSeriesIds(annotations)
annotations.map(i => {
if (i.MeasureData && i.MeasureData.seriesId) {
this.markedSeriesIds.push(i.MeasureData.seriesId)
}
})
} }
} }
@@ -2052,7 +2047,7 @@ export default {
// this.$refs['ecrf'].setAnnotation({ annotation, toolName: annotation.metadata.toolName }) // this.$refs['ecrf'].setAnnotation({ annotation, toolName: annotation.metadata.toolName })
this.$refs[`ecrf_${this.lastViewportTaskId}`][0].setAnnotation({ annotation, toolName: annotation.metadata.toolName }) this.$refs[`ecrf_${this.lastViewportTaskId}`][0].setAnnotation({ annotation, toolName: annotation.metadata.toolName })
this.markedSeriesIds.push(series.Id) this.syncMarkedSeriesIdsFromState(series.TaskInfo.VisitTaskId)
} }
this.setToolsPassive() this.setToolsPassive()
@@ -2087,16 +2082,14 @@ export default {
throw errorMsg throw errorMsg
} }
if (annotation.visitTaskId === this.taskInfo.VisitTaskId && annotation.seriesId) { if (annotation.visitTaskId === this.taskInfo.VisitTaskId && annotation.seriesId) {
const index = this.markedSeriesIds.indexOf(annotation.seriesId) this.syncMarkedSeriesIdsFromState(annotation.visitTaskId)
if (index !== -1) {
this.markedSeriesIds.splice(index, 1)
}
} else { } else {
const errorMsg = { message: 'annotation Not allowed to operate' } const errorMsg = { message: 'annotation Not allowed to operate' }
throw errorMsg throw errorMsg
} }
} catch (e) { } catch (e) {
cornerstoneTools.annotation.state.addAnnotation(annotation) cornerstoneTools.annotation.state.addAnnotation(annotation)
this.syncMarkedSeriesIdsFromState(annotation.visitTaskId)
const renderingEngine = getRenderingEngine(renderingEngineId) const renderingEngine = getRenderingEngine(renderingEngineId)
for (let i = 0; i < this.cells.length; i++) { for (let i = 0; i < this.cells.length; i++) {
const viewportId = `${this.viewportKey}-${i}` const viewportId = `${this.viewportKey}-${i}`
@@ -2133,7 +2126,7 @@ export default {
annotation.sliceThickness = series.SliceThickness annotation.sliceThickness = series.SliceThickness
annotation.numberOfFrames = isNaN(parseInt(params.frame)) ? null : parseInt(params.frame) annotation.numberOfFrames = isNaN(parseInt(params.frame)) ? null : parseInt(params.frame)
annotation.markTool = annotation.metadata.toolName annotation.markTool = annotation.metadata.toolName
this.markedSeriesIds.push(series.Id) this.syncMarkedSeriesIdsFromState(series.TaskInfo.VisitTaskId)
const operateStateEnum = this.$refs[`ecrf_${this.taskInfo.VisitTaskId}`][0].operateStateEnum const operateStateEnum = this.$refs[`ecrf_${this.taskInfo.VisitTaskId}`][0].operateStateEnum
const markName = await this.customPrompt(!this.isNumber(operateStateEnum)) const markName = await this.customPrompt(!this.isNumber(operateStateEnum))
@@ -2275,10 +2268,7 @@ export default {
if (!res.IsSuccess) throw '' if (!res.IsSuccess) throw ''
} }
} }
const index = this.markedSeriesIds.indexOf(annotation.seriesId) this.syncMarkedSeriesIdsFromState(annotation.visitTaskId)
if (index !== -1) {
this.markedSeriesIds.splice(index, 1)
}
const renderingEngine = getRenderingEngine(renderingEngineId) const renderingEngine = getRenderingEngine(renderingEngineId)
for (let i = 0; i < this.cells.length; i++) { for (let i = 0; i < this.cells.length; i++) {
const viewportId = `${this.viewportKey}-${i}` const viewportId = `${this.viewportKey}-${i}`
@@ -2291,6 +2281,7 @@ export default {
} }
} catch (e) { } catch (e) {
cornerstoneTools.annotation.state.addAnnotation(annotation) cornerstoneTools.annotation.state.addAnnotation(annotation)
this.syncMarkedSeriesIdsFromState(annotation.visitTaskId)
const renderingEngine = getRenderingEngine(renderingEngineId) const renderingEngine = getRenderingEngine(renderingEngineId)
for (let i = 0; i < this.cells.length; i++) { for (let i = 0; i < this.cells.length; i++) {
const viewportId = `${this.viewportKey}-${i}` const viewportId = `${this.viewportKey}-${i}`
@@ -2367,6 +2358,22 @@ export default {
this.$set(this.visitTaskList[taskIdx], 'Annotations', annotations) this.$set(this.visitTaskList[taskIdx], 'Annotations', annotations)
this.$set(this.visitTaskList[taskIdx], 'AnnotationUIDs', annotationUIDs) this.$set(this.visitTaskList[taskIdx], 'AnnotationUIDs', annotationUIDs)
}, },
collectMarkedSeriesIds(list = []) {
return [...new Set(
list
.map(item => item?.MeasureData?.seriesId || item?.seriesId)
.filter(Boolean)
)]
},
syncMarkedSeriesIds(list = []) {
this.markedSeriesIds = this.collectMarkedSeriesIds(list)
},
syncMarkedSeriesIdsFromState(visitTaskId = this.taskInfo?.VisitTaskId) {
const annotations = cornerstoneTools.annotation.state.getAllAnnotations().filter(item => {
return item.visitTaskId === visitTaskId && item.seriesId
})
this.syncMarkedSeriesIds(annotations)
},
async resetAnnotations(visitTaskId) { async resetAnnotations(visitTaskId) {
if (this.readingTaskState === 2) return if (this.readingTaskState === 2) return
const taskIdx = this.visitTaskList.findIndex(i => i.VisitTaskId === visitTaskId) const taskIdx = this.visitTaskList.findIndex(i => i.VisitTaskId === visitTaskId)
@@ -2401,9 +2408,9 @@ export default {
if (i.MeasureData) { if (i.MeasureData) {
const annotation = i.MeasureData const annotation = i.MeasureData
cornerstoneTools.annotation.state.addAnnotation(annotation) cornerstoneTools.annotation.state.addAnnotation(annotation)
this.markedSeriesIds.push(annotation.seriesId)
} }
}) })
this.syncMarkedSeriesIds(annotations)
const renderingEngine = getRenderingEngine(renderingEngineId) const renderingEngine = getRenderingEngine(renderingEngineId)
for (let i = 0; i < this.cells.length; i++) { for (let i = 0; i < this.cells.length; i++) {
const viewportId = `${this.viewportKey}-${i}` const viewportId = `${this.viewportKey}-${i}`
@@ -3415,6 +3422,15 @@ export default {
this.clipPlaying = !this.clipPlaying this.clipPlaying = !this.clipPlaying
this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].toggleClipPlay(isPlay, this.fps) this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].toggleClipPlay(isPlay, this.fps)
}, },
handleClipFpsChange() {
if (!this.clipPlaying) return
const activeViewportRef = this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`]
const activeViewport = activeViewportRef && activeViewportRef[0]
if (!activeViewport || typeof activeViewport.toggleClipPlay !== 'function') return
activeViewport.toggleClipPlay(true, this.fps)
},
// //
async getWwcTpl() { async getWwcTpl() {
try { try {
@@ -4037,8 +4053,10 @@ export default {
} }
} }
} }
this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].setSeriesInfo(series, true) if (!this.isActiveViewportAtMeasureLocation(obj.annotation)) {
this.$refs[series.TaskInfo.VisitTaskId][0].setSeriesActive(series.StudyIndex, series.SeriesIndex) this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].setSeriesInfo(series, true)
this.$refs[series.TaskInfo.VisitTaskId][0].setSeriesActive(series.StudyIndex, series.SeriesIndex)
}
setTimeout(async () => { setTimeout(async () => {
const divForDownloadViewport = document.querySelector( const divForDownloadViewport = document.querySelector(
`div[data-viewport-uid="${this.viewportKey}-${this.activeViewportIndex}"]` `div[data-viewport-uid="${this.viewportKey}-${this.activeViewportIndex}"]`
@@ -4049,9 +4067,48 @@ export default {
}, 200) }, 200)
} }
}, },
getMeasureImageLocation(measureData = {}) {
const referencedImageId = measureData?.metadata?.referencedImageId
const referencedImageParams = referencedImageId ? this.getInstanceInfo(referencedImageId) : {}
return {
visitTaskId: measureData.visitTaskId,
studyId: measureData.studyId || measureData.StudyId,
seriesId: measureData.seriesId || measureData.SeriesId,
instanceId: measureData.instanceId || measureData.InstanceId || referencedImageParams.instanceId || null,
frame: measureData.numberOfFrames ?? measureData.NumberOfFrames ?? referencedImageParams.frame
}
},
getActiveViewportImageLocation() {
const viewportRef = this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`]?.[0]
const currentSeries = viewportRef?.series
if (!currentSeries) return null
const renderingEngine = getRenderingEngine(renderingEngineId)
const viewport = renderingEngine?.getViewport(`${this.viewportKey}-${this.activeViewportIndex}`)
const currentImageId = viewport?.getCurrentImageId?.()
const currentImageParams = currentImageId ? this.getInstanceInfo(currentImageId) : {}
return {
visitTaskId: currentSeries.TaskInfo?.VisitTaskId,
studyId: currentSeries.StudyId,
seriesId: currentSeries.Id,
instanceId: currentImageParams.instanceId || null,
frame: currentImageParams.frame
}
},
isActiveViewportAtMeasureLocation(measureData) {
const targetLocation = this.getMeasureImageLocation(measureData)
const currentLocation = this.getActiveViewportImageLocation()
if (!currentLocation || !targetLocation.seriesId) return false
if (targetLocation.visitTaskId && currentLocation.visitTaskId !== targetLocation.visitTaskId) return false
if (targetLocation.studyId && currentLocation.studyId !== targetLocation.studyId) return false
if (currentLocation.seriesId !== targetLocation.seriesId) return false
if (targetLocation.instanceId && currentLocation.instanceId !== targetLocation.instanceId) return false
return currentLocation.frame === targetLocation.frame
},
async getScreenshots(measureData, callback) { async getScreenshots(measureData, callback) {
if (measureData) { if (measureData) {
await this.imageLocation(measureData) if (!this.isActiveViewportAtMeasureLocation(measureData.annotation)) {
await this.imageLocation(measureData)
}
const divForDownloadViewport = document.querySelector( const divForDownloadViewport = document.querySelector(
`div[data-viewport-uid="${this.viewportKey}-${this.activeViewportIndex}"]` `div[data-viewport-uid="${this.viewportKey}-${this.activeViewportIndex}"]`
) )
@@ -4,7 +4,8 @@
<el-form-item :label="$t('segment:form:label:studyName')" prop="taskBlindName"> <el-form-item :label="$t('segment:form:label:studyName')" prop="taskBlindName">
<el-select v-model="form.studyId" clearable @change="(e) => handleChange(e, 'study')" <el-select v-model="form.studyId" clearable @change="(e) => handleChange(e, 'study')"
@clear="(e) => handleClear(e, 'study')"> @clear="(e) => handleClear(e, 'study')">
<el-option v-for="item in studyList" :key="item.StudyId" :label="item.StudyCode" <el-option v-for="item in studyList" :key="item.StudyId"
:label="taskInfo.IsReadingTaskViewInOrder !== 0 ? item.StudyCode : `${item.Modalities}(${item.SeriesCount})`"
:value="item.StudyId" /> :value="item.StudyId" />
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -87,12 +88,13 @@ export default {
}, trigger: ['blur', 'change'] }, trigger: ['blur', 'change']
} }
] ]
} },
taskInfo: {}
} }
}, },
// mounted() { mounted() {
// this.init() this.taskInfo = JSON.parse(sessionStorage.getItem('taskInfo'))
// }, },
methods: { methods: {
setSeries(series) { setSeries(series) {
this.series = series this.series = series
@@ -150,6 +150,8 @@ export default {
originalMarkers: [], originalMarkers: [],
markers: { top: '', right: '', bottom: '', left: '' }, markers: { top: '', right: '', bottom: '', left: '' },
playClipState: false, playClipState: false,
clipFramesPerSecond: null,
toggleClipPlayTimer: null,
wwwcIdx: 2, wwwcIdx: 2,
loading: false, loading: false,
forceFitToWindow: false, forceFitToWindow: false,
@@ -169,6 +171,10 @@ export default {
this.resizeObserver.unobserve(this.element) this.resizeObserver.unobserve(this.element)
this.resizeObserver.disconnect() this.resizeObserver.disconnect()
} }
if (this.toggleClipPlayTimer) {
clearInterval(this.toggleClipPlayTimer)
this.toggleClipPlayTimer = null
}
}, },
methods: { methods: {
initViewport() { initViewport() {
@@ -210,12 +216,11 @@ export default {
this.imageInfo.imageOrientationPatient = imagePlaneModule.imageOrientationPatient this.imageInfo.imageOrientationPatient = imagePlaneModule.imageOrientationPatient
this.imageInfo.imagePositionPatient = imagePlaneModule.imagePositionPatient this.imageInfo.imagePositionPatient = imagePlaneModule.imagePositionPatient
this.imageInfo.location = imagePlaneModule.sliceLocation this.imageInfo.location = imagePlaneModule.sliceLocation
// this.imageInfo.wwwc = `${Math.round(detail.image.windowWidth)}/${Math.round(detail.image.windowCenter)}`
this.getOrientationMarker() this.getOrientationMarker()
this.$emit('renderAnnotations', this.series) const toolGroup = cornerstoneTools.ToolGroupManager.getToolGroup(this.viewportId)
const toolGroupId = this.viewportId if (toolGroup) {
const toolGroup = cornerstoneTools.ToolGroupManager.getToolGroup(toolGroupId) toolGroup.setToolEnabled('ScaleOverlay')
toolGroup.setToolEnabled('ScaleOverlay') }
}, },
imageRendered(e) { imageRendered(e) {
const renderingEngine = getRenderingEngine(this.renderingEngineId) const renderingEngine = getRenderingEngine(this.renderingEngineId)
@@ -312,14 +317,61 @@ export default {
} }
}, },
toggleClipPlay(isPlay, framesPerSecond) { toggleClipPlay(isPlay, framesPerSecond) {
this.playClipState = isPlay
const renderingEngine = getRenderingEngine(this.renderingEngineId) const renderingEngine = getRenderingEngine(this.renderingEngineId)
if (!renderingEngine) return
const viewport = renderingEngine.getViewport(this.viewportId) const viewport = renderingEngine.getViewport(this.viewportId)
if (!viewport?.element) return
const parsedFramesPerSecond = Number(framesPerSecond)
const nextFramesPerSecond = Number.isFinite(parsedFramesPerSecond)
? parsedFramesPerSecond
: (this.clipFramesPerSecond || 15)
const isSameSpeedWhilePlaying = this.playClipState &&
isPlay &&
this.clipFramesPerSecond === nextFramesPerSecond
if (isPlay) { if (isPlay) {
cornerstoneTools.utilities.cine.playClip(viewport.element, { framesPerSecond, loop: true }) if (isSameSpeedWhilePlaying) return
cornerstoneTools.utilities.cine.stopClip(viewport.element)
if (this.toggleClipPlayTimer) {
clearInterval(this.toggleClipPlayTimer)
this.toggleClipPlayTimer = null
}
const frameInterval = Math.max(16, Math.round(1000 / nextFramesPerSecond))
this.toggleClipPlayTimer = setInterval(() => {
const imageIds = viewport.getImageIds()
if (!imageIds?.length) return
let index = viewport.getCurrentImageIdIndex() + 1
if (index > imageIds.length - 1) {
index = 0
}
csUtils.jumpToSlice(viewport.element, {
imageIndex: index,
debounceLoading: false
})
}, frameInterval)
this.clipFramesPerSecond = nextFramesPerSecond
this.playClipState = true
} else { } else {
cornerstoneTools.utilities.cine.stopClip(viewport.element) cornerstoneTools.utilities.cine.stopClip(viewport.element)
if (this.toggleClipPlayTimer) {
clearInterval(this.toggleClipPlayTimer)
this.toggleClipPlayTimer = null
}
this.clipFramesPerSecond = null
this.playClipState = false
}
},
syncViewportStaticState() {
this.getOrientationMarker()
this.$emit('renderAnnotations', this.series)
const toolGroup = cornerstoneTools.ToolGroupManager.getToolGroup(this.viewportId)
if (toolGroup) {
toolGroup.setToolEnabled('ScaleOverlay')
} }
}, },
scrollPage(type) { scrollPage(type) {
@@ -339,7 +391,13 @@ export default {
} }
// viewport.setImageIdIndex(newImageIdIndex) // viewport.setImageIdIndex(newImageIdIndex)
csUtils.jumpToSlice(viewport.element, { imageIndex: newImageIdIndex }) csUtils.jumpToSlice(viewport.element, { imageIndex: newImageIdIndex })
if (this.toggleClipPlayTimer) {
clearInterval(this.toggleClipPlayTimer)
this.toggleClipPlayTimer = null
}
cornerstoneTools.utilities.cine.stopClip(viewport.element) cornerstoneTools.utilities.cine.stopClip(viewport.element)
this.clipFramesPerSecond = null
this.playClipState = false
}, },
setZoom(ratio) { setZoom(ratio) {
const renderingEngine = getRenderingEngine(this.renderingEngineId) const renderingEngine = getRenderingEngine(this.renderingEngineId)
@@ -432,6 +490,7 @@ export default {
} }
this.prefetchMetadataInformation(obj.ImageIds, obj.Modality) this.prefetchMetadataInformation(obj.ImageIds, obj.Modality)
await viewport.setStack(this.series.Stack, obj.SliceIndex) await viewport.setStack(this.series.Stack, obj.SliceIndex)
this.syncViewportStaticState()
viewport.render() viewport.render()
} catch (e) { } catch (e) {
@@ -251,7 +251,7 @@ export default {
return i return i
}) })
this.$set(this.visitTaskList[taskIdx], 'Annotations', annotations) this.$set(this.visitTaskList[taskIdx], 'Annotations', annotations)
this.$refs[visitTaskId][0].initCurrentMaredFiles() this.$refs[visitTaskId][0].initCurrentMaredFiles(annotations)
this.$refs.fileViewer.resetAnnotations({ annotations, visitTaskId }) this.$refs.fileViewer.resetAnnotations({ annotations, visitTaskId })
}, },
setReadingTaskState(state) { setReadingTaskState(state) {
@@ -97,6 +97,7 @@ export default {
this.taskInfo = JSON.parse(localStorage.getItem('taskInfo')) this.taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
this.BodyPart.Bodypart = await this.$getBodyPart(this.$route.query.trialId) this.BodyPart.Bodypart = await this.$getBodyPart(this.$route.query.trialId)
this.studyList = this.decorateStudyList(this.visitTaskInfo.StudyList || []) this.studyList = this.decorateStudyList(this.visitTaskInfo.StudyList || [])
this.initCurrentMaredFiles(this.visitTaskInfo.Annotations)
if (this.studyList.length === 0) return if (this.studyList.length === 0) return
this.$nextTick(() => { this.$nextTick(() => {
this.activeStudy(this.studyList[0].Id) this.activeStudy(this.studyList[0].Id)
@@ -110,8 +111,26 @@ export default {
}) })
} }
}, },
'visitTaskInfo.Annotations': {
handler(annotations) {
this.initCurrentMaredFiles(annotations)
},
deep: true
}
}, },
methods: { methods: {
buildCurrentMarkedFiles(annotations = []) {
return annotations.reduce((result, item) => {
const fileId = item?.NoneDicomFileId
if (!fileId) return result
if (!Object.hasOwn(result, fileId)) {
result[fileId] = { count: 1 }
} else {
result[fileId].count++
}
return result
}, {})
},
decorateStudyList(studyList = []) { decorateStudyList(studyList = []) {
return studyList.map(study => ({ return studyList.map(study => ({
...study, ...study,
@@ -204,6 +223,9 @@ export default {
if (type === 'remove') { if (type === 'remove') {
if (Object.hasOwn(this.currentMarkedFiles, fileId)) { if (Object.hasOwn(this.currentMarkedFiles, fileId)) {
this.currentMarkedFiles[fileId].count-- this.currentMarkedFiles[fileId].count--
if (this.currentMarkedFiles[fileId].count <= 0) {
this.$delete(this.currentMarkedFiles, fileId)
}
} }
} else if (type === 'add') { } else if (type === 'add') {
if (!Object.hasOwn(this.currentMarkedFiles, fileId)) { if (!Object.hasOwn(this.currentMarkedFiles, fileId)) {
@@ -214,15 +236,8 @@ export default {
} }
}, },
initCurrentMaredFiles() { initCurrentMaredFiles(annotations = this.visitTaskInfo.Annotations || []) {
this.currentMarkedFiles = {} this.currentMarkedFiles = this.buildCurrentMarkedFiles(annotations)
this.visitTaskInfo.Annotations.map(i => {
if (!Object.hasOwn(this.currentMarkedFiles, i.NoneDicomFileId)) {
this.$set(this.currentMarkedFiles, i.NoneDicomFileId, { count: 1 })
} else {
this.currentMarkedFiles[i.NoneDicomFileId].count++
}
})
}, },
} }
} }
@@ -120,7 +120,7 @@ export default {
// if (this.VUE_APP_OSS_PATH === '/uat/dist') { // if (this.VUE_APP_OSS_PATH === '/uat/dist') {
// this.form = { // this.form = {
// EmailFromEmail: 'uat@extimaging.com', // EmailFromEmail: 'uat@extimaging.com',
// EmailFromName: 'Uat EIC lmaging Trial Management System', // EmailFromName: 'Uat RPC lmaging Trial Management System',
// EmailAuthorizationCode: 'SHzyyl2021', // EmailAuthorizationCode: 'SHzyyl2021',
// EmailSMTPServerAddress: 'smtp.qiye.aliyun.com', // EmailSMTPServerAddress: 'smtp.qiye.aliyun.com',
// EmailSMTPServerPort: 465, // EmailSMTPServerPort: 465,
@@ -130,7 +130,7 @@ export default {
// if (this.VUE_APP_OSS_PATH === '/test/dist') { // if (this.VUE_APP_OSS_PATH === '/test/dist') {
// this.form = { // this.form = {
// EmailFromEmail: 'test@extimaging.com', // EmailFromEmail: 'test@extimaging.com',
// EmailFromName: 'Test EIC lmaging Trial Management System', // EmailFromName: 'Test RPC lmaging Trial Management System',
// EmailAuthorizationCode: 'SHzyyl2021', // EmailAuthorizationCode: 'SHzyyl2021',
// EmailSMTPServerAddress: 'smtp.qiye.aliyun.com', // EmailSMTPServerAddress: 'smtp.qiye.aliyun.com',
// EmailSMTPServerPort: 465, // EmailSMTPServerPort: 465,
+1 -1
View File
@@ -11,7 +11,7 @@ const webpack = require('webpack')
const defaultSettings = require('./src/settings.js') const defaultSettings = require('./src/settings.js')
const moment = require('moment') const moment = require('moment')
var distDate = moment(new Date()).format('YYYY-MM-DD') var distDate = moment(new Date()).format('YYYY-MM-DD')
const name = process.env.NODE_ENV === 'usa' ? 'Imaging Trial Management System' : defaultSettings.title || 'HASC lmaging Trial Management System' // page title const name = process.env.NODE_ENV === 'usa' ? 'Imaging Trial Management System' : defaultSettings.title || 'RPC lmaging Trial Management System' // page title
// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin // const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
module.exports = defineConfig({ module.exports = defineConfig({