项目文档资质材料
continuous-integration/drone/push Build is passing Details

uat
wangxiaoshuang 2025-03-14 17:09:38 +08:00
parent 1a4bfe64f9
commit a060c1745d
8 changed files with 413 additions and 193 deletions

View File

@ -1265,3 +1265,51 @@ export function getTrialFileTypeFile(data) {
data
})
}
// 项目文档-获取资质材料列表
export function getTrialAttachments(data) {
return request({
url: `/Attachment/getTrialAttachments`,
method: 'post',
data
})
}
// 项目文档-修改资质材料稽查状态
export function setAuthorizedViewC(data) {
return request({
url: `/Attachment/setAuthorizedView`,
method: 'post',
data
})
}
// 项目文档-上传资质材料
export function saveTrialAttachments(data) {
return request({
url: `/Attachment/saveTrialAttachments`,
method: 'post',
data
})
}
// 项目文档-资质材料(获取医生列表)
export function getTrialDoctorListC(data) {
return request({
url: `/Attachment/getTrialDoctorList`,
method: 'post',
data
})
}
// 项目文档-修改资质材料
export function updateTrialAttachments(data) {
return request({
url: `/Attachment/updateTrialAttachments`,
method: 'post',
data
})
}
// 项目文档-删除资质材料
export function deleteAttachment(data) {
return request({
url: `/Attachment/deleteAttachment`,
method: 'post',
data
})
}

View File

