关闭

获取用户star的所有项目信息(支持分页和关键字检索)

标签: 项目
929人阅读 评论(0) 收藏 举报
分类:

之前做的一个项目,现在做个小结。

query 关键字 可选
type 项目所属类型检索条件 可选
sub_type 项目所属子类型检索条件 可选
language 编程语言检索条件 可选
tag 标签索引条件 可选
direction 排序顺序desc,asc,默认desc 可选
sort created默认(按star时间)updated(按项目更新时间)stars(按stars数量) 可选
page 页码,请求第几页数据(默认值:1) 可选
size 每页数量(默认值:30) 可选

1、controller层

@RestController
@RequestMapping(value = "/v0.1/user")
public class UserController {

    @Resource
    private ProjectStarRecordService projectStarRecordService;

    /**
     * 用户star项目列表
     *
     * @param direction
     * @param sort
     * @param page
     * @param size
     * @param userInfo  登录用户信息,直接从Headers中取得
     * @return
     */
    @RequestMapping(value = "/stars", method = RequestMethod.GET)
    public Object projectStaredByUser(@RequestParam(value = "query", defaultValue = "") String keyword,
                                      @RequestParam(value = "type", required = false) String type,
                                      @RequestParam(value = "sub_type", required = false) String subType,
                                      @RequestParam(value = "language", required = false) String language,
                                      @RequestParam(value = "tag", required = false) String tag,
                                      @RequestParam(value = "direction", defaultValue = "DESC") String direction,
                                      @RequestParam(value = "sort", defaultValue = "created") String sort,
                                      @RequestParam(value = "page", defaultValue = "1") int page,
                                      @RequestParam(value = "size", defaultValue = "30") int size,
                                      @AuthenticationPrincipal UserInfo userInfo) {


        // 判断用户是否存在
        if (null == userInfo) {
            throw new WafAuthenticationException("该用户不存在");
        }

        // 将sort转化成数据库对应的字段名称
        if (sort.equals("created")) {
            sort = "star_time";
        } else if (sort.equals("updated")) {
            sort = "last_activity_at";
        } else {
            sort = "stars";
        }

        return projectStarRecordService.getUserStarProject( keyword, type, subType, language, tag, direction, sort, page, size,userInfo);
    }
}
2、service层
public Object getUserStarProject(String keyword, String type, String subType, String language, String tag,
                                     String direction, String sort, int page, int size, UserInfo userInfo) {

        List<ProjectStarRecord> projectStarRecordList = findByUserId(userInfo.getUserId());
        if (null == projectStarRecordList || projectStarRecordList.isEmpty()) {
            return Collections.emptyList();
        }
        // 遍历star项目,得到项目ID放入集合中用于mongodb查询
        Collection<String> projectIdList = Collections2.transform(projectStarRecordList, new Function<ProjectStarRecord, String>() {
            @Override
            public String apply(ProjectStarRecord input) {
                return input.getProjectId();
            }
        });

        // 返回该用户star的所有项目信息,并且进行分页操作
        PageVo<ProjectInfo> pv = projectInfoService.findById(projectIdList, keyword, type, subType, language, tag, direction, sort, page, size);
        PageVo<Map> pageVo = formatUserStarProject(projectStarRecordList, pv);  //重新获得值

        return pageVo;
    }
private PageVo<Map> formatUserStarProject(List<ProjectStarRecord> projectStarRecordList, PageVo<ProjectInfo> pv) {
        List<ProjectInfo> items = pv.getItems();

        List<Map> resList = new ArrayList<>();
        for (ProjectInfo info : items) {
            Map<String, Object> map = new HashMap<>();

            map.put("name", info.getName());
            map.put("description", info.getDescription());
            map.put("last_activity_at", info.getLastActivityAt());
            map.put("id", info.getId());
//            map.put("star_time", new Date(0L));

            for (ProjectStarRecord record : projectStarRecordList) {
                if (record.getProjectId().equals(info.getId())) {
                    map.put("star_time", record.getStarTime());
                }
            }
            resList.add(map);
        }

        PageVo<Map> pageVo = new PageVo<>();
        pageVo.setItems(resList);
        pageVo.setTotalCount(pv.getTotalCount());
        pageVo.setTotalPage(pv.getTotalPage());
        pageVo.setPage(pv.getPage());
        pageVo.setSize(pv.getSize());

        return pageVo;
    }
