ReportService.java 11.4 KB
package com.xkl.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xkl.config.Constants;
import com.xkl.config.ResultStatus;
import com.xkl.domain.*;
import com.xkl.model.ReportIdModel;
import com.xkl.model.ResultModel;
import com.xkl.repository.*;
import com.xkl.security.SecurityTool;
import lombok.extern.apachecommons.CommonsLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.*;

/**
 * Created by zhao yue on 2016/11/13.
 */
@Service
@CommonsLog
public class ReportService implements IReportService {
    @Autowired
    private ReportMetaItemsRepository reportMetaItemsRepository;

    @Autowired
    private ReportRepository reportRepository;

    @Autowired
    private ReportDetailRepository reportDetailRepository;

    @Autowired
    private ReportResultRepository reportResultRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private IScoreService scoreService;

    // 存储报告相关md5,防止重复上传已存在报告,防止重复上传错误报告。
    private RedisTemplate<String, String> redis;

    @Autowired
    public void setRedis(RedisTemplate redis) {
        this.redis = redis;
    }

    private static Map<Integer, XklAmpReportMetaItemsEntity> rpMetaItemMap = new HashMap<Integer, XklAmpReportMetaItemsEntity>();

    /*
     * 存储报告
     */
    public ResponseEntity<ResultModel> save(XklAdminEntity admin, String json_report) {
        // 验证存在性
        String reportMd5 = SecurityTool.encode("MD5", json_report);
        // 验证是无对应的会员,rediskey
        String reportWithNoUser = reportMd5 + "Member";
        // 验证报告格式有问题,rediskey
        String reportWrongFormat = reportMd5 + "Format";
        /*
         * 如果已经处理过的报告,不再进行处理。
         */
        XklAmpReportEntity report = reportRepository.findByMd5AndStatus(reportMd5, Constants.STATUS_OK);
        if (report != null && report.getStatus() > 0) {
            // 返回,报告已存在。
            return new ResponseEntity<>(ResultModel.error(ResultStatus.REPORT_EXISTED_ERROR, new ReportIdModel(report.getId())), HttpStatus.OK);
        } else if (redis.hasKey(reportWithNoUser)) {
            // 返回,报告对应会员不存在。
            return new ResponseEntity<>(ResultModel.error(ResultStatus.INVALID_USER_ERROR),HttpStatus.OK);
        } else if (redis.hasKey(reportWrongFormat)) {
            // 返回,报告格式有问题。
            return new ResponseEntity<>(ResultModel.error(ResultStatus.REPORT_FORMAT_ERROR),HttpStatus.OK);
        }
        /*
         * 解析报告数据
         */
        ReportData reportData = parseReport(json_report, reportMd5);
        /*
         * 检验报告格式
         */
        if (reportData == null) {
            redis.boundValueOps(reportWrongFormat).set("");
            // 返回,报告格式有问题。
            return new ResponseEntity<>(ResultModel.error(ResultStatus.REPORT_FORMAT_ERROR),HttpStatus.OK);
        }
        /*
         * 检验会员存在性
         */
        User user = userRepository.findByLoginAccountAndStatus(reportData.getAmpReport().getAccountStr(), Constants.STATUS_OK2);
        if (user == null) {
            redis.boundValueOps(reportWithNoUser).set("");
            // 返回,报告对应会员不存在。
            return new ResponseEntity<>(ResultModel.error(ResultStatus.INVALID_USER_ERROR),HttpStatus.OK);
        }

        /*
         * 存储报告
         */
        long reportId = save2DB(reportData, admin, user);
        if (reportId > 0) {
            // 返回,报告存储成功,报告id
            return new ResponseEntity<>(ResultModel.ok(new ReportIdModel(reportId)), HttpStatus.OK);
        } else {
            // 返回,服务器存储问题。
            return new ResponseEntity<>(ResultModel.error(ResultStatus.DB_ERROR),HttpStatus.OK);
        }
    }

    /*
     * 操作员删除报告,只能删除该操作员自己创建的报告。
     */
    public ResponseEntity<ResultModel> delete(XklAdminEntity admin, long report_id) {
        //  1. 得到report,验证报告存在性
        XklAmpReportEntity report = reportRepository.findById(report_id);
        if (report == null || report.getStatus() == 0) {
            // 报告不存在,返回
            return new ResponseEntity<>(ResultModel.error(ResultStatus.REPORT_INVALID_ERROR), HttpStatus.OK);
        }

        // 2. 验证admin
        if (report.getCreateBy() != admin.getId()) {
            // 非此admin创建,不能删除,返回
            return new ResponseEntity<>(ResultModel.error(ResultStatus.INVALID_ADMIN_RPDEL_ERROR),HttpStatus.OK);
        }
        // 3. 删除report和detail,返回ok
        reportRepository.delete(report);
        List<XklAmpReportDetailEntity> detailList = reportDetailRepository.findByReportId(report.getId());
        reportDetailRepository.delete(detailList);
        List<XklAmpReportResultEntity> rpResList = reportResultRepository.findByReportId(report.getId());
        reportResultRepository.delete(rpResList);
        return new ResponseEntity<>(ResultModel.ok(), HttpStatus.OK);
    }

