commit d81cf186b012801e97a5f93db6144de78c13f6fd Author: jiangdong Date: Fri Oct 3 11:24:11 2025 +0800 init diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..26122df --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,16 @@ +{ + "permissions": { + "allow": [ + "WebFetch(domain:www.fatemaster.ai)", + "Bash(npm create:*)", + "Bash(dir)", + "Bash(mkdir:*)", + "Bash(npm install)", + "Bash(tree:*)", + "Bash(dir \"D:\\fatemaster\\frontend\\fatemaster-web\" /B)", + "Bash(npm run dev:*)" + ], + "deny": [], + "ask": [] + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..88a67b0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,52 @@ +# Dependencies +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# Build outputs +dist/ +dist-ssr/ +*.local + +# .NET +bin/ +obj/ +*.user +*.suo +*.cache +*.dll +*.exe +*.pdb + +# Environment variables +.env +.env.local +.env.production +appsettings.Development.json +appsettings.Production.json + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db + +# Logs +logs/ +*.log + +# Database +*.db +*.sqlite + +# Secrets +*.key +*.pem +secrets/ diff --git a/PROJECT_SUMMARY.md b/PROJECT_SUMMARY.md new file mode 100644 index 0000000..230cd28 --- /dev/null +++ b/PROJECT_SUMMARY.md @@ -0,0 +1,246 @@ +# FateMaster 项目完成总结 + +## 项目概述 + +已成功搭建八字算命网站的完整框架,包括前端用户端、管理后台和后端API。 + +## 已完成内容 + +### ✅ 前端用户端 (fatemaster-web) +- **技术栈**: Vue 3 + TypeScript + Vite + Ant Design Vue +- **核心功能**: + - 响应式布局和导航系统 + - 多语言支持(简体中文、繁体中文、英文、日语) + - 5种卜卦页面:批八字、事业、姻缘、塔罗、星座 + - 支付流程集成(支持支付宝、PayPal、Stripe) + - 本地存储历史记录 + - 结果展示页面 + +### ✅ 管理后台 (fatemaster-admin) +- **技术栈**: Vue 3 + TypeScript + Vite + Ant Design Vue +- **核心功能**: + - 仪表盘统计(订单量、收入、类型分布) + - 卜卦记录管理(筛选、分页) + - 价格配置管理(编辑价格、启用/禁用服务) + +### ✅ 后端API (FateMaster.API) +- **技术栈**: ASP.NET Core 8 + EF Core + MySQL +- **核心功能**: + - RESTful API设计 + - 数据库实体模型(卜卦记录、价格配置、系统配置) + - API控制器(用户端、管理端) + - CORS配置 + - Swagger文档 + +### ✅ 数据库设计 +- **表结构**: + - DivinationRecords(卜卦记录) + - PriceConfig(价格配置) + - SystemConfig(系统配置) +- **特性**: + - 索引优化 + - JSON字段支持 + - 初始数据种子 + +### ✅ 文档 +- README.md - 项目说明 +- DEVELOPMENT.md - 开发指南 +- DEPLOYMENT.md - 部署文档 + +## 项目结构 + +``` +fatemaster/ +├── frontend/ +│ ├── fatemaster-web/ # 用户端 +│ │ ├── src/ +│ │ │ ├── views/ # 页面组件 +│ │ │ │ ├── Home.vue +│ │ │ │ ├── Result.vue +│ │ │ │ └── divination/ +│ │ │ │ ├── BaZi.vue +│ │ │ │ ├── Career.vue +│ │ │ │ ├── Marriage.vue +│ │ │ │ ├── Tarot.vue +│ │ │ │ └── Zodiac.vue +│ │ │ ├── layouts/ # 布局组件 +│ │ │ ├── router/ # 路由配置 +│ │ │ ├── i18n/ # 国际化 +│ │ │ └── main.ts +│ │ └── package.json +│ │ +│ └── fatemaster-admin/ # 管理后台 +│ ├── src/ +│ │ ├── views/ # 页面组件 +│ │ │ ├── Dashboard.vue +│ │ │ ├── Records.vue +│ │ │ └── Prices.vue +│ │ ├── layouts/ +│ │ ├── router/ +│ │ └── main.ts +│ └── package.json +│ +├── backend/ +│ └── FateMaster.API/ # 后端API +│ ├── Controllers/ # 控制器 +│ │ ├── DivinationController.cs +│ │ └── Admin/ +│ │ ├── RecordsController.cs +│ │ └── PricesController.cs +│ ├── Models/ # 数据模型 +│ │ ├── DivinationRecord.cs +│ │ ├── PriceConfig.cs +│ │ └── SystemConfig.cs +│ ├── Data/ # 数据访问 +│ │ └── ApplicationDbContext.cs +│ ├── Program.cs +│ └── appsettings.json +│ +├── docs/ # 文档 +│ ├── DEVELOPMENT.md +│ └── DEPLOYMENT.md +│ +├── README.md +└── .gitignore +``` + +## 待实现功能 + +### 🔲 支付集成 +需要实现具体的支付服务类: +- `Services/Payment/AlipayService.cs` - 支付宝SDK集成 +- `Services/Payment/PayPalService.cs` - PayPal SDK集成 +- `Services/Payment/StripeService.cs` - Stripe SDK集成 + +### 🔲 AI大模型集成 +需要实现AI解读服务: +- `Services/AI/AIService.cs` - 调用OpenAI/Claude等API +- 构建专业的命理解读提示词 +- 处理流式响应(可选) + +### 🔲 算命算法 +需要实现传统算命算法: +- `Services/Divination/BaZiService.cs` - 八字排盘 + - 四柱计算(年月日时) + - 大运流年 + - 五行分析 + - 十神关系 +- `Services/Divination/TarotService.cs` - 塔罗牌解读 +- `Services/Divination/ZodiacService.cs` - 星座运势 + +## 下一步工作 + +### 1. 立即需要做的 +1. **安装依赖** + ```bash + cd frontend/fatemaster-web && npm install + cd frontend/fatemaster-admin && npm install + ``` + +2. **配置数据库** + - 创建MySQL数据库 + - 修改 `appsettings.json` 中的连接字符串 + - 运行数据库迁移 + +3. **测试运行** + - 启动后端API + - 启动用户端 + - 启动管理后台 + +### 2. 短期开发计划 +1. **实现支付功能**(1-2周) + - 集成支付宝SDK + - 集成PayPal SDK + - 集成Stripe SDK + - 实现支付回调处理 + +2. **实现AI解读**(1周) + - 选择AI服务商(OpenAI/Claude/国内模型) + - 编写解读提示词模板 + - 实现API调用和结果解析 + +3. **实现算命算法**(2-3周) + - 研究或购买八字算法库 + - 实现基础的命盘计算 + - 实现塔罗牌和星座逻辑 + +### 3. 中期优化计划 +1. **性能优化** + - 引入Redis缓存 + - 优化数据库查询 + - 前端代码分割和懒加载 + +2. **安全加固** + - 实现请求频率限制 + - 添加CSRF保护 + - 敏感数据加密 + +3. **功能完善** + - 用户注册登录系统 + - 会员系统 + - 订单管理 + - 优惠券/折扣功能 + +## 技术要点 + +### 前端特性 +- **组件化设计**: 可复用的Vue组件 +- **类型安全**: 全面使用TypeScript +- **国际化**: 支持4种语言切换 +- **响应式**: 移动端友好 +- **状态管理**: Pinia集成 + +### 后端特性 +- **RESTful设计**: 清晰的API接口 +- **依赖注入**: ASP.NET Core内置DI +- **ORM映射**: EF Core简化数据访问 +- **跨域支持**: CORS配置完善 +- **文档生成**: Swagger自动生成API文档 + +### 数据库特性 +- **JSON支持**: 灵活存储复杂数据 +- **索引优化**: 常用查询字段加索引 +- **数据迁移**: Code First迁移管理 +- **种子数据**: 初始化价格配置 + +## 注意事项 + +### 开发环境 +- 需要安装 Node.js 18+ +- 需要安装 .NET 8 SDK +- 需要安装 MySQL 8.0+ + +### 安全提醒 +⚠️ **重要**: +- `appsettings.json` 中的敏感信息应使用环境变量 +- 生产环境必须配置正确的CORS白名单 +- 支付密钥不要提交到代码仓库 +- 建议使用 `.env` 文件管理环境变量 + +### 部署建议 +- 前端: 构建后部署到Nginx +- 后端: 使用systemd管理服务 +- 数据库: 独立MySQL服务器 +- SSL: 使用Let's Encrypt证书 + +## 参考资料 + +### 技术文档 +- Vue 3: https://vuejs.org/ +- Ant Design Vue: https://antdv.com/ +- ASP.NET Core: https://docs.microsoft.com/aspnet/core +- Entity Framework Core: https://docs.microsoft.com/ef/core + +### 算命算法参考 +- 八字排盘算法: 可参考开源项目或购买商业库 +- 塔罗牌数据: 可使用开源塔罗牌数据集 +- 星座运势: 可接入第三方API或自行编写 + +### 支付SDK +- 支付宝: https://opendocs.alipay.com/ +- PayPal: https://developer.paypal.com/ +- Stripe: https://stripe.com/docs/api + +## 总结 + +项目基础框架已完整搭建,架构清晰,代码规范,具备良好的扩展性。核心业务逻辑(支付、AI、算命算法)需要进一步实现。建议按照上述计划逐步完善功能,确保每个模块都经过充分测试后再上线。 diff --git a/README.md b/README.md new file mode 100644 index 0000000..ee1faec --- /dev/null +++ b/README.md @@ -0,0 +1,288 @@ +# FateMaster - 命运大师八字算命网站 + +一个功能完整的八字算命网站,支持多种卜卦方式、多语言、响应式设计。 + +## 技术栈 + +### 前端 +- **Vue 3** + **TypeScript** + **Vite** +- **Ant Design Vue** - UI组件库 +- **Vue Router** - 路由管理 +- **Pinia** - 状态管理 +- **vue-i18n** - 国际化 +- **Axios** - HTTP客户端 + +### 后端 +- **ASP.NET Core 8** - Web API框架 +- **Entity Framework Core** - ORM +- **Pomelo.EntityFrameworkCore.MySql** - MySQL数据库驱动 + +### 数据库 +- **MySQL** 8.0+ + +## 项目结构 + +``` +fatemaster/ +├── frontend/ +│ ├── fatemaster-web/ # 用户端前端 +│ └── fatemaster-admin/ # 管理后台前端 +├── backend/ +│ └── FateMaster.API/ # .NET后端API +└── docs/ # 文档 +``` + +## 功能特性 + +### 用户端功能 +- ✅ 批八字 - 详细的生辰八字分析 +- ✅ 事业运势 - 职业发展预测 +- ✅ 姻缘测算 - 婚姻关系分析 +- ✅ 塔罗占卜 - 互动式塔罗牌选择 +- ✅ 星座运势 - 12星座每日/每周/每月运势 +- ✅ 多语言支持 - 简体中文、繁体中文、英文、日语 +- ✅ 响应式设计 - 支持PC、平板、手机 +- ✅ 支付集成 - 支付宝、PayPal、Stripe + +### 管理后台功能 +- ✅ 仪表盘 - 数据统计概览 +- ✅ 卜卦记录管理 - 查看和筛选所有记录 +- ✅ 价格配置 - 动态调整各服务价格 +- ✅ 统计分析 - 订单量、收入等数据分析 + +## 快速开始 + +### 环境要求 +- Node.js 18+ +- .NET 8 SDK +- MySQL 8.0+ + +### 1. 安装前端依赖 + +```bash +# 用户端 +cd frontend/fatemaster-web +npm install + +# 管理后台 +cd frontend/fatemaster-admin +npm install +``` + +### 2. 配置数据库 + +创建MySQL数据库: +```sql +CREATE DATABASE fatemaster CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +``` + +修改 `backend/FateMaster.API/appsettings.json`: +```json +{ + "ConnectionStrings": { + "DefaultConnection": "Server=localhost;Port=3306;Database=fatemaster;User=root;Password=your_password;" + } +} +``` + +### 3. 运行数据库迁移 + +```bash +cd backend/FateMaster.API +dotnet ef migrations add InitialCreate +dotnet ef database update +``` + +### 4. 启动服务 + +```bash +# 启动后端API (端口5000) +cd backend/FateMaster.API +dotnet run + +# 启动用户端 (端口3000) +cd frontend/fatemaster-web +npm run dev + +# 启动管理后台 (端口3001) +cd frontend/fatemaster-admin +npm run dev +``` + +### 访问地址 +- 用户端: http://localhost:3000 +- 管理后台: http://localhost:3001 +- API文档: http://localhost:5000/swagger + +## 配置说明 + +### 支付配置 +在 `appsettings.json` 中配置支付信息: + +```json +{ + "PaymentSettings": { + "Alipay": { + "AppId": "your_app_id", + "PrivateKey": "your_private_key", + "PublicKey": "alipay_public_key" + }, + "PayPal": { + "ClientId": "your_client_id", + "ClientSecret": "your_client_secret", + "Mode": "sandbox" + }, + "Stripe": { + "SecretKey": "your_secret_key", + "PublishableKey": "your_publishable_key" + } + } +} +``` + +### AI配置 +配置AI大模型API(用于解读算命结果): + +```json +{ + "AISettings": { + "Provider": "OpenAI", + "ApiKey": "your_api_key", + "Model": "gpt-4", + "BaseUrl": "https://api.openai.com/v1" + } +} +``` + +## 数据库表结构 + +### DivinationRecords - 卜卦记录表 +- Id - 主键 +- Type - 卜卦类型 (bazi, career, marriage, tarot, zodiac) +- InputData - 用户输入数据(JSON) +- TraditionalResult - 传统算法结果(JSON) +- AIInterpretation - AI解读结果 +- PaymentStatus - 支付状态 (pending, paid, failed) +- PaymentMethod - 支付方式 +- Amount - 金额 +- ClientIp - 客户端IP +- Language - 语言 +- CreatedAt - 创建时间 + +### PriceConfig - 价格配置表 +- Id - 主键 +- ServiceType - 服务类型 +- Price - 价格 +- Currency - 货币 +- IsEnabled - 是否启用 + +### SystemConfig - 系统配置表 +- Id - 主键 +- ConfigKey - 配置键 +- ConfigValue - 配置值 +- Description - 描述 + +## 待实现功能 + +### 支付集成 +需要实现以下支付服务类: +- AlipayService - 支付宝支付 +- PayPalService - PayPal支付 +- StripeService - Stripe支付 + +参考位置:`backend/FateMaster.API/Services/Payment/` + +### AI集成 +需要实现AI服务类: +- AIService - 调用大模型API解读算命结果 + +参考位置:`backend/FateMaster.API/Services/AI/` + +### 算命算法 +需要实现传统算法类: +- BaZiService - 八字排盘算法 +- TarotService - 塔罗牌解读算法 +- ZodiacService - 星座运势算法 + +参考位置:`backend/FateMaster.API/Services/Divination/` + +## 部署建议 + +### 生产环境配置 + +1. **前端** + - 使用 `npm run build` 构建生产版本 + - 部署到 Nginx 或其他静态文件服务器 + - 配置反向代理到后端API + +2. **后端** + - 使用 `dotnet publish -c Release` 构建发布版本 + - 部署到 Linux 服务器 + - 使用 Nginx 作为反向代理 + - 配置 SSL 证书 + +3. **数据库** + - 使用独立的MySQL服务器 + - 配置定期备份 + - 优化索引和查询性能 + +### Nginx配置示例 + +```nginx +# 用户端 +server { + listen 80; + server_name your-domain.com; + root /var/www/fatemaster-web/dist; + + location / { + try_files $uri $uri/ /index.html; + } + + location /api { + proxy_pass http://localhost:5000; + } +} + +# 管理后台 +server { + listen 80; + server_name admin.your-domain.com; + root /var/www/fatemaster-admin/dist; + + location / { + try_files $uri $uri/ /index.html; + } + + location /api { + proxy_pass http://localhost:5000; + } +} +``` + +## 开发注意事项 + +1. **环境变量** + - 敏感信息(API密钥、数据库密码)应使用环境变量 + - 不要将密钥提交到代码仓库 + +2. **CORS配置** + - 生产环境需要更新CORS白名单 + - 移除开发环境的localhost地址 + +3. **日志记录** + - 配置适当的日志级别 + - 使用日志聚合工具(如ELK) + +4. **性能优化** + - 前端使用懒加载 + - 后端使用缓存(Redis) + - 数据库查询优化 + +## License + +MIT License + +## 联系方式 + +如有问题,请提交Issue或联系开发团队。 diff --git a/backend/FateMaster.API/.vs/FateMaster.API/DesignTimeBuild/.dtbcache.v2 b/backend/FateMaster.API/.vs/FateMaster.API/DesignTimeBuild/.dtbcache.v2 new file mode 100644 index 0000000..16afe37 Binary files /dev/null and b/backend/FateMaster.API/.vs/FateMaster.API/DesignTimeBuild/.dtbcache.v2 differ diff --git a/backend/FateMaster.API/.vs/FateMaster.API/FileContentIndex/6df2a7c3-84eb-4692-8dc9-a1385e100411.vsidx b/backend/FateMaster.API/.vs/FateMaster.API/FileContentIndex/6df2a7c3-84eb-4692-8dc9-a1385e100411.vsidx new file mode 100644 index 0000000..d47f90c Binary files /dev/null and b/backend/FateMaster.API/.vs/FateMaster.API/FileContentIndex/6df2a7c3-84eb-4692-8dc9-a1385e100411.vsidx differ diff --git a/backend/FateMaster.API/Controllers/Admin/PricesController.cs b/backend/FateMaster.API/Controllers/Admin/PricesController.cs new file mode 100644 index 0000000..c908e16 --- /dev/null +++ b/backend/FateMaster.API/Controllers/Admin/PricesController.cs @@ -0,0 +1,49 @@ +using FateMaster.API.Data; +using FateMaster.API.Models; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace FateMaster.API.Controllers.Admin; + +[ApiController] +[Route("api/admin/[controller]")] +public class PricesController : ControllerBase +{ + private readonly ApplicationDbContext _context; + + public PricesController(ApplicationDbContext context) + { + _context = context; + } + + /// + /// 获取所有价格配置 + /// + [HttpGet] + public async Task>> GetAll() + { + return await _context.PriceConfigs.ToListAsync(); + } + + /// + /// 更新价格配置 + /// + [HttpPut("{id}")] + public async Task Update(int id, [FromBody] UpdatePriceRequest request) + { + var price = await _context.PriceConfigs.FindAsync(id); + if (price == null) + { + return NotFound(); + } + + price.Price = request.Price; + price.IsEnabled = request.IsEnabled; + price.UpdatedAt = DateTime.UtcNow; + + await _context.SaveChangesAsync(); + return Ok(price); + } +} + +public record UpdatePriceRequest(decimal Price, bool IsEnabled); diff --git a/backend/FateMaster.API/Controllers/Admin/RecordsController.cs b/backend/FateMaster.API/Controllers/Admin/RecordsController.cs new file mode 100644 index 0000000..8690e7c --- /dev/null +++ b/backend/FateMaster.API/Controllers/Admin/RecordsController.cs @@ -0,0 +1,87 @@ +using FateMaster.API.Data; +using FateMaster.API.Models; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace FateMaster.API.Controllers; + +[ApiController] +[Route("api/admin/[controller]")] +public class RecordsController : ControllerBase +{ + private readonly ApplicationDbContext _context; + + public RecordsController(ApplicationDbContext context) + { + _context = context; + } + + /// + /// 获取卜卦记录列表 + /// + [HttpGet] + public async Task GetRecords( + [FromQuery] int page = 1, + [FromQuery] int pageSize = 20, + [FromQuery] string? type = null, + [FromQuery] string? paymentStatus = null) + { + var query = _context.DivinationRecords.AsQueryable(); + + if (!string.IsNullOrEmpty(type)) + { + query = query.Where(r => r.Type == type); + } + + if (!string.IsNullOrEmpty(paymentStatus)) + { + query = query.Where(r => r.PaymentStatus == paymentStatus); + } + + var total = await query.CountAsync(); + var records = await query + .OrderByDescending(r => r.CreatedAt) + .Skip((page - 1) * pageSize) + .Take(pageSize) + .ToListAsync(); + + return Ok(new + { + total, + page, + pageSize, + data = records + }); + } + + /// + /// 获取统计数据 + /// + [HttpGet("statistics")] + public async Task GetStatistics() + { + var total = await _context.DivinationRecords.CountAsync(); + var paidCount = await _context.DivinationRecords + .CountAsync(r => r.PaymentStatus == "paid"); + var totalRevenue = await _context.DivinationRecords + .Where(r => r.PaymentStatus == "paid") + .SumAsync(r => r.Amount); + + var typeStats = await _context.DivinationRecords + .GroupBy(r => r.Type) + .Select(g => new + { + Type = g.Key, + Count = g.Count() + }) + .ToListAsync(); + + return Ok(new + { + total, + paidCount, + totalRevenue, + typeStats + }); + } +} diff --git a/backend/FateMaster.API/Controllers/DivinationController.cs b/backend/FateMaster.API/Controllers/DivinationController.cs new file mode 100644 index 0000000..963838f --- /dev/null +++ b/backend/FateMaster.API/Controllers/DivinationController.cs @@ -0,0 +1,88 @@ +using FateMaster.API.Data; +using FateMaster.API.Models; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace FateMaster.API.Controllers; + +[ApiController] +[Route("api/[controller]")] +public class DivinationController : ControllerBase +{ + private readonly ApplicationDbContext _context; + private readonly ILogger _logger; + + public DivinationController( + ApplicationDbContext context, + ILogger logger) + { + _context = context; + _logger = logger; + } + + /// + /// 获取价格配置 + /// + [HttpGet("prices")] + public async Task>> GetPrices() + { + var prices = await _context.PriceConfigs + .Where(p => p.IsEnabled) + .ToListAsync(); + return Ok(prices); + } + + /// + /// 提交卜卦请求 + /// + [HttpPost("submit")] + public async Task> Submit([FromBody] SubmitRequest request) + { + try + { + var record = new DivinationRecord + { + Type = request.Type, + InputData = request.InputData, + PaymentStatus = "pending", + PaymentMethod = request.PaymentMethod, + Amount = request.Amount, + ClientIp = HttpContext.Connection.RemoteIpAddress?.ToString(), + Language = request.Language ?? "zh-CN" + }; + + _context.DivinationRecords.Add(record); + await _context.SaveChangesAsync(); + + return Ok(record); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error submitting divination request"); + return StatusCode(500, new { message = "提交失败" }); + } + } + + /// + /// 获取卜卦结果 + /// + [HttpGet("{id}")] + public async Task> GetResult(long id) + { + var record = await _context.DivinationRecords.FindAsync(id); + if (record == null) + { + return NotFound(); + } + + return Ok(record); + } +} + +public record SubmitRequest( + string Type, + string InputData, + string? PaymentMethod, + decimal Amount, + string? Language +); diff --git a/backend/FateMaster.API/Data/ApplicationDbContext.cs b/backend/FateMaster.API/Data/ApplicationDbContext.cs new file mode 100644 index 0000000..37f8596 --- /dev/null +++ b/backend/FateMaster.API/Data/ApplicationDbContext.cs @@ -0,0 +1,47 @@ +using FateMaster.API.Models; +using Microsoft.EntityFrameworkCore; + +namespace FateMaster.API.Data; + +public class ApplicationDbContext : DbContext +{ + public ApplicationDbContext(DbContextOptions options) + : base(options) + { + } + + public DbSet DivinationRecords { get; set; } + public DbSet SystemConfigs { get; set; } + public DbSet PriceConfigs { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + // 配置索引 + modelBuilder.Entity() + .HasIndex(d => d.Type); + + modelBuilder.Entity() + .HasIndex(d => d.PaymentStatus); + + modelBuilder.Entity() + .HasIndex(d => d.CreatedAt); + + modelBuilder.Entity() + .HasIndex(s => s.ConfigKey) + .IsUnique(); + + modelBuilder.Entity() + .HasIndex(p => p.ServiceType); + + // 初始化数据 + modelBuilder.Entity().HasData( + new PriceConfig { Id = 1, ServiceType = "bazi", Price = 99, Currency = "CNY" }, + new PriceConfig { Id = 2, ServiceType = "career", Price = 88, Currency = "CNY" }, + new PriceConfig { Id = 3, ServiceType = "marriage", Price = 88, Currency = "CNY" }, + new PriceConfig { Id = 4, ServiceType = "tarot", Price = 66, Currency = "CNY" }, + new PriceConfig { Id = 5, ServiceType = "zodiac", Price = 29, Currency = "CNY" } + ); + } +} diff --git a/backend/FateMaster.API/FateMaster.API.csproj b/backend/FateMaster.API/FateMaster.API.csproj new file mode 100644 index 0000000..6528c5d --- /dev/null +++ b/backend/FateMaster.API/FateMaster.API.csproj @@ -0,0 +1,19 @@ + + + + net8.0 + enable + enable + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + diff --git a/backend/FateMaster.API/Models/DivinationRecord.cs b/backend/FateMaster.API/Models/DivinationRecord.cs new file mode 100644 index 0000000..29bea01 --- /dev/null +++ b/backend/FateMaster.API/Models/DivinationRecord.cs @@ -0,0 +1,86 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace FateMaster.API.Models; + +/// +/// 卜卦记录表 +/// +public class DivinationRecord +{ + [Key] + public long Id { get; set; } + + /// + /// 卜卦类型: bazi, career, marriage, tarot, zodiac + /// + [Required] + [MaxLength(50)] + public string Type { get; set; } = string.Empty; + + /// + /// 用户输入数据(JSON) + /// + [Required] + [Column(TypeName = "json")] + public string InputData { get; set; } = string.Empty; + + /// + /// 传统算法结果(JSON) + /// + [Column(TypeName = "json")] + public string? TraditionalResult { get; set; } + + /// + /// AI解读结果 + /// + [Column(TypeName = "text")] + public string? AIInterpretation { get; set; } + + /// + /// 支付状态: pending, paid, failed + /// + [Required] + [MaxLength(20)] + public string PaymentStatus { get; set; } = "pending"; + + /// + /// 支付方式: alipay, paypal, stripe + /// + [MaxLength(20)] + public string? PaymentMethod { get; set; } + + /// + /// 支付金额 + /// + [Column(TypeName = "decimal(10,2)")] + public decimal Amount { get; set; } + + /// + /// 支付订单号 + /// + [MaxLength(100)] + public string? PaymentOrderId { get; set; } + + /// + /// 客户端IP + /// + [MaxLength(50)] + public string? ClientIp { get; set; } + + /// + /// 语言 + /// + [MaxLength(10)] + public string? Language { get; set; } + + /// + /// 创建时间 + /// + public DateTime CreatedAt { get; set; } = DateTime.UtcNow; + + /// + /// 更新时间 + /// + public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; +} diff --git a/backend/FateMaster.API/Models/PriceConfig.cs b/backend/FateMaster.API/Models/PriceConfig.cs new file mode 100644 index 0000000..4dea0de --- /dev/null +++ b/backend/FateMaster.API/Models/PriceConfig.cs @@ -0,0 +1,49 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace FateMaster.API.Models; + +/// +/// 价格配置表 +/// +public class PriceConfig +{ + [Key] + public int Id { get; set; } + + /// + /// 服务类型: bazi, career, marriage, tarot, zodiac + /// + [Required] + [MaxLength(50)] + public string ServiceType { get; set; } = string.Empty; + + /// + /// 价格 + /// + [Required] + [Column(TypeName = "decimal(10,2)")] + public decimal Price { get; set; } + + /// + /// 货币: CNY, USD + /// + [Required] + [MaxLength(10)] + public string Currency { get; set; } = "CNY"; + + /// + /// 是否启用 + /// + public bool IsEnabled { get; set; } = true; + + /// + /// 创建时间 + /// + public DateTime CreatedAt { get; set; } = DateTime.UtcNow; + + /// + /// 更新时间 + /// + public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; +} diff --git a/backend/FateMaster.API/Models/SystemConfig.cs b/backend/FateMaster.API/Models/SystemConfig.cs new file mode 100644 index 0000000..c5ac753 --- /dev/null +++ b/backend/FateMaster.API/Models/SystemConfig.cs @@ -0,0 +1,41 @@ +using System.ComponentModel.DataAnnotations; + +namespace FateMaster.API.Models; + +/// +/// 系统配置表 +/// +public class SystemConfig +{ + [Key] + public int Id { get; set; } + + /// + /// 配置键 + /// + [Required] + [MaxLength(100)] + public string ConfigKey { get; set; } = string.Empty; + + /// + /// 配置值 + /// + [Required] + public string ConfigValue { get; set; } = string.Empty; + + /// + /// 描述 + /// + [MaxLength(500)] + public string? Description { get; set; } + + /// + /// 创建时间 + /// + public DateTime CreatedAt { get; set; } = DateTime.UtcNow; + + /// + /// 更新时间 + /// + public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; +} diff --git a/backend/FateMaster.API/Program.cs b/backend/FateMaster.API/Program.cs new file mode 100644 index 0000000..1f1793c --- /dev/null +++ b/backend/FateMaster.API/Program.cs @@ -0,0 +1,41 @@ +using FateMaster.API.Data; +using Microsoft.EntityFrameworkCore; + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +builder.Services.AddControllers(); +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +// Configure MySQL +var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); +builder.Services.AddDbContext(options => + options.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString))); + +// Configure CORS +builder.Services.AddCors(options => +{ + options.AddPolicy("AllowFrontend", policy => + { + policy.WithOrigins("http://localhost:3000", "http://localhost:3001") + .AllowAnyMethod() + .AllowAnyHeader() + .AllowCredentials(); + }); +}); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseCors("AllowFrontend"); +app.UseAuthorization(); +app.MapControllers(); + +app.Run(); diff --git a/backend/FateMaster.API/Properties/launchSettings.json b/backend/FateMaster.API/Properties/launchSettings.json new file mode 100644 index 0000000..dd92fc6 --- /dev/null +++ b/backend/FateMaster.API/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "profiles": { + "FateMaster.API": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:63347;http://localhost:63348" + } + } +} \ No newline at end of file diff --git a/backend/FateMaster.API/appsettings.json b/backend/FateMaster.API/appsettings.json new file mode 100644 index 0000000..86b1fc7 --- /dev/null +++ b/backend/FateMaster.API/appsettings.json @@ -0,0 +1,34 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "ConnectionStrings": { + "DefaultConnection": "Server=localhost;Port=3306;Database=fatemaster;User=root;Password=your_password;" + }, + "PaymentSettings": { + "Alipay": { + "AppId": "", + "PrivateKey": "", + "PublicKey": "" + }, + "PayPal": { + "ClientId": "", + "ClientSecret": "", + "Mode": "sandbox" + }, + "Stripe": { + "SecretKey": "", + "PublishableKey": "" + } + }, + "AISettings": { + "Provider": "OpenAI", + "ApiKey": "", + "Model": "gpt-4", + "BaseUrl": "https://api.openai.com/v1" + } +} diff --git a/docs/1759421790791.jpg b/docs/1759421790791.jpg new file mode 100644 index 0000000..ec50d41 Binary files /dev/null and b/docs/1759421790791.jpg differ diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md new file mode 100644 index 0000000..71e5c0e --- /dev/null +++ b/docs/DEPLOYMENT.md @@ -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/ +``` diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md new file mode 100644 index 0000000..e29f50f --- /dev/null +++ b/docs/DEVELOPMENT.md @@ -0,0 +1,395 @@ +# 开发指南 + +## 项目架构说明 + +### 算命业务流程 + +``` +用户提交卜卦请求 + ↓ +选择支付方式 + ↓ +调用支付API + ↓ +支付成功后 + ↓ +传统算法计算命盘 + ↓ +AI大模型解读结果 + ↓ +返回完整结果给用户 +``` + +## 需要实现的核心服务 + +### 1. 支付服务实现 + +#### 支付宝支付示例结构 +```csharp +// backend/FateMaster.API/Services/Payment/AlipayService.cs +public class AlipayService : IPaymentService +{ + public async Task CreateOrder(decimal amount, string orderId) + { + // 调用支付宝SDK创建订单 + // 返回支付链接或二维码 + } + + public async Task VerifyCallback(Dictionary parameters) + { + // 验证支付宝回调签名 + // 更新订单状态 + } +} +``` + +#### PayPal支付示例结构 +```csharp +// backend/FateMaster.API/Services/Payment/PayPalService.cs +public class PayPalService : IPaymentService +{ + public async Task CreateOrder(decimal amount, string orderId) + { + // 调用PayPal API创建订单 + } + + public async Task CapturePayment(string paymentId) + { + // 捕获支付 + } +} +``` + +#### Stripe支付示例结构 +```csharp +// backend/FateMaster.API/Services/Payment/StripeService.cs +public class StripeService : IPaymentService +{ + public async Task 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 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 _cards; + + public TarotResult Interpret(List 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. **支付安全** + - 验证所有支付回调 + - 金额校验 + - 防止重复支付 diff --git a/docs/批八字.jpg b/docs/批八字.jpg new file mode 100644 index 0000000..8b5d12f Binary files /dev/null and b/docs/批八字.jpg differ diff --git a/docs/详情.jpg b/docs/详情.jpg new file mode 100644 index 0000000..1d9d8f1 Binary files /dev/null and b/docs/详情.jpg differ diff --git a/docs/详情1.jpg b/docs/详情1.jpg new file mode 100644 index 0000000..f93ff27 Binary files /dev/null and b/docs/详情1.jpg differ diff --git a/docs/首页.jpg b/docs/首页.jpg new file mode 100644 index 0000000..1404bd6 Binary files /dev/null and b/docs/首页.jpg differ diff --git a/frontend/fatemaster-admin/index.html b/frontend/fatemaster-admin/index.html new file mode 100644 index 0000000..7b5bf63 --- /dev/null +++ b/frontend/fatemaster-admin/index.html @@ -0,0 +1,13 @@ + + + + + + + FateMaster Admin - 管理后台 + + +
+ + + diff --git a/frontend/fatemaster-admin/package.json b/frontend/fatemaster-admin/package.json new file mode 100644 index 0000000..59c364a --- /dev/null +++ b/frontend/fatemaster-admin/package.json @@ -0,0 +1,26 @@ +{ + "name": "fatemaster-admin", + "private": true, + "version": "0.1.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vue-tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "vue": "^3.4.21", + "vue-router": "^4.3.0", + "pinia": "^2.1.7", + "ant-design-vue": "^4.2.1", + "axios": "^1.6.8", + "@ant-design/icons-vue": "^7.0.1" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.0.4", + "typescript": "^5.4.3", + "vite": "^5.2.0", + "vue-tsc": "^2.0.6", + "@types/node": "^20.11.30" + } +} diff --git a/frontend/fatemaster-admin/src/App.vue b/frontend/fatemaster-admin/src/App.vue new file mode 100644 index 0000000..cd9578a --- /dev/null +++ b/frontend/fatemaster-admin/src/App.vue @@ -0,0 +1,6 @@ + + + diff --git a/frontend/fatemaster-admin/src/layouts/AdminLayout.vue b/frontend/fatemaster-admin/src/layouts/AdminLayout.vue new file mode 100644 index 0000000..ddf7099 --- /dev/null +++ b/frontend/fatemaster-admin/src/layouts/AdminLayout.vue @@ -0,0 +1,72 @@ + + + + + diff --git a/frontend/fatemaster-admin/src/main.ts b/frontend/fatemaster-admin/src/main.ts new file mode 100644 index 0000000..0255153 --- /dev/null +++ b/frontend/fatemaster-admin/src/main.ts @@ -0,0 +1,15 @@ +import { createApp } from 'vue' +import { createPinia } from 'pinia' +import Antd from 'ant-design-vue' +import router from './router' +import App from './App.vue' +import 'ant-design-vue/dist/reset.css' + +const app = createApp(App) +const pinia = createPinia() + +app.use(pinia) +app.use(router) +app.use(Antd) + +app.mount('#app') diff --git a/frontend/fatemaster-admin/src/router/index.ts b/frontend/fatemaster-admin/src/router/index.ts new file mode 100644 index 0000000..f6677c1 --- /dev/null +++ b/frontend/fatemaster-admin/src/router/index.ts @@ -0,0 +1,34 @@ +import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router' +import Layout from '@/layouts/AdminLayout.vue' + +const routes: RouteRecordRaw[] = [ + { + path: '/', + component: Layout, + redirect: '/dashboard', + children: [ + { + path: 'dashboard', + name: 'Dashboard', + component: () => import('@/views/Dashboard.vue'), + }, + { + path: 'records', + name: 'Records', + component: () => import('@/views/Records.vue'), + }, + { + path: 'prices', + name: 'Prices', + component: () => import('@/views/Prices.vue'), + }, + ], + }, +] + +const router = createRouter({ + history: createWebHistory('/admin/'), + routes, +}) + +export default router diff --git a/frontend/fatemaster-admin/src/views/Dashboard.vue b/frontend/fatemaster-admin/src/views/Dashboard.vue new file mode 100644 index 0000000..b8ab54c --- /dev/null +++ b/frontend/fatemaster-admin/src/views/Dashboard.vue @@ -0,0 +1,80 @@ + + + diff --git a/frontend/fatemaster-admin/src/views/Prices.vue b/frontend/fatemaster-admin/src/views/Prices.vue new file mode 100644 index 0000000..e4e9438 --- /dev/null +++ b/frontend/fatemaster-admin/src/views/Prices.vue @@ -0,0 +1,96 @@ + + + diff --git a/frontend/fatemaster-admin/src/views/Records.vue b/frontend/fatemaster-admin/src/views/Records.vue new file mode 100644 index 0000000..bf10aea --- /dev/null +++ b/frontend/fatemaster-admin/src/views/Records.vue @@ -0,0 +1,94 @@ + + + diff --git a/frontend/fatemaster-admin/vite.config.ts b/frontend/fatemaster-admin/vite.config.ts new file mode 100644 index 0000000..daa5de3 --- /dev/null +++ b/frontend/fatemaster-admin/vite.config.ts @@ -0,0 +1,21 @@ +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' +import path from 'path' + +export default defineConfig({ + plugins: [vue()], + resolve: { + alias: { + '@': path.resolve(__dirname, './src'), + }, + }, + server: { + port: 3001, + proxy: { + '/api': { + target: 'http://localhost:5000', + changeOrigin: true, + }, + }, + }, +}) diff --git a/frontend/fatemaster-web/index.html b/frontend/fatemaster-web/index.html new file mode 100644 index 0000000..618ecc3 --- /dev/null +++ b/frontend/fatemaster-web/index.html @@ -0,0 +1,13 @@ + + + + + + + FateMaster - 命运大师 + + +
+ + + diff --git a/frontend/fatemaster-web/package-lock.json b/frontend/fatemaster-web/package-lock.json new file mode 100644 index 0000000..cf921f3 --- /dev/null +++ b/frontend/fatemaster-web/package-lock.json @@ -0,0 +1,1881 @@ +{ + "name": "fatemaster-web", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "fatemaster-web", + "version": "0.1.0", + "dependencies": { + "ant-design-vue": "^4.2.1", + "axios": "^1.6.8", + "pinia": "^2.1.7", + "vue": "^3.4.21", + "vue-i18n": "^9.10.2", + "vue-router": "^4.3.0" + }, + "devDependencies": { + "@types/node": "^20.11.30", + "@vitejs/plugin-vue": "^5.0.4", + "typescript": "^5.4.3", + "vite": "^5.2.0", + "vue-tsc": "^2.0.6" + } + }, + "node_modules/@ant-design/colors": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-6.0.0.tgz", + "integrity": "sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==", + "dependencies": { + "@ctrl/tinycolor": "^3.4.0" + } + }, + "node_modules/@ant-design/icons-svg": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz", + "integrity": "sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==" + }, + "node_modules/@ant-design/icons-vue": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@ant-design/icons-vue/-/icons-vue-7.0.1.tgz", + "integrity": "sha512-eCqY2unfZK6Fe02AwFlDHLfoyEFreP6rBwAZMIJ1LugmfMiVgwWDYlp1YsRugaPtICYOabV1iWxXdP12u9U43Q==", + "dependencies": { + "@ant-design/colors": "^6.0.0", + "@ant-design/icons-svg": "^4.2.1" + }, + "peerDependencies": { + "vue": ">=3.0.3" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", + "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", + "dependencies": { + "@babel/types": "^7.28.4" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", + "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", + "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@ctrl/tinycolor": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz", + "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==" + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@intlify/core-base": { + "version": "9.14.5", + "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.14.5.tgz", + "integrity": "sha512-5ah5FqZG4pOoHjkvs8mjtv+gPKYU0zCISaYNjBNNqYiaITxW8ZtVih3GS/oTOqN8d9/mDLyrjD46GBApNxmlsA==", + "dependencies": { + "@intlify/message-compiler": "9.14.5", + "@intlify/shared": "9.14.5" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, + "node_modules/@intlify/message-compiler": { + "version": "9.14.5", + "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.14.5.tgz", + "integrity": "sha512-IHzgEu61/YIpQV5Pc3aRWScDcnFKWvQA9kigcINcCBXN8mbW+vk9SK+lDxA6STzKQsVJxUPg9ACC52pKKo3SVQ==", + "dependencies": { + "@intlify/shared": "9.14.5", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, + "node_modules/@intlify/shared": { + "version": "9.14.5", + "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.14.5.tgz", + "integrity": "sha512-9gB+E53BYuAEMhbCAxVgG38EZrk59sxBtv3jSizNL2hEWlgjBjAw1AwpLHtNaeda12pe6W20OGEa0TwuMSRbyQ==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.3.tgz", + "integrity": "sha512-h6cqHGZ6VdnwliFG1NXvMPTy/9PS3h8oLh7ImwR+kl+oYnQizgjxsONmmPSb2C66RksfkfIxEVtDSEcJiO0tqw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.3.tgz", + "integrity": "sha512-wd+u7SLT/u6knklV/ifG7gr5Qy4GUbH2hMWcDauPFJzmCZUAJ8L2bTkVXC2niOIxp8lk3iH/QX8kSrUxVZrOVw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.3.tgz", + "integrity": "sha512-lj9ViATR1SsqycwFkJCtYfQTheBdvlWJqzqxwc9f2qrcVrQaF/gCuBRTiTolkRWS6KvNxSk4KHZWG7tDktLgjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.3.tgz", + "integrity": "sha512-+Dyo7O1KUmIsbzx1l+4V4tvEVnVQqMOIYtrxK7ncLSknl1xnMHLgn7gddJVrYPNZfEB8CIi3hK8gq8bDhb3h5A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.3.tgz", + "integrity": "sha512-u9Xg2FavYbD30g3DSfNhxgNrxhi6xVG4Y6i9Ur1C7xUuGDW3banRbXj+qgnIrwRN4KeJ396jchwy9bCIzbyBEQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.3.tgz", + "integrity": "sha512-5M8kyi/OX96wtD5qJR89a/3x5x8x5inXBZO04JWhkQb2JWavOWfjgkdvUqibGJeNNaz1/Z1PPza5/tAPXICI6A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.3.tgz", + "integrity": "sha512-IoerZJ4l1wRMopEHRKOO16e04iXRDyZFZnNZKrWeNquh5d6bucjezgd+OxG03mOMTnS1x7hilzb3uURPkJ0OfA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.3.tgz", + "integrity": "sha512-ZYdtqgHTDfvrJHSh3W22TvjWxwOgc3ThK/XjgcNGP2DIwFIPeAPNsQxrJO5XqleSlgDux2VAoWQ5iJrtaC1TbA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.3.tgz", + "integrity": "sha512-NcViG7A0YtuFDA6xWSgmFb6iPFzHlf5vcqb2p0lGEbT+gjrEEz8nC/EeDHvx6mnGXnGCC1SeVV+8u+smj0CeGQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.3.tgz", + "integrity": "sha512-d3pY7LWno6SYNXRm6Ebsq0DJGoiLXTb83AIPCXl9fmtIQs/rXoS8SJxxUNtFbJ5MiOvs+7y34np77+9l4nfFMw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.3.tgz", + "integrity": "sha512-3y5GA0JkBuirLqmjwAKwB0keDlI6JfGYduMlJD/Rl7fvb4Ni8iKdQs1eiunMZJhwDWdCvrcqXRY++VEBbvk6Eg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.3.tgz", + "integrity": "sha512-AUUH65a0p3Q0Yfm5oD2KVgzTKgwPyp9DSXc3UA7DtxhEb/WSPfbG4wqXeSN62OG5gSo18em4xv6dbfcUGXcagw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.3.tgz", + "integrity": "sha512-1makPhFFVBqZE+XFg3Dkq+IkQ7JvmUrwwqaYBL2CE+ZpxPaqkGaiWFEWVGyvTwZace6WLJHwjVh/+CXbKDGPmg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.3.tgz", + "integrity": "sha512-OOFJa28dxfl8kLOPMUOQBCO6z3X2SAfzIE276fwT52uXDWUS178KWq0pL7d6p1kz7pkzA0yQwtqL0dEPoVcRWg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.3.tgz", + "integrity": "sha512-jMdsML2VI5l+V7cKfZx3ak+SLlJ8fKvLJ0Eoa4b9/vCUrzXKgoKxvHqvJ/mkWhFiyp88nCkM5S2v6nIwRtPcgg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.3.tgz", + "integrity": "sha512-tPgGd6bY2M2LJTA1uGq8fkSPK8ZLYjDjY+ZLK9WHncCnfIz29LIXIqUgzCR0hIefzy6Hpbe8Th5WOSwTM8E7LA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.3.tgz", + "integrity": "sha512-BCFkJjgk+WFzP+tcSMXq77ymAPIxsX9lFJWs+2JzuZTLtksJ2o5hvgTdIcZ5+oKzUDMwI0PfWzRBYAydAHF2Mw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.3.tgz", + "integrity": "sha512-KTD/EqjZF3yvRaWUJdD1cW+IQBk4fbQaHYJUmP8N4XoKFZilVL8cobFSTDnjTtxWJQ3JYaMgF4nObY/+nYkumA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.3.tgz", + "integrity": "sha512-+zteHZdoUYLkyYKObGHieibUFLbttX2r+58l27XZauq0tcWYYuKUwY2wjeCN9oK1Um2YgH2ibd6cnX/wFD7DuA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.3.tgz", + "integrity": "sha512-of1iHkTQSo3kr6dTIRX6t81uj/c/b15HXVsPcEElN5sS859qHrOepM5p9G41Hah+CTqSh2r8Bm56dL2z9UQQ7g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.3.tgz", + "integrity": "sha512-s0hybmlHb56mWVZQj8ra9048/WZTPLILKxcvcq+8awSZmyiSUZjjem1AhU3Tf4ZKpYhK4mg36HtHDOe8QJS5PQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.3.tgz", + "integrity": "sha512-zGIbEVVXVtauFgl3MRwGWEN36P5ZGenHRMgNw88X5wEhEBpq0XrMEZwOn07+ICrwM17XO5xfMZqh0OldCH5VTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@simonwep/pickr": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@simonwep/pickr/-/pickr-1.8.2.tgz", + "integrity": "sha512-/l5w8BIkrpP6n1xsetx9MWPWlU6OblN5YgZZphxan0Tq4BByTCETL6lyIeY8lagalS2Nbt4F2W034KHLIiunKA==", + "dependencies": { + "core-js": "^3.15.1", + "nanopop": "^2.1.0" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.19.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.19.tgz", + "integrity": "sha512-pb1Uqj5WJP7wrcbLU7Ru4QtA0+3kAXrkutGiD26wUKzSMgNNaPARTUDQmElUXp64kh3cWdou3Q0C7qwwxqSFmg==", + "dev": true, + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@vitejs/plugin-vue": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz", + "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==", + "dev": true, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@volar/language-core": { + "version": "2.4.15", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.15.tgz", + "integrity": "sha512-3VHw+QZU0ZG9IuQmzT68IyN4hZNd9GchGPhbD9+pa8CVv7rnoOZwo7T8weIbrRmihqy3ATpdfXFnqRrfPVK6CA==", + "dev": true, + "dependencies": { + "@volar/source-map": "2.4.15" + } + }, + "node_modules/@volar/source-map": { + "version": "2.4.15", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.15.tgz", + "integrity": "sha512-CPbMWlUN6hVZJYGcU/GSoHu4EnCHiLaXI9n8c9la6RaI9W5JHX+NqG+GSQcB0JdC2FIBLdZJwGsfKyBB71VlTg==", + "dev": true + }, + "node_modules/@volar/typescript": { + "version": "2.4.15", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.15.tgz", + "integrity": "sha512-2aZ8i0cqPGjXb4BhkMsPYDkkuc2ZQ6yOpqwAuNwUoncELqoy5fRgOQtLR9gB0g902iS0NAkvpIzs27geVyVdPg==", + "dev": true, + "dependencies": { + "@volar/language-core": "2.4.15", + "path-browserify": "^1.0.1", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.22.tgz", + "integrity": "sha512-jQ0pFPmZwTEiRNSb+i9Ow/I/cHv2tXYqsnHKKyCQ08irI2kdF5qmYedmF8si8mA7zepUFmJ2hqzS8CQmNOWOkQ==", + "dependencies": { + "@babel/parser": "^7.28.4", + "@vue/shared": "3.5.22", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.22.tgz", + "integrity": "sha512-W8RknzUM1BLkypvdz10OVsGxnMAuSIZs9Wdx1vzA3mL5fNMN15rhrSCLiTm6blWeACwUwizzPVqGJgOGBEN/hA==", + "dependencies": { + "@vue/compiler-core": "3.5.22", + "@vue/shared": "3.5.22" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.22.tgz", + "integrity": "sha512-tbTR1zKGce4Lj+JLzFXDq36K4vcSZbJ1RBu8FxcDv1IGRz//Dh2EBqksyGVypz3kXpshIfWKGOCcqpSbyGWRJQ==", + "dependencies": { + "@babel/parser": "^7.28.4", + "@vue/compiler-core": "3.5.22", + "@vue/compiler-dom": "3.5.22", + "@vue/compiler-ssr": "3.5.22", + "@vue/shared": "3.5.22", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.19", + "postcss": "^8.5.6", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.22.tgz", + "integrity": "sha512-GdgyLvg4R+7T8Nk2Mlighx7XGxq/fJf9jaVofc3IL0EPesTE86cP/8DD1lT3h1JeZr2ySBvyqKQJgbS54IX1Ww==", + "dependencies": { + "@vue/compiler-dom": "3.5.22", + "@vue/shared": "3.5.22" + } + }, + "node_modules/@vue/compiler-vue2": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/@vue/compiler-vue2/-/compiler-vue2-2.7.16.tgz", + "integrity": "sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==", + "dev": true, + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.2.0" + } + }, + "node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==" + }, + "node_modules/@vue/language-core": { + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.2.12.tgz", + "integrity": "sha512-IsGljWbKGU1MZpBPN+BvPAdr55YPkj2nB/TBNGNC32Vy2qLG25DYu/NBN2vNtZqdRbTRjaoYrahLrToim2NanA==", + "dev": true, + "dependencies": { + "@volar/language-core": "2.4.15", + "@vue/compiler-dom": "^3.5.0", + "@vue/compiler-vue2": "^2.7.16", + "@vue/shared": "^3.5.0", + "alien-signals": "^1.0.3", + "minimatch": "^9.0.3", + "muggle-string": "^0.4.1", + "path-browserify": "^1.0.1" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@vue/reactivity": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.22.tgz", + "integrity": "sha512-f2Wux4v/Z2pqc9+4SmgZC1p73Z53fyD90NFWXiX9AKVnVBEvLFOWCEgJD3GdGnlxPZt01PSlfmLqbLYzY/Fw4A==", + "dependencies": { + "@vue/shared": "3.5.22" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.22.tgz", + "integrity": "sha512-EHo4W/eiYeAzRTN5PCextDUZ0dMs9I8mQ2Fy+OkzvRPUYQEyK9yAjbasrMCXbLNhF7P0OUyivLjIy0yc6VrLJQ==", + "dependencies": { + "@vue/reactivity": "3.5.22", + "@vue/shared": "3.5.22" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.22.tgz", + "integrity": "sha512-Av60jsryAkI023PlN7LsqrfPvwfxOd2yAwtReCjeuugTJTkgrksYJJstg1e12qle0NarkfhfFu1ox2D+cQotww==", + "dependencies": { + "@vue/reactivity": "3.5.22", + "@vue/runtime-core": "3.5.22", + "@vue/shared": "3.5.22", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.22.tgz", + "integrity": "sha512-gXjo+ao0oHYTSswF+a3KRHZ1WszxIqO7u6XwNHqcqb9JfyIL/pbWrrh/xLv7jeDqla9u+LK7yfZKHih1e1RKAQ==", + "dependencies": { + "@vue/compiler-ssr": "3.5.22", + "@vue/shared": "3.5.22" + }, + "peerDependencies": { + "vue": "3.5.22" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.22.tgz", + "integrity": "sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w==" + }, + "node_modules/alien-signals": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-1.0.13.tgz", + "integrity": "sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==", + "dev": true + }, + "node_modules/ant-design-vue": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-4.2.6.tgz", + "integrity": "sha512-t7eX13Yj3i9+i5g9lqFyYneoIb3OzTvQjq9Tts1i+eiOd3Eva/6GagxBSXM1fOCjqemIu0FYVE1ByZ/38epR3Q==", + "dependencies": { + "@ant-design/colors": "^6.0.0", + "@ant-design/icons-vue": "^7.0.0", + "@babel/runtime": "^7.10.5", + "@ctrl/tinycolor": "^3.5.0", + "@emotion/hash": "^0.9.0", + "@emotion/unitless": "^0.8.0", + "@simonwep/pickr": "~1.8.0", + "array-tree-filter": "^2.1.0", + "async-validator": "^4.0.0", + "csstype": "^3.1.1", + "dayjs": "^1.10.5", + "dom-align": "^1.12.1", + "dom-scroll-into-view": "^2.0.0", + "lodash": "^4.17.21", + "lodash-es": "^4.17.15", + "resize-observer-polyfill": "^1.5.1", + "scroll-into-view-if-needed": "^2.2.25", + "shallow-equal": "^1.0.0", + "stylis": "^4.1.3", + "throttle-debounce": "^5.0.0", + "vue-types": "^3.0.0", + "warning": "^4.0.0" + }, + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ant-design-vue" + }, + "peerDependencies": { + "vue": ">=3.2.0" + } + }, + "node_modules/array-tree-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-tree-filter/-/array-tree-filter-2.1.0.tgz", + "integrity": "sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==" + }, + "node_modules/async-validator": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz", + "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", + "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/compute-scroll-into-view": { + "version": "1.0.20", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz", + "integrity": "sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==" + }, + "node_modules/core-js": { + "version": "3.45.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.45.1.tgz", + "integrity": "sha512-L4NPsJlCfZsPeXukyzHFlg/i7IIVwHSItR0wg0FLNqYClJ4MQYTYLbC7EkjKYRLZF2iof2MUgN0EGy7MdQFChg==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/dayjs": { + "version": "1.11.18", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.18.tgz", + "integrity": "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==" + }, + "node_modules/de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", + "dev": true + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dom-align": { + "version": "1.12.4", + "resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.12.4.tgz", + "integrity": "sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==" + }, + "node_modules/dom-scroll-into-view": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-2.0.1.tgz", + "integrity": "sha512-bvVTQe1lfaUr1oFzZX80ce9KLDlZ3iU+XGNE/bz9HnGdklTieqsbmsLHe+rT2XWqopvL0PckkYqN7ksmm5pe3w==" + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/is-plain-object": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz", + "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.19", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz", + "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/muggle-string": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz", + "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/nanopop": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/nanopop/-/nanopop-2.4.2.tgz", + "integrity": "sha512-NzOgmMQ+elxxHeIha+OG/Pv3Oc3p4RU2aBhwWwAqDpXrdTbtRylbRLQztLy8dMMwfl6pclznBdfUhccEn9ZIzw==" + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, + "node_modules/pinia": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.3.1.tgz", + "integrity": "sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==", + "dependencies": { + "@vue/devtools-api": "^6.6.3", + "vue-demi": "^0.14.10" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "typescript": ">=4.4.4", + "vue": "^2.7.0 || ^3.5.11" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, + "node_modules/rollup": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.3.tgz", + "integrity": "sha512-RIDh866U8agLgiIcdpB+COKnlCreHJLfIhWC3LVflku5YHfpnsIKigRZeFfMfCc4dVcqNVfQQ5gO/afOck064A==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.52.3", + "@rollup/rollup-android-arm64": "4.52.3", + "@rollup/rollup-darwin-arm64": "4.52.3", + "@rollup/rollup-darwin-x64": "4.52.3", + "@rollup/rollup-freebsd-arm64": "4.52.3", + "@rollup/rollup-freebsd-x64": "4.52.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.3", + "@rollup/rollup-linux-arm-musleabihf": "4.52.3", + "@rollup/rollup-linux-arm64-gnu": "4.52.3", + "@rollup/rollup-linux-arm64-musl": "4.52.3", + "@rollup/rollup-linux-loong64-gnu": "4.52.3", + "@rollup/rollup-linux-ppc64-gnu": "4.52.3", + "@rollup/rollup-linux-riscv64-gnu": "4.52.3", + "@rollup/rollup-linux-riscv64-musl": "4.52.3", + "@rollup/rollup-linux-s390x-gnu": "4.52.3", + "@rollup/rollup-linux-x64-gnu": "4.52.3", + "@rollup/rollup-linux-x64-musl": "4.52.3", + "@rollup/rollup-openharmony-arm64": "4.52.3", + "@rollup/rollup-win32-arm64-msvc": "4.52.3", + "@rollup/rollup-win32-ia32-msvc": "4.52.3", + "@rollup/rollup-win32-x64-gnu": "4.52.3", + "@rollup/rollup-win32-x64-msvc": "4.52.3", + "fsevents": "~2.3.2" + } + }, + "node_modules/scroll-into-view-if-needed": { + "version": "2.2.31", + "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz", + "integrity": "sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==", + "dependencies": { + "compute-scroll-into-view": "^1.0.20" + } + }, + "node_modules/shallow-equal": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz", + "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==" + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylis": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz", + "integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==" + }, + "node_modules/throttle-debounce": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.2.tgz", + "integrity": "sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==", + "engines": { + "node": ">=12.22" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "devOptional": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true + }, + "node_modules/vite": { + "version": "5.4.20", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.20.tgz", + "integrity": "sha512-j3lYzGC3P+B5Yfy/pfKNgVEg4+UtcIJcVRt2cDjIOmhLourAqPqf8P7acgxeiSgUB7E3p2P8/3gNIgDLpwzs4g==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vscode-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz", + "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==", + "dev": true + }, + "node_modules/vue": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.22.tgz", + "integrity": "sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==", + "dependencies": { + "@vue/compiler-dom": "3.5.22", + "@vue/compiler-sfc": "3.5.22", + "@vue/runtime-dom": "3.5.22", + "@vue/server-renderer": "3.5.22", + "@vue/shared": "3.5.22" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/vue-i18n": { + "version": "9.14.5", + "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.14.5.tgz", + "integrity": "sha512-0jQ9Em3ymWngyiIkj0+c/k7WgaPO+TNzjKSNq9BvBQaKJECqn9cd9fL4tkDhB5G1QBskGl9YxxbDAhgbFtpe2g==", + "dependencies": { + "@intlify/core-base": "9.14.5", + "@intlify/shared": "9.14.5", + "@vue/devtools-api": "^6.5.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/vue-router": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.1.tgz", + "integrity": "sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==", + "dependencies": { + "@vue/devtools-api": "^6.6.4" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/vue-tsc": { + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.2.12.tgz", + "integrity": "sha512-P7OP77b2h/Pmk+lZdJ0YWs+5tJ6J2+uOQPo7tlBnY44QqQSPYvS0qVT4wqDJgwrZaLe47etJLLQRFia71GYITw==", + "dev": true, + "dependencies": { + "@volar/typescript": "2.4.15", + "@vue/language-core": "2.2.12" + }, + "bin": { + "vue-tsc": "bin/vue-tsc.js" + }, + "peerDependencies": { + "typescript": ">=5.0.0" + } + }, + "node_modules/vue-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vue-types/-/vue-types-3.0.2.tgz", + "integrity": "sha512-IwUC0Aq2zwaXqy74h4WCvFCUtoV0iSWr0snWnE9TnU18S66GAQyqQbRf2qfJtUuiFsBf6qp0MEwdonlwznlcrw==", + "dependencies": { + "is-plain-object": "3.0.1" + }, + "engines": { + "node": ">=10.15.0" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "dependencies": { + "loose-envify": "^1.0.0" + } + } + } +} diff --git a/frontend/fatemaster-web/package.json b/frontend/fatemaster-web/package.json new file mode 100644 index 0000000..4cd8fa5 --- /dev/null +++ b/frontend/fatemaster-web/package.json @@ -0,0 +1,26 @@ +{ + "name": "fatemaster-web", + "private": true, + "version": "0.1.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vue-tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "vue": "^3.4.21", + "vue-router": "^4.3.0", + "pinia": "^2.1.7", + "ant-design-vue": "^4.2.1", + "vue-i18n": "^9.10.2", + "axios": "^1.6.8" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.0.4", + "typescript": "^5.4.3", + "vite": "^5.2.0", + "vue-tsc": "^2.0.6", + "@types/node": "^20.11.30" + } +} diff --git a/frontend/fatemaster-web/src/App.vue b/frontend/fatemaster-web/src/App.vue new file mode 100644 index 0000000..f17da13 --- /dev/null +++ b/frontend/fatemaster-web/src/App.vue @@ -0,0 +1,26 @@ + + + diff --git a/frontend/fatemaster-web/src/components/RelationshipCompatibility.vue b/frontend/fatemaster-web/src/components/RelationshipCompatibility.vue new file mode 100644 index 0000000..c6aa153 --- /dev/null +++ b/frontend/fatemaster-web/src/components/RelationshipCompatibility.vue @@ -0,0 +1,378 @@ + + + + + diff --git a/frontend/fatemaster-web/src/i18n/index.ts b/frontend/fatemaster-web/src/i18n/index.ts new file mode 100644 index 0000000..82099a0 --- /dev/null +++ b/frontend/fatemaster-web/src/i18n/index.ts @@ -0,0 +1,1090 @@ +import { createI18n } from 'vue-i18n' + +const messages = { + 'zh-CN': { + nav: { + home: '首页', + bazi: '八字功能', + bazi_analysis: '八字分析', + daily_fortune: '每日运势', + bazi_marriage: '八字合婚', + career_compatibility: '事业合盘', + mother_in_law: '婆媳合盘', + best_friends: '闺蜜合盘', + father_son: '父子关系', + mother_son: '母子关系', + friends: '朋友关系', + boss_subordinate: '领导下属', + + divination: '周易占卜', + plum_blossom: '梅花易数·每日决策', + liuyao: '六爻', + + tarot: '塔罗牌', + tarot_reading: '塔罗牌', + tarot_meaning: '塔罗牌牌义解读', + + theory: '理论知识', + five_elements: '五行理论', + ten_heavenly: '十天干理论', + twelve_earthly: '十二地支理论', + sixty_jiazi: '六十甲子理论', + nayin: '纳音五行理论', + ten_gods: '十神理论', + spirits: '神煞大全', + fortune_period: '大运理论', + fortune_timing: '大运起运时间理论', + true_solar: '真太阳时理论', + child_hour: '早晚子时理论', + iching_64: '易经64卦', + + tools: '实用工具', + ai_calendar: 'AI老黄历', + + // 旧的菜单项(保持兼容) + career: '事业运势', + marriage: '姻缘测算', + zodiac: '星座运势', + }, + common: { + submit: '提交', + reset: '重置', + pay: '支付', + free: '免费体验', + language: '语言', + }, + home: { + title: '命运大师', + subtitle: '探索您的命运轨迹', + start_divination: '开始测算', + start: '开始测算', + our_services: '我们的服务', + why_choose_us: '为什么选择我们', + feature_1_title: '精准命盘', + feature_1_desc: '采用天文文献,编纂八字排盘的准确性,为你精准呈现命盘基础', + feature_2_title: 'AI解读', + feature_2_desc: '运用人工智能技术,深入分析五行属性与天地交互关系', + feature_3_title: '科学客观', + feature_3_desc: '融合大数据分析,提供客观、可量化的命理咨询建议', + bazi_desc: '通过生辰八字,解析您的命运密码', + career_desc: '事业运势分析,助您事业腾飞', + marriage_desc: '姻缘测算,寻找您的真命天子', + tarot_desc: '塔罗占卜,揭示未来的秘密', + zodiac_desc: '星座运势,每日运程早知道', + }, + // nav: { + // home: '首页', + // bazi: '批八字', + // career: '事业运势', + // marriage: '姻缘测算', + // tarot: '塔罗占卜', + // zodiac: '星座运势', + // }, + bazi: { + // 页面标题 + page_title: '八字计算', + page_subtitle: '精准解析生辰八字,揭示命盘奥秘', + + // 表单字段 + subtitle: '精准解析生辰八字,揭示命运奥秘', + basic_info: '基本信息', + time_info: '时间信息', + birth_place: '出生地点', + input_method: '输入方式', + input_date: '日期', + input_bazi: '八字', + calendar_method: '日历方式', + lunar_method: '农历方式', + birth_date: '出生日期', + select_date: '选择日期', + birth_time: '出生时间', + know_time: '我知道出生时间', + know_time_desc: '如果不知道确切的出生时间,可以不选择', + birth_hour: '出生时间', + time: '出生时辰', + hour: '时', + minute: '分', + hour_unit: '时', + minute_unit: '分', + place_placeholder: '搜索并选择出生地', + place_tip: '请尽量选择详细的地址以获取准确的经纬度', + use_early_child: '使用早晚子时', + start_calculation: '开始计算八字', + + // 八字输入 + bazi_input: '八字输入', + year_pillar: '年柱', + month_pillar: '月柱', + day_pillar: '日柱', + hour_pillar: '时柱', + select_heavenly_stem: '选择天干', + select_earthly_branch: '选择地支', + clear: '清空', + + // AI 智能解析 + ai_title: 'AI 智能八字解析系统', + ai_subtitle: '结合传统命理与现代科技,为您提供专业精准的八字分析服务', + feature_accurate_title: '精准命盘', + feature_accurate_desc: '采用天文文献,确保八字排盘的准确性,为分析提供坚实基础', + feature_ai_title: 'AI 解读', + feature_ai_desc: '运用人工智能技术,深入分析五行属性与天地关系', + feature_scientific_title: '科学客观', + feature_scientific_desc: '融合大数据分析,提供客观、可量化的命理咨询建议', + + // 全方位分析 + analysis_title: '全方位命理解析', + analysis_subtitle: '深入分析命盘各个方面,为您的人生选择提供智慧参考', + analysis_character_title: '性格洞察', + analysis_character_desc: '解读性格特质与天赋潜能,帮助更深刻的认知个人和成长方向', + analysis_career_title: '事业方向', + analysis_career_desc: '深解事业天赋与发展契机,为您的事业规划提供精准参考', + analysis_wealth_title: '财运特征', + analysis_wealth_desc: '分析财运走势与理财倾向,为您的财富积累提供思路发展', + analysis_health_title: '健康运势', + analysis_health_desc: '分析体质特征与健康倾向,为您的养生保健提供参考建议', + + // 使用指南 + guide_title: '使用指南', + guide_subtitle: '简单四步,获取您的专业八字分析报告', + guide_step1_title: '填写出生信息', + guide_step1_desc: '准确输入您的出生信息', + guide_step2_title: '选择性别', + guide_step2_desc: '填入个人基础信息', + guide_step3_title: '确认历法', + guide_step3_desc: '选择相应或农历', + guide_step4_title: '获取分析报告', + guide_step4_desc: '获取详细的结果报告', + + // 免责声明 + disclaimer: '本服务仅供娱乐之用,重要决策应结合个人认知和实际,生活由我与专业建议综合考虑。', + }, + daily_fortune: { + // 页面标题 + page_title: '每日运势', + page_subtitle: '掌握今日运势,抓住好运时机', + + // 表单字段 + birth_info: '出生信息', + check_fortune: '查看今日运势', + + // 功能介绍 + intro_title: '每日运势查询', + intro_subtitle: '基于您的八字,精准预测每日运势变化', + feature_daily_title: '每日更新', + feature_daily_desc: '每天为您提供最新的运势分析和建议', + feature_accurate_title: '精准预测', + feature_accurate_desc: '结合八字命理,准确把握运势走向', + feature_guide_title: '生活指引', + feature_guide_desc: '提供具体的生活、工作建议,助您趋吉避凶', + }, + marriage: { + // 页面标题 + page_title: '八字合婚', + page_subtitle: '分析两人八字相合程度,预测婚姻幸福指数', + + // 表单字段 + male_info: '男方信息', + female_info: '女方信息', + male_name_placeholder: '请输入男方姓名', + female_name_placeholder: '请输入女方姓名', + male_name_required: '请输入男方姓名', + female_name_required: '请输入女方姓名', + male_birth_required: '请选择男方出生日期', + female_birth_required: '请选择女方出生日期', + start_match: '开始合婚分析', + + // 功能介绍 + intro_title: '八字合婚分析', + intro_subtitle: '传统命理学结合AI智能,深度分析两人婚姻匹配度', + feature_compatibility_title: '姻缘匹配', + feature_compatibility_desc: '分析双方八字五行相生相克,评估婚姻契合度', + feature_analysis_title: '性格互补', + feature_analysis_desc: '深入解读双方性格特点,提供相处建议', + feature_suggest_title: '婚姻指导', + feature_suggest_desc: '提供婚姻生活建议,助力幸福美满', + }, + compatibility: { + // 通用字段 + person1_placeholder: '请输入姓名', + person2_placeholder: '请输入姓名', + person1_name_required: '请输入第一人姓名', + person2_name_required: '请输入第二人姓名', + person1_birth_required: '请选择第一人出生日期', + person2_birth_required: '请选择第二人出生日期', + start_analysis: '开始合盘分析', + + // 通用功能介绍 + feature1_title: '关系分析', + feature1_desc: '深入分析双方八字,评估关系和谐度', + feature2_title: 'AI解读', + feature2_desc: '运用AI技术,提供专业的关系建议', + feature3_title: '相处建议', + feature3_desc: '提供实用的相处技巧,促进关系和谐', + + // 事业合盘 + career_title: '事业合盘', + career_subtitle: '分析事业伙伴关系,预测合作前景', + career_person1: '第一人信息', + career_person2: '第二人信息', + career_intro_title: '事业合作分析', + career_intro_subtitle: '基于八字命理,评估事业合作的成功概率', + + // 婆媳合盘 + mother_in_law_title: '婆媳合盘', + mother_in_law_subtitle: '分析婆媳关系,促进家庭和睦', + mother_in_law_person1: '婆婆信息', + mother_in_law_person2: '媳妇信息', + mother_in_law_intro_title: '婆媳关系分析', + mother_in_law_intro_subtitle: '深入了解双方性格,提供和谐相处建议', + + // 闺蜜合盘 + best_friends_title: '闺蜜合盘', + best_friends_subtitle: '分析友谊契合度,增进闺蜜感情', + best_friends_person1: '第一人信息', + best_friends_person2: '第二人信息', + best_friends_intro_title: '闺蜜关系分析', + best_friends_intro_subtitle: '了解性格互补性,打造长久友谊', + + // 父子关系 + father_son_title: '父子关系', + father_son_subtitle: '分析父子互动模式,促进亲子和谐', + father_son_person1: '父亲信息', + father_son_person2: '儿子信息', + father_son_intro_title: '父子关系分析', + father_son_intro_subtitle: '深入了解代际差异,改善亲子沟通', + + // 母子关系 + mother_son_title: '母子关系', + mother_son_subtitle: '分析母子互动模式,增进亲子感情', + mother_son_person1: '母亲信息', + mother_son_person2: '儿子信息', + mother_son_intro_title: '母子关系分析', + mother_son_intro_subtitle: '理解性格差异,构建温馨亲子关系', + + // 朋友关系 + friends_title: '朋友关系', + friends_subtitle: '分析朋友契合度,维护友谊长久', + friends_person1: '第一人信息', + friends_person2: '第二人信息', + friends_intro_title: '朋友关系分析', + friends_intro_subtitle: '了解性格互补,建立真挚友谊', + + // 领导下属 + boss_subordinate_title: '领导下属关系', + boss_subordinate_subtitle: '分析上下级关系,促进工作和谐', + boss_subordinate_person1: '领导信息', + boss_subordinate_person2: '下属信息', + boss_subordinate_intro_title: '上下级关系分析', + boss_subordinate_intro_subtitle: '了解管理风格与工作方式,提升团队效率', + }, + plum_blossom: { + page_title: '梅花易数·每日决策', + page_subtitle: '古老智慧指引现代决策', + ask_question: '请输入您的问题', + question_placeholder: '详细描述您想要咨询的问题...', + question_hint: '问题越具体,解析越准确', + question_required: '请输入您的问题', + divination_method: '选择起卦方式', + time_method: '时间起卦', + number_method: '数字起卦', + random_method: '随机起卦', + enter_numbers: '输入数字', + upper_number: '上卦数', + lower_number: '下卦数', + number_hint: '请输入1-8的数字', + numbers_required: '请输入上卦数和下卦数', + start_divination: '开始占卜', + intro_title: '梅花易数占卜', + intro_subtitle: '源自宋代易学大师邵雍的占卜方法', + feature1_title: '快速灵验', + feature1_desc: '简单快捷的起卦方式,灵验准确', + feature2_title: '决策指引', + feature2_desc: '为日常决策提供智慧参考', + feature3_title: '易学精髓', + feature3_desc: '传承千年的易学智慧', + }, + liuyao: { + page_title: '六爻占卜', + page_subtitle: '传统卜卦方法,洞察事物发展', + ask_question: '请输入您的问题', + question_placeholder: '详细描述您想要咨询的问题...', + question_hint: '问题越具体,解析越准确', + question_required: '请输入您的问题', + line: '第', + shake_coins: '摇卦(点击投掷铜钱)', + shaking: '摇卦中...', + complete: '六爻已成,可以开始占卜', + incomplete: '请完成六次摇卦', + start_divination: '开始占卜解析', + intro_title: '六爻占卜', + intro_subtitle: '中国传统占卜术,通过六次投掷铜钱成卦', + feature1_title: '传统经典', + feature1_desc: '传承千年的卜卦方法', + feature2_title: '详细解析', + feature2_desc: '深入分析卦象,提供详尽建议', + feature3_title: '应用广泛', + feature3_desc: '适用于各种决策场景', + }, + tarot: { + page_title: '塔罗占卜', + page_subtitle: '探索内心,揭示未来', + ask_question: '请输入您的问题', + question_placeholder: '详细描述您想要咨询的问题...', + question_hint: '专注于您的问题,让塔罗牌为您指引', + question_required: '请输入您的问题', + select_spread: '选择牌阵', + single_card: '单张牌', + three_cards: '三张牌', + celtic_cross: '凯尔特十字', + start_reading: '开始占卜', + intro_title: '塔罗占卜', + intro_subtitle: '古老的智慧工具,洞察人生', + feature1_title: '心灵指引', + feature1_desc: '深入内心,探索真实想法', + feature2_title: '多种牌阵', + feature2_desc: '不同牌阵适用不同场景', + feature3_title: '丰富解读', + feature3_desc: '详细的牌面解释和建议', + }, + form: { + name: '姓名', + name_required: '请输入姓名', + name_placeholder: '请输入您的姓名', + gender: '性别', + gender_required: '请选择性别', + male: '男', + female: '女', + birth_date: '出生日期时辰', + birth_date_required: '请选择出生日期时辰', + birth_date_placeholder: '请选择出生日期和时辰', + birth_place: '出生地点', + birth_place_placeholder: '请输入出生地点(可选)', + calendar_type: '历法', + solar: '公历', + lunar: '农历', + }, + payment: { + title: '选择支付方式', + alipay: '支付宝', + paypal: 'PayPal', + stripe: 'Stripe', + price: '价格', + }, + message: { + submit_success: '提交成功,正在生成结果...', + submit_error: '提交失败,请重试', + }, + }, + 'zh-TW': { + nav: { + home: '首頁', + bazi: '八字功能', + bazi_analysis: '八字分析', + daily_fortune: '每日運勢', + bazi_marriage: '八字合婚', + career_compatibility: '事業合盤', + mother_in_law: '婆媳合盤', + best_friends: '閨蜜合盤', + father_son: '父子關係', + mother_son: '母子關係', + friends: '朋友關係', + boss_subordinate: '領導下屬', + + divination: '周易占卜', + plum_blossom: '梅花易數·每日決策', + liuyao: '六爻', + + tarot: '塔羅牌', + tarot_reading: '塔羅牌', + tarot_meaning: '塔羅牌牌義解讀', + + theory: '理論知識', + five_elements: '五行理論', + ten_heavenly: '十天干理論', + twelve_earthly: '十二地支理論', + sixty_jiazi: '六十甲子理論', + nayin: '納音五行理論', + ten_gods: '十神理論', + spirits: '神煞大全', + fortune_period: '大運理論', + fortune_timing: '大運起運時間理論', + true_solar: '真太陽時理論', + child_hour: '早晚子時理論', + iching_64: '易經64卦', + + tools: '實用工具', + ai_calendar: 'AI老黃歷', + + // 舊的菜單項(保持兼容) + career: '事業運勢', + marriage: '姻緣測算', + zodiac: '星座運勢', + }, + bazi: { + // 页面标题 + page_title: '八字計算', + page_subtitle: '精準解析生辰八字,揭示命盤奧秘', + + // 表單字段 + basic_info: '基本信息', + time_info: '時間信息', + birth_place: '出生地點', + input_date: '日期', + input_bazi: '八字', + birth_date: '出生日期', + select_date: '選擇日期', + know_time: '我知道出生時間', + know_time_desc: '如果不知道確切的出生時間,可以不選擇', + birth_hour: '出生時間', + hour: '時', + minute: '分', + place_placeholder: '搜索並選擇出生地', + place_tip: '請盡量選擇詳細的地址以獲取準確的經緯度', + use_early_child: '使用早晚子時', + start_calculation: '開始計算八字', + + // 八字輸入 + bazi_input: '八字輸入', + year_pillar: '年柱', + month_pillar: '月柱', + day_pillar: '日柱', + hour_pillar: '時柱', + select_heavenly_stem: '選擇天干', + select_earthly_branch: '選擇地支', + clear: '清空', + + // AI 智能解析 + ai_title: 'AI 智能八字解析系統', + ai_subtitle: '結合傳統命理與現代科技,為您提供專業精準的八字分析服務', + feature_accurate_title: '精準命盤', + feature_accurate_desc: '採用天文文獻,確保八字排盤的準確性,為分析提供堅實基礎', + feature_ai_title: 'AI 解讀', + feature_ai_desc: '運用人工智能技術,深入分析五行屬性與天地關係', + feature_scientific_title: '科學客觀', + feature_scientific_desc: '融合大數據分析,提供客觀、可量化的命理諮詢建議', + + // 全方位分析 + analysis_title: '全方位命理解析', + analysis_subtitle: '深入分析命盤各個方面,為您的人生選擇提供智慧參考', + analysis_character_title: '性格洞察', + analysis_character_desc: '解讀性格特質與天賦潛能,幫助更深刻的認知個人和成長方向', + analysis_career_title: '事業方向', + analysis_career_desc: '深解事業天賦與發展契機,為您的事業規劃提供精準參考', + analysis_wealth_title: '財運特徵', + analysis_wealth_desc: '分析財運走勢與理財傾向,為您的財富積累提供思路發展', + analysis_health_title: '健康運勢', + analysis_health_desc: '分析體質特徵與健康傾向,為您的養生保健提供參考建議', + + // 使用指南 + guide_title: '使用指南', + guide_subtitle: '簡單四步,獲取您的專業八字分析報告', + guide_step1_title: '填寫出生信息', + guide_step1_desc: '準確輸入您的出生信息', + guide_step2_title: '選擇性別', + guide_step2_desc: '填入個人基礎信息', + guide_step3_title: '確認曆法', + guide_step3_desc: '選擇相應或農曆', + guide_step4_title: '獲取分析報告', + guide_step4_desc: '獲取詳細的結果報告', + + // 免責聲明 + disclaimer: '本服務僅供娛樂之用,重要決策應結合個人認知和實際,生活由我與專業建議綜合考慮。', + }, + daily_fortune: { + // 頁面標題 + page_title: '每日運勢', + page_subtitle: '掌握今日運勢,抓住好運時機', + + // 表單字段 + birth_info: '出生信息', + check_fortune: '查看今日運勢', + + // 功能介紹 + intro_title: '每日運勢查詢', + intro_subtitle: '基於您的八字,精準預測每日運勢變化', + feature_daily_title: '每日更新', + feature_daily_desc: '每天為您提供最新的運勢分析和建議', + feature_accurate_title: '精準預測', + feature_accurate_desc: '結合八字命理,準確把握運勢走向', + feature_guide_title: '生活指引', + feature_guide_desc: '提供具體的生活、工作建議,助您趨吉避凶', + }, + marriage: { + // 頁面標題 + page_title: '八字合婚', + page_subtitle: '分析兩人八字相合程度,預測婚姻幸福指數', + + // 表單字段 + male_info: '男方信息', + female_info: '女方信息', + male_name_placeholder: '請輸入男方姓名', + female_name_placeholder: '請輸入女方姓名', + male_name_required: '請輸入男方姓名', + female_name_required: '請輸入女方姓名', + male_birth_required: '請選擇男方出生日期', + female_birth_required: '請選擇女方出生日期', + start_match: '開始合婚分析', + + // 功能介紹 + intro_title: '八字合婚分析', + intro_subtitle: '傳統命理學結合AI智能,深度分析兩人婚姻匹配度', + feature_compatibility_title: '姻緣匹配', + feature_compatibility_desc: '分析雙方八字五行相生相克,評估婚姻契合度', + feature_analysis_title: '性格互補', + feature_analysis_desc: '深入解讀雙方性格特點,提供相處建議', + feature_suggest_title: '婚姻指導', + feature_suggest_desc: '提供婚姻生活建議,助力幸福美滿', + }, + compatibility: { + // 通用字段 + person1_placeholder: '請輸入姓名', + person2_placeholder: '請輸入姓名', + person1_name_required: '請輸入第一人姓名', + person2_name_required: '請輸入第二人姓名', + person1_birth_required: '請選擇第一人出生日期', + person2_birth_required: '請選擇第二人出生日期', + start_analysis: '開始合盤分析', + feature1_title: '關係分析', + feature1_desc: '深入分析雙方八字,評估關係和諧度', + feature2_title: 'AI解讀', + feature2_desc: '運用AI技術,提供專業的關係建議', + feature3_title: '相處建議', + feature3_desc: '提供實用的相處技巧,促進關係和諧', + career_title: '事業合盤', + career_subtitle: '分析事業夥伴關係,預測合作前景', + career_person1: '第一人信息', + career_person2: '第二人信息', + career_intro_title: '事業合作分析', + career_intro_subtitle: '基於八字命理,評估事業合作的成功概率', + mother_in_law_title: '婆媳合盤', + mother_in_law_subtitle: '分析婆媳關係,促進家庭和睦', + mother_in_law_person1: '婆婆信息', + mother_in_law_person2: '媳婦信息', + mother_in_law_intro_title: '婆媳關係分析', + mother_in_law_intro_subtitle: '深入了解雙方性格,提供和諧相處建議', + best_friends_title: '閨蜜合盤', + best_friends_subtitle: '分析友誼契合度,增進閨蜜感情', + best_friends_person1: '第一人信息', + best_friends_person2: '第二人信息', + best_friends_intro_title: '閨蜜關係分析', + best_friends_intro_subtitle: '了解性格互補性,打造長久友誼', + father_son_title: '父子關係', + father_son_subtitle: '分析父子互動模式,促進親子和諧', + father_son_person1: '父親信息', + father_son_person2: '兒子信息', + father_son_intro_title: '父子關係分析', + father_son_intro_subtitle: '深入了解代際差異,改善親子溝通', + mother_son_title: '母子關係', + mother_son_subtitle: '分析母子互動模式,增進親子感情', + mother_son_person1: '母親信息', + mother_son_person2: '兒子信息', + mother_son_intro_title: '母子關係分析', + mother_son_intro_subtitle: '理解性格差異,構建溫馨親子關係', + friends_title: '朋友關係', + friends_subtitle: '分析朋友契合度,維護友誼長久', + friends_person1: '第一人信息', + friends_person2: '第二人信息', + friends_intro_title: '朋友關係分析', + friends_intro_subtitle: '了解性格互補,建立真摯友誼', + boss_subordinate_title: '領導下屬關係', + boss_subordinate_subtitle: '分析上下級關係,促進工作和諧', + boss_subordinate_person1: '領導信息', + boss_subordinate_person2: '下屬信息', + boss_subordinate_intro_title: '上下級關係分析', + boss_subordinate_intro_subtitle: '了解管理風格與工作方式,提升團隊效率', + }, + common: { + submit: '提交', + reset: '重置', + pay: '支付', + free: '免費體驗', + language: '語言', + }, + home: { + title: '命運大師', + subtitle: '探索您的命運軌跡', + bazi_desc: '通過生辰八字,解析您的命運密碼', + career_desc: '事業運勢分析,助您事業騰飛', + marriage_desc: '姻緣測算,尋找您的真命天子', + tarot_desc: '塔羅占卜,揭示未來的秘密', + zodiac_desc: '星座運勢,每日運程早知道', + }, + }, + 'en-US': { + nav: { + home: 'Home', + bazi: 'BaZi Features', + bazi_analysis: 'BaZi Analysis', + daily_fortune: 'Daily Fortune', + bazi_marriage: 'Marriage Compatibility', + career_compatibility: 'Career Compatibility', + mother_in_law: 'Mother-in-Law Compatibility', + best_friends: 'Best Friends Compatibility', + father_son: 'Father-Son Relationship', + mother_son: 'Mother-Son Relationship', + friends: 'Friends Relationship', + boss_subordinate: 'Boss-Subordinate', + + divination: 'I Ching Divination', + plum_blossom: 'Plum Blossom · Daily Decision', + liuyao: 'Six Lines', + + tarot: 'Tarot', + tarot_reading: 'Tarot Reading', + tarot_meaning: 'Tarot Card Meanings', + + theory: 'Theory', + five_elements: 'Five Elements Theory', + ten_heavenly: 'Ten Heavenly Stems', + twelve_earthly: 'Twelve Earthly Branches', + sixty_jiazi: 'Sixty Jiazi', + nayin: 'Nayin Five Elements', + ten_gods: 'Ten Gods Theory', + spirits: 'Spirits Encyclopedia', + fortune_period: 'Fortune Period Theory', + fortune_timing: 'Fortune Timing Theory', + true_solar: 'True Solar Time', + child_hour: 'Child Hour Theory', + iching_64: 'I Ching 64 Hexagrams', + + tools: 'Tools', + ai_calendar: 'AI Almanac', + + // Legacy menu items + career: 'Career', + marriage: 'Marriage', + zodiac: 'Zodiac', + }, + bazi: { + // Page titles + page_title: 'BaZi Calculation', + page_subtitle: 'Accurate BaZi analysis to reveal your destiny', + + // Form fields + basic_info: 'Basic Information', + time_info: 'Time Information', + birth_place: 'Birth Place', + input_date: 'Date', + input_bazi: 'BaZi', + birth_date: 'Birth Date', + select_date: 'Select Date', + know_time: 'I know the birth time', + know_time_desc: 'You can skip if you don\'t know the exact birth time', + birth_hour: 'Birth Time', + hour: 'Hour', + minute: 'Minute', + place_placeholder: 'Search and select birth place', + place_tip: 'Please select detailed address for accurate coordinates', + use_early_child: 'Use early/late child hour', + start_calculation: 'Calculate BaZi', + + // BaZi Input + bazi_input: 'BaZi Input', + year_pillar: 'Year Pillar', + month_pillar: 'Month Pillar', + day_pillar: 'Day Pillar', + hour_pillar: 'Hour Pillar', + select_heavenly_stem: 'Select Heavenly Stem', + select_earthly_branch: 'Select Earthly Branch', + clear: 'Clear', + + // AI Analysis + ai_title: 'AI-Powered BaZi Analysis System', + ai_subtitle: 'Combining traditional Chinese astrology with modern technology for professional analysis', + feature_accurate_title: 'Accurate Chart', + feature_accurate_desc: 'Using astronomical data to ensure accurate BaZi calculations', + feature_ai_title: 'AI Interpretation', + feature_ai_desc: 'Utilizing AI technology to analyze Five Elements and cosmic relationships', + feature_scientific_title: 'Scientific & Objective', + feature_scientific_desc: 'Integrating big data analysis for objective and quantifiable insights', + + // Comprehensive Analysis + analysis_title: 'Comprehensive Destiny Analysis', + analysis_subtitle: 'In-depth analysis of various aspects to guide your life choices', + analysis_character_title: 'Personality Insights', + analysis_character_desc: 'Decode personality traits and hidden talents for personal growth', + analysis_career_title: 'Career Direction', + analysis_career_desc: 'Analyze career talents and opportunities for professional planning', + analysis_wealth_title: 'Wealth Fortune', + analysis_wealth_desc: 'Analyze wealth trends and financial tendencies for prosperity', + analysis_health_title: 'Health Fortune', + analysis_health_desc: 'Analyze physical constitution and health tendencies for wellness', + + // Guide + guide_title: 'User Guide', + guide_subtitle: 'Get your professional BaZi analysis report in 4 simple steps', + guide_step1_title: 'Enter Birth Info', + guide_step1_desc: 'Accurately input your birth information', + guide_step2_title: 'Select Gender', + guide_step2_desc: 'Fill in basic personal information', + guide_step3_title: 'Confirm Calendar', + guide_step3_desc: 'Choose solar or lunar calendar', + guide_step4_title: 'Get Report', + guide_step4_desc: 'Receive detailed analysis report', + + // Disclaimer + disclaimer: 'This service is for entertainment purposes only. Important decisions should be based on personal judgment and professional advice.', + }, + daily_fortune: { + // Page titles + page_title: 'Daily Fortune', + page_subtitle: 'Master your daily fortune and seize opportunities', + + // Form fields + birth_info: 'Birth Information', + check_fortune: 'Check Today\'s Fortune', + + // Features + intro_title: 'Daily Fortune Reading', + intro_subtitle: 'Accurate daily fortune predictions based on your BaZi', + feature_daily_title: 'Daily Updates', + feature_daily_desc: 'Fresh fortune analysis and advice updated daily', + feature_accurate_title: 'Accurate Prediction', + feature_accurate_desc: 'Precise fortune insights based on BaZi principles', + feature_guide_title: 'Life Guidance', + feature_guide_desc: 'Practical advice for work and life to attract fortune', + }, + marriage: { + // Page titles + page_title: 'Marriage Compatibility', + page_subtitle: 'Analyze BaZi compatibility and predict marriage harmony', + + // Form fields + male_info: 'Male Information', + female_info: 'Female Information', + male_name_placeholder: 'Enter male name', + female_name_placeholder: 'Enter female name', + male_name_required: 'Please enter male name', + female_name_required: 'Please enter female name', + male_birth_required: 'Please select male birth date', + female_birth_required: 'Please select female birth date', + start_match: 'Start Compatibility Analysis', + + // Features + intro_title: 'Marriage Compatibility Analysis', + intro_subtitle: 'Traditional Chinese astrology combined with AI for in-depth compatibility analysis', + feature_compatibility_title: 'Marriage Match', + feature_compatibility_desc: 'Analyze Five Elements compatibility and evaluate marriage harmony', + feature_analysis_title: 'Personality Complement', + feature_analysis_desc: 'Deep insights into personality traits and relationship advice', + feature_suggest_title: 'Marriage Guidance', + feature_suggest_desc: 'Practical advice for a happy and harmonious marriage', + }, + compatibility: { + person1_placeholder: 'Enter name', + person2_placeholder: 'Enter name', + person1_name_required: 'Please enter first person name', + person2_name_required: 'Please enter second person name', + person1_birth_required: 'Please select first person birth date', + person2_birth_required: 'Please select second person birth date', + start_analysis: 'Start Compatibility Analysis', + feature1_title: 'Relationship Analysis', + feature1_desc: 'Deep BaZi analysis to evaluate relationship harmony', + feature2_title: 'AI Insights', + feature2_desc: 'Professional relationship advice powered by AI', + feature3_title: 'Interaction Tips', + feature3_desc: 'Practical tips for harmonious relationships', + career_title: 'Career Compatibility', + career_subtitle: 'Analyze business partnership and predict collaboration success', + career_person1: 'First Person', + career_person2: 'Second Person', + career_intro_title: 'Business Partnership Analysis', + career_intro_subtitle: 'BaZi-based evaluation of business collaboration success', + mother_in_law_title: 'Mother-in-Law Compatibility', + mother_in_law_subtitle: 'Analyze mother-in-law relationship for family harmony', + mother_in_law_person1: 'Mother-in-Law', + mother_in_law_person2: 'Daughter-in-Law', + mother_in_law_intro_title: 'Mother-in-Law Relationship Analysis', + mother_in_law_intro_subtitle: 'Understand personalities for harmonious coexistence', + best_friends_title: 'Best Friends Compatibility', + best_friends_subtitle: 'Analyze friendship compatibility to strengthen bonds', + best_friends_person1: 'First Friend', + best_friends_person2: 'Second Friend', + best_friends_intro_title: 'Best Friends Analysis', + best_friends_intro_subtitle: 'Understand personality complementarity for lasting friendship', + father_son_title: 'Father-Son Relationship', + father_son_subtitle: 'Analyze father-son dynamics for family harmony', + father_son_person1: 'Father', + father_son_person2: 'Son', + father_son_intro_title: 'Father-Son Relationship Analysis', + father_son_intro_subtitle: 'Understand generational differences to improve communication', + mother_son_title: 'Mother-Son Relationship', + mother_son_subtitle: 'Analyze mother-son dynamics to strengthen bonds', + mother_son_person1: 'Mother', + mother_son_person2: 'Son', + mother_son_intro_title: 'Mother-Son Relationship Analysis', + mother_son_intro_subtitle: 'Understand personality differences for warm family ties', + friends_title: 'Friends Relationship', + friends_subtitle: 'Analyze friendship compatibility for lasting bonds', + friends_person1: 'First Friend', + friends_person2: 'Second Friend', + friends_intro_title: 'Friends Relationship Analysis', + friends_intro_subtitle: 'Understand complementarity to build genuine friendship', + boss_subordinate_title: 'Boss-Subordinate Relationship', + boss_subordinate_subtitle: 'Analyze workplace hierarchy for work harmony', + boss_subordinate_person1: 'Boss', + boss_subordinate_person2: 'Subordinate', + boss_subordinate_intro_title: 'Boss-Subordinate Analysis', + boss_subordinate_intro_subtitle: 'Understand management styles to improve team efficiency', + }, + common: { + submit: 'Submit', + reset: 'Reset', + pay: 'Pay', + free: 'Free Trial', + language: 'Language', + }, + home: { + title: 'FateMaster', + subtitle: 'Explore Your Destiny', + bazi_desc: 'Decode your destiny through BaZi analysis', + career_desc: 'Career fortune analysis to boost your success', + marriage_desc: 'Find your soulmate through divination', + tarot_desc: 'Tarot reading reveals future secrets', + zodiac_desc: 'Daily horoscope and zodiac insights', + }, + }, + 'ja-JP': { + nav: { + home: 'ホーム', + bazi: '八字機能', + bazi_analysis: '八字分析', + daily_fortune: '毎日の運勢', + bazi_marriage: '八字相性', + career_compatibility: '仕事相性', + mother_in_law: '姑との相性', + best_friends: '親友相性', + father_son: '父子関係', + mother_son: '母子関係', + friends: '友達関係', + boss_subordinate: '上司部下', + + divination: '周易占い', + plum_blossom: '梅花易数・毎日の決断', + liuyao: '六爻', + + tarot: 'タロット', + tarot_reading: 'タロット占い', + tarot_meaning: 'タロットカード意味', + + theory: '理論知識', + five_elements: '五行理論', + ten_heavenly: '十天干理論', + twelve_earthly: '十二地支理論', + sixty_jiazi: '六十甲子理論', + nayin: '納音五行理論', + ten_gods: '十神理論', + spirits: '神煞大全', + fortune_period: '大運理論', + fortune_timing: '大運起運時間理論', + true_solar: '真太陽時理論', + child_hour: '早晚子時理論', + iching_64: '易経64卦', + + tools: '実用ツール', + ai_calendar: 'AI黄暦', + + // レガシーメニュー項目 + career: 'キャリア', + marriage: '結婚', + zodiac: '星座', + }, + bazi: { + // ページタイトル + page_title: '八字計算', + page_subtitle: '生年月日時を正確に分析し、運命を明らかに', + + // フォームフィールド + basic_info: '基本情報', + time_info: '時間情報', + birth_place: '出生地', + input_date: '日付', + input_bazi: '八字', + birth_date: '生年月日', + select_date: '日付を選択', + know_time: '出生時間を知っている', + know_time_desc: '正確な出生時間がわからない場合はスキップできます', + birth_hour: '出生時間', + hour: '時', + minute: '分', + place_placeholder: '出生地を検索して選択', + place_tip: '正確な座標を得るために詳細な住所を選択してください', + use_early_child: '早晩子時を使用', + start_calculation: '八字を計算', + + // 八字入力 + bazi_input: '八字入力', + year_pillar: '年柱', + month_pillar: '月柱', + day_pillar: '日柱', + hour_pillar: '時柱', + select_heavenly_stem: '天干を選択', + select_earthly_branch: '地支を選択', + clear: 'クリア', + + // AI分析 + ai_title: 'AI八字分析システム', + ai_subtitle: '伝統的な命理学と現代技術を組み合わせた専門的な分析サービス', + feature_accurate_title: '正確な命盤', + feature_accurate_desc: '天文データを使用して正確な八字計算を保証', + feature_ai_title: 'AI解読', + feature_ai_desc: 'AI技術を活用して五行属性と宇宙の関係を分析', + feature_scientific_title: '科学的・客観的', + feature_scientific_desc: 'ビッグデータ分析を統合し、客観的で定量化可能な洞察を提供', + + // 総合分析 + analysis_title: '総合運命分析', + analysis_subtitle: 'さまざまな側面を深く分析し、人生の選択をガイド', + analysis_character_title: '性格洞察', + analysis_character_desc: '性格特性と隠れた才能を解読し、個人的成長を支援', + analysis_career_title: 'キャリア方向', + analysis_career_desc: 'キャリアの才能と機会を分析し、専門的な計画を支援', + analysis_wealth_title: '財運', + analysis_wealth_desc: '財運の傾向と金融傾向を分析し、繁栄を支援', + analysis_health_title: '健康運', + analysis_health_desc: '体質と健康傾向を分析し、ウェルネスを支援', + + // ガイド + guide_title: '使用ガイド', + guide_subtitle: '4つの簡単なステップで専門的な八字分析レポートを入手', + guide_step1_title: '出生情報を入力', + guide_step1_desc: '正確に出生情報を入力', + guide_step2_title: '性別を選択', + guide_step2_desc: '基本的な個人情報を入力', + guide_step3_title: 'カレンダーを確認', + guide_step3_desc: '太陽暦または旧暦を選択', + guide_step4_title: 'レポートを取得', + guide_step4_desc: '詳細な分析レポートを受信', + + // 免責事項 + disclaimer: 'このサービスは娯楽目的のみです。重要な決定は個人の判断と専門的なアドバイスに基づいて行ってください。', + }, + daily_fortune: { + // ページタイトル + page_title: '毎日の運勢', + page_subtitle: '今日の運勢を把握し、幸運のチャンスをつかむ', + + // フォームフィールド + birth_info: '出生情報', + check_fortune: '今日の運勢を確認', + + // 機能紹介 + intro_title: '毎日の運勢占い', + intro_subtitle: '八字に基づいた正確な毎日の運勢予測', + feature_daily_title: '毎日更新', + feature_daily_desc: '毎日最新の運勢分析とアドバイスを提供', + feature_accurate_title: '正確な予測', + feature_accurate_desc: '八字命理に基づいた正確な運勢把握', + feature_guide_title: '生活ガイダンス', + feature_guide_desc: '仕事や生活に関する具体的なアドバイスで幸運を引き寄せる', + }, + marriage: { + // ページタイトル + page_title: '八字相性診断', + page_subtitle: '二人の八字の相性を分析し、結婚の幸福度を予測', + + // フォームフィールド + male_info: '男性情報', + female_info: '女性情報', + male_name_placeholder: '男性の名前を入力', + female_name_placeholder: '女性の名前を入力', + male_name_required: '男性の名前を入力してください', + female_name_required: '女性の名前を入力してください', + male_birth_required: '男性の生年月日を選択してください', + female_birth_required: '女性の生年月日を選択してください', + start_match: '相性分析を開始', + + // 機能紹介 + intro_title: '結婚相性分析', + intro_subtitle: '伝統的な命理学とAI技術を組み合わせた深い相性分析', + feature_compatibility_title: '相性マッチング', + feature_compatibility_desc: '五行の相性を分析し、結婚の調和度を評価', + feature_analysis_title: '性格の相補性', + feature_analysis_desc: '性格特性を深く解読し、関係アドバイスを提供', + feature_suggest_title: '結婚ガイダンス', + feature_suggest_desc: '幸せで調和のとれた結婚生活のための実用的なアドバイス', + }, + compatibility: { + person1_placeholder: '名前を入力', + person2_placeholder: '名前を入力', + person1_name_required: '第一人の名前を入力してください', + person2_name_required: '第二人の名前を入力してください', + person1_birth_required: '第一人の生年月日を選択してください', + person2_birth_required: '第二人の生年月日を選択してください', + start_analysis: '相性分析を開始', + feature1_title: '関係分析', + feature1_desc: '八字を深く分析し、関係の調和度を評価', + feature2_title: 'AI洞察', + feature2_desc: 'AIによる専門的な関係アドバイス', + feature3_title: '交流のヒント', + feature3_desc: '調和のとれた関係のための実用的なヒント', + career_title: 'ビジネス相性', + career_subtitle: 'ビジネスパートナーシップを分析し、協力の成功を予測', + career_person1: '第一人', + career_person2: '第二人', + career_intro_title: 'ビジネスパートナーシップ分析', + career_intro_subtitle: '八字に基づくビジネス協力成功の評価', + mother_in_law_title: '姑との相性', + mother_in_law_subtitle: '姑との関係を分析し、家族の調和を促進', + mother_in_law_person1: '姑', + mother_in_law_person2: '嫁', + mother_in_law_intro_title: '姑との関係分析', + mother_in_law_intro_subtitle: '性格を理解し、調和のとれた共存のために', + best_friends_title: '親友相性', + best_friends_subtitle: '友情の相性を分析し、絆を強化', + best_friends_person1: '第一人', + best_friends_person2: '第二人', + best_friends_intro_title: '親友分析', + best_friends_intro_subtitle: '性格の相補性を理解し、長続きする友情のために', + father_son_title: '父子関係', + father_son_subtitle: '父子のダイナミクスを分析し、家族の調和を促進', + father_son_person1: '父親', + father_son_person2: '息子', + father_son_intro_title: '父子関係分析', + father_son_intro_subtitle: '世代間の違いを理解し、コミュニケーションを改善', + mother_son_title: '母子関係', + mother_son_subtitle: '母子のダイナミクスを分析し、絆を強化', + mother_son_person1: '母親', + mother_son_person2: '息子', + mother_son_intro_title: '母子関係分析', + mother_son_intro_subtitle: '性格の違いを理解し、温かい家族関係のために', + friends_title: '友人関係', + friends_subtitle: '友情の相性を分析し、長続きする絆のために', + friends_person1: '第一人', + friends_person2: '第二人', + friends_intro_title: '友人関係分析', + friends_intro_subtitle: '相補性を理解し、真の友情を築く', + boss_subordinate_title: '上司部下関係', + boss_subordinate_subtitle: '職場の階層を分析し、仕事の調和を促進', + boss_subordinate_person1: '上司', + boss_subordinate_person2: '部下', + boss_subordinate_intro_title: '上司部下分析', + boss_subordinate_intro_subtitle: '管理スタイルを理解し、チーム効率を向上', + }, + common: { + submit: '送信', + reset: 'リセット', + pay: '支払い', + free: '無料体験', + language: '言語', + }, + home: { + title: 'フェイトマスター', + subtitle: 'あなたの運命を探る', + bazi_desc: '八字であなたの運命を解読', + career_desc: 'キャリア運勢分析でキャリアアップ', + marriage_desc: '運命の人を見つける占い', + tarot_desc: 'タロット占いで未来を明らかに', + zodiac_desc: '毎日の星座占いと運勢', + }, + }, +} + +const i18n = createI18n({ + legacy: false, + locale: localStorage.getItem('locale') || 'zh-CN', + fallbackLocale: 'zh-CN', + messages, +}) + +export default i18n diff --git a/frontend/fatemaster-web/src/layouts/MainLayout.vue b/frontend/fatemaster-web/src/layouts/MainLayout.vue new file mode 100644 index 0000000..a5aba22 --- /dev/null +++ b/frontend/fatemaster-web/src/layouts/MainLayout.vue @@ -0,0 +1,605 @@ + + + + + diff --git a/frontend/fatemaster-web/src/main.ts b/frontend/fatemaster-web/src/main.ts new file mode 100644 index 0000000..0724c98 --- /dev/null +++ b/frontend/fatemaster-web/src/main.ts @@ -0,0 +1,18 @@ +import { createApp } from 'vue' +import { createPinia } from 'pinia' +import Antd from 'ant-design-vue' +import router from './router' +import i18n from './i18n' +import App from './App.vue' +import 'ant-design-vue/dist/reset.css' +import './style.css' + +const app = createApp(App) +const pinia = createPinia() + +app.use(pinia) +app.use(router) +app.use(i18n) +app.use(Antd) + +app.mount('#app') diff --git a/frontend/fatemaster-web/src/router/index.ts b/frontend/fatemaster-web/src/router/index.ts new file mode 100644 index 0000000..82d988f --- /dev/null +++ b/frontend/fatemaster-web/src/router/index.ts @@ -0,0 +1,185 @@ +import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router' +import Layout from '@/layouts/MainLayout.vue' + +const routes: RouteRecordRaw[] = [ + { + path: '/', + component: Layout, + children: [ + { + path: '', + name: 'Home', + component: () => import('@/views/Home.vue'), + }, + // 旧路由(保持兼容) + { + path: 'bazi', + name: 'BaZi', + component: () => import('@/views/divination/BaZi.vue'), + }, + { + path: 'career', + name: 'Career', + component: () => import('@/views/divination/Career.vue'), + }, + { + path: 'marriage', + name: 'Marriage', + component: () => import('@/views/divination/Marriage.vue'), + }, + { + path: 'tarot', + name: 'Tarot', + component: () => import('@/views/divination/Tarot.vue'), + }, + { + path: 'zodiac', + name: 'Zodiac', + component: () => import('@/views/divination/Zodiac.vue'), + }, + { + path: 'result/:id', + name: 'Result', + component: () => import('@/views/Result.vue'), + }, + + // 八字功能 - 重定向到现有的 BaZi 页面 + { + path: 'bazi/analysis', + name: 'BaZiAnalysis', + component: () => import('@/views/bazi/Analysis.vue'), + }, + { + path: 'bazi/daily-fortune', + name: 'DailyFortune', + component: () => import('@/views/bazi/DailyFortune.vue'), + }, + { + path: 'bazi/marriage', + name: 'BaZiMarriage', + component: () => import('@/views/bazi/Marriage.vue'), + }, + { + path: 'bazi/career-compatibility', + name: 'CareerCompatibility', + component: () => import('@/views/bazi/CareerCompatibility.vue'), + }, + { + path: 'bazi/mother-in-law', + name: 'MotherInLaw', + component: () => import('@/views/bazi/MotherInLaw.vue'), + }, + { + path: 'bazi/best-friends', + name: 'BestFriends', + component: () => import('@/views/bazi/BestFriends.vue'), + }, + { + path: 'bazi/father-son', + name: 'FatherSon', + component: () => import('@/views/bazi/FatherSon.vue'), + }, + { + path: 'bazi/mother-son', + name: 'MotherSon', + component: () => import('@/views/bazi/MotherSon.vue'), + }, + { + path: 'bazi/friends', + name: 'Friends', + component: () => import('@/views/bazi/Friends.vue'), + }, + { + path: 'bazi/boss-subordinate', + name: 'BossSubordinate', + component: () => import('@/views/bazi/BossSubordinate.vue'), + }, + + // 周易占卜 + { + path: 'divination/plum-blossom', + name: 'PlumBlossom', + component: () => import('@/views/divination/PlumBlossom.vue'), + }, + { + path: 'divination/liuyao', + name: 'Liuyao', + component: () => import('@/views/divination/Liuyao.vue'), + }, + + // 塔罗牌 + { + path: 'tarot/reading', + name: 'TarotReading', + component: () => import('@/views/tarot/TarotReading.vue'), + }, + { + path: 'tarot/meaning', + redirect: '/tarot', + }, + + // 理论知识 - 重定向到首页 + { + path: 'theory/five-elements', + redirect: '/', + }, + { + path: 'theory/ten-heavenly', + redirect: '/', + }, + { + path: 'theory/twelve-earthly', + redirect: '/', + }, + { + path: 'theory/sixty-jiazi', + redirect: '/', + }, + { + path: 'theory/nayin', + redirect: '/', + }, + { + path: 'theory/ten-gods', + redirect: '/', + }, + { + path: 'theory/spirits', + redirect: '/', + }, + { + path: 'theory/fortune-period', + redirect: '/', + }, + { + path: 'theory/fortune-timing', + redirect: '/', + }, + { + path: 'theory/true-solar', + redirect: '/', + }, + { + path: 'theory/child-hour', + redirect: '/', + }, + { + path: 'theory/iching-64', + redirect: '/', + }, + + // 实用工具 - 重定向到首页 + { + path: 'tools/ai-calendar', + redirect: '/', + }, + ], + }, +] + +const router = createRouter({ + history: createWebHistory(), + routes, +}) + +export default router diff --git a/frontend/fatemaster-web/src/style.css b/frontend/fatemaster-web/src/style.css new file mode 100644 index 0000000..d80b044 --- /dev/null +++ b/frontend/fatemaster-web/src/style.css @@ -0,0 +1,17 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +#app { + min-height: 100vh; +} diff --git a/frontend/fatemaster-web/src/views/Home.vue b/frontend/fatemaster-web/src/views/Home.vue new file mode 100644 index 0000000..5b510da --- /dev/null +++ b/frontend/fatemaster-web/src/views/Home.vue @@ -0,0 +1,340 @@ + + + + + diff --git a/frontend/fatemaster-web/src/views/Result.vue b/frontend/fatemaster-web/src/views/Result.vue new file mode 100644 index 0000000..0c365f6 --- /dev/null +++ b/frontend/fatemaster-web/src/views/Result.vue @@ -0,0 +1,48 @@ + + + + + diff --git a/frontend/fatemaster-web/src/views/bazi/Analysis.vue b/frontend/fatemaster-web/src/views/bazi/Analysis.vue new file mode 100644 index 0000000..d58c224 --- /dev/null +++ b/frontend/fatemaster-web/src/views/bazi/Analysis.vue @@ -0,0 +1,1014 @@ + + + + + diff --git a/frontend/fatemaster-web/src/views/bazi/BestFriends.vue b/frontend/fatemaster-web/src/views/bazi/BestFriends.vue new file mode 100644 index 0000000..306fab4 --- /dev/null +++ b/frontend/fatemaster-web/src/views/bazi/BestFriends.vue @@ -0,0 +1,7 @@ + + + diff --git a/frontend/fatemaster-web/src/views/bazi/BossSubordinate.vue b/frontend/fatemaster-web/src/views/bazi/BossSubordinate.vue new file mode 100644 index 0000000..798b7ba --- /dev/null +++ b/frontend/fatemaster-web/src/views/bazi/BossSubordinate.vue @@ -0,0 +1,7 @@ + + + diff --git a/frontend/fatemaster-web/src/views/bazi/CareerCompatibility.vue b/frontend/fatemaster-web/src/views/bazi/CareerCompatibility.vue new file mode 100644 index 0000000..c49318d --- /dev/null +++ b/frontend/fatemaster-web/src/views/bazi/CareerCompatibility.vue @@ -0,0 +1,7 @@ + + + diff --git a/frontend/fatemaster-web/src/views/bazi/DailyFortune.vue b/frontend/fatemaster-web/src/views/bazi/DailyFortune.vue new file mode 100644 index 0000000..9c8fa26 --- /dev/null +++ b/frontend/fatemaster-web/src/views/bazi/DailyFortune.vue @@ -0,0 +1,331 @@ + + + + + diff --git a/frontend/fatemaster-web/src/views/bazi/FatherSon.vue b/frontend/fatemaster-web/src/views/bazi/FatherSon.vue new file mode 100644 index 0000000..7b92ab9 --- /dev/null +++ b/frontend/fatemaster-web/src/views/bazi/FatherSon.vue @@ -0,0 +1,7 @@ + + + diff --git a/frontend/fatemaster-web/src/views/bazi/Friends.vue b/frontend/fatemaster-web/src/views/bazi/Friends.vue new file mode 100644 index 0000000..b3557c6 --- /dev/null +++ b/frontend/fatemaster-web/src/views/bazi/Friends.vue @@ -0,0 +1,7 @@ + + + diff --git a/frontend/fatemaster-web/src/views/bazi/Marriage.vue b/frontend/fatemaster-web/src/views/bazi/Marriage.vue new file mode 100644 index 0000000..3b9dedf --- /dev/null +++ b/frontend/fatemaster-web/src/views/bazi/Marriage.vue @@ -0,0 +1,415 @@ + + + + + diff --git a/frontend/fatemaster-web/src/views/bazi/MotherInLaw.vue b/frontend/fatemaster-web/src/views/bazi/MotherInLaw.vue new file mode 100644 index 0000000..ec3e579 --- /dev/null +++ b/frontend/fatemaster-web/src/views/bazi/MotherInLaw.vue @@ -0,0 +1,7 @@ + + + diff --git a/frontend/fatemaster-web/src/views/bazi/MotherSon.vue b/frontend/fatemaster-web/src/views/bazi/MotherSon.vue new file mode 100644 index 0000000..f49b8a8 --- /dev/null +++ b/frontend/fatemaster-web/src/views/bazi/MotherSon.vue @@ -0,0 +1,7 @@ + + + diff --git a/frontend/fatemaster-web/src/views/divination/BaZi.vue b/frontend/fatemaster-web/src/views/divination/BaZi.vue new file mode 100644 index 0000000..5b796e1 --- /dev/null +++ b/frontend/fatemaster-web/src/views/divination/BaZi.vue @@ -0,0 +1,342 @@ + + + + + diff --git a/frontend/fatemaster-web/src/views/divination/Career.vue b/frontend/fatemaster-web/src/views/divination/Career.vue new file mode 100644 index 0000000..97224bb --- /dev/null +++ b/frontend/fatemaster-web/src/views/divination/Career.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/frontend/fatemaster-web/src/views/divination/Liuyao.vue b/frontend/fatemaster-web/src/views/divination/Liuyao.vue new file mode 100644 index 0000000..a97acb7 --- /dev/null +++ b/frontend/fatemaster-web/src/views/divination/Liuyao.vue @@ -0,0 +1,408 @@ + + + + + diff --git a/frontend/fatemaster-web/src/views/divination/Marriage.vue b/frontend/fatemaster-web/src/views/divination/Marriage.vue new file mode 100644 index 0000000..9655445 --- /dev/null +++ b/frontend/fatemaster-web/src/views/divination/Marriage.vue @@ -0,0 +1,49 @@ + + + + + diff --git a/frontend/fatemaster-web/src/views/divination/PlumBlossom.vue b/frontend/fatemaster-web/src/views/divination/PlumBlossom.vue new file mode 100644 index 0000000..a4151ef --- /dev/null +++ b/frontend/fatemaster-web/src/views/divination/PlumBlossom.vue @@ -0,0 +1,347 @@ + + + + + diff --git a/frontend/fatemaster-web/src/views/divination/Tarot.vue b/frontend/fatemaster-web/src/views/divination/Tarot.vue new file mode 100644 index 0000000..46337b7 --- /dev/null +++ b/frontend/fatemaster-web/src/views/divination/Tarot.vue @@ -0,0 +1,106 @@ + + + + + diff --git a/frontend/fatemaster-web/src/views/divination/Zodiac.vue b/frontend/fatemaster-web/src/views/divination/Zodiac.vue new file mode 100644 index 0000000..4f5b298 --- /dev/null +++ b/frontend/fatemaster-web/src/views/divination/Zodiac.vue @@ -0,0 +1,59 @@ + + + + + diff --git a/frontend/fatemaster-web/src/views/tarot/TarotReading.vue b/frontend/fatemaster-web/src/views/tarot/TarotReading.vue new file mode 100644 index 0000000..9a32064 --- /dev/null +++ b/frontend/fatemaster-web/src/views/tarot/TarotReading.vue @@ -0,0 +1,111 @@ + + + + + diff --git a/frontend/fatemaster-web/tsconfig.json b/frontend/fatemaster-web/tsconfig.json new file mode 100644 index 0000000..63cf416 --- /dev/null +++ b/frontend/fatemaster-web/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "preserve", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/frontend/fatemaster-web/tsconfig.node.json b/frontend/fatemaster-web/tsconfig.node.json new file mode 100644 index 0000000..42872c5 --- /dev/null +++ b/frontend/fatemaster-web/tsconfig.node.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/frontend/fatemaster-web/vite.config.ts b/frontend/fatemaster-web/vite.config.ts new file mode 100644 index 0000000..75636ba --- /dev/null +++ b/frontend/fatemaster-web/vite.config.ts @@ -0,0 +1,21 @@ +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' +import path from 'path' + +export default defineConfig({ + plugins: [vue()], + resolve: { + alias: { + '@': path.resolve(__dirname, './src'), + }, + }, + server: { + port: 3000, + proxy: { + '/api': { + target: 'http://localhost:5000', + changeOrigin: true, + }, + }, + }, +})