TH7-搜附近

news2024/11/9 4:44:02

TH7-搜附近

    • 说明
    • 1、探花
      • 1.1、查询推荐列表dubbo服务
        • 1.1.1、实体对象
        • 1.1.2、定义接口
        • 1.1.3、编写实现
        • 1.1.4、单元测试
      • 1.2、查询推荐列表APP接口实现
        • 1.2.1、TanHuaController
        • 1.2.2、TanHuaService
        • 1.2.3、测试
      • 1.3、喜欢的dubbo服务
        • 1.3.1、定义接口
        • 1.3.2、编写实现
      • 1.4、左滑右滑
        • 1.4.1、TanHuaController
        • 1.4.2、TanHuaService
        • 1.4.3、测试
    • 2、MongoDB地理位置检索
      • 2.1、地理位置索引
          • 2d :
          • 2dsphere:
        • Point
        • LineString
        • Polygon
      • 2.2、案例
        • 查询附近
        • 查询并获取距离
    • 3、上报地理位置
      • 3.1、dubbo服务
        • 3.1.1、定义pojo
        • 3.1.2、定义dubbo接口
        • 3.1.3、编写实现
        • 3.1.4、单元测试
      • 3.2、APP接口
        • 3.2.1、BaiduController
        • 3.2.2、BaiduService
      • 3.3、测试
    • 4、搜附近
      • 4.1、dubbo服务
        • 4.1.1、定义接口方法
        • 4.1.2、编写实现
      • 4.2、APP接口服务
        • 4.2.1、NearUserVo
        • 4.2.2、TanHuaController
        • 4.2.3、TanHuaService
        • 4.2.4、测试

说明

  • 实现探花功能
  • MongoDB geo
  • 搜附近
    • 上报地理位置
    • 搜附近

1、探花

探花功能是将推荐的好友随机的通过卡片的形式展现出来,用户可以选择左滑、右滑操作,左滑:“不喜欢”,右滑:“喜欢”。

喜欢:如果双方喜欢,那么就会成为好友。

在这里插入图片描述

如果已经喜欢或不喜欢的用户在列表中不再显示。

1.1、查询推荐列表dubbo服务

1.1.1、实体对象

package com.tanhua.dubbo.server.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "user_like")
public class UserLike implements java.io.Serializable {

    private static final long serialVersionUID = 6739966698394686523L;

    private ObjectId id;
    @Indexed
    private Long userId; //用户id,自己
    @Indexed
    private Long likeUserId; //喜欢的用户id,对方
    private Boolean isLike; // 是否喜欢
    private Long created; //创建时间
    private Long updated; // 更新时间

}

1.1.2、定义接口

RecommendUserApi

    /**
     * 查询探花列表,查询时需要排除喜欢和不喜欢的用户
     */
    List<RecommendUser> queryCardsList(Long userId, int count);

1.1.3、编写实现

RecommendUserApiImpl

   /**
     * 查询探花列表,查询时需要排除喜欢和不喜欢的用户
     * 1、排除喜欢,不喜欢的用户
     * 2、随机展示
     * 3、指定数量
     */
    public List<RecommendUser> queryCardsList(Long userId, int counts) {
        //1、查询喜欢不喜欢的用户ID
        List<UserLike> likeList = mongoTemplate.find(Query.query(Criteria.where("userId").is(userId)), UserLike.class);
        List<Long> likeUserIdS = CollUtil.getFieldValues(likeList, "likeUserId", Long.class);
        //2、构造查询推荐用户的条件
        Criteria criteria = Criteria.where("toUserId").is(userId).and("userId").nin(likeUserIdS);
        //3、使用统计函数,随机获取推荐的用户列表
        TypedAggregation<RecommendUser> newAggregation = TypedAggregation.newAggregation(RecommendUser.class,
                Aggregation.match(criteria),//指定查询条件
                Aggregation.sample(counts)
        );
        AggregationResults<RecommendUser> results = mongoTemplate.aggregate(newAggregation, RecommendUser.class);
        //4、构造返回
        return results.getMappedResults();
    }

1.1.4、单元测试

//com.tanhua.dubbo.server.api.TestRecommendUserApi

@Test
public void testQueryCardList(){
    this.recommendUserApi.queryCardsList(106l, 10)
            .forEach(recommendUser -> System.out.println(recommendUser));
}

