package com.tzy.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.tzy.annotation.ApiLog;
import com.tzy.annotation.RequireRoles;
import com.tzy.common.config.QuerySql;
import com.tzy.common.config.handle.ApiVersion;
import com.tzy.common.constant.Constants;
import com.tzy.common.core.controller.BaseController;
import com.tzy.common.core.domain.entity.SysDictData;
import com.tzy.common.dto.InDto;
import com.tzy.common.dto.OutDTO;
import com.tzy.common.dto.pay.PaymentChannel;
import com.tzy.common.enums.BusinessType;
import com.tzy.common.enums.NotifyNameEnum;
import com.tzy.common.utils.DateUtils;
import com.tzy.common.utils.ServletUtils;
import com.tzy.common.utils.StringUtils;
import com.tzy.common.utils.UserType;
import com.tzy.common.utils.bean.DozerUtils;
import com.tzy.common.utils.http.forest.CommonForestClient;
import com.tzy.common.utils.security.Md5Utils;
import com.tzy.coupon.card.domain.AppUserCardRecord;
import com.tzy.coupon.card.domain.TzyCardBaseInfo;
import com.tzy.coupon.card.domain.TzyCardTaskRemind;
import com.tzy.coupon.card.service.ITzyCardBaseInfoService;
import com.tzy.coupon.card.service.ITzyCardTaskRemindService;
import com.tzy.dto.AppActDTO;
import com.tzy.dto.local.ResultDTO;
import com.tzy.express.service.ExpressService;
import com.tzy.framework.util.RedisUtils;
import com.tzy.pojo.app.AppActConfig;
import com.tzy.sportcard.api.domain.AppNotifyConfig;
import com.tzy.sportcard.api.domain.AppUserInfoDto;
import com.tzy.sportcard.api.domain.CouponInfo;
import com.tzy.sportcard.api.dto.merchant.MerchantScoreDTO;
import com.tzy.sportcard.api.dto.merchant.MerchantSimpleDTO;
import com.tzy.sportcard.api.mapper.MerchantApiMapper;
import com.tzy.sportcard.api.service.*;
import com.tzy.sportcard.base.service.CommonCacheService;
import com.tzy.sportcard.base.service.CommonConsumeRankService;
import com.tzy.sportcard.base.service.ITzyPlayerInfoService;
import com.tzy.sportcard.dto.CommonConsumeRankParamDTO;
import com.tzy.sportcard.dto.TzyPlayerInfoDTO;
import com.tzy.sportcard.group.dto.ExpressCourierNumDTO;
import com.tzy.sportcard.group.service.ICardGroupOrderInfoService;
import com.tzy.util.BarcodeUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.common.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.teasoft.bee.osql.PreparedSql;
import org.teasoft.bee.osql.SuidRich;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author by po'yi
 * @Classname RongCloudController
 * @Description 融云api
 * @Date 2022/2/28 11:56
 */
@Slf4j
@Api("通用api")
@RestController
@RequestMapping("/api/common")
public class CommonController extends BaseController {

	@Value("${suolink.appKey:634586a92dfbd60cb30a7be89e@c758d0a2fa07d96b8471757554333ed4}")
	private String suolinkKey;
	@Value("${suolink.domainUrl:i6q.cn}")
	private String domainUrl;
	@Autowired
	private PreparedSql preparedSql;
	@Autowired
	private SuidRich suidRich;
	@Autowired
	private MineApiService mineApiService;
	@Resource
	private CommonForestClient commonForestClient;
	@Autowired
	private RedisUtils redisUtils;
	@Autowired
	private MerchantApiService merchantApiService;
	@Resource
	private AsyncAppService asyncAppService;
	@Resource
	private IAppNotifyConfigService notifyConfigService;
	@Autowired
	private ITzyCardBaseInfoService cardBaseInfoService;

	private final String linkReqUrl = "http://api.suolink.cn/api.htm";

