application.yml 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. server:
  2. port: 9082
  3. tomcat:
  4. headers:
  5. X-Content-Type-Options: nosniff
  6. X-Frame-Options: DENY
  7. X-XSS-Protection: 1; mode=block
  8. Strict-Transport-Security: max-age=31536000; includeSubDomains
  9. spring:
  10. servlet:
  11. multipart:
  12. max-file-size: 50MB
  13. max-request-size: 50MB
  14. application:
  15. name: cfc-backend
  16. datasource:
  17. driver-class-name: com.mysql.cj.jdbc.Driver
  18. url: jdbc:mysql://192.168.16.251:3306/zxyj?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true&createDatabaseIfNotExist=true
  19. username: zxyj
  20. password: zxyj@123
  21. hikari:
  22. maximum-pool-size: 50
  23. minimum-idle: 10
  24. connection-timeout: 30000
  25. idle-timeout: 600000
  26. max-lifetime: 1800000
  27. pool-name: CfcHikariPool
  28. redis:
  29. host: ${REDIS_HOST:localhost}
  30. port: ${REDIS_PORT:6379}
  31. password: ${REDIS_PASSWORD:}
  32. timeout: 3000ms
  33. lettuce:
  34. pool:
  35. max-active: 8
  36. max-idle: 8
  37. min-idle: 0
  38. sfms:
  39. datasource:
  40. enabled: false # 本地开发禁用 SFMS 数据源,需要迁移时改为 true
  41. driver-class-name: com.mysql.cj.jdbc.Driver
  42. url: jdbc:mysql://192.168.16.251:3306/zxyj?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true&createDatabaseIfNotExist=true
  43. username: zxyj
  44. password: zxyj@123
  45. mybatis-plus:
  46. mapper-locations: classpath*:/mapper/**/*.xml
  47. type-aliases-package: com.etotem.cfc.entity
  48. configuration:
  49. map-underscore-to-camel-case: true
  50. log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
  51. global-config:
  52. db-config:
  53. id-type: auto
  54. logic-delete-field: deleted
  55. logic-delete-value: 1
  56. logic-not-delete-value: 0
  57. jwt:
  58. secret: ${JWT_SECRET:cfc-prod-jwt-secret-2026-keep-it-safe!}
  59. # 30 天(2592000000ms)。配合小程序端 wx.login 静默续期(/api/auth/silent-login),
  60. # 用户几乎无需手动重新登录。
  61. # 安全前提:续期只能走 code2Session(微信签发的单次 code,能证明设备持有),
  62. # 严禁恢复「裸 openid 换 token」——那等于任何拿到 openid 的人都能冒充该账号。
  63. expiration: 2592000000
  64. zkxz:
  65. enabled: false
  66. sync-api-url: https://api.zkxz.org.cn/api/
  67. login-url: member/login
  68. sync-client-url: user/create
  69. list-client-url: user/list
  70. sync-teacher-url: teacher/create
  71. user-report: user/report
  72. report-info: report/info
  73. zx-user: ""
  74. zx-pass: ""
  75. wechat:
  76. appid: wx5ba8038ef16fb245
  77. secret: ${WECHAT_SECRET:dev-only-wechat-secret}
  78. mch-id: 1703255039
  79. mch-key: ${WECHAT_MCH_KEY:dev-only-mch-key}
  80. api-v3-key: ${WECHAT_API_V3_KEY:dev-only-api-v3-key}
  81. mch-serial-no: 53C2A906094D725BC350A3414AADCA6D79882AAF
  82. private-key-path: cert/apiclient_key.pem
  83. notify-url: http://cfc.bianwoyou.com.cn/api/payment/notify
  84. login-url: https://api.weixin.qq.com/sns/jscode2session
  85. phone-url: https://api.weixin.qq.com/wxa/business/getuserphonenumber
  86. test-mode: true # 测试模式:跳过微信 API 调用,使用模拟数据
  87. appkey: ${WECHAT_APPKEY:cXqYJseX2MUaRM5kVHLQRskw5l5ZrDNo} # 虚拟支付 AppKey 现网(环境变量可覆盖)
  88. sandbox-appkey: ${WECHAT_SANDBOX_APPKEY:sKcsYR0e9T603wvD5yFcvISBcFLh3TXH} # 虚拟支付 AppKey 沙箱(环境变量可覆盖)
  89. virtual-pay-env: ${WECHAT_VIRTUAL_PAY_ENV:0} # 0=现网 1=沙箱
  90. virtual-pay-token: ${WECHAT_VIRTUAL_PAY_TOKEN:cfcVirtualPay2026} # 虚拟支付消息推送 Token(与小程序后台消息推送配置一致)
  91. offer-id: ${WECHAT_VIRTUAL_PAY_OFFER_ID:1450607643} # 虚拟支付应用ID(mp-支付基础配置中的 offerId;productId 才是道具ID)
  92. test-phone: "13800138000" # 测试模式使用的手机号
  93. alert-template-id: ${WECHAT_ALERT_TEMPLATE_ID:}
  94. promotion-tier-template-id: ${WECHAT_PROMOTION_TIER_TEMPLATE_ID:}
  95. # 小程序码环境:dev=development / test=trial / prod=release
  96. env-version: ${WECHAT_ENV_VERSION:release}
  97. dify:
  98. base-url: ${DIFY_BASE_URL:http://dify.bianwoyou.cn/v1}
  99. api-key: ${DIFY_API_KEY:app-dev-only-key}
  100. nutrition-api-key: ${DIFY_NUTRITION_API_KEY:app-dev-only-nutrition-key}
  101. emotion-api-key: "" # 照片情绪识别,空字符串=mock模式
  102. bodyfat-scale:
  103. image-dir: ${BODYFAT_SCALE_IMAGE_DIR:docs/参考资料/体脂秤}
  104. deepseek:
  105. vision-api-key: ${DEEPSEEK_VISION_API_KEY:""} # DeepSeek-VL 视觉模型 API Key,空=mock模式
  106. vision-base-url: ${DEEPSEEK_VISION_BASE_URL:https://api.deepseek.com/v1}
  107. callback-secret: ${DIFY_CALLBACK_SECRET:dev-only-callback-secret}
  108. python:
  109. executable: python
  110. enabled: true
  111. base-url: https://ai.etotem.com.cn
  112. timeout-ms: 15000
  113. # LLM 推理可达 30-60s(画像/问卷更长),read 超时必须覆盖推理耗时,connect 超时才用 timeout-ms
  114. read-timeout-ms: 300000 # menu/generate 等长推理任务可达 120s,5 分钟兜底
  115. circuit-breaker:
  116. failure-threshold: 3
  117. reset-timeout-ms: 30000
  118. langgraph:
  119. # LangGraph 报告解析服务(健康报告 PDF → 结构化 JSON)
  120. # 开发环境默认 localhost,生产环境指向 ai.etotem.com.cn
  121. # TODO(部署): 容器化时需确保 uploads/health-reports 对 LangGraph 容器可见
  122. base-url: ${LANGGRAPH_BASE_URL:http://localhost:9000}
  123. profile-timeout-ms: 90000 # 画像生成推理可达 30-60s,独立超时
  124. report:
  125. collect:
  126. # 健康报告异步采集:未命中指纹脚本时交本地 opencode 服务解析
  127. # 启动命令见根 AGENTS.md:opencode web --port 4090 --hostname 127.0.0.1
  128. opencode-base: ${OPENCODE_BASE:http://127.0.0.1:4090}
  129. opencode-user: opencode
  130. opencode-password: ${OPENCODE_ADMIN_PASSWORD:IwinTrue@123}
  131. opencode-workdir: ${OPENCODE_WORKDIR:/app/cfc}
  132. # provider-id 必须与 GET /config/providers 返回的 id 完全一致(本机为 agnes,不是 agnes-ai)
  133. # 模型只在 prompt_async 请求体生效;勿用 opencode/big-pickle(免费额度限流,会空转超时)
  134. opencode-model-provider: ${OPENCODE_MODEL_PROVIDER:agnes}
  135. opencode-model-id: ${OPENCODE_MODEL_ID:agnes-2.5-flash}
  136. opencode-agent: ${OPENCODE_AGENT:build}
  137. math:
  138. verify-mode: dify # dify | eval; dify=走Dify工作流, eval=服务端计算(兜底)
  139. workflow-id: "" # Dify 数学判题工作流 ID(留空则使用 eval 兜底)
  140. upload:
  141. base-dir: /data/cfc-uploads
  142. allowed-types: image/jpeg,image/png,image/gif,image/webp,application/pdf
  143. storage:
  144. type: jdcloud # jdcloud | local
  145. jdcloud:
  146. endpoint: s3.cn-north-1.jdcloud-oss.com
  147. access-key: JDC_F351EC3CB1F8593204ABCDA2CBF2
  148. secret-key: 970C0C6985A6BF29D0C79AE3693B9899
  149. bucket: cfc
  150. region: cn-north-1
  151. shop:
  152. order:
  153. payment-timeout-minutes: 30 # 订单超时时间(分钟)
  154. virtual-pay:
  155. payment-timeout-minutes: 30 # 虚拟支付订单超时时间(分钟)
  156. logging:
  157. level:
  158. com.etotem.cfc: debug
  159. # 应用配置
  160. app:
  161. init-test-data: false # 是否初始化测试/种子数据,生产环境应关闭
  162. # Admin 登录配置
  163. admin:
  164. skip-captcha: true # 测试环境跳过验证码,方便自动化测试
  165. ai:
  166. prompts:
  167. questionnaire-version: "1"
  168. questionnaire-parent: |
  169. 你是一位专业的家庭关系评估顾问,擅长设计温暖、不具威胁性的关系问卷。
  170. 你的任务是为填写者设计一份关系评估问卷,了解填写者与被评估成员之间的关系质量。
  171. ## 基本信息
  172. - 填写者(答卷人):{respondent_name},{respondent_gender},{respondent_age}岁,星座:{respondent_zodiac}
  173. - 被评估成员:{member_name},{member_gender},{member_age}岁,星座:{member_zodiac}
  174. - 你(填写者)与被评估成员的关系:{relationship_desc}
  175. - 家庭基本情况:{family_context}
  176. ## 角色与任务
  177. 填写者是家长,被评估成员是其孩子。家长对子女的关系感知是评估的重点。
  178. 请生成 **15-18 道**情境化题目,涵盖三个维度,每个维度约 5-6 题:
  179. ### 信任维度(trust)
  180. 从以下间接角度设计题目:
  181. - 遇到困难时是否愿意向对方求助
  182. - 是否会向对方分享不愿让他人知道的事
  183. - 与对方相处时是否感到安全、不被评判
  184. - 对方是否值得信赖(守承诺、不泄露隐私等)
  185. - 犯错后是否担心对方的反应
  186. ### 亲密维度(intimacy)
  187. 从以下间接角度设计题目:
  188. - 是否愿意与对方共处(无需说话也能舒适)
  189. - 对方是否是你情绪低落时的"避风港"
  190. - 是否愿意与对方分享个人感受
  191. - 对方是否让你感到被理解和接纳
  192. - 是否觉得对方是"最懂你的人"之一
  193. ### 沟通维度(communication)
  194. 从以下间接角度设计题目:
  195. - 意见不合时是否能平静沟通
  196. - 对方是否认真倾听,而非急于评判或给建议
  197. - 是否能自然表达自己的真实想法
  198. - 对方是否经常打断你或没听完就下结论
  199. - 是否觉得你们之间有"说不出口"的话题
  200. ## 题目设计要求
  201. 1. **情境化**:用具体场景代替抽象问法(如:"当你遇到困难时..." 而非 "你是否信任对方")
  202. 2. **温暖语气**:避免让填写者感到被审判,用"你是否觉得...""你是否愿意..."
  203. 3. **选项差异化**:4-5 个选项,描述具体行为或感受
  204. 4. **反向计分题**:至少 3 道题设置 direction="negative",用于检测答题一致性
  205. 5. **覆盖双方画像**:如有星座、年龄差距等信息,可在题目中适度融入(如"青春期""代沟"等)
  206. ## 返回格式(严格 JSON,无其他内容)
  207. {{
  208. "version": 1,
  209. "questions": [
  210. {{
  211. "id": "q1",
  212. "dimension": "trust",
  213. "direction": "positive",
  214. "weight": 1.0,
  215. "text": "题目文字",
  216. "options": [
  217. {{"id": "a", "score": 0}},
  218. {{"id": "b", "score": 1}},
  219. {{"id": "c", "score": 2}},
  220. {{"id": "d", "score": 3}}
  221. ]
  222. }}
  223. ]
  224. }}
  225. 确保 JSON 格式正确,所有题目覆盖三个维度,共 15-18 题。
  226. questionnaire-child: |
  227. 你是一位专业的家庭关系评估顾问,擅长设计温暖、不具威胁性的关系问卷。
  228. 你的任务是为填写者设计一份关系评估问卷,了解填写者与被评估成员之间的关系质量。
  229. ## 基本信息
  230. - 填写者(答卷人):{respondent_name},{respondent_gender},{respondent_age}岁,星座:{respondent_zodiac}
  231. - 被评估成员:{member_name},{member_gender},{member_age}岁,星座:{member_zodiac}
  232. - 你(填写者)与被评估成员的关系:{relationship_desc}
  233. - 家庭基本情况:{family_context}
  234. ## 角色与任务
  235. 填写者是孩子,被评估成员是其家长。孩子对家长的关系感知是评估的重点。
  236. 请生成 **15-18 道**情境化题目,涵盖三个维度,每个维度约 5-6 题:
  237. ### 信任维度(trust)
  238. 从以下间接角度设计题目:
  239. - 遇到困难时是否愿意向对方求助
  240. - 是否会向对方分享不愿让他人知道的事
  241. - 与对方相处时是否感到安全、不被评判
  242. - 对方是否值得信赖(守承诺、不泄露隐私等)
  243. - 犯错后是否担心对方的反应
  244. ### 亲密维度(intimacy)
  245. 从以下间接角度设计题目:
  246. - 是否愿意与对方共处(无需说话也能舒适)
  247. - 对方是否是你情绪低落时的"避风港"
  248. - 是否愿意与对方分享个人感受
  249. - 对方是否让你感到被理解和接纳
  250. - 是否觉得对方是"最懂你的人"之一
  251. ### 沟通维度(communication)
  252. 从以下间接角度设计题目:
  253. - 意见不合时是否能平静沟通
  254. - 对方是否认真倾听,而非急于评判或给建议
  255. - 是否能自然表达自己的真实想法
  256. - 对方是否经常打断你或没听完就下结论
  257. - 是否觉得你们之间有"说不出口"的话题
  258. ## 题目设计要求
  259. 1. **情境化**:用具体场景代替抽象问法(如:"当你遇到困难时..." 而非 "你是否信任对方")
  260. 2. **温暖语气**:避免让填写者感到被审判,用"你是否觉得...""你是否愿意..."
  261. 3. **选项差异化**:4-5 个选项,描述具体行为或感受
  262. 4. **反向计分题**:至少 3 道题设置 direction="negative",用于检测答题一致性
  263. 5. **覆盖双方画像**:如有星座、年龄差距等信息,可在题目中适度融入(如"青春期""代沟"等)
  264. ## 返回格式(严格 JSON,无其他内容)
  265. {{
  266. "version": 1,
  267. "questions": [
  268. {{
  269. "id": "q1",
  270. "dimension": "trust",
  271. "direction": "positive",
  272. "weight": 1.0,
  273. "text": "题目文字",
  274. "options": [
  275. {{"id": "a", "score": 0}},
  276. {{"id": "b", "score": 1}},
  277. {{"id": "c", "score": 2}},
  278. {{"id": "d", "score": 3}}
  279. ]
  280. }}
  281. ]
  282. }}
  283. 确保 JSON 格式正确,所有题目覆盖三个维度,共 15-18 题。
  284. tongue-system: |
  285. 你是资深中医舌诊专家。根据用户上传的舌象图片,输出结构化 JSON,不要输出任何 JSON 之外的文字。indicators 数组的 code 字段必须严格从以下 7 个值中选择,禁止自创或改写:tongue_color(舌色)、coating_color(苔色)、coating_texture(苔质)、fissure(裂纹)、teeth_mark(齿痕)、sublingual_vein(舌下络脉)、constitution(体质)。JSON 格式:{"overall_assessment": "整体舌象评估结论", "indicators": [{"code": "tongue_color", "value": "淡红"}, {"code": "coating_color", "value": "薄白"}]}指标值用简短中文描述,如舌色「淡红」、苔色「薄白」、裂纹「无」、齿痕「轻」。