chore: complete infrastructure config, contracts, reference images and ui redesign artifacts

This commit is contained in:
Codex
2026-09-14 10:02:34 +08:00
parent 63cbbff2de
commit ea2bb2439d
32 changed files with 88 additions and 17 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

+5
View File
@@ -0,0 +1,5 @@
node_modules
dist
*.log
.env*
pnpm-lock.yaml
Binary file not shown.

After

Width:  |  Height:  |  Size: 279 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 931 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

+5
View File
@@ -0,0 +1,5 @@
target
.m2*
local-*
build-temp
*.log
+16 -6
View File
@@ -1,5 +1,4 @@
# 丹阳公益婚恋服务平台 - Backend # 丹阳公益婚恋服务平台 - 本地完整环境
version: '3.8'
services: services:
postgres: postgres:
@@ -89,18 +88,29 @@ services:
timeout: 10s timeout: 10s
retries: 3 retries: 3
admin-web:
build:
context: ../admin-web
dockerfile: Dockerfile
container_name: danyang-match-admin
depends_on:
backend:
condition: service_healthy
nginx: nginx:
image: nginx:alpine image: nginx:alpine
container_name: danyang-match-nginx container_name: danyang-match-nginx
depends_on: depends_on:
- backend backend:
condition: service_healthy
admin-web:
condition: service_started
ports: ports:
- "80:80" - "6688:80"
- "443:443"
volumes: volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro - ./nginx.conf:/etc/nginx/nginx.conf:ro
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"] test: ["CMD-SHELL", "wget -qO /dev/null http://localhost/nginx-health || exit 1"]
interval: 30s interval: 30s
timeout: 10s timeout: 10s
retries: 3 retries: 3
+13 -11
View File
@@ -38,6 +38,10 @@ http {
server backend:8080; server backend:8080;
} }
upstream admin_web {
server admin-web:80;
}
server { server {
listen 80; listen 80;
server_name localhost; server_name localhost;
@@ -59,6 +63,8 @@ http {
proxy_connect_timeout 30s; proxy_connect_timeout 30s;
proxy_send_timeout 60s; proxy_send_timeout 60s;
proxy_read_timeout 60s; proxy_read_timeout 60s;
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
add_header Pragma "no-cache";
} }
# WebSocket proxy # WebSocket proxy
@@ -84,17 +90,13 @@ http {
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
} }
# Admin web static files # Admin web
location /admin/ { location / {
root /usr/share/nginx/html; proxy_pass http://admin_web;
index index.html; proxy_set_header Host $host;
try_files $uri $uri/ /admin/index.html; proxy_set_header X-Real-IP $remote_addr;
} proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Don't cache API responses
location /api/ {
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
add_header Pragma "no-cache";
} }
} }
} }
+32
View File
@@ -103,6 +103,38 @@ assert.match(premaritalTemplate, /service-topics/, '婚前辅导页缺少四项
assert.match(premaritalTemplate, /预约辅导/, '婚前辅导页缺少预约按钮') assert.match(premaritalTemplate, /预约辅导/, '婚前辅导页缺少预约按钮')
assert.match(premaritalTemplate, /服务状态/, '婚前辅导页缺少服务状态') assert.match(premaritalTemplate, /服务状态/, '婚前辅导页缺少服务状态')
const contentTemplate = read('miniapp/pages/content/content.wxml')
const contentLogic = read('miniapp/pages/content/content.js')
assert.match(contentTemplate, /content-categories/, '婚恋课堂缺少分类导航')
assert.match(contentTemplate, /content-list/, '婚恋课堂缺少内容列表')
assert.match(contentTemplate, /viewCount/, '婚恋课堂缺少真实浏览量')
assert.match(contentTemplate, /publishAtText/, '婚恋课堂缺少发布日期')
assert.match(contentLogic, /\/content\/categories/, '婚恋课堂分类必须来自正式接口')
assert.match(contentLogic, /\/content\/articles/, '婚恋课堂文章必须来自正式接口')
assert.doesNotMatch(contentLogic, /id:\s*['"]1['"]/, '婚恋课堂不得保留演示文章')
const antiFraudTemplate = read('miniapp/pages/anti-fraud/anti-fraud.wxml')
assert.match(antiFraudTemplate, /ui-service-hero/, '婚恋反诈必须使用独立主视觉')
assert.match(antiFraudTemplate, /risk-grid/, '婚恋反诈缺少四类风险')
assert.match(antiFraudTemplate, /举报可疑行为/, '婚恋反诈缺少举报入口')
assert.match(antiFraudTemplate, /安全求助/, '婚恋反诈缺少求助入口')
const stationTemplate = read('miniapp/pages/service-station/service-station.wxml')
const stationLogic = read('miniapp/pages/service-station/service-station.js')
for (const label of ['地址', '联系电话', '开放时间', '服务项目', '地图定位', '预约到站服务']) {
assert.ok(stationTemplate.includes(label), `服务站缺少 ${label}`)
}
assert.match(stationLogic, /wx\.makePhoneCall/, '服务站电话必须使用微信原生拨号')
assert.match(stationLogic, /wx\.openLocation/, '服务站定位必须使用微信原生地图')
assert.match(stationLogic, /api\.get\(['"]\/home['"]\)/, '服务站必须读取真实首页服务站数据')
assert.doesNotMatch(stationLogic, /00000000/, '服务站不得保留演示电话')
for (const envFile of ['miniapp/env.js', 'miniapp/env.ts']) {
const envSource = read(envFile)
assert.match(envSource, /getAccountInfoSync/, `${envFile} 必须通过微信运行版本识别开发环境`)
assert.match(envSource, /envVersion\s*===\s*['"]develop['"]/, `${envFile} 必须将 develop 环境指向本地 API`)
}
const theme = read('miniapp/app.wxss') const theme = read('miniapp/app.wxss')
for (const token of [ for (const token of [
'--mini-night-start', '--mini-night-start',
@@ -0,0 +1,17 @@
import assert from 'node:assert/strict'
import fs from 'node:fs'
const read = (path) => fs.readFileSync(path, 'utf8')
const engine = read('backend/src/main/java/com/danyang/match/platform/match/service/RecommendationEngineService.java')
const legacyEligibility = read('backend/src/main/java/com/danyang/match/platform/match/service/MatchEligibilityService.java')
const home = read('backend/src/main/java/com/danyang/match/platform/home/service/HomeApplicationService.java')
const card = read('miniapp/components/recommend-card/index.wxml')
assert.match(engine, /isParticipantEligible\(userId\)/, '推荐入口必须校验当前用户资格')
assert.match(engine, /findByRelation\(targetUserId, userId, Constants\.RELATION_TYPE_BLOCKED\)/, '必须检查反向 Block')
assert.match(engine, /localEligibilityMapper\.findByUserId/, '正式推荐引擎必须接入本地资格 Provider')
assert.doesNotMatch(legacyEligibility, /PROFILE_STATUS_PENDING_REVIEW\.equals\(el\.getVerificationStatus\(\)\)/, 'pending_review 不得视为本地资格通过')
assert.match(home, /recommendationEngineService\.getDailyRecommendations\(userId\)/, '首页必须调用正式推荐引擎')
assert.doesNotMatch(card, /score|percent|匹配率|%/, '用户端不得显示数字匹配率')
console.log('Phase 06 match eligibility contracts passed')