xiangyixiangqin/server/技术栈与开发规范.md
2025-12-28 22:16:58 +08:00

18 KiB
Raw Permalink Blame History

相宜相亲 - 技术栈与开发规范

版本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 云服务抽象设计

为支持多云服务商切换,所有第三方云服务采用接口抽象 + 依赖注入模式:

// ============ 文件存储抽象 ============
public interface IStorageProvider
{
    Task<string> UploadAsync(Stream stream, string fileName, string folder);
    Task<bool> DeleteAsync(string fileKey);
    string GetAccessUrl(string fileKey, int expireMinutes = 30);
}

// 腾讯云COS实现
public class TencentCosProvider : IStorageProvider { ... }

// 阿里云OSS实现
public class AliyunOssProvider : IStorageProvider { ... }

// ============ 短信服务抽象 ============
public interface ISmsProvider
{
    Task<bool> SendVerifyCodeAsync(string phone, string code);
    Task<bool> SendNotificationAsync(string phone, string templateId, Dictionary<string, string> parameters);
}

// 阿里云短信实现
public class AliyunSmsProvider : ISmsProvider { ... }

// 腾讯云短信实现
public class TencentSmsProvider : ISmsProvider { ... }

// ============ 实名认证抽象 ============
public interface IRealNameProvider
{
    Task<RealNameResult> VerifyIdCardAsync(string name, string idCard);
    Task<RealNameResult> VerifyIdCardWithPhotoAsync(string name, string idCard, string photoBase64);
}

// 腾讯云实现
public class TencentRealNameProvider : IRealNameProvider { ... }

// 阿里云实现
public class AliyunRealNameProvider : IRealNameProvider { ... }

配置示例 (appsettings.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"
      }
    }
  }
}

依赖注入注册:

// 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<IStorageProvider, TencentCosProvider>();
        else
            services.AddSingleton<IStorageProvider, AliyunOssProvider>();

        // 短信服务
        var smsProvider = config["CloudServices:Sms:Provider"];
        if (smsProvider == "AliyunSms")
            services.AddSingleton<ISmsProvider, AliyunSmsProvider>();
        else
            services.AddSingleton<ISmsProvider, TencentSmsProvider>();

        // 实名认证
        var realNameProvider = config["CloudServices:RealName:Provider"];
        if (realNameProvider == "TencentRealName")
            services.AddSingleton<IRealNameProvider, TencentRealNameProvider>();
        else
            services.AddSingleton<IRealNameProvider, AliyunRealNameProvider>();

        return services;
    }
}

三、项目结构规范

3.1 命名空间规范

// 核心层
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  小程序的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 统一响应格式

// 成功响应
{
    "code": 0,
    "message": "success",
    "data": { ... }
}

// 错误响应
{
    "code": 40001,
    "message": "手机号格式不正确",
    "data": ["手机号格式不正确"]
}

// 分页响应
{
    "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 第三方服务错误
// 示例
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 表命名规范

-- 使用Pascal命名单数形式
User              -- 用户表
UserProfile       -- 用户相亲资料表
Member            -- 会员表
Order             -- 订单表
ChatMessage       -- 聊天消息表
UserView          -- 用户浏览记录表
UserFavorite      -- 用户收藏表
UserUnlock        -- 用户解锁记录表
SystemConfig      -- 系统配置表
Banner            -- Banner表
AdminUser         -- 管理员表

5.2 字段命名规范

-- 主键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配置

[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配置

// appsettings.json
{
    "Jwt": {
        "Secret": "your-256-bit-secret-key-here",
        "Issuer": "XiangYiXiangQin",
        "Audience": "XiangYiApp",
        "ExpireMinutes": 10080  // 7天
    }
}

6.3 敏感数据处理

// 手机号脱敏
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 已确认的技术选型

  • 小程序开发框架:uni-app
  • 即时通讯方案:SignalR自建
  • 文件存储:腾讯云COS已抽象可切换阿里云OSS
  • 短信服务商:阿里云SMS已抽象可切换腾讯云SMS
  • 实名认证服务商:腾讯云(已抽象,可切换阿里云)

9.2 需要确认的业务问题

  • 是否需要后台审核用户资料?
  • 聊天消息是否需要敏感词过滤?
  • 是否需要举报功能?
  • 数据备份策略?

十、版本记录

版本 日期 修改内容
1.0 2025-12-28 初始版本
1.1 2025-12-28 确认技术选型uni-app、SignalR新增云服务抽象设计支持多服务商切换