plugins { id 'java' id 'org.springframework.boot' version '3.3.6' id 'io.spring.dependency-management' version '1.1.7' id 'com.diffplug.spotless' version '8.10.2' } group = 'cn.rosercode' version = '0.0.1-SNAPSHOT' java { toolchain { languageVersion = JavaLanguageVersion.of(21) } } configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-mail' implementation 'org.springframework.security:spring-security-crypto' implementation 'com.baomidou:mybatis-plus-spring-boot3-starter:3.5.12' implementation 'com.baomidou:mybatis-plus-jsqlparser:3.5.12' runtimeOnly 'com.mysql:mysql-connector-j' // SQLite 驱动,用于本地文件数据库 runtimeOnly 'org.xerial:sqlite-jdbc:3.46.1.3' implementation 'com.github.xiaoymin:knife4j-openapi3-jakarta-spring-boot-starter:4.5.0' implementation 'com.alibaba:easyexcel:4.0.3' implementation 'org.apache.commons:commons-csv:1.12.0' // zip 压缩包解析(支持带密码的 ZipCrypto / AES 加密压缩包) implementation 'net.lingala.zip4j:zip4j:2.11.5' // PDF 账单解析(招商银行「交易流水」PDF 为文本型,按字符坐标还原表格) implementation 'org.apache.pdfbox:pdfbox:3.0.3' // OpenAI Java SDK:调用 DeepSeek 等 OpenAI 兼容接口(通过自定义 baseUrl 兼容) implementation 'com.openai:openai-java:4.65.0' implementation 'io.jsonwebtoken:jjwt-api:0.12.6' runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.6' runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.6' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' // MapStruct:编译期生成实体与视图对象之间的属性映射实现 implementation 'org.mapstruct:mapstruct:1.6.3' annotationProcessor 'org.mapstruct:mapstruct-processor:1.6.3' // 使 MapStruct 能识别 Lombok 生成的 getter/setter annotationProcessor 'org.projectlombok:lombok-mapstruct-binding:0.2.0' developmentOnly 'org.springframework.boot:spring-boot-devtools' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } tasks.named('test') { useJUnitPlatform() } // ===== 代码格式规范 ===== // 统一 Java 导入顺序:java/javax -> 第三方库 -> 项目包,组间空行分隔 spotless { java { target 'src/main/java/**/*.java', 'src/test/java/**/*.java' // '|' 表示同组导入不插入空行;'' 为未显式指定导入的兜底组(即所有第三方库) importOrder('java|javax', '', 'cn.rosercode') } } // ===== 前端构建与打包 ===== def frontendDir = file("${projectDir}/frontend") def frontendDistDir = file("${frontendDir}/dist") // 解析 npm 可执行文件:优先使用 NODE_HOME,其次使用 PATH 中的 npm def resolveNpm = { def nodeHome = System.getenv('NODE_HOME') return nodeHome ? "${nodeHome}/bin/npm" : 'npm' } // 安装前端依赖(node_modules 存在且 package.json 未变化时自动跳过) tasks.register('npmInstall', Exec) { group = 'frontend' description = '安装前端依赖' workingDir frontendDir commandLine resolveNpm(), 'install' inputs.file("${frontendDir}/package.json") outputs.dir("${frontendDir}/node_modules") } // 构建前端产物 tasks.register('frontendBuild', Exec) { group = 'frontend' description = '构建前端产物(npm run build)' dependsOn 'npmInstall' workingDir frontendDir commandLine resolveNpm(), 'run', 'build' inputs.dir("${frontendDir}/src") inputs.file("${frontendDir}/package.json") inputs.file("${frontendDir}/index.html") inputs.file("${frontendDir}/vite.config.ts") outputs.dir(frontendDistDir) } // 将前端产物打入可执行 jar 的静态资源目录,实现前后端一体化部署 tasks.named('bootJar') { dependsOn 'frontendBuild' from(frontendDistDir) { into 'BOOT-INF/classes/static' } }