| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- import React, { useMemo } from 'react';
- import { Button, Flex, message, Modal } from 'antd';
- import { useSelector } from 'react-redux';
- import { RootState, useAppDispatch } from '@/states/store';
- import {
- selectGridLayout,
- selectSelectedViewers,
- } from '@/states/view/viewerContainerSlice';
- import {
- judgeImageThunk,
- saveImageAsThunk
- } from '@/states/exam/bodyPositionListSlice';
- import { getDcmImageUrl } from '@/API/bodyPosition';
- import Icon from '@/components/Icon';
- import { useButtonAvailability } from '@/utils/useButtonAvailability';
- /**
- * 图像状态控制组件
- *
- * 功能:
- * - 拒绝按钮:将图像标记为拒绝状态
- * - 恢复按钮:将已拒绝的图像恢复为接受状态
- * - 另存为按钮:预留功能(当前禁用)
- *
- * 业务规则:
- * - 仅在单分格模式(1x1)下显示拒绝/恢复按钮
- * - 拒绝和恢复按钮互斥显示,基于 judged_status
- * - 另存为按钮始终可见但禁用
- */
- const ImageStateControl: React.FC = () => {
- const dispatch = useAppDispatch();
- const { disabled:ofReject } = useButtonAvailability('拒绝');
- const { disabled:ofRecover } = useButtonAvailability('恢复');
- const { disabled:ofSaveAs } = useButtonAvailability('另存为');
- // 获取必要的状态
- const selectedViewers = useSelector(selectSelectedViewers);
- const gridLayout = useSelector(selectGridLayout);
- const bodyPositionList = useSelector(
- (state: RootState) => state.bodyPositionList.bodyPositions
- );
- const loading = useSelector(
- (state: RootState) => state.bodyPositionList.loading
- );
- // 查找当前选中的图像
- const selectedImage = useMemo(() => {
- if (selectedViewers.length === 0) return null;
- const imageUrl = selectedViewers[0];
- return bodyPositionList.find(
- (bp) => getDcmImageUrl(bp.sop_instance_uid) === imageUrl
- );
- }, [selectedViewers, bodyPositionList]);
- // 判断按钮可见性
- const isSingleGrid = gridLayout === '1x1';
- const judgedStatus = selectedImage?.dview?.judged_status || '';
- const showRejectButton = isSingleGrid && judgedStatus !== 'Reject';
- const showRestoreButton = isSingleGrid && judgedStatus === 'Reject';
- // 拒绝按钮处理函数
- const handleReject = async () => {
- if (!selectedImage) return;
- Modal.confirm({
- title: '确认拒绝',
- content: `确定要拒绝选中的图像吗?`,
- okText: '确认拒绝',
- cancelText: '取消',
- okButtonProps: {
- danger: true,
- 'data-testid': 'modal-confirm-delete'
- },
- cancelButtonProps: {
- 'data-testid': 'modal-cancel-delete'
- },
- centered: true,
- onOk: async () => {
- try {
- await dispatch(
- judgeImageThunk({
- sopInstanceUid: selectedImage.sop_instance_uid,
- accept: false,
- })
- ).unwrap();
- message.success('图像已拒绝');
- } catch (err) {
- console.error('拒绝图像失败:', err);
- message.error('拒绝图像失败');
- }
- },
- });
- };
- // 恢复按钮处理函数
- const handleRestore = async () => {
- if (!selectedImage) return;
- try {
- await dispatch(
- judgeImageThunk({
- sopInstanceUid: selectedImage.sop_instance_uid,
- accept: true,
- })
- ).unwrap();
- message.success('图像已恢复');
- } catch (err) {
- console.error('恢复图像失败:', err);
- message.error('恢复图像失败');
- }
- };
- // 另存为按钮处理函数
- const handleSaveAs = async () => {
- if (!selectedImage) return;
- Modal.confirm({
- title: '确认另存为',
- content: `确定要复制选中的图像吗?`,
- okText: '确认',
- cancelText: '取消',
- centered: true,
- onOk: async () => {
- try {
- await dispatch(
- saveImageAsThunk({
- sopInstanceUid: selectedImage.sop_instance_uid,
- studyId: selectedImage.study_id || '',
- })
- ).unwrap();
- message.success('图像另存为成功,体位列表已更新');
- } catch (err) {
- console.error('图像另存为失败:', err);
- message.error('图像另存为失败');
- }
- },
- });
- };
- // 另存为按钮显示条件:单分格 + 有选中图像 + 图像已曝光
- const showSaveAsButton =
- isSingleGrid &&
- selectedImage !== null &&
- selectedImage?.dview?.expose_status === 'Exposed';
- return (
- <Flex gap="small" align="center" justify="start">
- {showRejectButton && (
- <Button
- onClick={handleReject}
- loading={loading}
- icon={
- <Icon
- module="module-process"
- name="RejectImage"
- userId="base"
- theme="default"
- size="2x"
- state="normal"
- />
- }
- style={{
- width: '1.5rem',
- height: '1.5rem',
- padding: 0,
- }}
- disabled={ofReject}
- title="拒绝"
- />
- )}
- {showRestoreButton && (
- <Button
- onClick={handleRestore}
- loading={loading}
- icon={
- <Icon
- module="module-process"
- name="RestoreImage"
- userId="base"
- theme="default"
- size="2x"
- state="normal"
- />
- }
- style={{
- width: '1.5rem',
- height: '1.5rem',
- padding: 0,
- }}
- title="恢复"
- disabled={ofRecover}
- />
- )}
- {showSaveAsButton && (
- <Button
- onClick={handleSaveAs}
- loading={loading}
- icon={
- <Icon
- module="module-process"
- name="SaveAs"
- userId="base"
- theme="default"
- size="2x"
- state="normal"
- />
- }
- style={{
- width: '1.5rem',
- height: '1.5rem',
- padding: 0,
- }}
- title="另存为"
- disabled={ofSaveAs}
- />
- )}
- </Flex>
- );
- };
- export default ImageStateControl;
|