Compare commits

..

No commits in common. "main" and "v1.13.0" have entirely different histories.

303 changed files with 27401 additions and 38795 deletions

23
package-lock.json generated
View File

@ -48,7 +48,6 @@
"nprogress": "^0.2.0",
"path-to-regexp": "^0.1.10",
"pdfobject": "^2.3.0",
"prismjs": "^1.30.0",
"qrcodejs2": "^0.0.2",
"screenfull": "^6.0.2",
"sortablejs": "^1.15.5",
@ -63,7 +62,6 @@
"vue-count-to": "^1.0.13",
"vue-demi": "^0.14.10",
"vue-i18n": "^8.28.2",
"vue-prism-editor": "^1.3.0",
"vue-puzzle-vcode": "^1.1.10",
"vue-router": "^3.0.6",
"vue-seamless-scroll": "^1.1.23",
@ -18046,15 +18044,6 @@
"renderkid": "^3.0.0"
}
},
"node_modules/prismjs": {
"version": "1.30.0",
"resolved": "https://registry.npmmirror.com/prismjs/-/prismjs-1.30.0.tgz",
"integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmmirror.com/process/-/process-0.11.10.tgz",
@ -23008,18 +22997,6 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/vue-prism-editor": {
"version": "1.3.0",
"resolved": "https://registry.npmmirror.com/vue-prism-editor/-/vue-prism-editor-1.3.0.tgz",
"integrity": "sha512-54RfgtMGRMNr9484zKMOZs1wyLDR6EfFylzE2QrMCD9alCvXyYYcS0vX8oUHh+6pMUu6ts59uSN9cHglpU2NRQ==",
"license": "MIT",
"engines": {
"node": ">=10"
},
"peerDependencies": {
"vue": "^2.6.11"
}
},
"node_modules/vue-puzzle-vcode": {
"version": "1.1.10",
"resolved": "https://registry.npmmirror.com/vue-puzzle-vcode/-/vue-puzzle-vcode-1.1.10.tgz",

View File

@ -20,7 +20,6 @@
"@cornerstonejs/core": "^2.19.7",
"@cornerstonejs/dicom-image-loader": "^2.19.7",
"@cornerstonejs/tools": "^2.19.7",
"@fingerprintjs/fingerprintjs": "^4.6.2",
"@icr/polyseg-wasm": "^0.4.0",
"@microsoft/signalr": "^8.0.7",
"@riophae/vue-treeselect": "^0.4.0",
@ -55,7 +54,6 @@
"nprogress": "^0.2.0",
"path-to-regexp": "^0.1.10",
"pdfobject": "^2.3.0",
"prismjs": "^1.30.0",
"qrcodejs2": "^0.0.2",
"screenfull": "^6.0.2",
"sortablejs": "^1.15.5",
@ -70,7 +68,6 @@
"vue-count-to": "^1.0.13",
"vue-demi": "^0.14.10",
"vue-i18n": "^8.28.2",
"vue-prism-editor": "^1.3.0",
"vue-puzzle-vcode": "^1.1.10",
"vue-router": "^3.0.6",
"vue-seamless-scroll": "^1.1.23",

View File

@ -11,14 +11,6 @@
<meta http-equiv="Cache-control" content="no-store,no-cache,must-revalidate">
<meta http-equiv="Cache" content="no-cache">
<title><%= webpackConfig.name %></title>
<style>
.customPromptTip {
position: absolute;
left: 0;
bottom: -100px;
z-index: 99999;
}
</style>
<% if (eval(process.env.VUE_APP_LOGIN_FOR_PERMISSION)) { %>
<script>
window.zzSessionStorage = {

Binary file not shown.

View File

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

View File

@ -281,13 +281,7 @@ export function getCommonDocumentList(param) {
data: param
})
}
export function getCommonDocument(param) {
return request({
url: `/CommonDocument/getCommonDocument`,
method: 'get',
params: param
})
}
export function addOrUpdateCommonDocument(param) {
return request({
url: `/CommonDocument/addOrUpdateCommonDocument`,
@ -424,11 +418,10 @@ export function addOrUpdateBasicDic(param) {
})
}
export function getDictionaryChildList(data) {
export function getDictionaryChildList(id) {
return request({
url: `/Dictionary/getChildList`,
method: 'post',
data
url: `/Dictionary/getChildList/${id}`,
method: 'get'
})
}
@ -1364,113 +1357,3 @@ export function deleteAttachment(data) {
data
})
}
// 项目文档-获取历史记录列表
export function getTrialHistoryRecordFileList(data) {
return request({
url: `/TrialHistoryRecordFile/getTrialHistoryRecordFileList`,
method: 'post',
data
})
}
// 项目文档-新增/修改历史记录
export function addOrUpdateTrialHistoryRecordFile(data) {
return request({
url: `/TrialHistoryRecordFile/addOrUpdateTrialHistoryRecordFile`,
method: 'post',
data
})
}
// 项目文档-批量新增历史记录
export function batchAddTrialHistoryRecordFile(data) {
return request({
url: `/TrialHistoryRecordFile/batchAddTrialHistoryRecordFile`,
method: 'post',
data
})
}
// 项目文档-删除历史记录
export function deleteTrialHistoryRecordFile(id) {
return request({
url: `/TrialHistoryRecordFile/deleteTrialHistoryRecordFile/${id}`,
method: 'delete',
})
}
// 邮件管理-批量修改邮件
export function batchUpdateEmail(data) {
return request({
url: `/EmailNoticeConfig/batchUpdateEmail`,
method: 'post',
data
})
}
// 隐私政策和用户协议-获取列表
export function getUserAgreementList(data) {
return request({
url: `/UserAgreement/getUserAgreementList`,
method: 'post',
data
})
}
// 隐私政策和用户协议-设置当前版本
export function setCurrentVersion(data) {
return request({
url: `/UserAgreement/setCurrentVersion`,
method: 'post',
data
})
}
// 隐私政策和用户协议-新增或修改
export function addOrUpdateUserAgreement(data) {
return request({
url: `/UserAgreement/addOrUpdateUserAgreement`,
method: 'post',
data
})
}
// 隐私政策和用户协议-删除
export function deleteUserAgreement(id) {
return request({
url: `/UserAgreement/deleteUserAgreement/${id}`,
method: 'delete',
})
}
// 隐私政策和用户协议-详情
export function getUserAgreementById(data) {
return request({
url: `/UserAgreement/getUserAgreementById`,
method: 'post',
data
})
}
// 隐私政策和用户协议-当前版本
export function getCurrentVersionUserAgreements(data) {
return request({
url: `/UserAgreement/getCurrentVersionUserAgreements`,
method: 'post',
data
})
}
// 获取系统阅片关键点文件列表
export function getSystemCriterionKeyFileList(data) {
return request({
url: `/SystemCriterionKeyFile/getSystemCriterionKeyFileList`,
method: 'post',
data
})
}
// 新增/修改系统阅片关键点文件
export function addOrUpdateSystemCriterionKeyFile(data) {
return request({
url: `/SystemCriterionKeyFile/addOrUpdateSystemCriterionKeyFile`,
method: 'post',
data
})
}
// 删除系统阅片关键点文件
export function deleteSystemCriterionKeyFile(systemCriterionKeyFileId) {
return request({
url: `/SystemCriterionKeyFile/deleteSystemCriterionKeyFile/${systemCriterionKeyFileId}`,
method: 'delete'
})
}

View File

@ -45,19 +45,10 @@ export function changeFrontAuditSort(param) {
})
}
export function getModuleTypeDescriptionList(params) {
export function getModuleTypeDescriptionList(param) {
return request({
url: `/FrontAuditConfig/getModuleTypeDescriptionList`,
method: 'get',
params
})
}
export function getModuleTypeList(data) {
return request({
url: `/FrontAuditConfig/getModuleTypeList`,
method: 'post',
data
url: `${param === '' ? '/FrontAuditConfig/getModuleTypeDescriptionList' : '/FrontAuditConfig/getModuleTypeDescriptionList?moduleTypeId=' + param}`,
method: 'get'
})
}

View File

@ -72,14 +72,7 @@ export function getReadingTaskList_Export(param) {
data: param
})
}
export function getTrialVisitImageStatList_Export(param) {
return requestDownload({
url: '/ExcelExport/getTrialVisitImageStatList_Export',
method: 'post',
responseType: 'blob',
data: param
})
}
export function getReReadingTaskList_Export(param) {
return requestDownload({
url: '/ExcelExport/getReReadingTaskList_Export',
@ -203,15 +196,6 @@ export function qCVisitList_Export(data) {
data
})
}
// 导出影像指控问题和答案
export function GetTrialQCQuestionAnserList_Export(data) {
return requestDownload({
url: `/ExcelExport/GetTrialQCQuestionAnserList_Export`,
responseType: 'blob',
method: 'post',
data
})
}
// 导出下载记录
export function getTrialDownloadList_Export(data) {
return requestDownload({
@ -239,14 +223,6 @@ export function getPatientList_Export(data) {
data
})
}
export function getTumor_CDISC_Export(data) {
return requestDownload({
url: `/IVUS_OCTExport/getTumor_CDISC_Export`,
responseType: 'blob',
method: 'post',
data
})
}
export function getCommonEvaluationList_Export(data) {
return requestDownload({
url: `/ExcelExport/getCommonEvaluationList_Export`,
@ -263,14 +239,6 @@ export function getCommonJudgeRatioList_Export(data) {
data
})
}
export function getTumor_CDISC_Export(data) {
return requestDownload({
url: `/Tumor_CDISC_Export/getTumor_CDISC_Export`,
responseType: 'blob',
method: 'post',
data
})
}
// 导出国际化列表
export function GetInternationalizationList_Export(data) {
return requestDownload({
@ -298,21 +266,3 @@ export function GetEmailNoticeConfigList_Export(data) {
data
})
}
// 导出重传审批
export function GetImageBackList_Export(data) {
return requestDownload({
url: `/ExcelExport/GetImageBackList_Export`,
responseType: 'blob',
method: 'post',
data
})
}
// 导出医学审核配置
export function GetReadingMedicineSystemQuestionList_Export(data) {
return requestDownload({
url: `/ExcelExport/GetReadingMedicineSystemQuestionList_Export`,
responseType: 'blob',
method: 'post',
data
})
}

View File

@ -45,11 +45,10 @@ export function saveImageLabelList(param) {
})
}
export function getStudyInfo(studyId, params) {
export function getStudyInfo(studyId) {
return request({
url: `/Study/item/${studyId}`,
method: 'get',
params
method: 'get'
})
}
export function getSeriesList(url) {
@ -286,36 +285,4 @@ export function deleteSingleTableQuestionMark(param, type) {
})
}
// 阅片导入
export function readingImport(param) {
return request({
url: `/ReadingCalculate/readingImport`,
method: 'post',
data: param
})
}
// 非dicom阅片保存标记
export function saveAnswerAndBindingNoneDicomMark(param) {
return request({
url: `/ReadingImageTask/saveAnswerAndBindingNoneDicomMark`,
method: 'post',
data: param
})
}
// 非dicom按比例修改答案
export function changePlottingScaleChangeAnswer(param) {
return request({
url: `/ReadingImageTask/changePlottingScaleChangeAnswer`,
method: 'post',
data: param
})
}
// 阅片获取图表数据
export function getReportsChartData(param) {
return request({
url: `/ReadingImageTask/getReportsChartData`,
method: 'post',
data: param
})
}

View File

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

View File

@ -1203,13 +1203,7 @@ export function getConsistencyVerificationList(param) {
data: param
})
}
export function getConsistencyCheckFileList(param) {
return request({
url: `/QCList/getConsistencyCheckFileList`,
method: 'post',
data: param
})
}
export function getCheckChallengeDialogList(subjectVisitId) {
return request({
url: `/QCList/getCheckChallengeDialogList/${subjectVisitId}`,
@ -1262,11 +1256,11 @@ export function getCRCVisitChallengeAndDialog(subjectVisitId, trialQCProcess) {
})
}
export function uploadVisitCheckExcel(trialId, file, isFullCheck = false) {
export function uploadVisitCheckExcel(trialId, file) {
const formData = new FormData()
formData.append('file', file)
return request({
url: `/QCOperation/UploadVisitCheckExcel/${trialId}?isFullCheck=${isFullCheck}`,
url: `/QCOperation/UploadVisitCheckExcel/${trialId}`,
method: 'post',
data: formData
})
@ -1411,9 +1405,9 @@ export function getForwardList(param) {
})
}
export function getNoneDicomStudyList(subjectVisitId, sudyId = '', isFilterZip = false, visitTaskId = '', IsReading = false, isImageSegmentLabel = '') {
export function getNoneDicomStudyList(subjectVisitId, sudyId = '', isFilterZip = false, visitTaskId = '', IsReading = false) {
return request({
url: `/NoneDicomStudy/getNoneDicomStudyList?isImageSegmentLabel=${isImageSegmentLabel}&subjectVisitId=${subjectVisitId}&nonedicomStudyId=${sudyId}&isFilterZip=${isFilterZip}&visitTaskId=${visitTaskId}&IsReading=${IsReading}`,
url: `/NoneDicomStudy/getNoneDicomStudyList?subjectVisitId=${subjectVisitId}&nonedicomStudyId=${sudyId}&isFilterZip=${isFilterZip}&visitTaskId=${visitTaskId}&IsReading=${IsReading}`,
method: 'get'
})
}
@ -2839,13 +2833,7 @@ export function getSplitPPdSum(param) {
data: param
})
}
export function getSplitPPdSumNoPet(param) {
return request({
url: `/LuganoWithoutPETCalculate/getSplitPPdSum`,
method: 'post',
data: param
})
}
export function submitDicomVisitTask(param) {
return request({
url: `/Inspection/ReadingImageTask/SubmitDicomVisitTask`,
@ -2884,13 +2872,7 @@ export function getIsSuvMaxLesion(param) {
data: param
})
}
export function getIsSuvMaxLesionNoPet(param) {
return request({
url: `/LuganoWithoutPETCalculate/getIsSuvMaxLesion`,
method: 'post',
data: param
})
}
export function getCanChooseNotMerge(param) {
return request({
url: `/LuganoCalculate/getCanChooseNotMerge`,
@ -2898,13 +2880,6 @@ export function getCanChooseNotMerge(param) {
data: param
})
}
export function getCanChooseNotMergeNoPet(param) {
return request({
url: `/LuganoWithoutPETCalculate/getCanChooseNotMerge`,
method: 'post',
data: param
})
}
export function saveTaskQuestion(saveQuestionType, param) {
return request({
url: `/SaveTaskQuestion/${saveQuestionType}`,
@ -3069,13 +3044,7 @@ export function readClinicalData(param) {
data: param
})
}
export function viewstudyPart(param) {
return request({
url: `/ReadingImageTask/viewstudyPart`,
method: 'post',
data: param
})
}
export function getCustomQuestionPreview(param) {
return request({
url: `/ReadingQuestion/getCustomQuestionPreview`,
@ -3628,24 +3597,13 @@ export function getSplenicState(visitTaskId, spleenLength) {
method: 'post'
})
}
export function getSplenicStateNoPet(visitTaskId, spleenLength) {
return request({
url: `/LuganoWithoutPETCalculate/getSplenicState?visitTaskId=${visitTaskId}&spleenLength=${spleenLength}`,
method: 'post'
})
}
export function getSplenicVerify(visitTaskId) {
return request({
url: `/LuganoCalculate/getSplenicVerify?visitTaskId=${visitTaskId}`,
method: 'post'
})
}
export function getSplenicVerifyNoPet(visitTaskId) {
return request({
url: `/LuganoWithoutPETCalculate/getSplenicVerify?visitTaskId=${visitTaskId}`,
method: 'post'
})
}
export function uploadTrialSiteSurveyUser(trialId, baseUrl, routeUrl, param) {
return request({
url: `/TrialSiteSurvey/UploadTrialSiteSurveyUser?trialId=${trialId}&baseUrl=${baseUrl}&routeUrl=${routeUrl}`,
@ -4172,246 +4130,4 @@ export function addFolder(data) {
method: 'post',
data
})
}
// 配置-项目文档发布
export function publishTrialDocument(data) {
return request({
url: `/TrialDocument/publishTrialDocument`,
method: 'post',
data
})
}
// 配置-获取项目文档附件列表
export function getTrialDocumentAttachmentList(data) {
return request({
url: `/TrialDocument/getTrialDocumentAttachmentList`,
method: 'post',
data
})
}
// 配置-新增或修改项目文档附件
export function addOrUpdateTrialDocumentAttachment(data) {
return request({
url: `/TrialDocument/addOrUpdateTrialDocumentAttachment`,
method: 'post',
data
})
}
// 配置-删除项目文档附件
export function deleteTrialDocumentAttachment(data) {
return request({
url: `/TrialDocument/deleteTrialDocumentAttachment/${data}`,
method: 'delete',
})
}
// 配置-获取稽查管理列表
export function getTrialShowInspection(data) {
return request({
url: `/Inspection/getTrialShowInspection`,
method: 'post',
data
})
}
// 配置-设置稽查管理配置
export function setTrialShowInspection(data) {
return request({
url: `/Inspection/setTrialShowInspection`,
method: 'post',
data
})
}
// 影像汇总-获取列表
export function getTrialVisitImageStatList(data) {
return request({
url: `/DownloadAndUpload/getTrialVisitImageStatList`,
method: 'post',
data
})
}
// 影像汇总-获取统计
export function getTrialVisitImageStatInfo(params) {
return request({
url: `/DownloadAndUpload/getTrialVisitImageStatInfo`,
method: 'get',
params
})
}
// 影像汇总-影像下载
export function getExportSubjectVisitImageList(data) {
return request({
url: `/DownloadAndUpload/getExportSubjectVisitImageList`,
method: 'post',
data
})
}
// 影像质控-更正dicom
export function updateDicomStudyInfo(data) {
return request({
url: `/Inspection/QCOperation/UpdateDicomStudyInfo`,
method: 'post',
data
})
}
// 影像质控-更正非dicom
export function updateNoneDicomStudy(data) {
return request({
url: `/Inspection/NoneDicomStudy/UpdateNoneDicomStudy`,
method: 'post',
data
})
}
// 阅片单元-获取访视计划
export function getVisitStage(data) {
return request({
url: `/VisitPlan/getVisitStage`,
method: 'post',
data
})
}
// 稽查管理-列表
export function getAuditRecordList(data) {
return request({
url: `/AuditDocument/getAuditRecordList`,
method: 'post',
data
})
}
// 稽查管理-列表(EA)
export function getAuditRecordSelectList(data) {
return request({
url: `/AuditDocument/getAuditRecordSelectList`,
method: 'post',
data
})
}
// 稽查管理-列表新增修改
export function addOrUpdateAuditRecord(data) {
return request({
url: `/AuditDocument/addOrUpdateAuditRecord`,
method: 'post',
data
})
}
// 稽查管理-文档授权
export function setAuditRecordPermission(data) {
return request({
url: `/AuditDocument/setAuditRecordPermission`,
method: 'post',
data
})
}
// 稽查管理-人员管理
export function addOrDeleteAuditRecordUser(data) {
return request({
url: `/AuditDocument/addOrDeleteAuditRecordUser`,
method: 'put',
data
})
}
// 稽查管理-删除
export function deleteAuditRecord(auditRecordId) {
return request({
url: `/AuditDocument/deleteAuditRecord/${auditRecordId}`,
method: 'delete'
})
}
// 核对中心人员发送邮件
export function sendCheckSiteSurveyUserEmail(data) {
return request({
url: `/TrialSiteSurvey/sendCheckSiteSurveyUserEmail`,
method: 'post',
data
})
}
// 更新中心人员发送邮件
export function sendUpdateSiteSurveyUserEmail(data) {
return request({
url: `/TrialSiteSurvey/sendUpdateSiteSurveyUserEmail`,
method: 'post',
data
})
}
// 更新中心人员发送邮件
export function getTrialSiteLatestSurvey(params) {
return request({
url: `/TrialSiteSurvey/getTrialSiteLatestSurvey`,
method: 'get',
params
})
}
// 阅片期计划列表
export function getReadModulePageList(data) {
return request({
url: `/ReadModule/getReadModulePageList`,
method: 'post',
data
})
}
// 移除阅片期
export function setBatchRemoveReadingPlan(data) {
return request({
url: `/ReadingPeriodSet/setBatchRemoveReadingPlan`,
method: 'post',
data
})
}
// 更新项目额外json配置
export function updateTrialExtralConfig(params, data) {
return request({
url: `/TrialConfig/updateTrialExtralConfig`,
method: 'put',
params,
data
})
}
// 获取项目标准阅片关键点列表
export function getTrialCriterionKeyFileList(data) {
return request({
url: `/TrialCriterionKeyFile/getTrialCriterionKeyFileList`,
method: 'post',
data
})
}
// 设置已阅读关键文件
export function setReadKeyFile(data) {
return request({
url: `/ReadingImageTask/setReadKeyFile`,
method: 'post',
data
})
}
// 项目报表-访视完成度
export function getTrialVisitFinishedStatList(data) {
return request({
url: `/TrialStat/getTrialVisitFinishedStatList`,
method: 'post',
data
})
}
// 项目报表-质疑统计表
export function getTrialQuestionStatList(data) {
return request({
url: `/TrialStat/getTrialQuestionStatList`,
method: 'post',
data
})
}
// 项目报表-疗效统计表
export function getTrialEfficacyEvaluationStatList(data) {
return request({
url: `/TrialStat/getTrialEfficacyEvaluationStatList`,
method: 'post',
data
})
}
// 靶段标注列表
export function getTrialSubjectVisitMarkList(data) {
return request({
url: `/DownloadAndUpload/getTrialSubjectVisitMarkList`,
method: 'post',
data
})
}

View File

@ -459,9 +459,9 @@ export function setMedicalReviewInvalid(params) {
})
}
export function getTrialCriterionList(trialId, isRandom = false) {
export function getTrialCriterionList(trialId) {
return request({
url: `/VisitTask/getTrialCriterionList?TrialId=${trialId}&isRandom=${isRandom}`,
url: `/VisitTask/getTrialCriterionList?TrialId=${trialId}`,
method: 'get'
})
}
@ -487,4 +487,4 @@ export function setRandomTaskOrder(data) {
method: 'post',
data
})
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 55 KiB

View File

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

View File

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

View File

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

View File

@ -1,7 +1,15 @@
<template>
<div id="canvas" ref="canvas" v-loading="loading" :element-loading-text="NSTip"
element-loading-background="rgba(0, 0, 0, 0.8)" style="width:100%;height:100%;position:relative;"
class="cornerstone-element" @contextmenu.prevent="onContextmenu" @mouseup="sliderMouseup">
<div
id="canvas"
ref="canvas"
v-loading="loading"
:element-loading-text="NSTip"
element-loading-background="rgba(0, 0, 0, 0.8)"
style="width:100%;height:100%;position:relative;"
class="cornerstone-element"
@contextmenu.prevent="onContextmenu"
@mouseup="sliderMouseup"
>
<div v-show="dicomInfo.series" class="info-series">
<div>Series #{{ dicomInfo.series }}</div>
<div>Image #{{ dicomInfo.frame }}</div>
@ -18,11 +26,9 @@
<div v-show="dicomInfo.location">Location {{ dicomInfo.location }}mm</div> -->
<!-- <div v-show="toolState.clipPlaying">FPS {{ dicomInfo.fps }}</div> -->
<div v-show="mousePosition.mo">
Pos: {{ mousePosition.x ? mousePosition.x.toFixed(0) : '' }}, {{ mousePosition.y ? mousePosition.y.toFixed(0) :
'' }}
Pos: {{ mousePosition.x?mousePosition.x.toFixed(0):'' }}, {{ mousePosition.y?mousePosition.y.toFixed(0):'' }}
</div>
<div
v-if="(dicomInfo.modality === 'CT' || dicomInfo.modality === 'DR' || dicomInfo.modality === 'CR') && mousePosition.mo">
<div v-if="(dicomInfo.modality === 'CT' || dicomInfo.modality === 'DR' || dicomInfo.modality === 'CR') && mousePosition.mo">
HU: {{ mousePosition.mo }}
</div>
<div v-else-if="(dicomInfo.modality === 'PT' && mousePosition.suv)">
@ -39,8 +45,6 @@
</div>
<div class="info-subject">
<div v-if="series.subjectCode">{{ series.subjectCode }}</div>
<div v-if="series.visitName">{{ series.visitName }}</div>
<div>{{ stack.description }}</div>
<!-- <div>{{ dicomInfo.hospital }}</div> -->
<!-- <div v-show="dicomInfo.pid">{{ dicomInfo.pid }}</div> -->
@ -49,12 +53,8 @@
<!-- <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"
@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 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;">
{{ markers.top }}
@ -81,8 +81,15 @@
<!-- <div v-show="stack.firstImageLoading" class="load-indicator">
Loading Series #{{ stack.seriesNumber }}...
</div>-->
<el-dialog v-if="dcmTag.visible" :visible.sync="dcmTag.visible" :close-on-click-modal="false" :title="dcmTag.title"
width="1000px" custom-class="base-dialog-wrapper" append-to-body>
<el-dialog
v-if="dcmTag.visible"
:visible.sync="dcmTag.visible"
:close-on-click-modal="false"
:title="dcmTag.title"
width="1000px"
custom-class="base-dialog-wrapper"
append-to-body
>
<dicom-tags :image-id="stack.imageIds[stack.currentImageIdIndex]" @close="dcmTag.visible = false" />
</el-dialog>
</div>
@ -116,7 +123,7 @@ export default {
components: { DicomTags },
computed: {
NSTip() {
return `${this.$store.state.trials.downloadSize}, NS: ${this.$store.state.trials.downloadTip}`
return `${this.$store.state.trials.uploadSize}, NS: ${this.$store.state.trials.uploadTip}`
}
},
data() {
@ -261,9 +268,9 @@ export default {
)
if (!toolAlreadyAddedToElement) {
if (toolName === 'RectangleRoi') {
cornerstoneTools.addToolForElement(element, apiTool, { configuration: { showMinMax: true, showStatsText: true } })
cornerstoneTools.addToolForElement(element, apiTool, { configuration: { showMinMax: true, showStatsText: true}})
} else if (toolName === 'EllipticalRoi') {
cornerstoneTools.addToolForElement(element, apiTool, { configuration: { showMinMax: true } })
cornerstoneTools.addToolForElement(element, apiTool, { configuration: { showMinMax: true}})
} else {
cornerstoneTools.addToolForElement(element, apiTool)
}
@ -326,7 +333,7 @@ export default {
// cornerstoneTools.addStackStateManager(this.canvas, ['stack', 'stackPrefetch', 'playClip'])
cornerstoneTools.addToolState(this.canvas, 'stack', this.stack)
// cornerstoneTools.stackPrefetch.enable(this.canvas)
cornerstone.updateImage(element, true)
cornerstone.updateImage(element, true)
// cornerstoneTools.stackPrefetch.setConfiguration({ maxImagesToPrefetch: Infinity,
// preserveExistingPool: true })
// cornerstoneTools.stackPrefetch.enable(this.canvas)
@ -366,8 +373,9 @@ export default {
data.string('x00080030')
)
this.dicomInfo.series = data.string('x00200011')
this.dicomInfo.frame = `${this.stack.currentImageIdIndex + 1}/${this.stack.imageIds.length
}`
this.dicomInfo.frame = `${this.stack.currentImageIdIndex + 1}/${
this.stack.imageIds.length
}`
this.dicomInfo.size = `${data.uint16('x00280011')}x${data.uint16(
'x00280010'
)}`
@ -385,7 +393,6 @@ export default {
this.stack.imageIdIndex = newImageIdIndex
this.series.imageIdIndex = newImageIdIndex
this.height = (this.stack.currentImageIdIndex) * 100 / (this.stack.imageIds.length - 1)
this.resetWwwc()
},
stackScrollCallback(e) {
const { detail } = e
@ -676,7 +683,7 @@ export default {
cornerstoneTools.getToolState(
this.canvas,
'playClip'
).data[0].loop = true
).data[0].loop = false
},
setFps(fps) {
this.dicomInfo.fps = fps
@ -1134,7 +1141,6 @@ export default {
font-size: 12px;
/* z-index: 1; */
}
.info-image {
position: absolute;
left: 10px;
@ -1154,7 +1160,6 @@ export default {
font-size: 12px;
/* z-index: 1; */
}
.info-instance {
position: absolute;
right: 15px;
@ -1187,7 +1192,6 @@ export default {
margin: 10px;
cursor: default;
}
.menu__item:hover {
color: #ff0000;
}
@ -1207,8 +1211,7 @@ li:hover {
background-color: #e0e0e2;
color: white;
}
.my_slider_box:after {
.my_slider_box:after{
content: '';
position: absolute;
bottom: -20px;

View File

@ -887,11 +887,11 @@ export default {
.dicom-wrapper .dropdown-content {
display: none;
position: absolute;
left: -20px;
left: 0;
top: 40px;
color: #d0d0d0;
background-color: #323232;
min-width: 100px;
min-width: 80px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
border: 1px solid #4e4e4e;
padding: 5px;

View File

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

View File

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

View File

@ -1,8 +1,15 @@
<template>
<el-dialog v-if="visible" :visible.sync="visible" :title="title" :fullscreen="true" append-to-body
custom-class="base-dialog-wrapper" @close="handleClose">
<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" :is-local="isLocal" />
<PreviewFile v-if="visible" :file-path="path" :file-type="type" />
</div>
</el-dialog>
</template>
@ -17,15 +24,13 @@ export default {
path: null,
type: null,
title: null,
isLocal: false
};
},
methods: {
open(path, type, title, isLocal) {
open(path, type, title) {
this.path = path;
this.type = type;
this.title = title;
this.isLocal = isLocal;
this.visible = true;
},
handleClose() {

View File

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

View File

@ -1,23 +0,0 @@
import Vue from "vue";
import Video from "./index.vue";
const PreviewConstructor = Vue.extend(Video);
const video = options => {
const { path, type, title } = options;
if (!path) throw `path is requred.but ${path}`
const id = `OnlyOffice_${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", () => {
instance.vm.docEditor = null
document.body.removeChild(instance.vm.$el);
instance.vm.$destroy();
});
return instance.vm;
}
export default video;

View File

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

View File

@ -1,38 +0,0 @@
<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">
<video :src="path" style="width: 100%;height: 99%;" autoplay controls controlsList="nodownload"></video>
</div>
</el-dialog>
</template>
<script>
export default {
name: "Video",
data() {
return {
visible: false,
path: null,
type: null,
title: null,
};
},
methods: {
open(path, type, title) {
this.path = this.OSSclientConfig.basePath + path;
this.title = title;
this.visible = true;
},
handleClose() {
this.$emit("closed");
},
},
};
</script>
<style lang="scss" scoped>
#placeholder {
width: 100%;
height: 100%;
}
</style>

View File

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

View File

@ -22,13 +22,7 @@
</div>
<el-table :data="questionForm[question.Id]">
<el-table-column v-for="item of question.TableQuestions" :key="item.Id" :prop="item.Id"
:label="item.QuestionName" min-width="100" show-overflow-tooltip>
<template slot-scope="scope">
{{ scope.row[item.Id] && Array.isArray(scope.row[item.Id]) ?
scope.row[item.Id].join(" | ")
: scope.row[item.Id] }}
</template>
</el-table-column>
:label="item.QuestionName" min-width="100" show-overflow-tooltip />
<el-table-column :label="$t('common:action:action')" min-width="100" show-overflow-tooltip
v-if="SecondReviewState <= 0">
<template slot-scope="scope">
@ -82,7 +76,7 @@
<el-option v-for="val in question.TypeValue.split('|')" :key="val" :label="val" :value="val.trim()" />
</template>
</el-select>
<!-- 日期 -->
<!-- 单选 -->
<el-date-picker v-if="question.ClinicalQuestionType === 'time'" v-model="questionForm[question.Id]"
style="width: 200px" align="right" type="date" format="yyyy-MM-dd" value-format="yyyy-MM-dd" />
<!-- 单选 -->
@ -323,6 +317,8 @@ export default {
})
break
case 6:
console.log(this.questionForm[o.QuestionId])
console.log(this.questionForm)
this.questionForm[o.QuestionId].forEach((q, qi) => {
if (qi === 0) {
num = parseFloat(q[o.TableQuestionId])
@ -365,16 +361,11 @@ export default {
}
break
case 11:
if (parseFloat(this.getCurrentAgeByBirthDate(this.questionForm[o.TableQuestionId])) > 0) {
num = parseFloat(this.getCurrentAgeByBirthDate(this.questionForm[o.TableQuestionId]))
if (parseFloat(this.getCurrentAgeByBirthDate2(this.questionForm[o.TableQuestionId], this.questionForm[o.QuestionId])) > 0) {
num = parseFloat(this.getCurrentAgeByBirthDate2(this.questionForm[o.TableQuestionId], this.questionForm[o.QuestionId]))
} else {
num = 0
}
// if (parseFloat(this.getCurrentAgeByBirthDate2(this.questionForm[o.TableQuestionId], this.questionForm[o.QuestionId])) > 0) {
// num = parseFloat(this.getCurrentAgeByBirthDate2(this.questionForm[o.TableQuestionId], this.questionForm[o.QuestionId]))
// } else {
// num = 0
// }
break
}
} else {
@ -414,19 +405,19 @@ export default {
} catch (e) {
console.log(e)
}
if (rules.DigitPlaces) {
num = num.toFixed(rules.DigitPlaces)
}
console.log(num)
return num
},
formItemNumberChange(questionId, isTable) {
try {
if (isTable) {
this.calculationList.forEach((v, i) => {
console.log(v, i)
var find = v.CalculateQuestionList.filter(o => {
return o.QuestionId === questionId
})
// findnumber
console.log('find', find)
if (find) {
var num = this.logic(v)
if (num !== false) {
@ -440,6 +431,7 @@ export default {
return o.TableQuestionId === questionId
})
// findnumber
console.log('find', find)
// findnumber
if (find) {
var num = this.logic(v)
@ -510,9 +502,6 @@ export default {
}
</script>
<style lang="scss" scoped>
::v-deep .el-form-item__label{
color: #606266 !important;
}
.my_dialog {
.criterion-form-item {
::v-deep .el-form-item__content {

View File

@ -1,65 +1,125 @@
<template>
<div class="criterion-form-item">
<el-form-item :label="`${question.QuestionName}`" :prop="question.Id" :rules="[
{
required: (question.IsRequired === 0 || (question.IsRequired === 1 && question.RelevanceId && !!~question.RelevanceValueList.indexOf(questionForm[question.RelevanceId]))),
message: $t('common:ruleMessage:specify'), trigger: ['blur'],
type: question.ClinicalTableQuestionType === 'checkbox' ? 'array' : ''
},
]"
:class="[question.ClinicalTableQuestionType === 'group' ? 'mb' : question.ClinicalTableQuestionType === 'upload' ? 'uploadWrapper' : '']">
<el-input v-if="question.ClinicalTableQuestionType === 'input'" v-model="questionForm[question.Id]"
:max-length="200" :disabled="question.TableQuestionType === 2" />
<el-form-item
:label="`${question.QuestionName}`"
:prop="question.Id"
:rules="[
{ required: (question.IsRequired === 0 || (question.IsRequired ===1 && question.RelevanceId && !!~question.RelevanceValueList.indexOf(questionForm[question.RelevanceId]))),
message: $t('common:ruleMessage:specify'), trigger: ['blur'],
type: question.ClinicalTableQuestionType === 'checkbox' ? 'array' : ''},
]"
:class="[question.ClinicalTableQuestionType==='group'?'mb':question.ClinicalTableQuestionType==='upload'?'uploadWrapper':'']"
>
<el-input
v-if="question.ClinicalTableQuestionType==='input'"
v-model="questionForm[question.Id]"
:max-length="200"
:disabled="question.TableQuestionType === 2"
/>
<!-- 多行文本输入框 -->
<el-input v-if="question.ClinicalTableQuestionType === 'textarea'" v-model="questionForm[question.Id]"
:max-length="200" type="textarea" :autosize="{ minRows: 2, maxRows: 4 }" />
<el-input
v-if="question.ClinicalTableQuestionType==='textarea'"
v-model="questionForm[question.Id]"
:max-length="200"
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
/>
<!-- 下拉框 -->
<el-select v-if="question.ClinicalTableQuestionType === 'select'" v-model="questionForm[question.Id]" clearable
:disabled="(question.TableQuestionType === 2 || question.QuestionGenre === 2) && !!question.DictionaryCode">
<el-select
v-if="question.ClinicalTableQuestionType==='select'"
v-model="questionForm[question.Id]"
clearable
:disabled="(question.TableQuestionType === 2 || question.QuestionGenre === 2) && !!question.DictionaryCode"
>
<template v-if="question.TableQuestionType === 1">
<el-option v-for="item in organList" :key="item.Id" :label="item[question.DataTableColumn]"
:value="item[question.DataTableColumn]" />
<el-option
v-for="item in organList"
:key="item.Id"
:label="item[question.DataTableColumn]"
:value="item[question.DataTableColumn]"
/>
</template>
<template v-else-if="question.TableQuestionType === 3 || question.QuestionGenre === 3">
<el-option v-for="item of $d[question.DictionaryCode]" :key="item.id" :value="item.value"
:label="item.label" />
<el-option
v-for="item of $d[question.DictionaryCode]"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template>
<template
v-else-if="(question.TableQuestionType === 2 || question.QuestionGenre === 2) && question.DictionaryCode">
<el-option v-for="item of $d[question.DictionaryCode]" :key="item.id" :value="item.value"
:label="item.label" />
<template v-else-if="(question.TableQuestionType === 2 || question.QuestionGenre === 2) && question.DictionaryCode">
<el-option
v-for="item of $d[question.DictionaryCode]"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template>
<template v-else>
<el-option v-for="val in question.TypeValue.split('|')" :key="val" :label="val" :value="val" />
<el-option
v-for="val in question.TypeValue.split('|')"
:key="val"
:label="val"
:value="val"
/>
</template>
</el-select>
<!-- 单选 -->
<el-date-picker v-if="question.ClinicalTableQuestionType === 'time'" v-model="questionForm[question.Id]"
format="yyyy-MM-dd" value-format="yyyy-MM-dd" style="width: 200px" align="right" type="date" />
<el-date-picker
v-if="question.ClinicalTableQuestionType === 'time'"
v-model="questionForm[question.Id]"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
style="width: 200px"
align="right"
type="date"
/>
<!-- 单选 -->
<el-radio-group v-if="question.ClinicalTableQuestionType === 'radio'" v-model="questionForm[question.Id]"
@change="((val) => { formItemChange(val, question) })">
<el-radio-group
v-if="question.ClinicalTableQuestionType==='radio'"
v-model="questionForm[question.Id]"
@change="((val)=>{formItemChange(val, question)})"
>
<template v-if="question.DictionaryCode">
<el-radio v-for="item of $d[question.DictionaryCode]" :key="item.id" :label="item.value">
<el-radio
v-for="item of $d[question.DictionaryCode]"
:key="item.id"
:label="item.value"
>
{{ item.label }}
</el-radio>
</template>
<template v-if="question.TypeValue">
<el-radio v-for="val in question.TypeValue.split('|')" :key="val" :label="val">
<el-radio
v-for="val in question.TypeValue.split('|')"
:key="val"
:label="val"
>
{{ val }}
</el-radio>
</template>
</el-radio-group>
<!-- 复选框 -->
<el-checkbox-group v-if="question.ClinicalTableQuestionType === 'checkbox'" v-model="questionForm[question.Id]">
<el-checkbox v-for="val in question.TypeValue.split('|')" :key="val" :label="val">
<el-checkbox-group
v-if="question.ClinicalTableQuestionType==='checkbox'"
v-model="questionForm[question.Id]"
>
<el-checkbox
v-for="val in question.TypeValue.split('|')"
:key="val"
:label="val"
>
{{ val }}
</el-checkbox>
</el-checkbox-group>
<el-input v-if="question.ClinicalTableQuestionType === 'number'" v-model="questionForm[question.Id]" type="number"
@input="limitInput($event, questionForm, question)" style="width: 200px">
<el-input
v-if="question.ClinicalTableQuestionType === 'number'"
v-model="questionForm[question.Id]"
type="number"
style="width: 200px"
>
<template v-if="question.Unit" slot="append">{{ question.Unit }}</template>
</el-input>
</el-form-item>
@ -127,14 +187,6 @@ export default {
}
},
methods: {
limitInput(value, form, row) {
if (value.indexOf('.') > -1) {
if (value.split('.')[1].length >= row.DigitPlaces) {
this.$set(form, row.Id, parseFloat(value).toFixed(row.DigitPlaces))
}
}
this.$forceUpdate()
},
save() {
},
openAddTableCol(row) {
@ -168,40 +220,34 @@ export default {
}
</script>
<style lang="scss" scoped>
.my_dialog {
.criterion-form-item {
::v-deep .el-form-item__content {
.my_dialog{
.criterion-form-item{
::v-deep .el-form-item__content{
width: auto;
}
}
}
.criterion-form-item {
.el-form-item {
.criterion-form-item{
.el-form-item{
display: flex;
flex-direction: row;
align-items: flex-start;
}
::v-deep .el-form-item__content {
::v-deep .el-form-item__content{
width: 500px;
}
.el-input {
width: 100%;
.el-input{
width:100%;
}
.mb {
.mb{
margin-bottom: 0px;
}
.disabled {
.disabled{
::v-deep .el-upload--picture-card {
display: none;
}
}
.uploadWrapper {
.uploadWrapper{
display: flex;
flex-direction: column;
align-items: flex-start;

View File

@ -375,7 +375,7 @@ export default {
console.log(i.Answer ? i.Answer.split(',') : [])
console.log(this.questionForm)
} else if (i.ClinicalQuestionType === 'number') {
this.$set(this.questionForm, i.Id, i.Answer || i.DefaultValue)
this.$set(this.questionForm, i.Id, i.Answer)
} else if (i.Childrens && i.Childrens.length > 0) {
this.setChild(i.Childrens)
}

View File

@ -22,9 +22,10 @@
<i class="el-icon-warning-outline"></i>
<div v-html="$t('download:tip:message')"></div>
</div>
<!--上传列表@selection-change="handleSelectionChange" @sort-change="handleSortByColumn"-->
<!--上传列表@selection-change="handleSelectionChange"-->
<el-table ref="dicomFilesTable" v-adaptive="{ bottomOffset: 85 }" height="100" :data="list" :loading="loading"
class="dicomFiles-table" :default-sort="{ prop: 'TaskBlindName', order: 'descending' }">
class="dicomFiles-table"
:default-sort="{ prop: 'TaskBlindName', order: 'descending' }">
<!-- <el-table-column
type="selection"
width="55"
@ -34,11 +35,9 @@
<!--受试者-->
<el-table-column :label="$t('download:table:subjectCode')" min-width="130" prop="SubjectCode"
show-overflow-tooltip />
<!--访视名称-->
<el-table-column prop="VisitName" :label="$t('download:table:VisitName')" sortable v-if="IsImageSegment" />
<!--任务名称-->
<el-table-column :label="$t('download:table:taskName')" min-width="130" show-overflow-tooltip prop="TaskBlindName"
sortable v-else />
sortable />
<!--检查类型-->
<el-table-column :label="$t('download:table:studyType')" min-width="130" show-overflow-tooltip prop="IsDicom"
sortable>
@ -77,8 +76,7 @@
</el-table-column>
</el-table>
<study-view v-if="model_cfg.visible" :model_cfg="model_cfg" :modelList="modelList" :bodyPart="bodyPart"
:subjectVisitId="modelSubjectVisitId" :IsDicom="IsDicom" :isDownload="true" :visitTaskId="modelTaskId"
:IsImageSegment="IsImageSegment" :Criterion="Criterion" />
:IsDicom="IsDicom" :visitTaskId="modelTaskId" />
</el-dialog>
</template>
<script>
@ -129,10 +127,6 @@ export default {
return {}
},
},
IsImageSegment: {
type: Boolean,
default: false,
}
},
data() {
return {
@ -156,16 +150,14 @@ export default {
open: null,
downloadId: null,
IsReadingTaskViewInOrder: 0, //
bodyPart: {},
bodyPart: [],
modelTaskId: null,
modelSubjectVisitId: null,
}
},
async mounted() {
this.bodyPart.Bodypart = await this.$getBodyPart(this.$route.query.trialId)
this.getList()
this.bodyPart = await this.$getBodyPart(this.$route.query.trialId)
this.title = `Download Images${this.SubjectCode}${this.Criterion.TrialReadingCriterionName}`
if (this.IsImageSegment) this.title = `Download Images${this.SubjectCode}`
},
beforeDestroy() {
store.dispatch('trials/setUnLock', false)
@ -184,12 +176,6 @@ export default {
if (this.TaskId) {
this.searchData.VisitTaskId = this.TaskId
}
if (this.IsImageSegment) {
this.searchData.IsImageSegmentLabel = true
}
else if (this.Criterion.CriterionType == 19 || this.Criterion.CriterionType == 20) {
this.searchData.IsImageSegmentLabel = false
}
this.loading = true
let res = await getSubjectImageDownloadSelectList(this.searchData)
this.loading = false
@ -272,12 +258,6 @@ export default {
data.NoneDicomStudyIdList = [...data.NoneDicomStudyIdList, ...arr]
}
}
if (this.IsImageSegment) {
data.IsImageSegmentLabel = true
}
else if (this.Criterion.CriterionType == 19 || this.Criterion.CriterionType == 20) {
data.IsImageSegmentLabel = false
}
this.btnLoading = true
let res = await getIRReadingDownloadStudyInfo(data)
this.btnLoading = false
@ -307,78 +287,35 @@ export default {
formatDownloadFile(list) {
let files = [],
name = `${list[0].SubjectCode}_${new Date().getTime()}.zip`
if (this.IsImageSegment) {
name = `${list[0].SubjectCode}.zip`
} else {
if (this.IsReadingTaskViewInOrder === 1) {
name = `${list[0].SubjectCode}_${list[0].TaskBlindName}.zip`
}
if (this.IsReadingTaskViewInOrder === 0) {
// name = `${list[0].TaskBlindName}.zip`
name = `${list[0].SubjectCode}_${list[0].TaskBlindName}.zip`
}
if (this.IsReadingTaskViewInOrder === 1) {
name = `${list[0].SubjectCode}_${list[0].TaskBlindName}.zip`
}
if (this.IsReadingTaskViewInOrder === 0) {
// name = `${list[0].TaskBlindName}.zip`
name = `${list[0].SubjectCode}_${list[0].TaskBlindName}.zip`
}
list.forEach((data) => {
if (data.StudyList && data.StudyList.length > 0) {
let StudyList = data.StudyList
StudyList.forEach((study) => {
if (study.StudyDIRPath) {
let obj = {
name: `${data.SubjectCode}/${data.TaskBlindName
}/${this.$fd('IsDicom', true)}/${study.StudyCode
}/DICOMDIR`,
url: this.OSSclientConfig.basePath + study.StudyDIRPath,
}
if (this.IsImageSegment) {
obj = {
name: `${data.SubjectCode}/${data.VisitName
}/${this.$fd('IsDicom', true)}/${study.StudyCode
}/DICOMDIR`,
url: this.OSSclientConfig.basePath + study.StudyDIRPath,
}
} else if (this.IsReadingTaskViewInOrder === 0) {
obj = {
name: `${data.TaskBlindName}/${this.$fd(
'IsDicom',
true
)}/DICOMDIR`,
url: this.OSSclientConfig.basePath + study.StudyDIRPath,
}
}
files.push(obj)
}
if (study.SeriesList.length > 0) {
study.SeriesList.forEach((series) => {
if (series.InstanceList.length > 0) {
series.InstanceList.forEach((instance) => {
if (series.InstancePathList.length > 0) {
series.InstancePathList.forEach((instance) => {
let fileName = instance.Path.split('/').pop()
if (instance.FileName) {
fileName = instance.FileName
}
let obj = {
name: `${data.SubjectCode}/${data.TaskBlindName
}/${this.$fd('IsDicom', true)}/${study.StudyCode
}/IMAGE/${fileName}`,
}/${fileName}`,
url: this.OSSclientConfig.basePath + instance.Path,
IsEncapsulated: instance.IsEncapsulated
}
if (this.IsImageSegment) {
obj = {
name: `${data.SubjectCode}/${data.VisitName
}/${this.$fd('IsDicom', true)}/${study.StudyCode
}/IMAGE/${fileName}`,
url: this.OSSclientConfig.basePath + instance.Path,
IsEncapsulated: instance.IsEncapsulated
}
} else if (this.IsReadingTaskViewInOrder === 0) {
if (this.IsReadingTaskViewInOrder === 0) {
obj = {
name: `${data.TaskBlindName}/${this.$fd(
'IsDicom',
true
)}/IMAGE/${fileName}`,
)}/${fileName}`,
url: this.OSSclientConfig.basePath + instance.Path,
IsEncapsulated: instance.IsEncapsulated
}
}
files.push(obj)
@ -401,16 +338,7 @@ export default {
)}/${study.StudyCode}/${item.FileName}`,
url: this.OSSclientConfig.basePath + item.Path,
}
if (this.IsImageSegment) {
obj = {
name: `${data.SubjectCode}/${data.VisitName}/${this.$fd(
'IsDicom',
false
)}/${study.StudyCode}/${item.FileName}`,
url: this.OSSclientConfig.basePath + item.Path,
}
}
else if (this.IsReadingTaskViewInOrder === 0) {
if (this.IsReadingTaskViewInOrder === 0) {
obj = {
name: `${data.TaskBlindName}/${this.$fd(
'IsDicom',
@ -440,9 +368,6 @@ export default {
},
handleOpenDialog(item) {
this.model_cfg.title = `${item.SubjectCode || ''} > ${item.TaskBlindName}`
if (this.IsImageSegment) {
this.model_cfg.title = `${item.SubjectCode || ''} > ${item.VisitName}`
}
if (item.IsDicom) {
this.modelList = item.DicomStudyList
} else {
@ -452,7 +377,6 @@ export default {
})
}
this.modelTaskId = item.VisitTaskId
this.modelSubjectVisitId = item.SourceSubjectVisitId
this.IsDicom = item.IsDicom
this.model_cfg.visible = true
},
@ -481,16 +405,9 @@ export default {
}
let trialId = this.$route.query.trialId
var token = getToken()
let routeData = null
if (!this.IsImageSegment && (this.Criterion.CriterionType == 19 || this.Criterion.CriterionType == 20)) {
routeData = this.$router.resolve({
path: `/showNoneDicoms?trialId=${trialId}&isImageSegmentLabel=${false}&visitTaskId=${row.VisitTaskId}&subjectVisitId=${row.SourceSubjectVisitId}&TokenKey=${token}&isReading=true`,
})
} else {
routeData = this.$router.resolve({
path: `/showNoneDicoms?trialId=${trialId}&visitTaskId=${row.VisitTaskId}&subjectVisitId=${row.SourceSubjectVisitId}&TokenKey=${token}&isReading=true`,
})
}
const routeData = this.$router.resolve({
path: `/showNoneDicoms?trialId=${trialId}&subjectVisitId=${row.SourceSubjectVisitId}&TokenKey=${token}&isReading=true`,
})
this.open = window.open(routeData.href, '_blank')
},
//

View File

@ -283,7 +283,6 @@ export default {
}
if (this.visitTaskId) {
this.form.VisitTaskId = this.visitTaskId
this.form.QuestionType = 6
}
if (this.SubjectVisitId) {
this.form.SubjectVisitId = this.SubjectVisitId

View File

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

View File

@ -4,65 +4,123 @@
<span>{{ $t('upload:dicom:title') }}</span>
<div class="tip">
<i class="el-icon-warning-outline"></i>
<div v-html="$t(`upload:dicom:tip:message${isReadingTaskViewInOrder}`)"></div>
<div
v-html="$t(`upload:dicom:tip:message${isReadingTaskViewInOrder}`)"
></div>
</div>
</div>
<!--检查列表-->
<el-table :data="list" style="width: 100%" height="300" :loading="loading">
<!--受试者-->
<el-table-column prop="SubjectCode" :label="$t('upload:dicom:table:subjectCode')" sortable />
<!--访视名称-->
<el-table-column prop="VisitName" :label="$t('download:table:VisitName')" v-if="IsImageSegment" sortable />
<el-table-column
prop="SubjectCode"
:label="$t('upload:dicom:table:subjectCode')"
/>
<!--任务名称-->
<el-table-column prop="TaskBlindName" :label="$t('upload:dicom:table:taskBlindName')" v-else sortable />
<el-table-column
prop="TaskBlindName"
:label="$t('upload:dicom:table:taskBlindName')"
/>
<!--原始检查数-->
<el-table-column prop="OrginalStudyList" :label="$t('upload:dicom:table:orginalStudyListNum')">
<el-table-column
prop="OrginalStudyList"
:label="$t('upload:dicom: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')">
<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('upload:dicom:table:uploadStudyListNum')">
<el-table-column
prop="UploadStudyList"
:label="$t('upload:dicom:table:uploadStudyListNum')"
>
<template slot-scope="scope">
<el-button v-if="
scope.row.UploadStudyList && scope.row.UploadStudyList.length >= 1
" type="text" @click="handleOpenDialog(scope.row, 'UploadStudyList', true)">
<el-button
v-if="
scope.row.UploadStudyList && scope.row.UploadStudyList.length >= 1
"
type="text"
@click="handleOpenDialog(scope.row, 'UploadStudyList', true)"
>
<span>{{ scope.row.UploadStudyList.length }}</span>
</el-button>
<span v-else>0</span>
</template>
</el-table-column>
<el-table-column :label="$t('common:action:action')" fixed="right" width="180">
<el-table-column
:label="$t('common:action:action')"
fixed="right"
width="180"
>
<template slot-scope="scope">
<div class="btnBox">
<!--上传--->
<form id="inputForm" :ref="`uploadForm_${scope.row.Id}`" enctype="multipart/form-data">
<form
id="inputForm"
:ref="`uploadForm_${scope.row.Id}`"
enctype="multipart/form-data"
>
<div class="form-group" style="margin-right: 10px">
<div :id="`directoryInputWrapper_${scope.row.Id}`" class="btn btn-link file-input">
<el-button circle icon="el-icon-upload2" :disabled="btnLoading" :loading="btnLoading"
:title="$t('upload:dicom:button:upload')" />
<input :title="$t('upload:dicom:button:upload')" type="file" :name="`file_${scope.row.VisitTaskId}`"
:ref="`pathClear_${scope.row.VisitTaskId}`" :disabled="btnLoading" webkitdirectory multiple @change="
<div
:id="`directoryInputWrapper_${scope.row.Id}`"
class="btn btn-link file-input"
>
<el-button
circle
icon="el-icon-upload2"
:disabled="btnLoading"
:loading="btnLoading"
:title="$t('upload:dicom:button:upload')"
/>
<input
:title="$t('upload:dicom:button:upload')"
type="file"
:name="`file_${scope.row.VisitTaskId}`"
:ref="`pathClear_${scope.row.VisitTaskId}`"
:disabled="btnLoading"
webkitdirectory
multiple
@change="
($event) => beginScanFiles($event, scope.row.VisitTaskId)
" />
"
/>
</div>
</div>
</form>
<!--预览--->
<el-button circle icon="el-icon-view" :disabled="!scope.row.UploadStudyList ||
scope.row.UploadStudyList.length <= 0
" @click.stop="handleViewReadingImages(scope.row)" :title="$t('upload:dicom:button:preview')" />
<el-button
circle
icon="el-icon-view"
:disabled="
!scope.row.UploadStudyList ||
scope.row.UploadStudyList.length <= 0
"
@click.stop="handleViewReadingImages(scope.row)"
:title="$t('upload:dicom:button:preview')"
/>
<!--删除--->
<el-button circle :disabled="!scope.row.UploadStudyList ||
scope.row.UploadStudyList.length <= 0 ||
scope.row.ReadingTaskState === 2
" icon="el-icon-delete" :title="$t('upload:dicom:button:delete')" @click.stop="remove(scope.row)" />
<el-button
circle
:disabled="
!scope.row.UploadStudyList ||
scope.row.UploadStudyList.length <= 0 ||
scope.row.ReadingTaskState === 2
"
icon="el-icon-delete"
:title="$t('upload:dicom:button:delete')"
@click.stop="remove(scope.row)"
/>
</div>
</template>
</el-table-column>
@ -76,19 +134,38 @@
<form id="inputForm" ref="uploadForm" enctype="multipart/form-data">
<div class="form-group">
<div id="directoryInputWrapper" class="btn btn-link file-input">
<el-button type="primary" :disabled="btnLoading" :loading="btnLoading" size="mini">
<el-button
type="primary"
:disabled="btnLoading"
:loading="btnLoading"
size="mini"
>
{{ $t('upload:dicom:button:batchUpload') }}
</el-button>
<input type="file" name="file" ref="pathClear" :disabled="btnLoading" webkitdirectory multiple title=""
@change="beginScanFiles($event)" />
<input
type="file"
name="file"
ref="pathClear"
:disabled="btnLoading"
webkitdirectory
multiple
title=""
@change="beginScanFiles($event)"
/>
</div>
</div>
</form>
</div>
</div>
<!--上传列表-->
<el-table ref="dicomFilesTable" v-adaptive="{ bottomOffset: 80 }" height="100" :data="uploadQueues"
class="dicomFiles-table" @selection-change="handleSelectionChange">
<el-table
ref="dicomFilesTable"
v-adaptive="{ bottomOffset: 80 }"
height="100"
:data="uploadQueues"
class="dicomFiles-table"
@selection-change="handleSelectionChange"
>
<el-table-column type="index" width="40" />
<el-table-column min-width="200" show-overflow-tooltip>
<template slot="header">
@ -105,21 +182,28 @@
<div style="line-height: 15px">
<div>
<div>
<span v-if="scope.row.dicomInfo.accNumber"><span style="font-weight: 500">Acc:</span>
{{ scope.row.dicomInfo.accNumber }}</span>
<span v-if="scope.row.dicomInfo.accNumber"
><span style="font-weight: 500">Acc:</span>
{{ scope.row.dicomInfo.accNumber }}</span
>
<span v-else style="color: #f44336">N/A</span>
</div>
<div style="display: inline-block; margin-right: 2px">
<span v-if="scope.row.dicomInfo.modality.length > 0">
{{ scope.row.dicomInfo.modality.join('、') }},</span>
{{ scope.row.dicomInfo.modality.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.seriesList.length">{{ scope.row.seriesList.length }} Series,</span>
<span v-if="scope.row.seriesList.length"
>{{ scope.row.seriesList.length }} Series,</span
>
<span v-else style="color: #f44336">N/A,</span>
</div>
<div style="display: inline-block">
<span v-if="scope.row.fileList.length">{{ scope.row.fileList.length }} Instances</span>
<span v-if="scope.row.fileList.length"
>{{ scope.row.fileList.length }} Instances</span
>
<span v-else style="color: #f44336">N/A</span>
</div>
</div>
@ -133,7 +217,8 @@
</div>
<div style="display: inline-block">
<span v-if="scope.row.dicomInfo.description">
{{ scope.row.dicomInfo.description }}</span>
{{ scope.row.dicomInfo.description }}</span
>
<span v-else style="color: #f44336">N/A</span>
</div>
</div>
@ -157,12 +242,16 @@
<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-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']">
<span
:class="[scope.row.dicomInfo.patientName ? '' : 'colorOfRed']"
>
{{
scope.row.dicomInfo.patientName
? scope.row.dicomInfo.patientName
@ -171,7 +260,9 @@
</span>
</div>
<div>
<span :class="[scope.row.dicomInfo.patientSex ? '' : 'colorOfRed']">
<span
:class="[scope.row.dicomInfo.patientSex ? '' : 'colorOfRed']"
>
{{
scope.row.dicomInfo.patientSex
? scope.row.dicomInfo.patientSex
@ -179,7 +270,9 @@
}},
</span>
<span :class="[scope.row.dicomInfo.patientAge ? '' : 'colorOfRed']">
<span
:class="[scope.row.dicomInfo.patientAge ? '' : 'colorOfRed']"
>
{{
scope.row.dicomInfo.patientAge
? scope.row.dicomInfo.patientAge
@ -187,9 +280,11 @@
}},
</span>
<span :class="[
scope.row.dicomInfo.patientBirthDate ? '' : 'colorOfRed',
]">
<span
:class="[
scope.row.dicomInfo.patientBirthDate ? '' : 'colorOfRed',
]"
>
{{
scope.row.dicomInfo.patientBirthDate
? scope.row.dicomInfo.patientBirthDate
@ -200,14 +295,21 @@
</div>
</template>
</el-table-column>
<el-table-column :label="$t('trials:uploadDicomList:table:failedFileCount')" min-width="150"
show-overflow-tooltip>
<el-table-column
:label="$t('trials:uploadDicomList:table:failedFileCount')"
min-width="150"
show-overflow-tooltip
>
<template slot-scope="scope">
<el-progress color="#409eff" :percentage="(
(scope.row.dicomInfo.uploadFileSize * 100) /
(scope.row.dicomInfo.fileSize ? scope.row.dicomInfo.fileSize : 1)
).toFixed(2) * 1
" />
<el-progress
color="#409eff"
:percentage="
(
(scope.row.dicomInfo.uploadFileSize * 100) /
scope.row.dicomInfo.fileSize
).toFixed(2) * 1
"
/>
<span>
{{ $t('trials:uploadDicomList:table:uploadNow')
}}{{ scope.row.dicomInfo.failedFileCount }}/{{
@ -222,52 +324,85 @@
</template>
</el-table-column>
<el-table-column :label="$t('trials:uploadDicomList:table:status')" min-width="140" show-overflow-tooltip>
<el-table-column
:label="$t('trials:uploadDicomList:table:status')"
min-width="140"
show-overflow-tooltip
>
<template slot-scope="scope">
<span v-if="
!scope.row.dicomInfo.failedFileCount &&
!scope.row.dicomInfo.isInit
">
{{ $t('trials:uploadDicomList:table:status1') }}</span>
<span style="color: #409eff" v-else-if="
!scope.row.dicomInfo.failedFileCount &&
scope.row.dicomInfo.isInit &&
btnLoading
">{{ $t('trials:uploadDicomList:table:status2') }}</span>
<span style="color: #409eff" v-else-if="
scope.row.dicomInfo.failedFileCount <
scope.row.dicomInfo.fileCount && !scope.row.uploadState.record
">{{ $t('trials:uploadDicomList:table:status2') }}</span>
<span style="color: #2cc368" v-else-if="
scope.row.dicomInfo.failedFileCount ===
scope.row.dicomInfo.fileCount
">{{ $t('trials:uploadDicomList:table:status3') }}</span>
<span style="color: #f66" v-else-if="
scope.row.uploadState.record &&
scope.row.uploadState.record.fileCount === 0
">{{ $t('trials:uploadDicomList:table:status5') }}</span>
<span
v-if="
!scope.row.dicomInfo.failedFileCount &&
!scope.row.dicomInfo.isInit
"
>
{{ $t('trials:uploadDicomList:table:status1') }}</span
>
<span
style="color: #409eff"
v-else-if="
!scope.row.dicomInfo.failedFileCount &&
scope.row.dicomInfo.isInit &&
btnLoading
"
>{{ $t('trials:uploadDicomList:table:status2') }}</span
>
<span
style="color: #409eff"
v-else-if="
scope.row.dicomInfo.failedFileCount <
scope.row.dicomInfo.fileCount && !scope.row.uploadState.record
"
>{{ $t('trials:uploadDicomList:table:status2') }}</span
>
<span
style="color: #2cc368"
v-else-if="
scope.row.dicomInfo.failedFileCount ===
scope.row.dicomInfo.fileCount
"
>{{ $t('trials:uploadDicomList:table:status3') }}</span
>
<span
style="color: #f66"
v-else-if="
scope.row.uploadState.record &&
scope.row.uploadState.record.fileCount === 0
"
>{{ $t('trials:uploadDicomList:table:status5') }}</span
>
<span style="color: #f66" v-else>{{
$t('trials:uploadDicomList:table:Failed')
}}</span>
</template>
</el-table-column>
<el-table-column :label="$t('trials:uploadDicomList:table:record')" min-width="140" show-overflow-tooltip>
<el-table-column
:label="$t('trials:uploadDicomList:table:record')"
min-width="140"
show-overflow-tooltip
>
<template slot-scope="scope">
<el-tooltip placement="top" v-if="scope.row.uploadState.record">
<div slot="content">
<div style="max-height: 500px; overflow-y: auto">
{{ $t('trials:uploadDicomList:table:Existed') }}:
<div v-if="scope.row.uploadState.record.Existed.length">
<div v-for="item of scope.row.uploadState.record.Existed" :key="item"
style="font-size: 12px; color: #baa72a">
<div
v-for="item of scope.row.uploadState.record.Existed"
:key="item"
style="font-size: 12px; color: #baa72a"
>
{{ item }}
</div>
</div>
<div v-else>&nbsp;</div>
{{ $t('trials:uploadDicomList:table:Uploaded') }}:
<div v-if="scope.row.uploadState.record.Uploaded.length">
<div v-for="item of scope.row.uploadState.record.Uploaded" :key="item"
style="font-size: 12px; color: #24b837">
<div
v-for="item of scope.row.uploadState.record.Uploaded"
:key="item"
style="font-size: 12px; color: #24b837"
>
{{ item }}
</div>
</div>
@ -275,8 +410,11 @@
<br />
{{ $t('trials:uploadDicomList:table:Failed') }}:
<div v-if="scope.row.uploadState.record.Failed.length">
<div v-for="item of scope.row.uploadState.record.Failed" :key="item"
style="font-size: 12px; color: #f66">
<div
v-for="item of scope.row.uploadState.record.Failed"
:key="item"
style="font-size: 12px; color: #f66"
>
{{ item }}
</div>
</div>
@ -300,9 +438,16 @@
</template>
</el-table-column>
</el-table>
<study-view v-if="model_cfg.visible" :model_cfg="model_cfg" :IsDicom="true" :bodyPart="bodyPart"
:subjectVisitId="openSubjectVisitId" :modelList="modelList" :isUpload="openIsUpload"
:visitTaskId="openVisitTaskId" :TrialModality="TrialModality" @getList="getList" />
<study-view
v-if="model_cfg.visible"
:model_cfg="model_cfg"
:IsDicom="true"
:bodyPart="bodyPart"
:modelList="modelList"
:isUpload="openIsUpload"
:TrialModality="TrialModality"
@getList="getList"
/>
</div>
</template>
<script>
@ -366,17 +511,12 @@ export default {
type: Number,
default: 0,
},
IsImageSegment: {
type: Boolean,
default: false,
}
},
components: {
'study-view': studyView,
},
data() {
return {
loading: false,
list: [],
StudyInstanceUidList: [],
SopInstanceUidList: [],
@ -414,17 +554,17 @@ export default {
subjectVisitId: null,
errStudyUidList: [],
open: null,
bodyPart: {},
bodyPart: [],
openIsUpload: false,
openSubjectVisitId: null,
openVisitTaskId: null,
TrialModality: [],
}
},
created() {
this.getList()
},
async mounted() {
this.trialId = this.$route.query.trialId
this.bodyPart.Bodypart = await this.$getBodyPart(this.$route.query.trialId)
this.getList()
this.bodyPart = await this.$getBodyPart(this.$route.query.trialId)
this.uploadQueues = []
this.OSSclient.close()
},
@ -449,12 +589,6 @@ export default {
if (this.TaskId) {
params.VisitTaskId = this.TaskId
}
if (this.IsImageSegment) {
params.IsImageSegmentLabel = true
}
else if (this.Criterion.CriterionType == 19 || this.Criterion.CriterionType == 20) {
params.IsImageSegmentLabel = false
}
this.loading = true
let res = await getSubjectImageUploadList(params)
this.loading = false
@ -470,7 +604,7 @@ export default {
data.SubjectId = item.SubejctId
data.VisitTaskId = item.VisitTaskId
data.SourceSubjectVisitId = item.SourceSubjectVisitId
// this.subjectVisitId = item.SourceSubjectVisitId
this.subjectVisitId = item.SourceSubjectVisitId
this.StudyInstanceUidList.push(data)
})
}
@ -504,7 +638,6 @@ export default {
if (confirm !== 'confirm') return
let params = {
VisitTaskId: item.VisitTaskId,
SubjectVisitId: item.SourceSubjectVisitId || item.SubjectVisitId,
IsDicom: true,
}
let res = await deleteTaskStudy(params)
@ -537,9 +670,7 @@ export default {
//
handleOpenDialog(item, list, isUpload = false) {
this.openIsUpload = isUpload
this.openSubjectVisitId = item.SubjectVisitId || item.SourceSubjectVisitId
this.openVisitTaskId = item.VisitTaskId
this.model_cfg.title = `${item.SubjectCode || ''} > ${this.IsImageSegment ? item.VisitName : item.TaskBlindName}`
this.model_cfg.title = `${item.SubjectCode || ''} > ${item.TaskBlindName}`
this.modelList = item[list]
this.model_cfg.visible = true
},
@ -555,9 +686,6 @@ export default {
if (this.VisitTaskId) {
data.VisitTaskId = this.VisitTaskId
}
if (this.IsImageSegment) {
data.IsImageSegmentLabel = true
}
let res = await verifyIRStudyAllowUpload(data)
if (res.IsSuccess) {
return res.Result
@ -584,9 +712,8 @@ export default {
confirmMessage = null
for (let i = 0; i < checkFiles.length; i++) {
let item = checkFiles[i]
var dicom = await parseDicom(item, ['StudyInstanceUid', 'Modality'])
var dicom = await parseDicom(item, 'StudyInstanceUid')
if (!dicom.StudyInstanceUid) continue
if (this.IsImageSegment && dicom.Modality !== 'IVUS') continue
let has = true,
has2 = false,
has3 = false
@ -640,8 +767,8 @@ export default {
if (this.errStudyUidList && this.errStudyUidList.length > 0) {
for (let i = 0; i < checkFiles.length; i++) {
let item = checkFiles[i]
var dicom = await parseDicom(item, ['StudyInstanceUid', 'Modality'])
if (!!~this.errStudyUidList.indexOf(dicom.StudyInstanceUid) || (this.IsImageSegment && dicom.Modality !== 'IVUS')) {
var dicom = await parseDicom(item, 'StudyInstanceUid')
if (!!~this.errStudyUidList.indexOf(dicom.StudyInstanceUid)) {
this.hasOtherStudy = true
checkFiles.splice(i, 1)
i--
@ -667,9 +794,8 @@ export default {
resolve()
})
var validFilesCount = 0
scope.uploadQueues = []
for (var i = 0; i < checkFiles.length; ++i) {
; (function (index) {
;(function (index) {
p = p.then(function () {
if (
checkFiles[index].name.toUpperCase().indexOf('DICOMDIR') === -1
@ -708,7 +834,6 @@ export default {
var studyUid = data.string('x0020000d')
if (!studyUid) return resolve()
var pixelDataElement = data.elements.x7fe00010
if (!pixelDataElement && modality !== 'SR') return resolve()
var studyIndex = 0
while (
studyIndex < scope.uploadQueues.length &&
@ -753,15 +878,6 @@ export default {
fileList: [],
dicomInfo: {
studyId: data.string('x00200010'),
Manufacturer: data.string('x00080070') || '',
ManufacturerModelName: data.string('x000801090') || '',
DeviceSerialNumber: data.string('x00181000') || '',
DeviceUID: data.string('x00181002') || '',
SoftwareVersions: data.string('x00181020') || '',
PatientWeight: data.string('x00101030') || '',
DicomStudyDate: data.string('x00080020'),
DicomStudyTime: data.string('x00080030'),
studyUid: studyUid,
patientId: data.string('x00100020'),
patientName: patientNameStr,
@ -872,11 +988,6 @@ export default {
)
seriesItem = {
seriesUid: seriesUid,
RadiopharmaceuticalInformationSequence: data.string('x00540016') || "",
AcquisitionDate: data.string('x00080022') || "",
DicomSeriesDate: data.string('x00080021'),
DicomSeriesTime: data.string('x00080031'),
seriesNumber: data.intString('x00200011') || 1,
modality: data.string('x00080060') || '',
description: seriesDescriptionStr,
@ -915,25 +1026,7 @@ export default {
instanceTime = time ? `${date} ${time}` : `${date} 00:00:00`
}
instanceItem = {
PhotometricInterpretation: data.string('x00280004') || '',
BitsAllocated: data.uint16('x00280100') || '',
PixelRepresentation: data.uint16('x00280103') || '',
RescaleIntercept: data.string('x00281052') || '',
RescaleSlope: data.string('x00281053') || '',
ImagePositionPatient: data.string('x00200032') || '',
ImageOrientationPatient: data.string('x00200037') || '',
SequenceOfUltrasoundRegions: data.string('x00186011') || '',
FrameTime: data.string('x00181063') || '',
CorrectedImage: data.string('x00280051') || '',
Units: data.string('x00541001') || '',
DecayCorrection: data.string('x00541102') || '',
EncapsulatedDocument: data.string('x00420011') || '',
instanceUid: instanceUid,
SOPClassUID: data.string('x00080016'),
TransferSytaxUID: data.string('x00020010'),
MediaStorageSOPInstanceUID: instanceUid,
MediaStorageSOPClassUID: data.string('x00080016'),
instanceNumber: data.intString('x00200013') || 1,
frameCount: data.intString('x00280008') || 1,
instanceTime: instanceTime,
@ -941,7 +1034,7 @@ export default {
imageColumns: data.uint16('x00280011') || 0,
sliceLocation: data.intString('x00201041') || 0,
sliceThickness: data.string('x00180050') || '',
numberOfFrames: data.intString('x00280008') || 1,
numberOfFrames: data.intString('x00280008') || 0,
pixelSpacing: data.string('x00280030') || '',
imagerPixelSpacing: data.string('x00181164') || '',
frameOfReferenceUID: data.string('x00200052') || '',
@ -1081,25 +1174,10 @@ export default {
var scope = this
return new Promise(function (resolve, reject) {
try {
let subjectVisitId = null;
if (scope.VisitTaskId) {
scope.StudyInstanceUidList.forEach(item => {
if (item.VisitTaskId === scope.VisitTaskId) {
subjectVisitId = item.SourceSubjectVisitId
}
})
} else {
scope.StudyInstanceUidList.forEach(item => {
if (item.StudyInstanceUid === scope.uploadQueues[index].dicomInfo.studyUid) {
subjectVisitId = item.SourceSubjectVisitId
}
})
}
if (!subjectVisitId) return reject('subjectVisitId is notFind')
preArchiveDicomStudy({
trialId: scope.trialId,
subjectId: scope.SubjectId,
subjectVisitId: subjectVisitId,
subjectVisitId: scope.subjectVisitId,
fileSize: scope.uploadQueues[index].dicomInfo.fileSize,
fileCount: scope.uploadQueues[index].dicomInfo.fileCount,
IsDicomReUpload:
@ -1115,7 +1193,7 @@ export default {
dicomInfo.seriesNum = seriesNum
dicomInfo.fileNum = fileNum
dicomInfo.subjectId = scope.SubjectId
dicomInfo.subjectVisitId = subjectVisitId
dicomInfo.subjectVisitId = scope.subjectVisitId
let t = setInterval(() => {
dicomUploadInProgress({
trialId: scope.trialId,
@ -1135,7 +1213,7 @@ export default {
let params = {
trialId: scope.trialId,
subjectId: scope.SubjectId,
subjectVisitId: subjectVisitId,
subjectVisitId: scope.subjectVisitId,
studyMonitorId: res.Result,
failedFileCount: 0,
RecordPath: null,
@ -1157,16 +1235,7 @@ export default {
acquisitionNumber: dicomInfo.acquisitionNumber,
triggerTime: dicomInfo.triggerTime,
bodyPartExamined: '',
DicomStudyDate: dicomInfo.DicomStudyDate,
DicomStudyTime: dicomInfo.DicomStudyTime,
seriesList: [],
Manufacturer: dicomInfo.Manufacturer,
ManufacturerModelName: dicomInfo.ManufacturerModelName,
DeviceSerialNumber: dicomInfo.DeviceSerialNumber,
DeviceUID: dicomInfo.DeviceUID,
SoftwareVersions: dicomInfo.SoftwareVersions,
PatientWeight: dicomInfo.PatientWeight,
},
}
let arr = []
@ -1190,10 +1259,6 @@ export default {
instanceList.push({
studyInstanceUid: dicomInfo.studyUid,
seriesInstanceUid: v.seriesUid,
SOPClassUID: o.SOPClassUID,
TransferSytaxUID: o.TransferSytaxUID,
MediaStorageSOPInstanceUID: o.MediaStorageSOPInstanceUID,
MediaStorageSOPClassUID: o.MediaStorageSOPClassUID,
sopInstanceUid: o.instanceUid,
instanceNumber: o.instanceNumber,
instanceTime: o.instanceTime,
@ -1209,43 +1274,21 @@ export default {
windowWidth: o.windowWidth,
path: o.myPath,
FileSize: o.FileSize,
PhotometricInterpretation: o.PhotometricInterpretation,
BitsAllocated: o.BitsAllocated,
PixelRepresentation: o.PixelRepresentation,
RescaleIntercept: o.RescaleIntercept,
RescaleSlope: o.RescaleSlope,
ImagePositionPatient: o.ImagePositionPatient,
ImageOrientationPatient: o.ImageOrientationPatient,
SequenceOfUltrasoundRegions: o.SequenceOfUltrasoundRegions,
FrameTime: o.FrameTime,
CorrectedImage: o.CorrectedImage,
Units: o.Units,
DecayCorrection: o.DecayCorrection,
EncapsulatedDocument: o.EncapsulatedDocument,
})
Record.Uploaded.push(name)
dicomInfo.failedFileCount++
Record.FileCount++
} else {
let path = `/${params.trialId}/Image/${params.subjectId
}/${params.subjectVisitId}/${dicomInfo.visitTaskId
}/${scope.getGuid(
dicomInfo.studyUid +
let path = `/${params.trialId}/Image/${
params.subjectId
}/${params.subjectVisitId}/${
dicomInfo.visitTaskId
}/${scope.getGuid(
dicomInfo.studyUid +
v.seriesUid +
o.instanceUid +
params.trialId
)}`
if (scope.IsImageSegment) {
path = `/${params.trialId}/Image/${params.subjectId
}/${params.subjectVisitId}/AnnotationImage/${dicomInfo.visitTaskId
}/${scope.getGuid(
dicomInfo.studyUid +
v.seriesUid +
o.instanceUid +
params.trialId
)}`
}
)}`
if (scope.isClose) return
let res = await dcmUpload(
{
@ -1279,9 +1322,6 @@ export default {
o.imageRows
)
let thumbnailPath = `/${params.trialId}/Image/${params.subjectId}/${params.subjectVisitId}/${dicomInfo.visitTaskId}/${dicomInfo.studyUid}/${v.seriesUid}.jpg`
if (scope.IsImageSegment) {
thumbnailPath = `/${params.trialId}/Image/${params.subjectId}/${params.subjectVisitId}/AnnotationImage/${dicomInfo.visitTaskId}/${dicomInfo.studyUid}/${v.seriesUid}.jpg`
}
let OSSclient = scope.OSSclient
let seriesRes = await OSSclient.put(
thumbnailPath,
@ -1302,10 +1342,6 @@ export default {
studyInstanceUid: dicomInfo.studyUid,
seriesInstanceUid: v.seriesUid,
sopInstanceUid: o.instanceUid,
SOPClassUID: o.SOPClassUID,
TransferSytaxUID: o.TransferSytaxUID,
MediaStorageSOPInstanceUID: o.MediaStorageSOPInstanceUID,
MediaStorageSOPClassUID: o.MediaStorageSOPClassUID,
instanceNumber: o.instanceNumber,
instanceTime: o.instanceTime,
imageRows: o.imageRows,
@ -1320,20 +1356,6 @@ export default {
windowWidth: o.windowWidth,
path: scope.$getObjectName(res.url),
FileSize: o.FileSize,
PhotometricInterpretation: o.PhotometricInterpretation,
BitsAllocated: o.BitsAllocated,
PixelRepresentation: o.PixelRepresentation,
RescaleIntercept: o.RescaleIntercept,
RescaleSlope: o.RescaleSlope,
ImagePositionPatient: o.ImagePositionPatient,
ImageOrientationPatient: o.ImageOrientationPatient,
SequenceOfUltrasoundRegions: o.SequenceOfUltrasoundRegions,
FrameTime: o.FrameTime,
CorrectedImage: o.CorrectedImage,
Units: o.Units,
DecayCorrection: o.DecayCorrection,
EncapsulatedDocument: o.EncapsulatedDocument,
})
o.myPath = scope.$getObjectName(res.url)
Record.Uploaded.push(name)
@ -1365,8 +1387,6 @@ export default {
seriesInstanceUid: v.seriesUid,
seriesNumber: v.seriesNumber,
seriesTime: v.seriesTime,
DicomSeriesDate: v.DicomSeriesDate,
DicomSeriesTime: v.DicomSeriesTime,
sliceThickness: v.sliceThickness,
imagePositionPatient: v.imagePositionPatient,
imageOrientationPatient: v.imageOrientationPatient,
@ -1382,17 +1402,11 @@ export default {
bodyPartExamined: dicomInfo.bodyPart,
instanceList: instanceList,
ImageResizePath: ImageResizePath,
RadiopharmaceuticalInformationSequence: v.RadiopharmaceuticalInformationSequence,
AcquisitionDate: v.AcquisitionDate,
})
}
let text = JSON.stringify(Record)
let logJsonBlob = scope.generateTxtFile(text)
let logJsonObjectName = `/${params.trialId}/Image/${params.subjectId}/${params.subjectVisitId}/${dicomInfo.visitTaskId}/${dicomInfo.studyUid}/${params.studyMonitorId}.txt`
if (scope.IsImageSegment) {
logJsonObjectName = `/${params.trialId}/Image/${params.subjectId}/${params.subjectVisitId}/AnnotationImage/${dicomInfo.visitTaskId}/${dicomInfo.studyUid}/${params.studyMonitorId}.txt`
}
let logRes
try {
logRes = await scope.OSSclient.put(
@ -1421,9 +1435,6 @@ export default {
v.instanceList[0].imageRows
)
let thumbnailPath = `/${params.trialId}/Image/${params.subjectId}/${params.subjectVisitId}/${dicomInfo.studyUid}/${v.seriesUid}.jpg`
if (scope.IsImageSegment) {
thumbnailPath = `/${params.trialId}/Image/${params.subjectId}/${params.subjectVisitId}/AnnotationImage/${dicomInfo.studyUid}/${v.seriesUid}.jpg`
}
let OSSclient = scope.OSSclient
try {
let seriesRes = await OSSclient.put(thumbnailPath, blob)
@ -1441,9 +1452,6 @@ export default {
if (scope.isClose) return false
console.log(params)
params.VisitTaskId = dicomInfo.visitTaskId
if (scope.IsImageSegment) {
params.IsImageSegmentLabel = true
}
addOrUpdateArchiveTaskStudy(params)
.then((res) => {
if (dicomInfo.failedFileCount === dicomInfo.fileCount) {
@ -1538,7 +1546,7 @@ export default {
var token = getToken()
let trialId = this.$route.query.trialId
const routeData = this.$router.resolve({
path: `/showvisitdicoms?page=upload&trialId=${trialId}&visitTaskId=${this.IsImageSegment ? 'undefined' : row.VisitTaskId}&subjectVisitId=${row.SourceSubjectVisitId}&isReading=1&TokenKey=${token}`,
path: `/showvisitdicoms?page=upload&trialId=${trialId}&visitTaskId=${row.VisitTaskId}&subjectVisitId=${row.SourceSubjectVisitId}&isReading=1&TokenKey=${token}`,
})
this.open = window.open(routeData.href, '_blank')
},
@ -1551,19 +1559,16 @@ export default {
align-items: center;
justify-content: space-between;
}
.btnBox,
.form-group {
display: flex;
align-items: center;
}
#inputForm .file-input {
position: relative;
overflow: hidden;
display: inline-block;
}
#inputForm .file-input input[type='file'] {
position: absolute;
top: 0;
@ -1573,12 +1578,10 @@ export default {
opacity: 0;
cursor: pointer;
}
.tip {
display: flex;
align-items: flex-start;
margin-top: 5px;
i {
margin: 3px 5px 0 0;
}

View File

@ -1,17 +1,40 @@
<template>
<el-dialog :visible.sync="visible" :fullscreen="true" :close-on-click-modal="false" :before-close="beforeClose"
:append-to-body="true" class="uploadDicomAndNonedicom">
<el-dialog
:visible.sync="visible"
:fullscreen="true"
:close-on-click-modal="false"
:before-close="beforeClose"
:append-to-body="true"
class="uploadDicomAndNonedicom"
>
<span slot="title">{{ title }}</span>
<el-tabs type="border-card" v-model="activeName">
<el-tab-pane :label="$t('uploadDicomAndNonedicom:label:dicom')" name="dicom">
<dicomFile v-if="activeName === 'dicom'" :SubjectId="SubjectId" :SubjectCode="SubjectCode"
:Criterion="Criterion" :TaskId="VisitTaskId" :isUpload.sync="isUpload"
:isReadingTaskViewInOrder="isReadingTaskViewInOrder" :IsImageSegment="IsImageSegment" />
<el-tab-pane
:label="$t('uploadDicomAndNonedicom:label:dicom')"
name="dicom"
>
<dicomFile
v-if="activeName === 'dicom'"
:SubjectId="SubjectId"
:SubjectCode="SubjectCode"
:Criterion="Criterion"
:TaskId="VisitTaskId"
:isUpload.sync="isUpload"
:isReadingTaskViewInOrder="isReadingTaskViewInOrder"
/>
</el-tab-pane>
<el-tab-pane :label="$t('uploadDicomAndNonedicom:label:nonedicom')" name="nonedicom">
<nonedicomFile v-if="activeName === 'nonedicom'" :SubjectId="SubjectId" :SubjectCode="SubjectCode"
:Criterion="Criterion" :VisitTaskId="VisitTaskId" :isUpload.sync="isUpload"
:IsImageSegment="IsImageSegment" />
<el-tab-pane
:label="$t('uploadDicomAndNonedicom:label:nonedicom')"
name="nonedicom"
>
<nonedicomFile
v-if="activeName === 'nonedicom'"
:SubjectId="SubjectId"
:SubjectCode="SubjectCode"
:Criterion="Criterion"
:VisitTaskId="VisitTaskId"
:isUpload.sync="isUpload"
/>
</el-tab-pane>
</el-tabs>
</el-dialog>
@ -51,10 +74,6 @@ export default {
type: Number,
default: 0,
},
IsImageSegment: {
type: Boolean,
default: false,
}
},
data() {
return {
@ -65,7 +84,6 @@ export default {
},
mounted() {
this.title = `Upload Images${this.SubjectCode}${this.Criterion.TrialReadingCriterionName}`
if (this.IsImageSegment) this.title = `Upload Images${this.SubjectCode}`
store.dispatch('trials/setUnLock', true)
},
methods: {
@ -85,13 +103,11 @@ export default {
::v-deep.el-tabs--left .el-tabs__header.is-left {
margin-right: 0;
}
.uploadDicomAndNonedicom {
::v-deep.el-tabs--border-card>.el-tabs__header .el-tabs__item {
::v-deep.el-tabs--border-card > .el-tabs__header .el-tabs__item {
color: #909399;
}
::v-deep.el-tabs--border-card>.el-tabs__header .el-tabs__item.is-active {
::v-deep.el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
color: #428bca;
background-color: #fff;
border-right-color: #dcdfe6;

View File

@ -4,31 +4,21 @@
<span>{{ $t('upload:nonedicom:title') }}</span>
<div class="tip">
<i class="el-icon-warning-outline"></i>
<div v-html="$t('upload:nonedicom:tip:message').replace(
'xxx',
relationInfo.ImageFormatList.join('、')
)"></div>
<div v-html="$t('upload:nonedicom:tip:message')"></div>
</div>
</div>
<!--检查列表 @sort-change="handleSortByColumn"-->
<!--检查列表-->
<el-table :data="list" style="width: 100%" v-adaptive="{ bottomOffset: 60 }" :loading="loading"
:default-sort="{ prop: 'TaskBlindName', order: 'descending' }">
<!--受试者 sortable="custom"-->
@sort-change="handleSortByColumn" :default-sort="{ prop: 'TaskBlindName', order: 'descending' }">
<!--受试者-->
<el-table-column prop="SubjectCode" :label="$t('upload:nonedicom:table:subject')" />
<!--访视名称-->
<el-table-column prop="VisitName" :label="$t('upload:nonedicom:table:VisitName')" sortable
v-if="IsImageSegment" />
<!--任务名称-->
<el-table-column prop="TaskBlindName" :label="$t('upload:nonedicom:table:taskName')" sortable v-else />
<el-table-column prop="TaskBlindName" :label="$t('upload:nonedicom:table:taskName')" sortable="custom" />
<!--检查类型-->
<el-table-column prop="Modality" :label="$t('upload:nonedicom:table:molityType')" sortable>
<el-table-column prop="Modality" :label="$t('upload:nonedicom:table:molityType')" sortable="custom">
</el-table-column>
<!--检查部位-->
<el-table-column prop="BodyPart" :label="$t('upload:nonedicom:table:bodyPart')" sortable>
<template slot-scope="scope">
<span>{{ getBodyPart(scope.row.BodyPart, scope.row.BodyPartForEditOther) }}</span>
</template>
</el-table-column>
<el-table-column prop="BodyPart" :label="$t('upload:nonedicom:table:bodyPart')" sortable="custom" />
<!--原文件数-->
<el-table-column prop="FileCount" :label="$t('upload:nonedicom:table:fileCount')">
<template slot-scope="scope">
@ -39,7 +29,9 @@
<el-table-column prop="FileSize" :label="$t('trials:audit:table:nonDicomsFileSize')" width="100">
<template slot-scope="scope">
<span>{{
$FormatSize(scope.row.FileSize)
scope.row.FileSize && scope.row.FileSize > 0
? `${(scope.row.FileSize / 1024 / 1024).toFixed(3)}MB`
: ''
}}</span>
</template>
</el-table-column>
@ -76,7 +68,9 @@
<el-table-column prop="FileSize" :label="$t('trials:audit:table:nonDicomsFileSize')" width="100">
<template slot-scope="scope">
<span>{{
$FormatSize(scope.row.FileSize)
scope.row.FileSize && scope.row.FileSize > 0
? `${(scope.row.FileSize / 1024 / 1024).toFixed(3)}MB`
: ''
}}</span>
</template>
</el-table-column>
@ -134,10 +128,7 @@
<!-- 多文件上传 -->
<form id="inputForm" ref="uploadForm">
<el-divider content-position="left">{{
$t('trials:uploadNonDicoms:label:fileType').replace(
'xxx',
relationInfo.ImageFormatList.join('、')
)
$t('trials:uploadNonDicoms:label:fileType')
}}</el-divider>
<div class="form-group">
<div class="upload" style="margin-right: 10px">
@ -228,8 +219,8 @@ let defaultSearchData = () => {
SubjectId: null,
TrialReadingCriterionId: null,
SubjectCode: null,
// Asc: false,
// SortField: 'TaskBlindName',
Asc: false,
SortField: 'TaskBlindName',
}
}
export default {
@ -257,10 +248,6 @@ export default {
type: Boolean,
default: false,
},
IsImageSegment: {
type: Boolean,
default: false,
},
},
data() {
return {
@ -279,10 +266,6 @@ export default {
currentRow: {},
studyMonitorId: null,
open: null,
BodyPart: {},
relationInfo: {
ImageFormatList: []
}
}
},
watch: {
@ -310,8 +293,7 @@ export default {
store.dispatch('trials/setUnLock', this.btnLoading)
},
},
async created() {
this.BodyPart.Bodypart = await this.$getBodyPart(this.$route.query.trialId)
created() {
this.getList()
},
beforeDestroy() {
@ -327,22 +309,11 @@ export default {
if (this.VisitTaskId) {
this.searchData.VisitTaskId = this.VisitTaskId
}
if (this.IsImageSegment) {
this.searchData.IsImageSegmentLabel = true
}
else if (this.Criterion.CriterionType == 19 || this.Criterion.CriterionType == 20) {
this.searchData.IsImageSegmentLabel = false
}
this.loading = true
let res = await getIRUploadTaskNoneDicomStudyList(this.searchData)
this.loading = false
if (res.IsSuccess) {
this.list = res.Result
this.relationInfo = res.OtherInfo
this.faccept = []
this.relationInfo.ImageFormatList.forEach((item) => {
this.faccept.push(`.${item}`)
})
}
} catch (err) {
this.loading = false
@ -506,16 +477,16 @@ export default {
}
},
//
// 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()
// },
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()
},
//
handleSelectionChange(selection) {
this.selectArr = selection
@ -561,15 +532,9 @@ export default {
let file = this.fileList.filter((item) => item.id === arr[index].id)[0]
file.status = 1
let path = `/${this.$route.query.trialId}/TaskImage/${this.currentRow.SubjectId
}/${this.currentRow.SourceSubjectVisitId}/${this.currentRow.VisitTaskId}/${this.$guid()}${file.name
}/${this.currentRow.VisitTaskId}/${this.$guid()}${file.name
.substring(file.name.lastIndexOf('.'))
.toLocaleLowerCase()}`
if (this.IsImageSegment) {
path = `/${this.$route.query.trialId}/TaskImage/${this.currentRow.SubjectId
}/${this.currentRow.SourceSubjectVisitId}/AnnotationImage/${this.currentRow.VisitTaskId}/${this.$guid()}${file.name
.substring(file.name.lastIndexOf('.'))
.toLocaleLowerCase()}`
}
file.curPath = path
const fileData = await this.fileToBlob(file.file)
let res = await this.fileToOss(path, fileData, file)
@ -653,9 +618,6 @@ export default {
params.RecordPath = RecordPath.path
params.FailedFileCount = RecordPath.Record.Failed.length
}
if (this.IsImageSegment) {
params.IsImageSegmentLabel = true
}
uploadNoneDicomFile(params)
.then((res) => {
if (!isReLoad) {
@ -694,10 +656,7 @@ export default {
})
let text = JSON.stringify(Record)
let logJsonBlob = this.generateTxtFile(text)
let logJsonObjectName = `/${this.$route.query.trialId}/TaskImage/${this.currentRow.SubjectId}/${this.currentRow.SourceSubjectVisitId}/${this.currentRow.VisitTaskId}/${this.studyMonitorId}.txt`
if (this.IsImageSegment) {
logJsonObjectName = `/${this.$route.query.trialId}/TaskImage/${this.currentRow.SubjectId}/${this.currentRow.SourceSubjectVisitId}/AnnotationImage/${this.currentRow.VisitTaskId}/${this.studyMonitorId}.txt`
}
let logJsonObjectName = `/${this.$route.query.trialId}/TaskImage/${this.currentRow.SubjectId}/${this.currentRow.VisitTaskId}/${this.studyMonitorId}.txt`
let logRes
try {
logRes = await this.OSSclient.put(logJsonObjectName, logJsonBlob)
@ -719,26 +678,6 @@ export default {
let blob = new Blob(['\ufeff', text], { type: 'text/plain' })
return blob
},
getBodyPart(bodyPart, other) {
if (!bodyPart && !other) return ''
var separator = ','
if (bodyPart.indexOf('|') > -1) {
separator = '|'
} else if (bodyPart.indexOf(',') > -1) {
separator = ','
} else if (bodyPart.indexOf('') > -1) {
separator = ''
}
var arr = bodyPart.split(separator)
var newArr = arr.map((i) => {
return this.$fd('Bodypart', i.trim(), 'Code', this.BodyPart, 'Name')
})
if (other) {
newArr.push(other)
}
newArr = newArr.filter(Boolean)
return newArr.join(' | ')
},
},
}
</script>

View File

@ -2,54 +2,120 @@
<div v-if="model_cfg.visible">
<base-model :config="model_cfg">
<div slot="dialog-body">
<el-button v-if="!isUpload && !isDownload" type='primary' size="small" style="float:right;" @click="preview">
{{ $t("common:button:preview") }}
</el-button>
<el-table :data="modelList" style="width: 100%" height="300">
<!--检查编号-->
<el-table-column prop="StudyCode" :label="$t('trials:uploadImage:table:StudyCode')" />
<el-table-column
prop="StudyCode"
:label="$t('trials:uploadImage:table:StudyCode')"
/>
<!--检查类型-->
<el-table-column prop="ModalityForEdit" :label="$t('trials:uploadImage:table:ModalityForEdit')"
v-if="IsDicom" />
<el-table-column
prop="ModalityForEdit"
:label="$t('trials:uploadImage:table:ModalityForEdit')"
v-if="IsDicom"
/>
<!--检查模态-->
<el-table-column prop="Modalities" :label="$t('trials:uploadImage:table:Modalities')" v-if="IsDicom" />
<el-table-column
prop="Modalities"
:label="$t('trials:uploadImage:table:Modalities')"
v-if="IsDicom"
/>
<!--检查部位-->
<el-table-column prop="BodyPartForEdit" :label="$t('trials:uploadImage:table:BodyPartForEdit')"
v-if="IsDicom">
<el-table-column
prop="BodyPartForEdit"
:label="$t('trials:uploadImage:table:BodyPartForEdit')"
v-if="IsDicom"
>
<template slot-scope="scope">
<span>{{ getBodyPart(scope.row.BodyPartForEdit, scope.row.BodyPartForEditOther) }}</span>
<span>{{
$fd(
'Bodypart',
scope.row.BodyPartForEdit,
'Code',
{ Bodypart: bodyPart },
'Name'
)
}}</span>
</template>
</el-table-column>
<!--序列数量-->
<el-table-column prop="ReadingSeriesCount" :label="$t('trials:uploadImage:table:SeriesCount')"
v-if="IsDicom" />
<el-table-column
prop="ReadingSeriesCount"
:label="$t('trials:uploadImage:table:SeriesCount')"
v-if="IsDicom"
/>
<!--图像数量-->
<el-table-column prop="ReadingInstanceCount" :label="$t('trials:uploadImage:table:InstanceCount')"
v-if="IsDicom" />
<el-table-column
prop="ReadingInstanceCount"
:label="$t('trials:uploadImage:table:InstanceCount')"
v-if="IsDicom"
/>
<!--检查时间-->
<el-table-column prop="StudyTime" :label="$t('trials:uploadImage:table:StudyTime')" v-if="IsDicom"
min-width="130" />
<el-table-column
prop="StudyTime"
:label="$t('trials:uploadImage:table:StudyTime')"
v-if="IsDicom"
min-width="130"
/>
<!--检查模态-->
<el-table-column prop="Modality" :label="$t('trials:uploadImage:table:Modalities')" v-if="!IsDicom" />
<el-table-column
prop="Modality"
:label="$t('trials:uploadImage:table:Modalities')"
v-if="!IsDicom"
/>
<!--检查部位-->
<el-table-column prop="BodyPart" :label="$t('trials:uploadImage:table:BodyPartForEdit')" v-if="!IsDicom">
<el-table-column
prop="BodyPart"
:label="$t('trials:uploadImage:table:BodyPartForEdit')"
v-if="!IsDicom"
>
<template slot-scope="scope">
<span>{{ getBodyPart(scope.row.BodyPart, scope.row.BodyPartForEditOther) }}</span>
<span>{{
$fd(
'Bodypart',
scope.row.BodyPart,
'Code',
{ Bodypart: bodyPart },
'Name'
)
}}</span>
</template>
</el-table-column>
<!--文件数量-->
<el-table-column prop="ReadingFileCount" :label="$t('trials:uploadImage:table:FileCount')" v-if="!IsDicom" />
<el-table-column
prop="ReadingFileCount"
:label="$t('trials:uploadImage:table:FileCount')"
v-if="!IsDicom"
/>
<!--检查时间-->
<el-table-column prop="ImageDate" :label="$t('trials:uploadImage:table:StudyTime')" v-if="!IsDicom"
min-width="130" />
<el-table-column :label="$t('common:action:action')" fixed="right" width="80" v-if="isUpload">
<el-table-column
prop="ImageDate"
:label="$t('trials:uploadImage:table:StudyTime')"
v-if="!IsDicom"
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:preview')" v-if="!isUpload"
@click.stop="preview(scope.row)" /> -->
<el-button
circle
icon="el-icon-view"
:title="$t('trials:uploadImage:button:preview')"
v-if="!isUpload"
@click.stop="preview(scope.row)"
/>
<!--编辑--->
<el-button circle icon="el-icon-edit-outline" :title="$t('trials:uploadImage:button:edit')"
@click.stop="openEdit(scope.row)" />
<el-button
circle
icon="el-icon-edit-outline"
:title="$t('trials:uploadImage:button:edit')"
v-else
@click.stop="openEdit(scope.row)"
/>
</template>
</el-table-column>
</el-table>
@ -58,20 +124,42 @@
<!--新增检查部位-->
<base-model v-if="editModality_model.visible" :config="editModality_model">
<template slot="dialog-body">
<el-form ref="editModalityform" :inline="true" :model="form" class="demo-form-inline" :rules="rules">
<el-form-item :label="$t('trials:uploadImage:form:ModalityForEdit')" prop="Modality" label-width="150px">
<el-form
ref="editModalityform"
:inline="true"
:model="form"
class="demo-form-inline"
:rules="rules"
>
<el-form-item
:label="$t('trials:uploadImage:form:ModalityForEdit')"
prop="Modality"
label-width="150px"
>
<el-select v-model="form.Modality" placeholder="">
<el-option v-for="item in TrialModality" :key="item" :label="item" :value="item">
<el-option
v-for="item in TrialModality"
:key="item"
:label="item"
:value="item"
>
</el-option>
</el-select>
</el-form-item>
</el-form>
</template>
<template slot="dialog-footer">
<el-button type="primary" @click="updateTaskStudyModality" :loading="loading">
<el-button
type="primary"
@click="updateTaskStudyModality"
:loading="loading"
>
{{ $t('common:button:confirm') }}
</el-button>
<el-button @click="editModality_model.visible = false" :loading="loading">
<el-button
@click="editModality_model.visible = false"
:loading="loading"
>
{{ $t('common:button:cancel') }}
</el-button>
</template>
@ -92,9 +180,9 @@ export default {
},
},
bodyPart: {
type: Object,
type: Array,
default: () => {
return {}
return []
},
},
modelList: {
@ -112,33 +200,16 @@ export default {
visitTaskId: {
type: String,
},
subjectVisitId: {
type: String,
default: ''
},
IsDicom: {
required: true,
type: Boolean,
default: true,
},
isUpload: {
required: true,
type: Boolean,
default: false,
},
IsImageSegment: {
type: Boolean,
default: false,
},
isDownload: {
type: Boolean,
default: false,
},
Criterion: {
type: Object,
default: () => {
return {}
},
},
},
components: {
'base-model': baseModel,
@ -165,7 +236,6 @@ export default {
],
},
loading: false,
BodyPart: {}
}
},
methods: {
@ -174,23 +244,15 @@ export default {
let routeData = null
if (this.IsDicom) {
var token = getToken()
let trialId = this.$route.query.trialId
routeData = this.$router.resolve({
path: `/showvisitdicoms?trialId=${trialId}&visitTaskId=${this.visitTaskId}&subjectVisitId=${this.subjectVisitId}&isReading=1&TokenKey=${token}`,
path: `/showdicom?studyId=${row.Id}&TokenKey=${token}&type=Study&visitTaskId=${this.visitTaskId}&isReading=true`,
})
} else {
let trialId = this.$route.query.trialId
var token = getToken()
if (!this.IsImageSegment && (this.Criterion.CriterionType == 19 || this.Criterion.CriterionType == 20)) {
routeData = this.$router.resolve({
path: `/showNoneDicoms?trialId=${trialId}&isImageSegmentLabel=${false}&visitTaskId=${this.visitTaskId}&subjectVisitId=${this.subjectVisitId}&TokenKey=${token}&isReading=true`,
})
} else {
routeData = this.$router.resolve({
path: `/showNoneDicoms?trialId=${trialId}&visitTaskId=${this.visitTaskId}&subjectVisitId=${this.subjectVisitId}&TokenKey=${token}&isReading=true`,
})
}
routeData = this.$router.resolve({
path: `/showNoneDicoms?trialId=${trialId}&subjectVisitId=${row.SourceSubjectVisitId}&studyId=${row.Id}&TokenKey=${token}&isReading=true`,
})
}
window.open(routeData.href, '_blank')
},
@ -222,28 +284,8 @@ export default {
console.log(err)
}
},
getBodyPart(bodyPart, other) {
if (!bodyPart && !other) return ''
var separator = ','
if (bodyPart.indexOf('|') > -1) {
separator = '|'
} else if (bodyPart.indexOf(',') > -1) {
separator = ','
} else if (bodyPart.indexOf('') > -1) {
separator = ''
}
var arr = bodyPart.split(separator)
console.log(this.bodyPart)
var newArr = arr.map((i) => {
return this.$fd('Bodypart', i.trim(), 'Code', this.bodyPart, 'Name')
})
if (other) {
newArr.push(other)
}
newArr = newArr.filter(Boolean)
return newArr.join(' | ')
},
},
}
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
</style>

View File

@ -32,7 +32,7 @@ export default {
ResetImageQualityControlQuestion: 112, //
CreateReviewTask: 113, //
ReviewImageQualityControlQuestion: 219, //
CorrectImageExaminationInformation: 220, //
},
};
</script>

View File

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

Before

Width:  |  Height:  |  Size: 812 B

View File

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

Before

Width:  |  Height:  |  Size: 3.3 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 418 B

View File

@ -1 +0,0 @@
<?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="1751350116150" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="20392" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M870.4 819.2a51.2 51.2 0 1 1 0 102.4 51.2 51.2 0 0 1 0-102.4zM512 179.2a332.8 332.8 0 1 1 0 665.6 332.8 332.8 0 0 1 0-665.6z m0 51.2a281.6 281.6 0 1 0 0 563.2 281.6 281.6 0 0 0 0-563.2zM153.6 102.4a51.2 51.2 0 1 1 0 102.4 51.2 51.2 0 0 1 0-102.4z" fill="#ADAEB8" p-id="20393"></path></svg>

Before

Width:  |  Height:  |  Size: 623 B

View File

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

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1 +0,0 @@
<?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="1751349783728" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9505" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M838.4 279.466667zM802.133333 814.933333H279.466667c-38.4 0-70.4-32-70.4-70.4V219.733333c0-38.4 32-70.4 70.4-70.4h123.733333c38.4 0 70.4 32 70.4 70.4v339.2h347.733333c2.133333 0-2.133333 0 0 0 25.6-2.133333 51.2 21.333333 51.2 46.933334v136.533333c0 40.533333-32 72.533333-70.4 72.533333z m25.6-179.2c2.133333-29.866667-34.133333-27.733333-34.133333-27.733333H445.866667c-2.133333 0-2.133333-2.133333-4.266667-2.133333h-2.133333c-8.533333-4.266667-12.8-10.666667-12.8-21.333334v-362.666666c0-14.933333-12.8-27.733333-27.733334-27.733334h-117.333333c-14.933333 0-27.733333 12.8-27.733333 27.733334v64h115.2c12.8 0 23.466667 10.666667 23.466666 23.466666 0 12.8-10.666667 23.466667-23.466666 23.466667h-115.2v78.933333h78.933333c12.8 0 23.466667 10.666667 23.466667 23.466667 0 12.8-10.666667 23.466667-23.466667 23.466667h-78.933333v78.933333h115.2c12.8 0 23.466667 10.666667 23.466666 23.466667 0 12.8-10.666667 23.466667-23.466666 23.466666h-115.2v149.333334c0 14.933333 12.8 27.733333 27.733333 27.733333H426.666667v-85.333333c0-12.8 10.666667-25.6 23.466666-25.6 12.8 0 23.466667 10.666667 23.466667 25.6v85.333333h96v-68.266667c0-12.8 10.666667-25.6 23.466667-25.6 12.8 0 23.466667 10.666667 23.466666 25.6V768h78.933334v-85.333333c0-12.8 10.666667-25.6 23.466666-25.6 12.8 0 23.466667 10.666667 23.466667 25.6v85.333333h51.2c14.933333 0 27.733333-12.8 27.733333-27.733333l6.4-104.533334z" p-id="9506"></path></svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

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

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

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

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -26,10 +26,6 @@ Vue.use(VueClipboard)
import permission from './utils/permission'
Vue.use(permission)
import { formatSize, guidToColor } from "./utils"
Vue.prototype.$FormatSize = formatSize
Vue.prototype.$GuidToColor = guidToColor
import Viewer from 'v-viewer'
import './assets/css/viewer.css'
Viewer.setDefaults({
@ -60,10 +56,6 @@ import Preview from '@/components/Preview/index'
Vue.use(Preview)
import Onlyoffice from '@/components/Preview_onlyoffice/index'
Vue.use(Onlyoffice)
import Video from '@/components/Preview_video/index'
Vue.use(Video)
import AGR from '@/components/AGR/index'
Vue.use(AGR)
import MFA from '@/components/MFA/index'
Vue.use(MFA)
import FB from '@/components/feedBack/index'
@ -205,7 +197,6 @@ async function VueInit() {
// 获取版本信息
let PublishInfo = await getCurrentPublishInfo();
Vue.prototype.$version = PublishInfo.Result;
Vue.prototype.$companyInfo = PublishInfo.OtherInfo;
// 获取检查部位
Vue.prototype.$getBodyPart = (id) => {
return new Promise(async (resolve, reject) => {
@ -279,20 +270,6 @@ async function VueInit() {
}
return companyName;
}
Vue.prototype.$reg = () => {
if (localStorage.getItem('CompanyInfo')) {
let { EmailRegexStr } = JSON.parse(localStorage.getItem('CompanyInfo'))
if (EmailRegexStr) {
return { EmailRegexStr }
}
} else if (Vue.prototype.$companyInfo) {
let { EmailRegexStr } = Vue.prototype.$companyInfo
if (EmailRegexStr) {
return { EmailRegexStr }
}
}
return { EmailRegexStr: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$' };
}
Vue.prototype.$updateDictionary = function () {
Vue.prototype.$d = function (code) {
var dictInfo = res.Result
@ -334,9 +311,9 @@ async function VueInit() {
})
}
let CompanyInfo = JSON.parse(localStorage.getItem('CompanyInfo'))
if (CompanyInfo && CompanyInfo.SystemShortName && text.toUpperCase() !== "CIRCLE") {
if(CompanyInfo&&CompanyInfo.SystemShortName){
let test = new RegExp('IRC', 'ig')
text = text.replace(test, CompanyInfo.SystemShortName)
text = text.replace(test, CompanyInfo.SystemShortName)
}
// return i18n.t(key)
return text;

View File

@ -34,7 +34,6 @@ const getters = {
paymentHistoryQuery: state => state.financials.paymentHistoryQuery,
revenusQuery: state => state.financials.revenusQuery,
visitTaskList: state => state.reading.visitTaskList,
BodyPart: state => state.reading.BodyPart,
organList: state => state.reading.organList,
seriesStack: state => state.reading.seriesStack,
activeHangingAgreement: state => state.reading.activeHangingAgreement,
@ -51,8 +50,6 @@ const getters = {
IsFirstSysDocNeedSign: state => state.user.IsFirstSysDocNeedSign,
TrialStatusStr: state => state.user.TrialStatusStr,
lastViewportTaskId: state => state.noneDicomReview.lastViewportTaskId,
currentTaskState: state => state.noneDicomReview.currentTaskState,
operateInfo: state => state.dicom3d.operateInfo,
deleteAnnotationIds: state => state.dicom3d.deleteAnnotationIds
currentTaskState: state => state.noneDicomReview.currentTaskState
}
export default getters

View File

@ -13,7 +13,6 @@ import financials from './modules/financials'
import reading from './modules/reading'
import lang from './modules/lang'
import noneDicomReview from './modules/noneDicomReview'
import dicom3d from './modules/dicom3d'
Vue.use(Vuex)
const store = new Vuex.Store({
@ -29,8 +28,7 @@ const store = new Vuex.Store({
financials,
reading,
lang,
noneDicomReview,
dicom3d
noneDicomReview
},
getters
})

View File

@ -1,28 +0,0 @@
const getDefaultState = () => {
return {
operateInfo: [],
deleteAnnotationIds: []
}
}
const state = getDefaultState
const mutations = {
}
const actions = {
setOperateInfo({ state }, arr) {
state.operateInfo = arr
},
setDeleteAnnotationIds({ state }, arr) {
state.deleteAnnotationIds = arr
},
}
export default {
namespaced: true,
state,
mutations,
actions
}

View File

@ -32,21 +32,13 @@ const getDefaultState = () => {
lastCanvasTaskId: '',
imageQuality: null,
imageQualityIssues: null,
currentLoadIns: [],
BodyPart: []
currentLoadIns: []
}
}
function getQuestions(questions) {
const criterionType = parseInt(localStorage.getItem('CriterionType'))
questions.forEach(item => {
if ((item.Type === 'table' || item.Type === 'basicTable') && item.TableQuestions && item.TableQuestions.Answers.length > 0) {
item.TableQuestions.Questions.forEach(question => {
if (question.Type === 'select' && question.OptionTypeEnum === 1) {
item.TableQuestions.Answers.forEach((answer) => {
answer[question.Id] = answer[question.Id] ? JSON.parse(answer[question.Id]) : []
})
}
})
item.TableQuestions.Answers.forEach(answerObj => {
answerObj.isDicomReading = answerObj.IsDicomReading === 'True'
@ -179,45 +171,6 @@ function getQuestionAnswer(questions, questionMark, answers) {
return ''
}
}
function getQuerys(e) {
if (!e) return "";
var t = {},
r = [],
n = "",
a = "";
try {
var i = [];
if (e.indexOf("?") >= 0 && (i = e.substring(e.indexOf("?") + 1, e.length).split("&")), i.length > 0) for (var o in i) n = (r = i[o].split("="))[0],
a = r[1],
t[n] = a
} catch (s) {
t = {}
}
return t
}
async function getBodyPart(bodyPart, other) {
if (!bodyPart && !other) return ''
var separator = ','
if (bodyPart.indexOf('|') > -1) {
separator = '|'
} else if (bodyPart.indexOf(',') > -1) {
separator = ','
} else if (bodyPart.indexOf('') > -1) {
separator = ''
}
let BodyPart = {}
let query = getQuerys(window.location.href)
BodyPart.Bodypart = await Vue.prototype.$getBodyPart(query.trialId)
var arr = bodyPart.split(separator)
var newArr = arr.map((i) => {
return Vue.prototype.$fd('Bodypart', i.trim(), 'Code', BodyPart, 'Name')
})
if (other) {
newArr.push(other)
}
newArr = newArr.filter(Boolean)
return newArr
}
// function getKeySeriesInfo(keyInstance, series) {
// const obj = {}
// const set = new Set()
@ -897,20 +850,6 @@ const actions = {
var studyList = []
var keyImages = []
getReadingVisitStudyList(obj.trialId, obj.subjectVisitId, obj.visitTaskId).then(res => {
try {
state.BodyPart = []
res.Result.forEach(async item => {
let arr = await getBodyPart(item.BodyPartForEdit, item.BodyPartForEditOther)
state.BodyPart.push({
StudyId: item.StudyId,
StudyCode: item.StudyCode,
BodyPart: arr,
Modalities: item.Modalities
})
})
} catch (err) {
console.log(err)
}
const i = res.Result.findIndex(i => i.IsCriticalSequence)
if (i > -1) {
const seriesList = res.Result[i].SeriesList && res.Result[i].SeriesList

View File

@ -10,8 +10,7 @@ const getDefaultState = () => {
unlock: false,
config: {},
uploadTip: '0.00KB/s',
downloadTip: '0.00KB/s',
downloadSize: '',
uploadSize: '',
timer: null,
whiteList: [],
checkTaskId: null

View File

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

View File

@ -1,346 +0,0 @@
class FileNameSorter {
/**
* 判断是否为纯数字字符串
* @param {any} value - 要检查的值
* @returns {boolean} 是否为纯数字
*/
static isPureNumber(value) {
if (typeof value !== 'string') return false;
return /^\d+$/.test(value);
}
/**
* 获取排序键值
* @param {any} item - 要排序的项目
* @returns {Array} 排序键值数组
*/
static getSortKey(item) {
const str = String(item);
const isNumber = this.isPureNumber(str);
// 排序优先级: [类型优先级, 数字值/字符串值]
if (isNumber) {
// 纯数字: 类型优先级为0, 使用数字值排序
return [0, BigInt(str)];
} else {
// 非纯数字: 类型优先级为1, 使用字符串排序
return [1, str.toLowerCase()];
}
}
/**
* 文件名排序
* @param {Array} arr - 要排序的数组
* @param {Object} options - 排序选项
* @returns {Array} 排序后的数组
*/
static sortFileNames(arr, options = {}) {
if (!Array.isArray(arr)) {
throw new TypeError('输入必须是一个数组');
}
const {
direction = 'asc', // 'asc' 升序, 'desc' 降序
caseSensitive = false, // 是否区分大小写
trim = true, // 是否去除前后空格
key = null
} = options;
// 创建数组的副本
const result = [...arr];
return result.sort((a, b) => {
let aStr = key ? String(a[key]).split(".")[0] : String(a);
let bStr = key ? String(b[key]).split(".")[0] : String(b);
// 处理空格
if (trim) {
aStr = aStr.trim();
bStr = bStr.trim();
}
// 处理大小写
if (!caseSensitive) {
aStr = aStr.toLowerCase();
bStr = bStr.toLowerCase();
}
// 获取排序键值
const aKey = this.getSortKey(aStr);
const bKey = this.getSortKey(bStr);
// 比较类型优先级
if (aKey[0] !== bKey[0]) {
// 纯数字(0) < 非纯数字(1)
return direction === 'asc' ? aKey[0] - bKey[0] : bKey[0] - aKey[0];
}
// 相同类型下的比较
if (aKey[0] === 0) {
// 都是纯数字,按数字大小比较
if (aKey[1] < bKey[1]) return direction === 'asc' ? -1 : 1;
if (aKey[1] > bKey[1]) return direction === 'asc' ? 1 : -1;
return 0;
} else {
// 都是非纯数字,按字符串比较
if (aStr < bStr) return direction === 'asc' ? -1 : 1;
if (aStr > bStr) return direction === 'asc' ? 1 : -1;
return 0;
}
});
}
/**
* 自然排序 - 处理文件名中的数字序列
* 例如: file1, file2, file10
* @param {Array} arr - 要排序的数组
* @param {Object} options - 排序选项
* @returns {Array} 排序后的数组
*/
static naturalSort(arr, options = {}) {
const {
direction = 'asc',
caseSensitive = false
} = options;
return [...arr].sort((a, b) => {
const aStr = String(a);
const bStr = String(b);
// 检查是否都是纯数字
const aIsPureNumber = this.isPureNumber(aStr);
const bIsPureNumber = this.isPureNumber(bStr);
// 如果一个纯数字,一个非纯数字
if (aIsPureNumber && !bIsPureNumber) {
return direction === 'asc' ? -1 : 1;
}
if (!aIsPureNumber && bIsPureNumber) {
return direction === 'asc' ? 1 : -1;
}
// 都是纯数字,按数字比较
if (aIsPureNumber && bIsPureNumber) {
const aNum = BigInt(aStr);
const bNum = BigInt(bStr);
if (aNum < bNum) return direction === 'asc' ? -1 : 1;
if (aNum > bNum) return direction === 'asc' ? 1 : -1;
return 0;
}
// 都是非纯数字,使用自然排序算法
return this.naturalCompare(aStr, bStr, direction, caseSensitive);
});
}
/**
* 自然比较算法
* @private
*/
static naturalCompare(a, b, direction = 'asc', caseSensitive = false) {
let aStr = caseSensitive ? a : a.toLowerCase();
let bStr = caseSensitive ? b : b.toLowerCase();
const regex = /(\d+|\D+)/g;
const aParts = aStr.match(regex) || [];
const bParts = bStr.match(regex) || [];
const maxLength = Math.max(aParts.length, bParts.length);
for (let i = 0; i < maxLength; i++) {
const aPart = aParts[i] || '';
const bPart = bParts[i] || '';
const aIsNumber = /^\d+$/.test(aPart);
const bIsNumber = /^\d+$/.test(bPart);
// 如果都是数字,按数字比较
if (aIsNumber && bIsNumber) {
const aNum = BigInt(aPart);
const bNum = BigInt(bPart);
if (aNum < bNum) return direction === 'asc' ? -1 : 1;
if (aNum > bNum) return direction === 'asc' ? 1 : -1;
continue;
}
// 都是文本,按字符串比较
if (aPart < bPart) return direction === 'asc' ? -1 : 1;
if (aPart > bPart) return direction === 'asc' ? 1 : -1;
}
return 0;
}
/**
* 分组排序 - 将纯数字和非纯数字分开显示
* @param {Array} arr - 要排序的数组
* @param {Object} options - 排序选项
* @returns {Array} 排序后的数组
*/
static groupSort(arr, options = {}) {
const {
direction = 'asc',
groupOrder = 'numbers-first' // 'numbers-first' 或 'names-first'
} = options;
// 分组
const numbers = [];
const names = [];
arr.forEach(item => {
const str = String(item);
if (this.isPureNumber(str)) {
numbers.push(item);
} else {
names.push(item);
}
});
// 对各组排序
const sortedNumbers = this.sortFileNames(numbers, { direction });
const sortedNames = this.sortFileNames(names, { direction });
// 按指定顺序合并
if (groupOrder === 'numbers-first') {
return [...sortedNumbers, ...sortedNames];
} else {
return [...sortedNames, ...sortedNumbers];
}
}
/**
* 文件扩展名排序 - 先按扩展名排序再按文件名排序
* @param {Array} arr - 要排序的数组
* @param {Object} options - 排序选项
* @returns {Array} 排序后的数组
*/
static sortByExtension(arr, options = {}) {
const {
direction = 'asc',
extensionsFirst = false // 扩展名优先还是文件名优先
} = options;
return [...arr].sort((a, b) => {
const aStr = String(a);
const bStr = String(b);
// 分离文件名和扩展名
const getFileParts = (str) => {
const lastDotIndex = str.lastIndexOf('.');
if (lastDotIndex > 0) {
return {
name: str.substring(0, lastDotIndex),
ext: str.substring(lastDotIndex + 1)
};
}
return { name: str, ext: '' };
};
const aParts = getFileParts(aStr);
const bParts = getFileParts(bStr);
let compareResult;
if (extensionsFirst) {
// 先比较扩展名
compareResult = this.sortFileNames([aParts.ext, bParts.ext], { direction })[0] === aParts.ext ? -1 : 1;
if (compareResult !== 0) return compareResult;
// 扩展名相同,再比较文件名
return this.sortFileNames([aParts.name, bParts.name], { direction })[0] === aParts.name ? -1 : 1;
} else {
// 先比较文件名
compareResult = this.sortFileNames([aParts.name, bParts.name], { direction })[0] === aParts.name ? -1 : 1;
if (compareResult !== 0) return compareResult;
// 文件名相同,再比较扩展名
return this.sortFileNames([aParts.ext, bParts.ext], { direction })[0] === aParts.ext ? -1 : 1;
}
});
}
/**
* 测试和演示函数
*/
static demonstrate() {
const testData = [
'100',
'23',
'1',
'003',
'file.txt',
'10',
'5',
'alpha',
'beta',
'gamma',
'00100',
'zebra',
'apple',
'banana',
'123',
'file10.txt',
'file2.txt',
'File1.txt',
'file20.txt',
'image.jpg',
'document.pdf',
'data.xlsx'
];
console.log('=== 文件名排序演示 ===\n');
console.log('原始数据:');
console.log(testData);
console.log('\n1. 基本排序 (纯数字 < 非纯数字):');
const basicSorted = this.sortFileNames(testData);
console.log(basicSorted);
console.log('\n2. 自然排序 (智能数字识别):');
const naturalSorted = this.naturalSort(testData);
console.log(naturalSorted);
console.log('\n3. 分组排序 (数字组和文件组):');
const groupSorted = this.groupSort(testData);
console.log(groupSorted);
console.log('\n4. 降序排序:');
const descSorted = this.sortFileNames(testData, { direction: 'desc' });
console.log(descSorted);
console.log('\n5. 按扩展名排序:');
const extSorted = this.sortByExtension(testData);
console.log(extSorted);
console.log('\n6. 大小写敏感排序:');
const caseSensitiveSorted = this.sortFileNames(testData, { caseSensitive: true });
console.log(caseSensitiveSorted);
// 验证排序规则
console.log('\n=== 排序规则验证 ===');
const validationData = ['100', '23', 'file.txt', '1', 'alpha', '003', '10'];
console.log('验证数据:', validationData);
console.log('排序结果:', this.sortFileNames(validationData));
console.log('规则验证:');
console.log(' - 纯数字: 1, 3(003), 10, 23, 100 (按数字大小)');
console.log(' - 非纯数字: alpha, file.txt (按字母顺序)');
console.log(' - 非纯数字 > 纯数字');
return {
basic: basicSorted,
natural: naturalSorted,
group: groupSorted,
descending: descSorted,
byExtension: extSorted,
caseSensitive: caseSensitiveSorted
};
}
}
if (typeof module !== 'undefined' && module.exports) {
module.exports = FileNameSorter;
} else if (typeof window !== 'undefined') {
window.FileNameSorter = FileNameSorter;
}

View File

@ -15,7 +15,6 @@ export const anonymization = function (file, config) {
let dataset = dcmjs.data.DicomMessage.readFile(buffer)
for (var i = 0; i < AnonymizeFixedList.length; i++) {
let AnonymizeFixed = AnonymizeFixedList[i]
if (!dataset.dict.hasOwnProperty(`${AnonymizeFixed.Group + AnonymizeFixed.Element}`)) continue
if (dataset.dict[AnonymizeFixed.Group + AnonymizeFixed.Element]) {
dataset.dict[AnonymizeFixed.Group + AnonymizeFixed.Element].Value[0] = AnonymizeFixed.ReplaceValue
} else {
@ -29,7 +28,6 @@ export const anonymization = function (file, config) {
}
for (var i = 0; i < AnonymizeNotFixedList.length; i++) {
let AnonymizeNotFixed = AnonymizeNotFixedList[i]
// if (!dataset.dict.hasOwnProperty(`${AnonymizeNotFixed.Group + AnonymizeNotFixed.Element}`)) continue
if (AnonymizeNotFixed.Group + AnonymizeNotFixed.Element === '00100020') {
console.log(`${DicomStoreInfo.TrialCode}_${DicomStoreInfo.SubjectCode}`)
if (dataset.dict[AnonymizeNotFixed.Group + AnonymizeNotFixed.Element]) {
@ -44,7 +42,7 @@ export const anonymization = function (file, config) {
}
} else {
if (dataset.dict[AnonymizeNotFixed.Group + AnonymizeNotFixed.Element]) {
dataset.dict[AnonymizeNotFixed.Group + AnonymizeNotFixed.Element].Value[0] = DicomStoreInfo[AnonymizeNotFixed.ReplaceValue] || Number(DicomStoreInfo[AnonymizeNotFixed.ReplaceValue]) === 0 ? DicomStoreInfo[AnonymizeNotFixed.ReplaceValue].toString() : ''
dataset.dict[AnonymizeNotFixed.Group + AnonymizeNotFixed.Element].Value[0] = DicomStoreInfo[AnonymizeNotFixed.ReplaceValue] ? DicomStoreInfo[AnonymizeNotFixed.ReplaceValue].toString() : ''
} else {
dataset.dict[AnonymizeNotFixed.Group + AnonymizeNotFixed.Element] = {
vr: AnonymizeNotFixed.ValueRepresentation,
@ -55,9 +53,9 @@ export const anonymization = function (file, config) {
}
}
}
// console.log(dataset)
try {
let newDicomFile = dataset.write() // fragmentMultiframe 原始数据是否进行分割
let newDicomFile = dataset.write()
const bufferArray = new Uint8Array(newDicomFile)
const blob = new Blob([bufferArray], { type: 'application/octet-stream' })
resolve({ blob, pixelDataElement })

View File

@ -8508,8 +8508,6 @@
var binaryStream;
var _writeOptions$fragmen = writeOptions.fragmentMultiframe,
fragmentMultiframe = _writeOptions$fragmen === void 0 ? true : _writeOptions$fragmen;
var _writeOptions$offset = writeOptions.startOffset,
isNeedStartOffset = _writeOptions$offset === void 0 ? true : _writeOptions$offset;
value = value === null || value === undefined ? [] : value;
if (isEncapsulated) {
@ -8537,9 +8535,7 @@
for (i = 0; i < frames; i++) {
var _needsPadding = Boolean(value[i].byteLength & 1);
if (isNeedStartOffset) {
startOffset.push(binaryStream.size);
}
startOffset.push(binaryStream.size);
var frameBuffer = value[i],
frameStream = new ReadBufferStream(frameBuffer);
var fragmentsLength = 1;

View File

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

View File

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

View File

@ -50,8 +50,7 @@ service.interceptors.response.use(
const a = document.createElement('a')
// xls类型: application/vnd.ms-excel
// xlsx类型application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8
// const href = URL.createObjectURL(new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8' }))
const href = URL.createObjectURL(new Blob([res], { type: response.headers['content-type'] }))
const href = URL.createObjectURL(new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8' }))
a.download = fileName
a.href = href
a.click()

View File

@ -5,7 +5,6 @@ import router from '@/router'
import WHITELIST from "./whiteList"
import moment from 'moment-timezone';
import { encryptConfig } from "@/utils/encrypt"
import { customAgent } from './fingerprint'
const ROUTER = require('@/router');
axios.defaults.withCredentials = false
const service = axios.create({
@ -27,8 +26,6 @@ service.interceptors.request.use(
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['TimeZoneId'] = moment.tz.guess()
let fingerprint = await customAgent()
config.headers['BrowserFingerprint'] = fingerprint.visitorId
if (config.ENCRYPT) {
try {
config = await encryptConfig(config)

View File

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

View File

@ -1,7 +1,6 @@
import streamSaver from "streamsaver";
import "streamsaver/examples/zip-stream.js";
import store from '@/store'
import dcmjs from './dcmUpload/dcmjs'
streamSaver.mitm = `${window.location.origin}/mitm.html?version=2.0.0`
// 下载文件并压缩
function zipFiles(zipName, files) {
@ -20,10 +19,7 @@ function zipFiles(zipName, files) {
if (fileInfo.done) {//迭代终止
ctrl.close();
} else {
let { name, url, IsEncapsulated = false } = fileInfo.value;
if (IsEncapsulated) {
url = await downloadFileToUrl(url)
}
let { name, url } = fileInfo.value;
// url = decodeUtf8(url); // 待定,可能做过特殊处理
return fetch(url).then(res => {
ctrl.enqueue({
@ -103,24 +99,6 @@ function decodeUtf8(bytes) {
str2.pop();
return str2.join("/") + '/' + name;
}
// 下载文件进行修改并输出本地url
function downloadFileToUrl(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
const arraybuffer = xhr.response;
let dataset = dcmjs.data.DicomMessage.readFile(arraybuffer)
let newDicomFile = dataset.write({ fragmentMultiframe: false, startOffset: false }) // fragmentMultiframe 原始数据是否进行分割
const bufferArray = new Uint8Array(newDicomFile)
const blob = new Blob([bufferArray], { type: 'application/octet-stream' })
const href = URL.createObjectURL(blob)
resolve(href)
};
xhr.send();
})
}
export async function downLoadFile(file, name, type = 'file') {
if (type === 'zip') return await zipFiles(name, file);
return await updateFile(file, name)

View File

@ -179,8 +179,7 @@ export default {
trigger: 'blur',
},
{
// type: 'email',
pattern: new RegExp(this.$reg().EmailRegexStr),
type: 'email',
message: 'Please input the correct email address',
trigger: ['blur'],
},

View File

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

View File

@ -83,36 +83,33 @@
{{ item.description }}
</div>
<div v-if="!item.keySeries" style="padding: 1px;">
{{ item.imageloadedArr.length <= item.instanceCount ? item.imageloadedArr.length :
item.instanceCount }}/{{ item.instanceCount }} </div>
{{ item.imageloadedArr.length }}/{{ item.instanceCount }}
</div>
</div>
<div v-if="showDelete" style="display: flex;flex-direction: row;justify-content: space-between;"
@click.stop="">
<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 * 100">
<el-progress
:percentage="parseInt((item.prefetchInstanceCount / item.instanceCount).toFixed(2))" />
</div>
</div>
<div v-if="showDelete" style="display: flex;flex-direction: row;justify-content: space-between;"
@click.stop="">
<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 * 100">
<el-progress
:percentage="parseInt((item.prefetchInstanceCount / item.instanceCount).toFixed(2))" />
</div>
</div>
</div>
</div>
</el-tab-pane>
</el-tabs>
</div>
@ -197,8 +194,7 @@ export default {
currentLoadIns: [],
isFromCRCUpload: false,
isReading: null,
activeSeriesId: null,
isPacs: false
activeSeriesId: null
}
},
created: function () {
@ -215,9 +211,6 @@ export default {
if (this.$router.currentRoute.query.isReading) {
this.isReading = this.$router.currentRoute.query.isReading
}
if (this.$router.currentRoute.query.isPacs) {
this.isPacs = Boolean(this.$router.currentRoute.query.isPacs)
}
this.studyId = this.$router.currentRoute.query.studyId
this.isFromCRCUpload = !!this.$router.currentRoute.query.isFromCRCUpload
if (this.type === 'Series') {
@ -248,11 +241,7 @@ export default {
},
methods: {
async loadStudy() {
let params = {}
if (this.isPacs) {
params.IsPacs = true
}
const data = await getStudyInfo(this.studyId, params)
const data = await getStudyInfo(this.studyId)
if (data.IsSuccess) {
if (data.Result) {
this.studyCode = data.Result.StudyCode
@ -261,11 +250,6 @@ export default {
this.description = data.Result.Description
}
let isReading = !!this.isReading ? `?IsReading=true` : ''
if (isReading && this.isPacs) {
isReading += `&IsPacs=true`
} else if (!isReading && this.isPacs) {
isReading = `?IsPacs=true`
}
const url = `/series/list/${this.studyId}${isReading}`
this.getSeriesList(url)
}
@ -316,9 +300,7 @@ export default {
loadStatus: false,
imageloadedArr: [],
isExistMutiFrames: item.IsExistMutiFrames,
isShowPopper: false,
subjectCode: item.SubjectCode,
visitName: item.VisitName
isShowPopper: false
})
})
this.seriesList = seriesList
@ -378,9 +360,7 @@ export default {
loadStatus: false,
imageloadedArr: [],
isExistMutiFrames: item.IsExistMutiFrames,
isShowPopper: false,
subjectCode: item.SubjectCode,
visitName: item.VisitName
isShowPopper: false
})
})
this.seriesList = seriesList
@ -450,9 +430,7 @@ export default {
loadStatus: false,
imageloadedArr: [],
isExistMutiFrames: isExistMutiFrames,
isShowPopper: false,
subjectCode: res.OtherInfo.SubjectCode,
visitName: res.OtherInfo.VisitName
isShowPopper: false
})
this.seriesList = seriesList
if (this.seriesList.length > 0) {
@ -538,9 +516,7 @@ export default {
isReading: series.isReading,
isDeleted: series.isDeleted,
previewImageUrl: series.previewImageUrl,
instanceCount: series.instanceCount,
subjectCode: series.SubjectCode,
visitName: series.VisitName
instanceCount: series.instanceCount
}
this.$refs.dicomViewer.loadImageStack(seriesInfo)
if (!series.loadStatus) {
@ -606,9 +582,7 @@ export default {
keySeries: seriesInfo.KeySeries,
loadStatus: false,
imageloadedArr: [],
isShowPopper: false,
subjectCode: seriesInfo.SubjectCode,
visitName: seriesInfo.VisitName
isShowPopper: false
})
this.seriesList = seriesList
if (this.seriesList.length > 0) {
@ -887,14 +861,13 @@ export default {
let file = this.seriesList[seriesIndex].instanceInfoList.find(item => item.ImageId === imageId)
if (file && this.activeSeriesId === this.seriesList[seriesIndex].seriesId) {
getNetWorkSpeed()
setNetWorkSpeedSize(percentComplete, e.detail.total, imageId)
setNetWorkSpeedSize(percentComplete, e.detail.total, imageId)
}
if (prefetchInstanceCount >= instanceCount * 100) {
this.seriesList[seriesIndex].prefetchInstanceCount = instanceCount * 100
//
this.seriesList[seriesIndex].loadStatus = true
workSpeedclose()
localStorage.setItem("QCRiskControl", 1)
if (!this.isFromCRCUpload) {
this.loadAllImages()
}

View File

@ -113,35 +113,35 @@
</div>
</el-tooltip>
<div style="padding: 1px;">
{{ series.imageloadedArr.length <= series.instanceCount ? series.imageloadedArr.length :
series.instanceCount }}/{{ series.instanceCount }} </div>
<div />
{{ series.imageloadedArr.length }}/{{ series.instanceCount }}
</div>
<div />
</div>
<div v-if="showDelete"
style="display: flex;flex-direction: row;justify-content: space-between;" @click.stop="">
</div>
<div v-if="showDelete"
style="display: flex;flex-direction: row;justify-content: space-between;" @click.stop="">
<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>
<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 style="position: absolute;bottom: -10px;left: 0;width: 100%;">
<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 * 100">
<el-progress
:percentage="parseInt((series.prefetchInstanceCount / series.instanceCount).toFixed(2))" />
</div>
<div
v-if="series.prefetchInstanceCount > 0 && series.prefetchInstanceCount < series.instanceCount * 100">
<el-progress
:percentage="parseInt((series.prefetchInstanceCount / series.instanceCount).toFixed(2))" />
</div>
</div>
</el-collapse-item>
</el-collapse>
@ -364,14 +364,11 @@ export default {
try {
let res = null
if (this.page === 'upload') {
res = await getTaskUploadedDicomStudyList({ visitTaskId: this.visitTaskId !== 'undefined' ? this.visitTaskId : null, subjectVisitId: this.subjectVisitId })
}
// else if (this.page === 'download') {
// res = await getVisitStudyList(this.trialId, this.subjectVisitId, this.isReading, this.visitTaskId)
// }
else {
// res = await getVisitStudyList(this.trialId, this.subjectVisitId, this.isReading)
res = await getVisitStudyList(this.trialId, this.subjectVisitId, this.isReading, this.visitTaskId !== 'undefined' ? this.visitTaskId : null)
res = await getTaskUploadedDicomStudyList({ visitTaskId: this.visitTaskId })
} else if (this.page === 'download') {
res = await getVisitStudyList(this.trialId, this.subjectVisitId, this.isReading, this.visitTaskId)
} else {
res = await getVisitStudyList(this.trialId, this.subjectVisitId, this.isReading)
}
if (res.IsSuccess) {
res.Result.forEach((study, studyIndex) => {
@ -420,9 +417,7 @@ export default {
loadStatus: false,
imageloadedArr: [],
isExistMutiFrames: series.IsExistMutiFrames,
isShowPopper: false,
subjectCode: series.SubjectCode,
visitName: series.VisitName
isShowPopper: false
})
})
data.SeriesList = seriesList
@ -523,9 +518,7 @@ export default {
isReading: series.isReading,
isDeleted: series.isDeleted,
previewImageUrl: series.previewImageUrl,
instanceCount: series.instanceCount,
subjectCode: series.SubjectCode,
visitName: series.VisitName
instanceCount: series.instanceCount
}
this.$refs.dicomViewer.loadImageStack(seriesInfo)
if (!series.loadStatus) {
@ -799,9 +792,7 @@ export default {
loadStatus: false,
imageloadedArr: [],
isExistMutiFrames: item.IsExistMutiFrames,
isShowPopper: false,
subjectCode: item.SubjectCode,
visitName: item.VisitName
isShowPopper: false
})
})
// scope.relationStudyList[index].seriesCount = seriesList.length
@ -940,7 +931,6 @@ export default {
this.loadAllImages()
}
workSpeedclose()
localStorage.setItem("QCRiskControl", 1)
}
}
}

View File

@ -10,7 +10,7 @@
<el-form-item :label="$t('dictionary:signature:form:File')">
<div class="upload-container">
<el-upload class="upload-demo" action accept=".pdf,.mp4" :before-upload="beforeUpload"
<el-upload class="upload-demo" action accept=".pdf" :before-upload="beforeUpload"
:http-request="handleUploadFile" :on-preview="handlePreview" :on-remove="handleRemoveFile"
:show-file-list="true" :file-list="fileList" :limit="1" :on-exceed="handleExceed"
:disabled="form.Type === ''">
@ -229,7 +229,7 @@ export default {
this.$message.warning(this.$t('upload:rule:maxFile1'))
},
checkFileSuffix(fileName) {
var typeArr = ['pdf', 'mp4']
var typeArr = ['pdf']
var extendName = fileName
.substring(fileName.lastIndexOf('.') + 1)
.toLocaleLowerCase()

View File

@ -16,7 +16,7 @@
:http-request="handleUploadFile" :on-preview="handlePreview" :on-remove="handleRemoveFile"
:show-file-list="true" :file-list="fileList" :limit="1" :on-exceed="handleExceed">
<el-button size="small" type="primary" :loading="btnLoading">{{ $t('common:button:check')
}}</el-button>
}}</el-button>
<span slot="tip" style="margin-left: 10px" class="el-upload__tip">
({{ $t('trials:signature:label:type').replace("xxx", this.accept.join(", ")) }})
</span>
@ -82,8 +82,7 @@ export default {
'.doc',
'.docx',
'.xls',
'.xlsx',
'.mp4']
'.xlsx']
}
},
mounted() {
@ -173,7 +172,18 @@ export default {
this.$message.warning(this.$t('upload:rule:maxFile1'))
},
checkFileSuffix(fileName) {
var typeArr = this.accept.map(item => item.split('.')[1])
var typeArr = [
'jpg',
'jpeg',
'png',
'pdf',
'ppt',
'pptx',
'doc',
'docx',
'xls',
'xlsx',
]
var extendName = fileName
.substring(fileName.lastIndexOf('.') + 1)
.toLocaleLowerCase()

View File

@ -46,16 +46,16 @@
<!-- 新增/编辑附件 -->
<el-dialog :visible.sync="visible" :close-on-click-modal="false" :append-to-body="true" :title="title"
width="800px" custom-class="base-dialog-wrapper">
<attachmentForm v-if="visible" :data="rowDATA" :SystemDocumentId="SystemDocumentId"
<attachmentForm v-if="visible" :data="rowData" :SystemDocumentId="SystemDocumentId"
@closeDialog="closeDialog" @getList="getAllList" />
</el-dialog>
</template>
</base-model>
<viewer ref="picture_perview2" style="margin: 0 10px"
v-if="rowDATA.FileFormat && ['png', 'jpg', 'jpeg'].includes(rowDATA.FileFormat.toLowerCase())"
:images="[`${OSSclientConfig.basePath}${rowDATA.FilePath}`]" :options="viewerOptions">
v-if="rowData.FileFormat && ['png', 'jpg', 'jpeg'].includes(rowData.FileFormat.toLowerCase())"
:images="[`${OSSclientConfig.basePath}${rowData.FilePath}`]" :options="viewerOptions">
<img v-show="false" :src="`${OSSclientConfig.basePath}${rowDATA.FilePath}`" alt="Image" />
<img v-show="false" :src="`${OSSclientConfig.basePath}${rowData.FilePath}`" alt="Image" />
</viewer>
<!-- <attachmentPreview :SystemDocumentId="SystemDocumentId" :visible.sync="perview_visible"
v-if="perview_visible" /> -->
@ -113,7 +113,7 @@ export default {
visible: false,
title: null,
list: [],
rowDATA: {},
rowData: {},
loading: false,
viewerOptions: {
toolbar: {
@ -167,7 +167,7 @@ export default {
if (!row.Id) {
this.title = this.$t('dictionary:signature:attachmentForm:title:add')
}
this.rowDATA = Object.assign({}, row)
this.rowData = Object.assign({}, row)
this.visible = true
},
async getList() {
@ -207,7 +207,7 @@ export default {
},
preview(data) {
// return this.perview_visible = true
this.rowDATA = Object.assign({}, data)
this.rowData = Object.assign({}, data)
if (['.ppt',
'.pptx',
'.doc',
@ -234,13 +234,6 @@ export default {
title: data.Name,
})
}
if (['.mp4'].includes(`.${data.FileFormat.toLowerCase()}`)) {
this.$video({
path: data.Path || data.FilePath,
type: 'mp4',
title: data.Name,
})
}
},
//
handleSortByColumn(column) {

View File

@ -70,11 +70,10 @@ import ppt from '@/assets/file_icon/ppt.png'
import pptx from '@/assets/file_icon/pptx.png'
import xls from '@/assets/file_icon/xls.png'
import xlsx from '@/assets/file_icon/xlsx.png'
import mp4 from '@/assets/file_icon/mp4.png'
import mp4 from '@/assets/file_icon/xlsx.png'
import PreviewFile from '@/components/PreviewFile'
import imageViewer from './image-viewer'
import { getSystemDocumentAttachmentList } from '@/api/dictionary'
import { getTrialDocumentAttachmentList } from '@/api/trials'
const defaultSearchData = () => {
return {
PageIndex: 1,
@ -102,20 +101,6 @@ export default {
isView: {
type: Boolean,
default: false
},
isTrial: {
type: Boolean,
default: false
},
isExternal: {
type: Boolean,
default: false
},
ExternalList: {
type: Array,
default: () => {
return []
}
}
},
data() {
@ -132,8 +117,7 @@ export default {
rowData: {},
list: [],
searchData: defaultSearchData(),
title: this.$t('dictionary:signature:fileList'),
loading: false
title: this.$t('dictionary:signature:fileList')
}
},
watch: {
@ -142,16 +126,6 @@ export default {
this.getList()
},
immediate: true,
},
isExternal: {
handler() {
if (this.isExternal) {
this.list = this.ExternalList
this.rowData = this.list[0] || {}
this.title = this.$t('dictionary:signature:view')
}
},
immediate: true
}
},
methods: {
@ -166,23 +140,13 @@ export default {
},
async getList() {
try {
if (this.isExternal) return
if (!this.SystemDocumentId) return false
this.loading = true
if (!this.isTrial) {
this.searchData.SystemDocumentId = this.SystemDocumentId
} else {
this.searchData.TrialDocumentId = this.SystemDocumentId
}
this.searchData.SystemDocumentId = this.SystemDocumentId
if (this.isView) {
this.searchData.OffLine = false
}
let res = null
if (!this.isTrial) {
res = await getSystemDocumentAttachmentList(this.searchData)
} else {
res = await getTrialDocumentAttachmentList(this.searchData)
}
let res = await getSystemDocumentAttachmentList(this.searchData)
this.loading = false
if (res.IsSuccess) {
this.list = res.Result.CurrentPageData

View File

@ -1,269 +0,0 @@
<template>
<el-form ref="sysTemplateFrom" v-loading="loading" :model="form" label-width="140px" size="small" :rules="rules"
class="upload-temporary-file">
<div class="base-dialog-body">
<el-form-item :label="$t('dictionary:attachment:label:code')" prop="Code">
<el-input v-model="form.Code" />
</el-form-item>
<el-form-item :label="$t('dictionary:attachment:label:businessScenario')" prop="BusinessScenarioEnum">
<el-select v-model="form.BusinessScenarioEnum" style="width: 100%" size="small" filterable>
<el-option v-for="item of $d.Common_File_BusinessScenario" :key="item.id" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item :label="$t('dictionary:attachment:label:file')">
<div class="upload-container">
<el-upload class="upload-demo" action accept="" :before-upload="beforeUpload" :http-request="handleUploadFile"
:on-preview="handlePreview" :on-remove="handleRemoveFile" :show-file-list="true" :file-list="fileList"
:limit="1" :on-exceed="handleExceed" :disabled="(!form.FileTypeEnum && form.FileTypeEnum !== 0)">
<el-button size="small" type="primary" :disabled="(!form.FileTypeEnum && form.FileTypeEnum !== 0)"
: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="$t('dictionary:attachment:label:name')" prop="Name">
<el-input v-model="form.Name" />
</el-form-item>
<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:label:isDeleted')">
<el-radio-group v-model="form.IsDeleted">
<el-radio v-for="item of $d.YesOrNo" :label="item.value" :key="item.id">{{ item.label }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="$t('dictionary:attachment:label:description')">
<el-input v-model="form.Description" type="textarea" :autosize="{ minRows: 2, maxRows: 4 }" />
</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.FileTypeEnum !== 0)"
: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'
export default {
name: 'TemplateForm',
props: {
data: {
type: Object,
default() {
return {}
},
},
},
data() {
return {
form: {
Id: '',
Code: '',
FileTypeEnum: 0,
BusinessScenarioEnum: null,
Name: '',
NameCN: '',
Path: '',
Description: '',
IsDeleted: false,
},
rules: {
Code: [
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: ['blur'] },
],
Name: [
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: ['blur'] },
],
NameCN: [
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: ['blur'] },
],
BusinessScenarioEnum: [
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: ['blur'] },
],
},
fileList: [],
btnLoading: false,
saveBtnLoading: false,
loading: false,
dictionaryList: {},
}
},
mounted() {
this.initForm()
},
methods: {
async initForm() {
await this.getDicData()
if (Object.keys(this.data).length > 0) {
if (this.data.Path) {
this.fileList = [
{
name: this.data.Name,
path: this.data.Path,
url: this.data.Path,
type: this.data.Type,
},
]
}
for (const k in this.form) {
if (this.data.hasOwnProperty(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
})
},
beforeUpload(file) {
//
if (this.checkFileSuffix(file.name)) {
this.fileList = []
return true
} else {
this.$alert(this.$t('dictionary:attachment:export:alert:formatFile'))
return false
}
},
async handleUploadFile(param) {
this.loading = true
this.form.FileName = param.file.name
let extendName = param.file.name
.substring(param.file.name.lastIndexOf('.'))
.toLocaleLowerCase()
let file = await this.fileToBlob(param.file)
let res = await this.OSSclient.put(`/System/Tools/${this.$guid()}${extendName}`, file)
this.form.Path = this.$getObjectName(res.url)
this.form.NameCN = param.file.name
this.fileList.push({
name: param.file.name,
path: this.form.Path,
fullPath: this.form.Path,
url: this.form.Path,
})
this.loading = false
this.btnLoading = false
// Upload(formData, 1).then((res) => {
// this.fileList.push({
// name: param.file.name,
// path: res.Result.FilePath,
// fullPath: res.Result.FullFilePath,
// url: res.Result.FilePath,
// })
// })
},
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)
})
},
handleSave() {
this.$refs.sysTemplateFrom.validate((valid) => {
if (!valid) return
if (!this.form.Name) {
this.$alert(this.$t('dictionary:attachment:message:msg1'))
return
}
this.saveBtnLoading = true
addOrUpdateCommonDocument(this.form)
.then((res) => {
this.saveBtnLoading = false
this.$emit('closeDialog')
this.$emit('getList')
this.$message.success(this.$t('common:message:savedSuccessfully'))
})
.catch(() => {
this.saveBtnLoading = false
})
})
},
handleRemoveFile() {
this.fileList = []
this.form.Path = ''
this.form.NameCN = ''
this.form.Name = ''
},
handlePreview(file) {
if (file.fullPath) {
window.open(file.fullPath, '_blank')
}
},
handleExceed(files, fileList) {
this.$message.warning(this.$t('upload:rule:maxFile1'))
},
checkFileSuffix(fileName) {
return true
var typeArr = ['xls', 'xlsx', 'doc', 'docx']
var extendName = fileName
.substring(fileName.lastIndexOf('.') + 1)
.toLocaleLowerCase()
if (typeArr.indexOf(extendName) !== -1) {
return true
} else {
return false
}
},
},
}
</script>
<style lang="scss">
.upload-temporary-file {
.upload-container .el-upload--text {
border: none;
width: 80px;
height: 40px;
}
.upload-container .el-input--small {
margin-bottom: 5px;
}
.upload-container .el-icon-circle-check {
color: #428bca;
font-size: 13px;
}
.account_item_clear {
.el-tag__close {
display: none !important;
}
}
}
</style>

View File

@ -1,238 +0,0 @@
<template>
<BaseContainer>
<template slot="search-container">
<el-form :inline="true" size="small">
<!-- 业务场景 -->
<el-form-item :label="$t('dictionary:attachment:label:businessScenario')">
<el-select v-model="searchData.BusinessScenarioEnum" style="width: 150px">
<el-option v-for="item of $d.Common_File_BusinessScenario" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<!-- 文件名称 -->
<el-form-item :label="$t('dictionary:attachment:label:name')">
<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') }}
</el-button>
<!-- 重置 -->
<el-button type="primary" icon="el-icon-refresh-left" @click="handleReset">
{{ $t('common:button:reset') }}
</el-button>
</el-form-item>
<el-button type="primary" style="float: right" size="small" @click="handleAdd">
{{ $t('common:button:new') }}
</el-button>
</el-form>
</template>
<template slot="main-container">
<el-table v-adaptive="{ bottomOffset: 60 }" v-loading="loading" :data="list" stripe height="100"
@sort-change="handleSortChange">
<el-table-column type="index" width="40" />
<el-table-column prop="Code" :label="$t('dictionary:attachment:label:code')" show-overflow-tooltip
sortable="custom" />
<!-- 业务场景 -->
<el-table-column prop="BusinessScenarioEnum" :label="$t('dictionary:attachment:label:businessScenario')"
show-overflow-tooltip sortable="custom">
<template slot-scope="scope">
{{
$fd(
'Common_File_BusinessScenario',
scope.row.BusinessScenarioEnum
)
}}
</template>
</el-table-column>
<!-- 文件名称 -->
<el-table-column prop="Name" :label="$t('dictionary:attachment:label:name')" show-overflow-tooltip
sortable="custom" />
<el-table-column prop="NameCN" :label="$t('dictionary:attachment:upload:table:nameCN')" show-overflow-tooltip
sortable="custom" />
<!-- 描述 -->
<el-table-column prop="Description" :label="$t('dictionary:attachment:label:description')"
show-overflow-tooltip />
<!-- 是否废除 -->
<el-table-column prop="IsDeleted" :label="$t('dictionary:attachment:label: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>
</template>
</el-table-column>
<!-- 上传时间 -->
<el-table-column prop="UpdateTime" :label="$t('dictionary:attachment:label:updateTime')" show-overflow-tooltip
sortable="custom" />
<el-table-column :label="$t('common:action:action')" width="300">
<template slot-scope="scope">
<!-- <el-button type="text" @click="PreviewFile(scope.row)">
{{ $t('common:button:preview') }}
</el-button> -->
<el-button type="text" @click="handleDownload(scope.row)">
{{ $t('common:button:download') }}
</el-button>
<el-button type="text" @click="handleEdit(scope.row)">
{{ $t('common:button:edit') }}
</el-button>
<el-button type="text" @click="handleDelete(scope.row)">
{{ $t('common:button:delete') }}
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
@pagination="getList" />
<!-- 新增/编辑 -->
<el-dialog v-if="editDialog.visible" :visible.sync="editDialog.visible" :close-on-click-modal="false"
:title="editDialog.title" width="600px" custom-class="base-dialog-wrapper">
<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'
import { downLoadFile } from '@/utils/stream.js'
const FileTypeEnum = 0
const searchDataDefault = () => {
return {
FileTypeEnum: FileTypeEnum,
BusinessScenarioEnum: null,
Name: '',
PageIndex: 1,
PageSize: 20,
}
}
export default {
name: 'ToolsTemplate',
components: { BaseContainer, Pagination, TemplateForm },
data() {
return {
searchData: searchDataDefault(),
list: [],
total: 0,
currentRow: {},
editDialog: { title: '', visible: false },
loading: false,
}
},
mounted() {
this.getList()
},
computed: {
isEN() {
return this.$i18n.locale !== 'zh'
},
},
methods: {
handleDelete(row) {
//
this.$confirm(this.$t('dictionary:attachment:message:msg1')).then(() => {
deleteCommonDocument(row.Id).then(() => {
this.$message.success(this.$t('common:message:deletedSuccessfully'))
this.getList()
})
}).catch(() => { })
},
PreviewFile(row) {
let basePath = window.location.origin
if (window.location.protocol !== 'https:') {
basePath = 'https://irc.test.extimaging.com'
}
let data = {
name: row.NameCN,
path: basePath + row.Path,
}
this.$emit('PreviewFile', data)
},
getList() {
this.loading = true
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 = this.$t('common:button:new')
this.currentRow = { FileTypeEnum: FileTypeEnum }
this.editDialog.visible = true
},
//
async handleDownload(row) {
try {
this.loading = true
let fileName = this.isEN ? row.Name : row.NameCN;
let type = fileName
.substring(fileName.lastIndexOf('.'))
.toLocaleLowerCase()
if (!type) {
let extendName = row.Path
.substring(row.Path.lastIndexOf('.'))
.toLocaleLowerCase()
fileName += extendName
}
let res = await downLoadFile(this.OSSclientConfig.basePath + row.Path, fileName)
this.loading = false
} catch (err) {
this.loading = false
}
},
//
handleEdit(row) {
this.editDialog.title = this.$t('common:button:edit')
this.currentRow = { ...row }
this.editDialog.visible = true
},
handleSearch() {
this.searchData.PageIndex = 1
this.getList()
},
handleReset() {
this.searchData = searchDataDefault()
this.getList()
},
closeDialog() {
this.editDialog.visible = false
},
//
handleSortChange(column) {
if (column.order === 'ascending') {
this.searchData.Asc = true
} else {
this.searchData.Asc = false
}
this.searchData.SortField = column.prop
this.searchData.PageIndex = 1
this.getList()
},
},
}
</script>
<style lang="scss" scoped>
::v-deep .search {
display: block;
}
</style>

View File

@ -1,22 +1,52 @@
<template>
<div class="attachment-wrapper">
<el-tabs v-model="activeTab" @tab-click="clickTab">
<el-tab-pane v-for="item in $d.Common_File_Type" :key="item.value" :label="item.label" :name="String(item.value)">
<UploadTemplate v-if="activeTab === '1' && item.value == activeTab" @PreviewFile="PreviewFile" />
<ExportTemplate v-if="activeTab === '2' && item.value == activeTab" @PreviewFile="PreviewFile" />
<el-tab-pane
v-for="item in $d.Common_File_Type"
:key="item.value"
:label="item.label"
:name="String(item.value)"
>
<UploadTemplate
v-if="activeTab === '1' && item.value == activeTab"
@PreviewFile="PreviewFile"
/>
<ExportTemplate
v-if="activeTab === '2' && item.value == activeTab"
@PreviewFile="PreviewFile"
/>
<EmailTemplate v-if="activeTab === '3' && item.value == activeTab" />
<CommonTemplate v-if="activeTab === '4' && item.value == activeTab" />
<SignatureTemplate v-if="activeTab === '5' && item.value == activeTab" />
<ToolsTemplate v-if="activeTab === '0' && item.value == activeTab" />
<SignatureTemplate
v-if="activeTab === '5' && item.value == activeTab"
/>
</el-tab-pane>
</el-tabs>
<!-- 预览 -->
<el-dialog v-if="Preview.visible" :visible.sync="Preview.visible" :close-on-click-modal="false" :fullscreen="true"
:title="Preview.title" width="600px" custom-class="base-dialog-wrapper">
<vue-office-docx v-if="docxTypes.includes(Preview.type)" :src="Preview.path" style="height: calc(100vh - 70px)"
@rendered="renderedHandler" @error="errorHandler" />
<vue-office-excel v-else-if="excelTypes.includes(Preview.type)" :src="Preview.path" :options="options"
style="height: calc(100vh - 70px)" @rendered="renderedHandler" @error="errorHandler" />
<el-dialog
v-if="Preview.visible"
:visible.sync="Preview.visible"
:close-on-click-modal="false"
:fullscreen="true"
:title="Preview.title"
width="600px"
custom-class="base-dialog-wrapper"
>
<vue-office-docx
v-if="docxTypes.includes(Preview.type)"
:src="Preview.path"
style="height: calc(100vh - 70px)"
@rendered="renderedHandler"
@error="errorHandler"
/>
<vue-office-excel
v-else-if="excelTypes.includes(Preview.type)"
:src="Preview.path"
:options="options"
style="height: calc(100vh - 70px)"
@rendered="renderedHandler"
@error="errorHandler"
/>
<PreviewFile v-else :file-path="Preview.path" :file-type="Preview.type" />
</el-dialog>
</div>
@ -27,7 +57,6 @@ import ExportTemplate from './components/ExportTemplate'
import EmailTemplate from './components/EmailTemplate'
import CommonTemplate from './components/CommonTemplate'
import SignatureTemplate from './components/SignatureTemplate'
import ToolsTemplate from './components/ToolsTemplate'
import VueOfficeDocx from '@vue-office/docx'
import '@vue-office/docx/lib/index.css'
import VueOfficeExcel from '@vue-office/excel'
@ -44,7 +73,6 @@ export default {
VueOfficeDocx,
VueOfficeExcel,
PreviewFile,
ToolsTemplate
},
data() {
return {
@ -114,18 +142,16 @@ export default {
display: flex;
flex-direction: column;
}
.el-tabs__header {
height: 40px;
margin-bottom: 5px;
}
.el-tabs__content {
flex: 1;
.el-tab-pane {
height: 100%;
}
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -7,28 +7,74 @@
<el-button type="primary" size="mini" @click="handleAdd"></el-button>
</span>
</div>
<el-table v-loading="loading" v-adaptive="{ bottomOffset: 45 }" :data="list" stripe size="small" height="100"
@sort-change="handleSortByColumn">
<el-table
v-loading="loading"
v-adaptive="{bottomOffset:45}"
:data="list"
stripe
size="small"
height="100"
>
<el-table-column type="index" width="60" />
<el-table-column v-if="!~$route.path.indexOf('select')" prop="Code" label="字典键值" min-width="180"
show-overflow-tooltip sortable='custom' />
<el-table-column prop="ValueCN" label="中文值" min-width="180" show-overflow-tooltip sortable='custom' />
<el-table-column prop="Value" label="英文值" min-width="180" show-overflow-tooltip sortable='custom' />
<el-table-column prop="ChildGroup" label="分组" min-width="180" show-overflow-tooltip sortable='custom' />
<el-table-column prop="ShowOrder" label="显示顺序" min-width="180" show-overflow-tooltip sortable='custom' />
<el-table-column prop="Description" label="描述" min-width="180" show-overflow-tooltip sortable='custom' />
<el-table-column
v-if="!~$route.path.indexOf('select')"
prop="Code"
label="字典键值"
min-width="180"
show-overflow-tooltip
/>
<el-table-column
prop="ValueCN"
label="中文值"
min-width="180"
show-overflow-tooltip
/>
<el-table-column
prop="Value"
label="英文值"
min-width="180"
show-overflow-tooltip
/>
<el-table-column
prop="ChildGroup"
label="分组"
min-width="180"
show-overflow-tooltip
/>
<el-table-column
prop="ShowOrder"
label="显示顺序"
min-width="180"
show-overflow-tooltip
/>
<el-table-column
prop="Description"
label="描述"
min-width="180"
show-overflow-tooltip
/>
<el-table-column label="是否可用" width="100" fixed="right">
<template slot-scope="scope">
<el-switch v-model="scope.row.IsEnable" :active-value="true" :inactive-value="false"
@change="(event) => { return switchChange(event, scope.row) }" />
<el-switch
v-model="scope.row.IsEnable"
:active-value="true"
:inactive-value="false"
@change="(event) => {return switchChange(event, scope.row)}"
/>
</template>
</el-table-column>
<el-table-column label="操作" width="150" fixed="right">
<template slot-scope="scope">
<el-button type="text" @click="handleEdit(scope.row)">
<el-button
type="text"
@click="handleEdit(scope.row)"
>
编辑
</el-button>
<el-button type="text" @click="handleDelete(scope.row)">
<el-button
type="text"
@click="handleDelete(scope.row)"
>
删除
</el-button>
</template>
@ -45,8 +91,7 @@ import DictionaryChildAddOrUpdateForm from './DictionaryChildAddOrUpdateForm'
const searchDataDefault = () => {
return {
Asc: true,
SortField: 'ShowOrder',
parentId: ''
}
}
export default {
@ -76,17 +121,6 @@ export default {
this.getList()
},
methods: {
//
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()
},
handleChild(row) {
this.drawerChild = true
this.getDictionaryChildList(row.Id)
@ -138,8 +172,7 @@ export default {
//
getList() {
this.loading = true
this.searchData.ParentId = this.parent.Id
getDictionaryChildList(this.searchData).then(res => {
getDictionaryChildList(this.parent.Id).then(res => {
this.loading = false
this.list = res.Result
}).catch(() => { this.loading = false })
@ -157,4 +190,6 @@ export default {
}
</script>
<style scoped></style>
<style scoped>
</style>

View File

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

View File

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

View File

@ -43,7 +43,6 @@
:data="list"
stripe
height="100"
@sort-change="handleSortByColumn"
>
<el-table-column type="index" width="60" />
<!-- Group -->
@ -51,7 +50,6 @@
prop="Group"
:label="$t('template:anonymization:label:group')"
show-overflow-tooltip
sortable="custom"
/>
<!-- Element -->
<el-table-column
@ -59,28 +57,24 @@
:label="$t('template:anonymization:label:element')"
show-overflow-tooltip
min-width="110"
sortable="custom"
/>
<!-- Tag Description -->
<el-table-column
prop="TagDescription"
:label="$t('template:anonymization:label:tagDescription')"
min-width="110"
sortable="custom"
/>
<!-- Tag DescriptionCN -->
<el-table-column
prop="TagDescriptionCN"
:label="$t('template:anonymization:label:tagDescriptionCN')"
min-width="110"
sortable="custom"
/>
<!-- Value Representation -->
<el-table-column
prop="ValueRepresentation"
:label="$t('template:anonymization:label:valueRepresentation')"
min-width="110"
sortable="custom"
/>
<!-- Is Fixed -->
<el-table-column :label="$t('template:anonymization:label:isFixed')" width="100">
@ -98,7 +92,6 @@
prop="ReplaceValue"
:label="$t('template:anonymization:label:valueReplace')"
min-width="110"
sortable="custom"
/>
<!-- Is Enable -->
<el-table-column :label="$t('template:anonymization:label:isEnable')" width="100" fixed="right">
@ -146,9 +139,7 @@ const searchDataDefault = () => {
IsAdd: false,
TagDescriptionCN: '',
PageIndex: 1,
PageSize: 500,
Asc: false,
SortField: ''
PageSize: 500
}
}
export default {
@ -168,17 +159,6 @@ export default {
this.getList()
},
methods: {
//
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()
},
switchChange(event, item) {
this.loading = true
addOrUpdateSystemAnonymization(item).then(res => {

View File

@ -5,81 +5,151 @@
</div>
<div>
<!-- 配置 -->
<el-button size="mini" type="primary" :disabled="isCompleteConfig" @click="handleAdd"
style="margin-right: 10px;">
<el-button
size="mini"
type="primary"
:disabled="isCompleteConfig"
@click="handleAdd"
style="margin-right: 10px;"
>
{{ $t('dictionary:template:criterionDictionary:button:config') }}
</el-button>
</div>
</div>
<el-table v-loading="loading" style="width: 100%" :data="list" stripe>
<el-table
v-loading="loading"
style="width: 100%"
:data="list"
stripe
>
<!-- 序号 -->
<el-table-column prop="" label="" width="50">
<el-table-column
prop=""
label=""
width="50"
>
<template slot-scope="scope">
{{ scope.$index + 1 }}
{{scope.$index + 1}}
</template>
</el-table-column>
<!-- 字典表名 -->
<el-table-column prop="Code" :label="$t('dictionary:template:criterionDictionary:table:code')"
show-overflow-tooltip>
<el-table-column
prop="Code"
:label="$t('dictionary:template:criterionDictionary:table:code')"
show-overflow-tooltip
>
</el-table-column>
<!-- 描述 -->
<el-table-column prop="Description" :label="$t('dictionary:template:criterionDictionary:table:description')"
show-overflow-tooltip>
<el-table-column
prop="Description"
:label="$t('dictionary:template:criterionDictionary:table:description')"
show-overflow-tooltip
>
</el-table-column>
<!-- 子项数量 -->
<el-table-column prop="Count" :label="$t('dictionary:template:criterionDictionary:table:count')"
show-overflow-tooltip>
<el-table-column
prop="Count"
:label="$t('dictionary:template:criterionDictionary:table:count')"
show-overflow-tooltip
>
</el-table-column>
<!-- 排序 -->
<el-table-column prop="ShowOrder" :label="$t('dictionary:template:criterionDictionary:table:showOrder')"
show-overflow-tooltip>
<el-table-column
prop="ShowOrder"
:label="$t('dictionary:template:criterionDictionary:table:showOrder')"
show-overflow-tooltip
>
</el-table-column>
<!-- 操作 -->
<el-table-column prop="Description" :label="$t('common:action:action')" show-overflow-tooltip>
<el-table-column
prop="Description"
:label="$t('common:action:action')"
show-overflow-tooltip
>
<template slot-scope="scope">
<!-- 配置 -->
<el-button type="text" @click="openChildren(scope.row)">
<el-button :disabled="isCompleteConfig" type="text" @click="openChildren(scope.row)">
{{ $t('dictionary:template:criterionDictionary:button:config') }}
</el-button>
<!-- 删除 -->
<el-button type="text" :disabled="isCompleteConfig" @click="handleDelete(scope.row)">
<el-button
type="text"
:disabled="isCompleteConfig"
@click="handleDelete(scope.row)"
>
{{ $t('common:button:delete') }}
</el-button>
</template>
</el-table-column>
</el-table>
<el-drawer :title="drawer_cfg.title" :append-to-body="true" :modal-append-to-body="false"
:visible.sync="drawer_cfg.drawerChild" direction="rtl" size="80%">
<CriterionDictionaryConfig v-if="drawer_cfg.drawerChild" @getList="getList" :isCompleteConfig="isCompleteConfig"
:criterionId="criterionId" :parentCode="drawer_cfg.title"></CriterionDictionaryConfig>
<el-drawer
:title="drawer_cfg.title"
:append-to-body="true"
:modal-append-to-body="false"
:visible.sync="drawer_cfg.drawerChild"
direction="rtl"
size="80%"
>
<CriterionDictionaryConfig v-if="drawer_cfg.drawerChild" @getList="getList" :criterionId="criterionId" :parentCode="drawer_cfg.title"></CriterionDictionaryConfig>
</el-drawer>
<el-drawer :title="drawer_cfg2.title" :append-to-body="true" :modal-append-to-body="false"
:visible.sync="drawer_cfg2.drawerChild" direction="rtl" size="80%">
<el-drawer
:title="drawer_cfg2.title"
:append-to-body="true"
:modal-append-to-body="false"
:visible.sync="drawer_cfg2.drawerChild"
direction="rtl"
size="80%"
>
<div style="text-align: right;">
<el-button size="mini" type="primary" @click="handleSave" v-loading="loading">
{{ $t('common:button:save') }}
<el-button
size="mini"
type="primary"
@click="handleSave"
v-loading="loading"
>
{{ $t('common:button:save')}}
</el-button>
</div>
<el-table v-loading="loading" v-adaptive="{ bottomOffset: 0 }" height="100" ref="multipleTable" style="width: 100%"
:data="dicList" stripe @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55">
<el-table
v-loading="loading"
v-adaptive="{bottomOffset:0}"
height="100"
ref="multipleTable"
style="width: 100%"
:data="dicList"
stripe
@selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column width="55">
<el-table-column
width="55">
<template slot-scope="scope">
{{ scope.$index + 1 }}
{{ scope.$index + 1}}
</template>
</el-table-column>
<!-- 字典表名 -->
<el-table-column prop="Code" :label="$t('dictionary:template:criterionDictionary:table:code')"
show-overflow-tooltip>
<el-table-column
prop="Code"
:label="$t('dictionary:template:criterionDictionary:table:code')"
show-overflow-tooltip
>
</el-table-column>
<!-- 描述 -->
<el-table-column prop="Description" :label="$t('dictionary:template:criterionDictionary:table:description')"
show-overflow-tooltip>
<el-table-column
prop="Description"
:label="$t('dictionary:template:criterionDictionary:table:description')"
show-overflow-tooltip
>
</el-table-column>
<!-- 排序 -->
<el-table-column prop="ShowOrder" :label="$t('dictionary:template:criterionDictionary:table:showOrder')"
show-overflow-tooltip>
<el-table-column
prop="ShowOrder"
:label="$t('dictionary:template:criterionDictionary:table:showOrder')"
show-overflow-tooltip
>
</el-table-column>
</el-table>
</el-drawer>
@ -194,7 +264,7 @@ export default {
this.loading = true
//
this.$confirm(this.$t('template:criterionDictionary:message:msg1')).then(() => {
deleteSystemCriterionDictionary({ Id: row.Id }).then(res => {
deleteSystemCriterionDictionary({Id: row.Id}).then(res => {
this.$message.success(this.$t('common:message:deletedSuccessfully'))
this.loading = false
this.getList()
@ -207,7 +277,7 @@ export default {
</script>
<style lang="scss" scoped>
::v-deep .el-form-item__content {
::v-deep .el-form-item__content{
width: calc(100% - 110px);
}
</style>

View File

@ -4,74 +4,134 @@
<div>
</div>
<div>
<el-button size="mini" type="primary" @click="handleAdd" style="margin-right: 10px;" v-if="!isCompleteConfig">
<el-button
size="mini"
type="primary"
@click="handleAdd"
style="margin-right: 10px;"
>
{{ $t('dictionary:template:criterionDictionary:button:config') }}
</el-button>
</div>
</div>
<el-table v-loading="loading" v-adaptive="{ bottomOffset: 0 }" height="100" style="width: 100%" :data="list" stripe>
<el-table-column prop="" label="" width="50">
<el-table
v-loading="loading"
v-adaptive="{bottomOffset:0}"
height="100"
style="width: 100%"
:data="list"
stripe
>
<el-table-column
prop=""
label=""
width="50"
>
<template slot-scope="scope">
{{ scope.$index + 1 }}
{{scope.$index + 1}}
</template>
</el-table-column>
<!-- 键值 -->
<el-table-column prop="Code" :label="$t('dictionary:template:criterionDictionary:table:code')"
show-overflow-tooltip />
<el-table-column
prop="Code"
:label="$t('dictionary:template:criterionDictionary:table:code')"
show-overflow-tooltip
/>
<!-- 中文值 -->
<el-table-column prop="ValueCN" :label="$t('dictionary:template:criterionDictionary:table:valueCN')"
show-overflow-tooltip>
<el-table-column
prop="ValueCN"
:label="$t('dictionary:template:criterionDictionary:table:valueCN')"
show-overflow-tooltip
>
</el-table-column>
<!-- 英文值 -->
<el-table-column prop="Value" :label="$t('dictionary:template:criterionDictionary:table:value')"
show-overflow-tooltip>
<el-table-column
prop="Value"
:label="$t('dictionary:template:criterionDictionary:table:value')"
show-overflow-tooltip
>
</el-table-column>
<!-- 描述 -->
<el-table-column prop="Description" :label="$t('dictionary:template:criterionDictionary:table:description')"
show-overflow-tooltip>
<el-table-column
prop="Description"
:label="$t('dictionary:template:criterionDictionary:table:description')"
show-overflow-tooltip
>
</el-table-column>
<!-- 分组 -->
<el-table-column prop="Description" :label="$t('dictionary:template:criterionDictionary:table:group')"
show-overflow-tooltip>
<el-table-column
prop="Description"
:label="$t('dictionary:template:criterionDictionary:table:group')"
show-overflow-tooltip
>
<template slot-scope="scope">
<div v-if="!isCompleteConfig">
<el-radio-group v-model="scope.row.CrterionDictionaryGroup"
@change="(v) => { crterionDictionaryGroupChange(v, scope.row) }" size="mini">
<el-radio-button v-for="item of $d.CrterionDictionaryGroup" :label="item.value" :key="item.id">{{
item.label }}</el-radio-button>
<div>
<el-radio-group v-model="scope.row.CrterionDictionaryGroup" @change="(v) => {crterionDictionaryGroupChange(v, scope.row)}" size="mini">
<el-radio-button v-for="item of $d.CrterionDictionaryGroup" :label="item.value" :key="item.id">{{item.label}}</el-radio-button>
</el-radio-group>
</div>
<div v-else>{{ $fd('CrterionDictionaryGroup', scope.row.CrterionDictionaryGroup) }}</div>
</template>
</el-table-column>
</el-table>
<el-dialog v-if="config.visible" :visible.sync="config.visible" :close-on-click-modal="false" :title="config.title"
width="90%" append-to-body>
<el-dialog
v-if="config.visible"
:visible.sync="config.visible"
:close-on-click-modal="false"
:title="config.title"
width="90%"
append-to-body
>
<div>
<div style="text-align: right;">
<el-button size="mini" type="primary" @click="handleSave" v-loading="loading">
{{ $t('common:button:save') }}
<el-button
size="mini"
type="primary"
@click="handleSave"
v-loading="loading"
>
{{ $t('common:button:save')}}
</el-button>
</div>
<el-table v-loading="loading" v-adaptive="{ bottomOffset: 100 }" height="100" ref="multipleTable"
:data="$d[parentCode]" stripe @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55">
<el-table
v-loading="loading"
v-adaptive="{bottomOffset:100}"
height="100"
ref="multipleTable"
:data="$d[parentCode]"
stripe
@selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
width="55">
</el-table-column>
<!-- 键值 -->
<el-table-column prop="raw.Code" :label="$t('dictionary:template:criterionDictionary:table:code')"
show-overflow-tooltip>
<el-table-column
prop="raw.Code"
:label="$t('dictionary:template:criterionDictionary:table:code')"
show-overflow-tooltip
>
</el-table-column>
<!-- 中文值 -->
<el-table-column prop="raw.ValueCN" :label="$t('dictionary:template:criterionDictionary:table:valueCN')"
show-overflow-tooltip>
<el-table-column
prop="raw.ValueCN"
:label="$t('dictionary:template:criterionDictionary:table:valueCN')"
show-overflow-tooltip
>
</el-table-column>
<!-- 英文值 -->
<el-table-column prop="raw.Value" :label="$t('dictionary:template:criterionDictionary:table:value')"
show-overflow-tooltip>
<el-table-column
prop="raw.Value"
:label="$t('dictionary:template:criterionDictionary:table:value')"
show-overflow-tooltip
>
</el-table-column>
<!-- 描述 -->
<el-table-column prop="raw.Description"
:label="$t('dictionary:template:criterionDictionary:table:description')" show-overflow-tooltip>
<el-table-column
prop="raw.Description"
:label="$t('dictionary:template:criterionDictionary:table:description')"
show-overflow-tooltip
>
</el-table-column>
</el-table>
</div>
@ -90,10 +150,6 @@ export default {
parentCode: {
type: String,
required: true
},
isCompleteConfig: {
type: Boolean,
default: false
}
},
data() {
@ -122,7 +178,7 @@ export default {
this.loading = false
this.$message.success(this.$t('common:message:savedSuccessfully'))
this.getList()
}).catch(() => { this.loading = false })
}).catch(() => {this.loading = false})
},
toggleSelection(rows) {
console.log(this.$refs.multipleTable)
@ -184,7 +240,7 @@ export default {
</script>
<style lang="scss" scoped>
::v-deep .el-form-item__content {
::v-deep .el-form-item__content{
width: calc(100% - 110px);
}
</style>

View File

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

View File

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

View File

@ -43,7 +43,6 @@
:data="list"
stripe
height="100"
@sort-change="handleSortByColumn"
>
<el-table-column type="index" width="60" />
<!-- Group -->
@ -51,7 +50,6 @@
prop="Group"
:label="$t('template:anonymization:label:group')"
show-overflow-tooltip
sortable="custom"
/>
<!-- Element -->
<el-table-column
@ -59,28 +57,24 @@
:label="$t('template:anonymization:label:element')"
show-overflow-tooltip
min-width="110"
sortable="custom"
/>
<!-- Tag Description -->
<el-table-column
prop="TagDescription"
:label="$t('template:anonymization:label:tagDescription')"
min-width="110"
sortable="custom"
/>
<!-- Tag DescriptionCN -->
<el-table-column
prop="TagDescriptionCN"
:label="$t('template:anonymization:label:tagDescriptionCN')"
min-width="110"
sortable="custom"
/>
<!-- Value Representation -->
<el-table-column
prop="ValueRepresentation"
:label="$t('template:anonymization:label:valueRepresentation')"
min-width="110"
sortable="custom"
/>
<!-- Is Fixed -->
<el-table-column :label="$t('template:anonymization:label:isFixed')" width="100">
@ -98,7 +92,6 @@
prop="ReplaceValue"
:label="$t('template:anonymization:label:valueReplace')"
min-width="110"
sortable="custom"
/>
<!-- Is Enable -->
<el-table-column :label="$t('template:anonymization:label:isEnable')" width="100" fixed="right">
@ -145,9 +138,7 @@ const searchDataDefault = () => {
TagDescriptionCN: '',
IsAdd: true,
PageIndex: 1,
PageSize: 500,
Asc: false,
SortField: ''
PageSize: 500
}
}
export default {
@ -167,17 +158,6 @@ export default {
this.getList()
},
methods: {
//
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()
},
switchChange(event, item) {
this.loading = true
addOrUpdateSystemAnonymization(item).then(res => {

View File

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

View File

@ -30,13 +30,13 @@
<el-form-item
:label="$t('trials:auditRecord:table:criterion')"
>
<el-select v-model="searchData.CriterionTypeEnum" clearable>
<el-select v-model="searchData.CriterionTypeEnum">
<el-option v-for="item of $d.CriterionType" :key="item.id" :value="item.value" :label="item.label" />
</el-select>
</el-form-item>
<!-- 是否通用 -->
<el-form-item :label="$t('dictionary:medicalAudit:label:IsGeneral')">
<el-select v-model="searchData.IsGeneral" clearable>
<el-select v-model="searchData.IsGeneral">
<el-option v-for="item of $d.YesOrNo" :key="item.id" :value="item.value" :label="item.label" />
</el-select>
</el-form-item>
@ -51,9 +51,6 @@
>
{{ $t('common:button:reset') }}
</el-button>
<el-button type="primary" @click="handleExport">
{{ $t('common:button:export') }}
</el-button>
</el-form-item>
</el-form>
<span style="margin-left:auto">
@ -69,7 +66,6 @@
:data="list"
stripe
height="100"
@sort-change="handleSortByColumn"
>
<!-- 序号 -->
<el-table-column
@ -83,7 +79,6 @@
:label="$t('trials:MIMqcCfg:table:questionName')"
show-overflow-tooltip
min-width="140"
sortable="custom"
/>
<!-- 审核问题 -->
<el-table-column
@ -91,7 +86,6 @@
:label="$t('common:title:languageType')"
show-overflow-tooltip
min-width="160"
sortable="custom"
>
<template slot-scope="scope">
{{ $fd('LanguageType', scope.row.LanguageType) }}
@ -103,7 +97,6 @@
:label="$t('trials:qcCfg:table:type')"
show-overflow-tooltip
min-width="140"
sortable="custom"
>
<template slot-scope="scope">
{{ $fd('QcType', scope.row.Type) }}
@ -115,7 +108,6 @@
:label="$t('trials:qcCfg:table:typeValue')"
show-overflow-tooltip
min-width="140"
sortable="custom"
/>
<!-- 任务类型 -->
<el-table-column
@ -123,7 +115,6 @@
:label="$t('trials:medicalFeedbackCfg:title:taskType')"
show-overflow-tooltip
min-width="140"
sortable="custom"
>
<template slot-scope="scope">
<el-tag v-if="scope.row.ReadingCategory === 1" type="primary">
@ -145,7 +136,6 @@
:label="$t('trials:auditRecord:table:criterion')"
min-width="160"
show-overflow-tooltip
sortable="custom"
>
<template slot-scope="scope">
<div>
@ -158,7 +148,6 @@
:label="$t('dictionary:medicalAudit:label:IsGeneral')"
min-width="120"
show-overflow-tooltip
sortable="custom"
>
<template slot-scope="scope">
<div>
@ -172,7 +161,6 @@
:label="$t('trials:qcCfg:table:parentQs')"
show-overflow-tooltip
min-width="140"
sortable="custom"
/>
<!-- 父问题触发值 -->
<el-table-column
@ -180,14 +168,12 @@
:label="$t('trials:qcCfg:table:parentTriggerValue')"
show-overflow-tooltip
min-width="160"
sortable="custom"
/>
<!-- 是否必填 -->
<el-table-column
prop="IsRequired"
:label="$t('trials:qcCfg:table:isRequired')"
min-width="120"
sortable="custom"
>
<template slot-scope="scope">
{{ $fd('YesOrNo', scope.row.IsRequired) }}
@ -198,7 +184,6 @@
prop="IsEnable"
:label="$t('trials:qcCfg:table:isEnable')"
min-width="120"
sortable="custom"
>
<template slot-scope="scope">
{{ $fd('YesOrNo', scope.row.IsEnable) }}
@ -230,7 +215,7 @@
</template>
<script>
import { getReadingMedicineSystemQuestionList, deleteReadingMedicineSystemQuestion } from '@/api/dictionary'
import { GetReadingMedicineSystemQuestionList_Export } from '@/api/export'
import BoxContent from '@/components/BoxContent'
import Pagination from '@/components/Pagination'
import MedicalAuditForm from './MedicalAuditForm'
@ -243,9 +228,7 @@ const searchDataDefault = () => {
LanguageType: null,
Type: '',
CriterionTypeEnum: null,
IsGeneral: null,
Asc: false,
SortField: ''
IsGeneral: null
}
}
export default {
@ -265,20 +248,6 @@ export default {
this.getList()
},
methods: {
async handleExport() {
await GetReadingMedicineSystemQuestionList_Export(this.searchData)
},
//
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()
},
//
getList() {
this.loading = true

View File

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

View File

@ -1,5 +1,12 @@
<template>
<el-form ref="emailForm" v-loading="loading" :model="form" label-width="180px" size="small" :rules="rules">
<el-form
ref="emailForm"
v-loading="loading"
:model="form"
label-width="180px"
size="small"
:rules="rules"
>
<el-row>
<el-col :span="24">
<!-- Code -->
@ -22,7 +29,12 @@
<el-col :span="12">
<!-- 邮件延时发送s数 -->
<el-form-item :label="$t('dictionary:email:label:emailDelaySeconds')" prop="EmailDelaySeconds">
<el-input v-model.number="form.EmailDelaySeconds" style="width: 300px" type="number" clearable>
<el-input
v-model.number="form.EmailDelaySeconds"
style="width: 300px"
type="number"
clearable
>
</el-input>
</el-form-item>
</el-col>
@ -30,8 +42,12 @@
<!-- 业务层级 -->
<el-form-item :label="$t('dictionary:email:label:businessLevel')" prop="BusinessLevelEnum">
<el-select v-model="form.BusinessLevelEnum" clearable class="mr">
<el-option v-for="item of $d.BusinessLevel" :key="`BusinessLevel${item.label}`" :label="item.label"
:value="item.value" />
<el-option
v-for="item of $d.BusinessLevel"
:key="`BusinessLevel${item.label}`"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
@ -39,8 +55,12 @@
<!-- 业务模块 -->
<el-form-item :label="$t('dictionary:email:label:businessModule')" prop="BusinessModuleEnum">
<el-select v-model="form.BusinessModuleEnum" clearable class="mr">
<el-option v-for="item of $d.BusinessModule" :key="`BusinessModule${item.label}`" :label="item.label"
:value="item.value" />
<el-option
v-for="item of $d.BusinessModule"
:key="`BusinessModule${item.label}`"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
@ -48,46 +68,80 @@
<!-- 业务场景 -->
<el-form-item :label="$t('trials:emailManageCfg:table:BusinessScenarioEnum')" prop="BusinessScenarioEnum">
<el-select v-model="form.BusinessScenarioEnum" clearable class="mr">
<el-option v-for="item of $d.Email_BusinessScenario" :key="`BusinessScenarioEnum${item.label}`"
:label="item.label" :value="item.value" />
<el-option
v-for="item of $d.Email_BusinessScenario"
:key="`BusinessScenarioEnum${item.label}`"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<!-- 收件人 -->
<el-form-item :label="$t('trials:emailManageCfg:title:toUserTypeList')" prop="ToUserTypeList">
<el-select v-model="form.ToUserTypeList" clearable multiple class="mr">
<el-option v-for="item of $d.UserType" :key="`ToUserTypeList${item.label}`" :label="item.label"
:value="item.value" />
<el-select
v-model="form.ToUserTypeList"
clearable
multiple
class="mr"
>
<el-option
v-for="item of $d.UserType"
:key="`ToUserTypeList${item.label}`"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<!-- 抄送人 -->
<el-form-item :label="$t('trials:emailManageCfg:title:copyUserTypeList')" prop="CopyUserTypeList">
<el-select v-model="form.CopyUserTypeList" clearable multiple class="mr">
<el-option v-for="item of $d.UserType" :key="`CopyUserTypeList${item.label}`" :label="item.label"
:value="item.value" />
<el-select
v-model="form.CopyUserTypeList"
clearable
multiple
class="mr"
>
<el-option
v-for="item of $d.UserType"
:key="`CopyUserTypeList${item.label}`"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<!-- 加急状态 -->
<el-form-item :label="$t('dictionary:email:label:IsUrgent')" prop="EmailUrgentEnum">
<el-select v-model="form.EmailUrgentEnum" @change="
(v) => {
v === 1 ? (form.EmailCron = null) : null
}
" clearable class="mr">
<el-option v-for="item of $d.EmailUrgent" :key="`EmailUrgent${item.label}`" :label="item.label"
:value="item.value" />
<el-select
v-model="form.EmailUrgentEnum"
@change="
(v) => {
v === 1 ? (form.EmailCron = null) : null
}
"
clearable
class="mr"
>
<el-option
v-for="item of $d.EmailUrgent"
:key="`EmailUrgent${item.label}`"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<!-- 发送周期和时间 -->
<el-form-item :label="$t('trials:emailManageCfg:table:EmailCron')" v-if="form.EmailUrgentEnum !== 1"
prop="EmailCron">
<el-form-item
:label="$t('trials:emailManageCfg:table:EmailCron')"
v-if="form.EmailUrgentEnum !== 1"
prop="EmailCron"
>
<el-input style="width: 300px" readonly v-model="form.EmailCron" />
<!-- 生成 cron -->
<el-button type="primary" @click="showDialog"> {{ $t('dictionary:email:button:cron') }} </el-button>
@ -97,8 +151,12 @@
<!-- 是否需要回执 -->
<el-form-item :label="$t('trials:emailManageCfg:title:isReturnRequired')" prop="IsReturnRequired">
<el-radio-group v-model="form.IsReturnRequired">
<el-radio v-for="item of $d.YesOrNo" :label="item.value" :key="`IsReturnRequired${item.value}`">{{
item.label }}</el-radio>
<el-radio
v-for="item of $d.YesOrNo"
:label="item.value"
:key="`IsReturnRequired${item.value}`"
>{{ item.label }}</el-radio
>
</el-radio-group>
</el-form-item>
</el-col>
@ -106,30 +164,48 @@
<!-- 是否自动发送 -->
<el-form-item :label="$t('trials:emailManageCfg:table:IsAutoSend')" prop="IsAutoSend">
<el-radio-group v-model="form.IsAutoSend">
<el-radio v-for="item of $d.YesOrNo" :label="item.value" :key="`IsAutoSend${item.value}`">{{ item.label
}}</el-radio>
<el-radio
v-for="item of $d.YesOrNo"
:label="item.value"
:key="`IsAutoSend${item.value}`"
>{{ item.label }}</el-radio
>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12" v-if="systemLevel">
<!-- 是否区分标准 -->
<el-form-item :label="$t('dictionary:email:button:isDistinguishCriteria')" prop="IsDistinguishCriteria">
<el-radio-group v-model="form.IsDistinguishCriteria" @change="
() => {
form.CriterionTypeEnum = null
}
">
<el-radio v-for="item of $d.YesOrNo" :label="item.value" :key="`IsDistinguishCriteria${item.value}`">{{
item.label }}</el-radio>
<el-radio-group
v-model="form.IsDistinguishCriteria"
@change="
() => {
form.CriterionTypeEnum = null
}
"
>
<el-radio
v-for="item of $d.YesOrNo"
:label="item.value"
:key="`IsDistinguishCriteria${item.value}`"
>{{ item.label }}</el-radio
>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="$t('trials:auditRecord:table:criterion')" v-if="form.IsDistinguishCriteria"
prop="CriterionTypeList">
<el-select v-model="form.CriterionTypeList" clearable class="mr" multiple>
<el-option v-for="item of $d.CriterionType" :key="`CriterionType${item.label}`" :label="item.label"
:value="item.value" />
<el-form-item
:label="$t('trials:auditRecord:table:criterion')"
v-if="form.IsDistinguishCriteria"
prop="CriterionTypeEnum"
>
<el-select v-model="form.CriterionTypeEnum" clearable class="mr">
<el-option
v-for="item of $d.CriterionType"
:key="`CriterionType${item.label}`"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
@ -137,65 +213,106 @@
<!-- 是否启用 -->
<el-form-item :label="$t('trials:emailManageCfg:table:IsEnable')" prop="IsEnable">
<el-radio-group v-model="form.IsEnable">
<el-radio v-for="item of $d.YesOrNo" :label="item.value" :key="`IsEnable${item.value}`">{{ item.label
}}</el-radio>
<el-radio
v-for="item of $d.YesOrNo"
:label="item.value"
:key="`IsEnable${item.value}`"
>{{ item.label }}</el-radio
>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<!-- 附件CN -->
<el-form-item :label="$t('trials:emailManageCfg:table:fileListCN')" prop="IsEnable">
<el-upload class="upload-demo" action :before-upload="beforeUploadCN" :http-request="handleUploadFileCN"
:on-preview="handlePreviewCN" :on-remove="handleRemoveFileCN" :show-file-list="true" :limit="1"
:file-list="fileListCN">
<el-button size="small" type="primary" :disabled="fileListCN.length > 0">{{ $t('common:button:upload')
}}</el-button>
<el-upload
class="upload-demo"
action
:before-upload="beforeUploadCN"
:http-request="handleUploadFileCN"
:on-preview="handlePreviewCN"
:on-remove="handleRemoveFileCN"
:show-file-list="true"
:limit="1"
:file-list="fileListCN"
>
<el-button
size="small"
type="primary"
:disabled="fileListCN.length > 0"
>{{ $t('common:button:upload') }}</el-button
>
</el-upload>
</el-form-item>
</el-col>
<el-col :span="12">
<!-- 附件EN -->
<el-form-item :label="$t('trials:emailManageCfg:table:fileListEN')" prop="IsEnable">
<el-upload class="upload-demo" action :before-upload="beforeUploadEN" :http-request="handleUploadFileEN"
:on-preview="handlePreviewEN" :on-remove="handleRemoveFileEN" :show-file-list="true" :limit="1"
:file-list="fileListEN">
<el-button size="small" type="primary" :disabled="fileListEN.length > 0">{{ $t('common:button:upload')
}}</el-button>
<el-upload
class="upload-demo"
action
:before-upload="beforeUploadEN"
:http-request="handleUploadFileEN"
:on-preview="handlePreviewEN"
:on-remove="handleRemoveFileEN"
:show-file-list="true"
:limit="1"
:file-list="fileListEN"
>
<el-button
size="small"
type="primary"
:disabled="fileListEN.length > 0"
>{{ $t('common:button:upload') }}</el-button
>
</el-upload>
</el-form-item>
</el-col>
</el-row>
<!-- 邮件内容模版CN -->
<el-form-item :label="$t('dictionary:email:label:emailHtmlContentCN')" prop="EmailHtmlContentCN"
style="position: relative">
<div class="html_temp">
<prism-editor class="my-editor" v-model="form.EmailHtmlContentCN" :highlight="highlighter" :line-numbers="true"
style="width: 50%;max-height: 500px;"></prism-editor>
<div v-html="form.EmailHtmlContentCN" style="width: 50%;"></div>
</div>
<!-- <el-input v-model="form.EmailHtmlContentCN" type="textarea" :autosize="{ minRows: 8, maxRows: 8 }" />
<el-button :disabled="!form.EmailHtmlContentCN && form.EmailHtmlContent" type="text"
<el-form-item
:label="$t('dictionary:email:label:emailHtmlContentCN')"
prop="EmailHtmlContentCN"
style="position: relative"
>
<el-input
v-model="form.EmailHtmlContentCN"
type="textarea"
:autosize="{ minRows: 8, maxRows: 8 }"
/>
<el-button
:disabled="!form.EmailHtmlContentCN && form.EmailHtmlContent"
type="text"
@click="PreviewHTML(form.EmailHtmlContentCN, form.EmailHtmlContent)"
style="position: absolute; left: -50px; top: 30px">
style="position: absolute; left: -50px; top: 30px"
>
{{ $t('common:button:preview') }}
</el-button> -->
</el-button>
</el-form-item>
<!-- 邮件内容模版EN -->
<el-form-item :label="$t('dictionary:email:label:emailHtmlContent')" prop="EmailHtmlContent"
style="position: relative">
<div class="html_temp">
<prism-editor class="my-editor" v-model="form.EmailHtmlContent" :highlight="highlighter" :line-numbers="true"
style="width: 50%;max-height: 500px;"></prism-editor>
<div v-html="form.EmailHtmlContent" style="width: 50%;"></div>
</div>
<!-- <el-input v-model="form.EmailHtmlContent" type="textarea" :autosize="{ minRows: 8, maxRows: 8 }" />
<el-button :disabled="!form.EmailHtmlContentCN && form.EmailHtmlContent" type="text"
<el-form-item
:label="$t('dictionary:email:label:emailHtmlContent')"
prop="EmailHtmlContent"
style="position: relative"
>
<el-input
v-model="form.EmailHtmlContent"
type="textarea"
:autosize="{ minRows: 8, maxRows: 8 }"
/>
<el-button
:disabled="!form.EmailHtmlContentCN && form.EmailHtmlContent"
type="text"
@click="PreviewHTML(form.EmailHtmlContentCN, form.EmailHtmlContent)"
style="position: absolute; left: -50px; top: 30px">
style="position: absolute; left: -50px; top: 30px"
>
{{ $t('common:button:preview') }}
</el-button> -->
</el-button>
</el-form-item>
<div class="base-dialog-footer" style="text-align: right; margin-top: 10px; padding-bottom: 10px">
<div
class="base-dialog-footer"
style="text-align: right; margin-top: 10px; padding-bottom: 10px"
>
<el-form-item style="text-align: right">
<el-button size="small" type="primary" @click="handleSave">
{{ $t('common:button:save') }}
@ -204,7 +321,12 @@
</div>
<!-- 生成 cron -->
<el-dialog append-to-body :title="$t('dictionary:email:button:cron')" :visible.sync="showCron">
<vcrontab :hideComponent="['year']" @hide="showCron = false" @fill="crontabFill" :expression="expression">
<vcrontab
:hideComponent="['year']"
@hide="showCron = false"
@fill="crontabFill"
:expression="expression"
>
</vcrontab>
</el-dialog>
</el-form>
@ -212,14 +334,6 @@
<script>
import { Upload, addOrUpdateEmailNoticeConfigList } from '@/api/dictionary'
import vcrontab from 'vcrontab'
import { PrismEditor } from 'vue-prism-editor';
import 'vue-prism-editor/dist/prismeditor.min.css';
import { highlight, languages } from 'prismjs/components/prism-core';
import 'prismjs/components/prism-clike';
import 'prismjs/components/prism-javascript';
import 'prismjs/themes/prism.css';
export default {
props: {
data: {
@ -241,7 +355,7 @@ export default {
},
},
},
components: { vcrontab, PrismEditor },
components: { vcrontab },
data() {
return {
expression: '',
@ -271,7 +385,6 @@ export default {
IsAutoSend: true,
CriterionTypeEnum: null,
EmailDelaySeconds: null,
CriterionTypeList: []
},
rules: {
Code: [{ required: true, message: this.$t('common:ruleMessage:select'), trigger: ['blur'] }],
@ -302,8 +415,8 @@ export default {
EmailHtmlContent: [
{ required: true, message: this.$t('common:ruleMessage:select'), trigger: ['blur'] },
],
CriterionTypeList: [
{ required: true, type: 'array', message: this.$t('common:ruleMessage:select'), trigger: ['blur'] },
CriterionTypeEnum: [
{ required: true, message: this.$t('common:ruleMessage:select'), trigger: ['blur'] },
],
},
scenarioOption: [],
@ -327,9 +440,6 @@ export default {
}
},
methods: {
highlighter(code) {
return highlight(code, languages.js);
},
showDialog() {
this.expression = this.form.EmailCron // cron UI
this.showCron = true
@ -453,13 +563,3 @@ export default {
},
}
</script>
<style lang="scss" scoped>
.html_temp {
display: flex;
.my-editor {
border: 1px solid #333;
}
}
</style>

View File

@ -9,11 +9,11 @@
</el-select>
</el-form-item>
<!-- 是否加急 -->
<!-- <el-form-item :label="$t('dictionary:email:label:IsUrgent')" v-if="!systemLevel">
<el-form-item :label="$t('dictionary:email:label:IsUrgent')" v-if="!systemLevel">
<el-select v-model="searchData.IsUrgent" clearable style="width: 100px">
<el-option v-for="item of $d.YesOrNo" :value="item.value" :label="item.label" :key="item.id" />
</el-select>
</el-form-item> -->
</el-form-item>
<!-- 是否启用 -->
<el-form-item :label="$t('trials:emailManageCfg:table:IsEnable')" v-if="!systemLevel">
<el-select v-model="searchData.IsEnable" clearable style="width: 100px">
@ -41,8 +41,7 @@
<el-option v-for="item of UserTypeList" :value="item.value" :label="item.label" :key="item.id" />
</el-select>
</el-form-item>
<!--v-if="systemLevel === 1"-->
<el-form-item :label="$t('trials:emailManageCfg:form:EmailUrgent')">
<el-form-item :label="$t('trials:emailManageCfg:form:EmailUrgent')" v-if="systemLevel === 1">
<el-select v-model="searchData.EmailUrgentEnum" clearable style="width: 100px">
<el-option v-for="item of $d.EmailUrgent" :value="item.value" :label="item.label" :key="item.id" />
</el-select>
@ -68,26 +67,20 @@
<el-button type="primary" @click="handleAdd">
{{ $t('common:button:new') }}
</el-button>
<el-button type="primary" @click="openDrawer" :disabled="multipleSelection.length <= 0">
{{ $t('trials:emailManageCfg:button:batchAudit') }}
</el-button>
</el-form-item>
</el-form>
</div>
<!-- 受试者列表 -->
<el-table v-loading="loading" v-adaptive="{ bottomOffset: 45 }" :data="list" stripe height="100" style="width: 100%"
@sort-change="handleSortByColumn" @selection-change="handleSelectionChange">
<!-- <el-table-column type="index" width="40" /> -->
<el-table-column type="selection" width="55">
</el-table-column>
@sort-change="handleSortByColumn">
<el-table-column type="index" width="40" />
<!-- Code -->
<el-table-column prop="Code" :label="$t('trials:emailManageCfg:title:code')" sortable="custom"
show-overflow-tooltip min-width="100" />
<el-table-column v-if="isDistinguishCriteria" prop="TrialReadingCriterionId"
:label="$t('trials:reviewTrack:table:criterionName')" show-overflow-tooltip sortable="custom" min-width="120">
<template slot-scope="scope">
{{scope.row.CriterionTypeList ? scope.row.CriterionTypeList.map(item => $fd('CriterionType', item)).join(', ')
: ''}}
{{ $fd('CriterionType', scope.row.CriterionTypeEnum) }}
</template>
</el-table-column>
<!-- 邮件主题中文 -->
@ -256,76 +249,12 @@
</div>
</div>
</el-dialog>
<el-drawer :title="$t('trials:emailManageCfg:title:audit')" :visible.sync="drawer" direction="rtl" size="80%">
<!-- <div style="width: 800px">
<el-form label-width="100px" @submit.native.prevent size="small" :inline="true" class="demo-form-inline">
<el-form-item :label="$t('il8n:search:keyword')">
<el-input v-model="key" @input="keyChange" />
</el-form-item>
<el-form-item :label="$t('il8n:search:state')">
<el-select v-model="State" clearable filterable @change="handleStateChange">
<el-option v-for="item of $d.InternationalizationKeyState"
:key="'InternationalizationKeyState' + item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</el-form>
</div> -->
<el-table :data="tableData" v-adaptive="{ bottomOffset: 50 }" height="100" style="width: 100%"
@sort-change="handleSortByColumnDrawer">
<!-- Code -->
<el-table-column prop="Code" :label="$t('trials:emailManageCfg:title:code')" sortable="custom"
show-overflow-tooltip min-width="100" />
<el-table-column v-if="isDistinguishCriteria" prop="TrialReadingCriterionId"
:label="$t('trials:reviewTrack:table:criterionName')" show-overflow-tooltip sortable="custom" min-width="120">
<template slot-scope="scope">
{{ $fd('CriterionType', scope.row.CriterionTypeEnum) }}
</template>
</el-table-column>
<!-- 邮件主题中文 -->
<el-table-column prop="EmailTopicCN" :label="$t('trials:emailManageCfg:table:EmailTopicCN')" sortable="custom"
show-overflow-tooltip min-width="160">
<template slot-scope="scope">
<el-input v-model="scope.row.EmailTopicCN" @input="
(e) => {
$set(scope.row, 'EmailTopicCN', e)
}
" size="mini"></el-input>
</template>
</el-table-column>
<!-- 邮件主题英文 -->
<el-table-column prop="EmailTopic" :label="$t('trials:emailManageCfg:table:EmailTopic')" sortable="custom"
show-overflow-tooltip min-width="160">
<template slot-scope="scope">
<el-input v-model="scope.row.EmailTopic" @input="
(e) => {
$set(scope.row, 'EmailTopic', e)
}
" size="mini"></el-input>
</template>
</el-table-column>
<!-- 业务层级 -->
<el-table-column prop="BusinessLevelEnum" :label="$t('dictionary:email:label:businessLevel')" sortable="custom"
show-overflow-tooltip min-width="150">
<template slot-scope="scope">
{{ $fd('BusinessLevel', scope.row.BusinessLevelEnum) }}
</template>
</el-table-column>
</el-table>
<div style="text-align: right; padding-top: 10px; padding-right: 10px">
<el-button size="mini" @click="drawer = false">{{ $t('common:button:cancel') }}
</el-button>
<el-button size="mini" type="primary" @click="handleSave">{{
$t('common:button:save')
}}</el-button>
</div>
</el-drawer>
</box-content>
</template>
<script>
import {
getEmailNoticeConfigList,
deleteEmailNoticeConfig,
batchUpdateEmail
} from '@/api/dictionary'
import { GetEmailNoticeConfigList_Export } from '@/api/export'
import BoxContent from '@/components/BoxContent'
@ -379,9 +308,6 @@ export default {
previewVisible: false,
previewHTML: null,
previewHTMLEN: null,
multipleSelection: [],
drawer: false,
tableData: []
}
},
computed: {
@ -399,50 +325,6 @@ export default {
this.getList()
},
methods: {
async handleSave() {
try {
let arr = []
this.tableData.forEach(item => {
let obj = {
EmailTopic: item.EmailTopic,
EmailTopicCN: item.EmailTopicCN,
Id: item.Id
}
arr.push(obj)
})
this.drawer = false
let res = await batchUpdateEmail(arr)
if (res.IsSuccess) {
this.$message.success(this.$t('trials:emailManageCfg:message:auditSuccess'))
this.getList()
}
} catch (err) {
console.log(err)
}
},
//
handleSortByColumnDrawer(column) {
if (column.order === 'ascending') {
this.tableData.sort((a, b) =>
a[column.prop].localeCompare(b[column.prop])
)
} else {
this.tableData.sort((a, b) =>
b[column.prop].localeCompare(a[column.prop])
)
}
},
openDrawer() {
this.tableData = []
this.multipleSelection.forEach(item => {
let obj = Object.assign({}, item)
this.tableData.push(obj)
})
this.drawer = true
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
//
getList() {
this.loading = true

View File

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

View File

@ -164,14 +164,6 @@ export default {
},
},
],
Email: [
{
// type: 'email',
pattern: new RegExp(this.$reg().EmailRegexStr),
message: this.$t('rules:email'),
trigger: 'blur,change',
},
]
},
userId: null,
loading: false,

View File

@ -21,19 +21,13 @@
<el-form-item :label="$t('trials:researchForm:form:verifyCode')" required>
<el-col :span="18">
<el-form-item prop="VerificationCode">
<div style="display: flex;justify-content: space-between;">
<el-input v-model="form.VerificationCode" autocomplete="off" />
<el-button size="small" class="codeBtn" :disabled="sendDisabled" @click="handleSendCode"
style="width: 30%;margin-left: 10px;">
{{ sendTitle }}
</el-button>
</div>
<el-input v-model="form.VerificationCode" autocomplete="off" />
</el-form-item>
</el-col>
<!-- <el-col :span="6" style="text-align: right">
</el-col> -->
<el-col :span="6" style="text-align: right">
<el-button size="small" type="primary" style="width: 80%" :disabled="sendDisabled"
@click="handleSendCode">{{ sendTitle }}</el-button>
</el-col>
</el-form-item>
</el-form>
<!-- 校验 -->
@ -131,9 +125,6 @@ export default {
} else {
var reg =
/^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/
if (this.$reg().EmailRegexStr) {
reg = new RegExp(this.$reg().EmailRegexStr)
}
if (this.form.EmailOrPhone && reg.test(this.form.EmailOrPhone)) {
this.sendDisabled = false
callback()
@ -387,21 +378,6 @@ export default {
/*::v-deep .is-error{*/
/* margin-bottom: 40px;*/
/*}*/
.codeBtn {
color: #409EFF;
border-color: #409EFF;
}
.codeBtn.is-disabled,
.codeBtn.is-disabled:focus,
.codeBtn.is-disabled:hover {
color: #c0c4cc;
cursor: not-allowed;
background-image: none;
background-color: #fff;
border-color: #ebeef5;
}
.is-error.my_new_pwd {
margin-bottom: 45px;
}

View File

@ -7,13 +7,20 @@
<div class="login-l">
<div class="login-logo">
<img v-if="language === 'zh'" src="@/assets/zzlogo2.png" alt="" />
<img v-else-if="NODE_ENV === 'usa'" src="@/assets/zzlogo-usa.png" alt="" class="usa-logo" />
<img
v-else-if="NODE_ENV === 'usa'"
src="@/assets/zzlogo-usa.png"
alt=""
class="usa-logo"
/>
<img v-else src="@/assets/zzlogo4.png" alt="" />
</div>
<div :class="{
'login-image': true,
'login-image-usa': true,
}">
<div
:class="{
'login-image': true,
'login-image-usa': true,
}"
>
<svg-icon icon-class="login-bg" style="width: 90%; height: 90%" />
<!-- <img src="@/assets/login-bg.png" v-else /> -->
</div>
@ -22,43 +29,77 @@
<div class="title-container">
<!-- IRC Management System -->
<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 class="title" v-else>{{ $t('login:title:system') }}</div>
</div>
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on"
label-position="left">
<el-form-item prop="username" :rules="[
{
required: true,
message: this.$t('login:formRule:userName'),
trigger: 'blur',
},
]">
<el-form
ref="loginForm"
:model="loginForm"
:rules="loginRules"
class="login-form"
auto-complete="on"
label-position="left"
>
<el-form-item
prop="username"
:rules="[
{
required: true,
message: this.$t('login:formRule:userName'),
trigger: 'blur',
},
]"
>
<span class="svg-container">
<svg-icon icon-class="user" />
</span>
<!-- User Name -->
<el-input ref="username" v-model="loginForm.username" size="small" :placeholder="$t('login:form:userName')"
name="username" type="text" tabindex="1" />
<el-input
ref="username"
v-model="loginForm.username"
size="small"
:placeholder="$t('login:form:userName')"
name="username"
type="text"
tabindex="1"
/>
</el-form-item>
<el-form-item prop="password" :rules="[
{
required: true,
message: this.$t('login:formRule:password'),
trigger: 'blur',
},
]">
<el-form-item
prop="password"
:rules="[
{
required: true,
message: this.$t('login:formRule:password'),
trigger: 'blur',
},
]"
>
<span class="svg-container">
<svg-icon icon-class="password" />
</span>
<!-- password -->
<el-input :key="passwordType" ref="password" v-model="loginForm.password" size="small" :type="passwordType"
:placeholder="$t('login:form:password')" name="password" auto-complete="new-password"
autocomplete="new-password" tabindex="2" @keyup.enter.native="handleLogin" />
<el-input
:key="passwordType"
ref="password"
v-model="loginForm.password"
size="small"
:type="passwordType"
:placeholder="$t('login:form:password')"
name="password"
auto-complete="new-password"
autocomplete="new-password"
tabindex="2"
@keyup.enter.native="handleLogin"
/>
<span class="show-pwd" @click="showPwd">
<svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
<svg-icon
:icon-class="passwordType === 'password' ? 'eye' : 'eye-open'"
/>
</span>
<!-- <el-input
:key="passwordType"
@ -77,29 +118,33 @@
</span> -->
</el-form-item>
<!-- Login -->
<el-button :loading="loading" type="primary" :disabled="!checked" style="
<el-button
:loading="loading"
type="primary"
style="
width: 100%;
margin-bottom: 10px;
background-color: rgb(0, 147, 221);
" size="medium" @click.native.prevent="handleLogin">
"
size="medium"
@click.native.prevent="handleLogin"
>
{{ $t('login:button:login') }}
</el-button>
<div class="PrivacyPolicy" style="font-size: 14px;">
<el-checkbox v-model="checked" style="margin-right: 5px;" />
<span>{{ $t('login:message:PrivacyPolicy') }}</span>
<span style="cursor: pointer;color:#428bca" @click="viewAgreement(0)">{{ $t('login:message:UserAgreement')
}}</span>
<span>{{ $t('login:message:and') }}</span>
<span style="cursor: pointer;color:#428bca" @click="viewAgreement(1)">{{
$t('login:message:PrivacyPolicyName') }}</span>
</div>
<div style="text-align: right">
<TopLang v-if="
VUE_APP_OSS_CONFIG_REGION !== 'oss-us-west-1' &&
NODE_ENV !== 'usa'
" />
<TopLang
v-if="
VUE_APP_OSS_CONFIG_REGION !== 'oss-us-west-1' &&
NODE_ENV !== 'usa'
"
/>
<!-- Forget password? -->
<el-button type="text" size="medium" @click.native.prevent="handleResetPwd" style="color: rgb(0, 147, 221)">
<el-button
type="text"
size="medium"
@click.native.prevent="handleResetPwd"
style="color: rgb(0, 147, 221)"
>
{{ $t('login:button:forgetPassword') }}
</el-button>
</div>
@ -107,14 +152,19 @@
</div>
</div>
<div v-if="language === 'zh'" class="login-footer">
<span>Copyright © {{ new Date().getFullYear() }} 上海展影医疗科技有限公司
版权所有</span>
<span
>Copyright © {{ new Date().getFullYear() }} 上海展影医疗科技有限公司
版权所有</span
>
<span> | </span>
<a target="_blank" href="https://beian.miit.gov.cn/">
<span> 沪ICP备2021037850-2 </span>
</a>
<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" />
<span>沪公网安备 31011002005859</span>
</a>
@ -130,23 +180,43 @@
<span style="color: #428bca">About</span>
</a>
</div>
<Vcode :show="isShow" :fail-text="$t('login:button:failText')" :success-text="$t('login:button:successText')"
:slider-text="$t('login:button:sliderText')" :imgs="[Img1]" @success="onSuccess" />
<el-dialog v-if="aboutVisible" :visible.sync="aboutVisible" width="680px" style="margin-top: 0"
:close-on-click-modal="false" size="small">
<div style="
<Vcode
:show="isShow"
:fail-text="$t('login:button:failText')"
:success-text="$t('login:button:successText')"
:slider-text="$t('login:button:sliderText')"
:imgs="[Img1]"
@success="onSuccess"
/>
<el-dialog
v-if="aboutVisible"
:visible.sync="aboutVisible"
width="680px"
style="margin-top: 0"
:close-on-click-modal="false"
size="small"
>
<div
style="
margin: 0 auto;
width: 600px;
line-height: 28px;
text-align: center;
">
<h1 style="text-align: center; margin-bottom: 30px" v-if="NODE_ENV === 'usa'">
"
>
<h1
style="text-align: center; margin-bottom: 30px"
v-if="NODE_ENV === 'usa'"
>
About
</h1>
<h1 style="text-align: center; margin-bottom: 30px" v-else></h1>
<p style="margin-bottom: 0px" v-if="NODE_ENV === 'usa'">
<!-- {{ $t('login:title:system_title_about') }} -->
<svg-icon icon-class="login-logo" style="width: 250px; height: 71px" />
<svg-icon
icon-class="login-logo"
style="width: 250px; height: 71px"
/>
</p>
<p style="margin-bottom: 0px" v-else>{{ $t('login:title:system') }}</p>
<p style="margin-bottom: 20px; margin-top: 0">
@ -177,8 +247,13 @@
</div>
</el-dialog>
<browserTip ref="browserTip" />
<toggleRole v-if="toggleRoleVisible" :visible.sync="toggleRoleVisible" :loading="toggleRoleLoading"
@save="loginByRole" @cancel="cancel" />
<toggleRole
v-if="toggleRoleVisible"
:visible.sync="toggleRoleVisible"
:loading="toggleRoleLoading"
@save="loginByRole"
@cancel="cancel"
/>
</div>
</template>
@ -190,9 +265,6 @@ import Vcode from 'vue-puzzle-vcode'
import browserTip from '@/views/dictionary/template/browser/tip.vue'
import Img1 from '@/assets/pic-2.png'
import toggleRole from '@/components/toggleRole'
import {
getCurrentVersionUserAgreements,
} from '@/api/dictionary'
export default {
name: 'Login',
components: { TopLang, Vcode, browserTip, toggleRole },
@ -240,8 +312,6 @@ export default {
Img1,
toggleRoleVisible: false,
toggleRoleLoading: false,
Agreement: [],
checked: true
}
},
computed: {
@ -269,13 +339,7 @@ export default {
this.location = this.$route.query.location
zzSessionStorage.setItem('loginType', this.loginType)
localStorage.setItem('location', this.location)
// zh-CN navigator.language
if (navigator.language !== 'zh-CN' && navigator.language !== 'zh-TW') {
this.$i18n.locale = 'en'
this.setLanguage('en')
this.$updateDictionary()
}
else if (process.env.VUE_APP_OSS_CONFIG_REGION === 'oss-us-west-1') {
if (process.env.VUE_APP_OSS_CONFIG_REGION === 'oss-us-west-1') {
this.$i18n.locale = 'en'
this.setLanguage('en')
this.$updateDictionary()
@ -291,30 +355,9 @@ export default {
}
}
this.$refs.browserTip.open()
this.getAgreementList()
},
methods: {
...mapMutations({ setLanguage: 'lang/setLanguage' }),
viewAgreement(type) {
let find = this.Agreement.find(item => item.IsCurrentVersion && item.UserAgreementTypeEnum === type)
if (!find) return this.$confirm(this.$t('login:message:noAgreement').replace('xxx', this.$fd('UserAgreementType', type)))
this.$AGR({
Id: find.Id,
IsEn_Us: this.$i18n.locale !== 'zh'
})
},
getAgreementList() {
getCurrentVersionUserAgreements({
PageIndex: 1,
PageSize: 20,
IsCurrentVersion: true
})
.then((res) => {
this.Agreement = res.Result
})
.catch(() => {
})
},
openAbout() {
this.aboutVisible = true
},
@ -473,7 +516,7 @@ export default {
Array.isArray(this.$store.state.user.roles) &&
this.$store.state.user.roles.filter((item) => item.IsUserRoleDisabled)
.length ===
this.$store.state.user.roles.length - 1
this.$store.state.user.roles.length - 1
) {
let role = this.$store.state.user.roles.find(
(item) => !item.IsUserRoleDisabled
@ -597,7 +640,6 @@ $cursor: #fff;
// }
}
}
.login-r {
.el-form-item {
border: 1px solid rgba(255, 255, 255, 0.1);
@ -613,28 +655,23 @@ $cursor: #fff;
$bg: #2d3a4b;
$dark_gray: #889aa4;
$light_gray: #606266;
.login-container {
position: relative;
width: 100%;
height: 100%;
overflow: auto;
background: rgb(249, 249, 249);
::v-deep .el-input__inner::placeholder {
color: $dark_gray;
}
.login-header {
margin: 10px 0px 20px 10px;
height: 3rem;
width: 720px;
.login-logo {
height: 100%;
}
}
.login-body {
position: absolute;
left: 50%;
@ -648,39 +685,32 @@ $light_gray: #606266;
box-sizing: border-box;
background: rgb(255, 255, 255);
border-radius: 10px 0px 0px 10px;
.login-l {
position: relative;
float: left;
width: 50%;
height: 100%;
.login-logo {
position: absolute;
top: 35px;
left: 50px;
img {
height: 40px;
}
.usa-logo {
height: 60px;
}
}
.login-image {
position: absolute;
top: 10px;
left: 0px;
// transform: translateY(-50%);
height: 100%;
img {
height: 100%;
}
}
.login-image-usa {
width: 100%;
display: flex;
@ -688,7 +718,6 @@ $light_gray: #606266;
justify-content: flex-end;
}
}
.login-r {
position: relative;
float: left;
@ -706,19 +735,16 @@ $light_gray: #606266;
margin: 0 auto;
overflow: hidden;
}
.title-container {
// margin-bottom: 50px;
text-align: center;
margin-top: 20%;
.title {
font-size: 35px;
color: $light_gray;
text-align: center;
font-weight: bold;
}
.title-logo-message {
font-size: 26px;
color: $light_gray;
@ -758,7 +784,6 @@ $light_gray: #606266;
}
}
}
.login-footer {
position: absolute;
bottom: 50px;
@ -772,7 +797,6 @@ $light_gray: #606266;
align-items: center;
// color: rgb(180, 190, 199);
color: #909399;
a {
display: inline-block;
text-decoration: none;
@ -781,16 +805,13 @@ $light_gray: #606266;
display: flex;
justify-content: center;
}
span {
margin: 0 2px;
}
img {
height: 20px;
line-height: 20px;
}
// p{
// display: inline-block;
// height:20px;

View File

@ -2,8 +2,13 @@
<template>
<div style="width: 100%; height: 100%">
<transition name="viewer-fade">
<div v-show="urlList.length > 0" ref="image-viewer__wrapper" tabindex="-1" class="image-viewer__wrapper"
:style="{ 'z-index': 5 }">
<div
v-show="urlList.length > 0"
ref="image-viewer__wrapper"
tabindex="-1"
class="image-viewer__wrapper"
:style="{ 'z-index': 5 }"
>
<span class="image-viewer_desc">
<!-- <span v-if="studyCode">NST00006</span>
<span v-if="modality">CT</span>
@ -16,12 +21,18 @@
</span>
<!-- Arrow -->
<template v-if="!isSingle">
<span class="image-viewer__btn image-viewer__prev" :class="{ 'is-disabled': !infinite && isFirst }"
@click="prev">
<span
class="image-viewer__btn image-viewer__prev"
:class="{ 'is-disabled': !infinite && isFirst }"
@click="prev"
>
<i class="el-icon-arrow-left" />
</span>
<span class="el-image-viewer__btn el-image-viewer__next" :class="{ 'is-disabled': !infinite && isLast }"
@click="next">
<span
class="el-image-viewer__btn el-image-viewer__next"
:class="{ 'is-disabled': !infinite && isLast }"
@click="next"
>
<i class="el-icon-arrow-right" />
</span>
</template>
@ -33,19 +44,36 @@
<i class="el-image-viewer__actions__divider" />
<i class="el-icon-c-scale-to-original" @click="toggleMode" />
<i class="el-image-viewer__actions__divider" />
<i class="el-icon-refresh-left" @click="handleActions('anticlocelise')" />
<i class="el-icon-refresh-right" @click="handleActions('clocelise')" />
<i
class="el-icon-refresh-left"
@click="handleActions('anticlocelise')"
/>
<i
class="el-icon-refresh-right"
@click="handleActions('clocelise')"
/>
</div>
</div>
<!-- 图片 -->
<div id="image-viewer__canvas" class="image-viewer__canvas">
<template v-for="(item, i) in urlList">
<img v-if="!~item.FileType.indexOf('pdf')" v-show="i === index" :ref="`img${i}`" :key="item.Id"
crossorigin="anonymous" :src="item.FileType && item.FileType.indexOf('zip') >= 0
? zipImg
: `${OSSclientConfig.basePath}${item.Path}`
" :style="imgStyle" style="max-width: 100%; max-height: 100%" @load="handleImgLoad"
@error="handleImgError" @mousedown="handleMouseDown" />
<img
v-if="!~item.FileType.indexOf('pdf')"
v-show="i === index"
:ref="`img${i}`"
:key="item.Id"
crossorigin="anonymous"
:src="
item.FileType && item.FileType.indexOf('zip') >= 0
? zipImg
: `${OSSclientConfig.basePath}${item.Path}`
"
:style="imgStyle"
style="max-width: 100%; max-height: 100%"
@load="handleImgLoad"
@error="handleImgError"
@mousedown="handleMouseDown"
/>
</template>
</div>
</div>
@ -80,11 +108,11 @@ export default {
},
onSwitch: {
type: Function,
default: () => { },
default: () => {},
},
onClose: {
type: Function,
default: () => { },
default: () => {},
},
initialIndex: {
type: Number,
@ -144,9 +172,7 @@ export default {
immediate: true,
handler(val) {
this.reset()
if (val >= 0) {
this.onSwitch(this.urlList[val].Id)
}
this.onSwitch(val)
},
},
},
@ -323,7 +349,6 @@ export default {
width: 100%;
height: 100%;
}
.image-viewer__btn {
position: absolute;
z-index: 1;
@ -345,7 +370,6 @@ export default {
height: 40px;
font-size: 40px;
}
.image-viewer_desc {
position: absolute;
top: 40px;
@ -363,7 +387,6 @@ export default {
border-radius: 17px;
// border-radius: 2%;
}
.image-viewer__canvas {
position: absolute;
top: 50%;
@ -374,7 +397,6 @@ export default {
justify-content: center;
align-items: center;
}
.image-viewer__actions {
left: 50%;
bottom: 30px;
@ -386,7 +408,6 @@ export default {
border-color: #fff;
border-radius: 22px;
}
.image-viewer__actions__inner {
width: 100%;
height: 100%;
@ -398,7 +419,6 @@ export default {
align-items: center;
justify-content: space-around;
}
.image-viewer__next,
.image-viewer__prev {
top: 50%;
@ -409,18 +429,15 @@ export default {
background-color: #606266;
border-color: #fff;
}
.image-viewer__prev {
transform: translateY(-50%);
left: 40px;
}
.image-viewer__next {
transform: translateY(-50%);
right: 40px;
text-indent: 2px;
}
.image-viewer__mask {
position: absolute;
width: 100%;
@ -430,11 +447,9 @@ export default {
opacity: 0.5;
// background:#000
}
.viewer-fade-enter-active {
animation: viewer-fade-in 0.3s;
}
.viewer-fade-leave-active {
animation: viewer-fade-out 0.3s;
}
@ -444,7 +459,6 @@ export default {
transform: translate3d(0, -20px, 0);
opacity: 0;
}
100% {
transform: translate3d(0, 0, 0);
opacity: 1;
@ -456,7 +470,6 @@ export default {
transform: translate3d(0, 0, 0);
opacity: 1;
}
100% {
transform: translate3d(0, -20px, 0);
opacity: 0;

View File

@ -2,29 +2,56 @@
<div class="none-dicom_preview-wrapper">
<div class="image-viewer-wrapper">
<!-- 预览图像 -->
<ImageViewer v-if="previewVisible" :on-switch="(index) => {
selected(index)
}
" :initial-index="previewImage.index" :url-list="previewImage.imgList" :study-code="previewImage.studyCode"
:body-part="previewImage.bodyPart" :modality="previewImage.modality" :zip-img="zipImg" />
<ImageViewer
v-if="previewVisible"
:on-switch="
(index) => {
selected(index)
}
"
:initial-index="previewImage.index"
:url-list="previewImage.imgList"
:study-code="previewImage.studyCode"
:body-part="previewImage.bodyPart"
:modality="previewImage.modality"
:zip-img="zipImg"
/>
</div>
<div class="thumbnail-wrapper" style="z-index: 999; background-color: #fff">
<div class="">
<div class="img-wrapper">
<el-button icon="el-icon-d-arrow-left" plain class="left to" :disabled="disabledPrev" @click="toRight" />
<el-button
icon="el-icon-d-arrow-left"
plain
class="left to"
:disabled="disabledPrev"
@click="toRight"
/>
<div ref="imagesWrapper" class="images">
<div v-if="noData" class="empty-text">
<slot name="empty">暂无数据</slot>
</div>
<div v-show="!noData" class="items" :style="itemsStyle">
<template v-for="(item, index) in previewImage.imgList">
<div v-if="!~item.FileType.indexOf('pdf')" :key="index" class="item-img" :style="imgSize" :class="{
'is-active': item.Id === currentFileId,
}" @click="selected(item.Id)">
<img :title="item.FileName" crossorigin="anonymous" :src="item.FileType && item.FileType.indexOf('zip') >= 0
? zipImg
: `${OSSclientConfig.basePath}${item.Path}`
" />
<div
v-if="!~item.FileType.indexOf('pdf')"
:key="index"
class="item-img"
:style="imgSize"
:class="{
'is-active': index === currentIndex,
}"
@click="selected(index)"
>
<img
:title="item.FileName"
crossorigin="anonymous"
:src="
item.FileType && item.FileType.indexOf('zip') >= 0
? zipImg
: `${OSSclientConfig.basePath}${item.Path}`
"
/>
<p v-if="item.FileName" class="item-date">
{{ `${index + 1}` }}
</p>
@ -32,7 +59,13 @@
</template>
</div>
</div>
<el-button icon="el-icon-d-arrow-right" :disabled="disabledNext" plain class="right to" @click="Left" />
<el-button
icon="el-icon-d-arrow-right"
:disabled="disabledNext"
plain
class="right to"
@click="Left"
/>
</div>
</div>
</div>
@ -60,10 +93,6 @@ export default {
type: Number,
default: null,
},
currentFileId: {
type: String,
default: ''
},
previewImage: {
type: Object,
default: () => {
@ -138,7 +167,7 @@ export default {
const scope = this
window.onresize = function () {
scope.pageSize = scope.wrapperWidth() / scope.itemWidth
scope.selected(scope.currentFileId)
scope.selected(scope.currentIndex)
}
},
methods: {
@ -156,8 +185,7 @@ export default {
this.translateX = maxTrans
}
},
selected(id) {
let index = this.previewImage.imgList.findIndex(item => item.Id === id)
selected(index) {
const center = this.pageSize >> 1
//
const lastCenter = this.dataLength - center
@ -174,7 +202,7 @@ export default {
if (this.currentIndex !== index) {
this.currentIndex = index
}
this.$emit('selectedImg', id)
this.$emit('selectedImg', index)
},
wrapperWidth() {
if (this.$refs.imagesWrapper) {
@ -196,30 +224,25 @@ export default {
.image-viewer-wrapper {
flex: 1;
}
.thumbnail-wrapper {
height: 130px;
}
.img-content {
position: absolute;
left: 0;
bottom: 10px;
width: 100%;
}
.img-wrapper {
display: flex;
position: relative;
margin: 0 20px;
height: 120px;
.to {
width: 32px;
height: 100%;
padding: 0;
}
.images::before {
position: absolute;
z-index: 5;
@ -228,15 +251,16 @@ export default {
width: 84px;
content: '';
pointer-events: none;
background: -webkit-gradient(linear,
left top,
right top,
from(#fff),
color-stop(50%, rgba(0, 0, 0, 0)));
background: -webkit-gradient(
linear,
left top,
right top,
from(#fff),
color-stop(50%, rgba(0, 0, 0, 0))
);
background: -o-linear-gradient(left, #fff, rgba(0, 0, 0, 0) 50%);
background: linear-gradient(90deg, #fff, rgba(0, 0, 0, 0) 50%);
}
.images::after {
position: absolute;
z-index: 5;
@ -246,22 +270,22 @@ export default {
width: 84px;
content: '';
pointer-events: none;
background: -webkit-gradient(linear,
right top,
left top,
from(#fff),
color-stop(50%, rgba(0, 0, 0, 0)));
background: -webkit-gradient(
linear,
right top,
left top,
from(#fff),
color-stop(50%, rgba(0, 0, 0, 0))
);
background: -o-linear-gradient(right, #fff, rgba(0, 0, 0, 0) 50%);
background: linear-gradient(270deg, #fff, rgba(0, 0, 0, 0) 50%);
}
.images {
position: relative;
overflow: hidden;
width: 100%;
height: 100%;
margin: 0 2px;
.empty-text {
color: rgb(158, 158, 158);
height: 100%;
@ -269,7 +293,6 @@ export default {
align-items: center;
justify-content: center;
}
.items {
position: absolute;
top: 0;
@ -279,7 +302,6 @@ export default {
height: 100%;
align-items: center;
transition: transform 0.25s ease;
.item-img {
display: inline-block;
box-sizing: border-box;
@ -287,7 +309,6 @@ export default {
margin-right: 8px;
border: 2px solid rgba(0, 0, 0, 0);
cursor: pointer;
.item-date {
bottom: 0px;
position: absolute;
@ -298,18 +319,15 @@ export default {
line-height: 24px;
color: white;
}
img {
width: 100%;
height: 100%;
}
}
.item-img:hover::after {
// border-color: #409EFF;
opacity: 0;
}
.item-img::after {
position: absolute;
top: 0;
@ -324,11 +342,9 @@ export default {
transition: opacity 0.3s ease;
background-color: #fff;
}
.is-active {
border-color: #409eff;
}
.is-active:after {
opacity: 0;
}

View File

@ -1,59 +1,84 @@
<template>
<div v-loading="loading" class="img-container">
<el-card class="box-card left">
<div class="title" style="display: flex;align-items: center;">
<div style="margin-right: 5px;cursor: pointer;" @click.stop="sortFile">
<i :class="['el-icon-caret-top', Asc === false || Asc === null ? '' : 'icon_check']"
style="display: block;margin-bottom: -5px;"></i>
<i :class="['el-icon-caret-bottom', Asc === true || Asc === null ? '' : 'icon_check']"
style="display: block; margin-top: -5px;"></i>
</div>
<div class="title">
{{ $t('trials:none-dicom-show:fileList') }}
</div>
<div class="left-content">
<!-- 检查层级 -->
<el-collapse v-model="activeNames" @change="handleChange">
<el-collapse-item v-for="(study, i) in studyList" :key="study.CodeView" :name="study.CodeView"><template
slot="title">
<el-collapse-item
v-for="(study, i) in studyList"
:key="study.CodeView"
:name="study.CodeView"
><template slot="title">
<div class="study-desc">
<span>{{ study.CodeView }}</span>
<span v-if="OtherInfo.IsShowStudyName" style="margin-left: 5px">
{{ study.StudyName }}
</span>
<span style="margin: 0 5px">{{ study.Modality }}</span>
<span>{{ getBodyPart(study.BodyPart, study.BodyPartForEditOther) }}</span>
<span>{{ getBodyPart(study.BodyPart) }}</span>
</div>
</template>
<!-- 文件层级 -->
<div v-if="study.NoneDicomStudyFileList.length === 0" class="empty-text">
<div
v-if="study.NoneDicomStudyFileList.length === 0"
class="empty-text"
>
<slot name="empty">{{ $t('trials:audit:message:noData') }}</slot>
</div>
<div v-else id="imgList" style="height: 100%; overflow: hidden">
<template v-for="(item, j) in study.NoneDicomStudyFileList">
<div :id="`img${item.Id}`" :key="item.Id" :class="{
'is-boxActive': item.Id === currentFileId,
}" class="img-box" @click="selected(item, i, j, true)">
<div
:id="`img${item.Id}`"
:key="item.Id"
:class="{
'is-boxActive': item.Id === currentFileId,
}"
class="img-box"
@click="selected(item, i, j, true)"
>
<div class="file-image">
<el-image v-if="
[
'image/jpeg',
'image/jpg',
'image/png',
'image/bmp',
].includes(item.FileType)
" style="width: 100%; height: 100%"
<el-image
v-if="
[
'image/jpeg',
'image/jpg',
'image/png',
'image/bmp',
].includes(item.FileType)
"
style="width: 100%; height: 100%"
:src="`${OSSclientConfig.basePath}${item.Path}?x-oss-process=image/resize,w_50,h_50/format,png`"
fit="contain" crossorigin="anonymous" />
<el-image v-else-if="item.FileType === 'application/pdf'" style="width: 100%; height: 100%"
:src="pdf" fit="contain" crossorigin="anonymous" />
<el-image v-else-if="
item.FileType === 'application/x-zip-compressed'
" style="width: 100%; height: 100%" :src="zip" fit="contain" crossorigin="anonymous" />
fit="contain"
crossorigin="anonymous"
/>
<el-image
v-else-if="item.FileType === 'application/pdf'"
style="width: 100%; height: 100%"
:src="pdf"
fit="contain"
crossorigin="anonymous"
/>
<el-image
v-else-if="
item.FileType === 'application/x-zip-compressed'
"
style="width: 100%; height: 100%"
:src="zip"
fit="contain"
crossorigin="anonymous"
/>
</div>
<div v-if="item.FileName.length < 15" class="img-text">
{{ `${j + 1}. ${item.FileName}` }}
</div>
<el-tooltip v-else :content="item.FileName" placement="bottom">
<el-tooltip
v-else
:content="item.FileName"
placement="bottom"
>
<div class="img-text">
{{ `${j + 1}. ${item.FileName}` }}
</div>
@ -61,15 +86,23 @@
<div v-if="isQcCheck" class="switchBox">
<div class="item">
<span>{{ $t('trials:audit:table:isReading') }}</span>
<el-switch v-model="item.IsReading" :disabled="item.IsDeleted || isAudit"
@change="changeReadingStatus($event, study, item)" :active-text="$fd('YesOrNo', true)"
:inactive-text="$fd('YesOrNo', false)" />
<el-switch
v-model="item.IsReading"
:disabled="item.IsDeleted || isAudit"
@change="changeReadingStatus($event, study, item)"
:active-text="$fd('YesOrNo', true)"
:inactive-text="$fd('YesOrNo', false)"
/>
</div>
<div class="item">
<span>{{ $t('trials:audit:table:isDelete') }}</span>
<el-switch v-model="item.IsDeleted" :disabled="isAudit"
@change="changeDeleteStatus($event, study, item)" :active-text="$fd('YesOrNo', true)"
:inactive-text="$fd('YesOrNo', false)" />
<el-switch
v-model="item.IsDeleted"
:disabled="isAudit"
@change="changeDeleteStatus($event, study, item)"
:active-text="$fd('YesOrNo', true)"
:inactive-text="$fd('YesOrNo', false)"
/>
</div>
</div>
</div>
@ -82,9 +115,14 @@
<!-- 预览图像 -->
<el-card class="box-card right">
<div style="width: 100%; height: 100%" v-if="!showPDF">
<Preview v-if="previewImage.imgList.length > 0" ref="previewImage" style="width: 100%"
:preview-image="previewImage" :value="currentStudyFileIndex" @selectedImg="selectedImg"
:currentFileId="currentFileId" />
<Preview
v-if="previewImage.imgList.length > 0"
ref="previewImage"
style="width: 100%"
:preview-image="previewImage"
:value="currentStudyFileIndex"
@selectedImg="selectedImg"
/>
</div>
<div style="width: 100%; height: 100%" v-else>
<PreviewFile :file-path="pdfFile.path" :file-type="pdfFile.type" />
@ -105,7 +143,6 @@ import zip from '@/assets/zip.jpg'
import { changeURLStatic } from '@/utils/history.js'
import Preview from './components/preview'
import PreviewFile from '@/components/PreviewFile'
import FileNameSorter from "@/utils/customSort";
// import CheckForm from './components/form'
export default {
name: 'Notice',
@ -137,7 +174,7 @@ export default {
subjectVisitId: '',
sudyId: '',
loading: false,
BodyPart: {},
bp: [],
OtherInfo: {},
showPDF: false,
pdfFile: {
@ -148,11 +185,10 @@ export default {
isAudit: false,
activeNames: [],
Asc: false
}
},
async created() {
this.BodyPart.Bodypart = await this.$getBodyPart(this.$route.query.trialId)
this.bp = await this.$getBodyPart(this.$route.query.trialId)
this.isQcCheck = !!this.$route.query.isQcCheck
},
async mounted() {
@ -165,31 +201,8 @@ export default {
this.getNoneDicomList()
//
},
computed: {
CriterionType() {
return this.OtherInfo.CriterionType ? this.OtherInfo.CriterionType : 0
}
},
methods: {
sortFile() {
if (this.Asc) {
this.Asc = false
} else {
this.Asc = true
}
console.log(this.Asc, 'this.Asc')
this.studyList.forEach(study => {
if (study.NoneDicomStudyFileList.length > 0) {
study.NoneDicomStudyFileList = FileNameSorter.sortFileNames(study.NoneDicomStudyFileList, {
direction: this.Asc ? 'asc' : 'desc',
key: 'FileName'
})
}
})
this.previewImage.imgList = this.studyList[this.currentStudyIndex].NoneDicomStudyFileList
this.previewImage.index = this.studyList[this.currentStudyIndex].NoneDicomStudyFileList.findIndex(item => item.Id === this.currentFileId)
},
handleChange() { },
handleChange() {},
changeReadingStatus(callback, row, file) {
let statusStr = ''
if (callback) {
@ -232,7 +245,7 @@ export default {
this.loading = false
})
})
.catch(() => { })
.catch(() => {})
},
changeDeleteStatus(callback, row, file) {
let statusStr = ''
@ -282,8 +295,8 @@ export default {
// file.IsDeleted = !file.IsDeleted
})
},
getBodyPart(bodyPart, other) {
if (!bodyPart && !other) return ''
getBodyPart(bodyPart) {
if (!bodyPart) return ''
var separator = ','
if (bodyPart.indexOf('|') > -1) {
separator = '|'
@ -294,12 +307,14 @@ export default {
}
var arr = bodyPart.split(separator)
var newArr = arr.map((i) => {
return this.$fd('Bodypart', i.trim(), 'Code', this.BodyPart, 'Name')
return this.$fd(
'Bodypart',
i.trim(),
'Code',
{ Bodypart: this.bp },
'Name'
)
})
if (other) {
newArr.push(other)
}
newArr = newArr.filter(Boolean)
return newArr.join(' | ')
},
// Dicom
@ -310,8 +325,7 @@ export default {
this.studyId,
false,
this.$route.query.visitTaskId,
!!this.$route.query.isReading,
this.$route.query.isImageSegmentLabel,
!!this.$route.query.isReading
)
.then((res) => {
this.studyList = res.Result
@ -322,13 +336,11 @@ export default {
return item.NoneDicomStudyFileList.length > 0
})
this.activeNames = this.studyList.map((item) => item.CodeView)
console.log(this.activeNames)
if (studyIndex > -1) {
var fileObj = this.studyList[studyIndex]['NoneDicomStudyFileList']
this.selected(fileObj[0], studyIndex, 0, true)
}
if (this.CriterionType === 19 || this.CriterionType === 20) {
this.sortFile()
}
})
.catch(() => {
this.loading = false
@ -355,13 +367,12 @@ export default {
this.previewImage.modality = this.studyList[studyIndex].Modality
this.$nextTick(() => {
if (isChangeSub) {
this.$refs['previewImage'].selected(this.currentFileId)
this.$refs['previewImage'].selected(fileIndex)
}
})
},
selectedImg(id) {
selectedImg(fileIndex) {
if (this.studyList.length > 0) {
let fileIndex = this.studyList[this.currentStudyIndex].NoneDicomStudyFileList.findIndex(item => item.Id === id)
this.currentStudyFileIndex = fileIndex
this.currentFileId =
this.studyList[this.currentStudyIndex].NoneDicomStudyFileList[
@ -389,39 +400,30 @@ export default {
</script>
<style lang="scss" scoped>
.icon_check {
color: #409EFF;
}
.img-container {
position: relative;
width: 100%;
height: 100%;
padding: 10px;
display: flex;
::-webkit-scrollbar {
width: 7px;
height: 7px;
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
background: #d0d0d0;
}
::v-deep .el-card__body {
padding: 0px;
}
}
.study-desc {
padding: 10px 5px;
line-height: 20px;
background-color: #d5d5d5;
font-weight: 500;
}
.left {
width: 220px;
height: 100%;
@ -432,7 +434,6 @@ export default {
display: flex;
flex-direction: column;
}
.title {
height: 40px;
line-height: 40px;
@ -442,7 +443,6 @@ export default {
background-color: #4e4e4e;
color: #ffffff;
}
.left-content {
flex: 1;
overflow-y: auto;
@ -474,7 +474,6 @@ export default {
// margin-bottom: 5px;
padding-left: 5px;
}
.img-text {
display: inline-block;
width: calc(100% - 60px);
@ -482,41 +481,33 @@ export default {
height: 50px;
line-height: 50px;
overflow: hidden;
text-overflow: ellipsis;
/* 用省略号表示溢出的文本 */
text-overflow: ellipsis; /* 用省略号表示溢出的文本 */
white-space: nowrap;
}
.img-box:nth-last-child(1) {
margin-bottom: 0px;
}
.is-boxActive {
// border-color: #409eff;
color: #409eff;
}
.is-boxActiv:after {
opacity: 0;
}
}
.right {
flex: 1;
height: 100%;
margin-left: 10px;
::v-deep .el-card__body {
height: 100%;
width: 100%;
}
}
.switchBox {
width: 100%;
margin: 5px 0;
color: #4e4e4e;
.item {
display: flex;
align-items: center;
@ -524,21 +515,17 @@ export default {
margin-bottom: 5px;
}
}
.file-image {
width: 50px;
height: 50px;
}
::v-deep .el-collapse-item__header {
background-color: #d5d5d5;
}
::v-deep .el-collapse-item__header {
min-height: 48px;
height: auto;
}
::v-deep .el-collapse-item__content {
padding-bottom: 0;
}

View File

@ -172,13 +172,6 @@ export default {
],
Phone: [
{ required: true, validator: checkPhone, trigger: 'blur' }
],
Email: [
{
pattern: new RegExp(this.$reg().EmailRegexStr),
message: 'Please input the correct email address',
trigger: 'blur,change',
}
]
},
siteOptions: [],

View File

@ -117,9 +117,6 @@ export default {
} else {
var reg =
/^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/
if (this.$reg().EmailRegexStr) {
reg = new RegExp(this.$reg().EmailRegexStr)
}
if (this.form.Email && reg.test(this.form.Email)) {
this.sendDisabled = false
callback()

View File

@ -136,9 +136,6 @@ export default {
} else {
var reg =
/^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/
if (this.$reg().EmailRegexStr) {
reg = new RegExp(this.$reg().EmailRegexStr)
}
if (this.form.Email && reg.test(this.form.Email)) {
this.sendDisabled = false
callback()

View File

@ -158,9 +158,6 @@ export default {
callback(new Error(this.$t('trials:researchForm:formRule:specify')))
} else {
var reg = /^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/
if (this.$reg().EmailRegexStr) {
reg = new RegExp(this.$reg().EmailRegexStr)
}
if (this.form.EmailOrPhone && reg.test(this.form.EmailOrPhone)) {
callback()
} else {
@ -173,9 +170,6 @@ export default {
callback(new Error(this.$t('trials:researchForm:formRule:specify')))
} else {
var reg = /^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/
if (this.$reg().EmailRegexStr) {
reg = new RegExp(this.$reg().EmailRegexStr)
}
if (this.form.ReplaceUserEmailOrPhone && reg.test(this.form.ReplaceUserEmailOrPhone)) {
callback()
} else {

View File

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

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