
package org.tio.sitexxx.service.service.base;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import org.tio.sitexxx.service.model.main.*;
import org.tio.sitexxx.service.service.ConfService;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.redisson.api.RTopic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.http.common.HttpRequest;
import org.tio.jfinal.kit.Kv;
import org.tio.jfinal.kit.Ret;
import org.tio.jfinal.plugin.activerecord.Db;
import org.tio.jfinal.plugin.activerecord.Page;
import org.tio.jfinal.plugin.activerecord.Record;
import org.tio.jfinal.plugin.activerecord.SqlPara;
import org.tio.sitexxx.service.cache.CacheConfig;
import org.tio.sitexxx.service.cache.Caches;
import org.tio.sitexxx.service.init.RedisInit;
import org.tio.sitexxx.service.service.UserBaseService;
import org.tio.sitexxx.service.service.atom.AbsTxAtom;
import org.tio.sitexxx.service.service.chat.FriendService;
import org.tio.sitexxx.service.service.chat.GroupService;
import org.tio.sitexxx.service.utils.CommonUtils;
import org.tio.sitexxx.service.utils.GoogleUtils;
import org.tio.sitexxx.service.utils.RetUtils;
import org.tio.sitexxx.service.vo.Const;
import org.tio.sitexxx.service.vo.topic.TopicVo;
import org.tio.utils.cache.CacheUtils;
import org.tio.utils.cache.ICache;
import org.tio.utils.resp.Resp;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author tanyaowu
 * 2016年8月10日 上午11:09:59
 */
public class UserService {
	public static final UserService ME = new UserService();
	public static final User nullUser = new User();

	private static Logger log = LoggerFactory.getLogger(UserService.class);

	/**
	 * 获取md5加密密码
	 * @param loginname 登录名
	 * @param plainpwd 明文密码
	 * @return
	 */
	public static String getMd5Pwd(String loginname, String plainpwd) {
		return SecureUtil.md5("${" + StrUtil.trim(loginname) + "}" + StrUtil.trim(plainpwd));
	}

	/**
	 * 获取两个userid的key
	 * @param uid1
	 * @param uid2
	 * @return
	 */
	public static String twoUid(Integer uid1, Integer uid2) {
		return Math.max(uid1, uid2) + "_" + Math.min(uid1, uid2);
	}

	/**
	 * 查询用户信息，主要用于展示给其它人看，所以有的信息是不允许查询出来的
	 * 会区分超管和非超管
	 * @param uid
	 * @return
	 * @author tanyaowu
	 */
	public Record info1(Integer uid) {
		ICache cache = Caches.getCache(CacheConfig.USER_INFO_3);

		String key = uid+"";
		return CacheUtils.get(cache, key, true, () -> {
			User user = UserService.ME.getById(uid);
			if (user == null) {
				return null;
			}
			Record record1 = new Record();
			record1.set("nick", user.getNick());
			record1.set("id", user.getId());
			record1.set("avatar", user.getAvatar());
			record1.set("status", user.getStatus());
			record1.set("userno", user.getUserno());

			perfectUserInfo(record1);
			UserBase userBase = UserBaseService.me.getUserBaseByUid(uid);
			if (userBase != null) {
				record1.set("sex", userBase.getSex());
				record1.set("sign", userBase.getSign());
			}
			return record1;
		});
	}

	/**
	 * 获取用户信息，所有人得到的值是一样的，不分超管和普通用户
	 * @param uid
	 * @return
	 * @throws Exception
	 * @author tanyaowu
	 */
	public Record info(Integer uid) throws Exception {
		return info1(uid);
	}

	/**
	 * 搜索用户
	 * @param nick
	 * @param pageNumber
	 * @param pageSize
	 * @return
	 * @author tanyaowu
	 */
	public Page<Record> searchNickname(String nick, Integer pageNumber, Integer pageSize) {
		if (pageNumber == null) {
			pageNumber = 1;
		}
		if (pageSize == null) {
			pageSize = 20;
		}
		Integer pageNumber1 = pageNumber;
		Integer pageSize1 = pageSize;
		if (StrUtil.isNotBlank(nick)) {
			nick = nick.trim();
			//多个空格，换成%
			Kv params = Kv.by("nick", "%"+ nick + "%");
			params.set("search", nick);
			SqlPara sqlPara = User.dao.getSqlPara("user.searchByNick", params);
			Page<Record> page1 = Db.paginate(pageNumber1, pageSize1, sqlPara);
			perfectUserInfo(page1.getList());
			return page1;
		} else {
			return null;
		}
	}

