package com.fs.hisStore.service.impl;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fs.common.core.domain.R;
import com.fs.common.core.redis.RedisCache;
import com.fs.common.exception.CustomException;
import com.fs.common.utils.DateUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fs.common.utils.StringUtils;
import com.fs.company.cache.ICompanyUserCacheService;
import com.fs.company.domain.CompanyUser;
import com.fs.company.mapper.CompanyUserMapper;
import com.fs.company.service.ICompanyService;
import com.fs.core.config.WxMaConfiguration;
import com.fs.core.config.WxPayProperties;
import com.fs.core.utils.OrderCodeUtils;
import com.fs.course.param.CollectConfirmGeneratePrescribeParam;
import com.fs.course.param.CollectionBindUserParam;
import com.fs.course.param.CollectionInfoConfirmParam;
import com.fs.course.param.SubmitCollectionAnswerParam;
import com.fs.course.vo.FsUserInfoCollectionUVO;
import com.fs.doctor.domain.DoctorMsg;
import com.fs.doctor.mapper.DoctorMsgMapper;
import com.fs.enums.PostPayPrescStatusEnum;
import com.fs.his.config.FsSysConfig;
import com.fs.his.domain.*;
import com.fs.his.enums.CollectionTaskStatusEnum;
import com.fs.his.enums.FsStoreOrderLogEnum;
import com.fs.his.enums.FsStoreOrderStatusEnum;
import com.fs.his.enums.PrescriptionTaskStepEnum;
import com.fs.his.mapper.*;
import com.fs.his.service.*;
import com.fs.his.utils.ConfigUtil;
import com.fs.his.vo.AnswerVO;
import com.fs.his.vo.FsQuestionAndAnswerVO;
import com.fs.hisStore.domain.FsUserInformationCollectionPersonalLog;
import com.fs.hisStore.dto.FsUserInformationCollectionOverviewDTO;
import com.fs.hisStore.dto.PendingSalesInfoQueryDTO;
import com.fs.hisStore.mapper.FsUserInformationCollectionPersonalLogMapper;
import com.fs.hisStore.param.FsUserInformationCollectionListDParam;
import com.fs.hisStore.param.FsUserInformationCollectionParam;
import com.fs.hisStore.param.bindCollectionPackageParam;
import com.fs.hisStore.vo.FsUserInformationCollectionListDVO;
import com.fs.hisStore.vo.FsUserInformationCollectionVO;
import com.fs.hisStore.vo.FsUserInformationCollectionOverviewVo;
import com.fs.huifuPay.domain.HuiFuRefundResult;
import com.fs.huifuPay.domain.HuifuConfirmrefundResult;
import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentDelaytransConfirmrefundRequest;
import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayRefundRequest;
import com.fs.huifuPay.service.HuiFuService;
import com.fs.qw.mapper.FsUserInformationCollectionScheduleMapper;
import com.fs.qw.mapper.QwExternalContactMapper;
import com.fs.store.domain.FsDoctorConfirm;
import com.fs.store.service.IFsDoctorConfirmService;
import com.fs.system.domain.SysConfig;
import com.fs.system.mapper.SysConfigMapper;
import com.fs.system.oss.CloudStorageService;
import com.fs.system.oss.OSSFactory;
import com.fs.system.service.ISysConfigService;
import com.fs.tzBankPay.TzBankService.TzBankService;
import com.fs.tzBankPay.doman.RefundParam;
import com.fs.tzBankPay.doman.RefundResult;
import com.fs.tzBankPay.doman.TzBankResult;
import com.fs.ybPay.dto.RefundDTO;
import com.fs.ybPay.service.IPayService;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundQueryResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fs.hisStore.mapper.FsUserInformationCollectionMapper;
import com.fs.hisStore.domain.FsUserInformationCollection;
import com.fs.hisStore.service.IFsUserInformationCollectionService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import static com.fs.his.utils.PhoneUtil.encryptPhone;

/**
 * 用户信息采集Service业务层处理
 *
 * @author fs
 * @date 2025-10-14
 */
@Slf4j
@Service
public class FsUserInformationCollectionServiceImpl extends ServiceImpl<FsUserInformationCollectionMapper, FsUserInformationCollection> implements IFsUserInformationCollectionService {
    Logger logger= LoggerFactory.getLogger(getClass());

    @Autowired
    private ISysConfigService configService;

    @Autowired
    SysConfigMapper sysConfigMapper;

    @Autowired
    private WxPayProperties wxPayProperties;

    @Autowired
    private WxPayService wxPayService;

    @Autowired
    IPayService payService;

    @Autowired
    private TzBankService tzBankService;

    @Autowired
    private HuiFuService huiFuService;

    @Autowired
    private CompanyUserMapper companyUserMapper;

    @Autowired
    private FsDoctorMapper doctorMapper;

    @Autowired
    private IFsDoctorService iFsDoctorService;

    @Autowired
    private IFsQuestionAndAnswerService questionAndAnswerService;

    @Autowired
    private FsUserInformationCollectionMapper fsUserInformationCollectionMapper;

    @Autowired
    private ConfigUtil configUtil;

    @Autowired
    private IFsDoctorConfirmService doctorConfirmService;

    @Autowired
    RedisCache redisCache;

    @Autowired
    private FsPackageMapper packageMapper;

    @Autowired
    private IFsStoreOrderService storeOrderService;

    @Autowired
    private FsPackageOrderMapper packageOrderMapper;

    @Autowired
    private FsPrescribeMapper fsPrescribeMapper;

    @Autowired
    private IFsPrescribeService prescribeService;

    @Autowired
    private ICompanyService companyService;

    @Autowired
    private FsStorePaymentMapper fsStorePaymentMapper;

    @Autowired
    private FsStoreOrderLogsMapper fsStoreOrderLogsMapper;
    @Autowired
    private DoctorMsgMapper doctorMsgMapper;

    @Autowired
    private IFsPackageService packageService;

    @Autowired
    private FsUserInformationCollectionScheduleMapper scheduleMapper;

    @Autowired
    private ICompanyUserCacheService companyUserCacheService;

    @Autowired
    private IFsStoreOrderLogsService fsStoreOrderLogsService;

    @Autowired
    private IFsUserService userService;

    @Autowired
    private QwExternalContactMapper qwExternalContactMapper;

    @Autowired
    private IPollingAssignDoctorService pollingAssignDoctorService;

    @Autowired
    private FsUserMapper fsUserMapper;

    @Autowired
    private FsUserInformationCollectionPersonalLogMapper infoCollectionPersonalLogMapper;

    //"默认就诊人"常量字符串
    private static final String DEFAULT_PATIENT_NAME = "默认就诊人";

    /**
     * 查询用户信息采集
     *
     * @param id 用户信息采集主键
     * @return 用户信息采集
     */
    @Override
    public FsUserInformationCollection selectFsUserInformationCollectionById(Long id)
    {
        return baseMapper.selectFsUserInformationCollectionById(id);
    }

    /**
     * 查询用户信息采集列表
     *
     * @param fsUserInformationCollection 用户信息采集
     * @return 用户信息采集
     */
    @Override
    public List<FsUserInformationCollection> selectFsUserInformationCollectionList(FsUserInformationCollection fsUserInformationCollection)
    {
        return baseMapper.selectFsUserInformationCollectionList(fsUserInformationCollection);
    }