1.2、查询推荐列表APP接口实现

接口文档:https://mock-java.itheima.net/project/35/interface/api/593

1.2.1、TanHuaController

	/**
     * 探花-推荐用户列表
     */
    @GetMapping("/cards")
    public ResponseEntity queryCardsList() {
        List<TodayBest> list = this.tanhuaService.queryCardsList();
        return ResponseEntity.ok(list);
    }

1.2.2、TanHuaService

#默认推荐列表
tanhua:
  default:
    recommend:
      users: 2,3,8,10,18,20,24,29,27,32,36,37,56,64,75,88
    @Value("${tanhua.default.recommend.users}")
    private String recommendUser;

	    //探花-推荐用户列表
    public List<TodayBest> queryCardsList() {
        //1、调用推荐API查询数据列表(排除喜欢/不喜欢的用户,数量限制)
        List<RecommendUser> users = recommendUserApi.queryCardsList(UserHolder.getUserId(),10);
        //2、判断数据是否存在,如果不存在,构造默认数据 1,2,3
        if(CollUtil.isEmpty(users)) {
            users = new ArrayList<>();
            String[] userIdS = recommendUser.split(",");
            for (String userId : userIdS) {
                RecommendUser recommendUser = new RecommendUser();
                recommendUser.setUserId(Convert.toLong(userId));
                recommendUser.setToUserId(UserHolder.getUserId());
                recommendUser.setScore(RandomUtil.randomDouble(60, 90));
                users.add(recommendUser);
            }
        }
        //3、构造VO
        List<Long> ids = CollUtil.getFieldValues(users, "userId", Long.class);
        Map<Long, UserInfo> infoMap = userInfoApi.findByIds(ids, null);

        List<TodayBest> vos = new ArrayList<>();
        for (RecommendUser user : users) {
            UserInfo userInfo = infoMap.get(user.getUserId());
            if(userInfo != null) {
                TodayBest vo = TodayBest.init(userInfo, user);
                vos.add(vo);
            }
        }
        return vos;
    }

1.2.3、测试

在这里插入图片描述在这里插入图片描述

效果:

在这里插入图片描述

1.3、喜欢的dubbo服务

用户的喜欢与不喜欢列表需要保存在redis中,为了防止redis中的数据丢失,同时需要将数据保存到mongodb进行持久化保存。

1.3.1、定义接口

package com.tanhua.dubbo.api;

public interface UserLikeApi {

    //保存或者更新
    Boolean saveOrUpdate(Long userId, Long likeUserId, boolean isLike);
}

1.3.2、编写实现