	/**
	 * 搜索用户
	 * @param nick
	 * @param uid
	 * @param loginname
	 * @param pageNumber
	 * @param pageSize
	 * @return
	 * @author tanyaowu
	 * @throws Exception
	 */
	public Page<Record> search(String nick, Integer uid, String loginname, Integer pageNumber, Integer pageSize) throws Exception {
		if (pageNumber == null) {
			pageNumber = 1;
		}
		if (pageSize == null) {
			pageSize = 20;
		}
		Integer pageNumber1 = pageNumber;
		Integer pageSize1 = pageSize;

		Short searchNickFlag = ConfService.getShort("nick.search.flag", Const.YesOrNo.YES);
		Short searchNickLike = ConfService.getShort("nick.search.like.flag", Const.YesOrNo.YES);
		ICache cache = Caches.getCache(CacheConfig.SEARCH_USER);
		Page<Record> page;
		Kv params = Kv.create();
		if (uid != null) { // 根据uid查询
			params.set("uid", uid);
			SqlPara sqlPara = User.dao.getSqlPara("user.searchByUid", params);
			page = Db.paginate(pageNumber, pageSize, sqlPara);
			perfectUserInfo(page.getList());
		} else if (StrUtil.isNotBlank(loginname)) {
			params.set("loginname", loginname);
			SqlPara sqlPara = User.dao.getSqlPara("user.searchByLoginname", params);
			page = Db.paginate(pageNumber, pageSize, sqlPara);
			perfectUserInfo(page.getList());
		} else if (StrUtil.isNotBlank(nick)) {
			nick = nick.trim();

			//多个空格，换成%
			Pattern p = Pattern.compile("\\s+");
			Matcher m = p.matcher(nick);
			String searchNick = m.replaceAll("%");

			String key = pageNumber + "_" + pageSize + "_" + searchNick;
			page = CacheUtils.get(cache, key, true, () -> {
				params.set("search", searchNick);
				if(searchNickFlag.equals(Const.YesOrNo.YES)) {
					if(searchNickLike.equals(Const.YesOrNo.YES)) {
						params.set("nicklike",searchNickFlag);
					} else {
						params.set("nickflag",searchNickFlag);
					}
				}
				SqlPara sqlPara = User.dao.getSqlPara("user.searchByNick", params);
				Page<Record> page1 = Db.paginate(pageNumber1, pageSize1, sqlPara);
				perfectUserInfo(page1.getList());
				return page1;
			});
		} else {
			return null;
		}
		return page;
	}

	/**
	 * 完善用户信息
	 * @param list
	 * @author tanyaowu
	 */
	public void perfectUserInfo(List<Record> list) {
		if (list != null) {
			for (Record record : list) {
				perfectUserInfo(record);
			}
		}
	}

	/**
	 * 完善用户信息
	 * @param record
	 * @author tanyaowu
	 */
	public void perfectUserInfo(Record record) {
		if (record == null) {
			return;
		}
		Integer uid = record.getInt("id");
		if (uid != null) {
			User user = UserService.ME.getById(uid);
			//判断是否是同一个空间
			record.set("roles", user.getRoles());
		}
	}

