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

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.ReportDetailRepository;
import com.xkl.repository.ReportMetaItemsRepository;
import com.xkl.repository.ReportRepository;
import com.xkl.repository.UserRepository;
import com.xkl.security.SecurityTool;
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
public class ReportService implements IReportService {
    @Autowired
    private ReportMetaItemsRepository reportMetaItemsRepository;

    @Autowired
    private ReportRepository reportRepository;

    @Autowired
    private ReportDetailRepository reportDetailRepository;

    @Autowired
    private UserRepository userRepository;

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

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

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

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

        /*
         * 存储报告
         */
        int 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.NOT_FOUND);
        }
    }

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

        // 2. 验证admin
        if (report.getCreate_by() != admin.getId()) {
            // 非此admin创建,不能删除,返回
            return new ResponseEntity<>(ResultModel.error(ResultStatus.INVALID_ADMIN_RPDEL_ERROR), HttpStatus.NOT_FOUND);
        }
        // 3. 删除report和detail,返回ok
        reportRepository.delete(report);
        List<AMPReportDetail> detailList = reportDetailRepository.findByReportId(report.getId());
        reportDetailRepository.delete(detailList);
        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();
        AMPReport ampReport = new AMPReport();
        List<AMPReportDetail> detailList = 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快速无创身心健康评估报告",
                    Timestamp.valueOf(rpJson.getString("report_date")),
                    new Timestamp(System.currentTimeMillis()),
                    rpJson.getString("account"),///
                    rpJson.getInteger("sex").intValue(),///
                    rpJson.getInteger("age").intValue(),
                    rpJson.getInteger("weight").intValue(),
                    rpJson.getInteger("pulse").intValue(),
                    rpJson.getInteger("respiratory_rate").intValue(),
                    rpJson.getFloat("atmospheric_pressure").floatValue(),
                    rpJson.getFloat("LCA").floatValue(),
                    rpJson.getFloat("RCA").floatValue(),
                    rpJson.getFloat("LAC").floatValue(),
                    rpJson.getFloat("RAC").floatValue(),
                    rpJson.getFloat("ABD").floatValue(),
                    rpJson.getFloat("total").floatValue(),
                    rpJson.getInteger("stable").intValue(),
                    md5, rpJson.getString("machine_num"), rpJson.getString("basic_result"));
            /*
             * 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();
                AMPReportDetail detail = new AMPReportDetail();
                detail.setItemValue(val);
                detail.setItemId(item_id);
                detailList.add(detail);
            }
        } catch (Exception e) {
            return null;
        }
        markItemStatus(sex, detailList);
        reportData.setAmpReport(ampReport);
        reportData.setRpDetailList(detailList);
        return reportData;
    }

    /*
     * 存储报告
     */
    private int save2DB(ReportData report, Admin admin, User user) {
        report.getAmpReport().setCreate_by((int) admin.getId());
        report.getAmpReport().setCompany_id(admin.getCoid());
        report.getAmpReport().setMember_id(user.getMemberId());
        AMPReport ampReport = reportRepository.save(report.getAmpReport());
        for (AMPReportDetail detail : report.getRpDetailList()) {
            detail.setReportId(ampReport.getId());
        }
        reportDetailRepository.save(report.getRpDetailList());
        return ampReport.getId();
    }

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