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:
parent
c84c4ba8e7
commit
3e42d29b6e
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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';
|
||||||
|
|
|
@ -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) => {
|
||||||
|
|
|
@ -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);
|
||||||
// 如果平台key存在调用平台change拉取插件字段
|
// 如果平台key存在调用平台change拉取插件字段
|
||||||
|
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;
|
||||||
|
|
Loading…
Reference in New Issue