	@Resource private CommonConsumeRankService commonConsumeRankService;

	@Resource private CommonCacheService commonCacheService;

	@Resource private ITzyPlayerInfoService playerInfoService;

	@Resource private ICardGroupOrderInfoService cardGroupOrderInfoService;
	@Autowired
	private ITzyCardTaskRemindService cardTaskRemindService;
	@Resource
	private TzyMerchantAssessService tzyMerchantAssessService;
	@Autowired
	private ExpressService expressService;

	@ApiLog(title = "生成短链", businessType = BusinessType.SEARCH)
	@ResponseBody
	@RequestMapping(value = "/{version}/suolink", method = RequestMethod.POST)
	@ApiVersion(1.0)
	@ApiOperation("生成短链")
	public OutDTO getSuolink(@RequestBody InDto inDto) throws UnsupportedEncodingException {
		String url = inDto.getString("url");
		if (StringUtils.isEmpty(url)) {
			return OutDTO.error500("url为空");
		}
		String key1="app_suo_link_cache";
		String key2= Md5Utils.hash(url);
		Object linkUrlCache = redisUtils.hget(key1, key2);
		if(linkUrlCache!=null){
			return OutDTO.ok().put("linkUrl", linkUrlCache);
		}
		StringBuffer reqUrl = new StringBuffer().append(linkReqUrl).append("?url=")
				.append(URLEncoder.encode(inDto.getString("url"), Constants.UTF8)).append("&key=")
				.append(suolinkKey).append("&expireDate=2030-12-31").append("&domain=").append(domainUrl);
		String linkUrl = commonForestClient.sendGet(reqUrl.toString());
		redisUtils.hset(key1, key2,linkUrl);
		return OutDTO.ok().put("linkUrl", linkUrl);

	}


	@ApiLog(title = "获取优惠劵信息", businessType = BusinessType.SEARCH)
	@ResponseBody
	@RequestMapping(value = "/{version}/getCouponByIds", method = RequestMethod.POST)
	@ApiVersion(1.0)
	@ApiOperation("获取优惠劵信息")
	public OutDTO getCouponByIds(@RequestBody InDto inDto) {
		if (StringUtils.isEmpty(inDto.getString("ids"))) {
			return OutDTO.error500("id为空");
		}
		List<TzyCardBaseInfo> coupons = Arrays.asList(inDto.getString("ids").split(","))
				.stream().map(id -> getCoupon(Long.valueOf(id))).collect(Collectors.toList());
		return OutDTO.ok().put("coupons", coupons);
	}


	@ApiLog(title = "获取开屏广告等活动", businessType = BusinessType.SEARCH)
	@ResponseBody
	@RequestMapping(value = "/{version}/act", method = RequestMethod.POST)
	@ApiVersion(1.0)
	@ApiOperation("获取开屏广告等活动")
	public OutDTO getAct(@RequestBody InDto inDto) {
		//优惠券发放活动，查询发放活动提醒表，
		log.info("开屏广告查询 userId {}",inDto.getUserId());
		List<AppActDTO> appActDTOList=new ArrayList<>();
		List<TzyCardTaskRemind> cardTaskRemindList = cardTaskRemindService.getRemindByUserId(inDto.getUserId());
		if (!CollectionUtils.isEmpty(cardTaskRemindList)){
			for (TzyCardTaskRemind tzyCardTaskRemind : cardTaskRemindList) {
				AppActDTO appActDTO=new AppActDTO();
				appActDTO.setActImg(tzyCardTaskRemind.getImgUrl());
				appActDTO.setImgType("0");
				appActDTO.setActUrl("/pageC/myCoupon/couponList");
				appActDTO.setClickType(0);
				appActDTO.setCouponIds("10");
				appActDTO.setLastTime(5);

				appActDTOList.add(appActDTO);
				//更新提醒状态
				cardTaskRemindService.updateCardTaskRemind(tzyCardTaskRemind.getId(),1);
			}
			log.info("优惠券提醒list：{}",appActDTOList);
		}
		List<AppActConfig> actList = getAppActConfigs(inDto.getUserId());
		if (actList.isEmpty()) {
			return OutDTO.ok().put("page_act",appActDTOList);
		}
		Map<String, List<AppActConfig>> groupActs = actList.stream().collect(Collectors.groupingBy(AppActConfig::getSubType));
		//开屏广告
		List<AppActConfig> open_ad = groupActs.get("open_ad");
		//首页活动
		List<AppActConfig> firstPageActs = groupActs.get("first_page");
		List<AppActDTO> pageActs;
		if (firstPageActs != null) {
			pageActs = firstPageActs.stream().filter(act -> checkAct(act, inDto.getUserId()))
					.map(act -> DozerUtils.map(act, AppActDTO.class)).collect(Collectors.toList());
		}else {
			pageActs=new ArrayList<>();
		}
		pageActs.addAll(appActDTOList);
		AppActDTO ad = null;
		if (open_ad != null && !open_ad.isEmpty()) {
			ad = DozerUtils.map(open_ad.get(0), AppActDTO.class);
		}

		return OutDTO.ok().put("open_ad", ad).put("page_act", pageActs);
	}

	private List<AppActConfig> getAppActConfigs(Integer userId) {
		Object actCache = redisUtils.get(Constants.APP_ACT_CACHE);
		List<AppActConfig> actList;
		if (actCache == null) {
			String sql = QuerySql.getQuerySql("com.tzy.pojo.app.AppActConfig.getAct");
			actList = preparedSql.selectSomeField(sql, new AppActConfig(), new Object[]{});
			redisUtils.set(Constants.APP_ACT_CACHE, actList);
		} else {
			actList = (List<AppActConfig>) actCache;
		}
		if (!actList.isEmpty()) {
			int currentHour = DateUtils.getCurrentHour();
			Date now = new Date();
			actList = actList.stream().filter(act -> {
				if (now.before(act.getStartTime()) || now.after(act.getEndTime())) {
					return false;
				}
				if (currentHour < act.getStartHour() || currentHour >= act.getEndHour()) {
					return false;
				}
				if (act.getCatId() != null && act.getCatId() > 0) {
					List<Long> userIds = mineApiService.getUserIdByCatId(act.getCatId());
					return userId != null && userIds.contains(userId.longValue());
				}
				return true;
			}).collect(Collectors.toList());
		}
		return actList;
	}

	private TzyCardBaseInfo getCoupon(Long id) {
		if (id == null) {
			return null;
		}
		TzyCardBaseInfo condition = new TzyCardBaseInfo();
		condition.setId(id);
		return suidRich.selectOne(condition);
	}

	private boolean checkAct(AppActConfig act, Integer userId) {
		if(userId==null||userId<1){
			return true;
		}
		boolean isRemind=act.getRemindTime() > 0;
		String key = "act_remind_cache_" + act.getId() + "_userid_" + userId;
		if (isRemind && redisUtils.hasKey(key)) {
			//限制时间内不再提示
			return false;
		}
		boolean needLogin = act.getHistoryLimitDay() > 0 || act.getUserGrowth() > 0;
		//判断条件
		if (!needLogin) {
			if (isRemind) {
				redisUtils.set(key, 1, act.getRemindTime() * 3600);
			}
			return true;
		}

		if (needLogin && userId == null) {
			return false;
		}

		boolean buyFlag = true;
		if (act.getHistoryLimitDay() > 0) {
			String limitDay = " and (now() - create_time::timestamp < interval '" + act.getHistoryLimitDay() + " day')";
			String sql = QuerySql.getQuerySql("com.tzy.pojo.app.AppActConfig.getUserOrderCount");
			sql += limitDay;
			String orderCount = preparedSql.selectFun(sql, new Object[]{userId});
			if (Integer.parseInt(orderCount) == 0) {
				buyFlag = false;
			}
		}

		boolean growthFlag = true;
		if (act.getUserGrowth() > 0) {
			AppUserInfoDto user = mineApiService.searchUserInfoById(userId);
			if (user.getGrowthNum() < act.getUserGrowth() * 100) {
				growthFlag = false;
			}
		}
		boolean reminderFlag = act.getOp() == 0 ? buyFlag || growthFlag : buyFlag && growthFlag;
		if (reminderFlag && StringUtils.isNotEmpty(act.getCouponIds())) {
			String sql = "SELECT count(0) FROM app_user_card_record WHERE user_id=" + userId + " and card_id in (" + act.getCouponIds() + ")";
			String couponCount = preparedSql.selectFun(sql, new Object[]{});
			if (Integer.parseInt(couponCount) > 0) {
				return false;
			}
		}

		if (reminderFlag && isRemind) {
			redisUtils.set(key, 1, act.getRemindTime() * 3600);
		}

		return reminderFlag;
	}