	/**
	 * 清空用户所有的相关缓存
	 * @param uid 如果为null，则清除所有用户的缓存
	 * @date 2016年11月20日 下午1:45:19
	 */
	public void _clearCache(Integer uid) {
		if (uid == null) {
			Caches.getCache(CacheConfig.USERID_USER_7).clear();
			Caches.getCache(CacheConfig.LOGINNAME_USER_1).clear();
			Caches.getCache(CacheConfig.USER_INFO_3).clear();
			Caches.getCache(CacheConfig.USERID_BASE).clear();
		} else {
			User user = UserService.ME.getById(uid);
			String key = uid + "";
			Caches.getCache(CacheConfig.USERID_USER_7).remove(key);
			if (user != null) {
				if (StrUtil.isNotBlank(user.getPhone())) {
					String loginkey = "phone*_" + user.getPhone();
					Caches.getCache(CacheConfig.LOGINNAME_USER_1).remove(loginkey);
				}
				if (StrUtil.isNotBlank(user.getEmail())) {
					String loginkey = "email*_" + user.getEmail();
					Caches.getCache(CacheConfig.LOGINNAME_USER_1).remove(loginkey);
				}
				Caches.getCache(CacheConfig.LOGINNAME_USER_1).remove(user.getLoginname());
			}
			ICache cache = Caches.getCache(CacheConfig.USER_INFO_3);
			cache.remove(false + key);
			cache.remove(true + key);
			Caches.getCache(CacheConfig.USERID_BASE).remove(key);
		}
	}

	/**
	 * 发topic通知清除用户缓存
	 * @param uid
	 */
	public void notifyClearCache(Integer uid) {
		_clearCache(uid);

		TopicVo topicVo = new TopicVo();
		topicVo.setType(TopicVo.Type.CLEAR_USER);
		topicVo.setValue(uid);
		RTopic topic = RedisInit.get().getTopic(Const.Topic.COMMON_TOPIC);

		//这里设置clientid，避免过滤掉自己
		//有的消息是要过滤自己的，就不能设置此值
		topic.publish(topicVo);
	}

	/**
	 * 所有用户，包括各种状态，调用后根据业务进行状态处理
	 * @param id
	 * @return
	 * @author tanyaowu
	 */
	public User getById(Integer id) {
		if (id == null) {
			return null;
		}
		ICache cache = Caches.getCache(CacheConfig.USERID_USER_7);
		String key = id + "";
		return CacheUtils.get(cache, key, true, () -> {
			User user = User.dao.findById(id);
			if (user == null) {
				return null;
			}
			List<Short> roles = new ArrayList<>();
			roles.add((short) 2);
			user.setRoles(roles);
			UserBase userBase = UserBaseService.me.getUserBaseByUid(id);
			if (userBase != null) {
				user.setSex(userBase.getSex());
				user.setSign(userBase.getSign());
			}
			return user;
		});
	}

	/**
	 * 所有状态下的用户，调用后，根据业务进行处理
	 * @param id
	 * @return
	 * @author: tanyaowu
	 */
	public User getById(String id) {
		if (StrUtil.isBlank(id)) {
			return null;
		}

		return getById(Integer.parseInt(id));
	}

	/**
	 * 保存用户，会连着保存ip等信息
	 * @param user
	 * @return
	 * @author tanyaowu
	 */
	public User save(User user) {
		IpInfo ip = user.getIpInfo();
		ip = IpInfoService.ME.save(ip);

		if (ip != null) {
			user.setIpid(ip.getId());
			boolean ff = user.save();
			if (ff) {
				user.setIpInfo(ip);
				return user;
			}
		}
		return null;
	}

	/**
	 * 获取用户数
	 * @return
	 */
	public int getUserCount() {
		ICache cache = Caches.getCache(CacheConfig.USER_COUNT);
		String key = Caches.SINGLE_KEY;

		return CacheUtils.get(cache, key, true, () -> {
			String sql = "select count(*) from user";
			return Db.use(Const.Db.TIO_SITE_MAIN).queryInt(sql);
		});
	}

	/**
	 * 根据loginname获取用户
	 * @param loginname
	 * @return
	 * @author tanyaowu
	 */
	public User getByLoginname(String loginname) {
		return User.dao.findFirst("select * from user where loginname = ? and `status` <> ?", loginname, User.Status.LOGOUT);
	}

