Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
f2cd523
refactor: rename project package to himarket
learnerjohn Dec 10, 2025
190a3af
feat: support Higress gateway IP for Model and MCP
learnerjohn Dec 10, 2025
834cbfd
fix: resolve issue where Model cannot use MCP in Higress
learnerjohn Dec 10, 2025
570869e
docs: add user guide and update README with PR guidelines
learnerjohn Dec 10, 2025
750848d
Merge remote-tracking branch 'upstream/main' into himarket_202512
learnerjohn Dec 10, 2025
9e6c5be
fix: developer consumer config and docs update
learnerjohn Dec 10, 2025
061ad1e
style: format code with spotless
learnerjohn Dec 10, 2025
96e2a61
merge
learnerjohn Dec 11, 2025
8497489
Merge remote-tracking branch 'upstream/main' into himarket_202512
learnerjohn Dec 11, 2025
1f17d1d
Merge remote-tracking branch 'upstream/main' into himarket_202512
learnerjohn Dec 11, 2025
07c092b
fix: correct branding to HiMarket and fix gateway address port handli…
learnerjohn Dec 12, 2025
8c5ed3c
Merge remote-tracking branch 'upstream/main' into himarket_202512
learnerjohn Dec 12, 2025
ad2caf6
fix: resolve MCP tools and Product config problems, optimize higress …
learnerjohn Dec 15, 2025
08447a1
merge
learnerjohn Dec 17, 2025
dbf19b8
Merge remote-tracking branch 'upstream/main' into himarket_product
learnerjohn Dec 17, 2025
19bee45
fix: extend request timeout to resolve MCP listTools timeout and add …
learnerjohn Dec 21, 2025
9991e4c
fix: Update image source in README
learnerjohn Dec 22, 2025
7f693ec
refactor: standardize code comments and improve consistency
learnerjohn Dec 22, 2025
2dca80b
fix: resolve product icon rendering issue and add missing port displa…
learnerjohn Dec 22, 2025
0a91d1e
merge
learnerjohn Dec 24, 2025
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ build/

/front-auth-app

package-lock.json
package-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

package com.alibaba.himarket.config;

import com.alibaba.himarket.core.security.DeveloperAuthenticationProvider;
import com.alibaba.himarket.core.security.JwtAuthenticationFilter;
import jakarta.servlet.DispatcherType;
import java.util.Collections;
Expand All @@ -33,23 +32,21 @@
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

