feat(文件管理): 文件管理部分接口&部分组件调整&无权限登录无限重定向问题解决

This commit is contained in:
baiqi 2023-11-02 10:13:03 +08:00 committed by rubylliu
parent 1514ab80db
commit eb9e4253e7
8 changed files with 120 additions and 52 deletions

View File

@ -129,11 +129,11 @@
// 01 // 01
const activeDetailIsFirst = computed(() => activeDetailIndex.value === 0 && props.pagination?.current === 1); const activeDetailIsFirst = computed(() => activeDetailIndex.value === 0 && props.pagination?.current === 1);
const activeDetailIsLast = computed( const activeDetailIsLast = computed(
// *+ // (-1)*+
() => () =>
activeDetailIndex.value === props.tableData.length - 1 && activeDetailIndex.value === props.tableData.length - 1 &&
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
props.pagination!.current * props.pagination!.pageSize + activeDetailIndex.value >= (props.pagination!.current - 1) * props.pagination!.pageSize + (activeDetailIndex.value + 1) >=
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
props.pagination!.total props.pagination!.total
); );
@ -158,6 +158,7 @@
activeDetailId.value = props.tableData[activeDetailIndex.value - 1].id; activeDetailId.value = props.tableData[activeDetailIndex.value - 1].id;
activeDetailIndex.value -= 1; activeDetailIndex.value -= 1;
} }
initDetail();
} }
} }
@ -181,13 +182,16 @@
activeDetailId.value = props.tableData[activeDetailIndex.value + 1].id; activeDetailId.value = props.tableData[activeDetailIndex.value + 1].id;
activeDetailIndex.value += 1; activeDetailIndex.value += 1;
} }
initDetail();
} }
} }
watch( watch(
() => activeDetailId.value, () => innerVisible.value,
() => { (val) => {
initDetail(); if (val) {
initDetail();
}
} }
); );

View File

