|
|
@@ -4,19 +4,19 @@
|
|
|
|
|
|
import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit';
|
|
|
import type { RootState } from '../store';
|
|
|
-import type {
|
|
|
- ProcessingStyle,
|
|
|
- LUTType,
|
|
|
- FullProcessingParams
|
|
|
+import type {
|
|
|
+ ProcessingStyle,
|
|
|
+ LUTType,
|
|
|
+ FullProcessingParams
|
|
|
} from '../../types/imageProcessing';
|
|
|
-import {
|
|
|
- PROCESSING_PRESETS,
|
|
|
- DEFAULT_ALGORITHM
|
|
|
+import {
|
|
|
+ PROCESSING_PRESETS,
|
|
|
+ DEFAULT_ALGORITHM
|
|
|
} from '../../domain/processingPresets';
|
|
|
import { DEFAULT_LUT } from '../../domain/lutConfig';
|
|
|
-import {
|
|
|
- getImageProcessingParams,
|
|
|
- saveImageProcessingParams
|
|
|
+import {
|
|
|
+ getImageProcessingParamsV2,
|
|
|
+ saveImageProcessingParams
|
|
|
} from '../../API/imageActions';
|
|
|
|
|
|
/**
|
|
|
@@ -25,28 +25,28 @@ import {
|
|
|
interface SliderAdjustmentPanelState {
|
|
|
// 当前图像ID
|
|
|
currentImageId: string | null;
|
|
|
-
|
|
|
+
|
|
|
// 当前参数值
|
|
|
parameters: FullProcessingParams;
|
|
|
-
|
|
|
+
|
|
|
// 当前选择的风格
|
|
|
selectedStyle: ProcessingStyle;
|
|
|
-
|
|
|
+
|
|
|
// 当前选择的算法(独立管理)
|
|
|
selectedAlgorithm: string;
|
|
|
-
|
|
|
+
|
|
|
// 当前选择的LUT(独立管理)
|
|
|
selectedLUT: LUTType;
|
|
|
-
|
|
|
+
|
|
|
// 是否正在加载
|
|
|
isLoading: boolean;
|
|
|
-
|
|
|
+
|
|
|
// 是否正在保存
|
|
|
isSaving: boolean;
|
|
|
-
|
|
|
+
|
|
|
// 初始加载标志(区分初始加载和用户操作)
|
|
|
isInitialLoad: boolean;
|
|
|
-
|
|
|
+
|
|
|
// 错误信息
|
|
|
error: string | null;
|
|
|
}
|
|
|
@@ -73,7 +73,7 @@ export const loadImageProcessingParams = createAsyncThunk(
|
|
|
'sliderAdjustmentPanel/loadParams',
|
|
|
async (sopInstanceUid: string, { rejectWithValue }) => {
|
|
|
try {
|
|
|
- const response = await getImageProcessingParams(sopInstanceUid);
|
|
|
+ const response = await getImageProcessingParamsV2(sopInstanceUid);
|
|
|
return {
|
|
|
sopInstanceUid,
|
|
|
params: response.data,
|
|
|
@@ -92,12 +92,12 @@ export const loadImageProcessingParams = createAsyncThunk(
|
|
|
export const saveProcessingParams = createAsyncThunk(
|
|
|
'sliderAdjustmentPanel/saveParams',
|
|
|
async (
|
|
|
- {
|
|
|
- sopInstanceUid,
|
|
|
- params
|
|
|
- }: {
|
|
|
- sopInstanceUid: string;
|
|
|
- params: { contrast: number; detail: number; latitude: number; noise: number }
|
|
|
+ {
|
|
|
+ sopInstanceUid,
|
|
|
+ params
|
|
|
+ }: {
|
|
|
+ sopInstanceUid: string;
|
|
|
+ params: { contrast: number; detail: number; latitude: number; noise: number }
|
|
|
},
|
|
|
{ rejectWithValue }
|
|
|
) => {
|
|
|
@@ -126,12 +126,12 @@ const sliderAdjustmentPanelSlice = createSlice({
|
|
|
state.currentImageId = action.payload;
|
|
|
state.isInitialLoad = true;
|
|
|
},
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 更新单个参数
|
|
|
*/
|
|
|
updateParameter: (
|
|
|
- state,
|
|
|
+ state,
|
|
|
action: PayloadAction<{ name: keyof FullProcessingParams; value: number }>
|
|
|
) => {
|
|
|
const { name, value } = action.payload;
|
|
|
@@ -139,7 +139,7 @@ const sliderAdjustmentPanelSlice = createSlice({
|
|
|
// 用户手动调整参数后,不再是初始加载状态
|
|
|
state.isInitialLoad = false;
|
|
|
},
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 应用风格预设
|
|
|
*/
|
|
|
@@ -150,7 +150,7 @@ const sliderAdjustmentPanelSlice = createSlice({
|
|
|
// 应用风格后,不再是初始加载状态
|
|
|
state.isInitialLoad = false;
|
|
|
},
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 重置为当前风格的默认值
|
|
|
*/
|
|
|
@@ -159,28 +159,28 @@ const sliderAdjustmentPanelSlice = createSlice({
|
|
|
state.parameters = { ...preset.params };
|
|
|
state.isInitialLoad = false;
|
|
|
},
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 设置算法
|
|
|
*/
|
|
|
setAlgorithm: (state, action: PayloadAction<string>) => {
|
|
|
state.selectedAlgorithm = action.payload;
|
|
|
},
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 设置LUT
|
|
|
*/
|
|
|
setLUT: (state, action: PayloadAction<LUTType>) => {
|
|
|
state.selectedLUT = action.payload;
|
|
|
},
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 清除错误
|
|
|
*/
|
|
|
clearError: (state) => {
|
|
|
state.error = null;
|
|
|
},
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 重置状态
|
|
|
*/
|
|
|
@@ -196,11 +196,14 @@ const sliderAdjustmentPanelSlice = createSlice({
|
|
|
.addCase(loadImageProcessingParams.fulfilled, (state, action) => {
|
|
|
state.isLoading = false;
|
|
|
state.currentImageId = action.payload.sopInstanceUid;
|
|
|
- // 只更新后端返回的4个参数,保持前端的 brightness 和 sharpness
|
|
|
+ // 更新所有6个参数,包括后端返回的 ww_coef 和 wl_coef
|
|
|
state.parameters.contrast = action.payload.params.contrast;
|
|
|
state.parameters.detail = action.payload.params.detail;
|
|
|
state.parameters.latitude = action.payload.params.latitude;
|
|
|
state.parameters.noise = action.payload.params.noise;
|
|
|
+ // 将 ww_coef 映射到 brightness,wl_coef 映射到 sharpness
|
|
|
+ state.parameters.brightness = action.payload.params.ww_coef;
|
|
|
+ state.parameters.sharpness = action.payload.params.wl_coef;
|
|
|
// 标记为初始加载,避免触发自动保存
|
|
|
state.isInitialLoad = true;
|
|
|
})
|
|
|
@@ -242,31 +245,31 @@ export const {
|
|
|
/**
|
|
|
* Selectors
|
|
|
*/
|
|
|
-export const selectCurrentImageId = (state: RootState) =>
|
|
|
+export const selectCurrentImageId = (state: RootState) =>
|
|
|
state.sliderAdjustmentPanel.currentImageId;
|
|
|
|
|
|
-export const selectParameters = (state: RootState) =>
|
|
|
+export const selectParameters = (state: RootState) =>
|
|
|
state.sliderAdjustmentPanel.parameters;
|
|
|
|
|
|
-export const selectSelectedStyle = (state: RootState) =>
|
|
|
+export const selectSelectedStyle = (state: RootState) =>
|
|
|
state.sliderAdjustmentPanel.selectedStyle;
|
|
|
|
|
|
-export const selectSelectedAlgorithm = (state: RootState) =>
|
|
|
+export const selectSelectedAlgorithm = (state: RootState) =>
|
|
|
state.sliderAdjustmentPanel.selectedAlgorithm;
|
|
|
|
|
|
-export const selectSelectedLUT = (state: RootState) =>
|
|
|
+export const selectSelectedLUT = (state: RootState) =>
|
|
|
state.sliderAdjustmentPanel.selectedLUT;
|
|
|
|
|
|
-export const selectIsLoading = (state: RootState) =>
|
|
|
+export const selectIsLoading = (state: RootState) =>
|
|
|
state.sliderAdjustmentPanel.isLoading;
|
|
|
|
|
|
-export const selectIsSaving = (state: RootState) =>
|
|
|
+export const selectIsSaving = (state: RootState) =>
|
|
|
state.sliderAdjustmentPanel.isSaving;
|
|
|
|
|
|
-export const selectIsInitialLoad = (state: RootState) =>
|
|
|
+export const selectIsInitialLoad = (state: RootState) =>
|
|
|
state.sliderAdjustmentPanel.isInitialLoad;
|
|
|
|
|
|
-export const selectError = (state: RootState) =>
|
|
|
+export const selectError = (state: RootState) =>
|
|
|
state.sliderAdjustmentPanel.error;
|
|
|
|
|
|
/**
|