phi_platform_user/src/main/java/com/hx/phip/controller/appointment/AppAutoMateController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
phi_platform_user/src/main/java/com/hx/phip/controller/appointment/AppointmentController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
phi_platform_user/src/main/java/com/hx/phip/controller/appointment/CrmSelfController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
phi_platform_user/src/main/java/com/hx/phip/controller/appointment/CrmSelfV2Controller.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
phi_platform_user/src/main/java/com/hx/phip/service/EmployeeService.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
phi_platform_user/src/main/java/com/hx/phip/service/appointment/AppointmentV2Service.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
phi_platform_user/src/main/java/com/hx/phip/service/appointment/impl/AppointmentV2ServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
phi_platform_user/src/main/java/com/hx/phip/service/impl/EmployeeServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
phi_platform_user/src/main/java/com/hx/phip/controller/appointment/AppAutoMateController.java
New file @@ -0,0 +1,760 @@ package com.hx.phip.controller.appointment; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.hx.common.BaseController; import com.hx.exception.TipsException; import com.hx.mybatisTool.SqlSentence; import com.hx.phiappt.common.OperatorConstants; import com.hx.phiappt.common.RoleType; import com.hx.phiappt.constants.tool.appointment.TransferUtil; import com.hx.phiappt.constants.tool.appointment.autoMate.AppAutoMateHandleUtil; import com.hx.phiappt.constants.tool.appointment.autoMate.AppAutoMateV5Util; import com.hx.phiappt.dao.mapper.*; import com.hx.phiappt.model.*; import com.hx.phiappt.vo.ApponintmentVo; import com.hx.phiappt.vo.ProjectVo; import com.hx.phiappt.vo.ShopWorkTimeVo; import com.hx.phiappt.vo.appointment.autoMate.AppAutoMateVo; import com.hx.phip.service.EmployeeRoleService; import com.hx.phip.service.SystemParameterService; import com.hx.resultTool.Result; import com.hx.util.DateUtil; import com.hx.util.StringUtils; import com.hz.his.dto.appointment.AppointmentAutoMateDto; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.*; import java.util.stream.Collectors; /** * author:fhx * Date:2021/3/24 18:43 */ @RestController @RequestMapping("/appointment/autoMate") public class AppAutoMateController extends BaseController { private final Logger logger = LoggerFactory.getLogger(AppAutoMateController.class); @Resource private SystemParameterService systemParameterService; @Resource private EmployeeRoleService employeeRoleService; /** 自动匹配 - 混合项目 */ @RequestMapping("/addApply/blend") public Result addApplyBland(@RequestBody AppointmentAutoMateDto dto) { logger.info("预约自动匹配请求参数:{}", JSONObject.toJSONString(dto)); if(dto.getOpType() == null){ throw new TipsException("操作人类型为空!"); } if(StringUtils.isEmpty(dto.getShopId())) { throw new TipsException("请选择门店"); } Shop shop = commonService.selectOneByKey(ShopMapper.class, dto.getShopId()); if(shop == null) { throw new TipsException("找不到门店"); } if(StringUtils.isEmpty(dto.getUserId())) { throw new TipsException("请选择用户"); } Map<String, Object> values = new HashMap<>(); SqlSentence sqlSentence = new SqlSentence(); sqlSentence.setM(values); StringBuilder sql = new StringBuilder(); values.put("userId", dto.getUserId()); sqlSentence.setSqlSentence(" select u.*, cu.depId as shopId from user u left join corp_user cu on cu.id = u.hisCorpUserId WHERE u.id = #{m.userId} "); User user = commonService.selectOne(UserMapper.class, sqlSentence); if(user == null) { throw new TipsException("找不到用户"); } Employee doctor = null; String doctorId = dto.getDoctorId(); if(!StringUtils.isEmpty(doctorId)) { values.put("id", doctorId); values.put("roleUniqueStr", RoleType.UNIQUE_STR_DOCTOR); sql.setLength(0); sql.append(" select e.*, r.shopId from employee e ") .append(" left join employee_role r on r.employeeId = e.id ") .append(" WHERE e.id = #{m.id} and r.roleUniqueStr = #{m.roleUniqueStr} and e.isDel = 0 ") .append(" group by r.roleUniqueStr "); sqlSentence.setSqlSentence(sql.toString()); doctor = commonService.selectOne(EmployeeMapper.class, sqlSentence); if(doctor == null) { throw new TipsException("找不到医生"); } }else{ doctorId = null; } if(StringUtils.isEmpty(dto.getArriveDate(), dto.getStartTime())) { throw new TipsException("请选择到店日期和时间"); } if(dto.getVisitType() == null) { throw new TipsException("请选择就诊类型"); } if(dto.getAppType() == null) { throw new TipsException("请选择预约类型"); } Integer waitDuration = dto.getWaitDuration(); if(waitDuration == null || waitDuration < 0){ waitDuration = 0; } Integer palsyDuration = dto.getPalsyDuration(); if(palsyDuration == null || palsyDuration < 0){ palsyDuration = 0; } if(dto.getSpecialUser() == null){ dto.setSpecialUser(Appointment.NO); } if(dto.getIsMicApprove() == null){ dto.setIsMicApprove(BaseEntity.NO); } if(dto.getIsSwitch() == null){ dto.setIsSwitch(BaseEntity.NO); } if(dto.getRealMzTime() == null){ dto.setRealMzTime(0); } //推荐匹配数量为空,则默认2 if(dto.getMateNum() == null){ dto.setMateNum(2); } //术前时间 int sqTime = 0; LinkedHashMap<String, ProjectVo> pMap = new LinkedHashMap<>(); Map<String, Integer> pNumMap = new HashMap<>(); Map<String, Integer> pZlMap = new HashMap<>(); List<Project> projectList = new ArrayList<>(); String [] projectIdsArr = null; String [] projectNamesArr = null; int isDevice = 0; //是否再生项目 String zsProjectId = ""; boolean isZsP = false; //是否有非生美项目 boolean isNotSm = false; //复查可以不选项目 if(StringUtils.isEmpty(dto.getProjectJson()) && dto.getAppType() != Appointment.APP_TYPE_REVIEW) { throw new TipsException("请选择项目"); }else { //再生项目逻辑,目前写死一个项目 SystemParameter sp = systemParameterService.selectOneByName(SystemParameter.KEY_CRM_APPOINTMENT_PROJECT_ID); if(sp != null && StringUtils.noNull(sp.getParamValue())){ zsProjectId = sp.getParamValue(); } JSONArray pArr = JSONArray.parseArray(dto.getProjectJson()); int len = pArr.size(); JSONObject temp ; String id ; int num ; Project p ; projectIdsArr = new String[len]; projectNamesArr = new String[len]; for(int i = 0;i < len;i ++) { temp = pArr.getJSONObject(i); id = temp.getString("id"); num = temp.getIntValue("num"); if(StringUtils.isEmpty(id) || num <= 0) { throw new TipsException("请选择正确项目和数量"); } p = commonService.selectOneByKey(ProjectMapper.class, id); if(p == null || p.getIsDel().equals(BaseEntity.YES) || p.getIsUp().equals(BaseEntity.NO)) { throw new TipsException("找不到项目或者项目下架"); } projectList.add(p); pMap.put(id, new ProjectVo(p, num, dto.getShopId())); pNumMap.put(id, num); //判断治疗时间等于0,则默认5分钟 pZlMap.put(id, p.getUseDuration() == null ? 0 : p.getUseDuration()); //获取最大的术前准备时间 if(p.getReadyDuration() > sqTime){ sqTime = p.getReadyDuration(); } projectIdsArr[i] = id; projectNamesArr[i] = p.getName(); if(p.getIsDevice().equals(BaseEntity.YES)){ isDevice++; } if(!isNotSm && p.getIsLifeBeauty().equals(BaseEntity.NO)){ isNotSm = true; } if(zsProjectId.equals(id)){ if(num > 1){ throw new TipsException("再生项目数量不能大于1!"); } isZsP = true; } } } //判断如果包含了再生项目, if(isZsP && projectList.size() > 1){ throw new TipsException("预约项目里面有再生项目,不能和其他项目同时预约!"); } if(isNotSm && StringUtils.isEmpty(doctorId)){ throw new TipsException("预约包含非生美项目,需选择预约医生!"); } ///////////////////////////////////////////////// //逻辑1 //1.通过客户类型和客户等级查询出面诊、沟通、手续时间(默认5分钟) int mzTime = 15; int gtTime = 5; // int sxTime = 5; sql.setLength(0); sql.append(" select * from cure_set_time "); sql.append(" where isDel = #{m.isDel} and appType = #{m.appType} and memberLevelId = #{m.memberLevelId}"); values.put("isDel", BaseEntity.NO); values.put("appType", dto.getAppType()); values.put("memberLevelId", user.getMemberLevelId()); sqlSentence.setSqlSentence(sql.toString()); List<CureSetTime> cList = commonService.selectList(CureSetTimeMapper.class, sqlSentence); if(cList != null && cList.size() > 0){ for(CureSetTime cst : cList){ if(cst.getSetType() == CureSetTime.SET_TYPE_COM){ mzTime = cst.getDuration(); //面诊 } // else if(cst.getSetType() == CureSetTime.SET_TYPE_COMMUNICATE){ // gtTime = cst.getDuration(); //沟通 // } // else if(cst.getSetType() == CureSetTime.SET_TYPE_PROCEDURES){ // sxTime = cst.getDuration(); //手续 // } } } if(mzTime > dto.getRealMzTime()){ waitDuration = 0; } //判断沟通或手续是否为空,不为空就使用传值的 gtTime = dto.getComDuration() != null ? dto.getComDuration() : gtTime; //术前时间(分钟) = 秒 /60 sqTime = sqTime / 60; //2.选择项目的治疗时间 //通过项目id和医生id查询判断是否有对应的医生项目治疗时间 int zlTime = 0; int thisTime ; //医生id不为空 if(!StringUtils.isEmpty(doctorId) && projectIdsArr != null){ sql.setLength(0); sql.append("select * from doctor_project_cure_time where isDel = #{m.isDel} and doctorId = #{m.doctorId} and projectId = #{m.projectId}"); sqlSentence.setSqlSentence(sql.toString()); values.put("doctorId", doctorId); DoctorProjectCureTime ct; for(String projectId : projectIdsArr){ values.put("projectId", projectId); ct = commonService.selectOne(DoctorProjectCureTimeMapper.class, sqlSentence); if(ct != null){ //设定的时间 * 数量 thisTime = ct.getDuration() * pNumMap.get(projectId); }else{ //项目治疗时间(秒) / 60 * 数量 thisTime = (pZlMap.get(projectId) / 60 * pNumMap.get(projectId)); } zlTime += thisTime; pMap.get(projectId).setZlTime(thisTime); } }else{ for(String projectId : projectIdsArr){ //项目治疗时间(秒) / 60 * 数量 thisTime = (pZlMap.get(projectId) / 60 * pNumMap.get(projectId)); zlTime += thisTime; pMap.get(projectId).setZlTime(thisTime); } } //用户操作时,对应个别时间为0 if(dto.getOpType() == OperatorConstants.OP_TYPE_USER){ // mzTime = 0; //默认标准轮匹配的实际面诊时长=系统面诊时长 dto.setRealMzTime(mzTime); gtTime = 0; // sqTime = 0; waitDuration = 0; } //再生项目时,其他时间都为0 else if(isZsP){ mzTime = 0; gtTime = 0; palsyDuration = 0; sqTime = 0; waitDuration = 0; } // //总时长 = 面诊 + 沟通 + 敷麻 + 术前 + 准备等待 + 治疗 // int duration = mzTime + gtTime + palsyDuration + sqTime + waitDuration + zlTime; ////////////////////////////////////////////////////////// //逻辑2 Date st = DateUtil.parseString_1(dto.getArriveDate() + " " + dto.getStartTime() + ":00"); //减去沟通时间 String dayStr = DateUtil.formatDate(st); String projectIds = org.apache.commons.lang3.StringUtils.join(projectIdsArr, ","); String projectNames = org.apache.commons.lang3.StringUtils.join(projectNamesArr, "|"); List<ApponintmentVo> aVoList = new ArrayList<>(); JSONObject json = new JSONObject(); Employee cu = null; //判断操作人是员工时 if(dto.getOpType() == OperatorConstants.OP_TYPE_EMPLOYEE && StringUtils.noNull(dto.getOpRoleId())){ cu = employeeRoleService.selectEmployeeById(dto.getOpRoleId()); } String err; //非MIC、非勾选转疗、且不是用户所属顾问门店的预约,才检查转疗限制逻辑 if(dto.getIsMicApprove() == BaseEntity.NO && dto.getIsSwitch() == BaseEntity.NO && !StringUtils.isEmpty(user.getShopId()) && !dto.getShopId().equals(user.getShopId())){ err = TransferUtil.checkTransferNotAccepted(commonService , user, shop, st, doctor, cu, projectList); if(err != null){ throw new TipsException(err); } //修改为转疗 dto.setIsSwitch(BaseEntity.YES); } //-----迁移到新增/修改预约进行判断 Integer occupySwitch = dto.getIsSwitch(); //检查是否不占用转疗名额 if(BaseEntity.YES.equals(occupySwitch)){ occupySwitch = TransferUtil.checkTransferNotOccupy(commonService , user.getUserLevel(), dto.getShopId() , st, doctorId , cu , projectList); } //非MIC检查下是否符合要求 if(dto.getIsMicApprove() == BaseEntity.NO){ //先检查下对应条件是否符合要求:1项目类型、2门店预约人数、3门店最大转疗人数、4检查设备、5医生预约人数 err = AppAutoMateHandleUtil.checkLimit(commonService, shop, doctorId, st, dayStr, projectIdsArr, dto.getIsSwitch(), occupySwitch, dto.getAptId()); if(!StringUtils.isEmpty(err)) { json.put("list", aVoList); json.put("sqTime", sqTime); json.put("zlTime", zlTime); json.put("mzTime", mzTime); json.put("isSwitch", dto.getIsSwitch()); json.put("occupySwitch", occupySwitch); json.put("errMsg", err); return Result.success(json); } } //处理项目可预约时间 List<Date> canAppList = AppAutoMateHandleUtil.getProjectCanAppTime(commonService, projectList, st); // List<Date> canAppList = null; //医生时间 List<DoctorTime> doctorTimeList = AppAutoMateHandleUtil.selectDoctorTime(commonService, dto.getShopId(), doctorId, dayStr, dto.getAptId()); //过滤出医生的预约占用的特殊用户时间 List<DoctorTime> specialTimeList = new ArrayList<>(); if(dto.getSpecialUser() == Appointment.YES){ specialTimeList = doctorTimeList.stream() .filter(s->s.getSpecialUser() == Appointment.YES && s.getApptType() != DoctorTime.APPT_TYPE_NONE) .collect(Collectors.toList()); } //判断如果是mic通用 if(dto.getIsMicApprove() == BaseEntity.YES){ return Result.success(AppAutoMateHandleUtil.MICList(commonService , aVoList, st, dto.getRealMzTime(), gtTime, palsyDuration , sqTime, zlTime, waitDuration, projectIds, projectNames ,isDevice, dto.getShopId(), dayStr, dto.getAptId(), pMap, specialTimeList)); } //没有医生为全部生美项目 if(StringUtils.isEmpty(doctorId)){ return Result.success(AppAutoMateHandleUtil.SMList(commonService, aVoList, st, dto.getRealMzTime(), gtTime, palsyDuration , sqTime, zlTime, waitDuration, projectIds, projectNames ,isDevice, dto.getShopId(), dayStr, dto.getAptId(), pMap, dto.getIsSwitch(),occupySwitch, canAppList , specialTimeList)); } //查询当天是否有活动日 values.put("shopId", dto.getShopId()); values.put("dayStr", dayStr); sqlSentence.setSqlSentence("select * from activity_day where isDel = #{m.isDel} and shopId = #{m.shopId} and dayStr = #{m.dayStr}"); ActivityDay activityDay = commonService.selectOne(ActivityDayMapper.class, sqlSentence); //门店营业时间 ShopWorkTimeVo shopWorkTimeVo = new ShopWorkTimeVo(shop, dayStr); // //初始日期(存储判断) // String initDayStr = dayStr; // //初始开始时间(如09:00) // String initStartTime = dto.getStartTime(); TreeMap<String, Integer> timeMap = null; // 医生id为空返回门店时间 // if(StringUtils.isEmpty(doctorId)){ // timeMap = AppAutoMateV5Util.shopWorkTimeSet(shopWorkTimeVo); // } //门店特殊时间 List<ShopTime> shopTimeList = AppAutoMateHandleUtil.selectShopTime(commonService, dto.getShopId(), dayStr, dto.getAppType(), user.getUserLevel(), user.getStarLevel()); //时间处理次数:1第一轮医生正常时间、2第二轮医生开头5分钟可预约、3第三轮医生结束5分钟可预约 int handleNum = 1; //向上还是向下:0标准1向下2向上(向下或向上中间可加等待时间) int upOrDown = 0; //按天分隔类型:0不分隔、1上午、2下午 int daySpaceType = dto.isDaySpace() ? 1 : 0; //第一轮匹配 AppAutoMateVo mateData = AppAutoMateHandleUtil.handleTime(commonService, shopWorkTimeVo, activityDay, projectIdsArr, doctorTimeList, shopTimeList , doctorId, dto.getShopId(), handleNum, canAppList); timeMap = mateData.getTimeMap(); err = mateData.getErrMsg(); if(timeMap == null || timeMap.size() <= 0){ throw new TipsException("当前预约医生预约日期无排班时间,无法选择系统推荐时间,请重新选择预约医生"); } //////////////////////////////////////////////////////////////////////// //判断用户选择的时间是否符合 //是否走扣减处理(默认true),即扣减医生上下5分钟逻辑 boolean deductHandle = true; //如果是是再生项目、或预约特殊类型为特殊客户,则不走扣减处理 if(isZsP || dto.getSpecialUser() == Appointment.YES){ deductHandle = false; } ApponintmentVo aVo = null; // ApponintmentVo aVo2 = null; String deviceErr = null; //从医生可用时间里面,拼接出当天最小可以时间 Date minStartTime = DateUtil.parseString_1(dto.getArriveDate() + " " + timeMap.keySet().iterator().next() + ":00"); Date upStratTime = st; Calendar cs = Calendar.getInstance(); //判断是否有项目可预约时间限制 int isCanApp = canAppList == null || canAppList.size() < 2 ? 0 : 1; //查询医生某个时间段有多少治疗数量sql sql.setLength(0); sql.append(" select COUNT(1) from doctor_time where ") .append(" where isDel = 0 and shopId = '").append(dto.getShopId()).append("' ") .append(" and apptType = 2 and timeType in (2, 3) ") .append(" and ( #{m.zlStartTime} BETWEEN startTime and endTime ") .append(" or #{m.zlEndTime} BETWEEN startTime and endTime) "); String doctorTimeAppNumSql = sql.toString(); //超过2个停止循环 while(aVoList.size() < dto.getMateNum() && StringUtils.isEmpty(err)){ //每次匹配都判断一下是否要做上下午时间处理 mateData = AppAutoMateHandleUtil.handleTimeToDaySpace(timeMap, dto.getArriveDate(), daySpaceType, palsyDuration, st); timeMap = mateData.getTimeMap(); st = mateData.getStartTime(); //如果是上下午区分的,时间开始时间要重新获取才能符合上下午时间的分隔 // logger.info("开始时间:{}", DateUtil.formatDate_2(st)); // logger.info("daySpaceType:{}", daySpaceType); // logger.info("upOrDown:{}", upOrDown); // logger.info("handleNum:{}", handleNum); // logger.info("时间:{}", JSONObject.toJSONString(timeMap)); //判断如果时特殊客户预约,且非第一次处理和没有符合的时间,则直接提示不继续处理 if(upOrDown == 0){ //标准轮(使用实际面诊时长) aVo = AppAutoMateV5Util.getAppTimeBlend(timeMap, upStratTime, gtTime, dto.getRealMzTime(), palsyDuration, sqTime, zlTime, waitDuration, pMap, isCanApp); } else if(upOrDown == 1){ //向下匹配预约时间(使用配置的面诊时长) aVo = AppAutoMateV5Util.getAppTimeByDownV2(timeMap, st, gtTime, mzTime, palsyDuration, sqTime, zlTime, 0, 50, pMap, isCanApp); }else if(upOrDown == 2){ //向上匹配预约时间(使用配置的面诊时长) aVo = AppAutoMateV5Util.getAppTimeByUpV2(timeMap, upStratTime, gtTime, mzTime, palsyDuration, sqTime, zlTime, 0, 50, pMap, isCanApp); } //为空,表示当天已经没有时间段可以预约 if(aVo == null && upOrDown != 0) { if (aVoList.size() < dto.getMateNum() && handleNum == 1 && deductHandle) { //第二轮(治疗开始时间+10分钟) handleNum = 2; mateData = AppAutoMateHandleUtil.handleTime(commonService, shopWorkTimeVo, activityDay, projectIdsArr, doctorTimeList, shopTimeList , doctorId, dto.getShopId(), handleNum, canAppList); timeMap = mateData.getTimeMap(); } else if (aVoList.size() < dto.getMateNum() && handleNum == 2 && deductHandle) { //第三轮(治疗结束时间-10分钟) handleNum = 3; mateData = AppAutoMateHandleUtil.handleTime(commonService, shopWorkTimeVo, activityDay, projectIdsArr, doctorTimeList, shopTimeList , doctorId, dto.getShopId(), handleNum, canAppList); timeMap = mateData.getTimeMap(); } //如果是处理到:向上处理+没满足2个+(第三轮后 或 非扣减处理),则跑向下处理(+等待时间) else if(upOrDown == 2 && aVoList.size() < dto.getMateNum() && (handleNum == 3 || !deductHandle)) { //修改向上匹配时间 upOrDown = 1; handleNum = 1; //还原正常时间先 mateData = AppAutoMateHandleUtil.handleTime(commonService, shopWorkTimeVo, activityDay, projectIdsArr, doctorTimeList, shopTimeList , doctorId, dto.getShopId(), handleNum, canAppList); timeMap = mateData.getTimeMap(); // } else if(upOrDown == 2 && handleNum == 3){ } //判断如果上午分隔时间执行完,则进行下午分隔处理 else if(daySpaceType == 1){ daySpaceType = 2; //重置标准匹配时间 upOrDown = 0; handleNum = 1; mateData = AppAutoMateHandleUtil.handleTime(commonService, shopWorkTimeVo, activityDay, projectIdsArr, doctorTimeList, shopTimeList , doctorId, dto.getShopId(), handleNum, canAppList); timeMap = mateData.getTimeMap(); }else { if(StringUtils.isEmpty(err)){ err = mateData.getErrMsg(); } if(StringUtils.isEmpty(err) && dto.getSpecialUser() == Appointment.YES && StringUtils.noNull(doctorId)){ err = "(特殊用户预约)系统匹配不到医生可用时间!"; }else if(StringUtils.isEmpty(err)){ err = deviceErr != null ? deviceErr : "系统匹配不到医生可用时间,或项目有可预约时间限制"; } break; } } else if(aVo != null) { //判断开始时间是否小于门店开始时间 boolean isSmaller = aVo.getStartTime().compareTo(shopWorkTimeVo.getmStartTime()) == -1; deviceErr = null; //判断需不需要设备判断,不需要不检查设备逻辑 if(isDevice > 0){ //检查设备时间 deviceErr = AppAutoMateHandleUtil.checkDevice(commonService, dto.getShopId(), dayStr, aVo, dto.getAptId()); } if(StringUtils.isEmpty(deviceErr) && !isSmaller) { //判断活动日不为空,并且匹配时间不超过活动日时间 if(activityDay != null && aVo.getStartTime().compareTo(activityDay.getStartTime()) > -1 && aVo.getEndTime().compareTo(activityDay.getEndTime()) < 1) { aVo.setActivityDayId(activityDay.getId()); } boolean isCustomerNum=true; if(shop.getSameTimeCustomerNum()!=null &&shop.getSameTimeCustomerNum()>0){ values.put("zlStartTime", aVo.getZlStartTime()); values.put("zlEndTime", aVo.getEndTime()); sqlSentence.setSqlSentence(doctorTimeAppNumSql); int count = commonService.selectCountSql(sqlSentence); logger.info("=====================预约订单自动获取时间===========当前时间段的订单数:"+count); logger.info(DateUtil.formatDate_2(aVo.getZlStartTime())+"=="+DateUtil.formatDate_2(aVo.getEndTime())+"=="+shop.getSameTimeCustomerNum()+"=="+count); if(count>=shop.getSameTimeCustomerNum()){ isCustomerNum=false; } } if(isCustomerNum){ //判断相同向下匹配 if(aVoList.size() > 0) { //遍历判断匹配时间是否重复, boolean isRepeat = false; for(ApponintmentVo apponintmentVo : aVoList){ if( (apponintmentVo.getStartTime().compareTo(aVo.getStartTime()) == 0 && apponintmentVo.getEndTime().compareTo(aVo.getEndTime()) == 0) // || (aVo2.getMzStartTime().compareTo(aVo.getMzStartTime()) == 0 && aVo2.getMzEndTime().compareTo(aVo.getMzEndTime()) == 0) // || (aVo2.getZlStartTime().compareTo(aVo.getZlStartTime()) ==0 && aVo2.getEndTime().compareTo(aVo.getEndTime()) == 0) ){ isRepeat = true; break; } } //不重复则,存储对应可用 if(!isRepeat){ aVo.setHandleNum(handleNum); aVo.setUpOrDown(upOrDown); aVo.setProjectIds(projectIds); aVo.setProjectNames(projectNames); aVo.handleTips(handleNum, upOrDown); aVo.setDaySpaceType(daySpaceType); aVoList.add(aVo); //进入则表示上午已有1个,重置标准匹配下午时间 if(daySpaceType == 1){ daySpaceType = 2; upOrDown = 0; handleNum = 1; mateData = AppAutoMateHandleUtil.handleTime(commonService, shopWorkTimeVo, activityDay, projectIdsArr, doctorTimeList, shopTimeList , doctorId, dto.getShopId(), handleNum, canAppList); timeMap = mateData.getTimeMap(); continue; }else if(daySpaceType == 2){ //如果是下午分隔的可以跳过 break; } }else{ //重复则向下匹配 upOrDown = 1; } }else{ aVo.setHandleNum(handleNum); aVo.setUpOrDown(upOrDown); aVo.setProjectIds(projectIds); aVo.setProjectNames(projectNames); aVo.handleTips(handleNum, upOrDown); aVo.setDaySpaceType(daySpaceType); aVoList.add(aVo); //进入则表示上午已有1个,重置标准匹配下午时间 if(daySpaceType == 1){ daySpaceType = 2; upOrDown = 0; handleNum = 1; mateData = AppAutoMateHandleUtil.handleTime(commonService, shopWorkTimeVo, activityDay, projectIdsArr, doctorTimeList, shopTimeList , doctorId, dto.getShopId(), handleNum, canAppList); timeMap = mateData.getTimeMap(); continue; }else if(daySpaceType == 2){ //如果是下午分隔的可以跳过 break; } } } } //如果检查返回有不符合的条件 if(upOrDown == 1 && aVoList.size() < dto.getMateNum()){ //向下 //已面诊开始时间为开头加5分钟重新判断 cs.setTime(aVo.getMzStartTime()); // cs.setTime(aVo.getEndTime()); cs.add(Calendar.MINUTE, 5); st = cs.getTime(); } // else if(upOrDown == 2 && aVoList.size() == 1){ // break; else if(upOrDown == 2 && aVoList.size() < dto.getMateNum()){ //向上 //已初始向上开始时间为开头减5分钟重新判断 cs.setTime(aVo.getMzStartTime()); cs.add(Calendar.MINUTE, -5); upStratTime = cs.getTime(); // st = cs.getTime(); //开始时间小于医生最小工作时间时 if(upStratTime.compareTo(minStartTime) < 0 ){ upOrDown = 1; handleNum = 1; mateData = AppAutoMateHandleUtil.handleTime(commonService, shopWorkTimeVo, activityDay, projectIdsArr, doctorTimeList, shopTimeList , doctorId, dto.getShopId(), handleNum, canAppList); timeMap = mateData.getTimeMap(); } } // dayStr = DateUtil.formatDate(st); } //判断标准匹配处理 if(upOrDown == 0){ //标准匹配没有跑上下减5分钟逻辑,且还没走到第三轮和走扣减逻辑 if(aVo == null && handleNum < 3 && deductHandle){ if (handleNum == 1 && deductHandle) { //第二轮(治疗开始时间+10分钟) handleNum = 2; mateData = AppAutoMateHandleUtil.handleTime(commonService, shopWorkTimeVo, activityDay, projectIdsArr, doctorTimeList, shopTimeList , doctorId, dto.getShopId(), handleNum, canAppList); timeMap = mateData.getTimeMap(); } else if (handleNum == 2 && deductHandle) { //第二轮(治疗结束时间-10分钟) handleNum = 3; mateData = AppAutoMateHandleUtil.handleTime(commonService, shopWorkTimeVo, activityDay, projectIdsArr, doctorTimeList, shopTimeList , doctorId, dto.getShopId(), handleNum, canAppList); timeMap = mateData.getTimeMap(); } } else { //标准匹配又符合的 或 已走完第三轮 或不走扣减逻辑,则向下匹配重新匹配 upStratTime = aVo != null ? aVo.getMzStartTime() : st; handleNum = 1; upOrDown = 2; mateData = AppAutoMateHandleUtil.handleTime(commonService, shopWorkTimeVo, activityDay, projectIdsArr, doctorTimeList, shopTimeList , doctorId, dto.getShopId(), handleNum, canAppList); timeMap = mateData.getTimeMap(); } } } json.put("list", aVoList); json.put("sqTime", sqTime); json.put("zlTime", zlTime); json.put("mzTime", mzTime); json.put("isSwitch", dto.getIsSwitch()); json.put("occupySwitch", occupySwitch); if(!StringUtils.isEmpty(err)){ json.put("errMsg", err); }else{ json.put("errMsg", deviceErr); } logger.info("预约匹配返回结果:{}", json.toString()); return Result.success(json); } } phi_platform_user/src/main/java/com/hx/phip/controller/appointment/AppointmentController.java
@@ -3,24 +3,29 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.hx.common.BaseController; import com.hx.guide.util.AppointmentListUtil; import com.hx.exception.TipsException; import com.hx.guide.util.CommonQueryUtil; import com.hx.mybatisTool.SqlSentence; import com.hx.phiappt.common.OperatorConstants; import com.hx.phiappt.common.RoleType; import com.hx.phiappt.common.UserStatusConstants; import com.hx.phiappt.constants.tool.appointment.AppAutoMateV5Util; import com.hx.phiappt.constants.tool.appointment.AppointmentTool; import com.hx.phiappt.constants.tool.appointment.TransferUtil; import com.hx.phiappt.dao.mapper.*; import com.hx.phiappt.model.*; import com.hx.phiappt.util.AppointmentV2Util; import com.hx.phiappt.vo.ProjectVo; import com.hx.phiappt.vo.OperatorVo; import com.hx.phip.service.EmployeeRoleService; import com.hx.phip.service.EmployeeService; import com.hx.phip.service.SystemParameterService; import com.hx.phip.service.appointment.AppointmentService; import com.hx.phip.service.appointment.AppointmentV2Service; import com.hx.resultTool.Result; import com.hx.util.DateUtil; import com.hx.util.StringUtils; import com.hz.his.dto.appointment.AppointmentCrmAddDto; import com.platform.exception.PlatTipsException; import com.platform.resultTool.PlatformCode; import com.hz.his.dto.appointment.AppointmentV2Dto; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -33,6 +38,7 @@ * @USER: fhx * @DATE: 2023/7/5 **/ @Slf4j @RestController @RequestMapping("/appointment") public class AppointmentController extends BaseController { @@ -41,238 +47,1075 @@ private AppointmentService appointmentService; @Resource private SystemParameterService systemParameterService; @Resource private AppointmentV2Service appointmentV2Service; @Resource private EmployeeRoleService employeeRoleService; @Resource private EmployeeService employeeService; /** CRM预约 */ @RequestMapping("/crm/app") public Result crmApp(@RequestBody(required = false) AppointmentCrmAddDto dto) { /** 新增预约 */ @RequestMapping("/add") public Result add(@RequestBody AppointmentV2Dto dto) { log.info("新增预约参数:{}", JSONObject.toJSONString(dto)); //获取操作人信息 OperatorVo operatorVo = getOperatorInfo(dto); if (dto == null) { throw new PlatTipsException(PlatformCode.ERROR_TIPS, "请求参数为空!"); if (StringUtils.isEmpty(dto.getShopId())) { throw new TipsException("请选择门店!"); } if(dto.getHandleType() == null){ throw new PlatTipsException(PlatformCode.ERROR_TIPS, "处理类型不能为空!"); if (StringUtils.isEmpty(dto.getUserId())) { throw new TipsException("请选择用户!"); } Appointment appointment = null; //判断处理类型处理类型(1新增2编辑3取消) if(dto.getHandleType() == 2 || dto.getHandleType() == 3){ if(StringUtils.isEmpty(dto.getAppointmentId())){ throw new PlatTipsException(PlatformCode.ERROR_TIPS, "预约标识不能为空!"); } if (StringUtils.isEmpty(dto.getStartTime())) { throw new TipsException("请选择预约时间!"); } appointment = commonService.selectOneByKey(AppointmentMapper.class, dto.getAppointmentId()); if(appointment == null){ throw new PlatTipsException(PlatformCode.ERROR_TIPS, "查询不到预约信息!"); } if (dto.getAddMode() == null) { throw new TipsException("预约方式为空!"); } //如果处理类型为取消,则直接调用取消逻辑然后返回 if(dto.getHandleType() == 3){ appointmentService.cancel(appointment, dto.getRemark(), Appointment.CANCEL_TYPE_CRM_USER, null); return Result.success(); if (dto.getVisitType() == null) { throw new TipsException("请选择就诊类型!"); } if (dto.getAppType() == null) { throw new TipsException("请选择预约类型!"); } if (dto.getIsMicApprove() == BaseEntity.YES){ if(dto.getAddMode() == Appointment.ADD_MODE_ADVISER_V2_3 && StringUtils.isEmpty(dto.getImgUrls())){ throw new TipsException("MIC同意必须选择图片!"); } } if(StringUtils.isEmpty(dto.getUserId())){ throw new PlatTipsException(PlatformCode.ERROR_TIPS, "用户标识为空!"); String corpUserId = StringUtils.isEmpty(dto.getCorpUserId()) ? null : dto.getCorpUserId(); //员工预约时 Employee employee = checkEmployee(operatorVo, corpUserId); Shop shop = commonService.selectOneByKey(ShopMapper.class, dto.getShopId()); if(shop == null) { throw new TipsException("查询不到预约门店信息!"); } if(StringUtils.isEmpty(dto.getShopId())){ throw new PlatTipsException(PlatformCode.ERROR_TIPS, "门店标识为空!"); User user = commonService.selectOneByKey(UserMapper.class, dto.getUserId()); if(user == null) { throw new TipsException("找不到用户"); } if(StringUtils.isEmpty(dto.getDoctorId())){ throw new PlatTipsException(PlatformCode.ERROR_TIPS, "医生标识为空!"); //用户自助预约时,判断使用用户所属顾问为预约顾问 if(dto.getAddMode() == Appointment.ADD_MODE_CRM_SELF && StringUtils.noNull(user.getHisCorpUserId())){ corpUserId = user.getHisCorpUserId(); } if(StringUtils.isEmpty(dto.getStartTime())){ throw new PlatTipsException(PlatformCode.ERROR_TIPS, "开始时间为空!"); } User user = commonService.selectOneByKeyBlob(UserMapper.class, dto.getUserId()); if (user == null) { throw new PlatTipsException(PlatformCode.ERROR_TIPS, "找不到用户信息!"); } Shop shop = commonService.selectOneByKeyBlob(ShopMapper.class, dto.getShopId()); if (shop == null) { throw new PlatTipsException(PlatformCode.ERROR_TIPS, "找不到门店信息!"); } Employee employee = commonService.selectOneByKeyBlob(EmployeeMapper.class, dto.getShopId()); if (shop == null) { throw new PlatTipsException(PlatformCode.ERROR_TIPS, "找不到医生信息!"); } //目前写死一个项目 SystemParameter sp = systemParameterService.selectOneByName(SystemParameter.KEY_CRM_APPOINTMENT_PROJECT_ID); if(sp == null || StringUtils.isEmpty(sp.getParamValue())){ throw new PlatTipsException(PlatformCode.ERROR_TIPS, "还未配置项目信息!"); } Project project = commonService.selectOneByKey(ProjectMapper.class, sp.getParamValue()); if(project == null){ throw new PlatTipsException(PlatformCode.ERROR_TIPS, "找不到项目信息!"); } if(project == null || project.getIsDel() == BaseEntity.YES || project.getIsUp() == BaseEntity.NO) String doctorId = dto.getDoctorId(); if(!StringUtils.isEmpty(doctorId) && !"null".equals(doctorId)) { throw new PlatTipsException(PlatformCode.ERROR_TIPS, "找不到项目或者项目下架!"); Employee doctor = employeeService.selectOneByIdAndRole(doctorId, RoleType.UNIQUE_STR_DOCTOR); if(doctor == null) throw new TipsException("找不到医生"); }else{ doctorId = null; } //组装json数组 JSONArray arr = new JSONArray(); JSONObject temp = new JSONObject(); temp.put("id", project.getId()); temp.put("num", 1); temp.put("isLifeBeauty", project.getIsLifeBeauty()); temp.put("name", project.getName()); temp.put("palsyDuration", project.getPalsyDuration()); temp.put("isPalsy", project.getPalsyDuration() > 0 ? 1 : 0); temp.put("useDuration", project.getUseDuration()); arr.add(temp); if(dto.getSpecialUser() == null) { dto.setSpecialUser(BaseEntity.NO); } String [] projectIdsArr = new String[arr.size()]; String [] projectNamesArr = new String[arr.size()]; Map<String, Integer> pNumMap = new HashMap<>(); Map<String, Integer> pZlMap = new HashMap<>(); String id = null; int num = 0; int zlTime = 0; if(dto.getIsSwitch() == null) { dto.setIsSwitch(BaseEntity.NO); } if(dto.getObeyDoctor() == null) { dto.setObeyDoctor(BaseEntity.NO); } List<AppointmentProject> apList = new ArrayList<>(); LinkedHashMap<String, ProjectVo> pMap = new LinkedHashMap<>(); for(int i = 0; i < arr.size(); i ++) if(dto.getObeyTime() == null) { dto.setObeyTime(BaseEntity.NO); } if(dto.getIsSendMsg() == null) { dto.setIsSendMsg(BaseEntity.NO); } if(dto.getIsArriveSendMsg() == null) { dto.setIsArriveSendMsg(BaseEntity.NO); } if(dto.getWaitTime() == null) { dto.setWaitTime(BaseEntity.NO); } if(dto.getGtTime() == null || dto.getMzTime() == null || dto.getMfTime() == null || dto.getSqTime() == null || dto.getZlTime() == null || dto.getWaitTime() == null || dto.getGtTime() < 0 || dto.getMzTime() < 0 || dto.getMfTime() < 0 || dto.getSqTime() < 0 || dto.getZlTime() < 0 || dto.getWaitTime() < 0) { temp = arr.getJSONObject(i); id = temp.getString("id"); num = temp.getIntValue("num"); if(StringUtils.isEmpty(id) || num <= 0) { throw new PlatTipsException(PlatformCode.ERROR_TIPS, "请选择正确项目和数量"); throw new TipsException("请填写正确的沟通时间、面诊时间、麻敷时间、术前准备时间、治疗准备开始时间、治疗时间"); } Integer duration = dto.getGtTime() + dto.getMzTime() + dto.getMfTime() + dto.getSqTime() + dto.getZlTime() + dto.getWaitTime(); Date st = DateUtil.parseString(dto.getStartTime(), "yyyy-MM-dd HH:mm:ss"); Date et = DateUtil.parseString(dto.getEndTime(), "yyyy-MM-dd HH:mm:ss"); //结束时间为空则根据总时长算出来 if(et == null){ Calendar ca = Calendar.getInstance(); ca.setTime(st); ca.add(Calendar.MINUTE, duration); et = ca.getTime(); } //检测用户创建预约 checkUserAdd(dto.getAddMode(), dto.getDoctorId(), st, et); //预约关联项目 List<Project> projectList = new ArrayList<>(); List<AppointmentProject> apList = getAppointmentProjectList(dto, projectList); //医生限制数量校验 AppointmentTool.doctorLimitPreNumCheck(dto.getShopId(),null,doctorId,st,commonService); //检测非繁忙项目 int rulePreType = AppointmentTool.preProjectNonBusy(dto.getShopId(),null,st, projectList,null,commonService); //检查是否不占用转疗名额 Integer occupySwitch = dto.getIsSwitch(); if(BaseEntity.YES.equals(occupySwitch)){ occupySwitch = TransferUtil.checkTransferNotOccupy(commonService , user.getUserLevel(), dto.getShopId() , st, doctorId, employee , projectList); } Map<String, Object> map = new HashMap<>(); SqlSentence sqlSentence = new SqlSentence(); sqlSentence.setM(map); String dayStr = DateUtil.formatDate(st); Appointment appointment = new Appointment(); appointment.setShopId(dto.getShopId()); appointment.setCorpUserId(corpUserId); appointment.setDoctorId(doctorId); appointment.setObeyDoctor(dto.getObeyDoctor()); appointment.setUserId(dto.getUserId()); appointment.setStartTime(st); appointment.setEndTime(et); appointment.setDuration(duration); appointment.setVisitType(dto.getVisitType()); appointment.setAppType(dto.getAppType()); appointment.setComDuration(dto.getGtTime()); appointment.setDocComDuration(dto.getMzTime()); appointment.setReadyDuration(dto.getSqTime()); appointment.setProDuration(0); appointment.setPalsyDuration(dto.getMfTime()); appointment.setTreatDuration(dto.getZlTime()); appointment.setRemark(dto.getRemark()); appointment.setObeyTime(dto.getObeyTime()); appointment.setSpecialUser(dto.getSpecialUser()); appointment.setOccupySwitch(occupySwitch); appointment.setRulePreType(rulePreType); appointment.setDayStr(dayStr); appointment.setMonthStr(dayStr.substring(0, 6)); appointment.setIsSwitch(dto.getIsSwitch()); appointment.setIsAnaesthesia(dto.getMfTime() > 0 ? BaseEntity.YES : BaseEntity.NO); appointment.setIsMicApprove(dto.getIsMicApprove()); //新创建人信息 appointment.setCreateManId(operatorVo.getOpId()); appointment.setCreateManName(operatorVo.getOpName()); if(operatorVo.getOpType() == OperatorConstants.OP_TYPE_EMPLOYEE){ appointment.setCreateManType(Appointment.CREATE_MAN_TYPE_EMPLOYEE); appointment.setCreateCorpUserId(operatorVo.getOpId()); appointment.setCreateRoleId(operatorVo.getOpRoleId()); appointment.setCreateRoleStr(operatorVo.getRoleStr()); }else if(operatorVo.getOpType() == OperatorConstants.OP_TYPE_USER){ appointment.setCreateManType(Appointment.CREATE_MAN_TYPE_USER); }else { appointment.setCreateManType(Appointment.CREATE_MAN_TYPE_UNKNOWN); } appointment.setImgUrls(dto.getImgUrls()); appointment.setProjectIds(dto.getProjectIds()); appointment.setProjectNames(dto.getProjectNames()); appointment.setProjectJson(dto.getProjectJson()); appointment.setStatus(Appointment.STATUS_WAIT); appointment.setActivityDayId(dto.getActivityDayId()); appointment.setIsSendMsg(dto.getIsSendMsg()); appointment.setIsArriveSendMsg(dto.getIsArriveSendMsg()); //标记预约的新增模式 appointment.setAddMode(dto.getAddMode()); //多余的等待时间 appointment.setWaitDuration(dto.getWaitTime()); //医生治疗时间 appointment.setDoctorZlDuration(dto.getDoctorZlTime()); //判断 预约所属顾问是否为空 为空则为预分诊预约,不为空则为普通预约 if(StringUtils.isEmpty(corpUserId)){ appointment.setIsPretriage(BaseEntity.YES); } //周,取当前周一 appointment.setWeekStr(DateUtil.formatDate(getWeekDate(st))); //预约冲突原因 appointment.setConflictReason(dto.getConflictReason()); //处理预约状态和是否转疗逻辑 handleStatusAndIsSwitch(dto.getAddMode(), appointment, shop, employee, false, null); //获取设备相关数据 List<AppointmentProjectDeviceNo> apdnList = new ArrayList<>(); List<DeviceNoSchedule> dnsList = AppointmentV2Util.handleDeviceTime(dto.getDeviceTimeJson(), apdnList); //治疗开始时间 Calendar ca = Calendar.getInstance(); ca.setTime(st); ca.add(Calendar.MINUTE, duration - appointment.getTreatDuration()); Date treatSt = ca.getTime(); //获取出医生的治疗时间记录 List<DoctorTime> doctorTimeList = null; //后台预约时,zlTimeJson没有对应的开始结束时间,所以要特殊处理 if(dto.getAddMode() == Appointment.ADD_MODE_BACKSTAGE_V2_3){ List<Integer> doctorZlTime = new ArrayList<>(); doctorZlTime.add(0); net.sf.json.JSONArray newZlTimeJson = new net.sf.json.JSONArray(); doctorTimeList = AppointmentV2Util.getDoctorZlTime(dto.getZlTimeJson(), treatSt , doctorId, dto.getShopId(), dayStr , appointment.getMonthStr(), doctorZlTime , newZlTimeJson, dnsList); appointment.setDoctorZlDuration(doctorZlTime.get(0)); }else{ doctorTimeList = AppointmentV2Util.getDoctorZlTime(dto.getZlTimeJson(), dto.getShopId(), doctorId, dayStr, dayStr.substring(0, 6)); } AppointmentInfo appointmentInfo = new AppointmentInfo(); appointmentInfo.setZlTimeJson(dto.getZlTimeJson()); appointmentInfo.setDeviceTimeJson(dto.getDeviceTimeJson()); appointmentInfo.setAutoTimeType(dto.getHandleNum()); appointmentInfo.setMealsRemark(dto.getMealsRemark()); if(!StringUtils.isEmpty(dto.getBirthday())){ appointmentInfo.setBirthday(DateUtil.parseString_2(dto.getBirthday())); } //填充冗余用户状态 appointmentInfo.setUserStatus(user.getUserStatus()); appointmentInfo.setUserStatusCn(UserStatusConstants.getName(user.getUserStatus())); appointmentInfo.setUserInternetCorpUserId(user.getInternetCorpUserId()); appointmentInfo.setUserInternetCorpUserName(CommonQueryUtil.getEmployeeName(user.getInternetCorpUserId(), commonService)); appointmentInfo.setUserConsultantId(user.getHisCorpUserId()); appointmentInfo.setUserConsultantName(CommonQueryUtil.getEmployeeName(user.getHisCorpUserId(), commonService)); appointmentInfo.setUserShopId(user.getShopId()); appointmentInfo.setUserShopName(CommonQueryUtil.getShopName(user.getShopId(), commonService)); appointmentInfo.setUserLevel(user.getUserLevel()); appointmentInfo.setMemberLevelId(user.getMemberLevelId()); //添加预约 appointmentV2Service.add(operatorVo, user, appointment, appointmentInfo, apList, apdnList, doctorTimeList, dnsList); JSONObject obj = new JSONObject(); obj.put("id", appointment.getId()); return Result.success(obj); } /** 编辑预约 */ @RequestMapping("/edit") public Result edit(@RequestBody AppointmentV2Dto dto) { log.info("编辑预约参数:{}", JSONObject.toJSONString(dto)); //获取操作人信息 OperatorVo operatorVo = getOperatorInfo(dto); if(StringUtils.isEmpty(dto.getId())) { throw new TipsException("预约标识为空!"); } if (dto.getAddMode() == null) { throw new TipsException("预约方式为空!"); } Appointment appointment = commonService.selectOneByKey(AppointmentMapper.class, dto.getId()); if(appointment == null) { throw new TipsException("查询不到预约信息!"); } appointment.setOrStartTime(appointment.getStartTime()); if(appointment.getAddMode() == Appointment.ADD_MODE_CRM_SELF){ throw new TipsException("用户自助预约无法编辑!"); } AppointmentInfo appointmentInfo = appointmentV2Service.selectOneByApptId(appointment.getId()); if(appointmentInfo == null){ throw new TipsException("查询不到预约其他信息!"); } User user = commonService.selectOneByKey(UserMapper.class, appointment.getUserId()); if(user == null){ throw new TipsException("查询不到预约用户信息!"); } //复制一个旧预约信息对象 Appointment oldInfo = new Appointment(); BeanUtils.copyProperties(appointment, oldInfo); //顾问或顾问助理,才判断所属顾问id不能为空 String corpUserId = StringUtils.isEmpty(dto.getCorpUserId()) ? null : dto.getCorpUserId(); Employee employee = checkEmployee(operatorVo, corpUserId); if(oldInfo.getStatus() == Appointment.STATUS_CANCEL) { throw new TipsException("已取消的预约不能修改!"); } if(oldInfo.getCancelStatus() == Appointment.CANCEL_STATUS_APPLY) { throw new TipsException("申请取消中的预约不能修改!"); } if(oldInfo.getStatus() == Appointment.STATUS_SUC && oldInfo.getIsArrive() == BaseEntity.YES) { throw new TipsException("已到店的预约不能修改!"); } if(StringUtils.isEmpty(dto.getStartTime())) { throw new TipsException("请选择预约时间!"); } Date st = DateUtil.parseString_1(dto.getStartTime()); if(st == null) { throw new TipsException("请选择预约时间!"); } if(dto.getAppType() == null) { throw new TipsException("请选择预约类型!"); } if(dto.getGtTime() == null || dto.getMzTime() == null || dto.getMfTime() == null || dto.getSqTime() == null || dto.getZlTime() == null || dto.getWaitTime() == null || dto.getGtTime() < 0 || dto.getMzTime() < 0 || dto.getMfTime() < 0 || dto.getSqTime() < 0 || dto.getZlTime() < 0 || dto.getWaitTime() < 0) { throw new TipsException("请填写正确的沟通时间、面诊时间、麻敷时间、术前准备时间、治疗准备开始时间、治疗时间!"); } //自动计算预约时长 Integer duration = dto.getGtTime() + dto.getMzTime() + dto.getMfTime() + dto.getSqTime() + dto.getZlTime() + dto.getWaitTime(); //把传过来的时间减去沟通时间 Calendar calendar = Calendar.getInstance(); calendar.setTime(st); Calendar ca = Calendar.getInstance(); ca.setTime(st); ca.add(Calendar.MINUTE, duration); Date et = ca.getTime(); if(StringUtils.noNull(dto.getShopId())) { appointment.setShopId(dto.getShopId()); } Shop shop = commonService.selectOneByKey(ShopMapper.class, appointment.getShopId()); if(shop == null){ throw new TipsException("查询不到预约门店信息!"); } if(dto.getSpecialUser() != null){ appointment.setSpecialUser(dto.getSpecialUser()); } if(dto.getRealComDuration() != null) { appointment.setRealComDuration(dto.getRealComDuration()); } if(dto.getRealDocComDuration() != null) { appointment.setRealDocComDuration(dto.getRealDocComDuration()); } if(dto.getRealDuration() != null) { appointment.setRealDuration(dto.getRealDuration()); } if(dto.getRealProDuration() != null) { appointment.setRealProDuration(dto.getRealProDuration()); } if(dto.getRealTreatDuration() != null) { appointment.setRealTreatDuration(dto.getRealTreatDuration()); } if(dto.getRealReadyDuration() != null) { appointment.setRealReadyDuration(dto.getRealReadyDuration()); } if(dto.getRealWaitDuration() != null){ appointment.setRealWaitDuration(dto.getRealWaitDuration()); } if(dto.getRealPalsyDuration() != null){ appointment.setRealPalsyDuration(dto.getRealPalsyDuration()); } if(dto.getIsArrive() != null) { appointment.setIsArrive(dto.getIsArrive()); } if(dto.getIsMicApprove() != null){ appointment.setIsMicApprove(dto.getIsMicApprove()); } //HIS助手编辑 if (dto.getAddMode() == Appointment.ADD_MODE_ADVISER_V2_3 && appointment.getIsMicApprove() == BaseEntity.YES && StringUtils.isEmpty(dto.getImgUrls())){ throw new TipsException("MIC同意必须选择图片!"); } if(StringUtils.noNull(dto.getImgUrls())){ appointment.setImgUrls(dto.getImgUrls()); } if(dto.getObeyDoctor() != null){ appointment.setObeyDoctor(dto.getObeyDoctor()); } if(dto.getObeyTime() != null){ appointment.setObeyTime(dto.getObeyTime()); } if(appointment.getIsArrive() == BaseEntity.YES && oldInfo.getIsArrive() == BaseEntity.NO) { if (oldInfo.getStatus() != Appointment.STATUS_SUC || oldInfo.getCancelStatus() == Appointment.CANCEL_STATUS_APPLY) { throw new TipsException("该预约非确认状态或者申请取消中!"); } project = commonService.selectOneByKey(ProjectMapper.class, id); if(project == null || project.getIsDel() == BaseEntity.YES || project.getIsUp() == BaseEntity.NO) { throw new PlatTipsException(PlatformCode.ERROR_TIPS, "找不到项目或者项目下架"); } // //获取最大的术前准备时间 // if(project.getReadyDuration() > sqTime){ // sqTime = project.getReadyDuration(); } if(dto.getIsSwitch() != null) { appointment.setIsSwitch(dto.getIsSwitch()); } if(StringUtils.noNull(dto.getVisitType())) { appointment.setVisitType(dto.getVisitType()); } if(dto.getIsSendMsg() != null) { dto.setIsSendMsg(appointment.getIsSendMsg() != null ? appointment.getIsSendMsg() : BaseEntity.NO); } if (dto.getIsArriveSendMsg() != null){ appointment.setIsArriveSendMsg(dto.getIsArriveSendMsg()); } String dayStr = DateUtil.formatDate(st); //预约关联项目 List<Project> projectList = new ArrayList<>(); List<AppointmentProject> apList = getAppointmentProjectList(dto, projectList); //医生限制数量校验 AppointmentTool.doctorLimitPreNumCheck(dto.getShopId(), appointment.getId(), dto.getDoctorId(), st ,commonService); //检测非繁忙项目 int rulePreType = AppointmentTool.preProjectNonBusy(dto.getShopId(), appointment.getId(),st,projectList,null,commonService); //检查是否不占用转疗名额 Integer occupySwitch = dto.getIsSwitch(); if(BaseEntity.YES.equals(occupySwitch)){ occupySwitch = TransferUtil.checkTransferNotOccupy(commonService , appointmentInfo==null?null:appointmentInfo.getUserLevel(), dto.getShopId() , st, dto.getDoctorId(), employee , projectList); } //获取设备相关数据 List<AppointmentProjectDeviceNo> apdnList = new ArrayList<>(); List<DeviceNoSchedule> dnsList = AppointmentV2Util.handleDeviceTime(dto.getDeviceTimeJson(), apdnList); //获取出医生的治疗时间记录 List<DoctorTime> doctorTimeList = null; //后台预约时,zlTimeJson没有对应的开始结束时间,所以要特殊处理 if(dto.getAddMode() == Appointment.ADD_MODE_BACKSTAGE_V2_3){ List<Integer> doctorZlTime = new ArrayList<>(); doctorZlTime.add(0); net.sf.json.JSONArray newZlTimeJson = new net.sf.json.JSONArray(); //治疗开始时间 ca.setTime(st); ca.add(Calendar.MINUTE, duration - dto.getZlTime()); Date treatSt = ca.getTime(); doctorTimeList = AppointmentV2Util.getDoctorZlTime(dto.getZlTimeJson(), treatSt , dto.getDoctorId(), dto.getShopId(), dayStr , appointment.getMonthStr(), doctorZlTime , newZlTimeJson, dnsList); appointment.setDoctorZlDuration(doctorZlTime.get(0)); }else{ doctorTimeList = AppointmentV2Util.getDoctorZlTime(dto.getZlTimeJson(), dto.getShopId(), dto.getDoctorId(), dayStr, dayStr.substring(0, 6)); } // if(isChangeTime == 1 || dto.getIsProjectChange() == 1) { // String [] projectIdsArr = StringUtils.isEmpty(dto.getProjectIds()) ? new String[0] : dto.getProjectIds().split(","); // //重新判断活动日 // ActivityDay activityDay = getActivityDay(dto.getShopId(), dayStr, dto.getDoctorId(), projectIdsArr); // //预约开始时间在活动时间段里面 // if(activityDay != null && st.compareTo(activityDay.getStartTime()) != -1 && st.compareTo(activityDay.getEndTime()) < 1){ // appointment.setActivityDayId(activityDay.getId()); // }else{ // appointment.setActivityDayId(null); // } pNumMap.put(id, num); //判断治疗时间等于0,则默认5分钟 pZlMap.put(id, project.getUseDuration() == null ? 0 : project.getUseDuration()); pMap.put(id, new ProjectVo(project, num, dto.getShopId())); pMap.get(id).setZlTime(project.getUseDuration() / 60); projectIdsArr[i] = id; projectNamesArr[i] = project.getName(); apList.add(new AppointmentProject(id, num)); //治疗时间(分钟) = 项目使用时长(秒) / 60 zlTime += project.getUseDuration() / 60; // } //赋值对应字段 appointment.setAddMode(dto.getAddMode()); appointment.setEditTime(new Date()); appointment.setDuration(duration); appointment.setPalsyDuration(dto.getMfTime()); appointment.setComDuration(dto.getGtTime()); appointment.setDocComDuration(dto.getMzTime()); appointment.setTreatDuration(dto.getZlTime()); appointment.setReadyDuration(dto.getSqTime()); appointment.setWaitDuration(dto.getWaitTime()); appointment.setStartTime(st); appointment.setEndTime(et); appointment.setDayStr(dayStr); appointment.setWeekStr(DateUtil.formatDate(getWeekDate(st))); appointment.setIsAnaesthesia(dto.getMfTime() > 0 ? BaseEntity.YES : BaseEntity.NO); appointment.setNotifyStatus(Appointment.NOTIFY_STATUS_SUC); appointment.setSpecialUser(dto.getSpecialUser()); appointment.setOccupySwitch(occupySwitch); appointment.setRulePreType(rulePreType); appointment.setDoctorId(dto.getDoctorId()); appointment.setNurseId(dto.getNurseId()); appointment.setCorpUserId(corpUserId); appointment.setRemark(dto.getRemark()); appointment.setProjectIds(dto.getProjectIds()); appointment.setProjectNames(dto.getProjectNames()); appointment.setProjectJson(dto.getProjectJson()); appointment.setComRoomId(dto.getComRoomId()); appointment.setTreatRoomId(dto.getTreatRoomId()); appointment.setConflictReason(dto.getConflictReason()); //如果预约已审核,则记录一下已审核修改 if(appointment.getStatus() == Appointment.STATUS_SUC || appointment.getStatus() == Appointment.STATUS_FAIL) { appointment.setIsModify(BaseEntity.YES); } //预约其他信息 appointmentInfo.setAutoTimeType(dto.getHandleNum()); appointmentInfo.setZlTimeJson(dto.getZlTimeJson()); appointmentInfo.setDeviceTimeJson(dto.getDeviceTimeJson()); appointmentInfo.setMealsRemark(dto.getMealsRemark()); if(!StringUtils.isEmpty(dto.getBirthday())){ appointmentInfo.setBirthday(DateUtil.parseString_2(dto.getBirthday())); } //处理预约状态和是否转疗逻辑 handleStatusAndIsSwitch(dto.getAddMode(), appointment, shop, employee, true, oldInfo); appointmentV2Service.edit(operatorVo, user, oldInfo, appointment, appointmentInfo, apList, apdnList, doctorTimeList, dnsList); return Result.success(); } /** 取消预约 */ @RequestMapping("/cancel") public Result cancel(@RequestBody AppointmentV2Dto dto){ log.info("取消预约参数:{}", JSONObject.toJSONString(dto)); OperatorVo operatorVo = getOperatorInfo(dto); if(StringUtils.isEmpty(dto.getId())) { throwParamException("预约标识为空!"); } // if(StringUtils.isEmpty(dto.getAnnexUrl())) { // throwParamException("对话凭证不能为空!"); // } Appointment appointment = commonService.selectOneByKey(AppointmentMapper.class, dto.getId()); if(appointment == null) { throwParamException("查询不到预约信息!"); } if(appointment.getStatus() == Appointment.STATUS_FAIL || appointment.getStatus() == Appointment.STATUS_CANCEL) { throwServiceException("预约不成功或者已取消!"); } if(appointment.getCancelStatus() != Appointment.CANCEL_STATUS_NONE && appointment.getCancelStatus() != Appointment.CANCEL_STATUS_FAIL) { throwServiceException("取消状态不正确!"); } //判断用户自助的预约,操作人非用户时,不能取消 if(appointment.getAddMode() == Appointment.ADD_MODE_CRM_SELF && !operatorVo.getOpId().equals(appointment.getCreateManId())){ throw new TipsException("无法取消用户的自助预约!"); } Integer isSendMsg = dto.getIsSendMsg(); if(isSendMsg == null) { isSendMsg = appointment.getIsSendMsg() != null ? appointment.getIsSendMsg() : BaseEntity.NO; } appointmentV2Service.cancel(appointment, operatorVo, dto.getRemark(), isSendMsg, dto.getAnnexUrl()); return Result.success(); } /////////////////////////////////////////////////////////////////////////// /** 获取操作人信息 */ private OperatorVo getOperatorInfo(AppointmentV2Dto dto){ if(dto.getOpType() == null){ throw new TipsException("操作人类型为空!"); } if(StringUtils.isEmpty(dto.getOpId())){ throw new TipsException("操作人标识为空!"); } OperatorVo operatorVo = null; if(dto.getOpType() == OperatorConstants.OP_TYPE_EMPLOYEE){ if(StringUtils.isEmpty(dto.getOpRoleId())){ throw new TipsException("操作人角色标识为空!"); } Employee employee = employeeRoleService.selectEmployeeById(dto.getOpRoleId()); if(employee == null){ throw new TipsException("查询不到员工操作人信息!"); } operatorVo = new OperatorVo(employee); }else if(dto.getOpType() == OperatorConstants.OP_TYPE_USER){ User user = commonService.selectOneByKey(UserMapper.class, dto.getOpId()); if(user == null){ throw new TipsException("查询不到用户操作人信息!"); } operatorVo = new OperatorVo(user); } else { throw new TipsException("操作人类型错误!"); } return operatorVo; } //校验员工判断 private Employee checkEmployee(OperatorVo operatorVo, String corpUserId){ if(operatorVo.getOpType() == OperatorConstants.OP_TYPE_EMPLOYEE){ //顾问或顾问助理,才判断所属顾问id不能为空 // if(RoleType.UNIQUE_STR_ADVISER_ASSISTANT.equals(operatorVo.getRoleStr()) // || RoleType.UNIQUE_STR_ADVISER_LEADER.equals(operatorVo.getRoleStr()) ){ // if(StringUtils.isEmpty(corpUserId)){ // throw new TipsException("请选择预约所属顾问!"); // } // } if(operatorVo.getEmployee() == null){ throw new TipsException("预约操作员工信息为空[020]"); } return operatorVo.getEmployee(); } return null; } //获取预约项目 private List<AppointmentProject> getAppointmentProjectList(AppointmentV2Dto dto, List<Project> projectList){ //预约关联项目 Project project; AppointmentProject appointmentProject = null; List<AppointmentProject> apList = new ArrayList<>(); String[] projectIdArr = StringUtils.isEmpty(dto.getProjectIds()) ? new String[0] : dto.getProjectIds().split(","); //复查时可不选预约项目 if(StringUtils.isEmpty(dto.getProjectIds(), dto.getProjectJson()) || projectIdArr == null || projectIdArr.length <= 0) { if(dto.getAppType() != Appointment.APP_TYPE_REVIEW){ throw new TipsException("请选择项目!"); } }else{ JSONArray arr = JSONArray.parseArray(dto.getProjectJson()); JSONObject json; for(int i = 0; i < arr.size(); i++){ json = arr.getJSONObject(i); //查找预约项目 project = commonService.selectOneByKey(ProjectMapper.class, json.getString("id")); if(project == null || project.getIsDel().equals(BaseEntity.YES) || project.getIsUp().equals(BaseEntity.NO)) { throw new TipsException("查询不到项目或者项目已下架!"); } projectList.add(project); appointmentProject = new AppointmentProject(json); apList.add(appointmentProject); } } return apList; } //处理预约状态和是否转疗逻辑 private void handleStatusAndIsSwitch(Integer addMode, Appointment appointment, Shop shop, Employee employee, boolean isEdit, Appointment oldInfo) { //默认状态:待审核 appointment.setStatus(Appointment.STATUS_WAIT); //CRM预约的默认状态:预约成功 if(addMode == Appointment.ADD_MODE_CRM_SELF){ appointment.setStatus(Appointment.STATUS_SUC); return; } //要MIC同意的则跳过 if(appointment.getIsMicApprove() == BaseEntity.YES){ return; } //非HIS助手顾问新增、后台信息的 if(addMode != Appointment.ADD_MODE_ADVISER_V2_3 && addMode != Appointment.ADD_MODE_BACKSTAGE_V2_3 && addMode != Appointment.ADD_MODE_BACKSTAGE_V2_4){ return; } //判断系统是否设置了自动审核成功 SystemParameter systemParameter = systemParameterService.selectOneByName(SystemParameter.KEY_APP_AUTO_EXAMINE_SUC); if(systemParameter == null || !"1".equals(systemParameter.getParamValue())){ return; } appointment.setStatus(Appointment.STATUS_SUC); //判断是否会占用转疗,不占用跳过 if(BaseEntity.NO.equals(appointment.getOccupySwitch())){ return; } if(!isEdit){ //新增预约判断:预约门店和预约员工门店不一致,判断门店是否还有转疗数量 if(!appointment.getShopId().equals(employee.getShopId())){ int countIsSwitch = appointmentV2Service.selectCountIsSwitch(appointment.getDayStr(), shop.getId()); log.info("新增预约:{}{}转疗单数:{},门店设置最大的转疗数:{}", shop.getName(), appointment.getDayStr(), countIsSwitch, shop.getMaxSwitchNum()); if(shop !=null && shop.getMaxSwitchNum()!=null && countIsSwitch>=shop.getMaxSwitchNum()){ throw new TipsException("转疗订单已经超过门店设置的最大转疗订单,转疗订单数:"+countIsSwitch+",门店转疗最大数:"+shop.getMaxSwitchNum()); } appointment.setIsSwitch(BaseEntity.YES); } }else{ //编辑预约判断:预约门店和预约员工门店不一致,判断门店是否还有转疗数量 if(!appointment.getShopId().equals(employee.getShopId()) && !oldInfo.getDayStr().equals(appointment.getDayStr())){ int countIsSwitch= appointmentV2Service.selectCountIsSwitch(appointment.getDayStr(), appointment.getShopId()); log.info("编辑预约:{}{}转疗预约数:{},门店设置最大的转疗数:{}", shop.getName(), appointment.getDayStr(), countIsSwitch, shop.getMaxSwitchNum()); if(shop !=null && shop.getMaxSwitchNum() != null && countIsSwitch >= shop.getMaxSwitchNum()){ throw new TipsException("转疗订单已经超过门店设置的最大转疗订单,转疗订单数:"+countIsSwitch+",门店转疗最大数:"+shop.getMaxSwitchNum()); } appointment.setIsSwitch(BaseEntity.YES); } } } //活动日 public ActivityDay getActivityDay(String shopId, String dayStr, String doctorId, String [] projectIdsArr){ Map<String, Object> map = new HashMap<>(); SqlSentence sqlSentence = new SqlSentence(); //查询当天是否有活动日 map.put("isDel", BaseEntity.NO); map.put("shopId", shopId); map.put("dayStr", dayStr); sqlSentence.setM(map); sqlSentence.setSqlSentence("select * from activity_day where isDel = #{m.isDel} and shopId = #{m.shopId} and dayStr = #{m.dayStr}"); ActivityDay activityDay = commonService.selectOne(ActivityDayMapper.class, sqlSentence); if(activityDay == null){ return activityDay; } //判断选择医生是否符合 boolean isDoctor = true; //类型为指定医生时 if(activityDay.getType() == ActivityDay.TYPE_APPOINT_DOCTOR){ isDoctor = activityDay.getDoctorIds().indexOf(doctorId) != -1; } boolean isProject = true; if(isDoctor == true){ //判断选择项目是否符合 for(String projectId : projectIdsArr){ //某个项目不符合时,直接返回false if(activityDay.getProjectIds().indexOf(projectId) == -1){ isProject = false; break; } } } boolean isOk = true; if(isDoctor && isProject){ sqlSentence.setSqlSentence("isDel = #{m.isDel} and shopId = #{m.shopId} and activityDayId = #{m.activityDayId} and status = #{m.status} "); map.put("status", Appointment.STATUS_SUC); map.put("activityDayId", activityDay.getId()); int count = commonService.selectCount(AppointmentMapper.class, sqlSentence); //判断预约人数是否超过可接待人数 if(count >= activityDay.getNumber()){ isOk = false; } }else{ //都不符合时提示或者下一天 isOk = false; } //符合条件,且在活动日时间段时,关联活动日id if(isOk == false){ activityDay = null; } return activityDay; } //获取周日期 private Date getWeekDate(Date st){ //周,取当前周一 Calendar ca = Calendar.getInstance(); ca.setTime(st); int dayOfWeek = ca.get(Calendar.DAY_OF_WEEK); if(dayOfWeek == 1) { ca.add(Calendar.DAY_OF_YEAR, -6); }else{ ca.add(Calendar.DAY_OF_YEAR, 2 - dayOfWeek); } return ca.getTime(); } //检测用户创建预约 public void checkUserAdd(Integer addMode, String doctorId, Date startTime, Date endTime){ //非CRM自助预约跳过 if(addMode != Appointment.ADD_MODE_CRM_SELF){ return; } SqlSentence sqlSentence = new SqlSentence(); Map<String, Object> values = new HashMap<>(); sqlSentence.setM(values); AppointmentInfo appointmentInfo = new AppointmentInfo(); if(appointment == null){ appointment = new Appointment(); } appointment.setStatus(Appointment.STATUS_SUC); appointment.setSourceId(dto.getSourceId()); appointment.setShopId(dto.getShopId()); appointment.setDoctorId(dto.getDoctorId()); appointment.setUserId(dto.getUserId()); //项目信息 appointment.setProjectJson(arr.toJSONString()); appointment.setProjectIds(org.apache.commons.lang.StringUtils.join(projectIdsArr,",")); appointment.setProjectNames(org.apache.commons.lang.StringUtils.join(projectNamesArr,",")); //时间信息 appointment.setStartTime(DateUtil.parseString_1(dto.getStartTime())); appointment.setEndTime(DateUtil.parseString_1(dto.getEndTime())); appointment.setDayStr(DateUtil.formatDate(appointment.getStartTime())); //周字符串 Calendar ca = Calendar.getInstance(); ca.setTime(appointment.getStartTime()); int dayOfWeek = ca.get(Calendar.DAY_OF_WEEK); if(dayOfWeek == 1) { ca.add(Calendar.DAY_OF_YEAR, -6); }else{ ca.add(Calendar.DAY_OF_YEAR, 2 - dayOfWeek); } appointment.setWeekStr(DateUtil.formatDate(ca.getTime())); appointment.setMonthStr(appointment.getDayStr().substring(0, 6)); //所属顾问,使用用户所属顾问 appointment.setCorpUserId(user.getHisCorpUserId()); //创建人信息 appointment.setCreateManId(user.getId()); appointment.setCreateManName(user.getName()); appointment.setCreateManType(Appointment.CREATE_MAN_TYPE_USER); //默认就诊类型:医美 appointment.setVisitType("医美"); //备注 appointment.setRemark(dto.getRemark()); //新增模式 appointment.setAddMode(Appointment.ADD_MODE_CRM_CREATE); // appointment.setComDuration(0); appointment.setDocComDuration(0); appointment.setReadyDuration(0); appointment.setProDuration(0); appointment.setPalsyDuration(0); appointment.setTreatDuration(zlTime); appointment.setDoctorZlDuration(zlTime); //总时长 = 面诊 + 沟通 + 敷麻 + 术前 + 准备等待 + 治疗 int duration = appointment.getDocComDuration() + appointment.getComDuration() + appointment.getPalsyDuration() + appointment.getReadyDuration() + appointment.getWaitDuration() + appointment.getTreatDuration(); appointment.setDuration(duration); //获取出医生的治疗时间记录 JSONArray zlTimeJson = AppAutoMateV5Util.handleDoctorZlTime(pMap, appointment.getStartTime()); appointmentInfo.setZlTimeJson(zlTimeJson.toString()); List<DoctorTime> doctorTimeList = AppointmentV2Util.getDoctorZlTime(zlTimeJson.toString(), appointment.getShopId(), appointment.getDoctorId(), appointment.getDayStr(), appointment.getMonthStr()); //新增时 if(StringUtils.isEmpty(appointment.getId())){ //冗余用户信息 appointmentInfo.setUserStatus(user.getUserStatus()); appointmentInfo.setUserStatusCn(UserStatusConstants.getName(user.getUserStatus())); appointmentInfo.setUserInternetCorpUserId(user.getInternetCorpUserId()); appointmentInfo.setUserInternetCorpUserName(CommonQueryUtil.getEmployeeName(user.getInternetCorpUserId(), commonService)); appointmentInfo.setUserConsultantId(user.getHisCorpUserId()); appointmentInfo.setUserConsultantName(CommonQueryUtil.getEmployeeName(user.getHisCorpUserId(), commonService)); appointmentInfo.setUserShopId(user.getShopId()); appointmentInfo.setUserShopName(CommonQueryUtil.getShopName(user.getShopId(), commonService)); appointmentInfo.setUserLevel(user.getUserLevel()); appointmentInfo.setMemberLevelId(user.getMemberLevelId()); //根据用户角色信息,获取对应可使用预约类型,多个取第一个 net.sf.json.JSONArray appTypeArr = AppointmentListUtil.userToAppType(dto.getUserId(), commonService); if(appTypeArr == null || appTypeArr.size() < 1){ throw new PlatTipsException(PlatformCode.ERROR_TIPS, "没有对应预约类型!"); } appointment.setAppType(appTypeArr.getInt(0)); values.put("doctorId", doctorId); values.put("startTime", DateUtil.formatDate_2(startTime)); values.put("endTime", DateUtil.formatDate_2(endTime)); sqlSentence.setSqlSentence(" select count(1) from appointment where isDel = 0 and status = 1 and startTime = #{m.startTime} and endTime = #{m.endTime} "); int count = commonService.selectCountSql(AppointmentMapper.class, sqlSentence); if(count > 0){ throw new TipsException("非常抱歉!\n" + DateUtil.formatDate(startTime, "MM月dd HH:mm - ") + DateUtil.formatDate(endTime, "HH:mm") + " 预约时间已被预约\n请返回重新选择时间。"); } //添加预约 if(dto.getHandleType() == 1){ appointmentService.crmAdd(appointment, apList, doctorTimeList, null, appointmentInfo); }else if(dto.getHandleType() == 2){ appointmentService.crmEdit(appointment, appointmentInfo, 0, doctorTimeList, apList, null, null); } JSONObject data = new JSONObject(); data.put("appointmentId", appointment.getId()); return Result.success(data); } // // /** CRM预约(CRM的再升美学预约) */ // @RequestMapping("/crm/app") // public Result crmApp(@RequestBody(required = false) AppointmentCrmAddDto dto) { // // if (dto == null) { // throw new PlatTipsException(PlatformCode.ERROR_TIPS, "请求参数为空!"); // } // // if(dto.getHandleType() == null){ // throw new PlatTipsException(PlatformCode.ERROR_TIPS, "处理类型不能为空!"); // } // // Appointment appointment = null; // //判断处理类型处理类型(1新增2编辑3取消) // if(dto.getHandleType() == 2 || dto.getHandleType() == 3){ // if(StringUtils.isEmpty(dto.getAppointmentId())){ // throw new PlatTipsException(PlatformCode.ERROR_TIPS, "预约标识不能为空!"); // } // // appointment = commonService.selectOneByKey(AppointmentMapper.class, dto.getAppointmentId()); // if(appointment == null){ // throw new PlatTipsException(PlatformCode.ERROR_TIPS, "查询不到预约信息!"); // } // // //如果处理类型为取消,则直接调用取消逻辑然后返回 // if(dto.getHandleType() == 3){ // appointmentService.cancel(appointment, dto.getRemark(), Appointment.CANCEL_TYPE_CRM_USER, null); // return Result.success(); // } // } // // if(StringUtils.isEmpty(dto.getUserId())){ // throw new PlatTipsException(PlatformCode.ERROR_TIPS, "用户标识为空!"); // } // // if(StringUtils.isEmpty(dto.getShopId())){ // throw new PlatTipsException(PlatformCode.ERROR_TIPS, "门店标识为空!"); // } // // if(StringUtils.isEmpty(dto.getDoctorId())){ // throw new PlatTipsException(PlatformCode.ERROR_TIPS, "医生标识为空!"); // } // // if(StringUtils.isEmpty(dto.getStartTime())){ // throw new PlatTipsException(PlatformCode.ERROR_TIPS, "开始时间为空!"); // } // // User user = commonService.selectOneByKeyBlob(UserMapper.class, dto.getUserId()); // if (user == null) { // throw new PlatTipsException(PlatformCode.ERROR_TIPS, "找不到用户信息!"); // } // // Shop shop = commonService.selectOneByKeyBlob(ShopMapper.class, dto.getShopId()); // if (shop == null) { // throw new PlatTipsException(PlatformCode.ERROR_TIPS, "找不到门店信息!"); // } // // Employee employee = commonService.selectOneByKeyBlob(EmployeeMapper.class, dto.getDoctorId()); // if (employee == null) { // throw new PlatTipsException(PlatformCode.ERROR_TIPS, "找不到医生信息!"); // } // // //目前写死一个项目 // SystemParameter sp = systemParameterService.selectOneByName(SystemParameter.KEY_CRM_APPOINTMENT_PROJECT_ID); // if(sp == null || StringUtils.isEmpty(sp.getParamValue())){ // throw new PlatTipsException(PlatformCode.ERROR_TIPS, "还未配置项目信息!"); // } // // Project project = commonService.selectOneByKey(ProjectMapper.class, sp.getParamValue()); // if(project == null){ // throw new PlatTipsException(PlatformCode.ERROR_TIPS, "找不到项目信息!"); // } // // if(project == null || project.getIsDel() == BaseEntity.YES || project.getIsUp() == BaseEntity.NO) // { // throw new PlatTipsException(PlatformCode.ERROR_TIPS, "找不到项目或者项目下架!"); // } // // //组装json数组 // JSONArray arr = new JSONArray(); // JSONObject temp = new JSONObject(); // temp.put("id", project.getId()); // temp.put("num", 1); // temp.put("isLifeBeauty", project.getIsLifeBeauty()); // temp.put("name", project.getName()); // temp.put("palsyDuration", project.getPalsyDuration()); // temp.put("isPalsy", project.getPalsyDuration() > 0 ? 1 : 0); // temp.put("useDuration", project.getUseDuration()); // arr.add(temp); // // String [] projectIdsArr = new String[arr.size()]; // String [] projectNamesArr = new String[arr.size()]; // Map<String, Integer> pNumMap = new HashMap<>(); // Map<String, Integer> pZlMap = new HashMap<>(); // String id = null; // int num = 0; // int zlTime = 0; // // // List<AppointmentProject> apList = new ArrayList<>(); // LinkedHashMap<String, ProjectVo> pMap = new LinkedHashMap<>(); // for(int i = 0; i < arr.size(); i ++) // { // temp = arr.getJSONObject(i); // id = temp.getString("id"); // num = temp.getIntValue("num"); // if(StringUtils.isEmpty(id) || num <= 0) // { // throw new PlatTipsException(PlatformCode.ERROR_TIPS, "请选择正确项目和数量"); // } // project = commonService.selectOneByKey(ProjectMapper.class, id); // if(project == null || project.getIsDel() == BaseEntity.YES || project.getIsUp() == BaseEntity.NO) // { // throw new PlatTipsException(PlatformCode.ERROR_TIPS, "找不到项目或者项目下架"); // } //// //获取最大的术前准备时间 //// if(project.getReadyDuration() > sqTime){ //// sqTime = project.getReadyDuration(); //// } // pNumMap.put(id, num); // //判断治疗时间等于0,则默认5分钟 // pZlMap.put(id, project.getUseDuration() == null ? 0 : project.getUseDuration()); // pMap.put(id, new ProjectVo(project, num, dto.getShopId())); // pMap.get(id).setZlTime(project.getUseDuration() / 60); // projectIdsArr[i] = id; // projectNamesArr[i] = project.getName(); // apList.add(new AppointmentProject(id, num)); // //治疗时间(分钟) = 项目使用时长(秒) / 60 // zlTime += project.getUseDuration() / 60; // } // // SqlSentence sqlSentence = new SqlSentence(); // Map<String, Object> values = new HashMap<>(); // sqlSentence.setM(values); // // AppointmentInfo appointmentInfo = new AppointmentInfo(); // if(appointment == null){ // appointment = new Appointment(); // } // appointment.setStatus(Appointment.STATUS_SUC); // appointment.setSourceId(dto.getSourceId()); // appointment.setShopId(dto.getShopId()); // appointment.setDoctorId(dto.getDoctorId()); // appointment.setUserId(dto.getUserId()); // //项目信息 // appointment.setProjectJson(arr.toJSONString()); // appointment.setProjectIds(org.apache.commons.lang.StringUtils.join(projectIdsArr,",")); // appointment.setProjectNames(org.apache.commons.lang.StringUtils.join(projectNamesArr,",")); // //时间信息 // appointment.setStartTime(DateUtil.parseString_1(dto.getStartTime())); // appointment.setEndTime(DateUtil.parseString_1(dto.getEndTime())); // appointment.setDayStr(DateUtil.formatDate(appointment.getStartTime())); // //周字符串 // Calendar ca = Calendar.getInstance(); // ca.setTime(appointment.getStartTime()); // int dayOfWeek = ca.get(Calendar.DAY_OF_WEEK); // if(dayOfWeek == 1) // { // ca.add(Calendar.DAY_OF_YEAR, -6); // }else{ // ca.add(Calendar.DAY_OF_YEAR, 2 - dayOfWeek); // } // appointment.setWeekStr(DateUtil.formatDate(ca.getTime())); // appointment.setMonthStr(appointment.getDayStr().substring(0, 6)); // //所属顾问,使用用户所属顾问 // appointment.setCorpUserId(user.getHisCorpUserId()); // //创建人信息 // appointment.setCreateManId(user.getId()); // appointment.setCreateManName(user.getName()); // appointment.setCreateManType(Appointment.CREATE_MAN_TYPE_USER); // //默认就诊类型:医美 // appointment.setVisitType("医美"); // //备注 // appointment.setRemark(dto.getRemark()); // //新增模式 // appointment.setAddMode(Appointment.ADD_MODE_CRM_CREATE); // // // // appointment.setComDuration(0); // appointment.setDocComDuration(0); // appointment.setReadyDuration(0); // appointment.setProDuration(0); // appointment.setPalsyDuration(0); // appointment.setTreatDuration(zlTime); // appointment.setDoctorZlDuration(zlTime); // // //总时长 = 面诊 + 沟通 + 敷麻 + 术前 + 准备等待 + 治疗 // int duration = appointment.getDocComDuration() + appointment.getComDuration() + appointment.getPalsyDuration() + appointment.getReadyDuration() + appointment.getWaitDuration() + appointment.getTreatDuration(); // appointment.setDuration(duration); // // //获取出医生的治疗时间记录 // JSONArray zlTimeJson = AppAutoMateV5Util.handleDoctorZlTime(pMap, appointment.getStartTime()); // appointmentInfo.setZlTimeJson(zlTimeJson.toString()); // List<DoctorTime> doctorTimeList = AppointmentV2Util.getDoctorZlTime(zlTimeJson.toString(), appointment.getShopId(), appointment.getDoctorId(), appointment.getDayStr(), appointment.getMonthStr()); // // // //新增时 // if(StringUtils.isEmpty(appointment.getId())){ // // //冗余用户信息 // appointmentInfo.setUserStatus(user.getUserStatus()); // appointmentInfo.setUserStatusCn(UserStatusConstants.getName(user.getUserStatus())); // appointmentInfo.setUserInternetCorpUserId(user.getInternetCorpUserId()); // appointmentInfo.setUserInternetCorpUserName(CommonQueryUtil.getEmployeeName(user.getInternetCorpUserId(), commonService)); // appointmentInfo.setUserConsultantId(user.getHisCorpUserId()); // appointmentInfo.setUserConsultantName(CommonQueryUtil.getEmployeeName(user.getHisCorpUserId(), commonService)); // appointmentInfo.setUserShopId(user.getShopId()); // appointmentInfo.setUserShopName(CommonQueryUtil.getShopName(user.getShopId(), commonService)); // appointmentInfo.setUserLevel(user.getUserLevel()); // appointmentInfo.setMemberLevelId(user.getMemberLevelId()); // // //根据用户角色信息,获取对应可使用预约类型,多个取第一个 // net.sf.json.JSONArray appTypeArr = AppointmentListUtil.userToAppType(dto.getUserId(), commonService); // if(appTypeArr == null || appTypeArr.size() < 1){ // throw new PlatTipsException(PlatformCode.ERROR_TIPS, "没有对应预约类型!"); // } // appointment.setAppType(appTypeArr.getInt(0)); // } // // //添加预约 // if(dto.getHandleType() == 1){ // appointmentService.crmAdd(appointment, apList, doctorTimeList, null, appointmentInfo); // }else if(dto.getHandleType() == 2){ // appointmentService.crmEdit(appointment, appointmentInfo, 0, doctorTimeList, apList, null, null); // } // // // JSONObject data = new JSONObject(); // data.put("appointmentId", appointment.getId()); // // return Result.success(data); // } } phi_platform_user/src/main/java/com/hx/phip/controller/appointment/CrmSelfController.java
New file @@ -0,0 +1,398 @@ package com.hx.phip.controller.appointment; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.hx.common.BaseController; import com.hx.exception.TipsException; import com.hx.guide.util.CommonQueryUtil; import com.hx.mybatisTool.SqlSentence; import com.hx.phiappt.common.OperatorConstants; import com.hx.phiappt.constants.enums.GroupTypeEnum; import com.hx.phiappt.dao.mapper.*; import com.hx.phiappt.model.*; import com.hx.phiappt.model.user.UserCard; import com.hx.phip.config.GlobalExceptionHandler; import com.hx.phip.tool.user.UserCardTool; import com.hx.resultTool.Result; import com.hx.util.DateUtil; import com.hx.util.StringUtils; import com.hz.his.dto.appointment.AppointmentAutoMateDto; import com.hz.his.dto.user.UserDto; import com.hz.his.vo.user.card.UserCardEquityVo; import com.hz.his.vo.user.card.UserCardItemVo; import com.hz.his.vo.user.card.UserCardVo; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.*; /** * CRM自助预约 * @USER: fhx * @DATE: 2024/4/3 **/ @Slf4j @RestController @RequestMapping("/appointment/crm/self") public class CrmSelfController extends BaseController { /** VIP等级字符 */ public static final String VIP_STR = "金卡|钻石卡|黑卡"; /** 门店标识(静安店) */ public static final List<String> SHOP_ID_LIST = Arrays.asList("bb4e8a7d620d11ebb06bb8599f4cafbe"); @Resource private AppAutoMateController appAutoMateController; /** 预约页面数据 */ @RequestMapping("/page/data") public Result pageData(@RequestBody UserDto dto){ JSONObject data = handleUserData(dto.getUserId()); return Result.success(data); } /** CRM首页预约列表 */ @RequestMapping("/index/app/list") public Result indexAppList(@RequestBody UserDto dto){ SqlSentence sqlSentence = new SqlSentence(); Map<String, Object> values = new HashMap<>(); sqlSentence.setM(values); //查询用户最近一条预约信息 values.put("userId", dto.getUserId()); values.put("status1", Appointment.STATUS_SUC); values.put("addMode10", Appointment.ADD_MODE_CRM_SELF); StringBuilder sql = new StringBuilder(); sql.append(" select a.id, a.startTime, a.endTime , s.name as shopName , d.cnName as doctorName, a.doctorId, a.isArrive, a.projectJson ") .append(" from appointment a ") .append(" left join shop s on s.id = a.shopId ") .append(" left join employee d on d.id = a.doctorId ") .append(" where a.isDel = 0 and a.userId = #{m.userId} and a.startTime > now() ") .append(" and a.status = #{m.status1} and a.addMode = #{m.addMode10} ") .append(" order by a.startTime asc limit 1 "); sqlSentence.setSqlSentence(sql.toString()); List<Map<String, Object>> list = commonService.selectListMap(AppointmentMapper.class, sqlSentence); if(list != null && list.size() > 0){ JSONArray arr; StringBuilder nameSb = new StringBuilder(); for(Map<String, Object> m : list){ nameSb.setLength(0); arr = JSONArray.parseArray(m.get("projectJson").toString()); if(arr ==null || arr.size() < 1){ continue; } for(int i = 0 ; i < arr.size(); i++){ if(nameSb.length() > 0){ nameSb.append(","); } nameSb.append(arr.getJSONObject(i).getString("commonName")); } m.remove("projectJson"); m.put("projectNames", nameSb.toString()); } } JSONObject data = new JSONObject(); data.put("list", list); return Result.success(data); } /** 用户预约列表 */ @RequestMapping("/list") public Result selfList(@RequestBody UserDto dto){ if(StringUtils.isEmpty(dto.getUserId())){ throw new TipsException("用户标识为空!"); } SqlSentence sqlSentence = new SqlSentence(); Map<String, Object> values = new HashMap<>(); sqlSentence.setM(values); values.put("userId", dto.getUserId()); values.put("status1", Appointment.STATUS_SUC); values.put("addMode9", Appointment.ADD_MODE_CRM_CREATE); StringBuilder sql = new StringBuilder(); sql.append(" select a.id, a.startTime, a.endTime, s.name as shopName , d.cnName as doctorName, a.doctorId ") .append(" , a.status, a.isArrive, a.projectJson, a.addMode ") .append(" from appointment a ") .append(" left join shop s on s.id = a.shopId ") .append(" left join employee d on d.id = a.doctorId ") .append(" where a.isDel = 0 and a.userId = #{m.userId} ") .append(" and a.addMode != #{m.addMode9} ") .append(" order by a.startTime desc "); sqlSentence.setSqlSentence(sql.toString()); //分页插件 PageHelper.startPage(dto.getPageNum(), dto.getPageSize()); List<Map<String, Object>> list = commonService.selectListMap(AppointmentMapper.class, sqlSentence); PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(list); Map<String, Object> data = new HashMap<>(); data.put("list", pageInfo.getList()); data.put("pageNum", pageInfo.getPageNum()); data.put("pageSize", pageInfo.getPageSize()); data.put("pages", pageInfo.getPages()); data.put("total", pageInfo.getTotal()); data.put("isLastPage", pageInfo.isIsLastPage()); return Result.success(data); } /** 用户自助预约项目 */ @RequestMapping("/project/list") public Result projectList(@RequestBody UserDto dto){ if(StringUtils.isEmpty(dto.getUserId())){ throw new TipsException("用户标识为空!"); } SqlSentence sqlSentence = new SqlSentence(); Map<String, Object> values = new HashMap<>(); sqlSentence.setM(values); values.put("userId", dto.getUserId()); StringBuilder sql = new StringBuilder(); //查询用户项目 sql.append(" SELECT '1' as commonType, ui.id as commonId, ui.goodsId as commonSubId, ui.goodsName as commonName ") .append(" , p.id as projectId, p.name as projectName, p.unit, p.specification ") .append(" , p.isLifeBeauty,p.useDuration, p.palsyDuration ") .append(" , spu.id as spuId, spu.name as spuName, pi.departmentCode, pi.departmentName ") .append(" FROM user_project_item ui ") .append(" join project_type_relation tr on tr.isDel = 0 and tr.skuId = ui.goodsId and tr.moduleType = 2 ") .append(" JOIN project_assoc_sku pas ON pas.skuId = ui.goodsId ") .append(" JOIN project p ON p.id = pas.projectId ") .append(" join project_general spu on spu.id = p.projectGeneralId ") .append(" join project_info pi on pi.projectId = pas.skuId and pi.departmentCode is not null ") .append(" WHERE ui.notUsedNum > 0 AND ui.isDel = 0 AND ui.effectiveStatus = 1 ") .append(" and ui.userId = #{m.userId} AND ui.goodsType = 'project' AND p.type = 1 ") .append(" group by ui.id "); sqlSentence.setSqlSentence(sql.toString()); List<Map<String, Object>> userProjectList = commonService.selectListMap(UserProjectItemMapper.class, sqlSentence); //查询用户卡项下的项目 sqlSentence.setSqlSentence(" select * from user_card where isDel = 0 and userId = #{m.userId} and effectiveStatus = 1 "); List<UserCard> userCardList = commonService.selectList(UserCardMapper.class, sqlSentence); // log.info("用户卡项数据:{}", JSONObject.toJSONString(userCardList)); List<UserCardVo> userCardVoList = new ArrayList<>(); //遍历查询用户卡项条目是否可用 for(UserCard userCard : userCardList){ userCardVoList.add(UserCardTool.getUserCardSurplus(userCard,commonService)); } sql.setLength(0); sql.append(" SELECT '2' as commonType, i.id as commonSubId, i.commonName ") .append(" , p.id as projectId, p.name as projectName, p.unit, p.specification ") .append(" , p.isLifeBeauty, p.useDuration, p.palsyDuration ") .append(" , spu.id as spuId, spu.name as spuName, pi.departmentCode, pi.departmentName ") .append(" FROM card_item_info i ") //基于项目映射表查对应打卡项目的卡项类型,而不是到sku(commonId) .append(" join project_type_relation tr on tr.isDel = 0 and tr.skuId = i.cardItemId and tr.moduleType = 2 ") .append(" JOIN project_assoc_sku pas ON pas.skuId = i.commonId ") .append(" JOIN project p ON p.id = pas.projectId ") .append(" join project_general spu on spu.id = p.projectGeneralId ") .append(" join project_info pi on pi.projectId = pas.skuId and pi.departmentCode is not null ") .append(" WHERE i.isDel = 0 and i.commonType = 'project' and i.id = #{m.id} ") .append(" GROUP by i.id "); String userCardSql = sql.toString(); sqlSentence.setSqlSentence(userCardSql); JSONArray arr = new JSONArray(); JSONArray groupArr = null; JSONObject json; Map<String, Object> map; List<Map<String, Object>> cardProjectList; //先遍历用户卡项 // log.info("卡项vo数据:{}", JSONObject.toJSONString(userCardVoList)); for(UserCardVo userCardVo : userCardVoList){ //再遍历卡项权益 groupArr = new JSONArray(); for(UserCardEquityVo userCardEquityVo : userCardVo.getUserCardEquityVoList()) { cardProjectList = new ArrayList<>(); //再遍历卡项权益下对应的条目 for(UserCardItemVo userCardItemVo : userCardEquityVo.getUserCardItemVoList()){ //非项目类型的条目跳过 if(!GroupTypeEnum.PROJECT.getCode().equals(userCardItemVo.getItemType())){ continue; } values.put("id", userCardItemVo.getItemId()); map = commonService.selectOneMap(CardItemInfoMapper.class, sqlSentence); if(map == null || map.size() < 1){ continue; } map.put("deductionNum", userCardItemVo.getDeductionNum()); //总抵扣次数 map.put("deductionSingle", userCardItemVo.getDeductionSingle()); //单次抵扣次数 map.put("usedNum", userCardItemVo.getUsedNum()); //已抵扣次数 map.put("surplusNum", userCardItemVo.getSurplusNum()); //剩余可抵扣总次数 cardProjectList.add(map); } //卡项权益没有查询项目的跳过 if(cardProjectList.size() == 0){ continue; } json = new JSONObject(); json.put("equityName", userCardEquityVo.getEquityName()); json.put("equityType", userCardEquityVo.getEquityType()); json.put("conditionValue", userCardEquityVo.getConditionValue()); //条件值 json.put("projectList", cardProjectList); groupArr.add(json); } //卡项权益分组不为空 if(groupArr.size() > 0){ json = new JSONObject(); json.put("commonId", userCardVo.getUserCardId()); json.put("cardName", userCardVo.getCardName()); json.put("groupList", groupArr); arr.add(json); } } json = new JSONObject(); json.put("projectList", userProjectList); json.put("cardList", arr); json.put("notDeptTips", "当前项目无科室医生,请联系您的专属顾问进行预约!"); return Result.success(json); } /** 自助预约时间 */ @RequestMapping("/getTime") public Result getTime(@RequestBody AppointmentAutoMateDto dto){ if(StringUtils.isEmpty(dto.getUserId())){ throw new TipsException("预约用户标识为空!"); } if(StringUtils.isEmpty(dto.getShopId())){ throw new TipsException("预约门店标识为空!"); } if(StringUtils.isEmpty(dto.getDoctorId())){ throw new TipsException("预约医生标识为空!"); } if(StringUtils.isEmpty(dto.getArriveDate())){ throw new TipsException("预约日期为空!"); } if(StringUtils.isEmpty(dto.getProjectJson())){ throw new TipsException("预约项目为空!"); } dto.setOpType(OperatorConstants.OP_TYPE_USER); dto.setOpId(dto.getUserId()); dto.setVisitType("医美"); dto.setAppType(Appointment.APP_TYPE_TREATMENT); dto.setStartTime("09:00"); dto.setDaySpace(true); Result result; try{ result = appAutoMateController.addApplyBland(dto); }catch (Exception e){ log.info("获取用户自助预约时间失败:{}", GlobalExceptionHandler.getExceptionInformation(e)); throw new TipsException("获取预约时间失败!"); } return result; } /** 获取一周内医生排班 */ @RequestMapping("/get/doctor/time") public Result getDoctorTime(@RequestBody AppointmentAutoMateDto dto){ if(StringUtils.isEmpty(dto.getShopId())){ throw new TipsException("预约门店标识为空!"); } if(StringUtils.isEmpty(dto.getDoctorId())){ throw new TipsException("预约医生标识为空!"); } Date now = new Date(); //当天时间 String startDay = DateUtil.formatDate(now); //一周后结束时间 String endDay = DateUtil.formatDate(DateUtil.addDay(now, 6)); SqlSentence sqlSentence = new SqlSentence(); Map<String, Object> values = new HashMap<>(); sqlSentence.setM(values); values.put("shopId", dto.getShopId()); values.put("doctorId", dto.getDoctorId()); values.put("startDay", startDay); values.put("endDay", endDay); values.put("timeType", DoctorTime.TIME_TYPE_WORK); StringBuffer sql = new StringBuffer(); sql.append(" select DATE_FORMAT(startTime, '%Y-%m-%d') as dateTime ") .append(" from doctor_Time ") .append(" where isDel = 0 and doctorId = #{m.doctorId} ") .append(" and shopId = #{m.shopId} and timeType = #{m.timeType} ") .append(" and dayTime >= #{m.startDay} and dayTime <= #{m.endDay} "); sqlSentence.setSqlSentence(sql.toString()); List<Map<String, Object>> list = commonService.selectListMap(DoctorTimeMapper.class, sqlSentence); JSONObject data = new JSONObject(); data.put("list", list); return Result.success(data); } //////////////////////////////////////////////////////////////////////////////////////// private JSONObject handleUserData(String userId){ if(StringUtils.isEmpty(userId)){ throw new TipsException("用户标识为空!"); } User user = commonService.selectOneByKey(UserMapper.class, userId); if(user == null){ throw new TipsException("查询不到用户信息!"); } JSONObject data = new JSONObject(); //是否能预约:0否1是,默认0 data.put("isCanApp", BaseEntity.NO); //预约门店 = 用户所属门店 data.put("shopId", user.getShopId()); data.put("shopName", CommonQueryUtil.getShopName(user.getShopId(), commonService)); //直接跳过:非VIP客户 if(!VIP_STR.contains(user.getUserLevel())){ data.put("notAppType", 1); return data; } //直接跳过:客户所属门店非规定的 if(!SHOP_ID_LIST.contains(user.getShopId())){ data.put("notAppType", 2); return data; } //对应条件成立,则用户能预约 data.put("isCanApp", BaseEntity.YES); SqlSentence sqlSentence = new SqlSentence(); Map<String, Object> values = new HashMap<>(); sqlSentence.setM(values); values.put("userId", userId); //查询用科室关系数量 sqlSentence.setSqlSentence(" select * from user_families_room where isDel = 0 and userId = #{m.userId} "); List<UserFamiliesRoom> userFamiliesRoomList = commonService.selectList(UserFamiliesRoomMapper.class, sqlSentence); //用户科室关系为空则跳过 if(userFamiliesRoomList == null && userFamiliesRoomList.size() < 1){ data.put("notAppType", 3); return data; } data.put("userFamiliesRoomList", userFamiliesRoomList); return data; } } phi_platform_user/src/main/java/com/hx/phip/controller/appointment/CrmSelfV2Controller.java
New file @@ -0,0 +1,438 @@ package com.hx.phip.controller.appointment; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.hx.common.BaseController; import com.hx.exception.TipsException; import com.hx.mybatisTool.SqlSentence; import com.hx.phiappt.common.OperatorConstants; import com.hx.phiappt.constants.tool.user.UserTool; import com.hx.phiappt.dao.mapper.*; import com.hx.phiappt.model.*; import com.hx.phip.config.GlobalExceptionHandler; import com.hx.resultTool.Result; import com.hx.util.DateUtil; import com.hx.util.StringUtils; import com.hz.his.dto.appointment.AppointmentAutoMateDto; import com.hz.his.dto.appointment.AppointmentDto; import com.hz.his.dto.appointment.AppointmentV2Dto; import com.hz.his.dto.user.UserDto; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; /** * CRM自助预约v2 * 按phis医生排班和预约项目进行预约 * @USER: fhx * @DATE: 2024/4/3 **/ @Slf4j @RestController @RequestMapping("/appointment/crm/self/v2") public class CrmSelfV2Controller extends BaseController { @Resource private AppAutoMateController appAutoMateController; @Resource private AppointmentController appointmentController; public static final String FORMAT = "yyyy-MM-ddHH:mm"; /** 预约门店 */ @RequestMapping("/shop/list") public Result shopList(){ SqlSentence sqlSentence = new SqlSentence(); sqlSentence.setSqlSentence(" select id, name, workTime from shop where isDel = 0 and isUp = 1 "); List<Map<String, Object>> list = commonService.selectListMap(ShopMapper.class, sqlSentence); Map<String, Object> data = new HashMap<>(); data.put("list", list); return Result.success(data); } /** 医生排班 */ @RequestMapping("/doctor/time/list") public Result doctorTimeList(@RequestBody AppointmentAutoMateDto dto){ if(StringUtils.isEmpty(dto.getShopId())){ throw new TipsException("门店标识为空!"); } if(StringUtils.isEmpty(dto.getStartTime())){ throw new TipsException("开始时间为空!"); } if(StringUtils.isEmpty(dto.getEndTime())){ throw new TipsException("结束时间为空!"); } // //版本1返回 // return Result.success(doctorTimeListV1(dto)); //版本2返回 return Result.success(doctorTimeListV2(dto)); } /** 预约项目SPU */ @RequestMapping("/spu/list") public Result spuList(){ SqlSentence sqlSentence = new SqlSentence(); Map<String, Object> values = new HashMap<>(); sqlSentence.setM(values); values.put("type", ProjectType.TYPE_APPOINTMENT); sqlSentence.setSqlSentence(" select id, name from project_general where isDel = 0 and type = #{m.type} and isUp = 1 order by orderNum asc "); List<Map<String, Object>> list = commonService.selectListMap(ProjectGeneralMapper.class, sqlSentence); Map<String, Object> data = new HashMap<>(); data.put("list", list); return Result.success(data); } /** 预约项目 */ @RequestMapping("/project/list") public Result projectList(@RequestBody AppointmentDto dto){ if(dto.getPageSize() == null || dto.getPageSize() > 20){ dto.setPageSize(20); } SqlSentence sqlSentence = new SqlSentence(); Map<String, Object> values = new HashMap<>(); sqlSentence.setM(values); values.put("type", ProjectType.TYPE_APPOINTMENT); StringBuilder sql = new StringBuilder(); sql.append(" select p.id, p.name, p.isLifeBeauty, p.unit, p.specification ") .append(", p.useDuration / 60 as useDuration ") .append(", p.palsyDuration / 60 as palsyDuration ") .append(", (p.useDuration + p.palsyDuration) / 60 as duration ") // .append(", (p.useDuration + p.palsyDuration + p.intervalDuration + p.readyDuration) / 60 as duration") .append(" from project p ") .append(" where p.isDel = 0 and p.isUp = 1 and p.isShow = 1 ") .append(" and p.type = #{m.type} "); if(StringUtils.noNull(dto.getKeyWord())){ sql.append(" and p.name like '%").append(dto.getKeyWord()).append("%' "); } //spuId查询 if(StringUtils.noNull(dto.getSpuId())){ sql.append(" and p.projectGeneralId = '").append(dto.getSpuId()).append("' "); } sql.append(" order by p.orderNum asc "); sqlSentence.setSqlSentence(sql.toString()); PageHelper.startPage(dto.getPageNum(), dto.getPageSize()); List<Map<String, Object>> list = commonService.selectListMap(ProjectMapper.class, sqlSentence); PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(list); Map<String, Object> data = new HashMap<>(); data.put("list", pageInfo.getList()); data.put("pageNum", pageInfo.getPageNum()); data.put("pageSize", pageInfo.getPageSize()); data.put("pages", pageInfo.getPages()); data.put("total", pageInfo.getTotal()); data.put("isLastPage", pageInfo.isIsLastPage()); return Result.success(data); } ////////////////////////////////////////////////////////////////////////////////////////// /** 自助预约匹配时间 */ @RequestMapping("/mate/time") public Result mateTime(@RequestBody AppointmentAutoMateDto dto){ if(StringUtils.isEmpty(dto.getUserId())){ throw new TipsException("预约用户标识为空!"); } if(StringUtils.isEmpty(dto.getShopId())){ throw new TipsException("预约门店标识为空!"); } if(StringUtils.isEmpty(dto.getDoctorId())){ throw new TipsException("预约医生标识为空!"); } if(StringUtils.isEmpty(dto.getArriveDate())){ throw new TipsException("预约日期为空!"); } if(StringUtils.isEmpty(dto.getStartTime())){ throw new TipsException("预约到店时间为空!"); } if(StringUtils.isEmpty(dto.getProjectJson())){ throw new TipsException("预约项目为空!"); } Date startTime = DateUtil.parseString(dto.getArriveDate() + dto.getStartTime(), FORMAT); if(startTime == null){ throw new TipsException("预约到店时间错误!"); } //查询用户是否有到店记录 dto.setOpType(OperatorConstants.OP_TYPE_USER); dto.setOpId(dto.getUserId()); dto.setVisitType("医美"); //判断用户没到店过,则初诊 if(UserTool.getUserArrivalNum(commonService, dto.getUserId()) == 0){ dto.setAppType(Appointment.APP_TYPE_FIRST); }else{ dto.setAppType(Appointment.APP_TYPE_TREATMENT); } dto.setMateNum(3); // dto.setDaySpace(true); Result result; try{ result = appAutoMateController.addApplyBland(dto); }catch (Exception e){ log.info("获取用户自助预约时间失败:{}", GlobalExceptionHandler.getExceptionInformation(e)); throw new TipsException("获取预约时间失败!"); } //匹配报错提示文案 JSONObject data = result.getJsonObject(result.getData()); JSONArray arr = data.getJSONArray("list"); if(arr != null && arr.size() > 0){ data.remove("errMsg"); } if(StringUtils.noNull(data.getString("errMsg")) ){ throw new TipsException(data.getString("errMsg")); } return result; } /** 新增预约 */ @RequestMapping("/add") public Result add(@RequestBody AppointmentV2Dto dto){ if(StringUtils.isEmpty(dto.getUserId())){ throw new TipsException("用户标识为空!"); } dto.setOpId(dto.getUserId()); dto.setOpType(OperatorConstants.OP_TYPE_USER); //操作人类型:用户 dto.setAddMode(Appointment.ADD_MODE_CRM_SELF); //crm自助预约 dto.setVisitType("医美"); //判断用户没到店过,则初诊 if(UserTool.getUserArrivalNum(commonService, dto.getUserId()) == 0){ dto.setAppType(Appointment.APP_TYPE_FIRST); }else{ dto.setAppType(Appointment.APP_TYPE_TREATMENT); } dto.setIsMicApprove(BaseEntity.NO); //无需MIC同意 dto.setIsSendMsg(BaseEntity.YES); //发送短信通知 dto.setIsArriveSendMsg(BaseEntity.YES); //发送短信通知 //新增预约 Result result = appointmentController.add(dto); if(!result.checkCode()){ log.error("新增用户自助预约V2失败:{}", JSONObject.toJSONString(result)); throw new TipsException("新增预约失败!"); } JSONObject data = result.getJsonObject(result.getData()); //查询返回对应预约信息 SqlSentence sqlSentence = new SqlSentence(); Map<String, Object> values = new HashMap<>(); sqlSentence.setM(values); values.put("id", data.getString("id")); StringBuilder sql = new StringBuilder(); sql.append(" select a.id, a.startTime, a.endTime , d.cnName as doctorName, a.doctorId ") .append(" , a.status, a.isArrive, a.projectNames, a.projectJson, a.addMode, a.createManName, a.createManType, remark ") .append(" , s.name as shopName, s.province, s.city, s.area, s.addr") .append(" from appointment a ") .append(" left join shop s on s.id = a.shopId ") .append(" left join employee d on d.id = a.doctorId ") .append(" where a.isDel = 0 and a.id = #{m.id} "); sqlSentence.setSqlSentence(sql.toString()); Map<String, Object> dataMap = commonService.selectOneMap(AppointmentMapper.class, sqlSentence); return Result.success(dataMap); } /** 取消预约 */ @RequestMapping("/cancel") public Result cancel(@RequestBody AppointmentV2Dto dto){ if(StringUtils.isEmpty(dto.getUserId())){ throw new TipsException("用户标识为空!"); } dto.setOpId(dto.getUserId()); dto.setOpType(OperatorConstants.OP_TYPE_USER); return appointmentController.cancel(dto); } /** 用户预约列表 */ @RequestMapping("/list") public Result list(@RequestBody UserDto dto){ if(StringUtils.isEmpty(dto.getUserId())){ throw new TipsException("用户标识为空!"); } SqlSentence sqlSentence = new SqlSentence(); Map<String, Object> values = new HashMap<>(); sqlSentence.setM(values); values.put("userId", dto.getUserId()); values.put("addMode9", Appointment.ADD_MODE_CRM_CREATE); StringBuilder sql = new StringBuilder(); sql.append(" select a.id, a.startTime, a.endTime, d.cnName as doctorName, a.doctorId, a.addMode ") .append(" , a.status, a.isArrive, a.projectJson, a.addMode, a.createManName, a.createManType, a.remark ") .append(" , s.name as shopName, s.province, s.city, s.area, s.addr") .append(" from appointment a ") .append(" left join shop s on s.id = a.shopId ") .append(" left join employee d on d.id = a.doctorId ") .append(" where a.isDel = 0 and a.userId = #{m.userId} ") //只查询预约成功和取消的 .append(" and a.status in (").append(Appointment.STATUS_SUC).append(",").append(Appointment.STATUS_CANCEL).append(") ") // .append(" and a.addMode != #{m.addMode9} ") .append(" order by a.startTime desc "); sqlSentence.setSqlSentence(sql.toString()); //分页插件 PageHelper.startPage(dto.getPageNum(), dto.getPageSize()); List<Map<String, Object>> list = commonService.selectListMap(AppointmentMapper.class, sqlSentence); PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(list); Map<String, Object> data = new HashMap<>(); data.put("list", pageInfo.getList()); data.put("pageNum", pageInfo.getPageNum()); data.put("pageSize", pageInfo.getPageSize()); data.put("pages", pageInfo.getPages()); data.put("total", pageInfo.getTotal()); data.put("isLastPage", pageInfo.isIsLastPage()); return Result.success(data); } /////////////////////////////////////////////////////////////////////////////////////////// // private void checkTime(Date startTime){ // Calendar calendar = Calendar.getInstance(); // calendar.setTime(startTime); // int hour = calendar.get(Calendar.HOUR); // if(hour ){} // } /** 医生排班(按日期选医生) */ private Map<String, Object> doctorTimeListV1(AppointmentAutoMateDto dto){ SqlSentence sqlSentence = new SqlSentence(); Map<String, Object> values = new HashMap<>(); sqlSentence.setM(values); values.put("timeType", DoctorTime.TIME_TYPE_WORK); values.put("shopId", dto.getShopId()); values.put("startTime", dto.getStartTime()); values.put("endTime", dto.getEndTime()); StringBuilder sql = new StringBuilder(); sql.append(" select dt.doctorId, e.cnName as doctorName, e.imgUrl ") .append(" , date_format(dt.startTime, '%Y-%m-%d') as startTime ") .append(" from doctor_time dt ") .append(" left join employee e on e.id = dt.doctorId ") .append(" where dt.isDel = 0 and dt.timeType = #{m.timeType} and dt.shopId = #{m.shopId} ") .append(" and dt.dayTime >= #{m.startTime} and dt.endTime <= #{m.endTime} ") .append(" order by dt.dayTime asc "); sqlSentence.setSqlSentence(sql.toString()); List<Map<String, Object>> list = commonService.selectListMap(DoctorTimeMapper.class, sqlSentence); if(list == null || list.size() < 1){ return null; } //先遍历按日期归类 List<Map<String, Object>> dataList; TreeMap<Object, List<Map<String, Object>>> treeMap = new TreeMap<>(); for(Map<String, Object> map : list){ dataList = treeMap.get(map.get("startTime")); if(!treeMap.containsKey(map.get("startTime"))){ dataList = new ArrayList<>(); treeMap.put(map.get("startTime"), dataList); } dataList.add(map); } //然后再组装 JSONArray arr = new JSONArray(); JSONObject json; for(Map.Entry<Object, List<Map<String, Object>>> entry : treeMap.entrySet()){ json = new JSONObject(); json.put("dateTime", entry.getKey()); json.put("doctorList", entry.getValue()); arr.add(json); } json = new JSONObject(); json.put("list", arr); json.put("version", "1"); return json; } /** 医生排班(按医生选日期) */ private Map<String, Object> doctorTimeListV2(AppointmentAutoMateDto dto){ SqlSentence sqlSentence = new SqlSentence(); Map<String, Object> values = new HashMap<>(); sqlSentence.setM(values); values.put("shopId", dto.getShopId()); StringBuilder sql = new StringBuilder(); //查询门店下的医生员工 sql.append(" select e.id as doctorId, e.cnName as doctorName, e.imgUrl ") .append(" from employee_role r ") .append(" join employee e on e.id = r.employeeId ") .append(" where r.isDel = 0 and e.isDel = 0 and e.isJob = 1 ") .append(" and r.shopId = #{m.shopId} and r.roleUniqueStr = #{m.roleUniqueStr} "); sqlSentence.setSqlSentence(sql.toString()); List<Map<String, Object>> doctorList = commonService.selectListMap(EmployeeMapper.class, sqlSentence); Map<String, Object> dataMap = new HashMap<>(); dataMap.put("list", doctorList); dataMap.put("version", "2"); if(doctorList == null || doctorList.size() < 1){ return dataMap; } //查询门店下对应日期范围的医生排班 values.put("timeType", DoctorTime.TIME_TYPE_WORK); values.put("startTime", dto.getStartTime()); values.put("endTime", dto.getEndTime()); sql.setLength(0); sql.append(" select dt.doctorId, date_format(dt.startTime, '%Y-%m-%d') as startTime ") .append(" from doctor_time dt ") .append(" left join employee e on e.id = dt.doctorId ") .append(" where dt.isDel = 0 and dt.timeType = #{m.timeType} and dt.shopId = #{m.shopId} ") .append(" and dt.dayTime >= #{m.startTime} and dt.endTime <= #{m.endTime} ") .append(" order by dt.dayTime asc "); sqlSentence.setSqlSentence(sql.toString()); List<Map<String, Object>> doctorTimeList = commonService.selectListMap(DoctorTimeMapper.class, sqlSentence); if(doctorTimeList == null || doctorTimeList.size() < 1){ return dataMap; } //按医生id分组归类排班数据 Map<String, List<Map<String, Object>>> doctorTimeMap = doctorTimeList.stream().collect(Collectors.groupingBy(m->m.get("doctorId").toString())); //先遍历按日期归类 List<Map<String, Object>> dateList; for(Map<String, Object> doctorMap : doctorList){ dateList = doctorTimeMap.get(doctorMap.get("doctorId")); if(dateList == null || dateList.size() < 1){ continue; } //按时间排序 dateList.sort(Comparator.comparing((Map<String, Object> h) -> ((String) h.get("startTime")))); dataMap.put("dateList", dateList); } return dataMap; } } phi_platform_user/src/main/java/com/hx/phip/service/EmployeeService.java
@@ -34,4 +34,7 @@ /** 查询角色信息 by id */ EmployeeRole selectRoleInfoById(String id); /** 查询员工 By id and role */ Employee selectOneByIdAndRole(String id, String roleUniqueStr); } phi_platform_user/src/main/java/com/hx/phip/service/appointment/AppointmentV2Service.java
New file @@ -0,0 +1,40 @@ package com.hx.phip.service.appointment; import com.hx.phiappt.model.*; import com.hx.phiappt.vo.OperatorVo; import java.util.List; /** * @USER: fhx * @DATE: 2024/4/1 **/ public interface AppointmentV2Service { /** 新增预约 */ void add(OperatorVo operatorVo, User user, Appointment appointment, AppointmentInfo appointmentInfo , List<AppointmentProject> appointmentProjectList , List<AppointmentProjectDeviceNo> appointmentProjectDeviceNoList , List<DoctorTime> doctorTimeList , List<DeviceNoSchedule> deviceNoScheduleList); /** 编辑预约 */ void edit(OperatorVo operatorVo, User user, Appointment oldInfo, Appointment appointment , AppointmentInfo appointmentInfo , List<AppointmentProject> appointmentProjectList , List<AppointmentProjectDeviceNo> appointmentProjectDeviceNoList , List<DoctorTime> doctorTimeList , List<DeviceNoSchedule> deviceNoScheduleList); /** 取消预约 */ void cancel(Appointment appointment, OperatorVo operatorVo, String remark, Integer isSendMsg, String annexUrl); /** 查询当天门店转疗订单总数数据 */ int selectCountIsSwitch(String dayStr, String shopId); /** 查询预约其他信息 */ AppointmentInfo selectOneByApptId(String apptId); } phi_platform_user/src/main/java/com/hx/phip/service/appointment/impl/AppointmentV2ServiceImpl.java
New file @@ -0,0 +1,617 @@ package com.hx.phip.service.appointment.impl; import com.hx.common.dao.CommonDao; import com.hx.common.service.CommonService; import com.hx.exception.TipsException; import com.hx.mybatisTool.SqlSentence; import com.hx.phiappt.constants.tool.appointment.AppointmentTool; import com.hx.phiappt.constants.tool.appointment.GuideSyncAppItemUtil; import com.hx.phiappt.dao.mapper.*; import com.hx.phiappt.dao.mapper.AppointmentV2Mapper; import com.hx.phiappt.model.*; import com.hx.phiappt.util.AppointmentV2Util; import com.hx.phiappt.util.system.config.AppointmentConfigUtil; import com.hx.phiappt.vo.OperatorVo; import com.hx.phip.service.appointment.AppointmentV2Service; import com.hx.util.StringUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.*; /** * @USER: fhx * @DATE: 2024/4/1 **/ @Slf4j @Transactional @Service public class AppointmentV2ServiceImpl implements AppointmentV2Service { @Resource private CommonDao commonDao; @Resource private CommonService commonService; @Resource private AppointmentV2Mapper appointmentV2Mapper; /** 新增预约 */ @Override public void add(OperatorVo operatorVo, User user, Appointment appointment, AppointmentInfo appointmentInfo , List<AppointmentProject> appointmentProjectList , List<AppointmentProjectDeviceNo> appointmentProjectDeviceNoList , List<DoctorTime> doctorTimeList , List<DeviceNoSchedule> deviceNoScheduleList) { //检测判断项目是否护士生美 checkProjectIsShengMei(appointment, false); //新增预约 if(commonDao.insert(AppointmentMapper.class, appointment) != 1){ throw new TipsException("新增预约失败!"); } //预约信息-关联表 appointmentInfo.setApptId(appointment.getId()); if(commonDao.insert(AppointmentInfoMapper.class, appointmentInfo) != 1){ throw new TipsException("新增预约信息失败!"); } //处理预约涉及的其他数据 handleAppointmentOtherData(false, appointment, doctorTimeList, appointmentProjectList, appointmentProjectDeviceNoList, deviceNoScheduleList); //预约日志 StringBuffer logRemark = new StringBuffer(); logRemark.append("(").append(Appointment.addModeStr(appointment.getAddMode())).append(")新增预约"); String content = logRemark.toString(); logRemark.setLength(0); logRemark.append("预约项目:").append(appointment.getProjectNames()); commonDao.insert(AppointmentLogMapper.class, new AppointmentLog(operatorVo, appointment.getId(), content, logRemark.toString())); //HIS助手预约时 if(appointment.getAddMode() == Appointment.ADD_MODE_ADVISER_V2_3){ //新增系统消息通知 commonDao.insert(SystemMessageMapper.class, new SystemMessage(SystemMessage.TYPE_CORP_USER_ADD_APP, appointment.getId(), operatorVo)); } //处理预约后定时项逻辑 handleTimerHandleItem(appointment); //更新用户最后预约医生和预约顾问 StringBuilder sql = new StringBuilder(); SqlSentence sqlSentence = new SqlSentence(); Map<String, Object> values = new HashMap<>(); sqlSentence.setM(values); if(StringUtils.noNull(appointment.getDoctorId()) && !appointment.getDoctorId().equals(user.getLastDoctorId())){ values.put("lastDoctorId", appointment.getDoctorId()); sql.append(" lastDoctorId = #{m.lastDoctorId} "); } if(StringUtils.noNull(appointment.getCorpUserId()) && !appointment.getCorpUserId().equals(user.getLastCorpUserId())){ values.put("lastCorpUserId", appointment.getCorpUserId()); sql.append(sql.length() > 0 ? "," : "").append(" lastCorpUserId = #{m.lastCorpUserId} "); } if(sql.length() > 0){ values.put("userId", user.getId()); sql.append(" where id = #{m.userId} "); sqlSentence.setSqlSentence(sql.toString()); commonDao.updateWhere(UserMapper.class, sqlSentence); } //用户预约备注 UserAppointmentRemark userAppointmentRemark = appointmentV2Mapper.selectUserAppointmentRemarkByUserId(user.getId()); if(userAppointmentRemark == null) { userAppointmentRemark = new UserAppointmentRemark(); userAppointmentRemark.setRemark(appointment.getRemark()); userAppointmentRemark.setUserId(user.getId()); commonDao.insert(UserAppointmentRemarkMapper.class, userAppointmentRemark); }else{ userAppointmentRemark.setRemark(appointment.getRemark()); commonDao.updateAll(UserAppointmentRemarkMapper.class, userAppointmentRemark); } } /** 编辑预约 */ @Override public void edit(OperatorVo operatorVo, User user, Appointment oldInfo, Appointment appointment , AppointmentInfo appointmentInfo , List<AppointmentProject> appointmentProjectList , List<AppointmentProjectDeviceNo> appointmentProjectDeviceNoList , List<DoctorTime> doctorTimeList , List<DeviceNoSchedule> deviceNoScheduleList) { //检测判断项目是否护士生美 checkProjectIsShengMei(appointment, false); //更新预约 if( appointmentV2Mapper.updateAppointment(appointment) != 1){ throw new TipsException("编辑更新预约失败!"); } //更新预约信息-关联表 if(appointmentV2Mapper.updateAppointmentInfo(appointmentInfo) != 1){ throw new TipsException("更新预约信息失败!"); } //处理预约涉及的其他数据 handleAppointmentOtherData(true, appointment, doctorTimeList, appointmentProjectList, appointmentProjectDeviceNoList, deviceNoScheduleList); //HIS助手预约时 if(appointment.getAddMode() == Appointment.ADD_MODE_ADVISER_V2_3){ //新增系统消息通知 commonDao.insert(SystemMessageMapper.class, new SystemMessage(SystemMessage.TYPE_CORP_USER_EDIT_APP, appointment.getId(), operatorVo)); } //获取变化日志内容 StringBuffer logInfo = new StringBuffer(); logInfo.append("(").append(Appointment.addModeStr(appointment.getAddMode())).append(")编辑预约"); String logRemark = AppointmentV2Util.checkChangeByEdit(oldInfo, appointment, commonService); commonDao.insert(AppointmentLogMapper.class, new AppointmentLog(operatorVo, appointment.getId(), logInfo.toString(), logRemark)); //统计门店转疗数量 editUpdateShopSwitchNum(oldInfo, appointment, oldInfo.getStatus() == Appointment.STATUS_FAIL ? 1 : 0); //更新下预约成功和待审核数量的统计 editUpdateAppNumCul(oldInfo, appointment); TimerHandleItem timerHandleItem = null; if(appointment.getStatus() == Appointment.STATUS_SUC){ //判断编辑前状态非成功,则统计成功数量 if(oldInfo.getStatus() != Appointment.STATUS_SUC){ timerHandleItem = new TimerHandleItem(); timerHandleItem.setItemNum(1); timerHandleItem.setItemStr(appointment.getId()); timerHandleItem.setItemStr1(appointment.getShopId()); timerHandleItem.setType(TimerHandleItem.TYPE_APP_APPLY_SUC); timerHandleItem.setCreateTime(appointment.getStartTime()); commonDao.insert(TimerHandleItemMapper.class, timerHandleItem); } if(appointment.getIsSendMsg() != null && appointment.getIsSendMsg() == 1){ //发送短信 暂时不发送 0303 timerHandleItem = new TimerHandleItem(); timerHandleItem.setItemNum(3); timerHandleItem.setItemStr(appointment.getId()); timerHandleItem.setType(TimerHandleItem.TYPE_SEND_SHORT_MSG); commonDao.insert(TimerHandleItemMapper.class, timerHandleItem); } //同步到导医 GuideSyncAppItemUtil.syncApp(commonService, appointment.getId()); }else { //同步到导医 GuideSyncAppItemUtil.cancle(commonService, appointment.getId()); } } /** 取消预约 */ @Override public void cancel(Appointment appointment, OperatorVo operatorVo, String remark, Integer isSendMsg, String annexUrl) { //修改状态 SqlSentence sqlSentence = new SqlSentence(); sqlSentence.setSqlSentence(" cancelRemark = #{m.cancelRemark}, notifyStatus = #{m.notifyStatus}, status = #{m.status}, cancelStatus = #{m.cancelStatus}, cancelType = #{m.cancelType}, isSendMsg = #{m.isSendMsg}, cancelTime = now() where id = #{m.id}"); Map<String, Object> map = new HashMap<>(); map.put("notifyStatus", Appointment.NOTIFY_STATUS_NONE); map.put("status", Appointment.STATUS_CANCEL); map.put("cancelStatus", Appointment.CANCEL_STATUS_SUC); map.put("cancelType", Appointment.CANCEL_TYPE_CORP_USER); map.put("cancelRemark", remark); map.put("id", appointment.getId()); map.put("isSendMsg", isSendMsg); sqlSentence.setM(map); if(commonDao.updateWhere(AppointmentMapper.class, sqlSentence) != 1){ throw new TipsException("取消预约失败!"); } if (!StringUtils.isEmpty(annexUrl)){ //更新info表图片 AppointmentTool.updateAppointmentInfo(appointment.getId(), annexUrl, commonDao); } StringBuffer logInfo = new StringBuffer(); logInfo.append("(").append(Appointment.addModeStr(appointment.getAddMode())).append(")取消预约"); String content = logInfo.toString(); logInfo.setLength(0); logInfo.append("取消预约"); if(StringUtils.noNull(remark)){ logInfo.append(",取消备注:").append(remark); } commonDao.insert(AppointmentLogMapper.class, new AppointmentLog(operatorVo, appointment.getId(), content, logInfo.toString())); //移除时间相关 AppointmentV2Util.removeRelateTime(appointment, commonService); TimerHandleItem timerHandleItem = null; //更新下预约统计 if(appointment.getStatus() == Appointment.STATUS_WAIT || appointment.getStatus() == Appointment.STATUS_SUC) { timerHandleItem = new TimerHandleItem(); timerHandleItem.setItemStr(appointment.getId()); timerHandleItem.setItemNum(-1); timerHandleItem.setCreateTime(appointment.getStartTime()); timerHandleItem.setItemStr1(appointment.getShopId()); if (appointment.getStatus() == Appointment.STATUS_WAIT) { //待审核预约统计-1 timerHandleItem.setType(TimerHandleItem.TYPE_APP_APPLY); } else if (appointment.getStatus() == Appointment.STATUS_SUC) { //审核成功统计-1 timerHandleItem.setType(TimerHandleItem.TYPE_APP_SUC); } commonDao.insert(TimerHandleItemMapper.class, timerHandleItem); } //转疗数量统计-1 if(appointment.getIsSwitch() == BaseEntity.YES) { timerHandleItem = new TimerHandleItem(); timerHandleItem.setItemStr(appointment.getId()); timerHandleItem.setItemNum(-1); timerHandleItem.setCreateTime(appointment.getStartTime()); timerHandleItem.setItemStr1(appointment.getShopId()); timerHandleItem.setType(TimerHandleItem.TYPE_APP_SWITCH); commonDao.insert(TimerHandleItemMapper.class, timerHandleItem); } //发送系统消息 timerHandleItem = new TimerHandleItem(); timerHandleItem.setItemStr(appointment.getId()); timerHandleItem.setType(TimerHandleItem.TYPE_SEND_QY_MSG); commonDao.insert(TimerHandleItemMapper.class, timerHandleItem); if(isSendMsg != null && isSendMsg == 1){ //发送取消预约通知:短信+公众号消息 timerHandleItem = new TimerHandleItem(); timerHandleItem.setItemNum(2); timerHandleItem.setItemStr(appointment.getId()); timerHandleItem.setType(TimerHandleItem.TYPE_SEND_SHORT_MSG); commonDao.insert(TimerHandleItemMapper.class, timerHandleItem); } //同步到导医 GuideSyncAppItemUtil.cancle(commonService, appointment.getId()); } /** 查询当天门店转疗订单总数数据 */ @Override public int selectCountIsSwitch(String dayStr, String shopId) { return appointmentV2Mapper.selectCountIsSwitch(dayStr, shopId); } @Override public AppointmentInfo selectOneByApptId(String apptId) { return appointmentV2Mapper.selectOneByApptId(apptId); } ///////////////////////////////////////////////////////////////////////////////////////////////// //检测判断项目是否护士生美 private void checkProjectIsShengMei(Appointment appointment, boolean isEdit){ //判断是否项目是否包含护士生美项目 int count= appointmentV2Mapper.isShengMei(appointment.getProjectIds().contains(",") ? Arrays.asList(appointment.getProjectIds().split(",")) : Arrays.asList(appointment.getProjectIds())); log.info("============统计========="+count); if(count > 0){ appointment.setIsLifeBeauty(2); //his助手预约时判断 if(appointment.getAddMode() == Appointment.ADD_MODE_ADVISER_V2_3){ Shop shop = commonDao.selectOneByKey(ShopMapper.class, appointment.getShopId()); int shengMeiNum = appointmentV2Mapper.selectCountShengMei(appointment.getShopId(), appointment.getDayStr(), isEdit ? appointment.getId() : null); if(shengMeiNum>0 && shop.getShengMeiNum() !=null && shengMeiNum >=shop.getShengMeiNum()&&shop.getShengMeiNum()>0 && appointment.getIsMicApprove() ==0){ throw new TipsException("生美预约订单数量已经超过最大值"); } } } } //处理预约涉及的其他数据 private void handleAppointmentOtherData(boolean isEdit, Appointment appointment , List<DoctorTime> doctorTimeList , List<AppointmentProject> appointmentProjectList , List<AppointmentProjectDeviceNo> appointmentProjectDeviceNoList , List<DeviceNoSchedule> deviceNoScheduleList ){ SqlSentence sqlSentence = new SqlSentence(); Map<String, Object> values = new HashMap<>(); sqlSentence.setM(values); //预约项目--------------------------------------------------------------------------------------- //把旧的移除掉 if(isEdit){ sqlSentence.setSqlSentence(" appId = #{m.apptId} "); values.put("apptId", appointment.getId()); commonDao.deleteWhere(AppointmentProjectMapper.class, sqlSentence); } //预约项目 for(AppointmentProject appointmentProject : appointmentProjectList) { appointmentProject.setAppId(appointment.getId()); if(commonDao.insert(AppointmentProjectMapper.class, appointmentProject) != 1){ throw new TipsException("新增预约项目失败!"); } } //门店排班时间------------------------------------------------------------------------------------- int count = 0; String monthStr = appointment.getDayStr().substring(0, 6); ShopTime shopTime = null; if(isEdit){ sqlSentence.setSqlSentence(" select * from shop_time where apptId = #{m.apptId}"); values.put("apptId", appointment.getId()); shopTime = commonDao.selectOne(ShopTimeMapper.class, sqlSentence); } if(shopTime == null) { shopTime = new ShopTime(ShopTime.TIME_TYPE_APPT, appointment.getId()); } shopTime.setMonthStr(monthStr); shopTime.setDayStr(appointment.getDayStr()); shopTime.setStartTime(appointment.getStartTime()); shopTime.setShopId(appointment.getShopId()); shopTime.setEndTime(appointment.getEndTime()); if(StringUtils.isEmpty(shopTime.getId())){ count = commonDao.insert(ShopTimeMapper.class, shopTime); }else{ count = commonDao.updateAll(ShopTimeMapper.class, shopTime); } if(count != 1){ throw new TipsException("处理预约门店排班时间失败!"); } //医生面诊和治疗排班时间---------------------------------------------------------------------- if(isEdit){ //删除治疗和面诊时间 values.put("aptId", appointment.getId()); sqlSentence.setSqlSentence(" aptId = #{m.aptId} and timeType = 2 "); commonDao.deleteWhere(DoctorTimeMapper.class, sqlSentence); } if(StringUtils.noNull(appointment.getDoctorId())){ //及时面诊开始和结束时间 Date docComSt, docComEt; Calendar ca = Calendar.getInstance(); ca.setTime(appointment.getStartTime()); ca.add(Calendar.MINUTE, appointment.getComDuration()); docComSt = ca.getTime(); ca.add(Calendar.MINUTE, appointment.getDocComDuration()); docComEt = ca.getTime(); //面诊医生时间 DoctorTime doctorTime = new DoctorTime(); doctorTime.setTimeType(DoctorTime.TIME_TYPE_APPT); doctorTime.setStartTime(docComSt); doctorTime.setShopId(appointment.getShopId()); doctorTime.setMonthTime(appointment.getMonthStr()); doctorTime.setEndTime(docComEt); doctorTime.setDoctorId(appointment.getDoctorId()); doctorTime.setDayTime(appointment.getDayStr()); doctorTime.setAptId(appointment.getId()); doctorTime.setApptType(DoctorTime.APPT_TYPE_COM); if(commonDao.insert(DoctorTimeMapper.class, doctorTime) != 1){ throw new TipsException("新增预约医生面诊时间失败!"); } //医生治疗时间 if(doctorTimeList != null){ for(DoctorTime dt : doctorTimeList){ dt.setAptId(appointment.getId()); if(commonDao.insert(DoctorTimeMapper.class, dt) != 1){ throw new TipsException("新增预约医生治疗时间失败!"); } } } } //设备部分逻辑处理---------------------------------------------------------------------------- if(isEdit){ //移除预约项目设备 sqlSentence.setSqlSentence(" appId = #{m.apptId} "); values.put("apptId", appointment.getId()); commonDao.deleteWhere(AppointmentProjectDeviceNoMapper.class, sqlSentence); //移除设备排班 sqlSentence.setSqlSentence(" aptId = #{m.aptId}"); values.put("aptId", appointment.getId()); commonDao.deleteWhere(DeviceNoScheduleMapper.class, sqlSentence); } //预约关联设备记录 if(appointmentProjectDeviceNoList != null){ for(AppointmentProjectDeviceNo apdn : appointmentProjectDeviceNoList) { apdn.setAppId(appointment.getId()); if(commonDao.insert(AppointmentProjectDeviceNoMapper.class, apdn) != 1){ throw new TipsException("新增预约项目使用设备信息失败!"); } } } //设备预约时间占用记录 if(deviceNoScheduleList != null){ for(DeviceNoSchedule dns : deviceNoScheduleList) { dns.setAptId(appointment.getId()); if(commonDao.insert(DeviceNoScheduleMapper.class, dns) != 1){ throw new TipsException("新增设备排班信息失败!"); } } } } //新增预约 - 处理预约后定时项逻辑 private void handleTimerHandleItem(Appointment appointment){ TimerHandleItem timerHandleItem; //待审核 if(appointment.getStatus() == Appointment.STATUS_WAIT){ //统计新增预约审核成功统计 timerHandleItem = new TimerHandleItem(); timerHandleItem.setItemNum(1); timerHandleItem.setItemNum1(1); timerHandleItem.setItemStr(appointment.getId()); timerHandleItem.setItemStr1(appointment.getShopId()); timerHandleItem.setType(TimerHandleItem.TYPE_APP_APPLY); timerHandleItem.setCreateTime(appointment.getStartTime()); commonDao.insert(TimerHandleItemMapper.class, timerHandleItem); //处理是否发送预约审核通知 AppointmentConfigUtil.handleAppointmentAuditNotice(commonDao, appointment); }else if(appointment.getStatus() == Appointment.STATUS_SUC){ //预约成功 timerHandleItem = new TimerHandleItem(); timerHandleItem.setItemNum(1); timerHandleItem.setItemStr(appointment.getId()); timerHandleItem.setItemStr1(appointment.getShopId()); timerHandleItem.setType(TimerHandleItem.TYPE_APP_APPLY_SUC); timerHandleItem.setCreateTime(appointment.getStartTime()); commonDao.insert(TimerHandleItemMapper.class, timerHandleItem); //统计转疗 if(appointment.getIsSwitch() == BaseEntity.YES){ timerHandleItem = new TimerHandleItem(); timerHandleItem.setItemNum(-1); timerHandleItem.setItemStr(appointment.getId()); timerHandleItem.setItemStr1(appointment.getShopId()); timerHandleItem.setType(TimerHandleItem.TYPE_APP_SWITCH); timerHandleItem.setCreateTime(appointment.getStartTime()); commonDao.insert(TimerHandleItemMapper.class, timerHandleItem); } if(appointment.getIsSendMsg() != null && appointment.getIsSendMsg() == 1){ //发送短信 暂时不发送 0303 timerHandleItem = new TimerHandleItem(); timerHandleItem.setItemNum(1); timerHandleItem.setItemStr(appointment.getId()); timerHandleItem.setType(TimerHandleItem.TYPE_SEND_SHORT_MSG); commonDao.insert(TimerHandleItemMapper.class, timerHandleItem); } //发送企业微信消息给顾问 timerHandleItem = new TimerHandleItem(); timerHandleItem.setItemStr(appointment.getId()); timerHandleItem.setType(TimerHandleItem.TYPE_AUDIT_APP_SUC); commonDao.insert(TimerHandleItemMapper.class, timerHandleItem); //新增同步导医处理 GuideSyncAppItemUtil.syncApp(commonService, appointment.getId()); } } /** 编辑预约 - 更新预约成功或者待审数量统计*/ private void editUpdateAppNumCul(Appointment oldInfo, Appointment appointment) { //先把原来成功或者待审的移除 TimerHandleItem timerHandleItem; if(oldInfo.getStatus() == Appointment.STATUS_WAIT || oldInfo.getStatus() == Appointment.STATUS_SUC) { timerHandleItem = new TimerHandleItem(); timerHandleItem.setItemNum(-1); timerHandleItem.setItemStr(oldInfo.getId()); timerHandleItem.setItemStr1(oldInfo.getShopId()); timerHandleItem.setCreateTime(oldInfo.getStartTime()); if(oldInfo.getStatus() == Appointment.STATUS_WAIT){ timerHandleItem.setType(TimerHandleItem.TYPE_APP_APPLY); }else if(oldInfo.getStatus() == Appointment.STATUS_SUC) { timerHandleItem.setType(TimerHandleItem.TYPE_APP_SUC); } commonDao.insert(TimerHandleItemMapper.class, timerHandleItem); } //新增成功或者待审核的增加 if(appointment.getStatus() == Appointment.STATUS_WAIT || appointment.getStatus() == Appointment.STATUS_SUC) { timerHandleItem = new TimerHandleItem(); timerHandleItem.setItemNum(1); timerHandleItem.setItemStr(appointment.getId()); timerHandleItem.setItemStr1(appointment.getShopId()); timerHandleItem.setCreateTime(appointment.getStartTime()); if (appointment.getStatus() == Appointment.STATUS_WAIT) { timerHandleItem.setType(TimerHandleItem.TYPE_APP_APPLY); //处理是否发送预约审核通知 AppointmentConfigUtil.handleAppointmentAuditNotice(commonDao, appointment); } else if (appointment.getStatus() == Appointment.STATUS_SUC) { timerHandleItem.setType(TimerHandleItem.TYPE_APP_SUC); //新增同步导医处理 GuideSyncAppItemUtil.syncApp(commonService, appointment.getId()); } commonDao.insert(TimerHandleItemMapper.class, timerHandleItem); } } /**编辑预约 - 更新下门店的转疗数量*/ private void editUpdateShopSwitchNum(Appointment oldInfo, Appointment appointment, Integer isFailEdit) { TimerHandleItem timerHandleItem = null; if(isFailEdit == 1) { //从审核失败到修改重新提审 if(appointment.getIsSwitch() == 1) { timerHandleItem = new TimerHandleItem(); timerHandleItem.setItemNum(1); timerHandleItem.setItemStr(oldInfo.getId()); timerHandleItem.setItemStr1(appointment.getShopId()); timerHandleItem.setType(TimerHandleItem.TYPE_APP_SWITCH); timerHandleItem.setCreateTime(appointment.getStartTime()); commonDao.insert(TimerHandleItemMapper.class, timerHandleItem); } }else { if (oldInfo.getShopId().equals(appointment.getShopId())) { if (oldInfo.getIsSwitch() == BaseEntity.NO && appointment.getIsSwitch() == 1) { timerHandleItem = new TimerHandleItem(); timerHandleItem.setItemNum(1); timerHandleItem.setItemStr(oldInfo.getId()); timerHandleItem.setItemStr1(oldInfo.getShopId()); timerHandleItem.setType(TimerHandleItem.TYPE_APP_SWITCH); timerHandleItem.setCreateTime(appointment.getStartTime()); commonDao.insert(TimerHandleItemMapper.class, timerHandleItem); } else if (oldInfo.getIsSwitch() == BaseEntity.YES && appointment.getIsSwitch() == 0) { timerHandleItem = new TimerHandleItem(); timerHandleItem.setItemNum(-1); timerHandleItem.setItemStr(oldInfo.getId()); timerHandleItem.setItemStr1(oldInfo.getShopId()); timerHandleItem.setType(TimerHandleItem.TYPE_APP_SWITCH); timerHandleItem.setCreateTime(oldInfo.getStartTime()); commonDao.insert(TimerHandleItemMapper.class, timerHandleItem); } } else { if (oldInfo.getIsSwitch() == BaseEntity.YES) { //原来是转疗的,则把原来的取消 timerHandleItem = new TimerHandleItem(); timerHandleItem.setItemNum(-1); timerHandleItem.setItemStr(oldInfo.getId()); timerHandleItem.setItemStr1(oldInfo.getShopId()); timerHandleItem.setType(TimerHandleItem.TYPE_APP_SWITCH); timerHandleItem.setCreateTime(oldInfo.getStartTime()); commonDao.insert(TimerHandleItemMapper.class, timerHandleItem); } if (appointment.getIsSwitch() == BaseEntity.YES) { //当前是转疗,则添加现在的 timerHandleItem = new TimerHandleItem(); timerHandleItem.setItemNum(1); timerHandleItem.setItemStr(oldInfo.getId()); timerHandleItem.setItemStr1(appointment.getShopId()); timerHandleItem.setType(TimerHandleItem.TYPE_APP_SWITCH); timerHandleItem.setCreateTime(appointment.getStartTime()); commonDao.insert(TimerHandleItemMapper.class, timerHandleItem); } } } } } phi_platform_user/src/main/java/com/hx/phip/service/impl/EmployeeServiceImpl.java
@@ -105,4 +105,10 @@ public EmployeeRole selectRoleInfoById(String id) { return employeeMapper.selectRoleInfoById(id); } /** 查询员工 By id and role */ @Override public Employee selectOneByIdAndRole(String id, String roleUniqueStr) { return employeeMapper.selectOneByIdAndRole(id, roleUniqueStr); } }