🆕 项目初始化,大概实现数据表的定义

This commit is contained in:
my_ong 2024-12-01 18:49:36 +08:00
commit 722abb3abf
109 changed files with 7175 additions and 0 deletions

View File

@ -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

33
.gitignore vendored Normal file
View File

@ -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/

19
.mvn/wrapper/maven-wrapper.properties vendored Normal file
View File

@ -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

259
mvnw vendored Normal file
View File

@ -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-<version>,maven-mvnd-<version>-<platform>}/<hash>
[ -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 "$@"

149
mvnw.cmd vendored Normal file
View File

@ -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-<version>,maven-mvnd-<version>-<platform>}/<hash>
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"

149
pom.xml Normal file
View File

@ -0,0 +1,149 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<project xmlns="https://maven.apache.org/POM/4.0.0"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>tech.riemann</groupId>
<artifactId>ims</artifactId>
<version>1.0.0</version>
<name>库管系统</name>
<description>Inventory Management System</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>1.2.23</version>
</dependency>
<dependency>
<groupId>com.ibeetl</groupId>
<artifactId>beetl</artifactId>
<version>3.17.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutz-spring-boot-starter</artifactId>
<version>3.3.5</version>
</dependency>
<dependency>
<groupId>club.zhcs</groupId>
<artifactId>open-api-spring-boot-starter</artifactId>
<version>3.3.5</version>
</dependency>
<dependency>
<groupId>club.zhcs</groupId>
<artifactId>lina-spring-boot-starter</artifactId>
<version>3.3.5</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.9</version>
</dependency>
<!-- 代码生成-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.9</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>4.0.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -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());
}
});
}
}

View File

@ -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 = "超级管理员,创世角色,一切均在掌控之中";
}
}

View File

@ -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());
}
}
}

View File

@ -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<String, AuthUser> 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;
}
}

View File

