fix: 修复通知人页面

This commit is contained in:
xlsea 2024-04-19 17:41:21 +08:00
parent 8095eb4295
commit 9dcb53905f
10 changed files with 152 additions and 175 deletions

2
.env
View File

@ -35,7 +35,7 @@ VITE_SERVICE_SUCCESS_CODE=1
VITE_SERVICE_LOGOUT_CODES=8888,8889 VITE_SERVICE_LOGOUT_CODES=8888,8889
# modal logout codes of backend service, when the code is received, the user will be logged out by displaying a modal # modal logout codes of backend service, when the code is received, the user will be logged out by displaying a modal
VITE_SERVICE_MODAL_LOGOUT_CODES=0 VITE_SERVICE_MODAL_LOGOUT_CODES=5001
# token expired codes of backend service, when the code is received, it will refresh the token and resend the request # token expired codes of backend service, when the code is received, it will refresh the token and resend the request
VITE_SERVICE_EXPIRED_TOKEN_CODES=9999,9998 VITE_SERVICE_EXPIRED_TOKEN_CODES=9999,9998

View File

@ -14,7 +14,6 @@ interface Props {
const props = defineProps<Props>(); const props = defineProps<Props>();
interface Emits { interface Emits {
(e: 'submitted'): void;
(e: 'update:modelValue', modelValue: boolean): void; (e: 'update:modelValue', modelValue: boolean): void;
} }
@ -64,7 +63,7 @@ const onUpdateShow = (value: boolean) => {
</script> </script>
<template> <template>
<NDrawer v-model:show="visible" display-directive="show" :width="drawerWidth" @update:show="onUpdateShow"> <NDrawer v-model:show="visible" display-directive="if" :width="drawerWidth" @update:show="onUpdateShow">
<NDrawerContent :title="props.title" :native-scrollbar="false" closable header-class="operate-dawer-header"> <NDrawerContent :title="props.title" :native-scrollbar="false" closable header-class="operate-dawer-header">
<template #header> <template #header>
{{ props.title }} {{ props.title }}

View File

@ -590,6 +590,6 @@ declare namespace Api {
type NotifyRecipientList = Common.PaginatingQueryRecord<NotifyRecipient>; type NotifyRecipientList = Common.PaginatingQueryRecord<NotifyRecipient>;
/** 1: 钉钉通知 2: 邮件通知 3: 企业通知 4: 飞书 */ /** 1: 钉钉通知 2: 邮件通知 3: 企业通知 4: 飞书 */
type AlarmType = '1' | '2' | '3' | '4'; type AlarmType = 1 | 2 | 3 | 4;
} }
} }

View File

@ -75,15 +75,19 @@ async function handleSubmit() {
// request // request
if (props.operateType === 'add') { if (props.operateType === 'add') {
const { name, uniqueId } = model; const { name, uniqueId } = model;
fetchAddNamespace({ name, uniqueId }); const { error } = await fetchAddNamespace({ name, uniqueId });
if (error) return;
window.$message?.success($t('common.addSuccess'));
} }
if (props.operateType === 'edit') { if (props.operateType === 'edit') {
const { id, name, uniqueId } = model; const { id, name, uniqueId } = model;
fetchEditNamespace({ id, name, uniqueId }); const { error } = await fetchEditNamespace({ id, name, uniqueId });
} if (error) return;
window.$message?.success($t('common.updateSuccess')); window.$message?.success($t('common.updateSuccess'));
visible.value = false; }
closeDrawer();
emit('submitted'); emit('submitted');
} }

