printSlice.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import { createSlice, PayloadAction } from '@reduxjs/toolkit';
  2. export type FilmLayout = '1x1' | '1x2' | '2x1' | '2x2';
  3. export type FilmOrientation = 'horizontal' | 'vertical';
  4. interface Film {
  5. id: string;
  6. layout: FilmLayout;
  7. orientation: FilmOrientation;
  8. images: (string | null)[]; // 图像ID或null(空格子)
  9. }
  10. interface PrintState {
  11. films: Film[];
  12. activeFilmId: string;
  13. selectedImageIndex: number | null; // 当前选中的图像在格子中的索引
  14. }
  15. const initialFilm: Film = {
  16. id: '1',
  17. layout: '1x1',
  18. orientation: 'vertical',
  19. /**
  20. * 存储每个成员本质上是个sop instance uid
  21. */
  22. images: [null], // 1x1只有一个格子
  23. };
  24. const initialState: PrintState = {
  25. films: [initialFilm],
  26. activeFilmId: '1',
  27. selectedImageIndex: null,
  28. };
  29. const printSlice = createSlice({
  30. name: 'print',
  31. initialState,
  32. reducers: {
  33. // 添加新胶片
  34. addFilm: (state) => {
  35. const newId = String(state.films.length + 1);
  36. const newFilm: Film = {
  37. id: newId,
  38. layout: '1x1',
  39. orientation: 'vertical',
  40. images: [null],
  41. };
  42. state.films.push(newFilm);
  43. state.activeFilmId = newId;
  44. },
  45. // 删除胶片
  46. deleteFilm: (state, action: PayloadAction<string>) => {
  47. if (state.films.length <= 1) {
  48. // 至少保留一个胶片
  49. return;
  50. }
  51. state.films = state.films.filter((film) => film.id !== action.payload);
  52. // 如果删除的是当前胶片,切换到第一个
  53. if (state.activeFilmId === action.payload) {
  54. state.activeFilmId = state.films[0].id;
  55. }
  56. },
  57. // 切换当前胶片
  58. setActiveFilm: (state, action: PayloadAction<string>) => {
  59. state.activeFilmId = action.payload;
  60. state.selectedImageIndex = null; // 切换胶片时清除选中
  61. },
  62. // 设置胶片布局
  63. setFilmLayout: (state, action: PayloadAction<FilmLayout>) => {
  64. const film = state.films.find((f) => f.id === state.activeFilmId);
  65. if (!film) return;
  66. film.layout = action.payload;
  67. // 根据布局调整images数组大小
  68. const layoutSizes = {
  69. '1x1': 1,
  70. '1x2': 2,
  71. '2x1': 2,
  72. '2x2': 4,
  73. };
  74. const newSize = layoutSizes[action.payload];
  75. // 保留现有图像,补充或裁剪
  76. if (film.images.length < newSize) {
  77. film.images = [...film.images, ...Array(newSize - film.images.length).fill(null)];
  78. } else {
  79. film.images = film.images.slice(0, newSize);
  80. }
  81. },
  82. // 切换胶片方向
  83. toggleFilmOrientation: (state) => {
  84. const film = state.films.find((f) => f.id === state.activeFilmId);
  85. if (!film) return;
  86. film.orientation = film.orientation === 'horizontal' ? 'vertical' : 'horizontal';
  87. },
  88. // 设置选中的图像格子
  89. setSelectedImageIndex: (state, action: PayloadAction<number | null>) => {
  90. state.selectedImageIndex = action.payload;
  91. },
  92. // 删除选中的图像
  93. deleteSelectedImage: (state) => {
  94. if (state.selectedImageIndex === null) return;
  95. const film = state.films.find((f) => f.id === state.activeFilmId);
  96. if (!film) return;
  97. film.images[state.selectedImageIndex] = null;
  98. state.selectedImageIndex = null;
  99. },
  100. // 添加图像到指定格子
  101. addImageToCell: (state, action: PayloadAction<{ index: number; imageId: string }>) => {
  102. const film = state.films.find((f) => f.id === state.activeFilmId);
  103. if (!film) return;
  104. film.images[action.payload.index] = action.payload.imageId;
  105. },
  106. },
  107. });
  108. export const {
  109. addFilm,
  110. deleteFilm,
  111. setActiveFilm,
  112. setFilmLayout,
  113. toggleFilmOrientation,
  114. setSelectedImageIndex,
  115. deleteSelectedImage,
  116. addImageToCell,
  117. } = printSlice.actions;
  118. export default printSlice.reducer;