@ -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;
/**
* <p>
* 权限 前端控制器
* </p>
*
* @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<Codebook> types() {
return Arrays.stream(Permission.Type.values())
.map(ICodeBook::build)
.toList();
}
@GetMapping("permissions/tree")
@Operation(summary = "权限树")
public List<Tree<String>> permissionTree(
@Parameter(description = "强制拉取") @RequestParam(required = false) Boolean force) {
return permissionService.permissionTree(force);
}
@GetMapping("permissions")
@Operation(summary = "权限列表")
public List<Permission> 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.<Permission> 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.<Permission> lambdaQuery().eq(Permission::getKey, key))) {
throw BizException.create("删除权限失败!");
}
}
@PostMapping("batch-init-permissions")
@Operation(summary = "批量新增权限")
@ResponseStatus(value = HttpStatus.OK)
public void batchInitPermissions(
@RequestBody List<Permission> permissions) {
permissionService.batchAddPermissions(permissions);
}
@PatchMapping("batch-sync-permissions")
@Operation(summary = "增量新增权限")
@ResponseStatus(value = HttpStatus.OK)
public void batchSyncPermissions(@RequestBody List<Permission> permissions) {
permissionService.updatePermissions(permissions);
}
}

View File

@ -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;
/**
* <p>
* 角色 前端控制器
* </p>
*
* @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<Role> 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.<Role> of(page, size),
Wrappers.<Role> lambdaQuery()
.like(hasLike, Role::getName, key)
.or()
.like(Role::getKey, key)
.or()
.like(Role::getDescription, key));
}
return roleService.page(Page.<Role> of(page, size), Wrappers.<Role> 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.<Role> 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.<Role> lambdaQuery().eq(Role::getKey, key))) {
throw BizException.create("删除角色失败!");
}
}
@GetMapping("role/{key}/permissions")
@Operation(summary = "查询角色权限")
public List<Permission> permissions(
@Parameter(description = "角色key") @PathVariable String key) {
return roleService.permissionsByRoleKey(key);
}
@GetMapping("role/{key}/permission-infos")
@Operation(summary = "查询用于授权的权限信息")
public List<PermissionInfo> 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<String> permissions) {
if (!roleService.grant(key, permissions)) {
throw BizException.create("授权失败");
}
}
}

View File

@ -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;
/**
* <p>
* 用户 前端控制器
* </p>
*
* @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<User> 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.<User> of(page, size),
Wrappers.<User> lambdaQuery()
.like(hasLike, User::getName, key)
.eq(sex != null, User::getSex, sex)
.orderByDesc(User::getId));
}
@GetMapping("user/sexes")
@Operation(summary = "用户性别")
public List<Codebook> 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.<User> 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<Permission> permissions(
@Parameter(description = "用户名") @PathVariable String name) {
return userService.permissionsByUserName(name);
}
@GetMapping("user/{name}/permission-infos")
@Operation(summary = "查询用于授权的权限信息")
public List<PermissionInfo> 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<String> permissions) {
if (!userService.grant(name, permissions)) {
throw BizException.create("授权失败");
}
}
@GetMapping("user/{name}/role-infos")
@Operation(summary = "查询用户权限")
public List<RoleInfo> 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<String> roles) {
if (!userService.grantRole(name, roles)) {
throw BizException.create("授权角色失败");
}
}
}

View File

@ -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
}
}
}

View File

@ -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;
/**
* <p>
* 码本数据 前端控制器
* </p>
*
* @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<Group> 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.<Group> of(page, size),
Wrappers.<Group> 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.<Group> 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.<Group> lambdaQuery().eq(Group::getKey, key))) {
throw Lang.makeThrow(BizException.class, "删除码本分组失败!");
}
}
@GetMapping("group/{group}/dictionaries")
@Operation(summary = "分组下的数据字典列表")
public List<Dictionary> dictionaries(@Parameter(description = "码本分组key", required = true) @PathVariable String group) {
return dictionaryService.list(Wrappers.<Dictionary> 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.<Dictionary> 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.<Dictionary> lambdaQuery().eq(Dictionary::getGroupKey, group).eq(Dictionary::getKey, key))) {
throw Lang.makeThrow("删除码本数据失败!");
}
}
}

View File

@ -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<ApplyForm> 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.<ApplyForm>lambdaQuery()
.eq(ApplyForm::getType, type)
.orderByDesc(ApplyForm::getUpdatedTime));
}
@GetMapping("apply/{applyId}")
@Operation(summary = "查询申请单详情")
public ApplyInfo detail(@Parameter(description = "类型") @PathVariable(name = "applyId") Integer applyId) {
List<ApplyDetail> list = applyDetailService.list(Wrappers.<ApplyDetail>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 更新申请单
}
}
}

View File

@ -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<Material> 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.<Material>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<Material> 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.<Material> 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("删除物料失败!");
}
}
}

View File

@ -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<ApplyDetail> applyDetails;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<String> {
private static final long serialVersionUID = 1L;
public static PermissionTree build(Permission permission) {
return Json.fromJson(PermissionTree.class, Json.toJson(permission));
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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; // 异常说明
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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-报废
}

View File

@ -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-其他
}

View File

@ -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()));
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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()));
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<Permission> {
}

View File

@ -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<Role> {
/**
* @param key
* @return
*/
List<PermissionInfo> permissionInfosByKey(String key);
}

View File

@ -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<RolePermission> {
}

View File

@ -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<UserBind> {
}

View File

@ -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<User> {
/**
* @param name
* @return
*/
List<PermissionInfo> indirectPermissionInfosByUserName(String name);
/**
* @param name
* @return
*/
List<PermissionInfo> directPermissionInfosByUserName(String name);
/**
* @param name
* @return
*/
List<RoleInfo> roleInfosByUserName(String name);
}

View File

@ -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<UserPermission> {
}

View File

@ -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<UserRole> {
}

View File

@ -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<Dictionary> {
}

View File

@ -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<Group> {
}

View File

@ -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<ApplyDetail> {
}

View File

@ -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<ApplyForm> {
}

View File

@ -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<Material> {
}

View File

@ -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;
/**
* <p>
* 权限 服务类
* </p>
*
* @author Kerbores(kerbores@gmail.com)
*
* @since 2024-09-10 18:07:15
*/
public interface IPermissionService extends IService<Permission>, IdNameEntityService<Permission> {
/**
* @param force
* @return
*/
List<Tree<String>> permissionTree(Boolean force);
/**
* @param force
* @return
*/
List<Permission> permissions(Boolean force);
/**
* @param permissions
*/
void batchAddPermissions(List<Permission> permissions);
/**
* @param permissions
*/
void updatePermissions(List<Permission> permissions);
}

View File

@ -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;
/**
* <p>
* 角色权限 服务类
* </p>
*
* @author Kerbores(kerbores@gmail.com)
*
* @since 2024-09-10 18:07:15
*/
public interface IRolePermissionService extends IService<RolePermission>, IdNameEntityService<RolePermission> {
}

