Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 初版随机小作文 #32

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
392 changes: 204 additions & 188 deletions src/main/java/asia/asoulcnki/api/common/duplicationcheck/LeaderBoard.java

Large diffs are not rendered by default.

29 changes: 29 additions & 0 deletions src/main/java/asia/asoulcnki/api/common/util/RandomUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package asia.asoulcnki.api.common.util;

import java.util.*;

public class RandomUtil {
public static <T> T choice(List<T> list) {
Random random = new Random();
int n = random.nextInt(list.size());
return list.get(n);
}

public static <T> List<T> sample(List<T> list, int num) {
if (list.size() < num) {
return list;
}
Random random = new Random();
Map<Integer, T> map = new HashMap<>();
while (map.size() < num) {
int n = random.nextInt(list.size());
if (!map.containsKey(n)) {
T data = list.get(n);
map.put(n, data);
}
}
List<T> ret = new ArrayList<>(map.values());
Collections.shuffle(ret);
return ret;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package asia.asoulcnki.api.controller;

import asia.asoulcnki.api.common.response.ApiResult;
import asia.asoulcnki.api.persistence.entity.Reply;
import asia.asoulcnki.api.persistence.param.QueryRandomLoveLetterParam;
import asia.asoulcnki.api.service.ILoveLetterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@Validated
public class LoveLetterController {
@Autowired
private ILoveLetterService loveLetterService;

@GetMapping("/loveletter/random")
@ResponseBody
public ApiResult<List<Reply>> queryLoveLetter(QueryRandomLoveLetterParam param) {
return ApiResult.ok(loveLetterService.queryLoveLetter(param));
}

}
22 changes: 22 additions & 0 deletions src/main/java/asia/asoulcnki/api/enums/ASoulRoleEnum.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package asia.asoulcnki.api.enums;

import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum ASoulRoleEnum {
AVA(0, "向晚"),
BELLA(1, "贝拉"),
CAROL(2, "珈乐"),
DIANA(3, "嘉然"),
EILEEN(4, "乃琳");
Comment on lines +10 to +15
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

前端传枚举的方式是否要修改成传UID?目前 ranking 接口前端是传的 uid数组

可以参考 ranking 的 uid 的 filter?

https://github.com/ASoulCnki/ASoulCnkiBackend/blob/master/src/main/java/asia/asoulcnki/api/common/duplicationcheck/filters/UserIdInFilter.java

Copy link
Member

@ch3cknull ch3cknull Aug 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

目前ranking接口是这样传值的,或许可以参考一下?

GET /v1/api/ranking/?pageSize=10&pageNum=1&timeRangeMode=1&sortMode=0&ids=672346917,672353429&keywords=关键词1,关键词2

上述参数都要经过encodeURIComponent做编码

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

传枚举的方式应该都行啦,我个人比较喜欢传具体的内容,这样比较明确,如果前端有需要的话我可以改一下改为传枚举值捏


@EnumValue
private int code;

@JsonValue
private String name;
}
132 changes: 93 additions & 39 deletions src/main/java/asia/asoulcnki/api/persistence/entity/Reply.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package asia.asoulcnki.api.persistence.entity;

import asia.asoulcnki.api.enums.ASoulRoleEnum;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonProperty;
Expand All @@ -8,59 +9,112 @@
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.util.Arrays;
import java.util.List;

@Data
@EqualsAndHashCode(callSuper = false)
@ToString
public class Reply implements Serializable {
private static final long serialVersionUID = 6554064566476229771L;
private static final long serialVersionUID = 6554064566476229771L;

@TableId(value = "rpid")
@JsonProperty("rpid")
@JsonSerialize(using = ToStringSerializer.class)
private Long rpid;
@TableId(value = "rpid")
@JsonProperty("rpid")
@JsonSerialize(using = ToStringSerializer.class)
private Long rpid;

@JsonProperty("type_id")
private int typeId;
@JsonProperty("type_id")
private int typeId;

@JsonProperty("dynamic_id")
@JsonSerialize(using = ToStringSerializer.class)
private long dynamicId;
@JsonProperty("dynamic_id")
@JsonSerialize(using = ToStringSerializer.class)
private long dynamicId;

@JsonProperty("mid")
private int mid;
@JsonProperty("mid")
private int mid;

@JsonProperty("uid")
private int uid;

@JsonProperty("oid")
@JsonSerialize(using = ToStringSerializer.class)
private long oid;
@JsonProperty("oid")
@JsonSerialize(using = ToStringSerializer.class)
private long oid;

@JsonProperty("ctime")
private int ctime;

@JsonProperty("m_name")
private String mName;

@JsonProperty("content")
private String content;

@JsonProperty("like_num")
private int likeNum;

@JsonProperty("origin_rpid")
@TableField(exist = false)
@JsonSerialize(using = ToStringSerializer.class)
private Long originRpid = -1L;

@TableField(exist = false)
@JsonProperty("similar_count")
private Integer similarCount = 0;

@TableField(exist = false)
@JsonProperty("similar_like_sum")
private Integer similarLikeSum = 0;

/**
* 得到小作文里某角色出现次数
*
* @param roleEnum
* @return
*/
public int getLetterRoleRepeatNum(ASoulRoleEnum roleEnum) {
if (StringUtils.isEmpty(content)) {
return 0;
}
if (roleEnum == null) {
return 0;
}
return content.split(roleEnum.getName()).length - 1;
}

/**
* 当点赞大于指定数,字数大于指定数时,我们认为这是一篇小作文
*
* @return
*/
public boolean isLoveLetter(int likeNum, int length) {
// 基础条件
boolean baseCond = this.likeNum > likeNum && this.content.length() > length;
// 附加条件,如向晚的小作文里经常有 "向晚不是","阿八" 等关键字,一般是撕逼,要排除。如珈乐也有请假等大量干扰选项
// TODO: 优化一下排除算法,但这需要更多数据,同时要考虑到性能
// TODO: 一个想法:单独靠算法排除掉干扰选项是很难做完善的,一般来说,au们看到小作文才会去查重。如果在查重时,
// 将匹配的小作文查重次数 +1,之后小作文就从如 查重次数 > 10 的小作文里随机挑选,这样可以保证小作文是比较准确的,而不是骂战留言之类的
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. 需要在 reply表 里新增一列用于存放查重次数?

  2. 可能存在有人反复查重某一篇非小作文评论来提升权重的情况?
    如何计算有效的查重次数好像比较困难

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. 需要在 reply表 里新增一列用于存放查重次数?
  2. 可能存在有人反复查重某一篇非小作文评论来提升权重的情况?
    如何计算有效的查重次数好像比较困难

查重次数和被引(偷)次数我觉得都是有必要留存的维度。以目前bb空间的量,也许要辅以redis定时刷数据到db,单凭数据库我不知道扛不扛得住。针对(2)的情况,我在下面那个单独的回复里提啦,可以看一下捏

List<String> keywords = Arrays.asList("阿八", "小粒", "请假", "切片", "道歉", "出问题", "解释", "挖掘机", "复盘", "节奏", "运营", "路人", "贵物", "笑嘻");
boolean extraCond = keywords.stream().noneMatch(k -> content.contains(k));
return baseCond && extraCond;
}

public boolean isLoveLetter() {
return isLoveLetter(50, 30);
}

/**
* 是否是某个特定的人的小作文?
*
* @param roleEnum
* @param repeatNum
* @return
*/
public boolean isSpecRoleLoveLetter(ASoulRoleEnum roleEnum, int repeatNum) {
// TODO: 是否某个人的小作文算法应该更详细,如有些小作文只出现霓虹甜心和红色高跟鞋而不出现珈乐,待优化
return getLetterRoleRepeatNum(roleEnum) > repeatNum;
}

@JsonProperty("ctime")
private int ctime;

@JsonProperty("m_name")
private String mName;

@JsonProperty("content")
private String content;

@JsonProperty("like_num")
private int likeNum;

@JsonProperty("origin_rpid")
@TableField(exist = false)
@JsonSerialize(using = ToStringSerializer.class)
private Long originRpid = -1L;

@TableField(exist = false)
@JsonProperty("similar_count")
private Integer similarCount = 0;

@TableField(exist = false)
@JsonProperty("similar_like_sum")
private Integer similarLikeSum = 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package asia.asoulcnki.api.persistence.param;

import asia.asoulcnki.api.enums.ASoulRoleEnum;
import lombok.Data;

@Data
public class QueryRandomLoveLetterParam {
// 谁的小作文,null 表示所有人,前端传 AVA, DIANA 等枚举名
private ASoulRoleEnum role;
// 随机几篇小作文
private int limit = 10;
// 点赞大于多少
private int likeNum = 50;
// 字数大于多少
private int length = 30;
}
10 changes: 10 additions & 0 deletions src/main/java/asia/asoulcnki/api/service/ILoveLetterService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package asia.asoulcnki.api.service;

import asia.asoulcnki.api.persistence.entity.Reply;
import asia.asoulcnki.api.persistence.param.QueryRandomLoveLetterParam;

import java.util.List;

public interface ILoveLetterService {
List<Reply> queryLoveLetter(QueryRandomLoveLetterParam param);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package asia.asoulcnki.api.service.impl;

import asia.asoulcnki.api.common.duplicationcheck.LeaderBoard;
import asia.asoulcnki.api.persistence.entity.Reply;
import asia.asoulcnki.api.persistence.param.QueryRandomLoveLetterParam;
import asia.asoulcnki.api.service.ILoveLetterService;
import org.springframework.stereotype.Service;
import asia.asoulcnki.api.common.duplicationcheck.LeaderBoard.LeaderBoardEntry;


import java.util.List;

@Service
public class ILoveLetterServiceImpl implements ILoveLetterService {
@Override
public List<Reply> queryLoveLetter(QueryRandomLoveLetterParam param){
LeaderBoardEntry leaderBoard = LeaderBoard.getInstance().getSimilarCountLeaderBoard();
return leaderBoard.queryLoveLetters(param);
}
}