	/**
	 * @param email
	 * @param status
	 * @return
	 * @author xufei
	 * 2020年12月16日 下午3:45:47
	 */
	public User getByEmail(String email, Short status) {
		ICache loginnameAndUserCache = Caches.getCache(CacheConfig.LOGINNAME_USER_1);
		String key = "email*_" + email;
		User user = (User) loginnameAndUserCache.get(key);
		if (user == null) {
			user = User.dao.findFirst("select * from user where email = ? and `status` <> ?", email, User.Status.LOGOUT);
			if (user != null) {
				user = getById(user.getId());
			}
			if (user != null) {
				loginnameAndUserCache.put(key, user);
			} else {
				loginnameAndUserCache.putTemporary(key, nullUser);
			}
		} else {
			//可能是 nullUser
			if (user.getId() == null) {
				return null;
			}
			if (status == null) {
				return user;
			}
			if (!Objects.equals(status, user.getStatus())) {
				return null;
			}
		}
		return user;
	}

	/**
	 * @param phone
	 * @param status
	 * @return
	 * @author xufei
	 * 2020年12月16日 下午3:45:44
	 */
	public User getByPhone(String phone, Short status) {
		ICache loginnameAndUserCache = Caches.getCache(CacheConfig.LOGINNAME_USER_1);
		String key = "phone*_" + phone;
		User user = (User) loginnameAndUserCache.get(key);
		if (user == null) {
			user = User.dao.findFirst("select * from user where phone = ? and `status` <> ? and `delsign` = ?", phone, User.Status.LOGOUT, -1);
			if (user != null) {
				user = getById(user.getId());
			}
			if (user != null) {
				loginnameAndUserCache.put(key, user);
			} else {
				loginnameAndUserCache.putTemporary(key, nullUser);
			}
		} else {
			//可能是 nullUser
			if (user.getId() == null) {
				return null;
			}
			if (status == null) {
				return user;
			}
			if (!Objects.equals(status, user.getStatus())) {
				return null;
			}
		}
		return user;
	}

	/**
	 * @param loginname
	 * @param pd5
	 * @return
	 * @throws Exception
	 * @author xufei
	 * 2020年12月16日 下午3:59:32
	 */
	public Ret login(String loginname, String pd5, String code2, HttpRequest request) throws Exception {
		String code1 = "code";
		if (StrUtil.isBlank(loginname)) {
			return Ret.fail(code1, 1);
		}
		User user = getByLoginname(loginname);
		if (user == null) {
			log.info("can find user by loginname:【{}】", loginname);
			return Ret.fail(code1, 1); //loginname不存在
		}
		//检查谷歌验证码
		if (Objects.equals(user.getGoogleStatus(), User.Google.BIND)) {
			if (StrUtil.isEmpty(code2)) {
				return Ret.fail(code1, 7);
			}
			boolean googleResult = GoogleUtils.check_code(user.getGoogleKey(), Long.parseLong(code2), System.currentTimeMillis());
			if (!googleResult) {
				return Ret.fail(code1, 6);
			}
		}
		if (!Objects.equals(pd5, user.getPwd())) {
			log.info("password is invalid, loginname:[{}], md5pwd:[{}], need md5pwd:[{}]", loginname, pd5, user.getPwd());
			return Ret.fail(code1, 2); //密码不正确
		}
		User newUser = new User();
		newUser.setId(user.getId());
		newUser.update();
		notifyClearCache(user.getId());
		return Ret.ok("user", user);
	}

	/**
	 * 修改用户昵称
	 * @param user
	 * @param newNick
	 * @return
	 * @author tanyaowu
	 */
	public Resp updateNick(User user, String newNick) {
		if (newNick.equals(user.getNick())) {
			return Resp.fail("原来的昵称就是这个哦！");
		}
		Resp resp = CommonUtils.checkGroupName(newNick, "昵称");
		if (!resp.isOk()) {
			return resp;
		}

		UserlogModifyNick userlogModifyNick = new UserlogModifyNick();
		userlogModifyNick.setNewnick(newNick);
		userlogModifyNick.setOldnick(user.getNick());
		userlogModifyNick.setUid(user.getId());

		int c;
		String sql = "update user set nick = ? where id = ?";
		c = Db.update(sql, newNick, user.getId());
		if (c < 1) {
			log.error("修改无变动：" + "用户昵称修改失败");
		}
		notifyClearCache(user.getId());
		userlogModifyNick.save();
		return Resp.ok().msg("用户昵称修改成功");
	}