View File

@ -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;
/**
* <p>
* 角色 服务类
* </p>
*
* @author Kerbores(kerbores@gmail.com)
*
* @since 2024-09-10 18:07:15
*/
public interface IRoleService extends IService<Role>, IdNameEntityService<Role> {
/**
* @param key
* @return
*/
List<Permission> permissionsByRoleKey(String key);
/**
* @param key
* @return
*/
List<PermissionInfo> permissionInfosByKey(String key);
/**
* @param key
* @param permissions
* @return
*/
boolean grant(String key, List<String> permissions);
}

View File

@ -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;
/**
* <p>
* 用户三方账号绑定 服务类
* </p>
*
* @author Kerbores(kerbores@gmail.com)
*
* @since 2024-09-10 18:07:15
*/
public interface IUserBindService extends IService<UserBind>, IdNameEntityService<UserBind> {
}

View File

@ -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;
/**
* <p>
* 用户权限 服务类
* </p>
*
* @author Kerbores(kerbores@gmail.com)
*
* @since 2024-09-10 18:07:15
*/
public interface IUserPermissionService extends IService<UserPermission>, IdNameEntityService<UserPermission> {
}

View File

@ -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;
/**
* <p>
* 用户角色 服务类
* </p>
*
* @author Kerbores(kerbores@gmail.com)
*
* @since 2024-09-10 18:07:15
*/
public interface IUserRoleService extends IService<UserRole>, IdNameEntityService<UserRole> {
}

View File

@ -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;
/**
* <p>
* 用户 服务类
* </p>
*
* @author Kerbores(kerbores@gmail.com)
*
* @since 2024-09-10 18:07:15
*/
public interface IUserService extends IService<User>, IdNameEntityService<User> {
/**
* 重置密码
*
* @param name
* 用户名
* @return 新密码
*/
String resetPassword(String name);
/**
* @param name
* @return
*/
List<Permission> permissionsByUserName(String name);
/**
* @param name
* @return
*/
List<PermissionInfo> permissionInfosByUserName(String name);
/**
* @param name
* @param permissions
* @return
*/
boolean grant(String name, List<String> permissions);
/**
* @param name
* @return
*/
List<RoleInfo> roleInfosByUserName(String name);
/**
* @param name
* @param roles
* @return
*/
boolean grantRole(String name, List<String> roles);
/**
* @param login
* @return
*/
AuthUser login(LoginDTO login);
/**
* @param key
* @return
*/
AuthUser authUser(String name);
}

View File

@ -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;
/**
* <p>
* 权限 服务实现类
* </p>
*
* @author Kerbores(kerbores@gmail.com)
*
* @since 2024-09-10 18:07:15
*/
@Service
@RequiredArgsConstructor
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements IPermissionService {
private final Dao dao;
LoadingCache<String, List<Permission>> cache = CacheBuilder.newBuilder()
.concurrencyLevel(8)
.expireAfterAccess(10, TimeUnit.MINUTES)
.initialCapacity(10)
.maximumSize(300)
.recordStats()
.build(new CacheLoader<String, List<Permission>>() {
@Override
public List<Permission> 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<Permission> getEntityType() {
return Permission.class;
}
/**
* @param force
* @return
* @see tech.riemann.laacam.service.acl.IPermissionService#permissionTree(java.lang.Boolean)
*/
@Override
public List<Tree<String>> permissionTree(Boolean force) {
List<Permission> permissions = permissions(force);
List<Treeable<String>> 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<Permission> 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<Permission> permissions) {
clear();
insert(permissions);
}
/**
* @param permissions
* @see tech.riemann.laacam.service.acl.IPermissionService#updatePermissions(java.util.List)
*/
@Override
public void updatePermissions(List<Permission> permissions) {
permissions.stream().forEach(permission -> {
if (exists(Wrappers.<Permission> lambdaQuery().eq(Permission::getKeyPath, permission.getKeyPath()))) {
update(
Wrappers.<Permission> lambdaUpdate()
.eq(Permission::getKeyPath, permission.getKeyPath())
.set(Permission::getName, permission.getName())
.set(Permission::getDescription, permission.getDescription())
.set(Permission::getType, permission.getType()));
} else {
save(permission);
}
});
}
}

View File

@ -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;
/**
* <p>
* 角色权限 服务实现类
* </p>
*
* @author Kerbores(kerbores@gmail.com)
*
* @since 2024-09-10 18:07:15
*/
@Service
@RequiredArgsConstructor
public class RolePermissionServiceImpl extends ServiceImpl<RolePermissionMapper, RolePermission> 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<RolePermission> getEntityType() {
return RolePermission.class;
}
}

View File

@ -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;
/**
* <p>
* 角色 服务实现类
* </p>
*
* @author Kerbores(kerbores@gmail.com)
*
* @since 2024-09-10 18:07:15
*/
@Service
@RequiredArgsConstructor
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> 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<Role> getEntityType() {
return Role.class;
}
/**
* @param key
* @return
* @see tech.riemann.laacam.service.acl.IRoleService#permissionsByRoleKey(java.lang.String)
*/
@Override
public List<Permission> 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<PermissionInfo> 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<String> permissions) {
rolePermissionMapper.delete(Wrappers.<RolePermission> lambdaQuery().eq(RolePermission::getRoleKey, key));
rolePermissionMapper.insert(permissions.stream()
.map(p -> RolePermission.builder().roleKey(key).permissionKeyPath(p).build())
.collect(Collectors.toList()));
return true;
}
}