	@ApiLog(title = "查询活动优惠券",businessType = BusinessType.UPDATE,indto = "{{inDto}}")
	@ResponseBody
	@RequestMapping(value = "/act/coupon", method = RequestMethod.POST)
	public OutDTO findActCoupon(@RequestBody InDto inDto){
		if (null == inDto) {
			return OutDTO.error500( "参数不能为空");
		}
		String actType=inDto.getString("actType");
		if(StringUtils.isEmpty(actType)){
			actType="双11";
		}
		Object merchantId = inDto.get("merchantId");
		AppUserCardRecord appUserCardRecord = new AppUserCardRecord();
		appUserCardRecord.setSport(inDto.getString("sport"));
		appUserCardRecord.setActType(actType);
		appUserCardRecord.setPage(inDto.getPageNo());
		appUserCardRecord.setRows(inDto.getPageSize());
		appUserCardRecord.setMerchantName(inDto.getString("merchantName"));
		if(merchantId!=null){
			appUserCardRecord.setMerchantId((Integer)merchantId);
		}
		if(StringUtils.isNotEmpty(inDto.getString("keyword"))){
			appUserCardRecord.setFromCategory(inDto.getString("keyword"));
		}
		if(inDto.getUserId()!=null){
			appUserCardRecord.setUserId(inDto.getUserId().longValue());
		}
		// 排序
		Integer orderType = Integer.valueOf(inDto.getData().get("orderType").toString());
		String sidx = "cbi.create_time DESC";
		// 排序类型：1新到券、2快过期、3面额从大到小、4折扣从大到小
		switch (orderType){
			case 1: // 新到券
				//sidx = " cbi.create_time DESC";
				break;
			case 2: // 前端冲突，弃用
				//sidx = " AND (aucr.expiry_time - now()::timestamp < interval '24 hour')  ORDER BY aucr.expiry_time DESC";
				break;
			case 3:  // 面额从大到小
				sidx = " cbi.discount DESC ";
				break;
			case 4:  // 折扣率从大到小
				sidx = " discountRate ASC ";
				break;
			case 5: // 快领完
				sidx = " num ASC ";
				break;
			default:
				//sidx = " case when (cbi.max_claim - cbi.received )>0 and aucr.user_id is null THEN 1 ELSE 0 end desc ,cbi.discount DESC";
				break;
		}
		appUserCardRecord.setSidx(sidx);
		List<CouponInfo> couponInfos = mineApiService.findActCoupon(appUserCardRecord);

		return OutDTO.ok().put("couponInfos",couponInfos);
	}