/**
     * 获取用户star的项目的所有信息列表
     *
     * @param projectIds
     * @param direction
     * @param sort
     * @param page
     * @param size
     * @return
     */
    public PageVo<ProjectInfo> findById(Collection<String> projectIds, String keyword, String type, String subType, String language, String tag,
                                        String direction, String sort, int page, int size) {

        Map<String, List<String>> categories = new HashMap<>();
        appendCategory(categories, "type", type);
        appendCategory(categories, "sub_type", subType);
        appendCategory(categories, "language", language);
        appendCategory(categories, "tag", tag);
        List<ProjectInfo> projectInfoList = projectInfoRepository.search(projectIds, keyword, categories, direction, sort, page, size);

        // 分页结果
        long total = projectInfoRepository.count(keyword, categories, projectIds);
        PageVo<ProjectInfo> pageVo = new PageVo<>();
        pageVo.setItems(projectInfoList);
        pageVo.setTotalCount(total);
        pageVo.setTotalPage(size == 0 ? 1 : (int) Math.ceil((double) total / (double) size));
        pageVo.setPage(page);
        pageVo.setSize(size);

        return pageVo;
    }
3、repository层

/**
     * 关键字检索
     *
     * @param keyword    关键字
     * @param categories 维度map:key为维度值,value为类别值数组
     * @param direction  排序方式,ASC 升序, DESC 降序
     * @param sort       要排序的字段
     * @param page       当前页码
     * @param size       每页显示数据条数
     * @return
     */
    @Override
    public List<ProjectInfo> search(Collection<String> projectIds, String keyword, Map<String, List<String>> categories, String direction, String sort, int page, int size) {
        Query query = makeSearchQuery(keyword, categories, projectIds);
        // 排序规则
        query.with(new Sort(Sort.Direction.valueOf(direction.toUpperCase()), sort));
        query.with(new PageRequest(page - 1, size));

        return mongoTemplate.find(query, ProjectInfo.class);
    }

    @Override
    public long count(String keyword, Map<String, List<String>> categories, Collection<String> projectIds) {
        Query query = makeSearchQuery(keyword, categories, projectIds);
        return mongoTemplate.count(query, ProjectInfo.class);
    }

    private Query makeSearchQuery(String keyword, Map<String, List<String>> categories, Collection<String> projectIds) {
        Query query = new Query();
        Criteria c = new Criteria();

        if (StringUtils.isNotBlank(keyword)) {// 对name和description进行全文检索
//          TextCriteria tc = TextCriteria.forLanguage("hans");
//          query.addCriteria(tc.matchingAny(keyword));
            // 2.x mongodb 不知支持中文的全文检索,改用正则
            String regexp = String.format("%s", keyword);
            c.orOperator(Criteria.where("name").regex(regexp), Criteria.where("description").regex(regexp)).and("_id").in(projectIds);

        } else {
            query.addCriteria(Criteria.where("_id").in(projectIds));
        }

        c.and("delete_flag").is(false);

        // 维度下面的精确匹配
        String category = "categories.";
        if (null != categories) {
            for (Map.Entry<String, List<String>> entry : categories.entrySet()) {
                String dimension = entry.getKey();
                List<String> dimensionValues = entry.getValue();
                c.and(category + dimension).in(dimensionValues);
            }
        }

        query.addCriteria(c);
        return query;
    }
4、model层
public class PageVo<T> {
    // 总数
    private long totalCount;
    // 总页数
    private int totalPage;
    // 页码
    private int page;
    // 单页数量
    private int size;
    // 结果列表
    private List<T> items;

    public List<T> getItems() {
        return items;
    }

    public void setItems(List<T> items) {
        this.items = items;
    }

    public long getTotalCount() {
        return totalCount;
    }

    public void setTotalCount(long totalCount) {
        this.totalCount = totalCount;
    }

    public int getTotalPage() {
        return totalPage;
    }

    public void setTotalPage(int totalPage) {
        this.totalPage = totalPage;
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }
}
@Document(collection = "project_star_record")
public class ProjectStarRecord extends BaseEntity {

    @Indexed
    @Field("project_id")
    private String projectId;

    @Indexed
    @Field("user_id")
    private String userId;

    @Indexed
    @CreatedDate
    @Field("star_time")
    private Date starTime;

    public Date getStarTime() {
        return starTime;
    }

    public void setStarTime(Date starTime) {
        this.starTime = starTime;
    }

