交友项目的思路与逻辑

前台接口:

注册接口:首先我们可以用到支付宝为我们提供的手机号发送验证码功能,之后我们利用这个功能向用户的手机号发送一个验证码 ,然后我们将这个验证码设置一分钟过期时间形式存入到redis中作为之后登录所需要的一个必须品,并将用户发送过来的手机号存入到我们的数据库用户表中 作为注册成功的证明,之后我们可以利用这个手机号完成用户的 登录及填写相关信息。

登录接口:

在上面注册的过程中 我们通过发送验证码得到了一个登录凭证然后在一分钟内我们利用这个验证码 进行登录的验证 如果验证码错误 则说明用户未注册 ,如果验证码正确则 让用户填写自己的相关信息 性别 年龄,名字等相关信息,然后通过传入的手机号和之前注册在数据库的手机号作为比对然后更新用户的信息,之后我们利用uuid或者其他方式生成一个Token码 并将这个Token存入到redis中作为 登录者的唯一凭证,之后所进行的一切接口访问,必须有这个Token的支持才可以进行操作,这就是登录的流程

 查看今日有趣灵魂的接口:

首先这个接口有三个部分分别是 今日访问过我的用户展示 和热度最高的用户展示 和列表用户的展示,首先我们在做最近来访的这个接口要考虑到多久才算最近 这里我设计的是七天内访问的都算是最近访问,之后我就开始建表 分别是用户表和访问记录表 访问记录表中我们要用三个字段 分别是用户的id和查看者的id 和查看时间 之后我们需要一个sql将用户表和这张访问记录表进行关联并判断访问的时间不能大于七天 之后将这个sql查询到的结果存入到一个List集合中遍历后返回给前端,之后能就是我们的查询今日最佳和列表中所展示的用户了 这里有一些条件 就是最佳包括展示的这些人都要和你有共同点,比如年龄相差不超过两岁啊,或者感情状态都为单身啊,还有就是用户的热度要高啊 等等这些,有了这些条件后 我认为如果只是在数据库中查询的话 可能会有很大的难度,所以我将这些用户信息都放入ES中也就是搜索引擎中,之后我就利用es的相关属性方法进行条件查询了,比如利用Filter这个关键字来过滤年龄讲年龄设置为是自己年龄最大不超过2岁最小也不超过两岁,感情状态的话利用Should来指定查询和自己一致的用户信息,之后就是热度值了 在这里呢 因为es会自动给出评分 并且从高到低排列 所以我就直接给了一个99-85中间的一些不重复随机数作为热度值,然后返回给前端,第一个就作为今日最佳,其余的就作为列表中展示的 order by热度值从高到低进行排序返回给前端。

情感测试接口:

接下来就是我们的情感测试接口,因为要做灵魂偶遇这个操作的时候要先回答一些测试题,然后根据测试题的结果来得到这个人的性格,然后根据性格进行匹配偶遇的人,会有一些情感测试题在这里我要写一些接口将这些测试题返回给前端,需要写三张表 分别是问题表,选项表 ,和用户回答记录表,表的具体内容是这样的 问题表是只有id和问题内容,选项表中有我们的选项id和我们对应的问题id,还有ABCD三个选项所对应的字段,而用户答题记录表呢 最主要的功能就类似与日志一样 存放着用户之前回答过得题和答案 有一个用户id和一个回答的详细信息的json串,还有abcd所对应的分值 来判断所对应的性格,最后还有一个创建时间的字段,,接下来我们有了这些表之后我们就可以写其中的逻辑了 具体逻辑是这样的,首先要先写一个接口是像用户随机发送我们题库中的一些测试题来让用户进行选择,这个接口具体是这样的 我首先写了一个方法就是随机给十二个不重复的数字 然后我调用这个方法生成十二个不重复的数字然后放入到我的sql中用一个list集合来接收返回值,具体sql是这样的 我用问题表去left join去连接选项表 然后 in 包含 我生成的那十二个不重复数字 在sql中也就是我的id,然后返回这些数据就得到了十二到题以及答案选项

 

 这就是我返回给前端用户的测试题接口,接下来我们就要接收用户做完题后的借口了 ,具体是这样实现的,首先我们可以在idea中在创建一个DTO来接收这些参数,这个dto中有这些参数,分别是题目的id 和题目的内容,然后还有一个集合 这个集合中有选项的id以及abcd四个选项 最后还有一个用户选择的id,有了这些内容后 我们就可以吧这个dto作为返回对象来进行返回,之后 我们根据前台填写的数据 接收这些内容然后来判断用户对每个题所做出的选择然后返回到数据库用户回答表中存储这些数据,存储前我们需要在逻辑层做一些判断,根据用户对每个题目的选择然后然后给对应的abcd加值 首先用户回答记录表中的abcd四个选项给默认值 为10 然后根据用户做的题来进行加等于赋值,比如说选择了两道a三道b那么a就加2分 b就加三分,如果abcd四项的分值都一样的话则给e加为满分,然后将这个结果以及JSON串存入数据库,得到用户做题的历史记录,做完这些后 我们还要有一个接口,既然已经将用户答题记录存入数据库了 那么用户如果想看自己的记录怎么办呢,这时候我们还需要一个用户查询自己答题记录的接口,这个就比较简单 只需要传入一个用户id然后根据这个id去数据库中查询用户之前做过题的记录,但是这个记录我们当时存数据的时候是转换为字符串形式存入进去了,我们需要进行一下转换来增加用户体验度,然后将这个查询到的集合对象返回给前端即可 附上代码。

 @Override
    public Result queryLoveResult(LoveResultAnswer loveResultAnswer) {
        loveResultAnswer.setCreatetime(new Date().getTime()/1000);
        List<AllLoveQuestionAndAnswerDTO> allLoveQuestionAndAnswerList = loveResultAnswer.getAllLoveQuestionAndAnswerList();
        //循环集合,取出每个结果,判断是哪个就给那个选项+1
        allLoveQuestionAndAnswerList.forEach(a ->{
            switch (a.getAnswer()){
                case "a":
                    loveResultAnswer.setDeviationA(loveResultAnswer.getDeviationA()+1);
                    break;
                case "b":
                    loveResultAnswer.setDeviationB(loveResultAnswer.getDeviationB()+1);
                    break;
                case "c":
                    loveResultAnswer.setDeviationC(loveResultAnswer.getDeviationC()+1);
                    break;
                case "d":
                    loveResultAnswer.setDeviationD(loveResultAnswer.getDeviationD()+1);
                    break;
            }
        });
        //如果四项结果相同则为结果e
        if (loveResultAnswer.getDeviationA()==loveResultAnswer.getDeviationB() &&
                loveResultAnswer.getDeviationA()==loveResultAnswer.getDeviationC() &&
                loveResultAnswer.getDeviationA()==loveResultAnswer.getDeviationD()){
            loveResultAnswer.setDeviationE(22);
        }
        TanswerPojo build = new TanswerPojo.Builder().createtime(loveResultAnswer.getCreatetime()).questionOpstionPojo(JSONArray.toJSONString(allLoveQuestionAndAnswerList)).deviationA(loveResultAnswer.getDeviationA()).deviationB(loveResultAnswer.getDeviationB()).deviationC(loveResultAnswer.getDeviationC()).deviationD(loveResultAnswer.getDeviationD()).deviationE(loveResultAnswer.getDeviationE())
                .userId(loveResultAnswer.getUserId()).build();

        userTanhuaMapper.addLoveResult(build);
        return Result.SUCCESS(build);
    }
 @Override
    public Result queryLoveTestingRecord(Integer userId) {
        TanswerPojo tanswerPojo= userTanhuaMapper.queryLoveTestingRecord(userId);
        if (tanswerPojo==null){
            return Result.ERROR();
        }
        String questionOpstionPojo = tanswerPojo.getQuestionOpstionPojo();
        List<AllLoveQuestionAndAnswerDTO> allLoveQuestionAndAnswerDTOS = JSONArray.parseArray(questionOpstionPojo, AllLoveQuestionAndAnswerDTO.class);
        LoveResultAnswer build = new LoveResultAnswer.Builder().allLoveQuestionAndAnswerList(allLoveQuestionAndAnswerDTOS).createtime(tanswerPojo.getCreatetime()).deviationA(tanswerPojo.getDeviationA())
                .deviationB(tanswerPojo.getDeviationB()).deviationC(tanswerPojo.getDeviationC()).deviationD(tanswerPojo.getDeviationE())
                .userId(tanswerPojo.getUserId()).build();
        return Result.SUCCESS(build);
    }

