-
Notifications
You must be signed in to change notification settings - Fork 21
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
feat: 初版随机小作文 #32
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
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)); | ||
} | ||
|
||
} |
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, "乃琳"); | ||
|
||
@EnumValue | ||
private int code; | ||
|
||
@JsonValue | ||
private String name; | ||
} |
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; | ||
|
@@ -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 的小作文里随机挑选,这样可以保证小作文是比较准确的,而不是骂战留言之类的 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
查重次数和被引(偷)次数我觉得都是有必要留存的维度。以目前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; | ||
} |
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); | ||
} | ||
} |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
目前ranking接口是这样传值的,或许可以参考一下?
上述参数都要经过encodeURIComponent做编码
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
传枚举的方式应该都行啦,我个人比较喜欢传具体的内容,这样比较明确,如果前端有需要的话我可以改一下改为传枚举值捏