Commit abf6965e authored by nick zheng's avatar nick zheng

chore(数据库管理): 对接接口&&多语言

parent a46132ab
import { request } from '@/utils/request'
import { DefaultPaginationData } from '@/composables/usePagination'
/**
* @param payload 数据库参数
* @returns 新建知识库
*/
export function fetchCreateDataBase<T>(payload: object) {
return request.post<T>('/databaseRest/create.json', payload)
}
/**
* @param payload 连接数据库参数
* @returns 连接数据库
*/
export function fetchTestConnectionDataBase<T>(payload: object) {
return request.post<T>('/databaseRest/testConnection.json', payload)
}
/**
* @params search 搜索值
* @returns 获取数据库列表
*/
export function fetchGetDataBaseList<T>(payload: { search: string; pagingInfo: DefaultPaginationData }) {
return request.post<T>('/databaseRest/getList.json', payload)
}
/**
* @query id 数据库Id
* @returns 删除数据库
*/
export function fetchDeleteDataBaseById<T>(id: number) {
return request.post<T>(`/databaseRest/delete.json?id=${id}`)
}
/**
* @param payload 数据库参数
* @returns 更新数据库信息
*/
export function handleUpdateDataBase<T>(payload: object) {
return request.post<T>('/databaseRest/update.json', payload)
}
/**
*
* @param id 数据库Id
* @returns 获取数据库详情
*/
export function fetchGetDataBaseDetail<T>(id: string) {
return request.post<T>(`/databaseRest/getDetail.json?id=${id}`)
}
...@@ -154,6 +154,7 @@ common_module: ...@@ -154,6 +154,7 @@ common_module:
authenticated: 'Authenticated' authenticated: 'Authenticated'
cancel_authorization: 'Cancel authorization' cancel_authorization: 'Cancel authorization'
get_code: 'Get Code' get_code: 'Get Code'
database: 'Database'
dialogue_module: dialogue_module:
continue_question_message: 'You can keep asking questions' continue_question_message: 'You can keep asking questions'
...@@ -214,6 +215,7 @@ router_title_module: ...@@ -214,6 +215,7 @@ router_title_module:
data_statistic: 'Data statistic' data_statistic: 'Data statistic'
plugin_center: 'Plugin center' plugin_center: 'Plugin center'
reset_password: 'Reset password' reset_password: 'Reset password'
database: 'Database'
login_module: login_module:
app_welcome_words: 'Hi, welcome to Model Link' app_welcome_words: 'Hi, welcome to Model Link'
...@@ -615,6 +617,36 @@ personal_space_module: ...@@ -615,6 +617,36 @@ personal_space_module:
upload_QA_format_error_message: 'Only xls and xlsx files can be uploaded. Please upload them again' upload_QA_format_error_message: 'Only xls and xlsx files can be uploaded. Please upload them again'
download_QA_template: 'Download Q&A Template' download_QA_template: 'Download Q&A Template'
database_module:
create_database: 'Create database'
edit_database: 'Edit database'
creation_method: 'Creation method'
direct_database_connection: 'Direct database connection'
db_title: 'Database title'
db_desc: 'Database description'
db_source_info: 'Database source info'
db_source_type: 'Database source type'
db_host: 'Database host'
db_port: 'Database port'
db_name: 'Database name'
db_username: 'Database username'
db_password: 'Database password'
please_enter_db_title: 'Please enter database title'
please_enter_db_desc: 'Please enter database description (for identification only, does not affect database operations)'
please_select_db_source_type: 'Please select database source type'
please_enter_db_host: 'Please enter IP address or domain name'
please_enter_db_port: 'Please enter database port'
please_enter_db_name: 'Please enter database name'
please_enter_db_username: 'Please enter database username'
please_enter_db_password: 'Please enter database password'
db_title_rule: 'Only Chinese characters, English letters, numbers, underscores (_), hyphens (-), and dots (.) are supported'
db_host_rule: 'The database source Host must be a public network address'
connect_test: 'Connection Test'
connect_test_success: 'Database connection successful'
connect_test_fail: 'Database connection failed. Please verify your input'
connect_test_must_pass_to_create: 'Connect test must pass to create'
connect_test_must_pass_to_update: 'Connect test must pass to update'
share_agent_module: share_agent_module:
please: 'Please first' please: 'Please first'
after_action: 'Then start asking questions' after_action: 'Then start asking questions'
......
...@@ -153,7 +153,7 @@ common_module: ...@@ -153,7 +153,7 @@ common_module:
authenticated: '已认证' authenticated: '已认证'
cancel_authorization: '取消授权' cancel_authorization: '取消授权'
get_code: '获取验证码' get_code: '获取验证码'
database: '数据库'
dialogue_module: dialogue_module:
continue_question_message: '你可以继续提问' continue_question_message: '你可以继续提问'
...@@ -214,6 +214,7 @@ router_title_module: ...@@ -214,6 +214,7 @@ router_title_module:
data_statistic: '数据统计' data_statistic: '数据统计'
plugin_center: '插件中心' plugin_center: '插件中心'
reset_password: '重置密码' reset_password: '重置密码'
database: '数据库'
login_module: login_module:
app_welcome_words: 'Hi, 欢迎使用Model Link' app_welcome_words: 'Hi, 欢迎使用Model Link'
...@@ -614,6 +615,36 @@ personal_space_module: ...@@ -614,6 +615,36 @@ personal_space_module:
upload_QA_format_error_message: '只能上传xls,xlsx格式文件,请重新上传' upload_QA_format_error_message: '只能上传xls,xlsx格式文件,请重新上传'
download_QA_template: '下载问答模版' download_QA_template: '下载问答模版'
database_module:
create_database: '创建数据库'
edit_database: '编辑数据库'
creation_method: '创建方式'
direct_database_connection: '直连数据库'
db_title: '数据库名称'
db_desc: '数据库描述'
db_source_info: '数据源信息'
db_source_type: '数据源类型'
db_host: '数据库地址host'
db_port: '端口号'
db_name: '数据库名'
db_username: '用户名'
db_password: '密码'
please_enter_db_title: '请输入数据库名称'
please_enter_db_desc: '请输入数据库描述,此描述仅用于区分不同数据库,不会影响数据库调用'
please_select_db_source_type: '请选择数据源类型'
please_enter_db_host: '请输入IP地址或域名'
please_enter_db_port: '请输入端口号'
please_enter_db_name: '请输入数据库名'
please_enter_db_username: '请输入用户名'
please_enter_db_password: '请输入密码'
db_title_rule: '仅支持中文、英文、数字、下划线(_)、中划线(-)、英文点(.)'
db_host_rule: '输入的数据源Host必须是公网地址'
connect_test: '连接测试'
connect_test_success: '数据库连接成功'
connect_test_fail: '无法联通数据库,请检查填写内容'
connect_test_must_pass_to_create: '测试通过才能创建'
connect_test_must_pass_to_update: '测试通过才能更新'
share_agent_module: share_agent_module:
please: '请先' please: '请先'
after_action: '后开始提问' after_action: '后开始提问'
......
...@@ -153,6 +153,7 @@ common_module: ...@@ -153,6 +153,7 @@ common_module:
authenticated: '已認證' authenticated: '已認證'
cancel_authorization: '取消授權' cancel_authorization: '取消授權'
get_code: '獲取驗証碼' get_code: '獲取驗証碼'
database: '數據庫'
dialogue_module: dialogue_module:
continue_question_message: '你可以繼續提問' continue_question_message: '你可以繼續提問'
...@@ -213,6 +214,7 @@ router_title_module: ...@@ -213,6 +214,7 @@ router_title_module:
data_statistic: '數據統計' data_statistic: '數據統計'
plugin_center: '插件中心' plugin_center: '插件中心'
reset_password: '重置密碼' reset_password: '重置密碼'
database: '數據庫'
login_module: login_module:
app_welcome_words: 'Hi, 歡迎使用Model Link' app_welcome_words: 'Hi, 歡迎使用Model Link'
...@@ -613,6 +615,36 @@ personal_space_module: ...@@ -613,6 +615,36 @@ personal_space_module:
upload_QA_format_error_message: '只能上傳xls,xlsx格式文件,請重新上傳' upload_QA_format_error_message: '只能上傳xls,xlsx格式文件,請重新上傳'
download_QA_template: '下載問答模版' download_QA_template: '下載問答模版'
database_module:
create_database: '創建數據庫'
edit_database: '編輯數據庫'
creation_method: '創建方式'
direct_database_connection: '直連數據庫'
db_title: '數據庫名稱'
db_desc: '數據庫描述'
db_source_info: '數據源信息'
db_source_type: '數據源類型'
db_host: '數據庫地址host'
db_port: '端口號'
db_name: '數據庫名'
db_username: '用户名'
db_password: '密碼'
please_enter_db_title: '請輸入數據庫名稱'
please_enter_db_desc: '請輸入數據庫描述,此描述僅用於區分不同數據庫,不會影響數據庫調用'
please_select_db_source_type: '請選擇數據源類型'
please_enter_db_host: '請輸入IP地址或域名'
please_enter_db_port: '請輸入端口號'
please_enter_db_name: '請輸入數據庫名'
please_enter_db_username: '請輸入用户名'
please_enter_db_password: '請輸入密碼'
db_title_rule: '僅支持中文、英文、數字、下劃線(_)、中劃線(-)、英文點(.)'
db_host_rule: '輸入的數據源Host必須是公網地址'
connect_test: '連接測試'
connect_test_success: '數據庫連接成功'
connect_test_fail: '無法聯通數據庫,請檢查填寫內容'
connect_test_must_pass_to_create: '測試通過才能創建'
connect_test_must_pass_to_update: '測試通過才能更新'
share_agent_module: share_agent_module:
please: '請先' please: '請先'
after_action: '後開始提問' after_action: '後開始提問'
......
...@@ -50,7 +50,7 @@ export default [ ...@@ -50,7 +50,7 @@ export default [
name: 'PersonalSpaceDatabase', name: 'PersonalSpaceDatabase',
meta: { meta: {
rank: 1001, rank: 1001,
title: '数据库', title: 'router_title_module.database',
belong: 'PersonalSpace', belong: 'PersonalSpace',
}, },
component: () => import('@/views/personal-space/personal-database/personal-database.vue'), component: () => import('@/views/personal-space/personal-database/personal-database.vue'),
......
...@@ -6,7 +6,7 @@ const t = i18n.global.t ...@@ -6,7 +6,7 @@ const t = i18n.global.t
export function createDatabaseColumn(handleDatabaseTableAction: (actionType: string, databaseId: number) => void) { export function createDatabaseColumn(handleDatabaseTableAction: (actionType: string, databaseId: number) => void) {
return [ return [
{ {
title: () => <span>数据库名称</span>, title: () => <span>{t('personal_space_module.database_module.db_title')}</span>,
key: 'databaseName', key: 'databaseName',
align: 'left', align: 'left',
ellipsis: { ellipsis: {
...@@ -19,7 +19,7 @@ export function createDatabaseColumn(handleDatabaseTableAction: (actionType: str ...@@ -19,7 +19,7 @@ export function createDatabaseColumn(handleDatabaseTableAction: (actionType: str
}, },
}, },
{ {
title: () => <span>数据库描述</span>, title: () => <span>{t('personal_space_module.database_module.db_desc')}</span>,
key: 'databaseDesc', key: 'databaseDesc',
align: 'left', align: 'left',
ellipsis: { ellipsis: {
...@@ -31,7 +31,7 @@ export function createDatabaseColumn(handleDatabaseTableAction: (actionType: str ...@@ -31,7 +31,7 @@ export function createDatabaseColumn(handleDatabaseTableAction: (actionType: str
}, },
}, },
{ {
title: () => <span>编辑时间</span>, title: () => <span>{t('common_module.modified_time')}</span>,
key: 'updateTime', key: 'updateTime',
align: 'left', align: 'left',
ellipsis: { ellipsis: {
...@@ -39,7 +39,7 @@ export function createDatabaseColumn(handleDatabaseTableAction: (actionType: str ...@@ -39,7 +39,7 @@ export function createDatabaseColumn(handleDatabaseTableAction: (actionType: str
}, },
width: 170, width: 170,
render(row: DatabaseItemInterface) { render(row: DatabaseItemInterface) {
return row.updateTime ? formatDateTime(row.updateTime) : '--' return row.modifiedTime ? formatDateTime(row.modifiedTime) : '--'
}, },
}, },
{ {
......
<script setup lang="ts"> <script setup lang="ts">
import { FormInst, FormItemRule, FormRules, ScrollbarInst } from 'naive-ui' import { FormInst, FormItemRule, FormRules, ScrollbarInst } from 'naive-ui'
import { nextTick, reactive, readonly, ref, shallowReadonly, useTemplateRef } from 'vue' import { nextTick, reactive, readonly, ref, shallowReadonly, useTemplateRef, watch, watchEffect } from 'vue'
import { useI18n } from 'vue-i18n'
import CustomModal from '@/components/custom-modal/custom-modal.vue' import CustomModal from '@/components/custom-modal/custom-modal.vue'
import DatabaseDirectIcon from '@/assets/svgs/database-direct.svg' import DatabaseDirectIcon from '@/assets/svgs/database-direct.svg'
import { fetchTestConnectionDataBase } from '@/apis/database'
import { DatabaseItemInterface } from '../type.d'
interface Props {
btnLoading: boolean
}
type CreateDatabaseFormInterface = Omit<DatabaseItemInterface, 'id' | 'modifiedTime'>
defineProps<Props>()
const emit = defineEmits<{
(e: 'confirm', databaseFormData: CreateDatabaseFormInterface): void
}>()
const { t } = useI18n()
const showModal = defineModel<boolean>('showModal', { required: true }) const showModal = defineModel<boolean>('showModal', { required: true })
const databaseFormRef = ref<FormInst | null>(null) const databaseFormRef = ref<FormInst | null>(null)
const scrollbarRef = useTemplateRef<ScrollbarInst | null>('scrollbarRef') const scrollbarRef = useTemplateRef<ScrollbarInst | null>('scrollbarRef')
const databaseFormData = reactive({ let databaseFormData = reactive<CreateDatabaseFormInterface>(databaseFormDataFactory())
title: '',
desc: '',
dbType: 'MYSQL',
dbHost: '',
dbPort: '',
dbName: '',
dbUserName: '',
dbPassword: '',
})
const databaseFormRules = shallowReadonly<FormRules>({ const databaseFormRules = shallowReadonly<FormRules>({
title: [ title: [
...@@ -29,9 +37,9 @@ const databaseFormRules = shallowReadonly<FormRules>({ ...@@ -29,9 +37,9 @@ const databaseFormRules = shallowReadonly<FormRules>({
const pattern = /^[\u4e00-\u9fa5a-zA-Z0-9_\-\\.]+$/ const pattern = /^[\u4e00-\u9fa5a-zA-Z0-9_\-\\.]+$/
if (!value) { if (!value) {
return new Error('请输入数据库名称') return new Error(t('personal_space_module.database_module.please_enter_db_title'))
} else if (!pattern.test(value)) { } else if (!pattern.test(value)) {
return new Error('数据库名称仅支持中文、英文、数字、下划线(_)、中划线(-)、英文点(.)') return new Error(t('personal_space_module.database_module.db_title_rule'))
} }
return return
...@@ -39,12 +47,37 @@ const databaseFormRules = shallowReadonly<FormRules>({ ...@@ -39,12 +47,37 @@ const databaseFormRules = shallowReadonly<FormRules>({
trigger: 'blur', trigger: 'blur',
}, },
], ],
dbType: [{ required: true, message: '请选择数据源类型', trigger: 'blur' }], dbType: [
dbHost: [{ required: true, message: '请输入IP地址或域名', trigger: 'blur' }], {
dbPort: [{ required: true, message: '请输入端口号', trigger: 'blur' }], required: true,
dbName: [{ required: true, message: '请输入数据库名', trigger: 'blur' }], message: t('personal_space_module.database_module.please_select_db_source_type'),
dbUserName: [{ required: true, message: '请输入用户名', trigger: 'blur' }], trigger: 'blur',
dbPassword: [{ required: true, message: '请输入密码', trigger: 'blur' }], },
],
dbHost: [
{
required: true,
message: t('personal_space_module.database_module.please_enter_db_host'),
trigger: 'blur',
},
],
dbPort: [
{
required: true,
message: t('personal_space_module.database_module.please_enter_db_port'),
trigger: 'blur',
type: 'number',
},
],
dbName: [
{ required: true, message: t('personal_space_module.database_module.please_enter_db_name'), trigger: 'blur' },
],
dbUsername: [
{ required: true, message: t('personal_space_module.database_module.please_enter_db_username'), trigger: 'blur' },
],
dbPassword: [
{ required: true, message: t('personal_space_module.database_module.please_enter_db_password'), trigger: 'blur' },
],
}) })
const databaseTypeList = readonly([ const databaseTypeList = readonly([
...@@ -52,7 +85,7 @@ const databaseTypeList = readonly([ ...@@ -52,7 +85,7 @@ const databaseTypeList = readonly([
id: 'KJ7rCkq3HNOk', id: 'KJ7rCkq3HNOk',
icon: DatabaseDirectIcon, icon: DatabaseDirectIcon,
type: 'Direct', type: 'Direct',
name: '直连数据库', name: t('personal_space_module.database_module.direct_database_connection'),
}, },
]) ])
...@@ -63,18 +96,74 @@ const databaseSourceTypeOptions = [ ...@@ -63,18 +96,74 @@ const databaseSourceTypeOptions = [
}, },
] ]
const isConnectDatabaseSuccess = ref(false) const isConnectDBSuccess = ref(false)
const showConnectStatus = ref(false) const showConnectStatus = ref(false)
const connectBtnLoading = ref(false)
watch(
() => [
databaseFormData.dbType,
databaseFormData.dbHost,
databaseFormData.dbPort,
databaseFormData.dbName,
databaseFormData.dbUsername,
databaseFormData.dbPassword,
],
() => {
showConnectStatus.value = false
isConnectDBSuccess.value = false
},
)
watchEffect(() => {
if (showModal.value) {
databaseFormData = Object.assign(databaseFormData, databaseFormDataFactory())
showConnectStatus.value = false
isConnectDBSuccess.value = false
}
})
function databaseFormDataFactory(): CreateDatabaseFormInterface {
return {
title: '',
desc: '',
dbType: 'MYSQL',
dbHost: '',
dbPort: 3306,
dbName: '',
dbUsername: '',
dbPassword: '',
}
}
function handleConnectDatabase() { function handleConnectDatabase() {
databaseFormRef.value?.validate( databaseFormRef.value?.validate(
(errors) => { async (errors) => {
if (!errors) { if (!errors) {
const { dbType, dbHost, dbPort, dbName, dbUsername, dbPassword } = databaseFormData
const payload = {
dbType,
dbHost,
dbPort,
dbName,
dbUsername,
dbPassword,
}
connectBtnLoading.value = true
const res = await fetchTestConnectionDataBase<{ status: 'success' | 'fail' }>(payload).finally(() => {
showConnectStatus.value = true showConnectStatus.value = true
isConnectDatabaseSuccess.value = false connectBtnLoading.value = false
nextTick(() => { nextTick(() => {
scrollbarRef.value?.scrollTo({ top: 9999, behavior: 'smooth' }) scrollbarRef.value?.scrollTo({ top: 9999, behavior: 'smooth' })
}) })
})
if (res.code === 0) {
isConnectDBSuccess.value = res.data.status === 'success'
}
} }
}, },
(rule) => { (rule) => {
...@@ -86,7 +175,12 @@ function handleConnectDatabase() { ...@@ -86,7 +175,12 @@ function handleConnectDatabase() {
function handleCreateDatabase() { function handleCreateDatabase() {
databaseFormRef.value?.validate((errors) => { databaseFormRef.value?.validate((errors) => {
if (!errors) { if (!errors) {
// TODO if (!isConnectDBSuccess.value) {
window.$message.warning(t('personal_space_module.database_module.connect_test_must_pass_to_create'))
return
}
emit('confirm', databaseFormData)
} }
}) })
} }
...@@ -95,42 +189,49 @@ function handleCreateDatabase() { ...@@ -95,42 +189,49 @@ function handleCreateDatabase() {
<template> <template>
<CustomModal <CustomModal
v-model:is-show="showModal" v-model:is-show="showModal"
:title="'创建知识库'" :title="t('personal_space_module.database_module.create_database')"
:width="534" :width="534"
:confirm-btn-text="'创建'" :confirm-btn-text="t('common_module.create')"
:btn-loading="btnLoading"
@confirm="handleCreateDatabase" @confirm="handleCreateDatabase"
> >
<template #content> <template #content>
<n-scrollbar ref="scrollbarRef" style="max-height: 550px"> <n-scrollbar ref="scrollbarRef" style="max-height: 550px">
<n-form ref="databaseFormRef" :model="databaseFormData" :rules="databaseFormRules"> <n-form ref="databaseFormRef" :model="databaseFormData" :rules="databaseFormRules">
<n-form-item label="创建方式"> <n-form-item :label="t('personal_space_module.database_module.creation_method')">
<div <div
v-for="databaseTypeItem in databaseTypeList" v-for="databaseTypeItem in databaseTypeList"
:key="databaseTypeItem.id" :key="databaseTypeItem.id"
class="flex-center border-theme-color rounded-theme text-theme-color h-[66px] w-[110px] cursor-pointer flex-col gap-[2px] border" class="flex-center border-theme-color rounded-theme text-theme-color h-[66px] min-w-[110px] cursor-pointer flex-col gap-[2px] border px-2.5"
> >
<img :src="databaseTypeItem.icon" class="h-6 w-6" /> <img :src="databaseTypeItem.icon" class="h-6 w-6" />
<n-ellipsis>
<span>{{ databaseTypeItem.name }}</span> <span>{{ databaseTypeItem.name }}</span>
</n-ellipsis>
</div> </div>
</n-form-item> </n-form-item>
<n-form-item label="数据库名称" path="title" :feedback-style="{ fontSize: '13px' }"> <n-form-item
path="title"
:label="t('personal_space_module.database_module.db_title')"
:feedback-style="{ fontSize: '13px' }"
>
<div class="flex w-full flex-col"> <div class="flex w-full flex-col">
<n-input <n-input
v-model:value="databaseFormData.title" v-model:value="databaseFormData.title"
placeholder="请输入数据库名称" :placeholder="t('personal_space_module.database_module.please_enter_db_title')"
show-count show-count
:maxlength="50" :maxlength="50"
/> />
<span class="text-gray-font-color mt-1 px-2.5 text-[12px]"> <span class="text-gray-font-color mt-1 px-2.5 text-[12px]">
仅支持中文、英文、数字、下划线(_)、中划线(-)、英文点(.) {{ t('personal_space_module.database_module.db_title_rule') }}
</span> </span>
</div> </div>
</n-form-item> </n-form-item>
<n-form-item label="数据库描述"> <n-form-item :label="t('personal_space_module.database_module.db_desc')">
<n-input <n-input
v-model:value="databaseFormData.desc" v-model:value="databaseFormData.desc"
placeholder="请输入数据库描述,此描述仅用于区分不同数据库,不会影响数据库调用" :placeholder="t('personal_space_module.database_module.please_enter_db_desc')"
show-count show-count
:maxlength="100" :maxlength="100"
type="textarea" type="textarea"
...@@ -138,43 +239,86 @@ function handleCreateDatabase() { ...@@ -138,43 +239,86 @@ function handleCreateDatabase() {
/> />
</n-form-item> </n-form-item>
<h3 class="font-family-medium mb-4 text-[18px]">数据源信息</h3> <h3 class="font-family-medium mb-4 text-[18px]">
{{ t('personal_space_module.database_module.db_source_info') }}
</h3>
<n-form-item label="数据源类型" path="dbType" :feedback-style="{ fontSize: '13px' }"> <n-form-item
path="dbType"
:label="t('personal_space_module.database_module.db_source_type')"
:feedback-style="{ fontSize: '13px' }"
>
<n-select <n-select
v-model:value="databaseFormData.dbType" v-model:value="databaseFormData.dbType"
placeholder="请选择数据源类型" :placeholder="t('personal_space_module.database_module.please_select_db_source_type')"
:options="databaseSourceTypeOptions" :options="databaseSourceTypeOptions"
/> />
</n-form-item> </n-form-item>
<n-form-item label="数据库地址host" path="dbHost" :feedback-style="{ fontSize: '13px' }"> <n-form-item
path="dbHost"
:label="t('personal_space_module.database_module.db_host')"
:feedback-style="{ fontSize: '13px' }"
>
<div class="flex w-full flex-col"> <div class="flex w-full flex-col">
<n-input v-model:value="databaseFormData.dbHost" placeholder="请输入IP地址或域名" /> <n-input
v-model:value="databaseFormData.dbHost"
:placeholder="t('personal_space_module.database_module.please_enter_db_host')"
/>
<span class="mt-1 px-2.5 text-[13px] text-[#6F77FF]"> <span class="mt-1 px-2.5 text-[13px] text-[#6F77FF]">
输入的数据源Host必须是公网地址,以百度云GaiaDB数据库为例,请参考文档进行配置 {{ t('personal_space_module.database_module.db_host_rule') }}
</span> </span>
</div> </div>
</n-form-item> </n-form-item>
<n-form-item label="端口号" path="dbPort" :feedback-style="{ fontSize: '13px' }"> <n-form-item
<n-input v-model:value="databaseFormData.dbPort" placeholder="请输入端口号" /> path="dbPort"
:label="t('personal_space_module.database_module.db_port')"
:feedback-style="{ fontSize: '13px' }"
>
<n-input-number
v-model:value="databaseFormData.dbPort"
class="w-full"
:placeholder="t('personal_space_module.database_module.please_enter_db_port')"
:show-button="false"
:max="65535"
:min="1"
/>
</n-form-item> </n-form-item>
<n-form-item label="数据库名" path="dbName" :feedback-style="{ fontSize: '13px' }"> <n-form-item
<n-input v-model:value="databaseFormData.dbName" placeholder="请输入数据库名" /> path="dbName"
:label="t('personal_space_module.database_module.db_name')"
:feedback-style="{ fontSize: '13px' }"
>
<n-input
v-model:value="databaseFormData.dbName"
:placeholder="t('personal_space_module.database_module.please_enter_db_name')"
/>
</n-form-item> </n-form-item>
<n-form-item label="用户名" path="dbUserName" :feedback-style="{ fontSize: '13px' }"> <n-form-item
<n-input v-model:value="databaseFormData.dbUserName" placeholder="请输入用户名" /> path="dbUsername"
:label="t('personal_space_module.database_module.db_username')"
:feedback-style="{ fontSize: '13px' }"
>
<n-input
v-model:value="databaseFormData.dbUsername"
:placeholder="t('personal_space_module.database_module.please_enter_db_username')"
/>
</n-form-item> </n-form-item>
<n-form-item label="密码" path="dbPassword" :feedback-style="{ fontSize: '13px' }"> <n-form-item
path="dbPassword"
:label="t('personal_space_module.database_module.db_password')"
:feedback-style="{ fontSize: '13px' }"
>
<n-input <n-input
v-model:value="databaseFormData.dbPassword" v-model:value="databaseFormData.dbPassword"
type="password" type="password"
show-password-on="click" show-password-on="click"
placeholder="请输入密码" :input-props="{ autocomplete: 'off' }"
:placeholder="t('personal_space_module.database_module.please_enter_db_password')"
class="font-sans" class="font-sans"
/> />
</n-form-item> </n-form-item>
...@@ -183,11 +327,15 @@ function handleCreateDatabase() { ...@@ -183,11 +327,15 @@ function handleCreateDatabase() {
<div <div
v-show="showConnectStatus" v-show="showConnectStatus"
class="flex items-center gap-[8px] rounded-[10px] px-3 py-[5px]" class="flex items-center gap-[8px] rounded-[10px] px-3 py-[5px]"
:class="isConnectDatabaseSuccess ? 'bg-[#ECFFE6]' : 'bg-[#FFE8E6]'" :class="isConnectDBSuccess ? 'bg-[#ECFFE6]' : 'bg-[#FFE8E6]'"
> >
<div class="h-[16px] w-[16px]" :class="isConnectDatabaseSuccess ? 'bg-svg-success' : 'bg-svg-error'" /> <div class="h-[16px] w-[16px]" :class="isConnectDBSuccess ? 'bg-svg-success' : 'bg-svg-error'" />
<span class="text-[12px] leading-[16px]"> <span class="text-[12px] leading-[16px]">
{{ isConnectDatabaseSuccess ? '数据库连接成功' : '无法联通数据库,请检查填写内容' }} {{
isConnectDBSuccess
? t('personal_space_module.database_module.connect_test_success')
: t('personal_space_module.database_module.connect_test_fail')
}}
</span> </span>
</div> </div>
...@@ -198,9 +346,10 @@ function handleCreateDatabase() { ...@@ -198,9 +346,10 @@ function handleCreateDatabase() {
class="h-[34px]!" class="h-[34px]!"
:bordered="false" :bordered="false"
:focusable="false" :focusable="false"
:loading="connectBtnLoading"
@click="handleConnectDatabase" @click="handleConnectDatabase"
> >
连接测试 {{ t('personal_space_module.database_module.connect_test') }}
</n-button> </n-button>
</div> </div>
</n-scrollbar> </n-scrollbar>
......
<script setup lang="ts"> <script setup lang="ts">
import { FormInst, FormRules, ScrollbarInst } from 'naive-ui' import { FormInst, FormItemRule, FormRules, ScrollbarInst } from 'naive-ui'
import { nextTick, reactive, ref, shallowReadonly, useTemplateRef } from 'vue' import { nextTick, reactive, ref, shallowReadonly, useTemplateRef, watch, watchEffect } from 'vue'
import { useI18n } from 'vue-i18n'
import CustomModal from '@/components/custom-modal/custom-modal.vue' import CustomModal from '@/components/custom-modal/custom-modal.vue'
import { DatabaseItemInterface } from '../type.d'
import { fetchTestConnectionDataBase } from '@/apis/database'
interface Props {
databaseDetail: DatabaseItemInterface
btnLoading: boolean
}
const props = defineProps<Props>()
const emit = defineEmits<{
(e: 'confirm', databaseFormData: DatabaseItemInterface): void
}>()
const { t } = useI18n()
const showModal = defineModel<boolean>('showModal', { required: true }) const showModal = defineModel<boolean>('showModal', { required: true })
const databaseFormRef = ref<FormInst | null>(null) const databaseFormRef = ref<FormInst | null>(null)
const scrollbarRef = useTemplateRef<ScrollbarInst | null>('scrollbarRef') const scrollbarRef = useTemplateRef<ScrollbarInst | null>('scrollbarRef')
const databaseFormData = reactive({ let databaseFormData = reactive<DatabaseItemInterface>(databaseFormDataFactory())
title: 'test',
desc: '',
dbType: 'MySQL',
dbHost: '125.88.205.65',
dbPort: '8080',
dbName: 'xxxx',
dbUserName: 'root',
dbPassword: '88888',
})
const databaseFormRules = shallowReadonly<FormRules>({ const databaseFormRules = shallowReadonly<FormRules>({
title: [{ required: true, message: '请输入数据库名称', trigger: 'blur' }], title: [
dbPassword: [{ required: true, message: '请输入密码', trigger: 'blur' }], {
key: 'title',
required: true,
validator: (_rule: FormItemRule, value: string) => {
const pattern = /^[\u4e00-\u9fa5a-zA-Z0-9_\-\\.]+$/
if (!value) {
return new Error(t('personal_space_module.database_module.please_enter_db_title'))
} else if (!pattern.test(value)) {
return new Error(t('personal_space_module.database_module.db_title_rule'))
}
return
},
trigger: 'blur',
},
],
dbPassword: [
{ required: true, message: t('personal_space_module.database_module.please_enter_db_password'), trigger: 'blur' },
],
}) })
const isConnectDatabaseSuccess = ref(false) const isConnectDBSuccess = ref(false)
const showConnectStatus = ref(false) const showConnectStatus = ref(false)
const connectBtnLoading = ref(false)
watchEffect(() => {
if (showModal.value) {
databaseFormData = Object.assign(databaseFormData, props.databaseDetail)
showConnectStatus.value = false
isConnectDBSuccess.value = false
}
})
watch(
() => [databaseFormData.dbPassword],
() => {
showConnectStatus.value = false
isConnectDBSuccess.value = false
},
)
function databaseFormDataFactory(): DatabaseItemInterface {
return {
id: 0,
title: '',
desc: '',
dbType: '',
dbHost: '',
dbPort: 0,
dbName: '',
dbUsername: '',
dbPassword: '',
modifiedTime: new Date(),
}
}
function handleConnectDatabase() { function handleConnectDatabase() {
databaseFormRef.value?.validate( databaseFormRef.value?.validate(
(errors) => { async (errors) => {
if (!errors) { if (!errors) {
const { dbType, dbHost, dbPort, dbName, dbUsername, dbPassword } = databaseFormData
const payload = {
dbType,
dbHost,
dbPort,
dbName,
dbUsername,
dbPassword,
}
connectBtnLoading.value = true
const res = await fetchTestConnectionDataBase<{ status: 'success' | 'fail' }>(payload).finally(() => {
showConnectStatus.value = true showConnectStatus.value = true
isConnectDatabaseSuccess.value = false connectBtnLoading.value = false
nextTick(() => { nextTick(() => {
scrollbarRef.value?.scrollTo({ top: 9999, behavior: 'smooth' }) scrollbarRef.value?.scrollTo({ top: 9999, behavior: 'smooth' })
}) })
})
if (res.code === 0) {
isConnectDBSuccess.value = res.data.status === 'success'
}
} }
}, },
(rule) => { (rule) => {
...@@ -43,31 +119,54 @@ function handleConnectDatabase() { ...@@ -43,31 +119,54 @@ function handleConnectDatabase() {
}, },
) )
} }
function handleUpdateDatabase() {
databaseFormRef.value?.validate((errors) => {
if (!errors) {
if (!isConnectDBSuccess.value) {
window.$message.warning(t('personal_space_module.database_module.connect_test_must_pass_to_update'))
return
}
emit('confirm', databaseFormData)
}
})
}
</script> </script>
<template> <template>
<CustomModal v-model:is-show="showModal" :title="'编辑知识库'" :width="534"> <CustomModal
v-model:is-show="showModal"
:title="t('personal_space_module.database_module.edit_database')"
:width="534"
:btn-loading="btnLoading"
@confirm="handleUpdateDatabase"
>
<template #content> <template #content>
<n-scrollbar ref="scrollbarRef" style="max-height: 550px"> <n-scrollbar ref="scrollbarRef" style="max-height: 550px">
<n-form ref="databaseFormRef" :model="databaseFormData" :rules="databaseFormRules"> <n-form ref="databaseFormRef" :model="databaseFormData" :rules="databaseFormRules">
<n-form-item label="数据库名称" path="title" :feedback-style="{ fontSize: '13px' }"> <n-form-item
path="title"
:label="t('personal_space_module.database_module.db_title')"
:feedback-style="{ fontSize: '13px' }"
>
<div class="flex w-full flex-col"> <div class="flex w-full flex-col">
<n-input <n-input
v-model:value="databaseFormData.title" v-model:value="databaseFormData.title"
placeholder="请输入数据库名称" :placeholder="t('personal_space_module.database_module.please_enter_db_title')"
show-count show-count
:maxlength="50" :maxlength="50"
/> />
<span class="text-gray-font-color mt-1 px-2.5 text-[12px]"> <span class="text-gray-font-color mt-1 px-2.5 text-[12px]">
仅支持中文、英文、数字、下划线(_)、中划线(-)、英文点(.) {{ t('personal_space_module.database_module.db_title_rule') }}
</span> </span>
</div> </div>
</n-form-item> </n-form-item>
<n-form-item label="数据库描述"> <n-form-item :label="t('personal_space_module.database_module.db_desc')">
<n-input <n-input
v-model:value="databaseFormData.desc" v-model:value="databaseFormData.desc"
placeholder="请输入数据库描述,此描述仅用于区分不同数据库,不会影响数据库调用" :placeholder="t('personal_space_module.database_module.please_enter_db_desc')"
show-count show-count
:maxlength="100" :maxlength="100"
type="textarea" type="textarea"
...@@ -75,44 +174,71 @@ function handleConnectDatabase() { ...@@ -75,44 +174,71 @@ function handleConnectDatabase() {
/> />
</n-form-item> </n-form-item>
<h3 class="font-family-medium mb-4 text-[18px]">数据源信息</h3> <h3 class="font-family-medium mb-4 text-[18px]">
{{ t('personal_space_module.database_module.db_source_info') }}
</h3>
<n-form-item label="数据源类型" show-require-mark :feedback-style="{ fontSize: '13px' }"> <n-form-item
show-require-mark
:label="t('personal_space_module.database_module.db_source_type')"
:feedback-style="{ fontSize: '13px' }"
>
<div class="rounded-theme flex h-[32px] w-full items-center bg-[#FAFAFA] px-[14px]"> <div class="rounded-theme flex h-[32px] w-full items-center bg-[#FAFAFA] px-[14px]">
{{ databaseFormData.dbType }} {{ databaseFormData.dbType }}
</div> </div>
</n-form-item> </n-form-item>
<n-form-item label="数据库地址host" show-require-mark :feedback-style="{ fontSize: '13px' }"> <n-form-item
show-require-mark
:label="t('personal_space_module.database_module.db_host')"
:feedback-style="{ fontSize: '13px' }"
>
<div class="rounded-theme flex h-[32px] w-full items-center bg-[#FAFAFA] px-[14px]"> <div class="rounded-theme flex h-[32px] w-full items-center bg-[#FAFAFA] px-[14px]">
{{ databaseFormData.dbHost }} {{ databaseFormData.dbHost }}
</div> </div>
</n-form-item> </n-form-item>
<n-form-item label="端口号" show-require-mark :feedback-style="{ fontSize: '13px' }"> <n-form-item
show-require-mark
:label="t('personal_space_module.database_module.db_port')"
:feedback-style="{ fontSize: '13px' }"
>
<div class="rounded-theme flex h-[32px] w-full items-center bg-[#FAFAFA] px-[14px]"> <div class="rounded-theme flex h-[32px] w-full items-center bg-[#FAFAFA] px-[14px]">
{{ databaseFormData.dbPort }} {{ databaseFormData.dbPort }}
</div> </div>
</n-form-item> </n-form-item>
<n-form-item label="数据库名称" show-require-mark :feedback-style="{ fontSize: '13px' }"> <n-form-item
show-require-mark
:label="t('personal_space_module.database_module.db_name')"
:feedback-style="{ fontSize: '13px' }"
>
<div class="rounded-theme flex h-[32px] w-full items-center bg-[#FAFAFA] px-[14px]"> <div class="rounded-theme flex h-[32px] w-full items-center bg-[#FAFAFA] px-[14px]">
{{ databaseFormData.dbName }} {{ databaseFormData.dbName }}
</div> </div>
</n-form-item> </n-form-item>
<n-form-item label="用户名" show-require-mark :feedback-style="{ fontSize: '13px' }"> <n-form-item
show-require-mark
:label="t('personal_space_module.database_module.db_username')"
:feedback-style="{ fontSize: '13px' }"
>
<div class="rounded-theme flex h-[32px] w-full items-center bg-[#FAFAFA] px-[14px]"> <div class="rounded-theme flex h-[32px] w-full items-center bg-[#FAFAFA] px-[14px]">
{{ databaseFormData.dbUserName }} {{ databaseFormData.dbUsername }}
</div> </div>
</n-form-item> </n-form-item>
<n-form-item label="密码" path="dbPassword" :feedback-style="{ fontSize: '13px' }"> <n-form-item
path="dbPassword"
:label="t('personal_space_module.database_module.db_password')"
:feedback-style="{ fontSize: '13px' }"
>
<n-input <n-input
v-model:value="databaseFormData.dbPassword" v-model:value="databaseFormData.dbPassword"
type="password" type="password"
show-password-on="click" show-password-on="click"
placeholder="请输入密码" :input-props="{ autocomplete: 'off' }"
:placeholder="t('personal_space_module.database_module.please_enter_db_password')"
class="font-sans" class="font-sans"
/> />
</n-form-item> </n-form-item>
...@@ -121,11 +247,15 @@ function handleConnectDatabase() { ...@@ -121,11 +247,15 @@ function handleConnectDatabase() {
<div <div
v-show="showConnectStatus" v-show="showConnectStatus"
class="flex items-center gap-[8px] rounded-[10px] px-3 py-[5px]" class="flex items-center gap-[8px] rounded-[10px] px-3 py-[5px]"
:class="isConnectDatabaseSuccess ? 'bg-[#ECFFE6]' : 'bg-[#FFE8E6]'" :class="isConnectDBSuccess ? 'bg-[#ECFFE6]' : 'bg-[#FFE8E6]'"
> >
<div class="h-[16px] w-[16px]" :class="isConnectDatabaseSuccess ? 'bg-svg-success' : 'bg-svg-error'" /> <div class="h-[16px] w-[16px]" :class="isConnectDBSuccess ? 'bg-svg-success' : 'bg-svg-error'" />
<span class="text-[12px] leading-[16px]"> <span class="text-[12px] leading-[16px]">
{{ isConnectDatabaseSuccess ? '数据库连接成功' : '无法联通数据库,请检查填写内容' }} {{
isConnectDBSuccess
? t('personal_space_module.database_module.connect_test_success')
: t('personal_space_module.database_module.connect_test_fail')
}}
</span> </span>
</div> </div>
...@@ -136,9 +266,10 @@ function handleConnectDatabase() { ...@@ -136,9 +266,10 @@ function handleConnectDatabase() {
class="h-[34px]!" class="h-[34px]!"
:bordered="false" :bordered="false"
:focusable="false" :focusable="false"
:loading="connectBtnLoading"
@click="handleConnectDatabase" @click="handleConnectDatabase"
> >
连接测试 {{ t('personal_space_module.database_module.connect_test') }}
</n-button> </n-button>
</div> </div>
</n-scrollbar> </n-scrollbar>
......
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref } from 'vue' import { computed, onMounted, ref, useTemplateRef, watch } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { Search } from '@icon-park/vue-next' import { Search } from '@icon-park/vue-next'
import { DataTableInst } from 'naive-ui'
import useTableScrollY from '@/composables/useTableScrollY' import useTableScrollY from '@/composables/useTableScrollY'
import { usePagination } from '@/composables/usePagination.ts' import { usePagination } from '@/composables/usePagination.ts'
import CustomPagination from '@/components/custom-pagination/custom-pagination.vue' import CustomPagination from '@/components/custom-pagination/custom-pagination.vue'
import { createDatabaseColumn } from './columns.tsx' import { createDatabaseColumn } from './columns.tsx'
import { DatabaseItemInterface } from './type.d' import { DatabaseItemInterface } from './type.d'
import EditDatabaseModal from './components/edit-database-modal.vue' import EditDatabaseModal from './components/edit-database-modal.vue'
import { fetchDeleteDataBaseById, fetchGetDataBaseList, handleUpdateDataBase } from '@/apis/database.ts'
const { t } = useI18n() const { t } = useI18n()
const databaseListTableRef = useTemplateRef<DataTableInst>('databaseListTableRef')
const { pageContentWrapRef, tableContentY } = useTableScrollY(48 + 32 + 18 + 16 + 28) const { pageContentWrapRef, tableContentY } = useTableScrollY(48 + 32 + 18 + 16 + 28)
const { paginationData, handlePageNoChange, handlePageSizeChange } = usePagination() const { paginationData, handlePageNoChange, handlePageSizeChange } = usePagination()
const searchDatabaseInputValue = ref('') const searchDatabaseInputValue = ref('')
const isSearchEmptyList = ref(false) const isSearchEmptyList = ref(false)
const databaseList = ref<DatabaseItemInterface[]>([])
const databaseListLoading = ref(false)
const showEditDatabaseModal = ref(false) const showEditDatabaseModal = ref(false)
const databaseList = ref<DatabaseItemInterface[]>([ const updateDatabaseBtnLoading = ref(false)
{ const currentEditDatabaseInfo = ref<DatabaseItemInterface>({
id: 1, id: 0,
title: '数据库1', title: '',
desc: '描述1', desc: '',
updateTime: new Date(), dbType: '',
}, dbHost: '',
{ dbPort: 0,
id: 2, dbName: '',
title: '数据库2', dbUsername: '',
desc: '描述2', dbPassword: '',
updateTime: new Date(), modifiedTime: new Date(),
}, })
])
const databaseColumns = createDatabaseColumn(handleDatabaseTableAction) const databaseColumns = createDatabaseColumn(handleDatabaseTableAction)
...@@ -42,6 +49,38 @@ const isLoadingPagination = computed(() => { ...@@ -42,6 +49,38 @@ const isLoadingPagination = computed(() => {
return tableContentY.value > 0 return tableContentY.value > 0
}) })
watch([() => paginationData.pageNo, () => paginationData.pageSize], async () => {
await handleGetDatabaseList()
databaseListTableRef.value?.scrollTo({ top: 0, behavior: 'smooth' })
})
onMounted(() => {
handleGetDatabaseList()
})
async function handleGetDatabaseList() {
databaseListLoading.value = true
const res = await fetchGetDataBaseList<DatabaseItemInterface[]>({
search: searchDatabaseInputValue.value,
pagingInfo: paginationData,
})
if (res.code === 0) {
databaseList.value = res.data
paginationData.totalRows = res.pagingInfo?.totalRows || 0
paginationData.totalPages = res.pagingInfo?.totalPages || 0
isSearchEmptyList.value = !!searchDatabaseInputValue.value && paginationData.totalRows === 0
databaseListLoading.value = false
}
}
async function handleSearchDatabaseList() {
paginationData.pageNo = 1
await handleGetDatabaseList()
databaseListTableRef.value?.scrollTo({ top: 0, behavior: 'smooth' })
}
function handleDatabaseTableAction(actionType: string, databaseId: number) { function handleDatabaseTableAction(actionType: string, databaseId: number) {
switch (actionType) { switch (actionType) {
case 'view': case 'view':
...@@ -56,21 +95,60 @@ function handleDatabaseTableAction(actionType: string, databaseId: number) { ...@@ -56,21 +95,60 @@ function handleDatabaseTableAction(actionType: string, databaseId: number) {
} }
} }
function handleToDatabaseDetail(_databaseId: number) {} function handleToDatabaseDetail(_databaseId: number) {
// TODO
}
function handleShowEditDatabaseModal(_databaseId: number) { function handleShowEditDatabaseModal(databaseId: number) {
showEditDatabaseModal.value = true showEditDatabaseModal.value = true
databaseList.value.forEach((item) => {
if (item.id === databaseId) {
currentEditDatabaseInfo.value = item
}
})
}
function handleDeleteDatabaseById(databaseId: number) {
window.$message
.ctWarning('', t('personal_space_module.knowledge_module.delete_knowledge_dialog_content'))
.then(async () => {
const res = await fetchDeleteDataBaseById(databaseId)
if (res.code === 0) {
if (databaseList.value.length <= 1 && paginationData.pageNo === paginationData.totalPages) {
paginationData.pageNo = paginationData.pageNo - 1 || 1
}
window.$message.success(t('common_module.delete_success_message'))
await handleGetDatabaseList()
}
})
} }
function handleDeleteDatabaseById(_databaseId: number) { async function handleUpdateDatabase(databaseData: DatabaseItemInterface) {
window.$message.ctWarning('', '删除后将无法恢复').then(() => {}) updateDatabaseBtnLoading.value = true
const res = await handleUpdateDataBase(databaseData).finally(() => {
updateDatabaseBtnLoading.value = false
})
if (res.code === 0) {
showEditDatabaseModal.value = false
window.$message.success(t('common_module.successful_update'))
handleGetDatabaseList()
}
} }
</script> </script>
<template> <template>
<div ref="pageContentWrapRef" class="h-full w-full"> <div ref="pageContentWrapRef" class="h-full w-full">
<div class="mb-[18px] flex justify-end"> <div class="mb-[18px] flex justify-end">
<n-input v-model:value="searchDatabaseInputValue" :placeholder="t('common_module.search')" class="w-[256px]!"> <n-input
v-model:value="searchDatabaseInputValue"
:placeholder="t('common_module.search')"
class="w-[256px]!"
@keyup.enter="handleSearchDatabaseList"
>
<template #suffix> <template #suffix>
<Search theme="outline" size="16" fill="#999" class="cursor-pointer" /> <Search theme="outline" size="16" fill="#999" class="cursor-pointer" />
</template> </template>
...@@ -79,8 +157,8 @@ function handleDeleteDatabaseById(_databaseId: number) { ...@@ -79,8 +157,8 @@ function handleDeleteDatabaseById(_databaseId: number) {
<div class="mb-4" :style="{ height: tableContentY + 48 + 'px' }"> <div class="mb-4" :style="{ height: tableContentY + 48 + 'px' }">
<n-data-table <n-data-table
ref="knowledgeListTableRef" ref="databaseListTableRef"
:loading="false" :loading="databaseListLoading"
:bordered="true" :bordered="true"
:bottom-bordered="true" :bottom-bordered="true"
:single-line="false" :single-line="false"
...@@ -110,6 +188,11 @@ function handleDeleteDatabaseById(_databaseId: number) { ...@@ -110,6 +188,11 @@ function handleDeleteDatabaseById(_databaseId: number) {
/> />
</footer> </footer>
<EditDatabaseModal v-model:show-modal="showEditDatabaseModal" /> <EditDatabaseModal
v-model:show-modal="showEditDatabaseModal"
:database-detail="currentEditDatabaseInfo!"
:btn-loading="updateDatabaseBtnLoading"
@confirm="handleUpdateDatabase"
/>
</div> </div>
</template> </template>
...@@ -2,5 +2,11 @@ export interface DatabaseItemInterface { ...@@ -2,5 +2,11 @@ export interface DatabaseItemInterface {
id: number id: number
title: string title: string
desc: string desc: string
updateTime: Date dbType: string
dbHost: string
dbPort: number
dbName: string
dbUsername: string
dbPassword: string
modifiedTime: Date
} }
...@@ -153,6 +153,7 @@ declare namespace I18n { ...@@ -153,6 +153,7 @@ declare namespace I18n {
authenticated: string authenticated: string
cancel_authorization: string cancel_authorization: string
get_code: string get_code: string
database: string
dialogue_module: { dialogue_module: {
continue_question_message: string continue_question_message: string
...@@ -220,6 +221,7 @@ declare namespace I18n { ...@@ -220,6 +221,7 @@ declare namespace I18n {
data_statistic: string data_statistic: string
plugin_center: string plugin_center: string
reset_password: string reset_password: string
database: string
} }
login_module: { login_module: {
...@@ -625,6 +627,37 @@ declare namespace I18n { ...@@ -625,6 +627,37 @@ declare namespace I18n {
download_QA_template: string download_QA_template: string
} }
} }
database_module: {
create_database: string
edit_database: string
creation_method: string
direct_database_connection: string
db_title: string
db_desc: string
db_source_info: string
db_source_type: string
db_host: string
db_port: string
db_name: string
db_username: string
db_password: string
please_enter_db_title: string
please_enter_db_desc: string
please_select_db_source_type: string
please_enter_db_host: string
please_enter_db_port: string
please_enter_db_name: string
please_enter_db_username: string
please_enter_db_password: string
db_title_rule: string
db_host_rule: string
connect_test: string
connect_test_success: string
connect_test_fail: string
connect_test_must_pass_to_create: string
connect_test_must_pass_to_update: string
}
} }
share_agent_module: { share_agent_module: {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment