refactor: 将组件前缀从Art统一替换为Fa

- 更新所有FA前缀的组件文件
- 新增Fa前缀的对应组件
- 更新所有引用路径和组件名
- 修改相关样式和变量名
- 调整部分组件目录结构
This commit is contained in:
zhangtao
2026-05-11 09:23:31 +08:00
parent 68b50359c5
commit 03a8151513
185 changed files with 2912 additions and 1283 deletions
@@ -1,7 +1,7 @@
<!-- 部门配置:Art + 树形表格(对齐 system/menu 模版) -->
<template>
<div class="art-full-height">
<ArtSearchBar
<FaSearchBar
v-show="showSearchBar"
ref="searchBarRef"
v-model="searchForm"
@@ -18,7 +18,7 @@
/>
<ElCard class="art-table-card" :style="{ 'margin-top': showSearchBar ? '12px' : '0' }">
<ArtTableHeader
<FaTableHeader
v-model:columns="columnChecks"
v-model:showSearchBar="showSearchBar"
:loading="loading"
@@ -26,7 +26,7 @@
>
<template #left>
<div class="inline-flex flex-wrap items-center gap-2">
<ArtTableHeaderLeft
<FaTableHeaderLeft
:remove-ids="selectedIds"
:perm-create="['module_system:dept:create']"
:perm-delete="['module_system:dept:delete']"
@@ -39,9 +39,9 @@
<ElButton @click="toggleExpand">{{ isExpanded ? "收起" : "展开" }}</ElButton>
</div>
</template>
</ArtTableHeader>
</FaTableHeader>
<ArtTable
<FaTable
ref="tableRef"
row-key="id"
:loading="loading"
@@ -53,7 +53,7 @@
/>
</ElCard>
<ArtDialog
<FaDialog
v-model="dialogVisible.visible"
:title="dialogVisible.title"
width="640px"
@@ -95,7 +95,7 @@
</template>
<template v-else>
<ElScrollbar max-height="75vh" :view-style="{ overflowX: 'hidden' }">
<ArtForm
<FaForm
:key="deptFormRenderKey"
ref="dataFormRef"
v-model="formData"
@@ -116,7 +116,7 @@
<ElRadio value="1">停用</ElRadio>
</ElRadioGroup>
</template>
</ArtForm>
</FaForm>
</ElScrollbar>
</template>
@@ -129,7 +129,7 @@
<ElButton v-else type="primary" @click="handleCloseDialog">确定</ElButton>
</div>
</template>
</ArtDialog>
</FaDialog>
</div>
</template>
@@ -141,14 +141,14 @@ import DeptAPI, {
type DeptPageQuery,
type DeptTable,
} from "@/api/module_system/dept";
import ArtTable from "@/components/Core/tables/art-table/index.vue";
import ArtTableHeader from "@/components/Core/tables/art-table-header/index.vue";
import ArtTableHeaderLeft from "@/components/Core/tables/art-table-header-left/index.vue";
import ArtSearchBar from "@/components/Core/forms/art-search-bar/index.vue";
import type { SearchFormItem } from "@/components/Core/forms/art-search-bar/index.vue";
import ArtDialog from "@/components/Core/modal/art-dialog/index.vue";
import ArtForm from "@/components/Core/forms/art-form/index.vue";
import type { FormItem } from "@/components/Core/forms/art-form/index.vue";
import FaTable from "@/components/tables/fa-table/index.vue";
import FaTableHeader from "@/components/tables/fa-table-header/index.vue";
import FaTableHeaderLeft from "@/components/tables/fa-table-header-left/index.vue";
import FaSearchBar from "@/components/forms/fa-search-bar/index.vue";
import type { SearchFormItem } from "@/components/forms/fa-search-bar/index.vue";
import FaDialog from "@/components/modal/fa-dialog/index.vue";
import FaForm from "@/components/forms/fa-form/index.vue";
import type { FormItem } from "@/components/forms/fa-form/index.vue";
import { ElMessage, ElMessageBox, ElTag } from "element-plus";
import { useAuth } from "@/hooks/core/useAuth";
import { useUserStore } from "@stores";
@@ -234,7 +234,7 @@ const searchForm = ref<DeptSearchForm>({
});
const showSearchBar = ref(true);
const searchBarRef = ref<InstanceType<typeof ArtSearchBar> | null>(null);
const searchBarRef = ref<InstanceType<typeof FaSearchBar> | null>(null);
const searchBarRules: Record<string, unknown> = {};
const statusOptions = ref([
@@ -362,7 +362,7 @@ const { columnChecks, columns } = useTableColumns<DeptTable>(() => [
const detailFormData = ref<DeptTable>({ code: "" });
const formData = reactive<DeptForm>({
const formData = ref<DeptForm>({
id: undefined,
name: undefined,
code: "",
@@ -404,7 +404,7 @@ const initialFormData: DeptForm = {
description: undefined,
};
const dataFormRef = ref<InstanceType<typeof ArtForm> | null>(null);
const dataFormRef = ref<InstanceType<typeof FaForm> | null>(null);
const deptFormRenderKey = ref(0);
const deptDialogFormItems = computed<FormItem[]>(() => [
@@ -515,10 +515,10 @@ async function handleOpenDialog(
}
} else {
dialogVisible.title = "新增部门";
Object.assign(formData, initialFormData);
formData.id = undefined;
Object.assign(formData.value, initialFormData);
formData.value.id = undefined;
if (parentId) {
formData.parent_id = parentId;
formData.value.parent_id = parentId;
}
}
deptFormRenderKey.value += 1;
@@ -528,12 +528,12 @@ async function handleOpenDialog(
async function handleSubmit() {
dataFormRef.value?.validate(async (valid: boolean) => {
if (!valid) return;
const id = formData.id;
const id = formData.value.id;
try {
if (id) {
await DeptAPI.updateDept(id, { id, ...formData });
await DeptAPI.updateDept(id, { id, ...formData.value });
} else {
await DeptAPI.createDept(formData);
await DeptAPI.createDept(formData.value);
}
dialogVisible.visible = false;
await resetForm();
@@ -1,13 +1,13 @@
<!-- 字典数据抽屉:Art 搜索 + useTable;固定 dict_type / dict_type_id 由父级传入 -->
<template>
<ArtDrawer
<FaDrawer
v-model="drawerVisible"
:title="'【' + dictLabel + '】字典数据'"
direction="rtl"
:size="drawerSize"
>
<div class="drawer-content">
<ArtSearchBar
<FaSearchBar
v-show="showSearchBar"
ref="searchBarRef"
v-model="searchForm"
@@ -27,14 +27,14 @@
class="art-table-card drawer-table-card"
:style="{ 'margin-top': showSearchBar ? '12px' : '0' }"
>
<ArtTableHeader
<FaTableHeader
v-model:columns="columnChecks"
v-model:showSearchBar="showSearchBar"
:loading="loading"
@refresh="refreshData"
>
<template #left>
<ArtTableHeaderLeft
<FaTableHeaderLeft
:remove-ids="selectedIds"
:perm-create="['module_system:dict_data:create']"
:perm-export="['module_system:dict_data:export']"
@@ -47,10 +47,10 @@
@more="handleMoreClick"
/>
</template>
</ArtTableHeader>
</FaTableHeader>
<ArtTable
ref="artTableRef"
<FaTable
ref="FaTableRef"
:loading="loading"
:data="data"
:columns="columns"
@@ -61,7 +61,7 @@
/>
</ElCard>
<ArtDialog
<FaDialog
v-model="dialogVisible.visible"
:title="dialogVisible.title"
width="720px"
@@ -112,7 +112,7 @@
</template>
<template v-else>
<ElScrollbar max-height="70vh" :view-style="{ overflowX: 'hidden' }">
<ArtForm
<FaForm
:key="dictDataFormRenderKey"
ref="dataFormRef"
v-model="formData"
@@ -211,7 +211,7 @@
:inactive-value="'1'"
/>
</template>
</ArtForm>
</FaForm>
</ElScrollbar>
</template>
@@ -224,9 +224,9 @@
<ElButton v-else type="primary" @click="handleCloseDialog">确定</ElButton>
</div>
</template>
</ArtDialog>
</FaDialog>
<ArtExportDialog
<FaExportDialog
v-model="exportModalVisible"
:content-config="dictDataExportContentConfig"
:query-params="exportQueryParams"
@@ -234,21 +234,21 @@
:selection-data="selectedRows"
/>
</div>
</ArtDrawer>
</FaDrawer>
</template>
<script setup lang="ts">
import { h, computed, ref, reactive } from "vue";
import { useTable } from "@/hooks/core/useTable";
import ArtTableHeaderLeft from "@/components/Core/tables/art-table-header-left/index.vue";
import ArtExportDialog from "@/components/Core/modal/art-export-dialog/index.vue";
import type { IObject } from "@/components/Core/modal/types";
import ArtSearchBar from "@/components/Core/forms/art-search-bar/index.vue";
import type { SearchFormItem } from "@/components/Core/forms/art-search-bar/index.vue";
import ArtDialog from "@/components/Core/modal/art-dialog/index.vue";
import ArtDrawer from "@/components/Core/modal/art-drawer/index.vue";
import ArtForm from "@/components/Core/forms/art-form/index.vue";
import type { FormItem } from "@/components/Core/forms/art-form/index.vue";
import FaTableHeaderLeft from "@/components/tables/fa-table-header-left/index.vue";
import FaExportDialog from "@/components/modal/fa-export-dialog/index.vue";
import type { IObject } from "@/components/modal/types";
import FaSearchBar from "@/components/forms/fa-search-bar/index.vue";
import type { SearchFormItem } from "@/components/forms/fa-search-bar/index.vue";
import FaDialog from "@/components/modal/fa-dialog/index.vue";
import FaDrawer from "@/components/modal/fa-drawer/index.vue";
import FaForm from "@/components/forms/fa-form/index.vue";
import type { FormItem } from "@/components/forms/fa-form/index.vue";
import type { ColumnOption } from "@/types/component";
import DictAPI, {
type DictDataForm,
@@ -363,7 +363,7 @@ const searchForm = ref<DictDataSearchForm>({
});
const showSearchBar = ref(true);
const searchBarRef = ref<InstanceType<typeof ArtSearchBar> | null>(null);
const searchBarRef = ref<InstanceType<typeof FaSearchBar> | null>(null);
const searchBarRules: Record<string, unknown> = {};
const statusOptions = ref([
@@ -408,7 +408,7 @@ const dictDataSearchItems = computed<SearchFormItem[]>(() => [
},
]);
const artTableRef = ref<{ elTableRef?: { clearSelection: () => void } } | null>(null);
const FaTableRef = ref<{ elTableRef?: { clearSelection: () => void } } | null>(null);
const selectedRows = ref<DictDataTable[]>([]);
const selectedIds = computed(() =>
selectedRows.value.map((r) => r.id).filter((id): id is number => id != null && !Number.isNaN(id))
@@ -554,7 +554,7 @@ const dialogVisible = reactive({
const detailFormData = ref<DictDataTable>({});
const formData = reactive<DictDataForm>({
const formData = ref<DictDataForm>({
id: undefined,
dict_sort: 1,
dict_label: "",
@@ -577,7 +577,7 @@ const rules = reactive({
is_default: [{ required: true, message: "请选择是否默认", trigger: "blur" }],
});
const dataFormRef = ref<InstanceType<typeof ArtForm> | null>(null);
const dataFormRef = ref<InstanceType<typeof FaForm> | null>(null);
const dictDataFormRenderKey = ref(0);
const dictDataDialogFormItems = computed<FormItem[]>(() => [
@@ -728,11 +728,11 @@ async function handleOpenDialog(type: "create" | "update" | "detail", id?: numbe
}
} else {
dialogVisible.title = "新增字典数据";
Object.assign(formData, initialFormData);
formData.dict_type = props.dictType;
formData.dict_type_id = props.dictTypeId;
formData.status = "0";
formData.id = undefined;
Object.assign(formData.value, initialFormData);
formData.value.dict_type = props.dictType;
formData.value.dict_type_id = props.dictTypeId;
formData.value.status = "0";
formData.value.id = undefined;
}
dictDataFormRenderKey.value += 1;
dialogVisible.visible = true;
@@ -741,20 +741,20 @@ async function handleOpenDialog(type: "create" | "update" | "detail", id?: numbe
async function handleSubmit() {
dataFormRef.value?.validate(async (valid: boolean) => {
if (!valid) return;
const id = formData.id;
const id = formData.value.id;
try {
if (id) {
await DictAPI.updateDictData(id, { id, ...formData });
await refreshUpdate();
} else {
await DictAPI.createDictData(formData);
await DictAPI.createDictData(formData.value);
await refreshCreate();
}
dialogVisible.visible = false;
await resetForm();
dictStore.clearDictData();
if (formData.dict_type) {
await dictStore.getDict([formData.dict_type]);
if (formData.value.dict_type) {
await dictStore.getDict([formData.value.dict_type]);
}
} catch (error: unknown) {
console.error(error);
@@ -812,7 +812,7 @@ function deleteDictDataRow(id: number) {
await dictStore.getDict([props.dictType]);
}
ElMessage.success("删除成功");
artTableRef.value?.elTableRef?.clearSelection();
FaTableRef.value?.elTableRef?.clearSelection();
await refreshRemove();
})
.catch(() => {});
@@ -835,7 +835,7 @@ function handleBatchDelete() {
await dictStore.getDict([props.dictType]);
}
ElMessage.success("删除成功");
artTableRef.value?.elTableRef?.clearSelection();
FaTableRef.value?.elTableRef?.clearSelection();
await refreshRemove();
} finally {
batchDeleting.value = false;
@@ -1,7 +1,7 @@
<!-- 字典类型:Art 布局;操作列最多 3 个外露 +「更多」 -->
<template>
<div class="art-full-height">
<ArtSearchBar
<FaSearchBar
v-show="showSearchBar"
ref="searchBarRef"
v-model="searchForm"
@@ -18,14 +18,14 @@
/>
<ElCard class="art-table-card" :style="{ 'margin-top': showSearchBar ? '12px' : '0' }">
<ArtTableHeader
<FaTableHeader
v-model:columns="columnChecks"
v-model:showSearchBar="showSearchBar"
:loading="loading"
@refresh="refreshData"
>
<template #left>
<ArtTableHeaderLeft
<FaTableHeaderLeft
:remove-ids="selectedIds"
:perm-create="['module_system:dict_type:create']"
:perm-export="['module_system:dict_type:export']"
@@ -38,10 +38,10 @@
@more="handleMoreClick"
/>
</template>
</ArtTableHeader>
</FaTableHeader>
<ArtTable
ref="artTableRef"
<FaTable
ref="FaTableRef"
:loading="loading"
:data="data"
:columns="columns"
@@ -52,7 +52,7 @@
/>
</ElCard>
<ArtDialog
<FaDialog
v-model="dialogVisible.visible"
:title="dialogVisible.title"
width="640px"
@@ -87,7 +87,7 @@
</template>
<template v-else>
<ElScrollbar max-height="70vh" :view-style="{ overflowX: 'hidden' }">
<ArtForm
<FaForm
:key="dictFormRenderKey"
ref="dataFormRef"
v-model="formData"
@@ -108,7 +108,7 @@
<ElRadio value="1">停用</ElRadio>
</ElRadioGroup>
</template>
</ArtForm>
</FaForm>
</ElScrollbar>
</template>
@@ -121,9 +121,9 @@
<ElButton v-else type="primary" @click="handleCloseDialog">确定</ElButton>
</div>
</template>
</ArtDialog>
</FaDialog>
<ArtExportDialog
<FaExportDialog
v-model="exportModalVisible"
:content-config="dictTypeExportContentConfig"
:query-params="exportQueryParams"
@@ -144,14 +144,14 @@
<script setup lang="ts">
import { h, computed, ref, reactive } from "vue";
import { useTable } from "@/hooks/core/useTable";
import ArtTableHeaderLeft from "@/components/Core/tables/art-table-header-left/index.vue";
import ArtExportDialog from "@/components/Core/modal/art-export-dialog/index.vue";
import type { IObject } from "@/components/Core/modal/types";
import ArtSearchBar from "@/components/Core/forms/art-search-bar/index.vue";
import type { SearchFormItem } from "@/components/Core/forms/art-search-bar/index.vue";
import ArtDialog from "@/components/Core/modal/art-dialog/index.vue";
import ArtForm from "@/components/Core/forms/art-form/index.vue";
import type { FormItem } from "@/components/Core/forms/art-form/index.vue";
import FaTableHeaderLeft from "@/components/tables/fa-table-header-left/index.vue";
import FaExportDialog from "@/components/modal/fa-export-dialog/index.vue";
import type { IObject } from "@/components/modal/types";
import FaSearchBar from "@/components/forms/fa-search-bar/index.vue";
import type { SearchFormItem } from "@/components/forms/fa-search-bar/index.vue";
import FaDialog from "@/components/modal/fa-dialog/index.vue";
import FaForm from "@/components/forms/fa-form/index.vue";
import type { FormItem } from "@/components/forms/fa-form/index.vue";
import type { ColumnOption } from "@/types/component";
import DictAPI, {
type DictForm,
@@ -194,7 +194,7 @@ const searchForm = ref<DictTypeSearchForm>({
});
const showSearchBar = ref(true);
const searchBarRef = ref<InstanceType<typeof ArtSearchBar> | null>(null);
const searchBarRef = ref<InstanceType<typeof FaSearchBar> | null>(null);
const searchBarRules: Record<string, unknown> = {};
const statusOptions = ref([
@@ -247,7 +247,7 @@ const dictTypeSearchItems = computed<SearchFormItem[]>(() => [
},
]);
const artTableRef = ref<{ elTableRef?: { clearSelection: () => void } } | null>(null);
const FaTableRef = ref<{ elTableRef?: { clearSelection: () => void } } | null>(null);
const selectedRows = ref<DictTable[]>([]);
const selectedIds = computed(() =>
selectedRows.value.map((r) => r.id).filter((id): id is number => id != null && !Number.isNaN(id))
@@ -372,7 +372,7 @@ const dialogVisible = reactive({
const detailFormData = ref<DictTable>({});
const formData = reactive<DictForm>({
const formData = ref<DictForm>({
id: undefined,
dict_name: "",
dict_type: "",
@@ -386,7 +386,7 @@ const rules = reactive({
status: [{ required: true, message: "请选择字典状态", trigger: "blur" }],
});
const dataFormRef = ref<InstanceType<typeof ArtForm> | null>(null);
const dataFormRef = ref<InstanceType<typeof FaForm> | null>(null);
const dictFormRenderKey = ref(0);
const dictDialogFormItems = computed<FormItem[]>(() => [
@@ -542,8 +542,8 @@ async function handleOpenDialog(type: "create" | "update" | "detail", id?: numbe
}
} else {
dialogVisible.title = "新增字典";
Object.assign(formData, initialFormData);
formData.id = undefined;
Object.assign(formData.value, initialFormData);
formData.value.id = undefined;
}
dictFormRenderKey.value += 1;
dialogVisible.visible = true;
@@ -552,20 +552,20 @@ async function handleOpenDialog(type: "create" | "update" | "detail", id?: numbe
async function handleSubmit() {
dataFormRef.value?.validate(async (valid: boolean) => {
if (!valid) return;
const id = formData.id;
const id = formData.value.id;
try {
if (id) {
await DictAPI.updateDictType(id, { id, ...formData });
await DictAPI.updateDictType(id, { id, ...formData.value });
await refreshUpdate();
} else {
await DictAPI.createDictType(formData);
await DictAPI.createDictType(formData.value);
await refreshCreate();
}
dialogVisible.visible = false;
await resetForm();
dictStore.clearDictData();
if (formData.dict_type) {
await dictStore.getDict([formData.dict_type]);
if (formData.value.dict_type) {
await dictStore.getDict([formData.value.dict_type]);
}
} catch (error: unknown) {
console.error(error);
@@ -587,7 +587,7 @@ function deleteDictTypeRow(id: number) {
await dictStore.getDict(dictTypes);
}
ElMessage.success("删除成功");
artTableRef.value?.elTableRef?.clearSelection();
FaTableRef.value?.elTableRef?.clearSelection();
await refreshRemove();
})
.catch(() => {});
@@ -611,7 +611,7 @@ function handleBatchDelete() {
await dictStore.getDict(dictTypes);
}
ElMessage.success("删除成功");
artTableRef.value?.elTableRef?.clearSelection();
FaTableRef.value?.elTableRef?.clearSelection();
await refreshRemove();
} finally {
batchDeleting.value = false;
@@ -1,7 +1,7 @@
<!-- 日志管理:Art 布局 + useTable,与 dict 页一致 -->
<template>
<div class="art-full-height">
<ArtSearchBar
<FaSearchBar
v-show="showSearchBar"
ref="searchBarRef"
v-model="searchForm"
@@ -24,17 +24,17 @@
@clear-click="afterUserSelectSearch"
/>
</template>
</ArtSearchBar>
</FaSearchBar>
<ElCard class="art-table-card" :style="{ 'margin-top': showSearchBar ? '12px' : '0' }">
<ArtTableHeader
<FaTableHeader
v-model:columns="columnChecks"
v-model:showSearchBar="showSearchBar"
:loading="loading"
@refresh="refreshData"
>
<template #left>
<ArtTableHeaderLeft
<FaTableHeaderLeft
:remove-ids="selectedIds"
:perm-export="['module_system:log:export']"
:perm-delete="['module_system:log:delete']"
@@ -43,10 +43,10 @@
@delete="handleBatchDelete"
/>
</template>
</ArtTableHeader>
</FaTableHeader>
<ArtTable
ref="artTableRef"
<FaTable
ref="FaTableRef"
:loading="loading"
:data="data"
:columns="columns"
@@ -57,7 +57,7 @@
/>
</ElCard>
<ArtDialog
<FaDialog
v-model="dialogVisible.visible"
:title="dialogVisible.title"
width="960px"
@@ -130,9 +130,9 @@
<ElButton type="primary" @click="handleCloseDialog">确定</ElButton>
</div>
</template>
</ArtDialog>
</FaDialog>
<ArtExportDialog
<FaExportDialog
v-model="exportModalVisible"
:content-config="logExportContentConfig"
:query-params="exportQueryParams"
@@ -145,14 +145,14 @@
<script setup lang="ts">
import { h, computed, ref, nextTick } from "vue";
import { useTable } from "@/hooks/core/useTable";
import ArtTable from "@/components/Core/tables/art-table/index.vue";
import ArtTableHeader from "@/components/Core/tables/art-table-header/index.vue";
import ArtTableHeaderLeft from "@/components/Core/tables/art-table-header-left/index.vue";
import ArtExportDialog from "@/components/Core/modal/art-export-dialog/index.vue";
import type { IObject } from "@/components/Core/modal/types";
import ArtSearchBar from "@/components/Core/forms/art-search-bar/index.vue";
import type { SearchFormItem } from "@/components/Core/forms/art-search-bar/index.vue";
import ArtDialog from "@/components/Core/modal/art-dialog/index.vue";
import FaTable from "@/components/tables/fa-table/index.vue";
import FaTableHeader from "@/components/tables/fa-table-header/index.vue";
import FaTableHeaderLeft from "@/components/tables/fa-table-header-left/index.vue";
import FaExportDialog from "@/components/modal/fa-export-dialog/index.vue";
import type { IObject } from "@/components/modal/types";
import FaSearchBar from "@/components/forms/fa-search-bar/index.vue";
import type { SearchFormItem } from "@/components/forms/fa-search-bar/index.vue";
import FaDialog from "@/components/modal/fa-dialog/index.vue";
import JsonPretty from "@/components/JsonPretty/index.vue";
import CopyButton from "@/components/CopyButton/index.vue";
import type { ColumnOption } from "@/types/component";
@@ -204,7 +204,7 @@ const searchForm = ref<LogSearchForm>({
});
const showSearchBar = ref(true);
const searchBarRef = ref<InstanceType<typeof ArtSearchBar> | null>(null);
const searchBarRef = ref<InstanceType<typeof FaSearchBar> | null>(null);
const searchBarRules: Record<string, unknown> = {};
const logTypeOptions = ref([
@@ -255,7 +255,7 @@ const logSearchItems = computed<SearchFormItem[]>(() => [
},
]);
const artTableRef = ref<{ elTableRef?: { clearSelection: () => void } } | null>(null);
const FaTableRef = ref<{ elTableRef?: { clearSelection: () => void } } | null>(null);
const selectedRows = ref<LogTable[]>([]);
const selectedIds = computed(() =>
selectedRows.value.map((r) => r.id).filter((id): id is number => id != null && !Number.isNaN(id))
@@ -483,7 +483,7 @@ function deleteLogRow(id: number) {
.then(async () => {
await LogAPI.deleteLog([id]);
ElMessage.success("删除成功");
artTableRef.value?.elTableRef?.clearSelection();
FaTableRef.value?.elTableRef?.clearSelection();
await refreshRemove();
})
.catch(() => {});
@@ -533,7 +533,7 @@ function handleBatchDelete() {
batchDeleting.value = true;
await LogAPI.deleteLog(ids);
ElMessage.success("删除成功");
artTableRef.value?.elTableRef?.clearSelection();
FaTableRef.value?.elTableRef?.clearSelection();
await refreshRemove();
} finally {
batchDeleting.value = false;
@@ -1,7 +1,7 @@
<!-- 菜单管理:Art + 树形表格;操作列最多 3 个外露,其余「更多」 -->
<template>
<div class="art-full-height">
<ArtSearchBar
<FaSearchBar
v-show="showSearchBar"
ref="searchBarRef"
v-model="searchForm"
@@ -27,7 +27,7 @@
</ElTabs>
<ElCard class="art-table-card" :style="{ 'margin-top': showSearchBar ? '12px' : '0' }">
<ArtTableHeader
<FaTableHeader
v-model:columns="columnChecks"
v-model:showSearchBar="showSearchBar"
:loading="loading"
@@ -35,7 +35,7 @@
>
<template #left>
<div class="inline-flex flex-wrap items-center gap-2">
<ArtTableHeaderLeft
<FaTableHeaderLeft
:remove-ids="selectedIds"
:perm-create="['module_system:menu:create']"
:perm-delete="['module_system:menu:delete']"
@@ -48,9 +48,9 @@
<ElButton @click="toggleExpand">{{ isExpanded ? "收起" : "展开" }}</ElButton>
</div>
</template>
</ArtTableHeader>
</FaTableHeader>
<ArtTable
<FaTable
ref="tableRef"
row-key="id"
:loading="loading"
@@ -63,7 +63,7 @@
/>
</ElCard>
<ArtDrawer
<FaDrawer
v-model="dialogVisible.visible"
:title="dialogVisible.title"
:size="drawerSize"
@@ -497,7 +497,7 @@
<ElButton @click="handleCloseDialog">取消</ElButton>
</div>
</template>
</ArtDrawer>
</FaDrawer>
</div>
</template>
@@ -521,12 +521,12 @@ import MenuAPI, {
import { MenuClientEnum, MenuTypeEnum } from "@/enums/system/menu.enum";
import { formatTree } from "@utils/common";
import MenuRouteIcon from "@/components/MenuRouteIcon/index.vue";
import ArtTable from "@/components/Core/tables/art-table/index.vue";
import ArtTableHeader from "@/components/Core/tables/art-table-header/index.vue";
import ArtTableHeaderLeft from "@/components/Core/tables/art-table-header-left/index.vue";
import ArtSearchBar from "@/components/Core/forms/art-search-bar/index.vue";
import type { SearchFormItem } from "@/components/Core/forms/art-search-bar/index.vue";
import ArtDrawer from "@/components/Core/modal/art-drawer/index.vue";
import FaTable from "@/components/tables/fa-table/index.vue";
import FaTableHeader from "@/components/tables/fa-table-header/index.vue";
import FaTableHeaderLeft from "@/components/tables/fa-table-header-left/index.vue";
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 { ElMessage, ElMessageBox, ElTag, ElTooltip } from "element-plus";
import { useAuth } from "@/hooks/core/useAuth";
import { renderTableOperationCell, type TableOperationAction } from "@utils/table";
@@ -628,7 +628,7 @@ const searchForm = ref<MenuSearchForm>({
created_time: undefined,
});
const showSearchBar = ref(true);
const searchBarRef = ref<InstanceType<typeof ArtSearchBar> | null>(null);
const searchBarRef = ref<InstanceType<typeof FaSearchBar> | null>(null);
const searchBarRules: Record<string, unknown> = {};
const statusOptions = ref([
@@ -692,7 +692,7 @@ const createParentLocked = ref(false);
const detailFormData = ref<MenuTable>({});
const formData = reactive<MenuForm>({
const formData = ref<MenuForm>({
id: undefined,
name: undefined,
type: MenuTypeEnum.CATALOG,
@@ -1,7 +1,7 @@
<!-- 公告通知:Art 布局 + useTable,与 dict 页一致 -->
<template>
<div class="art-full-height">
<ArtSearchBar
<FaSearchBar
v-show="showSearchBar"
ref="searchBarRef"
v-model="searchForm"
@@ -24,17 +24,17 @@
@clear-click="afterUserSelectSearch"
/>
</template>
</ArtSearchBar>
</FaSearchBar>
<ElCard class="art-table-card" :style="{ 'margin-top': showSearchBar ? '12px' : '0' }">
<ArtTableHeader
<FaTableHeader
v-model:columns="columnChecks"
v-model:showSearchBar="showSearchBar"
:loading="loading"
@refresh="refreshData"
>
<template #left>
<ArtTableHeaderLeft
<FaTableHeaderLeft
:remove-ids="selectedIds"
:perm-create="['module_system:notice:create']"
:perm-export="['module_system:notice:export']"
@@ -47,10 +47,10 @@
@more="handleMoreClick"
/>
</template>
</ArtTableHeader>
</FaTableHeader>
<ArtTable
ref="artTableRef"
<FaTable
ref="FaTableRef"
:loading="loading"
:data="data"
:columns="columns"
@@ -61,7 +61,7 @@
/>
</ElCard>
<ArtDialog
<FaDialog
v-model="dialogVisible.visible"
:title="dialogVisible.title"
width="920px"
@@ -113,8 +113,8 @@
</template>
<template v-else>
<ElScrollbar max-height="75vh" :view-style="{ overflowX: 'hidden' }">
<!-- ArtForm + items + 栅格;弹窗内关闭内置提交/重置,仍用底部按钮 -->
<ArtForm
<!-- FaForm + items + 栅格;弹窗内关闭内置提交/重置,仍用底部按钮 -->
<FaForm
:key="noticeFormRenderKey"
ref="dataFormRef"
v-model="formData"
@@ -144,7 +144,7 @@
@update:model-value="(v: string) => (formData.notice_content = v)"
/>
</template>
</ArtForm>
</FaForm>
</ElScrollbar>
</template>
@@ -162,9 +162,9 @@
<ElButton v-else type="primary" @click="handleCloseDialog">确定</ElButton>
</div>
</template>
</ArtDialog>
</FaDialog>
<ArtExportDialog
<FaExportDialog
v-model="exportModalVisible"
:content-config="noticeExportContentConfig"
:query-params="exportQueryParams"
@@ -177,14 +177,14 @@
<script setup lang="ts">
import { h, computed, ref, reactive, nextTick, onMounted } from "vue";
import { useTable } from "@/hooks/core/useTable";
import ArtTable from "@/components/Core/tables/art-table/index.vue";
import ArtTableHeader from "@/components/Core/tables/art-table-header/index.vue";
import ArtTableHeaderLeft from "@/components/Core/tables/art-table-header-left/index.vue";
import ArtExportDialog from "@/components/Core/modal/art-export-dialog/index.vue";
import type { IObject } from "@/components/Core/modal/types";
import ArtSearchBar from "@/components/Core/forms/art-search-bar/index.vue";
import type { SearchFormItem } from "@/components/Core/forms/art-search-bar/index.vue";
import ArtDialog from "@/components/Core/modal/art-dialog/index.vue";
import FaTable from "@/components/tables/fa-table/index.vue";
import FaTableHeader from "@/components/tables/fa-table-header/index.vue";
import FaTableHeaderLeft from "@/components/tables/fa-table-header-left/index.vue";
import FaExportDialog from "@/components/modal/fa-export-dialog/index.vue";
import type { IObject } from "@/components/modal/types";
import FaSearchBar from "@/components/forms/fa-search-bar/index.vue";
import type { SearchFormItem } from "@/components/forms/fa-search-bar/index.vue";
import FaDialog from "@/components/modal/fa-dialog/index.vue";
import type { ColumnOption } from "@/types/component";
import NoticeAPI, {
type NoticeForm,
@@ -196,9 +196,9 @@ import { useAuth } from "@/hooks/core/useAuth";
import { renderTableOperationCell, type TableOperationAction } from "@utils/table";
import { useDictStore, useNoticeStore } from "@stores/index";
import UserTableSelect from "@views/module_system/user/components/UserTableSelect.vue";
import ArtWangEditor from "@/components/Core/forms/art-wang-editor/index.vue";
import ArtForm from "@/components/Core/forms/art-form/index.vue";
import type { FormItem } from "@/components/Core/forms/art-form/index.vue";
import ArtWangEditor from "@/components/forms/fa-wang-editor/index.vue";
import FaForm from "@/components/forms/fa-form/index.vue";
import type { FormItem } from "@/components/forms/fa-form/index.vue";
defineOptions({
name: "Notice",
@@ -240,7 +240,7 @@ const searchForm = ref<NoticeSearchForm>({
});
const showSearchBar = ref(true);
const searchBarRef = ref<InstanceType<typeof ArtSearchBar> | null>(null);
const searchBarRef = ref<InstanceType<typeof FaSearchBar> | null>(null);
const searchBarRules: Record<string, unknown> = {};
const statusOptions = ref([
@@ -309,7 +309,7 @@ const noticeSearchItems = computed<SearchFormItem[]>(() => [
},
]);
const artTableRef = ref<{ elTableRef?: { clearSelection: () => void } } | null>(null);
const FaTableRef = ref<{ elTableRef?: { clearSelection: () => void } } | null>(null);
const selectedRows = ref<NoticeTable[]>([]);
const selectedIds = computed(() =>
selectedRows.value.map((r) => r.id).filter((id): id is number => id != null && !Number.isNaN(id))
@@ -463,7 +463,7 @@ const detailHasRenderableContent = computed(() => {
return plain.length > 0;
});
const formData = reactive<NoticeForm>({
const formData = ref<NoticeForm>({
id: undefined,
notice_title: "",
notice_type: "",
@@ -485,13 +485,13 @@ const rules = reactive({
status: [{ required: true, message: "请选择公告通知状态", trigger: "blur" }],
});
const dataFormRef = ref<InstanceType<typeof ArtForm> | null>(null);
const dataFormRef = ref<InstanceType<typeof FaForm> | null>(null);
const submitLoading = ref(false);
/** 每次打开弹窗递增,令 ArtForm 重新挂载并同步初始 model(与示例页声明式 items 一致) */
/** 每次打开弹窗递增,令 FaForm 重新挂载并同步初始 model(与示例页声明式 items 一致) */
const noticeFormRenderKey = ref(0);
/** 公告编辑表单字段配置(ArtForm + items) */
/** 公告编辑表单字段配置(FaForm + items) */
const noticeDialogFormItems = computed<FormItem[]>(() => [
{
label: "标题",
@@ -660,7 +660,7 @@ function deleteNoticeRow(id: number) {
await NoticeAPI.deleteNotice([id]);
await noticeStore.getNotice();
ElMessage.success("删除成功");
artTableRef.value?.elTableRef?.clearSelection();
FaTableRef.value?.elTableRef?.clearSelection();
await refreshRemove();
})
.catch(() => {});
@@ -721,7 +721,7 @@ function handleBatchDelete() {
await NoticeAPI.deleteNotice(ids);
await noticeStore.getNotice();
ElMessage.success("删除成功");
artTableRef.value?.elTableRef?.clearSelection();
FaTableRef.value?.elTableRef?.clearSelection();
await refreshRemove();
} finally {
batchDeleting.value = false;
@@ -759,11 +759,7 @@ onMounted(async () => {
</script>
<style scoped lang="scss">
.art-table-card {
flex: 1;
}
/* ArtForm 底部预留的操作栏列在弹窗内不需要占位 */
/* FaForm 底部预留的操作栏列在弹窗内不需要占位 */
.crud-dialog-art-form :deep(.el-row > .el-col:last-child) {
display: none;
}
@@ -1,5 +1,5 @@
<template>
<ArtDrawer
<FaDrawer
v-model="drawerVisible"
title="配置中心"
:size="drawerSize"
@@ -281,7 +281,7 @@
保存
</ElButton>
</template>
</ArtDrawer>
</FaDrawer>
</template>
<script lang="ts" setup>
@@ -290,7 +290,7 @@ import ParamsAPI, { type ConfigTable } from "@/api/module_system/params";
import { useConfigStore } from "@stores";
import { useI18n } from "vue-i18n";
import { ElMessage, ElMessageBox } from "element-plus";
import ArtDrawer from "@/components/Core/modal/art-drawer/index.vue";
import FaDrawer from "@/components/modal/fa-drawer/index.vue";
import SingleImageUpload from "@/components/Upload/SingleImageUpload.vue";
import { useAppStore } from "@stores/modules/app.store";
import { DeviceEnum } from "@/enums/settings/device.enum";
@@ -1,7 +1,7 @@
<!-- 系统配置:Art 布局 + useTable,与 notice 页一致 -->
<template>
<div class="art-full-height">
<ArtSearchBar
<FaSearchBar
v-show="showSearchBar"
ref="searchBarRef"
v-model="searchForm"
@@ -18,14 +18,14 @@
/>
<ElCard class="art-table-card" :style="{ 'margin-top': showSearchBar ? '12px' : '0' }">
<ArtTableHeader
<FaTableHeader
v-model:columns="columnChecks"
v-model:showSearchBar="showSearchBar"
:loading="loading"
@refresh="refreshData"
>
<template #left>
<ArtTableHeaderLeft
<FaTableHeaderLeft
:remove-ids="selectedIds"
:perm-create="['module_system:param:create']"
:perm-export="['module_system:param:export']"
@@ -36,10 +36,10 @@
@delete="handleBatchDelete"
/>
</template>
</ArtTableHeader>
</FaTableHeader>
<ArtTable
ref="artTableRef"
<FaTable
ref="FaTableRef"
:loading="loading"
:data="data"
:columns="columns"
@@ -50,7 +50,7 @@
/>
</ElCard>
<ArtDialog
<FaDialog
v-model="dialogVisible.visible"
:title="dialogVisible.title"
width="640px"
@@ -88,7 +88,7 @@
</template>
<template v-else>
<ElScrollbar max-height="75vh" :view-style="{ overflowX: 'hidden' }">
<ArtForm
<FaForm
:key="paramFormRenderKey"
ref="dataFormRef"
v-model="formData"
@@ -109,7 +109,7 @@
<ElRadio :value="false">否</ElRadio>
</ElRadioGroup>
</template>
</ArtForm>
</FaForm>
</ElScrollbar>
</template>
@@ -127,9 +127,9 @@
<ElButton v-else type="primary" @click="handleCloseDialog">确定</ElButton>
</div>
</template>
</ArtDialog>
</FaDialog>
<ArtExportDialog
<FaExportDialog
v-model="exportModalVisible"
:content-config="paramExportContentConfig"
:query-params="exportQueryParams"
@@ -142,16 +142,16 @@
<script setup lang="ts">
import { h, computed, ref, reactive } from "vue";
import { useTable } from "@/hooks/core/useTable";
import ArtTable from "@/components/Core/tables/art-table/index.vue";
import ArtTableHeader from "@/components/Core/tables/art-table-header/index.vue";
import ArtTableHeaderLeft from "@/components/Core/tables/art-table-header-left/index.vue";
import ArtExportDialog from "@/components/Core/modal/art-export-dialog/index.vue";
import type { IObject } from "@/components/Core/modal/types";
import ArtSearchBar from "@/components/Core/forms/art-search-bar/index.vue";
import type { SearchFormItem } from "@/components/Core/forms/art-search-bar/index.vue";
import ArtDialog from "@/components/Core/modal/art-dialog/index.vue";
import ArtForm from "@/components/Core/forms/art-form/index.vue";
import type { FormItem } from "@/components/Core/forms/art-form/index.vue";
import FaTable from "@/components/tables/fa-table/index.vue";
import FaTableHeader from "@/components/tables/fa-table-header/index.vue";
import FaTableHeaderLeft from "@/components/tables/fa-table-header-left/index.vue";
import FaExportDialog from "@/components/modal/fa-export-dialog/index.vue";
import type { IObject } from "@/components/modal/types";
import FaSearchBar from "@/components/forms/fa-search-bar/index.vue";
import type { SearchFormItem } from "@/components/forms/fa-search-bar/index.vue";
import FaDialog from "@/components/modal/fa-dialog/index.vue";
import FaForm from "@/components/forms/fa-form/index.vue";
import type { FormItem } from "@/components/forms/fa-form/index.vue";
import type { ColumnOption } from "@/types/component";
import ParamsAPI, {
type ConfigForm,
@@ -205,7 +205,7 @@ const searchForm = ref<ParamSearchForm>({
});
const showSearchBar = ref(true);
const searchBarRef = ref<InstanceType<typeof ArtSearchBar> | null>(null);
const searchBarRef = ref<InstanceType<typeof FaSearchBar> | null>(null);
const searchBarRules: Record<string, unknown> = {};
const builtinOptions = ref([
@@ -258,7 +258,7 @@ const paramSearchItems = computed<SearchFormItem[]>(() => [
},
]);
const artTableRef = ref<{ elTableRef?: { clearSelection: () => void } } | null>(null);
const FaTableRef = ref<{ elTableRef?: { clearSelection: () => void } } | null>(null);
const selectedRows = ref<ConfigTable[]>([]);
const selectedIds = computed(() =>
selectedRows.value.map((r) => r.id).filter((id): id is number => id != null && !Number.isNaN(id))
@@ -370,7 +370,7 @@ const paginationBind = computed(() => {
const detailFormData = ref<ConfigTable>({} as ConfigTable);
const formData = reactive<ConfigForm>({
const formData = ref<ConfigForm>({
id: undefined,
config_name: "",
config_key: "",
@@ -392,7 +392,7 @@ const rules = reactive({
config_type: [{ required: true, message: "请选择系统配置类型", trigger: "blur" }],
});
const dataFormRef = ref<InstanceType<typeof ArtForm> | null>(null);
const dataFormRef = ref<InstanceType<typeof FaForm> | null>(null);
const paramFormRenderKey = ref(0);
const paramDialogFormItems = computed<FormItem[]>(() => [
@@ -534,7 +534,7 @@ function deleteParamRow(id: number) {
configStore.isConfigLoaded = false;
await configStore.getConfig();
ElMessage.success("删除成功");
artTableRef.value?.elTableRef?.clearSelection();
FaTableRef.value?.elTableRef?.clearSelection();
await refreshRemove();
})
.catch(() => {});
@@ -596,7 +596,7 @@ function handleBatchDelete() {
configStore.isConfigLoaded = false;
await configStore.getConfig();
ElMessage.success("删除成功");
artTableRef.value?.elTableRef?.clearSelection();
FaTableRef.value?.elTableRef?.clearSelection();
await refreshRemove();
} finally {
batchDeleting.value = false;
@@ -1,7 +1,7 @@
<!-- 岗位管理:Art + useTable;操作列前 3 个为 ArtButtonTable,其余收入「更多」下拉 -->
<template>
<div class="art-full-height">
<ArtSearchBar
<FaSearchBar
v-show="showSearchBar"
ref="searchBarRef"
v-model="searchForm"
@@ -24,17 +24,17 @@
@clear-click="afterUserSelectSearch"
/>
</template>
</ArtSearchBar>
</FaSearchBar>
<ElCard class="art-table-card" :style="{ 'margin-top': showSearchBar ? '12px' : '0' }">
<ArtTableHeader
<FaTableHeader
v-model:columns="columnChecks"
v-model:showSearchBar="showSearchBar"
:loading="loading"
@refresh="refreshData"
>
<template #left>
<ArtTableHeaderLeft
<FaTableHeaderLeft
:remove-ids="selectedIds"
:perm-create="['module_system:position:create']"
:perm-export="['module_system:position:export']"
@@ -47,10 +47,10 @@
@more="handleMoreClick"
/>
</template>
</ArtTableHeader>
</FaTableHeader>
<ArtTable
ref="artTableRef"
<FaTable
ref="FaTableRef"
:loading="loading"
:data="data"
:columns="columns"
@@ -61,7 +61,7 @@
/>
</ElCard>
<ArtDialog
<FaDialog
v-model="dialogVisible.visible"
:title="dialogVisible.title"
width="720px"
@@ -102,7 +102,7 @@
</template>
<template v-else>
<ElScrollbar max-height="75vh" :view-style="{ overflowX: 'hidden' }">
<ArtForm
<FaForm
:key="positionFormRenderKey"
ref="dataFormRef"
v-model="formData"
@@ -123,7 +123,7 @@
<ElRadio value="1">停用</ElRadio>
</ElRadioGroup>
</template>
</ArtForm>
</FaForm>
</ElScrollbar>
</template>
@@ -141,9 +141,9 @@
<ElButton v-else type="primary" @click="handleCloseDialog">确定</ElButton>
</div>
</template>
</ArtDialog>
</FaDialog>
<ArtExportDialog
<FaExportDialog
v-model="exportModalVisible"
:content-config="positionExportContentConfig"
:query-params="exportQueryParams"
@@ -156,17 +156,17 @@
<script setup lang="ts">
import { h, computed, ref, reactive, nextTick } from "vue";
import { useTable } from "@/hooks/core/useTable";
import ArtTable from "@/components/Core/tables/art-table/index.vue";
import ArtTableHeader from "@/components/Core/tables/art-table-header/index.vue";
import ArtTableHeaderLeft from "@/components/Core/tables/art-table-header-left/index.vue";
import ArtExportDialog from "@/components/Core/modal/art-export-dialog/index.vue";
import ArtButtonTable from "@/components/Core/forms/art-button-table/index.vue";
import type { IObject } from "@/components/Core/modal/types";
import ArtSearchBar from "@/components/Core/forms/art-search-bar/index.vue";
import type { SearchFormItem } from "@/components/Core/forms/art-search-bar/index.vue";
import ArtDialog from "@/components/Core/modal/art-dialog/index.vue";
import ArtForm from "@/components/Core/forms/art-form/index.vue";
import type { FormItem } from "@/components/Core/forms/art-form/index.vue";
import FaTable from "@/components/tables/fa-table/index.vue";
import FaTableHeader from "@/components/tables/fa-table-header/index.vue";
import FaTableHeaderLeft from "@/components/tables/fa-table-header-left/index.vue";
import FaExportDialog from "@/components/modal/fa-export-dialog/index.vue";
import ArtButtonTable from "@/components/forms/fa-button-table/index.vue";
import type { IObject } from "@/components/modal/types";
import FaSearchBar from "@/components/forms/fa-search-bar/index.vue";
import type { SearchFormItem } from "@/components/forms/fa-search-bar/index.vue";
import FaDialog from "@/components/modal/fa-dialog/index.vue";
import FaForm from "@/components/forms/fa-form/index.vue";
import type { FormItem } from "@/components/forms/fa-form/index.vue";
import type { ColumnOption } from "@/types/component";
import PositionAPI, {
type PositionForm,
@@ -341,7 +341,7 @@ const searchForm = ref<PositionSearchForm>({
});
const showSearchBar = ref(true);
const searchBarRef = ref<InstanceType<typeof ArtSearchBar> | null>(null);
const searchBarRef = ref<InstanceType<typeof FaSearchBar> | null>(null);
const searchBarRules: Record<string, unknown> = {};
const statusOptions = ref([
@@ -392,7 +392,7 @@ const positionSearchItems = computed<SearchFormItem[]>(() => [
},
]);
const artTableRef = ref<{ elTableRef?: { clearSelection: () => void } } | null>(null);
const FaTableRef = ref<{ elTableRef?: { clearSelection: () => void } } | null>(null);
const selectedRows = ref<PositionTable[]>([]);
const selectedIds = computed(() =>
selectedRows.value.map((r) => r.id).filter((id): id is number => id != null && !Number.isNaN(id))
@@ -413,7 +413,7 @@ function deletePositionRow(id: number) {
await PositionAPI.deletePosition([id]);
await userStore.getUserInfo();
ElMessage.success("删除成功");
artTableRef.value?.elTableRef?.clearSelection();
FaTableRef.value?.elTableRef?.clearSelection();
await refreshRemove();
})
.catch(() => {});
@@ -537,7 +537,7 @@ const paginationBind = computed(() => {
const detailFormData = ref<PositionTable>({});
const formData = reactive<PositionForm>({
const formData = ref<PositionForm>({
id: undefined,
name: undefined,
order: 1,
@@ -565,7 +565,7 @@ const initialFormData: PositionForm = {
description: undefined,
};
const dataFormRef = ref<InstanceType<typeof ArtForm> | null>(null);
const dataFormRef = ref<InstanceType<typeof FaForm> | null>(null);
const positionFormRenderKey = ref(0);
const positionDialogFormItems = computed<FormItem[]>(() => [
@@ -707,7 +707,7 @@ function handleBatchDelete() {
await PositionAPI.deletePosition(ids);
await userStore.getUserInfo();
ElMessage.success("删除成功");
artTableRef.value?.elTableRef?.clearSelection();
FaTableRef.value?.elTableRef?.clearSelection();
await refreshRemove();
} finally {
batchDeleting.value = false;
@@ -1,6 +1,6 @@
<!-- 角色授权 -->
<template>
<ArtDrawer
<FaDrawer
v-model="drawerVisible"
:title="'【' + props.roleName + '】权限分配'"
:size="drawerSize"
@@ -143,14 +143,14 @@
<ElButton type="primary" :loading="loading" @click.stop="handleDrawerSave">确 定</ElButton>
</div>
</template>
</ArtDrawer>
</FaDrawer>
</template>
<script setup lang="ts">
import { computed, ref, watch, onMounted } from "vue";
import { QuestionFilled, Switch as SwitchIcon } from "@element-plus/icons-vue";
import type { TreeInstance } from "element-plus";
import ArtDrawer from "@/components/Core/modal/art-drawer/index.vue";
import FaDrawer from "@/components/modal/fa-drawer/index.vue";
import { listToTree, formatTree } from "@utils/common";
import RoleAPI, {
permissionDataType,
@@ -1,7 +1,7 @@
<!-- 角色管理:Art + useTable;操作列最多 3 个外露 +「更多」 -->
<template>
<div class="art-full-height">
<ArtSearchBar
<FaSearchBar
v-show="showSearchBar"
ref="searchBarRef"
v-model="searchForm"
@@ -18,14 +18,14 @@
/>
<ElCard class="art-table-card" :style="{ 'margin-top': showSearchBar ? '12px' : '0' }">
<ArtTableHeader
<FaTableHeader
v-model:columns="columnChecks"
v-model:showSearchBar="showSearchBar"
:loading="loading"
@refresh="refreshData"
>
<template #left>
<ArtTableHeaderLeft
<FaTableHeaderLeft
:remove-ids="selectedIds"
:perm-create="['module_system:role:create']"
:perm-export="['module_system:role:export']"
@@ -38,10 +38,10 @@
@more="handleMoreClick"
/>
</template>
</ArtTableHeader>
</FaTableHeader>
<ArtTable
ref="artTableRef"
<FaTable
ref="FaTableRef"
:loading="loading"
:data="data"
:columns="columns"
@@ -52,7 +52,7 @@
/>
</ElCard>
<ArtDialog
<FaDialog
v-model="dialogVisible.visible"
:title="dialogVisible.title"
width="720px"
@@ -113,7 +113,7 @@
</template>
<template v-else>
<ElScrollbar max-height="75vh" :view-style="{ overflowX: 'hidden' }">
<ArtForm
<FaForm
:key="roleFormRenderKey"
ref="dataFormRef"
v-model="formData"
@@ -134,7 +134,7 @@
<ElRadio value="1">停用</ElRadio>
</ElRadioGroup>
</template>
</ArtForm>
</FaForm>
</ElScrollbar>
</template>
@@ -152,7 +152,7 @@
<ElButton v-else type="primary" @click="handleCloseDialog">确定</ElButton>
</div>
</template>
</ArtDialog>
</FaDialog>
<PermissonDrawer
v-if="drawerVisible"
@@ -162,7 +162,7 @@
@saved="refreshData"
/>
<ArtExportDialog
<FaExportDialog
v-model="exportModalVisible"
:content-config="roleExportContentConfig"
:query-params="exportQueryParams"
@@ -175,17 +175,17 @@
<script setup lang="ts">
import { h, computed, ref, reactive } from "vue";
import { useTable } from "@/hooks/core/useTable";
import ArtTable from "@/components/Core/tables/art-table/index.vue";
import ArtTableHeader from "@/components/Core/tables/art-table-header/index.vue";
import ArtTableHeaderLeft from "@/components/Core/tables/art-table-header-left/index.vue";
import ArtExportDialog from "@/components/Core/modal/art-export-dialog/index.vue";
import FaTable from "@/components/tables/fa-table/index.vue";
import FaTableHeader from "@/components/tables/fa-table-header/index.vue";
import FaTableHeaderLeft from "@/components/tables/fa-table-header-left/index.vue";
import FaExportDialog from "@/components/modal/fa-export-dialog/index.vue";
import { renderTableOperationCell, type TableOperationAction } from "@utils/table";
import type { IObject } from "@/components/Core/modal/types";
import ArtSearchBar from "@/components/Core/forms/art-search-bar/index.vue";
import type { SearchFormItem } from "@/components/Core/forms/art-search-bar/index.vue";
import ArtDialog from "@/components/Core/modal/art-dialog/index.vue";
import ArtForm from "@/components/Core/forms/art-form/index.vue";
import type { FormItem } from "@/components/Core/forms/art-form/index.vue";
import type { IObject } from "@/components/modal/types";
import FaSearchBar from "@/components/forms/fa-search-bar/index.vue";
import type { SearchFormItem } from "@/components/forms/fa-search-bar/index.vue";
import FaDialog from "@/components/modal/fa-dialog/index.vue";
import FaForm from "@/components/forms/fa-form/index.vue";
import type { FormItem } from "@/components/forms/fa-form/index.vue";
import type { ColumnOption } from "@/types/component";
import RoleAPI, {
type RoleForm,
@@ -345,7 +345,7 @@ const searchForm = ref<RoleSearchForm>({
});
const showSearchBar = ref(true);
const searchBarRef = ref<InstanceType<typeof ArtSearchBar> | null>(null);
const searchBarRef = ref<InstanceType<typeof FaSearchBar> | null>(null);
const searchBarRules: Record<string, unknown> = {};
const statusOptions = ref([
@@ -390,7 +390,7 @@ const roleSearchItems = computed<SearchFormItem[]>(() => [
},
]);
const artTableRef = ref<{ elTableRef?: { clearSelection: () => void } } | null>(null);
const FaTableRef = ref<{ elTableRef?: { clearSelection: () => void } } | null>(null);
const selectedRows = ref<RoleTable[]>([]);
const selectedIds = computed(() =>
selectedRows.value.map((r) => r.id).filter((id): id is number => id != null && !Number.isNaN(id))
@@ -420,7 +420,7 @@ function deleteRoleRow(id: number) {
const userStore = useUserStore();
await userStore.getUserInfo();
ElMessage.success("删除成功");
artTableRef.value?.elTableRef?.clearSelection();
FaTableRef.value?.elTableRef?.clearSelection();
await refreshRemove();
})
.catch(() => {});
@@ -560,7 +560,7 @@ const paginationBind = computed(() => {
const detailFormData = ref<RoleTable>({} as RoleTable);
const formData = reactive<RoleForm>({
const formData = ref<RoleForm>({
id: undefined,
name: undefined,
order: 1,
@@ -591,7 +591,7 @@ const rules = reactive({
status: [{ required: true, message: "请选择状态", trigger: "blur" }],
});
const dataFormRef = ref<InstanceType<typeof ArtForm> | null>(null);
const dataFormRef = ref<InstanceType<typeof FaForm> | null>(null);
const roleFormRenderKey = ref(0);
const roleDialogFormItems = computed<FormItem[]>(() => [
@@ -744,7 +744,7 @@ function handleBatchDelete() {
const userStore = useUserStore();
await userStore.getUserInfo();
ElMessage.success("删除成功");
artTableRef.value?.elTableRef?.clearSelection();
FaTableRef.value?.elTableRef?.clearSelection();
await refreshRemove();
} finally {
batchDeleting.value = false;
@@ -1,7 +1,7 @@
<!-- 租户管理:Art + useTable;操作列前 3 个为 ArtButtonTable,其余收入「更多」下拉 -->
<template>
<div class="art-full-height">
<ArtSearchBar
<FaSearchBar
v-show="showSearchBar"
ref="searchBarRef"
v-model="searchForm"
@@ -18,14 +18,14 @@
/>
<ElCard class="art-table-card" :style="{ 'margin-top': showSearchBar ? '12px' : '0' }">
<ArtTableHeader
<FaTableHeader
v-model:columns="columnChecks"
v-model:showSearchBar="showSearchBar"
:loading="loading"
@refresh="refreshData"
>
<template #left>
<ArtTableHeaderLeft
<FaTableHeaderLeft
:remove-ids="selectedIds"
:perm-create="['module_system:tenant:create']"
:perm-delete="['module_system:tenant:delete']"
@@ -34,10 +34,10 @@
@delete="handleBatchDelete"
/>
</template>
</ArtTableHeader>
</FaTableHeader>
<ArtTable
ref="artTableRef"
<FaTable
ref="FaTableRef"
:loading="loading"
:data="data"
:columns="columns"
@@ -48,7 +48,7 @@
/>
</ElCard>
<ArtDialog
<FaDialog
v-model="dialogVisible.visible"
:title="dialogVisible.title"
width="640px"
@@ -87,7 +87,7 @@
</template>
<template v-else>
<ElScrollbar max-height="75vh" :view-style="{ overflowX: 'hidden' }">
<ArtForm
<FaForm
:key="tenantFormRenderKey"
ref="dataFormRef"
v-model="formData"
@@ -119,22 +119,22 @@
<ElButton v-else type="primary" @click="handleCloseDialog">确定</ElButton>
</div>
</template>
</ArtDialog>
</FaDialog>
</div>
</template>
<script setup lang="ts">
import { h, computed, ref, reactive } from "vue";
import { useTable } from "@/hooks/core/useTable";
import ArtTable from "@/components/Core/tables/art-table/index.vue";
import ArtTableHeader from "@/components/Core/tables/art-table-header/index.vue";
import ArtTableHeaderLeft from "@/components/Core/tables/art-table-header-left/index.vue";
import ArtButtonTable from "@/components/Core/forms/art-button-table/index.vue";
import ArtSearchBar from "@/components/Core/forms/art-search-bar/index.vue";
import type { SearchFormItem } from "@/components/Core/forms/art-search-bar/index.vue";
import ArtDialog from "@/components/Core/modal/art-dialog/index.vue";
import ArtForm from "@/components/Core/forms/art-form/index.vue";
import type { FormItem } from "@/components/Core/forms/art-form/index.vue";
import FaTable from "@/components/tables/fa-table/index.vue";
import FaTableHeader from "@/components/tables/fa-table-header/index.vue";
import FaTableHeaderLeft from "@/components/tables/fa-table-header-left/index.vue";
import ArtButtonTable from "@/components/forms/fa-button-table/index.vue";
import FaSearchBar from "@/components/forms/fa-search-bar/index.vue";
import type { SearchFormItem } from "@/components/forms/fa-search-bar/index.vue";
import FaDialog from "@/components/modal/fa-dialog/index.vue";
import FaForm from "@/components/forms/fa-form/index.vue";
import type { FormItem } from "@/components/forms/fa-form/index.vue";
import type { ColumnOption } from "@/types/component";
import TenantAPI, {
type TenantCreateForm,
@@ -300,7 +300,7 @@ const searchForm = ref<TenantSearchForm>({
});
const showSearchBar = ref(true);
const searchBarRef = ref<InstanceType<typeof ArtSearchBar> | null>(null);
const searchBarRef = ref<InstanceType<typeof FaSearchBar> | null>(null);
const searchBarRules: Record<string, unknown> = {};
const statusOptions = ref([
@@ -353,7 +353,7 @@ const tenantSearchItems = computed<SearchFormItem[]>(() => [
},
]);
const artTableRef = ref<{ elTableRef?: { clearSelection: () => void } } | null>(null);
const FaTableRef = ref<{ elTableRef?: { clearSelection: () => void } } | null>(null);
const selectedRows = ref<TenantTable[]>([]);
const selectedIds = computed(() =>
selectedRows.value.map((r) => r.id).filter((id): id is number => id != null && !Number.isNaN(id))
@@ -373,7 +373,7 @@ function deleteTenantRow(id: number) {
.then(async () => {
await TenantAPI.deleteTenant([id]);
ElMessage.success("删除成功");
artTableRef.value?.elTableRef?.clearSelection();
FaTableRef.value?.elTableRef?.clearSelection();
await refreshRemove();
})
.catch(() => {});
@@ -455,7 +455,7 @@ const detailFormData = ref<TenantTable>({ code: "", name: "", status: "0" });
const currentEditId = ref<number | null>(null);
const formData = reactive<TenantForm>({
const formData = ref<TenantForm>({
name: "",
code: "",
status: "0",
@@ -502,7 +502,7 @@ const initialFormData: TenantForm = {
end_time: undefined,
};
const dataFormRef = ref<InstanceType<typeof ArtForm> | null>(null);
const dataFormRef = ref<InstanceType<typeof FaForm> | null>(null);
const submitLoading = ref(false);
const tenantFormRenderKey = ref(0);
@@ -672,7 +672,7 @@ function handleBatchDelete() {
batchDeleting.value = true;
await TenantAPI.deleteTenant(ids);
ElMessage.success("删除成功");
artTableRef.value?.elTableRef?.clearSelection();
FaTableRef.value?.elTableRef?.clearSelection();
await refreshRemove();
} finally {
batchDeleting.value = false;
@@ -15,8 +15,8 @@
</template>
<script setup lang="ts">
import type { ISelectConfig } from "@/components/TableSelect/index.vue";
import UserAPI from "@/api/module_system/user";
import type { ISelectConfig } from "@/components/others/fa-table-select/index.vue";
import UserAPI, { UserPageQuery } from "@/api/module_system/user";
// 父组件双向绑定的值(选中用户ID)
const props = defineProps<{ modelValue?: number }>();
@@ -29,7 +29,7 @@ const emit = defineEmits<{
const selectConfig: ISelectConfig = {
pk: "id",
/** 与 ArtSearchBar 栅格内 ElInput 一致,占满表单项内容区 */
/** 与 FaSearchBar 栅格内 ElInput 一致,占满表单项内容区 */
width: "100%",
placeholder: "请选择用户",
popover: {
@@ -54,7 +54,7 @@ const selectConfig: ISelectConfig = {
],
},
],
indexAction(params) {
indexAction(params: UserPageQuery) {
// 映射查询参数到后端接口
const query: any = { ...params };
// 清理空字符串/空值,避免后端 422
@@ -22,7 +22,7 @@
</div>
<div class="user-main-panel flex flex-col flex-grow min-w-0 min-h-0">
<ArtSearchBar
<FaSearchBar
v-show="showSearchBar"
ref="searchBarRef"
v-model="searchForm"
@@ -45,20 +45,17 @@
@clear-click="afterUserSelectSearch"
/>
</template>
</ArtSearchBar>
</FaSearchBar>
<ElCard
class="flex flex-col flex-1 min-h-0 art-table-card"
:style="{ 'margin-top': showSearchBar ? '12px' : '0' }"
>
<ArtTableHeader
<ElCard class="art-table-card" :style="{ 'margin-top': showSearchBar ? '12px' : '0' }">
<FaTableHeader
v-model:columns="columnChecks"
v-model:showSearchBar="showSearchBar"
:loading="loading"
@refresh="refreshData"
>
<template #left>
<ArtTableHeaderLeft
<FaTableHeaderLeft
:remove-ids="selectedIds"
:perm-create="['module_system:user:create']"
:perm-import="['module_system:user:import']"
@@ -74,10 +71,10 @@
@more="handleMoreClick"
/>
</template>
</ArtTableHeader>
</FaTableHeader>
<ArtTable
ref="artTableRef"
<FaTable
ref="FaTableRef"
row-key="id"
:loading="loading"
:data="data"
@@ -91,7 +88,7 @@
</div>
</div>
<ArtDrawer
<FaDrawer
v-model="dialogVisible.visible"
:title="dialogVisible.title"
append-to-body
@@ -294,7 +291,7 @@
<ElButton v-else type="primary" @click="handleCloseDialog">确定</ElButton>
</div>
</template>
</ArtDrawer>
</FaDrawer>
<ArtImportDialog
v-model="importModalVisible"
@@ -304,7 +301,7 @@
@upload="handleImportUpload"
/>
<ArtExportDialog
<FaExportDialog
v-model="exportModalVisible"
:content-config="userExportContentConfig"
:query-params="exportQueryParams"
@@ -326,15 +323,15 @@ import { useAppStore } from "@stores/modules/app.store";
import { DeviceEnum } from "@/enums/settings/device.enum";
import { ResultEnum } from "@/enums/api/result.enum";
import { useTable } from "@/hooks/core/useTable";
import ArtTable from "@/components/Core/tables/art-table/index.vue";
import ArtTableHeader from "@/components/Core/tables/art-table-header/index.vue";
import ArtTableHeaderLeft from "@/components/Core/tables/art-table-header-left/index.vue";
import ArtSearchBar from "@/components/Core/forms/art-search-bar/index.vue";
import type { SearchFormItem } from "@/components/Core/forms/art-search-bar/index.vue";
import ArtDrawer from "@/components/Core/modal/art-drawer/index.vue";
import ArtImportDialog from "@/components/Core/modal/art-import-dialog/index.vue";
import ArtExportDialog from "@/components/Core/modal/art-export-dialog/index.vue";
import type { IContentConfig, IObject } from "@/components/Core/modal/types";
import FaTable from "@/components/tables/fa-table/index.vue";
import FaTableHeader from "@/components/tables/fa-table-header/index.vue";
import FaTableHeaderLeft from "@/components/tables/fa-table-header-left/index.vue";
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 ArtImportDialog from "@/components/modal/fa-import-dialog/index.vue";
import FaExportDialog from "@/components/modal/fa-export-dialog/index.vue";
import type { IContentConfig, IObject } from "@/components/modal/types";
import UserAPI, {
type UserForm,
type UserInfo,
@@ -479,7 +476,7 @@ const searchForm = ref<UserSearchForm>({
});
const showSearchBar = ref(true);
const searchBarRef = ref<InstanceType<typeof ArtSearchBar> | null>(null);
const searchBarRef = ref<InstanceType<typeof FaSearchBar> | null>(null);
const searchBarRules: Record<string, unknown> = {};
const statusOptions = ref([
@@ -538,7 +535,7 @@ const userSearchItems = computed<SearchFormItem[]>(() => [
},
]);
const artTableRef = ref<{ elTableRef?: { clearSelection: () => void } } | null>(null);
const FaTableRef = ref<{ elTableRef?: { clearSelection: () => void } } | null>(null);
const selectedRows = ref<UserInfo[]>([]);
const selectedIds = computed(() =>
selectedRows.value.map((r) => r.id).filter((id): id is number => id != null && !Number.isNaN(id))
@@ -579,7 +576,7 @@ function deleteUserRow(id: number) {
} else {
ElMessage.success("删除成功");
}
artTableRef.value?.elTableRef?.clearSelection();
FaTableRef.value?.elTableRef?.clearSelection();
await refreshRemove();
})
.catch(() => {});
@@ -732,22 +729,7 @@ const userExportContentConfig = computed(() => ({
},
}));
const paginationBind = computed(() => {
const p = pagination as unknown as {
current?: number;
size?: number;
total?: number;
page_no?: number;
page_size?: number;
};
return {
current: p.current ?? p.page_no ?? 1,
size: p.size ?? p.page_size ?? 20,
total: p.total ?? 0,
};
});
const formData = reactive<UserForm>({
const formData = ref<UserForm>({
id: undefined,
username: undefined,
name: undefined,