/*
 * *********************************************************************************************************************
 *
 *          !!
 *        .F88X
 *        X8888Y
 *      .}888888N;
 *        i888888N;        .:!              .I$WI:
 *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
 *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
 *            +888888N;  .8888888Y                                  "&&8Y.}8,
 *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
 *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
 *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
 *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
 *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
 *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
 *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
 *      .:R888888I
 *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
 *        ~8888'
 *        .!88~                                                                     All rights reserved.
 *
 * *********************************************************************************************************************
 */

@file:Suppress("IMPLICIT_CAST_TO_ANY")

package com.persagy.server.services.graphtype

import com.persagy.base.extensions.toJson
import com.persagy.database.SFilter
import com.persagy.mybatis.SMybatisDao
import com.persagy.server.Opt
import com.persagy.server.datacenter.models.entities.dictnew.DefFuncId
import com.persagy.server.datacenter.models.entities.graphtype.RelationTypeProject
import com.persagy.server.datacenter.models.entities.graphtype.rel.RelZoneSpace
import com.persagy.server.datacenter.models.entities.objects.Equipment
import com.persagy.server.mappers.IRelationExcelExportMapper
import com.persagy.server.mappers.IRelationExcelImportMapper
import com.persagy.server.services.base.RService
import com.persagy.server.services.objects.EquipmentService
import com.persagy.server.utils.IdUtils
import com.persagy.service.SObjectService
import com.persagy.service.SPageContext
import com.persagy.service.models.enums.SResponseType
import com.persagy.service.models.requests.SUpdateRequest
import com.persagy.service.models.responses.SBaseResponse
import com.persagy.service.utils.SSpringContextUtil
import org.apache.poi.ss.usermodel.CellType
import org.apache.poi.xssf.usermodel.XSSFSheet
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import org.slf4j.LoggerFactory
import org.springframework.web.multipart.MultipartFile
import java.io.File
import java.io.FileOutputStream
import java.io.OutputStream
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import javax.servlet.http.HttpServletResponse

/**
 * 查询总览
 *
 * @author  邓婷婷
 */
object RelationTypeProjectService : RService<RelationTypeProject>(SMybatisDao(RelationTypeProject::class.java))  {

    // 日志
    private val logger = LoggerFactory.getLogger(RelationTypeProjectService::class.java)

    /** 导出excel对应的Mapper */
    private val excelExport by lazy {
        SSpringContextUtil.getBean(IRelationExcelExportMapper::class.java) as IRelationExcelExportMapper
    }

    /** 导入excel对应的Mapper */
    private val excelImport by lazy {
        SSpringContextUtil.getBean(IRelationExcelImportMapper::class.java) as IRelationExcelImportMapper
    }

    /** 信息点 */
    private val dictDefFuncId = SObjectService(SMybatisDao(DefFuncId::class.java))

    private val spaceService = SObjectService(SMybatisDao(RelZoneSpace::class.java))

    private val codeColMap by lazy {
        val map = HashMap<String, String>()
        map["对象ID"] = "id"
        map["对象名称"] = "name"
        map["对象本地编码"] = "local_id"
        map["对象本地名称"] = "local_name"
        map
    }

    private val codeTableMap by lazy {
        val map = HashMap<String, String>()
        map["bd"] = "building"
        map["eq"] = "equipment"
        map["fl"] = "floor"
        map["pe"] = "property"
        map["pj"] = "project"
        map["sh"] = "shaft"
        map["sp"] = "zone_space_base"
        map["sy"] = "general_system"
        map["tn"] = "tenant"
        map
    }

    val itemList = arrayOf("_sbm", "abc", "name", "id", "local_id", "local_name", "object_type", "building_floor",
            "_sbm", "_abc", "_name", "_id", "_local_id", "_local_name","_object_type", "_building_floor")
    val itemListTwo = arrayOf( "id", "local_id", "local_name","category")

    /** 关系记录启始行 */
    private const val rowStart = 5
    /** 主对项ID所在列 */
    private const val id1Col = 3
    /** 从对项ID所在列 */
    private const val id2Col = 11

    /** 主对项识别码所在列 */
    private const val idCode1Col = 0
    /** 从对项识别码所在列 */
    private const val idCode2Col = 8