	/**
	 * 更新头像
	 * @param user
	 * @param newavatar
	 * @return
	 * @author tanyaowu
	 */
	public Resp updateAvatar(User user, String newavatar) {
		UserlogModifyAvatar userlogModifyAvatar = new UserlogModifyAvatar();
		userlogModifyAvatar.setNewavatar(newavatar);
		userlogModifyAvatar.setOldavatar(user.getAvatar());
		userlogModifyAvatar.setUid(user.getId());

		String sql = "update user set avatar = ? where id = ?";
		int c = Db.update(sql, newavatar, user.getId());

		if (c < 1) {
			log.error("修改无变动：" + "用户头像修改失败");
		}
		userlogModifyAvatar.save();
		notifyClearCache(user.getId());
		return Resp.ok().msg("用户头像修改成功");
	}

	/**
	 * 修改验证方式
	 * @param user
	 * @param fdvalidtype
	 * @return
	 * @author xufei
	 * 2020年3月3日 下午5:24:48
	 */
	public Resp updateFdvalidtype(User user, Short fdvalidtype) {
		String sql = "update user set fdvalidtype = ? where id = ?";
		int c = Db.update(sql, fdvalidtype, user.getId());

		if (c < 1) {
			log.error("修改无变动：" + "用户验证方式失败");
		}
		notifyClearCache(user.getId());
		return Resp.ok().msg("用户验证方式成功");
	}

	/**
	 * @param user
	 * @param emailpwd
	 * @param phonepwd
	 * @return
	 * @author xufei
	 * 2020年12月16日 下午4:50:31
	 */
	public Resp bindPhone(User user, String phone, String phonepwd, String emailpwd) {
		String sql = "update user set phone = ?,phonepwd = ?,emailpwd = ?,pwd = ?,phonebindflag = ? where id = ?";
		int c = Db.update(sql, phone, phonepwd, emailpwd, phonepwd, Const.YesOrNo.YES, user.getId());
		if (c < 1) {
			log.error("修改无变动：" + "用户绑定失败");
		}
		notifyClearCache(user.getId());
		return Resp.ok().msg("用户绑定成功");
	}

	/**
	 * 手机注册绑定邮箱
	 * @param user
	 * @param phone
	 * @param phonepwd
	 * @param emailpwd
	 * @return
	 * @author xufei
	 * 2020年12月24日 下午6:18:27
	 */
	public Resp regbindemail(User user, String phone, String phonepwd, String emailpwd) {
		String sql = "update user set phone = ?,phonepwd = ?,phonebindflag = ? where id = ?";
		int c = Db.update(sql, phone, phonepwd, Const.YesOrNo.YES, user.getId());
		if (c < 1) {
			log.error("修改无变动：" + "用户绑定失败");
		}
		notifyClearCache(user.getId());
		return Resp.ok().msg("注册成功");
	}

	/**
	 * @param user
	 * @param phonepwd
	 * @return
	 * @author xufei
	 * 2020年12月16日 下午6:18:41
	 */
	public Resp bindNewPhone(User user, String phone, String phonepwd, String emailpwd) {
		String sql = "update user set loginname = ?,phone = ?,phonepwd = ?,emailpwd = ?,pwd = ? where id = ?";
		int c = Db.update(sql, phone, phone, phonepwd, emailpwd, phonepwd, user.getId());
		if (c < 1) {
			log.error("修改无变动：" + "用户重新绑定失败");
		}
		notifyClearCache(user.getId());
		return Resp.ok().msg("用户重新绑定成功");
	}

	/**
	 * 消息提醒设置
	 * @param user
	 * @param remindflag
	 * @return
	 * @author xufei
	 * 2020年3月3日 下午6:21:30
	 */
	public Resp updateRemind(User user, Short remindflag) {
		String sql = "update user set msgremindflag = ? where id = ?";
		int c = Db.update(sql, remindflag, user.getId());

		if (c < 1) {
			log.error("修改无变动：" + "用户消息提醒设置失败");
		}
		notifyClearCache(user.getId());
		return Resp.ok().msg("用户消息提醒设置成功");
	}

