feat(项目管理): 菜单管理新增误报规则
This commit is contained in:
parent
74249c3663
commit
848d817e60
|
@ -3,6 +3,7 @@ import * as Url from '@/api/requrls/project-management/menuManagement';
|
|||
|
||||
import { TableQueryParams } from '@/models/common';
|
||||
import type {
|
||||
FakeTableListItem,
|
||||
MenuTableConfigItem,
|
||||
MenuTableListItem,
|
||||
MenuTableListParams,
|
||||
|
@ -106,6 +107,35 @@ export function getPlatformOptions(organizationId: string, type: MenuEnum) {
|
|||
return MSR.get<PoolOption[]>({ url: `${Url.getPlatformOptionUrlByCase}${organizationId}` });
|
||||
}
|
||||
|
||||
/**
|
||||
* 缺陷同步保存
|
||||
* @param data 缺陷同步配置项
|
||||
* @param projectId 项目ID
|
||||
* @returns
|
||||
*/
|
||||
export function postSaveDefectSync(data: MenuTableConfigItem, projectId: string) {
|
||||
return MSR.post<MenuTableListItem>({ url: `${Url.postSyncBugConfigUrl}${projectId}`, data });
|
||||
}
|
||||
|
||||
// 误报规则列表查询
|
||||
export function postFakeTableList(data: TableQueryParams) {
|
||||
return MSR.post<FakeTableListItem[]>({ url: `${Url.postFakeTableUrl}`, data });
|
||||
}
|
||||
// 误报规则新增
|
||||
export function postAddFake(data: any) {
|
||||
return MSR.post<FakeTableListItem[]>({ url: Url.postFakeTableAddUrl, data });
|
||||
}
|
||||
// 误报规则更新
|
||||
export function postUpdateFake(data: any) {
|
||||
return MSR.post<FakeTableListItem[]>({ url: Url.postFakeTableUpdateUrl, data });
|
||||
}
|
||||
|
||||
// 误报规则启用禁用
|
||||
export function postUpdateEnableFake(data: any) {
|
||||
return MSR.post<FakeTableListItem[]>({ url: Url.postFakeTableEnableUrl, data });
|
||||
}
|
||||
|
||||
// 误报规则删除
|
||||
export function getDeleteFake(data: any) {
|
||||
return MSR.get<FakeTableListItem[]>({ url: Url.getFakeTableDeleteUrl, data });
|
||||
}
|
||||
|
|
|
@ -8,3 +8,13 @@ export const getPlatformOptionUrlByBug = '/project/application/bug/platform/';
|
|||
export const getPlatformOptionUrlByCase = '/project/application/case/platform/';
|
||||
// 缺陷管理-同步缺陷配置
|
||||
export const postSyncBugConfigUrl = '/project/application/update/bug/sync/';
|
||||
// 误报规则列表查询
|
||||
export const postFakeTableUrl = '/fake/error/list';
|
||||
// 误报规则列表删除
|
||||
export const getFakeTableDeleteUrl = '/fake/error/delete';
|
||||
// 误报规则列表新增
|
||||
export const postFakeTableAddUrl = '/fake/error/add';
|
||||
// 误报规则列表更改
|
||||
export const postFakeTableUpdateUrl = '/fake/error/update';
|
||||
// 误报规则列表启用或禁用
|
||||
export const postFakeTableEnableUrl = '/fake/error/update/enable';
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
asterisk-position="end"
|
||||
:hide-asterisk="model.hideAsterisk"
|
||||
:hide-label="model.hideLabel"
|
||||
:content-flex="model.type !== 'multiple'"
|
||||
:merge-props="model.type !== 'multiple'"
|
||||
>
|
||||
<a-input
|
||||
v-if="model.type === 'input'"
|
||||
|
@ -56,7 +58,61 @@
|
|||
:max="model.max || 9999999"
|
||||
allow-clear
|
||||
/>
|
||||
<MsTagsInput
|
||||
v-if="model.type === 'tagInput'"
|
||||
v-model="element[model.filed]"
|
||||
class="flex-1"
|
||||
:placeholder="t(model.placeholder || 'common.tagPlaceholder')"
|
||||
allow-clear
|
||||
unique-value
|
||||
retain-input-value
|
||||
/>
|
||||
<a-select
|
||||
v-if="model.type === 'select'"
|
||||
v-model="element[model.filed]"
|
||||
class="flex-1"
|
||||
:placeholder="t(model.placeholder || '')"
|
||||
:options="model.options"
|
||||
:field-names="model.filedNames"
|
||||
/>
|
||||
<div v-if="model.type === 'multiple'" class="flex flex-row items-center gap-[4px]">
|
||||
<a-form-item
|
||||
v-for="(child, childIndex) in model.children"
|
||||
:key="`${child.filed}${childIndex}${index}`"
|
||||
:field="`list[${index}].${child.filed}`"
|
||||
:label="child.label ? t(child.label) : ''"
|
||||
asterisk-position="end"
|
||||
:hide-asterisk="child.hideAsterisk"
|
||||
:hide-label="child.hideLabel"
|
||||
class="hidden-item"
|
||||
>
|
||||
<a-input
|
||||
v-if="child.type === 'input'"
|
||||
v-model="element[child.filed]"
|
||||
:class="child.className"
|
||||
:placeholder="t(child.placeholder || '')"
|
||||
:max-length="child.maxLength || 250"
|
||||
allow-clear
|
||||
/>
|
||||
<a-select
|
||||
v-if="child.type === 'select'"
|
||||
v-model="element[child.filed]"
|
||||
:class="child.className"
|
||||
:placeholder="t(child.placeholder || '')"
|
||||
:options="child.options"
|
||||
:field-names="child.filedNames"
|
||||
:default-value="child.defaultValue"
|
||||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
</a-form-item>
|
||||
<div v-if="showEnable">
|
||||
<a-switch
|
||||
v-model="element.enable"
|
||||
:style="{ 'margin-top': index === 0 && !props.isShowDrag ? '36px' : '' }"
|
||||
size="small"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-show="form.list.length > 1"
|
||||
class="minus"
|
||||
|
@ -94,6 +150,8 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, unref, watchEffect } from 'vue';
|
||||
|
||||
import MsTagsInput from '@/components/pure/ms-tags-input/index.vue';
|
||||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { scrollIntoView } from '@/utils/dom';
|
||||
|
||||
|
@ -112,6 +170,7 @@
|
|||
defaultVals?: any[]; // 当外层是编辑状态时,可传入已填充的数据
|
||||
isShowDrag: boolean; // 是否可以拖拽
|
||||
formWidth?: string; // 自定义表单区域宽度
|
||||
showEnable?: boolean; // 是否显示启用禁用switch状态
|
||||
}>(),
|
||||
{
|
||||
maxHeight: '30vh',
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { FieldRule } from '@arco-design/web-vue';
|
||||
import { FieldRule, SelectFieldNames, SelectOptionData, SelectOptionGroup } from '@arco-design/web-vue';
|
||||
|
||||
export type FormItemType = 'input' | 'select' | 'inputNumber';
|
||||
export type FormItemType = 'input' | 'select' | 'inputNumber' | 'tagInput' | 'multiple' | 'switch';
|
||||
export type FormMode = 'create' | 'edit';
|
||||
export type ValueType = 'Array' | 'string';
|
||||
// 自定义检验器,为了传入动态渲染的表单项下标
|
||||
|
@ -19,6 +19,11 @@ export interface FormItemModel {
|
|||
maxLength?: number;
|
||||
hideAsterisk?: boolean;
|
||||
hideLabel?: boolean;
|
||||
children?: FormItemModel[];
|
||||
options?: (string | number | boolean | SelectOptionData | SelectOptionGroup)[]; // select option 选项
|
||||
filedNames?: SelectFieldNames; // select option 选项字段名
|
||||
className?: string; // 自定义样式
|
||||
defaultValue?: string | string[] | number | number[] | boolean; // 默认值
|
||||
}
|
||||
|
||||
declare const _default: import('vue').DefineComponent<
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
:label="t('system.userGroup.user')"
|
||||
:rules="[{ required: true, message: t('system.userGroup.pleaseSelectUser') }]"
|
||||
>
|
||||
<MsUserSelector v-model:value="form.name" v-bind="userSelectorProps" />
|
||||
<MsUserSelector v-model="form.name" v-bind="userSelectorProps" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
value: string[] | string; // 选中的值
|
||||
modelValue: string[] | string; // 选中的值
|
||||
disabled?: boolean; // 是否禁用
|
||||
disabledKey?: string; // 禁用的key
|
||||
valueKey?: string; // value的key
|
||||
|
@ -61,17 +61,16 @@
|
|||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:value', value: string[]): void;
|
||||
(e: 'update:modelValue', value: string[]): void;
|
||||
}>();
|
||||
const { t } = useI18n();
|
||||
|
||||
const allOptions = ref<MsUserSelectorOption[]>([]);
|
||||
const currentOptions = ref<MsUserSelectorOption[]>([]);
|
||||
const currentLoadParams = ref<Record<string, any>>(props.loadOptionParams || {});
|
||||
const loading = ref(false);
|
||||
|
||||
const currentValue = computed(() => {
|
||||
return currentOptions.value.filter((item) => props.value.includes(item.id)) || [];
|
||||
return allOptions.value.filter((item) => props.modelValue.includes(item.id)) || [];
|
||||
});
|
||||
|
||||
const loadList = async () => {
|
||||
|
@ -128,13 +127,11 @@
|
|||
value: string | number | boolean | Record<string, any> | (string | number | boolean | Record<string, any>)[]
|
||||
) => {
|
||||
const tmpArr = Array.isArray(value) ? value : [value];
|
||||
currentOptions.value = tmpArr;
|
||||
const { valueKey } = props;
|
||||
emit(
|
||||
'update:value',
|
||||
'update:modelValue',
|
||||
tmpArr.map((item) => item[valueKey])
|
||||
);
|
||||
debouncedSearch('');
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
|
|
|
@ -28,6 +28,7 @@ export enum ProjectManagementRouteEnum {
|
|||
PROJECT_MANAGEMENT_PERMISSION_VERSION = 'projectManagementPermissionVersion',
|
||||
PROJECT_MANAGEMENT_PERMISSION_USER_GROUP = 'projectManagementPermissionUserGroup',
|
||||
PROJECT_MANAGEMENT_PERMISSION_MEMBER = 'projectManagementPermissionMember',
|
||||
PROJECT_MANAGEMENT_MENU_MANAGEMENT_ERROR_REPORT_RULE = 'projectManagementMenuManagementErrorReportRule',
|
||||
}
|
||||
|
||||
export enum TestPlanRouteEnum {
|
||||
|
|
|
@ -23,6 +23,7 @@ export enum TableKeyEnum {
|
|||
FILE_MANAGEMENT_FILE = 'fileManagementFile',
|
||||
FILE_MANAGEMENT_CASE = 'fileManagementCase',
|
||||
FILE_MANAGEMENT_VERSION = 'fileManagementVersion',
|
||||
PROJECT_MANAGEMENT_MENU_FALSE_ALERT = 'projectManagementMenuFalseAlert',
|
||||
}
|
||||
|
||||
// 具有特殊功能的列
|
||||
|
|
|
@ -62,4 +62,5 @@ export default {
|
|||
'common.allSelect': '全选',
|
||||
'common.setting': '设置',
|
||||
'common.resetDefault': '恢复默认',
|
||||
'common.tagPlaceholder': '添加标签回车结束',
|
||||
};
|
||||
|
|
|
@ -25,3 +25,12 @@ export type SelectValue =
|
|||
| boolean
|
||||
| Record<string, any>
|
||||
| (string | number | boolean | Record<string, any>)[];
|
||||
|
||||
export interface FakeTableListItem {
|
||||
name: string;
|
||||
enable: boolean;
|
||||
label: string[];
|
||||
rule: string;
|
||||
creator: string;
|
||||
updateDate: string;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ export interface CreateOrUpdateSystemOrgParams {
|
|||
id?: string;
|
||||
name: string;
|
||||
description: string;
|
||||
memberIds: string[];
|
||||
userIds: string[];
|
||||
}
|
||||
export interface CreateOrUpdateSystemProjectParams {
|
||||
id?: string;
|
||||
|
|
|
@ -143,6 +143,29 @@ const ProjectManagement: AppRouteRecordRaw = {
|
|||
isTopMenu: true,
|
||||
},
|
||||
},
|
||||
// 菜单管理-误报规则
|
||||
{
|
||||
path: 'errorReportRule',
|
||||
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_MENU_MANAGEMENT_ERROR_REPORT_RULE,
|
||||
component: () =>
|
||||
import('@/views/project-management/projectAndPermission/menuManagement/components/falseAlermRule.vue'),
|
||||
meta: {
|
||||
locale: 'project.menu.far',
|
||||
roles: ['*'],
|
||||
breadcrumbs: [
|
||||
{
|
||||
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_PERMISSION_MENU_MANAGEMENT,
|
||||
locale: 'project.permission.menuManagement',
|
||||
},
|
||||
{
|
||||
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_MENU_MANAGEMENT_ERROR_REPORT_RULE,
|
||||
locale: 'menu.projectManagement.menuManagementErrorReportRule',
|
||||
editTag: 'id',
|
||||
editLocale: 'project.menu.far',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
:rules="[{ required: true, message: t('project.member.selectMemberEmptyTip') }]"
|
||||
>
|
||||
<MsUserSelector
|
||||
v-model:value="form.userIds"
|
||||
v-model="form.userIds"
|
||||
:load-option-params="{ projectId: lastProjectId }"
|
||||
:type="UserRequestTypeEnum.PROJECT_PERMISSION_MEMBER"
|
||||
placeholder="project.member.selectMemberScope"
|
||||
|
|
|
@ -0,0 +1,339 @@
|
|||
<template>
|
||||
<MsCard simple>
|
||||
<div class="mb-4 flex items-center justify-between">
|
||||
<a-button type="primary" @click="showAddRule">{{ t('project.menu.addFalseAlertRules') }}</a-button>
|
||||
<a-input-search
|
||||
v-model="keyword"
|
||||
:placeholder="t('project.menu.nameSearch')"
|
||||
class="w-[240px]"
|
||||
allow-clear
|
||||
@press-enter="fetchData"
|
||||
@search="fetchData"
|
||||
></a-input-search>
|
||||
</div>
|
||||
<MsBaseTable v-bind="propsRes" v-on="propsEvent">
|
||||
<template #operation="{ record }">
|
||||
<template v-if="record.deleted">
|
||||
<MsButton @click="handleRevokeDelete(record)">{{ t('common.revokeDelete') }}</MsButton>
|
||||
</template>
|
||||
<template v-else-if="!record.enable">
|
||||
<MsButton @click="handleEnableOrDisableProject(record)">{{ t('common.enable') }}</MsButton>
|
||||
<MsButton @click="handleDelete(record)">{{ t('common.delete') }}</MsButton>
|
||||
</template>
|
||||
<template v-else>
|
||||
<MsButton @click="showAddProjectModal(record)">{{ t('common.edit') }}</MsButton>
|
||||
<MsButton @click="showAddUserModal(record)">{{ t('system.organization.addMember') }}</MsButton>
|
||||
<MsButton @click="handleEnableOrDisableProject(record, false)">{{ t('common.end') }}</MsButton>
|
||||
<MsTableMoreAction :list="tableActions" @select="handleMoreAction($event, record)"></MsTableMoreAction>
|
||||
</template>
|
||||
</template>
|
||||
</MsBaseTable>
|
||||
</MsCard>
|
||||
<MsDrawer
|
||||
v-model:visible="addVisible"
|
||||
:title="t('project.menu.addFalseAlertRules')"
|
||||
:destroy-on-close="true"
|
||||
:closable="true"
|
||||
:mask-closable="false"
|
||||
:get-container="false"
|
||||
:body-style="{ padding: '0px' }"
|
||||
:width="1200"
|
||||
:ok-loading="addLoading"
|
||||
@cancel="handleCancel(false)"
|
||||
@confirm="handleConfirm"
|
||||
>
|
||||
<a-form ref="ruleFormRef" class="rounded-[4px]" :model="ruleForm" layout="vertical">
|
||||
<MsBatchForm
|
||||
ref="batchFormRef"
|
||||
:models="batchFormModels"
|
||||
:form-mode="ruleFormMode"
|
||||
add-text="system.user.addUser"
|
||||
:default-vals="ruleForm.list"
|
||||
show-enable
|
||||
></MsBatchForm>
|
||||
</a-form>
|
||||
</MsDrawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { FormInstance, Message, TableData } from '@arco-design/web-vue';
|
||||
|
||||
import MsCard from '@/components/pure/ms-card/index.vue';
|
||||
import MsDrawer from '@/components/pure/ms-drawer/index.vue';
|
||||
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
||||
import { MsTableColumn } from '@/components/pure/ms-table/type';
|
||||
import useTable from '@/components/pure/ms-table/useTable';
|
||||
import { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
||||
import MsBatchForm from '@/components/business/ms-batch-form/index.vue';
|
||||
import { FormItemModel } from '@/components/business/ms-batch-form/types';
|
||||
|
||||
import { postFakeTableList } from '@/api/modules/project-management/menuManagement';
|
||||
import {
|
||||
createOrUpdateProjectByOrg,
|
||||
deleteProjectByOrg,
|
||||
enableOrDisableProjectByOrg,
|
||||
postProjectTableByOrg,
|
||||
revokeDeleteProjectByOrg,
|
||||
} from '@/api/modules/setting/organizationAndProject';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import { useAppStore } from '@/store';
|
||||
import { validateEmail, validatePhone } from '@/utils/validate';
|
||||
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
|
||||
type UserModalMode = 'create' | 'edit';
|
||||
|
||||
const { t } = useI18n();
|
||||
const appStore = useAppStore();
|
||||
const currentProjectId = computed(() => appStore.currentProjectId);
|
||||
const addVisible = ref(false);
|
||||
const addLoading = ref(false);
|
||||
const ruleFormRef = ref<FormInstance>();
|
||||
const batchFormRef = ref<FormInstance>();
|
||||
const ruleFormMode = ref<UserModalMode>('create');
|
||||
const ruleForm = reactive({
|
||||
name: '',
|
||||
enable: true,
|
||||
label: '',
|
||||
type: '',
|
||||
creator: '',
|
||||
updateTime: '',
|
||||
list: [],
|
||||
});
|
||||
const rulesColumn: MsTableColumn = [
|
||||
{
|
||||
title: 'project.menu.rule.name',
|
||||
dataIndex: 'name',
|
||||
width: 100,
|
||||
showTooltip: true,
|
||||
},
|
||||
{
|
||||
title: 'project.menu.rule.enable',
|
||||
dataIndex: 'enable',
|
||||
showTooltip: true,
|
||||
},
|
||||
{
|
||||
title: 'project.menu.rule.label',
|
||||
dataIndex: 'label',
|
||||
width: 100,
|
||||
showTooltip: true,
|
||||
},
|
||||
{
|
||||
title: 'project.menu.rule.rule',
|
||||
dataIndex: 'type',
|
||||
width: 100,
|
||||
showTooltip: true,
|
||||
},
|
||||
{
|
||||
title: 'project.menu.rule.creator',
|
||||
dataIndex: 'creator',
|
||||
width: 100,
|
||||
showTooltip: true,
|
||||
},
|
||||
{
|
||||
title: 'project.menu.rule.updateTime',
|
||||
dataIndex: 'updateTime',
|
||||
width: 100,
|
||||
showTooltip: true,
|
||||
},
|
||||
{
|
||||
title: 'project.menu.rule.operation',
|
||||
dataIndex: 'operation',
|
||||
slotName: 'operation',
|
||||
width: 100,
|
||||
showTooltip: true,
|
||||
},
|
||||
];
|
||||
const { propsRes, propsEvent, loadList, setKeyword, setLoadListParams } = useTable(postFakeTableList, {
|
||||
columns: rulesColumn,
|
||||
tableKey: TableKeyEnum.PROJECT_MANAGEMENT_MENU_FALSE_ALERT,
|
||||
selectable: true,
|
||||
noDisable: false,
|
||||
size: 'default',
|
||||
});
|
||||
|
||||
const { openDeleteModal, openModal } = useModal();
|
||||
|
||||
const keyword = ref('');
|
||||
|
||||
const fetchData = async () => {
|
||||
setKeyword(keyword.value);
|
||||
await loadList();
|
||||
};
|
||||
|
||||
const handleDelete = (record: TableData) => {
|
||||
openDeleteModal({
|
||||
title: t('system.organization.deleteName', { name: record.name }),
|
||||
content: t('system.organization.deleteTip'),
|
||||
onBeforeOk: async () => {
|
||||
try {
|
||||
await deleteProjectByOrg(record.id);
|
||||
Message.success(t('common.deleteSuccess'));
|
||||
fetchData();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const handleMoreAction = (tag: ActionsItem, record: TableData) => {
|
||||
if (tag.eventTag === 'delete') {
|
||||
handleDelete(record);
|
||||
}
|
||||
};
|
||||
|
||||
const tableActions: ActionsItem[] = [
|
||||
{
|
||||
label: 'system.user.delete',
|
||||
eventTag: 'delete',
|
||||
danger: true,
|
||||
},
|
||||
];
|
||||
|
||||
const handleEnableOrDisableProject = async (record: any, isEnable = true) => {
|
||||
const title = isEnable ? t('system.project.enableTitle') : t('system.project.endTitle');
|
||||
const content = isEnable ? t('system.project.enableContent') : t('system.project.endContent');
|
||||
const okText = isEnable ? t('common.confirmEnable') : t('common.confirmClose');
|
||||
openModal({
|
||||
type: 'error',
|
||||
cancelText: t('common.cancel'),
|
||||
title,
|
||||
content,
|
||||
okText,
|
||||
onBeforeOk: async () => {
|
||||
try {
|
||||
await enableOrDisableProjectByOrg(record.id, isEnable);
|
||||
Message.success(isEnable ? t('common.enableSuccess') : t('common.closeSuccess'));
|
||||
fetchData();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
hideCancel: false,
|
||||
});
|
||||
};
|
||||
const handleRevokeDelete = async (record: TableData) => {
|
||||
openModal({
|
||||
type: 'error',
|
||||
cancelText: t('common.cancel'),
|
||||
title: t('system.project.revokeDeleteTitle', { name: record.name }),
|
||||
content: t('system.project.enableContent'),
|
||||
okText: t('common.revokeDelete'),
|
||||
onBeforeOk: async () => {
|
||||
try {
|
||||
await revokeDeleteProjectByOrg(record.id);
|
||||
Message.success(t('common.revokeDeleteSuccess'));
|
||||
fetchData();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
}
|
||||
},
|
||||
hideCancel: false,
|
||||
});
|
||||
};
|
||||
|
||||
const showAddProjectModal = (record: any) => {
|
||||
console.log(record);
|
||||
};
|
||||
|
||||
const showAddUserModal = (record: any) => {
|
||||
console.log(record);
|
||||
};
|
||||
const showAddRule = () => {
|
||||
addVisible.value = true;
|
||||
};
|
||||
|
||||
const handleConfirm = () => {
|
||||
addVisible.value = false;
|
||||
};
|
||||
|
||||
const handleCancel = (shouldSearch: boolean) => {
|
||||
if (shouldSearch) {
|
||||
fetchData();
|
||||
}
|
||||
addVisible.value = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* 校验用户姓名
|
||||
* @param value 输入的值
|
||||
* @param callback 失败回调,入参是提示信息
|
||||
*/
|
||||
function checkUerName(value: string | undefined, callback: (error?: string) => void) {
|
||||
if (value === '' || value === undefined) {
|
||||
callback(t('system.user.createUserNameNotNull'));
|
||||
} else if (value.length > 50) {
|
||||
callback(t('system.user.createUserNameOverLength'));
|
||||
}
|
||||
}
|
||||
|
||||
const batchFormModels: Ref<FormItemModel[]> = ref([
|
||||
{
|
||||
filed: 'name',
|
||||
type: 'input',
|
||||
label: 'project.menu.rule.ruleName',
|
||||
rules: [
|
||||
{ required: true, message: t('system.user.createUserNameNotNull') },
|
||||
{ validator: checkUerName },
|
||||
{ notRepeat: true, message: 'system.user.createUserEmailNoRepeat' },
|
||||
],
|
||||
},
|
||||
{
|
||||
filed: 'type',
|
||||
type: 'tagInput',
|
||||
label: 'project.menu.rule.label',
|
||||
},
|
||||
{
|
||||
filed: 'rule',
|
||||
type: 'multiple',
|
||||
label: 'project.menu.rule.rule',
|
||||
// rules: [{ required: true, message: t('system.user.createUserEmailNotNull') }],
|
||||
children: [
|
||||
{
|
||||
filed: 'respType', // 匹配规则-内容类型/header/data/body
|
||||
type: 'select',
|
||||
rules: [{ required: true, message: t('system.user.createUserEmailNotNull') }],
|
||||
options: [
|
||||
{ label: 'Response Headers', value: 'headers' },
|
||||
{ label: 'Response Data', value: 'data' },
|
||||
{ label: 'Response Body', value: 'body' },
|
||||
],
|
||||
className: 'w-[205px]',
|
||||
defaultValue: 'headers',
|
||||
},
|
||||
{
|
||||
filed: 'relation', // 匹配规则-操作类型
|
||||
type: 'select',
|
||||
options: [
|
||||
{ label: '包含', value: 'contain' },
|
||||
{ label: '不包含', value: 'notContain' },
|
||||
{ label: '等于', value: 'equal' },
|
||||
{ label: '不等于', value: 'notEqual' },
|
||||
{ label: '正则匹配', value: 'regex' },
|
||||
{ label: '以...开始', value: 'startWith' },
|
||||
{ label: '以...结束', value: 'endWith' },
|
||||
],
|
||||
rules: [{ required: true, message: t('system.user.createUserEmailNotNull') }],
|
||||
className: 'w-[120px]',
|
||||
defaultValue: 'contain',
|
||||
},
|
||||
{
|
||||
filed: 'expression', // 匹配规则-表达式
|
||||
type: 'input',
|
||||
rules: [{ required: true, message: t('system.user.createUserEmailNotNull') }],
|
||||
className: 'w-[301px]',
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
onMounted(() => {
|
||||
setLoadListParams({ projectId: currentProjectId.value });
|
||||
fetchData();
|
||||
});
|
||||
</script>
|
|
@ -62,4 +62,14 @@ export default {
|
|||
'project.menu.howGetJiraKey': '如何获取JIRA 项目 key ',
|
||||
'project.menu.preview': '预览',
|
||||
'project.menu.pleaseInputJiraKey': '请输入 JIRA 项目 key',
|
||||
'project.menu.addFalseAlertRules': '新增误报规则',
|
||||
'project.menu.nameSearch': '通过名称搜索',
|
||||
'project.menu.rule.name': '名称',
|
||||
'project.menu.rule.enable': '状态',
|
||||
'project.menu.rule.label': '标签',
|
||||
'project.menu.rule.rule': '规则',
|
||||
'project.menu.rule.creator': '创建人',
|
||||
'project.menu.rule.updateTime': '更新时间',
|
||||
'project.menu.rule.operation': '操作',
|
||||
'project.menu.rule.ruleName': '规则名称',
|
||||
};
|
||||
|
|
|
@ -120,7 +120,7 @@
|
|||
</template>
|
||||
</a-input>
|
||||
</div>
|
||||
<div class="ml-[8px] text-[rgb(var(--primary-7))]" @click="showDefectDrawer">{{ t('project.menu.far') }}</div>
|
||||
<div class="ml-[8px] text-[rgb(var(--primary-7))]" @click="pushFar">{{ t('project.menu.far') }}</div>
|
||||
<a-tooltip :content="t('project.menu.API_ERROR_REPORT_RULE_TIP')" position="right">
|
||||
<div>
|
||||
<MsIcon class="ml-[4px] text-[rgb(var(--primary-5))]" type="icon-icon-maybe_outlined" />
|
||||
|
@ -310,6 +310,7 @@
|
|||
/**
|
||||
* @description 项目管理-项目与权限-菜单管理
|
||||
*/
|
||||
import { useRouter } from 'vue-router';
|
||||
import { Message, TableData } from '@arco-design/web-vue';
|
||||
|
||||
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
|
||||
|
@ -331,8 +332,10 @@
|
|||
|
||||
import { MenuTableConfigItem, PoolOption, SelectValue } from '@/models/projectManagement/menuManagement';
|
||||
import { MenuEnum } from '@/enums/commonEnum';
|
||||
import { ProjectManagementRouteEnum } from '@/enums/routeEnum';
|
||||
|
||||
const appStore = useAppStore();
|
||||
const router = useRouter();
|
||||
const currentProjectId = computed(() => appStore.currentProjectId);
|
||||
const { t } = useI18n();
|
||||
const defectDrawerVisible = ref(false);
|
||||
|
@ -587,6 +590,10 @@
|
|||
const showDefectDrawer = () => {
|
||||
defectDrawerVisible.value = true;
|
||||
};
|
||||
// 跳转到误报规则列表页
|
||||
const pushFar = () => {
|
||||
router.push({ name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_MENU_MANAGEMENT_ERROR_REPORT_RULE });
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
setLoadListParams({ projectId: currentProjectId.value });
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
:rules="[{ required: true, message: t('system.organization.addMemberRequired') }]"
|
||||
>
|
||||
<MsUserSelector
|
||||
v-model:value="form.name"
|
||||
v-model="form.name"
|
||||
:type="UserRequestTypeEnum.PROJECT_USER_GROUP"
|
||||
:load-option-params="{ projectId: props.projectId, userRoleId: props.userRoleId }"
|
||||
disabled-key="checkRoleFlag"
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<!-- 编辑项目 -->
|
||||
<a-form-item v-if="type === 'edit'" :label="t('organization.member.project')" asterisk-position="end">
|
||||
<MsUserSelector
|
||||
v-model:value="form.projectIds"
|
||||
v-model="form.projectIds"
|
||||
:load-option-params="{ organizationId: lastOrganizationId }"
|
||||
:type="UserRequestTypeEnum.SYSTEM_ORGANIZATION_PROJECT"
|
||||
placeholder="organization.member.selectProjectScope"
|
||||
|
@ -35,7 +35,7 @@
|
|||
:rules="[{ required: true, message: t('organization.member.selectMemberEmptyTip') }]"
|
||||
>
|
||||
<MsUserSelector
|
||||
v-model:value="form.memberIds"
|
||||
v-model="form.memberIds"
|
||||
:load-option-params="{ organizationId: lastOrganizationId }"
|
||||
:type="UserRequestTypeEnum.SYSTEM_ORGANIZATION_MEMBER"
|
||||
placeholder="organization.member.selectMemberScope"
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
</a-form-item>
|
||||
<a-form-item field="userIds" :label="t('system.project.projectAdmin')">
|
||||
<MsUserSelector
|
||||
v-model:value="form.userIds"
|
||||
v-model="form.userIds"
|
||||
:type="UserRequestTypeEnum.ORGANIZATION_PROJECT_ADMIN"
|
||||
placeholder="system.project.projectAdminPlaceholder"
|
||||
:load-option-params="{
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
:rules="[{ required: true, message: t('system.organization.addMemberRequired') }]"
|
||||
>
|
||||
<MsUserSelector
|
||||
v-model:value="form.name"
|
||||
v-model="form.name"
|
||||
:type="UserRequestTypeEnum.ORGANIZATION_PROJECT"
|
||||
:load-option-params="{ organizationId: currentOrgId, projectId: props.projectId }"
|
||||
disabled-key="memberFlag"
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
</a-form-item>
|
||||
<a-form-item field="name" :label="t('system.organization.organizationAdmin')">
|
||||
<MsUserSelector
|
||||
v-model:value="form.memberIds"
|
||||
v-model="form.userIds"
|
||||
placeholder="system.organization.organizationAdminPlaceholder"
|
||||
:type="UserRequestTypeEnum.SYSTEM_ORGANIZATION_ADMIN"
|
||||
/>
|
||||
|
@ -78,9 +78,9 @@
|
|||
(e: 'submit'): void;
|
||||
}>();
|
||||
|
||||
const form = reactive<{ name: string; memberIds: string[]; description: string }>({
|
||||
const form = reactive<{ name: string; userIds: string[]; description: string }>({
|
||||
name: '',
|
||||
memberIds: [],
|
||||
userIds: [],
|
||||
description: '',
|
||||
});
|
||||
|
||||
|
@ -125,7 +125,7 @@
|
|||
watchEffect(() => {
|
||||
if (props.currentOrganization) {
|
||||
form.name = props.currentOrganization.name;
|
||||
form.memberIds = props.currentOrganization.memberIds;
|
||||
form.userIds = props.currentOrganization.userIds;
|
||||
form.description = props.currentOrganization.description;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
</a-form-item>
|
||||
<a-form-item field="userIds" :label="t('system.project.projectAdmin')">
|
||||
<MsUserSelector
|
||||
v-model:value="form.userIds"
|
||||
v-model="form.userIds"
|
||||
:type="UserRequestTypeEnum.SYSTEM_PROJECT_ADMIN"
|
||||
placeholder="system.project.projectAdminPlaceholder"
|
||||
/>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
:rules="[{ required: true, message: t('system.organization.addMemberRequired') }]"
|
||||
>
|
||||
<MsUserSelector
|
||||
v-model:value="form.name"
|
||||
v-model="form.name"
|
||||
:type="UserRequestTypeEnum.SYSTEM_ORGANIZATION"
|
||||
disabled-key="memberFlag"
|
||||
:load-option-params="{ sourceId: props.organizationId || props.projectId }"
|
||||
|
|
|
@ -250,7 +250,7 @@
|
|||
id: record.id,
|
||||
name: record.name,
|
||||
description: record.description,
|
||||
memberIds: record.orgAdmins.map((item: any) => item.id) || [],
|
||||
userIds: record.orgAdmins.map((item: any) => item.id) || [],
|
||||
};
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue