Browse Source

二期需求实现

jiayongqiang 1 tuần trước cách đây
mục cha
commit
8ba8333296
50 tập tin đã thay đổi với 1787 bổ sung62 xóa
  1. BIN
      agent/data/20260507对公贷款数据.xlsx
  2. BIN
      agent/logs/aitagging-app.2026-03-10_10-12-47_456980.log.zip
  3. BIN
      agent/logs/aitagging-app.2026-03-11_17-19-07_238711.log.zip
  4. BIN
      agent/logs/aitagging-app.2026-03-12_15-29-18_138302.log.zip
  5. BIN
      agent/logs/aitagging-app.2026-03-13_09-47-02_435341.log.zip
  6. BIN
      agent/logs/aitagging-app.2026-03-16_09-34-01_075272.log.zip
  7. BIN
      agent/logs/aitagging-app.2026-03-17_10-36-37_002744.log.zip
  8. BIN
      agent/logs/aitagging-app.2026-03-23_14-44-11_403520.log.zip
  9. BIN
      agent/logs/aitagging-app.2026-03-26_18-19-50_023840.log.zip
  10. BIN
      agent/logs/aitagging-app.2026-03-31_19-14-14_513382.log.zip
  11. BIN
      agent/logs/aitagging-app.2026-04-10_10-20-00_803764.log.zip
  12. BIN
      agent/logs/aitagging-app.2026-05-06_18-50-04_192821.log.zip
  13. BIN
      agent/logs/aitagging-app.2026-05-07_16-18-49_120948.log.zip
  14. 7 9
      agent/src/agent/agent.py
  15. 19 10
      agent/src/agent/api_outter.py
  16. 10 2
      agent/src/agent/core/tagging_state.py
  17. 12 4
      agent/tests/test_tagging.py
  18. 29 0
      agent/tests/test_tagging_0507.py
  19. 1 0
      agent/update.md
  20. 82 33
      agent/update.sql
  21. 9 1
      server/yusp-tagging-core/pom.xml
  22. 92 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagTagComWhiteController.java
  23. 68 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagTagLogController.java
  24. 22 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagComWhiteListDto.java
  25. 14 2
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/fastapidto/AiTaggingRequestDto.java
  26. 41 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/entity/AitagTagComWhiteListDetailEntity.java
  27. 48 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/entity/AitagTagComWhiteListEntity.java
  28. 6 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/entity/AitagTagLogEntity.java
  29. 7 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/vo/SmartTaggingResultVo.java
  30. 177 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/feign/AdminSmOrg.java
  31. 27 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/feign/OcaUserService.java
  32. 45 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/mapper/AitagComWhitelistDetailMapper.java
  33. 48 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/mapper/AitagComWhitelistMapper.java
  34. 19 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/AitagTagComWhiteListDetailService.java
  35. 31 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/AitagTagComWhiteListService.java
  36. 29 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/impl/AitagTagComWhitelistDetailServiceImpl.java
  37. 100 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/impl/AitagTagComWhitelistServiceImpl.java
  38. 45 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/impl/AitagTagLogServiceImpl.java
  39. 18 1
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/impl/FastApiServiceImpl.java
  40. 6 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/util/Roles.java
  41. 65 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/util/SessionCommonUtil.java
  42. 58 0
      server/yusp-tagging-core/src/main/resources/mapper/AitagComWhitelistDetailMapper.xml
  43. 61 0
      server/yusp-tagging-core/src/main/resources/mapper/AitagComWhitelistMapper.xml
  44. 50 0
      server/yusp-tagging-core/src/main/resources/mapper/AitagTagLogMapper.xml
  45. 5 0
      server/yusp-tagging-starter/pom.xml
  46. 3 0
      server/yusp-tagging-starter/src/main/java/cn/com/yusys/yusp/detail/App.java
  47. 4 0
      server/yusp-tagging-starter/src/main/resources/bootstrap.yml
  48. 37 0
      server/yusp-tagging-starter/src/test/java/cn/com/yusys/yusp/TestManagerAuth.java
  49. 172 0
      web/src/views/aiTagging/comWhiteList/components/LogDetailDrawer.vue
  50. 320 0
      web/src/views/aiTagging/comWhiteList/index.vue

BIN
agent/data/20260507对公贷款数据.xlsx


BIN
agent/logs/aitagging-app.2026-03-10_10-12-47_456980.log.zip


BIN
agent/logs/aitagging-app.2026-03-11_17-19-07_238711.log.zip


BIN
agent/logs/aitagging-app.2026-03-12_15-29-18_138302.log.zip


BIN
agent/logs/aitagging-app.2026-03-13_09-47-02_435341.log.zip


BIN
agent/logs/aitagging-app.2026-03-16_09-34-01_075272.log.zip


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


BIN
agent/logs/aitagging-app.2026-03-31_19-14-14_513382.log.zip


BIN
agent/logs/aitagging-app.2026-04-10_10-20-00_803764.log.zip


BIN
agent/logs/aitagging-app.2026-05-06_18-50-04_192821.log.zip


BIN
agent/logs/aitagging-app.2026-05-07_16-18-49_120948.log.zip


+ 7 - 9
agent/src/agent/agent.py

@@ -6,7 +6,7 @@ from agent.core.config import get_config_path
 from agent.logger import logger
 import uuid
 from datetime import datetime
-
+from agent.logger import logger
 config = get_config_path()
 TOP_K = config['app']['top_k']
 
@@ -21,7 +21,7 @@ if max_retries is None:
 timeout = config['llm']['timeout']
 if timeout is None:
     timeout = 30  # 默认超时时间(秒)
-
+logger.info(f"model_name:{model}, base_url:{base_url}")
 llm = init_chat_model(
     model_provider="openai", 
     model=model, 
@@ -30,7 +30,7 @@ llm = init_chat_model(
     temperature= temperature,
     extra_body={"enable_thinking": False},
     max_retries=max_retries,
-    timeout=timeout
+    # timeout=timeout
 )
 
 class Lable(BaseModel):
@@ -104,12 +104,12 @@ async def reflect_check(context: str,is_marine: bool, labels: list):
         "messages": [{"role":"system","content": prompt}]
     },context = {})
     result = response["structured_response"]
+    logger.info(f"{context} LLM result: {result}")
     # 只保留passr为true的标签,并将结果转换为字典列表格式
-    result =  [r.dict() for r in result.labels if r.passr]
+    result =  [r.dict() for r in result.labels ]
     result = json.dumps(result, ensure_ascii=False)
     l2 = datetime.now().isoformat()
     logger.info(f"Reflection check completed with uuid {uid}. timestamp: {l2}, consuming {(datetime.fromisoformat(l2) - datetime.fromisoformat(l1)).total_seconds()} seconds.")
-    logger.info(f"{context} LLM result: {result}")
 
     return result
 
@@ -172,9 +172,7 @@ async def generate_reg(tag_name: str, tag_remark: str):
     return reg
 
 if __name__ == "__main__":
-    context = "该笔贷款用于支持一家制造企业的生产线升级改造,涉及购买新设备、技术改造和相关建设活动。文本中提到的资产包括数台高端数控机床和自动化生产线,项目性质为产能提升和技术升级,合同内容涉及设备采购和安装服务,资金用途明确指向生产线改造,建设活动包括厂房扩建和设备安装调试。"
-    labels = [{"label": "设备采购", "desc": "用于采购新设备"}, {"label": "标签2", "desc": "标签2定义"}, {"label": "标签3", "desc": "标签3定义"}]
-    optimized_labels = reflect_check(context, False, labels)
-    print(optimized_labels)
+    res = llm.invoke("你好")
+    print(res)
  
 

+ 19 - 10
agent/src/agent/api_outter.py

@@ -30,11 +30,20 @@ class TaggingRequest(BaseModel):
     app_id:  Optional[str] = Field(None, description="应用ID")
     timestamp: Optional[int] = Field(None, description="请求时间戳")
     sign: Optional[str] = Field(None, description="请求签名")
-    business_attr: str = Field(..., description="业务属性")
+
+    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流水号")
     instucde:Optional[str] = Field(None, description="法人行社代码")
+    contract_no:Optional[str] = Field(None,description="合同编号")
+    instucde_nm:Optional[str] = Field(None,description="法人行社名称")
+    company_nm:Optional[str] = Field(None,description="企业名称")
+    company_code:Optional[str]=Field(None,description="企业统一社会信用代码")
+    user_id:Optional[str] = Field(None,description="发起人ID")
+    user_nm:Optional[str] = Field(None,description="发起人姓名")
+    user_org:Optional[str] = Field(None,description="发起人所属机构")
+    user_endpoint:Optional[str] = Field(None,description="发起人所属网点")
 
 async def execute_reg(log_id:str,tag_category_id:str,phrase: str)-> list:
     sql = f"""select 
@@ -54,7 +63,7 @@ async def execute_reg(log_id:str,tag_category_id:str,phrase: str)-> list:
             reg = label[1]
             if reg is not None:
                 pattern = re.compile(reg, re.VERBOSE)
-                logger.info(f"Executing regex for label_id {label[0]}: {reg}")
+                # logger.info(f"Executing regex for label_id {label[0]}: {reg}")
                 if pattern.match(phrase):
                     logger.info(f"Executing regex for label_id {label[0]}: {reg} true")
                     result.append(label[0])
@@ -62,7 +71,7 @@ async def execute_reg(log_id:str,tag_category_id:str,phrase: str)-> list:
                 result.append(label[0])
     except Exception as e:
         logger.error(f"Regex execution failed: {e}")
-    logger.info(f"Regex filtering candidates: {result}")
+    # logger.info(f"Regex filtering candidates: {result}")
     dao.execute(
             """UPDATE aitag_tag_log SET reg_result = %s WHERE id = %s""",
             (str(result), log_id)
@@ -90,8 +99,8 @@ 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,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)
+        """INSERT INTO aitag_tag_log (id,app_id, insert_time, business_attr, phrase, state, tag_scope,esb_seq_no,instucde,instucde_nm,company_nm,company_code,start_user_id,start_user_nm,start_user_org,start_user_endpoint) VALUES (%s, %s, %s, %s, %s, %s, %s,%s,%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,request.instucde,request.instucde_nm,request.company_nm,request.company_code,request.user_id,request.user_nm,request.user_org,request.user_endpoint)
     )
     return id
 
@@ -110,12 +119,12 @@ def fail_tagging(id:str):
 def start_tagging(id:str, instucde: Optional[str] = None):
     is_marine = 0
     if instucde is not None:
-        rows = dao.query("select tag_type from aitag_org_whitelist where org_code = %s", (instucde,))
+        rows = dao.query("select tag_type from aitag_instucde_whitelist where instucde_code = %s", (instucde,))
         if rows and len(rows) == 1:
             logger.info(f"机构{instucde}在白名单中")
             is_marine = 1 if rows[0][0] == 'marine' else 0
     dao.execute(
-            """UPDATE aitag_tag_log SET state = %s, is_marine = %s,org_code = %s, ai_result_starttime = %s WHERE id = %s""",
+            """UPDATE aitag_tag_log SET state = %s, is_marine = %s,instucde = %s, ai_result_starttime = %s WHERE id = %s""",
             (TAGGING_STATE.BEGIN.value, is_marine, instucde, datetime.now(),  id)
         )
     return is_marine
