/**
 * Copyright &copy; 2012-2014 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.cku.oa.show.service;

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.cku.core.RESTResponse;
import com.cku.core.ZAErrorCode;
import com.cku.core.ZAException;
import com.cku.oa.dog.dao.DogColorMarkDao;
import com.cku.oa.dog.dao.DogDao;
import com.cku.oa.dog.entity.Dog;
import com.cku.oa.dog.entity.DogColorMark;
import com.cku.oa.dog.entity.DogType;
import com.cku.oa.dog.entity.DogTypeShow;
import com.cku.oa.dog.service.BusinessBanService;
import com.cku.oa.dog.service.DogService;
import com.cku.oa.dog.service.DogStickerApplyService;
import com.cku.oa.dog.service.DogTypeService;
import com.cku.oa.dog.service.DogTypeShowService;
import com.cku.oa.finance.entity.PaymentChargingItem;
import com.cku.oa.finance.service.PaymentChargingItemService;
import com.cku.oa.order.service.impl.ShowApplyOrderServiceImpl;
import com.cku.oa.order.vo.ShowApplyFeeVO;
import com.cku.oa.show.dao.ChampionLoginDao;
import com.cku.oa.show.dao.ChildShowsDao;
import com.cku.oa.show.dao.MainShowsDao;
import com.cku.oa.show.dao.ShowApplyDao;
import com.cku.oa.show.dao.ShowFciContrastDao;
import com.cku.oa.show.dao.ShowJudgeDao;
import com.cku.oa.show.entity.ChampionLogin;
import com.cku.oa.show.entity.ChildShows;
import com.cku.oa.show.entity.MainShows;
import com.cku.oa.show.entity.ShowApply;
import com.cku.oa.show.entity.ShowApplyPage;
import com.cku.oa.show.entity.ShowFciContrast;
import com.cku.oa.show.entity.ShowJudge;
import com.cku.oa.show.entity.ShowResults;
import com.cku.oa.show.entity.ShowScoreBlankExport;
import com.cku.oa.show.entity.ShowSortBreed;
import com.cku.oa.show.entity.ShowSortGroup;
import com.cku.oa.sys.code.SysCodeUtil;
import com.cku.oa.sys.entity.user.Member;
import com.cku.oa.sys.service.LoginServerService;
import com.cku.oa.sys.service.RemindService;
import com.cku.oa.sys.service.user.MemberService;
import com.cku.oa.sys.util.MemberUtil;
import com.cku.oa.sys.util.ZtSmsUtil;
import com.cku.restful.v1.dog.service.RestDogService;
import com.cku.restful.v1.finance.service.OADeleteService;
import com.cku.util.DateUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.common.service.CrudService;
import com.thinkgem.jeesite.common.utils.excel.ExportExcel;
import com.thinkgem.jeesite.common.utils.excel.ImportExcel;
import com.thinkgem.jeesite.modules.sys.entity.Dict;
import com.thinkgem.jeesite.modules.sys.entity.User;
import com.thinkgem.jeesite.modules.sys.utils.DataPermissionUtil;
import com.thinkgem.jeesite.modules.sys.utils.DictUtils;
import com.thinkgem.jeesite.modules.sys.utils.UserUtils;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

/**
 * 犬展报名表Service
 *
 * @author lgl
 * @version 2016-07-15
 */
@Service
@Transactional(readOnly = true)
public class ShowApplyService extends CrudService<ShowApplyDao, ShowApply> {

	private static final String DOG_SHOW_COUPON = "sys_coupon@show";
	private static final String DOG_SHOW_COUPON_ZZ = "sys_coupon@show_zz";// 郑州办公室
	private static final String DOG_SHOW_COUPON_CQ = "sys_coupon@show_cq";// 重庆办公室
	private static final String DOG_SHOW_COUPON_HZ = "sys_coupon@show_hz";// 杭州办公室
	private static final String DOG_SHOW_COUPON_CS = "sys_coupon@show_cs";// 长沙办公室
	private static final String DOG_SHOW_COUPON_BJ = "sys_coupon@show_bj";// 北京办公室
	private static final String DOG_SHOW_COUPON_CC = "sys_coupon@show_cc";// 长春办公室
	private static final String DOG_SHOW_COUPON_NF = "sys_coupon@show_nf";// 南方区
	private static final String DOG_SHOW_COUPON_BF = "sys_coupon@show_bf";// 北方区

	@Autowired
	private ChildShowsService childShowsService;
	@Autowired
	private MemberService memberService;
	@Autowired
	private DogService dogService;
	@Autowired
	private RestDogService restDogService;
	@Autowired
	private MainShowsService mainShowsService;
	@Autowired
	private DogTypeService dogTypeService;
	@Autowired
	private DogTypeShowService dogTypeShowService;
	@Autowired
	private PaymentChargingItemService paymentChargingItemService;
	@Autowired
	private RemindService remindService;
	@Autowired
	private OADeleteService oADeleteService;
	@Autowired
	private BusinessBanService businessBanService;
	@Autowired
	private ChildShowsDao childShowsDao;
	@Autowired
	private ChampionLoginService championLoginService;
	@Autowired
	private ChampionLoginDao championLoginDao;
	@Autowired
	private MainShowsDao mainShowsDao;
	@Autowired
	private DogColorMarkDao dogColorMarkDao;
	@Autowired
	private LoginServerService loginServerService;
	@Autowired
	private ShowFciContrastDao showFciContrastDao;
	@Autowired
	private ShowJudgeDao showJudgeDao;
	@Autowired
	private DogDao dogDao;
	@Autowired
	private DogStickerApplyService dogStickerApplyService;
	@Autowired
	private ShowApplyDiscountService showApplyDiscountService;

	public ShowApply get(String id) {
		return super.get(id);
	}

	public List<ShowApply> findList(ShowApply showApply) {
		return super.findList(showApply);
	}

	/**
	 * 申请退款数据
	 *
	 * @param ids
	 * @return
	 */
	public RESTResponse getRefundList(String ids) {
		ShowApply showApply = new ShowApply();
		showApply.setDelFlag("0");
		showApply.setId(ids);
		List<ShowApply> showApplyList = findList(showApply);
		JSONArray jsonArray = new JSONArray();
		for (ShowApply i : showApplyList) {
			JSONObject jsonObject = new JSONObject();
			jsonObject.put("reviewStateCode", "0");
			jsonObject.put("showCode", i.getShowCode());
			jsonObject.put("pedigreeCertified", i.getPedigreeCertified());
			jsonObject.put("dogOwnerNameCn", i.getDogOwnerNameCn());
			jsonObject.put("id", i.getId());
			jsonObject.put("mainShowName", mainShowsService.get(i.getMainShowId()).getMainShowName());
			jsonArray.add(jsonObject);
		}
		return new RESTResponse("data", jsonArray);
	}

	public Page<ShowApply> findPage(Page<ShowApply> page, ShowApply showApply) {
		// 根据当前登录端查询犬种
		if (StringUtils.isBlank(showApply.getDogBreedNameCn())) {
			String dogType = loginServerService.findDogType();
			if (dogType != null && !dogType.contains(",")) {
				DogType dog1 = dogTypeService.getByDogBreedCode(dogType);
				showApply.setDogBreedNameCn(dog1.getBreedCnName());
			}
		}
		User loginUser = UserUtils.getLoginUser();
		if ("1".equals(loginUser.getUserType())) {// OA系统用户用办公室区分
			// 在sql中加入对organizer字段进行筛选
			showApply.getSqlMap().put("organizer", dataScopeFilterNew());
			// 默认只能查询OA申请的未缴费订单
			// 有权限的可以无视
			if (!SecurityUtils.getSubject().isPermitted("apply:showApply:notDefault")) {
				showApply.getSqlMap().put("default", "0");
			}
		}
		
		return super.findPage(page, showApply);
	}

	@Transactional(readOnly = false)
	public void save(ShowApply showApply) {
		super.save(showApply);
	}

	/**
	 * 保存犬展报名信息
	 *
	 * @param showApply
	 * @throws Exception
	 */
	@Transactional(readOnly = false)
	public synchronized void saveShowApply(ShowApply showApply) throws Exception {
		boolean isSendMsg = false;//只有新增报名记录的时候发一次短信
		// 业务校验
		validateBusiness(showApply);
		if (StringUtils.isBlank(showApply.getId())) {
			isSendMsg = true ;
			// 计算犬展报名手续费并设置犬展编号
			calculateShowApplyFee(showApply);
			// 设置用于统计的收费项id
			setPaymentChargingItemId(showApply);
			showApply.setRefundFlag("0");
			showApply.setAbsenceFlag("0");
			showApply.setPaymentState("1");
		} else {
			// OA犬展报名编辑，更新年龄组别
			updateAgeGroup(showApply);
		}
		// 处理芯片为空的情况
		if (StringUtils.isBlank(showApply.getChipCode())) {
			showApply.setChipCode("累计成绩需登记芯片");
		}
		super.save(showApply);
		// 更新狗表犬只代数
		String pedigreeCertified = showApply.getPedigreeCertified();
		Dog dog = dogService.getByPedigreeCertifiedCode(pedigreeCertified);
		Integer dogGeneration = restDogService.getDogGeneration(dog.getPedigreeCertifiedCode());
		dog.setDogGeneration(dogGeneration.toString());
		dogDao.updateDogGeneration(dog);
		if(isSendMsg) {
			// 给用户发送消息
			sendMsg(showApply);
		}
		// 是否满足进入满减周期的条件
		boolean isCycleSign = showApplyDiscountService.isCycleSignForStringParam(showApply.getPedigreeCertified(),
				showApply.getAgeGroupJson());
		if (isCycleSign) {
			// 记录满减优惠
			showApplyDiscountService.saveNewRecord(showApply);// 0减免 1不减免
		}
	}

	/**
	 * @description: OA犬展报名编辑，更新年龄组别
	 * @author: laiguanglong
	 * @date: 2017/7/29 12:53
	 */
	private void updateAgeGroup(ShowApply showApply) {
		String[] childShowIdAgeGroupArray = showApply.getAgeGroupJson().split(",");
		StringBuilder sb = new StringBuilder();
		for (String childShowIdAgeGroupString : childShowIdAgeGroupArray) {
			String[] childShowIdAgeGroup = childShowIdAgeGroupString.split("=");
			sb.append(childShowIdAgeGroup[1]).append(",");
		}
		showApply.setAgeGroup(sb.deleteCharAt(sb.length() - 1).toString());
	}

