Forráskód Böngészése

专家库相关接口

zhangcl 14 órája
szülő
commit
cfb4b67270

+ 47 - 120
yudao-server/src/main/resources/application-local.yaml → randd-server/src/main/resources/application-local.yaml

@@ -1,18 +1,17 @@
 server:
 server:
-  port: 48080
+  port: 38080
 
 
 --- #################### 数据库相关配置 ####################
 --- #################### 数据库相关配置 ####################
+
 spring:
 spring:
+  #  autoconfigure:
+  #    exclude:
+  #      - org.springframework.ai.autoconfigure.vectorstore.qdrant.QdrantVectorStoreAutoConfiguration # 禁用 AI 模块的 Qdrant,手动创建
+  #      - org.springframework.ai.autoconfigure.vectorstore.milvus.MilvusVectorStoreAutoConfiguration # 禁用 AI 模块的 Milvus,手动创建
+  # 数据源配置项
   autoconfigure:
   autoconfigure:
     exclude:
     exclude:
       - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源
       - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源
-      # - org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration # 默认 local 环境,不开启 Quartz 的自动配置
-      - de.codecentric.boot.admin.server.config.AdminServerAutoConfiguration # 禁用 Spring Boot Admin 的 Server 的自动配置
-      - de.codecentric.boot.admin.server.ui.config.AdminServerUiAutoConfiguration # 禁用 Spring Boot Admin 的 Server UI 的自动配置
-      - de.codecentric.boot.admin.client.config.SpringBootAdminClientAutoConfiguration # 禁用 Spring Boot Admin 的 Client 的自动配置
-      - org.springframework.ai.autoconfigure.vectorstore.qdrant.QdrantVectorStoreAutoConfiguration # 禁用 AI 模块的 Qdrant,手动创建
-      - org.springframework.ai.autoconfigure.vectorstore.milvus.MilvusVectorStoreAutoConfiguration # 禁用 AI 模块的 Milvus,手动创建
-  # 数据源配置项
   datasource:
   datasource:
     druid: # Druid 【监控】相关的全局配置
     druid: # Druid 【监控】相关的全局配置
       web-stat-filter:
       web-stat-filter:
@@ -34,62 +33,41 @@ spring:
             multi-statement-allow: true
             multi-statement-allow: true
     dynamic: # 多数据源配置
     dynamic: # 多数据源配置
       druid: # Druid 【连接池】相关的全局配置
       druid: # Druid 【连接池】相关的全局配置
-        initial-size: 1 # 初始连接数
-        min-idle: 1 # 最小连接池数量
+        initial-size: 5 # 初始连接数
+        min-idle: 10 # 最小连接池数量
         max-active: 20 # 最大连接池数量
         max-active: 20 # 最大连接池数量
         max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒
         max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒
         time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒
         time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒
         min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒
         min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒
         max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒
         max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒
-        validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效
+        validation-query: SELECT 1 # 配置检测连接是否有效
         test-while-idle: true
         test-while-idle: true
         test-on-borrow: false
         test-on-borrow: false
         test-on-return: false
         test-on-return: false
       primary: master
       primary: master
       datasource:
       datasource:
         master:
         master:
-          url: jdbc:mysql://1.94.244.160:3306/rqiot?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例
-          #          url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true # MySQL Connector/J 5.X 连接的示例
-          #          url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro # PostgreSQL 连接的示例
-          #          url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
-          #          url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ruoyi-vue-pro;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true;useUnicode=true;characterEncoding=utf-8 # SQLServer 连接的示例
-          #          url: jdbc:dm://127.0.0.1:5236?schema=RUOYI_VUE_PRO # DM 连接的示例
-          #          url: jdbc:kingbase8://127.0.0.1:54321/test  # 人大金仓 KingbaseES 连接的示例
-          #          url: jdbc:postgresql://127.0.0.1:5432/postgres # OpenGauss 连接的示例
+          url: jdbc:mysql://127.0.0.1:3308/rqrd?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例
           username: root
           username: root
-          password: .N_Mdq!BR1W4
-          #          username: sa # SQL Server 连接的示例
-          #          password: Yudao@2024 # SQL Server 连接的示例
-          #          username: SYSDBA # DM 连接的示例
-          #          password: SYSDBA001 # DM 连接的示例
-          #          username: root # OpenGauss 连接的示例
-          #          password: Yudao@2024 # OpenGauss 连接的示例
-        slave: # 模拟从库,可根据自己需要修改
-          lazy: true # 开启懒加载,保证启动速度
-          url: jdbc:mysql://1.94.244.160:3306/rqiot?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true&nullCatalogMeansCurrent=true
-          username: root
-          password: .N_Mdq!BR1W4
-#        tdengine: # IoT 数据库(需要 IoT 物联网再开启噢!)
-#          url: jdbc:TAOS-RS://127.0.0.1:6041/ruoyi_vue_pro
-#          driver-class-name: com.taosdata.jdbc.rs.RestfulDriver
-#          username: root
-#          password: taosdata
-#          druid:
-#            validation-query: SELECT SERVER_STATUS() # TDengine 数据源的有效性检查 SQL
-
+          password: 123456
   # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
   # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
   redis:
   redis:
-    host: 127.0.0.1 # 地址
+    host: localhost # 地址
     port: 6379 # 端口
     port: 6379 # 端口
-    database: 0 # 数据库索引
-    password: 123456 # 密码,建议生产环境开启
+  #  username: default
+    database: 10  # 数据库索引
+    password: 123456
+
+mybatis-plus:
+  configuration:
+    log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
 
 
 --- #################### 定时任务相关配置 ####################
 --- #################### 定时任务相关配置 ####################
 
 
 # Quartz 配置项,对应 QuartzProperties 配置类
 # Quartz 配置项,对应 QuartzProperties 配置类
 spring:
 spring:
   quartz:
   quartz:
-    auto-startup: true # 本地开发环境,尽量不要开启 Job
+    auto-startup: true # 测试环境,需要开启 Job
     scheduler-name: schedulerName # Scheduler 名字。默认为 schedulerName
     scheduler-name: schedulerName # Scheduler 名字。默认为 schedulerName
     job-store-type: jdbc # Job 存储器类型。默认为 memory 表示内存,可选 jdbc 使用数据库。
     job-store-type: jdbc # Job 存储器类型。默认为 memory 表示内存,可选 jdbc 使用数据库。
     wait-for-jobs-to-complete-on-shutdown: true # 应用关闭时,是否等待定时任务执行完成。默认为 false ,建议设置为 true
     wait-for-jobs-to-complete-on-shutdown: true # 应用关闭时,是否等待定时任务执行完成。默认为 false ,建议设置为 true
@@ -126,8 +104,8 @@ spring:
   rabbitmq:
   rabbitmq:
     host: 127.0.0.1 # RabbitMQ 服务的地址
     host: 127.0.0.1 # RabbitMQ 服务的地址
     port: 5672 # RabbitMQ 服务的端口
     port: 5672 # RabbitMQ 服务的端口
-    username: rabbit # RabbitMQ 服务的账号
-    password: rabbit # RabbitMQ 服务的密码
+    username: guest # RabbitMQ 服务的账号
+    password: guest # RabbitMQ 服务的密码
   # Kafka 配置项,对应 KafkaProperties 配置类
   # Kafka 配置项,对应 KafkaProperties 配置类
   kafka:
   kafka:
     bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔
     bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔
@@ -165,36 +143,12 @@ spring:
 logging:
 logging:
   file:
   file:
     name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径
     name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径
-  level:
-    # 配置自己写的 MyBatis Mapper 打印日志
-    cn.iocoder.yudao.module.bpm.dal.mysql: debug
-    cn.iocoder.yudao.module.infra.dal.mysql: debug
-    cn.iocoder.yudao.module.infra.dal.mysql.logger.ApiErrorLogMapper: INFO # 配置 ApiErrorLogMapper 的日志级别为 info,避免和 GlobalExceptionHandler 重复打印
-    cn.iocoder.yudao.module.infra.dal.mysql.job.JobLogMapper: INFO # 配置 JobLogMapper 的日志级别为 info
-    cn.iocoder.yudao.module.infra.dal.mysql.file.FileConfigMapper: INFO # 配置 FileConfigMapper 的日志级别为 info
-    cn.iocoder.yudao.module.pay.dal.mysql: debug
-    cn.iocoder.yudao.module.pay.dal.mysql.notify.PayNotifyTaskMapper: INFO # 配置 PayNotifyTaskMapper 的日志级别为 info
-    cn.iocoder.yudao.module.system.dal.mysql: debug
-    cn.iocoder.yudao.module.system.dal.mysql.sms.SmsChannelMapper: INFO # 配置 SmsChannelMapper 的日志级别为 info
-    cn.iocoder.yudao.module.tool.dal.mysql: debug
-    cn.iocoder.yudao.module.member.dal.mysql: debug
-    cn.iocoder.yudao.module.trade.dal.mysql: debug
-    cn.iocoder.yudao.module.promotion.dal.mysql: debug
-    cn.iocoder.yudao.module.statistics.dal.mysql: debug
-    cn.iocoder.yudao.module.crm.dal.mysql: debug
-    cn.iocoder.yudao.module.erp.dal.mysql: debug
-    cn.iocoder.yudao.module.iot.dal.mysql: debug
-    cn.iocoder.yudao.module.iot.dal.tdengine: DEBUG
-    cn.iocoder.yudao.module.ai.dal.mysql: debug
-    org.springframework.context.support.PostProcessorRegistrationDelegate: ERROR # TODO 芋艿:先禁用,Spring Boot 3.X 存在部分错误的 WARN 提示
-
-debug: false
 
 
 --- #################### 钉微应用相关配置 ####################
 --- #################### 钉微应用相关配置 ####################
 dingtalk:
 dingtalk:
-  AGENT_ID: 3687646006  # DeepOil 微应用 agent_id
-  APP_KEY: dingmr9ez0ecgbmscfeb # 钉钉微应用 appkey
-  APP_SECRET: VhG_zMdTvIBwA_0Ef8FJ0foH3VYYo5T-kw0ukX_PBA8Ah1xl7AjDw5RVYCU0DTpe # 钉钉微应用 appkey
+  AGENT_ID: 4849455173  # DeepOil 微应用 agent_id
+  APP_KEY: dingixs2wmtiduibhkck # 钉钉微应用 appkey
+  APP_SECRET: jO2SP-gNS7LHt64THBPXmAaBxPh_S01JSePzdbszmLGH8MhQ_4Al0zQG3MZ-qihB # 钉钉微应用 appkey
   GET_ACCESS_TOKEN_URL: https://oapi.dingtalk.com/gettoken  # 获取access_token
   GET_ACCESS_TOKEN_URL: https://oapi.dingtalk.com/gettoken  # 获取access_token
   URL_GET_USERINFO_BYCODE: https://oapi.dingtalk.com/sns/getuserinfo_bycode # 通过二维码扫码获取UNIONID
   URL_GET_USERINFO_BYCODE: https://oapi.dingtalk.com/sns/getuserinfo_bycode # 通过二维码扫码获取UNIONID
   URL_GET_USERINFO_BYUNIONID: https://oapi.dingtalk.com/topapi/user/getbyunionid # 通过UNIONID获取用户信息
   URL_GET_USERINFO_BYUNIONID: https://oapi.dingtalk.com/topapi/user/getbyunionid # 通过UNIONID获取用户信息
