feat: datasource

This commit is contained in:
junjun
2025-05-07 16:55:09 +08:00
parent 178d41a1e9
commit 8384432860
7 changed files with 123 additions and 33 deletions
+10 -2
View File
@@ -1,5 +1,5 @@
from fastapi import APIRouter, HTTPException
from ..crud.datasource import get_datasource_list, check_status, create_ds
from ..crud.datasource import get_datasource_list, check_status, create_ds, update_ds, delete_ds
from common.core.deps import SessionDep
from ..models.datasource import DatasourceConf, CoreDatasource
@@ -14,5 +14,13 @@ def check(session: SessionDep, conf: DatasourceConf):
return check_status(session, conf)
@router.post("/add", response_model=CoreDatasource)
def check(session: SessionDep, ds: CoreDatasource):
def add(session: SessionDep, ds: CoreDatasource):
return create_ds(session, ds)
@router.post("/update", response_model=CoreDatasource)
def update(session: SessionDep, ds: CoreDatasource):
return update_ds(session, ds)
@router.post("/delete/{id}", response_model=CoreDatasource)
def delete(session: SessionDep, id: int):
return delete_ds(session, id)
+25 -6
View File
@@ -1,14 +1,15 @@
from sqlmodel import Session, select
from sqlmodel import select
from ..models.datasource import CoreDatasource, DatasourceConf
import pyodbc
import datetime
from common.core.deps import SessionDep
def get_datasource_list(session: Session) -> CoreDatasource:
statement = select(CoreDatasource)
def get_datasource_list(session: SessionDep) -> CoreDatasource:
statement = select(CoreDatasource).order_by(CoreDatasource.create_time.desc())
datasource_list = session.exec(statement).fetchall()
return datasource_list
def check_status(session: Session, conf: DatasourceConf):
def check_status(session: SessionDep, conf: DatasourceConf):
conn_str = (
"DRIVER={MySQL ODBC 9.3 Unicode Driver};" # todo driver config
f"SERVER={conf.host};"
@@ -30,10 +31,28 @@ def check_status(session: Session, conf: DatasourceConf):
if conn is not None:
conn.close()
def create_ds(session: Session, ds: CoreDatasource):
def create_ds(session: SessionDep, ds: CoreDatasource):
record = CoreDatasource(**ds.model_dump())
record.create_time = datetime.datetime.now()
record.status = "Success" # todo check status
session.add(record)
session.commit()
return record
return record
def update_ds(session: SessionDep, ds: CoreDatasource):
ds.id = int(ds.id)
term = session.exec(select(CoreDatasource).where(CoreDatasource.id == ds.id)).first()
update_data = ds.model_dump(exclude_unset=True)
for field, value in update_data.items():
setattr(term, field, value)
session.add(term)
session.commit()
return ds
def delete_ds(session: SessionDep, id: int):
term = session.exec(select(CoreDatasource).where(CoreDatasource.id == id)).first()
session.delete(term)
session.commit()
return {
"message": f"Datasource with ID {id} deleted successfully."
}
+6 -6
View File
@@ -15,9 +15,9 @@ class CoreDatasource(SQLModel, table=True):
status: str = Field(max_length=64, nullable=True)
class DatasourceConf(BaseModel):
host: str
port: int
username: str
password: str
database: str
driver: str
host: str = ''
port: int = 0
username: str = ''
password: str = ''
database: str = ''
driver: str = ''
+3 -1
View File
@@ -3,5 +3,7 @@ import { request } from '@/utils/request'
export const datasourceApi = {
check: (data: any) => request.post('/datasource/check', data),
add: (data: any) => request.post('/datasource/add', data),
list: () => request.get('/datasource/list')
list: () => request.get('/datasource/list'),
update: (data: any) => request.post('/datasource/update', data),
delete: (id: Number) => request.post(`/datasource/delete/${id}`)
}
+2 -1
View File
@@ -164,7 +164,8 @@ class HttpService {
// ElMessage.error(errorMessage)
ElMessage({
message: errorMessage,
type: 'error'
type: 'error',
showClose: true
})
}
+46 -11
View File
@@ -9,7 +9,7 @@
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="Description">
<el-input v-model="form.desc" :rows="2" type="textarea" />
<el-input v-model="form.description" :rows="2" type="textarea" />
</el-form-item>
<el-form-item label="Type">
<el-select v-model="form.type" placeholder="Select Type">
@@ -37,26 +37,29 @@
<el-input v-model="form.database" />
</el-form-item>
<el-form-item>
<div style="display: flex;justify-content: flex-end;">
<el-button @click="close">Cancel</el-button>
<el-button @click="check">Test Connect</el-button>
<el-button type="primary" @click="save">Save</el-button>
</el-form-item>
</div>
</el-form>
</el-dialog>
</template>
<script lang="ts" setup>
import { reactive } from 'vue'
import { ref } from 'vue'
import { datasourceApi } from '@/api/datasource'
const emit = defineEmits(['refresh'])
const dialogVisible = ref<boolean>(false)
const dsType = [
{label:"MySQL", value:"mysql"}
]
const form = reactive({
const form = ref<any>({
name:'',
desc:'',
description:'',
type:'mysql',
driver:'',
host:'',
port:0,
username:'',
@@ -65,19 +68,51 @@ const form = reactive({
configuration: ''
})
const open = () => {
const close = () => {
dialogVisible.value = false
}
const open = (item: any) => {
if (item) {
form.value.id = item.id
form.value.name = item.name
form.value.description = item.description
form.value.type = item.type
const configuration = JSON.parse(item.configuration)
form.value.host = configuration.host
form.value.port = configuration.port
form.value.username = configuration.username
form.value.password = configuration.password
form.value.database = configuration.database
}
dialogVisible.value = true
}
const save = () => {
form.configuration = JSON.stringify({host:form.host,port:form.port,username:form.username,password:form.password,database:form.database})
datasourceApi.add(form).then((res: any) => {
console.log(res)
form.value.configuration = JSON.stringify({
host:form.value.host,
port:form.value.port,
username:form.value.username,
password:form.value.password,
database:form.value.database
})
if (form.value.id) {
datasourceApi.update(form.value).then((res) => {
console.log(res)
close()
emit('refresh')
})
} else {
datasourceApi.add(form.value).then((res: any) => {
console.log(res)
close()
emit('refresh')
})
}
}
const check = () => {
datasourceApi.check(form).then((res: any) => {
datasourceApi.check(form.value).then((res: any) => {
console.log(res)
})
}
+31 -6
View File
@@ -14,7 +14,7 @@
</el-input>
</div>
<el-button type="primary" :icon="IconOpeAdd" @click="addDs">Add Datasource</el-button>
<el-button type="primary" :icon="IconOpeAdd" @click="editDs()">Add Datasource</el-button>
</div>
<div class="connections-container">
@@ -33,17 +33,17 @@
</div>
<div class="connection-status" :class="`${getStatus(ds.status)}`">{{ ds.status }}</div>
<div class="connection-actions">
<button class="action-btn">
<button class="action-btn" @click="editDs(ds)">
<el-icon><IconOpeEdit /></el-icon>
</button>
<button class="action-btn">
<button class="action-btn" @click="deleteDs(ds)">
<el-icon><IconOpeDelete /></el-icon>
</button>
</div>
</div>
</div>
</div>
<DsForm ref="dsForm"/>
<DsForm ref="dsForm" @refresh="refresh"/>
</template>
<script lang="ts" setup>
import IconOpeAdd from '@/assets/svg/operate/ope-add.svg'
@@ -54,6 +54,7 @@ import { ref, onMounted } from 'vue'
import DsForm from './form.vue'
import { datasourceApi } from '@/api/datasource'
import { datetimeFormat } from '@/utils/utils'
import { ElMessageBox } from 'element-plus'
const search = ref<string>('')
const dsForm = ref()
@@ -71,8 +72,8 @@ const getStatus = (status: string) => {
}
}
const addDs = () => {
dsForm.value.open()
const refresh = () => {
list()
}
const list = () => {
@@ -81,6 +82,30 @@ const list = () => {
})
}
const editDs = (item: any = {}) => {
dsForm.value.open(item)
}
const deleteDs = (item: any) => {
ElMessageBox.confirm(
'Delete this datasource?',
'Delete',
{
confirmButtonText: 'Confirm',
cancelButtonText: 'Cancel',
type: 'warning',
}
)
.then(() => {
datasourceApi.delete(item.id).then(() => {
console.log('success')
list()
})
})
.catch(() => {
})
}
onMounted(() => {
list()
})