太美丽了!

This commit is contained in:
Cain 2025-03-12 14:13:29 +08:00
parent fa71031f00
commit 075fd374b3
5 changed files with 99 additions and 62 deletions

View File

@ -1,14 +1,21 @@
import { request } from '../request'; import { request } from '../request';
/** get category list */ /** get category list */
export function fetchGetCategoryList(name?: string | null, type?: string | null) { // export function fetchGetCategoryList(name?: string | null, type?: string | null) {
// return request({
// url: '/category/categoryTree',
// method: 'post',
// data: {
// categoryName: name,
// categoryType: type
// }
// });
// }
export function fetchGetCategoryList(data?: Api.Category.CategorySearchParams) {
return request({ return request({
url: '/category/categoryTree', url: '/category/categoryTree',
method: 'post', method: 'post',
data: { data
categoryName: name,
categoryType: type
}
}); });
} }

View File

@ -1368,6 +1368,11 @@ declare namespace Api {
namespace Category { namespace Category {
type CategoryType = '网站' | '文献'; type CategoryType = '网站' | '文献';
type CategorySearchParams = {
categoryName?: string | null,
categoryType?: string | null
}
type RowData = Category & { type RowData = Category & {
children?: RowData[]; children?: RowData[];
}; };

View File

@ -1,25 +1,19 @@
<script setup lang="tsx"> <script setup lang="tsx">
import { $t } from '@/locales'; import { $t } from '@/locales';
import { ref, onMounted } from 'vue';
import { NButton, NPopconfirm, DataTableColumns } from 'naive-ui'; import { NButton, NPopconfirm, DataTableColumns } from 'naive-ui';
import { fetchGetCategoryList, fetchDeleteCategory } from '@/service/api'; import { fetchGetCategoryList, fetchDeleteCategory } from '@/service/api';
import { useFormOperate } from './modules/table'; import { useFormOperate, useCategoryTable } from './modules/table';
import CategorySearch from './modules/category.vue'; import CategorySearch from './modules/category.vue';
import CategoryOperateDrawer from './modules/category-operate-drawer.vue'; import CategoryOperateDrawer from './modules/category-operate-drawer.vue';
import CategoryHeaderOperation from "./modules/category-header-operation.vue"; import CategoryHeaderOperation from "./modules/category-header-operation.vue";
onMounted(async () => { const {
try { loading,
getData(); tableData,
} catch (error) { params,
window.$message?.success($t('common.loadFail')); getData,
} rowKey,
}); } = useCategoryTable(fetchGetCategoryList);
let loading = ref(false)
//
let tableData = ref<Api.Category.RowData[]>([]);
//
const columns = (): DataTableColumns<Api.Category.RowData> => [ const columns = (): DataTableColumns<Api.Category.RowData> => [
{ {
title: $t('page.category.form.categoryName'), title: $t('page.category.form.categoryName'),
@ -69,23 +63,18 @@ const columns = (): DataTableColumns<Api.Category.RowData> => [
) )
} }
] ]
const rowKey = (row: Api.Category.RowData) => row.id
const getData = async () => {
loading.value = true;
const { data } = await fetchGetCategoryList();
tableData.value = data as Api.Category.RowData[];
loading.value = false;
};
const { const {
drawerVisible, drawerVisible,
operateType, operateType,
editingData, editingData,
handleAdd, handleAdd,
handleEdit, handleEdit,
onDeleted onDeleted,
onUpdate
} = useFormOperate({ } = useFormOperate({
getData getData,
immediate: true
}); });
// //
@ -106,17 +95,15 @@ const Delete = async (id: number) => {
if (res.error) return; if (res.error) return;
onDeleted(); onDeleted();
} }
//
const update = (res: Api.Category.RowData[]) => {
tableData.value = res;
}
</script> </script>
<template> <template>
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto"> <div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
<!-- 查询组件 --> <!-- 查询组件 -->
<CategorySearch <CategorySearch
@update="update" @update="onUpdate"
v-model:model="params"
/> />
<DeleteAlert /> <DeleteAlert />
<NCard <NCard
@ -140,6 +127,7 @@ const update = (res: Api.Category.RowData[]) => {
:max-height="490" :max-height="490"
:columns="columns()" :columns="columns()"
:data="tableData" :data="tableData"
:loading="loading"
:row-key="rowKey" :row-key="rowKey"
default-expand-all default-expand-all
/> />
@ -152,6 +140,5 @@ const update = (res: Api.Category.RowData[]) => {
/> />
</NCard> </NCard>
</div> </div>
</template> </template>

View File

@ -1,12 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { $t } from '@/locales'; import { $t } from '@/locales';
import { ref, computed } from 'vue'; import { computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { NCard, NForm, NFormItemGi, NGrid, NInput, NSelect, NButton, NSpace } from 'naive-ui'; import { NCard, NForm, NFormItemGi, NGrid, NInput, NSelect, NButton, NSpace } from 'naive-ui';
import { useAppStore } from '@/store/modules/app'; import { useAppStore } from '@/store/modules/app';
import { translateOptions } from '@/utils/common';
// import { categoryTypeOptions } from '@/constants/business';
import { fetchGetCategoryList } from '@/service/api';
const appStore = useAppStore(); const appStore = useAppStore();
interface Model { interface Model {
@ -14,9 +10,10 @@ interface Model {
categoryType: string | null; categoryType: string | null;
} }
const model = ref<Model>({ // 使 defineModel
categoryName: null, const model = defineModel<Model>('model', {
categoryType: null required: true,
default: () => ({ categoryName: null, categoryType: null })
}); });
const categoryTypeOptions = [ const categoryTypeOptions = [
@ -27,27 +24,17 @@ const categoryTypeOptions = [
const btnSpan = computed(() => appStore.isMobile ? '24' : '12'); const btnSpan = computed(() => appStore.isMobile ? '24' : '12');
interface Emits { interface Emits {
(e: 'update', value: any): void; (e: 'update'): void;
} }
const emit = defineEmits<Emits>(); const emit = defineEmits<Emits>();
const search = async () => { const search = async () => {
console.log('搜索:', model.value.categoryName); emit('update');
//
try {
const {data} = await fetchGetCategoryList(model.value.categoryName, model.value.categoryType);
emit('update', data);
} catch (error) {
console.error('Failed to fetch category list:', error);
}
} }
function reset() {
async function reset() { model.value.categoryName = null;
model.value.categoryName = null; model.value.categoryType = null;
model.value.categoryType = null; emit('update');
//
const {data} = await fetchGetCategoryList();
emit('update', data);
} }
</script> </script>

View File

@ -1,12 +1,47 @@
import { ref, Ref, Reactive } from 'vue'; import { ref, Ref } from 'vue';
import { jsonClone } from '@sa/utils';
import { useBoolean } from '@sa/hooks'; import { useBoolean } from '@sa/hooks';
import { $t } from '@/locales'; import { $t } from '@/locales';
type CategoryApiFn<T = any, R = Api.Category.CategorySearchParams> = (
params?: R
) => Promise<NaiveUI.FlatResponseData<T>>; // data/msg
export function useCategoryTable<T extends Api.Category.RowData[]>(apiFn: CategoryApiFn<T>) {
const loading = ref(false);
const tableData = ref<Api.Category.RowData[]>([]);
const params = ref({
categoryName: null,
categoryType: null
});
const rowKey = (row: Api.Category.RowData) => row.id
const getData = async () => { // 无参
loading.value = true;
try {
const { data } = await apiFn(params.value);
tableData.value = data as Api.Category.RowData[];
} catch (error) {
console.error(error);
} finally {
loading.value = false;
}
};
return {
loading,
tableData,
params,
getData,
rowKey
};
}
export function useFormOperate<T extends Record<string, any>>(config: { export function useFormOperate<T extends Record<string, any>>(config: {
getData: () => Promise<void>; getData: () => Promise<void>;
immediate?: boolean; // 添加 immediate 参数,默认为 false
}) { }) {
const { getData } = config; const { getData, immediate } = config;
const { bool: drawerVisible, setTrue: openDrawer, setFalse: closeDrawer } = useBoolean(); const { bool: drawerVisible, setTrue: openDrawer, setFalse: closeDrawer } = useBoolean();
const operateType: Ref<NaiveUI.TableOperateType> = ref('add'); const operateType: Ref<NaiveUI.TableOperateType> = ref('add');
@ -38,6 +73,21 @@ export function useFormOperate<T extends Record<string, any>>(config: {
await getData(); await getData();
} }
async function onUpdate() {
console.log('搜索');
// 在这里添加搜索逻辑
try {
await getData();
} catch (error) {
window.$message?.error($t('common.loadFail'));
}
}
// 如果 immediate 为 true则在初始化时调用 getData
if (immediate) {
getData();
}
return { return {
drawerVisible, // 抽屉是否可见 drawerVisible, // 抽屉是否可见
operateType, // 操作类型 operateType, // 操作类型
@ -46,6 +96,7 @@ export function useFormOperate<T extends Record<string, any>>(config: {
closeDrawer, // 关闭抽屉 closeDrawer, // 关闭抽屉
handleAdd, // 添加操作 handleAdd, // 添加操作
handleEdit, // 编辑操作 handleEdit, // 编辑操作
onDeleted onDeleted, // 删除操作
onUpdate // 搜索操作
}; };
} }