LOADING

加载过慢请开启缓存 浏览器默认开启

springboot后端重点

springboot后端重点

axio封装

//定制请求的实例
// import { globals } from "@/main";
//导入axios  npm install axios
import axios from 'axios';


import { ElMessage } from 'element-plus'
//定义一个变量,记录公共的前缀  ,  baseURL
const baseURL = '/api';
const instance = axios.create({ baseURL })

import { useTokenStore } from '@/stores/token.js'
//添加 Axios 请求拦截器 ,用于在请求发送之前执行某些操作
instance.interceptors.request.use(
    (config) => {
        // 第一个参数是一个回调函数,它在请求发送之前被调用。这个函数接受一个 config 对象作为参数,这个对象包含了请求的所有配置。
        //请求前的回调
        //添加token
        const tokenStore = useTokenStore();
        // 检查 tokenStore 是否存在 token。
        if (tokenStore.token) {
            // 如果存在 token,就将它添加到请求头的 Authorization 字段中。这通常用于 API 身份验证。
            config.headers.Authorization = tokenStore.token
        }
        return config;
        // 修改后的配置被返回给 Axios,随后请求将继续进行。
    },
    (err) => {
        //请求错误的回调
        // 如果请求配置过程中发生了错误,它会将错误通过 Promise.reject(err) 传递出去,以便后续的错误处理可以捕获到这个错误。
        Promise.reject(err)
    }
)
/*
这段代码的主要目的是在每次发送请求之前,检查用户是否已经登录(通过 token),如果是,就将 token 添加到请求头中,
以便进行身份验证。当请求发生错误时,也会正常处理错误。这种做法常见于需要认证的 API 请求场景。
*/


/* import {useRouter} from 'vue-router'
const router = useRouter(); */

import router from '@/router'  // '@/router' 将自动导入 `router/index.js` 中的默认导出 
//添加 Axios 的响应拦截器,可以在接收到服务器响应后执行某些操作。
instance.interceptors.response.use(
    result => {
        // 判断业务状态码
        // 如果业务逻辑中的状态码为 0,表示请求成功,返回 result.data
        if (result.data.code === 0) {
            return result.data;
        }

        //操作失败
        //alert(result.data.msg?result.data.msg:'服务异常')
        ElMessage.error(result.data.msg ? result.data.msg : '服务异常')
        //异步操作的状态转换为失败
        return Promise.reject(result.data)

    },
    err => {
        //判断响应状态码,如果为401,则证明未登录,提示请登录,并跳转到登录页面
        if (err.response.status === 401) {
            ElMessage.error('请先登录')
            router.push('/login')
        } else {
            ElMessage.error('服务异常')
        }

        return Promise.reject(err);//异步的状态转化成失败的状态
    }
)

export default instance;

文件上传功能实现

@RestController
public class FileUploadController {

    @Autowired
    private UploadedFilesService uploadedFilesService;


    @Value("${file.upload-dir}")
    private String uploadDir;

    @Value("${python.interpreter}")
    private String pythonInterpreter;

}

uploadurlbyid

