Skip to content

Commit

Permalink
fix(frontend): mysql开区单据详情、单据克隆 TencentBlueKing#7779
Browse files Browse the repository at this point in the history
  • Loading branch information
JustaCattt committed Nov 15, 2024
1 parent b0ee60c commit 32b28b1
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,60 @@
* 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.
*/
import _ from 'lodash';

import type { MysqlOpenAreaDetails } from '@services/model/ticket/details/mysql';
import TicketModel from '@services/model/ticket/ticket';
import { getDetail } from '@services/source/openarea';

import { random } from '@utils';

// 解析器,根据范式提取变量->映射关系
const parser = (pattern: string, input: string) => {
const regexPattern = new RegExp(pattern.replace(/{(.+?)}/g, '(?<$1>.+)'));
return input.match(regexPattern)?.groups || {};
};

// MySQL 开区
export function generateMysqlOpenAreaCloneData(ticketData: TicketModel<MysqlOpenAreaDetails>) {
return Promise.resolve({ id: ticketData.details.config_id });
export async function generateMysqlOpenAreaCloneData(ticketData: TicketModel<MysqlOpenAreaDetails>) {
const { details } = ticketData;
// 获取模板详情
const templateDetail = await getDetail({ id: details.config_id });
// 模板定义的范式
const templatePatterns = templateDetail.config_rules.map((item) => item.target_db_pattern);

const data = details.config_data.map((cur, index) => {
// 集群信息
const clusterInfo = details.clusters[cur.cluster_id];

// 变量
const vars = cur.execute_objects.reduce<Record<string, string>>((varAcc, varCur) => {
let obj = {};
templatePatterns.forEach((pattern) => {
obj = Object.assign(obj, parser(pattern, varCur.target_db));
});
return { ...varAcc, ...obj };
}, {});

// 授权IP
const authorizeIps: string[] = _.get(details, `rules_set[${index}].source_ips`, []);

return {
rowKey: random(),
clusterData: {
id: clusterInfo.id,
master_domain: clusterInfo.immute_domain,
bk_biz_id: clusterInfo.bk_biz_id,
bk_cloud_id: clusterInfo.bk_cloud_id,
bk_cloud_name: clusterInfo.bk_cloud_name,
},
vars,
authorizeIps,
};
});

return Promise.resolve({
id: details.config_id,
data,
});
}
5 changes: 5 additions & 0 deletions dbm-ui/frontend/src/services/model/ticket/details/mysql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,11 @@ export interface MysqlOpenAreaDetails extends DetailBase {
source_ips: string[];
target_instances: string[];
user: string;
privileges: {
priv: string;
user: string;
access_db: string;
}[];
}[];
}

Expand Down
26 changes: 12 additions & 14 deletions dbm-ui/frontend/src/services/source/openarea.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import OpenareaTemplateModel from '@services/model/openarea/openareaTemplate';
import type { ListBase } from '@services/types';

import { useGlobalBizs } from '@stores';

import http from '../http';

const { currentBizId } = useGlobalBizs();

const path = '/apis/mysql/bizs';

// 开区模板列表
Expand All @@ -18,10 +14,12 @@ export const getList = function (params: {
limit?: number;
offset?: number;
}) {
return http.get<ListBase<OpenareaTemplateModel[]>>(`${path}/${currentBizId}/openarea/`, params).then((data) => ({
...data,
results: data.results.map((item: OpenareaTemplateModel) => new OpenareaTemplateModel(item)),
}));
return http
.get<ListBase<OpenareaTemplateModel[]>>(`${path}/${window.PROJECT_CONFIG.BIZ_ID}/openarea/`, params)
.then((data) => ({
...data,
results: data.results.map((item: OpenareaTemplateModel) => new OpenareaTemplateModel(item)),
}));
};

// 新建开区
Expand All @@ -38,12 +36,12 @@ export const create = function (params: {
source_cluster_id: number;
cluster_type?: string;
}) {
return http.post(`${path}/${currentBizId}/openarea/`, params);
return http.post(`${path}/${window.PROJECT_CONFIG.BIZ_ID}/openarea/`, params);
};