@@ -203,40 +157,20 @@ dingtalk:
   URL_GET_SEND_MESSAGE: https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2 # 发送钉钉工作消息
   URL_GET_SEND_MESSAGE: https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2 # 发送钉钉工作消息
   URL_GET_USERINFO_BYMOBILE: https://oapi.dingtalk.com/topapi/v2/user/getbymobile # 根据用户手机号获取钉钉用户信息 url
   URL_GET_USERINFO_BYMOBILE: https://oapi.dingtalk.com/topapi/v2/user/getbymobile # 根据用户手机号获取钉钉用户信息 url
 
 
---- #################### SAP相关配置 ####################
-sap:
-  jco:
-    ashost: 172.17.25.120
-    sysnr: 00
-    client: 901
-    user: ZPMS
-    passwd: Kr2024.0
-    lang: zh
-    pool_capacity: 10
-    peak_limit: 20
---- #################### 微信公众号、小程序相关配置 ####################
-wx:
-  mp: # 公众号配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md 文档
-#    app-id: wx041349c6f39b268b # 测试号(牛希尧提供的)
-#    secret: 5abee519483bc9f8cb37ce280e814bd0
-    app-id: wx5b23ba7a5589ecbb # 测试号(自己的)
-    secret: 2a7b3b20c537e52e74afd395eb85f61f
-#    app-id: wxa69ab825b163be19 # 测试号(Kongdy 提供的)
-#    secret: bd4f9fab889591b62aeac0d7b8d8b4a0
+--- #################### 微信公众号相关配置 ####################
+wx: # 参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md 文档
+  mp:
+    # 公众号配置(必填)
+    app-id: wx041349c6f39b268b
+    secret: 5abee519483bc9f8cb37ce280e814bd0
     # 存储配置,解决 AccessToken 的跨节点的共享
     # 存储配置,解决 AccessToken 的跨节点的共享
     config-storage:
     config-storage:
       type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取
       type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取
       key-prefix: wx # Redis Key 的前缀
       key-prefix: wx # Redis Key 的前缀
       http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台
       http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台
   miniapp: # 小程序配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md 文档
   miniapp: # 小程序配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md 文档
-    #    appid: wx62056c0d5e8db250 # 测试号(牛希尧提供的)
-    #    secret: 333ae72f41552af1e998fe1f54e1584a
-#    appid: wx63c280fe3248a3e7 # wenhualian的接口测试号
-#    secret: 6f270509224a7ae1296bbf1c8cb97aed
-#    appid: wxc4598c446f8a9cb3 # 测试号(Kongdy 提供的)
-#    secret: 4a1a04e07f6a4a0751b39c3064a92c8b
-    appid: wx66186af0759f47c9 # 测试号(puhui 提供的)
-    secret: 3218bcbd112cbc614c7264ceb20144ac
+    appid: wx63c280fe3248a3e7
+    secret: 6f270509224a7ae1296bbf1c8cb97aed
     config-storage:
     config-storage:
       type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取
       type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取
       key-prefix: wa # Redis Key 的前缀
       key-prefix: wa # Redis Key 的前缀
@@ -247,34 +181,22 @@ wx:
 # 芋道配置项,设置当前项目所有自定义的配置
 # 芋道配置项,设置当前项目所有自定义的配置
 yudao:
 yudao:
   captcha:
   captcha:
-    enable: false # 本地环境,暂时关闭图片验证码,方便登录等接口的测试;
-  security:
-    mock-enable: true
+    enable: false
   pay:
   pay:
     order-notify-url: http://yunai.natapp1.cc/admin-api/pay/notify/order # 支付渠道的【支付】回调地址
     order-notify-url: http://yunai.natapp1.cc/admin-api/pay/notify/order # 支付渠道的【支付】回调地址
     refund-notify-url: http://yunai.natapp1.cc/admin-api/pay/notify/refund # 支付渠道的【退款】回调地址
     refund-notify-url: http://yunai.natapp1.cc/admin-api/pay/notify/refund # 支付渠道的【退款】回调地址
-    transfer-notify-url: http://yunai.natapp1.cc/admin-api/pay/notify/transfer # 支付渠道的【转账】回调地址
-  access-log: # 访问日志的配置项
-    enable: false
-  demo: false # 关闭演示模式
-  wxa-code:
-    env-version: develop # 小程序版本: 正式版为 "release";体验版为 "trial";开发版为 "develop"
-  wxa-subscribe-message:
-    miniprogram-state: developer # 跳转小程序类型:开发版为 “developer”;体验版为 “trial”为;正式版为 “formal”
+    transfer-notify-url: https://yunai.natapp1.cc/admin-api/pay/notify/transfer # 支付渠道的【转账】回调地址
+  demo: false # 开启演示模式
   tencent-lbs-key: TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E # QQ 地图的密钥 https://lbs.qq.com/service/staticV2/staticGuide/staticDoc
   tencent-lbs-key: TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E # QQ 地图的密钥 https://lbs.qq.com/service/staticV2/staticGuide/staticDoc
 
 
-portal:
-  secret: cc99d802-ce5c-5f62-b037-9a00726e7109
-
 justauth:
 justauth:
   enabled: true
   enabled: true
   type:
   type:
     DINGTALK: # 钉钉
     DINGTALK: # 钉钉
-      client-id: dingmr9ez0ecgbmscfeb
-      client-secret: VhG_zMdTvIBwA_0Ef8FJ0foH3VYYo5T-kw0ukX_PBA8Ah1xl7AjDw5RVYCU0DTpe
+      client-id: dingixs2wmtiduibhkck
+      client-secret: jO2SP-gNS7LHt64THBPXmAaBxPh_S01JSePzdbszmLGH8MhQ_4Al0zQG3MZ-qihB
       ignore-check-redirect-uri: true
       ignore-check-redirect-uri: true
       ignore-check-state: true
       ignore-check-state: true