View File

@ -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;
/**
* <p>
* 用户三方账号绑定 服务实现类
* </p>
*
* @author Kerbores(kerbores@gmail.com)
*
* @since 2024-09-10 18:07:15
*/
@Service
@RequiredArgsConstructor
public class UserBindServiceImpl extends ServiceImpl<UserBindMapper, UserBind> 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<UserBind> getEntityType() {
return UserBind.class;
}
}

View File

@ -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;
/**
* <p>
* 用户权限 服务实现类
* </p>
*
* @author Kerbores(kerbores@gmail.com)
*
* @since 2024-09-10 18:07:15
*/
@Service
@RequiredArgsConstructor
public class UserPermissionServiceImpl extends ServiceImpl<UserPermissionMapper, UserPermission> 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<UserPermission> getEntityType() {
return UserPermission.class;
}
}

View File

@ -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;
/**
* <p>
* 用户角色 服务实现类
* </p>
*
* @author Kerbores(kerbores@gmail.com)
*
* @since 2024-09-10 18:07:15
*/
@Service
@RequiredArgsConstructor
public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> 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<UserRole> getEntityType() {
return UserRole.class;
}
}

View File

@ -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;
/**
* <p>
* 用户 服务实现类
* </p>
*
* @author Kerbores(kerbores@gmail.com)
*
* @since 2024-09-10 18:07:15
*/
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> 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<User> 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.<User> 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<Permission> 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<PermissionInfo> permissionInfosByUserName(String name) {
List<PermissionInfo> directPermissionInfos = directPermissionInfosByUserName(name);
List<PermissionInfo> 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<PermissionInfo> indirectPermissionInfosByUserName(String name) {
return getBaseMapper().indirectPermissionInfosByUserName(name);
}
/**
* @param name
* @return
*/
private List<PermissionInfo> 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<String> permissions) {
userPermissionMapper.delete(Wrappers.<UserPermission> 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<RoleInfo> 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<String> roles) {
userRoleMapper.delete(Wrappers.<UserRole> 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.<User> 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.<User> lambdaQuery().eq(User::getName, name));
if (Lang.isEmpty(user)) {
throw Lang.makeThrow(BizException.class, "不存在的用户: %s", name);
}
return authUser(user);
}
}

View File

@ -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;
/**
* <p>
* 码本数据 服务类
* </p>
*
* @author Kerbores(kerbores@gmail.com)
*
* @since 2024-09-14 15:42:31
*/
public interface IDictionaryService extends IService<Dictionary>, IdNameEntityService<Dictionary> {
}

View File

@ -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;
/**
* <p>
* 码本分组 服务类
* </p>
*
* @author Kerbores(kerbores@gmail.com)
*
* @since 2024-09-14 15:42:31
*/
public interface IGroupService extends IService<Group>, IdNameEntityService<Group> {
}

View File

@ -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;
/**
* <p>
* 码本数据 服务实现类
* </p>
*
* @author Kerbores(kerbores@gmail.com)
*
* @since 2024-09-14 15:42:31
*/
@Service
@RequiredArgsConstructor
public class DictionaryServiceImpl extends ServiceImpl<DictionaryMapper, Dictionary> 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<Dictionary> getEntityType() {
return Dictionary.class;
}
}