灵魂偶遇接口:

接下来用户做完题之后,我们就可以进行灵魂偶遇功能了,做这个接口之前我们要考虑到一个问题那就是会员问题,如果是会员的话那么这个用户可以一直进行偶遇,如果不是会员的话限制这个用户一个月只可以偶遇20个用户 ,而且已经偶遇过得用户不可以在次遇到,所以呢,我选择在建一个会员表和会员对应用户表,然后就可以判断这个用户是不是会员了,具体逻辑是这样的,我们需要一个接口这个接口只需要传入用户id 然后里面有一个方法就是根据id查询用户分值的方法,得到用户分值后我们需要在根据传过来的id来进行判断此用户是否是会员,然后呢再写一个方法查询是否是用户已查询过的数据,如果是的话不展示,接下来我们将这些用户的abcd分值放入在一个map中然后查询这些信息,然后将查询出来的结果存放到reids中,之后在查询的时候就不会出现了,已经偶遇过的人只能去历史记录中查看。

    @Override
    public Result soulMeet(Integer userId) {
         //* 1.根据用户id查到答题结果
        LoveResultAnswer loveResultAnswer = getLoveResultAnswer(userId);
        //先拿到ABCD的分值
        Integer deviationA = loveResultAnswer.getDeviationA();
        Integer deviationB = loveResultAnswer.getDeviationB();
        Integer deviationC = loveResultAnswer.getDeviationC();
        Integer deviationD = loveResultAnswer.getDeviationD();
        Integer deviationE = loveResultAnswer.getDeviationE();
        //* 2.查询会员状态
        Integer flag= userTanhuaMapper.queryUserSoulMemberInfo(userId);
        //* 3,查询所有该用户未查询过的数据
        Set members = redisTemplate.opsForSet().members("soul_user_" + userId);

        if (members.size()!=0 || members!=null){
            return Result.ERROR(999,"Redis中以有数据");
        }

        Map<String, Object> map = new HashMap<>();
        map.put("deviationA",deviationA);
        map.put("deviationB",deviationB);
        map.put("deviationC",deviationC);
        map.put("deviationD",deviationD);
        map.put("deviationE",deviationE);
        map.put("flag",flag);
        map.put("members",members);
        //* 4.如果不是会员,择取redis查询是否本月已查询过
        List<UserPojo>list= userTanhuaMapper.querySoulMeetMember(map);
        List<Integer> list1 = new ArrayList<>();
        list.forEach(a ->{
            list1.add(a.getUserId());
        });
        //将查过得用户id添加到redis中去
        redisTemplate.opsForSet().add("soul_user_"+userId,list);

         //* 5.已经偶遇过得人,只能去历史记录查找

        return Result.SUCCESS(list);
    }

暂时更新到这里 后期会更新更多接下来的接口,热爱生活 ,热爱代码。

 love you guys。

Hellow 我来更新啦,国庆节过后的第一个工作日 哈哈 大家玩的还开心吗,我补全了几个接口在这里我来给大家详细再解释一下其中的逻辑

查询附近人接口:

我们做完灵魂偶遇这个功能后,我们还需要做一个查询附近人的接口,因为是交友软件,所以查询附近人是一个相对来说比较重要的功能,附近人顾名思义这个需要我们自己的位置以及用户的位置,所以我们在进行此功能的实现前需要一个工具类就是根据经纬度计算自己距离的这么一个工具包,在这里我用的是谷歌地图提供的一个插件,我把工具类复制在下面

 /**

     * 默认地球半径

     */

    private static double EARTH_RADIUS = 6371000;//赤道半径(单位m)

    /**

     * 转化为弧度(rad)

     * */

    private static double rad(double d)

    {

        return d * Math.PI / 180.0;

    }

    /**

     * @param lon1 第一点的精度

     * @param lat1 第一点的纬度

     * @param lon2 第二点的精度

     * @param lat2 第二点的纬度

     * @return 返回的距离,单位m

     * */

    public static double GetDistance(double lon1,double lat1,double lon2, double lat2) {

        double radLat1 = rad(lat1);

        double radLat2 = rad(lat2);

        double a = radLat1 - radLat2;

        double b = rad(lon1) - rad(lon2);

        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));

        s = s * EARTH_RADIUS;

        s = Math.round(s * 10000) / 10000;

        return s;

    }

    public static void main(String[] args) {
        double v = GetDistance(113.63141921, 34.75343885, 113.63241921, 34.75343885);
        System.out.println("当前位置距离目标位置的距离是:"+v+"米");
    }