-      redirect-uri: http://1.94.244.160:70
     WECHAT_ENTERPRISE: # 企业微信
     WECHAT_ENTERPRISE: # 企业微信
       client-id: wwd411c69a39ad2e54
       client-id: wwd411c69a39ad2e54
       client-secret: 1wTb7hYxnpT2TUbIeHGXGo7T0odav1ic10mLdyyATOw
       client-secret: 1wTb7hYxnpT2TUbIeHGXGo7T0odav1ic10mLdyyATOw
@@ -295,7 +217,12 @@ justauth:
     prefix: 'social_auth_state:' # 缓存前缀,目前只对 Redis 缓存生效,默认 JUSTAUTH::STATE::
     prefix: 'social_auth_state:' # 缓存前缀,目前只对 Redis 缓存生效,默认 JUSTAUTH::STATE::
     timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟
     timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟
 
 
---- #################### iot相关配置 TODO 芋艿【IOT】:再瞅瞅 ####################
+# 插件配置
 pf4j:
 pf4j:
-#  pluginsDir: /tmp/
-  pluginsDir: ../plugins
+  pluginsDir: ${user.home}/plugins # 插件目录
+system:
+  url: https://rdm.deepoil.cc/
+portal:
+  secret: 71ba46d3-3dd4-5232-9b7e-75765b36897f
+file:
+  upload-path: /rdfiles

+ 182 - 2
yudao-module-rd/yudao-module-rd-biz/src/main/java/cn/iocoder/yudao/module/rd/controller/admin/expertpool/ExpertPoolController.java

@@ -1,16 +1,26 @@
 package cn.iocoder.yudao.module.rd.controller.admin.expertpool;
 package cn.iocoder.yudao.module.rd.controller.admin.expertpool;
 
 
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
 import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.rd.controller.admin.expertpool.vo.EchelonExpertPoolRespVO;
 import cn.iocoder.yudao.module.rd.controller.admin.expertpool.vo.ExpertPoolPageReqVO;
 import cn.iocoder.yudao.module.rd.controller.admin.expertpool.vo.ExpertPoolPageReqVO;
 import cn.iocoder.yudao.module.rd.controller.admin.expertpool.vo.ExpertPoolRespVO;
 import cn.iocoder.yudao.module.rd.controller.admin.expertpool.vo.ExpertPoolRespVO;
 import cn.iocoder.yudao.module.rd.controller.admin.expertpool.vo.ExpertPoolSaveReqVO;
 import cn.iocoder.yudao.module.rd.controller.admin.expertpool.vo.ExpertPoolSaveReqVO;
+import cn.iocoder.yudao.module.rd.controller.admin.team.vo.TeamPageReqVO;
+import cn.iocoder.yudao.module.rd.controller.admin.team.vo.TeamRespVO;
 import cn.iocoder.yudao.module.rd.dal.dataobject.expertpool.ExpertPoolDO;
 import cn.iocoder.yudao.module.rd.dal.dataobject.expertpool.ExpertPoolDO;
+import cn.iocoder.yudao.module.rd.dal.dataobject.team.TeamDO;
 import cn.iocoder.yudao.module.rd.service.expertpool.ExpertPoolService;
 import cn.iocoder.yudao.module.rd.service.expertpool.ExpertPoolService;
+import cn.iocoder.yudao.module.rd.service.team.TeamService;
+import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
+import cn.iocoder.yudao.module.system.service.dict.DictDataService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -22,7 +32,8 @@ import javax.annotation.Resource;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpServletResponse;
 import javax.validation.Valid;
 import javax.validation.Valid;
 import java.io.IOException;
 import java.io.IOException;
