refactor(缺陷管理): 缺陷管理创建缺陷创建组件抽离&重构
This commit is contained in:
parent
00f4cf449c
commit
01a912b399
|
@ -32,7 +32,7 @@ const BugManagement: AppRouteRecordRaw = {
|
||||||
{
|
{
|
||||||
path: 'detail/:mode?',
|
path: 'detail/:mode?',
|
||||||
name: BugManagementRouteEnum.BUG_MANAGEMENT_DETAIL,
|
name: BugManagementRouteEnum.BUG_MANAGEMENT_DETAIL,
|
||||||
component: () => import('@/views/bug-management/edit.vue'),
|
component: () => import('@/views/bug-management/createAndEditBug.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
locale: 'bugManagement.editBug',
|
locale: 'bugManagement.editBug',
|
||||||
roles: ['PROJECT_BUG:READ+ADD', 'PROJECT_BUG:READ+UPDATE'],
|
roles: ['PROJECT_BUG:READ+ADD', 'PROJECT_BUG:READ+UPDATE'],
|
||||||
|
|
|
@ -0,0 +1,156 @@
|
||||||
|
<template>
|
||||||
|
<MsCard
|
||||||
|
has-breadcrumb
|
||||||
|
:title="title"
|
||||||
|
:loading="loading"
|
||||||
|
:is-edit="isEdit"
|
||||||
|
@save="saveHandler(false)"
|
||||||
|
@save-and-continue="saveHandler(true)"
|
||||||
|
>
|
||||||
|
<template v-if="!isEdit" #headerRight>
|
||||||
|
<a-select
|
||||||
|
v-model="bugTemplateId"
|
||||||
|
class="w-[240px]"
|
||||||
|
:options="templateOption"
|
||||||
|
allow-search
|
||||||
|
:placeholder="t('bugManagement.edit.defaultSystemTemplate')"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<BugDetail ref="bugDetailRef" v-model:template-id="bugTemplateId" :bug-id="bugId" @save-params="saveParams" />
|
||||||
|
</MsCard>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
import { Message } from '@arco-design/web-vue';
|
||||||
|
|
||||||
|
import MsCard from '@/components/pure/ms-card/index.vue';
|
||||||
|
import BugDetail from './edit.vue';
|
||||||
|
|
||||||
|
import { createOrUpdateBug, getTemplateOption } from '@/api/modules/bug-management';
|
||||||
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
import useLeaveUnSaveTip from '@/hooks/useLeaveUnSaveTip';
|
||||||
|
import useVisit from '@/hooks/useVisit';
|
||||||
|
import router from '@/router';
|
||||||
|
import { useAppStore } from '@/store';
|
||||||
|
|
||||||
|
import { BugEditFormObject } from '@/models/bug-management';
|
||||||
|
import { BugManagementRouteEnum } from '@/enums/routeEnum';
|
||||||
|
|
||||||
|
defineOptions({ name: 'BugEditPage' });
|
||||||
|
const { setIsSave } = useLeaveUnSaveTip();
|
||||||
|
setIsSave(false);
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
interface TemplateOption {
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const appStore = useAppStore();
|
||||||
|
const route = useRoute();
|
||||||
|
const templateOption = ref<TemplateOption[]>([]);
|
||||||
|
const bugTemplateId = ref<string>('');
|
||||||
|
const loading = ref(false);
|
||||||
|
const isEdit = computed(() => !!route.query.id && route.params.mode === 'edit');
|
||||||
|
const bugId = computed(() => route.query.id as string | undefined);
|
||||||
|
|
||||||
|
const isCopy = computed(() => route.params.mode === 'copy');
|
||||||
|
|
||||||
|
const visitedKey = 'doNotNextTipCreateBug';
|
||||||
|
|
||||||
|
const { getIsVisited } = useVisit(visitedKey);
|
||||||
|
|
||||||
|
const title = computed(() => {
|
||||||
|
if (isCopy.value) {
|
||||||
|
return t('bugManagement.copyBug');
|
||||||
|
}
|
||||||
|
return isEdit.value ? t('bugManagement.editBug') : t('bugManagement.createBug');
|
||||||
|
});
|
||||||
|
|
||||||
|
const getTemplateOptions = async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const res = await getTemplateOption(appStore.currentProjectId);
|
||||||
|
templateOption.value = res.map((item) => {
|
||||||
|
if (item.enableDefault && !isEdit.value) {
|
||||||
|
// 选中默认模板
|
||||||
|
bugTemplateId.value = item.id;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const bugDetailRef = ref<InstanceType<typeof BugDetail>>();
|
||||||
|
|
||||||
|
async function saveParams(isContinue: boolean, params: { request: BugEditFormObject; fileList: File[] }) {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const res = await createOrUpdateBug(params);
|
||||||
|
if (isEdit.value) {
|
||||||
|
setIsSave(true);
|
||||||
|
Message.success(t('common.updateSuccess'));
|
||||||
|
router.push({
|
||||||
|
name: BugManagementRouteEnum.BUG_MANAGEMENT_INDEX,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Message.success(t('common.createSuccess'));
|
||||||
|
if (isContinue) {
|
||||||
|
setIsSave(false);
|
||||||
|
bugDetailRef.value?.resetForm();
|
||||||
|
} else {
|
||||||
|
setIsSave(true);
|
||||||
|
// 跳转到成功页
|
||||||
|
if (getIsVisited()) {
|
||||||
|
router.push({
|
||||||
|
name: BugManagementRouteEnum.BUG_MANAGEMENT_INDEX,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
router.push({
|
||||||
|
name: BugManagementRouteEnum.BUG_MANAGEMENT_CREATE_SUCCESS,
|
||||||
|
query: {
|
||||||
|
...route.query,
|
||||||
|
id: res.data.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const saveHandler = async (isContinue = false) => {
|
||||||
|
bugDetailRef.value?.saveHandler(isContinue);
|
||||||
|
};
|
||||||
|
|
||||||
|
const initDefaultFields = async () => {
|
||||||
|
await getTemplateOptions();
|
||||||
|
};
|
||||||
|
|
||||||
|
onBeforeMount(() => {
|
||||||
|
initDefaultFields();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
:deep(.arco-form-item-extra) {
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--color-text-4);
|
||||||
|
}
|
||||||
|
:deep(.arco-form-item-content) {
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,185 +1,161 @@
|
||||||
<template>
|
<template>
|
||||||
<MsCard
|
<a-form ref="formRef" :model="form" layout="vertical">
|
||||||
has-breadcrumb
|
<div class="flex flex-row">
|
||||||
:title="title"
|
<div class="left mt-[16px] w-[calc(100%-428px)] grow">
|
||||||
:loading="loading"
|
<!-- 平台默认模板不展示缺陷名称, 描述 -->
|
||||||
:is-edit="isEdit"
|
<a-form-item
|
||||||
@save="saveHandler(false)"
|
v-if="!isPlatformDefaultTemplate"
|
||||||
@save-and-continue="saveHandler(true)"
|
field="title"
|
||||||
>
|
:label="t('bugManagement.bugName')"
|
||||||
<template v-if="!isEdit" #headerRight>
|
:rules="[{ required: true, message: t('bugManagement.edit.nameIsRequired') }]"
|
||||||
<a-select
|
>
|
||||||
v-model="form.templateId"
|
<a-input v-model="form.title" :placeholder="t('bugManagement.edit.pleaseInputBugName')" :max-length="255" />
|
||||||
class="w-[240px]"
|
</a-form-item>
|
||||||
:options="templateOption"
|
<a-form-item v-if="!isPlatformDefaultTemplate" field="description" :label="t('bugManagement.edit.content')">
|
||||||
allow-search
|
<MsRichText
|
||||||
:placeholder="t('bugManagement.edit.defaultSystemTemplate')"
|
v-model:raw="form.description"
|
||||||
@change="templateChange"
|
v-model:filed-ids="descriptionFileIds"
|
||||||
/>
|
:upload-image="handleUploadImage"
|
||||||
</template>
|
:preview-url="`${EditorPreviewFileUrl}/${appStore.currentProjectId}`"
|
||||||
<a-form ref="formRef" :model="form" layout="vertical">
|
/>
|
||||||
<div class="flex flex-row">
|
</a-form-item>
|
||||||
<div class="left mt-[16px] w-[calc(100%-428px)] grow">
|
<!-- 平台默认模板展示字段, 暂时支持输入框, 富文本类型 -->
|
||||||
<!-- 平台默认模板不展示缺陷名称, 描述 -->
|
<div v-if="isPlatformDefaultTemplate">
|
||||||
<a-form-item
|
<a-form-item
|
||||||
v-if="!isPlatformDefaultTemplate"
|
v-for="(value, key) in form.platformSystemFields"
|
||||||
field="title"
|
:key="key"
|
||||||
:label="t('bugManagement.bugName')"
|
:field="'platformSystemFields.' + key"
|
||||||
:rules="[{ required: true, message: t('bugManagement.edit.nameIsRequired') }]"
|
:label="platformSystemFieldMap[key].fieldName"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: platformSystemFieldMap[key].required,
|
||||||
|
message: `${platformSystemFieldMap[key].fieldName}` + t('bugManagement.edit.cannotBeNull'),
|
||||||
|
},
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<a-input v-model="form.title" :placeholder="t('bugManagement.edit.pleaseInputBugName')" :max-length="255" />
|
<a-input
|
||||||
</a-form-item>
|
v-if="platformSystemFieldMap[key].type === 'INPUT'"
|
||||||
<a-form-item v-if="!isPlatformDefaultTemplate" field="description" :label="t('bugManagement.edit.content')">
|
v-model="form.platformSystemFields[key]"
|
||||||
|
:max-length="255"
|
||||||
|
/>
|
||||||
<MsRichText
|
<MsRichText
|
||||||
v-model:raw="form.description"
|
v-if="platformSystemFieldMap[key].type === 'RICH_TEXT'"
|
||||||
v-model:filed-ids="descriptionFileIds"
|
v-model:raw="form.platformSystemFields[key]"
|
||||||
|
v-model:filed-ids="descriptionFileIdMap[key]"
|
||||||
:upload-image="handleUploadImage"
|
:upload-image="handleUploadImage"
|
||||||
:preview-url="`${EditorPreviewFileUrl}/${appStore.currentProjectId}`"
|
:preview-url="`${EditorPreviewFileUrl}/${appStore.currentProjectId}`"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<!-- 平台默认模板展示字段, 暂时支持输入框, 富文本类型 -->
|
</div>
|
||||||
<div v-if="isPlatformDefaultTemplate">
|
<a-form-item field="attachment">
|
||||||
<a-form-item
|
<div class="flex flex-col">
|
||||||
v-for="(value, key) in form.platformSystemFields"
|
<div class="mb-1">
|
||||||
:key="key"
|
<AddAttachment v-model:file-list="fileList" @change="handleChange" @link-file="associatedFile" />
|
||||||
:field="'platformSystemFields.' + key"
|
</div>
|
||||||
:label="platformSystemFieldMap[key].fieldName"
|
</div>
|
||||||
:rules="[
|
</a-form-item>
|
||||||
{
|
<MsFileList
|
||||||
required: platformSystemFieldMap[key].required,
|
ref="fileListRef"
|
||||||
message: `${platformSystemFieldMap[key].fieldName}` + t('bugManagement.edit.cannotBeNull'),
|
v-model:file-list="fileList"
|
||||||
},
|
:init-file-save-tips="t('ms.upload.waiting_save')"
|
||||||
]"
|
mode="static"
|
||||||
>
|
>
|
||||||
<a-input
|
<template #actions="{ item }">
|
||||||
v-if="platformSystemFieldMap[key].type === 'INPUT'"
|
<!-- 本地文件 -->
|
||||||
v-model="form.platformSystemFields[key]"
|
<div v-if="item.local || item.status === 'init'" class="flex flex-nowrap">
|
||||||
:max-length="255"
|
<MsButton
|
||||||
|
v-if="item.status !== 'init' && item.file.type.includes('image')"
|
||||||
|
type="button"
|
||||||
|
status="primary"
|
||||||
|
class="!mr-[4px]"
|
||||||
|
@click="handlePreview(item)"
|
||||||
|
>
|
||||||
|
{{ t('ms.upload.preview') }}
|
||||||
|
</MsButton>
|
||||||
|
<MsButton
|
||||||
|
v-if="item.status !== 'init'"
|
||||||
|
type="button"
|
||||||
|
status="primary"
|
||||||
|
class="!mr-[4px]"
|
||||||
|
@click="transferFile(item)"
|
||||||
|
>
|
||||||
|
{{ t('caseManagement.featureCase.storage') }}
|
||||||
|
</MsButton>
|
||||||
|
<SaveAsFilePopover
|
||||||
|
v-model:visible="transferVisible"
|
||||||
|
:saving-file="activeTransferFileParams"
|
||||||
|
:file-save-as-source-id="(form.id as string)"
|
||||||
|
:file-save-as-api="transferFileRequest"
|
||||||
|
:file-module-options-api="getTransferFileTree"
|
||||||
|
source-id-key="bugId"
|
||||||
|
@finish="getDetailInfo()"
|
||||||
/>
|
/>
|
||||||
<MsRichText
|
<MsButton
|
||||||
v-if="platformSystemFieldMap[key].type === 'RICH_TEXT'"
|
v-if="item.status !== 'init'"
|
||||||
v-model:raw="form.platformSystemFields[key]"
|
type="button"
|
||||||
v-model:filed-ids="descriptionFileIdMap[key]"
|
status="primary"
|
||||||
:upload-image="handleUploadImage"
|
class="!mr-[4px]"
|
||||||
:preview-url="`${EditorPreviewFileUrl}/${appStore.currentProjectId}`"
|
@click="downloadFile(item)"
|
||||||
|
>
|
||||||
|
{{ t('common.download') }}
|
||||||
|
</MsButton>
|
||||||
|
</div>
|
||||||
|
<!-- 关联文件 -->
|
||||||
|
<div v-else class="flex flex-nowrap">
|
||||||
|
<MsButton
|
||||||
|
v-if="item.status !== 'init' && item.file.type.includes('image')"
|
||||||
|
type="button"
|
||||||
|
status="primary"
|
||||||
|
class="!mr-[4px]"
|
||||||
|
@click="handlePreview(item)"
|
||||||
|
>
|
||||||
|
{{ t('ms.upload.preview') }}
|
||||||
|
</MsButton>
|
||||||
|
<MsButton v-if="bugId" type="button" status="primary" class="!mr-[4px]" @click="downloadFile(item)">
|
||||||
|
{{ t('common.download') }}
|
||||||
|
</MsButton>
|
||||||
|
<MsButton
|
||||||
|
v-if="bugId && item.isUpdateFlag"
|
||||||
|
type="button"
|
||||||
|
status="primary"
|
||||||
|
@click="handleUpdateFile(item)"
|
||||||
|
>
|
||||||
|
{{ t('common.update') }}
|
||||||
|
</MsButton>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #title="{ item }">
|
||||||
|
<span v-if="item.isUpdateFlag" class="ml-4 flex items-center font-normal text-[rgb(var(--warning-6))]"
|
||||||
|
><icon-exclamation-circle-fill /> <span>{{ t('caseManagement.featureCase.fileIsUpdated') }}</span>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</MsFileList>
|
||||||
|
</div>
|
||||||
|
<a-divider class="ml-[16px]" direction="vertical" />
|
||||||
|
<div class="right mt-[16px] w-[428px] grow pr-[24px]">
|
||||||
|
<div class="min-w-[250px] overflow-auto">
|
||||||
|
<a-skeleton v-if="isLoading" :loading="isLoading" :animation="true">
|
||||||
|
<a-space direction="vertical" class="w-full" size="large">
|
||||||
|
<a-skeleton-line :rows="12" :line-height="30" :line-spacing="30" />
|
||||||
|
</a-space>
|
||||||
|
</a-skeleton>
|
||||||
|
<a-form v-else :model="form" layout="vertical">
|
||||||
|
<div style="display: inline-block; width: 100%; word-wrap: break-word">
|
||||||
|
<MsFormCreate ref="formCreateRef" v-model:formItem="formItem" v-model:api="fApi" :form-rule="formRules" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a-form-item v-if="!isPlatformDefaultTemplate" field="tag" :label="t('bugManagement.tag')">
|
||||||
|
<MsTagsInput
|
||||||
|
v-model:model-value="form.tags"
|
||||||
|
:placeholder="t('bugManagement.edit.tagPlaceholder')"
|
||||||
|
allow-clear
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</div>
|
</a-form>
|
||||||
<a-form-item field="attachment">
|
|
||||||
<div class="flex flex-col">
|
|
||||||
<div class="mb-1">
|
|
||||||
<AddAttachment v-model:file-list="fileList" @change="handleChange" @link-file="associatedFile" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a-form-item>
|
|
||||||
<MsFileList
|
|
||||||
ref="fileListRef"
|
|
||||||
v-model:file-list="fileList"
|
|
||||||
:init-file-save-tips="t('ms.upload.waiting_save')"
|
|
||||||
mode="static"
|
|
||||||
>
|
|
||||||
<template #actions="{ item }">
|
|
||||||
<!-- 本地文件 -->
|
|
||||||
<div v-if="item.local || item.status === 'init'" class="flex flex-nowrap">
|
|
||||||
<MsButton
|
|
||||||
v-if="item.status !== 'init' && item.file.type.includes('image')"
|
|
||||||
type="button"
|
|
||||||
status="primary"
|
|
||||||
class="!mr-[4px]"
|
|
||||||
@click="handlePreview(item)"
|
|
||||||
>
|
|
||||||
{{ t('ms.upload.preview') }}
|
|
||||||
</MsButton>
|
|
||||||
<MsButton
|
|
||||||
v-if="item.status !== 'init'"
|
|
||||||
type="button"
|
|
||||||
status="primary"
|
|
||||||
class="!mr-[4px]"
|
|
||||||
@click="transferFile(item)"
|
|
||||||
>
|
|
||||||
{{ t('caseManagement.featureCase.storage') }}
|
|
||||||
</MsButton>
|
|
||||||
<SaveAsFilePopover
|
|
||||||
v-model:visible="transferVisible"
|
|
||||||
:saving-file="activeTransferFileParams"
|
|
||||||
:file-save-as-source-id="(form.id as string)"
|
|
||||||
:file-save-as-api="transferFileRequest"
|
|
||||||
:file-module-options-api="getTransferFileTree"
|
|
||||||
source-id-key="bugId"
|
|
||||||
@finish="getDetailInfo()"
|
|
||||||
/>
|
|
||||||
<MsButton
|
|
||||||
v-if="item.status !== 'init'"
|
|
||||||
type="button"
|
|
||||||
status="primary"
|
|
||||||
class="!mr-[4px]"
|
|
||||||
@click="downloadFile(item)"
|
|
||||||
>
|
|
||||||
{{ t('common.download') }}
|
|
||||||
</MsButton>
|
|
||||||
</div>
|
|
||||||
<!-- 关联文件 -->
|
|
||||||
<div v-else class="flex flex-nowrap">
|
|
||||||
<MsButton
|
|
||||||
v-if="item.status !== 'init' && item.file.type.includes('image')"
|
|
||||||
type="button"
|
|
||||||
status="primary"
|
|
||||||
class="!mr-[4px]"
|
|
||||||
@click="handlePreview(item)"
|
|
||||||
>
|
|
||||||
{{ t('ms.upload.preview') }}
|
|
||||||
</MsButton>
|
|
||||||
<MsButton v-if="bugId" type="button" status="primary" class="!mr-[4px]" @click="downloadFile(item)">
|
|
||||||
{{ t('common.download') }}
|
|
||||||
</MsButton>
|
|
||||||
<MsButton
|
|
||||||
v-if="bugId && item.isUpdateFlag"
|
|
||||||
type="button"
|
|
||||||
status="primary"
|
|
||||||
@click="handleUpdateFile(item)"
|
|
||||||
>
|
|
||||||
{{ t('common.update') }}
|
|
||||||
</MsButton>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template #title="{ item }">
|
|
||||||
<span v-if="item.isUpdateFlag" class="ml-4 flex items-center font-normal text-[rgb(var(--warning-6))]"
|
|
||||||
><icon-exclamation-circle-fill /> <span>{{ t('caseManagement.featureCase.fileIsUpdated') }}</span>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</MsFileList>
|
|
||||||
</div>
|
|
||||||
<a-divider class="ml-[16px]" direction="vertical" />
|
|
||||||
<div class="right mt-[16px] w-[428px] grow pr-[24px]">
|
|
||||||
<div class="min-w-[250px] overflow-auto">
|
|
||||||
<a-skeleton v-if="isLoading" :loading="isLoading" :animation="true">
|
|
||||||
<a-space direction="vertical" class="w-full" size="large">
|
|
||||||
<a-skeleton-line :rows="12" :line-height="30" :line-spacing="30" />
|
|
||||||
</a-space>
|
|
||||||
</a-skeleton>
|
|
||||||
<a-form v-else :model="form" layout="vertical">
|
|
||||||
<div style="display: inline-block; width: 100%; word-wrap: break-word">
|
|
||||||
<MsFormCreate
|
|
||||||
ref="formCreateRef"
|
|
||||||
v-model:formItem="formItem"
|
|
||||||
v-model:api="fApi"
|
|
||||||
:form-rule="formRules"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<a-form-item v-if="!isPlatformDefaultTemplate" field="tag" :label="t('bugManagement.tag')">
|
|
||||||
<MsTagsInput
|
|
||||||
v-model:model-value="form.tags"
|
|
||||||
:placeholder="t('bugManagement.edit.tagPlaceholder')"
|
|
||||||
allow-clear
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-form>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a-form>
|
</div>
|
||||||
</MsCard>
|
</a-form>
|
||||||
<div>
|
<div>
|
||||||
<MsUpload
|
<MsUpload
|
||||||
v-model:file-list="fileList"
|
v-model:file-list="fileList"
|
||||||
|
@ -211,7 +187,6 @@
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
|
|
||||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||||
import MsCard from '@/components/pure/ms-card/index.vue';
|
|
||||||
import MsFormCreate from '@/components/pure/ms-form-create/ms-form-create.vue';
|
import MsFormCreate from '@/components/pure/ms-form-create/ms-form-create.vue';
|
||||||
import { FormItem, FormRuleItem } from '@/components/pure/ms-form-create/types';
|
import { FormItem, FormRuleItem } from '@/components/pure/ms-form-create/types';
|
||||||
import MsRichText from '@/components/pure/ms-rich-text/MsRichText.vue';
|
import MsRichText from '@/components/pure/ms-rich-text/MsRichText.vue';
|
||||||
|
@ -225,13 +200,11 @@
|
||||||
|
|
||||||
import {
|
import {
|
||||||
checkFileIsUpdateRequest,
|
checkFileIsUpdateRequest,
|
||||||
createOrUpdateBug,
|
|
||||||
downloadFileRequest,
|
downloadFileRequest,
|
||||||
editorUploadFile,
|
editorUploadFile,
|
||||||
getAssociatedFileList,
|
getAssociatedFileList,
|
||||||
getBugDetail,
|
getBugDetail,
|
||||||
getTemplateById,
|
getTemplateById,
|
||||||
getTemplateOption,
|
|
||||||
previewFile,
|
previewFile,
|
||||||
transferFileRequest,
|
transferFileRequest,
|
||||||
updateFile,
|
updateFile,
|
||||||
|
@ -240,9 +213,6 @@
|
||||||
import { getModules, getModulesCount } from '@/api/modules/project-management/fileManagement';
|
import { getModules, getModulesCount } from '@/api/modules/project-management/fileManagement';
|
||||||
import { EditorPreviewFileUrl } from '@/api/requrls/bug-management';
|
import { EditorPreviewFileUrl } from '@/api/requrls/bug-management';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import useLeaveUnSaveTip from '@/hooks/useLeaveUnSaveTip';
|
|
||||||
import useVisit from '@/hooks/useVisit';
|
|
||||||
import router from '@/router';
|
|
||||||
import { useAppStore } from '@/store';
|
import { useAppStore } from '@/store';
|
||||||
import useUserStore from '@/store/modules/user';
|
import useUserStore from '@/store/modules/user';
|
||||||
import { downloadByteFile } from '@/utils';
|
import { downloadByteFile } from '@/utils';
|
||||||
|
@ -260,24 +230,29 @@
|
||||||
import { TableQueryParams } from '@/models/common';
|
import { TableQueryParams } from '@/models/common';
|
||||||
import { SelectValue } from '@/models/projectManagement/menuManagement';
|
import { SelectValue } from '@/models/projectManagement/menuManagement';
|
||||||
import type { CustomField } from '@/models/setting/template';
|
import type { CustomField } from '@/models/setting/template';
|
||||||
import { BugManagementRouteEnum } from '@/enums/routeEnum';
|
|
||||||
|
|
||||||
import { convertToFile } from '../case-management/caseManagementFeature/components/utils';
|
import { convertToFile } from '../case-management/caseManagementFeature/components/utils';
|
||||||
import { convertToFileByBug } from './utils';
|
import { convertToFileByBug } from './utils';
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
bugId?: string;
|
||||||
|
templateId: string;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'saveParams', isContinue: boolean, params: { request: BugEditFormObject; fileList: File[] }): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const innerTemplateId = defineModel<string>('templateId', {
|
||||||
|
required: true,
|
||||||
|
});
|
||||||
|
|
||||||
defineOptions({ name: 'BugEditPage' });
|
defineOptions({ name: 'BugEditPage' });
|
||||||
const { setIsSave } = useLeaveUnSaveTip();
|
|
||||||
setIsSave(false);
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
interface TemplateOption {
|
|
||||||
label: string;
|
|
||||||
value: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const templateOption = ref<TemplateOption[]>([]);
|
|
||||||
const form = ref<BugEditFormObject>({
|
const form = ref<BugEditFormObject>({
|
||||||
projectId: appStore.currentProjectId,
|
projectId: appStore.currentProjectId,
|
||||||
title: '',
|
title: '',
|
||||||
|
@ -314,7 +289,7 @@
|
||||||
const acceptType = ref('none'); // 模块-上传文件类型
|
const acceptType = ref('none'); // 模块-上传文件类型
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const isEdit = computed(() => !!route.query.id && route.params.mode === 'edit');
|
const isEdit = computed(() => !!route.query.id && route.params.mode === 'edit');
|
||||||
const bugId = computed(() => route.query.id || '');
|
const bugId = ref<string | undefined>(props.bugId);
|
||||||
const isEditOrCopy = computed(() => !!bugId.value);
|
const isEditOrCopy = computed(() => !!bugId.value);
|
||||||
const isCopy = computed(() => route.params.mode === 'copy');
|
const isCopy = computed(() => route.params.mode === 'copy');
|
||||||
const isPlatformDefaultTemplate = ref(false);
|
const isPlatformDefaultTemplate = ref(false);
|
||||||
|
@ -324,15 +299,7 @@
|
||||||
const descriptionFileIds = ref<string[]>([]);
|
const descriptionFileIds = ref<string[]>([]);
|
||||||
// 描述-环境/富文本临时附件ID
|
// 描述-环境/富文本临时附件ID
|
||||||
const descriptionFileIdMap = ref<Record<string, string[]>>({});
|
const descriptionFileIdMap = ref<Record<string, string[]>>({});
|
||||||
const visitedKey = 'doNotNextTipCreateBug';
|
|
||||||
const { getIsVisited } = useVisit(visitedKey);
|
|
||||||
|
|
||||||
const title = computed(() => {
|
|
||||||
if (isCopy.value) {
|
|
||||||
return t('bugManagement.copyBug');
|
|
||||||
}
|
|
||||||
return isEdit.value ? t('bugManagement.editBug') : t('bugManagement.createBug');
|
|
||||||
});
|
|
||||||
const isLoading = ref<boolean>(true);
|
const isLoading = ref<boolean>(true);
|
||||||
const rowLength = ref<number>(0);
|
const rowLength = ref<number>(0);
|
||||||
|
|
||||||
|
@ -462,29 +429,6 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getTemplateOptions = async () => {
|
|
||||||
try {
|
|
||||||
loading.value = true;
|
|
||||||
const res = await getTemplateOption(appStore.currentProjectId);
|
|
||||||
templateOption.value = res.map((item) => {
|
|
||||||
if (item.enableDefault && !isEdit.value) {
|
|
||||||
// 当创建时 选中默认模板
|
|
||||||
form.value.templateId = item.id;
|
|
||||||
templateChange(item.id);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
label: item.name,
|
|
||||||
value: item.id,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(error);
|
|
||||||
} finally {
|
|
||||||
loading.value = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 预览图片
|
// 预览图片
|
||||||
async function handlePreview(item: MsFileItem) {
|
async function handlePreview(item: MsFileItem) {
|
||||||
try {
|
try {
|
||||||
|
@ -568,120 +512,94 @@
|
||||||
return fileIds;
|
return fileIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function makeParams() {
|
||||||
|
// 自定义字段参数
|
||||||
|
const customFields: BugEditCustomFieldItem[] = [];
|
||||||
|
if (formItem.value && formItem.value.length) {
|
||||||
|
formItem.value.forEach((item: FormRuleItem) => {
|
||||||
|
if (item.sourceType === 'CASCADER') {
|
||||||
|
item.value = findParents(item.options as Option[], item.value as string, []) || '';
|
||||||
|
}
|
||||||
|
customFields.push({
|
||||||
|
id: item.field as string,
|
||||||
|
name: item.title as string,
|
||||||
|
type: item.sourceType as string,
|
||||||
|
value: Array.isArray(item.value) ? JSON.stringify(item.value) : (item.value as string),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (isPlatformDefaultTemplate.value && form.value.platformSystemFields) {
|
||||||
|
Object.keys(form.value.platformSystemFields).forEach((key) => {
|
||||||
|
customFields.push({
|
||||||
|
id: platformSystemFieldMap[key].fieldId,
|
||||||
|
name: platformSystemFieldMap[key].fieldName,
|
||||||
|
type: platformSystemFieldMap[key].type,
|
||||||
|
value: form.value.platformSystemFields[key],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// delete form.value.platformSystemFields;
|
||||||
|
// 平台默认模板不传递名称, 描述, 标签等参数
|
||||||
|
delete form.value.title;
|
||||||
|
delete form.value.description;
|
||||||
|
delete form.value.tags;
|
||||||
|
}
|
||||||
|
// 过滤出复制的附件
|
||||||
|
const copyFileList = fileList.value.filter((item) => item.isCopyFlag);
|
||||||
|
let copyFiles: { refId: string; fileId: string; local: boolean }[] = [];
|
||||||
|
if (copyFileList.length > 0) {
|
||||||
|
copyFiles = copyFileList.map((file) => {
|
||||||
|
return {
|
||||||
|
refId: file.associateId,
|
||||||
|
fileId: file.uid,
|
||||||
|
local: file.local,
|
||||||
|
bugId: bugId.value as string,
|
||||||
|
fileName: file.name,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const tmpObj: BugEditFormObject = {
|
||||||
|
...form.value,
|
||||||
|
customFields,
|
||||||
|
copyFiles,
|
||||||
|
richTextTmpFileIds: isPlatformDefaultTemplate.value ? getDescriptionFileId() : descriptionFileIds.value,
|
||||||
|
};
|
||||||
|
if (isCopy.value) {
|
||||||
|
delete tmpObj.id;
|
||||||
|
delete tmpObj.richTextTmpFileIds;
|
||||||
|
}
|
||||||
|
// 过滤出本地保存的文件
|
||||||
|
const localFiles = fileList.value.filter((item) => item.local && item.status === 'init');
|
||||||
|
|
||||||
|
return {
|
||||||
|
request: tmpObj,
|
||||||
|
fileList: localFiles as unknown as File[],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function resetForm() {
|
||||||
|
// 如果是保存并继续创建
|
||||||
|
const { templateId } = form.value;
|
||||||
|
// 用当前模板初始化自定义字段
|
||||||
|
form.value = {
|
||||||
|
projectId: appStore.currentProjectId, // 取当前项目id
|
||||||
|
title: '',
|
||||||
|
description: '',
|
||||||
|
templateId,
|
||||||
|
tags: [],
|
||||||
|
platformSystemFields: {},
|
||||||
|
};
|
||||||
|
await templateChange(templateId);
|
||||||
|
// 清空文件列表
|
||||||
|
fileList.value = [];
|
||||||
|
}
|
||||||
|
|
||||||
// 保存
|
// 保存
|
||||||
const saveHandler = async (isContinue = false) => {
|
const saveHandler = async (isContinue = false) => {
|
||||||
formRef.value.validate((error: any) => {
|
formRef.value.validate((error: any) => {
|
||||||
if (!error) {
|
if (!error) {
|
||||||
fApi.value.validate(async (valid: any) => {
|
fApi.value.validate(async (valid: any) => {
|
||||||
if (valid === true) {
|
if (valid === true) {
|
||||||
try {
|
emit('saveParams', isContinue, makeParams());
|
||||||
loading.value = true;
|
|
||||||
const customFields: BugEditCustomFieldItem[] = [];
|
|
||||||
if (formItem.value && formItem.value.length) {
|
|
||||||
formItem.value.forEach((item: FormRuleItem) => {
|
|
||||||
if (item.sourceType === 'CASCADER') {
|
|
||||||
item.value = findParents(item.options as Option[], item.value as string, []) || '';
|
|
||||||
}
|
|
||||||
customFields.push({
|
|
||||||
id: item.field as string,
|
|
||||||
name: item.title as string,
|
|
||||||
type: item.sourceType as string,
|
|
||||||
value: Array.isArray(item.value) ? JSON.stringify(item.value) : (item.value as string),
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (isPlatformDefaultTemplate.value && form.value.platformSystemFields) {
|
|
||||||
Object.keys(form.value.platformSystemFields).forEach((key) => {
|
|
||||||
customFields.push({
|
|
||||||
id: platformSystemFieldMap[key].fieldId,
|
|
||||||
name: platformSystemFieldMap[key].fieldName,
|
|
||||||
type: platformSystemFieldMap[key].type,
|
|
||||||
value: form.value.platformSystemFields[key],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
// delete form.value.platformSystemFields;
|
|
||||||
// 平台默认模板不传递名称, 描述, 标签等参数
|
|
||||||
delete form.value.title;
|
|
||||||
delete form.value.description;
|
|
||||||
delete form.value.tags;
|
|
||||||
}
|
|
||||||
// 过滤出复制的附件
|
|
||||||
const copyFileList = fileList.value.filter((item) => item.isCopyFlag);
|
|
||||||
let copyFiles: { refId: string; fileId: string; local: boolean }[] = [];
|
|
||||||
if (copyFileList.length > 0) {
|
|
||||||
copyFiles = copyFileList.map((file) => {
|
|
||||||
return {
|
|
||||||
refId: file.associateId,
|
|
||||||
fileId: file.uid,
|
|
||||||
local: file.local,
|
|
||||||
bugId: bugId.value as string,
|
|
||||||
fileName: file.name,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const tmpObj: BugEditFormObject = {
|
|
||||||
...form.value,
|
|
||||||
customFields,
|
|
||||||
copyFiles,
|
|
||||||
richTextTmpFileIds: isPlatformDefaultTemplate.value ? getDescriptionFileId() : descriptionFileIds.value,
|
|
||||||
};
|
|
||||||
if (isCopy.value) {
|
|
||||||
delete tmpObj.id;
|
|
||||||
delete tmpObj.richTextTmpFileIds;
|
|
||||||
}
|
|
||||||
// 过滤出本地保存的文件
|
|
||||||
const localFiles = fileList.value.filter((item) => item.local && item.status === 'init');
|
|
||||||
// 执行保存操作
|
|
||||||
const res = await createOrUpdateBug({ request: tmpObj, fileList: localFiles as unknown as File[] });
|
|
||||||
if (isEdit.value) {
|
|
||||||
setIsSave(true);
|
|
||||||
Message.success(t('common.updateSuccess'));
|
|
||||||
router.push({
|
|
||||||
name: BugManagementRouteEnum.BUG_MANAGEMENT_INDEX,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
Message.success(t('common.createSuccess'));
|
|
||||||
if (isContinue) {
|
|
||||||
setIsSave(false);
|
|
||||||
// 如果是保存并继续创建
|
|
||||||
const { templateId } = form.value;
|
|
||||||
// 用当前模板初始化自定义字段
|
|
||||||
form.value = {
|
|
||||||
projectId: appStore.currentProjectId, // 取当前项目id
|
|
||||||
title: '',
|
|
||||||
description: '',
|
|
||||||
templateId,
|
|
||||||
tags: [],
|
|
||||||
platformSystemFields: {},
|
|
||||||
};
|
|
||||||
await templateChange(templateId);
|
|
||||||
// 清空文件列表
|
|
||||||
fileList.value = [];
|
|
||||||
} else {
|
|
||||||
setIsSave(true);
|
|
||||||
// 否则跳转到成功页
|
|
||||||
if (getIsVisited()) {
|
|
||||||
router.push({
|
|
||||||
name: BugManagementRouteEnum.BUG_MANAGEMENT_INDEX,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
router.push({
|
|
||||||
name: BugManagementRouteEnum.BUG_MANAGEMENT_CREATE_SUCCESS,
|
|
||||||
query: {
|
|
||||||
...route.query,
|
|
||||||
id: res.data.id,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(err);
|
|
||||||
} finally {
|
|
||||||
loading.value = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -812,10 +730,6 @@
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const initDefaultFields = async () => {
|
|
||||||
await getTemplateOptions();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 监视自定义字段改变处理formCreate
|
// 监视自定义字段改变处理formCreate
|
||||||
watch(
|
watch(
|
||||||
() => formRules.value,
|
() => formRules.value,
|
||||||
|
@ -846,12 +760,29 @@
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
watch(
|
||||||
await initDefaultFields();
|
() => innerTemplateId.value,
|
||||||
if (isEditOrCopy.value) {
|
(val) => {
|
||||||
// 详情
|
if (val) {
|
||||||
await getDetailInfo();
|
form.value.templateId = val;
|
||||||
|
templateChange(val);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
immediate: true,
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (isEditOrCopy.value) {
|
||||||
|
// 获取详情
|
||||||
|
getDetailInfo();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
saveHandler,
|
||||||
|
resetForm,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
@loaded="loadedCase"
|
@loaded="loadedCase"
|
||||||
>
|
>
|
||||||
<template #titleName>
|
<template #titleName>
|
||||||
<div :class="`case-title flex items-center ${isEditTitle ? 'w-full' : ''}`">
|
<div :class="`case-title flex items-center gap-[8px] ${isEditTitle ? 'w-full' : ''}`">
|
||||||
|
<div v-if="!isEditTitle" class="flex items-center"><caseLevel :case-level="caseLevels" /></div>
|
||||||
<a-input
|
<a-input
|
||||||
v-if="isEditTitle"
|
v-if="isEditTitle"
|
||||||
v-model="titleName"
|
v-model="titleName"
|
||||||
|
@ -30,7 +31,7 @@
|
||||||
@keydown.enter="handleEditName"
|
@keydown.enter="handleEditName"
|
||||||
/>
|
/>
|
||||||
<div v-else class="flex items-center">
|
<div v-else class="flex items-center">
|
||||||
<div> 【{{ detailInfo?.num }}】 </div>
|
<div> [ {{ detailInfo?.num }} ] </div>
|
||||||
<div
|
<div
|
||||||
:class="`${
|
:class="`${
|
||||||
hasAnyPermission(['FUNCTIONAL_CASE:READ+UPDATE']) ? 'hover-title-name' : ''
|
hasAnyPermission(['FUNCTIONAL_CASE:READ+UPDATE']) ? 'hover-title-name' : ''
|
||||||
|
@ -41,9 +42,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #titleLeft>
|
|
||||||
<div v-if="!isEditTitle" class="flex items-center"><caseLevel :case-level="caseLevels" /></div>
|
|
||||||
</template>
|
|
||||||
<template #titleRight="{ loading }">
|
<template #titleRight="{ loading }">
|
||||||
<div class="rightButtons flex items-center">
|
<div class="rightButtons flex items-center">
|
||||||
<MsButton
|
<MsButton
|
||||||
|
|
|
@ -1,7 +1,23 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="flex items-center justify-between">
|
<div class="mb-[16px] flex items-center justify-between">
|
||||||
<div v-if="showType === 'link'" class="flex">
|
<div>
|
||||||
|
<a-radio-group v-model:model-value="showType" type="button" size="medium">
|
||||||
|
<a-radio value="link">{{ t('caseManagement.featureCase.directLink') }}</a-radio>
|
||||||
|
<a-radio value="testPlan">{{ t('caseManagement.featureCase.testPlan') }}</a-radio>
|
||||||
|
</a-radio-group>
|
||||||
|
<a-input-search
|
||||||
|
v-model:model-value="keyword"
|
||||||
|
:placeholder="t('caseManagement.featureCase.searchByName')"
|
||||||
|
allow-clear
|
||||||
|
class="mx-[8px] w-[240px]"
|
||||||
|
@search="getFetch"
|
||||||
|
@press-enter="getFetch"
|
||||||
|
@clear="resetFetch"
|
||||||
|
@input="changeHandler"
|
||||||
|
></a-input-search>
|
||||||
|
</div>
|
||||||
|
<div v-if="showType === 'link'" class="flex items-center">
|
||||||
<a-tooltip v-if="!total">
|
<a-tooltip v-if="!total">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ t('caseManagement.featureCase.noAssociatedDefect') }}
|
{{ t('caseManagement.featureCase.noAssociatedDefect') }}
|
||||||
|
@ -32,29 +48,6 @@
|
||||||
>{{ t('testPlan.featureCase.noBugDataNewBug') }}
|
>{{ t('testPlan.featureCase.noBugDataNewBug') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
<div v-else v-permission="['FUNCTIONAL_CASE:READ+UPDATE']" class="font-medium">{{
|
|
||||||
t('caseManagement.featureCase.testPlanLinkList')
|
|
||||||
}}</div>
|
|
||||||
<div class="mb-4">
|
|
||||||
<a-radio-group v-model:model-value="showType" type="button" class="file-show-type ml-[4px]">
|
|
||||||
<a-radio value="link" class="show-type-icon p-[2px]">{{
|
|
||||||
t('caseManagement.featureCase.directLink')
|
|
||||||
}}</a-radio>
|
|
||||||
<a-radio value="testPlan" class="show-type-icon p-[2px]">{{
|
|
||||||
t('caseManagement.featureCase.testPlan')
|
|
||||||
}}</a-radio>
|
|
||||||
</a-radio-group>
|
|
||||||
<a-input-search
|
|
||||||
v-model:model-value="keyword"
|
|
||||||
:placeholder="t('caseManagement.featureCase.searchByName')"
|
|
||||||
allow-clear
|
|
||||||
class="mx-[8px] w-[240px]"
|
|
||||||
@search="getFetch"
|
|
||||||
@press-enter="getFetch"
|
|
||||||
@clear="resetFetch"
|
|
||||||
@input="changeHandler"
|
|
||||||
></a-input-search>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<BugList
|
<BugList
|
||||||
v-if="showType === 'link'"
|
v-if="showType === 'link'"
|
||||||
|
|
Loading…
Reference in New Issue