	/**
	 * 修改电话
	 * @param user
	 * @return
	 * @author xufei
	 * 2020年3月3日 下午6:24:15
	 */
	public Resp updatePhone(User user, String phone) {
		if (phone == null) {
			phone = "";
		}
		String sql = "update user_base set phone = ? where uid = ?";
		int c = Db.update(sql, phone, user.getId());
		if (c < 1) {
			log.error("修改无变动：" + "用户修改电话失败");
		}
		notifyClearCache(user.getId());
		return Resp.ok().msg("用户修改电话成功");
	}

	/**
	 * 修改签名
	 * @param user
	 * @param sign
	 * @return
	 * @author xufei
	 * 2020年3月3日 下午6:30:39
	 */
	public Resp updateSign(User user, String sign) {
		if (sign == null) {
			sign = "";
		}
		String sql = "update user_base set sign = ? where uid = ?";
		int c = Db.update(sql, sign, user.getId());
		if (c < 1) {
			log.error("修改无变动：" + "用户修改签名失败");
		}
		notifyClearCache(user.getId());
		return Resp.ok().msg("用户修改签名成功");
	}

	/**
	 * 修改用户
	 * @param curr
	 * @param update
	 * @return
	 * @author xufei
	 * 2020年4月23日 上午11:06:07
	 */
	public Resp updateUser(User curr, User update) {
		if (update == null) {
			return RetUtils.getInvalidResp();
		}
		if (StrUtil.isNotBlank(update.getNick())) {
			String filterContent = update.getNick();
			filterContent = SensitiveWordsService.findAndReplace(filterContent);
			filterContent = StringEscapeUtils.escapeHtml4(filterContent);
			update.setNick(filterContent);
		}
		AbsTxAtom absTxAtom = new AbsTxAtom() {

			@Override
			public boolean noTxRun() {
				Kv param = Kv.by("uid", curr.getId());
				if (StrUtil.isBlank(update.getSign())) {
					param.set("sign", "");
				} else {
					param.set("sign", update.getSign());
				}
				if (update.getSex() != null) {
					param.set("sex", update.getSex());
				}
				SqlPara sqlPara = Db.use(Const.Db.TIO_SITE_MAIN).getSqlPara("user.updateBase", param);
				Db.use(Const.Db.TIO_SITE_MAIN).update(sqlPara);
				update.setId(curr.getId());
				return update.update();
			}
		};
		boolean atom = Db.use(Const.Db.TIO_SITE_MAIN).tx(absTxAtom);
		if (!atom) {
			return Resp.fail("用户修改失败");
		}
		notifyClearCache(curr.getId());
		return Resp.ok().msg("用户修改成功");
	}

	/**
	 * 性别修改
	 * @param user
	 * @param sex
	 * @return
	 * @author xufei
	 * 2020年3月3日 下午6:33:38
	 */
	public Resp updateSex(User user, Short sex) {
		if (sex == null) {
			sex = Const.UserSex.MALE;
		}
		String sql = "update user_base set sex = ? where uid = ?";
		int c = Db.update(sql, sex, user.getId());
		if (c < 1) {
			log.error("修改无变动：" + "用户修改性别失败");
		}
		notifyClearCache(user.getId());
		return Resp.ok().msg("用户修改性别成功");
	}

	/**
	 * @param user
	 * @param searchflag
	 * @return
	 * @author xufei
	 * 2020年3月3日 下午6:25:59
	 */
	public Resp updateSearchFlag(User user, Short searchflag) {
		String sql = "update user set searchflag = ? where id = ?";
		int c = Db.update(sql, searchflag, user.getId());
		if (c < 1) {
			log.error("修改无变动：" + "用户设置别人搜索开关失败");
		}
		notifyClearCache(user.getId());
		return Resp.ok().msg("用户设置别人搜索开关成功");
	}