    /** 导入状态所在列 */
    private const val stateCol = 16

    /**
     * 下载模板
     * @param   response        应答体
     */
    fun templateDownloads(response: HttpServletResponse) {
        val workbook = XSSFWorkbook(RelationTypeProjectService::class.java.classLoader.getResourceAsStream("excel/relation-template.xlsx"))
        response.contentType = "application/octet-stream"
        response.setHeader("Content-disposition", "attachment;filename=relation-template.xlsx")
        response.flushBuffer()
        workbook.write(response.outputStream)
    } // Function templateDownloads()

    /**
     * 下载报告
     *
     * @param   response        应答体
     * @param   relType         关系类型
     * @param   zoneType        业务空间类型
     */
    fun reportDownloads(response: HttpServletResponse, projectId: String, relType: String, zoneType: String? = null) {
        val zone = if (zoneType != null) {
            "_${zoneType}"
        } else {
            ""
        }
//        val projectId = SPageContext.getHeader("projectId")
        val file = File("/tmp/relation-$projectId-${relType}${zone}.xlsx")
        val workbook = if (file.exists()) {
            XSSFWorkbook(file)
        } else {
            XSSFWorkbook(RelationTypeProjectService::class.java.classLoader.getResourceAsStream("excel/relation-template.xlsx"))
        }
        response.contentType = "application/octet-stream"
        response.setHeader("Content-disposition", "attachment;filename=report-${relType}${zone}.xlsx")
        response.flushBuffer()
        workbook.write(response.outputStream)
    } // Function templateDownloads()

    /**
     * 导出excel
     *
     * @param   response        应答体
     * @param   relType         关系类型
     * @param   code            识别码类型
     * @param   zoneType        业务空间类型
     */
    fun exportExcel(response: HttpServletResponse, projectId: String,relType: String, code: String = "对象ID", zoneType: String? = null) {
        val workbook = XSSFWorkbook(RelationTypeProjectService::class.java.classLoader.getResourceAsStream("excel/relation-template.xlsx"))
        response.contentType = "application/octet-stream"
        response.setHeader("Content-disposition", "attachment;filename=relation-$relType.xlsx")
        response.flushBuffer()

        val sheet = workbook.getSheet("关系维护")

//        val projectId = SPageContext.getHeader("projectId")

        try {
            writeExcelRelation(sheet, projectId, relType, code, zoneType)
        }catch (e: Exception) {
            // DO NOTHING
        }

        workbook.write(response.outputStream)
    } // Function exportExcel()