@ -1,11 +1,12 @@
<template> <template>
<div <div
:class="`ms-button ms-button-${props.type} ms-button--${props.status} ${ :class="`ms-button ms-button-${props.type} ms-button--${props.status} ${
props.disabled ? 'ms-button--disabled' : '' props.disabled || props.loading ? 'ms-button--disabled' : ''
}`" }`"
@click="clickHandler" @click="clickHandler"
> >
<slot></slot> <slot></slot>
<icon-loading v-if="props.loading" />
</div> </div>
</template> </template>
@ -15,6 +16,7 @@
type?: 'text' | 'icon' | 'button'; type?: 'text' | 'icon' | 'button';
status?: 'primary' | 'danger' | 'secondary'; status?: 'primary' | 'danger' | 'secondary';
disabled?: boolean; disabled?: boolean;
loading?: boolean;
}>(), }>(),
{ {
type: 'text', type: 'text',

View File

@ -22,11 +22,13 @@
<slot name="item-value" :item="item"> <slot name="item-value" :item="item">
<template v-if="item.isTag"> <template v-if="item.isTag">
<MsTag <MsTag
v-for="tag of item.value" v-for="tag of Array.isArray(item.value) ? item.value : [item.value]"
:key="`${tag}`" :key="`${tag}`"
theme="outline" theme="outline"
color="var(--color-text-n8)" color="var(--color-text-n8)"
class="mb-[8px] mr-[8px] font-normal !text-[var(--color-text-1)]" class="mb-[8px] mr-[8px] font-normal !text-[var(--color-text-1)]"
:closable="item.closable"
@close="emit('tagClose', tag, item)"
> >
{{ tag }} {{ tag }}
</MsTag> </MsTag>
@ -106,6 +108,7 @@
value: (string | number) | (string | number)[]; value: (string | number) | (string | number)[];
key?: string; key?: string;
isTag?: boolean; // isTag?: boolean; //
closable?: boolean; //
showTagAdd?: boolean; // showTagAdd?: boolean; //
isButton?: boolean; isButton?: boolean;
showCopy?: boolean; showCopy?: boolean;
@ -120,7 +123,7 @@
column?: number; column?: number;
descriptions: Description[]; descriptions: Description[];
labelWidth?: string; labelWidth?: string;
addTagFunc?: (val: string) => Promise<void>; addTagFunc?: (val: string, item: Description) => Promise<void>;
}>(), }>(),
{ {
column: 1, column: 1,
@ -128,6 +131,7 @@
); );
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'addTag', val: string): void; (e: 'addTag', val: string): void;
(e: 'tagClose', tag: string | number, item: Description): void;
}>(); }>();
const { t } = useI18n(); const { t } = useI18n();
@ -163,6 +167,10 @@
* @param item 当前标签项 * @param item 当前标签项
*/ */
async function handleAddTag(item: Description) { async function handleAddTag(item: Description) {
if (addTagInput.value.trim() === '') {
showTagInput.value = false;
return;
}
if (Array.isArray(item.value) && item.value.includes(addTagInput.value)) { if (Array.isArray(item.value) && item.value.includes(addTagInput.value)) {
tagInputError.value = t('ms.description.addTagRepeat'); tagInputError.value = t('ms.description.addTagRepeat');
return; return;
@ -171,7 +179,7 @@
try { try {
tagInputLoading.value = true; tagInputLoading.value = true;
if (props.addTagFunc && typeof props.addTagFunc === 'function') { if (props.addTagFunc && typeof props.addTagFunc === 'function') {
await props.addTagFunc(addTagInput.value); await props.addTagFunc(addTagInput.value, item);
if (Array.isArray(item.value)) { if (Array.isArray(item.value)) {
item.value.push(addTagInput.value); item.value.push(addTagInput.value);
} else { } else {
@ -180,6 +188,7 @@
} else { } else {
emit('addTag', addTagInput.value); emit('addTag', addTagInput.value);
} }
addTagInput.value = '';
showTagInput.value = false; showTagInput.value = false;
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console

View File

@ -3,17 +3,18 @@
v-bind="attrs" v-bind="attrs"
:type="props.type" :type="props.type"
defer defer
:size="props.size"
:style="{ :style="{
...typeStyle, ...typeStyle,
'margin-right': tagMargin, 'margin-right': tagMargin,
'min-width': props.width && `${props.width}ch`, 'min-width': props.width && `${props.width}ch`,
'max-width: 144px': !props.width, 'max-width': '144px',
}" }"
:size="props.size"
class="inline-block"
> >
<slot name="icon"></slot> <slot name="icon"></slot>
<slot></slot> <div class="one-line-text">
<slot></slot>
</div>
</a-tag> </a-tag>
</template> </template>

View File

@ -28,6 +28,7 @@ export interface FileDetail extends FileItem {
projectId: string; projectId: string;
moduleName: string; // 所属模块名 moduleName: string; // 所属模块名
moduleId: string; moduleId: string;
storage?: string; // 存储方式
createUser: string; createUser: string;
createTime: number; createTime: number;
} }
@ -43,7 +44,7 @@ export interface UploadFileParams {
export interface UpdateFileParams { export interface UpdateFileParams {
id: string; id: string;
name?: string; name?: string;
tags?: string[]; tags?: (string | number)[];
description?: string; description?: string;
moduleId?: string; moduleId?: string;
} }

View File

@ -28,7 +28,7 @@ function setupPageGuard(router: Router) {
} }
switch (getRouteLevelByKey(to.name as PathMapRoute)) { switch (getRouteLevelByKey(to.name as PathMapRoute)) {
case MENU_LEVEL[1]: // 组织级别的页面,需要给页面携带上组织 ID case MENU_LEVEL[1]: // 组织级别的页面,需要给页面携带上组织 ID
if (!urlOrgId) { if (urlOrgId === undefined) {
to.query = { to.query = {
...to.query, ...to.query,
organizationId: appStore.currentOrgId, organizationId: appStore.currentOrgId,
@ -38,7 +38,7 @@ function setupPageGuard(router: Router) {
} }
break; break;
case MENU_LEVEL[2]: // 项目级别的页面,需要给页面携带上组织 ID和项目 ID case MENU_LEVEL[2]: // 项目级别的页面,需要给页面携带上组织 ID和项目 ID
if (!urlOrgId && !urlProjectId) { if (urlOrgId === undefined && urlProjectId === undefined) {
to.query = { to.query = {
...to.query, ...to.query,
organizationId: appStore.currentOrgId, organizationId: appStore.currentOrgId,

View File

@ -16,7 +16,7 @@
<template #titleRight="{ loading, detail }"> <template #titleRight="{ loading, detail }">
<a-switch <a-switch
v-if="fileType === 'jar'" v-if="fileType === 'jar'"
:default-checked="detail?.enable" v-model:model-value="detail.enable"
:before-change="handleEnableIntercept" :before-change="handleEnableIntercept"
:disabled="loading" :disabled="loading"
size="small" size="small"
@ -27,7 +27,8 @@
status="secondary" status="secondary"
class="!rounded-[var(--border-radius-small)] !text-[var(--color-text-1)]" class="!rounded-[var(--border-radius-small)] !text-[var(--color-text-1)]"
:disabled="loading" :disabled="loading"
@click="handleDownload" :loading="downLoading"
@click="handleDownload(detail)"
> >
<MsIcon type="icon-icon_bottom-align_outlined" class="mr-[4px]" /> <MsIcon type="icon-icon_bottom-align_outlined" class="mr-[4px]" />
{{ t('project.fileManagement.download') }} {{ t('project.fileManagement.download') }}
@ -71,6 +72,7 @@
:descriptions="fileDescriptions" :descriptions="fileDescriptions"
:label-width="currentLocale === 'zh-CN' ? '80px' : '100px'" :label-width="currentLocale === 'zh-CN' ? '80px' : '100px'"
:add-tag-func="addFileTag" :add-tag-func="addFileTag"
@tag-close="handleFileTagClose"
> >
<template #value="{ item }"> <template #value="{ item }">
<div class="flex flex-wrap items-center"> <div class="flex flex-wrap items-center">
@ -197,13 +199,20 @@
import MsThumbnailCard from '@/components/business/ms-thumbnail-card/index.vue'; import MsThumbnailCard from '@/components/business/ms-thumbnail-card/index.vue';
import popConfirm from './popConfirm.vue'; import popConfirm from './popConfirm.vue';
import { getFileDetail, reuploadFile, updateFile } from '@/api/modules/project-management/fileManagement'; import {
downloadFile,
getFileDetail,
reuploadFile,
toggleJarFileStatus,
updateFile,
} from '@/api/modules/project-management/fileManagement';
import { CompressImgUrl, OriginImgUrl } from '@/api/requrls/project-management/fileManagement'; import { CompressImgUrl, OriginImgUrl } from '@/api/requrls/project-management/fileManagement';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import useLocale from '@/locale/useLocale'; import useLocale from '@/locale/useLocale';
import useUserStore from '@/store/modules/user'; import useUserStore from '@/store/modules/user';
import { downloadUrlFile, formatFileSize } from '@/utils'; import { downloadByteFile, downloadUrlFile, formatFileSize } from '@/utils';
import { FileDetail } from '@/models/projectManagement/file';
import { TableKeyEnum } from '@/enums/tableEnum'; import { TableKeyEnum } from '@/enums/tableEnum';
const props = defineProps<{ const props = defineProps<{
@ -241,22 +250,38 @@
); );
async function handleEnableIntercept(newValue: string | number | boolean) { async function handleEnableIntercept(newValue: string | number | boolean) {
await new Promise((resolve) => { try {
setTimeout(() => { await toggleJarFileStatus(props.fileId, newValue as boolean);
resolve(true); return true;
}, 1000); } catch (error) {
}); // eslint-disable-next-line no-console
return true; console.log(error);
return false;
}
} }
function handleDownload(detail: any) { const downLoading = ref(false);
downloadUrlFile(detail.url, detail.name); /**
* 下载单个文件
* @param record 表格数据项
*/
async function handleDownload(detail: FileDetail) {
try {
downLoading.value = true;
const res = await downloadFile(detail.id);
downloadByteFile(res, `${detail.name}.${detail.fileType}`);
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
} finally {
downLoading.value = false;
}
} }
const fileType = ref('unknown'); const fileType = ref('unknown');
const renameTitle = ref(''); // const renameTitle = ref(''); //
function loadedFile(detail: any) { function loadedFile(detail: FileDetail) {
if (detail.fileType) { if (detail.fileType) {
fileType.value = getFileEnum(`/${detail.fileType.toLowerCase()}`); fileType.value = getFileEnum(`/${detail.fileType.toLowerCase()}`);
} }
@ -269,7 +294,7 @@
}, },
{ {
label: t('project.fileManagement.desc'), label: t('project.fileManagement.desc'),
value: detail.desc, value: detail.description,
key: 'desc', key: 'desc',
}, },
{ {
@ -291,9 +316,10 @@
}, },
{ {
label: t('project.fileManagement.tag'), label: t('project.fileManagement.tag'),
value: detail.tag, value: detail.tags,
isTag: true, isTag: true,
showTagAdd: true, showTagAdd: true,
closable: true,
key: 'tag', key: 'tag',
}, },
{ {
@ -306,18 +332,18 @@
3, 3,
0, 0,
...[ ...[
{ // {
label: t('project.fileManagement.gitBranch'), // label: t('project.fileManagement.gitBranch'),
value: detail.gitBranch, // value: detail.gitBranch,
}, // },
{ // {
label: t('project.fileManagement.gitPath'), // label: t('project.fileManagement.gitPath'),
value: detail.gitPath, // value: detail.gitPath,
}, // },
{ // {
label: t('project.fileManagement.gitVersion'), // label: t('project.fileManagement.gitVersion'),
value: detail.gitVersion, // value: detail.gitVersion,
}, // },
] ]
); );
} }
@ -359,10 +385,17 @@
const previewVisible = ref(false); const previewVisible = ref(false);
async function addFileTag(val: string) { async function addFileTag(val: string, item: Description) {
await updateFile({ await updateFile({
id: props.fileId, id: props.fileId,
tags: [val], tags: Array.isArray(item.value) ? [...item.value, val] : [item.value, val],
});
}
async function handleFileTagClose(tag: string | number, item: Description) {
await updateFile({
id: props.fileId,
tags: Array.isArray(item.value) ? item.value.filter((e) => e !== tag) : [],
}); });
} }

View File

@ -466,12 +466,21 @@
]; ];
const tableStore = useTableStore(); const tableStore = useTableStore();
tableStore.initColumn(TableKeyEnum.FILE_MANAGEMENT_FILE, columns, 'drawer'); tableStore.initColumn(TableKeyEnum.FILE_MANAGEMENT_FILE, columns, 'drawer');
const { propsRes, propsEvent, loadList, setLoadListParams } = useTable(getFileList, { const { propsRes, propsEvent, loadList, setLoadListParams } = useTable(
tableKey: TableKeyEnum.FILE_MANAGEMENT_FILE, getFileList,
showSetting: true, {
selectable: true, tableKey: TableKeyEnum.FILE_MANAGEMENT_FILE,
showSelectAll: true, showSetting: true,
}); selectable: true,
showSelectAll: true,
},
(item) => {
return {
...item,
tags: item.tags?.map((e: string) => ({ id: e, name: e })) || [],
};
}
);
const moduleFileBatchActions = { const moduleFileBatchActions = {
baseAction: [ baseAction: [
{ {
@ -653,7 +662,7 @@
try { try {
batchMoveFileLoading.value = true; batchMoveFileLoading.value = true;
await batchMoveFile({ await batchMoveFile({
selectIds: batchParams.value?.selectedIds || [activeFile.value?.id || ''], selectIds: isBatchMove.value ? batchParams.value?.selectedIds || [] : [activeFile.value?.id || ''],
selectAll: !!batchParams.value?.selectAll, selectAll: !!batchParams.value?.selectAll,
excludeIds: batchParams.value?.excludeIds || [], excludeIds: batchParams.value?.excludeIds || [],
condition: { keyword: keyword.value, comebine: combine.value }, condition: { keyword: keyword.value, comebine: combine.value },
@ -834,6 +843,15 @@
activeFileIndex.value = index; activeFileIndex.value = index;
} }
watch(
() => showDetailDrawer.value,
(val) => {
if (!val) {
loadList();
}
}
);
const uploadDrawerVisible = ref(false); // - const uploadDrawerVisible = ref(false); // -
const fileList = ref<MsFileItem[]>(asyncTaskStore.uploadFileTask.fileList); const fileList = ref<MsFileItem[]>(asyncTaskStore.uploadFileTask.fileList);
// //