View File

@ -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;
/**
* <p>
* 码本分组 服务实现类
* </p>
*
* @author Kerbores(kerbores@gmail.com)
*
* @since 2024-09-14 15:42:31
*/
@Service
@RequiredArgsConstructor
public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> 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<Group> getEntityType() {
return Group.class;
}
}

View File

@ -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<ApplyDetail>, IdNameEntityService<ApplyDetail> {
}

View File

@ -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<ApplyForm>, IdNameEntityService<ApplyForm> {
}

View File

@ -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<Material>, IdNameEntityService<Material> {
}

View File

@ -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<ApplyDetailMapper, ApplyDetail> implements IApplyDetailService {
private final Dao dao;
@Override
public Dao dao() {
return dao;
}
}

View File

@ -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<ApplyFormMapper, ApplyForm> implements IApplyFormService {
private final Dao dao;
@Override
public Dao dao() {
return dao;
}
}

View File

@ -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<MaterialMapper, Material> implements IMaterialService {
private final Dao dao;
@Override
public Dao dao() {
return dao;
}
}

View File

@ -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

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="tech.riemann.ims.mapper.acl.RoleMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="tech.riemann.ims.entity.acl.Role">
<result column="id" property="id" />
<result column="created_time" property="createdTime" />
<result column="updated_time" property="updatedTime" />
<result column="created_by" property="createdBy" />
<result column="updated_by" property="updatedBy" />
<result column="r_key" property="key" />
<result column="r_name" property="name" />
<result column="r_description" property="description" />
</resultMap>
<resultMap id="PermissionInfoResultMap" type="tech.riemann.ims.dto.response.PermissionInfo">
<result column="id" property="id" />
<result column="p_key" property="key" />
<result column="p_key_path" property="keyPath" />
<result column="p_name" property="name" />
<result column="p_description" property="description" />
<result column="p_parent_key" property="parentKey" />
<result column="p_type" property="type" />
<result column="selected" property="selected" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
created_time,
updated_time,
created_by,
updated_by,
r_key, r_name, r_description
</sql>
<select id="permissionInfosByKey" resultMap="PermissionInfoResultMap">
SELECT
p.*,
rp.id IS NOT NULL AS selected
FROM
t_permission p
LEFT JOIN (
SELECT
*
FROM
t_role_permission
WHERE
rp_role_key = #{key}
) rp ON
p.p_key_path = rp.rp_permission_key_path
</select>
</mapper>