	/**
	 * 会员资格校验
	 *
	 * @param showApply
	 * @param mainShowsStartTime
	 * @throws Exception
	 */
	private void validateMember(ShowApply showApply, Date mainShowsStartTime) throws ZAException {
		Member member1 = memberService.getByMemberCode(showApply.getDogOwnerMemberCode());
		if (showApply.getPedigreeCertified().toUpperCase().startsWith("CKU") && !MemberUtil.isActiveMember(member1)) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "犬主人会员已过期");
		}
		if (suspendStatus(showApply.getDogOwnerMemberCode(), mainShowsStartTime)) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "该场活动报名不成功，请致电010-53977050");
		}
		String handlerMemberCode = showApply.getHandlerMemberCode();
		// 由于CAB过来的犬展报名handlerMemberCode格式为16615,陈曦,15524289999，需要进行处理
		if (handlerMemberCode.contains(",")) {
			handlerMemberCode = handlerMemberCode.split(",")[0];
		}
		Member handler = memberService.getByMemberCode(handlerMemberCode);
		// 校验牵犬师会员
		validateHandler(handler, showApply.getMainShowId());
	}

	/**
	 * @description: 校验牵犬师会员
	 * @author: laiguanglong
	 * @date: 2017/12/27 16:43
	 */
	public void validateHandler(Member handler, String mainShowId) {
		// 【犬展-犬展报名】牵犬师会员类型为外籍会员时可以为无效会员
		if (!"foreign".equals(handler.getMemberType()) && !MemberUtil.isActiveMember(handler)) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "牵犬师会员已过期");
		}
		MainShows mainShows = mainShowsDao.get(mainShowId);
		if ("1".equals(mainShows.getHandlerPhotoFlag())) {
			// 必须有照片
			if (StringUtils.isBlank(handler.getAvatar())) {
				throw new ZAException(ZAErrorCode.ZA_ERC_UNKNOWN,
						"您选择的牵犬师还没有上传证件照，无法报名犬展.会员中心添加照片请前往“个人中心”页面，点击“证件照上传”按钮即可添加");
			}
		}
		// 犬展活动报名牵犬师项添加“禁赛”校验
		if (suspendStatus(handler.getMemberCode(), mainShows.getStartTime())) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "该场活动报名不成功，请致电010-53977050");
		}
	}

	/**
	 * 计算犬展报名手续费并设置犬展编号
	 *
	 * @param showApply
	 * @return
	 * @throws Exception
	 */
	public String calculateShowApplyFee(ShowApply showApply) throws Exception {
		if (StringUtils.isBlank(showApply.getShowCode())) {
			return "0";
		}

		String[] childShowIdArray;
		if (StringUtils.isNotBlank(showApply.getAgeGroupJson())) {
			childShowIdArray = showApply.getAgeGroupJson().split(",");
		} else {
			childShowIdArray = showApply.getShowCode().split(",");
		}
		// 保存犬展编号的空数组
		String[] showCodeArray = new String[childShowIdArray.length];
		// 计算电话报名服务费
		String phoneApplyFeeString = "";
		// 如果oa报名的犬只血统证书号不为CKU开头，不收服务费
		// 将CKU-NB前缀的犬只和CKUTM-开头的藏獒犬取消电话报名费
		// 2018-11-28增加CKURK取消电话报名费
		// 2019-02-13增加CKU-JD取消电话报名费
		if (showApply.getPedigreeCertified() != null
				&& (!showApply.getPedigreeCertified().toUpperCase().startsWith("CKU")
						|| showApply.getPedigreeCertified().toUpperCase().startsWith("CKU-NB")
						|| showApply.getPedigreeCertified().toUpperCase().startsWith("CKUTM")
						|| showApply.getPedigreeCertified().toUpperCase().startsWith("CKURK")
						|| showApply.getPedigreeCertified().toUpperCase().startsWith("CKU-JD"))) {
			showApply.setPhoneApplyFlag(null);
		}
		if (showApply.getPedigreeCertified() == null || ("0".equals(showApply.getPhoneApplyFlag())
				&& showApply.getPedigreeCertified().toUpperCase().startsWith("CKU"))) {
			PaymentChargingItem paymentChargingItem = paymentChargingItemService.get("195");
			double price = Double.parseDouble(paymentChargingItem.getPrice());
			double phoneApplyFee = price * childShowIdArray.length;
			showApply.setPhoneApplyFee(phoneApplyFee + "");
			phoneApplyFeeString = (int) phoneApplyFee + "+";
		}
		// 本次报名是否满减优惠
		Map<String, String> showIdAgeGroups = new HashMap<>();
		for (int i = 0; i < childShowIdArray.length; i++) {
			String[] showIdAgeGroupArray = childShowIdArray[i].split("=");
			showIdAgeGroups.put(showIdAgeGroupArray[0], showIdAgeGroupArray[1]);
		}
		boolean isDiscount = showApplyDiscountService.isDiscount(showApply.getPedigreeCertified(), showIdAgeGroups);
		String mainShowId = showApplyDiscountService.getMainShowId(childShowIdArray[0].split("=")[0]);
		Set<String> set = showApplyDiscountService.getDiscountChildShowsId(mainShowId);// 所有参与优惠的子犬展

		// 计算报名费
		// 2018-11-29增加世界杯犬展9月龄下报名费不变规则
		double totalFee = 0;
		Dog dog = dogService.getByPedigreeCertifiedCode(showApply.getPedigreeCertified());
		Map<String, String> map = new HashMap<String, String>();
		for (int i = 0; i < childShowIdArray.length; i++) {
			String childShowIdAndAgeGroup = childShowIdArray[i];
			String childShowId = childShowIdAndAgeGroup;
			String ageGroup = childShowIdAndAgeGroup;
			if (childShowIdAndAgeGroup.contains("=")) {
				childShowId = childShowIdAndAgeGroup.split("=")[0];
				ageGroup = childShowIdAndAgeGroup.split("=")[1];
			}
			ChildShows childShows = childShowsService.get(childShowId);
			String fee = childShows.getFee();
			if (dog != null && !StringUtils.isBlank(dog.getId())) {
				int monthAge = getMonthAge(childShows.getStartTime(), dog.getBirthdate());
				if (monthAge < 9) {
					String tempFee = getFeeByShow(childShowId);
					fee = StringUtils.isBlank(tempFee) ? fee : tempFee;
				}
			}
			// UPDATE BY ZJW 2021-07-01 单独展，幼小组（6-9月龄） 收费标准调整，不在优惠为 150
			// TAPD 【ID1003980】关于更改单独展4-6月龄报名费
			if ("1".equals(childShows.getShowRules())
					&& (Integer.parseInt(ageGroup) == 3 || Integer.parseInt(ageGroup) == 4)) {
				// 如果是单独展，幼小组不做处理
			} else if (Integer.parseInt(ageGroup) <= 4) {
				// 特幼幼小组报名费固定150
				fee = "150";
			}
			// 此场犬展活动费用是否满减
			if (isDiscount && set.contains(childShowId)) {
				fee = "0.00";
			}

			totalFee += Double.parseDouble(fee);
			showCodeArray[i] = childShows.getShowCode();
			if (childShowIdAndAgeGroup.contains("=")) {
				map.put(childShows.getShowCode(), childShowIdAndAgeGroup.split("=")[1]);
			}
		}
		// 犬展编号排序
		Arrays.sort(showCodeArray);
		StringBuilder showCodes = new StringBuilder();
		StringBuilder ageGroups = new StringBuilder();
		for (String showCode : showCodeArray) {
			showCodes.append(",").append(showCode);
			ageGroups.append(",").append(map.get(showCode));
		}
		// 判断是否有优惠卷
		double sysCouponPrice = 0;
		if (StringUtils.isNotBlank(showApply.getNowCouponNum())) {
			String useCouponNum = showApply.getNowCouponNum();
			int num = Integer.parseInt(useCouponNum);
			if (num > 0) {
				sysCouponPrice = -150;
				// 判断子犬展是否可以使用
				ArrayList<Integer> noUseList = Lists.newArrayList();
				for (int i = 0; i < showCodeArray.length; i++) {
					String showCode = showCodeArray[i];
					ChildShows childShows = childShowsService.getByShowCode(showCode);
					if (childShows.getUseCoupon().equals("1")) {
						noUseList.add(i);
					}
				}
				// 获取收费项
				MainShows mainShows = mainShowsDao.get(showApply.getMainShowId());
				String label = DictUtils.getDictLabel(mainShows.getOrganizer(), "show_organizer", "");
				String shortName = getOrganizerName(label);
				PaymentChargingItem paymentChargingItem = paymentChargingItemService.getByShortName(shortName);
				if (paymentChargingItem == null) {
					throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "获取CAC犬展免费参展券失败！");
				}
				// 判断优惠券在某个组别是否可以显示
				ArrayList<String> ageList = new ArrayList<>(Arrays.asList(ageGroups.substring(1).split(",")));
				Collections.reverse(noUseList);
				for (int i : noUseList) {
					ageList.remove(i);
				}
				for (String age : ageList) {
					if (Integer.parseInt(age) > 4) {
						sysCouponPrice = Double.parseDouble(paymentChargingItem.getPrice());
					}
				}
			}
		}
		showApply.setOrderPrice((totalFee + sysCouponPrice) + "");
		String fee = phoneApplyFeeString + (int) (totalFee + sysCouponPrice);
		showApply.setFee(fee);
		showApply.setShowCode(showCodes.substring(1));
		showApply.setAgeGroup(ageGroups.substring(1));

		return fee;
	}

	/**
	 * @description: 选择该场犬展 办公室相应的业务表名
	 * @author: 张向
	 * @date: 2019/3/7 10:00
	 */
	public String getOrganizerName(String label) {
		String shortName = null;
		if (label.indexOf("郑州") != -1) {
			shortName = DOG_SHOW_COUPON_ZZ;
		} else if (label.indexOf("重庆") != -1) {
			shortName = DOG_SHOW_COUPON_CQ;
		} else if (label.indexOf("杭州") != -1) {
			shortName = DOG_SHOW_COUPON_HZ;
		} else if (label.indexOf("长沙") != -1) {
			shortName = DOG_SHOW_COUPON_CS;
		} else if (label.indexOf("北京") != -1) {
			shortName = DOG_SHOW_COUPON_BJ;
		} else if (label.indexOf("长春") != -1) {
			shortName = DOG_SHOW_COUPON_CC;
		} else if (label.indexOf("南方区") != -1) {
			shortName = DOG_SHOW_COUPON_NF;
		} else if (label.indexOf("北方区") != -1) {
			shortName = DOG_SHOW_COUPON_BF;
		} else {
			shortName = DOG_SHOW_COUPON;
		}
		return shortName;
	}

	/**
	 * @Description： 增加世界杯犬展9月龄下报名费不变规则, 获得报名费金额,仅供世界杯犬展使用。
	 * 
	 * @author: yuanshuai
	 * @date: 2018/11/29 14:48
	 */
	public String getFeeByShow(String childShowId) {
		if (childShowId.equals("e5c9d88210db411a8fcc5d1a20be0058")
				|| childShowId.equals("37383f374eea492faba0fea1943736ff")) {
			return "420";
		} else if (childShowId.equals("b2f9ce081cdb48c181caa259f0d75e51")
				|| childShowId.equals("de1e0e55e32f4ce3a436779b3a44c929")) {
			return "350";
		} else if (childShowId.equals("cdf441091ba24de6ab55123aec0cc748")
				|| childShowId.equals("a4faf6ecffba413d9eb69ce864c00c21")
				|| childShowId.equals("c0a44e3a1aad4aae9555ed8a65f0148e")) {
			return "540";
		}
		return null;
	}
	
	private static final String SHOW_ORGNIZE_TYPE_XHB = "3";//合办新模式2025
	private static final String PAYMENT_CHARGING_ITEM_BJZB = "犬只参赛费（北京自办）";
	private static final String PAYMENT_CHARGING_ITEM_DWWL = "单位往来";
	private static final String AGE_GROUP_TY_MALE = "1";// 特幼公犬组
	private static final String AGE_GROUP_TY_FEMALE = "2";// 特幼母犬组
	private static final String AGE_GROUP_YX_MALE = "3";// 幼小公犬组
	private static final String AGE_GROUP_YX_FEMALE = "4";// 幼小母犬组
	private static final String SHOW_RULES_QQZ = "0";// 赛制 0 全犬种 1 单独展
	private static final String SHOW_RULES_DDZ = "1";
	private static final String CAC_TYPE_CAC = "0";// 赛事CAC类型(0:CAC;1CACIB)
	private static final String CAC_TYPE_CACIB = "1";
	private static final double CAC_TYPE_CAC_FEE = 40;
	private static final double CAC_TYPE_CACIB_FEE = 55;
	
	/**
	 * 2025新合办专用
	 * 
	 * @param showApply
	 * @return
	 */
	public ShowApplyFeeVO countFeeForNew(ShowApply showApply) {
		Map<String, String> ageGroupMap = new HashMap<>();
		// 三种拆分方式：CAC 北京自办40 单位往来 总额-40
		// CACIB 北京自办55 单位往来 总额-55
		// 全犬种特幼组和幼小组参赛费、单独展特幼组 单位往来 总额
		BigDecimal bjzb = BigDecimal.ZERO;
		BigDecimal dwwl = BigDecimal.ZERO;
		if (StringUtils.isNotBlank(showApply.getAgeGroup()) && StringUtils.isNotBlank(showApply.getShowCode())) {
			for (int i=0;i< showApply.getShowCode().split(",").length;i++) {
				String showCode =showApply.getShowCode().split(",")[i];// 202510-国秀-01,202510-国秀-02,202510-国秀-03,202510-国秀-04,202510-国秀-05,202510-国秀-06,202510-国秀-07
				ageGroupMap.put(showCode, showApply.getAgeGroup().split(",")[i]);
			}
			for (String showCode : ageGroupMap.keySet()) {
				String ageGroup = ageGroupMap.get(showCode);
				ChildShows childShows = childShowsService.getByShowCode(showCode);
				if ((SHOW_RULES_QQZ.equals(childShows.getShowRules())
						&& (AGE_GROUP_TY_MALE.equals(ageGroup) || AGE_GROUP_TY_FEMALE.equals(ageGroup)
								|| AGE_GROUP_YX_MALE.equals(ageGroup) || AGE_GROUP_YX_FEMALE.equals(ageGroup)))
						|| (SHOW_RULES_DDZ.equals(childShows.getShowRules())
								&& (AGE_GROUP_TY_MALE.equals(ageGroup) || AGE_GROUP_TY_FEMALE.equals(ageGroup)))) {
					dwwl = dwwl.add(BigDecimal.valueOf(150));
				} else {
					BigDecimal bjzbFee = CAC_TYPE_CAC.equals(childShows.getCacType())
							? BigDecimal.valueOf(CAC_TYPE_CAC_FEE)
							: BigDecimal.valueOf(CAC_TYPE_CACIB_FEE);
					bjzb = bjzb.add(bjzbFee);
					BigDecimal dwwlFee = BigDecimal.valueOf(Double.valueOf(childShows.getFee())).subtract(bjzbFee);
					dwwl = dwwl.add(dwwlFee);
				}
			}
		}
		return ShowApplyFeeVO.builder().bjzb(bjzb).dwwl(dwwl).build();
	}
	/**
	 * 除2025新合办之外的赛事报名都走这个
	 * 
	 * @param showApply
	 * @return
	 */
	public BigDecimal countFee(ShowApply showApply) {
		BigDecimal fee = BigDecimal.ZERO;

		Map<String, String> ageGroupMap = new HashMap<>();
		if (StringUtils.isNotBlank(showApply.getAgeGroup()) && StringUtils.isNotBlank(showApply.getShowCode())) {
			for (int i=0;i< showApply.getShowCode().split(",").length;i++) {
				String showCode =showApply.getShowCode().split(",")[i];// 202510-国秀-01,202510-国秀-02,202510-国秀-03,202510-国秀-04,202510-国秀-05,202510-国秀-06,202510-国秀-07
				ageGroupMap.put(showCode, showApply.getAgeGroup().split(",")[i]);
			}
			for (String showCode : ageGroupMap.keySet()) {
				String ageGroup = ageGroupMap.get(showCode);
				ChildShows childShows = childShowsService.getByShowCode(showCode);
				if ((SHOW_RULES_QQZ.equals(childShows.getShowRules())
						&& (AGE_GROUP_TY_MALE.equals(ageGroup) || AGE_GROUP_TY_FEMALE.equals(ageGroup)
								|| AGE_GROUP_YX_MALE.equals(ageGroup) || AGE_GROUP_YX_FEMALE.equals(ageGroup)))
						|| (SHOW_RULES_DDZ.equals(childShows.getShowRules())
								&& (AGE_GROUP_TY_MALE.equals(ageGroup) || AGE_GROUP_TY_FEMALE.equals(ageGroup)))) {
					fee = fee.add(BigDecimal.valueOf(150));
				} else {
					fee = fee.add(BigDecimal.valueOf(Double.valueOf(childShows.getFee())));
				}
			}
		}

		return fee;

	}


	/**
	 * @description: 设置用于统计的收费项id
	 * @author: laiguanglong
	 * @date: 2016年7月29日 下午5:41:55
	 */
	private void setPaymentChargingItemId(ShowApply showApply) {
		String showCode = showApply.getShowCode().split(",")[0];
		ChildShows childShows = childShowsService.getByShowCode(showCode);
		MainShows mainShows = childShows.getMainShows();
		String organizer = DictUtils.getDictLabel(mainShows.getOrganizer(), "show_organizer", "").replace("市", "");
		String orgnizeType = DictUtils.getDictLabel(mainShows.getOrgnizeType(), "show_orgnize_type", "");
		if(SHOW_ORGNIZE_TYPE_XHB.equals(mainShows.getOrgnizeType())) {
			//合办新模式2025 收费项固定为北京自办、单位往来
			ShowApplyFeeVO fee = countFeeForNew(showApply);
			//北京自办
			String bjzb = paymentChargingItemService.getPaymentCodeGeneral(PAYMENT_CHARGING_ITEM_BJZB);
			//单位往来
			String dwwl = paymentChargingItemService.getPaymentCodeGeneral(PAYMENT_CHARGING_ITEM_DWWL);
			showApply.setPaymentChargingItemId(fee.getBjzb().compareTo(BigDecimal.ZERO)>0 ? bjzb+","+dwwl : dwwl);
		}else {
			// 判断新旧合办
			if ("0".equals(mainShows.getOrgnizeType()) && "1".equals(mainShows.getBusinessModelFlag())) {
				orgnizeType = "新" + orgnizeType;
			}
			String paymentChargingItemId = paymentChargingItemService.getPaymentCode(organizer + orgnizeType);
			showApply.setPaymentChargingItemId(paymentChargingItemId);
		}
		
		// 犬展报名继承主犬展的承办单位，用于不同地区公司只能查自己举办的犬展报名
		showApply.setOrganizer(mainShows.getOrganizer());
		showApply.setMainShowId(mainShows.getId());
	}

	@Transactional(readOnly = false)
	public void delete(ShowApply showApply) {
		// 已缴费的订单不允许删除
		if ("2".equals(showApply.getPaymentState())) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "该订单已缴费，不允许删除");
		}
		// OA删除订单
		oADeleteService.deleteUnpay(showApply.getPaymentState(), "show_apply", showApply.getId(),
				showApply.getRunningNumber());
		// 如果是oa报名的话，没有订单，故没走上面的删除，所以需要再次删除
		super.delete(showApply);
		// 给用户发送取消参展消息
		sendCancelMsg(showApply);
	}

	/**
	 * 根据查询报名犬信息
	 *
	 * @param mainShowId
	 * @param pedigreeCertified
	 * @return
	 * @throws Exception
	 */
	public Map<String, Object> setShowApplyInfo(String mainShowId, String pedigreeCertified, String showCode) {
		Map<String, Object> map = new HashMap<>();
		Dog dog = dogService.getByPedigreeCertifiedCode(pedigreeCertified);
		if (dog == null) {
			map.put("status", 1);
			map.put("msg", "血统证书号有误!");
			return map;
		}

		// 主犬展开始时间
		MainShows mainShows = mainShowsService.get(mainShowId);
		Date mainShowsStartTime = mainShows.getStartTime();

		// 判断是否重复报名
		ShowApply showApply = new ShowApply();
		showApply.setPedigreeCertified(pedigreeCertified);
		showApply.setMainShowId(mainShowId);
		if (!SecurityUtils.getSubject().isPermitted("apply:showApply:repeatApply") && repeatApply(showApply)) {
			map.put("status", 1);
			map.put("msg", "该犬只已经报名了这场主犬展");
			return map;
		}
		// 判断是否超出报名上限
		if (validateDogNumMax(mainShows)) {
			map.put("status", 1);
			map.put("msg", "该场犬展活动已经超出犬展报名上限");
			return map;
		}
		// 判断是否有犬主人
		String memberCode = dog.getMemberCode();
		if (StringUtils.isBlank(memberCode)) {
			map.put("status", 1);
			map.put("msg", "该犬只没有犬主人，不允许报名");
			return map;
		}
		// 判断会员号
		Member member = memberService.getByMemberCode(memberCode);
		if (member == null) {
			map.put("status", 1);
			map.put("msg", "该犬只犬主会员号有误");
			return map;
		}
		// 判断犬主名下犬只有没有未提交订单
		// 如果是后台报名且犬主人是外籍会员则不校验未缴费订单
		if (!"foreign".equals(member.getMemberType())) {
			List<ShowApply> list = findUnpaidListByDogOwnerMemberCode(memberCode);
			if (list.size() > 0) {
				map.put("status", 1);
				map.put("msg", "当前犬主名下犬只已有未缴费的犬展订单，请先处理。");
				return map;
			}
		}
		map.put("dogOwnerNameCn", member.getName());
		map.put("dogOwnerNameEn", member.getNameEn());
		map.put("dogOwnerMemberCode", member.getMemberCode());
		try {
			map.put("ageGroupList", getAgeGroupListString(mainShowId, dog, "0").get("ageGroupArray"));
		} catch (Exception e) {
			map.put("status", 1);
			map.put("msg", e.getMessage());
			return map;
		}
		String breed = dog.getShowDogBreed();
		if (StringUtils.isBlank(breed)) {
			breed = dog.getDogBreed();
			if (StringUtils.isNotBlank(breed)) {
				DogType dogType = dogTypeService.getByDogBreedCode(breed);
				if (dogType != null) {
					map.put("dogBreedNameCn", dogType.getBreedCnName());
					map.put("dogBreedNameEn", dogType.getBreedEnName());
					map.put("dogBreedGroup", dogType.getTypeGroup());
				} else {
					throw new ZAException(ZAErrorCode.ZA_VALID_FAILED,
							"该犬只的犬种" + dog.getDogBreed() + ",在犬种表无法找到对应的记录，请检查是否有该犬种");
				}
			}
		} else {
			if (StringUtils.isNotBlank(dog.getDogBreed())) {
				DogTypeShow dogTypeShow = dogTypeShowService.getByDogShowCode(breed);
				if (dogTypeShow != null) {
					map.put("dogBreedNameCn", dogTypeShow.getShowCnName());
					map.put("dogBreedNameEn", dogTypeShow.getShowEnName());
					map.put("dogBreedGroup", dogTypeShow.getTypeGroup());
				} else {
					throw new ZAException(ZAErrorCode.ZA_VALID_FAILED,
							"该犬只的犬种" + dog.getDogBreed() + ",在犬种表无法找到对应的记录，请检查是否有该犬种");
				}
			}
		}
		map.put("fciCode", breed);
		map.put("dogName", dog.getNameCn());
		map.put("dogGender", dog.getGender());
		map.put("dogGeneration", dog.getDogGeneration());
		map.put("dogBirthday", dog.getBirthdate() == null ? "" : DateUtils.dateToStr(dog.getBirthdate()));
		map.put("breeder", dog.getBreeder());
		map.put("otherCertified", dog.getPedigreeCertifiedEn());
		map.put("fdogPedigreeCertified", dog.getFdogPedigreeCertified());
		map.put("mdogPedigreeCertified", dog.getMdogPedigreeCertified());
		if (StringUtils.isNotBlank(dog.getFdogPedigreeCertified())) {
			Dog fdog = dogService.getByPedigreeCertifiedCode(dog.getFdogPedigreeCertified());
			if (fdog != null && fdog.getNameEn() != null) {
				String fdogName = fdog.getNameEn();
				map.put("fdogName", fdogName);
			}
		}
		if (StringUtils.isNotBlank(dog.getMdogPedigreeCertified())) {
			Dog mdog = dogService.getByPedigreeCertifiedCode(dog.getMdogPedigreeCertified());
			if (mdog != null && mdog.getNameEn() != null) {
				String mdogName = mdog.getNameEn();
				map.put("mdogName", mdogName);
			}
		}
		map.put("chipCode", dog.getIdentificationFlag());
		map.put("bbeFlag", getMonthAge(mainShowsStartTime, dog.getBirthdate()) >= 15 ? "1" : "0");
		map.put("secondDogOwner", dog.getSecondDogOwner());
		map.put("secondOwnerMember", dog.getSecondOwnerMemberNum());
		return map;
	}

	/**
	 * 获取可报名年龄组别
	 *
	 * @param groupType 0,1,2 后台使用0，表示显示全部年龄组别 app使用1，2：用逗号分隔 1表示冠军登陆头衔 2表示工作组头衔
	 * @return 年龄组别key list
	 */
	public List<Integer> getAgeGroupListInteger(ChildShows childShows, Dog dog, String groupType,
			boolean isChampionLogin) throws ZAException {
		List<Integer> ageGroupList = new ArrayList<>();
		boolean isMale = "1".equals(dog.getGender());
		// 犬只出生日期为空，返回所有组别
		if (dog.getBirthdate() == null) {
			ageGroupList.add(isMale ? 1 : 2);
			ageGroupList.add(isMale ? 3 : 4);
			ageGroupList.add(isMale ? 5 : 6);
			ageGroupList.add(isMale ? 7 : 8);
			ageGroupList.add(isMale ? 9 : 10);
			ageGroupList.add(isMale ? 13 : 14);
			ageGroupList.add(isMale ? 15 : 16);
			ageGroupList.add(isMale ? 17 : 18);
			ageGroupList.add(isMale ? 19 : 20);
			return ageGroupList;
		}
		int monthAge = getMonthAge(childShows.getStartTime(), dog.getBirthdate());
		// 冠军组
		// 优先判断冠军组，如为CAC赛制则跳出循环
		// CIB犬展：是否显示冠军组根据犬展报名中是否勾选冠军登录头衔判断，勾选中则显示，否则不显示
		// CAC犬展：无符合中国冠军登录条件的犬只或审核通过的中国冠军登录不显示冠军组
		if (monthAge >= 15) {
			if ("1".equals(childShows.getCacType())
					&& ("0".equals(groupType) || (!StringUtils.isBlank(groupType) && groupType.contains("1")))
					|| ("0".equals(childShows.getCacType()) && isChampionLogin)) {
				ageGroupList.add(isMale ? 13 : 14);
				if ("0".equals(childShows.getCacType())) {
					return ageGroupList;
				}
			}
		}
		// 特幼组
		if (monthAge < 6) {
			ageGroupList.add(isMale ? 1 : 2);
		}
		// 幼小组
		if (monthAge >= 6 && monthAge < 9) {
			ageGroupList.add(isMale ? 3 : 4);
		}
		// 青年组
		if (monthAge >= 9 && monthAge < 18) {
			ageGroupList.add(isMale ? 5 : 6);
		}
		// 中间组
		if (monthAge >= 15 && monthAge < 24) {
			ageGroupList.add(isMale ? 7 : 8);
		}
		// 公开组
		if (monthAge >= 15) {
			ageGroupList.add(isMale ? 9 : 10);
		}
		// 老年组
		if (monthAge >= 96) {
			ageGroupList.add(isMale ? 15 : 16);
		}
		// BBE组
		if (monthAge >= 15 && !("0".equals(childShows.getShowRules()) && "1".equals(childShows.getCacType()))) {
			ageGroupList.add(isMale ? 17 : 18);
		}
		// 工作组
		if (monthAge >= 15 && !"1".equals(childShows.getCacType())) {
			ageGroupList.add(isMale ? 19 : 20);
		}
		return ageGroupList;
	}

	/**
	 * 获取可报名年龄组别，以key=label的字符串格式
	 */
	public List<String> getAgeGroupListString(ChildShows childShows, Dog dog, String groupType) throws ZAException {
		List<String> ageGroupList = new ArrayList<>();
		// 是否有有效的普通登录记录
		boolean isChampionLogin = false;
		List<ChampionLogin> loginList = championLoginDao.getByPedigreeCertified(dog.getPedigreeCertifiedCode());
		if (loginList != null && loginList.size() > 0) {
			isChampionLogin = loginList.stream().anyMatch(login -> "1".equals(login.getLoginType()));
		}
		if (!isChampionLogin) {
			// 判断是否有冠军登陆资格
			isChampionLogin = championLoginService.validateComLoginForBoolean(dog);
		}

		// 获得年龄组别编号
		List<Integer> list = getAgeGroupListInteger(childShows, dog, groupType, isChampionLogin);
		for (Integer ageGroup : list) {
			String valueLabel = ageGroup.toString() + "="
					+ DictUtils.getDictLabel(ageGroup.toString(), "show_age_group", "");
			ageGroupList.add(valueLabel);
		}
		return ageGroupList;
	}

	/**
	 * 获取可报名年龄组别，以key=label的字符串格式
	 */
	public JSONObject getAgeGroupListString(String mainShowId, Dog dog, String groupType) {
		JSONArray ja = new JSONArray();
		// 1获取子犬展列表
		List<ChildShows> childShowList = childShowsService.findChildShowsByMainShowId(mainShowId);
		for (int i = 0, j = childShowList.size(); i < j; i++) {
			JSONObject jo = new JSONObject();
			jo.put("childShowId", childShowList.get(i).getId());
			//有特殊符号，转成unicode编码,前端展示
			jo.put("childShowName", childShowList.get(i).getShowName());
			jo.put("childShowCode", childShowList.get(i).getShowCode());
			if (getMonthAge(childShowList.get(i).getStartTime(), dog.getBirthdate()) < 3) {
				List<String> list = new ArrayList<>(1);
				list.add("none=无可选组别");
				jo.put("ageGroup", list);
			} else {
				jo.put("ageGroup", getAgeGroupListString(childShowList.get(i), dog, groupType));
			}
			ja.add(jo);
		}
		JSONObject jo = new JSONObject();
		jo.put("ageGroupArray", ja);
		jo.put("isAgeGroupChange", isAgeGroupChange(ja));
		return jo;
	}

	private Boolean isAgeGroupChange(JSONArray ja) {
		String ageGroupString = null;
		Boolean isAgeGroupChange = false;
		for (Object obj : ja) {
			JSONObject jsonObject = (JSONObject) obj;
			if (ageGroupString == null) {
				ageGroupString = jsonObject.getString("ageGroup");
			} else {
				if (!ageGroupString.equals(jsonObject.getString("ageGroup"))) {
					isAgeGroupChange = true;
					break;
				}
			}
		}
		return isAgeGroupChange;
	}

	/**
	 * 计算月龄
	 *
	 * @param date
	 * @param birthdate
	 * @return
	 */
	public int getMonthAge(Date date, Date birthdate) {
		Calendar dateCalendar = Calendar.getInstance();
		Calendar birthdateCalendar = Calendar.getInstance();
		dateCalendar.setTime(date);
		birthdateCalendar.setTime(birthdate);
		int monthAge = dateCalendar.get(Calendar.MONTH) - birthdateCalendar.get(Calendar.MONTH);
		if (dateCalendar.get(Calendar.YEAR) != birthdateCalendar.get(Calendar.YEAR)) {
			monthAge = (dateCalendar.get(Calendar.YEAR) - birthdateCalendar.get(Calendar.YEAR)) * 12 + monthAge;
		}
		birthdateCalendar.add(Calendar.MONTH, monthAge);
		if (birthdateCalendar.getTime().after(dateCalendar.getTime())) {
			monthAge = monthAge - 1;
		}
		return monthAge;
	}

	/**
	 * 判断犬展开始时会员是否被禁赛（禁赛返回true）
	 *
	 * @param memberCode
	 * @param showStartTime
	 * @return
	 */
	public boolean suspendStatus(String memberCode, Date showStartTime) {
		Member member = memberService.getByMemberCode(memberCode);
		if (member != null && member.getBanEndDate() != null) {
			if (showStartTime.before(member.getBanEndDate())) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 是否有未支付报名犬展(返回true表示没有未支付订单)
	 *
	 * @return
	 */
	public boolean noUnpayShowApply(ShowApply showApply) {
		List<ShowApply> list = dao.findUnpayShowApplyByPedigreeCertified(showApply);
		if (list.size() == 0) {
			return true;
		}
		return false;
	}

	/**
	 * 犬只校验
	 *
	 * @param mainShowsStartTime
	 * @return
	 * @throws Exception
	 */
	private Dog validateDog(ShowApply showApply, Date mainShowsStartTime, MainShows mainShows) throws ZAException {
		String pedigreeCertified = showApply.getPedigreeCertified();
		Dog dog = null;
		dog = dogService.getByPedigreeCertifiedCode(pedigreeCertified);
		if (dog == null) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "血统证书号有误!");
		}
		// FCI不认可品种:unauth不能报名犬展活动
		DogType dogType = dogTypeService.getByDogBreedCode(dog.getDogBreed());
		if ("unauth".equals(dogType.getBreedClass())) {
			throw new ZAException(ZAErrorCode.ZA_ERC_UNKNOWN, "FCI不认可品种不能报名犬展活动！");
		}
		String[] showCodes = showApply.getShowCode().split(",");
		for (int s = 0; s < showCodes.length; s++) {
			ChildShows childShows = childShowsService.get(showCodes[s]);
			if (childShows == null) {
				childShows = childShowsService.getByShowCode(showCodes[s]);
			}
			// FCI临时认可品种temp、FCI国家级认可品种country仅限报名CAC犬展
			if (("temp".equals(dogType.getBreedClass()) || "country".equals(dogType.getBreedClass()))
					&& !"0".equals(childShows.getCacType())) {
				throw new ZAException(ZAErrorCode.ZA_ERC_UNKNOWN, "FCI临时认可/国家级认可品种不能报名非CAC犬展活动！");
			}
		}

		if (!"0".equals(dog.getDogState()) && !"5".equals(dog.getDogState())) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "犬只状态异常，无法办理此业务!");
		}
		// 业务禁止校验
		// 杜高不校验禁止繁殖规则--2018年12月5日10:29:26--yuanshuai
		if (!"292".equals(dog.getDogBreed())) {
			businessBanService.validateBusinessBan(dog, "该犬为禁止繁殖状态");
		}
		pedigreeCertified = dog.getPedigreeCertifiedCode();
		// 如果是WB的话必须以CKU开头,出生日期不能为空，犬只代数大于0
		if ("WB".equals(showApply.getApplyCode())) {
			if (!pedigreeCertified.toUpperCase().startsWith("CKU")) {
				throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "血统证书号必须以CKU开头!");
			}
			if (dog.getBirthdate() == null) {
				throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "犬只信息不全，无法报名犬展活动，请联系CKU协会客服处理。");
			}
			Integer dogGeneration = restDogService.getDogGeneration(dog.getPedigreeCertifiedCode());
			// 犬展类型及赛制包含CACIB和全犬种时必须满足三代--2019年02月28日10:29:26--zhangxiang
			for (int s = 0; s < showCodes.length; s++) {
				ChildShows childShows = childShowsService.get(showCodes[s]);
				if (childShows == null) {
					childShows = childShowsService.getByShowCode(showCodes[s]);
				}
				if (childShows.getCacType().equals("1") && childShows.getShowRules().equals("0")
						&& !pedigreeCertified.toUpperCase().startsWith("CKU-NB") && !(dogGeneration > 2)) {
					throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "此犬祖辈信息不满三代，不可报名CACIB犬展。");
				}
			}
			if (getMonthAge(mainShows.getEndTime(), dog.getBirthdate()) < 3) {
				throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "犬只月龄不够3个月!");
			}
		}
		if (StringUtils.isNumeric(dog.getDisqualificationNumber())
				&& Integer.parseInt(dog.getDisqualificationNumber()) >= 3) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "该犬因失格限定已被禁止报名参展");
		}
		// 经犬展部确认取消此判断 2019年3月26日10:41:40
		// 经犬展部确认开启此判断 2021年5月18日16:17:43
		// 犬只状态为已出口
		if ("5".equals(dog.getDogState())) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "犬只状态为已出口，不允许参加犬展");
		}
		return dog;
	}

	/**
	 * 获取主犬展开始时间
	 *
	 * @param showApply
	 * @return
	 */
	private MainShows getMainShows(ShowApply showApply) {
		String showCode = showApply.getShowCode().split(",")[0];
		ChildShows childShows = null;
		if (showCode.length() == 32 || StringUtils.isNumeric(showCode)) {
			childShows = childShowsService.get(showCode);
		} else {
			childShows = childShowsService.getByShowCode(showCode);
		}
		showApply.setMainShowId(childShows.getMainShowId());
		return childShows.getMainShows();
	}

	/**
	 * @description: 更新赛前退费和赛场请假标志位
	 * @author: laiguanglong
	 * @date: 2016年8月2日 上午10:41:25
	 */
	@Transactional(readOnly = false)
	public void updateRefundAbsenceFlag(ShowApply showApply) {
		showApply.preUpdate();
		dao.updateRefundAbsenceFlag(showApply);
		/*
		 * 点击退费自动给予犬主人安全手机发送短信提醒（温馨提示）功能。 2019.06.14 zhangxiang
		 */
		if (StringUtils.isNotBlank(showApply.getRefundFlag()) && showApply.getRefundFlag().equals("1")) {
			Member member = memberService.getByMemberCode(showApply.getDogOwnerMemberCode());
			if (member != null && StringUtils.isNotBlank(member.getSafeMobile())) {
				// 获取犬展时间和地点
				MainShows mainshows = mainShowsService.get(showApply.getMainShowId());
				String result = ZtSmsUtil.sendNoteYX(
						"尊敬的" + member.getName() + "会员：您名下证书号为：" + showApply.getPedigreeCertified() + "的犬只，已取消"
								+ mainshows.getShowLocation()
								+ "地点的全犬种犬展活动报名，请从官网下载退费申请手动填写内容发送至对应邮箱进行退费，如有问题请及时致电各区域办公室或CKU客服：400-660-7000",
						member.getSafeMobile());
				System.out.println(result);
			}
		}
	}

	/**
	 * @description: 导出犬展报名信息
	 * @author: laiguanglong
	 * @date: 2016年8月2日 上午10:42:15
	 */
	public void export(String showCodePrefix, HttpServletResponse response) throws Exception {
		List<ShowApply> showApplyList = new ArrayList<ShowApply>();
		// 检验犬展编号必须大于等于6位，位数太少会找到多个mianshow
		if (showCodePrefix.length() >= 6) {
			// 检验本次犬展报名截至时间已过
			MainShows mainShows = mainShowsDao.getByShowCodePrefix(showCodePrefix);
			if (mainShows != null && mainShows.getClosingTime() != null
					&& System.currentTimeMillis() > mainShows.getClosingTime().getTime()) {
				if (DataPermissionUtil.isShowApplyDataLimited()) {
					// 检验用户所属部门属于本次犬展承办单位
					// 获取承办单位字典Label
					List<Dict> dictList = DictUtils.getDictList("show_organizer");
					// 获取当前用户有权限访问的部门
					String[] show_organizers = DataPermissionUtil.getShowApplyPermission();
					List<String> organizers = new LinkedList<String>();
					for (String show_organizer : show_organizers) {
						for (Dict dict : dictList) {
							// 如果部门以承办单位开头，则可以查询该承办单位的报名数据
							if (dict.getLabel().equals(show_organizer)) {
								organizers.add(dict.getValue());
								break;
							}
						}
					}
					if (organizers.contains(mainShows.getOrganizer())) {
						showApplyList = getShowApplyByShowCodePrefix(showCodePrefix);
					}
				} else {
					showApplyList = getShowApplyByShowCodePrefix(showCodePrefix);
				}
			}
		}
		// 导出
		new ExportExcel(showCodePrefix + "犬展报名", ShowApply.class, 2).setDataList(showApplyList)
				.write(response, showCodePrefix + "犬展报名.xlsx").dispose();
	}

	/**
	 * @description: 根据犬展编号前缀查询犬展报名信息
	 * @author: laiguanglong
	 * @date: 2017/3/30 16:43
	 */
	private List<ShowApply> getShowApplyByShowCodePrefix(String showCodePrefix) {
		List<ShowApply> showApplyList = dao.exportShowApply(showCodePrefix);
		// 字典类型转换
		for (ShowApply sa : showApplyList) {
			try {
				sa.setRefundFlag("1".equals(sa.getRefundFlag()) ? "是" : "否");
				sa.setAbsenceFlag("1".equals(sa.getAbsenceFlag()) ? "是" : "否");
				sa.setBbeFlag("1".equals(sa.getBbeFlag()) ? "是" : "否");
				sa.setDogGender(DictUtils.getDictLabel(sa.getDogGender(), "dog_gender", ""));
				sa.setPaymentState(DictUtils.getDictLabel(sa.getPaymentState(), "user_payment_state", ""));
				// 犬展编号排序
				String[] showCodeArray = sa.getShowCode().split(",");
				Arrays.sort(showCodeArray);
				StringBuilder sb = new StringBuilder();
				for (int i = 0; i < showCodeArray.length; i++) {
					sb.append(showCodeArray[i]).append(",");
				}
				sb.deleteCharAt(sb.length() - 1);
				sa.setShowCode(sb.toString());
				// 犬主名（牵犬人名） 联系方式
				String dogOwnerAndHandler = sa.getDogOwnerNameCn();
				Member member = memberService.getByMemberCode(sa.getDogOwnerMemberCode());
				String contact = member.getMobile();
				if (!sa.getDogOwnerMemberCode().equals(sa.getHandlerMemberCode())) {
					if (sa.getHandlerMemberCode().contains(",")) {
						sa.setHandlerMemberCode(sa.getHandlerMemberCode().split(",")[0]);
					}
					Member handlerMember = memberService.getByMemberCode(sa.getHandlerMemberCode());
					dogOwnerAndHandler = dogOwnerAndHandler + "(" + handlerMember.getName() + ")";
					contact = contact + " " + handlerMember.getMobile();
				}
				sa.setDogOwnerAndHandler(dogOwnerAndHandler);
				sa.setContact(contact);
				sa.setColorFlag(getColorFlag(sa.getPedigreeCertified()));
				sa.setIsSameAgeGroup(getIsSameAgeGroup(sa));
				setAgeGroup(sa);
			} catch (Exception e) {
				logger.warn("导出犬展报名记录出错" + sa.getPedigreeCertified(), e);
				continue;
			}
		}
		return showApplyList;
	}

	/**
	 * @description: 判断是否重复报名（返回false表示没有重复报名）
	 * @author: laiguanglong
	 * @date: 2016年8月3日 上午9:54:02
	 */
	public boolean repeatApply(ShowApply showApply) {
		boolean flag = true;
		if (dao.countByMainShowId(showApply.getMainShowId(), showApply.getPedigreeCertified()) == 0) {
			flag = false;
		}
		return flag;
	}

	/**
	 * @description: 判断是否超出报名上限(返回true表示超出上限)
	 * @author: laiguanglong
	 * @date: 2016年8月3日 上午10:03:46
	 */
	public boolean validateDogNumMax(MainShows mainShows) {
		long dogNumMax = Long.parseLong(mainShows.getDogNumMax());
		long count = dao.countByMainShowId(mainShows.getId(), null);
		if (count >= dogNumMax) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * @description: 犬展报名信息根据举办单位进行过滤
	 * @author: laiguanglong
	 * @date: 2016年8月3日 下午4:30:38
	 */
	private String dataScopeFilter() {
		StringBuilder sb = new StringBuilder();
		if (DataPermissionUtil.isShowApplyDataLimited()) {
			sb.append("(");
			// 获取承办单位字典Label
			List<Dict> dictList = DictUtils.getDictList("show_organizer");
			// 获取当前用户有权限访问的部门
			String[] show_organizers = DataPermissionUtil.getShowApplyPermission();
			for (String show_organizer : show_organizers) {
				for (Dict dict : dictList) {
					// 如果部门以承办单位开头，则可以查询该承办单位的报名数据
					if (dict.getLabel().equals(show_organizer)) {
						sb.append(dict.getValue() + ",");
						break;
					}
				}
			}
			sb.deleteCharAt(sb.length() - 1);
			sb.append(")");
		}
		return sb.toString();
	}

	private String dataScopeFilterNew() {
		StringBuilder sb = new StringBuilder();
		if (DataPermissionUtil.isShowApplyDataLimited()) {
			sb.append("(");
			// 特殊账号权限
			User user = UserUtils.getUser();
			List<Dict> userList = DictUtils.getDictList("show_special_permission");
			List<String> userIds = userList.stream().map(Dict::getValue).collect(Collectors.toList());
			if (userIds.contains(user.getId())) {
				for (Dict dict : userList) {
					if (user.getId().equals(dict.getValue())) {
						sb.append(dict.getLabel());
					}
				}
			} else {
				// 获取承办单位字典Label
				List<Dict> dictList = DictUtils.getDictList("show_organizer");
				// 获取当前用户有权限访问的部门
				String[] show_organizers = DataPermissionUtil.getShowApplyPermission();
				for (String show_organizer : show_organizers) {
					for (Dict dict : dictList) {
						// 如果部门以承办单位开头，则可以查询该承办单位的报名数据
						if (dict.getLabel().equals(show_organizer)) {
							sb.append(dict.getValue() + ",");
							break;
						}
					}
				}
				sb.deleteCharAt(sb.length() - 1);
			}
			sb.append(")");
		}
		return sb.toString();
	}

	/**
	 * @description: 根据角色判断是否用只显示第一页page类
	 * @author: laiguanglong
	 * @date: 2016年8月3日 下午5:24:16
	 */
	public Object transformPage(Page<ShowApply> page) {
		User user = UserUtils.getUser();
		if (!user.isAdmin()) {
			ShowApplyPage<ShowApply> showApplyPage = new ShowApplyPage<ShowApply>();
			BeanUtils.copyProperties(page, showApplyPage);
			return showApplyPage;
		}
		return page;
	}

	/**
	 * @description: 给用户发送消息，根据缴费状态和取消状态来判断发送内容
	 * @author: laiguanglong
	 * @date: 2016年8月19日 下午4:14:35
	 */
	public void sendMsg(ShowApply showApply) {
		if ("1".equals(showApply.getPaymentState())) {
			Member member = memberService.getByMemberCode(showApply.getDogOwnerMemberCode());
			ChildShows childShows = childShowsService.getByShowCode(showApply.getShowCode().split(",")[0]);
			String[] showCodeStrs = childShows.getShowCode().split("-");
			String showName = showCodeStrs.length > 1 ? showCodeStrs[1] : "";
			SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日HH时mm分");
			String dateString = formatter.format(new Date());
			String content = "您于" + dateString + "报名CKU犬展" + showName
					+ (StringUtils.isNotBlank(childShows.getMainShowName()) ? "-" + childShows.getMainShowName() : "")
					+ "，参展犬只证书号为" + showApply.getPedigreeCertified() + "。本次参展费" + showApply.getOrderPrice()
					+ "元整，请您核对报名信息，以免耽误正常参展。";
			ZtSmsUtil.sendNote(content, member.getMobile());
		}

//		String paymentState = showApply.getPaymentState();
//		// TODO:取消状态也要发短信？？
//		// 只有9，2的状态发消息
//		if ("9".equals(paymentState) || "2".equals(paymentState)) {
//			String content = "";
//			ChildShows childShows = childShowsService.getByShowCode(showApply.getShowCode().split(",")[0]);
//			String organizer = DictUtils.getDictLabel(showApply.getOrganizer(), "show_organizer", "");
//			if ("9".equals(paymentState)) {
//				// 提交未缴费
//				SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日HH时mm分");
//				String dateString = formatter.format(new Date());
//				content = "您于" + dateString + "报名CKU犬展-“" + organizer + "+" + childShows.getMainShowName() + "”，参展犬只为“"
//						+ showApply.getChipCode() + "/" + showApply.getPedigreeCertified() + "”。本次参展费"
//						+ showApply.getOrderPrice() + "元整，请您务必于当日24时前完成犬展缴费，以免耽误正常参展。";
//			} else if ("2".equals(paymentState)) {
//				// 缴费成功
//				SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日");
//				String dateString = formatter.format(childShows.getMainShows().getStartTime());
//				content = "您已成功报名CKU犬展-“" + childShows.getMainShowName() + "”，参展犬只为“" + showApply.getChipCode() + "/"
//						+ showApply.getPedigreeCertified() + "”。请于妥善安排行程，" + dateString + organizer + "CKU与您不见散。";
//			}
//			remindService.addRemind(content, showApply.getDogOwnerMemberCode());
//		}
	}

	/**
	 * @description: 给用户发送取消参展消息
	 * @author: laiguanglong
	 * @date: 2016年8月23日 上午11:27:22
	 */
	private void sendCancelMsg(ShowApply showApply) {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日HH时mm分");
		String dateString = formatter.format(new Date());
		ChildShows childShows = childShowsService.getByShowCode(showApply.getShowCode().split(",")[0]);
		String content = "您于" + dateString + "已取消了CKU犬展-“" + childShows.getMainShowName() + "”，参展犬只为“"
				+ showApply.getChipCode() + "/" + showApply.getPedigreeCertified()
				+ "”。如非您本人操作，请尽快登录CKU会员中心进行重新报名，以免耽误您的参展安排。";
		remindService.addRemind(content, showApply.getDogOwnerMemberCode());
	}

	/**
	 * @description: 返回犬展当天网络报名数
	 * @author: laiguanglong
	 * @date: 2016年8月29日 下午1:47:38
	 */
	public int getShowApplyCountToday() {
		ShowApply showApply = new ShowApply();
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.MILLISECOND, 0);
		showApply.setBeginCreateDate(cal.getTime());
		// 网报
		showApply.setApplyCode("WB");
		// 在sql中加入对organizer字段进行筛选
		showApply.getSqlMap().put("organizer", dataScopeFilter());
		return dao.listCount(showApply);
	}

	/**
	 * @description: 业务校验
	 * @author: laiguanglong
	 * @date: 2016年9月10日 下午5:20:47
	 */
	public void validateBusiness(ShowApply showApply) {
		MainShows mainShows = getMainShows(showApply);
		// 主犬展开始时间,校验以该时间点为准
		Date mainShowsStartTime = mainShows.getStartTime();
		// 会员资格校验
		validateMember(showApply, mainShowsStartTime);
		// 犬只校验
		validateDog(showApply, mainShowsStartTime, mainShows);
		// 其他校验
		if (showApply.getIsNewRecord()) {
			if ("WB".equals(showApply.getApplyCode())) {
				if (!noUnpayShowApply(showApply)) {
					throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "有未支付订单");
				}
				// 判断是否已过报名时间
				if (System.currentTimeMillis() > mainShows.getClosingTime().getTime()) {
					throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "已过犬展报名截止时间");
				}
				// BBE校验
				if ("1".equals(showApply.getBbeFlag())
						&& !"1".equals(getBbeFlag(mainShows.getId(), showApply.getPedigreeCertified()))) {
					throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "该犬只不符合BBE组规则");
				}
			}
			// 判断是否重复报名
			if (!SecurityUtils.getSubject().isPermitted("apply:showApply:repeatApply") && repeatApply(showApply)) {
				throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "该犬只已经报名了这场主犬展");
			}
			// 判断是否超出报名上限
			if (validateDogNumMax(mainShows)) {
				throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "该场犬展活动已经超出犬展报名上限");
			}
			// 判断是否超出报名上限
			if ("0".equals(mainShows.getRegister())) {
				throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "该犬展报名已关闭");
			}
			// 判断犬主名下犬只有没有未提交订单
			// 如果是后台报名且犬主人是外籍会员则不校验未缴费订单
			Member member = memberService.getByMemberCode(showApply.getDogOwnerMemberCode());
			if (!showApply.getApplyCode().startsWith("BM")
					|| (showApply.getApplyCode().startsWith("BM") && !"foreign".equals(member.getMemberType()))) {
				List<ShowApply> list = findUnpaidListByDogOwnerMemberCode(showApply.getDogOwnerMemberCode());
				if (list.size() > 0) {
					throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "当前犬主名下犬只已有未缴费的犬展订单，请先处理。");
				}
			}
		}
		// 贴纸申请业务校验
		// 等级贴纸为APP犬展报名附带业务，APP提交时已经校验，并已经生成等级贴纸申请记录
		// 此处在校验必然校验不通过(等级贴纸只允许申请一次)，故将校验逻辑注释
		/**
		 * if ("1".equals(showApply.getStickerFlag())) { Dog dog =
		 * dogService.getByPedigreeCertifiedCode(showApply.getPedigreeCertified()); //
		 * 犬展等级贴纸申请校验 stickerCheck(dog.getIdentificationFlag()); }
		 **/
	}

	/**
	 * @description: 根据犬展编号和血统证书号判断是否报名，没报名返回false
	 * @author: laiguanglong
	 * @date: 2016年10月19日 下午2:30:43
	 */
	public boolean isApply(String showCode, String pedigreeCertified) {
		boolean flag = false;
		if (dao.countByShowCodeAndPedigreeCertified(showCode, pedigreeCertified) > 0) {
			flag = true;
		}
		return flag;
	}

	/**
	 * @description: 根据主犬展id，把该主犬展下所有的报名信息标记为已过期
	 * @author: laiguanglong
	 * @date: 2016年12月5日 上午11:25:12
	 */
	@Transactional(readOnly = false)
	public void expireByMainShowId(String mainShowId) {
		dao.expireByMainShowId(mainShowId);
	}

	/**
	 * @description: 获取BBEFlag标记位
	 * @author: laiguanglong
	 * @date: 2017/2/23 10:47
	 */
	public String getBbeFlag(String mainShowId, String pedigreeCertified) {
		// 包含CAC犬展活动（主犬展下包含CAC犬展）
		MainShows mainShows = mainShowsService.get(mainShowId);
		List<ChildShows> childShowsList = childShowsDao.getByMainShowId(mainShows.getId());
		boolean cacFlag = false;
		for (ChildShows childShows : childShowsList) {
			if ("0".equals(childShows.getCacType())) {
				cacFlag = true;
				break;
			}
		}
		if (!cacFlag) {
			return "0";
		}
		// 犬只犬展活动当天年龄大于等于15个月
		Dog dog = dogService.getByPedigreeCertifiedCode(pedigreeCertified);
		if (getMonthAge(mainShows.getStartTime(), dog.getBirthdate()) < 14) {
			return "0";
		}
		// 无冠军登录信息（犬只信息表犬展活动成绩为空，冠军登录列表无记录）
		if (StringUtils.isNotBlank(dog.getShowGrade())) {
			return "0";
		}
		if (championLoginDao.countByPedigreeCertified(pedigreeCertified) > 0) {
			return "0";
		}
		return "1";
	}

	/**
	 * @description: 判断犬只年龄组别是否发生变化，返回true表示是 跨如下月龄年龄组别会发生变化6，9，15，18，24，96
	 * @author: laiguanglong
	 * @date: 2017/7/7 16:15
	 */
	public boolean isAgeGroupChange(Dog dog, MainShows mainShows) {
		boolean flag = false;
		if (dog.getBirthdate() == null || mainShows.getStartTime() == null || mainShows.getEndTime() == null) {
			return flag;
		}
		int startTimeMonthAge = getMonthAge(mainShows.getStartTime(), dog.getBirthdate());
		int endTimeMonthAge = getMonthAge(mainShows.getEndTime(), dog.getBirthdate());
		if (startTimeMonthAge != endTimeMonthAge
				&& (endTimeMonthAge == 3 || endTimeMonthAge == 6 || endTimeMonthAge == 9 || endTimeMonthAge == 15
						|| endTimeMonthAge == 18 || endTimeMonthAge == 24 || endTimeMonthAge == 96)) {
			return true;
		}
		return flag;
	}

	/**
	 * @Description： 判断所有年龄组别是否为同一个
	 */
	private String getIsSameAgeGroup(ShowApply sa) {
		boolean isSameAgeGroup = true;
		if (sa.getAgeGroup().contains(",")) {
			String[] ageGroupArray = sa.getAgeGroup().split(",");
			String ageGroup = ageGroupArray[0];
			for (int i = 1, len = ageGroupArray.length; i < len; i++) {
				if (!ageGroup.equals(ageGroupArray[i])) {
					isSameAgeGroup = false;
					break;
				}
			}
		}
		if (isSameAgeGroup) {
			return "同";
		} else {
			return "不同";
		}
	}

	/**
	 * @Description： 设置excel导出时的年龄组别
	 */
	private void setAgeGroup(ShowApply sa) {
		String showCodes = sa.getShowCode();
		String ageGroups = sa.getAgeGroup();
		String[] showCodesArray = showCodes.split(",");
		String[] ageGroupArray = ageGroups.split(",");
		for (int i = 0, len = showCodesArray.length; i < len; i++) {
			String ageGroupLabel;
			if (!ageGroups.contains(",")) {
				ageGroupLabel = DictUtils.getDictLabel(ageGroups, "show_age_group", "");
			} else {
				ageGroupLabel = DictUtils.getDictLabel(ageGroupArray[i], "show_age_group", "");
			}
			setAgeGroup(sa, showCodesArray[i], ageGroupLabel);
		}
	}

	/**
	 * @Description： 设置excel导出时的年龄组别
	 */
	private void setAgeGroup(ShowApply sa, String showCode, String ageGroupLabel) {
		String index = showCode.substring(showCode.length() - 2);
		if ("01".equals(index)) {
			sa.setAgeGroup01(ageGroupLabel);
		} else if ("02".equals(index)) {
			sa.setAgeGroup02(ageGroupLabel);
		} else if ("03".equals(index)) {
			sa.setAgeGroup03(ageGroupLabel);
		} else if ("04".equals(index)) {
			sa.setAgeGroup04(ageGroupLabel);
		} else if ("05".equals(index)) {
			sa.setAgeGroup05(ageGroupLabel);
		} else if ("06".equals(index)) {
			sa.setAgeGroup06(ageGroupLabel);
		} else if ("07".equals(index)) {
			sa.setAgeGroup07(ageGroupLabel);
		} else if ("08".equals(index)) {
			sa.setAgeGroup08(ageGroupLabel);
		} else if ("09".equals(index)) {
			sa.setAgeGroup09(ageGroupLabel);
		} else if ("10".equals(index)) {
			sa.setAgeGroup10(ageGroupLabel);
		} else if ("11".equals(index)) {
			sa.setAgeGroup11(ageGroupLabel);
		} else if ("12".equals(index)) {
			sa.setAgeGroup12(ageGroupLabel);
		} else if ("13".equals(index)) {
			sa.setAgeGroup13(ageGroupLabel);
		} else if ("14".equals(index)) {
			sa.setAgeGroup14(ageGroupLabel);
		} else if ("15".equals(index)) {
			sa.setAgeGroup15(ageGroupLabel);
		} else if ("16".equals(index)) {
			sa.setAgeGroup16(ageGroupLabel);
		} else if ("17".equals(index)) {
			sa.setAgeGroup17(ageGroupLabel);
		} else if ("18".equals(index)) {
			sa.setAgeGroup18(ageGroupLabel);
		} else if ("19".equals(index)) {
			sa.setAgeGroup19(ageGroupLabel);
		} else if ("20".equals(index)) {
			sa.setAgeGroup20(ageGroupLabel);
		}
	}

	private String getColorFlag(String pedigreeCertified) {
		String colorFlag = "";
		Dog dog = dogService.getByPedigreeCertifiedCode(pedigreeCertified);
		if (dog != null && StringUtils.isNotBlank(dog.getColorFlag())) {
			DogColorMark dogColorMark = dogColorMarkDao.getByDogColorMarkCode(dog.getColorFlag());
			if (dogColorMark != null) {
				colorFlag = dogColorMark.getDogColorMarkCn();
			} else {
				colorFlag = dog.getColorFlag();
			}
		}
		return colorFlag;
	}

	/**
	 * @description: 获取犬展报名信息
	 * @author: cuihuaiyu
	 * @date: 2018/01/10
	 */
	public List<ShowApply> getShowApply(String showCodePrefix) throws Exception {
		List<ShowApply> showApplyList = new ArrayList<ShowApply>();
		// 检验犬展编号必须大于等于6位，位数太少会找到多个mianshow
		if (showCodePrefix.length() >= 6) {
			// 检验本次犬展报名截至时间已过
			MainShows mainShows = mainShowsDao.getByShowCodePrefix(showCodePrefix);
			if (mainShows != null && mainShows.getClosingTime() != null
					&& System.currentTimeMillis() > mainShows.getClosingTime().getTime()) {
				// 特殊账号逻辑
				User user = UserUtils.getUser();
				List<Dict> userList = DictUtils.getDictList("show_special_permission");
				List<String> userIds = userList.stream().map(Dict::getValue).collect(Collectors.toList());
				if (userIds.contains(user.getId())) {
					for (Dict dict : userList) {
						if (user.getId().equals(dict.getValue())) {
							String label = dict.getLabel(); // 可访问的主办法
							if (label.contains(mainShows.getOrganizer())) {
								showApplyList = getShowApplyByShowCodePrefixNew(showCodePrefix);
							}
						}
					}
				} else {
					if (DataPermissionUtil.isShowApplyDataLimited()) {
						// 检验用户所属部门属于本次犬展承办单位
						// 获取承办单位字典Label
						List<Dict> dictList = DictUtils.getDictList("show_organizer");
						// 获取当前用户有权限访问的部门
						String[] show_organizers = DataPermissionUtil.getShowApplyPermission();
						List<String> organizers = new LinkedList<String>();
						for (String show_organizer : show_organizers) {
							for (Dict dict : dictList) {
								// 如果部门以承办单位开头，则可以查询该承办单位的报名数据
								if (dict.getLabel().equals(show_organizer)) {
									organizers.add(dict.getValue());
									break;
								}
							}
						}
						if (organizers.contains(mainShows.getOrganizer())) {
							showApplyList = getShowApplyByShowCodePrefixNew(showCodePrefix);
						}
					} else {
						showApplyList = getShowApplyByShowCodePrefixNew(showCodePrefix);
					}

				}
			}
		}
		return showApplyList;
	}

	/**
	 *
	 * @description: 更新犬展报名(copy表)
	 * @author: cuihuaiyu
	 * @date: 2018年1月25日 上午10:41:25
	 */
	// @Transactional(readOnly = false)
	// public void updateRefundAbsence(ShowApply showApply) {
	// dao.update(showApply);
	// }

	/**
	 * @description: 根据犬展编号前缀查询犬展报名信息
	 * @author: cuihuaiyu
	 * @date: 2018年1月25日 上午10:41:25
	 */
	private List<ShowApply> getShowApplyByShowCodePrefixNew(String showCodePrefix) {
		List<ShowApply> showApplyList = dao.exportShowApply(showCodePrefix);
		
		Map<String,Dog> map = dogService.getMapByPedigreeCertifiedCodes(
				showApplyList.stream().map(a->a.getPedigreeCertified()).collect(Collectors.toList()));
		
		// 处理数据-字典类型转换
		for (ShowApply showApply : showApplyList) {
			try {
				// 犬只累计获得JCC卡数量
				int jccCount = championLoginDao.countJCC(showApply.getPedigreeCertified());
				showApply.setJCCnum(jccCount);
				// 犬只累计获得CC/RCC卡数量
				int ccNum = championLoginDao.countCC(showApply.getPedigreeCertified());
				int rccNum = championLoginDao.countRCC(showApply.getPedigreeCertified());
				showApply.setCCNum(ccNum + rccNum);
				// 是否完成青年登录
				List<String> list = championLoginDao.getLoginTypeByPedigreeCertified(showApply.getPedigreeCertified());
				if (list.contains("7")) {
					showApply.setIsChampionLogin("是");
				} else {
					showApply.setIsChampionLogin("否");
				}
				// 退赛
				showApply.setRefundFlag("1".equals(showApply.getRefundFlag()) ? "是" : "否");

				// 请假
				showApply.setAbsenceFlag("1".equals(showApply.getAbsenceFlag()) ? "是" : "否");
				// bbe标识 -- 由于bbeflag已经不用，所以此表示无效，改为根据年龄组别判断 by yuanshuai 2018-3-23 11:19:37
				showApply.setBbeFlag(
						(showApply.getAgeGroup().contains("17") || showApply.getAgeGroup().contains("18")) ? "是" : "否");
				// 公母
				showApply.setDogGender(DictUtils.getDictLabel(showApply.getDogGender(), "dog_gender", ""));
				// 付款状态
				showApply
						.setPaymentState(DictUtils.getDictLabel(showApply.getPaymentState(), "user_payment_state", ""));
				// 代数是否满足三代
				showApply.setDogGenerationFlag(
						dogService.validate3Generation(showApply.getPedigreeCertified()) ? "是" : "否");
				// 动态刷新代数
				showApply.setDogGeneration(
						String.valueOf(restDogService.getDogGeneration(showApply.getPedigreeCertified())));
				// //犬展编号排序 -- 不能排序，顺序改变会导致年龄组别变化 by yuanshuai 2018-3-21 14:44:27
				// String[] showCodeArray = showApply.getShowCode().split(",");
				// Arrays.sort(showCodeArray);
				// StringBuilder sb = new StringBuilder();
				// for (String aShowCodeArray : showCodeArray) {
				// sb.append(aShowCodeArray).append(",");
				// }
				// sb.deleteCharAt(sb.length() - 1);
				// showApply.setShowCode(sb.toString());
				// 犬主名（牵犬人名）、联系方式
				String dogOwnerAndHandler = showApply.getDogOwnerNameCn();
				Member member = memberService.getByMemberCode(showApply.getDogOwnerMemberCode());
				// 英文名
				showApply.setDogOwnerNameEn(member.getNameEn());
				// 联系方式
				String contact = member.getMobile();
				if (showApply.getDogOwnerMemberCode().equals(showApply.getHandlerMemberCode())) {
					showApply.setHandlerMemberName(showApply.getDogOwnerNameCn());
					showApply.setHandlerMemberNameTemp(showApply.getDogOwnerNameCn());
				} else {
					if (showApply.getHandlerMemberCode().contains(",")) {
						showApply.setHandlerMemberCode(showApply.getHandlerMemberCode().split(",")[0]);
					}
					member = memberService.getByMemberCode(showApply.getHandlerMemberCode());
					showApply.setHandlerMemberName(member.getName());
					showApply.setHandlerMemberNameTemp(member.getName());

					dogOwnerAndHandler = dogOwnerAndHandler + "(" + member.getName() + ")";
					contact = contact + " " + member.getMobile();
				}
				showApply.setDogOwnerAndHandler(dogOwnerAndHandler);
				showApply.setContact(contact);
				// 毛色
				showApply.setColorFlag(getColorFlag(showApply.getPedigreeCertified()));
				// 判断所有年龄组别是否为同一个
				showApply.setIsSameAgeGroup(getIsSameAgeGroup(showApply));
				// 犬主人组
				String isOwner = showApply.getIsOwner();
				if (StringUtils.isNotBlank(isOwner)) {
					StringBuilder isowner = new StringBuilder();
					String[] isOwnerArray = isOwner.split(",");
					for (String str : isOwnerArray) {
						isowner.append("1".equals(str) ? "是" : "否").append(",");
					}
					showApply.setIsOwner(isowner.toString());
				} else {
					showApply.setIsOwner("");
				}
				// 判断年龄组别上场顺序对应FCI上场顺序
				String[] ageGroupArray = showApply.getAgeGroup().split(",");
				String ageGroup = ageGroupArray[0];
				List<ShowFciContrast> showFciContrasts = showFciContrastDao.findAllList();
				for (ShowFciContrast sh : showFciContrasts) {
					if (sh.getOaCode().equals(ageGroup)) {
						showApply.setAgeGroupFci(sh.getProCode());
					}
				}
				// 设置所有的年龄组别，去重显示
				List<String> newList = new ArrayList<>();
				for (String str : ageGroupArray) {
					if (!newList.contains(str)) {
						newList.add(str);
					}
				}
				StringBuilder ageGroupCn = new StringBuilder();
				for (String str : newList) {
					if (ageGroupCn.length() != 0) {
						ageGroupCn.append(",");
					}
					ageGroupCn.append(DictUtils.getDictLabel(str, "show_age_group", ""));
				}
				showApply.setAgeGroupCn(ageGroupCn.toString());
				// bbe组判断，繁殖人与参展人不一致(根据参加的年龄组别判断是否有BBE组)
				if (null != showApply.getBreeder()
						&& (showApply.getAgeGroup().contains("17") || showApply.getAgeGroup().contains("18"))
						&& !showApply.getHandlerMemberName().equals(showApply.getBreeder())) {
					showApply.setIsPassReason("BBE组参展人与繁殖人不一致");
					showApply.setReasonColor("#ee1d24");
				}
				// 判断犬主人姓名拼音是否正确
				if (!StringUtils.isBlank(showApply.getDogOwnerNameCn())
						&& StringUtils.isBlank(showApply.getDogOwnerNameEn())) {
					showApply.setIsPassReason("犬主姓名拼音为空");
					showApply.setReasonColor("#FF0000");
				}
				// 判断犬只代数三代
				if (null != showApply.getDogGeneration() && showApply.getDogGeneration().compareTo("3") < 0) {
					showApply.setIsPassReason("犬只代数少于三代");
					showApply.setReasonColor("#0000FF");
				}
				// 判断有父母犬的是否有繁殖人
				if ((!StringUtils.isBlank(showApply.getFdogPedigreeCertified())
						|| !StringUtils.isBlank(showApply.getMdogPedigreeCertified()))
						&& StringUtils.isBlank(showApply.getBreeder())) {
					showApply.setIsPassReason("有父母犬信息的应该有繁殖人");
					showApply.setReasonColor("#EE9A49");
				}
				// 判断退赛请假
				if (null != showApply.getRefundFlag()
						&& (showApply.getRefundFlag().equals("是") || showApply.getAbsenceFlag().equals("是"))) {
					showApply.setIsPassReason("请假或中途离场");
					showApply.setReasonColor("#bfdcf5");
				}
				// 设置excel导出时的年龄组别
				setAgeGroup(showApply);
				// 设置月龄
				Dog dog = map.get(showApply.getPedigreeCertified());
				Date minDate = dao.getMinDateByShowCodes(Arrays.asList(showApply.getShowCode().split(",")));
				showApply.setMonthAge(getMonthAge(minDate, dog.getBirthdate()));
				
			} catch (Exception e) {
				logger.warn("导出犬展报名记录出错" + showApply.getPedigreeCertified(), e);
			}
		}

		// 重新排序
		showApplyList.sort((o1, o2) -> {
			int i = Integer.compare(Integer.parseInt(o1.getDogBreedGroup()), Integer.parseInt(o2.getDogBreedGroup()));
			if (i == 0) {
				// 字符串排序方法
				i = new Comparator<String>() {
					@Override
					public int compare(String s1, String s2) {
						Pattern nonNumReg = Pattern.compile("\\D");
						Pattern numReg = Pattern.compile("\\d");
						// 排除空和相同
						if (StringUtils.isBlank(s1)) {
							return 1;
						}
						if (StringUtils.isBlank(s2)) {
							return -1;
						}
						if (s1.equals(s2)) {
							return 0;
						}
						// 判断第一位
						// 数字大于字母
						if (numReg.matcher(s1.substring(0, 1)).matches()
								&& nonNumReg.matcher(s2.substring(0, 1)).matches()) {
							return 1;
						}
						// 字母小于数字
						if (nonNumReg.matcher(s1.substring(0, 1)).matches()
								&& numReg.matcher(s2.substring(0, 1)).matches()) {
							return -1;
						}
						// 判断剩余
						// 默认为非数字规则
						Pattern reg = numReg;
						boolean intFlag = false;
						// 判断是否为数字，并更改为数字规则
						if (numReg.matcher(s1.substring(0, 1)).matches()
								&& numReg.matcher(s2.substring(0, 1)).matches()) {
							reg = nonNumReg;
							intFlag = true;
						}
						// 截取相同组成部分并比较
						String ss1 = s1, ss2 = s2;
						Matcher matcher1 = reg.matcher(s1);
						if (matcher1.find()) {
							ss1 = ss1.substring(0, matcher1.start());
							s1 = s1.substring(matcher1.start(), s1.length());
						} else {
							s1 = "";
						}
						Matcher matcher2 = reg.matcher(s2);
						if (matcher2.find()) {
							ss2 = ss2.substring(0, matcher2.start());
							s2 = s2.substring(matcher2.start(), s2.length());
						} else {
							s2 = "";
						}
						int i;
						if (intFlag) {
							i = Integer.compare(Integer.parseInt(ss1), Integer.parseInt(ss2));
						} else {
							i = ss1.toUpperCase().compareTo(ss2.toUpperCase());
						}
						// 剩余部分继续循环
						if (!s1.equals(s2) && i != 0) {
							compare(s1, s2);
						}
						return i;
					}
				}.compare(o1.getFciCode(), o2.getFciCode());
				if (i == 0) {
					i = Integer.compare(Integer.parseInt(o1.getAgeGroupFci()), Integer.parseInt(o2.getAgeGroupFci()));
					if (i == 0) {
						return o1.getDogBirthday().compareTo(o2.getDogBirthday());
					}
				}
			}
			return i;
		});
		// 秩序号
		for (int i = 0; i < showApplyList.size(); i++) {
			showApplyList.get(i).setOrderNum(SysCodeUtil.stringFormat((long) (i + 1), "000"));
		}
		return showApplyList;
	}

	/**
	 * @Description： 犬展成绩空白表导出
	 * 
	 * @author: yuanshuai
	 * @date: 2018/4/8 16:28
	 */
	public void exportScoreBlank(String showCodePrefix, MultipartFile file, HttpServletResponse response)
			throws Exception {
		// 处理原始数据
		List<ShowApply> showApplyList;
		if (file != null && !file.isEmpty()) {
			ImportExcel ei = new ImportExcel(file, 1, 0);
			showApplyList = ei.getDataList(ShowApply.class);
		} else {
			showApplyList = getShowApply(showCodePrefix);
		}
		// 储存子犬展的map
		Map<String, ChildShows> childShowsMap = Maps.newHashMap();
		// 存储裁判的map
		Map<String, ShowJudge> judgeMap = Maps.newHashMap();
		// 处理导出数据
		List<ShowScoreBlankExport> exportList = new ArrayList<>();
		for (ShowApply showApply : showApplyList) {
			ShowScoreBlankExport model = new ShowScoreBlankExport(showApply);
			String[] showCodes = model.getShowCode().split(",");
			String[] ageGroups = model.getDogAgeGroup().split(",");
			if (StringUtils.isBlank(model.getShowCode()) || showCodes.length != ageGroups.length) {
				continue;
			}
			// 拆分子犬展
			for (int i = 0; i < showCodes.length; i++) {
				String showCode = showCodes[i];
				ShowScoreBlankExport export = new ShowScoreBlankExport();
				BeanUtils.copyProperties(model, export);
				export.setShowCode(showCode);
				export.setDogAgeGroup(DictUtils.getDictLabel(ageGroups[i], "show_age_group", ""));
				ChildShows childShows;
				if (childShowsMap.containsKey(showCode)) {
					childShows = childShowsMap.get(showCode);
				} else {
					childShows = childShowsService.getByShowCode(showCode);
					childShowsMap.put(showCode, childShows);
				}
				export.setShowDate(childShows.getStartTime());
				export.setShowName(childShows.getShowName().replaceAll("\\d{1,2}月\\d{1,2}日", ""));
				export.setShowRule("0".equals(childShows.getCacType()) ? "CAC" : "CACIB");
				// 裁判信息
				if (!StringUtils.isBlank(childShows.getReferee())) {
					// 默认值：取第一个裁判
					String judgeId = childShows.getReferee().split(",")[0];
					ShowJudge showJudge;
					if (judgeMap.containsKey(judgeId)) {
						showJudge = judgeMap.get(judgeId);
					} else {
						showJudge = showJudgeDao.get(judgeId);
						judgeMap.put(judgeId, showJudge);
					}
					export.setJudge(
							"（" + showJudge.getCitizenship() + "）" + showJudge.getJudgeName().replace("&middot;", "·"));
				}
				// 默认值：奇数为1赛圈，偶数为2赛圈
				export.setShowRing(String.valueOf(Integer.parseInt(showCode.split("-")[2]) % 2 == 1 ? 1 : 2));
				exportList.add(export);
			}
		}
		// 排序
		exportList.sort((o1, o2) -> {
			int i = o1.getShowCode().compareTo(o2.getShowCode());
			if (i == 0) {
				return Integer.compare(Integer.parseInt(o1.getOrderNum()), Integer.parseInt(o2.getOrderNum()));
			}
			return i;
		});
		// 录入秩序册顺序
		for (int i = 0; i < exportList.size(); i++) {
			ShowScoreBlankExport export = exportList.get(i);
			export.setId(String.valueOf(i + 1));
		}
		new ExportExcel(showCodePrefix + "空白成绩表", ShowScoreBlankExport.class, 2).setDataList(exportList)
				.write(response, showCodePrefix + "空白成绩表.xlsx").dispose();
	}

	/**
	 * @Description： 分组并按组排序
	 * 
	 * @author: yuanshuai
	 * @date: 2018/3/26 16:01
	 */
	public List<ShowSortGroup> groupByShowApply(List<ShowApply> showApplyList) throws Exception {
		// 犬展排序List
		Map<String, ShowSortGroup> showSortGroupMap = Maps.newLinkedHashMap();
		List<ShowSortGroup> showSortGroupList = null;
		// 设置取小数点后两位
		NumberFormat numberFormat = NumberFormat.getInstance();
		numberFormat.setMaximumFractionDigits(2);
		try {
			// 按犬种组、犬种分组,showApplyList必须为有序list
			for (ShowApply showApply : showApplyList) {
				ShowSortGroup showSortGroup = showSortGroupMap.computeIfAbsent(showApply.getDogBreedGroup(),
						k -> new ShowSortGroup(showApply.getDogBreedGroup()));
				ShowSortBreed showSortBreed = showSortGroup.getShowBreedMap().computeIfAbsent(showApply.getFciCode(),
						k -> new ShowSortBreed(showApply.getDogBreedNameCn(), showApply.getDogBreedNameEn(),
								showApply.getFciCode()));
				showSortBreed.getShowApplyList().add(showApply);
			}
			// 转list计算数量
			showSortGroupList = new ArrayList<>(showSortGroupMap.values());
			showSortGroupMap.clear();
			for (ShowSortGroup showSortGroup : showSortGroupList) {
				showSortGroup.mapToList();
				int num = 0;
				for (ShowSortBreed showSortBreed : showSortGroup.getShowSortBreedList()) {
					num += showSortBreed.getShowApplyList().size();
				}
				showSortGroup.getShowSortBreedList().clear();
				showSortGroup.setNum(num);
				showSortGroup.setPercent(numberFormat.format((float) num / (float) showApplyList.size() * 100) + "%");
			}
			// 按犬种组中报名数量排序
			showSortGroupList.sort((o1, o2) -> Integer.compare(o2.getNum(), o1.getNum()));
			int sort = 1;
			for (ShowSortGroup showSortGroup : showSortGroupList) {
				showSortGroup.setSort(sort++);
			}
		} catch (Exception e) {
			logger.warn("犬展排序出错:", e);
		}
		return showSortGroupList;
	}

	/**
	 * @Description： 检查牵犬师重复的情况
	 * 
	 * @author: yuanshuai
	 * @date: 2018/3/26 13:36
	 */
	public List<ShowApply> checkShowApplyConflict(List<ShowApply> showApplyList) {
		// 重复list
		List<ShowApply> conflictList = new ArrayList<>();
		// 根据牵犬师姓名获得重复项
		HashSet<String> set = new HashSet<>();
		HashSet<String> repeatSet = new HashSet<>();
		for (ShowApply showApply : showApplyList) {
			if (set.contains(showApply.getHandlerMemberCode())) {
				// 重复元素
				repeatSet.add(showApply.getHandlerMemberCode());
			} else {
				set.add(showApply.getHandlerMemberCode());
			}
		}
		// 把重复项key转成list
		List<String> repeatList = new ArrayList<>();
		repeatList.addAll(repeatSet);
		for (String str : repeatList) {
			for (ShowApply showApply : showApplyList) {
				if (str.equals(showApply.getHandlerMemberCode())) {
					conflictList.add(showApply);
				}
			}
		}
		return conflictList;
	}

	/**
	 * 汉字转拼音
	 *
	 * @Author cuihuaiyu
	 * @2018年1月24日
	 */
	public static String ToPinyin(String chinese) {
		String pinyinStr = "";
		char[] newChar = chinese.toCharArray();
		HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
		defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
		defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
		try {
			for (int i = 0; i < newChar.length; i++) {
				if (String.valueOf(newChar[i]).matches("[\u4e00-\u9fa5]+")) {// 如果字符是中文,则将中文转为汉语拼音
					/*
					 * if (i == 2) { pinyinStr += PinyinHelper.toHanyuPinyinStringArray(newChar[i],
					 * defaultFormat)[0]; }else{ pinyinStr +=
					 * upperCase(PinyinHelper.toHanyuPinyinStringArray(newChar[i],
					 * defaultFormat)[0]); }
					 */
					pinyinStr += (PinyinHelper.toHanyuPinyinStringArray(newChar[i], defaultFormat)[0]).toUpperCase();
					if (i == 0) {
						pinyinStr = pinyinStr + " ";
					}
				} else {// 如果字符不是中文,则不转换
					pinyinStr += newChar[i];
				}
			}
		} catch (BadHanyuPinyinOutputFormatCombination e) {
			System.out.println("字符不能转成汉语拼音");
		}
		return pinyinStr;
	}

	/**
	 * 首字母大写
	 *
	 * @Author cuihuaiyu
	 * @2018年1月24日
	 */
	public static String upperCase(String str) {
		char[] ch = str.toCharArray();
		if (ch[0] >= 'a' && ch[0] <= 'z') {
			ch[0] = (char) (ch[0] - 32);
		}
		return new String(ch);
	}

	// 犬展等级贴纸申请校验
	public void stickerCheck(String identificationFlag) {
		// 等级贴纸申请基础校验
		dogStickerApplyService.basicValidate(identificationFlag, UserUtils.getLoginMember().getMemberCode());
		// 有成绩
		Dog dog = dogService.getByIdentificationFlag(identificationFlag);
		ShowResults example = new ShowResults();
		example.setPedigreeCertified(dog.getPedigreeCertifiedCode());
		// TODO: 2019/8/14 bug编号CKUVIP-1081 去掉犬展成绩验证
		// List<ShowResults> showResultsList = showResultsDao.findList(example);
		// if (showResultsList.size() == 0) {
		// throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "该犬只目前没有犬展成绩,不可申请贴纸");
		// }
	}

	@Transactional(readOnly = false)
	public void afterPay(String businessIds) {
		ShowApply po = dao.get(businessIds);
		// update by zjw 2023-02-07 工单号：ID1005116 取消宠爱护照发放
//		if ("1".equals(po.getStickerFlag())) {
//			Dog dog = dogService.getByPedigreeCertifiedCode(po.getPedigreeCertified());
//			dogStickerApplyService.applySticker(dog, po.getPaymentMemberCode(), po.getRunningNumber());
//		}
	}

	public ShowApply getByShowCodeAndPedigreeCertified(String pedigreeCertified, String showCode) {
		return dao.getByShowCodeAndPedigreeCertified(pedigreeCertified, showCode);
	}

	/**
	 * @Description： 根据子犬展编号和配种证明号获取报名信息
	 * 
	 * @author: yuanshuai
	 * @date: 2020/11/6 10:41
	 */
	public ShowApply getByShowMainIdAndPedigreeCertified(String showMainId, String pedigreeCertified) {
		return dao.getByShowMainIdAndPedigreeCertified(showMainId, pedigreeCertified);
	}

	// public int countByShowCode(String showCode) {
	// dao.countByShowCode(showCode);
	// }

	/**
	 * 当前犬主名下犬只有未缴费的犬展订单
	 * 
	 * @param dogOwnerMemberCode
	 * @return
	 */
	public List<ShowApply> findUnpaidListByDogOwnerMemberCode(String dogOwnerMemberCode) {
		return dao.findUnpaidListByDogOwnerMemberCode(dogOwnerMemberCode);
	}

	/**
	 * 当前犬主名下犬只有未缴费的犬展订单
	 * 
	 * @param pedigreeCertified
	 * @return
	 * @throws Exception
	 */
	public boolean isUnpaidShowApply(String pedigreeCertified) {
		Dog dog = dogService.getByPedigreeCertifiedCode(pedigreeCertified);
		if (Objects.isNull(dog)) {
			dog = dogService.getByIdentificationFlag(pedigreeCertified);
		}
		List<ShowApply> list = findUnpaidListByDogOwnerMemberCode(dog.getMemberCode());
		return list.size() > 0;
	}

	public boolean isUnpaidShowApplyById(String showApplyId) {
		ShowApply showApply = dao.get(showApplyId);
		List<ShowApply> list = findUnpaidListByDogOwnerMemberCode(showApply.getDogOwnerMemberCode());
		return list.stream().filter(a -> !showApplyId.equals(a.getId())).count() > 0;

	}

	/**
	 * 判断是否已经完成一场犬展
	 * 
	 * @author yuanshuai
	 * @date 2023/8/10 15:10
	 */
	public Boolean isFinishShowApply(String pedigreeCertified) {
		int count = dao.finishShowApplyCount(pedigreeCertified);
		return count > 0 ? Boolean.TRUE : Boolean.FALSE;
	}
}
