Fivk博客 - 探花交友
type: channel
link: https://blog.fivk.cn/tag/%E6%8E%A2%E8%8A%B1%E4%BA%A4%E5%8F%8B/
items: 【探花交友】推荐系统&实战简介
items: 【探花交友】数据统计与内容审核
items: 【探花交友】后台系统
items: 【探花交友】小视频方案
items: 【探花交友】环信API方法介绍
items: 【探花交友】即时通信
items: 【探花交友】圈子互动
items: 【探花交友】圈子功能实现
items: 【探花交友】MongoDB基础
items: 【探花交友】完善个人信息

【探花交友】推荐系统&实战简介
type: item
date: 2023-04-12T21:04:00+08:00
description: 1、了解推荐系统1.1、什么是推荐系统？为了解决信息过载和用户无明确需求的问题，找到用户感兴趣的物品，才有了个性化推荐系统。其实，解决信息过载的问题，代表性的解决方案是分类目录和搜索引擎，如hao123，电商首页的分类目录以及百度，360搜索等。不过分类目录和搜索引擎只能解决用户主动查找信息的需求，即用户知道自己想要什么，并不能解决用户没用明确需求很随便的问题。经典语录是：你想吃什么，随便！面对这种很随便又得罪不起的用户（女友和上帝），只能通过分析用户的历史行为给用户的兴趣建模，从而主动给用户推荐能够满足他们兴趣和需求的信息。比如问问女友的闺蜜，她一般什么时候喜欢吃什么。1.2、电商是推荐系统的先行者[ ] 电子商务网站是个性化推荐系统重要地应用的领域之一，亚马逊就是个性化推荐系统的积极应用者和推广者，亚马逊的推荐系统深入到网站的各类商品，为亚马逊带来了至少30%的销售额。[ ] 不光是电商类，推荐系统无处不在。QQ，微信的好友推荐；新浪微博的你可能感兴趣的人；优酷，土豆的电影推荐；豆瓣的图书推荐；大从点评的餐饮推荐；脉脉的同事推荐等。[ ] 推荐引擎的鼻祖思想源泉：http://portal.acm.org/citation.cfm?id=1070751[ ] 亚马逊最早提出基于物品的协同过滤推荐算法：http://portal.acm.org/citation.cfm?id=372071京东的推荐： 1.3、推荐系统业务流程推荐系统广泛存在于各类网站中，作为一个应用为用户提供个性化的推荐。它需要一些用户的历史数据，一般由三个部分组成：基础数据、推荐算法系统、前台展示。基础数据包括很多维度，包括用户的访问、浏览、下单、收藏，用户的历史订单信息，评价信息等很多信息；推荐算法系统主要是根据不同的推荐诉求由多个算法组成的推荐模型；前台展示主要是对客户端系统进行响应，返回相关的推荐信息以供展示。1.4、协同过滤推荐算法迄今为止，在个性化推荐系统中，协同过滤技术是应用最成功的技术。目前国内外有许多大型网站应用这项技术为用户更加智能（个性化、千人千面）的推荐内容。核心思想：协同过滤一般是在海量的用户中发掘出一小部分和你品位比较类似的，在协同过滤中，这些用户成为邻居，然后根据他们喜欢的其他东西组织成一个排序的目彔作为推荐给你。1.4.1、基于用户的推荐 UserCF对于用户A，根据用户的历史偏好，这里只计算得到一个邻居–用户C，然后将用户C 喜欢的物品D 推荐给用户A。基于用户的协同过滤算法先计算的是用户与用户的相似度（兴趣相投，物以类聚人以群分），然后将相似度比较接近的用户A购买的物品推荐给用户B，专业的说法是该算法用最近邻居（nearest-neighbor）算法找出一个用户的邻居集合，该集合的用户和该用户有相似的喜好，算法根据邻居的偏好对该用户进行预测。1.4.2、基于商品的推荐 ItemCF基于ItemCF的原理和基于UserCF类似，只是在计算邻居时采用物品本身，而不是从用户的角度，即基于用户对物品的偏好找到相似的物品，然后根据用户的历史偏好，推荐相似的物品给他。从计算的角度看，就是将所有用户对某个物品的偏好作为一个向量来计算物品之间的相似度，得到物品的相似物品后，根据用户历史的偏好预测当前用户还没有表示偏好的物品，计算得到一个排序的物品列表作为推荐。解释：对于物品A，根据所有用户的历史偏好，喜欢物品A 的用户都喜欢物品C，得出物品A 和物品C 比较相似，而用户C 喜欢物品A，那么可以推断出用户C 可能也喜欢物品C。1.5、ALS算法ALS 是交替最小二乘 （alternating least squares）的简称。在机器学习的上下文中，ALS 特指使用交替最小二乘求解的一个协同推荐算法。它通过观察到的所有用户给产品的打分，来推断每个用户的喜好并向用户推荐适合的产品。从协同过滤的分类来说，ALS算法属于User-Item CF，也叫做混合CF。它同时考虑了User和Item两个方面。用户和商品的关系，可以抽象为如下的三元组：<User,Item,Rating>。其中，Rating是用户对商品的评分，表征用户对该商品的喜好程度。如下：196 242 3 881250949 186 302 3 891717742 22 377 1 878887116 244 51 2 880606923 166 346 1 886397596 298 474 4 884182806 115 265 2 881171488 253 465 5 891628467 305 451 3 886324817 6 86 3 883603013 62 257 2 879372434 286 1014 5 879781125 200 222 5 8760423…