View File

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="tech.riemann.ims.mapper.acl.UserMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="tech.riemann.ims.entity.acl.User">
<result column="id" property="id" />
<result column="created_time" property="createdTime" />
<result column="updated_time" property="updatedTime" />
<result column="created_by" property="createdBy" />
<result column="updated_by" property="updatedBy" />
<result column="u_name" property="name" />
<result column="u_password" property="password" />
<result column="u_mobile" property="mobile" />
<result column="u_sex" property="sex" />
<result column="u_email" property="email" />
<result column="u_full_name" property="fullName" />
</resultMap>
<resultMap id="RoleInfoBaseResultMap" type="tech.riemann.ims.dto.response.RoleInfo">
<result column="id" property="id" />
<result column="r_key" property="key" />
<result column="r_name" property="name" />
<result column="r_description" property="description" />
<result column="selected" property="selected" />
</resultMap>
<resultMap id="PermissionInfoResultMap" type="tech.riemann.ims.dto.response.PermissionInfo">
<result column="id" property="id" />
<result column="p_key" property="key" />
<result column="p_key_path" property="keyPath" />
<result column="p_name" property="name" />
<result column="p_description" property="description" />
<result column="p_parent_key" property="parentKey" />
<result column="p_type" property="type" />
<result column="selected" property="selected" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
created_time,
updated_time,
created_by,
updated_by,
u_name, u_password, u_mobile, u_sex, u_email, u_full_name
</sql>
<select id="indirectPermissionInfosByUserName" resultMap="PermissionInfoResultMap">
SELECT
p.*,
rp.id IS NOT NULL AS selected
FROM
t_permission p
LEFT JOIN (
SELECT
*
FROM
t_role_permission
WHERE
rp_role_key IN (
SELECT
ur_role_key
FROM
t_user_role
WHERE
ur_user_name = #{name}
)
) rp ON
p.p_key_path = rp.rp_permission_key_path
</select>
<select id="directPermissionInfosByUserName" resultMap="PermissionInfoResultMap">
SELECT
p.*,
up.id IS NOT NULL AS selected
FROM
t_permission p
LEFT JOIN (
SELECT
*
FROM
t_user_permission
WHERE
up_user_name = #{name}
) up ON
p.p_key_path = up.up_permission_key_path
</select>
<select id="roleInfosByUserName" resultMap="RoleInfoBaseResultMap">
SELECT
r.*,
ur.id IS NOT NULL AS selected
FROM
t_role r
LEFT JOIN (
SELECT
*
FROM
t_user_role
WHERE
ur_user_name = #{name}
) ur ON
r.r_key = ur.ur_role_key
</select>
</mapper>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="tech.riemann.ims.mapper.dictionary.DictionaryMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="tech.riemann.ims.entity.dictionary.Dictionary">
<result column="id" property="id" />
<result column="created_time" property="createdTime" />
<result column="updated_time" property="updatedTime" />
<result column="created_by" property="createdBy" />
<result column="updated_by" property="updatedBy" />
<result column="d_group_key" property="groupKey" />
<result column="d_parent_key" property="parentKey" />
<result column="d_index" property="index" />
<result column="d_key" property="key" />
<result column="d_value" property="value" />
<result column="d_description" property="description" />
<result column="d_disabled" property="disabled" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
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
</sql>
</mapper>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="tech.riemann.ims.mapper.dictionary.GroupMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="tech.riemann.ims.entity.dictionary.Group">
<result column="id" property="id" />
<result column="created_time" property="createdTime" />
<result column="updated_time" property="updatedTime" />
<result column="created_by" property="createdBy" />
<result column="updated_by" property="updatedBy" />
<result column="g_key" property="key" />
<result column="g_name" property="name" />
<result column="g_description" property="description" />
<result column="g_disabled" property="disabled" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
created_time,
updated_time,
created_by,
updated_by,
g_key, g_name, g_description, g_disabled
</sql>
</mapper>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="tech.riemann.ims.mapper.acl.PermissionMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="tech.riemann.ims.entity.acl.Permission">
<result column="id" property="id" />
<result column="created_time" property="createdTime" />
<result column="updated_time" property="updatedTime" />
<result column="created_by" property="createdBy" />
<result column="updated_by" property="updatedBy" />
<result column="p_key" property="key" />
<result column="p_key_path" property="keyPath" />
<result column="p_name" property="name" />
<result column="p_description" property="description" />
<result column="p_parent_key" property="parentKey" />
<result column="p_type" property="type" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
created_time,
updated_time,
created_by,
updated_by,
p_key, p_key_path, p_name, p_description, p_parent_key, p_type
</sql>
</mapper>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="tech.riemann.ims.mapper.acl.RoleMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="tech.riemann.ims.entity.acl.Role">
<result column="id" property="id" />
<result column="created_time" property="createdTime" />
<result column="updated_time" property="updatedTime" />
<result column="created_by" property="createdBy" />
<result column="updated_by" property="updatedBy" />
<result column="r_key" property="key" />
<result column="r_name" property="name" />
<result column="r_description" property="description" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
created_time,
updated_time,
created_by,
updated_by,
r_key, r_name, r_description
</sql>
</mapper>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="tech.riemann.ims.mapper.acl.RolePermissionMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="tech.riemann.ims.entity.acl.RolePermission">
<result column="id" property="id" />
<result column="created_time" property="createdTime" />
<result column="updated_time" property="updatedTime" />
<result column="created_by" property="createdBy" />
<result column="updated_by" property="updatedBy" />
<result column="rp_role_key" property="roleKey" />
<result column="rp_permission_key_path" property="permissionKeyPath" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
created_time,
updated_time,
created_by,
updated_by,
rp_role_key, rp_permission_key_path
</sql>
</mapper>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="tech.riemann.ims.mapper.acl.UserBindMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="tech.riemann.ims.entity.acl.UserBind">
<result column="id" property="id" />
<result column="created_time" property="createdTime" />
<result column="updated_time" property="updatedTime" />
<result column="created_by" property="createdBy" />
<result column="updated_by" property="updatedBy" />
<result column="b_user_name" property="userName" />
<result column="b_type" property="type" />
<result column="b_openid" property="openid" />
<result column="b_metadata" property="metadata" />
<result column="b_uuid" property="uuid" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
created_time,
updated_time,
created_by,
updated_by,
b_user_name, b_type, b_openid, b_metadata, b_uuid
</sql>
</mapper>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="tech.riemann.ims.mapper.acl.UserMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="tech.riemann.ims.entity.acl.User">
<result column="id" property="id" />
<result column="created_time" property="createdTime" />
<result column="updated_time" property="updatedTime" />
<result column="created_by" property="createdBy" />
<result column="updated_by" property="updatedBy" />
<result column="u_name" property="name" />
<result column="u_password" property="password" />
<result column="u_mobile" property="mobile" />
<result column="u_sex" property="sex" />
<result column="u_email" property="email" />
<result column="u_full_name" property="fullName" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
created_time,
updated_time,
created_by,
updated_by,
u_name, u_password, u_mobile, u_sex, u_email, u_full_name
</sql>
</mapper>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="tech.riemann.ims.mapper.acl.UserPermissionMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="tech.riemann.ims.entity.acl.UserPermission">
<result column="id" property="id" />
<result column="created_time" property="createdTime" />
<result column="updated_time" property="updatedTime" />
<result column="created_by" property="createdBy" />
<result column="updated_by" property="updatedBy" />
<result column="up_user_name" property="userName" />
<result column="up_permission_key_path" property="permissionKeyPath" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
created_time,
updated_time,
created_by,
updated_by,
up_user_name, up_permission_key_path
</sql>
</mapper>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="tech.riemann.ims.mapper.acl.UserRoleMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="tech.riemann.ims.entity.acl.UserRole">
<result column="id" property="id" />
<result column="created_time" property="createdTime" />
<result column="updated_time" property="updatedTime" />
<result column="created_by" property="createdBy" />
<result column="updated_by" property="updatedBy" />
<result column="ur_user_name" property="userName" />
<result column="ur_role_key" property="roleKey" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
created_time,
updated_time,
created_by,
updated_by,
ur_user_name, ur_role_key
</sql>
</mapper>

