mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-10-10 11:31:38 +00:00
feat(web): 升级至 v3.0 并重构组件与引导流程
- 提取应用引导逻辑至 useAppBootstrap 组合式函数 - 增强日期选择器组件,支持全类型与格式自动推导 - 修复资源泄漏:清理 RAF、定时器、事件与 mitt 监听 - 修复退出登录逻辑与异步导出流程 - 迁移 ::v-deep 至 Vue 3 标准 :deep 语法 - 移除调试日志并改进类型定义与注释文档
This commit is contained in:
@@ -22,8 +22,8 @@ defineEmits<{ link: [] }>();
|
||||
|
||||
<style scoped lang="scss">
|
||||
.login-auth-link-row {
|
||||
::v-deep(.el-link),
|
||||
::v-deep(.el-link__inner) {
|
||||
:deep(.el-link),
|
||||
:deep(.el-link__inner) {
|
||||
line-height: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,11 +246,11 @@ html.dark {
|
||||
|
||||
/* EP 全局规则:相邻 .el-button { margin-left: 12px },纵向叠放时仍会命中,导致第二颗按钮横向错位 */
|
||||
.login-mobile-actions {
|
||||
::v-deep(.el-button + .el-button) {
|
||||
:deep(.el-button + .el-button) {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
|
||||
::v-deep(.el-button) {
|
||||
:deep(.el-button) {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
|
||||
@@ -78,7 +78,7 @@ const qrPayload = computed(() => {
|
||||
|
||||
/* EP:相邻按钮横向间距;单列返回按钮无需处理 */
|
||||
.login-mobile-actions {
|
||||
::v-deep(.el-button) {
|
||||
:deep(.el-button) {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
|
||||
@@ -546,12 +546,14 @@ const showVoteNotification = () => {
|
||||
});
|
||||
};
|
||||
|
||||
let voteTimer: ReturnType<typeof setTimeout> | null = null;
|
||||
|
||||
onMounted(async () => {
|
||||
setupAccount("super");
|
||||
await configStore.getConfig();
|
||||
await tryConsumeOAuthCallback();
|
||||
getCaptcha();
|
||||
setTimeout(showVoteNotification, 500);
|
||||
voteTimer = setTimeout(showVoteNotification, 500);
|
||||
});
|
||||
|
||||
onActivated(() => {
|
||||
@@ -561,6 +563,7 @@ onActivated(() => {
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (voteTimer !== null) clearTimeout(voteTimer);
|
||||
notificationInstance?.close();
|
||||
notificationInstance = null;
|
||||
});
|
||||
@@ -661,68 +664,68 @@ async function submitForget() {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.login-page-panel {
|
||||
::v-deep(.btn) {
|
||||
:deep(.btn) {
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
html.dark .login-page-panel {
|
||||
::v-deep(.text-g-800) {
|
||||
:deep(.text-g-800) {
|
||||
color: rgb(255 255 255 / 78%) !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 副标题与表单块间距(login-page-form 在子组件内,须 :deep) */
|
||||
::v-deep(.login-page-form) {
|
||||
:deep(.login-page-form) {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
::v-deep(.login-page-form .el-form-item) {
|
||||
:deep(.login-page-form .el-form-item) {
|
||||
margin-bottom: 1.1rem;
|
||||
}
|
||||
|
||||
::v-deep(.el-select__wrapper) {
|
||||
:deep(.el-select__wrapper) {
|
||||
min-height: 42px !important;
|
||||
}
|
||||
|
||||
/* 仅账号登录底部「手机号 / 扫码」双列按钮需要 42px;手机号登录页的返回钮与主按钮同为 h-11,勿全局压高度 */
|
||||
::v-deep(.login-secondary-actions .login-secondary-btn) {
|
||||
:deep(.login-secondary-actions .login-secondary-btn) {
|
||||
height: 42px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
html.dark {
|
||||
::v-deep(.login-page-form .el-input__wrapper) {
|
||||
:deep(.login-page-form .el-input__wrapper) {
|
||||
background-color: rgb(255 255 255 / 6%) !important;
|
||||
box-shadow: 0 0 0 1px rgb(255 255 255 / 10%) inset !important;
|
||||
}
|
||||
|
||||
::v-deep(.login-page-form .el-input__inner) {
|
||||
:deep(.login-page-form .el-input__inner) {
|
||||
color: rgb(255 255 255 / 92%);
|
||||
}
|
||||
|
||||
::v-deep(.login-page-form .el-input__inner::placeholder) {
|
||||
:deep(.login-page-form .el-input__inner::placeholder) {
|
||||
color: rgb(255 255 255 / 35%);
|
||||
}
|
||||
|
||||
::v-deep(.login-page-form .el-select .el-select__wrapper) {
|
||||
:deep(.login-page-form .el-select .el-select__wrapper) {
|
||||
background-color: rgb(255 255 255 / 6%) !important;
|
||||
box-shadow: 0 0 0 1px rgb(255 255 255 / 10%) inset !important;
|
||||
}
|
||||
|
||||
::v-deep(.login-page-form .el-select__placeholder) {
|
||||
:deep(.login-page-form .el-select__placeholder) {
|
||||
color: rgb(255 255 255 / 40%);
|
||||
}
|
||||
|
||||
::v-deep(.login-page-form .el-select__selected-item) {
|
||||
:deep(.login-page-form .el-select__selected-item) {
|
||||
color: rgb(255 255 255 / 92%);
|
||||
}
|
||||
|
||||
::v-deep(.login-remember .el-checkbox__label) {
|
||||
:deep(.login-remember .el-checkbox__label) {
|
||||
color: rgb(255 255 255 / 65%);
|
||||
}
|
||||
|
||||
::v-deep(.login-secondary-btn) {
|
||||
:deep(.login-secondary-btn) {
|
||||
color: rgb(255 255 255 / 85%) !important;
|
||||
background: transparent !important;
|
||||
border-color: rgb(255 255 255 / 22%) !important;
|
||||
@@ -735,7 +738,7 @@ html.dark {
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep(.login-secondary-actions .login-secondary-btn) {
|
||||
:deep(.login-secondary-actions .login-secondary-btn) {
|
||||
height: 42px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,20 +310,21 @@ async function loadDeptData() {
|
||||
}
|
||||
}
|
||||
|
||||
function deleteDeptRow(id: number) {
|
||||
ElMessageBox.confirm("确认删除该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
await DeptAPI.deleteDept([id]);
|
||||
await userStore.getUserInfo();
|
||||
ElMessage.success("删除成功");
|
||||
selectedRows.value = [];
|
||||
await loadDeptData();
|
||||
})
|
||||
.catch(() => {});
|
||||
async function deleteDeptRow(id: number) {
|
||||
try {
|
||||
await ElMessageBox.confirm("确认删除该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
await DeptAPI.deleteDept([id]);
|
||||
await userStore.getUserInfo();
|
||||
ElMessage.success("删除成功");
|
||||
selectedRows.value = [];
|
||||
await loadDeptData();
|
||||
} catch {
|
||||
// 用户取消
|
||||
}
|
||||
}
|
||||
|
||||
const opCtx = {
|
||||
@@ -545,50 +546,46 @@ async function handleSubmit() {
|
||||
});
|
||||
}
|
||||
|
||||
function handleBatchDelete() {
|
||||
async function handleBatchDelete() {
|
||||
const ids = selectedIds.value;
|
||||
if (ids.length === 0) return;
|
||||
ElMessageBox.confirm(`确定删除选中的 ${ids.length} 条数据吗?`, "批量删除", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
batchDeleting.value = true;
|
||||
await DeptAPI.deleteDept(ids);
|
||||
await userStore.getUserInfo();
|
||||
ElMessage.success("删除成功");
|
||||
selectedRows.value = [];
|
||||
await loadDeptData();
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
try {
|
||||
await ElMessageBox.confirm(`确定删除选中的 ${ids.length} 条数据吗?`, "批量删除", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
batchDeleting.value = true;
|
||||
await DeptAPI.deleteDept(ids);
|
||||
await userStore.getUserInfo();
|
||||
ElMessage.success("删除成功");
|
||||
selectedRows.value = [];
|
||||
await loadDeptData();
|
||||
} catch {
|
||||
// 用户取消
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function handleMoreClick(status: string) {
|
||||
async function handleMoreClick(status: string) {
|
||||
const ids = selectedIds.value;
|
||||
if (!ids.length) {
|
||||
ElMessage.warning("请先选择要操作的数据");
|
||||
return;
|
||||
}
|
||||
ElMessageBox.confirm(`确认${status === "0" ? "启用" : "停用"}该项数据?`, "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
await DeptAPI.batchDept({ ids, status });
|
||||
await loadDeptData();
|
||||
await userStore.getUserInfo();
|
||||
} catch (error: unknown) {
|
||||
console.error(error);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
try {
|
||||
await ElMessageBox.confirm(`确认${status === "0" ? "启用" : "停用"}该项数据?`, "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
await DeptAPI.batchDept({ ids, status });
|
||||
await loadDeptData();
|
||||
await userStore.getUserInfo();
|
||||
} catch {
|
||||
// 用户取消或操作失败
|
||||
}
|
||||
}
|
||||
|
||||
function toggleExpand() {
|
||||
@@ -614,15 +611,15 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.crud-dialog-art-form ::v-deep(.el-row > .el-col:last-child) {
|
||||
.crud-dialog-art-form :deep(.el-row > .el-col:last-child) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.crud-dialog-art-form ::v-deep(.el-form-item__content) {
|
||||
.crud-dialog-art-form :deep(.el-form-item__content) {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
::v-deep(.dept-table-actions .inline-flex) {
|
||||
:deep(.dept-table-actions .inline-flex) {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -786,71 +786,66 @@ function formatDictDataOperationCell(row: DictDataTable) {
|
||||
});
|
||||
}
|
||||
|
||||
function deleteDictDataRow(id: number) {
|
||||
ElMessageBox.confirm("确认删除该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
await DictAPI.deleteDictData([id]);
|
||||
dictStore.clearDictData();
|
||||
if (props.dictType) {
|
||||
await dictStore.getDict([props.dictType]);
|
||||
}
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
})
|
||||
.catch(() => {});
|
||||
async function deleteDictDataRow(id: number) {
|
||||
try {
|
||||
await ElMessageBox.confirm("确认删除该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
await DictAPI.deleteDictData([id]);
|
||||
dictStore.clearDictData();
|
||||
if (props.dictType) await dictStore.getDict([props.dictType]);
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} catch {
|
||||
// 用户取消
|
||||
}
|
||||
}
|
||||
|
||||
function handleBatchDelete() {
|
||||
async function handleBatchDelete() {
|
||||
const ids = selectedIds.value;
|
||||
if (ids.length === 0) return;
|
||||
ElMessageBox.confirm(`确定删除选中的 ${ids.length} 条数据吗?`, "批量删除", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
batchDeleting.value = true;
|
||||
await DictAPI.deleteDictData(ids);
|
||||
dictStore.clearDictData();
|
||||
if (props.dictType) {
|
||||
await dictStore.getDict([props.dictType]);
|
||||
}
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
try {
|
||||
await ElMessageBox.confirm(`确定删除选中的 ${ids.length} 条数据吗?`, "批量删除", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
batchDeleting.value = true;
|
||||
await DictAPI.deleteDictData(ids);
|
||||
dictStore.clearDictData();
|
||||
if (props.dictType) await dictStore.getDict([props.dictType]);
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} catch {
|
||||
// 用户取消
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function handleMoreClick(status: string) {
|
||||
async function handleMoreClick(status: string) {
|
||||
const ids = selectedIds.value;
|
||||
if (!ids.length) {
|
||||
ElMessage.warning("请先选择要操作的数据");
|
||||
return;
|
||||
}
|
||||
ElMessageBox.confirm(`确认${status === "0" ? "启用" : "停用"}该项数据?`, "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
await DictAPI.batchDictData({ ids, status });
|
||||
await refreshData();
|
||||
dictStore.clearDictData();
|
||||
if (props.dictType) {
|
||||
await dictStore.getDict([props.dictType]);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
try {
|
||||
await ElMessageBox.confirm(`确认${status === "0" ? "启用" : "停用"}该项数据?`, "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
await DictAPI.batchDictData({ ids, status });
|
||||
await refreshData();
|
||||
dictStore.clearDictData();
|
||||
if (props.dictType) await dictStore.getDict([props.dictType]);
|
||||
} catch {
|
||||
// 用户取消
|
||||
}
|
||||
}
|
||||
|
||||
function openExportModal() {
|
||||
@@ -890,11 +885,11 @@ function openExportModal() {
|
||||
border-color: var(--el-border-color-lighter);
|
||||
}
|
||||
|
||||
.crud-dialog-art-form ::v-deep(.el-row > .el-col:last-child) {
|
||||
.crud-dialog-art-form :deep(.el-row > .el-col:last-child) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.crud-dialog-art-form ::v-deep(.el-form-item__content) {
|
||||
.crud-dialog-art-form :deep(.el-form-item__content) {
|
||||
max-width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -560,74 +560,69 @@ async function handleSubmit() {
|
||||
});
|
||||
}
|
||||
|
||||
function deleteDictTypeRow(id: number) {
|
||||
ElMessageBox.confirm("确认删除该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
await DictAPI.deleteDictType([id]);
|
||||
dictStore.clearDictData();
|
||||
const dictTypes = Object.keys(dictStore.dictData);
|
||||
if (dictTypes.length > 0) {
|
||||
await dictStore.getDict(dictTypes);
|
||||
}
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
})
|
||||
.catch(() => {});
|
||||
async function deleteDictTypeRow(id: number) {
|
||||
try {
|
||||
await ElMessageBox.confirm("确认删除该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
await DictAPI.deleteDictType([id]);
|
||||
dictStore.clearDictData();
|
||||
const dictTypes = Object.keys(dictStore.dictData);
|
||||
if (dictTypes.length > 0) await dictStore.getDict(dictTypes);
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} catch {
|
||||
// 用户取消
|
||||
}
|
||||
}
|
||||
|
||||
function handleBatchDelete() {
|
||||
async function handleBatchDelete() {
|
||||
const ids = selectedIds.value;
|
||||
if (ids.length === 0) return;
|
||||
ElMessageBox.confirm(`确定删除选中的 ${ids.length} 条数据吗?`, "批量删除", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
batchDeleting.value = true;
|
||||
await DictAPI.deleteDictType(ids);
|
||||
dictStore.clearDictData();
|
||||
const dictTypes = Object.keys(dictStore.dictData);
|
||||
if (dictTypes.length > 0) {
|
||||
await dictStore.getDict(dictTypes);
|
||||
}
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
try {
|
||||
await ElMessageBox.confirm(`确定删除选中的 ${ids.length} 条数据吗?`, "批量删除", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
batchDeleting.value = true;
|
||||
await DictAPI.deleteDictType(ids);
|
||||
dictStore.clearDictData();
|
||||
const dictTypes = Object.keys(dictStore.dictData);
|
||||
if (dictTypes.length > 0) await dictStore.getDict(dictTypes);
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} catch {
|
||||
// 用户取消
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function handleMoreClick(status: string) {
|
||||
async function handleMoreClick(status: string) {
|
||||
const ids = selectedIds.value;
|
||||
if (!ids.length) {
|
||||
ElMessage.warning("请先选择要操作的数据");
|
||||
return;
|
||||
}
|
||||
ElMessageBox.confirm(`确认${status === "0" ? "启用" : "停用"}该项数据?`, "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
await DictAPI.batchDictType({ ids, status });
|
||||
await refreshData();
|
||||
dictStore.clearDictData();
|
||||
const dictTypes = Object.keys(dictStore.dictData);
|
||||
if (dictTypes.length > 0) {
|
||||
await dictStore.getDict(dictTypes);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
try {
|
||||
await ElMessageBox.confirm(`确认${status === "0" ? "启用" : "停用"}该项数据?`, "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
await DictAPI.batchDictType({ ids, status });
|
||||
await refreshData();
|
||||
dictStore.clearDictData();
|
||||
const dictTypes = Object.keys(dictStore.dictData);
|
||||
if (dictTypes.length > 0) await dictStore.getDict(dictTypes);
|
||||
} catch {
|
||||
// 用户取消
|
||||
}
|
||||
}
|
||||
|
||||
function openExportModal() {
|
||||
@@ -636,11 +631,11 @@ function openExportModal() {
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.crud-dialog-art-form ::v-deep(.el-row > .el-col:last-child) {
|
||||
.crud-dialog-art-form :deep(.el-row > .el-col:last-child) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.crud-dialog-art-form ::v-deep(.el-form-item__content) {
|
||||
.crud-dialog-art-form :deep(.el-form-item__content) {
|
||||
max-width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -461,19 +461,20 @@ async function handleOpenDialog(id: number) {
|
||||
dialogVisible.value.visible = true;
|
||||
}
|
||||
|
||||
function deleteLogRow(id: number) {
|
||||
ElMessageBox.confirm("确认删除该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
await LogAPI.deleteLog([id]);
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
})
|
||||
.catch(() => {});
|
||||
async function deleteLogRow(id: number) {
|
||||
try {
|
||||
await ElMessageBox.confirm("确认删除该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
await LogAPI.deleteLog([id]);
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} catch {
|
||||
// 用户取消
|
||||
}
|
||||
}
|
||||
|
||||
function buildLogRowActions(row: LogTable): TableOperationAction[] {
|
||||
@@ -507,26 +508,25 @@ function formatLogOperationCell(row: LogTable) {
|
||||
});
|
||||
}
|
||||
|
||||
function handleBatchDelete() {
|
||||
async function handleBatchDelete() {
|
||||
const ids = selectedIds.value;
|
||||
if (ids.length === 0) return;
|
||||
ElMessageBox.confirm(`确定删除选中的 ${ids.length} 条数据吗?`, "批量删除", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
batchDeleting.value = true;
|
||||
await LogAPI.deleteLog(ids);
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
try {
|
||||
await ElMessageBox.confirm(`确定删除选中的 ${ids.length} 条数据吗?`, "批量删除", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
batchDeleting.value = true;
|
||||
await LogAPI.deleteLog(ids);
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} catch {
|
||||
// 用户取消
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function openExportModal() {
|
||||
|
||||
@@ -436,7 +436,7 @@
|
||||
|
||||
<ElFormItem v-if="formData.type !== MenuTypeEnum.BUTTON" label="图标" prop="icon">
|
||||
<!-- 图标选择器 -->
|
||||
<icon-select v-model="formData.icon" />
|
||||
<FaIconSelect v-model="formData.icon" />
|
||||
</ElFormItem>
|
||||
|
||||
<ElFormItem
|
||||
@@ -527,6 +527,7 @@ import FaTableHeaderLeft from "@/components/tables/fa-table-header-left/index.vu
|
||||
import FaSearchBar from "@/components/forms/fa-search-bar/index.vue";
|
||||
import type { SearchFormItem } from "@/components/forms/fa-search-bar/index.vue";
|
||||
import FaDrawer from "@/components/modal/fa-drawer/index.vue";
|
||||
import FaIconSelect from "@/components/others/fa-icon-select/index.vue";
|
||||
import { ElMessage, ElMessageBox, ElTag, ElTooltip } from "element-plus";
|
||||
import { useAuth } from "@/hooks/core/useAuth";
|
||||
import { renderTableOperationCell, type TableOperationAction } from "@utils/table";
|
||||
@@ -820,20 +821,22 @@ function toggleExpand() {
|
||||
});
|
||||
}
|
||||
|
||||
function deleteMenuRow(id: number) {
|
||||
ElMessageBox.confirm("确认删除该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
await MenuAPI.deleteMenu([id]);
|
||||
await userStore.getUserInfo();
|
||||
ElMessage.success("删除成功");
|
||||
selectedRows.value = [];
|
||||
await loadMenuData();
|
||||
})
|
||||
.catch(() => {});
|
||||
async function deleteMenuRow(id: number) {
|
||||
try {
|
||||
await ElMessageBox.confirm("确认删除该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
|
||||
await MenuAPI.deleteMenu([id]);
|
||||
await userStore.getUserInfo();
|
||||
ElMessage.success("删除成功");
|
||||
selectedRows.value = [];
|
||||
await loadMenuData();
|
||||
} catch {
|
||||
// 用户取消
|
||||
}
|
||||
}
|
||||
|
||||
const opCtx = {
|
||||
@@ -1040,11 +1043,11 @@ async function handleOpenDialog(
|
||||
Object.assign(detailFormData.value, response.data.data ?? {});
|
||||
} else if (type === "update") {
|
||||
dialogVisible.title = "修改菜单";
|
||||
Object.assign(formData, response.data.data);
|
||||
Object.assign(formData.value, response.data.data);
|
||||
}
|
||||
} else {
|
||||
dialogVisible.title = "新增菜单";
|
||||
Object.assign(formData, initialFormData);
|
||||
formData.value = { ...initialFormData };
|
||||
if (parentRow?.id != null) {
|
||||
formData.value.parent_id = parentRow.id;
|
||||
formData.value.client = (parentRow.client as MenuClientEnum) || menuClientTab.value;
|
||||
@@ -1102,27 +1105,26 @@ async function handleSubmit() {
|
||||
});
|
||||
}
|
||||
|
||||
function handleBatchDelete() {
|
||||
async function handleBatchDelete() {
|
||||
const ids = selectedIds.value;
|
||||
if (ids.length === 0) return;
|
||||
ElMessageBox.confirm(`确定删除选中的 ${ids.length} 条数据吗?`, "批量删除", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
batchDeleting.value = true;
|
||||
await MenuAPI.deleteMenu(ids);
|
||||
await userStore.getUserInfo();
|
||||
ElMessage.success("删除成功");
|
||||
selectedRows.value = [];
|
||||
await loadMenuData();
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
try {
|
||||
await ElMessageBox.confirm(`确定删除选中的 ${ids.length} 条数据吗?`, "批量删除", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
batchDeleting.value = true;
|
||||
await MenuAPI.deleteMenu(ids);
|
||||
await userStore.getUserInfo();
|
||||
ElMessage.success("删除成功");
|
||||
selectedRows.value = [];
|
||||
await loadMenuData();
|
||||
} catch {
|
||||
// 用户取消
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function handleMoreClick(status: string) {
|
||||
@@ -1135,16 +1137,18 @@ async function handleMoreClick(status: string) {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
await MenuAPI.batchMenu({ ids, status });
|
||||
await loadMenuData();
|
||||
} catch (error: unknown) {
|
||||
console.error(error);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
});
|
||||
try {
|
||||
await ElMessageBox.confirm("确认启用或停用该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
await MenuAPI.batchMenu({ ids, status });
|
||||
await loadMenuData();
|
||||
} catch {
|
||||
// 用户取消
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
@@ -1153,7 +1157,7 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
::v-deep(.menu-table-actions .inline-flex) {
|
||||
:deep(.menu-table-actions .inline-flex) {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -637,20 +637,22 @@ async function handleSubmit() {
|
||||
});
|
||||
}
|
||||
|
||||
function deleteNoticeRow(id: number) {
|
||||
ElMessageBox.confirm("确认删除该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
await NoticeAPI.deleteNotice([id]);
|
||||
await noticeStore.getNotice();
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
})
|
||||
.catch(() => {});
|
||||
async function deleteNoticeRow(id: number) {
|
||||
try {
|
||||
await ElMessageBox.confirm("确认删除该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
|
||||
await NoticeAPI.deleteNotice([id]);
|
||||
await noticeStore.getNotice();
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} catch {
|
||||
// 用户取消
|
||||
}
|
||||
}
|
||||
|
||||
function buildNoticeRowActions(row: NoticeTable): TableOperationAction[] {
|
||||
@@ -694,30 +696,29 @@ function formatNoticeOperationCell(row: NoticeTable) {
|
||||
});
|
||||
}
|
||||
|
||||
function handleBatchDelete() {
|
||||
async function handleBatchDelete() {
|
||||
const ids = selectedIds.value;
|
||||
if (ids.length === 0) return;
|
||||
ElMessageBox.confirm(`确定删除选中的 ${ids.length} 条数据吗?`, "批量删除", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
batchDeleting.value = true;
|
||||
await NoticeAPI.deleteNotice(ids);
|
||||
await noticeStore.getNotice();
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
try {
|
||||
await ElMessageBox.confirm(`确定删除选中的 ${ids.length} 条数据吗?`, "批量删除", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
batchDeleting.value = true;
|
||||
await NoticeAPI.deleteNotice(ids);
|
||||
await noticeStore.getNotice();
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} catch {
|
||||
// 用户取消
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function handleMoreClick(status: string) {
|
||||
async function handleMoreClick(status: string) {
|
||||
const ids = selectedIds.value;
|
||||
if (!ids.length) {
|
||||
ElMessage.warning("请先选择要操作的数据");
|
||||
@@ -727,13 +728,14 @@ function handleMoreClick(status: string) {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
await NoticeAPI.batchNotice({ ids, status });
|
||||
await refreshData();
|
||||
await noticeStore.getNotice();
|
||||
})
|
||||
.catch(() => {});
|
||||
});
|
||||
try {
|
||||
await NoticeAPI.batchNotice({ ids, status });
|
||||
await refreshData();
|
||||
await noticeStore.getNotice();
|
||||
} catch {
|
||||
// 用户取消
|
||||
}
|
||||
}
|
||||
|
||||
function openExportModal() {
|
||||
@@ -747,11 +749,11 @@ onMounted(async () => {
|
||||
|
||||
<style scoped lang="scss">
|
||||
/* FaForm 底部预留的操作栏列在弹窗内不需要占位 */
|
||||
.crud-dialog-art-form ::v-deep(.el-row > .el-col:last-child) {
|
||||
.crud-dialog-art-form :deep(.el-row > .el-col:last-child) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.crud-dialog-art-form ::v-deep(.el-form-item__content) {
|
||||
.crud-dialog-art-form :deep(.el-form-item__content) {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
@@ -773,27 +775,27 @@ onMounted(async () => {
|
||||
color: var(--el-text-color-placeholder);
|
||||
}
|
||||
|
||||
.notice-html-preview ::v-deep(h1),
|
||||
.notice-html-preview ::v-deep(h2),
|
||||
.notice-html-preview ::v-deep(h3) {
|
||||
.notice-html-preview :deep(h1),
|
||||
.notice-html-preview :deep(h2),
|
||||
.notice-html-preview :deep(h3) {
|
||||
margin: 12px 0 8px;
|
||||
}
|
||||
|
||||
.notice-html-preview ::v-deep(p) {
|
||||
.notice-html-preview :deep(p) {
|
||||
margin: 8px 0;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.notice-html-preview ::v-deep(table) {
|
||||
.notice-html-preview :deep(table) {
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
.notice-html-preview ::v-deep(table th),
|
||||
.notice-html-preview ::v-deep(table td) {
|
||||
.notice-html-preview :deep(table th),
|
||||
.notice-html-preview :deep(table td) {
|
||||
padding: 8px 12px;
|
||||
}
|
||||
|
||||
.notice-html-preview ::v-deep(pre) {
|
||||
.notice-html-preview :deep(pre) {
|
||||
padding: 12px;
|
||||
margin: 12px 0;
|
||||
overflow-x: auto;
|
||||
@@ -801,14 +803,14 @@ onMounted(async () => {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.notice-html-preview ::v-deep(blockquote) {
|
||||
.notice-html-preview :deep(blockquote) {
|
||||
padding-left: 16px;
|
||||
margin: 12px 0;
|
||||
color: var(--el-text-color-regular);
|
||||
border-left: 4px solid var(--el-color-primary);
|
||||
}
|
||||
|
||||
.notice-html-preview ::v-deep(img) {
|
||||
.notice-html-preview :deep(img) {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<!-- 参数配置 -->
|
||||
<template>
|
||||
<FaDrawer
|
||||
v-model="drawerVisible"
|
||||
@@ -716,12 +717,12 @@ const logoConfigs = computed(() => ({
|
||||
const handleUploadSuccess = (fileInfo: UploadFilePath, type: string) => {
|
||||
const fileUrl = fileInfo.file_url;
|
||||
if (type in configStore.configData) {
|
||||
(configStore.configData as any)[type].config_value = fileUrl;
|
||||
(configStore.configData as Record<string, ConfigTable>)[type].config_value = fileUrl;
|
||||
}
|
||||
if (type in systemConfigs.value) {
|
||||
(systemConfigs.value as any)[type].config_value = fileUrl;
|
||||
(systemConfigs.value as Record<string, { config_value: string }>)[type].config_value = fileUrl;
|
||||
} else if (type in logoConfigs.value) {
|
||||
(logoConfigs.value as any)[type].config_value = fileUrl;
|
||||
(logoConfigs.value as Record<string, { config_value: string }>)[type].config_value = fileUrl;
|
||||
}
|
||||
markModified(type);
|
||||
};
|
||||
|
||||
@@ -510,21 +510,23 @@ async function handleSubmit() {
|
||||
});
|
||||
}
|
||||
|
||||
function deleteParamRow(id: number) {
|
||||
ElMessageBox.confirm("确认删除该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
await ParamsAPI.deleteParams([id]);
|
||||
configStore.isConfigLoaded = false;
|
||||
await configStore.getConfig();
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
})
|
||||
.catch(() => {});
|
||||
async function deleteParamRow(id: number) {
|
||||
try {
|
||||
await ElMessageBox.confirm("确认删除该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
|
||||
await ParamsAPI.deleteParams([id]);
|
||||
configStore.isConfigLoaded = false;
|
||||
await configStore.getConfig();
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} catch {
|
||||
// 用户取消
|
||||
}
|
||||
}
|
||||
|
||||
function buildParamRowActions(row: ConfigTable): TableOperationAction[] {
|
||||
@@ -568,28 +570,27 @@ function formatParamOperationCell(row: ConfigTable) {
|
||||
});
|
||||
}
|
||||
|
||||
function handleBatchDelete() {
|
||||
async function handleBatchDelete() {
|
||||
const ids = selectedIds.value;
|
||||
if (ids.length === 0) return;
|
||||
ElMessageBox.confirm(`确定删除选中的 ${ids.length} 条数据吗?`, "批量删除", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
batchDeleting.value = true;
|
||||
await ParamsAPI.deleteParams(ids);
|
||||
configStore.isConfigLoaded = false;
|
||||
await configStore.getConfig();
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
try {
|
||||
await ElMessageBox.confirm(`确定删除选中的 ${ids.length} 条数据吗?`, "批量删除", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
batchDeleting.value = true;
|
||||
await ParamsAPI.deleteParams(ids);
|
||||
configStore.isConfigLoaded = false;
|
||||
await configStore.getConfig();
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} catch {
|
||||
// 用户取消
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function openExportModal() {
|
||||
@@ -598,11 +599,11 @@ function openExportModal() {
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.crud-dialog-art-form ::v-deep(.el-row > .el-col:last-child) {
|
||||
.crud-dialog-art-form :deep(.el-row > .el-col:last-child) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.crud-dialog-art-form ::v-deep(.el-form-item__content) {
|
||||
.crud-dialog-art-form :deep(.el-form-item__content) {
|
||||
max-width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -403,20 +403,22 @@ function onTableSelectionChange(rows: PositionTable[]) {
|
||||
selectedRows.value = rows;
|
||||
}
|
||||
|
||||
function deletePositionRow(id: number) {
|
||||
ElMessageBox.confirm("确认删除该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
await PositionAPI.deletePosition([id]);
|
||||
await userStore.getUserInfo();
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
})
|
||||
.catch(() => {});
|
||||
async function deletePositionRow(id: number) {
|
||||
try {
|
||||
await ElMessageBox.confirm("确认删除该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
|
||||
await PositionAPI.deletePosition([id]);
|
||||
await userStore.getUserInfo();
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} catch {
|
||||
// 用户取消
|
||||
}
|
||||
}
|
||||
|
||||
const opCtx = {
|
||||
@@ -680,63 +682,59 @@ async function handleSubmit() {
|
||||
});
|
||||
}
|
||||
|
||||
function handleBatchDelete() {
|
||||
async function handleBatchDelete() {
|
||||
const ids = selectedIds.value;
|
||||
if (ids.length === 0) return;
|
||||
ElMessageBox.confirm(`确定删除选中的 ${ids.length} 条数据吗?`, "批量删除", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
batchDeleting.value = true;
|
||||
await PositionAPI.deletePosition(ids);
|
||||
await userStore.getUserInfo();
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
try {
|
||||
await ElMessageBox.confirm(`确定删除选中的 ${ids.length} 条数据吗?`, "批量删除", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
batchDeleting.value = true;
|
||||
await PositionAPI.deletePosition(ids);
|
||||
await userStore.getUserInfo();
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} catch {
|
||||
// 用户取消
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function handleMoreClick(status: string) {
|
||||
async function handleMoreClick(status: string) {
|
||||
const ids = selectedIds.value;
|
||||
if (!ids.length) {
|
||||
ElMessage.warning("请先选择要操作的数据");
|
||||
return;
|
||||
}
|
||||
ElMessageBox.confirm(`确认${status === "0" ? "启用" : "停用"}该项数据?`, "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
await PositionAPI.batchPosition({ ids, status });
|
||||
await refreshData();
|
||||
await userStore.getUserInfo();
|
||||
} catch (error: unknown) {
|
||||
console.error(error);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
try {
|
||||
await ElMessageBox.confirm(`确认${status === "0" ? "启用" : "停用"}该项数据?`, "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
await PositionAPI.batchPosition({ ids, status });
|
||||
await refreshData();
|
||||
await userStore.getUserInfo();
|
||||
} catch {
|
||||
// 用户取消
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.crud-dialog-art-form ::v-deep(.el-row > .el-col:last-child) {
|
||||
.crud-dialog-art-form :deep(.el-row > .el-col:last-child) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.crud-dialog-art-form ::v-deep(.el-form-item__content) {
|
||||
.crud-dialog-art-form :deep(.el-form-item__content) {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
::v-deep(.position-table-actions .inline-flex) {
|
||||
:deep(.position-table-actions .inline-flex) {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -409,21 +409,22 @@ function handleOpenAssignPermDialog(roleId: number, roleName: string) {
|
||||
drawerVisible.value = true;
|
||||
}
|
||||
|
||||
function deleteRoleRow(id: number) {
|
||||
ElMessageBox.confirm("确认删除该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
await RoleAPI.deleteRole([id]);
|
||||
const userStore = useUserStore();
|
||||
await userStore.getUserInfo();
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
})
|
||||
.catch(() => {});
|
||||
async function deleteRoleRow(id: number) {
|
||||
try {
|
||||
await ElMessageBox.confirm("确认删除该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
await RoleAPI.deleteRole([id]);
|
||||
const userStore = useUserStore();
|
||||
await userStore.getUserInfo();
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} catch {
|
||||
// 用户取消
|
||||
}
|
||||
}
|
||||
|
||||
const opCtx = {
|
||||
@@ -716,48 +717,48 @@ async function handleSubmit() {
|
||||
});
|
||||
}
|
||||
|
||||
function handleBatchDelete() {
|
||||
async function handleBatchDelete() {
|
||||
const ids = selectedIds.value;
|
||||
if (ids.length === 0) return;
|
||||
ElMessageBox.confirm(`确定删除选中的 ${ids.length} 条数据吗?`, "批量删除", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
batchDeleting.value = true;
|
||||
await RoleAPI.deleteRole(ids);
|
||||
const userStore = useUserStore();
|
||||
await userStore.getUserInfo();
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
try {
|
||||
await ElMessageBox.confirm(`确定删除选中的 ${ids.length} 条数据吗?`, "批量删除", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
batchDeleting.value = true;
|
||||
await RoleAPI.deleteRole(ids);
|
||||
const userStore = useUserStore();
|
||||
await userStore.getUserInfo();
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} catch {
|
||||
// 用户取消
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function handleMoreClick(status: string) {
|
||||
async function handleMoreClick(status: string) {
|
||||
const ids = selectedIds.value;
|
||||
if (!ids.length) {
|
||||
ElMessage.warning("请先选择要操作的数据");
|
||||
return;
|
||||
}
|
||||
ElMessageBox.confirm(`确认${status === "0" ? "启用" : "停用"}该项数据?`, "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
await RoleAPI.batchRole({ ids, status });
|
||||
await refreshData();
|
||||
const userStore = useUserStore();
|
||||
await userStore.getUserInfo();
|
||||
})
|
||||
.catch(() => {});
|
||||
try {
|
||||
await ElMessageBox.confirm(`确认${status === "0" ? "启用" : "停用"}该项数据?`, "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
await RoleAPI.batchRole({ ids, status });
|
||||
await refreshData();
|
||||
const userStore = useUserStore();
|
||||
await userStore.getUserInfo();
|
||||
} catch {
|
||||
// 用户取消
|
||||
}
|
||||
}
|
||||
|
||||
function openExportModal() {
|
||||
@@ -766,15 +767,15 @@ function openExportModal() {
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.crud-dialog-art-form ::v-deep(.el-row > .el-col:last-child) {
|
||||
.crud-dialog-art-form :deep(.el-row > .el-col:last-child) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.crud-dialog-art-form ::v-deep(.el-form-item__content) {
|
||||
.crud-dialog-art-form :deep(.el-form-item__content) {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
::v-deep(.role-table-actions .inline-flex) {
|
||||
:deep(.role-table-actions .inline-flex) {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -364,19 +364,21 @@ function onTableSelectionChange(rows: TenantTable[]) {
|
||||
selectedRows.value = rows;
|
||||
}
|
||||
|
||||
function deleteTenantRow(id: number) {
|
||||
ElMessageBox.confirm("确认删除该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
await TenantAPI.deleteTenant([id]);
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
})
|
||||
.catch(() => {});
|
||||
async function deleteTenantRow(id: number) {
|
||||
try {
|
||||
await ElMessageBox.confirm("确认删除该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
|
||||
await TenantAPI.deleteTenant([id]);
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} catch {
|
||||
// 用户取消
|
||||
}
|
||||
}
|
||||
|
||||
const opCtx = {
|
||||
@@ -648,39 +650,38 @@ async function handleSubmit() {
|
||||
});
|
||||
}
|
||||
|
||||
function handleBatchDelete() {
|
||||
async function handleBatchDelete() {
|
||||
const ids = selectedIds.value;
|
||||
if (ids.length === 0) return;
|
||||
ElMessageBox.confirm(`确定删除选中的 ${ids.length} 条数据吗?`, "批量删除", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
batchDeleting.value = true;
|
||||
await TenantAPI.deleteTenant(ids);
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
try {
|
||||
await ElMessageBox.confirm(`确定删除选中的 ${ids.length} 条数据吗?`, "批量删除", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
batchDeleting.value = true;
|
||||
await TenantAPI.deleteTenant(ids);
|
||||
ElMessage.success("删除成功");
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} catch {
|
||||
// 用户取消
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.crud-dialog-art-form ::v-deep(.el-row > .el-col:last-child) {
|
||||
.crud-dialog-art-form :deep(.el-row > .el-col:last-child) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.crud-dialog-art-form ::v-deep(.el-form-item__content) {
|
||||
.crud-dialog-art-form :deep(.el-form-item__content) {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
::v-deep(.tenant-table-actions .inline-flex) {
|
||||
:deep(.tenant-table-actions .inline-flex) {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -152,15 +152,14 @@ const queryFormData = reactive<DeptPageQuery>({
|
||||
|
||||
const loading = ref(true);
|
||||
|
||||
onBeforeMount(() => {
|
||||
onBeforeMount(async () => {
|
||||
loading.value = true;
|
||||
DeptAPI.listDept(queryFormData)
|
||||
.then((response) => {
|
||||
deptOptions.value = formatTree(response.data.data);
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
try {
|
||||
const response = await DeptAPI.listDept(queryFormData);
|
||||
deptOptions.value = formatTree(response.data.data);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ const selectConfig: ISelectConfig = {
|
||||
],
|
||||
},
|
||||
],
|
||||
indexAction(params: UserPageQuery) {
|
||||
async indexAction(params: UserPageQuery) {
|
||||
// 映射查询参数到后端接口
|
||||
const query: any = { ...params };
|
||||
// 清理空字符串/空值,避免后端 422
|
||||
@@ -70,12 +70,11 @@ const selectConfig: ISelectConfig = {
|
||||
else if (query.status === "false") query.status = false;
|
||||
}
|
||||
// 请求用户分页列表并适配 TableSelect 需要的结构
|
||||
return UserAPI.listUser(query).then((res: any) => {
|
||||
return {
|
||||
total: res.data.data.total,
|
||||
list: res.data.data.items,
|
||||
};
|
||||
});
|
||||
const res = await UserAPI.listUser(query);
|
||||
return {
|
||||
total: res.data.data.total,
|
||||
list: res.data.data.items,
|
||||
};
|
||||
},
|
||||
tableColumns: [
|
||||
{ type: "selection", width: 50, align: "center" },
|
||||
|
||||
@@ -545,41 +545,43 @@ function onTableSelectionChange(rows: UserInfo[]) {
|
||||
selectedRows.value = rows;
|
||||
}
|
||||
|
||||
function handleResetPassword(row: UserInfo) {
|
||||
ElMessageBox.prompt(`请输入用户【${row.username ?? ""}】的新密码`, "重置密码", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
}).then(
|
||||
async ({ value }) => {
|
||||
if (!value || value.length < 6) {
|
||||
ElMessage.warning("密码至少需要6位字符,请重新输入");
|
||||
return;
|
||||
}
|
||||
await UserAPI.resetUserPassword({ id: row.id!, password: value });
|
||||
ElMessage.success("密码已重置");
|
||||
},
|
||||
() => {}
|
||||
);
|
||||
async function handleResetPassword(row: UserInfo) {
|
||||
try {
|
||||
const { value } = await ElMessageBox.prompt(
|
||||
`请输入用户【${row.username ?? ""}】的新密码`,
|
||||
"重置密码",
|
||||
{ confirmButtonText: "确定", cancelButtonText: "取消" }
|
||||
);
|
||||
if (!value || value.length < 6) {
|
||||
ElMessage.warning("密码至少需要6位字符,请重新输入");
|
||||
return;
|
||||
}
|
||||
await UserAPI.resetUserPassword({ id: row.id!, password: value });
|
||||
ElMessage.success("密码已重置");
|
||||
} catch {
|
||||
// 用户取消
|
||||
}
|
||||
}
|
||||
|
||||
function deleteUserRow(id: number) {
|
||||
ElMessageBox.confirm("确认删除该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
await UserAPI.deleteUser([id]);
|
||||
const idSet = [id];
|
||||
if (userStore.basicInfo.id && idSet.includes(userStore.basicInfo.id)) {
|
||||
userStore.clearUserInfo();
|
||||
} else {
|
||||
ElMessage.success("删除成功");
|
||||
}
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
})
|
||||
.catch(() => {});
|
||||
async function deleteUserRow(id: number) {
|
||||
try {
|
||||
await ElMessageBox.confirm("确认删除该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
await UserAPI.deleteUser([id]);
|
||||
const idSet = [id];
|
||||
if (userStore.basicInfo.id && idSet.includes(userStore.basicInfo.id)) {
|
||||
userStore.clearUserInfo();
|
||||
} else {
|
||||
ElMessage.success("删除成功");
|
||||
}
|
||||
faTableRef.value?.elTableRef?.clearSelection();
|
||||
await refreshRemove();
|
||||
} catch {
|
||||
// 用户取消
|
||||
}
|
||||
}
|
||||
|
||||
const opCtx = {
|
||||
@@ -708,7 +710,7 @@ const exportQueryParams = computed(() => {
|
||||
const userImportContentConfig = computed<IContentConfig>(() => ({
|
||||
permPrefix: "module_system:user",
|
||||
cols: userCrudCols.value,
|
||||
indexAction: async () => ({}) as any,
|
||||
indexAction: async () => ({}),
|
||||
importTemplate: () => UserAPI.downloadTemplateUser(),
|
||||
}));
|
||||
|
||||
@@ -839,25 +841,23 @@ function openExportModal() {
|
||||
exportModalVisible.value = true;
|
||||
}
|
||||
|
||||
function handleImportUpload(formDataUpload: FormData) {
|
||||
async function handleImportUpload(formDataUpload: FormData) {
|
||||
uploadLoading.value = true;
|
||||
UserAPI.importUser(formDataUpload)
|
||||
.then(async (response) => {
|
||||
if (response.data.code === ResultEnum.SUCCESS) {
|
||||
ElMessage.success(`${response.data.msg},${response.data.data}`);
|
||||
importModalVisible.value = false;
|
||||
await refreshData();
|
||||
} else {
|
||||
ElMessage.error(response.data.msg || "导入失败");
|
||||
}
|
||||
})
|
||||
.catch((error: unknown) => {
|
||||
console.error(error);
|
||||
ElMessage.error("上传失败");
|
||||
})
|
||||
.finally(() => {
|
||||
uploadLoading.value = false;
|
||||
});
|
||||
try {
|
||||
const response = await UserAPI.importUser(formDataUpload);
|
||||
if (response.data.code === ResultEnum.SUCCESS) {
|
||||
ElMessage.success(`${response.data.msg},${response.data.data}`);
|
||||
importModalVisible.value = false;
|
||||
await refreshData();
|
||||
} else {
|
||||
ElMessage.error(response.data.msg || "导入失败");
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
console.error(error);
|
||||
ElMessage.error("上传失败");
|
||||
} finally {
|
||||
uploadLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function resetForm() {
|
||||
@@ -950,61 +950,57 @@ async function handleSubmit() {
|
||||
});
|
||||
}
|
||||
|
||||
function handleBatchDelete() {
|
||||
async function handleBatchDelete() {
|
||||
const ids = selectedIds.value;
|
||||
if (ids.length === 0) return;
|
||||
ElMessageBox.confirm(`确定删除选中的 ${ids.length} 条数据吗?`, "批量删除", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
batchDeleting.value = true;
|
||||
await UserAPI.deleteUser(ids);
|
||||
if (userStore.basicInfo.id && ids.includes(userStore.basicInfo.id)) {
|
||||
userStore.clearUserInfo();
|
||||
} else {
|
||||
ElMessage.success("删除成功");
|
||||
}
|
||||
selectedRows.value = [];
|
||||
await refreshRemove();
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
try {
|
||||
await ElMessageBox.confirm(`确定删除选中的 ${ids.length} 条数据吗?`, "批量删除", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
batchDeleting.value = true;
|
||||
await UserAPI.deleteUser(ids);
|
||||
if (userStore.basicInfo.id && ids.includes(userStore.basicInfo.id)) {
|
||||
userStore.clearUserInfo();
|
||||
} else {
|
||||
ElMessage.success("删除成功");
|
||||
}
|
||||
selectedRows.value = [];
|
||||
await refreshRemove();
|
||||
} catch {
|
||||
// 用户取消
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function handleMoreClick(status: string) {
|
||||
async function handleMoreClick(status: string) {
|
||||
const ids = selectedIds.value;
|
||||
if (!ids.length) {
|
||||
ElMessage.warning("请先选择要操作的数据");
|
||||
return;
|
||||
}
|
||||
ElMessageBox.confirm("确认启用或停用该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
batchDeleting.value = true;
|
||||
await UserAPI.batchUser({ ids, status });
|
||||
await refreshData();
|
||||
} catch (error: unknown) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
try {
|
||||
await ElMessageBox.confirm("确认启用或停用该项数据?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
});
|
||||
batchDeleting.value = true;
|
||||
await UserAPI.batchUser({ ids, status });
|
||||
await refreshData();
|
||||
} catch {
|
||||
// 用户取消
|
||||
} finally {
|
||||
batchDeleting.value = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 左侧部门树内容区:card body 纵向 flex + 滚动条占满剩余高度(布局在 index,内边距在 DeptTree) */
|
||||
.tree-card ::v-deep(.el-card__body) {
|
||||
.tree-card :deep(.el-card__body) {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
|
||||
Reference in New Issue
Block a user