View File

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { reactive } from 'vue'; import { reactive, watch } from 'vue';
import { useFormRules, useNaiveForm } from '@/hooks/common/form'; import { useFormRules, useNaiveForm } from '@/hooks/common/form';
import { $t } from '@/locales'; import { $t } from '@/locales';
@ -7,29 +7,35 @@ defineOptions({
name: 'DingDingForm' name: 'DingDingForm'
}); });
interface Props {
value: Api.NotifyRecipient.NotifyRecipient;
}
const props = defineProps<Props>();
interface Emits { interface Emits {
(e: 'fetchAdd', model: Api.NotifyRecipient.NotifyRecipient): void; (e: 'update:value', value: Api.NotifyRecipient.NotifyRecipient): void;
(e: 'fetchUpdate', model: Api.NotifyRecipient.NotifyRecipient): void;
} }
const emit = defineEmits<Emits>(); const emit = defineEmits<Emits>();
const { formRef, validate } = useNaiveForm(); const { formRef, validate, restoreValidation } = useNaiveForm();
const { defaultRequiredRule } = useFormRules(); const { defaultRequiredRule } = useFormRules();
type Model = Pick< type Model = Pick<
Api.NotifyRecipient.DingDingNotify, Api.NotifyRecipient.DingDingNotify,
'id' | 'recipientName' | 'notifyType' | 'webhookUrl' | 'ats' | 'description' 'id' | 'recipientName' | 'notifyType' | 'webhookUrl' | 'ats' | 'description' | 'notifyAttribute'
>; >;
const model: Model = reactive(createDefaultModel()); const model: Model = reactive(createDefaultModel());
function createDefaultModel(): Model { function createDefaultModel(): Model {
const { webhookUrl, ats } = JSON.parse(props.value.notifyAttribute!) as { webhookUrl: string; ats: string[] };
return { return {
id: '', id: props.value.id,
recipientName: '', recipientName: props.value.recipientName,
notifyType: '1', notifyType: 1,
webhookUrl: '', webhookUrl,
ats: [], ats,
description: '' description: ''
}; };
} }
@ -47,33 +53,19 @@ const buildNotifyAttribute = (webhookUrl: string, ats: string[]) => {
return JSON.stringify({ webhookUrl, ats }); return JSON.stringify({ webhookUrl, ats });
}; };
async function save() { watch(
await validate(); () => model,
const { recipientName, notifyType, webhookUrl, ats, description } = model; () => {
const notifyAttribute = buildNotifyAttribute(webhookUrl, ats);
emit('fetchAdd', { recipientName, notifyType, notifyAttribute, description });
}
async function update() {
await validate();
const { id, recipientName, notifyType, webhookUrl, ats, description } = model; const { id, recipientName, notifyType, webhookUrl, ats, description } = model;
const notifyAttribute = buildNotifyAttribute(webhookUrl, ats); const notifyAttribute = buildNotifyAttribute(webhookUrl, ats);
emit('fetchUpdate', { id, recipientName, notifyType, notifyAttribute, description }); emit('update:value', { id, recipientName, notifyType, notifyAttribute, description });
} },
{ deep: true }
const showData = (rowData: Api.NotifyRecipient.NotifyRecipient) => { );
if (rowData.notifyAttribute) {
const notifyAttribute = JSON.parse(rowData.notifyAttribute);
Object.assign(model, rowData);
Object.assign(model, notifyAttribute);
}
};
defineExpose({ defineExpose({
save, validate,
createDefaultModel, restoreValidation
showData,
update
}); });
</script> </script>
@ -96,7 +88,7 @@ defineExpose({
<template #trigger> <template #trigger>
{{ $t('page.notifyRecipient.ats') }} {{ $t('page.notifyRecipient.ats') }}
</template> </template>
{{ $t('page.notifyRecipient.form.dingdingAts') }} {{ $t('page.notifyRecipient.form.dingDingAts') }}
</NTooltip> </NTooltip>
</a> </a>
</template> </template>

View File

@ -1,20 +1,25 @@
<script setup lang="ts"> <script setup lang="ts">
import { reactive } from 'vue'; import { reactive, watch } from 'vue';
import { useFormRules, useNaiveForm } from '@/hooks/common/form'; import { useFormRules, useNaiveForm } from '@/hooks/common/form';
import { $t } from '@/locales'; import { $t } from '@/locales';
defineOptions({ defineOptions({
name: 'LarkForm' name: 'EmailForm'
}); });
interface Props {
value: Api.NotifyRecipient.NotifyRecipient;
}
defineProps<Props>();
interface Emits { interface Emits {
(e: 'fetchAdd', model: Api.NotifyRecipient.NotifyRecipient): void; (e: 'update:value', value: Api.NotifyRecipient.NotifyRecipient): void;
(e: 'fetchUpdate', model: Api.NotifyRecipient.NotifyRecipient): void;
} }
const emit = defineEmits<Emits>(); const emit = defineEmits<Emits>();
const { formRef, validate } = useNaiveForm(); const { formRef, validate, restoreValidation } = useNaiveForm();
const { defaultRequiredRule } = useFormRules(); const { defaultRequiredRule } = useFormRules();
type Model = Pick<Api.NotifyRecipient.EmailNotify, 'id' | 'recipientName' | 'notifyType' | 'tos' | 'description'>; type Model = Pick<Api.NotifyRecipient.EmailNotify, 'id' | 'recipientName' | 'notifyType' | 'tos' | 'description'>;
@ -24,7 +29,7 @@ function createDefaultModel(): Model {
return { return {
id: '', id: '',
recipientName: '', recipientName: '',
notifyType: '2', notifyType: 2,
tos: [], tos: [],
description: '' description: ''
}; };
@ -42,33 +47,19 @@ const buildNotifyAttribute = (tos: string[]) => {
return JSON.stringify({ tos }); return JSON.stringify({ tos });
}; };
async function save() { watch(
await validate(); () => model,
() => {
const { id, recipientName, notifyType, tos, description } = model; const { id, recipientName, notifyType, tos, description } = model;
const notifyAttribute = buildNotifyAttribute(tos); const notifyAttribute = buildNotifyAttribute(tos);
emit('fetchAdd', { id, recipientName, notifyType, notifyAttribute, description }); emit('update:value', { id, recipientName, notifyType, notifyAttribute, description });
} },
{ immediate: true, deep: true }
const showData = (rowData: Api.NotifyRecipient.NotifyRecipient) => { );
if (rowData.notifyAttribute) {
const notifyAttribute = JSON.parse(rowData.notifyAttribute);
Object.assign(model, rowData);
Object.assign(model, notifyAttribute);
}
};
async function update() {
await validate();
const { id, recipientName, notifyType, tos, description } = model;
const notifyAttribute = buildNotifyAttribute(tos);
emit('fetchUpdate', { id, recipientName, notifyType, notifyAttribute, description });
}
defineExpose({ defineExpose({
save, validate,
showData, restoreValidation
createDefaultModel,
update
}); });
</script> </script>

View File

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { reactive } from 'vue'; import { reactive, watch } from 'vue';
import { useFormRules, useNaiveForm } from '@/hooks/common/form'; import { useFormRules, useNaiveForm } from '@/hooks/common/form';
import { $t } from '@/locales'; import { $t } from '@/locales';
@ -7,19 +7,24 @@ defineOptions({
name: 'LarkForm' name: 'LarkForm'
}); });
interface Props {
value: Api.NotifyRecipient.NotifyRecipient;
}
defineProps<Props>();
interface Emits { interface Emits {
(e: 'fetchAdd', model: Api.NotifyRecipient.NotifyRecipient): void; (e: 'update:value', value: Api.NotifyRecipient.NotifyRecipient): void;
(e: 'fetchUpdate', model: Api.NotifyRecipient.NotifyRecipient): void;
} }
const emit = defineEmits<Emits>(); const emit = defineEmits<Emits>();
const { formRef, validate } = useNaiveForm(); const { formRef, validate, restoreValidation } = useNaiveForm();
const { defaultRequiredRule } = useFormRules(); const { defaultRequiredRule } = useFormRules();
type Model = Pick< type Model = Pick<
Api.NotifyRecipient.DingDingNotify, Api.NotifyRecipient.DingDingNotify,
'id' | 'recipientName' | 'notifyType' | 'webhookUrl' | 'ats' | 'description' 'id' | 'recipientName' | 'notifyType' | 'webhookUrl' | 'ats' | 'description' | 'notifyAttribute'
>; >;
const model: Model = reactive(createDefaultModel()); const model: Model = reactive(createDefaultModel());
@ -27,7 +32,7 @@ function createDefaultModel(): Model {
return { return {
id: '', id: '',
recipientName: '', recipientName: '',
notifyType: '4', notifyType: 4,
webhookUrl: '', webhookUrl: '',
ats: [], ats: [],
description: '' description: ''
@ -47,33 +52,19 @@ const buildNotifyAttribute = (webhookUrl: string, ats: string[]) => {
return JSON.stringify({ webhookUrl, ats }); return JSON.stringify({ webhookUrl, ats });
}; };
async function save() { watch(
await validate(); () => model,
() => {
const { id, recipientName, notifyType, webhookUrl, ats, description } = model; const { id, recipientName, notifyType, webhookUrl, ats, description } = model;
const notifyAttribute = buildNotifyAttribute(webhookUrl, ats); const notifyAttribute = buildNotifyAttribute(webhookUrl, ats);
emit('fetchAdd', { id, recipientName, notifyType, notifyAttribute, description }); emit('update:value', { id, recipientName, notifyType, notifyAttribute, description });
} },
{ immediate: true, deep: true }
async function update() { );
await validate();
const { id, recipientName, notifyType, webhookUrl, ats, description } = model;
const notifyAttribute = buildNotifyAttribute(webhookUrl, ats);
emit('fetchUpdate', { id, recipientName, notifyType, notifyAttribute, description });
}
const showData = (rowData: Api.NotifyRecipient.NotifyRecipient) => {
if (rowData.notifyAttribute) {
const notifyAttribute = JSON.parse(rowData.notifyAttribute);
Object.assign(model, rowData);
Object.assign(model, notifyAttribute);
}
};
defineExpose({ defineExpose({
save, validate,
showData, restoreValidation
createDefaultModel,
update
}); });
</script> </script>
@ -107,8 +98,8 @@ defineExpose({
v-model:value="model.description" v-model:value="model.description"
type="textarea" type="textarea"
:placeholder="$t('page.notifyRecipient.form.description')" :placeholder="$t('page.notifyRecipient.form.description')"
round
clearable clearable
round
/> />
</NFormItem> </NFormItem>
</NForm> </NForm>

View File

@ -13,8 +13,6 @@ defineOptions({
name: 'NotifyRecipientOperateDrawer' name: 'NotifyRecipientOperateDrawer'
}); });
const CommonRef = ref();
interface Props { interface Props {
/** the type of operation */ /** the type of operation */
operateType: NaiveUI.TableOperateType; operateType: NaiveUI.TableOperateType;
@ -34,11 +32,11 @@ const visible = defineModel<boolean>('visible', {
default: false default: false
}); });
const defaultTabPane = defineModel<string>('defaultTabPane', { const notifyTabPane = defineModel<Api.NotifyRecipient.AlarmType>('notifyTabPane', {
default: '1' default: 1
}); });
const { restoreValidation } = useNaiveForm(); const { formRef, validate, restoreValidation } = useNaiveForm();
const title = computed(() => { const title = computed(() => {
const titles: Record<NaiveUI.TableOperateType, string> = { const titles: Record<NaiveUI.TableOperateType, string> = {
@ -48,43 +46,52 @@ const title = computed(() => {
return titles[props.operateType]; return titles[props.operateType];
}); });
type Model = Pick<
Api.NotifyRecipient.NotifyRecipient,
'id' | 'recipientName' | 'notifyType' | 'notifyAttribute' | 'description'
>;
const model = ref<Model>(createDefaultModel());
function createDefaultModel(): Model {
return {
recipientName: '',
notifyType: notifyTabPane.value!,
notifyAttribute: '{}',
description: ''
};
}
function handleUpdateModelWhenEdit() { function handleUpdateModelWhenEdit() {
if (props.operateType === 'add') { if (props.operateType === 'add') {
CommonRef.value?.createDefaultModel(); model.value = createDefaultModel();
return; return;
} }
if (props.operateType === 'edit' && props.rowData) { if (props.operateType === 'edit' && props.rowData) {
defaultTabPane.value = props.rowData.notifyType.toString(); model.value = props.rowData;
CommonRef.value?.showData(props.rowData);
} }
} }
async function handleSubmit() { async function handleSubmit() {
await validate();
// request // request
if (props.operateType === 'add') { if (props.operateType === 'add') {
CommonRef.value?.save(); const { recipientName, notifyAttribute, notifyType, description } = model.value;
const { error } = await fetchAddNotifyRecipient({ recipientName, notifyAttribute, notifyType, description });
if (error) return;
window.$message?.success($t('common.addSuccess'));
} }
if (props.operateType === 'edit') { if (props.operateType === 'edit') {
CommonRef.value?.update(); const { id, recipientName, notifyAttribute, notifyType, description } = model.value;
const { error } = await fetchEditNotifyRecipient({ id, recipientName, notifyAttribute, notifyType, description });
if (error) return;
window.$message?.success($t('common.updateSuccess'));
} }
closeDrawer();
emit('submitted'); emit('submitted');
} }
const commonFetchAdd = (dingDingModel: Api.NotifyRecipient.NotifyRecipient) => {
const { recipientName, notifyAttribute, notifyType, description } = dingDingModel;
fetchAddNotifyRecipient({ recipientName, notifyAttribute, notifyType, description });
window.$message?.success($t('common.addSuccess'));
};
const commonFetchUpdate = (dingDingModel: Api.NotifyRecipient.NotifyRecipient) => {
const { id, recipientName, notifyAttribute, notifyType, description } = dingDingModel;
fetchEditNotifyRecipient({ id, recipientName, notifyAttribute, notifyType, description });
window.$message?.success($t('common.updateSuccess'));
};
function closeDrawer() { function closeDrawer() {
visible.value = false; visible.value = false;
} }
@ -98,19 +105,19 @@ watch(visible, () => {
</script> </script>
<template> <template>
<OperateDrawer v-model="visible" :title="title" @handle-submit="handleSubmit"> <OperateDrawer v-model="visible" :title="title">
<NTabs v-model:value="defaultTabPane" type="segment" animated> <NTabs v-model:value="notifyTabPane" type="segment" animated>
<NTabPane name="1" :tab="$t('page.notifyRecipient.dingDing')"> <NTabPane :name="1" tab="钉钉">
<DingDingForm ref="CommonRef" @fetch-add="commonFetchAdd" @fetch-update="commonFetchUpdate" /> <DingDingForm ref="formRef" v-model:value="model" />
</NTabPane> </NTabPane>
<NTabPane name="2" :tab="$t('page.notifyRecipient.email')"> <NTabPane :name="2" tab="邮箱">
<EmailForm ref="CommonRef" @fetch-add="commonFetchAdd" @fetch-update="commonFetchUpdate" /> <EmailForm ref="formRef" v-model:value="model" />
</NTabPane> </NTabPane>
<NTabPane name="3" :tab="$t('page.notifyRecipient.weCom')"> <NTabPane :name="3" tab="企业微信">
<WeComForm ref="CommonRef" @fetch-add="commonFetchAdd" @fetch-update="commonFetchUpdate" /> <WeComForm ref="formRef" v-model:value="model" />
</NTabPane> </NTabPane>
<NTabPane name="4" :tab="$t('page.notifyRecipient.lark')"> <NTabPane :name="4" tab="飞书">
<LarkForm ref="CommonRef" @fetch-add="commonFetchAdd" @fetch-update="commonFetchUpdate" /> <LarkForm ref="formRef" v-model:value="model" />
</NTabPane> </NTabPane>
</NTabs> </NTabs>
<template #footer> <template #footer>

View File

@ -1,25 +1,30 @@
<script setup lang="ts"> <script setup lang="ts">
import { reactive } from 'vue'; import { reactive, watch } from 'vue';
import { useFormRules, useNaiveForm } from '@/hooks/common/form'; import { useFormRules, useNaiveForm } from '@/hooks/common/form';
import { $t } from '@/locales'; import { $t } from '@/locales';
defineOptions({ defineOptions({
name: 'LarkForm' name: 'WecomForm'
}); });
interface Props {
value: Api.NotifyRecipient.NotifyRecipient;
}
defineProps<Props>();
interface Emits { interface Emits {
(e: 'fetchAdd', model: Api.NotifyRecipient.NotifyRecipient): void; (e: 'update:value', value: Api.NotifyRecipient.NotifyRecipient): void;
(e: 'fetchUpdate', model: Api.NotifyRecipient.NotifyRecipient): void;
} }
const emit = defineEmits<Emits>(); const emit = defineEmits<Emits>();
const { formRef, validate } = useNaiveForm(); const { formRef, validate, restoreValidation } = useNaiveForm();
const { defaultRequiredRule } = useFormRules(); const { defaultRequiredRule } = useFormRules();
type Model = Pick< type Model = Pick<
Api.NotifyRecipient.DingDingNotify, Api.NotifyRecipient.DingDingNotify,
'id' | 'recipientName' | 'notifyType' | 'webhookUrl' | 'ats' | 'description' 'id' | 'recipientName' | 'notifyType' | 'webhookUrl' | 'ats' | 'description' | 'notifyAttribute'
>; >;
const model: Model = reactive(createDefaultModel()); const model: Model = reactive(createDefaultModel());
@ -27,7 +32,7 @@ function createDefaultModel(): Model {
return { return {
id: '', id: '',
recipientName: '', recipientName: '',
notifyType: '3', notifyType: 3,
webhookUrl: '', webhookUrl: '',
ats: [], ats: [],
description: '' description: ''
@ -47,33 +52,19 @@ const buildNotifyAttribute = (webhookUrl: string, ats: string[]) => {
return JSON.stringify({ webhookUrl, ats }); return JSON.stringify({ webhookUrl, ats });
}; };
async function save() { watch(
await validate(); () => model,
() => {
const { id, recipientName, notifyType, webhookUrl, ats, description } = model; const { id, recipientName, notifyType, webhookUrl, ats, description } = model;
const notifyAttribute = buildNotifyAttribute(webhookUrl, ats); const notifyAttribute = buildNotifyAttribute(webhookUrl, ats);
emit('fetchAdd', { id, recipientName, notifyType, notifyAttribute, description }); emit('update:value', { id, recipientName, notifyType, notifyAttribute, description });
} },
{ immediate: true, deep: true }
async function update() { );
await validate();
const { id, recipientName, notifyType, webhookUrl, ats, description } = model;
const notifyAttribute = buildNotifyAttribute(webhookUrl, ats);
emit('fetchUpdate', { id, recipientName, notifyType, notifyAttribute, description });
}
const showData = (rowData: Api.NotifyRecipient.NotifyRecipient) => {
if (rowData.notifyAttribute) {
const notifyAttribute = JSON.parse(rowData.notifyAttribute);
Object.assign(model, rowData);
Object.assign(model, notifyAttribute);
}
};
defineExpose({ defineExpose({
save, validate,
showData, restoreValidation
createDefaultModel,
update
}); });
</script> </script>
@ -107,8 +98,8 @@ defineExpose({
v-model:value="model.description" v-model:value="model.description"
type="textarea" type="textarea"
:placeholder="$t('page.notifyRecipient.form.description')" :placeholder="$t('page.notifyRecipient.form.description')"
round
clearable clearable
round
/> />
</NFormItem> </NFormItem>
</NForm> </NForm>

View File

@ -111,7 +111,7 @@ async function handleSubmit() {
notifyThreshold, notifyThreshold,
description description
} = model; } = model;
fetchAddNotify({ const { error } = await fetchAddNotify({
groupName, groupName,
businessId, businessId,
notifyStatus, notifyStatus,
@ -121,6 +121,7 @@ async function handleSubmit() {
notifyThreshold, notifyThreshold,
description description
}); });
if (error) return;
} }
if (props.operateType === 'edit') { if (props.operateType === 'edit') {
@ -135,7 +136,7 @@ async function handleSubmit() {
notifyThreshold, notifyThreshold,
description description
} = model; } = model;
fetchEditNotify({ const { error } = await fetchEditNotify({
id, id,
groupName, groupName,
businessId, businessId,
@ -146,6 +147,7 @@ async function handleSubmit() {
notifyThreshold, notifyThreshold,
description description
}); });
if (error) return;
} }
window.$message?.success($t('common.updateSuccess')); window.$message?.success($t('common.updateSuccess'));
closeDrawer(); closeDrawer();