	@ApiLog(title = "查询参加优惠劵活动的商家",businessType = BusinessType.UPDATE,indto = "{{inDto}}")
	@ResponseBody
	@RequestMapping(value = "/act/coupon/merchant", method = RequestMethod.POST)
	public OutDTO findActMerchant(@RequestBody InDto inDto){
		if (null == inDto) {
			return OutDTO.error500( "参数不能为空");
		}
		String actType=inDto.getString("actType");
		if(StringUtils.isEmpty(actType)){
			actType="双11";
		}
		List<MerchantSimpleDTO> merchantInfos=merchantApiService.findActMerchant(actType,inDto.getString("name"));
		return OutDTO.ok().put("merchantInfos",merchantInfos);
	}

	@ApiLog(title = "查询活动消费排行榜",businessType = BusinessType.SEARCH)
	@ResponseBody
	@PostMapping("/consumeRank")
	public OutDTO consumeRank(@RequestBody InDto inDto){
		if (null == inDto) {
			return OutDTO.error500( "参数不能为空");
		}

		List<SysDictData> sysDictDataList = commonCacheService.getCommonDictData("consume_rank", null, Constants.STATUS_OK, null, 600);
		//{"merchantId":85,"startTime":"2022-11-24","endTime":"2022-12-06","hotType":"2022双11主,2022双11分"}
		if (CollectionUtils.isEmpty(sysDictDataList)) {
			return OutDTO.error500( "活动不存在");
		}
		String paramStr = sysDictDataList.get(0).getDictValue();
		com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(paramStr);
		CommonConsumeRankParamDTO dto = JSONObject.toJavaObject(jsonObject, CommonConsumeRankParamDTO.class);
		Object hotType = jsonObject.get("hotType");
		if(null != hotType) {
			dto.setHotTypes(hotType.toString().split(","));
		}
		return OutDTO.ok().put("data", commonConsumeRankService.consumeRank(dto, inDto.getUserId()));
	}

	@ApiLog(title = "根据球员姓名查询球员",businessType = BusinessType.SEARCH)
	@ResponseBody
	@PostMapping("/getPlayerByNames")
	public OutDTO getPlayerByNames(@RequestBody InDto inDto){
		if (null == inDto) {
			return OutDTO.error500( "参数不能为空");
		}
		List<TzyPlayerInfoDTO> playerInfoList = playerInfoService
				.getPlayerInfoByNames(inDto.getString("name"), inDto.getString("sport"));
		return OutDTO.ok().put("playerInfoList", playerInfoList);
	}

	/**
	 * 查询订单物流轨迹
	 */
	@ApiLog(title = "根据物流单号公司查询物流轨迹v3", businessType = BusinessType.SEARCH)
	@PostMapping( "/order/express3")
	@ResponseBody
	public OutDTO getOrderExpressInfoV3(@RequestBody InDto inDto) {
		mineApiService.checkUserNew(inDto);
		String courierNum = inDto.getString("courierNum"); // 快递单号
		if (StringUtils.isEmpty(courierNum)) {
			return OutDTO.error500("参数[courierNum]不能为空");
		}
		String curierCompany = inDto.getString("curierCompany"); // 快递公司
		if (StringUtils.isEmpty(curierCompany)) {
			return OutDTO.error500("参数[curierCompany]不能为空");
		}
		String phone = inDto.getString("phone"); // 手机号
		ExpressCourierNumDTO courierDTO = new ExpressCourierNumDTO(0, courierNum, curierCompany, phone);

		if (curierCompany.contains("顺丰")) {
			if (StringUtils.isEmpty(phone)) {
				return OutDTO.error500("参数[phone]不能为空");
			}
			if(courierNum.startsWith("SF")) {
				return OutDTO.ok().put("expressData", cardGroupOrderInfoService.getSFExpressInfo(courierDTO));
			}else {
				return OutDTO.ok().put("expressData", null);
			}
		} else {
			return OutDTO.ok().put("expressData", cardGroupOrderInfoService.getOtherExpressInfo(courierDTO));
		}
	}


