Przeglądaj źródła

Merge branch 'master' of http://git.yangzhiqiang.tech/jiayq/ai-tagging

jianggs 6 dni temu
rodzic
commit
dd39af5a82
39 zmienionych plików z 610 dodań i 196 usunięć
  1. 2 2
      agent/config.ini
  2. BIN
      agent/data/样本数据标注后-完整版.xlsx
  3. BIN
      agent/dist/agent-0.1.5-py3-none-any.whl
  4. BIN
      agent/dist/agent-0.1.5.tar.gz
  5. BIN
      agent/logs/aitagging-app.2026-03-17_10-36-37_002744.log.zip
  6. BIN
      agent/logs/aitagging-app.2026-03-23_14-44-11_403520.log.zip
  7. BIN
      agent/logs/aitagging-app.2026-03-26_18-19-50_023840.log.zip
  8. 1 1
      agent/pyproject.toml
  9. 33 9
      agent/src/agent/api_outter.py
  10. 94 4
      agent/src/agent/core/es.py
  11. 11 0
      agent/src/agent/core/tagging_state.py
  12. 0 48
      agent/tests/load_tag_2_es.py
  13. 19 0
      agent/tests/test_bm25.py
  14. 10 10
      agent/tests/test_inner_api.py
  15. 3 0
      agent/tests/test_state.py
  16. 1 1
      agent/tests/test_sync_category.py
  17. 2 1
      agent/tests/test_tagging.py
  18. 1 0
      agent/tests/test_tagging_batch.py
  19. 17 29
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagApiLogController.java
  20. 14 17
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagAppController.java
  21. 31 39
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagTagCategoryController.java
  22. 77 13
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagTagInfoController.java
  23. 51 6
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagTagLogController.java
  24. 3 9
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/FastApiController.java
  25. 22 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagApiLogDetailDto.java
  26. 23 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagApiLogListDto.java
  27. 17 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagAppListDto.java
  28. 22 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagAppQueryDto.java
  29. 16 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagAppResetSecretDto.java
  30. 17 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagEnabledTagCategoryListDto.java
  31. 16 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagTagCategoryDetailDto.java
  32. 20 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagTagCategoryListDto.java
  33. 16 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagTagCategoryOperationDto.java
  34. 16 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/TagInfoDetailDto.java
  35. 29 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/TagInfoPageDto.java
  36. 16 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/TagLogDetailDto.java
  37. 6 5
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/fastapidto/AiTaggingQueryRequestDto.java
  38. 2 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/vo/AitagTagInfoQueryVo.java
  39. 2 2
      server/yusp-tagging-core/src/main/resources/mapper/AitagTagLogMapper.xml

+ 2 - 2
agent/config.ini

@@ -1,5 +1,5 @@
 [database]
-host = 10.192.72.11  ;数据库地址
+host = 10.192.72.11  
 port = 4321
 user = root
 password = admin
@@ -25,7 +25,7 @@ url = http://10.192.72.13:9200
 [app]
 top_k = 2
 port=9876
-concurrence=3
+concurrence=1
 
 [logging]
 log_path= logs/aitagging-app.log

BIN
agent/data/样本数据标注后-完整版.xlsx


BIN
agent/dist/agent-0.1.5-py3-none-any.whl


BIN
agent/dist/agent-0.1.5.tar.gz


BIN
agent/logs/aitagging-app.2026-03-17_10-36-37_002744.log.zip


BIN
agent/logs/aitagging-app.2026-03-23_14-44-11_403520.log.zip


BIN
agent/logs/aitagging-app.2026-03-26_18-19-50_023840.log.zip


+ 1 - 1
agent/pyproject.toml

@@ -1,6 +1,6 @@
 [project]
 name = "agent"