FileUploadController

    @PostMapping("/uploadurlbyid")
 public Result<String> uploadtest(@RequestParam("file") MultipartFile file, @RequestParam Integer id) {
        // 检查文件是否为空
        if (file.isEmpty()) {
            return Result.error("File is empty. Please upload a valid file.");
        }

        // 获取并检查文件名
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null || !originalFilename.toLowerCase().endsWith(".nii")) {
            return Result.error("Invalid file type. Please upload a file with .nii extension.");
        }

        // 安全文件名生成
        String safeFileName = UUID.randomUUID().toString() + ".nii"; // 生成唯一文件名
        String filePath = uploadDir + safeFileName;

        try {
            // 确保上传目录存在
            Files.createDirectories(Paths.get(uploadDir));

            // 保存上传的NII文件
            file.transferTo(new File(filePath));

            // 执行 Python 脚本并处理输出
            String sliceFilePath = executePythonScript(filePath);
            if (sliceFilePath == null) {
                return Result.error("Failed to execute Python script.");
            }

            // 将 JPG 文件以流的形式上传到云端
            String uploadedUrl = uploadSliceFile(sliceFilePath);

            // 保存上传链接到数据库或做其他处理
            uploadedFilesService.addFileAndUrlById(id, originalFilename, filePath, uploadedUrl);

            return Result.success(uploadedUrl);
        } catch (IOException e) {
            return Result.error("Failed to upload file: " + e.getMessage());
        }
    }

    private String executePythonScript(String filePath) {
        try {
            String pythonScriptPath = "script/extract_slice.py"; // 替换为你的脚本路径
            ProcessBuilder processBuilder = new ProcessBuilder(pythonInterpreter, pythonScriptPath, filePath);
            processBuilder.redirectErrorStream(true); // 合并错误与正常输出流
            Process process = processBuilder.start();

            // 读取脚本输出
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    System.out.println(line); // 打印输出日志
                }
            }

            // 等待脚本执行完成并检查退出代码
            int exitCode = process.waitFor();
            if (exitCode != 0) {
                throw new IOException("Python script error: exit code " + exitCode);
            }

            // 提取的 JPG 文件路径
            return filePath.replace(".nii", "_middle_slice.jpg");
        } catch (IOException | InterruptedException e) {
            System.out.println("Error executing Python script: ");
            return null;
        }
    }

    private String uploadSliceFile(String sliceFilePath) throws IOException {

        // 将 JPG 文件以流的形式上传到云端
        try (FileInputStream fis = new FileInputStream(sliceFilePath)) {
            String objectName = sliceFilePath.substring(sliceFilePath.lastIndexOf("\\") + 1);
            return AliOssUtil.uploadFile(objectName, fis);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

UploadedFilesServiceImpl

@Service
public class UploadedFilesServiceImpl implements UploadedFilesService {
    @Override
    public void addFileAndUrlById(Integer associatedId, String fileName, String filePath, String uploadedUrl) {
        uploadedFilesMapper.insertFileAndUrl(associatedId, fileName, filePath, uploadedUrl);
    }
}

UploadedFilesMapper

@Mapper
public interface UploadedFilesMapper {

    @Insert("INSERT INTO uploaded_files (associated_id, file_name, url, file_path) " +
            "VALUES (#{associatedId}, #{fileName}, #{uploadedUrl}, #{filePath})")
    void insertFileAndUrl(Integer associatedId, String fileName, String filePath, String uploadedUrl);

}

vue

<el-upload
 ref="dialogUploadRef"
 :action="`/api/uploadurlbyid?id=${userInfo.id}`"
 :headers="{'Authorization': tokenStore.token}"
 drag
 list-type="picture-card"
>

getImage

FileUploadController

@GetMapping("/getImage")
    public Result<List<String>> getImageUrls(@RequestParam Integer id) throws Exception {
        String filePath = uploadedFilesService.getniipathById(id);
        List<String> urls = new ArrayList<>();

        try {
            // 调用Python脚本
            String pythonScriptPath = "script/segimage.py"; // 替换为你的脚本路径
            ProcessBuilder processBuilder = new ProcessBuilder(pythonInterpreter, pythonScriptPath, filePath);

            processBuilder.redirectErrorStream(true); // 将错误流合并到输入流中
            Process process = processBuilder.start();

            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line); // 打印输出
            }

            // 等待脚本执行完成
            int exitCode = process.waitFor();
            if (exitCode != 0) {
                throw new IOException("Python script error: " + exitCode);
            }

            // 处理生成的JPG文件
            String sliceFilePath = filePath.replace(".nii", "_slice.jpg");
            for (int i = 0; i < 10; i++) {
                String newsliceFilePath = sliceFilePath.replace(".jpg", "_" + String.valueOf(i) + ".jpg");

                // 将 JPG 文件以流的形式上传到云端
                try (FileInputStream fis = new FileInputStream(newsliceFilePath)) {
                    // 使用文件名作为对象名
                    String objectName = newsliceFilePath.substring(newsliceFilePath.lastIndexOf("\\") + 1);
                    String uploadedUrl = AliOssUtil.uploadFile(objectName, fis);
                    urls.add(uploadedUrl);
                }
            }
            return Result.success(urls);
        } catch (IOException | InterruptedException e) {
            return Result.error("Failed to upload file: " + e.getMessage());
        }
    }

UploadedFilesServiceImpl

@Service
public class UploadedFilesServiceImpl implements UploadedFilesService {

    @Override
    public String getniipathById(Integer id) {
        return uploadedFilesMapper.getniipathById(id);
    }  

}

UploadedFilesMapper

@Mapper
public interface UploadedFilesMapper {

    @Select("SELECT file_path FROM uploaded_files WHERE id = #{id}")
    String getniipathById(@Param("id") Integer id);

}

@/api/upload.js

export const ImagesService = (imgId) => {
    const params = new URLSearchParams(imgId).toString();
    return request.get(`/getImage?${params}`);
};

@/stores/images.js

const fetchImages = async (imageId) => {
    images.value = [];
    const Id = {
        id: imageId
    };
    try {
        const response = await ImagesService(Id);
        console.log('API Response:', response);  // 调试输出
        if (response.code === 0) {  // 确保响应成功
            const imageUrls = response.data;
            imageUrls.forEach(url => {
                addImage(url);
            });
            console.log('Fetched Infos:', imageList.value);  // 调试输出
        } else {
            console.error('Error fetching images:', response.message);
        }
    } catch (error) {
        console.error('Error fetching images:', error);
    }
};

patientfiles

FileUploadController

    @GetMapping("/patientfiles")
    public Result<List<UploadedFile>> getPatientFilesById(@RequestParam Integer id) {
        if (id == null) {
            return Result.error("ID cannot be null or empty");
        }

        try {
            return Result.success(uploadedFilesService.getPatientFilesById(id));
        } catch (Exception e) {
            return Result.error("Failed to get patients files: " + e.getMessage());
        }
    }