【探花交友】数据统计与内容审核
type: item
date: 2023-04-10T09:31:00+08:00
description: 1、用户冻结解冻用户冻结/解冻使用管理员在后台系统对用户的惩罚措施。对于发布不当言论或者违法违规内容的用户，可以暂时、永久禁止其登录，评论，发布动态、后台中解冻/冻结，就是将用户状态写入数据库中APP端用户在进行登录，评论，发布动态时检测Redis中冻结状态1.1 用户冻结ManageController//用户冻结 @PostMapping("/users/freeze") public ResponseEntity freeze(@RequestBody Map params) { Map map = managerService.userFreeze(params); return ResponseEntity.ok(map); }ManageService//用户冻结 public Map userFreeze(Map params) { Integer freezingTime = (Integer) params.get("freezingTime"); Long userId = (Long) params.get("userId"); int days = 0; if (freezingTime == 1) { days = 3; } if (freezingTime == 2) { days = 7; } if (freezingTime == 3) { days = -1; } String value = JSON.toJSONString(params); redisTemplate.opsForValue().set(Constants.FREEZE_USER+userId,value,days, TimeUnit.MINUTES); Map map = new HashMap(); map.put("message","冻结成功"); return map; }1.2 用户解冻ManageController//用户解冻 @PostMapping("/users/unfreeze") public ResponseEntity unfreeze(@RequestBody Map params) { Map map = managerService.userUnfreeze(params); return ResponseEntity.ok(map); }ManageService//用户解冻 public Map userUnfreeze(Map params) { Long userId = (Long) params.get("userId"); String reasonsForThawing = (String) params.get("reasonsForThawing"); redisTemplate.delete(Constants.FREEZE_USER+userId); Map map = new HashMap(); map.put("message","解冻成功"); return map; }1.3 查询数据列表UserInfo添加字段//用户状态,1为正常，2为冻结 @TableField(exist = false) private String userStatus = "1";ManageServicepublic ResponseEntity findById(Long userId) { UserInfo info = userInfoApi.findById(userId); if(redisTemplate.hasKey(Constants.FREEZE_USER+info.getId())) { info.setUserStatus("2"); } return ResponseEntity.ok(info); }1.4 探花系统修改UserFreezeService@Service public class UserFreezeService { @Autowired private RedisTemplate<String,String> redisTemplate; public void checkUserStatus(Integer state,Long userId) { String value = redisTemplate.opsForValue().get(Constants.FREEZE_USER + userId); if(!StringUtils.isEmpty(value)) { Map map = JSON.parseObject(value, Map.class); Integer freezingRange = (Integ…

