init
This commit is contained in:
BIN
docs/1759421790791.jpg
Normal file
BIN
docs/1759421790791.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 166 KiB |
276
docs/DEPLOYMENT.md
Normal file
276
docs/DEPLOYMENT.md
Normal file
@@ -0,0 +1,276 @@
|
||||
# 部署脚本示例
|
||||
|
||||
## Linux服务器部署步骤
|
||||
|
||||
### 1. 安装必要软件
|
||||
```bash
|
||||
# 更新系统
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
|
||||
# 安装Nginx
|
||||
sudo apt install nginx -y
|
||||
|
||||
# 安装.NET 8 Runtime
|
||||
wget https://dot.net/v1/dotnet-install.sh
|
||||
chmod +x dotnet-install.sh
|
||||
./dotnet-install.sh --channel 8.0 --runtime aspnetcore
|
||||
|
||||
# 安装Node.js
|
||||
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
|
||||
sudo apt install nodejs -y
|
||||
|
||||
# 安装MySQL
|
||||
sudo apt install mysql-server -y
|
||||
```
|
||||
|
||||
### 2. 创建数据库
|
||||
```bash
|
||||
sudo mysql -u root -p
|
||||
|
||||
CREATE DATABASE fatemaster CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
CREATE USER 'fatemaster'@'localhost' IDENTIFIED BY 'your_password';
|
||||
GRANT ALL PRIVILEGES ON fatemaster.* TO 'fatemaster'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
||||
EXIT;
|
||||
```
|
||||
|
||||
### 3. 部署后端
|
||||
```bash
|
||||
# 构建项目
|
||||
cd backend/FateMaster.API
|
||||
dotnet publish -c Release -o /var/www/fatemaster-api
|
||||
|
||||
# 创建systemd服务
|
||||
sudo nano /etc/systemd/system/fatemaster-api.service
|
||||
```
|
||||
|
||||
服务配置内容:
|
||||
```ini
|
||||
[Unit]
|
||||
Description=FateMaster API
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
WorkingDirectory=/var/www/fatemaster-api
|
||||
ExecStart=/root/.dotnet/dotnet /var/www/fatemaster-api/FateMaster.API.dll
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
KillSignal=SIGINT
|
||||
SyslogIdentifier=fatemaster-api
|
||||
User=www-data
|
||||
Environment=ASPNETCORE_ENVIRONMENT=Production
|
||||
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
启动服务:
|
||||
```bash
|
||||
sudo systemctl enable fatemaster-api
|
||||
sudo systemctl start fatemaster-api
|
||||
sudo systemctl status fatemaster-api
|
||||
```
|
||||
|
||||
### 4. 部署前端
|
||||
```bash
|
||||
# 构建用户端
|
||||
cd frontend/fatemaster-web
|
||||
npm install
|
||||
npm run build
|
||||
|
||||
# 部署到Nginx
|
||||
sudo cp -r dist/* /var/www/fatemaster-web/
|
||||
|
||||
# 构建管理后台
|
||||
cd ../fatemaster-admin
|
||||
npm install
|
||||
npm run build
|
||||
|
||||
# 部署到Nginx
|
||||
sudo cp -r dist/* /var/www/fatemaster-admin/
|
||||
```
|
||||
|
||||
### 5. 配置Nginx
|
||||
```bash
|
||||
sudo nano /etc/nginx/sites-available/fatemaster
|
||||
```
|
||||
|
||||
配置内容:
|
||||
```nginx
|
||||
# 用户端
|
||||
server {
|
||||
listen 80;
|
||||
server_name yourdomain.com;
|
||||
|
||||
root /var/www/fatemaster-web;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location /api {
|
||||
proxy_pass http://localhost:5000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection 'upgrade';
|
||||
proxy_set_header Host $host;
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
}
|
||||
|
||||
# 管理后台
|
||||
server {
|
||||
listen 80;
|
||||
server_name admin.yourdomain.com;
|
||||
|
||||
root /var/www/fatemaster-admin;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location /api {
|
||||
proxy_pass http://localhost:5000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection 'upgrade';
|
||||
proxy_set_header Host $host;
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
启用配置:
|
||||
```bash
|
||||
sudo ln -s /etc/nginx/sites-available/fatemaster /etc/nginx/sites-enabled/
|
||||
sudo nginx -t
|
||||
sudo systemctl restart nginx
|
||||
```
|
||||
|
||||
### 6. 配置SSL证书(使用Let's Encrypt)
|
||||
```bash
|
||||
sudo apt install certbot python3-certbot-nginx -y
|
||||
sudo certbot --nginx -d yourdomain.com -d admin.yourdomain.com
|
||||
```
|
||||
|
||||
### 7. 配置防火墙
|
||||
```bash
|
||||
sudo ufw allow 80/tcp
|
||||
sudo ufw allow 443/tcp
|
||||
sudo ufw allow 22/tcp
|
||||
sudo ufw enable
|
||||
```
|
||||
|
||||
### 8. 设置定时备份
|
||||
```bash
|
||||
sudo nano /usr/local/bin/backup-fatemaster.sh
|
||||
```
|
||||
|
||||
备份脚本:
|
||||
```bash
|
||||
#!/bin/bash
|
||||
BACKUP_DIR="/backups/fatemaster"
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
|
||||
# 创建备份目录
|
||||
mkdir -p $BACKUP_DIR
|
||||
|
||||
# 备份数据库
|
||||
mysqldump -u fatemaster -p'your_password' fatemaster > $BACKUP_DIR/db_$DATE.sql
|
||||
|
||||
# 备份上传的文件(如果有)
|
||||
# tar -czf $BACKUP_DIR/files_$DATE.tar.gz /var/www/uploads
|
||||
|
||||
# 删除7天前的备份
|
||||
find $BACKUP_DIR -name "*.sql" -mtime +7 -delete
|
||||
|
||||
echo "Backup completed: $DATE"
|
||||
```
|
||||
|
||||
设置定时任务:
|
||||
```bash
|
||||
sudo chmod +x /usr/local/bin/backup-fatemaster.sh
|
||||
sudo crontab -e
|
||||
|
||||
# 添加每天凌晨2点执行备份
|
||||
0 2 * * * /usr/local/bin/backup-fatemaster.sh >> /var/log/fatemaster-backup.log 2>&1
|
||||
```
|
||||
|
||||
## 更新部署
|
||||
|
||||
### 更新后端
|
||||
```bash
|
||||
cd /path/to/source/backend/FateMaster.API
|
||||
git pull
|
||||
dotnet publish -c Release -o /var/www/fatemaster-api
|
||||
sudo systemctl restart fatemaster-api
|
||||
```
|
||||
|
||||
### 更新前端
|
||||
```bash
|
||||
# 用户端
|
||||
cd /path/to/source/frontend/fatemaster-web
|
||||
git pull
|
||||
npm install
|
||||
npm run build
|
||||
sudo cp -r dist/* /var/www/fatemaster-web/
|
||||
|
||||
# 管理后台
|
||||
cd ../fatemaster-admin
|
||||
git pull
|
||||
npm install
|
||||
npm run build
|
||||
sudo cp -r dist/* /var/www/fatemaster-admin/
|
||||
```
|
||||
|
||||
## 监控和维护
|
||||
|
||||
### 查看服务日志
|
||||
```bash
|
||||
# 查看API日志
|
||||
sudo journalctl -u fatemaster-api -f
|
||||
|
||||
# 查看Nginx日志
|
||||
sudo tail -f /var/log/nginx/access.log
|
||||
sudo tail -f /var/log/nginx/error.log
|
||||
```
|
||||
|
||||
### 性能监控
|
||||
```bash
|
||||
# 查看系统资源
|
||||
htop
|
||||
|
||||
# 查看数据库性能
|
||||
sudo mysqladmin -u root -p processlist
|
||||
sudo mysqladmin -u root -p status
|
||||
```
|
||||
|
||||
## 故障排查
|
||||
|
||||
### API无法启动
|
||||
```bash
|
||||
# 检查服务状态
|
||||
sudo systemctl status fatemaster-api
|
||||
|
||||
# 检查端口占用
|
||||
sudo netstat -tlnp | grep 5000
|
||||
|
||||
# 检查数据库连接
|
||||
mysql -u fatemaster -p -h localhost fatemaster
|
||||
```
|
||||
|
||||
### 前端访问404
|
||||
```bash
|
||||
# 检查Nginx配置
|
||||
sudo nginx -t
|
||||
|
||||
# 检查文件权限
|
||||
ls -la /var/www/fatemaster-web/
|
||||
```
|
||||
395
docs/DEVELOPMENT.md
Normal file
395
docs/DEVELOPMENT.md
Normal file
@@ -0,0 +1,395 @@
|
||||
# 开发指南
|
||||
|
||||
## 项目架构说明
|
||||
|
||||
### 算命业务流程
|
||||
|
||||
```
|
||||
用户提交卜卦请求
|
||||
↓
|
||||
选择支付方式
|
||||
↓
|
||||
调用支付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. **支付安全**
|
||||
- 验证所有支付回调
|
||||
- 金额校验
|
||||
- 防止重复支付
|
||||
BIN
docs/批八字.jpg
Normal file
BIN
docs/批八字.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 392 KiB |
BIN
docs/详情.jpg
Normal file
BIN
docs/详情.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 160 KiB |
BIN
docs/详情1.jpg
Normal file
BIN
docs/详情1.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 400 KiB |
BIN
docs/首页.jpg
Normal file
BIN
docs/首页.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 941 KiB |
Reference in New Issue
Block a user