commit 44687f2766262b6a978e4939affd88d966b799d5 Author: zpc Date: Sun Dec 28 22:13:47 2025 +0800 添加文档 diff --git a/docs/原型图/Thumbs.db b/docs/原型图/Thumbs.db new file mode 100644 index 0000000..a68f0c6 Binary files /dev/null and b/docs/原型图/Thumbs.db differ diff --git a/docs/原型图/同城群 2.png b/docs/原型图/同城群 2.png new file mode 100644 index 0000000..5c9582d Binary files /dev/null and b/docs/原型图/同城群 2.png differ diff --git a/docs/原型图/同城群.png b/docs/原型图/同城群.png new file mode 100644 index 0000000..5bd3dfd Binary files /dev/null and b/docs/原型图/同城群.png differ diff --git a/docs/原型图/搜索.png b/docs/原型图/搜索.png new file mode 100644 index 0000000..bcda0ac Binary files /dev/null and b/docs/原型图/搜索.png differ diff --git a/docs/原型图/消息 14.png b/docs/原型图/消息 14.png new file mode 100644 index 0000000..5f47c2b Binary files /dev/null and b/docs/原型图/消息 14.png differ diff --git a/docs/原型图/消息 15.png b/docs/原型图/消息 15.png new file mode 100644 index 0000000..480492e Binary files /dev/null and b/docs/原型图/消息 15.png differ diff --git a/docs/原型图/消息 16.png b/docs/原型图/消息 16.png new file mode 100644 index 0000000..da133d2 Binary files /dev/null and b/docs/原型图/消息 16.png differ diff --git a/docs/原型图/消息 17.png b/docs/原型图/消息 17.png new file mode 100644 index 0000000..9f21cc8 Binary files /dev/null and b/docs/原型图/消息 17.png differ diff --git a/docs/原型图/消息 18.png b/docs/原型图/消息 18.png new file mode 100644 index 0000000..12b9d39 Binary files /dev/null and b/docs/原型图/消息 18.png differ diff --git a/docs/原型图/消息 19.png b/docs/原型图/消息 19.png new file mode 100644 index 0000000..2f8941c Binary files /dev/null and b/docs/原型图/消息 19.png differ diff --git a/docs/原型图/消息 20.png b/docs/原型图/消息 20.png new file mode 100644 index 0000000..6d259e1 Binary files /dev/null and b/docs/原型图/消息 20.png differ diff --git a/docs/原型图/消息 21.png b/docs/原型图/消息 21.png new file mode 100644 index 0000000..784a170 Binary files /dev/null and b/docs/原型图/消息 21.png differ diff --git a/docs/原型图/消息 23.png b/docs/原型图/消息 23.png new file mode 100644 index 0000000..3244557 Binary files /dev/null and b/docs/原型图/消息 23.png differ diff --git a/docs/原型图/消息 24.png b/docs/原型图/消息 24.png new file mode 100644 index 0000000..3b97133 Binary files /dev/null and b/docs/原型图/消息 24.png differ diff --git a/docs/原型图/消息 26.png b/docs/原型图/消息 26.png new file mode 100644 index 0000000..5498e29 Binary files /dev/null and b/docs/原型图/消息 26.png differ diff --git a/docs/原型图/消息 27.png b/docs/原型图/消息 27.png new file mode 100644 index 0000000..b7d8464 Binary files /dev/null and b/docs/原型图/消息 27.png differ diff --git a/docs/原型图/消息 28.png b/docs/原型图/消息 28.png new file mode 100644 index 0000000..9fe2033 Binary files /dev/null and b/docs/原型图/消息 28.png differ diff --git a/docs/原型图/消息.png b/docs/原型图/消息.png new file mode 100644 index 0000000..6bf8b37 Binary files /dev/null and b/docs/原型图/消息.png differ diff --git a/docs/原型图/聊天室.png b/docs/原型图/聊天室.png new file mode 100644 index 0000000..995e0c7 Binary files /dev/null and b/docs/原型图/聊天室.png differ diff --git a/docs/原型图/解锁联系方式 3.png b/docs/原型图/解锁联系方式 3.png new file mode 100644 index 0000000..9cc3e2a Binary files /dev/null and b/docs/原型图/解锁联系方式 3.png differ diff --git a/docs/原型图/解锁联系方式.png b/docs/原型图/解锁联系方式.png new file mode 100644 index 0000000..1b26be7 Binary files /dev/null and b/docs/原型图/解锁联系方式.png differ diff --git a/docs/原型图/详细资料 13.png b/docs/原型图/详细资料 13.png new file mode 100644 index 0000000..668bd82 Binary files /dev/null and b/docs/原型图/详细资料 13.png differ diff --git a/docs/原型图/详细资料 25.png b/docs/原型图/详细资料 25.png new file mode 100644 index 0000000..1c534fb Binary files /dev/null and b/docs/原型图/详细资料 25.png differ diff --git a/docs/原型图/详细资料.png b/docs/原型图/详细资料.png new file mode 100644 index 0000000..f29f617 Binary files /dev/null and b/docs/原型图/详细资料.png differ diff --git a/docs/原型图/资料填写 (2).png b/docs/原型图/资料填写 (2).png new file mode 100644 index 0000000..b5999cd Binary files /dev/null and b/docs/原型图/资料填写 (2).png differ diff --git a/docs/原型图/资料填写 (3).png b/docs/原型图/资料填写 (3).png new file mode 100644 index 0000000..1db6896 Binary files /dev/null and b/docs/原型图/资料填写 (3).png differ diff --git a/docs/原型图/资料填写 10.png b/docs/原型图/资料填写 10.png new file mode 100644 index 0000000..13e7e0b Binary files /dev/null and b/docs/原型图/资料填写 10.png differ diff --git a/docs/原型图/资料填写 11.png b/docs/原型图/资料填写 11.png new file mode 100644 index 0000000..d7f62c4 Binary files /dev/null and b/docs/原型图/资料填写 11.png differ diff --git a/docs/原型图/资料填写.png b/docs/原型图/资料填写.png new file mode 100644 index 0000000..a0c90a8 Binary files /dev/null and b/docs/原型图/资料填写.png differ diff --git a/docs/原型图/通知.png b/docs/原型图/通知.png new file mode 100644 index 0000000..43ff94f Binary files /dev/null and b/docs/原型图/通知.png differ diff --git a/docs/原型图/通知权限.png b/docs/原型图/通知权限.png new file mode 100644 index 0000000..059e10e Binary files /dev/null and b/docs/原型图/通知权限.png differ diff --git a/docs/原型图/首页_1.png b/docs/原型图/首页_1.png new file mode 100644 index 0000000..d6d1f7e Binary files /dev/null and b/docs/原型图/首页_1.png differ diff --git a/docs/原型图/首页弹窗 12.png b/docs/原型图/首页弹窗 12.png new file mode 100644 index 0000000..e4d16b9 Binary files /dev/null and b/docs/原型图/首页弹窗 12.png differ diff --git a/docs/原型图/首页弹窗 8.png b/docs/原型图/首页弹窗 8.png new file mode 100644 index 0000000..3a30e57 Binary files /dev/null and b/docs/原型图/首页弹窗 8.png differ diff --git a/docs/原型图/首页弹窗.png b/docs/原型图/首页弹窗.png new file mode 100644 index 0000000..5bb5858 Binary files /dev/null and b/docs/原型图/首页弹窗.png differ diff --git a/docs/技术栈与开发规范.md b/docs/技术栈与开发规范.md new file mode 100644 index 0000000..1f2d366 --- /dev/null +++ b/docs/技术栈与开发规范.md @@ -0,0 +1,557 @@ +# 相宜相亲 - 技术栈与开发规范 + +> 版本:1.1 +> 更新日期:2025-12-28 + +--- + +## 一、项目架构概览 + +``` +┌─────────────────────────────────────────────────────────────┐ +│ 客户端层 │ +├──────────────────┬──────────────────┬───────────────────────┤ +│ 微信小程序 │ 后台管理系统 │ 微信服务号 │ +│ (uni-app) │ (Vue3+ElementPlus)│ (消息推送) │ +└────────┬─────────┴────────┬─────────┴───────────┬───────────┘ + │ │ │ + ▼ ▼ ▼ +┌─────────────────────────────────────────────────────────────┐ +│ API网关层 │ +├──────────────────────────┬──────────────────────────────────┤ +│ 小程序API (独立部署) │ 后台管理API (独立部署) │ +│ /api/app/* │ /api/admin/* │ +└──────────────────────────┴──────────────────────────────────┘ + │ │ + ▼ ▼ +┌─────────────────────────────────────────────────────────────┐ +│ 业务服务层 (.NET 8) │ +├─────────────────────────────────────────────────────────────┤ +│ 用户服务 │ 相亲资料服务 │ 会员服务 │ 聊天服务 │ 支付服务 │ +└─────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ 数据层 │ +├──────────────────┬──────────────────┬───────────────────────┤ +│ SQL Server │ Redis │ 文件存储 │ +│ (主数据库) │ (缓存/会话) │ (OSS/本地) │ +└──────────────────┴──────────────────┴───────────────────────┘ +``` + +--- + +## 二、技术栈清单 + +### 2.1 后端技术栈 + +| 类别 | 技术选型 | 版本 | 说明 | +|-----|---------|------|------| +| **运行时** | .NET | 8.0 LTS | 长期支持版本,性能优秀 | +| **Web框架** | ASP.NET Core WebAPI | 8.0 | RESTful API | +| **ORM** | FreeSql | 3.x | 国产ORM,功能强大,支持CodeFirst | +| **数据库** | SQL Server | 2019+ | 主数据库 | +| **缓存** | Redis | 7.x | 验证码、Token、热点数据缓存 | +| **认证** | JWT | - | JSON Web Token 身份认证 | +| **API文档** | Swagger/OpenAPI | - | 接口文档自动生成 | +| **日志** | Serilog | 3.x | 结构化日志 | +| **对象映射** | Mapster | 7.x | 轻量级对象映射(比AutoMapper快) | +| **验证** | FluentValidation | 11.x | 请求参数验证 | +| **后台任务** | Hangfire | 1.8.x | 定时任务(每日推荐刷新等) | +| **实时通信** | SignalR | 8.0 | 聊天消息实时推送 | + +### 2.2 前端技术栈(后台管理) + +| 类别 | 技术选型 | 版本 | 说明 | +|-----|---------|------|------| +| **框架** | Vue | 3.4+ | 渐进式JavaScript框架 | +| **构建工具** | Vite | 5.x | 快速构建工具 | +| **UI组件库** | Element Plus | 2.x | Vue3 UI组件库 | +| **状态管理** | Pinia | 2.x | Vue3官方状态管理 | +| **路由** | Vue Router | 4.x | 路由管理 | +| **HTTP客户端** | Axios | 1.x | HTTP请求 | +| **图表** | ECharts | 5.x | 数据可视化(统计报表) | +| **富文本** | WangEditor | 5.x | 富文本编辑器(通知编辑) | +| **TypeScript** | TypeScript | 5.x | 类型安全 | + +### 2.3 小程序端 + +| 类别 | 技术选型 | 版本 | 说明 | +|-----|---------|------|------| +| **开发框架** | uni-app | 3.x | 基于Vue3,可跨平台 | +| **UI组件** | uView Plus | 3.x | uni-app专用UI组件库 | +| **状态管理** | Pinia | 2.x | 全局状态管理 | +| **请求库** | luch-request | - | uni-app请求封装 | + +### 2.4 第三方服务(抽象设计,支持多服务商) + +| 服务 | 默认方案 | 备选方案 | 用途 | +|-----|---------|---------|------| +| **文件存储** | 腾讯云COS | 阿里云OSS | 用户头像、照片存储 | +| **短信服务** | 阿里云SMS | 腾讯云SMS | 手机号验证 | +| **实名认证** | 腾讯云人脸核身 | 阿里云实名认证 | 身份证验证 | +| **微信支付** | 微信支付V3 | - | 会员购买、实名认证付费 | +| **微信服务号** | 微信公众平台 | - | 消息推送通知 | +| **即时通讯** | SignalR | - | 用户聊天功能(自建) | + +### 2.5 云服务抽象设计 + +为支持多云服务商切换,所有第三方云服务采用**接口抽象 + 依赖注入**模式: + +```csharp +// ============ 文件存储抽象 ============ +public interface IStorageProvider +{ + Task UploadAsync(Stream stream, string fileName, string folder); + Task DeleteAsync(string fileKey); + string GetAccessUrl(string fileKey, int expireMinutes = 30); +} + +// 腾讯云COS实现 +public class TencentCosProvider : IStorageProvider { ... } + +// 阿里云OSS实现 +public class AliyunOssProvider : IStorageProvider { ... } + +// ============ 短信服务抽象 ============ +public interface ISmsProvider +{ + Task SendVerifyCodeAsync(string phone, string code); + Task SendNotificationAsync(string phone, string templateId, Dictionary parameters); +} + +// 阿里云短信实现 +public class AliyunSmsProvider : ISmsProvider { ... } + +// 腾讯云短信实现 +public class TencentSmsProvider : ISmsProvider { ... } + +// ============ 实名认证抽象 ============ +public interface IRealNameProvider +{ + Task VerifyIdCardAsync(string name, string idCard); + Task VerifyIdCardWithPhotoAsync(string name, string idCard, string photoBase64); +} + +// 腾讯云实现 +public class TencentRealNameProvider : IRealNameProvider { ... } + +// 阿里云实现 +public class AliyunRealNameProvider : IRealNameProvider { ... } +``` + +**配置示例 (appsettings.json):** + +```json +{ + "CloudServices": { + "Storage": { + "Provider": "TencentCos", // 可切换为 "AliyunOss" + "TencentCos": { + "SecretId": "xxx", + "SecretKey": "xxx", + "Region": "ap-shanghai", + "BucketName": "xiangyi-1234567890" + }, + "AliyunOss": { + "AccessKeyId": "xxx", + "AccessKeySecret": "xxx", + "Endpoint": "oss-cn-shanghai.aliyuncs.com", + "BucketName": "xiangyi" + } + }, + "Sms": { + "Provider": "AliyunSms", // 可切换为 "TencentSms" + "AliyunSms": { + "AccessKeyId": "xxx", + "AccessKeySecret": "xxx", + "SignName": "相宜相亲", + "TemplateCode": "SMS_123456789" + }, + "TencentSms": { + "SecretId": "xxx", + "SecretKey": "xxx", + "AppId": "1400123456", + "SignName": "相宜相亲", + "TemplateId": "123456" + } + }, + "RealName": { + "Provider": "TencentRealName", // 可切换为 "AliyunRealName" + "TencentRealName": { + "SecretId": "xxx", + "SecretKey": "xxx" + }, + "AliyunRealName": { + "AccessKeyId": "xxx", + "AccessKeySecret": "xxx" + } + } + } +} +``` + +**依赖注入注册:** + +```csharp +// Program.cs +public static class CloudServiceExtensions +{ + public static IServiceCollection AddCloudServices(this IServiceCollection services, IConfiguration config) + { + // 文件存储 + var storageProvider = config["CloudServices:Storage:Provider"]; + if (storageProvider == "TencentCos") + services.AddSingleton(); + else + services.AddSingleton(); + + // 短信服务 + var smsProvider = config["CloudServices:Sms:Provider"]; + if (smsProvider == "AliyunSms") + services.AddSingleton(); + else + services.AddSingleton(); + + // 实名认证 + var realNameProvider = config["CloudServices:RealName:Provider"]; + if (realNameProvider == "TencentRealName") + services.AddSingleton(); + else + services.AddSingleton(); + + return services; + } +} +``` + +--- + +## 三、项目结构规范 + +### 3.1 命名空间规范 + +```csharp +// 核心层 +XiangYi.Core.Entities +XiangYi.Core.Enums +XiangYi.Core.Constants + +// 应用层 +XiangYi.Application.Services +XiangYi.Application.DTOs +XiangYi.Application.Interfaces + +// 基础设施层 +XiangYi.Infrastructure.Data +XiangYi.Infrastructure.Cache +XiangYi.Infrastructure.WeChat + +// API层 +XiangYi.AppApi.Controllers +XiangYi.AdminApi.Controllers +``` + +--- + +## 四、API设计规范 + +### 4.1 URL规范 + +``` +# 小程序API +POST /api/app/auth/login # 微信登录 +POST /api/app/auth/bindPhone # 绑定手机号 +GET /api/app/users/recommend # 获取推荐用户列表 +GET /api/app/users/getUserId # 获取用户详情 +POST /api/app/profile # 提交相亲资料 +POST /api/app/updateProfile # 更新相亲资料 +POST /api/app/unlock/getToUser # 解锁联系方式 +GET /api/app/messages # 获取消息列表 +POST /api/app/chat/send # 发送聊天消息 +... + +# 后台管理API +POST /api/admin/auth/login # 管理员登录 +GET /api/admin/users # 用户列表 +GET /api/admin/users/{id} # 用户详情 +PUT /api/admin/users/{id}/status # 更新用户状态 +GET /api/admin/members # 会员列表 +GET /api/admin/orders # 订单列表 +POST /api/admin/banners # 添加Banner +PUT /api/admin/settings/popup # 配置弹窗 +GET /api/admin/statistics/overview # 统计概览 +... +``` + +### 4.2 统一响应格式 + +```csharp +// 成功响应 +{ + "code": 0, + "message": "success", + "data": { ... } +} + +// 错误响应 +{ + "code": 40001, + "message": "参数验证失败", + "errors": ["手机号格式不正确"] +} + +// 分页响应 +{ + "code": 0, + "message": "success", + "data": { + "items": [...], + "total": 100, + "pageIndex": 1, + "pageSize": 10 + } +} +``` + +### 4.3 错误码规范 + +| 错误码范围 | 说明 | +|-----------|------| +| 0 | 成功 | +| 10000-19999 | 系统级错误 | +| 20000-29999 | 认证授权错误 | +| 30000-39999 | 参数验证错误 | +| 40000-49999 | 业务逻辑错误 | +| 50000-59999 | 第三方服务错误 | + +```csharp +// 示例 +public static class ErrorCodes +{ + // 系统错误 + public const int SystemError = 10001; + public const int DatabaseError = 10002; + + // 认证错误 + public const int Unauthorized = 20001; + public const int TokenExpired = 20002; + public const int InvalidToken = 20003; + + // 参数错误 + public const int ValidationFailed = 30001; + public const int InvalidParameter = 30002; + + // 业务错误 + public const int UserNotFound = 40001; + public const int ProfileNotCompleted = 40002; + public const int InsufficientContactCount = 40003; + public const int AlreadyUnlocked = 40004; + public const int MembershipRequired = 40005; +} +``` + +--- + +## 五、数据库设计规范 + +### 5.1 表命名规范 + +```sql +-- 使用Pascal命名,单数形式 +User -- 用户表 +UserProfile -- 用户相亲资料表 +Member -- 会员表 +Order -- 订单表 +ChatMessage -- 聊天消息表 +UserView -- 用户浏览记录表 +UserFavorite -- 用户收藏表 +UserUnlock -- 用户解锁记录表 +SystemConfig -- 系统配置表 +Banner -- Banner表 +AdminUser -- 管理员表 +``` + +### 5.2 字段命名规范 + +```sql +-- 主键:Id +-- 外键:{表名}Id,如 UserId +-- 时间字段:CreateTime, UpdateTime, ExpireTime +-- 状态字段:Status +-- 布尔字段:Is前缀,如 IsDeleted, IsEnabled +-- 枚举字段:使用int类型存储 + +CREATE TABLE [User] ( + Id BIGINT PRIMARY KEY IDENTITY, + OpenId NVARCHAR(64) NOT NULL, -- 微信OpenId + UnionId NVARCHAR(64), -- 微信UnionId + Phone NVARCHAR(20), -- 手机号 + Nickname NVARCHAR(50), -- 昵称 + Avatar NVARCHAR(500), -- 头像URL + XiangQinNo NVARCHAR(10), -- 相亲编号 + Status INT DEFAULT 1, -- 状态:1正常 2禁用 + IsRealName BIT DEFAULT 0, -- 是否实名 + IsMember BIT DEFAULT 0, -- 是否会员 + MemberLevel INT DEFAULT 0, -- 会员等级 + ContactCount INT DEFAULT 2, -- 剩余联系次数 + CreateTime DATETIME2 DEFAULT GETDATE(), + UpdateTime DATETIME2, + IsDeleted BIT DEFAULT 0 +); +``` + +### 5.3 FreeSql CodeFirst配置 + +```csharp +[Table(Name = "User")] +public class User +{ + [Column(IsPrimary = true, IsIdentity = true)] + public long Id { get; set; } + + [Column(StringLength = 64, IsNullable = false)] + public string OpenId { get; set; } + + [Column(StringLength = 20)] + public string? Phone { get; set; } + + [Column(StringLength = 50)] + public string? Nickname { get; set; } + + [Column(InsertValueSql = "GETDATE()")] + public DateTime CreateTime { get; set; } + + [Column(IsIgnore = true)] + public UserProfile? Profile { get; set; } +} +``` + +--- + +## 六、安全规范 + +### 6.1 认证流程 + +``` +小程序端: +1. 用户点击登录 → 调用wx.login()获取code +2. 前端将code发送到后端 /api/app/auth/login +3. 后端用code换取openid/unionid +4. 后端生成JWT Token返回 +5. 前端存储Token,后续请求携带Authorization头 + +后台管理端: +1. 管理员输入账号密码 +2. 后端验证成功后生成JWT Token +3. 前端存储Token,后续请求携带Authorization头 +``` + +### 6.2 JWT配置 + +```csharp +// appsettings.json +{ + "Jwt": { + "Secret": "your-256-bit-secret-key-here", + "Issuer": "XiangYiXiangQin", + "Audience": "XiangYiApp", + "ExpireMinutes": 10080 // 7天 + } +} +``` + +### 6.3 敏感数据处理 + +```csharp +// 手机号脱敏 +public static string MaskPhone(string phone) + => phone.Length >= 11 ? $"{phone[..3]}****{phone[^4..]}" : phone; + +// 身份证脱敏 +public static string MaskIdCard(string idCard) + => idCard.Length >= 18 ? $"{idCard[..3]}***********{idCard[^4..]}" : idCard; + +``` + +--- + +## 七、部署架构 + +### 7.1 推荐部署方案 + +``` +┌─────────────────────────────────────────┐ +│ Nginx (反向代理) │ +│ SSL证书、负载均衡、静态资源 │ +└────────────────┬────────────────────────┘ + │ + ┌────────────┼────────────┐ + ▼ ▼ ▼ +┌────────┐ ┌──────────┐ ┌──────────┐ +│小程序API│ │后台管理API│ │后台管理前端│ +│ :5001 │ │ :5002 │ │ :80 │ +└────────┘ └──────────┘ └──────────┘ + │ │ + └─────┬──────┘ + ▼ + ┌──────────┐ + │ SQL Server│ ◄── 主数据库 + │ :1433 │ + └──────────┘ + │ + ┌──────────┐ + │ Redis │ ◄── 缓存 + │ :6379 │ + └──────────┘ +``` + +### 7.2 服务器配置建议 + +| 环境 | 配置 | 说明 | +|-----|------|------| +| 开发环境 | 2核4G | 本地开发 | +| 测试环境 | 2核4G | 功能测试 | +| 生产环境 | 4核8G起 | 根据用户量调整 | + +--- + +## 八、开发工具 + +| 工具 | 用途 | +|-----|------| +| Visual Studio 2022 / Rider | .NET开发 | +| VS Code | 前端开发 | +| 微信开发者工具 | 小程序开发调试 | +| Navicat / SSMS | 数据库管理 | +| Redis Desktop Manager | Redis管理 | +| Postman / Apifox | API调试 | +| Git | 版本控制 | + +--- + +## 九、待确认事项 + +### 9.1 已确认的技术选型 + +- [x] 小程序开发框架:**uni-app** +- [x] 即时通讯方案:**SignalR(自建)** +- [x] 文件存储:**腾讯云COS**(已抽象,可切换阿里云OSS) +- [x] 短信服务商:**阿里云SMS**(已抽象,可切换腾讯云SMS) +- [x] 实名认证服务商:**腾讯云**(已抽象,可切换阿里云) + +### 9.2 需要确认的业务问题 + +- [ ] 是否需要后台审核用户资料? +- [ ] 聊天消息是否需要敏感词过滤? +- [ ] 是否需要举报功能? +- [ ] 数据备份策略? + +--- + +## 十、版本记录 + +| 版本 | 日期 | 修改内容 | +|-----|------|---------| +| 1.0 | 2025-12-28 | 初始版本 | +| 1.1 | 2025-12-28 | 确认技术选型:uni-app、SignalR;新增云服务抽象设计,支持多服务商切换 | diff --git a/docs/数据库设计.md b/docs/数据库设计.md new file mode 100644 index 0000000..d5188b9 --- /dev/null +++ b/docs/数据库设计.md @@ -0,0 +1,1079 @@ +# 相宜相亲 - 数据库设计 + +> 版本:1.0 +> 更新日期:2025-12-28 + +--- + +## 一、数据库架构 + +采用**物理分离**方案,分为两个独立数据库: + +| 数据库 | 名称 | 说明 | +|-------|------|------| +| 管理库 | XiangYi_Admin | 后台管理相关(管理员、角色、权限、菜单、操作日志) | +| 业务库 | XiangYi_Biz | 业务数据(用户、资料、会员、订单、聊天、配置等) | + +``` +┌─────────────────────────┐ ┌─────────────────────────┐ +│ XiangYi_Admin │ │ XiangYi_Biz │ +│ (后台管理库) │ │ (业务库) │ +├─────────────────────────┤ ├─────────────────────────┤ +│ Admin_User │ │ User │ +│ Admin_Role │ │ User_Profile │ +│ Admin_Permission │ │ User_Photo │ +│ Admin_Role_Permission │ │ User_Requirement │ +│ Admin_User_Role │ │ Member │ +│ Admin_Menu │ │ Order │ +│ Admin_Role_Menu │ │ Chat_Session │ +│ Admin_Operation_Log │ │ Chat_Message │ +│ │ │ User_View │ +│ │ │ User_Favorite │ +│ │ │ User_Unlock │ +│ │ │ Real_Name_Auth │ +│ │ │ Banner │ +│ │ │ System_Config │ +│ │ │ System_Notification │ +│ │ │ Daily_Recommend │ +└─────────────────────────┘ └─────────────────────────┘ +``` + +--- + +## 二、管理库表设计 (XiangYi_Admin) + +### 2.1 Admin_User (管理员用户表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| Username | nvarchar(50) | Y | 用户名,唯一 | +| Password | nvarchar(128) | Y | 密码(加密存储) | +| Salt | nvarchar(32) | Y | 密码盐 | +| RealName | nvarchar(50) | N | 真实姓名 | +| Phone | nvarchar(20) | N | 手机号 | +| Email | nvarchar(100) | N | 邮箱 | +| Avatar | nvarchar(500) | N | 头像URL | +| Status | int | Y | 状态:1正常 2禁用 | +| LastLoginTime | datetime2 | N | 最后登录时间 | +| LastLoginIp | nvarchar(50) | N | 最后登录IP | +| CreateTime | datetime2 | Y | 创建时间 | +| UpdateTime | datetime2 | N | 更新时间 | +| IsDeleted | bit | Y | 是否删除,默认0 | + +```sql +CREATE TABLE Admin_User ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + Username NVARCHAR(50) NOT NULL, + Password NVARCHAR(128) NOT NULL, + Salt NVARCHAR(32) NOT NULL, + RealName NVARCHAR(50), + Phone NVARCHAR(20), + Email NVARCHAR(100), + Avatar NVARCHAR(500), + Status INT NOT NULL DEFAULT 1, + LastLoginTime DATETIME2, + LastLoginIp NVARCHAR(50), + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE(), + UpdateTime DATETIME2, + IsDeleted BIT NOT NULL DEFAULT 0, + CONSTRAINT UQ_Admin_User_Username UNIQUE (Username) +); +``` + +### 2.2 Admin_Role (角色表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| RoleName | nvarchar(50) | Y | 角色名称 | +| RoleCode | nvarchar(50) | Y | 角色编码,唯一 | +| Description | nvarchar(200) | N | 角色描述 | +| Sort | int | Y | 排序,默认0 | +| Status | int | Y | 状态:1正常 2禁用 | +| CreateTime | datetime2 | Y | 创建时间 | +| UpdateTime | datetime2 | N | 更新时间 | +| IsDeleted | bit | Y | 是否删除,默认0 | + +```sql +CREATE TABLE Admin_Role ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + RoleName NVARCHAR(50) NOT NULL, + RoleCode NVARCHAR(50) NOT NULL, + Description NVARCHAR(200), + Sort INT NOT NULL DEFAULT 0, + Status INT NOT NULL DEFAULT 1, + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE(), + UpdateTime DATETIME2, + IsDeleted BIT NOT NULL DEFAULT 0, + CONSTRAINT UQ_Admin_Role_RoleCode UNIQUE (RoleCode) +); +``` + +### 2.3 Admin_Permission (权限表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| PermissionName | nvarchar(50) | Y | 权限名称 | +| PermissionCode | nvarchar(100) | Y | 权限编码,唯一,如:user:view | +| Description | nvarchar(200) | N | 权限描述 | +| Module | nvarchar(50) | Y | 所属模块 | +| CreateTime | datetime2 | Y | 创建时间 | + +```sql +CREATE TABLE Admin_Permission ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + PermissionName NVARCHAR(50) NOT NULL, + PermissionCode NVARCHAR(100) NOT NULL, + Description NVARCHAR(200), + Module NVARCHAR(50) NOT NULL, + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE(), + CONSTRAINT UQ_Admin_Permission_Code UNIQUE (PermissionCode) +); +``` + +### 2.4 Admin_Role_Permission (角色权限关联表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| RoleId | bigint | Y | 角色ID | +| PermissionId | bigint | Y | 权限ID | + +```sql +CREATE TABLE Admin_Role_Permission ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + RoleId BIGINT NOT NULL, + PermissionId BIGINT NOT NULL, + CONSTRAINT UQ_Role_Permission UNIQUE (RoleId, PermissionId) +); +``` + +### 2.5 Admin_User_Role (用户角色关联表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| UserId | bigint | Y | 用户ID | +| RoleId | bigint | Y | 角色ID | + +```sql +CREATE TABLE Admin_User_Role ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + UserId BIGINT NOT NULL, + RoleId BIGINT NOT NULL, + CONSTRAINT UQ_User_Role UNIQUE (UserId, RoleId) +); +``` + +### 2.6 Admin_Menu (菜单表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| ParentId | bigint | Y | 父级ID,0为顶级 | +| MenuName | nvarchar(50) | Y | 菜单名称 | +| MenuType | int | Y | 类型:1目录 2菜单 3按钮 | +| Path | nvarchar(200) | N | 路由路径 | +| Component | nvarchar(200) | N | 组件路径 | +| Icon | nvarchar(50) | N | 图标 | +| PermissionCode | nvarchar(100) | N | 关联权限编码 | +| Sort | int | Y | 排序 | +| IsVisible | bit | Y | 是否可见 | +| IsCache | bit | Y | 是否缓存 | +| Status | int | Y | 状态:1正常 2禁用 | +| CreateTime | datetime2 | Y | 创建时间 | +| UpdateTime | datetime2 | N | 更新时间 | + +```sql +CREATE TABLE Admin_Menu ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + ParentId BIGINT NOT NULL DEFAULT 0, + MenuName NVARCHAR(50) NOT NULL, + MenuType INT NOT NULL, + Path NVARCHAR(200), + Component NVARCHAR(200), + Icon NVARCHAR(50), + PermissionCode NVARCHAR(100), + Sort INT NOT NULL DEFAULT 0, + IsVisible BIT NOT NULL DEFAULT 1, + IsCache BIT NOT NULL DEFAULT 0, + Status INT NOT NULL DEFAULT 1, + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE(), + UpdateTime DATETIME2 +); +``` + +### 2.7 Admin_Role_Menu (角色菜单关联表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| RoleId | bigint | Y | 角色ID | +| MenuId | bigint | Y | 菜单ID | + +```sql +CREATE TABLE Admin_Role_Menu ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + RoleId BIGINT NOT NULL, + MenuId BIGINT NOT NULL, + CONSTRAINT UQ_Role_Menu UNIQUE (RoleId, MenuId) +); +``` + +### 2.8 Admin_Operation_Log (操作日志表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| AdminUserId | bigint | Y | 管理员ID | +| AdminUsername | nvarchar(50) | Y | 管理员用户名(冗余) | +| Module | nvarchar(50) | Y | 操作模块 | +| Action | nvarchar(50) | Y | 操作类型 | +| Description | nvarchar(500) | N | 操作描述 | +| RequestUrl | nvarchar(500) | N | 请求URL | +| RequestMethod | nvarchar(10) | N | 请求方法 | +| RequestParams | nvarchar(max) | N | 请求参数(JSON) | +| ResponseResult | nvarchar(max) | N | 响应结果(JSON) | +| TargetId | nvarchar(50) | N | 操作目标ID | +| Ip | nvarchar(50) | N | IP地址 | +| UserAgent | nvarchar(500) | N | 用户代理 | +| ExecuteTime | int | N | 执行时长(ms) | +| Status | int | Y | 状态:1成功 2失败 | +| ErrorMsg | nvarchar(max) | N | 错误信息 | +| CreateTime | datetime2 | Y | 创建时间 | + +```sql +CREATE TABLE Admin_Operation_Log ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + AdminUserId BIGINT NOT NULL, + AdminUsername NVARCHAR(50) NOT NULL, + Module NVARCHAR(50) NOT NULL, + Action NVARCHAR(50) NOT NULL, + Description NVARCHAR(500), + RequestUrl NVARCHAR(500), + RequestMethod NVARCHAR(10), + RequestParams NVARCHAR(MAX), + ResponseResult NVARCHAR(MAX), + TargetId NVARCHAR(50), + Ip NVARCHAR(50), + UserAgent NVARCHAR(500), + ExecuteTime INT, + Status INT NOT NULL DEFAULT 1, + ErrorMsg NVARCHAR(MAX), + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE() +); + +-- 索引 +CREATE INDEX IX_Admin_Operation_Log_CreateTime ON Admin_Operation_Log(CreateTime DESC); +CREATE INDEX IX_Admin_Operation_Log_AdminUserId ON Admin_Operation_Log(AdminUserId); +CREATE INDEX IX_Admin_Operation_Log_Module ON Admin_Operation_Log(Module); +``` + +--- + +## 三、业务库表设计 (XiangYi_Biz) + +### 3.1 User (用户表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| OpenId | nvarchar(64) | Y | 微信OpenId | +| UnionId | nvarchar(64) | N | 微信UnionId | +| Phone | nvarchar(20) | N | 手机号 | +| Nickname | nvarchar(50) | N | 昵称(如:李家长(父亲)) | +| Avatar | nvarchar(500) | N | 头像URL | +| XiangQinNo | nvarchar(10) | N | 相亲编号(6位数字) | +| Gender | int | N | 用户性别:1男 2女 | +| City | nvarchar(50) | N | 定位城市 | +| Status | int | Y | 状态:1正常 2禁用 | +| IsProfileCompleted | bit | Y | 是否完成资料填写 | +| IsRealName | bit | Y | 是否实名认证 | +| IsMember | bit | Y | 是否会员 | +| MemberLevel | int | Y | 会员等级:0非会员 1不限时 2诚意 3家庭版 | +| MemberExpireTime | datetime2 | N | 会员到期时间(不限时会员为null) | +| ContactCount | int | Y | 剩余联系次数,默认2 | +| LastLoginTime | datetime2 | N | 最后登录时间 | +| CreateTime | datetime2 | Y | 创建时间 | +| UpdateTime | datetime2 | N | 更新时间 | +| IsDeleted | bit | Y | 是否删除 | + +```sql +CREATE TABLE [User] ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + OpenId NVARCHAR(64) NOT NULL, + UnionId NVARCHAR(64), + Phone NVARCHAR(20), + Nickname NVARCHAR(50), + Avatar NVARCHAR(500), + XiangQinNo NVARCHAR(10), + Gender INT, + City NVARCHAR(50), + Status INT NOT NULL DEFAULT 1, + IsProfileCompleted BIT NOT NULL DEFAULT 0, + IsRealName BIT NOT NULL DEFAULT 0, + IsMember BIT NOT NULL DEFAULT 0, + MemberLevel INT NOT NULL DEFAULT 0, + MemberExpireTime DATETIME2, + ContactCount INT NOT NULL DEFAULT 2, + LastLoginTime DATETIME2, + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE(), + UpdateTime DATETIME2, + IsDeleted BIT NOT NULL DEFAULT 0, + CONSTRAINT UQ_User_OpenId UNIQUE (OpenId), + CONSTRAINT UQ_User_XiangQinNo UNIQUE (XiangQinNo) +); + +CREATE INDEX IX_User_Phone ON [User](Phone); +CREATE INDEX IX_User_City ON [User](City); +``` + +### 3.2 User_Profile (用户相亲资料表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| UserId | bigint | Y | 用户ID | +| Relationship | int | Y | 与孩子关系:1父亲 2母亲 3本人 | +| Surname | nvarchar(50) | Y | 姓氏 | +| ChildGender | int | Y | 孩子性别:1男 2女 | +| BirthYear | int | Y | 出生年份 | +| Education | int | Y | 学历 | +| WorkProvince | nvarchar(50) | Y | 工作省份 | +| WorkCity | nvarchar(50) | Y | 工作城市 | +| WorkDistrict | nvarchar(50) | N | 工作区县 | +| Occupation | nvarchar(50) | Y | 职业 | +| MonthlyIncome | int | Y | 月收入档位 | +| Height | int | Y | 身高(cm) | +| Weight | int | Y | 体重(kg) | +| HouseStatus | int | Y | 房产情况 | +| CarStatus | int | Y | 车辆情况 | +| MarriageStatus | int | Y | 婚姻状态 | +| ExpectMarryTime | int | Y | 期望结婚时间 | +| Introduction | nvarchar(500) | Y | 相亲介绍 | +| IsPhotoPublic | bit | Y | 是否公开照片 | +| HomeProvince | nvarchar(50) | N | 家乡省份 | +| HomeCity | nvarchar(50) | N | 家乡城市 | +| WeChatNo | nvarchar(128) | Y | 微信号 | +| CreateTime | datetime2 | Y | 创建时间 | +| UpdateTime | datetime2 | N | 更新时间 | + +```sql +CREATE TABLE User_Profile ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + UserId BIGINT NOT NULL, + Relationship INT NOT NULL, + Surname NVARCHAR(10) NOT NULL, + ChildGender INT NOT NULL, + BirthYear INT NOT NULL, + Education INT NOT NULL, + WorkProvince NVARCHAR(20) NOT NULL, + WorkCity NVARCHAR(20) NOT NULL, + WorkDistrict NVARCHAR(20), + Occupation NVARCHAR(50) NOT NULL, + MonthlyIncome INT NOT NULL, + Height INT NOT NULL, + Weight INT NOT NULL, + HouseStatus INT NOT NULL, + CarStatus INT NOT NULL, + MarriageStatus INT NOT NULL, + ExpectMarryTime INT NOT NULL, + Introduction NVARCHAR(500) NOT NULL, + IsPhotoPublic BIT NOT NULL DEFAULT 1, + HomeProvince NVARCHAR(20), + HomeCity NVARCHAR(20), + WeChatNo NVARCHAR(50) NOT NULL, + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE(), + UpdateTime DATETIME2, + CONSTRAINT UQ_User_Profile_UserId UNIQUE (UserId) +); + +CREATE INDEX IX_User_Profile_ChildGender ON User_Profile(ChildGender); +CREATE INDEX IX_User_Profile_WorkCity ON User_Profile(WorkCity); +CREATE INDEX IX_User_Profile_BirthYear ON User_Profile(BirthYear); +``` + +### 3.3 User_Photo (用户照片表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| UserId | bigint | Y | 用户ID | +| PhotoUrl | nvarchar(500) | Y | 照片URL | +| Sort | int | Y | 排序 | +| CreateTime | datetime2 | Y | 创建时间 | + +```sql +CREATE TABLE User_Photo ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + UserId BIGINT NOT NULL, + PhotoUrl NVARCHAR(500) NOT NULL, + Sort INT NOT NULL DEFAULT 0, + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE() +); + +CREATE INDEX IX_User_Photo_UserId ON User_Photo(UserId); +``` + +### 3.4 User_Requirement (择偶要求表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| UserId | bigint | Y | 用户ID | +| AgeMin | int | Y | 年龄最小值 | +| AgeMax | int | Y | 年龄最大值 | +| HeightMin | int | N | 身高最小值,null表示不限 | +| HeightMax | int | N | 身高最大值 | +| Education | nvarchar(50) | Y | 学历要求(JSON数组) | +| City1Province | nvarchar(20) | Y | 地区1-省 | +| City1City | nvarchar(20) | Y | 地区1-市 | +| City2Province | nvarchar(20) | N | 地区2-省 | +| City2City | nvarchar(20) | N | 地区2-市 | +| MonthlyIncomeMin | int | N | 月收入最小值,null表示不限 | +| MonthlyIncomeMax | int | N | 月收入最大值 | +| HouseStatus | nvarchar(50) | N | 房产要求(JSON数组) | +| CarStatus | nvarchar(50) | N | 车产要求(JSON数组) | +| MarriageStatus | nvarchar(50) | N | 婚姻要求(JSON数组) | +| CreateTime | datetime2 | Y | 创建时间 | +| UpdateTime | datetime2 | N | 更新时间 | + +```sql +CREATE TABLE User_Requirement ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + UserId BIGINT NOT NULL, + AgeMin INT NOT NULL, + AgeMax INT NOT NULL, + HeightMin INT, + HeightMax INT, + Education NVARCHAR(50) NOT NULL, + City1Province NVARCHAR(20) NOT NULL, + City1City NVARCHAR(20) NOT NULL, + City2Province NVARCHAR(20), + City2City NVARCHAR(20), + MonthlyIncomeMin INT, + MonthlyIncomeMax INT, + HouseStatus NVARCHAR(50), + CarStatus NVARCHAR(50), + MarriageStatus NVARCHAR(50), + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE(), + UpdateTime DATETIME2, + CONSTRAINT UQ_User_Requirement_UserId UNIQUE (UserId) +); +``` + +### 3.5 Member (会员表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| UserId | bigint | Y | 用户ID | +| MemberLevel | int | Y | 会员等级:1不限时 2诚意 3家庭版 | +| OrderId | bigint | Y | 关联订单ID | +| StartTime | datetime2 | Y | 开始时间 | +| ExpireTime | datetime2 | N | 到期时间(不限时为null) | +| Status | int | Y | 状态:1生效中 2已过期 | +| CreateTime | datetime2 | Y | 创建时间 | + +```sql +CREATE TABLE Member ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + UserId BIGINT NOT NULL, + MemberLevel INT NOT NULL, + OrderId BIGINT NOT NULL, + StartTime DATETIME2 NOT NULL, + ExpireTime DATETIME2, + Status INT NOT NULL DEFAULT 1, + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE() +); + +CREATE INDEX IX_Member_UserId ON Member(UserId); +``` + +### 3.6 Member_Family (家庭版会员绑定表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| MemberId | bigint | Y | 会员记录ID | +| MasterUserId | bigint | Y | 主账号用户ID | +| BindUserId | bigint | Y | 绑定用户ID | +| CreateTime | datetime2 | Y | 创建时间 | + +```sql +CREATE TABLE Member_Family ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + MemberId BIGINT NOT NULL, + MasterUserId BIGINT NOT NULL, + BindUserId BIGINT NOT NULL, + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE(), + CONSTRAINT UQ_Member_Family UNIQUE (MemberId, BindUserId) +); +``` + +### 3.7 Order (订单表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| OrderNo | nvarchar(32) | Y | 订单号 | +| UserId | bigint | Y | 用户ID | +| OrderType | int | Y | 订单类型:1会员 2实名认证 | +| ProductName | nvarchar(100) | Y | 商品名称 | +| Amount | decimal(10,2) | Y | 订单金额 | +| PayAmount | decimal(10,2) | Y | 实付金额 | +| PayType | int | N | 支付方式:1微信支付 | +| PayTime | datetime2 | N | 支付时间 | +| TransactionId | nvarchar(64) | N | 微信支付交易号 | +| Status | int | Y | 状态:1待支付 2已支付 3已取消 4已退款 | +| Remark | nvarchar(200) | N | 备注 | +| ExpireTime | datetime2 | Y | 订单过期时间 | +| CreateTime | datetime2 | Y | 创建时间 | +| UpdateTime | datetime2 | N | 更新时间 | + +```sql +CREATE TABLE [Order] ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + OrderNo NVARCHAR(32) NOT NULL, + UserId BIGINT NOT NULL, + OrderType INT NOT NULL, + ProductName NVARCHAR(100) NOT NULL, + Amount DECIMAL(10,2) NOT NULL, + PayAmount DECIMAL(10,2) NOT NULL, + PayType INT, + PayTime DATETIME2, + TransactionId NVARCHAR(64), + Status INT NOT NULL DEFAULT 1, + Remark NVARCHAR(200), + ExpireTime DATETIME2 NOT NULL, + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE(), + UpdateTime DATETIME2, + CONSTRAINT UQ_Order_OrderNo UNIQUE (OrderNo) +); + +CREATE INDEX IX_Order_UserId ON [Order](UserId); +CREATE INDEX IX_Order_Status ON [Order](Status); +CREATE INDEX IX_Order_CreateTime ON [Order](CreateTime DESC); +``` + +### 3.8 Real_Name_Auth (实名认证表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| UserId | bigint | Y | 用户ID | +| OrderId | bigint | Y | 关联订单ID | +| RealName | nvarchar(50) | Y | 真实姓名(加密存储) | +| IdCard | nvarchar(128) | Y | 身份证号(加密存储) | +| IdCardFrontUrl | nvarchar(500) | Y | 身份证正面照URL | +| IdCardBackUrl | nvarchar(500) | Y | 身份证反面照URL | +| Status | int | Y | 状态:1待审核 2已通过 3已拒绝 | +| RejectReason | nvarchar(200) | N | 拒绝原因 | +| VerifyTime | datetime2 | N | 审核时间 | +| CreateTime | datetime2 | Y | 创建时间 | + +```sql +CREATE TABLE Real_Name_Auth ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + UserId BIGINT NOT NULL, + OrderId BIGINT NOT NULL, + RealName NVARCHAR(50) NOT NULL, + IdCard NVARCHAR(128) NOT NULL, + IdCardFrontUrl NVARCHAR(500) NOT NULL, + IdCardBackUrl NVARCHAR(500) NOT NULL, + Status INT NOT NULL DEFAULT 1, + RejectReason NVARCHAR(200), + VerifyTime DATETIME2, + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE() +); + +CREATE INDEX IX_Real_Name_Auth_UserId ON Real_Name_Auth(UserId); +``` + +### 3.9 Chat_Session (聊天会话表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| User1Id | bigint | Y | 用户1 ID(较小的ID) | +| User2Id | bigint | Y | 用户2 ID(较大的ID) | +| LastMessageId | bigint | N | 最后一条消息ID | +| LastMessageTime | datetime2 | N | 最后消息时间 | +| User1UnreadCount | int | Y | 用户1未读数 | +| User2UnreadCount | int | Y | 用户2未读数 | +| CreateTime | datetime2 | Y | 创建时间 | +| UpdateTime | datetime2 | N | 更新时间 | + +```sql +CREATE TABLE Chat_Session ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + User1Id BIGINT NOT NULL, + User2Id BIGINT NOT NULL, + LastMessageId BIGINT, + LastMessageTime DATETIME2, + User1UnreadCount INT NOT NULL DEFAULT 0, + User2UnreadCount INT NOT NULL DEFAULT 0, + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE(), + UpdateTime DATETIME2, + CONSTRAINT UQ_Chat_Session UNIQUE (User1Id, User2Id) +); + +CREATE INDEX IX_Chat_Session_User1Id ON Chat_Session(User1Id); +CREATE INDEX IX_Chat_Session_User2Id ON Chat_Session(User2Id); +``` + +### 3.10 Chat_Message (聊天消息表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| SessionId | bigint | Y | 会话ID | +| SenderId | bigint | Y | 发送者ID | +| ReceiverId | bigint | Y | 接收者ID | +| MessageType | int | Y | 消息类型:1文本 2语音 3图片 4交换微信请求 5交换微信结果 6交换照片请求 7交换照片结果 | +| Content | nvarchar(max) | N | 消息内容 | +| VoiceUrl | nvarchar(500) | N | 语音URL | +| VoiceDuration | int | N | 语音时长(秒) | +| ExtraData | nvarchar(max) | N | 扩展数据(JSON) | +| Status | int | Y | 状态:1正常 2已撤回 3已删除 | +| IsRead | bit | Y | 是否已读 | +| CreateTime | datetime2 | Y | 创建时间 | + +```sql +CREATE TABLE Chat_Message ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + SessionId BIGINT NOT NULL, + SenderId BIGINT NOT NULL, + ReceiverId BIGINT NOT NULL, + MessageType INT NOT NULL, + Content NVARCHAR(MAX), + VoiceUrl NVARCHAR(500), + VoiceDuration INT, + ExtraData NVARCHAR(MAX), + Status INT NOT NULL DEFAULT 1, + IsRead BIT NOT NULL DEFAULT 0, + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE() +); + +CREATE INDEX IX_Chat_Message_SessionId ON Chat_Message(SessionId, CreateTime DESC); +CREATE INDEX IX_Chat_Message_ReceiverId ON Chat_Message(ReceiverId, IsRead); +``` + +### 3.11 User_View (浏览记录表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| UserId | bigint | Y | 浏览者ID | +| TargetUserId | bigint | Y | 被浏览者ID | +| ViewCount | int | Y | 当日浏览次数 | +| ViewDate | date | Y | 浏览日期 | +| LastViewTime | datetime2 | Y | 最后浏览时间 | +| CreateTime | datetime2 | Y | 创建时间 | + +```sql +CREATE TABLE User_View ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + UserId BIGINT NOT NULL, + TargetUserId BIGINT NOT NULL, + ViewCount INT NOT NULL DEFAULT 1, + ViewDate DATE NOT NULL, + LastViewTime DATETIME2 NOT NULL, + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE(), + CONSTRAINT UQ_User_View UNIQUE (UserId, TargetUserId, ViewDate) +); + +CREATE INDEX IX_User_View_TargetUserId ON User_View(TargetUserId, ViewDate DESC); +``` + +### 3.12 User_Favorite (收藏表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| UserId | bigint | Y | 收藏者ID | +| TargetUserId | bigint | Y | 被收藏者ID | +| CreateTime | datetime2 | Y | 创建时间 | + +```sql +CREATE TABLE User_Favorite ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + UserId BIGINT NOT NULL, + TargetUserId BIGINT NOT NULL, + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE(), + CONSTRAINT UQ_User_Favorite UNIQUE (UserId, TargetUserId) +); + +CREATE INDEX IX_User_Favorite_TargetUserId ON User_Favorite(TargetUserId); +``` + +### 3.13 User_Unlock (解锁记录表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| UserId | bigint | Y | 解锁者ID | +| TargetUserId | bigint | Y | 被解锁者ID | +| CreateTime | datetime2 | Y | 创建时间 | + +```sql +CREATE TABLE User_Unlock ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + UserId BIGINT NOT NULL, + TargetUserId BIGINT NOT NULL, + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE(), + CONSTRAINT UQ_User_Unlock UNIQUE (UserId, TargetUserId) +); + +CREATE INDEX IX_User_Unlock_TargetUserId ON User_Unlock(TargetUserId); +``` + +### 3.14 Daily_Recommend (每日推荐表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| UserId | bigint | Y | 用户ID | +| RecommendUserId | bigint | Y | 推荐用户ID | +| RecommendDate | date | Y | 推荐日期 | +| Sort | int | Y | 排序 | +| IsViewed | bit | Y | 是否已查看 | +| CreateTime | datetime2 | Y | 创建时间 | + +```sql +CREATE TABLE Daily_Recommend ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + UserId BIGINT NOT NULL, + RecommendUserId BIGINT NOT NULL, + RecommendDate DATE NOT NULL, + Sort INT NOT NULL DEFAULT 0, + IsViewed BIT NOT NULL DEFAULT 0, + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE(), + CONSTRAINT UQ_Daily_Recommend UNIQUE (UserId, RecommendUserId, RecommendDate) +); + +CREATE INDEX IX_Daily_Recommend_UserId_Date ON Daily_Recommend(UserId, RecommendDate DESC); +``` + +### 3.15 Banner (Banner配置表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| Title | nvarchar(100) | Y | 标题 | +| ImageUrl | nvarchar(500) | Y | 图片URL | +| LinkType | int | Y | 链接类型:1内部页面 2外部链接 3小程序 | +| LinkUrl | nvarchar(500) | N | 链接地址 | +| Sort | int | Y | 排序 | +| Status | int | Y | 状态:1启用 2禁用 | +| StartTime | datetime2 | N | 开始时间 | +| EndTime | datetime2 | N | 结束时间 | +| CreateTime | datetime2 | Y | 创建时间 | +| UpdateTime | datetime2 | N | 更新时间 | + +```sql +CREATE TABLE Banner ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + Title NVARCHAR(100) NOT NULL, + ImageUrl NVARCHAR(500) NOT NULL, + LinkType INT NOT NULL DEFAULT 1, + LinkUrl NVARCHAR(500), + Sort INT NOT NULL DEFAULT 0, + Status INT NOT NULL DEFAULT 1, + StartTime DATETIME2, + EndTime DATETIME2, + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE(), + UpdateTime DATETIME2 +); +``` + +### 3.16 System_Config (系统配置表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| ConfigKey | nvarchar(100) | Y | 配置键 | +| ConfigValue | nvarchar(max) | Y | 配置值 | +| ConfigType | nvarchar(50) | Y | 配置类型 | +| Description | nvarchar(200) | N | 描述 | +| CreateTime | datetime2 | Y | 创建时间 | +| UpdateTime | datetime2 | N | 更新时间 | + +```sql +CREATE TABLE System_Config ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + ConfigKey NVARCHAR(100) NOT NULL, + ConfigValue NVARCHAR(MAX) NOT NULL, + ConfigType NVARCHAR(50) NOT NULL, + Description NVARCHAR(200), + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE(), + UpdateTime DATETIME2, + CONSTRAINT UQ_System_Config_Key UNIQUE (ConfigKey) +); +``` + +### 3.17 System_Notification (系统通知表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| Title | nvarchar(100) | Y | 标题 | +| Content | nvarchar(max) | Y | 内容 | +| TargetType | int | Y | 目标类型:1全部用户 2指定用户 | +| TargetUsers | nvarchar(max) | N | 指定用户ID列表(JSON数组) | +| Status | int | Y | 状态:1草稿 2已发布 | +| PublishTime | datetime2 | N | 发布时间 | +| CreateTime | datetime2 | Y | 创建时间 | +| UpdateTime | datetime2 | N | 更新时间 | + +```sql +CREATE TABLE System_Notification ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + Title NVARCHAR(100) NOT NULL, + Content NVARCHAR(MAX) NOT NULL, + TargetType INT NOT NULL DEFAULT 1, + TargetUsers NVARCHAR(MAX), + Status INT NOT NULL DEFAULT 1, + PublishTime DATETIME2, + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE(), + UpdateTime DATETIME2 +); + +CREATE INDEX IX_System_Notification_Status ON System_Notification(Status, PublishTime DESC); +``` + +### 3.18 User_Notification_Read (用户通知已读表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| UserId | bigint | Y | 用户ID | +| NotificationId | bigint | Y | 通知ID | +| ReadTime | datetime2 | Y | 阅读时间 | + +```sql +CREATE TABLE User_Notification_Read ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + UserId BIGINT NOT NULL, + NotificationId BIGINT NOT NULL, + ReadTime DATETIME2 NOT NULL DEFAULT GETDATE(), + CONSTRAINT UQ_User_Notification_Read UNIQUE (UserId, NotificationId) +); +``` + +### 3.19 Popup_Config (弹窗配置表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| PopupType | int | Y | 弹窗类型:1每日首次 2服务号关注 3会员广告 | +| Title | nvarchar(100) | N | 标题 | +| ImageUrl | nvarchar(500) | Y | 背景图URL | +| LinkUrl | nvarchar(500) | N | 跳转链接 | +| ButtonText | nvarchar(50) | N | 按钮文字 | +| Status | int | Y | 状态:1启用 2禁用 | +| CreateTime | datetime2 | Y | 创建时间 | +| UpdateTime | datetime2 | N | 更新时间 | + +```sql +CREATE TABLE Popup_Config ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + PopupType INT NOT NULL, + Title NVARCHAR(100), + ImageUrl NVARCHAR(500) NOT NULL, + LinkUrl NVARCHAR(500), + ButtonText NVARCHAR(50), + Status INT NOT NULL DEFAULT 1, + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE(), + UpdateTime DATETIME2, + CONSTRAINT UQ_Popup_Config_Type UNIQUE (PopupType) +); +``` + +### 3.20 King_Kong (金刚位配置表) + +| 字段名 | 类型 | 是否必填 | 说明 | +|-------|------|---------|------| +| Id | bigint | PK | 主键,自增 | +| Title | nvarchar(50) | Y | 标题 | +| IconUrl | nvarchar(500) | Y | 图标URL | +| LinkType | int | Y | 链接类型 | +| LinkUrl | nvarchar(500) | N | 链接地址 | +| Sort | int | Y | 排序 | +| Status | int | Y | 状态 | +| CreateTime | datetime2 | Y | 创建时间 | +| UpdateTime | datetime2 | N | 更新时间 | + +```sql +CREATE TABLE King_Kong ( + Id BIGINT PRIMARY KEY IDENTITY(1,1), + Title NVARCHAR(50) NOT NULL, + IconUrl NVARCHAR(500) NOT NULL, + LinkType INT NOT NULL DEFAULT 1, + LinkUrl NVARCHAR(500), + Sort INT NOT NULL DEFAULT 0, + Status INT NOT NULL DEFAULT 1, + CreateTime DATETIME2 NOT NULL DEFAULT GETDATE(), + UpdateTime DATETIME2 +); +``` + +--- + +## 四、枚举定义 + +### 4.1 通用状态 +```csharp +public enum Status +{ + Normal = 1, // 正常 + Disabled = 2 // 禁用 +} +``` + +### 4.2 用户相关 +```csharp +public enum Gender +{ + Male = 1, // 男 + Female = 2 // 女 +} + +public enum Relationship +{ + Father = 1, // 父亲 + Mother = 2, // 母亲 + Self = 3 // 本人 +} + +public enum MemberLevel +{ + None = 0, // 非会员 + Unlimited = 1, // 不限时会员 + Sincere = 2, // 诚意会员 + Family = 3 // 家庭版会员 +} +``` + +### 4.3 资料相关 +```csharp +public enum Education +{ + None = 0, // 不限 + HighSchool = 1, // 高中 + Technical = 2, // 中专 + College = 3, // 大专 + Bachelor = 4, // 本科 + Master = 5, // 研究生 + Doctor = 6 // 博士及以上 +} + +public enum HouseStatus +{ + LocalOwned = 1, // 现居地已购房 + HometownOwned = 2, // 家乡已购房 + AfterMarriage = 3, // 婚后购房 + WithParents = 4, // 父母同住 + Renting = 5, // 租房 + Planning = 6 // 近期有购房计划 +} + +public enum CarStatus +{ + Owned = 1, // 已购车 + None = 2, // 无车 + Planning = 3 // 近期购车 +} + +public enum MarriageStatus +{ + Single = 1, // 未婚 + DivorcedNoChild = 2,// 离异未育 + DivorcedWithChild = 3 // 离异已育 +} + +public enum ExpectMarryTime +{ + ASAP = 1, // 尽快结婚 + OneToTwoYears = 2, // 一到两年内 + WhenReady = 3 // 孩子满意就结婚 +} +``` + +### 4.4 订单相关 +```csharp +public enum OrderType +{ + Membership = 1, // 会员 + RealName = 2 // 实名认证 +} + +public enum OrderStatus +{ + Pending = 1, // 待支付 + Paid = 2, // 已支付 + Cancelled = 3, // 已取消 + Refunded = 4 // 已退款 +} + +public enum PayType +{ + WeChat = 1 // 微信支付 +} +``` + +### 4.5 消息相关 +```csharp +public enum MessageType +{ + Text = 1, // 文本 + Voice = 2, // 语音 + Image = 3, // 图片 + ExchangeWeChatRequest = 4, // 交换微信请求 + ExchangeWeChatResult = 5, // 交换微信结果 + ExchangePhotoRequest = 6, // 交换照片请求 + ExchangePhotoResult = 7 // 交换照片结果 +} +``` + +### 4.6 菜单相关 +```csharp +public enum MenuType +{ + Directory = 1, // 目录 + Menu = 2, // 菜单 + Button = 3 // 按钮 +} +``` + +--- + +## 五、索引策略 + +### 5.1 主要查询场景索引 + +| 表名 | 索引字段 | 场景 | +|-----|---------|------| +| User | OpenId | 微信登录查询 | +| User | Phone | 手机号查询 | +| User | City | 按城市筛选 | +| User_Profile | ChildGender | 按性别筛选 | +| User_Profile | WorkCity | 按城市筛选 | +| User_Profile | BirthYear | 按年龄筛选 | +| Chat_Message | SessionId, CreateTime | 聊天记录查询 | +| User_View | TargetUserId, ViewDate | 谁看过我 | +| User_Favorite | TargetUserId | 谁收藏我 | +| User_Unlock | TargetUserId | 谁解锁我 | +| Daily_Recommend | UserId, RecommendDate | 每日推荐 | +| Order | UserId | 用户订单查询 | +| Admin_Operation_Log | CreateTime | 日志时间查询 | + +--- + +## 六、版本记录 + +| 版本 | 日期 | 修改内容 | +|-----|------|---------| +| 1.0 | 2025-12-28 | 初始版本 | diff --git a/docs/相宜相亲_需求文档.docx b/docs/相宜相亲_需求文档.docx new file mode 100644 index 0000000..a11e506 Binary files /dev/null and b/docs/相宜相亲_需求文档.docx differ diff --git a/docs/需求文档.md b/docs/需求文档.md new file mode 100644 index 0000000..d5e7be9 --- /dev/null +++ b/docs/需求文档.md @@ -0,0 +1,357 @@ +相家相亲 需求文档 +一、需求简介 +1. 开发版本:微信小程序。 +2. 功能大纲:参考《完美亲爱》小程序,实现主体功能,即资料填写、信息浏览、用户沟通、会员、消息推送。 +2.1. 消息推送,与服务号关联。 +3. 原型地址:https://modao.cc/proto/CLMLb26ft510c4LoysTKvV/sharing?view_mode=read_only&screen=rbpV1GIXR6fX3ngyI #tb0017_相宜相亲-分享 +二、定位 +1. 小程序通过获得用户IP、网络等参数,获得模糊的用户所在城市。 +1.1. 该城市,用于用户填写资料前,展示相亲用户列表。 +2. 用户填写资料后,以填写的资料为准。 +三、首页弹窗 +(一)首页弹窗基础规则 +1. 满足条件才会弹出。 +1.1. 条件固定,不可配置。 +2. 后台配置可配置:是否启用、弹窗背景图、按钮、弹窗跳转链接。 +2.1. 默认情况下只有两个按钮,跳转按钮、关闭按钮。 +(二)每日首次弹窗 + +每日首次弹窗 +1. 每日首次打开小程序,弹出弹窗。 +2. 弹窗后台可配置。 +3. 点击按钮可关闭弹窗或跳转到指定页面。 +(三)服务号通知权限弹窗 + +1. 用户未关注服务号的情况下,从其他页面返回到首页时弹出。 +2. 弹出后,5分钟内不再弹出。 +3. 一天最多弹出3次。 +4. 点击跳转到服务号的文章页,通过文章内的内容跳转到服务号页面。 +(四)同城群弹窗 +1. 是否需要待定、弹出条件待定。 +2. 因为没有准确的关闭逻辑,即也许用户已经加群了,但系统无法获取,后面仍会频繁触发条件弹出。 +(五)会员弹窗 + +1. 用户未购买会员时,首页导航栏上方显示会员购买入口。 +2. 图片后台可配置。 +3. 点击【购买】跳转至会员页。 +4. 点击关闭后,今日不再出现。 +(六)相亲资料填写提示弹窗 + +1. 优先级最高。 +2. 用户没选择用户列表性别或没填写相亲资料,每次启动小程序时弹出。 +3. 点击【找儿媳】按钮,只展示女生资料。 +4. 点击【找女婿】按钮,只展示男生资料。 +5. 点击【关闭】按钮,关闭弹窗。 +四、首页 + +1. 用户第一次进入小程序时,男女生资料随机展示,后续展示根据用户在不同页面的选择决定。 +2. 搜索框,点击跳转进搜索页。 +3. 首页banner图,后台可配置图片、跳转链接。 +3.1. 跳转的内容,要提前告知,需要做相应的适配。 +4. 金刚位,后台可配置图片、跳转链接。 +4.1. 跳转的内容,要提前告知,需要做相应的适配。 +(一)用户列表 + +1. 共有两种排版,不公开照片、公开照片排版。 +1.1. 不公开照片排版:用户上传资料时,选择“不公开照片”时的排版。 +1.2. 公开照片排版:用户上传资料时,选择“公开照片”时的排版。 +2. 显示用户基础信息。 +3. 如果该用户是会员用户,显示“会员”身份标识。 +4. 如果该用户已完成实名,显示“已实名”身份标识。 +5. 若今天看过某个用户资料,右上角显示“今天看过”标识。 +6. 点击【查看详细资料】,跳转到“资料详情页”。 +7. 点击【联系对方】: +7.1. 若用户没有填写孩子相亲资料,弹出“填写相亲资料弹窗”。点击按钮跳转到 + +7.2. 若当前用户未实名、对方已完成实名认证,跳转到“实名认证页”。 +7.3. 没有解锁联系方式时,弹出“解锁联系方式弹窗”。 + +7.3.1. 解锁联系方式,即可与该用户在小程序内直接聊天。 +7.3.2. 解锁每个用户,将消耗1次联系次数。 +7.3.2.1. 每个用户,赠送2次。 +7.3.3. 次数耗尽,点击【立即增加联系次数】,跳转到“会员页”。 + +7.3.3.1. 不能单独购买,次数都和会员绑定。 +7.4. 已解锁联系方式时,跳转到“聊天页”。 +(二)推荐规则 +1. 每天每个用户,推荐10名用户。 +2. 推荐优先级: +2.1. 全部满足用户资料中“想找什么样的另一半”的全部条件。 +2.2. 逐一减少满足用户资料中“想找什么样的另一半”的条件数量。 +2.3. 与用户现居城市较近的城市。 +2.4. 与用户家乡城市较近的城市。 +3. 每天早上5点刷新用户列表,原则上不会出现3天内推荐过的用户。 +3.1. 若用户数量不足时,可重复推荐。 +(三)会员广告 +1. 未购买会员时,导航栏上方显示会员广告图片,点击【购买】可跳转到会员页。 +1.1. 图片后台可配置。 +2. 点击【关闭】,不再显示。 +(四)小程序自带推送权限提醒 +1. 用户未关注服务号、今日已弹出3次“服务号通知权限弹窗”时,在导航栏上方显示“小程序自带推送权限提醒”。 +1.1. 图片后台可配置。 +1.2. 优先级低于“会员广告”。 +1.2.1. 用户关闭“会员广告”后,本次小程序开启期间,不显示本图片。 +2. 点击【打开】,弹出小程序自带推送权限弹窗。 +3. 点击【关闭】,今日不再弹出。 +五、资料详情页 + +1. 若用户为会员用户,显示对应的会员标识。 +2. 若用户已完成实名,显示“已实名”标识。 +3. 顶部展示用户头像、用户昵称、用户ID。 +4. 点击【分享】,拉起该页面分享链接。 +5. 孩子的照片,根据用户填写资料时的选项,展示对应的UI。 +5.1. 若用户选择了“公开”,直接展示照片。 +5.2. 若用户选择“暂不公开”,模糊蒙版遮挡并显示提示文字。 +6. 页面底部显示尽快联系对方提示悬浮窗,点击【关闭提示】,今日不再出现。 +7. 点击【打招呼】按钮,与首页的【联系对方】规则相同。 +8. 点击【收藏】按钮,收藏该用户,弹出系统提示“已收藏该用户”。 +8.1. 改变按钮状态,变为【已收藏】状态,颜色与原状态做出区分。 +9. 点击【拔打电话】按钮: +9.1. 若未解锁联系方式,与首页的【联系对方】规则相同。 +9.2. 若已解锁,弹出“联系电话弹窗”。 + +9.2.1. 点击【拔打电话】,跳转到手机拔号页,自动录入电话号码。 +9.2.1.1. 因权限问题,无法直接拔打电话。 +六、沟通聊天页 + +1. 用户解锁联系方式后,可进入本页面。 +1.1. 沟通双方有任一一方解锁方式,即可沟通。 +2. 顶部展示用户账号信息、孩子简介。 +2.1. 点击孩子简介,进入资料详情页。 +3. 点击【交换微信】按钮,聊天列表中展示交换提示。 + +3.1. 用户B点击【同意】,聊天列表中相互展示对方的微信号。点击【复制】,复制微信号。 +3.2. 点击【拒绝】,聊天列表中展示拒绝交换的提示。 +4. 点击【拔打电话】按钮,弹出“联系电话弹窗”。 +5. 点击【交换照片】按钮,聊天列表中展示交换提示。 + +5.1. 用户B点击【同意】,聊天列表中相互展示对方孩子的照片列表。 +5.1.1. 点击图片,可放大查看。可左右切换图片。不可下载照片。 +5.2. 点击【拒绝】,聊天列表中展示拒绝交换的提示。 +6. 底部输入框: +6.1. 点击【语音】,可发送单条语音信息。 +6.2. 点击【表情】,呼出表情列表。 +6.3. 点击【发送】,发送文字信息。为空时点击无响应。 +七、搜索页 + +1. 年龄要求,双列选择,最低18岁,最高60岁。 +1.1. 每1岁为一档。 +2. 身高要求,双列选择,最低140cm,最高200cm及以上。 +2.1. 每1cm为一档。 +2.2. 可选择“不限”。 +3. 学历要求,可多选,最少选择一个。 +4. 地区要求,最多可选择2个,默认选择用户在孩子资料中填写的“对方所在地区”。 +4.1. 点击【其他地区】,弹出省市县选择列表。 +5. 月收入要求,双列选择,最低3000,最高2万及以上。 +5.1. 每1000为一档。 +5.2. 可选择“不限”。 +6. 房产要求、车产要求、婚姻要求,可选择的内容,同“相亲资料填写”中可选择的内容。 +7. 点击【立即搜索】: +7.1. 所有选项都为必填项,检测是否有未填写的选项。若有,弹出系统提示“请填写xx项目名称xx”。 +7.2. 检测用户是否为相应等级的会员,若为非会员,展示搜索结果,并提醒用户开通会员。 + +7.2.1. 无法查看用户资料,点击跳转到对应会员页。 +7.3. 若用户为对应会员,正常展示资料。 + +八、相亲资料填写页 +1. 所有页面、所有选项,默认为必填项。当前页面未填完,无法进入下一步。 +(一)孩子基础信息页 + +1. 孩子性别,如果在首页的“相亲资料填写提示弹窗”中选择了性别,此处自动选择相应性别。 +2. 用户填写“与孩子的关系”“您的姓氏”“性别”,自动生成昵称,如“李家长(父亲)”“王家长(母亲)”“王先生(本人)”“张女士(本人)”。 +3. 出生年份: +3.1. 最小年份,自动计算至当前年份为18岁的年份。 +3.2. 最大年份,自动计算至当前年份为50岁的年份。 +4. 学历,可选择:不限、高中、中专、大专、本科、研究生、博士及以上。 +5. 在哪上班,选择孩子所在省市县城市。 +6. 孩子职业,点击弹出职业弹窗。 + +6.1. 在输入框中自定义输入职业,最多9个字。 +6.2. 可选择提交预设好的职业。 +6.3. 当选择预设好的职业时,输入框中的文字自动清空。 +6.4. 输入框或预设职业不为空时,可点击【提交】。 +7. 月收入,多列选择,最低3000,最高3万及以上。 +(二)孩子详细信息页 + +1. 身高,最低130cm及以下,最高200cm及以上。 +2. 体重,最低45kg及以下,最高120kg及以上。 +3. 房产情况:现居地已购房、家乡已购房、婚后购房、父母同住、租房、近期有购房计划。 +4. 车辆情况:已购车、无车、近期购车。 +5. 婚姻状态:未婚、离异未育、离异已育。 +6. 何时结婚:尽快结婚、一到两年内结婚、孩子满意就结婚。 +(三)相亲介绍页 + +1. 自定义录入孩子的相亲介绍情况。 +2. 上传孩子的照片,最多上传5张。 +3. 照片可选择是否公开。 +(四)相亲对象的要求 + +1. 根据孩子的性别,自动更换文字“女方”“男方”。 +2. 可选择两个城市。 +2.1. 第一个城市必选,默认自动选择孩子当前工作地。 +2.2. 第二个城市可选,非必填。 +3. 月收入可选择“不限”。 +(五)联系方式填写 + +1. 分为两步,先填写微信号、再获取手机号。 +2. 未填写微信号时,【验证手机号】为灰色不可点击。 +3. 填写微信号后,点击【验证手机号】弹出小程序获取手机号权限提示弹窗。 +4. 获取手机号后,流程结束,保存存上传资料,返回上级页面。 +九、消息页 + +1. 显示“看过我”“收藏我”“解锁我”的用户数量,点击跳转到对应页面。 +1.1. 右上角显示新增的数量提示。 +2. 显示我和沟通的用户聊天记录列表。 +2.1. 显示用户头像、昵称、双方最后一句聊天内容、时间。 +3. 当有未读消息时,对应按钮右上角显示未读的消息。 +(一)看过我页 + +1. 显示用户在哪一天、哪个时间看了我、看过我几次、显示对方的资料。 +1.1. 当天看过我,显示哪个时间看了我。 +1.2. 超过当天,不显示时间,只显示“看过我”。 +1.3. 三天内,显示“今天”“昨天”“前天”。超过3天,显示对应日期 +1.4. 例:“今天15:21看过我”“昨天看过我”“10月1号看过我” +2. 其他用户只看过我1次、超过1次,显示不同的提示文字背景。 +3. 若用户为非对应权限的会员: +3.1. 页面底部悬浮显示会员宣传,无法关闭,点击跳转到会员页。 +3.2. 点击用户资料,跳转到会员页。 +(二)我看过的页 + +1. 显示我近14天浏览记录。 +1.1. 进入资料详情页,视为浏览记录。 +2. 三天内浏览的,显示“今天/昨天/前天 我看过的”。 +3. 超过三天,显示对应日期“10月1号 我看过的”。 +4. 若用户为非对应权限的会员: +3.3. 页面底部悬浮显示会员宣传,无法关闭,点击跳转到会员页。 +3.4. 用户资料,覆盖一层模糊蒙版。 +(三)收藏我页 + +1. 显示用户在哪一天收藏了我: +1.1. 当天收藏我,显示“今天”+“时间点”+“收藏了我”。 +1.2. 超过当天,显示“昨天/前天收藏了我”。 +1.3. 超过3天,显示“日期”+“收藏了我”。 +1.4. 例:10月1号收藏了我。 +2. 若用户为非对应权限的会员: +2.1. 页面底部悬浮显示会员宣传,无法关闭,点击跳转到会员页。 +(四)我收藏的页 + +1. 显示哪一天收藏的。 +1.1. 三天内,显示“今天”“昨天”“前天”。 +1.2. 超过三天,显示日期。 +(五)解锁我页 + +1. 显示用户在哪一天解锁了我的联系方式。 +2. 当天解锁的,显示“今天”+“时间点”+“解锁了我”。 +2.1. 例:今天13:12解锁了我。 +3. 三天内解锁的,显示“昨天/前天解锁了我”。 +4. 超过三天的,显示“日期”+“解锁了我”。 +4.1. 例:10月1号解锁了我。 +(六)我解锁的页 + +1. 三天内解锁的,显示“今天/昨天/前天 我解锁的”。 +2. 超过三天,显示“日期 我解锁的”。 +2.1. 例:10月1号 我解锁的。 +(七)空状态页 + +1. 每个页面有空状态,显示对应文字。 +2. 点击【去相亲】按钮,跳转到首页。 +(八)系统消息页 +1. 点击系统消息,跳转到系统消息页。 + +1.1. 可向全部用户、指定用户发送消息。 +十、我的页 + +1. 未登录时提醒用户登录。 +2. 登录后,若用户未填写相亲资料,提醒填写资料。 + +2.1. 点击【立即填写】,跳转到“相亲资料填写页”。 +3. 点击头像或昵称,跳转到“个人资料页”。 + +3.1. 只能修改头像,可手动获取微信头像。 +4. 用户填写相亲资料后,显示资料简介。 + +4.1. 固定展示图片。 +5. 点击【预览资料】,跳转到“资料预览页”。 + +5.1. 点击【分享】,拉起该页分享链接。 +5.2. 点击【编辑资料】,跳转到“相亲资料填写页”,重新走流程,自动填充已填写的内容。 +6. 点击【编辑资料】,跳转到“相亲资料填写页”,重新走流程,自动填充已填写的内容。 +7. 相亲编号,随机6位数字,0不做为开头数字。 +8. 点击【会员宣传入口图】,跳转到“会员页”。 +9. 点击【管家指导】,弹出“客服二维码弹窗”。 + +9.1. 图片后台可配置。 +10. 点击【实名认证】,跳转到实名认证页。 + +10.1. 点击【联系管家】,弹出“客服二维码弹窗”。 +10.2. 点击【开通会员】,跳转到“会员页”。 +10.3. 点击【88元认证】,拉起微信支付。 +10.4. 成功支付后,进入“实名认证资料页”。 +10.4.1. 下次进入实名认证页,直接进入“实名认证资料页”或实名认证结果页。 +10.5. 实名认证资料页,上传身份证正反面、填写身份证号码、姓名。 + +10.5.1. 所有选项为必填项。 +10.5.2. 提交时: +10.5.2.1. 照片为空时,弹出系统提示“请上传身份证照片”。 +10.5.2.2. 正则检查“身份证”号码,有误时弹出系统提示“身份证号码错误”。 +10.5.2.3. 正则检查“姓名”,有误时弹出系统提示“姓名有误”。 +10.5.2.4. 无问题,提交内容至阿里实名,等待结果返回。 +10.5.3. 若通过实名认证,跳转到“实名认证结果页”。 + +10.5.4. 姓名、身份证以“*”遮盖。 +十一、会员 + +参考图 +1. 共有三种会员等级: +1.1. 限时会员。 +1.2. 诚意会员。 +1.3. 诚意会员(家庭版)。 +2. 高等级会员继承低等级会员所有权益。 +3. 详情页面效果,需美术设计出图。 +(一)不限时会员 +1. 不限时会员,1299元,不限制时间。 +2. 权益: +2.1. 每日推荐用户数量,24人。 +2.2. 免费实名认证。 +2.3. 新资源优先推荐。 +2.3.1. 首次填写资料的用户,前30分钟优先推荐给会员用户。10分钟后再推荐给普通用户。 +2.4. 管家陪伴指导。 +2.4.1. 需要用户主动增加客服微信。 +(二)诚意会员 +1. 诚意会员,1999元,不限制时间。 +2. 权益: +2.1. 每日推荐用户数量24~29人。 +2.2. 可查看所有推荐过的用户资料,直接在首页列表展示,向下划动加载。 +2.3. 双向匹配相亲资料。 +2.3.1. 可去掉,无实际意义和功能。 +2.3.2. 不用展示。 +2.4. 同城置顶曝光资料。 +2.4.1. 男女方同一城市、满足条件的情况下,会员用户置顶显示。 +2.5. 无门槛被联系。 +2.5.1. 无实际意义和功能,不用展示。 +2.6. 优质资源优先推荐 +2.6.1. 同条件下,优先推送。 +2.7. 直播音情感老师优先连麦情感咨询。 +2.7.1. 通过线下微信联系客服。 +2.8. 管理陪伴指导:解答相亲过程中任何问题。 +2.8.1. 通过线下微信联系客服。 +2.9. 精准搜索:可定制详细条件资源库进行搜索,每日搜索最多5位,精准度更高加速脱单。 +2.10. 情感指导:情感老师进行一次单独指导,解答相亲中遇到的任何问题推荐孩子感情发展。 +2.10.1. 通过线下微信联系客服。 +(三)诚意会员(家庭版) +1. 诚意会员(家庭版),2999元。 +2. 权益: +2.1. 包含诚意会员所有功能服务。 +2.2. 家庭账号:父母孩子可同时使用。 +2.2.1. 算上用户本人,共可绑定3名用户。 +2.2.2. 开通家庭版后,在会员页填写要绑定的用户微信ID。 +2.2.3. 只同步会员身份、相亲资料,其他信息不同步。 +2.3. 情感课程:持续更新的成功案例分析,情感分析,助力家长不走弯路 +2.3.1. 通过线下微信联系客服。 +2.4. 帮婚训练营:国家认证情感老师直播授课,深度解决孩子情感问题,提升父母帮婚能力。 +2.4.1. 通过线下微信联系客服。 +十二、服务号通知 +1. 有用户解锁我、收藏我时,服务号发送相应通知。 +2. 有用户通过小程序聊天首次沟通我时,服务号发送相应通知。 +3. 有用户通过小程序聊天沟通我,我5分钟没回复时,服务号发送相应通知。 +4. 每天更新推荐列表时,服务号在早上8~10点随机时间发送相应通知。 diff --git a/docs/需求文档与原型图对比分析.md b/docs/需求文档与原型图对比分析.md new file mode 100644 index 0000000..bbe6c9f --- /dev/null +++ b/docs/需求文档与原型图对比分析.md @@ -0,0 +1,192 @@ +# 需求文档与原型图对比分析 + +> 分析日期:2025-12-28 +> 项目名称:相宜相亲 微信小程序 + +--- + +## 一、原型图中已有,需求文档中也有的功能 + +| 功能模块 | 状态 | 说明 | +|---------|------|------| +| 首页用户列表 | ✅ 一致 | 公开/不公开照片两种排版 | +| 搜索页 | ✅ 一致 | 年龄、身高、学历、地区、收入、房产、车产、婚姻筛选 | +| 资料填写流程 | ✅ 一致 | 5步流程:基本信息→详细信息→相亲介绍→择偶要求→联系方式 | +| 详细资料页 | ✅ 一致 | 用户信息、孩子资料、照片、分享按钮 | +| 消息页 | ✅ 一致 | 看过我/收藏我/解锁我统计 + 聊天列表 | +| 看过我页/我看过的页 | ✅ 一致 | 包含时间显示规则 | +| 收藏我页/我收藏的页 | ✅ 一致 | 包含时间显示规则 | +| 解锁我页/我解锁的页 | ✅ 一致 | 包含时间显示规则 | +| 空状态页 | ✅ 一致 | "还没有人看过/收藏/解锁/我" | +| 聊天室 | ✅ 一致 | 交换微信、拨打电话、交换照片功能 | +| 解锁联系方式弹窗 | ✅ 一致 | 消耗联系次数提示 | +| 联系电话弹窗 | ✅ 一致 | 显示电话号码,点击拨打 | +| 我的页面 | ✅ 一致 | 未登录/未填写资料/已填写资料 三种状态 | +| 个人资料页 | ✅ 一致 | 头像、相亲编号 | +| 实名认证资料页 | ✅ 一致 | 上传身份证正反面、填写信息 | +| 实名认证结果页 | ✅ 一致 | 显示已完成认证,姓名身份证脱敏显示 | +| 相亲资料填写提示弹窗 | ✅ 一致 | 找儿媳/找女婿选择 | +| 同城群弹窗 | ✅ 一致 | 邀请进入同城相亲群 | +| 红包弹窗 | ✅ 一致 | 双签惊喜红包 | +| 通知/系统消息页 | ✅ 一致 | 系统消息列表 | + +--- + +## 二、需求文档中有,但原型图中缺失或不明确的功能 + +### 2.1 完全缺失的页面/功能 + +| 功能 | 需求文档描述 | 重要程度 | +|-----|-------------|---------| +| **会员页面** | 三种会员等级详情页:不限时会员(1299元)、诚意会员(1999元)、诚意会员家庭版(2999元),包含权益对比、购买流程 | ⭐⭐⭐ 高 | +| **实名认证入口页** | 显示联系管家、开通会员、88元认证按钮,需付费后才能进入资料填写 | ⭐⭐⭐ 高 | +| **搜索结果页** | 非会员看到搜索结果但无法查看详情,需提醒开通会员;会员可正常查看 | ⭐⭐⭐ 高 | +| **服务号通知权限弹窗** | 用户未关注服务号时弹出,引导关注服务号,5分钟内不再弹出,一天最多3次 | ⭐⭐ 中 | +| **每日首次弹窗** | 每日首次打开小程序弹出,后台可配置图片和跳转链接 | ⭐⭐ 中 | +| **小程序推送权限提醒** | 导航栏上方显示,引导用户开启小程序推送权限 | ⭐⭐ 中 | +| **填写相亲资料弹窗** | 点击"联系对方"时,若用户未填写资料弹出提醒跳转填写 | ⭐⭐ 中 | +| **联系次数耗尽弹窗** | 次数耗尽时提示"立即增加联系次数",跳转会员页 | ⭐⭐ 中 | +| **客服二维码弹窗** | 点击"管家指导"后弹出客服微信二维码,图片后台可配置 | ⭐ 低 | +| **家庭版会员绑定页** | 开通家庭版后,填写要绑定的用户微信ID,最多绑定3人 | ⭐ 低 | + +### 2.2 部分缺失或不明确 + +| 功能 | 需求文档描述 | 原型图现状 | +|-----|-------------|-----------| +| **会员广告条位置** | 首页导航栏上方显示,可关闭 | 原型图在页面底部有,但导航栏上方没有 | +| **资料预览页** | 从"我的"页面点击预览资料,可分享和编辑 | 只看到详细资料页,未明确区分预览页与详情页 | +| **尽快联系提示悬浮窗** | 资料详情页底部显示,点击关闭后今日不再出现 | 未看到此UI元素 | + +--- + +## 三、原型图中有,但需求文档中描述不够详细的功能 + +| 功能 | 原型图展示 | 建议补充 | +|-----|-----------|---------| +| **脱单小助手** | 首页出现相关UI | 需明确功能定义和交互逻辑 | +| **200元优惠倒计时** | 首页底部有限时优惠促销UI,显示倒计时 | 需明确优惠规则、倒计时结束后的处理 | +| **Banner图配置** | 原型图有Banner占位 | 需明确尺寸规范、轮播规则、跳转类型 | +| **金刚位配置** | 原型图显示4个金刚位 | 需明确图标规范、跳转页面类型 | + +--- + +## 四、建议补充的原型图 + +### 4.1 高优先级(核心付费功能) + +1. **会员购买页面** + - 三种会员等级展示 + - 权益对比列表 + - 价格和购买按钮 + - 支付流程 + +2. **实名认证入口页** + - 认证说明 + - 88元支付按钮 + - 联系管家入口 + - 开通会员入口 + +3. **搜索结果页** + - 会员用户看到的结果列表 + - 非会员用户看到的模糊结果 + 开通会员提示 + +### 4.2 中优先级(用户体验相关) + +4. **服务号关注引导弹窗** + - 弹窗UI设计 + - 关注引导文案 + +5. **每日首次弹窗** + - 弹窗模板设计 + - 按钮布局 + +6. **联系次数耗尽提示** + - 提示文案 + - 跳转会员页按钮 + +7. **填写资料提醒弹窗** + - 提示文案 + - 跳转填写按钮 + +### 4.3 低优先级 + +8. **客服二维码弹窗** +9. **家庭版绑定用户页面** +10. **小程序推送权限提醒条** + +--- + +## 五、功能完整性统计 + +| 类别 | 数量 | 占比 | +|-----|------|------| +| 需求文档和原型图一致 | 20+ | 约 65% | +| 需求有但原型缺失 | 10 | 约 25% | +| 原型有但需求描述不足 | 3-4 | 约 10% | + +--- + +## 六、后续行动建议 + +### 6.1 设计侧 + +- [ ] 补充会员购买页面设计 +- [ ] 补充实名认证入口页设计 +- [ ] 补充搜索结果页设计 +- [ ] 补充各类弹窗设计(服务号、每日首次、次数耗尽等) +- [ ] 确认会员广告条的位置(导航栏上方 vs 页面底部) + +### 6.2 产品侧 + +- [ ] 完善脱单小助手功能说明 +- [ ] 完善限时优惠活动规则 +- [ ] 明确Banner和金刚位的配置规范 +- [ ] 确认资料预览页与详情页是否为同一页面 + +### 6.3 开发侧 + +- [ ] 对于缺失原型的页面,开发前需与设计确认UI +- [ ] 后台管理系统需支持:弹窗配置、Banner配置、金刚位配置、会员管理等 + +--- + +## 附录:原型图文件清单 + +``` +docs/原型图/ +├── 首页_1.png - 首页主界面 +├── 首页弹窗.png - 红包弹窗 +├── 首页弹窗 8.png - 择偶要求填写 +├── 首页弹窗 12.png - 相亲介绍填写 +├── 搜索.png - 搜索筛选页 +├── 资料填写.png - 性别选择弹窗 +├── 资料填写 (2).png - 基本信息填写(1/5) +├── 资料填写 (3).png - 联系方式填写(5/5) +├── 资料填写 10.png - 详细信息填写(2/5) +├── 资料填写 11.png - 职业选择弹窗 +├── 详细资料.png - 详细资料页(小图) +├── 详细资料 13.png - 详细资料页(照片不公开) +├── 详细资料 25.png - 详细资料页(照片公开) +├── 解锁联系方式.png - 解锁联系方式弹窗 +├── 解锁联系方式 3.png - 联系电话弹窗 +├── 消息.png - 消息页主界面 +├── 消息 14.png - 看过我页 +├── 消息 15.png - 我看过的页 +├── 消息 16.png - 收藏我页 +├── 消息 17.png - 我收藏的页 +├── 消息 18.png - 解锁我页 +├── 消息 19.png - 我解锁的页 +├── 消息 20.png - 空状态页 +├── 消息 21.png - 我的页(未登录) +├── 消息 23.png - 我的页(未填写资料) +├── 消息 24.png - 我的页(已填写资料) +├── 消息 26.png - 个人资料页 +├── 消息 27.png - 实名认证资料页 +├── 消息 28.png - 实名认证结果页 +├── 聊天室.png - 聊天室界面 +├── 同城群.png - 同城群邀请弹窗 +├── 同城群 2.png - 同城群相关 +├── 通知.png - 通知/系统消息页 +├── 通知权限.png - 通知权限相关 +└── Thumbs.db - 系统缩略图缓存 +``` \ No newline at end of file