您的位置:首页 > 其它

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

2016-08-28 21:32 381 查看
之前做的一个项目,现在做个小结。

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的时间
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: