diff --git a/dbm-ui/frontend/package.json b/dbm-ui/frontend/package.json
index 3ae3915a41..0709124280 100644
--- a/dbm-ui/frontend/package.json
+++ b/dbm-ui/frontend/package.json
@@ -88,6 +88,7 @@
"vite-plugin-html-env": "1.2.8",
"vite-plugin-imp": "2.4.0",
"vite-plugin-style-import": "2.0.0",
+ "vue-component-type-helpers": "^2.0.6",
"vue-tsc": "^1.8.22"
},
"simple-git-hooks": {
diff --git a/dbm-ui/frontend/public/sqlserver_cluster_authorize.xlsx b/dbm-ui/frontend/public/sqlserver_cluster_authorize.xlsx
new file mode 100644
index 0000000000..0c2a1dd524
Binary files /dev/null and b/dbm-ui/frontend/public/sqlserver_cluster_authorize.xlsx differ
diff --git a/dbm-ui/frontend/src/common/const.ts b/dbm-ui/frontend/src/common/const.ts
index 94b83a93e6..b013941446 100644
--- a/dbm-ui/frontend/src/common/const.ts
+++ b/dbm-ui/frontend/src/common/const.ts
@@ -316,6 +316,10 @@ export enum TicketTypes {
MONGODB_BACKUP = 'MONGODB_BACKUP', // mongo 库表备份
MONGODB_RESTORE = 'MONGODB_RESTORE', // mongo 定点构造
MONGODB_TEMPORARY_DESTROY = 'MONGODB_TEMPORARY_DESTROY', // mongo 临时集群销毁
+ SQLSERVER_AUTHORIZE_RULES = 'SQLSERVER_AUTHORIZE_RULES', // sqlserver 集群授权
+ SQLSERVER_EXCEL_AUTHORIZE_RULES = 'SQLSERVER_EXCEL_AUTHORIZE_RULES', // sqlserver 导入授权
+ SQLSERVER_RESET = 'SQLSERVER_RESET', // sqlserver 集群重置
+ SQLSERVER_BACKUP_DBS = 'SQLSERVER_BACKUP_DBS', // sqlserver 数据库备份
}
export type TicketTypesStrings = keyof typeof TicketTypes;
@@ -499,6 +503,8 @@ export enum UserPersonalSettings {
MONGODB_INSTANCE_TABLE_SETTINGS = 'MONGODB_INSTANCE_TABLE_SETTINGS',
MONGODB_REPLICA_SET_SETTINGS = 'MONGODB_REPLICA_SET_SETTINGS',
MONGODB_SHARED_CLUSTER_SETTINGS = 'MONGODB_SHARED_CLUSTER_SETTINGS',
+ SQLSERVER_SINGLE_TABLE_SETTINGS = 'SQLSERVER_SINGLE_TABLE_SETTINGS',
+ SQLSERVER_HA_TABLE_SETTINGS = 'SQLSERVER_HA_TABLE_SETTINGS',
}
/**
@@ -558,6 +564,7 @@ export enum AccountTypes {
MYSQL = 'mysql',
TENDBCLUSTER = 'tendbcluster',
MONGODB = 'mongodb',
+ SQLSERVER = 'sqlserver',
}
export type AccountTypesValues = `${AccountTypes}`;
diff --git a/dbm-ui/frontend/src/components/cluster-authorize/ClusterAuthorize.vue b/dbm-ui/frontend/src/components/cluster-authorize/ClusterAuthorize.vue
index 4cd65ab6f9..52836c7ef6 100644
--- a/dbm-ui/frontend/src/components/cluster-authorize/ClusterAuthorize.vue
+++ b/dbm-ui/frontend/src/components/cluster-authorize/ClusterAuthorize.vue
@@ -26,7 +26,7 @@
-
-
-
-
-
- {{ t('添加账号规则') }}
-
-
-
- {{ t('全部清空') }}
-
-
-
-
-
-
+
{{ t('权限规则') }}
@@ -160,6 +129,38 @@
:empty-text="t('请选择访问DB')" />
+
+
+
+
+
+ {{ t('添加账号规则') }}
+
+
+
+ {{ t('全部清空') }}
+
+
+
+
+
-
+
@@ -203,17 +205,19 @@
import MongodbModel from '@services/model/mongodb/mongodb';
import MongodbPermissonAccountModel from '@services/model/mongodb-permission/mongodb-permission-account';
+ import SqlserverPermissionAccountModel from '@services/model/sqlserver-permission/sqlserver-permission-account';
import { getPermissionRules, preCheckAuthorizeRules } from '@services/permission';
import { checkHost } from '@services/source/ipchooser';
import { getMongodbPermissionRules } from '@services/source/mongodbPermissionAccount';
import { preCheckMongodbAuthorizeRules } from '@services/source/mongodbPermissionAuthorize';
+ import { getSqlserverPermissionRules } from '@services/source/sqlserverPermissionAccount';
+ import { preCheckSqlserverAuthorizeRules } from '@services/source/sqlserverPermissionAuthorize';
import { createTicket } from '@services/source/ticket';
import { getWhitelist } from '@services/source/whitelist';
import type { AuthorizePreCheckData, PermissionRule } from '@services/types/permission';
import { useCopy, useInfo, useStickyFooter, useTicketMessage } from '@hooks';
- import type { AccountTypesValues } from '@common/const';
import { AccountTypes, ClusterTypes, TicketTypes } from '@common/const';
import ClusterSelectorNew, { type TabConfig } from '@components/cluster-selector-new/Index.vue';
@@ -234,9 +238,10 @@
type ResourceItem = NonNullable[number] & { isMaster?: boolean };
type MysqlPreCheckResulst = ServiceReturnType
type MongoPreCheckResulst = ServiceReturnType
+ type SqlserverPreCheckResulst = ServiceReturnType
interface Props {
- accountType: AccountTypesValues,
+ accountType: AccountTypes,
user?: string,
accessDbs?: string[],
selected?: {
@@ -281,6 +286,14 @@
name: t('分片集群'),
showPreviewResultTitle: true,
},
+ [ClusterTypes.SQLSERVER_SINGLE]: {
+ name: t('单节点集群'),
+ showPreviewResultTitle: true,
+ },
+ [ClusterTypes.SQLSERVER_HA]: {
+ name: t('主从集群'),
+ showPreviewResultTitle: true,
+ },
};
/**
@@ -314,7 +327,7 @@
/** 权限规则功能 */
const accountState = reactive({
isLoading: false,
- rules: [] as PermissionRule[] | MongodbPermissonAccountModel[],
+ rules: [] as PermissionRule[] | MongodbPermissonAccountModel[] | SqlserverPermissionAccountModel[],
});
const clusterState = reactive({
@@ -344,6 +357,8 @@
],
});
+ const isMysql = computed(() => [AccountTypes.MYSQL, AccountTypes.TENDBCLUSTER].includes(props.accountType))
+
const collapseTableColumns = computed(() => {
const columns = [
{
@@ -419,7 +434,7 @@
tableProps,
} = clusterState;
selected[clusterType] = tableProps.data;
- return selected as unknown as Record;
+ return selected as unknown as Record;
});
const tabListConfig = computed(() => props.clusterTypes.reduce((prevConfig, clusterTypeItem) => ({
@@ -431,6 +446,7 @@
[AccountTypes.MYSQL]: TicketTypes.MYSQL_AUTHORIZE_RULES,
[AccountTypes.TENDBCLUSTER]: TicketTypes.TENDBCLUSTER_AUTHORIZE_RULES,
[AccountTypes.MONGODB]: TicketTypes.MONGODB_AUTHORIZE,
+ [AccountTypes.SQLSERVER]: TicketTypes.SQLSERVER_AUTHORIZE_RULES
};
const bizId = window.PROJECT_CONFIG.BIZ_ID;
@@ -497,6 +513,7 @@
[AccountTypes.MYSQL]: getPermissionRules,
[AccountTypes.TENDBCLUSTER]: getPermissionRules,
[AccountTypes.MONGODB]: getMongodbPermissionRules,
+ [AccountTypes.SQLSERVER]: getSqlserverPermissionRules
};
apiMap[props.accountType]({
@@ -522,6 +539,8 @@
[ClusterTypes.TENDBCLUSTER]: 'Spider',
[ClusterTypes.MONGO_REPLICA_SET]: t('副本集'),
[ClusterTypes.MONGO_SHARED_CLUSTER]: t('分片集群'),
+ [ClusterTypes.SQLSERVER_SINGLE]: t('单节点'),
+ [ClusterTypes.SQLSERVER_HA]: t('主从'),
};
return clusterTextMap[clusterState.clusterType];
});
@@ -621,6 +640,7 @@
[AccountTypes.MYSQL]: 'PermissionRules',
[AccountTypes.TENDBCLUSTER]: 'spiderPermission',
[AccountTypes.MONGODB]: 'MongodbPermission',
+ [AccountTypes.SQLSERVER]: 'SqlServerPermissionRules'
};
const url = router.resolve({ name: routeMap[props.accountType] });
window.open(url.href, '_blank');
@@ -629,7 +649,10 @@
/**
* 创建授权单据
*/
- const createAuthorizeTicket = (uid: string, data: MysqlPreCheckResulst['authorize_data'] | MongoPreCheckResulst['authorize_data']) => {
+ const createAuthorizeTicket = (
+ uid: string,
+ data: MysqlPreCheckResulst['authorize_data'] | MongoPreCheckResulst['authorize_data'] | SqlserverPreCheckResulst['authorize_data']
+ ) => {
const params = {
bk_biz_id: bizId,
details: {
@@ -664,6 +687,7 @@
[AccountTypes.MYSQL]: preCheckAuthorizeRules,
[AccountTypes.TENDBCLUSTER]: preCheckAuthorizeRules,
[AccountTypes.MONGODB]: preCheckMongodbAuthorizeRules,
+ [AccountTypes.SQLSERVER]: preCheckSqlserverAuthorizeRules
};
const params = {
target_instances: formdata.target_instances,
@@ -677,6 +701,13 @@
access_dbs: selectedItem.rules.map(mapItem => mapItem.access_db),
})),
});
+ } else if (props.accountType === AccountTypes.SQLSERVER) {
+ Object.assign(params, {
+ sqlserver_users: selectedList.value.map(selectedItem => ({
+ user: selectedItem.account.user,
+ access_dbs: selectedItem.rules.map(mapItem => mapItem.access_db),
+ })),
+ });
} else {
Object.assign(params, {
access_dbs: formdata.access_dbs,
diff --git a/dbm-ui/frontend/src/components/cluster-authorize/accouter-rules-selector/Index.vue b/dbm-ui/frontend/src/components/cluster-authorize/accouter-rules-selector/Index.vue
index 20db994aeb..155e9939e3 100644
--- a/dbm-ui/frontend/src/components/cluster-authorize/accouter-rules-selector/Index.vue
+++ b/dbm-ui/frontend/src/components/cluster-authorize/accouter-rules-selector/Index.vue
@@ -27,11 +27,12 @@
class="mb-16"
:data="filters"
:placeholder="t('请输入账号或DB名')"
- style="width: 520px;"
+ style="width: 520px"
unique-select
@change="handleSearchSelectChange" />
@@ -54,24 +55,27 @@
-
+
-
diff --git a/dbm-ui/frontend/src/components/cluster-authorize/accouter-rules-selector/components/AccountRulesTable.vue b/dbm-ui/frontend/src/components/cluster-authorize/accouter-rules-selector/components/AccountRulesTable.vue
index ca6325d95d..b98873763e 100644
--- a/dbm-ui/frontend/src/components/cluster-authorize/accouter-rules-selector/components/AccountRulesTable.vue
+++ b/dbm-ui/frontend/src/components/cluster-authorize/accouter-rules-selector/components/AccountRulesTable.vue
@@ -26,25 +26,28 @@
-
diff --git a/dbm-ui/frontend/src/components/cluster-common/ExcelAuthorize.vue b/dbm-ui/frontend/src/components/cluster-common/ExcelAuthorize.vue
index 75407ecae9..315b7b6e15 100644
--- a/dbm-ui/frontend/src/components/cluster-common/ExcelAuthorize.vue
+++ b/dbm-ui/frontend/src/components/cluster-common/ExcelAuthorize.vue
@@ -166,7 +166,12 @@
downloadTemplatePath: `${basePath}mongo_cluster_authorize.xlsx`,
};
}
-
+ if ([ClusterTypes.SQLSERVER_SINGLE, ClusterTypes.SQLSERVER_HA].includes(props.clusterType)) {
+ return {
+ uploadLink: `/apis/sqlserver/bizs/${globalBizsStore.currentBizId}/permission/authorize/pre_check_excel_rules/`,
+ downloadTemplatePath: `${basePath}sqlserver_cluster_authorize.xlsx`,
+ };
+ }
return {
uploadLink: `/apis/mysql/bizs/${globalBizsStore.currentBizId}/permission/authorize/pre_check_excel_rules/`,
downloadTemplatePath: `${basePath}cluster-authorize.xlsx`,
@@ -195,7 +200,10 @@
excel_url: excelState.precheck.excelUrl,
authorize_data_list: excelState.precheck.authorizeDataList.map((authorizeItem) => {
const authorizeItemCopy = { ...authorizeItem };
- if ([ClusterTypes.MONGO_REPLICA_SET, ClusterTypes.MONGO_SHARED_CLUSTER].includes(props.clusterType)) {
+ if ([
+ ClusterTypes.MONGO_REPLICA_SET,
+ ClusterTypes.MONGO_SHARED_CLUSTER,
+ ].includes(props.clusterType)) {
delete authorizeItemCopy.source_ips;
}
return authorizeItemCopy;
diff --git a/dbm-ui/frontend/src/components/cluster-event-change/EventChange.vue b/dbm-ui/frontend/src/components/cluster-event-change/EventChange.vue
index c405465f54..e35975e7da 100644
--- a/dbm-ui/frontend/src/components/cluster-event-change/EventChange.vue
+++ b/dbm-ui/frontend/src/components/cluster-event-change/EventChange.vue
@@ -57,7 +57,7 @@
interface Props {
id: number, // 集群 or 实例 id
- isFetchInstance: boolean
+ isFetchInstance?: boolean
}
const props = withDefaults(defineProps(), {
diff --git a/dbm-ui/frontend/src/components/cluster-selector-new/components/sqlserver/Index.vue b/dbm-ui/frontend/src/components/cluster-selector-new/components/sqlserver/Index.vue
index 5652529685..96f9b8738c 100644
--- a/dbm-ui/frontend/src/components/cluster-selector-new/components/sqlserver/Index.vue
+++ b/dbm-ui/frontend/src/components/cluster-selector-new/components/sqlserver/Index.vue
@@ -12,29 +12,31 @@
-->
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/Index.vue b/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/Index.vue
new file mode 100644
index 0000000000..c88ead678c
--- /dev/null
+++ b/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/Index.vue
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
diff --git a/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page1/Index.vue b/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page1/Index.vue
new file mode 100644
index 0000000000..2d31536e37
--- /dev/null
+++ b/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page1/Index.vue
@@ -0,0 +1,407 @@
+
+
+
+
+
+
+
+
+ handleAppend(index)"
+ @input-backup-dbs-finish="(backupDbs: string[]) => handleDbListChange(index, backupDbs, 'backupDbs')"
+ @input-cluster-finish="(domain: string) => handleClusterChange(index, domain)"
+ @input-ignore-dbs-finish="(ignoreDbs: string[]) => handleDbListChange(index, ignoreDbs, 'ignoreDbs')"
+ @remove="() => handleRemove(index)"
+ @show-final-reviewer="() => handleShowFianlDbReviewer(item)" />
+
+
+
+
+
+ {{ t('全量备份') }}
+
+
+ {{ t('增量备份') }}
+
+
+
+
+
+
+
+
+
+ 3 {{ t('年') }}
+ 30 {{ t('天') }}
+
+
+
+ 15 {{ t('天') }}
+
+
+
+
+
+
+
+
+ {{ t('提交') }}
+
+
+
+ {{ t('重置') }}
+
+
+
+
+
+
+
+ {{ t('预览DB结果列表') }}
+ {{ currentRowData.domain }}
+
+
+
+
+
+
+
+
+
diff --git a/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page1/components/BatchEntry/Index.vue b/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page1/components/BatchEntry/Index.vue
new file mode 100644
index 0000000000..814e97df62
--- /dev/null
+++ b/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page1/components/BatchEntry/Index.vue
@@ -0,0 +1,363 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('n处格式错误', [inputInvalidStack.length]) }}
+
+
+
+ ;
+ {{ t('n处缺少匹配对象', [inputErrorStack.length]) }}
+
+
+
+ ;
+ {{ t('n处目标集群不存在', [inputClusterErrorStack.length]) }}
+
+
+
+
+
+
+ {{ t('确定') }}
+
+
+ {{ t('取消') }}
+
+
+
+
+
+
+
+
+
+
diff --git a/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page1/components/FianlDbReviewer/Index.vue b/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page1/components/FianlDbReviewer/Index.vue
new file mode 100644
index 0000000000..858c2417ee
--- /dev/null
+++ b/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page1/components/FianlDbReviewer/Index.vue
@@ -0,0 +1,198 @@
+
+
+
+
+
+
+
+ {{ t('备份DB名') }}
+
+
+ {{ t('忽略DB名') }}
+
+
+
+
+
+
+ |
+
+
+ |
+
+
+
+
+
+ {{ t('最终DB') }}
+ ({{ t('共n个', [finalDbs.length]) }})
+
+
+ {{ t('复制') }}
+
+
+
+
+
+
+
+
+
+
diff --git a/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page1/components/RenderData/Index.vue b/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page1/components/RenderData/Index.vue
new file mode 100644
index 0000000000..0bd133a2e4
--- /dev/null
+++ b/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page1/components/RenderData/Index.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+ {{ t('目标集群') }}
+
+
+
+
+
+
+
+ {{ t('备份DB名') }}
+
+
+ {{ t('忽略DB名') }}
+
+
+ {{ t('最终DB') }}
+
+
+ {{ t('操作') }}
+
+
+
+
+
+
+
+
+
+
diff --git a/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page1/components/RenderData/RenderDbName.vue b/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page1/components/RenderData/RenderDbName.vue
new file mode 100644
index 0000000000..eac49289e4
--- /dev/null
+++ b/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page1/components/RenderData/RenderDbName.vue
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
+
+
diff --git a/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page1/components/RenderData/RenderDomain.vue b/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page1/components/RenderData/RenderDomain.vue
new file mode 100644
index 0000000000..7501a2553f
--- /dev/null
+++ b/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page1/components/RenderData/RenderDomain.vue
@@ -0,0 +1,146 @@
+
+
+
+
+
+
+
+
+
diff --git a/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page1/components/RenderData/RenderRow.vue b/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page1/components/RenderData/RenderRow.vue
new file mode 100644
index 0000000000..0a1abb35ca
--- /dev/null
+++ b/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page1/components/RenderData/RenderRow.vue
@@ -0,0 +1,202 @@
+
+
+
+
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+
+ {{ finalDbs.length }}
+
+
+
+ {{ t('自动生成') }}
+
+ |
+
+
+
+
+
+
+
+
diff --git a/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page2/Index.vue b/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page2/Index.vue
new file mode 100644
index 0000000000..30b0074794
--- /dev/null
+++ b/dbm-ui/frontend/src/views/sqlserver-manage/db-backup/pages/page2/Index.vue
@@ -0,0 +1,86 @@
+
+
+
+
+
+ {{ t('数据库备份任务提交成功') }}
+
+
+
+ {{ t('我的服务单') }}
+
+
+
+
+ {{ t('去看看') }}
+
+
+ {{ t('继续提单') }}
+
+
+
+
+
+
diff --git a/dbm-ui/frontend/src/views/sqlserver-manage/ha-cluster-list/components/List.vue b/dbm-ui/frontend/src/views/sqlserver-manage/ha-cluster-list/components/List.vue
index effdabd2bd..b6d329d9a8 100644
--- a/dbm-ui/frontend/src/views/sqlserver-manage/ha-cluster-list/components/List.vue
+++ b/dbm-ui/frontend/src/views/sqlserver-manage/ha-cluster-list/components/List.vue
@@ -97,8 +97,8 @@
+ :settings="settings"
+ @selection="handleSelection"
+ @setting-change="updateTableSettings" />
+ :cluster-type="ClusterTypes.SQLSERVER_HA"
+ :ticket-type="TicketTypes.SQLSERVER_EXCEL_AUTHORIZE_RULES"/>
+
diff --git a/dbm-ui/frontend/src/views/sqlserver-manage/permission/components/AccountDialog.vue b/dbm-ui/frontend/src/views/sqlserver-manage/permission/components/AccountDialog.vue
index a38301f706..b3ca86d255 100644
--- a/dbm-ui/frontend/src/views/sqlserver-manage/permission/components/AccountDialog.vue
+++ b/dbm-ui/frontend/src/views/sqlserver-manage/permission/components/AccountDialog.vue
@@ -106,6 +106,7 @@
} from '@services/permission';
import { createSqlserverAccount } from '@services/source/sqlserverPermissionAccount';
+ import { AccountTypes } from '@common/const';
import { dbTippy } from '@common/tippy';
import { messageSuccess } from '@utils';
@@ -408,6 +409,7 @@
runCreateAccount({
password: getEncryptPassword(),
user: formData.user,
+ account_type: AccountTypes.SQLSERVER
});
};
diff --git a/dbm-ui/frontend/src/views/sqlserver-manage/permission/components/CreateRule.vue b/dbm-ui/frontend/src/views/sqlserver-manage/permission/components/CreateRule.vue
index 927c0789b3..27b342930c 100644
--- a/dbm-ui/frontend/src/views/sqlserver-manage/permission/components/CreateRule.vue
+++ b/dbm-ui/frontend/src/views/sqlserver-manage/permission/components/CreateRule.vue
@@ -6,7 +6,7 @@
:width="640"
@closed="handleClose">
handleSelectAllPrivileges(value)">
- db_owner({{ t('包含所有权限,其他权限无需授予') }})
+ db_owner ( {{ t('包含所有权限,其他权限无需授予') }} )
@@ -113,22 +113,26 @@
import { useI18n } from 'vue-i18n';
import { useRequest } from 'vue-request';
+ import SqlserverPermissionAccountModel from '@services/model/sqlserver-permission/sqlserver-permission-account';
import {
addSqlserverAccountRule,
querySqlserverAccountRules,
} from '@services/source/sqlserverPermissionAccount';
- import type { PermissionRuleAccount } from '@services/types/permission';
import {
useInfo,
useStickyFooter,
} from '@hooks';
+ import DbForm from '@components/db-form/index.vue'
+
import { messageSuccess } from '@utils';
+ import { AccountTypes } from '@/common/const';
+
interface Props {
accountId: number
- accountMapList: PermissionRuleAccount[]
+ accountMapList: SqlserverPermissionAccountModel['account'][]
dbOperations: string[]
}
@@ -147,14 +151,14 @@
default: false,
});
- const ruleRef = ref();
+ const formRef = ref>();
const checkAllPrivileges = ref(false);
- const existDBs = ref();
+ const existDBs = ref([]);
const textareaRef = ref();
const textareaHeight = ref(0);
/** 设置底部按钮粘性布局 */
- useStickyFooter(ruleRef);
+ useStickyFooter(formRef);
const { t } = useI18n();
@@ -170,19 +174,27 @@
/**
* 校验规则重复性
*/
- const verifyAccountRules = async () => {
+ const verifyAccountRules = () => {
+ existDBs.value = [];
+
+ const userInfo = props.accountMapList.find((item) => item.account_id === formData.account_id)
const dbs = formData.access_db.replace(/\n|;/g, ',')
.split(',')
.filter(db => db);
- if (!dbs.length) {
+
+ if (!userInfo || dbs.length === 0) {
return false;
}
- const res = await querySqlserverAccountRules({
- user: String(formData.account_id),
+
+ return querySqlserverAccountRules({
+ user: userInfo.user,
access_dbs: dbs,
- });
- existDBs.value = res.results[0].rules.map(item => item.access_db);
- return !res.results[0].rules.length;
+ })
+ .then((res) => {
+ const rules = res.results[0]?.rules || [];
+ existDBs.value = rules.map(item => item.access_db);
+ return rules.length === 0;
+ });
};
const rules = {
@@ -202,7 +214,7 @@
},
{
trigger: 'blur',
- message: () => t('该账号下已存在xx规则', [existDBs.value?.join(',')]),
+ message: () => t('该账号下已存在xx规则', [existDBs.value.join(',')]),
validator: verifyAccountRules,
},
],
@@ -214,7 +226,7 @@
const {
loading: isSubmitting,
- run: runaddSqlserverAccountRule,
+ run: addSqlserverAccountRuleRun,
} = useRequest(addSqlserverAccountRule, {
manual: true,
onSuccess() {
@@ -294,16 +306,23 @@
* 提交功能
*/
const handleSubmit = async () => {
- await ruleRef.value.validate();
- if (checkAllPrivileges.value) {
- // 包含所有权限
- formData.privilege = ['all privileges'];
- }
- runaddSqlserverAccountRule({
+ await formRef.value!.validate();
+ const params = {
access_db: formData.access_db.replace(/\n|;/g, ','), // 统一分隔符
- privilege: formData.privilege,
+ privilege: {},
account_id: formData.account_id,
- });
+ account_type: AccountTypes.SQLSERVER
+ }
+ if (checkAllPrivileges.value) {
+ Object.assign(params.privilege, {
+ sqlserver_owner: ['db_owner']
+ })
+ } else {
+ Object.assign(params.privilege, {
+ sqlserver_dml: formData.privilege
+ })
+ }
+ addSqlserverAccountRuleRun(params);
};
@@ -363,13 +382,9 @@
.check-all {
position: relative;
- width: 48px;
+ width: 50px;
margin-right: 48px;
- :deep(.bk-checkbox-label) {
- font-weight: bold;
- }
-
&::after {
position: absolute;
top: 50%;
diff --git a/dbm-ui/frontend/src/views/sqlserver-manage/routes.ts b/dbm-ui/frontend/src/views/sqlserver-manage/routes.ts
index a14dfd7b66..5f276c1188 100644
--- a/dbm-ui/frontend/src/views/sqlserver-manage/routes.ts
+++ b/dbm-ui/frontend/src/views/sqlserver-manage/routes.ts
@@ -42,6 +42,14 @@ const routes: RouteRecordRaw[] = [
},
component: () => import('@views/sqlserver-manage/permission/Index.vue'),
},
+ {
+ name: 'SqlServerDbBackup',
+ path: 'sqlserver-db-backup/:page?',
+ meta: {
+ navName: t('数据库备份'),
+ },
+ component: () => import('@views/sqlserver-manage/db-backup/Index.vue'),
+ },
],
},
];
diff --git a/dbm-ui/frontend/src/views/sqlserver-manage/single-cluster/components/List.vue b/dbm-ui/frontend/src/views/sqlserver-manage/single-cluster/components/List.vue
index fe89ad0164..e2ca87e1f9 100644
--- a/dbm-ui/frontend/src/views/sqlserver-manage/single-cluster/components/List.vue
+++ b/dbm-ui/frontend/src/views/sqlserver-manage/single-cluster/components/List.vue
@@ -97,8 +97,8 @@
@@ -108,20 +108,29 @@
:data-source="getSingleClusterList"
:row-class="setRowClass"
selectable
- @selection="handleSelection" />
+ :settings="settings"
+ @selection="handleSelection"
+ @setting-change="updateTableSettings" />
+ :cluster-type="ClusterTypes.SQLSERVER_SINGLE"
+ :ticket-type="TicketTypes.SQLSERVER_EXCEL_AUTHORIZE_RULES"/>
+
+
+
+
diff --git a/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/sqlserver/ClusterOperation.vue b/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/sqlserver/ClusterOperation.vue
new file mode 100644
index 0000000000..e3b8fb5625
--- /dev/null
+++ b/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/sqlserver/ClusterOperation.vue
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
diff --git a/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/sqlserver/ClusterReset.vue b/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/sqlserver/ClusterReset.vue
new file mode 100644
index 0000000000..3d9ee2d959
--- /dev/null
+++ b/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/sqlserver/ClusterReset.vue
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
diff --git a/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/sqlserver/DbBackup.vue b/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/sqlserver/DbBackup.vue
new file mode 100644
index 0000000000..221796a06b
--- /dev/null
+++ b/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/sqlserver/DbBackup.vue
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
+
+
diff --git a/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/sqlserver/Details.vue b/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/sqlserver/Details.vue
new file mode 100644
index 0000000000..401037dcf2
--- /dev/null
+++ b/dbm-ui/frontend/src/views/tickets/common/components/demand-factory/sqlserver/Details.vue
@@ -0,0 +1,198 @@
+
+
+
+
+
+
+
+
+
diff --git a/dbm-ui/frontend/src/views/version-files/list/Index.vue b/dbm-ui/frontend/src/views/version-files/list/Index.vue
index c026d36d9f..f5ae952e96 100644
--- a/dbm-ui/frontend/src/views/version-files/list/Index.vue
+++ b/dbm-ui/frontend/src/views/version-files/list/Index.vue
@@ -294,6 +294,19 @@
},
],
},
+ {
+ controller: {
+ moduleId: 'sqlserver',
+ },
+ label: 'SQLServer',
+ name: DBTypes.SQLSERVER,
+ children: [
+ {
+ label: 'SQLServer',
+ name: DBTypes.SQLSERVER,
+ },
+ ],
+ },
];
const renderTabs = tabs.filter((item) => {