UploadedFilesServiceImpl

@Service
public class UploadedFilesServiceImpl implements UploadedFilesService {

    @Override
    public List<UploadedFile> getPatientFilesById(Integer id) {
        return uploadedFilesMapper.getFilesById(id);
    }

}

UploadedFilesMapper

@Mapper
public interface UploadedFilesMapper {

    @Select("SELECT * FROM uploaded_files WHERE associated_id = #{id}")
    List<UploadedFile> getFilesById(Integer id);

}

@/api/upload.js

//获取用户详细信息
export const filesNameService = (patientId) => {
    // 将 patientId 对象转化为查询参数字符串
    const params = new URLSearchParams(patientId).toString();
    return request.get(`/patientfiles?${params}`);
}

@/stores/files.js

const fetchInfos = async (userid) => {
    const Id = {
        id: userid
    };
    console.log("ID:", Id);
    try {
        const response = await filesNameService(Id);
        console.log('API Response:', response)  // 调试输出
        if (response.code === 0) {
            infos.value = response.data
            console.log(response.data);
        } else {
            console.error('Error fetching files:', response.message);
        }
    } catch (error) {
        console.error('Error fetching filesName:');
    }
}

delete

FileUploadController

    @DeleteMapping("/delete")
    public Result<String> deleteFile(@RequestBody Map<String, Integer> params) {
        Integer fileId = params.get("fileId");

        try {
            // 获取文件信息
            UploadedFile file = uploadedFilesService.getFileById(fileId);
            if (file == null) {
                return Result.error("File not found");
            }

            uploadedFilesService.deleteFile(fileId);
            boolean isDeleted = deleteFileWithPython(file.getFilePath());
            if (!isDeleted) {
                return Result.error("Failed to delete file from disk");
            }

            return Result.success("File deleted successfully");
        } catch (Exception e) {
            return Result.error("Failed to delete file: " + e.getMessage());
        }
    }

    private boolean deleteFileWithPython(String filePath) {
        try {
            ProcessBuilder pb = new ProcessBuilder("python", "script/delete_file.py", filePath);
            Process process = pb.start();
            int exitCode = process.waitFor();
            return exitCode == 0;
        } catch (Exception e) {
            return false;
        }
    }

UploadedFilesServiceImpl

@Service
public class UploadedFilesServiceImpl implements UploadedFilesService {

    @Override
    public void deleteFile(Integer fileId) {
        uploadedFilesMapper.deleteFile(fileId);
    }

}

UploadedFilesMapper

@Mapper
public interface UploadedFilesMapper {

    @Delete("DELETE FROM uploaded_files WHERE id = #{fileId}")
    void deleteFile(Integer fileId);

}

@/api/upload.js

export const deleteFileService = (data) => {
    return request.delete("/delete", {
        data: data
    });
};

@\components\user.vue

const deleteItem = async (id, index) => {
  const data = {
    fileId: id
  };

  try {
    const result = await deleteFileService(data);
    if (result.code === 0) {
      imagesresult.value.splice(index, 1);
      console.log(result.message);
    } else {
      console.error('Error deleting file:', result.message);
    }
  } catch (error) {
    console.error('Error deleting file:', error);
  }
  getFilesName();
};

patientdetails

DoctorPatientController

@RestController
@RequestMapping("/doctor-patients")
@Validated
public class DoctorPatientController {
    @Autowired
    private DoctorPatientService doctorPatientService;

    @GetMapping("/patientdetails")
    public Result<List<User>> getPatientDetailsByDoctorId() {
        return Result.success(doctorPatientService.getPatientDetailsByDoctorId());

}

DoctorPatientServiceImpl

@Service
public class DoctorPatientServiceImpl implements DoctorPatientService {
    public List<User> getPatientDetailsByDoctorId() {
        Map<String,Object> map = ThreadLocalUtil.get();
        Integer doctorId = (Integer) map.get("id");
        // 获取病人 ID 列表
        List<Integer> patientIds = doctorPatientMapper.findPatientIdsByDoctorId(doctorId);
        // 获取病人详细信息
        return userMapper.findUsersByIds(patientIds);
    }
}

DoctorPatientMapper

@Mapper
public interface DoctorPatientMapper {

    @Select("SELECT patient_id FROM doctor_patient WHERE doctor_id = #{doctorId}")
    List<Integer> findPatientIdsByDoctorId(@Param("doctorId") Integer doctorId);

}

UserMapper

@Mapper
public interface UserMapper {

    @Select("<-script->" +
            "SELECT * FROM user WHERE id IN " +
            "<-foreach item='id' collection='ids' open='(' separator=',' close=')'->" +
            "#{id}" +
            "<-/foreach->" +
            "<-/script->")
    List<User> findUsersByIds(@Param("ids") List<Integer> ids);

}