【探花交友】后台系统
type: item
date: 2023-04-02T16:01:00+08:00
description: 1、项目架构1.1 概述API网关有很多实现方式，我们通过SpringCloud Gateway实现使用Nacos作为配置中心1.2 API网关1.2.1 搭建网关依赖<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- nacos配置中心依赖支持 <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> --> <dependency> <groupId>com.itheima</groupId> <artifactId>tanhua-commons</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>引导类@SpringBootApplication public class GatewayApplication { public static void main(String[] args) { SpringApplication.run(GatewayApplication.class, args); } }跨域问题配置类package com.itheima.gateway.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.reactive.CorsWebFilter; import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource; import org.springframework.web.util.pattern.PathPatternParser; /** * 跨域支持 */ @Configuration public class CorsConfig { @Bean public CorsWebFilter corsFilter() { CorsConfiguration config = new CorsConfiguration(); config.addAllowedMethod("*"); config.addAllowedOrigin("*"); config.addAllowedHeader("*"); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser()); source.registerCorsConfiguration("/**", config); return new CorsWebFilter(source); } }配置文件server: port: 8888 spring: profiles: active: prod application: name: tanhua-gateway cloud: nacos: discovery: server-addr: 192.168.136.160:8848 gateway: globalcors: add-to-simple-url-handler-mapping: true corsConfig…

