feat(认证/通知): 单设备登录互踢 + 站内通知铃铛系统

- 单设备登录:登录成功即 last-login-wins 绑定 users.machine;非超管旧 token
  在下一次受保护请求抛 4011 下线,超管豁免;仅认 token 内签名 deviceId,不用请求头。
  前端两端接入踢下线跳转(?kicked=1 提示),V118 清空历史 machine
- 站内通知:新增 notification 模块(任务失败扫描 / 密钥欠费 / 下游服务探测三类来源),
  前后台铃铛组件 + 轮询;后台列表按主管数据范围(UserDataScopeSupport)过滤;V116 建表

均已于 2026-09-13 部署上线,此次补提交源码(此前仅存在于已部署 JAR/构建产物中)
This commit is contained in:
2026-09-13 23:08:22 +08:00
parent a0f6582914
commit b70557a077
53 changed files with 3982 additions and 101 deletions
@@ -318,6 +318,22 @@ aiimage:
jikip-balance-url: ${AIIMAGE_USER_SECRET_JIKIP_BALANCE_URL:https://api.jikip.com/find-balance}
jikip-plan-id: ${AIIMAGE_USER_SECRET_JIKIP_PLAN_ID:}
jikip-user-id: ${AIIMAGE_USER_SECRET_JIKIP_USER_ID:}
# 巡检发现欠费/密钥失效时是否推送站内通知(铃铛)
notify-enabled: ${AIIMAGE_USER_SECRET_NOTIFY_ENABLED:true}
# 站内通知(铃铛):任务失败扫描 + 下游服务健康探测
notification:
scan-enabled: ${AIIMAGE_NOTIFICATION_SCAN_ENABLED:true}
scan-interval-ms: ${AIIMAGE_NOTIFICATION_SCAN_INTERVAL_MS:300000}
scan-initial-delay-ms: ${AIIMAGE_NOTIFICATION_SCAN_INITIAL_DELAY_MS:120000}
task-scan-enabled: ${AIIMAGE_NOTIFICATION_TASK_SCAN_ENABLED:true}
task-failed-window-minutes: ${AIIMAGE_NOTIFICATION_TASK_FAILED_WINDOW_MINUTES:60}
task-scan-max-rows: ${AIIMAGE_NOTIFICATION_TASK_SCAN_MAX_ROWS:1000}
service-probe-enabled: ${AIIMAGE_NOTIFICATION_SERVICE_PROBE_ENABLED:true}
# 探测地址留空=跳过该项;部署时按主机拓扑配置(15126 品牌检测 / 18960 跟价任务 API
brand-service-url: ${AIIMAGE_NOTIFICATION_BRAND_SERVICE_URL:}
price-track-api-url: ${AIIMAGE_NOTIFICATION_PRICE_TRACK_API_URL:}
jikip-probe-enabled: ${AIIMAGE_NOTIFICATION_JIKIP_PROBE_ENABLED:true}
read-retention-days: ${AIIMAGE_NOTIFICATION_READ_RETENTION_DAYS:90}
security:
shop-credential-key: ${AIIMAGE_SHOP_CREDENTIAL_KEY:change-me-shop-credential-key}
internal-token: ${AIIMAGE_INTERNAL_TOKEN:}
@@ -328,6 +344,7 @@ aiimage:
cookie-name: ${AIIMAGE_AUTH_COOKIE_NAME:aiimage_token}
cookie-secure: ${AIIMAGE_AUTH_COOKIE_SECURE:false}
cookie-same-site: ${AIIMAGE_AUTH_COOKIE_SAME_SITE:Lax}
single-device-enabled: ${AIIMAGE_AUTH_SINGLE_DEVICE_ENABLED:true}
ziniao:
enabled: ${AIIMAGE_ZINIAO_ENABLED:false}
base-url: ${AIIMAGE_ZINIAO_BASE_URL:https://sbappstoreapi.ziniao.com/openapi-router}