@@ -141,15 +150,15 @@ def defined_rule_match(phrase: str):
 
 def end_tagging_predefined_rule(id:str, result:str):
     dao.execute(
-            """UPDATE aitag_tag_log SET state = %s, result = %s WHERE id = %s""",
-            (TAGGING_STATE.PREDEFINED_RULE_MATCH.value, result,  id)
+            """UPDATE aitag_tag_log SET state = %s, result = %s,ai_result_endtime = %s WHERE id = %s""",
+            (TAGGING_STATE.PREDEFINED_RULE_MATCH.value, result,datetime.now(),  id)
         )
 
 async def run_ai_pipeline(log_id: str, tag_category_id: str, phrase: str, instucde: Optional[str] = None):
     try:
         async with background_semaphore:
             logger.info(f"开始打标:{log_id}, {phrase}")
-            # step0: 开始打标
+            # step0: 开始打标,初始化打标日志,如果是在行社白名单中,标记下
             is_marine = start_tagging(log_id, instucde)
 
             # step0.5: 预设规则匹配,如果匹配成功则直接更新结果并结束打标流程

+ 10 - 2
agent/src/agent/core/tagging_state.py

@@ -1,5 +1,13 @@
-# 0:请求已接收;1:打标完成; 2:客户经理已经确认;3,结果已推送; 
-# 4:开始打标, 5:打标失败; 6:预设规则匹配成功跳过客户经理确认,下一步就可以推送结果了
+# 0:请求已接收;
+# 1:打标完成; 
+# 2:客户经理已经确认;
+# 3,结果已推送; 
+# 4:开始打标, 
+# 5:打标失败; 
+# 6:预设规则匹配成功 默认客户经理已经确认,下一步就可以推送结果了,等待变3
+# 流程1,预设规则:0-->4-->6-->3
+# 流程2,常规流程: 0-->4-->1-->2--->3
+# 流程3,异常流程:0--4-->5
 from enum import Enum
 
 class TAGGING_STATE(Enum):

+ 12 - 4
agent/tests/test_tagging.py

@@ -3,14 +3,22 @@ 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_attr3",
-    "phrase": "职业:水产养殖人员 投向:内陆养殖 用途:其他海洋服务",
-    "instucde": "9080803001"
+    "business_attr": "test_attr7",
+    "phrase": "测试:职业:水产养殖人员 投向:内陆养殖 用途:其他海洋服务",
+    "instucde": "901020300",
+    "contract_no":"contract_no",
+    "instucde_nm":"instucde_nm",
+    "company_nm":"company_nm",
+    "company_code":"company_code",
+    "user_id":"user_id",
+    "user_nm":"user_nm",
+    "user_org":"user_org",
+    "user_endpoint":"user_endpoint"
 })
 
 logging.info(res.text)

+ 29 - 0
agent/tests/test_tagging_0507.py

@@ -0,0 +1,29 @@
+import requests
+import uuid
+from openpyxl import load_workbook
+
+wb = load_workbook('./data/20260507对公贷款数据.xlsx')
+ws = wb.active
+idx = 0
+for row in ws.iter_rows(min_row=2, values_only=True):
+    idx += 1
+    instucde = row[0] if row[0] is not None else ""
+    instucde_nm = row[1] if row[1] is not None else ""
+    concat_no = row[3] if row[3] is not None else ""
+    zhiye = row[6] if row[6] is not None else ""
+    touxiang = row[8] if row[8] is not None else ""
+    yongtu = row[10] if row[10] is not None else ""
+    phrase = f"职业:{zhiye}; 投向:{touxiang}; 用途:{yongtu}"
+    print(f"{instucde}, {instucde_nm} , {concat_no},{phrase}" )
+    # requests.post("http://10.192.72.13:9876/api/aitag/v1/tagging", json={
+    #     "esb_seq_no": is_sea,
+    #     "business_attr": concat_no,
+    #     "phrase": phrase
+    # })
+    requests.post("http://localhost:9876/api/aitag/v1/tagging", json={
+        "business_attr": concat_no,
+        "phrase": phrase,
+        "instucde":instucde,
+        "instucde_nm":instucde_nm
+    })
+    break

+ 1 - 0
agent/update.md

@@ -0,0 +1 @@
+1. 打标接口 /api/fastapi/tagging 增加参数:instucde(行社代码)

+ 82 - 33
agent/update.sql

@@ -1,47 +1,62 @@
 /**
 	行社白名单功能
 **/
--- 添加是否是海洋标签字段
 ALTER TABLE ai_tagging.aitag_tag_log ADD is_marine bit DEFAULT 0;
 COMMENT ON COLUMN ai_tagging.aitag_tag_log.is_marine IS '是否匹配行社白名单,匹配上的默认隶属于海洋经济,在大模型处理阶段给予提示,没匹配上的不给提示,0:否,1:是';
 
 -- 添加法人行社代码字段
-ALTER TABLE ai_tagging.aitag_tag_log ADD org_code varchar(100);
-comment on column ai_tagging.aitag_tag_log.org_code is '法人行社代码';
+ALTER TABLE ai_tagging.aitag_tag_log ADD instucde varchar(100);
+comment on column ai_tagging.aitag_tag_log.instucde is '法人行社代码';
+ALTER TABLE ai_tagging.aitag_tag_log DROP COLUMN org_code;
+ALTER TABLE ai_tagging.aitag_tag_log ADD instucde_nm varchar(100);
+comment on column ai_tagging.aitag_tag_log.instucde_nm is '法人行社名称';
+ALTER TABLE ai_tagging.aitag_tag_log add company_nm varchar(100);
+comment on column ai_tagging.aitag_tag_log.company_nm is '企业名称';
+ALTER TABLE ai_tagging.aitag_tag_log add company_code varchar(100);
+comment on column ai_tagging.aitag_tag_log.company_code is '企业统一社会信用代码';
+ ALTER TABLE ai_tagging.aitag_tag_log add start_user_id varchar(100);
+comment on column ai_tagging.aitag_tag_log.start_user_id is '发起人ID';
+ ALTER TABLE ai_tagging.aitag_tag_log add start_user_nm varchar(100);
+comment on column ai_tagging.aitag_tag_log.start_user_nm is '发起人名字';
+ ALTER TABLE ai_tagging.aitag_tag_log add start_user_org varchar(100);
+comment on column ai_tagging.aitag_tag_log.start_user_org is '发起人机构代码';
+ ALTER TABLE ai_tagging.aitag_tag_log add start_user_endpoint varchar(100);
+comment on column ai_tagging.aitag_tag_log.start_user_endpoint is '发起人网点';
 
+DROP TABLE  ai_tagging.ai_tagging.aitag_org_whitelist;
 -- 创建行社白名单表
