init
This commit is contained in:
parent
628d9c9567
commit
16bb8fac3f
@ -0,0 +1,39 @@
|
||||
package top.biwin.xinayu.common.dto.request;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2026-01-29 23:58
|
||||
*/
|
||||
@Data
|
||||
public class AiSettingRequest {
|
||||
|
||||
@JsonProperty("ai_enabled")
|
||||
private Boolean aiEnabled;
|
||||
|
||||
@JsonProperty("api_key")
|
||||
private String apiKey;
|
||||
|
||||
@JsonProperty("base_url")
|
||||
private String baseUrl;
|
||||
|
||||
@JsonProperty("custom_prompts")
|
||||
private String customPrompts;
|
||||
|
||||
@JsonProperty("max_bargain_rounds")
|
||||
private Integer maxBargainRounds;
|
||||
|
||||
@JsonProperty("max_discount_amount")
|
||||
private Integer maxDiscountAmount;
|
||||
|
||||
@JsonProperty("max_discount_percent")
|
||||
private Integer maxDiscountPercent;
|
||||
|
||||
@JsonProperty("model_name")
|
||||
private String modelName;
|
||||
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package top.biwin.xianyu.core.entity;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
@ -17,37 +18,48 @@ public class AiReplySettingEntity {
|
||||
|
||||
@Id
|
||||
@Column(name = "goofish_id")
|
||||
@JsonProperty("goofish_id")
|
||||
private String goofishId;
|
||||
|
||||
@Column(name = "ai_enabled")
|
||||
@JsonProperty("ai_enabled")
|
||||
private Boolean aiEnabled = false;
|
||||
|
||||
@Column(name = "model_name")
|
||||
@JsonProperty("model_name")
|
||||
private String modelName = "qwen-plus";
|
||||
|
||||
@Column(name = "api_key")
|
||||
@JsonProperty("api_key")
|
||||
private String apiKey;
|
||||
|
||||
@Column(name = "base_url")
|
||||
@JsonProperty("base_url")
|
||||
private String baseUrl = "https://dashscope.aliyuncs.com/compatible-mode/v1";
|
||||
|
||||
@Column(name = "max_discount_percent")
|
||||
@JsonProperty("max_discount_percent")
|
||||
private Integer maxDiscountPercent = 10;
|
||||
|
||||
@Column(name = "max_discount_amount")
|
||||
@JsonProperty("max_discount_amount")
|
||||
private Integer maxDiscountAmount = 100;
|
||||
|
||||
@Column(name = "max_bargain_rounds")
|
||||
@JsonProperty("max_bargain_rounds")
|
||||
private Integer maxBargainRounds = 3;
|
||||
|
||||
@Column(name = "custom_prompts", columnDefinition = "TEXT")
|
||||
@JsonProperty("custom_prompts")
|
||||
private String customPrompts;
|
||||
|
||||
@CreationTimestamp
|
||||
@Column(name = "created_at", updatable = false)
|
||||
@JsonProperty("created_at")
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@UpdateTimestamp
|
||||
@Column(name = "updated_at")
|
||||
@JsonProperty("updated_at")
|
||||
private LocalDateTime updatedAt;
|
||||
}
|
||||
|
||||
@ -2,8 +2,12 @@ package top.biwin.xianyu.core.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import top.biwin.xianyu.core.entity.AdminUserEntity;
|
||||
import top.biwin.xianyu.core.entity.AiReplySettingEntity;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface AiReplySettingRepository extends JpaRepository<AiReplySettingEntity, String> {
|
||||
|
||||
}
|
||||
|
||||
@ -85,6 +85,11 @@ public class HttpClientConfig {
|
||||
*/
|
||||
@Bean
|
||||
public ObjectMapper objectMapper() {
|
||||
return new ObjectMapper();
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
// 注册 JavaTimeModule 以支持 Java 8 时间类型 (LocalDateTime 等)
|
||||
mapper.registerModule(new com.fasterxml.jackson.datatype.jsr310.JavaTimeModule());
|
||||
// 禁用将日期写为时间戳,使其序列化为 ISO 格式字符串
|
||||
mapper.disable(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||
return mapper;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,13 @@
|
||||
package top.biwin.xinayu.server.controller;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.bean.copier.CopyOptions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
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;
|
||||
import top.biwin.xianyu.core.entity.AiReplySettingEntity;
|
||||
@ -12,6 +16,7 @@ import top.biwin.xianyu.core.entity.KeywordEntity;
|
||||
import top.biwin.xianyu.core.repository.AiReplySettingRepository;
|
||||
import top.biwin.xianyu.core.repository.GoofishAccountRepository;
|
||||
import top.biwin.xianyu.core.repository.KeywordRepository;
|
||||
import top.biwin.xinayu.common.dto.request.AiSettingRequest;
|
||||
import top.biwin.xinayu.common.dto.response.KeywordResponse;
|
||||
|
||||
import java.util.List;
|
||||
@ -47,6 +52,26 @@ public class KeywordController {
|
||||
return ResponseEntity.ok(settings.stream().collect(Collectors.toMap(AiReplySettingEntity::getGoofishId, s -> s)));
|
||||
}
|
||||
|
||||
@GetMapping("/ai-reply-settings/{accountId}")
|
||||
public ResponseEntity<AiReplySettingEntity> getAiSetting(@PathVariable String accountId) {
|
||||
return ResponseEntity.ok(aiReplySettingRepository.findById(accountId).orElse(null));
|
||||
}
|
||||
|
||||
@PutMapping("/ai-reply-settings/{accountId}")
|
||||
public ResponseEntity<AiReplySettingEntity> upsertAiSetting(@PathVariable String accountId, @RequestBody AiSettingRequest request) {
|
||||
// Upsert 逻辑:存在则更新,不存在则创建
|
||||
AiReplySettingEntity entity = aiReplySettingRepository.findById(accountId)
|
||||
.orElseGet(() -> {
|
||||
// 不存在时创建新实体
|
||||
AiReplySettingEntity newEntity = new AiReplySettingEntity();
|
||||
newEntity.setGoofishId(accountId);
|
||||
return newEntity;
|
||||
});
|
||||
// 忽略 null 值,防止前端未传的字段覆盖已有值或默认值
|
||||
BeanUtil.copyProperties(request, entity, CopyOptions.create().setIgnoreNullValue(true));
|
||||
return ResponseEntity.ok(aiReplySettingRepository.save(entity));
|
||||
}
|
||||
|
||||
@GetMapping("/keywords-with-item-id/{gid}")
|
||||
public ResponseEntity<List<KeywordResponse>> getKeywordsWithItemId(@PathVariable Long gid) {
|
||||
|
||||
|
||||
@ -1,17 +1,11 @@
|
||||
package top.biwin.xinayu.server.exception;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import top.biwin.xinayu.common.dto.response.BaseResponse;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 全局异常处理器
|
||||
* 统一处理认证授权相关的异常,返回友好的 JSON 错误响应
|
||||
@ -34,23 +28,25 @@ import java.util.Map;
|
||||
* @author wangli
|
||||
* @since 2026-01-21
|
||||
*/
|
||||
@Slf4j
|
||||
@RestControllerAdvice
|
||||
public class AuthenticationExceptionHandler {
|
||||
|
||||
/**
|
||||
* 处理未知异常
|
||||
* <p>
|
||||
* 触发场景:
|
||||
* - 其他未被捕获的异常
|
||||
*
|
||||
* @param ex 异常对象
|
||||
* @return ResponseEntity<BaseResponse> 错误响应
|
||||
*/
|
||||
@ExceptionHandler(Exception.class)
|
||||
public ResponseEntity<BaseResponse> handleException(Exception ex) {
|
||||
return ResponseEntity.ok(BaseResponse.builder()
|
||||
.success(false)
|
||||
.message(ex.getMessage())
|
||||
.build());
|
||||
}
|
||||
/**
|
||||
* 处理未知异常
|
||||
* <p>
|
||||
* 触发场景:
|
||||
* - 其他未被捕获的异常
|
||||
*
|
||||
* @param ex 异常对象
|
||||
* @return ResponseEntity<BaseResponse> 错误响应
|
||||
*/
|
||||
@ExceptionHandler(Exception.class)
|
||||
public ResponseEntity<BaseResponse> handleException(Exception ex) {
|
||||
log.error("发生异常:{}", ex.getMessage(), ex);
|
||||
return ResponseEntity.ok(BaseResponse.builder()
|
||||
.success(false)
|
||||
.message(ex.getMessage())
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user