web-home
This commit is contained in:
@@ -248,7 +248,7 @@ const cleanDialogVisible = ref(false);
|
||||
const cleanDays = ref(30);
|
||||
|
||||
// 加载日志列表
|
||||
const loadLogList = async () => {
|
||||
async function loadLogList() {
|
||||
loading.value = true;
|
||||
try {
|
||||
const filter: Partial<CrontabLog> = {};
|
||||
@@ -273,37 +273,37 @@ const loadLogList = async () => {
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 搜索
|
||||
const handleSearch = () => {
|
||||
function handleSearch() {
|
||||
pageParam.pageNumber = 1;
|
||||
loadLogList();
|
||||
};
|
||||
}
|
||||
|
||||
// 重置搜索
|
||||
const handleReset = () => {
|
||||
function handleReset() {
|
||||
searchForm.taskName = '';
|
||||
searchForm.taskGroup = '';
|
||||
searchForm.executeStatus = undefined;
|
||||
pageParam.pageNumber = 1;
|
||||
loadLogList();
|
||||
};
|
||||
}
|
||||
|
||||
// 分页变化
|
||||
const handlePageChange = (page: number) => {
|
||||
function handlePageChange(page: number) {
|
||||
pageParam.pageNumber = page;
|
||||
loadLogList();
|
||||
};
|
||||
}
|
||||
|
||||
const handleSizeChange = (size: number) => {
|
||||
function handleSizeChange(size: number) {
|
||||
pageParam.pageSize = size;
|
||||
pageParam.pageNumber = 1;
|
||||
loadLogList();
|
||||
};
|
||||
}
|
||||
|
||||
// 查看详情
|
||||
const handleViewDetail = async (row: CrontabLog) => {
|
||||
async function handleViewDetail(row: CrontabLog) {
|
||||
try {
|
||||
const result = await crontabApi.getLogById(row.id!);
|
||||
if (result.success && result.data) {
|
||||
@@ -316,10 +316,10 @@ const handleViewDetail = async (row: CrontabLog) => {
|
||||
console.error('获取日志详情失败:', error);
|
||||
ElMessage.error('获取日志详情失败');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 删除日志
|
||||
const handleDelete = async (row: CrontabLog) => {
|
||||
async function handleDelete(row: CrontabLog) {
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
'确定要删除这条日志吗?',
|
||||
@@ -344,15 +344,15 @@ const handleDelete = async (row: CrontabLog) => {
|
||||
ElMessage.error('删除日志失败');
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 清理日志
|
||||
const handleCleanLogs = () => {
|
||||
function handleCleanLogs() {
|
||||
cleanDialogVisible.value = true;
|
||||
};
|
||||
}
|
||||
|
||||
// 确认清理
|
||||
const handleConfirmClean = async () => {
|
||||
async function handleConfirmClean() {
|
||||
submitting.value = true;
|
||||
try {
|
||||
const result = await crontabApi.cleanLogs(cleanDays.value);
|
||||
@@ -369,7 +369,7 @@ const handleConfirmClean = async () => {
|
||||
} finally {
|
||||
submitting.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
|
||||
@@ -266,10 +266,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import {
|
||||
Plus, Search, Refresh, DocumentCopy, VideoPlay,
|
||||
VideoPause, Promotion, Edit, Delete
|
||||
} from '@element-plus/icons-vue';
|
||||
import { Plus, Search, Refresh, DocumentCopy, VideoPlay, VideoPause, Promotion, Edit, Delete } from '@element-plus/icons-vue';
|
||||
import { crontabApi } from '@/apis/crontab';
|
||||
import type { CrontabTask, PageParam } from '@/types';
|
||||
|
||||
@@ -310,7 +307,7 @@ const formData = reactive<Partial<CrontabTask>>({
|
||||
});
|
||||
|
||||
// 加载爬虫列表
|
||||
const loadCrawlerList = async () => {
|
||||
async function loadCrawlerList() {
|
||||
loading.value = true;
|
||||
try {
|
||||
const filter: Partial<CrontabTask> = {
|
||||
@@ -337,50 +334,50 @@ const loadCrawlerList = async () => {
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 搜索
|
||||
const handleSearch = () => {
|
||||
function handleSearch() {
|
||||
pageParam.pageNumber = 1;
|
||||
loadCrawlerList();
|
||||
};
|
||||
}
|
||||
|
||||
// 重置搜索
|
||||
const handleReset = () => {
|
||||
function handleReset() {
|
||||
searchForm.taskName = '';
|
||||
searchForm.status = undefined;
|
||||
pageParam.pageNumber = 1;
|
||||
loadCrawlerList();
|
||||
};
|
||||
}
|
||||
|
||||
// 分页变化
|
||||
const handlePageChange = (page: number) => {
|
||||
function handlePageChange(page: number) {
|
||||
pageParam.pageNumber = page;
|
||||
loadCrawlerList();
|
||||
};
|
||||
}
|
||||
|
||||
const handleSizeChange = (size: number) => {
|
||||
function handleSizeChange(size: number) {
|
||||
pageParam.pageSize = size;
|
||||
pageParam.pageNumber = 1;
|
||||
loadCrawlerList();
|
||||
};
|
||||
}
|
||||
|
||||
// 新增爬虫
|
||||
const handleAdd = () => {
|
||||
function handleAdd() {
|
||||
isEdit.value = false;
|
||||
resetFormData();
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
}
|
||||
|
||||
// 编辑爬虫
|
||||
const handleEdit = (row: CrontabTask) => {
|
||||
function handleEdit(row: CrontabTask) {
|
||||
isEdit.value = true;
|
||||
Object.assign(formData, row);
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
}
|
||||
|
||||
// 启动爬虫
|
||||
const handleStart = async (row: CrontabTask) => {
|
||||
async function handleStart(row: CrontabTask) {
|
||||
try {
|
||||
const result = await crontabApi.startTask(row.taskId!);
|
||||
if (result.success) {
|
||||
@@ -393,10 +390,10 @@ const handleStart = async (row: CrontabTask) => {
|
||||
console.error('启动爬虫失败:', error);
|
||||
ElMessage.error('启动爬虫失败');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 暂停爬虫
|
||||
const handlePause = async (row: CrontabTask) => {
|
||||
async function handlePause(row: CrontabTask) {
|
||||
try {
|
||||
const result = await crontabApi.pauseTask(row.taskId!);
|
||||
if (result.success) {
|
||||
@@ -409,10 +406,10 @@ const handlePause = async (row: CrontabTask) => {
|
||||
console.error('暂停爬虫失败:', error);
|
||||
ElMessage.error('暂停爬虫失败');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 执行一次
|
||||
const handleExecute = async (row: CrontabTask) => {
|
||||
async function handleExecute(row: CrontabTask) {
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`确定立即执行爬虫"${row.taskName}"吗?`,
|
||||
@@ -436,10 +433,10 @@ const handleExecute = async (row: CrontabTask) => {
|
||||
ElMessage.error('执行爬虫失败');
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 删除爬虫
|
||||
const handleDelete = async (row: CrontabTask) => {
|
||||
async function handleDelete(row: CrontabTask) {
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`确定要删除爬虫"${row.taskName}"吗?`,
|
||||
@@ -464,10 +461,10 @@ const handleDelete = async (row: CrontabTask) => {
|
||||
ElMessage.error('删除爬虫失败');
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 验证Cron表达式
|
||||
const validateCron = async () => {
|
||||
async function validateCron() {
|
||||
if (!formData.cronExpression) {
|
||||
ElMessage.warning('请输入Cron表达式');
|
||||
return;
|
||||
@@ -484,10 +481,10 @@ const validateCron = async () => {
|
||||
console.error('验证Cron表达式失败:', error);
|
||||
ElMessage.error('验证失败');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
async function handleSubmit() {
|
||||
// 表单验证
|
||||
if (!formData.taskName) {
|
||||
ElMessage.warning('请输入爬虫名称');
|
||||
@@ -533,15 +530,15 @@ const handleSubmit = async () => {
|
||||
} finally {
|
||||
submitting.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 重置表单
|
||||
const resetForm = () => {
|
||||
function resetForm() {
|
||||
resetFormData();
|
||||
};
|
||||
}
|
||||
|
||||
// 重置表单数据
|
||||
const resetFormData = () => {
|
||||
function resetFormData() {
|
||||
Object.assign(formData, {
|
||||
taskName: '',
|
||||
taskGroup: 'NEWS_CRAWLER',
|
||||
@@ -554,7 +551,7 @@ const resetFormData = () => {
|
||||
misfirePolicy: 3,
|
||||
description: ''
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
|
||||
@@ -315,48 +315,48 @@ const loadTaskList = async () => {
|
||||
};
|
||||
|
||||
// 搜索
|
||||
const handleSearch = () => {
|
||||
function handleSearch() {
|
||||
pageParam.pageNumber = 1;
|
||||
loadTaskList();
|
||||
};
|
||||
}
|
||||
|
||||
// 重置搜索
|
||||
const handleReset = () => {
|
||||
function handleReset() {
|
||||
searchForm.taskName = '';
|
||||
searchForm.taskGroup = '';
|
||||
searchForm.status = undefined;
|
||||
pageParam.pageNumber = 1;
|
||||
loadTaskList();
|
||||
};
|
||||
}
|
||||
|
||||
// 分页变化
|
||||
const handlePageChange = (page: number) => {
|
||||
function handlePageChange(page: number) {
|
||||
pageParam.pageNumber = page;
|
||||
loadTaskList();
|
||||
};
|
||||
}
|
||||
|
||||
const handleSizeChange = (size: number) => {
|
||||
function handleSizeChange(size: number) {
|
||||
pageParam.pageSize = size;
|
||||
pageParam.pageNumber = 1;
|
||||
loadTaskList();
|
||||
};
|
||||
}
|
||||
|
||||
// 新增任务
|
||||
const handleAdd = () => {
|
||||
function handleAdd() {
|
||||
isEdit.value = false;
|
||||
resetFormData();
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
}
|
||||
|
||||
// 编辑任务
|
||||
const handleEdit = (row: CrontabTask) => {
|
||||
function handleEdit(row: CrontabTask) {
|
||||
isEdit.value = true;
|
||||
Object.assign(formData, row);
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
}
|
||||
|
||||
// 启动任务
|
||||
const handleStart = async (row: CrontabTask) => {
|
||||
async function handleStart(row: CrontabTask) {
|
||||
try {
|
||||
const result = await crontabApi.startTask(row.taskId!);
|
||||
if (result.success) {
|
||||
@@ -369,10 +369,10 @@ const handleStart = async (row: CrontabTask) => {
|
||||
console.error('启动任务失败:', error);
|
||||
ElMessage.error('启动任务失败');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 暂停任务
|
||||
const handlePause = async (row: CrontabTask) => {
|
||||
async function handlePause(row: CrontabTask) {
|
||||
try {
|
||||
const result = await crontabApi.pauseTask(row.taskId!);
|
||||
if (result.success) {
|
||||
@@ -385,10 +385,10 @@ const handlePause = async (row: CrontabTask) => {
|
||||
console.error('暂停任务失败:', error);
|
||||
ElMessage.error('暂停任务失败');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 执行一次
|
||||
const handleExecute = async (row: CrontabTask) => {
|
||||
async function handleExecute(row: CrontabTask) {
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`确定立即执行任务"${row.taskName}"吗?`,
|
||||
@@ -412,10 +412,10 @@ const handleExecute = async (row: CrontabTask) => {
|
||||
ElMessage.error('执行任务失败');
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 删除任务
|
||||
const handleDelete = async (row: CrontabTask) => {
|
||||
async function handleDelete(row: CrontabTask) {
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`确定要删除任务"${row.taskName}"吗?`,
|
||||
@@ -440,10 +440,10 @@ const handleDelete = async (row: CrontabTask) => {
|
||||
ElMessage.error('删除任务失败');
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 验证Cron表达式
|
||||
const validateCron = async () => {
|
||||
async function validateCron() {
|
||||
if (!formData.cronExpression) {
|
||||
ElMessage.warning('请输入Cron表达式');
|
||||
return;
|
||||
@@ -460,10 +460,10 @@ const validateCron = async () => {
|
||||
console.error('验证Cron表达式失败:', error);
|
||||
ElMessage.error('验证失败');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
async function handleSubmit() {
|
||||
// 表单验证
|
||||
if (!formData.taskName) {
|
||||
ElMessage.warning('请输入任务名称');
|
||||
@@ -510,15 +510,15 @@ const handleSubmit = async () => {
|
||||
} finally {
|
||||
submitting.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 重置表单
|
||||
const resetForm = () => {
|
||||
function resetForm() {
|
||||
resetFormData();
|
||||
};
|
||||
}
|
||||
|
||||
// 重置表单数据
|
||||
const resetFormData = () => {
|
||||
function resetFormData() {
|
||||
Object.assign(formData, {
|
||||
taskName: '',
|
||||
taskGroup: 'DEFAULT',
|
||||
@@ -531,7 +531,7 @@ const resetFormData = () => {
|
||||
misfirePolicy: 2,
|
||||
description: ''
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
|
||||
@@ -455,7 +455,7 @@ const filteredModules = computed(() => {
|
||||
});
|
||||
|
||||
// 加载模块列表
|
||||
const loadModuleList = async () => {
|
||||
async function loadModuleList() {
|
||||
moduleLoading.value = true;
|
||||
try {
|
||||
const result = await moduleApi.getModuleList();
|
||||
@@ -470,10 +470,10 @@ const loadModuleList = async () => {
|
||||
} finally {
|
||||
moduleLoading.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 加载权限列表
|
||||
const loadPermissions = async (moduleID: string) => {
|
||||
async function loadPermissions(moduleID: string) {
|
||||
permissionLoading.value = true;
|
||||
try {
|
||||
const result = await moduleApi.getModulePermissions(moduleID);
|
||||
@@ -489,32 +489,32 @@ const loadPermissions = async (moduleID: string) => {
|
||||
} finally {
|
||||
permissionLoading.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 选择模块
|
||||
const handleSelectModule = (module: SysModule) => {
|
||||
function handleSelectModule(module: SysModule) {
|
||||
currentModule.value = module;
|
||||
if (module.moduleID) {
|
||||
loadPermissions(module.moduleID);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 新增模块
|
||||
const handleAddModule = () => {
|
||||
function handleAddModule() {
|
||||
isEditModule.value = false;
|
||||
resetModuleForm();
|
||||
moduleDialogVisible.value = true;
|
||||
};
|
||||
}
|
||||
|
||||
// 编辑模块
|
||||
const handleEditModule = (module: SysModule) => {
|
||||
function handleEditModule(module: SysModule) {
|
||||
isEditModule.value = true;
|
||||
Object.assign(moduleForm, module);
|
||||
moduleDialogVisible.value = true;
|
||||
};
|
||||
}
|
||||
|
||||
// 删除模块
|
||||
const handleDeleteModule = async (module: SysModule) => {
|
||||
async function handleDeleteModule(module: SysModule) {
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`确定要删除模块"${module.name}"吗?删除后该模块下的所有权限也会被删除。`,
|
||||
@@ -543,10 +543,10 @@ const handleDeleteModule = async (module: SysModule) => {
|
||||
ElMessage.error('删除模块失败');
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 提交模块表单
|
||||
const handleSubmitModule = async () => {
|
||||
async function handleSubmitModule() {
|
||||
if (!moduleForm.name) {
|
||||
ElMessage.warning('请输入模块名称');
|
||||
return;
|
||||
@@ -582,24 +582,24 @@ const handleSubmitModule = async () => {
|
||||
} finally {
|
||||
submitting.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 新增权限
|
||||
const handleAddPermission = () => {
|
||||
function handleAddPermission() {
|
||||
isEditPermission.value = false;
|
||||
resetPermissionForm();
|
||||
permissionDialogVisible.value = true;
|
||||
};
|
||||
}
|
||||
|
||||
// 编辑权限
|
||||
const handleEditPermission = (permission: SysPermission) => {
|
||||
function handleEditPermission(permission: SysPermission) {
|
||||
isEditPermission.value = true;
|
||||
Object.assign(permissionForm, permission);
|
||||
permissionDialogVisible.value = true;
|
||||
};
|
||||
}
|
||||
|
||||
// 删除权限
|
||||
const handleDeletePermission = async (permission: SysPermission) => {
|
||||
async function handleDeletePermission(permission: SysPermission) {
|
||||
if (!currentModule.value) return;
|
||||
|
||||
try {
|
||||
@@ -630,10 +630,10 @@ const handleDeletePermission = async (permission: SysPermission) => {
|
||||
ElMessage.error('删除权限失败');
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 提交权限表单
|
||||
const handleSubmitPermission = async () => {
|
||||
async function handleSubmitPermission() {
|
||||
if (!permissionForm.name) {
|
||||
ElMessage.warning('请输入权限名称');
|
||||
return;
|
||||
@@ -674,10 +674,10 @@ const handleSubmitPermission = async () => {
|
||||
} finally {
|
||||
submitting.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 绑定菜单
|
||||
const handleBindMenu = async (permission: SysPermission) => {
|
||||
async function handleBindMenu(permission: SysPermission) {
|
||||
currentPermission.value = permission;
|
||||
permission.bindType = 'menu';
|
||||
|
||||
@@ -695,10 +695,10 @@ const handleBindMenu = async (permission: SysPermission) => {
|
||||
console.error('获取菜单绑定信息失败:', error);
|
||||
ElMessage.error('获取菜单绑定信息失败');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 绑定角色
|
||||
const handleBindRole = async (permission: SysPermission) => {
|
||||
async function handleBindRole(permission: SysPermission) {
|
||||
currentPermission.value = permission;
|
||||
permission.bindType = 'role';
|
||||
|
||||
@@ -716,14 +716,14 @@ const handleBindRole = async (permission: SysPermission) => {
|
||||
console.error('获取角色绑定信息失败:', error);
|
||||
ElMessage.error('获取角色绑定信息失败');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 菜单选择相关
|
||||
const isMenuSelected = (menuID: string | undefined): boolean => {
|
||||
function isMenuSelected(menuID: string | undefined): boolean {
|
||||
return menuID ? selectedMenus.value.includes(menuID) : false;
|
||||
};
|
||||
}
|
||||
|
||||
const toggleMenuSelection = (menu: SysMenu) => {
|
||||
function toggleMenuSelection(menu: SysMenu) {
|
||||
if (!menu.menuID) return;
|
||||
const index = selectedMenus.value.indexOf(menu.menuID);
|
||||
if (index > -1) {
|
||||
@@ -731,14 +731,14 @@ const toggleMenuSelection = (menu: SysMenu) => {
|
||||
} else {
|
||||
selectedMenus.value.push(menu.menuID);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 角色选择相关
|
||||
const isRoleSelected = (roleID: string | undefined): boolean => {
|
||||
function isRoleSelected(roleID: string | undefined): boolean {
|
||||
return roleID ? selectedRoles.value.includes(roleID) : false;
|
||||
};
|
||||
}
|
||||
|
||||
const toggleRoleSelection = (role: SysRole) => {
|
||||
function toggleRoleSelection(role: SysRole) {
|
||||
if (!role.roleID) return;
|
||||
const index = selectedRoles.value.indexOf(role.roleID);
|
||||
if (index > -1) {
|
||||
@@ -746,10 +746,10 @@ const toggleRoleSelection = (role: SysRole) => {
|
||||
} else {
|
||||
selectedRoles.value.push(role.roleID);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 保存菜单绑定
|
||||
const saveMenuBinding = async () => {
|
||||
async function saveMenuBinding() {
|
||||
if (!currentPermission.value?.permissionID) {
|
||||
ElMessage.error('权限信息不完整');
|
||||
return;
|
||||
@@ -792,10 +792,10 @@ const saveMenuBinding = async () => {
|
||||
} finally {
|
||||
submitting.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 保存角色绑定
|
||||
const saveRoleBinding = async () => {
|
||||
async function saveRoleBinding() {
|
||||
if (!currentPermission.value?.permissionID) {
|
||||
ElMessage.error('权限信息不完整');
|
||||
return;
|
||||
@@ -837,10 +837,10 @@ const saveRoleBinding = async () => {
|
||||
} finally {
|
||||
submitting.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 重置表单
|
||||
const resetModuleForm = () => {
|
||||
function resetModuleForm() {
|
||||
Object.assign(moduleForm, {
|
||||
name: '',
|
||||
code: '',
|
||||
@@ -849,21 +849,21 @@ const resetModuleForm = () => {
|
||||
orderNum: 0,
|
||||
status: 1
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
const resetPermissionForm = () => {
|
||||
function resetPermissionForm() {
|
||||
Object.assign(permissionForm, {
|
||||
name: '',
|
||||
code: '',
|
||||
description: ''
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
const resetBindList = () => {
|
||||
function resetBindList() {
|
||||
selectedMenus.value = [];
|
||||
selectedRoles.value = [];
|
||||
currentPermission.value = null;
|
||||
};
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
|
||||
Reference in New Issue
Block a user