diff --git a/STARTUP_GUIDE.md b/STARTUP_GUIDE.md new file mode 100644 index 0000000..a990513 --- /dev/null +++ b/STARTUP_GUIDE.md @@ -0,0 +1,123 @@ +# Java Service Template - Quick Start Guide + +This guide explains how to initialize the database, establish Flyway baseline, and start the application. + +## Prerequisites + +Before running the application, ensure you have: + +1. **Java 21** installed +2. **Maven** installed +3. **PostgreSQL** server running locally (or configure external access) +4. **Redis** server running locally (or configure external access) + +## Quick Start Script + +The project includes a script to automate the entire setup process: + +### Using the Start Script + +```bash +# Make the script executable (if not already done) +chmod +x start_app.sh + +# Run the complete setup and start the application +./start_app.sh +``` + +This script will: +1. Check PostgreSQL connectivity +2. Build the application using Maven +3. Create the database named `java_template` +4. Establish Flyway baseline and run migrations +5. Start the application + +### Manual Steps (Alternative) + +If you prefer to run the steps manually: + +#### 1. Build the Application +```bash +mvn clean package -DskipTests +``` + +#### 2. Set Up Database + +Make sure PostgreSQL is running, then: + +```bash +# Connect to PostgreSQL as superuser +psql -h localhost -p 5432 -U postgres + +# Create the database +CREATE DATABASE java_template; +\q +``` + +#### 3. Run the Application with Flyway + +```bash +# The application will automatically run Flyway migrations on startup +java -jar tmpl-api/target/tmpl-api-0.1.0-SNAPSHOT.jar \ + -Dspring.profiles.active=dev \ + -DDB_HOST=localhost \ + -DDB_PORT=5432 \ + -DDB_NAME=java_template \ + -DDB_USER=postgres \ + -DDB_PASS=postgres +``` + +## Configuration + +The application uses the following default configuration: + +- **Database**: PostgreSQL at `localhost:5432`, database name `java_template` +- **Database User**: `postgres` with password `postgres` +- **Redis**: At `localhost:6379` +- **Application Port**: `8080` +- **Management Port**: `8080` (in dev profile, merged with app port) + +These can be overridden using environment variables: +- `DB_HOST`, `DB_PORT`, `DB_NAME`, `DB_USER`, `DB_PASS` +- `REDIS_HOST`, `REDIS_PORT` + +## Database Migrations + +The application includes Flyway migrations: +- `V1__init.sql`: Basic schema initialization +- `V2__create_order.sql`: Creates the order table with audit columns + +Flyway will automatically apply these migrations on application startup. + +## Accessing the Application + +Once started, the application will be available at: +- **Main endpoint**: http://localhost:8080 +- **API Documentation**: http://localhost:8080/swagger-ui.html +- **Health check**: http://localhost:8080/actuator/health +- **Metrics**: http://localhost:8080/actuator/prometheus + +## Troubleshooting + +### Common Issues: + +1. **PostgreSQL not accessible**: Make sure PostgreSQL server is running and accessible +2. **Database permissions**: Ensure the database user has CREATE privileges +3. **Port conflicts**: Check if ports 8080 and 6379 are available +4. **Connection timeouts**: Verify network connectivity to database and Redis + +### Environment Variables: + +You can customize the configuration using environment variables: + +```bash +export DB_HOST=localhost +export DB_PORT=5432 +export DB_NAME=java_template +export DB_USER=postgres +export DB_PASS=postgres +export REDIS_HOST=localhost +export REDIS_PORT=6379 +``` + +Then run the application normally. \ No newline at end of file diff --git a/init_and_start.sh b/init_and_start.sh new file mode 100755 index 0000000..4e7b715 --- /dev/null +++ b/init_and_start.sh @@ -0,0 +1,198 @@ +#!/bin/bash + +# Java Service Template - Initialization and Startup Script +# This script initializes the database, establishes Flyway baseline, and starts the application + +set -e # Exit immediately if a command exits with a non-zero status + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +echo_color() { + local color=$1 + local message=$2 + echo -e "${color}${message}${NC}" +} + +# Configuration +DB_NAME="java_template" +DB_USER="${DB_USER:-postgres}" +DB_PASS="${DB_PASS:-postgres}" +DB_HOST="${DB_HOST:-localhost}" +DB_PORT="${DB_PORT:-5432}" + +APP_JAR="tmpl-api/target/tmpl-api-0.1.0-SNAPSHOT.jar" + +echo_color $YELLOW "Starting Java Service Template initialization..." + +# Function to check if PostgreSQL is running +check_postgres() { + if ! command -v psql &> /dev/null; then + echo_color $RED "psql command not found. Please install PostgreSQL client." + exit 1 + fi + + if ! pg_isready -h "$DB_HOST" -p "$DB_PORT" 2>/dev/null; then + echo_color $RED "PostgreSQL server is not running at $DB_HOST:$DB_PORT" + echo_color $YELLOW "Please start PostgreSQL server before running this script." + exit 1 + fi +} + +# Function to create database +create_database() { + echo_color $YELLOW "Creating database: $DB_NAME" + + # Check if database already exists + if PGPASSWORD="$DB_PASS" psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -lqt | cut -d \| -f 1 | grep -qw "$DB_NAME"; then + echo_color $GREEN "Database $DB_NAME already exists, skipping creation." + return 0 + fi + + # Create database + PGPASSWORD="$DB_PASS" createdb -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -O "$DB_USER" "$DB_NAME" + echo_color $GREEN "Database $DB_NAME created successfully." +} + +# Function to establish Flyway baseline +establish_flyway_baseline() { + echo_color $YELLOW "Establishing Flyway baseline..." + + # Check if flyway schema history table exists + if PGPASSWORD="$DB_PASS" psql -h "$DB_HOST" -p "$DB_PORT" -d "$DB_NAME" -U "$DB_USER" -tAc "SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'flyway_schema_history');" | grep -q 't'; then + echo_color $GREEN "Flyway schema history table already exists, skipping baseline." + return 0 + fi + + # Run the application with Flyway baseline enabled + echo_color $YELLOW "Running application to establish Flyway baseline..." + + # Temporarily set baseline on migrate to true + JAVA_OPTS="-Dspring.flyway.baseline-on-migrate=true -Dspring.flyway.baseline-version=0 -Dspring.profiles.active=dev" + JAVA_OPTS="$JAVA_OPTS -DDB_HOST=$DB_HOST -DDB_PORT=$DB_PORT -DDB_NAME=$DB_NAME -DDB_USER=$DB_USER -DDB_PASS=$DB_PASS" + + # Run the application briefly to establish baseline + timeout 30s java $JAVA_OPTS -jar $APP_JAR || true + + echo_color $GREEN "Flyway baseline established." +} + +# Function to run migrations +run_migrations() { + echo_color $YELLOW "Running database migrations..." + + # Run the application to apply migrations + JAVA_OPTS="-Dspring.profiles.active=dev" + JAVA_OPTS="$JAVA_OPTS -DDB_HOST=$DB_HOST -DDB_PORT=$DB_PORT -DDB_NAME=$DB_NAME -DDB_USER=$DB_USER -DDB_PASS=$DB_PASS" + + # Run the application briefly to apply migrations + timeout 30s java $JAVA_OPTS -jar $APP_JAR || true + + echo_color $GREEN "Database migrations applied." +} + +# Function to build the application +build_application() { + echo_color $YELLOW "Building the application..." + + if [ ! -f "pom.xml" ]; then + echo_color $RED "pom.xml not found in current directory!" + exit 1 + fi + + mvn clean package -DskipTests + + if [ ! -f "$APP_JAR" ]; then + echo_color $RED "Application JAR not found at $APP_JAR after build!" + exit 1 + fi + + echo_color $GREEN "Application built successfully." +} + +# Function to start the application +start_application() { + echo_color $YELLOW "Starting the application..." + + # Set environment variables for the application + export DB_HOST=$DB_HOST + export DB_PORT=$DB_PORT + export DB_NAME=$DB_NAME + export DB_USER=$DB_USER + export DB_PASS=$DB_PASS + + # Start the application in the background + JAVA_OPTS="-Dspring.profiles.active=dev" + JAVA_OPTS="$JAVA_OPTS -DDB_HOST=$DB_HOST -DDB_PORT=$DB_PORT -DDB_NAME=$DB_NAME -DDB_USER=$DB_USER -DDB_PASS=$DB_PASS" + + echo_color $GREEN "Starting application with command: java $JAVA_OPTS -jar $APP_JAR" + java $JAVA_OPTS -jar $APP_JAR & + + APP_PID=$! + echo $APP_PID > app.pid + echo_color $GREEN "Application started with PID: $APP_PID" + echo_color $GREEN "Application is available at: http://localhost:8080" + echo_color $GREEN "Actuator endpoints available at: http://localhost:8080/actuator" + + # Wait for the application to finish + wait $APP_PID +} + +# Main execution +main() { + echo_color $YELLOW "Step 1: Checking prerequisites..." + check_postgres + + echo_color $YELLOW "Step 2: Building application..." + build_application + + echo_color $YELLOW "Step 3: Creating database..." + create_database + + echo_color $YELLOW "Step 4: Establishing Flyway baseline..." + establish_flyway_baseline + + echo_color $YELLOW "Step 5: Running migrations..." + run_migrations + + echo_color $YELLOW "Step 6: Starting application..." + start_application +} + +# Parse command line arguments +case "${1:-full}" in + "init-only") + echo_color $YELLOW "Initializing database and establishing Flyway baseline only..." + check_postgres + create_database + establish_flyway_baseline + run_migrations + echo_color $GREEN "Database initialization completed!" + ;; + "start-only") + echo_color $YELLOW "Starting application only..." + if [ ! -f "$APP_JAR" ]; then + echo_color $RED "Application JAR not found. Please build first or run 'full'." + exit 1 + fi + start_application + ;; + "build-only") + echo_color $YELLOW "Building application only..." + build_application + ;; + "full"|"") + main + ;; + *) + echo_color $RED "Usage: $0 [full|init-only|start-only|build-only]" + echo_color $YELLOW " full (default): Initialize database and start application" + echo_color $YELLOW " init-only: Initialize database and establish Flyway baseline only" + echo_color $YELLOW " start-only: Start application only (requires built JAR)" + echo_color $YELLOW " build-only: Build application only" + exit 1 + ;; +esac \ No newline at end of file diff --git a/start_app.sh b/start_app.sh new file mode 100755 index 0000000..27e9f9b --- /dev/null +++ b/start_app.sh @@ -0,0 +1,153 @@ +#!/bin/bash + +# Java Service Template - Quick Start Script +# Initializes database 'java_template', establishes Flyway baseline, and starts the application + +set -e # Exit immediately if a command exits with a non-zero status + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +echo_color() { + local color=$1 + local message=$2 + echo -e "${color}${message}${NC}" +} + +# Check if another instance is already running +if pgrep -f "java.*tmpl-api.*SNAPSHOT.jar" > /dev/null; then + echo_color $RED "Another instance of the application is already running!" + echo_color $YELLOW "Please stop the existing process before starting a new one." + exit 1 +fi + +# Configuration - Use environment variables with defaults +PORT="${PORT:-48080}" +DB_NAME="${DB_NAME:-java_template}" +DB_USER="${DB_USER:-postgres}" +DB_PASS="${DB_PASS:-postgres}" +DB_HOST="${DB_HOST:-localhost}" +DB_PORT="${DB_PORT:-5432}" + +APP_JAR="tmpl-api/target/tmpl-api-0.1.0-SNAPSHOT.jar" + +echo_color $YELLOW "Starting Java Service Template setup..." +echo_color $YELLOW "Using port: $PORT" + +# Function to check if PostgreSQL is running +check_postgres() { + echo_color $YELLOW "Checking PostgreSQL connectivity..." + + if ! command -v psql &> /dev/null; then + echo_color $RED "psql command not found. Please install PostgreSQL client." + exit 1 + fi + + if ! pg_isready -h "$DB_HOST" -p "$DB_PORT" 2>/dev/null; then + echo_color $RED "PostgreSQL server is not running at $DB_HOST:$DB_PORT" + echo_color $YELLOW "Please start PostgreSQL server before running this script." + exit 1 + fi + + echo_color $GREEN "✓ PostgreSQL is accessible" +} + +# Function to create database +create_database() { + echo_color $YELLOW "Creating database: $DB_NAME" + + # Check if database already exists + if PGPASSWORD="$DB_PASS" psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -lqt | cut -d \| -f 1 | grep -qw "$DB_NAME"; then + echo_color $GREEN "✓ Database $DB_NAME already exists" + return 0 + fi + + # Create database + PGPASSWORD="$DB_PASS" createdb -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -O "$DB_USER" "$DB_NAME" + echo_color $GREEN "✓ Database $DB_NAME created successfully" +} + +# Function to build the application +build_application() { + echo_color $YELLOW "Building the application..." + + if [ ! -f "pom.xml" ]; then + echo_color $RED "✗ Pom.xml not found in current directory!" + exit 1 + fi + + mvn clean package -DskipTests + + if [ ! -f "$APP_JAR" ]; then + echo_color $RED "✗ Application JAR not found at $APP_JAR after build!" + exit 1 + fi + + echo_color $GREEN "✓ Application built successfully" +} + +# Function to establish Flyway baseline and run migrations +setup_flyway() { + echo_color $YELLOW "Setting up Flyway migrations..." + + # Run the application once to let Flyway handle the database setup + # This will create the flyway_schema_history table and apply migrations + JAVA_OPTS="-Dspring.profiles.active=dev,redis -Dspring.main.allow-bean-definition-overriding=true" + JAVA_OPTS="$JAVA_OPTS -DDB_HOST=$DB_HOST -DDB_PORT=$DB_PORT -DDB_NAME=$DB_NAME -DDB_USER=$DB_USER -DDB_PASS=$DB_PASS" + + echo_color $YELLOW "Running application to initialize database with Flyway..." + + # Run the application briefly to let Flyway do its job + # Use a random port to avoid conflicts and ensure quick startup/shutdown + timeout 30s java $JAVA_OPTS -Dserver.port=0 -Dmanagement.server.port=0 -jar $APP_JAR || true + # The || true ensures the script continues even if timeout kills the process + + echo_color $GREEN "✓ Flyway setup completed (baseline and migrations applied)" +} + +# Function to start the application properly +start_application() { + echo_color $YELLOW "Starting the application..." + + # Set environment variables for the application + export DB_HOST=$DB_HOST + export DB_PORT=$DB_PORT + export DB_NAME=$DB_NAME + export DB_USER=$DB_USER + export DB_PASS=$DB_PASS + + # Start the application with the specified port + JAVA_OPTS="-Dserver.port=$PORT -Dmanagement.server.port=$PORT" + JAVA_OPTS="$JAVA_OPTS -Dspring.profiles.active=dev,redis -Dspring.main.allow-bean-definition-overriding=true" + JAVA_OPTS="$JAVA_OPTS -DDB_HOST=$DB_HOST -DDB_PORT=$DB_PORT -DDB_NAME=$DB_NAME -DDB_USER=$DB_USER -DDB_PASS=$DB_PASS" + + echo_color $GREEN "✓ Starting application with command: java $JAVA_OPTS -jar $APP_JAR" + echo_color $GREEN "✓ Application will be available at: http://localhost:$PORT" + echo_color $GREEN "✓ Health endpoint: http://localhost:$PORT/actuator/health" + + java $JAVA_OPTS -jar $APP_JAR +} + +# Main execution sequence +main() { + echo_color $YELLOW "=== Step 1: Checking prerequisites ===" + check_postgres + + echo_color $YELLOW "=== Step 2: Building application ===" + build_application + + echo_color $YELLOW "=== Step 3: Creating database '$DB_NAME' ===" + create_database + + echo_color $YELLOW "=== Step 4: Setting up Flyway (baseline and migrations) ===" + setup_flyway + + echo_color $YELLOW "=== Step 5: Starting application ===" + start_application +} + +# Run the main function +main \ No newline at end of file diff --git a/tmpl-admin/.env.development b/tmpl-admin/.env.development new file mode 100644 index 0000000..c616c4d --- /dev/null +++ b/tmpl-admin/.env.development @@ -0,0 +1,5 @@ +# 开发环境后端地址。Vite proxy 会读取这些值作为 target。 +# 如需覆盖,创建 .env.development.local(不入 Git)。 +VITE_API_BASE_URL=http://localhost:8080 +VITE_ACTUATOR_BASE_URL=http://localhost:9090 +VITE_ENABLE_MSW=true \ No newline at end of file diff --git a/tmpl-admin/.env.production b/tmpl-admin/.env.production new file mode 100644 index 0000000..8b46abe --- /dev/null +++ b/tmpl-admin/.env.production @@ -0,0 +1,5 @@ +# 生产环境:前端与后端同域部署(通过 Nginx/网关转发 /api 和 /actuator), +# 因此 baseURL 为空,所有请求走相对路径。Vite proxy 仅在 dev server 生效。 +VITE_API_BASE_URL= +VITE_ACTUATOR_BASE_URL= +VITE_ENABLE_MSW=false \ No newline at end of file diff --git a/tmpl-admin/.prettierrc.json b/tmpl-admin/.prettierrc.json new file mode 100644 index 0000000..57221f6 --- /dev/null +++ b/tmpl-admin/.prettierrc.json @@ -0,0 +1,8 @@ +{ + "semi": true, + "singleQuote": true, + "trailingComma": "all", + "printWidth": 120, + "tabWidth": 2, + "endOfLine": "lf" +} \ No newline at end of file diff --git a/tmpl-admin/eslint.config.js b/tmpl-admin/eslint.config.js new file mode 100644 index 0000000..2770da2 --- /dev/null +++ b/tmpl-admin/eslint.config.js @@ -0,0 +1,19 @@ +import js from '@eslint/js'; +import tseslint from 'typescript-eslint'; +import vue from 'eslint-plugin-vue'; + +export default [ + js.configs.recommended, + ...tseslint.configs.recommended, + ...vue.configs['flat/recommended'], + { + files: ['**/*.{ts,vue}'], + rules: { + 'vue/multi-word-component-names': 'off', + '@typescript-eslint/no-explicit-any': 'warn', + }, + }, + { + ignores: ['dist/', 'node_modules/', 'public/mockServiceWorker.js', 'src/auto-imports.d.ts', 'src/components.d.ts'], + }, +]; \ No newline at end of file diff --git a/tmpl-admin/index.html b/tmpl-admin/index.html new file mode 100644 index 0000000..67ebe5c --- /dev/null +++ b/tmpl-admin/index.html @@ -0,0 +1,12 @@ + + +
+ + +TODO: 实现 ${pageName} 页面
+