commit 722abb3abf86357f5f30aef694ce9c2c7a4c7dc8 Author: my_ong <429426262@qq.com> Date: Sun Dec 1 18:49:36 2024 +0800 :new: 项目初始化,大概实现数据表的定义 diff --git a/.gitea/workflows/release.yaml b/.gitea/workflows/release.yaml new file mode 100644 index 0000000..b0ee520 --- /dev/null +++ b/.gitea/workflows/release.yaml @@ -0,0 +1,31 @@ +name: Release +run-name: ${{ gitea.actor }} is deploying project to test server 🚀 +on: + push: + branches: + - develop +jobs: + Release: + runs-on: linux_amd64 + steps: + - name: 拉取代码 + uses: actions/checkout@v4 + - name: 执行打包 + run: mvn clean package -U -Dmaven.test.skip=true + - name: 读取项目信息 + uses: actions/maven-gav-extractor@v2 + id: maven + - name: 部署到服务器 + uses: actions/ssh-deploy@main + with: + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + ARGS: "-rlgoDzvc -i" + SOURCE: target/${{ steps.maven.outputs.artifact-id }}.jar + REMOTE_HOST: 10.100.130.80 + REMOTE_USER: root + TARGET: /root/apps + EXCLUDE: "" + SCRIPT_BEFORE: /root/springboot.sh bakup ${{ steps.maven.outputs.artifact-id }} + SCRIPT_AFTER: | + /root/springboot.sh restart ${{ steps.maven.outputs.artifact-id }} + echo $RSYNC_STDOUT diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..d58dfb7 --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +wrapperVersion=3.3.2 +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip diff --git a/mvnw b/mvnw new file mode 100644 index 0000000..19529dd --- /dev/null +++ b/mvnw @@ -0,0 +1,259 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.2 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000..249bdf3 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,149 @@ +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.2 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' +$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" +if ($env:MAVEN_USER_HOME) { + $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" +} +$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..b22ba83 --- /dev/null +++ b/pom.xml @@ -0,0 +1,149 @@ + + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.3.5 + + + tech.riemann + ims + 1.0.0 + 库管系统 + Inventory Management System + + + + + + + + + + + + + + + 17 + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-logging + + + + + org.springframework.boot + spring-boot-starter-log4j2 + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + org.springframework.boot + spring-boot-starter-undertow + + + org.apache.httpcomponents.client5 + httpclient5 + + + + com.mysql + mysql-connector-j + runtime + + + com.alibaba + druid-spring-boot-3-starter + 1.2.23 + + + com.ibeetl + beetl + 3.17.0.RELEASE + + + org.nutz + nutz-spring-boot-starter + 3.3.5 + + + + club.zhcs + open-api-spring-boot-starter + 3.3.5 + + + club.zhcs + lina-spring-boot-starter + 3.3.5 + + + + com.baomidou + mybatis-plus-spring-boot3-starter + 3.5.9 + + + + com.baomidou + mybatis-plus-generator + 3.5.9 + test + + + + com.alibaba + easyexcel + 4.0.3 + + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + diff --git a/src/main/java/tech/riemann/ims/Application.java b/src/main/java/tech/riemann/ims/Application.java new file mode 100644 index 0000000..8560042 --- /dev/null +++ b/src/main/java/tech/riemann/ims/Application.java @@ -0,0 +1,97 @@ +package tech.riemann.ims; + +import java.io.IOException; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.time.temporal.TemporalAccessor; +import java.util.Locale; + +import org.mybatis.spring.annotation.MapperScan; +import org.nutz.castor.Castors; +import org.nutz.json.Json; +import org.nutz.json.JsonFormat; +import org.nutz.json.JsonRender; +import org.nutz.json.JsonTypeHandler; +import org.nutz.lang.Mirror; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; + +@SpringBootApplication +@MapperScan("tech.riemann.ims.mapper") +@EnableAsync +@EnableScheduling +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + Json.addTypeHandler(new JsonTypeHandler() { + /** + * @param mirror + * @param obj + * @return + * @see org.nutz.json.JsonTypeHandler#supportFromJson(org.nutz.lang.Mirror, + * java.lang.Object) + */ + @Override + public boolean supportFromJson(Mirror mirror, Object obj) { + return mirror.getType().equals(LocalTime.class); + } + + /** + * @param mirror + * @param obj + * @param jf + * @return + * @see org.nutz.json.JsonTypeHandler#supportToJson(org.nutz.lang.Mirror, + * java.lang.Object, org.nutz.json.JsonFormat) + */ + @Override + public boolean supportToJson(Mirror mirror, Object obj, JsonFormat jf) { + return mirror.getType().equals(LocalTime.class); + } + + /** + * @param mirror + * @param currentObj + * @param r + * @param jf + * @throws IOException + * @see org.nutz.json.JsonTypeHandler#toJson(org.nutz.lang.Mirror, + * java.lang.Object, org.nutz.json.JsonRender, + * org.nutz.json.JsonFormat) + */ + @Override + public void toJson(Mirror mirror, Object currentObj, JsonRender r, JsonFormat jf) throws IOException { + String df = jf.getDateFormatRaw(); + if (mirror.getType().equals(LocalTime.class)) { + df = "HH:mm:ss"; + } + Locale locale = null; + String tmp = jf.getLocale(); + if (tmp != null) { + locale = Locale.forLanguageTag(tmp); + } else { + locale = Locale.getDefault(); + } + r.string2Json(DateTimeFormatter.ofPattern(df, locale).withZone(ZoneId.systemDefault()).format((TemporalAccessor) currentObj)); + } + + /** + * @param obj + * @param mirror + * @return + * @throws Exception + * @see org.nutz.json.JsonTypeHandler#fromJson(java.lang.Object, + * org.nutz.lang.Mirror) + */ + @Override + public Object fromJson(Object obj, Mirror mirror) throws Exception { + return Castors.me().castTo(obj, mirror.getType()); + } + }); + } + +} diff --git a/src/main/java/tech/riemann/ims/config/AdministratorConfigurationProperties.java b/src/main/java/tech/riemann/ims/config/AdministratorConfigurationProperties.java new file mode 100644 index 0000000..4c0933a --- /dev/null +++ b/src/main/java/tech/riemann/ims/config/AdministratorConfigurationProperties.java @@ -0,0 +1,44 @@ +package tech.riemann.ims.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Builder.Default; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author kerbores(kerbores@gmail.com) + */ +@Data +@ConfigurationProperties("riemann.laacam.acl") +public class AdministratorConfigurationProperties { + + boolean enabled = true; + + String userName = "kerbores"; + + String fullName = "Kerbores"; + + String email = "kerbores@gmail.com"; + + String cypher = "G00dl^ck"; + + String mobile = "18723465734"; + + Role admin = Role.builder().build(); + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Role { + @Default + String key = "admin"; + @Default + String name = "超级管理员"; + @Default + String description = "超级管理员,创世角色,一切均在掌控之中"; + } +} diff --git a/src/main/java/tech/riemann/ims/config/AdministratorInitializationAutoConfiguration.java b/src/main/java/tech/riemann/ims/config/AdministratorInitializationAutoConfiguration.java new file mode 100644 index 0000000..0d533d9 --- /dev/null +++ b/src/main/java/tech/riemann/ims/config/AdministratorInitializationAutoConfiguration.java @@ -0,0 +1,77 @@ +package tech.riemann.ims.config; + +import org.nutz.spring.boot.dao.NutzDatabaseInitializer; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import club.zhcs.lina.auth.encode.PasswordUtils; +import jakarta.annotation.PostConstruct; +import lombok.RequiredArgsConstructor; +import tech.riemann.ims.entity.acl.Role; +import tech.riemann.ims.entity.acl.User; +import tech.riemann.ims.entity.acl.UserRole; +import tech.riemann.ims.service.acl.IRoleService; +import tech.riemann.ims.service.acl.IUserRoleService; +import tech.riemann.ims.service.acl.IUserService; + +/** + * + * @author kerbores(kerbores@gmail.com) + * + */ +@Configuration +@ConditionalOnExpression("${riemann.laacam.acl.enabled:true}") +@EnableConfigurationProperties(AdministratorConfigurationProperties.class) +@RequiredArgsConstructor +public class AdministratorInitializationAutoConfiguration { + + private final AdministratorConfigurationProperties configurationProperties; + + private final IUserService userService; + + private final IRoleService roleService; + + private final IUserRoleService userRoleService; + + private final NutzDatabaseInitializer nutzDatabaseInitializer; + + @PostConstruct + public void init() { + nutzDatabaseInitializer.hashCode(); + final String su = configurationProperties.getUserName(); + final String admin = configurationProperties.getAdmin().getKey(); + + /* + * 初始化用户 + */ + if (userService.countByNutz() == 0) { + userService.insert(User.builder() + .name(su) + .mobile(configurationProperties.getMobile()) + .fullName(configurationProperties.getFullName()) + .email(configurationProperties.getEmail()) + .password(PasswordUtils.randomSaltEncode(configurationProperties.getCypher())) + .build()); + } + + /* + * 初始化角色 + */ + if (roleService.countByNutz() == 0) { + roleService.insert(Role.builder() + .key(admin) + .name(configurationProperties.getAdmin().getName()) + .description(configurationProperties.getAdmin().getDescription()) + .build()); + } + + /* + * 给用户授予角色 + */ + if (userRoleService.countByNutz() == 0) { + userRoleService.insert(UserRole.builder().userName(su).roleKey(admin).build()); + } + + } +} diff --git a/src/main/java/tech/riemann/ims/config/auth/LoadingCacheUserDetailService.java b/src/main/java/tech/riemann/ims/config/auth/LoadingCacheUserDetailService.java new file mode 100644 index 0000000..8259236 --- /dev/null +++ b/src/main/java/tech/riemann/ims/config/auth/LoadingCacheUserDetailService.java @@ -0,0 +1,78 @@ +package tech.riemann.ims.config.auth; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +import javax.annotation.Nonnull; + +import org.nutz.lang.Lang; +import org.springframework.stereotype.Component; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; + +import club.zhcs.lina.auth.service.AuthUser; +import club.zhcs.lina.auth.service.UserDetailService; +import lombok.RequiredArgsConstructor; +import tech.riemann.ims.service.acl.IUserService; + +/** + * + */ +@Component +@RequiredArgsConstructor +public class LoadingCacheUserDetailService implements UserDetailService { + + private IUserService userService; + + LoadingCache cache = CacheBuilder.newBuilder() + .concurrencyLevel(8) + .expireAfterAccess(10, TimeUnit.MINUTES) + .initialCapacity(10) + .maximumSize(300) + .recordStats() + .build(new CacheLoader<>() { + + @Override + @Nonnull + public AuthUser load(@Nonnull String key) throws Exception { + return userService.authUser(key); + } + }); + + /** + * @param name + * @return + * @see club.zhcs.lina.auth.service.UserDetailService#userByName(java.lang.String) + */ + @Override + public AuthUser userByName(String name) { + try { + return cache.get(name); + } + catch (ExecutionException e) { + throw Lang.wrapThrow(e); + } + } + + /** + * @param user + * @see club.zhcs.lina.auth.service.UserDetailService#save(club.zhcs.lina.auth.service.AuthUser) + */ + @Override + public void save(AuthUser user) { + cache.put(user.getUserName(), user); + } + + /** + * @param token + * @return + * @see club.zhcs.lina.auth.service.UserDetailService#userByToken(java.lang.String) + */ + @Override + public AuthUser userByToken(String token) { + return null; + } + +} diff --git a/src/main/java/tech/riemann/ims/controller/platform/acl/PermissionController.java b/src/main/java/tech/riemann/ims/controller/platform/acl/PermissionController.java new file mode 100644 index 0000000..40d6e90 --- /dev/null +++ b/src/main/java/tech/riemann/ims/controller/platform/acl/PermissionController.java @@ -0,0 +1,125 @@ +package tech.riemann.ims.controller.platform.acl; + +import java.util.Arrays; +import java.util.List; + +import org.springframework.http.HttpStatus; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; + +import club.zhcs.lina.starter.exception.BizException; +import club.zhcs.lina.utils.enums.Codebook; +import club.zhcs.lina.utils.enums.ICodeBook; +import club.zhcs.lina.utils.tree.Tree; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import tech.riemann.ims.entity.acl.Permission; +import tech.riemann.ims.service.acl.IPermissionService; + +/** + *

+ * 权限 前端控制器 + *

+ * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-07-22 13:56:54 + */ +@RestController +@Tag(name = "Permission", description = "权限") +@RequiredArgsConstructor +public class PermissionController { + + private final IPermissionService permissionService; + + @GetMapping("permission/types") + @Operation(summary = "权限类型") + public List types() { + return Arrays.stream(Permission.Type.values()) + .map(ICodeBook::build) + .toList(); + } + + @GetMapping("permissions/tree") + @Operation(summary = "权限树") + public List> permissionTree( + @Parameter(description = "强制拉取") @RequestParam(required = false) Boolean force) { + return permissionService.permissionTree(force); + } + + @GetMapping("permissions") + @Operation(summary = "权限列表") + public List permissions( + @Parameter(description = "强制拉取") @RequestParam(required = false) Boolean force) { + return permissionService.permissions(force); + } + + @GetMapping("permission/{id}") + @Operation(summary = "权限详情") + public Permission detail(@Parameter(description = "权限id", required = true) @PathVariable long id) { + return permissionService.getById(id); + } + + @PostMapping("permission") + @Operation(summary = "增加权限") + public Permission add(@Validated @Parameter(description = "权限") @RequestBody Permission permission) { + if (permissionService.save(permission)) { + return permission; + } else { + throw BizException.create("保存权限失败!"); + } + } + + @PatchMapping("permission") + @Operation(summary = "更新权限") + public Permission update(@Validated @Parameter(description = "权限") @RequestBody Permission permission) { + if (permissionService.update(permission, Wrappers. lambdaUpdate().eq(Permission::getId, permission.getId()))) { + return permission; + } else { + throw BizException.create("更新权限失败!"); + } + } + + /** + * 删除权限 + * + * @param id + * 权限id + * @return 是否删除成功 + */ + @DeleteMapping("permission/{key}") + @Operation(summary = "删除权限") + public void deletePermission(@Parameter(description = "权限key", required = true) @PathVariable String key) { + if (!permissionService.remove(Wrappers. lambdaQuery().eq(Permission::getKey, key))) { + throw BizException.create("删除权限失败!"); + } + } + + @PostMapping("batch-init-permissions") + @Operation(summary = "批量新增权限") + @ResponseStatus(value = HttpStatus.OK) + public void batchInitPermissions( + @RequestBody List permissions) { + permissionService.batchAddPermissions(permissions); + } + + @PatchMapping("batch-sync-permissions") + @Operation(summary = "增量新增权限") + @ResponseStatus(value = HttpStatus.OK) + public void batchSyncPermissions(@RequestBody List permissions) { + permissionService.updatePermissions(permissions); + } + +} diff --git a/src/main/java/tech/riemann/ims/controller/platform/acl/RoleController.java b/src/main/java/tech/riemann/ims/controller/platform/acl/RoleController.java new file mode 100644 index 0000000..0be8ac9 --- /dev/null +++ b/src/main/java/tech/riemann/ims/controller/platform/acl/RoleController.java @@ -0,0 +1,126 @@ +package tech.riemann.ims.controller.platform.acl; + +import java.util.List; + +import org.nutz.lang.Strings; +import org.springframework.http.HttpStatus; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; + +import club.zhcs.lina.starter.exception.BizException; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import tech.riemann.ims.dto.response.PermissionInfo; +import tech.riemann.ims.entity.acl.Permission; +import tech.riemann.ims.entity.acl.Role; +import tech.riemann.ims.service.acl.IRoleService; + +/** + *

+ * 角色 前端控制器 + *

+ * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-07-22 13:56:54 + */ +@RestController +@Tag(name = "Role", description = "角色") +@RequiredArgsConstructor +public class RoleController { + + private final IRoleService roleService; + + @GetMapping("roles") + @Operation(summary = "分页查询角色") + public IPage roles( + @Parameter(description = "页码") @RequestParam(required = false, defaultValue = "1") long page, + @Parameter(description = "页面大小") @RequestParam(required = false, defaultValue = "10") long size, + @Parameter(description = "搜索关键词") @RequestParam(required = false, defaultValue = "") String key) { + boolean hasLike = Strings.isNotBlank(key); + key = String.format("%%%s%%", key); + if (hasLike) { + return roleService.page(Page. of(page, size), + Wrappers. lambdaQuery() + .like(hasLike, Role::getName, key) + .or() + .like(Role::getKey, key) + .or() + .like(Role::getDescription, key)); + } + return roleService.page(Page. of(page, size), Wrappers. lambdaQuery()); + } + + @GetMapping("role/{id}") + @Operation(summary = "角色详情") + public Role detail(@Parameter(description = "角色id", required = true) @PathVariable long id) { + return roleService.getById(id); + } + + @PutMapping("role") + @Operation(summary = "增加/编辑角色") + public Role saveOrUpdateRole(@Validated @Parameter(description = "角色") @RequestBody Role role) { + if (role.getId() != null && role.getId() > 0) { + if (roleService.update(role, Wrappers. lambdaUpdate().eq(Role::getId, role.getId()))) { + return role; + } else { + throw BizException.create("更新角色失败!"); + } + } else { + if (roleService.save(role)) { + return role; + } else { + throw BizException.create("保存角色失败!"); + } + } + } + + @DeleteMapping("role/{key}") + @Operation(summary = "删除角色") + @ResponseStatus(HttpStatus.OK) + public void deleteRole(@Parameter(description = "角色key", required = true) @PathVariable String key) { + if (!roleService.remove(Wrappers. lambdaQuery().eq(Role::getKey, key))) { + throw BizException.create("删除角色失败!"); + } + } + + @GetMapping("role/{key}/permissions") + @Operation(summary = "查询角色权限") + public List permissions( + @Parameter(description = "角色key") @PathVariable String key) { + return roleService.permissionsByRoleKey(key); + } + + @GetMapping("role/{key}/permission-infos") + @Operation(summary = "查询用于授权的权限信息") + public List permissionInfos( + @Parameter(description = "角色key") @PathVariable String key) { + return roleService.permissionInfosByKey(key); + } + + @PostMapping("role/{key}/permissions") + @Operation(summary = "为指定角色授权") + @ResponseStatus(HttpStatus.OK) + public void grant( + @Parameter(description = "角色key") @PathVariable String key, + @Parameter(name = "permissions", description = "待授权信息[keyPath]") @RequestBody List permissions) { + if (!roleService.grant(key, permissions)) { + throw BizException.create("授权失败"); + } + } + +} diff --git a/src/main/java/tech/riemann/ims/controller/platform/acl/UserController.java b/src/main/java/tech/riemann/ims/controller/platform/acl/UserController.java new file mode 100644 index 0000000..8a79cf5 --- /dev/null +++ b/src/main/java/tech/riemann/ims/controller/platform/acl/UserController.java @@ -0,0 +1,161 @@ +package tech.riemann.ims.controller.platform.acl; + +import java.util.Arrays; +import java.util.List; + +import org.nutz.lang.Strings; +import org.springframework.http.HttpStatus; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; + +import club.zhcs.lina.auth.encode.PasswordUtils; +import club.zhcs.lina.auth.service.AuthUser.Sex; +import club.zhcs.lina.starter.exception.BizException; +import club.zhcs.lina.utils.enums.Codebook; +import club.zhcs.lina.utils.enums.ICodeBook; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import tech.riemann.ims.dto.response.PermissionInfo; +import tech.riemann.ims.dto.response.RoleInfo; +import tech.riemann.ims.entity.acl.Permission; +import tech.riemann.ims.entity.acl.User; +import tech.riemann.ims.service.acl.IUserService; + +/** + *

+ * 用户 前端控制器 + *

+ * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-07-22 13:56:54 + */ +@RestController +@Tag(name = "User", description = "用户") +@RequiredArgsConstructor +public class UserController { + + private final IUserService userService; + + @GetMapping("users") + @Operation(summary = "分页查询用户") + public IPage users( + @Parameter(description = "页码") @RequestParam(required = false, defaultValue = "1") int page, + @Parameter(description = "页面大小") @RequestParam(required = false, defaultValue = "10") int size, + @Parameter(description = "性别") @RequestParam(required = false, defaultValue = "") Sex sex, + @Parameter(description = "搜索关键词") @RequestParam(required = false, defaultValue = "") String key) { + boolean hasLike = Strings.isNotBlank(key); + key = String.format("%%%s%%", key); + return userService.page(Page. of(page, size), + Wrappers. lambdaQuery() + .like(hasLike, User::getName, key) + .eq(sex != null, User::getSex, sex) + .orderByDesc(User::getId)); + } + + @GetMapping("user/sexes") + @Operation(summary = "用户性别") + public List sexes() { + return Arrays.stream(Sex.values()).map(ICodeBook::build).toList(); + } + + @PatchMapping("user/{name}/password") + @Operation(summary = "重置密码") + public String resetPassword(@Parameter(description = "用户名", required = true) @PathVariable String name) { + return userService.resetPassword(name); + } + + @GetMapping("user/{id}") + @Operation(summary = "用户详情") + public User detail(@Parameter(description = "用户id", required = true) @PathVariable long id) { + return userService.getById(id); + } + + @PutMapping("user") + @Operation(summary = "增加/编辑用户") + public User saveOrUpdateUser(@Validated @Parameter(description = "用户") @RequestBody User user) { + if (user.getId() == null || user.getId() <= 0) { + user.setPassword(PasswordUtils.randomSaltEncode(user.getPassword())); + if (userService.save(user)) { + return user; + } else { + throw BizException.create("保存用户失败!"); + } + } else { + if (userService.update(user, Wrappers. lambdaUpdate().eq(User::getId, user.getId()))) { + return user; + } else { + throw BizException.create("更新用户失败!"); + } + } + } + + @DeleteMapping("user/{id}") + @Operation(summary = "删除用户") + @ResponseStatus(HttpStatus.OK) + public void deleteUser(@Parameter(description = "用户id", required = true) @PathVariable long id) { + if (!userService.removeById(id)) { + throw BizException.create("删除用户失败!"); + } + } + + @GetMapping("user/{name}/permissions") + @Operation(summary = "查询用户权限") + public List permissions( + @Parameter(description = "用户名") @PathVariable String name) { + return userService.permissionsByUserName(name); + } + + @GetMapping("user/{name}/permission-infos") + @Operation(summary = "查询用于授权的权限信息") + public List permissionInfos( + @Parameter(description = "用户名") @PathVariable String name) { + return userService.permissionInfosByUserName(name); + } + + @PostMapping("user/{name}/permissions") + @Operation(summary = "为指定用户授权") + @ResponseStatus(HttpStatus.OK) + public void grant( + @Parameter(description = "用户名") @PathVariable String name, + @Parameter(name = "permissions", + description = "待授权信息[keyPath]") @RequestBody List permissions) { + if (!userService.grant(name, permissions)) { + throw BizException.create("授权失败"); + } + } + + @GetMapping("user/{name}/role-infos") + @Operation(summary = "查询用户权限") + public List roleInfos( + @Parameter(description = "用户名") @PathVariable String name) { + return userService.roleInfosByUserName(name); + } + + @PostMapping("user/{name}/roles") + @Operation(summary = "为指定用户设置角色") + @ResponseStatus(HttpStatus.OK) + public void grantRole( + @Parameter(description = "用户名") @PathVariable String name, + @Parameter(name = "roles", description = "待授权角色") @RequestBody List roles) { + if (!userService.grantRole(name, roles)) { + throw BizException.create("授权角色失败"); + } + } + +} diff --git a/src/main/java/tech/riemann/ims/controller/platform/auth/AuthController.java b/src/main/java/tech/riemann/ims/controller/platform/auth/AuthController.java new file mode 100644 index 0000000..c2a0150 --- /dev/null +++ b/src/main/java/tech/riemann/ims/controller/platform/auth/AuthController.java @@ -0,0 +1,91 @@ +package tech.riemann.ims.controller.platform.auth; + +import org.springframework.http.HttpStatus; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import club.zhcs.lina.auth.service.AuthService; +import club.zhcs.lina.auth.service.AuthUser; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.AllArgsConstructor; +import lombok.Builder.Default; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.RequiredArgsConstructor; +import lombok.experimental.Accessors; +import lombok.experimental.SuperBuilder; +import tech.riemann.ims.service.acl.IUserService; + +/** + * Auth + * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2022-09-13 09:49:04 + */ +@RestController +@RequiredArgsConstructor +@Tag(name = "Auth", description = "登录") +public class AuthController { + + private final AuthService authService; + private final IUserService userService; + + @PostMapping("auth/login") + @Operation(summary = "登录") + public AuthUser login(@Validated @RequestBody LoginDTO login) { + AuthUser authUser = userService.login(login); + if (authUser != null) { + authService.login(authUser); + } + return authUser; + } + + @PostMapping("auth/logout") + @Operation(summary = "登出") + @ResponseStatus(HttpStatus.OK) + public void logout() { + authService.logout(); + } + + @GetMapping("auth/current-user") + @Operation(summary = "当前用户") + public AuthUser currentUser() { + return authService.user(); + } + + @Data + @SuperBuilder + @Accessors(chain = true) + @NoArgsConstructor + @AllArgsConstructor + @Schema(name = "LoginDTO", description = "登录实体") + public static class LoginDTO { + @Schema(description = "用户名", requiredMode = RequiredMode.NOT_REQUIRED) + String userName; + @Schema(description = "密码", requiredMode = RequiredMode.NOT_REQUIRED) + String password; + @Schema(description = "uuid", requiredMode = RequiredMode.NOT_REQUIRED) + String uuid; + @Schema(description = "验证码", requiredMode = RequiredMode.NOT_REQUIRED) + String captcha; + @Schema(description = "手机号", requiredMode = RequiredMode.NOT_REQUIRED) + String mobile; + @Default + @Schema(description = "登录类型", requiredMode = RequiredMode.REQUIRED) + Type type = Type.ACCOUNT; + + public enum Type { + ACCOUNT, + WECHAT + } + } + +} diff --git a/src/main/java/tech/riemann/ims/controller/platform/dictionary/DictionaryController.java b/src/main/java/tech/riemann/ims/controller/platform/dictionary/DictionaryController.java new file mode 100644 index 0000000..1bfd487 --- /dev/null +++ b/src/main/java/tech/riemann/ims/controller/platform/dictionary/DictionaryController.java @@ -0,0 +1,134 @@ +package tech.riemann.ims.controller.platform.dictionary; + +import java.util.List; + +import org.nutz.lang.Lang; +import org.nutz.lang.Strings; +import org.springframework.http.HttpStatus; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; + +import club.zhcs.lina.starter.exception.BizException; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import tech.riemann.ims.entity.dictionary.Dictionary; +import tech.riemann.ims.entity.dictionary.Group; +import tech.riemann.ims.service.dictionary.IDictionaryService; +import tech.riemann.ims.service.dictionary.IGroupService; + +/** + *

+ * 码本数据 前端控制器 + *

+ * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-07-22 13:56:55 + */ +@RestController +@Tag(name = "Dictionary", description = "码本数据") +@RequiredArgsConstructor +public class DictionaryController { + + private final IDictionaryService dictionaryService; + + private final IGroupService groupService; + + @GetMapping("groups") + @Operation(summary = "分页查询码本分组") + public IPage groups( + @Parameter(description = "页码") @RequestParam(required = false, defaultValue = "1") int page, + @Parameter(description = "页面大小") @RequestParam(required = false, defaultValue = "10") int size, + @Parameter(description = "搜索关键词") @RequestParam(required = false, defaultValue = "") String key) { + boolean hasLike = Strings.isNotBlank(key); + key = String.format("%%%s%%", key); + return groupService.page(Page. of(page, size), + Wrappers. lambdaQuery() + .like(hasLike, Group::getDescription, key) + .orderByAsc(Group::getId)); + } + + @GetMapping("group/{id}") + @Operation(summary = "码本分组详情") + public Group groupDetail(@Parameter(description = "码本分组id", required = true) @PathVariable long id) { + return groupService.getById(id); + } + + @PutMapping("group") + @Operation(summary = "增加/编辑码本分组") + public Group saveOrUpdateGroup(@Validated @Parameter(description = "码本分组") @RequestBody Group group) { + if (group.getId() != null && group.getId() > 0) { + if (groupService.update(group, Wrappers. lambdaUpdate().eq(Group::getId, group.getId()))) { + return group; + } else { + throw BizException.create("更新码本分组失败!"); + } + } else { + if (groupService.save(group)) { + return group; + } else { + throw BizException.create("保存码本分组失败!"); + } + } + } + + @DeleteMapping("group/{key}") + @Operation(summary = "删除码本分组") + @ResponseStatus(HttpStatus.OK) + public void deleteGroup(@Parameter(description = "码本分组key", required = true) @PathVariable String key) { + if (groupService.remove(Wrappers. lambdaQuery().eq(Group::getKey, key))) { + throw Lang.makeThrow(BizException.class, "删除码本分组失败!"); + } + } + + @GetMapping("group/{group}/dictionaries") + @Operation(summary = "分组下的数据字典列表") + public List dictionaries(@Parameter(description = "码本分组key", required = true) @PathVariable String group) { + return dictionaryService.list(Wrappers. lambdaQuery().eq(Dictionary::getGroupKey, group).orderByAsc(Dictionary::getIndex, Dictionary::getId)); + } + + @PutMapping("group/{group}/dictionary") + @Operation(summary = "增加/编辑码本数据") + public Dictionary saveOrUpdateDictionary( + @Parameter(description = "码本分组key", required = true) @PathVariable String group, + @Validated @Parameter(description = "码本数据") @RequestBody Dictionary dictionary) { + dictionary.setGroupKey(group); + if (dictionary.getId() != null && dictionary.getId() > 0) { + if (dictionaryService.update(dictionary, Wrappers. lambdaUpdate().eq(Dictionary::getId, dictionary.getId()))) { + return dictionary; + } else { + throw Lang.makeThrow("更新码本数据失败!"); + } + } else { + if (dictionaryService.save(dictionary)) { + return dictionary; + } else { + throw BizException.create("保存码本分组失败!"); + } + } + } + + @DeleteMapping("group/{group}/dictionary/{key}") + @Operation(summary = "删除码本数据") + @ResponseStatus(HttpStatus.OK) + public void deleteDictionary(@Parameter(description = "码本分组key", required = true) @PathVariable String group, + @Parameter(description = "码本数据key", required = true) @PathVariable String key) { + if (!dictionaryService.remove(Wrappers. lambdaQuery().eq(Dictionary::getGroupKey, group).eq(Dictionary::getKey, key))) { + throw Lang.makeThrow("删除码本数据失败!"); + } + } + +} diff --git a/src/main/java/tech/riemann/ims/controller/platform/material/ApplyFormController.java b/src/main/java/tech/riemann/ims/controller/platform/material/ApplyFormController.java new file mode 100644 index 0000000..953fe45 --- /dev/null +++ b/src/main/java/tech/riemann/ims/controller/platform/material/ApplyFormController.java @@ -0,0 +1,69 @@ +package tech.riemann.ims.controller.platform.material; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.nutz.lang.Strings; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import tech.riemann.ims.dto.request.ApplyInfo; +import tech.riemann.ims.entity.Inventory.ApplyDetail; +import tech.riemann.ims.entity.Inventory.ApplyForm; +import tech.riemann.ims.service.material.IApplyDetailService; +import tech.riemann.ims.service.material.IApplyFormService; + +import java.util.List; + +/** + * @author mayong + * @since 2024/11/28 15:29 + */ +@RestController +@Tag(name = "Apply", description = "入库/出库 申请单管理") +@RequiredArgsConstructor +public class ApplyFormController { + + private final IApplyFormService applyFormService; + private final IApplyDetailService applyDetailService; + + @GetMapping("apply") + @Operation(summary = "分页查询申请单列表") + public IPage applies( + @Parameter(description = "页码") @RequestParam(required = false, defaultValue = "1") int page, + @Parameter(description = "页面大小") @RequestParam(required = false, defaultValue = "10") int size, + @Parameter(description = "类型") @RequestParam(name = "type") Integer type, // 1入库 2出库 + @Parameter(description = "搜索关键词") @RequestParam(required = false, defaultValue = "") String key) { + boolean hasLike = Strings.isNotBlank(key); + key = String.format("%%%s%%", key); + return applyFormService.page(Page.of(page, size), Wrappers.lambdaQuery() + .eq(ApplyForm::getType, type) + .orderByDesc(ApplyForm::getUpdatedTime)); + } + + @GetMapping("apply/{applyId}") + @Operation(summary = "查询申请单详情") + public ApplyInfo detail(@Parameter(description = "类型") @PathVariable(name = "applyId") Integer applyId) { + List list = applyDetailService.list(Wrappers.lambdaQuery().eq(ApplyDetail::getApplyId, applyId)); + return ApplyInfo.builder() + .applyForm(applyFormService.getById(applyId)) + .applyDetails(list) + .build(); + } + + @PutMapping("apply") + @Operation(summary = "增加/编辑申请单") + public void saveOrUpdateApply(@Validated @Parameter(description = "申请单") @RequestBody ApplyInfo applyInfo) { + if (applyInfo.getApplyForm().getId() == null || applyInfo.getApplyForm().getId() <= 0) { + applyFormService.save(applyInfo.getApplyForm()); + applyInfo.getApplyDetails().forEach(detail -> detail.setApplyId(applyInfo.getApplyForm().getId())); + applyDetailService.saveBatch(applyInfo.getApplyDetails()); + } else { + // TODO 更新申请单 + } + } + +} diff --git a/src/main/java/tech/riemann/ims/controller/platform/material/MaterialController.java b/src/main/java/tech/riemann/ims/controller/platform/material/MaterialController.java new file mode 100644 index 0000000..75e6a26 --- /dev/null +++ b/src/main/java/tech/riemann/ims/controller/platform/material/MaterialController.java @@ -0,0 +1,89 @@ +package tech.riemann.ims.controller.platform.material; + +import club.zhcs.lina.starter.exception.BizException; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.nutz.lang.Strings; +import org.nutz.lang.random.R; +import org.springframework.http.HttpStatus; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import tech.riemann.ims.entity.Inventory.Material; +import tech.riemann.ims.service.material.IMaterialService; + +import java.util.List; + +/** + * @author mayong + * @since 2024/11/27 15:11 + */ +@RestController +@Tag(name = "Material", description = "物料管理") +@RequiredArgsConstructor +public class MaterialController { + + private final IMaterialService materialService; + + @GetMapping("materials") + @Operation(summary = "分页查询物料列表") + public IPage materials( + @Parameter(description = "页码") @RequestParam(required = false, defaultValue = "1") int page, + @Parameter(description = "页面大小") @RequestParam(required = false, defaultValue = "10") int size, + @Parameter(description = "类型") @RequestParam(required = false, defaultValue = "") Integer type, + @Parameter(description = "搜索关键词") @RequestParam(required = false, defaultValue = "") String key) { + boolean hasLike = Strings.isNotBlank(key); + key = String.format("%%%s%%", key); + return materialService.page(Page.of(page, size),Wrappers.lambdaQuery() + + .like(hasLike, Material::getName, key) + .or() + .like(hasLike, Material::getCode, key) + .eq(type != null, Material::getType, type) + .orderByDesc(Material::getUpdatedTime)); + } + + @GetMapping("material/list") + @Operation(summary = "查询所有物料列表") + public List all(){ + return materialService.list(); + } + + @GetMapping("material/{id}") + @Operation(summary = "物料详情") + public Material detail(@Parameter(description = "物料id", required = true) @PathVariable long id) { + return materialService.getById(id); + } + + @PutMapping("material") + @Operation(summary = "增加/编辑物料") + public Material saveOrUpdateMaterial(@Validated @Parameter(description = "物料信息") @RequestBody Material material) { + if (material.getId() == null || material.getId() <= 0) { + material.setCode(R.UU16()); + if (materialService.save(material)) { + return material; + } else { + throw BizException.create("保存物料失败!"); + } + } else { + if (materialService.update(material, Wrappers. lambdaUpdate().eq(Material::getId, material.getId()))) { + return material; + } else { + throw BizException.create("更新物料失败!"); + } + } + } + + @DeleteMapping("material/{id}") + @Operation(summary = "删除物料") + @ResponseStatus(HttpStatus.OK) + public void deleteMaterial(@Parameter(description = "物料id", required = true) @PathVariable long id) { + if (!materialService.removeById(id)) { + throw BizException.create("删除物料失败!"); + } + } +} diff --git a/src/main/java/tech/riemann/ims/dto/request/ApplyInfo.java b/src/main/java/tech/riemann/ims/dto/request/ApplyInfo.java new file mode 100644 index 0000000..7b39416 --- /dev/null +++ b/src/main/java/tech/riemann/ims/dto/request/ApplyInfo.java @@ -0,0 +1,25 @@ +package tech.riemann.ims.dto.request; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import tech.riemann.ims.entity.Inventory.ApplyDetail; +import tech.riemann.ims.entity.Inventory.ApplyForm; + +import java.util.List; + +/** + * @author mayong + * @since 2024/11/28 16:20 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ApplyInfo { + + private ApplyForm applyForm; + private List applyDetails; + +} diff --git a/src/main/java/tech/riemann/ims/dto/response/Option.java b/src/main/java/tech/riemann/ims/dto/response/Option.java new file mode 100644 index 0000000..880ee44 --- /dev/null +++ b/src/main/java/tech/riemann/ims/dto/response/Option.java @@ -0,0 +1,37 @@ +package tech.riemann.ims.dto.response; + +import com.baomidou.mybatisplus.annotation.TableName; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import lombok.experimental.FieldNameConstants; +import lombok.experimental.SuperBuilder; + +/** + * + */ +@Data +@EqualsAndHashCode(callSuper = false, of = {"value"}) +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@FieldNameConstants +@Accessors(chain = true) +@TableName(autoResultMap = true) +@Schema(name = "Option", description = "选项") +public class Option { + + @Schema(description = "显示信息", requiredMode = RequiredMode.REQUIRED) + String label; + + @Schema(description = "唯一键", requiredMode = RequiredMode.REQUIRED) + String value; + + @Schema(description = "是否不可选", requiredMode = RequiredMode.REQUIRED) + boolean disabled; +} diff --git a/src/main/java/tech/riemann/ims/dto/response/PermissionInfo.java b/src/main/java/tech/riemann/ims/dto/response/PermissionInfo.java new file mode 100644 index 0000000..0943c51 --- /dev/null +++ b/src/main/java/tech/riemann/ims/dto/response/PermissionInfo.java @@ -0,0 +1,39 @@ +package tech.riemann.ims.dto.response; + +import org.nutz.dao.entity.annotation.Column; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import lombok.experimental.FieldNameConstants; +import lombok.experimental.SuperBuilder; +import tech.riemann.ims.entity.acl.Permission; + +/** + * @author kerbores(kerbores@riemann.tech) + * + */ +@Data +@EqualsAndHashCode(callSuper = true) +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@FieldNameConstants +@Accessors(chain = true) +@TableName(autoResultMap = true) +@Schema(name = "PermissionInfo", description = "权限信息,包含是否选中标识") +public class PermissionInfo extends Permission { + + private static final long serialVersionUID = 1L; + @Column("selected") + @TableField("selected") + @Schema(description = "权限是否选中标识", requiredMode = RequiredMode.REQUIRED) + boolean selected; +} diff --git a/src/main/java/tech/riemann/ims/dto/response/PermissionTree.java b/src/main/java/tech/riemann/ims/dto/response/PermissionTree.java new file mode 100644 index 0000000..9c33816 --- /dev/null +++ b/src/main/java/tech/riemann/ims/dto/response/PermissionTree.java @@ -0,0 +1,26 @@ +package tech.riemann.ims.dto.response; + +import org.nutz.json.Json; + +import club.zhcs.lina.utils.tree.Treeable; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import tech.riemann.ims.entity.acl.Permission; + +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +@SuperBuilder +@Schema(name = "PermissionTree", description = "权限树") +public class PermissionTree extends Permission implements Treeable { + + private static final long serialVersionUID = 1L; + + public static PermissionTree build(Permission permission) { + return Json.fromJson(PermissionTree.class, Json.toJson(permission)); + } + +} diff --git a/src/main/java/tech/riemann/ims/dto/response/RoleInfo.java b/src/main/java/tech/riemann/ims/dto/response/RoleInfo.java new file mode 100644 index 0000000..0d63a1d --- /dev/null +++ b/src/main/java/tech/riemann/ims/dto/response/RoleInfo.java @@ -0,0 +1,42 @@ +package tech.riemann.ims.dto.response; + +import org.nutz.dao.entity.annotation.Column; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.FieldNameConstants; +import lombok.experimental.SuperBuilder; +import tech.riemann.ims.entity.acl.Role; + +/** + * @author Kerbores(kerbores@gmail.com) + * + */ +@Data +@EqualsAndHashCode(callSuper = true) +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@FieldNameConstants +@TableName(autoResultMap = true) +@Schema(name = "RoleInfo", description = "角色信息,包含是否选中标识") +public class RoleInfo extends Role { + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Schema(description = "角色是否选中标识", requiredMode = RequiredMode.REQUIRED) + @Column("selected") + @TableField("selected") + boolean selected; + +} diff --git a/src/main/java/tech/riemann/ims/entity/IdBaseEntity.java b/src/main/java/tech/riemann/ims/entity/IdBaseEntity.java new file mode 100644 index 0000000..42fd5df --- /dev/null +++ b/src/main/java/tech/riemann/ims/entity/IdBaseEntity.java @@ -0,0 +1,72 @@ +package tech.riemann.ims.entity; + +import java.time.LocalDateTime; + +import org.nutz.dao.entity.annotation.Column; +import org.nutz.dao.entity.annotation.Comment; +import org.nutz.dao.entity.annotation.Id; +import org.nutz.spring.boot.service.entity.Entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder.Default; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import lombok.experimental.SuperBuilder; + +/** + * + * @author Kerbores(kerbores@gmail.com) + * + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = true) +public class IdBaseEntity extends Entity { + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Id + @TableId(type = IdType.AUTO) + private Long id; + + @Column("created_time") + @Comment("创建时间") + @TableField("created_time") + @Default + protected LocalDateTime createdTime = LocalDateTime.now(); + + @Column("updated_time") + @TableField("updated_time") + @Comment("最后更新时间") + @Default + protected LocalDateTime updatedTime = LocalDateTime.now(); + + @Schema(description = "创建人") + @Column("created_by") + @TableField("created_by") + @Comment("创建人") + @JsonIgnore + protected String createdBy; + + @Schema(description = "更新人") + @Column("updated_by") + @TableField("updated_by") + @Comment("更新人") + @JsonIgnore + protected String updatedBy; + +} diff --git a/src/main/java/tech/riemann/ims/entity/Inventory/ApplyDetail.java b/src/main/java/tech/riemann/ims/entity/Inventory/ApplyDetail.java new file mode 100644 index 0000000..a5dcd38 --- /dev/null +++ b/src/main/java/tech/riemann/ims/entity/Inventory/ApplyDetail.java @@ -0,0 +1,75 @@ +package tech.riemann.ims.entity.Inventory; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import lombok.experimental.FieldNameConstants; +import lombok.experimental.SuperBuilder; +import org.nutz.dao.entity.annotation.*; +import tech.riemann.ims.entity.IdBaseEntity; + +import java.io.Serial; + +/** + * @author mayong + * @since 2024/11/26 17:13 + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@FieldNameConstants +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +@TableName("t_apply_detail") +@Table("t_apply_detail") +@Comment("申请单明细") +@Schema(name = "ApplyDetail", description = "申请单明细") +public class ApplyDetail extends IdBaseEntity { + + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "申请单ID", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("ad_apply_id") + @Column("ad_apply_id") + @Comment("申请单ID") + @ColDefine(notNull = false) + private Long applyId; + + @Schema(description = "物料Id", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("ad_material_id") + @Column("ad_material_id") + @Comment("物料Id") + @ColDefine(notNull = false) + private Long materialId; + + @Schema(description = "申请数量", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("ad_quantity") + @Column("ad_quantity") + @Comment("数量") + @ColDefine(notNull = false, type = ColType.INT) + private Integer quantity; + + @Schema(description = "确认数量", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("ad_confirm_quantity") + @Column("ad_confirm_quantity") + @Comment("确认数量") + @ColDefine(notNull = false, type = ColType.INT) + private Integer confirmQuantity; + + @Schema(description = "异常情况说明", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("ad_exception_remark") + @Column("ad_exception_remark") + @Comment("异常情况说明") + @ColDefine(notNull = false, width = 128, precision = 0) + private String exceptionRemark; + + +} diff --git a/src/main/java/tech/riemann/ims/entity/Inventory/ApplyForm.java b/src/main/java/tech/riemann/ims/entity/Inventory/ApplyForm.java new file mode 100644 index 0000000..9765e8d --- /dev/null +++ b/src/main/java/tech/riemann/ims/entity/Inventory/ApplyForm.java @@ -0,0 +1,74 @@ +package tech.riemann.ims.entity.Inventory; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import lombok.experimental.FieldNameConstants; +import lombok.experimental.SuperBuilder; +import org.nutz.dao.entity.annotation.*; +import tech.riemann.ims.entity.IdBaseEntity; + +import java.io.Serial; +import java.util.Date; + +/** + * @author mayong + * @since 2024/11/26 16:53 + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@FieldNameConstants +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +@TableName("t_apply_form") +@Table("t_apply_form") +@Comment("入库/出库 申请单") +@Schema(name = "ApplyForm", description = "入库/出库 申请单") +public class ApplyForm extends IdBaseEntity { + + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "类型", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("af_type") + @Column("af_type") + @Comment("类型") + @ColDefine(type = ColType.INT) + private Integer type; // 1: 采购入库 2: 归还入库 3: 出库外借 + + @Schema(description = "申请人", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("af_applicant") + @Column("af_applicant") + @Comment("申请人") + @ColDefine(notNull = false, width = 128, precision = 0) + private String applicant; + + @Schema(description = "申请日期", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("af_apply_date") + @Column("af_apply_date") + @Comment("申请日期") + @ColDefine(type = ColType.DATE, notNull = false, width = 128, precision = 0) + private Date applyDate; + + @Schema(description = "是否确认", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("af_is_confirm") + @Column("af_is_confirm") + @Comment("是否确认") + @ColDefine(type = ColType.BOOLEAN, notNull = false, width = 128, precision = 0) + private Boolean isConfirm; // 0: 未确认 1: 已确认 + + @Schema(description = "异常说明", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("af_remark") + @Column("af_remark") + @Comment("异常说明") + @ColDefine(type = ColType.TEXT, notNull = false, width = 128, precision = 0) + private String exceptionExplain; // 异常说明 +} diff --git a/src/main/java/tech/riemann/ims/entity/Inventory/Material.java b/src/main/java/tech/riemann/ims/entity/Inventory/Material.java new file mode 100644 index 0000000..938bfed --- /dev/null +++ b/src/main/java/tech/riemann/ims/entity/Inventory/Material.java @@ -0,0 +1,84 @@ +package tech.riemann.ims.entity.Inventory; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import lombok.experimental.FieldNameConstants; +import lombok.experimental.SuperBuilder; +import org.nutz.dao.entity.annotation.*; +import tech.riemann.ims.entity.IdBaseEntity; + +import java.io.Serial; + +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@FieldNameConstants +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +@TableName("t_material") +@Table("t_material") +@Comment("物料") +@Schema(name = "Material", description = "物料") +public class Material extends IdBaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "编码", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("m_code") + @Column("m_code") + @Comment("编码") + @ColDefine(notNull = false, width = 128, precision = 0) + private String code; + + @Schema(description = "名称", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("m_name") + @Column("m_name") + @Comment("名称") + @ColDefine(notNull = false, width = 128, precision = 0) + private String name; + + @Schema(description = "赋码规则", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("m_assign_rule") + @Column("m_assign_rule") + @Comment("赋码规则(0-低值易耗品(不参与赋码) 1-高价值工具类(参与唯一赋码))") + @ColDefine(notNull = false, type = ColType.INT) + private Integer assignRule; // 0-低值易耗品(不参与赋码) 1-高价值工具类(参与唯一赋码) + + @Schema(description = "类型", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("m_type") + @Column("m_type") + @Comment("类型") + @ColDefine(notNull = false, width = 128, precision = 0) + private String type; + + @Schema(description = "规格", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("m_spec") + @Column("m_spec") + @Comment("规格") + @ColDefine(notNull = false, width = 128, precision = 0) + private String spec; + + + @Schema(description = "库存数量", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("m_stock") + @Column("m_stock") + @Comment("库存数量") + @ColDefine(notNull = false, type = ColType.INT) + private Integer stock; + + @Schema(description = "备注", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("m_description") + @Column("m_description") + @Comment("备注") + @ColDefine(notNull = false, width = 500, precision = 0) + private String description; + +} diff --git a/src/main/java/tech/riemann/ims/entity/Inventory/MaterialBarcodeConfig.java b/src/main/java/tech/riemann/ims/entity/Inventory/MaterialBarcodeConfig.java new file mode 100644 index 0000000..6cdf996 --- /dev/null +++ b/src/main/java/tech/riemann/ims/entity/Inventory/MaterialBarcodeConfig.java @@ -0,0 +1,52 @@ +package tech.riemann.ims.entity.Inventory; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import lombok.experimental.FieldNameConstants; +import lombok.experimental.SuperBuilder; +import org.nutz.dao.entity.annotation.*; +import tech.riemann.ims.entity.IdBaseEntity; + +import java.io.Serial; + +/** + * @author mayong + * @since 2024/11/26 16:39 + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@FieldNameConstants +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +@TableName("t_material_barcode_config") +@Table("t_material_barcode_config") +@Comment("物料库条码配置表") +@Schema(name = "MaterialBarcodeConfig", description = "物料库条码配置表") +public class MaterialBarcodeConfig extends IdBaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "物料Key", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("mbc_material_key") + @Column("mbc_material_key") + @Comment("物料Key") + @ColDefine(notNull = false, width = 128, precision = 0) + private String materialKey; + + + @Schema(description = "最新编码位置", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("mbc_latest_location") + @Column("mbc_latest_location") + @Comment("最新编码位置") + @ColDefine(notNull = false, type = ColType.INT) + private Integer latestLocation; +} diff --git a/src/main/java/tech/riemann/ims/entity/Inventory/MaterialStockDetail.java b/src/main/java/tech/riemann/ims/entity/Inventory/MaterialStockDetail.java new file mode 100644 index 0000000..7f0243d --- /dev/null +++ b/src/main/java/tech/riemann/ims/entity/Inventory/MaterialStockDetail.java @@ -0,0 +1,63 @@ +package tech.riemann.ims.entity.Inventory; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import lombok.experimental.FieldNameConstants; +import lombok.experimental.SuperBuilder; +import org.nutz.dao.entity.annotation.ColDefine; +import org.nutz.dao.entity.annotation.Column; +import org.nutz.dao.entity.annotation.Comment; +import org.nutz.dao.entity.annotation.Table; +import tech.riemann.ims.entity.IdBaseEntity; + +import java.io.Serial; + +/** + * @author mayong + * @since 2024/11/26 17:21 + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@FieldNameConstants +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +@TableName("t_material_stock_detail") +@Table("t_material_stock_detail") +@Comment("物料明细数据表") +@Schema(name = "MaterialStockDetail", description = "物料明细数据表") +public class MaterialStockDetail extends IdBaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "物料Key", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("msd_material_key") + @Column("msd_material_key") + @Comment("物料Key") + @ColDefine(notNull = false, width = 128, precision = 0) + private String materialKey; + + @Schema(description = "条码", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("msd_barcode") + @Column("msd_barcode") + @Comment("条码") + @ColDefine(notNull = false, width = 128, precision = 0) + private String barcode; + + @Schema(description = "状态", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("msd_status") + @Column("msd_status") + @Comment("状态") + @ColDefine(notNull = false, width = 128, precision = 0) + private String status; // 状态 0-在库 1-外借 2-报废 + + +} diff --git a/src/main/java/tech/riemann/ims/entity/Inventory/Stocktaking.java b/src/main/java/tech/riemann/ims/entity/Inventory/Stocktaking.java new file mode 100644 index 0000000..97d2ab8 --- /dev/null +++ b/src/main/java/tech/riemann/ims/entity/Inventory/Stocktaking.java @@ -0,0 +1,109 @@ +package tech.riemann.ims.entity.Inventory; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import lombok.experimental.FieldNameConstants; +import lombok.experimental.SuperBuilder; +import org.nutz.dao.entity.annotation.*; +import tech.riemann.ims.entity.IdBaseEntity; + +import java.io.Serial; + +/** + * @author mayong + * @since 2024/11/26 17:51 + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@FieldNameConstants +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +@TableName("t_stocktaking") +@Table("t_stocktaking") +@Comment("盘点表") +@Schema(name = "Stocktaking", description = "盘点表") +public class Stocktaking extends IdBaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "盘点key", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("s_key") + @Column("s_key") + @Comment("盘点key") + @ColDefine(notNull = false, width = 128, precision = 0) + private String key; + + @Schema(description = "盘点类型", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("s_type") + @Column("s_type") + @Comment("盘点类型(0-全部盘点 1-部分盘点)") + @ColDefine(type = ColType.INT) + private Integer type; // 盘点类型 0-全部盘点 1-部分盘点 + + @Schema(description = "盘点日期", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("s_date") + @Column("s_date") + @Comment("盘点日期") + @ColDefine(notNull = false, width = 128, precision = 0) + private String date; + + @Schema(description = "盘点人", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("s_operator") + @Column("s_operator") + @Comment("盘点人") + @ColDefine(notNull = false, width = 128, precision = 0) + private String operator; + + @Schema(description = "盘点审核人", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("s_reviewer") + @Column("s_reviewer") + @Comment("盘点审核人") + @ColDefine(type = ColType.VARCHAR,notNull = false, width = 128, precision = 0) + private String reviewer; + + @Schema(description = "盘点任务状态", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("s_status") + @Column("s_status") + @Comment("盘点任务状态(0-未开始 1-进行中 2-已完成)") + @ColDefine(type = ColType.INT) + private Integer status; // 盘点任务状态 0-未开始 1-进行中 2-已完成 + + + @Schema(description = "盘点结果(系统自动生成)", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("s_result") + @Column("s_result") + @Comment("盘点结果(系统自动生成)") + @ColDefine(notNull = false, width = 128, precision = 0) + private String result; + + @Schema(description = "盘点审核结果", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("s_review_result") + @Column("s_review_result") + @Comment("盘点审核结果(0-通过 1-不通过 2-待审核 3-退回重新盘点)") + @ColDefine(type = ColType.VARCHAR,notNull = false, width = 128, precision = 0) + private String reviewResult; // 盘点审核结果 0-通过 1-不通过 2-待审核 3-退回重新盘点 + + @Schema(description = "盘点异常情况说明", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("s_exception") + @Column("s_exception") + @Comment("盘点异常情况说明") + @ColDefine(type = ColType.VARCHAR,notNull = false, width = 128, precision = 0) + private String exception; + + @Schema(description = "异常情况处理方式", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @TableField("s_exception_handle") + @Column("s_exception_handle") + @Comment("异常情况处理方式(0-无需处理 1-忽略并修改库存 2-补充库存 3-其他)") + @ColDefine(type = ColType.VARCHAR,notNull = false, width = 128, precision = 0) + private String exceptionHandle; // 异常情况处理方式 0-无需处理 1-忽略并修改库存 2-补充库存 3-其他 + +} diff --git a/src/main/java/tech/riemann/ims/entity/acl/Permission.java b/src/main/java/tech/riemann/ims/entity/acl/Permission.java new file mode 100644 index 0000000..39408a4 --- /dev/null +++ b/src/main/java/tech/riemann/ims/entity/acl/Permission.java @@ -0,0 +1,126 @@ +package tech.riemann.ims.entity.acl; + +import org.nutz.dao.entity.annotation.ColDefine; +import org.nutz.dao.entity.annotation.Column; +import org.nutz.dao.entity.annotation.Comment; +import org.nutz.dao.entity.annotation.Table; +import org.nutz.json.JsonField; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonGetter; + +import club.zhcs.lina.utils.enums.Codebook; +import club.zhcs.lina.utils.enums.ICodeBook; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import lombok.AllArgsConstructor; +import lombok.Builder.Default; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import lombok.experimental.FieldNameConstants; +import lombok.experimental.SuperBuilder; +import tech.riemann.ims.entity.IdBaseEntity; + +import java.io.Serial; + +/** + * 权限 + * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-07-22 13:56:54 + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@FieldNameConstants +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +@TableName(value = "t_permission", autoResultMap = true) +@Table("t_permission") +@Comment("权限") +@Schema(name = "Permission", description = "权限") +public class Permission extends IdBaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "权限key,英文", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("p_key") + @Column("p_key") + @Comment("权限key,英文") + @ColDefine(notNull = false, width = 128, precision = 0) + private String key; + + @Schema(description = "权限keyPath,用来做业务,(父级keyPath.key)", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("p_key_path") + @Column("p_key_path") + @Comment("权限keyPath,用来做业务,(父级keyPath.key)") + @ColDefine(notNull = false, width = 128, precision = 0) + private String keyPath; + + @Schema(description = "权限名称,中文用来做标识", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("p_name") + @Column("p_name") + @Comment("权限名称,中文用来做标识") + @ColDefine(notNull = false, width = 128, precision = 0) + private String name; + + @Schema(description = "权限描述", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("p_description") + @Column("p_description") + @Comment("权限描述") + @ColDefine(notNull = false, width = 128, precision = 0) + private String description; + + @Schema(description = "父权限key", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("p_parent_key") + @Column("p_parent_key") + @Comment("父权限key") + @ColDefine(notNull = false, width = 128, precision = 0) + private String parentKey; + + @Schema(description = "权限类型", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("p_type") + @Column("p_type") + @Comment("权限类型") + @ColDefine(notNull = false, width = 20, precision = 0) + @Default + private Type type = Type.MENU; + + @Getter + @AllArgsConstructor + public enum Type implements ICodeBook { + /** + * 菜单/页面 + */ + MENU("menu", "菜单"), + /** + * 按钮 + */ + BUTTON("button", "按钮"), + /** + * 其他页面元素 + */ + OTHER("other", "其他页面元素"); + + String code; + String description; + + } + + @JsonGetter + @JsonField + public Codebook getTypeInfo() { + return type == null ? null : type.build(); + } + + public void setTypeInfo(Codebook typeInfo) { + setType(Type.valueOf(typeInfo.getName())); + } +} diff --git a/src/main/java/tech/riemann/ims/entity/acl/Role.java b/src/main/java/tech/riemann/ims/entity/acl/Role.java new file mode 100644 index 0000000..02573e4 --- /dev/null +++ b/src/main/java/tech/riemann/ims/entity/acl/Role.java @@ -0,0 +1,65 @@ +package tech.riemann.ims.entity.acl; + +import org.nutz.dao.entity.annotation.ColDefine; +import org.nutz.dao.entity.annotation.Column; +import org.nutz.dao.entity.annotation.Comment; +import org.nutz.dao.entity.annotation.Table; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.FieldNameConstants; +import lombok.experimental.SuperBuilder; +import tech.riemann.ims.entity.IdBaseEntity; + +import java.io.Serial; + +/** + * 角色 + * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-07-22 13:56:54 + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@FieldNameConstants +@EqualsAndHashCode(callSuper = true) +@TableName(value = "t_role", autoResultMap = true) +@Table("t_role") +@Comment("角色") +@Schema(name = "Role", description = "角色") +public class Role extends IdBaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "角色key,英文,用来做业务", requiredMode = RequiredMode.REQUIRED) + @TableField("r_key") + @Column("r_key") + @Comment("角色key,英文,用来做业务") + @ColDefine(notNull = true, width = 128, precision = 0) + private String key; + + @Schema(description = "角色名称,中文用来做标识", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("r_name") + @Column("r_name") + @Comment("角色名称,中文用来做标识") + @ColDefine(notNull = false, width = 128, precision = 0) + private String name; + + @Schema(description = "角色描述", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("r_description") + @Column("r_description") + @Comment("角色描述") + @ColDefine(notNull = false, width = 128, precision = 0) + private String description; +} diff --git a/src/main/java/tech/riemann/ims/entity/acl/RolePermission.java b/src/main/java/tech/riemann/ims/entity/acl/RolePermission.java new file mode 100644 index 0000000..b4e6be1 --- /dev/null +++ b/src/main/java/tech/riemann/ims/entity/acl/RolePermission.java @@ -0,0 +1,60 @@ +package tech.riemann.ims.entity.acl; + +import org.nutz.dao.entity.annotation.ColDefine; +import org.nutz.dao.entity.annotation.Column; +import org.nutz.dao.entity.annotation.Comment; +import org.nutz.dao.entity.annotation.Table; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import lombok.experimental.FieldNameConstants; +import lombok.experimental.SuperBuilder; +import tech.riemann.ims.entity.IdBaseEntity; + +import java.io.Serial; + +/** + * 角色权限 + * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-07-22 13:56:54 + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@FieldNameConstants +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +@TableName("t_role_permission") +@Table("t_role_permission") +@Comment("角色权限") +@Schema(name = "RolePermission", description = "角色权限") +public class RolePermission extends IdBaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "角色key", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("rp_role_key") + @Column("rp_role_key") + @Comment("角色key") + @ColDefine(notNull = false, width = 128, precision = 0) + private String roleKey; + + @Schema(description = "权限keyPath", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("rp_permission_key_path") + @Column("rp_permission_key_path") + @Comment("权限keyPath") + @ColDefine(notNull = false, width = 128, precision = 0) + private String permissionKeyPath; +} diff --git a/src/main/java/tech/riemann/ims/entity/acl/User.java b/src/main/java/tech/riemann/ims/entity/acl/User.java new file mode 100644 index 0000000..94a104f --- /dev/null +++ b/src/main/java/tech/riemann/ims/entity/acl/User.java @@ -0,0 +1,103 @@ +package tech.riemann.ims.entity.acl; + +import java.io.Serial; +import java.util.Optional; + +import org.nutz.dao.entity.annotation.ColDefine; +import org.nutz.dao.entity.annotation.Column; +import org.nutz.dao.entity.annotation.Comment; +import org.nutz.dao.entity.annotation.Table; +import org.nutz.json.JsonField; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import club.zhcs.lina.auth.service.AuthUser.Sex; +import club.zhcs.lina.utils.enums.Codebook; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import lombok.AllArgsConstructor; +import lombok.Builder.Default; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import lombok.experimental.FieldNameConstants; +import lombok.experimental.SuperBuilder; +import tech.riemann.ims.entity.IdBaseEntity; + +/** + * 用户 + * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-07-22 13:56:54 + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@FieldNameConstants +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +@TableName("t_user") +@Table("t_user") +@Comment("用户") +@Schema(name = "User", description = "用户") +public class User extends IdBaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "用户名", requiredMode = RequiredMode.REQUIRED) + @TableField("u_name") + @Column("u_name") + @Comment("用户名") + @ColDefine(notNull = true, width = 128, precision = 0) + private String name; + + @Schema(description = "密码", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("u_password") + @Column("u_password") + @Comment("密码") + @ColDefine(notNull = false, width = 128, precision = 0) + private String password; + + @Schema(description = "手机号", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("u_mobile") + @Column("u_mobile") + @Comment("手机号") + @ColDefine(notNull = false, width = 128, precision = 0) + private String mobile; + + @Schema(description = "性别", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("u_sex") + @Column("u_sex") + @Comment("性别") + @ColDefine(notNull = false, width = 20, precision = 0) + @Default + private Sex sex = Sex.FEMALE; + + @Schema(description = "邮箱", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("u_email") + @Column("u_email") + @Comment("邮箱") + @ColDefine(notNull = false, width = 128, precision = 0) + private String email; + + @Schema(description = "真实姓名", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("u_full_name") + @Column("u_full_name") + @Comment("真实姓名") + @ColDefine(notNull = false, width = 128, precision = 0) + private String fullName; + + @JsonField + public Codebook getSexInfo() { + return Optional.of(getSex()).orElse(Sex.FEMALE).build(); + } + + public void setSexInfo(Codebook sexInfo) { + setSex(Sex.valueOf(sexInfo.getName())); + } +} diff --git a/src/main/java/tech/riemann/ims/entity/acl/UserBind.java b/src/main/java/tech/riemann/ims/entity/acl/UserBind.java new file mode 100644 index 0000000..bf7a447 --- /dev/null +++ b/src/main/java/tech/riemann/ims/entity/acl/UserBind.java @@ -0,0 +1,100 @@ +package tech.riemann.ims.entity.acl; + +import org.nutz.dao.entity.annotation.ColDefine; +import org.nutz.dao.entity.annotation.Column; +import org.nutz.dao.entity.annotation.Comment; +import org.nutz.dao.entity.annotation.Table; + +import com.baomidou.mybatisplus.annotation.TableField; + +import club.zhcs.lina.utils.enums.ICodeBook; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import lombok.experimental.FieldNameConstants; +import lombok.experimental.SuperBuilder; +import tech.riemann.ims.entity.IdBaseEntity; + +import java.io.Serial; + +/** + * 用户三方账号绑定 + * + * @author Kerbores(kerbores@riemann.tech) + * + * @since 2023-12-15 22:56:03 + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@FieldNameConstants +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +@Table("t_user_bind") +@Comment("用户三方账号绑定") +@Schema(name = "UserBind", description = "用户三方账号绑定") +public class UserBind extends IdBaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "用户名", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("b_user_name") + @Column("b_user_name") + @Comment("用户名") + @ColDefine(notNull = false, width = 50, precision = 0) + private String userName; + + @Schema(description = "OAuth2 渠道类型", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("b_type") + @Column("b_type") + @Comment("OAuth2 渠道类型") + @ColDefine(notNull = false, width = 20, precision = 0) + private Type type; + + @Schema(description = "openid", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("b_openid") + @Column("b_openid") + @Comment("openid") + @ColDefine(notNull = false, width = 128, precision = 0) + private String openid; + + @Schema(description = "metadata", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("b_metadata") + @Column("b_metadata") + @Comment("metadata") + @ColDefine(notNull = false, width = 3000, precision = 0) + private String metadata; + + @Schema(description = "uuid", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("b_uuid") + @Column("b_uuid") + @Comment("uuid") + @ColDefine(notNull = false, width = 128, precision = 0) + private String uuid; + + @Getter + @AllArgsConstructor + public enum Type implements ICodeBook { + + WORK_WECHAT("WORK_WECHAT", "企业微信"), + /** + * + */ + AD("AD", "AD域账号"), + /** + * + */ + GITEA("gitea", "GITEA"); + + String code; + String description; + + } +} diff --git a/src/main/java/tech/riemann/ims/entity/acl/UserPermission.java b/src/main/java/tech/riemann/ims/entity/acl/UserPermission.java new file mode 100644 index 0000000..909f285 --- /dev/null +++ b/src/main/java/tech/riemann/ims/entity/acl/UserPermission.java @@ -0,0 +1,60 @@ +package tech.riemann.ims.entity.acl; + +import org.nutz.dao.entity.annotation.ColDefine; +import org.nutz.dao.entity.annotation.Column; +import org.nutz.dao.entity.annotation.Comment; +import org.nutz.dao.entity.annotation.Table; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import lombok.experimental.FieldNameConstants; +import lombok.experimental.SuperBuilder; +import tech.riemann.ims.entity.IdBaseEntity; + +import java.io.Serial; + +/** + * 用户权限 + * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-07-22 13:56:54 + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@FieldNameConstants +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +@TableName("t_user_permission") +@Table("t_user_permission") +@Comment("用户权限") +@Schema(name = "UserPermission", description = "用户权限") +public class UserPermission extends IdBaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "用户名", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("up_user_name") + @Column("up_user_name") + @Comment("用户名") + @ColDefine(notNull = false, width = 128, precision = 0) + private String userName; + + @Schema(description = "权限keyPath", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("up_permission_key_path") + @Column("up_permission_key_path") + @Comment("权限keyPath") + @ColDefine(notNull = false, width = 128, precision = 0) + private String permissionKeyPath; +} diff --git a/src/main/java/tech/riemann/ims/entity/acl/UserRole.java b/src/main/java/tech/riemann/ims/entity/acl/UserRole.java new file mode 100644 index 0000000..a19dc5e --- /dev/null +++ b/src/main/java/tech/riemann/ims/entity/acl/UserRole.java @@ -0,0 +1,60 @@ +package tech.riemann.ims.entity.acl; + +import org.nutz.dao.entity.annotation.ColDefine; +import org.nutz.dao.entity.annotation.Column; +import org.nutz.dao.entity.annotation.Comment; +import org.nutz.dao.entity.annotation.Table; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import lombok.experimental.FieldNameConstants; +import lombok.experimental.SuperBuilder; +import tech.riemann.ims.entity.IdBaseEntity; + +import java.io.Serial; + +/** + * 用户角色 + * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-07-22 13:56:54 + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@FieldNameConstants +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +@TableName("t_user_role") +@Table("t_user_role") +@Comment("用户角色") +@Schema(name = "UserRole", description = "用户角色") +public class UserRole extends IdBaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "用户名", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("ur_user_name") + @Column("ur_user_name") + @Comment("用户名") + @ColDefine(notNull = false, width = 128, precision = 0) + private String userName; + + @Schema(description = "角色Key", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("ur_role_key") + @Column("ur_role_key") + @Comment("角色Key") + @ColDefine(notNull = false, width = 128, precision = 0) + private String roleKey; +} diff --git a/src/main/java/tech/riemann/ims/entity/dictionary/Dictionary.java b/src/main/java/tech/riemann/ims/entity/dictionary/Dictionary.java new file mode 100644 index 0000000..7fe146a --- /dev/null +++ b/src/main/java/tech/riemann/ims/entity/dictionary/Dictionary.java @@ -0,0 +1,95 @@ +package tech.riemann.ims.entity.dictionary; + +import org.nutz.dao.entity.annotation.ColDefine; +import org.nutz.dao.entity.annotation.Column; +import org.nutz.dao.entity.annotation.Comment; +import org.nutz.dao.entity.annotation.Table; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import lombok.experimental.FieldNameConstants; +import lombok.experimental.SuperBuilder; +import tech.riemann.ims.entity.IdBaseEntity; + +import java.io.Serial; + +/** + * 码本数据 + * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-07-22 13:56:55 + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@FieldNameConstants +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +@TableName("t_dictionary") +@Table("t_dictionary") +@Comment("码本数据") +@Schema(name = "Dictionary", description = "码本数据") +public class Dictionary extends IdBaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "分组Key", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("d_group_key") + @Column("d_group_key") + @Comment("分组Key") + @ColDefine(notNull = false, width = 128, precision = 0) + private String groupKey; + + @Schema(description = "上级Key", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("d_parent_key") + @Column("d_parent_key") + @Comment("上级Key") + @ColDefine(notNull = false, width = 128, precision = 0) + private String parentKey; + + @Schema(description = "序号", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("d_index") + @Column("d_index") + @Comment("序号") + @ColDefine(notNull = false, width = 19, precision = 0) + private Long index; + + @Schema(description = "key", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("d_key") + @Column("d_key") + @Comment("key") + @ColDefine(notNull = false, width = 128, precision = 0) + private String key; + + @Schema(description = "value", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("d_value") + @Column("d_value") + @Comment("value") + @ColDefine(notNull = false, width = 128, precision = 0) + private String value; + + @Schema(description = "描述", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("d_description") + @Column("d_description") + @Comment("描述") + @ColDefine(notNull = false, width = 128, precision = 0) + private String description; + + @Schema(description = "禁用标识", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("d_disabled") + @Column("d_disabled") + @Comment("禁用标识") + @ColDefine(notNull = false, width = 1, precision = 0) + private Boolean disabled; +} diff --git a/src/main/java/tech/riemann/ims/entity/dictionary/Group.java b/src/main/java/tech/riemann/ims/entity/dictionary/Group.java new file mode 100644 index 0000000..37258b8 --- /dev/null +++ b/src/main/java/tech/riemann/ims/entity/dictionary/Group.java @@ -0,0 +1,77 @@ +package tech.riemann.ims.entity.dictionary; + +import org.nutz.dao.entity.annotation.ColDefine; +import org.nutz.dao.entity.annotation.Column; +import org.nutz.dao.entity.annotation.Comment; +import org.nutz.dao.entity.annotation.Table; +import org.nutz.lang.random.R; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import lombok.AllArgsConstructor; +import lombok.Builder.Default; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import lombok.experimental.FieldNameConstants; +import lombok.experimental.SuperBuilder; +import tech.riemann.ims.entity.IdBaseEntity; + +import java.io.Serial; + +/** + * 码本分组 + * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-07-22 13:56:55 + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@FieldNameConstants +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +@TableName("t_group") +@Table("t_group") +@Comment("码本分组") +@Schema(name = "Group", description = "码本分组") +public class Group extends IdBaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "分组唯一键", requiredMode = RequiredMode.REQUIRED) + @TableField("g_key") + @Column("g_key") + @Comment("分组唯一键") + @ColDefine(notNull = true, width = 128, precision = 0) + @Default + private String key = R.UU16(); + + @Schema(description = "分组名称", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("g_name") + @Column("g_name") + @Comment("分组名称") + @ColDefine(notNull = false, width = 128, precision = 0) + private String name; + + @Schema(description = "分组描述", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("g_description") + @Column("g_description") + @Comment("分组描述") + @ColDefine(notNull = false, width = 128, precision = 0) + private String description; + + @Schema(description = "禁用标识", requiredMode = RequiredMode.NOT_REQUIRED) + @TableField("g_disabled") + @Column("g_disabled") + @Comment("禁用标识") + @ColDefine(notNull = false, width = 1, precision = 0) + private Boolean disabled; +} diff --git a/src/main/java/tech/riemann/ims/mapper/acl/PermissionMapper.java b/src/main/java/tech/riemann/ims/mapper/acl/PermissionMapper.java new file mode 100644 index 0000000..08aa048 --- /dev/null +++ b/src/main/java/tech/riemann/ims/mapper/acl/PermissionMapper.java @@ -0,0 +1,16 @@ +package tech.riemann.ims.mapper.acl; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +import tech.riemann.ims.entity.acl.Permission; + +/** + * 权限 Mapper 接口 + * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-10 18:07:15 + */ +public interface PermissionMapper extends BaseMapper { + +} diff --git a/src/main/java/tech/riemann/ims/mapper/acl/RoleMapper.java b/src/main/java/tech/riemann/ims/mapper/acl/RoleMapper.java new file mode 100644 index 0000000..9e80b46 --- /dev/null +++ b/src/main/java/tech/riemann/ims/mapper/acl/RoleMapper.java @@ -0,0 +1,25 @@ +package tech.riemann.ims.mapper.acl; + +import java.util.List; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +import tech.riemann.ims.dto.response.PermissionInfo; +import tech.riemann.ims.entity.acl.Role; + +/** + * 角色 Mapper 接口 + * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-10 18:07:15 + */ +public interface RoleMapper extends BaseMapper { + + /** + * @param key + * @return + */ + List permissionInfosByKey(String key); + +} diff --git a/src/main/java/tech/riemann/ims/mapper/acl/RolePermissionMapper.java b/src/main/java/tech/riemann/ims/mapper/acl/RolePermissionMapper.java new file mode 100644 index 0000000..4568a65 --- /dev/null +++ b/src/main/java/tech/riemann/ims/mapper/acl/RolePermissionMapper.java @@ -0,0 +1,16 @@ +package tech.riemann.ims.mapper.acl; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +import tech.riemann.ims.entity.acl.RolePermission; + +/** + * 角色权限 Mapper 接口 + * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-10 18:07:15 + */ +public interface RolePermissionMapper extends BaseMapper { + +} diff --git a/src/main/java/tech/riemann/ims/mapper/acl/UserBindMapper.java b/src/main/java/tech/riemann/ims/mapper/acl/UserBindMapper.java new file mode 100644 index 0000000..0eea589 --- /dev/null +++ b/src/main/java/tech/riemann/ims/mapper/acl/UserBindMapper.java @@ -0,0 +1,16 @@ +package tech.riemann.ims.mapper.acl; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +import tech.riemann.ims.entity.acl.UserBind; + +/** + * 用户三方账号绑定 Mapper 接口 + * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-10 18:07:15 + */ +public interface UserBindMapper extends BaseMapper { + +} diff --git a/src/main/java/tech/riemann/ims/mapper/acl/UserMapper.java b/src/main/java/tech/riemann/ims/mapper/acl/UserMapper.java new file mode 100644 index 0000000..c5c728c --- /dev/null +++ b/src/main/java/tech/riemann/ims/mapper/acl/UserMapper.java @@ -0,0 +1,38 @@ +package tech.riemann.ims.mapper.acl; + +import java.util.List; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +import tech.riemann.ims.dto.response.PermissionInfo; +import tech.riemann.ims.dto.response.RoleInfo; +import tech.riemann.ims.entity.acl.User; + +/** + * 用户 Mapper 接口 + * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-10 18:07:15 + */ +public interface UserMapper extends BaseMapper { + + /** + * @param name + * @return + */ + List indirectPermissionInfosByUserName(String name); + + /** + * @param name + * @return + */ + List directPermissionInfosByUserName(String name); + + /** + * @param name + * @return + */ + List roleInfosByUserName(String name); + +} diff --git a/src/main/java/tech/riemann/ims/mapper/acl/UserPermissionMapper.java b/src/main/java/tech/riemann/ims/mapper/acl/UserPermissionMapper.java new file mode 100644 index 0000000..e66fdd9 --- /dev/null +++ b/src/main/java/tech/riemann/ims/mapper/acl/UserPermissionMapper.java @@ -0,0 +1,16 @@ +package tech.riemann.ims.mapper.acl; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +import tech.riemann.ims.entity.acl.UserPermission; + +/** + * 用户权限 Mapper 接口 + * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-10 18:07:15 + */ +public interface UserPermissionMapper extends BaseMapper { + +} diff --git a/src/main/java/tech/riemann/ims/mapper/acl/UserRoleMapper.java b/src/main/java/tech/riemann/ims/mapper/acl/UserRoleMapper.java new file mode 100644 index 0000000..1ea12f1 --- /dev/null +++ b/src/main/java/tech/riemann/ims/mapper/acl/UserRoleMapper.java @@ -0,0 +1,16 @@ +package tech.riemann.ims.mapper.acl; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +import tech.riemann.ims.entity.acl.UserRole; + +/** + * 用户角色 Mapper 接口 + * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-10 18:07:15 + */ +public interface UserRoleMapper extends BaseMapper { + +} diff --git a/src/main/java/tech/riemann/ims/mapper/dictionary/DictionaryMapper.java b/src/main/java/tech/riemann/ims/mapper/dictionary/DictionaryMapper.java new file mode 100644 index 0000000..eb43d69 --- /dev/null +++ b/src/main/java/tech/riemann/ims/mapper/dictionary/DictionaryMapper.java @@ -0,0 +1,15 @@ +package tech.riemann.ims.mapper.dictionary; + +import tech.riemann.ims.entity.dictionary.Dictionary; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 码本数据 Mapper 接口 + * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-14 15:42:31 + */ +public interface DictionaryMapper extends BaseMapper { + +} diff --git a/src/main/java/tech/riemann/ims/mapper/dictionary/GroupMapper.java b/src/main/java/tech/riemann/ims/mapper/dictionary/GroupMapper.java new file mode 100644 index 0000000..9ea261a --- /dev/null +++ b/src/main/java/tech/riemann/ims/mapper/dictionary/GroupMapper.java @@ -0,0 +1,15 @@ +package tech.riemann.ims.mapper.dictionary; + +import tech.riemann.ims.entity.dictionary.Group; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 码本分组 Mapper 接口 + * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-14 15:42:31 + */ +public interface GroupMapper extends BaseMapper { + +} diff --git a/src/main/java/tech/riemann/ims/mapper/material/ApplyDetailMapper.java b/src/main/java/tech/riemann/ims/mapper/material/ApplyDetailMapper.java new file mode 100644 index 0000000..6762936 --- /dev/null +++ b/src/main/java/tech/riemann/ims/mapper/material/ApplyDetailMapper.java @@ -0,0 +1,11 @@ +package tech.riemann.ims.mapper.material; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import tech.riemann.ims.entity.Inventory.ApplyDetail; + +/** + * @author mayong + * @since 2024/11/28 15:38 + */ +public interface ApplyDetailMapper extends BaseMapper { +} diff --git a/src/main/java/tech/riemann/ims/mapper/material/ApplyFormMapper.java b/src/main/java/tech/riemann/ims/mapper/material/ApplyFormMapper.java new file mode 100644 index 0000000..4dee4f0 --- /dev/null +++ b/src/main/java/tech/riemann/ims/mapper/material/ApplyFormMapper.java @@ -0,0 +1,11 @@ +package tech.riemann.ims.mapper.material; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import tech.riemann.ims.entity.Inventory.ApplyForm; + +/** + * @author mayong + * @since 2024/11/28 15:38 + */ +public interface ApplyFormMapper extends BaseMapper { +} diff --git a/src/main/java/tech/riemann/ims/mapper/material/MaterialMapper.java b/src/main/java/tech/riemann/ims/mapper/material/MaterialMapper.java new file mode 100644 index 0000000..85422e3 --- /dev/null +++ b/src/main/java/tech/riemann/ims/mapper/material/MaterialMapper.java @@ -0,0 +1,11 @@ +package tech.riemann.ims.mapper.material; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import tech.riemann.ims.entity.Inventory.Material; + +/** + * @author mayong + * @since 2024/11/27 15:42 + */ +public interface MaterialMapper extends BaseMapper { +} diff --git a/src/main/java/tech/riemann/ims/service/acl/IPermissionService.java b/src/main/java/tech/riemann/ims/service/acl/IPermissionService.java new file mode 100644 index 0000000..5cdb62f --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/acl/IPermissionService.java @@ -0,0 +1,45 @@ +package tech.riemann.ims.service.acl; + +import java.util.List; + +import org.nutz.spring.boot.service.interfaces.IdNameEntityService; + +import com.baomidou.mybatisplus.extension.service.IService; + +import club.zhcs.lina.utils.tree.Tree; +import tech.riemann.ims.entity.acl.Permission; + +/** + *

+ * 权限 服务类 + *

+ * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-10 18:07:15 + */ +public interface IPermissionService extends IService, IdNameEntityService { + + /** + * @param force + * @return + */ + List> permissionTree(Boolean force); + + /** + * @param force + * @return + */ + List permissions(Boolean force); + + /** + * @param permissions + */ + void batchAddPermissions(List permissions); + + /** + * @param permissions + */ + void updatePermissions(List permissions); + +} diff --git a/src/main/java/tech/riemann/ims/service/acl/IRolePermissionService.java b/src/main/java/tech/riemann/ims/service/acl/IRolePermissionService.java new file mode 100644 index 0000000..3f0250d --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/acl/IRolePermissionService.java @@ -0,0 +1,20 @@ +package tech.riemann.ims.service.acl; + +import org.nutz.spring.boot.service.interfaces.IdNameEntityService; + +import com.baomidou.mybatisplus.extension.service.IService; + +import tech.riemann.ims.entity.acl.RolePermission; + +/** + *

+ * 角色权限 服务类 + *

+ * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-10 18:07:15 + */ +public interface IRolePermissionService extends IService, IdNameEntityService { + +} diff --git a/src/main/java/tech/riemann/ims/service/acl/IRoleService.java b/src/main/java/tech/riemann/ims/service/acl/IRoleService.java new file mode 100644 index 0000000..f8900a9 --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/acl/IRoleService.java @@ -0,0 +1,43 @@ +package tech.riemann.ims.service.acl; + +import java.util.List; + +import org.nutz.spring.boot.service.interfaces.IdNameEntityService; + +import com.baomidou.mybatisplus.extension.service.IService; + +import tech.riemann.ims.dto.response.PermissionInfo; +import tech.riemann.ims.entity.acl.Permission; +import tech.riemann.ims.entity.acl.Role; + +/** + *

+ * 角色 服务类 + *

+ * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-10 18:07:15 + */ +public interface IRoleService extends IService, IdNameEntityService { + + /** + * @param key + * @return + */ + List permissionsByRoleKey(String key); + + /** + * @param key + * @return + */ + List permissionInfosByKey(String key); + + /** + * @param key + * @param permissions + * @return + */ + boolean grant(String key, List permissions); + +} diff --git a/src/main/java/tech/riemann/ims/service/acl/IUserBindService.java b/src/main/java/tech/riemann/ims/service/acl/IUserBindService.java new file mode 100644 index 0000000..de899ff --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/acl/IUserBindService.java @@ -0,0 +1,20 @@ +package tech.riemann.ims.service.acl; + +import org.nutz.spring.boot.service.interfaces.IdNameEntityService; + +import com.baomidou.mybatisplus.extension.service.IService; + +import tech.riemann.ims.entity.acl.UserBind; + +/** + *

+ * 用户三方账号绑定 服务类 + *

+ * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-10 18:07:15 + */ +public interface IUserBindService extends IService, IdNameEntityService { + +} diff --git a/src/main/java/tech/riemann/ims/service/acl/IUserPermissionService.java b/src/main/java/tech/riemann/ims/service/acl/IUserPermissionService.java new file mode 100644 index 0000000..00d3165 --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/acl/IUserPermissionService.java @@ -0,0 +1,20 @@ +package tech.riemann.ims.service.acl; + +import org.nutz.spring.boot.service.interfaces.IdNameEntityService; + +import com.baomidou.mybatisplus.extension.service.IService; + +import tech.riemann.ims.entity.acl.UserPermission; + +/** + *

+ * 用户权限 服务类 + *

+ * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-10 18:07:15 + */ +public interface IUserPermissionService extends IService, IdNameEntityService { + +} diff --git a/src/main/java/tech/riemann/ims/service/acl/IUserRoleService.java b/src/main/java/tech/riemann/ims/service/acl/IUserRoleService.java new file mode 100644 index 0000000..851f4fa --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/acl/IUserRoleService.java @@ -0,0 +1,20 @@ +package tech.riemann.ims.service.acl; + +import org.nutz.spring.boot.service.interfaces.IdNameEntityService; + +import com.baomidou.mybatisplus.extension.service.IService; + +import tech.riemann.ims.entity.acl.UserRole; + +/** + *

+ * 用户角色 服务类 + *

+ * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-10 18:07:15 + */ +public interface IUserRoleService extends IService, IdNameEntityService { + +} diff --git a/src/main/java/tech/riemann/ims/service/acl/IUserService.java b/src/main/java/tech/riemann/ims/service/acl/IUserService.java new file mode 100644 index 0000000..193687b --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/acl/IUserService.java @@ -0,0 +1,80 @@ +package tech.riemann.ims.service.acl; + +import java.util.List; + +import org.nutz.spring.boot.service.interfaces.IdNameEntityService; + +import com.baomidou.mybatisplus.extension.service.IService; + +import club.zhcs.lina.auth.service.AuthUser; +import tech.riemann.ims.controller.platform.auth.AuthController.LoginDTO; +import tech.riemann.ims.dto.response.PermissionInfo; +import tech.riemann.ims.dto.response.RoleInfo; +import tech.riemann.ims.entity.acl.Permission; +import tech.riemann.ims.entity.acl.User; + +/** + *

+ * 用户 服务类 + *

+ * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-10 18:07:15 + */ +public interface IUserService extends IService, IdNameEntityService { + + /** + * 重置密码 + * + * @param name + * 用户名 + * @return 新密码 + */ + String resetPassword(String name); + + /** + * @param name + * @return + */ + List permissionsByUserName(String name); + + /** + * @param name + * @return + */ + List permissionInfosByUserName(String name); + + /** + * @param name + * @param permissions + * @return + */ + boolean grant(String name, List permissions); + + /** + * @param name + * @return + */ + List roleInfosByUserName(String name); + + /** + * @param name + * @param roles + * @return + */ + boolean grantRole(String name, List roles); + + /** + * @param login + * @return + */ + AuthUser login(LoginDTO login); + + /** + * @param key + * @return + */ + AuthUser authUser(String name); + +} diff --git a/src/main/java/tech/riemann/ims/service/acl/impl/PermissionServiceImpl.java b/src/main/java/tech/riemann/ims/service/acl/impl/PermissionServiceImpl.java new file mode 100644 index 0000000..ea01106 --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/acl/impl/PermissionServiceImpl.java @@ -0,0 +1,142 @@ +package tech.riemann.ims.service.acl.impl; + +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import javax.annotation.Nonnull; + +import org.nutz.dao.Dao; +import org.nutz.lang.Lang; +import org.nutz.lang.Strings; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; + +import club.zhcs.lina.utils.tree.Tree; +import club.zhcs.lina.utils.tree.Treeable; +import lombok.RequiredArgsConstructor; +import tech.riemann.ims.dto.response.PermissionTree; +import tech.riemann.ims.entity.acl.Permission; +import tech.riemann.ims.mapper.acl.PermissionMapper; +import tech.riemann.ims.service.acl.IPermissionService; + +/** + *

+ * 权限 服务实现类 + *

+ * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-10 18:07:15 + */ +@Service +@RequiredArgsConstructor +public class PermissionServiceImpl extends ServiceImpl implements IPermissionService { + + private final Dao dao; + + LoadingCache> cache = CacheBuilder.newBuilder() + .concurrencyLevel(8) + .expireAfterAccess(10, TimeUnit.MINUTES) + .initialCapacity(10) + .maximumSize(300) + .recordStats() + .build(new CacheLoader>() { + + @Override + public List load(@Nonnull String key) throws Exception { + return list(); + } + }); + + /** + * @return + * @see org.nutz.spring.boot.service.ExtService#dao() + */ + @Override + public Dao dao() { + return dao; + } + + /** + * @return + * @see org.nutz.spring.boot.service.interfaces.EntityService#getEntityType() + */ + @Override + public Class getEntityType() { + return Permission.class; + } + + /** + * @param force + * @return + * @see tech.riemann.laacam.service.acl.IPermissionService#permissionTree(java.lang.Boolean) + */ + @Override + public List> permissionTree(Boolean force) { + List permissions = permissions(force); + List> permissionTrees = permissions.stream() + .map(PermissionTree::build) + .collect(Collectors.toList()); + return Tree.from(permissionTrees, + permissions.stream() + .filter(organization -> Strings.isBlank(organization.getParentKey())) + .map(Permission::getKey) + .toList()); + } + + /** + * @param force + * @return + * @see tech.riemann.laacam.service.acl.IPermissionService#permissions(java.lang.Boolean) + */ + @Override + public List permissions(Boolean force) { + try { + if (Boolean.TRUE.equals(force)) { + cache.refresh("all"); + } + return cache.get("all"); + } + catch (ExecutionException e) { + throw Lang.wrapThrow(e); + } + } + + /** + * @param permissions + * @see tech.riemann.laacam.service.acl.IPermissionService#batchAddPermissions(java.util.List) + */ + @Override + public void batchAddPermissions(List permissions) { + clear(); + insert(permissions); + } + + /** + * @param permissions + * @see tech.riemann.laacam.service.acl.IPermissionService#updatePermissions(java.util.List) + */ + @Override + public void updatePermissions(List permissions) { + permissions.stream().forEach(permission -> { + if (exists(Wrappers. lambdaQuery().eq(Permission::getKeyPath, permission.getKeyPath()))) { + update( + Wrappers. lambdaUpdate() + .eq(Permission::getKeyPath, permission.getKeyPath()) + .set(Permission::getName, permission.getName()) + .set(Permission::getDescription, permission.getDescription()) + .set(Permission::getType, permission.getType())); + } else { + save(permission); + } + }); + + } +} diff --git a/src/main/java/tech/riemann/ims/service/acl/impl/RolePermissionServiceImpl.java b/src/main/java/tech/riemann/ims/service/acl/impl/RolePermissionServiceImpl.java new file mode 100644 index 0000000..1d4e181 --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/acl/impl/RolePermissionServiceImpl.java @@ -0,0 +1,45 @@ +package tech.riemann.ims.service.acl.impl; + +import org.nutz.dao.Dao; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +import lombok.RequiredArgsConstructor; +import tech.riemann.ims.entity.acl.RolePermission; +import tech.riemann.ims.mapper.acl.RolePermissionMapper; +import tech.riemann.ims.service.acl.IRolePermissionService; + +/** + *

+ * 角色权限 服务实现类 + *

+ * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-10 18:07:15 + */ +@Service +@RequiredArgsConstructor +public class RolePermissionServiceImpl extends ServiceImpl implements IRolePermissionService { + + private final Dao dao; + + /** + * @return + * @see org.nutz.spring.boot.service.ExtService#dao() + */ + @Override + public Dao dao() { + return dao; + } + + /** + * @return + * @see org.nutz.spring.boot.service.interfaces.EntityService#getEntityType() + */ + @Override + public Class getEntityType() { + return RolePermission.class; + } +} diff --git a/src/main/java/tech/riemann/ims/service/acl/impl/RoleServiceImpl.java b/src/main/java/tech/riemann/ims/service/acl/impl/RoleServiceImpl.java new file mode 100644 index 0000000..608754c --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/acl/impl/RoleServiceImpl.java @@ -0,0 +1,93 @@ +package tech.riemann.ims.service.acl.impl; + +import java.util.List; +import java.util.stream.Collectors; + +import org.nutz.dao.Dao; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +import lombok.RequiredArgsConstructor; +import tech.riemann.ims.dto.response.PermissionInfo; +import tech.riemann.ims.entity.acl.Permission; +import tech.riemann.ims.entity.acl.Role; +import tech.riemann.ims.entity.acl.RolePermission; +import tech.riemann.ims.mapper.acl.RoleMapper; +import tech.riemann.ims.mapper.acl.RolePermissionMapper; +import tech.riemann.ims.service.acl.IRoleService; + +/** + *

+ * 角色 服务实现类 + *

+ * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-10 18:07:15 + */ +@Service +@RequiredArgsConstructor +public class RoleServiceImpl extends ServiceImpl implements IRoleService { + + private final Dao dao; + private final RolePermissionMapper rolePermissionMapper; + + /** + * @return + * @see org.nutz.spring.boot.service.ExtService#dao() + */ + @Override + public Dao dao() { + return dao; + } + + /** + * @return + * @see org.nutz.spring.boot.service.interfaces.EntityService#getEntityType() + */ + @Override + public Class getEntityType() { + return Role.class; + } + + /** + * @param key + * @return + * @see tech.riemann.laacam.service.acl.IRoleService#permissionsByRoleKey(java.lang.String) + */ + @Override + public List permissionsByRoleKey(String key) { + return permissionInfosByKey(key) + .stream() + .filter(PermissionInfo::isSelected) + .collect(Collectors.toList()); + } + + /** + * @param key + * @return + * @see tech.riemann.laacam.service.acl.IRoleService#permissionInfosByKey(java.lang.String) + */ + @Override + public List permissionInfosByKey(String key) { + return getBaseMapper().permissionInfosByKey(key); + } + + /** + * @param key + * @param permissions + * @return + * @see tech.riemann.laacam.service.acl.IRoleService#grant(java.lang.String, + * java.util.List) + */ + @Override + public boolean grant(String key, List permissions) { + rolePermissionMapper.delete(Wrappers. lambdaQuery().eq(RolePermission::getRoleKey, key)); + rolePermissionMapper.insert(permissions.stream() + .map(p -> RolePermission.builder().roleKey(key).permissionKeyPath(p).build()) + .collect(Collectors.toList())); + return true; + } +} diff --git a/src/main/java/tech/riemann/ims/service/acl/impl/UserBindServiceImpl.java b/src/main/java/tech/riemann/ims/service/acl/impl/UserBindServiceImpl.java new file mode 100644 index 0000000..4643983 --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/acl/impl/UserBindServiceImpl.java @@ -0,0 +1,45 @@ +package tech.riemann.ims.service.acl.impl; + +import org.nutz.dao.Dao; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +import lombok.RequiredArgsConstructor; +import tech.riemann.ims.entity.acl.UserBind; +import tech.riemann.ims.mapper.acl.UserBindMapper; +import tech.riemann.ims.service.acl.IUserBindService; + +/** + *

+ * 用户三方账号绑定 服务实现类 + *

+ * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-10 18:07:15 + */ +@Service +@RequiredArgsConstructor +public class UserBindServiceImpl extends ServiceImpl implements IUserBindService { + + private final Dao dao; + + /** + * @return + * @see org.nutz.spring.boot.service.ExtService#dao() + */ + @Override + public Dao dao() { + return dao; + } + + /** + * @return + * @see org.nutz.spring.boot.service.interfaces.EntityService#getEntityType() + */ + @Override + public Class getEntityType() { + return UserBind.class; + } +} diff --git a/src/main/java/tech/riemann/ims/service/acl/impl/UserPermissionServiceImpl.java b/src/main/java/tech/riemann/ims/service/acl/impl/UserPermissionServiceImpl.java new file mode 100644 index 0000000..f3d0eec --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/acl/impl/UserPermissionServiceImpl.java @@ -0,0 +1,45 @@ +package tech.riemann.ims.service.acl.impl; + +import org.nutz.dao.Dao; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +import lombok.RequiredArgsConstructor; +import tech.riemann.ims.entity.acl.UserPermission; +import tech.riemann.ims.mapper.acl.UserPermissionMapper; +import tech.riemann.ims.service.acl.IUserPermissionService; + +/** + *

+ * 用户权限 服务实现类 + *

+ * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-10 18:07:15 + */ +@Service +@RequiredArgsConstructor +public class UserPermissionServiceImpl extends ServiceImpl implements IUserPermissionService { + + private final Dao dao; + + /** + * @return + * @see org.nutz.spring.boot.service.ExtService#dao() + */ + @Override + public Dao dao() { + return dao; + } + + /** + * @return + * @see org.nutz.spring.boot.service.interfaces.EntityService#getEntityType() + */ + @Override + public Class getEntityType() { + return UserPermission.class; + } +} diff --git a/src/main/java/tech/riemann/ims/service/acl/impl/UserRoleServiceImpl.java b/src/main/java/tech/riemann/ims/service/acl/impl/UserRoleServiceImpl.java new file mode 100644 index 0000000..0ba471e --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/acl/impl/UserRoleServiceImpl.java @@ -0,0 +1,45 @@ +package tech.riemann.ims.service.acl.impl; + +import org.nutz.dao.Dao; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +import lombok.RequiredArgsConstructor; +import tech.riemann.ims.entity.acl.UserRole; +import tech.riemann.ims.mapper.acl.UserRoleMapper; +import tech.riemann.ims.service.acl.IUserRoleService; + +/** + *

+ * 用户角色 服务实现类 + *

+ * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-10 18:07:15 + */ +@Service +@RequiredArgsConstructor +public class UserRoleServiceImpl extends ServiceImpl implements IUserRoleService { + + private final Dao dao; + + /** + * @return + * @see org.nutz.spring.boot.service.ExtService#dao() + */ + @Override + public Dao dao() { + return dao; + } + + /** + * @return + * @see org.nutz.spring.boot.service.interfaces.EntityService#getEntityType() + */ + @Override + public Class getEntityType() { + return UserRole.class; + } +} diff --git a/src/main/java/tech/riemann/ims/service/acl/impl/UserServiceImpl.java b/src/main/java/tech/riemann/ims/service/acl/impl/UserServiceImpl.java new file mode 100644 index 0000000..8bb1efb --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/acl/impl/UserServiceImpl.java @@ -0,0 +1,243 @@ +package tech.riemann.ims.service.acl.impl; + +import java.util.List; +import java.util.stream.Collectors; + +import org.nutz.dao.Dao; +import org.nutz.lang.Lang; +import org.nutz.lang.Strings; +import org.nutz.lang.random.R; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +import club.zhcs.lina.auth.encode.PasswordUtils; +import club.zhcs.lina.auth.jwt.JWTEncoder; +import club.zhcs.lina.auth.service.AuthUser; +import club.zhcs.lina.starter.exception.BizException; +import lombok.RequiredArgsConstructor; +import tech.riemann.ims.controller.platform.auth.AuthController.LoginDTO; +import tech.riemann.ims.dto.response.PermissionInfo; +import tech.riemann.ims.dto.response.RoleInfo; +import tech.riemann.ims.entity.acl.Permission; +import tech.riemann.ims.entity.acl.Role; +import tech.riemann.ims.entity.acl.User; +import tech.riemann.ims.entity.acl.UserPermission; +import tech.riemann.ims.entity.acl.UserRole; +import tech.riemann.ims.mapper.acl.UserMapper; +import tech.riemann.ims.mapper.acl.UserPermissionMapper; +import tech.riemann.ims.mapper.acl.UserRoleMapper; +import tech.riemann.ims.service.acl.IUserService; + +/** + *

+ * 用户 服务实现类 + *

+ * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-10 18:07:15 + */ +@Service +@RequiredArgsConstructor +public class UserServiceImpl extends ServiceImpl implements IUserService { + + private final Dao dao; + private final UserPermissionMapper userPermissionMapper; + private final UserRoleMapper userRoleMapper; + private final JWTEncoder jwtEncoder; + + /** + * @return + * @see org.nutz.spring.boot.service.ExtService#dao() + */ + @Override + public Dao dao() { + return dao; + } + + /** + * @return + * @see org.nutz.spring.boot.service.interfaces.EntityService#getEntityType() + */ + @Override + public Class getEntityType() { + return User.class; + } + + /** + * @param name + * @return + * @see tech.riemann.laacam.service.acl.IUserService#resetPassword(java.lang.String) + */ + @Override + public String resetPassword(String name) { + String newPassword = R.sg(10).next(); + + if (!update(Wrappers. lambdaUpdate() + .eq(User::getName, name) + .set(User::getPassword, + PasswordUtils.randomSaltEncode(newPassword)))) { + throw BizException.create("重置密码失败!"); + } + return newPassword; + } + + /** + * @param name + * @return + * @see tech.riemann.laacam.service.acl.IUserService#permissionsByUserName(java.lang.String) + */ + @Override + public List permissionsByUserName(String name) { + return permissionInfosByUserName(name) + .stream() + .filter(PermissionInfo::isSelected) + .collect(Collectors.toList()); + } + + /** + * @param name + * @return + * @see tech.riemann.laacam.service.acl.IUserService#permissionInfosByUserName(java.lang.String) + */ + @Override + public List permissionInfosByUserName(String name) { + List directPermissionInfos = directPermissionInfosByUserName(name); + List indirectPermissionInfos = indirectPermissionInfosByUserName(name); + directPermissionInfos.stream().forEach(direct -> { + boolean selected = indirectPermissionInfos.stream() + .anyMatch(indirect -> Strings.equals(indirect.getKeyPath(), direct.getKeyPath()) + && indirect.isSelected()); + if (selected) { + direct.setSelected(selected); + } + }); + return directPermissionInfos; + } + + /** + * @param name + * @return + */ + private List indirectPermissionInfosByUserName(String name) { + return getBaseMapper().indirectPermissionInfosByUserName(name); + } + + /** + * @param name + * @return + */ + private List directPermissionInfosByUserName(String name) { + return getBaseMapper().directPermissionInfosByUserName(name); + } + + /** + * @param name + * @param permissions + * @return + * @see tech.riemann.laacam.service.acl.IUserService#grant(java.lang.String, + * java.util.List) + */ + @Override + public boolean grant(String name, List permissions) { + userPermissionMapper.delete(Wrappers. lambdaQuery().eq(UserPermission::getUserName, name)); + userPermissionMapper.insert(permissions.stream() + .map(p -> UserPermission.builder().permissionKeyPath(p).userName(name).build()) + .collect(Collectors.toList())); + return true; + } + + /** + * @param name + * @return + * @see tech.riemann.laacam.service.acl.IUserService#roleInfosByUserName(java.lang.String) + */ + @Override + public List roleInfosByUserName(String name) { + return getBaseMapper().roleInfosByUserName(name); + } + + /** + * @param name + * @param roles + * @return + * @see tech.riemann.laacam.service.acl.IUserService#grantRole(java.lang.String, + * java.util.List) + */ + @Override + public boolean grantRole(String name, List roles) { + userRoleMapper.delete(Wrappers. lambdaQuery().eq(UserRole::getUserName, name)); + userRoleMapper.insert(roles.stream() + .map(role -> UserRole.builder() + .userName(name) + .roleKey(role) + .build()) + .collect(Collectors.toList())); + return true; + } + + /** + * @param login + * @return + * @see tech.riemann.laacam.service.acl.IUserService#login(tech.riemann.laacam.controller.platform.auth.AuthController.LoginDTO) + */ + @Override + public AuthUser login(LoginDTO login) { + AuthUser authUser = null; + if (login.getType() == LoginDTO.Type.ACCOUNT) { + User user = getBaseMapper().selectOne(Wrappers. lambdaQuery().eq(User::getName, login.getUserName())); + if (Lang.isEmpty(user)) { + throw Lang.makeThrow(BizException.class, "不存在的用户: %s", login.getUserName()); + } + if (!PasswordUtils.randomSaltVerify(login.getPassword(), user.getPassword())) { + throw Lang.makeThrow(BizException.class, "用户: %s 密码不正确", login.getUserName()); + } + authUser = authUser(user); + } + return authUser; + } + + /** + * 转换用户 + * + * @param user + * @return + */ + protected AuthUser authUser(User user) { + return user == null ? null + : AuthUser.builder() + .email(user.getEmail()) + .fullName(user.getFullName()) + .mobile(user.getEmail()) + .password(user.getPassword()) + .sex(user.getSex()) + .token(jwtEncoder.token(user.getName())) + .refreshToken(jwtEncoder.refreshToken(user.getName())) + .userName(user.getName()) + .roles(roleInfosByUserName(user.getName()).stream() + .filter(RoleInfo::isSelected) + .map(Role::getKey) + .toList()) + .permissions(permissionInfosByUserName(user.getName()).stream() + .filter(PermissionInfo::isSelected) + .map(Permission::getKeyPath) + .toList()) + .build(); + } + + /** + * @param name + * @return + * @see tech.riemann.laacam.service.acl.IUserService#authUser(java.lang.String) + */ + @Override + public AuthUser authUser(String name) { + User user = getBaseMapper().selectOne(Wrappers. lambdaQuery().eq(User::getName, name)); + if (Lang.isEmpty(user)) { + throw Lang.makeThrow(BizException.class, "不存在的用户: %s", name); + } + return authUser(user); + } +} diff --git a/src/main/java/tech/riemann/ims/service/dictionary/IDictionaryService.java b/src/main/java/tech/riemann/ims/service/dictionary/IDictionaryService.java new file mode 100644 index 0000000..9497b2a --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/dictionary/IDictionaryService.java @@ -0,0 +1,18 @@ +package tech.riemann.ims.service.dictionary; + +import tech.riemann.ims.entity.dictionary.Dictionary; +import com.baomidou.mybatisplus.extension.service.IService; +import org.nutz.spring.boot.service.interfaces.IdNameEntityService; + +/** + *

+ * 码本数据 服务类 + *

+ * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-14 15:42:31 + */ +public interface IDictionaryService extends IService, IdNameEntityService { + +} diff --git a/src/main/java/tech/riemann/ims/service/dictionary/IGroupService.java b/src/main/java/tech/riemann/ims/service/dictionary/IGroupService.java new file mode 100644 index 0000000..7063f38 --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/dictionary/IGroupService.java @@ -0,0 +1,18 @@ +package tech.riemann.ims.service.dictionary; + +import tech.riemann.ims.entity.dictionary.Group; +import com.baomidou.mybatisplus.extension.service.IService; +import org.nutz.spring.boot.service.interfaces.IdNameEntityService; + +/** + *

+ * 码本分组 服务类 + *

+ * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-14 15:42:31 + */ +public interface IGroupService extends IService, IdNameEntityService { + +} diff --git a/src/main/java/tech/riemann/ims/service/dictionary/impl/DictionaryServiceImpl.java b/src/main/java/tech/riemann/ims/service/dictionary/impl/DictionaryServiceImpl.java new file mode 100644 index 0000000..c9a20da --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/dictionary/impl/DictionaryServiceImpl.java @@ -0,0 +1,45 @@ +package tech.riemann.ims.service.dictionary.impl; + +import tech.riemann.ims.entity.dictionary.Dictionary; +import tech.riemann.ims.mapper.dictionary.DictionaryMapper; +import tech.riemann.ims.service.dictionary.IDictionaryService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +import lombok.RequiredArgsConstructor; + +import org.nutz.dao.Dao; +import org.springframework.stereotype.Service; + +/** + *

+ * 码本数据 服务实现类 + *

+ * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-14 15:42:31 + */ +@Service +@RequiredArgsConstructor +public class DictionaryServiceImpl extends ServiceImpl implements IDictionaryService { + + private final Dao dao; + + /** + * @return + * @see org.nutz.spring.boot.service.ExtService#dao() + */ + @Override + public Dao dao() { + return dao; + } + + /** + * @return + * @see org.nutz.spring.boot.service.interfaces.EntityService#getEntityType() + */ + @Override + public Class getEntityType() { + return Dictionary.class; + } +} diff --git a/src/main/java/tech/riemann/ims/service/dictionary/impl/GroupServiceImpl.java b/src/main/java/tech/riemann/ims/service/dictionary/impl/GroupServiceImpl.java new file mode 100644 index 0000000..5a344ee --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/dictionary/impl/GroupServiceImpl.java @@ -0,0 +1,45 @@ +package tech.riemann.ims.service.dictionary.impl; + +import tech.riemann.ims.entity.dictionary.Group; +import tech.riemann.ims.mapper.dictionary.GroupMapper; +import tech.riemann.ims.service.dictionary.IGroupService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +import lombok.RequiredArgsConstructor; + +import org.nutz.dao.Dao; +import org.springframework.stereotype.Service; + +/** + *

+ * 码本分组 服务实现类 + *

+ * + * @author Kerbores(kerbores@gmail.com) + * + * @since 2024-09-14 15:42:31 + */ +@Service +@RequiredArgsConstructor +public class GroupServiceImpl extends ServiceImpl implements IGroupService { + + private final Dao dao; + + /** + * @return + * @see org.nutz.spring.boot.service.ExtService#dao() + */ + @Override + public Dao dao() { + return dao; + } + + /** + * @return + * @see org.nutz.spring.boot.service.interfaces.EntityService#getEntityType() + */ + @Override + public Class getEntityType() { + return Group.class; + } +} diff --git a/src/main/java/tech/riemann/ims/service/material/IApplyDetailService.java b/src/main/java/tech/riemann/ims/service/material/IApplyDetailService.java new file mode 100644 index 0000000..49d5ab5 --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/material/IApplyDetailService.java @@ -0,0 +1,12 @@ +package tech.riemann.ims.service.material; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.nutz.spring.boot.service.interfaces.IdNameEntityService; +import tech.riemann.ims.entity.Inventory.ApplyDetail; + +/** + * @author mayong + * @since 2024/11/28 15:41 + */ +public interface IApplyDetailService extends IService, IdNameEntityService { +} diff --git a/src/main/java/tech/riemann/ims/service/material/IApplyFormService.java b/src/main/java/tech/riemann/ims/service/material/IApplyFormService.java new file mode 100644 index 0000000..b2fa4d5 --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/material/IApplyFormService.java @@ -0,0 +1,12 @@ +package tech.riemann.ims.service.material; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.nutz.spring.boot.service.interfaces.IdNameEntityService; +import tech.riemann.ims.entity.Inventory.ApplyForm; + +/** + * @author mayong + * @since 2024/11/28 15:35 + */ +public interface IApplyFormService extends IService, IdNameEntityService { +} diff --git a/src/main/java/tech/riemann/ims/service/material/IMaterialService.java b/src/main/java/tech/riemann/ims/service/material/IMaterialService.java new file mode 100644 index 0000000..2579f72 --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/material/IMaterialService.java @@ -0,0 +1,12 @@ +package tech.riemann.ims.service.material; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.nutz.spring.boot.service.interfaces.IdNameEntityService; +import tech.riemann.ims.entity.Inventory.Material; + +/** + * @author mayong + * @since 2024/11/27 15:40 + */ +public interface IMaterialService extends IService, IdNameEntityService { +} diff --git a/src/main/java/tech/riemann/ims/service/material/impl/ApplyDetailServiceImpl.java b/src/main/java/tech/riemann/ims/service/material/impl/ApplyDetailServiceImpl.java new file mode 100644 index 0000000..1b833a1 --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/material/impl/ApplyDetailServiceImpl.java @@ -0,0 +1,25 @@ +package tech.riemann.ims.service.material.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.RequiredArgsConstructor; +import org.nutz.dao.Dao; +import org.springframework.stereotype.Service; +import tech.riemann.ims.entity.Inventory.ApplyDetail; +import tech.riemann.ims.mapper.material.ApplyDetailMapper; +import tech.riemann.ims.service.material.IApplyDetailService; + +/** + * @author mayong + * @since 2024/11/28 15:36 + */ +@Service +@RequiredArgsConstructor +public class ApplyDetailServiceImpl extends ServiceImpl implements IApplyDetailService { + + private final Dao dao; + + @Override + public Dao dao() { + return dao; + } +} diff --git a/src/main/java/tech/riemann/ims/service/material/impl/ApplyFormServiceImpl.java b/src/main/java/tech/riemann/ims/service/material/impl/ApplyFormServiceImpl.java new file mode 100644 index 0000000..6fcfe8a --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/material/impl/ApplyFormServiceImpl.java @@ -0,0 +1,25 @@ +package tech.riemann.ims.service.material.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.RequiredArgsConstructor; +import org.nutz.dao.Dao; +import org.springframework.stereotype.Service; +import tech.riemann.ims.entity.Inventory.ApplyForm; +import tech.riemann.ims.mapper.material.ApplyFormMapper; +import tech.riemann.ims.service.material.IApplyFormService; + +/** + * @author mayong + * @since 2024/11/28 15:36 + */ +@Service +@RequiredArgsConstructor +public class ApplyFormServiceImpl extends ServiceImpl implements IApplyFormService { + + private final Dao dao; + + @Override + public Dao dao() { + return dao; + } +} diff --git a/src/main/java/tech/riemann/ims/service/material/impl/MaterialServiceImpl.java b/src/main/java/tech/riemann/ims/service/material/impl/MaterialServiceImpl.java new file mode 100644 index 0000000..56edf44 --- /dev/null +++ b/src/main/java/tech/riemann/ims/service/material/impl/MaterialServiceImpl.java @@ -0,0 +1,24 @@ +package tech.riemann.ims.service.material.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.RequiredArgsConstructor; +import org.nutz.dao.Dao; +import org.springframework.stereotype.Service; +import tech.riemann.ims.entity.Inventory.Material; +import tech.riemann.ims.mapper.material.MaterialMapper; +import tech.riemann.ims.service.material.IMaterialService; + +/** + * @author mayong + * @since 2024/11/27 15:41 + */ +@Service +@RequiredArgsConstructor +public class MaterialServiceImpl extends ServiceImpl implements IMaterialService { + private final Dao dao; + + @Override + public Dao dao() { + return dao; + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..3b9e3ce --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,154 @@ +# actuator +management: + info: + git: + mode: full + endpoint: + health: + show-details: always + env: + show-values: always + configprops: + show-values: always + endpoints: + web: + exposure: + include: + - "*" +server: + port: 7777 # 改端口号后swagger文档访问不到 + http2: + enabled: true + undertow: + threads: + io: 16 + worker: 256 + buffer-size: 1024 + direct-buffers: true +# nutz +nutz: + json: + enabled: true + mode: compact + date-format: yyyy-MM-dd HH:mm:ss + dao: + sql-template: + enable: true + type: beetl + runtime: + add-column: true + basepackage: + - tech.riemann.ims.entity + - BOOT-INF.classes.tech.riemann.ims.entity + check-index: false + create: true + delete-column: false + migration: true + sql-manager: + paths: + - sqls +mybatis-plus: + global-config: + db-config: + property-format: '`%s`' + configuration: + auto-mapping-behavior: full +# spring +spring: + output: + ansi: + enabled: always + pid: + fail-on-write-error: true + file: ${user.home}/${spring.application.name}.pid #pid文件 + servlet: + multipart: # 文件上传 + max-file-size: 10MB + max-request-size: 50MB + application: + name: ims + datasource: + url: jdbc:mysql://mysql.riemann.tech:13307/hx_jxc?characterEncoding=UTF-8 + username: hx_jxc + password: BBSzc7cnbAhLAenT + driver-class-name: com.mysql.cj.jdbc.Driver + druid: + filters: stat,wall,log4j2 + initial-size: 10 + min-idle: 1 + max-active: 50 + max-wait: 60000 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + validation-query: SELECT 'ezalor' + test-while-idle: true + test-on-borrow: true + test-on-return: false + pool-prepared-statements: true + max-pool-prepared-statement-per-connection-size: 20 + web-stat-filter: + enabled: true + url-pattern: /* + exclusions: /druid/*,*.js,*.gif,*.jpg,*.png,*.css,*.ico + stat-view-servlet: + enabled: true + url-pattern: /druid/* + reset-enable: true +# 日志配置 +logging: + file: + name: ${user.home}/logs/${spring.application.name}.log + path: ${user.home}/logs + level: + "[org.nutz]": debug + "[club.zhcs]": debug + "[tech.riemann]": debug + "[org.apache.logging]": off + "[io.swagger]": off +# swagger配置 +springdoc: + customer: + theme: feeling-blue + title: 库管系统 + url: https://www.riemann.tech + config-url: /v3/api-docs/swagger-config + server: + url: http://localhost:7777 + description: 物料库存管理系统 + info: + title: 库管系统 + description: 物料库存管理系统 API接口文档 + version: 1.0.0 + terms-of-service: https://github.com/nutzam/nutz-spring-boot-starter + license: + name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0 + contact: + email: product@ipmt.online + name: ETP + url: https://www.riemann.tech + swagger-ui: + enabled: true + group-configs: + - group: default + packages-to-scan: + - tech.riemann.ims.controller + - group: acl + packages-to-scan: + - tech.riemann.ims.controller.platform.acl + - group: dictionary + packages-to-scan: + - tech.riemann.ims.controller.platform.dictionary + - group: auth + packages-to-scan: + - tech.riemann.ims.controller.platform.auth + - group: material + packages-to-scan: + - tech.riemann.ims.controller.platform.material + api-docs: + enabled: true + groups: + enabled: true +lina: + oidc: + enabled: false \ No newline at end of file diff --git a/src/main/resources/mapper/RoleMapper.xml b/src/main/resources/mapper/RoleMapper.xml new file mode 100644 index 0000000..5fb0d0b --- /dev/null +++ b/src/main/resources/mapper/RoleMapper.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, + created_time, + updated_time, + created_by, + updated_by, + r_key, r_name, r_description + + + \ No newline at end of file diff --git a/src/main/resources/mapper/UserMapper.xml b/src/main/resources/mapper/UserMapper.xml new file mode 100644 index 0000000..b4439dd --- /dev/null +++ b/src/main/resources/mapper/UserMapper.xml @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, + created_time, + updated_time, + created_by, + updated_by, + u_name, u_password, u_mobile, u_sex, u_email, u_full_name + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper_/DictionaryMapper.xml b/src/main/resources/mapper_/DictionaryMapper.xml new file mode 100644 index 0000000..cde61ed --- /dev/null +++ b/src/main/resources/mapper_/DictionaryMapper.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + id, + created_time, + updated_time, + created_by, + updated_by, + d_group_key, d_parent_key, d_index, d_key, d_value, d_description, d_disabled + + \ No newline at end of file diff --git a/src/main/resources/mapper_/GroupMapper.xml b/src/main/resources/mapper_/GroupMapper.xml new file mode 100644 index 0000000..6379770 --- /dev/null +++ b/src/main/resources/mapper_/GroupMapper.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + id, + created_time, + updated_time, + created_by, + updated_by, + g_key, g_name, g_description, g_disabled + + \ No newline at end of file diff --git a/src/main/resources/mapper_/PermissionMapper.xml b/src/main/resources/mapper_/PermissionMapper.xml new file mode 100644 index 0000000..1035202 --- /dev/null +++ b/src/main/resources/mapper_/PermissionMapper.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + id, + created_time, + updated_time, + created_by, + updated_by, + p_key, p_key_path, p_name, p_description, p_parent_key, p_type + + \ No newline at end of file diff --git a/src/main/resources/mapper_/RoleMapper.xml b/src/main/resources/mapper_/RoleMapper.xml new file mode 100644 index 0000000..7a92537 --- /dev/null +++ b/src/main/resources/mapper_/RoleMapper.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + id, + created_time, + updated_time, + created_by, + updated_by, + r_key, r_name, r_description + + \ No newline at end of file diff --git a/src/main/resources/mapper_/RolePermissionMapper.xml b/src/main/resources/mapper_/RolePermissionMapper.xml new file mode 100644 index 0000000..c1883ff --- /dev/null +++ b/src/main/resources/mapper_/RolePermissionMapper.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + id, + created_time, + updated_time, + created_by, + updated_by, + rp_role_key, rp_permission_key_path + + \ No newline at end of file diff --git a/src/main/resources/mapper_/UserBindMapper.xml b/src/main/resources/mapper_/UserBindMapper.xml new file mode 100644 index 0000000..a9f0218 --- /dev/null +++ b/src/main/resources/mapper_/UserBindMapper.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + id, + created_time, + updated_time, + created_by, + updated_by, + b_user_name, b_type, b_openid, b_metadata, b_uuid + + \ No newline at end of file diff --git a/src/main/resources/mapper_/UserMapper.xml b/src/main/resources/mapper_/UserMapper.xml new file mode 100644 index 0000000..9ceda1c --- /dev/null +++ b/src/main/resources/mapper_/UserMapper.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + id, + created_time, + updated_time, + created_by, + updated_by, + u_name, u_password, u_mobile, u_sex, u_email, u_full_name + + \ No newline at end of file diff --git a/src/main/resources/mapper_/UserPermissionMapper.xml b/src/main/resources/mapper_/UserPermissionMapper.xml new file mode 100644 index 0000000..8a993e8 --- /dev/null +++ b/src/main/resources/mapper_/UserPermissionMapper.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + id, + created_time, + updated_time, + created_by, + updated_by, + up_user_name, up_permission_key_path + + \ No newline at end of file diff --git a/src/main/resources/mapper_/UserRoleMapper.xml b/src/main/resources/mapper_/UserRoleMapper.xml new file mode 100644 index 0000000..08d51d7 --- /dev/null +++ b/src/main/resources/mapper_/UserRoleMapper.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + id, + created_time, + updated_time, + created_by, + updated_by, + ur_user_name, ur_role_key + + \ No newline at end of file diff --git a/src/test/java/tech/riemann/ims/ApplicationTests.java b/src/test/java/tech/riemann/ims/ApplicationTests.java new file mode 100644 index 0000000..417f21c --- /dev/null +++ b/src/test/java/tech/riemann/ims/ApplicationTests.java @@ -0,0 +1,13 @@ +package tech.riemann.ims; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class ApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/src/test/java/tech/riemann/ims/MysqlGenerator.java b/src/test/java/tech/riemann/ims/MysqlGenerator.java new file mode 100644 index 0000000..2e67015 --- /dev/null +++ b/src/test/java/tech/riemann/ims/MysqlGenerator.java @@ -0,0 +1,167 @@ +package tech.riemann.ims; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.stream.Collectors; + +import org.nutz.lang.Lang; +import org.nutz.lang.Strings; +import org.nutz.lang.util.NutMap; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.generator.FastAutoGenerator; +import com.baomidou.mybatisplus.generator.config.ConstVal; +import com.baomidou.mybatisplus.generator.config.OutputFile; +import com.baomidou.mybatisplus.generator.config.rules.DateType; +import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; +import com.baomidou.mybatisplus.generator.engine.BeetlTemplateEngine; + +import tech.riemann.ims.entity.IdBaseEntity; + +public class MysqlGenerator { + + static String jdbcUrl = "jdbc:mysql://mysql.riemann.tech:13307/hx_jxc?characterEncoding=UTF-8"; + static String user = "hx_jxc"; + static String password = "BBSzc7cnbAhLAenT"; + static String packageName = "tech.riemann"; + static String module = "ims"; + + static Mode mode = Mode.BOTH; + + public enum Mode { + NUTZ, + MYBATIS, + BOTH + } + + public static String[] prefixes(String... addOn) { + List pool = Lang.array2list("abcdefghijklmnopqrstuvwxyz".toCharArray(), char.class) + .stream() + .map(c -> c + "") + .toList(); + + List prefixes = pool.stream().map(item -> item + "_").collect(Collectors.toList()); + + pool.stream().forEach(item -> { + pool.stream().forEach(item1 -> { + prefixes.add(String.format("%s%s_", item, item1)); + }); + }); + if (Lang.isNotEmpty(addOn)) { + Arrays.stream(addOn).forEach(add -> { + Arrays.stream(Lang.collection2array(prefixes)).forEach(p -> { + prefixes.add(String.format("%s%s_", p, add)); + }); + }); + } + return Lang.collection2array(prefixes); + } + + /** + * RUN THIS TO GEN CODE + */ + public static void main(String[] args) { + + String projectPath = System.getProperty("user.dir"); + List relationTables = Lang.list("t_role_permission", "t_user_permission", "t_user_role", "t_user_bind"); + NutMap.NEW() + // .addv("acl", Lang.array("t_user", "t_role", "t_permission", + // "t_role_permission", "t_user_permission", "t_user_role", + // "t_user_bind")) + // .addv("dictionary", Lang.array("t_dictionary", "t_group")) + // .addv("sensor", Lang.array("t_sensor", "t_sensor_log")) + // .addv("station", Lang.array("t_station", "t_team")) + .addv("station.status", Lang.array("t_station_status", "t_power_log", "t_working_log")) + .entrySet() + .stream() + .forEach(e -> { + + FastAutoGenerator.create(jdbcUrl, user, password) + .globalConfig(builder -> { + builder + .author("Kerbores(kerbores@gmail.com)") + .enableSpringdoc() + .commentDate(() -> LocalDateTime.now() + .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", + Locale.CHINESE))) + .disableOpenDir() + .dateType(DateType.TIME_PACK) + .outputDir(projectPath + "/src/main/java"); + }) + .injectionConfig(builder -> builder.customMap(Collections.singletonMap("mode", mode))) + .packageConfig(builder -> { + builder.parent(packageName) + .moduleName(module) + .entity(String.format("entity.%s", e.getKey())) + .mapper(String.format("mapper.%s", e.getKey())) + .service(String.format("service.%s", e.getKey())) + .serviceImpl(String.format("service.%s.impl", e.getKey())) + .controller(String.format("controller.platform.%s", e.getKey())) + .pathInfo(Collections.singletonMap(OutputFile.xml, + String.format("%s/src/main/resources/mapper_", + projectPath))); + }) + .strategyConfig(builder -> { + builder.addTablePrefix("t_") + .addFieldPrefix(prefixes(e.getKey())) + .addInclude((String[]) e.getValue()) // 指定表生成 + .entityBuilder() + .javaTemplate(String.format("templates/%s/entity.java", mode.name().toLowerCase())) + .enableLombok() + .enableFileOverride() + .enableChainModel() + .enableRemoveIsPrefix() + .enableTableFieldAnnotation() + .superClass(IdBaseEntity.class) + .addSuperEntityColumns( + "id", + "created_by", + "created_time", + "updated_by", + // "f_budget_id", + // "f_matter_id", + // "f_remark", + "updated_time") + .naming(NamingStrategy.underline_to_camel) + .controllerBuilder() + .template(String.format("templates/%s/controller.java", mode.name().toLowerCase())) + .enableRestStyle() + .enableHyphenStyle() + .convertFileName(entityName -> { + boolean isRelation = relationTables.stream().anyMatch(item -> { + String name = NamingStrategy.capitalFirst( + NamingStrategy.underlineToCamel( + item.replace(String.format("t_%s_", + e.getKey()), + ""))); + return Strings.equals(entityName, name); + }); + return isRelation ? null : entityName + ConstVal.CONTROLLER; + }) + .mapperBuilder() + .mapperTemplate(String.format("/templates/%s/mapper.java", mode.name().toLowerCase())) + .mapperXmlTemplate(mode == Mode.NUTZ ? "" + : String.format("/templates/%s/mapper.xml", mode.name().toLowerCase())) + .convertMapperFileName(entityName -> mode == Mode.NUTZ ? entityName + "Repository" : entityName + ConstVal.MAPPER) + .convertXmlFileName(entityName -> mode == Mode.NUTZ ? null : entityName + ConstVal.MAPPER) + .superClass(BaseMapper.class) + .enableBaseResultMap() + .enableBaseColumnList() + .serviceBuilder() + .serviceTemplate(String.format("/templates/%s/service.java", mode.name().toLowerCase())) + .serviceImplTemplate(String.format("/templates/%s/serviceImpl.java", mode.name().toLowerCase())) + .convertServiceFileName(entityName -> (mode == Mode.NUTZ ? "" : "I") + + entityName + + ConstVal.SERVICE) + .convertServiceImplFileName(entityName -> entityName + ConstVal.SERVICE_IMPL); + }) + .templateEngine(new BeetlTemplateEngine()) + .execute(); + }); + + } +} diff --git a/src/test/resources/templates/both/controller.java.btl b/src/test/resources/templates/both/controller.java.btl new file mode 100644 index 0000000..dc42cbe --- /dev/null +++ b/src/test/resources/templates/both/controller.java.btl @@ -0,0 +1,241 @@ +package ${package.Controller}; + +import org.nutz.lang.Lang; +import org.nutz.lang.Strings; +import lombok.RequiredArgsConstructor; +import tech.riemann.axe.exception.BizException; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +<% if(restControllerStyle){ %> +import org.springframework.web.bind.annotation.RestController; +<% }else{ %> +import org.springframework.stereotype.Controller; +<% } %> +<% if(isNotEmpty(superControllerClassPackage)){ %> +import ${superControllerClassPackage}; +<% } %> +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import ${package.Entity}.${entity}; +import ${package.Service}.${table.serviceName}; + +<% if(springdoc){ %> +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +<% } %> +/** + *

+ * ${table.comment!} 前端控制器 + *

+ * + * @author ${author} + * + * @since ${date} + */ +<% if(restControllerStyle){ %> +@RestController +<% }else{ %> +@Controller +<% } %> +<% if(kotlin){ %> +class ${table.controllerName}<% if(isNotEmpty(superControllerClass)){ %> : ${superControllerClass}()<% } %> +<% }else{ %> + <% if(isNotEmpty(superControllerClass)){ %> +public class ${table.controllerName} extends ${superControllerClass} { + <% }else{ %> + <% if(springdoc){ %> +@Tag(name = "${entity}", description = "${table.comment!''}") + <% } %> +@RequiredArgsConstructor +public class ${table.controllerName} { + <% } %> + + <% + var entityNameFirst = strutil.subStringTo(entity,0,1); + var entityNameFirstLower = strutil.toLowerCase(entityNameFirst); + var entityName = strutil.replace(entity,entityNameFirst,entityNameFirstLower); + %> + private final ${table.serviceName} ${entityName}Service; + + /** + * 分页查询${table.comment!} + * + * @param page + * 页码 + * @param size + * 分页大小 + * @param key + * 关键词 + * @return ${table.comment!}分页数据 + */ + @GetMapping("${controllerMappingHyphen}s") + <% if(springdoc){ %> + @Operation(summary = "分页查询${table.comment!''}") + public IPage<${entity}> ${entityName}s( + @Parameter(description = "页码") @RequestParam(value = "page", required = false, defaultValue = "1") long page, + @Parameter(description = "页面大小") @RequestParam(value = "size", required = false, defaultValue = "10") long size, + @Parameter(description = "搜索关键词") @RequestParam(name = "key", required = false, defaultValue = "") String key) { + <% }else{ %> + public IPage<${entity}> ${entityName}s(@RequestParam("page") long page, + @RequestParam("size") long size, + @RequestParam(name = "key", required = false, defaultValue = "") String key) { + <% } %> + boolean hasLike = Strings.isNotBlank(key); + key = String.format("%%%s%%", key); + /** + * TODO 根据业务情况进行搜索字段和条件的处理 + * + *
+         *                                     Wrappers.<${entity}> lambdaQuery()
+         *                                                .like(hasLike, ${entity}::getName, key)
+         *                                                .or()
+         *                                                .like(hasLike, ${entity}::getMobile, key)
+         * 
+ * + * nutz实现 + * + *
+         * return ${entityName}Service.searchByKeyAndPage(key,
+         *                                       page,
+         *                                       size,
+         *                                       ${entity}.Fields.name); 
+         * 
+ */ + return ${entityName}Service.page(Page.<${entity}> of(page, size), + Wrappers.<${entity}> lambdaQuery() + .like(hasLike, ${entity}::getName, key)); + } + + /** + * ${table.comment!}详情 + * + * @param id + * ${table.comment!}id + * @return ${table.comment!} + */ + @GetMapping("${controllerMappingHyphen}/{id}") + <% if(springdoc){ %> + @Operation(summary ="${table.comment!''}详情") + public ${entity} detail(@Parameter(description = "${table.comment!''}id", required = true) @PathVariable("id") long id) { + <% }else{ %> + public ${entity} detail(@PathVariable("id") long id) { + <% } %> + /** + * TODO 根据情况调整参数和查询条件 + * nutz实现 + * + *
+         * return ${entityName}Service.fetch(id);
+         * 
+ */ + return ${entityName}Service.getById(id); + } + + /** + * 添加${table.comment!} + * + * @param ${entityName} + * ${table.comment!}数据 + * @return ${table.comment!} + */ + @PostMapping("${controllerMappingHyphen}") + <% if(springdoc){ %> + @Operation(summary = "增加${table.comment!''}") + public ${entity} add(@Validated @Parameter(description ="${table.comment!''}")@RequestBody ${entity} ${entityName}) { + <% }else{ %> + public ${entity} add(@Validated @RequestBody ${entity} ${entityName}) { + <% } %> + /** + * TODO 根据实际情况处理业务 + * nutz实现 + * + *
+         * return ${entityName}Service.insert(${entityName});
+         * 
+ */ + if (${entityName}Service.save(${entityName})) { + return ${entityName}; + } else { + throw BizException.create("保存${table.comment!}失败!"); + } + } + + /** + * 编辑${table.comment!} + * + * @param ${entityName} + * ${table.comment!}数据 + * @return ${table.comment!} + */ + @PatchMapping("${controllerMappingHyphen}") + <% if(springdoc){ %> + @Operation(summary = "更新${table.comment!''}") + public ${entity} update(@Validated @Parameter(description ="${table.comment!''}")@RequestBody ${entity} ${entityName}) { + <% }else{ %> + public ${entity} update(@Validated @RequestBody ${entity} ${entityName}) { + <% } %> + /** + * TODO 根据实际情况进行更新条件和字段的处理
+ * + *
+         * ${entityName}Service.update(Wrappers.<${entity}> lambdaUpdate().set(${entity}::getName, ${entityName}.getName()).eq(${entity}::getId, ${entityName}.getId()));
+         * 
+ * + * nutz实现 + * + *
+         * ${entityName}Service.update(${entityName});
+         * 
+ */ + if (${entityName}Service.update(${entityName}, Wrappers.<${entity}> lambdaUpdate().eq(${entity}::getId, ${entityName}.getId()))) { + return ${entityName}; + } else { + throw BizException.create("更新${table.comment!}失败!"); + } + } + + /** + * 删除${table.comment!} + * + * @param id + * ${table.comment!}id + * @return 是否删除成功 + */ + @DeleteMapping("${controllerMappingHyphen}/{id}") + <% if(springdoc){ %> + @Operation(summary = "删除${table.comment!''}") + public void delete${entity}(@Parameter(description = "${table.comment!''}id", required = true)@PathVariable("id") long id) { + <% }else{ %> + public void delete${entity}(@PathVariable("id") long id) { + <% } %> + /** + * TODO 根据情况调整参数和删除逻辑
+ * + *
+         * ${entityName}Service.update(Wrappers.<${entity}> lambdaUpdate().set(${entity}::getStatus, false).eq(${entity}::getId, id));
+         * 
+ * + * nutz实现 + * + *
+         * if(${entityName}Service.delete(id) != 1){
+         *		throw Lang.makeThrow("删除${table.comment!}失败!");
+         * }
+         * 
+ */ + if(! ${entityName}Service.removeById(id)){ + throw BizException.create("删除${table.comment!}失败!"); + } + } + +} +<% } %> \ No newline at end of file diff --git a/src/test/resources/templates/both/entity.java.btl b/src/test/resources/templates/both/entity.java.btl new file mode 100644 index 0000000..13469f9 --- /dev/null +++ b/src/test/resources/templates/both/entity.java.btl @@ -0,0 +1,202 @@ +package ${package.Entity}; + +<% for(pkg in table.importPackages){ %> +import ${pkg}; +<% } %> +import org.nutz.dao.entity.annotation.Column; +import org.nutz.dao.entity.annotation.Comment; +import org.nutz.dao.entity.annotation.Name; +import org.nutz.dao.entity.annotation.Table; +import org.nutz.dao.entity.annotation.ColDefine; +<% if(springdoc){ %> +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +<% }else if(swagger){ %> +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +<% } %> +<% if(entityLombokModel){ %> +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import lombok.experimental.FieldNameConstants; +import lombok.experimental.SuperBuilder; +<% if(chainModel){ %> +import lombok.experimental.Accessors; +<% } %> +<% } %> + +/** + * ${table.comment!} + * + * @author ${author} + * + * @since ${date} + */ +<% if(entityLombokModel){ %> +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@FieldNameConstants +@EqualsAndHashCode(callSuper = true) + <% if(chainModel){ %> +@Accessors(chain = true) + <% } %> +<% } %> +<% if(table.convert){ %> +@TableName("${schemaName}${table.name}") +@Table("${schemaName}${table.name}") +@Comment("${table.comment!''}") +<% } %> +<% if(springdoc){ %> +@Schema(name = "${entity}", description = "${table.comment!''}") +<% }else if(swagger){ %> +@ApiModel(value = "${entity}对象", description = "${table.comment!''}") +<% } %> +<% if(isNotEmpty(superEntityClass)){ %> +public class ${entity} extends ${superEntityClass}<% if(activeRecord){ %><${entity}><%}%>{ +<% }else if(activeRecord){ %> +public class ${entity} extends Model<${entity}> { +<% }else if(entitySerialVersionUID){ %> +public class ${entity} implements Serializable { +<% }else{ %> +public class ${entity} { +<% } %> +<% if(entitySerialVersionUID){ %> + + private static final long serialVersionUID = 1L; +<% } %> +<% var keyPropertyName; %> +<% /** -----------BEGIN 字段循环遍历----------- **/ %> +<% for(field in table.fields){ %> + <% + if(field.keyFlag){ + keyPropertyName = field.propertyName; + } + %> + <% if(isNotEmpty(field.comment)){ %> + + <% if(springdoc){ %> + @Schema(description = "${field.comment}", requiredMode = ${!field.metaInfo.nullable? 'RequiredMode.REQUIRED' :'RequiredMode.NOT_REQUIRED'}) + <% }else if(swagger){ %> + @ApiModelProperty(value = "${field.comment}") + <% }else{ %> + /** + * ${field.comment} + */ + <% } %> + <% } %> + <% if(field.keyFlag){ %> + <% + /*主键*/ + %> + <% if(field.keyIdentityFlag){ %> + @TableField(value = "${field.annotationColumnName}", type = IdType.AUTO) + <% }else if(isNotEmpty(idType)){ %> + @TableField(value = "${field.annotationColumnName}", type = IdType.${idType}) + <% }else if(field.convert){ %> + @TableField("${field.annotationColumnName}") + @Name + //@Prev(els=@EL("uuid(32)")) 这样就可以生成主键 + @Column("${field.annotationColumnName}") + @Comment("${field.comment!''}") + @ColDefine(notNull = ${!field.metaInfo.nullable}, width = ${field.metaInfo.length}, precision = ${field.metaInfo.scale}) + <% } %> + <% + /*普通字段*/ + %> + <% }else if(isNotEmpty(field.fill)){ %> + <% if(field.convert){ %> + @TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill}) + @Column("${field.annotationColumnName}") + @Comment("${field.comment!''}") + @ColDefine(notNull = ${!field.metaInfo.nullable}, width = ${field.metaInfo.length}, precision = ${field.metaInfo.scale}) + <% }else{ %> + @TableField(fill = FieldFill.${field.fill}) + @Column("${field.annotationColumnName}") + @Comment("${field.comment!''}") + @ColDefine(notNull = ${!field.metaInfo.nullable}, width = ${field.metaInfo.length}, precision = ${field.metaInfo.scale}) + <% } %> + <% }else if(field.convert){ %> + @TableField("${field.annotationColumnName}") + @Column("${field.annotationColumnName}") + @Comment("${field.comment!''}") + @ColDefine(notNull = ${!field.metaInfo.nullable}, width = ${field.metaInfo.length}, precision = ${field.metaInfo.scale}) + <% } %> + <% + /*乐观锁注解*/ + %> + <% if(field.versionField){ %> + @Version + <% } %> + <% + /*逻辑删除注解*/ + %> + <% if(field.logicDeleteField){ %> + @TableLogic + <% } %> + private ${field.propertyType} ${field.propertyName}; +<% } %> +<% /** -----------END 字段循环遍历----------- **/ %> +<% if(!entityLombokModel){ %> + <% for(field in table.fields){ %> + <% + var getprefix =''; + if(field.propertyType=='boolean'){ + getprefix='is'; + }else{ + getprefix='get'; + } + %> + + public ${field.propertyType} ${getprefix}${field.capitalName}() { + return ${field.propertyName}; + } + + <% if(chainModel){ %> + public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) { + <% }else{ %> + public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) { + <% } %> + this.${field.propertyName} = ${field.propertyName}; + <% if(chainModel){ %> + return this; + <% } %> + } + <% } %> +<% } %> +<% if(entityColumnConstant){ %> + <% for(field in table.fields){ %> + + public static final String ${strutil.toUpperCase(field.name)} = "${field.name}"; + <% } %> +<% } %> +<% if(activeRecord){ %> + + @Override + public Serializable pkVal() { + <% if(isNotEmpty(keyPropertyName)){ %> + return this.${keyPropertyName}; + <% }else{ %> + return null; + <% } %> + } +<% } %> +<% if(!entityLombokModel){ %> + + @Override + public String toString() { + return "${entity}{" + + <% for(field in table.fields){ %> + <% if(fieldLP.index==0){ %> + "${field.propertyName} = " + ${field.propertyName} + + <% }else{ %> + ", ${field.propertyName} = " + ${field.propertyName} + + <% } %> + <% } %> + "}"; + } +<% } %> +} \ No newline at end of file diff --git a/src/test/resources/templates/both/entity.kt.btl b/src/test/resources/templates/both/entity.kt.btl new file mode 100644 index 0000000..0a32b86 --- /dev/null +++ b/src/test/resources/templates/both/entity.kt.btl @@ -0,0 +1,132 @@ +package ${package.Entity} + +<% for(pkg in table.importPackages){ %> +import ${pkg} +<% } %> +<% if(springdoc){ %> +import io.swagger.v3.oas.annotations.media.Schema; +<% }else if(swagger){ %> +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +<% } %> + +/** + *

+ * ${table.comment!} + *

+ * + * @author ${author} + * @since ${date} + */ +<% if(table.convert){ %> +@TableName("${schemaName}${table.name}") +<% } %> +<% if(springdoc){ %> +@Schema(name = "${entity}", description = "$!{table.comment}") +<% }else if(swagger){ %> +@ApiModel(value = "${entity}对象", description = "${table.comment!''}") +<% } %> +<% if(isNotEmpty(superEntityClass)){ %> +class ${entity} : ${superEntityClass}<% if(activeRecord){ %><${entity}><%}%>{ +<% }else if(activeRecord){ %> +class ${entity} : Model<${entity}> { +<% }else if(entitySerialVersionUID){ %> +class ${entity} : Serializable { +<% }else{ %> +class ${entity} { +<% } %> + +<% /** -----------BEGIN 字段循环遍历----------- **/ %> +<% for(field in table.fields){ %> + <% + if(field.keyFlag){ + var keyPropertyName = field.propertyName; + } + %> + <% if(isNotEmpty(field.comment)){ %> + <% if(springdoc){ %> + @Schema(description = "${field.comment}") + <% }else if(swagger){ %> + @ApiModelProperty(value = "${field.comment}") + <% }else{ %> + /** + * ${field.comment} + */ + <% } %> + <% } %> + <% if(field.keyFlag){ %> + <% + /*主键*/ + %> + <% if(field.keyIdentityFlag){ %> + @TableId(value = "${field.annotationColumnName}", type = IdType.AUTO) + <% }else if(isNotEmpty(idType)){ %> + @TableId(value = "${field.annotationColumnName}", type = IdType.${idType}) + <% }else if(field.convert){ %> + @TableId("${field.columnName}") + <% } %> + <% + /*普通字段*/ + %> + <% }else if(isNotEmpty(field.fill)){ %> + <% if(field.convert){ %> + @TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill}) + <% }else{ %> + @TableField(fill = FieldFill.${field.fill}) + <% } %> + <% }else if(field.convert){ %> + @TableField("${field.annotationColumnName}") + <% } %> + <% + /*乐观锁注解*/ + %> + <% if(field.versionField){ %> + @Version + <% } %> + <% + /*逻辑删除注解*/ + %> + <% if(field.logicDeleteField){ %> + @TableLogic + <% } %> + <% if(field.propertyType == 'Integer'){ %> + var ${field.propertyName}: Int ? = null + <% }else{ %> + var ${field.propertyName}: ${field.propertyType} ? = null + <% } %> + +<% } %> +<% /** -----------END 字段循环遍历----------- **/ %> +<% if(entityColumnConstant){ %> + companion object { + <% for(field in table.fields){ %> + const val ${strutil.toUpperCase(field.name)} : String = "${field.name}" + <% } %> + } +<% } %> +<% if(activeRecord){ %> + @Override + override fun pkVal(): Serializable? { + <% if(isNotEmpty(keyPropertyName)){ %> + return this.${keyPropertyName} + <% }else{ %> + return null; + <% } %> + } + +<% } %> +<% if(!entityLombokModel){ %> + @Override + override fun toString(): String { + return "${entity}{" + + <% for(field in table.fields){ %> + <% if(fieldLP.index==0){ %> + "${field.propertyName}=" + ${field.propertyName} + + <% }else{ %> + ", ${field.propertyName}=" + ${field.propertyName} + + <% } %> + <% } %> + "}" + } +<% } %> +} \ No newline at end of file diff --git a/src/test/resources/templates/both/mapper.java.btl b/src/test/resources/templates/both/mapper.java.btl new file mode 100644 index 0000000..e394944 --- /dev/null +++ b/src/test/resources/templates/both/mapper.java.btl @@ -0,0 +1,25 @@ +package ${package.Mapper}; + +import ${package.Entity}.${entity}; +import ${superMapperClassPackage}; +<% if(mapperAnnotationClass!=null){ %> +import ${mapperAnnotationClass.name}; +<% } %> + +/** + * ${table.comment!} Mapper 接口 + * + * @author ${author} + * + * @since ${date} + */ +<% if(mapperAnnotationClass!=null){ %> +@${mapperAnnotationClass.simpleName} +<% } %> +<% if(kotlin){ %> +interface ${table.mapperName} : ${superMapperClass}<${entity}> +<% }else{ %> +public interface ${table.mapperName} extends ${superMapperClass}<${entity}> { + +} +<% } %> \ No newline at end of file diff --git a/src/test/resources/templates/both/mapper.xml.btl b/src/test/resources/templates/both/mapper.xml.btl new file mode 100644 index 0000000..45e3621 --- /dev/null +++ b/src/test/resources/templates/both/mapper.xml.btl @@ -0,0 +1,39 @@ + + + + +<% if(enableCache){ %> + + +<% } %> +<% if(baseResultMap){ %> + + +<% for(field in table.fields){ %> + <% /** 生成主键排在第一位 **/ %> + <% if(field.keyFlag){ %> + + <% } %> +<% } %> +<% for(field in table.commonFields){ %> + <% /** 生成公共字段 **/ %> + +<% } %> +<% for(field in table.fields){ %> + <% /** 生成普通字段 **/ %> + <% if(!field.keyFlag){ %> + + <% } %> +<% } %> + +<% } %> +<% if(baseColumnList){ %> + + +<% for(field in table.commonFields){ %> + ${field.columnName}, +<% } %> + ${table.fieldNames} + +<% } %> + \ No newline at end of file diff --git a/src/test/resources/templates/both/service.java.btl b/src/test/resources/templates/both/service.java.btl new file mode 100644 index 0000000..0da9f35 --- /dev/null +++ b/src/test/resources/templates/both/service.java.btl @@ -0,0 +1,22 @@ +package ${package.Service}; + +import ${package.Entity}.${entity}; +import ${superServiceClassPackage}; +import org.nutz.spring.boot.service.interfaces.IdNameEntityService; + +/** + *

+ * ${table.comment!} 服务类 + *

+ * + * @author ${author} + * + * @since ${date} + */ +<% if(kotlin){ %> +interface ${table.serviceName} : ${superServiceClass}<${entity}> +<% }else{ %> +public interface ${table.serviceName} extends ${superServiceClass}<${entity}>, IdNameEntityService<${entity}> { + +} +<% } %> diff --git a/src/test/resources/templates/both/serviceImpl.java.btl b/src/test/resources/templates/both/serviceImpl.java.btl new file mode 100644 index 0000000..302b509 --- /dev/null +++ b/src/test/resources/templates/both/serviceImpl.java.btl @@ -0,0 +1,51 @@ +package ${package.ServiceImpl}; + +import ${package.Entity}.${entity}; +import ${package.Mapper}.${table.mapperName}; +import ${package.Service}.${table.serviceName}; +import ${superServiceImplClassPackage}; + +import lombok.RequiredArgsConstructor; + +import org.nutz.dao.Dao; +import org.springframework.stereotype.Service; + +/** + *

+ * ${table.comment!} 服务实现类 + *

+ * + * @author ${author} + * + * @since ${date} + */ +@Service +@RequiredArgsConstructor +<% if(kotlin){ %> +open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} { + +} +<% }else{ %> +public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} { + + private final Dao dao; + + /** + * @return + * @see org.nutz.spring.boot.service.ExtService#dao() + */ + @Override + public Dao dao() { + return dao; + } + + /** + * @return + * @see org.nutz.spring.boot.service.interfaces.EntityService#getEntityType() + */ + @Override + public Class<${entity}> getEntityType() { + return ${entity}.class; + } +} +<% } %> diff --git a/src/test/resources/templates/mybatis/controller.java.btl b/src/test/resources/templates/mybatis/controller.java.btl new file mode 100644 index 0000000..8f14623 --- /dev/null +++ b/src/test/resources/templates/mybatis/controller.java.btl @@ -0,0 +1,185 @@ +package ${package.Controller}; + +import org.nutz.lang.Lang; +import org.nutz.lang.Strings; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +<% if(restControllerStyle){ %> +import org.springframework.web.bind.annotation.RestController; +<% }else{ %> +import org.springframework.stereotype.Controller; +<% } %> +<% if(isNotEmpty(superControllerClassPackage)){ %> +import ${superControllerClassPackage}; +<% } %> +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import ${package.Entity}.${entity}; +import ${package.Service}.${table.serviceName}; + +<% if(swagger){ %> +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +<% } %> +/** + *

+ * ${table.comment!} 前端控制器 + *

+ * + * @author ${author} + * + * @since ${date} + */ +<% if(restControllerStyle){ %> +@RestController +<% }else{ %> +@Controller +<% } %> +<% if(kotlin){ %> +class ${table.controllerName}<% if(isNotEmpty(superControllerClass)){ %> : ${superControllerClass}()<% } %> +<% }else{ %> + <% if(isNotEmpty(superControllerClass)){ %> +public class ${table.controllerName} extends ${superControllerClass} { + <% }else{ %> + <% if(swagger){ %> +@Tag(name = "${entity}", description = "${table.comment!''}") + <% } %> +@RequiredArgsConstructor +public class ${table.controllerName} { + <% } %> + + <% + var entityNameFirst = strutil.subStringTo(entity,0,1); + var entityNameFirstLower = strutil.toLowerCase(entityNameFirst); + var entityName = strutil.replace(entity,entityNameFirst,entityNameFirstLower); + %> + private final ${table.serviceName} ${entityName}Service; + + /** + * 分页查询${table.comment!} + * + * @param page + * 页码 + * @param size + * 分页大小 + * @param key + * 关键词 + * @return ${table.comment!}分页数据 + */ + @GetMapping("${controllerMappingHyphen}s") + <% if(swagger){ %> + @Operation(summary = "分页查询${table.comment!''}") + public IPage<${entity}> ${entityName}s( + @Parameter(description = "页码") @RequestParam(value = "page", required = false, defaultValue = "1") long page, + @Parameter(description = "页面大小") @RequestParam(value = "size", required = false, defaultValue = "10") long size, + @Parameter(description = "搜索关键词") @RequestParam(name = "key", required = false, defaultValue = "") String key) { + <% }else{ %> + public IPage<${entity}> ${entityName}s(@RequestParam("page") long page, + @RequestParam("size") long size, + @RequestParam(name = "key", required = false, defaultValue = "") String key) { + <% } %> + boolean hasLike = Strings.isNotBlank(key); + key = String.format("%%%s%%", key); + /** + * TODO 处理搜索条件 + * + *
+                                              Wrappers.<${entity}> lambdaQuery()
+                                                         .like(hasLike, ${entity}::getName, key)
+                                                         .or()
+                                                         .like(hasLike, ${entity}::getMobile, key)
+         * 
+ */ + return ${entityName}Service.page(Page.<${entity}> of(page, size), + Wrappers.<${entity}> lambdaQuery() + .like(hasLike, ${entity}::getName, key)); + } + + /** + * ${table.comment!}详情 + * + * @param id + * ${table.comment!}id + * @return ${table.comment!} + */ + @GetMapping("${controllerMappingHyphen}/{id}") + <% if(swagger){ %> + @Operation(summary ="${table.comment!''}详情") + public ${entity} ${entityName}Detail(@Parameter(description = "${table.comment!''}id", required = true) @PathVariable("id") long id) { + <% }else{ %> + public ${entity} ${entityName}Detail(@PathVariable("id") long id) { + <% } %> + return ${entityName}Service.getById(id); + } + + /** + * 添加或者更新${table.comment!} + * + * @param ${entityName} + * ${table.comment!}数据 + * @return ${table.comment!} + */ + @PutMapping("${controllerMappingHyphen}") + <% if(swagger){ %> + @Operation(summary = "增加/编辑${table.comment!''}") + public ${entity} saveOrUpdate${entity}(@Validated @Parameter(description ="${table.comment!''}")@RequestBody ${entity} ${entityName}) { + <% }else{ %> + public ${entity} saveOrUpdate${entity}(@Validated @RequestBody ${entity} ${entityName}) { + <% } %> + if (${entityName}.getId() != null && ${entityName}.getId() > 0) { + /** + * XXX 根据情况处理是否需要根据指定条件更新指定字段
+ * + *
+             * ${entityName}Service.update(Wrappers.<${entity}> lambdaUpdate().set(${entity}::getName, ${entityName}.getName()).eq(${entity}::getId, ${entityName}.getId()));
+             * 
+ */ + if (${entityName}Service.update(${entityName}, Wrappers.<${entity}>lambdaUpdate().eq(${entity}::getId, ${entityName}.getId()))) { + return ${entityName}; + } else { + throw Lang.makeThrow("更新${table.comment!}失败!"); + } + } + if (${entityName}Service.save(${entityName})) { + return ${entityName}; + } else { + throw Lang.makeThrow("保存${table.comment!}失败!"); + } + } + + /** + * 删除${table.comment!} + * + * @param id + * ${table.comment!}id + * @return 是否删除成功 + */ + @DeleteMapping("${controllerMappingHyphen}/{id}") + <% if(swagger){ %> + @Operation(summary = "删除${table.comment!''}") + public void delete${entity}(@Parameter(description = "${table.comment!''}id", required = true)@PathVariable("id") long id) { + <% }else{ %> + public void delete${entity}(@PathVariable("id") long id) { + <% } %> + /** + * XXX 根据情况判断是否处理逻辑删除
+ * + *
+         * ${entityName}Service.update(Wrappers.<${entity}> lambdaUpdate().set(${entity}::getStatus, false).eq(${entity}::getId, id));
+         * 
+ */ + if(! ${entityName}Service.removeById(id)){ + throw Lang.makeThrow("删除${table.comment!}失败!"); + } + } + +} +<% } %> \ No newline at end of file diff --git a/src/test/resources/templates/mybatis/entity.java.btl b/src/test/resources/templates/mybatis/entity.java.btl new file mode 100644 index 0000000..170828a --- /dev/null +++ b/src/test/resources/templates/mybatis/entity.java.btl @@ -0,0 +1,180 @@ +package ${package.Entity}; + +<% for(pkg in table.importPackages){ %> +import ${pkg}; +<% } %> +<% if(springdoc){ %> +import io.swagger.v3.oas.annotations.media.Schema; +<% }else if(swagger){ %> +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +<% } %> +<% if(entityLombokModel){ %> +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import lombok.experimental.FieldNameConstants; +import lombok.experimental.SuperBuilder; +<% if(chainModel){ %> +import lombok.experimental.Accessors; +<% } %> +<% } %> + +/** + * ${table.comment!} + * + * @author ${author} + * + * @since ${date} + */ +<% if(entityLombokModel){ %> +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@FieldNameConstants +@EqualsAndHashCode(callSuper = true) + <% if(chainModel){ %> +@Accessors(chain = true) + <% } %> +<% } %> +<% if(table.convert){ %> +@TableName("${schemaName}${table.name}") +<% } %> +<% if(springdoc){ %> +@Schema(name = "${entity}", description = "${table.comment!''}") +<% }else if(swagger){ %> +@ApiModel(value = "${entity}对象", description = "${table.comment!''}") +<% } %> +<% if(isNotEmpty(superEntityClass)){ %> +public class ${entity} extends ${superEntityClass}<% if(activeRecord){ %><${entity}><%}%>{ +<% }else if(activeRecord){ %> +public class ${entity} extends Model<${entity}> { +<% }else if(entitySerialVersionUID){ %> +public class ${entity} implements Serializable { +<% }else{ %> +public class ${entity} { +<% } %> +<% if(entitySerialVersionUID){ %> + + private static final long serialVersionUID = 1L; +<% } %> +<% var keyPropertyName; %> +<% /** -----------BEGIN 字段循环遍历----------- **/ %> +<% for(field in table.fields){ %> + <% + if(field.keyFlag){ + keyPropertyName = field.propertyName; + } + %> + <% if(isNotEmpty(field.comment)){ %> + + <% if(springdoc){ %> + @Schema(description = "${field.comment}", required = ${!field.metaInfo.nullable}) + <% }else if(swagger){ %> + @ApiModelProperty(value = "${field.comment}") + <% }else{ %> + /** + * ${field.comment} + */ + <% } %> + <% } %> + <% if(field.keyFlag){ %> + <% + /*主键*/ + %> + <% if(field.keyIdentityFlag){ %> + @TableId(value = "${field.annotationColumnName}", type = IdType.AUTO) + <% }else if(isNotEmpty(idType)){ %> + @TableId(value = "${field.annotationColumnName}", type = IdType.${idType}) + <% }else if(field.convert){ %> + @TableId("${field.annotationColumnName}") + <% } %> + <% + /*普通字段*/ + %> + <% }else if(isNotEmpty(field.fill)){ %> + <% if(field.convert){ %> + @TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill}) + <% }else{ %> + @TableField(fill = FieldFill.${field.fill}) + <% } %> + <% }else if(field.convert){ %> + @TableField("${field.annotationColumnName}") + <% } %> + <% + /*乐观锁注解*/ + %> + <% if(field.versionField){ %> + @Version + <% } %> + <% + /*逻辑删除注解*/ + %> + <% if(field.logicDeleteField){ %> + @TableLogic + <% } %> + private ${field.propertyType} ${field.propertyName}; +<% } %> +<% /** -----------END 字段循环遍历----------- **/ %> +<% if(!entityLombokModel){ %> + <% for(field in table.fields){ %> + <% + var getprefix =''; + if(field.propertyType=='boolean'){ + getprefix='is'; + }else{ + getprefix='get'; + } + %> + + public ${field.propertyType} ${getprefix}${field.capitalName}() { + return ${field.propertyName}; + } + + <% if(chainModel){ %> + public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) { + <% }else{ %> + public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) { + <% } %> + this.${field.propertyName} = ${field.propertyName}; + <% if(chainModel){ %> + return this; + <% } %> + } + <% } %> +<% } %> +<% if(entityColumnConstant){ %> + <% for(field in table.fields){ %> + + public static final String ${strutil.toUpperCase(field.name)} = "${field.name}"; + <% } %> +<% } %> +<% if(activeRecord){ %> + + @Override + public Serializable pkVal() { + <% if(isNotEmpty(keyPropertyName)){ %> + return this.${keyPropertyName}; + <% }else{ %> + return null; + <% } %> + } +<% } %> +<% if(!entityLombokModel){ %> + + @Override + public String toString() { + return "${entity}{" + + <% for(field in table.fields){ %> + <% if(fieldLP.index==0){ %> + "${field.propertyName} = " + ${field.propertyName} + + <% }else{ %> + ", ${field.propertyName} = " + ${field.propertyName} + + <% } %> + <% } %> + "}"; + } +<% } %> +} \ No newline at end of file diff --git a/src/test/resources/templates/mybatis/entity.kt.btl b/src/test/resources/templates/mybatis/entity.kt.btl new file mode 100644 index 0000000..0a32b86 --- /dev/null +++ b/src/test/resources/templates/mybatis/entity.kt.btl @@ -0,0 +1,132 @@ +package ${package.Entity} + +<% for(pkg in table.importPackages){ %> +import ${pkg} +<% } %> +<% if(springdoc){ %> +import io.swagger.v3.oas.annotations.media.Schema; +<% }else if(swagger){ %> +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +<% } %> + +/** + *

+ * ${table.comment!} + *

+ * + * @author ${author} + * @since ${date} + */ +<% if(table.convert){ %> +@TableName("${schemaName}${table.name}") +<% } %> +<% if(springdoc){ %> +@Schema(name = "${entity}", description = "$!{table.comment}") +<% }else if(swagger){ %> +@ApiModel(value = "${entity}对象", description = "${table.comment!''}") +<% } %> +<% if(isNotEmpty(superEntityClass)){ %> +class ${entity} : ${superEntityClass}<% if(activeRecord){ %><${entity}><%}%>{ +<% }else if(activeRecord){ %> +class ${entity} : Model<${entity}> { +<% }else if(entitySerialVersionUID){ %> +class ${entity} : Serializable { +<% }else{ %> +class ${entity} { +<% } %> + +<% /** -----------BEGIN 字段循环遍历----------- **/ %> +<% for(field in table.fields){ %> + <% + if(field.keyFlag){ + var keyPropertyName = field.propertyName; + } + %> + <% if(isNotEmpty(field.comment)){ %> + <% if(springdoc){ %> + @Schema(description = "${field.comment}") + <% }else if(swagger){ %> + @ApiModelProperty(value = "${field.comment}") + <% }else{ %> + /** + * ${field.comment} + */ + <% } %> + <% } %> + <% if(field.keyFlag){ %> + <% + /*主键*/ + %> + <% if(field.keyIdentityFlag){ %> + @TableId(value = "${field.annotationColumnName}", type = IdType.AUTO) + <% }else if(isNotEmpty(idType)){ %> + @TableId(value = "${field.annotationColumnName}", type = IdType.${idType}) + <% }else if(field.convert){ %> + @TableId("${field.columnName}") + <% } %> + <% + /*普通字段*/ + %> + <% }else if(isNotEmpty(field.fill)){ %> + <% if(field.convert){ %> + @TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill}) + <% }else{ %> + @TableField(fill = FieldFill.${field.fill}) + <% } %> + <% }else if(field.convert){ %> + @TableField("${field.annotationColumnName}") + <% } %> + <% + /*乐观锁注解*/ + %> + <% if(field.versionField){ %> + @Version + <% } %> + <% + /*逻辑删除注解*/ + %> + <% if(field.logicDeleteField){ %> + @TableLogic + <% } %> + <% if(field.propertyType == 'Integer'){ %> + var ${field.propertyName}: Int ? = null + <% }else{ %> + var ${field.propertyName}: ${field.propertyType} ? = null + <% } %> + +<% } %> +<% /** -----------END 字段循环遍历----------- **/ %> +<% if(entityColumnConstant){ %> + companion object { + <% for(field in table.fields){ %> + const val ${strutil.toUpperCase(field.name)} : String = "${field.name}" + <% } %> + } +<% } %> +<% if(activeRecord){ %> + @Override + override fun pkVal(): Serializable? { + <% if(isNotEmpty(keyPropertyName)){ %> + return this.${keyPropertyName} + <% }else{ %> + return null; + <% } %> + } + +<% } %> +<% if(!entityLombokModel){ %> + @Override + override fun toString(): String { + return "${entity}{" + + <% for(field in table.fields){ %> + <% if(fieldLP.index==0){ %> + "${field.propertyName}=" + ${field.propertyName} + + <% }else{ %> + ", ${field.propertyName}=" + ${field.propertyName} + + <% } %> + <% } %> + "}" + } +<% } %> +} \ No newline at end of file diff --git a/src/test/resources/templates/mybatis/mapper.java.btl b/src/test/resources/templates/mybatis/mapper.java.btl new file mode 100644 index 0000000..e394944 --- /dev/null +++ b/src/test/resources/templates/mybatis/mapper.java.btl @@ -0,0 +1,25 @@ +package ${package.Mapper}; + +import ${package.Entity}.${entity}; +import ${superMapperClassPackage}; +<% if(mapperAnnotationClass!=null){ %> +import ${mapperAnnotationClass.name}; +<% } %> + +/** + * ${table.comment!} Mapper 接口 + * + * @author ${author} + * + * @since ${date} + */ +<% if(mapperAnnotationClass!=null){ %> +@${mapperAnnotationClass.simpleName} +<% } %> +<% if(kotlin){ %> +interface ${table.mapperName} : ${superMapperClass}<${entity}> +<% }else{ %> +public interface ${table.mapperName} extends ${superMapperClass}<${entity}> { + +} +<% } %> \ No newline at end of file diff --git a/src/test/resources/templates/mybatis/mapper.xml.btl b/src/test/resources/templates/mybatis/mapper.xml.btl new file mode 100644 index 0000000..45e3621 --- /dev/null +++ b/src/test/resources/templates/mybatis/mapper.xml.btl @@ -0,0 +1,39 @@ + + + + +<% if(enableCache){ %> + + +<% } %> +<% if(baseResultMap){ %> + + +<% for(field in table.fields){ %> + <% /** 生成主键排在第一位 **/ %> + <% if(field.keyFlag){ %> + + <% } %> +<% } %> +<% for(field in table.commonFields){ %> + <% /** 生成公共字段 **/ %> + +<% } %> +<% for(field in table.fields){ %> + <% /** 生成普通字段 **/ %> + <% if(!field.keyFlag){ %> + + <% } %> +<% } %> + +<% } %> +<% if(baseColumnList){ %> + + +<% for(field in table.commonFields){ %> + ${field.columnName}, +<% } %> + ${table.fieldNames} + +<% } %> + \ No newline at end of file diff --git a/src/test/resources/templates/mybatis/service.java.btl b/src/test/resources/templates/mybatis/service.java.btl new file mode 100644 index 0000000..2b48d45 --- /dev/null +++ b/src/test/resources/templates/mybatis/service.java.btl @@ -0,0 +1,19 @@ +package ${package.Service}; + +import ${package.Entity}.${entity}; +import ${superServiceClassPackage}; + +/** + * ${table.comment!} 服务类 + * + * @author ${author} + * + * @since ${date} + */ +<% if(kotlin){ %> +interface ${table.serviceName} : ${superServiceClass}<${entity}> +<% }else{ %> +public interface ${table.serviceName} extends ${superServiceClass}<${entity}> { + +} +<% } %> \ No newline at end of file diff --git a/src/test/resources/templates/mybatis/serviceImpl.java.btl b/src/test/resources/templates/mybatis/serviceImpl.java.btl new file mode 100644 index 0000000..93261bf --- /dev/null +++ b/src/test/resources/templates/mybatis/serviceImpl.java.btl @@ -0,0 +1,25 @@ +package ${package.ServiceImpl}; + +import ${package.Entity}.${entity}; +import ${package.Mapper}.${table.mapperName}; +import ${package.Service}.${table.serviceName}; +import ${superServiceImplClassPackage}; +import org.springframework.stereotype.Service; + +/** + * ${table.comment!} 服务实现类 + * + * @author ${author} + * + * @since ${date} + */ +@Service +<% if(kotlin){ %> +open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} { + +} +<% }else{ %> +public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} { + +} +<% } %> \ No newline at end of file diff --git a/src/test/resources/templates/nutz/controller.java.btl b/src/test/resources/templates/nutz/controller.java.btl new file mode 100644 index 0000000..4b5473c --- /dev/null +++ b/src/test/resources/templates/nutz/controller.java.btl @@ -0,0 +1,159 @@ +package ${package.Controller}; + +import static org.nutz.spring.boot.service.interfaces.EntityService.*; + +import org.springframework.http.HttpStatus; +import org.nutz.lang.Lang; +import org.nutz.lang.Strings; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +<% if(restControllerStyle){ %> +import org.springframework.web.bind.annotation.RestController; +<% }else{ %> +import org.springframework.stereotype.Controller; +<% } %> +<% if(isNotEmpty(superControllerClassPackage)){ %> +import ${superControllerClassPackage}; +<% } %> + +import org.nutz.spring.boot.service.entity.Pagination; +import ${package.Entity}.${entity}; +import ${package.Service}.${entity}Service; + +<% if(springdoc){ %> +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +<% } %> +/** + * ${table.comment!} 前端控制器 + * + * @author ${author} + * + * @since ${date} + */ +<% if(restControllerStyle){ %> +@RestController +@RequiredArgsConstructor +<% }else{ %> +@Controller +@RequiredArgsConstructor +<% } %> +<% if(kotlin){ %> +class ${table.controllerName}<% if(isNotEmpty(superControllerClass)){ %> : ${superControllerClass}()<% } %> +<% }else{ %> + <% if(isNotEmpty(superControllerClass)){ %> +public class ${table.controllerName} extends ${superControllerClass} { + <% }else{ %> + <% if(springdoc){ %> +@Tag(name = "${entity}", description = "${table.comment!''}") + <% } %> +public class ${table.controllerName} { + <% } %> + + <% + var entityNameFirst = strutil.subStringTo(entity,0,1); + var entityNameFirstLower = strutil.toLowerCase(entityNameFirst); + var entityName = strutil.replace(entity,entityNameFirst,entityNameFirstLower); + %> + private final ${entity}Service ${entityName}Service; + + /** + * 分页查询${table.comment!} + * + * @param page + * 页码 + * @param size + * 分页大小 + * @param key + * 关键词 + * @return ${table.comment!}分页数据 + */ + @GetMapping("${controllerMappingHyphen}s") + <% if(springdoc){ %> + @Operation(summary = "分页查询${table.comment!''}") + public Pagination<${entity}> ${entityName}s( + @Parameter(description = "页码") @RequestParam(value = "page", required = false, defaultValue = "1") int page, + @Parameter(description = "页面大小") @RequestParam(value = "size", required = false, defaultValue = "10") int size, + @Parameter(description = "搜索关键词") @RequestParam(name = "key", required = false, defaultValue = "") String key) { + <% }else{ %> + public Pagination<${entity}> ${entityName}s(@RequestParam("page") int page, + @RequestParam("size") int size, + @RequestParam(name = "key", required = false, defaultValue = "") String key) { + <% } %> + return ${entityName}Service.searchByKeyAndPage(key, + page, + size, + ${entity}.Fields.name); + } + + /** + * ${table.comment!}详情 + * + * @param id + * ${table.comment!}id + * @return ${table.comment!} + */ + @GetMapping("${controllerMappingHyphen}/{id}") + <% if(springdoc){ %> + @Operation(summary ="${table.comment!''}详情") + public ${entity} ${entityName}Detail(@Parameter(description = "${table.comment!''}id", required = true) @PathVariable("id") long id) { + <% }else{ %> + public ${entity} ${entityName}Detail(@PathVariable("id") long id) { + <% } %> + return ${entityName}Service.fetch(id); + } + + /** + * 添加或者更新${table.comment!} + * + * @param ${entityName} + * ${table.comment!}数据 + * @return ${table.comment!} + */ + @PutMapping("${controllerMappingHyphen}") + <% if(springdoc){ %> + @Operation(summary = "增加/编辑${table.comment!''}") + public ${entity} saveOrUpdate${entity}(@Validated @Parameter(description ="${table.comment!''}")@RequestBody ${entity} ${entityName}) { + <% }else{ %> + public ${entity} saveOrUpdate${entity}(@Validated @RequestBody ${entity} ${entityName}) { + <% } %> + if (${entityName}.getId() != null && ${entityName}.getId() > 0) { + if (${entityName}Service.update(${entityName}) == 1) { + return ${entityName}; + } else { + throw Lang.makeThrow("更新${table.comment!}失败!"); + } + } + return ${entityName}Service.insert(${entityName}); + } + + /** + * 删除${table.comment!} + * + * @param id + * ${table.comment!}id + * @return 是否删除成功 + */ + @DeleteMapping("${controllerMappingHyphen}/{id}") + <% if(springdoc){ %> + @Operation(summary = "删除${table.comment!''}") + @ResponseStatus(HttpStatus.OK) + public void delete${entity}(@Parameter(description = "${table.comment!''}id", required = true)@PathVariable("id") long id) { + <% }else{ %> + public void delete${entity}(@PathVariable("id") long id) { + <% } %> + if(${entityName}Service.delete(id) != 1){ + throw Lang.makeThrow("删除${table.comment!}失败!"); + } + } + +} +<% } %> \ No newline at end of file diff --git a/src/test/resources/templates/nutz/entity.java.btl b/src/test/resources/templates/nutz/entity.java.btl new file mode 100644 index 0000000..4451e61 --- /dev/null +++ b/src/test/resources/templates/nutz/entity.java.btl @@ -0,0 +1,187 @@ +package ${package.Entity}; + +<% for(pkg in table.importPackages){ %> +import ${pkg}; +<% } %> +import org.nutz.dao.entity.annotation.Column; +import org.nutz.dao.entity.annotation.Comment; +import org.nutz.dao.entity.annotation.EL; +import org.nutz.dao.entity.annotation.Name; +import org.nutz.dao.entity.annotation.Prev; +import org.nutz.dao.entity.annotation.Table; +<% if(springdoc){ %> +import io.swagger.v3.oas.annotations.media.Schema; +<% }else if(swagger){ %> +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +<% } %> +<% if(entityLombokModel){ %> +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import lombok.experimental.FieldNameConstants; +import lombok.experimental.SuperBuilder; +<% if(chainModel){ %> +import lombok.experimental.Accessors; +<% } %> +<% } %> + +/** + * ${table.comment!} + * + * @author ${author} + * + * @since ${date} + */ +<% if(entityLombokModel){ %> +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@FieldNameConstants +@EqualsAndHashCode(callSuper = true) + <% if(chainModel){ %> +@Accessors(chain = true) + <% } %> +<% } %> +<% if(table.convert){ %> +@Table("${schemaName}${table.name}") +@Comment("${table.comment!''}") +<% } %> +<% if(springdoc){ %> +@Schema(name = "${entity}", description = "${table.comment!''}") +<% }else if(swagger){ %> +@ApiModel(value = "${entity}对象", description = "${table.comment!''}") +<% } %> +<% if(isNotEmpty(superEntityClass)){ %> +public class ${entity} extends ${superEntityClass}<% if(activeRecord){ %><${entity}><%}%>{ +<% }else if(activeRecord){ %> +public class ${entity} extends Model<${entity}> { +<% }else if(entitySerialVersionUID){ %> +public class ${entity} implements Serializable { +<% }else{ %> +public class ${entity} { +<% } %> +<% if(entitySerialVersionUID){ %> + + private static final long serialVersionUID = 1L; +<% } %> +<% var keyPropertyName; %> +<% /** -----------BEGIN 字段循环遍历----------- **/ %> +<% for(field in table.fields){ %> + <% + if(field.keyFlag){ + keyPropertyName = field.propertyName; + } + %> + <% if(isNotEmpty(field.comment)){ %> + + <% if(springdoc){ %> + @Schema(description = "${field.comment}", required = ${!field.metaInfo.nullable}) + <% }else if(swagger){ %> + @ApiModelProperty(value = "${field.comment}") + <% }else{ %> + /** + * ${field.comment} + */ + <% } %> + <% } %> + <% if(field.keyFlag){ %> + <% + /*主键*/ + %> + @Name + //@Prev(els=@EL("uuid(32)")) 这样就可以生成主键 + @Column("${field.annotationColumnName}") + @Comment("${field.comment!''}") + <% + /*普通字段*/ + %> + <% }else if(isNotEmpty(field.fill)){ %> + <% if(field.convert){ %> + @Column("${field.annotationColumnName}") + @Comment("${field.comment!''}") + <% }else{ %> + @Column("${field.annotationColumnName}") + @Comment("${field.comment!''}") + <% } %> + <% }else if(field.convert){ %> + @Column("${field.annotationColumnName}") + @Comment("${field.comment!''}") + <% } %> + <% + /*乐观锁注解*/ + %> + <% if(field.versionField){ %> + @Version + <% } %> + <% + /*逻辑删除注解*/ + %> + <% if(field.logicDeleteField){ %> + @TableLogic + <% } %> + private ${field.propertyType} ${field.propertyName}; +<% } %> +<% /** -----------END 字段循环遍历----------- **/ %> +<% if(!entityLombokModel){ %> + <% for(field in table.fields){ %> + <% + var getprefix =''; + if(field.propertyType=='boolean'){ + getprefix='is'; + }else{ + getprefix='get'; + } + %> + + public ${field.propertyType} ${getprefix}${field.capitalName}() { + return ${field.propertyName}; + } + + <% if(chainModel){ %> + public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) { + <% }else{ %> + public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) { + <% } %> + this.${field.propertyName} = ${field.propertyName}; + <% if(chainModel){ %> + return this; + <% } %> + } + <% } %> +<% } %> +<% if(entityColumnConstant){ %> + <% for(field in table.fields){ %> + + public static final String ${strutil.toUpperCase(field.name)} = "${field.name}"; + <% } %> +<% } %> +<% if(activeRecord){ %> + + @Override + public Serializable pkVal() { + <% if(isNotEmpty(keyPropertyName)){ %> + return this.${keyPropertyName}; + <% }else{ %> + return null; + <% } %> + } +<% } %> +<% if(!entityLombokModel){ %> + + @Override + public String toString() { + return "${entity}{" + + <% for(field in table.fields){ %> + <% if(fieldLP.index==0){ %> + "${field.propertyName} = " + ${field.propertyName} + + <% }else{ %> + ", ${field.propertyName} = " + ${field.propertyName} + + <% } %> + <% } %> + "}"; + } +<% } %> +} \ No newline at end of file diff --git a/src/test/resources/templates/nutz/entity.kt.btl b/src/test/resources/templates/nutz/entity.kt.btl new file mode 100644 index 0000000..0a32b86 --- /dev/null +++ b/src/test/resources/templates/nutz/entity.kt.btl @@ -0,0 +1,132 @@ +package ${package.Entity} + +<% for(pkg in table.importPackages){ %> +import ${pkg} +<% } %> +<% if(springdoc){ %> +import io.swagger.v3.oas.annotations.media.Schema; +<% }else if(swagger){ %> +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +<% } %> + +/** + *

+ * ${table.comment!} + *

+ * + * @author ${author} + * @since ${date} + */ +<% if(table.convert){ %> +@TableName("${schemaName}${table.name}") +<% } %> +<% if(springdoc){ %> +@Schema(name = "${entity}", description = "$!{table.comment}") +<% }else if(swagger){ %> +@ApiModel(value = "${entity}对象", description = "${table.comment!''}") +<% } %> +<% if(isNotEmpty(superEntityClass)){ %> +class ${entity} : ${superEntityClass}<% if(activeRecord){ %><${entity}><%}%>{ +<% }else if(activeRecord){ %> +class ${entity} : Model<${entity}> { +<% }else if(entitySerialVersionUID){ %> +class ${entity} : Serializable { +<% }else{ %> +class ${entity} { +<% } %> + +<% /** -----------BEGIN 字段循环遍历----------- **/ %> +<% for(field in table.fields){ %> + <% + if(field.keyFlag){ + var keyPropertyName = field.propertyName; + } + %> + <% if(isNotEmpty(field.comment)){ %> + <% if(springdoc){ %> + @Schema(description = "${field.comment}") + <% }else if(swagger){ %> + @ApiModelProperty(value = "${field.comment}") + <% }else{ %> + /** + * ${field.comment} + */ + <% } %> + <% } %> + <% if(field.keyFlag){ %> + <% + /*主键*/ + %> + <% if(field.keyIdentityFlag){ %> + @TableId(value = "${field.annotationColumnName}", type = IdType.AUTO) + <% }else if(isNotEmpty(idType)){ %> + @TableId(value = "${field.annotationColumnName}", type = IdType.${idType}) + <% }else if(field.convert){ %> + @TableId("${field.columnName}") + <% } %> + <% + /*普通字段*/ + %> + <% }else if(isNotEmpty(field.fill)){ %> + <% if(field.convert){ %> + @TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill}) + <% }else{ %> + @TableField(fill = FieldFill.${field.fill}) + <% } %> + <% }else if(field.convert){ %> + @TableField("${field.annotationColumnName}") + <% } %> + <% + /*乐观锁注解*/ + %> + <% if(field.versionField){ %> + @Version + <% } %> + <% + /*逻辑删除注解*/ + %> + <% if(field.logicDeleteField){ %> + @TableLogic + <% } %> + <% if(field.propertyType == 'Integer'){ %> + var ${field.propertyName}: Int ? = null + <% }else{ %> + var ${field.propertyName}: ${field.propertyType} ? = null + <% } %> + +<% } %> +<% /** -----------END 字段循环遍历----------- **/ %> +<% if(entityColumnConstant){ %> + companion object { + <% for(field in table.fields){ %> + const val ${strutil.toUpperCase(field.name)} : String = "${field.name}" + <% } %> + } +<% } %> +<% if(activeRecord){ %> + @Override + override fun pkVal(): Serializable? { + <% if(isNotEmpty(keyPropertyName)){ %> + return this.${keyPropertyName} + <% }else{ %> + return null; + <% } %> + } + +<% } %> +<% if(!entityLombokModel){ %> + @Override + override fun toString(): String { + return "${entity}{" + + <% for(field in table.fields){ %> + <% if(fieldLP.index==0){ %> + "${field.propertyName}=" + ${field.propertyName} + + <% }else{ %> + ", ${field.propertyName}=" + ${field.propertyName} + + <% } %> + <% } %> + "}" + } +<% } %> +} \ No newline at end of file diff --git a/src/test/resources/templates/nutz/mapper.java.btl b/src/test/resources/templates/nutz/mapper.java.btl new file mode 100644 index 0000000..e394944 --- /dev/null +++ b/src/test/resources/templates/nutz/mapper.java.btl @@ -0,0 +1,25 @@ +package ${package.Mapper}; + +import ${package.Entity}.${entity}; +import ${superMapperClassPackage}; +<% if(mapperAnnotationClass!=null){ %> +import ${mapperAnnotationClass.name}; +<% } %> + +/** + * ${table.comment!} Mapper 接口 + * + * @author ${author} + * + * @since ${date} + */ +<% if(mapperAnnotationClass!=null){ %> +@${mapperAnnotationClass.simpleName} +<% } %> +<% if(kotlin){ %> +interface ${table.mapperName} : ${superMapperClass}<${entity}> +<% }else{ %> +public interface ${table.mapperName} extends ${superMapperClass}<${entity}> { + +} +<% } %> \ No newline at end of file diff --git a/src/test/resources/templates/nutz/mapper.xml.btl b/src/test/resources/templates/nutz/mapper.xml.btl new file mode 100644 index 0000000..45e3621 --- /dev/null +++ b/src/test/resources/templates/nutz/mapper.xml.btl @@ -0,0 +1,39 @@ + + + + +<% if(enableCache){ %> + + +<% } %> +<% if(baseResultMap){ %> + + +<% for(field in table.fields){ %> + <% /** 生成主键排在第一位 **/ %> + <% if(field.keyFlag){ %> + + <% } %> +<% } %> +<% for(field in table.commonFields){ %> + <% /** 生成公共字段 **/ %> + +<% } %> +<% for(field in table.fields){ %> + <% /** 生成普通字段 **/ %> + <% if(!field.keyFlag){ %> + + <% } %> +<% } %> + +<% } %> +<% if(baseColumnList){ %> + + +<% for(field in table.commonFields){ %> + ${field.columnName}, +<% } %> + ${table.fieldNames} + +<% } %> + \ No newline at end of file diff --git a/src/test/resources/templates/nutz/service.java.btl b/src/test/resources/templates/nutz/service.java.btl new file mode 100644 index 0000000..ad8542a --- /dev/null +++ b/src/test/resources/templates/nutz/service.java.btl @@ -0,0 +1,45 @@ +<% var hasKey = false; +%> +<% for(field in table.fields){ %> + <% + if(field.keyFlag && field.propertyType == 'String'){ + hasKey = true; + } + %> +<% } %> +package ${package.Service}; + +import ${package.Entity}.${entity}; +import ${superServiceClassPackage}; +import org.nutz.spring.boot.service.interfaces.IdNameEntityService; +import org.nutz.spring.boot.service.interfaces.IdEntityService; +import lombok.RequiredArgsConstructor; + +import org.nutz.dao.Dao; +import org.springframework.stereotype.Service; +/** + * ${table.comment!} 服务类 + * + * @author ${author} + * + * @since ${date} + */ +<% if(kotlin){ %> +class ${table.serviceName} : ${superServiceClass}<${entity}> +<% }else{ %> +@Service +@RequiredArgsConstructor +public class ${table.serviceName} implements ${hasKey?'IdName':'Id'}EntityService<${entity}> { + + private final Dao dao; + + /** + * @return + * @see org.nutz.spring.boot.service.ExtService#dao() + */ + @Override + public Dao dao() { + return dao; + } +} +<% } %> diff --git a/src/test/resources/templates/nutz/serviceImpl.java.btl b/src/test/resources/templates/nutz/serviceImpl.java.btl new file mode 100644 index 0000000..93261bf --- /dev/null +++ b/src/test/resources/templates/nutz/serviceImpl.java.btl @@ -0,0 +1,25 @@ +package ${package.ServiceImpl}; + +import ${package.Entity}.${entity}; +import ${package.Mapper}.${table.mapperName}; +import ${package.Service}.${table.serviceName}; +import ${superServiceImplClassPackage}; +import org.springframework.stereotype.Service; + +/** + * ${table.comment!} 服务实现类 + * + * @author ${author} + * + * @since ${date} + */ +@Service +<% if(kotlin){ %> +open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} { + +} +<% }else{ %> +public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} { + +} +<% } %> \ No newline at end of file