	/**
	 * 修改密码
	 * @param user
	 * @param initPwd 用户输入的原密码
	 * @param newPwd
	 * @return
	 * @author tanyaowu
	 */
	public Resp updatePwd(User user, String initPwd, String newPwd) {
		String md5pwd = getMd5Pwd(user.getLoginname(), initPwd);
		if (StrUtil.isNotBlank(newPwd)) {
			if (!Objects.equals(md5pwd, user.getPwd())) {
				return Resp.fail("原密码不正确");
			}
		}
//		String newmd5pwd = getMd5Pwd(user.getLoginname(), newPwd);
		String sql = "update user set phonepwd = ?,pwd = ? where id = ?";
		int c = Db.update(sql, newPwd, newPwd, user.getId());
		if (c <= 0) {
			log.error("修改无变动：" + "修改密码");
		}
		notifyClearCache(user.getId());
		return Resp.ok();
	}

	public Resp checkPwd(User user, String pwd){
		if (StrUtil.isNotBlank(pwd)) {
			if (!Objects.equals(pwd, user.getPwd())) {
				return Resp.fail("密码不正确");
			}
		}
		return Resp.ok();
	}

	/**
	 * @param user
	 * @param phonepwd
	 * @param emailpwd
	 * @return
	 * @author xufei
	 * 2020年12月17日 上午10:31:28
	 */
	public Resp resetPwd(User user, String phonepwd, String emailpwd) {
		String sql = "update user set phonepwd = ?,emailpwd = ?,pwd = ? where id = ?";
		int c = Db.update(sql, phonepwd, emailpwd, phonepwd, user.getId());
		if (c <= 0) {
			log.error("修改无变动：" + "找回密码");
		}
		notifyClearCache(user.getId());
		return Resp.ok();
	}

	/**
	 * 注销
	 * 1、修改用户的状态为无效
	 * 2、我-删除好友
	 * 3、我-退出群聊
	 * 4、修改所有关联的好友会话为注销会话-此处需要修改-判断是否为好友的所有逻辑-判断是否进行弹窗提醒
	 * 5、好友通讯录-要判断对方的状态
	 * @param user
	 * @return
	 * @author xufei
	 * 2021年2月26日 下午4:52:33
	 */
	public Ret logout(User user, Integer ipid) {
		if (user.getId() == null) {
			return RetUtils.failMsg("用户id为空");
		}
		User old = getById(user.getId());
		if (old == null || Objects.equals(old.getStatus(), User.Status.LOGOUT)) {
			return RetUtils.failMsg("用户已注销或不存在");
		}
		Integer uid = old.getId();
		if (Objects.equals(old.getFdvalidtype(), Const.YesOrNo.NO)) {
			User update = new User();
			update.setId(uid);
			update.setFdvalidtype(Const.YesOrNo.YES);
			update.update();
			notifyClearCache(old.getId());
		}
		try {
			List<Ret> friendList = new ArrayList<>();
			List<Ret> groupList = new ArrayList<>();
			Ret friendRet = FriendService.me.fdList(old.getId(), "");
			List<Record> myFriends = RetUtils.getOkTData(friendRet);
			Ret groupRet = GroupService.me.groupList(uid, "");
			List<Record> myGroups = RetUtils.getOkTData(groupRet);
			if (CollectionUtil.isNotEmpty(myFriends)) {
				for (Record record : myFriends) {
					try {
						//好友
						Integer touid = record.getInt("frienduid");
						Ret ret = FriendService.me.delFriend(old, touid, ipid);
						if (ret.isOk()) {
							ret.set("touid", touid);
							if (!Objects.equals(touid, uid)) {
								friendList.add(ret);
							}
						}
					} catch (Exception e) {
						log.error("注销删除好友异常-已忽略");
						log.error("", e);
					}
				}
			}
			if (CollectionUtil.isNotEmpty(myGroups)) {
				for (Record record : myGroups) {
					try {
						//退群
						Long groupid = record.getLong("groupid");
						Ret ret = GroupService.me.leaveGroup(old, groupid);
						if (ret.isOk()) {
							ret.set("groupid", groupid);
							groupList.add(ret);
						}
					} catch (Exception e) {
						log.error("注销删除群异常-已忽略");
						log.error("", e);
					}
				}
			}
			Map<String, List<Ret>> retMap = new HashMap<>();
			retMap.put("friend", friendList);
			retMap.put("group", groupList);
			User update = new User();
			update.setId(uid);
			update.setStatus(User.Status.LOGOUT);
			update.setDelsign(uid);
			update.update();
			notifyClearCache(old.getId());
			return RetUtils.okData(retMap);
		} catch (Exception e) {
			log.error(e.toString(), e);
		}
		return RetUtils.failOper();
	}

