feat(node): Implements node group selection functionality
- Introduces the Group entity and groupRepository - Adds a new database utility function, getDatabase, to centrally retrieve database instances - Removes the loading state and skeleton screen logic from nodeList to simplify the page structure - Updates dependencies and adds the zod library for data validation
This commit is contained in:
@@ -17,7 +17,8 @@
|
||||
"@tauri-apps/plugin-sql": "~2",
|
||||
"vue": "^3.5.21",
|
||||
"vue-router": "^4.5.1",
|
||||
"vuetify": "^3.10.1"
|
||||
"vuetify": "^3.10.1",
|
||||
"zod": "^4.1.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "^2",
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import {ref, onMounted, computed} from 'vue'
|
||||
import {computed, onMounted, ref} from 'vue'
|
||||
import {invoke} from '@tauri-apps/api/core'
|
||||
import Database from '@tauri-apps/plugin-sql'
|
||||
import {Group, groupRepository} from "@/entities/group.ts";
|
||||
|
||||
defineProps<{
|
||||
groupId: string
|
||||
@@ -10,6 +11,13 @@ defineProps<{
|
||||
const db = ref<any>(null)
|
||||
const db_ready = ref(false)
|
||||
|
||||
const allGroups = ref<Group[]>([])
|
||||
|
||||
|
||||
const loadGroups = async () => {
|
||||
allGroups.value = await groupRepository.findAll()
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
db.value = await Database.load('sqlite:spary.db')
|
||||
db_ready.value = true
|
||||
@@ -64,6 +72,8 @@ async function add_node(nodeAlias: string, nodeArguments: string | null) {
|
||||
isAdding.value = false
|
||||
}
|
||||
}
|
||||
|
||||
loadGroups()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -74,7 +84,13 @@ async function add_node(nodeAlias: string, nodeArguments: string | null) {
|
||||
v-model="nodeAlias"
|
||||
label="Node alias"
|
||||
></v-text-field>
|
||||
<v-select></v-select>
|
||||
<v-select
|
||||
label="Group"
|
||||
:items="allGroups"
|
||||
item-title="name"
|
||||
item-value="id"
|
||||
variant="solo"
|
||||
></v-select>
|
||||
|
||||
<v-textarea
|
||||
v-model="nodeArguments"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import {ref, onMounted} from 'vue'
|
||||
import {ref} from 'vue'
|
||||
import Database from "@tauri-apps/plugin-sql";
|
||||
import {useRouter} from "vue-router";
|
||||
const router = useRouter()
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
interface GroupItem {
|
||||
name: string
|
||||
@@ -19,10 +19,9 @@ interface Group {
|
||||
|
||||
const db = ref<any>(null)
|
||||
const panels = ref([])
|
||||
const loading = ref(true) // 是否在加载中
|
||||
const groups = ref<Group[]>([])
|
||||
|
||||
onMounted(async () => {
|
||||
const loadData = async () => {
|
||||
db.value = await Database.load('sqlite:spary.db')
|
||||
|
||||
const groupsInDb = await db.value.select(
|
||||
@@ -45,42 +44,18 @@ onMounted(async () => {
|
||||
id: group.id
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 模拟异步加载(例如从 API 获取)
|
||||
await new Promise(resolve => setTimeout(resolve, 100))
|
||||
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
function addItem(group: Group) {
|
||||
console.log(group.id)
|
||||
router.push(`/addNode/${group.id}`)
|
||||
}
|
||||
|
||||
loadData()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-container>
|
||||
<!-- 加载中时显示骨架屏 -->
|
||||
<template v-if="loading">
|
||||
<v-skeleton-loader type="heading" class="mb-4"/>
|
||||
|
||||
<v-row dense>
|
||||
<v-col
|
||||
v-for="i in 8"
|
||||
:key="i"
|
||||
cols="12"
|
||||
sm="6"
|
||||
md="4"
|
||||
lg="3"
|
||||
>
|
||||
<v-skeleton-loader type="card" class="ma-2"/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</template>
|
||||
|
||||
<!-- 加载完成后显示实际内容 -->
|
||||
<template v-else>
|
||||
<v-expansion-panels v-model="panels" multiple>
|
||||
<v-expansion-panel
|
||||
v-for="(group, i) in groups"
|
||||
@@ -128,7 +103,6 @@ function addItem(group: Group) {
|
||||
</v-expansion-panel-text>
|
||||
</v-expansion-panel>
|
||||
</v-expansion-panels>
|
||||
</template>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
|
||||
57
src/entities/group.ts
Normal file
57
src/entities/group.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import {z} from "zod";
|
||||
import {getDatabase} from "@/utils/db.ts";
|
||||
import {DBDefaultDateTime} from "@/utils/common.ts";
|
||||
|
||||
export const GroupSchema = z.object({
|
||||
id: z.number(),
|
||||
name: z.string(),
|
||||
url: z.string().nullable().optional(),
|
||||
arguments: z
|
||||
.union([z.string(), z.record(z.any(), z.any())]) // 兼容 SQLite JSON 字段可能返回 string 或 object
|
||||
.transform(val => {
|
||||
if (typeof val === "string") {
|
||||
try {
|
||||
return JSON.parse(val);
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
return val ?? {};
|
||||
}),
|
||||
created_at: DBDefaultDateTime,
|
||||
updated_at: DBDefaultDateTime,
|
||||
});
|
||||
export type Group = z.infer<typeof GroupSchema>;
|
||||
|
||||
export class GroupRepository {
|
||||
async findAll(): Promise<Group[]> {
|
||||
const db = await getDatabase();
|
||||
const rows = await db.select(`SELECT *
|
||||
FROM "group"
|
||||
ORDER BY id DESC`);
|
||||
console.log(
|
||||
rows
|
||||
)
|
||||
return GroupSchema.array().parse(rows);
|
||||
}
|
||||
|
||||
async insert(group: Group): Promise<void> {
|
||||
const db = await getDatabase();
|
||||
await db.execute(`INSERT INTO "group" (name, url, arguments)
|
||||
VALUES (?, ?, ?)`, [
|
||||
group.name,
|
||||
group.url,
|
||||
JSON.stringify(group.arguments),
|
||||
]);
|
||||
}
|
||||
|
||||
async findByName(name: string): Promise<Group[]> {
|
||||
const db = await getDatabase();
|
||||
const rows = await db.select(`SELECT *
|
||||
FROM "group"
|
||||
WHERE name = ?`, [name]);
|
||||
return GroupSchema.array().parse(rows);
|
||||
}
|
||||
}
|
||||
|
||||
export const groupRepository = new GroupRepository();
|
||||
9
src/utils/common.ts
Normal file
9
src/utils/common.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
// 自定义日期时间格式 yyyy-MM-dd HH:mm:ss
|
||||
import {z} from "zod";
|
||||
|
||||
export const DBDefaultDateTime = z
|
||||
.string()
|
||||
.refine(
|
||||
val => /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(val),
|
||||
{ message: "Invalid datetime format, expected yyyy-MM-dd HH:mm:ss" }
|
||||
);
|
||||
5
src/utils/db.ts
Normal file
5
src/utils/db.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import Database from "@tauri-apps/plugin-sql";
|
||||
|
||||
export async function getDatabase () {
|
||||
return await Database.load('sqlite:spary.db');
|
||||
}
|
||||
Reference in New Issue
Block a user