2025-04-16-網站從零開始到能跑起來的明確逐步作法 從零開始到能跑起來的明確逐步作法 釐清成一個可跟做的清單(以 Windows 為主力開發機 / 使用 C# (ASP.NET Core) 為預設後端 ,並同時給你 Python(FastAPI) 的快速替代路徑備選)。每一步都包含必需的指令、檔案或範例內容,你照著做就能把整個「Vue 前端 + 後端 API + MySQL + AI proxy」MVP 拉起來並互通。
我把流程分成三大階段:準備環境 → 建立資料庫與後端 → 建立前端並整合 AI。每一步都有可直接貼上的指令或檔案範例。
一覽(高層)
設環境:Windows 安裝必要工具(Node、.NET、Docker、VS Code、Git)
建 MySQL(用 Docker)並建立資料表 seed 資料
Scaffold 後端(C# ASP.NET Core )含 AI proxy endpoint 與 DB 連線(若你要 Python,我也附 FastAPI 快速替代)
Scaffold 前端(Vue 3 + Vite),設定 proxy 呼叫後端
本機測試:啟動 DB → 後端 → 前端;測 AI endpoint,確認能拿到回應
下一步(選項):加入認證、部署到雲、監控、備份
詳細步驟(請在 Windows 主力機上操作;PowerShell 為例) 第 0 節:先決條件(如果你已經裝好可跳過)
Visual Studio 2022 或 .NET SDK(建議 .NET 7/8 LTS) 下載並安裝 .NET SDK:https://dotnet.microsoft.com (或用 Visual Studio Installer)
Node.js (LTS) 已安裝(你已完成)
Docker Desktop 已安裝並啟用(啟用 WSL2 integration 建議)
VS Code 已安裝(推薦安裝 Volar、C#、Docker、ESLint 等擴充)
Git 已安裝,並設定 SSH key 加到 GitHub
1. 建專案目錄結構(在你想放的位置) 1 2 3 4 5 6 mkdir psych-site cd psych-site mkdir frontend backend infra
2. 用 Docker 在 Windows 建 MySQL(開發用) 在 psych-site/infra 建 docker-compose.yml(可直接複製):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 version: "3.8" services: mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: RootPwd123! MYSQL_DATABASE: psychdb MYSQL_USER: appuser MYSQL_PASSWORD: AppUserPwd123! ports: - "3306:3306" volumes: - mysql_data:/var/lib/mysql healthcheck: test: ["CMD" , "mysqladmin" , "ping" , "-pRootPwd123!" ] interval: 10s retries: 5 phpmyadmin: image: phpmyadmin/phpmyadmin environment: PMA_HOST: mysql PMA_USER: root PMA_PASSWORD: RootPwd123! ports: - "8080:80" depends_on: - mysql volumes: mysql_data:
啟動:
1 2 3 4 cd infradocker compose up -d docker ps
注意 :本機開發用密碼示範,實務請用更強密碼且不要放 repo。
3. 建資料表(用 SQL seed) 在 infra 下建立檔案 init_seed.sql(或用 phpMyAdmin 匯入):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 USE psychdb; CREATE TABLE IF NOT EXISTS readings ( id BIGINT PRIMARY KEY AUTO_INCREMENT, title VARCHAR (200 ), category VARCHAR (80 ), text TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS history ( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id BIGINT NULL , reading_id BIGINT NULL , custom_text TEXT, picked_at DATETIME, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); INSERT INTO readings (title, category, text) VALUES ('暖心小語' ,'心情' ,'今天給自己一個微笑,你比想像中堅強。' ), ('職場提醒' ,'工作' ,'用小步快跑的方式完成大目標,別怕分段執行。' ), ('情感共鳴' ,'情感' ,'說出你的感受,也許會帶來意外的理解。' ), ('小挑戰' ,'成長' ,'嘗試 10 分鐘的新習慣,給自己驚喜。' );
匯入方式:
1 2 3 docker exec -i $ (docker ps -q -f name=psych-site_infra_mysql ) mysql -uroot -pRootPwd123 ! psychdb < init_seed.sql
(或用 phpMyAdmin 匯入 SQL)
4. 建後端:C# ASP.NET Core Web API (主要範例) 4.1 scaffold 專案 1 2 3 cd ..\backenddotnet new webapi -n psych.backend cd psych.backend
4.2 安裝必要套件(EF Core + MySQL provider) 1 2 3 dotnet add package Pomelo.EntityFrameworkCore.MySql --version 6.0 .0 dotnet add package Microsoft.EntityFrameworkCore.Design dotnet tool install --global dotnet-ef
4.3 修改 appsettings.Development.json(加入 DB 連線) 在 appsettings.Development.json 加入:
1 2 3 4 5 { "ConnectionStrings" : { "DefaultConnection" : "server=localhost;port=3306;database=psychdb;user=appuser;password=AppUserPwd123!" } }
4.4 建 DbContext 與 Model(簡短範例) 在 Models/Reading.cs:
1 2 3 4 5 6 7 public class Reading { public long Id { get ; set ; } public string Title { get ; set ; } public string Category { get ; set ; } public string Text { get ; set ; } public DateTime CreatedAt { get ; set ; } }
在 Data/AppDbContext.cs:
1 2 3 4 5 6 using Microsoft.EntityFrameworkCore;public class AppDbContext : DbContext { public AppDbContext (DbContextOptions<AppDbContext> options ) : base (options ) {} public DbSet<Reading> Readings { get ; set ; } public DbSet<HistoryItem> History { get ; set ; } }
在 Program.cs 註冊:
1 2 3 4 5 6 7 8 9 var builder = WebApplication.CreateBuilder(args);builder.Services.AddDbContext<AppDbContext>(options => options.UseMySql(builder.Configuration.GetConnectionString("DefaultConnection" ), ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("DefaultConnection" )))); builder.Services.AddControllers(); builder.Services.AddCors(options => options.AddDefaultPolicy(pb => pb.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod())); var app = builder.Build();app.MapControllers(); app.Run();
4.5 建簡單 Controller(Readings & AI proxy) Controllers/ReadingsController.cs(簡潔示範):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [ApiController ] [Route("api/[controller]" ) ] public class ReadingsController : ControllerBase { private readonly AppDbContext _db; public ReadingsController (AppDbContext db ) { _db = db; } [HttpGet ] public async Task<IActionResult> Get () => Ok(await _db.Readings.ToListAsync()); [HttpGet("random" ) ] public async Task<IActionResult> Random () { var list = await _db.Readings.ToListAsync(); var item = list[new Random().Next(list.Count)]; return Ok(item); } }
Controllers/AiController.cs(AI proxy 範例,需在環境變數放 API KEY):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 [ApiController ] [Route("api/ai" ) ] public class AiController : ControllerBase { private readonly IHttpClientFactory _http; private readonly IConfiguration _config; public AiController (IHttpClientFactory http, IConfiguration config ) { _http = http; _config = config; } [HttpPost("read" ) ] public async Task<IActionResult> Read ([FromBody] AiRequest req ) { if (!string .IsNullOrEmpty(req.Prompt) && req.Prompt.Contains("自殺" )) { return BadRequest(new { error = "偵測到危險文字,請求助專業機構" }); } var client = _http.CreateClient(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer" , _config["AI_API_KEY" ]); var payload = new { model = "gpt-like" , input = $"請用溫柔語氣回覆:{req.Prompt} " , max_tokens = 200 }; var resp = await client.PostAsJsonAsync(_config["AI_API_URL" ], payload); if (!resp.IsSuccessStatusCode) return StatusCode(502 , "AI provider error" ); var j = await resp.Content.ReadFromJsonAsync<JsonElement>(); var text = j.GetProperty("choices" )[0 ].GetProperty("text" ).GetString(); return Ok(new { text = text.Trim() }); } }
将你的 AI_API_KEY、AI_API_URL 放在 Windows environment variable 或 secrets。不要放到前端。
4.6 建 DB migration 並執行 1 2 dotnet ef migrations add InitialCreate dotnet ef database update
4.7 執行後端
5. 建後端:Python FastAPI (如果你未來想用 Python 快速試 AI) 快速 scaffold(備選):
1 2 3 4 cd ..\backendpython -m venv venv venv\Scripts\activate pip install fastapi uvicorn sqlalchemy pymysql httpx python-dotenv
main.py 提供 /api/ai/read 與 /api/readings;使用 httpx 呼叫 AI provider;DB 用 SQLAlchemy 連 mysql+pymysql://appuser:AppUserPwd123!@localhost:3306/psychdb。
6. 建前端:Vue 3 + Vite(在 frontend) 1 2 3 cd ..\frontendnpm create vite@latest . -- --template vue npm install
在 vite.config.js 加 proxy,讓開發時呼叫 /api 轉到後端(以 C# 為例):
1 2 3 4 5 6 7 8 9 10 import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' export default defineConfig ({ plugins : [vue ()], server : { proxy : { '/api' : 'http://localhost:5000' } } })
把之前提供給你的 App.vue(純前端版本)貼到 src/App.vue,但將 getReading() 改為呼叫後端 AI 或 readings:
呼叫本地 /api/readings 或 /api/ai/read(視你要哪個)
示例呼叫 AI(前端):
1 2 3 4 5 6 const res = await fetch ('/api/ai/read' , { method : 'POST' , headers : { 'Content-Type' : 'application/json' }, body : JSON .stringify ({ prompt : promptText }) }); const json = await res.json ();
啟動前端:
7. 本機測試順序(非常重要)
docker compose up -d (infra/mysql) → 等 mysql ready
在 backend 專案執行 dotnet run(或 uvicorn main:app --reload for FastAPI)
在 frontend 執行 npm run dev
用瀏覽器開 http://localhost:5173 測 UI;或直接呼叫 http://localhost:5000/api/readings 測後端
8. AI Key 與安全(必做)
在 Windows 設環境變數(PowerShell):
1 2 3 setx AI_API_KEY "你的_api_key" setx AI_API_URL "https://api.yourprovider/v1/generate"
後端只讀 env 的值,不寫在程式碼中。
加速測試可先用 mock 回應,再接真實 provider。
在後端實作「簡易敏感詞過濾」及速率限制(ASP.NET 可用 middleware 或套件)。
9. Dockerize 後端(快速 build & run) 在 backend/psych.backend 建 Dockerfile:
1 2 3 4 5 6 7 8 9 10 11 12 13 FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS baseWORKDIR /app EXPOSE 80 FROM mcr.microsoft.com/dotnet/sdk:7.0 AS buildWORKDIR /src COPY . . RUN dotnet publish -c Release -o /app/publish FROM base AS finalWORKDIR /app COPY --from=build /app/publish . ENTRYPOINT ["dotnet" ,"psych.backend.dll" ]
建 image & run(示例):
1 2 docker build -t psych-backend :latest . docker run -d -p 5000 :80 --name psych-backend --env AI_API_KEY=... psych-backend :latest
10. 後續建議(短期 & 長期) 短期(先做 MVP):
完成前端抽小語 / 新增小語 / 歷史儲存(DB)
做 AI proxy endpoint 並測試(把 prompt 邏輯寫在後端)
加速限制與簡易 moderation
長期(上線):
把 DB 移到雲端 Managed DB(RDS / Azure Database)
實作 JWT 認證、使用者系統
加監控(Application Insights / Prometheus)與 log(Serilog)
部署:Docker Compose / Kubernetes 或雲端 PaaS(Azure App Service / DigitalOcean App)
最後 — 我為你準備的「立即可複製」清單(三個立即任務)
在 psych-site/infra 建 docker-compose.yml(上面內容)並執行:docker compose up -d
在 psych-site/backend scaffold C#(上面 dotnet 指令),把 appsettings.Development.json 的連線字串改成你 docker 的設定,執行 dotnet ef database update。
在 psych-site/frontend scaffold Vite、貼上 App.vue(或我之前給的完整前端程式),在 vite.config.js 設 proxy,然後 npm run dev 開前端。
你要我現在幫你做哪一件 我就直接把對應完整檔案內容貼給你 (不用再問): A. 把 backend 的 C# 專案 完整檔案(Program.cs、AppDbContext.cs、Model、Controllers、Dockerfile) 一次貼給你複製貼上; B. 或把 FastAPI 版本的 backend 完整檔案一次貼給你; C. 或把 前端 App.vue + vite.config.js (已優化可呼叫後端 AI)一次貼給你。
選 A、B 或 C,我立刻把那個部分的完整可運行檔案貼出來。