@DubboService
public class UserLikeApiImpl implements UserLikeApi{

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public Boolean saveOrUpdate(Long userId, Long likeUserId, boolean isLike) {
        try {
            //1、查询数据
            Query query = Query.query(Criteria.where("userId").is(userId).and("likeUserId").is(likeUserId));
            UserLike userLike = mongoTemplate.findOne(query, UserLike.class);
            //2、如果不存在,保存
            if(userLike == null) {
                userLike = new UserLike();
                userLike.setUserId(userId);
                userLike.setLikeUserId(likeUserId);
                userLike.setCreated(System.currentTimeMillis());
                userLike.setUpdated(System.currentTimeMillis());
                userLike.setIsLike(isLike);
                mongoTemplate.save(userLike);
            }else {
                //3、更新
                Update update = Update.update("isLike", isLike)
                        .set("updated",System.currentTimeMillis());
                mongoTemplate.updateFirst(query,update,UserLike.class);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}

1.4、左滑右滑

左滑:“不喜欢”,右滑:“喜欢”,如果双方喜欢,那么就会成为好友。

1.4.1、TanHuaController

/**
 * 喜欢
 */
@GetMapping("{id}/love")
public ResponseEntity<Void> likeUser(@PathVariable("id") Long likeUserId) {
        this.tanhuaService.likeUser(likeUserId);
        return ResponseEntity.ok(null);
}

/**
 * 不喜欢
 */
@GetMapping("{id}/unlove")
public ResponseEntity<Void> notLikeUser(@PathVariable("id") Long likeUserId) {
        this.tanhuaService.notLikeUser(likeUserId);
        return ResponseEntity.ok(null);
}

1.4.2、TanHuaService

    @Autowired
    private MessagesService messagesService;

    //探花喜欢 106 -  2
    public void likeUser(Long likeUserId) {
        //1、调用API,保存喜欢数据(保存到MongoDB中)
        Boolean save = userLikeApi.saveOrUpdate(UserHolder.getUserId(),likeUserId,true);
        if(!save) {
            //失败
            throw new BusinessException(ErrorResult.error());
        }
        //2、操作redis,写入喜欢的数据,删除不喜欢的数据 (喜欢的集合,不喜欢的集合)
        redisTemplate.opsForSet().remove(Constants.USER_NOT_LIKE_KEY+UserHolder.getUserId(),likeUserId.toString());
        redisTemplate.opsForSet().add(Constants.USER_LIKE_KEY+UserHolder.getUserId(),likeUserId.toString());
        //3、判断是否双向喜欢
        if(isLike(likeUserId,UserHolder.getUserId())) {
            //4、添加好友
            messagesService.contacts(likeUserId);
        }
    }

    public Boolean isLike(Long userId,Long likeUserId) {
        String key = Constants.USER_LIKE_KEY+userId;
        return redisTemplate.opsForSet().isMember(key,likeUserId.toString());
    }

    //不喜欢
    public void notLikeUser(Long likeUserId) {
        //1、调用API,保存喜欢数据(保存到MongoDB中)
        Boolean save = userLikeApi.saveOrUpdate(UserHolder.getUserId(),likeUserId,false);
        if(!save) {
            //失败
            throw new BusinessException(ErrorResult.error());
        }
        //2、操作redis,写入喜欢的数据,删除不喜欢的数据 (喜欢的集合,不喜欢的集合)
        redisTemplate.opsForSet().add(Constants.USER_NOT_LIKE_KEY+UserHolder.getUserId(),likeUserId.toString());
        redisTemplate.opsForSet().remove(Constants.USER_LIKE_KEY+UserHolder.getUserId(),likeUserId.toString());
        //3、判断是否双向喜欢,删除好友(各位自行实现)
    }

1.4.3、测试

在这里插入图片描述
在这里插入图片描述

user_like表,可以看到已经相互喜欢了:

在这里插入图片描述

tanhua_users表,可以看到相互是好友了:

在这里插入图片描述

环信平台:

在这里插入图片描述

2、MongoDB地理位置检索

MongoDB 支持对地理空间数据的查询操作。

2.1、地理位置索引

地理位置查询,必须创建索引才可以能查询,目前有两种索引。

2d :

使用2d index 能够将数据作为二维平面上的点存储起来,在MongoDB 2.4以前使用2。

2dsphere:

2dsphere索引支持查询在一个类地球的球面上进行几何计算,以GeoJSON对象或者普通坐标对的方式存储数据。

MongoDB内部支持多种GeoJson对象类型:

Point

最基础的坐标点,指定纬度和经度坐标,首先列出经度,然后列出 纬度

  • 有效的经度值介于-180和之间180,两者都包括在内。
  • 有效的纬度值介于-90和之间90,两者都包括在内。
{ type: "Point", coordinates: [ 40, 5 ] }

LineString

{ type: "LineString", coordinates: [ [ 40, 5 ], [ 41, 6 ] ] }

Polygon

{
  type: "Polygon",
  coordinates: [ [ [ 0 , 0 ] , [ 3 , 6 ] , [ 6 , 1 ] , [ 0 , 0  ] ] ]
}

2.2、案例

查询附近并按照距离返回

查询附近

查询当前坐标附近的目标

@Test
public void testNear() {
    //构造坐标点
    GeoJsonPoint point = new GeoJsonPoint(116.404, 39.915);
    //构造半径
    Distance distanceObj = new Distance(1, Metrics.KILOMETERS);
    //画了一个圆圈
    Circle circle = new Circle(point, distanceObj);
    //构造query对象
    Query query = Query.query(Criteria.where("location").withinSphere(circle));
    //省略其他内容
    List<Places> list = mongoTemplate.find(query, Places.class);
    list.forEach(System.out::println);
}

查询并获取距离

我们假设需要以当前坐标为原点,查询附近指定范围内的餐厅,并直接显示距离

//查询附近且获取间距
@Test
public void testNear1() {
    //1、构造中心点(圆点)
    GeoJsonPoint point = new GeoJsonPoint(116.404, 39.915);
    //2、构建NearQuery对象
    NearQuery query = NearQuery.near(point, Metrics.KILOMETERS).maxDistance(1, Metrics.KILOMETERS);
    //3、调用mongoTemplate的geoNear方法查询
    GeoResults<Places> results = mongoTemplate.geoNear(query, Places.class);
    //4、解析GeoResult对象,获取距离和数据
    for (GeoResult<Places> result : results) {
        Places places = result.getContent();
        double value = result.getDistance().getValue();
        System.out.println(places+"---距离:"+value + "km");
    }
}

3、上报地理位置

当客户端检测用户的地理位置,当变化大于500米时或每隔5分钟,向服务端上报地理位置。

用户的地理位置存储到MongoDB中,如下:

在这里插入图片描述

3.1、dubbo服务

3.1.1、定义pojo

在my-tanhua-dubbo-interface中创建:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "user_location")
@CompoundIndex(name = "location_index", def = "{'location': '2dsphere'}")
public class UserLocation implements java.io.Serializable{

    private static final long serialVersionUID = 4508868382007529970L;

    @Id
    private ObjectId id;
    @Indexed
    private Long userId; //用户id
    private GeoJsonPoint location; //x:经度 y:纬度
    private String address; //位置描述
    private Long created; //创建时间
    private Long updated; //更新时间
    private Long lastUpdated; //上次更新时间
}

3.1.2、定义dubbo接口

在my-tanhua-dubbo-interface工程中。

package com.tanhua.dubbo.server.api;

public interface UserLocationApi {

    //更新地理位置
    Boolean updateLocation(Long userId, Double longitude, Double latitude, String address);
}

3.1.3、编写实现

@DubboService
public class UserLocationApiImpl implements UserLocationApi{

    @Autowired
    private MongoTemplate mongoTemplate;

    //更新地理位置
    public Boolean updateLocation(Long userId, Double longitude, Double latitude, String address) {
        try {
            //1、根据用户id查询位置信息
            Query query = Query.query(Criteria.where("userId").is(userId));
            UserLocation location = mongoTemplate.findOne(query, UserLocation.class);
            if(location == null) {
                //2、如果不存在用户位置信息,保存
                location = new UserLocation();
                location.setUserId(userId);
                location.setAddress(address);
                location.setCreated(System.currentTimeMillis());
                location.setUpdated(System.currentTimeMillis());
                location.setLastUpdated(System.currentTimeMillis());
                location.setLocation(new GeoJsonPoint(longitude,latitude));
                mongoTemplate.save(location);
            }else {
                //3、如果存在,更新
                Update update = Update.update("location", new GeoJsonPoint(longitude, latitude))
                        .set("updated", System.currentTimeMillis())
                        .set("lastUpdated", location.getUpdated());
                mongoTemplate.updateFirst(query,update,UserLocation.class);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}

3.1.4、单元测试

地理位置坐标拾取:http://api.map.baidu.com/lbsapi/getpoint/index.html

@RunWith(SpringRunner.class)
@SpringBootTest(classes = AppServerApplication.class)
public class TestUserLocationApi {

    @DubboReference
    private UserLocationApi userLocationApi;

    @Test
    public void testUpdateUserLocation() {
        this.userLocationApi.updateLocation(1L, 116.353885,40.065911, "育新地铁站");
        this.userLocationApi.updateLocation(2L, 116.352115,40.067441, "北京石油管理干部学院");
        this.userLocationApi.updateLocation(3L, 116.336438,40.072505, "回龙观医院");
        this.userLocationApi.updateLocation(4L, 116.396797,40.025231, "奥林匹克森林公园");
        this.userLocationApi.updateLocation(5L, 116.323849,40.053723, "小米科技园");
        this.userLocationApi.updateLocation(6L, 116.403963,39.915119, "天安门");
        this.userLocationApi.updateLocation(7L, 116.328103,39.900835, "北京西站");
        this.userLocationApi.updateLocation(8L, 116.609564,40.083812, "北京首都国际机场");
        this.userLocationApi.updateLocation(9L, 116.459958,39.937193, "德云社(三里屯店)");
        this.userLocationApi.updateLocation(10L, 116.333374,40.009645, "清华大学");
        this.userLocationApi.updateLocation(41L, 116.316833,39.998877, "北京大学");
        this.userLocationApi.updateLocation(42L, 117.180115,39.116464, "天津大学(卫津路校区)");
    }
}

3.2、APP接口

接口文档:https://mock-java.itheima.net/project/35/interface/api/557

3.2.1、BaiduController

@RestController
@RequestMapping("/baidu")
public class BaiduController {

    @Autowired
    private BaiduService baiduService;

    /**
     * 更新位置
     */
    @PostMapping("/location")
    public ResponseEntity updateLocation(@RequestBody Map param) {
        Double longitude = Double.valueOf(param.get("longitude").toString());
        Double latitude = Double.valueOf(param.get("latitude").toString());
        String address = param.get("addrStr").toString();
        this.baiduService.updateLocation(longitude, latitude,address);
        return ResponseEntity.ok(null);
    }
}

3.2.2、BaiduService

@Service
public class BaiduService {

    @DubboReference
    private UserLocationApi userLocationApi;

    //更新地理位置
    public void updateLocation(Double longitude, Double latitude, String address) {
        Boolean flag = userLocationApi.updateLocation(UserHolder.getUserId(),longitude,latitude,address);
        if(!flag) {
            throw  new BusinessException(ErrorResult.error());
        }
    }
}

3.3、测试

在这里插入图片描述

4、搜附近

在首页中点击“搜附近”可以搜索附近的好友,效果如下:

在这里插入图片描述

实现思路:根据当前用户的位置,查询附近范围内的用户。范围是可以设置的。

4.1、dubbo服务

4.1.1、定义接口方法

UserLocationApi

    /**
     * 根据位置搜索附近人的所有ID
     */
    List<Long> queryNearUser(Long userId, Double metre);

4.1.2、编写实现

UserLocationApiImpl

    @Override
    public List<Long> queryNearUser(Long userId, Double metre) {
        //1、根据用户id,查询用户的位置信息
        Query query = Query.query(Criteria.where("userId").is(userId));
        UserLocation location = mongoTemplate.findOne(query, UserLocation.class);
        if(location == null) {
            return null;
        }
        //2、已当前用户位置绘制原点
        GeoJsonPoint point = location.getLocation();
        //3、绘制半径
        Distance distance = new Distance(metre / 1000, Metrics.KILOMETERS);
        //4、绘制圆形
        Circle circle = new Circle(point, distance);
        //5、查询
        Query locationQuery = Query.query(Criteria.where("location").withinSphere(circle));
        List<UserLocation> list = mongoTemplate.find(locationQuery, UserLocation.class);
        return CollUtil.getFieldValues(list,"userId",Long.class);
    }

4.2、APP接口服务

4.2.1、NearUserVo

//附近的人vo对象
@Data
@NoArgsConstructor
@AllArgsConstructor
public class NearUserVo {

    private Long userId;
    private String avatar;
    private String nickname;

    public static NearUserVo init(UserInfo userInfo) {
        NearUserVo vo = new NearUserVo();
        vo.setUserId(userInfo.getId());
        vo.setAvatar(userInfo.getAvatar());
        vo.setNickname(userInfo.getNickname());
        return vo;
    }
}

4.2.2、TanHuaController

    /**
     * 搜附近
     */
    @GetMapping("/search")
    public ResponseEntity<List<NearUserVo>> queryNearUser(String gender,
                                                          @RequestParam(defaultValue = "2000") String distance) {
        List<NearUserVo> list = this.tanhuaService.queryNearUser(gender, distance);
        return ResponseEntity.ok(list);
    }

4.2.3、TanHuaService

    //搜附近
    public List<NearUserVo> queryNearUser(String gender, String distance) {
        //1、调用API查询附近的用户(返回的是附近的人的所有用户id,包含当前用户的id)
        List<Long> userIds = userLocationApi.queryNearUser(UserHolder.getUserId(),Double.valueOf(distance));
        //2、判断集合是否为空
        if(CollUtil.isEmpty(userIds)) {
            return new ArrayList<>();
        }
        //3、调用UserInfoApi根据用户id查询用户详情
        UserInfo userInfo = new UserInfo();
        userInfo.setGender(gender);
        Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, userInfo);
        //4、构造返回值。
        List<NearUserVo> vos = new ArrayList<>();
        for (Long userId : userIds) {
            //排除当前用户
            if(userId == UserHolder.getUserId()) {
                continue;
            }
            UserInfo info = map.get(userId);
            if(info != null) {
                NearUserVo vo = NearUserVo.init(info);
                vos.add(vo);
            }
        }
        return vos;
    }

4.2.4、测试

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/73957.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

fofa搜索漏洞技巧

fofa搜索漏洞技巧整理,主要有以下十个方面:搜索HTTP响应头中含有"thinkphp"关键词的网站和IP;加上标题带有后台的;加上时间,现在新网站有thinkphp日志泄露的有很多; 搜索html正文中含有"管理后台"关键词的网站和IP body="管理后台"等。 …

Linux内核缓存

【推荐阅读】 轻松学会linux下查看内存频率,内核函数,cpu频率 纯干货&#xff0c;linux内存管理——内存管理架构&#xff08;建议收藏&#xff09; 一篇长文叙述Linux内核虚拟地址空间的基本概括 页缓存和块缓存 内核为块设备提供了两种通用的缓存方案&#xff1a; 页缓存&a…

光华股份深交所上市:市值51亿 应收账款余额超5亿

雷递网 雷建平 12月8日浙江光华科技股份有限公司&#xff08;简称&#xff1a;“光华股份”&#xff0c;证券代码&#xff1a;001333&#xff09;今日在深交所主板上市。光华股份本次发行3200万股&#xff0c;发行价为27.76元&#xff0c;募资8.88亿元。光华股份开盘价为33.31元…

开源,是不道德的!

原创&#xff1a;小姐姐味道&#xff08;微信公众号ID&#xff1a;xjjdog&#xff09;&#xff0c;欢迎分享&#xff0c;非公众号转载保留此声明。请删掉你的github开源代码&#xff0c;让CV工程师成为真正的工程师。不要做真正的代码分享&#xff0c;因为除了满足一下你的虚荣…

vue-cli中学习vue

vue部分知识 大部分学习内容及代码在gitee仓库 生命周期 基本介绍 生命周期描述beforeCreate组件实例被创建之初created组件实例已经完全创建beforeMount组件挂载之前mounted组件挂载到实例上去之后beforeUpdate组件数据发生变化&#xff0c;更新之前updated组件数据更新之后…

springboot知识点

基本介绍 微服务最早由Martin Fowler与James Lewis于2014年共同提出&#xff0c;微服务架构风格是一种使用一套小服务来开发单个应用的方式途径&#xff0c;每个服务运行在自己的进程中&#xff0c;并使用轻量级机制通信&#xff0c;通常是HTTP API&#xff0c;这些服务基于业…

TH8-小视频方案

TH8-小视频方案说明1、我的访客1.1、dubbo服务1.1.1、实体对象1.1.2、定义接口1.1.3、编写实现1.2、记录访客数据1.3、首页谁看过我1.3.1、VO对象1.3.2、MovementController1.3.3、MovementService2、小视频功能说明3、FastDFS2.1、FastDFS是什么&#xff1f;2.2、工作原理2.1.…

会员消费占比高达96%,孩子王究竟是怎么做到的?

&#x1f446;点击关注公众号&#x1f446;1.孩子王&#xff1a;依靠会员“稳江山”2021年上半年&#xff0c;增长黑盒独家发布了一篇关于孩子王的研究文章《万字拆解孩子王&#xff1a;充满矛盾的母婴零售之王》&#xff0c;彼时&#xff0c;孩子王尚在二度上市的前夕等待敲钟…

JAVA SCRIPT设计模式--行为型--设计模式之Template Method模板方法(22)

JAVA SCRIPT设计模式是本人根据GOF的设计模式写的博客记录。使用JAVA SCRIPT语言来实现主体功能&#xff0c;所以不可能像C&#xff0c;JAVA等面向对象语言一样严谨&#xff0c;大部分程序都附上了JAVA SCRIPT代码&#xff0c;代码只是实现了设计模式的主体功能&#xff0c;不代…

2023最新SSM计算机毕业设计选题大全(附源码+LW)之java课程教学过程f6oz5

对于即将毕业或者即将做课设的同学而言&#xff0c;由于经验的欠缺&#xff0c;面临的第一个难题就是选题&#xff0c;确定好题目之后便是开题报告&#xff0c;如果选题首先看自己学习那些技术&#xff0c;不同技术适合做不同的产品&#xff0c;比如自己会些简单的Java语言&…

BSV 上的 Graftroot

我们已经演示了如何使用无合约的合约在 BSV 上实现 Taproot。我们将展示了其后续提案 Graftroot 可以以类似的方式实施。 BTC 中的 Grabroot 与 Taproot 类似&#xff0c;有两种方式可以使用锁定在由多方创建的聚合公钥 P 中的资金&#xff1a; 合作案例&#xff1a;又名默认…

kubernetes 安装 Harbor 仓库

文章目录kubernetes 安装 Harbor 仓库1. 下载 Harbor2. 安装 docker3. 优化 docker 配置4. 下载 docker-compose5. 安装 Harbor:one: 上传 harbor 文件包:two: 解压:three: 修改配置文件:four: 执行安装脚本安装:five: 配置开机自启6. 登陆测试:one: 浏览器登陆:two: 命令行登陆…

为什么需要对相机标定?

以下内容来自系统教程如何搞定单目/鱼眼/双目/阵列 相机标定&#xff1f; 点击领取相机标定资料和代码 为什么需要对相机标定&#xff1f; 我们所处的世界是三维的&#xff0c;而相机拍摄的照片却是二维的&#xff0c;丢失了其中距离/深度的信息。从数学上可以简单理解为&…

Peppol网络对接流程

Peppol 代表泛欧在线公共采购&#xff0c;现在连接到 Peppol 的组织可以通过高度安全的国际网络交换商业文件。知行软件通过了 PEPPOL 的 AS2 及 AS4 测试&#xff0c;被 OpenPEPPOL AISBL 正式认证为 PEPPOL 接入点供应商。可以在Peppol查询到相关接入点信息&#xff0c;如下&…

TH9-搭建后台系统

TH9-搭建后台系统1、项目架构1.1 概述1.2 API网关1.2.1 搭建网关依赖引导类跨域问题配置类配置文件1.2.2 配置鉴权管理器1.3 Nacos配置中心1.3.1 添加依赖1.3.2 添加bootstrap.yml配置1.3.3 nacos添加配置2、后台系统2.1 概述2.2 环境前端搭建2.2.1 导入数据库2.2.2 导入静态页…

MYSQL-INNODB索引构成详解

作者&#xff1a;郑啟龙 摘要&#xff1a; 对于MYSQL的INNODB存储引擎的索引&#xff0c;大家是不陌生的&#xff0c;都能想到是 B树结构&#xff0c;可以加速SQL查询。但对于B树索引&#xff0c;它到底“长”得什么样子&#xff0c;它具体如何由一个个字节构成的&#xff0c…

插入排序

目录 插入排序 思路: 原理视频: 代码: 时间复杂度: 总结: 题目链接: 插入排序 题目描述&#xff1a; 插入排序基本思想是每一步将一个待排序的记录&#xff0c;插入到前面已经排好序的有序序列中去&#xff0c;直到插完所有元素为止。 输入N个整数&#xff0c;将它们从…

【设计模式】代理模式(Proxy Pattern)

代理模式属于结构型模式&#xff0c;当一个对象不处于相同内存空间时、创建开销大时、需要进行安全控制时或需要代理处理一些其他事物时可以使用代理模式。代理模式通过为另一个类提供一个替身类来控制对这个类的对象的访问。 文章目录代理模式的介绍代理的分类&#xff1a;优点…

了解CloudCompare软件

CloudCompare是一款基于GPL开源协议的3D点云处理软件&#xff0c; 打开一个点云&#xff1b; 按住鼠标拖动旋转会出现坐标轴&#xff1b; 如果选中 TLS/GBL&#xff0c; 会出来右边这个线框&#xff0c;可以一起旋转&#xff1b;查了一下&#xff0c;TLS/GBL似乎是地面激光雷达…

2022年国际工程行业研究报告

第一章 行业概况 国际工程是指一个工程项目从咨询、投资、招投标、承包(包括分包)、设备采购、培训到监理各个阶段的参与者来自不止一个国家&#xff0c;并且按照国际工程项目管理模式进行管理的工程。国际工程是一种综合性的国际经济合作方式&#xff0c;是国际技术贸易的一种…