-import java.util.List;
+import java.util.*;
+import java.util.stream.Collectors;
 
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -35,6 +46,10 @@ public class ExpertPoolController {
 
 
     @Resource
     @Resource
     private ExpertPoolService expertPoolService;
     private ExpertPoolService expertPoolService;
+    @Resource
+    private DictDataService dictDataService;
+    @Resource
+    private TeamService expertTeamService;
 
 
     @PostMapping("/create")
     @PostMapping("/create")
     @Operation(summary = "创建专家库")
     @Operation(summary = "创建专家库")
@@ -66,7 +81,114 @@ public class ExpertPoolController {
     @PreAuthorize("@ss.hasPermission('rd:expert-pool:query')")
     @PreAuthorize("@ss.hasPermission('rd:expert-pool:query')")
     public CommonResult<ExpertPoolRespVO> getExpertPool(@RequestParam("id") Long id) {
     public CommonResult<ExpertPoolRespVO> getExpertPool(@RequestParam("id") Long id) {
         ExpertPoolDO expertPool = expertPoolService.getExpertPool(id);
         ExpertPoolDO expertPool = expertPoolService.getExpertPool(id);
-        return success(BeanUtils.toBean(expertPool, ExpertPoolRespVO.class));
+        return success(buildDailyReport(expertPool));
+    }
+
+    /**
+     * 查询专家库 专家详情
+     * @param expertPool
+     * @return
+     */
+    private ExpertPoolRespVO buildDailyReport(ExpertPoolDO expertPool) {
+        // 如果 expertPool 为空 返回空对象
+        if (ObjUtil.isEmpty(expertPool)) {
+            return new ExpertPoolRespVO();
+        }
+        ExpertPoolRespVO expertPoolVO = BeanUtils.toBean(expertPool, ExpertPoolRespVO.class);
+
+        // 专家梯队 字典数据
+        Map<String, String> expertEchelonPair = getDictData("rd_expert_echelon");
+        // 专家序列 数据字典
+        Map<String, String> expertRankPair = getDictData("rd_expert_rank");
+        // 专家学历 数据字典
+        Map<String, String> expertEducationPair = getDictData("rd_expert_education");
+        // 软件技能 数据字典
+        Map<String, String> expertSoftwarePair = getDictData("rd_expert_software");
+        // 专业方向 数据字典
+        Map<String, String> expertTechnicalPair = getDictData("rd_expert_technical");
+        // 学历
+        String education = expertPoolVO.getEducation();
+        if (StrUtil.isNotBlank(education) && expertEducationPair.containsKey(education)) {
+            expertPoolVO.setEducationLabel(expertEducationPair.get(education));
+        }
+        // 梯队
+        String echelon = expertPoolVO.getEchelon();
+        if (StrUtil.isNotBlank(echelon) && expertEchelonPair.containsKey(echelon)) {
+            expertPoolVO.setEchelonLabel(expertEchelonPair.get(echelon));
+        }
+        // 专家技术序列
+        Set<Long> expertRankValues = expertPoolVO.getExpertRank();
+        if (CollUtil.isNotEmpty(expertRankValues)) {
+            String rankLabels = expertRankValues.stream()
+                    .map(lg -> ObjUtil.isNotEmpty(lg) ? lg.toString() : StrUtil.EMPTY) // 将Long转为String,匹配techniqueDictPair的key类型
+                    .map(key -> expertRankPair.getOrDefault(key, key)) // 取label,无则用原key
+                    .collect(Collectors.joining(",")); // 逗号拼接
+            expertPoolVO.setExpertRankLabel(rankLabels);
+        }
+        // 专家软件技能
+        Set<Long> expertSoftwareValues = expertPoolVO.getSoftwareSkills();
+        if (CollUtil.isNotEmpty(expertSoftwareValues)) {
+            String softwareLabels = expertSoftwareValues.stream()
+                    .map(lg -> ObjUtil.isNotEmpty(lg) ? lg.toString() : StrUtil.EMPTY) // 将Long转为String,匹配techniqueDictPair的key类型
+                    .map(key -> expertSoftwarePair.getOrDefault(key, key)) // 取label,无则用原key
+                    .collect(Collectors.joining(",")); // 逗号拼接
+            expertPoolVO.setSoftwareSkillsLabel(softwareLabels);
+        }
+        // 专家 专业方向
+        Set<Long> expertTechnicalValues = expertPoolVO.getSpecialDirection();
+        if (CollUtil.isNotEmpty(expertTechnicalValues)) {
+            String technicalLabels = expertTechnicalValues.stream()
+                    .map(lg -> ObjUtil.isNotEmpty(lg) ? lg.toString() : StrUtil.EMPTY) // 将Long转为String,匹配techniqueDictPair的key类型
+                    .map(key -> expertTechnicalPair.getOrDefault(key, key)) // 取label,无则用原key
+                    .collect(Collectors.joining(",")); // 逗号拼接
+            expertPoolVO.setSoftwareSkillsLabel(technicalLabels);
+        }
+        // 专家所属队伍
+        Set<Long> teamIds = expertPoolVO.getTeamIds();
+        if (CollUtil.isNotEmpty(teamIds)) {
+            TeamPageReqVO teamReqVO = new TeamPageReqVO();
+            teamReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+            teamReqVO.setTeamIds(teamIds);
+            PageResult<TeamDO> pageTeams = expertTeamService.getTeamPage(teamReqVO);
+            List<TeamDO> teams = pageTeams.getList();
+            if (CollUtil.isNotEmpty(teams)) {
+                List<TeamRespVO> teamResp = BeanUtils.toBean(teams, TeamRespVO.class);
+                expertPoolVO.setTeams(teamResp);
+            }
+        }
+        return expertPoolVO;
+    }
+
+    /**
+     * 根据数据字典类型获取数据字典值列表
+     * @param dictType
+     * @return
+     */
+    private Map<String, String> getDictData(String dictType) {
+        Map<String, String> dictDataPair = new HashMap<>();
+        List<DictDataDO> somethingDictData = dictDataService.getDictDataListByDictType(dictType);
+        if (CollUtil.isNotEmpty(somethingDictData)) {
+            somethingDictData.forEach(tech -> {
+                dictDataPair.put(tech.getValue(), tech.getLabel());
+            });
+        }
+        return dictDataPair;
+    }
+
+    /**
+     * 根据数据字典类型获取数据字典值排序
+     * @param dictType
+     * @return
+     */
+    private Map<String, Integer> getDictDataSort(String dictType) {
+        Map<String, Integer> dictDataPair = new HashMap<>();
+        List<DictDataDO> somethingDictData = dictDataService.getDictDataListByDictType(dictType);
+        if (CollUtil.isNotEmpty(somethingDictData)) {
+            somethingDictData.forEach(tech -> {
+                dictDataPair.put(tech.getValue(), tech.getSort());
+            });
+        }
+        return dictDataPair;
     }
     }
 
 
     @GetMapping("/page")
     @GetMapping("/page")
@@ -77,6 +199,64 @@ public class ExpertPoolController {
         return success(BeanUtils.toBean(pageResult, ExpertPoolRespVO.class));
         return success(BeanUtils.toBean(pageResult, ExpertPoolRespVO.class));
     }
     }
 
 
+
+    @GetMapping("/echelonExperts")
+    @Operation(summary = "将专家按照梯队汇总数据返回")
+    @PreAuthorize("@ss.hasPermission('rd:expert-pool:query')")
+    public CommonResult<List<EchelonExpertPoolRespVO>> echelonExperts(@Valid ExpertPoolPageReqVO pageReqVO) {
+        List<EchelonExpertPoolRespVO> result = new ArrayList<>();
+        // 查询所有专家后组装
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        PageResult<ExpertPoolDO> pageResult = expertPoolService.getExpertPoolPage(pageReqVO);
+        List<ExpertPoolDO> experts = pageResult.getList();
+        // key梯队数据字典value   value梯队包含的专家列表
+        Map<String, List<ExpertPoolDO>> echelonExpertPair = new HashMap<>();
+        // 专家梯队 字典数据 key值   value标签
+        Map<String, String> expertEchelonPair = getDictData("rd_expert_echelon");
+        // 专家梯队 字典数据 排序值 key值  value排序sort
+        Map<String, Integer> expertEchelonSortPair = getDictDataSort("rd_expert_echelon");
+        // 按照梯队对专家分组
+        if (CollUtil.isNotEmpty(experts)) {
+            experts.forEach(expert -> {
+                // 梯队
+                String echelon = expert.getEchelon();
+                if (expertEchelonPair.containsKey(echelon)) {
+                    String echelonLabel = expertEchelonPair.get(echelon);
+                    if (echelonExpertPair.containsKey(echelon)) {
+                        List<ExpertPoolDO> tempExperts = echelonExpertPair.get(echelon);
+                        tempExperts.add(expert);
+                        echelonExpertPair.put(echelon, tempExperts);
+                    } else {
+                        List<ExpertPoolDO> tempExperts = new ArrayList<>();
+                        tempExperts.add(expert);
+                        echelonExpertPair.put(echelon, tempExperts);
+                    }
+
+                }
+
+            });
+        }
+        if (CollUtil.isNotEmpty(echelonExpertPair)) {
+            echelonExpertPair.forEach((echelon, relatedExperts) -> {
+                EchelonExpertPoolRespVO expertPool = new EchelonExpertPoolRespVO();
+                if (expertEchelonPair.containsKey(echelon)) {
+                    String echelonLabel = expertEchelonPair.get(echelon);
+                    expertPool.setEchelonLabel(echelonLabel);
+                }
+                expertPool.setNum(relatedExperts.size());
+                expertPool.setExperts(relatedExperts);
+                // 设置各专家梯队的排序值
+                if (expertEchelonSortPair.containsKey(echelon)) {
+                    Integer echelonSort = expertEchelonSortPair.get(echelon);
+                    expertPool.setSort(echelonSort);
+                }
+                result.add(expertPool);
+            });
+            result.sort(Comparator.comparing(EchelonExpertPoolRespVO::getSort));
+        }
+        return success(result);
+    }
+
     @GetMapping("/export-excel")
     @GetMapping("/export-excel")
     @Operation(summary = "导出专家库 Excel")
     @Operation(summary = "导出专家库 Excel")
     @PreAuthorize("@ss.hasPermission('rd:expert-pool:export')")
     @PreAuthorize("@ss.hasPermission('rd:expert-pool:export')")

+ 27 - 0
yudao-module-rd/yudao-module-rd-biz/src/main/java/cn/iocoder/yudao/module/rd/controller/admin/expertpool/vo/EchelonExpertPoolRespVO.java

@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.module.rd.controller.admin.expertpool.vo;
+
+import cn.iocoder.yudao.module.rd.dal.dataobject.expertpool.ExpertPoolDO;
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+@Schema(description = "管理后台 - 专家库 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class EchelonExpertPoolRespVO {
+
+    @Schema(description = "梯队名称", example = "第一梯队")
+    private String echelonLabel;
+
+    @Schema(description = "梯队下包含的专家数量", example = "30")
+    private Integer num;
+
+    @Schema(description = "梯队排序值", example = "3")
+    private Integer sort;
+
+    @Schema(description = "梯队包含的专家列表", example = "")
+    private List<ExpertPoolDO> experts;
+
+}

+ 57 - 4
yudao-module-rd/yudao-module-rd-biz/src/main/java/cn/iocoder/yudao/module/rd/controller/admin/expertpool/vo/ExpertPoolRespVO.java

@@ -1,11 +1,14 @@
 package cn.iocoder.yudao.module.rd.controller.admin.expertpool.vo;
 package cn.iocoder.yudao.module.rd.controller.admin.expertpool.vo;
 
 
+import cn.iocoder.yudao.module.rd.controller.admin.team.vo.TeamRespVO;
 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
 import com.alibaba.excel.annotation.ExcelProperty;
 import com.alibaba.excel.annotation.ExcelProperty;
 import io.swagger.v3.oas.annotations.media.Schema;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 import lombok.Data;
 
 
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Set;
 
 
 @Schema(description = "管理后台 - 专家库 Response VO")
 @Schema(description = "管理后台 - 专家库 Response VO")
 @Data
 @Data
@@ -20,17 +23,33 @@ public class ExpertPoolRespVO {
     @ExcelProperty("所属部门")
     @ExcelProperty("所属部门")
     private Long deptId;
     private Long deptId;
 
 
+    @Schema(description = "专家姓名")
+    @ExcelProperty("专家姓名")
+    private String expertName;
+
     @Schema(description = "梯队(第一 第二 第三)")
     @Schema(description = "梯队(第一 第二 第三)")
     @ExcelProperty("梯队(第一 第二 第三)")
     @ExcelProperty("梯队(第一 第二 第三)")
     private String echelon;
     private String echelon;
 
 
     @Schema(description = "序列(技术 商务 运营 法务 安全)")
     @Schema(description = "序列(技术 商务 运营 法务 安全)")
     @ExcelProperty("序列(技术 商务 运营 法务 安全)")
     @ExcelProperty("序列(技术 商务 运营 法务 安全)")
-    private String expertRank;
+    private Set<Long> expertRank;
+
+    @Schema(description = "职称")
+    @ExcelProperty("职称")
+    private String professionalTitle;
+
+    @Schema(description = "岗位")
+    @ExcelProperty("岗位")
+    private String jobTitle;
+
+    @Schema(description = "历任岗位")
+    @ExcelProperty("历任岗位")
+    private String formerPost;
 
 
     @Schema(description = "所属团队(多个逗号分隔)")
     @Schema(description = "所属团队(多个逗号分隔)")
     @ExcelProperty("所属团队(多个逗号分隔)")
     @ExcelProperty("所属团队(多个逗号分隔)")
-    private String teamIds;
+    private Set<Long> teamIds;
 
 
     @Schema(description = "头像url")
     @Schema(description = "头像url")
     @ExcelProperty("头像url")
     @ExcelProperty("头像url")
@@ -40,13 +59,17 @@ public class ExpertPoolRespVO {
     @ExcelProperty("出生日期")
     @ExcelProperty("出生日期")
     private LocalDateTime birthday;
     private LocalDateTime birthday;
 
 
+    @Schema(description = "毕业院校")
+    @ExcelProperty("毕业院校")
+    private String school;
+
     @Schema(description = "学历")
     @Schema(description = "学历")
     @ExcelProperty("学历")
     @ExcelProperty("学历")
     private String education;
     private String education;
 
 
     @Schema(description = "专业方向(多个逗号分隔)")
     @Schema(description = "专业方向(多个逗号分隔)")
     @ExcelProperty("专业方向(多个逗号分隔)")
     @ExcelProperty("专业方向(多个逗号分隔)")
-    private String specialDirection;
+    private Set<Long> specialDirection;
 
 
     @Schema(description = "主要业绩")
     @Schema(description = "主要业绩")
     @ExcelProperty("主要业绩")
     @ExcelProperty("主要业绩")
@@ -54,7 +77,7 @@ public class ExpertPoolRespVO {
 
 
     @Schema(description = "专业软件技能")
     @Schema(description = "专业软件技能")
     @ExcelProperty("专业软件技能")
     @ExcelProperty("专业软件技能")
-    private String softwareSkills;
+    private Set<Long> softwareSkills;
 
 
     @Schema(description = "排序值")
     @Schema(description = "排序值")
     @ExcelProperty("排序值")
     @ExcelProperty("排序值")
@@ -84,4 +107,34 @@ public class ExpertPoolRespVO {
     @ExcelProperty("创建时间")
     @ExcelProperty("创建时间")
     private LocalDateTime createTime;
     private LocalDateTime createTime;
 
 
+    /**
+     * 扩展字段
+     */
+    @Schema(description = "专业软件技能 label")
+    @ExcelProperty("专业软件技能 label")
+    private String softwareSkillsLabel;
+
+    @Schema(description = "专家序列 label")
+    @ExcelProperty("专家序列 label")
+    private String expertRankLabel;
+
+    @Schema(description = "专家所属团队 label")
+    @ExcelProperty("专家所属团队 label")
+    private String teamsLabel;
+
+    @Schema(description = "专家所属团队列表")
+    private List<TeamRespVO> teams;
+
+    @Schema(description = "专业方向 label")
+    @ExcelProperty("专业方向 label")
+    private String specialDirectionLabel;
+
+    @Schema(description = "学历 label")
+    @ExcelProperty("学历 label")
+    private String educationLabel;
+
+    @Schema(description = "梯队 label")
+    @ExcelProperty("梯队 label")
+    private String echelonLabel;
+
 }
 }

+ 20 - 4
yudao-module-rd/yudao-module-rd-biz/src/main/java/cn/iocoder/yudao/module/rd/controller/admin/expertpool/vo/ExpertPoolSaveReqVO.java

@@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 import lombok.Data;
 
 
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
+import java.util.Set;
 
 
 @Schema(description = "管理后台 - 专家库新增/修改 Request VO")
 @Schema(description = "管理后台 - 专家库新增/修改 Request VO")
 @Data
 @Data
@@ -15,14 +16,26 @@ public class ExpertPoolSaveReqVO {
     @Schema(description = "所属部门", example = "30265")
     @Schema(description = "所属部门", example = "30265")
     private Long deptId;
     private Long deptId;
 
 
+    @Schema(description = "专家姓名")
+    private String expertName;
+
     @Schema(description = "梯队(第一 第二 第三)")
     @Schema(description = "梯队(第一 第二 第三)")
     private String echelon;
     private String echelon;
 
 
     @Schema(description = "序列(技术 商务 运营 法务 安全)")
     @Schema(description = "序列(技术 商务 运营 法务 安全)")
-    private String expertRank;
+    private Set<Long> expertRank;
+
+    @Schema(description = "职称")
+    private String professionalTitle;
+
+    @Schema(description = "岗位")
+    private String jobTitle;
+
+    @Schema(description = "历任岗位")
+    private String formerPost;
 
 
     @Schema(description = "所属团队(多个逗号分隔)")
     @Schema(description = "所属团队(多个逗号分隔)")
-    private String teamIds;
+    private Set<Long> teamIds;
 
 
     @Schema(description = "头像url")
     @Schema(description = "头像url")
     private String avatar;
     private String avatar;
@@ -30,17 +43,20 @@ public class ExpertPoolSaveReqVO {
     @Schema(description = "出生日期")
     @Schema(description = "出生日期")
     private LocalDateTime birthday;
     private LocalDateTime birthday;
 
 
+    @Schema(description = "毕业院校")
+    private String school;
+
     @Schema(description = "学历")
     @Schema(description = "学历")
     private String education;
     private String education;
 
 
     @Schema(description = "专业方向(多个逗号分隔)")
     @Schema(description = "专业方向(多个逗号分隔)")
-    private String specialDirection;
+    private Set<Long> specialDirection;
 
 
     @Schema(description = "主要业绩")
     @Schema(description = "主要业绩")
     private String achievement;
     private String achievement;
 
 
     @Schema(description = "专业软件技能")
     @Schema(description = "专业软件技能")
-    private String softwareSkills;
+    private Set<Long> softwareSkills;
 
 
     @Schema(description = "排序值")
     @Schema(description = "排序值")
     private Integer sort;
     private Integer sort;

+ 6 - 0
yudao-module-rd/yudao-module-rd-biz/src/main/java/cn/iocoder/yudao/module/rd/controller/admin/team/vo/TeamPageReqVO.java

@@ -8,6 +8,7 @@ import lombok.ToString;
 import org.springframework.format.annotation.DateTimeFormat;
 import org.springframework.format.annotation.DateTimeFormat;
 
 
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
+import java.util.Collection;
 
 
 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 
 
@@ -45,4 +46,9 @@ public class TeamPageReqVO extends PageParam {
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     private LocalDateTime[] createTime;
     private LocalDateTime[] createTime;
 
 
+    /**
+     * 扩展字段
+     */
+    @Schema(description = "专家所属团队id集合", example = "222,75")
+    private Collection<Long> teamIds;
 }
 }

+ 32 - 5
yudao-module-rd/yudao-module-rd-biz/src/main/java/cn/iocoder/yudao/module/rd/dal/dataobject/expertpool/ExpertPoolDO.java

@@ -2,18 +2,21 @@ package cn.iocoder.yudao.module.rd.dal.dataobject.expertpool;
 
 
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 import com.baomidou.mybatisplus.annotation.KeySequence;
 import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
 import lombok.*;
 import lombok.*;
 
 
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
+import java.util.Set;
 
 
 /**
 /**
  * 专家库 DO
  * 专家库 DO
  *
  *
  * @author ruiqi
  * @author ruiqi
  */
  */
-@TableName("rd_expert_pool")
+@TableName(value="rd_expert_pool", autoResultMap = true)
 @KeySequence("rd_expert_pool_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
 @KeySequence("rd_expert_pool_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
 @Data
 @Data
 @EqualsAndHashCode(callSuper = true)
 @EqualsAndHashCode(callSuper = true)
@@ -32,6 +35,10 @@ public class ExpertPoolDO extends BaseDO {
      * 所属部门
      * 所属部门
      */
      */
     private Long deptId;
     private Long deptId;
+    /**
+     * 专家姓名
+     */
+    private String expertName;
     /**
     /**
      * 梯队(第一 第二 第三)
      * 梯队(第一 第二 第三)
      */
      */
@@ -39,11 +46,25 @@ public class ExpertPoolDO extends BaseDO {
     /**
     /**
      * 序列(技术 商务 运营 法务 安全)
      * 序列(技术 商务 运营 法务 安全)
      */
      */
-    private String expertRank;
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private Set<Long> expertRank;
+    /**
+     * 职称
+     */
+    private String professionalTitle;
+    /**
+     * 岗位
+     */
+    private String jobTitle;
+    /**
+     * 历任岗位
+     */
+    private String formerPost;
     /**
     /**
      * 所属团队(多个逗号分隔)
      * 所属团队(多个逗号分隔)
      */
      */
-    private String teamIds;
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private Set<Long> teamIds;
     /**
     /**
      * 头像url
      * 头像url
      */
      */
@@ -52,6 +73,10 @@ public class ExpertPoolDO extends BaseDO {
      * 出生日期
      * 出生日期
      */
      */
     private LocalDateTime birthday;
     private LocalDateTime birthday;
+    /**
+     * 毕业院校
+     */
+    private String school;
     /**
     /**
      * 学历
      * 学历
      */
      */
@@ -59,7 +84,8 @@ public class ExpertPoolDO extends BaseDO {
     /**
     /**
      * 专业方向(多个逗号分隔)
      * 专业方向(多个逗号分隔)
      */
      */
-    private String specialDirection;
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private Set<Long> specialDirection;
     /**
     /**
      * 主要业绩
      * 主要业绩
      */
      */
@@ -67,7 +93,8 @@ public class ExpertPoolDO extends BaseDO {
     /**
     /**
      * 专业软件技能
      * 专业软件技能
      */
      */
-    private String softwareSkills;
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private Set<Long> softwareSkills;
     /**
     /**
      * 排序值
      * 排序值
      */
      */

+ 1 - 0
yudao-module-rd/yudao-module-rd-biz/src/main/java/cn/iocoder/yudao/module/rd/dal/mysql/team/TeamMapper.java

@@ -18,6 +18,7 @@ public interface TeamMapper extends BaseMapperX<TeamDO> {
     default PageResult<TeamDO> selectPage(TeamPageReqVO reqVO) {
     default PageResult<TeamDO> selectPage(TeamPageReqVO reqVO) {
         return selectPage(reqVO, new LambdaQueryWrapperX<TeamDO>()
         return selectPage(reqVO, new LambdaQueryWrapperX<TeamDO>()
                 .eqIfPresent(TeamDO::getDeptId, reqVO.getDeptId())
                 .eqIfPresent(TeamDO::getDeptId, reqVO.getDeptId())
+                .inIfPresent(TeamDO::getId, reqVO.getTeamIds())
                 .eqIfPresent(TeamDO::getCategory, reqVO.getCategory())
                 .eqIfPresent(TeamDO::getCategory, reqVO.getCategory())
                 .likeIfPresent(TeamDO::getTeamName, reqVO.getTeamName())
                 .likeIfPresent(TeamDO::getTeamName, reqVO.getTeamName())
                 .eqIfPresent(TeamDO::getAvatar, reqVO.getAvatar())
                 .eqIfPresent(TeamDO::getAvatar, reqVO.getAvatar())