查词检测+小红书代理功能
parent
8aacfb91b9
commit
b061a03f98
@ -0,0 +1,84 @@
|
||||
package com.baiye.controller;
|
||||
|
||||
import com.baiye.annotation.Inner;
|
||||
import com.baiye.core.base.api.Result;
|
||||
import com.baiye.core.constant.AddGroup;
|
||||
import com.baiye.core.constant.UpdateGroup;
|
||||
import com.baiye.dto.EssayDTO;
|
||||
import com.baiye.entity.LexiconFilter;
|
||||
import com.baiye.service.EssayHandleService;
|
||||
import com.baiye.vo.CheckContentVO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/xhs/essay")
|
||||
@RequiredArgsConstructor
|
||||
@Api(tags = "小红书文章处理")
|
||||
public class EssayHandleController {
|
||||
|
||||
private final EssayHandleService essayHandleService;
|
||||
|
||||
@GetMapping("/getLexiconFilterList")
|
||||
@Inner(value = false)
|
||||
@ApiOperation("获取违禁词列表")
|
||||
public Result<Object> getLexiconFilterList(){
|
||||
return Result.data(essayHandleService.getLexiconFilterList());
|
||||
}
|
||||
|
||||
@GetMapping("/getLexiconFilterAllList")
|
||||
@ApiOperation("获取违禁词全部列表")
|
||||
public Result<Object> getLexiconFilterAllList(){
|
||||
return Result.data(essayHandleService.getLexiconFilterAllList());
|
||||
}
|
||||
|
||||
@PostMapping("/updateLexiconFilter")
|
||||
@Inner(value = false)
|
||||
@ApiOperation("更新违禁词")
|
||||
public Result<?> updateLexiconFilter(@Validated({UpdateGroup.class}) @RequestBody LexiconFilter lexiconFilter){
|
||||
essayHandleService.updateLexiconFilter(lexiconFilter);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@PostMapping("/addLexiconFilter")
|
||||
@Inner(value = false)
|
||||
@ApiOperation("添加违禁词")
|
||||
public Result<?> addLexiconFilter(@Validated({AddGroup.class}) @RequestBody LexiconFilter lexiconFilter){
|
||||
essayHandleService.addLexiconFilter(lexiconFilter);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@PostMapping("/checkContent")
|
||||
@Inner(value = false)
|
||||
@ApiOperation("检测内容")
|
||||
public Result<CheckContentVO> checkContent(@RequestBody EssayDTO essayDTO){
|
||||
return Result.data(essayHandleService.checkContent(essayDTO));
|
||||
}
|
||||
|
||||
@PostMapping("/processArticle")
|
||||
@Inner(value = false)
|
||||
@ApiOperation("处理文章")
|
||||
public Result<Object> processArticle(@RequestBody EssayDTO essayDTO){
|
||||
return Result.data(essayHandleService.processArticle(essayDTO));
|
||||
}
|
||||
|
||||
@GetMapping("/writeInRedis")
|
||||
@Inner(value = false)
|
||||
@ApiOperation("向redis写入拼音库")
|
||||
public Result<?> writeInRedisPinyinLexicon(){
|
||||
essayHandleService.writeInRedisPinyinLexicon();
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@GetMapping("/writeInForbiddenWords")
|
||||
@Inner(value = false)
|
||||
@ApiOperation("文件写入违禁词")
|
||||
public Result<?> writeInForbiddenWords(@RequestParam("file") MultipartFile file, @RequestParam("organizeId") Long organizeId){
|
||||
essayHandleService.writeInForbiddenWords(file, organizeId);
|
||||
return Result.success();
|
||||
}
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
package com.baiye.controller;
|
||||
|
||||
import com.baiye.annotation.Inner;
|
||||
import com.baiye.core.base.api.Result;
|
||||
import com.baiye.core.constant.AddGroup;
|
||||
import com.baiye.core.constant.UpdateGroup;
|
||||
import com.baiye.core.page.PageResult;
|
||||
import com.baiye.dto.ProxyDTO;
|
||||
import com.baiye.entity.ProxyEntity;
|
||||
import com.baiye.service.ProxyService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author YQY
|
||||
* @Date 2023/3/29
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/xhs/proxy")
|
||||
@RequiredArgsConstructor
|
||||
@Api(tags = "小红书代理管理")
|
||||
public class ProxyController {
|
||||
|
||||
private final ProxyService proxyService;
|
||||
|
||||
@GetMapping("/findProxy")
|
||||
@Inner(value = false)
|
||||
@ApiOperation("手机号绑定代理")
|
||||
public Result<ProxyEntity> findProxy(@RequestParam("phone") String phone){
|
||||
return Result.data(proxyService.findProxy(phone));
|
||||
}
|
||||
|
||||
@PostMapping("/add")
|
||||
@Inner(value = false)
|
||||
@ApiOperation("添加")
|
||||
public Result<?> add(@Validated({AddGroup.class}) @RequestBody ProxyEntity proxyEntity){
|
||||
proxyService.add(proxyEntity);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
@Inner(value = false)
|
||||
@ApiOperation("修改")
|
||||
public Result<?> update(@Validated({UpdateGroup.class}) @RequestBody ProxyEntity proxyEntity){
|
||||
proxyService.update(proxyEntity);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@DeleteMapping("/del")
|
||||
@Inner(value = false)
|
||||
@ApiOperation("删除IP-并删除绑定")
|
||||
public Result<?> del(@RequestParam("id") Long id, @RequestParam("type") Integer type){
|
||||
proxyService.del(id, type);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@GetMapping("/ipBindingList")
|
||||
@Inner(value = false)
|
||||
@ApiOperation("IP绑定手机号列表")
|
||||
public PageResult ipBindingList(ProxyDTO proxyDTO, Pageable pageable){
|
||||
return proxyService.ipBindingList(proxyDTO, pageable);
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@Inner(value = false)
|
||||
@ApiOperation("IP列表")
|
||||
public Result<List<ProxyEntity>> list(){
|
||||
return Result.data(proxyService.list());
|
||||
}
|
||||
|
||||
@PostMapping("/delAccount")
|
||||
@Inner(value = false)
|
||||
@ApiOperation("删除账号绑定关系")
|
||||
public Result<?> delAccount(@RequestBody List<String> phoneList){
|
||||
proxyService.delAccount(phoneList);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@GetMapping("/replaceAccountIp")
|
||||
@Inner(value = false)
|
||||
@ApiOperation("替换账号绑定IP")
|
||||
public Result<?> replaceAccountIp(@RequestParam("proxyId") Long proxyId, @RequestParam("phone") String phone){
|
||||
proxyService.replaceAccountIp(proxyId, phone);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@GetMapping("/writeProxy")
|
||||
@Inner(value = false)
|
||||
@ApiOperation("文件写入代理信息")
|
||||
public Result<?> writeProxy(@RequestParam("file") MultipartFile file){
|
||||
proxyService.writeProxy(file);
|
||||
return Result.success();
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.baiye.dao;
|
||||
|
||||
import com.baiye.entity.LexiconFilter;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface LexiconFilterMapper extends BaseMapper<LexiconFilter> {
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.baiye.dao;
|
||||
|
||||
import com.baiye.entity.LexiconPinyin;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface LexiconPinyinMapper extends BaseMapper<LexiconPinyin> {
|
||||
|
||||
void insertAll(List<LexiconPinyin> list);
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.baiye.dao;
|
||||
|
||||
import com.baiye.entity.ProxyAccountEntity;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author YQY
|
||||
* @Date 2023/3/29
|
||||
*/
|
||||
@Mapper
|
||||
public interface ProxyAccountMapper extends BaseMapper<ProxyAccountEntity> {
|
||||
|
||||
void insertAll(List<ProxyAccountEntity> list);
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
package com.baiye.dao;
|
||||
|
||||
import com.baiye.entity.ProxyEntity;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author YQY
|
||||
* @Date 2023/3/29
|
||||
*/
|
||||
@Mapper
|
||||
public interface ProxyMapper extends BaseMapper<ProxyEntity> {
|
||||
|
||||
List<ProxyEntity> findProxy(@Param("phone") String phone);
|
||||
|
||||
void insertAll(List<ProxyEntity> list);
|
||||
|
||||
void updateExpireDateSubtractOne();
|
||||
|
||||
void updateExpireDateStatus();
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.baiye.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @Author YQY
|
||||
* @Date 2023/3/22
|
||||
*/
|
||||
@Data
|
||||
public class EssayDTO {
|
||||
|
||||
@ApiModelProperty("文章")
|
||||
private String content;
|
||||
|
||||
@ApiModelProperty("小组ID")
|
||||
private List<Long> organizeId;
|
||||
|
||||
@ApiModelProperty("处理类型:1、拼音首字母替换 2、拼音替换 3、繁体字替换 4、同音字替换")
|
||||
private Integer type;
|
||||
|
||||
@ApiModelProperty("违禁词")
|
||||
private Set<String> prohibitedWords;
|
||||
|
||||
@ApiModelProperty("自定义词库")
|
||||
private String customEssay;
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.baiye.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author YQY
|
||||
* @Date 2023/3/29
|
||||
*/
|
||||
@Data
|
||||
public class ProxyDTO {
|
||||
|
||||
@ApiModelProperty("手机号")
|
||||
private String phone;
|
||||
|
||||
@ApiModelProperty("ip地址")
|
||||
private String ip;
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.baiye.entity;
|
||||
|
||||
import com.baiye.core.base.MybatisBaseEntity;
|
||||
import com.baiye.core.constant.AddGroup;
|
||||
import com.baiye.core.constant.UpdateGroup;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @Author YQY
|
||||
* @Date 2023/3/22
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
@TableName("tb_lexicon_filter")
|
||||
@ApiOperation("违禁词库")
|
||||
public class LexiconFilter extends MybatisBaseEntity {
|
||||
|
||||
@ApiModelProperty(value = "违禁词库主键ID")
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
@NotNull(message = "ID不能为空", groups = UpdateGroup.class)
|
||||
private Long id;
|
||||
|
||||
@NotNull(message = "词不能为空", groups = AddGroup.class)
|
||||
private String speech;
|
||||
|
||||
@NotNull(message = "组ID不能为空", groups = AddGroup.class)
|
||||
private Long organizeId;
|
||||
|
||||
@NotNull(message = "组名称不能为空", groups = AddGroup.class)
|
||||
private String organizeName;
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.baiye.entity;
|
||||
|
||||
import com.baiye.core.base.MybatisBaseEntity;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* @Author YQY
|
||||
* @Date 2023/3/22
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
@TableName("tb_lexicon_pinyin")
|
||||
@ApiOperation("拼音词库")
|
||||
public class LexiconPinyin extends MybatisBaseEntity {
|
||||
|
||||
@ApiModelProperty(value = "拼音词库主键ID")
|
||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty("拼音")
|
||||
private String phoneticTranscription;
|
||||
|
||||
@ApiModelProperty("词")
|
||||
private String words;
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.baiye.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* @Author YQY
|
||||
* @Date 2023/3/29
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@TableName("tb_proxy_account")
|
||||
@ApiOperation("代理地址手机号映射表")
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ProxyAccountEntity {
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty("手机号")
|
||||
private String nid;
|
||||
|
||||
@ApiModelProperty("映射IP的ID")
|
||||
private Long proxyId;
|
||||
|
||||
public ProxyAccountEntity(String nid, Long proxyId) {
|
||||
this.nid = nid;
|
||||
this.proxyId = proxyId;
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.baiye.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @Author YQY
|
||||
* @Date 2023/3/22
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class CheckContentVO {
|
||||
|
||||
@ApiModelProperty("内容")
|
||||
private String content;
|
||||
|
||||
@ApiModelProperty("内容长度")
|
||||
private Integer contentCount;
|
||||
|
||||
@ApiModelProperty("违禁词数量")
|
||||
private Integer prohibitedWordCount;
|
||||
|
||||
@ApiModelProperty("违禁词")
|
||||
private Set<String> prohibitedWords;
|
||||
|
||||
public CheckContentVO() {
|
||||
}
|
||||
|
||||
public CheckContentVO(String content, Integer contentCount, Integer prohibitedWordCount, Set<String> prohibitedWords) {
|
||||
this.content = content;
|
||||
this.contentCount = contentCount;
|
||||
this.prohibitedWordCount = prohibitedWordCount;
|
||||
this.prohibitedWords = prohibitedWords;
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.baiye.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
/**
|
||||
* @Author YQY
|
||||
* @Date 2023/4/3
|
||||
*/
|
||||
@Configuration
|
||||
public class JDKConfig {
|
||||
|
||||
@PostConstruct
|
||||
public void httpsProxyConfig() {
|
||||
System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
|
||||
}
|
||||
}
|
@ -1,33 +1,33 @@
|
||||
package com.baiye.config;
|
||||
|
||||
import com.alibaba.alicloud.context.AliCloudProperties;
|
||||
import com.alibaba.alicloud.context.oss.OssProperties;
|
||||
import com.aliyun.oss.OSS;
|
||||
import com.aliyun.oss.OSSClientBuilder;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
|
||||
/**
|
||||
* @author Enzo
|
||||
* @date : 2022/8/15
|
||||
*/
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
public class OssConfig {
|
||||
|
||||
private final OssProperties ossProperties;
|
||||
private final AliCloudProperties aliCloudProperties;
|
||||
|
||||
@Bean
|
||||
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public OSS ossClient() {
|
||||
return new OSSClientBuilder().build
|
||||
(ossProperties.getEndpoint(),
|
||||
aliCloudProperties.getAccessKey(),
|
||||
aliCloudProperties.getSecretKey());
|
||||
}
|
||||
|
||||
}
|
||||
//package com.baiye.config;
|
||||
//
|
||||
//import com.alibaba.alicloud.context.AliCloudProperties;
|
||||
//import com.alibaba.alicloud.context.oss.OssProperties;
|
||||
//import com.aliyun.oss.OSS;
|
||||
//import com.aliyun.oss.OSSClientBuilder;
|
||||
//import lombok.RequiredArgsConstructor;
|
||||
//import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
//import org.springframework.context.annotation.Bean;
|
||||
//import org.springframework.context.annotation.Configuration;
|
||||
//import org.springframework.context.annotation.Scope;
|
||||
//
|
||||
///**
|
||||
// * @author Enzo
|
||||
// * @date : 2022/8/15
|
||||
// */
|
||||
//@Configuration
|
||||
//@RequiredArgsConstructor
|
||||
//public class OssConfig {
|
||||
//
|
||||
// private final OssProperties ossProperties;
|
||||
// private final AliCloudProperties aliCloudProperties;
|
||||
//
|
||||
// @Bean
|
||||
// @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
// public OSS ossClient() {
|
||||
// return new OSSClientBuilder().build
|
||||
// (ossProperties.getEndpoint(),
|
||||
// aliCloudProperties.getAccessKey(),
|
||||
// aliCloudProperties.getSecretKey());
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
@ -0,0 +1,50 @@
|
||||
package com.baiye.service;
|
||||
|
||||
import com.baiye.dto.EssayDTO;
|
||||
import com.baiye.entity.LexiconFilter;
|
||||
import com.baiye.vo.CheckContentVO;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
public interface EssayHandleService {
|
||||
|
||||
/**
|
||||
* 获取违禁过滤词
|
||||
*/
|
||||
Object getLexiconFilterList();
|
||||
|
||||
/**
|
||||
* 获取违禁词全部列表
|
||||
*/
|
||||
Object getLexiconFilterAllList();
|
||||
|
||||
/**
|
||||
* 修改违禁过滤词
|
||||
*/
|
||||
void updateLexiconFilter(LexiconFilter lexiconFilter);
|
||||
|
||||
/**
|
||||
* 添加违禁词
|
||||
*/
|
||||
void addLexiconFilter(LexiconFilter lexiconFilter);
|
||||
|
||||
/**
|
||||
* 内容检测
|
||||
*/
|
||||
CheckContentVO checkContent(EssayDTO essayDTO);
|
||||
|
||||
/**
|
||||
* 处理文章
|
||||
*/
|
||||
Object processArticle(EssayDTO essayDTO);
|
||||
|
||||
/**
|
||||
* 向redis写入拼音库
|
||||
*/
|
||||
void writeInRedisPinyinLexicon();
|
||||
|
||||
/**
|
||||
* 文件写入违禁词
|
||||
* @param organizeId 小组ID
|
||||
*/
|
||||
void writeInForbiddenWords(MultipartFile file, Long organizeId);
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package com.baiye.service;
|
||||
|
||||
import com.baiye.core.page.PageResult;
|
||||
import com.baiye.dto.ProxyDTO;
|
||||
import com.baiye.entity.ProxyEntity;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ProxyService {
|
||||
|
||||
/**
|
||||
* 手机号绑定代理
|
||||
*/
|
||||
ProxyEntity findProxy(String phone);
|
||||
|
||||
/**
|
||||
* 添加IP
|
||||
*/
|
||||
void add(ProxyEntity proxyEntity);
|
||||
|
||||
/**
|
||||
* 修改IP-并修改绑定
|
||||
*/
|
||||
void update(ProxyEntity proxyEntity);
|
||||
|
||||
/**
|
||||
* 删除IP-并删除绑定
|
||||
*
|
||||
* @param type 0:删除IP和所有映射账号 1:删除IP-删除账号重新绑定IP
|
||||
*/
|
||||
void del(Long id, Integer type);
|
||||
|
||||
/**
|
||||
* IP绑定手机号列表
|
||||
*/
|
||||
PageResult ipBindingList(ProxyDTO proxyDTO, Pageable pageable);
|
||||
|
||||
/**
|
||||
* IP列表
|
||||
*/
|
||||
List<ProxyEntity> list();
|
||||
|
||||
/**
|
||||
* 删除手机号绑定关系
|
||||
*
|
||||
* @param phoneList 手机号
|
||||
*/
|
||||
void delAccount(List<String> phoneList);
|
||||
|
||||
/**
|
||||
* 替换账号绑定IP
|
||||
*/
|
||||
void replaceAccountIp(Long proxyId, String phone);
|
||||
|
||||
/**
|
||||
* 列表插入
|
||||
*/
|
||||
void insertAll(List<ProxyEntity> proxyEntityList);
|
||||
|
||||
/**
|
||||
* 文件写入代理信息
|
||||
*/
|
||||
void writeProxy(MultipartFile file);
|
||||
}
|
@ -0,0 +1,287 @@
|
||||
package com.baiye.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import com.alibaba.excel.EasyExcelFactory;
|
||||
import com.baiye.BadRequestException;
|
||||
import com.baiye.config.JDKConfig;
|
||||
import com.baiye.core.page.PageResult;
|
||||
import com.baiye.core.util.StringUtils;
|
||||
import com.baiye.dao.ProxyMapper;
|
||||
import com.baiye.dao.ProxyAccountMapper;
|
||||
import com.baiye.dto.ProxyDTO;
|
||||
import com.baiye.easyexcel.dto.ProxyDto;
|
||||
import com.baiye.easyexcel.listener.ProxyListener;
|
||||
import com.baiye.entity.ProxyEntity;
|
||||
import com.baiye.entity.ProxyAccountEntity;
|
||||
import com.baiye.service.ProxyService;
|
||||
import com.baiye.util.MobileUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.net.Authenticator;
|
||||
import java.net.PasswordAuthentication;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author YQY
|
||||
* @Date 2023/3/29
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class ProxyServiceImpl implements ProxyService {
|
||||
|
||||
private final ProxyMapper proxyMapper;
|
||||
private final ProxyAccountMapper proxyAccountMapper;
|
||||
private final String QUILT_PROXY_URL = "https://tool.lu/ip";
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ProxyEntity findProxy(String phone) {
|
||||
|
||||
// 1、校验手机号
|
||||
if (!MobileUtil.checkPhone(phone)) throw new BadRequestException("请输入正确手机号!!!");
|
||||
// 2、有绑定关系直接返回
|
||||
ProxyAccountEntity entity = proxyAccountMapper.selectOne(new LambdaQueryWrapper<ProxyAccountEntity>().eq(ProxyAccountEntity::getNid, phone));
|
||||
if (entity != null && entity.getId() != null) {
|
||||
return proxyMapper.selectById(entity.getProxyId());
|
||||
}
|
||||
|
||||
List<ProxyEntity> proxyList = proxyMapper.selectList(new LambdaQueryWrapper<ProxyEntity>().eq(ProxyEntity::getStatus, 0));
|
||||
if (CollUtil.isNotEmpty(proxyList)) {
|
||||
//3、获取一个可用代理地址
|
||||
ProxyEntity proxyEntity = proxyList.get(RandomUtil.randomInt(0, proxyList.size()));
|
||||
try {
|
||||
String account = proxyEntity.getAccount();
|
||||
String password = proxyEntity.getPassword();
|
||||
/**
|
||||
* 代理配置 以下配置要在项目启动之前{@link JDKConfig}配置
|
||||
* System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
|
||||
*/
|
||||
Authenticator.setDefault(
|
||||
new Authenticator() {
|
||||
@Override
|
||||
public PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(account, password.toCharArray());
|
||||
}
|
||||
}
|
||||
);
|
||||
HttpResponse execute = HttpRequest.get(QUILT_PROXY_URL)
|
||||
.setHttpProxy(proxyEntity.getIp(), proxyEntity.getPort())
|
||||
.basicProxyAuth(account, password)
|
||||
.execute();
|
||||
if (execute.getStatus() != 200) {
|
||||
log.info("代理请求失败: {}", proxyEntity.getIp());
|
||||
proxyEntity = askProxy(proxyList, proxyEntity);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("无效的代理地址: {}, 错误信息:{}", proxyEntity.getIp(), e.getMessage());
|
||||
proxyEntity = askProxy(proxyList, proxyEntity);
|
||||
}
|
||||
|
||||
//4、添加代理地址-手机号映射关系
|
||||
if (proxyEntity.getId() != null) {
|
||||
ProxyAccountEntity proxyAccountEntity = new ProxyAccountEntity();
|
||||
proxyAccountEntity.setNid(phone);
|
||||
proxyAccountEntity.setProxyId(proxyEntity.getId());
|
||||
proxyAccountMapper.insert(proxyAccountEntity);
|
||||
return proxyEntity;
|
||||
} else {
|
||||
throw new BadRequestException("无可用代理,请联系管理员!!!");
|
||||
}
|
||||
}
|
||||
throw new BadRequestException("无可用代理,请联系管理员!!!");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void add(ProxyEntity proxyEntity) {
|
||||
// 添加IP
|
||||
proxyEntity.setCreateTime(new Date());
|
||||
proxyMapper.insert(proxyEntity);
|
||||
Long id = proxyEntity.getId();
|
||||
|
||||
// IP绑定账号
|
||||
List<ProxyAccountEntity> proxyAccountEntities = new ArrayList<>();
|
||||
List<String> phoneList = proxyEntity.getPhoneList();
|
||||
if (CollUtil.isNotEmpty(phoneList)) {
|
||||
for (String phone : phoneList) {
|
||||
if (MobileUtil.checkPhone(phone)) {
|
||||
ProxyAccountEntity proxyAccountEntity = new ProxyAccountEntity(phone, id);
|
||||
proxyAccountEntities.add(proxyAccountEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CollUtil.isNotEmpty(proxyAccountEntities)) proxyAccountMapper.insertAll(proxyAccountEntities);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void update(ProxyEntity proxyEntity) {
|
||||
|
||||
// 修改IP的信息
|
||||
proxyMapper.updateById(proxyEntity);
|
||||
List<String> phoneList = proxyEntity.getPhoneList();
|
||||
List<ProxyAccountEntity> list = new ArrayList<>();
|
||||
|
||||
List<ProxyAccountEntity> proxyAccountEntities = proxyAccountMapper.selectList(new LambdaQueryWrapper<ProxyAccountEntity>()
|
||||
.eq(ProxyAccountEntity::getProxyId, proxyEntity.getId()));
|
||||
Map<String, List<ProxyAccountEntity>> map = proxyAccountEntities.stream().collect(Collectors.groupingBy(ProxyAccountEntity::getNid));
|
||||
|
||||
// 获取所有要绑定的账号-并添加绑定关系
|
||||
for (String phone : phoneList) {
|
||||
if (!map.containsKey(phone)) {
|
||||
ProxyAccountEntity proxyAccountEntity = new ProxyAccountEntity(phone, proxyEntity.getId());
|
||||
list.add(proxyAccountEntity);
|
||||
}
|
||||
}
|
||||
if (CollUtil.isNotEmpty(list)) proxyAccountMapper.insertAll(list);
|
||||
|
||||
// 删除的账号-删除绑定关系
|
||||
Set<String> phones = map.keySet();
|
||||
List<String> deleteList = phones.stream().filter(t -> !phoneList.contains(t)).collect(Collectors.toList());
|
||||
if (CollUtil.isNotEmpty(deleteList)) {
|
||||
proxyAccountMapper.delete(new LambdaQueryWrapper<ProxyAccountEntity>().in(ProxyAccountEntity::getNid, deleteList));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void del(Long id, Integer type) {
|
||||
proxyMapper.deleteById(id);
|
||||
if (type == 0) {
|
||||
// 删除绑定关系
|
||||
proxyAccountMapper.delete(new LambdaQueryWrapper<ProxyAccountEntity>().eq(ProxyAccountEntity::getProxyId, id));
|
||||
} else {
|
||||
List<ProxyAccountEntity> entities = proxyAccountMapper.selectList(new LambdaQueryWrapper<ProxyAccountEntity>().eq(ProxyAccountEntity::getProxyId, id));
|
||||
proxyAccountMapper.delete(new LambdaQueryWrapper<ProxyAccountEntity>().eq(ProxyAccountEntity::getProxyId, id));
|
||||
// 账号重新绑定IP
|
||||
List<String> phoneList = entities.stream().map(ProxyAccountEntity::getNid).collect(Collectors.toList());
|
||||
phoneList.forEach(this::findProxy);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult ipBindingList(ProxyDTO proxyDTO, Pageable pageable) {
|
||||
String ip = proxyDTO.getIp();
|
||||
String phone = proxyDTO.getPhone();
|
||||
|
||||
Page<ProxyEntity> page = new Page<>(pageable.getPageNumber(), pageable.getPageSize());
|
||||
LambdaQueryWrapper<ProxyEntity> wrapper = new LambdaQueryWrapper<>();
|
||||
if (StringUtils.isNotBlank(ip)) wrapper.eq(ProxyEntity::getIp, ip);
|
||||
|
||||
List<ProxyAccountEntity> entities;
|
||||
if (StringUtils.isNotBlank(phone)) {
|
||||
entities = proxyAccountMapper.selectList(new LambdaQueryWrapper<ProxyAccountEntity>().like(ProxyAccountEntity::getNid, phone));
|
||||
List<Long> proxyAccountIds = entities.stream().map(ProxyAccountEntity::getProxyId).collect(Collectors.toList());
|
||||
if (CollUtil.isNotEmpty(proxyAccountIds)) wrapper.in(ProxyEntity::getId, proxyAccountIds);
|
||||
else return PageResult.success(0L, 0L, new ArrayList<>());
|
||||
} else {
|
||||
entities = proxyAccountMapper.selectList(new LambdaQueryWrapper<>());
|
||||
}
|
||||
Map<Long, List<ProxyAccountEntity>> map = entities.stream().collect(Collectors.groupingBy(ProxyAccountEntity::getProxyId));
|
||||
|
||||
Page<ProxyEntity> iPage = proxyMapper.selectPage(page, wrapper);
|
||||
for (ProxyEntity record : iPage.getRecords()) {
|
||||
if (map.containsKey(record.getId())) {
|
||||
List<String> phoneList = map.get(record.getId()).stream().map(ProxyAccountEntity::getNid).collect(Collectors.toList());
|
||||
record.setPhoneList(phoneList);
|
||||
}
|
||||
}
|
||||
return PageResult.success(iPage.getTotal(), iPage.getPages(), iPage.getRecords());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProxyEntity> list() {
|
||||
return proxyMapper.selectList(new QueryWrapper<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void delAccount(List<String> phoneList) {
|
||||
proxyAccountMapper.delete(new LambdaQueryWrapper<ProxyAccountEntity>().in(ProxyAccountEntity::getNid, phoneList));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replaceAccountIp(Long proxyId, String phone) {
|
||||
ProxyAccountEntity proxyAccountEntity = proxyAccountMapper.selectOne(new LambdaQueryWrapper<ProxyAccountEntity>()
|
||||
.eq(ProxyAccountEntity::getNid, phone));
|
||||
|
||||
proxyAccountEntity.setProxyId(proxyId);
|
||||
proxyAccountMapper.updateById(proxyAccountEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void insertAll(List<ProxyEntity> proxyEntityList) {
|
||||
proxyMapper.insertAll(proxyEntityList);
|
||||
|
||||
List<ProxyAccountEntity> list = new ArrayList<>();
|
||||
for (ProxyEntity proxyEntity : proxyEntityList) {
|
||||
List<String> phoneList = proxyEntity.getPhoneList();
|
||||
for (String phone : phoneList) {
|
||||
ProxyAccountEntity proxyAccountEntity = new ProxyAccountEntity(phone, proxyEntity.getId());
|
||||
list.add(proxyAccountEntity);
|
||||
}
|
||||
}
|
||||
if (CollUtil.isNotEmpty(list)) proxyAccountMapper.insertAll(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeProxy(MultipartFile file) {
|
||||
if (file == null) throw new BadRequestException("文件不能为空!!!");
|
||||
|
||||
String extName = FileUtil.extName(file.getOriginalFilename());
|
||||
if (extName != null && !(extName.equals("xlsx") || extName.equals("xls"))) {
|
||||
throw new BadRequestException("仅支持Excel文件!!!");
|
||||
}
|
||||
try {
|
||||
EasyExcelFactory.read(file.getInputStream(), ProxyDto.class, new ProxyListener(this)).build().readAll();
|
||||
} catch (Exception e) {
|
||||
log.error("错误信息:{}", e.getMessage());
|
||||
throw new BadRequestException("上传错误,请联系管理员!!!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机代理失败后,循环获取可用代理
|
||||
*/
|
||||
private ProxyEntity askProxy(List<ProxyEntity> proxyList, ProxyEntity proxyEntity) {
|
||||
proxyList.remove(proxyEntity);
|
||||
if (CollUtil.isNotEmpty(proxyList)) {
|
||||
for (ProxyEntity entity : proxyList) {
|
||||
try {
|
||||
Authenticator.setDefault(
|
||||
new Authenticator() {
|
||||
@Override
|
||||
public PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(entity.getAccount(), entity.getPassword().toCharArray());
|
||||
}
|
||||
}
|
||||
);
|
||||
HttpResponse execute = HttpRequest.get(QUILT_PROXY_URL)
|
||||
.setHttpProxy(entity.getIp(), entity.getPort())
|
||||
.basicProxyAuth(entity.getAccount(), entity.getPassword())
|
||||
.execute();
|
||||
if (execute.getStatus() != 200) log.info("无效的代理地址: {}", entity.getIp());
|
||||
else return entity;
|
||||
} catch (Exception e) {
|
||||
log.error("无效的代理地址: {}, 报错信息:{}", entity.getIp(), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
return new ProxyEntity();
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.baiye.task;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.baiye.dao.ProxyMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @Author YQY
|
||||
* @Date 2023/4/10
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class ProxyExpireDateTask {
|
||||
|
||||
private final ProxyMapper proxyMapper;
|
||||
/**
|
||||
* 代理地址到期时间减一天(每天0点)
|
||||
*/
|
||||
@Scheduled(cron = "0 0 0 * * ? ")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void checkProxyExpireDate() {
|
||||
log.info("--------------代理地址到期时间减一天,执行时间{}--------------", DateUtil.now());
|
||||
proxyMapper.updateExpireDateSubtractOne();
|
||||
proxyMapper.updateExpireDateStatus();
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.baiye.dao.LexiconFilterMapper">
|
||||
|
||||
</mapper>
|
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.baiye.dao.LexiconPinyinMapper">
|
||||
|
||||
<insert id="insertAll">
|
||||
insert into tb_lexicon_pinyin
|
||||
(phonetic_transcription, words)
|
||||
values
|
||||
<foreach collection="list" item="item" index="index" separator=",">
|
||||
(#{item.phoneticTranscription}, #{item.words})
|
||||
</foreach>
|
||||
</insert>
|
||||
</mapper>
|
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.baiye.dao.ProxyAccountMapper">
|
||||
|
||||
<insert id="insertAll">
|
||||
insert into tb_proxy_account
|
||||
(nid, proxy_id)
|
||||
values
|
||||
<foreach collection="list" item="item" index="index" separator=",">
|
||||
(#{item.nid}, #{item.proxyId})
|
||||
</foreach>
|
||||
</insert>
|
||||
</mapper>
|
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.baiye.dao.ProxyMapper">
|
||||
|
||||
<select id="findProxy" resultType="com.baiye.entity.ProxyEntity">
|
||||
SELECT *
|
||||
FROM tb_proxy
|
||||
where id not in (select proxy_id from tb_proxy_phone where phone = #{phone})
|
||||
</select>
|
||||
|
||||
<insert id="insertAll" keyProperty="id" useGeneratedKeys="true">
|
||||
insert into tb_proxy
|
||||
(ip, port, account, password, address, agreement_type, surplus_day, is_domestic, agent, status, create_time)
|
||||
values
|
||||
<foreach collection="list" item="item" index="index" separator=",">
|
||||
(#{item.ip}, #{item.port}, #{item.account}, #{item.password}, #{item.address},
|
||||
#{item.agreementType}, #{item.surplusDay}, #{item.isDomestic}, #{item.agent}, #{item.status}, #{item.createTime})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<update id="updateExpireDateSubtractOne">
|
||||
update tb_proxy set surplus_day = surplus_day - 1 where surplus_day > 0
|
||||
</update>
|
||||
|
||||
<update id="updateExpireDateStatus">
|
||||
update tb_proxy set status = 1 where status = 0 AND surplus_day = 0
|
||||
</update>
|
||||
</mapper>
|
Loading…
Reference in New Issue