#!D:/IDE/anaconda3/envs python
# -*- coding: UTF-8 -*-
"""
 @Author: Administrator
 @FileName：AppDBUtils.py\n
 @DateTime: 2025/6/24 13:16\n
 @Author  ：xsh
"""
from PyQt5 import Qt
from datetime import datetime, date
import numpy as np
import cv2
from AppCore.Levels                         import *
from AppUtils.AppConvert                    import AppConvert
from AppCore.AppDBModels.DBModels           import *
from AppCore.Levels import *
from AppSettings.AppSetting import AppSetting, AppConfig
class AppDBUtils:
    @staticmethod
    def quick_sort(case_list: list[SlideModelInterface], start: int, end: int):
        """快速排序"""
        if start >= end:  # 递归的退出条件
            return
        mid: SlideModelInterface = case_list[start]  # 设定起始的基准元素
        low = start  # low为序列左边在开始位置的由左向右移动的游标
        high = end  # high为序列右边末尾位置的由右向左移动的游标
        while low < high:
            # 如果low与high未重合，high(右边)指向的元素大于等于基准元素，则high向左移动
            while low < high and case_list[high].ImageScore >= mid.ImageScore:
                high -= 1
            case_list[low] = case_list[
                high]  # 走到此位置时high指向一个比基准元素小的元素,将high指向的元素放到low的位置上,此时high指向的位置空着,接下来移动low找到符合条件的元素放在此处
            # 如果low与high未重合，low指向的元素比基准元素小，则low向右移动
            while low < high and case_list[low].ImageScore < mid.ImageScore:
                low += 1
            case_list[high] = case_list[
                low]  # 此时low指向一个比基准元素大的元素,将low指向的元素放到high空着的位置上,此时low指向的位置空着,之后进行下一次循环,将high找到符合条件的元素填到此处

        # 退出循环后，low与high重合，此时所指位置为基准元素的正确位置,左边的元素都比基准元素小,右边的元素都比基准元素大
        case_list[low] = mid  # 将基准元素放到该位置,
        # 对基准元素左边的子序列进行快速排序
        AppDBUtils.quick_sort(case_list, start, low - 1)  # start :0  low -1 原基准元素靠左边一位
        # 对基准元素右边的子序列进行快速排序
        AppDBUtils.quick_sort(case_list, low + 1, end)  # low+1 : 原基准元素靠右一位  end: 最后

    @staticmethod
    def save_filename(self: SlideModelInterface) -> (str, str):

        codeString  : str
        Pos_X       : int
        Pos_Y       : int
        Pos_Z       : int
        Score       : int
        SpecimenNO  : str
        SlideNO     : str = None
        LineNO      : str = None

        if self.has_SpecimenNumber:
            SpecimenNO = f'{self.SpecimenNumber}'
        elif self.has_CodeString:
            SpecimenNO = f'{self.CodeString}'
        else:
            SpecimenNO = AppConvert.QDateToPath(Qt.QDate.currentDate(), '')
        if self.has_SlideNumber:
            SlideNO = f'slide{self.SlideNumber}'
        else:
            SlideNO = f'slide{self.ChamberRowNumber}'


        if not isinstance(SlideNO, str) or len(SlideNO) <= 0:
            SlideNO = f'slide{self.ChamberRowNumber}'

        savePath        : str
        path            : str
        separator_no    : str
        image_format    : str
        SpecimenPath    : str
        ImageScore      : int
        Pos_X           : int
        Pos_Y           : int
        Pos_Z           : int
        save_filename   : str
        _datetime       : str
        """设置保存路径"""
        """
        有线号:样本号/线号/玻片号
        有线号:样本号/玻片号
        """
        SpecimenPath = f'{SpecimenNO}/{SlideNO}/'

        """获取保存路径 和保存格式"""
        template        : ScanTemplate
        previewsettings : Previewsettings
        collectsettings : Collectsettings
        template, previewsettings, collectsettings = CustomScanningModel.template(chamber_number=self.ChamberGroupNumber, row_number=self.ChamberRowNumber)
        if template is None or previewsettings is None or collectsettings is None:
            return None, None
        separator_no = template.separator_no
        _datetime = AppConvert.QDateTimeMsecToPath(Qt.QDateTime.currentDateTime(), '')
        codeString = self.CodeString
        ImageScore = 0 if not self.hasImageScore else self.ImageScore

        Pos_X = 0 if not self.hasPosition else int(self.Position_X * 100)
        Pos_Y = 0 if not self.hasPosition else int(self.Position_Y * 100)
        Pos_Z = 0 if not self.hasPosition else int(self.Position_Z * 100)
        if not isinstance(codeString, str) or len(codeString) <= 0:
            codeString = f'{SpecimenNO}{separator_no}{SlideNO}'
        if ObjectiveLevel.isHigObjective(self.ObjectiveLevel):
            path = f'{collectsettings.save_address}'
            image_format = collectsettings.image_format
        else:
            path = f'{previewsettings.save_address}'
            image_format = previewsettings.image_format
        if ScanStatusLevel.isLowFocusing(self.Level):
            savePath = f'{AppConfig.PathConfig.getAbsoluteFocusing_SavePath(path, SpecimenPath)}/{self.RowNumber}-{self.ColNumber}/{self.Level}'
        elif ScanStatusLevel.isLowScanning(self.Level):
            if previewsettings.isMicronucleus():
                savePath = f'{AppConfig.PathConfig.getAbsoluteMicronucleus_SavePath(path, SpecimenPath)}/'
            else:
                savePath = f'{AppConfig.PathConfig.getAbsoluteScanning_SavePath(path, SpecimenPath)}/'
        elif ScanStatusLevel.isLowIdentificationCell(self.Level):
            savePath = f'{AppConfig.PathConfig.getAbsoluteCell_SavePath(path, SpecimenPath)}/'
        elif ScanStatusLevel.isHigFocusing(self.Level):
            savePath = f'{AppConfig.PathConfig.getCellFocusing_SavePath(path, SpecimenPath)}/Cell{self.ID}/{self.Level}/'
        elif ScanStatusLevel.isHigKaryotype(self.Level):
            if collectsettings.isAberration():
                savePath = f'{AppConfig.PathConfig.getAbsoluteAberration_SavePath(path, SpecimenPath)}/'
            elif collectsettings.isKaryotyping():
                savePath = f'{AppConfig.PathConfig.getAbsoluteKaryotype_SavePath(path, SpecimenPath)}/'
            elif collectsettings.isMicronucleus():
                savePath = f'{AppConfig.PathConfig.getAbsoluteMicronucleus_SavePath(path, SpecimenPath)}/'
            else:
                savePath = f'{AppConfig.PathConfig.getAbsoluteKaryotype_SavePath(path, SpecimenPath)}/'
        else:
            return None, None

        if self.hasPosition:
            if ScanStatusLevel.isLowIdentificationCell(self.Level):
                if self.ObjectiveLevel == ObjectiveLevel.Objective20 or self.ObjectiveLevel == ObjectiveLevel.Objective40:
                    if self.hasIndex:
                        filename = f'{codeString}{separator_no}{self.index}.{image_format}'
                    else:
                        filename = f'{codeString}{separator_no}{_datetime}.{image_format}'
                else:
                    filename = f'{self.ID}{separator_no}{self.RowNumber}{separator_no}{self.ColNumber}{separator_no}{Pos_X}{separator_no}{Pos_Y}{separator_no}{Pos_Z}.{image_format}'
            elif ScanStatusLevel.isLowScanning(self.Level):
                if self.ObjectiveLevel == ObjectiveLevel.Objective20 or self.ObjectiveLevel == ObjectiveLevel.Objective40:
                    if self.hasIndex:
                        filename = f'{codeString}{separator_no}{self.index}.{image_format}'
                    else:
                        filename = f'{codeString}{separator_no}{_datetime}.{image_format}'
                else:
                    if self.hasIndex:
                        filename = f'{codeString}{separator_no}{self.RowNumber}{separator_no}{self.ColNumber}{separator_no}{Pos_X}{separator_no}{Pos_Y}{separator_no}{Pos_Z}.{image_format}'
                    else:
                        filename = f'{codeString}{separator_no}{self.RowNumber}{separator_no}{self.ColNumber}{separator_no}{Pos_X}{separator_no}{Pos_Y}{separator_no}{Pos_Z}.{image_format}'

            elif ScanStatusLevel.isHigFocusing(self.Level):
                """保存文件名称 样本号 线号 玻片号  ID 评分"""
                if self.hasIndex:
                    filename = f'{codeString}{separator_no}{self.ID}{separator_no}{self.index}{separator_no}{ImageScore}.{image_format}'
                else:
                    filename = f'{codeString}{separator_no}{self.ID}{separator_no}{_datetime}{separator_no}{ImageScore}.{image_format}'
            elif ScanStatusLevel.isHigKaryotype(self.Level):
                filename = f'{codeString}{separator_no}{self.index}.{image_format}'

            else:
                filename = f'{Pos_X}{separator_no}{Pos_Y}{separator_no}{Pos_Z}{separator_no}{ImageScore}.{image_format}'
        else:
            if ScanStatusLevel.isLowIdentificationCell(self.Level):
                if self.ObjectiveLevel == ObjectiveLevel.Objective20 or self.ObjectiveLevel == ObjectiveLevel.Objective40:
                    if self.hasIndex:
                        filename = f'{codeString}{separator_no}{self.index}.{image_format}'
                    else:
                        filename = f'{codeString}{separator_no}{self.ID}.{image_format}'
                else:
                    filename = f'{self.ID}{separator_no}{self.RowNumber}{separator_no}{self.ColNumber}{_datetime}.{image_format}'
            elif ScanStatusLevel.isLowScanning(self.Level):
                if self.ObjectiveLevel == ObjectiveLevel.Objective20 or self.ObjectiveLevel == ObjectiveLevel.Objective40:
                    if self.hasIndex:
                        filename = f'{codeString}{separator_no}{self.index}.{image_format}'
                    else:
                        filename = f'{codeString}{separator_no}{self.ID}.{image_format}'
                else:
                    if self.hasIndex:
                        filename = f'{codeString}{separator_no}{self.index}.{image_format}'
                    else:
                        filename = f'{codeString}{separator_no}{_datetime}.{image_format}'

            elif ScanStatusLevel.isHigKaryotype(self.Level):
                filename = f'{codeString}{separator_no}{self.index}.{image_format}'
            else:
                filename = f'{_datetime}{separator_no}{ImageScore}.{image_format}'

        save_filename: str = f'{savePath}/{filename}'
        info: Qt.QFileInfo = Qt.QFileInfo(save_filename)
        return info.absoluteFilePath(), image_format.upper()

    @staticmethod
    def info_filename(self: SlideModelInterface) -> str:
        codeString  : str
        Pos_X       : int
        Pos_Y       : int
        Pos_Z       : int
        Score       : int
        SpecimenNO  : str
        SlideNO     : str = None
        LineNO      : str = None

        if self.has_SpecimenNumber:
            SpecimenNO = f'{self.SpecimenNumber}'
        elif self.has_CodeString:
            SpecimenNO = f'{self.CodeString}'
        else:
            SpecimenNO = AppConvert.QDateToPath(Qt.QDate.currentDate(), '')
        if self.has_SlideNumber:
            SlideNO = f'slide{self.SlideNumber}'
        else:
            SlideNO = f'slide{self.ChamberRowNumber}'

        if not isinstance(SlideNO, str) or len(SlideNO) <= 0:
            SlideNO = f'slide{self.ChamberRowNumber}'

        savePath        : str
        path            : str
        separator_no    : str
        image_format    : str
        SpecimenPath    : str
        ImageScore      : int
        Pos_X           : int
        Pos_Y           : int
        Pos_Z           : int
        save_filename   : str
        _datetime       : str
        """设置保存路径"""
        """
        有线号:样本号/线号/玻片号
        有线号:样本号/玻片号
        """
        SpecimenPath = f'{SpecimenNO}/{SlideNO}/'
        """获取保存路径 和保存格式"""
        template        : ScanTemplate
        previewsettings : Previewsettings
        collectsettings : Collectsettings
        template, previewsettings, collectsettings = CustomScanningModel.template(chamber_number=self.ChamberGroupNumber, row_number=self.ChamberRowNumber)
        if template is None or previewsettings is None or collectsettings is None:
            return None, None

        separator_no = template.separator_no
        _datetime = AppConvert.QDateTimeMsecToPath(Qt.QDateTime.currentDateTime(), '')
        codeString = self.CodeString
        if not isinstance(codeString, str) or len(codeString) <= 0:
            codeString = f'{SpecimenNO}{separator_no}{SlideNO}'
        if ObjectiveLevel.isLowObjective(self.ObjectiveLevel):
            path = f'{previewsettings.save_address}'

        else:
            path = f'{collectsettings.save_address}'

        image_format = AppConfig.PathConfig.Info_Format

        if ScanStatusLevel.isHigFocusing(self.Level):
            savePath = f'{AppConfig.PathConfig.getCellFocusing_SavePath(path, SpecimenPath)}/Cell{self.ID}/{self.Level}/'
        elif ScanStatusLevel.isHigKaryotype(self.Level):
            if collectsettings.isAberration():
                savePath = f'{AppConfig.PathConfig.getAbsoluteAberration_SavePath(path, SpecimenPath)}/'
            elif collectsettings.isKaryotyping():
                savePath = f'{AppConfig.PathConfig.getAbsoluteKaryotype_SavePath(path, SpecimenPath)}/'
            elif collectsettings.isMicronucleus():
                savePath = f'{AppConfig.PathConfig.getAbsoluteMicronucleus_SavePath(path, SpecimenPath)}/'
            else:
                savePath = f'{AppConfig.PathConfig.getAbsoluteKaryotype_SavePath(path, SpecimenPath)}/'
        elif ScanStatusLevel.isLowIdentificationCell(self.Level):
            if previewsettings.isAberration():
                savePath = f'{AppConfig.PathConfig.getAbsoluteAberration_SavePath(path, SpecimenPath)}/'
            elif previewsettings.isKaryotyping():
                savePath = f'{AppConfig.PathConfig.getAbsoluteKaryotype_SavePath(path, SpecimenPath)}/'
            elif previewsettings.isMicronucleus():
                savePath = f'{AppConfig.PathConfig.getAbsoluteMicronucleus_SavePath(path, SpecimenPath)}/'
            else:
                savePath = f'{AppConfig.PathConfig.getAbsoluteKaryotype_SavePath(path, SpecimenPath)}/'
        elif ScanStatusLevel.isLowScanning(self.Level):
            if previewsettings.isAberration():
                savePath = f'{AppConfig.PathConfig.getAbsoluteAberration_SavePath(path, SpecimenPath)}/'
            elif previewsettings.isKaryotyping():
                savePath = f'{AppConfig.PathConfig.getAbsoluteKaryotype_SavePath(path, SpecimenPath)}/'
            elif previewsettings.isMicronucleus():
                savePath = f'{AppConfig.PathConfig.getAbsoluteMicronucleus_SavePath(path, SpecimenPath)}/'
            else:
                savePath = f'{AppConfig.PathConfig.getAbsoluteKaryotype_SavePath(path, SpecimenPath)}/'
        else:
            return None, None
        if ScanStatusLevel.isHigFocusing(self.Level):
            if self.hasIndex:
                filename = f'{codeString}{separator_no}{self.index}{separator_no}{_datetime}.{image_format}'
            else:
                filename = f'{codeString}{separator_no}{self.ID   }{separator_no}{_datetime}.{image_format}'

        elif ScanStatusLevel.isHigKaryotype(self.Level):
            if self.hasIndex:
                filename = f'{codeString}{separator_no}{self.index}.{image_format}'
            else:
                filename = f'{codeString}{separator_no}{self.ID   }.{image_format}'
        elif ScanStatusLevel.isLowIdentificationCell(self.Level):
            if self.hasIndex:
                filename = f'{codeString}{separator_no}{self.index}.{image_format}'
            else:
                filename = f'{codeString}{separator_no}{self.ID}.{image_format}'
        elif ScanStatusLevel.isLowScanning(self.Level):
            if self.hasIndex:
                filename = f'{codeString}{separator_no}{self.index}.{image_format}'
            else:
                filename = f'{codeString}{separator_no}{self.ID}.{image_format}'
        else:
            return None, None
        save_filename: str = f'{savePath}/{filename}'
        info: Qt.QFileInfo = Qt.QFileInfo(save_filename)
        return info.absoluteFilePath(), image_format

    @staticmethod
    def text_filename(self: SlideModelInterface) -> str:
        savePath                : str
        path                    : str
        separator_no            : str
        image_format            : str
        SpecimenPath            : str
        ImageScore              : int
        """设置保存路径"""
        """
        有线号:样本号/线号/玻片号
        有线号:样本号/玻片号
        """
        # SpecimenPath = f'{SpecimenNO}/'
        """获取保存路径 和保存格式"""
        template        : ScanTemplate
        previewsettings : Previewsettings
        collectsettings : Collectsettings
        template, previewsettings, collectsettings = CustomScanningModel.template( chamber_number=self.ChamberGroupNumber, row_number=self.ChamberRowNumber)
        if template is None or previewsettings is None or collectsettings is None:
            return None, None

        # separator_no = template.separator_no
        _datetime = AppConvert.QDateTimeMsecToPath(Qt.QDateTime.currentDateTime(), '')
        # codeString = self.CodeString
        # if not isinstance(codeString, str) or len(codeString) <= 0:
        #     codeString = f'{SpecimenNO}{separator_no}{SlideNO}'
        if ObjectiveLevel.isLowObjective(self.ObjectiveLevel):
            path = f'{previewsettings.save_address}'
        else:
            path = f'{collectsettings.save_address}'
        image_format = 'txt'
        if previewsettings.isAberration():
            savePath = f'{AppConfig.PathConfig.getAbsoluteAberrationPath(path)}/'
        elif previewsettings.isKaryotyping():
            savePath = f'{AppConfig.PathConfig.getAbsoluteKaryotypePath(path)}/'
        elif previewsettings.isMicronucleus():
            savePath = f'{AppConfig.PathConfig.getAbsoluteMicronucleusPath(path)}/'
        else:
            savePath = f'{AppConfig.PathConfig.getAbsoluteKaryotypePath(path)}/'
        info: Qt.QFileInfo = Qt.QFileInfo(f'{savePath}/Specimen.{image_format}')
        return info.absoluteFilePath(), image_format

    @staticmethod
    def get_info_filename(self: dict[str, object]) -> str:
        codeString: str
        Pos_X: int
        Pos_Y: int
        Pos_Z: int
        Score: int
        SpecimenNO: str
        SlideNO: str = None
        LineNO: str = None
        if isinstance(self.get('SpecimenNumber', None), str):
            SpecimenNO = '{0}'.format(self['SpecimenNumber'])
        elif isinstance(self.get('CodeString', None), str):
            SpecimenNO = '{0}'.format(self['CodeString'])
        else:
            SpecimenNO = AppConvert.QDateToPath(Qt.QDate.currentDate(), '')
        if isinstance(self.get('SlideNumber', None), str):
            SlideNO = 'slide{0}'.format(self['SlideNumber'])
        else:
            SlideNO = 'slide{0}'.format(self['ChamberRowNumber'])
        if not isinstance(SlideNO, str) or len(SlideNO) <= 0:
            SlideNO = 'slide{0}'.format(self['ChamberRowNumber'])
        if not isinstance(SpecimenNO, str) or len(SpecimenNO) <= 0:
            return None, None
        image_format: str = 'yaml'
        savePath        : str
        path            : str
        separator_no    : str
        SpecimenPath    : str
        ImageScore      : int
        Pos_X           : int
        Pos_Y           : int
        Pos_Z           : int
        save_filename   : str
        _datetime       : str
        """设置保存路径"""
        """
        有线号:样本号/线号/玻片号
        有线号:样本号/玻片号
        """
        SpecimenPath = f'{SpecimenNO}/{SlideNO}/'
        ChamberNumber: int
        ChamberRowNumber: int
        if isinstance(self.get('ChamberNumber', None), int):
            ChamberNumber = self.get('ChamberNumber', None)
        else:
            return None, None
        if isinstance(self.get('ChamberRowNumber', None), int):
            ChamberRowNumber = self.get('ChamberRowNumber', None)
        else:
            return None, None
        template        : ScanTemplate
        previewsettings : Previewsettings
        collectsettings : Collectsettings
        template, previewsettings, collectsettings = CustomScanningModel.template(chamber_number=ChamberNumber, row_number=ChamberRowNumber)
        if template is None or previewsettings is None or collectsettings is None:
            return None, None

        """获取保存路径 和保存格式"""
        separator_no = template.separator_no
        _datetime = AppConvert.QDateTimeMsecToPath(Qt.QDateTime.currentDateTime(), '')
        codeString = self.get('CodeString', None)
        ImageScore = self.get('ImageScore', 0)
        hasPosition: bool = True
        if self.get('Position_X', None) is None:
            hasPosition = False
        elif self.get('Position_Y', None) is None:
            hasPosition = False
        elif self.get('Position_Z', None) is None:
            hasPosition = False
        hasIndex: bool = isinstance(self.get('Index', None), (int, float))
        Index = self.get('Index', 1)
        Pos_X = self.get('Position_X', 0) * 100
        Pos_Y = self.get('Position_Y', 0) * 100
        Pos_Z = self.get('Position_Z', 0) * 100
        if not isinstance(codeString, str) or len(codeString) <= 0:
            codeString = f'{SpecimenNO}{separator_no}{SlideNO}'
        Objective: int = self.get('ObjectiveLevel', ObjectiveLevel.Objective10)
        Level: int = self.get('Level', ScanStatusLevel.Default_Status)
        ColNumber: int = self.get('ColNumber', 1)
        RowNumber: int = self.get('RowNumber', 1)
        ID: int = self.get('ID', 1)
        if ObjectiveLevel.isLowObjective(Objective):
            path = f'{previewsettings.save_address}'
        else:
            path = f'{collectsettings.save_address}'
        if ScanStatusLevel.isLowFocusing(Level):
            savePath = f'{AppConfig.PathConfig.getAbsoluteFocusing_SavePath(path, SpecimenPath)}/{RowNumber}-{ColNumber}/{Level}'
        elif ScanStatusLevel.isLowScanning(Level):
            savePath = f'{AppConfig.PathConfig.getAbsoluteScanning_SavePath(path, SpecimenPath)}/'
        elif ScanStatusLevel.isHigFocusing(Level):
            savePath = f'{AppConfig.PathConfig.getCellFocusing_SavePath(path, SpecimenPath)}/Cell{ID}/{Level}/'
        elif ScanStatusLevel.isHigKaryotype(Level):
            if collectsettings.isAberration():
                savePath = f'{AppConfig.PathConfig.getAbsoluteAberration_SavePath(path, SpecimenPath)}/'
            elif collectsettings.isKaryotyping():
                savePath = f'{AppConfig.PathConfig.getAbsoluteKaryotype_SavePath(path, SpecimenPath)}/'
        elif ScanStatusLevel.isLowIdentificationCell(Level):
            savePath = f'{AppConfig.PathConfig.getAbsoluteCell_SavePath(path, SpecimenPath)}/{Level}'
        else:
            return None, None
        if hasPosition:
            if ScanStatusLevel.isLowIdentificationCell(Level):
                filename = f'{ID}{separator_no}{RowNumber}{separator_no}{ColNumber}{separator_no}{Pos_X}{separator_no}{Pos_Y}{separator_no}{Pos_Z}.{image_format}'
            elif ScanStatusLevel.isHigFocusing(Level):
                """保存文件名称 样本号 线号 玻片号  ID 评分"""
                if hasIndex:
                    filename = f'{codeString}{separator_no}{ID}{separator_no}{Index}{separator_no}{ImageScore}.{image_format}'
                else:
                    filename = f'{codeString}{separator_no}{ID}{separator_no}{ID}{separator_no}{ImageScore}.{image_format}'
            elif ScanStatusLevel.isHigKaryotype(Level):
                if hasIndex:
                    filename = f'{codeString}{separator_no}{Index}.{image_format}'
                else:
                    filename = f'{codeString}{separator_no}{AppConvert.DateTimeToString(Qt.QDateTime.currentDateTime())}.{image_format}'
            else:
                filename = f'{Pos_X}{separator_no}{Pos_Y}{separator_no}{Pos_Z}{separator_no}{ImageScore}.{image_format}'
        else:
            if ScanStatusLevel.isLowIdentificationCell(Level):
                filename = f'{ID}{separator_no}{RowNumber}{separator_no}{ColNumber}{_datetime}.{image_format}'
            elif ScanStatusLevel.isHigKaryotype(Level):
                if hasIndex:
                    filename = f'{codeString}{separator_no}{Index}.{image_format}'
                else:
                    filename = f'{codeString}{separator_no}{AppConvert.DateTimeToString(Qt.QDateTime.currentDateTime())}.{image_format}'
            else:
                filename = f'{_datetime}{separator_no}{ImageScore}.{image_format}'
        save_filename: str = f'{savePath}/{filename}'
        info: Qt.QFileInfo = Qt.QFileInfo(save_filename)
        if not info.dir().exists():
            info.dir().mkpath(info.absolutePath())
        return info.absoluteFilePath(), image_format

    @staticmethod
    def get_save_filename(self: dict[str, object]) -> str:
        savePath        : str
        path            : str
        separator_no    : str
        SpecimenPath    : str
        ImageScore      : int
        Pos_X           : int
        Pos_Y           : int
        Pos_Z           : int
        save_filename   : str
        _datetime       : str
        """设置保存路径"""
        """
        有线号:样本号/线号/玻片号
        有线号:样本号/玻片号
        """
        SlideNO: str = None
        LineNO: str = None
        if isinstance(self.get('SpecimenNumber', None), str):
            SpecimenNO = '{0}'.format(self['SpecimenNumber'])
        elif isinstance(self.get('CodeString', None), str):
            SpecimenNO = '{0}'.format(self['CodeString'])
        else:
            SpecimenNO = AppConvert.QDateToPath(Qt.QDate.currentDate(), '')
        if isinstance(self.get('SlideNumber', None), str):
            SlideNO = 'slide{0}'.format(self['SlideNumber'])
        else:
            SlideNO = 'slide{0}'.format(self['ChamberRowNumber'])
        if not isinstance(SlideNO, str) or len(SlideNO) <= 0:
            SlideNO = 'slide{0}'.format(self['ChamberRowNumber'])
        if not isinstance(SpecimenNO, str) or len(SpecimenNO) <= 0:
            return None, None

        SpecimenPath = f'{SpecimenNO}/{SlideNO}/'
        ChamberNumber: int
        ChamberRowNumber: int
        image_format: str
        if isinstance(self.get('ChamberNumber', None), int):
            ChamberNumber = self.get('ChamberNumber', None)
        else:
            return None, None
        if isinstance(self.get('ChamberRowNumber', None), int):
            ChamberRowNumber = self.get('ChamberRowNumber', None)
        else:
            return None, None
        template: ScanTemplate
        previewsettings: Previewsettings
        collectsettings: Collectsettings
        template, previewsettings, collectsettings = CustomScanningModel.template(chamber_number=ChamberNumber,
                                                                                  row_number=ChamberRowNumber)
        if template is None or previewsettings is None or collectsettings is None:
            return None, None
        """获取保存路径 和保存格式"""
        separator_no = template.separator_no
        _datetime = AppConvert.QDateTimeMsecToPath(Qt.QDateTime.currentDateTime(), '')
        codeString = self.get('CodeString', None)
        ImageScore = self.get('ImageScore', 0)
        hasPosition: bool = True
        if self.get('Position_X', None) is None:
            hasPosition = False
        elif self.get('Position_Y', None) is None:
            hasPosition = False
        elif self.get('Position_Z', None) is None:
            hasPosition = False
        hasIndex: bool = isinstance(self.get('Index', None), (int, float))
        Index = self.get('Index', 1)
        Pos_X = self.get('Position_X', 0) * 100
        Pos_Y = self.get('Position_Y', 0) * 100
        Pos_Z = self.get('Position_Z', 0) * 100
        if not isinstance(codeString, str) or len(codeString) <= 0:
            codeString = f'{SpecimenNO}{separator_no}{SlideNO}'
        Objective: int = self.get('ObjectiveLevel', ObjectiveLevel.Objective10)
        Level: int = self.get('Level', ScanStatusLevel.Default_Status)
        ColNumber: int = self.get('ColNumber', 1)
        RowNumber: int = self.get('RowNumber', 1)
        ID: int = self.get('ID', 1)
        if ObjectiveLevel.isLowObjective(Objective):
            path = f'{previewsettings.save_address}'
            image_format = previewsettings.image_format
        else:
            path = f'{collectsettings.save_address}'
            image_format = collectsettings.image_format
        if ScanStatusLevel.isLowFocusing(Level):
            savePath = f'{AppConfig.PathConfig.getAbsoluteFocusing_SavePath(path, SpecimenPath)}/{RowNumber}-{ColNumber}/{Level}'
        elif ScanStatusLevel.isLowScanning(Level):
            savePath = f'{AppConfig.PathConfig.getAbsoluteScanning_SavePath(path, SpecimenPath)}/'
        elif ScanStatusLevel.isHigFocusing(Level):
            savePath = f'{AppConfig.PathConfig.getCellFocusing_SavePath(path, SpecimenPath)}/Cell{ID}/{Level}/'
        elif ScanStatusLevel.isHigKaryotype(Level):
            savePath = f'{AppConfig.PathConfig.getAbsoluteKaryotype_SavePath(path, SpecimenPath)}/'
        elif ScanStatusLevel.isLowIdentificationCell(Level):
            savePath = f'{AppConfig.PathConfig.getAbsoluteCell_SavePath(path, SpecimenPath)}/{Level}'
        else:
            return None, None
        if hasPosition:
            if ScanStatusLevel.isLowIdentificationCell(Level):
                filename = f'{ID}{separator_no}{RowNumber}{separator_no}{ColNumber}{separator_no}{Pos_X}{separator_no}{Pos_Y}{separator_no}{Pos_Z}.{image_format}'
            elif ScanStatusLevel.isHigFocusing(Level):
                """保存文件名称 样本号 线号 玻片号  ID 评分"""
                if hasIndex:
                    filename = f'{codeString}{separator_no}{ID}{separator_no}{Index}{separator_no}{ImageScore}.{image_format}'
                else:
                    filename = f'{codeString}{separator_no}{ID}{separator_no}{ID}{separator_no}{ImageScore}.{image_format}'
            elif ScanStatusLevel.isHigKaryotype(Level):
                if hasIndex:
                    filename = f'{codeString}{separator_no}{Index}.{image_format}'
                else:
                    filename = f'{codeString}{separator_no}{AppConvert.DateTimeToString(Qt.QDateTime.currentDateTime())}.{image_format}'
            else:
                filename = f'{Pos_X}{separator_no}{Pos_Y}{separator_no}{Pos_Z}{separator_no}{ImageScore}.{image_format}'
        else:
            if ScanStatusLevel.isLowIdentificationCell(Level):
                filename = f'{ID}{separator_no}{RowNumber}{separator_no}{ColNumber}{_datetime}.{image_format}'
            elif ScanStatusLevel.isHigKaryotype(Level):
                if hasIndex:
                    filename = f'{codeString}{separator_no}{Index}.{image_format}'
                else:
                    filename = f'{codeString}{separator_no}{AppConvert.DateTimeToString(Qt.QDateTime.currentDateTime())}.{image_format}'
            else:
                filename = f'{_datetime}{separator_no}{ImageScore}.{image_format}'
        save_filename: str = f'{savePath}/{filename}'
        info: Qt.QFileInfo = Qt.QFileInfo(save_filename)
        if not info.dir().exists():
            info.dir().mkpath(info.absolutePath())
        return info.absoluteFilePath(), image_format.upper()