fix: 缺陷管理bug修复&用例紧急bug修复

This commit is contained in:
xinxin.wu 2024-03-14 11:39:44 +08:00 committed by Craftsman
parent 1faaa395e8
commit 5ceec82c42
14 changed files with 114 additions and 45 deletions

View File

@ -239,3 +239,8 @@ export function cancelAssociation(id: string) {
export function getChangeHistoryList(data: TableQueryParams) {
return MSR.post({ url: bugURL.getChangeHistoryListUrl, data });
}
// 校验跳转用例权限
export function checkCasePermission(projectId: string, caseType: string) {
return MSR.get({ url: `${bugURL.checkCasePermissionUrl}/${projectId}/${caseType}` });
}

View File

@ -73,3 +73,6 @@ export const getUnrelatedModuleTreeCountUrl = '/bug/case/un-relate/module/count'
// 缺陷管理-变更历史-列表
export const getChangeHistoryListUrl = '/bug/history/page';
// 缺陷用例跳转用例是否具备权限
export const checkCasePermissionUrl = '/bug/case/check-permission';

View File

@ -6,7 +6,7 @@
'commentWrapper': props.isUseBottom,
}"
>
<div v-if="props.isShowAvatar" class="mr-3 inline-block"> <MsAvatar avatar="word"></MsAvatar></div>
<div v-if="props.isShowAvatar" class="mr-3 inline-block"> <MsAvatar :avatar="userStore.avatar"></MsAvatar></div>
<div class="w-full items-center">
<a-input
v-if="!isActive"
@ -37,6 +37,7 @@
import MsRichText from '@/components/pure/ms-rich-text/MsRichText.vue';
import { useI18n } from '@/hooks/useI18n';
import { useUserStore } from '@/store';
defineOptions({ name: 'MsCommentInput' });
@ -48,9 +49,8 @@
}>();
const currentContent = defineModel<string>('defaultValue', { default: '' });
const commentIds = defineModel<string[]>('noticeUserIds', { default: [] });
const userStore = useUserStore();
const emit = defineEmits<{
(event: 'publish', value: string): void;
(event: 'cancel'): void;

View File

@ -279,6 +279,7 @@
} from './type';
import type { TableChangeExtra, TableColumnData, TableData } from '@arco-design/web-vue';
import type { TableOperationColumn } from '@arco-design/web-vue/es/table/interface';
import { log } from 'console';
const batchLeft = ref('10px');
const { t } = useI18n();
@ -398,6 +399,23 @@
tmpArr = props.columns;
}
currentColumns.value = arr || tmpArr;
//
if (props.showSetting) {
const isNoDragColumns = currentColumns.value.filter((item) => item.showDrag).length;
if (!isNoDragColumns) {
currentColumns.value = tmpArr.map((item: any) => {
if (item.slotName === SpecialColumnEnum.OPERATION || item.slotName === SpecialColumnEnum.ACTION) {
return {
...item,
fixed: '',
};
}
return {
...item,
};
});
}
}
} catch (error) {
// eslint-disable-next-line no-console
console.error('InitColumn failed', error);

View File

@ -19,33 +19,36 @@
<template #titleRight="{ loading }">
<div class="rightButtons flex items-center">
<MsButton
v-permission="['PROJECT_BUG:READ+UPDATE']"
type="icon"
status="secondary"
class="mr-4 !rounded-[var(--border-radius-small)]"
:disabled="loading"
:loading="editLoading"
:disabled="loading"
@click="updateHandler"
>
<MsIcon type="icon-icon_edit_outlined" class="mr-1 font-[16px]" />
{{ t('common.edit') }}
</MsButton>
<MsButton
v-permission="['PROJECT_BUG:READ+UPDATE']"
type="icon"
status="secondary"
class="mr-4 !rounded-[var(--border-radius-small)]"
:disabled="loading"
:loading="shareLoading"
:disabled="loading"
@click="shareHandler"
>
<MsIcon type="icon-icon_share1" class="mr-1 font-[16px]" />
{{ t('caseManagement.featureCase.share') }}
</MsButton>
<MsButton
v-permission="['PROJECT_BUG:READ+UPDATE']"
type="icon"
status="secondary"
class="mr-4 !rounded-[var(--border-radius-small)]"
:disabled="loading"
:loading="followLoading"
:disabled="loading"
@click="followHandler"
>
<MsIcon
@ -154,7 +157,10 @@
content-class="tags-class"
>
<a-form-item field="tags" :label="t('system.orgTemplate.tags')">
<MsTagsInput v-model:model-value="tags" />
<MsTagsInput
v-model:model-value="tags"
:disabled="!hasAnyPermission(['PROJECT_BUG:READ+UPDATE'])"
/>
</a-form-item>
</a-form>
@ -213,6 +219,7 @@
import useModal from '@/hooks/useModal';
import { useAppStore } from '@/store';
import { characterLimit } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
import { BugEditCustomField, BugEditFormObject, BugTemplateRequest } from '@/models/bug-management';
import { SelectValue } from '@/models/projectManagement/menuManagement';
@ -274,6 +281,7 @@
props: {
modelValue: valueObj[item.fieldId],
options: item.platformOptionJson ? JSON.parse(item.platformOptionJson) : item.options,
disabled: !hasAnyPermission(['PROJECT_BUG:READ+UPDATE']),
},
};
});