	/**
	 * 查询订单物流轨迹
	 */
	@ApiLog(title = "根据物流单号公司查询物流轨迹v4", businessType = BusinessType.SEARCH)
	@PostMapping( "/order/v4/express")
	@ResponseBody
	public OutDTO getOrderExpressInfoV4(@RequestBody InDto inDto) {
		mineApiService.checkUserNew(inDto);
		String courierNum = inDto.getString("courierNum"); // 快递单号
		if (StringUtils.isEmpty(courierNum)) {
			return OutDTO.error500("参数[courierNum]不能为空");
		}
		String curierCompany = inDto.getString("curierCompany"); // 快递公司
		if (StringUtils.isEmpty(curierCompany)) {
			return OutDTO.error500("参数[curierCompany]不能为空");
		}
		String phone = inDto.getString("phone"); // 手机号
		ExpressCourierNumDTO courierDTO = new ExpressCourierNumDTO(0, courierNum, curierCompany, phone);

		//2025年8月25日 修改 ，顺丰时 查询快递记录表是否是一键发货订单 如果是一键发货订单，如果是sfgf 调用顺丰获取路由接口
		if(curierCompany.contains("顺丰")) {
			if (StringUtils.isEmpty(phone)) {
				return OutDTO.error500("参数[phone]不能为空");
			}
			if(courierNum.startsWith("SF")) {
				return OutDTO.ok().put("expressData", expressService.getCourierRoute(phone,courierNum));
			}else {
				return OutDTO.ok().put("expressData", null);
			}
		}else{
			return OutDTO.ok().put("expressData", cardGroupOrderInfoService.getOtherExpressInfo(courierDTO));
		}
	}