-CREATE TABLE ai_tagging.aitag_org_whitelist (
+CREATE TABLE ai_tagging.aitag_instucde_whitelist (
 	id varchar(100),
-	org_name varchar(100),
-	org_code varchar(100),
+	instucde_name varchar(100),
+	instucde_code varchar(100),
 	tag_type varchar(100),
-	CONSTRAINT aitag_org_whitelist_PK PRIMARY KEY (id)
+	CONSTRAINT aitag_instucde_whitelist_PK PRIMARY KEY (id)
 );
-COMMENT ON TABLE ai_tagging.aitag_org_whitelist IS '行社白名单表';
-COMMENT ON COLUMN ai_tagging.aitag_org_whitelist.tag_type IS '标签类型,marine:海洋标签';
-INSERT INTO ai_tagging.aitag_org_whitelist (id, org_name, org_code, tag_type) VALUES ('1', '福建福州农村商业银行股份有限公司', '901020300', 'marine');
-INSERT INTO ai_tagging.aitag_org_whitelist (id, org_name, org_code, tag_type) VALUES ('2', '福建长乐农村商业银行股份有限公司', '901060300', 'marine');
-INSERT INTO ai_tagging.aitag_org_whitelist (id, org_name, org_code, tag_type) VALUES ('3', '福建福清汇通农村商业银行股份有限公司', '901070300', 'marine');
-INSERT INTO ai_tagging.aitag_org_whitelist (id, org_name, org_code, tag_type) VALUES ('4', '福建平潭农村商业银行股份有限公司', '901080300', 'marine');
-INSERT INTO ai_tagging.aitag_org_whitelist (id, org_name, org_code, tag_type) VALUES ('5', '福建连江农村商业银行股份有限公司', '901090300', 'marine');
-INSERT INTO ai_tagging.aitag_org_whitelist (id, org_name, org_code, tag_type) VALUES ('6', '罗源县农村信用合作联社', '901100300', 'marine');
-INSERT INTO ai_tagging.aitag_org_whitelist (id, org_name, org_code, tag_type) VALUES ('7', '厦门农村商业银行股份有限公司', '902010200', 'marine');
-INSERT INTO ai_tagging.aitag_org_whitelist (id, org_name, org_code, tag_type) VALUES ('8', '福建莆田农村商业银行股份有限公司', '904020300', 'marine');
-INSERT INTO ai_tagging.aitag_org_whitelist (id, org_name, org_code, tag_type) VALUES ('9', '福建宁德农村商业银行股份有限公司', '906020300', 'marine');
-INSERT INTO ai_tagging.aitag_org_whitelist (id, org_name, org_code, tag_type) VALUES ('10', '福鼎市农村信用合作联社', '906030300', 'marine');
-INSERT INTO ai_tagging.aitag_org_whitelist (id, org_name, org_code, tag_type) VALUES ('11', '霞浦县农村信用合作联社', '906040300', 'marine');
-INSERT INTO ai_tagging.aitag_org_whitelist (id, org_name, org_code, tag_type) VALUES ('12', '福安市农村信用合作联社', '906050300', 'marine');
-INSERT INTO ai_tagging.aitag_org_whitelist (id, org_name, org_code, tag_type) VALUES ('13', '泉州农村商业银行股份有限公司', '907020300', 'marine');
-INSERT INTO ai_tagging.aitag_org_whitelist (id, org_name, org_code, tag_type) VALUES ('14', '惠安县农村信用合作联社', '907030300', 'marine');
-INSERT INTO ai_tagging.aitag_org_whitelist (id, org_name, org_code, tag_type) VALUES ('15', '福建晋江农村商业银行股份有限公司', '907040300', 'marine');
-INSERT INTO ai_tagging.aitag_org_whitelist (id, org_name, org_code, tag_type) VALUES ('16', '福建石狮农村商业银行股份有限公司', '907060300', 'marine');
-INSERT INTO ai_tagging.aitag_org_whitelist (id, org_name, org_code, tag_type) VALUES ('17', '福建南安农村商业银行股份有限公司', '907070300', 'marine');
-INSERT INTO ai_tagging.aitag_org_whitelist (id, org_name, org_code, tag_type) VALUES ('18', '福建漳州农村商业银行股份有限公司', '908020300', 'marine');
-INSERT INTO ai_tagging.aitag_org_whitelist (id, org_name, org_code, tag_type) VALUES ('19', '福建龙海农村商业银行股份有限公司', '908030300', 'marine');
-INSERT INTO ai_tagging.aitag_org_whitelist (id, org_name, org_code, tag_type) VALUES ('20', '云霄县农村信用合作联社', '908040300', 'marine');
-INSERT INTO ai_tagging.aitag_org_whitelist (id, org_name, org_code, tag_type) VALUES ('21', '福建漳浦农村商业银行股份有限公司', '908050300', 'marine');
-INSERT INTO ai_tagging.aitag_org_whitelist (id, org_name, org_code, tag_type) VALUES ('22', '诏安县农村信用合作联社', '908060300', 'marine');
-INSERT INTO ai_tagging.aitag_org_whitelist (id, org_name, org_code, tag_type) VALUES ('23', '东山县农村信用合作联社', '908080300', 'marine');
+COMMENT ON TABLE ai_tagging.aitag_instucde_whitelist IS '行社白名单表';
+COMMENT ON COLUMN ai_tagging.aitag_instucde_whitelist.tag_type IS '标签类型,marine:海洋标签';
+INSERT INTO ai_tagging.aitag_instucde_whitelist (id, instucde_name, instucde_code, tag_type) VALUES ('1', '福建福州农村商业银行股份有限公司', '901020300', 'marine');
+INSERT INTO ai_tagging.aitag_instucde_whitelist (id, instucde_name, instucde_code, tag_type) VALUES ('2', '福建长乐农村商业银行股份有限公司', '901060300', 'marine');
+INSERT INTO ai_tagging.aitag_instucde_whitelist (id, instucde_name, instucde_code, tag_type) VALUES ('3', '福建福清汇通农村商业银行股份有限公司', '901070300', 'marine');
+INSERT INTO ai_tagging.aitag_instucde_whitelist (id, instucde_name, instucde_code, tag_type) VALUES ('4', '福建平潭农村商业银行股份有限公司', '901080300', 'marine');
+INSERT INTO ai_tagging.aitag_instucde_whitelist (id, instucde_name, instucde_code, tag_type) VALUES ('5', '福建连江农村商业银行股份有限公司', '901090300', 'marine');
+INSERT INTO ai_tagging.aitag_instucde_whitelist (id, instucde_name, instucde_code, tag_type) VALUES ('6', '罗源县农村信用合作联社', '901100300', 'marine');
+INSERT INTO ai_tagging.aitag_instucde_whitelist (id, instucde_name, instucde_code, tag_type) VALUES ('7', '厦门农村商业银行股份有限公司', '902010200', 'marine');
+INSERT INTO ai_tagging.aitag_instucde_whitelist (id, instucde_name, instucde_code, tag_type) VALUES ('8', '福建莆田农村商业银行股份有限公司', '904020300', 'marine');
+INSERT INTO ai_tagging.aitag_instucde_whitelist (id, instucde_name, instucde_code, tag_type) VALUES ('9', '福建宁德农村商业银行股份有限公司', '906020300', 'marine');
+INSERT INTO ai_tagging.aitag_instucde_whitelist (id, instucde_name, instucde_code, tag_type) VALUES ('10', '福鼎市农村信用合作联社', '906030300', 'marine');
+INSERT INTO ai_tagging.aitag_instucde_whitelist (id, instucde_name, instucde_code, tag_type) VALUES ('11', '霞浦县农村信用合作联社', '906040300', 'marine');
+INSERT INTO ai_tagging.aitag_instucde_whitelist (id, instucde_name, instucde_code, tag_type) VALUES ('12', '福安市农村信用合作联社', '906050300', 'marine');
+INSERT INTO ai_tagging.aitag_instucde_whitelist (id, instucde_name, instucde_code, tag_type) VALUES ('13', '泉州农村商业银行股份有限公司', '907020300', 'marine');
+INSERT INTO ai_tagging.aitag_instucde_whitelist (id, instucde_name, instucde_code, tag_type) VALUES ('14', '惠安县农村信用合作联社', '907030300', 'marine');
+INSERT INTO ai_tagging.aitag_instucde_whitelist (id, instucde_name, instucde_code, tag_type) VALUES ('15', '福建晋江农村商业银行股份有限公司', '907040300', 'marine');
+INSERT INTO ai_tagging.aitag_instucde_whitelist (id, instucde_name, instucde_code, tag_type) VALUES ('16', '福建石狮农村商业银行股份有限公司', '907060300', 'marine');
+INSERT INTO ai_tagging.aitag_instucde_whitelist (id, instucde_name, instucde_code, tag_type) VALUES ('17', '福建南安农村商业银行股份有限公司', '907070300', 'marine');
+INSERT INTO ai_tagging.aitag_instucde_whitelist (id, instucde_name, instucde_code, tag_type) VALUES ('18', '福建漳州农村商业银行股份有限公司', '908020300', 'marine');
+INSERT INTO ai_tagging.aitag_instucde_whitelist (id, instucde_name, instucde_code, tag_type) VALUES ('19', '福建龙海农村商业银行股份有限公司', '908030300', 'marine');
+INSERT INTO ai_tagging.aitag_instucde_whitelist (id, instucde_name, instucde_code, tag_type) VALUES ('20', '云霄县农村信用合作联社', '908040300', 'marine');
+INSERT INTO ai_tagging.aitag_instucde_whitelist (id, instucde_name, instucde_code, tag_type) VALUES ('21', '福建漳浦农村商业银行股份有限公司', '908050300', 'marine');
+INSERT INTO ai_tagging.aitag_instucde_whitelist (id, instucde_name, instucde_code, tag_type) VALUES ('22', '诏安县农村信用合作联社', '908060300', 'marine');
+INSERT INTO ai_tagging.aitag_instucde_whitelist (id, instucde_name, instucde_code, tag_type) VALUES ('23', '东山县农村信用合作联社', '908080300', 'marine');
 
 /**
  预设规则的匹配,可以不用人工确认,直接通过推送给画像系统
@@ -82,4 +97,38 @@ INSERT INTO ai_tagging.aitag_predefined_rules (id, defined_rule, tag_type, tag_n
 ('rule_18', '海底管道运输', 'marine', '海洋交通运输业'),
 ('rule_19', '海洋气象服务', 'marine', '海洋自然科学研究和试验发展'),
 ('rule_20', '海洋环境服务', 'marine', '海洋信息集成服务'),
-('rule_21', '其他海洋服务', 'marine', '海洋技术服务');
+('rule_21', '其他海洋服务', 'marine', '海洋技术服务');
+
+/**
+	企业白名单
+**/
+CREATE TABLE ai_tagging.aitag_company_whitelist (
+	id varchar(100) NOT NULL,
+	tag_name varchar(100),
+	tag_code varchar(100),
+	is_valid int,
+	create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+	CONSTRAINT aitag_company_whitelist_pk PRIMARY KEY (id)
+);
+COMMENT ON TABLE  ai_tagging.aitag_company_whitelist IS '企业白名单';
+COMMENT ON COLUMN ai_tagging.aitag_company_whitelist.tag_name is '标签名称';
+COMMENT ON COLUMN ai_tagging.aitag_company_whitelist.tag_code is '标签代码';
+COMMENT ON COLUMN ai_tagging.aitag_company_whitelist.is_valid is '0启用;1停用';
+
+/**
+	企业列表
+**/
+CREATE TABLE ai_tagging.aitag_company_whitelist_detail(
+	id varchar(100) NOT NULL,
+	aitag_company_whitelist_id varchar(100),
+	tag_code varchar(100),
+	company_name varchar(100),
+	company_code varchar(100),
+	create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+	CONSTRAINT aitag_company_whitelist_detail_pk PRIMARY KEY(id)
+);
+COMMENT ON TABLE  ai_tagging.aitag_company_whitelist_detail IS '企业白名单明细';
+COMMENT ON COLUMN ai_tagging.aitag_company_whitelist_detail.aitag_company_whitelist_id is '外键';
+COMMENT ON COLUMN ai_tagging.aitag_company_whitelist_detail.tag_code is '标签代码';
+COMMENT ON COLUMN ai_tagging.aitag_company_whitelist_detail.company_name is '企业名称';
+COMMENT ON COLUMN ai_tagging.aitag_company_whitelist_detail.company_code is '企业统一社会信用代码';

+ 9 - 1
server/yusp-tagging-core/pom.xml

@@ -219,7 +219,15 @@
             <artifactId>httpclient</artifactId>
             <version>4.5.13</version>
         </dependency>
-
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.persistence</groupId>
+            <artifactId>javax.persistence-api</artifactId>
+            <version>2.2</version>
+        </dependency>
 
     </dependencies>
 

+ 92 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagTagComWhiteController.java

@@ -0,0 +1,92 @@
+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.*;
+import cn.com.yusys.yusp.domain.entity.AitagTagCategory;
+import cn.com.yusys.yusp.domain.entity.AitagTagComWhiteListEntity;
+import cn.com.yusys.yusp.domain.entity.AitagTagLogEntity;
+import cn.com.yusys.yusp.domain.vo.*;
+import cn.com.yusys.yusp.model.Result;
+import cn.com.yusys.yusp.service.AitagTagComWhiteListService;
+import cn.com.yusys.yusp.service.AitagTagLogService;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+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;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.List;
+
+import static cn.com.yusys.yusp.config.DataDictionary.FEEDBACK_RESULT_REJECT;
+
+/**
+ * 
+ *
+ * @author 2507040827
+ * @date 2026-02-25 14:56:45
+ */
+@Api(tags = "企业白名单")
+@RestController
+@RequestMapping("/api/aitagcomwhitelist")
+public class AitagTagComWhiteController {
+    /**
+     * AitagTagLogService
+     */
+    @Autowired
+    private AitagTagComWhiteListService comWhiteListService;
+
+    @PostMapping("/list")
+    public Result<List<AitagTagComWhiteListEntity>> list(@RequestBody AitagComWhiteListDto dto) {
+        try {
+            Page<AitagTagComWhiteListEntity> pageResult = comWhiteListService.list(dto);
+            return Result.pageSuccess(pageResult.getRecords(), pageResult.getTotal());
+        } catch (Exception e) {
+            return Result.error("500", "查询日志列表失败:" + e.getMessage());
+        }
+    }
+
+    @PostMapping("/add")
+    public Result<AitagTagComWhiteListEntity> createCategory(@Validated @RequestBody AitagTagComWhiteListEntity dto) {
+        try {
+            comWhiteListService.insert(dto);
+            return Result.success(dto);
+        } catch (Exception e) {
+            return Result.error("500", "新建标签体系失败:" + e.getMessage());
+        }
+    }
+
+    @PostMapping("/update")
+    public Result<AitagTagComWhiteListEntity> update(@Validated @RequestBody AitagTagComWhiteListEntity dto) {
+        try {
+            comWhiteListService.update(dto);
+            return Result.success(dto);
+        } catch (Exception e) {
+            return Result.error("500", "新建标签体系失败:" + e.getMessage());
+        }
+    }
+
+
+    @PostMapping("/delete")
+    public Result delete(@RequestBody AitagTagComWhiteListEntity dto) {
+        comWhiteListService.delete(dto.getId());
+        return Result.success();
+    }
+
+    @GetMapping("/select")
+    public Result<AitagTagComWhiteListEntity> select(String id){
+        AitagTagComWhiteListEntity entity = comWhiteListService.selectById(id);
+        return Result.success(entity);
+    }
+
+
+}

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

@@ -7,8 +7,13 @@ 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.*;
+import cn.com.yusys.yusp.feign.AdminSmOrg;
+import cn.com.yusys.yusp.feign.OcaUserService;
 import cn.com.yusys.yusp.service.AitagTagLogService;
+import cn.com.yusys.yusp.util.Roles;
+import cn.com.yusys.yusp.util.SessionCommonUtil;
 import com.alibaba.excel.EasyExcel;
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -23,6 +28,7 @@ import java.io.IOException;
 import java.net.URLEncoder;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import static cn.com.yusys.yusp.config.DataDictionary.FEEDBACK_RESULT_REJECT;
 
@@ -41,6 +47,8 @@ public class AitagTagLogController {
      */
     @Autowired
     private AitagTagLogService aitagTagLogService;
+    @Autowired
+    private OcaUserService ocaUserService;
 
 
     /**
@@ -52,6 +60,32 @@ public class AitagTagLogController {
     @ApiOperationType("我的配置")
     @PostMapping("/dataOverview")
     public ResultDto<DataOverviewVo> dataOverview(@RequestBody SmartTaggingResultVo taggingResult) {
+        String userId = SessionCommonUtil.getUserId();
+        String role = null;
+        List<String> roles = SessionCommonUtil.getUserRole();
+        if(roles.contains(Roles.TAG_MANAGER)){
+            role = Roles.TAG_MANAGER;
+        }
+        if(roles.contains(Roles.TAG_ADMIN)){
+            role = Roles.TAG_ADMIN;
+            JSONObject org = SessionCommonUtil.getUserOrg();
+            String id = org.getString("id");
+            String code = org.getString("code");
+            List<String> childrens = new ArrayList<>();
+            childrens.add(code);
+            ResultDto<List<AdminSmOrg>> resultDto =  ocaUserService.orgtreequery("A",false,id);
+            if(resultDto!=null && resultDto.getData()!=null && resultDto.getData().size()>0){
+                List<String> codes = resultDto.getData().stream().map(d->d.getOrgCode()).collect(Collectors.toList());
+                childrens.addAll(codes);
+            }
+            taggingResult.setOrgs(childrens);
+        }
+        ResultDto<List<AdminSmOrg>> resultDto =  ocaUserService.orgtreequery("A",false,"0");
+        System.out.println("========to here========");
+        System.out.println(JSON.toJSONString(resultDto.getData()));
+
+        taggingResult.setUserId(userId);
+        taggingResult.setRoleCode(role);
         DataOverviewVo dataOverviewDTO = aitagTagLogService.dataOverview(taggingResult);
         return ResultDto.success(dataOverviewDTO);
     }
@@ -67,6 +101,17 @@ public class AitagTagLogController {
     @ApiOperationType("打标趋势")
     @PostMapping("/taggingTrend")
     public ResultDto<List<IconResVo>> taggingTrend(@RequestBody TaggingTrendReqVo taggingTrendReq) {
+        String userId = SessionCommonUtil.getUserId();
+        String role = null;
+        List<String> roles = SessionCommonUtil.getUserRole();
+        if(roles.contains(Roles.TAG_MANAGER)){
+            role = Roles.TAG_MANAGER;
+        }
+        if(roles.contains(Roles.TAG_ADMIN)){
+            role = Roles.TAG_ADMIN;
+        }
+        taggingTrendReq.setUserId(userId);
+        taggingTrendReq.setRoleCode(role);
         List<IconResVo> taggingTrendRes = aitagTagLogService.taggingTrend(taggingTrendReq);
         return ResultDto.success(taggingTrendRes);
     }
@@ -80,6 +125,17 @@ public class AitagTagLogController {
     @ApiOperationType("标签分布统计")
     @PostMapping("/tagDistStats")
     public ResultDto<List<IconResVo>> tagDistStats(@RequestBody TagDistStatsReqVo resultDTO) {
+        String userId = SessionCommonUtil.getUserId();
+        String role = null;
+        List<String> roles = SessionCommonUtil.getUserRole();
+        if(roles.contains(Roles.TAG_MANAGER)){
+            role = Roles.TAG_MANAGER;
+        }
+        if(roles.contains(Roles.TAG_ADMIN)){
+            role = Roles.TAG_ADMIN;
+        }
+        resultDTO.setUserId(userId);
+        resultDTO.setRoleCode(role);
         List<IconResVo> taggingTrendRes = aitagTagLogService.tagDistStats(resultDTO);
         return ResultDto.success(taggingTrendRes);
     }
@@ -94,10 +150,22 @@ public class AitagTagLogController {
     @ApiOperationType("打标明细")
     @PostMapping("/taggingTransaction")
     public ResultDto<IPage<TagLogDto>> taggingTransaction(@RequestBody TaggingTransactionReqVo transactionReqVo) {
+        String userId = SessionCommonUtil.getUserId();
+        String role = null;
+        List<String> roles = SessionCommonUtil.getUserRole();
+        if(roles.contains(Roles.TAG_MANAGER)){
+            role = Roles.TAG_MANAGER;
+        }
+        if(roles.contains(Roles.TAG_ADMIN)){
+            role = Roles.TAG_ADMIN;
+        }
+        transactionReqVo.setUserId(userId);
+        transactionReqVo.setRoleCode(role);
         IPage<TagLogDto> page = aitagTagLogService.taggingDetails(transactionReqVo);
         return ResultDto.success(page.getRecords()).total(page.getTotal());
     }
 
+
     /**
      * 打标结果详情
      *

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

@@ -0,0 +1,22 @@
+package cn.com.yusys.yusp.domain.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * API 日志列表查询 DTO
+ */
+@Data
+public class AitagComWhiteListDto {
+
+    @ApiModelProperty(value = "查询条件")
+    private String search;
+
+    @ApiModelProperty(value = "页码", example = "1")
+    private Integer page = 1;
+
+    @ApiModelProperty(value = "每页大小", example = "10")
+    private Integer pageSize = 10;
+
+    private String id;
+}

+ 14 - 2
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/fastapidto/AiTaggingRequestDto.java

@@ -11,7 +11,7 @@ import javax.validation.constraints.NotBlank;
 public class AiTaggingRequestDto {
 
 
-    @NotBlank(message = "业务属性不能为空")
+    @NotBlank(message = "业务属性不能为空,贷款申请编号")
     @ApiModelProperty(value = "业务属性", required = true)
     private String businessAttr;
 
@@ -34,9 +34,21 @@ public class AiTaggingRequestDto {
     @ApiModelProperty(value = "用户机构", required = false)
     private String userOrg;
 
-    @ApiModelProperty(value = "用户终端", required = false)
+    @ApiModelProperty(value = "用户网点", required = false)
     private String userEndpoint;
 
     @ApiModelProperty(value="行社代码",required = false)
     private String instucde;
+
+    @ApiModelProperty(value="行社名称",required = false)
+    private String instucdeNm;
+
+    @ApiModelProperty(value="企业名称",required = false)
+    private String companyNm;
+
+    @ApiModelProperty(value="企业统一社会信用代码",required = false)
+    private String companyCode;
+
+    @ApiModelProperty(value="ESB流水号",required = false)
+    private String esbSeqNo;
 }

+ 41 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/entity/AitagTagComWhiteListDetailEntity.java

@@ -0,0 +1,41 @@
+package cn.com.yusys.yusp.domain.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 
+ *
+ * @author 2507040827
+ * @date 2026-02-25 14:56:45
+ */
+
+@Data
+@TableName("aitag_company_whitelist_detail")
+@ApiModel(value = "AitagTagComWhiteListDetailEntity", description = "企业白名单明细表")
+public class AitagTagComWhiteListDetailEntity {
+
+    /**
+     * id
+     **/
+    @ApiModelProperty(value="id")
+    @TableId(type=IdType.UUID)
+    private String id;
+
+    @ApiModelProperty(value = "外键")
+    private String aitagCompanyWhitelistId;
+
+    @ApiModelProperty(value="所属标签代码")
+    private String tagCode;
+
+    @ApiModelProperty(value="企业名称")
+    private String companyName;
+
+    @ApiModelProperty(value="企业代码")
+    private String companyCode;
+
+}

+ 48 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/entity/AitagTagComWhiteListEntity.java

@@ -0,0 +1,48 @@
+package cn.com.yusys.yusp.domain.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 
+ *
+ * @author 2507040827
+ * @date 2026-02-25 14:56:45
+ */
+
+@Data
+@TableName("aitag_company_whitelist")
+@ApiModel(value = "AitagTagComWhiteListEntity", description = "企业白名单类型表")
+public class AitagTagComWhiteListEntity {
+
+    /**
+     * id
+     **/
+    @ApiModelProperty(value="id")
+    @TableId(type=IdType.UUID)
+    private String id;
+
+    /**
+     * 标签名称
+     **/
+    @ApiModelProperty(value = "标签名称")
+    private String tagName;
+
+    /**
+     * 标签代码
+     */
+    @ApiModelProperty(value="标签代码")
+    private String tagCode;
+
+    /**
+     * 状态,0启用;1停用
+     */
+    @ApiModelProperty(value = "状态")
+    private int isValid = 0;
+}

+ 6 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/entity/AitagTagLogEntity.java

@@ -164,4 +164,10 @@ passr: true/false
      **/
     @ApiModelProperty(value = "标签标识 0:正常数据; 1:测试数据")
     private Integer tagScope;
+
+    @ApiModelProperty(value="发起人ID")
+    private String startUserId;
+
+    @ApiModelProperty(value="发起人机构")
+    private String startUserOrg;
 }

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

@@ -5,6 +5,9 @@ import cn.com.yusys.yusp.commons.module.adapter.query.PageQuery;
 import cn.com.yusys.yusp.commons.util.date.DateUtils;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import lombok.Data;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
 
 /**
  * 智能打标结果
@@ -32,6 +35,10 @@ public class SmartTaggingResultVo extends PageQuery {
      */
     private String categoryId;
 
+    private String userId;
+    private String roleCode;
+    private List<String> orgs;
+
 
     public String getCategoryExp() {
         return "[{\"category_id\": \""+categoryId+"\"}]";

+ 177 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/feign/AdminSmOrg.java

@@ -0,0 +1,177 @@
+package cn.com.yusys.yusp.feign;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import java.io.Serializable;
+
+
+/**
+ * The persistent class for the admin_sm_org database table.
+ *
+ */
+@Entity
+@Table(name="admin_sm_org")
+public class AdminSmOrg  implements Serializable{
+	private static final long serialVersionUID = 1L;
+
+	@Id
+	@Column(name="ORG_ID")
+	private String orgId;
+
+	@Column(name="CONT_TEL")
+	private String contTel;
+
+	@Column(name="CONT_USR")
+	private String contUsr;
+
+	@Column(name="INSTU_ID")
+	private String instuId;
+
+	@Column(name="LAST_CHG_DT")
+	private String lastChgDt;
+
+	@Column(name="LAST_CHG_USR")
+	private String lastChgUsr;
+
+	@Column(name="ORG_ADDR")
+	private String orgAddr;
+
+	@Column(name="ORG_CODE")
+	private String orgCode;
+
+	@Column(name="ORG_LEVEL")
+	private String orgLevel;
+
+	@Column(name="ORG_NAME")
+	private String orgName;
+
+	@Column(name="ORG_STS")
+	private String orgSts;
+
+	@Column(name="UP_ORG_ID")
+	private String upOrgId;
+
+	@Column(name="UP_ORG_NAME")
+	private String upOrgName;
+
+	@Column(name="ZIP_CDE")
+	private String zipCde;
+
+	public AdminSmOrg() {
+	}
+
+	public String getUpOrgName() {
+		return upOrgName;
+	}
+
+	public void setUpOrgName(String upOrgName) {
+		this.upOrgName = upOrgName;
+	}
+
+	public String getOrgId() {
+		return this.orgId;
+	}
+
+	public void setOrgId(String orgId) {
+		this.orgId = orgId;
+	}
+
+	public String getContTel() {
+		return this.contTel;
+	}
+
+	public void setContTel(String contTel) {
+		this.contTel = contTel;
+	}
+
+	public String getContUsr() {
+		return this.contUsr;
+	}
+
+	public void setContUsr(String contUsr) {
+		this.contUsr = contUsr;
+	}
+
+	public String getInstuId() {
+		return this.instuId;
+	}
+
+	public void setInstuId(String instuId) {
+		this.instuId = instuId;
+	}
+
+	public String getLastChgDt() {
+		return this.lastChgDt;
+	}
+
+	public void setLastChgDt(String lastChgDt) {
+		this.lastChgDt = lastChgDt;
+	}
+
+	public String getLastChgUsr() {
+		return this.lastChgUsr;
+	}
+
+	public void setLastChgUsr(String lastChgUsr) {
+		this.lastChgUsr = lastChgUsr;
+	}
+
+	public String getOrgAddr() {
+		return this.orgAddr;
+	}
+
+	public void setOrgAddr(String orgAddr) {
+		this.orgAddr = orgAddr;
+	}
+
+	public String getOrgCode() {
+		return this.orgCode;
+	}
+
+	public void setOrgCode(String orgCode) {
+		this.orgCode = orgCode;
+	}
+
+	public String getOrgLevel() {
+		return this.orgLevel;
+	}
+
+	public void setOrgLevel(String orgLevel) {
+		this.orgLevel = orgLevel;
+	}
+
+	public String getOrgName() {
+		return this.orgName;
+	}
+
+	public void setOrgName(String orgName) {
+		this.orgName = orgName;
+	}
+
+	public String getOrgSts() {
+		return this.orgSts;
+	}
+
+	public void setOrgSts(String orgSts) {
+		this.orgSts = orgSts;
+	}
+
+	public String getUpOrgId() {
+		return this.upOrgId;
+	}
+
+	public void setUpOrgId(String upOrgId) {
+		this.upOrgId = upOrgId;
+	}
+
+	public String getZipCde() {
+		return this.zipCde;
+	}
+
+	public void setZipCde(String zipCde) {
+		this.zipCde = zipCde;
+	}
+
+}

+ 27 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/feign/OcaUserService.java

@@ -0,0 +1,27 @@
+package cn.com.yusys.yusp.feign;
+
+import cn.com.yusys.yusp.commons.module.adapter.query.QueryModel;
+import cn.com.yusys.yusp.commons.module.adapter.web.rest.ResultDto;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.List;
+
+/**
+ * 用户信息获取客户端.
+ *
+ * @author dusong
+ * @since 2.1.1
+ */
+@FeignClient(name = "${service.name.yusp.oca}", path = "/api")
+public interface OcaUserService {
+
+
+    @GetMapping("/adminsmorg/orgtreequery")
+    ResultDto<List<AdminSmOrg>> orgtreequery(@RequestParam("orgSts")String orgSts,@RequestParam("lazy")boolean lazy,@RequestParam("orgId")String orgId);
+
+    // 获取机构列表
+    @GetMapping( "/adminsmorg/")
+    public ResultDto<List<AdminSmOrg>> adminsmorg(QueryModel model);
+}

+ 45 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/mapper/AitagComWhitelistDetailMapper.java

@@ -0,0 +1,45 @@
+package cn.com.yusys.yusp.mapper;
+
+import cn.com.yusys.yusp.commons.mybatisplus.mapper.BaseMapper;
+import cn.com.yusys.yusp.domain.entity.AitagApiLog;
+import cn.com.yusys.yusp.domain.entity.AitagTagComWhiteListDetailEntity;
+import cn.com.yusys.yusp.domain.entity.AitagTagComWhiteListEntity;
+import cn.com.yusys.yusp.domain.entity.AitagTagLogEntity;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Date;
+import java.util.List;
+
+@Mapper
+public interface AitagComWhitelistDetailMapper extends BaseMapper<AitagTagComWhiteListDetailEntity> {
+
+    /**
+     * 插入API调用日志
+     * @return 影响行数
+     */
+    int insert(AitagTagComWhiteListDetailEntity entity);
+
+    /**
+     * 统计符合条件的企业白名单类型数量
+     * @return 数量
+     */
+    long count(@Param("search") String search);
+
+    /**
+     * 分页查询日志列表
+     * @param offset 偏移量
+     * @param limit 限制数量
+     * @return 日志列表
+     */
+    List<AitagTagComWhiteListDetailEntity> select(@Param("search") String search,
+                                            @Param("offset") int offset,
+                                            @Param("limit") int limit);
+
+    /**
+     * 根据ID查询日志详情
+     * @param id 日志ID
+     * @return 日志详情
+     */
+    AitagTagComWhiteListDetailEntity selectById(@Param("id") String id);
+}

+ 48 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/mapper/AitagComWhitelistMapper.java

@@ -0,0 +1,48 @@
+package cn.com.yusys.yusp.mapper;
+
+import cn.com.yusys.yusp.commons.mybatisplus.mapper.BaseMapper;
+import cn.com.yusys.yusp.domain.entity.AitagApiLog;
+import cn.com.yusys.yusp.domain.entity.AitagTagComWhiteListEntity;
+import cn.com.yusys.yusp.domain.entity.AitagTagLogEntity;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Date;
+import java.util.List;
+
+@Mapper
+public interface AitagComWhitelistMapper extends BaseMapper<AitagTagComWhiteListEntity> {
+
+    /**
+     * 插入API调用日志
+     * @return 影响行数
+     */
+    int insert(AitagTagComWhiteListEntity entity);
+
+    /**
+     * 统计符合条件的企业白名单类型数量
+     * @return 数量
+     */
+    long count(@Param("search") String search);
+
+    /**
+     * 分页查询日志列表
+     * @param offset 偏移量
+     * @param limit 限制数量
+     * @return 日志列表
+     */
+    List<AitagTagComWhiteListEntity> select(@Param("search") String search,
+                                    @Param("offset") int offset,
+                                    @Param("limit") int limit);
+
+    /**
+     * 根据ID查询日志详情
+     * @param id 日志ID
+     * @return 日志详情
+     */
+    AitagTagComWhiteListEntity selectById(@Param("id") String id);
+
+    void update(AitagTagComWhiteListEntity entity);
+
+    void delete(@Param("id") String id);
+}

+ 19 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/AitagTagComWhiteListDetailService.java

@@ -0,0 +1,19 @@
+package cn.com.yusys.yusp.service;
+
+import cn.com.yusys.yusp.domain.entity.AitagTagComWhiteListDetailEntity;
+import cn.com.yusys.yusp.domain.entity.AitagTagComWhiteListEntity;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * 
+ *
+ * @author 2507040827
+ * @date 2026-02-25 14:56:45
+ */
+
+public interface AitagTagComWhiteListDetailService extends IService<AitagTagComWhiteListDetailEntity> {
+
+    
+
+}
+

+ 31 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/AitagTagComWhiteListService.java

@@ -0,0 +1,31 @@
+package cn.com.yusys.yusp.service;
+
+import cn.com.yusys.yusp.domain.dto.AitagApiLogQueryDto;
+import cn.com.yusys.yusp.domain.dto.AitagComWhiteListDto;
+import cn.com.yusys.yusp.domain.dto.TagLogDto;
+import cn.com.yusys.yusp.domain.entity.AitagTagComWhiteListEntity;
+import cn.com.yusys.yusp.domain.entity.AitagTagLogEntity;
+import cn.com.yusys.yusp.domain.vo.*;
+import cn.com.yusys.yusp.mapper.AitagComWhitelistMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.List;
+
+/**
+ * 
+ *
+ * @author 2507040827
+ * @date 2026-02-25 14:56:45
+ */
+
+public interface AitagTagComWhiteListService extends IService<AitagTagComWhiteListEntity> {
+
+    Page<AitagTagComWhiteListEntity> list(AitagComWhiteListDto queryDTO);
+    void insert(AitagTagComWhiteListEntity entity);
+    void delete(String id);
+    void update(AitagTagComWhiteListEntity entity);
+    AitagTagComWhiteListEntity selectById(String id);
+}
+

+ 29 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/impl/AitagTagComWhitelistDetailServiceImpl.java

@@ -0,0 +1,29 @@
+package cn.com.yusys.yusp.service.impl;
+
+import cn.com.yusys.yusp.domain.entity.AitagTagComWhiteListDetailEntity;
+import cn.com.yusys.yusp.domain.entity.AitagTagComWhiteListEntity;
+import cn.com.yusys.yusp.mapper.AitagComWhitelistDetailMapper;
+import cn.com.yusys.yusp.mapper.AitagComWhitelistMapper;
+import cn.com.yusys.yusp.service.AitagTagComWhiteListDetailService;
+import cn.com.yusys.yusp.service.AitagTagComWhiteListService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * 
+ *
+ * @author 2507040827
+ * @date 2026-02-25 14:56:45
+ */
+
+@Service("aitagComWhitelistDetailService")
+@Slf4j
+public class AitagTagComWhitelistDetailServiceImpl extends ServiceImpl<AitagComWhitelistDetailMapper, AitagTagComWhiteListDetailEntity> implements AitagTagComWhiteListDetailService {
+
+    @Autowired
+    private AitagComWhitelistDetailMapper comWhitelistDetailMapper;
+
+
+}

+ 100 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/impl/AitagTagComWhitelistServiceImpl.java

@@ -0,0 +1,100 @@
+package cn.com.yusys.yusp.service.impl;
+
+import cn.com.yusys.yusp.commons.util.date.DateUtils;
+import cn.com.yusys.yusp.config.DataDictionary;
+import cn.com.yusys.yusp.domain.dto.AitagComWhiteListDto;
+import cn.com.yusys.yusp.domain.dto.TagLogDto;
+import cn.com.yusys.yusp.domain.entity.AitagApiLog;
+import cn.com.yusys.yusp.domain.entity.AitagTagComWhiteListEntity;
+import cn.com.yusys.yusp.domain.entity.AitagTagLogEntity;
+import cn.com.yusys.yusp.domain.vo.*;
+import cn.com.yusys.yusp.mapper.AitagComWhitelistMapper;
+import cn.com.yusys.yusp.mapper.AitagTagInfoDao;
+import cn.com.yusys.yusp.mapper.AitagTagLogDao;
+import cn.com.yusys.yusp.service.AitagTagComWhiteListService;
+import cn.com.yusys.yusp.service.AitagTagLogService;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.YearMonth;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+import static cn.com.yusys.yusp.config.DataDictionary.*;
+
+/**
+ * 
+ *
+ * @author 2507040827
+ * @date 2026-02-25 14:56:45
+ */
+
+@Service("aitagComWhiteListService")
+@Slf4j
+public class AitagTagComWhitelistServiceImpl extends ServiceImpl<AitagComWhitelistMapper, AitagTagComWhiteListEntity> implements AitagTagComWhiteListService {
+
+    @Autowired
+    private AitagComWhitelistMapper comWhitelistMapper;
+
+
+    @Override
+    public Page<AitagTagComWhiteListEntity> list(AitagComWhiteListDto queryDTO) {
+        int page = queryDTO.getPage() != null ? queryDTO.getPage() : 1;
+        int pageSize = queryDTO.getPageSize() != null ? queryDTO.getPageSize() : 10;
+        int offset = (page - 1) * pageSize;
+
+        // 查询总记录数
+        long total = comWhitelistMapper.count(queryDTO.getSearch());
+
+        // 查询列表数据
+        List<AitagTagComWhiteListEntity> logs = comWhitelistMapper.select(
+                queryDTO.getSearch(),
+                offset,
+                pageSize
+        );
+
+        Page<AitagTagComWhiteListEntity> pageResult = new Page<>(page, pageSize, total);
+        pageResult.setRecords(logs);
+        return pageResult;
+
+    }
+
+    @Override
+    public void insert(AitagTagComWhiteListEntity entity) {
+        comWhitelistMapper.insert(entity);
+    }
+
+    @Override
+    public void delete(String id) {
+        comWhitelistMapper.delete(id);
+    }
+
+    @Override
+    public void update(AitagTagComWhiteListEntity entity) {
+        comWhitelistMapper.update(entity);
+    }
+
+    @Override
+    public AitagTagComWhiteListEntity selectById(String id) {
+        return comWhitelistMapper.selectById(id);
+    }
+}

+ 45 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/impl/AitagTagLogServiceImpl.java

@@ -9,6 +9,7 @@ import cn.com.yusys.yusp.mapper.AitagTagInfoDao;
 import cn.com.yusys.yusp.mapper.AitagTagLogDao;
 import cn.com.yusys.yusp.domain.entity.AitagTagLogEntity;
 import cn.com.yusys.yusp.service.AitagTagLogService;
+import cn.com.yusys.yusp.util.Roles;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -75,6 +76,22 @@ public class AitagTagLogServiceImpl extends ServiceImpl<AitagTagLogDao, AitagTag
         queryWrapper.in(AitagTagLogEntity::getState, DataDictionary.RESULT_PUSHED,DataDictionary.MANAGER_CONFIRMED);
         queryWrapper.eq(AitagTagLogEntity::getTagScope, PROD_DATA);
         queryWrapper.eq(AitagTagLogEntity::getIsDelete, NON_DELETE);
+
+        if(taggingResult.getUserId()!=null && taggingResult.getRoleCode()!=null && taggingResult.getRoleCode().equals(Roles.TAG_MANAGER)){
+            queryWrapper.and(w -> w
+                    .eq(AitagTagLogEntity::getStartUserId, taggingResult.getUserId())
+                    .or()
+                    .eq(AitagTagLogEntity::getFeedbackUserId, taggingResult.getUserId())
+            );
+        }
+        if(taggingResult.getUserId()!=null && taggingResult.getRoleCode()!=null && taggingResult.getRoleCode().equals(Roles.TAG_ADMIN)){
+            queryWrapper.and(w -> w
+                    .in(AitagTagLogEntity::getStartUserOrg, taggingResult.getOrgs())
+                    .or()
+                    .in(AitagTagLogEntity::getStartUserOrg, taggingResult.getOrgs())
+            );
+        }
+
         Integer totalConfirmedCnt = this.baseMapper.selectCount(queryWrapper);
         log.info("查询出符合条件的打标完成数据:{} 条",totalConfirmedCnt);
 
@@ -210,6 +227,20 @@ public class AitagTagLogServiceImpl extends ServiceImpl<AitagTagLogDao, AitagTag
         if (StringUtils.isNotBlank(transactionReqVo.getLoanApplicationNo())){
             queryWrapper.eq(AitagTagLogEntity::getBusinessAttr, transactionReqVo.getLoanApplicationNo());
         }
+        if(transactionReqVo.getUserId()!=null && transactionReqVo.getRoleCode()!=null && transactionReqVo.getRoleCode().equals(Roles.TAG_MANAGER)){
+            queryWrapper.and(w -> w
+                    .eq(AitagTagLogEntity::getStartUserId, transactionReqVo.getUserId())
+                    .or()
+                    .eq(AitagTagLogEntity::getFeedbackUserId, transactionReqVo.getUserId())
+            );
+        }
+        if(transactionReqVo.getRoleCode()!=null && transactionReqVo.getRoleCode().equals(Roles.TAG_ADMIN)){
+            queryWrapper.and(w -> w
+                    .in(AitagTagLogEntity::getStartUserOrg, transactionReqVo.getOrgs())
+                    .or()
+                    .in(AitagTagLogEntity::getFeedbackUserOrg, transactionReqVo.getOrgs())
+            );
+        }
         queryWrapper.eq(AitagTagLogEntity::getTagScope, PROD_DATA);
         queryWrapper.eq(AitagTagLogEntity::getIsDelete, NON_DELETE);
         queryWrapper.orderByDesc(AitagTagLogEntity::getInsertTime);
@@ -258,6 +289,20 @@ public class AitagTagLogServiceImpl extends ServiceImpl<AitagTagLogDao, AitagTag
         query.in(AitagTagLogEntity::getState, DataDictionary.RESULT_PUSHED,DataDictionary.MANAGER_CONFIRMED);
         query.eq(AitagTagLogEntity::getTagScope, PROD_DATA);
         query.eq(AitagTagLogEntity::getIsDelete, NON_DELETE);
+        if(transactionReqVo.getUserId()!=null && transactionReqVo.getRoleCode()!=null && transactionReqVo.getRoleCode().equals(Roles.TAG_MANAGER)){
+            query.and(w -> w
+                    .eq(AitagTagLogEntity::getStartUserId, transactionReqVo.getUserId())
+                    .or()
+                    .eq(AitagTagLogEntity::getFeedbackUserId, transactionReqVo.getUserId())
+            );
+        }
+        if(transactionReqVo.getRoleCode()!=null && transactionReqVo.getRoleCode().equals(Roles.TAG_ADMIN)){
+            query.and(w -> w
+                    .in(AitagTagLogEntity::getStartUserOrg, transactionReqVo.getOrgs())
+                    .or()
+                    .in(AitagTagLogEntity::getFeedbackUserOrg, transactionReqVo.getOrgs())
+            );
+        }
         query.orderByDesc(AitagTagLogEntity::getInsertTime);
         return this.baseMapper.selectList(query);
     }

+ 18 - 1
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/impl/FastApiServiceImpl.java

@@ -25,6 +25,8 @@ import org.springframework.stereotype.Service;
 
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
+import java.util.Arrays;
+import java.util.stream.Collectors;
 
 @Slf4j
 @Service
@@ -79,6 +81,19 @@ public class FastApiServiceImpl implements FastApiService {
             }
             if(request.getInstucde()!=null){
                 jsonBody.put("instucde",request.getInstucde());
+
+            }
+            if(request.getInstucdeNm()!=null){
+                jsonBody.put("instucde_nm",request.getInstucdeNm());
+            }
+            if(request.getCompanyNm()!=null){
+                jsonBody.put("company_nm",request.getCompanyNm());
+            }
+            if(request.getCompanyCode()!=null){
+                jsonBody.put("company_code",request.getCompanyCode());
+            }
+            if(request.getEsbSeqNo()!=null){
+                jsonBody.put("esb_seq_no", request.getEsbSeqNo());
             }
 
             String requestBody = jsonBody.toJSONString();
@@ -132,7 +147,9 @@ public class FastApiServiceImpl implements FastApiService {
                     return errorResponse;
                 }
 
-                return JSON.parseObject(responseBody, AiTaggingQueryResponseVo.class);
+                AiTaggingQueryResponseVo v =  JSON.parseObject(responseBody, AiTaggingQueryResponseVo.class);
+                v.getData().setResult(Arrays.stream(v.getData().getResult()).filter(r->r.getPassr()).toArray(AiTaggingQueryResponseVo.AiTagResultVo[]::new));
+                return v;
             }
         } catch (Exception e) {
             log.error("调用 AI 打标查询接口失败", e);

+ 6 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/util/Roles.java

@@ -0,0 +1,6 @@
+package cn.com.yusys.yusp.util;
+
+public class Roles {
+    public static final String TAG_MANAGER = "aitag02";//客户经理
+    public static final String TAG_ADMIN ="aitag01"; //打标管理员
+}

+ 65 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/util/SessionCommonUtil.java

@@ -9,9 +9,12 @@ import org.springframework.stereotype.Component;
 import org.springframework.web.context.request.RequestAttributes;
 import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
+import reactor.util.function.Tuple3;
 
 import javax.annotation.PostConstruct;
 import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+import java.util.stream.Collectors;
 
 
 @Component
@@ -75,5 +78,67 @@ public class SessionCommonUtil {
         throw BizException.of("E009");
     }
 
+    public static List<String> getUserRole() {
+        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
+        if (requestAttributes != null) {
+            HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
+            String authorization = request.getHeader("Authorization");
+            if (authorization != null) {
+                String jwtToken = authorization.startsWith("Bearer ") ? authorization.substring(7) : authorization;
+                String jsonStr = (String) redisTemplate.opsForValue().get("access:"+jwtToken);
+                if (jsonStr != null) {
+                    // 解析JSON数组
+                    JSONArray objects = JSONArray.parseArray(jsonStr);
+                    if (objects.size() >= 2) {
+                        String map = objects.get(1).toString();
+                        JSONObject jsonObject = JSONObject.parseObject(map);
+                        String userInfo = jsonObject.getString("userInfo");
+                        System.out.println(userInfo);
+                        JSONObject userInfoMap = JSONObject.parseObject(userInfo);
+                        JSONArray ja = userInfoMap.getJSONArray("roles");
+                        return ja.stream().map(jo->{
+                            JSONObject jo1 = (JSONObject) jo;
+                            return jo1.getString("code");
+                        }).collect(Collectors.toList());
+                    }
+                }
+            }else{
+                throw BizException.of("E009");
+            }
+        }
+        throw BizException.of("E009");
+    }
+
+    // <id,code,name>
+    public static JSONObject getUserOrg(){
+        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
+        if (requestAttributes != null) {
+            HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
+            String authorization = request.getHeader("Authorization");
+            if (authorization != null) {
+                String jwtToken = authorization.startsWith("Bearer ") ? authorization.substring(7) : authorization;
+                String jsonStr = (String) redisTemplate.opsForValue().get("access:"+jwtToken);
+                if (jsonStr != null) {
+                    // 解析JSON数组
+                    JSONArray objects = JSONArray.parseArray(jsonStr);
+                    if (objects.size() >= 2) {
+                        String map = objects.get(1).toString();
+                        JSONObject jsonObject = JSONObject.parseObject(map);
+                        String userInfo = jsonObject.getString("userInfo");
+                        System.out.println(userInfo);
+                        JSONObject userInfoMap = JSONObject.parseObject(userInfo);
+                        JSONObject jo = userInfoMap.getJSONObject("org");
+                        String code =  jo.getString("code");
+                        String id = jo.getString("id");
+                        String name = jo.getString("name");
+                        return jo;
+                    }
+                }
+            }else{
+                throw BizException.of("E009");
+            }
+        }
+        throw BizException.of("E009");
+    }
 
 }

