diff --git a/ChatGPT Image 2026年9月11日 10_34_34 (1).png b/ChatGPT Image 2026年9月11日 10_34_34 (1).png new file mode 100644 index 0000000..db0fbbb Binary files /dev/null and b/ChatGPT Image 2026年9月11日 10_34_34 (1).png differ diff --git a/ChatGPT Image 2026年9月11日 12_46_40.png b/ChatGPT Image 2026年9月11日 12_46_40.png new file mode 100644 index 0000000..20b7a6c Binary files /dev/null and b/ChatGPT Image 2026年9月11日 12_46_40.png differ diff --git a/admin-web/.dockerignore b/admin-web/.dockerignore new file mode 100644 index 0000000..da04cd3 --- /dev/null +++ b/admin-web/.dockerignore @@ -0,0 +1,5 @@ +node_modules +dist +*.log +.env* +pnpm-lock.yaml diff --git a/artifacts/ui-redesign/miniapp/01-home.png b/artifacts/ui-redesign/miniapp/01-home.png new file mode 100644 index 0000000..cc9cd8c Binary files /dev/null and b/artifacts/ui-redesign/miniapp/01-home.png differ diff --git a/artifacts/ui-redesign/miniapp/02-discover.png b/artifacts/ui-redesign/miniapp/02-discover.png new file mode 100644 index 0000000..c96fa0e Binary files /dev/null and b/artifacts/ui-redesign/miniapp/02-discover.png differ diff --git a/artifacts/ui-redesign/miniapp/03-messages.png b/artifacts/ui-redesign/miniapp/03-messages.png new file mode 100644 index 0000000..7f0935b Binary files /dev/null and b/artifacts/ui-redesign/miniapp/03-messages.png differ diff --git a/artifacts/ui-redesign/miniapp/04-activity.png b/artifacts/ui-redesign/miniapp/04-activity.png new file mode 100644 index 0000000..c1d96a2 Binary files /dev/null and b/artifacts/ui-redesign/miniapp/04-activity.png differ diff --git a/artifacts/ui-redesign/miniapp/05-mine.png b/artifacts/ui-redesign/miniapp/05-mine.png new file mode 100644 index 0000000..0102340 Binary files /dev/null and b/artifacts/ui-redesign/miniapp/05-mine.png differ diff --git a/artifacts/ui-redesign/miniapp/06-matchmaker.png b/artifacts/ui-redesign/miniapp/06-matchmaker.png new file mode 100644 index 0000000..f8e9966 Binary files /dev/null and b/artifacts/ui-redesign/miniapp/06-matchmaker.png differ diff --git a/artifacts/ui-redesign/miniapp/07-counseling.png b/artifacts/ui-redesign/miniapp/07-counseling.png new file mode 100644 index 0000000..62dbbf2 Binary files /dev/null and b/artifacts/ui-redesign/miniapp/07-counseling.png differ diff --git a/artifacts/ui-redesign/miniapp/08-premarital.png b/artifacts/ui-redesign/miniapp/08-premarital.png new file mode 100644 index 0000000..73c8f63 Binary files /dev/null and b/artifacts/ui-redesign/miniapp/08-premarital.png differ diff --git a/artifacts/ui-redesign/miniapp/09-content.png b/artifacts/ui-redesign/miniapp/09-content.png new file mode 100644 index 0000000..14b70d5 Binary files /dev/null and b/artifacts/ui-redesign/miniapp/09-content.png differ diff --git a/artifacts/ui-redesign/miniapp/10-anti-fraud.png b/artifacts/ui-redesign/miniapp/10-anti-fraud.png new file mode 100644 index 0000000..e049150 Binary files /dev/null and b/artifacts/ui-redesign/miniapp/10-anti-fraud.png differ diff --git a/artifacts/ui-redesign/miniapp/11-service-station.png b/artifacts/ui-redesign/miniapp/11-service-station.png new file mode 100644 index 0000000..c0bd9ad Binary files /dev/null and b/artifacts/ui-redesign/miniapp/11-service-station.png differ diff --git a/artifacts/ui-redesign/miniapp/contact-sheet.png b/artifacts/ui-redesign/miniapp/contact-sheet.png new file mode 100644 index 0000000..23125fa Binary files /dev/null and b/artifacts/ui-redesign/miniapp/contact-sheet.png differ diff --git a/artifacts/ui-redesign/miniapp/preview-qr.png b/artifacts/ui-redesign/miniapp/preview-qr.png new file mode 100644 index 0000000..fcdecd2 Binary files /dev/null and b/artifacts/ui-redesign/miniapp/preview-qr.png differ diff --git a/artifacts/ui-redesign/miniapp/reference-comparisons/01-home-comparison.jpg b/artifacts/ui-redesign/miniapp/reference-comparisons/01-home-comparison.jpg new file mode 100644 index 0000000..a39ff11 Binary files /dev/null and b/artifacts/ui-redesign/miniapp/reference-comparisons/01-home-comparison.jpg differ diff --git a/artifacts/ui-redesign/miniapp/reference-comparisons/02-discover-comparison.jpg b/artifacts/ui-redesign/miniapp/reference-comparisons/02-discover-comparison.jpg new file mode 100644 index 0000000..1478378 Binary files /dev/null and b/artifacts/ui-redesign/miniapp/reference-comparisons/02-discover-comparison.jpg differ diff --git a/artifacts/ui-redesign/miniapp/reference-comparisons/03-messages-comparison.jpg b/artifacts/ui-redesign/miniapp/reference-comparisons/03-messages-comparison.jpg new file mode 100644 index 0000000..1e76612 Binary files /dev/null and b/artifacts/ui-redesign/miniapp/reference-comparisons/03-messages-comparison.jpg differ diff --git a/artifacts/ui-redesign/miniapp/reference-comparisons/04-activity-comparison.jpg b/artifacts/ui-redesign/miniapp/reference-comparisons/04-activity-comparison.jpg new file mode 100644 index 0000000..2aaa951 Binary files /dev/null and b/artifacts/ui-redesign/miniapp/reference-comparisons/04-activity-comparison.jpg differ diff --git a/artifacts/ui-redesign/miniapp/reference-comparisons/05-mine-comparison.jpg b/artifacts/ui-redesign/miniapp/reference-comparisons/05-mine-comparison.jpg new file mode 100644 index 0000000..09e69d1 Binary files /dev/null and b/artifacts/ui-redesign/miniapp/reference-comparisons/05-mine-comparison.jpg differ diff --git a/artifacts/ui-redesign/miniapp/reference-comparisons/06-matchmaker-comparison.jpg b/artifacts/ui-redesign/miniapp/reference-comparisons/06-matchmaker-comparison.jpg new file mode 100644 index 0000000..8813457 Binary files /dev/null and b/artifacts/ui-redesign/miniapp/reference-comparisons/06-matchmaker-comparison.jpg differ diff --git a/artifacts/ui-redesign/miniapp/reference-comparisons/07-counseling-comparison.jpg b/artifacts/ui-redesign/miniapp/reference-comparisons/07-counseling-comparison.jpg new file mode 100644 index 0000000..7d5ad79 Binary files /dev/null and b/artifacts/ui-redesign/miniapp/reference-comparisons/07-counseling-comparison.jpg differ diff --git a/artifacts/ui-redesign/miniapp/reference-comparisons/08-premarital-comparison.jpg b/artifacts/ui-redesign/miniapp/reference-comparisons/08-premarital-comparison.jpg new file mode 100644 index 0000000..6d1c80b Binary files /dev/null and b/artifacts/ui-redesign/miniapp/reference-comparisons/08-premarital-comparison.jpg differ diff --git a/artifacts/ui-redesign/miniapp/reference-comparisons/09-content-comparison.jpg b/artifacts/ui-redesign/miniapp/reference-comparisons/09-content-comparison.jpg new file mode 100644 index 0000000..432c6e2 Binary files /dev/null and b/artifacts/ui-redesign/miniapp/reference-comparisons/09-content-comparison.jpg differ diff --git a/artifacts/ui-redesign/miniapp/reference-comparisons/10-anti-fraud-comparison.jpg b/artifacts/ui-redesign/miniapp/reference-comparisons/10-anti-fraud-comparison.jpg new file mode 100644 index 0000000..1a5330a Binary files /dev/null and b/artifacts/ui-redesign/miniapp/reference-comparisons/10-anti-fraud-comparison.jpg differ diff --git a/artifacts/ui-redesign/miniapp/reference-comparisons/11-service-station-comparison.jpg b/artifacts/ui-redesign/miniapp/reference-comparisons/11-service-station-comparison.jpg new file mode 100644 index 0000000..ff9efbf Binary files /dev/null and b/artifacts/ui-redesign/miniapp/reference-comparisons/11-service-station-comparison.jpg differ diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 0000000..36397e0 --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1,5 @@ +target +.m2* +local-* +build-temp +*.log diff --git a/infrastructure/docker-compose.yml b/infrastructure/docker-compose.yml index b62173f..5a01518 100644 --- a/infrastructure/docker-compose.yml +++ b/infrastructure/docker-compose.yml @@ -1,5 +1,4 @@ -# 丹阳公益婚恋服务平台 - Backend -version: '3.8' +# 丹阳公益婚恋服务平台 - 本地完整环境 services: postgres: @@ -89,18 +88,29 @@ services: timeout: 10s retries: 3 + admin-web: + build: + context: ../admin-web + dockerfile: Dockerfile + container_name: danyang-match-admin + depends_on: + backend: + condition: service_healthy + nginx: image: nginx:alpine container_name: danyang-match-nginx depends_on: - - backend + backend: + condition: service_healthy + admin-web: + condition: service_started ports: - - "80:80" - - "443:443" + - "6688:80" volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro healthcheck: - test: ["CMD", "curl", "-f", "http://localhost/health"] + test: ["CMD-SHELL", "wget -qO /dev/null http://localhost/nginx-health || exit 1"] interval: 30s timeout: 10s retries: 3 diff --git a/infrastructure/nginx.conf b/infrastructure/nginx.conf index 90d9ac6..333276c 100644 --- a/infrastructure/nginx.conf +++ b/infrastructure/nginx.conf @@ -38,6 +38,10 @@ http { server backend:8080; } + upstream admin_web { + server admin-web:80; + } + server { listen 80; server_name localhost; @@ -59,6 +63,8 @@ http { proxy_connect_timeout 30s; proxy_send_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 @@ -84,17 +90,13 @@ http { proxy_set_header X-Forwarded-Proto $scheme; } - # Admin web static files - location /admin/ { - root /usr/share/nginx/html; - index index.html; - try_files $uri $uri/ /admin/index.html; - } - - # 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"; + # Admin web + location / { + proxy_pass http://admin_web; + proxy_set_header Host $host; + 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; } } } diff --git a/ui-tests/miniapp-reference-contracts.mjs b/ui-tests/miniapp-reference-contracts.mjs index 353ed7b..b7de38f 100644 --- a/ui-tests/miniapp-reference-contracts.mjs +++ b/ui-tests/miniapp-reference-contracts.mjs @@ -103,6 +103,38 @@ assert.match(premaritalTemplate, /service-topics/, '婚前辅导页缺少四项 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') for (const token of [ '--mini-night-start', diff --git a/ui-tests/phase06-match-eligibility-contracts.mjs b/ui-tests/phase06-match-eligibility-contracts.mjs new file mode 100644 index 0000000..a402754 --- /dev/null +++ b/ui-tests/phase06-match-eligibility-contracts.mjs @@ -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')