// 删除开区模板
export const remove = function (params: { id: number }) {
return http.delete(`${path}/${currentBizId}/openarea/${params.id}/`);
return http.delete(`${path}/${window.PROJECT_CONFIG.BIZ_ID}/openarea/${params.id}/`);
};

// 获取开区结果预览
Expand Down Expand Up @@ -81,13 +79,13 @@ export const getPreview = function (params: {
target_instances: string[];
user: string;
}[];
}>(`${path}/${currentBizId}/openarea/preview/`, params);
}>(`${path}/${window.PROJECT_CONFIG.BIZ_ID}/openarea/preview/`, params);
};

// 开区模板详情
export const getDetail = function (params: { id: number }) {
return http
.get<OpenareaTemplateModel>(`${path}/${currentBizId}/openarea/${params.id}/`)
.get<OpenareaTemplateModel>(`${path}/${window.PROJECT_CONFIG.BIZ_ID}/openarea/${params.id}/`)
.then((data) => new OpenareaTemplateModel(data));
};

Expand All @@ -109,7 +107,7 @@ export const update = function (params: {
const realParams = { ...params } as { id?: number };
delete realParams.id;

return http.put(`${path}/${currentBizId}/openarea/${params.id}/`, realParams);
return http.put(`${path}/${window.PROJECT_CONFIG.BIZ_ID}/openarea/${params.id}/`, realParams);
};

export const updateVariable = function <T extends 'add' | 'update' | 'delete'>(params: {
Expand All @@ -129,5 +127,5 @@ export const updateVariable = function <T extends 'add' | 'update' | 'delete'>(p
}
: undefined;
}) {
return http.post(`${path}/${currentBizId}/openarea/alter_var/`, params);
return http.post(`${path}/${window.PROJECT_CONFIG.BIZ_ID}/openarea/alter_var/`, params);
};
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@
import TendbhaModel from '@services/model/mysql/tendbha';
import type { HostInfo } from '@services/types/ip';
import { ClusterTypes } from '@common/const';
import { useTicketCloneInfo } from '@hooks';
import { ClusterTypes, TicketTypes } from '@common/const';
import ClusterSelector from '@components/cluster-selector/Index.vue';
import IpSelector, { type IPSelectorResult } from '@components/ip-selector/IpSelector.vue';
Expand All @@ -75,6 +77,14 @@
const props = defineProps<Props>();
// 单据克隆
useTicketCloneInfo({
type: TicketTypes.MYSQL_OPEN_AREA,
onSuccess({ data }) {
tableData.value = data;
},
});
const { t } = useI18n();
// 检测列表是否为空
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@
id: cloneData.id,
},
query: {
from: route.name as string
from: route.name as string,
ticketId: route.query.ticketId,
}
})
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import { useI18n } from 'vue-i18n';
import { useRequest } from 'vue-request';
import MysqlPermissionAccountModel from '@services/model/mysql/mysql-permission-account';
import type OpenareaTemplateModel from '@services/model/openarea/openareaTemplate';
import type { MysqlOpenAreaDetails } from '@services/model/ticket/details/mysql';
import TicketModel from '@services/model/ticket/ticket';
Expand All @@ -34,6 +33,13 @@
import TextOverflowLayout from '@components/text-overflow-layout/Index.vue';
interface IDataRow {
user: string;
rules: {
priv: string;
access_db: string;
}[];
}
interface Props {
ticketDetails: TicketModel<MysqlOpenAreaDetails>;
Expand All @@ -45,15 +51,15 @@
const { t } = useI18n();
const rowFlodMap = ref<Record<string, boolean>>({});
const tableData = shallowRef<MysqlPermissionAccountModel[]>([]);
const tableData = shallowRef<IDataRow[]>([]);
const columns = computed(() => [
{
label: t('账号名称'),
field: 'user',
width: 220,
showOverflowTooltip: false,
render: ({ data }: { data: MysqlPermissionAccountModel }) => (
render: ({ data }: { data: IDataRow }) => (
<div class="account-box">
{
data.rules.length > 1
Expand All @@ -62,12 +68,12 @@
type="down-shape"
class={{
'flod-flag': true,
'is-flod': rowFlodMap.value[data.account.user],
'is-flod': rowFlodMap.value[data.user],
}}
onClick={() => handleToogleExpand(data.account.user)}/>
onClick={() => handleToogleExpand(data.user)}/>
)
}
{ data.account.user }
{ data.user }
</div>
),
},
Expand All @@ -76,8 +82,8 @@
width: 300,
field: 'access_db',
showOverflowTooltip: true,
render: ({ data }: { data: MysqlPermissionAccountModel }) => {
const renderRules = rowFlodMap.value[data.account.user] ? data.rules.slice(0, 1) : data.rules;
render: ({ data }: { data: IDataRow }) => {
const renderRules = rowFlodMap.value[data.user] ? data.rules.slice(0, 1) : data.rules;
return renderRules.map(item => (
<div class="inner-row">
<bk-tag>
Expand All @@ -89,18 +95,18 @@
},
{
label: t('权限'),
field: 'privilege',
field: 'priv',
showOverflowTooltip: false,
render: ({ data }: { data: MysqlPermissionAccountModel }) => {
render: ({ data }: { data: IDataRow }) => {
if (data.rules.length === 0) {
return <div class="inner-row">--</div>;
}
const renderRules = rowFlodMap.value[data.account.user] ? data.rules.slice(0, 1) : data.rules;
const renderRules = rowFlodMap.value[data.user] ? data.rules.slice(0, 1) : data.rules;
return renderRules.map(item => (
<div class="inner-row cell-privilege">
<TextOverflowLayout>
{{
default: () => item.privilege.replace(/,/g, ''),
default: () => item.priv.replace(/,/g, ''),
}}
</TextOverflowLayout>
</div>
Expand All @@ -109,10 +115,34 @@
},
]);
watch(
() => props.ticketDetails,
() => {
// 有权限快照返回直接渲染
if (props.ticketDetails.details.rules_set?.[0].privileges?.length) {
const rulesMemo: Record<string, boolean> = {}
tableData.value = props.ticketDetails.details.rules_set.reduce<IDataRow[]>((acc, cur) => {
if (!rulesMemo[cur.user]) {
rulesMemo[cur.user] = true;
acc.push({
user: cur.user,
rules: cur.privileges,
});
}
return acc;
}, []);
}
},
{
immediate: true,
}
);
watch(
() => props.templateDetail,
() => {
if (props.templateDetail) {
// 无权限返回则现查
if (props.templateDetail && tableData.value.length === 0) {
const accountTypeMap = {
[ClusterTypes.TENDBHA]: AccountTypes.MYSQL,
[ClusterTypes.TENDBSINGLE]: AccountTypes.MYSQL,
Expand All @@ -132,7 +162,13 @@
const { run: getPermissionRulesRun, loading: isLoading } = useRequest(getPermissionRules, {
manual: true,
onSuccess({ results }) {
tableData.value = results;
tableData.value = results.map((item) => ({
user: item.account.user,
rules: item.rules.map((rule) => ({
priv: rule.privilege,
access_db: rule.access_db,
})),
}));
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
return item.execute_objects.map((executeObject) => ({
targetCluster: cluster,
newDb: executeObject.target_db,
ips: clusterIpsMap[cluster].join(''),
ips: clusterIpsMap[cluster]?.join('') || '',
}));
}), 'newDb')
),
Expand Down Expand Up @@ -88,10 +88,10 @@
<span>
{ data.ips || '--' }
<db-icon
is-show={data.ips}
is-show={data.ips.length > 0}
class="copy-btn"
type="copy"
onClick={() => copy(data.ips)} />
onClick={() => copy(data.ips.replace(/,/g, '\n'))} />
</span>
),
},
Expand Down

0 comments on commit 32b28b1

Please sign in to comment.