View File

@ -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() {
}
}

View File

@ -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<String> pool = Lang.array2list("abcdefghijklmnopqrstuvwxyz".toCharArray(), char.class)
.stream()
.map(c -> c + "")
.toList();
List<String> 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<String> 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();
});
}
}

View File

@ -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;
<% } %>
/**
* <p>
* ${table.comment!} 前端控制器
* </p>
*
* @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 根据业务情况进行搜索字段和条件的处理
*
* <pre>
* Wrappers.<${entity}> lambdaQuery()
* .like(hasLike, ${entity}::getName, key)
* .or()
* .like(hasLike, ${entity}::getMobile, key)
* </pre>
*
* nutz实现
*
* <pre>
* return ${entityName}Service.searchByKeyAndPage(key,
* page,
* size,
* ${entity}.Fields.name);
* </pre>
*/
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实现
*
* <pre>
* return ${entityName}Service.fetch(id);
* </pre>
*/
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实现
*
* <pre>
* return ${entityName}Service.insert(${entityName});
* </pre>
*/
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 根据实际情况进行更新条件和字段的处理<br>
*
* <pre>
* ${entityName}Service.update(Wrappers.<${entity}> lambdaUpdate().set(${entity}::getName, ${entityName}.getName()).eq(${entity}::getId, ${entityName}.getId()));
* </pre>
*
* nutz实现
*
* <pre>
* ${entityName}Service.update(${entityName});
* </pre>
*/
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 根据情况调整参数和删除逻辑<br>
*
* <pre>
* ${entityName}Service.update(Wrappers.<${entity}> lambdaUpdate().set(${entity}::getStatus, false).eq(${entity}::getId, id));
* </pre>
*
* nutz实现
*
* <pre>
* if(${entityName}Service.delete(id) != 1){
* throw Lang.makeThrow("删除${table.comment!}失败!");
* }
* </pre>
*/
if(! ${entityName}Service.removeById(id)){
throw BizException.create("删除${table.comment!}失败!");
}
}
}
<% } %>

View File

@ -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} +
<% } %>
<% } %>
"}";
}
<% } %>
}

View File

