init
This commit is contained in:
parent
3254a34675
commit
f020343856
@ -0,0 +1,17 @@
|
||||
package top.biwin.xinayu.common.dto.request;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2026-02-05 23:39
|
||||
*/
|
||||
@Data
|
||||
public class ProductBatchDeleteRequest {
|
||||
private List<ProductDeleteRequest> items;
|
||||
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package top.biwin.xinayu.common.dto.request;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2026-02-05 23:53
|
||||
*/
|
||||
@Data
|
||||
public class ProductDeleteRequest {
|
||||
@JsonProperty("goofish_id")
|
||||
private String goofishId;
|
||||
@JsonProperty("item_id")
|
||||
private String goofishProductId;
|
||||
}
|
||||
@ -18,4 +18,10 @@ import lombok.experimental.SuperBuilder;
|
||||
public class BaseResponse {
|
||||
private String message;
|
||||
private Boolean success;
|
||||
private Object data;
|
||||
|
||||
public BaseResponse(String message, Boolean success) {
|
||||
this.message = message;
|
||||
this.success = success;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
package top.biwin.xinayu.common.dto.response;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2026-02-05 23:41
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@SuperBuilder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class BatchDeleteResponse extends BaseResponse {
|
||||
private Integer count;
|
||||
}
|
||||
@ -14,4 +14,8 @@ public interface ProductRepository extends JpaRepository<ProductEntity, Long> {
|
||||
List<ProductEntity> findByGoofishId(String goofishId);
|
||||
|
||||
Optional<ProductEntity> findByGoofishIdAndGoofishProductId(String goofishId, String itemId);
|
||||
|
||||
void deleteByGoofishIdAndGoofishProductIdIn(String goofishId, List<String> itemIds);
|
||||
|
||||
void deleteByGoofishIdAndGoofishProductId(String goofishId, String itemId);
|
||||
}
|
||||
|
||||
@ -24,6 +24,19 @@ public abstract class GoofishAbstractApi<T> implements GoofishApi<T> {
|
||||
return apiHostUrl + getApi() + "/" + getVersion() + "/?";
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract String getApi();
|
||||
|
||||
protected final Map<String, String> buildHeaderMap(String cookieStr) {
|
||||
Map<String, String> headerMap = new HashMap<>();
|
||||
headerMap.put("Cookie", cookieStr);
|
||||
headerMap.put("content-type", "application/x-www-form-urlencoded");
|
||||
headerMap.put("priority", "u=1, i");
|
||||
headerMap.put("dnt", "1");
|
||||
headerMap.put("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36 Edg/143.0.0.0");
|
||||
return headerMap;
|
||||
}
|
||||
|
||||
protected Map<String, String> buildQueryParams(String cookieStr, String dataStr, Map<String, String> overrideMap) {
|
||||
Map<String, String> api_query_params = new HashMap<>();
|
||||
api_query_params.put("jsv", "2.7.2");
|
||||
@ -36,7 +49,7 @@ public abstract class GoofishAbstractApi<T> implements GoofishApi<T> {
|
||||
api_query_params.put("accountSite", "xianyu");
|
||||
api_query_params.put("dataType", "json");
|
||||
api_query_params.put("timeout", "20000");
|
||||
api_query_params.put("api", "");
|
||||
api_query_params.put("api", getApi());
|
||||
api_query_params.put("sessionOption", "AutoLoginOnly");
|
||||
api_query_params.put("spm_cnt", "a21ybx.account.0.0");
|
||||
|
||||
|
||||
@ -10,8 +10,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import top.biwin.xianyu.goofish.api.GoofishAbstractApi;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -39,18 +37,15 @@ public class GetAccountApi extends GoofishAbstractApi<String> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String call(String goofishId, String cookieStr, Map<String,Object> data) {
|
||||
public String call(String goofishId, String cookieStr, Map<String, Object> data) {
|
||||
String dataStr = JSONUtil.toJsonStr(data);
|
||||
String apiUrl = buildApiUrl() + HttpUtil.toParams(buildQueryParams(cookieStr, dataStr));
|
||||
log.debug("【{}】获取账号名 ApiUrl: {}", goofishId, apiUrl);
|
||||
log.debug("【{}】获取账号名时使用的 Cookie 为: {}", goofishId, cookieStr);
|
||||
|
||||
try (HttpResponse response = HttpRequest.post(apiUrl)
|
||||
.header("Cookie", cookieStr)
|
||||
.header("content-type", "application/x-www-form-urlencoded")
|
||||
.header("priority", "u=1, i")
|
||||
.header("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36 Edg/143.0.0.0")
|
||||
.body("data=" + URLEncoder.encode(dataStr, StandardCharsets.UTF_8))
|
||||
.headerMap(buildHeaderMap(cookieStr), true)
|
||||
.form("data", dataStr)
|
||||
.execute()) {
|
||||
String body = response.body();
|
||||
log.info("【{}】获取账号名时,服务端返回的完整响应为: {}", goofishId, body);
|
||||
|
||||
@ -16,8 +16,6 @@ import top.biwin.xianyu.core.repository.ProductRepository;
|
||||
import top.biwin.xianyu.goofish.api.GoofishAbstractApi;
|
||||
import top.biwin.xinayu.common.dto.response.GetRemoteProductApiVo;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -93,12 +91,9 @@ public class GetAllItemsApi extends GoofishAbstractApi<GetRemoteProductApiVo> {
|
||||
log.debug("【{}】获取闲鱼商品数据时使用的 Cookie 为: {}", goofishId, cookieStr);
|
||||
|
||||
try (HttpResponse response = HttpRequest.post(apiUrl)
|
||||
.header("Cookie", cookieStr)
|
||||
.header("content-type", "application/x-www-form-urlencoded")
|
||||
.header("priority", "u=1, i")
|
||||
.headerMap(buildHeaderMap(cookieStr), true)
|
||||
.header("dnt", "1")
|
||||
.header("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36 Edg/143.0.0.0")
|
||||
.body("data=" + URLEncoder.encode(dataStr, StandardCharsets.UTF_8))
|
||||
.form("data", dataStr)
|
||||
.execute()) {
|
||||
String body = response.body();
|
||||
log.info("【{}】获取闲鱼商品数据时,服务端返回的完整响应为: {}", goofishId, body);
|
||||
|
||||
@ -10,8 +10,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import top.biwin.xianyu.goofish.api.GoofishAbstractApi;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -39,18 +37,15 @@ public class GetDisplayNameApi extends GoofishAbstractApi<String> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String call(String goofishId, String cookieStr, Map<String,Object> data) {
|
||||
public String call(String goofishId, String cookieStr, Map<String, Object> data) {
|
||||
String dataStr = JSONUtil.toJsonStr(data);
|
||||
String apiUrl = buildApiUrl() + HttpUtil.toParams(buildQueryParams(cookieStr, dataStr));
|
||||
log.debug("【{}】获取闲鱼昵称 ApiUrl: {}", goofishId, apiUrl);
|
||||
log.debug("【{}】获取闲鱼昵称时使用的 Cookie 为: {}", goofishId, cookieStr);
|
||||
|
||||
try (HttpResponse response = HttpRequest.post(apiUrl)
|
||||
.header("Cookie", cookieStr)
|
||||
.header("content-type", "application/x-www-form-urlencoded")
|
||||
.header("priority", "u=1, i")
|
||||
.header("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36 Edg/143.0.0.0")
|
||||
.body("data=" + URLEncoder.encode(dataStr, StandardCharsets.UTF_8))
|
||||
.headerMap(buildHeaderMap(cookieStr), true)
|
||||
.form("data", dataStr)
|
||||
.execute()) {
|
||||
String body = response.body();
|
||||
log.info("【{}】获取闲鱼昵称时,服务端返回的完整响应为: {}", goofishId, body);
|
||||
|
||||
@ -11,8 +11,6 @@ import org.springframework.stereotype.Component;
|
||||
import top.biwin.xianyu.goofish.api.GoofishAbstractApi;
|
||||
import top.biwin.xinayu.common.dto.response.GetRemoteProductDescApiVo;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -49,12 +47,9 @@ public class GetItemDescApi extends GoofishAbstractApi<GetRemoteProductDescApiVo
|
||||
log.debug("【{}】获取闲鱼商品详情数据时使用的 Cookie 为: {}", goofishId, cookieStr);
|
||||
|
||||
try (HttpResponse response = HttpRequest.post(apiUrl)
|
||||
.header("Cookie", cookieStr)
|
||||
.header("content-type", "application/x-www-form-urlencoded")
|
||||
.header("priority", "u=1, i")
|
||||
.headerMap(buildHeaderMap(cookieStr), true)
|
||||
.header("dnt", "1")
|
||||
.header("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36 Edg/143.0.0.0")
|
||||
.body("data=" + URLEncoder.encode(dataStr, StandardCharsets.UTF_8))
|
||||
.form("data", dataStr)
|
||||
.execute()) {
|
||||
String body = response.body();
|
||||
log.info("【{}】获取闲鱼商品详情数据时,服务端返回的完整响应为: {}", goofishId, body);
|
||||
|
||||
@ -10,8 +10,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import top.biwin.xianyu.goofish.api.GoofishAbstractApi;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -39,18 +37,19 @@ public class GetUserIdApi extends GoofishAbstractApi<Long> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long call(String goofishId, String cookieStr, Map<String,Object> data) {
|
||||
public Long call(String goofishId, String cookieStr, Map<String, Object> data) {
|
||||
String dataStr = JSONUtil.toJsonStr(data);
|
||||
String apiUrl = buildApiUrl() + HttpUtil.toParams(buildQueryParams(cookieStr, dataStr));
|
||||
// 主人,要把 data 内容也塞进 URL 参数列表里计算并传递哦!
|
||||
Map<String, String> queryParams = buildQueryParams(cookieStr, dataStr);
|
||||
// TODO: 请在这里将 dataStr 放入 queryParams 变量中:queryParams.put("data", dataStr);
|
||||
queryParams.put("data", dataStr);
|
||||
String apiUrl = buildApiUrl() + HttpUtil.toParams(queryParams);
|
||||
log.debug("【{}】获取闲鱼用户 ID ApiUrl: {}", goofishId, apiUrl);
|
||||
log.debug("【{}】获取闲鱼用户 ID 时使用的 Cookie 为: {}", goofishId, cookieStr);
|
||||
|
||||
try (HttpResponse response = HttpRequest.post(apiUrl)
|
||||
.header("Cookie", cookieStr)
|
||||
.header("content-type", "application/x-www-form-urlencoded")
|
||||
.header("priority", "u=1, i")
|
||||
.header("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36 Edg/143.0.0.0")
|
||||
.body("data=" + URLEncoder.encode(dataStr, StandardCharsets.UTF_8))
|
||||
.headerMap(buildHeaderMap(cookieStr), true)
|
||||
.form("data", dataStr)
|
||||
.execute()) {
|
||||
String body = response.body();
|
||||
log.info("【{}】获取闲鱼用户 ID 时,服务端返回的完整响应为: {}", goofishId, body);
|
||||
|
||||
@ -10,8 +10,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import top.biwin.xianyu.goofish.api.GoofishAbstractApi;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -39,30 +37,27 @@ public class GetWsTokenApi extends GoofishAbstractApi<String> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String call(String goofishId, String cookieStr, Map<String,Object> data) {
|
||||
public String call(String goofishId, String cookieStr, Map<String, Object> data) {
|
||||
String dataStr = JSONUtil.toJsonStr(data);
|
||||
String apiUrl = buildApiUrl() + HttpUtil.toParams(buildQueryParams(cookieStr, dataStr));
|
||||
log.debug("【{}】获取闲鱼 WebSocket Token ApiUrl: {}", goofishId, apiUrl);
|
||||
log.debug("【{}】获取闲鱼 WebSocket Token 时使用的 Cookie 为: {}", goofishId, cookieStr);
|
||||
|
||||
try (HttpResponse response = HttpRequest.post(apiUrl)
|
||||
.header("Cookie", cookieStr)
|
||||
.header("content-type", "application/x-www-form-urlencoded")
|
||||
.header("priority", "u=1, i")
|
||||
.header("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36 Edg/143.0.0.0")
|
||||
.body("data=" + URLEncoder.encode(dataStr, StandardCharsets.UTF_8))
|
||||
.headerMap(buildHeaderMap(cookieStr), true)
|
||||
.form("data", dataStr)
|
||||
.execute()) {
|
||||
String body = response.body();
|
||||
log.info("【{}】获取闲鱼 WebSocket Token 时,服务端返回的完整响应为: {}", goofishId, body);
|
||||
|
||||
JSONObject resJson = JSONUtil.parseObj(body);
|
||||
// 检查是否需要滑块验证
|
||||
// 检查是否需要滑块验证
|
||||
if (needsCaptchaVerification(resJson)) {
|
||||
log.warn("【{}】检测到滑块验证要求,需要刷新Cookie", goofishId);
|
||||
return null;
|
||||
}
|
||||
|
||||
// 检查响应
|
||||
// 检查响应
|
||||
if (resJson.containsKey("ret")) {
|
||||
JSONArray retArray = resJson.getJSONArray("ret");
|
||||
for (int i = 0; i < retArray.size(); i++) {
|
||||
|
||||
@ -8,6 +8,7 @@ import com.microsoft.playwright.Frame;
|
||||
import com.microsoft.playwright.Page;
|
||||
import com.microsoft.playwright.Playwright;
|
||||
import com.microsoft.playwright.options.Cookie;
|
||||
import com.microsoft.playwright.options.LoadState;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -321,8 +322,8 @@ public class BrowserService {
|
||||
page.navigate("https://www.goofish.com/im");
|
||||
log.debug("【{}】等待页面加载,查找登录框... url: http://www.goofish.com/im", goofishId);
|
||||
// 确保页面加载完成
|
||||
page.getByText("登录后可以更懂你,推荐你喜欢的商品!");
|
||||
|
||||
// page.getByText("登录后可以更懂你,推荐你喜欢的商品!");
|
||||
page.waitForLoadState(LoadState.DOMCONTENTLOADED);
|
||||
String cookieStr = buildCookieStr(browserContext);
|
||||
Long goofishUserId = goofishApiService.getUserId(goofishId, cookieStr);
|
||||
if (goofishUserId > 0L) {
|
||||
|
||||
@ -151,8 +151,8 @@ public class GoofishAccountWebsocket extends TextWebSocketHandler {
|
||||
BrowserContext browserContext = browserService.loadPersistentContext(account.getId(), account.getShowBrowser() == 1, 1000D, null);
|
||||
browserService.autoLoginUsingAccountAndPassword(browserContext, account.getUsername(), account.getPassword(), account.getShowBrowser() == 1);
|
||||
this.cookiesStr = buildCookieStr(browserContext);
|
||||
browserContext.close();
|
||||
Long goofishUserId = goofishApiService.getUserId(goofishId, cookiesStr);
|
||||
browserContext.close();
|
||||
if (goofishUserId > 0L) {
|
||||
log.debug("【{}】Cookie 刷新成功", goofishId);
|
||||
} else {
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
package top.biwin.xinayu.server;
|
||||
package top.biwin.xianyu.server;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
|
||||
/**
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.config;
|
||||
package top.biwin.xianyu.server.config;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.config;
|
||||
package top.biwin.xianyu.server.config;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import okhttp3.ConnectionPool;
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.config;
|
||||
package top.biwin.xianyu.server.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@ -16,7 +16,7 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import top.biwin.xinayu.server.security.JwtAuthenticationFilter;
|
||||
import top.biwin.xianyu.server.security.JwtAuthenticationFilter;
|
||||
|
||||
/**
|
||||
* Spring Security 配置类
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.config;
|
||||
package top.biwin.xianyu.server.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -21,7 +21,7 @@ public class ThreadPoolConfig {
|
||||
// 创建定时任务线程池
|
||||
return Executors.newScheduledThreadPool(5, r -> {
|
||||
Thread t = new Thread(r);
|
||||
t.setName("GAWebSocket-" + t.getId());
|
||||
t.setName("Goofish-Account-WebSocket-" + t.getId());
|
||||
t.setDaemon(true);
|
||||
return t;
|
||||
});
|
||||
@ -31,7 +31,7 @@ public class ThreadPoolConfig {
|
||||
public ExecutorService executorService() {
|
||||
return Executors.newSingleThreadExecutor(r -> {
|
||||
Thread t = new Thread(r);
|
||||
t.setName("goofish-item-refresh-" + t.getId());
|
||||
t.setName("Goofish-Item-Refresh-" + t.getId());
|
||||
t.setDaemon(true);
|
||||
return t;
|
||||
});
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.controller;
|
||||
package top.biwin.xianyu.server.controller;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.controller;
|
||||
package top.biwin.xianyu.server.controller;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import top.biwin.xinayu.common.dto.response.FileUploadResponse;
|
||||
import top.biwin.xinayu.server.util.ImageUtils;
|
||||
import top.biwin.xianyu.server.util.ImageUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.controller;
|
||||
package top.biwin.xianyu.server.controller;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
@ -26,19 +26,17 @@ import top.biwin.xinayu.common.dto.response.CheckDefaultPwdResponse;
|
||||
import top.biwin.xinayu.common.dto.response.LoginResponse;
|
||||
import top.biwin.xinayu.common.dto.response.RefreshResponse;
|
||||
import top.biwin.xinayu.common.dto.response.SendCodeResponse;
|
||||
import top.biwin.xinayu.server.security.JwtUtil;
|
||||
import top.biwin.xinayu.server.service.AuthService;
|
||||
import top.biwin.xinayu.server.service.CaptchaService;
|
||||
import top.biwin.xinayu.server.service.EmailVerificationService;
|
||||
import top.biwin.xinayu.server.util.CurrentUserUtil;
|
||||
import top.biwin.xianyu.server.security.JwtUtil;
|
||||
import top.biwin.xianyu.server.service.AuthService;
|
||||
import top.biwin.xianyu.server.service.CaptchaService;
|
||||
import top.biwin.xianyu.server.service.EmailVerificationService;
|
||||
import top.biwin.xianyu.server.util.CurrentUserUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import static java.awt.SystemColor.info;
|
||||
|
||||
/**
|
||||
* 认证控制器
|
||||
* 提供登录、刷新令牌等认证相关的 REST API
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.controller;
|
||||
package top.biwin.xianyu.server.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.controller;
|
||||
package top.biwin.xianyu.server.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
package top.biwin.xinayu.server.controller;
|
||||
package top.biwin.xianyu.server.controller;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import top.biwin.xinayu.server.service.GeetestService;
|
||||
import top.biwin.xianyu.server.service.GeetestService;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.controller;
|
||||
package top.biwin.xianyu.server.controller;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -23,7 +23,7 @@ import top.biwin.xinayu.common.dto.response.BaseResponse;
|
||||
import top.biwin.xinayu.common.dto.response.GoofishAccountResponse;
|
||||
import top.biwin.xinayu.common.dto.response.GoofishQrStatusResponse;
|
||||
import top.biwin.xinayu.common.dto.response.QrLoginResponse;
|
||||
import top.biwin.xinayu.server.util.CurrentUserUtil;
|
||||
import top.biwin.xianyu.server.util.CurrentUserUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.controller;
|
||||
package top.biwin.xianyu.server.controller;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.bean.copier.CopyOptions;
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.controller;
|
||||
package top.biwin.xianyu.server.controller;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -1,13 +1,20 @@
|
||||
package top.biwin.xinayu.server.controller;
|
||||
package top.biwin.xianyu.server.controller;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.bean.copier.CopyOptions;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@ -15,11 +22,14 @@ import top.biwin.xianyu.core.entity.ProductEntity;
|
||||
import top.biwin.xianyu.core.repository.GoofishAccountRepository;
|
||||
import top.biwin.xianyu.core.repository.ProductRepository;
|
||||
import top.biwin.xianyu.goofish.service.GoofishApiService;
|
||||
import top.biwin.xianyu.server.util.CurrentUserUtil;
|
||||
import top.biwin.xinayu.common.dto.request.FetchRemoteAllProductRequest;
|
||||
import top.biwin.xinayu.common.dto.request.ProductBatchDeleteRequest;
|
||||
import top.biwin.xinayu.common.dto.response.BaseResponse;
|
||||
import top.biwin.xinayu.common.dto.response.BatchDeleteResponse;
|
||||
import top.biwin.xinayu.common.dto.response.FetchRemoteAllProductResponse;
|
||||
import top.biwin.xinayu.common.dto.response.GetRemoteProductApiVo;
|
||||
import top.biwin.xinayu.common.dto.response.GetRemoteProductDescApiVo;
|
||||
import top.biwin.xinayu.server.util.CurrentUserUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -76,14 +86,17 @@ public class ProductController {
|
||||
|
||||
GetRemoteProductApiVo vo = goofishApiService.getAllItems(request.getGoofishId(), null);
|
||||
|
||||
// TODO 异步化
|
||||
vo.getItemIds().forEach(itemId -> {
|
||||
// 异步化
|
||||
vo.getItemIds().parallelStream().forEach(itemId -> {
|
||||
executorService.execute(() -> {
|
||||
Optional<ProductEntity> productOpt = productRepository.findByGoofishIdAndGoofishProductId(request.getGoofishId(), itemId);
|
||||
log.debug("【{}】完善【{}】商品的详情信息", request.getGoofishId(), itemId);
|
||||
productOpt.ifPresent(product -> {
|
||||
GetRemoteProductDescApiVo productVo = goofishApiService.getProductDesc(request.getGoofishId(), itemId, null);
|
||||
product.setProductDescription(productVo.getDesc());
|
||||
product.setProductDetail(productVo.getRichTextDesc());
|
||||
product.setProductDetail(productVo.getDesc());
|
||||
product.setProductDescription(productVo.getRichTextDesc());
|
||||
product.setUserId(CurrentUserUtil.getCurrentUserId());
|
||||
log.debug("【{}】商品完整信息为: {}", request.getGoofishId(), JSONUtil.toJsonStr(product));
|
||||
productRepository.saveAndFlush(product);
|
||||
});
|
||||
});
|
||||
@ -97,4 +110,50 @@ public class ProductController {
|
||||
.savedCount(vo.getTotalSaved())
|
||||
.build());
|
||||
}
|
||||
|
||||
@PutMapping("/products/{goofish_id}/{item_id}")
|
||||
public ResponseEntity<BaseResponse> productUpdate(@PathVariable("goofish_id") String goofishId,
|
||||
@PathVariable("item_id") String goofishProductId,
|
||||
@RequestBody ProductEntity productUpdate) {
|
||||
ProductEntity product = productRepository.findByGoofishIdAndGoofishProductId(goofishId, goofishProductId)
|
||||
.orElseThrow(() -> new IllegalArgumentException("商品信息未找到"));
|
||||
BeanUtil.copyProperties(productUpdate, product, CopyOptions.create().setIgnoreNullValue(true));
|
||||
productRepository.save(product);
|
||||
return ResponseEntity.ok(BaseResponse.builder()
|
||||
.success(true)
|
||||
.message("商品已更新")
|
||||
.data(product)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@DeleteMapping("/products/{goofish_id}/{item_id}")
|
||||
public ResponseEntity<BaseResponse> deleteProduct(@PathVariable("goofish_id") String goofishId,
|
||||
@PathVariable("item_id") String goofishProductId) {
|
||||
productRepository.deleteByGoofishIdAndGoofishProductId(goofishId, goofishProductId);
|
||||
return ResponseEntity.ok(BaseResponse.builder()
|
||||
.success(true)
|
||||
.message("商品删除成功")
|
||||
.build());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@DeleteMapping("/products/batch")
|
||||
public ResponseEntity<BatchDeleteResponse> deleteProductBatch(@RequestBody ProductBatchDeleteRequest request) {
|
||||
if (CollectionUtils.isEmpty(request.getItems())) {
|
||||
return ResponseEntity.ok(BatchDeleteResponse.builder()
|
||||
.success(false)
|
||||
.message("缺少商品数据")
|
||||
.build());
|
||||
}
|
||||
|
||||
request.getItems().forEach(i -> {
|
||||
productRepository.deleteByGoofishIdAndGoofishProductId(i.getGoofishId(), i.getGoofishProductId());
|
||||
});
|
||||
return ResponseEntity.ok(BatchDeleteResponse.builder()
|
||||
.success(true)
|
||||
.message("商品批量删除成功")
|
||||
.count(request.getItems().size())
|
||||
.build());
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.controller;
|
||||
package top.biwin.xianyu.server.controller;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.controller.demo;
|
||||
package top.biwin.xianyu.server.controller.demo;
|
||||
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@ -6,7 +6,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import top.biwin.xianyu.core.entity.AdminUserEntity;
|
||||
import top.biwin.xinayu.common.enums.UserRole;
|
||||
import top.biwin.xinayu.server.util.CurrentUserUtil;
|
||||
import top.biwin.xianyu.server.util.CurrentUserUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -1,12 +1,12 @@
|
||||
package top.biwin.xinayu.server.controller.demo;
|
||||
package top.biwin.xianyu.server.controller.demo;
|
||||
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import top.biwin.xinayu.server.security.RequireSuperAdmin;
|
||||
import top.biwin.xinayu.server.util.CurrentUserUtil;
|
||||
import top.biwin.xianyu.server.security.RequireSuperAdmin;
|
||||
import top.biwin.xianyu.server.util.CurrentUserUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.controller.demo;
|
||||
package top.biwin.xianyu.server.controller.demo;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import top.biwin.xianyu.core.entity.AdminUserEntity;
|
||||
import top.biwin.xianyu.core.repository.AdminUserRepository;
|
||||
import top.biwin.xinayu.server.util.CurrentUserUtil;
|
||||
import top.biwin.xianyu.server.util.CurrentUserUtil;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.util.HashMap;
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.exception;
|
||||
package top.biwin.xianyu.server.exception;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.initialization;
|
||||
package top.biwin.xianyu.server.initialization;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.notice;
|
||||
package top.biwin.xianyu.server.notice;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.notice.channel;
|
||||
package top.biwin.xianyu.server.notice.channel;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.security;
|
||||
package top.biwin.xianyu.server.security;
|
||||
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.security;
|
||||
package top.biwin.xianyu.server.security;
|
||||
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.security;
|
||||
package top.biwin.xianyu.server.security;
|
||||
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.service;
|
||||
package top.biwin.xianyu.server.service;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.service;
|
||||
package top.biwin.xianyu.server.service;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -14,7 +14,7 @@ import top.biwin.xianyu.core.repository.AdminUserRepository;
|
||||
import top.biwin.xinayu.common.dto.request.LoginRequest;
|
||||
import top.biwin.xinayu.common.dto.response.LoginResponse;
|
||||
import top.biwin.xinayu.common.dto.response.RefreshResponse;
|
||||
import top.biwin.xinayu.server.security.JwtUtil;
|
||||
import top.biwin.xianyu.server.security.JwtUtil;
|
||||
|
||||
/**
|
||||
* 认证服务
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.service;
|
||||
package top.biwin.xianyu.server.service;
|
||||
|
||||
import cn.hutool.captcha.CaptchaUtil;
|
||||
import cn.hutool.captcha.LineCaptcha;
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.service;
|
||||
package top.biwin.xianyu.server.service;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.service;
|
||||
package top.biwin.xianyu.server.service;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.service;
|
||||
package top.biwin.xianyu.server.service;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.digest.DigestUtil;
|
||||
@ -12,7 +12,7 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import top.biwin.xinayu.server.config.GeetestConfig;
|
||||
import top.biwin.xianyu.server.config.GeetestConfig;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.util;
|
||||
package top.biwin.xianyu.server.util;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.util;
|
||||
package top.biwin.xianyu.server.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package top.biwin.xinayu.server.util;
|
||||
package top.biwin.xianyu.server.util;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
@ -46,6 +46,12 @@ logging:
|
||||
org.hibernate.type.descriptor.sql: INFO # Ensure Hibernate parameter logging is not set to DEBUG/TRACE
|
||||
file:
|
||||
name: logs/backend-java.log
|
||||
# 主人,在这里我们可以为日志格式“扩容”哦!
|
||||
pattern:
|
||||
# TODO: 请在这里配置控制台日志格式,将线程名部分([%t])改为允许更多字符,例如:console: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%25t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"
|
||||
console: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%25t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"
|
||||
# TODO: 请在这里配置日志文件格式,同样将线程名部分改为:file: "%d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } --- [%25t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"
|
||||
file: "%d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } --- [%25t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"
|
||||
|
||||
# JWT 配置
|
||||
jwt:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user