	/**
	 * 修改用户地址
	 * @param uid
	 * @param userAddress
	 * @return
	 *
	 */
	public Ret updateUserAddress(Integer uid, UserAddress userAddress) {
		if (userAddress == null || uid == null) {
			return Ret.fail().set("msg", "无效参数");
		}
		userAddress.setUid(uid);
		userAddress.update();
		return Ret.ok().set("data", userAddress);
	}

	public List<Record> findChild(Integer id) {
		String sql = "select * from user where pid = ?";
		return Db.use(Const.Db.TIO_SITE_MAIN).find(sql, id);
	}

	public List<Record> findByPids(List<Integer> ids) {
		String string = StringUtils.join(ids,",");
		String sql = "select * from user where pid in (?)";
		return Db.use(Const.Db.TIO_SITE_MAIN).find(sql, string);
	}

	/**
	 * 删除用户分组
	 */
	public Resp delUserGroup(User curr, Integer id) {
		Db.use(Const.Db.TIO_SITE_MAIN).update("update wx_friend set gid = 0 where uid = ? and gid = ?", curr.getId(), id);
		Db.use(Const.Db.TIO_SITE_MAIN).update("update wx_group_user set gid = 0 where uid = ? and gid = ?", curr.getId(), id);
		Db.use(Const.Db.TIO_SITE_MAIN).delete("delete from user_group where id = ?", id);
		return Resp.ok();
	}

	/**
	 * 添加用户分组
	 */
	public Resp addUserGroup(User curr, String name, Integer type) {
		UserGroup user = new UserGroup();
		user.setName(name);
		user.setType(type);
		user.setUid(curr.getId());
		user.setCreatetime(new Date());
		user.ignoreSave();
		return Resp.ok();
	}

	/**
	 * 更新分组名称
	 * @param id 序号
	 * @param name 名称
	 * @return
	 */
	public Resp updateUserGroup(Integer id, String name) {
		UserGroup user = UserGroup.dao.findById(id);
		if (user == null) {
			return Resp.fail("未创建群组");
		}
		user.setName(name);
		user.update();
		return Resp.ok();
	}

	/**
	 * 更新推送
	 * @param id 序号
	 * @param type 类型
	 * @param token 令牌
	 */
    public void updatePush(Integer id, String type, String token, String iosToken) {
		WxJpushUser user = WxJpushUser.dao.findFirst("select * from wx_jpush_user where uid = ?", id);
		if (user == null) {
			user = new WxJpushUser();
			user.setUid(id);
			if ("jpush".equals(type)){
				user.setRegid(token);
			} else if ("ios".equals(type)) {
				user.setRegid(iosToken);
			} else {
				user.setType(type);
				user.setToken(token);
			}
			user.setCreatetime(new Date());
			user.ignoreSave();
		} else {
			if ("jpush".equals(type)) {
				user.setRegid(token);
			} else if ("ios".equals(type)) {
				user.setRegid(iosToken);
			} else {
				user.setType(type);
				user.setToken(token);
			}
			user.setUpdatetime(new Date());
			user.update();
		}
    }

	/**
	 * 是自己才需要检测是否需要重新登录
	 * @param user
	 * @return
	 */
	public boolean checkUserStatusOther(User user) {
		if (user == null) {
			return false;
		}
		return Objects.equals(user.getStatus(), User.Status.NORMAL);
	}

	public boolean checkUserStatus(User user) {
		return checkUserStatusOther(user);
	}

	public boolean checkUserStatus(Integer uid) {
		User user = UserService.ME.getById(uid);
		return checkUserStatus(user);
	}

    public Boolean selectByCard(String idCard) {
		List<Record> find = Db.use(Const.Db.TIO_SITE_MAIN).find("select * from user where idCard = ? ",idCard);
		return CollectionUtil.isNotEmpty(find);
    }
}
