fix(缺陷管理&用例管理): 修改缺陷管理用例管理文件转存&用例需求bug&授权到期移动到全局布局

This commit is contained in:
xinxin.wu 2024-04-26 12:05:45 +08:00 committed by 刘瑞斌
parent e62728ad81
commit e46d26da57
24 changed files with 133 additions and 159 deletions

View File

@ -71,12 +71,14 @@
visible: boolean; visible: boolean;
savingFile?: MsFileItem; savingFile?: MsFileItem;
fileSaveAsSourceId: string | number; fileSaveAsSourceId: string | number;
sourceIdKey?: string; // idkey
fileIdKey?: string; fileIdKey?: string;
fileSaveAsApi?: (params: TransferFileParams) => Promise<string>; fileSaveAsApi?: (params: TransferFileParams) => Promise<string>;
fileModuleOptionsApi?: (projectId: string) => Promise<ModuleTreeNode[]>; // fileModuleOptionsApi?: (projectId: string) => Promise<ModuleTreeNode[]>; //
}>(), }>(),
{ {
fileIdKey: 'fileId', fileIdKey: 'fileId',
sourceIdKey: 'sourceId',
} }
); );
const emit = defineEmits<{ const emit = defineEmits<{
@ -148,7 +150,7 @@
saveLoading.value = true; saveLoading.value = true;
const res = await props.fileSaveAsApi({ const res = await props.fileSaveAsApi({
projectId: appStore.currentProjectId, projectId: appStore.currentProjectId,
sourceId: props.fileSaveAsSourceId || '', [props.sourceIdKey || 'sourceId']: props.fileSaveAsSourceId || '',
fileId: props.savingFile[props.fileIdKey] || props.savingFile.uid, fileId: props.savingFile[props.fileIdKey] || props.savingFile.uid,
local: true, local: true,
moduleId: saveFileForm.value.moduleId, moduleId: saveFileForm.value.moduleId,

View File

@ -37,6 +37,7 @@
:current-data="attrs.data as Record<string,any>[]" :current-data="attrs.data as Record<string,any>[]"
:show-select-all="!!attrs.showPagination && props.showSelectorAll" :show-select-all="!!attrs.showPagination && props.showSelectorAll"
:disabled="(attrs.data as []).length === 0" :disabled="(attrs.data as []).length === 0"
:row-key="rowKey"
@change="handleSelectAllChange" @change="handleSelectAllChange"
/> />
</template> </template>
@ -92,12 +93,20 @@
@init-data="handleInitColumn" @init-data="handleInitColumn"
/> />
<slot v-else-if="item.filterConfig" :name="item.filterConfig.filterSlotName"> <slot v-else-if="item.filterConfig" :name="item.filterConfig.filterSlotName">
<DefaultFilter <!-- <DefaultFilter
class="ml-[4px]" class="ml-[4px]"
:options="item.filterConfig.options" :options="item.filterConfig.options"
:multiple="(item.filterConfig.multiple as boolean)" @handle-confirm="(v) => handleFilterConfirm(v, item.dataIndex as string, item.isCustomParam || false)"
@handle-confirm="(v) => handleFilterConfirm(v, item.dataIndex as string, item.filterConfig?.multiple || false,item.isCustomParam || false)" /> -->
/> <!-- TODO 待办 过滤选项不生效 -->
<!-- <TableFilter
v-bind="item.filterConfig"
@handle-confirm="(v) => handleFilterConfirm(v, item.dataIndex as string,item.isCustomParam || false)"
>
<template #item="{ item: itemValue, index }">
<slot name="filter-content" :item="itemValue" :index="index"> </slot>
</template>
</TableFilter> -->
</slot> </slot>
</div> </div>
</template> </template>
@ -271,7 +280,9 @@
import BatchAction from './batchAction.vue'; import BatchAction from './batchAction.vue';
import ColumnSelector from './columnSelector.vue'; import ColumnSelector from './columnSelector.vue';
import columnSelectorIcon from './columnSelectorIcon.vue'; import columnSelectorIcon from './columnSelectorIcon.vue';
import DefaultFilter from './comp/defaultFilter.vue'; // TODO
// import DefaultFilter from './comp/defaultFilter.vue';
// import TableFilter from './comp/tableFilter.vue';
import SelectALL from './select-all.vue'; import SelectALL from './select-all.vue';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
@ -335,7 +346,7 @@
(e: 'expand', record: TableData): void | Promise<any>; (e: 'expand', record: TableData): void | Promise<any>;
(e: 'cell-click', record: TableData, column: TableColumnData, ev: Event): void | Promise<any>; (e: 'cell-click', record: TableData, column: TableColumnData, ev: Event): void | Promise<any>;
(e: 'clearSelector'): void; (e: 'clearSelector'): void;
(e: 'filterChange', dataIndex: string, value: (string | number)[], multiple: boolean, isCustomParam: boolean): void; (e: 'filterChange', dataIndex: string, value: (string | number)[], isCustomParam: boolean): void;
(e: 'moduleChange'): void; (e: 'moduleChange'): void;
(e: 'initEnd'): void; (e: 'initEnd'): void;
}>(); }>();
@ -445,7 +456,7 @@
function handleRadioChange(val: boolean, record: TableData) { function handleRadioChange(val: boolean, record: TableData) {
if (val) { if (val) {
selectedKey.value = record.id; selectedKey.value = record[rowKey as string];
record.tableChecked = true; record.tableChecked = true;
tempRecord.value.tableChecked = false; tempRecord.value.tableChecked = false;
tempRecord.value = record; tempRecord.value = record;
@ -617,14 +628,9 @@
columnSelectorVisible.value = true; columnSelectorVisible.value = true;
}; };
const handleFilterConfirm = ( // const handleFilterConfirm = (value: (string | number)[], dataIndex: string, isCustomParam: boolean) => {
value: (string | number)[], // emit('filterChange', dataIndex, value, isCustomParam);
dataIndex: string, // };
multiple: boolean,
isCustomParam: boolean
) => {
emit('filterChange', dataIndex, value, multiple, isCustomParam);
};
onMounted(async () => { onMounted(async () => {
await initColumn(); await initColumn();

View File

@ -42,12 +42,14 @@
showSelectAll: boolean; showSelectAll: boolean;
disabled: boolean; disabled: boolean;
excludeKeys: string[]; excludeKeys: string[];
rowKey?: string;
}>(), }>(),
{ {
current: 0, current: 0,
total: 0, total: 0,
showSelectAll: true, showSelectAll: true,
disabled: false, disabled: false,
rowKey: 'id',
} }
); );
@ -79,7 +81,7 @@
}; };
const handleCheckChange = () => { const handleCheckChange = () => {
if (props.currentData.some((item) => !props.selectedKeys.has(item.id))) { if (props.currentData.some((item) => !props.selectedKeys.has(item[props.rowKey]))) {
// //
handleSelect(SelectAllEnum.CURRENT); handleSelect(SelectAllEnum.CURRENT);
} else { } else {

View File

@ -293,6 +293,7 @@ export default function useTableProps<T>(
// 重置选择器 // 重置选择器
const resetSelector = (isNone = true) => { const resetSelector = (isNone = true) => {
const { rowKey } = propsRes.value;
if (isNone) { if (isNone) {
propsRes.value.selectorStatus = SelectAllEnum.NONE; propsRes.value.selectorStatus = SelectAllEnum.NONE;
// 清空选中项 // 清空选中项
@ -301,8 +302,8 @@ export default function useTableProps<T>(
} else { } else {
// 取消当前页的选中项 // 取消当前页的选中项
propsRes.value.data.forEach((item) => { propsRes.value.data.forEach((item) => {
propsRes.value.selectedKeys.delete(item.id); propsRes.value.selectedKeys.delete(item[rowKey]);
propsRes.value.excludeKeys.delete(item.id); propsRes.value.excludeKeys.delete(item[rowKey]);
}); });
} }
}; };

View File

@ -1,4 +1,3 @@
import { useAppStore } from '@/store';
import useLicenseStore from '@/store/modules/setting/license'; import useLicenseStore from '@/store/modules/setting/license';
/** /**
@ -8,8 +7,7 @@ import useLicenseStore from '@/store/modules/setting/license';
function checkHasLicenseExpiration(el: HTMLElement) { function checkHasLicenseExpiration(el: HTMLElement) {
const licenseStore = useLicenseStore(); const licenseStore = useLicenseStore();
const appStore = useAppStore(); const isValid = licenseStore.expiredDuring;
const isValid = licenseStore.expiredDuring && appStore.packageType === 'enterprise';
if (!isValid && el.parentNode) { if (!isValid && el.parentNode) {
el.parentNode.removeChild(el); el.parentNode.removeChild(el);

View File

@ -45,6 +45,8 @@
<MsBreadCrumb /> <MsBreadCrumb />
<a-layout-content> <a-layout-content>
<slot name="page"> <slot name="page">
<!-- 授权到期在系统菜单展示提示 -->
<ExpireAlert v-if="isShowExpireTime" />
<PageLayout v-if="!props.isPreview" /> <PageLayout v-if="!props.isPreview" />
</slot> </slot>
<slot></slot> <slot></slot>
@ -68,6 +70,7 @@
import MsBreadCrumb from '@/components/business/ms-breadcrumb/index.vue'; import MsBreadCrumb from '@/components/business/ms-breadcrumb/index.vue';
import MsMenu from '@/components/business/ms-menu/index.vue'; import MsMenu from '@/components/business/ms-menu/index.vue';
import PageLayout from './page-layout.vue'; import PageLayout from './page-layout.vue';
import ExpireAlert from '@/views/setting/system/authorizedManagement/components/expireAlert.vue';
import { GetTitleImgUrl } from '@/api/requrls/setting/config'; import { GetTitleImgUrl } from '@/api/requrls/setting/config';
import usePermission from '@/hooks/usePermission'; import usePermission from '@/hooks/usePermission';
@ -124,6 +127,9 @@
const paddingTop = navbar.value ? { paddingTop: navbarHeight } : {}; const paddingTop = navbar.value ? { paddingTop: navbarHeight } : {};
return { ...paddingLeft, ...paddingTop }; return { ...paddingLeft, ...paddingTop };
}); });
const isShowExpireTime = computed(() => {
return route.path.includes('/setting/system');
});
const setCollapsed = (val: boolean) => { const setCollapsed = (val: boolean) => {
if (!isInit.value) return; // for page initialization menu state problem if (!isInit.value) return; // for page initialization menu state problem
appStore.updateSettings({ menuCollapse: val }); appStore.updateSettings({ menuCollapse: val });

View File

@ -88,10 +88,11 @@ export interface DragSortParams {
// 文件转存入参 // 文件转存入参
export interface TransferFileParams { export interface TransferFileParams {
projectId: string; projectId: string;
sourceId: string | number; sourceId?: string | number;
fileName?: string; fileName?: string;
fileId: string; fileId: string;
local: true; local: true;
moduleId: string; moduleId: string;
originalName?: string; originalName?: string;
[x: string]: any;
} }

View File

@ -109,6 +109,15 @@
> >
{{ t('caseManagement.featureCase.storage') }} {{ t('caseManagement.featureCase.storage') }}
</MsButton> </MsButton>
<SaveAsFilePopover
v-model:visible="transferVisible"
:saving-file="activeTransferFileParams"
:file-save-as-source-id="props.detailInfo.id"
:file-save-as-api="transferFileRequest"
:file-module-options-api="getTransferFileTree"
source-id-key="bugId"
@finish="emit('updateSuccess')"
/>
<MsButton <MsButton
v-if="item.status === 'done'" v-if="item.status === 'done'"
type="button" type="button"
@ -186,12 +195,6 @@
@save="saveSelectAssociatedFile" @save="saveSelectAssociatedFile"
/> />
<a-image-preview v-model:visible="previewVisible" :src="imageUrl" /> <a-image-preview v-model:visible="previewVisible" :src="imageUrl" />
<TransferModal
v-model:visible="transferVisible"
:request-fun="transferFileRequest"
:params="activeTransferFileParams"
@success="emit('updateSuccess')"
/>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -205,8 +208,8 @@
import MsUpload from '@/components/pure/ms-upload/index.vue'; import MsUpload from '@/components/pure/ms-upload/index.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 SaveAsFilePopover from '@/components/business/ms-add-attachment/saveAsFilePopover.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 { import {
checkFileIsUpdateRequest, checkFileIsUpdateRequest,
@ -221,6 +224,7 @@
updateFile, updateFile,
uploadOrAssociationFile, uploadOrAssociationFile,
} from '@/api/modules/bug-management'; } from '@/api/modules/bug-management';
import { getTransferFileTree } from '@/api/modules/case-management/featureCase';
import { getModules, getModulesCount } from '@/api/modules/project-management/fileManagement'; import { getModules, getModulesCount } from '@/api/modules/project-management/fileManagement';
import { EditorPreviewFileUrl } from '@/api/requrls/bug-management'; import { EditorPreviewFileUrl } from '@/api/requrls/bug-management';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
@ -230,7 +234,6 @@
import { findParents, Option } from '@/utils/recursion'; import { findParents, Option } from '@/utils/recursion';
import { BugEditCustomField, BugEditCustomFieldItem, BugEditFormObject } from '@/models/bug-management'; import { BugEditCustomField, BugEditCustomFieldItem, BugEditFormObject } from '@/models/bug-management';
import type { OperationFile } from '@/models/caseManagement/featureCase';
import { AssociatedList, AttachFileInfo } from '@/models/caseManagement/featureCase'; import { AssociatedList, AttachFileInfo } from '@/models/caseManagement/featureCase';
import { TableQueryParams } from '@/models/common'; import { TableQueryParams } from '@/models/common';
@ -349,15 +352,6 @@
} }
} }
function beforeUpload(file: File) {
const _maxSize = 50 * 1024 * 1024;
if (file.size > _maxSize) {
Message.warning(t('ms.upload.overSize'));
return Promise.resolve(false);
}
return Promise.resolve(true);
}
// //
async function handlePreview(item: MsFileItem) { async function handlePreview(item: MsFileItem) {
try { try {
@ -536,19 +530,12 @@
await handleFileFunc(attachments); await handleFileFunc(attachments);
Message.success(t('common.linkSuccess')); Message.success(t('common.linkSuccess'));
} }
const activeTransferFileParams = ref<OperationFile>({
projectId: '', const activeTransferFileParams = ref<MsFileItem>();
bugId: '',
fileId: '',
local: true,
});
function transferHandler(item: MsFileItem) { function transferHandler(item: MsFileItem) {
activeTransferFileParams.value = { activeTransferFileParams.value = {
projectId: currentProjectId.value, ...item,
fileId: item.uid,
bugId: props.detailInfo.id,
local: true,
}; };
transferVisible.value = true; transferVisible.value = true;
} }

View File

@ -96,20 +96,18 @@
type="button" type="button"
status="primary" status="primary"
class="!mr-[4px]" class="!mr-[4px]"
@click="transferFile" @click="transferFile(item)"
> >
{{ t('caseManagement.featureCase.storage') }} {{ t('caseManagement.featureCase.storage') }}
</MsButton> </MsButton>
<TransferModal <SaveAsFilePopover
v-model:visible="transferVisible" v-model:visible="transferVisible"
:request-fun="transferFileRequest" :saving-file="activeTransferFileParams"
:params="{ :file-save-as-source-id="(form.id as string)"
projectId: currentProjectId, :file-save-as-api="transferFileRequest"
bugId: bugId as string, :file-module-options-api="getTransferFileTree"
fileId: item.uid, source-id-key="bugId"
associated: !item.local, @finish="getDetailInfo()"
}"
@success="getDetailInfo()"
/> />
<MsButton <MsButton
v-if="item.status !== 'init'" v-if="item.status !== 'init'"
@ -223,8 +221,8 @@
import MsUpload from '@/components/pure/ms-upload/index.vue'; import MsUpload from '@/components/pure/ms-upload/index.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 SaveAsFilePopover from '@/components/business/ms-add-attachment/saveAsFilePopover.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 { import {
checkFileIsUpdateRequest, checkFileIsUpdateRequest,
@ -239,6 +237,7 @@
transferFileRequest, transferFileRequest,
updateFile, updateFile,
} from '@/api/modules/bug-management'; } from '@/api/modules/bug-management';
import { getTransferFileTree } from '@/api/modules/case-management/featureCase';
import { getModules, getModulesCount } from '@/api/modules/project-management/fileManagement'; import { getModules, getModulesCount } from '@/api/modules/project-management/fileManagement';
import { EditorPreviewFileUrl } from '@/api/requrls/bug-management'; import { EditorPreviewFileUrl } from '@/api/requrls/bug-management';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
@ -329,6 +328,9 @@
const { getIsVisited } = useVisit(visitedKey); const { getIsVisited } = useVisit(visitedKey);
const title = computed(() => { const title = computed(() => {
if (isCopy.value) {
return t('bugManagement.copyBug');
}
return isEdit.value ? t('bugManagement.editBug') : t('bugManagement.createBug'); return isEdit.value ? t('bugManagement.editBug') : t('bugManagement.createBug');
}); });
const isLoading = ref<boolean>(true); const isLoading = ref<boolean>(true);
@ -368,8 +370,12 @@
); );
const transferVisible = ref<boolean>(false); const transferVisible = ref<boolean>(false);
const activeTransferFileParams = ref<MsFileItem>();
// //
function transferFile() { function transferFile(item: MsFileItem) {
activeTransferFileParams.value = {
...item,
};
transferVisible.value = true; transferVisible.value = true;
} }
@ -761,10 +767,18 @@
}); });
} }
const { platformSystemFields } = form.value; const { platformSystemFields } = form.value;
let copyName = '';
if (isCopy.value) {
copyName = `copy_${res.title}`;
if (copyName.length > 255) {
form.value.title = copyName.slice(0, 255);
}
}
// //
form.value = { form.value = {
id: res.id, id: res.id,
title: res.title, title: isCopy.value ? copyName : res.title,
description: res.description, description: res.description,
templateId: res.templateId, templateId: res.templateId,
tags: res.tags || [], tags: res.tags || [],
@ -801,15 +815,6 @@
{ deep: true } { deep: true }
); );
function renameCopyBug() {
if (isCopy.value) {
const copyName = `copy_${form.value.title}`;
if (copyName.length > 255) {
form.value.title = copyName.slice(0, 255);
}
}
}
async function handleUploadImage(file: File) { async function handleUploadImage(file: File) {
const { data } = await editorUploadFile({ const { data } = await editorUploadFile({
fileList: [file], fileList: [file],
@ -822,7 +827,6 @@
if (isEditOrCopy.value) { if (isEditOrCopy.value) {
// //
await getDetailInfo(); await getDetailInfo();
renameCopyBug();
} }
}); });
</script> </script>

View File

@ -4,6 +4,7 @@ export default {
addBug: '创建缺陷', addBug: '创建缺陷',
editBug: '更新缺陷', editBug: '更新缺陷',
createBug: '创建缺陷', createBug: '创建缺陷',
copyBug: '复制缺陷',
syncBug: '同步缺陷', syncBug: '同步缺陷',
ID: 'ID', ID: 'ID',
project: '项目', project: '项目',

View File

@ -28,10 +28,11 @@
</a-popover> </a-popover>
</template> </template>
<template #right> <template #right>
<a-radio-group v-model:model-value="showType" type="button" class="file-show-type"> <!-- TODO 暂时先不展示了 -->
<!-- <a-radio-group v-model:model-value="showType" type="button" class="file-show-type">
<a-radio value="list" class="show-type-icon p-[2px]"><MsIcon type="icon-icon_view-list_outlined" /></a-radio> <a-radio value="list" class="show-type-icon p-[2px]"><MsIcon type="icon-icon_view-list_outlined" /></a-radio>
<!-- <a-radio value="xMind" class="show-type-icon p-[2px]"><MsIcon type="icon-icon_mindnote_outlined" /></a-radio>--> <a-radio value="xMind" class="show-type-icon p-[2px]"><MsIcon type="icon-icon_mindnote_outlined" /></a-radio>
</a-radio-group> </a-radio-group> -->
</template> </template>
</MsAdvanceFilter> </MsAdvanceFilter>
<ms-base-table <ms-base-table
@ -226,6 +227,8 @@
<a-tree-select <a-tree-select
v-if="record.showModuleTree" v-if="record.showModuleTree"
v-model:modelValue="record.moduleId" v-model:modelValue="record.moduleId"
dropdown-class-name="tree-dropdown"
class="param-input w-full"
:data="caseTreeData" :data="caseTreeData"
:allow-search="true" :allow-search="true"
:field-names="{ :field-names="{
@ -233,19 +236,18 @@
key: 'id', key: 'id',
children: 'children', children: 'children',
}" }"
size="mini"
:tree-props="{ :tree-props="{
virtualListProps: { virtualListProps: {
height: 200, height: 200,
}, },
}" }"
size="mini"
:filter-tree-node="filterTreeNode"
@click.stop @click.stop
@change="(value) => handleChangeModule(record, value)" @change="(value) => handleChangeModule(record, value)"
> >
<template #tree-slot-title="node"> <template #tree-slot-title="node">
<a-tooltip :content="`${node.name}`" position="tl"> <a-tooltip :content="`${node.name}`" position="tl">
<div class="one-line-text text-[var(--color-text-1)]">{{ node.name }}</div> <div class="one-line-text max-w-[200px] text-[var(--color-text-1)]">{{ node.name }}</div>
</a-tooltip> </a-tooltip>
</template> </template>
</a-tree-select> </a-tree-select>
@ -450,7 +452,7 @@
import useModal from '@/hooks/useModal'; import useModal from '@/hooks/useModal';
import { useAppStore, useTableStore } from '@/store'; import { useAppStore, useTableStore } from '@/store';
import useFeatureCaseStore from '@/store/modules/case/featureCase'; import useFeatureCaseStore from '@/store/modules/case/featureCase';
import { characterLimit, findNodeByKey, findNodePathByKey } from '@/utils'; import { characterLimit, findNodeByKey, findNodePathByKey, mapTree } from '@/utils';
import { hasAnyPermission } from '@/utils/permission'; import { hasAnyPermission } from '@/utils/permission';
import type { import type {
@ -503,7 +505,14 @@
}, },
]); ]);
const caseTreeData = computed(() => featureCaseStore.caseTree); const caseTreeData = computed(() => {
return mapTree<ModuleTreeNode>(featureCaseStore.caseTree, (e) => {
return {
...e,
draggable: false,
};
});
});
const moduleId = computed(() => featureCaseStore.moduleId[0]); const moduleId = computed(() => featureCaseStore.moduleId[0]);
const currentProjectId = computed(() => appStore.currentProjectId); const currentProjectId = computed(() => appStore.currentProjectId);
@ -1738,4 +1747,9 @@
justify-content: space-between; justify-content: space-between;
} }
.ms-table--special-small(); .ms-table--special-small();
.tree-dropdown {
.arco-tree-select-tree-wrapper {
width: 200px !important;
}
}
</style> </style>

View File

@ -103,6 +103,15 @@
> >
{{ t('ms.upload.preview') }} {{ t('ms.upload.preview') }}
</MsButton> </MsButton>
<SaveAsFilePopover
v-model:visible="transferVisible"
:saving-file="activeTransferFileParams"
:file-save-as-source-id="(form.id as string)"
:file-save-as-api="transferFileRequest"
:file-module-options-api="getTransferFileTree"
source-id-key="caseId"
@finish="getCaseInfo()"
/>
<MsButton <MsButton
v-if="item.status !== 'init'" v-if="item.status !== 'init'"
type="button" type="button"
@ -239,12 +248,6 @@
@save="saveSelectAssociatedFile" @save="saveSelectAssociatedFile"
/> />
<a-image-preview v-model:visible="previewVisible" :src="imageUrl" /> <a-image-preview v-model:visible="previewVisible" :src="imageUrl" />
<TransferModal
v-model:visible="transferVisible"
:request-fun="transferFileRequest"
:params="activeTransferFileParams"
@success="getCaseInfo()"
/>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -261,9 +264,9 @@
import MsUpload from '@/components/pure/ms-upload/index.vue'; import MsUpload from '@/components/pure/ms-upload/index.vue';
import type { MsFileItem } from '@/components/pure/ms-upload/types'; import type { 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 SaveAsFilePopover from '@/components/business/ms-add-attachment/saveAsFilePopover.vue';
import LinkFileDrawer from '@/components/business/ms-link-file/associatedFileDrawer.vue'; import LinkFileDrawer from '@/components/business/ms-link-file/associatedFileDrawer.vue';
import AddStep from './addStep.vue'; import AddStep from './addStep.vue';
import TransferModal from './tabContent/transferModal.vue';
import { import {
checkFileIsUpdateRequest, checkFileIsUpdateRequest,
@ -273,6 +276,7 @@
getCaseDefaultFields, getCaseDefaultFields,
getCaseDetail, getCaseDetail,
getCaseModuleTree, getCaseModuleTree,
getTransferFileTree,
previewFile, previewFile,
transferFileRequest, transferFileRequest,
updateFile, updateFile,
@ -291,7 +295,6 @@
CreateOrUpdateCase, CreateOrUpdateCase,
CustomAttributes, CustomAttributes,
DetailCase, DetailCase,
OperationFile,
OptionsFieldId, OptionsFieldId,
StepList, StepList,
} from '@/models/caseManagement/featureCase'; } from '@/models/caseManagement/featureCase';
@ -692,21 +695,11 @@
const transferVisible = ref<boolean>(false); const transferVisible = ref<boolean>(false);
const activeTransferFileParams = ref<OperationFile>({ const activeTransferFileParams = ref<MsFileItem>();
projectId: '',
caseId: '',
fileId: '',
local: true,
});
// //
function transferFile(item: MsFileItem) { function transferFile(item: MsFileItem) {
activeTransferFileParams.value = { activeTransferFileParams.value = { ...item };
projectId: currentProjectId.value,
caseId: form.value.id,
fileId: item.uid,
local: true,
};
transferVisible.value = true; transferVisible.value = true;
} }
@ -808,16 +801,6 @@
} }
}); });
// onMounted(() => {
// nextTick(() => {
// console.log(document.querySelector('.preview-left'));
// scrollIntoView(document.querySelector('.preview-left'), { block: 'center' });
// console.log(caseFormRef.value?.$el.querySelector('.arco-form-item-message'));
// });
// });
defineExpose({ defineExpose({
caseFormRef, caseFormRef,
formRef, formRef,

View File

@ -207,6 +207,7 @@
scroll: { x: '100%' }, scroll: { x: '100%' },
heightUsed: 290, heightUsed: 290,
selectable: true, selectable: true,
showSelectorAll: true,
showSetting: false, showSetting: false,
}); });

View File

@ -148,6 +148,15 @@
> >
{{ t('ms.upload.preview') }} {{ t('ms.upload.preview') }}
</MsButton> </MsButton>
<SaveAsFilePopover
v-model:visible="transferVisible"
:saving-file="activeTransferFileParams"
:file-save-as-source-id="(form.id as string)"
:file-save-as-api="transferFileRequest"
:file-module-options-api="getTransferFileTree"
source-id-key="caseId"
@finish="emit('updateSuccess')"
/>
<MsButton type="button" status="primary" class="!mr-[4px]" @click="transferFileHandler(item)"> <MsButton type="button" status="primary" class="!mr-[4px]" @click="transferFileHandler(item)">
{{ t('caseManagement.featureCase.storage') }} {{ t('caseManagement.featureCase.storage') }}
</MsButton> </MsButton>
@ -225,12 +234,6 @@
/> />
</div> </div>
<a-image-preview v-model:visible="previewVisible" :src="imageUrl" /> <a-image-preview v-model:visible="previewVisible" :src="imageUrl" />
<TransferModal
v-model:visible="transferVisible"
:request-fun="transferFileRequest"
:params="activeTransferFileParams"
@success="emit('updateSuccess')"
/>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -244,17 +247,17 @@
import MsUpload from '@/components/pure/ms-upload/index.vue'; import MsUpload from '@/components/pure/ms-upload/index.vue';
import type { MsFileItem } from '@/components/pure/ms-upload/types'; import type { 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 SaveAsFilePopover from '@/components/business/ms-add-attachment/saveAsFilePopover.vue';
import LinkFileDrawer from '@/components/business/ms-link-file/associatedFileDrawer.vue'; import LinkFileDrawer from '@/components/business/ms-link-file/associatedFileDrawer.vue';
import AddStep from '../addStep.vue'; import AddStep from '../addStep.vue';
import TransferModal from './transferModal.vue';
import { deleteRecycleCase } from '@/api/modules/api-test/management';
import { import {
checkFileIsUpdateRequest, checkFileIsUpdateRequest,
deleteFileOrCancelAssociation, deleteFileOrCancelAssociation,
downloadFileRequest, downloadFileRequest,
editorUploadFile, editorUploadFile,
getAssociatedFileListUrl, getAssociatedFileListUrl,
getTransferFileTree,
previewFile, previewFile,
transferFileRequest, transferFileRequest,
updateCaseRequest, updateCaseRequest,
@ -269,7 +272,7 @@
import { downloadByteFile, getGenerateId, sleep } from '@/utils'; import { downloadByteFile, getGenerateId, sleep } from '@/utils';
import { scrollIntoView } from '@/utils/dom'; import { scrollIntoView } from '@/utils/dom';
import type { AssociatedList, DetailCase, OperationFile, StepList } from '@/models/caseManagement/featureCase'; import type { AssociatedList, DetailCase, StepList } from '@/models/caseManagement/featureCase';
import type { TableQueryParams } from '@/models/common'; import type { TableQueryParams } from '@/models/common';
import { convertToFile } from '../utils'; import { convertToFile } from '../utils';
@ -492,15 +495,6 @@
const fileListRef = ref<InstanceType<typeof MsFileList>>(); const fileListRef = ref<InstanceType<typeof MsFileList>>();
function beforeUpload(file: File) {
const _maxSize = 50 * 1024 * 1024;
if (file.size > _maxSize) {
Message.warning(t('ms.upload.overSize'));
return Promise.resolve(false);
}
return Promise.resolve(true);
}
// //
async function deleteFileHandler(item: MsFileItem) { async function deleteFileHandler(item: MsFileItem) {
if (!item.local) { if (!item.local) {
@ -613,6 +607,7 @@
const imageUrl = ref(''); const imageUrl = ref('');
const previewVisible = ref<boolean>(false); const previewVisible = ref<boolean>(false);
// //
async function handlePreview(item: MsFileItem) { async function handlePreview(item: MsFileItem) {
try { try {
@ -635,19 +630,11 @@
fileListRef.value?.startUpload(); fileListRef.value?.startUpload();
} }
const activeTransferFileParams = ref<OperationFile>({ const activeTransferFileParams = ref<MsFileItem>();
projectId: '',
caseId: '',
fileId: '',
local: true,
});
function transferFileHandler(item: MsFileItem) { function transferFileHandler(item: MsFileItem) {
activeTransferFileParams.value = { activeTransferFileParams.value = {
projectId: currentProjectId.value, ...item,
caseId: props.form.id,
fileId: item.uid,
local: true,
}; };
transferVisible.value = true; transferVisible.value = true;
} }
@ -691,7 +678,6 @@
// //
function saveSelectAssociatedFile(fileData: AssociatedList[]) { function saveSelectAssociatedFile(fileData: AssociatedList[]) {
// const fileResultList = fileData.map((fileInfo) => convertToFile(fileInfo));
const fileResultList = fileData.map((fileInfo) => convertToFile(fileInfo)); const fileResultList = fileData.map((fileInfo) => convertToFile(fileInfo));
fileList.value.push(...fileResultList); fileList.value.push(...fileResultList);
const fileIds = fileResultList.map((item: any) => item.uid); const fileIds = fileResultList.map((item: any) => item.uid);

View File

@ -1,5 +1,5 @@
<template> <template>
<div v-expire class="mb-4" :class="props.styleClass"> <div v-expire class="mb-2" :class="props.styleClass">
<a-alert type="warning">{{ <a-alert type="warning">{{
licenseStore.expiredDays >= 0 && licenseStore.expiredDays <= 30 licenseStore.expiredDays >= 0 && licenseStore.expiredDays <= 30
? t('system.authorized.LicenseExpirationPromptLessThanThirty', { day: licenseStore.expiredDays }) ? t('system.authorized.LicenseExpirationPromptLessThanThirty', { day: licenseStore.expiredDays })

View File

@ -1,6 +1,5 @@
<template> <template>
<MsCard :loading="loading" simple> <MsCard :loading="loading" simple>
<ExpireAlert />
<div class="wrapper"> <div class="wrapper">
<div class="content-wrapper"> <div class="content-wrapper">
<div class="authorized_logo"> <div class="authorized_logo">
@ -120,7 +119,6 @@
import MsCard from '@/components/pure/ms-card/index.vue'; import MsCard from '@/components/pure/ms-card/index.vue';
import MsDrawer from '@/components/pure/ms-drawer/index.vue'; import MsDrawer from '@/components/pure/ms-drawer/index.vue';
import MsUpload from '@/components/pure/ms-upload/index.vue'; import MsUpload from '@/components/pure/ms-upload/index.vue';
import ExpireAlert from './components/expireAlert.vue';
import { addLicense, getLicenseInfo } from '@/api/modules/setting/authorizedManagement'; import { addLicense, getLicenseInfo } from '@/api/modules/setting/authorizedManagement';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';

View File

@ -1,5 +1,4 @@
<template> <template>
<ExpireAlert />
<MsTabCard v-model:active-tab="activeTab" :title="t('system.config.parameterConfig')" :tab-list="tabList" /> <MsTabCard v-model:active-tab="activeTab" :title="t('system.config.parameterConfig')" :tab-list="tabList" />
<baseConfig v-if="activeTab === 'baseConfig'" v-show="activeTab === 'baseConfig'" /> <baseConfig v-if="activeTab === 'baseConfig'" v-show="activeTab === 'baseConfig'" />
<pageConfig v-if="isInitPageConfig" v-show="activeTab === 'pageConfig'" /> <pageConfig v-if="isInitPageConfig" v-show="activeTab === 'pageConfig'" />
@ -14,7 +13,6 @@
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import MsTabCard from '@/components/pure/ms-tab-card/index.vue'; import MsTabCard from '@/components/pure/ms-tab-card/index.vue';
import ExpireAlert from '@/views/setting/system/authorizedManagement/components/expireAlert.vue';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import useLicenseStore from '@/store/modules/setting/license'; import useLicenseStore from '@/store/modules/setting/license';

View File

@ -1,6 +1,5 @@
<template> <template>
<div class="flex h-full flex-col"> <div class="flex h-full flex-col">
<ExpireAlert />
<logCards class="flex-1" mode="SYSTEM"></logCards> <logCards class="flex-1" mode="SYSTEM"></logCards>
</div> </div>
</template> </template>
@ -10,7 +9,6 @@
* @description 系统设置-日志 * @description 系统设置-日志
*/ */
import logCards from './components/logCards.vue'; import logCards from './components/logCards.vue';
import ExpireAlert from '@/views/setting/system/authorizedManagement/components/expireAlert.vue';
</script> </script>
<style lang="less" scoped></style> <style lang="less" scoped></style>

View File

@ -1,6 +1,5 @@
<template> <template>
<MsCard simple> <MsCard simple>
<ExpireAlert />
<div class="mb-4 flex items-center justify-between"> <div class="mb-4 flex items-center justify-between">
<div> <div>
<a-button <a-button
@ -53,7 +52,6 @@
import AddProjectModal from './components/addProjectModal.vue'; import AddProjectModal from './components/addProjectModal.vue';
import SystemOrganization from './components/systemOrganization.vue'; import SystemOrganization from './components/systemOrganization.vue';
import SystemProject from './components/systemProject.vue'; import SystemProject from './components/systemProject.vue';
import ExpireAlert from '@/views/setting/system/authorizedManagement/components/expireAlert.vue';
import { getOrgAndProjectCount } from '@/api/modules/setting/organizationAndProject'; import { getOrgAndProjectCount } from '@/api/modules/setting/organizationAndProject';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';

View File

@ -1,7 +1,6 @@
<template> <template>
<MsCard simple> <MsCard simple>
<div class="flex h-full flex-col overflow-hidden"> <div class="flex h-full flex-col overflow-hidden">
<ExpireAlert />
<div class="wrapper"> <div class="wrapper">
<a-alert :closable="true" class="mb-4"> <a-alert :closable="true" class="mb-4">
<div> <div>
@ -21,7 +20,6 @@
*/ */
import MsCard from '@/components/pure/ms-card/index.vue'; import MsCard from '@/components/pure/ms-card/index.vue';
import pluginTable from './components/pluginTable.vue'; import pluginTable from './components/pluginTable.vue';
import ExpireAlert from '@/views/setting/system/authorizedManagement/components/expireAlert.vue';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';

View File

@ -1,6 +1,5 @@
<template> <template>
<MsCard :loading="loading" simple> <MsCard :loading="loading" simple>
<ExpireAlert />
<div class="mb-4 flex items-center justify-between"> <div class="mb-4 flex items-center justify-between">
<a-button v-permission="['SYSTEM_TEST_RESOURCE_POOL:READ+ADD']" v-xpack type="primary" @click="addPool"> <a-button v-permission="['SYSTEM_TEST_RESOURCE_POOL:READ+ADD']" v-xpack type="primary" @click="addPool">
{{ t('system.resourcePool.createPool') }} {{ t('system.resourcePool.createPool') }}
@ -92,7 +91,6 @@
import type { ActionsItem } from '@/components/pure/ms-table-more-action/types'; import type { ActionsItem } from '@/components/pure/ms-table-more-action/types';
import { TagType, Theme } from '@/components/pure/ms-tag/ms-tag.vue'; import { TagType, Theme } from '@/components/pure/ms-tag/ms-tag.vue';
import JobTemplateDrawer from './components/jobTemplateDrawer.vue'; import JobTemplateDrawer from './components/jobTemplateDrawer.vue';
import ExpireAlert from '@/views/setting/system/authorizedManagement/components/expireAlert.vue';
import { delPoolInfo, getPoolInfo, getPoolList, togglePoolStatus } from '@/api/modules/setting/resourcePool'; import { delPoolInfo, getPoolInfo, getPoolList, togglePoolStatus } from '@/api/modules/setting/resourcePool';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';

View File

@ -1,5 +1,4 @@
<template> <template>
<ExpireAlert />
<MsCard simple no-content-padding> <MsCard simple no-content-padding>
<TaskCenter group="system" /> <TaskCenter group="system" />
</MsCard> </MsCard>
@ -10,7 +9,6 @@
import MsCard from '@/components/pure/ms-card/index.vue'; import MsCard from '@/components/pure/ms-card/index.vue';
import TaskCenter from '@/views/project-management/taskCenter/component/taskCom.vue'; import TaskCenter from '@/views/project-management/taskCenter/component/taskCom.vue';
import ExpireAlert from '@/views/setting/system/authorizedManagement/components/expireAlert.vue';
</script> </script>
<style scoped lang="less"> <style scoped lang="less">

View File

@ -1,6 +1,5 @@
<template> <template>
<MsCard simple> <MsCard simple>
<ExpireAlert />
<div class="mb-4 flex items-center justify-between"> <div class="mb-4 flex items-center justify-between">
<div> <div>
<a-button <a-button
@ -312,7 +311,6 @@
import MsSelect from '@/components/business/ms-select'; import MsSelect from '@/components/business/ms-select';
import batchModal from './components/batchModal.vue'; import batchModal from './components/batchModal.vue';
import inviteModal from './components/inviteModal.vue'; import inviteModal from './components/inviteModal.vue';
import ExpireAlert from '@/views/setting/system/authorizedManagement/components/expireAlert.vue';
import { import {
batchCreateUser, batchCreateUser,

View File

@ -13,7 +13,6 @@
</template> </template>
<template #second> <template #second>
<div class="flex h-full flex-col overflow-hidden pt-[16px]"> <div class="flex h-full flex-col overflow-hidden pt-[16px]">
<ExpireAlert class="px-4" />
<div class="mb-4 flex flex-row items-center justify-between px-[16px]"> <div class="mb-4 flex flex-row items-center justify-between px-[16px]">
<a-tooltip :content="currentUserGroupItem.name"> <a-tooltip :content="currentUserGroupItem.name">
<div class="one-line-text max-w-[300px] font-medium">{{ currentUserGroupItem.name }}</div> <div class="one-line-text max-w-[300px] font-medium">{{ currentUserGroupItem.name }}</div>
@ -73,7 +72,6 @@
import AuthTable from '@/components/business/ms-user-group-comp/authTable.vue'; import AuthTable from '@/components/business/ms-user-group-comp/authTable.vue';
import UserGroupLeft from '@/components/business/ms-user-group-comp/msUserGroupLeft.vue'; import UserGroupLeft from '@/components/business/ms-user-group-comp/msUserGroupLeft.vue';
import UserTable from '@/components/business/ms-user-group-comp/userTable.vue'; import UserTable from '@/components/business/ms-user-group-comp/userTable.vue';
import ExpireAlert from '@/views/setting/system/authorizedManagement/components/expireAlert.vue';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { hasAnyPermission } from '@/utils/permission'; import { hasAnyPermission } from '@/utils/permission';