@ -361,11 +361,11 @@ export default {
var file = await this.fileToBlob(param.file)
let typeArr = ['', 'Report', 'Doc', 'Record', 'Reviewer', 'Template']
let types = typeArr[this.ArchiveTypeEnum]
// let fileNameNoType = param.file.name
// .substring(0, param.file.name.lastIndexOf('.'))
// .toLocaleLowerCase()
let fileNameNoType = param.file.name
.substring(0, param.file.name.lastIndexOf('.'))
.toLocaleLowerCase()
const res = await this.OSSclient.put(
`/${trialId}/Document/${types}/${this.$guid()}${extendName}`,
`/${trialId}/Document/${types}/${fileNameNoType}${extendName}`,
file
)
this.form[`${key}FileRecord`] = {

View File

@ -249,11 +249,11 @@ export default {
var file = await this.fileToBlob(param.file)
let typeArr = ['', 'Report', 'Doc', 'Record', 'Reviewer', 'Template']
let types = typeArr[this.ArchiveTypeEnum]
// let fileNameNoType = param.file.name
// .substring(0, param.file.name.lastIndexOf('.'))
// .toLocaleLowerCase()
let fileNameNoType = param.file.name
.substring(0, param.file.name.lastIndexOf('.'))
.toLocaleLowerCase()
const res = await this.OSSclient.put(
`/${trialId}/Document/${types}/${this.$guid()}${extendName}`,
`/${trialId}/Document/${types}/${fileNameNoType}${extendName}`,
file
)
this.form[`${key}FileRecord`] = {

View File

@ -376,7 +376,7 @@
v-if="hasDownLoad && isManage && !viewStatus"
icon="el-icon-download"
:title="
$t('trials:trialDocument:trainRecord:button:downLoadFileFileFile')
$t('trials:trialDocument:trainRecord:button:downLoadFile')
"
circle
:disabled="

View File

@ -335,10 +335,10 @@ export default {
let fileType = file.name
.substring(file.name.lastIndexOf('.'))
.toLocaleLowerCase()
// let fileName = file.name
// .substring(0, file.name.lastIndexOf('.'))
// .toLocaleLowerCase()
let path = `${this.uploadPath}/${this.$guid()}${fileType}`
let fileName = file.name
.substring(0, file.name.lastIndexOf('.'))
.toLocaleLowerCase()
let path = `${this.uploadPath}/${fileName}${fileType}`
file.curPath = path
const fileData = await this.fileToBlob(file.file)
let res = await this.fileToOss(path, fileData, file)

View File

@ -0,0 +1,253 @@
<template>
<base-model :config="config">
<div slot="dialog-body">
<el-form
ref="certificateForm"
:model="form"
label-width="140px"
size="small"
:rules="rules"
>
<div class="base-dialog-body">
<el-form-item
:label="$t('trials:trialDocument:certificate:form:fileType')"
prop="Type"
>
<el-select
v-model="form.Type"
placeholder=""
clearable
:disabled="config.status === 'edit' && !!this.data.Type"
>
<el-option
v-for="item in $d.CertificateFileType"
:key="item.id"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item
:label="$t('trials:trialDocument:certificate:form:DoctorId')"
prop="DoctorId"
>
<el-select
v-model="form.DoctorId"
placeholder=""
clearable
:disabled="config.status === 'edit' && !!this.data.DoctorId"
>
<el-option
v-for="item in doctorList"
:key="item.Id"
:label="item.FullName"
:value="item.Id"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item
:label="$t('trials:trialDocument:certificate:form:pdfFileRecord')"
prop="Path"
>
<el-upload
class="upload-demo"
action
:before-upload="(param) => beforeUpload(param, '.pdf')"
:http-request="handleUploadFile"
:on-remove="handleRemoveFile"
:limit="1"
accept=".pdf"
:file-list="PDFFile"
>
<el-button size="small" type="primary" :disabled="!!form.Path"
>{{ $t('common:button:upload') }}
</el-button>
<span slot="tip" class="el-upload__tip">
{{ $t('trials:trialDocument:certificate:rule:mustPDF') }}
</span>
</el-upload>
</el-form-item>
</div>
</el-form>
</div>
<div slot="dialog-footer">
<el-button size="small" @click="canel">
{{ $t('trials:trialDocument:certificate:button:canel') }}
</el-button>
<el-button size="small" type="primary" :loading="loading" @click="save">
{{ $t('trials:trialDocument:certificate:button:save') }}
</el-button>
</div>
</base-model>
</template>
<script>
import baseModel from '@/components/BaseModel'
import { saveTrialAttachments, updateTrialAttachments } from '@/api/dictionary'
export default {
props: {
config: {
required: true,
default: () => {
return {}
},
},
data: {
required: true,
default: () => {
return {}
},
},
ArchiveTypeEnum: {
type: Number,
default: 0,
},
doctorList: {
type: Array,
default: () => {
return []
},
},
},
components: {
'base-model': baseModel,
},
data() {
return {
form: {
Type: null,
DoctorId: null,
FileName: null,
Path: null,
FullPath: null,
},
rules: {
Type: [
{
required: true,
message: this.$t('common:ruleMessage:select'),
trigger: ['blur', 'change'],
},
],
DoctorId: [
{
required: true,
message: this.$t('common:ruleMessage:select'),
trigger: ['blur', 'change'],
},
],
Path: [
{
required: true,
validator: (rule, value, callback) => {
if (!this.form.Path) {
callback(
new Error(
this.$t('trials:trialDocument:certificate:msg:noFile')
)
)
} else {
callback()
}
},
// message: this.$t('common:ruleMessage:specify'),
trigger: ['blur', 'change'],
},
],
},
loading: false,
PDFFile: [],
}
},
created() {
if (this.config.status === 'edit') {
Object.keys(this.form).forEach((key) => {
this.form[key] = this.data[key]
})
if (this.form.Path) {
this.PDFFile = []
this.PDFFile.push({
name: this.form.FileName,
url: this.form.Path,
})
}
}
},
methods: {
async save() {
try {
let validate = await this.$refs.certificateForm.validate()
if (!validate) return false
this.loading = true
this.form.TrialId = this.$route.query.trialId
let res = null
if (this.config.status === 'edit') {
this.form.Id = this.data.Id
res = await updateTrialAttachments(this.form)
} else {
res = await saveTrialAttachments([this.form])
}
if (res.IsSuccess) {
this.$emit('close')
this.$emit('getList')
}
} catch (err) {
console.log(err)
this.loading = false
}
},
canel() {
this.$emit('close')
},
handleRemoveFile() {
this.form.Path = null
this.form.FileName = null
this.form.FullPath = null
this.PDFFile = []
},
beforeUpload(param, accept) {
if (this.PDFFile && this.PDFFile[0]) {
this.$alert(
this.$t('trials:trialDocument:certificate:msg:hasFile')
).catch()
return
}
let extendName = param.name
.substring(param.name.lastIndexOf('.'))
.toLocaleLowerCase()
if (accept !== extendName) {
this.$alert(
this.$t('trials:trialDocument:certificate:msg:typeErr')
).catch()
return
}
},
async handleUploadFile(param) {
let trialId = this.$route.query.trialId
let extendName = param.file.name
.substring(param.file.name.lastIndexOf('.'))
.toLocaleLowerCase()
if (!trialId)
return this.$alert(
this.$t('trials:trialDocument:certificate:msg:noTrialId')
).catch()
this.loading = true
var file = await this.fileToBlob(param.file)
let typeArr = ['', 'Report', 'Doc', 'Record', 'Reviewer', 'Template']
let types = typeArr[this.ArchiveTypeEnum]
let fileNameNoType = param.file.name
.substring(0, param.file.name.lastIndexOf('.'))
.toLocaleLowerCase()
const res = await this.OSSclient.put(
`/${trialId}/Document/${types}/${fileNameNoType}${extendName}`,
file
)
this.form.Path = this.$getObjectName(res.url)
this.form.FullPath = this.$getObjectName(res.url)
this.form.FileName = param.file.name
this.loading = false
},
},
}
</script>

View File

@ -11,7 +11,7 @@
:label="$t('trials:trialDocument:certificate:search:fileType')"
>
<el-select
v-model="searchData.IsAuthorizedView"
v-model="searchData.Type"
style="width: 100px"
placeholder=""
clearable
@ -40,16 +40,16 @@
:label="$t('trials:trialDocument:certificate:search:viewer')"
>
<el-select
v-model="searchData.IsAuthorizedView"
v-model="searchData.DoctorId"
style="width: 100px"
placeholder=""
clearable
>
<el-option
v-for="item in $d.CertificateFileType"
:key="item.id"
:label="item.label"
:value="item.value"
v-for="item in doctorList"
:key="item.Id"
:label="item.FullName"
:value="item.Id"
>
</el-option>
</el-select>
@ -131,6 +131,7 @@
type="primary"
:disabled="selectTable.length <= 0"
v-if="hasDel && isManage && !viewStatus"
@click.stop="handleDel"
>
{{ $t('trials:trialDocument:certificate:button:del') }}
</el-button>
@ -157,24 +158,34 @@
<!--文件类型-->
<el-table-column
prop="FileName"
prop="type"
:label="$t('trials:trialDocument:certificate:table:fileType')"
show-overflow-tooltip
sortable="custom"
/>
>
<template slot-scope="scope">
<span>{{ $fd('CertificateFileType', scope.row.Type) }}</span>
</template>
</el-table-column>
<!--文件名称-->
<el-table-column
prop="HistoryFileRecord"
prop="FileName"
:label="$t('trials:trialDocument:certificate:table:FileName')"
show-overflow-tooltip
sortable="custom"
/>
<!--阅片人-->
<el-table-column
prop="HistoryFileRecord"
prop="UserName"
:label="$t('trials:trialDocument:certificate:table:viewer')"
show-overflow-tooltip
/>
sortable="custom"
>
<template slot-scope="scope">
<span>{{ scope.row.UserName }} ({{ scope.row.FullName }})</span>
</template>
</el-table-column>
<el-table-column
prop="IsAuthorizedView"
:label="$t('trials:trialDocument:certificate:table:isAuthorizedView')"
@ -184,7 +195,7 @@
>
<template slot-scope="scope">
<el-switch
:disabled="!scope.row.TrianingDate"
:disabled="!scope.row.DoctorId"
v-if="isManage && !viewStatus && hasEdit"
v-model="scope.row.IsAuthorizedView"
@change="(val) => auth(false, scope.row, val)"
@ -215,10 +226,7 @@
icon="el-icon-view"
:title="$t('common:button:view')"
circle
:disabled="
!scope.row.TrialFileRecord || !scope.row.TrialFileRecord.FilePath
"
@click.stop="preview(scope.row.TrialFileRecord)"
@click.stop="preview(scope.row)"
/>
<el-button
v-if="hasEdit && isManage && !viewStatus"
@ -230,18 +238,16 @@
<el-button
v-if="hasDownLoad && isManage && !viewStatus"
icon="el-icon-download"
:title="
$t('trials:trialDocument:certificate:button:downLoadFileFileFile')
"
:title="$t('trials:trialDocument:certificate:button:downLoadFile')"
circle
@click.stop="downLoad(false, scope.row.TrialFileRecord, 'file')"
@click.stop="downLoad(scope.row, 'file')"
/>
<el-button
v-if="hasDel && isManage && !viewStatus"
icon="el-icon-delete"
:title="$t('trials:trialDocument:certificate:button:delete')"
circle
@click.stop="handleDel(scope.row)"
@click.stop="handleDel(scope.row, false)"
/>
</template>
</el-table-column>
@ -266,9 +272,9 @@
/>
<certificate-form
:ArchiveTypeEnum="ArchiveTypeEnum"
:rowData="rowData"
:config="update_config"
:data="selectData"
:doctorList="doctorList"
v-if="update_config.visible"
@close="updateClose"
@getList="getList"
@ -277,12 +283,11 @@
</template>
<script>
import {
addOrUpdateTrialFileType,
getTrialTrianingRecordList,
deleteTrialTrianingRecord,
authorizedTrialTrianingRecord,
addOrUpdateTrialTrianingRecord,
batchAddTrialTrianingRecord,
getTrialAttachments,
setAuthorizedViewC,
saveTrialAttachments,
getTrialDoctorListC,
deleteAttachment,
} from '@/api/dictionary'
import { downLoadFile } from '@/utils/stream.js'
import { deepClone } from '@/utils/index.js'
@ -294,14 +299,12 @@ const searchDataDefault = () => {
return {
IsAuthorizedView: null,
FileName: null,
TrianingDateStartTime: null,
TrianingDateEndTime: null,
UpdateStartTime: null,
UpdateEndTime: null,
DoctorId: null,
Type: null,
PageIndex: 1,
PageSize: 20,
Asc: false,
SortField: 'TrianingDate',
SortField: 'UserName',
}
}
export default {
@ -329,8 +332,6 @@ export default {
},
data() {
return {
rowBtnStatus: 'edit', // edit save
rowBtnLoading: false,
searchData: searchDataDefault(),
loading: false,
list: [],
@ -349,8 +350,6 @@ export default {
faccept: ['.pdf'],
limitLength: 0,
TrianingDate: [],
UpdateTime: [],
update_config: {
visible: false,
showClose: true,
@ -361,6 +360,7 @@ export default {
upload: null,
},
DATA: {},
doctorList: [],
}
},
methods: {
@ -373,21 +373,16 @@ export default {
list.forEach((item) => {
let obj = {
TrialId: this.$route.query.trialId,
TrialFileTypeId: this.Id,
IsAuthorizedView: false,
TrialFileRecord: item,
HistoryFileRecord: null,
Note: null,
TrianingCount: null,
TrianingDate: null,
TrianingState: null,
FileName: item.FileName,
Path: item.FilePath,
FullPath: item.FilePath,
type: '',
DoctorId: null,
}
arr.push(obj)
})
this.loading = true
let res = await batchAddTrialTrianingRecord({
TrianingRecordList: arr,
})
let res = await saveTrialAttachments(arr)
this.loading = false
if (res.IsSuccess) {
this.getList()
@ -397,18 +392,6 @@ export default {
console.log(err)
}
},
//
upload(row, key) {
this.selectData = deepClone(row)
this.update_config.title = `${this.$t(
'trials:trialDocument:certificate:form:title:upload'
)}
-
${this.isEN ? this.rowData.Name : this.rowData.NameCN}`
this.update_config.status = 'edit'
this.update_config.upload = key
this.update_config.visible = true
},
//
handleAdd() {
this.selectData = {}
@ -433,41 +416,16 @@ export default {
this.update_config.upload = null
this.update_config.visible = true
},
//
async delFile(row, key) {
try {
let confirm = await this.$confirm(
this.$t('trials:trialDocument:certificate:message:deleteFile'),
{
type: 'warning',
distinguishCancelAndClose: true,
}
)
if (confirm !== 'confirm') return false
let data = deepClone(row)
data[`${key}FileRecord`] = null
this.loading = true
let res = await addOrUpdateTrialTrianingRecord(data)
this.loading = false
if (res.IsSuccess) {
this.$message.success(this.$t('common:message:deletedSuccessfully'))
this.getList()
}
} catch (err) {
this.loading = false
console.log(err)
}
},
//
async downLoad(isArray = true, row, type = 'zip') {
async downLoad(row, type = 'zip') {
try {
if (type === 'file') {
return await downLoadFile(
this.OSSclientConfig.basePath + row.FilePath,
this.OSSclientConfig.basePath + row.Path,
row.FileName
)
}
let { files, name } = this.formatDownloadFile(isArray, row)
let { files, name } = this.formatDownloadFile()
let res = await downLoadFile(files, name, type)
// if (res && this.downloadId) {
// this.downloadImageSuccess()
@ -477,52 +435,28 @@ export default {
}
},
//
formatDownloadFile(isArray = true, row) {
formatDownloadFile() {
let files = [],
name = `${this.TITLE}_${new Date().getTime()}.zip`,
arr = ['Trial', 'History']
if (!isArray) {
name = `${row.Name}_${row.Version}_${new Date().getTime()}.zip`
arr.forEach((key) => {
if (row[`${key}FileRecord`] && row[`${key}FileRecord`].FilePath) {
let obj = {
name: `${row[`${key}FileRecord`].FileName.substring(
0,
row[`${key}FileRecord`].FileName.lastIndexOf('.')
)}__${row.Version}${row[`${key}FileRecord`].FileName.substring(
row[`${key}FileRecord`].FileName.lastIndexOf('.')
).toLocaleLowerCase()}`,
url:
this.OSSclientConfig.basePath +
row[`${key}FileRecord`].FilePath,
}
files.push(obj)
}
})
} else {
name = `${this.TITLE}_${new Date().getTime()}.zip`
this.selectTable.forEach((item) => {
arr.forEach((key) => {
if (item[`${key}FileRecord`] && item[`${key}FileRecord`].FilePath) {
let obj = {
name: `${item.TrianingDate}_${item[
`${key}FileRecord`
].FileName.substring(
name: `${item.UserName} (${item.LastName}_${
item.FirstName
})/${this.$fd(
'CertificateFileType',
item.Type
)}_${item.FileName.substring(
0,
item[`${key}FileRecord`].FileName.lastIndexOf('.')
)}__${new Date().getTime()}${item[
`${key}FileRecord`
].FileName.substring(
item[`${key}FileRecord`].FileName.lastIndexOf('.')
item.FileName.lastIndexOf('.')
)}__${new Date().getTime()}${item.FileName.substring(
item.FileName.lastIndexOf('.')
).toLocaleLowerCase()}`,
url:
this.OSSclientConfig.basePath +
item[`${key}FileRecord`].FilePath,
url: this.OSSclientConfig.basePath + item.Path,
}
files.push(obj)
}
})
})
}
return { files, name }
},
//
@ -530,12 +464,10 @@ export default {
try {
let data = {}
if (isArray) {
let flag = this.selectTable.some((item) => !item.TrianingDate)
let flag = this.selectTable.some((item) => !item.DoctorId)
if (flag)
return this.$message.warning(
this.$t(
'trials:trialDocument:certificate:message:hsaNoTrianingDate'
)
this.$t('trials:trialDocument:certificate:message:hsaNoDoctorId')
)
data = {
Ids: this.selectTable.map((item) => item.Id),
@ -548,7 +480,7 @@ export default {
}
}
this.loading = true
let res = await authorizedTrialTrianingRecord(data)
let res = await setAuthorizedViewC(data)
this.loading = false
if (res.IsSuccess) {
this.$t('trials:trialDocument:certificate:message:authSuccessfully')
@ -565,7 +497,7 @@ export default {
}
},
//
handleDel(row) {
handleDel(row, isArray = true) {
this.$confirm(
this.$t('trials:trialDocument:certificate:message:deleteMessage'),
{
@ -575,7 +507,13 @@ export default {
)
.then(() => {
this.loading = true
deleteTrialTrianingRecord(row.Id)
let data = {}
if (isArray) {
data.Ids = this.selectTable.map((item) => item.Id)
} else {
data.Ids = [row.Id]
}
deleteAttachment(data)
.then((res) => {
this.loading = false
if (res.IsSuccess) {
@ -595,30 +533,30 @@ export default {
console.log(err)
})
},
//
async getTrialDoctorList() {
try {
let data = {
TrialId: this.$route.query.trialId,
}
let res = await getTrialDoctorListC(data)
if (res.IsSuccess) {
this.doctorList = res.Result
}
} catch (err) {
console.log(err)
}
},
async getList() {
try {
if (!this.Id) return false
this.searchData.TrialFileTypeId = this.Id
// this.searchData.TrialFileTypeId = this.Id
this.searchData.TrialId = this.$route.query.trialId
if (this.viewStatus) {
this.searchData.IsAuthorizedView = true
}
if (this.TrianingDate && this.TrianingDate.length >= 2) {
this.searchData.TrianingDateStartTime = this.TrianingDate[0]
this.searchData.TrianingDateEndTime = this.TrianingDate[1]
} else {
this.searchData.TrianingDateStartTime = null
this.searchData.TrianingDateEndTime = null
}
if (this.UpdateTime && this.UpdateTime.length >= 2) {
this.searchData.UpdateStartTime = this.UpdateTime[0]
this.searchData.UpdateEndTime = this.UpdateTime[1]
} else {
this.searchData.UpdateStartTime = null
this.searchData.UpdateEndTime = null
}
this.loading = true
let res = await getTrialTrianingRecordList(this.searchData)
let res = await getTrialAttachments(this.searchData)
this.loading = false
if (res.IsSuccess) {
this.list = res.Result.CurrentPageData
@ -637,8 +575,6 @@ export default {
//
handleReset() {
this.searchData = searchDataDefault()
this.TrianingDate = []
this.UpdateTime = []
this.getList()
},
//
@ -655,27 +591,11 @@ export default {
handleSelectionChange(val) {
this.selectTable = val
},
//
async saveRowData() {
try {
this.rowBtnLoading = true
let res = await addOrUpdateTrialFileType(this.DATA)
this.rowBtnLoading = false
if (res.IsSuccess) {
this.rowBtnStatus = 'edit'
this.$emit('getMenu')
this.$message.success(this.$t('common:message:savedSuccessfully'))
}
} catch (err) {
console.log(err)
this.rowBtnLoading = false
}
},
//
preview(row) {
if (!row.FilePath) return false
if (!row.Path) return false
this.$preview({
path: row.FilePath || row.fullPath,
path: row.FilePath || row.fullPath || row.Path,
type: 'pdf',
title: row.FileName,
})
@ -696,7 +616,6 @@ export default {
},
openFile(isFolder = false) {
this.selectData = {}
this.selectKey = null
this.faccept = ['.pdf']
this.limitLength = 0
this.config.title = this.$t(
@ -709,7 +628,6 @@ export default {
watch: {
Id: {
handler() {
this.rowBtnStatus = 'edit'
this.getList()
},
immediate: true,
@ -725,6 +643,7 @@ export default {
let typeArr = ['', 'Report', 'Doc', 'Record', 'Reviewer', 'Template']
let types = typeArr[this.ArchiveTypeEnum]
this.uploadPath = `/${this.$route.query.trialId}/Document/${types}`
this.getTrialDoctorList()
},
computed: {
isEN() {

View File

@ -74,13 +74,13 @@
:rowData="rowData"
/>
<!--阅片人资质材料-->
<!-- <certificate
<certificate
v-if="[8].includes(SubIdentificationEnum)"
:ArchiveTypeEnum="ArchiveTypeEnum"
:rowData="rowData"
:Id="Id"
:viewStatus="viewStatus"
/> -->
/>
<!--医学审核-->
<medical-feedback
v-if="[9].includes(SubIdentificationEnum)"