Skip to content

Commit

Permalink
Merge pull request #533 from nanasikeai/feat_rule_audit
Browse files Browse the repository at this point in the history
Feat rule audit
  • Loading branch information
viouse authored Jan 15, 2025
2 parents 805f706 + 6f8ca12 commit eae0de4
Show file tree
Hide file tree
Showing 6 changed files with 277 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default class DatabaseTableField {
raw_name: string; // bkbase 字段名
display_name: string; // 展示名称 -- 用于 AS 别名,查询中唯一
field_type: string; // 字段类型 -- 来自 bkbase
aggregate: string | null; // 聚合函数 -- 聚合算法
aggregate: any; // 聚合函数 -- 聚合算法
remark: string; // 备注

constructor(payload = {} as DatabaseTableField) {
Expand Down
4 changes: 2 additions & 2 deletions src/frontend/src/domain/model/strategy/strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ export default class Strategy {
};
select: Array<DatabaseTableFieldModel>,
where: {
operator: 'and' | 'or' ;
connector: 'and' | 'or' ;
conditions: Array<{
operator: 'and' | 'or';
connector: 'and' | 'or';
conditions: Array<{
field: DatabaseTableFieldModel | '';
filter: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,106 @@
class="collapse-card-title"
:label="t('方案')"
style="margin-top: 24px;">
<render-info-block class="mt16">
<render-info-item :label="t('配置方式')">
<span
:style="{
padding: '4px 6px',
color: data.strategy_type === 'rule' ? '#299E56' : '#E38B02',
background: data.strategy_type === 'rule' ? '#DAF6E5' : '#FDEED8',
borderRadius: '2px',
}">
{{ strategyTypeTextMap[data.strategy_type] }}
</span>
</render-info-item>
</render-info-block>
<render-info-block class="mt16">
<render-info-item :label="t('方案名称')">
{{ currentControl?.control_name || '--' }} - V{{ data.control_version }}
</render-info-item>
</render-info-block>
<!-- 自定义规则审计 -->
<template v-if="data.strategy_type === 'rule'">
<render-info-block class="mt16">
<render-info-item :label="t('数据源')">
{{ data.configs.data_source?.rt_id }}
<template v-if="data.configs.data_source?.system_ids.length">
<div
v-for="item in data.configs.data_source.system_ids"
:key="item"
style="line-height: 32px;">
{{ item }}
</div>
</template>
</render-info-item>
</render-info-block>
<render-info-block class="mt16">
<render-info-item :label="t('预期结果')">
<template v-if="data.configs.select.length">
<div class="panel-edit flex">
<div
v-for="element in data.configs.select"
:key="element.raw_name + element.aggregate + element.display_name"
class="query-field flex-center-wrap">
{{ getMetricName(element) }}
</div>
</div>
</template>
<div v-else>
--
</div>
</render-info-item>
</render-info-block>
<render-info-block>
<render-info-item :label="t('风险发现规则')">
<div class="condition-render-item">
<div class="condition-equation-wrap">
<span
v-if="data.configs.where.conditions.length > 1"
class="condition-equation first-equation">
{{ data.configs.where.connector }}
</span>
</div>
<div>
<template
v-for="(item, index) in data.configs.where.conditions"
:key="index">
<div
v-for="(childItem, childIndex) in item.conditions"
:key="childIndex"
class="condition-item"
:style="{ marginTop: index ? '30px' : '0px' }">
<div
v-if="childIndex"
class="condition-equation mr4 mb4">
{{ item.connector }}
</div>
<template v-if="childItem.field">
<div class="condition-key mr4 mb4">
{{ childItem.field.display_name }}
</div>
<div class="condition-method mr4 mb4">
{{ commonData.rule_audit_condition_operator.
find(item => item.value === (childItem.field as DatabaseTableField).aggregate)?.label }}
</div>
</template>
<div
v-for="(value, valIndex) in childItem.filters"
:key="valIndex"
class="condition-value mr4 mb4">
{{ value }}
</div>
</div>
</template>
</div>
</div>
</render-info-item>
</render-info-block>
</template>

<bk-loading :loading="controlLoading">
<component
:is="comMap[currentControl?.control_id || '--']"
:is="comMap[currentControl?.control_type_id || '--']"
ref="comRef"
:data="data" />
</bk-loading>
Expand All @@ -97,6 +188,9 @@

import StrategyManageService from '@service/strategy-manage';

import CommonDataModel from '@model/strategy/common-data';
import type DatabaseTableField from '@model/strategy/database-table-field';
import DatabaseTableFieldModel from '@model/strategy/database-table-field';
import type StrategyModel from '@model/strategy/strategy';

import useRequest from '@hooks/use-request';
Expand Down Expand Up @@ -139,6 +233,23 @@
},
};

const strategyTypeTextMap = {
rule: t('自定义规则审计'),
model: t('引入模型审计'),
} as Record<string, string>;

const {
data: commonData,
} = useRequest(StrategyManageService.fetchStrategyCommon, {
defaultValue: new CommonDataModel(),
manual: true,
});

const getMetricName = (element: DatabaseTableFieldModel) => {
const item = commonData.value.rule_audit_aggregate_type.find(item => item.value === element.aggregate);
return t(`[${item?.label}] ${element.display_name}`);
};

// 获取方案列表
const {
data: controlList,
Expand All @@ -149,3 +260,99 @@
});

</script>
<style scoped lang="postcss">
.risk-detection {
.panel-edit {
position: relative;
min-height: 32px;
padding: 0 3px;
background: #f5f7fa;
border-radius: 2px;
flex-wrap: wrap;

.query-field {
position: relative;
height: 26px;
margin: 3px 4px 3px 0;
line-height: 26px;
color: #fff;
white-space: nowrap;
background: #1eab8b;
border-radius: 2px;

&:hover {
.query-field-remove {
visibility: visible;
}
}

.dragging-handle {
padding: 0 4px;
cursor: move;
}

.query-field-remove {
padding: 0 4px;
text-align: center;
visibility: hidden;
}
}

.flex-center-wrap {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
}
}

.condition-render-item {
display: flex;

.condition-equation-wrap {
position: relative;
width: 50px;
}

.condition-equation {
padding: 2px 8px;
color: #3a84ff;
text-align: center;
background: #edf4ff;
border-radius: 2px;
}

.first-equation {
position: absolute;
top: calc(50% - 10px);
}

.condition-item {
display: flex;
margin-bottom: 8px;
flex-wrap: wrap;

.condition-key {
padding: 2px 8px;
color: #788779;
background: #dde9de;
border-radius: 2px;
}

.condition-method {
padding: 2px 8px;
color: #fe9c00;
background: #fff1db;
border-radius: 2px;
}

.condition-value {
padding: 2px 8px;
color: #63656e;
background: #f0f1f5;
border-radius: 2px;
}
}
}
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@
<span> {{ groupMap[key] }} </span>
</div>
<div class="value-row">
<value-item :item="item" />
<value-item
:data="data"
:item="item" />
</div>
</div>
</template>
Expand Down Expand Up @@ -84,7 +86,11 @@
const props = defineProps<Props>();
const { t, locale } = useI18n();

const column = [t('事件分组'), t('字段名称'), t('字段显示名'), t('重点展示'), t('字段说明')];
const column = computed(() => {
const initColumn = [t('事件分组'), t('字段名称'), t('字段显示名'), t('重点展示'), t('字段映射'), t('字段说明')];
props.data.strategy_type === 'rule' ? initColumn : initColumn.splice(4, 1);
return initColumn;
});

const groupMap = {
event_basic_field_configs: t('基本信息'),
Expand Down Expand Up @@ -128,13 +134,17 @@

&:nth-child(2),
&:nth-child(3) {
width: 180px;
width: 150px;
}

&:nth-child(4) {
width: 100px;
}

&:nth-child(5) {
width: 150px;
}

&:last-child {
flex: 1;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,23 @@
v-for="(value, valueKey) in config"
:key="valueKey">
<div
v-if="!['example', 'prefix'].includes(valueKey)"
v-if="!excludeKey.includes(valueKey)"
class="item">
<div v-if="typeof value === 'boolean'">
{{ value ? t('是') : t('否') }}
</div>
<div
v-else
v-bk-tooltips="{
disabled: value && value.length < 15,
content: value
}">
{{ value }}
<div v-else-if="typeof value === 'object'">
<tooltips
v-if="value.source_field"
:data="value.source_field" />
<tooltips
v-if="value.target_value"
:data="value.target_value" />
</div>
<div v-else>
<tooltips
v-if="value"
:data="value" />
</div>
</div>
</template>
Expand All @@ -37,18 +42,31 @@
</template>

<script setup lang='ts'>
import { computed } from 'vue';
import { useI18n } from 'vue-i18n';
import type StrategyModel from '@model/strategy/strategy';
import StrategyFieldEvent from '@model/strategy/strategy-field-event';
import Tooltips from '@components/show-tooltips-text/index.vue';
interface Props {
item: StrategyFieldEvent['event_basic_field_configs'],
data: StrategyModel,
}
defineProps<Props>();
const props = defineProps<Props>();
const { t } = useI18n();
const excludeKey = computed<Array<string>>(() => {
const initKey = ['example', 'prefix'];
if (props.data.strategy_type === 'model') {
initKey.push('map_config');
}
return initKey;
});
</script>
<style lang="postcss" scoped>
.value-item {
Expand All @@ -62,13 +80,17 @@
&:nth-child(1),
&:nth-child(2) {
width: 180px;
width: 150px;
}
&:nth-child(3) {
width: 100px;
}
&:nth-child(4) {
width: 150px;
}
&:last-child {
flex: 1;
Expand Down
Loading

0 comments on commit eae0de4

Please sign in to comment.