有了这个工具类 我们就可以计算一个经纬度到另一个经纬度的距离了,所以我们下一步应该怎么做呢 当然是更新自己的经纬度位置信息了,我把这个位置信息以Hash的这种形式存放在redis中了,在使用我们的这个接口前首先会更新自己所在的经纬度位置,然后我们的redis中就有了我们的经纬度信息

 接下来我们就要再写一个接口来查询附近人了,因为我们Redis中已经有我们的经纬度信息了,所以我们只需要将他们取出来然后进行遍历就可以了,具体是这样实现的,我们首先需要将自己的经纬度取出来 方便之后进行比对,然后遍历我们存储在redis中的所有HashMap集合,得到所有用户的经纬度,然后new一个List集合方便我们存储这些数据,但在存储之前我们需要做一个判断 就是要从这个集合中排除掉自己在存入,因为获取附近人是不可以也没必要获取到自己信息的,进行完这个判断之后 我们就可以将这个所有附近人的键值对存储在new的这个list集合中了,然后我们就可以调用我们的工具类进行测距了,首先呢 需要进行for循环循环这些数据调用工具类进行测距,得到这些距离后我们就可以排序了,排序的话我们可以利用stream流中的filter这个属性来进行距离的过滤,然后利用sorted这个属性来进行自然排序,排序过后我们就可以将这些我们查询到的附近人数据的用户id获取到 然后进行循环,到数据库中去查询这个用户的详细信息 就可以啦。

    //传入自己距离,根据经纬度得到附近人信息
    @PostMapping("queryNearMember")
    public Result queryNearMember(Integer userId){
        //取得Redis中用户存进去的Hash键
        Map address = redisTemplate.opsForHash().entries("address");
        //根据Hash键获取到自己的用户id
        String str =(String)address.get("user_" + userId);
        NearMember aaa = aaa(str);//自己的经纬度
        //遍历
        List<NearMember> list = new ArrayList<>();
        //获取到这个键中的所有键值对
        Set set = address.keySet();
        //遍历这些键值对
        set.forEach(a->{
            //分割key 只需要后面的userID
            Integer NearuserId = Integer.parseInt(a.toString().substring(5)) ;
            //如果得到的UserId中不包含传入的userid就进入
            if (!NearuserId.equals(userId)){
                String s = address.get(a).toString();
                NearMember aaa1 = aaa(s);
                aaa1.setUserId(NearuserId);
                list.add(aaa1);
            }
        });
        //list里有所有附近的人的经纬度
        //循环得到所有人离我的距离
        list.forEach(a->{
            double v = NearDistanceUtil.GetDistance(aaa.getLon(), aaa.getLat(), a.getLon(), a.getLat());
            a.setDistance(v);
        });
        //排序 根据Stream流中提供的过滤方法 查询到距离在五公里以内的用户正序排序
        List<NearMember> collect = list.stream().filter(a -> a.getDistance() <= 5000).sorted(Comparator.comparing(NearMember::getDistance)).collect(Collectors.toList());
        List<UserPojo>list1=new ArrayList<>();
        //将查询到的附近人数据的用户id获取到然后进行循环 到数据库中查询获得用户详细的信息
        for (int i = 0; i < collect.size(); i++) {
            NearMember nearMember = collect.get(i);
            Integer userId1 = nearMember.getUserId();
            Double distance = nearMember.getDistance();
            UserPojo userPojo=userTanhuaService.queryUser(userId1);
            userPojo.setDistance(distance);
            list1.add(userPojo);
        }
        return Result.SUCCESS(list1);
    }

桃花传音接口:

接下来附近人结束之后呢,还需要做一个小功能就是桃花传音,类似于微信中的漂流瓶功能一样,可以发送语音也可以接收语音,每个人一天只可以发送十条,也只可以接收十条,接下来我就给大家详细说下我的实现过程....首先先从发送语音开始上手,我们需要在数据库中在建一张表 语音表,这个表中有一下几个字段分别是主键id,用户id,创建时间和用户上传的录音路径,在这里呢 我上传录音的方法是将这个音频存入到阿里云oss对象存储这个空间中,这个空间中可以获取到一个路径 路径就是这个音频,所以我们只需要将这个路径存入到数据库中即可,因为有限制每个用户每天只可以上传10条语音,所以我们在进行上传录音前需要先去这张表中查询当天这个用户已经发送几条了所以需要一个查询方法

 之后我们就可以进行上传录音了,我们需要两个参数 分别是用户id和文件,之后我们调用阿里云oss的工具类将用户传过来的这个文件传入到oss中 然后调用刚才的查询方法如果这个用户今天已经发送了十条或者十条以上就将这个信息返回给用户,否则我们就可以将这个用户id和语音路径以及当前时间存入到数据库中,这就是我们桃花传音 发送语音的方法

 接下来我们就可以进行随机接收语音的这个接口了,这个接口我仍然要创建一张数据库表 叫作收听者表,里面有几个字段 主键id,用户id,收听次数,当前日期,这几个字段  这个我写的比较麻烦复杂一些 ,因为我没用redis缓存中间件,大家可以考虑用redis ,具体逻辑是这样的,首先我们需要先做一个判断 那就是日期是否是当前日期 如果传入的用户日期不是当前日期的话那么就更新日期并把收听次数改为0,如果是当前是当前日期呢就做以下判断,判断当前传入的用户id是否存在如果不存在的话就新创建这个用户并赋予当前日期和用户id以及浏览次数为0,如果存在该用户id呢 那么就更新这个用户id使它的收听次数在原有的基础上加1, 之后呢我们就可以查询当前用户的查询次数了 只需要传入用户id然后进行查询收听次数,如果大于10就将这个信息返回给用户,之后呢我们就可以查询用户发送的语音了,只需要利用随机数来实现就可以,random一个随机数然后给这个查询方法 ,但写这个查询方法前需要做一个判断那就是 当前查到的这个用户id不能和自己传入的id一致 如果一致的话就说明又是接收到自己的语音了,然后将查询到的这个数据返回就可以了。

 @Override
    public Result queryMemberMp3(Integer userId) {
        Date date = new Date();
        LookMp3 lookMp3= userTanhuaMapper.queryLookMp3(userId);
        LookMp3 lookMp31 = new LookMp3();
        if (lookMp3!=null && lookMp3.getCreateTime().getDay()!=date.getDay()){
            lookMp31.setUserId(userId);
            lookMp31.setLookCount(0);
            userTanhuaMapper.updateLookMp3Bydate(lookMp31);
        }else {

        if (lookMp3!=null && lookMp3.getUserId()!=null){
            lookMp3.setUserId(userId);
            lookMp3.setLookCount(lookMp3.getLookCount()+1);
            userTanhuaMapper.updateLookMp3(lookMp3);
        }else {
            lookMp31.setUserId(userId);
            lookMp31.setLookCount(lookMp31.getLookCount());
            userTanhuaMapper.addLookMp3(lookMp31);
        }
          }
       //查询当前用户查询次数
        LookMp3 lookMp30= userTanhuaMapper.queryLookMp3Count(userId);
        Integer lookCount = lookMp30.getLookCount();
        if (lookCount>=10){
            return Result.ERROR(998,"今日查看已达上限");
        }
        List<MemberMp3>list=userTanhuaMapper.queryMp3();
        int random=(int)(Math.random()*10+1);
        List<MemberMp3>memberMp3s= userTanhuaMapper.queryMemberMp3(random);
        for (int i = 0; i < memberMp3s.size(); i++) {
            MemberMp3 memberMp3 = memberMp3s.get(i);
            Integer userId1 = memberMp3.getUserId();
            if (!userId1.equals(userId)){
                return Result.SUCCESS(memberMp3s);
            }
        }
        return Result.SUCCESS("未查询到,稍后再试");
    }

先更新到这里 之后会继续进行更新,热爱生活,热爱代码。

猜你喜欢

转载自blog.csdn.net/m0_67864787/article/details/127086482
今日推荐