feat(device): 新增开发者模式指令及下拉菜单样式优化
新增推送开发者模式指令到设备的 API。 优化设备页面表格工具栏更多按钮的下拉菜单: - 点击触发并支持点击菜单项后自动隐藏 - 移除触发按钮 hover 时的背景色 - 调整下拉菜单项的布局、间距与圆角样式
This commit is contained in:
62
src/api/system/developer/index.ts
Normal file
62
src/api/system/developer/index.ts
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
import request from "@/utils/request";
|
||||||
|
import type { DeveloperQueryParams, DeveloperForm, DeveloperItem } from "./types";
|
||||||
|
import type { PageResult } from "@/api/common";
|
||||||
|
|
||||||
|
const DEVELOPER_BASE_URL = "/api/v1/developers";
|
||||||
|
|
||||||
|
const DeveloperAPI = {
|
||||||
|
/** 获取开发者选项分页数据 */
|
||||||
|
getPage(queryParams?: DeveloperQueryParams) {
|
||||||
|
return request<unknown, PageResult<DeveloperItem>>({
|
||||||
|
url: `${DEVELOPER_BASE_URL}`,
|
||||||
|
method: "get",
|
||||||
|
params: queryParams,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 获取开发者选项表单数据 */
|
||||||
|
getFormData(id: string) {
|
||||||
|
return request<unknown, DeveloperForm>({
|
||||||
|
url: `${DEVELOPER_BASE_URL}/${id}/form`,
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 新增开发者选项配置 */
|
||||||
|
create(data: DeveloperForm) {
|
||||||
|
return request({ url: `${DEVELOPER_BASE_URL}`, method: "post", data });
|
||||||
|
},
|
||||||
|
/** 修改开发者选项配置 */
|
||||||
|
update(id: string, data: DeveloperForm) {
|
||||||
|
return request({ url: `${DEVELOPER_BASE_URL}/${id}`, method: "put", data });
|
||||||
|
},
|
||||||
|
/** 批量删除开发者选项配置,多个以英文逗号(,)分隔 */
|
||||||
|
deleteByIds(ids: string) {
|
||||||
|
return request({ url: `${DEVELOPER_BASE_URL}/${ids}`, method: "delete" });
|
||||||
|
},
|
||||||
|
/** 根据设备序列号获取开发者选项开关 */
|
||||||
|
getBySn(sn: string) {
|
||||||
|
return request<unknown, number>({
|
||||||
|
url: `${DEVELOPER_BASE_URL}/sn/${sn}`,
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 根据设备序列号保存或更新开发者选项开关 */
|
||||||
|
saveOrUpdateBySn(sn: string, developerOptions: number) {
|
||||||
|
return request({
|
||||||
|
url: `${DEVELOPER_BASE_URL}/sn/${sn}`,
|
||||||
|
method: "put",
|
||||||
|
params: { developerOptions },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 推送开发者模式指令到设备 */
|
||||||
|
pushBySn(sn: string) {
|
||||||
|
return request({
|
||||||
|
url: `${DEVELOPER_BASE_URL}/sn/${sn}/push`,
|
||||||
|
method: "post",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DeveloperAPI;
|
||||||
|
|
||||||
|
// 重导出类型
|
||||||
|
export * from "./types";
|
||||||
37
src/api/system/developer/types.ts
Normal file
37
src/api/system/developer/types.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* Developer 设备开发者选项类型定义
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { BaseQueryParams } from "@/api/common";
|
||||||
|
|
||||||
|
/** 开发者选项分页查询参数 */
|
||||||
|
export interface DeveloperQueryParams extends BaseQueryParams {
|
||||||
|
/** 搜索关键字(设备序列号) */
|
||||||
|
keywords?: string;
|
||||||
|
/** 开发者选项开关(0关闭,1开启) */
|
||||||
|
developerOptions?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 开发者选项表单对象 */
|
||||||
|
export interface DeveloperForm {
|
||||||
|
/** 配置ID */
|
||||||
|
id?: string;
|
||||||
|
/** 设备序列号 */
|
||||||
|
sn?: string;
|
||||||
|
/** 开发者选项开关(0关闭,1开启) */
|
||||||
|
developerOptions?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 开发者选项分页对象 */
|
||||||
|
export interface DeveloperItem {
|
||||||
|
/** 配置ID */
|
||||||
|
id: string;
|
||||||
|
/** 设备序列号 */
|
||||||
|
sn: string;
|
||||||
|
/** 开发者选项开关(0关闭,1开启) */
|
||||||
|
developerOptions: number;
|
||||||
|
/** 创建时间 */
|
||||||
|
createTime?: string;
|
||||||
|
/** 更新时间 */
|
||||||
|
updateTime?: string;
|
||||||
|
}
|
||||||
@@ -307,6 +307,18 @@ const DeviceAPI = {
|
|||||||
params: { sn },
|
params: { sn },
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 推送开发者模式指令到设备
|
||||||
|
* @param sn 设备SN号
|
||||||
|
*/
|
||||||
|
deviceDeveloper(sn: string) {
|
||||||
|
return request({
|
||||||
|
url: `${DEVICE_BASE_URL}/developer`,
|
||||||
|
method: "post",
|
||||||
|
params: { sn },
|
||||||
|
});
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DeviceAPI;
|
export default DeviceAPI;
|
||||||
|
|||||||
@@ -160,11 +160,17 @@
|
|||||||
<template v-else-if="col.templet === 'tool'">
|
<template v-else-if="col.templet === 'tool'">
|
||||||
<div class="flex items-center justify-center gap-x-2">
|
<div class="flex items-center justify-center gap-x-2">
|
||||||
<template v-for="(btn, index) in tableToolbarBtn" :key="index">
|
<template v-for="(btn, index) in tableToolbarBtn" :key="index">
|
||||||
<el-dropdown v-if="btn.children !== undefined && btn.children.length > 0">
|
<el-dropdown
|
||||||
|
v-if="btn.children !== undefined && btn.children.length > 0"
|
||||||
|
trigger="click"
|
||||||
|
:hide-on-click="true"
|
||||||
|
popper-class="more-dropdown-menu"
|
||||||
|
>
|
||||||
<el-button
|
<el-button
|
||||||
v-if="btn.render === undefined || btn.render(scope.row)"
|
v-if="btn.render === undefined || btn.render(scope.row)"
|
||||||
v-hasPerm="btn.perm ?? '*:*:*'"
|
v-hasPerm="btn.perm ?? '*:*:*'"
|
||||||
v-bind="btn.attrs"
|
v-bind="btn.attrs"
|
||||||
|
class="more-trigger-btn"
|
||||||
>
|
>
|
||||||
{{ btn.text }}
|
{{ btn.text }}
|
||||||
<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
||||||
@@ -976,4 +982,40 @@ defineExpose({ fetchPageData, exportPageData, getFilterParams, getSelectionData,
|
|||||||
margin-left: 0 !important;
|
margin-left: 0 !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 更多按钮:去掉 link 类型 hover 时的浅蓝背景层 */
|
||||||
|
.more-trigger-btn {
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:focus-visible {
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- 非 scoped:下拉菜单通过 teleport 渲染到 body,需用全局样式覆盖 -->
|
||||||
|
<style lang="scss">
|
||||||
|
.more-dropdown-menu {
|
||||||
|
.el-dropdown-menu {
|
||||||
|
gap: 2px;
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-dropdown-menu__item {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
padding: 8px 16px;
|
||||||
|
line-height: 1.4;
|
||||||
|
border-radius: 6px;
|
||||||
|
|
||||||
|
& + .el-dropdown-menu__item {
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-icon {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
340
src/views/devices/developer/index.vue
Normal file
340
src/views/devices/developer/index.vue
Normal file
@@ -0,0 +1,340 @@
|
|||||||
|
<template>
|
||||||
|
<div class="page-container">
|
||||||
|
<el-card class="page-search" shadow="never">
|
||||||
|
<el-form ref="queryFormRef" :model="params" :inline="true">
|
||||||
|
<el-form-item label="设备序列号" prop="keywords">
|
||||||
|
<el-input
|
||||||
|
v-model="params.keywords"
|
||||||
|
placeholder="请输入设备序列号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="开关状态" prop="developerOptions">
|
||||||
|
<el-select
|
||||||
|
v-model="params.developerOptions"
|
||||||
|
placeholder="全部"
|
||||||
|
clearable
|
||||||
|
style="width: 140px"
|
||||||
|
@change="handleQuery"
|
||||||
|
>
|
||||||
|
<el-option label="已开启" :value="1" />
|
||||||
|
<el-option label="已关闭" :value="0" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button @click="handleResetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<el-card ref="tableWrapperRef" class="page-content" shadow="never">
|
||||||
|
<div class="page-toolbar">
|
||||||
|
<div class="page-toolbar__left">
|
||||||
|
<el-button v-hasPerm="['device:developer:create']" type="primary" @click="openDialog()">
|
||||||
|
新增
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-hasPerm="['device:developer:delete']"
|
||||||
|
type="danger"
|
||||||
|
:disabled="selectIds.length === 0"
|
||||||
|
@click="handleDelete()"
|
||||||
|
>
|
||||||
|
批量删除
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="page-toolbar__right">
|
||||||
|
<el-tooltip content="刷新" placement="top">
|
||||||
|
<el-button class="page-icon-btn" @click="handleQuery">
|
||||||
|
<el-icon><Refresh /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip content="全屏" placement="top">
|
||||||
|
<el-button class="page-icon-btn" @click="toggleFullscreen">
|
||||||
|
<el-icon><FullScreen /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-table-wrapper">
|
||||||
|
<el-table
|
||||||
|
ref="dataTableRef"
|
||||||
|
v-loading="loading"
|
||||||
|
:data="list"
|
||||||
|
class="page-table"
|
||||||
|
height="100%"
|
||||||
|
highlight-current-row
|
||||||
|
border
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="50" align="center" />
|
||||||
|
<el-table-column type="index" label="序号" width="60" />
|
||||||
|
<el-table-column key="sn" label="设备序列号" prop="sn" min-width="180" />
|
||||||
|
<el-table-column key="developerOptions" label="开发者选项" width="140" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-switch
|
||||||
|
:model-value="scope.row.developerOptions === 1"
|
||||||
|
:loading="switchLoadingSn === scope.row.sn"
|
||||||
|
:disabled="!hasSwitchPerm"
|
||||||
|
inline-prompt
|
||||||
|
active-text="开"
|
||||||
|
inactive-text="关"
|
||||||
|
@change="
|
||||||
|
(val: string | number | boolean) =>
|
||||||
|
handleSwitchChange(scope.row as DeveloperItem, Boolean(val))
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column key="createTime" label="创建时间" prop="createTime" min-width="160" />
|
||||||
|
<el-table-column key="updateTime" label="更新时间" prop="updateTime" min-width="160" />
|
||||||
|
<el-table-column fixed="right" label="操作" width="240">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
v-hasPerm="['device:developer:push']"
|
||||||
|
type="success"
|
||||||
|
size="small"
|
||||||
|
link
|
||||||
|
@click="handlePush(scope.row.sn)"
|
||||||
|
>
|
||||||
|
推送设备
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-hasPerm="['device:developer:update']"
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
link
|
||||||
|
@click="openDialog(scope.row.id)"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-hasPerm="['device:developer:delete']"
|
||||||
|
type="danger"
|
||||||
|
size="small"
|
||||||
|
link
|
||||||
|
@click="handleDelete(scope.row.id)"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pagination
|
||||||
|
v-if="total > 0"
|
||||||
|
v-model:total="total"
|
||||||
|
v-model:page="params.pageNum"
|
||||||
|
v-model:limit="params.pageSize"
|
||||||
|
@pagination="fetchData"
|
||||||
|
/>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<el-dialog
|
||||||
|
v-model="dialogState.visible"
|
||||||
|
:title="dialogState.title"
|
||||||
|
width="500px"
|
||||||
|
@close="closeDialog"
|
||||||
|
>
|
||||||
|
<el-form
|
||||||
|
ref="dataFormRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="rules"
|
||||||
|
label-suffix=":"
|
||||||
|
label-width="120px"
|
||||||
|
>
|
||||||
|
<el-form-item label="设备序列号" prop="sn">
|
||||||
|
<el-input
|
||||||
|
v-model="formData.sn"
|
||||||
|
placeholder="请输入设备序列号"
|
||||||
|
:maxlength="64"
|
||||||
|
:disabled="!!formData.id"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="开发者选项" prop="developerOptions">
|
||||||
|
<el-radio-group v-model="formData.developerOptions">
|
||||||
|
<el-radio :value="1">开启</el-radio>
|
||||||
|
<el-radio :value="0">关闭</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="handleSubmit">确定</el-button>
|
||||||
|
<el-button @click="closeDialog">取消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from "element-plus";
|
||||||
|
import { Refresh, FullScreen } from "@element-plus/icons-vue";
|
||||||
|
|
||||||
|
import DeveloperAPI from "@/api/system/developer";
|
||||||
|
import type { DeveloperItem, DeveloperForm, DeveloperQueryParams } from "@/api/system/developer";
|
||||||
|
import { usePageTable } from "@/composables";
|
||||||
|
import { hasPerm } from "@/utils/auth";
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: "Developer",
|
||||||
|
inheritAttrs: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const tableWrapperRef = ref<HTMLElement | null>(null);
|
||||||
|
const { toggle: toggleFullscreen } = useFullscreen(tableWrapperRef);
|
||||||
|
|
||||||
|
const queryFormRef = ref<FormInstance>();
|
||||||
|
const dataFormRef = ref<FormInstance>();
|
||||||
|
|
||||||
|
/** 分页表格数据管理 */
|
||||||
|
const { loading, list, total, params, fetchData, handleQuery, handleResetQuery } = usePageTable<
|
||||||
|
DeveloperItem,
|
||||||
|
DeveloperQueryParams
|
||||||
|
>({
|
||||||
|
initialParams: { pageNum: 1, pageSize: 10, keywords: "", developerOptions: undefined },
|
||||||
|
request: DeveloperAPI.getPage,
|
||||||
|
onBeforeReset: () => queryFormRef.value?.resetFields(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const selectIds = ref<string[]>([]);
|
||||||
|
const switchLoadingSn = ref<string>("");
|
||||||
|
|
||||||
|
/** 是否拥有开关快捷切换权限 */
|
||||||
|
const hasSwitchPerm = computed(() => hasPerm("device:developer:update"));
|
||||||
|
|
||||||
|
const dialogState = reactive({ title: "", visible: false });
|
||||||
|
|
||||||
|
const formData = reactive<DeveloperForm>({
|
||||||
|
id: undefined,
|
||||||
|
sn: "",
|
||||||
|
developerOptions: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const rules: FormRules = {
|
||||||
|
sn: [{ required: true, message: "请输入设备序列号", trigger: "blur" }],
|
||||||
|
developerOptions: [{ required: true, message: "请选择开发者选项开关", trigger: "change" }],
|
||||||
|
};
|
||||||
|
|
||||||
|
function handleSelectionChange(selection: DeveloperItem[]): void {
|
||||||
|
selectIds.value = selection.map((item) => item.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开新增/编辑开发者选项弹窗
|
||||||
|
*/
|
||||||
|
async function openDialog(id?: string): Promise<void> {
|
||||||
|
dialogState.visible = true;
|
||||||
|
if (id) {
|
||||||
|
dialogState.title = "修改开发者选项";
|
||||||
|
const data = await DeveloperAPI.getFormData(id);
|
||||||
|
Object.assign(formData, data);
|
||||||
|
} else {
|
||||||
|
dialogState.title = "新增开发者选项";
|
||||||
|
formData.id = undefined;
|
||||||
|
formData.sn = "";
|
||||||
|
formData.developerOptions = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表格内快捷切换开发者选项开关
|
||||||
|
*/
|
||||||
|
async function handleSwitchChange(row: DeveloperItem, checked: boolean): Promise<void> {
|
||||||
|
switchLoadingSn.value = row.sn;
|
||||||
|
try {
|
||||||
|
await DeveloperAPI.saveOrUpdateBySn(row.sn, checked ? 1 : 0);
|
||||||
|
row.developerOptions = checked ? 1 : 0;
|
||||||
|
ElMessage.success(checked ? "已开启开发者选项" : "已关闭开发者选项");
|
||||||
|
} finally {
|
||||||
|
switchLoadingSn.value = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 推送开发者模式指令到设备
|
||||||
|
*/
|
||||||
|
async function handlePush(sn: string): Promise<void> {
|
||||||
|
await ElMessageBox.confirm(`确认向设备【${sn}】推送开发者模式指令?`, "提示", {
|
||||||
|
confirmButtonText: "确定",
|
||||||
|
cancelButtonText: "取消",
|
||||||
|
type: "warning",
|
||||||
|
});
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
await DeveloperAPI.pushBySn(sn);
|
||||||
|
ElMessage.success("推送成功");
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验并提交开发者选项表单
|
||||||
|
*/
|
||||||
|
async function handleSubmit(): Promise<void> {
|
||||||
|
const valid = await dataFormRef.value?.validate().catch(() => false);
|
||||||
|
if (!valid) return;
|
||||||
|
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
const id = formData.id;
|
||||||
|
if (id) {
|
||||||
|
await DeveloperAPI.update(id, formData);
|
||||||
|
ElMessage.success("修改成功");
|
||||||
|
} else {
|
||||||
|
await DeveloperAPI.create(formData);
|
||||||
|
ElMessage.success("新增成功");
|
||||||
|
}
|
||||||
|
closeDialog();
|
||||||
|
handleResetQuery();
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭弹窗并重置表单
|
||||||
|
*/
|
||||||
|
function closeDialog(): void {
|
||||||
|
dialogState.visible = false;
|
||||||
|
dataFormRef.value?.resetFields();
|
||||||
|
dataFormRef.value?.clearValidate();
|
||||||
|
formData.id = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除开发者选项配置
|
||||||
|
*/
|
||||||
|
async function handleDelete(id?: string): Promise<void> {
|
||||||
|
const ids = id ? [id] : selectIds.value;
|
||||||
|
if (ids.length === 0) {
|
||||||
|
ElMessage.warning("请勾选要删除的数据");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await ElMessageBox.confirm("确认删除选中的开发者选项配置?", "警告", {
|
||||||
|
confirmButtonText: "确定",
|
||||||
|
cancelButtonText: "取消",
|
||||||
|
type: "warning",
|
||||||
|
});
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
await DeveloperAPI.deleteByIds(ids.join(","));
|
||||||
|
ElMessage.success("删除成功");
|
||||||
|
selectIds.value = [];
|
||||||
|
handleResetQuery();
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
handleQuery();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
Reference in New Issue
Block a user