396 lines
8.2 KiB
Markdown
396 lines
8.2 KiB
Markdown
|
|
# 开发指南
|
|||
|
|
|
|||
|
|
## 项目架构说明
|
|||
|
|
|
|||
|
|
### 算命业务流程
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
用户提交卜卦请求
|
|||
|
|
↓
|
|||
|
|
选择支付方式
|
|||
|
|
↓
|
|||
|
|
调用支付API
|
|||
|
|
↓
|
|||
|
|
支付成功后
|
|||
|
|
↓
|
|||
|
|
传统算法计算命盘
|
|||
|
|
↓
|
|||
|
|
AI大模型解读结果
|
|||
|
|
↓
|
|||
|
|
返回完整结果给用户
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 需要实现的核心服务
|
|||
|
|
|
|||
|
|
### 1. 支付服务实现
|
|||
|
|
|
|||
|
|
#### 支付宝支付示例结构
|
|||
|
|
```csharp
|
|||
|
|
// backend/FateMaster.API/Services/Payment/AlipayService.cs
|
|||
|
|
public class AlipayService : IPaymentService
|
|||
|
|
{
|
|||
|
|
public async Task<PaymentResult> CreateOrder(decimal amount, string orderId)
|
|||
|
|
{
|
|||
|
|
// 调用支付宝SDK创建订单
|
|||
|
|
// 返回支付链接或二维码
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public async Task<bool> VerifyCallback(Dictionary<string, string> parameters)
|
|||
|
|
{
|
|||
|
|
// 验证支付宝回调签名
|
|||
|
|
// 更新订单状态
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### PayPal支付示例结构
|
|||
|
|
```csharp
|
|||
|
|
// backend/FateMaster.API/Services/Payment/PayPalService.cs
|
|||
|
|
public class PayPalService : IPaymentService
|
|||
|
|
{
|
|||
|
|
public async Task<PaymentResult> CreateOrder(decimal amount, string orderId)
|
|||
|
|
{
|
|||
|
|
// 调用PayPal API创建订单
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public async Task<bool> CapturePayment(string paymentId)
|
|||
|
|
{
|
|||
|
|
// 捕获支付
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Stripe支付示例结构
|
|||
|
|
```csharp
|
|||
|
|
// backend/FateMaster.API/Services/Payment/StripeService.cs
|
|||
|
|
public class StripeService : IPaymentService
|
|||
|
|
{
|
|||
|
|
public async Task<PaymentResult> CreatePaymentIntent(decimal amount, string orderId)
|
|||
|
|
{
|
|||
|
|
// 使用Stripe.net SDK
|
|||
|
|
// 创建PaymentIntent
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. AI解读服务实现
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// backend/FateMaster.API/Services/AI/AIService.cs
|
|||
|
|
public class AIService
|
|||
|
|
{
|
|||
|
|
private readonly HttpClient _httpClient;
|
|||
|
|
private readonly string _apiKey;
|
|||
|
|
private readonly string _model;
|
|||
|
|
|
|||
|
|
public async Task<string> InterpretDivination(string type, string traditionalResult)
|
|||
|
|
{
|
|||
|
|
// 构建提示词
|
|||
|
|
var prompt = BuildPrompt(type, traditionalResult);
|
|||
|
|
|
|||
|
|
// 调用OpenAI API
|
|||
|
|
var response = await _httpClient.PostAsync("chat/completions", new
|
|||
|
|
{
|
|||
|
|
model = _model,
|
|||
|
|
messages = new[]
|
|||
|
|
{
|
|||
|
|
new { role = "system", content = "你是一位专业的命理大师" },
|
|||
|
|
new { role = "user", content = prompt }
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 解析返回结果
|
|||
|
|
return await ParseResponse(response);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private string BuildPrompt(string type, string traditionalResult)
|
|||
|
|
{
|
|||
|
|
switch (type)
|
|||
|
|
{
|
|||
|
|
case "bazi":
|
|||
|
|
return $"请根据以下八字命盘进行详细解读:{traditionalResult}";
|
|||
|
|
case "tarot":
|
|||
|
|
return $"请解读以下塔罗牌组合:{traditionalResult}";
|
|||
|
|
// ... 其他类型
|
|||
|
|
default:
|
|||
|
|
return traditionalResult;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 批八字算法实现
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// backend/FateMaster.API/Services/Divination/BaZiService.cs
|
|||
|
|
public class BaZiService
|
|||
|
|
{
|
|||
|
|
public BaZiResult Calculate(BaZiInput input)
|
|||
|
|
{
|
|||
|
|
// 1. 转换公历/农历
|
|||
|
|
var solarDate = ConvertToSolar(input);
|
|||
|
|
|
|||
|
|
// 2. 计算四柱
|
|||
|
|
var fourPillars = CalculateFourPillars(solarDate);
|
|||
|
|
|
|||
|
|
// 3. 排大运
|
|||
|
|
var majorCycles = CalculateMajorCycles(fourPillars, input.Gender);
|
|||
|
|
|
|||
|
|
// 4. 五行分析
|
|||
|
|
var elements = AnalyzeElements(fourPillars);
|
|||
|
|
|
|||
|
|
// 5. 十神分析
|
|||
|
|
var tenGods = AnalyzeTenGods(fourPillars);
|
|||
|
|
|
|||
|
|
return new BaZiResult
|
|||
|
|
{
|
|||
|
|
FourPillars = fourPillars,
|
|||
|
|
MajorCycles = majorCycles,
|
|||
|
|
Elements = elements,
|
|||
|
|
TenGods = tenGods
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private FourPillars CalculateFourPillars(DateTime date)
|
|||
|
|
{
|
|||
|
|
// 天干地支计算逻辑
|
|||
|
|
// 年柱、月柱、日柱、时柱
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4. 塔罗牌服务实现
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// backend/FateMaster.API/Services/Divination/TarotService.cs
|
|||
|
|
public class TarotService
|
|||
|
|
{
|
|||
|
|
private readonly Dictionary<int, TarotCard> _cards;
|
|||
|
|
|
|||
|
|
public TarotResult Interpret(List<int> selectedCardIds, string question)
|
|||
|
|
{
|
|||
|
|
var cards = selectedCardIds.Select(id => _cards[id]).ToList();
|
|||
|
|
|
|||
|
|
// 三张牌的位置含义
|
|||
|
|
var positions = new[]
|
|||
|
|
{
|
|||
|
|
"过去/问题根源",
|
|||
|
|
"现在/当前状况",
|
|||
|
|
"未来/发展趋势"
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var interpretation = new StringBuilder();
|
|||
|
|
for (int i = 0; i < cards.Count; i++)
|
|||
|
|
{
|
|||
|
|
interpretation.AppendLine($"{positions[i]}: {cards[i].Name}");
|
|||
|
|
interpretation.AppendLine(cards[i].Meaning);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return new TarotResult
|
|||
|
|
{
|
|||
|
|
Cards = cards,
|
|||
|
|
Interpretation = interpretation.ToString()
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 数据库迁移命令
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 创建迁移
|
|||
|
|
dotnet ef migrations add MigrationName
|
|||
|
|
|
|||
|
|
# 应用迁移
|
|||
|
|
dotnet ef database update
|
|||
|
|
|
|||
|
|
# 回滚迁移
|
|||
|
|
dotnet ef database update PreviousMigrationName
|
|||
|
|
|
|||
|
|
# 删除最后一次迁移
|
|||
|
|
dotnet ef migrations remove
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## API接口文档
|
|||
|
|
|
|||
|
|
### 用户端API
|
|||
|
|
|
|||
|
|
#### 获取价格列表
|
|||
|
|
```
|
|||
|
|
GET /api/divination/prices
|
|||
|
|
Response: [
|
|||
|
|
{ "ServiceType": "bazi", "Price": 99, "Currency": "CNY" }
|
|||
|
|
]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 提交卜卦请求
|
|||
|
|
```
|
|||
|
|
POST /api/divination/submit
|
|||
|
|
Body: {
|
|||
|
|
"Type": "bazi",
|
|||
|
|
"InputData": "{ ... }",
|
|||
|
|
"PaymentMethod": "alipay",
|
|||
|
|
"Amount": 99
|
|||
|
|
}
|
|||
|
|
Response: {
|
|||
|
|
"Id": 123,
|
|||
|
|
"PaymentUrl": "https://..."
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 获取卜卦结果
|
|||
|
|
```
|
|||
|
|
GET /api/divination/{id}
|
|||
|
|
Response: {
|
|||
|
|
"Id": 123,
|
|||
|
|
"Type": "bazi",
|
|||
|
|
"TraditionalResult": "{ ... }",
|
|||
|
|
"AIInterpretation": "根据您的八字..."
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 管理后台API
|
|||
|
|
|
|||
|
|
#### 获取统计数据
|
|||
|
|
```
|
|||
|
|
GET /api/admin/records/statistics
|
|||
|
|
Response: {
|
|||
|
|
"total": 1000,
|
|||
|
|
"paidCount": 800,
|
|||
|
|
"totalRevenue": 79200,
|
|||
|
|
"typeStats": [...]
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 获取记录列表
|
|||
|
|
```
|
|||
|
|
GET /api/admin/records?page=1&pageSize=20&type=bazi
|
|||
|
|
Response: {
|
|||
|
|
"total": 100,
|
|||
|
|
"data": [...]
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 更新价格配置
|
|||
|
|
```
|
|||
|
|
PUT /api/admin/prices/{id}
|
|||
|
|
Body: {
|
|||
|
|
"Price": 99,
|
|||
|
|
"IsEnabled": true
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 前端开发规范
|
|||
|
|
|
|||
|
|
### 组件命名
|
|||
|
|
- 页面组件:PascalCase (例如:BaZi.vue)
|
|||
|
|
- 布局组件:PascalCase + Layout (例如:MainLayout.vue)
|
|||
|
|
- 通用组件:PascalCase (例如:PaymentModal.vue)
|
|||
|
|
|
|||
|
|
### API调用封装
|
|||
|
|
```typescript
|
|||
|
|
// src/api/divination.ts
|
|||
|
|
import axios from 'axios'
|
|||
|
|
|
|||
|
|
export const divinationApi = {
|
|||
|
|
getPrices: () => axios.get('/api/divination/prices'),
|
|||
|
|
|
|||
|
|
submit: (data: SubmitRequest) =>
|
|||
|
|
axios.post('/api/divination/submit', data),
|
|||
|
|
|
|||
|
|
getResult: (id: number) =>
|
|||
|
|
axios.get(`/api/divination/${id}`)
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 状态管理示例
|
|||
|
|
```typescript
|
|||
|
|
// src/stores/divination.ts
|
|||
|
|
import { defineStore } from 'pinia'
|
|||
|
|
|
|||
|
|
export const useDivinationStore = defineStore('divination', {
|
|||
|
|
state: () => ({
|
|||
|
|
history: [] as DivinationRecord[],
|
|||
|
|
currentResult: null as DivinationRecord | null
|
|||
|
|
}),
|
|||
|
|
|
|||
|
|
actions: {
|
|||
|
|
addToHistory(record: DivinationRecord) {
|
|||
|
|
this.history.push(record)
|
|||
|
|
localStorage.setItem('divination_history', JSON.stringify(this.history))
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 测试建议
|
|||
|
|
|
|||
|
|
### 单元测试
|
|||
|
|
```csharp
|
|||
|
|
// 测试八字计算
|
|||
|
|
[Fact]
|
|||
|
|
public void Calculate_ValidInput_ReturnsCorrectFourPillars()
|
|||
|
|
{
|
|||
|
|
var service = new BaZiService();
|
|||
|
|
var input = new BaZiInput
|
|||
|
|
{
|
|||
|
|
BirthDate = new DateTime(1990, 1, 1, 12, 0, 0),
|
|||
|
|
Gender = "male"
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var result = service.Calculate(input);
|
|||
|
|
|
|||
|
|
Assert.NotNull(result.FourPillars);
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 集成测试
|
|||
|
|
```csharp
|
|||
|
|
[Fact]
|
|||
|
|
public async Task Submit_ValidRequest_CreatesRecord()
|
|||
|
|
{
|
|||
|
|
var response = await _client.PostAsJsonAsync("/api/divination/submit", new
|
|||
|
|
{
|
|||
|
|
Type = "bazi",
|
|||
|
|
InputData = "{}",
|
|||
|
|
Amount = 99
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 性能优化建议
|
|||
|
|
|
|||
|
|
1. **前端优化**
|
|||
|
|
- 使用路由懒加载
|
|||
|
|
- 图片使用WebP格式
|
|||
|
|
- 启用Gzip压缩
|
|||
|
|
|
|||
|
|
2. **后端优化**
|
|||
|
|
- 使用Redis缓存价格配置
|
|||
|
|
- 数据库查询添加索引
|
|||
|
|
- 异步处理AI解读
|
|||
|
|
|
|||
|
|
3. **数据库优化**
|
|||
|
|
- 为常用查询字段添加索引
|
|||
|
|
- 定期清理旧数据
|
|||
|
|
- 使用只读副本分担查询
|
|||
|
|
|
|||
|
|
## 安全建议
|
|||
|
|
|
|||
|
|
1. **API安全**
|
|||
|
|
- 实现请求频率限制
|
|||
|
|
- 添加CSRF保护
|
|||
|
|
- 使用HTTPS
|
|||
|
|
|
|||
|
|
2. **数据安全**
|
|||
|
|
- 敏感数据加密存储
|
|||
|
|
- 定期备份数据库
|
|||
|
|
- 实现访问日志
|
|||
|
|
|
|||
|
|
3. **支付安全**
|
|||
|
|
- 验证所有支付回调
|
|||
|
|
- 金额校验
|
|||
|
|
- 防止重复支付
|