diff --git a/backend/.env.example b/backend/.env.example
index 385a445..d05055a 100644
--- a/backend/.env.example
+++ b/backend/.env.example
@@ -14,3 +14,7 @@
# MINIO_ENDPOINT=http://localhost:9000
# MINIO_ACCESS_KEY=replace-with-local-access-key
# MINIO_SECRET_KEY=replace-with-local-secret-key
+# 本地资格佐证保留期(天)
+LOCAL_EVIDENCE_RETENTION_DAYS=365
+LOCAL_EVIDENCE_ALLOWED_TYPES=jpg,png
+MATCH_LOCAL_ELIGIBILITY_REQUIRED=false
diff --git a/backend/src/main/resources/application-docker.yml b/backend/src/main/resources/application-docker.yml
index 38ec9c5..1f9e54a 100644
--- a/backend/src/main/resources/application-docker.yml
+++ b/backend/src/main/resources/application-docker.yml
@@ -42,6 +42,7 @@ match:
default-daily-limit: 6
default-score-threshold: 60
default-cooldown-days: 180
+ local-eligibility-required: ${MATCH_LOCAL_ELIGIBILITY_REQUIRED:false}
activity:
default-need-review: true
@@ -73,6 +74,7 @@ features:
local-evidence-upload-enabled: true
local-evidence-max-files: 5
local-evidence-max-file-size-mb: 10
- local-evidence-allowed-types: jpg,png,pdf
+ local-evidence-allowed-types: ${LOCAL_EVIDENCE_ALLOWED_TYPES:jpg,png}
+ local-evidence-retention-days: ${LOCAL_EVIDENCE_RETENTION_DAYS:365}
counseling-attachments-private: true
counseling-attachments-bucket: counseling-attachments
diff --git a/miniapp/assets/brand/default-avatar.png b/miniapp/assets/brand/default-avatar.png
index 3000ed8..92fb1a4 100644
Binary files a/miniapp/assets/brand/default-avatar.png and b/miniapp/assets/brand/default-avatar.png differ
diff --git a/miniapp/env.js b/miniapp/env.js
index 054f649..66b2b84 100644
--- a/miniapp/env.js
+++ b/miniapp/env.js
@@ -6,7 +6,14 @@
*/
const isDev = (function() {
try {
- // 使用非废弃的 API(wx.getSystemInfoSync 在基础库 3.7.0+ 已废弃)
+ const accountInfo = typeof wx.getAccountInfoSync === 'function'
+ ? wx.getAccountInfoSync()
+ : null;
+ if (accountInfo && accountInfo.miniProgram && accountInfo.miniProgram.envVersion === 'develop') {
+ return true;
+ }
+
+ // 兼容旧基础库与部分自动化运行环境。
const info = wx.getDeviceInfo ? wx.getDeviceInfo() : wx.getSystemInfoSync();
return info.platform === 'devtools';
} catch (e) {
diff --git a/miniapp/env.ts b/miniapp/env.ts
index 5093dfc..10406c7 100644
--- a/miniapp/env.ts
+++ b/miniapp/env.ts
@@ -5,6 +5,13 @@ declare const wx: WechatMiniprogram.Wx;
function isDev(): boolean {
try {
+ const accountInfo = typeof wx.getAccountInfoSync === 'function'
+ ? wx.getAccountInfoSync()
+ : null;
+ if (accountInfo?.miniProgram?.envVersion === 'develop') {
+ return true;
+ }
+
const info = (wx.getDeviceInfo ? wx.getDeviceInfo() : wx.getSystemInfoSync()) as any;
return info.platform === 'devtools';
} catch {
diff --git a/miniapp/pages/anti-fraud/anti-fraud.js b/miniapp/pages/anti-fraud/anti-fraud.js
index a820a0d..6f65f21 100644
--- a/miniapp/pages/anti-fraud/anti-fraud.js
+++ b/miniapp/pages/anti-fraud/anti-fraud.js
@@ -1 +1,27 @@
-Page({data:{warnings:['刚认识就引导投资或博彩','以生病、工程、周转为由借款','催促脱离平台并索要隐私资料']},report(){wx.navigateTo({url:'/pages/report/report?type=fraud'})}})
\ No newline at end of file
+Page({
+ data: {
+ risks: [
+ { title: '投资博彩诱导', description: '刚认识便引导投资、博彩或下载陌生应用' },
+ { title: '借款资金周转', description: '以生病、工程或临时周转为由反复借款' },
+ { title: '索取隐私资料', description: '催促脱离平台并索要验证码、银行卡或证件信息' },
+ { title: '冒充平台人员', description: '以认证、保证金或解冻账户为由要求转账' },
+ ],
+ },
+
+ report() {
+ wx.navigateTo({ url: '/pages/report/report?type=fraud' })
+ },
+
+ requestHelp() {
+ wx.showModal({
+ title: '安全求助',
+ content: '如有财产损失或人身危险,请立即拨打 110;非紧急问题可前往平台帮助中心。',
+ confirmText: '拨打 110',
+ cancelText: '帮助中心',
+ success(result) {
+ if (result.confirm) wx.makePhoneCall({ phoneNumber: '110' })
+ else if (result.cancel) wx.navigateTo({ url: '/pages/help-center/help-center' })
+ },
+ })
+ },
+})
diff --git a/miniapp/pages/anti-fraud/anti-fraud.json b/miniapp/pages/anti-fraud/anti-fraud.json
index 817794d..1aaafd4 100644
--- a/miniapp/pages/anti-fraud/anti-fraud.json
+++ b/miniapp/pages/anti-fraud/anti-fraud.json
@@ -1 +1,7 @@
-{"navigationBarTitleText":"婚恋反诈","backgroundColor":"#FAFAF8"}
\ No newline at end of file
+{
+ "navigationBarTitleText": "婚恋反诈",
+ "backgroundColor": "#F4F5FA",
+ "usingComponents": {
+ "ui-service-hero": "/components/service-hero/index"
+ }
+}
diff --git a/miniapp/pages/anti-fraud/anti-fraud.wxml b/miniapp/pages/anti-fraud/anti-fraud.wxml
index 180e921..5f06f76 100644
--- a/miniapp/pages/anti-fraud/anti-fraud.wxml
+++ b/miniapp/pages/anti-fraud/anti-fraud.wxml
@@ -1 +1,19 @@
-婚恋反诈中心真诚交往,也要守住安全边界平台不会以任何理由要求转账、投资或提供银行卡密码。常见风险信号!{{item}}遇到异常请停止转账并保存相关记录遇到可疑情况怎么办1停止资金操作不要继续转账、充值或提供验证码2保存相关证据保留聊天、付款与账号信息3及时举报或报警紧急情况请直接拨打 110举报可疑行为
\ No newline at end of file
+
+
+
+ 常见风险信号出现以下情况,请先停止资金或隐私操作
+
+ {{item.title}}{{item.description}}
+
+
+
+ 遇到可疑情况怎么办
+
+ 立即停止资金操作不要继续转账、充值或提供验证码
+ 保存相关证据保留聊天、付款和对方账号信息
+ 及时举报或报警平台举报不会通知被举报人,紧急情况请拨打 110
+
+
+
+ 安全求助举报可疑行为
+
diff --git a/miniapp/pages/anti-fraud/anti-fraud.wxss b/miniapp/pages/anti-fraud/anti-fraud.wxss
index db9c96d..5424136 100644
--- a/miniapp/pages/anti-fraud/anti-fraud.wxss
+++ b/miniapp/pages/anti-fraud/anti-fraud.wxss
@@ -1 +1,2 @@
-@import "../../styles/service-page.wxss";
\ No newline at end of file
+@import "../../styles/service-page.wxss";
+.risk-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:16rpx;margin-top:18rpx}.risk-card{display:flex;min-height:174rpx;flex-direction:column;padding:20rpx;border:1rpx solid #F7DCE2;border-radius:24rpx;background:#FFF9FA}.risk-card image{width:42rpx;height:42rpx}.risk-title{margin-top:10rpx;color:#9E4054;font-size:23rpx;font-weight:650}.risk-desc{margin-top:7rpx;color:#846F78;font-size:18rpx;line-height:1.5}.safety-steps{overflow:hidden;margin-top:18rpx;border-radius:24rpx;background:#fff;box-shadow:0 8rpx 26rpx rgba(35,35,95,.06)}.safety-step{display:flex;align-items:center;gap:16rpx;min-height:104rpx;padding:16rpx 20rpx;border-bottom:1rpx solid #EFF0F5}.safety-step:last-child{border-bottom:0}.safety-step>image{width:48rpx;height:48rpx;flex:none}.safety-step>view{display:flex;flex:1;flex-direction:column}.safety-step view text:first-child{color:#303654;font-size:23rpx;font-weight:650}.safety-step view text:last-child{margin-top:5rpx;color:#858A9E;font-size:19rpx;line-height:1.45}
diff --git a/miniapp/pages/content/content.js b/miniapp/pages/content/content.js
index 11164ad..1163106 100644
--- a/miniapp/pages/content/content.js
+++ b/miniapp/pages/content/content.js
@@ -1 +1,76 @@
-Page({data:{categories:['推荐','认识自己','沟通成长','关系经营','婚恋反诈'],active:0,articles:[{id:'1',title:'第一次见面,怎样自然地开始交流',category:'沟通成长',read:'5分钟'},{id:'2',title:'建立健康关系,需要怎样的边界',category:'关系经营',read:'6分钟'},{id:'3',title:'警惕以投资为名的婚恋骗局',category:'婚恋反诈',read:'4分钟'}]},select(e){this.setData({active:e.currentTarget.dataset.index})},open(e){wx.navigateTo({url:'/pages/content-detail/content-detail?id='+e.currentTarget.dataset.id})}})
\ No newline at end of file
+const api = require('../../utils/api')
+
+const formatDate = (value) => {
+ if (!value) return ''
+ const date = new Date(value)
+ if (Number.isNaN(date.getTime())) return ''
+ const month = String(date.getMonth() + 1).padStart(2, '0')
+ const day = String(date.getDate()).padStart(2, '0')
+ return `${date.getFullYear()}-${month}-${day}`
+}
+
+Page({
+ data: {
+ categories: [{ id: '', name: '推荐' }],
+ activeCategoryId: '',
+ articles: [],
+ loading: true,
+ loadError: false,
+ },
+
+ onLoad() {
+ this.loadPage()
+ },
+
+ async loadPage() {
+ this.setData({ loading: true, loadError: false })
+ try {
+ const [categories, articles] = await Promise.all([
+ api.get('/content/categories'),
+ api.get('/content/articles'),
+ ])
+ this.setData({
+ categories: [{ id: '', name: '推荐' }, ...(categories || [])],
+ articles: this.normalizeArticles(articles || [], categories || []),
+ loading: false,
+ })
+ } catch (error) {
+ console.error('加载婚恋课堂失败', error)
+ this.setData({ loading: false, loadError: true })
+ }
+ },
+
+ normalizeArticles(articles, categories) {
+ const categoryNames = new Map(categories.map((item) => [item.id, item.name]))
+ return articles.map((item) => ({
+ ...item,
+ categoryName: categoryNames.get(item.categoryId) || '婚恋课堂',
+ publishAtText: formatDate(item.publishAt || item.createdAt),
+ }))
+ },
+
+ async select(e) {
+ const categoryId = e.currentTarget.dataset.id || ''
+ if (categoryId === this.data.activeCategoryId) return
+ this.setData({ activeCategoryId: categoryId, loading: true, loadError: false })
+ try {
+ const articles = await api.get('/content/articles', categoryId ? { categoryId } : undefined)
+ this.setData({
+ articles: this.normalizeArticles(articles || [], this.data.categories),
+ loading: false,
+ })
+ } catch (error) {
+ console.error('加载课堂分类失败', error)
+ this.setData({ loading: false, loadError: true })
+ }
+ },
+
+ open(e) {
+ const id = e.currentTarget.dataset.id
+ if (id) wx.navigateTo({ url: `/pages/content-detail/content-detail?id=${id}` })
+ },
+
+ onRetry() {
+ this.loadPage()
+ },
+})
diff --git a/miniapp/pages/content/content.json b/miniapp/pages/content/content.json
index 9626719..e68b580 100644
--- a/miniapp/pages/content/content.json
+++ b/miniapp/pages/content/content.json
@@ -1 +1,10 @@
-{"navigationBarTitleText":"婚恋课堂","backgroundColor":"#FAFAF8"}
\ No newline at end of file
+{
+ "navigationBarTitleText": "婚恋课堂",
+ "backgroundColor": "#F4F5FA",
+ "usingComponents": {
+ "ui-service-hero": "/components/service-hero/index",
+ "ui-loading": "/components/loading/index",
+ "ui-empty": "/components/empty/index",
+ "ui-error-state": "/components/error-state/index"
+ }
+}
diff --git a/miniapp/pages/content/content.wxml b/miniapp/pages/content/content.wxml
index ec8f7c0..be698c5 100644
--- a/miniapp/pages/content/content.wxml
+++ b/miniapp/pages/content/content.wxml
@@ -1 +1,19 @@
-婚恋课堂认真学习,更好地相遇提供真实、克制、可实践的关系成长与安全知识。{{item}}{{item.category}}{{item.title}}{{item.category}} · 阅读约 {{item.read}}
\ No newline at end of file
+
+
+
+ {{item.name}}
+
+
+
+
+
+
+
+
+ {{item.categoryName}}{{item.title}}{{item.summary}}浏览 {{item.viewCount || 0}}{{item.publishAtText}}
+
+
+
+
+
+
diff --git a/miniapp/pages/content/content.wxss b/miniapp/pages/content/content.wxss
index db9c96d..ba4856e 100644
--- a/miniapp/pages/content/content.wxss
+++ b/miniapp/pages/content/content.wxss
@@ -1 +1,2 @@
-@import "../../styles/service-page.wxss";
\ No newline at end of file
+@import "../../styles/service-page.wxss";
+.content-page{min-height:100vh;padding-bottom:40rpx;background:#F4F5FA}.content-categories{padding:24rpx 0;white-space:nowrap}.content-category-row{display:inline-flex;gap:12rpx;padding:0 24rpx}.content-category{padding:11rpx 22rpx;border-radius:24rpx;background:#fff;color:#767D96;font-size:21rpx;box-shadow:0 6rpx 18rpx rgba(35,35,95,.05)}.content-category.active{background:linear-gradient(135deg,var(--mini-accent-coral),var(--mini-accent-pink));color:#fff;font-weight:650}.content-list{padding:0 24rpx}.content-card{display:flex;align-items:center;overflow:hidden;min-height:150rpx;margin-bottom:16rpx;border-radius:24rpx;background:#fff;box-shadow:0 8rpx 26rpx rgba(35,35,95,.06)}.content-cover{width:176rpx;height:150rpx;flex:none}.content-card__body{display:flex;flex:1;min-width:0;flex-direction:column;padding:16rpx}.content-card__category{align-self:flex-start;padding:4rpx 10rpx;border-radius:12rpx;background:#FFF0F5;color:var(--mini-accent-pink);font-size:17rpx}.content-card__title{overflow:hidden;margin-top:8rpx;color:#283056;font-size:24rpx;font-weight:650;white-space:nowrap;text-overflow:ellipsis}.content-card__summary{overflow:hidden;margin-top:5rpx;color:#83899F;font-size:18rpx;white-space:nowrap;text-overflow:ellipsis}.content-card__meta{display:flex;gap:18rpx;margin-top:9rpx;color:#9A9EB0;font-size:17rpx}.content-card__arrow{width:24rpx;height:24rpx;margin-right:16rpx;flex:none}
diff --git a/miniapp/pages/local-eligibility-supplement/local-eligibility-supplement.wxml b/miniapp/pages/local-eligibility-supplement/local-eligibility-supplement.wxml
index f365392..126ae20 100644
--- a/miniapp/pages/local-eligibility-supplement/local-eligibility-supplement.wxml
+++ b/miniapp/pages/local-eligibility-supplement/local-eligibility-supplement.wxml
@@ -11,7 +11,7 @@
- 已声明:{{getEligibilityLabel(eligibilityType)}}
+ 已选择本地资格类型
@@ -36,7 +36,7 @@
上传佐证材料
- 支持 JPG/PNG,最多 6 张
+ 支持 JPG/PNG,最多 {{maxFiles}} 张
×
-
+
+
上传
@@ -57,13 +57,13 @@
- 🔒 仅用于资格审核,不对其他用户展示
+ 材料仅用于资格审核,不对其他用户展示
-
diff --git a/miniapp/pages/local-eligibility/local-eligibility.wxml b/miniapp/pages/local-eligibility/local-eligibility.wxml
index e555ba7..9d25487 100644
--- a/miniapp/pages/local-eligibility/local-eligibility.wxml
+++ b/miniapp/pages/local-eligibility/local-eligibility.wxml
@@ -1,5 +1,10 @@
+
+ 当前状态:{{statusText[status]}}
+
+ 正在读取资格状态…
+ 状态加载失败,点击重试