feat(文件管理): 文件管理部分接口&部分组件调整
This commit is contained in:
parent
7f8173b5f8
commit
dc49dc4e3c
|
@ -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 });
|
||||
}
|
||||
|
|
|
@ -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'; // 获取关联用例列表
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -188,6 +188,8 @@
|
|||
@apply w-full;
|
||||
}
|
||||
.arco-drawer-close-btn {
|
||||
@apply flex items-center;
|
||||
|
||||
margin-left: 16px;
|
||||
color: var(--color-text-2);
|
||||
}
|
||||
|
|
|
@ -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; // 文件版本
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
Loading…
Reference in New Issue