feat(文件管理): 文件管理部分接口&部分组件调整

This commit is contained in:
baiqi 2023-11-16 13:56:26 +08:00 committed by 刘瑞斌
parent 7f8173b5f8
commit dc49dc4e3c
10 changed files with 194 additions and 124 deletions

View File

@ -10,6 +10,7 @@ import {
DeleteModuleUrl,
DownloadFileUrl,
FilePageUrl,
GetAssociationListUrl,
GetFileDetailUrl,
GetFileTypesUrl,
GetModuleCountUrl,
@ -24,6 +25,7 @@ import {
UpdateModuleUrl,
UpdateRepositoryFileUrl,
UpdateRepositoryUrl,
UpgradeAssociationUrl,
UploadFileUrl,
} from '@/api/requrls/project-management/fileManagement';
@ -32,6 +34,7 @@ import type {
AddModuleParams,
AddRepositoryFileParams,
AddRepositoryParams,
AssociationItem,
BatchFileApiParams,
FileDetail,
FileItem,
@ -173,3 +176,13 @@ export function updateRepositoryFile(id: string) {
export function getRepositoryInfo(id: string) {
return MSR.get<RepositoryInfo>({ url: GetRepositoryInfoUrl, params: id });
}
// 更新关联用例文件
export function upgradeAssociation(projectId: string, id: string) {
return MSR.get({ url: `${UpgradeAssociationUrl}/${projectId}`, params: id });
}
// 获取文件关联用例列表
export function getAssociationList(params: { id: string }) {
return MSR.get<AssociationItem[]>({ url: GetAssociationListUrl, params: params.id });
}

View File

@ -25,3 +25,6 @@ export const AddRepositoryUrl = '/project/file/repository/add-repository'; //
export const AddRepositoryFileUrl = '/project/file/repository/add-file'; // 添加存储库文件
export const UpdateRepositoryFileUrl = '/project/file/repository/pull-file'; // 更新存储库文件
export const GetRepositoryInfoUrl = '/project/file/repository/info'; // 获取存储库信息
export const DeleteAssociationUrl = '/project/file/association/delete'; // 删除关联用例
export const UpgradeAssociationUrl = '/project/file/association/upgrade'; // 更新关联用例文件
export const GetAssociationListUrl = '/project/file/association/list'; // 获取关联用例列表

View File

@ -96,12 +96,11 @@
);
const listSize = ref(0);
const listPage = ref(0);
const listTotal = ref(0);
const remoteList = ref<any[]>([]);
const noMore = ref(false);
const isInit = ref(false);
const endPage = ref(0); //
const topLoading = ref(false);
const bottomLoading = ref(false);
const isLoadError = ref(false); // TODO:
@ -109,26 +108,28 @@
/**
* 加载上一页
*/
async function loadPrevList() {
try {
if (props.mode === 'remote' && typeof props.remoteFunc === 'function') {
topLoading.value = true;
listPage.value -= 1;
const res = await props.remoteFunc({
current: listPage.value,
pageSize: listSize.value,
...(props.remoteParams || {}),
});
remoteList.value = res.list;
listTotal.value = res.total;
}
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
} finally {
topLoading.value = false;
}
}
// async function loadPrevList() {
// try {
// if (props.mode === 'remote' && typeof props.remoteFunc === 'function') {
// topLoading.value = true;
// endPage.value -= 1;
// const res = await props.remoteFunc({
// current: startPage.value,
// pageSize: listSize.value,
// ...(props.remoteParams || {}),
// });
// remoteList.value = isApartMax.value
// ? [...res.list, remoteList.value.slice(0, listSize.value * endPage.value)]
// : remoteList.value.concat(res.list);
// listTotal.value = res.total;
// }
// } catch (error) {
// // eslint-disable-next-line no-console
// console.log(error);
// } finally {
// topLoading.value = false;
// }
// }
/**
* 加载下一页
@ -138,19 +139,23 @@
try {
if (props.mode === 'remote' && typeof props.remoteFunc === 'function') {
bottomLoading.value = true;
listPage.value += 1;
endPage.value += 1;
if (isReload) {
listPage.value = 1;
endPage.value = 1;
}
const res = await props.remoteFunc({
current: listPage.value,
current: endPage.value,
pageSize: listSize.value,
...(props.remoteParams || {}),
});
remoteList.value = isReload ? res.list : remoteList.value.concat(res.list);
if (isReload) {
remoteList.value = res.list;
} else {
remoteList.value = remoteList.value.concat(res.list);
}
listTotal.value = res.total;
bottomLoading.value = false;
noMore.value = listSize.value * (listPage.value - 1) + remoteList.value.length >= listTotal.value;
noMore.value = listSize.value * endPage.value >= listTotal.value;
}
} catch (error) {
// eslint-disable-next-line no-console
@ -186,8 +191,8 @@
isInit.value = true;
}, 400);
//
listPage.value = 0;
await loadNextList();
endPage.value = 0;
await loadNextList(true);
}
/**
@ -221,16 +226,7 @@
watchEffect(async () => {
//
if (props.mode === 'remote' && typeof props.remoteFunc === 'function') {
if (isArrivedTop.value && !isArrivedBottom.value && listPage.value > 1 && !topLoading.value) {
// 1
loadPrevList();
} else if (
isArrivedBottom.value &&
!isArrivedTop.value &&
!noMore.value &&
!bottomLoading.value &&
!isLoadError.value
) {
if (isArrivedBottom.value && !isArrivedTop.value && !noMore.value && !bottomLoading.value && !isLoadError.value) {
// 1
loadNextList();
}
@ -248,7 +244,7 @@
<style lang="less" scoped>
.ms-card-list-container {
@apply overflow-hidden;
@apply h-full overflow-hidden;
.ms-container--shadow();
.ms-card-list {
@apply grid max-h-full overflow-auto;

View File

@ -1,8 +1,8 @@
<template>
<div :class="['ms-thumbnail-card', `ms-thumbnail-card--${props.mode}`]" @click="handleCardClick">
<div class="ms-thumbnail-card-content">
<div class="ms-thumbnail-card-more">
<MsTableMoreAction v-if="props.moreActions" :list="props.moreActions" @select="handleMoreActionSelect" />
<div v-if="props.moreActions" class="ms-thumbnail-card-more">
<MsTableMoreAction :list="props.moreActions" @select="handleMoreActionSelect" />
</div>
<a-image
v-if="fileType === 'image'"

View File

@ -188,6 +188,8 @@
@apply w-full;
}
.arco-drawer-close-btn {
@apply flex items-center;
margin-left: 16px;
color: var(--color-text-2);
}

View File

@ -133,3 +133,12 @@ export interface AddRepositoryFileParams {
filePath: string;
enable: boolean;
}
// 关联用例列表项
export interface AssociationItem {
id: string;
sourceId: string; // 资源Id
fileId: string; // 文件Id
sourceName: string; // 资源名称
sourceType: string; // 资源类型
fileVersion: string; // 文件版本
}

View File

@ -34,7 +34,7 @@
{{ t('project.fileManagement.download') }}
</MsButton>
<MsButton
v-if="detail?.storage === 'git'"
v-if="detail?.storage === 'GIT'"
type="icon"
status="secondary"
class="!rounded-[var(--border-radius-small)] !text-[var(--color-text-1)]"
@ -142,7 +142,7 @@
<a-tab-pane key="version" :title="t('project.fileManagement.versionHistory')" />
</a-tabs>
<div class="h-[16px] bg-[var(--color-text-n9)]"></div>
<div v-if="activeTab === 'case'" class="flex items-center justify-between p-[16px]">
<div v-if="activeTab === 'case'" class="flex items-center justify-between px-[16px] pt-[16px]">
<div class="text-[var(--color-text-1)]">{{ t('project.fileManagement.caseList') }}</div>
<a-input-search
v-model:model-value="keyword"
@ -155,9 +155,10 @@
</a-input-search>
</div>
<div class="p-[16px]">
<!-- <ms-base-table
<ms-base-table
v-if="activeTab === 'case'"
v-bind="caseTableProps"
:data="caseList"
no-disable
:action-config="caseBatchActions"
v-on="caseTableEvent"
@ -168,7 +169,7 @@
</MsButton>
</template>
</ms-base-table>
<ms-base-table
<!-- <ms-base-table
v-if="activeTab === 'version'"
v-bind="versionTableProps"
no-disable
@ -184,7 +185,7 @@
</template>
<script setup lang="ts">
import { ref, watch, watchEffect } from 'vue';
import { ref, watch } from 'vue';
import { useFileSystemAccess } from '@vueuse/core';
import { Message } from '@arco-design/web-vue';
import dayjs from 'dayjs';
@ -202,6 +203,7 @@
import {
downloadFile,
getAssociationList,
getFileDetail,
reuploadFile,
toggleJarFileStatus,
@ -215,7 +217,6 @@
import { downloadByteFile, formatFileSize } from '@/utils';
import { FileDetail } from '@/models/projectManagement/file';
import { TableKeyEnum } from '@/enums/tableEnum';
const props = defineProps<{
visible: boolean;
@ -329,7 +330,7 @@
value: dayjs(detail.createTime).format('YYYY-MM-DD HH:mm:ss'),
},
];
if (detail?.storage !== 'minio') {
if (detail?.storage !== 'MINIO') {
fileDescriptions.value.splice(
3,
0,
@ -421,61 +422,68 @@
const activeTab = ref('case');
// const caseColumns: MsTableColumn = [
// {
// title: 'project.fileManagement.id',
// dataIndex: 'id',
// width: 100,
// },
// {
// title: 'project.fileManagement.name',
// dataIndex: 'name',
// showTooltip: true,
// width: 200,
// },
// {
// title: 'project.fileManagement.type',
// dataIndex: 'type',
// },
// {
// title: 'project.fileManagement.fileVersion',
// dataIndex: 'fileVersion',
// },
// {
// title: 'common.operation',
// slotName: 'action',
// fixed: 'right',
// width: 130,
// },
// ];
// const {
// propsRes: caseTableProps,
// propsEvent: caseTableEvent,
// loadList: loadCaseList,
// setKeyword,
// } = useTable(getFileCases, {
// tableKey: TableKeyEnum.FILE_MANAGEMENT_CASE,
// scroll: { x: 800 },
// columns: caseColumns,
// selectable: true,
// showSelectAll: true,
// size: 'default',
// });
const caseColumns: MsTableColumn = [
{
title: 'project.fileManagement.id',
dataIndex: 'id',
width: 100,
},
{
title: 'project.fileManagement.name',
dataIndex: 'sourceName',
showTooltip: true,
width: 200,
},
{
title: 'project.fileManagement.type',
dataIndex: 'sourceType',
},
{
title: 'project.fileManagement.fileVersion',
dataIndex: 'fileVersion',
},
{
title: 'common.operation',
slotName: 'action',
fixed: 'right',
width: 130,
},
];
const {
propsRes: caseTableProps,
propsEvent: caseTableEvent,
loadList: loadCaseList,
setLoadListParams,
setKeyword,
} = useTable(getAssociationList, {
scroll: { x: 800 },
columns: caseColumns,
selectable: true,
showSelectAll: true,
showPagination: false,
size: 'default',
});
// const caseBatchActions = {
// baseAction: [
// {
// label: 'project.fileManagement.updateCaseFile',
// eventTag: 'updateCaseFile',
// },
// ],
// };
const caseBatchActions = {
baseAction: [
{
label: 'project.fileManagement.updateCaseFile',
eventTag: 'updateCaseFile',
},
],
};
const keyword = ref('');
const caseList = ref<any[]>([]);
function searchCase() {
// setKeyword(keyword.value);
// loadCaseList();
function filterCaseList() {
caseList.value = caseTableProps.value.data.filter((item) => item.sourceName.includes(keyword.value));
}
async function searchCase() {
setKeyword(keyword.value);
await loadCaseList();
filterCaseList();
}
function updateCase(record: any) {
@ -514,15 +522,19 @@
// selectable: false,
// });
// watchEffect(() => {
// if (innerVisible.value) {
// if (activeTab.value === 'case') {
// loadCaseList();
// } else {
// loadVersionList();
// }
// }
// });
watchEffect(async () => {
if (innerVisible.value) {
if (activeTab.value === 'case') {
setLoadListParams({
id: props.fileId,
});
await loadCaseList();
filterCaseList();
} else {
// loadVersionList();
}
}
});
</script>
<style lang="less" scoped>

View File

@ -33,7 +33,7 @@
</a-radio-group>
</div>
</div>
<a-spin class="w-full" :loading="loading">
<a-spin class="h-[calc(100%-48px)] w-full" :loading="loading">
<ms-base-table
v-if="showType === 'list'"
v-bind="propsRes"
@ -80,6 +80,7 @@
projectId: appStore.currentProjectId,
moduleId: props.activeFolder,
fileType: tableFileType,
combine,
keyword,
}"
:shadow-limit="50"
@ -372,6 +373,7 @@
} else {
res = await getFileTypes(appStore.currentProjectId);
}
tableFileType.value = '';
tableFileTypeOptions.value = res;
} catch (error) {
// eslint-disable-next-line no-console
@ -772,12 +774,25 @@
/**
* 更改文件展示类型模块/存储库
*/
function changeFileType() {
initFileTypes();
async function changeFileType() {
await initFileTypes();
setTableParams();
loadList();
if (showType.value === 'card') {
cardListRef.value?.reload();
} else {
loadList();
}
}
watch(
() => showType.value,
(val) => {
if (val === 'list') {
loadList();
}
}
);
watch(
() => props.activeFolderType,
(val) => {

View File

@ -167,6 +167,7 @@
activeFolder: string | number;
drawerVisible: boolean;
showType: string;
modulesCount?: Record<string, number>; //
}>();
const emit = defineEmits(['update:drawerVisible', 'itemClick']);
@ -217,7 +218,10 @@
loading.value = true;
const res = await getRepositories(appStore.currentProjectId);
originStorageList.value = res;
storageList.value = [...originStorageList.value];
storageList.value = originStorageList.value.map((e) => ({
...e,
count: props.modulesCount?.[e.id] || 0,
}));
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);

View File

@ -67,6 +67,7 @@
<StorageList
v-model:drawer-visible="storageDrawerVisible"
:active-folder="activeFolder"
:modules-count="modulesCount"
:show-type="showType"
@item-click="storageItemSelect"
/>
@ -148,13 +149,6 @@
return activeFolder.value === id ? 'folder-text folder-text--active' : 'folder-text';
}
type FileShowType = 'Module' | 'Storage';
const showType = ref<FileShowType>('Module');
function changeShowType(val: string | number | boolean) {
showType.value = val as FileShowType;
}
/**
* 处理文件夹树节点选中事件
*/
@ -180,6 +174,14 @@
rootModulesName.value = names;
}
type FileShowType = 'Module' | 'Storage';
const showType = ref<FileShowType>('Module');
const tableFilterParams = ref<FileListQueryParams>({
moduleIds: [],
fileType: '',
projectId: '',
});
const folderTreeRef = ref<InstanceType<typeof FolderTree>>();
/**
* 添加根模块后若当前展示的是模块则刷新模块树
@ -208,13 +210,27 @@
}
}
function changeShowType(val: string | number | boolean) {
showType.value = val as FileShowType;
if (val === 'Storage') {
initModulesCount({
...tableFilterParams.value,
combine: {
...tableFilterParams.value.combine,
storage: 'git',
},
});
} else {
initModulesCount(tableFilterParams.value);
}
}
/**
* 右侧表格数据刷新后若当前展示的是模块则刷新模块树的统计数量
*/
function handleModuleTableInit(params: FileListQueryParams) {
if (showType.value === 'Module') {
initModulesCount(params);
}
initModulesCount(params);
tableFilterParams.value = { ...params };
}
</script>