    public String getProjectId() {
        return projectId;
    }

    public void setProjectId(String projectId) {
        this.projectId = projectId;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }
}
@Document(collection = "project_info")
public class ProjectInfo extends BaseEntity {
    @TextIndexed(weight = 3)
    private String name;

    @TextIndexed(weight = 2)
    private String description;

    @Field("nick_name")
    private String nickName;
    @Field("is_available")
    private boolean isAvailable = true;
    @Field("is_public")
    private boolean isPublic;
    @Field("create_at")
    private Date createAt;
    @Field("last_activity_at")
    private Date lastActivityAt;
    @Field("web_url")
    private String webUrl;
    @Field("repo_url")
    private String repoUrl;
    @Field("avatar_url")
    private String avatarUrl;
    private User owner;
    @Indexed
    private long stars;
    private Map<String, Collection<String>> categories;
    private Collection<ProjectMember> members;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public boolean getIsAvailable() {
        return isAvailable;
    }

    public void setIsAvailable(boolean available) {
        isAvailable = available;
    }

    public boolean getIsPublic() {
        return isPublic;
    }

    public void setIsPublic(boolean aPublic) {
        isPublic = aPublic;
    }

    public Date getCreateAt() {
        return createAt;
    }

    public void setCreateAt(Date createAt) {
        this.createAt = createAt;
    }

    public Date getLastActivityAt() {
        return lastActivityAt;
    }

    public void setLastActivityAt(Date lastActivityAt) {
        this.lastActivityAt = lastActivityAt;
    }

    public String getWebUrl() {
        return webUrl;
    }

    public void setWebUrl(String webUrl) {
        this.webUrl = webUrl;
    }

    public String getRepoUrl() {
        return repoUrl;
    }

    public void setRepoUrl(String repoUrl) {
        this.repoUrl = repoUrl;
    }

    public String getAvatarUrl() {
        return avatarUrl;
    }

    public void setAvatarUrl(String avatarUrl) {
        this.avatarUrl = avatarUrl;
    }

    public Map<String, Collection<String>> getCategories() {
        return categories;
    }

    public void setCategories(Map<String, Collection<String>> categories) {
        this.categories = categories;
    }

    public User getOwner() {
        return owner;
    }

    public void setOwner(User owner) {
        this.owner = owner;
    }

    public long getStars() {
        return stars;
    }

    public void setStars(long stars) {
        this.stars = stars;
    }

    public Collection<ProjectMember> getMembers() {
        return members;
    }

    public void setMembers(Collection<ProjectMember> members) {
        this.members = members;
    }


    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }
}

主要涉及到的表:

项目基本信息(project_info)

{
    "id":"",//主键
    "name":"", //名称
    "description":"",//描述
    "is_available":false,//是否可用
    "is_public":false, //是否公开
    "create_at":"", //项目创建时间
    "last_activity_at":"", //最后一次更新时间
    "is_starred_by_current_user":false,
    "owner":{ //拥有者
        "id":"", //拥有者id,uc的user_id
        "name":"", //拥有者的名字
        "user_name":"" //拥有者的工号
    },
    "stars" : NumberLong(0),
    "web_url":"", //项目首页地址,预留
    "repo_url":"", //仓库地址,gitlab or svn
    "avatar_url":"", //项目logo
    "categories":{ //项目所属类别
        "language":[], //编程语言
        "type":[], //项目所属类别 web or 组件
        "sub_type":[], //项目所属子类别 web应用 移动应用 web组件 ios组件 android组件
        "tag":[] //项目标签
    },
    "members":[ //项目成员
        {
            "id":"", //拥有者id,uc的user_id
            "name":"", //项目成员姓名
            "user_name":"", //项目成员工号
            "role":"" //项目成员角色,如:主程,开发者,策划,测试
        }
    ]
}
维度(dimension)
{
    "id":"",//主键
    "value":"language", //维度值:type/sub_type/tag/language
    "text":"编程语言" //维度显示文本
}
项目被star记录(project_star_record)
{
    "id":"", //主键
    "project_id":"", //关联project_info的id
    "user_id":"", //用户id
    "star_time":"", // 项目被star的时间
}

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:177950次
    • 积分:2962
    • 等级:
    • 排名:第12452名
    • 原创:137篇
    • 转载:34篇
    • 译文:0篇
    • 评论:25条
    最新评论