实验4
This commit is contained in:
commit
8afbe59985
|
@ -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/
|
|
@ -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
|
|
@ -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 "$@"
|
|
@ -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"
|
|
@ -0,0 +1,108 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.3.4</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.xiaoshuai.springboot</groupId>
|
||||
<artifactId>task1</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>task1</name>
|
||||
<description>task1</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-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<scope>runtime</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</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>
|
||||
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
|
||||
<version>3.5.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.33</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-generator</artifactId>
|
||||
<version>3.5.7</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.freemarker</groupId>
|
||||
<artifactId>freemarker</artifactId>
|
||||
<version>2.3.31</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<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>
|
|
@ -0,0 +1,15 @@
|
|||
package com.c202201020323.task1;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
@MapperScan("com.c202201020323.task1.dao")
|
||||
public class Task1Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Task1Application.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
package com.c202201020323.task1.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.c202201020323.task1.model.*;
|
||||
import com.c202201020323.task1.service.BookService;
|
||||
import com.c202201020323.task1.service.ReviewsService;
|
||||
import com.c202201020323.task1.service.UserService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@CrossOrigin
|
||||
@Controller
|
||||
@RequestMapping("/api")
|
||||
public class BookController {
|
||||
// @Autowired
|
||||
// private BookService bookService;
|
||||
//
|
||||
// @RequestMapping("/book")
|
||||
// public String book(Model model){
|
||||
// model.addAttribute("booklist", bookService.getAllBook());
|
||||
// return "book.html";
|
||||
// }
|
||||
//
|
||||
// @RequestMapping("/addbook")
|
||||
// public String addbook(){
|
||||
// return "addbook.html";
|
||||
// }
|
||||
//
|
||||
// @RequestMapping("/addbookcommit")
|
||||
// public String addbookcommit(Book book){
|
||||
// bookService.addBook(book);
|
||||
// return "redirect:/book";
|
||||
// }
|
||||
// @RequestMapping("/deletebook")
|
||||
// public String deletebook(int id){
|
||||
// bookService.deleteBook(id);
|
||||
// return "redirect:/book";
|
||||
// }
|
||||
// @RequestMapping("/updatebook")
|
||||
// public String updatebook(Book book,Model model){
|
||||
// model.addAttribute("book",book);
|
||||
// return "updatebook.html";
|
||||
// }
|
||||
// @RequestMapping("/updatebookcommit")
|
||||
// public String updatebookcommit(Book book){
|
||||
// bookService.updateBook(book);
|
||||
// return "redirect:/book";
|
||||
// }
|
||||
//
|
||||
// // 评论
|
||||
// @RequestMapping("/commentbook")
|
||||
// public String commentbook(int id){
|
||||
// return "commentbook.html";
|
||||
// }
|
||||
// @RequestMapping("/commentbookcommit")
|
||||
// public String commentbookcommit(){
|
||||
// return "redirect:/book";
|
||||
// }
|
||||
|
||||
// 图书操作
|
||||
@Autowired
|
||||
private BookService bookService;
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping("/getBook")
|
||||
public Result getBook() {
|
||||
List<Book> list = bookService.list();
|
||||
return Result.ok().put("data", list);
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping(value = "/saveOrUpdate")
|
||||
public Result saveOrUpdate(@RequestBody Book book) {
|
||||
boolean save = bookService.saveOrUpdate(book);
|
||||
if (save) {
|
||||
return Result.ok();
|
||||
}
|
||||
return Result.error();
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping("/deleteBook")
|
||||
public Result deleteBook(Integer id) {
|
||||
boolean remove = bookService.removeById(id);
|
||||
if (remove) {
|
||||
return Result.ok();
|
||||
}
|
||||
return Result.error();
|
||||
}
|
||||
|
||||
// 评论操作
|
||||
@Autowired
|
||||
private ReviewsService reviewsService;
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping("/getReviews")
|
||||
public Result getReviews(Integer bookId) {
|
||||
LambdaQueryWrapper<Reviews> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(Reviews::getBookId, bookId);
|
||||
List<Reviews> list = reviewsService.list(queryWrapper);
|
||||
List<ReviewsVo> result = new ArrayList<>();
|
||||
for (Reviews reviews : list) {
|
||||
ReviewsVo reviewsVo = new ReviewsVo();
|
||||
reviewsVo.setUserId(reviews.getUserId());
|
||||
reviewsVo.setBookId(reviews.getBookId());
|
||||
reviewsVo.setReview(reviews.getReview());
|
||||
reviewsVo.setUsername(userService.getById(reviews.getUserId()).getUsername());
|
||||
result.add(reviewsVo);
|
||||
}
|
||||
return Result.ok().put("data", result);
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping(value = "/addReviews")
|
||||
public Result addReviews(@RequestBody Reviews reviews) {
|
||||
boolean save = reviewsService.save(reviews);
|
||||
if (save) {
|
||||
return Result.ok();
|
||||
}
|
||||
return Result.error();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package com.c202201020323.task1.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.c202201020323.task1.dao.BookMapper;
|
||||
import com.c202201020323.task1.dao.BorrowMapper;
|
||||
import com.c202201020323.task1.model.*;
|
||||
import com.c202201020323.task1.service.BookService;
|
||||
import com.c202201020323.task1.service.BorrowService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@CrossOrigin
|
||||
@Controller
|
||||
@RequestMapping("/api")
|
||||
@Slf4j
|
||||
public class BorrowController {
|
||||
|
||||
@Autowired
|
||||
private BorrowService borrowService;
|
||||
|
||||
@Autowired
|
||||
private BookService bookService;
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping("/getBorrow")
|
||||
public Result getBorrow(Integer userId) {
|
||||
List<BorrowRecords> borrowRecords = borrowService.list(new LambdaQueryWrapper<BorrowRecords>().eq(BorrowRecords::getUserId, userId));
|
||||
List<Book> result = new ArrayList<>();
|
||||
for (BorrowRecords borrowRecord : borrowRecords) {
|
||||
Book book = bookService.getById(borrowRecord.getBookId());
|
||||
result.add(book);
|
||||
}
|
||||
return Result.ok().put("data", result);
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping("/cancelBorrow")
|
||||
public Result cancelBorrow(Integer bookId) {
|
||||
boolean remove = borrowService.removeById(bookId);
|
||||
log.info("bookId:{}", bookId);
|
||||
log.info("remove:{}", remove);
|
||||
if (remove) {
|
||||
return Result.ok();
|
||||
}
|
||||
return Result.error();
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping(value = "/borrowBook")
|
||||
public Result borrowBook(@RequestBody BorrowRecords borrowRecords) {
|
||||
boolean save = borrowService.save(borrowRecords);
|
||||
if (save) {
|
||||
return Result.ok();
|
||||
}
|
||||
return Result.error();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package com.c202201020323.task1.controller;
|
||||
|
||||
import com.c202201020323.task1.model.Result;
|
||||
import com.c202201020323.task1.model.User;
|
||||
import com.c202201020323.task1.service.UserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
@CrossOrigin
|
||||
@Controller
|
||||
@RequestMapping("/api")
|
||||
public class LoginController {
|
||||
// @Autowired
|
||||
// private UserService userService;
|
||||
//
|
||||
// @RequestMapping("/register")
|
||||
// public String register(){
|
||||
// return "register.html";
|
||||
// }
|
||||
//
|
||||
// @RequestMapping("/registercommit")
|
||||
// public String registercommit(User user){
|
||||
// userService.addUser(user);
|
||||
// return "redirect:/login";
|
||||
// }
|
||||
//
|
||||
// @RequestMapping("/login")
|
||||
// public String login(){
|
||||
// return "login.html";
|
||||
// }
|
||||
//
|
||||
// @RequestMapping("/logincommit")
|
||||
// public String logincommit(User user){
|
||||
// System.out.println(userService.getAllUser());
|
||||
// System.out.println(user);
|
||||
// if(userService.getAllUser().contains(user)){
|
||||
// return "redirect:/book";
|
||||
// }
|
||||
// return "redirect:/login";
|
||||
// }
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping("/register")
|
||||
public Result register(@RequestBody User user) {
|
||||
userService.save(user);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping("/login")
|
||||
public Result login(@RequestBody User user) {
|
||||
if (userService.validateUser(user) != 0) {
|
||||
return Result.ok().put("info", userService.validateUser(user));
|
||||
}
|
||||
return Result.error();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package com.c202201020323.task1.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.c202201020323.task1.model.Book;
|
||||
|
||||
|
||||
public interface BookMapper extends BaseMapper<Book> {
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package com.c202201020323.task1.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.c202201020323.task1.model.BorrowRecords;
|
||||
|
||||
public interface BorrowMapper extends BaseMapper<BorrowRecords> {
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package com.c202201020323.task1.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.c202201020323.task1.model.Reviews;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ReviewsMapper extends BaseMapper<Reviews> {
|
||||
public List<Reviews> getReviews();
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package com.c202201020323.task1.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.c202201020323.task1.model.User;
|
||||
|
||||
public interface UserMapper extends BaseMapper<User> {
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.c202201020323.task1.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@TableName("books202201020323")
|
||||
public class Book {
|
||||
private int id;
|
||||
private String title;
|
||||
private String author;
|
||||
private String isbn;
|
||||
private String publisher;
|
||||
private String publishedDate;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.c202201020323.task1.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@TableName("borrow_records202201020323")
|
||||
public class BorrowRecords {
|
||||
private int id;
|
||||
private int bookId;
|
||||
private int userId;
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package com.c202201020323.task1.model;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 返回数据封装类
|
||||
*/
|
||||
public class Result extends HashMap<String, Object> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public Result() {
|
||||
put("code", 200);
|
||||
put("msg", "success");
|
||||
}
|
||||
|
||||
public static Result error() {
|
||||
return error(500, "未知异常,请联系管理员");
|
||||
}
|
||||
|
||||
public static Result error(String msg) {
|
||||
return error(500, msg);
|
||||
}
|
||||
|
||||
public static Result error(int code, String msg) {
|
||||
Result r = new Result();
|
||||
r.put("code", code);
|
||||
r.put("msg", msg);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static Result ok(String msg) {
|
||||
Result r = new Result();
|
||||
r.put("msg", msg);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
public static Result ok(Object obj) {
|
||||
Result r = new Result();
|
||||
r.put("data", obj);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static Result ok(Map<String, Object> map) {
|
||||
Result r = new Result();
|
||||
r.putAll(map);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static Result ok() {
|
||||
return new Result();
|
||||
}
|
||||
|
||||
public Result put(String key, Object value) {
|
||||
super.put(key, value);
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.c202201020323.task1.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@TableName("reviews202201020323")
|
||||
public class Reviews {
|
||||
private int id;
|
||||
private String review;
|
||||
private int userId;
|
||||
private int bookId;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.c202201020323.task1.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ReviewsVo {
|
||||
private int id;
|
||||
private String review;
|
||||
private int userId;
|
||||
private int bookId;
|
||||
private String username;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.c202201020323.task1.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@TableName("users202201020323")
|
||||
public class User {
|
||||
private int id;
|
||||
private String username;
|
||||
private String password;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package com.c202201020323.task1.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.c202201020323.task1.model.Book;
|
||||
|
||||
public interface BookService extends IService<Book> {
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package com.c202201020323.task1.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.c202201020323.task1.model.BorrowRecords;
|
||||
|
||||
public interface BorrowService extends IService<BorrowRecords> {
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package com.c202201020323.task1.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.c202201020323.task1.model.Reviews;
|
||||
|
||||
public interface ReviewsService extends IService<Reviews> {
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package com.c202201020323.task1.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.c202201020323.task1.model.User;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface UserService extends IService<User> {
|
||||
public Integer validateUser(User user);
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.c202201020323.task1.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.c202201020323.task1.dao.BookMapper;
|
||||
import com.c202201020323.task1.model.Book;
|
||||
import com.c202201020323.task1.service.BookService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements BookService {
|
||||
@Autowired
|
||||
private BookMapper bookMapper;
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.c202201020323.task1.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.c202201020323.task1.dao.BorrowMapper;
|
||||
import com.c202201020323.task1.model.BorrowRecords;
|
||||
import com.c202201020323.task1.service.BorrowService;
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class BorrowServiceImpl extends ServiceImpl<BorrowMapper, BorrowRecords> implements BorrowService {
|
||||
@Autowired
|
||||
private BorrowMapper borrowMapper;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.c202201020323.task1.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.c202201020323.task1.dao.ReviewsMapper;
|
||||
import com.c202201020323.task1.model.Reviews;
|
||||
import com.c202201020323.task1.service.ReviewsService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class ReviewsServiceImpl extends ServiceImpl<ReviewsMapper, Reviews> implements ReviewsService {
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.c202201020323.task1.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.c202201020323.task1.dao.UserMapper;
|
||||
import com.c202201020323.task1.model.User;
|
||||
import com.c202201020323.task1.service.UserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
|
||||
@Autowired
|
||||
private UserMapper userMapper;
|
||||
|
||||
// 验证
|
||||
@Override
|
||||
public Integer validateUser(User user) {
|
||||
User dbUser = userMapper.selectOne(new QueryWrapper<User>()
|
||||
.eq("username", user.getUsername())
|
||||
.eq("password", user.getPassword()));
|
||||
return dbUser.getId();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
spring.application.name=task1
|
||||
|
||||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||
spring.datasource.name=defaultDataSource
|
||||
spring.datasource.url=jdbc:mysql://106.53.194.250:63306/task202201020323?serverTimezone=UTC
|
||||
spring.datasource.username=202201020323
|
||||
spring.datasource.password=@hnucm1254
|
||||
|
||||
mybatis-plus.mapper-locations=classpath:mapper/*.xml
|
||||
mybatis-plus.type-aliases-package=com.c202201020323.task1.model
|
||||
|
||||
logging.level.com.c202201020323.task1 = debug
|
|
@ -0,0 +1,17 @@
|
|||
<?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="com.c202201020323.task1.dao.BookMapper">
|
||||
<!-- <select id="getAllBook" resultMap="reviewsMap"> -->
|
||||
<!-- select * from books202201020323 -->
|
||||
<!-- </select> -->
|
||||
<!-- <resultMap id="reviewsMap" type="com.c202201020323.task1.model.Book"> -->
|
||||
<!-- <!– column表示数据库字段名,property表示实体类字段名 –> -->
|
||||
<!-- <id column="id" property="id"/> -->
|
||||
<!-- <!– 一对多查询 –> -->
|
||||
<!-- <collection property="reviewsList" -->
|
||||
<!-- column="id" -->
|
||||
<!-- select="com.c202201020323.task1.dao.ReviewsMapper.getReviews" -->
|
||||
<!-- ofType="com.c202201020323.task1.model.Reviews"> -->
|
||||
<!-- </collection> -->
|
||||
<!-- </resultMap> -->
|
||||
</mapper>
|
|
@ -0,0 +1,12 @@
|
|||
<?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="com.c202201020323.task1.dao.ReviewsMapper">
|
||||
<!-- <select id="getReviews" resultType="com.c202201020323.task1.model.Reviews"> -->
|
||||
<!-- select re.*, us.username -->
|
||||
<!-- from reviews202201020323 re -->
|
||||
<!-- join users202201020323 us on re.userid = us.id in ( -->
|
||||
<!-- select userid from borrow_records202201020323 -->
|
||||
<!-- where bookid=#{bookid} -->
|
||||
<!-- ) -->
|
||||
<!-- </select> -->
|
||||
</mapper>
|
|
@ -0,0 +1,5 @@
|
|||
<?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="com.c202201020323.task1.dao.UserMapper">
|
||||
|
||||
</mapper>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>增加书籍</h1>
|
||||
<form th:action="@{/addbookcommit}" method="post">
|
||||
<input type="text" name="title" placeholder="书名"><br>
|
||||
<input type="text" name="author" placeholder="作者"/><br>
|
||||
<input type="text" name="isbn" placeholder="ISBN"/><br>
|
||||
<input type="text" name="publisher" placeholder="出版社"/><br>
|
||||
<input type="text" name="published_date" placeholder="出版日期"/><br>
|
||||
<input type="submit" value="确定"/>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,69 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>书籍列表</h1>
|
||||
<table border="1" cellspacing="0" cellpadding="0" style="width: 100vw">
|
||||
<tr>
|
||||
<th>id</th>
|
||||
<th>书名</th>
|
||||
<th>作者</th>
|
||||
<th>ISBN</th>
|
||||
<th>出版社</th>
|
||||
<th>出版日期</th>
|
||||
<th>用户评论</th>
|
||||
<th>修改操作</th>
|
||||
<th>删除操作</th>
|
||||
<th>借阅操作</th>
|
||||
<th>评论操作</th>
|
||||
</tr>
|
||||
</tr>
|
||||
<tr th:each="book:${booklist}">
|
||||
<td th:text="${book.id}"></td>
|
||||
<td th:text="${book.title}"></td>
|
||||
<td th:text="${book.author}"></td>
|
||||
<td th:text="${book.isbn}"></td>
|
||||
<td th:text="${book.publisher}"></td>
|
||||
<td th:text="${book.published_date}"></td>
|
||||
<td>
|
||||
<ol>
|
||||
<li th:each="comment:${book.reviewsList}">
|
||||
<span th:text="${comment.username}"></span>
|
||||
———
|
||||
<span th:text="${comment.review}"></span>
|
||||
</li>
|
||||
</ol>
|
||||
</td>
|
||||
<td>
|
||||
<a th:href="@{/updatebook(id=${book.id},title=${book.title},author=${book.author}, isbn=${book.isbn}, publisher=${book.publisher}, published_date=${book.published_date})}" th:text="修改"></a>
|
||||
</td>
|
||||
<td>
|
||||
<a th:href="@{/deletebook(id=${book.id})}" th:text="删除"></a>
|
||||
</td>
|
||||
<td>
|
||||
<ul>
|
||||
<li>
|
||||
<a th:href="@{/reviews(id=${book.id})}" th:text="查看借阅"></a>
|
||||
</li>
|
||||
<li>
|
||||
<a th:href="@{/addreviews}" th:text="增加借阅"></a>
|
||||
</li>
|
||||
<li>
|
||||
<a th:href="@{/deletereviews}" th:text="删除借阅"></a>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<a th:href="@{/commentbook(id=${book.id})}" th:text="评论"></a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<a href="/addbook">增加书籍</a>
|
||||
<script>
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>评论</h1>
|
||||
<form action="/commentbookcommit" method="post">
|
||||
<input type="hidden" name="bookid" th:value="${bookid}"/>
|
||||
<textarea name="content" id="content" cols="30" rows="10"></textarea>
|
||||
<input type="submit" value="提交"/>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>登录界面</h1>
|
||||
<form th:action="@{/logincommit}" method="post">
|
||||
<input type="text" name="username" placeholder="用户名"><br>
|
||||
<input type="password" name="password" placeholder="密码"><br>
|
||||
<input type="submit" value="登录"></input>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>注册界面</h1>
|
||||
<form th:action="@{/registercommit}" method="post">
|
||||
<input type="text" name="username" placeholder="用户名"><br>
|
||||
<input type="password" name="password" placeholder="密码"><br>
|
||||
<input type="submit" value="注册"></input>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>借阅详情</h1>
|
||||
<ol >
|
||||
<li th:each="borrowRecords:${borrowRecords}">
|
||||
<span th:text="${borrowRecords.title}"></span>
|
||||
</li>
|
||||
</ol>
|
||||
<h3>
|
||||
<a th:href="@{/book}">返回</a>
|
||||
</h3>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>修改书籍</h1>
|
||||
<form th:action="@{/updatebookcommit}" method="post">
|
||||
<input type="hidden" name="id" th:value="${book.id}" placeholder="id"/>
|
||||
<input type="text" name="title" placeholder="书名" th:value="${book.title}"><br>
|
||||
<input type="text" name="author" placeholder="作者" th:value="${book.author}"/><br>
|
||||
<input type="text" name="isbn" placeholder="ISBN" th:value="${book.isbn}"/><br>
|
||||
<input type="text" name="publisher" placeholder="出版社" th:value="${book.publisher}"/><br>
|
||||
<input type="text" name="published_date" placeholder="出版日期" th:value="${book.published_date}"/><br>
|
||||
<input type="submit" value="确定"/>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
package com.c202201020323.task1;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class Task1ApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
dist-ssr
|
||||
coverage
|
||||
*.local
|
||||
|
||||
/cypress/videos/
|
||||
/cypress/screenshots/
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
*.tsbuildinfo
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"recommendations": ["Vue.volar"]
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
# xiaoshuai
|
||||
|
||||
This template should help get you started developing with Vue 3 in Vite.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
|
||||
|
||||
## Customize configuration
|
||||
|
||||
See [Vite Configuration Reference](https://vite.dev/config/).
|
||||
|
||||
## Project Setup
|
||||
|
||||
```sh
|
||||
pnpm install
|
||||
```
|
||||
|
||||
### Compile and Hot-Reload for Development
|
||||
|
||||
```sh
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
### Compile and Minify for Production
|
||||
|
||||
```sh
|
||||
pnpm build
|
||||
```
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Vite App</title>
|
||||
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"name": "xiaoshuai",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"axios": "^1.7.7",
|
||||
"element-plus": "^2.8.7",
|
||||
"pinia": "^2.2.6",
|
||||
"vue": "^3.5.12",
|
||||
"vue-router": "^4.4.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^5.1.4",
|
||||
"unplugin-auto-import": "^0.18.3",
|
||||
"unplugin-vue-components": "^0.27.4",
|
||||
"vite": "^5.4.10"
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
|
@ -0,0 +1,3 @@
|
|||
<template>
|
||||
<router-view></router-view>
|
||||
</template>
|
|
@ -0,0 +1,13 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 图书操作
|
||||
export const getBookApi = () => request.get('/getBook')
|
||||
|
||||
export const saveOrUpdateApi = (data) => request.post('/saveOrUpdate',data)
|
||||
|
||||
export const deleteBookApi = (id) => request.get(`/deleteBook?id=${id}`)
|
||||
|
||||
// 评论操作
|
||||
export const getReviewsApi = (bookId) => request.get(`/getReviews?bookId=${bookId}`)
|
||||
|
||||
export const addReviewApi = (data) => request.post('/addReviews',data)
|
|
@ -0,0 +1,10 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 获取借阅记录
|
||||
export const getBorrowApi = (userId) => request.get(`/getBorrow?userId=${userId}`)
|
||||
|
||||
// 取消借阅图书
|
||||
export const cancelBorrowApi = (bookId) => request.get(`/cancelBorrow?bookId=${bookId}`)
|
||||
|
||||
// 借阅图书
|
||||
export const borrowApi = (data) => request.post(`/borrowBook`, data)
|
|
@ -0,0 +1,4 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
export const loginApi = (data) => request.post('/login', data)
|
||||
export const registerApi = (data) => request.post('/register', data)
|
|
@ -0,0 +1,12 @@
|
|||
import { createApp } from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(createPinia())
|
||||
app.use(router)
|
||||
|
||||
app.mount('#app')
|
|
@ -0,0 +1,33 @@
|
|||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
redirect: '/book',
|
||||
},
|
||||
{
|
||||
path: '/book',
|
||||
name: 'book',
|
||||
component: () => import('@/views/Book.vue'),
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
name: 'login',
|
||||
component: () => import('@/views/Login.vue'),
|
||||
},
|
||||
{
|
||||
path: '/borrow',
|
||||
name: 'borrow',
|
||||
component: () => import('@/views/borrow.vue'),
|
||||
}
|
||||
],
|
||||
})
|
||||
|
||||
router.beforeEach((to) => {
|
||||
const info = sessionStorage.getItem('info')
|
||||
if (to.path !== '/login' && !info) return '/login'
|
||||
})
|
||||
|
||||
export default router
|
|
@ -0,0 +1,33 @@
|
|||
import axios from 'axios'
|
||||
|
||||
// 基本配置
|
||||
const baseURL = 'http://127.0.0.1:8080/api'
|
||||
const instance = axios.create({
|
||||
baseURL,
|
||||
timeout: 10000,
|
||||
})
|
||||
|
||||
instance.interceptors.request.use(
|
||||
(config) => {
|
||||
return config
|
||||
},
|
||||
(error) => {
|
||||
ElMessage.error('请求异常')
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
instance.interceptors.response.use(
|
||||
(response) => {
|
||||
if (response.data.code === 200) {
|
||||
return response
|
||||
}
|
||||
ElMessage.error('服务异常1')
|
||||
return Promise.reject(response.data)
|
||||
},
|
||||
(error) => {
|
||||
ElMessage.error('服务异常2')
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
export default instance
|
|
@ -0,0 +1,348 @@
|
|||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { Edit, Delete } from "@element-plus/icons-vue";
|
||||
import {
|
||||
getBookApi,
|
||||
saveOrUpdateApi,
|
||||
deleteBookApi,
|
||||
getReviewsApi,
|
||||
addReviewApi,
|
||||
} from "@/api/book.js";
|
||||
import { getBorrowApi, borrowApi } from "@/api/borrow.js";
|
||||
|
||||
const tableData = ref([
|
||||
{
|
||||
id: 1,
|
||||
title: "Book 1",
|
||||
author: "Author 1",
|
||||
isbn: "ISBN 1",
|
||||
publisher: "Publisher 1",
|
||||
publishedDate: "2022-01-01",
|
||||
},
|
||||
]);
|
||||
|
||||
// 获取图书列表
|
||||
const getBook = async () => {
|
||||
const res = await getBookApi();
|
||||
tableData.value = res.data.data;
|
||||
};
|
||||
onMounted(() => {
|
||||
getBook();
|
||||
});
|
||||
|
||||
// 借阅相关
|
||||
const list = ref([]);
|
||||
const getBorrow = async () => {
|
||||
const res = await getBorrowApi(
|
||||
+sessionStorage.getItem("info")
|
||||
);
|
||||
for (let i = 0; i < res.data.data.length; i++) {
|
||||
list.value.push(res.data.data[i].id);
|
||||
}
|
||||
};
|
||||
|
||||
// 删除图书
|
||||
const deleteBook = async (row) => {
|
||||
console.log(row.id);
|
||||
await getBorrow();
|
||||
if (list.value.includes(row.id)) {
|
||||
ElMessage.warning("该图书已被借阅,无法删除");
|
||||
} else {
|
||||
await deleteBookApi(row.id);
|
||||
await getBook();
|
||||
ElMessage.success("删除成功");
|
||||
}
|
||||
};
|
||||
|
||||
// 编辑或增加图书
|
||||
const dialogVisible = ref(false);
|
||||
const add = ref(false);
|
||||
const form = ref({});
|
||||
const saveOrUpdate = (row) => {
|
||||
dialogVisible.value = true;
|
||||
form.value = { ...row };
|
||||
if (!row) {
|
||||
add.value = true;
|
||||
form.value.id = 0;
|
||||
}
|
||||
};
|
||||
const book = async () => {
|
||||
dialogVisible.value = false;
|
||||
await saveOrUpdateApi(form.value);
|
||||
await getBook();
|
||||
if (add.value) {
|
||||
add.value = false;
|
||||
ElMessage.success("添加成功");
|
||||
} else {
|
||||
ElMessage.success("修改成功");
|
||||
}
|
||||
};
|
||||
|
||||
// 查看图书评论
|
||||
const reviewsVisible = ref(false);
|
||||
const reviewsTitle = ref(null);
|
||||
const reviewsData = ref([{}]);
|
||||
const bookId = ref(0);
|
||||
const getReviews = async (row) => {
|
||||
bookId.value = row.id;
|
||||
reviewsVisible.value = true;
|
||||
reviewsTitle.value = row.title;
|
||||
const res = await getReviewsApi(bookId.value);
|
||||
reviewsData.value = res.data.data;
|
||||
};
|
||||
|
||||
// 发布评论
|
||||
const reviewsForm = ref("");
|
||||
const reviews = ref({
|
||||
userId: +sessionStorage.getItem("info"),
|
||||
bookId: null,
|
||||
review: null,
|
||||
});
|
||||
const publish = async () => {
|
||||
reviews.value.bookId = bookId.value;
|
||||
reviews.value.review = reviewsForm.value;
|
||||
await addReviewApi(reviews.value);
|
||||
reviewsForm.value = "";
|
||||
getReviews({
|
||||
id: bookId.value,
|
||||
title: reviewsTitle.value,
|
||||
});
|
||||
};
|
||||
|
||||
// 借阅图书
|
||||
const router = useRouter();
|
||||
const borrow = async (row) => {
|
||||
await getBorrow();
|
||||
if (list.value.includes(row.id)) {
|
||||
ElMessage.warning("您已借阅该图书");
|
||||
return;
|
||||
} else {
|
||||
const userId = +sessionStorage.getItem("info");
|
||||
const bookId = row.id;
|
||||
const id = ref({ userId, bookId });
|
||||
await borrowApi(id.value);
|
||||
ElMessage.success("借阅成功");
|
||||
router.push("/borrow");
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="body">
|
||||
<!-- 增加书籍按钮 -->
|
||||
<el-button
|
||||
@click="saveOrUpdate(null)"
|
||||
type="primary"
|
||||
style="margin-bottom: 20px"
|
||||
>添加书籍
|
||||
</el-button>
|
||||
|
||||
<!-- 借阅管理按钮 -->
|
||||
<el-button
|
||||
@click="$router.push('/borrow')"
|
||||
type="primary"
|
||||
style="margin-bottom: 20px"
|
||||
>我的借阅
|
||||
</el-button>
|
||||
|
||||
<!-- 增加编辑弹出框 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
title="编辑或增加"
|
||||
width="500"
|
||||
>
|
||||
<el-form
|
||||
v-model="form"
|
||||
label-width="100px"
|
||||
style="max-width: 400px"
|
||||
>
|
||||
<el-form-item label="id">
|
||||
<el-input disabled v-model="form.id" />
|
||||
</el-form-item>
|
||||
<el-form-item label="书名">
|
||||
<el-input v-model="form.title" />
|
||||
</el-form-item>
|
||||
<el-form-item label="作者">
|
||||
<el-input v-model="form.author" />
|
||||
</el-form-item>
|
||||
<el-form-item label="ISBN">
|
||||
<el-input v-model="form.isbn" />
|
||||
</el-form-item>
|
||||
<el-form-item label="出版社">
|
||||
<el-input v-model="form.publisher" />
|
||||
</el-form-item>
|
||||
<el-form-item label="出版日期">
|
||||
<el-input v-model="form.publishedDate" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button type="primary" @click="book()"
|
||||
>确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 评论弹出窗 -->
|
||||
<el-drawer
|
||||
v-model="reviewsVisible"
|
||||
:title="reviewsTitle"
|
||||
size="440px"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
position: absolute;
|
||||
top: 50vh;
|
||||
left: 100px;
|
||||
color: #aaa;
|
||||
"
|
||||
v-if="!reviewsData.length"
|
||||
>
|
||||
还没有评论,赶快来评论吧 ~~~
|
||||
</div>
|
||||
<ul v-else style="padding: 0 16px">
|
||||
<li v-for="item in reviewsData" :key="item">
|
||||
<div class="reviews-user">
|
||||
{{ item.username }}
|
||||
</div>
|
||||
<span class="reviews-content">{{
|
||||
item.review
|
||||
}}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="reviews">
|
||||
<el-input
|
||||
v-model="reviewsForm"
|
||||
style="width: 300px"
|
||||
/>
|
||||
<el-button
|
||||
:disabled="reviewsForm === ''"
|
||||
type="primary"
|
||||
@click="publish"
|
||||
>
|
||||
发布
|
||||
</el-button>
|
||||
</div>
|
||||
</el-drawer>
|
||||
|
||||
<!-- 书籍列表 -->
|
||||
<el-table stripe border :data="tableData">
|
||||
<el-table-column prop="id" label="id" width="50" />
|
||||
<el-table-column
|
||||
prop="title"
|
||||
label="书名"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
prop="author"
|
||||
label="作者"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
prop="isbn"
|
||||
label="ISBN"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
prop="publisher"
|
||||
label="出版社"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
prop="publishedDate"
|
||||
label="出版日期"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column label="借阅" width="53" disabled>
|
||||
<template #default="{ row }">
|
||||
<el-text
|
||||
type="primary"
|
||||
@click="borrow(row)"
|
||||
style="cursor: pointer"
|
||||
>借阅
|
||||
</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="用户评论" width="82">
|
||||
<template #default="{ row }">
|
||||
<el-text
|
||||
type="success"
|
||||
@click="getReviews(row)"
|
||||
style="cursor: pointer"
|
||||
>查看评论
|
||||
</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
width="140"
|
||||
fixed="right"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
plain
|
||||
type="primary"
|
||||
@click="saveOrUpdate(row)"
|
||||
>
|
||||
<el-icon><Edit /></el-icon>
|
||||
</el-button>
|
||||
<el-button
|
||||
plain
|
||||
type="danger"
|
||||
@click="deleteBook(row)"
|
||||
>
|
||||
<el-icon><Delete /></el-icon>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.body {
|
||||
width: 90vw;
|
||||
height: 90vh;
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
}
|
||||
:deep(.el-drawer__body) {
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
border-bottom: #e6e6e6 1px solid;
|
||||
scrollbar-width: none;
|
||||
border-top: 1px solid #e6e6e6;
|
||||
margin-bottom: 100px;
|
||||
.reviews {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
position: fixed;
|
||||
bottom: 36px;
|
||||
width: 400px;
|
||||
}
|
||||
li {
|
||||
list-style: none;
|
||||
padding: 8px 0 8px 0;
|
||||
border-bottom: rgba(62, 62, 62, 0.1) 1px solid;
|
||||
color: #888;
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.reviews-user {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.reviews-content {
|
||||
padding-left: 16px;
|
||||
font-weight: 600;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,203 @@
|
|||
<script setup>
|
||||
import { useRouter } from "vue-router";
|
||||
import { ref, useTemplateRef } from "vue";
|
||||
import { User, Lock } from "@element-plus/icons-vue";
|
||||
import { loginApi, registerApi } from "@/api/loginApi";
|
||||
|
||||
const form = ref({
|
||||
username: "",
|
||||
password: "",
|
||||
});
|
||||
|
||||
const rules = ref({
|
||||
user: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入用户名",
|
||||
trigger: "blur",
|
||||
},
|
||||
{
|
||||
min: 3,
|
||||
max: 10,
|
||||
message: "请输入 3 到 10 个字符",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入密码",
|
||||
trigger: "blur",
|
||||
},
|
||||
{
|
||||
pattern: /^[a-zA-Z0-9]{3,10}$/,
|
||||
message: "请输入 3 到 10 个数字或字母",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// 切换
|
||||
const toggleLogin = ref(false);
|
||||
const toggle = () => {
|
||||
toggleLogin.value = !toggleLogin.value;
|
||||
form.value = {
|
||||
username: "",
|
||||
password: "",
|
||||
}
|
||||
}
|
||||
|
||||
// 注册
|
||||
const register = async () => {
|
||||
await formRef.value.validate();
|
||||
loading.value = true;
|
||||
console.log(form.value);
|
||||
await registerApi(form.value);
|
||||
loading.value = false;
|
||||
ElMessage.success('注册成功');
|
||||
toggleLogin.value = false;
|
||||
form.value = {
|
||||
username: "",
|
||||
password: "",
|
||||
}
|
||||
};
|
||||
|
||||
// 登录
|
||||
const loading = ref(false);
|
||||
const formRef = useTemplateRef("formRef");
|
||||
const router = useRouter();
|
||||
const login = async () => {
|
||||
await formRef.value.validate();
|
||||
loading.value = true;
|
||||
const res = await loginApi(form.value)
|
||||
sessionStorage.setItem("info",res.data.info);
|
||||
loading.value = false
|
||||
ElMessage.success('登录成功')
|
||||
router.push("/book");
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="login">
|
||||
<!-- 注册 -->
|
||||
<el-form
|
||||
:model="form"
|
||||
:rules
|
||||
ref="formRef"
|
||||
size="large"
|
||||
v-if="toggleLogin"
|
||||
>
|
||||
<el-form-item prop="username">
|
||||
<el-input
|
||||
v-model="form.username"
|
||||
:prefix-icon="User"
|
||||
clearable
|
||||
autocomplete="off"
|
||||
placeholder="请输入用户名"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input
|
||||
v-model="form.password"
|
||||
:prefix-icon="Lock"
|
||||
clearable
|
||||
autocomplete="off"
|
||||
placeholder="请输入密码"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
@click="register"
|
||||
type="primary"
|
||||
:loading="loading"
|
||||
class="btn"
|
||||
round
|
||||
auto-insert-space
|
||||
>注册</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 登录 -->
|
||||
<el-form
|
||||
:model="form"
|
||||
:rules
|
||||
ref="formRef"
|
||||
size="large"
|
||||
v-else
|
||||
>
|
||||
<el-form-item prop="username">
|
||||
<el-input
|
||||
v-model="form.username"
|
||||
:prefix-icon="User"
|
||||
clearable
|
||||
autocomplete="off"
|
||||
placeholder="请输入用户名"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input
|
||||
v-model="form.password"
|
||||
:prefix-icon="Lock"
|
||||
clearable
|
||||
autocomplete="off"
|
||||
placeholder="请输入密码"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
@click="login"
|
||||
type="primary"
|
||||
:loading="loading"
|
||||
class="btn"
|
||||
round
|
||||
auto-insert-space
|
||||
>登录</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!-- 切换 -->
|
||||
<div
|
||||
@click="toggle"
|
||||
style="cursor: pointer"
|
||||
>
|
||||
{{
|
||||
toggleLogin
|
||||
? "已有账号?去登录"
|
||||
: "没有账号?去注册"
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.login {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 380px;
|
||||
width: 420px;
|
||||
margin: 0 auto;
|
||||
margin-top: 100px;
|
||||
background-color: #ccc;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 20px #ccc;
|
||||
opacity: 0.8;
|
||||
}
|
||||
:deep(.el-form) {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-evenly;
|
||||
height: 280px;
|
||||
.el-form-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.btn {
|
||||
margin-top: 36px;
|
||||
height: 40px;
|
||||
width: 360px;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,107 @@
|
|||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { getBorrowApi, cancelBorrowApi } from "@/api/borrow.js";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
const tableData = ref([
|
||||
{
|
||||
id: 1,
|
||||
title: "Book 1",
|
||||
author: "Author 1",
|
||||
isbn: "ISBN 1",
|
||||
publisher: "Publisher 1",
|
||||
publishedDate: "2022-01-01",
|
||||
},
|
||||
]);
|
||||
|
||||
// 获取图书列表
|
||||
const getBorrow = async () => {
|
||||
const res = await getBorrowApi(+sessionStorage.getItem("info"));
|
||||
tableData.value = res.data.data;
|
||||
};
|
||||
onMounted(() => {
|
||||
getBorrow();
|
||||
});
|
||||
|
||||
// 取消借阅
|
||||
const cancelBorrow = async (row) => {
|
||||
await cancelBorrowApi(row.id);
|
||||
await getBorrow();
|
||||
ElMessage.success("删除成功");
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="body">
|
||||
<!-- 返回按钮 -->
|
||||
<el-button
|
||||
@click="$router.push('/book')"
|
||||
type="primary"
|
||||
style="margin-bottom: 20px"
|
||||
>返回
|
||||
</el-button>
|
||||
|
||||
<!-- 书籍列表 -->
|
||||
<el-table stripe border :default-sort="{ prop: 'id', order: 'ascending' }" :data="tableData">
|
||||
<el-table-column sortable prop="id" label="id" width="50" />
|
||||
<el-table-column
|
||||
prop="title"
|
||||
label="书名"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
prop="author"
|
||||
label="作者"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
prop="isbn"
|
||||
label="ISBN"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
prop="publisher"
|
||||
label="出版社"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
prop="publishedDate"
|
||||
label="出版日期"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
width="81"
|
||||
fixed="right"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-text
|
||||
plain
|
||||
type="danger"
|
||||
@click="cancelBorrow(row)"
|
||||
style="cursor: pointer"
|
||||
>取消借阅
|
||||
</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.body {
|
||||
width: 90vw;
|
||||
height: 90vh;
|
||||
.reviews {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
position: fixed;
|
||||
bottom: 36px;
|
||||
width: 400px;
|
||||
}
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,27 @@
|
|||
import { fileURLToPath, URL } from 'node:url'
|
||||
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import AutoImport from 'unplugin-auto-import/vite'
|
||||
import Components from 'unplugin-vue-components/vite'
|
||||
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
vue(),
|
||||
AutoImport({
|
||||
resolvers: [ElementPlusResolver()],
|
||||
}),
|
||||
Components({
|
||||
resolvers: [ElementPlusResolver()],
|
||||
}),
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||
}
|
||||
},
|
||||
server: {
|
||||
port: 3333,
|
||||
}
|
||||
})
|
Loading…
Reference in New Issue