Merge remote-tracking branch 'origin/master'

This commit is contained in:
xlsea 2024-04-20 22:42:24 +08:00
commit d57ab2a954
19 changed files with 729 additions and 70 deletions

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -12,12 +12,12 @@ export const enableStatusRecord: Record<Api.Common.EnableStatus, App.I18n.I18nKe
export const enableStatusOptions = transformRecordToOption(enableStatusRecord);
export const enableStatus01Record: Record<Api.Common.EnableStatus01, App.I18n.I18nKey> = {
0: 'page.manage.common.status.enable',
1: 'page.manage.common.status.disable'
export const enableStatus01Record: Record<Api.Common.EnableStatusNumber, App.I18n.I18nKey> = {
0: 'page.manage.common.status.disable',
1: 'page.manage.common.status.enable'
};
export const enableStatus01Options = transformRecordToNumberOption(enableStatus01Record);
export const enableStatus01Options = transformRecordToNumberOption(enableStatus01Record, true);
export const userGenderRecord: Record<Api.SystemManage.UserGender, App.I18n.I18nKey> = {
'1': 'page.manage.user.gender.male',
@ -54,25 +54,25 @@ export const alarmTypeRecord: Record<Api.NotifyRecipient.AlarmType, App.I18n.I18
export const alarmTypeRecordOptions = transformRecordToOption(alarmTypeRecord);
export const systemTaskType: Record<Api.NotifyConfig.SystemTaskType, App.I18n.I18nKey> = {
'1': 'common.systemTaskType.retry',
// '2': 'common.systemTaskType.callback',
'3': 'common.systemTaskType.job',
'4': 'common.systemTaskType.workflow'
1: 'common.systemTaskType.retry',
// 2: 'common.systemTaskType.callback',
3: 'common.systemTaskType.job',
4: 'common.systemTaskType.workflow'
};
export const systemTaskTypeOptions = transformRecordToOption(systemTaskType);
export const systemTaskTypeOptions = transformRecordToNumberOption(systemTaskType);
export const retryNotifyScene: Record<Api.NotifyConfig.RetryNotifyScene, App.I18n.I18nKey> = {
'1': 'page.notifyConfig.retryNotifyScene.maxRetry',
'2': 'page.notifyConfig.retryNotifyScene.maxRetryError',
'3': 'page.notifyConfig.retryNotifyScene.clientReportError',
'4': 'page.notifyConfig.retryNotifyScene.clientComponentError',
'5': 'page.notifyConfig.retryNotifyScene.retryTaskReachThreshold',
'6': 'page.notifyConfig.retryNotifyScene.retryTaskEnterDeadLetter'
1: 'page.notifyConfig.retryNotifyScene.maxRetry',
2: 'page.notifyConfig.retryNotifyScene.maxRetryError',
3: 'page.notifyConfig.retryNotifyScene.clientReportError',
4: 'page.notifyConfig.retryNotifyScene.clientComponentError',
5: 'page.notifyConfig.retryNotifyScene.retryTaskReachThreshold',
6: 'page.notifyConfig.retryNotifyScene.retryTaskEnterDeadLetter'
};
export const retryNotifySceneOptions = transformRecordToOption(retryNotifyScene);
export const retryNotifySceneOptions = transformRecordToNumberOption(retryNotifyScene);
export const jobNotifyScene: Record<Api.NotifyConfig.JobNotifyScene, App.I18n.I18nKey> = {
'1': 'page.notifyConfig.jobNotifyScene.jobTaskError'
1: 'page.notifyConfig.jobNotifyScene.jobTaskError'
};
export const jobNotifySceneOptions = transformRecordToOption(jobNotifyScene);

View File

@ -169,6 +169,8 @@ const local: App.I18n.Schema = {
notify: 'notify',
notify_recipient: 'Notify recipient',
notify_scene: 'Notify scene',
retry: 'Retry task',
retry_scene: 'Retry scene',
'manage_user-detail': 'User Detail',
manage_role: 'Role Manage',
manage_menu: 'Menu Manage',
@ -602,6 +604,35 @@ const local: App.I18n.Schema = {
email: 'Email',
weCom: 'WeCom',
lark: 'Lark'
},
retryScene: {
title: 'Scene List',
groupName: 'Group name',
sceneName: 'Scene name',
sceneStatus: 'State',
backOff: 'Backoff strategy',
maxRetryCount: 'Maximum number of retries',
triggerInterval: 'Intervals',
deadlineRequest: 'Call chain timeout',
executorTimeout: 'Overtime time',
createDt: 'Creation time',
updateDt: 'Update time',
description: 'Describe',
routeKey: 'Routing strategy',
form: {
maxRetryCount: 'Please enter Maximum number of retries',
triggerInterval: 'Please enter Intervals',
groupName: 'Please enter Group name',
description: 'Please enter Describe',
executorTimeout: 'Please enter Overtime time',
sceneName: 'Please enter Scene name',
sceneStatus: 'Please enter State',
deadlineRequest: 'Please enter Call chain timeout',
routeKey: 'Please enter Routing strategy',
backOff: 'Please enter Backoff strategy'
},
addScene: 'Add Scenes',
editScene: 'Add Scenes'
}
},
form: {

View File

@ -170,6 +170,8 @@ const local: App.I18n.Schema = {
notify: '告警通知',
notify_recipient: '通知人',
notify_scene: '通知场景',
retry: '重试任务',
retry_scene: '重试场景',
'manage_user-detail': '用户详情',
manage_role: '角色管理',
manage_menu: '菜单管理',
@ -598,6 +600,35 @@ const local: App.I18n.Schema = {
email: '邮箱',
weCom: '企业微信',
lark: '飞书'
},
retryScene: {
title: 'Scene 列表',
groupName: '组名',
sceneName: '场景名',
sceneStatus: '状态',
backOff: '退避策略',
maxRetryCount: '最大重试次数',
triggerInterval: '间隔时间',
deadlineRequest: '调用链超时时间',
executorTimeout: '超时时间',
createDt: '创建时间',
updateDt: '更新时间',
description: '描述',
routeKey: '路由策略',
form: {
maxRetryCount: '请输入最大重试次数',
triggerInterval: '请输入间隔时间',
groupName: '请输入组名',
description: '请输入描述',
executorTimeout: '请输入超时时间',
sceneName: '请输入场景名',
sceneStatus: '请输入状态',
deadlineRequest: '请输入调用链超时时间',
routeKey: '请输入路由策略',
backOff: '请输入退避策略'
},
addScene: '新增场景',
editScene: '编辑场景'
}
},
form: {

View File

@ -40,5 +40,6 @@ export const views: Record<LastLevelRouteKey, RouteComponent | (() => Promise<Ro
notify_recipient: () => import("@/views/notify/recipient/index.vue"),
notify_scene: () => import("@/views/notify/scene/index.vue"),
pods: () => import("@/views/pods/index.vue"),
retry_scene: () => import("@/views/retry/scene/index.vue"),
"user-center": () => import("@/views/user-center/index.vue"),
};

View File

@ -173,7 +173,8 @@ export const generatedRoutes: GeneratedRoute[] = [
component: 'layout.base$view.group-config',
meta: {
title: 'group-config',
i18nKey: 'route.group-config'
i18nKey: 'route.group-config',
order: 40
}
},
{
@ -335,7 +336,7 @@ export const generatedRoutes: GeneratedRoute[] = [
title: 'namepase',
i18nKey: 'route.namepase',
icon: 'oui:app-spaces',
order: 2
order: 20
}
},
{
@ -344,7 +345,8 @@ export const generatedRoutes: GeneratedRoute[] = [
component: 'layout.base',
meta: {
title: 'notify',
i18nKey: 'route.notify'
i18nKey: 'route.notify',
order: 100
},
children: [
{
@ -375,9 +377,30 @@ export const generatedRoutes: GeneratedRoute[] = [
title: 'pods',
i18nKey: 'route.pods',
icon: 'ant-design:database-outlined',
order: 1
order: 10
}
},
{
name: 'retry',
path: '/retry',
component: 'layout.base',
meta: {
title: 'retry',
i18nKey: 'route.retry',
order: 50
},
children: [
{
name: 'retry_scene',
path: '/retry/scene',
component: 'view.retry_scene',
meta: {
title: 'retry_scene',
i18nKey: 'route.retry_scene'
}
}
]
},
{
name: 'user-center',
path: '/user-center',

View File

@ -180,6 +180,8 @@ const routeMap: RouteMap = {
"notify_recipient": "/notify/recipient",
"notify_scene": "/notify/scene",
"pods": "/pods",
"retry": "/retry",
"retry_scene": "/retry/scene",
"user-center": "/user-center"
};

View File

@ -6,3 +6,4 @@ export * from './namespace';
export * from './system-manage';
export * from './notify';
export * from './group-config';
export * from './retry';

37
src/service/api/retry.ts Normal file
View File

@ -0,0 +1,37 @@
import { request } from '../request';
/** get retry scene list */
export function fetchGetRetryScenePageList(params?: Api.RetryScene.SceneSearchParams) {
return request<Api.RetryScene.SceneList>({
url: '/scene-config/page/list',
method: 'get',
params
});
}
/** get retry scene list */
export function fetchGetRetrySceneList(params?: Api.RetryScene.SceneSearchParams) {
return request<Api.RetryScene.SceneList>({
url: '/scene-config/list',
method: 'get',
params
});
}
/** add retry scene */
export function fetchAddRetryScene(data: Api.RetryScene.Scene) {
return request<boolean>({
url: '/scene-config',
method: 'post',
data
});
}
/** edit retry scene */
export function fetchEditRetryScene(data: Api.RetryScene.Scene) {
return request<boolean>({
url: '/scene-config',
method: 'put',
data
});
}

71
src/typings/api.d.ts vendored
View File

@ -41,10 +41,10 @@ declare namespace Api {
/**
* enable status
*
* - "0": enabled
* - "1": disabled
* - 0: enabled
* - 1: disabled
*/
type EnableStatus01 = 0 | 1;
type EnableStatusNumber = 0 | 1;
/**
* yes/no status
@ -527,13 +527,13 @@ declare namespace Api {
/** 业务名称 */
businessName?: string;
/** 状态 */
notifyStatus: string;
notifyStatus: Api.Common.EnableStatusNumber;
/** 通知场景 */
notifyScene: string;
/** 通知阈值 */
notifyThreshold: number;
/** 限流开关 */
rateLimiterStatus: number;
rateLimiterStatus: Api.Common.EnableStatusNumber;
/** 每秒限流阈值 */
rateLimiterThreshold: number;
/** 描述 */
@ -553,13 +553,13 @@ declare namespace Api {
type NotifyConfigList = Common.PaginatingQueryRecord<NotifyConfig>;
/** 任务类型 1、重试任务 2、回调任务、 3、JOB任务 4、WORKFLOW任务 */
type SystemTaskType = '1' | '3' | '4';
type SystemTaskType = 1 | 3 | 4;
/** 1、场景重试数量超过阈值 2、场景重试失败数量超过阈值 3、客户端上报失败 4、客户端组件异常 5、任务重试失败数量超过阈值 6、任务重试失败进入死信队列 */
type RetryNotifyScene = '1' | '2' | '3' | '4' | '5' | '6';
type RetryNotifyScene = 1 | 2 | 3 | 4 | 5 | 6;
/** 1、任务执行失败 */
type JobNotifyScene = '1';
type JobNotifyScene = 1;
}
/**
@ -610,4 +610,59 @@ declare namespace Api {
/** 1: 钉钉通知 2: 邮件通知 3: 企业通知 4: 飞书 */
type AlarmType = 1 | 2 | 3 | 4;
}
/**
* namespace Scene
*
* backend api module: "scene"
*/
namespace RetryScene {
import EnableStatusNumber = Api.Common.EnableStatusNumber;
type CommonSearchParams = Pick<Common.PaginatingCommonParams, 'page' | 'size'>;
/** scene */
type Scene = Common.CommonRecord<{
/** 组名 */
groupName: string;
/** 场景名 */
sceneName: string;
/** 状态 */
sceneStatus: EnableStatusNumber;
/** 退避策略 */
backOff: number;
/** 最大重试次数 */
maxRetryCount: number;
/** 间隔时间 */
triggerInterval: string;
/** 调用链超时时间 */
deadlineRequest: number;
/** 超时时间 */
executorTimeout: number;
/** 描述 */
description: string;
/** 路由策略 */
routeKey: number;
}>;
/** scene search params */
type SceneSearchParams = CommonType.RecordNullable<
Pick<
Api.RetryScene.Scene,
| 'groupName'
| 'sceneName'
| 'sceneStatus'
| 'backOff'
| 'maxRetryCount'
| 'triggerInterval'
| 'deadlineRequest'
| 'executorTimeout'
| 'description'
| 'routeKey'
> &
CommonSearchParams
>;
/** scene list */
type SceneList = Common.PaginatingQueryRecord<Scene>;
}
}

29
src/typings/app.d.ts vendored
View File

@ -774,6 +774,35 @@ declare namespace App {
weCom: string;
lark: string;
};
retryScene: {
title: string;
groupName: string;
sceneName: string;
sceneStatus: string;
backOff: string;
maxRetryCount: string;
triggerInterval: string;
deadlineRequest: string;
executorTimeout: string;
createDt: string;
updateDt: string;
description: string;
routeKey: string;
form: {
maxRetryCount: string;
triggerInterval: string;
groupName: string;
description: string;
executorTimeout: string;
sceneName: string;
sceneStatus: string;
deadlineRequest: string;
routeKey: string;
backOff: string;
};
addScene: string;
editScene: string;
};
};
form: {
required: string;

View File

@ -54,6 +54,8 @@ declare module "@elegant-router/types" {
"notify_recipient": "/notify/recipient";
"notify_scene": "/notify/scene";
"pods": "/pods";
"retry": "/retry";
"retry_scene": "/retry/scene";
"user-center": "/user-center";
};
@ -103,6 +105,7 @@ declare module "@elegant-router/types" {
| "namepase"
| "notify"
| "pods"
| "retry"
| "user-center"
>;
@ -146,6 +149,7 @@ declare module "@elegant-router/types" {
| "notify_recipient"
| "notify_scene"
| "pods"
| "retry_scene"
| "user-center"
>;

View File

@ -29,6 +29,7 @@ export function transformRecordToOption<T extends Record<string, string>>(record
* Transform record to option with keys of number
*
* @param record
* @param reverse
*/
export function transformRecordToNumberOption<T extends Record<number, string>>(record: T, reverse: boolean = false) {
const options = Object.entries(record).map(([value, label]) => ({

View File

@ -26,7 +26,6 @@ interface Props {
const groupNameList = ref<string[]>([]);
const notifyRecipientList = ref<CommonType.Option<number>[]>([]);
const props = defineProps<Props>();
const defaultChecked = ref<number>(0);
interface Emits {
(e: 'submitted'): void;
@ -92,8 +91,8 @@ function createDefaultModel(): Model {
groupName: '',
businessId: '',
notifyRecipientIds: 0,
systemTaskType: '1',
notifyStatus: '',
systemTaskType: 1,
notifyStatus: 1,
notifyScene: '',
notifyThreshold: 0,
rateLimiterStatus: 0,
@ -271,7 +270,7 @@ watch(visible, () => {
/>
</NFormItem>
<NFormItem :label="$t('page.notifyConfig.rateLimiterStatus')" path="rateLimiterStatus">
<NRadioGroup v-model:value="model.rateLimiterStatus" :default-value="defaultChecked" name="rateLimiterStatus">
<NRadioGroup v-model:value="model.rateLimiterStatus" name="rateLimiterStatus">
<NSpace>
<NRadio
v-for="item in enableStatus01Options"

View File

@ -0,0 +1,206 @@
<script setup lang="tsx">
import { NButton, NPopconfirm } from 'naive-ui';
import { fetchGetRetryScenePageList } from '@/service/api';
import { $t } from '@/locales';
import { useAppStore } from '@/store/modules/app';
import { useTable, useTableOperate } from '@/hooks/common/table';
import SceneOperateDrawer from './modules/scene-operate-drawer.vue';
import SceneSearch from './modules/scene-search.vue';
const appStore = useAppStore();
const { columns, columnChecks, data, getData, loading, mobilePagination, searchParams, resetSearchParams } = useTable({
apiFn: fetchGetRetryScenePageList,
apiParams: {
page: 1,
size: 10,
// if you want to use the searchParams in Form, you need to define the following properties, and the value is null
// the value can not be undefined, otherwise the property in Form will not be reactive
groupName: null,
sceneName: null,
sceneStatus: null
},
columns: () => [
{
type: 'selection',
align: 'center',
width: 48
},
{
key: 'index',
title: $t('common.index'),
align: 'center',
width: 64
},
{
key: 'groupName',
title: $t('page.retryScene.groupName'),
align: 'left',
minWidth: 120
},
{
key: 'sceneName',
title: $t('page.retryScene.sceneName'),
align: 'left',
minWidth: 120
},
{
key: 'sceneStatus',
title: $t('page.retryScene.sceneStatus'),
align: 'left',
minWidth: 120
},
{
key: 'backOff',
title: $t('page.retryScene.backOff'),
align: 'left',
minWidth: 120
},
{
key: 'maxRetryCount',
title: $t('page.retryScene.maxRetryCount'),
align: 'left',
minWidth: 120
},
{
key: 'triggerInterval',
title: $t('page.retryScene.triggerInterval'),
align: 'left',
minWidth: 120
},
{
key: 'deadlineRequest',
title: $t('page.retryScene.deadlineRequest'),
align: 'left',
minWidth: 120
},
{
key: 'executorTimeout',
title: $t('page.retryScene.executorTimeout'),
align: 'left',
minWidth: 120
},
{
key: 'createDt',
title: $t('page.retryScene.createDt'),
align: 'left',
minWidth: 120
},
{
key: 'updateDt',
title: $t('page.retryScene.updateDt'),
align: 'left',
minWidth: 120
},
{
key: 'description',
title: $t('page.retryScene.description'),
align: 'left',
minWidth: 120
},
{
key: 'routeKey',
title: $t('page.retryScene.routeKey'),
align: 'left',
minWidth: 120
},
{
key: 'operate',
title: $t('common.operate'),
align: 'center',
width: 130,
render: row => (
<div class="flex-center gap-8px">
<NButton type="primary" ghost size="small" onClick={() => edit(row.id!)}>
{$t('common.edit')}
</NButton>
<NPopconfirm onPositiveClick={() => handleDelete(row.id!)}>
{{
default: () => $t('common.confirmDelete'),
trigger: () => (
<NButton type="error" ghost size="small">
{$t('common.delete')}
</NButton>
)
}}
</NPopconfirm>
</div>
)
}
]
});
const {
drawerVisible,
operateType,
editingData,
handleAdd,
handleEdit,
checkedRowKeys,
onBatchDeleted,
onDeleted
// closeDrawer
} = useTableOperate(data, getData);
async function handleBatchDelete() {
// request
console.log(checkedRowKeys.value);
onBatchDeleted();
}
function handleDelete(id: string) {
// request
console.log(id);
onDeleted();
}
function edit(id: string) {
handleEdit(id);
}
</script>
<template>
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
<SceneSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getData" />
<NCard
:title="$t('page.retryScene.title')"
:bordered="false"
size="small"
class="sm:flex-1-hidden card-wrapper"
header-class="view-card-header"
>
<template #header-extra>
<TableHeaderOperation
v-model:columns="columnChecks"
:disabled-delete="checkedRowKeys.length === 0"
:loading="loading"
@add="handleAdd"
@delete="handleBatchDelete"
@refresh="getData"
/>
</template>
<NDataTable
v-model:checked-row-keys="checkedRowKeys"
:columns="columns"
:data="data"
:flex-height="!appStore.isMobile"
:scroll-x="962"
:loading="loading"
remote
:row-key="row => row.id"
:pagination="mobilePagination"
class="sm:h-full"
/>
<SceneOperateDrawer
v-model:visible="drawerVisible"
:operate-type="operateType"
:row-data="editingData"
@submitted="getData"
/>
</NCard>
</div>
</template>
<style scoped></style>

View File

@ -0,0 +1,217 @@
<script setup lang="ts">
import { computed, reactive, watch } from 'vue';
import { useFormRules, useNaiveForm } from '@/hooks/common/form';
import OperateDrawer from '@/components/common/operate-drawer.vue';
import { $t } from '@/locales';
import { fetchAddRetryScene, fetchEditRetryScene } from '@/service/api';
import { enableStatus01Options } from '@/constants/business';
defineOptions({
name: 'SceneOperateDrawer'
});
interface Props {
/** the type of operation */
operateType: NaiveUI.TableOperateType;
/** the edit row data */
rowData?: Api.RetryScene.Scene | null;
}
const props = defineProps<Props>();
interface Emits {
(e: 'submitted'): void;
}
const emit = defineEmits<Emits>();
const visible = defineModel<boolean>('visible', {
default: false
});
const { formRef, validate, restoreValidation } = useNaiveForm();
const { defaultRequiredRule } = useFormRules();
const title = computed(() => {
const titles: Record<NaiveUI.TableOperateType, string> = {
add: $t('page.retryScene.addScene'),
edit: $t('page.retryScene.editScene')
};
return titles[props.operateType];
});
type Model = Pick<
Api.RetryScene.Scene,
| 'id'
| 'groupName'
| 'sceneName'
| 'sceneStatus'
| 'backOff'
| 'maxRetryCount'
| 'triggerInterval'
| 'deadlineRequest'
| 'executorTimeout'
| 'description'
| 'routeKey'
>;
const model: Model = reactive(createDefaultModel());
function createDefaultModel(): Model {
return {
groupName: '',
sceneName: '',
sceneStatus: 1,
backOff: 0,
maxRetryCount: 0,
triggerInterval: '',
deadlineRequest: 0,
executorTimeout: 0,
description: '',
routeKey: 0
};
}
type RuleKey = Extract<
keyof Model,
| 'groupName'
| 'sceneName'
| 'sceneStatus'
| 'backOff'
| 'maxRetryCount'
| 'triggerInterval'
| 'deadlineRequest'
| 'executorTimeout'
| 'routeKey'
>;
const rules: Record<RuleKey, App.Global.FormRule> = {
groupName: defaultRequiredRule,
sceneName: defaultRequiredRule,
sceneStatus: defaultRequiredRule,
backOff: defaultRequiredRule,
maxRetryCount: defaultRequiredRule,
triggerInterval: defaultRequiredRule,
deadlineRequest: defaultRequiredRule,
executorTimeout: defaultRequiredRule,
routeKey: defaultRequiredRule
};
function handleUpdateModelWhenEdit() {
if (props.operateType === 'add') {
Object.assign(model, createDefaultModel());
return;
}
if (props.operateType === 'edit' && props.rowData) {
Object.assign(model, props.rowData);
}
}
function closeDrawer() {
visible.value = false;
}
async function handleSubmit() {
await validate();
// request
if (props.operateType === 'add') {
const {
groupName,
sceneName,
sceneStatus,
backOff,
maxRetryCount,
triggerInterval,
deadlineRequest,
executorTimeout,
routeKey,
description
} = model;
fetchAddRetryScene({
groupName,
sceneName,
sceneStatus,
backOff,
maxRetryCount,
triggerInterval,
deadlineRequest,
executorTimeout,
routeKey,
description
});
}
if (props.operateType === 'edit') {
const {
id,
groupName,
sceneName,
sceneStatus,
backOff,
maxRetryCount,
triggerInterval,
deadlineRequest,
executorTimeout,
routeKey,
description
} = model;
fetchEditRetryScene({
id,
groupName,
sceneName,
sceneStatus,
backOff,
maxRetryCount,
triggerInterval,
deadlineRequest,
executorTimeout,
routeKey,
description
});
}
window.$message?.success($t('common.updateSuccess'));
closeDrawer();
emit('submitted');
}
watch(visible, () => {
if (visible.value) {
handleUpdateModelWhenEdit();
restoreValidation();
}
});
</script>
<template>
<OperateDrawer v-model="visible" :title="title" @handle-submit="handleSubmit">
<NForm ref="formRef" :model="model" :rules="rules">
<NFormItem :label="$t('page.retryScene.groupName')" path="groupName">
<NInput v-model:value="model.groupName" :placeholder="$t('page.retryScene.form.groupName')" />
</NFormItem>
<NFormItem :label="$t('page.retryScene.sceneName')" path="sceneName">
<NInput v-model:value="model.sceneName" :placeholder="$t('page.retryScene.form.sceneName')" />
</NFormItem>
<NFormItem :label="$t('page.retryScene.sceneStatus')" path="sceneStatus">
<NRadioGroup v-model:value="model.sceneStatus" name="sceneStatus">
<NSpace>
<NRadio
v-for="item in enableStatus01Options"
:key="item.value"
:value="item.value"
:label="$t(item.label)"
/>
</NSpace>
</NRadioGroup>
</NFormItem>
</NForm>
<template #footer>
<NSpace :size="16">
<NButton @click="closeDrawer">{{ $t('common.cancel') }}</NButton>
<NButton type="primary" @click="handleSubmit">{{ $t('common.save') }}</NButton>
</NSpace>
</template>
</OperateDrawer>
</template>
<style scoped></style>

View File

@ -0,0 +1,40 @@
<script setup lang="ts">
import { $t } from '@/locales';
defineOptions({
name: 'SceneSearch'
});
interface Emits {
(e: 'reset'): void;
(e: 'search'): void;
}
const emit = defineEmits<Emits>();
const model = defineModel<Api.RetryScene.SceneSearchParams>('model', { required: true });
function reset() {
emit('reset');
}
function search() {
emit('search');
}
</script>
<template>
<SearchForm :model="model" @search="search" @reset="reset">
<NFormItemGi span="24 s:12 m:6" :label="$t('page.scene.scene.groupName')" path="userName" class="pr-24px">
<NInput v-model:value="model.groupName" :placeholder="$t('page.scene.scene.form.groupName')" />
</NFormItemGi>
<NFormItemGi span="24 s:12 m:6" :label="$t('page.scene.scene.sceneName')" path="userName" class="pr-24px">
<NInput v-model:value="model.sceneName" :placeholder="$t('page.scene.scene.form.sceneName')" />
</NFormItemGi>
<NFormItemGi span="24 s:12 m:6" :label="$t('page.scene.scene.sceneStatus')" path="userName" class="pr-24px">
<!-- <NInput v-model:value="model.sceneStatus" :placeholder="$t('page.scene.scene.form.sceneStatus')" />-->
</NFormItemGi>
</SearchForm>
</template>
<style scoped></style>