【探花交友】小视频方案
type: item
date: 2023-03-29T11:33:00+08:00
description: 我的动态（查询思路）圈子的互动（点赞，喜欢，评论）数据表：quanzi_comment(commentType记录操作类型)点赞，喜欢，评论（保存记录）取消点赞，取消喜欢（删除记录）为了保证效率（结合redis缓存，互动数量记录到动态表）课程说明小视频功能说明FastDFS环境搭建小视频的功能实现1、我的访客查询别人来访了我的主页的信息，其他用户在浏览我的主页时，需要记录访客数据。访客在一天内每个用户只记录一次。查询数据时，如果用户查询过列表，就需要记录这次查询数据的时间，下次查询时查询大于等于该时间的数据。如果，用户没有记录查询时间，就查询最近的5个来访用户。1.1、dubbo服务1.1.1、实体对象@Data @NoArgsConstructor @AllArgsConstructor @Document(collection = "visitors") public class Visitors implements java.io.Serializable{ private static final long serialVersionUID = 2811682148052386573L; private ObjectId id; private Long userId; //我的id private Long visitorUserId; //来访用户id private String from; //来源，如首页、圈子等 private Long date; //来访时间 private String visitDate;//来访日期 private Double score; //得分 }1.1.2、定义接口package com.tanhua.dubbo.server.api; import com.tanhua.dubbo.server.pojo.Visitors; import java.util.List; public interface VisitorsApi { /** * 保存访客数据 * * @param userId 我的id * @param visitorUserId 访客id * @param from 来源 * @return */ String save(Long userId, Long visitorUserId, String from); /** * 查询我的访客数据，存在2种情况： * 1. 我没有看过我的访客数据，返回前5个访客信息 * 2. 之前看过我的访客，从上一次查看的时间点往后查询5个访客数据 */ List<Visitors> queryMyVisitor(Long userId); }1.1.3、编写实现package com.tanhua.dubbo.server.api; import cn.hutool.core.convert.Convert; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; import com.alibaba.dubbo.config.annotation.Service; import com.tanhua.dubbo.server.pojo.RecommendUser; import com.tanhua.dubbo.server.pojo.Visitors; import org.bson.types.ObjectId; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.redis.core.RedisTemplate; import java.util.List; @Service(version = "1.0.0") public class VisitorsApiImpl implements VisitorsApi { @Autowire…

【探花交友】环信API方法介绍
type: item
date: 2023-03-01T09:39:00+08:00
description: 安装如果你的项目使用Maven构建并且spring boot是2.4.3以上版本，可以在pom.xml中添加下面代码：<dependency> <groupId>com.easemob.im</groupId> <artifactId>im-sdk-core</artifactId> <version>0.5.9</version> </dependency>如果你使用的spring-boot是2.4.3以下版本的，还需要在pom.xml中添加:<dependencyManagement> <dependencies> <dependency> <groupId>io.netty</groupId> <artifactId>netty-bom</artifactId> <version>4.1.59.Final</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>io.projectreactor</groupId> <artifactId>reactor-bom</artifactId> <version>2020.0.4</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>准备在使用Server SDK之前，需要准备环信appkey、Client ID、ClientSecre。如果你有环信管理后台账号并创建过应用，请先登录环信管理后台，点击 这里，然后到“应用列表” → 点击“查看”即可获取到appkey、Client ID、ClientSecret。使用EMService是所有API的入口，可以这样初始化：EMProperties properties = EMProperties.builder() .setAppkey(cliProperties.getAppkey()) .setClientId(cliProperties.getClientId()) .setClientSecret(cliProperties.getClientSecret()) .build(); EMService service = new EMService(properties);根据业务资源，API分为：Attachment 用于上传下载附件Block 用于限制访问Contact 用于管理联系人Group 用于管理群组Message 用于发送消息User 用于管理用户Room 用于管理聊天室后续用到的API所有的API上面链接可查// 创建环信用户 service.user().create("user01", "123456").block(); // 添加好友 service.contact().add("user01, "user02").block(); // 删除好友 service.contact().remove("user01", "uer02").block(); // 服务端发送消息 Set<String> set = CollUtil.newHashSet("123"); service.message().send("user01", "users", set, new EMTextMessage().text("java"), null) .block();

【探花交友】即时通信
type: item
date: 2023-03-01T09:33:00+08:00
description: 1、即时通信1.1、什么是即时通信？1.2、功能说明在探花交友项目中也提供了类似微信的聊天功能，用户可以和好友或陌生人聊天。如果是陌生人，通过《聊一下》功能进行打招呼，如果对方同意后，就成为了好友，可以进行聊天了。陌生人之间如果相互喜欢，那么就会成为好友，也就可以聊天了。在消息界面中也可以查看：点赞、评论、喜欢、公告等消息信息。1.3、技术方案对于高并发的即时通讯实现，还是很有挑战的，所需要考虑的点非常多，除了要实现功能，还要考虑并发、流量、负载、服务器、容灾等等。虽然有难度也并不是高不可攀。对于现实即时通讯往往有两种方案：方案一：自主实现，从设计到架构，再到实现。技术方面可以采用：Netty + WebSocket + RocketMQ + MongoDB + Redis + ZooKeeper + MySQL方案二：对接第三方服务完成。这种方式简单，只需要按照第三方的api进行对接就可以了。如：环信、网易、容联云通讯等。如何选择呢？如果是中大型企业做项目可以选择自主研发，如果是中小型企业研发中小型的项目，选择第二种方案即可。方案一需要有大量的人力、物力的支持，开发周期长，成本高，但可控性强。方案二，成本低，开发周期短，能够快速的集成起来进行功能的开发，只是在可控性方面来说就差了一些。探花交友项目选择方案二进行实现。2、环信官网：https://www.easemob.com/ 稳定健壮，消息必达，亿级并发的即时通讯云2.1、开发简介平台架构：集成：环信和用户体系的集成主要发生在2个地方，服务器端集成和客户端集成。探花集成：探花前端使用AndroidSDK进行集成文档：http://docs-im.easemob.com/im/android/sdk/import后端集成用户体系文档：http://docs-im.easemob.com/im/server/ready/user2.2、环信Console需要使用环信平台，那么必须要进行注册，登录之后即可创建应用。环信100以内的用户免费使用，100以上就要注册企业版了。企业版价格：创建应用：创建完成：2.3、接口说明2.3.1、Appkey 数据结构当您申请了 AppKey 后，会得到一个 xxxx#xxxx 格式的字符串，字符串只能由小写字母数字组成，AppKey是环信应用的唯一标识。前半部分 org_name 是在多租户体系下的唯一租户标识，后半部分 app_name 是租户下的app唯一标识（在环信后台创建一个app时填写的应用 id 即是 app_name ）。下述的 REST API 中，/{org_name}/{app_name}的请求，均是针对一个唯一的appkey进行的。目前环信注册的appkey暂不能由用户自己完成删除操作，如果对 APP 删除需要联系环信操作完成。Appkeyxxxx分隔符xxxx环信应用的唯一标识org_name#app_name2.3.2、环信 ID 数据结构环信作为一个聊天通道，只需要提供环信 ID （也就是 IM 用户名）和密码就够了。名称字段名数据类型描述环信 IDusernameString在 AppKey 的范围内唯一用户名。用户密码passwordString用户登录环信使用的密码。2.3.4、获取管理员权限环信提供的 REST API 需要权限才能访问，权限通过发送 HTTP 请求时携带 token 来体现，下面描述获取 token 的方式。说明：API 描述的时候使用到的 {APP 的 client_id} 之类的这种参数需要替换成具体的值。重要提醒：获取 token 时服务器会返回 token 有效期，具体值参考接口返回的 expires_in 字段值。由于网络延迟等原因，系统不保证 token 在此值表示的有效期内绝对有效，如果发现 token 使用异常请重新获取新的 token，比如“http response code”返回 401。另外，请不要频繁向服务器发送获取 token 的请求，同一账号发送此请求超过一定频率会被服务器封号，切记，切记！！client_id 和 client_secret 可以在环信管理后台的 APP 详情页面看到。HTTP Request/{org_name}/{app_name}/token Request Headers参数说明Content-Typeapplication/jsonRequest Body参数说明grant_typeclient_credentialsclient_idApp的client_id，可在app详情页找到client_secretApp的client_secret，可在app详情页找到Response Body参数说明access_token有效的tok…

【探花交友】圈子互动
type: item
date: 2023-01-11T15:49:00+08:00
description: 课程说明圈子动态查询圈子实现评论圈子实现点赞、喜欢功能圈子实现评论1、动态查询我的动态：查询个人发布的动态列表（分页查询），和之前实现的好友动态，推荐动态实现逻辑是一致。1.1、查询好友动态查询好友动态与查询推荐动态显示的结构是一样的，只是其查询数据源不同1.1.1、接口文档API接口文档：http://192.168.136.160:3000/project/19/interface/api/1421.1.2、代码步骤Controller层接受请求参数Service数据封装调用API查询好友动态详情数据调用API查询动态发布人详情构造VO对象API层根据用户ID查询好友发布动态详情查询好友时间线表查询动态详情1.1.3、代码实现MovementController /** * 查询好友动态 */ @GetMapping public ResponseEntity movements(@RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "10") Integer pagesize) { PageResult pr = movementService.findFriendMovements(page,pagesize); return ResponseEntity.ok(pr); }MovementService//好友动态 public PageResult findFriendMovements(Integer page, Integer pagesize) { //1、获取当前用户id Long userId = UserHolder.getUserId(); //2、查询数据列表 List<Movement> items = movementApi.findFriendMovements(userId,page,pagesize); //3、非空判断 if(CollUtil.isEmpty(items)) { return new PageResult(); } //4、获取好友用户id List<Long> userIds = CollUtil.getFieldValues(items, "userId", Long.class); //5、循环数据列表 Map<Long, UserInfo> userMaps = userInfoApi.findByIds(userIds, null); List<MovementsVo> vos = new ArrayList<>(); for (Movement item : items) { //5、一个Movement构建一个Vo对象 UserInfo userInfo = userMaps.get(item.getUserId()); MovementsVo vo = MovementsVo.init(userInfo, item); vos.add(vo); } //6、构建返回值 return new PageResult(page,pagesize,0L,vos); }movementApi@Override public List<Movement> findFriendMovements(Long friendId, Integer page, Integer pagesize) { //1、查询好友时间线表 Query query = Query.query(Criteria.where("friendId").in(friendId)) .skip((page - 1)*pagesize).limit(pagesize) .with(Sort.by(Sort.Order.desc("created"))); List<MovementTimeLine> lines = mongoTemplate.find(query, MovementTimeLine.class); //2、提取动态id集合 List<ObjectId> movementIds = CollUtil.getFieldValues(lines, "movementId", ObjectId.class); //3、根据动态id查询动态详情 Query movementQuery = Query.query(Criteria.where("id").in(movementIds)); return mongoTemplate.find(movementQuery, Movement.class); }1.2、查询推荐动态推荐动态是通过推荐系统计算出的结果，现在我们只需要实现查询即可，推荐系统在后…

【探花交友】圈子功能实现
type: item
date: 2022-10-05T18:34:00+08:00
description: 1、首页推荐1.1、接口分析地址：http://192.168.136.160:3000/project/19/interface/api/118响应：{ "counts": 4698, "pagesize": 20, "pages": 58, "page": 16, "items": [ { "id": 1011, "avatar": "assets/images/avatar_2.png", "nickname": "黑马小妹", "gender": "woman", "age": 23, "tags": [ "本科", "年龄相仿", "单身" ], "fateValue": 96 }, { "id": 2495, "avatar": "assets/images/avatar_1.png", "nickname": "米朵妹妹", "gender": "man", "age": 28, "tags": [ "年龄相仿", "本科", "单身" ], "fateValue": 87 }, { "id": 5708, "avatar": "assets/images/avatar_4.png", "nickname": "黑马小妹", "gender": "man", "age": 24, "tags": [ "单身", "本科", "年龄相仿" ], "fateValue": 94 }, { "id": 4768, "avatar": "assets/images/avatar_3.png", "nickname": "黑马小妹", "gender": "man", "age": 24, "tags": [ "年龄相仿", "单身", "本科" ], "fateValue": 80 } ] }1.2、功能实现1.2.1 controllerTanhuaController编写推荐列表方法/** * 查询分页推荐好友列表 */ @GetMapping("/recommendation") public ResponseEntity recommendation(RecommendUserDto dto) { PageResult pr = tanhuaService.recommendation(dto); return ResponseEntity.ok(pr); }1.2.2 serviceTanhuaService编写推荐列表方法//查询分页推荐好友列表 public PageResult recommendation(RecommendUserDto dto) { //1、获取用户id Long userId = UserHolder.getUserId(); //2、调用recommendUserApi分页查询数据列表（PageResult -- RecommendUser） PageResult pr = recommendUserApi.queryRecommendUserList(dto.getPage(),dto.getPagesize(),userId); //3、获取分页中的RecommendUser数据列表 List<RecommendUser> items = (List<RecommendUser>) pr.getItems(); //4、判断列表是否为空 if(items == null || items.size() <=0) { return pr; } //5、提取所有推荐的用户id列表 List<Long> ids = CollUtil.getFieldValues(items, "userId", Long.class); UserInfo userInfo = new UserInfo(); userInfo.setAge(dto.getAge()); userInfo.setGender(dto.getGender()); //6、构建查询条件，批量查询所有的用户详情 Map<Long, UserInfo> map = userInfoApi.findByIds(ids, userInfo); //7、循环推荐的数据列表，构建vo对象 List<TodayBest> list = new ArrayList<>(); for (RecommendUser item : items) { UserInfo info = map.get(item.getUserId()); if(info!=null) { TodayBest vo = TodayBest.init(info, item); list.add(vo); } } //8、构造返回值 pr.setItems(list);…

【探花交友】MongoDB基础
type: item
date: 2022-09-20T12:48:00+08:00
description: 课程介绍MongoDB环境搭建MongoDB基本CRUD操作通过JavaApi操作MongoDBSpringBoot整合MongoDB1、通用设置1.1 需求分析1.1.1 需求分析通用设置，包含探花交友APP基本的软件设置功能。包含：设置陌生人问题：当平台其他用户想进行在线交流时需要回答陌生人问题。通用设置：包含一些APP通知设置黑名单：对于不感兴趣的用户设置黑名单屏蔽骚扰1.1.2 数据库表通用设置CREATE TABLE `tb_settings` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `user_id` bigint(20) DEFAULT NULL, `like_notification` tinyint(4) DEFAULT '1' COMMENT '推送喜欢通知', `pinglun_notification` tinyint(4) DEFAULT '1' COMMENT '推送评论通知', `gonggao_notification` tinyint(4) DEFAULT '1' COMMENT '推送公告通知', `created` datetime DEFAULT NULL, `updated` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='设置表';问题表CREATE TABLE `tb_question` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `user_id` bigint(20) DEFAULT NULL COMMENT '用户id', `txt` varchar(200) DEFAULT NULL COMMENT '问题内容', `created` datetime DEFAULT NULL, `updated` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `user_id` (`user_id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8黑名单CREATE TABLE `tb_black_list` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `user_id` bigint(20) DEFAULT NULL, `black_user_id` bigint(20) DEFAULT NULL, `created` datetime DEFAULT NULL, `updated` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `user_id` (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='黑名单';1.1.3 搭建提供者环境实体类（1） Settings@Data @NoArgsConstructor @AllArgsConstructor public class Settings extends BasePojo { private Long id; private Long userId; private Boolean likeNotification; private Boolean pinglunNotification; private Boolean gonggaoNotification; }（2）Question@Data @NoArgsConstructor @AllArgsConstructor public class Question extends BasePojo { private Long id; private Long userId; //问题内容 private String txt; }（3）BlackList@Data @NoArgsConstructor @AllArgsConstructor public class BlackList extends BasePojo { private Long id; private Long userId; private Long blackUserId; }mapper接口（1）SettingsMapperpublic interface SettingsMapper extends BaseMapper<Settings> { }（2）QuestionMapperpublic interface Questi…

【探花交友】完善个人信息
type: item
date: 2022-09-11T17:54:00+08:00
description: 1、完善用户信息用户在首次登录时需要完善个人信息，包括性别、昵称、生日、城市、头像等。其中，头像数据需要做图片上传，这里采用阿里云的OSS服务作为我们的图片服务器，并且对头像要做人脸识别，非人脸照片不得上传。首次登录时（手机号码不存在），需要创建用户存入数据库中客户端检测首次登录需要完善用户信息填写用户基本信息上传用户头像（需要人脸认证）1.1、阿里云OSS实现图片上传服务，需要有存储的支持，那么我们的解决方案将以下几种：直接将图片保存到服务的硬盘（springmvc将的文件上传）优点：开发便捷，成本低缺点：扩容困难使用分布式文件系统进行存储优点：容易实现扩容缺点：开发复杂度稍大（有成熟的产品可以使用，比如：FastDFS）使用第三方的存储服务优点：开发简单，拥有强大功能，免维护缺点：付费在本套课程中选用阿里云的OSS服务进行图片存储。1.1.1、概述对象存储服务（Object Storage Service，OSS）是一种海量、安全、低成本、高可靠的云存储服务，适合存放任意类型的文件。容量和处理能力弹性扩展，多种存储类型供选择，全面优化存储成本。地址：https://www.aliyun.com/product/oss1.1.2、账号申请购买服务使用第三方服务最大的缺点就是需要付费，下面，我们看下如何购买开通服务。购买下行流量包： （不购买也可以使用，按照流量付费）说明：OSS的上行流量是免费的，但是下行流量是需要购买的。创建Bucket使用OSS，首先需要创建Bucket，Bucket翻译成中文是水桶的意思，把存储的图片资源看做是水，想要盛水必须得有桶，就是这个意思了。进入控制台，https://oss.console.aliyun.com/overview选择Bucket后，即可看到对应的信息，如：url、消耗流量等 :文件管理：查看文件：1.1.3、抽取模板工具和发送短信类似，阿里云OSS也是采用自定义工具的形式进行封装OssPropertiestanhua-autoconfig创建配置类@Data @ConfigurationProperties(prefix = "tanhua.oss") public class OssProperties { private String accessKey; private String secret; private String bucketName; private String url; //域名 private String endpoint; }OssTemplatetanhua-autoconfig创建模板对象package com.tanhua.autoconfig.template; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.tanhua.autoconfig.properties.OssProperties; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.Date; import java.util.UUID; public class OssTemplate { private OssProperties properties; public OssTemplate(OssProperties properties) { this.properties = properties; } /** * 文件上传 * 1：文件名称 * 2：输入流 */ public String upload(String filename, InputStream is) { //3、拼写图片路径 filename = new SimpleDateFormat("yyyy/MM/dd").format(new Date()) +"/"+ UUID.randomUUID().toString() + filename.substring(filename.lastIndexOf(".")); // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1（杭州）为例，Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。 String endpoint = properties.getEndpoint(); // 阿里云主账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维，请登录 https://ram.console.aliy…