fix: 保留工作流列表返回状态

- 记录页码、分类和搜索条件并同步到路由

- 从工作流设计页返回时恢复原列表位置
This commit is contained in:
2026-07-31 09:51:21 +08:00
parent 615092f4f7
commit c2ed5a24a3
8 changed files with 386 additions and 9 deletions

View File

@@ -1,5 +1,5 @@
<script setup>
import { computed, ref } from 'vue';
import { computed, ref, watch } from 'vue';
import { ArrowDown, Search } from '@element-plus/icons-vue';
import {
@@ -31,6 +31,10 @@ const props = defineProps({
type: Number,
default: 3,
},
initialValue: {
type: String,
default: '',
},
searchPlaceholder: {
type: String,
default: $t('common.searchPlaceholder'),
@@ -39,7 +43,14 @@ const props = defineProps({
const emit = defineEmits(['search', 'buttonClick', 'reset']);
const searchValue = ref('');
const searchValue = ref(props.initialValue);
watch(
() => props.initialValue,
(value) => {
searchValue.value = value;
},
);
const filterButtonsByPermission = (buttons) => {
return buttons.filter((button) => {

View File

@@ -5,6 +5,40 @@ import { describe, expect, it, vi } from 'vitest';
import PageData from './PageData.vue';
describe('page data recovery', () => {
it('loads the restored page and query without requesting the first page', async () => {
const get = vi
.fn()
.mockResolvedValue({ data: { records: [], totalRow: 30 } });
const wrapper = mount(PageData, {
global: {
directives: { loading: {} },
},
props: {
initialPageNumber: 3,
initialQueryParams: { categoryId: '7', title: '月报' },
pageSize: 18,
pageUrl: '/page',
requestClient: { get },
},
});
await flushPromises();
expect(get).toHaveBeenCalledTimes(1);
expect(get).toHaveBeenCalledWith('/page', {
params: {
categoryId: '7',
pageNumber: 3,
pageSize: 18,
title: '月报',
},
});
expect((wrapper.vm as any).getPageState()).toEqual({
pageNumber: 3,
pageSize: 18,
});
});
it('shows a retry action after a page request fails', async () => {
const get = vi
.fn()

View File

@@ -13,27 +13,38 @@ interface PageDataProps {
pageSize?: number;
pageSizes?: number[];
extraQueryParams?: Record<string, any>;
initialPageNumber?: number;
initialQueryParams?: Record<string, any>;
requestClient?: any;
}
type PageDataRow = Record<string, any>;
interface PageDataState {
pageNumber: number;
pageSize: number;
}
const props = withDefaults(defineProps<PageDataProps>(), {
pageSize: 10,
pageSizes: () => [10, 20, 50, 100],
extraQueryParams: () => ({}),
initialPageNumber: 1,
initialQueryParams: () => ({}),
requestClient: () => api,
});
const emit = defineEmits<{
(e: 'stateChange', state: PageDataState): void;
}>();
// 响应式数据
const pageList = ref<PageDataRow[]>([]);
const loading = ref(false);
const loadError = ref<unknown>();
const queryParams = ref<Record<string, any>>({});
const queryParams = ref<Record<string, any>>({ ...props.initialQueryParams });
let pageRequest = 0;
const pageInfo = reactive({
pageNumber: 1,
pageNumber: Math.max(1, Math.trunc(props.initialPageNumber)),
pageSize: props.pageSize,
total: 0,
});
@@ -80,10 +91,21 @@ const getPageList = async () => {
const handleSizeChange = (newSize: number) => {
pageInfo.pageSize = newSize;
pageInfo.pageNumber = 1; // 重置到第一页
emitPageState();
};
const handleCurrentChange = (newPage: number) => {
pageInfo.pageNumber = newPage;
emitPageState();
};
const getPageState = (): PageDataState => ({
pageNumber: pageInfo.pageNumber,
pageSize: pageInfo.pageSize,
});
const emitPageState = () => {
emit('stateChange', getPageState());
};
const patchRowById = (
@@ -110,10 +132,12 @@ const setQuery = (newQueryParams: Record<string, any>) => {
pageInfo.pageNumber = 1;
pageInfo.pageSize = props.pageSize;
queryParams.value = newQueryParams;
emitPageState();
};
// 暴露方法给父组件
defineExpose({
getPageState,
reload: getPageList,
patchRowById,
setQuery,
@@ -130,6 +154,7 @@ watch(
// 生命周期
onMounted(() => {
emitPageState();
getPageList();
});
</script>