fix(缺陷管理): 缺陷编辑附件更新失败

--bug=1036395 --user=宋昌昌 【缺陷管理】编辑ms平台缺陷,关联附件,更新失败 https://www.tapd.cn/55049933/s/1469807
This commit is contained in:
song-cc-rock 2024-03-05 16:45:18 +08:00 committed by Craftsman
parent 5e17fe21cb
commit ebf7d5ca5f
7 changed files with 61 additions and 41 deletions

View File

@ -576,7 +576,7 @@ public class BugAttachmentService {
private String getLocalFileType(String fileName) { private String getLocalFileType(String fileName) {
int i = fileName.lastIndexOf("."); int i = fileName.lastIndexOf(".");
if (i > 0) { if (i > 0) {
return fileName.substring(i); return fileName.substring(i + 1);
} else { } else {
return StringUtils.EMPTY; return StringUtils.EMPTY;
} }

View File

@ -1,11 +1,11 @@
import { CommentParams } from '@/components/business/ms-comment/types'; import {CommentParams} from '@/components/business/ms-comment/types';
import MSR from '@/api/http/index'; import MSR from '@/api/http/index';
import * as bugURL from '@/api/requrls/bug-management'; import * as bugURL from '@/api/requrls/bug-management';
import { BugEditFormObject, BugExportParams, BugListItem } from '@/models/bug-management'; import {BugEditFormObject, BugListItem} from '@/models/bug-management';
import { AssociatedList, CreateOrUpdateDemand, DemandItem, OperationFile } from '@/models/caseManagement/featureCase'; import {AssociatedList, DemandItem, OperationFile} from '@/models/caseManagement/featureCase';
import { CommonList, TableQueryParams, TemplateOption } from '@/models/common'; import {CommonList, TableQueryParams, TemplateOption} from '@/models/common';
/** /**
* *
@ -154,8 +154,8 @@ export function checkFileIsUpdateRequest(data: string[]) {
} }
// 更新文件 // 更新文件
export function updateFile(projectId: string, id: string) { export function updateFile(data: OperationFile) {
return MSR.get({ url: `${bugURL.getFileIsUpdateUrl}/${projectId}/${id}` }); return MSR.post({ url: bugURL.getFileIsUpdateUrl, data });
} }
// 删除文件或取消关联用例文件 // 删除文件或取消关联用例文件

View File

@ -288,7 +288,8 @@
innerFileList.value = [fileItem]; innerFileList.value = [fileItem];
inputFileName.value = fileItem.name || ''; inputFileName.value = fileItem.name || '';
} }
emit('change', innerFileList.value, { ...fileItem, local: true }); fileItem.local = true;
emit('change', _fileList);
nextTick(() => { nextTick(() => {
// emit // emit
buttonDropDownVisible.value = false; buttonDropDownVisible.value = false;

View File

@ -26,7 +26,7 @@
{{ t('common.save') }} {{ t('common.save') }}
</a-button> </a-button>
</div> </div>
<AddAttachment v-model:file-list="fileList" @link-file="associatedFile"/> <AddAttachment v-model:file-list="fileList" @link-file="associatedFile" />
<MsFileList <MsFileList
ref="fileListRef" ref="fileListRef"
v-model:file-list="fileList" v-model:file-list="fileList"
@ -45,7 +45,7 @@
<!-- 本地文件 --> <!-- 本地文件 -->
<div v-if="item.local || item.status === 'init'" class="flex flex-nowrap"> <div v-if="item.local || item.status === 'init'" class="flex flex-nowrap">
<MsButton <MsButton
v-if="item.status !== 'init'" v-if="item.status !== 'init' && item.file.type.includes('image')"
type="button" type="button"
status="primary" status="primary"
class="!mr-[4px]" class="!mr-[4px]"
@ -80,7 +80,7 @@
<!-- 关联文件 --> <!-- 关联文件 -->
<div v-else class="flex flex-nowrap"> <div v-else class="flex flex-nowrap">
<MsButton <MsButton
v-if="item.status !== 'init'" v-if="item.status !== 'init' && item.file.type.includes('image')"
type="button" type="button"
status="primary" status="primary"
class="!mr-[4px]" class="!mr-[4px]"
@ -136,7 +136,7 @@
import MsRichText from '@/components/pure/ms-rich-text/MsRichText.vue'; import MsRichText from '@/components/pure/ms-rich-text/MsRichText.vue';
import MsFileList from '@/components/pure/ms-upload/fileList.vue'; import MsFileList from '@/components/pure/ms-upload/fileList.vue';
import { MsFileItem } from '@/components/pure/ms-upload/types'; import { MsFileItem } from '@/components/pure/ms-upload/types';
import AddAttachment from "@/components/business/ms-add-attachment/index.vue"; import AddAttachment from '@/components/business/ms-add-attachment/index.vue';
import RelateFileDrawer from '@/components/business/ms-link-file/associatedFileDrawer.vue'; import RelateFileDrawer from '@/components/business/ms-link-file/associatedFileDrawer.vue';
import TransferModal from '@/views/case-management/caseManagementFeature/components/tabContent/transferModal.vue'; import TransferModal from '@/views/case-management/caseManagementFeature/components/tabContent/transferModal.vue';
@ -151,7 +151,7 @@
previewFile, previewFile,
transferFileRequest, transferFileRequest,
updateFile, updateFile,
uploadOrAssociationFile uploadOrAssociationFile,
} from '@/api/modules/bug-management'; } from '@/api/modules/bug-management';
import { getModules, getModulesCount } from '@/api/modules/project-management/fileManagement'; import { getModules, getModulesCount } from '@/api/modules/project-management/fileManagement';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
@ -223,7 +223,7 @@
return { return {
...fileInfo, ...fileInfo,
name: fileInfo.fileName, name: fileInfo.fileName,
isUpdateFlag: checkUpdateFileIds.includes(fileInfo.id), isUpdateFlag: checkUpdateFileIds.includes(fileInfo.fileId),
}; };
}) })
.map((fileInfo: any) => { .map((fileInfo: any) => {
@ -241,7 +241,7 @@
form.value.title = title; form.value.title = title;
form.value.description = description; form.value.description = description;
defaultContentValue.value = description; defaultContentValue.value = description;
handleFileFunc(attachments); await handleFileFunc(attachments);
}; };
// //
@ -264,7 +264,7 @@
item.local ? t('caseManagement.featureCase.deleteSuccess') : t('caseManagement.featureCase.cancelLinkSuccess') item.local ? t('caseManagement.featureCase.deleteSuccess') : t('caseManagement.featureCase.cancelLinkSuccess')
); );
const attachments = await getAttachmentList(bugId.value); const attachments = await getAttachmentList(bugId.value);
handleFileFunc(attachments); await handleFileFunc(attachments);
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log(error); console.log(error);
@ -357,7 +357,7 @@
async (val) => { async (val) => {
const isNewFiles = val.filter((item) => item.status === 'init').length; const isNewFiles = val.filter((item) => item.status === 'init').length;
if (val && isNewFiles) { if (val && isNewFiles) {
startUpload(); await startUpload();
} }
} }
); );
@ -365,8 +365,16 @@
// //
async function handleUpdateFile(item: MsFileItem) { async function handleUpdateFile(item: MsFileItem) {
try { try {
await updateFile(currentProjectId.value, item.associationId); const params = {
refId: item.associateId,
associated: !item.local,
bugId: bugId.value,
projectId: currentProjectId.value,
};
await updateFile(params);
Message.success(t('common.updateSuccess')); Message.success(t('common.updateSuccess'));
const attachments = await getAttachmentList(bugId.value);
await handleFileFunc(attachments);
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log(error); console.log(error);
@ -438,12 +446,12 @@
request: { request: {
bugId: bugId.value as string, bugId: bugId.value as string,
projectId: currentProjectId.value, projectId: currentProjectId.value,
selectIds: fileResultList.map((item: any) => item.uid) selectIds: fileResultList.map((item: any) => item.uid),
} },
}; };
await uploadOrAssociationFile(params); await uploadOrAssociationFile(params);
const attachments = await getAttachmentList(bugId.value); const attachments = await getAttachmentList(bugId.value);
handleFileFunc(attachments); await handleFileFunc(attachments);
Message.success(t('common.linkSuccess')); Message.success(t('common.linkSuccess'));
} }

View File

@ -42,7 +42,7 @@
<a-form-item field="attachment"> <a-form-item field="attachment">
<div class="flex flex-col"> <div class="flex flex-col">
<div class="mb-1"> <div class="mb-1">
<AddAttachment v-model:file-list="fileList" @change="handleChange" @link-file="associatedFile"/> <AddAttachment v-model:file-list="fileList" @change="handleChange" @link-file="associatedFile" />
</div> </div>
</div> </div>
</a-form-item> </a-form-item>
@ -51,7 +51,7 @@
<!-- 本地文件 --> <!-- 本地文件 -->
<div v-if="item.local || item.status === 'init'" class="flex flex-nowrap"> <div v-if="item.local || item.status === 'init'" class="flex flex-nowrap">
<MsButton <MsButton
v-if="item.status !== 'init'" v-if="item.status !== 'init' && item.file.type.includes('image')"
type="button" type="button"
status="primary" status="primary"
class="!mr-[4px]" class="!mr-[4px]"
@ -92,7 +92,7 @@
<!-- 关联文件 --> <!-- 关联文件 -->
<div v-else class="flex flex-nowrap"> <div v-else class="flex flex-nowrap">
<MsButton <MsButton
v-if="item.status !== 'init'" v-if="item.status !== 'init' && item.file.type.includes('image')"
type="button" type="button"
status="primary" status="primary"
class="!mr-[4px]" class="!mr-[4px]"
@ -270,22 +270,23 @@
// //
function getFilesParams() { function getFilesParams() {
const associateFileIds = attachmentsList.value.filter((item) => !item.local).map((item) => item.id); // link file
const newAssociateFileListIds = fileList.value const associateFileIds = attachmentsList.value.filter((item) => !item.local).map((item) => item.fileId);
form.value.linkFileIds = fileList.value
.filter((item) => !item.local && !associateFileIds.includes(item.uid)) .filter((item) => !item.local && !associateFileIds.includes(item.uid))
.map((item) => item.uid); .map((item) => item.uid);
// unlink file
const currentOldLocalFileList = fileList.value const remainLinkFileIds = fileList.value.filter((item) => !item.local).map((item) => item.uid);
form.value.unLinkRefIds = attachmentsList.value
.filter((item) => !item.local && !remainLinkFileIds.includes(item.fileId))
.map((item) => item.refId);
// delete local file
const remainLocalFileIds = fileList.value
.filter((item) => item.local && item.status !== 'init') .filter((item) => item.local && item.status !== 'init')
.map((item) => item.uid); .map((item) => item.uid);
// form
form.value.deleteLocalFileIds = attachmentsList.value form.value.deleteLocalFileIds = attachmentsList.value
.filter((item) => item.local && !currentOldLocalFileList.includes(item.uid)) .filter((item) => item.local && !remainLocalFileIds.includes(item.fileId))
.map((item) => item.uid); .map((item) => item.fileId);
form.value.unLinkRefIds = associateFileIds.filter((id) => !newAssociateFileListIds.includes(id));
form.value.linkFileIds = newAssociateFileListIds;
} }
// //
@ -404,7 +405,13 @@
// //
async function handleUpdateFile(item: MsFileItem) { async function handleUpdateFile(item: MsFileItem) {
try { try {
await updateFile(currentProjectId.value, item.associationId); const params = {
refId: item.associateId,
associated: !item.local,
bugId: bugId.value,
projectId: currentProjectId.value,
};
await updateFile(params);
Message.success(t('common.updateSuccess')); Message.success(t('common.updateSuccess'));
} catch (error) { } catch (error) {
console.log(error); console.log(error);
@ -429,7 +436,6 @@
return { return {
...e, ...e,
enable: true, // enable: true, //
local: true, //
}; };
}); });
} }
@ -466,8 +472,10 @@
if (isCopy.value) { if (isCopy.value) {
delete tmpObj.id; delete tmpObj.id;
} }
//
const localFiles = fileList.value.filter((item) => item.local && item.status === 'init');
// //
const res = await createOrUpdateBug({ request: tmpObj, fileList: fileList.value as unknown as File[] }); const res = await createOrUpdateBug({ request: tmpObj, fileList: localFiles as unknown as File[] });
if (isEdit.value) { if (isEdit.value) {
Message.success(t('common.updateSuccess')); Message.success(t('common.updateSuccess'));
router.push({ router.push({

View File

@ -4,6 +4,7 @@
* @param {stafileInfotus} file * @param {stafileInfotus} file
*/ */
import { getFileEnum } from '@/components/pure/ms-upload/iconMap';
import { MsFileItem } from '@/components/pure/ms-upload/types'; import { MsFileItem } from '@/components/pure/ms-upload/types';
import { AssociatedList } from '@/models/caseManagement/featureCase'; import { AssociatedList } from '@/models/caseManagement/featureCase';
@ -11,11 +12,14 @@ import { AssociatedList } from '@/models/caseManagement/featureCase';
export function convertToFileByBug(fileInfo: AssociatedList): MsFileItem { export function convertToFileByBug(fileInfo: AssociatedList): MsFileItem {
const gatewayAddress = `${window.location.protocol}//${window.location.hostname}:${window.location.port}`; const gatewayAddress = `${window.location.protocol}//${window.location.hostname}:${window.location.port}`;
const fileName = `${fileInfo.name}`; const fileName = `${fileInfo.name}`;
const type = `${fileInfo.fileType}`; const fileFormatMatch = fileName.match(/\.([a-zA-Z0-9]+)$/);
const fileFormatType = fileFormatMatch ? fileFormatMatch[1] : 'none';
const type = getFileEnum(fileFormatType);
const file = new File([new Blob()], `${fileName}`, { const file = new File([new Blob()], `${fileName}`, {
type: `application/${type}`, type: `application/${type}`,
}); });
Object.defineProperty(file, 'size', { value: fileInfo.fileSize }); Object.defineProperty(file, 'size', { value: fileInfo.fileSize });
Object.defineProperty(file, 'type', { value: type });
const { fileId, local, isUpdateFlag, refId, createUserName, createTime } = fileInfo; const { fileId, local, isUpdateFlag, refId, createUserName, createTime } = fileInfo;
return { return {
enable: fileInfo.enable || false, enable: fileInfo.enable || false,
@ -30,7 +34,7 @@ export function convertToFileByBug(fileInfo: AssociatedList): MsFileItem {
isUpdateFlag, isUpdateFlag,
associateId: refId, associateId: refId,
createUserName, createUserName,
uploadedTime: createTime uploadedTime: createTime,
}; };
} }
/** * /** *

View File

@ -654,7 +654,6 @@
return { return {
...e, ...e,
enable: true, // enable: true, //
local: true, //
}; };
}); });
} }