	@ApiLog(title = "消息推送",businessType = BusinessType.INSERT)
	@ResponseBody
	@PostMapping("/push")
	public OutDTO push(@RequestBody InDto inDto){
		if(inDto.existKeyString("userId")){
			Integer userId = Integer.parseInt(inDto.getString("userId"));
			// 验证用户是否开启聊天通知
			List<AppNotifyConfig> configs = notifyConfigService.selectNotifyConfigByUserId(userId);
			if(!CollectionUtils.isEmpty(configs)){
				Optional<AppNotifyConfig> optional = configs.stream()
						.filter(config -> NotifyNameEnum.CHAT.getType().equals(config.getMsgType()) && config.getStatus() == 1)
						.findFirst();
				if(optional.isPresent()) {
					AppUserInfoDto appUserInfoDto = mineApiService.searchUserInfoById(userId);
					//AppUserInfoDto appUserInfoDto = mineApiService.checkUserNew(inDto);
					String userName = inDto.getString("userName");
					String message = inDto.getString("message");
					List<String> params = Lists.newArrayList();
					params.add(userName);
					params.add(message);
					Map<String, String> extrasMap = Maps.newHashMap();
					extrasMap.put("url", inDto.getString("url"));
					asyncAppService.jpush(14, Constants.JPUSH_TYPE_ID, Collections.singletonList(appUserInfoDto.getSmsRegisterId()), params, extrasMap);
				}
			}
			return OutDTO.ok();
		}
		else if(inDto.existKeyString("merchantId")){
			//查询商家账号对应的开启聊天通知的SmsRegisterId列表
			List<AppUserInfoDto> SmsRegisterIdList = merchantApiService.getSmsRegisterIdsByMerchantId(Integer.parseInt(inDto.getString("merchantId")));
			List<Integer> userIDs = SmsRegisterIdList.stream().map(AppUserInfoDto::getId).collect(Collectors.toList());

			//由于通知设置的存储结构限制，还需逐个判断是否能发到具体用户上
			List<AppNotifyConfig> chatConfigs = notifyConfigService.selectChatNotifyConfigByUserIds(userIDs);

			if(!CollectionUtils.isEmpty(SmsRegisterIdList)){
				SmsRegisterIdList.forEach(userInfo->{
					Optional<AppNotifyConfig> optional = chatConfigs.stream()
							.filter(config -> NotifyNameEnum.CHAT.getType().equals(config.getMsgType()) && config.getUserId()==userInfo.getId().longValue() && config.getStatus() == 1)
							.findFirst();
					if(optional.isPresent()) {
						String userName = inDto.getString("userName");
						String message = inDto.getString("message");
						List<String> params = Lists.newArrayList();
						params.add(userName);
						params.add(message);
						Map<String, String> extrasMap = Maps.newHashMap();
						extrasMap.put("url", inDto.getString("url"));
						asyncAppService.jpush(14, Constants.JPUSH_TYPE_ID, Collections.singletonList(userInfo.getSmsRegisterId()), params, extrasMap);
					}
				});
			}
			return OutDTO.ok();
		}
		else if(inDto.existKeyString("hscs")){
			List<SysDictData> sysDictDataList = commonCacheService.getCommonDictData("IMAdmin", null, Constants.STATUS_OK, "IMAdmin", 600);
			List<String> accountName = sysDictDataList.stream().map(dict -> dict.getDictValue()).collect(Collectors.toList());
			List<Long> userids = sysDictDataList.stream().map(dict -> Long.parseLong(dict.getDictLabel())).collect(Collectors.toList());
			//查询客服的userid
			List<String> SmsRegisterIdList = Stream.concat(mineApiService.getAllIMAdminSmsRegisterIdListByUsername(accountName).stream(), mineApiService.getAllIMAdminSmsRegisterIdList(userids).stream())
					.distinct()
					.collect(Collectors.toCollection(ArrayList::new));
			// 客服不校验聊天通知
			if(!CollectionUtils.isEmpty(SmsRegisterIdList)){
					String userName = inDto.getString("userName");
					String message = inDto.getString("message");
					List<String> params = Lists.newArrayList();
					params.add(userName);
					params.add(message);
					Map<String, String> extrasMap = Maps.newHashMap();
					extrasMap.put("url", inDto.getString("url"));
					asyncAppService.jpush(14, Constants.JPUSH_TYPE_ID, SmsRegisterIdList, params, extrasMap);
			}
			return OutDTO.ok();
		}else if(inDto.existKeyString("operation")){
			List<SysDictData> sysDictDataList = commonCacheService.getCommonDictData("operationUserId", null, Constants.STATUS_OK, "operationUserId", 600);
			List<String> useridStr = JSON.parseObject( sysDictDataList.get(0).getDictValue(),List.class);
			List<Long> userids = useridStr.stream().map(Long::parseLong).collect(Collectors.toList());
			//查询运营的userid
			List<String> SmsRegisterIdList =  mineApiService.getAllIMAdminSmsRegisterIdList(userids).stream()
					.distinct()
					.collect(Collectors.toCollection(ArrayList::new));
			// 运营不校验聊天通知
			if(!CollectionUtils.isEmpty(SmsRegisterIdList)){
				String userName = inDto.getString("userName");
				String message = inDto.getString("message");
				List<String> params = Lists.newArrayList();
				params.add(userName);
				params.add(message);
				Map<String, String> extrasMap = Maps.newHashMap();
				extrasMap.put("url", inDto.getString("url"));
				asyncAppService.jpush(14, Constants.JPUSH_TYPE_ID, SmsRegisterIdList, params, extrasMap);
			}
			return OutDTO.ok();
		}
		else{return OutDTO.error(400,"InDto missing param");}
	}

	@ApiLog(title = "修改优惠劵msg",businessType = BusinessType.INSERT)
	@RequireRoles(value = {UserType.USER_ROLE_ADMIN})
	@ResponseBody
	@PostMapping("/check/coupon")
	public OutDTO checkCoupon(@RequestBody InDto inDto) {
		Integer id = inDto.getIntegerParam("id");
		String msg = inDto.getString("msg");
		if (id == null || StringUtils.isEmpty(msg)) {
			return OutDTO.error500("参数缺失！");
		}
		TzyCardBaseInfo updateMsg = new TzyCardBaseInfo();
		updateMsg.setId(id.longValue());
		updateMsg.setMsg(msg);
		cardBaseInfoService.updateTzyCardBaseInfo(updateMsg);
		return OutDTO.ok();
	}

