Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(frontend): 新增单据通知设置页面 #8335 #8870

Merged
merged 1 commit into from
Jan 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dbm-ui/frontend/src/common/const/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export * from './dbTypeInfos';
export * from './dbTypes';
export * from './localStorageKeys';
export * from './machineTypes';
export * from './messageTypes';
export * from './occupiedInnerHeight';
export * from './osTypes';
export * from './pipelineStatus';
Expand Down
14 changes: 14 additions & 0 deletions dbm-ui/frontend/src/common/const/messageTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* 消息通知类型
*/

export enum MessageTypes {
SMS = 'sms',
WEIXIN = 'weixin',
MAIL = 'mail',
VOICE = 'voice',
RTX = 'rtx',
WECOM_ROBOT = 'wecom_robot',
}

export const InputMessageTypes = [MessageTypes.WECOM_ROBOT] as string[];
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ const withBizActionList = [
'biz_ticket_config_set',
'doris_apply',
'biz_assistance_vars_config',
'biz_notify_config',
];

export default function (props: Props) {
Expand Down
1 change: 1 addition & 0 deletions dbm-ui/frontend/src/layout/Index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@
'StaffManage',
'TicketFlowSetting',
'TicketCooperationSetting',
'TicketNoticeSetting',
],
[menuEnum.resourceManage]: ['ResourceSpec', 'resourceManage', 'resourcePoolDirtyMachines'],
[menuEnum.platformManage]: [
Expand Down
12 changes: 12 additions & 0 deletions dbm-ui/frontend/src/layout/components/ConfigManage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,18 @@
{{ t('单据协作设置') }}
</span>
</BkMenuItem>
<BkMenuItem
key="TicketNoticeSetting"
v-db-console="'bizConfigManage.ticketNoticeSetting'">
<template #icon>
<DbIcon type="note" />
</template>
<span
v-overflow-tips.right
class="text-overflow">
{{ t('单据通知') }}
</span>
</BkMenuItem>
</BkMenuGroup>
<BkMenuGroup :name="t('设置')">
<BkMenuItem
Expand Down
3 changes: 3 additions & 0 deletions dbm-ui/frontend/src/locales/zh-cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -3882,6 +3882,9 @@
"Mongo分片集群": "Mongo 分片集群",
"sqlserver单节点版": "sqlserver 单节点版",
"sqlserver主从版": "sqlserver 主从版",
"审批人": "审批人",
"协助人": "协助人",
"单据通知": "单据通知",
"这行勿动!新增翻译请在上一行添加!": ""

}
2 changes: 2 additions & 0 deletions dbm-ui/frontend/src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import getTicketRoutes from '@views/ticket-center/routes';
import getTicketCooperationSettingRoutes from '@views/ticket-cooperation-setting/routes';
import getTicketFlowSettingBizRoutes from '@views/ticket-flow-setting-biz/routes';
import getTicketFlowSettingGlobalRoutes from '@views/ticket-flow-setting-global/routes';
import getTicketNoticeRoutes from '@views/ticket-notice-setting/routes';
import getVersionFilesRoutes from '@views/version-files/routes';
import getWhitelistRoutes from '@views/whitelist/routes';