    /*
     验证md5
     获取report
     获取detail
     评判detail
     验证member
     获取admin
     */
    // 需要程喆增加 title,account,machine_num字段 String; 修改set字段为int,0男,1女。125项目,改为float类型。
    //
    private ReportData parseReport(String reportJson, String md5) {
        ReportData reportData = new ReportData();
        XklAmpReportEntity ampReport = new XklAmpReportEntity();
        List<XklAmpReportDetailEntity> detailList = new ArrayList<>();
        List<XklAmpReportResultEntity> basicResList = new ArrayList<>();
        int sex;

        /*
         * 2. 获取report基础信息
         */
        try {
            JSONObject rpJson = JSONObject.parseObject(reportJson);
            sex = rpJson.getInteger("sex").intValue();
            ampReport.setReport(rpJson.getString("name"),
                    rpJson.getString("title"),///                    "AMP快速无创身心健康评估报告",
                    new Timestamp(rpJson.getLong("report_date")),
                    new Timestamp(System.currentTimeMillis()),
                    rpJson.getString("account"),///
                    rpJson.getInteger("sex").byteValue(),///
                    rpJson.getInteger("age").byteValue(),
                    rpJson.getInteger("weight").intValue(),
                    rpJson.getInteger("pulse").intValue(),
                    rpJson.getInteger("respiratory_rate").intValue(),
                    rpJson.getDouble("atmospheric_pressure").doubleValue(),
                    rpJson.getDouble("LCA").doubleValue(),
                    rpJson.getDouble("RCA").doubleValue(),
                    rpJson.getDouble("LAC").doubleValue(),
                    rpJson.getDouble("RAC").doubleValue(),
                    rpJson.getDouble("ABD").doubleValue(),
                    rpJson.getDouble("total").doubleValue(),
                    rpJson.getInteger("stable").intValue(),
                    md5, rpJson.getString("machine_num"),
                    rpJson.getString("basic_result"),
                    rpJson.getString("T0"),
                    rpJson.getString("T1"),
                    rpJson.getString("T2"),
                    rpJson.getString("T3"),
                    rpJson.getString("T4")
            );
            /*
             * 3. 获取detail信息,id,float类型
             */
            JSONObject rpDetails = rpJson.getJSONObject("detail");
            for (int item_id = 1; item_id <= 125; item_id++) {
                float val = rpDetails.getFloat(String.valueOf(item_id)).floatValue();
                XklAmpReportDetailEntity detail = new XklAmpReportDetailEntity();
                detail.setItemValue(val);
                detail.setItemId(item_id);
                detailList.add(detail);
            }
            /*
             * 4. 获取诊断结论编号
             */
            JSONArray basicResIdsArr = rpJson.getJSONArray("basic_result_ids");
            if (basicResIdsArr != null && basicResIdsArr.size() > 0) {
                for (int resId = 0; resId < basicResIdsArr.size(); resId++) {
                    XklAmpReportResultEntity rpRes = new XklAmpReportResultEntity();
                    rpRes.setResultItemId(basicResIdsArr.getInteger(resId));
                    basicResList.add(rpRes);
                }
            }
        } catch (Exception e) {
            log.info("ERROR, JSON FROMAT ERROR!!!"+e);
            return null;
        }
        markItemStatus(sex, detailList);
        reportData.setAmpReport(ampReport);
        reportData.setRpDetailList(detailList);
        reportData.setBasicResList(basicResList);
        return reportData;
    }

    /*
     * 存储报告
     */
    private long save2DB(ReportData report, XklAdminEntity admin, User user) {
        report.getAmpReport().setCreateBy(admin.getId());
        report.getAmpReport().setCompanyId((long) admin.getCoid());
        report.getAmpReport().setMemberId((long) user.getMemberId());
        XklAmpReportEntity ampReport = reportRepository.save(report.getAmpReport());
        for (XklAmpReportDetailEntity detail : report.getRpDetailList()) {
            detail.setReportId(ampReport.getId());
        }
        for (XklAmpReportResultEntity rpRes : report.getBasicResList()){
            rpRes.setReportId(ampReport.getId());
        }
        reportDetailRepository.save(report.getRpDetailList());
        reportResultRepository.save(report.getBasicResList());
        scoreService.getScore(ampReport.getId());
        return ampReport.getId();
    }

    /*
     * 判断detail是正常,高于标准或低于标准。
     */
    private void markItemStatus(int sex, List<XklAmpReportDetailEntity> detailList) {
        // load ReportMetaItems into memory.
        synchronized (this) {
            if (rpMetaItemMap.size() == 0) {
                Iterator<XklAmpReportMetaItemsEntity> rpMetaIter = reportMetaItemsRepository.findAll().iterator();
                while (rpMetaIter.hasNext()) {
                    XklAmpReportMetaItemsEntity rpMetaItem = rpMetaIter.next();
                    rpMetaItemMap.put(rpMetaItem.getItemId(), rpMetaItem);
                }
            }
        }
        // mark status
        for (XklAmpReportDetailEntity detail : detailList) {
            double lowSt;
            double highSt;
            // get standard
            if (sex == Constants.MALE) { // male
                lowSt = rpMetaItemMap.get(detail.getItemId()).getStandardLowMale();
                highSt = rpMetaItemMap.get(detail.getItemId()).getStandardHighMale();
            } else { // female
                lowSt = rpMetaItemMap.get(detail.getItemId()).getStandardLowFemale();
                highSt = rpMetaItemMap.get(detail.getItemId()).getStandardHighFemale();
            }
            int status;
            if (detail.getItemValue() < lowSt) {
                status = Constants.LOWER;
            } else if (detail.getItemValue() > highSt) {
                status = Constants.HIGHER;
            } else {
                status = Constants.NORMAL;
            }
            detail.setStatus(status);
        }
    }
}