Merge branch 'main-framework' into develop-business-css
This commit is contained in:
commit
16549de421
150
.gitignore
vendored
150
.gitignore
vendored
@ -1,104 +1,46 @@
|
|||||||
HELP.md
|
framework/src/main/resources/static/assets/401-099a3a32.js
|
||||||
target/
|
framework/src/main/resources/static/assets/401-fffd1e4b.css
|
||||||
!.mvn/wrapper/maven-wrapper.jar
|
framework/src/main/resources/static/assets/404-6dcbdda2.js
|
||||||
!**/src/main/**/target/
|
framework/src/main/resources/static/assets/404-51ac6f86.css
|
||||||
!**/src/test/**/target/
|
framework/src/main/resources/static/assets/BarChart-efd5cbe1.js
|
||||||
|
framework/src/main/resources/static/assets/editor-b13c93a6.js
|
||||||
### STS ###
|
framework/src/main/resources/static/assets/FunnelChart-79f3d5f7.js
|
||||||
.apt_generated
|
framework/src/main/resources/static/assets/index-1a396a09.css
|
||||||
.classpath
|
framework/src/main/resources/static/assets/index-01e2cfa9.js
|
||||||
.factorypath
|
framework/src/main/resources/static/assets/index-2b88764d.css
|
||||||
.project
|
framework/src/main/resources/static/assets/index-04bb232d.js
|
||||||
.settings
|
framework/src/main/resources/static/assets/index-5a5afaa7.css
|
||||||
.springBeans
|
framework/src/main/resources/static/assets/index-6cf33161.js
|
||||||
.sts4-cache
|
framework/src/main/resources/static/assets/index-6ee17396.css
|
||||||
|
framework/src/main/resources/static/assets/index-9c04fca4.css
|
||||||
### IntelliJ IDEA ###
|
framework/src/main/resources/static/assets/index-63bba755.js
|
||||||
.idea
|
framework/src/main/resources/static/assets/index-70f67d2a.js
|
||||||
*.iws
|
framework/src/main/resources/static/assets/index-98c36269.js
|
||||||
*.iml
|
framework/src/main/resources/static/assets/index-362b32fa.css
|
||||||
*.ipr
|
framework/src/main/resources/static/assets/index-486d1d98.js
|
||||||
|
framework/src/main/resources/static/assets/index-2814df08.js
|
||||||
### NetBeans ###
|
framework/src/main/resources/static/assets/index-5282e30f.js
|
||||||
/nbproject/private/
|
framework/src/main/resources/static/assets/index-9057b190.js
|
||||||
/nbbuild/
|
framework/src/main/resources/static/assets/index-968257e1.css
|
||||||
/dist/
|
framework/src/main/resources/static/assets/index-b25f0d08.js
|
||||||
/nbdist/
|
framework/src/main/resources/static/assets/index-b98a9d85.js
|
||||||
/.nb-gradle/
|
framework/src/main/resources/static/assets/index-bca4e108.js
|
||||||
build/
|
framework/src/main/resources/static/assets/index-c2e52e75.js
|
||||||
/logs/
|
framework/src/main/resources/static/assets/index-c03bc2fe.js
|
||||||
!**/src/main/**/build/
|
framework/src/main/resources/static/assets/index-cdc0bc49.css
|
||||||
!**/src/test/**/build/
|
framework/src/main/resources/static/assets/index-ce8e85c4.js
|
||||||
|
framework/src/main/resources/static/assets/index-e5abaec0.js
|
||||||
### VS Code ###
|
framework/src/main/resources/static/assets/index-e051e64c.js
|
||||||
.vscode/
|
framework/src/main/resources/static/assets/index-f52936ec.js
|
||||||
src/main/resources/static/favicon.ico
|
framework/src/main/resources/static/assets/index1-5c7d9d99.js
|
||||||
src/main/resources/static/index.html
|
framework/src/main/resources/static/assets/index2-26043b81.js
|
||||||
src/main/resources/static/assets/401-88639a9f.js
|
framework/src/main/resources/static/assets/lbcz_xg-6b0694a6.js
|
||||||
src/main/resources/static/assets/401-a61ddb94.gif
|
framework/src/main/resources/static/assets/page.vue_vue_type_script_setup_true_lang-7a09a11a.js
|
||||||
src/main/resources/static/assets/401-d244ab29.css
|
framework/src/main/resources/static/assets/personalCenter-a026f3ae.js
|
||||||
src/main/resources/static/assets/404_cloud-98e7ac66.png
|
framework/src/main/resources/static/assets/PieChart-bffd7bcc.js
|
||||||
src/main/resources/static/assets/404-7ca1fe28.css
|
framework/src/main/resources/static/assets/RadarChart-e43ec971.js
|
||||||
src/main/resources/static/assets/404-7d365cf6.js
|
framework/src/main/resources/static/assets/resize-24879ea2.js
|
||||||
src/main/resources/static/assets/404-538aa4d7.png
|
framework/src/main/resources/static/assets/sortable.esm-616533ae.js
|
||||||
src/main/resources/static/assets/BarChart-4fa92581.js
|
framework/src/main/resources/static/assets/tagsView-6df0ea3e.js
|
||||||
src/main/resources/static/assets/BarChart.vue_vue_type_script_setup_true_lang-2e88c556.js
|
framework/src/main/resources/static/assets/uploader-0562c8e7.js
|
||||||
src/main/resources/static/assets/editor-1fcae90e.js
|
framework/src/main/resources/static/assets/uploader-4183de44.css
|
||||||
src/main/resources/static/assets/editor-501cf061.css
|
|
||||||
src/main/resources/static/assets/FunnelChart-54cd9c1c.js
|
|
||||||
src/main/resources/static/assets/index-0c0fc4d5.js
|
|
||||||
src/main/resources/static/assets/index-0c6de5c4.css
|
|
||||||
src/main/resources/static/assets/index-0e353610.js
|
|
||||||
src/main/resources/static/assets/index-0fdbb0c3.css
|
|
||||||
src/main/resources/static/assets/index-2a2e686f.js
|
|
||||||
src/main/resources/static/assets/index-2d8a94de.js
|
|
||||||
src/main/resources/static/assets/index-3c8b576d.js
|
|
||||||
src/main/resources/static/assets/index-3e4e0c0c.css
|
|
||||||
src/main/resources/static/assets/index-3ea31a03.css
|
|
||||||
src/main/resources/static/assets/index-4a40522c.js
|
|
||||||
src/main/resources/static/assets/index-4af6c095.js
|
|
||||||
src/main/resources/static/assets/index-4b2c54eb.css
|
|
||||||
src/main/resources/static/assets/index-4e9a4a3c.css
|
|
||||||
src/main/resources/static/assets/index-4e36f11e.css
|
|
||||||
src/main/resources/static/assets/index-5b909b30.js
|
|
||||||
src/main/resources/static/assets/index-6cfbc6e9.js
|
|
||||||
src/main/resources/static/assets/index-6d369684.js
|
|
||||||
src/main/resources/static/assets/index-9cdf102e.js
|
|
||||||
src/main/resources/static/assets/index-013c92bf.css
|
|
||||||
src/main/resources/static/assets/index-45b24ee3.js
|
|
||||||
src/main/resources/static/assets/index-58b7edbc.css
|
|
||||||
src/main/resources/static/assets/index-97e2e5d7.js
|
|
||||||
src/main/resources/static/assets/index-336eb0cd.js
|
|
||||||
src/main/resources/static/assets/index-1124a30a.js
|
|
||||||
src/main/resources/static/assets/index-5736aae9.js
|
|
||||||
src/main/resources/static/assets/index-23665d45.js
|
|
||||||
src/main/resources/static/assets/index-35744cd0.css
|
|
||||||
src/main/resources/static/assets/index-49408471.js
|
|
||||||
src/main/resources/static/assets/index-a7bce641.css
|
|
||||||
src/main/resources/static/assets/index-adef366f.js
|
|
||||||
src/main/resources/static/assets/index-dd0c8cf0.css
|
|
||||||
src/main/resources/static/assets/index-dd267244.js
|
|
||||||
src/main/resources/static/assets/index-de40e6e9.css
|
|
||||||
src/main/resources/static/assets/index-f9a887b2.css
|
|
||||||
src/main/resources/static/assets/index1-f104bedb.js
|
|
||||||
src/main/resources/static/assets/index2-8960589f.js
|
|
||||||
src/main/resources/static/assets/indicator-5b15d0d1.png
|
|
||||||
src/main/resources/static/assets/lbcz_sc-0ed76926.js
|
|
||||||
src/main/resources/static/assets/lbcz_td-b5984317.js
|
|
||||||
src/main/resources/static/assets/lbcz_xg-aaaefba0.js
|
|
||||||
src/main/resources/static/assets/logo-03d6d6da.png
|
|
||||||
src/main/resources/static/assets/page.vue_vue_type_script_setup_true_lang-b61c9f0c.js
|
|
||||||
src/main/resources/static/assets/personalCenter-035ae2fa.js
|
|
||||||
src/main/resources/static/assets/personalCenter-ad68cb91.css
|
|
||||||
src/main/resources/static/assets/PieChart-24d7f015.js
|
|
||||||
src/main/resources/static/assets/PieChart.vue_vue_type_script_setup_true_lang-d4bdc783.js
|
|
||||||
src/main/resources/static/assets/RadarChart-f3f7d950.js
|
|
||||||
src/main/resources/static/assets/RadarChart.vue_vue_type_script_setup_true_lang-c1ab7800.js
|
|
||||||
src/main/resources/static/assets/resize-76420810.js
|
|
||||||
src/main/resources/static/assets/rsaEncrypt-96cab0ea.js
|
|
||||||
src/main/resources/static/assets/sortable.esm-be94e56d.js
|
|
||||||
src/main/resources/static/assets/tagsView-23de2998.js
|
|
||||||
src/main/resources/static/assets/top_tx-3cab94c6.png
|
|
||||||
src/main/resources/static/assets/u287-9a3328bc.gif
|
|
||||||
src/main/resources/static/assets/uploader-769f4f98.js
|
|
||||||
src/main/resources/static/assets/uploader-ccfd78f9.css
|
|
||||||
|
|||||||
@ -1,7 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
|
|
||||||
# Basic pre-commit hook initialized at repo root.
|
|
||||||
# Add your checks below (lint/test/etc.).
|
|
||||||
|
|
||||||
echo "husky pre-commit: no checks configured yet"
|
|
||||||
exit 0
|
|
||||||
17
.vscode/launch.json
vendored
17
.vscode/launch.json
vendored
@ -1,21 +1,14 @@
|
|||||||
{
|
{
|
||||||
// 使用 IntelliSense 了解相关属性。
|
|
||||||
// 悬停以查看现有属性的描述。
|
|
||||||
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
|
||||||
"version": "0.2.0",
|
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"type": "java",
|
"type": "java",
|
||||||
"name": "PlatformApplication",
|
"name": "Spring Boot-PlatformApplication<platform>",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
"mainClass": "com.yfd.platform.PlatformApplication",
|
"mainClass": "com.yfd.platform.PlatformApplication",
|
||||||
"projectName": ""
|
"projectName": "platform",
|
||||||
},
|
"args": "",
|
||||||
{
|
"envFile": "${workspaceFolder}/.env"
|
||||||
"type": "java",
|
|
||||||
"name": "Current File",
|
|
||||||
"request": "launch",
|
|
||||||
"mainClass": "${file}"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -1,19 +0,0 @@
|
|||||||
# Critical Scenario Simulator (CSS)
|
|
||||||
|
|
||||||
临界事故情景分析模拟系统(CSS)业务模块。
|
|
||||||
|
|
||||||
## 后端模块
|
|
||||||
- Maven 模块路径:`business-css/`
|
|
||||||
- 依赖复用:依赖 `framework` 生成的 classes JAR(`com.yfd:platform:1.0`)。
|
|
||||||
- 按需添加业务领域代码(实体、服务、控制器)。
|
|
||||||
|
|
||||||
## 前端模块
|
|
||||||
- 目录:`business-css/frontend/`
|
|
||||||
- 初始化方式:从 `framework/frontend` 复制基线前端后进行业务化开发。
|
|
||||||
- 同步机制:使用 `scripts/sync-frontend.ps1` 从基线前端同步公共目录(排除环境配置)。
|
|
||||||
|
|
||||||
## 初始化步骤
|
|
||||||
1. 执行前端同步脚本,初始化 `business-css/frontend`。
|
|
||||||
2. 安装前端依赖:`pnpm i` 或 `npm ci`。
|
|
||||||
3. 启动前端:`pnpm dev` 或 `npm run dev`。
|
|
||||||
4. 后端模块使用 `mvn -pl business-css -am clean verify` 构建与测试。
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
# CSS 前端(占位)
|
|
||||||
|
|
||||||
初始化指引:
|
|
||||||
- 运行 `scripts/sync-frontend.ps1` 将 `framework/frontend` 基线复制到此目录。
|
|
||||||
- 在本目录执行 `pnpm i` 或 `npm ci` 安装依赖。
|
|
||||||
- 更新 `.env.*`、路由与页面以适配 CSS 业务需求。
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>com.yfd</groupId>
|
|
||||||
<artifactId>JavaProjectParent</artifactId>
|
|
||||||
<version>1.0</version>
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<groupId>com.yfd.css</groupId>
|
|
||||||
<artifactId>css-backend</artifactId>
|
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
|
||||||
<packaging>war</packaging>
|
|
||||||
|
|
||||||
<name>Critical Scenario Simulator (CSS) Backend</name>
|
|
||||||
<description>临界事故情景分析模拟系统 - 后端模块</description>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<java.version>17</java.version>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<!-- 复用平台框架的 classes JAR -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.yfd</groupId>
|
|
||||||
<artifactId>framework</artifactId>
|
|
||||||
<version>1.0</version>
|
|
||||||
<type>jar</type>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- 业务自身的基础依赖,可按需扩展 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-validation</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
server:
|
|
||||||
port: 8098
|
|
||||||
|
|
||||||
spring:
|
|
||||||
application:
|
|
||||||
name: css-backend
|
|
||||||
|
|
||||||
css:
|
|
||||||
scenario:
|
|
||||||
defaultRiskLevel: MEDIUM
|
|
||||||
simulationMaxSteps: 1000
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
# syntax=docker/dockerfile:1
|
|
||||||
FROM eclipse-temurin:17-jre-alpine
|
|
||||||
|
|
||||||
LABEL maintainer="platform-team"
|
|
||||||
|
|
||||||
ENV TZ=Asia/Shanghai \
|
|
||||||
LANG=zh_CN.UTF-8 \
|
|
||||||
JAVA_OPTS="-Dfile.encoding=UTF-8" \
|
|
||||||
SPRING_PROFILES_ACTIVE=dev
|
|
||||||
|
|
||||||
RUN apk add --no-cache tzdata && \
|
|
||||||
ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
# 注意:在构建镜像前先执行 `mvn -DskipTests package` 生成 WAR
|
|
||||||
COPY target/platform-1.0.war /app/app.war
|
|
||||||
|
|
||||||
EXPOSE 8093
|
|
||||||
|
|
||||||
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar /app/app.war --spring.profiles.active=$SPRING_PROFILES_ACTIVE"]
|
|
||||||
8
framework/db-init/README.md
Normal file
8
framework/db-init/README.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# db-init 目录说明
|
||||||
|
|
||||||
|
- `sql/base-schema.sql`:数据库结构(表、索引、约束),由 mysqldump 导出或手写维护。
|
||||||
|
- `sql/base-data.sql`:初始化数据(字典、角色、菜单、管理员等),由 mysqldump 导出或手写维护。
|
||||||
|
- `scripts/export.ps1`:Windows 导出脚本;将当前库结构与指定白名单数据导出到 sql 目录。
|
||||||
|
- `scripts/import.ps1`:Windows 导入脚本;将 sql 中的结构与数据导入到目标库。
|
||||||
|
|
||||||
|
请参考 `../docs/数据库初始方案.md` 获取完整流程与约束。
|
||||||
100
framework/db-init/scripts/export.ps1
Normal file
100
framework/db-init/scripts/export.ps1
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
param(
|
||||||
|
[string]$DB_HOST = '43.138.168.68',
|
||||||
|
[int]$DB_PORT = 3306,
|
||||||
|
[string]$DB_NAME = 'frameworkdb2023',
|
||||||
|
[string]$DB_USER = 'root',
|
||||||
|
[string]$DB_PASSWORD = 'ylfw20230626@'
|
||||||
|
)
|
||||||
|
|
||||||
|
# 确保输出目录存在
|
||||||
|
$outputDir = Join-Path $PSScriptRoot '..\sql'
|
||||||
|
if (!(Test-Path $outputDir)) {
|
||||||
|
New-Item -ItemType Directory -Path $outputDir | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
# 构建输出文件路径
|
||||||
|
$schemaFile = Join-Path $outputDir "base-schema.sql"
|
||||||
|
$dataFile = Join-Path $outputDir "base-data.sql"
|
||||||
|
|
||||||
|
# 构建 mysqldump 命令参数
|
||||||
|
$commonArgs = @(
|
||||||
|
"--host=$hostName",
|
||||||
|
"--port=$port",
|
||||||
|
"--user=$user",
|
||||||
|
"--routines",
|
||||||
|
"--triggers",
|
||||||
|
"--single-transaction",
|
||||||
|
"--set-charset",
|
||||||
|
"--default-character-set=utf8mb4"
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($password) {
|
||||||
|
$commonArgs += "--password=$password"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "开始导出数据库结构和数据..."
|
||||||
|
Write-Host "数据库: $database"
|
||||||
|
Write-Host "主机: $hostName:$port"
|
||||||
|
Write-Host "用户: $user"
|
||||||
|
Write-Host "输出目录: $outputDir"
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
# 导出数据库结构(仅结构,不包含数据)
|
||||||
|
Write-Host "正在导出数据库结构到: $schemaFile"
|
||||||
|
try {
|
||||||
|
$schemaArgs = $commonArgs + @(
|
||||||
|
"--no-data",
|
||||||
|
"--result-file=$schemaFile",
|
||||||
|
$database
|
||||||
|
)
|
||||||
|
|
||||||
|
& mysqldump @schemaArgs
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -eq 0) {
|
||||||
|
Write-Host "✓ 数据库结构导出成功" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
throw "mysqldump 返回错误代码: $LASTEXITCODE"
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Error "导出数据库结构失败: $_"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 导出数据(仅数据,不包含结构)
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "正在导出数据到: $dataFile"
|
||||||
|
try {
|
||||||
|
$dataArgs = $commonArgs + @(
|
||||||
|
"--no-create-info",
|
||||||
|
"--skip-triggers",
|
||||||
|
"--result-file=$dataFile",
|
||||||
|
$database
|
||||||
|
)
|
||||||
|
|
||||||
|
& mysqldump @dataArgs
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -eq 0) {
|
||||||
|
Write-Host "✓ 数据导出成功" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
throw "mysqldump 返回错误代码: $LASTEXITCODE"
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Error "导出数据失败: $_"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "数据库导出完成!" -ForegroundColor Green
|
||||||
|
Write-Host "结构文件: $schemaFile"
|
||||||
|
Write-Host "数据文件: $dataFile"
|
||||||
|
|
||||||
|
# 显示文件大小
|
||||||
|
if (Test-Path $schemaFile) {
|
||||||
|
$schemaSize = (Get-Item $schemaFile).Length
|
||||||
|
Write-Host "结构文件大小: $([math]::Round($schemaSize/1KB, 2)) KB"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Test-Path $dataFile) {
|
||||||
|
$dataSize = (Get-Item $dataFile).Length
|
||||||
|
Write-Host "数据文件大小: $([math]::Round($dataSize/1KB, 2)) KB"
|
||||||
|
}
|
||||||
46
framework/db-init/scripts/import.ps1
Normal file
46
framework/db-init/scripts/import.ps1
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
param(
|
||||||
|
[string]$DB_HOST = '43.138.168.68',
|
||||||
|
[int]$DB_PORT = 3306,
|
||||||
|
[string]$DB_NAME = 'frameworkdb2025',
|
||||||
|
[string]$DB_USER = 'root',
|
||||||
|
[string]$DB_PASSWORD = 'ylfw20230626@'
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
$env:MYSQL_PWD = $DB_PASSWORD
|
||||||
|
|
||||||
|
$schemaPath = Join-Path $PSScriptRoot '..\sql\base-schema.sql'
|
||||||
|
$dataPath = Join-Path $PSScriptRoot '..\sql\base-data.sql'
|
||||||
|
|
||||||
|
function Invoke-MySqlFile([string]$filePath) {
|
||||||
|
Write-Host ("Processing SQL file: {0}" -f $filePath)
|
||||||
|
$sql = Get-Content -Raw $filePath
|
||||||
|
# Strip UTF-8 BOM if present
|
||||||
|
$bom = [char]0xFEFF
|
||||||
|
if ($sql.StartsWith($bom)) { $sql = $sql.Substring(1) }
|
||||||
|
# Sanitize dump headers and environment-specific statements
|
||||||
|
$lines = $sql -split "`r?`n"
|
||||||
|
$cleanLines = $lines | Where-Object {
|
||||||
|
$t = $_.Trim()
|
||||||
|
if ($t -eq '') { return $false }
|
||||||
|
if ($t -match '^(--|/\*|\*/|/\*!|[-]+$)') { return $false }
|
||||||
|
if ($t -match '^USE\s+') { return $false }
|
||||||
|
if ($t -match '^CREATE\s+DATABASE') { return $false }
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
$cleanSql = ($cleanLines -join "`n")
|
||||||
|
if ([string]::IsNullOrWhiteSpace($cleanSql)) {
|
||||||
|
Write-Warning ("Sanitized script is empty, skipping: {0}" -f $filePath)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Write-Host ("Importing via mysql from: {0}" -f $filePath)
|
||||||
|
$cleanSql | & mysql -h $DB_HOST -P $DB_PORT -u $DB_USER $DB_NAME
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
throw ("Import failed for {0} with exit code {1}" -f $filePath, $LASTEXITCODE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Invoke-MySqlFile $schemaPath
|
||||||
|
Invoke-MySqlFile $dataPath
|
||||||
|
|
||||||
|
Write-Host 'Import completed'
|
||||||
139
framework/docs/Java框架项目技术文档.md
Normal file
139
framework/docs/Java框架项目技术文档.md
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
# 项目技术文档(framework 模块)
|
||||||
|
|
||||||
|
> 运行环境:Windows,Java 21(兼容 17+),Spring Boot 3.3.x
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
- 平台型后端服务,采用 `Spring Boot 3.3.x`,区分 `dev` / `server` 两种运行配置。
|
||||||
|
- 数据访问:`MyBatis-Plus 3.5.6` + `MyBatis 3.5.16`;连接池:`Druid`。
|
||||||
|
- 任务调度:`Quartz 2.3.2`;API 文档:`springdoc-openapi`(Swagger UI)。
|
||||||
|
- 缓存与基础设施:`Redis`、`WebSocket`、`Actuator`、验证码(`easy-captcha`)、加密(`jasypt`)、`ip2region`、`hutool` 等。
|
||||||
|
- 打包方式:可执行 `JAR`(已启用 `spring-boot-maven-plugin` 的 `repackage`)。默认开发端口 `8093`(`server` 可使用 `8090`)。
|
||||||
|
|
||||||
|
## 目录结构
|
||||||
|
- 仓库根(当前工作目录):`D:\JavaProjectSpace\framework`
|
||||||
|
- 主要结构:
|
||||||
|
```
|
||||||
|
framework/
|
||||||
|
├── Dockerfile
|
||||||
|
├── frontend/ # 前端源码(Vite + TypeScript + Tailwind)
|
||||||
|
├── pom.xml # Maven 构建管理
|
||||||
|
└── src/
|
||||||
|
├── main/
|
||||||
|
│ ├── java/ # 业务代码(入口类在 com.yfd.platform.*)
|
||||||
|
│ └── resources/ # 配置与静态资源(static、配置 YAML、日志)
|
||||||
|
└── test/
|
||||||
|
└── java/ # 测试代码
|
||||||
|
```
|
||||||
|
|
||||||
|
## 快速开始
|
||||||
|
- 前置要求:
|
||||||
|
- 安装 `JDK 21`(兼容 17+)、`Maven 3.9+`、`Git`、`Node.js 18+`(前端构建)。
|
||||||
|
- Windows 终端建议执行 `chcp 65001`,确保 UTF-8 编码输出。
|
||||||
|
- 构建后端:
|
||||||
|
- `mvn clean package -DskipTests`
|
||||||
|
- 本地运行(dev):
|
||||||
|
- `java -jar target/platform-1.0.jar --spring.profiles.active=dev`
|
||||||
|
- 运行(server):
|
||||||
|
- `java -jar target/platform-1.0.jar --spring.profiles.active=server`
|
||||||
|
- API 文档:
|
||||||
|
- 访问 `http://localhost:8093/swagger-ui/index.html`(以实际配置为准)
|
||||||
|
|
||||||
|
## 前端集成
|
||||||
|
- 自动构建:Maven 在 `generate-resources` 阶段调用 `npm install` 与 `npm run build:mvn`,产物输出到 `frontend/dist`。
|
||||||
|
- 静态资源复制:可通过 `maven-resources-plugin` 将 `frontend/dist` 复制至 `src/main/resources/static`,如需开启请将 POM 中该插件的 `<skip>` 设置为 `false` 或按需配置 Profile。
|
||||||
|
- 单独构建:在 `framework/frontend` 目录手动执行 `npm install && npm run build`,然后复制 `dist/` 到后端静态目录。
|
||||||
|
|
||||||
|
## 配置说明
|
||||||
|
- Profile 切换:通过 `--spring.profiles.active=<dev|server>` 激活环境。
|
||||||
|
- 关键属性:
|
||||||
|
- `file-space.system`:文件根路径,需在激活的 profile 中配置。
|
||||||
|
- `spring.datasource.druid.*`:数据库连接与池化参数。
|
||||||
|
- `server.port`:端口(`dev` 默认 8093,`server` 可使用 8090)。
|
||||||
|
- 编码与 JVM 参数:
|
||||||
|
- 统一 JVM 编码:`-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8`(POM 已配置)。
|
||||||
|
- PowerShell 输出建议设为 UTF-8:`chcp 65001`。
|
||||||
|
|
||||||
|
## 依赖与版本
|
||||||
|
- Spring:`spring-boot-starter-web`、`security`、`cache`、`websocket`、`actuator`。
|
||||||
|
- 数据访问:`mybatis-spring-boot-starter`、`mybatis-plus-boot-starter`、`druid-spring-boot-starter`、`mysql-connector-j`、`sqlite-jdbc`。
|
||||||
|
- 工具与增强:`hutool-all`、`poi` / `poi-ooxml`、`fastjson`、`freemarker`、`jsoup`、`jasypt`、`ip2region`、`easy-captcha`、`UserAgentUtils`、`nashorn-core`。
|
||||||
|
- 文档:`springdoc-openapi-starter-webmvc-ui`(Swagger UI)。
|
||||||
|
- 构建管控:`maven-enforcer-plugin`(JDK≥17、Maven≥3.6.3)。
|
||||||
|
|
||||||
|
## 数据库配置示例
|
||||||
|
- MySQL 连接:
|
||||||
|
```yaml
|
||||||
|
spring:
|
||||||
|
datasource:
|
||||||
|
druid:
|
||||||
|
master:
|
||||||
|
url: jdbc:mysql://<host>:3306/<db>?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&useSSL=false&allowPublicKeyRetrieval=true
|
||||||
|
username: <user>
|
||||||
|
password: <password>
|
||||||
|
```
|
||||||
|
- 授权建议:
|
||||||
|
```sql
|
||||||
|
CREATE USER 'appuser'@'%' IDENTIFIED BY 'StrongPassword!';
|
||||||
|
GRANT ALL PRIVILEGES ON <db>.* TO 'appuser'@'%';
|
||||||
|
FLUSH PRIVILEGES;
|
||||||
|
```
|
||||||
|
- Druid 健壮性:
|
||||||
|
```yaml
|
||||||
|
spring:
|
||||||
|
datasource:
|
||||||
|
druid:
|
||||||
|
initial-size: 0
|
||||||
|
test-on-borrow: false
|
||||||
|
test-while-idle: true
|
||||||
|
validation-query: SELECT 1
|
||||||
|
```
|
||||||
|
|
||||||
|
## 日志与监控
|
||||||
|
- 日志:Logback(UTF-8 输出),推荐格式:`%d [%thread] %-5level %logger{50} - %msg%n`。
|
||||||
|
- 监控:启用 Actuator,健康检查路径:`/actuator/health`。
|
||||||
|
- 建议接入集中日志与指标采集(ELK / Vector),监控数据库与线程池(Druid / Quartz)。
|
||||||
|
|
||||||
|
## 定时任务
|
||||||
|
- 默认 `RAMJobStore`(非集群、内存存储)。
|
||||||
|
- 如需持久化与集群,改用 `JdbcJobStore` 并配置数据源与表结构。
|
||||||
|
|
||||||
|
## 安全与鉴权
|
||||||
|
- 采用 JWT 进行鉴权(如 `jwtAuthenticationTokenFilter`,按实际代码启用)。
|
||||||
|
- 敏感配置(`jwt.secret`、数据库密码)通过环境变量或外部密钥管理。
|
||||||
|
- 生产环境建议启用 HTTPS 并使用强密钥。
|
||||||
|
|
||||||
|
## Docker 部署
|
||||||
|
- 端口:默认暴露 `8093`(dev);可在 `server` profile 使用 `8090`。
|
||||||
|
- 基本流程:
|
||||||
|
- 构建镜像:`docker build -t projectframework-app:latest .`
|
||||||
|
- 运行(开发环境):`docker run -d --name platform-app -p 8093:8093 -e SPRING_PROFILES_ACTIVE=dev projectframework-app:latest`
|
||||||
|
- 运行(服务器环境):`docker run -d --name platform-app -p 8090:8090 -e SPRING_PROFILES_ACTIVE=server projectframework-app:latest`
|
||||||
|
- 文件空间挂载示例:`-v D:/data/file-space:/data/file-space -e FILE_SPACE_SYSTEM=/data/file-space`
|
||||||
|
|
||||||
|
## Git 使用(框架分支)
|
||||||
|
- 远程仓库:根据实际仓库地址配置(示例:`http://121.37.111.42:3000/ThbTech/JavaProjectRepo.git`)。
|
||||||
|
- 分支建议:`main-framework`(稳定分支)、`develop-framework`(开发分支)。
|
||||||
|
- 常用命令:`git pull`、`git add .`、`git commit -m "<message>"`、`git push`。
|
||||||
|
- 提交署名:`git config user.name "<Your Name>"`,`git config user.email "<your@email>"`。
|
||||||
|
|
||||||
|
## CI/CD 建议
|
||||||
|
- CI 阶段:`mvn -B -DskipTests clean package`,配合单元测试与安全扫描(依赖检查、代码质量)。
|
||||||
|
- CD 阶段:推送镜像到私有仓库,使用环境变量注入敏感信息。
|
||||||
|
|
||||||
|
## 常见问题
|
||||||
|
- 中文乱码:执行 `chcp 65001`,确保 `logback-spring.xml` 使用 UTF-8。
|
||||||
|
- `NoSuchMethodError`(MyBatis):升级到 `MyBatis 3.5.16+` 并与 MP 版本匹配。
|
||||||
|
- 数据库 `Access denied`:校验账户密码与远程授权;必要时新建业务账户并放开 `3306`。
|
||||||
|
- 端口占用/启动失败:检查 `server.port` 与冲突端口;查看应用日志定位根因。
|
||||||
|
- 前端构建问题:如遇 npm 依赖警告或复制冲突,可先独立构建并手动复制 `dist/`。
|
||||||
|
|
||||||
|
## 变更日志(模板)
|
||||||
|
- `feat:` 新增功能说明
|
||||||
|
- `fix:` 缺陷修复说明
|
||||||
|
- `docs:` 文档更新说明
|
||||||
|
- `refactor:` 重构说明
|
||||||
|
- `perf:` 性能优化说明
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
如需扩展专题文档(接口规范、部署拓扑、参数字典等),请在 `docs/` 目录继续维护并与版本管理同步。
|
||||||
141
framework/docs/develop分支Git操作指南.md
Normal file
141
framework/docs/develop分支Git操作指南.md
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
# develop-framework 分支 Git 操作指南(面向 main-framework 主分支)
|
||||||
|
|
||||||
|
> 适用范围:`D:/JavaProjectSpace/framework` 项目(Spring Boot 3.3.x,可执行 JAR),远程仓库:`http://121.37.111.42:3000/ThbTech/JavaProjectRepo.git`
|
||||||
|
> 主分支:`main-framework`;开发分支:`develop-framework`
|
||||||
|
|
||||||
|
## 分支策略与目标
|
||||||
|
- `main-framework`:稳定发布分支,受保护(建议启用 PR 合并、代码审查、CI 通过)。
|
||||||
|
- `develop-framework`:日常开发分支,合并至主分支前需完成构建与自测。
|
||||||
|
- 推荐临时特性分支:`feature/<name>` 从 `develop-framework` 拉出,完成后合并回 `develop-framework`。
|
||||||
|
|
||||||
|
## 初始仓库设置
|
||||||
|
- 设置用户信息(确保提交署名一致):
|
||||||
|
```
|
||||||
|
git config user.name "zhengsl"
|
||||||
|
git config user.email "13910913995@163.com"
|
||||||
|
```
|
||||||
|
- 关联远程(如已有请忽略):
|
||||||
|
```
|
||||||
|
git remote set-url origin http://121.37.111.42:3000/ThbTech/JavaProjectRepo.git
|
||||||
|
```
|
||||||
|
- 拉取远程分支列表并跟踪:
|
||||||
|
```
|
||||||
|
git fetch --all --prune
|
||||||
|
```
|
||||||
|
|
||||||
|
## 开发日常流程(在 develop-framework)
|
||||||
|
- 切换到开发分支并更新:
|
||||||
|
```
|
||||||
|
git checkout develop-framework
|
||||||
|
git pull --ff-only
|
||||||
|
```
|
||||||
|
- 提交更改(遵循约定式提交,示例):
|
||||||
|
```
|
||||||
|
git add .
|
||||||
|
git commit -m "feat: 支持可执行JAR打包并优化资源复制逻辑"
|
||||||
|
```
|
||||||
|
|
||||||
|
- 推送到远程:
|
||||||
|
```
|
||||||
|
git push -u origin develop-framework
|
||||||
|
```
|
||||||
|
|
||||||
|
## 合并到主分支(首选 PR 流程)
|
||||||
|
- 方式一:在 Gitea 发起 PR(推荐)
|
||||||
|
- 目标:`develop-framework` -> `main-framework`
|
||||||
|
- 检查 CI 构建通过、代码评审通过后合并。
|
||||||
|
- 合并策略建议:`Squash` 或 `Rebase and merge` 保持主分支提交整洁。
|
||||||
|
|
||||||
|
|
||||||
|
## 版本与标签(发布规范)
|
||||||
|
- 采用语义化版本:`vMAJOR.MINOR.PATCH`(示例:`v1.0.0`)。
|
||||||
|
- 打标签并推送:
|
||||||
|
```
|
||||||
|
# 核心检查:构建通过、基本功能自测 OK
|
||||||
|
mvn -B -DskipTests clean package
|
||||||
|
|
||||||
|
# 标签与推送
|
||||||
|
git tag -a v1.0.0 -m "release: framework v1.0.0 可执行JAR"
|
||||||
|
git push origin v1.0.0
|
||||||
|
```
|
||||||
|
|
||||||
|
## 构建校验(必须)
|
||||||
|
- 本地快速验证:
|
||||||
|
```
|
||||||
|
# 打包
|
||||||
|
mvn -q -DskipTests package
|
||||||
|
# 启动(dev)
|
||||||
|
java -jar target/platform-1.0.jar --spring.profiles.active=dev
|
||||||
|
# 浏览器访问(默认端口)
|
||||||
|
http://localhost:8093/
|
||||||
|
```
|
||||||
|
- 如果使用前端集成:
|
||||||
|
- POM 已配置在 `generate-resources` 阶段执行 `npm install` 与 `npm run build:mvn`。
|
||||||
|
- 静态资源复制(`frontend/dist` -> `src/main/resources/static`)可通过 `maven-resources-plugin` 控制;必要时启用/关闭 `<skip>` 或使用 Maven Profile 控制。
|
||||||
|
|
||||||
|
## 分支保护与权限(建议在 Gitea 设置)
|
||||||
|
- 保护 `main-framework`:
|
||||||
|
- 禁止直接 push 到主分支,仅允许通过 PR 合并。
|
||||||
|
- 最少 1 人审核,CI 必须通过。
|
||||||
|
- 禁止强制推送(force push)。
|
||||||
|
- 标签权限:仅发布管理员可打 `release` 标签。
|
||||||
|
|
||||||
|
## 常见场景与命令速查
|
||||||
|
- 同步远程状态(清理过期分支):
|
||||||
|
```
|
||||||
|
git fetch --all --prune
|
||||||
|
```
|
||||||
|
- 创建特性分支:
|
||||||
|
```
|
||||||
|
git checkout develop-framework
|
||||||
|
git pull --ff-only
|
||||||
|
git checkout -b feature/<name>
|
||||||
|
```
|
||||||
|
- 将特性分支合并回开发分支:
|
||||||
|
```
|
||||||
|
git checkout develop-framework
|
||||||
|
git merge --no-ff feature/<name>
|
||||||
|
git push origin develop-framework
|
||||||
|
```
|
||||||
|
- 更新主分支并合并开发分支(CLI):
|
||||||
|
```
|
||||||
|
git checkout main-framework
|
||||||
|
git pull --ff-only
|
||||||
|
git merge --ff-only develop-framework || git merge --no-ff develop-framework
|
||||||
|
git push origin main-framework
|
||||||
|
```
|
||||||
|
- 回滚错误提交:
|
||||||
|
```
|
||||||
|
# 回滚指定提交(保留历史)
|
||||||
|
git revert <commit_sha>
|
||||||
|
# 或回退到某版本(谨慎,可能重写历史)
|
||||||
|
git reset --hard <commit_sha>
|
||||||
|
git push -f origin <branch> # 若分支受保护,需取消保护或走 PR revert
|
||||||
|
```
|
||||||
|
|
||||||
|
## 冲突处理指南
|
||||||
|
- Rebase 阶段冲突:
|
||||||
|
- 编辑冲突文件,确保以 `main-framework` 为基线保留正确逻辑。
|
||||||
|
- 逐个解决后:`git add <file>`,继续:`git rebase --continue`。
|
||||||
|
- Merge 阶段冲突:
|
||||||
|
- 优先在 `develop-framework` 解决,再合并到 `main-framework`,减少主分支污染。
|
||||||
|
|
||||||
|
## 提交规范建议(Conventional Commits)
|
||||||
|
- 前缀示例:`feat`、`fix`、`docs`、`refactor`、`perf`、`test`、`build`、`chore`。
|
||||||
|
- 示例:`feat: 前端静态资源复制支持 Profile 开关`。
|
||||||
|
|
||||||
|
## CI/CD 建议
|
||||||
|
- CI:
|
||||||
|
- `mvn -B -DskipTests clean package`
|
||||||
|
- 单元测试、依赖安全扫描、代码质量检查
|
||||||
|
- CD:
|
||||||
|
- 根据标签构建镜像,注入敏感配置(环境变量/密钥管理)。
|
||||||
|
|
||||||
|
## 问题排查
|
||||||
|
- 构建失败:检查 `pom.xml` 插件配置,先本地运行 `mvn -e package` 查看详细栈。
|
||||||
|
- 端口冲突:调整 `server.port` 或释放占用端口。
|
||||||
|
- npm 警告/冲突:在 `frontend/` 内单独 `npm install && npm run build`,再复制到后端静态目录。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
如需将资源复制与文档生成改为按需开关(Maven Profile),可在 `pom.xml` 中添加 Profile 并通过 `-P <profile>` 控制。需要我帮助你落地 Profile 与分支保护脚本,请告诉我你的偏好(例如是否必须走 PR)。
|
||||||
@ -1,52 +0,0 @@
|
|||||||
# 前后端一体化构建与打包说明
|
|
||||||
|
|
||||||
本文档说明如何在 Maven 构建流程中,先编译前端(pnpm),再编译后端(Java),并在 `package` 阶段将两者一起打包,使生成的可运行 `jar/war` 直接可以访问前端首页 `index.html`。
|
|
||||||
|
|
||||||
## 前置要求
|
|
||||||
- 已安装 JDK(推荐 17+)和 Maven(3.6.3+)。
|
|
||||||
- 已安装 Node.js(推荐 18+)与 pnpm(全局):`npm i -g pnpm`。
|
|
||||||
- 当前项目结构:
|
|
||||||
- 后端(Spring Boot):`app/pom.xml`,源码在 `app/src/main/java` 与资源在 `app/src/main/resources`。
|
|
||||||
- 前端(Vite/Vue):位于 `app/frontend`,构建输出目录默认是 `app/frontend/dist`。
|
|
||||||
|
|
||||||
## 构建流程概览
|
|
||||||
在 `pom.xml` 中集成了以下步骤:
|
|
||||||
1. `generate-resources` 阶段:进入 `frontend` 目录,执行 `pnpm install --frozen-lockfile` 与 `pnpm run build`。
|
|
||||||
2. `process-resources` 阶段:将前端构建产物从 `frontend/dist` 复制到后端资源目录 `src/main/resources/static`。
|
|
||||||
3. 随后执行后端 Java 编译与打包,最终产出可运行的 `jar/war`。
|
|
||||||
|
|
||||||
这样在运行后端时,Spring Boot 会从类路径的 `static` 目录自动提供 `index.html` 作为欢迎页入口(访问根路径 `/` 即可看到前端页面)。
|
|
||||||
|
|
||||||
## 关键 POM 配置(摘要)
|
|
||||||
已经在 `app/pom.xml` 的 `<build><plugins>` 中加入:
|
|
||||||
- `exec-maven-plugin`:在 Java 编译前执行 pnpm 安装与构建。
|
|
||||||
- `maven-resources-plugin`:复制前端构建产物到 `src/main/resources/static`。
|
|
||||||
|
|
||||||
无需手动改动目录,只需按下述命令执行即可。
|
|
||||||
|
|
||||||
## 常用命令
|
|
||||||
- 开发运行(跳过测试):`mvn -DskipTests spring-boot:run`
|
|
||||||
- 如需指定开发配置:`mvn -DskipTests -Dspring-boot.run.profiles=dev spring-boot:run`
|
|
||||||
- 构建打包(跳过测试):`mvn -DskipTests package`
|
|
||||||
- 构建过程中会自动执行前端构建并拷贝到后端资源。
|
|
||||||
|
|
||||||
## 运行与访问
|
|
||||||
- 运行可执行包(以 `war` 为例,`artifactId=platform`,`version=1.0`):
|
|
||||||
- 默认运行:`java -jar target/platform-1.0.war`
|
|
||||||
- 指定 dev 配置:`java -Dspring.profiles.active=dev -jar target/platform-1.0.war`
|
|
||||||
- 访问:
|
|
||||||
- 若启用 `dev` 配置并端口为 `8093`:`http://localhost:8093/`
|
|
||||||
- 若使用默认端口(例如 `18080`):`http://localhost:18080/`
|
|
||||||
|
|
||||||
> 说明:Spring Boot 会自动将 `classpath:/static/index.html` 作为欢迎页,访问根路径即可进入前端入口页面。
|
|
||||||
|
|
||||||
## 注意事项
|
|
||||||
- 请确保 `pnpm` 可在构建机/开发机的环境变量中直接调用。
|
|
||||||
- 若前端构建输出目录(`dist`)有自定义,请同步更新 POM 中的复制路径。
|
|
||||||
- 如前端使用路由的 `history` 模式并期望后端兜底到 `index.html`,可按需添加后端控制器或使用前端服务器侧配置(当前方案以静态欢迎页为主)。
|
|
||||||
|
|
||||||
## 故障排查
|
|
||||||
- 构建失败(找不到 `pnpm`):确认已安装并可在命令行执行 `pnpm -v`。
|
|
||||||
- 页面乱码:已在 POM 配置统一 JVM 编码为 `UTF-8`;在 Windows PowerShell 终端也应设置为 `UTF-8`。
|
|
||||||
|
|
||||||
完成上述配置后,只需使用 Maven 的标准命令,即可实现前后端一体化构建和打包运行。
|
|
||||||
@ -1,161 +0,0 @@
|
|||||||
# 项目技术文档
|
|
||||||
|
|
||||||
> 项目:ProjectFrameWork2025(模块:`app` / Java 后端)
|
|
||||||
> 运行环境:Windows,Java 21(兼容 17+),Spring Boot 3.x
|
|
||||||
|
|
||||||
## 概述
|
|
||||||
- 平台型后端服务,采用 `Spring Boot 3.x`,区分 `dev` / `server` 两种运行配置。
|
|
||||||
- 数据访问使用 `MyBatis-Plus 3.5.6` 与 `MyBatis 3.5.16`,连接池为 `Druid`。
|
|
||||||
- 任务调度使用 `Quartz 2.3.2`;API 文档采用 `springdoc-openapi` / Swagger UI。
|
|
||||||
- 支持 WAR 包运行,亦可容器化部署;默认开发端口 `8093`(`server` 可使用 `8090`)。
|
|
||||||
|
|
||||||
## 目录结构
|
|
||||||
- 仓库根(当前工作目录):`D:\Trae_space\ProjectFrameWork2025\app`
|
|
||||||
- 主要结构:
|
|
||||||
```
|
|
||||||
app/
|
|
||||||
├── .gitignore
|
|
||||||
├── Dockerfile
|
|
||||||
├── frontend/ # 前端说明或资源
|
|
||||||
│ └── readme.md
|
|
||||||
├── pom.xml # Maven 构建管理
|
|
||||||
└── src/
|
|
||||||
├── main/
|
|
||||||
│ ├── java/ # 业务代码(入口类在 com.yfd.platform.*)
|
|
||||||
│ └── resources/ # 配置与静态资源
|
|
||||||
└── test/
|
|
||||||
└── java/ # 测试代码
|
|
||||||
```
|
|
||||||
|
|
||||||
## 快速开始
|
|
||||||
- 前置要求:
|
|
||||||
- 安装 `JDK 21`(兼容 17+),`Maven 3.9+`,`Git`。
|
|
||||||
- Windows 终端执行 `chcp 65001`,确保 UTF-8 编码输出。
|
|
||||||
- 构建后端:
|
|
||||||
- `mvn clean package -DskipTests`
|
|
||||||
- 本地运行(dev):
|
|
||||||
- `java -jar target/platform-1.0.war --spring.profiles.active=dev`
|
|
||||||
- 运行(server):
|
|
||||||
- `java -jar target/platform-1.0.war --spring.profiles.active=server`
|
|
||||||
- API 文档:
|
|
||||||
- 默认访问 `http://localhost:8093/swagger-ui/index.html`(以实际配置为准)
|
|
||||||
|
|
||||||
## 配置说明
|
|
||||||
- Profile 切换:
|
|
||||||
- 通过 `--spring.profiles.active=<dev|server>` 激活环境。
|
|
||||||
- 关键属性:
|
|
||||||
- `file-space.system`:文件根路径,需在激活的 profile 中配置。
|
|
||||||
- `spring.datasource.druid.*`:数据库连接参数与池化配置。
|
|
||||||
- `server.port`:端口(`dev` 默认 8093,`server` 可使用 8090)。
|
|
||||||
- VS Code/终端编码建议:
|
|
||||||
- 启动参数加入 `-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8`。
|
|
||||||
- 终端执行 `chcp 65001`,PowerShell 输出设置为 UTF-8。
|
|
||||||
|
|
||||||
## 依赖与版本
|
|
||||||
- `Spring Boot 3.x`
|
|
||||||
- `MyBatis-Plus 3.5.6`(依赖 `MyBatis 3.5.16+`,需有 `Configuration.parsePendingResultMaps(boolean)`)
|
|
||||||
- `Druid` 数据源
|
|
||||||
- `Quartz 2.3.2`
|
|
||||||
- `springdoc-openapi` / Swagger UI
|
|
||||||
- 日志:`Logback`(UTF-8 输出,`logback-spring.xml`)
|
|
||||||
|
|
||||||
## 数据库配置
|
|
||||||
- MySQL 连接示例:
|
|
||||||
```yaml
|
|
||||||
spring:
|
|
||||||
datasource:
|
|
||||||
druid:
|
|
||||||
master:
|
|
||||||
url: jdbc:mysql://<host>:3306/<db>?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&useSSL=false&allowPublicKeyRetrieval=true
|
|
||||||
username: <user>
|
|
||||||
password: <password>
|
|
||||||
```
|
|
||||||
- 远程授权建议:
|
|
||||||
```sql
|
|
||||||
CREATE USER 'appuser'@'%' IDENTIFIED BY 'StrongPassword!';
|
|
||||||
GRANT ALL PRIVILEGES ON <db>.* TO 'appuser'@'%';
|
|
||||||
FLUSH PRIVILEGES;
|
|
||||||
```
|
|
||||||
- Druid 健壮性:
|
|
||||||
```yaml
|
|
||||||
spring:
|
|
||||||
datasource:
|
|
||||||
druid:
|
|
||||||
initial-size: 0
|
|
||||||
test-on-borrow: false
|
|
||||||
test-while-idle: true
|
|
||||||
validation-query: SELECT 1
|
|
||||||
```
|
|
||||||
|
|
||||||
## 日志
|
|
||||||
- 控制台与文件统一 UTF-8 输出:
|
|
||||||
- 控制台 `ConsoleAppender`,文件 `RollingFileAppender`(按日滚动,保留 30 天)。
|
|
||||||
- 推荐日志格式:`%d [%thread] %-5level %logger{50} - %msg%n`。
|
|
||||||
|
|
||||||
## 定时任务
|
|
||||||
- 默认 `RAMJobStore`(非集群、内存存储)。
|
|
||||||
- 如需持久化与集群,改用 `JdbcJobStore` 并配置数据源与表结构。
|
|
||||||
|
|
||||||
## 安全与鉴权
|
|
||||||
- 使用 `JWT` 过滤器进行鉴权(如 `jwtAuthenticationTokenFilter`)。
|
|
||||||
- 敏感配置(`jwt.secret`、数据库密码)建议通过环境变量或外部密钥管理。
|
|
||||||
- 生产环境必须启用 HTTPS 并使用强密钥。
|
|
||||||
|
|
||||||
## API 文档
|
|
||||||
- 启用 `swagger-ui.enabled: true`。
|
|
||||||
- 访问路径通常为 `http://<host>:<port>/swagger-ui/index.html`。
|
|
||||||
|
|
||||||
## Docker 部署
|
|
||||||
- `Dockerfile` 已暴露端口 `8093`:
|
|
||||||
- 构建镜像:`docker build -t projectframework2025-app:latest .`
|
|
||||||
- 运行(开发环境):
|
|
||||||
- `docker run -d --name platform-app -p 8093:8093 -e SPRING_PROFILES_ACTIVE=dev projectframework2025-app:latest`
|
|
||||||
- 运行(服务器环境):
|
|
||||||
- `docker run -d --name platform-app -p 8090:8090 -e SPRING_PROFILES_ACTIVE=server projectframework2025-app:latest`
|
|
||||||
- 如需挂载文件空间:
|
|
||||||
- `-v D:/data/file-space:/data/file-space -e FILE_SPACE_SYSTEM=/data/file-space`
|
|
||||||
|
|
||||||
## 前端
|
|
||||||
- 前端说明见 `frontend/readme.md`。如需联调,请统一跨域与鉴权策略。
|
|
||||||
|
|
||||||
## Git 使用
|
|
||||||
- 远程仓库:`http://121.37.111.42:3000/ThbTech/ProjectFrameWork2025.git`
|
|
||||||
- 主分支:`main`
|
|
||||||
- 常用命令:
|
|
||||||
- `git pull`、`git add .`、`git commit -m "<message>"`、`git push`
|
|
||||||
- 提交署名:
|
|
||||||
- `git config user.name "<Your Name>"`
|
|
||||||
- `git config user.email "<your@email>"`
|
|
||||||
|
|
||||||
## 常见问题
|
|
||||||
- 中文乱码:
|
|
||||||
- 执行 `chcp 65001`,确保 `logback-spring.xml` 使用 UTF-8。
|
|
||||||
- `NoSuchMethodError`(MyBatis):
|
|
||||||
- 升级 `MyBatis` 至 `3.5.16+` 并与 MP 版本匹配。
|
|
||||||
- 数据库 `Access denied`:
|
|
||||||
- 校验账户密码与远程授权;必要时新建业务账户并放开 `3306`。
|
|
||||||
- 端口占用/启动失败:
|
|
||||||
- 检查 `server.port` 与冲突端口;查看应用日志定位根因。
|
|
||||||
|
|
||||||
## 运维与监控
|
|
||||||
- 建议接入 `Spring Boot Actuator`:`/actuator/health`。
|
|
||||||
- 配合日志轮转与集中采集(ELK/Vector),区分环境日志路径。
|
|
||||||
- 监控数据库与线程池指标(Druid/Quartz)。
|
|
||||||
|
|
||||||
## CI/CD 建议
|
|
||||||
- 在 CI 阶段执行:
|
|
||||||
- `mvn -B -DskipTests clean package`
|
|
||||||
- 单元测试与安全扫描(依赖检查、代码质量)
|
|
||||||
- 在 CD 阶段:
|
|
||||||
- 推送镜像到私有仓库,环境变量注入敏感信息。
|
|
||||||
|
|
||||||
## 变更日志(示例模板)
|
|
||||||
- `feat:` 新增功能说明
|
|
||||||
- `fix:` 缺陷修复说明
|
|
||||||
- `docs:` 文档更新说明
|
|
||||||
- `refactor:` 重构说明
|
|
||||||
- `perf:` 性能优化说明
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
如需扩展专题文档(接口规范、部署拓扑、参数字典等),建议在 `docs/` 目录继续维护并与版本管理同步。
|
|
||||||
134
framework/docs/数据库初始方案.md
Normal file
134
framework/docs/数据库初始方案.md
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
# 数据库初始方案(framework)
|
||||||
|
|
||||||
|
## 目标
|
||||||
|
- 在 `framework` 目录下建立 `db-init` 初始化目录,保存基础结构与基础数据。
|
||||||
|
- 支持从 MySQL 导出一份“初始化用”的基线数据,并在应用启动时自动检测是否已初始化;若未初始化,自动导入。
|
||||||
|
- 过程可重复、可审计、可在 `dev` 与 `server` 环境下安全运行。
|
||||||
|
|
||||||
|
## 目录结构规划
|
||||||
|
- `framework/db-init/`
|
||||||
|
- `sql/`
|
||||||
|
- `base-schema.sql`:基础库结构(表、索引、约束);可由 `mysqldump --no-data` 导出。
|
||||||
|
- `base-data.sql`:初始化数据(字典、默认角色、管理员等);可由 `mysqldump --no-create-info` 导出或手写。
|
||||||
|
- `scripts/`
|
||||||
|
- `export.ps1`:Windows 导出脚本(PowerShell)。
|
||||||
|
- `import.ps1`:Windows 导入脚本(PowerShell)。
|
||||||
|
- `export.sh`:Linux/Mac 导出脚本(可选)。
|
||||||
|
- `import.sh`:Linux/Mac 导入脚本(可选)。
|
||||||
|
- `README.md`:说明如何导出/导入、注意事项与环境变量。
|
||||||
|
|
||||||
|
## MySQL 导出策略
|
||||||
|
- 推荐使用 `mysqldump` 分离结构与数据,以便初始化时灵活控制:
|
||||||
|
- 结构:`mysqldump -h$DB_HOST -P$DB_PORT -u$DB_USER -p$DB_PASSWORD --no-data --databases $DB_NAME > sql/base-schema.sql`
|
||||||
|
- 数据:`mysqldump -h$DB_HOST -P$DB_PORT -u$DB_USER -p$DB_PASSWORD --no-create-info --databases $DB_NAME --tables <白名单表> > sql/base-data.sql`
|
||||||
|
- 数据白名单建议包含:
|
||||||
|
- 字典/配置表(如 `sys_dict`, `sys_config`)
|
||||||
|
- 权限/角色/菜单(如 `sys_user`(仅管理员)、`sys_role`, `sys_menu`, `sys_user_role`, `sys_role_menu`)
|
||||||
|
- 地区或静态映射表(如有)
|
||||||
|
- 机密信息与动态数据不导出:
|
||||||
|
- 排除审计日志、任务运行记录、业务动态表等。
|
||||||
|
|
||||||
|
## 导入策略
|
||||||
|
- 应用启动时进行“初始化检测”:
|
||||||
|
- 建议引入标记表:`app_init`(单行),字段 `initialized boolean`, `version varchar`,或在 `sys_config` 中维护 `init_done` 键。
|
||||||
|
- 检测逻辑:
|
||||||
|
- 若标记不存在或值为 `false`,视为未初始化。
|
||||||
|
- 若存在且为 `true`,跳过初始化。
|
||||||
|
- 导入步骤(未初始化时):
|
||||||
|
- 执行 `base-schema.sql`(若目标库为空或需校正结构时)。
|
||||||
|
- 执行 `base-data.sql`(插入/更新缺失的基线数据,注意幂等性)。
|
||||||
|
- 更新标记为已初始化,并记录版本与时间戳。
|
||||||
|
- 幂等性建议:
|
||||||
|
- 数据插入使用“存在则跳过/更新”策略(`INSERT ... ON DUPLICATE KEY UPDATE` 或先查询再写入)。
|
||||||
|
- 避免覆盖已有业务数据;仅在缺失时补充。
|
||||||
|
|
||||||
|
## Spring Boot 集成方案
|
||||||
|
- 方案 A(轻量):在后端增加初始化 Runner
|
||||||
|
- 新增一个 `@Component` 实现 `ApplicationRunner` 或 `CommandLineRunner` 的 `DataInitializer`。
|
||||||
|
- 启动时:检查标记 → 未初始化则依次执行 `sql/base-schema.sql` 与 `sql/base-data.sql`。
|
||||||
|
- SQL 执行方式:
|
||||||
|
- 直接通过 JDBC 读取并执行 SQL 文件(分号切分、事务包裹、失败回滚)。
|
||||||
|
- 或调用外部 `mysql` 命令(需服务器已安装 `mysql` 客户端,适合运维环境)。
|
||||||
|
- Profile 控制:默认仅在 `server` 或 `dev` 首次运行时启用;可通过配置 `app.init.enabled=true/false` 控制。
|
||||||
|
- 方案 B(推荐中长期):引入数据库版本管理工具
|
||||||
|
- `Flyway` 或 `Liquibase` 管理结构与数据变更;将初始化作为 `V1__base.sql` 脚本。
|
||||||
|
- 优点:变更有版本与校验,部署一致性更强;缺点:需要改造现有 SQL 并纳入流水线。
|
||||||
|
|
||||||
|
## 配置示例
|
||||||
|
- `application-server.yml` 中添加:
|
||||||
|
```
|
||||||
|
app:
|
||||||
|
init:
|
||||||
|
enabled: true
|
||||||
|
schema: classpath:db-init/sql/base-schema.sql
|
||||||
|
data: classpath:db-init/sql/base-data.sql
|
||||||
|
marker-table: app_init
|
||||||
|
marker-version: v1.0.0
|
||||||
|
```
|
||||||
|
- 路径策略:
|
||||||
|
- 若以资源方式打包,建议将 `db-init/sql` 复制到 `src/main/resources/db-init/sql`。
|
||||||
|
- 或保留在项目根并通过绝对/相对路径访问(需考虑部署路径与权限)。
|
||||||
|
|
||||||
|
## 脚本示例(Windows PowerShell)
|
||||||
|
- `framework/db-init/scripts/export.ps1`
|
||||||
|
```
|
||||||
|
param(
|
||||||
|
[string]$DB_HOST = "43.138.168.68",
|
||||||
|
[int]$DB_PORT = 3306,
|
||||||
|
[string]$DB_NAME = "frameworkdb2025",
|
||||||
|
[string]$DB_USER = "root",
|
||||||
|
[string]$DB_PASSWORD = "ylfw20230626@"
|
||||||
|
)
|
||||||
|
|
||||||
|
$env:MYSQL_PWD = $DB_PASSWORD
|
||||||
|
|
||||||
|
# 导出结构
|
||||||
|
mysqldump -h $DB_HOST -P $DB_PORT -u $DB_USER --no-data --databases $DB_NAME > ../sql/base-schema.sql
|
||||||
|
|
||||||
|
# 按需导出数据(示例表名可调整)
|
||||||
|
mysqldump -h $DB_HOST -P $DB_PORT -u $DB_USER --no-create-info $DB_NAME sys_dict sys_config sys_role sys_menu sys_user sys_user_role sys_role_menu > ../sql/base-data.sql
|
||||||
|
|
||||||
|
Write-Host "Export completed: base-schema.sql & base-data.sql"
|
||||||
|
```
|
||||||
|
- `framework/db-init/scripts/import.ps1`
|
||||||
|
```
|
||||||
|
param(
|
||||||
|
[string]$DB_HOST = "127.0.0.1",
|
||||||
|
[int]$DB_PORT = 3306,
|
||||||
|
[string]$DB_NAME = "platform",
|
||||||
|
[string]$DB_USER = "root",
|
||||||
|
[string]$DB_PASSWORD = "root"
|
||||||
|
)
|
||||||
|
|
||||||
|
$env:MYSQL_PWD = $DB_PASSWORD
|
||||||
|
|
||||||
|
mysql -h $DB_HOST -P $DB_PORT -u $DB_USER $DB_NAME < ../sql/base-schema.sql
|
||||||
|
mysql -h $DB_HOST -P $DB_PORT -u $DB_USER $DB_NAME < ../sql/base-data.sql
|
||||||
|
|
||||||
|
Write-Host "Import completed"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 启动时自动初始化的实现建议(代码思路)
|
||||||
|
- 创建 `DataInitializer`:
|
||||||
|
- 读取 `app.init.enabled`;若为 `false` 则直接返回。
|
||||||
|
- 使用 `JdbcTemplate` 或 `EntityManager` 查询 `marker-table` 状态。
|
||||||
|
- 若未初始化:
|
||||||
|
- 读取并执行 `schema`、`data` 指定的 SQL 文件;分批执行并开启事务。
|
||||||
|
- 写入标记表 `initialized=true, version=marker-version, ts=now()`。
|
||||||
|
- 并发保护:
|
||||||
|
- 使用数据库锁或单例启动(例如基于 `SELECT ... FOR UPDATE` 或分布式锁)避免多实例重复初始化。
|
||||||
|
- 失败回滚与告警:
|
||||||
|
- 执行失败时回滚事务并记录日志,提示人工介入;避免部分写入。
|
||||||
|
|
||||||
|
## 运维与审计
|
||||||
|
- 对 `sql/base-data.sql` 的修改应评审并走 PR,避免带入敏感数据。
|
||||||
|
- CI 提示:
|
||||||
|
- 在 `server` 构建流水线中,可增加“初始化脚本语法检查”(如用 `mysql --dry-run` 或解析器)。
|
||||||
|
- 版本管理:
|
||||||
|
- 在 `db-init/README.md` 中记录每次更新目的与影响;或使用 `Flyway` 版本号管理。
|
||||||
|
|
||||||
|
## 下一步落地
|
||||||
|
- 我可以为你:
|
||||||
|
- 搭建 `framework/db-init` 目录与示例脚本、README。
|
||||||
|
- 在后端新增 `DataInitializer` 组件与配置项,支持 `dev/server` 下自动初始化。
|
||||||
|
- 可选集成 `Flyway`,将初始化脚本迁移为 `V1__base.sql` 并接入 CI。
|
||||||
@ -11,7 +11,7 @@
|
|||||||
<groupId>com.yfd</groupId>
|
<groupId>com.yfd</groupId>
|
||||||
<artifactId>platform</artifactId>
|
<artifactId>platform</artifactId>
|
||||||
<version>1.0</version>
|
<version>1.0</version>
|
||||||
<packaging>war</packaging>
|
<packaging>jar</packaging>
|
||||||
<name>platform</name>
|
<name>platform</name>
|
||||||
<description>springboot 项目基础框架3.0</description>
|
<description>springboot 项目基础框架3.0</description>
|
||||||
<properties>
|
<properties>
|
||||||
@ -111,12 +111,7 @@
|
|||||||
<version>${guava.version}</version>
|
<version>${guava.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- spring-内置Tomcat-->
|
<!-- 对于 jar 包,spring-boot-starter-web 已包含嵌入式 Tomcat,无需显式 provided -->
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- spring-quartz任务-->
|
<!-- spring-quartz任务-->
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -367,6 +362,9 @@
|
|||||||
<goal>copy-resources</goal>
|
<goal>copy-resources</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
<overwrite>true</overwrite>
|
||||||
|
<failOnError>false</failOnError>
|
||||||
<outputDirectory>${project.basedir}/src/main/resources/static</outputDirectory>
|
<outputDirectory>${project.basedir}/src/main/resources/static</outputDirectory>
|
||||||
<resources>
|
<resources>
|
||||||
<resource>
|
<resource>
|
||||||
@ -390,6 +388,7 @@
|
|||||||
<goal>process-asciidoc</goal>
|
<goal>process-asciidoc</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
<backend>html</backend>
|
<backend>html</backend>
|
||||||
<doctype>book</doctype>
|
<doctype>book</doctype>
|
||||||
</configuration>
|
</configuration>
|
||||||
@ -411,6 +410,13 @@
|
|||||||
</exclude>
|
</exclude>
|
||||||
</excludes>
|
</excludes>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<!-- 固化构建规则:Maven Enforcer -->
|
<!-- 固化构建规则:Maven Enforcer -->
|
||||||
<plugin>
|
<plugin>
|
||||||
@ -439,26 +445,24 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<!-- 额外生成 classes JAR,便于其他业务工程作为依赖引用 -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.3.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>attach-jar</id>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<classifier>plain</classifier>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<!-- 额外生成 classes JAR,便于其他业务工程作为依赖引用 -->
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
|
||||||
<version>3.3.0</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>attach-jar</id>
|
|
||||||
<goals>
|
|
||||||
<goal>jar</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@ -0,0 +1,17 @@
|
|||||||
|
package com.yfd.platform.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(prefix = "app.init")
|
||||||
|
public class AppInitProperties {
|
||||||
|
private boolean enabled = false;
|
||||||
|
private String schema;
|
||||||
|
private String data;
|
||||||
|
// 用于判断是否已初始化:默认检查是否存在核心表
|
||||||
|
private String markerTable = "sys_user";
|
||||||
|
private String markerVersion = "v1.0.0";
|
||||||
|
}
|
||||||
@ -0,0 +1,129 @@
|
|||||||
|
package com.yfd.platform.config;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.boot.ApplicationArguments;
|
||||||
|
import org.springframework.boot.ApplicationRunner;
|
||||||
|
import org.springframework.context.annotation.Profile;
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.core.io.ResourceLoader;
|
||||||
|
import org.springframework.core.io.support.EncodedResource;
|
||||||
|
import org.springframework.jdbc.datasource.init.ScriptUtils;
|
||||||
|
import org.springframework.jdbc.datasource.init.ScriptException;
|
||||||
|
import org.springframework.jdbc.datasource.init.ScriptStatementFailedException;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import org.springframework.util.StreamUtils;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
@Profile({"dev","server"})
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||||
|
public class DataInitializer implements ApplicationRunner {
|
||||||
|
|
||||||
|
private final DataSource dataSource;
|
||||||
|
private final AppInitProperties properties;
|
||||||
|
private final ResourceLoader resourceLoader;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(ApplicationArguments args) throws Exception {
|
||||||
|
if (!properties.isEnabled()) {
|
||||||
|
log.info("[DataInit] 自动初始化已关闭 app.init.enabled=false");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try (Connection conn = dataSource.getConnection()) {
|
||||||
|
boolean initialized = tableExists(conn, properties.getMarkerTable());
|
||||||
|
if (initialized) {
|
||||||
|
log.info("[DataInit] 检测到标记表已存在: {},跳过初始化", properties.getMarkerTable());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("[DataInit] 未检测到标记表: {},开始导入 schema 与 data", properties.getMarkerTable());
|
||||||
|
executeIfPresent(conn, properties.getSchema());
|
||||||
|
executeIfPresent(conn, properties.getData());
|
||||||
|
log.info("[DataInit] 导入完成。marker={} version={}", properties.getMarkerTable(), properties.getMarkerVersion());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("[DataInit] 初始化失败: {}", ex.getMessage(), ex);
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean tableExists(Connection conn, String tableName) {
|
||||||
|
if (tableName == null || tableName.isEmpty()) return false;
|
||||||
|
try {
|
||||||
|
DatabaseMetaData meta = conn.getMetaData();
|
||||||
|
try (ResultSet rs = meta.getTables(conn.getCatalog(), null, tableName, null)) {
|
||||||
|
return rs.next();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("[DataInit] 检查表存在异常: {}", e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeIfPresent(Connection conn, String location) throws Exception {
|
||||||
|
if (location == null || location.isEmpty()) return;
|
||||||
|
Resource resource = resourceLoader.getResource(location);
|
||||||
|
if (!resource.exists()) {
|
||||||
|
log.warn("[DataInit] 资源不存在: {}", location);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log.info("[DataInit] 执行脚本: {}", location);
|
||||||
|
// 读取并清理脚本首部的 BOM 和危险语句(CREATE DATABASE / USE schema)
|
||||||
|
String sql = StreamUtils.copyToString(resource.getInputStream(), StandardCharsets.UTF_8);
|
||||||
|
if (sql != null && !sql.isEmpty()) {
|
||||||
|
// 移除 UTF-8 BOM(\uFEFF)
|
||||||
|
if (sql.charAt(0) == '\uFEFF') {
|
||||||
|
sql = sql.substring(1);
|
||||||
|
}
|
||||||
|
// 移除 "USE xxx;" 和 "CREATE DATABASE" 等与连接无关的语句
|
||||||
|
sql = sql.lines()
|
||||||
|
.filter(line -> {
|
||||||
|
String raw = line;
|
||||||
|
String t = raw.trim();
|
||||||
|
String u = t.toUpperCase();
|
||||||
|
// 过滤与连接无关或可能引发解析问题的语句/注释
|
||||||
|
if (u.startsWith("USE ")) return false;
|
||||||
|
if (u.startsWith("CREATE DATABASE")) return false;
|
||||||
|
if (t.startsWith("--")) return false; // 单行注释
|
||||||
|
if (t.startsWith("/*") || t.startsWith("*/")) return false; // 多行注释行
|
||||||
|
if (t.startsWith("/*!")) return false; // MySQL 版本注释
|
||||||
|
if (t.matches("^-+$")) return false; // 分隔线
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.collect(Collectors.joining("\n"));
|
||||||
|
}
|
||||||
|
if (sql != null && !sql.trim().isEmpty()) {
|
||||||
|
try {
|
||||||
|
ScriptUtils.executeSqlScript(conn, new EncodedResource(new ByteArrayResource(sql.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8));
|
||||||
|
} catch (ScriptStatementFailedException e) {
|
||||||
|
String preview = sql.lines()
|
||||||
|
.filter(s -> !s.trim().isEmpty())
|
||||||
|
.limit(10)
|
||||||
|
.collect(Collectors.joining("\n"));
|
||||||
|
log.error("[DataInit] SQL语句执行失败: {}\n前10行预览:\n{}", e.getMessage(), preview);
|
||||||
|
throw e;
|
||||||
|
} catch (ScriptException e) {
|
||||||
|
String preview = sql.lines()
|
||||||
|
.filter(s -> !s.trim().isEmpty())
|
||||||
|
.limit(10)
|
||||||
|
.collect(Collectors.joining("\n"));
|
||||||
|
log.error("[DataInit] 脚本执行失败: {}\n前10行预览:\n{}", e.getMessage(), preview);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn("[DataInit] 脚本在清理后为空,跳过执行: {}", location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -24,6 +24,8 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.boot.ApplicationArguments;
|
import org.springframework.boot.ApplicationArguments;
|
||||||
import org.springframework.boot.ApplicationRunner;
|
import org.springframework.boot.ApplicationRunner;
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -34,6 +36,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
|
@Order(Ordered.LOWEST_PRECEDENCE)
|
||||||
public class JobRunner implements ApplicationRunner {
|
public class JobRunner implements ApplicationRunner {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(JobRunner.class);
|
private static final Logger log = LoggerFactory.getLogger(JobRunner.class);
|
||||||
|
|||||||
@ -1,168 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 此配置文件只是用作展示所有配置项, 不可不直接使用
|
|
||||||
|
|
||||||
|
|
||||||
spring:
|
|
||||||
# REDIS数据库配置
|
|
||||||
redis:
|
|
||||||
# [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1
|
|
||||||
host: 127.0.0.1
|
|
||||||
# [必须修改] 端口号
|
|
||||||
port: 6379
|
|
||||||
# [可选] 数据库 DB
|
|
||||||
database: 6
|
|
||||||
# [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接
|
|
||||||
password:
|
|
||||||
# [可选] 超时时间
|
|
||||||
timeout: 10000
|
|
||||||
# [可选] 一个pool最多可分配多少个jedis实例
|
|
||||||
poolMaxTotal: 1000
|
|
||||||
# [可选] 一个pool最多有多少个状态为idle(空闲)的jedis实例
|
|
||||||
poolMaxIdle: 500
|
|
||||||
# [可选] 最大的等待时间(秒)
|
|
||||||
poolMaxWait: 5
|
|
||||||
# [可选] jdbc数据库配置, 项目使用sqlite作为数据库,一般不需要配置
|
|
||||||
datasource:
|
|
||||||
# 使用mysql 打开23-28行注释, 删除29-36行
|
|
||||||
name: wvp
|
|
||||||
url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true
|
|
||||||
username:
|
|
||||||
password:
|
|
||||||
type: com.alibaba.druid.pool.DruidDataSource
|
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
|
||||||
# name: eiot
|
|
||||||
# url: jdbc:sqlite::resource:wvp.sqlite
|
|
||||||
# username:
|
|
||||||
# password:
|
|
||||||
# type: com.alibaba.druid.pool.DruidDataSource
|
|
||||||
# driver-class-name: org.sqlite.JDBC
|
|
||||||
max-active: 1
|
|
||||||
min-idle: 1
|
|
||||||
|
|
||||||
# [可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口
|
|
||||||
server:
|
|
||||||
port: 18080
|
|
||||||
# [可选] HTTPS配置, 默认不开启
|
|
||||||
ssl:
|
|
||||||
# [可选] 是否开启HTTPS访问
|
|
||||||
enabled: false
|
|
||||||
# [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名
|
|
||||||
key-store: classpath:xxx.jks
|
|
||||||
# [可选] 证书密码
|
|
||||||
key-password: password
|
|
||||||
# [可选] 证书类型, 默认为jks,根据实际修改
|
|
||||||
key-store-type: JKS
|
|
||||||
|
|
||||||
# 作为28181服务器的配置
|
|
||||||
sip:
|
|
||||||
# [必须修改] 本机的IP, 必须是网卡上的IP,用于sip下协议栈监听ip,如果监听所有设置为0.0.0.0
|
|
||||||
monitor-ip: 0.0.0.0
|
|
||||||
# [必须修改] 本机的IP
|
|
||||||
ip: 192.168.0.100
|
|
||||||
# [可选] 28181服务监听的端口
|
|
||||||
port: 5060
|
|
||||||
# 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007)
|
|
||||||
# 后两位为行业编码,定义参照附录D.3
|
|
||||||
# 3701020049标识山东济南历下区 信息行业接入
|
|
||||||
# [可选]
|
|
||||||
domain: 4401020049
|
|
||||||
# [可选]
|
|
||||||
id: 44010200492000000001
|
|
||||||
# [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验
|
|
||||||
password: admin123
|
|
||||||
# [可选] 心跳超时时间, 建议设置为心跳周期的三倍
|
|
||||||
keepalive-timeout: 255
|
|
||||||
# [可选] 国标级联注册失败,再次发起注册的时间间隔。 默认60秒
|
|
||||||
register-time-interval: 60
|
|
||||||
# [可选] 云台控制速度
|
|
||||||
ptz-speed: 50
|
|
||||||
# TODO [可选] 收到心跳后自动上线, 重启服务后会将所有设备置为离线,默认false,等待注册后上线。设置为true则收到心跳设置为上线。
|
|
||||||
# keepalliveToOnline: false
|
|
||||||
|
|
||||||
#zlm 默认服务器配置
|
|
||||||
media:
|
|
||||||
# [可选] zlm服务器唯一id,用于触发hook时区别是哪台服务器,general.mediaServerId
|
|
||||||
id:
|
|
||||||
# [必须修改] zlm服务器的内网IP
|
|
||||||
ip: 192.168.0.100
|
|
||||||
# [可选] 返回流地址时的ip,置空使用 media.ip
|
|
||||||
stream-ip:
|
|
||||||
# [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip
|
|
||||||
sdp-ip:
|
|
||||||
# [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip
|
|
||||||
hook-ip:
|
|
||||||
# [必须修改] zlm服务器的http.port
|
|
||||||
http-port: 80
|
|
||||||
# [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置
|
|
||||||
http-ssl-port:
|
|
||||||
# [可选] zlm服务器的rtmp.port, 置空使用zlm配置文件配置
|
|
||||||
rtmp-port:
|
|
||||||
# [可选] zlm服务器的rtmp.sslport, 置空使用zlm配置文件配置
|
|
||||||
rtmp-ssl-port:
|
|
||||||
# [可选] zlm服务器的 rtp_proxy.port, 置空使用zlm配置文件配置
|
|
||||||
rtp-proxy-port:
|
|
||||||
# [可选] zlm服务器的 rtsp.port, 置空使用zlm配置文件配置
|
|
||||||
rtsp-port:
|
|
||||||
# [可选] zlm服务器的 rtsp.sslport, 置空使用zlm配置文件配置
|
|
||||||
rtsp-ssl-port:
|
|
||||||
# [可选] 是否自动配置ZLM, 如果希望手动配置ZLM, 可以设为false, 不建议新接触的用户修改
|
|
||||||
auto-config: true
|
|
||||||
# [可选] zlm服务器的hook.admin_params=secret
|
|
||||||
secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc
|
|
||||||
# [可选] zlm服务器的general.streamNoneReaderDelayMS
|
|
||||||
stream-none-reader-delay-ms: 18000 # 无人观看多久自动关闭流, -1表示永不自动关闭,即 关闭按需拉流
|
|
||||||
# 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试
|
|
||||||
rtp:
|
|
||||||
# [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输
|
|
||||||
enable: true
|
|
||||||
# [可选] 在此范围内选择端口用于媒体流传输,
|
|
||||||
port-range: 30000,30500 # 端口范围
|
|
||||||
# [可选] 国标级联在此范围内选择端口发送媒体流,
|
|
||||||
send-port-range: 30000,30500 # 端口范围
|
|
||||||
# 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用
|
|
||||||
record-assist-port: 0
|
|
||||||
|
|
||||||
# [可选] 日志配置, 一般不需要改
|
|
||||||
logging:
|
|
||||||
file:
|
|
||||||
name: logs/wvp.log
|
|
||||||
max-history: 30
|
|
||||||
max-size: 10MB
|
|
||||||
total-size-cap: 300MB
|
|
||||||
level:
|
|
||||||
com.genersoft.iot: debug
|
|
||||||
com.genersoft.iot.vmp.storager.dao: info
|
|
||||||
com.genersoft.iot.vmp.gb28181: info
|
|
||||||
# [根据业务需求配置]
|
|
||||||
user-settings:
|
|
||||||
# [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true
|
|
||||||
auto-apply-play: false
|
|
||||||
# [可选] 部分设备需要扩展SDP,需要打开此设置
|
|
||||||
senior-sdp: false
|
|
||||||
# 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认)
|
|
||||||
save-position-history: false
|
|
||||||
# 点播等待超时时间,单位:毫秒
|
|
||||||
play-timeout: 3000
|
|
||||||
# 等待音视频编码信息再返回, true: 可以根据编码选择合适的播放器,false: 可以更快点播
|
|
||||||
wait-track: false
|
|
||||||
# 是否开启接口鉴权
|
|
||||||
interface-authentication: true
|
|
||||||
# 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录
|
|
||||||
interface-authentication-excludes:
|
|
||||||
- /api/v1/**
|
|
||||||
# 推流直播是否录制
|
|
||||||
record-push-live: true
|
|
||||||
# 是否将日志存储进数据库
|
|
||||||
logInDatebase: true
|
|
||||||
|
|
||||||
# 在线文档: swagger-ui(生产环境建议关闭)
|
|
||||||
swagger-ui:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
# 版本信息, 不需修改
|
|
||||||
version:
|
|
||||||
version: "@project.version@"
|
|
||||||
description: "@project.description@"
|
|
||||||
artifact-id: "@project.artifactId@"
|
|
||||||
@ -10,12 +10,12 @@ spring:
|
|||||||
druid:
|
druid:
|
||||||
master:
|
master:
|
||||||
driverClassName: com.mysql.cj.jdbc.Driver
|
driverClassName: com.mysql.cj.jdbc.Driver
|
||||||
url: jdbc:mysql://43.138.168.68:3306/frameworkdb2023?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true
|
url: jdbc:mysql://43.138.168.68:3306/frameworkdb2025?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true
|
||||||
username: root
|
username: root
|
||||||
password: ylfw20230626@
|
password: ylfw20230626@
|
||||||
slave:
|
slave:
|
||||||
driverClassName: com.mysql.cj.jdbc.Driver
|
driverClassName: com.mysql.cj.jdbc.Driver
|
||||||
url: jdbc:mysql://43.138.168.68:3306/frameworkdb2023?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true
|
url: jdbc:mysql://43.138.168.68:3306/frameworkdb2025?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true
|
||||||
username: root
|
username: root
|
||||||
password: ylfw20230626@
|
password: ylfw20230626@
|
||||||
|
|
||||||
@ -50,6 +50,16 @@ login:
|
|||||||
login-code:
|
login-code:
|
||||||
# 验证码类型配置 查看 LoginProperties 类
|
# 验证码类型配置 查看 LoginProperties 类
|
||||||
code-type: arithmetic
|
code-type: arithmetic
|
||||||
|
|
||||||
|
# 启动自动数据库初始化(仅 dev/server):
|
||||||
|
app:
|
||||||
|
init:
|
||||||
|
enabled: false
|
||||||
|
schema: classpath:db-init/sql/min-schema.sql
|
||||||
|
# data 文件可选;为避免复杂 dump 解析问题,先不导入
|
||||||
|
# data:
|
||||||
|
marker-table: sys_user
|
||||||
|
marker-version: v1.0.0
|
||||||
# 登录图形验证码有效时间/分钟
|
# 登录图形验证码有效时间/分钟
|
||||||
expiration: 2
|
expiration: 2
|
||||||
# 验证码高度
|
# 验证码高度
|
||||||
|
|||||||
@ -10,9 +10,9 @@ spring:
|
|||||||
druid:
|
druid:
|
||||||
master:
|
master:
|
||||||
driverClassName: com.mysql.cj.jdbc.Driver
|
driverClassName: com.mysql.cj.jdbc.Driver
|
||||||
url: jdbc:mysql://43.138.168.68:3306/framework2023?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true
|
url: jdbc:mysql://43.138.168.68:3306/frameworkdb2025?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true
|
||||||
username: root
|
username: root
|
||||||
password: zhengg7QkXa<gRqqQ2023
|
password: ylfw20230626@
|
||||||
|
|
||||||
mvc:
|
mvc:
|
||||||
pathmatch:
|
pathmatch:
|
||||||
@ -41,3 +41,13 @@ file-space: #项目文档空间
|
|||||||
useravatar: D:\demoproject\useravatar\ #用户头像
|
useravatar: D:\demoproject\useravatar\ #用户头像
|
||||||
system: D:\demoproject\system\ #系统文档根目录,用于头像等静态资源
|
system: D:\demoproject\system\ #系统文档根目录,用于头像等静态资源
|
||||||
|
|
||||||
|
# 启动自动数据库初始化(仅 dev/server):
|
||||||
|
app:
|
||||||
|
init:
|
||||||
|
enabled: true
|
||||||
|
schema: classpath:db-init/sql/min-schema.sql
|
||||||
|
# data 文件可选;为避免复杂 dump 解析问题,先不导入
|
||||||
|
# data:
|
||||||
|
marker-table: sys_user
|
||||||
|
marker-version: v1.0.0
|
||||||
|
|
||||||
|
|||||||
420
git管理方案.md
420
git管理方案.md
@ -1,420 +0,0 @@
|
|||||||
# Git 多分支 + 多模块 单仓库方案(优化版)
|
|
||||||
|
|
||||||
本方案在原有文档基础上进行了结构重构与细则完善,使其更易落地、可操作性强,并与当前仓库现状保持一致且可平滑演进。
|
|
||||||
|
|
||||||
## 0. 适用范围与设计目标
|
|
||||||
|
|
||||||
- 适用范围:Java Spring Boot 后端 + 独立前端工程的单仓库(Monorepo)协作。
|
|
||||||
- 总体目标:
|
|
||||||
- 公共框架代码统一维护与版本化发布。
|
|
||||||
- 业务系统独立演进,低耦合地复用框架能力。
|
|
||||||
- 清晰的分支与发布节奏,降低冲突与回归风险。
|
|
||||||
|
|
||||||
## 1. 仓库结构与现状
|
|
||||||
|
|
||||||
### 当前仓库(已存在)
|
|
||||||
```
|
|
||||||
ProjectFrameWork2025/
|
|
||||||
├── framework/ # 后端框架(含 src/、pom.xml 等)
|
|
||||||
│ └── frontend/ # 前端工程(当前位于 framework 目录下)
|
|
||||||
├── docs/ # 项目文档
|
|
||||||
├── pom.xml # 父 POM
|
|
||||||
└── git.md # Git 管理方案
|
|
||||||
```
|
|
||||||
|
|
||||||
### 推荐结构(框架含基线前端,业务前端复制自框架)
|
|
||||||
```
|
|
||||||
ProjectFrameWork2025/
|
|
||||||
├── framework/ # 后端框架(Maven 模块)+ 基线前端
|
|
||||||
│ └── frontend/ # 基线前端(可作为模板与上游源)
|
|
||||||
├── business-app-a/ # 业务系统A(Maven 模块)
|
|
||||||
│ ├── src/ # 业务A后端代码
|
|
||||||
│ └── frontend/ # 业务A前端(由 framework/frontend 复制)
|
|
||||||
├── business-app-b/ # 业务系统B(Maven 模块)
|
|
||||||
│ ├── src/
|
|
||||||
│ └── frontend/
|
|
||||||
├── docs/
|
|
||||||
├── pom.xml # 父POM(仅管理后端Maven模块)
|
|
||||||
└── README.md
|
|
||||||
```
|
|
||||||
|
|
||||||
说明:
|
|
||||||
- 保持 `framework/frontend` 为“基线前端”,承载公共 UI/组件、构建脚本与基础配置。
|
|
||||||
- 每个业务系统在自身目录下维护独立 `frontend/`,初始化时从 `framework/frontend` 复制;后续按业务需求改造。
|
|
||||||
- 根 `pom.xml` 仅管理后端模块;各前端项目独立使用 `pnpm/npm/yarn` 管理与构建。
|
|
||||||
|
|
||||||
## 2. 分支与权限策略
|
|
||||||
|
|
||||||
### 长期分支
|
|
||||||
```bash
|
|
||||||
main # 框架稳定版本(受保护)
|
|
||||||
develop-framework # 框架开发分支
|
|
||||||
develop-business # 业务开发分支(单业务时)
|
|
||||||
business-main # 业务稳定分支(单业务时,受保护)
|
|
||||||
# 多业务可扩展:develop-business-a / business-a-main 等
|
|
||||||
```
|
|
||||||
|
|
||||||
### 受保护策略(建议在 Git 服务器上配置)
|
|
||||||
- `main`、`business-main`:
|
|
||||||
- 禁止直接 push;必须通过合并请求(MR/PR)。
|
|
||||||
- 必须通过 CI(单元测试 + 构建)与至少 1 人代码评审。
|
|
||||||
- 建议启用“必须线性历史”(不允许非快进式合并)或统一使用 squash merge。
|
|
||||||
- 标签(tags)仅允许由“发布管理员”或 CI 流水线创建。
|
|
||||||
|
|
||||||
### 合并策略
|
|
||||||
- 框架到业务:业务分支定期合入 `main` 的框架更新(推荐 `git merge --no-ff` 或 `git rebase`,视团队偏好)。
|
|
||||||
- 业务到业务稳定:`develop-business` → `business-main` 通过 MR/PR,保持发布记录清晰。
|
|
||||||
- 框架发布:`develop-framework` → `main`,并打版本标签。
|
|
||||||
|
|
||||||
## 3. 代码组织(Maven 多模块 + 前端)
|
|
||||||
|
|
||||||
### 根 POM(示例)
|
|
||||||
```xml
|
|
||||||
<!-- pom.xml -->
|
|
||||||
<modules>
|
|
||||||
<module>framework</module>
|
|
||||||
<module>business-app</module>
|
|
||||||
<!-- 前端不纳入 Maven modules;独立管理 -->
|
|
||||||
<!-- 如需统一构建,可在 CI 中分阶段调用前端构建脚本 -->
|
|
||||||
</modules>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<java.version>21</java.version>
|
|
||||||
<spring-boot.version>3.x</spring-boot.version>
|
|
||||||
<mybatis-plus.version>3.5.6</mybatis-plus.version>
|
|
||||||
</properties>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Framework 模块 POM(示例)
|
|
||||||
```xml
|
|
||||||
<groupId>com.yfd.platform</groupId>
|
|
||||||
<artifactId>platform-framework</artifactId>
|
|
||||||
<version>1.0.0</version>
|
|
||||||
<packaging>jar</packaging>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.baomidou</groupId>
|
|
||||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
|
||||||
<version>${mybatis-plus.version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Business-App 模块 POM(示例)
|
|
||||||
```xml
|
|
||||||
<parent>
|
|
||||||
<groupId>com.yfd.platform</groupId>
|
|
||||||
<artifactId>platform-parent</artifactId>
|
|
||||||
<version>1.0.0</version>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<artifactId>platform-business</artifactId>
|
|
||||||
<packaging>war</packaging>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.yfd.platform</groupId>
|
|
||||||
<artifactId>platform-framework</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- 业务特定依赖 -->
|
|
||||||
<!-- 如需框架版本对齐,建议使用 BOM 或统一 parent 管理 -->
|
|
||||||
<!-- 也可将框架发布到私有仓库(Nexus/Artifactory)后以固定版本依赖 -->
|
|
||||||
</dependencies>
|
|
||||||
```
|
|
||||||
|
|
||||||
### 前端工程(建议)
|
|
||||||
- `framework/frontend` 作为上游基线;业务前端以复制方式继承并二次开发。
|
|
||||||
- 每个业务的前端位于 `business-app-*/frontend`,独立构建与发布;与后端解耦。
|
|
||||||
- 公共前端能力尽量沉淀在基线前端的可复用目录(如 `src/shared`、`ui/components`),便于业务端复制后保持一致。
|
|
||||||
|
|
||||||
### 前端复制与同步策略
|
|
||||||
- 初次复制:从 `framework/frontend` 完整复制到 `business-app-x/frontend`,保留 `.editorconfig`、`eslint/prettier`、`tailwind`、`vite` 等工程化文件。
|
|
||||||
- 差异化开发:在业务前端中修改业务页面、路由、接口地址、主题等,不直接改动 `framework/frontend`。
|
|
||||||
- 上游更新引入(从框架基线同步到业务前端)可选方案:
|
|
||||||
- 轻量脚本复制:使用 `robocopy`(Windows)或 `rsync`(Linux/Mac)定期同步除配置与 `node_modules` 外的公共目录;同步前使用分支/MR审阅。
|
|
||||||
- 组件库抽取:将通用UI/工具抽取为 `shared` 子包(后续可独立NPM私库),业务端通过包管理升级;当前阶段以目录复制为主。
|
|
||||||
- 提交粒度控制:框架前端的公共改动与模板变更使用 `feat(shared):`、`refactor(shared):` 提交,业务端便于识别与选择性采纳。
|
|
||||||
|
|
||||||
示例:Windows 下使用 `robocopy` 同步公共目录(不覆盖业务自定义配置)
|
|
||||||
```powershell
|
|
||||||
# 在仓库根执行,将 framework/frontend 的公共目录同步到业务A前端
|
|
||||||
$src = "framework/frontend"
|
|
||||||
$dst = "business-app-a/frontend"
|
|
||||||
# 同步 src 目录与部分工程化文件;排除 node_modules、环境配置
|
|
||||||
robocopy $src $dst /MIR /XD node_modules .git .husky /XF .env* pnpm-lock.yaml
|
|
||||||
# 可按需选择性同步 src/shared、types 等
|
|
||||||
robocopy "$src/src/shared" "$dst/src/shared" /MIR
|
|
||||||
```
|
|
||||||
|
|
||||||
## 4. 开发与协作工作流(落地命令)
|
|
||||||
|
|
||||||
### 初始化与分支创建
|
|
||||||
```bash
|
|
||||||
git clone http://121.37.111.42:3000/ThbTech/ProjectFrameWork2025.git
|
|
||||||
cd ProjectFrameWork2025
|
|
||||||
git checkout -b main
|
|
||||||
|
|
||||||
# 框架开发分支
|
|
||||||
git checkout -b develop-framework
|
|
||||||
git push -u origin develop-framework
|
|
||||||
|
|
||||||
# 业务开发分支(如仅一个业务)
|
|
||||||
git checkout main
|
|
||||||
git checkout -b develop-business
|
|
||||||
git push -u origin develop-business
|
|
||||||
```
|
|
||||||
|
|
||||||
### 框架功能开发
|
|
||||||
```bash
|
|
||||||
git checkout develop-framework
|
|
||||||
# 修改 framework/ 下代码
|
|
||||||
git add framework/
|
|
||||||
git commit -m "feat(framework): 新增通用权限管理模块"
|
|
||||||
git push origin develop-framework
|
|
||||||
|
|
||||||
# 合并到 main(发布框架版本)
|
|
||||||
git checkout main
|
|
||||||
git merge --no-ff develop-framework
|
|
||||||
git tag -a fw-v1.1.0 -m "框架版本 v1.1.0"
|
|
||||||
git push origin main --tags
|
|
||||||
```
|
|
||||||
|
|
||||||
### 业务功能开发与同步框架
|
|
||||||
```bash
|
|
||||||
git checkout develop-business
|
|
||||||
git fetch origin
|
|
||||||
git merge origin/main # 合入最新框架
|
|
||||||
|
|
||||||
# 在 business-app/ 下开发
|
|
||||||
git add business-app/
|
|
||||||
git commit -m "feat(order): 实现订单管理功能"
|
|
||||||
git push origin develop-business
|
|
||||||
|
|
||||||
# 稳定分支(如需要)
|
|
||||||
git checkout -b business-main
|
|
||||||
git push -u origin business-main
|
|
||||||
```
|
|
||||||
|
|
||||||
### 业务前端初始化(从框架复制)
|
|
||||||
```powershell
|
|
||||||
# 以 business-app-a 为例:在仓库根执行
|
|
||||||
mkdir business-app-a\frontend
|
|
||||||
# 复制基线前端(保留工程化配置,排除 node_modules)
|
|
||||||
robocopy framework\frontend business-app-a\frontend /MIR /XD node_modules .git .husky /XF .env* pnpm-lock.yaml
|
|
||||||
|
|
||||||
# 进入业务前端目录并安装依赖
|
|
||||||
cd business-app-a\frontend
|
|
||||||
pnpm i || npm ci
|
|
||||||
|
|
||||||
# 修改业务专属配置:
|
|
||||||
# - package.json 的 name、version(如需)
|
|
||||||
# - .env.*(API 地址、端口等)
|
|
||||||
# - src/pages/*、src/routes/*(业务页面与路由)
|
|
||||||
|
|
||||||
# 开发与启动
|
|
||||||
pnpm dev || npm run dev
|
|
||||||
```
|
|
||||||
|
|
||||||
### 模块级构建与测试(Maven)
|
|
||||||
```bash
|
|
||||||
# 仅构建框架
|
|
||||||
mvn -pl framework -am clean package
|
|
||||||
|
|
||||||
# 仅测试业务模块
|
|
||||||
mvn -pl business-app -am clean test
|
|
||||||
|
|
||||||
# 全部模块
|
|
||||||
mvn clean verify
|
|
||||||
```
|
|
||||||
|
|
||||||
## 5. 版本与标签策略
|
|
||||||
|
|
||||||
- 框架版本采用 SemVer:`fw-vMAJOR.MINOR.PATCH`,如 `fw-v1.2.0`。
|
|
||||||
- 业务版本与框架版本对齐或独立:建议 `biz-<system>-vMAJOR.MINOR.PATCH`,如 `biz-order-v1.0.0`。
|
|
||||||
- 标签一律打在稳定分支合并完成后;禁止在临时/开发分支打标签。
|
|
||||||
|
|
||||||
## 6. 配置管理与覆盖
|
|
||||||
|
|
||||||
### 框架通用配置示例
|
|
||||||
```yaml
|
|
||||||
# framework/src/main/resources/application.yml
|
|
||||||
spring:
|
|
||||||
datasource:
|
|
||||||
druid:
|
|
||||||
url: jdbc:mysql://${DB_HOST:localhost}:3306/${DB_NAME:platform}?useUnicode=true&characterEncoding=UTF8
|
|
||||||
username: ${DB_USER:appuser}
|
|
||||||
password: ${DB_PASSWORD:}
|
|
||||||
profiles:
|
|
||||||
active: @activatedProperties@
|
|
||||||
```
|
|
||||||
|
|
||||||
### 业务特定配置示例
|
|
||||||
```yaml
|
|
||||||
# business-app/src/main/resources/application-dev.yml
|
|
||||||
server:
|
|
||||||
port: 8093
|
|
||||||
|
|
||||||
business:
|
|
||||||
order:
|
|
||||||
timeout: 3600
|
|
||||||
file:
|
|
||||||
upload-path: D:/data/business-upload
|
|
||||||
|
|
||||||
spring:
|
|
||||||
datasource:
|
|
||||||
druid:
|
|
||||||
url: jdbc:mysql://localhost:3306/business_db
|
|
||||||
```
|
|
||||||
|
|
||||||
配置原则:
|
|
||||||
- 框架提供默认配置;业务分支优先保留业务特定配置。
|
|
||||||
- 配置差异通过 profile 管理;不要在框架直接硬编码业务参数。
|
|
||||||
|
|
||||||
## 7. 冲突与同步指南
|
|
||||||
|
|
||||||
### 定期同步流程
|
|
||||||
```bash
|
|
||||||
git checkout develop-business
|
|
||||||
git fetch origin
|
|
||||||
git merge origin/main # 或:git rebase origin/main
|
|
||||||
|
|
||||||
# 处理常见冲突:
|
|
||||||
# - application.yml / profiles 差异
|
|
||||||
# - 通用实体与业务扩展字段
|
|
||||||
# - 依赖版本不一致
|
|
||||||
|
|
||||||
mvn clean test -pl business-app
|
|
||||||
```
|
|
||||||
|
|
||||||
### 处理建议
|
|
||||||
- 配置冲突:业务优先;框架提供可扩展参数,而非覆盖业务。
|
|
||||||
- 实体冲突:为框架实体保留扩展点(如继承/组合);避免强耦合。
|
|
||||||
- API 兼容:框架废弃旧 API 需标注 deprecate,过渡期保留兼容层。
|
|
||||||
- 推荐启用 `git rerere` 记忆冲突解决,减少重复操作。
|
|
||||||
|
|
||||||
## 8. CI/CD 集成建议
|
|
||||||
|
|
||||||
### 典型流水线分阶段
|
|
||||||
```yaml
|
|
||||||
stages:
|
|
||||||
- framework-test
|
|
||||||
- business-test
|
|
||||||
- frontend-build
|
|
||||||
- build
|
|
||||||
- deploy
|
|
||||||
|
|
||||||
framework-test:
|
|
||||||
only:
|
|
||||||
- develop-framework
|
|
||||||
- main
|
|
||||||
script:
|
|
||||||
- mvn -pl framework -am clean verify
|
|
||||||
|
|
||||||
business-test:
|
|
||||||
only:
|
|
||||||
- develop-business
|
|
||||||
- business-main
|
|
||||||
script:
|
|
||||||
- mvn -pl business-app -am clean verify
|
|
||||||
|
|
||||||
frontend-build:
|
|
||||||
only:
|
|
||||||
- develop-framework
|
|
||||||
- develop-business
|
|
||||||
- business-main
|
|
||||||
- main
|
|
||||||
script:
|
|
||||||
# 构建基线前端
|
|
||||||
- cd framework/frontend
|
|
||||||
- pnpm i --frozen-lockfile || npm ci
|
|
||||||
- pnpm build || npm run build
|
|
||||||
# 构建业务前端(示例:A;可按项目实际枚举)
|
|
||||||
- cd ../../business-css/frontend
|
|
||||||
- pnpm i --frozen-lockfile || npm ci
|
|
||||||
- pnpm build || npm run build
|
|
||||||
```
|
|
||||||
|
|
||||||
### 分支保护与质量门禁
|
|
||||||
- `main`/`business-main` 必须通过上述阶段且无失败后才允许合并。
|
|
||||||
- 建议强制代码扫描(如 SpotBugs、ESLint)、制品上传、部署前审批。
|
|
||||||
|
|
||||||
## 9. 落地与迁移指南
|
|
||||||
|
|
||||||
### 从当前结构平滑演进到推荐结构
|
|
||||||
1. 保持现状:`framework/frontend` 作为基线前端,上游统一维护公共能力。
|
|
||||||
2. 新增 `business-app-a/` 模块(后端):复制示例 POM,引入 `platform-framework` 依赖。
|
|
||||||
3. 初始化业务前端:复制 `framework/frontend` → `business-app-a/frontend`,安装依赖并调整 `.env.*`、路由与页面。
|
|
||||||
4. 在 Git 服务器上设置分支保护与 MR/PR 规则、必需检查与发布审批。
|
|
||||||
5. 建立“前端同步脚本”或“公共组件抽取”机制,周期性从基线前端引入更新并审阅。
|
|
||||||
|
|
||||||
### CSS 项目(Critical Scenario Simulator, CSS)落地步骤
|
|
||||||
1. 根父 POM:在仓库根新增 `pom.xml`(已添加),注册 `framework` 与 `business-css` 模块。
|
|
||||||
2. 业务后端:新增 `business-css/pom.xml`,依赖 `com.yfd:platform:1.0` 的 classes JAR(框架已配置 maven-jar-plugin)。
|
|
||||||
3. 前端初始化:运行 `./scripts/sync-frontend.ps1 -Source "framework/frontend" -Target "business-css/frontend"`,复制基线前端。
|
|
||||||
4. 前端安装与启动:在 `business-css/frontend` 执行 `pnpm i` 或 `npm ci` 后,`pnpm dev`。
|
|
||||||
5. 构建与测试:
|
|
||||||
- 后端单模块:`mvn -pl business-css -am clean verify`
|
|
||||||
- 聚合构建:`mvn clean verify`
|
|
||||||
6. 分支策略建议:
|
|
||||||
- 框架:`develop-framework` → `main`,标签 `fw-vx.y.z`
|
|
||||||
- CSS:`develop-business-css`(或沿用 `develop-business`)→ `business-main`,标签 `biz-css-vx.y.z`
|
|
||||||
7. 同步策略:CSS 业务分支定期合入 `origin/main` 的框架更新;前端公共更新通过脚本或 MR 评审引入。
|
|
||||||
|
|
||||||
### 新业务扩展
|
|
||||||
```
|
|
||||||
ProjectFrameWork2025/
|
|
||||||
├── framework/
|
|
||||||
├── business-app-a/
|
|
||||||
├── business-app-b/
|
|
||||||
├── frontend/
|
|
||||||
└── pom.xml
|
|
||||||
```
|
|
||||||
- 每个业务独立 `develop-business-x` 与 `business-x-main` 分支;统一从 `main` 合入框架更新。
|
|
||||||
|
|
||||||
## 10. 开发规范(精炼)
|
|
||||||
|
|
||||||
### 提交消息(Conventional Commits 建议)
|
|
||||||
```
|
|
||||||
feat(order): 新增订单管理功能
|
|
||||||
fix(auth): 修复用户权限验证问题
|
|
||||||
docs(api): 更新接口文档
|
|
||||||
refactor(payment): 重构支付服务层
|
|
||||||
perf(db): 优化数据库查询性能
|
|
||||||
```
|
|
||||||
|
|
||||||
### 分支命名
|
|
||||||
- 功能:`feature/<模块>-<简述>`
|
|
||||||
- 修复:`hotfix/<问题>-<简述>`
|
|
||||||
- 发布:`release/<版本号>`
|
|
||||||
|
|
||||||
## 11. 运维监控与治理
|
|
||||||
|
|
||||||
- 分支健康:定期检查各业务分支落后于 `main` 的提交数,提示同步。
|
|
||||||
- 冲突监控:统计合并冲突频率与位置,反推框架设计优化点。
|
|
||||||
- 框架使用率:记录各业务对框架模块的依赖程度与版本分布,指导演进。
|
|
||||||
|
|
||||||
## 12. 附录:命令速查
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 获取模块依赖树
|
|
||||||
mvn -pl framework -am dependency:tree
|
|
||||||
|
|
||||||
# 仅运行某模块测试
|
|
||||||
mvn -pl business-app -am -DskipITs=false test
|
|
||||||
|
|
||||||
# 前端构建(根级)
|
|
||||||
cd frontend && pnpm i && pnpm build
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
本优化版方案兼顾当前仓库现状与后续演进路径,优先实现“可用且可管控”,再循序迭代至“前后端分离、多业务扩展”的理想结构。若需要,我可以进一步:
|
|
||||||
- 提供 Git 服务器(Gitea/GitLab)具体保护规则配置截图级操作步骤;
|
|
||||||
- 为当前 CI 环境生成可直接使用的脚本与模板文件;
|
|
||||||
- 输出 `CODEOWNERS`、PR 模板与自动化检查清单。
|
|
||||||
22
pom.xml
22
pom.xml
@ -1,22 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<groupId>com.yfd</groupId>
|
|
||||||
<artifactId>platform-parent</artifactId>
|
|
||||||
<version>1.0</version>
|
|
||||||
<packaging>pom</packaging>
|
|
||||||
<name>JavaProjectParent</name>
|
|
||||||
<description>Java项目父模块</description>
|
|
||||||
|
|
||||||
<modules>
|
|
||||||
<module>framework</module>
|
|
||||||
<module>business-css</module>
|
|
||||||
</modules>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<java.version>17</java.version>
|
|
||||||
</properties>
|
|
||||||
</project>
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
Param(
|
|
||||||
[string]$Source = "framework/frontend",
|
|
||||||
[string]$Target = "business-css/frontend"
|
|
||||||
)
|
|
||||||
|
|
||||||
Write-Host "Sync frontend from '$Source' to '$Target'" -ForegroundColor Cyan
|
|
||||||
|
|
||||||
if (!(Test-Path $Target)) {
|
|
||||||
New-Item -ItemType Directory -Path $Target | Out-Null
|
|
||||||
}
|
|
||||||
|
|
||||||
# 同步除 node_modules/.git/.husky 外的所有文件,排除环境与锁文件
|
|
||||||
robocopy $Source $Target /MIR /XD node_modules .git .husky /XF .env* pnpm-lock.yaml npm-lock.yaml yarn.lock
|
|
||||||
|
|
||||||
# 可选:按需同步共享目录,避免覆盖业务自定义
|
|
||||||
if (Test-Path "$Source/src/shared") {
|
|
||||||
robocopy "$Source/src/shared" "$Target/src/shared" /MIR
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host "Sync completed." -ForegroundColor Green
|
|
||||||
Loading…
Reference in New Issue
Block a user