    /**
     * 新增用户信息采集
     *
     * @param param 用户信息采集
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long insertFsUserInformationCollection(FsUserInformationCollectionParam param) {
        checkSalesFillCondition(param);
        if (param.getIsPackage() != null && param.getIsPackage() == 1) {
            FsPackage fsPackage = packageMapper.selectFsPackageByPackageId(param.getPackageId());
            if (fsPackage != null && !(fsPackage.getProductType() == 1 || fsPackage.getProductType() == 2 || fsPackage.getProductType() == 3)) {
                throw new CustomException("该套餐不支持用户信息采集");
            }
        }
        //用户是否已存在采集信息
        FsUserInformationCollection queryCondition = new FsUserInformationCollection();
        queryCondition.setUserId(param.getUserId());
        List<FsUserInformationCollection> fsUserInformationCollections = baseMapper.selectFsUserInformationCollectionList(queryCondition);
        if (!CollectionUtils.isEmpty(fsUserInformationCollections) && fsUserInformationCollections.size() > 1) {
            log.info("用户已存在采集信息,用户id:{}", param.getUserId());
            throw new CustomException("用户已存在采集信息");
        }
        //构建用户信息采集信息
        FsUserInformationCollection fsUserInformationCollection = buildUserInfoCollection(param);
        try {
            if (validateRequiredRemarks(param.getAnswers(),param.getQuestionId())){
                //用户采集信息问题完善状态 0-未完善 1-完善
                fsUserInformationCollection.setCompleteStatus(1);
            }else {
                fsUserInformationCollection.setCompleteStatus(0);
            }
            baseMapper.insertFsUserInformationCollection(fsUserInformationCollection);
            //构建采集进度信息
            FsUserInformationCollectionSchedule fsUserInformationCollectionSchedule = buildUserInfoSchedule(fsUserInformationCollection);
            scheduleMapper.insertFsUserInformationCollectionSchedule(fsUserInformationCollectionSchedule);
        } catch (Exception e) {
            logger.error("新增---用户id:{},新增用户信息采集进度失败", param.getUserId(), e);
            throw new CustomException("用户信息采集进度新增失败");
        }
        return fsUserInformationCollection.getId();
    }

    /**
     * 修改用户信息采集
     *
     * @param param 用户信息采集
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long updateFsUserInformationCollection(FsUserInformationCollectionParam param)
    {
        checkSalesFillCondition(param);
        if (param.getId() == null || param.getId() < 1) {
            throw new CustomException("参数错误");
        }
        FsUserInformationCollection collection = fsUserInformationCollectionMapper.selectFsUserInformationCollectionById(param.getId());
        if (collection == null) {
            throw new CustomException("用户:"+param.getUserId()+"没有用户采集信息");
        }
        if(collection.getQwTag()==1){
            throw new CustomException("用户信息采集已同步到个微，请勿修改");
        }
        if (collection.getUserConfirm() == 1 && collection.getUserConfirm2() == 0) {
            throw new CustomException("确认中，暂无法修改");
        }
        if (param.getIsPackage() == 1) {
            FsPackage fsPackage = packageMapper.selectFsPackageByPackageId(param.getPackageId());
            if (fsPackage != null && !(fsPackage.getProductType() == 1 || fsPackage.getProductType() == 2 || fsPackage.getProductType() ==3)) {
                throw new CustomException("该疗法不支持用户信息采集");
            }
        }
        //编辑用户信息采集信息时，需要新增采集进度数据(先取消进度再新增进度)
        FsUserInformationCollectionSchedule schedule = scheduleMapper.selectCollectionScheduleRunningByCollectionId(collection.getId());
        if (schedule != null){
            log.info("用户信息采集进度未取消,进度id:{}",schedule.getId());
            throw new CustomException("请先取消此用户信息的采集进度");
        }
        FsUserInformationCollection fsUserInformationCollection = buildUserInfoCollection(param);
        try {
            FsUserInformationCollectionSchedule fsUserInformationCollectionSchedule = buildUserInfoSchedule(fsUserInformationCollection);
            scheduleMapper.insertFsUserInformationCollectionSchedule(fsUserInformationCollectionSchedule);
        }catch (Exception e){
            logger.error("编辑---用户id:{},新增用户信息采集进度失败",param.getUserId(),e);
            throw new CustomException("用户信息采集进度新增失败");
        }
        //清空订单号
        fsUserInformationCollectionMapper.collectionOderCodeNULL(param.getId());
        fsUserInformationCollection.setUserConfirm2(0);
        fsUserInformationCollection.setUserConfirm(0);
        fsUserInformationCollection.setDoctorConfirm(0);
        fsUserInformationCollection.setFillFlag(param.getFillFlag());//填写标识 0:未填写
        fsUserInformationCollection.setStatus(1);
        fsUserInformationCollection.setUpdateTime(DateUtils.getNowDate());
        fsUserInformationCollection.setRemark(param.getRemark());
        fsUserInformationCollection.setSex(param.getSex());
        fsUserInformationCollection.setIsPackage(param.getIsPackage());
        fsUserInformationCollection.setUserName(param.getUserName());
        if (param.getIsPackage() != null && param.getIsPackage() == 1){
            fsUserInformationCollection.setPackageId(param.getPackageId());
        }
        fsUserInformationCollection.setUserPhoneFour(param.getUserPhoneFour());
        fsUserInformationCollection.setAllergy(param.getAllergy());
        fsUserInformationCollection.setPayType(param.getPayType());
        fsUserInformationCollection.setQuestionId(param.getQuestionId());
        fsUserInformationCollection.setAmount(param.getAmount());
        fsUserInformationCollection.setAge(param.getAge());
        if (validateRequiredRemarks(param.getAnswers(),collection.getQuestionId())){
            //用户采集信息问题完善状态 0-未完善 1-完善
            fsUserInformationCollection.setCompleteStatus(1);
        }else {
            fsUserInformationCollection.setCompleteStatus(0);
        }
        //更新用户信息采集信息
        int addResult = baseMapper.updateFsUserInformationCollection(fsUserInformationCollection);
        return fsUserInformationCollection.getId();
    }


    //创建个微版采集信息(起始无绑定用户id)
    @Override
    @Transactional(rollbackFor = Exception.class)
    public FsUserInformationCollection createSimpleUserInfo(FsUserInformationCollectionParam param) {
        //校验销售填写条件
        checkSalesFillCondition(param);
        //构建用户信息采集对象
        FsUserInformationCollection fsUserInformationCollection = buildFastInfoCollection(param);
        //添加个微标识
        fsUserInformationCollection.setQwTag(1);
        fsUserInformationCollection.setPersonalCollectStatus(PostPayPrescStatusEnum.INFO_COLLECTION.getCode());//个微采集表初始状态
        try {
            if (validateRequiredRemarks(param.getAnswers(),param.getQuestionId())){
                //用户采集信息问题完善状态 0-未完善 1-完善
                fsUserInformationCollection.setCompleteStatus(1);
            }else {
                fsUserInformationCollection.setCompleteStatus(0);
            }
            baseMapper.insertFsUserInformationCollection(fsUserInformationCollection);
        } catch (Exception e) {
            logger.error("个微版-----用户信息采集进度创建失败", e);
            throw new CustomException("个微信息采集创建失败");
        }
        return fsUserInformationCollection;
    }

    //个微信息采集用户确认并生成医生待开处方
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R generateFormalPrescription(CollectConfirmGeneratePrescribeParam param) {
        FsUserInformationCollection collection = fsUserInformationCollectionMapper.selectFsUserInformationCollectionById(param.getId());
        if (collection == null) {
            log.error("当前用户userId:{},信息采集表id:{}", param.getUserId(), param.getId());
            return R.error("采集信息不存在");
        }
        if (!Objects.equals(collection.getUserId(), param.getUserId())) {
            log.error("当前用户userId:{},信息采集表userId:{}", param.getUserId(), collection.getUserId());
            return R.error("用户信息与绑定用户不匹配,无法确认");
        }

        collection.setPersonalCollectStatus(PostPayPrescStatusEnum.PENDING_DOCTOR.getCode());
        if (fsUserInformationCollectionMapper.updateFsUserInformationCollection(collection) > 0) {
            //组装处方信息
            FsPrescribe fsPrescribe = transformCollectionParamToFsPrescribe(param, collection);
            //新增fs_prescribe处方信息
            int addPrescribeResult = fsPrescribeMapper.insertFsPrescribe(fsPrescribe);

            collection.setPrescribeId(fsPrescribe.getPrescribeId());//TODO 向fs_user_information_collection表写入处方id 后续要优化改成更新一次collection
            //如果用户的患者信息还是默认就诊人则也需要更新信息采集为待完善
            if (DEFAULT_PATIENT_NAME.equals(param.getPatientInfo().getPatientName())){
                collection.setCompleteStatus(0);
            }
            fsUserInformationCollectionMapper.updateFsUserInformationCollection(collection);
            FsUserInformationCollectionPersonalLog informationCollectionPersonalLog=new FsUserInformationCollectionPersonalLog();
            BeanUtils.copyProperties(collection, informationCollectionPersonalLog);
            informationCollectionPersonalLog.setCollectionId(collection.getId());
            informationCollectionPersonalLog.setPrescribeId(fsPrescribe.getPrescribeId());
            informationCollectionPersonalLog.setPackageOrderCode("");//这里还没有产生订单号，避免采集表原有的脏数据
            //新增 个微用户信息采集记录
            infoCollectionPersonalLogMapper.insertFsUserInformationCollectionPersonalLog(informationCollectionPersonalLog);
            //存入医生确认统计时间数据
            Date currentTime = DateUtils.getNowDate();
            FsDoctorConfirm doctorConfirm = new FsDoctorConfirm();
            doctorConfirm.setCollectionId(collection.getId());
            doctorConfirm.setDoctorId(collection.getDoctorId());
            doctorConfirm.setStartTime(currentTime);
            doctorConfirmService.insertFsDoctorConfirm(doctorConfirm);
            //医生确认时间存入缓存 医生确认后删除
            redisCache.setCacheObject("doctorConfirm:" + collection.getId(), doctorConfirm);
            if (addPrescribeResult > 0){
                R result=new R();
                result.put("personalCollectStatus",collection.getPersonalCollectStatus());
                return result;
            }

        }
        return R.error("用户确认失败");
    }

    private FsPrescribe transformCollectionParamToFsPrescribe(CollectConfirmGeneratePrescribeParam param, FsUserInformationCollection fsUserInformationCollection) {
        //构建处方编号
        String prescribeCode = IdUtil.getSnowflake(0, 0).nextIdStr();
        FsPrescribe fsPrescribe = new FsPrescribe();
        fsPrescribe.setCreateTime(DateUtils.getNowDate());
        fsPrescribe.setStatus(0);//待开方
        fsPrescribe.setDoctorConfirm(0);//未确认
        fsPrescribe.setHistoryAllergic(fsUserInformationCollection.getAllergy());
        fsPrescribe.setPrescribeCode(prescribeCode);
        fsPrescribe.setCollectionId(fsUserInformationCollection.getId());
        fsPrescribe.setUserId(fsUserInformationCollection.getUserId());
        //查询销售绑定医生
        CompanyUser companyUser = companyUserMapper.selectCompanyUserByCompanyUserId(fsUserInformationCollection.getCompanyUserId());
        if (companyUser == null || companyUser.getDoctorId() == null) {
            log.error("销售信息获取异常:" + fsUserInformationCollection.getCompanyUserId());
            throw new CustomException("销售未绑定医生，请稍后再试!");
        }
        Long doctorId = companyUser.getDoctorId();
        fsPrescribe.setDoctorId(doctorId);
        FsDoctor fsDoctor = doctorMapper.selectFsDoctorByDoctorId(doctorId);
        if (fsDoctor == null) {
            log.error("开方医生信息获取异常:" + companyUser.getDoctorId());
            throw new CustomException("网络异常，请稍后再试!");
        }
        fsPrescribe.setPrescribeDoctorId(fsDoctor.getDoctorId());
        fsPrescribe.setPrescribeDoctorSignUrl(fsDoctor.getSignUrl());
        //分配在线的随机药师
        FsDoctor fsDrugDoctor = null;
        try {
            // 使用新写的轮询服务分配药师，传入处方编号
            fsDrugDoctor = pollingAssignDoctorService.getNextPharmacist(prescribeCode);

            fsPrescribe.setDrugDoctorId(fsDrugDoctor.getDoctorId());
            fsPrescribe.setDrugDoctorSignUrl(fsDrugDoctor.getSignUrl());
        } catch (Exception e) {
            log.error("分配药师失败 - 处方号:{}", prescribeCode, e);
            throw new CustomException("网络异常，请稍后再试!");
        }
        //组装处方表里的患者信息
        String birthday = null;
        if (param.getPatientInfo().getBirthday() != null) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            birthday = sdf.format(param.getPatientInfo().getBirthday());
            fsPrescribe.setPatientBirthday(birthday);
            //因为患者信息的身份证号可能是默认的会有问题，这里就只能是用户信息采集的年龄了
            fsPrescribe.setPatientAge(String.valueOf(fsUserInformationCollection.getAge()));
        }
        if (param.getPatientInfo().getWeight()!=null){
            fsPrescribe.setWeight(String.valueOf(param.getPatientInfo().getWeight()));
        }
        fsPrescribe.setPatientId(param.getPatientInfo().getPatientId());
        fsPrescribe.setPatientName(param.getPatientInfo().getPatientName());
        if (param.getPatientInfo().getMobile() != null){
            //存储加密字符串到处方表
            fsPrescribe.setPatientTel(encryptPhone(param.getPatientInfo().getMobile()));
        }
        fsPrescribe.setPatientGender(String.valueOf(param.getPatientInfo().getSex()));
        return fsPrescribe;
    }

    //检测销售代填条件
    private void checkSalesFillCondition(FsUserInformationCollectionParam param) {
        if (param.getFillFlag() != null && param.getFillFlag() == 1 && !getSalesProxyFillConfig()) {
            throw new CustomException("当前不可代填写患者问题信息，请刷新页面后重试");
        }
    }

    /**
     * 根据出生日期计算年龄
     * @param birthday 出生日期，格式：yyyy-MM-dd
     * @return Integer类型的年龄，如果入参无效返回null
     */
    public static Integer calculateAge(String birthday) {
        if (org.apache.commons.lang3.StringUtils.isBlank(birthday)) {
            return null;
        }

        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            sdf.setLenient(false);
            Date birthDate = sdf.parse(birthday);

            Calendar birthCal = Calendar.getInstance();
            birthCal.setTime(birthDate);

            Calendar nowCal = Calendar.getInstance();

            int age = nowCal.get(Calendar.YEAR) - birthCal.get(Calendar.YEAR);

            // 如果今年还没过生日，年龄减1
            if (nowCal.get(Calendar.MONTH) < birthCal.get(Calendar.MONTH) ||
                    (nowCal.get(Calendar.MONTH) == birthCal.get(Calendar.MONTH) &&
                            nowCal.get(Calendar.DAY_OF_MONTH) < birthCal.get(Calendar.DAY_OF_MONTH))) {
                age--;
            }

            return age;

        } catch (ParseException e) {
            throw new CustomException("用户年龄计算异常", 500);
        }
    }

    /**
     * 批量删除用户信息采集
     *
     * @param ids 需要删除的用户信息采集主键
     * @return 结果
     */
    @Override
    public int deleteFsUserInformationCollectionByIds(Long[] ids)
    {
        return baseMapper.deleteFsUserInformationCollectionByIds(ids);
    }

    /**
     * 删除用户信息采集信息
     *
     * @param id 用户信息采集主键
     * @return 结果
     */
    @Override
    public int deleteFsUserInformationCollectionById(Long id)
    {
        return baseMapper.deleteFsUserInformationCollectionById(id);
    }

    @Override
    public FsUserInformationCollectionVO getInfo(FsUserInformationCollection map) {
        FsUserInformationCollectionVO vo = new FsUserInformationCollectionVO();
        Long userId = map.getUserId();
        Long questionId = map.getQuestionId();
        FsUserInformationCollection fsUserInformationCollection = baseMapper.selectByUserId(userId);
        if (fsUserInformationCollection != null) {
            //组装返回数据
            vo.setQuestionId(fsUserInformationCollection.getQuestionId());
            vo.setAge(fsUserInformationCollection.getAge());
            vo.setId(fsUserInformationCollection.getId());
            vo.setAmount(fsUserInformationCollection.getAmount());
            vo.setPackageId(fsUserInformationCollection.getPackageId());
            vo.setPayType(fsUserInformationCollection.getPayType());
            vo.setIsPackage(fsUserInformationCollection.getIsPackage());
            vo.setSex(fsUserInformationCollection.getSex());
            vo.setUserPhoneFour(fsUserInformationCollection.getUserPhoneFour());
            vo.setUserName(fsUserInformationCollection.getUserName());
            vo.setRemark(fsUserInformationCollection.getRemark());
            vo.setAllergy(fsUserInformationCollection.getAllergy());
            boolean salesProxyFill = getSalesProxyFillConfig();
            vo.setIsSalesProxyFill(salesProxyFill);//销售填写权限 false:不可填写 true:可以填写
            if (map.getQuestionId() == null) {
                FsQuestionAndAnswerVO questionAndAnswerVO = questionAndAnswerService.selectFsQuestionAndAnswerById(fsUserInformationCollection.getQuestionId());
                List<AnswerVO> answerVOS = JSON.parseArray(fsUserInformationCollection.getJsonInfo(), AnswerVO.class);
                List<AnswerVO> collect = getAnswerVOs(answerVOS, questionAndAnswerVO.getAnswers());
                vo.setAnswers(collect);
            } else {
                vo.setAnswers(JSON.parseArray(fsUserInformationCollection.getJsonInfo(), AnswerVO.class));
            }
            FsUserInformationCollectionSchedule schedule = scheduleMapper.selectPendingSchedule(fsUserInformationCollection.getId());
            if (schedule != null) {
                vo.setIsShare(1);
            }
        }
        if (questionId != null) {
            vo.setQuestionId(questionId);
            //问答数据
            FsQuestionAndAnswerVO questionAndAnswerVO = questionAndAnswerService.selectFsQuestionAndAnswerById(questionId);
            if (questionAndAnswerVO != null) {
                questionAndAnswerVO.getAnswers().forEach(answerVO -> {
                    answerVO.setFlag(false);
                });
                if (fsUserInformationCollection != null) {
                    vo.getAnswers().addAll(questionAndAnswerVO.getAnswers());
                    vo.setAnswers(getAnswerVOs(vo.getAnswers(),questionAndAnswerVO.getAnswers()));
                } else {
                    //返回问答
                    vo.setAnswers(questionAndAnswerVO.getAnswers());
                }
            }
        }
        if (ObjectUtil.isNotEmpty(vo.getAnswers())){
            vo.getAnswers().forEach(answerVO -> {
                if (answerVO.getSort() == null) {
                    if (answerVO.getTitle().contains("糖尿病")) {
                        answerVO.setSort(1);
                    } else if (answerVO.getTitle().contains("心脑血管")) {
                        answerVO.setSort(2);
                    } else if (answerVO.getTitle().contains("风湿骨病")) {
                        answerVO.setSort(3);
                    } else if (answerVO.getTitle().contains("肝胆")) {
                        answerVO.setSort(4);
                    } else if (answerVO.getTitle().contains("其他")) {
                        answerVO.setSort(5);
                    } else if (answerVO.getTitle().contains("特殊")) {
                        answerVO.setSort(6);
                    }
                }
                if(answerVO.getFlag() == null) {
                    answerVO.setFlag(false);
                }
                if (answerVO.getValue() == null) {
                    answerVO.setValue(new ArrayList<>());
                }
            });
            //有值且为true排前面
//            List<AnswerVO> collect = vo.getAnswers().stream()
//                    .sorted(Comparator.comparing(AnswerVO::getValue, Comparator.nullsFirst(Integer::compareTo)).reversed()).collect(Collectors.toList())
//                    .stream()
//                    .sorted((a,b)-> Boolean.compare(b.getFlag(),a.getFlag())).collect(Collectors.toList());
            //List<AnswerVO> collect = vo.getAnswers().stream()
            //        .sorted(Comparator.comparing(AnswerVO::getValue, Comparator.nullsFirst(List::indexOf)).reversed()).collect(Collectors.toList())
            //        .stream()
            //        .sorted((a,b)-> Boolean.compare(b.getFlag(),a.getFlag())).collect(Collectors.toList());

//            List<AnswerVO> collect = vo.getAnswers().stream()
//                    .sorted(Comparator.comparing(AnswerVO::getSort)).collect(Collectors.toList());
//
//            vo.setAnswers(collect);

            List<AnswerVO> answerList = vo.getAnswers();

            // 1. 收集已有的非空 sort 值
            Set<Integer> usedSorts = answerList.stream()
                    .map(AnswerVO::getSort)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());

            // 2. 为 null 的元素分配不冲突的默认值（从1开始递增）
            int nextDefault = 1;
            for (AnswerVO answer : answerList) {
                if (answer.getSort() == null) {
                    // 找到下一个未使用的最小整数
                    while (usedSorts.contains(nextDefault)) {
                        nextDefault++;
                    }
                    answer.setSort(nextDefault);
                    usedSorts.add(nextDefault); // 标记为已使用
                    nextDefault++; // 继续下一个起始值（可选，也可以不加，但为了效率建议加）
                }
            }

            // 3. 按 sort 升序排序
            List<AnswerVO> collect = answerList.stream()
                    .sorted(Comparator.comparing(AnswerVO::getSort))
                    .collect(Collectors.toList());

            vo.setAnswers(collect);
        }
        return vo;
    }

    @Override
    public List<FsUserInformationCollectionListDVO> selectFsUserInformationCollectionListDVO(FsUserInformationCollectionListDParam param) {
        return fsUserInformationCollectionMapper.selectFsUserInformationCollectionListDVO(param);
    }

    @Override
    public FsUserInformationCollectionVO detail(Long id) {
        FsUserInformationCollectionVO vo = new FsUserInformationCollectionVO();
        FsUserInformationCollection collection = fsUserInformationCollectionMapper.selectFsUserInformationCollectionById(id);
        if (collection != null) {
            vo.setAllergy(collection.getAllergy());
            vo.setRemark(collection.getRemark());
            vo.setAnswers(JSON.parseArray(collection.getJsonInfo(), AnswerVO.class));
            List<AnswerVO> answers = vo.getAnswers();
            if (!CollectionUtils.isEmpty(answers)){
                List<AnswerVO> collect = answers
                        .stream()
                        .filter(answerVO -> !answerVO.getValue().isEmpty())
                        .collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(collect)) {
                    collect.forEach(answerVO -> {
                        List<Integer> value = answerVO.getValue();
                        List<AnswerVO.Options> options = answerVO.getOptions();
                        List<AnswerVO.Options> filterOptions = Lists.newArrayList();
                        for (AnswerVO.Options option : options) {
                            if (value.contains(option.getValue())) {
                                filterOptions.add(option);
                            }
                        }
                        answerVO.setOptions(filterOptions);
                    });
                }
                vo.setAnswers(collect);
            }
        }
        return vo;
    }

    @Override
    public R getWxaCodePackageOrderUnLimit(Long collectionId,String appId) {
        logger.info("生成用户信息采集二维码，请求参数：{}，{}",collectionId,appId);
        FsSysConfig sysConfig = configUtil.getSysConfig();
//
//        final WxMaService wxMaService = WxMaConfiguration.getMaService(sysConfig.getAppid());
        final WxMaService wxMaService = WxMaConfiguration.getMaService(appId);

        String scene="collectionId="+ collectionId ;
        byte[] file;
        try {
            file = wxMaService.getQrcodeService().createWxaCodeUnlimitBytes(
                    scene,
                    "pages_order/confirmUserinfo",
                    true,
                    "release",//release trial
                    430,
                    true,
                    null,
                    false);

            // 上传图片到存储桶
            String suffix = ".png";
            CloudStorageService storage = OSSFactory.build();
            String url;
            try {
                url = storage.uploadSuffix(file, suffix);
            }  catch (Exception e) {
                // 记录错误日志
                logger.error("生成图片失败:{}",e.getMessage(),e);
                return R.error("生成图片失败");
            }
            // 返回成功信息
            return R.ok().put("url",url);

        } catch (WxErrorException e) {
            logger.error(e.getMessage(), e);
            return R.error("微信接口调用失败: " + e.getMessage());
        }
    }

    @Override
    public R getWxaCodePackageOrderUnLimitNew(Long collectionId, String appId) {
        logger.info("生成用户信息采集二维码，请求参数：{}，{}",collectionId,appId);
        FsSysConfig sysConfig = configUtil.getSysConfig();
//
//        final WxMaService wxMaService = WxMaConfiguration.getMaService(sysConfig.getAppid());
        final WxMaService wxMaService = WxMaConfiguration.getMaService(appId);

        String scene="collectionId="+ collectionId ;
        byte[] file;
        try {
            file = wxMaService.getQrcodeService().createWxaCodeUnlimitBytes(
                    scene,
                    "pages_order/confirmUserinfoNew",
                    true,
                    "release",//release trial
                    430,
                    true,
                    null,
                    false);

            // 上传图片到存储桶
            String suffix = ".png";
            CloudStorageService storage = OSSFactory.build();
            String url;
            try {
                url = storage.uploadSuffix(file, suffix);
            }  catch (Exception e) {
                // 记录错误日志
                logger.error("生成图片失败:{}",e.getMessage(),e);
                return R.error("生成图片失败");
            }
            // 返回成功信息
            return R.ok().put("url",url);

        } catch (WxErrorException e) {
            logger.error(e.getMessage(), e);
            return R.error("微信接口调用失败: " + e.getMessage());
        }
    }

    @Override
    public R getCustomerGenerateQRCode(Long orderId, String appId) {
        logger.info("生成客户信息表制单二维码，请求参数：{}，{}",orderId,appId);
        final WxMaService wxMaService = WxMaConfiguration.getMaService(appId);

        String scene="orderId="+ orderId ;
        byte[] file;
        try {
            file = wxMaService.getQrcodeService().createWxaCodeUnlimitBytes(
                    scene,
                    "pages/shopping/paymentOrder",
                    true,
                    "release",
                    430,
                    true,
                    null,
                    false);

            // 上传图片到存储桶
            String suffix = ".png";
            CloudStorageService storage = OSSFactory.build();
            String url;
            try {
                url = storage.uploadSuffix(file, suffix);
            }  catch (Exception e) {
                // 记录错误日志
                logger.error("生成图片失败:{}",e.getMessage(),e);
                return R.error("生成图片失败");
            }
            // 返回成功信息
            return R.ok().put("url",url);

        } catch (WxErrorException e) {
            logger.error(e.getMessage(), e);
            return R.error("微信接口调用失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public R doctorConfirm(FsUserInformationCollection collection) {
        FsUserInformationCollection fsUserInformationCollection = fsUserInformationCollectionMapper.selectFsUserInformationCollectionById(collection.getId());
        if (fsUserInformationCollection == null) {
            return R.error("没有用户采集信息");
        }
        if (fsUserInformationCollection.getUserConfirm() == 0){
            return R.error("用户未确认");
        }
        if (fsUserInformationCollection.getDoctorConfirm() == 1){
            return R.error("医生已确认");
        }
        List<AnswerVO> answerVOS = null;
        //医生确认确认状态为true（用于封档）
        if (StringUtils.isNotEmpty(fsUserInformationCollection.getJsonInfo()) ){
            answerVOS = JSONArray.parseArray(fsUserInformationCollection.getJsonInfo(), AnswerVO.class);
            answerVOS.forEach(answerVO -> {
                answerVO.setFlag(true);
            });
        }
        FsUserInformationCollection map = new FsUserInformationCollection();
        map.setId(collection.getId());
        map.setDoctorAdvice(collection.getDoctorAdvice());
        map.setDoctorConfirm(1);
        //医生确认时间
        map.setDoctorConfirmTime(DateUtils.getNowDate());
        if (answerVOS != null && !answerVOS.isEmpty()) {
            map.setJsonInfo(JSON.toJSONString(answerVOS));
        }
//        if (fsUserInformationCollection.getIsPackage() == 1) {
//            //插入生成处方签定时任务数据
//            if(fsUserInformationCollection.getPackageOrderCode() != null) {
//                //套餐包订单
//                FsPackageOrder fsPackageOrder = packageOrderMapper.selectByOderCode(fsUserInformationCollection.getPackageOrderCode());
//                if (fsPackageOrder != null && fsPackageOrder.getIsPay() == 1) {
//                    //套餐包信息
//                    FsPackage fsPackage = JSON.parseObject(fsPackageOrder.getPackageJson(), FsPackage.class);
//
//                    //套餐包为药品生成处方信息
//                    if(fsPackage != null && (fsPackage.getProductType() == 1 || fsPackage.getProductType() == 2 || fsPackage.getProductType() == 3)) {
//                        FsStoreOrder fsStoreOrder = storeOrderService.selectFsStoreOrderByOrderCode(fsUserInformationCollection.getPackageOrderCode());
//                        if (fsStoreOrder != null && fsStoreOrder.getIsPay() == 1 ) {
//                            if (fsStoreOrder.getPrescribeId() != null) {
////                                FsPrescribeParam fsPrescribeParam = new FsPrescribeParam();
////                                fsPrescribeParam.setPrescribeId(fsStoreOrder.getPrescribeId());
////                                prescribeService.confirmPrescribe(fsPrescribeParam);
//                                prescribeService.collectionPrescribe(fsStoreOrder.getPrescribeId());
//                            }
//                        } else {
//                            throw new CustomException("生成处方信息中......");
//                        }
//                    }
//                }
//            }
//        } else {
//            //没有关联套餐包医生确认清空所有状态
//            map.setUserConfirm2(1);
//        }

        if (fsUserInformationCollectionMapper.updateFsUserInformationCollection(map) > 0) {

            //更新医生确认信息
            FsDoctorConfirm doctorConfirm = redisCache.getCacheObject("doctorConfirm:" + collection.getId());
            if(doctorConfirm == null) {
                return R.error("没有医生确认信息");
            }
            doctorConfirm.setDoctorEndTime(DateUtils.getNowDate());
            Long seconds = DateUtil.between(doctorConfirm.getStartTime(), doctorConfirm.getDoctorEndTime(), DateUnit.SECOND);
            doctorConfirm.setConfirmSecond(seconds);
            doctorConfirmService.updateFsDoctorConfirm(doctorConfirm);
            redisCache.deleteObject("doctorConfirm:" + collection.getId());

            //同步用户信息采集进度
            FsUserInformationCollectionSchedule schedule = scheduleMapper.selectCollectionScheduleByCollectionId(collection.getId());
            if (schedule != null){
                //"待用户二次确认"节点
                schedule.setCurrentStep(PrescriptionTaskStepEnum.WAITING_SECOND_CONFIRM.getCode());
                scheduleMapper.updateFsUserInformationCollectionSchedule(schedule);
                log.info("同步用户信息采集进度节点为:{},信息采集表id:{}",PrescriptionTaskStepEnum.WAITING_SECOND_CONFIRM.getDesc(),schedule.getCollectionId());
            }
            return R.ok();
        }
        return R.error("医生确认失败");
    }

    @Override
    public FsUserInfoCollectionUVO info(Long id,Long userId) {

        FsUserInfoCollectionUVO vo = new FsUserInfoCollectionUVO();
        FsUserInformationCollection collection = fsUserInformationCollectionMapper.selectFsUserInformationCollectionById(id);

        if (collection != null) {

//            if (!Objects.equals(collection.getUserId(), userId)) {
//                return vo;
//            }
            if (collection.getIsPackage() == 1) {
                vo.setPackageId(collection.getPackageId());
                vo.setPayType(collection.getPayType());
                vo.setAmount(collection.getAmount());
                FsPackage fsPackage = new FsPackage();
                FsPackage fsPackage1 = packageMapper.selectFsPackageByPackageId(collection.getPackageId());
                if (fsPackage1 != null) {
                    fsPackage = fsPackage1;
                }
                vo.setFsPackage(fsPackage);
                CompanyUser companyUser = companyUserMapper.selectCompanyUserById(collection.getCompanyUserId());
                if (companyUser == null) {
                    throw new CustomException("销售不存在");
                }
                vo.setCompanyUserId(collection.getCompanyUserId());
                vo.setCompanyId(companyUser.getCompanyId());
                vo.setPackageOrderCode(collection.getPackageOrderCode());
                FsPackageOrder fsPackageOrder = packageOrderMapper.selectByOderCode(collection.getPackageOrderCode());
                if(fsPackageOrder!=null) {
                    vo.setOrderStatus(fsPackageOrder.getIsPay());
                    vo.setOrderId(fsPackageOrder.getOrderId());
                    vo.setPatientJson(fsPackageOrder.getPatientJson());
                    if((fsPackage.getProductType() == 1 || fsPackage.getProductType() == 2 || fsPackage.getProductType() == 3) && fsPackageOrder.getIsPay() == 1) {
                        //套餐包为药品且已支付的查询处方订单拿到处方签
                        FsStoreOrder fsStoreOrder = storeOrderService.selectFsStoreOrderByOrderCode(collection.getPackageOrderCode());
                        if (fsStoreOrder != null) {
                            Long prescribeId = fsStoreOrder.getPrescribeId();
                            FsPrescribe fsPrescribe = fsPrescribeMapper.selectFsPrescribeByPrescribeId(prescribeId);
                            if (fsPrescribe != null) {
                                vo.setPrescribeImgUrl(fsPrescribe.getPrescribeImgUrl());
                                vo.setPrescribeStatus(fsPrescribe.getStatus());
                            }
                        } else {
                            throw new CustomException("没有处方订单");
                        }
                    }
                }
                if (collection.getQwTag()==1){
                    //如果是个微信息采集，需要取个微的处方图片
                    FsUserInformationCollectionPersonalLog collectionPersonalLog = infoCollectionPersonalLogMapper.selectLatestByCollectionId(collection.getId());
                    if (collectionPersonalLog!=null&&collectionPersonalLog.getPrescribeId()!=null){
                        FsPrescribe fsPrescribe = fsPrescribeMapper.selectFsPrescribeByPrescribeId(collectionPersonalLog.getPrescribeId());
                        if (fsPrescribe != null) {
                            vo.setPrescribeImgUrl(fsPrescribe.getPrescribeImgUrl());
                            vo.setPrescribeStatus(fsPrescribe.getStatus());
                        }
                    }
                }
            }
            vo.setQwTag(collection.getQwTag());
            vo.setPersonalCollectStatus(collection.getPersonalCollectStatus());
            vo.setIsPackage(collection.getIsPackage());
            vo.setId(collection.getId());
            vo.setAnswers(JSON.parseArray(collection.getJsonInfo(), AnswerVO.class));
            vo.setStatus(collection.getStatus());
            vo.setUserConfirm(collection.getUserConfirm());
            vo.setUserConfirm2(collection.getUserConfirm2());
            vo.setDoctorConfirm(collection.getDoctorConfirm());
            vo.setUserAdvice(collection.getUserAdvice());
            vo.setDoctorAdvice(collection.getDoctorAdvice());
            vo.setDoctor(doctorMapper.selectFsDoctorByDoctorId(collection.getDoctorId()));
            vo.setAllergy(collection.getAllergy());
            vo.setRemark(collection.getRemark());
            vo.setSex(collection.getSex());
            vo.setUserPhoneFour(collection.getUserPhoneFour());
            vo.setUserName(collection.getUserName());
            vo.setFillTag(collection.getFillFlag());
            vo.setUserId(collection.getUserId());
        }
        return vo;
    }

    @Override
    @Transactional
    public R userConfirm(CollectionInfoConfirmParam param) {

        if (param.getId() == null) {
            return R.error("参数错误");
        }
        FsUserInformationCollection collection = fsUserInformationCollectionMapper.selectFsUserInformationCollectionById(param.getId());
        if (collection == null) {
            return R.error("没有用户采集信息");
        }
        if (collection.getStatus() == 1 ){
            if (collection.getUserConfirm() == 1){
                return R.error("用户已确认");
            }
        }
        if (collection.getStatus() == 2 ){
            if (collection.getUserConfirm2() == 1)
                return R.error("用户已二次确认");
        }
        logger.info("采集信息id:{},采集信息用户id{}，当前登录用户id{}",param.getId(),collection.getUserId(),param.getUserId());
        if (!Objects.equals(collection.getUserId(), param.getUserId())) {
            log.error("当前用户userId:{},信息采集表实际userId:{}",param.getUserId(),collection.getUserId());
            return R.error("用户信息不匹配,无法确认");
        }
        if (collection.getIsPackage() == 1) {
            FsPackage fsPackage = packageMapper.selectFsPackageByPackageId(collection.getPackageId());
            if (fsPackage != null && !(fsPackage.getProductType() == 1 || fsPackage.getProductType() == 2 || fsPackage.getProductType() ==3)) {
                return R.error("该套餐包不支持用户确认");
            }
        }

        FsUserInformationCollection map = new FsUserInformationCollection();
        map.setId(param.getId());
        map.setUserConfirm(1);
        map.setUserAdvice(param.getUserAdvice());
        //用户信息采集表id
        Long collectionId = collection.getId();
        FsUserInformationCollectionSchedule schedule = scheduleMapper.selectCollectionScheduleByCollectionId(collectionId);
        if (schedule != null&&schedule.getStatus() != 1) {
            //没有进行中的进度 抛出提示信息
            return R.error("用户采集信息已更新，请扫描最新二维码确认");
        }
        //支付0元的创建订单就是待开方
        if (schedule != null&&(schedule.getStatus() == 2||schedule.getStatus() == 3) && collection.getAmount().compareTo(new BigDecimal(0))==1) {
            return R.error("用户采集信息已更新，请扫描最新二维码确认");
        }
        Date currentTime=DateUtils.getNowDate();
        if (collection.getStatus() == 1) {
            if (collection.getIsPackage() == 0) {
                //用户第一次确认添加医生消息
                DoctorMsg msg = new DoctorMsg();
                String name = collection.getUserName() != null ? collection.getUserName() : "-";
                //没套餐包的添加医生信息采集建议消息
                msg.setTitle("用户采集信息建议");
                msg.setType(3);
                String companyUserName = companyUserCacheService.selectCompanyUserNameUserById(collection.getCompanyUserId());
                msg.setContent("患者:" + name + "的信息采集，前往建议，来源客服："+companyUserName);
                msg.setDoctorId(collection.getDoctorId());
                msg.setCreateTime(currentTime);
                //插入医生消息
                doctorMsgMapper.insertDoctorMsg(msg);
            }
            //第一次确认
            map.setStatus(2);
            //设置用户信息采集进度节点
            if (schedule != null) {
                if (collection.getIsPackage() == 1 ) {
                    if(collection.getAmount().compareTo(new BigDecimal(0))==1 || collection.getPayType() == 1){
                        //带套餐包的 "待支付"节点
                        schedule.setCurrentStep(PrescriptionTaskStepEnum.WAITING_UN_PAY.getCode());
                        log.info("同步用户信息采集进度节点为:{},信息采集表id:{}",PrescriptionTaskStepEnum.WAITING_UN_PAY.getDesc(),schedule.getCollectionId());
                    }
                } else {
                    //没套餐包的 "待建议"节点
                    schedule.setCurrentStep(PrescriptionTaskStepEnum.WAITING_SUGGESTION.getCode());
                    log.info("同步用户信息采集进度节点为:{},信息采集表id:{}",PrescriptionTaskStepEnum.WAITING_SUGGESTION.getDesc(),schedule.getCollectionId());
                }
            }
        } else if (collection.getStatus() == 2) {
            //第二次确认
            map.setUserConfirm2(1);
            if (collection.getUserConfirm2() == 0 && collection.getIsPackage() == 1) {
                FsStoreOrder fsStoreOrder = storeOrderService.selectFsStoreOrderByOrderCode(collection.getPackageOrderCode());
                if (fsStoreOrder != null) {
                    FsStoreOrder editOrder = new FsStoreOrder();
                    editOrder.setOrderId(fsStoreOrder.getOrderId());
                    editOrder.setIsConfirm(1);
                    storeOrderService.updateFsStoreOrder(editOrder);
                } else {
                    return R.error("没有找到订单");
                }
            }
            //----------同步修改用户信息采集进度----------
            if (schedule != null) {
                //"已完成"任务节点
                schedule.setCurrentStep(PrescriptionTaskStepEnum.WAITING_COMPLETED.getCode());
                //"完成"任务状态
                schedule.setStatus(CollectionTaskStatusEnum.COMPLETED.getCode());
                schedule.setCompletedTime(currentTime);
                log.info("同步用户信息采集进度节点为:{},信息采集表id:{}",PrescriptionTaskStepEnum.WAITING_COMPLETED.getDesc(),schedule.getCollectionId());
            }
        }
        if (fsUserInformationCollectionMapper.updateFsUserInformationCollection(map) > 0) {
            //存入医生确认统计时间数据
            FsDoctorConfirm doctorConfirm = new FsDoctorConfirm();
            doctorConfirm.setCollectionId(collection.getId());
            doctorConfirm.setDoctorId(collection.getDoctorId());
            doctorConfirm.setStartTime(currentTime);
            doctorConfirmService.insertFsDoctorConfirm(doctorConfirm);
            //医生确认时间存入缓存 医生确认后删除
            redisCache.setCacheObject("doctorConfirm:" + collection.getId(), doctorConfirm);
            //----------同步用户信息采集进度----------
            if (schedule != null) {
                scheduleMapper.updateFsUserInformationCollectionSchedule(schedule);
            }
            return R.ok();
        }
        return R.error("用户确认失败");
    }


    @Override
    @Transactional
    public void autoRefund(FsUserInformationCollection collection,Integer operateType) {

        //清空订单号
        fsUserInformationCollectionMapper.collectionOderCodeNULL(collection.getId());

        //更新采集信息状态
        FsUserInformationCollection map = new FsUserInformationCollection();
        map.setId(collection.getId());
        map.setUserConfirm(0);
        map.setUserConfirm2(0);
        map.setStatus(1);
        map.setDoctorConfirm(0);
        map.setFillFlag(0);//填写标识 0:未填写
        //更新用户信息采集状态
        fsUserInformationCollectionMapper.updateFsUserInformationCollection(map);

        //退款操作
        FsStoreOrder fsStoreOrder = storeOrderService.selectFsStoreOrderByOrderCode(collection.getPackageOrderCode());
        if (fsStoreOrder == null) {
            throw new CustomException("没有处方订单");
        }

        //更新处方单信息
        FsStoreOrder mapStoreOrder = new FsStoreOrder();
        mapStoreOrder.setOrderId(fsStoreOrder.getOrderId());
        mapStoreOrder.setStatus(-2);
        mapStoreOrder.setRefundTime(DateUtils.getNowDate());
        storeOrderService.updateFsStoreOrder(mapStoreOrder);

        //退款日志
        String status = null;
        String msg = null;
        if (operateType == 1) {
            CompanyUser companyUser = companyUserMapper.selectCompanyUserById(fsStoreOrder.getCompanyUserId());
            status = FsStoreOrderLogEnum.CUSTOMER_SERVICE_STOP.getValue();
            msg = companyUser.getNickName() + " " + FsStoreOrderLogEnum.CUSTOMER_SERVICE_STOP.getDesc();
        } else if (operateType == 2) {
            FsDoctor doctor = doctorMapper.selectFsDoctorByDoctorId(fsStoreOrder.getDoctorId());
            status = FsStoreOrderLogEnum.DOCTOR_STOP.getValue();
            msg = doctor.getDoctorName() + " " + FsStoreOrderLogEnum.DOCTOR_STOP.getDesc();
        }
        //添加订单日志
        fsStoreOrderLogsService.create(fsStoreOrder.getOrderId(), status,
                msg);

        //订单日志
        FsStoreOrderLogs Logs = new FsStoreOrderLogs();
        Logs.setChangeMessage(FsStoreOrderStatusEnum.REFUND_STATUS_2.getDesc());
        Logs.setOrderId(fsStoreOrder.getOrderId());
        Logs.setChangeTime(new DateTime());
        Logs.setChangeType(FsStoreOrderStatusEnum.REFUND_STATUS_2.getValue().toString());
        fsStoreOrderLogsMapper.insertFsStoreOrderLogs(Logs);

        String orderType = "store";
        Long orderId = fsStoreOrder.getOrderId();
        if (fsStoreOrder.getPackageOrderId() != null) {
            orderType = "package";

            FsPackageOrder fsPackageOrder = packageOrderMapper.selectByOderCode(collection.getPackageOrderCode());
            if (fsPackageOrder == null) {
                throw new CustomException("没有套餐订单");
            }
            orderId = fsStoreOrder.getPackageOrderId();

            //更新套餐单信息
            FsPackageOrder mapPackageOrder = new FsPackageOrder();
            mapPackageOrder.setOrderId(fsPackageOrder.getOrderId());
            mapPackageOrder.setStatus(-2);
            mapPackageOrder.setRefundStatus(2);
            packageOrderMapper.updateFsPackageOrder(fsPackageOrder);
        }

        if (fsStoreOrder.getCompanyId() != null) {
            companyService.refundCompanyMoney(fsStoreOrder);
        }

        //获取支付明细
        List<FsStorePayment> payments = fsStorePaymentMapper.selectFsStorePaymentByPay(2, fsStoreOrder.getOrderId());
        if (fsStoreOrder.getPackageOrderId() != null) {

            payments = fsStorePaymentMapper.selectFsStorePaymentByPay(3, fsStoreOrder.getPackageOrderId());
        }
        if (payments != null && !payments.isEmpty()) {
            FsStorePayment payment = payments.get(0);
            String json = configService.selectConfigByKey("his.pay");
            if (payment.getPayMode().equals("wx")) {
                WxPayConfig payConfig = new WxPayConfig();
                SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
                FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
                payConfig.setAppId(fsPayConfig.getAppId());
                payConfig.setMchId(fsPayConfig.getWxMchId());
                payConfig.setMchKey(fsPayConfig.getWxMchKey());
                payConfig.setKeyPath(wxPayProperties.getKeyPath());
                payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                wxPayService.setConfig(payConfig);
                WxPayRefundRequest refundRequest = new WxPayRefundRequest();
                refundRequest.setOutTradeNo(orderType + "-" + payment.getPayCode());
                refundRequest.setOutRefundNo(orderType + "-" + payment.getPayCode());
                refundRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(payment.getPayMoney().toString()));
                refundRequest.setRefundFee(WxPayUnifiedOrderRequest.yuanToFen(payment.getPayMoney().toString()));
                try {
                    WxPayRefundResult refundResult = wxPayService.refund(refundRequest);
                    WxPayRefundQueryResult refundQueryResult = wxPayService.refundQuery("", refundResult.getOutTradeNo(), refundResult.getOutRefundNo(), refundResult.getRefundId());
                    if (refundQueryResult != null && refundQueryResult.getResultCode().equals("SUCCESS")) {
                        FsStorePayment paymentMap = new FsStorePayment();
                        paymentMap.setPaymentId(payment.getPaymentId());
                        paymentMap.setStatus(-1);
                        paymentMap.setRefundTime(DateUtils.getNowDate());
                        paymentMap.setRefundMoney(payment.getPayMoney());
                        fsStorePaymentMapper.updateFsStorePayment(paymentMap);
                    } else {
                        throw new CustomException("退款请求失败" + refundQueryResult.getReturnMsg());
                    }
                } catch (WxPayException e) {
                    throw new CustomException("退款请求失败" + e.getReturnMsg());
                }
            } else if (payment.getPayMode().equals("yb")) {
                //易宝
                RefundDTO refundDTO = new RefundDTO();
                refundDTO.setRefundMoney(payment.getPayMoney().toString());
                refundDTO.setLowRefundNo(orderType + "-" + payment.getPayCode());
                refundDTO.setUpOrderId(payment.getTradeNo());
                com.fs.ybPay.domain.RefundResult result = payService.refund(refundDTO);
                logger.info("订单退款返回结果:退款订单id:" + orderId + result);
                if (result.getState().equals("5")) {
                    FsStorePayment paymentMap = new FsStorePayment();
                    paymentMap.setPaymentId(payment.getPaymentId());
                    paymentMap.setStatus(-1);
                    paymentMap.setRefundTime(DateUtils.getNowDate());
                    paymentMap.setRefundMoney(payment.getPayMoney());
                    fsStorePaymentMapper.updateFsStorePayment(paymentMap);
                } else {
                    throw new CustomException("退款请求失败" + result.getMessage());
                }
            } else if (payment.getPayMode().equals("tz")) {
                RefundParam tzBankResult = new RefundParam();
                // 使用set方法为对象的字段赋值
                //商户原支付订单号
                tzBankResult.setOldPayOutOrderNo(orderType + payment.getPayCode());
                // 商户退款订单号 对接平台系统里自己生成的退款订单号
                tzBankResult.setRefundOrderNo(orderType + payment.getPayCode());
                // 交易发送时间 yyyyMMddHHmmss
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                tzBankResult.setTrxSendTime(sdf.format(new Date()));
                // 退款金额
                tzBankResult.setRefundOrdTransAmt(payment.getPayMoney().doubleValue());
                TzBankResult<RefundResult> result = tzBankService.refund(tzBankResult);
                logger.info("订单退款返回结果:退款订单id:" + orderId + result);
                if (result.getBody().getRefundOrdStatus().equals("90") || result.getBody().getRefundOrdStatus().equals("60")) {
                    FsStorePayment paymentMap = new FsStorePayment();
                    paymentMap.setPaymentId(payment.getPaymentId());
                    paymentMap.setStatus(-1);
                    paymentMap.setRefundTime(DateUtils.getNowDate());
                    paymentMap.setRefundMoney(payment.getPayMoney());
                    fsStorePaymentMapper.updateFsStorePayment(paymentMap);
                } else {
                    throw new CustomException("退款请求失败" + result.getRetMsg());
                }
            } else if (payment.getPayMode().equals("hf")) {
                if (payment.getIsShare() == 1 && payment.getShareStatus() == 1) {
                    V2TradePaymentDelaytransConfirmrefundRequest confirmRefundRequest = new V2TradePaymentDelaytransConfirmrefundRequest();
                    //Map<String, Object> extendInfoMap = new HashMap<>();
                    String orderCode = OrderCodeUtils.getOrderSn();
                    if (StringUtils.isEmpty(orderCode)) {
                        throw new CustomException("订单生成失败，请重试");
                    }
                    confirmRefundRequest.setReqSeqId(orderCode);
                    confirmRefundRequest.setOrgReqSeqId(payment.getShareCode());
                    confirmRefundRequest.setOrgReqDate(payment.getShareDate());
                    //多汇付使用appID
                    HuifuConfirmrefundResult result = huiFuService.confirmRefund(confirmRefundRequest, null);
                    if (result.getResp_code().equals("00000000") && (result.getTrans_stat().equals("S") || result.getTrans_stat().equals("P"))) {
                        refund(payment, orderType, orderId);
                    } else {
                        throw new CustomException("交易确认退款请求失败" + result.getResp_desc());
                    }
                } else {
                    refund(payment, orderType, orderId);
                }
            }
        } else {
            //处理支付金额是0元的订单
            if (fsStoreOrder.getPayMoney() == null || fsStoreOrder.getPayMoney().compareTo(BigDecimal.ZERO) != 0) {
                throw new CustomException("未找到支付明细");
            }

        }


    }
    private void refund(FsStorePayment payment, String orderType, Long orderId) {
        V2TradePaymentScanpayRefundRequest request = new V2TradePaymentScanpayRefundRequest();
        request.setOrdAmt(payment.getPayMoney().toString());
        request.setOrgReqDate(new SimpleDateFormat("yyyyMMdd").format(payment.getCreateTime()));
        request.setReqSeqId("refund-" + payment.getPayCode());
        request.setAppId(payment.getAppId());
        Map<String, Object> extendInfoMap = new HashMap<>();
        extendInfoMap.put("org_req_seq_id", orderType + "-" + payment.getPayCode());
        request.setExtendInfo(extendInfoMap);
        HuiFuRefundResult refund = huiFuService.refund(request);
        logger.info("订单退款返回结果:退款订单id:" + orderId + refund);
        if ((refund.getResp_code().equals("00000000") || refund.getResp_code().equals("00000100")) && (refund.getTrans_stat().equals("S") || refund.getTrans_stat().equals("P"))) {
            FsStorePayment paymentMap = new FsStorePayment();
            paymentMap.setPaymentId(payment.getPaymentId());
            paymentMap.setStatus(-1);
            paymentMap.setRefundTime(DateUtils.getNowDate());
            paymentMap.setRefundMoney(payment.getPayMoney());
            fsStorePaymentMapper.updateFsStorePayment(paymentMap);
        } else {
            throw new CustomException("退款请求失败" + refund.getResp_desc());
        }
    }
    @Override
    public FsUserInformationCollectionVO getCollectionByUserId(Long userId) {
        FsUserInformationCollectionVO vo = new FsUserInformationCollectionVO();
        FsUserInformationCollection collection = fsUserInformationCollectionMapper.selectFsUserInformationCollectionByUserId(userId);
        if (collection != null) {
            BeanUtils.copyProperties(collection, vo);
            vo.setAnswers(JSON.parseArray(collection.getJsonInfo(), AnswerVO.class));
            //医生建议
            if (collection.getDoctorAdvice() != null){
                vo.setDoctorAdvice(collection.getDoctorAdvice());
            }
        }
        return vo;
    }

    @Override
    public FsUserInformationCollectionVO getCollectionByInfoSourceAndThirdPartyUserId(Integer infoSource,Long thirdPartyUserId) {
        FsUserInformationCollectionVO vo = new FsUserInformationCollectionVO();
        FsUserInformationCollection queryCondition=new FsUserInformationCollection();
        queryCondition.setThirdPartyUserId(thirdPartyUserId);
        queryCondition.setInfoSource(infoSource);
        FsUserInformationCollection collection = fsUserInformationCollectionMapper.getCollectionByInfoSourceAndThirdPartyUserId(queryCondition);
        if (collection != null) {
            BeanUtils.copyProperties(collection, vo);
            vo.setAnswers(JSON.parseArray(collection.getJsonInfo(), AnswerVO.class));
            //医生建议
            if (collection.getDoctorAdvice() != null){
                vo.setDoctorAdvice(collection.getDoctorAdvice());
            }
        }
        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R stopCollection(FsUserInformationCollectionSchedule param, Long operateId,Integer operateType) {
        FsUserInformationCollection collection = fsUserInformationCollectionMapper.selectFsUserInformationCollectionById(param.getCollectionId());
        if (collection == null) {
            return R.error("未找到采集信息");
        }
        if (collection.getStatus() == 2 && collection.getUserConfirm2() == 1) {
            return R.error("用户信息采集已完成，无法取消");
        }
        //清空订单号
        fsUserInformationCollectionMapper.collectionOderCodeNULL(param.getCollectionId());
        //清空信息采集状态
        FsUserInformationCollection map = new FsUserInformationCollection();
        map.setId(param.getCollectionId());
        map.setUserConfirm(0);
        map.setUserConfirm2(0);
        map.setDoctorConfirm(0);
        map.setStatus(1);
        map.setFillFlag(0);//重置为未填写
        if(fsUserInformationCollectionMapper.updateFsUserInformationCollection(map) > 0) {
            //根据采集表id查询信息采集进度信息
            FsUserInformationCollectionSchedule schedule;
            // 有进度id主键就用进度id查询，没有就用采集表id查询
            if (param.getId()!=null){
                schedule=scheduleMapper.selectFsUserInformationCollectionScheduleById(param.getId());
            }else {
                schedule = scheduleMapper.selectCollectionScheduleByCollectionId(param.getCollectionId());
            }
            // "用户采集进度"取消时间
            schedule.setTerminatedTime(DateUtils.getNowDate());
            // "用户采集进度"取消标识
            schedule.setStatus(CollectionTaskStatusEnum.TERMINATED.getCode());
            // "用户采集进度"取消原因
            schedule.setRemark(param.getRemark());
            // "用户采集进度"取消操作人员
            schedule.setTerminatedBy(operateId);
            int result = scheduleMapper.updateFsUserInformationCollectionSchedule(schedule);
            if (StringUtils.isNotBlank(param.getOrderCode())){
                //获取订单信息
                FsStoreOrder fsStoreOrder = storeOrderService.selectFsStoreOrderByOrderCode(param.getOrderCode());
                if (fsStoreOrder != null&&"0".equals(fsStoreOrder.getRefundStatus())&&( fsStoreOrder.getStatus()==2||fsStoreOrder.getStatus()==3)){
                    //如果传入订单号不为空则在取消时需要执行退款操作
                    map.setPackageOrderCode(param.getOrderCode());
                    autoRefund(map,operateType);
                }

            }
            return R.ok();
        }
        return R.error("取消失败");
    }

    @Override
    @Transactional
    public R salesHelpConfirm(Long collectionId, Long operateId) {
        if (collectionId == null) {
            return R.error("参数错误");
        }
        FsUserInformationCollection collection = fsUserInformationCollectionMapper.selectFsUserInformationCollectionById(collectionId);
        if (collection == null) {
            return R.error("未找到采集信息");
        }
        if (collection.getStatus() == 2 && collection.getUserConfirm2() == 1) {
            return R.error("采集信息已二次确认");
        }
        FsUserInformationCollectionSchedule schedule = scheduleMapper.selectSecondConfirmScheduleByCollectionId(collectionId);
        if (schedule == null) {
            return R.error("没有二次确认进度任务");
        }
        //第二次确认
        FsUserInformationCollection editCollection = new FsUserInformationCollection();
        editCollection.setId(collectionId);
        editCollection.setUserConfirm2(1);
        if (collection.getUserConfirm2() == 0 && collection.getIsPackage() == 1) {
            FsStoreOrder fsStoreOrder = storeOrderService.selectFsStoreOrderByOrderCode(collection.getPackageOrderCode());
            if (fsStoreOrder != null) {
                FsStoreOrder editOrder   = new FsStoreOrder();
                editOrder.setOrderId(fsStoreOrder.getOrderId());
                editOrder.setIsConfirm(1);
                storeOrderService.updateFsStoreOrder(editOrder);
            } else {
                return R.error("没有找到订单");
            }
        }
        FsUserInformationCollectionSchedule editSchedule = new FsUserInformationCollectionSchedule();
        //----------同步修改用户信息采集进度----------
        editSchedule.setId(schedule.getId());
        //"已完成"任务节点
        editSchedule.setCurrentStep(PrescriptionTaskStepEnum.WAITING_COMPLETED.getCode());
        //"完成"任务状态
        editSchedule.setStatus(CollectionTaskStatusEnum.COMPLETED.getCode());
        editSchedule.setCompletedTime(DateUtils.getNowDate());
        editSchedule.setTerminatedBy(operateId);
        log.info("同步用户信息采集进度节点为:{},信息采集表id:{}",PrescriptionTaskStepEnum.WAITING_COMPLETED.getDesc(),schedule.getCollectionId());
        if (fsUserInformationCollectionMapper.updateFsUserInformationCollection(editCollection) > 0 && scheduleMapper.updateFsUserInformationCollectionSchedule(editSchedule) > 0) {
            return R.ok();
        }
        return R.error("确认失败");

    }

    @Override
    public List<FsUserInformationCollection> selectFsUserInformationCollectionListByUserIds(List<Long> fsUserIds) {
        if (CollectionUtils.isEmpty(fsUserIds)){
            return Collections.emptyList();
        }
        List<FsUserInformationCollection> resultList=fsUserInformationCollectionMapper.selectFsUserInformationCollectionListByUserIds(fsUserIds);
        if (CollectionUtils.isEmpty(resultList)){
            return Collections.emptyList();
        }
        return resultList;
    }

    @Override
    public void hasUserCollectionInfo(Long userId) {
        FsUserInformationCollection fsUserInformationCollection = fsUserInformationCollectionMapper.selectByUserId(userId);
        if (fsUserInformationCollection != null) {
            throw new CustomException("用户已有信息采集数据");
        }
    }

    @Override
    public R addUserCollection(FsUserInformationCollectionParam param) {
        //用户是否已存在采集信息
        FsUserInformationCollection fsUserInformationCollection = fsUserInformationCollectionMapper.selectByUserId(param.getUserId());
        if (fsUserInformationCollection != null) {
            throw new CustomException("用户已有信息采集数据");
        }
        FsUserInformationCollection collection = new FsUserInformationCollection();
        collection.setUserId(param.getUserId());
        collection.setJsonInfo(JSON.toJSONString(param.getAnswers()));
        collection.setQuestionId(param.getQuestionId());
        collection.setCreateTime(DateUtils.getNowDate());

        int i = fsUserInformationCollectionMapper.insertFsUserInformationCollection(collection);
        if (i > 0) {
            return R.ok();
        }
        return R.error("添加信息采集失败");
    }

    @Override
    public List<FsUserInformationCollectionOverviewVo> selectUserInformationCollectionOverviewByPage(FsUserInformationCollectionOverviewDTO queryDto) {
        queryDto.setQuestionId(10L); // 问答模板为信息采集表类型
        List<FsUserInformationCollectionOverviewVo> resultList = fsUserInformationCollectionMapper.selectUserInformationCollectionOverviewByPage(queryDto);
        if (CollectionUtils.isEmpty(resultList)) {
            return Collections.emptyList();
        }
        return resultList;
    }

    @Override
    public List<FsUserInformationCollectionOverviewVo> selectExportUserInfoCollectionList(FsUserInformationCollectionOverviewDTO queryDto) {
        try {
            List<FsUserInformationCollectionOverviewVo> resultList = this.selectUserInformationCollectionOverviewByPage(queryDto);
            if (CollectionUtils.isEmpty(resultList)) {
                return Collections.emptyList();
            }

            // 收集用户id查询用户处方列表
            List<Long> userIds = resultList.stream()
                    .filter(vo -> vo.getUserId() != null)
                    .map(FsUserInformationCollectionOverviewVo::getUserId)
                    .distinct()
                    .collect(Collectors.toList());

            if (userIds.isEmpty()) {
                return resultList;
            }

            List<FsPrescribe> fsPrescribes = prescribeService.selectFsPrescribeListByUserIds(userIds);

            if (CollectionUtils.isEmpty(fsPrescribes)) {
                for (FsUserInformationCollectionOverviewVo vo : resultList) {
                    vo.setPrescribeImgUrl(Collections.emptyList());
                }
                return resultList;
            }

            // 转成map<userId,List<FsPrescribe>>
            Map<Long, List<FsPrescribe>> userIdPrescribeMap = fsPrescribes.stream()
                    .filter(prescribe -> prescribe.getUserId() != null)
                    .collect(Collectors.groupingBy(FsPrescribe::getUserId));

            // 遍历resultList赋值处方图片列表
            for (FsUserInformationCollectionOverviewVo vo : resultList) {
                if (vo.getUserId() != null) {
                    List<FsPrescribe> userPrescribes = userIdPrescribeMap.get(vo.getUserId());
                    if (userPrescribes != null && !userPrescribes.isEmpty()) {
                        List<String> imgUrlList = userPrescribes.stream()
                                .filter(prescribe -> prescribe.getPrescribeImgUrl() != null)
                                .map(FsPrescribe::getPrescribeImgUrl)
                                .filter(url -> !url.trim().isEmpty())
                                .collect(Collectors.toList());

                        // 使用setPrescribeImgUrl方法，会自动设置prescribeImgUrlString
                        vo.setPrescribeImgUrl(imgUrlList);
                    } else {
                        vo.setPrescribeImgUrl(Collections.emptyList());
                    }
                } else {
                    vo.setPrescribeImgUrl(Collections.emptyList());
                }
            }

            return resultList;
        } catch (Exception e) {
            log.error("导出用户信息采集列表时发生错误", e);
            // 返回基本数据，不包含处方图片信息
            return this.selectUserInformationCollectionOverviewByPage(queryDto);
        }
    }

    @Override
    public R bindUser(CollectionBindUserParam param) {
        //TODO 是否判断销售后续再做
        log.error("-----------------销售id:{}",param.getCompanyUserId());
//        if (param.getCompanyUserId() != null) {
//            return R.error("销售人员无法绑定");
//        }
        if (param.getUserId() == null) {
            return R.error("用户参数错误");
        }
        FsUser fsUser = userService.selectFsUserByUserId(param.getUserId());
        if (fsUser == null) {
            return R.error("用户信息错误");
        }
        FsUserInformationCollection collection = fsUserInformationCollectionMapper.selectFsUserInformationCollectionById(param.getCollectionId());
        if (collection == null) {
            return R.error("未找到信息采集信息");
        }
        if (collection.getUserId() != null) {
            return R.error("信息采集已绑定用户");
        }
        FsUserInformationCollection selectByUserId = fsUserInformationCollectionMapper.selectByUserId(param.getUserId());
        if (selectByUserId != null) {
            //查询此用户是否添加该销售企微好友,未添加提示添加销售
//            QwExternalContact externalContactCondition=new QwExternalContact();
//            externalContactCondition.setFsUserId(param.getUserId());
//            externalContactCondition.setCompanyUserId(selectByUserId.getCompanyUserId());
//            List<QwExternalContact> qwExternalContacts = qwExternalContactMapper.selectQwExternalContactList(externalContactCondition);
//            if (CollectionUtils.isEmpty(qwExternalContacts)){
//                log.error("客户二次提交采集信息,销售与分享客户之间没有企微好友关系,当前销售id:{},当前客户id:{}",selectByUserId.getCompanyUserId(),param.getUserId());
//                throw new CustomException("请添加分享销售企微好友！");
//            }
            if (!selectByUserId.getId().equals(param.getCollectionId())) {
                throw new CustomException("已有信息采集信息！,请联系销售重新分享二维码！");
            }
        }

        FsUserInformationCollection map = new FsUserInformationCollection();
        map.setUserId(param.getUserId());
        map.setId(param.getCollectionId());
        map.setQwTag(1);
        map.setPersonalCollectStatus(PostPayPrescStatusEnum.GENERATE_OPEN_DATA.getCode());//个微信息采集完善状态
        if (fsUserInformationCollectionMapper.updateFsUserInformationCollection(map) > 0) {
            //更新信息采集进度表里面的用户id
            FsUserInformationCollectionSchedule schedule = scheduleMapper.selectCollectionScheduleRunningByCollectionId(param.getCollectionId());
            if (schedule != null&&schedule.getUserId()==null){
                schedule.setUserId(param.getUserId());
                scheduleMapper.updateFsUserInformationCollectionSchedule(schedule);
            }
            return R.ok();
        }
        return R.error("绑定失败");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int submitCollectionAnswerParam(SubmitCollectionAnswerParam param) {
        logger.info("提交问答参数：{}",param);
        FsUserInformationCollection informationCollection = fsUserInformationCollectionMapper.selectFsUserInformationCollectionById(param.getCollectionId());
        if (informationCollection == null) {
            throw new CustomException("用户采集信息不存在");
        }
        //校验填写用户与信息采集信息用户是否一致
        FsUser fsUser = userService.selectFsUserByUserId(param.getUserId());
        if (fsUser == null) {
            log.error("用户信息不存在");
            throw new CustomException("请登录");
        }
        if (!informationCollection.getUserId().equals(param.getUserId())) {
            log.error("信息采集用户信息不一致,当前用户userId:{},信息采集表实际userId:{}", param.getUserId(), informationCollection.getUserId());
            throw new CustomException("用户信息不一致,请检查");
        }
        //根据前端传递的填写结果判断是否更新标识符
        if (informationCollection.getFillFlag() == 0 && !CollectionUtils.isEmpty(param.getAnswers())) {
            param.getAnswers().forEach(answer -> {
                if (answer.getFlag() == null) {
                    answer.setFlag(false);
                }
            });
            informationCollection.setJsonInfo(JSON.toJSONString(param.getAnswers()));
            //设置填写标识
            if (validateRequiredRemarks(param.getAnswers(), informationCollection.getQuestionId())) {
                informationCollection.setFillFlag(1);
                informationCollection.setCompleteStatus(1);
            } else {
                informationCollection.setFillFlag(1);//TODO 这里需要配合前端优化一下改成0
                informationCollection.setCompleteStatus(0);
            }
            int result=fsUserInformationCollectionMapper.updateFsUserInformationCollection(informationCollection);
            if (informationCollection.getQwTag()==0){//企业微信息采集需要记录填写时间
                FsUserInformationCollectionSchedule schedule = scheduleMapper.selectCollectionScheduleRunningByCollectionId(informationCollection.getId());
                if (schedule == null) {
                    throw new CustomException("用户采集信息已更新,请扫描最新二维码确认");
                }
                //设置填写时间
                schedule.setFillTime(DateUtils.getNowDate());
                return scheduleMapper.updateFsUserInformationCollectionSchedule(schedule);
            }else {
                //个微信息采集直接返回更新条数
                return result;
            }

        }
        log.error("采集信息问题提交异常,提交问答参数：{}",param);
        return 1;
    }

    @Override
    public List<FsUserInformationCollectionOverviewVo> getUnBindCollectionList(FsUserInformationCollectionOverviewDTO queryDto) {
        List<FsUserInformationCollectionOverviewVo> resultList=fsUserInformationCollectionMapper.getUnBindCollectionList(queryDto);
        if (CollectionUtils.isEmpty(resultList)){
            return Collections.emptyList();
        }
        return resultList;
    }

    /**
     * 获取销售代填配置
     * @return true: 允许销售代填, false: 不允许销售代填
     */
    @Override
    public boolean getSalesProxyFillConfig() {
        String json = configService.selectConfigByKey("his.salesProxyFill");
        if (StringUtils.isNotEmpty(json)) {
            try {
                JSONObject jsonObject = JSON.parseObject(json);
                return jsonObject.getBooleanValue("isSalesProxyFill");
            } catch (Exception e) {
                log.error("解析销售代填配置失败, json={}", json, e);
            }
        }
        return false; // 默认返回 false
    }

    @Override
    public List<FsUserInformationCollectionOverviewVo> pendingSalesInfoList(PendingSalesInfoQueryDTO pendingSalesInfoQueryDTO) {
        FsUserInformationCollectionOverviewDTO queryDto=new FsUserInformationCollectionOverviewDTO();
        BeanUtils.copyProperties(pendingSalesInfoQueryDTO,queryDto);
        queryDto.setCompleteStatus(0);//未完善信息标识
        PageHelper.startPage(queryDto.getPageNum(), queryDto.getPageSize());
        List<FsUserInformationCollectionOverviewVo> resultList=fsUserInformationCollectionMapper.selectUserInformationCollectionOverviewByPage(queryDto);
        if (CollectionUtils.isEmpty(resultList)){
            return Collections.emptyList();
        }
        return resultList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitSalesInfo(FsUserInformationCollectionParam param) {
        FsUserInformationCollection sourceInfo = fsUserInformationCollectionMapper.selectFsUserInformationCollectionById(param.getId());
        if (sourceInfo == null) {
            log.error("完善采集信息-用户采集信息源不存在");
            throw new CustomException("用户采集信息不存在");
        }
        List<AnswerVO> answers = param.getAnswers();
        sourceInfo.setId(param.getId());
        sourceInfo.setJsonInfo(JSON.toJSONString(answers));
        // 后端校验备注是否完整，返回 false 则未完善
        if (validateRequiredRemarks(answers, sourceInfo.getQuestionId())) {
            sourceInfo.setCompleteStatus(1);
        }else {
            log.error("信息采集id:{}存在必填备注未填写，请完善后再提交", param.getId());//为了不影响业务正常执行这里暂时就不抛异常了
            sourceInfo.setCompleteStatus(0);
        }
        if (sourceInfo.getPrescribeId()!=null){
            //获取这个信息采集对应的处方信息
            FsPrescribe fsPrescribe = fsPrescribeMapper.selectFsPrescribeByPrescribeId(sourceInfo.getPrescribeId());
            if (fsPrescribe!=null){
                if (DEFAULT_PATIENT_NAME.equals(fsPrescribe.getPatientName())){
                    //如果待完善用户的信息采集对应的处方中使用患者名称是"默认就诊人"，则需要更新对应处方中的患者信息
                    fsPrescribe.setPatientBirthday(param.getPatientInfo().getBirthday());
                    fsPrescribe.setPatientId(param.getPatientInfo().getPatientId());
                    fsPrescribe.setPatientName(param.getPatientInfo().getPatientName());
                    if (param.getPatientInfo().getMobile()!=null&&param.getPatientInfo().getMobile().length()==11){
                        //说明传入的是未加密的手机号，则需要加密后再存储
                        fsPrescribe.setPatientTel(encryptPhone(param.getPatientInfo().getMobile()));
                    } else if (param.getPatientInfo().getMobile()!=null&&param.getPatientInfo().getMobile().length()>11) {
                        //说明传入的是加密后的字符串，无需加密直接赋值
                        fsPrescribe.setPatientTel(param.getPatientInfo().getMobile());
                    }

                    fsPrescribe.setPatientGender(param.getPatientInfo().getSex());
                    fsPrescribeMapper.updateFsPrescribe(fsPrescribe);
                }
            }

        }
        fsUserInformationCollectionMapper.updateFsUserInformationCollection(sourceInfo);
    }

    @Override
    public List<FsUserInformationCollectionOverviewVo> fullyCollectionInfoList(FsUserInformationCollectionOverviewDTO queryDto) {
        queryDto.setCompleteStatus(1);//已完善信息标识
        queryDto.setQwTag(1);//个微标识
        PageHelper.startPage(queryDto.getPageNum(), queryDto.getPageSize());
        List<FsUserInformationCollectionOverviewVo> resultList = fsUserInformationCollectionMapper.selectUserInformationCollectionOverviewByPage(queryDto);
        if (CollectionUtils.isEmpty(resultList)) {
            return Collections.emptyList();
        }
        // 填充药师信息（处方对应药师）
        fillPharmacistInfo(resultList);
        return resultList;
    }

    /**
     * 填充结果列表中的药师ID与姓名
     */
    private void fillPharmacistInfo(List<FsUserInformationCollectionOverviewVo> resultList) {
        if (CollectionUtils.isEmpty(resultList)) {
            return;
        }
        // 1. 收集非空的处方ID
        List<Long> prescribeIds = resultList.stream()
                .map(FsUserInformationCollectionOverviewVo::getPrescribeId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        if (prescribeIds.isEmpty()) {
            return;
        }

        // 2. 查询处方表（只需 prescribe_id 和 drug_doctor_id）
        List<FsPrescribe> prescribeList = fsPrescribeMapper.selectFsPrescribeListByPrescribeIds(prescribeIds);
        if (CollectionUtils.isEmpty(prescribeList)) {
            return;
        }

        // 3. 构建 处方ID -> 药师ID 的映射
        Map<Long, Long> prescribeToDoctorIdMap = prescribeList.stream()
                .collect(Collectors.toMap(
                        FsPrescribe::getPrescribeId,
                        FsPrescribe::getDrugDoctorId,
                        (existing, replacement) -> existing
                ));

        // 4. 收集所有药师ID（去重）
        List<Long> doctorIds = prescribeList.stream()
                .map(FsPrescribe::getDrugDoctorId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        if (doctorIds.isEmpty()) {
            return;
        }

        // 5. 批量查询医生（药师）信息
        List<FsDoctor> doctorList = doctorMapper.selectDoctorByIds(doctorIds);
        if (CollectionUtils.isEmpty(doctorList)) {
            return;
        }
        Map<Long, FsDoctor> doctorMap = doctorList.stream()
                .collect(Collectors.toMap(
                        FsDoctor::getDoctorId,
                        Function.identity(),
                        (existing, replacement) -> existing
                ));

        // 6. 回填药师ID与姓名
        resultList.forEach(vo -> {
            Long prescribeId = vo.getPrescribeId();
            if (prescribeId != null) {
                Long doctorId = prescribeToDoctorIdMap.get(prescribeId);
                if (doctorId != null) {
                    vo.setPharmacistId(doctorId.toString()); // 字段类型注意转换
                    FsDoctor doctor = doctorMap.get(doctorId);
                    if (doctor != null) {
                        vo.setPharmacistName(doctor.getDoctorName());
                    }
                }
            }
        });
    }

    @Override
    @Transactional
    public Long bindCollectionPackage(bindCollectionPackageParam param) {
        //校验参数
        FsUserInformationCollection informationCollection = fsUserInformationCollectionMapper.selectFsUserInformationCollectionById(param.getId());
        if (informationCollection == null || informationCollection.getQwTag() == 0 || informationCollection.getCompleteStatus() == 0) {
            log.error("用户信息采集id:{},条件不符", param.getId());
            throw new CustomException("信息采集绑定条件不符合");
        }
        if(informationCollection.getPackageOrderCode()!=null){
            log.error("用户信息采集已有订单,信息采集id:{}", param.getId());
            throw new CustomException("用户已有订单,请清除后再购买");
        }
        //根据信息采集id查询最新处方
        FsPrescribe fsPrescribe = prescribeService.selectNewestAuditedPrescribeByCollectionId(param.getId());
        if (fsPrescribe == null) {
            log.error("用户信息采集id:{},未查询到处方信息", param.getId());
            throw new CustomException("未查询到处方信息");
        }
        //如果查询到了处方信息，则判断该处方是否已被信息采集使用过
        FsUserInformationCollectionPersonalLog infoCollectionPersonalLog = infoCollectionPersonalLogMapper.selectByCollectionIdAndPrescribeId(param.getId(), fsPrescribe.getPrescribeId());
        if (infoCollectionPersonalLog == null) {
            log.error("当前信息采集未找到匹配处方记录,信息采集id:{},处方id:{}", param.getId(), fsPrescribe.getPrescribeId());
            throw new CustomException("流程异常,需要医生开具最新处方才能绑定套餐包！");
        }
        CompanyUser companyUser = companyUserMapper.selectCompanyUserById(informationCollection.getCompanyUserId());
        if (companyUser == null) {
            throw new CustomException("未查询到绑定销售人员");
        }
        FsPackage packageParam = new FsPackage();
        packageParam.setProductJson(param.getProductJson());
        packageParam.setErpType(param.getErpType());
        packageParam.setStoreId(param.getStoreId());
        packageParam.setTotalPrice(param.getTotalPrice());
        //生成套餐包
        Long packageId = packageService.generatePackage(packageParam, param.getGiftProductJson());
//        Long packageId = null;
//        if (param.getPackageIds().size() > 1) {
//            Long mergePackageId = packageService.mergePackage(param.getPackageIds());
//            if (mergePackageId > 0L ) {
//                packageId = mergePackageId;
//            } else {
//                if (mergePackageId == -1L) {
//                    throw new CustomException("套餐包数据错误");
//                } else if (mergePackageId == -2L){
//                    throw new CustomException("ERP类型不相同");
//                }
//            }
//        } else {
//            packageId = param.getPackageIds().get(0);
//        }
        FsPackage fsPackage = packageMapper.selectFsPackageByPackageId(packageId);
        if (fsPackage == null){
            throw new CustomException("套餐包不存在");
        }
        infoCollectionPersonalLog.setPackageId(fsPackage.getPackageId());
        infoCollectionPersonalLog.setPackageName(fsPackage.getPackageName());//套餐包名称
        infoCollectionPersonalLogMapper.updateFsUserInformationCollectionPersonalLog(infoCollectionPersonalLog);
        //套餐包必须是OTC、中药、处方药类型
        if (fsPackage.getProductType() == 1 || fsPackage.getProductType() == 2 || fsPackage.getProductType() == 3) {
            informationCollection.setIsPackage(1);//套餐包标识
            informationCollection.setPackageId(packageId);
            informationCollection.setPayType(param.getPayType());
            informationCollection.setAmount(param.getAmount());
            informationCollection.setPersonalCollectStatus(PostPayPrescStatusEnum.PENDING_SHARE.getCode());
//            String ids = param.getPackageIds().stream().map(String::valueOf).collect(Collectors.joining(","));
//            informationCollection.setPackageIds(ids);
            int result = fsUserInformationCollectionMapper.updateFsUserInformationCollection(informationCollection);
            if (result > 0){
                return informationCollection.getId();
            }
        }
        return 0L;
    }

    @Override
    public FsUserInformationCollection getCollectionPackageInfo(Long collectionId) {
        FsUserInformationCollection queryDto=new FsUserInformationCollection();
        queryDto.setId(collectionId);
        queryDto.setQwTag(1);
        List<FsUserInformationCollection> fsUserInformationCollections = fsUserInformationCollectionMapper.selectFsUserInformationCollectionList(queryDto);
        if (CollectionUtils.isEmpty(fsUserInformationCollections)){
            throw new CustomException("用户信息采集不存在");
        }
        return fsUserInformationCollections.get(0);
    }

    @Transactional
    @Override
    public int resetCIDCollection(Long collectionId,Long operatorId,String nickName) {
        FsUserInformationCollection collection = fsUserInformationCollectionMapper.selectFsUserInformationCollectionById(collectionId);
        if (collection == null) {
            throw new CustomException("信息采集信息错误，重置失败");
        }
        if (collection.getQwTag() == 0) {
            throw new CustomException("企微信息采集无法重置，操作失败");
        }
        if (collection.getPersonalCollectStatus() == 6) {
            //创建的订单取消
            if (StringUtils.isNotEmpty(collection.getPackageOrderCode())) {
                FsPackageOrder fsPackageOrder = packageOrderMapper.selectFsPackageOrderByOrderSn(collection.getPackageOrderCode());
                if (fsPackageOrder != null) {
                    //TODO 是否更新套餐包状态后续再做
                    FsPackageOrder mapOrder = new FsPackageOrder();
                    mapOrder.setOrderId(fsPackageOrder.getOrderId());
                    mapOrder.setStatus(3);
                }
            }
        }

        if (Objects.equals(collection.getPersonalCollectStatus(), PostPayPrescStatusEnum.PENDING_DOCTOR.getCode()) || Objects.equals(collection.getPersonalCollectStatus(), PostPayPrescStatusEnum.PENDING_DRUG_DOCTOR.getCode())) {
            //当流程状态等于待医生开放或者待药师审核在重置时就需要删除对应的处方信息，因为信息采集在开放过程被重置，对应的处方已经无意义了
            if (collection.getPrescribeId() != null){
                fsPrescribeMapper.deleteFsPrescribeByPrescribeId(collection.getPrescribeId());
            }
        }
        //记录操作人
        FsUserInformationCollectionPersonalLog collectionPersonalLog = infoCollectionPersonalLogMapper.selectLatestByCollectionId(collectionId);
        if (collectionPersonalLog != null){
            collectionPersonalLog.setOperatorId(operatorId);
            collectionPersonalLog.setRemark(nickName+":执行重置操作");
        }
        infoCollectionPersonalLogMapper.updateFsUserInformationCollectionPersonalLog(collectionPersonalLog);
        return fsUserInformationCollectionMapper.resetCIDCollection(collectionId);
    }

    @Override
    public List<FsUserInformationCollectionOverviewVo> selectUserInformationCollectionByPhone(String phone) {
        if (StringUtils.isEmpty(phone)){
            throw new CustomException("手机号不能为空");
        }
        List<FsUserInformationCollectionOverviewVo> fsUserInformationCollections =fsUserInformationCollectionMapper.selectFsUserInformationCollectionByPhone(phone);
        if (CollectionUtils.isEmpty(fsUserInformationCollections)){
            return Collections.emptyList();
        }
        return fsUserInformationCollections;
    }

    /**
     * 校验必填备注：对于 open=true 且被勾选的选项，必须填写备注文本
     *
     * @param answers    提交的答案列表
     * @param questionId 问答模板ID
     * @return true 校验通过，false 校验失败
     */
    private boolean validateRequiredRemarks(List<AnswerVO> answers, Long questionId) {
        if (CollectionUtils.isEmpty(answers)) {
            return true;
        }
        // 查询模板数据，获取选项的 open 配置
        FsQuestionAndAnswerVO template = questionAndAnswerService.selectFsQuestionAndAnswerById(questionId);
        if (template == null || CollectionUtils.isEmpty(template.getAnswers())) {
            return true;
        }

        // 构建模板中每个问题下选项的 open 映射：title -> (optionValue -> open)
        Map<String, Map<Integer, Boolean>> openConfigMap = template.getAnswers().stream()
                .collect(Collectors.toMap(
                        AnswerVO::getTitle,
                        ans -> ans.getOptions().stream()
                                .collect(Collectors.toMap(
                                        AnswerVO.Options::getValue,
                                        AnswerVO.Options::isOpen,
                                        (existing, replacement) -> replacement
                                )),
                        (existing, replacement) -> replacement
                ));

        // 遍历提交的答案进行校验
        for (AnswerVO answer : answers) {
            String title = answer.getTitle();

            Map<Integer, Boolean> optionOpenMap = openConfigMap.get(title);
            if (optionOpenMap == null) {
                continue;
            }

            List<Integer> selectedValues = answer.getValue();
            if (CollectionUtils.isEmpty(selectedValues)) {
                continue;
            }

            // 构建已选值的备注映射：optionValue -> remarkText
            Map<Integer, String> remarkMap = new HashMap<>();
            if (answer.getRemarksList() != null) {
                for (AnswerVO.Remarks remark : answer.getRemarksList()) {
                    if (StringUtils.isNotBlank(remark.getText())) {
                        remarkMap.put(remark.getValue(), remark.getText().trim());
                    }
                }
            }

            // 检查每个被选中的、open=true 的选项是否有备注
            for (Integer val : selectedValues) {
                if (Boolean.TRUE.equals(optionOpenMap.get(val))) {
                    String text = remarkMap.get(val);

                    if (StringUtils.isBlank(text)) {
                        return false;
                    }
                }
            }
        }
        return true;
    }

    private List<AnswerVO> getAnswerVOs(List<AnswerVO> target, List<AnswerVO> source) {
        // 1. 先对 target 中的每个 AnswerVO，从 source 中按 title 找到对应的模板，补充 options 的 open 字段
        if (target != null && source != null) {
            // 构建 source 的 title -> AnswerVO 映射
            Map<String, AnswerVO> sourceMap = source.stream()
                    .collect(Collectors.toMap(AnswerVO::getTitle, Function.identity(), (a, b) -> a));

            for (AnswerVO targetAnswer : target) {
                AnswerVO sourceAnswer = sourceMap.get(targetAnswer.getTitle());
                if (sourceAnswer != null) {
                    // 构建 source 中 options 的 value -> open 映射
                    Map<Integer, Boolean> openMap = sourceAnswer.getOptions().stream()
                            .collect(Collectors.toMap(AnswerVO.Options::getValue, AnswerVO.Options::isOpen, (a, b) -> a));

                    // 遍历 target 的 options，设置 open 字段
                    if (targetAnswer.getOptions() != null) {
                        for (AnswerVO.Options opt : targetAnswer.getOptions()) {
                            Boolean open = openMap.get(opt.getValue());
                            if (open != null) {
                                opt.setOpen(open);
                            } else {
                                opt.setOpen(false); // 默认 false
                            }
                        }
                    }
                }
            }
        }

        // 2. 合并列表并去重（保留第一个出现的，即 target 中补全后的数据优先）
        target.addAll(source);
        return target.stream()
                .collect(Collectors.groupingBy(AnswerVO::getTitle))
                .values().stream()
                .map(group -> group.stream().reduce((a, b) -> a).orElse(null))
                .collect(Collectors.toList());
    }
    //这个是备份方法
//    private List<AnswerVO> getAnswerVOs(List<AnswerVO> target,List<AnswerVO> source) {
//        target.addAll(source);
//        return target.stream()
//                .collect(Collectors.groupingBy(AnswerVO::getTitle))
//                .values().stream()
//                .map(group -> group.stream().reduce((a, b) -> a).orElse(null))
//                .collect(Collectors.toList());
//    }

    /**
     * 辅助方法:组装信息采集对象
     * */
    private FsUserInformationCollection buildUserInfoCollection(FsUserInformationCollectionParam param) {
        logger.info("组装FsUserInformationCollection入参companyUserId：{},source:{},fillFlag:{}", param.getCompanyUserId(),param.getSource(),param.getFillFlag());
        FsUserInformationCollection fsUserInformationCollection = new FsUserInformationCollection();

        if (!CollectionUtils.isEmpty(param.getAnswers())) {
            param.getAnswers().forEach(answer -> {
                if (answer.getFlag() == null) {
                    answer.setFlag(false);
                }
            });
        }


        fsUserInformationCollection.setFillFlag(param.getFillFlag());
        fsUserInformationCollection.setJsonInfo(JSON.toJSONString(param.getAnswers()));
        fsUserInformationCollection.setUserId(param.getUserId());
        fsUserInformationCollection.setCompanyUserId(param.getCompanyUserId());
        fsUserInformationCollection.setQuestionId(param.getQuestionId());
        fsUserInformationCollection.setId(param.getId());
        if (param.getIsPackage() != null&&param.getIsPackage() == 1){
            fsUserInformationCollection.setPackageId(param.getPackageId());
        }
        fsUserInformationCollection.setPayType(param.getPayType());
        fsUserInformationCollection.setAmount(param.getAmount());
        fsUserInformationCollection.setIsPackage(param.getIsPackage());
        fsUserInformationCollection.setUserName(param.getUserName());
        fsUserInformationCollection.setUserPhoneFour(param.getUserPhoneFour());
        fsUserInformationCollection.setSex(param.getSex());
        fsUserInformationCollection.setAllergy(param.getAllergy());
        fsUserInformationCollection.setRemark(param.getRemark());
        fsUserInformationCollection.setAge(param.getAge());
        fsUserInformationCollection.setCompanyId(param.getCompanyId());
        fsUserInformationCollection.setCreateTime(DateUtils.getNowDate());

        // 根据销售人员获取医生信息
        CompanyUser companyUser = companyUserMapper.selectCompanyUserById(param.getCompanyUserId());
        if (companyUser == null) {
            throw new CustomException("销售不存在");
        }
        Long doctorId = null;
        if (companyUser.getDoctorId() != null) {
            FsDoctor doctor = doctorMapper.selectFsDoctorByDoctorId(companyUser.getDoctorId());
            if (doctor != null) {
                doctorId = doctor.getDoctorId();
            }
        } else {
            doctorId = iFsDoctorService.selectFsDoctorDoctorByPackage();
        }
        fsUserInformationCollection.setDoctorId(doctorId);

        return fsUserInformationCollection;
    }

    //辅助方法：组装用户信息采集进度对象
    private FsUserInformationCollectionSchedule buildUserInfoSchedule(FsUserInformationCollection param){
        FsUserInformationCollectionSchedule shedule = new FsUserInformationCollectionSchedule();
        shedule.setCollectionId(param.getId());
        shedule.setUserId(param.getUserId());
        shedule.setDoctorId(param.getDoctorId());
        shedule.setCompanyUserId(param.getCompanyUserId());
        shedule.setCompanyId(param.getCompanyId());
        //任务状态:"进行中"
        shedule.setStatus(CollectionTaskStatusEnum.PROCESSING.getCode());
        //当前流程节点:"待用户第一次确认"
        shedule.setCurrentStep(PrescriptionTaskStepEnum.WAITING_FIRST_CONFIRM.getCode());
        Date currentTime = DateUtils.getNowDate();
        shedule.setCreateTime(currentTime);
        if (param.getFillFlag()!=null&& param.getFillFlag() == 1){
            //如果采集信息填写标识为1,就记录一下填写时间
            shedule.setFillTime(currentTime);
        }
        Long packageId = param.getPackageId();
        if (packageId != null&&param.getIsPackage() == 1){
            shedule.setPackageId(packageId);
            FsPackage fsPackage = packageService.selectFsPackageByPackageId(param.getPackageId());
            if (fsPackage != null){
                shedule.setPackageName(fsPackage.getPackageName());
            }
        }
        return shedule;
    }

    /**
     * 辅助方法:组装极速版信息采集对象
     * */
    private FsUserInformationCollection buildFastInfoCollection(FsUserInformationCollectionParam param) {
        FsUserInformationCollection fsUserInformationCollection = new FsUserInformationCollection();

        if (!CollectionUtils.isEmpty(param.getAnswers())) {
            param.getAnswers().forEach(answer -> {
                if (answer.getFlag() == null) {
                    answer.setFlag(false);
                }
            });
        }

        fsUserInformationCollection.setFillFlag(param.getFillFlag());
        fsUserInformationCollection.setJsonInfo(JSON.toJSONString(param.getAnswers()));
        fsUserInformationCollection.setUserId(param.getUserId());
        fsUserInformationCollection.setCompanyUserId(param.getCompanyUserId());
        fsUserInformationCollection.setQuestionId(param.getQuestionId());
        fsUserInformationCollection.setId(param.getId());
        fsUserInformationCollection.setUserName(param.getUserName());
        fsUserInformationCollection.setUserPhoneFour(param.getUserPhoneFour());
        fsUserInformationCollection.setSex(param.getSex());
        fsUserInformationCollection.setAllergy(param.getAllergy());
        fsUserInformationCollection.setRemark(param.getRemark());
        fsUserInformationCollection.setAge(param.getAge());
        fsUserInformationCollection.setCompanyId(param.getCompanyId());
        fsUserInformationCollection.setCreateTime(DateUtils.getNowDate());

        // 根据销售人员获取医生信息
        CompanyUser companyUser = companyUserMapper.selectCompanyUserById(param.getCompanyUserId());
        if (companyUser == null) {
            throw new CustomException("销售不存在");
        }
        Long doctorId = null;
        if (companyUser.getDoctorId() != null) {
            FsDoctor doctor = doctorMapper.selectFsDoctorByDoctorId(companyUser.getDoctorId());
            if (doctor != null) {
                doctorId = doctor.getDoctorId();
            }
        } else {
            doctorId = iFsDoctorService.selectFsDoctorDoctorByPackage();
        }
        fsUserInformationCollection.setDoctorId(doctorId);

        return fsUserInformationCollection;
    }

    public static void main(String[] args) {
//        String str1 = "[{\"options\":[{\"flag\":false,\"name\":\"通天\",\"value\":0},{\"flag\":false,\"name\":\"哈哈\",\"value\":1}],\"title\":\"测试标题1\",\"value\":1},{\"options\":[{\"flag\":false,\"name\":\"呼呼\",\"value\":0},{\"flag\":false,\"name\":\"嘻嘻\",\"value\":1}],\"title\":\"测试标题2\",\"value\":1},{\"options\":[{\"flag\":false,\"name\":\"胸痛\",\"value\":0},{\"flag\":false,\"name\":\"胸闷\",\"value\":1},{\"flag\":false,\"name\":\"头晕\",\"value\":2},{\"flag\":false,\"name\":\"肢体麻木\",\"value\":3},{\"flag\":false,\"name\":\"无\",\"value\":4}],\"title\":\"您目前是否有心脑血管相关症状，如胸痛、胸闷、头晕、肢体麻木等?\",\"value\":1}]";
//        String str2 = "[{\"options\":[{\"flag\":true,\"name\":\"胸痛\",\"value\":0},{\"flag\":true,\"name\":\"胸闷\",\"value\":1},{\"flag\":true,\"name\":\"头晕\",\"value\":2},{\"flag\":true,\"name\":\"肢体麻木\",\"value\":3},{\"flag\":true,\"name\":\"无\",\"value\":4}],\"title\":\"您目前是否有心脑血管相关症状，如胸痛、胸闷、头晕、肢体麻木等?\",\"value\":1},{\"options\":[{\"flag\":false,\"name\":\"胃疼\",\"value\":0},{\"flag\":false,\"name\":\"反酸\",\"value\":1},{\"flag\":false,\"name\":\"恶心\",\"value\":2},{\"flag\":false,\"name\":\"呕吐\",\"value\":3},{\"flag\":false,\"name\":\"黑便\",\"value\":4},{\"flag\":false,\"name\":\"无\",\"value\":5}],\"title\":\"您近期是否出现胃部不适症状，如胃痛、反酸、恶心、呕吐或黑便?\",\"value\":1}]";
//        List<AnswerVO> vo1 = null;
//        List<AnswerVO> vo2 = JSON.parseArray(str2, AnswerVO.class);
//        System.out.println(vo1);
//        System.out.println(vo2);
//        vo2.addAll(vo1);
//        Map<String, List<AnswerVO>> collect = vo2.stream()
//                .collect(Collectors.groupingBy(AnswerVO::getTitle));
//        List<AnswerVO> collect1 = vo2.stream()
//                .collect(Collectors.groupingBy(AnswerVO::getTitle))
//                .values().stream()
//                .map(group -> group.stream().reduce((a, b) -> a).orElse(null)).collect(Collectors.toList());
//        System.out.println(JSON.toJSONString(collect));
//        System.out.println(JSON.toJSONString(collect1));
        boolean contains = "是否有糖尿病相关疾病?".contains("糖尿病");
        System.out.println(calculateAge("1997-04-15"));
    }
}