-version = "0.1.4"
+version = "0.1.5"
 description = "Default template for PDM package"
 authors = [
     {name = "jiayongqiang", email = "15936285643@163.com"},

+ 33 - 9
agent/src/agent/api_outter.py

@@ -16,6 +16,8 @@ import json
 from agent.logger import logger
 from agent.core.config import get_config_path
 import asyncio
+from agent.core.tagging_state import TAGGING_STATE
+import time
 
 config = get_config_path()
 TOP_K = config['app']['top_k']
@@ -31,6 +33,7 @@ class TaggingRequest(BaseModel):
     business_attr: str = Field(..., description="业务属性")
     phrase: str = Field(..., description="需要打标签的文本")
     tag_category_id: Optional[str] = Field(None, description="指定标签类别ID,默认为空表示不指定")
+    esb_seq_no: Optional[str] = Field(None,description="ESB流水号")
 
 async def execute_reg(log_id:str,tag_category_id:str,phrase: str)-> list:
     sql = f"""select 
@@ -73,7 +76,7 @@ def vector_similarity_search(phrase: str, ids:list)-> list:
     results = hybrid_search(ids, query, top_k=TOP_K)
     # return [{"id": r["_id"], "score": r["_score"], "tag_prompt": r["_source"]["tag_prompt"],"tag_name": r["_source"]["tag_name"],"tag_code": r["_source"]["tag_code"]} for r in results]
     r = [{"id": r["_id"], "tag_remark":r["_source"]["tag_remark"], "tag_prompt": r["_source"]["tag_prompt"],"tag_name": r["_source"]["tag_name"],"tag_code": r["_source"]["tag_code"],"tag_path": r["_source"]["tag_path"],"category_id": r["_source"]["category_id"]   } for r in results]
-    logger.info(f"{phrase} Vector search result: {r}")
+    # logger.info(f"{phrase} Vector search result: {r}")
     return r
 
 def init_tag_log(request: TaggingRequest):
@@ -86,20 +89,36 @@ def init_tag_log(request: TaggingRequest):
     # 业务编号如果以test开头,则tag_scope = 1,否则都是0
     tag_scope = 1 if request.business_attr.startswith("test") else 0
     dao.execute(
-        """INSERT INTO aitag_tag_log (id,app_id, insert_time, business_attr, phrase, state, tag_scope) VALUES (%s, %s, %s, %s, %s, %s, %s)""",
-        (id,request.app_id, datetime.now(), request.business_attr, request.phrase, 0, tag_scope)
+        """INSERT INTO aitag_tag_log (id,app_id, insert_time, business_attr, phrase, state, tag_scope,esb_seq_no) VALUES (%s, %s, %s, %s, %s, %s, %s,%s)""",
+        (id,request.app_id, datetime.now(), request.business_attr, request.phrase, TAGGING_STATE.REQUEST.value, tag_scope, request.esb_seq_no)
     )
     return id
 
-def update_tag_log(id:str, result:str):
+def end_tagging(id:str, result:str):
     dao.execute(
             """UPDATE aitag_tag_log SET state = %s, result = %s, ai_result_endtime = %s WHERE id = %s""",
-            (1, result, datetime.now(), id)
+            (TAGGING_STATE.END.value, result, datetime.now(), id)
         )
 
+def fail_tagging(id:str):
+    dao.execute(
+            """UPDATE aitag_tag_log SET state = %s,  ai_result_endtime = %s WHERE id = %s""",
+            (TAGGING_STATE.FAIL.value,  datetime.now(), id)
+        )
+
+def start_tagging(id:str):
+    dao.execute(
+            """UPDATE aitag_tag_log SET state = %s,  ai_result_starttime = %s WHERE id = %s""",
+            (TAGGING_STATE.BEGIN.value, datetime.now(),  id)
+        )
+
+
 async def run_ai_pipeline(log_id: str, tag_category_id: str, phrase: str):
     try:
         async with background_semaphore:
+            logger.info(f"开始打标:{log_id}, {phrase}")
+            # step0: 开始打标
+            start_tagging(log_id)
             # step1: 正则过滤
             result = await execute_reg(log_id,tag_category_id,phrase)
             # step2: 向量检索
@@ -111,17 +130,22 @@ async def run_ai_pipeline(log_id: str, tag_category_id: str, phrase: str):
                 except Exception as e:
                     logger.error(f"LLM reflection check failed: {e}")
                     result = None
+                    fail_tagging(log_id)
+                    return
             # step4: 更新数据库
             # 如果result是个空集合,插入None
-            update_tag_log(log_id, result if result else None)
+            end_tagging(log_id, result if result else None)
             
     except Exception as e:
         logger.error(f"[{log_id}] Pipeline failed: {e}")
-        update_tag_log(log_id, None)
+        fail_tagging(log_id)
+
 
+# 0:请求已接收;1:打标完成; 2:客户经理已经确认;3,结果已推送; 
+# 4:开始打标, 5:打标失败
 @router.post("/tagging")
 async def ai_tagging(request: TaggingRequest,background_tasks: BackgroundTasks):
-    logger.info(f"app_id: {request.app_id}, timestamp: {request.timestamp}, sign: {request.sign}, business_attr: {request.business_attr}, phrase: {request.phrase}")
+    logger.info(f"esb_seq_no: {request.esb_seq_no}, business_attr: {request.business_attr}, phrase: {request.phrase}")
     # 数据库中插入一条记录,记录请求的app_id、timestamp、business_attr、phrase等信息,状态设为“处理中”,后续步骤完成后更新状态和结果
     id = init_tag_log(request)
     # 执行异步任务
@@ -162,7 +186,7 @@ def ai_feedback(feedback_request: FeedbackRequest):
     # 这里将用户的反馈信息保存到数据库中aitag_tag_log,供后续分析和模型优化使用
     dao.execute(
         """update aitag_tag_log set feedback = %s, feedback_result = %s, feedback_time = %s, feedback_user_id = %s, feedback_user_nm = %s, contract_no = %s, feedback_user_org = %s, feedback_user_endpoint = %s, state = %s where business_attr = %s""",   
-        (feedback_request.feedback, feedback_request.feedback_result, datetime.now(), feedback_request.user_id, feedback_request.user_nm, feedback_request.contract_no, feedback_request.user_org, feedback_request.user_endpoint, 2, feedback_request.business_attr)
+        (feedback_request.feedback, feedback_request.feedback_result, datetime.now(), feedback_request.user_id, feedback_request.user_nm, feedback_request.contract_no, feedback_request.user_org, feedback_request.user_endpoint, TAGGING_STATE.FEEDBACK.value, feedback_request.business_attr)
     )
     return {"code": 200, "message": "Feedback received successfully"}
 

+ 94 - 4
agent/src/agent/core/es.py

@@ -3,11 +3,13 @@ from agent.logger import logger
 
 from agent.core.config import get_config_path
 config = get_config_path()
-TOP_K = config['app']['top_k']
+TOP_K = int(config['app']['top_k'])
 
 url = config['es']['url']
 DIMS = int(config['embedding']['default_dims'])
 
+RRF_CONST:int = 60
+
 es = Elasticsearch(
     hosts=[url],
     retry_on_timeout=True,
@@ -19,11 +21,40 @@ INDEX_NAME = "ai-tagging"
 if not es.indices.exists(index=INDEX_NAME):
     es.indices.create(
         index=INDEX_NAME,
+        settings={
+            "index": {
+                "similarity": {
+                    "my_bm25": { 
+                    "type": "BM25",
+                    "b": "0.9",   
+                    "k1": "0.6"   
+                    }
+                },
+                "analysis": {
+                    "analyzer": {
+                        "my_custom_analyzer": {
+                            "type": "custom",
+                            "tokenizer": "standard", 
+                            "filter": [
+                                "lowercase", 
+                                "my_stop_filter" 
+                            ]
+                        }
+                    },
+                    "filter": {
+                        "my_stop_filter": {
+                            "type": "stop",
+                            "stopwords": ["的", "了", "是", "在", "职","业","投","向","海","洋","水"] 
+                        }
+                    }
+                }
+            },
+        },
         mappings={
             "properties": {
                 "tag_code": {"type": "text"},
                 "tag_name": {"type": "text"},
-                "tag_path": {"type": "text"},
+                "tag_path": {"type": "text","similarity": "my_bm25"},
                 "tag_level": {"type": "integer"},
                 "tag_remark": {"type": "text"},
                 "tag_reg": {"type": "text"},
@@ -58,7 +89,8 @@ def delete_category_documents(category_id):
             }
         }
     }
-    es.options(request_timeout=60).delete_by_query(index=INDEX_NAME, body=query)
+    if es.indices.exists(index=INDEX_NAME):
+        es.options(request_timeout=60).delete_by_query(index=INDEX_NAME, body=query)
     
 def search_documents(query):
     response = es.search(
@@ -116,17 +148,75 @@ def hybrid_search( target_doc_ids, query_vector, top_k=2):
             "k": top_k,           # 不超过候选集大小
             "num_candidates": 100
         }
-    print(f"Constructed knn query: {knn}")
+  
     response = es.search(
         index=INDEX_NAME,
         knn=knn
     )
     return response["hits"]["hits"]
 
+def bm25_vector_search(query:str,query_vector,vector_threshold =0.76,rrf_threshold=0.031):
+    resp_bm25 = es.search(
+        index=INDEX_NAME,
+        size=max(TOP_K, 10),
+        query={"match": {"tag_path": query}}
+    )
+    resp_vector = es.search(
+        index=INDEX_NAME,
+        size=max(TOP_K,10),
+        knn={
+            "field": "tag_vector",
+            "query_vector": query_vector,
+            "k": max(TOP_K, 10),
+            "num_candidates": 100
+        }
+    )
+    rrf_scores = {}
+    rrf_scores_data = {}
+    for rank, hit in enumerate(resp_bm25['hits']['hits'], start=1):
+        hit["_source"]["tag_vector"] = None
+        print("a:"+hit["_source"]["tag_path"])
+        doc_id = hit['_id']
+        score = rrf_scores.get(doc_id, 0.0)
+        rrf_scores[doc_id] = score + (1.0 / (RRF_CONST + rank))
+        if doc_id not in rrf_scores_data:
+             rrf_scores_data[doc_id] = hit
+
+    for rank, hit in enumerate(resp_vector['hits']['hits'], start=1):
+        hit["_source"]["tag_vector"] = None
+        print("b:"+hit["_source"]["tag_path"]+";"+str(hit["_score"]))
+        if hit["_score"]>vector_threshold:
+            doc_id = hit['_id']
+            score = rrf_scores.get(doc_id, 0.0)
+            rrf_scores[doc_id] = score + (1.0 / (RRF_CONST + rank))
+            if doc_id not in rrf_scores_data:
+                rrf_scores_data[doc_id] = hit
+            rrf_scores_data[doc_id]['vector_score'] = hit["_score"]
+
+    # 4. 排序并截取 Top K
+    # 按 RRF 分数降序排序
+    sorted_ids = sorted(rrf_scores.items(), key=lambda x: x[1], reverse=True)[:TOP_K]
+    final_results = []
+    for doc_id, score in sorted_ids:
+        hit = rrf_scores_data[doc_id]
+        hit['_score'] = score # 覆盖为计算出的 RRF 分数
+        if 'vector_score' in hit and score>rrf_threshold:
+            final_results.append({
+                'rrf_score':score,
+                'vector_score':hit['vector_score'],
+                'tag_path':hit['_source']['tag_path']
+            })
+        
+    return final_results
+
 if __name__ == "__main__":
     results = search_all()
     for r in results:
         # 排除 tag_vector 字段的输出
         print({k: v for k, v in r["_source"].items() if k != "tag_vector"})
     print(f"Search results: {len(results)}")
+
+
+
+
     

+ 11 - 0
agent/src/agent/core/tagging_state.py

@@ -0,0 +1,11 @@
+# 0:请求已接收;1:打标完成; 2:客户经理已经确认;3,结果已推送; 
+# 4:开始打标, 5:打标失败
+from enum import Enum
+
+class TAGGING_STATE(Enum):
+    REQUEST = 0
+    END = 1
+    FEEDBACK = 2
+    PUSHED = 3
+    BEGIN = 4
+    FAIL = 5

+ 0 - 48
agent/tests/load_tag_2_es.py

@@ -1,48 +0,0 @@
-import agent.core.es as es
-import agent.core.dao as dao
-import numpy as np
-
-if __name__ == "__main__":
-    tags = dao.query("""select 
-                     tti.id,
-                    tti.tag_nm,
-                    tti.tag_code,
-                    tti.tag_remark,
-                    tti.reg,
-                    tti.level,
-                    tti.tag_path,
-                    ttc.category_nm,
-                    ttc.category_code
-                    from fjnx.tab_tag_info tti left join fjnx.tab_tag_category  ttc 
-                    on tti.category_id = ttc.id 
-                    where ttc.is_delete=0 and tti.is_delete=0 and ttc.state =  0 and tti.state = 0 and tti.`level` = ttc.visibility_level""")
-    for tag in tags:
-        tag_id = tag[0]         
-        tag_name = tag[1]
-        tag_code = tag[2]
-        tag_remark = tag[3]
-        tag_reg = tag[4]
-        tag_level = tag[5]
-        tag_path = tag[6]
-        tag_category = tag[7]
-        tag_category_code = tag[8]
-        print(tag_name, tag_code, tag_remark, tag_reg, tag_level, tag_path, tag_category, tag_category_code)
-        # 生成随机向量,实际应用中应使用真实的向量
-        tag_vector = np.random.rand(es.DIMS).tolist()
-        document = {
-            "tag_code": tag_code,
-            "tag_name": tag_name,   
-            "tag_remark": tag_remark,
-            "tag_reg": tag_reg,
-            "tag_level": tag_level,
-            "tag_path": tag_path,   
-            "tag_category": tag_category,
-            "tag_category_code": tag_category_code, 
-            "tag_vector": tag_vector    
-        }
-        es.upsert_document(tag_id, document)
-        print(f"Upserted document with ID {tag_id}")
-        res = es.search_documents({
-            "tag_name": "海水养殖"
-        })
-        print(res)

+ 19 - 0
agent/tests/test_bm25.py

@@ -0,0 +1,19 @@
+from agent.core.es import bm25_vector_search
+from agent.core.vector import get_embeddings
+
+phrase = "渔业产品批发,海带边周转"
+phrase_vector = get_embeddings([phrase])[0]
+r = bm25_vector_search(phrase,phrase_vector)
+print(r)
+# from openpyxl import load_workbook
+# workbook = load_workbook('data/样本数据标注后-完整版.xlsx', data_only=True)
+# sheet = workbook['核对结果'] 
+# for row in sheet.iter_rows(min_row=2,min_col=2, max_col=3, values_only=True):
+#     touxiang = row[0] # B列的值
+#     yongtu = row[1] # C列的值
+#     phrase = f"投向:{touxiang},用途:{yongtu}"
+#     phrase_vector = get_embeddings([phrase])[0]
+#     r = bm25_vector_search(phrase,phrase_vector)
+#     print(f"输入:{phrase}")
+#     print(f"输出:{r}")
+# workbook.close()

+ 10 - 10
agent/tests/test_inner_api.py

@@ -15,7 +15,7 @@ ids = [
 "20260200013",
 "20260200014",
 "20260200015",
-"202602000016",
+"20260200016",
 "20260200017",  
 "20260200018",
 "20260200019",
@@ -85,17 +85,17 @@ ids = [
 "20260200083",
 ]
 
-res = requests.post("http://localhost:9876/api/aitag/admin/v1/synchronize_tag", json={
-    "tag_ids": ids
-})
-print(res.text)
+# res = requests.post("http://localhost:9876/api/aitag/admin/v1/synchronize_tag", json={
+#     "tag_ids": ids
+# })
+# print(res.text)
 
-res = requests.post("http://localhost:9876/api/aitag/admin/v1/delete_tag", json={
-    "tag_ids": ["20260200083"]
-})
-print(res.text)
+# res = requests.post("http://localhost:9876/api/aitag/admin/v1/delete_tag", json={
+#     "tag_ids": ["20260200083"]
+# })
+# print(res.text)
 
-res = requests.post("http://10.192.72.13:9876/api/aitag/admin/v1/synchronize_category", json={
+res = requests.post("http://localhost:9876/api/aitag/admin/v1/synchronize_category", json={
     "category_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
 })
 print(res.text)

+ 3 - 0
agent/tests/test_state.py

@@ -0,0 +1,3 @@
+from agent.core.tagging_state import TAGGING_STATE
+
+print(TAGGING_STATE.REQUEST.value)

+ 1 - 1
agent/tests/test_sync_category.py

@@ -1,6 +1,6 @@
 import requests
 
-res = requests.post("http://10.192.72.13:9876/api/aitag/admin/v1/synchronize_category", json={
+res = requests.post("http://localhost:9876/api/aitag/admin/v1/synchronize_category", json={
     "category_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
 })
 print(res.text)

+ 2 - 1
agent/tests/test_tagging.py

@@ -3,10 +3,11 @@ import logging
 logging.basicConfig(level=logging.INFO, force=True,format='%(asctime)s - %(levelname)s - %(message)s')
 logging.info("app starting!")
 
-res = requests.post("http://10.192.72.13:9876/api/aitag/v1/tagging", json={
+res = requests.post("http://localhost:9876/api/aitag/v1/tagging", json={
     # "app_id": "test_app",
     # "timestamp": 1234567890,
     # "sign": "test_sign",
+    "esb_seq_no":"abc",
     "business_attr": "test_attr",
     "phrase": "职业:水产养殖人员 投向:内陆养殖 用途:养殖鲍鱼"
 })

+ 1 - 0
agent/tests/test_tagging_batch.py

@@ -13,6 +13,7 @@ with open("tests/test_data.txt", "r", encoding="utf-8") as f:
             phrase = "职业:"+phrase[0]+" "+"投向:"+phrase[1]+" "+"用途:"+phrase[2]
 
         res = requests.post("http://10.192.72.13:9876/api/aitag/v1/tagging", json={
+            "esb_seq_no": uuid.uuid4().hex,
             "business_attr": uuid.uuid4().hex,
             "phrase": phrase
         })

+ 17 - 29
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagApiLogController.java

@@ -1,12 +1,15 @@
 package cn.com.yusys.yusp.controller;
 
 import cn.com.yusys.yusp.domain.dto.AitagApiLogQueryDto;
+import cn.com.yusys.yusp.domain.dto.AitagApiLogDetailDto;
+import cn.com.yusys.yusp.domain.dto.AitagApiLogListDto;
 import cn.com.yusys.yusp.domain.entity.AitagApiLog;
 import cn.com.yusys.yusp.domain.vo.AitagApiLogListVo;
 import cn.com.yusys.yusp.model.Result;
 import cn.com.yusys.yusp.service.AitagApiLogService;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import java.text.ParseException;
@@ -24,25 +27,24 @@ public class AitagApiLogController {
     private AitagApiLogService apiLogService;
 
 
-    @GetMapping("/list")
-    public Result<List<AitagApiLogListVo>> listApiLogs(
-            @RequestParam(required = false) String startTime,
-            @RequestParam(required = false) String endTime,
-            @RequestParam(defaultValue = "1") Integer page,
-            @RequestParam(defaultValue = "10") Integer pageSize) {
+    @PostMapping("/list")
+    public Result<List<AitagApiLogListVo>> listApiLogs(@RequestBody AitagApiLogListDto dto) {
         try {
             // 构建查询条件
             AitagApiLogQueryDto queryDTO = new AitagApiLogQueryDto();
-            queryDTO.setPage(page);
-            queryDTO.setPageSize(pageSize);
+            queryDTO.setPage(dto.getPage());
+
+            // 处理 pageSize:如果前端没传,使用默认值 10;否则使用前端传入的值
+            int actualSize = (dto.getPageSize() == null || dto.getPageSize() <= 0) ? 10 : dto.getPageSize();
+            queryDTO.setPageSize(actualSize);
 
             // 处理时间参数 - 只处理日期粒度
-            if (startTime != null && !startTime.isEmpty()) {
-                queryDTO.setStartTime(parseDateOnly(startTime));
+            if (dto.getStartTime() != null && !dto.getStartTime().isEmpty()) {
+                queryDTO.setStartTime(parseDateOnly(dto.getStartTime()));
             }
 
-            if (endTime != null && !endTime.isEmpty()) {
-                queryDTO.setEndTime(parseDateOnly(endTime));
+            if (dto.getEndTime() != null && !dto.getEndTime().isEmpty()) {
+                queryDTO.setEndTime(parseDateOnly(dto.getEndTime()));
             }
 
             Page<AitagApiLogListVo> pageResult = apiLogService.listApiLogs(queryDTO);
@@ -72,24 +74,10 @@ public class AitagApiLogController {
         }
     }
 
-    @GetMapping("/refresh")
-    public Result<List<AitagApiLogListVo>> refreshApiLogs(
-            @RequestParam(defaultValue = "1") Integer page,
-            @RequestParam(defaultValue = "10") Integer pageSize) {
-        try {
-            Page<AitagApiLogListVo> pageResult = apiLogService.refreshApiLogs(page, pageSize);
-            // 直接返回Page对象
-            return Result.pageSuccess(pageResult.getRecords(), pageResult.getTotal());
-        } catch (Exception e) {
-            return Result.error("500", "刷新日志列表失败:" + e.getMessage());
-        }
-    }
-
-
-    @GetMapping("/query/{id}")
-    public Result<AitagApiLog> getApiLogDetail(@PathVariable String id) {
+    @PostMapping("/query")
+    public Result<AitagApiLog> getApiLogDetail(@Validated @RequestBody AitagApiLogDetailDto dto) {
         try {
-            AitagApiLog logDetail = apiLogService.getApiLogDetail(id);
+            AitagApiLog logDetail = apiLogService.getApiLogDetail(dto.getId());
             if (logDetail == null) {
                 return Result.error("404", "日志记录不存在");
             }

+ 14 - 17
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagAppController.java

@@ -1,6 +1,8 @@
 package cn.com.yusys.yusp.controller;
 
-import cn.com.yusys.yusp.annotation.RequireRole;
+import cn.com.yusys.yusp.domain.dto.AitagAppListDto;
+import cn.com.yusys.yusp.domain.dto.AitagAppQueryDto;
+import cn.com.yusys.yusp.domain.dto.AitagAppResetSecretDto;
 import cn.com.yusys.yusp.model.Result;
 import cn.com.yusys.yusp.domain.dto.AitagAppCreateDto;
 import cn.com.yusys.yusp.domain.entity.AitagApp;
@@ -22,14 +24,11 @@ public class AitagAppController {
     private AitagAppService aiTagAppService;
 
     @ApiOperationType("应用列表一览")
-    @RequireRole({"1", "4"})
-    @GetMapping("/list")
-    public Result<List<AitagApp>> listApps(
-            @RequestParam(defaultValue = "1") int page,
-            @RequestParam(defaultValue = "10") int size) {
+    @PostMapping("/list")
+    public Result<List<AitagApp>> listApps(@RequestBody AitagAppListDto dto) {
         try {
             // 分页查询
-            Page<AitagApp> pageResult = aiTagAppService.listApps(page, size);
+            Page<AitagApp> pageResult = aiTagAppService.listApps(dto.getPage(), dto.getPageSize());
 
             // 提取 records 并封装为 Result 对象
             return Result.pageSuccess(pageResult.getRecords(), pageResult.getTotal());
@@ -39,6 +38,7 @@ public class AitagAppController {
     }
 
 
+
     @ApiOperationType("新增应用")
     @PostMapping("/add")
     public Result<AitagApp> addApp(@Validated @RequestBody AitagAppCreateDto dto) {
@@ -51,13 +51,10 @@ public class AitagAppController {
     }
 
     @ApiOperationType("查询应用")
-    @GetMapping("/query")
-    public Result<List<AitagApp>> queryByName(
-            @RequestParam String appName,
-            @RequestParam(defaultValue = "1") int page,
-            @RequestParam(defaultValue = "10") int pageSize) {
+    @PostMapping("/query")
+    public Result<List<AitagApp>> queryByName(@Validated @RequestBody AitagAppQueryDto dto) {
         try {
-            Page<AitagApp> pageResult = aiTagAppService.queryByAppNameLikeWithPagination(appName, page, pageSize);
+            Page<AitagApp> pageResult = aiTagAppService.queryByAppNameLikeWithPagination(dto.getAppName(), dto.getPage(), dto.getPageSize());
             return Result.pageSuccess(pageResult.getRecords(), pageResult.getTotal()); // ✅ 返回 Result<List<AitagApp>>
         } catch (Exception e) {
             return Result.error("500", "应用查询失败:" + e.getMessage());
@@ -68,9 +65,9 @@ public class AitagAppController {
 
     @ApiOperationType("重置密钥")
     @PostMapping("/reset-secret")
-    public Result<String> resetSecret(@RequestParam String id) {
+    public Result<String> resetSecret(@Validated @RequestBody AitagAppResetSecretDto dto) {
         try {
-            String newSecret = aiTagAppService.resetSecret(id);
+            String newSecret = aiTagAppService.resetSecret(dto.getId());
             return Result.success(newSecret);
         } catch (Exception e) {
             return Result.error("500", "密钥重置失败:" + e.getMessage());
@@ -79,9 +76,9 @@ public class AitagAppController {
 
     @ApiOperationType("禁用应用")
     @PostMapping("/disable")
-    public Result<Void> disableApp(@RequestParam String id) {
+    public Result<Void> disableApp(@Validated @RequestBody AitagAppResetSecretDto dto) {
         try {
-            aiTagAppService.disableApp(id);
+            aiTagAppService.disableApp(dto.getId());
             return Result.success();
         } catch (Exception e) {
             return Result.error("500", "应用禁用失败:" + e.getMessage());

+ 31 - 39
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagTagCategoryController.java

@@ -1,7 +1,6 @@
 package cn.com.yusys.yusp.controller;
 
-import cn.com.yusys.yusp.domain.dto.AitagTagCategoryCreateDto;
-import cn.com.yusys.yusp.domain.dto.AitagTagCategoryUpdateDto;
+import cn.com.yusys.yusp.domain.dto.*;
 import cn.com.yusys.yusp.domain.entity.AitagTagCategory;
 import cn.com.yusys.yusp.domain.vo.AitagTagCategoryVo;
 import cn.com.yusys.yusp.model.Result;
@@ -30,17 +29,13 @@ public class AitagTagCategoryController {
     private static final int MAX_PAGE_SIZE = 100;
 
     @ApiOperationType("标签体系列表")
-    @GetMapping("/list")
-    public Result<List<AitagTagCategoryVo>> listCategories(
-            @RequestParam(required = false) String categoryNm,
-            @RequestParam(defaultValue = "1") int page,
-            @RequestParam(value = "pageSize", required = false) Integer size) {
-
-        // 处理 pageSize:如果前端没传,使用默认值;如果传了,可以使用前端值
-        int actualSize = (size == null || size <= 0) ? DEFAULT_PAGE_SIZE : Math.min(size, MAX_PAGE_SIZE);
-
+    @PostMapping("/list")
+    public Result<List<AitagTagCategoryVo>> listCategories(@RequestBody AitagTagCategoryListDto dto) {
         try {
-            Page<AitagTagCategoryVo> pageResult = aiTagCategoryService.listCategories(categoryNm, page, actualSize);
+            // 如果前端没传 pageSize,使用默认值 10;否则使用前端传入的值
+            int actualSize = (dto.getPageSize() == null || dto.getPageSize() <= 0) ? 10 : dto.getPageSize();
+
+            Page<AitagTagCategoryVo> pageResult = aiTagCategoryService.listCategories(dto.getCategoryNm(), dto.getPage(), actualSize);
             return Result.pageSuccess(pageResult.getRecords(), pageResult.getTotal());
         } catch (Exception e) {
             return Result.error("500", "分页查询失败:" + e.getMessage());
@@ -73,10 +68,10 @@ public class AitagTagCategoryController {
 
     @ApiOperationType("启用标签体系")
     @PostMapping("/enable")
-    public Result<Void> enableCategory(@RequestParam String id) {
+    public Result<Void> enableCategory(@Validated @RequestBody AitagTagCategoryOperationDto dto) {
         try {
-            aiTagCategoryService.enableCategory(id);
-            fastApiService.categorySync(id);
+            aiTagCategoryService.enableCategory(dto.getId());
+            fastApiService.categorySync(dto.getId());
             return Result.success();
         } catch (Exception e) {
             return Result.error("500", "启用标签体系失败:" + e.getMessage());
@@ -85,10 +80,10 @@ public class AitagTagCategoryController {
 
     @ApiOperationType("停用标签体系")
     @PostMapping("/disable")
-    public Result<Void> disableCategory(@RequestParam String id) {
+    public Result<Void> disableCategory(@Validated @RequestBody AitagTagCategoryOperationDto dto) {
         try {
-            aiTagCategoryService.disableCategory(id);
-            fastApiService.categorySync(id);
+            aiTagCategoryService.disableCategory(dto.getId());
+            fastApiService.categorySync(dto.getId());
             return Result.success();
         } catch (Exception e) {
             return Result.error("500", "停用标签体系失败:" + e.getMessage());
@@ -97,25 +92,24 @@ public class AitagTagCategoryController {
 
     @ApiOperationType("删除标签体系")
     @PostMapping("/delete")
-    public Result<Void> deleteCategory(@RequestParam String id) {
+    public Result<Void> deleteCategory(@Validated @RequestBody AitagTagCategoryOperationDto dto) {
         try {
-            aiTagCategoryService.deleteCategory(id);
+            aiTagCategoryService.deleteCategory(dto.getId());
             return Result.success();
         } catch (Exception e) {
             return Result.error("500", "删除标签体系失败:" + e.getMessage());
         }
     }
 
-    @ApiOperationType("已启用标签体系列表一览")
-    @GetMapping("/enablelist")
-    public Result<List<AitagTagCategoryVo>> listEnabledCategories(
-            @RequestParam(defaultValue = "1") int page,
-            @RequestParam(value = "pageSize", required = false) Integer size) { // 修改点:改为 Integer,移除 defaultValue
-
-        int actualSize = (size == null || size <= 0) ? DEFAULT_PAGE_SIZE : Math.min(size, MAX_PAGE_SIZE);
 
+    @ApiOperationType("已启用标签体系列表一览")
+    @PostMapping("/enablelist")
+    public Result<List<AitagTagCategoryVo>> listEnabledCategories(@RequestBody AitagEnabledTagCategoryListDto dto) {
         try {
-            Page<AitagTagCategoryVo> pageResult = aiTagCategoryService.listEnabledCategories(page, actualSize);
+            // 如果前端没传 pageSize,使用默认值 10;否则使用前端传入的值
+            int actualSize = (dto.getPageSize() == null || dto.getPageSize() <= 0) ? 10 : dto.getPageSize();
+
+            Page<AitagTagCategoryVo> pageResult = aiTagCategoryService.listEnabledCategories(dto.getPage(), actualSize);
             return Result.pageSuccess(pageResult.getRecords(), pageResult.getTotal());
         } catch (Exception e) {
             return Result.error("500", "分页查询失败:" + e.getMessage());
@@ -123,10 +117,10 @@ public class AitagTagCategoryController {
     }
 
     @ApiOperationType("标签体系详情")
-    @GetMapping("/detail/{id}")
-    public Result<AitagTagCategoryVo> getCategoryDetail(@PathVariable String id) {
+    @PostMapping("/detail")
+    public Result<AitagTagCategoryVo> getCategoryDetail(@Validated @RequestBody AitagTagCategoryDetailDto dto) {
         try {
-            AitagTagCategoryVo categoryDetail = aiTagCategoryService.getCategoryDetail(id);
+            AitagTagCategoryVo categoryDetail = aiTagCategoryService.getCategoryDetail(dto.getId());
             return Result.success(categoryDetail);
         } catch (Exception e) {
             return Result.error("500", "查询标签体系详情失败:" + e.getMessage());
@@ -134,15 +128,13 @@ public class AitagTagCategoryController {
     }
 
     @ApiOperationType("外部标签体系")
-    @GetMapping("/enablelistnoauth")
-    public Result<List<AitagTagCategoryVo>> listEnabledCategoriesNoAuth(
-            @RequestParam(defaultValue = "1") int page,
-            @RequestParam(value = "pageSize", required = false) Integer size) { // 修改点:改为 Integer,移除 defaultValue
-
-        int actualSize = (size == null || size <= 0) ? DEFAULT_PAGE_SIZE : Math.min(size, MAX_PAGE_SIZE);
-
+    @PostMapping("/enablelistnoauth")
+    public Result<List<AitagTagCategoryVo>> listEnabledCategoriesNoAuth(@RequestBody AitagEnabledTagCategoryListDto dto) {
         try {
-            Page<AitagTagCategoryVo> pageResult = aiTagCategoryService.listEnabledCategories(page, actualSize);
+            // 如果前端没传 pageSize,使用默认值 10;否则使用前端传入的值
+            int actualSize = (dto.getPageSize() == null || dto.getPageSize() <= 0) ? 10 : dto.getPageSize();
+
+            Page<AitagTagCategoryVo> pageResult = aiTagCategoryService.listEnabledCategories(dto.getPage(), actualSize);
             return Result.pageSuccess(pageResult.getRecords(), pageResult.getTotal());
         } catch (Exception e) {
             return Result.error("500", "分页查询失败:" + e.getMessage());

+ 77 - 13
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagTagInfoController.java

@@ -3,7 +3,9 @@ package cn.com.yusys.yusp.controller;
 import cn.com.yusys.yusp.annotation.ApiOperationType;
 import cn.com.yusys.yusp.commons.exception.BizException;
 import cn.com.yusys.yusp.commons.module.adapter.web.rest.ResultDto;
+import cn.com.yusys.yusp.domain.dto.TagInfoDetailDto;
 import cn.com.yusys.yusp.domain.dto.TagInfoDto;
+import cn.com.yusys.yusp.domain.dto.TagInfoPageDto;
 import cn.com.yusys.yusp.domain.entity.AitagTagInfoEntity;
 import cn.com.yusys.yusp.domain.vo.*;
 import cn.com.yusys.yusp.domain.vo.fastapivo.AiTaggingResponseVo;
@@ -20,6 +22,7 @@ import org.springframework.core.io.Resource;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -57,13 +60,26 @@ public class AitagTagInfoController {
     /**
      * 列表查询
      *
-     * @param aitagTagInfoQueryVo
+     * @param dto
      * @return ResultDto
      */
     @ApiOperationType("列表标签分页信息")
-    @GetMapping("/page")
-    public ResultDto<List<AitagTagInfoEntity>> page(AitagTagInfoQueryVo aitagTagInfoQueryVo) {
-        IPage<AitagTagInfoEntity> page = aitagTagInfoService.queryPage(aitagTagInfoQueryVo);
+    @PostMapping("/page")
+    public ResultDto<List<AitagTagInfoEntity>> page(@RequestBody TagInfoPageDto dto) {
+        AitagTagInfoQueryVo queryVo = new AitagTagInfoQueryVo();
+        queryVo.setCategoryId(dto.getCategoryId());
+        queryVo.setTagNm(dto.getTagName());
+        queryVo.setTagCode(dto.getTagCode());
+
+        // 处理 state:String -> Integer
+        if (dto.getState() != null && !dto.getState().isEmpty()) {
+            queryVo.setState(Integer.valueOf(dto.getState()));
+        }
+
+        queryVo.setPage(dto.getPage());
+        queryVo.setPageSize(dto.getPageSize());
+
+        IPage<AitagTagInfoEntity> page = aitagTagInfoService.queryPage(queryVo);
         return ResultDto.success(page.getRecords()).total(page.getTotal());
     }
 
@@ -71,16 +87,49 @@ public class AitagTagInfoController {
     /**
      * 列表查询
      *
-     * @param aitagTagInfoQueryVo
+     * @param dto
      * @return ResultDto
      */
     @ApiOperationType("标签列表查询")
-    @GetMapping("/list")
-    public ResultDto<List<AitagTagInfoEntity>> list(AitagTagInfoQueryVo aitagTagInfoQueryVo) {
-        List<AitagTagInfoEntity> page = aitagTagInfoService.queryList(aitagTagInfoQueryVo);
+    @PostMapping("/list")
+    public ResultDto<List<AitagTagInfoEntity>> list(@RequestBody TagInfoPageDto dto) {
+        AitagTagInfoQueryVo queryVo = new AitagTagInfoQueryVo();
+        queryVo.setCategoryId(dto.getCategoryId());
+        queryVo.setTagNm(dto.getTagName());
+        queryVo.setTagCode(dto.getTagCode());
+
+        // 处理 state:String -> Integer
+        if (dto.getState() != null && !dto.getState().isEmpty()) {
+            queryVo.setState(Integer.valueOf(dto.getState()));
+        }
+
+        List<AitagTagInfoEntity> page = aitagTagInfoService.queryList(queryVo);
         return ResultDto.success(page);
     }
 
+//    @ApiOperationType("列表标签分页信息")
+//    @GetMapping("/page")
+//    public ResultDto<List<AitagTagInfoEntity>> page(AitagTagInfoQueryVo aitagTagInfoQueryVo) {
+//        IPage<AitagTagInfoEntity> page = aitagTagInfoService.queryPage(aitagTagInfoQueryVo);
+//        return ResultDto.success(page.getRecords()).total(page.getTotal());
+//    }
+//
+//
+//    /**
+//     * 列表查询
+//     *
+//     * @param aitagTagInfoQueryVo
+//     * @return ResultDto
+//     */
+//    @ApiOperationType("标签列表查询")
+//    @GetMapping("/list")
+//    public ResultDto<List<AitagTagInfoEntity>> list(AitagTagInfoQueryVo aitagTagInfoQueryVo) {
+//        List<AitagTagInfoEntity> page = aitagTagInfoService.queryList(aitagTagInfoQueryVo);
+//        return ResultDto.success(page);
+//    }
+
+
+
     /**
      * 查询标签树
      *
@@ -101,16 +150,30 @@ public class AitagTagInfoController {
     /**
      * 详细
      *
-     * @param id
+     * @param dto
      * @return ResultDto
      */
     @ApiOperationType("标签详细")
-    @GetMapping("/info/{id}")
-    public ResultDto<TagInfoDto> info(@PathVariable("id") String id) {
-        TagInfoDto aitagTagInfo = aitagTagInfoService.getTagInfo(id);
+    @PostMapping("/info")
+    public ResultDto<TagInfoDto> info(@Validated @RequestBody TagInfoDetailDto dto) {
+        TagInfoDto aitagTagInfo = aitagTagInfoService.getTagInfo(dto.getId());
         return ResultDto.success(aitagTagInfo);
     }
 
+//    /**
+//     * 详细
+//     *
+//     * @param id
+//     * @return ResultDto
+//     */
+//    @ApiOperationType("标签详细")
+//    @GetMapping("/info/{id}")
+//    public ResultDto<TagInfoDto> info(@PathVariable("id") String id) {
+//        TagInfoDto aitagTagInfo = aitagTagInfoService.getTagInfo(id);
+//        return ResultDto.success(aitagTagInfo);
+//    }
+//
+
     /**
      * 保存
      *
@@ -233,7 +296,8 @@ public class AitagTagInfoController {
      * @return ResultDto
      */
     @ApiOperationType("批量导入模板下载")
-    @GetMapping("/downloadFile")
+    @PostMapping("/downloadFile")
+//    @GetMapping("/downloadFile")
     public ResponseEntity<Resource> downloadFile( ) throws IOException {
 
         ClassPathResource resource = new ClassPathResource("template/tag_batch_Import_template.xlsx");

+ 51 - 6
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagTagLogController.java

@@ -3,6 +3,7 @@ package cn.com.yusys.yusp.controller;
 import cn.com.yusys.yusp.annotation.ApiOperationType;
 import cn.com.yusys.yusp.commons.module.adapter.web.rest.ResultDto;
 import cn.com.yusys.yusp.domain.dto.TagLogDto;
+import cn.com.yusys.yusp.domain.dto.TagLogDetailDto;
 import cn.com.yusys.yusp.domain.dto.TagResultDto;
 import cn.com.yusys.yusp.domain.entity.AitagTagLogEntity;
 import cn.com.yusys.yusp.domain.vo.*;
@@ -14,6 +15,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import io.swagger.annotations.Api;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletResponse;
@@ -99,16 +101,23 @@ public class AitagTagLogController {
     /**
      * 打标结果详情
      *
-     * @param id
+     * @param dto
      * @return ResultDto
      */
     @ApiOperationType("打标结果详情")
-    @GetMapping("/show/{id}")
-    public ResultDto<TagLogDto> show(@PathVariable("id") String id) {
-        TagLogDto taggingDetailsResDTO = aitagTagLogService.show(id);
+    @PostMapping("/show")
+    public ResultDto<TagLogDto> show(@Validated @RequestBody TagLogDetailDto dto) {
+        TagLogDto taggingDetailsResDTO = aitagTagLogService.show(dto.getId());
         return ResultDto.success(taggingDetailsResDTO);
     }
 
+//    @ApiOperationType("打标结果详情")
+//    @GetMapping("/show/{id}")
+//    public ResultDto<TagLogDto> show(@PathVariable("id") String id) {
+//        TagLogDto taggingDetailsResDTO = aitagTagLogService.show(id);
+//        return ResultDto.success(taggingDetailsResDTO);
+//    }
+
 
     /**
      * 导出数据
@@ -117,8 +126,8 @@ public class AitagTagLogController {
      * @return ResultDto
      */
     @ApiOperationType("导出数据")
-    @GetMapping("/exportData")
-    public void exportData(TaggingTransactionReqVo transactionReqVo,HttpServletResponse response) throws IOException {
+    @PostMapping("/exportData")
+    public void exportData(@RequestBody TaggingTransactionReqVo transactionReqVo, HttpServletResponse response) throws IOException {
         List<AitagTagLogEntity> aitagTagLogEntities = aitagTagLogService.queryConfirmedTagData(transactionReqVo);
         List<ExportDataVo> exportDataVos = new ArrayList<>();
         for (AitagTagLogEntity aitagTagLog:aitagTagLogEntities) {
@@ -143,6 +152,42 @@ public class AitagTagLogController {
                 .doWrite(exportDataVos);
     }
 
+
+//
+//
+//    /**
+//     * 导出数据
+//     *
+//     * @param transactionReqVo
+//     * @return ResultDto
+//     */
+//    @ApiOperationType("导出数据")
+//    @GetMapping("/exportData")
+//    public void exportData(TaggingTransactionReqVo transactionReqVo,HttpServletResponse response) throws IOException {
+//        List<AitagTagLogEntity> aitagTagLogEntities = aitagTagLogService.queryConfirmedTagData(transactionReqVo);
+//        List<ExportDataVo> exportDataVos = new ArrayList<>();
+//        for (AitagTagLogEntity aitagTagLog:aitagTagLogEntities) {
+//            ExportDataVo exportDataVo = JSONObject.parseObject(JSONObject.toJSONString(aitagTagLog), ExportDataVo.class);
+//            if(FEEDBACK_RESULT_REJECT.equals(aitagTagLog.getFeedback())){
+//                String feedbackResult = aitagTagLog.getFeedbackResult();
+//                exportDataVo.setResult(getTags(feedbackResult));
+//            }else{
+//                String result = aitagTagLog.getResult();
+//                exportDataVo.setResult(getTags(result));
+//            }
+//            exportDataVos.add(exportDataVo);
+//        }
+//        // 2. 设置响应头(防止中文乱码)
+//        response.reset();
+//        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+//        response.setCharacterEncoding("utf-8");
+//        String fileName = URLEncoder.encode("导出标签", "UTF-8").replaceAll("\\+", "%20");
+//        response.setHeader("Content-Disposition", "attachment; filename*=utf-8''" + fileName + ".xlsx");
+//        EasyExcel.write(response.getOutputStream(), ExportDataVo.class)
+//                .sheet("标签数据")
+//                .doWrite(exportDataVos);
+//    }
+
     private String getTags(String result) {
         if(StringUtils.isBlank(result)){
             return "";

+ 3 - 9
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/FastApiController.java

@@ -4,12 +4,10 @@ import cn.com.yusys.yusp.annotation.ApiOperationType;
 import cn.com.yusys.yusp.domain.dto.fastapidto.AiTaggingFeedbackRequestDto;
 import cn.com.yusys.yusp.domain.dto.fastapidto.AiTaggingQueryRequestDto;
 import cn.com.yusys.yusp.domain.dto.fastapidto.AiTaggingRequestDto;
-import cn.com.yusys.yusp.domain.vo.EsbVo.CustomerProfileReqVo;
 import cn.com.yusys.yusp.domain.vo.fastapivo.AiTaggingQueryResponseVo;
 import cn.com.yusys.yusp.domain.vo.fastapivo.AiTaggingResponseVo;
 import cn.com.yusys.yusp.model.Result;
 import cn.com.yusys.yusp.service.FastApiService;
-import cn.com.yusys.yusp.service.esb.ESBService;
 import cn.com.yusys.yusp.util.AuthContextUtil;
 import io.swagger.annotations.Api;
 import lombok.extern.slf4j.Slf4j;
@@ -42,14 +40,10 @@ public class FastApiController {
     }
 
     @ApiOperationType("AI 打标查询")
-    @GetMapping("/query")
-    public Result<AiTaggingQueryResponseVo> query(
-            @Valid @RequestParam String businessAttr) {
+    @PostMapping("/query")
+    public Result<AiTaggingQueryResponseVo> query(@Valid @RequestBody AiTaggingQueryRequestDto request) {
         try {
-            log.info("收到 AI 打标查询请求:businessAttr={}", businessAttr);
-
-            AiTaggingQueryRequestDto request = new AiTaggingQueryRequestDto();
-            request.setBusinessAttr(businessAttr);
+            log.info("收到 AI 打标查询请求:businessAttr={}", request.getBusinessAttr());
 
             AiTaggingQueryResponseVo response = fastApiService.query(request);
             return Result.success(response);

+ 22 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagApiLogDetailDto.java

@@ -0,0 +1,22 @@
+package cn.com.yusys.yusp.domain.dto;
+
+import lombok.Data;
+import io.swagger.annotations.ApiModelProperty;
+import javax.validation.constraints.NotBlank;
+
+/**
+ * API 日志详情查询 DTO
+ */
+@Data
+public class AitagApiLogDetailDto {
+    
+    @NotBlank(message = "日志 ID 不能为空")
+    @ApiModelProperty(value = "日志 ID", required = true)
+    private String id;
+    
+    @ApiModelProperty(value = "页码", example = "1")
+    private Integer page = 1;
+    
+    @ApiModelProperty(value = "每页大小", example = "10")
+    private Integer pageSize;
+}

+ 23 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagApiLogListDto.java

@@ -0,0 +1,23 @@
+package cn.com.yusys.yusp.domain.dto;
+
+import lombok.Data;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * API 日志列表查询 DTO
+ */
+@Data
+public class AitagApiLogListDto {
+
+    @ApiModelProperty(value = "开始时间(yyyy-MM-dd)")
+    private String startTime;
+
+    @ApiModelProperty(value = "结束时间(yyyy-MM-dd)")
+    private String endTime;
+
+    @ApiModelProperty(value = "页码", example = "1")
+    private Integer page = 1;
+
+    @ApiModelProperty(value = "每页大小", example = "10")
+    private Integer pageSize;
+}

+ 17 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagAppListDto.java

@@ -0,0 +1,17 @@
+package cn.com.yusys.yusp.domain.dto;
+
+import lombok.Data;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * 应用列表查询 DTO
+ */
+@Data
+public class AitagAppListDto {
+
+    @ApiModelProperty(value = "页码")
+    private Integer page = 1;
+
+    @ApiModelProperty(value = "每页大小")
+    private Integer pageSize;
+}

+ 22 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagAppQueryDto.java

@@ -0,0 +1,22 @@
+package cn.com.yusys.yusp.domain.dto;
+
+import lombok.Data;
+import io.swagger.annotations.ApiModelProperty;
+import javax.validation.constraints.NotBlank;
+
+/**
+ * 应用查询 DTO
+ */
+@Data
+public class AitagAppQueryDto {
+    
+    @NotBlank(message = "应用名称不能为空")
+    @ApiModelProperty(value = "应用名称", required = true)
+    private String appName;
+    
+    @ApiModelProperty(value = "页码", example = "1")
+    private Integer page = 1;
+    
+    @ApiModelProperty(value = "每页大小", example = "10")
+    private Integer pageSize = 10;
+}

+ 16 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagAppResetSecretDto.java

@@ -0,0 +1,16 @@
+package cn.com.yusys.yusp.domain.dto;
+
+import lombok.Data;
+import io.swagger.annotations.ApiModelProperty;
+import javax.validation.constraints.NotBlank;
+
+/**
+ * 应用重置密钥请求 DTO
+ */
+@Data
+public class AitagAppResetSecretDto {
+    
+    @NotBlank(message = "应用 ID 不能为空")
+    @ApiModelProperty(value = "应用 ID", required = true)
+    private String id;
+}

+ 17 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagEnabledTagCategoryListDto.java

@@ -0,0 +1,17 @@
+package cn.com.yusys.yusp.domain.dto;
+
+import lombok.Data;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * 已启用标签体系列表查询 DTO
+ */
+@Data
+public class AitagEnabledTagCategoryListDto {
+    
+    @ApiModelProperty(value = "页码", example = "1")
+    private Integer page = 1;
+    
+    @ApiModelProperty(value = "每页大小", example = "10")
+    private Integer pageSize;
+}

+ 16 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagTagCategoryDetailDto.java

@@ -0,0 +1,16 @@
+package cn.com.yusys.yusp.domain.dto;
+
+import lombok.Data;
+import io.swagger.annotations.ApiModelProperty;
+import javax.validation.constraints.NotBlank;
+
+/**
+ * 标签体系详情查询 DTO
+ */
+@Data
+public class AitagTagCategoryDetailDto {
+    
+    @NotBlank(message = "体系 ID 不能为空")
+    @ApiModelProperty(value = "体系 ID", required = true)
+    private String id;
+}

+ 20 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagTagCategoryListDto.java

@@ -0,0 +1,20 @@
+package cn.com.yusys.yusp.domain.dto;
+
+import lombok.Data;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * 标签体系列表查询 DTO
+ */
+@Data
+public class AitagTagCategoryListDto {
+
+    @ApiModelProperty(value = "体系名称(模糊查询)")
+    private String categoryNm;
+
+    @ApiModelProperty(value = "页码", example = "1")
+    private Integer page = 1;
+
+    @ApiModelProperty(value = "每页大小")
+    private Integer pageSize;
+}

+ 16 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagTagCategoryOperationDto.java

@@ -0,0 +1,16 @@
+package cn.com.yusys.yusp.domain.dto;
+
+import lombok.Data;
+import io.swagger.annotations.ApiModelProperty;
+import javax.validation.constraints.NotBlank;
+
+/**
+ * 标签体系操作请求 DTO(启用/禁用/删除)
+ */
+@Data
+public class AitagTagCategoryOperationDto {
+
+    @NotBlank(message = "体系 ID 不能为空")
+    @ApiModelProperty(value = "体系 ID", required = true)
+    private String id;
+}

+ 16 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/TagInfoDetailDto.java

@@ -0,0 +1,16 @@
+package cn.com.yusys.yusp.domain.dto;
+
+import lombok.Data;
+import io.swagger.annotations.ApiModelProperty;
+import javax.validation.constraints.NotBlank;
+
+/**
+ * 标签详情查询 DTO
+ */
+@Data
+public class TagInfoDetailDto {
+    
+    @NotBlank(message = "标签 ID 不能为空")
+    @ApiModelProperty(value = "标签 ID", required = true)
+    private String id;
+}

+ 29 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/TagInfoPageDto.java

@@ -0,0 +1,29 @@
+package cn.com.yusys.yusp.domain.dto;
+
+import lombok.Data;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * 标签分页查询 DTO
+ */
+@Data
+public class TagInfoPageDto {
+
+    @ApiModelProperty(value = "体系 ID")
+    private String categoryId;
+
+    @ApiModelProperty(value = "标签名称")
+    private String tagName;
+
+    @ApiModelProperty(value = "标签编码")
+    private String tagCode;
+
+    @ApiModelProperty(value = "状态:0-启用;1-停用")
+    private String state;
+
+    @ApiModelProperty(value = "页码", example = "1")
+    private long page = 1;
+
+    @ApiModelProperty(value = "每页大小", example = "10")
+    private Integer pageSize;
+}

+ 16 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/TagLogDetailDto.java

@@ -0,0 +1,16 @@
+package cn.com.yusys.yusp.domain.dto;
+
+import lombok.Data;
+import io.swagger.annotations.ApiModelProperty;
+import javax.validation.constraints.NotBlank;
+
+/**
+ * 打标结果详情查询 DTO
+ */
+@Data
+public class TagLogDetailDto {
+
+    @NotBlank(message = "日志 ID 不能为空")
+    @ApiModelProperty(value = "日志 ID", required = true)
+    private String id;
+}

+ 6 - 5
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/fastapidto/AiTaggingQueryRequestDto.java

@@ -1,17 +1,18 @@
-
 package cn.com.yusys.yusp.domain.dto.fastapidto;
 
 import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
-
+import io.swagger.annotations.ApiModelProperty;
 import javax.validation.constraints.NotBlank;
 
+/**
+ * AI 打标查询请求 DTO
+ */
 @Data
 @ApiModel("AI 打标查询请求")
 public class AiTaggingQueryRequestDto {
-
+    
     @NotBlank(message = "业务属性不能为空")
-    @ApiModelProperty(value = "业务属性", required = true)
+    @ApiModelProperty(value = "业务属性(贷款编号)", required = true)
     private String businessAttr;
 }

+ 2 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/vo/AitagTagInfoQueryVo.java

@@ -75,4 +75,6 @@ public class AitagTagInfoQueryVo extends PageQuery {
     private String tagPrompt;
 
 
+    public void setPageSize(Integer pageSize) {
+    }
 }

+ 2 - 2
server/yusp-tagging-core/src/main/resources/mapper/AitagTagLogMapper.xml

@@ -104,7 +104,7 @@
         FROM (
         -- 从feedback_result获取
         SELECT elem->>'tag_name' AS tag_name
-        FROM ai_tagging.aitag_tag_log t
+        FROM aitag_tag_log t
         CROSS JOIN LATERAL jsonb_array_elements(t.feedback_result) elem
         WHERE t.is_delete = 0
         AND t.tag_scope = 0
@@ -123,7 +123,7 @@
         </if>
         UNION ALL
         SELECT elem->>'tag_name' AS tag_name
-        FROM ai_tagging.aitag_tag_log t
+        FROM aitag_tag_log t
         CROSS JOIN LATERAL jsonb_array_elements(t.result) elem
         WHERE t.is_delete = 0
         AND t.tag_scope = 0