/** Spring Security安全配置,集成JWT认证与接口权限控制,支持管理员和开发者多用户体系 */
@Configuration
@RequiredArgsConstructor
@Slf4j
@EnableMethodSecurity
public class SecurityConfig {

private final DeveloperAuthenticationProvider developerAuthenticationProvider;

// Auth相关
// Auth endpoints
private static final String[] AUTH_WHITELIST = {
"/admins/init",
"/admins/need-init",
Expand All @@ -65,43 +62,42 @@ public class SecurityConfig {
"/developers/oauth2/token"
};

// Swagger API文档相关
// Swagger endpoints
private static final String[] SWAGGER_WHITELIST = {
"/portal/swagger-ui.html", "/portal/swagger-ui/**", "/portal/v3/api-docs/**"
};

// 系统路径白名单
// System endpoints
private static final String[] SYSTEM_WHITELIST = {"/favicon.ico", "/error"};

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors(Customizer.withDefaults())
.csrf(csrf -> csrf.disable())
.csrf(AbstractHttpConfigurer::disable)
.sessionManagement(
session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(
auth ->
auth
// 异步分发不进行权限检查(解决SSE等流式响应完成后的AccessDenied问题)
// Permit async dispatch for SSE/streaming
.dispatcherTypeMatchers(DispatcherType.ASYNC)
.permitAll()
// OPTIONS请求放行
// Permit OPTIONS
.requestMatchers(HttpMethod.OPTIONS, "/**")
.permitAll()
// 认证相关接口放行
// Permit auth endpoints
.requestMatchers(AUTH_WHITELIST)
.permitAll()
// Swagger相关接口放行
// Permit Swagger endpoints
.requestMatchers(SWAGGER_WHITELIST)
.permitAll()
// 系统路径放行
// Permit system endpoints
.requestMatchers(SYSTEM_WHITELIST)
.permitAll()
.anyRequest()
.authenticated())
.addFilterBefore(
new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.authenticationProvider(developerAuthenticationProvider);
new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
return http.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ public class WebMvcConfig {
public PageableHandlerMethodArgumentResolver pageableResolver() {
PageableHandlerMethodArgumentResolver resolver =
new PageableHandlerMethodArgumentResolver();
// 默认分页和排序
// Default page size is 100
resolver.setFallbackPageable(
PageRequest.of(0, 100, Sort.by(Sort.Direction.DESC, "createAt")));
// 页码从1开始
// Page index starts from 1
resolver.setOneIndexedParameters(true);
return resolver;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ protected void doFilterInternal(
}

log.debug(
"域名解析调试 - Origin: {}, Host: {}, X-Forwarded-Host: {}, ServerName: {},"
+ " X-Real-IP: {}, X-Forwarded-For: {}",
"Domain resolution - Origin: {}, Host: {}, X-Forwarded-Host: {}, ServerName:"
+ " {}, X-Real-IP: {}, X-Forwarded-For: {}",
origin,
host,
xForwardedHost,
Expand All @@ -74,9 +74,11 @@ protected void doFilterInternal(
xForwardedFor);

if (domain == null) {
// 优先使用Host头,如果没有则使用ServerName
// Priority:
// 1. Use Host header if available
// 2. Fallback to ServerName if Host header is missing
if (host != null && !host.isEmpty()) {
domain = host.split(":")[0]; // 去掉端口号
domain = host.split(":")[0];
} else {
domain = request.getServerName();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ public T convertToEntityAttribute(String dbData) {

@SuppressWarnings("unchecked")
private T cloneAndEncrypt(T original) {
// Clone避免JPA更新数据
// T cloned = JSONUtil.toBean(JSONUtil.toJsonStr(original), type);
// Clone to avoid automatic database updates through JPA persistence
T cloned =
original instanceof List
? (T) new ArrayList<>((List<?>) original)
Expand Down Expand Up @@ -101,7 +100,7 @@ private void handleEncryption(Object obj, boolean isEncrypt) {
return;
}

// 处理需要加密/解密的字段
// Process fields that require encryption/decryption
if (field.isAnnotationPresent(Encrypted.class) && value instanceof String) {
String result =
isEncrypt
Expand Down
52 changes: 39 additions & 13 deletions himarket-dal/src/main/java/com/alibaba/himarket/entity/Chat.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,57 +45,83 @@ public class Chat extends BaseEntity {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

/** Chat ID */
/**
* Chat ID
*/
@Column(name = "chat_id", nullable = false, unique = true, length = 64)
private String chatId;

/** Session ID */
/**
* Session ID
*/
@Column(name = "session_id", nullable = false, length = 64)
private String sessionId;

/** User ID */
/**
* User ID
*/
@Column(name = "user_id", nullable = false, length = 64)
private String userId;

/** Conversation ID (Chat group ID) */
/**
* Conversation ID (Chat group ID)
*/
@Column(name = "conversation_id", nullable = false, length = 64)
private String conversationId;

/** Chat status: INIT/PROCESSING/SUCCESS/FAILED */
/**
* Chat status: INIT/PROCESSING/SUCCESS/FAILED
*/
@Column(name = "status", length = 32)
@Enumerated(EnumType.STRING)
private ChatStatus status = ChatStatus.INIT;

/** Product ID */
/**
* Product ID
*/
@Column(name = "product_id", length = 64)
private String productId;

/** Question ID */
/**
* Question ID
*/
@Column(name = "question_id", length = 64)
private String questionId;

/** Question */
/**
* Question
*/
@Column(name = "question", columnDefinition = "text")
private String question;

/** Multi-modal content */
/**
* Multi-modal content
*/
@Column(name = "attachments", columnDefinition = "json")
@Convert(converter = ListJsonConverter.class)
private List<ChatAttachmentConfig> attachments;

/** Answer ID */
/**
* Answer ID
*/
@Column(name = "answer_id", length = 64)
private String answerId;

/** Answer from product */
/**
* Answer from product
*/
@Column(name = "answer", columnDefinition = "longtext")
private String answer;

/** The index of the question submitted */
/**
* The index of the question submitted
*/
@Column(name = "sequence", columnDefinition = "int DEFAULT 0")
private Integer sequence;

/** Usage */
/**
* Usage
*/
@Column(name = "chat_usage", columnDefinition = "json")
@Convert(converter = ChatUsageConverter.class)
private ChatUsage chatUsage;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,33 +41,47 @@ public class ChatAttachment extends BaseEntity {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

/** Attachment ID */
/**
* Attachment ID
*/
@Column(name = "attachment_id", nullable = false, unique = true, length = 64)
private String attachmentId;

/** User ID */
/**
* User ID
*/
@Column(name = "user_id", nullable = false, length = 64)
private String userId;

/** Attachment name */
/**
* Attachment name
*/
@Column(name = "name", length = 255)
private String name;

/** Attachment type, IMAGE/VIDEO/DOCUMENT */
/**
* Attachment type, IMAGE/VIDEO/DOCUMENT
*/
@Column(name = "type", nullable = false, length = 32)
@Enumerated(EnumType.STRING)
private ChatAttachmentType type;

/** MIME type */
/**
* MIME type
*/
@Column(name = "mime_type", length = 64)
private String mimeType;

/** Size */
/**
* Size
*/
@Column(name = "size", columnDefinition = "bigint")
@ColumnDefault("0")
private Long size;

/** Raw data */
/**
* Raw data
*/
@Column(name = "data", columnDefinition = "mediumblob")
private byte[] data;
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,27 @@ public class ChatSession extends BaseEntity {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

/** Session ID */
/**
* Session ID
*/
@Column(name = "session_id", nullable = false, unique = true, length = 64)
private String sessionId;

/** User ID */
/**
* User ID
*/
@Column(name = "user_id", nullable = false, length = 64)
private String userId;

/** Session name */
/**
* Session name
*/
@Column(name = "name", length = 255)
private String name;

/** Product IDs, support multiple products */
/**
* Product IDs, support multiple products
*/
@Column(name = "products", length = 255)
@Convert(converter = ListJsonConverter.class)
private List<String> products;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;

/** 管理员数据访问接口,提供管理员相关的数据库操作 */
public interface AdministratorRepository extends JpaRepository<Administrator, Long> {
Optional<Administrator> findByAdminId(String adminId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,20 @@
import org.springframework.lang.NonNull;

/**
* 基础数据访问接口,提供通用的数据库操作方法
* Base data access interface that provides common database operations
*
* @param <D> 实体类型(Domain/Entity)
* @param <I> 主键类型(ID)
* @param <D> Domain/Entity type
* @param <I> ID type (Primary key)
*/
@NoRepositoryBean
public interface BaseRepository<D, I> extends JpaRepository<D, I>, JpaSpecificationExecutor<D> {

/**
* 根据ID集合批量查询实体列表
* Batch query entities by collection of IDs
*
* @param ids
* @param sort
* @return
* @param ids Collection of entity IDs
* @param sort Sort criteria
* @return List of entities
*/
List<D> findAllByIdIn(@NonNull Collection<I> ids, @NonNull Sort sort);
}
Loading
Loading