    /**
     * 向excel表中写关系
     *
     * @param   sheet           Excel Sheet
     * @param   projectId       项目ID
     * @param   relType         关系类型
     * @param   code            识别码类型
     * @param   zoneType        业务空间类型
     */
    @Suppress("UNCHECKED_CAST")
    private fun writeExcelRelation(sheet: XSSFSheet, projectId: String, relType: String, code: String, zoneType: String? = null) {
        try {
            val len = relType.indexOf("_")
            var cmd = if (len > 0) {
                relType.substring(0, len)
            } else {
                relType
            }
            val type = relType
//        val type = if (len > 0) {
//            relType.substring(len + 1)
//        } else {
//            ""
//        }
            logger.debug("type= ${relType}")
            val list = if (relType == "eq2bd" || relType == "pe2bd") {
                val exportMethod = excelExport.javaClass.getDeclaredMethod("${relType}In", String::class.java)
                exportMethod!!.invoke(excelExport, projectId) as List<HashMap<String, Any?>>
            } else if (relType == "eq2fl" || relType == "pe2fl") {
                val exportMethod = excelExport.javaClass.getDeclaredMethod("${relType}In", String::class.java)
                exportMethod!!.invoke(excelExport, projectId) as List<HashMap<String, Any?>>
            } else if (relType == "eq2bd_for"||relType == "eq2fl_for"||relType == "eq2sh_for"||relType =="sy2bd_for"||relType =="sy2fl_for"
                ||relType =="sy2sh_for"||relType =="sy2sp_for"){
                logger.debug("type= **************************************************************************************")
                val exportMethod = excelExport.javaClass.getDeclaredMethod("${relType}", String::class.java)
                exportMethod!!.invoke(excelExport, projectId) as List<HashMap<String, Any?>>
            } else
//                if (cmd == "bd2bd"){
//                val exportMethod = excelExport.javaClass.getDeclaredMethod(cmd, String::class.java, String::class.java)
//                exportMethod!!.invoke(excelExport, projectId, type) as List<HashMap<String, Any?>>
//            }else
            {
                if (relType == "eq2sp_SensorRelationship_ss2sp"){
                    cmd = "eq2spIn"
                }else if (relType == "sh2bd_ArchForArch") {
                    cmd = "sh2bdArchForArch"
                }else if (relType == "sh2fl_ArchForArch"){
                    cmd = "sh2flArchForArch"
                }else if (relType == "sh2sh_ArchForArch"){
                    cmd = "sh2shArchForArch"
                }else if (relType == "sh2sp_ArchForArch"){
                    cmd = "sh2spArchForArch"
                }else if (relType == "sp2bd_ArchForArch"){
                    cmd = "sp2bdArchForArch"
                }else if (relType == "sp2fl_ArchForArch"){
                    cmd = "sp2flArchForArch"
                }

                if(zoneType.isNullOrEmpty()) {
                    val exportMethod = excelExport.javaClass.getDeclaredMethod(cmd, String::class.java, String::class.java)
                    exportMethod!!.invoke(excelExport, projectId, type) as List<HashMap<String, Any?>>
                } else {
                    val exportMethod = excelExport.javaClass.getDeclaredMethod(cmd, String::class.java, String::class.java, String::class.java)
                    exportMethod!!.invoke(excelExport, projectId, type, zoneType) as List<HashMap<String, Any?>>
                }
            }
            var rowNum = rowStart
            logger.debug("数据长度= ${list.toJson()}   ****************************************************************")
            // 填写识别码对应
            sheet.getRow(2).getCell(1).setCellValue(code)

            for (it in list) {
                val row = sheet.createRow(rowNum)
                for ((i, item) in itemList.withIndex()) {
                    val cellValue = it[item]
                    if (item == "building_floor"){
                        val buildingName = it["building_name"]
                        val floorName = it["floor_name"]
                        if (buildingName!=null&&floorName!=null&&!buildingName.toString().isEmpty()&&!floorName.toString().isEmpty()){
                            val cells = row.createCell(i)
                            cells.setCellValue(buildingName.toString()+"-"+floorName.toString())
                        }else if (buildingName!=null&&!buildingName.toString().isEmpty()) {
                            val cells = row.createCell(i)
                            cells.setCellValue(buildingName.toString())
                        }

                    }else if(item == "_building_floor"){
                        val buildingName = it["_building_name"]
                        val floorName = it["_floor_name"]
                        if (buildingName!=null&&floorName!=null&&!buildingName.toString().isNullOrEmpty()&&!floorName.toString().isNullOrEmpty()){
                            val cells = row.createCell(i)
                            cells.setCellValue(buildingName.toString()+"-"+floorName.toString())
                        }else if (buildingName!=null&&!buildingName.toString().isNullOrEmpty()) {
                            val cells = row.createCell(i)
                            cells.setCellValue(buildingName.toString())
                        }
                    } else {
                        val cell = row.createCell(i)
                        if (cellValue != null) {
                            cell.setCellValue(cellValue.toString())
                        }
                    }
                    logger.debug("数据item= ${item?.toString()}")
                    logger.debug("数据= ${cellValue?.toString()}")


                }

                // 添加识别码
                row.createCell(0).setCellValue(row.getCell(id1Col).toString())
                row.createCell(8).setCellValue(row.getCell(id2Col).toString())
                rowNum++
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    } // Fun writeExcelRelation()

    /**
     * 导入excel
     *
     * @param   file            上传的Excel文件
     * @param   relType         关系类型
     * @param   zoneType        业务空间类型
     * @return  应答体
     */
    fun importExcel(file: MultipartFile, relType: String, zoneType: String? = null): SBaseResponse {
        try {
            if (file.isEmpty) {
                throw Exception("未选择文件")
            }

            val zone = if (zoneType != null) {
                "_${zoneType}"
            } else {
                ""
            }
            val projectId = SPageContext.getHeader("projectId")
            try {

                val relationTypeProjectService = SObjectService(SMybatisDao(RelationTypeProject::class.java))
                val relationType = relationTypeProjectService.select(SFilter.eq("projectId", projectId!!),SFilter.eq("relationType", relType)).entity()
                if (relationType!=null){
                    relationType.computingTime = IdUtils.time()
                    relationTypeProjectService.update(relationType)
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }

            val workbook = XSSFWorkbook(file.inputStream)
            val sheet = workbook.getSheet("关系维护")

            // 填写识别码对应
            val code = sheet.getRow(2).getCell(1).toString()
            logger.debug("识别编码：${code}  ******************************************")
            preExcelRelation(sheet, projectId!!, relType, code, zoneType)

            readExcelRelation(sheet, projectId, relType, zoneType)

            val outFile = File("/tmp/relation-$projectId-${relType}${zone}.xlsx")
            workbook.write(outFile.outputStream())
            /** 发送消息 */
            rabbitMqService.sendRel(Opt.projectId!!, relType,"20","123","456")
        } catch (e: Exception) {
            e.printStackTrace()
            return SBaseResponse(SResponseType.failure, e.message!!)
        }
        return SBaseResponse(SResponseType.success)
    } // Fun importExcel()
    /**
     * 预处理Excel数据
     *
     * @param   sheet           Excel Sheet
     * @param   projectId       项目ID
     * @param   relType         关系类型
     * @param   code            识别码类型
     * @param   zoneType        业务空间类型
     */
    private fun preExcelRelation(sheet: XSSFSheet, projectId: String, relType: String, code: String, zoneType: String? = null): Boolean {
        var result = true
        val rowNum = rowStart


        for (i in rowNum .. sheet.lastRowNum) {
            try {

                val row = sheet.getRow(i)
                if (row?.getCell(idCode1Col) == null ||row.getCell(idCode2Col) == null){
                    continue
                }
                val idCode1ColValue = row.getCell(idCode1Col).toString()
                val idCode2ColValue = row.getCell(idCode2Col).toString()
                logger.debug("idCode1ColValue=${idCode1ColValue}")
                logger.debug("idCode2ColValue=${idCode2ColValue}")
                // 主对象识别码为空，则不能导入数据
                if (idCode1ColValue.isEmpty() || idCode2ColValue.isEmpty()) {
                    row.createCell(stateCol).setCellValue("失败，主对象or从对象的识别编码为空")
                    // result = false
                    continue
                }

                if (code.compareTo("对象ID", true) == 0) {

                    row.createCell(id1Col).setCellValue(idCode1ColValue)
                    row.createCell(id2Col).setCellValue(idCode2ColValue)
                } else  {

                    val id1List = excelImport.findObjectId(projectId, codeTableMap[relType.substring(0, 2)]!!, codeColMap[code]!!, idCode1ColValue)
                    val id2List = excelImport.findObjectId(projectId, codeTableMap[relType.substring(3, 5)]!!, codeColMap[code]!!, idCode2ColValue)

                    if (id1List.count() < 1) {
                        row.createCell(stateCol).setCellValue("未找到主对象")
                        continue
                    }
                    if (id1List.count() > 1) {
                        row.createCell(stateCol).setCellValue("匹配到多个主对象")
                        continue
                    }
                    if (id2List.count() < 1) {
                        row.createCell(stateCol).setCellValue("未找到从对象")
                        continue
                    }
                    if (id2List.count() > 1) {
                        row.createCell(stateCol).setCellValue("匹配到多个从对象")
                        continue
                    }
                    row.createCell(id1Col).setCellValue(id1List[0])
                    row.createCell(id2Col).setCellValue(id2List[0])
                }
            } catch (e: Exception) {
                e.printStackTrace()
                // DO NOTHING
            }
        }

        return result
    } // Fun preExcelRelation()
    /**
     * 从Excel读取关系并存入数据库中
     *
     * @param   sheet           Excel Sheet
     * @param   projectId       项目ID
     * @param   relType         关系类型
     * @param   zone           业务空间类型
     */
    private fun readExcelRelation(sheet: XSSFSheet, projectId: String, relType: String, zone: String? = null) {
        try {
            var zoneType = zone
            val len = relType.indexOf("_")
            val cmd = if (len > 0) {
                relType.substring(0, len)
            } else {
                relType
            }
//        val type = if (len > 0) {
//            relType.substring(len + 1)
//        } else {
//            ""
//        }

            val type = relType

            val importMethod = if (relType == "eq2bd" || relType == "pe2bd") {
                excelImport.javaClass.getDeclaredMethod("${relType}In", String::class.java, String::class.java, String::class.java, String::class.java)
            } else if (relType == "eq2fl" || relType == "pe2fl") {
                excelImport.javaClass.getDeclaredMethod("${relType}In", String::class.java, String::class.java, String::class.java, String::class.java)
            } else if (relType == "sh2bd_ArchForArch") {
                excelImport.javaClass.getDeclaredMethod("sh2bdfor", String::class.java, String::class.java, String::class.java, String::class.java)
            } else if (relType == "sh2fl_ArchForArch"){
                excelImport.javaClass.getDeclaredMethod("sh2flfor", String::class.java, String::class.java, String::class.java, String::class.java)
            }else if (relType == "sh2sh_ArchForArch"){
                excelImport.javaClass.getDeclaredMethod("sh2shfor", String::class.java, String::class.java, String::class.java, String::class.java)
            }else if (cmd == "sp2sp"||cmd == "bd2sp"||cmd == "fl2sp"||cmd == "sh2sp"
                    ||cmd == "sp2bd"||cmd == "sp2fl"||cmd == "sp2sh"){
                 excelImport.javaClass.getDeclaredMethod(cmd, String::class.java, String::class.java, String::class.java, String::class.java, String::class.java)
            } else {
                if(zoneType.isNullOrEmpty()) {
                     excelImport.javaClass.getDeclaredMethod(cmd, String::class.java, String::class.java, String::class.java, String::class.java)
                } else {
                    excelImport.javaClass.getDeclaredMethod(cmd, String::class.java, String::class.java, String::class.java, String::class.java, String::class.java)
                }
            }
            val rowNum = rowStart
            for (i in rowNum .. sheet.lastRowNum) {
                val row = sheet.getRow(i)
                try {
                if (row == null||row.getCell(id1Col) == null||row.getCell(id2Col) == null){
                    sheet.getRow(0).createCell(stateCol).setCellValue("第$i 行数据为空")
                    continue
                }
                val id1 = row.getCell(id1Col).toString()
                val id2 = row.getCell(id2Col).toString()
                // 任意一个ID为空，则不能导入数据
                if (id1.isEmpty() || id2.isEmpty()) {
                    return
                }
                    if (cmd == "sp2sp"||cmd == "bd2sp"||cmd == "fl2sp"||cmd == "sh2sp"){
                        val space = spaceService.select(SFilter.eq("id", id2)).entity()
                        zoneType =  space!!.classCode
                    }else if (cmd == "sp2bd"||cmd == "sp2fl"||cmd == "sp2sh") {
                        val space = spaceService.select(SFilter.eq("id", id1)).entity()
                        zoneType =  space!!.classCode
                    }
                    if(zoneType.isNullOrEmpty()) {
                        importMethod.invoke(excelImport, projectId, type, id1, id2)
                    } else {
                        importMethod.invoke(excelImport, projectId, type, id1, id2, zoneType)
                    }
                    row.createCell(stateCol).setCellValue("关联成功")
                } catch (e: Exception) {
                    e.printStackTrace()
                    row.createCell(stateCol).setCellValue("关联失败")
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    } // Fun readExcelRelation()


    /**
     * 导出 exportExcelPoint
     *
     * @param   response        应答体
     * @param   relType         关系类型
     * @param   code            识别码类型
     * @param   zoneType        业务空间类型
     */
    fun exportExcelPoint(response: HttpServletResponse,buildingId: String,floorId: String,category: String) {
        val projectId = SPageContext.getHeader("ProjectId")
        val workbook = XSSFWorkbook(RelationTypeProjectService::class.java.classLoader.getResourceAsStream("excel/point_infos.xlsx"))
        response.contentType = "application/octet-stream"
        response.setHeader("Content-disposition", "attachment;filename=${projectId}-${category}.xlsx")
        response.flushBuffer()

        val sheet = workbook.getSheet("信息点")

//        val projectId = SPageContext.getHeader("ProjectId")

        try {
            writeExcelPoint(sheet, projectId!!, buildingId, floorId, category)
        }catch (e: Exception) {
            // DO NOTHING
            e.printStackTrace()
        }

        workbook.write(response.outputStream)
    } // Function exportExcel()

    /**
     * 向excel表中写关系
     *
     * @param   sheet           Excel Sheet
     * @param   projectId       项目ID
     * @param   relType         关系类型
     * @param   code            识别码类型
     * @param   zoneType        业务空间类型
     */
    @Suppress("UNCHECKED_CAST")
    private fun writeExcelPoint(sheet: XSSFSheet, projectId: String, buildingId: String,floorId: String,category: String) {
        val exportMethod = excelExport.javaClass.getDeclaredMethod("equipPoint", String::class.java,String::class.java, String::class.java, String::class.java)
        val list = exportMethod!!.invoke(excelExport, projectId,buildingId,floorId,category) as List<HashMap<String, Any?>>


        var rowNum = 1
        // 填写识别码对应
//        sheet.getRow(2).getCell(1).setCellValue(code)

        for (it in list) {
            val row = sheet.createRow(rowNum)
            for ((i, item) in itemListTwo.withIndex()) {
                logger.debug("数据= ${i?.toString()}")
                val cellValue = it[item]
                val cell = row.createCell(i)
                if (cellValue != null) {
                    cell.setCellValue(cellValue.toString())
                }
                logger.debug("数据= ${cellValue?.toString()}")
            }
            // 添加识别码
//            row.createCell(0).setCellValue(row.getCell(id1Col).toString())
//            row.createCell(8).setCellValue(row.getCell(id2Col).toString())
            rowNum++
        }
    } // Fun writeExcelRelation()

    /**
     * 导入excel
     *
     * @param   file            上传的Excel文件
     * @param   relType         关系类型
     * @param   zoneType        业务空间类型
     * @return  应答体
     */
    fun importExcelPoint(file: MultipartFile): SBaseResponse {
        try {
            if (file.isEmpty) {
                throw Exception("未选择文件")
            }

            val projectId = SPageContext.getHeader("projectId")
            // 转为 XSSFWorkbook 对象
            val workbook = XSSFWorkbook(file.inputStream)
            // 读取第一个 sheet
            val sheet = workbook.getSheetAt(0)

            readExcelPoint(sheet, projectId!!)
            // 时间
            val date: String = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))
            var path:String
            // Tomcat 路径
            val tomcat_path = System.getProperty("user.dir")
            // 上传的文件名
            val myFileName = file.originalFilename
            // 重组文件名
            val fileName = projectId +  date + "." + myFileName.substring(myFileName.lastIndexOf(".") + 1)
            //获取tomcat中项目同级路径
            val bin_path = tomcat_path.substring(tomcat_path.lastIndexOf("/") + 1, tomcat_path.length)
            if ("bin" == bin_path) {
                path = tomcat_path.substring(0, System.getProperty("user.dir").lastIndexOf("/")) + "/temp/" + "/upload/"
            } else {
                path = "$tomcat_path/temp/upload/"
            }
            val fileDir = File(path)
            //如果不存在 则创建
            if (!fileDir.exists()) {
                fileDir.mkdirs()
            }
            // 文件
            val files = File(path,fileName)
            // 文件流
            val os: OutputStream = FileOutputStream(files)
            // 写入
            workbook.write(os)
            os.flush()
            os.close()

            return SBaseResponse(SResponseType.success,fileName)
        } catch (e: Exception) {
            e.printStackTrace()
            return SBaseResponse(SResponseType.failure, e.message!!)
        }
    } // Fun importExcel()

    /**
     * 从Excel读取关系并存入数据库中
     *
     * @param   sheet           Excel Sheet
     * @param   projectId       项目ID
     * @param   relType         关系类型
     * @param   zoneType        业务空间类型
     */
    private fun readExcelPoint(sheet: XSSFSheet, projectId: String) = try {

        logger.debug("id3= ***************************************************")
        val rowNum = 1
        for (i in rowNum .. sheet.lastRowNum) {
            val row = sheet.getRow(i)
            try {
                if (row == null){
                    sheet.getRow(0).createCell(stateCol).setCellValue("第$i 行数据为空")
                    continue
                }
                if (row != null){
                    val cell = row.getCell(0)
                    cell.setCellType(CellType.STRING);
                    val cell1 = row.getCell(1)
                    cell1.setCellType(CellType.STRING);
                    val cell2 = row.getCell(2)
                    cell2.setCellType(CellType.STRING);
                    val cell3 = row.getCell(3)
                    cell3.setCellType(CellType.STRING);
                    val id0 =cell.toString().trim()
                    val id1 = cell1.toString().trim()
                    val id2 = cell2.toString().trim()
                    val id3 = cell3.toString().trim()
                    logger.debug("id0= $id0")
                    logger.debug("id1= $id1")
                    logger.debug("id2= $id2")
                    logger.debug("id3= $id3")
                    if (!id0.isNullOrEmpty()&&!id1.isNullOrEmpty()&&!id2.isNullOrEmpty()&&!id3.isNullOrEmpty()) {

                        val equipmentList = EquipmentService.select(SFilter.eq("projectId", projectId), SFilter.eq("localId", id0.trim())).exec()
                        if (equipmentList.isEmpty()){
                            row.createCell(4).setCellValue("本地编码不存在")
                        }else if (equipmentList.size>1) {
                            row.createCell(4).setCellValue("本地编码重复")
                        }else {
                            val entity = dictDefFuncId.select(SFilter.eq("type", equipmentList[0].classCode!!), SFilter.eq("code", id1)).entity()
                            if (entity == null) {
                                row.createCell(4).setCellValue("信息点不存在")
                            }else {
                                val equip = equipUpdate(equipmentList[0], id1, id2, id3)
                                val request = SUpdateRequest<Equipment>()
                                request.content = arrayListOf(equip)
                                try {
                                    val updateList = EquipmentService.updateList(request)
                                    if (updateList.result == SResponseType.success){
                                        row.createCell(4).setCellValue("成功")
                                    }else{
                                        row.createCell(4).setCellValue("失败")
                                    }
                                } catch (e: Exception) {
                                    e.printStackTrace()
                                    row.createCell(4).setCellValue("失败")
                                }
                            }
                        }
                    }else {
                        row.createCell(4).setCellValue("信息不全")
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
                row.createCell(4).setCellValue("失败")
            }
        }
    } catch (e: Exception) {
        e.printStackTrace()
    } // Fun readExcelRelation()

    fun equipUpdate(equipment: Equipment,id1: String,id2: String,id3: String):Equipment {
        val entity = dictDefFuncId.select(SFilter.eq("type", equipment.classCode!!), SFilter.eq("code", id1)).entity()
        logger.debug("信息点1=${equipment.classCode}")
        logger.debug("信息点=${entity?.toJson()}")
        if (entity!=null) {

            if (equipment.infos.isNullOrEmpty()) {
                equipment.infos = HashMap()
            }
            equipment.infos!![id1] = "$id2-$id3"
        }
        return equipment
    }

    /**
     * 下载报告
     *
     * @param   response        应答体
     * @param   relType         关系类型
     * @param   zoneType        业务空间类型
     */
    fun reportDownloadsPoint(response: HttpServletResponse,key:String) {
        var path:String
        val projectId = SPageContext.getHeader("projectId")

        val tomcat_path = System.getProperty("user.dir")

        //获取tomcat中项目同级路径
        val bin_path = tomcat_path.substring(tomcat_path.lastIndexOf("/") + 1, tomcat_path.length)
        if ("bin" == bin_path) {
            path = tomcat_path.substring(0, System.getProperty("user.dir").lastIndexOf("/")) + "/temp/" + "/upload/"
        } else {
            path = "$tomcat_path/temp/upload/"
        }
        val file = File(path+key)
        val workbook = if (file.exists()) {
            XSSFWorkbook(file)
        } else {
            XSSFWorkbook(RelationTypeProjectService::class.java.classLoader.getResourceAsStream("excel/relation-template.xlsx"))
        }
        response.contentType = "application/octet-stream"
        response.setHeader("Content-disposition", "attachment;filename=${key}")
        response.flushBuffer()
        workbook.write(response.outputStream)
    }

}