View File

@ -95,12 +95,14 @@
import {
batchAssociation,
cancelAssociation,
checkCasePermission,
getAssociatedList,
getModuleTree,
getUnAssociatedList,
} from '@/api/modules/bug-management';
import { postTabletList } from '@/api/modules/project-management/menuManagement';
import { useI18n } from '@/hooks/useI18n';
import { NO_RESOURCE_ROUTE_NAME } from '@/router/constants';
import { useAppStore } from '@/store';
import useFeatureCaseStore from '@/store/modules/case/featureCase';
@ -276,12 +278,21 @@
await loadList();
}
function openDetail(id: string) {
window.open(
`${window.location.origin}#${
router.resolve({ name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE }).fullPath
}?id=${id}`
);
async function openDetail(id: string) {
try {
const res = await checkCasePermission(currentProjectId.value, 'FUNCTIONAL');
if (res) {
window.open(
`${window.location.origin}#${
router.resolve({ name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE }).fullPath
}?id=${id}`
);
} else {
window.open(`${window.location.origin}#${router.resolve({ name: NO_RESOURCE_ROUTE_NAME }).fullPath}`);
}
} catch (error) {
console.log(error);
}
}
onMounted(async () => {

View File

@ -17,7 +17,7 @@
v-model:raw="form.description"
v-model:filed-ids="fileIds"
:disabled="!contentEditAble"
:placeholder="t('bugManagement.edit.contentPlaceholder')"
:placeholder="t('editor.placeholder')"
:upload-image="handleUploadImage"
/>
<div v-else v-dompurify-html="form?.description || '-'" class="markdown-body"></div>
@ -41,7 +41,7 @@
v-if="contentEditAble"
v-model:raw="item.defaultValue"
:disabled="!contentEditAble"
:placeholder="t('bugManagement.edit.contentPlaceholder')"
:placeholder="t('editor.placeholder')"
/>
<div v-else v-dompurify-html="item?.defaultValue || '-'" class="markdown-body"></div>
</div>

View File

@ -48,12 +48,11 @@
];
const { propsRes, propsEvent, loadList, setLoadListParams } = useTable(getChangeHistoryList, {
heightUsed: 240,
heightUsed: 380,
columns,
scroll: { x: '100%' },
selectable: false,
noDisable: false,
pageSimple: true,
debug: true,
});

View File

@ -393,6 +393,7 @@
}
const res = await getTemplateById(param);
await getFormRules(res.customFields);
isLoading.value = false;
isPlatformDefaultTemplate.value = res.platformDefault;
if (isPlatformDefaultTemplate.value) {
const systemFields = res.customFields.filter((field) => field.platformSystemField);
@ -402,16 +403,18 @@
});
}
getFormRules(res.customFields.filter((field) => !field.platformSystemField));
isLoading.value = false;
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
} finally {
loading.value = false;
}
}
};
const getTemplateOptions = async () => {
try {
loading.value = true;
const res = await getTemplateOption(appStore.currentProjectId);
templateOption.value = res.map((item) => {
if (item.enableDefault && !isEdit.value) {
@ -427,6 +430,8 @@
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
} finally {
loading.value = false;
}
};

View File

@ -211,7 +211,6 @@
import { BackEndEnum, FilterFormItem, FilterResult, FilterType } from '@/components/pure/ms-advance-filter/type';
import MsButton from '@/components/pure/ms-button/index.vue';
import MsCard from '@/components/pure/ms-card/index.vue';
import MsExportDrawer from '@/components/pure/ms-export-drawer/index.vue';
import { MsExportDrawerMap, MsExportDrawerOption } from '@/components/pure/ms-export-drawer/types';
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
import { BatchActionParams, BatchActionQueryParams, MsTableColumn } from '@/components/pure/ms-table/type';
@ -220,7 +219,6 @@
import { ActionsItem } from '@/components/pure/ms-table-more-action/types';
import BatchEditModal from './components/batchEditModal.vue';
import BugDetailDrawer from './components/bug-detail-drawer.vue';
import DeleteModal from './components/deleteModal.vue';
import TableFilter from '@/views/case-management/caseManagementFeature/components/tableFilter.vue';
import {
@ -246,12 +244,17 @@
downloadByteFile,
tableParamsToRequestParams,
} from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
import { BugEditCustomField, BugListItem, BugOptionItem } from '@/models/bug-management';
import { RouteEnum } from '@/enums/routeEnum';
import { TableKeyEnum } from '@/enums/tableEnum';
import { log } from 'console';
const { t } = useI18n();
const MsExportDrawer = defineAsyncComponent(() => import('@/components/pure/ms-export-drawer/index.vue'));
const DeleteModal = defineAsyncComponent(() => import('./components/deleteModal.vue'));
const tableStore = useTableStore();
const appStore = useAppStore();
@ -355,7 +358,7 @@
title: 'bugManagement.ID',
dataIndex: 'num',
slotName: 'num',
width: 80,
width: 200,
sortable: {
sortDirections: ['ascend', 'descend'],
sorter: true,
@ -366,7 +369,7 @@
{
title: 'bugManagement.bugName',
dataIndex: 'title',
width: 200,
width: 300,
showTooltip: true,
sortable: {
sortDirections: ['ascend', 'descend'],
@ -484,6 +487,7 @@
showJumpMethod: true,
noDisable: false,
showSetting: true,
heightUsed: 380,
},
(record: TableData) => ({
...record,
@ -576,8 +580,15 @@
};
const checkSyncStatus = async () => {
const { complete } = await getSyncStatus(appStore.currentProjectId);
isComplete.value = complete;
if (!hasAnyPermission(['PROJECT_BUG:READ+UPDATE'])) {
return;
}
try {
const { complete } = await getSyncStatus(appStore.currentProjectId);
isComplete.value = complete;
} catch (error) {
console.log(error);
}
};
/** 同步缺陷 */
const { pause, resume } = useIntervalFn(() => {

View File

@ -24,6 +24,7 @@
<template #titleRight="{ loading }">
<div class="rightButtons flex items-center">
<MsButton
v-permission="['FUNCTIONAL_CASE:READ+UPDATE']"
type="icon"
status="secondary"
class="mr-4 !rounded-[var(--border-radius-small)]"
@ -35,6 +36,7 @@
{{ t('common.edit') }}
</MsButton>
<MsButton
v-permission="['FUNCTIONAL_CASE:READ+UPDATE']"
type="icon"
status="secondary"
class="mr-4 !rounded-[var(--border-radius-small)]"
@ -46,6 +48,7 @@
{{ t('caseManagement.featureCase.share') }}
</MsButton>
<MsButton
v-permission="['FUNCTIONAL_CASE:READ+UPDATE']"
type="icon"
status="secondary"
class="mr-4 !rounded-[var(--border-radius-small)]"

View File

@ -398,7 +398,7 @@
value: userStore.id || '',
},
];
if (item.defaultValue === 'CREATE_USER') {
if (item.defaultValue === 'CREATE_USER' || item.defaultValue.includes('CREATE_USER')) {
initValue = item.type === 'MEMBER' ? userStore.id : [userStore.id];
}
}

View File

@ -9,7 +9,12 @@
t('caseManagement.featureCase.createDefect')
}}</span>
</template>
<a-button v-permission="['FUNCTIONAL_CASE:READ+UPDATE']" class="mr-3" type="primary" @click="linkDefect">
<a-button
v-permission="hasAnyPermission(['FUNCTIONAL_CASE:READ+UPDATE'])"
class="mr-3"
type="primary"
@click="linkDefect"
>
{{ t('caseManagement.featureCase.linkDefect') }}
</a-button>
</a-tooltip>
@ -134,12 +139,12 @@
</template>
<template #handleUserFilter="{ columnConfig }">
<TableFilter
v-model:visible="handleUserFilterVisible"
v-model:status-filters="handleUserFilterValue"
:title="(columnConfig.title as string)"
:list="handleUserFilterOptions"
value-key="value"
@search="searchData()"
v-model:visible="handleUserFilterVisible"
v-model:status-filters="handleUserFilterValue"
:title="(columnConfig.title as string)"
:list="handleUserFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
@ -148,12 +153,12 @@
</template>
<template #statusFilter="{ columnConfig }">
<TableFilter
v-model:visible="statusFilterVisible"
v-model:status-filters="statusFilterValue"
:title="(columnConfig.title as string)"
:list="statusFilterOptions"
value-key="value"
@search="searchData()"
v-model:visible="statusFilterVisible"
v-model:status-filters="statusFilterValue"
:title="(columnConfig.title as string)"
:list="statusFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
@ -163,12 +168,12 @@
<template #severityFilter="{ columnConfig }">
<TableFilter
v-model:visible="severityFilterVisible"
v-model:status-filters="severityFilterValue"
:title="(columnConfig.title as string)"
:list="severityFilterOptions"
value-key="value"
@search="searchData()"
v-model:visible="severityFilterVisible"
v-model:status-filters="severityFilterValue"
:title="(columnConfig.title as string)"
:list="severityFilterOptions"
value-key="value"
@search="searchData()"
>
<template #item="{ item }">
{{ item.text }}
@ -221,6 +226,7 @@
import { useI18n } from '@/hooks/useI18n';
import { useAppStore } from '@/store';
import useFeatureCaseStore from '@/store/modules/case/featureCase';
import { hasAnyPermission } from '@/utils/permission';
import { BugOptionItem } from '@/models/bug-management';
import type { TableQueryParams } from '@/models/common';

View File

@ -199,7 +199,7 @@ export function initFormCreate(customFields: CustomAttributes[], permission: str
value: userStore.id || '',
},
];
currentDefaultValue = item.defaultValue;
currentDefaultValue = tempValue;
} else {
currentDefaultValue = JSON.parse(item.defaultValue);
}