@ -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;
<% } %>
/**
* <p>
* ${table.comment!}
* </p>
*
* @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} +
<% } %>
<% } %>
"}"
}
<% } %>
}

View File

@ -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}> {
}
<% } %>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="${package.Mapper}.${table.mapperName}">
<% if(enableCache){ %>
<!-- 开启二级缓存 -->
<cache type="${cacheClassName}"/>
<% } %>
<% if(baseResultMap){ %>
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="${package.Entity}.${entity}">
<% for(field in table.fields){ %>
<% /** 生成主键排在第一位 **/ %>
<% if(field.keyFlag){ %>
<id column="${field.name}" property="${field.propertyName}" />
<% } %>
<% } %>
<% for(field in table.commonFields){ %>
<% /** 生成公共字段 **/ %>
<result column="${field.name}" property="${field.propertyName}" />
<% } %>
<% for(field in table.fields){ %>
<% /** 生成普通字段 **/ %>
<% if(!field.keyFlag){ %>
<result column="${field.name}" property="${field.propertyName}" />
<% } %>
<% } %>
</resultMap>
<% } %>
<% if(baseColumnList){ %>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
<% for(field in table.commonFields){ %>
${field.columnName},
<% } %>
${table.fieldNames}
</sql>
<% } %>
</mapper>

View File

@ -0,0 +1,22 @@
package ${package.Service};
import ${package.Entity}.${entity};
import ${superServiceClassPackage};
import org.nutz.spring.boot.service.interfaces.IdNameEntityService;
/**
* <p>
* ${table.comment!} 服务类
* </p>
*
* @author ${author}
*
* @since ${date}
*/
<% if(kotlin){ %>
interface ${table.serviceName} : ${superServiceClass}<${entity}>
<% }else{ %>
public interface ${table.serviceName} extends ${superServiceClass}<${entity}>, IdNameEntityService<${entity}> {
}
<% } %>

View File

@ -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;
/**
* <p>
* ${table.comment!} 服务实现类
* </p>
*
* @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;
}
}
<% } %>

View File

@ -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;
<% } %>
/**
* <p>
* ${table.comment!} 前端控制器
* </p>
*
* @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 处理搜索条件
*
* <pre>
Wrappers.<${entity}> lambdaQuery()
.like(hasLike, ${entity}::getName, key)
.or()
.like(hasLike, ${entity}::getMobile, key)
* </pre>
*/
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 根据情况处理是否需要根据指定条件更新指定字段<br>
*
* <pre>
* ${entityName}Service.update(Wrappers.<${entity}> lambdaUpdate().set(${entity}::getName, ${entityName}.getName()).eq(${entity}::getId, ${entityName}.getId()));
* </pre>
*/
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 根据情况判断是否处理逻辑删除<br>
*
* <pre>
* ${entityName}Service.update(Wrappers.<${entity}> lambdaUpdate().set(${entity}::getStatus, false).eq(${entity}::getId, id));
* </pre>
*/
if(! ${entityName}Service.removeById(id)){
throw Lang.makeThrow("删除${table.comment!}失败!");
}
}
}
<% } %>

View File

@ -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} +
<% } %>
<% } %>
"}";
}
<% } %>
}

View File

@ -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;
<% } %>
/**
* <p>
* ${table.comment!}
* </p>
*
* @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} +
<% } %>
<% } %>
"}"
}
<% } %>
}

View File

@ -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}> {
}
<% } %>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="${package.Mapper}.${table.mapperName}">
<% if(enableCache){ %>
<!-- 开启二级缓存 -->
<cache type="${cacheClassName}"/>
<% } %>
<% if(baseResultMap){ %>
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="${package.Entity}.${entity}">
<% for(field in table.fields){ %>
<% /** 生成主键排在第一位 **/ %>
<% if(field.keyFlag){ %>
<id column="${field.name}" property="${field.propertyName}" />
<% } %>
<% } %>
<% for(field in table.commonFields){ %>
<% /** 生成公共字段 **/ %>
<result column="${field.name}" property="${field.propertyName}" />
<% } %>
<% for(field in table.fields){ %>
<% /** 生成普通字段 **/ %>
<% if(!field.keyFlag){ %>
<result column="${field.name}" property="${field.propertyName}" />
<% } %>
<% } %>
</resultMap>
<% } %>
<% if(baseColumnList){ %>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
<% for(field in table.commonFields){ %>
${field.columnName},
<% } %>
${table.fieldNames}
</sql>
<% } %>
</mapper>

Some files were not shown because too many files have changed in this diff Show More