Expand Down Expand Up @@ -140,6 +141,7 @@ export default () => {
...getTicketCooperationSettingRoutes(),
...getTicketFlowSettingGlobalRoutes(),
...businessModuleList,
...getTicketNoticeRoutes(),
],
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export default class FunctionController {
'bizConfigManage.StaffManage': ControllerItem<string>;
'bizConfigManage.ticketFlowSetting': ControllerItem<string>;
'bizConfigManage.ticketCooperationSetting': ControllerItem<string>;
'bizConfigManage.ticketNoticeSetting': ControllerItem<string>;
databaseManage: ControllerItem<string>;
'databaseManage.missionManage': ControllerItem<string>;
'databaseManage.whitelistManage': ControllerItem<string>;
Expand Down
2 changes: 1 addition & 1 deletion dbm-ui/frontend/src/services/model/ticket/ticket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ export default class Ticket<T extends unknown | DetailBase = unknown> {

static statusTextMap = {
[STATUS_APPROVE]: t('待审批'),
[STATUS_INNER_TODO]: t('待继续'),
[STATUS_TODO]: t('待执行'),
[STATUS_RUNNING]: t('执行中'),
[STATUS_RESOURCE_REPLENISH]: t('待补货'),
[STATUS_INNER_TODO]: t('待继续'),
[STATUS_FAILED]: t('已失败'),
[STATUS_SUCCEEDED]: t('已完成'),
[STATUS_TERMINATED]: t('已终止'),
Expand Down
290 changes: 290 additions & 0 deletions dbm-ui/frontend/src/views/ticket-notice-setting/Index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,290 @@
<!--
* TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available.
*
* Copyright (C) 2017-2023 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License athttps://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for
* the specific language governing permissions and limitations under the License.
-->

<template>
<BkLoading :loading="getBizSettingLoading || groupNotifyLoading">
<SmartAction
class="ticket-notice"
:offset-target="getSmartActionOffsetTarget">
<BkCard
:border="false"
class="mb-32"
:show-header="false">
<DbForm
class="notice-form"
:label-width="100">
<DbFormItem
:label="t('通知方式')"
required>
<BkTable
align="center"
border="full"
class="notice-table"
:columns="columns"
:data="dataList"
header-align="center"
:header-cell-class-name="setHeadCellClassName">
</BkTable>
</DbFormItem>
</DbForm>
</BkCard>
<template #action>
<AuthButton
action-id="biz_notify_config"
class="w-88"
:loading="updateSettingLoading"
:resource="bizId"
theme="primary"
@click="handleSubmit">
{{ t('提交') }}
</AuthButton>
<BkButton
class="ml8 w-88"
:disabled="updateSettingLoading"
@click="handleReset">
{{ t('重置') }}
</BkButton>
</template>
</SmartAction>
</BkLoading>
</template>
<script setup lang="tsx">
import _ from 'lodash';
import { useI18n } from 'vue-i18n';
import { useRequest } from 'vue-request';

import TicketModel from '@services/model/ticket/ticket';
import { getBizSettingList, updateBizSetting } from '@services/source/bizSetting';
import { getAlarmGroupNotifyList } from '@services/source/monitorNoticeGroup';

import { InputMessageTypes, MessageTypes } from '@common/const'

import { messageSuccess } from '@utils';

interface DataRow {
status: string;
statusText: string;
noticeMember: string[];
checkbox: Record<string, boolean>,
input: Record<string, string>,
}

const { t } = useI18n();

const dataList = ref<DataRow[]>([]);

const bizId = window.PROJECT_CONFIG.BIZ_ID

const columns = computed(() => {
const baseColumns = [
{
label: t('单据状态'),
field: 'statusText',
width: 100,
},
{
label: t('通知对象'),
field: 'noticeMember',
width: 200,
render: ({ data } : { data: DataRow }) => data.noticeMember.join(',')
},
];

const nofityColumns = (alarmGroupNotifyList.value || []).filter((item) => item.is_active).map(item => {
const isInputType = InputMessageTypes.includes(item.type)
return {
field: item.type,
minWidth: isInputType ? 320 : 120,
showOverflowTooltip: false,
renderHead: () => (
<div class="message-type-head">
<img
height="20"
src={`data:image/png;base64,${item.icon}`}
width="20" />
<span
class="ml-4">
{ item.label }
</span>
</div>
),
render: ({ data } : { data: DataRow }) => {
if (isInputType) {
return (
<bk-input
v-model={data.input[item.type]}
placeholder={t('请输入群ID')}/>
)
}
return <bk-checkbox v-model={data.checkbox[item.type]}/>
}
}
});

return [...baseColumns, ...nofityColumns];
});

const { loading: getBizSettingLoading, data: bizSetting, run: runGetBizSettingList } = useRequest(getBizSettingList, {
manual: true,
});

const { loading: groupNotifyLoading, data: alarmGroupNotifyList, run: runGetAlarmGroupNotifyList } = useRequest(getAlarmGroupNotifyList, {
manual: true,
});

const { loading: updateSettingLoading, run: runUpdateBizSetting } = useRequest(updateBizSetting, {
manual: true,
onSuccess: () => {
messageSuccess(t('保存成功'));
},
});

watch([bizSetting, alarmGroupNotifyList], () => {
if (bizSetting.value && alarmGroupNotifyList.value) {
const activeTypeMap = alarmGroupNotifyList.value.reduce<{
checkbox: Record<string, boolean>,
input: Record<string, string>,
}>((prevMap, item) => {
if (item.is_active) {
if (InputMessageTypes.includes(item.type)) {
Object.assign(prevMap.input, {
[item.type]: ''
})
} else {
Object.assign(prevMap.checkbox, {
[item.type]: false
})
}
}
return prevMap;
}, {
checkbox: {},
input: {}
})

const isBizSettingEmpty = _.isEmpty(bizSetting.value) || _.isEmpty(bizSetting.value.NOTIFY_CONFIG)
const list: DataRow[] = []

Object.entries(TicketModel.statusTextMap).forEach(([status, statusText]) => {
if (![TicketModel.STATUS_RUNNING, TicketModel.STATUS_TIMER].includes(status)) {
const initSetting = _.cloneDeep(activeTypeMap)
if (isBizSettingEmpty) {
[MessageTypes.MAIL, MessageTypes.RTX].forEach(type => {
if (initSetting.checkbox[type] !== undefined) {
initSetting.checkbox[type] = true;
}
});
} else {
const statusBizSetting = bizSetting.value!.NOTIFY_CONFIG[status]
Object.keys(initSetting.checkbox).forEach(initSettingKey => {
initSetting.checkbox[initSettingKey] = statusBizSetting[initSettingKey] || false
})
Object.keys(initSetting.input).forEach(initSettingKey => {
initSetting.input[initSettingKey] = (statusBizSetting[initSettingKey] || []).join(',')
})
}

list.push({
status,
statusText,
noticeMember: status === TicketModel.STATUS_APPROVE ? [t('审批人')] : [t('提单人'), t('协助人')],
checkbox: initSetting.checkbox,
input: initSetting.input
})
}
})
dataList.value = list
}
})

const setHeadCellClassName = ({ columnIndex }: { columnIndex: number }) => columnIndex < 2 ? 'common-head' : ''

const getSmartActionOffsetTarget = () => document.querySelector('.bk-form-content');

const getData = () => {
runGetBizSettingList({
bk_biz_id: bizId,
key: 'NOTIFY_CONFIG',
})
runGetAlarmGroupNotifyList({
bk_biz_id: bizId
})
}

const handleSubmit = () => {
runUpdateBizSetting({
bk_biz_id: bizId,
key: 'NOTIFY_CONFIG',
value: dataList.value.reduce<Record<string, Record<string, boolean | string[]>>>((prevMap, dataItem) => {
const checkboxMap = Object.entries(dataItem.checkbox).reduce<Record<string, boolean>>((prevMap, [key, value])=> {
if (value) {
return Object.assign({}, prevMap, { [key]: value })
}
return prevMap
}, {})
const inputMap = Object.entries(dataItem.input).reduce<Record<string, string[]>>((prevMap, [key, value])=> {
if (value) {
return Object.assign({}, prevMap, { [key]: value.split(',') })
}
return prevMap
}, {})
return Object.assign({}, prevMap, {
[dataItem.status]: {
...checkboxMap,
...inputMap
}
})
}, {})
})
};

const handleReset = () => {
getData()
};

// 初始化查询
getData()
</script>

<style lang="less" scoped>
.ticket-notice {
padding: 20px;

.db-card {
& ~ .db-card {
margin: 20px;
}
}

:deep(.notice-form) {
padding: 24px 0;

.bk-form-label {
font-size: 12px;
}
}

:deep(.notice-table) {
th {
&.common-head {
font-weight: bolder;
}

.message-type-head {
display: flex;
align-items: center;
}
}
}
}
</style>
Loading
Loading