Jelajahi Sumber

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

jianggs 2 hari lalu
induk
melakukan
421f4cda7d
95 mengubah file dengan 6170 tambahan dan 608 penghapusan
  1. 24 0
      agent/build.md
  2. 32 0
      agent/child.html
  3. 6 6
      agent/config.ini
  4. 38 0
      agent/parent.html
  5. 23 37
      agent/pdm.lock
  6. 3 5
      agent/pyproject.toml
  7. 88 0
      agent/readme.md
  8. 19 9
      agent/src/agent/agent.py
  9. 21 24
      agent/src/agent/api_inner.py
  10. 70 25
      agent/src/agent/api_outter.py
  11. 30 20
      agent/src/agent/core/dao.py
  12. 1 2
      agent/src/agent/core/es.py
  13. 0 35
      agent/tests/api_tagging_test.py
  14. 53 0
      agent/tests/generate_excel.py
  15. 1911 0
      agent/tests/test_data.txt
  16. 22 0
      agent/tests/test_feedback.py
  17. 7 1
      agent/tests/test_generate_reg.py
  18. 91 16
      agent/tests/test_inner_api.py
  19. 4 0
      agent/tests/test_query.py
  20. 14 2
      agent/tests/test_reg.py
  21. 2 2
      agent/tests/test_tagging.py
  22. 25 0
      agent/tests/test_tagging_batch.py
  23. TEMPAT SAMPAH
      agent/服务接口定义.xlsx
  24. 11 0
      server/pom.xml
  25. 36 1
      server/yusp-tagging-core/pom.xml
  26. 33 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/annotation/RequireRole.java
  27. 34 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/aop/ApiLogAspect.java
  28. 13 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/condition/AuthEnabledCondition.java
  29. 190 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/config/AuthInterceptor.java
  30. 20 7
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/config/DataDictionary.java
  31. 31 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/config/FastApiConfig.java
  32. 18 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/config/MyBatisPlusConfig.java
  33. 59 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/config/WebMvcConfig.java
  34. 2 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagAppController.java
  35. 47 12
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagTagCategoryController.java
  36. 200 24
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagTagInfoController.java
  37. 108 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagTagInfoVersionController.java
  38. 16 14
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagTagLogController.java
  39. 153 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagUserController.java
  40. 82 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/FastApiController.java
  41. 26 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/LoginRequestDto.java
  42. 29 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/TagImportDto.java
  43. 114 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/TagInfoDto.java
  44. 114 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/TagInfoVersionDto.java
  45. 47 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/fastapidto/AiTaggingFeedbackRequestDto.java
  46. 17 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/fastapidto/AiTaggingQueryRequestDto.java
  47. 24 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/fastapidto/AiTaggingRequestDto.java
  48. 1 1
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/entity/AitagTagDailyAggEntity.java
  49. 21 96
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/entity/AitagTagInfoEntity.java
  50. 115 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/entity/AitagTagInfoVersionEntity.java
  51. 6 5
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/entity/AitagTagLogEntity.java
  52. 57 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/entity/AitagUser.java
  53. 5 98
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/vo/AitagTagInfoQueryVo.java
  54. 93 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/vo/AitagTagInfoVersionQueryVo.java
  55. 23 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/vo/GenerateRegexVo.java
  56. 41 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/vo/LoginResponseVo.java
  57. 17 1
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/vo/SmartTaggingResultVo.java
  58. 104 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/vo/TagNodeVo.java
  59. 35 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/vo/VersionRollbackVo.java
  60. 53 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/vo/fastapivo/AiTaggingQueryResponseVo.java
  61. 20 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/vo/fastapivo/AiTaggingResponseVo.java
  62. 23 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/mapper/AitagTagCategoryMapper.java
  63. 7 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/mapper/AitagTagInfoDao.java
  64. 17 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/mapper/AitagTagInfoVersionDao.java
  65. 23 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/mapper/AitagUserMapper.java
  66. 9 2
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/AitagTagCategoryService.java
  67. 29 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/AitagTagInfoService.java
  68. 25 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/AitagTagInfoVersionService.java
  69. 7 1
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/AitagTagLogService.java
  70. 46 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/AuthService.java
  71. 25 17
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/DistributedScheduledTask.java
  72. 31 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/FastApiService.java
  73. 44 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/TagImportListener.java
  74. 57 8
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/impl/AitagTagCategoryServiceImpl.java
  75. 384 5
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/impl/AitagTagInfoServiceImpl.java
  76. 81 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/impl/AitagTagInfoVersionServiceImpl.java
  77. 61 44
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/impl/AitagTagLogServiceImpl.java
  78. 118 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/impl/AuthServiceImpl.java
  79. 216 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/impl/FastApiServiceImpl.java
  80. 81 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/util/AuthContextUtil.java
  81. 126 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/util/JwtUtil.java
  82. 53 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/util/SessionCommonUtil.java
  83. 2 4
      server/yusp-tagging-core/src/main/resources/mapper/AitagApiLogMapper.xml
  84. 36 0
      server/yusp-tagging-core/src/main/resources/mapper/AitagTagCategoryMapper.xml
  85. 5 5
      server/yusp-tagging-core/src/main/resources/mapper/AitagTagDailyAggMapper.xml
  86. 61 4
      server/yusp-tagging-core/src/main/resources/mapper/AitagTagInfoMapper.xml
  87. 21 0
      server/yusp-tagging-core/src/main/resources/mapper/AitagTagInfoVersionMapper.xml
  88. 24 24
      server/yusp-tagging-core/src/main/resources/mapper/AitagTagLogMapper.xml
  89. 10 0
      server/yusp-tagging-core/src/main/resources/mapper/AitagUserMapper.xml
  90. 10 1
      server/yusp-tagging-core/src/main/resources/messages/yusp_input_msg.properties
  91. TEMPAT SAMPAH
      server/yusp-tagging-core/src/main/resources/template/tag_batch_Import_template.xlsx
  92. 14 7
      server/yusp-tagging-starter/pom.xml
  93. 4 0
      server/yusp-tagging-starter/src/main/java/cn/com/yusys/yusp/detail/App.java
  94. 17 41
      server/yusp-tagging-starter/src/main/resources/application.yml
  95. 4 2
      server/yusp-tagging-starter/src/main/resources/bootstrap.yml

+ 24 - 0
agent/build.md

@@ -0,0 +1,24 @@
+# 1. 锁定并安装(确保 pdm.lock 最新)
+pdm install --prod
+
+# 2. 导出 requirements.txt
+pdm export -o requirements.txt --prod
+
+# 3. 下载所有 wheel
+rm -rf release
+mkdir -p release
+pip download -r requirements.txt -d release/ --prefer-binary
+
+# 4. 导出pdm wheel
+pip download pdm -d ./release
+
+# 5. 打包
+rm release.tar.gz
+tar -czvf release.tar.gz release/
+
+# 6. 在目标机上安装pdm
+pip install --no-index --find-links ./release pdm
+
+# 7. 修改 PDM 配置,设置 find-links
+pdm config pypi.url file://$(pwd)/release
+pdm install

+ 32 - 0
agent/child.html

@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+  <meta charset="UTF-8" />
+  <title>子页面(iframe)</title>
+</head>
+<body>
+  <h2>子页面(iframe)</h2>
+  <div id="output">等待接收消息...</div>
+
+  <script>
+    // 监听来自父页面的消息
+    window.addEventListener('message', (event) => {
+      // 安全检查:验证来源是否可信
+      if (event.origin !== window.parent.location.origin) {
+        console.warn('收到未知来源的消息,已忽略:', event.origin);
+        return;
+      }
+
+      const data = event.data;
+      console.log('收到来自父页面的消息:', data);
+
+      // 显示消息内容
+      document.getElementById('output').innerHTML = `
+        <p>消息: ${data.message}</p>
+        <p>用户ID: ${data.userId}</p>
+        <p>时间: ${data.timestamp}</p>
+      `;
+    });
+  </script>
+</body>
+</html>

+ 6 - 6
agent/config.ini

@@ -1,14 +1,14 @@
 [database]
-host = 10.192.72.13
-port = 6780
+host = 10.192.72.11
+port = 4321
 user = root
-password = 123456
-database = fjnx
+password = admin
+database = ai_tagging
 
 [llm]
-model = qwen3-vl-32b-instruct
+model = Qwen3-4B-Instruct
 temperature = 0.2
-base_url = http://172.16.40.16:20001/compatible-mode/v1
+base_url = http://10.192.72.12:8003/v1
 api_key = 
 
 [embedding]

+ 38 - 0
agent/parent.html

@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+  <meta charset="UTF-8" />
+  <title>父页面</title>
+</head>
+<body>
+  <h2>父页面</h2>
+  <button id="sendBtn">向 iframe 发送消息</button>
+
+  <!-- 注意:src 必须是同源或你明确知道目标 origin -->
+  <iframe id="myIframe" src="child.html" width="600" height="300"></iframe>
+
+  <script>
+    const iframe = document.getElementById('myIframe');
+    const sendBtn = document.getElementById('sendBtn');
+
+    // 等待 iframe 加载完成再发送消息更安全
+    iframe.onload = () => {
+      console.log('iframe 已加载');
+    };
+
+    sendBtn.addEventListener('click', () => {
+      const data = {
+        message: '你好,子页面!',
+        userId: 12345,
+        timestamp: new Date().toISOString()
+      };
+
+      // 向 iframe 发送消息
+      // 第二个参数是目标 origin,出于安全考虑建议不要用 '*'
+      // 如果 child.html 在同一域名下,可以用 window.location.origin
+      console.log('向 iframe 发送消息:', data);
+      iframe.contentWindow.postMessage(data, window.location.origin);
+    });
+  </script>
+</body>
+</html>

+ 23 - 37
agent/pdm.lock

@@ -5,7 +5,7 @@
 groups = ["default"]
 strategy = ["inherit_metadata"]
 lock_version = "4.5.0"
-content_hash = "sha256:456f199d9527d2770f35dba560e5b05b51f845d481d5433946ddd0326bf3b9b5"
+content_hash = "sha256:6733268f6b19c3ef998cc0e93e0c7287e601b0ce3a4de4d63bcb10731f9ab579"
 
 [[metadata.targets]]
 requires_python = "==3.10.*"
@@ -139,18 +139,6 @@ files = [
 ]
 
 [[package]]
-name = "dbutils"
-version = "3.1.2"
-requires_python = ">=3.7"
-summary = "Database connections for multi-threaded environments."
-groups = ["default"]
-marker = "python_version == \"3.10\""
-files = [
-    {file = "dbutils-3.1.2-py3-none-any.whl", hash = "sha256:0cb388a89eeecf04089aef113a7007c3fac9199e9580c8549829f954870c403a"},
-    {file = "dbutils-3.1.2.tar.gz", hash = "sha256:160b5788154f1adeddc61080daff1530b4df2ba0d45af1c3bfbac76db24186b3"},
-]
-
-[[package]]
 name = "distro"
 version = "1.9.0"
 requires_python = ">=3.6"
@@ -584,6 +572,28 @@ files = [
 ]
 
 [[package]]
+name = "psycopg2-binary"
+version = "2.9.11"
+requires_python = ">=3.9"
+summary = "psycopg2 - Python-PostgreSQL Database Adapter"
+groups = ["default"]
+marker = "python_version == \"3.10\""
+files = [
+    {file = "psycopg2-binary-2.9.11.tar.gz", hash = "sha256:b6aed9e096bf63f9e75edf2581aa9a7e7186d97ab5c177aa6c87797cd591236c"},
+    {file = "psycopg2_binary-2.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d6fe6b47d0b42ce1c9f1fa3e35bb365011ca22e39db37074458f27921dca40f2"},
+    {file = "psycopg2_binary-2.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a6c0e4262e089516603a09474ee13eabf09cb65c332277e39af68f6233911087"},
+    {file = "psycopg2_binary-2.9.11-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c47676e5b485393f069b4d7a811267d3168ce46f988fa602658b8bb901e9e64d"},
+    {file = "psycopg2_binary-2.9.11-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:a28d8c01a7b27a1e3265b11250ba7557e5f72b5ee9e5f3a2fa8d2949c29bf5d2"},
+    {file = "psycopg2_binary-2.9.11-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5f3f2732cf504a1aa9e9609d02f79bea1067d99edf844ab92c247bbca143303b"},
+    {file = "psycopg2_binary-2.9.11-cp310-cp310-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:865f9945ed1b3950d968ec4690ce68c55019d79e4497366d36e090327ce7db14"},
+    {file = "psycopg2_binary-2.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:91537a8df2bde69b1c1db01d6d944c831ca793952e4f57892600e96cee95f2cd"},
+    {file = "psycopg2_binary-2.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4dca1f356a67ecb68c81a7bc7809f1569ad9e152ce7fd02c2f2036862ca9f66b"},
+    {file = "psycopg2_binary-2.9.11-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:0da4de5c1ac69d94ed4364b6cbe7190c1a70d325f112ba783d83f8440285f152"},
+    {file = "psycopg2_binary-2.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:37d8412565a7267f7d79e29ab66876e55cb5e8e7b3bbf94f8206f6795f8f7e7e"},
+    {file = "psycopg2_binary-2.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:c665f01ec8ab273a61c62beeb8cce3014c214429ced8a308ca1fc410ecac3a39"},
+]
+
+[[package]]
 name = "pydantic"
 version = "2.12.5"
 requires_python = ">=3.9"
@@ -637,30 +647,6 @@ files = [
 ]
 
 [[package]]
-name = "pymysql"
-version = "1.1.2"
-requires_python = ">=3.8"
-summary = "Pure Python MySQL Driver"
-groups = ["default"]
-marker = "python_version == \"3.10\""
-files = [
-    {file = "pymysql-1.1.2-py3-none-any.whl", hash = "sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9"},
-    {file = "pymysql-1.1.2.tar.gz", hash = "sha256:4961d3e165614ae65014e361811a724e2044ad3ea3739de9903ae7c21f539f03"},
-]
-
-[[package]]
-name = "python-multipart"
-version = "0.0.22"
-requires_python = ">=3.10"
-summary = "A streaming multipart parser for Python"
-groups = ["default"]
-marker = "python_version == \"3.10\""
-files = [
-    {file = "python_multipart-0.0.22-py3-none-any.whl", hash = "sha256:2b2cd894c83d21bf49d702499531c7bafd057d730c201782048f7945d82de155"},
-    {file = "python_multipart-0.0.22.tar.gz", hash = "sha256:7340bef99a7e0032613f56dc36027b959fd3b30a787ed62d310e951f7c3a3a58"},
-]
-
-[[package]]
 name = "pyyaml"
 version = "6.0.3"
 requires_python = ">=3.8"

+ 3 - 5
agent/pyproject.toml

@@ -1,22 +1,20 @@
 [project]
 name = "agent"
 version = "0.1.0"
-description = "ai-tagging"
+description = "Default template for PDM package"
 authors = [
     {name = "jiayongqiang", email = "15936285643@163.com"},
 ]
 dependencies = [
     "fastapi>=0.128.0",
     "uvicorn>=0.40.0",
-    "python-multipart>=0.0.22",
     "requests>=2.32.5",
     "langchain>=1.2.9",
     "langchain-openai>=1.1.7",
-    "dbutils>=3.1.2",
-    "pymysql>=1.1.2",
     "elasticsearch==8.9.0",
     "numpy>=2.2.6",
     "asyncer>=0.0.17",
+    "psycopg2-binary>=2.9.11",
 ]
 requires-python = ">=3.10"
 readme = "README.md"
@@ -27,7 +25,7 @@ build.package-dir = "src"
 distribution = true
 
 [tool.pdm.scripts]
-start = "uvicorn agent.main:app --host 0.0.0.0 --port 8080"
+start = "uvicorn agent.main:app --host 0.0.0.0 --port 9876"
 start-bg = { shell = "nohup pdm run start > uvicorn.log 2>&1 & echo 'Started in background'; echo \"Logs in uvicorn.log\"" }
 
 [build-system]

+ 88 - 0
agent/readme.md

@@ -1 +1,89 @@
 # AI-TAGGING
+
+## 1. 对管理端接口
+
+### 1.1 同步标签接口
+- URL:/api/aitag/admin/v1/synchronize_tag
+- METHOD: post
+- Content-Type: application/json
+- BODY:{"tag_ids": [xx,xx]}
+  
+### 1.2 同步删除标签接口
+- URL: /api/aitag/admin/v1/delete_tag
+- METHOD:post
+- Content-Type: application/json
+- Body:{"tag_ids": ["2","3"]}
+
+### 1.3 生成正则表达式接口
+- URL: /api/aitag/admin/v1/generate_reg
+- METHOD:POST
+- Context-Type:application/json
+- Body:{
+        "tag_name": "智能电网",
+        "tag_remark": "指以智能电网技术为核心,建设或改造电力系统,提升电力系统智能化水平和运行效率的项目。"
+    }
+
+## 2. 对下游系统接口
+
+### 2.1 智能打标接口
+- URL: /api/aitag/v1/tagging
+- METHOD:POST
+- Content-Type:application/json
+- Body:{
+  - "business_attr": "test_attr",
+  - "phrase": "职业:水产养殖人员 投向:海水养殖 用途:个人经营",
+  - "tag_category_id":"xxx" 非必填
+  - }
+
+### 2.2 查询接口
+- URL:/api/aitag/v1/query
+- METHOD:GET
+- params:
+  - business_attr:d372684dbae64b3dadd33b631480d946 # 申请编号
+- response:
+```
+{
+    "code":200,
+    "message":"AI Query Endpoint",
+    "data":{
+        "id":"016e96f4b76e4d1097421e9e055db48e",
+        "app_id":null,
+        "insert_time":"2026-02-26T18:23:32","business_attr":"d372684dbae64b3dadd33b631480d946",
+        "phrase":"职业:水产养殖人员 投向:海水养殖 用途:个人经营",
+        "attachment":null,"attachment_url":null,
+        "result":"[{\"id\": \"20260200001\", \"tag_code\": \"011\", \"tag_name\": \"海水养殖\", \"desc\": \"贷款用途明确为‘个人经营’,且投向为‘海水养殖’,直接对应标签定义中‘在海水环境中进行人工养殖’的核心语义。尽管未使用‘海水养殖’等术语,但‘投向:海水养殖’已明确表达在
+        海水环境中开展养殖活动,符合‘通过人工干预方式培育水生生物’的生产本质。该信息足以支撑在本笔贷款层面命中‘海水养殖’标签,且无任何符合排除情形(如捕捞、服务支持等)的描述。\", \"passr\": true}]",
+        "feedback_user_id":null,
+        "feedback_user_nm":null,
+        "feedback_time":null,
+        "feedback":null,
+        "feedback_result":null,
+        "state":1,
+        "consuming_time":null,
+        "category_code":null,
+        "contract_no":null,
+        "reg_result":"['20260200001']",
+        "feedback_user_org":null,
+        "feedback_user_endpoint":null,
+        "is_delete":0
+        }
+}
+```
+
+### 2.3 反馈接口
+- URL: /api/aitag/v1/feedback
+- METHOD:GET
+- BODY:
+```
+{
+    "user_id": "12345",
+    "user_nm": "张三",
+    "feedback": "agree",
+    "contract_no": "HT-2024-001",
+    "user_org": "XX公司",
+    "user_endpoint": "XX网点",
+    "business_attr": "99c1c7bc976c45d0912e914a602d547f"
+}
+```
+
+

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

@@ -16,7 +16,8 @@ llm = init_chat_model(
     model=model, 
     api_key=api_key_env_var,
     base_url=base_url,
-    temperature= temperature
+    temperature= temperature,
+    extra_body={"enable_thinking": False}
 )
 
 class Lable(BaseModel):
@@ -26,6 +27,7 @@ class Lable(BaseModel):
     id: str = Field(description="标签ID")
     tag_code: str = Field(description="标签编码")
     tag_name: str = Field(description="标签名称")
+    tag_path: str = Field(description="标签路径")
     desc: str = Field(description="给出简要的理由说明该标签为何被保留或剔除。")
     passr:bool = Field(description="是否保留该标签,true表示保留,false表示剔除。")
 
@@ -80,6 +82,7 @@ async def reflect_check(context: str, labels: list):
         3.不以企业整体行业属性替代对贷款具体内容的判断
         4.所有判断应服务于产业打标的可用性与可解释性
     """
+    print(prompt)
     response = await agent.ainvoke({
         "messages": [{"role":"system","content": prompt}]
     },context = {})
@@ -87,15 +90,16 @@ async def reflect_check(context: str, labels: list):
 
 class GenerateReg(BaseModel):
     """ 大模型生成的正则表达式 """
-    reg: str = Field(..., description="大模型生成的正则表达式")
+    reg: str = Field(description="大模型生成的正则表达式")
+
+async def generate_reg(tag_name: str, tag_remark: str):
 
-async def generate_reg(tag_info):
     prompt = f"""
         你是一名银行信贷业务产业标签打标平台的规则设计专家。你的任务是:仅根据我提供的【标签名称】与【语义定义】,生成一条中文关键词正则规则,用于极短文本字段(投向 / 贷款用途)的第一阶段初筛。
 ###
 【输入】
- 标签名称:{tag_info[1] if tag_info else ''}
- 语义定义:{tag_info[2] if tag_info else ''}
+标签名称:{tag_name}
+ 语义定义:{tag_remark}
 ###
 【数据特征】
  ● 文本极短(通常 2~8 字)
@@ -121,19 +125,25 @@ async def generate_reg(tag_info):
 12.关键词应尽量覆盖:
  ● 文本未出现标签名称
  ● 文本未出现核心字面词
- ● 仅通过业务对象 / 场景 / 行为即可识别的情况      
+ ● 仅通过业务对象 / 场景 / 行为即可识别的情况
+###
+【输出要求】
+只输出最终那一条正则表达式
+ 不要解释
+ 不要 JSON
+ 不要换行
+ 可直接入库
+###
     """
 
     agent = create_agent(
         model = llm, 
         response_format=GenerateReg
     )
-    print(prompt)
     response = await agent.ainvoke({
         "messages": [{"role":"system","content": prompt}]
     },context = {})
-    print("to here 2")
-    reg = response["structured_response"]["reg"]
+    reg = response["structured_response"].reg
     return reg
 
 if __name__ == "__main__":

+ 21 - 24
agent/src/agent/api_inner.py

@@ -44,14 +44,14 @@ def load_tag_2_es(tag_ids: list[str]):
                     tti.tag_code,
                     tti.tag_remark,
                     tti.reg,
-                    tti.level,
+                    tti.tag_level,
                     tti.tag_path,
                     ttc.category_nm,
                     ttc.category_code,
                     tti.tag_prompt
-                    from aitag_tag_info tti left join aitag_tag_category  ttc 
+                    from ai_tagging.aitag_tag_info tti left join ai_tagging.aitag_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
+                    where ttc.is_delete=0 and tti.is_delete=0 and ttc.state =  0 and tti.state = 0 and tti.tag_level = ttc.visibility_level
                     and tti.id in ({placeholders})"""    
     labels = dao.query(sql,tag_ids)
     res = es.bulk_upsert([{
@@ -65,7 +65,6 @@ def load_tag_2_es(tag_ids: list[str]):
         "tag_prompt": label[9],
         "tag_vector": get_embeddings([(label[6] or '')+(label[4] or '')])[0] 
     } for label in labels])
-    print(f"bulk_upsert result: {res}")
     return labels
 
 @router.post("/synchronize_tag")
@@ -87,30 +86,28 @@ def delete_tag(request: SynchronizeTagRequest):
 
 
 class GenerateRegRequest(BaseModel):
-    id: str = Field(..., description="标签编码")
+    tag_name: str = Field(..., description="标签名称")
+    tag_remark: str = Field(..., description="标签定义")
 
-async def generate_and_update_reg(tag_info):
-    reg = await agent.generate_reg(tag_info)
-    dao.execute(
-        """UPDATE aitag_tag_info SET reg = %s WHERE id = %s""",
-        (reg, tag_info[0])
-    )
-    logging.info(f"Updated reg in database for tag {tag_info[0]}: {reg}")
+async def generate_and_update_reg(tag_name: str, tag_remark: str):
+    reg = await agent.generate_reg(tag_name,tag_remark)
+    logging.info(f"Generated reg for tag {tag_name}: {reg}")
+    reg = reg.replace('))(', ')).*(')
+    logging.info(f"Generated reg for tag {tag_name}: {reg}")
+    logging.info(f"Updated reg in database for tag {tag_name}: {reg}")
+    return reg
 
 @router.post("/generate_reg")
-async def generate_reg(id: GenerateRegRequest, background_tasks: BackgroundTasks):
-    print(f"Received request to generate reg for tag id: {id.id}")
-    tag_info = dao.query(
-            """SELECT id,tag_nm, tag_remark FROM aitag_tag_info WHERE id = %s
-            """,
-            (id.id,)
-    )
-    background_tasks.add_task(
-        generate_and_update_reg,  # 后台任务函数
-        tag_info=tag_info[0] if tag_info else None,
-    )
+async def generate_reg(request: GenerateRegRequest, background_tasks: BackgroundTasks):
+    print(f"Received request to generate reg for tag remark: {request.tag_remark}")
+    # background_tasks.add_task(
+    #     generate_and_update_reg,  # 后台任务函数
+    #     tag_name=request.tag_name,
+    #     tag_remark=request.tag_remark
+    # )
+    reg = await generate_and_update_reg(request.tag_name, request.tag_remark)
     return {
         "code": 200,
-        "message": "generate_reg background task started"
+        "data": reg
     }
     

+ 70 - 25
agent/src/agent/api_outter.py

@@ -29,48 +29,73 @@ class TaggingRequest(BaseModel):
     sign: Optional[str] = Field(None, description="请求签名")
     business_attr: str = Field(..., description="业务属性")
     phrase: str = Field(..., description="需要打标签的文本")
+    tag_category_id: Optional[str] = Field(None, description="指定标签类别ID,默认为空表示不指定")
 
-def execute_reg(phrase: str)-> list:
+async def execute_reg(log_id:str,tag_category_id:str,phrase: str)-> list:
     sql = f"""select 
                     tti.id,
                     tti.reg
-                    from aitag_tag_info tti left join aitag_tag_category  ttc 
+                    from ai_tagging.aitag_tag_info tti left join ai_tagging.aitag_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
+                    where ttc.is_delete=0 and tti.is_delete=0 and ttc.state =  0 and tti.state = 0 and tti.tag_level = ttc.visibility_level
                     """    
+    if tag_category_id:
+        sql += f""" and ttc.id = '{tag_category_id}'"""
     labels = dao.query(sql)
     # 循环调用reg匹配phrase,匹配成功则返回标签id
-    # result = []
-    # for label in labels:
-    #     reg = label[1]
-    #     if reg is not None and re.search(reg, phrase):
-    #         result.append(label[0])
-    return [ l[0] for l in labels]
+    result = []
+    try:
+        for label in labels:
+            reg = label[1]
+            logging.info(f"Executing regex for label_id {label[0]}")
+            if reg is not None:
+                pattern = re.compile(reg, re.VERBOSE)
+                if pattern.match(phrase):
+                    result.append(label[0])
+            else:
+                result.append(label[0])
+    except Exception as e:
+        logging.error(f"Regex execution failed: {e}")
+    logging.info(f"Regex filtering candidates: {result}")
+    dao.execute(
+            """UPDATE ai_tagging.aitag_tag_log SET reg_result = %s WHERE id = %s""",
+            (str(result), log_id)
+        )
+    logging.info(f"Updated reg_result for log_id {id}")
+    return result
 
 def vector_similarity_search(phrase: str, ids:list)-> list:
     # 这里应该调用向量数据库进行相似度检索,返回相关标签id列表
     query = get_embeddings([phrase])[0]
     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]
+    # 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]
+    return [{"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"]   } for r in results]
 
 def init_tag_log(request: TaggingRequest):
-     id = uuid.uuid4().hex
-     dao.execute(
-            """INSERT INTO aitag_tag_log (id,app_id, insert_time, business_attr, phrase, state) VALUES (%s, %s, %s, %s, %s, %s)""",
-            (id,request.app_id, datetime.now(), request.business_attr, request.phrase, 0)
-        )
-     return id
+    id = uuid.uuid4().hex
+    # 保证business_attr的唯一性,如果已经存在相同business_attr且状态为0(处理中)的记录,则将is_delete设为1(已删除),然后插入新记录
+    dao.execute(
+        """UPDATE ai_tagging.aitag_tag_log SET is_delete = 1 WHERE business_attr = %s""",
+        (request.business_attr,)
+    )
+    # 业务编号如果以test开头,则tag_scope = 1,否则都是0
+    tag_scope = 1 if request.business_attr.startswith("test") else 0
+    dao.execute(
+        """INSERT INTO ai_tagging.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)
+    )
+    return id
 
 def update_tag_log(id:str, result:str):
     dao.execute(
-            """UPDATE aitag_tag_log SET state = %s, result = %s WHERE id = %s""",
+            """UPDATE ai_tagging.aitag_tag_log SET state = %s, result = %s WHERE id = %s""",
             (1, result, id)
         )
 
-async def run_ai_pipeline(log_id: str, phrase: str):
+async def run_ai_pipeline(log_id: str, tag_category_id: str, phrase: str):
     try:
         # step1: 正则过滤
-        result = execute_reg(phrase)
+        result = await execute_reg(log_id,tag_category_id,phrase)
         logging.info(f"[{log_id}] Regex filtering result: {result}")
 
         # step2: 向量检索
@@ -86,8 +111,7 @@ async def run_ai_pipeline(log_id: str, phrase: str):
             logging.info(f"[{log_id}] LLM result: {result}")
 
         # step4: 更新数据库
-        if result:
-            update_tag_log(log_id, str(result))
+        update_tag_log(log_id, str(result))
             
     except Exception as e:
         logging.error(f"[{log_id}] Pipeline failed: {e}")
@@ -101,6 +125,7 @@ async def ai_tagging(request: TaggingRequest,background_tasks: BackgroundTasks):
     background_tasks.add_task(
         run_ai_pipeline,  # 后台任务函数
         log_id=id,
+        tag_category_id=request.tag_category_id,    
         phrase=request.phrase
     )
     logging.info(f"Started background task for log_id: {id}")
@@ -110,10 +135,30 @@ async def ai_tagging(request: TaggingRequest,background_tasks: BackgroundTasks):
     }
 
 @router.get("/query")
-def query():
-    return {"message": "AI Query Endpoint"}
+def query(business_attr: str):
+    # 查询指定business_attr对应的标签信息
+    sql = """SELECT * FROM ai_tagging.aitag_tag_log WHERE business_attr = %s and is_delete = 0"""
+    result = dao.query_dict(sql, (business_attr,))
+    print(result)
+    return {"code": 200, "message": "AI Query Endpoint", "data": result[0] if result else None}
+
+class FeedbackRequest(BaseModel):
+    user_id: str = Field(..., description="用户ID")
+    user_nm: Optional[str] = Field(None, description="用户名称")
+    feedback: str = Field(..., description="用户反馈,必填,agree/reject")
+    feedback_result: Optional[str] = Field(None, description="反馈的标签结果")
+    contract_no: str = Field(..., description="合同编号")
+    user_org: Optional[str] = Field(None, description="用户所属机构")
+    user_endpoint: Optional[str] = Field(None, description="用户所属网点")
+    business_attr: str = Field(..., description="业务属性")
 
 @router.post("/feedback")
-def ai_feedback():
-    return {"message": "AI Feedback Endpoint"}
+def ai_feedback(feedback_request: FeedbackRequest):
+    logging.info(f"Received feedback request: {feedback_request}")
+    # 这里将用户的反馈信息保存到数据库中aitag_tag_log,供后续分析和模型优化使用
+    dao.execute(
+        """update ai_tagging.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)
+    )
+    return {"code": 200, "message": "Feedback received successfully"}
 

+ 30 - 20
agent/src/agent/core/dao.py

@@ -1,6 +1,7 @@
-from dbutils.pooled_db import PooledDB 
-import pymysql
+import psycopg2
+from psycopg2 import pool
 import configparser
+from contextlib import contextmanager
 
 config = configparser.ConfigParser()
 config.read('config.ini')
@@ -11,43 +12,52 @@ user = config['database']['user']
 password = config['database']['password']
 database = config['database']['database']
 
-pool = PooledDB(
-    creator=pymysql,                    # 使用 PyMySQL 作为底层驱动
+pool = psycopg2.pool.SimpleConnectionPool(
+    20, 50,
     host=host,
     port=port,
-    user=user,
-    password=password,
     database=database,
-    charset='utf8mb4',
-    autocommit=True,                    # 自动提交事务(根据需求设置)
-    mincached=2,                        # 初始化时创建的空闲连接数
-    maxcached=10,                       # 最大空闲连接数
-    maxshared=10,                       # 最大共享连接数(PyMySQL 不支持共享,可忽略)
-    maxconnections=20,                  # 最大连接数
-    blocking=True,                      # 连接数满时是否阻塞等待
-    ping=1                              # 每次从池取连接前 ping 一下(0=不 ping, 1~7=不同级别)
+    user=user,
+    password=password
 )
 
+@contextmanager
+def get_db_connection():
+    conn = None
+    try:
+        conn = pool.getconn()
+        yield conn
+    finally:
+        if conn:
+            pool.putconn(conn)
+
 def query(sql, params=None):
-    with pool.connection() as conn:
+    with get_db_connection() as conn:
         with conn.cursor() as cursor:
             cursor.execute(sql, params)
             result = cursor.fetchall()
             return result
+
+def query_dict(sql, params=None):
+    with get_db_connection() as conn:
+        with conn.cursor() as cursor:
+            cursor.execute(sql, params)
+            result = cursor.fetchall()
+
+            columns = [desc[0] for desc in cursor.description]
+            return [dict(zip(columns, row)) for row in result]
    
 
 def execute(sql, params=None):
-    conn = pool.connection()
-    try:
+    with get_db_connection() as conn:
         with conn.cursor() as cursor:
             cursor.execute(sql, params)
             conn.commit()
-    finally:
-        conn.close()
+     
 
 if __name__ == "__main__":
     print(host, port, user, password, database)
-    with pool.connection() as conn:
+    with get_db_connection() as conn:
         with conn.cursor() as cursor:
             cursor.execute("SELECT VERSION()")
             version = cursor.fetchone()

+ 1 - 2
agent/src/agent/core/es.py

@@ -106,5 +106,4 @@ def hybrid_search( target_doc_ids, query_vector, top_k=2):
 if __name__ == "__main__":
     results = search_all()
     print(f"Search results: {len(results)}")
-    for result in results:
-        print(result["_source"])
+    

+ 0 - 35
agent/tests/api_tagging_test.py

@@ -1,35 +0,0 @@
-import requests
-from agent.core.sm3_sign import generate
-
-APP_ID = "test_app"
-APP_SECRET = "test_secret"
-
-def test_tagging_endpoint():
-    with open("test/data/输入-1.docx", "rb") as f:
-        timestamp = 1234567890
-        url = "http://localhost:8080/aitag/v1/tagging/"
-        sign = generate(APP_SECRET.encode('utf-8'), {
-            'app_id': 'test_app',
-            'timestamp': timestamp,
-            'business_attr': 'test_attr',   
-            'category': 'test_category',
-            'phrase': '测试短语'
-        })
-
-        data = {
-            'app_id': 'test_app',
-            'timestamp': timestamp,
-            'sign': sign,
-            'business_attr': 'test_attr',   
-            'category': 'test_category',
-            'phrase': '测试短语'
-        }
-        response = requests.post(url, data=data, files={'attachment': ("输入-1.docx", f)})
-        assert response.status_code == 200
-        json_response = response.json()
-        assert json_response['code'] == 200
-        assert json_response['message'] == "AI Tagging successful"
-        print("Test passed!")
-
-if __name__ == "__main__":
-    test_tagging_endpoint()

+ 53 - 0
agent/tests/generate_excel.py

@@ -0,0 +1,53 @@
+import pandas as pd
+
+# 定义完整的表格数据:28 行 x 18 列 (A to R)
+# 每一行是一个包含 18 个元素的列表
+rows = [
+    # 第1行
+    ["交易名称", "申请进度查询", "", "", "", "", "", "", "服务名称", "个人贷款申请信息查询服务", "", "", "", "", "是否文件", "X", "", ""],
+    # 第2行
+    ["原交易代码", "", "", "", "", "", "", "", "服务代码", "G2003000152", "", "服务场景", "01-申请进度查询", "是否分页", "Y", "", "", ""],
+    # 第3行
+    ["交易描述", "借管各业务阶段申请进度列表查询", "", "", "", "", "", "", "发布日期:", "", "", "更新日期:", "", "", "", "", "", ""],
+    # 第4行
+    ["原始接口", "", "", "", "", "", "", "", "FJMXKBSD", "", "", "", "", "", "", "", "", ""],
+    # 第5行(表头)
+    ["英文名称", "ESB定义名", "中文名称", "数据类型", "长度", "是否必输", "字典名称", "备注", "", "英文名称", "数据类型", "长度", "中文名称", "是否必输", "字典名称", "备注", "", ""],
+    
+    # 输入字段开始(第6行起)
+    ["QUERY_TYPE", "查询类型", "查询类型", "string", "5", "Y", "", "1 客户号\n2 借管业务流水号\n3 合同编号", "", "QUERY_TYPE", "string", "5", "查询类型", "Y", "", "1 客户号\n2 借管业务流水号\n3 合同编号", "", ""],
+    ["BUSI_TYPE", "业务类型", "业务类型", "string", "1", "Y", "", "1 贷款申请\n2 出账申请\n3 展期申请", "", "BUSI_TYPE", "string", "1", "业务类型", "Y", "", "1 贷款申请\n2 出账申请\n3 展期申请", "", ""],
+    ["CUST_NO", "客户号", "客户号", "string", "40", "N", "", "查询类型为1时必输", "", "CUST_NO", "string", "40", "客户号", "N", "", "查询类型为1时必输", "", ""],
+    ["INSTU_CDE", "所属法人行社", "所属法人行社", "string", "20", "N", "", "查询类型为1时必输", "", "INSTU_CDE", "string", "20", "所属法人行社", "N", "", "查询类型为1时必输", "", ""],
+    ["PRO_ID", "产品编号", "产品编号", "string", "40", "N", "", "查询类型为1时选填", "", "PRO_ID", "string", "40", "产品编号", "N", "", "查询类型为1时选填", "", ""],
+    ["IQP_SEQNO", "借管业务流水号", "借管业务流水号", "string", "40", "N", "", "查询类型为2是必输", "", "BUSS_SEQ_NO", "string", "40", "借管业务流水号", "N", "", "查询类型为2是必输", "", ""],
+    ["CONT_NO", "合同编号", "合同编号", "string", "40", "N", "", "查询类型为3是必输,业务类型为1时无须查询", "", "CONT_NO", "string", "40", "合同编号", "N", "", "查询类型为3是必输", "", ""],
+    ["APPROVE_STATUS", "申请状态", "申请状态", "string", "5", "N", "CD0399", "", "", "APPROVE_STATUS", "string", "5", "申请状态", "N", "CD0399", "", "", ""],
+    
+    # 空行(第14行)
+    ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""],
+    
+    # 输出字段开始
+    ["APP_PRO_LIST", "申请进度列表", "申请进度列表", "array", "", "", "", "start", "", "APP_PRO_LIST", "array", "", "申请进度列表", "", "", "start", "", ""],
+    ["CONT_NO", "", "合同编号", "string", "40", "N", "", "", "", "CONT_NO", "string", "40", "合同编号", "N", "", "", "", ""],
+    ["INSTU_CDE", "", "所属法人行社", "string", "20", "", "", "", "", "INSTU_CDE", "string", "20", "所属法人行社", "", "", "", "", ""],
+    ["IQP_SEQNO", "", "借管业务流水号", "string", "40", "", "", "", "", "BUSS_SEQ_NO", "string", "40", "借管业务流水号", "", "", "", "", ""],
+    ["APPROVE_STATUS", "", "申请状态", "string", "5", "", "CD0399", "", "", "APPROVE_STATUS", "string", "5", "申请状态", "", "CD0399", "", "", ""],
+    ["CUR_TYPE", "", "币种", "string", "10", "", "CD0020", "", "", "CCY", "string", "10", "币种", "", "CD0020", "", "", ""],
+    ["APF_AMT", "", "申请金额", "double", "18.2", "", "", "", "", "APF_AMT", "string", "18.2", "申请金额", "", "", "", "", ""],
+    ["APPLY_DATE", "", "申请时间", "string", "25", "", "", "yyyy-MM-dd hh:mm:ss", "", "APPLY_DATE", "string", "25", "申请时间", "", "", "yyyy-MM-dd hh:mm:ss", "", ""],
+    ["APR_PASS_DATE", "", "审批通过时间", "string", "25", "", "", "yyyy-MM-dd hh:mm:ss", "", "APR_PASS_DATE", "string", "25", "审批通过时间", "", "", "yyyy-MM-dd hh:mm:ss", "", ""],
+    ["LOAN_PURP", "", "借款用途", "string", "256", "", "", "填款申请时返回", "", "LOAN_PURP", "string", "256", "借款用途", "", "", "填款申请时返回", "", ""],
+    ["INCOMING_CODE", "", "渠道系统编号", "string", "40", "N", "", "ECS系统编号", "", "CHANNEL_SYS_ID", "string", "40", "渠道系统编号", "N", "", "ECS系统编号", "", ""],
+    ["INCOMING_SERNO", "", "渠道业务流水号", "string", "40", "N", "", "", "", "CHANNEL_SEQ_NO", "string", "40", "渠道业务流水号", "N", "", "", "", ""],
+    ["APP_PRO_LIST", "", "申请进度列表", "array", "", "", "", "end", "", "APP_PRO_LIST", "array", "", "申请进度列表", "", "", "end", "", ""],
+]
+
+# 转为 DataFrame
+df = pd.DataFrame(rows)
+
+# 保存到 Excel
+output_file = "服务接口定义.xlsx"
+df.to_excel(output_file, index=False, header=False)
+
+print(f"✅ Excel 文件已生成:{output_file}")

+ 1911 - 0
agent/tests/test_data.txt

@@ -0,0 +1,1911 @@
+销售人员 服装零售 经营周转
+销售人员 其他农业 个人消费
+农业生产服务人员 仁果类和核果类水果种植 种植果树
+农、林、牧、渔业生产及辅助人员 农业 农业
+农作物生产人员 蔬菜种植 农业
+中小学教育教师 成人小学教育 家庭综合消费
+农、林、牧、渔业生产及辅助人员 林木育种 农、林、牧、渔专业及辅助性活动
+销售人员 其他房地产业 购房
+社会生产服务和生活服务人员 果品、蔬菜零售 个人经营
+农作物生产人员 小麦种植 种植小麦
+工程技术人员 零售业 零售业
+自由职业者 茶叶种植 个人经营
+木制品制造人员 木质装饰材料零售 个人经营
+中等职业教育教师 中等职业学校教育 转贷
+畜牧制品加工人员 肉制品及副产品加工 肉类食品加工
+其他批发与零售服务人员 便利店零售 经营便利店
+农作物生产人员 普通货物道路运输 借新还旧
+行政业务办理人员 其他未列明服务业 个人消费
+建筑工程技术人员 其他建筑安装 借新还旧
+其他修理及制作服务人员 五金零售 用于归还黄恩贵名下贷款
+中等职业教育教师 住宅装饰和装修 个人消费
+行政事务处理人员 建筑装饰、装修和其他建筑业 建筑装饰、装修和其他建筑业
+其他农、林、牧、渔业生产及辅助人员 餐饮配送服务 餐饮业
+销售人员 肉、禽、蛋、奶及水产品批发 经营冷冻食品等
+销售人员 肉、禽、蛋、奶及水产品批发 经营冷冻食品等
+销售人员 肉、禽、蛋、奶及水产品批发 经营冷冻食品
+其他租赁和商务服务人员 建筑工程机械与设备经营租赁 购挖掘机配件
+木制品制造人员 金属制品修理 流动资金
+木制品制造人员 金属制品修理 流动资金
+其他社会生产和生活服务人员 其他房屋建筑业 购建材
+销售人员 其他室内装饰材料零售 经营建材
+农作物生产人员 精制茶加工 经营茶叶加工厂
+不便分类的其他从业人员 木片加工 购木材
+其他批发与零售服务人员 建材批发 购砂石
+水产养殖人员 海水养殖 渔排养殖
+作物种子(苗)繁育生产人员 花卉种植 种植
+房屋建筑施工人员 其他未列明建筑业 经营搅拌场
+建筑工程技术人员 花卉种植 种植花木
+行政执法和仲裁人员 其他农业 个人消费
+销售人员 陶瓷、石材装饰材料零售 进货等
+其他修理及制作服务人员 其他未列明日用产品修理业
+水产养殖人员 海水养殖 个人经营
+销售人员 机动车燃油零售 个人经营
+农作物生产人员 小麦种植 经营周转
+畜禽饲养人员 果品、蔬菜零售 个人消费
+农作物生产人员 柑橘类种植 种果
+销售人员 其他室内装饰材料零售 销售建材等
+中小学教育教师 其他综合零售 个人消费资金
+其他农业生产人员 茶叶种植 续贷盘转
+销售人员 家具零售 归还郑群贷款、信用卡本金
+餐饮服务人员 正餐服务 个人经营
+销售人员 其他居民服务业 借新还旧
+贸易经济代理人员 五金产品批发 购卫浴等
+银行服务人员 其他居民服务业 个人消费
+销售人员 纺织品、针织品及原料批发 个人经营
+检察官 零售业 零售业
+作物种子(苗)繁育生产人员 房地产租赁经营 参与建设村集体用地“霞梧集体项目”
+其他社会生产和生活服务人员 米、面制品及食用油批发 批发业
+餐饮服务人员 其他未列明餐饮业 个人经营
+农业生产人员 森林经营和管护 林业
+农作物生产人员 食用菌种植 种植香菇
+销售人员 化妆品及卫生用品零售 经营网络销售购买化妆品
+销售人员 住宅装饰和装修 经营建材
+建筑装饰人员 其他房屋建筑业 承包工程
+销售人员 文具用品零售 采购玩具
+住宿服务人员 造纸和纸制品业 造纸和纸制品业
+企事业单位负责人 五金产品批发 个人经营
+水产养殖人员 海水养殖 养殖鲍鱼
+行政事务处理人员 其他未列明服务业 家庭综合消费
+社会生产服务和生活服务人员 其他农牧产品批发 个人经营
+其他农林牧渔生产辅助人员 茶叶种植 种茶
+农作物生产人员 粘土及其他土砂石开采 经营沙石场
+行政事务处理人员 其他居民服务业 消费
+销售人员 机动车燃油零售 购成品油
+土木工程建筑施工人员 其他土木工程建筑施工 采购五金
+销售人员 服装零售 经营服装流动资金需要
+销售人员 肉制品及副产品加工 购肉制品等
+销售人员 日用家电零售 经营家用电器店购电器
+其他社会生产和生活服务人员 住宅装饰和装修 装修房屋
+银行专业人员 其他居民服务业 个人消费
+银行专业人员 其他居民服务业 个人消费
+销售人员 蔬菜种植 种植(转贷)
+其他农业生产人员 森林经营和管护 林业经营
+其他农、林、牧、渔业生产及辅助人员 羊的饲养 经营周转
+其他农、林、牧、渔业生产及辅助人员 羊的饲养 经营周转
+销售人员 小吃服务 经营小吃店
+作物种子(苗)繁育生产人员 民宿服务 个人经营
+通用基础件装配制造人员 水泥制造 经营煤炭调运
+销售人员 房地产租赁经营 参与建设村集体用地“霞梧集体项目”
+农作物生产人员 葡萄种植 种植葡萄(红色老区)
+农作物生产人员 稻谷种植 经营农产品(借新还旧)
+农、林、牧、渔业生产及辅助人员 农、林、牧、渔专业及辅助性活动 农、林、牧、渔专业及辅助性活动
+保险专业人员 住宅装饰和装修 个人消费
+银行服务人员 稻谷种植 装修
+银行服务人员 稻谷种植 装修
+办事人员和有关人员 其他未列明服务业 个人消费
+销售人员 肉、禽、蛋、奶及水产品批发 批发业
+销售人员 汽车及零配件批发 个人经营
+其他房地产服务人员 其他未列明建筑业 购挖机
+作物种子(苗)繁育生产人员 其他房地产业 购一手房
+农作物生产人员 花卉种植 种植花木
+销售人员 正餐服务 购油、食品等
+农作物生产人员 其他清洁服务 经营家政服务周转金
+国家行政机关负责人 住宅装饰和装修 消费
+销售人员 通信设备零售 经营手机店购买手机
+农作物生产人员 柑橘类种植 种果
+其他办事人员 农业 农业
+未知 种子种苗培育活动 农、林、牧、渔专业及辅助性活动
+销售人员 摩托车及零配件零售 经营电动车
+其他 坚果种植 个人经营
+科学研究人员 软件和信息技术服务业 软件和信息技术服务业
+农、林、牧、渔业生产及辅助人员 其他农业 个人经营
+道路运输服务人员 普通货物道路运输 借新还旧
+畜禽饲养人员 鸭的饲养 个人经营
+专业技术人员 其他室内装饰材料零售 调货
+健身和娱乐场所服务人员 休闲观光活动 借新还旧
+社会生产服务和生活服务人员 快餐服务 借新还旧
+销售人员 渔业产品批发 经营水产批发
+水产养殖人员 网吧活动 经营网咖
+农作物生产人员 食用菌种植 个人经营
+其他居民服务人员 其他未列明服务业 无还本续贷
+其他纺织品、服装和皮革、毛皮制品加工制作人员 卫生洁具零售 经营卫浴建材
+农、林、牧、渔业生产及辅助人员 零售业 零售业
+其他健康服务人员 村卫生室 经营周转
+办事人员和有关人员 国家机构 国家机构
+未知 汽车零配件零售 汽车配件批发经营
+销售人员 其他居民服务业 个人消费
+销售人员 建筑装饰、装修和其他建筑业 建筑装饰、装修和其他建筑业
+行政业务办理人员 百货零售 消费
+保卫人员 其他农业 个人消费
+其他农业生产人员 小吃服务 经营小吃
+广播、电视、电影和影视录音制作人员 其他农业专业及辅助性活动 农、林、牧、渔专业及辅助性活动
+销售人员 酒、饮料及茶叶零售 经营茶庄
+广播、电视、电影和影视录音制作人员 其他文化艺术业 经营周转
+水产捕捞及有关人员 海水捕捞 个人经营
+销售人员 酒、饮料及茶叶零售 进货
+销售人员 五金零售 经营建材经营部
+水产养殖人员 海水养殖 个人经营
+其他农业生产人员 其他中药材种植 种仙草
+销售人员 便利店零售 个人经营贷款资金周转需要
+销售人员 其他综合零售 购船舶配件及渔需用品等
+其他办事人员 普通高中教育 无还本续贷
+租赁业务人员 房地产租赁经营 参与建设村集体用地“霞梧集体项目”
+餐饮服务人员 小吃服务 经营小吃
+餐饮服务人员 正餐服务 小吃店
+餐饮服务人员 快餐服务 借新还旧(归还普惠卡)
+餐饮服务人员 内陆养殖 经营养殖场
+农业生产服务人员 机动车燃油零售 汽车修理
+银行专业人员 其他未列明服务业 家庭综合消费(好享贷)
+销售人员 其他综合零售 经营电商,购买日用品
+采购人员 其他土木工程建筑施工 个人经营
+销售人员 农业 农业
+农、林、牧、渔业生产及辅助人员 住宅房屋建筑 建房转贷
+企事业单位负责人 农业 农业
+农作物生产人员 柑橘类种植 个人经营
+废料和碎屑加工处理人员 金属废料和碎屑加工处理 废品回收经营
+农业生产人员 薯类种植 种植槟榔芋
+销售人员 通信设备零售 购水泥钢筋等
+销售人员 五金产品批发 危房翻建
+采购人员 钟表、眼镜零售 个人经营
+农作物生产人员 农产品初加工活动 食用菌初加工
+不便分类的其他从业人员 酒、饮料及茶叶批发 批发业
+销售人员 五金零售 经营电子设备
+销售人员 建材批发 个人经营
+销售人员 五金产品批发 五金产品的批发、零售
+社会生产服务和生活服务人员 首饰、工艺品及收藏品批发 无还本续贷
+销售人员 百货零售 百货零售超市经营周转
+农业生产服务人员 森林经营和管护 林业
+其他农业生产人员 普通货物道路运输 借新还旧
+农业生产人员 鬃毛加工、制刷及清扫工具制造 其他制造业
+其他农、林、牧、渔业生产及辅助人员 棉花种植 无还本续贷
+销售人员 鸡的饲养 个人经营
+销售人员 影视节目制作 视频剪辑
+批发与零售服务人员 果品、蔬菜零售 零售业
+农作物生产人员 香蕉等亚热带水果种植 种植百香果
+专业技术人员 教育 教育
+农、林、牧、渔业生产及辅助人员 住宅装饰和装修 装修
+农、林、牧、渔业生产及辅助人员 其他土木工程建筑施工 土木工程建筑业
+销售人员 再生物资回收与批发 个人经营
+酒、饮料及精制茶制造人员 精制茶加工 茶叶加工
+销售人员 其他土木工程建筑施工 经营电梯安装
+农作物生产人员 柑橘类种植 种果
+销售人员 服装零售 个人经营
+餐饮服务人员 快餐服务 经营连锁餐饮
+销售人员 小吃服务 个人经营
+党的机关、国家机关、群众团体和社会组织、企事业单位负责人 居民服务业 居民服务业
+建筑装饰人员 住宅装饰和装修 购房(二手房)
+建筑装饰人员 建筑装饰、装修和其他建筑业 建筑装饰、装修和其他建筑业
+行政业务办理人员 零售业 购家具等
+其他信息传输、软件和信息技术服务人员 其他互联网服务 进货
+销售人员 通信设备零售 个人经营
+销售人员 营养和保健品批发 个人经营
+其他社会生产和生活服务人员 零售业 零售业
+粮油加工人员 其他综合零售 个人经营
+农业生产服务人员 种子批发 经营农产品
+社会生产服务和生活服务人员 五金零售
+营造林人员 海水养殖 个人消费
+农作物生产人员 小麦种植 经营种植
+社会生产服务和生活服务人员 服装零售 服装店
+销售人员 便利店零售 经营茶叶
+畜禽饲养人员 茶叶种植 个人经营
+销售人员 其他食品批发 经营周转
+群众文化活动服务人员 其他综合零售 综合消费
+销售人员 五金零售 经营五金店资金需要
+水产养殖人员 海水捕捞 养殖鲍鱼
+信息通信网络运行管理人员 通信设备零售 经营电子产品
+销售人员 建材批发 经营建材
+办事人员和有关人员 其他未列明服务业 个人消费
+农作物生产人员 食用菌种植 种菇
+销售人员 烟草制品零售 经营便利店
+鞋帽制作人员 其他制鞋业 个人消费
+其他农、林、牧、渔业生产及辅助人员 其他一般旅馆 经营毛竹林管理
+销售人员 首饰、工艺品及收藏品批发 购工艺品
+销售人员 首饰、工艺品及收藏品批发 购工艺品
+水产养殖人员 五金零售 五金店经营
+水产捕捞及有关人员 海水捕捞
+其他文化、体育和娱乐服务人员 其他室内娱乐活动 经营周转
+餐饮服务人员 小吃服务 经营小吃
+其他专业技术人员 零售业 零售业
+销售人员 棉花种植 经营家政
+销售人员 其他日用品零售 购水果
+农作物生产人员 稻谷种植 农业
+水产养殖人员 海水养殖 鲍鱼养殖
+餐饮服务人员 正餐服务 开店周转金
+其他批发与零售服务人员 茶叶种植 借新还旧
+其他纸及纸制品生产加工人员 加工纸制造 购买家具
+其他农、林、牧、渔业生产及辅助人员 正餐服务 经营餐饮
+软件和信息技术服务人员 住宅装饰和装修 房屋装修
+销售人员 木质装饰材料零售 零售业
+农作物生产人员 住宅房屋建筑 购房
+采购人员 建筑装饰、装修和其他建筑业 建筑装饰、装修和其他建筑业
+建筑工程技术人员 房屋建筑业 房屋建筑业
+批发与零售服务人员 其他日用杂品制造 其他制造业
+销售人员 计算机、软件及辅助设备批发 经营周转
+不便分类的其他从业人员 农产品初加工活动 农、林、牧、渔专业及辅助性活动
+其他办事人员 道路运输业 道路运输业
+作物种子(苗)繁育生产人员 日用家电批发 个人经营
+农、林、牧、渔业生产及辅助人员 其他农业 种养
+会计专业人员 家庭服务 购二手房
+电力、燃气及水供应服务人员 电力供应 电力、热力生产和供应业
+其他社会生产和生活服务人员 其他农业 个人消费
+农作物生产人员 稻谷种植 农业
+房屋建筑施工人员 住宅房屋建筑 购钢筋
+销售人员 百货零售 经营食杂店经营货款需要
+畜禽饲养人员 鸡的饲养 经营家禽养殖
+农作物生产人员 蔬菜种植 蔬菜种植
+销售人员 其他综合零售 进衣服
+其他农业生产人员 柑橘类种植 种植脐橙
+水产养殖人员 海水养殖 网箱养殖购饲料
+销售人员 五金产品批发 经营卫浴
+农、林、牧、渔业生产及辅助人员 酒、饮料及茶叶零售 个人经营
+销售人员 谷物、豆及薯类批发 经营农产品
+销售人员 服装零售 服装经营周转
+销售人员 鞋帽零售 个人经营
+其他农、林、牧、渔业生产及辅助人员 食用菌种植 个人经营
+作物种子(苗)繁育生产人员 中药零售 中药零售。
+销售人员 其他未列明制造业 无还本续贷
+销售人员 陶瓷、石材装饰材料零售 贩运瓷器
+水产捕捞及有关人员 海水捕捞 个人经营
+中小学教育教师 中等职业学校教育 个人消费
+销售人员 五金零售 个人经营
+采购人员 建材批发 瓷砖经营
+行政业务办理人员 其他农业 个人消费
+中小学教育教师 普通小学教育 个人消费
+销售人员 机动车燃油零售 购成品油
+其他批发与零售服务人员 快餐服务 经营快餐店、购买食材
+行政业务办理人员 其他综合零售 个人消费
+水产养殖人员 海水养殖 海产养殖
+采购人员 蔬菜种植 个人经营
+农作物生产人员 柑橘类种植 经营果园
+农作物生产人员 其他农业 个人经营
+其他农业生产人员 五金零售 经营五金店
+水产养殖人员 海水养殖 养殖
+社会生产服务和生活服务人员 纺织品及针织品零售 经营周转
+水产养殖人员 内陆养殖 个人养殖
+销售人员 百货零售 经营食杂店
+农、林、牧、渔业生产及辅助人员 坚果种植 个人经营
+水产养殖人员 海水养殖 无还本息续贷
+销售人员 住宅房屋建筑 购五金电缆等
+社会生产服务和生活服务人员 其他建筑安装 建筑安装业
+销售人员 渔业产品批发 批发业
+销售人员 渔业产品批发 个人经营
+销售人员 通信设备零售 购电子产品等
+销售人员 石油及制品批发 经营加油站购买成品油
+水产养殖人员 内陆养殖 无还本续贷(个人经营)
+作物种子(苗)繁育生产人员 建筑装饰和装修业 个人消费
+道路运输服务人员 普通货物道路运输 经营物流公司
+社会生产服务和生活服务人员 其他未列明批发业 归还陈钦山贷款
+办事人员和有关人员 建筑装饰、装修和其他建筑业 建筑装饰、装修和其他建筑业
+农、林、牧、渔业生产及辅助人员 农、林、牧、渔专业及辅助性活动 农、林、牧、渔专业及辅助性活动
+其他批发与零售服务人员 汽车新车零售 经营车行
+行政业务办理人员 其他未列明服务业 家庭综合消费
+销售人员 文具用品零售 购文具
+销售人员 便利店零售 食品店
+教学人员 农业 农业
+道路运输服务人员 其他综合零售 个人消费
+销售人员 烟草制品零售 经营卷烟销售
+不便分类的其他从业人员 其他未列明信息技术服务业 无还本续贷
+采矿、建筑专用设备制造人员 其他农业 个人消费
+销售人员 木质家具制造 经营工艺品生意
+销售人员 酒、饮料及茶叶零售 无还本续贷
+销售人员 服装零售 个人经营
+销售人员 文具用品零售 经营百货店购买玩具
+销售人员 果品、蔬菜零售 经营水果
+农、林、牧、渔业生产及辅助人员 海水养殖 个人经营
+其他文化、体育和娱乐服务人员 其他互联网服务 个人经营
+农、林、牧、渔业生产及辅助人员 海水养殖 养殖鲍鱼
+销售人员 通信设备零售 购销手机
+餐饮服务人员 正餐服务 购预包装食品等经营产品
+其他居民服务人员 其他未列明服务业 个人经营
+销售人员 电气安装 无还本续贷
+其他农业生产人员 其他农业 经营鞋厂
+水产养殖人员 海水养殖 鲍鱼养殖
+农、林、牧、渔业生产及辅助人员 海水捕捞 渔业
+销售人员 陶瓷、石材装饰材料零售 经营装饰材料
+建筑安装施工人员 公共建筑装饰和装修 个人消费
+土木工程建筑施工人员 建材批发 经营周转购买建材等
+畜禽饲养人员 鹅的饲养 养殖鹅周转金
+电力供应服务人员 其他未列明国家机构 个人消费
+销售人员 汽车零配件零售 购汽车配件
+农作物生产人员 稻谷种植 无还本续贷
+道路运输服务人员 其他农业 个人消费
+中小学教育教师 住宅装饰和装修 房屋装修
+土木工程建筑施工人员 工矿工程建筑 承包水电站工程
+健身和娱乐场所服务人员 商业综合体管理服务 个人生产经营
+行政事务处理人员 其他未列明服务业 家庭综合消费
+农作物生产人员 茶叶种植 个人经营
+其他居民服务人员 酒、饮料及茶叶零售 零售业
+其他农林牧渔生产辅助人员 海水养殖 鲍鱼养殖
+其他农林牧渔生产辅助人员 海水养殖 鲍鱼养殖
+其他农林牧渔生产辅助人员 海水养殖 鲍鱼养殖
+技术辅助服务人员 零售业 零售业
+销售人员 文具用品零售 房屋装修
+作物种子(苗)繁育生产人员 其他未列明服务业 个人消费
+行政业务办理人员 临床检验服务 房屋装修及购买家具家电
+销售人员 果品、蔬菜批发 经营水果店购买水果
+制糖人员 其他综合零售 购货物
+采购人员 房地产租赁经营 参与建设村集体用地“霞梧集体项目”
+销售人员 建材批发 批发业
+销售人员 建筑幕墙装饰和装修 建材零售
+餐饮服务人员 小吃服务 个人经营
+行政业务办理人员 其他农业 个人消费
+行政业务办理人员 住宅装饰和装修 购买家具
+其他农业生产人员 其他房地产业 购房
+作物种子(苗)繁育生产人员 其他土木工程建筑施工 工程
+农作物生产人员 豆类种植 归还普惠卡
+其他建筑施工人员 住宅装饰和装修 个人经营
+销售人员 汽车修理与维护 机动车维修店
+销售人员 纺织品及针织品零售 个人经营
+销售人员 批发业 批发业
+农、林、牧、渔业生产及辅助人员 其他农业 个人消费
+销售人员 便利店零售 便利店经营周转
+道路运输服务人员 其他农业 个人消费
+水产品加工人员 其他未列明制造业 其他制造业
+木材加工人员 其他居民服务业 个人消费
+农、林、牧、渔业生产及辅助人员 稻谷种植 个人经营
+其他批发与零售服务人员 五金零售 购买五金材料
+其他社会生产和生活服务人员 建筑工程机械与设备经营租赁 经营周转
+其他农业生产人员 五金零售 五金经营部经营周转
+水产养殖人员 海水养殖 个人经营
+农作物生产人员 稻谷种植 经营木工行业
+服装裁剪和洗染织补人员 旅行社及相关服务 商务服务业
+木材加工人员 胶合板制造 经营木材
+社会生产服务和生活服务人员 服装零售 经营服装店
+销售人员 五金产品批发 经营周转
+销售人员 纺织品、针织品及原料批发 经营周转
+行政业务办理人员 超级市场零售 个人消费
+粮油加工人员 其他农业 个人消费
+水产捕捞及有关人员 海水捕捞 水产捕捞
+水产捕捞及有关人员 海水养殖 个人经营
+行政业务办理人员 其他中药材种植 个人经营
+软件和信息技术服务人员 其他农业 个人消费
+其他批发与零售服务人员 建材批发 用于归还信用卡
+农、林、牧、渔业生产及辅助人员 茶叶种植 农、林、牧、渔专业及辅助性活动
+农作物生产人员 酒、饮料及茶叶零售 零售业
+销售人员 服装批发 个人经营
+中国共产党机关负责人 其他居民服务业 个人消费
+行政事务处理人员 其他综合零售 购服装
+销售人员 酒、饮料及茶叶零售 经营茶叶店
+其他农业生产人员 其他道路货物运输 经营汽车
+销售人员 文具用品批发 购文具及苗木等
+销售人员 日用家电零售 家电进货
+自由职业者 房地产租赁经营 参与建设村集体用地“霞梧集体项目”
+行政业务办理人员 花卉种植 购装修材料等
+水产养殖人员 内陆养殖 养殖
+销售人员 电气设备批发 购买控制板等经营所需的货品
+销售人员 肉、禽、蛋、奶及水产品零售 经营猪肉摊
+生产制造及有关人员 装卸搬运 经营周转
+农作物生产人员 其他房地产业 购房
+物业管理服务人员 住宅房屋建筑 个人消费
+办事人员和有关人员 住宅装饰和装修 房屋装修
+五金制品制作装配人员 金属门窗制造 个人经营
+农、林、牧、渔业生产及辅助人员 其他水果种植 种植黄金百香果
+销售人员 果品、蔬菜批发 个人经营
+水产养殖人员 海水养殖 养鱼
+农、林、牧、渔业生产及辅助人员 海水捕捞 渔业
+农作物生产人员 稻谷种植 购二手房
+销售人员 石油及制品批发 经营加油站购买成品油
+其他批发与零售服务人员 其他未列明制造业 购建材等
+其他办事人员 国家机构 国家机构
+林木种苗繁育人员 果品、蔬菜零售 经营水果店
+皮革、毛皮及其制品制造人员 塑料零件及其他塑料制品制造 购包装材料等
+餐饮服务人员 小吃服务 无还本续贷
+水产养殖人员 海水养殖 黄鱼养殖
+木材采运人员 木材采运 个人经营资金
+其他办事人员 人民法院 个人消费
+农作物生产人员 其他农业 个人经营
+农、林、牧、渔业生产及辅助人员 服饰制造 纺织服装、服饰业
+销售人员 五金零售 零售业
+文教用品制作人员 其他未列明服务业 个人经营
+文教用品制作人员 其他文教办公用品制造 房屋建设等
+不便分类的其他从业人员 建材批发 个人经营
+销售人员 卫生洁具零售 经营建材
+其他农、林、牧、渔业生产及辅助人员 内陆养殖 养虾
+销售人员 其他农牧产品批发 生产经营周转
+环境卫生服务人员 卫生 卫生
+采购人员 机动车燃油零售 经营周转
+其他批发与零售服务人员 服装批发 经营服装店,购买服装
+建筑安装施工人员 住宅房屋建筑 经营装修
+餐饮服务人员 外卖送餐服务 经营外卖
+其他金融服务人员 其他农业 个人消费
+农副林特产品初加工人员 酒、饮料及茶叶零售 采购食品、酒等
+采购人员 其他综合零售 经营石材
+农、林、牧、渔业生产及辅助人员 海水捕捞 渔业
+社会生产服务和生活服务人员 其他文化用品零售 续贷
+销售人员 卫生洁具零售 卫浴店经营周转
+餐饮服务人员 餐饮业 餐饮业
+农业生产人员 柑橘类种植 种植及家庭综合支出
+农作物生产人员 茶叶种植 个人经营
+生产制造及有关人员 五金产品批发 个人经营
+作物种子(苗)繁育生产人员 茶叶种植 个人经营
+餐饮服务人员 其他综合零售 个人经营
+销售人员 家具零售 购买木材
+其他生产制造及有关人员 陶瓷、石材装饰材料零售 个人经营
+销售人员 百货零售 个人经营
+生活照料服务人员 零售业 零售业
+农作物生产人员 牛的饲养 养牛生产
+邮政和快递服务人员 快递服务 归还贷款
+其他农业生产人员 其他水果种植 种植百香果
+农业生产服务人员 仁果类和核果类水果种植 种养殖
+水产养殖人员 海水养殖 鲍鱼养殖
+销售人员 肉、禽、蛋、奶及水产品零售 经营海鲜摊
+其他农业生产人员 其他农业 借新还旧
+水产养殖人员 海水养殖 养殖鲍鱼
+其他农、林、牧、渔业生产及辅助人员 其他农业 个人消费
+其他批发与零售服务人员 建筑用石加工 归还洪江淮贷款
+企事业单位负责人 精制茶加工 茶叶加工
+企事业单位负责人 农产品初加工活动 茶叶加工
+销售人员 其他综合零售 零售业
+销售人员 汽车新车零售 个人经营
+农作物生产人员 花卉种植 个人经营
+其他批发与零售服务人员 食用菌种植 食用菌种植
+社会生产服务和生活服务人员 建筑幕墙装饰和装修 扩大经营
+销售人员 市场管理服务 购白酒、农贸市场日常维护、支付工资等
+销售人员 化妆品及卫生用品零售 进行农村裸房整治
+社会生产服务和生活服务人员 其他未列明批发业 采购原材料
+其他批发与零售服务人员 厨具卫具及日用杂品批发 无还本续贷及购电器。
+其他批发与零售服务人员 厨具卫具及日用杂品批发 经营电器
+中小学教育教师 家具零售 购家具
+行政业务办理人员 家具零售 个人消费
+销售人员 鞋帽零售 鞋帽零售
+农、林、牧、渔业生产及辅助人员 其他农牧产品批发 购农产品
+农作物生产人员 家具零售 家具零售
+其他农业生产人员 柑橘类种植 农场经营周转
+软件和信息技术服务人员 其他农业 个人消费
+销售人员 鞋帽零售 经营周转
+医疗卫生技术人员 农业专业及辅助性活动 个人消费
+农作物生产人员 烟草种植 种烟
+陶瓷制品制造人员 建材批发 周转性贷款
+其他社会生产和生活服务人员 其他未列明信息技术服务业 个人经营
+其他批发与零售服务人员 互联网零售 经营电商购买日用品
+农、林、牧、渔业生产及辅助人员 其他日用杂品制造 其他制造业
+销售人员 建材批发 经营建材
+采购人员 其他农业 个人消费
+营造林人员 纺织品及针织品零售 电商资金周转
+其他文化、体育和娱乐服务人员 其他居民服务业 购设计设备等
+农作物生产人员 建材批发 经营建材
+其他交通运输、仓储和邮政业服务人员 货物运输代理 个人消费
+皮革、毛皮及其制品制造人员 毛皮服装加工 经营周转
+农作物生产人员 柑橘类种植 无还本续贷(种植水果)
+其他金属制品制造人员 其他室内装饰材料零售 无还本续贷
+农、林、牧、渔业生产及辅助人员 农、林、牧、渔专业及辅助性活动 农、林、牧、渔专业及辅助性活动
+其他农业生产人员 其他农业 生产经营
+事业单位负责人 住宅装饰和装修 综合消费
+其他农业生产人员 鸡的饲养 养鸡
+其他社会生产和生活服务人员 歌舞厅娱乐活动 经营室内娱乐
+生活照料服务人员 其他未列明建筑业 个人经营
+其他批发与零售服务人员 摩托车及零配件批发 购买摩托车配件
+水产养殖人员 海水养殖 养殖海带
+广播、电视、电影和影视录音制作人员 其他广告服务 广告制作
+哲学研究人员 其他农业 个人消费
+中小学教育教师 零售业 零售业
+森林经营和管护人员 森林经营和管护 个人经营
+期货服务人员 商务服务业 商务服务业
+土木工程建筑施工人员 建筑装饰、装修和其他建筑业 建筑装饰、装修和其他建筑业
+销售人员 其他化工产品批发 购水泥
+餐饮服务人员 快餐服务 小炒店经营
+农、林、牧、渔业生产及辅助人员 建材批发 经营橱柜加工销售
+社会生产服务和生活服务人员 日用家电零售 个人经营性贷款,用于经营周转
+农、林、牧、渔业生产及辅助人员 城乡市容管理 个人消费
+水产捕捞及有关人员 海水捕捞 购渔船设备
+水产捕捞及有关人员 海水捕捞 购渔船设备
+农作物生产人员 其他农业 经营周转
+农、林、牧、渔业生产及辅助人员 其他房屋建筑业 农、林、牧、渔专业及辅助性活动
+批发与零售服务人员 海水养殖 养殖
+农作物生产人员 中草药种植 种植太子参、茶叶
+社会生产服务和生活服务人员 五金零售 购建材等
+销售人员 房地产租赁经营 参与建设村集体用地“霞梧集体项目”
+销售人员 便利店零售 副食品店
+销售人员 百货零售 经营周转
+农作物生产人员 海水捕捞 捕捞生产
+农作物生产人员 蔬菜种植 个人经营
+农作物生产人员 渔业产品批发 个人生产经营
+畜禽种苗繁育人员 鸭的饲养 畜牧业
+事业单位负责人 住宅装饰和装修 综合消费
+销售人员 酒、饮料及茶叶零售 茶叶经营
+道路运输服务人员 其他公路客运 经营客运
+采购人员 建材批发 经营周转
+水产捕捞及有关人员 海水捕捞 个人经营
+农业生产服务人员 猪的饲养 个人经营
+销售人员 百货零售 食品店
+农、林、牧、渔业生产及辅助人员 道路运输业 道路运输业
+砖瓦石材等建筑材料制造人员 粘土砖瓦及建筑砌块制造 购煤土
+社会生产服务和生活服务人员 服装零售 经营服装店
+销售人员 稻谷种植 进货
+农、林、牧、渔业生产及辅助人员 小麦种植 经营种植
+销售人员 其他综合零售 个人经营
+农业生产服务人员 其他农牧产品批发 经营农副产品
+农作物生产人员 稻谷种植 续贷
+其他批发与零售服务人员 其他室内装饰材料零售 住房装修
+采购人员 医疗用品及器材零售 电商经营
+其他批发与零售服务人员 便利店零售 经营医疗投资日常资金需要
+其他农业生产人员 其他建筑安装 厨柜安装经营
+农、林、牧、渔业生产及辅助人员 其他食品批发 无还本续贷
+销售人员 其他未列明服务业 家庭综合消费
+其他新闻出版、文化专业人员 其他娱乐业 综合消费
+专业化设计服务人员 住宅装饰和装修 购买建材
+其他文化、体育和娱乐服务人员 教育辅助服务 用于偿还黄阳生贷款
+销售人员 服装零售 周转性贷款
+社会生产服务和生活服务人员 酒、饮料及茶叶零售 零售业
+销售人员 其他日用品零售 无还本续贷
+水产养殖人员 海水养殖 养鲍鱼
+餐饮服务人员 互联网零售 个人经营
+木材加工人员 单板加工 购木材
+其他批发与零售服务人员 灯具零售 经营家具城
+销售人员 果品、蔬菜零售 续贷
+销售人员 肉、禽、蛋、奶及水产品零售 风险化解续贷
+水产养殖人员 海水养殖 养殖鲍鱼
+美容美发和浴池服务人员 理发及美容服务 无还本续贷
+水产养殖人员 海水养殖 个人经营
+水产捕捞及有关人员 海水捕捞 个人经营
+农作物生产人员 香蕉等亚热带水果种植 购买化肥等
+行政事务处理人员 其他居民服务业 个人消费
+农作物生产人员 茶叶种植 个人经营
+农副产品加工人员 猪的饲养 借新还旧
+水产养殖人员 海水养殖 养殖鲍鱼
+其他农、林、牧、渔业生产及辅助人员 酒、饮料及茶叶零售 借新还旧
+销售人员 其他日用品零售 个人经营
+行政业务办理人员 其他农业 个人消费
+针织人员 其他针织或钩针编织服装制造 购涤纶丝
+道路运输服务人员 其他农业 个人消费
+中小学教育教师 普通初中教育 个人消费
+农、林、牧、渔业生产及辅助人员 居民服务业 居民服务业
+农作物生产人员 食用菌种植 种植香菇
+农、林、牧、渔业生产及辅助人员 其他食品批发 无还本续贷
+农、林、牧、渔业生产及辅助人员 零售业 零售业
+不便分类的其他从业人员 其他综合零售 个人消费
+生产制造及有关人员 建筑装饰、装修和其他建筑业 建筑装饰、装修和其他建筑业
+畜禽饲养人员 鸡的饲养 经营种养殖周转
+其他房地产服务人员 其他住宿业 购出租房家居材料
+农作物生产人员 果品、蔬菜零售 个人经营
+农作物生产人员 小麦种植 种植小麦
+党的机关、国家机关、群众团体和社会组织、企事业单位负责人 零售业 零售业
+房屋建筑施工人员 住宅房屋建筑 个人经营
+房地产中介服务人员 房地产租赁经营 参与建设村集体用地“霞梧集体项目”
+环境治理服务人员 其他农业 个人消费
+水产养殖人员 海水养殖 养殖鲍鱼
+水产养殖人员 海水养殖 养殖鲍鱼
+水产养殖人员 海水养殖 养鱼
+销售人员 其他房地产业 购房
+农作物生产人员 其他中药材种植 个人经营
+销售人员 酒、饮料及茶叶批发 烟酒进货
+销售人员 住宅装饰和装修 个人消费
+销售人员 橡胶零件制造 无还本续贷
+行政业务办理人员 其他服务业 其他服务业
+销售人员 建材批发 购建筑材料
+群众文化活动服务人员 其他房地产业 购二手房
+广播电视传输服务人员 建筑装饰、装修和其他建筑业 建筑装饰、装修和其他建筑业
+农、林、牧、渔业生产及辅助人员 林木育种 种绿化苗
+销售人员 肉、禽、蛋、奶及水产品零售 归还薛明好名下普惠金融卡
+森林经营和管护人员 森林经营和管护 林业
+销售人员 零售业 零售业
+其他批发与零售服务人员 非金属矿及制品批发 经营石材
+事业单位负责人 住宅装饰和装修 个人消费
+销售人员 建材批发 购买建筑材料
+销售人员 建材批发 购买建筑材料
+销售人员 建材批发 购买建筑材料
+塑料制品加工人员 住宅装饰和装修 住房装修
+农、林、牧、渔业生产及辅助人员 林业 林业
+销售人员 五金零售 经营五金店
+自由职业者 房地产租赁经营 参与建设村集体用地“霞梧集体项目”
+五金制品制作装配人员 其他金属制日用品制造 无还本续贷
+餐饮服务人员 小吃服务 个人经营
+水产养殖人员 海水养殖 养殖鲍鱼
+农、林、牧、渔业生产及辅助人员 零售业 零售业
+建筑装饰人员 住宅装饰和装修 个人经营
+农作物生产人员 茶叶种植 无还本续贷
+农作物生产人员 茶叶种植 茶叶种植
+销售人员 其他水果种植 果树
+其他批发与零售服务人员 便利店零售 无还本续贷(个人经营-便利店)
+社会生产服务和生活服务人员 陶瓷、石材装饰材料零售 个人经营
+农、林、牧、渔业生产及辅助人员 海水养殖 借新还旧(个人经营)
+木材加工人员 其他家具制造 购石材等
+餐饮服务人员 快餐服务 经营快餐
+其他房地产服务人员 陶瓷、石材装饰材料零售 进货
+农作物生产人员 茶叶种植 个人经营
+销售人员 珠宝首饰零售 经营玉器@JY4LD9QT0
+销售人员 工艺美术品及收藏品零售 经营周转金
+销售人员 陶瓷、石材装饰材料零售 购买建材等
+水产养殖人员 海水养殖 养殖鲍鱼
+采购人员 家具零售 经营建材
+办事人员和有关人员 正餐服务 餐饮业
+水产养殖人员 海水养殖 养殖八爪鱼
+银行专业人员 其他农业 个人消费
+作物种子(苗)繁育生产人员 其他居民服务业 个人消费
+销售人员 陶瓷、石材装饰材料零售 零售业
+农、林、牧、渔业生产及辅助人员 小吃服务 个人经营
+农、林、牧、渔业生产及辅助人员 农产品初加工活动 农、林、牧、渔专业及辅助性活动
+销售人员 家具零售 个人经营
+销售人员 建材批发 采购装饰材料
+幼儿教育教师 住宅装饰和装修 个人消费
+机械工程技术人员 其他农业 个人消费
+水产养殖人员 海水养殖 养鱼
+销售人员 百货零售 零售业
+农作物生产人员 稻谷种植 经营农产品(借新还旧)
+不便分类的其他从业人员 其他农业专业及辅助性活动 个人经营
+农业生产人员 其他制鞋业 个人经营周转
+水产捕捞及有关人员 海水捕捞 海洋捕捞(再贷款专项额度)
+其他专业技术人员 居民服务业 居民服务业
+行政业务办理人员 居民服务业 居民服务业
+农、林、牧、渔业生产及辅助人员 金属结构制造 金属制品业
+农、林、牧、渔业生产及辅助人员 雕塑工艺品制造 个人经营
+军人 零售业 零售业
+公共卫生辅助服务人员 其他居民服务业 家庭综合消费
+销售人员 陶瓷、石材装饰材料零售 经营石材
+道路运输服务人员 大型货物道路运输 无还本续贷经营货运
+销售人员 五金零售 购水暖配件等
+租赁业务人员 汽车租赁 经营二手车
+餐饮服务人员 其他房屋建筑业 购桃李春风住宅
+销售人员 服装零售 购买服装
+行政业务办理人员 其他居民服务业 个人消费
+其他办事人员和有关人员 国家机构 国家机构
+水上运输服务人员 海水养殖 养殖鲍鱼
+其他农、林、牧、渔业生产及辅助人员 其他居民服务业 个人消费
+道路运输服务人员 普通货物道路运输 货运经营
+销售人员 果品、蔬菜零售 水果购销(借新还旧)
+其他纺织品、服装和皮革、毛皮制品加工制作人员 其他家用纺织制成品制造 用于归还黄艺玲的贷款
+农、林、牧、渔业生产及辅助人员 麻类种植 借新还旧
+社会生产服务和生活服务人员 木质家具制造 无还本续贷(经营家具)
+专业技术人员 住宅装饰和装修 无还本续贷
+农业生产服务人员 五金产品批发 个人经营
+办事人员和有关人员 其他未列明国家机构 个人消费
+销售人员 其他非金属矿物制品制造 销售煤矸石等
+销售人员 其他非金属矿物制品制造 销售煤矸石等
+保险专业人员 其他未列明商务服务业 无还本续贷
+住宿服务人员 其他住宿业 无还本续贷
+水产养殖人员 海水养殖 养殖对虾
+作物种子(苗)繁育生产人员 建材批发 个人经营
+销售人员 住宅装饰和装修 归还本人普惠卡
+汽车摩托车修理技术服务人员 其他农业 个人经营
+销售人员 肉、禽、蛋、奶及水产品零售 经营周转
+销售人员 陶瓷、石材装饰材料零售 购建材
+其他农、林、牧、渔业生产及辅助人员 农业机械活动 购买农机
+其他农业生产人员 柑橘类种植 农业
+生活照料服务人员 住宅装饰和装修 装修房屋
+纺织品和服装剪裁缝纫人员 服饰制造 重组贷款
+砖瓦石材等建筑材料制造人员 其他非金属矿物制品制造 个人消费
+销售人员 正餐服务 个人经营
+其他批发与零售服务人员 肉、禽、蛋、奶及水产品批发 个人经营
+销售人员 珠宝首饰零售 经营珠宝店
+销售人员 珠宝首饰零售 经营珠宝店
+其他办事人员 住宅装饰和装修 续贷盘转(原普惠卡)
+销售人员 计算机、软件及辅助设备零售 购电子产品
+行政业务办理人员 其他居民服务业 购房
+农、林、牧、渔业生产及辅助人员 猪的饲养 养猪(转贷)
+餐饮服务人员 小吃服务 经营餐饮
+其他批发与零售服务人员 服装零售 经营服装
+农作物生产人员 稻谷种植 无还本续贷
+建筑工程技术人员 市政道路工程建筑 购房
+群众文化活动服务人员 其他农业 个人消费
+餐饮服务人员 其他饮料及冷饮服务 盘活不良
+其他农林牧渔生产辅助人员 酒、饮料及茶叶零售 借新还旧
+农业生产服务人员 其他综合零售 零售业
+销售人员 百货零售 购买原材料
+作物种子(苗)繁育生产人员 其他农业专业及辅助性活动 收购槟榔芋
+其他食品、饮料产品加工人员 鱼糜制品及水产品干腌制加工
+销售人员 便利店零售 无还本续贷
+餐饮服务人员 柑橘类种植 果树种植
+其他社会生产和生活服务人员 服装零售 经营服装店
+水产养殖人员 海水养殖 个人经营
+农作物生产人员 居民服务业 居民服务业
+农作物生产人员 其他中药材种植 个人经营
+其他修理及制作服务人员 住宅房屋建筑 借新还旧
+销售人员 五金零售 零售业
+农作物生产人员 小麦种植 种植小麦
+
+调味品及食品添加剂制作人员 其他调味品、发酵制品制造 红曲加工
+物业管理服务人员 居民服务业 居民服务业
+其他批发与零售服务人员 肉、禽、蛋、奶及水产品零售 个人经营
+销售人员 建材批发 经营建材店
+中小学教育教师 住宅装饰和装修 个人消费
+销售人员 建材批发 经营周转
+农作物生产人员 茶叶种植 个人经营
+电力、热力生产和供应人员 水力发电 归还贷记卡欠款
+美容美发和浴池服务人员 理发及美容服务 理发店经营
+销售人员 粮油零售 经营便利店,购买食品
+销售人员 机动车燃油零售 购买成品油
+水产养殖人员 海水养殖 个人经营
+销售人员 日用陶瓷制品制造 购陶瓷等
+销售人员 建材批发 购石材、烟酒等
+经济和金融专业人员 零售业 零售业
+销售人员 酒、饮料及茶叶零售 个人经营续贷
+餐饮服务人员 快餐服务 个人经营
+其他批发与零售服务人员 日用家电零售 个人经营
+销售人员 服装零售 购服装
+水产养殖人员 海水养殖 养殖鲍鱼
+社会生产服务和生活服务人员 住宅房屋建筑 垫付工程款
+社会生产服务和生活服务人员 住宅房屋建筑 垫付工程款
+销售人员 纺织品、针织品及原料批发 经营周转备用金
+销售人员 机动车燃油零售 经营挖掘机销售
+销售人员 其他房地产业 购二手房
+办事人员 服装零售 个人经营
+安全和消防人员 零售业 零售业
+其他社会生产和生活服务人员 其他未列明制造业 借新还旧
+农作物生产人员 稻谷种植 个人消费
+金属加工机械制造人员 环境保护专用设备制造 环卫设备生产与销售
+其他农、林、牧、渔业生产及辅助人员 其他综合零售 购房
+行政业务办理人员 日用家电零售 个人消费
+建筑工程技术人员 住宅装饰和装修 借新还旧贷款
+农作物生产人员 服装零售 经营服装辅料经营部
+道路运输服务人员 普通货物道路运输 无还本续贷
+销售人员 服装零售 经营周转
+水产养殖人员 海水养殖 鱼排养殖
+行政事务处理人员 其他家禽饲养 养殖(续贷)
+行政事务处理人员 其他家禽饲养 养殖(续贷)
+其他批发与零售服务人员 服装零售 经营服装
+行政事务处理人员 其他娱乐业 综合消费
+农业生产服务人员 柑橘类种植 种果
+农作物生产人员 其他房屋建筑业 借新还旧
+其他专业技术人员 其他农业 个人消费
+不便分类的其他从业人员 其他日用品零售 周转性贷款
+销售人员 烟草制品零售 个人经营
+农、林、牧、渔业生产及辅助人员 居民服务业 居民服务业
+不便分类的其他从业人员 餐饮业 餐饮业
+农、林、牧、渔业生产及辅助人员 海水捕捞 借新还旧
+其他批发与零售服务人员 其他居民服务业 经营蔬菜摊
+其他批发与零售服务人员 其他居民服务业 经营蔬菜摊
+美容美发和浴池服务人员 理发及美容服务 购化妆品
+美容美发和浴池服务人员 理发及美容服务 购化妆品
+农作物生产人员 蔬菜种植 个人经营
+销售人员 其他综合零售 手机店经营
+农作物生产人员 住宅装饰和装修 个人经营
+房屋建筑施工人员 其他土木工程建筑施工 足浴店周转
+汽车摩托车修理技术服务人员 汽车新车零售 公司经营流动资金
+其他办事人员 柑橘类种植 种果费用(购入化肥等物资)
+水产捕捞及有关人员 内陆捕捞 经营渔船(无还本续贷)
+销售人员 其他制鞋业 借新还旧
+行政事务处理人员 住宅装饰和装修 个人消费
+水产养殖人员 海水养殖 个人经营
+餐饮服务人员 正餐服务 归还到期贷款
+农作物生产人员 食用菌种植 种植木耳
+其他农、林、牧、渔业生产及辅助人员 海水养殖 个人经营
+销售人员 其他日用品零售 经营日杂店
+销售人员 服装零售 经营周转
+陶瓷制品制造人员 陈设艺术陶瓷制造 进货
+作物种子(苗)繁育生产人员 其他农业专业及辅助性活动 养殖
+邮政和快递服务人员 住宅房屋建筑 购一手房
+纺织品和服装剪裁缝纫人员 服饰制造 借新还旧
+软件和信息技术服务人员 应用软件开发 经营周转
+农、林、牧、渔业生产及辅助人员 羊的饲养 经营周转(养殖)
+汽车摩托车修理技术服务人员 摩托车修理与维护 经营汽车配件,购买配件
+其他农、林、牧、渔业生产及辅助人员 房地产租赁经营 参与建设村集体用地“霞梧集体项目”
+销售人员 日用家电零售 生产经营周转
+销售人员 海水养殖 周转性贷款
+农作物生产人员 柑橘类种植 种植柑橘
+水产养殖人员 内陆养殖 养殖白对虾
+销售人员 肉、禽、蛋、奶及水产品零售
+销售人员 酒、饮料及茶叶零售 购烟酒
+办事人员和有关人员 学前教育 综合消费
+塑料制品加工人员 塑料零件及其他塑料制品制造 购塑料制品等
+农作物生产人员 其他农业 农场经营
+农作物生产人员 其他农业专业及辅助性活动 蔬菜收购
+水产养殖人员 海水捕捞 养殖鲍鱼
+其他农副产品加工人员 普通货物道路运输 个人经营
+农、林、牧、渔业生产及辅助人员 其他家禽饲养 畜牧业
+社会生产服务和生活服务人员 建材批发 建材店经营周转
+销售人员 便利店零售 生产经营周转
+生产制造及有关人员 住宅房屋建筑 建筑装饰、装修和其他建筑业
+销售人员 建材批发 个人经营
+住宿服务人员 快餐服务 购食材
+农作物生产人员 土木工程建筑业 土木工程建筑业
+农、林、牧、渔业生产及辅助人员 其他农业 借新还旧(归还普惠卡欠款)
+销售人员 肉、禽、蛋、奶及水产品零售 周转性贷款
+销售人员 酒、饮料及茶叶零售 经营茶叶店(无还本续贷)
+销售人员 建材批发 购建材等
+房屋建筑施工人员 含油果种植 个人经营
+行政业务办理人员 其他居民服务业 家庭综合消费(好享贷)
+销售人员 百货零售 经营便利店
+行政业务办理人员 社会事务管理机构 消费
+其他居民服务人员 摩托车及零配件零售 经营电动车车行
+生活照料服务人员 家庭服务 个人经营
+销售人员 建材批发 经营建材
+农作物生产人员 茶叶种植 个人经营
+电力工程技术人员 其他居民服务业 综合消费
+农、林、牧、渔业生产及辅助人员 内陆养殖 经营海鲜
+水产养殖人员 内陆养殖 个人经营
+其他专业技术人员 其他农业 个人消费
+水产养殖人员 内陆养殖 经营周转
+建筑装饰人员 住宅装饰和装修 个人经营
+农作物生产人员 食用菌种植 个人经营
+作物种子(苗)繁育生产人员 正餐服务 个人经营
+农、林、牧、渔业生产及辅助人员 花卉种植 农业
+党的机关、国家机关、群众团体和社会组织、企事业单位负责人 海水养殖 个人消费性贷款
+农作物生产人员 其他综合零售 零售业
+农作物生产人员 架线及设备工程建筑 无还本续贷
+销售人员 日用家电零售 借新还旧
+其他农业生产人员 猪的饲养 养猪
+建筑装饰人员 住宅装饰和装修 购建材
+销售人员 通信设备零售 购对讲机等
+酒、饮料及精制茶制造人员 茶叶种植 个人经营
+农作物生产人员 其他互联网平台 短视频创作
+电力供应服务人员 其他建筑安装 个人消费
+水泥、石灰、石膏及其制品制造人员 石灰石、石膏开采 个体经营
+水泥、石灰、石膏及其制品制造人员 石灰石、石膏开采 经营加工厂
+销售人员 五金零售 个人经营-永安市燕南罗暧莹五金经营部周转
+销售人员 住宅装饰和装修 住房装修
+餐饮服务人员 正餐服务 经营餐饮店
+餐饮服务人员 正餐服务 经营餐饮店
+餐饮服务人员 正餐服务 经营海鲜楼
+销售人员 酒、饮料及茶叶批发 个人经营
+其他金属制品制造人员 五金零售 购五金配件等
+其他批发与零售服务人员 烟草制品批发 经营食杂店周转
+农业生产人员 柑橘类种植 借新还旧
+农作物生产人员 柑橘类种植 水果种植
+其他农业生产人员 其他未列明餐饮业 购房
+采购人员 淀粉及淀粉制品制造 食品
+银行服务人员 住宅装饰和装修 房屋装修
+采购人员 汽车旧车零售 购二手车周转
+水产养殖人员 海水养殖 个人经营
+其他交通运输、仓储和邮政业服务人员 普通货物道路运输 周转性贷款
+商务咨询服务人员 其他农业 个人消费
+贸易经济代理人员 其他科技推广服务业 经营周转
+农副林特产品初加工人员 其他水果种植 个人经营
+住宿和餐饮服务人员 零售业 零售业
+其他办事人员 零售业 零售业
+销售人员 其他农牧产品批发 经营流动资金
+销售人员 鞋帽零售 经营周转
+餐饮服务人员 正餐服务 开小吃店
+其他农、林、牧、渔业生产及辅助人员 海水养殖 养殖鲍鱼
+其他农林牧渔生产辅助人员 其他农业 个人经营
+农作物生产人员 百货零售 日用品店经营转贷
+销售人员 厨具卫具及日用杂品批发 批发业
+其他房地产服务人员 住宅装饰和装修 无还本续贷
+销售人员 日用家电零售 制冷设备店经营
+销售人员 日用家电零售 制冷设备店经营
+行政业务办理人员 住宅房屋建筑 购二手房
+酒、饮料及精制茶制造人员 精制茶加工 经营茶叶
+五金制品制作装配人员 建筑幕墙装饰和装修 门窗
+水产养殖人员 海水养殖 个人经营
+农作物生产人员 柑橘类种植 个人经营
+销售人员 住宅装饰和装修 经营装潢公司
+电力、热力生产和供应人员 太阳能发电 进光伏板
+社会生产服务和生活服务人员 果品、蔬菜零售 综合消费
+道路运输服务人员 其他道路运输辅助活动 个人经营
+农、林、牧、渔业生产及辅助人员 烟草种植 种烟
+土木工程建筑施工人员 工矿工程建筑 工程周转
+建材工程技术人员 文具用品零售 进货
+其他批发与零售服务人员 其他园艺作物种植 借新还旧
+销售人员 酒、饮料及茶叶零售 经营食杂店
+行政业务办理人员 其他农业 个人消费
+中等职业教育教师 其他综合零售 综合消费
+水产养殖人员 海水养殖 水产养殖
+水产养殖人员 内陆养殖 养虾
+农、林、牧、渔业生产及辅助人员 五金零售 经营支出
+住宿服务人员 其他未列明卫生服务 个人经营
+其他办事人员 其他居民服务业 住房装修
+其他办事人员 其他居民服务业 住房装修
+房屋建筑施工人员 建筑用石加工 借新还旧
+其他批发与零售服务人员 便利店零售 经营超市
+农作物生产人员 建材批发 经营建材
+党的机关、国家机关、群众团体和社会组织、企事业单位负责人 建筑装饰、装修和其他建筑业 建筑装饰、装修和其他建筑业
+农作物生产人员 林木育苗 借新还旧(种植苗木)
+农、林、牧、渔业生产及辅助人员 其他土木工程建筑施工 个人经营
+其他烟草及其制品加工人员 烟叶复烤 种植烟草
+房屋建筑施工人员 住宅装饰和装修 建筑装饰、装修和其他建筑业
+农业生产服务人员 其他居民服务业 个人经营
+其他农业生产人员 柑橘类种植 种植蜜柚
+餐饮服务人员 农、林、牧、渔专业及辅助性活动 农、林、牧、渔专业及辅助性活动
+销售人员 肉、禽、蛋、奶及水产品零售 经营水产品零售
+其他批发与零售服务人员 其他综合零售 经营建材
+销售人员 肉、禽、蛋、奶及水产品零售 经营周转金
+销售人员 果品、蔬菜批发 购水果
+不便分类的其他从业人员 零售业 零售业
+农、林、牧、渔业生产及辅助人员 农、林、牧、渔专业及辅助性活动 农、林、牧、渔专业及辅助性活动
+农、林、牧、渔业生产及辅助人员 居民服务业 居民服务业
+销售人员 鞋帽批发 用于归还李春侨贷款
+生活照料服务人员 其他土木工程建筑施工 承包工程垫资
+农作物生产人员 茶叶种植 经营茶叶
+销售人员 蔬菜加工 个人经营
+采购人员 超级市场零售 经营超市
+道路和水上运输工程技术人员 其他综合零售 个人消费
+农、林、牧、渔业生产及辅助人员 其他水果种植 种植
+销售人员 其他未列明批发业 建材购销
+销售人员 房地产租赁经营 参与建设村集体用地“霞梧集体项目”
+销售人员 五金产品批发 个人经营
+作物种子(苗)繁育生产人员 茶叶种植 个人经营
+农业生产人员 零售业 零售业
+其他农、林、牧、渔业生产及辅助人员 海水养殖 养殖黄鱼
+其他社会生产和生活服务人员 花卉种植 种花
+居民服务人员 零售业 零售业
+行政业务办理人员 群众团体、社会团体和其他成员组织 群众团体、社会团体和其他成员组织
+销售人员 服装零售 进货款
+农作物生产人员 稻谷种植 种植
+其他农、林、牧、渔业生产及辅助人员 猪的饲养 养猪
+自由职业者 房地产租赁经营 参与建设村集体用地“霞梧集体项目”
+办事人员和有关人员 零售业 零售业
+中小学教育教师 其他居民服务业 家庭综合消费
+销售人员 卫生洁具零售 经营周转
+五金制品制作装配人员 其他农业 借新还旧
+中小学教育教师 其他娱乐业 综合消费
+采购人员 茶叶种植 个人经营
+销售人员 服装批发 个人经营
+水产养殖人员 海水捕捞 鲍鱼养殖
+水产养殖人员 海水养殖 养殖鲍鱼
+广播电视传输服务人员 互联网广告服务 农业
+信息传输、软件和信息技术服务人员 零售业 零售业
+销售人员 肉、禽、蛋、奶及水产品零售 水产品店经营
+销售人员 肉、禽、蛋、奶及水产品零售 购水产品
+销售人员 建材批发 购砂石等
+销售人员 建材批发 购砂石等
+销售人员 建材批发 购砂石等
+餐饮服务人员 正餐服务 归还普惠卡透支本金
+林木种苗繁育人员 林木育苗 种植绿化苗
+社会生产服务和生活服务人员 社会保障 社会保障
+其他批发与零售服务人员 住宅装饰和装修 住房装修
+银行专业人员 住宅装饰和装修 个人消费
+销售人员 化妆品及卫生用品零售 经营化妆品
+农作物生产人员 茶叶种植 个人经营
+销售人员 酒、饮料及茶叶零售 购买茶叶
+销售人员 其他农业专业及辅助性活动 农、林、牧、渔专业及辅助性活动
+销售人员 酒、饮料及茶叶零售 借新还旧
+水产养殖人员 海水养殖 养殖海带
+其他批发与零售服务人员 便利店零售 零售业
+皮革、毛皮及其制品制造人员 橡胶鞋制造 采购各类鞋材
+教学人员 教育 教育
+销售人员 百货零售 经营食杂
+销售人员 其他未列明零售业 个人经营
+其他农业生产人员 柑橘类种植 农业
+销售人员 住宅装饰和装修 个人经营
+行政事务处理人员 社会事务管理机构 个人消费
+水产养殖人员 海水养殖 养殖鲍鱼
+采购人员 其他水果种植 购化肥
+其他农业生产人员 花卉种植 无还本续贷
+餐饮服务人员 快餐服务 经营烧烤店
+农作物生产人员 其他水果种植 种植水果
+农、林、牧、渔业生产及辅助人员 塑料板、管、型材制造 橡胶和塑料制品业
+其他批发与零售服务人员 百货零售 购买日用百货
+销售人员 香蕉等亚热带水果种植 种植水果
+销售人员 酒、饮料及茶叶批发 经营食品店购买食品
+社会生产服务和生活服务人员 建材批发 无还本续贷
+销售人员 其他居民服务业 经营普惠众诚网络有限公司
+其他农林牧渔生产辅助人员 柑橘类种植 种植生产费用
+农业生产服务人员 其他水果种植 购房
+餐饮服务人员 餐饮配送服务 个人经营
+其他生产制造及有关人员 其他居民服务业 周转性贷款
+销售人员 非金属矿及制品批发 个人经营
+销售人员 其他农业 个人消费
+销售人员 五金零售 五金材料批发
+其他批发与零售服务人员 百货零售 零售业
+农业生产服务人员 营养和保健品批发 经营流动资金
+批发与零售服务人员 农产品初加工活动 个人经营
+
+销售人员 住宅装饰和装修 住宅装修
+作物种子(苗)繁育生产人员 农业 农业
+水产养殖人员 海水养殖 购饲料(养殖青蟹)
+不便分类的其他从业人员 其他农业 个人消费
+其他办事人员 住宅装饰和装修 住房装修
+行政事务处理人员 住宅装饰和装修 个人消费
+水产捕捞及有关人员 海水捕捞 个人经营
+畜禽饲养人员 牛的饲养 购买肉牛
+租赁业务人员 互联网安全服务 无还本续贷
+社会生产服务和生活服务人员 果品、蔬菜零售 经营周转
+其他 房地产租赁经营 参与建设村集体用地“霞梧集体项目”
+水产捕捞及有关人员 沿海货物运输 经营沙船周转
+农作物生产人员 蔬菜种植 种植
+水产养殖人员 内陆养殖 个人经营
+纺织品和服装剪裁缝纫人员 其他房地产业 购住房
+其他专业技术人员 其他房屋建筑业 借新还旧
+其他专业技术人员 其他居民服务业 个人消费
+教学人员 农、林、牧、渔专业及辅助性活动 农、林、牧、渔专业及辅助性活动
+销售人员 农业专业及辅助性活动 个人经营
+其他专业技术人员 其他未列明服务业 个人消费
+其他专业技术人员 其他未列明服务业 个人消费
+销售人员 汽车修理与维护 个人消费
+畜禽饲养人员 牛的饲养 养殖黄牛
+保险服务人员 住宅装饰和装修 个人消费
+销售人员 百货零售 周转性贷款
+软件和信息技术服务人员 其他农业 个人消费
+其他农、林、牧、渔业生产及辅助人员 其他居民服务业 个人经营
+住宿和餐饮服务人员 其他农业 个人经营
+销售人员 食品、饮料及烟草制品批发 个人经营
+销售人员 百货零售 零售业
+婚姻服务人员 婚姻服务 经营婚庆
+农作物生产人员 茶叶种植 个人经营
+党的机关、国家机关、群众团体和社会组织、企事业单位负责人 其他金融业 其他金融业
+美容美发和浴池服务人员 理发及美容服务 经营理发店
+生活照料服务人员 首饰、工艺品及收藏品批发 无还本续贷
+水产养殖人员 海水养殖 养殖黄鱼
+农作物生产人员 茶叶种植 个人经营
+销售人员 肉、禽、蛋、奶及水产品零售 经营水产品零售
+作物种子(苗)繁育生产人员 造林和更新 种桉树
+农业生产人员 海水养殖 虾池养殖
+销售人员 酒、饮料及茶叶批发 个人消费
+水产养殖人员 海水养殖 海蛏养殖、销售
+餐饮服务人员 正餐服务 经营餐饮店
+农作物生产人员 其他农业 农业
+农业生产人员 其他乳制品制造 购黄豆
+销售人员 陶瓷、石材装饰材料零售 购买瓷砖存货
+销售人员 建材批发 经营周转
+其他农、林、牧、渔业生产及辅助人员 正餐服务 经营饭店日常资金周转
+销售人员 天然植物纤维编织工艺品制造 购硅胶、石膏粉等
+社会生产服务和生活服务人员 果品、蔬菜批发 经营周转
+作物种子(苗)繁育生产人员 葡萄种植 个人经营
+土木工程建筑施工人员 公路工程建筑 包工地
+农作物生产人员 林木育种 种植林木
+水产养殖人员 海水养殖 个人经营
+销售人员 卫生洁具零售 无还本续贷
+其他社会生产和生活服务人员 住宅装饰和装修 建筑装饰、装修和其他建筑业
+水产养殖人员 海水养殖 个人经营
+农、林、牧、渔业生产及辅助人员 水产品冷冻加工 经营冷冻厂
+教学人员 建筑装饰、装修和其他建筑业 建筑装饰、装修和其他建筑业
+销售人员 汽车旧车零售 周转性贷款
+水产养殖人员 海水养殖 养殖鲍鱼
+销售人员 纺织面料鞋制造 经营鞋面厂支付货款
+道路运输服务人员 普通货物道路运输 汽车运输周转
+农作物生产人员 其他农业 农业
+房屋建筑施工人员 住宅房屋建筑 购装修材料
+水产养殖人员 海水养殖 鲍鱼养殖
+水产养殖人员 海水养殖 无还本续贷
+农作物生产人员 住宅装饰和装修 借新还旧
+其他批发与零售服务人员 汽车及零配件批发 轮胎批发
+水产养殖人员 海水养殖 养殖鲍鱼
+其他农、林、牧、渔业生产及辅助人员 其他公路客运 农村客运
+行政事务处理人员 住宅装饰和装修 购买装修材料
+专业技术人员 其他居民服务业 个人消费
+五金制品制作装配人员 金属结构制造 房屋装修
+餐饮服务人员 快餐服务 经营糕饼店
+其他农林牧渔生产辅助人员 其他农业专业及辅助性活动 个人经营
+水产养殖人员 海水养殖 鲍鱼养殖
+作物种子(苗)繁育生产人员 稻谷种植 养蜂
+
+销售人员 服装零售 经营周转
+批发与零售服务人员 食品、饮料及烟草制品专门零售 个人经营
+作物种子(苗)繁育生产人员 流动货摊零售 谷仓
+餐饮服务人员 正餐服务 归还杨信伟贷款
+销售人员 服装批发 经营服装
+五金制品制作装配人员 其他未列明建筑业 钢架结构搭建
+农作物生产人员 住宅房屋建筑 经营房屋建筑
+销售人员 日用家电零售 经营周转
+销售人员 日用家电零售 经营周转
+畜禽饲养人员 鸡的饲养 养鸡
+其他采矿人员 建筑装饰用石开采 经营石材
+水产养殖人员 海水养殖 水产养殖公司经营周转
+餐饮服务人员 其他食品批发 购农产品
+信息通信业务人员 信息技术咨询服务 个人经营
+其他批发与零售服务人员 五金零售 购建材、五金
+基础化学原料制造人员 其他未列明服务业 综合消费
+社会生产服务和生活服务人员 供应链管理服务 人力资源服务
+销售人员 百货零售 经营日杂店
+其他食品、饮料产品加工人员 小吃服务 经营小吃店
+销售人员 灯具零售 生产经营
+水产捕捞及有关人员 肉、禽、蛋、奶及水产品零售 水产品零售
+销售人员 其他居民服务业 购房
+销售人员 鞋帽零售 服装店
+社会生产服务和生活服务人员 住宅装饰和装修 经营装修
+其他批发与零售服务人员 家具零售 家具店进货
+环境保护工程技术人员 公共建筑装饰和装修 无还本续贷
+销售人员 肉、禽、蛋、奶及水产品零售 购生猪等
+社会生产服务和生活服务人员 普通货物道路运输 无还本续贷
+糖制品加工人员 精制茶加工 经营茶叶加工厂
+销售人员 五金零售 购五金配件
+水产养殖人员 海水养殖 个人经营
+餐饮服务人员 正餐服务 经营周转
+农作物生产人员 茶叶种植 种植茶叶
+自由职业者 房地产租赁经营 参与建设村集体用地“霞梧集体项目”
+销售人员 建材批发 经营砂石
+销售人员 建筑幕墙装饰和装修 无还本续贷
+农作物生产人员 麻类种植 种植茶叶
+水产育苗繁育人员 内陆养殖 个人经营
+农业生产服务人员 柑橘类种植 种果
+不便分类的其他从业人员 零售业 零售业
+销售人员 汽车旧车零售 经营二手车
+餐饮服务人员 小吃服务 经营小吃店购买食材
+销售人员 酒、饮料及茶叶零售 经营周转
+销售人员 酒、饮料及茶叶零售 经营周转
+纺织品和服装剪裁缝纫人员 其他未列明批发业 个人消费
+销售人员 涂料零售 采购五金
+农作物生产人员 建材批发 经营建筑材料、室内装饰材料、五金材料等
+专业技术人员 其他水果种植 农、林、牧、渔专业及辅助性活动
+销售人员 非金属矿及制品批发 购买商铺
+农、林、牧、渔业生产及辅助人员 酒、饮料及茶叶批发 购复合肥
+餐饮服务人员 正餐服务 购餐具、酒、食材
+销售人员 其他房地产业 购房
+销售人员 其他互联网服务 无还本续贷
+其他办事人员 住宅装饰和装修 经营室内装修
+其他农业生产人员 汽车新车零售 零售业
+技术辅助服务人员 零售业 零售业
+销售人员 其他农业 个人消费
+其他建筑施工人员 太阳能发电 用于安装光伏发电设备
+其他农、林、牧、渔业生产及辅助人员 住宅装饰和装修 个人消费
+销售人员 日用家电零售 购电器等
+其他农林牧渔生产辅助人员 快餐服务 个人经营
+社会生产服务和生活服务人员 住宅装饰和装修 装修
+销售人员 鞋帽零售 经营周转
+水产养殖人员 海水养殖 养殖黄鱼
+水产养殖人员 海水养殖 养虾投资生产
+其他农业生产人员 坚果种植 种植吊瓜
+销售人员 首饰、工艺品及收藏品批发 金店经营周转
+销售人员 酒、饮料及茶叶零售 经营茶厂
+农、林、牧、渔业生产及辅助人员 其他农业专业及辅助性活动 农、林、牧、渔专业及辅助性活动
+其他非金属矿物制品制造人员 其他非金属矿物制品制造 归还贷款
+销售人员 公共建筑装饰和装修 经营灯具
+农作物生产人员 金属工艺品制造 采购木材
+其他文化、体育和娱乐服务人员 其他土木工程建筑施工 个人经营
+其他农业生产人员 其他居民服务业 个人消费
+水产养殖人员 小吃服务 经营小吃店
+水产养殖人员 海水养殖 养殖鲍鱼
+企事业单位负责人 住宅装饰和装修 个人消费
+农作物生产人员 其他农业专业及辅助性活动 个人经营
+机械工程技术人员 其他居民服务业 个人消费
+再生物资回收人员 再生物资回收与批发 经营废品
+销售人员 其他未列明批发业 装修需要
+农作物生产人员 烟草种植 个人经营
+农作物生产人员 茶叶种植 茶叶展销
+电子工程技术人员 其他农业 个人消费
+销售人员 五金零售 个人经营
+社会生产服务和生活服务人员 管道和设备安装 建筑安装业
+其他农业生产人员 手工具制造 经营蔬菜店资金需要
+其他农业生产人员 手工具制造 经营蔬菜店资金需要
+销售人员 其他未列明批发业 经营电器经营部
+农作物生产人员 茶叶种植 个人经营
+生产制造及有关人员 零售业 零售业
+餐饮服务人员 正餐服务 经营火锅店
+餐饮服务人员 正餐服务 购食材等
+销售人员 住宅装饰和装修 进货
+销售人员 日用家电零售 经营周转
+建筑工程技术人员 其他房屋建筑业 个人经营
+住宿服务人员 民宿服务 经营周转
+其他 其他互联网服务 借新还旧
+农作物生产人员 其他农业专业及辅助性活动 帮扶贷(种植柿子)
+销售人员 住宅装饰和装修 经营五金店
+销售人员 建材批发 流动资金
+农作物生产人员 其他农业 农业
+其他电气机械和器材制造人员 五金产品批发 无还本续贷
+餐饮服务人员 正餐服务 无还本续贷
+畜禽饲养人员 羊的饲养 个人经营
+经济和金融专业人员 其他金融业 其他金融业
+办事人员和有关人员 其他未列明批发业 批发业
+销售人员 首饰、工艺品及收藏品批发 购买工艺品
+销售人员 木质装饰材料零售 经营周转
+销售人员 化妆品及卫生用品零售 化妆品店周转金
+农、林、牧、渔业生产及辅助人员 海水养殖 养殖海参
+工艺美术与创意设计专业人员 五金零售 个人经营
+水产养殖人员 海水养殖 养殖螃蟹
+农业生产服务人员 烟草种植 种烟
+健身和娱乐场所服务人员 健身休闲活动 个人经营
+水产捕捞及有关人员 海水养殖 无还本续贷
+餐饮服务人员 小吃服务 经营小吃店
+采购人员 卫生洁具零售 购卫浴产品
+其他社会生产和生活服务人员 零售业 零售业
+农作物生产人员 住宅房屋建筑 购房
+销售人员 服装零售 购服装
+建材工程技术人员 其他居民服务业 家庭综合消费
+软件和信息技术服务人员 信息技术咨询服务 购买经营所需的货品及日常经营周转
+水产养殖人员 海水养殖 个人经营
+农作物生产人员 便利店零售 经营食杂周转金。
+餐饮服务人员 快餐服务 购买食品
+矿物采选人员 建筑装饰用石开采 石材经营
+其他 建材批发 个人经营
+中小学教育教师 住宅装饰和装修 个人消费
+社会生产服务和生活服务人员 再生物资回收与批发 个人经营
+行政业务办理人员 其他文化艺术业 综合消费
+电力供应服务人员 电力供应 综合消费
+销售人员 住宅装饰和装修 建房装修
+销售人员 其他林业专业及辅助性活动 个人经营
+销售人员 住宅房屋建筑 装修房屋
+其他批发与零售服务人员 木质装饰材料零售 经营建材店
+其他农、林、牧、渔业生产及辅助人员 柑橘类种植 种柑
+其他社会生产和生活服务人员 其他未列明制造业 用于归还贷款。
+住宿服务人员 其他未列明餐饮业 经营餐饮店日常资金需要
+水产养殖人员 海水养殖 养殖黄鱼
+其他 其他食品零售 购烟
+其他 其他食品零售 经营日杂零售
+销售人员 谷物、豆及薯类批发 批发业
+销售人员 化妆品及卫生用品批发 购买商品
+销售人员 其他食品零售 经营食杂店日常资金需要
+农作物生产人员 稻谷种植 个人经营
+销售人员 百货零售 购买住宅
+畜禽饲养人员 其他未列明服务业 养猪周转
+农作物生产人员 房地产租赁经营 参与建设村集体用地“霞梧集体项目”
+销售人员 机动车燃油零售 个人经营
+其他食品、饮料产品加工人员 其他未列明农副食品加工 地瓜干加工周转金
+销售人员 其他居民服务业 经营电脑店、食品店
+作物种子(苗)繁育生产人员 运动休闲针织服装制造 个人经营
+销售人员 住宅装饰和装修 建筑安装工程有限公司
+销售人员 营养和保健品零售 经营食品
+销售人员 厨具卫具及日用杂品批发 经营建材店
+摄影扩印服务人员 其他居民服务业 居民服务业
+批发与零售服务人员 零售业 零售业
+不便分类的其他从业人员 其他非金属矿物制品制造 个人经营
+其他批发与零售服务人员 酒、饮料及茶叶零售 住房装修
+销售人员 零售业 零售业
+销售人员 建材批发 经营周转
+农作物生产人员 仁果类和核果类水果种植 种植水果
+农作物生产人员 农业 农业
+农作物生产人员 蔬菜种植 购买化肥
+其他专业技术人员 酒、饮料及茶叶零售 经营茶叶
+其他居民服务人员 其他居民服务业 个人经营
+销售人员 仁果类和核果类水果种植 经营家庭农场
+农、林、牧、渔业生产及辅助人员 猪的饲养 养猪
+采购人员 房地产租赁经营 参与建设村集体用地“霞梧集体项目”
+商务咨询服务人员 果品、蔬菜批发 周转金
+社会生产服务和生活服务人员 酒、饮料及茶叶零售 经营奶茶
+行政业务办理人员 住宅装饰和装修 房屋装修
+其他批发与零售服务人员 其他综合零售 经营佛具
+中小学教育教师 普通小学教育 综合消费
+农作物生产人员 鸡的饲养 养鸡
+销售人员 酒、饮料及茶叶零售 经营茶叶店
+农、林、牧、渔业生产及辅助人员 内陆养殖 养鱼
+道路运输服务人员 建筑工程机械与设备经营租赁 归还贷款
+保卫人员 安全服务 个人经营(续贷)
+农、林、牧、渔业生产及辅助人员 稻谷种植 个人经营
+销售人员 其他软件开发 软件和信息技术服务业
+酒、饮料及精制茶制造人员 茶叶种植 个人经营
+行政业务办理人员 其他不提供住宿社会工作 个人消费
+销售人员 其他食品零售 经营卤料店
+销售人员 其他房地产业 购一手房
+销售人员 建材批发 借新还旧
+销售人员 果品、蔬菜批发 流动资金
+专业技术人员 摩托车及零配件零售 经营周转
+其他农业生产人员 其他中药材种植 种仙草
+美容美发和浴池服务人员 足浴服务 经营足浴店
+其他办事人员 茶叶种植 个人经营
+其他社会生产和生活服务人员 葡萄种植 个人经营
+销售人员 汽车旧车零售 个人经营
+水产养殖人员 海水养殖 养殖鲍鱼
+销售人员 酒、饮料及茶叶零售 经营周转
+砖瓦石材等建筑材料制造人员 粘土砖瓦及建筑砌块制造 个人经营
+销售人员 涂料零售 经营油漆
+销售人员 纺织服装、服饰业 纺织服装、服饰业
+采购人员 其他食品零售 经营便利店
+其他办事人员和有关人员 国家机构 国家机构
+其他林业生产人员 林木育苗 苗木种植
+作物种子(苗)繁育生产人员 花卉种植 个人经营
+销售人员 厨具卫具及日用杂品批发 批发业
+餐饮服务人员 其他房地产业 购一手房
+其他批发与零售服务人员 建材批发 经营建材
+社会生产服务和生活服务人员 稻谷种植 农、林、牧、渔专业及辅助性活动
+作物种子(苗)繁育生产人员 其他居民服务业 个人经营
+销售人员 建材批发 购石材等
+建筑装饰人员 住宅装饰和装修 借新还旧,用于归还债务。
+其他办事人员和有关人员 建筑装饰、装修和其他建筑业 建筑装饰、装修和其他建筑业
+销售人员 便利店零售 零售业
+行政事务处理人员 住宅装饰和装修 综合消费
+其他批发与零售服务人员 五金产品批发 借新还旧
+其他农业生产人员 其他林业专业及辅助性活动 农业
+房屋建筑施工人员 住宅房屋建筑 工程周转
+销售人员 五金零售 五金店周转
+销售人员 日用电器修理 归还傅顺情我行贷款本金
+畜禽饲养人员 猪的饲养 个人经营
+信息和通信工程技术人员 互联网其他信息服务 购房
+化工产品生产通用工艺人员 住宅装饰和装修 个人消费
+销售人员 酒、饮料及茶叶批发 经营茶叶
+销售人员 鞋帽零售 经营鞋店
+销售人员 纺织品及针织品零售 经营百货店(无还本续贷)
+销售人员 其他食品零售 进货
+工艺美术品制作人员 其他工艺美术及礼仪用品制造 经营工艺品加工资金需要
+炼钢人员 其他综合零售 个人消费
+生产制造及有关人员 其他金属制日用品制造 购铜等
+销售人员 正餐服务 无还本续贷
+健康咨询服务人员 门诊部(所) 卫生室经营周转
+不便分类的其他从业人员 土木工程建筑业 土木工程建筑业
+建筑安装施工人员 其他建筑安装 无还本续贷,用于归还贷款本金。
+水产养殖人员 海水养殖 养鱼
+房地产中介服务人员 房地产租赁经营 参与建设村集体用地“霞梧集体项目”
+农、林、牧、渔业生产及辅助人员 便利店零售 经营便利店
+党的机关、国家机关、群众团体和社会组织、企事业单位负责人 居民服务业 居民服务业
+行政业务办理人员 其他居民服务业 个人消费
+矿物采选人员 家庭服务 家庭综合消费
+其他石油加工和炼焦、煤化工生产人员 其他基础化学原料制造 购原料
+销售人员 百货零售 经营百货店资金需要
+其他农业生产人员 大型车辆装备修理与维护 经营机动车检测站
+专业化设计服务人员 其他广告服务 经营广告设计
+餐饮服务人员 民宿服务 经营民宿
+其他木材加工、家具与木制品制作人员 家具零售 购买家具家电
+中小学教育教师 普通小学教育
+农、林、牧、渔业生产及辅助人员 百货零售 购食品等
+农作物生产人员 小麦种植 种植小麦
+销售人员 酒、饮料及茶叶零售 茶叶店经营周转
+居民服务人员 汽车修理与维护 个人经营
+水产养殖人员 海水养殖 养殖鲍鱼
+餐饮服务人员 快餐服务 个人经营
+农作物生产人员 花卉种植 兰花种植
+作物种子(苗)繁育生产人员 其他农业专业及辅助性活动 个人经营
+畜禽饲养人员 鸡的饲养 购买饲料
+销售人员 服装零售 经营服装
+销售人员 服装零售 经营服装
+办事人员和有关人员 稻谷种植 农业
+销售人员 住宅装饰和装修 个人消费
+不便分类的其他从业人员 农、林、牧、渔专业及辅助性活动 农、林、牧、渔专业及辅助性活动
+销售人员 住宅装饰和装修 购进家具
+不便分类的其他从业人员 其他非金属矿物制品制造 个人经营
+再生物资回收人员 再生物资回收与批发 个人经营
+销售人员 电气设备批发 个人经营
+其他社会生产和生活服务人员 其他农业 个人消费
+销售人员 鞋帽零售 用于鞋服店日常经营
+纺纱人员 房屋建筑业 房屋建筑业
+农、林、牧、渔业生产及辅助人员 农、林、牧、渔专业及辅助性活动 农、林、牧、渔专业及辅助性活动
+畜禽饲养人员 鸡的饲养 畜牧业
+行政业务办理人员 住宅装饰和装修 个人消费
+保卫人员 住宅装饰和装修 房子装修
+酒、饮料及精制茶制造人员 精制茶加工 茶叶生产
+其他批发与零售服务人员 其他综合零售 归还本金
+水产养殖人员 海水养殖 鲍鱼养殖
+销售人员 果品、蔬菜批发 经营周转
+社会生产服务和生活服务人员 服装零售 零售业
+销售人员 陶瓷、石材装饰材料零售 购建筑材料
+其他办事人员 机动车燃油零售 经营流动金
+农作物生产人员 林木育种 个人经营
+房屋建筑施工人员 住宅装饰和装修 房屋改造
+销售人员 保健辅助治疗器材零售 零售业
+餐饮服务人员 百货零售 个人经营
+信息通信业务人员 信息技术咨询服务 购装鉓品、鞋等
+纺织品和服装剪裁缝纫人员 服饰制造 支付进货款
+五金制品制作装配人员 黑色金属冶炼和压延加工业 黑色金属冶炼和压延加工业
+销售人员 便利店零售 个人经营贷款资金周转需要
+其他批发与零售服务人员 肉、禽、蛋、奶及水产品零售 经营食品店
+农作物生产人员 食用菌种植 个人经营
+行政业务办理人员 果品、蔬菜批发 个人经营
+其他批发与零售服务人员 住宅房屋建筑 个人经营
+办事人员和有关人员 居民服务业 居民服务业
+销售人员 鞋帽批发 无还本续贷
+销售人员 柑橘类种植 种植蜜柚
+道路运输服务人员 其他综合零售 个人消费
+电机制造人员 家用电力器具专用配件制造 购车等综合消费
+销售人员 服装零售 无还本续贷
+销售人员 灯具零售 购灯具等
+销售人员 其他饮料及冷饮服务 综合消费
+银行专业人员 住宅装饰和装修 个人消费
+其他专业技术人员 铁路货物运输 个人经营资金
+行政执法和仲裁人员 住宅装饰和装修 个人消费
+销售人员 其他未列明批发业 购鱼
+其他办事人员 住宅装饰和装修 个人消费
+其他居民服务人员 其他房屋建筑业 借新还旧
+社会生产服务和生活服务人员 建筑装饰、装修和其他建筑业 建筑装饰、装修和其他建筑业
+采购人员 纺织品及针织品零售 个人经营
+销售人员 汽车零配件零售 借新还旧
+道路运输服务人员 普通货物道路运输 经营运输
+房屋建筑施工人员 其他综合零售 个人消费
+水产养殖人员 海水养殖 个人经营
+群众文化活动服务人员 群众文体活动 经营周转
+销售人员 其他非金属矿物制品制造 个人经营
+销售人员 酒、饮料及茶叶零售 食品销售
+水泥、石灰、石膏及其制品制造人员 水泥制造 归还贷记卡
+水产养殖人员 海水养殖 养殖龙须菜
+其他办事人员 其他综合零售 个人消费
+农作物生产人员 其他未列明制造业 硅胶加工
+家具制造人员 木质家具制造 经营全屋定制
+销售人员 百货零售 百货进货
+农作物生产人员 仁果类和核果类水果种植 个人经营
+水产养殖人员 海水养殖 养殖鲍鱼
+文化、娱乐、体育经纪代理人员 电子游艺厅娱乐活动 个人经营
+土木工程建筑施工人员 园林绿化工程施工 经营周转
+其他批发与零售服务人员 酒、饮料及茶叶零售 个人经营
+其他批发与零售服务人员 陶瓷、石材装饰材料零售 购板材
+农、林、牧、渔业生产及辅助人员 其他家具制造 木质模具加工
+其他办事人员 其他日用品零售 购居家用品等
+其他办事人员 其他日用品零售 购居家用品等
+其他批发与零售服务人员 卫生洁具零售 经营周转
+住宿服务人员 房地产租赁经营 参与建设村集体用地“霞梧集体项目”
+销售人员 便利店零售 经营便利店
+农、林、牧、渔业生产及辅助人员 其他农牧产品批发 水果营销
+健身和娱乐场所服务人员 健身休闲活动 经营健身活动中心
+畜禽饲养人员 羊的饲养 养羊
+农作物生产人员 其他农业专业及辅助性活动 购茶苗
+销售人员 厨具卫具及日用杂品批发 购酒店用品
+销售人员 厨具卫具及日用杂品批发 购酒店用品
+住宿服务人员 房地产租赁经营 周转性贷款
+销售人员 五金零售 购买经营货品等
+企业负责人 家具零售 个人消费
+采购人员 建材批发 购建材
+幼儿教育教师 学前教育 购教学耗材
+农作物生产人员 服装零售 经营服装店资金周转
+学生 住宅装饰和装修 购买家具
+销售人员 其他日用品零售 经营周转
+销售人员 五金产品批发 经营周转
+采购人员 酒、饮料及茶叶零售 购买茶叶
+餐饮服务人员 正餐服务 个人经营
+农作物生产人员 小麦种植 经营建材
+餐饮服务人员 其他未列明餐饮业 经营周转。
+道路运输服务人员 其他公路客运 道路运输
+采购人员 其他室内装饰材料零售 经营装饰材料商店
+采购人员 其他室内装饰材料零售 经营装饰材料商店
+古建筑修建人员 其他土木工程建筑施工 无还本续贷
+其他批发与零售服务人员 其他软件开发 经营周转
+农作物生产人员 茶叶种植 个人经营
+护理人员 其他农业 个人消费
+作物种子(苗)繁育生产人员 茶叶种植 农业
+作物种子(苗)繁育生产人员 百货零售 零售业
+销售人员 海水养殖 个人经营贷款资金周转需
+农作物生产人员 蔬菜种植 种植业转贷
+建筑工程技术人员 其他居民服务业 房屋装修
+建筑工程技术人员 其他未列明服务业 房屋装修
+道路运输服务人员 普通货物道路运输 无还本续贷(个人经营)
+其他信息传输、软件和信息技术服务人员 住宅装饰和装修 无还本续贷
+生产制造及有关人员 粘土砖瓦及建筑砌块制造 非金属矿物制品业
+检验、检测和计量服务人员 其他居民服务业 购二手房
+水产养殖人员 海水养殖 养殖海参
+仓储人员 其他居民服务业 经营周转(借新还旧)
+办事人员和有关人员 运行维护服务 公司流动资金周转
+销售人员 柑橘类种植 经营周转
+其他社会生产和生活服务人员 其他道路货物运输 个人经营
+销售人员 糕点、面包零售 住房装修
+销售人员 涂料零售 个人经营
+社会生产服务和生活服务人员 鞋帽零售 个人经营
+仪器仪表装配人员 卫生洁具零售 个人经营
+其他社会生产和生活服务人员 金属结构制造 养殖业
+其他金属制品制造人员 金属门窗制造 门窗加工销售
+公共卫生辅助服务人员 住宅装饰和装修 房屋装修及购买家具
+农作物生产人员 其他农业 个人经营
+土木工程建筑施工人员 其他土木工程建筑施工 建筑包工转贷
+销售人员 内陆养殖 购鱼苗
+中等职业教育教师 其他农业 个人消费
+销售人员 酒、饮料及茶叶批发 经营周转
+销售人员 其他综合零售 食杂经营
+销售人员 酒、饮料及茶叶零售 无本续贷(经营茶叶)
+企业负责人 其他日用品零售 经营周转
+销售人员 卫生洁具零售 裸房外墙装修
+作物种子(苗)繁育生产人员 稻谷种植 无还本续贷(农E贷)
+房屋建筑施工人员 管道和设备安装 经营周转金
+农作物生产人员 其他综合零售 个人消费性贷款
+其他社会生产和生活服务人员 餐饮业 餐饮业
+销售人员 果品、蔬菜零售 经营水果店购买水果
+销售人员 珠宝首饰零售 个人经营
+销售人员 工艺美术品及收藏品零售 正常
+其他批发与零售服务人员 五金零售 钢材批发销售
+销售人员 建材批发 个人经营
+办事人员和有关人员 烟叶复烤 个人消费
+邮政和快递服务人员 快递服务 周转性贷款
+事业单位负责人 其他未列明服务业 家庭综合消费
+其他批发与零售服务人员 其他食品零售 购食杂等
+其他批发与零售服务人员 其他食品零售 购食杂等
+其他批发与零售服务人员 计算机、软件及辅助设备零售 购买材料
+销售人员 酒、饮料及茶叶零售 茶叶经营
+餐饮服务人员 小吃服务 经营小吃店
+销售人员 首饰、工艺品及收藏品批发 个人经营
+其他办事人员和有关人员 其他农业 个人消费
+销售人员 服装零售 购服装
+社会生产服务和生活服务人员 日用家电零售 个人经营
+其他批发与零售服务人员 其他未列明零售业 借新还旧
+销售人员 纺织品及针织品零售 周转性贷款
+销售人员 服装零售 购经营所需材料等
+其他办事人员 住宅房屋建筑 经营周转金
+农作物生产人员 薯类种植 个人经营
+农作物生产人员 薯类种植 个人经营
+其他农林牧渔生产辅助人员 海水捕捞 养殖经营
+水产养殖人员 内陆养殖 借新还旧
+其他农业生产人员 柑橘类种植 种植蜜柚
+行政业务办理人员 住宅装饰和装修 个人消费
+不便分类的其他从业人员 农业 农业
+农作物生产人员 烟草种植 种烟
+银行专业人员 住宅装饰和装修 个人消费
+销售人员 百货零售 经营超市,购买百货
+水产捕捞及有关人员 海水捕捞 捕捞生产
+销售人员 其他食品批发 个人经营
+水产养殖人员 海水养殖 经营扇贝养殖
+社会生产服务和生活服务人员 其他未列明服务业 其他服务业
+房屋建筑施工人员 住宅装饰和装修 建筑装饰、装修和其他建筑业
+销售人员 建材批发 建材进货
+销售人员 其他室内装饰材料零售 建材店经营
+农作物生产人员 稻谷种植 经营周转
+销售人员 百货零售 百货经营
+其他批发与零售服务人员 纺织品及针织品零售 购买纺织品
+农作物生产人员 便利店零售 饮料商店
+美容美发和浴池服务人员 住宅装饰和装修 住房装修
+行政业务办理人员 其他居民服务业 个人消费
+农业生产人员 海水养殖 网箱养殖购鱼苗及饲料
+其他教学人员 教育辅助服务 经营教育信息服务
+党的机关、国家机关、群众团体和社会组织、企事业单位负责人 卫生 卫生
+水产养殖人员 海水养殖 鲍鱼养殖
+水产养殖人员 海水养殖 鲍鱼养殖
+其他农、林、牧、渔业生产及辅助人员 海水养殖 养虾
+农作物生产人员 葡萄种植 种植葡萄
+水产养殖人员 海水养殖 养殖鲍鱼
+餐饮服务人员 小吃服务 经营小吃店等
+销售人员 超级市场零售 经营超市
+水产养殖人员 海水养殖 个人经营
+其他办事人员 游乐园 购游乐设施等
+农、林、牧、渔业生产及辅助人员 稻谷种植 个人经营
+销售人员 工艺美术品及收藏品零售 零售业
+信息和通信工程技术人员 其他居民服务业 个人消费
+社会生产服务和生活服务人员 住宅装饰和装修 借新还旧
+房地产中介服务人员 房地产租赁经营 参与建设村集体用地“霞梧集体项目”
+销售人员 互联网零售 电商推广运营
+木材加工人员 单板加工 无还本续贷
+其他卫生专业技术人员 门诊部(所) 个人经营
+农、林、牧、渔业生产及辅助人员 食用菌种植 种木耳
+农作物生产人员 葡萄种植 种植葡萄
+土木工程建筑施工人员 其他土木工程建筑施工 个人经营
+销售人员 其他农牧产品批发 茶叶销售
+销售人员 日用家电零售 经营永定区银玲电器经营部
+采购人员 鸭的饲养 扶贫贷养鸡鸭
+农作物生产人员 其他日用杂品制造 其他制造业
+建筑工程技术人员 住宅装饰和装修 个人经营
+水产养殖人员 海水养殖 个人经营
+不便分类的其他从业人员 建筑装饰、装修和其他建筑业 建筑装饰、装修和其他建筑业
+销售人员 零售业 零售业
+餐饮服务人员 正餐服务 购房
+批发与零售服务人员 零售业 零售业
+水产捕捞及有关人员 其他渔业专业及辅助性活动 捕捞生产
+水产捕捞及有关人员 海水捕捞 捕捞生产
+农作物生产人员 海水养殖 魔芋经营
+农作物生产人员 海水养殖 养蟹生产
+水产养殖人员 其他农业 无还本续贷
+其他橡胶和塑料制品制造人员 非金属废料和碎屑加工处理 塑料制造加工
+农作物生产人员 其他水果种植 种植西瓜
+销售人员 酒、饮料及茶叶零售 个体经营
+其他批发与零售服务人员 机动车燃油零售 购成品油
+销售人员 百货零售 购日用品
+销售人员 百货零售 购日用品
+其他农业生产人员 住宅装饰和装修 个人消费
+农副产品加工人员 塑料零件及其他塑料制品制造 购原材料
+农作物生产人员 茶叶种植 个人经营
+销售人员 日用家电零售 购经营所需的家电等
+销售人员 服装零售 经营周转
+餐饮服务人员 其他房地产业 购首套住房
+作物种子(苗)繁育生产人员 花卉种植 经营周转
+销售人员 建筑装饰及水暖管道零件制造 经营卫浴
+房地产中介服务人员 其他居民服务业 个人消费
+住宿服务人员 民宿服务 经营出租房
+销售人员 其他农业 个人消费
+农作物生产人员 食用菌种植 种植香菇
+销售人员 便利店零售 借新还旧
+农业生产人员 海水养殖 养殖生蚝
+生产制造及有关人员 群众团体、社会团体和其他成员组织 群众团体、社会团体和其他成员组织
+道路运输服务人员 普通货物道路运输 普惠卡转贷款
+其他办事人员 零售业 零售业
+建筑装饰人员 住宅房屋建筑 盘转存量到期信贷业务
+社会生产服务和生活服务人员 鞋帽批发 皮革、毛皮、羽毛及其制品和制鞋业
+销售人员 服装零售 购服装
+销售人员 其他未列明制造业 其他制造业
+销售人员 其他食品零售 经营土特产
+社会生产服务和生活服务人员 金属门窗制造 经营周转
+其他农、林、牧、渔业生产及辅助人员 海水养殖 个人经营
+销售人员 建材批发 无还本续贷
+农副产品加工人员 酒、饮料及茶叶零售 酒、饮料及精制茶制造业
+销售人员 家具零售 无还本续贷
+畜禽饲养人员 鸡的饲养 养鸡鸭
+销售人员 其他未列明服务业 个人经营
+化工产品生产通用工艺人员 住宅装饰和装修 住房装修
+生产制造及有关人员 建筑用石加工 无还本续贷
+行政事务处理人员 住宅房屋建筑 购房
+行政事务处理人员 其他土木工程建筑施工 建筑装饰、装修和其他建筑业
+作物种子(苗)繁育生产人员 酒、饮料及茶叶零售 零售业
+销售人员 卫生洁具零售 购水暖卫浴等
+房屋建筑施工人员 住宅房屋建筑 经营周转金
+销售人员 其他综合零售 建材经营
+餐饮服务人员 其他未列明餐饮业 餐饮业
+销售人员 酒、饮料及茶叶零售 个人经营
+销售人员 服装零售 购服装
+水产养殖人员 海水养殖 鲍鱼养殖
+农作物生产人员 茶叶种植 经营茶叶种植场
+其他办事人员 其他综合零售 个人消费资金
+建筑装饰人员 住宅房屋建筑 用于归还贷款本金
+住宿服务人员 通信设备零售 经营周转
+批发与零售服务人员 零售业 零售业
+水产养殖人员 海水养殖 养殖鲍鱼
+餐饮服务人员 正餐服务 用于归还庄丽明的普惠卡
+水产养殖人员 海水养殖 个人经营
+建筑工程技术人员 建筑用石加工 无还本续贷
+农作物生产人员 其他农牧产品批发 贩卖食用菌
+销售人员 汽车新车零售 二手车经营
+销售人员 酒、饮料及茶叶零售 个人经营
+软件和信息技术服务人员 其他未列明信息技术服务业 用于无还本续贷
+社会生产服务和生活服务人员 肉、禽、蛋、奶及水产品零售 借新还旧贷款
+其他农业生产人员 其他农牧产品批发 竹林管理
+不便分类的其他从业人员 住宅装饰和装修 个人消费
+其他农、林、牧、渔业生产及辅助人员 海水养殖 养殖鲍鱼
+农业生产人员 陶瓷、石材装饰材料零售 五金店周转
+软件和信息技术服务人员 其他农业 个人消费
+其他社会生产和生活服务人员 建材批发 购管材、水泥等
+行政事务处理人员 化肥批发 个人经营资金
+银行服务人员 其他农业 个人消费
+其他农业生产人员 木材采运 收购木材
+农、林、牧、渔业生产及辅助人员 其他农业 农业
+餐饮服务人员 快餐服务 个人经营
+销售人员 通信设备零售 经营手机店
+房屋建筑施工人员 住宅房屋建筑 住房装修
+其他农林牧渔生产辅助人员 通信设备零售 购买电子产品
+建筑安装施工人员 其他居民服务业 个人消费
+租赁业务人员 房地产租赁经营 经营出租房
+销售人员 汽车旧车零售 经营二手车销售等
+销售人员 汽车旧车零售 经营二手车销售
+其他农、林、牧、渔业生产及辅助人员 食品、饮料及烟草制品专门零售 个人经营
+销售人员 医疗用品及器材批发 经营周转
+行政业务办理人员 住宅装饰和装修 无还本续贷
+其他社会生产和生活服务人员 其他食品批发 批发业
+销售人员 互联网批发 经营电子商务,购买工艺品
+销售人员 其他未列明批发业 归还本金
+行政业务办理人员 住宅装饰和装修 个人消费
+其他橡胶和塑料制品制造人员 教育 教育
+其他居民服务人员 其他居民服务业 个人经营
+销售人员 其他室内装饰材料零售 采购卫浴产品
+农作物生产人员 酒、饮料及茶叶零售 茶叶生产
+销售人员 建材批发 购买建材
+农作物生产人员 茶叶种植 茶叶种植
+农业生产服务人员 农业机械活动 盘活逾期普惠卡
+住宿服务人员 其他住宿业 周转性贷款
+行政业务办理人员 其他综合零售 个人消费
+农作物生产人员 茶叶种植 经营茶叶种植
+农作物生产人员 茶叶种植 经营茶叶种植
+销售人员 卫生洁具零售 购水暖卫浴等
+其他木材加工、家具与木制品制作人员 竹材采运 购买原材料
+销售人员 工艺美术品及收藏品零售 购配件等
+销售人员 其他仪器仪表制造业 购彩钢板、镀锌板
+销售人员 营养和保健品零售 个人经营
+销售人员 建材批发 经营建材
+农作物生产人员 稻谷种植 种植水稻
+批发与零售服务人员 零售业 零售业
+自由职业者 百货零售 零售业
+农、林、牧、渔业生产及辅助人员 住宅装饰和装修 无还本续贷
+水产养殖人员 海水养殖 养殖鲍鱼
+销售人员 陶瓷、石材装饰材料零售 零售业
+销售人员 餐饮业 餐饮业
+农作物生产人员 茶叶种植 个人经营
+五金制品制作装配人员 金属表面处理及热处理加工 建房
+农作物生产人员 稻谷种植 个人消费
+人造板制造人员 胶合板制造 购材料
+农副产品加工人员 住宅房屋建筑 装修装潢
+农作物生产人员 茶叶种植 个人消费
+水产养殖人员 海水养殖 养殖场周转金
+农业生产人员 市政道路工程建筑 个人经营
+其他 稻谷种植 农业
+餐饮服务人员 快餐服务 经营早餐店
+销售人员 其他机械设备及电子产品批发 经营贸易商行
+销售人员 五金零售 经营卷帘门
+建筑装饰人员 管道和设备安装 个人经营
+农、林、牧、渔业生产及辅助人员 其他居民服务业 借新还旧
+农作物生产人员 茶叶种植 个人经营
+皮革、毛皮及其制品制造人员 皮鞋制造 无还本续贷
+中等职业教育教师 中等职业学校教育 综合消费
+药学技术人员 农业 农业
+其他租赁和商务服务人员 其他广告服务 经营周转
+其他农业生产人员 茶叶种植 经营种植茶叶
+其他社会生产和生活服务人员 其他居民服务业 压降转贷
+销售人员 五金零售 建材购销
+水上运输服务人员 蔬菜种植 个人经营
+农业生产人员 其他农业 个人消费
+作物种子(苗)繁育生产人员 蔬菜种植 借新还旧
+销售人员 便利店零售 个人经营
+不便分类的其他从业人员 其他土木工程建筑施工 购买建材
+销售人员 其他房地产业 购二手住房
+销售人员 其他农业 个人消费
+信息通信业务人员 住宅装饰和装修 住房装修
+健康矫正服务人员 化妆品及卫生用品零售 经营周转金
+销售人员 其他食品批发 经营农副产品店
+农作物生产人员 蔬菜种植 经营周转,地亩款
+生活照料服务人员 茶叶种植 茶叶种植
+其他批发与零售服务人员 其他未列明信息技术服务业 购信息设备
+森林经营和管护人员 森林经营和管护 林业
+旅游及公共游览场所服务人员 旅行社及相关服务 旅游公司经营
+其他交通运输、仓储和邮政业服务人员 其他未列明建筑业 综合消费
+其他批发与零售服务人员 服装零售 个人经营资金
+保健服务人员 养生保健服务 进货
+餐饮服务人员 酒吧服务 个人经营
+农作物生产人员 市政设施管理 经营承包工程
+不便分类的其他从业人员 农、林、牧、渔专业及辅助性活动 农、林、牧、渔专业及辅助性活动
+采购人员 建材批发 续贷
+其他社会生产和生活服务人员 零售业 零售业
+餐饮服务人员 正餐服务 个人经营
+农作物生产人员 农、林、牧、渔专业及辅助性活动 农、林、牧、渔专业及辅助性活动
+农作物生产人员 含油果种植 种油茶
+居民服务人员 村民自治组织 种植柑橘,养殖鸡鸭
+纺织品和服装剪裁缝纫人员 服饰制造 转贷
+水产养殖人员 内陆养殖 借新还旧
+水产养殖人员 内陆养殖 借新还旧
+餐饮服务人员 餐饮配送服务 周转性贷款
+餐饮服务人员 餐饮配送服务 经营周转
+餐饮服务人员 餐饮配送服务 经营周转
+批发与零售服务人员 便利店零售 零售业
+其他卫生专业技术人员 综合医院 借新还旧
+家具制造人员 木质家具制造 个人经营
+销售人员 农产品初加工活动 经营茶叶
+农作物生产人员 其他房地产业 购二手房
+纺织品和服装剪裁缝纫人员 服饰制造 经营周转
+社会生产服务和生活服务人员 家具零售 经营周转,家具备货
+餐饮服务人员 小吃服务 经营小酒馆
+森林经营和管护人员 森林经营和管护 借新还旧
+其他租赁和商务服务人员 其他未列明服务业 无还本续贷
+电力供应服务人员 其他综合零售 无还本续贷
+采购人员 农产品初加工活动 经营茶叶
+销售人员 服装批发 服装经营
+教学人员 零售业 零售业
+皮革、毛皮及其制品制造人员 皮箱、包(袋)制造 借新还旧
+销售人员 家用电子产品修理 个人经营
+销售人员 日用家电零售 流动资金
+不便分类的其他从业人员 快餐服务 无还本续贷
+幼儿教育教师 其他房地产业 购房
+保险专业人员 农业 农业
+自由职业者 房地产租赁经营 参与建设村集体用地“霞梧集体项目”
+其他农、林、牧、渔业生产及辅助人员 住宅房屋建筑 流动资金
+销售人员 服装批发 服饰公司经营
+中小学教育教师 住宅房屋建筑 个人消费
+水产养殖人员 海水捕捞 海洋捕捞
+交通运输、仓储和邮政业服务人员 道路运输业 道路运输业
+销售人员 纺织品、针织品及原料批发 经营周转
+销售人员 纺织品、针织品及原料批发 经营周转
+农、林、牧、渔业生产及辅助人员 稻谷种植 无还本续贷
+销售人员 茶叶种植 个人经营
+其他办事人员 住宅房屋建筑 个人经营
+其他农林牧渔生产辅助人员 住宅房屋建筑 购一手房
+交通运输、仓储和邮政业服务人员 普通货物道路运输 道路运输业
+销售人员 木质家具制造 购买家具
+道路运输服务人员 普通货物道路运输 无还本续贷
+社会生产服务和生活服务人员 居民服务业 居民服务业
+其他批发与零售服务人员 其他综合零售 经营水果店
+行政事务处理人员 其他居民服务业 个人消费
+农作物生产人员 住宅装饰和装修 房屋装修
+邮政和快递服务人员 住宅装饰和装修 个人经营
+水产养殖人员 海水养殖 借新还旧
+销售人员 超级市场零售 经营超市
+森林经营和管护人员 森林经营和管护 无还本续贷
+银行服务人员 零售业 零售业
+社会生产服务和生活服务人员 纺织面料鞋制造 鞋材加工
+水产捕捞及有关人员 海水捕捞 个人经营
+农作物生产人员 住宅装饰和装修 不锈钢加工
+销售人员 其他农牧产品批发 经营农副产品
+销售人员 其他农牧产品批发 经营农副产品
+农作物生产人员 其他农业 个人经营
+其他农、林、牧、渔业生产及辅助人员 海水养殖 借新还旧
+销售人员 其他食品批发 归还普惠卡欠款
+销售人员 正餐服务 个人经营
+轨道交通运输服务人员 高速铁路旅客运输 个人消费
+销售人员 其他室内装饰材料零售 经营建材
+销售人员 住宅装饰和装修 住房装修
+农作物生产人员 其他房地产业 购房
+农作物生产人员 住宅装饰和装修 经营装饰材料店
+及辅助性活动
+高等教育教师 普通高等教育 消费
+农作物生产人员 香蕉等亚热带水果种植 种植香蕉、麻竹
+农、林、牧、渔业生产及辅助人员 造林和更新 造林
+农作物生产人员 其他农业 个人经营
+销售人员 其他电子产品零售 归还贷款本金
+销售人员 烟草制品零售 卷烟零售
+销售人员 住宅装饰和装修 个人消费
+其他社会生产和生活服务人员 其他综合零售 零售业
+农作物生产人员 百货零售 个人消费
+餐饮服务人员 正餐服务 经营五金店
+土木工程建筑施工人员 其他未列明建筑业 购建筑材料
+其他居民服务人员 食用菌种植 个人经营
+销售人员 其他机械设备及电子产品批发 批发业
+农作物生产人员 稻谷种植 续贷
+其他农、林、牧、渔业生产及辅助人员 肉、禽、蛋、奶及水产品零售 个人经营
+销售人员 其他未列明批发业 批发业
+其他通用设备制造人员 其他未列明通用设备制造业 支付材料耗材款
+水产养殖人员 海水养殖 鲍鱼养殖
+农作物生产人员 食用菌种植 个人经营
+销售人员 其他农牧产品批发 个人经营
+农作物生产人员 猪的饲养 养猪
+作物种子(苗)繁育生产人员 茶叶种植 农业
+家具制造人员 家具零售 无还本续贷
+农、林、牧、渔业生产及辅助人员 煤炭及制品批发 个人经营
+幼儿教育教师 学前教育 盘转存量到期业务
+农作物生产人员 其他农业 个人消费
+道路运输服务人员 小吃服务 个人经营性贷款
+中小学教育教师 住宅房屋建筑 住房按揭
+不便分类的其他从业人员 零售业 零售业
+销售人员 陶瓷、石材装饰材料零售 个人经营
+中小学教育教师 居民服务业 居民服务业
+行政业务办理人员 牲畜批发 购销活禽等
+餐饮服务人员 小吃服务 经营小吃店
+农、林、牧、渔业生产及辅助人员 柑橘类种植 种果
+其他专业技术人员 其他居民服务业 盘转存量到期业务
+销售人员 其他综合零售 经营美发店
+销售人员 酒、饮料及茶叶零售 购茶叶
+住宿服务人员 经济型连锁酒店 购酒店用品
+其他批发与零售服务人员 百货零售 购经营用日用百货等
+人民警察 住宅房屋建筑 个人消费
+销售人员 服装零售 服装销售
+销售人员 其他机械设备及电子产品批发 归还吴志雄贷款和信用卡
+贸易经济代理人员 其他农业 个人消费
+销售人员 其他综合零售 购货物
+软件和信息技术服务人员 计算机、通信和其他电子设备制造业 计算机、通信和其他电子设备制造业
+餐饮服务人员 正餐服务 个人经营
+行政事务处理人员 住宅装饰和装修 住房装修
+批发与零售服务人员 普通货物道路运输 道路运输
+销售人员 糕点、面包零售 购冷热食品原材料
+不便分类的其他从业人员 农、林、牧、渔专业及辅助性活动 农、林、牧、渔专业及辅助性活动
+其他农业生产人员 鸡的饲养 养鸡
+销售人员 服装零售 贸易公司流动资金
+销售人员 住宅装饰和装修 个人消费
+砖瓦石材等建筑材料制造人员 建筑用石加工 个人经营
+其他批发与零售服务人员 服装批发 购买经营所需的服装等
+其他办事人员 零售业 零售业
+农、林、牧、渔业生产及辅助人员 酒、饮料及茶叶零售 经营日用品店
+销售人员 其他日用品零售 经营日用品
+土木工程建筑施工人员 住宅房屋建筑 借新还旧
+水产养殖人员 海水养殖 海蛎养殖
+餐饮服务人员 快餐服务 
+农作物生产人员 茶叶种植 个人消费
+道路运输服务人员 普通货物道路运输 经营理发店
+销售人员 酒、饮料及茶叶零售 购茶叶
+砖瓦石材等建筑材料制造人员 建筑用石加工 个人周转金
+销售人员 汽车零配件零售 进购配件,日常周转等
+销售人员 酒、饮料及茶叶零售 经营烟酒
+居民服务人员 机动车、电子产品和日用产品修理业 机动车、电子产品和日用产品修理业
+船舶制造人员 其他房地产业 购买二手房
+住宿和餐饮服务人员 小吃服务 经营小吃
+销售人员 棉织造加工 借新还旧
+建筑安装施工人员 其他建筑安装 购买石材
+农作物生产人员 稻谷种植 种养殖周转
+其他建筑施工人员 住宅房屋建筑 经营周转金
+农作物生产人员 其他未列明餐饮业 经营餐饮
+农、林、牧、渔业生产及辅助人员 其他农业 个人经营
+农、林、牧、渔业生产及辅助人员 鱼苗及鱼种场活动 农、林、牧、渔专业及辅助性活动
+销售人员 其他农牧产品批发 经营周转金
+农作物生产人员 蔬菜种植 蔬菜种植
+贸易经济代理人员 家具零售 购家具及家电
+餐饮服务人员 住宅装饰和装修 个人消费
+销售人员 酒、饮料及茶叶批发 茶叶销售
+不便分类的其他从业人员 农副食品加工专用设备制造 农副食品加工业
+采购人员 机动车燃油零售 购成品油
+其他办事人员 住宅房屋建筑 借新还旧
+水产养殖人员 海水养殖 海水养殖
+销售人员 其他室内装饰材料零售 周转性贷款
+住宿服务人员 其他农业 个人消费
+销售人员 酒、饮料及茶叶零售 经营茶叶
+婚姻服务人员 摄影扩印服务 个人经营
+农作物生产人员 住宅房屋建筑 购一手房
+电子元件制造人员 其他房地产业 一手房按揭
+销售人员 酒、饮料及茶叶零售 经营茶叶店资金周转
+企业负责人 综合零售 个人消费
+农作物生产人员 造林和更新 个人经营
+其他纺织品、服装和皮革、毛皮制品加工制作人员 毛巾类制品制造 加工一次性毛巾
+其他林业生产人员 造林和更新 经营毛竹林
+农作物生产人员 小麦种植 种植小麦
+其他农业生产人员 柑橘类种植 个人经营
+幼儿教育教师 学前教育 经营幼儿园
+销售人员 橡胶鞋制造 综合消费
+行政业务办理人员 零售业 零售业
+销售人员 酒、饮料及茶叶批发 经营家庭农场
+建筑工程技术人员 住宅房屋建筑 流动资金
+其他社会生产和生活服务人员 其他农业 个人消费
+作物种子(苗)繁育生产人员 其他食品零售 个人经营
+社会生产服务和生活服务人员 建筑物拆除活动 拆迁工程
+销售人员 住宅装饰和装修 装修等
+销售人员 零售业 零售业
+销售人员 互联网零售 购五金产品
+其他农业生产人员 其他渔业专业及辅助性活动 个人经营
+办事人员和有关人员 通讯设备批发 个人经营
+农、林、牧、渔业生产及辅助人员 电气安装 建筑安装业
+水产养殖人员 海水养殖 借新还旧
+农、林、牧、渔业生产及辅助人员 其他农业专业及辅助性活动 购买肥料
+教学人员 教育 教育
+销售人员 家具零售 经营流动资金
+水产养殖人员 小吃服务 经营小吃店
+专业化设计服务人员 其他居民服务业 经营工程机械生意
+商务咨询服务人员 其他居民服务业 经营周转
+商务咨询服务人员 社会经济咨询 经营周转
+其他农业生产人员 其他中药材种植 种仙草
+社会生产服务和生活服务人员 再生物资回收与批发 购废品
+美容美发和浴池服务人员 理发及美容服务 经营零售超市
+农、林、牧、渔业生产及辅助人员 互联网零售 经营电商
+销售人员 其他未列明餐饮业 经营周转
+餐饮服务人员 快餐服务 经营餐饮周转
+销售人员 摄影扩印服务 个人经营
+其他农业生产人员 其他农业 建烤房
+其他农业生产人员 其他农业 个人经营
+销售人员 住宅装饰和装修 房屋装修
+水产养殖人员 海水养殖 养殖鲍鱼
+生产制造及有关人员 零售业 零售业
+农业生产人员 五金零售 经营五金销售
+销售人员 零售业 零售业
+水产养殖人员 海水养殖 虾池养殖
+农作物生产人员 茶叶种植 个人经营
+其他批发与零售服务人员 计算机、软件及辅助设备批发 零售业
+其他农业生产人员 农业 农业
+行政业务办理人员 农业 农业
+其他社会生产和生活服务人员 房屋建筑业 房屋建筑业
+销售人员 鞋帽零售 支付进货款
+社会生产服务和生活服务人员 便利店零售 食杂店
+其他农业生产人员 烟草种植 种烟
+其他生产制造及有关人员 住宅装饰和装修 房屋装修
+行政事务处理人员 住宅装饰和装修 个人消费
+销售人员 珠宝首饰零售 购珠宝
+销售人员 果品、蔬菜零售 进货等
+销售人员 果品、蔬菜零售 进货等
+销售人员 果品、蔬菜零售 进货等
+销售人员 其他综合零售 个人经营
+餐饮服务人员 其他未列明信息技术服务业 用于经营周转
+餐饮服务人员 其他未列明信息技术服务业 经营周转

+ 22 - 0
agent/tests/test_feedback.py

@@ -0,0 +1,22 @@
+import requests
+import logging
+logging.basicConfig(level=logging.INFO, force=True,format='%(asctime)s - %(levelname)s - %(message)s')
+# user_id: str = Field(..., description="用户ID")
+#     user_nm: Optional[str] = Field(None, description="用户名称")
+#     feedback: str = Field(..., description="用户反馈,必填,agree/reject")
+#     feedback_result: Optional[str] = Field(None, description="反馈的标签结果")
+#     contract_no: str = Field(..., description="合同编号")
+#     user_org: Optional[str] = Field(None, description="用户所属机构")
+#     user_endpoint: Optional[str] = Field(None, description="用户所属网点")
+#     business_attr: str = Field(..., description="业务属性")
+res = requests.post("http://localhost:9876/api/aitag/v1/feedback", json={
+    "user_id": "12345",
+    "user_nm": "张三",
+    "feedback": "agree",
+    "contract_no": "HT-2024-001",
+    "user_org": "XX公司",
+    "user_endpoint": "XX网点",
+    "business_attr": "test_attr"
+})
+logging.info(res.text)
+

+ 7 - 1
agent/tests/test_generate_reg.py

@@ -1,6 +1,12 @@
 import requests
 res = requests.post("http://10.192.72.13:9876/api/aitag/admin/v1/generate_reg", json={
-    "id": "2"
+    "tag_name": "智能电网",
+    "tag_remark": "指以智能电网技术为核心,建设或改造电力系统,提升电力系统智能化水平和运行效率的项目。"
 })
+
+# res = requests.post("http://localhost:8080/api/aitag/admin/v1/generate_reg", json={
+#     "tag_name": "智能电网",
+#     "tag_remark": "指以智能电网技术为核心,建设或改造电力系统,提升电力系统智能化水平和运行效率的项目。"
+# })
 print(res.json())
 

+ 91 - 16
agent/tests/test_inner_api.py

@@ -1,23 +1,98 @@
 import requests
+ids = [
+"20260200001",
+"20260200002",
+"20260200003",
+"20260200004",
+"20260200005",
+"20260200006",
+"20260200007",
+"20260200008",
+"20260200009",
+"20260200010",
+"20260200011",
+"20260200012",
+"20260200013",
+"20260200014",
+"20260200015",
+"202602000016",
+"20260200017",  
+"20260200018",
+"20260200019",
+"20260200020",
+"20260200021",
+"20260200022",      
+"20260200023",
+"20260200024",
+"20260200025",
+"20260200026",
+"20260200027",
+"20260200028",
+"20260200029",   
+"20260200030",
+"20260200031",
+"20260200032",
+"20260200033",
+"20260200034",
+"20260200035",
+"20260200036",
+"20260200037",
+"20260200038",
+"20260200039",
+"20260200040",
+"20260200041",
+"20260200042",
+"20260200043",
+"20260200044",
+"20260200045",
+"20260200046",
+"20260200047",
+"20260200048",
+"20260200049",
+"20260200050",
+"20260200051",
+"20260200052",
+"20260200053",
+"20260200054",
+"20260200055",
+"20260200056",
+"20260200057",
+"20260200058",
+"20260200059",
+"20260200060",
+"20260200061",
+"20260200062",
+"20260200063",
+"20260200064",
+"20260200065",
+"20260200066",
+"20260200067",
+"20260200068",
+"20260200069",
+"20260200070",
+"20260200071",
+"20260200072",
+"20260200073",
+"20260200074",
+"20260200075",
+"20260200076",
+"20260200077",
+"20260200078",
+"20260200079",
+"20260200080",
+"20260200081",
+"20260200082",
+"20260200083",
+]
 
-res = requests.post("http://localhost:8080/api/aitag/admin/v1/synchronize_tag", json={
-    "tag_ids": ["2","3"]
+res = requests.post("http://localhost:9876/api/aitag/admin/v1/synchronize_tag", json={
+    "tag_ids": ids
 })
-print(res.json())
+print(res.text)
 
-# res = requests.post("http://localhost:8080/api/aitag/admin/v1/delete_tag", json={
-#     "tag_ids": ["2","3"]
+# res = requests.post("http://localhost:9876/api/aitag/admin/v1/delete_tag", json={
+#     "tag_ids": ["20260200083"]
 # })
 
-# print(res.json())
+# print(res.text)
 
-# # 在mysql中修改标签后,调用该接口同步标签到es中
-# res = requests.post("http://10.192.72.13:9876/api/aitag/admin/v1/synchronize_tag", json={
-#     "tag_ids": ["2","3"]
-# })
-# print(res.json())
-
-# # 在mysql中删除标签后,调用该接口同步标签到es中
-# res = requests.post("http://10.192.72.13:9876/api/aitag/admin/v1/delete_tag", json={
-#     "tag_ids": ["2","3"]
-# })

+ 4 - 0
agent/tests/test_query.py

@@ -0,0 +1,4 @@
+import requests
+
+result = requests.get("http://localhost:9876/api/aitag/v1/query?business_attr=test_attr")
+print(result.text)

+ 14 - 2
agent/tests/test_reg.py

@@ -1,8 +1,20 @@
 import re
 
 regstr = """
-^(?!.*(服装|纺织|食品|农业|医疗))(海洋.{0,6}(防护|防腐|防污|防附着|防渗透)|防护.{0,6}海洋|防腐.{0,6}(材料|涂料)|防污.{0,6}(材料|涂层)|船舶.{0,3}(防腐|防污)|海工.{0,3}(材料|防护))
+^(?!.*(服装|纺织|食品|农业|医疗)).*(海洋.{0,6}(防护|防腐|防污|防附着|防渗透)|防护.{0,6}海洋|防腐.{0,6}(材料|涂料)|防污.{0,6}(材料|涂层)|船舶.{0,3}(防腐|防污)|海工.{0,3}(材料|防护))
 """
 
+test_cases = [
+    "防腐材料",       
+    "海洋防污涂层",     
+    "船舶防腐",        
+    "职业:个体;投向:船体防腐;用途:海洋防污涂层", 
+    "材料",           
+    "医疗防护服",      
+]
+
+pattern = re.compile(regstr, re.VERBOSE)
+
+for t in test_cases:
+    print(f"{t!r}: {'✓' if pattern.match(t) else '✗'}")
 
-# re.search(regstr, phrase)

+ 2 - 2
agent/tests/test_outter_api.py → agent/tests/test_tagging.py

@@ -3,12 +3,12 @@ import logging
 logging.basicConfig(level=logging.INFO, force=True,format='%(asctime)s - %(levelname)s - %(message)s')
 logging.info("app starting!")
 
-res = requests.post("http://localhost:8080/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",
     "business_attr": "test_attr",
-    "phrase": "职业:务农;投向:水产养殖;用途:养螃蟹"
+    "phrase": "职业:水产养殖人员 投向:海水养殖 用途:个人经营"
 })
 logging.info(res.text)
 

+ 25 - 0
agent/tests/test_tagging_batch.py

@@ -0,0 +1,25 @@
+import requests
+import logging
+import uuid
+logging.basicConfig(level=logging.INFO, force=True,format='%(asctime)s - %(levelname)s - %(message)s')
+logging.info("app starting!")
+
+#批量读取test_data.txt中的测试用例,并调用接口进行测试
+with open("tests/test_data.txt", "r", encoding="utf-8") as f:
+    for line in f:
+        phrase = line.strip().split(" ")
+        if len(phrase) < 2:
+            continue
+        if len(phrase) ==2:
+            phrase = "职业:"+phrase[0]+" "+"投向:"+phrase[1]
+        if len(phrase) == 3:
+            phrase = "职业:"+phrase[0]+" "+"投向:"+phrase[1]+" "+"用途:"+phrase[2]
+
+        logging.info("测试用例: "+phrase)
+        res = requests.post("http://10.192.72.13:9876/api/aitag/v1/tagging", json={
+            "business_attr": uuid.uuid4().hex,
+            "phrase": phrase
+        })
+        logging.info(res.text)
+
+

TEMPAT SAMPAH
agent/服务接口定义.xlsx


+ 11 - 0
server/pom.xml

@@ -26,6 +26,17 @@
         <ojdbc8.version>19.3.0.0</ojdbc8.version>
         <dynamic.datasource.version>3.4.1</dynamic.datasource.version>
     </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>io.jsonwebtoken</groupId>
+                <artifactId>jjwt</artifactId>
+                <version>0.9.1</version>
+            </dependency>
+
+        </dependencies>
+    </dependencyManagement>
     <!-- 模块 -->
     <modules>
         <module>yusp-tagging-core</module>

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

@@ -13,7 +13,12 @@
     <version>1.0.0-SNAPSHOT</version>
 
     <dependencies>
-
+        <!-- Spring Web MVC依赖 -->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+            <version>5.3.33</version>
+        </dependency>
 
         <dependency>
             <groupId>cn.com.yusys.yusp.common</groupId>
@@ -186,6 +191,36 @@
             <artifactId>aspectjrt</artifactId>
             <version>1.9.7</version>
         </dependency>
+
+        <!-- JWT支持 -->
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt</artifactId>
+            <version>0.9.1</version>
+        </dependency>
+
+        <!-- 用于JWT签名算法 -->
+        <dependency>
+            <groupId>javax.xml.bind</groupId>
+            <artifactId>jaxb-api</artifactId>
+            <version>2.3.1</version>
+        </dependency>
+
+        <!-- Servlet API -->
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <version>4.0.1</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.5.13</version>
+        </dependency>
+
+
     </dependencies>
 
     <dependencyManagement>

+ 33 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/annotation/RequireRole.java

@@ -0,0 +1,33 @@
+package cn.com.yusys.yusp.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 权限校验注解
+ * 用于控制接口访问权限
+ *
+ * @author AI助手
+ * @date 2026-02-27
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface RequireRole {
+
+    /**
+     * 允许访问的角色数组
+     * 0: 客户经理
+     * 1: 标签管理人员
+     * 2: 业务管理员
+     * 3: 运维管理员
+     * 4: 测试管理员
+     */
+    String[] value() default {};
+
+    /**
+     * 是否需要登录(默认需要)
+     */
+    boolean requireLogin() default true;
+}

+ 34 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/aop/ApiLogAspect.java

@@ -3,6 +3,7 @@ package cn.com.yusys.yusp.aop;
 import cn.com.yusys.yusp.annotation.ApiOperationType;
 import cn.com.yusys.yusp.domain.entity.AitagApiLog;
 import cn.com.yusys.yusp.service.AitagApiLogService;
+import cn.com.yusys.yusp.util.AuthContextUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import org.aspectj.lang.ProceedingJoinPoint;
@@ -10,6 +11,7 @@ import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;
 import org.aspectj.lang.reflect.MethodSignature;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
 import java.lang.reflect.Method;
@@ -22,6 +24,9 @@ public class ApiLogAspect {
     @Autowired
     private AitagApiLogService apiLogService;
 
+    @Value("${auth.enabled:false}")
+    private boolean authEnabled;
+
     @Around("@annotation(cn.com.yusys.yusp.annotation.ApiOperationType)")
     public Object logApiCall(ProceedingJoinPoint joinPoint) throws Throwable {
         long startTime = System.currentTimeMillis();
@@ -30,6 +35,9 @@ public class ApiLogAspect {
         apiLog.setId(apiLogService.generateLogId());
         apiLog.setCreateDate(new Date());
 
+        // 设置用户信息 - 根据认证状态决定
+        setUserInfo(apiLog);
+
         // 获取操作类型
         MethodSignature signature = (MethodSignature) joinPoint.getSignature();
         Method method = signature.getMethod();
@@ -101,6 +109,32 @@ public class ApiLogAspect {
     }
 
     /**
+     * 设置用户信息
+     * @param apiLog API日志对象
+     */
+    private void setUserInfo(AitagApiLog apiLog) {
+        if (authEnabled) {
+            // 认证启用时,使用当前登录用户信息
+            String currentUserId = AuthContextUtil.getCurrentUser();
+            String currentUserName = AuthContextUtil.getCurrentUserName();
+
+            if (currentUserId != null) {
+                apiLog.setUserId(currentUserId);
+                // 如果有用户名就用用户名,否则用用户ID
+                apiLog.setUserName(currentUserName != null ? currentUserName : currentUserId);
+            } else {
+                // fallback到默认值
+                apiLog.setUserId("unknown");
+                apiLog.setUserName("unknown");
+            }
+        } else {
+            // 认证关闭时,使用固定测试值
+            apiLog.setUserId("testID");
+            apiLog.setUserName("testName");
+        }
+    }
+
+    /**
      * 隐藏敏感数据
      * @param jsonStr 原始JSON字符串
      * @return 隐藏敏感数据后的JSON字符串

+ 13 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/condition/AuthEnabledCondition.java

@@ -0,0 +1,13 @@
+package cn.com.yusys.yusp.condition;
+
+import org.springframework.context.annotation.Condition;
+import org.springframework.context.annotation.ConditionContext;
+import org.springframework.core.type.AnnotatedTypeMetadata;
+
+public class AuthEnabledCondition implements Condition {
+    @Override
+    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
+        String authEnabled = context.getEnvironment().getProperty("auth.enabled");
+        return "true".equals(authEnabled);
+    }
+}

+ 190 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/config/AuthInterceptor.java

@@ -0,0 +1,190 @@
+package cn.com.yusys.yusp.config;
+
+import cn.com.yusys.yusp.annotation.RequireRole;
+import cn.com.yusys.yusp.condition.AuthEnabledCondition;
+import cn.com.yusys.yusp.domain.entity.AitagUser;
+import cn.com.yusys.yusp.mapper.AitagUserMapper;
+import cn.com.yusys.yusp.model.Result;
+import cn.com.yusys.yusp.util.AuthContextUtil;
+import cn.com.yusys.yusp.util.JwtUtil;
+import com.alibaba.fastjson.JSON;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Component;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * 认证拦截器
+ *
+ * @author AI助手
+ * @date 2026-02-27
+ */
+@Slf4j
+@Component
+@Conditional(AuthEnabledCondition.class)
+public class AuthInterceptor implements HandlerInterceptor {
+
+    @Autowired
+    private JwtUtil jwtUtil;
+
+    @Autowired
+    private AitagUserMapper userMapper;
+
+    @Value("${auth.enabled:true}")
+    private boolean authEnabled;
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+        // 如果认证功能未启用,直接放行
+        if (!authEnabled) {
+            log.debug("认证功能已关闭,放行请求: {}", request.getRequestURI());
+            return true;
+        }
+
+        // 只处理Controller方法
+        if (!(handler instanceof HandlerMethod)) {
+            return true;
+        }
+
+        HandlerMethod handlerMethod = (HandlerMethod) handler;
+        RequireRole requireRole = handlerMethod.getMethodAnnotation(RequireRole.class);
+
+        // 如果没有权限注解,直接放行
+        if (requireRole == null) {
+            requireRole = handlerMethod.getBeanType().getAnnotation(RequireRole.class);
+            if (requireRole == null) {
+                return true;
+            }
+        }
+
+        // 检查是否需要登录
+        if (!requireRole.requireLogin()) {
+            return true;
+        }
+
+        // 获取token
+        String token = getTokenFromRequest(request);
+        if (token == null || token.isEmpty()) {
+            log.warn("请求缺少认证token: {}", request.getRequestURI());
+            handleUnauthorized(response, "未提供认证信息");
+            return false;
+        }
+
+        // 验证token
+        if (!jwtUtil.validateToken(token)) {
+            log.warn("token验证失败: {}", request.getRequestURI());
+            handleUnauthorized(response, "认证信息无效或已过期");
+            return false;
+        }
+
+        // 获取用户信息
+        String userId = jwtUtil.getUserIdFromToken(token);
+        String role = jwtUtil.getRoleFromToken(token);
+
+        if (userId == null || role == null) {
+            log.warn("token中缺少必要的用户信息: {}", request.getRequestURI());
+            handleUnauthorized(response, "认证信息不完整");
+            return false;
+        }
+
+        // 获取完整的用户信息(包括用户名)
+        AitagUser user = userMapper.selectByUserId(userId);
+        if (user == null) {
+            log.warn("用户不存在: {}", userId);
+            handleUnauthorized(response, "用户信息不存在");
+            return false;
+        }
+
+        // 检查角色权限
+        String[] allowedRoles = requireRole.value();
+        if (allowedRoles.length > 0) {
+            boolean hasPermission = false;
+            for (String allowedRole : allowedRoles) {
+                if (allowedRole.equals(role)) {
+                    hasPermission = true;
+                    break;
+                }
+            }
+            if (!hasPermission) {
+                log.warn("用户{}角色{}无权访问: {}", userId, role, request.getRequestURI());
+                handleForbidden(response, "权限不足");
+                return false;
+            }
+        }
+
+        // 设置当前用户信息到上下文(包括用户名)
+        AuthContextUtil.setCurrentUser(userId);
+        AuthContextUtil.setCurrentRole(role);
+        AuthContextUtil.setCurrentUserName(user.getUserName()); // 新增:存储用户名
+
+        log.debug("用户{}认证通过,角色: {}, 用户名: {}, 访问: {}", userId, role, user.getUserName(), request.getRequestURI());
+        return true;
+    }
+
+    @Override
+    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
+        // 清除线程本地变量
+        AuthContextUtil.clear();
+    }
+
+    /**
+     * 从请求中获取token
+     *
+     * @param request HTTP请求
+     * @return token
+     */
+    private String getTokenFromRequest(HttpServletRequest request) {
+        // 优先从Header获取
+        String token = request.getHeader("Authorization");
+        if (token != null && token.startsWith("Bearer ")) {
+            return token.substring(7);
+        }
+
+        // 从参数获取
+        token = request.getParameter("token");
+        if (token != null) {
+            return token;
+        }
+
+        return null;
+    }
+
+    /**
+     * 处理未授权响应
+     *
+     * @param response HTTP响应
+     * @param message 错误消息
+     */
+    private void handleUnauthorized(HttpServletResponse response, String message) throws IOException {
+        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+        response.setContentType("application/json;charset=UTF-8");
+        PrintWriter writer = response.getWriter();
+        Result<Void> result = Result.error("401", message);
+        writer.write(JSON.toJSONString(result));
+        writer.flush();
+    }
+
+    /**
+     * 处理禁止访问响应
+     *
+     * @param response HTTP响应
+     * @param message 错误消息
+     */
+    private void handleForbidden(HttpServletResponse response, String message) throws IOException {
+        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
+        response.setContentType("application/json;charset=UTF-8");
+        PrintWriter writer = response.getWriter();
+        Result<Void> result = Result.error("403", message);
+        writer.write(JSON.toJSONString(result));
+        writer.flush();
+    }
+}

+ 20 - 7
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/config/DataDictionary.java

@@ -35,15 +35,28 @@ public class DataDictionary {
 
 
     /**
-     *    统计值
-     *        day:日
-     *        week:周
-     *        month:月
+     *标签启用	tag_enabled
+     * 标签停用	tag_disabled
+     * 标签删除	tag_deleted
+     * 标签未删除	tag_undeleted
      */
-    public static final String DAY = "day";
+    public static final Integer TAG_ENABLED = 0;
 
-    public static final String WEEK = "week";
+    public static final Integer TAG_DISABLED = 1;
+    public static final Integer TAG_DELETED = 1;
 
-    public static final String MONTH = "month";
+    public static final Integer TAG_UNDELETED = 0;
+
+
+
+
+    /**
+     *    标签范围 tag_scope:
+     *        day0正常数据; 1测试数据
+     *
+     */
+    public static final String TEST_DATA = "1";
+
+    public static final String PROD_DATA = "0";
 
 }

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

@@ -0,0 +1,31 @@
+package cn.com.yusys.yusp.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Data
+@Component
+@ConfigurationProperties(prefix = "fastapi.service")
+public class FastApiConfig {
+
+    /**
+     * FastAPI服务地址
+     */
+    private String url;
+
+    /**
+     * 请求超时时间(毫秒)
+     */
+    private int timeout = 10000;
+
+    /**
+     * 连接超时时间(毫秒)
+     */
+    private int connectTimeout = 5000;
+
+    /**
+     * 读取超时时间(毫秒)
+     */
+    private int readTimeout = 10000;
+}

+ 18 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/config/MyBatisPlusConfig.java

@@ -0,0 +1,18 @@
+package cn.com.yusys.yusp.config;
+
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class MyBatisPlusConfig {
+
+    @Bean
+    public MybatisPlusInterceptor mybatisPlusInterceptor() {
+        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
+        return interceptor;
+    }
+}

+ 59 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/config/WebMvcConfig.java

@@ -0,0 +1,59 @@
+package cn.com.yusys.yusp.config;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import java.text.SimpleDateFormat;
+
+/**
+ * Web MVC配置类
+ *
+ * @author AI助手
+ * @date 2026-02-27
+ */
+@Configuration
+public class WebMvcConfig implements WebMvcConfigurer {
+
+    @Autowired(required = false)  // 改为可选注入,避免启动时报错
+    private AuthInterceptor authInterceptor;
+
+    @Value("${auth.enabled:false}")
+    private boolean authEnabled;
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        // 只有当认证功能启用且拦截器存在时才注册
+        if (authEnabled && authInterceptor != null) {
+            registry.addInterceptor(authInterceptor)
+                    .addPathPatterns("/**")
+                    .excludePathPatterns(
+                            "/api/auth/login",
+                            "/api/auth/logout",
+                            "/health",
+                            "/swagger-ui/**",
+                            "/v2/api-docs",
+                            "/webjars/**"
+                    );
+        }
+    }
+
+    /**
+     * 全局Jackson配置,统一时间格式化
+     */
+    @Bean
+    public ObjectMapper objectMapper() {
+        return Jackson2ObjectMapperBuilder.json()
+                .dateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))
+                .timeZone("GMT+8")
+                .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
+                .build();
+    }
+}

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

@@ -1,5 +1,6 @@
 package cn.com.yusys.yusp.controller;
 
+import cn.com.yusys.yusp.annotation.RequireRole;
 import cn.com.yusys.yusp.model.Result;
 import cn.com.yusys.yusp.domain.dto.AitagAppCreateDto;
 import cn.com.yusys.yusp.domain.entity.AitagApp;
@@ -21,6 +22,7 @@ public class AitagAppController {
     private AitagAppService aiTagAppService;
 
     @ApiOperationType("应用列表一览")
+    @RequireRole({"1", "4"})
     @GetMapping("/list")
     public Result<List<AitagApp>> listApps(
             @RequestParam(defaultValue = "1") int page,

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

@@ -24,10 +24,11 @@ public class AitagTagCategoryController {
     @ApiOperationType("标签体系列表")
     @GetMapping("/list")
     public Result<List<AitagTagCategoryVo>> listCategories(
+            @RequestParam(required = false) String categoryNm,
             @RequestParam(defaultValue = "1") int page,
             @RequestParam(defaultValue = "5") int size) {
         try {
-            Page<AitagTagCategoryVo> pageResult = aiTagCategoryService.listCategories(page, size);
+            Page<AitagTagCategoryVo> pageResult = aiTagCategoryService.listCategories(categoryNm, page, size);
             return Result.pageSuccess(pageResult.getRecords(), pageResult.getTotal());
         } catch (Exception e) {
             return Result.error("500", "分页查询失败:" + e.getMessage());
@@ -56,17 +57,6 @@ public class AitagTagCategoryController {
         }
     }
 
-    @ApiOperationType("查询标签体系")
-    @GetMapping("/query")
-    public Result<List<AitagTagCategory>> searchByCategoryNm(@RequestParam String categoryNm) {
-        try {
-            List<AitagTagCategory> categories = aiTagCategoryService.searchByCategoryNm(categoryNm);
-            return Result.success(categories);
-        } catch (Exception e) {
-            return Result.error("500", "模糊查询失败:" + e.getMessage());
-        }
-    }
-
     @ApiOperationType("启用标签体系")
     @PostMapping("/enable")
     public Result<Void> enableCategory(@RequestParam String id) {
@@ -99,4 +89,49 @@ public class AitagTagCategoryController {
             return Result.error("500", "删除标签体系失败:" + e.getMessage());
         }
     }
+
+    @ApiOperationType("已启用标签体系列表一览")
+    @GetMapping("/enablelist")
+    public Result<List<AitagTagCategoryVo>> listEnabledCategories(
+            @RequestParam(defaultValue = "1") int page,
+            @RequestParam(defaultValue = "5") int size) {
+        try {
+            Page<AitagTagCategoryVo> pageResult = aiTagCategoryService.listEnabledCategories(page, size);
+            return Result.pageSuccess(pageResult.getRecords(), pageResult.getTotal());
+        } catch (Exception e) {
+            return Result.error("500", "分页查询失败:" + e.getMessage());
+        }
+    }
+
+
+
+    @ApiOperationType("标签体系详情")
+    @GetMapping("/detail/{id}")
+    public Result<AitagTagCategoryVo> getCategoryDetail(@PathVariable String id) {
+        try {
+            AitagTagCategoryVo categoryDetail = aiTagCategoryService.getCategoryDetail(id);
+            return Result.success(categoryDetail);
+        } catch (Exception e) {
+            return Result.error("500", "查询标签体系详情失败:" + e.getMessage());
+        }
+    }
+
+
+    /**
+     * 外部页面获取已启用的标签体系列表,无需token
+     *
+     * @return ResultDto
+     */
+    @ApiOperationType("外部标签体系")
+    @GetMapping("/enablelistnoauth")
+    public Result<List<AitagTagCategoryVo>> listEnabledCategoriesNoAuth(
+            @RequestParam(defaultValue = "1") int page,
+            @RequestParam(defaultValue = "5") int size) {
+        try {
+            Page<AitagTagCategoryVo> pageResult = aiTagCategoryService.listEnabledCategories(page, size);
+            return Result.pageSuccess(pageResult.getRecords(), pageResult.getTotal());
+        } catch (Exception e) {
+            return Result.error("500", "分页查询失败:" + e.getMessage());
+        }
+    }
 }

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

@@ -1,22 +1,42 @@
 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.util.SessionCommonUtil;
+import cn.com.yusys.yusp.domain.dto.TagInfoDto;
 import cn.com.yusys.yusp.domain.entity.AitagTagInfoEntity;
 import cn.com.yusys.yusp.domain.vo.AitagTagInfoQueryVo;
+import cn.com.yusys.yusp.domain.vo.GenerateRegexVo;
+import cn.com.yusys.yusp.domain.vo.TagNodeVo;
+import cn.com.yusys.yusp.domain.vo.VersionRollbackVo;
+import cn.com.yusys.yusp.domain.vo.fastapivo.AiTaggingResponseVo;
 import cn.com.yusys.yusp.service.AitagTagInfoService;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-
-import java.util.Arrays;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 
@@ -24,9 +44,10 @@ import java.util.List;
  * @author 2507040827
  * @date 2026-02-26 14:34:56
  */
-@Api(tags = "")
+@Api(tags = "标签管理")
 @RestController
 @RequestMapping("/api/aitagtaginfo")
+@Slf4j
 public class AitagTagInfoController {
     /**
      * AitagTagInfoService
@@ -34,6 +55,19 @@ public class AitagTagInfoController {
     @Autowired
     private AitagTagInfoService aitagTagInfoService;
 
+    /**
+     * 列表查询
+     *
+     * @param aitagTagInfoQueryVo
+     * @return ResultDto
+     */
+    @ApiOperationType("列表标签分页信息")
+    @GetMapping("/page")
+    public ResultDto<List<AitagTagInfoEntity>> page(AitagTagInfoQueryVo aitagTagInfoQueryVo) {
+        IPage<AitagTagInfoEntity> page = aitagTagInfoService.queryPage(aitagTagInfoQueryVo);
+        return ResultDto.success(page.getRecords()).total(page.getTotal());
+    }
+
 
     /**
      * 列表查询
@@ -41,25 +75,40 @@ public class AitagTagInfoController {
      * @param aitagTagInfoQueryVo
      * @return ResultDto
      */
-    @ApiOperation("列表查询")
+    @ApiOperationType("标签列表查询")
     @GetMapping("/list")
     public ResultDto<List<AitagTagInfoEntity>> list(AitagTagInfoQueryVo aitagTagInfoQueryVo) {
-        IPage<AitagTagInfoEntity> page = aitagTagInfoService.queryPage(aitagTagInfoQueryVo);
+        List<AitagTagInfoEntity> page = aitagTagInfoService.queryList(aitagTagInfoQueryVo);
+        return ResultDto.success(page);
+    }
 
-        return ResultDto.success(page.getRecords()).total(page.getTotal());
+    /**
+     * 查询标签树
+     *
+     * @param aitagTagInfoQueryVo
+     * @return ResultDto
+     */
+    @ApiOperationType("查询标签树")
+    @PostMapping("/queryTagTree")
+    public ResultDto<List<TagNodeVo>> queryTagTree(@RequestBody AitagTagInfoQueryVo aitagTagInfoQueryVo) {
+        if(StringUtils.isBlank(aitagTagInfoQueryVo.getCategoryId())){
+           throw BizException.of("E001");
+        }
+        List<TagNodeVo> tagNodeVos = aitagTagInfoService.queryTagTree(aitagTagInfoQueryVo);
+        return ResultDto.success(tagNodeVos);
     }
 
+
     /**
      * 详细
      *
      * @param id
      * @return ResultDto
      */
-    @ApiOperation("详细")
+    @ApiOperationType("标签详细")
     @GetMapping("/info/{id}")
-    public ResultDto<AitagTagInfoEntity> info(@PathVariable("id") String id) {
-        AitagTagInfoEntity aitagTagInfo = aitagTagInfoService.getById(id);
-
+    public ResultDto<TagInfoDto> info(@PathVariable("id") String id) {
+        TagInfoDto aitagTagInfo = aitagTagInfoService.getTagInfo(id);
         return ResultDto.success(aitagTagInfo);
     }
 
@@ -69,11 +118,14 @@ public class AitagTagInfoController {
      * @param aitagTagInfoEntity
      * @return ResultDto
      */
-    @ApiOperation("保存")
+    @ApiOperationType("标签保存")
     @PostMapping("/save")
     public ResultDto save(@RequestBody AitagTagInfoEntity aitagTagInfoEntity) {
-        aitagTagInfoService.save(aitagTagInfoEntity);
-
+        String id = aitagTagInfoService.saveTag(aitagTagInfoEntity);
+        HashMap<String, Object> body = new HashMap<>();
+        String[] ids = {id};
+        body.put("tag_ids",ids);
+        aitagTagInfoService.callAiTag(body,"/api/aitag/admin/v1/synchronize_tag");
         return ResultDto.success();
     }
 
@@ -83,26 +135,150 @@ public class AitagTagInfoController {
      * @param aitagTagInfoEntity
      * @return ResultDto
      */
-    @ApiOperation("修改")
+    @ApiOperationType("标签修改")
     @PostMapping("/update")
     public ResultDto update(@RequestBody AitagTagInfoEntity aitagTagInfoEntity) {
-        aitagTagInfoService.updateById(aitagTagInfoEntity);
+        aitagTagInfoService.updateTag(aitagTagInfoEntity);
+        HashMap<String, Object> body = new HashMap<>();
+        String[] ids = {aitagTagInfoEntity.getId()};
+        body.put("tag_ids",ids);
+        aitagTagInfoService.callAiTag(body,"/api/aitag/admin/v1/synchronize_tag");
+        return ResultDto.success();
+    }
 
+    /**
+     * 修改
+     *
+     * @param versionRollbackVo
+     * @return ResultDto
+     */
+    @ApiOperationType("版本回溯")
+    @PostMapping("/versionRollback")
+    public ResultDto versionRollback(@RequestBody VersionRollbackVo versionRollbackVo) {
+        String id = aitagTagInfoService.versionRollback(versionRollbackVo);
+        if(StringUtils.isNotBlank(id)){
+            HashMap<String, Object> body = new HashMap<>();
+            String[] ids = {id};
+            body.put("tag_ids",ids);
+            aitagTagInfoService.callAiTag(body,"/api/aitag/admin/v1/synchronize_tag");
+        }
         return ResultDto.success();
     }
 
+
     /**
      * 删除
      *
      * @param ids
      * @return ResultDto
      */
-    @ApiOperation("删除")
+    @ApiOperationType("删除标签")
     @PostMapping("/delete")
-    public ResultDto delete(@RequestBody String[] ids) {
-        aitagTagInfoService.removeByIds(Arrays.asList(ids));
+    public ResultDto delete(@RequestBody Map<String,List> ids) {
+        List<String> idsList = ids.get("ids");
+        aitagTagInfoService.removeTags(idsList);
+        HashMap<String, Object> body = new HashMap<>();
+        body.put("tag_ids",ids);
+        aitagTagInfoService.callAiTag(body,"/api/aitag/admin/v1/delete_tag");
+        return ResultDto.success();
+    }
 
+    /**
+     * 批量导入
+     *
+     * @param file
+     * @return ResultDto
+     */
+    @ApiOperationType("批量导入")
+    @PostMapping("/batchImport")
+    public ResultDto batchImport( @RequestParam("file") MultipartFile file,
+                                  @RequestParam("reviser") String reviser,
+                                  @RequestParam("categoryId") String categoryId) throws IOException {
+
+        if (file.isEmpty()) {
+           throw BizException.of("E002");
+        }
+
+        // 简单的文件类型检查
+        String fileName = file.getOriginalFilename();
+        if (fileName == null || (!fileName.endsWith(".xlsx") && !fileName.endsWith(".xls"))) {
+            throw BizException.of("E003");
+        }
+        List<String> tagIds = aitagTagInfoService.batchImport(file, reviser, categoryId);
+
+        HashMap<String, Object> body = new HashMap<>();
+        body.put("tag_ids",tagIds);
+        aitagTagInfoService.callAiTag(body,"/api/aitag/admin/v1/synchronize_tag");
         return ResultDto.success();
     }
 
+
+    /**
+     * 生成正则表达式
+     *
+     * @param regexVo
+     * @return ResultDto
+     */
+    @ApiOperationType("生成正则表达式")
+    @PostMapping("/generateRegex")
+    public ResultDto<String> generateRegex( @RequestBody GenerateRegexVo regexVo) throws IOException {
+        Map body = JSONObject.parseObject(JSONObject.toJSONString(regexVo), Map.class);
+
+        AiTaggingResponseVo taggingResponse = aitagTagInfoService.callAiTag(body, "/api/aitag/admin/v1/generate_reg");
+        if(cn.com.yusys.yusp.commons.util.StringUtils.equals(taggingResponse.getCode(),"200")){
+            return ResultDto.success(taggingResponse.getData());
+        }
+        log.error("生成正则表达式异常:返回参数为:{}", JSON.toJSONString(taggingResponse));
+        throw BizException.of("E008");
+
+    }
+
+    /**
+     * 批量导入模板下载
+     *
+     * @return ResultDto
+     */
+    @ApiOperationType("批量导入模板下载")
+    @GetMapping("/downloadFile")
+    public ResponseEntity<Resource> downloadFile( ) throws IOException {
+
+        // 1. 构造文件路径并进行规范化,防止路径遍历攻击 (如 ../../恶意路径)
+        Path filePath = Paths.get("template").resolve("tag_batch_Import_template.xlsx").normalize();
+        ClassPathResource resource = new ClassPathResource(filePath.toString());
+
+        // 2. 校验文件是否存在且可读
+        if (resource.exists() && resource.isReadable()) {
+            // 3. 推断文件的 MediaType (MIME type)
+            String contentType = MediaType.APPLICATION_OCTET_STREAM_VALUE;
+            contentType = Files.probeContentType(filePath);
+            // 4. 返回 ResponseEntity,设置响应头
+            return ResponseEntity.ok()
+                    .contentType(MediaType.parseMediaType(contentType))
+                    // 告知浏览器以附件形式下载,并指定文件名
+                    // 使用 URLEncoder.encode 处理中文文件名乱码问题
+                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\""
+                            + URLEncoder.encode("tag_batch_Import_template.xlsx", StandardCharsets.UTF_8.toString()) + "\"")
+                    .body(resource);
+        } else {
+            // 文件不存在或不可读,返回 404
+            return ResponseEntity.notFound().build();
+        }
+    }
+
+
+    /**
+     * 外部页面查询标签树,无需token
+     *
+     * @param aitagTagInfoQueryVo
+     * @return ResultDto
+     */
+    @ApiOperationType("外部查询标签树")
+    @PostMapping("/queryTagTreeNoAuth")
+    public ResultDto<List<TagNodeVo>> queryTagTreeNoAuth(@RequestBody AitagTagInfoQueryVo aitagTagInfoQueryVo) {
+        if(StringUtils.isBlank(aitagTagInfoQueryVo.getCategoryId())){
+            throw BizException.of("E001");
+        }
+        List<TagNodeVo> tagNodeVos = aitagTagInfoService.queryTagTree(aitagTagInfoQueryVo);
+        return ResultDto.success(tagNodeVos);
+    }
 }

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

@@ -0,0 +1,108 @@
+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.entity.AitagTagInfoVersionEntity;
+import cn.com.yusys.yusp.domain.vo.AitagTagInfoVersionQueryVo;
+import cn.com.yusys.yusp.service.AitagTagInfoVersionService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 标签信息版本表
+ *
+ * @author 2507040827
+ * @date 2026-02-27 11:33:54
+ */
+@Api(tags = "标签信息版本表")
+@RestController
+@RequestMapping("/api/aitagtaginfoversion")
+public class AitagTagInfoVersionController {
+    /**
+     * AitagTagInfoVersionService
+     */
+    @Autowired
+    private AitagTagInfoVersionService aitagTagInfoVersionService;
+
+
+    /**
+     * 列表查询
+     *
+     * @param aitagTagInfoVersionQueryVo
+     * @return ResultDto
+     */
+    @ApiOperationType("列表查询")
+    @GetMapping("/list")
+    public ResultDto<List<AitagTagInfoVersionEntity>> list(AitagTagInfoVersionQueryVo aitagTagInfoVersionQueryVo) {
+        IPage<AitagTagInfoVersionEntity> page = aitagTagInfoVersionService.queryPage(aitagTagInfoVersionQueryVo);
+
+        return ResultDto.success(page.getRecords()).total(page.getTotal());
+    }
+
+    /**
+     * 详细
+     *
+     * @param id
+     * @return ResultDto
+     */
+    @ApiOperationType("详细")
+    @GetMapping("/info/{id}")
+    public ResultDto<AitagTagInfoVersionEntity> info(@PathVariable("id") String id) {
+        AitagTagInfoVersionEntity aitagTagInfoVersion = aitagTagInfoVersionService.getById(id);
+
+        return ResultDto.success(aitagTagInfoVersion);
+    }
+
+    /**
+     * 保存
+     *
+     * @param aitagTagInfoVersionEntity
+     * @return ResultDto
+     */
+    @ApiOperationType("保存")
+    @PostMapping("/save")
+    public ResultDto save(@RequestBody AitagTagInfoVersionEntity aitagTagInfoVersionEntity) {
+        aitagTagInfoVersionService.save(aitagTagInfoVersionEntity);
+        return ResultDto.success();
+    }
+
+    /**
+     * 修改
+     *
+     * @param aitagTagInfoVersionEntity
+     * @return ResultDto
+     */
+    @ApiOperationType("修改")
+    @PostMapping("/update")
+    public ResultDto update(@RequestBody AitagTagInfoVersionEntity aitagTagInfoVersionEntity) {
+        aitagTagInfoVersionService.updateById(aitagTagInfoVersionEntity);
+
+        return ResultDto.success();
+    }
+
+    /**
+     * 删除
+     *
+     * @param ids
+     * @return ResultDto
+     */
+    @ApiOperationType("删除")
+    @PostMapping("/delete")
+    public ResultDto delete(@RequestBody String[] ids) {
+        aitagTagInfoVersionService.removeByIds(Arrays.asList(ids));
+
+        return ResultDto.success();
+    }
+
+}

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

@@ -1,9 +1,11 @@
 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.entity.AitagTagLogEntity;
 import cn.com.yusys.yusp.domain.vo.*;
 import cn.com.yusys.yusp.service.AitagTagLogService;
+import cn.com.yusys.yusp.service.DistributedScheduledTask;
 import com.alibaba.excel.EasyExcel;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
@@ -47,7 +49,7 @@ public class AitagTagLogController {
      * @param taggingResult 智能打标结果
      * @return ResultDto
      */
-    @ApiOperation("我的配置")
+    @ApiOperationType("我的配置")
     @PostMapping("/dataOverview")
     public ResultDto<DataOverviewVo> dataOverview(@RequestBody SmartTaggingResultVo taggingResult) {
         DataOverviewVo dataOverviewDTO = aitagTagLogService.dataOverview(taggingResult);
@@ -62,7 +64,7 @@ public class AitagTagLogController {
      * @param taggingTrendReq 打标趋势
      * @return ResultDto
      */
-    @ApiOperation("打标趋势")
+    @ApiOperationType("打标趋势")
     @PostMapping("/taggingTrend")
     public ResultDto<List<IconResVo>> taggingTrend(@RequestBody TaggingTrendReqVo taggingTrendReq) {
         List<IconResVo> taggingTrendRes = aitagTagLogService.taggingTrend(taggingTrendReq);
@@ -75,7 +77,7 @@ public class AitagTagLogController {
      * @param resultDTO 智能打标结果
      * @return ResultDto
      */
-    @ApiOperation("标签分布统计")
+    @ApiOperationType("标签分布统计")
     @PostMapping("/tagDistStats")
     public ResultDto<List<IconResVo>> tagDistStats(@RequestBody TagDistStatsReqVo resultDTO) {
         List<IconResVo> taggingTrendRes = aitagTagLogService.tagDistStats(resultDTO);
@@ -89,11 +91,11 @@ public class AitagTagLogController {
      * @param transactionReqVo
      * @return ResultDto
      */
-    @ApiOperation("打标明细")
+    @ApiOperationType("打标明细")
     @PostMapping("/taggingTransaction")
     public ResultDto<IPage<AitagTagLogEntity>> taggingTransaction(@RequestBody TaggingTransactionReqVo transactionReqVo) {
         IPage<AitagTagLogEntity> page = aitagTagLogService.taggingDetails(transactionReqVo);
-        return ResultDto.success(page);
+        return ResultDto.success(page.getRecords()).total(page.getTotal());
     }
 
     /**
@@ -102,23 +104,24 @@ public class AitagTagLogController {
      * @param id
      * @return ResultDto
      */
-    @ApiOperation("打标结果详情")
-    @PostMapping("/show")
-    public ResultDto<AitagTagLogEntity> show(@RequestBody String id) {
+    @ApiOperationType("打标结果详情")
+    @GetMapping("/show/{id}")
+    public ResultDto<AitagTagLogEntity> show(@PathVariable("id") String id) {
         AitagTagLogEntity taggingDetailsResDTO = aitagTagLogService.show(id);
         return ResultDto.success(taggingDetailsResDTO);
     }
 
+
     /**
      * 导出数据
      *
      * @param transactionReqVo
      * @return ResultDto
      */
-    @ApiOperation("导出数据")
-    @PostMapping("/exportData")
-    public void exportData(@RequestBody TaggingTransactionReqVo transactionReqVo,HttpServletResponse response) throws IOException {
-        List<AitagTagLogEntity> aitagTagLogEntities = aitagTagLogService.queryList(transactionReqVo);
+    @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);
@@ -142,11 +145,11 @@ public class AitagTagLogController {
                 .doWrite(exportDataVos);
     }
 
-
     private String getTags(String result) {
         if(StringUtils.isBlank(result)){
             return "";
         }
+        result = result.replace("\\", "");
         List<Map> results = JSONArray.parseArray(result, Map.class);
         StringBuilder stringBuilder = new StringBuilder();
         for (int i = 0 ;i<results.size();i++){
@@ -160,5 +163,4 @@ public class AitagTagLogController {
         return stringBuilder.toString();
     }
 
-
 }

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

@@ -0,0 +1,153 @@
+package cn.com.yusys.yusp.controller;
+
+import cn.com.yusys.yusp.annotation.ApiOperationType;
+import cn.com.yusys.yusp.condition.AuthEnabledCondition;
+import cn.com.yusys.yusp.model.Result;
+import cn.com.yusys.yusp.domain.dto.LoginRequestDto;
+import cn.com.yusys.yusp.domain.vo.LoginResponseVo;
+import cn.com.yusys.yusp.service.AuthService;
+import cn.com.yusys.yusp.util.AuthContextUtil;
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+/**
+ * 认证控制器
+ *
+ * @author AI助手
+ * @date 2026-02-27
+ */
+@Slf4j
+@Api(tags = "认证管理")
+@RestController
+@RequestMapping("/api/auth")
+@Conditional(AuthEnabledCondition.class)
+public class AitagUserController {
+
+    @Autowired
+    private AuthService authService;
+
+    @Value("${auth.enabled:true}")
+    private boolean authEnabled;
+
+    /**
+     * 用户登录
+     *
+     * @param loginRequest 登录请求
+     * @return 登录结果
+     */
+    @ApiOperationType("用户登录")
+    @PostMapping("/login")
+    public Result<LoginResponseVo> login(@Valid @RequestBody LoginRequestDto loginRequest) {
+        try {
+            log.info("收到登录请求: {}", loginRequest.getUserId());
+
+            if (!authEnabled) {
+                log.warn("认证功能已关闭,但仍允许登录");
+            }
+
+            LoginResponseVo response = authService.login(loginRequest);
+            return Result.success(response);
+        } catch (Exception e) {
+            log.error("登录失败", e);
+            return Result.error("500", "登录失败: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 用户登出
+     *
+     * @return 登出结果
+     */
+    @ApiOperationType("用户登出")
+    @PostMapping("/logout")
+    public Result<Void> logout() {
+        try {
+            String currentUserId = AuthContextUtil.getCurrentUser();
+            if (currentUserId != null) {
+                authService.logout(currentUserId);
+                log.info("用户登出成功: {}", currentUserId);
+            }
+            return Result.success();
+        } catch (Exception e) {
+            log.error("登出失败", e);
+            return Result.error("500", "登出失败: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 获取当前用户信息
+     *
+     * @return 用户信息
+     */
+    @ApiOperationType("获取当前用户信息")
+    @GetMapping("/current-user")
+    public Result<Object> getCurrentUser() {
+        try {
+            String userId = AuthContextUtil.getCurrentUser();
+            String role = AuthContextUtil.getCurrentRole();
+
+            if (userId == null) {
+                return Result.error("401", "未登录");
+            }
+
+            return Result.success(new CurrentUserInfo(userId, role));
+        } catch (Exception e) {
+            log.error("获取当前用户信息失败", e);
+            return Result.error("500", "获取用户信息失败: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 检查认证状态
+     *
+     * @return 认证状态
+     */
+    @ApiOperationType("检查认证状态")
+    @GetMapping("/status")
+    public Result<AuthStatusVo> getStatus() {
+        AuthStatusVo status = new AuthStatusVo();
+        status.setEnabled(authEnabled);
+        status.setCurrentUser(AuthContextUtil.getCurrentUser());
+        status.setCurrentRole(AuthContextUtil.getCurrentRole());
+        return Result.success(status);
+    }
+
+    /**
+     * 当前用户信息内部类
+     */
+    private static class CurrentUserInfo {
+        private String userId;
+        private String role;
+
+        public CurrentUserInfo(String userId, String role) {
+            this.userId = userId;
+            this.role = role;
+        }
+
+        public String getUserId() { return userId; }
+        public String getRole() { return role; }
+    }
+
+    /**
+     * 认证状态VO
+     */
+    private static class AuthStatusVo {
+        private boolean enabled;
+        private String currentUser;
+        private String currentRole;
+
+        // Getters and setters
+        public boolean isEnabled() { return enabled; }
+        public void setEnabled(boolean enabled) { this.enabled = enabled; }
+        public String getCurrentUser() { return currentUser; }
+        public void setCurrentUser(String currentUser) { this.currentUser = currentUser; }
+        public String getCurrentRole() { return currentRole; }
+        public void setCurrentRole(String currentRole) { this.currentRole = currentRole; }
+    }
+}

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

@@ -0,0 +1,82 @@
+package cn.com.yusys.yusp.controller;
+
+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.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.util.AuthContextUtil;
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+@Slf4j
+@Api(tags = "AI打标接口")
+@RestController
+@RequestMapping("/api/fastapi")
+public class FastApiController {
+
+    @Autowired
+    private FastApiService fastApiService;
+
+    @ApiOperationType("AI 打标")
+    @PostMapping("/tagging")
+    public Result<AiTaggingResponseVo> tagging(@RequestBody AiTaggingRequestDto request) {
+        try {
+            log.info("收到 AI 打标请求:businessAttr={}, tagCategoryId={}", request.getBusinessAttr(), request.getTagCategoryId());
+            AiTaggingResponseVo response = fastApiService.tagging(request);
+            return Result.success(response);
+        } catch (Exception e) {
+            log.error("AI 打标接口调用失败", e);
+            return Result.error("500", "AI 打标接口调用失败:" + e.getMessage());
+        }
+    }
+
+    @ApiOperationType("AI 打标查询")
+    @GetMapping("/query")
+    public Result<AiTaggingQueryResponseVo> query(
+            @Valid @RequestParam String businessAttr) {
+        try {
+            log.info("收到 AI 打标查询请求:businessAttr={}", businessAttr);
+
+            AiTaggingQueryRequestDto request = new AiTaggingQueryRequestDto();
+            request.setBusinessAttr(businessAttr);
+
+            AiTaggingQueryResponseVo response = fastApiService.query(request);
+            return Result.success(response);
+        } catch (Exception e) {
+            log.error("AI 打标查询接口调用失败", e);
+            return Result.error("500", "AI 打标查询接口调用失败:" + e.getMessage());
+        }
+    }
+
+    @ApiOperationType("AI 打标反馈")
+    @PostMapping("/feedback")
+    public Result<AiTaggingResponseVo> feedback(@RequestBody AiTaggingFeedbackRequestDto request) {
+        try {
+            log.info("收到 AI 打标反馈请求:userId={}, businessAttr={}, feedback={}, feedbackResult={}",
+                    request.getUserId(), request.getBusinessAttr(), request.getFeedback(), request.getFeedbackResult());
+
+            // 如果未设置用户信息,使用登录信息
+            String currentUserId = AuthContextUtil.getCurrentUser();
+            String currentUserName = AuthContextUtil.getCurrentUserName();
+
+            if (currentUserId != null && currentUserName != null) {
+                request.setUserId(currentUserId);
+                request.setUserNm(currentUserName);
+            }
+
+            AiTaggingResponseVo response = fastApiService.feedback(request);
+            return Result.success(response);
+        } catch (Exception e) {
+            log.error("AI 打标反馈接口调用失败", e);
+            return Result.error("500", "AI 打标反馈接口调用失败:" + e.getMessage());
+        }
+    }
+}

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

@@ -0,0 +1,26 @@
+package cn.com.yusys.yusp.domain.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * 登录请求DTO
+ *
+ * @author AI助手
+ * @date 2026-02-27
+ */
+@Data
+@ApiModel("登录请求")
+public class LoginRequestDto {
+
+    @NotBlank(message = "用户ID不能为空")
+    @ApiModelProperty(value = "用户ID", required = true)
+    private String userId;
+
+    @NotBlank(message = "密码不能为空")
+    @ApiModelProperty(value = "密码", required = true)
+    private String pwd;
+}

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

@@ -0,0 +1,29 @@
+package cn.com.yusys.yusp.domain.dto;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+public class TagImportDto {
+
+    @ExcelProperty("标签名称")
+    private String tagNm;
+
+    @ExcelProperty("父标签名称")
+    private String parentName;
+
+    @ExcelProperty("标签说明")
+    private String tagRemark;
+
+    @ExcelProperty("标签关键词规则")
+    private String reg;
+
+    /**
+     *  运行时填充字段
+     */
+    private String id;
+    private String parentId;
+    private String tagPath;
+}

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

@@ -0,0 +1,114 @@
+package cn.com.yusys.yusp.domain.dto;
+
+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.util.List;
+
+
+/**
+ * 
+ *标签详情信息
+ * @author 2507040827
+ * @date 2026-02-26 14:34:56
+ */
+@Data
+public class TagInfoDto {
+
+    /**
+     * id
+     **/
+    @ApiModelProperty(value="id")
+    private String id;
+
+    /**
+     * 所属大类
+     **/
+    @ApiModelProperty(value = "所属大类")
+    private String categoryId;
+
+    /**
+     * 标签名称
+     **/
+    @ApiModelProperty(value = "标签名称")
+    private String tagNm;
+
+    /**
+     * 标签代码
+     **/
+    @ApiModelProperty(value = "标签代码")
+    private String tagCode;
+
+    /**
+     * 标签备注
+     **/
+    @ApiModelProperty(value = "标签备注")
+    private String tagRemark;
+
+    /**
+     * 父级ID
+     **/
+    @ApiModelProperty(value = "父级ID")
+    private String parentId;
+
+    /**
+     * 标签规则
+     **/
+    @ApiModelProperty(value = "标签规则")
+    private String reg;
+
+    /**
+     * 标签等级
+     **/
+    @ApiModelProperty(value = "标签等级")
+    private Integer tagLevel;
+
+    /**
+     * tag1/tag2/tag3/...
+     **/
+    @ApiModelProperty(value = "tag1/tag2/tag3/...")
+    private String tagPath;
+
+
+    /**
+     * 标签提示词
+     **/
+    @ApiModelProperty(value = "标签提示词")
+    private String tagPrompt;
+
+
+    /**
+     * 标签版本
+     **/
+    @ApiModelProperty(value = "标签版本")
+    private String tagVersion;
+
+    /**
+     * 修订时间
+     **/
+    @ApiModelProperty(value = "修订时间")
+    private String revisionTime;
+
+    /**
+     * 修订人
+     **/
+    @ApiModelProperty(value = "修订人")
+    private String reviser;
+
+
+    /**
+     * 标签历史版本信息
+     */
+    @ApiModelProperty(value = "标签历史版本信息")
+    private List<TagInfoVersionDto> tagInfoVersionDtos;
+
+
+    public String getTagVersionShow() {
+        return "版本V"+tagVersion;
+    }
+
+}

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

@@ -0,0 +1,114 @@
+package cn.com.yusys.yusp.domain.dto;
+
+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-27 11:33:54
+ */
+@Data
+public class TagInfoVersionDto {
+
+    /**
+     * id
+     **/
+    @ApiModelProperty(value="id")
+    @TableId(type=IdType.UUID)
+    private String id;
+
+    /**
+     * 所属大类
+     **/
+    @ApiModelProperty(value = "所属大类")
+    private String categoryId;
+
+    /**
+     * 标签名称
+     **/
+    @ApiModelProperty(value = "标签名称")
+    private String tagNm;
+
+    /**
+     * 标签代码
+     **/
+    @ApiModelProperty(value = "标签代码")
+    private String tagCode;
+
+    /**
+     * 标签备注
+     **/
+    @ApiModelProperty(value = "标签备注")
+    private String tagRemark;
+
+    /**
+     * 父级ID
+     **/
+    @ApiModelProperty(value = "父级ID")
+    private String parentId;
+
+    /**
+     * 标签规则
+     **/
+    @ApiModelProperty(value = "标签规则")
+    private String reg;
+
+    /**
+     * 标签等级
+     **/
+    @ApiModelProperty(value = "标签等级")
+    private Integer tagLevel;
+
+    /**
+     * tag1/tag2/tag3/...
+     **/
+    @ApiModelProperty(value = "tag1/tag2/tag3/...")
+    private String tagPath;
+
+    /**
+     * 0未删除;1删除
+     **/
+    @ApiModelProperty(value = "0未删除;1删除")
+    private Integer isDelete;
+
+    /**
+     * 0 正常;1 停用
+     **/
+    @ApiModelProperty(value = "0 正常;1 停用")
+    private Integer state;
+
+    /**
+     * 标签提示词
+     **/
+    @ApiModelProperty(value = "标签提示词")
+    private String tagPrompt;
+
+    /**
+     * 标签版本
+     **/
+    @ApiModelProperty(value = "标签版本")
+    private String tagVersion;
+
+    /**
+     * 修订时间
+     **/
+    @ApiModelProperty(value = "修订时间")
+    private String revisionTime;
+
+    /**
+     * 修订人
+     **/
+    @ApiModelProperty(value = "修订人")
+    private String reviser;
+
+    public String getTagVersionShow() {
+        return "版本V"+tagVersion;
+    }
+}

+ 47 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/fastapidto/AiTaggingFeedbackRequestDto.java

@@ -0,0 +1,47 @@
+package cn.com.yusys.yusp.domain.dto.fastapidto;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+@ApiModel("AI 打标反馈请求")
+public class AiTaggingFeedbackRequestDto {
+
+    @JsonProperty("user_id")
+    @ApiModelProperty(value = "用户 ID", required = false)
+    private String userId;
+
+    @JsonProperty("user_nm")
+    @ApiModelProperty(value = "用户姓名", required = false)
+    private String userNm;
+
+    @NotBlank(message = "反馈结果不能为空")
+    @JsonProperty("feedback")
+    @ApiModelProperty(value = "反馈结果 (agree/reject)", required = true)
+    private String feedback;
+
+    @JsonProperty("feedback_result")
+    @ApiModelProperty(value = "用户反馈的打标结果详情,为空表示同意,不为空表示不同意并输入了反馈", required = false)
+    private String feedbackResult;
+
+    @JsonProperty("contract_no")
+    @ApiModelProperty(value = "合同编号", required = false)
+    private String contractNo;
+
+    @JsonProperty("user_org")
+    @ApiModelProperty(value = "用户机构", required = false)
+    private String userOrg;
+
+    @JsonProperty("user_endpoint")
+    @ApiModelProperty(value = "用户终端", required = false)
+    private String userEndpoint;
+
+    @NotBlank(message = "业务属性不能为空")
+    @JsonProperty("business_attr")
+    @ApiModelProperty(value = "业务属性", required = true)
+    private String businessAttr;
+}

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

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

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

@@ -0,0 +1,24 @@
+package cn.com.yusys.yusp.domain.dto.fastapidto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+@ApiModel("AI打标请求")
+public class AiTaggingRequestDto {
+
+
+    @NotBlank(message = "业务属性不能为空")
+    @ApiModelProperty(value = "业务属性", required = true)
+    private String businessAttr;
+
+    @NotBlank(message = "投向+用途+职业不能为空")
+    @ApiModelProperty(value = "投向+用途+职业", required = true)
+    private String phrase;
+
+    @ApiModelProperty(value = "体系 ID", required = false)
+    private String tagCategoryId;
+}

+ 1 - 1
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/entity/AitagTagDailyAggEntity.java

@@ -36,7 +36,7 @@ public class AitagTagDailyAggEntity {
      * 类别名称
      **/
     @ApiModelProperty(value = "标签类别")
-    private String categoryCode;
+    private String categoryId;
 
     /**
      * 标签名称

+ 21 - 96
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/entity/AitagTagInfoEntity.java

@@ -5,16 +5,18 @@ import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.IdType;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
 
 
 /**
  * 
- *
+ *标签信息表
  * @author 2507040827
  * @date 2026-02-26 14:34:56
  */
 @TableName("aitag_tag_info")
-@ApiModel(value = "AitagTagInfoEntity", description = "")
+@ApiModel(value = "AitagTagInfoEntity", description = "标签信息表")
+@Data
 public class AitagTagInfoEntity {
 
     /**
@@ -52,7 +54,7 @@ public class AitagTagInfoEntity {
      * 父级ID
      **/
     @ApiModelProperty(value = "父级ID")
-    private String parentCode;
+    private String parentId;
 
     /**
      * 标签规则
@@ -64,7 +66,7 @@ public class AitagTagInfoEntity {
      * 标签等级
      **/
     @ApiModelProperty(value = "标签等级")
-    private Integer level;
+    private Integer tagLevel;
 
     /**
      * tag1/tag2/tag3/...
@@ -91,100 +93,23 @@ public class AitagTagInfoEntity {
     private String tagPrompt;
 
 
-    public String getId() {
-        return this.id;
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    public String getCategoryId() {
-        return this.categoryId;
-    }
-
-    public void setCategoryId(String categoryId) {
-        this.categoryId = categoryId;
-    }
-
-    public String getTagNm() {
-        return this.tagNm;
-    }
-
-    public void setTagNm(String tagNm) {
-        this.tagNm = tagNm;
-    }
-
-    public String getTagCode() {
-        return this.tagCode;
-    }
-
-    public void setTagCode(String tagCode) {
-        this.tagCode = tagCode;
-    }
-
-    public String getTagRemark() {
-        return this.tagRemark;
-    }
-
-    public void setTagRemark(String tagRemark) {
-        this.tagRemark = tagRemark;
-    }
-
-    public String getParentCode() {
-        return this.parentCode;
-    }
-
-    public void setParentCode(String parentCode) {
-        this.parentCode = parentCode;
-    }
-
-    public String getReg() {
-        return this.reg;
-    }
-
-    public void setReg(String reg) {
-        this.reg = reg;
-    }
-
-    public Integer getLevel() {
-        return this.level;
-    }
-
-    public void setLevel(Integer level) {
-        this.level = level;
-    }
-
-    public String getTagPath() {
-        return this.tagPath;
-    }
-
-    public void setTagPath(String tagPath) {
-        this.tagPath = tagPath;
-    }
-
-    public Integer getIsDelete() {
-        return this.isDelete;
-    }
-
-    public void setIsDelete(Integer isDelete) {
-        this.isDelete = isDelete;
-    }
-
-    public Integer getState() {
-        return this.state;
-    }
+    /**
+     * 标签版本
+     **/
+    @ApiModelProperty(value = "标签版本")
+    private String tagVersion;
 
-    public void setState(Integer state) {
-        this.state = state;
-    }
+    /**
+     * 修订时间
+     **/
+    @ApiModelProperty(value = "修订时间")
+    private String revisionTime;
 
-    public String getTagPrompt() {
-        return this.tagPrompt;
-    }
+    /**
+     * 修订人
+     **/
+    @ApiModelProperty(value = "修订人")
+    private String reviser;
 
-    public void setTagPrompt(String tagPrompt) {
-        this.tagPrompt = tagPrompt;
-    }
 
 }

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

@@ -0,0 +1,115 @@
+package cn.com.yusys.yusp.domain.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.IdType;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+
+/**
+ * 标签信息版本表
+ *
+ * @author 2507040827
+ * @date 2026-02-27 11:33:54
+ */
+@TableName("aitag_tag_info_version")
+@ApiModel(value = "AitagTagInfoVersionEntity", description = "标签信息版本表")
+@Data
+public class AitagTagInfoVersionEntity {
+
+    /**
+     * id
+     **/
+    @ApiModelProperty(value="id")
+    @TableId(type=IdType.UUID)
+    private String id;
+
+    /**
+     * 所属大类
+     **/
+    @ApiModelProperty(value = "所属大类")
+    private String categoryId;
+
+    /**
+     * 标签名称
+     **/
+    @ApiModelProperty(value = "标签名称")
+    private String tagNm;
+
+    /**
+     * 标签代码
+     **/
+    @ApiModelProperty(value = "标签代码")
+    private String tagCode;
+
+    /**
+     * 标签备注
+     **/
+    @ApiModelProperty(value = "标签备注")
+    private String tagRemark;
+
+    /**
+     * 父级ID
+     **/
+    @ApiModelProperty(value = "父级ID")
+    private String parentId;
+
+    /**
+     * 标签规则
+     **/
+    @ApiModelProperty(value = "标签规则")
+    private String reg;
+
+    /**
+     * 标签等级
+     **/
+    @ApiModelProperty(value = "标签等级")
+    private Integer tagLevel;
+
+    /**
+     * tag1/tag2/tag3/...
+     **/
+    @ApiModelProperty(value = "tag1/tag2/tag3/...")
+    private String tagPath;
+
+    /**
+     * 0未删除;1删除
+     **/
+    @ApiModelProperty(value = "0未删除;1删除")
+    private Integer isDelete;
+
+    /**
+     * 0 正常;1 停用
+     **/
+    @ApiModelProperty(value = "0 正常;1 停用")
+    private Integer state;
+
+    /**
+     * 标签提示词
+     **/
+    @ApiModelProperty(value = "标签提示词")
+    private String tagPrompt;
+
+    /**
+     * 标签版本
+     **/
+    @ApiModelProperty(value = "标签版本")
+    private String tagVersion;
+
+    /**
+     * 修订时间
+     **/
+    @ApiModelProperty(value = "修订时间")
+    private String revisionTime;
+
+    /**
+     * 修订人
+     **/
+    @ApiModelProperty(value = "修订人")
+    private String reviser;
+
+
+
+}

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

@@ -126,11 +126,6 @@ passr: true/false
     @ApiModelProperty(value = "打标耗时,秒")
     private String consumingTime;
 
-    /**
-     * 标签类别
-     **/
-    @ApiModelProperty(value = "标签类别")
-    private String categoryCode;
 
     /**
      * 合同编号
@@ -157,4 +152,10 @@ passr: true/false
      **/
     @ApiModelProperty(value = "网点")
     private String feedbackUserEndpoint;
+
+    /**
+     * 标签标识 0正常数据; 1测试数据
+     **/
+    @ApiModelProperty(value = "标签标识 0:正常数据; 1:测试数据")
+    private String tagScope;
 }

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

@@ -0,0 +1,57 @@
+package cn.com.yusys.yusp.domain.entity;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
+import javax.validation.constraints.NotNull;
+
+import java.io.Serializable;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+/**
+* 
+* @TableName aitag_user
+*/
+@Data
+public class AitagUser implements Serializable {
+
+    /**
+    * 主键
+    */
+    @NotBlank(message="[主键]不能为空")
+    @Size(max= 100,message="编码长度不能超过100")
+    @ApiModelProperty("主键")
+    @Length(max= 100,message="编码长度不能超过100")
+    private String id;
+    /**
+    * 登录用的用户ID,具备唯一性
+    */
+    @Size(max= 100,message="编码长度不能超过100")
+    @ApiModelProperty("登录用的用户ID,具备唯一性")
+    @Length(max= 100,message="编码长度不能超过100")
+    private String userId;
+    /**
+    * 登陆密码
+    */
+    @Size(max= 100,message="编码长度不能超过100")
+    @ApiModelProperty("登陆密码")
+    @Length(max= 100,message="编码长度不能超过100")
+    private String pwd;
+    /**
+    * 用户名称
+    */
+    @Size(max= 100,message="编码长度不能超过100")
+    @ApiModelProperty("用户名称")
+    @Length(max= 100,message="编码长度不能超过100")
+    private String userName;
+    /**
+    * 角色权限(0客户经理,1标签管理人员,2业务管理员,3运维管理员,4测试管理员)
+    */
+    @Size(max= 100,message="编码长度不能超过100")
+    @ApiModelProperty("角色权限(0客户经理,1标签管理人员,2业务管理员,3运维管理员,4测试管理员)")
+    @Length(max= 100,message="编码长度不能超过100")
+    private String userRole;
+
+}

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

@@ -1,6 +1,7 @@
 package cn.com.yusys.yusp.domain.vo;
 
 import cn.com.yusys.yusp.commons.module.adapter.query.PageQuery;
+import lombok.Data;
 
 
 /**
@@ -9,6 +10,8 @@ import cn.com.yusys.yusp.commons.module.adapter.query.PageQuery;
  * @author 2507040827
  * @date 2026-02-26 14:34:56
  */
+
+@Data
 public class AitagTagInfoQueryVo extends PageQuery {
 
     /**
@@ -39,7 +42,7 @@ public class AitagTagInfoQueryVo extends PageQuery {
     /**
      * 父级ID
      **/
-    private String parentCode;
+    private String parentId;
 
     /**
      * 标签规则
@@ -49,7 +52,7 @@ public class AitagTagInfoQueryVo extends PageQuery {
     /**
      * 标签等级
      **/
-    private Integer level;
+    private Integer tagLevel;
 
     /**
      * tag1/tag2/tag3/...
@@ -72,100 +75,4 @@ public class AitagTagInfoQueryVo extends PageQuery {
     private String tagPrompt;
 
 
-    public String getId() {
-        return this.id;
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    public String getCategoryId() {
-        return this.categoryId;
-    }
-
-    public void setCategoryId(String categoryId) {
-        this.categoryId = categoryId;
-    }
-
-    public String getTagNm() {
-        return this.tagNm;
-    }
-
-    public void setTagNm(String tagNm) {
-        this.tagNm = tagNm;
-    }
-
-    public String getTagCode() {
-        return this.tagCode;
-    }
-
-    public void setTagCode(String tagCode) {
-        this.tagCode = tagCode;
-    }
-
-    public String getTagRemark() {
-        return this.tagRemark;
-    }
-
-    public void setTagRemark(String tagRemark) {
-        this.tagRemark = tagRemark;
-    }
-
-    public String getParentCode() {
-        return this.parentCode;
-    }
-
-    public void setParentCode(String parentCode) {
-        this.parentCode = parentCode;
-    }
-
-    public String getReg() {
-        return this.reg;
-    }
-
-    public void setReg(String reg) {
-        this.reg = reg;
-    }
-
-    public Integer getLevel() {
-        return this.level;
-    }
-
-    public void setLevel(Integer level) {
-        this.level = level;
-    }
-
-    public String getTagPath() {
-        return this.tagPath;
-    }
-
-    public void setTagPath(String tagPath) {
-        this.tagPath = tagPath;
-    }
-
-    public Integer getIsDelete() {
-        return this.isDelete;
-    }
-
-    public void setIsDelete(Integer isDelete) {
-        this.isDelete = isDelete;
-    }
-
-    public Integer getState() {
-        return this.state;
-    }
-
-    public void setState(Integer state) {
-        this.state = state;
-    }
-
-    public String getTagPrompt() {
-        return this.tagPrompt;
-    }
-
-    public void setTagPrompt(String tagPrompt) {
-        this.tagPrompt = tagPrompt;
-    }
-
 }

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

@@ -0,0 +1,93 @@
+package cn.com.yusys.yusp.domain.vo;
+
+import cn.com.yusys.yusp.commons.module.adapter.query.PageQuery;
+import lombok.Data;
+
+
+/**
+ * 标签信息版本表
+ *
+ * @author 2507040827
+ * @date 2026-02-27 11:33:54
+ */
+
+@Data
+public class AitagTagInfoVersionQueryVo extends PageQuery {
+
+    /**
+     * id
+     **/
+    private String id;
+
+    /**
+     * 所属大类
+     **/
+    private String categoryId;
+
+    /**
+     * 标签名称
+     **/
+    private String tagNm;
+
+    /**
+     * 标签代码
+     **/
+    private String tagCode;
+
+    /**
+     * 标签备注
+     **/
+    private String tagRemark;
+
+    /**
+     * 父级ID
+     **/
+    private String parentId;
+
+    /**
+     * 标签规则
+     **/
+    private String reg;
+
+    /**
+     * 标签等级
+     **/
+    private Integer tagLevel;
+
+    /**
+     * tag1/tag2/tag3/...
+     **/
+    private String tagPath;
+
+    /**
+     * 0未删除;1删除
+     **/
+    private Integer isDelete;
+
+    /**
+     * 0 正常;1 停用
+     **/
+    private Integer state;
+
+    /**
+     * 标签提示词
+     **/
+    private String tagPrompt;
+
+    /**
+     * 标签版本
+     **/
+    private String tagVersion;
+
+    /**
+     * 修订时间
+     **/
+    private String revisionTime;
+
+    /**
+     * 修订人
+     **/
+    private String reviser;
+
+
+}

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

@@ -0,0 +1,23 @@
+package cn.com.yusys.yusp.domain.vo;
+
+
+import lombok.Data;
+
+/**
+ * 生成正则表达式入场
+ */
+
+@Data
+public class GenerateRegexVo {
+
+    /**
+     * 标签名称
+     */
+     private String tag_name;
+
+
+    /**
+     * 标签说明
+     */
+    private String tag_remark;
+}

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

@@ -0,0 +1,41 @@
+package cn.com.yusys.yusp.domain.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 登录响应VO
+ *
+ * @author AI助手
+ * @date 2026-02-27
+ */
+@Data
+@ApiModel("登录响应")
+public class LoginResponseVo {
+
+    @ApiModelProperty("访问令牌")
+    private String token;
+
+    @ApiModelProperty("用户ID")
+    private String userId;
+
+    @ApiModelProperty("用户名称")
+    private String userName;
+
+    @ApiModelProperty("用户角色")
+    private String role;
+
+    @ApiModelProperty("过期时间(毫秒)")
+    private Long expiresIn;
+
+    public static LoginResponseVo success(String token, String userId, String userName, String role, Long expiresIn) {
+        LoginResponseVo response = new LoginResponseVo();
+        response.setToken(token);
+        response.setUserId(userId);
+        response.setUserName(userName);
+        response.setRole(role);
+        response.setExpiresIn(expiresIn);
+        return response;
+    }
+}

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

@@ -2,6 +2,8 @@ package cn.com.yusys.yusp.domain.vo;
 
 
 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;
 
 /**
@@ -28,5 +30,19 @@ public class SmartTaggingResultVo extends PageQuery {
     /**
      * 标签类别
      */
-    private String categoryCode;
+    private String categoryId;
+
+
+    public String getCategoryExp() {
+        return "[{\"category_id\": \""+categoryId+"\"}]";
+    }
+
+    public String getStartTaggingTime() {
+        return StringUtils.isBlank(startTaggingTime)? DateUtils.getCurrYear()+"-01-01 00:00:00":startTaggingTime;
+    }
+
+    public String getEndTaggingTime() {
+        return StringUtils.isBlank(endTaggingTime)? DateUtils.getCurrDateTimeStr():endTaggingTime;
+    }
+
 }

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

@@ -0,0 +1,104 @@
+package cn.com.yusys.yusp.domain.vo;
+
+
+import cn.com.yusys.yusp.domain.entity.AitagTagInfoEntity;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 智能标签数
+ */
+public class TagNodeVo {
+
+
+    /**
+     * 标签Id
+     */
+    private String id;
+
+
+    /**
+     * 父标签Id
+     */
+    private String parentId;
+
+    /**
+     * 标签名称
+     */
+    private String tagNm;
+
+    /**
+     * 标签编码
+     */
+    private String tagCode;
+
+    /**
+     * 标签体系Id
+     */
+    private String categoryId;
+
+    private List<TagNodeVo> children = new ArrayList<>();
+
+
+    public TagNodeVo(AitagTagInfoEntity entity) {
+        this.id = entity.getId();
+        this.parentId = entity.getParentId();
+        this.tagNm = entity.getTagNm();
+        this.tagCode = entity.getTagCode();
+        this.categoryId = entity.getCategoryId();
+    }
+
+    public String getCategoryId() {
+        return categoryId;
+    }
+
+    public void setCategoryId(String categoryId) {
+        this.categoryId = categoryId;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(String parentId) {
+        this.parentId = parentId;
+    }
+
+    public String getTagNm() {
+        return tagNm;
+    }
+
+    public void setTagNm(String tagNm) {
+        this.tagNm = tagNm;
+    }
+
+    public String getTagCode() {
+        return tagCode;
+    }
+
+    public void setTagCode(String tagCode) {
+        this.tagCode = tagCode;
+    }
+
+
+    public List<TagNodeVo> getChildren() {
+        return children;
+    }
+
+    public void setChildren(List<TagNodeVo> children) {
+        this.children = children;
+    }
+
+    public void addChild(TagNodeVo child) {
+        this.children.add(child);
+    }
+}

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

@@ -0,0 +1,35 @@
+package cn.com.yusys.yusp.domain.vo;
+
+
+import lombok.Data;
+
+/**
+ * 版本回溯
+ */
+
+@Data
+public class VersionRollbackVo {
+
+
+
+    /**
+     * 标签主键
+     */
+    private String id;
+
+    /**
+     * 标签代码
+     */
+    private String tagCode;
+
+
+    /**
+     * 要回溯标签版本
+     */
+    private String version;
+
+    /**
+     * 修订人
+     */
+    private String reviser;
+}

+ 53 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/vo/fastapivo/AiTaggingQueryResponseVo.java

@@ -0,0 +1,53 @@
+package cn.com.yusys.yusp.domain.vo.fastapivo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel("AI 打标查询响应")
+public class AiTaggingQueryResponseVo {
+
+    @ApiModelProperty(value = "状态码 200(查询成功)/300(正在处理中)/500(处理失败)")
+    private String code;
+
+    @ApiModelProperty(value = "消息内容")
+    private String message;
+
+    @ApiModelProperty(value = "标签数据")
+    private AiTagDataWrapper data;
+
+    @Data
+    @ApiModel("标签数据包装")
+    public static class AiTagDataWrapper {
+
+        @ApiModelProperty(value = "标签结果列表")
+        private AiTagResultVo[] result;
+    }
+
+    @Data
+    @ApiModel("标签结果")
+    public static class AiTagResultVo {
+
+        @ApiModelProperty(value = "标签 ID")
+        private String id;
+
+        @ApiModelProperty(value = "标签名称")
+        private String tag_name;
+
+        @ApiModelProperty(value = "标签代码")
+        private String tag_code;
+
+        @ApiModelProperty(value = "标签路径")
+        private String tag_path;
+
+        @ApiModelProperty(value = "是否 AI 推荐 true: AI 推荐的标签,false: 算法筛选出来但是被 LLM 淘汰的候选标签")
+        private Boolean passr;
+
+        @ApiModelProperty(value = "解释说明")
+        private String desc;
+
+        @ApiModelProperty(value = "分类 ID")
+        private String category_id;
+    }
+}

+ 20 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/vo/fastapivo/AiTaggingResponseVo.java

@@ -0,0 +1,20 @@
+package cn.com.yusys.yusp.domain.vo.fastapivo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel("AI打标响应")
+public class AiTaggingResponseVo {
+
+    @ApiModelProperty(value = "状态码 200/500")
+    private String code;
+
+    @ApiModelProperty(value = "消息内容")
+    private String message;
+
+    @ApiModelProperty(value = "返回数据")
+    private String data;
+
+}

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

@@ -12,6 +12,15 @@ public interface AitagTagCategoryMapper {
     // 分页查询(偏移量 + 限制)
     List<AitagTagCategory> selectPageCategories(@Param("offset") int offset, @Param("limit") int limit);
 
+    // 带模糊筛选的分页查询
+    List<AitagTagCategory> selectPageCategoriesWithFilter(
+            @Param("categoryNm") String categoryNm,
+            @Param("offset") int offset,
+            @Param("limit") int limit);
+
+    // 带模糊筛选的总数
+    long selectCountWithFilter(@Param("categoryNm") String categoryNm);
+
     // 模糊查询(按名称)
     List<AitagTagCategory> selectByCategoryNmLike(@Param("categoryNm") String categoryNm);
 
@@ -38,4 +47,18 @@ public interface AitagTagCategoryMapper {
 
     // 全表计数(分页总数)
     long selectCountAll();
+
+    // 分页查询已启用的标签体系
+    List<AitagTagCategory> selectPageEnabledCategories(@Param("offset") int offset, @Param("limit") int limit);
+
+    // 统计已启用标签体系的数量
+    long selectCountEnabled();
+
+    /**
+     * 根据ID查询标签体系详情(包含标签数量)
+     * @param id 标签体系ID
+     * @return 标签体系实体
+     */
+    AitagTagCategory selectDetailById(@Param("id") String id);
+
 }

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

@@ -1,8 +1,12 @@
 package cn.com.yusys.yusp.mapper;
 
 import cn.com.yusys.yusp.commons.mybatisplus.mapper.BaseMapper;
+import cn.com.yusys.yusp.domain.dto.TagInfoDto;
 import cn.com.yusys.yusp.domain.entity.AitagTagInfoEntity;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 /**
  * 
@@ -14,4 +18,7 @@ import org.apache.ibatis.annotations.Mapper;
 @Mapper
 public interface AitagTagInfoDao extends BaseMapper<AitagTagInfoEntity> {
 
+
+   TagInfoDto selectTagInfo(@Param("id") String id);
+
 }

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

@@ -0,0 +1,17 @@
+package cn.com.yusys.yusp.mapper;
+
+import cn.com.yusys.yusp.commons.mybatisplus.mapper.BaseMapper;
+import cn.com.yusys.yusp.domain.entity.AitagTagInfoVersionEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 标签信息版本表
+ *
+ * @author 2507040827
+ * @date 2026-02-27 11:33:54
+ */
+
+@Mapper
+public interface AitagTagInfoVersionDao extends BaseMapper<AitagTagInfoVersionEntity> {
+
+}

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

@@ -0,0 +1,23 @@
+package cn.com.yusys.yusp.mapper;
+
+import cn.com.yusys.yusp.domain.entity.AitagUser;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+/**
+ * 用户Mapper接口
+ *
+ * @author AI助手
+ * @date 2026-02-27
+ */
+public interface AitagUserMapper extends BaseMapper<AitagUser> {
+
+    /**
+     * 根据用户ID查询用户
+     *
+     * @param userId 用户ID
+     * @return 用户信息
+     */
+    AitagUser selectByUserId(@Param("userId") String userId);
+}

+ 9 - 2
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/AitagTagCategoryService.java

@@ -9,11 +9,18 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import java.util.List;
 
 public interface AitagTagCategoryService {
-    Page<AitagTagCategoryVo> listCategories(int page, int size); // ← 改为 VO
+    Page<AitagTagCategoryVo> listCategories(String categoryNm, int page, int size);
     AitagTagCategory createCategory(AitagTagCategoryCreateDto dto);
     AitagTagCategory updateCategory(AitagTagCategoryUpdateDto dto);
-    List<AitagTagCategory> searchByCategoryNm(String categoryNm);
     void enableCategory(String id);
     void disableCategory(String id);
     void deleteCategory(String id);
+    // 分页查询已启用的标签体系
+    Page<AitagTagCategoryVo> listEnabledCategories(int page, int size);
+    /**
+     * 根据ID查询标签体系详情
+     * @param id 标签体系ID
+     * @return 标签体系详情VO
+     */
+    AitagTagCategoryVo getCategoryDetail(String id);
 }

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

@@ -1,9 +1,19 @@
 package cn.com.yusys.yusp.service;
 
+import cn.com.yusys.yusp.domain.dto.TagInfoDto;
 import cn.com.yusys.yusp.domain.entity.AitagTagInfoEntity;
 import cn.com.yusys.yusp.domain.vo.AitagTagInfoQueryVo;
+import cn.com.yusys.yusp.domain.vo.GenerateRegexVo;
+import cn.com.yusys.yusp.domain.vo.TagNodeVo;
+import cn.com.yusys.yusp.domain.vo.VersionRollbackVo;
+import cn.com.yusys.yusp.domain.vo.fastapivo.AiTaggingResponseVo;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
 
 /**
  * 
@@ -21,5 +31,24 @@ public interface AitagTagInfoService extends IService<AitagTagInfoEntity> {
      * @return IPage
      */
     IPage<AitagTagInfoEntity> queryPage(AitagTagInfoQueryVo aitagTagInfoQueryVo);
+
+    String saveTag(AitagTagInfoEntity aitagTagInfo);
+
+    List<TagNodeVo> queryTagTree(AitagTagInfoQueryVo aitagTagInfoQueryVo);
+
+    TagInfoDto getTagInfo(String id);
+
+    void updateTag(AitagTagInfoEntity aitagTagInfoEntity);
+
+    void removeTags(List<String> list);
+
+    String versionRollback(VersionRollbackVo versionRollbackVo);
+
+    List<AitagTagInfoEntity> queryList(AitagTagInfoQueryVo aitagTagInfoQueryVo);
+
+    List<String> batchImport(MultipartFile file, String reviser, String categoryId) throws IOException;
+
+
+    AiTaggingResponseVo callAiTag(Map<String, Object> body, String path);
 }
 

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

@@ -0,0 +1,25 @@
+package cn.com.yusys.yusp.service;
+
+import cn.com.yusys.yusp.domain.entity.AitagTagInfoVersionEntity;
+import cn.com.yusys.yusp.domain.vo.AitagTagInfoVersionQueryVo;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * 标签信息版本表
+ *
+ * @author 2507040827
+ * @date 2026-02-27 11:33:54
+ */
+
+public interface AitagTagInfoVersionService extends IService<AitagTagInfoVersionEntity> {
+
+    /**
+     * 分页查询
+     *
+     * @param aitagTagInfoVersionQueryVo
+     * @return IPage
+     */
+    IPage<AitagTagInfoVersionEntity> queryPage(AitagTagInfoVersionQueryVo aitagTagInfoVersionQueryVo);
+}
+

+ 7 - 1
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/AitagTagLogService.java

@@ -26,6 +26,12 @@ public interface AitagTagLogService extends IService<AitagTagLogEntity> {
 
     List<IconResVo> tagDistStats(TagDistStatsReqVo resultDTO);
 
-    List<AitagTagLogEntity> queryList(TaggingTransactionReqVo transactionReqVo);
+
+    /**
+     * 查询确认后的标签数据
+     * @param transactionReqVo
+     * @return 有效的标签数据
+     */
+    List<AitagTagLogEntity> queryConfirmedTagData(TaggingTransactionReqVo transactionReqVo);
 }
 

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

@@ -0,0 +1,46 @@
+package cn.com.yusys.yusp.service;
+
+import cn.com.yusys.yusp.domain.dto.LoginRequestDto;
+import cn.com.yusys.yusp.domain.entity.AitagUser;
+import cn.com.yusys.yusp.domain.vo.LoginResponseVo;
+
+/**
+ * 认证服务接口
+ *
+ * @author AI助手
+ * @date 2026-02-27
+ */
+public interface AuthService {
+
+    /**
+     * 用户登录
+     *
+     * @param loginRequest 登录请求
+     * @return 登录响应
+     */
+    LoginResponseVo login(LoginRequestDto loginRequest);
+
+    /**
+     * 用户登出
+     *
+     * @param userId 用户ID
+     */
+    void logout(String userId);
+
+    /**
+     * 根据用户ID获取用户信息
+     *
+     * @param userId 用户ID
+     * @return 用户信息
+     */
+    AitagUser getUserById(String userId);
+
+    /**
+     * 验证用户密码
+     *
+     * @param userId 用户ID
+     * @param password 密码
+     * @return 是否验证通过
+     */
+    boolean validatePassword(String userId, String password);
+}

+ 25 - 17
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/DistributedScheduledTask.java

@@ -6,6 +6,7 @@ import cn.com.yusys.yusp.domain.entity.AitagTagDailyAggEntity;
 import cn.com.yusys.yusp.domain.entity.AitagTagLogEntity;
 import cn.com.yusys.yusp.mapper.AitagTagDailyAggDao;
 import cn.com.yusys.yusp.mapper.AitagTagLogDao;
+import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import lombok.extern.slf4j.Slf4j;
@@ -23,14 +24,13 @@ import java.util.UUID;
 import java.util.concurrent.TimeUnit;
 
 import static cn.com.yusys.yusp.config.DataDictionary.FEEDBACK_RESULT_AGREE;
+import static cn.com.yusys.yusp.config.DataDictionary.FEEDBACK_RESULT_REJECT;
 
 @Component
 @Slf4j
 public class DistributedScheduledTask {
 
 
-    private static final String TASK_LOCK_KEY = "scheduled_task:sync_data";
-
 
     @Autowired
     private StringRedisTemplate redisTemplate;
@@ -75,14 +75,16 @@ public class DistributedScheduledTask {
             Map<String,Integer> count = new HashMap<>();
             for (AitagTagLogEntity aitagTagLog:aitagTagLogEntities){
                 String feedback = aitagTagLog.getFeedback();
-                String categoryCode = aitagTagLog.getCategoryCode();
-                if(FEEDBACK_RESULT_AGREE.equals(feedback)){
-                    String result = aitagTagLog.getResult();
-                    duCount(result, count,categoryCode);
+                String result = null;
+                if(FEEDBACK_RESULT_REJECT.equals(feedback)){
+                    result = aitagTagLog.getFeedbackResult();
                 }else{
-                    String result = aitagTagLog.getFeedbackResult();
-                    duCount(result, count,categoryCode);
+                    result = aitagTagLog.getResult();
+                }
+                if(StringUtils.isBlank(result)){
+                    continue;
                 }
+                duCount(result, count);
             }
             AitagTagDailyAggEntity aitagTagLog = new AitagTagDailyAggEntity();
             for (String key : count.keySet()){
@@ -90,22 +92,28 @@ public class DistributedScheduledTask {
                 aitagTagLog.setAggDate(yesterday);
                 aitagTagLog.setTagCount(count.get(key));
                 String[] split = key.split(":");
+                if(split.length==2){
+                    aitagTagLog.setCategoryId(split[1]);
+                }
                 aitagTagLog.setTagNm(split[0]);
-                aitagTagLog.setCategoryCode(split[1]);
                 aitagTagDailyAggDao.insert(aitagTagLog);
             }
 
         }
     }
 
-    private static void duCount(String result, Map<String, Integer> count,String categoryCode) {
-        JSONObject resultMap = JSONObject.parseObject(result);
-        String labe = resultMap.getString("labe")+":"+categoryCode;
-        if(count.containsKey(labe)){
-            Integer integer = count.get(labe);
-            count.put(labe,integer+1);
-        }else{
-            count.put(labe,1);
+    private static void duCount(String result, Map<String, Integer> count) {
+        List<Map> results = JSONArray.parseArray(result, Map.class);
+        for (int i = 0 ;i<results.size();i++){
+            Map resultMap = results.get(i);
+            String labe = resultMap.getOrDefault("tag_name","").toString()+":"
+                    + resultMap.getOrDefault("category_id","").toString();
+            if(count.containsKey(labe)){
+                Integer integer = count.get(labe);
+                count.put(labe,integer+1);
+            }else{
+                count.put(labe,1);
+            }
         }
     }
 

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

@@ -0,0 +1,31 @@
+package cn.com.yusys.yusp.service;
+
+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.fastapivo.AiTaggingQueryResponseVo;
+import cn.com.yusys.yusp.domain.vo.fastapivo.AiTaggingResponseVo;
+
+public interface FastApiService {
+
+    /**
+     * AI打标接口
+     * @param request 打标请求
+     * @return 响应结果
+     */
+    AiTaggingResponseVo tagging(AiTaggingRequestDto request);
+
+    /**
+     * AI打标查询接口
+     * @param request 查询请求
+     * @return 查询结果
+     */
+    AiTaggingQueryResponseVo query(AiTaggingQueryRequestDto request);
+
+    /**
+     * AI打标反馈接口
+     * @param request 反馈请求
+     * @return 响应结果
+     */
+    AiTaggingResponseVo feedback(AiTaggingFeedbackRequestDto request);
+}

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

@@ -0,0 +1,44 @@
+package cn.com.yusys.yusp.service;
+
+import cn.com.yusys.yusp.commons.util.StringUtils;
+import cn.com.yusys.yusp.domain.dto.TagImportDto;
+import cn.com.yusys.yusp.mapper.AitagTagInfoDao;
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+
+
+@Slf4j
+public class TagImportListener extends AnalysisEventListener<TagImportDto> {
+    private final List<TagImportDto> dataList = new ArrayList<>();
+
+
+    @Override
+    public void invoke(TagImportDto data, AnalysisContext context) {
+        // 数据清洗
+        if (StringUtils.isBlank(data.getTagNm())) {
+            return;
+        }
+        data.setTagNm(data.getTagNm().trim());
+        if (!StringUtils.isBlank(data.getParentName())) {
+            data.setParentName(data.getParentName().trim());
+        }
+        // 生成临时 ID
+        data.setId(UUID.randomUUID().toString().replace("-", ""));
+        dataList.add(data);
+    }
+
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext context) {
+        // 解析完成后自动调用 processData,或者在外部调用
+    }
+    public List<TagImportDto> getDataList() {
+        return dataList;
+    }
+
+}

+ 57 - 8
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/impl/AitagTagCategoryServiceImpl.java

@@ -21,10 +21,10 @@ public class AitagTagCategoryServiceImpl implements AitagTagCategoryService {
     private AitagTagCategoryMapper aiTagCategoryMapper;
 
     @Override
-    public Page<AitagTagCategoryVo> listCategories(int page, int size) {
+    public Page<AitagTagCategoryVo> listCategories(String categoryNm, int page, int size) {
         int offset = (page - 1) * size;
-        List<AitagTagCategory> records = aiTagCategoryMapper.selectPageCategories(offset, size);
-        long total = aiTagCategoryMapper.selectCountAll();
+        List<AitagTagCategory> records = aiTagCategoryMapper.selectPageCategoriesWithFilter(categoryNm, offset, size);
+        long total = aiTagCategoryMapper.selectCountWithFilter(categoryNm);
 
         // 转换为 VO 并动态计算 tagNum
         List<AitagTagCategoryVo> voList = records.stream().map(category -> {
@@ -61,7 +61,7 @@ public class AitagTagCategoryServiceImpl implements AitagTagCategoryService {
         category.setId(UUID.randomUUID().toString());
         category.setCategoryNm(dto.getCategoryNm());
         category.setCategoryDesc(dto.getCategoryDesc());
-        category.setState(0); // 默认启
+        category.setState(1); // 默认停
         category.setIsDelete(0); // 未删除
 
         aiTagCategoryMapper.insertCategory(category);
@@ -89,10 +89,7 @@ public class AitagTagCategoryServiceImpl implements AitagTagCategoryService {
         return existing;
     }
 
-    @Override
-    public List<AitagTagCategory> searchByCategoryNm(String categoryNm) {
-        return aiTagCategoryMapper.selectByCategoryNmLike(categoryNm);
-    }
+
 
     @Override
     public void enableCategory(String id) {
@@ -145,4 +142,56 @@ public class AitagTagCategoryServiceImpl implements AitagTagCategoryService {
 
         aiTagCategoryMapper.deleteCategory(id);
     }
+
+    @Override
+    public Page<AitagTagCategoryVo> listEnabledCategories(int page, int size) {
+        int offset = (page - 1) * size;
+        List<AitagTagCategory> records = aiTagCategoryMapper.selectPageEnabledCategories(offset, size);
+        long total = aiTagCategoryMapper.selectCountEnabled();
+
+        // 转换为 VO 并动态计算 tagNum
+        List<AitagTagCategoryVo> voList = records.stream().map(category -> {
+            AitagTagCategoryVo vo = new AitagTagCategoryVo();
+            vo.setId(category.getId());
+            vo.setCategoryCode(category.getCategoryCode());
+            vo.setCategoryNm(category.getCategoryNm());
+            vo.setCategoryDesc(category.getCategoryDesc());
+            vo.setVisibilityLevel(category.getVisibilityLevel());
+            vo.setState(category.getState());
+            vo.setIsDelete(category.getIsDelete());
+
+            // 动态计算 tagNum
+            int tagNum = aiTagCategoryMapper.countTagsByCategoryId(category.getId());
+            vo.setTagNum(tagNum);
+
+            return vo;
+        }).collect(Collectors.toList());
+
+        Page<AitagTagCategoryVo> pageObj = new Page<>(page, size, total);
+        pageObj.setRecords(voList);
+        return pageObj;
+    }
+
+    @Override
+    public AitagTagCategoryVo getCategoryDetail(String id) {
+        AitagTagCategory category = aiTagCategoryMapper.selectDetailById(id);
+        if (category == null) {
+            throw new RuntimeException("标签体系不存在");
+        }
+
+        AitagTagCategoryVo vo = new AitagTagCategoryVo();
+        vo.setId(category.getId());
+        vo.setCategoryCode(category.getCategoryCode());
+        vo.setCategoryNm(category.getCategoryNm());
+        vo.setCategoryDesc(category.getCategoryDesc());
+        vo.setVisibilityLevel(category.getVisibilityLevel());
+        vo.setState(category.getState());
+        vo.setIsDelete(category.getIsDelete());
+
+        // 计算标签数量
+        int tagNum = aiTagCategoryMapper.countTagsByCategoryId(category.getId());
+        vo.setTagNum(tagNum);
+
+        return vo;
+    }
 }

+ 384 - 5
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/impl/AitagTagInfoServiceImpl.java

@@ -1,14 +1,51 @@
 package cn.com.yusys.yusp.service.impl;
 
+import cn.com.yusys.yusp.commons.exception.BizException;
+import cn.com.yusys.yusp.commons.util.StringUtils;
+import cn.com.yusys.yusp.commons.util.date.DateUtils;
+import cn.com.yusys.yusp.config.FastApiConfig;
+import cn.com.yusys.yusp.domain.dto.TagImportDto;
+import cn.com.yusys.yusp.domain.entity.AitagTagCategory;
+import cn.com.yusys.yusp.domain.vo.GenerateRegexVo;
+import cn.com.yusys.yusp.domain.vo.VersionRollbackVo;
+import cn.com.yusys.yusp.domain.vo.fastapivo.AiTaggingResponseVo;
+import cn.com.yusys.yusp.mapper.AitagTagCategoryMapper;
+import cn.com.yusys.yusp.mapper.AitagTagInfoVersionDao;
+import cn.com.yusys.yusp.domain.dto.TagInfoDto;
+import cn.com.yusys.yusp.domain.entity.AitagTagInfoVersionEntity;
+import cn.com.yusys.yusp.domain.vo.TagNodeVo;
 import cn.com.yusys.yusp.mapper.AitagTagInfoDao;
 import cn.com.yusys.yusp.domain.entity.AitagTagInfoEntity;
 import cn.com.yusys.yusp.domain.vo.AitagTagInfoQueryVo;
 import cn.com.yusys.yusp.service.AitagTagInfoService;
+import cn.com.yusys.yusp.service.TagImportListener;
+import cn.com.yusys.yusp.util.SessionCommonUtil;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static cn.com.yusys.yusp.config.DataDictionary.*;
 
 /**
  * 
@@ -18,8 +55,19 @@ import org.springframework.stereotype.Service;
  */
 
 @Service("aitagTagInfoService")
+@Slf4j
 public class AitagTagInfoServiceImpl extends ServiceImpl<AitagTagInfoDao, AitagTagInfoEntity> implements AitagTagInfoService {
 
+
+    @Autowired
+    private AitagTagInfoVersionDao aitagTagInfoVersionDao;
+
+    @Autowired
+    private AitagTagCategoryMapper aiTagCategoryMapper;
+
+    @Autowired
+    private FastApiConfig fastApiConfig;
+
     /**
      * 分页查询
      *
@@ -44,14 +92,14 @@ public class AitagTagInfoServiceImpl extends ServiceImpl<AitagTagInfoDao, AitagT
         if (aitagTagInfoQueryVo.getTagRemark() != null) {
             queryWrapper.eq(AitagTagInfoEntity::getTagRemark, aitagTagInfoQueryVo.getTagRemark());
         }
-        if (aitagTagInfoQueryVo.getParentCode() != null) {
-            queryWrapper.eq(AitagTagInfoEntity::getParentCode, aitagTagInfoQueryVo.getParentCode());
+        if (aitagTagInfoQueryVo.getParentId() != null) {
+            queryWrapper.eq(AitagTagInfoEntity::getParentId, aitagTagInfoQueryVo.getParentId());
         }
         if (aitagTagInfoQueryVo.getReg() != null) {
             queryWrapper.eq(AitagTagInfoEntity::getReg, aitagTagInfoQueryVo.getReg());
         }
-        if (aitagTagInfoQueryVo.getLevel() != null) {
-            queryWrapper.eq(AitagTagInfoEntity::getLevel, aitagTagInfoQueryVo.getLevel());
+        if (aitagTagInfoQueryVo.getTagLevel() != null) {
+            queryWrapper.eq(AitagTagInfoEntity::getTagLevel, aitagTagInfoQueryVo.getTagLevel());
         }
         if (aitagTagInfoQueryVo.getTagPath() != null) {
             queryWrapper.eq(AitagTagInfoEntity::getTagPath, aitagTagInfoQueryVo.getTagPath());
@@ -69,4 +117,335 @@ public class AitagTagInfoServiceImpl extends ServiceImpl<AitagTagInfoDao, AitagT
         IPage<AitagTagInfoEntity> page = this.page(new Page<>(aitagTagInfoQueryVo.getPage(), aitagTagInfoQueryVo.getSize()), queryWrapper);
         return page;
     }
-}
+
+
+    @Override
+    public String saveTag(AitagTagInfoEntity aitagTagInfo){
+        aitagTagInfo.setId(StringUtils.getUUID());
+        String parentId = aitagTagInfo.getParentId();
+        if(!StringUtils.isBlank(parentId)){
+            LambdaQueryWrapper<AitagTagInfoEntity> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AitagTagInfoEntity::getParentId,parentId);
+            queryWrapper.eq(AitagTagInfoEntity::getIsDelete,TAG_UNDELETED);
+            List<AitagTagInfoEntity> aitagTagInfoEntities = this.baseMapper.selectList(queryWrapper);
+            if(!aitagTagInfoEntities.isEmpty()){
+                AitagTagInfoEntity aitagTagInfoEntity = aitagTagInfoEntities.get(0);
+                aitagTagInfo.setTagPath(aitagTagInfoEntity.getTagPath()+"/"+aitagTagInfo.getTagNm());
+                aitagTagInfo.setTagLevel(aitagTagInfoEntity.getTagLevel()+1);
+            }else{
+                aitagTagInfo.setTagPath(aitagTagInfo.getTagNm());
+                aitagTagInfo.setTagLevel(1);
+            }
+        }else{
+            aitagTagInfo.setTagPath(aitagTagInfo.getTagNm());
+            aitagTagInfo.setTagLevel(1);
+        }
+        aitagTagInfo.setRevisionTime(DateUtils.getCurrDateTimeStr());
+        aitagTagInfo.setTagVersion("1");
+        aitagTagInfo.setIsDelete(TAG_UNDELETED);
+        aitagTagInfo.setState(TAG_ENABLED);
+        aitagTagInfo.setReviser(SessionCommonUtil.getUserInfo());
+        this.save(aitagTagInfo);
+        return aitagTagInfo.getId();
+    }
+
+    /**
+     * 列表查询
+     *
+     * @param aitagTagInfoQueryVo
+     * @return List<TagNodeVo>
+     */
+    @Override
+    public List<TagNodeVo> queryTagTree(AitagTagInfoQueryVo aitagTagInfoQueryVo) {
+        LambdaQueryWrapper<AitagTagInfoEntity> queryWrapper = new LambdaQueryWrapper<>();
+        if (aitagTagInfoQueryVo.getId() != null) {
+            queryWrapper.eq(AitagTagInfoEntity::getId, aitagTagInfoQueryVo.getId());
+        }
+        queryWrapper.eq(AitagTagInfoEntity::getCategoryId, aitagTagInfoQueryVo.getCategoryId());
+        if (aitagTagInfoQueryVo.getTagNm() != null) {
+            queryWrapper.like(AitagTagInfoEntity::getTagNm, aitagTagInfoQueryVo.getTagNm());
+        }
+        queryWrapper.eq(AitagTagInfoEntity::getIsDelete, TAG_UNDELETED);
+        List<AitagTagInfoEntity> aitagTagInfoEntities = this.baseMapper.selectList(queryWrapper);
+        return this.buildTree(aitagTagInfoEntities);
+    }
+
+    @Override
+    public TagInfoDto getTagInfo(String id) {
+        return this.baseMapper.selectTagInfo(id);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateTag(AitagTagInfoEntity aitagTagInfoEntity) {
+        AitagTagInfoEntity tagInfo = this.baseMapper.selectById(aitagTagInfoEntity.getId());
+        AitagTagInfoVersionEntity aitagTagInfoVersionEntity = JSON.parseObject(JSON.toJSONString(tagInfo), AitagTagInfoVersionEntity.class);
+        aitagTagInfoVersionEntity.setId(StringUtils.getUUID());
+        this.aitagTagInfoVersionDao.insert(aitagTagInfoVersionEntity);
+        aitagTagInfoEntity.setRevisionTime(DateUtils.getCurrDateTimeStr());
+        aitagTagInfoEntity.setTagVersion(Integer.parseInt(tagInfo.getTagVersion())+1+"");
+        AitagTagInfoEntity parentTagInfo = this.baseMapper.selectById(aitagTagInfoEntity.getParentId());
+        aitagTagInfoEntity.setTagPath(parentTagInfo.getTagPath()+"/"+aitagTagInfoEntity.getTagNm());
+        aitagTagInfoEntity.setTagLevel(parentTagInfo.getTagLevel()+1);
+        aitagTagInfoEntity.setReviser(SessionCommonUtil.getUserInfo());
+        this.baseMapper.updateById(aitagTagInfoEntity);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void removeTags(List<String> list) {
+        AitagTagInfoEntity aitagTagInfoEntity = new AitagTagInfoEntity();
+        for (String id:list){
+            aitagTagInfoEntity.setId(id);
+            aitagTagInfoEntity.setIsDelete(TAG_DELETED);
+            aitagTagInfoEntity.setReviser(SessionCommonUtil.getUserInfo());
+            this.baseMapper.updateById(aitagTagInfoEntity);
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public String versionRollback(VersionRollbackVo versionRollback) {
+        LambdaQueryWrapper<AitagTagInfoVersionEntity> queryTagVersionWrapper = new LambdaQueryWrapper<>();
+        queryTagVersionWrapper.eq(AitagTagInfoVersionEntity::getTagCode,versionRollback.getTagCode());
+        queryTagVersionWrapper.eq(AitagTagInfoVersionEntity::getTagVersion,versionRollback.getVersion());
+        List<AitagTagInfoVersionEntity> versionEntities = this.aitagTagInfoVersionDao.selectList(queryTagVersionWrapper);
+        if(versionEntities !=null && !versionEntities.isEmpty()){
+            AitagTagInfoVersionEntity tagInfoVersion = versionEntities.get(0);
+            AitagTagInfoEntity aitagTagInfoEntity = JSON.parseObject(JSONObject.toJSONString(tagInfoVersion), AitagTagInfoEntity.class);
+            aitagTagInfoEntity.setId(versionRollback.getId());
+            aitagTagInfoEntity.setRevisionTime(DateUtils.getCurrDateTimeStr());
+            aitagTagInfoEntity.setReviser(versionRollback.getReviser());
+            aitagTagInfoEntity.setReviser(SessionCommonUtil.getUserInfo());
+            this.baseMapper.updateById(aitagTagInfoEntity);
+            LambdaUpdateWrapper<AitagTagInfoVersionEntity> updateTagVersion = new LambdaUpdateWrapper<>();
+            updateTagVersion.eq(AitagTagInfoVersionEntity::getTagCode,versionRollback.getTagCode());
+            updateTagVersion.ge(AitagTagInfoVersionEntity::getTagVersion,versionRollback.getVersion());
+            AitagTagInfoVersionEntity aitagTagInfoVersionEntity = new AitagTagInfoVersionEntity();
+            aitagTagInfoVersionEntity.setReviser(SessionCommonUtil.getUserInfo());
+            aitagTagInfoVersionEntity.setIsDelete(TAG_DELETED);
+            this.aitagTagInfoVersionDao.update(aitagTagInfoVersionEntity,updateTagVersion);
+            return aitagTagInfoEntity.getId();
+        }
+        return null;
+    }
+
+    @Override
+    public List<AitagTagInfoEntity> queryList(AitagTagInfoQueryVo aitagTagInfoQueryVo) {
+        LambdaQueryWrapper<AitagTagInfoEntity> queryWrapper = new LambdaQueryWrapper<>();
+        if (aitagTagInfoQueryVo.getId() != null) {
+            queryWrapper.eq(AitagTagInfoEntity::getId, aitagTagInfoQueryVo.getId());
+        }
+        if (aitagTagInfoQueryVo.getCategoryId() != null) {
+            queryWrapper.eq(AitagTagInfoEntity::getCategoryId, aitagTagInfoQueryVo.getCategoryId());
+        }
+        if (aitagTagInfoQueryVo.getTagNm() != null) {
+            queryWrapper.eq(AitagTagInfoEntity::getTagNm, aitagTagInfoQueryVo.getTagNm());
+        }
+        if (aitagTagInfoQueryVo.getTagCode() != null) {
+            queryWrapper.eq(AitagTagInfoEntity::getTagCode, aitagTagInfoQueryVo.getTagCode());
+        }
+        if (aitagTagInfoQueryVo.getTagRemark() != null) {
+            queryWrapper.eq(AitagTagInfoEntity::getTagRemark, aitagTagInfoQueryVo.getTagRemark());
+        }
+        if (aitagTagInfoQueryVo.getParentId() != null) {
+            queryWrapper.eq(AitagTagInfoEntity::getParentId, aitagTagInfoQueryVo.getParentId());
+        }
+        if (aitagTagInfoQueryVo.getReg() != null) {
+            queryWrapper.eq(AitagTagInfoEntity::getReg, aitagTagInfoQueryVo.getReg());
+        }
+        if (aitagTagInfoQueryVo.getTagLevel() != null) {
+            queryWrapper.eq(AitagTagInfoEntity::getTagLevel, aitagTagInfoQueryVo.getTagLevel());
+        }
+        if (aitagTagInfoQueryVo.getTagPath() != null) {
+            queryWrapper.eq(AitagTagInfoEntity::getTagPath, aitagTagInfoQueryVo.getTagPath());
+        }
+        if (aitagTagInfoQueryVo.getIsDelete() != null) {
+            queryWrapper.eq(AitagTagInfoEntity::getIsDelete, aitagTagInfoQueryVo.getIsDelete());
+        }
+        if (aitagTagInfoQueryVo.getState() != null) {
+            queryWrapper.eq(AitagTagInfoEntity::getState, aitagTagInfoQueryVo.getState());
+        }
+        if (aitagTagInfoQueryVo.getTagPrompt() != null) {
+            queryWrapper.eq(AitagTagInfoEntity::getTagPrompt, aitagTagInfoQueryVo.getTagPrompt());
+        }
+        queryWrapper.select(AitagTagInfoEntity::getId,AitagTagInfoEntity::getTagNm,AitagTagInfoEntity::getParentId);
+        return this.baseMapper.selectList(queryWrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public List<String> batchImport(MultipartFile file, String reviser, String categoryId) throws IOException {
+        log.info("开始处理上传文件:{}", file.getOriginalFilename());
+
+        TagImportListener listener = new TagImportListener();
+        EasyExcel.read(file.getInputStream(), TagImportDto.class, listener)
+                .headRowNumber(1)
+                .sheet(1)
+                .doRead();
+        List<TagImportDto> tagImportDtos = listener.getDataList();
+        if (tagImportDtos.isEmpty()) {
+            throw BizException.of("E004");
+        }
+
+        Map<String, TagImportDto> nameToDtoMap  = new HashMap<>();
+        for (TagImportDto d : tagImportDtos) {
+            if (nameToDtoMap.containsKey(d.getTagNm())) {
+                throw BizException.of("E005",d.getTagNm());
+            }
+            nameToDtoMap.put(d.getTagNm(), d);
+        }
+
+        validateParentTags(nameToDtoMap);
+        resolveHierarchy(nameToDtoMap);
+        saveToDatabase(tagImportDtos,reviser,categoryId);
+        return  tagImportDtos.stream().map(TagImportDto::getId).collect(Collectors.toList());
+    }
+
+
+    private void saveToDatabase(List<TagImportDto> tagImportDtos,String reviser,String categoryId) {
+        AitagTagCategory aitagTagCategory = aiTagCategoryMapper.selectById(categoryId);
+        String categoryNm = aitagTagCategory.getCategoryNm();
+        for (TagImportDto tagImportDto: tagImportDtos){
+            AitagTagInfoEntity aitagTagInfo = JSONObject.parseObject(JSONObject.toJSONString(tagImportDto),
+                    AitagTagInfoEntity.class);
+            String tagPath = tagImportDto.getTagPath();
+            aitagTagInfo.setTagPath(categoryNm+"/"+tagPath);
+            aitagTagInfo.setTagLevel(aitagTagInfo.getTagPath().split("/").length);
+            aitagTagInfo.setRevisionTime(DateUtils.getCurrDateTimeStr());
+            aitagTagInfo.setReviser(reviser);
+            aitagTagInfo.setTagVersion("1");
+            aitagTagInfo.setIsDelete(TAG_UNDELETED);
+            aitagTagInfo.setCategoryId(categoryId);
+            aitagTagInfo.setState(TAG_ENABLED);
+            aitagTagInfo.setReviser(SessionCommonUtil.getUserInfo());
+            this.save(aitagTagInfo);
+        }
+
+    }
+
+    /**
+     * 校验父标签存在性并将赋值parentId
+     * @param nameToDtoMap
+     */
+    private void validateParentTags(Map<String, TagImportDto> nameToDtoMap) {
+        Set<String> validNames = nameToDtoMap.keySet();
+        for (TagImportDto d : nameToDtoMap.values()) {
+            if (!StringUtils.isBlank(d.getParentName())) {
+                if(!validNames.contains(d.getParentName())){
+                    throw BizException.of("E006",d.getTagNm(),d.getParentName());
+                }else{
+                    d.setParentId(nameToDtoMap.get(d.getParentName()).getId());
+                }
+
+            }
+        }
+    }
+
+
+    /**
+     * 构建path路径
+     * @param nameToDtoMap
+     */
+    private void resolveHierarchy(Map<String, TagImportDto> nameToDtoMap) {
+        for (TagImportDto current : nameToDtoMap.values()) {
+            current.setTagPath(buildFullPath(current, new HashSet<>(),nameToDtoMap));
+        }
+    }
+
+    private String buildFullPath(TagImportDto current, Set<String> visited,Map<String, TagImportDto> nameToDtoMap) {
+        if (current == null) {
+            return "";
+        }
+        if (visited.contains(current.getTagNm())) {
+            throw BizException.of("E007",  String.join("->", visited) + "->" + current.getTagNm());
+        }
+        visited.add(current.getTagNm());
+
+        StringBuilder path = new StringBuilder();
+        if (current.getParentName() != null && nameToDtoMap.containsKey(current.getParentName())) {
+            TagImportDto parent = nameToDtoMap.get(current.getParentName());
+            String parentPath = buildFullPath(parent, visited, nameToDtoMap);
+            if (!parentPath.isEmpty()) {
+                path.append(parentPath).append("/");
+            }
+        }
+        path.append(current.getTagNm());
+        visited.remove(current.getTagNm());
+        return path.toString();
+    }
+
+    /**
+     * 将AitagTagInfoEntity列表转换为树形结构
+     * @param entities AitagTagInfoEntity列表
+     * @return 树形结构的根节点列表
+     */
+    private List<TagNodeVo> buildTree(List<AitagTagInfoEntity> entities) {
+        List<TagNodeVo> rootNodes = new ArrayList<>();
+        Map<String, TagNodeVo> nodeMap = new HashMap<>();
+
+        // 首先创建所有节点并放入map
+        for (AitagTagInfoEntity entity : entities) {
+            TagNodeVo node = new TagNodeVo(entity);
+            nodeMap.put(entity.getId(), node);
+        }
+
+        // 构建树形结构
+        for (AitagTagInfoEntity entity : entities) {
+            TagNodeVo currentNode = nodeMap.get(entity.getId());
+            String parentId = entity.getParentId();
+
+            // 如果parentId为null或空,则为根节点
+            if (parentId == null || parentId.isEmpty()) {
+                rootNodes.add(currentNode);
+            } else {
+                // 查找父节点并添加为子节点
+                TagNodeVo parentNode = nodeMap.get(parentId);
+                if (parentNode != null) {
+                    parentNode.addChild(currentNode);
+                }else{
+                    rootNodes.add(currentNode);
+                }
+            }
+        }
+        return rootNodes;
+    }
+
+
+    @Override
+    public AiTaggingResponseVo callAiTag(Map<String, Object> body, String path) {
+        String url = fastApiConfig.getUrl() + path;
+        log.info("调用AI打标接口: {}", url);
+
+        try (CloseableHttpClient httpClient = createHttpClient()) {
+            HttpPost httpPost = new HttpPost(url);
+            httpPost.setHeader("Content-Type", "application/json");
+            // 构造请求体
+            String requestBody = JSON.toJSONString(body);
+            httpPost.setEntity(new StringEntity(requestBody, "UTF-8"));
+
+            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
+                String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
+                log.info("AI打标接口响应: {}", responseBody);
+                return JSON.parseObject(responseBody, AiTaggingResponseVo.class);
+            }
+        } catch (Exception e) {
+            log.error("调用AI打标接口失败", e);
+            throw BizException.of("E008");
+        }
+    }
+
+    /**
+     * 创建HTTP客户端
+     */
+    private CloseableHttpClient createHttpClient() {
+        RequestConfig requestConfig = RequestConfig.custom()
+                .setConnectTimeout(fastApiConfig.getConnectTimeout())
+                .setSocketTimeout(fastApiConfig.getReadTimeout())
+                .build();
+        return HttpClients.custom()
+                .setDefaultRequestConfig(requestConfig)
+                .build();
+    }
+
+}

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

@@ -0,0 +1,81 @@
+package cn.com.yusys.yusp.service.impl;
+
+import cn.com.yusys.yusp.mapper.AitagTagInfoVersionDao;
+import cn.com.yusys.yusp.domain.entity.AitagTagInfoVersionEntity;
+import cn.com.yusys.yusp.domain.vo.AitagTagInfoVersionQueryVo;
+import cn.com.yusys.yusp.service.AitagTagInfoVersionService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * 标签信息版本表
+ *
+ * @author 2507040827
+ * @date 2026-02-27 11:33:54
+ */
+
+@Service("aitagTagInfoVersionService")
+public class AitagTagInfoVersionServiceImpl extends ServiceImpl<AitagTagInfoVersionDao, AitagTagInfoVersionEntity> implements AitagTagInfoVersionService {
+
+    /**
+     * 分页查询
+     *
+     * @param aitagTagInfoVersionQueryVo
+     * @return IPage
+     */
+    @Override
+    public IPage<AitagTagInfoVersionEntity> queryPage(AitagTagInfoVersionQueryVo aitagTagInfoVersionQueryVo) {
+        LambdaQueryWrapper<AitagTagInfoVersionEntity> queryWrapper = new LambdaQueryWrapper<>();
+        if (aitagTagInfoVersionQueryVo.getId() != null) {
+            queryWrapper.eq(AitagTagInfoVersionEntity::getId, aitagTagInfoVersionQueryVo.getId());
+        }
+        if (aitagTagInfoVersionQueryVo.getCategoryId() != null) {
+            queryWrapper.eq(AitagTagInfoVersionEntity::getCategoryId, aitagTagInfoVersionQueryVo.getCategoryId());
+        }
+        if (aitagTagInfoVersionQueryVo.getTagNm() != null) {
+            queryWrapper.eq(AitagTagInfoVersionEntity::getTagNm, aitagTagInfoVersionQueryVo.getTagNm());
+        }
+        if (aitagTagInfoVersionQueryVo.getTagCode() != null) {
+            queryWrapper.eq(AitagTagInfoVersionEntity::getTagCode, aitagTagInfoVersionQueryVo.getTagCode());
+        }
+        if (aitagTagInfoVersionQueryVo.getTagRemark() != null) {
+            queryWrapper.eq(AitagTagInfoVersionEntity::getTagRemark, aitagTagInfoVersionQueryVo.getTagRemark());
+        }
+        if (aitagTagInfoVersionQueryVo.getParentId() != null) {
+            queryWrapper.eq(AitagTagInfoVersionEntity::getParentId, aitagTagInfoVersionQueryVo.getParentId());
+        }
+        if (aitagTagInfoVersionQueryVo.getReg() != null) {
+            queryWrapper.eq(AitagTagInfoVersionEntity::getReg, aitagTagInfoVersionQueryVo.getReg());
+        }
+        if (aitagTagInfoVersionQueryVo.getTagLevel() != null) {
+            queryWrapper.eq(AitagTagInfoVersionEntity::getTagLevel, aitagTagInfoVersionQueryVo.getTagLevel());
+        }
+        if (aitagTagInfoVersionQueryVo.getTagPath() != null) {
+            queryWrapper.eq(AitagTagInfoVersionEntity::getTagPath, aitagTagInfoVersionQueryVo.getTagPath());
+        }
+        if (aitagTagInfoVersionQueryVo.getIsDelete() != null) {
+            queryWrapper.eq(AitagTagInfoVersionEntity::getIsDelete, aitagTagInfoVersionQueryVo.getIsDelete());
+        }
+        if (aitagTagInfoVersionQueryVo.getState() != null) {
+            queryWrapper.eq(AitagTagInfoVersionEntity::getState, aitagTagInfoVersionQueryVo.getState());
+        }
+        if (aitagTagInfoVersionQueryVo.getTagPrompt() != null) {
+            queryWrapper.eq(AitagTagInfoVersionEntity::getTagPrompt, aitagTagInfoVersionQueryVo.getTagPrompt());
+        }
+        if (aitagTagInfoVersionQueryVo.getTagVersion() != null) {
+            queryWrapper.eq(AitagTagInfoVersionEntity::getTagVersion, aitagTagInfoVersionQueryVo.getTagVersion());
+        }
+        if (aitagTagInfoVersionQueryVo.getRevisionTime() != null) {
+            queryWrapper.eq(AitagTagInfoVersionEntity::getRevisionTime, aitagTagInfoVersionQueryVo.getRevisionTime());
+        }
+        if (aitagTagInfoVersionQueryVo.getReviser() != null) {
+            queryWrapper.eq(AitagTagInfoVersionEntity::getReviser, aitagTagInfoVersionQueryVo.getReviser());
+        }
+
+        IPage<AitagTagInfoVersionEntity> page = this.page(new Page<>(aitagTagInfoVersionQueryVo.getPage(), aitagTagInfoVersionQueryVo.getSize()), queryWrapper);
+        return page;
+    }
+}

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

@@ -1,6 +1,7 @@
 package cn.com.yusys.yusp.service.impl;
 
 import cn.com.yusys.yusp.commons.exception.BizException;
+import cn.com.yusys.yusp.commons.util.date.DateUtils;
 import cn.com.yusys.yusp.config.DataDictionary;
 import cn.com.yusys.yusp.domain.entity.AitagTagInfoEntity;
 import cn.com.yusys.yusp.domain.vo.*;
@@ -10,11 +11,13 @@ import cn.com.yusys.yusp.mapper.AitagTagLogDao;
 import cn.com.yusys.yusp.domain.entity.AitagTagLogEntity;
 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.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -22,6 +25,7 @@ import org.springframework.stereotype.Service;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.net.URL;
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
@@ -35,6 +39,7 @@ import static cn.com.yusys.yusp.config.DataDictionary.*;
  */
 
 @Service("aitagTagLogService")
+@Slf4j
 public class AitagTagLogServiceImpl extends ServiceImpl<AitagTagLogDao, AitagTagLogEntity> implements AitagTagLogService {
 
     @Autowired
@@ -46,34 +51,36 @@ public class AitagTagLogServiceImpl extends ServiceImpl<AitagTagLogDao, AitagTag
     @Override
     public DataOverviewVo dataOverview(SmartTaggingResultVo taggingResult) {
         DataOverviewVo dataOverview = new DataOverviewVo();
+
         Integer totalCnt = this.baseMapper.selectTagCount(taggingResult);
+        log.info("查询出符合条件的全部打标数据:{} 条",totalCnt);
         dataOverview.setCountNum(totalCnt);
 
-        LambdaQueryWrapper<AitagTagLogEntity> queryCount = new LambdaQueryWrapper<>();
-        LambdaQueryWrapper<AitagTagLogEntity> queryAgreeTags = new LambdaQueryWrapper<>();
-        if (StringUtils.isNotBlank(taggingResult.getCategoryCode())) {
-            queryCount.eq(AitagTagLogEntity::getCategoryCode, taggingResult.getCategoryCode());
-            queryAgreeTags.eq(AitagTagLogEntity::getCategoryCode, taggingResult.getCategoryCode());
+        LambdaQueryWrapper<AitagTagLogEntity> queryWrapper = new LambdaQueryWrapper<>();
+        if (StringUtils.isNotBlank(taggingResult.getCategoryId())) {
+            queryWrapper.apply("result @> '"+taggingResult.getCategoryExp()+"'");
         }
         if (StringUtils.isNotBlank(taggingResult.getStartTaggingTime())){
-            queryCount.ge(AitagTagLogEntity::getInsertTime, taggingResult.getStartTaggingTime());
-            queryAgreeTags.ge(AitagTagLogEntity::getInsertTime, taggingResult.getStartTaggingTime());
+            queryWrapper.ge(AitagTagLogEntity::getInsertTime, taggingResult.getStartTaggingTime());
         }
         if (StringUtils.isNotBlank(taggingResult.getEndTaggingTime())){
-            queryCount.le(AitagTagLogEntity::getInsertTime, taggingResult.getEndTaggingTime());
-            queryAgreeTags.le(AitagTagLogEntity::getInsertTime, taggingResult.getEndTaggingTime());
+            queryWrapper.le(AitagTagLogEntity::getInsertTime, taggingResult.getEndTaggingTime());
         }
-        queryCount.in(AitagTagLogEntity::getState, DataDictionary.RESULT_PUSHED,DataDictionary.MANAGER_CONFIRMED);
-        queryAgreeTags.in(AitagTagLogEntity::getState, DataDictionary.RESULT_PUSHED,DataDictionary.MANAGER_CONFIRMED);
+        queryWrapper.in(AitagTagLogEntity::getState, DataDictionary.RESULT_PUSHED,DataDictionary.MANAGER_CONFIRMED);
+        queryWrapper.eq(AitagTagLogEntity::getTagScope, PROD_DATA);
+        Integer totalConfirmedCnt = this.baseMapper.selectCount(queryWrapper);
+        log.info("查询出符合条件的打标完成数据:{} 条",totalConfirmedCnt);
 
-        Integer totalConfirmedCnt = this.baseMapper.selectCount(queryCount);
+        queryWrapper.eq(AitagTagLogEntity::getFeedback,FEEDBACK_RESULT_AGREE);
+        Integer agreeTagNum = this.baseMapper.selectCount(queryWrapper);
+        log.info("查询出符合条件的打标准确数据:{} 条",agreeTagNum);
+        dataOverview.setAccurateNum(agreeTagNum);
 
-        queryAgreeTags.eq(AitagTagLogEntity::getFeedback,FEEDBACK_RESULT_AGREE);
-        Integer agreeTagNum = this.baseMapper.selectCount(queryAgreeTags);
-        BigDecimal accurateRate = calculateAccuracy(agreeTagNum, totalConfirmedCnt);
 
-        dataOverview.setAccurateNum(totalConfirmedCnt);
+        BigDecimal accurateRate = calculateAccuracy(agreeTagNum, totalConfirmedCnt);
+        log.info("计算出准确率:{} 条",accurateRate);
         dataOverview.setAccurateRate(accurateRate+"%");
+
         if(totalConfirmedCnt == 0){
             dataOverview.setManualAdjustRate("0%");
         }else{
@@ -82,22 +89,21 @@ public class AitagTagLogServiceImpl extends ServiceImpl<AitagTagLogDao, AitagTag
         }
         dataOverview.setManualAdjustCount(totalConfirmedCnt-agreeTagNum);
         dataOverview.setTaggedUnconfirmed(totalCnt-totalConfirmedCnt);
+        log.info("准备返回数据为:{} ", JSONObject.toJSONString(dataOverview));
         return dataOverview;
     }
 
     @Override
     public List<IconResVo> taggingTrend(TaggingTrendReqVo taggingTrendReqVo) {
-        String statisticalPeriod = taggingTrendReqVo.getStatisticalPeriod();
+        String startTaggingTime = taggingTrendReqVo.getStartTaggingTime();
+        String endTaggingTime = taggingTrendReqVo.getEndTaggingTime();
+
+        int daysByTwoDatesDef = DateUtils.getDaysByTwoDatesDef(startTaggingTime, endTaggingTime);
         List<IconResVo> taggingTrendResVo = null;
-                switch (statisticalPeriod){
-            case DAY:
-                taggingTrendResVo = this.baseMapper.selectTagReportByDay(taggingTrendReqVo);
-                break;
-            case MONTH:
-                taggingTrendResVo = this.baseMapper.selectTagReportByMonth(taggingTrendReqVo);
-                break;
-            default:
-                throw BizException.of("NO_DATA_PERIOD");
+        if(daysByTwoDatesDef>=15){
+            taggingTrendResVo = this.baseMapper.selectTagReportByDay(taggingTrendReqVo);
+        }else{
+            taggingTrendResVo = this.baseMapper.selectTagReportByMonth(taggingTrendReqVo);
         }
         return taggingTrendResVo;
     }
@@ -105,8 +111,8 @@ public class AitagTagLogServiceImpl extends ServiceImpl<AitagTagLogDao, AitagTag
     @Override
     public IPage<AitagTagLogEntity> taggingDetails(TaggingTransactionReqVo transactionReqVo) {
         LambdaQueryWrapper<AitagTagLogEntity> queryWrapper = new LambdaQueryWrapper<>();
-        if (StringUtils.isNotBlank(transactionReqVo.getCategoryCode())) {
-            queryWrapper.eq(AitagTagLogEntity::getCategoryCode, transactionReqVo.getCategoryCode());
+        if (StringUtils.isNotBlank(transactionReqVo.getCategoryId())) {
+            queryWrapper.apply("result @> '"+transactionReqVo.getCategoryExp()+"'");
         }
         if (StringUtils.isNotBlank(transactionReqVo.getStartTaggingTime())){
             queryWrapper.ge(AitagTagLogEntity::getInsertTime, transactionReqVo.getStartTaggingTime());
@@ -117,8 +123,10 @@ public class AitagTagLogServiceImpl extends ServiceImpl<AitagTagLogDao, AitagTag
         if (StringUtils.isNotBlank(transactionReqVo.getLoanApplicationNo())){
             queryWrapper.le(AitagTagLogEntity::getBusinessAttr, transactionReqVo.getLoanApplicationNo());
         }
-        return this.baseMapper.selectPage(new Page<>(transactionReqVo.getPage(),
-                transactionReqVo.getSize()),queryWrapper);
+        queryWrapper.eq(AitagTagLogEntity::getTagScope, PROD_DATA);
+
+        return this.page(new Page<>(transactionReqVo.getPage() == null?0:transactionReqVo.getPage(),
+                transactionReqVo.getSize() == null?10:transactionReqVo.getSize()),queryWrapper);
     }
 
     @Override
@@ -141,14 +149,15 @@ public class AitagTagLogServiceImpl extends ServiceImpl<AitagTagLogDao, AitagTag
     }
 
     private String getTagPath(String result) {
+        result = result.replace("\\", "");
         List<Map> results = JSONArray.parseArray(result, Map.class);
+        if(results == null){
+            return "";
+        }
         for (Map resultMap: results){
-            String tagCode = resultMap.getOrDefault("tag_code","").toString();
-            LambdaQueryWrapper<AitagTagInfoEntity> queryCount = new LambdaQueryWrapper<>();
-            queryCount.eq(AitagTagInfoEntity::getTagCode,tagCode);
-            List<AitagTagInfoEntity> aitagTagInfoEntities = tagInfoDao.selectList(queryCount);
-            if(!aitagTagInfoEntities.isEmpty()){
-                AitagTagInfoEntity aitagTagInfoEntity = aitagTagInfoEntities.get(0);
+            String tagId = resultMap.getOrDefault("id","").toString();
+            AitagTagInfoEntity aitagTagInfoEntity = tagInfoDao.selectById(tagId);
+            if(aitagTagInfoEntity!=null){
                 resultMap.put("tag_path",aitagTagInfoEntity.getTagPath());
             }
         }
@@ -160,22 +169,30 @@ public class AitagTagLogServiceImpl extends ServiceImpl<AitagTagLogDao, AitagTag
         return aggDao.selectTagDistStats(resultVo);
     }
 
+
+    /**
+     * 查询确认后的标签数据
+     * @param transactionReqVo
+     * @return
+     */
     @Override
-    public List<AitagTagLogEntity> queryList(TaggingTransactionReqVo transactionReqVo) {
-        LambdaQueryWrapper<AitagTagLogEntity> queryCount = new LambdaQueryWrapper<>();
-        if (StringUtils.isNotBlank(transactionReqVo.getCategoryCode())) {
-            queryCount.eq(AitagTagLogEntity::getCategoryCode, transactionReqVo.getCategoryCode());
+    public List<AitagTagLogEntity> queryConfirmedTagData(TaggingTransactionReqVo transactionReqVo) {
+        LambdaQueryWrapper<AitagTagLogEntity> query = new LambdaQueryWrapper<>();
+        if (StringUtils.isNotBlank(transactionReqVo.getCategoryId())) {
+            query.apply("result @> '"+transactionReqVo.getCategoryExp()+"'");
         }
         if (StringUtils.isNotBlank(transactionReqVo.getStartTaggingTime())){
-            queryCount.ge(AitagTagLogEntity::getInsertTime, transactionReqVo.getStartTaggingTime());
+            query.ge(AitagTagLogEntity::getInsertTime, transactionReqVo.getStartTaggingTime());
         }
         if (StringUtils.isNotBlank(transactionReqVo.getEndTaggingTime())){
-            queryCount.le(AitagTagLogEntity::getInsertTime, transactionReqVo.getEndTaggingTime());
+            query.le(AitagTagLogEntity::getInsertTime, transactionReqVo.getEndTaggingTime());
         }
         if (StringUtils.isNotBlank(transactionReqVo.getLoanApplicationNo())){
-            queryCount.le(AitagTagLogEntity::getBusinessAttr, transactionReqVo.getLoanApplicationNo());
+            query.eq(AitagTagLogEntity::getBusinessAttr, transactionReqVo.getLoanApplicationNo());
         }
-        return this.baseMapper.selectList(queryCount);
+        query.in(AitagTagLogEntity::getState, DataDictionary.RESULT_PUSHED,DataDictionary.MANAGER_CONFIRMED);
+        query.eq(AitagTagLogEntity::getTagScope, PROD_DATA);
+        return this.baseMapper.selectList(query);
     }
 
 

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

@@ -0,0 +1,118 @@
+package cn.com.yusys.yusp.service.impl;
+
+import cn.com.yusys.yusp.condition.AuthEnabledCondition;
+import cn.com.yusys.yusp.domain.dto.LoginRequestDto;
+import cn.com.yusys.yusp.domain.entity.AitagUser;
+import cn.com.yusys.yusp.domain.vo.LoginResponseVo;
+import cn.com.yusys.yusp.mapper.AitagUserMapper;
+import cn.com.yusys.yusp.service.AuthService;
+import cn.com.yusys.yusp.util.JwtUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.stereotype.Service;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 认证服务实现类
+ *
+ * @author AI助手
+ * @date 2026-02-27
+ */
+@Slf4j
+@Service
+@Conditional(AuthEnabledCondition.class)
+public class AuthServiceImpl implements AuthService {
+
+    @Autowired
+    private AitagUserMapper userMapper;
+
+    @Autowired
+    private JwtUtil jwtUtil;
+
+    @Value("${jwt.expiration:86400000}")
+    private Long expiration;
+
+    // 存储在线用户的token(简单实现,生产环境建议使用Redis)
+    private final ConcurrentHashMap<String, String> onlineUsers = new ConcurrentHashMap<>();
+
+    @Override
+    public LoginResponseVo login(LoginRequestDto loginRequest) {
+        String userId = loginRequest.getUserId();
+        String password = loginRequest.getPwd();
+
+        log.info("用户尝试登录: {}", userId);
+
+        // 验证用户是否存在
+        AitagUser user = getUserById(userId);
+        if (user == null) {
+            log.warn("用户不存在: {}", userId);
+            throw new RuntimeException("用户名或密码错误");
+        }
+
+        // 验证密码
+        if (!validatePassword(userId, password)) {
+            log.warn("密码错误: {}", userId);
+            throw new RuntimeException("用户名或密码错误");
+        }
+
+        // 生成token
+        String token = jwtUtil.generateToken(userId, user.getUserRole());
+
+        // 记录在线用户
+        onlineUsers.put(userId, token);
+
+        log.info("用户登录成功: {}, 角色: {}", userId, user.getUserRole());
+
+        return LoginResponseVo.success(
+                token,
+                user.getUserId(),
+                user.getUserName(),
+                user.getUserRole(),
+                expiration
+        );
+    }
+
+    @Override
+    public void logout(String userId) {
+        log.info("用户登出: {}", userId);
+        onlineUsers.remove(userId);
+    }
+
+    @Override
+    public AitagUser getUserById(String userId) {
+        return userMapper.selectByUserId(userId);
+    }
+
+    @Override
+    public boolean validatePassword(String userId, String password) {
+        AitagUser user = getUserById(userId);
+        if (user == null) {
+            return false;
+        }
+        // 简单的密码比较,实际项目中应该使用加密存储
+        return user.getPwd() != null && user.getPwd().equals(password);
+    }
+
+    /**
+     * 检查用户是否在线
+     *
+     * @param userId 用户ID
+     * @return 是否在线
+     */
+    public boolean isUserOnline(String userId) {
+        return onlineUsers.containsKey(userId);
+    }
+
+    /**
+     * 获取用户的当前token
+     *
+     * @param userId 用户ID
+     * @return token
+     */
+    public String getUserToken(String userId) {
+        return onlineUsers.get(userId);
+    }
+}

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

@@ -0,0 +1,216 @@
+package cn.com.yusys.yusp.service.impl;
+
+import cn.com.yusys.yusp.config.FastApiConfig;
+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.fastapivo.AiTaggingQueryResponseVo;
+import cn.com.yusys.yusp.domain.vo.fastapivo.AiTaggingResponseVo;
+import cn.com.yusys.yusp.service.FastApiService;
+import com.alibaba.fastjson.JSON;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
+
+@Slf4j
+@Service
+public class FastApiServiceImpl implements FastApiService {
+
+    @Autowired
+    private FastApiConfig fastApiConfig;
+
+    private static final String TAGGING_PATH = "/api/aitag/v1/tagging";
+    private static final String QUERY_PATH = "/api/aitag/v1/query";
+    private static final String FEEDBACK_PATH = "/api/aitag/v1/feedback";
+
+    @Override
+    public AiTaggingResponseVo tagging(AiTaggingRequestDto request) {
+        String url = fastApiConfig.getUrl() + TAGGING_PATH;
+        log.info("调用 AI 打标接口:{}", url);
+
+        try (CloseableHttpClient httpClient = createHttpClient()) {
+            HttpPost httpPost = new HttpPost(url);
+            httpPost.setHeader("Content-Type", "application/json");
+
+            // 构造请求体
+            String requestBody = JSON.toJSONString(request);
+            httpPost.setEntity(new StringEntity(requestBody, "UTF-8"));
+
+            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
+                String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
+                log.info("AI 打标接口响应:{}", responseBody);
+
+                return JSON.parseObject(responseBody, AiTaggingResponseVo.class);
+            }
+        } catch (Exception e) {
+            log.error("调用 AI 打标接口失败", e);
+            AiTaggingResponseVo errorResponse = new AiTaggingResponseVo();
+            errorResponse.setCode("500");
+            errorResponse.setMessage("调用 AI 打标接口失败:" + e.getMessage());
+            return errorResponse;
+        }
+    }
+
+    @Override
+    public AiTaggingQueryResponseVo query(AiTaggingQueryRequestDto request) {
+        String url = fastApiConfig.getUrl() + QUERY_PATH + "?business_attr=" + encodeParam(request.getBusinessAttr());
+
+        log.info("调用 AI 打标查询接口:{}", url);
+        try (CloseableHttpClient httpClient = createHttpClient()) {
+            HttpGet httpGet = new HttpGet(url);
+
+            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
+                String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
+                log.info("AI 打标查询接口响应:{}", responseBody);
+
+                return JSON.parseObject(responseBody, AiTaggingQueryResponseVo.class);
+            }
+        } catch (Exception e) {
+            log.error("调用 AI 打标查询接口失败", e);
+            AiTaggingQueryResponseVo errorResponse = new AiTaggingQueryResponseVo();
+            errorResponse.setCode("500");
+            errorResponse.setMessage("调用 AI 打标查询接口失败:" + e.getMessage());
+            return errorResponse;
+        }
+    }
+
+
+//    @Override
+//    public AiTaggingResponseVo feedback(AiTaggingFeedbackRequestDto request) {
+//        StringBuilder urlBuilder = new StringBuilder(fastApiConfig.getUrl()).append(FEEDBACK_PATH);
+//
+//        // 构造 GET 请求参数
+//        boolean hasParams = false;
+//
+//        if (request.getUserId() != null && !request.getUserId().isEmpty()) {
+//            urlBuilder.append(hasParams ? "&" : "?").append("user_id=").append(encodeParam(request.getUserId()));
+//            hasParams = true;
+//        }
+//
+//        if (request.getUserNm() != null && !request.getUserNm().isEmpty()) {
+//            urlBuilder.append(hasParams ? "&" : "?").append("user_nm=").append(encodeParam(request.getUserNm()));
+//            hasParams = true;
+//        }
+//
+//        // feedback 是必填参数
+//        urlBuilder.append(hasParams ? "&" : "?").append("feedback=").append(encodeParam(request.getFeedback()));
+//        hasParams = true;
+//
+//        if (request.getContractNo() != null && !request.getContractNo().isEmpty()) {
+//            urlBuilder.append(hasParams ? "&" : "?").append("contract_no=").append(encodeParam(request.getContractNo()));
+//            hasParams = true;
+//        }
+//
+//        if (request.getUserOrg() != null && !request.getUserOrg().isEmpty()) {
+//            urlBuilder.append(hasParams ? "&" : "?").append("user_org=").append(encodeParam(request.getUserOrg()));
+//            hasParams = true;
+//        }
+//
+//        if (request.getUserEndpoint() != null && !request.getUserEndpoint().isEmpty()) {
+//            urlBuilder.append(hasParams ? "&" : "?").append("user_endpoint=").append(encodeParam(request.getUserEndpoint()));
+//            hasParams = true;
+//        }
+//
+//        // business_attr 是必填参数
+//        urlBuilder.append(hasParams ? "&" : "?").append("business_attr=").append(encodeParam(request.getBusinessAttr()));
+//
+//        String url = urlBuilder.toString();
+//        log.info("调用 AI 打标反馈接口:{}", url);
+//
+//        try (CloseableHttpClient httpClient = createHttpClient()) {
+//            HttpGet httpGet = new HttpGet(url);
+//
+//            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
+//                String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
+//                log.info("AI 打标反馈接口响应:{}", responseBody);
+//
+//                return JSON.parseObject(responseBody, AiTaggingResponseVo.class);
+//            }
+//        } catch (Exception e) {
+//            log.error("调用 AI 打标反馈接口失败", e);
+//            AiTaggingResponseVo errorResponse = new AiTaggingResponseVo();
+//            errorResponse.setCode("500");
+//            errorResponse.setMessage("调用 AI 打标反馈接口失败:" + e.getMessage());
+//            return errorResponse;
+//        }
+//    }
+
+
+    @Override
+    public AiTaggingResponseVo feedback(AiTaggingFeedbackRequestDto request) {
+        String url = fastApiConfig.getUrl() + FEEDBACK_PATH;
+
+        log.info("调用 AI 打标反馈接口:{}", url);
+
+        try (CloseableHttpClient httpClient = createHttpClient()) {
+            HttpPost httpPost = new HttpPost(url);
+            httpPost.setHeader("Content-Type", "application/json");
+
+            // 手动构造符合 FastAPI 要求的 JSON 请求体(使用下划线格式)
+            com.alibaba.fastjson.JSONObject jsonBody = new com.alibaba.fastjson.JSONObject();
+            jsonBody.put("user_id", request.getUserId());
+            jsonBody.put("user_nm", request.getUserNm());
+            jsonBody.put("feedback", request.getFeedback());
+            jsonBody.put("feedback_result", request.getFeedbackResult());
+            jsonBody.put("contract_no", request.getContractNo());
+            jsonBody.put("user_org", request.getUserOrg());
+            jsonBody.put("user_endpoint", request.getUserEndpoint());
+            jsonBody.put("business_attr", request.getBusinessAttr());
+
+            String requestBody = jsonBody.toJSONString();
+            log.info("请求体:{}", requestBody);
+
+            httpPost.setEntity(new StringEntity(requestBody, "UTF-8"));
+
+            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
+                String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
+                log.info("AI 打标反馈接口响应:{}", responseBody);
+
+                return JSON.parseObject(responseBody, AiTaggingResponseVo.class);
+            }
+        } catch (Exception e) {
+            log.error("调用 AI 打标反馈接口失败", e);
+            AiTaggingResponseVo errorResponse = new AiTaggingResponseVo();
+            errorResponse.setCode("500");
+            errorResponse.setMessage("调用 AI 打标反馈接口失败:" + e.getMessage());
+            return errorResponse;
+        }
+    }
+
+
+    // 辅助方法用于URL编码
+    private String encodeParam(String param) {
+        try {
+            return URLEncoder.encode(param, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            log.warn("URL编码失败,使用原始值: {}", param);
+            return param;
+        }
+    }
+
+    /**
+     * 创建HTTP客户端
+     */
+    private CloseableHttpClient createHttpClient() {
+        RequestConfig requestConfig = RequestConfig.custom()
+                .setConnectTimeout(fastApiConfig.getConnectTimeout())
+                .setSocketTimeout(fastApiConfig.getReadTimeout())
+                .build();
+
+        return HttpClients.custom()
+                .setDefaultRequestConfig(requestConfig)
+                .build();
+    }
+}

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

@@ -0,0 +1,81 @@
+package cn.com.yusys.yusp.util;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 认证上下文工具类
+ * 用于存储当前线程的用户信息
+ *
+ * @author AI助手
+ * @date 2026-02-27
+ */
+@Slf4j
+public class AuthContextUtil {
+
+    private static final ThreadLocal<String> currentUser = new ThreadLocal<>();
+    private static final ThreadLocal<String> currentRole = new ThreadLocal<>();
+    private static final ThreadLocal<String> currentUserName = new ThreadLocal<>(); // 新增:存储用户名
+
+    /**
+     * 设置当前用户
+     *
+     * @param userId 用户ID
+     */
+    public static void setCurrentUser(String userId) {
+        currentUser.set(userId);
+    }
+
+    /**
+     * 获取当前用户
+     *
+     * @return 用户ID
+     */
+    public static String getCurrentUser() {
+        return currentUser.get();
+    }
+
+    /**
+     * 设置当前用户角色
+     *
+     * @param role 用户角色
+     */
+    public static void setCurrentRole(String role) {
+        currentRole.set(role);
+    }
+
+    /**
+     * 获取当前用户角色
+     *
+     * @return 用户角色
+     */
+    public static String getCurrentRole() {
+        return currentRole.get();
+    }
+
+    /**
+     * 设置当前用户名
+     *
+     * @param userName 用户名
+     */
+    public static void setCurrentUserName(String userName) {
+        currentUserName.set(userName);
+    }
+
+    /**
+     * 获取当前用户名
+     *
+     * @return 用户名
+     */
+    public static String getCurrentUserName() {
+        return currentUserName.get();
+    }
+
+    /**
+     * 清除当前线程的用户信息
+     */
+    public static void clear() {
+        currentUser.remove();
+        currentRole.remove();
+        currentUserName.remove(); // 新增:清除用户名
+    }
+}

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

@@ -0,0 +1,126 @@
+package cn.com.yusys.yusp.util;
+
+import cn.com.yusys.yusp.condition.AuthEnabledCondition;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm; // 0.9.1 使用这个枚举
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * JWT工具类 (适配 JJWT 0.9.1)
+ *
+ * @author 2643616413
+ * @date 2026-02-27
+ */
+@Slf4j
+@Component
+@Conditional(AuthEnabledCondition.class)
+public class JwtUtil {
+
+    @Value("${jwt.secret:yusp-tagging-secret-key}")
+    private String secret;
+
+    @Value("${jwt.expiration:86400000}")
+    private Long expiration;
+
+    /**
+     * 生成JWT token
+     */
+    public String generateToken(String userId, String userRole) {
+        Map<String, Object> claims = new HashMap<>();
+        claims.put("userId", userId);
+        claims.put("userRole", userRole);
+        return createToken(claims, userId);
+    }
+
+    /**
+     * 创建token
+     */
+    private String createToken(Map<String, Object> claims, String subject) {
+        Date now = new Date();
+        Date expiryDate = new Date(now.getTime() + expiration);
+
+        return Jwts.builder()
+                .setClaims(claims)
+                .setSubject(subject)
+                .setIssuedAt(now)
+                .setExpiration(expiryDate)
+                // 0.9.1 的 signWith 签名算法在前,密钥在后,且密钥可以是 String
+                .signWith(SignatureAlgorithm.HS512, secret)
+                .compact();
+    }
+
+    /**
+     * 验证token有效性
+     */
+    public Boolean validateToken(String token) {
+        try {
+            Claims claims = getClaimsFromToken(token);
+            Date expiration = claims.getExpiration();
+            return !expiration.before(new Date());
+        } catch (Exception e) {
+            log.warn("JWT token验证失败:{}", e.getMessage());
+            return false;
+        }
+    }
+
+    /**
+     * 从token中获取用户ID
+     */
+    public String getUserIdFromToken(String token) {
+        try {
+            Claims claims = getClaimsFromToken(token);
+            return claims.get("userId", String.class);
+        } catch (Exception e) {
+            log.warn("从token获取用户ID失败:{}", e.getMessage());
+            return null;
+        }
+    }
+
+    /**
+     * 从token中获取用户角色
+     */
+    public String getRoleFromToken(String token) {
+        try {
+            Claims claims = getClaimsFromToken(token);
+            return claims.get("userRole", String.class);
+        } catch (Exception e) {
+            log.warn("从token获取用户角色失败:{}", e.getMessage());
+            return null;
+        }
+    }
+
+    /**
+     * 从token中获取声明 (0.9.1 写法)
+     */
+    private Claims getClaimsFromToken(String token) {
+        // 修改点 3: 0.9.1 没有 parserBuilder(),直接使用 parser()
+        // 修改点 4: setSigningKey 直接接受 String secret
+        return Jwts.parser()
+                .setSigningKey(secret)
+                .parseClaimsJws(token)
+                .getBody();
+    }
+
+    /**
+     * 刷新token
+     */
+    public String refreshToken(String token) {
+        try {
+            Claims claims = getClaimsFromToken(token);
+            String userId = claims.getSubject();
+            String role = claims.get("userRole", String.class);
+            return generateToken(userId, role);
+        } catch (Exception e) {
+            log.warn("刷新token失败:{}", e.getMessage());
+            return null;
+        }
+    }
+}

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

@@ -0,0 +1,53 @@
+package cn.com.yusys.yusp.util;
+
+import cn.com.yusys.yusp.commons.exception.BizException;
+import cn.com.yusys.yusp.commons.util.SpringContextUtils;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import org.springframework.data.redis.core.StringRedisTemplate;
+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 javax.annotation.PostConstruct;
+import javax.servlet.http.HttpServletRequest;
+
+
+@Component
+public class SessionCommonUtil {
+
+    private static StringRedisTemplate redisTemplate;
+
+
+    @PostConstruct
+    public void init() {
+        redisTemplate = SpringContextUtils.getBean(StringRedisTemplate.class);
+    }
+    public static String getUserInfo() {
+        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");
+                        JSONObject userInfoMap = JSONObject.parseObject(userInfo);
+                        return userInfoMap.getString("userName");
+                    }
+                }
+            }else{
+               throw BizException.of("E009");
+            }
+        }
+        throw BizException.of("E009");
+    }
+
+}

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

@@ -43,8 +43,7 @@
                 AND create_date >= #{startTime}
             </if>
             <if test="endTime != null">
-                <!-- 结束时间加一天,确保包含当天的所有记录 -->
-                AND create_date <![CDATA[<]]> DATE_ADD(#{endTime}, INTERVAL 1 DAY)
+                AND DATE(create_date) <![CDATA[<=]]> DATE(#{endTime})
             </if>
         </where>
     </select>
@@ -58,8 +57,7 @@
                 AND create_date >= #{startTime}
             </if>
             <if test="endTime != null">
-                <!-- 结束时间加一天,确保包含当天的所有记录 -->
-                AND create_date <![CDATA[<]]> DATE_ADD(#{endTime}, INTERVAL 1 DAY)
+                AND DATE(create_date) <![CDATA[<=]]> DATE(#{endTime})
             </if>
         </where>
         ORDER BY create_date DESC

+ 36 - 0
server/yusp-tagging-core/src/main/resources/mapper/AitagTagCategoryMapper.xml

@@ -9,6 +9,25 @@
             LIMIT #{offset}, #{limit}
     </select>
 
+    <!-- 带模糊筛选的分页查询 -->
+    <select id="selectPageCategoriesWithFilter" resultType="cn.com.yusys.yusp.domain.entity.AitagTagCategory">
+        SELECT * FROM aitag_tag_category
+        WHERE is_delete = 0
+        <if test="categoryNm != null and categoryNm != ''">
+            AND category_nm LIKE CONCAT('%', #{categoryNm}, '%')
+        </if>
+        LIMIT #{offset}, #{limit}
+    </select>
+
+    <!-- 带模糊筛选的总数 -->
+    <select id="selectCountWithFilter" resultType="long">
+        SELECT COUNT(*) FROM aitag_tag_category
+        WHERE is_delete = 0
+        <if test="categoryNm != null and categoryNm != ''">
+            AND category_nm LIKE CONCAT('%', #{categoryNm}, '%')
+        </if>
+    </select>
+
     <!-- 模糊查询 -->
     <select id="selectByCategoryNmLike" resultType="cn.com.yusys.yusp.domain.entity.AitagTagCategory">
         SELECT * FROM aitag_tag_category
@@ -59,4 +78,21 @@
     <select id="selectCountAll" resultType="long">
         SELECT COUNT(*) FROM aitag_tag_category WHERE is_delete = 0
     </select>
+
+    <!-- 分页查询已启用的标签体系 -->
+    <select id="selectPageEnabledCategories" resultType="cn.com.yusys.yusp.domain.entity.AitagTagCategory">
+        SELECT * FROM aitag_tag_category
+        WHERE is_delete = 0 AND state = 0
+            LIMIT #{offset}, #{limit}
+    </select>
+
+    <!-- 统计已启用标签体系的数量 -->
+    <select id="selectCountEnabled" resultType="long">
+        SELECT COUNT(*) FROM aitag_tag_category WHERE is_delete = 0 AND state = 0
+    </select>
+
+    <!-- 根据ID查询标签体系详情 -->
+    <select id="selectDetailById" resultType="cn.com.yusys.yusp.domain.entity.AitagTagCategory">
+        SELECT * FROM aitag_tag_category WHERE id = #{id}
+    </select>
 </mapper>

+ 5 - 5
server/yusp-tagging-core/src/main/resources/mapper/AitagTagDailyAggMapper.xml

@@ -4,7 +4,7 @@
     <resultMap id="aitagTagDailyAgg" type="cn.com.yusys.yusp.domain.entity.AitagTagDailyAggEntity">
         <id column="id" jdbcType="VARCHAR" property="id"/>
         <result column="agg_date" jdbcType="VARCHAR" property="aggDate"/>
-        <result column="category_nm" jdbcType="VARCHAR" property="categoryNm"/>
+        <result column="category_id" jdbcType="VARCHAR" property="categoryId"/>
         <result column="tag_nm" jdbcType="VARCHAR" property="tagNm"/>
         <result column="tag_count" jdbcType="INTEGER" property="tagCount"/>
     </resultMap>
@@ -16,14 +16,14 @@
         tag_count AS val
         FROM aitag_tag_daily_agg
         <where>
-            <if test="startTaggingTime != null">
+            <if test="startTaggingTime != null and startTaggingTime != ''">
                 AND agg_date >= #{startTaggingTime}
             </if>
-            <if test="endTaggingTime != null">
+            <if test="endTaggingTime != null and endTaggingTime != ''">
                 AND #{endTaggingTime} >= agg_date
             </if>
-            <if test="categoryCode != null">
-                AND #{categoryCode} = category_code
+            <if test="categoryId != null and categoryId != '' ">
+                AND #{categoryId} = category_id
             </if>
             <if test="sort == 'ase'">
                 order by tag_count

+ 61 - 4
server/yusp-tagging-core/src/main/resources/mapper/AitagTagInfoMapper.xml

@@ -7,12 +7,69 @@
         <result column="tag_nm" jdbcType="VARCHAR" property="tagNm"/>
         <result column="tag_code" jdbcType="VARCHAR" property="tagCode"/>
         <result column="tag_remark" jdbcType="VARCHAR" property="tagRemark"/>
-        <result column="parent_code" jdbcType="VARCHAR" property="parentCode"/>
+        <result column="parent_id" jdbcType="VARCHAR" property="parentId"/>
         <result column="reg" jdbcType="VARCHAR" property="reg"/>
-        <result column="level" jdbcType="INTEGER" property="level"/>
+        <result column="tag_level" jdbcType="INTEGER" property="tagLevel"/>
         <result column="tag_path" jdbcType="VARCHAR" property="tagPath"/>
-        <result column="is_delete" jdbcType="INTEGER" property="isDelete"/>
-        <result column="state" jdbcType="INTEGER" property="state"/>
         <result column="tag_prompt" jdbcType="VARCHAR" property="tagPrompt"/>
+        <result column="tag_version" jdbcType="VARCHAR" property="tagVersion"/>
+        <result column="revision_time" jdbcType="VARCHAR" property="revisionTime"/>
+        <result column="reviser" jdbcType="VARCHAR" property="reviser"/>
     </resultMap>
+
+
+    <resultMap id="tagInfo" type="cn.com.yusys.yusp.domain.dto.TagInfoDto" extends="aitagTagInfo">
+        <collection property="tagInfoVersionDtos" ofType="cn.com.yusys.yusp.domain.dto.TagInfoVersionDto">
+            <id property="id" column="version_id"/>
+            <result property="categoryId" column="version_category_id"/>
+            <result property="tagNm" column="version_tag_nm"/>
+            <result property="tagCode" column="version_tag_code"/>
+            <result property="tagRemark" column="version_tag_remark"/>
+            <result property="parentId" column="version_parent_id"/>
+            <result property="reg" column="version_reg"/>
+            <result property="tagLevel" column="version_level"/>
+            <result property="tagPath" column="version_tag_path"/>
+            <result property="tagPrompt" column="version_tag_prompt"/>
+            <result property="tagVersion" column="version_tag_version"/>
+            <result property="revisionTime" column="version_revision_time"/>
+            <result property="reviser" column="version_reviser"/>
+        </collection>
+    </resultMap>
+
+
+    <select id="selectTagInfo" resultMap="tagInfo">
+        SELECT
+            ti.id,
+            ti.category_id,
+            ti.tag_nm,
+            ti.tag_code,
+            ti.tag_remark,
+            ti.parent_id,
+            ti.reg,
+            ti.tag_level,
+            ti.tag_path,
+            ti.tag_prompt,
+            ti.tag_version,
+            ti.revision_time,
+            ti.reviser,
+            tiv.id AS version_id,
+            tiv.category_id AS version_category_id,
+            tiv.tag_nm AS version_tag_nm,
+            tiv.tag_code AS version_tag_code,
+            tiv.tag_remark AS version_tag_remark,
+            tiv.parent_id AS version_parent_id,
+            tiv.reg AS version_reg,
+            tiv.tag_level AS version_level,
+            tiv.tag_path AS version_tag_path,
+            tiv.tag_prompt AS version_tag_prompt,
+            tiv.tag_version AS version_tag_version,
+            tiv.revision_time AS version_revision_time,
+            tiv.reviser AS version_reviser
+        FROM aitag_tag_info ti
+                 LEFT JOIN (SELECT *
+                            FROM aitag_tag_info_version
+                            WHERE is_delete = '0')  tiv ON ti.tag_code = tiv.tag_code
+        where ti.id= #{id}
+    </select>
+
 </mapper>

+ 21 - 0
server/yusp-tagging-core/src/main/resources/mapper/AitagTagInfoVersionMapper.xml

@@ -0,0 +1,21 @@
+<?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.AitagTagInfoVersionDao">
+    <resultMap id="aitagTagInfoVersion" type="cn.com.yusys.yusp.domain.entity.AitagTagInfoVersionEntity">
+        <id column="id" jdbcType="VARCHAR" property="id"/>
+        <result column="category_id" jdbcType="VARCHAR" property="categoryId"/>
+        <result column="tag_nm" jdbcType="VARCHAR" property="tagNm"/>
+        <result column="tag_code" jdbcType="VARCHAR" property="tagCode"/>
+        <result column="tag_remark" jdbcType="LONGVARCHAR" property="tagRemark"/>
+        <result column="parent_id" jdbcType="VARCHAR" property="parentId"/>
+        <result column="reg" jdbcType="LONGVARCHAR" property="reg"/>
+        <result column="tag_level" jdbcType="INTEGER" property="tagLevel"/>
+        <result column="tag_path" jdbcType="VARCHAR" property="tagPath"/>
+        <result column="is_delete" jdbcType="INTEGER" property="isDelete"/>
+        <result column="state" jdbcType="INTEGER" property="state"/>
+        <result column="tag_prompt" jdbcType="VARCHAR" property="tagPrompt"/>
+        <result column="tag_version" jdbcType="VARCHAR" property="tagVersion"/>
+        <result column="revision_time" jdbcType="VARCHAR" property="revisionTime"/>
+        <result column="reviser" jdbcType="VARCHAR" property="reviser"/>
+    </resultMap>
+</mapper>

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

@@ -17,28 +17,27 @@
         <result column="feedback_result" jdbcType="VARCHAR" property="feedbackResult"/>
         <result column="state" jdbcType="INTEGER" property="state"/>
         <result column="consuming_time" jdbcType="LONGVARCHAR" property="consumingTime"/>
-        <result column="category_code" jdbcType="VARCHAR" property="categoryCode"/>
         <result column="reg_result" jdbcType="VARCHAR" property="regResult"/>
         <result column="feedback_user_org" jdbcType="VARCHAR" property="feedbackUserOrg"/>
         <result column="feedback_user_endpoint" jdbcType="VARCHAR" property="feedbackUserEndpoint"/>
     </resultMap>
 
 
-    <select id="selectTagCount" parameterType="cn.com.yusys.yusp.domain.vo.SmartTaggingResultVo">
+    <select id="selectTagCount" resultType="integer" parameterType="cn.com.yusys.yusp.domain.vo.SmartTaggingResultVo">
         SELECT
         COUNT(1) as totalCount
         FROM aitag_tag_log
-        <where>
+        WHERE
+            tag_scope = 0
             <if test="startTaggingTime != null and startTaggingTime != ''">
                 AND insert_time >= #{startTaggingTime}
             </if>
             <if test="endTaggingTime != null and endTaggingTime != ''">
                 AND #{endTaggingTime} >= insert_time
             </if>
-            <if test="categoryCode != null and categoryCode != ''">
-                AND #{categoryCode} = category_code
+            <if test="categoryId != null and categoryId != ''">
+                AND result @> #{categoryExp}::jsonb
             </if>
-        </where>
     </select>
 
     <select id="selectTagReportByDay" resultType="cn.com.yusys.yusp.domain.vo.IconResVo" parameterType="cn.com.yusys.yusp.domain.vo.SmartTaggingResultVo">
@@ -46,18 +45,18 @@
         DATE_FORMAT(insert_time, '%Y年%m月%d日') AS stat,
         COUNT(1) AS val
         FROM aitag_tag_log
-        <where>
+        WHERE
+        tag_scope = 0
             <if test="startTaggingTime != null and startTaggingTime != ''">
                 AND insert_time >= #{startTaggingTime}
             </if>
             <if test="endTaggingTime != null and endTaggingTime != ''">
                 AND #{endTaggingTime} >= insert_time
             </if>
-            <if test="categoryCode != null and categoryCode != ''">
-                AND #{categoryCode} = category_code
+            <if test="categoryId != null and categoryId != ''">
+                AND result @> #{categoryExp}::jsonb
             </if>
-        </where>
-        GROUP BY DATE(insert_time)
+        GROUP BY DATE_FORMAT(insert_time, '%Y年%m月%d日')
         ORDER BY stat;
     </select>
 
@@ -66,18 +65,18 @@
         DATE_FORMAT(insert_time, '%Y年%m月') AS stat,
         COUNT(1) AS val
         FROM aitag_tag_log
-        <where>
+        WHERE
+        tag_scope = 0
             <if test="startTaggingTime != null and startTaggingTime != ''">
                 AND insert_time >= #{startTaggingTime}
             </if>
             <if test="endTaggingTime != null and endTaggingTime != ''">
                 AND #{endTaggingTime} >= insert_time
             </if>
-            <if test="categoryCode != null and categoryCode != ''">
-                AND #{categoryCode} = category_code
+            <if test="categoryId != null and categoryId != ''">
+                AND result @> #{categoryExp}::jsonb
             </if>
-        </where>
-        GROUP BY DATE_FORMAT(insert_time, '%Y-%m')
+        GROUP BY DATE_FORMAT(insert_time, '%Y年%m月')
         ORDER BY stat;
     </select>
 
@@ -86,27 +85,28 @@
         YEARWEEK(insert_time, 1) AS stat,
         COUNT(1) AS val
         FROM aitag_tag_log
-        <where>
+        WHERE
+        tag_scope = 0
             <if test="startTaggingTime != null and  startTaggingTime != ''">
                 AND insert_time >= #{startTaggingTime}
             </if>
             <if test="endTaggingTime != null and  endTaggingTime != ''">
                 AND #{endTaggingTime} >= insert_time
             </if>
-            <if test="categoryCode != null and categoryCode != ''">
-                AND #{categoryCode} = category_code
+            <if test="categoryId != null and categoryId != ''">
+                AND result @> #{categoryExp}::jsonb
             </if>
-        </where>
         GROUP BY YEARWEEK(insert_time, 1)
         ORDER BY stat;
     </select>
 
     <select id="selectByInsertTime" resultType="cn.com.yusys.yusp.domain.entity.AitagTagLogEntity">
-        SELECT id, app_id, insert_time, business_attr, phrase, attachment, attachment_url, `result`, feedback_user_id, feedback_user_nm, feedback_time, feedback, feedback_result, state, consuming_time, category_code
+        SELECT id, app_id, insert_time, business_attr, phrase, attachment, attachment_url, `result`, feedback_user_id, feedback_user_nm, feedback_time, feedback, feedback_result, state, consuming_time
         FROM aitag_tag_log
-            where
-            DATE(insert_time) = #{insertTime}
-        AND state in ("2","3")
+        WHERE
+            tag_scope = 0
+        AND DATE(insert_time) = #{insertTime}
+        AND state in ('2','3')
     </select>
 
 </mapper>

+ 10 - 0
server/yusp-tagging-core/src/main/resources/mapper/AitagUserMapper.xml

@@ -0,0 +1,10 @@
+<?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.AitagUserMapper">
+
+    <select id="selectByUserId" resultType="cn.com.yusys.yusp.domain.entity.AitagUser">
+        SELECT * FROM aitag_user
+        WHERE user_id = #{userId}
+    </select>
+
+</mapper>

+ 10 - 1
server/yusp-tagging-core/src/main/resources/messages/yusp_input_msg.properties

@@ -97,4 +97,13 @@ REQUEST_PARAMETER_CANNOT_BE_EMPTY=\u8BF7\u6C42\u53C2\u6570\u4E0D\u80FD\u4E3A\u7A
 EXTENSION_FIELD_CANNOT_BE_EMPTY=\u6269\u5C55\u5B57\u6BB5\u4E0D\u80FD\u4E3A\u7A7A
 SUPPLEMENTAL_TABLE_CONFIG_NOT_EXIST=\u8865\u5F55\u8868\u914D\u7F6E\u4E0D\u5B58\u5728,\u8BF7\u786E\u8BA4\u540E\u518D\u64CD\u4F5C
 DATA_SOURCE_INFO_NOT_EXIST=\u5F53\u524D\u8868\u6570\u636E\u6E90\u4FE1\u606F\u4E0D\u5B58\u5728
-NO_DATA_PERIOD=\u8BE5\u7EDF\u8BA1\u5468\u671F\u6682\u672A\u5B9E\u73B0
+NO_DATA_PERIOD=\u8BE5\u7EDF\u8BA1\u5468\u671F\u6682\u672A\u5B9E\u73B0
+E001=\u6240\u5C5E\u5927\u7C7B\u4E0D\u80FD\u4E3A\u7A7A
+E002=\u4E0A\u4F20\u6587\u4EF6\u4E0D\u80FD\u4E3A\u7A7A
+E003=\u4EC5\u652F\u6301 .xlsx \u6216 .xls \u683C\u5F0F\u6587\u4EF6
+E004=Excel \u4E2D\u6CA1\u6709\u6709\u6548\u6570\u636E
+E005=\u53D1\u73B0\u91CD\u590D\u7684\u6807\u7B7E\u540D\u79F0:[{0}]
+E006=\u6821\u9A8C\u5931\u8D25\uFF1A\u6807\u7B7E [{0}] \u7684\u7236\u6807\u7B7E [{1}] \u4E0D\u5B58\u5728\u4E8E\u6587\u4EF6\u4E2D\u3002
+E007=\u68C0\u6D4B\u5230\u6807\u7B7E\u5C42\u7EA7\u73AF\u8DEF:{0}
+E008=\u8C03\u7528AI\u6253\u6807\u63A5\u53E3\u5931\u8D25
+E009=\u83B7\u53D6\u7528\u6237\u767B\u9646\u4FE1\u606F\u4E3A\u7A7A

TEMPAT SAMPAH
server/yusp-tagging-core/src/main/resources/template/tag_batch_Import_template.xlsx


+ 14 - 7
server/yusp-tagging-starter/pom.xml

@@ -14,6 +14,7 @@
     <version>1.0.0-SNAPSHOT</version>
     <packaging>jar</packaging>
 
+
     <dependencies>
         <!-- 依赖 core 模块 -->
         <dependency>
@@ -118,16 +119,22 @@
                     <version>5.2.24.RELEASE</version>
                 </dependency>-->
         <!-- MySQL JDBC Driver -->
+<!--        <dependency>-->
+<!--            <groupId>mysql</groupId>-->
+<!--            <artifactId>mysql-connector-java</artifactId>-->
+<!--            <version>8.0.33</version> &lt;!&ndash; 使用最新稳定版本 &ndash;&gt;-->
+<!--        </dependency>-->
+
         <dependency>
-            <groupId>mysql</groupId>
-            <artifactId>mysql-connector-java</artifactId>
-            <version>8.0.33</version> <!-- 使用最新稳定版本 -->
+            <groupId>cn.com.kingbase</groupId>
+            <artifactId>kingbase8</artifactId>
+            <version>9.0.0</version>
         </dependency>
         <!-- PostgreSQL 的 JDBC 驱动-->
-        <dependency>
-            <groupId>org.postgresql</groupId>
-            <artifactId>postgresql</artifactId>
-        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>org.postgresql</groupId>-->
+<!--            <artifactId>postgresql</artifactId>-->
+<!--        </dependency>-->
         <!-- HikariCP -->
         <dependency>
             <groupId>com.zaxxer</groupId>

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

@@ -7,6 +7,7 @@ import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
 
 import java.net.URL;
 
@@ -14,8 +15,11 @@ import java.net.URL;
 @SpringBootApplication(scanBasePackages = {"cn.com.yusys.yusp"})
 @MapperScan("cn.com.yusys.yusp.mapper")
 @EnableScheduling
+@EnableTransactionManagement
 public class App {
     public static void main(String[] args) {
+
+
         SpringApplication.run(App.class, args);
     }
 

+ 17 - 41
server/yusp-tagging-starter/src/main/resources/application.yml

@@ -1,49 +1,16 @@
 spring:
   cache:
     type: redis #缓存类型
-  main:
-    allow-bean-definition-overriding: true
-  redis:
-    database: 0 #Redis默认情况下有16个分片,这里配置具体使用的分片,默认是0
-    host: 10.192.72.13 #Redis地址
-    port: 36379 #Redis端口
-    password: 123456 #Redis密码
-    timeout: 10000 #Redis连接超时时间
-    lettuce:
-      shutdown-timeout: 60000ms #关闭超时时间
-      pool:
-        max-active: 20 #连接池最大连接数(使用负值表示没有限制) 默认 8
-        max-wait: 10000ms #连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
-        min-idle: 1 #连接池中的最小空闲连接 默认 0
-        max-idle: 20 #连接池中的最大空闲连接 默认 8
   application:
     jackson:
-      date-format: yyyy-MM-dd HH:mm:ss #日期格式
+      date-format: yyyy-MM-dd HH:mm:ss  # 您已有的配置
+      time-zone: GMT+8                  # 添加时区配置
       serialization:
-        INDENT_OUTPUT: true #是否格式化输出
-      default-property-inclusion: non_null #null不进行序列化
-#  datasource:
-#    driver-class-name: org.postgresql.Driver # PostgreSQL数据库连接驱动
-#    type: com.zaxxer.hikari.HikariDataSource # 数据库连接池类型
-#    url: jdbc:postgresql://10.192.72.13:5656/fjnx?currentSchema=ai_tag # PostgreSQL数据库地址及schema
-#    username: ai_tag # 数据库用户名
-#    password: 3edc$RFV # 数据库密码
-#    hikari:
-#      minimum-idle: 1 # 空闲时最小连接数
-#      maximum-pool-size: 20 # 连接池大小
-#      connection-test-query: SELECT 1 # 连接池验证查询
-
-  datasource:
-    driver-class-name: com.mysql.cj.jdbc.Driver #mysql数据库连接驱动
-    type: com.zaxxer.hikari.HikariDataSource #数据库连接池类型
-    url: jdbc:mysql://10.192.72.13:6780/fjnx?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&allowMultiQueries=true&useSSL=false #数据库地址
-    username: root #数据库用户名
-    password: 123456 #数据库密码(密文)
-    hikari:
-      minimum-idle: 1 #空闲时最小连接数
-      maximum-pool-size: 20 #连接池大小
-      connection-test-query: select 1 #连接池验证
-
+        write-dates-as-timestamps: false  # 确保日期以字符串形式序列化
+        INDENT_OUTPUT: true
+      deserialization:
+        fail-on-unknown-properties: false
+      default-property-inclusion: non_null
 
 license:
   licenseContext: <?xml version="1.0" encoding="UTF-8"?><license build-time="Tue Dec 29 13:26:00 CST 2020" validate-code="6A1B578E7FDEF76A57917A12BC359ED4"><element name="customer_name">上海银行股份有限公司</element><element name="contract_code">KJ2020-0038</element><element name="license_code">0000019279</element><element name="product_code">0000001122</element><element name="product_name_zh-cn">宇信科技基于微服务框架统一开发平台</element><element name="product_name_en-us">YUSP</element><element name="version_major">1</element><element name="version_sub">0</element><element name="version_publish">1</element><element name="complie_date">2018-03-20</element><element name="license_type">客户销售许可证</element><element name="license_start_time">2020-12-29</element><element name="license_end_time">2040-12-27</element></license>
@@ -56,4 +23,13 @@ management:
 
 mybatis-plus:
   configuration:
-    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  # 控制台输出
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  # 控制台输出
+
+# 认证配置
+auth:
+  enabled: false  # 认证开关,true为开启,false为关闭
+
+# JWT配置
+jwt:
+  secret: yusp-tagging-secret-key-for-jwt-token-generation-and-validation-2026
+  expiration: 86400000  # token过期时间(毫秒),默认24小时

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

@@ -1,4 +1,6 @@
 spring:
+  main:
+    allow-bean-definition-overriding: true
   application:
     name: tag-server
   cloud:
@@ -6,6 +8,8 @@ spring:
       discovery:
         server-addr: 10.192.72.13:38848
         namespace: ai-tagging
+        username: nacos
+        password: nacos
       config:
         server-addr: 10.192.72.13:38848
         namespace: ai-tagging
@@ -19,7 +23,5 @@ spring:
         extension-configs[1]:
           data-id: application-license.yml
           refresh: true #配置扩展属性动态刷新
-
-
 server:
   port: 30001