feat(项目管理): 菜单管理前端修改
This commit is contained in:
parent
26e0691216
commit
074effb40c
|
@ -5,3 +5,4 @@
|
||||||
|
|
||||||
**/*.svg
|
**/*.svg
|
||||||
**/*.sh
|
**/*.sh
|
||||||
|
src/auto-imports.js
|
|
@ -30,7 +30,7 @@ export function postUpdateMenu(data: MenuTableListParams) {
|
||||||
suffix = 'test-plan';
|
suffix = 'test-plan';
|
||||||
break;
|
break;
|
||||||
case MenuEnum.bugManagement:
|
case MenuEnum.bugManagement:
|
||||||
suffix = 'issue';
|
suffix = 'bug';
|
||||||
break;
|
break;
|
||||||
case MenuEnum.caseManagement:
|
case MenuEnum.caseManagement:
|
||||||
suffix = 'case';
|
suffix = 'case';
|
||||||
|
@ -58,7 +58,7 @@ export function getConfigByMenuItem(data: MenuTableListParams) {
|
||||||
suffix = 'test-plan';
|
suffix = 'test-plan';
|
||||||
break;
|
break;
|
||||||
case MenuEnum.bugManagement:
|
case MenuEnum.bugManagement:
|
||||||
suffix = 'issue';
|
suffix = 'bug';
|
||||||
break;
|
break;
|
||||||
case MenuEnum.caseManagement:
|
case MenuEnum.caseManagement:
|
||||||
suffix = 'case';
|
suffix = 'case';
|
||||||
|
|
|
@ -210,7 +210,7 @@
|
||||||
.arco-select-view-single,
|
.arco-select-view-single,
|
||||||
.arco-select {
|
.arco-select {
|
||||||
border: 1px solid var(--color-text-input-border);
|
border: 1px solid var(--color-text-input-border);
|
||||||
background-color: var(--color-text-fff) !important;
|
background-color: var(--color-text-fff);
|
||||||
&:not(:disabled):hover {
|
&:not(:disabled):hover {
|
||||||
border-color: rgb(var(--primary-5));
|
border-color: rgb(var(--primary-5));
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,6 +115,7 @@
|
||||||
],
|
],
|
||||||
onUpdate: () => {
|
onUpdate: () => {
|
||||||
content.value = `${editor.value?.getHTML()}`;
|
content.value = `${editor.value?.getHTML()}`;
|
||||||
|
console.log(content.value);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -408,6 +408,9 @@
|
||||||
initColumn();
|
initColumn();
|
||||||
batchLeft.value = getBatchLeft();
|
batchLeft.value = getBatchLeft();
|
||||||
});
|
});
|
||||||
|
defineExpose({
|
||||||
|
initColumn,
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|
|
@ -1,5 +1,121 @@
|
||||||
<template>
|
<template>
|
||||||
<a-input>
|
<div class="ms-time-selector">
|
||||||
<template #append> </template>
|
<a-input-number
|
||||||
</a-input>
|
v-model="current.value"
|
||||||
|
class="w-[120px]"
|
||||||
|
:min="0"
|
||||||
|
:max="current.max"
|
||||||
|
hide-button
|
||||||
|
size="small"
|
||||||
|
@blur="handleBlur"
|
||||||
|
>
|
||||||
|
<template #suffix>
|
||||||
|
<a-select v-model="current.type" size="small" class="max-w-[64px]" :options="option"> </a-select>
|
||||||
</template>
|
</template>
|
||||||
|
</a-input-number>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const props = defineProps<{ modelValue: string }>();
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'update:modelValue', value: string): void;
|
||||||
|
(e: 'change', value: string): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
function parseValue(v: string) {
|
||||||
|
// 使用正则表达式匹配输入字符串,提取类型和值
|
||||||
|
const match = v.match(/^(\d+)([MYHD])$/);
|
||||||
|
if (match) {
|
||||||
|
const value = parseInt(match[1], 10); // 提取值并将其转换为整数
|
||||||
|
const type = match[2]; // 提取类型
|
||||||
|
let max = 0;
|
||||||
|
// 根据类型设置最大值
|
||||||
|
switch (type) {
|
||||||
|
case 'H':
|
||||||
|
max = 24;
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
max = 12;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
max = Number.MAX_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { type, value, max };
|
||||||
|
}
|
||||||
|
// 如果输入字符串不匹配格式,可以抛出错误或返回一个默认值
|
||||||
|
return { type: 'H', value: undefined, max: Number.MAX_VALUE };
|
||||||
|
}
|
||||||
|
const current = reactive(parseValue(props.modelValue));
|
||||||
|
|
||||||
|
const handleBlur = () => {
|
||||||
|
const result = current.value ? `${current.value}${current.type}` : '';
|
||||||
|
emit('update:modelValue', current.value ? `${current.value}${current.type}` : '');
|
||||||
|
emit('change', result);
|
||||||
|
};
|
||||||
|
const option = computed(() => [
|
||||||
|
{
|
||||||
|
label: t('msTimeSelector.hour'),
|
||||||
|
value: 'H',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('msTimeSelector.day'),
|
||||||
|
value: 'D',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('msTimeSelector.month'),
|
||||||
|
value: 'M',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('msTimeSelector.year'),
|
||||||
|
value: 'Y',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.ms-time-selector {
|
||||||
|
display: inline;
|
||||||
|
:deep(.arco-input-wrapper) {
|
||||||
|
padding-right: 0;
|
||||||
|
:focus-within {
|
||||||
|
border-color: rgb(var(--primary-7));
|
||||||
|
border-top: none;
|
||||||
|
border-bottom: none;
|
||||||
|
border-left: none;
|
||||||
|
}
|
||||||
|
.arco-input.arco-input-size-small {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:deep(.arco-input-wrapper:not(:disabled):hover) {
|
||||||
|
border-color: rgb(var(--primary-7));
|
||||||
|
background-color: var(--color-text-n10);
|
||||||
|
}
|
||||||
|
:deep(.arco-select) {
|
||||||
|
border-top: 1px solid var(--color-text-n7);
|
||||||
|
border-right: 1px solid var(--color-text-n7);
|
||||||
|
border-bottom: 1px solid var(--color-text-n7);
|
||||||
|
border-radius: 0 4px 4px 0;
|
||||||
|
background: var(--color-text-n8);
|
||||||
|
}
|
||||||
|
:deep(.arco-select-focused) {
|
||||||
|
border-color: rgb(var(--primary-7));
|
||||||
|
}
|
||||||
|
:deep(.arco-select-view-single) {
|
||||||
|
padding: 5px 8px;
|
||||||
|
.arco-select-view-value {
|
||||||
|
padding-top: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
height: 22px;
|
||||||
|
min-height: 22px;
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -1 +1,6 @@
|
||||||
export default {};
|
export default {
|
||||||
|
'msTimeSelector.hour': 'Hour',
|
||||||
|
'msTimeSelector.day': 'Day',
|
||||||
|
'msTimeSelector.month': 'Month',
|
||||||
|
'msTimeSelector.year': 'Year',
|
||||||
|
};
|
||||||
|
|
|
@ -1 +1,6 @@
|
||||||
export default {};
|
export default {
|
||||||
|
'msTimeSelector.hour': '小时',
|
||||||
|
'msTimeSelector.day': '天',
|
||||||
|
'msTimeSelector.month': '月',
|
||||||
|
'msTimeSelector.year': '年',
|
||||||
|
};
|
||||||
|
|
|
@ -41,7 +41,7 @@ const ProjectManagement: AppRouteRecordRaw = {
|
||||||
{
|
{
|
||||||
path: 'menuManagement',
|
path: 'menuManagement',
|
||||||
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_PERMISSION_MENU_MANAGEMENT,
|
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_PERMISSION_MENU_MANAGEMENT,
|
||||||
component: () => import('@/views/project-management/projectAndPermission/menuManagement/index.vue'),
|
component: () => import('@/views/project-management/projectAndPermission/menuManagement/menuManagement.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
locale: 'project.permission.menuManagement',
|
locale: 'project.permission.menuManagement',
|
||||||
roles: ['*'],
|
roles: ['*'],
|
||||||
|
|
|
@ -12,7 +12,9 @@
|
||||||
@select="onSelect"
|
@select="onSelect"
|
||||||
@ok="onOk"
|
@ok="onOk"
|
||||||
/>
|
/>
|
||||||
<MsRichText v-model="content" />
|
<!-- <MsRichText v-model="content" /> -->
|
||||||
|
<MsTimeSelector v-model="timeValue" />
|
||||||
|
<div>value: {{ timeValue }}</div>
|
||||||
</MsCard>
|
</MsCard>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -20,6 +22,8 @@
|
||||||
import MsPagination from '@/components/pure/ms-pagination/index';
|
import MsPagination from '@/components/pure/ms-pagination/index';
|
||||||
import MsCard from '@/components/pure/ms-card/index.vue';
|
import MsCard from '@/components/pure/ms-card/index.vue';
|
||||||
import MsRichText from '@/components/pure/ms-rich-text/MsRichText.vue';
|
import MsRichText from '@/components/pure/ms-rich-text/MsRichText.vue';
|
||||||
|
import MsTimeSelector from '@/components/pure/ms-time-selector/MsTimeSelector.vue';
|
||||||
|
|
||||||
const content = ref('');
|
const content = ref('');
|
||||||
|
const timeValue = ref('3M');
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -23,9 +23,8 @@ export default {
|
||||||
'project.menu.API_SYNC_CASE': '变更同步CASE',
|
'project.menu.API_SYNC_CASE': '变更同步CASE',
|
||||||
|
|
||||||
'project.menu.CASE_PUBLIC': '公共用例库',
|
'project.menu.CASE_PUBLIC': '公共用例库',
|
||||||
'project.menu.CASE_RE_REVIEW': '关联需求',
|
'project.menu.CASE_RE_REVIEW': '重新提审',
|
||||||
'project.menu.CASE_RELATED': '重新提审',
|
'project.menu.CASE_ENABLE': '关联需求',
|
||||||
'project.menu.CASE_ENABLE': '接口测试待更新同步规则',
|
|
||||||
'project.menu.ISSUE_SYNC': '同步缺陷',
|
'project.menu.ISSUE_SYNC': '同步缺陷',
|
||||||
'project.menu.CRON_EXPRESSION': '同步频率',
|
'project.menu.CRON_EXPRESSION': '同步频率',
|
||||||
'project.menu.SYNC_ENABLE': '状态',
|
'project.menu.SYNC_ENABLE': '状态',
|
||||||
|
|
|
@ -32,11 +32,11 @@
|
||||||
</div>
|
</div>
|
||||||
<div v-if="record.type === 'TEST_PLAN_CLEAN_REPORT'">
|
<div v-if="record.type === 'TEST_PLAN_CLEAN_REPORT'">
|
||||||
<!-- 测试计划 报告保留时间范围 -->
|
<!-- 测试计划 报告保留时间范围 -->
|
||||||
<a-input v-model="record.typeValue" />
|
<MsTimeSelectorVue v-model="record.typeValue" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="record.type === 'TEST_PLAN_SHARE_REPORT'">
|
<div v-if="record.type === 'TEST_PLAN_SHARE_REPORT'">
|
||||||
<!-- 测试计划 报告链接有效期 -->
|
<!-- 测试计划 报告链接有效期 -->
|
||||||
<a-input v-model="record.typeValue" />
|
<MsTimeSelectorVue v-model="record.typeValue" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="record.type === 'ISSUE_SYNC'">
|
<div v-if="record.type === 'ISSUE_SYNC'">
|
||||||
<!-- 缺陷同步 -->
|
<!-- 缺陷同步 -->
|
||||||
|
@ -47,28 +47,28 @@
|
||||||
<!-- 用例 公共用例库 -->
|
<!-- 用例 公共用例库 -->
|
||||||
{{ t('project.menu.row3') }}
|
{{ t('project.menu.row3') }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="record.type === 'CASE_RE_REVIEW'" class="flex flex-row">
|
<div v-if="record.type === 'CASE_ENABLE'" class="flex flex-row">
|
||||||
<!-- 用例 关联需求 -->
|
<!-- 用例 关联需求 -->
|
||||||
<div>{{ t('project.menu.row4') }}</div>
|
<div>{{ t('project.menu.row4') }}</div>
|
||||||
<div class="ml-[8px] text-[rgb(var(--primary-7))]" @click="showDefectDrawer">{{ t('project.menu.rr') }}</div>
|
<div class="ml-[8px] text-[rgb(var(--primary-7))]" @click="showDefectDrawer">{{ t('project.menu.rr') }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="record.type === 'CASE_RELATED'">
|
<div v-if="record.type === 'CASE_RE_REVIEW'">
|
||||||
<!-- 用例 重新提审 -->
|
<!-- 用例 重新提审 -->
|
||||||
{{ t('project.menu.row5') }}
|
{{ t('project.menu.row5') }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="record.type === 'API_URL_REPEATABLE'">
|
<div v-if="record.type === 'API_URL_REPEATABLE'">
|
||||||
<!-- 接口 -->
|
<!-- 接口测试 接口定义URL可重复 -->
|
||||||
{{ t('project.menu.row6') }}
|
{{ t('project.menu.row6') }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="record.type === 'API_CLEAN_REPORT'">
|
<div v-if="record.type === 'API_CLEAN_REPORT'">
|
||||||
<a-input v-model="record.typeValue" />
|
<MsTimeSelectorVue v-model="record.typeValue" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="record.type === 'API_SHARE_REPORT'">
|
<div v-if="record.type === 'API_SHARE_REPORT'">
|
||||||
<!-- 报告链接有效期 -->
|
<!--接口测试 报告链接有效期 -->
|
||||||
<a-input v-model="record.typeValue" />
|
<MsTimeSelectorVue v-model="record.typeValue" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="record.type === 'API_RESOURCE_POOL'" class="flex flex-row items-center">
|
<div v-if="record.type === 'API_RESOURCE_POOL'" class="flex flex-row items-center">
|
||||||
<!-- 执行资源池 -->
|
<!--接口测试 执行资源池 -->
|
||||||
<a-select v-model="record.typeValue" />
|
<a-select v-model="record.typeValue" />
|
||||||
<a-tooltip :content="t('project.menu.manageTip')" position="bl">
|
<a-tooltip :content="t('project.menu.manageTip')" position="bl">
|
||||||
<div>
|
<div>
|
||||||
|
@ -77,7 +77,7 @@
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="record.type === 'API_SCRIPT_REVIEWER'" class="flex flex-row items-center">
|
<div v-if="record.type === 'API_SCRIPT_REVIEWER'" class="flex flex-row items-center">
|
||||||
<!-- 脚本审核 -->
|
<!--接口测试 脚本审核 -->
|
||||||
<a-select v-model="record.typeValue" />
|
<a-select v-model="record.typeValue" />
|
||||||
<a-tooltip :content="t('project.menu.manageTip')" position="bl">
|
<a-tooltip :content="t('project.menu.manageTip')" position="bl">
|
||||||
<div>
|
<div>
|
||||||
|
@ -86,8 +86,8 @@
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="record.type === 'API_ERROR_REPORT_RULE'" class="flex w-[100%] flex-row items-center">
|
<div v-if="record.type === 'API_ERROR_REPORT_RULE'" class="flex w-[100%] flex-row items-center">
|
||||||
<!-- 误报规则 -->
|
<!--接口测试 误报规则 -->
|
||||||
<a-select v-model="record.typeValue" class="w-[290px]" />
|
<a-select v-model="record.typeValue" class="w-[120px]" />
|
||||||
<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="showDefectDrawer">{{ t('project.menu.far') }}</div>
|
||||||
<a-tooltip :content="t('project.menu.manageTip')" position="bl">
|
<a-tooltip :content="t('project.menu.manageTip')" position="bl">
|
||||||
<div>
|
<div>
|
||||||
|
@ -98,15 +98,15 @@
|
||||||
<div v-if="record.type === 'API_SYNC_CASE'">{{ t('project.menu.row7') }} </div>
|
<div v-if="record.type === 'API_SYNC_CASE'">{{ t('project.menu.row7') }} </div>
|
||||||
<div v-if="record.type === 'UI_CLEAN_REPORT'">
|
<div v-if="record.type === 'UI_CLEAN_REPORT'">
|
||||||
<!--UI 报告保留时间范围 -->
|
<!--UI 报告保留时间范围 -->
|
||||||
<a-input v-model="record.typeValue" />
|
<MsTimeSelectorVue v-model="record.typeValue" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="record.type === 'UI_SHARE_REPORT'">
|
<div v-if="record.type === 'UI_SHARE_REPORT'">
|
||||||
<!--UI 报告链接有效期 -->
|
<!--UI 报告链接有效期 -->
|
||||||
<a-input v-model="record.typeValue" />
|
<MsTimeSelectorVue v-model="record.typeValue" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="record.type === 'UI_RESOURCE_POOL'" class="flex flex-row items-center">
|
<div v-if="record.type === 'UI_RESOURCE_POOL'" class="flex flex-row items-center">
|
||||||
<!--UI 执行资源池 -->
|
<!--UI 执行资源池 -->
|
||||||
<a-select v-model="record.typeValue" />
|
<a-select v-model="record.typeValue" class="w-[120px]" />
|
||||||
<a-tooltip :content="t('project.menu.manageTip')" position="bl">
|
<a-tooltip :content="t('project.menu.manageTip')" position="bl">
|
||||||
<div>
|
<div>
|
||||||
<MsIcon class="ml-[4px] text-[var(--color-text-4)]" type="icon-icon-maybe_outlined" />
|
<MsIcon class="ml-[4px] text-[var(--color-text-4)]" type="icon-icon-maybe_outlined" />
|
||||||
|
@ -115,15 +115,15 @@
|
||||||
</div>
|
</div>
|
||||||
<div v-if="record.type === 'PERFORMANCE_TEST_CLEAN_REPORT'">
|
<div v-if="record.type === 'PERFORMANCE_TEST_CLEAN_REPORT'">
|
||||||
<!--性能测试 报告保留时间范围 -->
|
<!--性能测试 报告保留时间范围 -->
|
||||||
<a-input v-model="record.typeValue" />
|
<MsTimeSelectorVue v-model="record.typeValue" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="record.type === 'PERFORMANCE_TEST_SHARE_REPORT'">
|
<div v-if="record.type === 'PERFORMANCE_TEST_SHARE_REPORT'">
|
||||||
<!--UI 报告链接有效期 -->
|
<!--UI 报告链接有效期 -->
|
||||||
<a-input v-model="record.typeValue" />
|
<MsTimeSelectorVue v-model="record.typeValue" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="record.type === 'PERFORMANCE_TEST_SCRIPT_REVIEWER'" class="flex flex-row items-center">
|
<div v-if="record.type === 'PERFORMANCE_TEST_SCRIPT_REVIEWER'" class="flex flex-row items-center">
|
||||||
<!--UI 脚本审核 -->
|
<!--UI 脚本审核 -->
|
||||||
<a-select v-model="record.typeValue" />
|
<a-select v-model="record.typeValue" class="w-[120px]" />
|
||||||
<a-tooltip :content="t('project.menu.manageTip')" position="bl">
|
<a-tooltip :content="t('project.menu.manageTip')" position="bl">
|
||||||
<div>
|
<div>
|
||||||
<MsIcon class="ml-[4px] text-[var(--color-text-4)]" type="icon-icon-maybe_outlined" />
|
<MsIcon class="ml-[4px] text-[var(--color-text-4)]" type="icon-icon-maybe_outlined" />
|
||||||
|
@ -134,14 +134,13 @@
|
||||||
</MsBaseTable>
|
</MsBaseTable>
|
||||||
<MsDrawer
|
<MsDrawer
|
||||||
v-model:visible="defectDrawerVisible"
|
v-model:visible="defectDrawerVisible"
|
||||||
title="缺陷同步"
|
:title="t('project.menu.ISSUE_SYNC')"
|
||||||
:width="600"
|
|
||||||
:destroy-on-close="true"
|
:destroy-on-close="true"
|
||||||
:closable="true"
|
:closable="true"
|
||||||
:mask-closable="false"
|
:mask-closable="false"
|
||||||
:footer="null"
|
|
||||||
:get-container="false"
|
:get-container="false"
|
||||||
:body-style="{ padding: '0px' }"
|
:body-style="{ padding: '0px' }"
|
||||||
|
:width="400"
|
||||||
>
|
>
|
||||||
<DefectSync />
|
<DefectSync />
|
||||||
</MsDrawer>
|
</MsDrawer>
|
||||||
|
@ -161,6 +160,9 @@
|
||||||
import { MenuTableListItem } from '@/models/projectManagement/menuManagement';
|
import { MenuTableListItem } from '@/models/projectManagement/menuManagement';
|
||||||
import { MenuEnum } from '@/enums/commonEnum';
|
import { MenuEnum } from '@/enums/commonEnum';
|
||||||
import { Message, TableData } from '@arco-design/web-vue';
|
import { Message, TableData } from '@arco-design/web-vue';
|
||||||
|
import MsTimeSelectorVue from '@/components/pure/ms-time-selector/MsTimeSelector.vue';
|
||||||
|
import MsDrawer from '@/components/pure/ms-drawer/index.vue';
|
||||||
|
import DefectSync from './components/defectSync.vue';
|
||||||
|
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
const currentProjectId = computed(() => appStore.currentProjectId);
|
const currentProjectId = computed(() => appStore.currentProjectId);
|
Loading…
Reference in New Issue