	@PostMapping("/barcode/decode")
	@ResponseBody
	public OutDTO decodeBarcode(@RequestParam("file") MultipartFile file,
								@RequestParam(required = false, defaultValue = "barcode") String type) throws IOException {
		// 直接从流读取 BufferedImage
		BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
		if (bufferedImage == null) {
			return OutDTO.error500("无法读取图片");
		}
		String barcodeText = null;
		if ("barcode".equalsIgnoreCase(type)) {
			barcodeText = BarcodeUtil.decodeBarcode(bufferedImage);
		} else if ("qrcode".equalsIgnoreCase(type)) {
			barcodeText = BarcodeUtil.decodeQRCode(bufferedImage);
		} else {
			return OutDTO.error500("未知的类型，请选择barcode或qrcode");
		}
		return OutDTO.ok().put("barCode", barcodeText);
	}


	@GetMapping("/merchant/score/{merchantId}")
	@ApiOperation("商家店铺评分")
	public ResultDTO merchantScore(@PathVariable Long merchantId){
		String timestamp =  ServletUtils.getRequest().getHeader("timestamp"); // 时间戳
		String token = ServletUtils.getRequest().getHeader("token"); // 校验请求身份
		String key = "hobby_" + timestamp + "_merchant_score";
		String md5PassWord = DigestUtils.md5DigestAsHex(key.getBytes()).toUpperCase();
		if(Strings.isEmpty(token) || !token.equals(md5PassWord)){
			return ResultDTO.build500Error("token认证失败");
		}
		MerchantScoreDTO merchantScoreDTO = tzyMerchantAssessService.getMerchantMemberInfoV3(merchantId);
		return ResultDTO.buildSuccessResult(merchantScoreDTO);
	}

	@GetMapping("/merchant/scores/{ids}")
	@ApiOperation("多商家店铺评分")
	public ResultDTO merchantScore(@PathVariable String ids){
		String timestamp =  ServletUtils.getRequest().getHeader("timestamp"); // 时间戳
		String token = ServletUtils.getRequest().getHeader("token"); // 校验请求身份
		String key = "hobby_multiple_" + timestamp + "_merchant_scores";
		String md5PassWord = DigestUtils.md5DigestAsHex(key.getBytes()).toUpperCase();
		if(Strings.isEmpty(token) || !token.equals(md5PassWord)){
			return ResultDTO.build500Error("token认证失败");
		}
		String[] idArray = ids.split(",");
		List<MerchantScoreDTO> resultList = new ArrayList<>();

		for (String idStr : idArray) {
			Long merchantId = Long.parseLong(idStr.trim());
			MerchantScoreDTO merchantScoreDTO = tzyMerchantAssessService.getMerchantMemberInfoV3(merchantId);
			merchantScoreDTO.setId(merchantId);
			resultList.add(merchantScoreDTO);
		}
		return ResultDTO.buildSuccessResult(resultList);
	}

	@GetMapping("/merchant/scores/avg")
	@ApiOperation("活跃商家店铺平均分")
	public ResultDTO activeMerchantAvg(){
		String timestamp =  ServletUtils.getRequest().getHeader("timestamp"); // 时间戳
		String token = ServletUtils.getRequest().getHeader("token"); // 校验请求身份
		String key = "hobby_" + timestamp + "_merchant_avg_score";
		String md5PassWord = DigestUtils.md5DigestAsHex(key.getBytes()).toUpperCase();
		if(Strings.isEmpty(token) || !token.equals(md5PassWord)){
			return ResultDTO.build500Error("token认证失败");
		}
		BigDecimal avgScore = tzyMerchantAssessService.getActiveMerchantAvg();
		return ResultDTO.buildSuccessResult(avgScore);
	}
}