+ 58 - 0
server/yusp-tagging-core/src/main/resources/mapper/AitagComWhitelistDetailMapper.xml

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.com.yusys.yusp.mapper.AitagComWhitelistDetailMapper">
+
+    <!-- 插入API调用日志 -->
+    <insert id="insert" parameterType="cn.com.yusys.yusp.domain.entity.AitagTagComWhiteListDetailEntity">
+        INSERT INTO aitag_company_whitelist_detail (
+            id,
+            aitag_company_whitelist_id,
+            tag_code,
+            company_name,
+            company_code
+        ) VALUES (
+                     #{id},
+                     #{aitagCompanyWhitelistId},
+                     #{tagCode},
+                     #{companyName},
+                     #{companyCode}
+                 )
+    </insert>
+
+
+    <select id="count" resultType="long">
+        SELECT COUNT(*)
+        FROM aitag_company_whitelist_detail
+        <where>
+            <if test="search != null">
+                and (company_name like CONCAT('%', #{search}, '%') or company_code like CONCAT('%', #{search}, '%'))
+            </if>
+
+        </where>
+    </select>
+
+    <select id="select" resultType="cn.com.yusys.yusp.domain.entity.AitagTagComWhiteListDetailEntity">
+        SELECT id,
+        aitag_company_whitelist_id,
+        tag_code,
+        company_name,
+        company_code
+        FROM aitag_company_whitelist_detail
+        <where>
+            is_valid = 0
+            <if test="search != null">
+                and (tag_name like CONCAT('%', #{search}, '%') or tag_code like CONCAT('%', #{search}, '%'))
+            </if>
+
+        </where>
+        ORDER BY create_time DESC
+        LIMIT #{offset}, #{limit}
+    </select>
+
+    <select id="selectById" resultType="cn.com.yusys.yusp.domain.entity.AitagTagComWhiteListDetailEntity">
+        SELECT *
+        FROM aitag_company_whitelist_detail
+        WHERE id = #{id}
+    </select>
+
+</mapper>

+ 61 - 0
server/yusp-tagging-core/src/main/resources/mapper/AitagComWhitelistMapper.xml

@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.com.yusys.yusp.mapper.AitagComWhitelistMapper">
+
+    <!-- 插入API调用日志 -->
+    <insert id="insert" parameterType="cn.com.yusys.yusp.domain.entity.AitagTagComWhiteListEntity">
+        INSERT INTO aitag_company_whitelist (
+            id,
+            tag_name,
+            tag_code,
+            is_valid
+        ) VALUES (
+                     #{id},
+                     #{tagName},
+                     #{tagCode},
+                     #{isValid}
+                 )
+    </insert>
+
+
+    <select id="count" resultType="long">
+        SELECT COUNT(*)
+        FROM aitag_company_whitelist
+        <where>
+            is_valid = 0
+            <if test="search != null">
+                and (tag_name like CONCAT('%', #{search}, '%') or tag_code like CONCAT('%', #{search}, '%'))
+            </if>
+
+        </where>
+    </select>
+
+    <select id="select" resultType="cn.com.yusys.yusp.domain.entity.AitagTagComWhiteListEntity">
+        SELECT id, tag_name, tag_code,
+        FROM aitag_company_whitelist
+        <where>
+            is_valid = 0
+            <if test="search != null">
+                and (tag_name like CONCAT('%', #{search}, '%') or tag_code like CONCAT('%', #{search}, '%'))
+            </if>
+
+        </where>
+        ORDER BY create_time DESC
+        LIMIT #{offset}, #{limit}
+    </select>
+
+    <select id="selectById" resultType="cn.com.yusys.yusp.domain.entity.AitagTagComWhiteListEntity">
+        SELECT *
+        FROM aitag_company_whitelist
+        WHERE id = #{id}
+    </select>
+
+    <update id="update" parameterType="cn.com.yusys.yusp.domain.entity.AitagTagComWhiteListEntity">
+        update aitag_company_whitelist set is_valid = #{isValid},tag_name = #{tagName},tag_code=#{tagCode} where id = #{id}
+    </update>
+
+    <delete id="delete">
+        delete from aitag_company_whitelist where id = #{id}
+    </delete>
+
+</mapper>

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

@@ -39,6 +39,16 @@
             <if test="categoryId != null and categoryId != ''">
                 AND result @> #{categoryExp}::jsonb
             </if>
+            <if test="roleCode != null and roleCode == 'aitag02' and userId != null">
+                AND (start_user_id = #{userId} or feedback_user_id = #{userId})
+            </if>
+            <if test="roleCode != null and roleCode == 'aitag01' ">
+                and (start_user_org in <foreach collection="orgs" item="code" open="(" separator="," close=")">
+                #{code}
+            </foreach> or feedback_user_org in <foreach collection="orgs" item="code" open="(" separator="," close=")">
+                #{code}
+            </foreach>)
+            </if>
     </select>
 
     <select id="selectTagReportByDay" resultType="cn.com.yusys.yusp.domain.vo.IconResVo" parameterType="cn.com.yusys.yusp.domain.vo.SmartTaggingResultVo">
@@ -59,6 +69,16 @@
             <if test="categoryId != null and categoryId != ''">
                 AND result @> #{categoryExp}::jsonb
             </if>
+            <if test="roleCode != null and roleCode == 'aitag02' and userId != null">
+                AND (start_user_id = #{userId} or feedback_user_id = #{userId})
+            </if>
+            <if test="roleCode != null and roleCode == 'aitag01' ">
+                and (start_user_org in <foreach collection="orgs" item="code" open="(" separator="," close=")">
+                #{code}
+            </foreach> or feedback_user_org in <foreach collection="orgs" item="code" open="(" separator="," close=")">
+                #{code}
+            </foreach>)
+            </if>
         GROUP BY DATE_FORMAT(insert_time, '%Y-%m-%d')
         ORDER BY stat;
     </select>
@@ -81,6 +101,16 @@
             <if test="categoryId != null and categoryId != ''">
                 AND result @> #{categoryExp}::jsonb
             </if>
+            <if test="roleCode != null and roleCode == 'aitag02' and userId != null">
+                AND (start_user_id = #{userId} or feedback_user_id = #{userId})
+            </if>
+            <if test="roleCode != null and roleCode == 'aitag01' ">
+                and (start_user_org in <foreach collection="orgs" item="code" open="(" separator="," close=")">
+                #{code}
+            </foreach> or feedback_user_org in <foreach collection="orgs" item="code" open="(" separator="," close=")">
+                #{code}
+            </foreach>)
+            </if>
         GROUP BY DATE_FORMAT(insert_time, '%Y-%m')
         ORDER BY stat;
     </select>
@@ -121,6 +151,16 @@
         <if test="endTaggingTime != null and endTaggingTime != ''">
             AND #{endTaggingTime} >= insert_time
         </if>
+        <if test="roleCode != null and roleCode == 'aitag02' and userId != null">
+            AND (t.start_user_id = #{userId} or t.feedback_user_id = #{userId})
+        </if>
+        <if test="roleCode != null and roleCode == 'aitag01' ">
+            and (start_user_org in <foreach collection="orgs" item="code" open="(" separator="," close=")">
+            #{code}
+        </foreach> or feedback_user_org in <foreach collection="orgs" item="code" open="(" separator="," close=")">
+            #{code}
+        </foreach>)
+        </if>
         UNION ALL
         SELECT elem->>'tag_name' AS tag_name
         FROM aitag_tag_log t
@@ -141,6 +181,16 @@
         <if test="endTaggingTime != null and endTaggingTime != ''">
             AND #{endTaggingTime} >= insert_time
         </if>
+        <if test="roleCode != null and roleCode == 'aitag02' and userId != null">
+            AND (t.start_user_id = #{userId} or t.feedback_user_id = #{userId})
+        </if>
+        <if test="roleCode != null and roleCode == 'aitag01' ">
+            and (t.start_user_org in <foreach collection="orgs" item="code" open="(" separator="," close=")">
+            #{code}
+        </foreach> or t.feedback_user_org in <foreach collection="orgs" item="code" open="(" separator="," close=")">
+            #{code}
+        </foreach>)
+        </if>
         ) valid_tags
         WHERE tag_name IS NOT NULL
         GROUP BY tag_name

+ 5 - 0
server/yusp-tagging-starter/pom.xml

@@ -223,6 +223,11 @@
         <artifactId>easyexcel</artifactId>
         <version>3.3.4</version>
     </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
 
     </dependencies>
 

+ 3 - 0
server/yusp-tagging-starter/src/main/java/cn/com/yusys/yusp/detail/App.java

@@ -6,6 +6,8 @@ import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+//import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.cloud.openfeign.EnableFeignClients;
 import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.transaction.annotation.EnableTransactionManagement;
 
@@ -16,6 +18,7 @@ import java.net.URL;
 @MapperScan("cn.com.yusys.yusp.mapper")
 @EnableScheduling
 @EnableTransactionManagement
+@EnableFeignClients(basePackages = {"cn.com.yusys.yusp.feign"})
 public class App {
     public static void main(String[] args) {
 

+ 4 - 0
server/yusp-tagging-starter/src/main/resources/bootstrap.yml

@@ -25,3 +25,7 @@ spring:
           refresh: true #配置扩展属性动态刷新
 server:
   port: 30001
+service:
+  name:
+    yusp:
+      oca: base-oca

+ 37 - 0
server/yusp-tagging-starter/src/test/java/cn/com/yusys/yusp/TestManagerAuth.java

@@ -0,0 +1,37 @@
+package cn.com.yusys.yusp;
+
+import cn.com.yusys.yusp.commons.module.adapter.web.rest.ResultDto;
+import cn.com.yusys.yusp.detail.App;
+import cn.com.yusys.yusp.domain.vo.SmartTaggingResultVo;
+import cn.com.yusys.yusp.feign.AdminSmOrg;
+import cn.com.yusys.yusp.feign.OcaUserService;
+import cn.com.yusys.yusp.service.AitagTagLogService;
+import cn.com.yusys.yusp.service.impl.AitagTagLogServiceImpl;
+import cn.com.yusys.yusp.util.Roles;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.util.List;
+
+@SpringBootTest(classes = App.class)
+public class TestManagerAuth {
+
+    @Autowired
+    private AitagTagLogService aitagTagLogService;
+    @Autowired
+    private OcaUserService ocaUserService;
+
+    @Test
+    public void test() {
+        SmartTaggingResultVo taggingResult = new SmartTaggingResultVo();
+        taggingResult.setUserId("aaa");
+        taggingResult.setRoleCode(Roles.TAG_MANAGER);
+        aitagTagLogService.dataOverview(taggingResult);
+    }
+
+    @Test
+    public void test2() {
+        ResultDto<List<AdminSmOrg>> resultDto =  ocaUserService.orgtreequery("a",false,"0");
+    }
+}

+ 172 - 0
web/src/views/aiTagging/comWhiteList/components/LogDetailDrawer.vue

@@ -0,0 +1,172 @@
+<template>
+  <el-drawer
+    title="日志详情"
+    :visible="visible"
+    direction="rtl"
+    size="50%"
+    :close-on-click-modal="false"
+    @close="handleClose"
+  >
+    <div class="log-detail-container">
+      <!-- 基本信息 -->
+      <div class="detail-section">
+        <div class="info-item">
+          <span class="label">用户名称:</span>
+          <span class="value">{{ logDetail.userName }}</span>
+        </div>
+        <div class="info-item">
+          <span class="label">用户ID:</span>
+          <span class="value">{{ logDetail.userId }}</span>
+        </div>
+        <div class="info-item">
+          <span class="label">操作类型:</span>
+          <span class="value">{{ logDetail.operationType }}</span>
+        </div>
+        <div class="info-item">
+          <span class="label">操作时间:</span>
+          <span class="value">{{ logDetail.operationTime }}</span>
+        </div>
+      </div>
+
+      <!-- 输入信息 -->
+      <div class="detail-section">
+        <div class="info-item">
+          <span class="label">输入:</span>
+          <pre class="code-block">{{ logDetail.input }}</pre>
+        </div>
+      </div>
+
+      <!-- 输出信息 -->
+      <div class="detail-section">
+        <div class="info-item">
+          <span class="label">输出:</span>
+          <pre class="code-block">{{ logDetail.output }}</pre>
+        </div>
+      </div>
+
+
+    </div>
+  </el-drawer>
+</template>
+
+<script>
+export default {
+  name: 'LogDetailDrawer',
+  props: {
+    visible: {
+      type: Boolean,
+      default: false
+    },
+    logDetail: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  methods: {
+    // 处理关闭
+    handleClose() {
+      this.$emit('update:visible', false)
+    },
+    
+
+    
+    // 格式化JSON
+    formatJson(json) {
+      if (!json) return ''
+      try {
+        return JSON.stringify(json, null, 2)
+      } catch (error) {
+        return json
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+.log-detail-container {
+  padding: 20px;
+  max-height: calc(100vh - 120px);
+  overflow-y: auto;
+}
+
+.detail-section {
+  /* margin-bottom: 30px;
+  padding-bottom: 20px;
+  border-bottom: 1px solid #f0f0f0; */
+}
+
+.section-title {
+  font-size: 16px;
+  font-weight: bold;
+  margin: 0 0 16px 0;
+  color: #303133;
+}
+
+.info-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
+  gap: 16px;
+}
+
+.info-item {
+  display: flex;
+  flex-direction: row;
+  align-items: flex-start;
+  margin-bottom: 16px;
+}
+
+.label {
+  font-weight: bold;
+  color: #606266;
+  width: 80px; /* 设置固定宽度 */
+  text-align: right; /* 文字居右显示 */
+  flex-shrink: 0;
+  margin-right: 12px;
+}
+
+.value {
+  color: #303133;
+  word-break: break-all;
+  flex: 1;
+  min-width: 200px;
+}
+
+.code-block {
+  background-color: #f5f7fa;
+  border: 1px solid #e4e7ed;
+  border-radius: 4px;
+  padding: 12px;
+  font-family: 'Courier New', Courier, monospace;
+  font-size: 14px;
+  line-height: 1.5;
+  overflow-x: auto;
+  white-space: pre-wrap;
+  margin: 0;
+  flex: 1;
+  min-width: 200px;
+}
+
+.detail-footer {
+  display: flex;
+  justify-content: flex-end;
+  margin-top: 40px;
+  padding-top: 20px;
+  border-top: 1px solid #f0f0f0;
+}
+
+/* 响应式设计 */
+@media (max-width: 768px) {
+  .log-detail-container {
+    padding: 10px;
+  }
+
+  .info-grid {
+    grid-template-columns: 1fr;
+  }
+
+  .code-block {
+    font-size: 12px;
+  }
+}
+</style>

+ 320 - 0
web/src/views/aiTagging/comWhiteList/index.vue

@@ -0,0 +1,320 @@
+<template>
+  <div class="tagging-logs-container">
+    <!-- 顶部搜索栏 -->
+    <div class="search-bar">
+      <el-form :inline="true" :model="searchForm" label-width="110px">
+        <el-form-item label="查询条件:">
+          <el-input v-model="search" placeholder="请输入查询条件"/>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="handleSearch">查询</el-button>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="" plain @click="handleReset">重置</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+
+    <!-- 表格和分页容器 -->
+    <div class="table-and-pagination-container">
+      <!-- 数据表格 -->
+      <div class="table-container">
+        <div class="table-header">
+          <el-button type="primary" size="small" icon="el-icon-refresh" @click="handleRefresh">刷新</el-button>
+        </div>
+        <el-table :data="logs" style="width: 100%">
+          <el-table-column prop="userName" label="用户名称" ></el-table-column>
+          <el-table-column prop="userId" label="用户id" ></el-table-column>
+          <el-table-column prop="operationType" label="操作类型" ></el-table-column>
+          <el-table-column prop="createDate" label="操作时间" ></el-table-column>
+          <el-table-column prop="action" label="操作" width="100">
+            <template slot-scope="scope">
+              <el-button type="text" @click="handleViewDetail(scope.row)">查看详情</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+
+      <!-- 分页控件 -->
+      <div class="pagination">
+        <el-pagination
+          :current-page="currentPage"
+          :page-size="pageSize"
+          :page-sizes="[10, 20, 50]"
+          layout="total, sizes, prev, pager, next, jumper"
+          :total="totalCount"
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange"
+        ></el-pagination>
+      </div>
+    </div>
+
+    <!-- 日志详情抽屉 -->
+    <LogDetailDrawer
+      :visible="drawerVisible"
+      :log-detail="currentLogDetail"
+      @update:visible="drawerVisible = $event"
+    />
+  </div>
+</template>
+
+<script>
+import LogDetailDrawer from './components/LogDetailDrawer.vue'
+
+export default {
+  name: 'TaggingLogs',
+  components: {
+    LogDetailDrawer
+  },
+  data() {
+    return {
+      // 搜索表单
+      searchForm: {
+        search: ''
+      },
+      
+      // 日志列表
+      logs: [],
+      
+      // 分页数据
+      totalCount: 0,
+      currentPage: 1,
+      pageSize: 10,
+      
+      // 抽屉相关
+      drawerVisible: false,
+      currentLogDetail: {}
+    }
+  },
+  mounted() {
+    // 初始加载日志列表
+    this.loadLogs();
+  },
+  methods: {
+    // 加载日志列表
+    loadLogs() {
+      // 处理时间参数
+      let startTime = '';
+      let endTime = '';
+      
+      if (this.searchForm.callTime && this.searchForm.callTime.length === 2) {
+        // 格式化开始时间为 2026-03-02 00:00:00
+        const start = new Date(this.searchForm.callTime[0]);
+        startTime = this.formatDateTime(start, 'start');
+        
+        // 格式化结束时间为 2026-03-02 23:59:59
+        const end = new Date(this.searchForm.callTime[1]);
+        endTime = this.formatDateTime(end, 'end');
+      }
+      
+      yufp.service.request({
+        url: backend.tagServer + "/api/aitag-apilog/list",
+        method: 'POST',
+        data: {
+          startTime: startTime,
+          endTime: endTime,
+          page: this.currentPage,
+          pageSize: this.pageSize
+        },
+        callback: (code, error, response) => {
+          if (response.code == '0') {
+            this.logs = response.data || [];
+            this.totalCount = response.total || 0;
+          } else {
+            this.$message.error(response.message || '获取日志列表失败');
+          }
+        }
+      });
+    },
+
+    // 搜索日志
+    handleSearch() {
+      console.log('搜索日志:', this.searchForm)
+      this.currentPage = 1;
+      this.loadLogs();
+    },
+
+    // 重置搜索
+    handleReset() {
+      this.searchForm = {
+        search: ''
+      }
+      console.log('重置搜索')
+      this.currentPage = 1;
+      this.loadLogs();
+    },
+
+    // 刷新日志
+    handleRefresh() {
+      console.log('刷新日志')
+      this.currentPage = 1;
+      this.pageSize = 10;
+      this.loadLogs();
+    },
+
+    // 查看详情
+    handleViewDetail(row) {
+      console.log('查看详情:', row)
+      
+      // 调用后端接口获取日志详情
+      yufp.service.request({
+        url: backend.tagServer + "/api/aitag-apilog/query",
+        method: 'POST',
+        data: {
+          id: row.id
+        },
+        callback: (code, error, response) => {
+          if (response.code == '0') {
+            // 构建与LogDetailDrawer.vue期望结构一致的详情数据
+            this.currentLogDetail = {
+              userName: response.data.userName,
+              userId: response.data.userId,
+              operationType: response.data.operationType,
+              operationTime: response.data.createDate,
+              input: response.data.inputData,
+              output: response.data.outputData
+            }
+            this.drawerVisible = true
+          } else {
+            this.$message.error(response.message || '获取日志详情失败');
+          }
+        }
+      });
+    },
+
+    // 分页大小变化
+    handleSizeChange(size) {
+      console.log('每页条数:', size)
+      this.pageSize = size
+      this.loadLogs();
+    },
+
+    // 当前页码变化
+    handleCurrentChange(current) {
+      console.log('当前页码:', current)
+      this.currentPage = current
+      this.loadLogs();
+    },
+    
+    // 格式化日期时间
+    formatDateTime(date, type) {
+      const year = date.getFullYear();
+      const month = String(date.getMonth() + 1).padStart(2, '0');
+      const day = String(date.getDate()).padStart(2, '0');
+      
+      if (type === 'start') {
+        return `${year}-${month}-${day} 00:00:00`;
+      } else if (type === 'end') {
+        return `${year}-${month}-${day} 23:59:59`;
+      }
+      
+      return '';
+    }
+  }
+}
+</script>
+
+<style scoped>
+.tagging-logs-container {
+  padding: 0;
+  background-color: transparent !important;
+  height: 100% !important;
+  box-shadow: none !important;
+  display: flex;
+  flex-direction: column;
+}
+
+/* 搜索栏样式 */
+.search-bar {
+  background-color: #fff;
+  padding: 20px;
+  border-radius: 8px;
+  margin-bottom: 20px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+}
+
+.search-row {
+  display: flex;
+  align-items: center;
+  margin-bottom: 16px;
+}
+
+.search-row:last-child {
+  margin-bottom: 0;
+  justify-content: flex-end;
+}
+
+.search-row .el-form-item {
+  margin-right: 32px;
+  margin-bottom: 0;
+}
+
+.search-row .el-form-item:last-child {
+  margin-right: 0;
+}
+
+.search-row .el-button {
+  margin-left: 12px;
+}
+
+/* 表格和分页容器 */
+.table-and-pagination-container {
+  background-color: #fff;
+  flex: 1;
+  border-radius: 8px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+  margin-bottom: 20px;
+  overflow: hidden;
+}
+
+/* 表格容器 */
+.table-container {
+  padding: 20px 20px 10px;
+}
+
+/* 表格头部 */
+.table-header {
+  margin-bottom: 16px;
+}
+
+/* 分页 */
+.pagination {
+  display: flex;
+  justify-content: flex-end;
+  align-items: center;
+}
+.pagination .el-pagination{
+  padding: 10px 20px;
+}
+
+/* 响应式设计 */
+@media (max-width: 1200px) {
+  .search-form {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 12px;
+  }
+}
+
+@media (max-width: 768px) {
+  .tagging-logs-container {
+    padding: 10px;
+  }
+
+  .search-bar,
+  .table-container,
+  .pagination {
+    padding: 10px;
+  }
+
+  .pagination {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 16px;
+  }
+
+  .el-pagination {
+    align-self: flex-end;
+  }
+}
+</style>