fix(缺陷管理): 缺陷管理部分问题

--bug=1036445 --user=宋昌昌 【缺陷管理】分享缺陷,用户从项目中移除,刷新分享缺陷链接页面提示信息优化 https://www.tapd.cn/55049933/s/1480367
--bug=1036347 --user=宋昌昌 【缺陷管理】项目集成禅道-同步缺陷失败 https://www.tapd.cn/55049933/s/1480473
--bug=1036389 --user=宋昌昌 【缺陷管理】用户组禁用了缺陷的编辑权限,用户点击ID查看详情可编辑,修改基本信息,提交时提示无权限 https://www.tapd.cn/55049933/s/1480474
--bug=1036868 --user=宋昌昌 【缺陷管理】已经存在一条评论的前提下-再添加一条评论-查看展开/收起评论的变化 https://www.tapd.cn/55049933/s/1480478
--bug=1036917 --user=宋昌昌 【缺陷管理】缺陷详情-拖拽上传附件遮罩层调整 https://www.tapd.cn/55049933/s/1480479
This commit is contained in:
song-cc-rock 2024-03-25 18:13:46 +08:00 committed by Craftsman
parent c84c4ba8e7
commit 3e42d29b6e
14 changed files with 44 additions and 27 deletions

View File

@ -228,14 +228,14 @@ public class BugController {
@GetMapping("/follow/{id}") @GetMapping("/follow/{id}")
@Operation(summary = "缺陷管理-详情-关注缺陷") @Operation(summary = "缺陷管理-详情-关注缺陷")
@RequiresPermissions(PermissionConstants.PROJECT_BUG_UPDATE) @RequiresPermissions(PermissionConstants.PROJECT_BUG_READ)
public void follow(@PathVariable String id) { public void follow(@PathVariable String id) {
bugService.follow(id, SessionUtils.getUserId()); bugService.follow(id, SessionUtils.getUserId());
} }
@GetMapping("/unfollow/{id}") @GetMapping("/unfollow/{id}")
@Operation(summary = "缺陷管理-详情-取消关注缺陷") @Operation(summary = "缺陷管理-详情-取消关注缺陷")
@RequiresPermissions(PermissionConstants.PROJECT_BUG_UPDATE) @RequiresPermissions(PermissionConstants.PROJECT_BUG_READ)
public void unfollow(@PathVariable String id) { public void unfollow(@PathVariable String id) {
bugService.unfollow(id, SessionUtils.getUserId()); bugService.unfollow(id, SessionUtils.getUserId());
} }

View File

@ -42,7 +42,7 @@ public class BugRelateCaseController {
@PostMapping("/un-relate/page") @PostMapping("/un-relate/page")
@Operation(description = "缺陷管理-关联用例-未关联用例-列表分页") @Operation(description = "缺陷管理-关联用例-未关联用例-列表分页")
@RequiresPermissions(PermissionConstants.PROJECT_BUG_UPDATE) @RequiresPermissions(PermissionConstants.PROJECT_BUG_READ)
public Pager<List<TestCaseProviderDTO>> unRelatedPage(@Validated @RequestBody TestCasePageProviderRequest request) { public Pager<List<TestCaseProviderDTO>> unRelatedPage(@Validated @RequestBody TestCasePageProviderRequest request) {
// 目前只保留功能用例的Provider接口, 后续其他用例根据RelateCaseType扩展 // 目前只保留功能用例的Provider接口, 后续其他用例根据RelateCaseType扩展
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize()); Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize());
@ -51,7 +51,7 @@ public class BugRelateCaseController {
@PostMapping("/un-relate/module/count") @PostMapping("/un-relate/module/count")
@Operation(summary = "缺陷管理-关联用例-未关联用例-模块树数量") @Operation(summary = "缺陷管理-关联用例-未关联用例-模块树数量")
@RequiresPermissions(PermissionConstants.PROJECT_BUG_UPDATE) @RequiresPermissions(PermissionConstants.PROJECT_BUG_READ)
@CheckOwner(resourceId = "#request.projectId", resourceType = "project") @CheckOwner(resourceId = "#request.projectId", resourceType = "project")
public Map<String, Long> countTree(@RequestBody @Validated TestCasePageProviderRequest request) { public Map<String, Long> countTree(@RequestBody @Validated TestCasePageProviderRequest request) {
return bugRelateCaseCommonService.countTree(request); return bugRelateCaseCommonService.countTree(request);
@ -59,7 +59,7 @@ public class BugRelateCaseController {
@PostMapping("/un-relate/module/tree") @PostMapping("/un-relate/module/tree")
@Operation(summary = "缺陷管理-关联用例-未关联用例-模块树") @Operation(summary = "缺陷管理-关联用例-未关联用例-模块树")
@RequiresPermissions(PermissionConstants.PROJECT_BUG_UPDATE) @RequiresPermissions(PermissionConstants.PROJECT_BUG_READ)
@CheckOwner(resourceId = "#request.projectId", resourceType = "project") @CheckOwner(resourceId = "#request.projectId", resourceType = "project")
public List<BaseTreeNode> getTree(@RequestBody @Validated AssociateCaseModuleRequest request) { public List<BaseTreeNode> getTree(@RequestBody @Validated AssociateCaseModuleRequest request) {
return bugRelateCaseCommonService.getRelateCaseTree(request); return bugRelateCaseCommonService.getRelateCaseTree(request);
@ -75,7 +75,7 @@ public class BugRelateCaseController {
@PostMapping("/page") @PostMapping("/page")
@Operation(description = "缺陷管理-关联用例-列表分页查询") @Operation(description = "缺陷管理-关联用例-列表分页查询")
@RequiresPermissions(PermissionConstants.PROJECT_BUG_UPDATE) @RequiresPermissions(PermissionConstants.PROJECT_BUG_READ)
public Pager<List<BugRelateCaseDTO>> page(@Validated @RequestBody BugRelatedCasePageRequest request) { public Pager<List<BugRelateCaseDTO>> page(@Validated @RequestBody BugRelatedCasePageRequest request) {
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize()); Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize());
return PageUtils.setPageInfo(page, bugRelateCaseCommonService.page(request)); return PageUtils.setPageInfo(page, bugRelateCaseCommonService.page(request));

View File

@ -42,7 +42,6 @@ public class ProjectController {
@GetMapping("/list/options/{organizationId}") @GetMapping("/list/options/{organizationId}")
@Operation(summary = "根据组织ID获取所有有权限的项目") @Operation(summary = "根据组织ID获取所有有权限的项目")
@RequiresPermissions(PermissionConstants.PROJECT_BASE_INFO_READ)
public List<Project> getUserProject(@PathVariable String organizationId) { public List<Project> getUserProject(@PathVariable String organizationId) {
return projectService.getUserProject(organizationId, SessionUtils.getUserId()); return projectService.getUserProject(organizationId, SessionUtils.getUserId());
} }

View File

@ -252,9 +252,6 @@ public class ProjectControllerTests extends BaseTest {
list = parseObjectFromMvcResult(mvcResult, List.class); list = parseObjectFromMvcResult(mvcResult, List.class);
//断言list是空的 //断言list是空的
Assertions.assertEquals(0, list.size()); Assertions.assertEquals(0, list.size());
//权限校验
requestGetPermissionTest(PermissionConstants.PROJECT_BASE_INFO_READ, getOptions + DEFAULT_ORGANIZATION_ID);
} }
@Test @Test

View File

@ -140,6 +140,13 @@ export default defineComponent({
); );
}; };
watch(
() => props.commentList,
() => {
expendedIds.value = [];
}
);
const renderChildrenList = (list?: CommentItem[]) => { const renderChildrenList = (list?: CommentItem[]) => {
if (!list || list.length === 0) { if (!list || list.length === 0) {
return null; return null;

View File

@ -92,6 +92,7 @@
<style scoped lang="less"> <style scoped lang="less">
.commentWrapper { .commentWrapper {
box-shadow: 1px -1px 4px rgba(2 2 2 / 10%); box-shadow: 1px -1px 4px rgba(2 2 2 / 10%);
z-index: 101;
@apply absolute bottom-0 w-full bg-white px-4 py-4; @apply absolute bottom-0 w-full bg-white px-4 py-4;
} }
</style> </style>

View File

@ -14,7 +14,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { getProjectList } from '@/api/modules/project-management/project'; import { getProjectList } from '@/api/modules/project-management/project';
import useAppStore from '@/store/modules/app'; import useAppStore from '@/store/modules/app';
import { hasAnyPermission } from '@/utils/permission';
import type { ProjectListItem } from '@/models/setting/project'; import type { ProjectListItem } from '@/models/setting/project';
@ -46,7 +45,7 @@
onBeforeMount(async () => { onBeforeMount(async () => {
try { try {
if (appStore.currentOrgId && hasAnyPermission(['PROJECT_BASE_INFO:READ'])) { if (appStore.currentOrgId) {
const res = await getProjectList(appStore.getCurrentOrgId); const res = await getProjectList(appStore.getCurrentOrgId);
projectList.value = res; projectList.value = res;
} else { } else {

View File

@ -12,7 +12,7 @@
:disabled="props.disabled" :disabled="props.disabled"
:class="getAllScreenClass" :class="getAllScreenClass"
:style="{ :style="{
width: props.isAllScreen ? `calc(100% - ${menuWidth}px - 16px)` : '', width: props.isAllScreen ? `calc(90% - ${menuWidth}px - 16px)` : '',
}" }"
@change="handleChange" @change="handleChange"
@before-upload="beforeUpload" @before-upload="beforeUpload"

View File

@ -15,7 +15,6 @@ const ProjectManagement: AppRouteRecordRaw = {
hideChildrenInMenu: true, hideChildrenInMenu: true,
roles: [ roles: [
'PROJECT_BASE_INFO:READ', 'PROJECT_BASE_INFO:READ',
'SYSTEM_PARAMETER_SETTING_BASE:READ',
'PROJECT_TEMPLATE:READ', 'PROJECT_TEMPLATE:READ',
'PROJECT_FILE_MANAGEMENT:READ', 'PROJECT_FILE_MANAGEMENT:READ',
'PROJECT_MESSAGE:READ', 'PROJECT_MESSAGE:READ',

View File

@ -32,7 +32,7 @@
import { getProjectList, switchProject } from '@/api/modules/project-management/project'; import { getProjectList, switchProject } from '@/api/modules/project-management/project';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { useAppStore, useUserStore } from '@/store'; import { useAppStore, useUserStore } from '@/store';
import { getFirstRouteNameByPermission, hasAnyPermission } from '@/utils/permission'; import { getFirstRouteNameByPermission } from '@/utils/permission';
import { SelectValue } from '@/models/projectManagement/menuManagement'; import { SelectValue } from '@/models/projectManagement/menuManagement';
import type { ProjectListItem } from '@/models/setting/project'; import type { ProjectListItem } from '@/models/setting/project';
@ -49,7 +49,7 @@
async function initProjects() { async function initProjects() {
try { try {
if (appStore.getCurrentOrgId && hasAnyPermission(['PROJECT_BASE_INFO:READ'])) { if (appStore.getCurrentOrgId) {
const res = await getProjectList(appStore.getCurrentOrgId); // TODO: const res = await getProjectList(appStore.getCurrentOrgId); // TODO:
projectList.value = res; projectList.value = res;
} else { } else {

View File

@ -44,7 +44,6 @@
{{ t('common.edit') }} {{ t('common.edit') }}
</MsButton> </MsButton>
<MsButton <MsButton
v-permission="['PROJECT_BUG:READ+UPDATE']"
type="icon" type="icon"
status="secondary" status="secondary"
class="mr-4 !rounded-[var(--border-radius-small)]" class="mr-4 !rounded-[var(--border-radius-small)]"
@ -56,7 +55,6 @@
{{ t('caseManagement.featureCase.share') }} {{ t('caseManagement.featureCase.share') }}
</MsButton> </MsButton>
<MsButton <MsButton
v-permission="['PROJECT_BUG:READ+UPDATE']"
type="icon" type="icon"
status="secondary" status="secondary"
class="mr-4 !rounded-[var(--border-radius-small)]" class="mr-4 !rounded-[var(--border-radius-small)]"
@ -115,7 +113,7 @@
v-if="activeTab === 'detail'" v-if="activeTab === 'detail'"
ref="bugDetailTabRef" ref="bugDetailTabRef"
:form-item="formItem" :form-item="formItem"
:allow-edit="true" :allow-edit="hasAnyPermission(['PROJECT_BUG:READ+UPDATE'])"
:detail-info="detailInfo" :detail-info="detailInfo"
:is-platform-default-template="isPlatformDefaultTemplate" :is-platform-default-template="isPlatformDefaultTemplate"
:platform-system-fields="platformSystemFields" :platform-system-fields="platformSystemFields"

View File

@ -1,7 +1,9 @@
<template> <template>
<div> <div>
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<a-button type="primary" @click="handleSelect">{{ t('caseManagement.featureCase.linkCase') }}</a-button> <a-button type="primary" :disabled="!hasAnyPermission(['PROJECT_BUG:READ+UPDATE'])" @click="handleSelect">{{
t('caseManagement.featureCase.linkCase')
}}</a-button>
<a-input-search <a-input-search
v-model:model-value="keyword" v-model:model-value="keyword"
:placeholder="t('caseManagement.featureCase.searchByIdAndName')" :placeholder="t('caseManagement.featureCase.searchByIdAndName')"
@ -25,12 +27,14 @@
><span class="ml-1 text-[rgb(var(--primary-5))]">{{ t('caseManagement.featureCase.preview') }}</span> ><span class="ml-1 text-[rgb(var(--primary-5))]">{{ t('caseManagement.featureCase.preview') }}</span>
</template> </template>
<template #operation="{ record }"> <template #operation="{ record }">
<MsButton @click="cancelLink(record)">{{ t('caseManagement.featureCase.cancelLink') }}</MsButton> <MsButton :disabled="!hasAnyPermission(['PROJECT_BUG:READ+UPDATE'])" @click="cancelLink(record)">{{
t('caseManagement.featureCase.cancelLink')
}}</MsButton>
</template> </template>
<template v-if="(keyword || '').trim() === ''" #empty> <template v-if="(keyword || '').trim() === ''" #empty>
<div class="flex w-full items-center justify-center text-[var(--color-text-4)]"> <div class="flex w-full items-center justify-center text-[var(--color-text-4)]">
{{ t('caseManagement.caseReview.tableNoData') }} {{ t('caseManagement.caseReview.tableNoData') }}
<MsButton class="ml-[8px]" @click="handleSelect"> <MsButton class="ml-[8px]" :disabled="!hasAnyPermission(['PROJECT_BUG:READ+UPDATE'])" @click="handleSelect">
{{ t('caseManagement.featureCase.linkCase') }} {{ t('caseManagement.featureCase.linkCase') }}
</MsButton> </MsButton>
</div> </div>
@ -105,6 +109,7 @@
import { NO_RESOURCE_ROUTE_NAME } from '@/router/constants'; import { NO_RESOURCE_ROUTE_NAME } from '@/router/constants';
import { useAppStore } from '@/store'; import { useAppStore } from '@/store';
import useFeatureCaseStore from '@/store/modules/case/featureCase'; import useFeatureCaseStore from '@/store/modules/case/featureCase';
import { hasAnyPermission } from '@/utils/permission';
import type { TableQueryParams } from '@/models/common'; import type { TableQueryParams } from '@/models/common';
import { CaseManagementRouteEnum } from '@/enums/routeEnum'; import { CaseManagementRouteEnum } from '@/enums/routeEnum';

View File

@ -66,7 +66,11 @@
</div> </div>
<!-- 附件布局 --> <!-- 附件布局 -->
<div class="mt-6"> <div class="mt-6">
<AddAttachment v-model:file-list="fileList" @link-file="associatedFile" /> <AddAttachment
v-model:file-list="fileList"
:disabled="!hasAnyPermission(['PROJECT_BUG:READ+UPDATE'])"
@link-file="associatedFile"
/>
</div> </div>
</a-form> </a-form>
<MsFileList <MsFileList
@ -96,7 +100,7 @@
{{ t('ms.upload.preview') }} {{ t('ms.upload.preview') }}
</MsButton> </MsButton>
<MsButton <MsButton
v-if="item.status === 'done'" v-if="item.status === 'done' && hasAnyPermission(['PROJECT_BUG:READ+UPDATE'])"
type="button" type="button"
status="primary" status="primary"
class="!mr-[4px]" class="!mr-[4px]"
@ -146,7 +150,7 @@
{{ t('caseManagement.featureCase.download') }} {{ t('caseManagement.featureCase.download') }}
</MsButton> </MsButton>
<MsButton <MsButton
v-if="item.isUpdateFlag" v-if="item.isUpdateFlag && hasAnyPermission(['PROJECT_BUG:READ+UPDATE'])"
type="button" type="button"
status="primary" status="primary"
class="!mr-[4px]" class="!mr-[4px]"
@ -226,6 +230,7 @@
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { useAppStore } from '@/store'; import { useAppStore } from '@/store';
import { downloadByteFile, sleep } from '@/utils'; import { downloadByteFile, sleep } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
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';
@ -299,6 +304,7 @@
...fileInfo, ...fileInfo,
name: fileInfo.fileName, name: fileInfo.fileName,
isUpdateFlag: checkUpdateFileIds.includes(fileInfo.fileId), isUpdateFlag: checkUpdateFileIds.includes(fileInfo.fileId),
showDelete: hasAnyPermission(['PROJECT_BUG:READ+UPDATE']),
}; };
}) })
.map((fileInfo: any) => { .map((fileInfo: any) => {
@ -563,4 +569,4 @@
:deep(.arco-form-item-label) { :deep(.arco-form-item-label) {
font-weight: bold !important; font-weight: bold !important;
} }
</style> </style>

View File

@ -258,6 +258,12 @@
if (res && res.platform_key) { if (res && res.platform_key) {
formCreateValue.value = JSON.parse(res.bug_platform_config); formCreateValue.value = JSON.parse(res.bug_platform_config);
// keychange // keychange
const findKey = platformOption.value.find((item) => item.id === res.platform_key);
if (!findKey) {
formRef.value?.resetFields();
platformRules.value = [];
return;
}
await handlePlatformChange(res.platform_key); await handlePlatformChange(res.platform_key);
form.SYNC_ENABLE = res.sync_enable; form.SYNC_ENABLE = res.sync_enable;
form.PLATFORM_KEY = res.platform_key; form.PLATFORM_KEY = res.platform_key;
@ -286,4 +292,4 @@
} }
} }
); );
</script> </script>