fix(全局): bug 修复

This commit is contained in:
baiqi 2024-05-30 16:06:19 +08:00 committed by 刘瑞斌
parent e556dc2fa5
commit 5f0135261c
15 changed files with 145 additions and 122 deletions

View File

@ -233,6 +233,7 @@
import type { ProjectListItem } from '@/models/setting/project';
import { CaseLinkEnum } from '@/enums/caseEnum';
import { CaseManagementRouteEnum } from '@/enums/routeEnum';
import { TableKeyEnum } from '@/enums/tableEnum';
import { FilterSlotNameEnum } from '@/enums/tableFilterEnum';
import { initGetModuleCountFunc, type RequestModuleEnum } from './utils';
@ -524,6 +525,7 @@
props.getTableFunc,
{
columns,
tableKey: TableKeyEnum.CASE_MANAGEMENT_ASSOCIATED_TABLE,
scroll: { x: '100%' },
showSetting: false,
selectable: true,

View File

@ -36,7 +36,7 @@
<template v-for="item in record.permissions" :key="item.id">
<a-checkbox
v-if="(item.license && licenseStore.hasLicense()) || !item.license"
:disabled="item.license || systemAdminDisabled || disabled"
:disabled="systemAdminDisabled || disabled"
:value="item.id"
>
{{ t(item.name) }}
@ -239,39 +239,41 @@
const makeData = (item: UserGroupAuthSetting, type: AuthScopeType) => {
const result: AuthTableItem[] = [];
item.children?.forEach((child, index) => {
const perChecked =
child?.permissions?.reduce((acc: string[], cur) => {
if (cur.enable) {
acc.push(cur.id);
}
return acc;
}, []) || [];
const perCheckedLength = perChecked.length;
let indeterminate = false;
if (child?.permissions) {
indeterminate = perCheckedLength > 0 && perCheckedLength < child?.permissions?.length;
if (!child.license || (child.license && licenseStore.hasLicense())) {
const perChecked =
child?.permissions?.reduce((acc: string[], cur) => {
if (cur.enable) {
acc.push(cur.id);
}
return acc;
}, []) || [];
const perCheckedLength = perChecked.length;
let indeterminate = false;
if (child?.permissions) {
indeterminate = perCheckedLength > 0 && perCheckedLength < child?.permissions?.length;
}
result.push({
id: child?.id,
license: child?.license,
enable: child?.enable,
permissions: child?.permissions,
indeterminate,
perChecked,
ability: index === 0 ? item.name : undefined,
operationObject: t(child.name),
isSystem: index === 0 && type === 'SYSTEM',
isOrganization: index === 0 && type === 'ORGANIZATION',
isProject: index === 0 && type === 'PROJECT',
isWorkstation: index === 0 && type === 'WORKSTATION',
isTestPlan: index === 0 && type === 'TEST_PLAN',
isBugManagement: index === 0 && type === 'BUG_MANAGEMENT',
isCaseManagement: index === 0 && type === 'CASE_MANAGEMENT',
isUiTest: index === 0 && type === 'UI_TEST',
isLoadTest: index === 0 && type === 'LOAD_TEST',
isApiTest: index === 0 && type === 'API_TEST',
isPersonal: index === 0 && type === 'PERSONAL',
});
}
result.push({
id: child?.id,
license: child?.license,
enable: child?.enable,
permissions: child?.permissions,
indeterminate,
perChecked,
ability: index === 0 ? item.name : undefined,
operationObject: t(child.name),
isSystem: index === 0 && type === 'SYSTEM',
isOrganization: index === 0 && type === 'ORGANIZATION',
isProject: index === 0 && type === 'PROJECT',
isWorkstation: index === 0 && type === 'WORKSTATION',
isTestPlan: index === 0 && type === 'TEST_PLAN',
isBugManagement: index === 0 && type === 'BUG_MANAGEMENT',
isCaseManagement: index === 0 && type === 'CASE_MANAGEMENT',
isUiTest: index === 0 && type === 'UI_TEST',
isLoadTest: index === 0 && type === 'LOAD_TEST',
isApiTest: index === 0 && type === 'API_TEST',
isPersonal: index === 0 && type === 'PERSONAL',
});
});
return result;
};

View File

@ -95,6 +95,11 @@
nameExistTipText?: string; //
}
export interface ConfirmValue {
field: string;
id?: string;
}
const props = withDefaults(
defineProps<{
title: string; //
@ -117,7 +122,7 @@
}
);
const emits = defineEmits<{
(e: 'confirm', formValue?: { field: string; id?: string }, cancel?: () => void): void;
(e: 'confirm', formValue: ConfirmValue, cancel?: () => void): void;
(e: 'cancel'): void;
(e: 'update:visible', visible: boolean): void;
}>();
@ -126,28 +131,12 @@
const attrs = useAttrs();
const formRef = ref<FormInstance>();
const isPass = ref(false);
const setValidateResult = (isValidatePass: boolean) => {
isPass.value = isValidatePass;
};
//
const form = ref({
field: props.fieldConfig?.field || '',
});
//
const validateForm = async () => {
await formRef.value?.validate((errors) => {
if (!errors) {
setValidateResult(true);
} else {
setValidateResult(false);
}
});
};
//
const reset = () => {
form.value.field = '';
@ -160,13 +149,12 @@
reset();
};
const handleConfirm = async () => {
await validateForm();
if (props.isDelete) {
emits('confirm', undefined, handleCancel);
} else {
emits('confirm', { ...form.value, id: props.nodeId }, handleCancel);
}
const handleConfirm = () => {
formRef.value?.validate((errors) => {
if (!errors) {
emits('confirm', { ...form.value, id: props.nodeId }, handleCancel);
}
});
};
//
const titleClass = computed(() => {
@ -209,11 +197,6 @@
}
}
};
defineExpose({
form,
isPass,
});
</script>
<style scoped lang="less">

View File

@ -87,6 +87,7 @@ export interface MsTableProps<T> {
heightUsed?: number; // 已经使用的高度
enableDrag?: boolean; // 表格是否可拖拽
draggable?: TableDraggable;
draggableCondition?: boolean; // 允许拖拽的条件
/** 选择器相关 */
selectable?: boolean; // 是否显示选择器
selectorType: 'none' | 'checkbox' | 'radio'; // 选择器类型

View File

@ -85,7 +85,7 @@ export default function useTableProps<T>(
};
// 属性组
const propsRes = ref<MsTableProps<T>>(defaultProps);
const propsRes = ref<MsTableProps<T>>(cloneDeep(defaultProps));
// 排序
const sortItem = ref<object>({});
@ -366,11 +366,34 @@ export default function useTableProps<T>(
propsRes.value.filter = cloneDeep(filterItem.value);
};
/**
*
* @param otherCondition false
*/
const setTableDraggable = (otherCondition?: boolean) => {
if (otherCondition === false || props?.draggableCondition === false) {
propsRes.value.draggable = undefined;
} else {
propsRes.value.draggable = props?.draggable;
}
};
watch(
() => props?.draggableCondition,
() => {
setTableDraggable();
},
{
immediate: true,
}
);
// 事件触发组
const propsEvent = ref({
// 排序触发
sorterChange: (sortObj: { [key: string]: string }) => {
sortItem.value = sortObj;
setTableDraggable(Object.keys(sortItem.value).length === 0);
loadList();
},
@ -387,7 +410,7 @@ export default function useTableProps<T>(
filterItem.value = { ...getTableQueryParams().filter, [dataIndex]: filteredValues };
}
propsRes.value.filter = cloneDeep(filterItem.value);
propsRes.value.draggable = (filterItem.value[dataIndex] || []).length > 0 ? undefined : props?.draggable;
setTableDraggable((filterItem.value[dataIndex] || []).length === 0);
loadList();
},
// 分页触发

View File

@ -18,7 +18,7 @@ const useLicenseStore = defineStore('license', {
this.status = null;
},
hasLicense() {
return this.status && this.status === 'valid';
return this.status === 'valid';
},
getExpirationTime(resTime: string) {
const today = Date.now();

View File

@ -42,13 +42,13 @@
<template v-if="!props.isModal" #extra="nodeData">
<MsPopConfirm
v-if="hasAnyPermission(['FUNCTIONAL_CASE:READ+ADD'])"
:visible="addSubVisible"
:is-delete="false"
:all-names="[]"
:all-names="(nodeData.children || []).map((e: ModuleTreeNode) => e.name || '')"
:title="t('caseManagement.featureCase.addSubModule')"
:ok-text="t('common.confirm')"
:field-config="{
placeholder: t('caseManagement.featureCase.addGroupTip'),
nameExistTipText: t('project.fileManagement.nameExist'),
}"
:loading="confirmLoading"
@confirm="addSubModule"
@ -61,11 +61,11 @@
<MsPopConfirm
v-if="hasAnyPermission(['FUNCTIONAL_CASE:READ+UPDATE'])"
:title="t('caseManagement.featureCase.rename')"
:all-names="[]"
:all-names="(nodeData.parent? nodeData.parent.children || [] : caseTree).filter((e: ModuleTreeNode) => e.id !== nodeData.id).map((e: ModuleTreeNode) => e.name || '')"
:is-delete="false"
:node-id="nodeData.id"
:ok-text="t('common.confirm')"
:field-config="{ field: renameCaseName }"
:field-config="{ field: renameCaseName, nameExistTipText: t('project.fileManagement.nameExist') }"
:loading="confirmLoading"
@confirm="updateNameModule"
@cancel="resetFocusNodeKey"
@ -83,7 +83,7 @@
import { Message } from '@arco-design/web-vue';
import MsButton from '@/components/pure/ms-button/index.vue';
import MsPopConfirm from '@/components/pure/ms-popconfirm/index.vue';
import MsPopConfirm, { ConfirmValue } from '@/components/pure/ms-popconfirm/index.vue';
import type { ActionsItem } from '@/components/pure/ms-table-more-action/types';
import MsTree from '@/components/business/ms-tree/index.vue';
import type { MsTreeNodeData } from '@/components/business/ms-tree/types';
@ -303,11 +303,10 @@
}
};
const addSubVisible = ref(false);
const confirmLoading = ref(false);
//
async function addSubModule(formValue?: { field: string }, cancel?: () => void) {
async function addSubModule(formValue: ConfirmValue, cancel?: () => void) {
try {
confirmLoading.value = true;
const params: CreateOrUpdateModule = {
@ -322,6 +321,7 @@
}
initModules();
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
} finally {
confirmLoading.value = false;
@ -329,7 +329,7 @@
}
//
async function updateNameModule(formValue?: { field: string; id?: string }, cancel?: () => void) {
async function updateNameModule(formValue: ConfirmValue, cancel?: () => void) {
try {
confirmLoading.value = true;
if (formValue && formValue.id) {
@ -345,6 +345,7 @@
initModules();
}
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
} finally {
confirmLoading.value = false;

View File

@ -51,7 +51,6 @@
</a-tooltip>
<MsPopConfirm
v-if="hasAnyPermission(['FUNCTIONAL_CASE:READ+ADD'])"
ref="confirmRef"
v-model:visible="addSubVisible"
:is-delete="false"
:title="t('caseManagement.featureCase.addSubModule')"
@ -60,6 +59,7 @@
:ok-text="t('common.confirm')"
:field-config="{
placeholder: t('caseManagement.featureCase.addGroupTip'),
nameExistTipText: t('project.fileManagement.nameExist'),
}"
@confirm="confirmHandler"
>
@ -154,7 +154,7 @@
import MsButton from '@/components/pure/ms-button/index.vue';
import MsCard from '@/components/pure/ms-card/index.vue';
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
import MsPopConfirm from '@/components/pure/ms-popconfirm/index.vue';
import MsPopConfirm, { ConfirmValue } from '@/components/pure/ms-popconfirm/index.vue';
import MsSplitBox from '@/components/pure/ms-split-box/index.vue';
import { MsTreeNodeData } from '@/components/business/ms-tree/types';
import CaseTable from './components/caseTable.vue';
@ -231,22 +231,17 @@
}
const confirmLoading = ref(false);
const confirmRef = ref();
const addSubVisible = ref(false);
const caseTreeRef = ref();
const caseTableRef = ref();
//
const confirmHandler = async () => {
async function confirmHandler(formValue: ConfirmValue) {
try {
confirmLoading.value = true;
const { field } = confirmRef.value.form;
if (!confirmRef.value.isPass) {
return;
}
const params: CreateOrUpdateModule = {
projectId: currentProjectId.value,
name: field,
name: formValue.field,
parentId: 'NONE',
};
await createCaseModuleTree(params);
@ -254,11 +249,12 @@
caseTreeRef.value.initModules();
addSubVisible.value = false;
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
} finally {
confirmLoading.value = false;
}
};
}
/**
* 设置根模块名称列表

View File

@ -70,7 +70,6 @@
allow-search
:multiple="true"
:placeholder="t('project.messageManagement.receiverPlaceholder')"
@click.stop="record.showModuleTree = true"
@change="() => changeReviewer(record)"
>
</MsSelect>
@ -278,7 +277,6 @@
import { MsFileItem } from '@/components/pure/ms-upload/types';
import caseLevel from '@/components/business/ms-case-associate/caseLevel.vue';
import MsSelect from '@/components/business/ms-select';
import TableFilter from '@/views/case-management/caseManagementFeature/components/tableFilter.vue';
import {
batchChangeReviewer,
@ -334,9 +332,6 @@
const filterConfigList = ref<FilterFormItem[]>([]);
const tableParams = ref<Record<string, any>>({});
const statusFilterVisible = ref(false);
const statusFilters = ref<string[]>([]);
const hasOperationPermission = computed(() =>
hasAnyPermission(['CASE_REVIEW:READ+REVIEW', 'CASE_REVIEW:READ+RELEVANCE'])
);

View File

@ -23,8 +23,10 @@
:type="IconMap[robot.platform]"
class="mr-[8px] h-[40px] w-[40px] bg-[var(--color-text-n9)] p-[8px] text-[rgb(var(--primary-5))]"
/>
<div class="flex flex-1 flex-col">
<div class="break-all font-medium text-[var(--color-text-1)]">{{ robot.name }}</div>
<div class="flex flex-1 flex-col overflow-hidden">
<a-tooltip position="tl" :content="robot.name">
<div class="one-line-text font-medium text-[var(--color-text-1)]">{{ robot.name }}</div>
</a-tooltip>
<div
v-if="['IN_SITE', 'MAIL'].includes(robot.platform)"
class="text-[12px] leading-[16px] text-[var(--color-text-4)]"

View File

@ -222,7 +222,12 @@
pause();
};
const handleModuleChange = (value: (string | number | boolean)[]) => {
if (props.currentProject?.id && timer.value === 5 && props.currentProject.moduleIds?.length) {
if (
value.length < (props.currentProject?.moduleIds || []).length &&
props.currentProject?.id &&
timer.value === 5 &&
props.currentProject.moduleIds?.length
) {
if (props.currentProject.moduleIds.some((item) => value.includes(item))) {
resume();
Message.warning({

View File

@ -78,10 +78,10 @@
v-if="!record.internal && hasAnyPermission(props.updatePermission)"
:disabled="record.internal"
class="!mr-0"
>{{ t('system.orgTemplate.edit') }}</MsButton
></MsPopConfirm
>
>
{{ t('system.orgTemplate.edit') }}
</MsButton>
</MsPopConfirm>
<a-divider
v-if="
!record.internal && hasAnyPermission(props.updatePermission) && hasAnyPermission(props.deletePermission)

View File

@ -34,7 +34,6 @@
<template #extra="nodeData">
<MsPopConfirm
v-if="hasAnyPermission(['PROJECT_TEST_PLAN:READ+ADD'])"
:visible="addSubVisible"
:is-delete="false"
:all-names="(nodeData.children || []).map((e: ModuleTreeNode) => e.name || '')"
:title="t('testPlan.testPlanIndex.addSubModule')"
@ -81,7 +80,7 @@
import { Message } from '@arco-design/web-vue';
import MsButton from '@/components/pure/ms-button/index.vue';
import MsPopConfirm from '@/components/pure/ms-popconfirm/index.vue';
import MsPopConfirm, { ConfirmValue } from '@/components/pure/ms-popconfirm/index.vue';
import type { ActionsItem } from '@/components/pure/ms-table-more-action/types';
import MsTree from '@/components/business/ms-tree/index.vue';
import type { MsTreeNodeData } from '@/components/business/ms-tree/types';
@ -297,16 +296,15 @@
}
};
const addSubVisible = ref(false);
const confirmLoading = ref(false);
//
async function addSubModule(formValue?: { field: string }, cancel?: () => void) {
async function addSubModule(formValue: ConfirmValue, cancel?: () => void) {
try {
confirmLoading.value = true;
const params: CreateOrUpdateModule = {
projectId: currentProjectId.value,
name: formValue?.field as string,
name: formValue.field,
parentId: focusNodeKey.value,
};
await createPlanModuleTree(params);
@ -316,6 +314,7 @@
}
initModules(true);
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
} finally {
confirmLoading.value = false;
@ -323,12 +322,12 @@
}
//
async function updateNameModule(formValue?: { field: string }, cancel?: () => void) {
async function updateNameModule(formValue: ConfirmValue, cancel?: () => void) {
try {
confirmLoading.value = true;
const params: UpdateModule = {
id: focusNodeKey.value,
name: formValue?.field as string,
name: formValue.field,
};
await updatePlanModuleTree(params);
Message.success(t('common.updateSuccess'));
@ -337,6 +336,7 @@
}
initModules();
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
} finally {
confirmLoading.value = false;

View File

@ -18,9 +18,6 @@
v-bind="propsRes"
:action-config="batchActions"
:selectable="hasOperationPermission"
:draggable="
hasAnyPermission(['PROJECT_TEST_PLAN:READ+UPDATE']) && props.canEdit ? { type: 'handle', width: 32 } : undefined
"
v-on="propsEvent"
@batch-action="handleTableBatch"
@drag-change="handleDragChange"
@ -173,7 +170,12 @@
import MsButton from '@/components/pure/ms-button/index.vue';
import MsPopconfirm from '@/components/pure/ms-popconfirm/index.vue';
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
import type { BatchActionParams, BatchActionQueryParams, MsTableColumn } from '@/components/pure/ms-table/type';
import type {
BatchActionParams,
BatchActionQueryParams,
MsTableColumn,
MsTableProps,
} from '@/components/pure/ms-table/type';
import useTable from '@/components/pure/ms-table/useTable';
import CaseLevel from '@/components/business/ms-case-associate/caseLevel.vue';
import ExecuteResult from '@/components/business/ms-case-associate/executeResult.vue';
@ -345,15 +347,20 @@
width: hasOperationPermission.value ? 200 : 50,
},
]);
const tableProps = ref<Partial<MsTableProps<PlanDetailFeatureCaseItem>>>({
scroll: { x: '100%' },
tableKey: TableKeyEnum.TEST_PLAN_DETAIL_FEATURE_CASE_TABLE,
showSetting: true,
heightUsed: 460,
showSubdirectory: true,
draggable: { type: 'handle' },
draggableCondition: true,
});
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector, getTableQueryParams } = useTable(
getPlanDetailFeatureCaseList,
{
scroll: { x: '100%' },
tableKey: TableKeyEnum.TEST_PLAN_DETAIL_FEATURE_CASE_TABLE,
showSetting: true,
heightUsed: 460,
showSubdirectory: true,
},
tableProps.value,
(record) => {
return {
...record,
@ -363,6 +370,17 @@
};
}
);
watch(
() => props.canEdit,
(val) => {
tableProps.value.draggableCondition = hasAnyPermission(['PROJECT_TEST_PLAN:READ+UPDATE']) && val;
},
{
immediate: true,
}
);
const batchActions = {
baseAction: [
{

View File

@ -37,7 +37,6 @@
</MsButton>
</a-tooltip>
<MsPopConfirm
ref="confirmRef"
v-model:visible="addSubVisible"
:is-delete="false"
:title="t('testPlan.testPlanIndex.addSubModule')"
@ -110,7 +109,7 @@
import MsButton from '@/components/pure/ms-button/index.vue';
import MsCard from '@/components/pure/ms-card/index.vue';
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
import MsPopConfirm from '@/components/pure/ms-popconfirm/index.vue';
import MsPopConfirm, { ConfirmValue } from '@/components/pure/ms-popconfirm/index.vue';
import MsSplitBox from '@/components/pure/ms-split-box/index.vue';
import PlanTable from './components/planTable.vue';
import TestPlanTree from './components/testPlanTree.vue';
@ -159,17 +158,12 @@
const addSubVisible = ref(false);
const planTreeRef = ref();
const confirmLoading = ref(false);
const confirmRef = ref();
async function confirmHandler() {
async function confirmHandler(formValue: ConfirmValue) {
try {
confirmLoading.value = true;
const { field } = confirmRef.value.form;
if (!confirmRef.value.isPass) {
return;
}
const params: CreateOrUpdateModule = {
projectId: currentProjectId.value,
name: field,
name: formValue.field,
parentId: 'NONE',
};
await createPlanModuleTree(params);
@ -177,6 +171,7 @@
planTreeRef.value.initModules();
addSubVisible.value = false;
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
} finally {
confirmLoading.value = false;